[llvm] [AArch64, ELF] Allow implicit $d/$x at section beginning (PR #99718)

Fangrui Song via llvm-commits llvm-commits at lists.llvm.org
Fri Aug 16 19:10:12 PDT 2024


================
@@ -299,6 +311,53 @@ void AArch64TargetELFStreamer::finish() {
   AArch64ELFStreamer &S = getStreamer();
   MCContext &Ctx = S.getContext();
   auto &Asm = S.getAssembler();
+
+  // If ImplicitMapSyms is specified, ensure that text sections end with
+  // the A64 state while non-text sections end with the data state. When
+  // sections are combined by the linker, the subsequent section will start with
+  // the right state. The ending mapping symbol is added right after the last
+  // symbol relative to the section. When a dumb linker combines (.text.0; .word
+  // 0) and (.text.1; .word 0), the ending $x of .text.0 precedes the $d of
+  // .text.1, even if they have the same address.
+  if (S.ImplicitMapSyms) {
+    auto &Syms = Asm.getSymbols();
+    const size_t NumSyms = Syms.size();
+    DenseMap<MCSection *, MCSymbol *> EndMappingSym;
+    for (MCSection &Sec : Asm) {
+      S.switchSection(&Sec);
+      if (S.LastEMS == (Sec.isText() ? AArch64ELFStreamer::EMS_Data
+                                     : AArch64ELFStreamer::EMS_A64))
+        EndMappingSym.try_emplace(
+            &Sec, S.emitMappingSymbol(Sec.isText() ? "$x" : "$d"));
+    }
+    if (Syms.size() != NumSyms) {
+      SmallVector<const MCSymbol *, 0> NewSyms;
+      DenseMap<MCSection *, size_t> Cnt;
+      Syms.truncate(NumSyms);
+      for (const MCSymbol *Sym : Syms)
+        if (Sym->isInSection())
----------------
MaskRay wrote:

Having 2 dense maps `DenseMap<MCSection *, MCSymbol *> EndMappingSym; DenseMap<MCSection *, size_t> Cnt;` was wasteful. I have changed the code to use one single map.

The performance benefit should be negligible as we cannot avoid the `Syms` iteration. 

https://github.com/llvm/llvm-project/pull/99718


More information about the llvm-commits mailing list