forked from OSchip/llvm-project
PECOFF: make dumpbin tool happy.
The dumpbin tool in the MSVC toolchain cannot handle an executable created by LLD if the executable contains a long section name. In PE/COFF, a section name is stored to a section table entry. Because the section name field in the table is only 8 byte long, a name longer than that is stored to the string table and the offset in the string table is stored to the section table entry instead. In order to look up a string from the string table, tools need to handle the symbol table, because the string table is defined as it immediately follows the symbol table. And seems the dumpbin doesn't like zero-length symbol table. This patch teaches LLD how to emit a dummy symbol table. The dummy table has one dummy entry in it. llvm-svn: 228900
This commit is contained in:
parent
63aaa98d94
commit
1a40b2062c
|
@ -148,6 +148,7 @@ public:
|
|||
}
|
||||
|
||||
void setNumberOfSections(uint32_t num) { _coffHeader.NumberOfSections = num; }
|
||||
void setNumberOfSymbols(uint32_t num) { _coffHeader.NumberOfSymbols = num; }
|
||||
|
||||
void setAddressOfEntryPoint(uint32_t address) {
|
||||
_peHeader.AddressOfEntryPoint = address;
|
||||
|
@ -186,13 +187,20 @@ public:
|
|||
}
|
||||
|
||||
uint32_t addSectionName(StringRef sectionName) {
|
||||
if (_stringTable.empty())
|
||||
_stringTable.insert(_stringTable.begin(), 4, 0);
|
||||
if (_stringTable.empty()) {
|
||||
// The string table immediately follows the symbol table.
|
||||
// We don't really need a symbol table, but some tools (e.g. dumpbin)
|
||||
// don't like zero-length symbol table.
|
||||
// Make room for the empty symbol slot, which occupies 18 byte.
|
||||
// We also need to reserve 4 bytes for the string table header.
|
||||
int size = sizeof(llvm::object::coff_symbol16) + 4;
|
||||
_stringTable.insert(_stringTable.begin(), size, 0);
|
||||
}
|
||||
uint32_t offset = _stringTable.size();
|
||||
_stringTable.insert(_stringTable.end(), sectionName.begin(),
|
||||
sectionName.end());
|
||||
_stringTable.push_back('\0');
|
||||
return offset;
|
||||
return offset - sizeof(llvm::object::coff_symbol16);
|
||||
}
|
||||
|
||||
uint64_t size() const override { return _stringTable.size(); }
|
||||
|
@ -200,7 +208,8 @@ public:
|
|||
void write(uint8_t *buffer) override {
|
||||
if (_stringTable.empty())
|
||||
return;
|
||||
*reinterpret_cast<ulittle32_t *>(_stringTable.data()) = _stringTable.size();
|
||||
char *off = _stringTable.data() + sizeof(llvm::object::coff_symbol16);
|
||||
*reinterpret_cast<ulittle32_t *>(off) = _stringTable.size();
|
||||
std::memcpy(buffer, _stringTable.data(), _stringTable.size());
|
||||
}
|
||||
|
||||
|
@ -1158,11 +1167,11 @@ void PECOFFWriter::build(const File &linkedFile) {
|
|||
}
|
||||
|
||||
setImageSizeOnDisk();
|
||||
// N.B. Currently released versions of dumpbin do not appropriately handle
|
||||
// symbol tables which NumberOfSymbols set to zero but a non-zero
|
||||
// PointerToSymbolTable.
|
||||
if (stringTable->size())
|
||||
|
||||
if (stringTable->size()) {
|
||||
peHeader->setPointerToSymbolTable(stringTable->fileOffset());
|
||||
peHeader->setNumberOfSymbols(1);
|
||||
}
|
||||
|
||||
for (std::unique_ptr<Chunk> &chunk : _chunks) {
|
||||
SectionChunk *section = dyn_cast<SectionChunk>(chunk.get());
|
||||
|
|
Loading…
Reference in New Issue