1
0
mirror of https://github.com/RPCS3/llvm-mirror.git synced 2024-11-22 02:33:06 +01:00

[yaml2obj] Add support for writing the long symbol name.

Summary: This patch, as a follow-up of D95505, adds
support for writing the long symbol name by implementing
the StringTable. Only XCOFF32 is suppoted now.

Reviewed By: jhenderson, shchenz

Differential Revision: https://reviews.llvm.org/D103455
This commit is contained in:
Esme-Yi 2021-06-21 05:09:56 +00:00
parent 633abb5259
commit d5a215bffc
2 changed files with 61 additions and 4 deletions

View File

@ -13,6 +13,7 @@
#include "llvm/ADT/DenseMap.h"
#include "llvm/BinaryFormat/XCOFF.h"
#include "llvm/MC/StringTableBuilder.h"
#include "llvm/Object/XCOFFObjectFile.h"
#include "llvm/ObjectYAML/ObjectYAML.h"
#include "llvm/ObjectYAML/yaml2obj.h"
@ -31,12 +32,14 @@ constexpr uint32_t MaxRawDataSize = UINT32_MAX;
class XCOFFWriter {
public:
XCOFFWriter(XCOFFYAML::Object &Obj, raw_ostream &OS, yaml::ErrorHandler EH)
: Obj(Obj), W(OS, support::big), ErrHandler(EH) {
: Obj(Obj), W(OS, support::big), ErrHandler(EH),
Strings(StringTableBuilder::XCOFF) {
Is64Bit = Obj.Header.Magic == (llvm::yaml::Hex16)XCOFF::XCOFF64;
}
bool writeXCOFF();
private:
bool nameShouldBeInStringTable(StringRef SymbolName);
bool initFileHeader(uint64_t CurrentOffset);
bool initSectionHeader(uint64_t &CurrentOffset);
bool initRelocations(uint64_t &CurrentOffset);
@ -51,6 +54,7 @@ private:
bool Is64Bit = false;
support::endian::Writer W;
yaml::ErrorHandler ErrHandler;
StringTableBuilder Strings;
uint64_t StartOffset;
// Map the section name to its corrresponding section index.
DenseMap<StringRef, int16_t> SectionIndexMap = {
@ -70,6 +74,10 @@ static void writeName(StringRef StrName, support::endian::Writer W) {
W.write(NameRef);
}
bool XCOFFWriter::nameShouldBeInStringTable(StringRef SymbolName) {
return SymbolName.size() > XCOFF::NameSize;
}
bool XCOFFWriter::initRelocations(uint64_t &CurrentOffset) {
for (uint16_t I = 0, E = InitSections.size(); I < E; ++I) {
if (!InitSections[I].Relocations.empty()) {
@ -139,7 +147,11 @@ bool XCOFFWriter::initFileHeader(uint64_t CurrentOffset) {
for (const XCOFFYAML::Symbol &YamlSym : Obj.Symbols) {
// Add the number of auxiliary symbols to the total number.
InitFileHdr.NumberOfSymTableEntries += YamlSym.NumberOfAuxEntries;
if (nameShouldBeInStringTable(YamlSym.SymbolName))
Strings.add(YamlSym.SymbolName);
}
// Finalize the string table.
Strings.finalize();
// Calculate SymbolTableOffset for the file header.
if (InitFileHdr.NumberOfSymTableEntries) {
@ -157,6 +169,7 @@ bool XCOFFWriter::initFileHeader(uint64_t CurrentOffset) {
}
bool XCOFFWriter::assignAddressesAndIndices() {
Strings.clear();
uint64_t CurrentOffset =
XCOFF::FileHeaderSize32 /* TODO: + auxiliaryHeaderSize() */ +
InitSections.size() * XCOFF::SectionHeaderSize32;
@ -260,7 +273,14 @@ bool XCOFFWriter::writeSymbols() {
if (PaddingSize > 0)
W.OS.write_zeros(PaddingSize);
for (const XCOFFYAML::Symbol &YamlSym : Obj.Symbols) {
writeName(YamlSym.SymbolName, W);
if (nameShouldBeInStringTable(YamlSym.SymbolName)) {
// For XCOFF32: A value of 0 indicates that the symbol name is in the
// string table.
W.write<int32_t>(0);
W.write<uint32_t>(Strings.getOffset(YamlSym.SymbolName));
} else {
writeName(YamlSym.SymbolName, W);
}
W.write<uint32_t>(YamlSym.Value);
W.write<int16_t>(
YamlSym.SectionName.size() ? SectionIndexMap[YamlSym.SectionName] : 0);
@ -297,8 +317,12 @@ bool XCOFFWriter::writeXCOFF() {
if (!writeRelocations())
return false;
}
if (!Obj.Symbols.empty())
return writeSymbols();
if (!Obj.Symbols.empty()) {
if (!writeSymbols())
return false;
// Write the string table.
Strings.write(W.OS);
}
return true;
}

View File

@ -0,0 +1,33 @@
## Test that the string table works well for long symbol names.
## TODO: Dump the raw string table and check the contents.
# RUN: yaml2obj %s -o %t
# RUN: llvm-readobj --symbols %t | FileCheck %s
# CHECK: AddressSize: 32bit
# CHECK-NEXT: Symbols [
# CHECK-NEXT: Symbol {
# CHECK-NEXT: Index: 0
# CHECK-NEXT: Name: .symname
# CHECK-NEXT: Value: 0x0
# CHECK-NEXT: Section: N_UNDEF
# CHECK-NEXT: Type: 0x0
# CHECK-NEXT: StorageClass: C_NULL (0x0)
# CHECK-NEXT: NumberOfAuxEntries: 0
# CHECK-NEXT: }
# CHECK-NEXT: Symbol {
# CHECK-NEXT: Index: 1
# CHECK-NEXT: Name: .longname
# CHECK-NEXT: Value: 0x0
# CHECK-NEXT: Section: N_UNDEF
# CHECK-NEXT: Type: 0x0
# CHECK-NEXT: StorageClass: C_NULL (0x0)
# CHECK-NEXT: NumberOfAuxEntries: 0
# CHECK-NEXT: }
# CHECK-NEXT: ]
--- !XCOFF
FileHeader:
MagicNumber: 0x1DF
Symbols:
- Name: .symname
- Name: .longname