From 27e877c837fba5645f949fd007d9575fb35ad92e Mon Sep 17 00:00:00 2001 From: Fangrui Song Date: Thu, 9 May 2019 12:43:37 +0000 Subject: [PATCH] [llvm-nm] Fix handling of symbol types 't' 'd' 'r' This restores part of r359311 that was reverted by r359830. Rewrite the symbol types to fix several issues. Notable difference is that the type of __init_array_start changes from 't' to 'd'. GNU nm used to mark ELF symbols relative to .init_array as 't' https://sourceware.org/bugzilla/show_bug.cgi?id=24505 (before 2.33) because ".init" is the prefix. The bug was copied by r287803. Reviewed By: jhenderson Differential Revision: https://reviews.llvm.org/D61551 git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@360339 91177308-0d34-0410-b5e6-96231b3b80d8 --- test/ThinLTO/X86/strong_non_prevailing.ll | 4 +- .../X86/Inputs/init-fini.out.elf-x86_64 | Bin 904 -> 0 bytes test/tools/llvm-nm/X86/init-fini.test | 8 --- test/tools/llvm-nm/data.test | 43 +++++++++++++ test/tools/llvm-nm/linker-synthesized.test | 57 ++++++++++++++++++ test/tools/llvm-nm/nobits.test | 35 +++++++++++ test/tools/llvm-nm/nonalloc.test | 17 ++++++ test/tools/llvm-nm/readonly.test | 43 +++++++++++++ tools/llvm-nm/llvm-nm.cpp | 27 +++------ 9 files changed, 204 insertions(+), 30 deletions(-) delete mode 100755 test/tools/llvm-nm/X86/Inputs/init-fini.out.elf-x86_64 delete mode 100644 test/tools/llvm-nm/X86/init-fini.test create mode 100644 test/tools/llvm-nm/data.test create mode 100644 test/tools/llvm-nm/linker-synthesized.test create mode 100644 test/tools/llvm-nm/nobits.test create mode 100644 test/tools/llvm-nm/nonalloc.test create mode 100644 test/tools/llvm-nm/readonly.test diff --git a/test/ThinLTO/X86/strong_non_prevailing.ll b/test/ThinLTO/X86/strong_non_prevailing.ll index f96e23adc3d..214af649fcf 100644 --- a/test/ThinLTO/X86/strong_non_prevailing.ll +++ b/test/ThinLTO/X86/strong_non_prevailing.ll @@ -12,5 +12,5 @@ $__llvm_profile_filename = comdat any @__llvm_profile_filename = constant [19 x i8] c"default_%m.profraw\00", comdat -; EXPORTED: N __llvm_profile_filename -; NOT_EXPORTED-NOT: N __llvm_profile_filename +; EXPORTED: R __llvm_profile_filename +; NOT_EXPORTED-NOT: R __llvm_profile_filename diff --git a/test/tools/llvm-nm/X86/Inputs/init-fini.out.elf-x86_64 b/test/tools/llvm-nm/X86/Inputs/init-fini.out.elf-x86_64 deleted file mode 100755 index b5c74f234c609b4336cb5e64dee4868c57a0422f..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 904 zcmbu7u}%Xq42J*Ssnvl50wyFD7+8>~#MTLQfr)nrsd^F}=x~>TPP___(77X1AEA%X z$G~>%UPyt3NV(ts;@D0u?+;IpMXv`N1@6J#5@SK}3si-;%0?(?eSlJ8``r>*WA&o0 z)H4Mxg>a1lP2(#(3pcIAqq?fLZ`-E?+e)+S7XLK3OFK^*Skfu1o^kFA#6Ptk<7dkA z_#5IUKjgm_zMtpr7k;FCoz;bNv-vDI-!y*V>iP6LXoGJ8p-J01wd<)59vHTZ*Wf3l zp^5rpR;b?shFw}J{qJ!>8Tjt_pYpK#UPc#(swVNC%>%B;Jf>MHvU|4o(Y=EhkncZD v_G$`|jRxMPknDUv`^gjEMX%M`sPbFqY5kllKOnW<6^VRkp-~FS&g*{xFyBCt diff --git a/test/tools/llvm-nm/X86/init-fini.test b/test/tools/llvm-nm/X86/init-fini.test deleted file mode 100644 index 86afc711c4e..00000000000 --- a/test/tools/llvm-nm/X86/init-fini.test +++ /dev/null @@ -1,8 +0,0 @@ -# RUN: llvm-nm -B -S %p/Inputs/init-fini.out.elf-x86_64 | FileCheck --match-full-lines %s - -CHECK: 00000000006000c2 0000000000000000 T __bss_start -CHECK: 00000000006000c2 0000000000000000 t __init_array_end -CHECK: 00000000006000ba 0000000000000000 t __init_array_start -CHECK: 00000000006000c2 0000000000000000 T _edata -CHECK: 00000000006000c8 0000000000000000 T _end -CHECK: 00000000004000b0 0000000000000000 T _start diff --git a/test/tools/llvm-nm/data.test b/test/tools/llvm-nm/data.test new file mode 100644 index 00000000000..c86f284e5f8 --- /dev/null +++ b/test/tools/llvm-nm/data.test @@ -0,0 +1,43 @@ +# RUN: yaml2obj %s -o %t +# RUN: llvm-nm --no-sort %t | FileCheck %s + +# CHECK: b mybss_local +# CHECK-NEXT: d mydata_local +# CHECK-NEXT: d mytdata_local +# CHECK-NEXT: B mybss_global +# CHECK-NEXT: D mydata_global +# CHECK-NEXT: D mytdata_global + +!ELF +FileHeader: + Class: ELFCLASS64 + Data: ELFDATA2LSB + Type: ET_EXEC + Machine: EM_X86_64 +Sections: + - Name: mybss + Type: SHT_NOBITS + Flags: [ SHF_ALLOC, SHF_WRITE ] + - Name: mydata + Type: SHT_PROGBITS + Flags: [ SHF_ALLOC, SHF_WRITE ] + - Name: mytdata + Type: SHT_PROGBITS + Flags: [ SHF_ALLOC, SHF_WRITE, SHF_TLS ] +Symbols: + - Name: mybss_local + Section: mybss + - Name: mydata_local + Section: mydata + - Name: mytdata_local + Section: mytdata + + - Name: mybss_global + Binding: STB_GLOBAL + Section: mybss + - Name: mydata_global + Binding: STB_GLOBAL + Section: mydata + - Name: mytdata_global + Binding: STB_GLOBAL + Section: mytdata diff --git a/test/tools/llvm-nm/linker-synthesized.test b/test/tools/llvm-nm/linker-synthesized.test new file mode 100644 index 00000000000..7f9e88718de --- /dev/null +++ b/test/tools/llvm-nm/linker-synthesized.test @@ -0,0 +1,57 @@ +# RUN: yaml2obj %s -o %t +# RUN: llvm-nm --no-sort %t | FileCheck %s + +## We used to be wrong with some linker synthesized symbols. + +## We mark __init_array_start as 'd', as consistent with GNU nm >= 2.33 (older GNU +## nm marks it as 't'). See https://sourceware.org/bugzilla/show_bug.cgi?id=24511 + +# CHECK: d __fini_array_start +# CHECK: d __init_array_start +# CHECK: d __preinit_array_start +# CHECK: B __bss_start +# CHECK: D _edata +# CHECK: B _end + +!ELF +FileHeader: + Class: ELFCLASS64 + Data: ELFDATA2LSB + Type: ET_EXEC + Machine: EM_X86_64 +Sections: + - Name: .text + Type: SHT_PROGBITS + Flags: [ SHF_ALLOC, SHF_EXECINSTR ] + - Name: .fini_array + Type: SHT_FINI_ARRAY + Flags: [ SHF_ALLOC, SHF_WRITE ] + - Name: .init_array + Type: SHT_INIT_ARRAY + Flags: [ SHF_ALLOC, SHF_WRITE ] + - Name: .preinit_array + Type: SHT_PREINIT_ARRAY + Flags: [ SHF_ALLOC, SHF_WRITE ] + - Name: .data + Type: SHT_PROGBITS + Flags: [ SHF_ALLOC, SHF_WRITE ] + - Name: .bss + Type: SHT_NOBITS + Flags: [ SHF_ALLOC, SHF_WRITE ] +Symbols: + - Name: __fini_array_start + Section: .fini_array + - Name: __init_array_start + Section: .init_array + - Name: __preinit_array_start + Section: .preinit_array + + - Name: __bss_start + Section: .bss + Binding: STB_GLOBAL + - Name: _edata + Section: .data + Binding: STB_GLOBAL + - Name: _end + Section: .bss + Binding: STB_GLOBAL diff --git a/test/tools/llvm-nm/nobits.test b/test/tools/llvm-nm/nobits.test new file mode 100644 index 00000000000..ad07e3ddaf2 --- /dev/null +++ b/test/tools/llvm-nm/nobits.test @@ -0,0 +1,35 @@ +# RUN: yaml2obj %s -o %t +# RUN: llvm-nm --no-sort %t | FileCheck %s + +# CHECK: b mybss_local +# CHECK: b mytbss_local +# CHECK: B mybss_global +# CHECK: B mytbss_global + +!ELF +FileHeader: + Class: ELFCLASS64 + Data: ELFDATA2LSB + Type: ET_REL + Machine: EM_X86_64 +Sections: + - Name: mybss + Type: SHT_NOBITS + Flags: [ SHF_ALLOC, SHF_WRITE ] + - Name: mytbss + Type: SHT_NOBITS + Flags: [ SHF_ALLOC, SHF_WRITE, SHF_TLS ] +Symbols: + - Name: mybss_local + Binding: STB_LOCAL + Section: mybss + - Name: mytbss_local + Binding: STB_LOCAL + Section: mytbss + + - Name: mybss_global + Binding: STB_GLOBAL + Section: mybss + - Name: mytbss_global + Binding: STB_GLOBAL + Section: mytbss diff --git a/test/tools/llvm-nm/nonalloc.test b/test/tools/llvm-nm/nonalloc.test new file mode 100644 index 00000000000..c8fe432efaa --- /dev/null +++ b/test/tools/llvm-nm/nonalloc.test @@ -0,0 +1,17 @@ +# RUN: yaml2obj %s -o %t +# RUN: llvm-nm --no-sort %t | FileCheck %s + +# CHECK: n debug_info_main + +!ELF +FileHeader: + Class: ELFCLASS64 + Data: ELFDATA2LSB + Type: ET_REL + Machine: EM_X86_64 +Sections: + - Name: .debug_info + Type: SHT_PROGBITS +Symbols: + - Name: debug_info_main + Section: .debug_info diff --git a/test/tools/llvm-nm/readonly.test b/test/tools/llvm-nm/readonly.test new file mode 100644 index 00000000000..853f9f2b3d1 --- /dev/null +++ b/test/tools/llvm-nm/readonly.test @@ -0,0 +1,43 @@ +# RUN: yaml2obj %s -o %t +# RUN: llvm-nm --no-sort %t | FileCheck %s + +# CHECK: r myrodata0_local +# CHECK-NEXT: r myrodata1_local +# CHECK-NEXT: r myrodata2_local +# CHECK-NEXT: R myrodata0_global +# CHECK-NEXT: R myrodata1_global +# CHECK-NEXT: R myrodata2_global + +!ELF +FileHeader: + Class: ELFCLASS64 + Data: ELFDATA2LSB + Type: ET_EXEC + Machine: EM_X86_64 +Sections: + - Name: myrodata0 + Type: SHT_PROGBITS + Flags: [ SHF_ALLOC ] + - Name: myrodata1 + Type: SHT_PROGBITS + Flags: [ SHF_ALLOC, SHF_MERGE ] + - Name: myrodata2 + Type: SHT_PROGBITS + Flags: [ SHF_ALLOC, SHF_MERGE, SHF_STRINGS ] +Symbols: + - Name: myrodata0_local + Section: myrodata0 + - Name: myrodata1_local + Section: myrodata1 + - Name: myrodata2_local + Section: myrodata2 + + - Name: myrodata0_global + Binding: STB_GLOBAL + Section: myrodata0 + - Name: myrodata1_global + Binding: STB_GLOBAL + Section: myrodata1 + - Name: myrodata2_global + Binding: STB_GLOBAL + Section: myrodata2 diff --git a/tools/llvm-nm/llvm-nm.cpp b/tools/llvm-nm/llvm-nm.cpp index 651a8b30975..d7ac98c5b2c 100644 --- a/tools/llvm-nm/llvm-nm.cpp +++ b/tools/llvm-nm/llvm-nm.cpp @@ -901,27 +901,14 @@ static char getSymbolNMTypeChar(ELFObjectFileBase &Obj, elf_section_iterator SecI = *SecIOrErr; if (SecI != Obj.section_end()) { - switch (SecI->getType()) { - case ELF::SHT_PROGBITS: - case ELF::SHT_DYNAMIC: - switch (SecI->getFlags()) { - case (ELF::SHF_ALLOC | ELF::SHF_EXECINSTR): - return 't'; - case (ELF::SHF_TLS | ELF::SHF_ALLOC | ELF::SHF_WRITE): - case (ELF::SHF_ALLOC | ELF::SHF_WRITE): - return 'd'; - case ELF::SHF_ALLOC: - case (ELF::SHF_ALLOC | ELF::SHF_MERGE): - case (ELF::SHF_ALLOC | ELF::SHF_MERGE | ELF::SHF_STRINGS): - return 'r'; - } - break; - case ELF::SHT_NOBITS: - return 'b'; - case ELF::SHT_INIT_ARRAY: - case ELF::SHT_FINI_ARRAY: + uint32_t Type = SecI->getType(); + uint64_t Flags = SecI->getFlags(); + if (Flags & ELF::SHF_EXECINSTR) return 't'; - } + if (Type == ELF::SHT_NOBITS) + return 'b'; + if (Flags & ELF::SHF_ALLOC) + return Flags & ELF::SHF_WRITE ? 'd' : 'r'; } if (SymI->getELFType() == ELF::STT_SECTION) { -- 2.50.1