[llvm] f3471dc - [llvm-objcopy] Preserve ARM and AArch64 mapping symbols
Igor Kudrin via llvm-commits
llvm-commits at lists.llvm.org
Tue Jan 18 23:43:26 PST 2022
Author: Igor Kudrin
Date: 2022-01-19T14:41:21+07:00
New Revision: f3471dc517696b3dcd9a3f3c2c0642dfff499776
URL: https://github.com/llvm/llvm-project/commit/f3471dc517696b3dcd9a3f3c2c0642dfff499776
DIFF: https://github.com/llvm/llvm-project/commit/f3471dc517696b3dcd9a3f3c2c0642dfff499776.diff
LOG: [llvm-objcopy] Preserve ARM and AArch64 mapping symbols
Mapping symbols are required by ARM/AArch64 ELF ABI. They help to
disassemble files correctly and are also used in linkers. Nonetheless,
for executable files, the symbols can be stripped to better resemble
the behavior of GNU's objcopy.
Differential Revision: https://reviews.llvm.org/D117233
Added:
llvm/test/tools/llvm-objcopy/ELF/strip-unneeded-aarch64.test
llvm/test/tools/llvm-objcopy/ELF/strip-unneeded-arm.test
Modified:
llvm/tools/llvm-objcopy/ELF/ELFObjcopy.cpp
Removed:
################################################################################
diff --git a/llvm/test/tools/llvm-objcopy/ELF/strip-unneeded-aarch64.test b/llvm/test/tools/llvm-objcopy/ELF/strip-unneeded-aarch64.test
new file mode 100644
index 0000000000000..4f8c6215cf5fd
--- /dev/null
+++ b/llvm/test/tools/llvm-objcopy/ELF/strip-unneeded-aarch64.test
@@ -0,0 +1,53 @@
+## Check that llvm-objcopy preserves AArch64 mapping symbols for relocatable files.
+# RUN: yaml2obj %s -o %t.o -DTYPE=REL
+# RUN: llvm-objcopy --strip-unneeded %t.o %t1.o
+# RUN: llvm-nm -j --special-syms %t1.o | FileCheck %s --match-full-lines
+# RUN: llvm-objcopy --discard-all %t.o %t2.o
+# RUN: llvm-nm -j --special-syms %t2.o | FileCheck %s --match-full-lines
+
+# CHECK: $d
+# CHECK-NEXT: $d.d
+# CHECK-NEXT: $x
+# CHECK-NEXT: $x.x
+
+## A mapping symbol can be deleted if specified explicitly.
+# RUN: llvm-objcopy -w -N '$d*' %t.o %t3.o
+# RUN: llvm-nm --special-syms %t3.o | FileCheck /dev/null --implicit-check-not='$d'
+
+## Mapping symbols are not preserved for executable files
+# RUN: yaml2obj %s -o %t.exec -DTYPE=EXEC
+# RUN: llvm-objcopy --strip-unneeded %t.exec %t1.exec
+# RUN: llvm-nm --special-syms %t1.exec | count 0
+
+# RUN: yaml2obj %s -o %t.so -DTYPE=DYN
+# RUN: llvm-objcopy --strip-unneeded %t.so %t1.so
+# RUN: llvm-nm --special-syms %t1.so | count 0
+
+!ELF
+FileHeader:
+ Class: ELFCLASS64
+ Data: ELFDATA2LSB
+ Type: ET_[[TYPE]]
+ Machine: EM_AARCH64
+Sections:
+ - Name: .text
+ Type: SHT_PROGBITS
+Symbols:
+ - Name: $a
+ Section: .text
+ - Name: $d
+ Section: .text
+ - Name: $dd
+ Section: .text
+ - Name: $d.d
+ Section: .text
+ - Name: $m
+ Section: .text
+ - Name: $t.t
+ Section: .text
+ - Name: $x
+ Section: .text
+ - Name: $xx
+ Section: .text
+ - Name: $x.x
+ Section: .text
diff --git a/llvm/test/tools/llvm-objcopy/ELF/strip-unneeded-arm.test b/llvm/test/tools/llvm-objcopy/ELF/strip-unneeded-arm.test
new file mode 100644
index 0000000000000..c6160cf8aff6c
--- /dev/null
+++ b/llvm/test/tools/llvm-objcopy/ELF/strip-unneeded-arm.test
@@ -0,0 +1,60 @@
+## Check that llvm-objcopy preserves ARM mapping symbols for relocatable files.
+# RUN: yaml2obj %s -o %t.o -DTYPE=REL
+# RUN: llvm-objcopy --strip-unneeded %t.o %t1.o
+# RUN: llvm-nm -j --special-syms %t1.o | FileCheck %s --match-full-lines
+# RUN: llvm-objcopy --discard-all %t.o %t2.o
+# RUN: llvm-nm -j --special-syms %t2.o | FileCheck %s --match-full-lines
+
+# CHECK: $a
+# CHECK-NEXT: $a.a
+# CHECK-NEXT: $d
+# CHECK-NEXT: $d.d
+# CHECK-NEXT: $t
+# CHECK-NEXT: $t.t
+# CHECK-NOT: $x
+
+## A mapping symbol can be deleted if specified explicitly.
+# RUN: llvm-objcopy -w -N '$d*' %t.o %t3.o
+# RUN: llvm-nm --special-syms %t3.o | FileCheck /dev/null --implicit-check-not='$d'
+
+## Mapping symbols are not preserved for executable files
+# RUN: yaml2obj %s -o %t.exec -DTYPE=EXEC
+# RUN: llvm-objcopy --strip-unneeded %t.exec %t1.exec
+# RUN: llvm-nm --special-syms %t1.exec | count 0
+
+# RUN: yaml2obj %s -o %t.so -DTYPE=DYN
+# RUN: llvm-objcopy --strip-unneeded %t.so %t1.so
+# RUN: llvm-nm --special-syms %t1.so | count 0
+
+!ELF
+FileHeader:
+ Class: ELFCLASS32
+ Data: ELFDATA2LSB
+ Type: ET_[[TYPE]]
+ Machine: EM_ARM
+Sections:
+ - Name: .text
+ Type: SHT_PROGBITS
+Symbols:
+ - Name: $a
+ Section: .text
+ - Name: $aa
+ Section: .text
+ - Name: $a.a
+ Section: .text
+ - Name: $d
+ Section: .text
+ - Name: $dd
+ Section: .text
+ - Name: $d.d
+ Section: .text
+ - Name: $m
+ Section: .text
+ - Name: $t
+ Section: .text
+ - Name: $tt
+ Section: .text
+ - Name: $t.t
+ Section: .text
+ - Name: $x
+ Section: .text
diff --git a/llvm/tools/llvm-objcopy/ELF/ELFObjcopy.cpp b/llvm/tools/llvm-objcopy/ELF/ELFObjcopy.cpp
index 16de84a961b5c..f8521fa0d5b70 100644
--- a/llvm/tools/llvm-objcopy/ELF/ELFObjcopy.cpp
+++ b/llvm/tools/llvm-objcopy/ELF/ELFObjcopy.cpp
@@ -227,6 +227,41 @@ static Error replaceDebugSections(
return Obj.replaceSections(FromTo);
}
+static bool isAArch64MappingSymbol(const Symbol &Sym) {
+ if (Sym.Binding != STB_LOCAL || Sym.Type != STT_NOTYPE ||
+ Sym.getShndx() == SHN_UNDEF)
+ return false;
+ StringRef Name = Sym.Name;
+ if (!Name.consume_front("$x") && !Name.consume_front("$d"))
+ return false;
+ return Name.empty() || Name.startswith(".");
+}
+
+static bool isArmMappingSymbol(const Symbol &Sym) {
+ if (Sym.Binding != STB_LOCAL || Sym.Type != STT_NOTYPE ||
+ Sym.getShndx() == SHN_UNDEF)
+ return false;
+ StringRef Name = Sym.Name;
+ if (!Name.consume_front("$a") && !Name.consume_front("$d") &&
+ !Name.consume_front("$t"))
+ return false;
+ return Name.empty() || Name.startswith(".");
+}
+
+// Check if the symbol should be preserved because it is required by ABI.
+static bool isRequiredByABISymbol(const Object &Obj, const Symbol &Sym) {
+ switch (Obj.Machine) {
+ case EM_AARCH64:
+ // Mapping symbols should be preserved for a relocatable object file.
+ return Obj.isRelocatable() && isAArch64MappingSymbol(Sym);
+ case EM_ARM:
+ // Mapping symbols should be preserved for a relocatable object file.
+ return Obj.isRelocatable() && isArmMappingSymbol(Sym);
+ default:
+ return false;
+ }
+}
+
static bool isUnneededSymbol(const Symbol &Sym) {
return !Sym.Referenced &&
(Sym.Binding == STB_LOCAL || Sym.getShndx() == SHN_UNDEF) &&
@@ -297,20 +332,23 @@ static Error updateAndRemoveSymbols(const CommonConfig &Config,
(ELFConfig.KeepFileSymbols && Sym.Type == STT_FILE))
return false;
- if ((Config.DiscardMode == DiscardType::All ||
- (Config.DiscardMode == DiscardType::Locals &&
- StringRef(Sym.Name).startswith(".L"))) &&
- Sym.Binding == STB_LOCAL && Sym.getShndx() != SHN_UNDEF &&
- Sym.Type != STT_FILE && Sym.Type != STT_SECTION)
+ if (Config.SymbolsToRemove.matches(Sym.Name))
return true;
if (Config.StripAll || Config.StripAllGNU)
return true;
+ if (isRequiredByABISymbol(Obj, Sym))
+ return false;
+
if (Config.StripDebug && Sym.Type == STT_FILE)
return true;
- if (Config.SymbolsToRemove.matches(Sym.Name))
+ if ((Config.DiscardMode == DiscardType::All ||
+ (Config.DiscardMode == DiscardType::Locals &&
+ StringRef(Sym.Name).startswith(".L"))) &&
+ Sym.Binding == STB_LOCAL && Sym.getShndx() != SHN_UNDEF &&
+ Sym.Type != STT_FILE && Sym.Type != STT_SECTION)
return true;
if ((Config.StripUnneeded ||
More information about the llvm-commits
mailing list