[llvm-symbolizer][llvm-nm] Fix AArch64 and ARM mapping symbols handling.

Exclude AArch64 mapping symbols ($x and $d) for symtab symbolization as
it was done for ARM since D95916 tom bring bots back to green state.

This is implemented by setting SF_FormatSpecific such that
llvm-symbolizer will ignore them, and use this flag to re-implement
llvm-nm --special-syms option which make it work for both targets.

Differential Revision: https://reviews.llvm.org/D98803
This commit is contained in:
Yvan Roux 2021-03-23 14:09:49 +01:00
parent d709dcc090
commit 241032a205
6 changed files with 108 additions and 23 deletions

View File

@ -716,7 +716,16 @@ Expected<uint32_t> ELFObjectFile<ELFT>::getSymbolFlags(DataRefImpl Sym) const {
// TODO: Test this error.
return SymbolsOrErr.takeError();
if (EF.getHeader().e_machine == ELF::EM_ARM) {
if (EF.getHeader().e_machine == ELF::EM_AARCH64) {
if (Expected<StringRef> NameOrErr = getSymbolName(Sym)) {
StringRef Name = *NameOrErr;
if (Name.startswith("$d") || Name.startswith("$x"))
Result |= SymbolRef::SF_FormatSpecific;
} else {
// TODO: Actually report errors helpfully.
consumeError(NameOrErr.takeError());
}
} else if (EF.getHeader().e_machine == ELF::EM_ARM) {
if (Expected<StringRef> NameOrErr = getSymbolName(Sym)) {
StringRef Name = *NameOrErr;
if (Name.startswith("$d") || Name.startswith("$t") ||

View File

@ -0,0 +1,31 @@
# REQUIRES: aarch64-registered-target
## Ignore AArch64 mapping symbols (with a prefix of $d or $x).
# RUN: llvm-mc -filetype=obj -triple=aarch64 %s -o %t
## Verify that mapping symbols are actually present in the object at expected
## addresses.
# RUN: llvm-nm --special-syms %t | FileCheck %s -check-prefix MAPPING_SYM
# MAPPING_SYM: 0000000000000000 t $d.0
# MAPPING_SYM-NEXT: 000000000000000c t $d.2
# MAPPING_SYM-NEXT: 0000000000000004 t $x.1
# MAPPING_SYM-NEXT: 0000000000000000 T foo
# RUN: llvm-symbolizer --obj=%t 0 4 0xc | FileCheck %s -check-prefix SYMBOL
# SYMBOL: foo
# SYMBOL-NEXT: ??:0:0
# SYMBOL-EMPTY:
# SYMBOL: foo
# SYMBOL-NEXT: ??:0:0
# SYMBOL-EMPTY:
# SYMBOL: foo
# SYMBOL-NEXT: ??:0:0
.global foo
foo:
.word 32
nop
nop
.word 42

View File

@ -2,15 +2,32 @@
## Ignore ARM mapping symbols (with a prefix of $a, $d or $t).
# RUN: llvm-mc -filetype=obj -triple=armv7-none-linux %s -o %t
# RUN: llvm-symbolizer --obj=%t 4 8 | FileCheck %s
# RUN: llvm-mc -filetype=obj -triple=thumbv7-none-linux %s -o %tthumb
# RUN: llvm-symbolizer --obj=%tthumb 4 8 | FileCheck %s
# CHECK: foo
# CHECK-NEXT: ??:0:0
# CHECK-EMPTY:
# CHECK-NEXT: foo
# CHECK-NEXT: ??:0:0
## Verify that mapping symbols are actually present in the object at expected
## addresses.
# RUN: llvm-nm --special-syms %t | FileCheck %s -check-prefix MAPPING_A
# MAPPING_A: 00000004 t $a.1
# MAPPING_A-NEXT: 00000000 t $d.0
# MAPPING_A-NEXT: 00000008 t $d.2
# MAPPING_A-NEXT: 00000000 T foo
# RUN: llvm-mc -filetype=obj -triple=thumbv7-none-linux %s -o %tthumb
# RUN: llvm-nm --special-syms %tthumb | FileCheck %s -check-prefix MAPPING_T
# MAPPING_T: 00000000 t $d.0
# MAPPING_T-NEXT: 00000006 t $d.2
# MAPPING_T-NEXT: 00000004 t $t.1
# MAPPING_T-NEXT: 00000000 T foo
# RUN: llvm-symbolizer --obj=%t 4 8 | FileCheck %s -check-prefix SYMBOL
# RUN: llvm-symbolizer --obj=%tthumb 4 8 | FileCheck %s -check-prefix SYMBOL
# SYMBOL: foo
# SYMBOL-NEXT: ??:0:0
# SYMBOL-EMPTY:
# SYMBOL-NEXT: foo
# SYMBOL-NEXT: ??:0:0
.globl foo
foo:

View File

@ -0,0 +1,30 @@
## Test --special-syms flag for ARM mapping symbols used to mark transitions
## between ARM code, THUMB code and data ($a, $t, $t).
#
# RUN: yaml2obj %s -o %t
# RUN: llvm-nm %t | count 0
# RUN: llvm-nm --special-syms %t | FileCheck %s
!ELF
FileHeader:
Class: ELFCLASS32
Data: ELFDATA2LSB
Type: ET_REL
Machine: EM_ARM
Flags: [ EF_ARM_EABI_VER5 ]
Sections:
- Name: .text
Type: SHT_PROGBITS
Flags: [ SHF_ALLOC, SHF_EXECINSTR ]
AddressAlign: 0x4
Symbols:
- Name: '$d.0'
Section: .text
- Name: '$a.1'
Section: .text
- Name: '$t.1'
Section: .text
# CHECK: 00000000 t $a.1
# CHECK: 00000000 t $d.0
# CHECK: 00000000 t $t.1

View File

@ -1,6 +1,6 @@
# RUN: yaml2obj %s -o %t.o
# RUN: llvm-nm --special-syms --debug-syms %t.o | FileCheck %s --implicit-check-not {{.}} --check-prefix SYMBOL
# RUN: llvm-nm --special-syms -a %t.o | FileCheck %s --implicit-check-not {{.}} --check-prefix SYMBOL
# RUN: llvm-nm --debug-syms %t.o | FileCheck %s --implicit-check-not {{.}} --check-prefix SYMBOL
# RUN: llvm-nm -a %t.o | FileCheck %s --implicit-check-not {{.}} --check-prefix SYMBOL
# SYMBOL: 0000000000000000 n $a
# SYMBOL-NEXT: 0000000000000000 n $d

View File

@ -742,16 +742,6 @@ static void writeFileName(raw_ostream &S, StringRef ArchiveName,
}
}
static bool isSpecialSym(SymbolicFile &Obj, StringRef Name) {
auto *ELFObj = dyn_cast<ELFObjectFileBase>(&Obj);
if (!ELFObj)
return false;
uint16_t EMachine = ELFObj->getEMachine();
if (EMachine != ELF::EM_ARM && EMachine != ELF::EM_AARCH64)
return false;
return !Name.empty() && Name[0] == '$';
}
static void sortAndPrintSymbolList(SymbolicFile &Obj, bool printName,
StringRef ArchiveName,
StringRef ArchitectureName) {
@ -840,9 +830,10 @@ static void sortAndPrintSymbolList(SymbolicFile &Obj, bool printName,
bool Undefined = SymFlags & SymbolRef::SF_Undefined;
bool Global = SymFlags & SymbolRef::SF_Global;
bool Weak = SymFlags & SymbolRef::SF_Weak;
bool FormatSpecific = SymFlags & SymbolRef::SF_FormatSpecific;
if ((!Undefined && UndefinedOnly) || (Undefined && DefinedOnly) ||
(!Global && ExternalOnly) || (Weak && NoWeakSymbols) ||
(!SpecialSyms && isSpecialSym(Obj, Name)))
(FormatSpecific && !(SpecialSyms || DebugSyms)))
continue;
if (PrintFileName)
writeFileName(outs(), ArchiveName, ArchitectureName);
@ -1812,7 +1803,14 @@ static void dumpSymbolNamesFromObject(SymbolicFile &Obj, bool printName,
error(SymFlagsOrErr.takeError(), Obj.getFileName());
return;
}
if (!DebugSyms && (*SymFlagsOrErr & SymbolRef::SF_FormatSpecific))
// Don't drop format specifc symbols for ARM and AArch64 ELF targets, they
// are used to repesent mapping symbols and needed to honor the
// --special-syms option.
auto *ELFObj = dyn_cast<ELFObjectFileBase>(&Obj);
if ((!ELFObj || (ELFObj->getEMachine() != ELF::EM_ARM &&
ELFObj->getEMachine() != ELF::EM_AARCH64)) &&
!DebugSyms && (*SymFlagsOrErr & SymbolRef::SF_FormatSpecific))
continue;
if (WithoutAliases && (*SymFlagsOrErr & SymbolRef::SF_Indirect))
continue;