[llvm] 657aa3a - [yaml2obj] Add support for writing the long symbol name.
via llvm-commits
llvm-commits at lists.llvm.org
Sun Jun 20 22:11:14 PDT 2021
Author: Esme-Yi
Date: 2021-06-21T05:09:56Z
New Revision: 657aa3a7631b991b25d0292ed73211f824938598
URL: https://github.com/llvm/llvm-project/commit/657aa3a7631b991b25d0292ed73211f824938598
DIFF: https://github.com/llvm/llvm-project/commit/657aa3a7631b991b25d0292ed73211f824938598.diff
LOG: [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
Added:
llvm/test/tools/yaml2obj/XCOFF/long-symbol-name.yaml
Modified:
llvm/lib/ObjectYAML/XCOFFEmitter.cpp
Removed:
################################################################################
diff --git a/llvm/lib/ObjectYAML/XCOFFEmitter.cpp b/llvm/lib/ObjectYAML/XCOFFEmitter.cpp
index c113fae20f1f4..2fd73a77cae5f 100644
--- a/llvm/lib/ObjectYAML/XCOFFEmitter.cpp
+++ b/llvm/lib/ObjectYAML/XCOFFEmitter.cpp
@@ -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 @@ class XCOFFWriter {
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;
}
diff --git a/llvm/test/tools/yaml2obj/XCOFF/long-symbol-name.yaml b/llvm/test/tools/yaml2obj/XCOFF/long-symbol-name.yaml
new file mode 100644
index 0000000000000..d800f6cd73f91
--- /dev/null
+++ b/llvm/test/tools/yaml2obj/XCOFF/long-symbol-name.yaml
@@ -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
More information about the llvm-commits
mailing list