24
24
#include " llvm/ADT/STLExtras.h"
25
25
#include " llvm/ADT/StringSet.h"
26
26
#include " llvm/BinaryFormat/COFF.h"
27
+ #include " llvm/MC/StringTableBuilder.h"
27
28
#include " llvm/Support/Endian.h"
28
29
#include " llvm/Support/FileOutputBuffer.h"
29
30
#include " llvm/Support/Parallel.h"
@@ -201,7 +202,8 @@ struct ChunkRange {
201
202
class Writer {
202
203
public:
203
204
Writer (COFFLinkerContext &c)
204
- : buffer(c.e.outputBuffer), delayIdata(c), ctx(c) {}
205
+ : buffer(c.e.outputBuffer), strtab(StringTableBuilder::WinCOFF),
206
+ delayIdata (c), ctx(c) {}
205
207
void run ();
206
208
207
209
private:
@@ -281,7 +283,7 @@ class Writer {
281
283
282
284
std::unique_ptr<FileOutputBuffer> &buffer;
283
285
std::map<PartialSectionKey, PartialSection *> partialSections;
284
- std::vector< char > strtab;
286
+ StringTableBuilder strtab;
285
287
std::vector<llvm::object::coff_symbol16> outputSymtab;
286
288
std::vector<ECCodeMapEntry> codeMap;
287
289
IdataContents idata;
@@ -1434,14 +1436,6 @@ void Writer::assignOutputSectionIndices() {
1434
1436
sc->setOutputSectionIdx (mc->getOutputSectionIdx ());
1435
1437
}
1436
1438
1437
- size_t Writer::addEntryToStringTable (StringRef str) {
1438
- assert (str.size () > COFF::NameSize);
1439
- size_t offsetOfEntry = strtab.size () + 4 ; // +4 for the size field
1440
- strtab.insert (strtab.end (), str.begin (), str.end ());
1441
- strtab.push_back (' \0 ' );
1442
- return offsetOfEntry;
1443
- }
1444
-
1445
1439
std::optional<coff_symbol16> Writer::createSymbol (Defined *def) {
1446
1440
coff_symbol16 sym;
1447
1441
switch (def->kind ()) {
@@ -1482,7 +1476,8 @@ std::optional<coff_symbol16> Writer::createSymbol(Defined *def) {
1482
1476
StringRef name = def->getName ();
1483
1477
if (name.size () > COFF::NameSize) {
1484
1478
sym.Name .Offset .Zeroes = 0 ;
1485
- sym.Name .Offset .Offset = addEntryToStringTable (name);
1479
+ sym.Name .Offset .Offset = 0 ; // Filled in later.
1480
+ strtab.add (name);
1486
1481
} else {
1487
1482
memset (sym.Name .ShortName , 0 , COFF::NameSize);
1488
1483
memcpy (sym.Name .ShortName , name.data (), name.size ());
@@ -1514,6 +1509,7 @@ void Writer::createSymbolAndStringTable() {
1514
1509
// solution where discardable sections have long names preserved and
1515
1510
// non-discardable sections have their names truncated, to ensure that any
1516
1511
// section which is mapped at runtime also has its name mapped at runtime.
1512
+ SmallVector<OutputSection *> longNameSections;
1517
1513
for (OutputSection *sec : ctx.outputSections ) {
1518
1514
if (sec->name .size () <= COFF::NameSize)
1519
1515
continue ;
@@ -1525,9 +1521,13 @@ void Writer::createSymbolAndStringTable() {
1525
1521
<< " is longer than 8 characters and will use a non-standard string "
1526
1522
" table" ;
1527
1523
}
1528
- sec->setStringTableOff (addEntryToStringTable (sec->name ));
1524
+ // Put the section name in the begin of strtab so that its offset is less
1525
+ // than Max7DecimalOffset otherwise lldb/gdb will not read it.
1526
+ strtab.add (sec->name , /* Priority=*/ UINT8_MAX);
1527
+ longNameSections.push_back (sec);
1529
1528
}
1530
1529
1530
+ std::vector<std::pair<size_t , StringRef>> longNameSymbols;
1531
1531
if (ctx.config .writeSymtab ) {
1532
1532
for (ObjFile *file : ctx.objFileInstances ) {
1533
1533
for (Symbol *b : file->getSymbols ()) {
@@ -1542,15 +1542,22 @@ void Writer::createSymbolAndStringTable() {
1542
1542
continue ;
1543
1543
}
1544
1544
1545
- if (std::optional<coff_symbol16> sym = createSymbol (d))
1545
+ if (std::optional<coff_symbol16> sym = createSymbol (d)) {
1546
+ if (d->getName ().size () > COFF::NameSize)
1547
+ longNameSymbols.emplace_back (outputSymtab.size (), d->getName ());
1546
1548
outputSymtab.push_back (*sym);
1549
+ }
1547
1550
1548
1551
if (auto *dthunk = dyn_cast<DefinedImportThunk>(d)) {
1549
1552
if (!dthunk->wrappedSym ->writtenToSymtab ) {
1550
1553
dthunk->wrappedSym ->writtenToSymtab = true ;
1551
1554
if (std::optional<coff_symbol16> sym =
1552
- createSymbol (dthunk->wrappedSym ))
1555
+ createSymbol (dthunk->wrappedSym )) {
1556
+ if (d->getName ().size () > COFF::NameSize)
1557
+ longNameSymbols.emplace_back (outputSymtab.size (),
1558
+ dthunk->wrappedSym ->getName ());
1553
1559
outputSymtab.push_back (*sym);
1560
+ }
1554
1561
}
1555
1562
}
1556
1563
}
@@ -1560,11 +1567,19 @@ void Writer::createSymbolAndStringTable() {
1560
1567
if (outputSymtab.empty () && strtab.empty ())
1561
1568
return ;
1562
1569
1570
+ strtab.finalize ();
1571
+ for (OutputSection *sec : longNameSections)
1572
+ sec->setStringTableOff (strtab.getOffset (sec->name ));
1573
+ for (auto P : longNameSymbols) {
1574
+ coff_symbol16 &sym = outputSymtab[P.first ];
1575
+ sym.Name .Offset .Offset = strtab.getOffset (P.second );
1576
+ }
1577
+
1563
1578
// We position the symbol table to be adjacent to the end of the last section.
1564
1579
uint64_t fileOff = fileSize;
1565
1580
pointerToSymbolTable = fileOff;
1566
1581
fileOff += outputSymtab.size () * sizeof (coff_symbol16);
1567
- fileOff += 4 + strtab.size ();
1582
+ fileOff += strtab.getSize ();
1568
1583
fileSize = alignTo (fileOff, ctx.config .fileAlign );
1569
1584
}
1570
1585
@@ -1945,9 +1960,7 @@ template <typename PEHeaderTy> void Writer::writeHeader() {
1945
1960
// Create the string table, it follows immediately after the symbol table.
1946
1961
// The first 4 bytes is length including itself.
1947
1962
buf = reinterpret_cast <uint8_t *>(&symbolTable[numberOfSymbols]);
1948
- write32le (buf, strtab.size () + 4 );
1949
- if (!strtab.empty ())
1950
- memcpy (buf + 4 , strtab.data (), strtab.size ());
1963
+ strtab.write (buf);
1951
1964
}
1952
1965
1953
1966
void Writer::openFile (StringRef path) {
0 commit comments