[llvm] r218636 - WinCOFFObjectWriter: optimize the string table for common suffices
Hans Wennborg
hans at hanshq.net
Mon Sep 29 15:43:20 PDT 2014
Author: hans
Date: Mon Sep 29 17:43:20 2014
New Revision: 218636
URL: http://llvm.org/viewvc/llvm-project?rev=218636&view=rev
Log:
WinCOFFObjectWriter: optimize the string table for common suffices
This is a follow-up from r207670 which did the same for ELF.
Differential Revision: http://reviews.llvm.org/D5530
Modified:
llvm/trunk/include/llvm/MC/StringTableBuilder.h
llvm/trunk/lib/MC/ELFObjectWriter.cpp
llvm/trunk/lib/MC/StringTableBuilder.cpp
llvm/trunk/lib/MC/WinCOFFObjectWriter.cpp
llvm/trunk/test/MC/COFF/section-name-encoding.s
llvm/trunk/tools/yaml2obj/yaml2elf.cpp
llvm/trunk/unittests/MC/StringTableBuilderTest.cpp
Modified: llvm/trunk/include/llvm/MC/StringTableBuilder.h
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/include/llvm/MC/StringTableBuilder.h?rev=218636&r1=218635&r2=218636&view=diff
==============================================================================
--- llvm/trunk/include/llvm/MC/StringTableBuilder.h (original)
+++ llvm/trunk/include/llvm/MC/StringTableBuilder.h Mon Sep 29 17:43:20 2014
@@ -29,9 +29,14 @@ public:
return StringIndexMap.GetOrCreateValue(s, 0).getKey();
}
+ enum Kind {
+ ELF,
+ WinCOFF
+ };
+
/// \brief Analyze the strings and build the final table. No more strings can
/// be added after this point.
- void finalize();
+ void finalize(Kind kind);
/// \brief Retrieve the string table data. Can only be used after the table
/// is finalized.
@@ -48,6 +53,8 @@ public:
return StringIndexMap[s];
}
+ void clear();
+
private:
bool isFinalized() {
return !StringTable.empty();
Modified: llvm/trunk/lib/MC/ELFObjectWriter.cpp
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/MC/ELFObjectWriter.cpp?rev=218636&r1=218635&r2=218636&view=diff
==============================================================================
--- llvm/trunk/lib/MC/ELFObjectWriter.cpp (original)
+++ llvm/trunk/lib/MC/ELFObjectWriter.cpp Mon Sep 29 17:43:20 2014
@@ -1073,7 +1073,7 @@ ELFObjectWriter::computeSymbolTable(MCAs
for (auto i = Asm.file_names_begin(), e = Asm.file_names_end(); i != e; ++i)
StrTabBuilder.add(*i);
- StrTabBuilder.finalize();
+ StrTabBuilder.finalize(StringTableBuilder::ELF);
for (auto i = Asm.file_names_begin(), e = Asm.file_names_end(); i != e; ++i)
FileSymbolData.push_back(StrTabBuilder.getOffset(*i));
@@ -1446,7 +1446,7 @@ void ELFObjectWriter::CreateMetadataSect
static_cast<const MCSectionELF&>(it->getSection());
ShStrTabBuilder.add(Section.getSectionName());
}
- ShStrTabBuilder.finalize();
+ ShStrTabBuilder.finalize(StringTableBuilder::ELF);
F->getContents().append(ShStrTabBuilder.data().begin(),
ShStrTabBuilder.data().end());
}
Modified: llvm/trunk/lib/MC/StringTableBuilder.cpp
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/MC/StringTableBuilder.cpp?rev=218636&r1=218635&r2=218636&view=diff
==============================================================================
--- llvm/trunk/lib/MC/StringTableBuilder.cpp (original)
+++ llvm/trunk/lib/MC/StringTableBuilder.cpp Mon Sep 29 17:43:20 2014
@@ -9,6 +9,8 @@
#include "llvm/MC/StringTableBuilder.h"
#include "llvm/ADT/SmallVector.h"
+#include "llvm/Support/COFF.h"
+#include "llvm/Support/Endian.h"
using namespace llvm;
@@ -25,19 +27,28 @@ static bool compareBySuffix(StringRef a,
return sizeA > sizeB;
}
-void StringTableBuilder::finalize() {
+void StringTableBuilder::finalize(Kind kind) {
SmallVector<StringRef, 8> Strings;
+ Strings.reserve(StringIndexMap.size());
+
for (auto i = StringIndexMap.begin(), e = StringIndexMap.end(); i != e; ++i)
Strings.push_back(i->getKey());
std::sort(Strings.begin(), Strings.end(), compareBySuffix);
- // FIXME: Starting with a null byte is ELF specific. Generalize this so we
- // can use the class with other object formats.
- StringTable += '\x00';
+ if (kind == ELF) {
+ // Start the table with a NUL byte.
+ StringTable += '\x00';
+ } else if (kind == WinCOFF) {
+ // Make room to write the table size later.
+ StringTable.append(4, '\x00');
+ }
StringRef Previous;
for (StringRef s : Strings) {
+ if (kind == WinCOFF)
+ assert(s.size() > COFF::NameSize && "Short string in COFF string table!");
+
if (Previous.endswith(s)) {
StringIndexMap[s] = StringTable.size() - 1 - s.size();
continue;
@@ -48,4 +59,16 @@ void StringTableBuilder::finalize() {
StringTable += '\x00';
Previous = s;
}
+
+ if (kind == WinCOFF) {
+ assert(StringTable.size() <= std::numeric_limits<uint32_t>::max());
+ uint32_t size = static_cast<uint32_t>(StringTable.size());
+ support::endian::write<uint32_t, support::little, support::unaligned>(
+ StringTable.data(), size);
+ }
+}
+
+void StringTableBuilder::clear() {
+ StringTable.clear();
+ StringIndexMap.clear();
}
Modified: llvm/trunk/lib/MC/WinCOFFObjectWriter.cpp
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/MC/WinCOFFObjectWriter.cpp?rev=218636&r1=218635&r2=218636&view=diff
==============================================================================
--- llvm/trunk/lib/MC/WinCOFFObjectWriter.cpp (original)
+++ llvm/trunk/lib/MC/WinCOFFObjectWriter.cpp Mon Sep 29 17:43:20 2014
@@ -26,6 +26,7 @@
#include "llvm/MC/MCSectionCOFF.h"
#include "llvm/MC/MCSymbol.h"
#include "llvm/MC/MCValue.h"
+#include "llvm/MC/StringTableBuilder.h"
#include "llvm/Support/COFF.h"
#include "llvm/Support/Debug.h"
#include "llvm/Support/Endian.h"
@@ -102,25 +103,6 @@ public:
static size_t size();
};
-// This class holds the COFF string table.
-class StringTable {
- typedef StringMap<size_t> map;
- map Map;
-
- void update_length();
-public:
- std::vector<char> Data;
-
- StringTable();
- size_t size() const;
- size_t insert(StringRef String);
- void clear() {
- Map.clear();
- Data.resize(4);
- update_length();
- }
-};
-
class WinCOFFObjectWriter : public MCObjectWriter {
public:
@@ -136,7 +118,7 @@ public:
COFF::header Header;
sections Sections;
symbols Symbols;
- StringTable Strings;
+ StringTableBuilder Strings;
// Maps used during object file creation.
section_map SectionMap;
@@ -168,8 +150,8 @@ public:
void DefineSymbol(MCSymbolData const &SymbolData, MCAssembler &Assembler,
const MCAsmLayout &Layout);
- void MakeSymbolReal(COFFSymbol &S, size_t Index);
- void MakeSectionReal(COFFSection &S, size_t Number);
+ void SetSymbolName(COFFSymbol &S);
+ void SetSectionName(COFFSection &S);
bool ExportSymbol(const MCSymbol &Symbol, MCAssembler &Asm);
@@ -265,49 +247,6 @@ size_t COFFSection::size() {
}
//------------------------------------------------------------------------------
-// StringTable class implementation
-
-/// Write the length of the string table into Data.
-/// The length of the string table includes uint32 length header.
-void StringTable::update_length() {
- write_uint32_le(&Data.front(), Data.size());
-}
-
-StringTable::StringTable() {
- // The string table data begins with the length of the entire string table
- // including the length header. Allocate space for this header.
- Data.resize(4);
- update_length();
-}
-
-size_t StringTable::size() const {
- return Data.size();
-}
-
-/// Add String to the table iff it is not already there.
-/// @returns the index into the string table where the string is now located.
-size_t StringTable::insert(StringRef String) {
- map::iterator i = Map.find(String);
-
- if (i != Map.end())
- return i->second;
-
- size_t Offset = Data.size();
-
- // Insert string data into string table.
- Data.insert(Data.end(), String.begin(), String.end());
- Data.push_back('\0');
-
- // Put a reference to it in the map.
- Map[String] = Offset;
-
- // Update the internal length field.
- update_length();
-
- return Offset;
-}
-
-//------------------------------------------------------------------------------
// WinCOFFObjectWriter class implementation
WinCOFFObjectWriter::WinCOFFObjectWriter(MCWinCOFFObjectTargetWriter *MOTW,
@@ -521,11 +460,9 @@ static void encodeBase64StringEntry(char
}
}
-/// making a section real involves assigned it a number and putting
-/// name into the string table if needed
-void WinCOFFObjectWriter::MakeSectionReal(COFFSection &S, size_t Number) {
+void WinCOFFObjectWriter::SetSectionName(COFFSection &S) {
if (S.Name.size() > COFF::NameSize) {
- uint64_t StringTableEntry = Strings.insert(S.Name.c_str());
+ uint64_t StringTableEntry = Strings.getOffset(S.Name);
if (StringTableEntry <= Max6DecimalOffset) {
std::sprintf(S.Header.Name, "/%d", unsigned(StringTableEntry));
@@ -543,20 +480,13 @@ void WinCOFFObjectWriter::MakeSectionRea
}
} else
std::memcpy(S.Header.Name, S.Name.c_str(), S.Name.size());
-
- S.Number = Number;
- S.Symbol->Data.SectionNumber = S.Number;
- S.Symbol->Aux[0].Aux.SectionDefinition.Number = S.Number;
}
-void WinCOFFObjectWriter::MakeSymbolReal(COFFSymbol &S, size_t Index) {
- if (S.Name.size() > COFF::NameSize) {
- size_t StringTableEntry = Strings.insert(S.Name.c_str());
-
- S.set_name_offset(StringTableEntry);
- } else
+void WinCOFFObjectWriter::SetSymbolName(COFFSymbol &S) {
+ if (S.Name.size() > COFF::NameSize)
+ S.set_name_offset(Strings.getOffset(S.Name));
+ else
std::memcpy(S.Data.Name, S.Name.c_str(), S.Name.size());
- S.Index = Index;
}
bool WinCOFFObjectWriter::ExportSymbol(const MCSymbol &Symbol,
@@ -860,10 +790,14 @@ void WinCOFFObjectWriter::WriteObject(MC
DenseMap<COFFSection *, int32_t> SectionIndices(
NextPowerOf2(NumberOfSections));
+
+ // Assign section numbers.
size_t Number = 1;
for (const auto &Section : Sections) {
SectionIndices[Section.get()] = Number;
- MakeSectionReal(*Section, Number);
+ Section->Number = Number;
+ Section->Symbol->Data.SectionNumber = Number;
+ Section->Symbol->Aux[0].Aux.SectionDefinition.Number = Number;
++Number;
}
@@ -903,10 +837,8 @@ void WinCOFFObjectWriter::WriteObject(MC
// Update section number & offset for symbols that have them.
if (Symbol->Section)
Symbol->Data.SectionNumber = Symbol->Section->Number;
-
if (Symbol->should_keep()) {
- MakeSymbolReal(*Symbol, Header.NumberOfSymbols++);
-
+ Symbol->Index = Header.NumberOfSymbols++;
// Update auxiliary symbol info.
Symbol->Data.NumberOfAuxSymbols = Symbol->Aux.size();
Header.NumberOfSymbols += Symbol->Data.NumberOfAuxSymbols;
@@ -914,6 +846,22 @@ void WinCOFFObjectWriter::WriteObject(MC
Symbol->Index = -1;
}
+ // Build string table.
+ for (const auto &S : Sections)
+ if (S->Name.size() > COFF::NameSize)
+ Strings.add(S->Name);
+ for (const auto &S : Symbols)
+ if (S->should_keep() && S->Name.size() > COFF::NameSize)
+ Strings.add(S->Name);
+ Strings.finalize(StringTableBuilder::WinCOFF);
+
+ // Set names.
+ for (const auto &S : Sections)
+ SetSectionName(*S);
+ for (auto &S : Symbols)
+ if (S->should_keep())
+ SetSymbolName(*S);
+
// Fixup weak external references.
for (auto & Symbol : Symbols) {
if (Symbol->Other) {
@@ -1076,7 +1024,7 @@ void WinCOFFObjectWriter::WriteObject(MC
if (Symbol->Index != -1)
WriteSymbol(*Symbol);
- OS.write((char const *)&Strings.Data.front(), Strings.Data.size());
+ OS.write(Strings.data().data(), Strings.data().size());
}
MCWinCOFFObjectTargetWriter::MCWinCOFFObjectTargetWriter(unsigned Machine_) :
Modified: llvm/trunk/test/MC/COFF/section-name-encoding.s
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/test/MC/COFF/section-name-encoding.s?rev=218636&r1=218635&r2=218636&view=diff
==============================================================================
--- llvm/trunk/test/MC/COFF/section-name-encoding.s (original)
+++ llvm/trunk/test/MC/COFF/section-name-encoding.s Mon Sep 29 17:43:20 2014
@@ -21,14 +21,19 @@
.section s1234567; .long 1
+// Note: the names in the string table will be sorted in reverse
+// lexicographical order. Use a suffix letter (z, y, x, ...) to
+// get the preferred ordering of names in the test.
+
// Base 10 encoding
+// Ending in z should put the name first in the string table.
// /4
// CHECK: Section {
// CHECK: Number: 6
-// CHECK: Name: s12345678 (2F 34 00 00 00 00 00 00)
+// CHECK: Name: s1234567z (2F 34 00 00 00 00 00 00)
// CHECK: }
-.section s12345678; .long 1
+.section s1234567z; .long 1
// Generate padding sections to increase the string table size to at least
@@ -47,20 +52,20 @@
pad_sections2 \pad\pad\pad\pad\pad\pad\pad\pad\pad\pad\pad\pad\pad\pad\pad\pad\pad\pad\pad\pad
.endm
-// 1000x 'a'
-pad_sections aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa!
aaaaaaaaa
aaaaaaaaaaaaaaaa
+// 1000x 'y'
+pad_sections yyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyy!
yyyyyyyyy
yyyyyyyyyyyyyyyy
// /1000029 == 4 + 10 + (5 * (2 + (20 * 10 * 1000) + 1))
// v | | v ~~~~~~~~~~~~~~ v
// table size v v "p0" pad NUL separator
-// "s12345678\0" # of pad sections
+// "s1234567z\0" # of pad sections
//
// CHECK: Section {
// CHECK: Number: 12
-// CHECK: Name: seven_digit (2F 31 30 30 30 30 32 39)
+// CHECK: Name: sevendigitx (2F 31 30 30 30 30 32 39)
// CHECK: }
-.section seven_digit; .long 1
+.section sevendigitx; .long 1
// Generate padding sections to increase the string table size to at least
@@ -71,18 +76,18 @@ pad_sections aaaaaaaaaaaaaaaaaaaaaaaaaaa
.endm
// 1000x 'a'
-pad_sections_ex aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa!
aaaaaaaaa
aaaaaaaaaaaaaaaaaaa
+pad_sections_ex wwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwww!
wwwwwwwww
wwwwwwwwwwwwwwwwwww
// //AAmJa4 == 1000029 + 12 + (5 * (2 + (9 * 20 * 10 * 1000) + 1)) == 38*64^3 + 9*64^2 + 26*64 + 56
// v | | v ~~~~~~~~~~~~~~~~~~ v
// seven_digit offset v v "p0" pad NUL separator
-// "seven_digit\0" # of pad sections
+// "sevendigitx\0" # of pad sections
//
// "2F 2F 41 41 6D 4A 61 34" is "//AAmJa4", which decodes to "0 0 38 9 26 56".
//
// CHECK: Section {
// CHECK: Number: 18
-// CHECK: Name: double_slash (2F 2F 41 41 6D 4A 61 34)
+// CHECK: Name: doubleslashv (2F 2F 41 41 6D 4A 61 34)
// CHECK: }
-.section double_slash; .long 1
+.section doubleslashv; .long 1
Modified: llvm/trunk/tools/yaml2obj/yaml2elf.cpp
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/tools/yaml2obj/yaml2elf.cpp?rev=218636&r1=218635&r2=218636&view=diff
==============================================================================
--- llvm/trunk/tools/yaml2obj/yaml2elf.cpp (original)
+++ llvm/trunk/tools/yaml2obj/yaml2elf.cpp Mon Sep 29 17:43:20 2014
@@ -190,7 +190,7 @@ bool ELFState<ELFT>::initSectionHeaders(
for (const auto &Sec : Doc.Sections)
DotShStrtab.add(Sec->Name);
- DotShStrtab.finalize();
+ DotShStrtab.finalize(StringTableBuilder::ELF);
for (const auto &Sec : Doc.Sections) {
zero(SHeader);
@@ -261,7 +261,7 @@ void ELFState<ELFT>::initSymtabSectionHe
DotStrtab.add(Sym.Name);
for (const auto &Sym : Doc.Symbols.Weak)
DotStrtab.add(Sym.Name);
- DotStrtab.finalize();
+ DotStrtab.finalize(StringTableBuilder::ELF);
addSymbols(Doc.Symbols.Local, Syms, ELF::STB_LOCAL);
addSymbols(Doc.Symbols.Global, Syms, ELF::STB_GLOBAL);
Modified: llvm/trunk/unittests/MC/StringTableBuilderTest.cpp
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/unittests/MC/StringTableBuilderTest.cpp?rev=218636&r1=218635&r2=218636&view=diff
==============================================================================
--- llvm/trunk/unittests/MC/StringTableBuilderTest.cpp (original)
+++ llvm/trunk/unittests/MC/StringTableBuilderTest.cpp Mon Sep 29 17:43:20 2014
@@ -9,20 +9,21 @@
#include "llvm/MC/StringTableBuilder.h"
#include "gtest/gtest.h"
+#include "llvm/Support/Endian.h"
#include <string>
using namespace llvm;
namespace {
-TEST(StringTableBuilderTest, Basic) {
+TEST(StringTableBuilderTest, BasicELF) {
StringTableBuilder B;
B.add("foo");
B.add("bar");
B.add("foobar");
- B.finalize();
+ B.finalize(StringTableBuilder::ELF);
std::string Expected;
Expected += '\x00';
@@ -37,4 +38,34 @@ TEST(StringTableBuilderTest, Basic) {
EXPECT_EQ(8U, B.getOffset("foo"));
}
+TEST(StringTableBuilderTest, BasicWinCOFF) {
+ StringTableBuilder B;
+
+ // Strings must be 9 chars or longer to go in the table.
+ B.add("hippopotamus");
+ B.add("pygmy hippopotamus");
+ B.add("river horse");
+
+ B.finalize(StringTableBuilder::WinCOFF);
+
+ // size_field + "pygmy hippopotamus\0" + "river horse\0"
+ uint32_t ExpectedSize = 4 + 19 + 12;
+ EXPECT_EQ(ExpectedSize, B.data().size());
+
+ std::string Expected;
+
+ ExpectedSize =
+ support::endian::byte_swap<uint32_t, support::little>(ExpectedSize);
+ Expected.append((const char*)&ExpectedSize, 4);
+ Expected += "pygmy hippopotamus";
+ Expected += '\x00';
+ Expected += "river horse";
+ Expected += '\x00';
+
+ EXPECT_EQ(Expected, B.data());
+ EXPECT_EQ(4U, B.getOffset("pygmy hippopotamus"));
+ EXPECT_EQ(10U, B.getOffset("hippopotamus"));
+ EXPECT_EQ(23U, B.getOffset("river horse"));
+}
+
}
More information about the llvm-commits
mailing list