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:
parent
633abb5259
commit
d5a215bffc
@ -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;
|
||||
}
|
||||
|
||||
|
33
test/tools/yaml2obj/XCOFF/long-symbol-name.yaml
Normal file
33
test/tools/yaml2obj/XCOFF/long-symbol-name.yaml
Normal 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
|
Loading…
Reference in New Issue
Block a user