[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