@@ -210,6 +210,7 @@ template <class ELFT>
210
210
class SymbolTableSection final : public OutputSectionBase<ELFT::Is64Bits> {
211
211
public:
212
212
typedef typename ELFFile<ELFT>::Elf_Sym Elf_Sym;
213
+ typedef typename ELFFile<ELFT>::Elf_Sym_Range Elf_Sym_Range;
213
214
typedef typename OutputSectionBase<ELFT::Is64Bits>::uintX_t uintX_t;
214
215
SymbolTableSection (Writer<ELFT> &W, SymbolTable &Table,
215
216
StringTableSection<ELFT::Is64Bits> &StrTabSec)
@@ -221,25 +222,25 @@ class SymbolTableSection final : public OutputSectionBase<ELFT::Is64Bits> {
221
222
typedef OutputSectionBase<ELFT::Is64Bits> Base;
222
223
typename Base::HeaderT &Header = this ->Header ;
223
224
224
- // For now the only local symbol is going to be the one at index 0
225
- Header.sh_info = 1 ;
226
-
227
225
Header.sh_entsize = sizeof (Elf_Sym);
228
226
Header.sh_addralign = ELFT::Is64Bits ? 8 : 4 ;
229
227
}
230
228
231
229
void finalize () override {
232
230
this ->Header .sh_size = getNumSymbols () * sizeof (Elf_Sym);
233
231
this ->Header .sh_link = StrTabSec.getSectionIndex ();
232
+ this ->Header .sh_info = NumLocals + 1 ;
234
233
}
235
234
236
235
void writeTo (uint8_t *Buf) override ;
237
236
238
237
const SymbolTable &getSymTable () const { return Table; }
239
238
240
- void addSymbol (StringRef Name) {
239
+ void addSymbol (StringRef Name, bool isLocal = false ) {
241
240
StrTabSec.add (Name);
242
241
++NumVisible;
242
+ if (isLocal)
243
+ ++NumLocals;
243
244
}
244
245
245
246
StringTableSection<ELFT::Is64Bits> &getStrTabSec () { return StrTabSec; }
@@ -249,6 +250,7 @@ class SymbolTableSection final : public OutputSectionBase<ELFT::Is64Bits> {
249
250
SymbolTable &Table;
250
251
StringTableSection<ELFT::Is64Bits> &StrTabSec;
251
252
unsigned NumVisible = 0 ;
253
+ unsigned NumLocals = 0 ;
252
254
const Writer<ELFT> &W;
253
255
};
254
256
@@ -434,6 +436,7 @@ template <class ELFT> class Writer {
434
436
typedef typename ELFFile<ELFT>::Elf_Ehdr Elf_Ehdr;
435
437
typedef typename ELFFile<ELFT>::Elf_Phdr Elf_Phdr;
436
438
typedef typename ELFFile<ELFT>::Elf_Sym Elf_Sym;
439
+ typedef typename ELFFile<ELFT>::Elf_Sym_Range Elf_Sym_Range;
437
440
typedef typename ELFFile<ELFT>::Elf_Rela Elf_Rela;
438
441
Writer (SymbolTable *T)
439
442
: SymTabSec(*this , *T, StrTabSec), DynSymSec(*this , *T, DynStrSec),
@@ -623,9 +626,28 @@ static bool includeInSymtab(const SymbolBody &B) {
623
626
}
624
627
625
628
template <class ELFT > void SymbolTableSection<ELFT>::writeTo(uint8_t *Buf) {
626
- uint8_t *BufStart = Buf;
627
-
628
629
Buf += sizeof (Elf_Sym);
630
+
631
+ // All symbols with STB_LOCAL binding precede the weak and global symbols.
632
+ // .dynsym only contains global symbols.
633
+ if (!Config->DiscardAll && !StrTabSec.isDynamic ()) {
634
+ for (const std::unique_ptr<ObjectFileBase> &FileB :
635
+ Table.getObjectFiles ()) {
636
+ auto &File = cast<ObjectFile<ELFT>>(*FileB);
637
+ Elf_Sym_Range Syms = File.getLocalSymbols ();
638
+ for (const Elf_Sym &Sym : Syms) {
639
+ auto *ESym = reinterpret_cast <Elf_Sym *>(Buf);
640
+ ErrorOr<StringRef> SymName = Sym.getName (File.getStringTable ());
641
+ ESym->st_name = (SymName) ? StrTabSec.getFileOff (*SymName) : 0 ;
642
+ ESym->st_value = Sym.st_value ;
643
+ ESym->st_size = Sym.st_size ;
644
+ Buf += sizeof (Elf_Sym);
645
+ }
646
+ }
647
+ }
648
+
649
+ uint8_t *GlobalStart = Buf;
650
+
629
651
for (auto &P : Table.getSymbols ()) {
630
652
StringRef Name = P.first ;
631
653
Symbol *Sym = P.second ;
@@ -686,9 +708,8 @@ template <class ELFT> void SymbolTableSection<ELFT>::writeTo(uint8_t *Buf) {
686
708
// The default hashing of StringRef produces different results on 32 and 64
687
709
// bit systems so we sort by st_name. That is arbitrary but deterministic.
688
710
// FIXME: Experiment with passing in a custom hashing instead.
689
- auto *Syms = reinterpret_cast <Elf_Sym *>(BufStart);
690
- ++Syms;
691
- array_pod_sort (Syms, Syms + NumVisible, compareSym<ELFT>);
711
+ auto *Syms = reinterpret_cast <Elf_Sym *>(GlobalStart);
712
+ array_pod_sort (Syms, Syms + NumVisible - NumLocals, compareSym<ELFT>);
692
713
}
693
714
694
715
template <bool Is64Bits>
@@ -819,6 +840,14 @@ template <class ELFT> void Writer<ELFT>::createSections() {
819
840
820
841
for (const std::unique_ptr<ObjectFileBase> &FileB : Symtab.getObjectFiles ()) {
821
842
auto &File = cast<ObjectFile<ELFT>>(*FileB);
843
+ if (!Config->DiscardAll ) {
844
+ Elf_Sym_Range Syms = File.getLocalSymbols ();
845
+ for (const Elf_Sym &Sym : Syms) {
846
+ ErrorOr<StringRef> SymName = Sym.getName (File.getStringTable ());
847
+ if (SymName)
848
+ SymTabSec.addSymbol (*SymName, true );
849
+ }
850
+ }
822
851
for (SectionChunk<ELFT> *C : File.getChunks ()) {
823
852
if (!C)
824
853
continue ;
0 commit comments