diff options
| author | Rafael Espindola <rafael.espindola@gmail.com> | 2015-10-05 15:24:04 +0000 |
|---|---|---|
| committer | Rafael Espindola <rafael.espindola@gmail.com> | 2015-10-05 15:24:04 +0000 |
| commit | 4f674ed1387cf1aa484e80edead2fafbb86d5847 (patch) | |
| tree | a84c213210ad773c6c154a5d416fb864405d84e0 | |
| parent | 953f908173e353fd26053b960a5b52f8e23de2e1 (diff) | |
| download | bcm5719-llvm-4f674ed1387cf1aa484e80edead2fafbb86d5847.tar.gz bcm5719-llvm-4f674ed1387cf1aa484e80edead2fafbb86d5847.zip | |
Include hidden and internal symbols in the regular symbol table.
This matches the behavior of bfd ld and gold. It is also convenient for
testing other changes.
llvm-svn: 249323
| -rw-r--r-- | lld/ELF/OutputSections.cpp | 38 | ||||
| -rw-r--r-- | lld/ELF/OutputSections.h | 3 | ||||
| -rw-r--r-- | lld/ELF/Writer.cpp | 2 | ||||
| -rw-r--r-- | lld/test/elf2/string-table.s | 7 | ||||
| -rw-r--r-- | lld/test/elf2/symbols.s | 18 | ||||
| -rw-r--r-- | lld/test/elf2/visibility.s | 63 |
6 files changed, 107 insertions, 24 deletions
diff --git a/lld/ELF/OutputSections.cpp b/lld/ELF/OutputSections.cpp index c9a353b666e..c74e4631e3b 100644 --- a/lld/ELF/OutputSections.cpp +++ b/lld/ELF/OutputSections.cpp @@ -384,18 +384,25 @@ void StringTableSection<Is64Bits>::writeTo(uint8_t *Buf) { memcpy(Buf, Data.data(), Data.size()); } -bool lld::elf2::includeInSymtab(const SymbolBody &B) { +template <class ELFT> bool lld::elf2::includeInSymtab(const SymbolBody &B) { if (B.isLazy()) return false; if (!B.isUsedInRegularObj()) return false; - uint8_t V = B.getMostConstrainingVisibility(); - if (V != STV_DEFAULT && V != STV_PROTECTED) - return false; + + // Don't include synthetic symbols like __init_array_start in every output. + if (auto *U = dyn_cast<DefinedAbsolute<ELFT>>(&B)) + if (&U->Sym == &DefinedAbsolute<ELFT>::IgnoreUndef) + return false; + return true; } bool lld::elf2::includeInDynamicSymtab(const SymbolBody &B) { + uint8_t V = B.getMostConstrainingVisibility(); + if (V != STV_DEFAULT && V != STV_PROTECTED) + return false; + if (Config->ExportDynamic || Config->Shared) return true; return B.isUsedInDynamicReloc(); @@ -475,11 +482,12 @@ template <class ELFT> void SymbolTableSection<ELFT>::writeGlobalSymbols(uint8_t *&Buf) { // Write the internal symbol table contents to the output symbol table // pointed by Buf. + uint8_t *Start = Buf; for (const std::pair<StringRef, Symbol *> &P : Table.getSymbols()) { StringRef Name = P.first; Symbol *Sym = P.second; SymbolBody *Body = Sym->Body; - if (!includeInSymtab(*Body)) + if (!includeInSymtab<ELFT>(*Body)) continue; if (StrTabSec.isDynamic() && !includeInDynamicSymtab(*Body)) continue; @@ -511,9 +519,14 @@ void SymbolTableSection<ELFT>::writeGlobalSymbols(uint8_t *&Buf) { llvm_unreachable("Lazy symbol got to output symbol table!"); } - ESym->setBindingAndType(InputSym.getBinding(), InputSym.getType()); + unsigned char Binding = InputSym.getBinding(); + unsigned char Visibility = EBody.getMostConstrainingVisibility(); + if (Visibility != STV_DEFAULT && Visibility != STV_PROTECTED) + Binding = STB_LOCAL; + + ESym->setBindingAndType(Binding, InputSym.getType()); ESym->st_size = InputSym.st_size; - ESym->setVisibility(EBody.getMostConstrainingVisibility()); + ESym->setVisibility(Visibility); if (InputSym.isAbsolute()) { ESym->st_shndx = SHN_ABS; ESym->st_value = InputSym.st_value; @@ -527,6 +540,12 @@ void SymbolTableSection<ELFT>::writeGlobalSymbols(uint8_t *&Buf) { if (Out) ESym->st_shndx = Out->getSectionIndex(); } + if (!StrTabSec.isDynamic()) + std::stable_sort( + reinterpret_cast<Elf_Sym *>(Start), reinterpret_cast<Elf_Sym *>(Buf), + [](const Elf_Sym &A, const Elf_Sym &B) -> bool { + return A.getBinding() == STB_LOCAL && B.getBinding() != STB_LOCAL; + }); } namespace lld { @@ -607,5 +626,10 @@ getLocalSymVA(const ELFFile<ELF64LE>::Elf_Sym *, const ObjectFile<ELF64LE> &); template ELFFile<ELF64BE>::uintX_t getLocalSymVA(const ELFFile<ELF64BE>::Elf_Sym *, const ObjectFile<ELF64BE> &); + +template bool includeInSymtab<ELF32LE>(const SymbolBody &); +template bool includeInSymtab<ELF32BE>(const SymbolBody &); +template bool includeInSymtab<ELF64LE>(const SymbolBody &); +template bool includeInSymtab<ELF64BE>(const SymbolBody &); } } diff --git a/lld/ELF/OutputSections.h b/lld/ELF/OutputSections.h index 5e2119630d7..af81de0c7db 100644 --- a/lld/ELF/OutputSections.h +++ b/lld/ELF/OutputSections.h @@ -41,7 +41,8 @@ typename llvm::object::ELFFile<ELFT>::uintX_t getLocalSymVA(const typename llvm::object::ELFFile<ELFT>::Elf_Sym *Sym, const ObjectFile<ELFT> &File); -bool includeInSymtab(const SymbolBody &B); +template <class ELFT> bool includeInSymtab(const SymbolBody &B); + bool includeInDynamicSymtab(const SymbolBody &B); bool shouldKeepInSymtab(StringRef SymName); diff --git a/lld/ELF/Writer.cpp b/lld/ELF/Writer.cpp index 4fadfd237f4..105abd7b069 100644 --- a/lld/ELF/Writer.cpp +++ b/lld/ELF/Writer.cpp @@ -341,7 +341,7 @@ template <class ELFT> void Writer<ELFT>::createSections() { if (auto *C = dyn_cast<DefinedCommon<ELFT>>(Body)) CommonSymbols.push_back(C); - if (!includeInSymtab(*Body)) + if (!includeInSymtab<ELFT>(*Body)) continue; SymTabSec.addSymbol(Name); diff --git a/lld/test/elf2/string-table.s b/lld/test/elf2/string-table.s index 2e8d9d0f693..666c649835c 100644 --- a/lld/test/elf2/string-table.s +++ b/lld/test/elf2/string-table.s @@ -6,10 +6,6 @@ .global _start _start: -.global hidden -.hidden hidden -hidden: - .section foobar,"",@progbits,unique,1 .section foobar,"T",@progbits,unique,2 .section foobar,"",@nobits,unique,3 @@ -46,8 +42,7 @@ hidden: // CHECK-NOT: Name: foobar -// Test that the sting "bar" is merged into "foobar" and that we don't output -// the name of a hidden symbol. +// Test that the string "bar" is merged into "foobar". // CHECK: Section { // CHECK: Index: diff --git a/lld/test/elf2/symbols.s b/lld/test/elf2/symbols.s index 27e6fb7d16b..8b7286c2093 100644 --- a/lld/test/elf2/symbols.s +++ b/lld/test/elf2/symbols.s @@ -80,6 +80,24 @@ internal: // CHECK-NEXT: Other: 0 // CHECK-NEXT: Section: Undefined (0x0) // CHECK-NEXT: } +// CHECK-NEXT: Symbol { +// CHECK-NEXT: Name: hidden +// CHECK-NEXT: Value: 0x11008 +// CHECK-NEXT: Size: 0 +// CHECK-NEXT: Binding: Local +// CHECK-NEXT: Type: None +// CHECK-NEXT: Other: 2 +// CHECK-NEXT: Section: foobar +// CHECK-NEXT: } +// CHECK-NEXT: Symbol { +// CHECK-NEXT: Name: internal +// CHECK-NEXT: Value: 0x11008 +// CHECK-NEXT: Size: 0 +// CHECK-NEXT: Binding: Local +// CHECK-NEXT: Type: None +// CHECK-NEXT: Other: 1 +// CHECK-NEXT: Section: foobar +// CHECK-NEXT: } // CHECK-NEXT: Symbol { // CHECK-NEXT: Name: _start // CHECK-NEXT: Value: 0x12000 diff --git a/lld/test/elf2/visibility.s b/lld/test/elf2/visibility.s index f9015fd816d..941561e9699 100644 --- a/lld/test/elf2/visibility.s +++ b/lld/test/elf2/visibility.s @@ -1,7 +1,7 @@ // RUN: llvm-mc -filetype=obj -triple=x86_64-pc-linux %s -o %t // RUN: llvm-mc -filetype=obj -triple=x86_64-pc-linux %p/Inputs/visibility.s -o %t2 -// RUN: lld -flavor gnu2 %t %t2 -o %t3 -// RUN: llvm-readobj -t %t3 | FileCheck %s +// RUN: lld -flavor gnu2 -shared %t %t2 -o %t3 +// RUN: llvm-readobj -t -dyn-symbols %t3 | FileCheck %s // REQUIRES: x86 // CHECK: Symbols [ @@ -15,8 +15,35 @@ // CHECK-NEXT: Section: Undefined // CHECK-NEXT: } // CHECK-NEXT: Symbol { -// CHECK-NEXT: Name: _start -// CHECK-NEXT: Value: 0x11000 +// CHECK-NEXT: Name: hidden +// CHECK-NEXT: Value: +// CHECK-NEXT: Size: 0 +// CHECK-NEXT: Binding: Local +// CHECK-NEXT: Type: None +// CHECK-NEXT: Other: 2 +// CHECK-NEXT: Section: .text +// CHECK-NEXT: } +// CHECK-NEXT: Symbol { +// CHECK-NEXT: Name: internal +// CHECK-NEXT: Value: +// CHECK-NEXT: Size: 0 +// CHECK-NEXT: Binding: Local +// CHECK-NEXT: Type: None +// CHECK-NEXT: Other: 1 +// CHECK-NEXT: Section: .text +// CHECK-NEXT: } +// CHECK-NEXT: Symbol { +// CHECK-NEXT: Name: protected_with_hidden +// CHECK-NEXT: Value: +// CHECK-NEXT: Size: 0 +// CHECK-NEXT: Binding: Local +// CHECK-NEXT: Type: None +// CHECK-NEXT: Other: 2 +// CHECK-NEXT: Section: .text +// CHECK-NEXT: } +// CHECK-NEXT: Symbol { +// CHECK-NEXT: Name: default +// CHECK-NEXT: Value: // CHECK-NEXT: Size: 0 // CHECK-NEXT: Binding: Global // CHECK-NEXT: Type: None @@ -24,8 +51,29 @@ // CHECK-NEXT: Section: .text // CHECK-NEXT: } // CHECK-NEXT: Symbol { +// CHECK-NEXT: Name: protected +// CHECK-NEXT: Value: +// CHECK-NEXT: Size: 0 +// CHECK-NEXT: Binding: Global +// CHECK-NEXT: Type: None +// CHECK-NEXT: Other: 3 +// CHECK-NEXT: Section: .text +// CHECK-NEXT: } +// CHECK-NEXT: ] + +// CHECK: DynamicSymbols [ +// CHECK-NEXT: Symbol { +// CHECK-NEXT: Name: @ (0) +// CHECK-NEXT: Value: 0x0 +// CHECK-NEXT: Size: 0 +// CHECK-NEXT: Binding: Local +// CHECK-NEXT: Type: None +// CHECK-NEXT: Other: 0 +// CHECK-NEXT: Section: Undefined +// CHECK-NEXT: } +// CHECK-NEXT: Symbol { // CHECK-NEXT: Name: default -// CHECK-NEXT: Value: 0x11000 +// CHECK-NEXT: Value: // CHECK-NEXT: Size: 0 // CHECK-NEXT: Binding: Global // CHECK-NEXT: Type: None @@ -34,7 +82,7 @@ // CHECK-NEXT: } // CHECK-NEXT: Symbol { // CHECK-NEXT: Name: protected -// CHECK-NEXT: Value: 0x11000 +// CHECK-NEXT: Value: // CHECK-NEXT: Size: 0 // CHECK-NEXT: Binding: Global // CHECK-NEXT: Type: None @@ -43,9 +91,6 @@ // CHECK-NEXT: } // CHECK-NEXT: ] -.global _start -_start: - .global default default: |

