@@ -177,15 +177,24 @@ template <class ELFT> class ELFState {
177
177
178
178
enum class SymtabType { Static, Dynamic };
179
179
180
- // / The future ".strtab" section.
180
+ // / The future symbol table string section.
181
181
StringTableBuilder DotStrtab{StringTableBuilder::ELF};
182
182
183
- // / The future ".shstrtab" section.
183
+ // / The future section header string table section, if a unique string table
184
+ // / is needed. Don't reference this variable direectly: use the
185
+ // / ShStrtabStrings member instead.
184
186
StringTableBuilder DotShStrtab{StringTableBuilder::ELF};
185
187
186
- // / The future ".dynstr" section.
188
+ // / The future dynamic symbol string section.
187
189
StringTableBuilder DotDynstr{StringTableBuilder::ELF};
188
190
191
+ // / The name of the section header string table section. If it is .strtab or
192
+ // / .dynstr, the section header strings will be written to the same string
193
+ // / table as the static/dynamic symbols respectively. Otherwise a dedicated
194
+ // / section will be created with that name.
195
+ StringRef SectionHeaderStringTableName = " .shstrtab" ;
196
+ StringTableBuilder *ShStrtabStrings = &DotShStrtab;
197
+
189
198
NameToIdxMap SN2I;
190
199
NameToIdxMap SymN2I;
191
200
NameToIdxMap DynSymN2I;
@@ -327,6 +336,18 @@ template <class T> static void zero(T &Obj) { memset(&Obj, 0, sizeof(Obj)); }
327
336
template <class ELFT >
328
337
ELFState<ELFT>::ELFState(ELFYAML::Object &D, yaml::ErrorHandler EH)
329
338
: Doc(D), ErrHandler(EH) {
339
+ // The input may explicitly request to store the section header table strings
340
+ // in the same string table as dynamic or static symbol names. Set the
341
+ // ShStrtabStrings member accordingly.
342
+ if (Doc.Header .SectionHeaderStringTable ) {
343
+ SectionHeaderStringTableName = *Doc.Header .SectionHeaderStringTable ;
344
+ if (*Doc.Header .SectionHeaderStringTable == " .strtab" )
345
+ ShStrtabStrings = &DotStrtab;
346
+ else if (*Doc.Header .SectionHeaderStringTable == " .dynstr" )
347
+ ShStrtabStrings = &DotDynstr;
348
+ // Otherwise, the unique table will be used.
349
+ }
350
+
330
351
std::vector<ELFYAML::Section *> Sections = Doc.getSections ();
331
352
// Insert SHT_NULL section implicitly when it is not defined in YAML.
332
353
if (Sections.empty () || Sections.front ()->Type != ELF::SHT_NULL)
@@ -363,19 +384,35 @@ ELFState<ELFT>::ELFState(ELFYAML::Object &D, yaml::ErrorHandler EH)
363
384
" ' at YAML section/fill number " + Twine (I));
364
385
}
365
386
366
- std::vector<StringRef> ImplicitSections;
367
- if (Doc.DynamicSymbols )
368
- ImplicitSections.insert (ImplicitSections.end (), {" .dynsym" , " .dynstr" });
369
- if (Doc.Symbols )
370
- ImplicitSections.push_back (" .symtab" );
387
+ SmallSetVector<StringRef, 8 > ImplicitSections;
388
+ if (Doc.DynamicSymbols ) {
389
+ if (SectionHeaderStringTableName == " .dynsym" )
390
+ reportError (" cannot use '.dynsym' as the section header name table when "
391
+ " there are dynamic symbols" );
392
+ ImplicitSections.insert (" .dynsym" );
393
+ ImplicitSections.insert (" .dynstr" );
394
+ }
395
+ if (Doc.Symbols ) {
396
+ if (SectionHeaderStringTableName == " .symtab" )
397
+ reportError (" cannot use '.symtab' as the section header name table when "
398
+ " there are symbols" );
399
+ ImplicitSections.insert (" .symtab" );
400
+ }
371
401
if (Doc.DWARF )
372
402
for (StringRef DebugSecName : Doc.DWARF ->getNonEmptySectionNames ()) {
373
403
std::string SecName = (" ." + DebugSecName).str ();
374
- ImplicitSections.push_back (StringRef (SecName).copy (StringAlloc));
404
+ // TODO: For .debug_str it should be possible to share the string table,
405
+ // in the same manner as the symbol string tables.
406
+ if (SectionHeaderStringTableName == SecName)
407
+ reportError (" cannot use '" + SecName +
408
+ " ' as the section header name table when it is needed for "
409
+ " DWARF output" );
410
+ ImplicitSections.insert (StringRef (SecName).copy (StringAlloc));
375
411
}
376
- ImplicitSections.insert (ImplicitSections.end (), {" .strtab" });
412
+ // TODO: Only create the .strtab here if any symbols have been requested.
413
+ ImplicitSections.insert (" .strtab" );
377
414
if (!SecHdrTable || !SecHdrTable->NoHeaders .getValueOr (false ))
378
- ImplicitSections.insert (ImplicitSections. end (), { " .shstrtab " } );
415
+ ImplicitSections.insert (SectionHeaderStringTableName );
379
416
380
417
// Insert placeholders for implicit sections that are not
381
418
// defined explicitly in YAML.
@@ -387,7 +424,9 @@ ELFState<ELFT>::ELFState(ELFYAML::Object &D, yaml::ErrorHandler EH)
387
424
ELFYAML::Chunk::ChunkKind::RawContent, true /* IsImplicit*/ );
388
425
Sec->Name = SecName;
389
426
390
- if (SecName == " .dynsym" )
427
+ if (SecName == SectionHeaderStringTableName)
428
+ Sec->Type = ELF::SHT_STRTAB;
429
+ else if (SecName == " .dynsym" )
391
430
Sec->Type = ELF::SHT_DYNSYM;
392
431
else if (SecName == " .symtab" )
393
432
Sec->Type = ELF::SHT_SYMTAB;
@@ -480,8 +519,9 @@ void ELFState<ELFT>::writeELFHeader(raw_ostream &OS) {
480
519
481
520
if (Doc.Header .EShStrNdx )
482
521
Header.e_shstrndx = *Doc.Header .EShStrNdx ;
483
- else if (SectionHeaders.Offset && !ExcludedSectionHeaders.count (" .shstrtab" ))
484
- Header.e_shstrndx = SN2I.get (" .shstrtab" );
522
+ else if (SectionHeaders.Offset &&
523
+ !ExcludedSectionHeaders.count (SectionHeaderStringTableName))
524
+ Header.e_shstrndx = SN2I.get (SectionHeaderStringTableName);
485
525
else
486
526
Header.e_shstrndx = 0 ;
487
527
@@ -615,16 +655,16 @@ bool ELFState<ELFT>::initImplicitHeader(ContiguousBlobAccumulator &CBA,
615
655
if (Header.sh_offset )
616
656
return false ;
617
657
618
- if (SecName == " .symtab" )
619
- initSymtabSectionHeader (Header, SymtabType::Static, CBA, YAMLSec);
620
- else if (SecName == " .strtab" )
658
+ if (SecName == " .strtab" )
621
659
initStrtabSectionHeader (Header, SecName, DotStrtab, CBA, YAMLSec);
622
- else if (SecName == " .shstrtab" )
623
- initStrtabSectionHeader (Header, SecName, DotShStrtab, CBA, YAMLSec);
624
- else if (SecName == " .dynsym" )
625
- initSymtabSectionHeader (Header, SymtabType::Dynamic, CBA, YAMLSec);
626
660
else if (SecName == " .dynstr" )
627
661
initStrtabSectionHeader (Header, SecName, DotDynstr, CBA, YAMLSec);
662
+ else if (SecName == SectionHeaderStringTableName)
663
+ initStrtabSectionHeader (Header, SecName, *ShStrtabStrings, CBA, YAMLSec);
664
+ else if (SecName == " .symtab" )
665
+ initSymtabSectionHeader (Header, SymtabType::Static, CBA, YAMLSec);
666
+ else if (SecName == " .dynsym" )
667
+ initSymtabSectionHeader (Header, SymtabType::Dynamic, CBA, YAMLSec);
628
668
else if (SecName.startswith (" .debug_" )) {
629
669
// If a ".debug_*" section's type is a preserved one, e.g., SHT_DYNAMIC, we
630
670
// will not treat it as a debug section.
@@ -671,7 +711,7 @@ uint64_t ELFState<ELFT>::getSectionNameOffset(StringRef Name) {
671
711
// the string table.
672
712
if (ExcludedSectionHeaders.count (Name))
673
713
return 0 ;
674
- return DotShStrtab. getOffset (Name);
714
+ return ShStrtabStrings-> getOffset (Name);
675
715
}
676
716
677
717
static uint64_t writeContent (ContiguousBlobAccumulator &CBA,
@@ -995,7 +1035,7 @@ void ELFState<ELFT>::initStrtabSectionHeader(Elf_Shdr &SHeader, StringRef Name,
995
1035
StringTableBuilder &STB,
996
1036
ContiguousBlobAccumulator &CBA,
997
1037
ELFYAML::Section *YAMLSec) {
998
- SHeader.sh_name = getSectionNameOffset (Name);
1038
+ SHeader.sh_name = getSectionNameOffset (ELFYAML::dropUniqueSuffix ( Name) );
999
1039
SHeader.sh_type = YAMLSec ? YAMLSec->Type : ELF::SHT_STRTAB;
1000
1040
SHeader.sh_addralign = YAMLSec ? (uint64_t )YAMLSec->AddressAlign : 1 ;
1001
1041
@@ -1817,10 +1857,8 @@ template <class ELFT> void ELFState<ELFT>::buildSectionIndex() {
1817
1857
llvm_unreachable (" buildSectionIndex() failed" );
1818
1858
1819
1859
if (!ExcludedSectionHeaders.count (S->Name ))
1820
- DotShStrtab. add (ELFYAML::dropUniqueSuffix (S->Name ));
1860
+ ShStrtabStrings-> add (ELFYAML::dropUniqueSuffix (S->Name ));
1821
1861
}
1822
-
1823
- DotShStrtab.finalize ();
1824
1862
}
1825
1863
1826
1864
template <class ELFT > void ELFState<ELFT>::buildSymbolIndexes() {
@@ -1870,6 +1908,11 @@ template <class ELFT> void ELFState<ELFT>::finalizeStrings() {
1870
1908
}
1871
1909
1872
1910
DotDynstr.finalize ();
1911
+
1912
+ // Don't finalize the section header string table a second time if it has
1913
+ // already been finalized due to being one of the symbol string tables.
1914
+ if (ShStrtabStrings != &DotStrtab && ShStrtabStrings != &DotDynstr)
1915
+ ShStrtabStrings->finalize ();
1873
1916
}
1874
1917
1875
1918
template <class ELFT >
@@ -1879,14 +1922,16 @@ bool ELFState<ELFT>::writeELF(raw_ostream &OS, ELFYAML::Object &Doc,
1879
1922
if (State.HasError )
1880
1923
return false ;
1881
1924
1882
- // Finalize .strtab and .dynstr sections. We do that early because want to
1883
- // finalize the string table builders before writing the content of the
1884
- // sections that might want to use them.
1885
- State.finalizeStrings ();
1886
-
1925
+ // Build the section index, which adds sections to the section header string
1926
+ // table first, so that we can finalise the section header string table.
1887
1927
State.buildSectionIndex ();
1888
1928
State.buildSymbolIndexes ();
1889
1929
1930
+ // Finalize section header string table and the .strtab and .dynstr sections.
1931
+ // We do this early because we want to finalize the string table builders
1932
+ // before writing the content of the sections that might want to use them.
1933
+ State.finalizeStrings ();
1934
+
1890
1935
if (State.HasError )
1891
1936
return false ;
1892
1937
0 commit comments