[PATCH] D78820: [LLD][ELF] Eliminate symbols of merged .ARM.exidx sections.
Igor Kudrin via Phabricator via llvm-commits
llvm-commits at lists.llvm.org
Fri Apr 24 11:21:02 PDT 2020
ikudrin created this revision.
ikudrin added reviewers: ruiu, MaskRay, grimar, peter.smith.
ikudrin added projects: lld, LLVM.
Herald added subscribers: danielkiss, kristof.beyls, arichardson, emaste.
Herald added a reviewer: espindola.
GNU tools generate mapping symbols "$d" for `.ARM.exidx` sections. The symbols are added to the symbol table much earlier than the merging takes place, and after that, they become dangling. Before the patch, LLD output those symbols as SHN_ABS with the value of 0. The patch removes such symbols from the symbol table.
Repository:
rG LLVM Github Monorepo
https://reviews.llvm.org/D78820
Files:
lld/ELF/SyntheticSections.cpp
lld/ELF/SyntheticSections.h
lld/test/ELF/arm-exidx-mapping-symbols.s
Index: lld/test/ELF/arm-exidx-mapping-symbols.s
===================================================================
--- /dev/null
+++ lld/test/ELF/arm-exidx-mapping-symbols.s
@@ -0,0 +1,41 @@
+// REQUIRES: arm
+// Test that symbols which point to merged .ARM.exidx sections are eliminated.
+// These symbols might be produced, for example, by GNU tools.
+
+// RUN: llvm-mc -filetype=obj -triple=armv7a-none-linux-gnueabi %s -o %t
+// RUN: ld.lld %t -o %t2
+// RUN: llvm-readelf -s %t2 | FileCheck %s
+
+// CHECK-NOT: $d.exidx.bar
+
+ .syntax unified
+ .section .text.foo,"axG",%progbits,foo,comdat
+foo:
+ bx lr
+
+// GNU as adds a mapping symbol "$d" for .ARM.exidx sections it generate.
+// llvm-mc does not do that, so reproduce such sections manually.
+// Use an explicit name of the symbol for the test purpose and because all
+// symbols in the assembly file should have unique names.
+ .section .ARM.exidx.text.foo,"ao?",%0x70000001,.text.foo
+$d.exidx.foo:
+ .reloc 0, R_ARM_NONE, __aeabi_unwind_cpp_pr0
+ .long .text.foo(PREL31)
+ .long 0x80b0b0b0
+
+ .section .text.bar,"axG",%progbits,bar,comdat
+bar:
+ bx lr
+
+// This section is the same as the one for foo so it is a subject to merge.
+ .section .ARM.exidx.text.bar,"ao?",%0x70000001,.text.bar
+$d.exidx.bar:
+ .reloc 0, R_ARM_NONE, __aeabi_unwind_cpp_pr0
+ .long .text.bar(PREL31)
+ .long 0x80b0b0b0
+
+ .section .text.h
+ .global __aeabi_unwind_cpp_pr0
+__aeabi_unwind_cpp_pr0:
+ nop
+ bx lr
Index: lld/ELF/SyntheticSections.h
===================================================================
--- lld/ELF/SyntheticSections.h
+++ lld/ELF/SyntheticSections.h
@@ -585,6 +585,7 @@
unsigned getNumSymbols() const { return symbols.size() + 1; }
size_t getSymbolIndex(Symbol *sym);
ArrayRef<SymbolTableEntry> getSymbols() const { return symbols; }
+ void removeDeadLocalSymbols();
protected:
void sortSymTabSymbols();
Index: lld/ELF/SyntheticSections.cpp
===================================================================
--- lld/ELF/SyntheticSections.cpp
+++ lld/ELF/SyntheticSections.cpp
@@ -2021,6 +2021,21 @@
}
}
+// Remove local symbols which belong to dead sections.
+// The method is used to clean up the table after merging .ARM.exidx sections.
+// The symbols are added earlier than the merging takes place, and it is not
+// known at that time which of them will become dangling. Thus, we first add
+// all the symbols, and eliminate them when the dead sections are known.
+void SymbolTableBaseSection::removeDeadLocalSymbols() {
+ llvm::erase_if(symbols, [](const SymbolTableEntry &s) {
+ if (!s.sym->isLocal())
+ return false;
+ auto *d = dyn_cast<Defined>(s.sym);
+ assert(d);
+ return d->section && !d->section->repl->isLive();
+ });
+}
+
// The ELF spec requires that all local symbols precede global symbols, so we
// sort symbol entries in this function. (For .dynsym, we don't do that because
// symbols for dynamic linking are inherently all globals.)
@@ -3405,6 +3420,15 @@
}
// Size includes Sentinel.
size = offset + 8;
+
+ // Mark merged input .ARM.exidx sections as dead.
+ if (config->mergeArmExidx) {
+ for (InputSection *isec : exidxSections)
+ if (!isec->getParent())
+ isec->markDead();
+ if (in.symTab)
+ in.symTab->removeDeadLocalSymbols();
+ }
}
InputSection *ARMExidxSyntheticSection::getLinkOrderDep() const {
-------------- next part --------------
A non-text attachment was scrubbed...
Name: D78820.259934.patch
Type: text/x-patch
Size: 3441 bytes
Desc: not available
URL: <http://lists.llvm.org/pipermail/llvm-commits/attachments/20200424/1f78c3f9/attachment.bin>
More information about the llvm-commits
mailing list