llvm.org GIT mirror llvm / 4edcbae
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 git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@218636 91177308-0d34-0410-b5e6-96231b3b80d8 Hans Wennborg 4 years ago
7 changed file(s) with 123 addition(s) and 109 deletion(s). Raw diff Collapse all Expand all
2828 return StringIndexMap.GetOrCreateValue(s, 0).getKey();
2929 }
3030
31 enum Kind {
32 ELF,
33 WinCOFF
34 };
35
3136 /// \brief Analyze the strings and build the final table. No more strings can
3237 /// be added after this point.
33 void finalize();
38 void finalize(Kind kind);
3439
3540 /// \brief Retrieve the string table data. Can only be used after the table
3641 /// is finalized.
4752 return StringIndexMap[s];
4853 }
4954
55 void clear();
56
5057 private:
5158 bool isFinalized() {
5259 return !StringTable.empty();
10721072 for (auto i = Asm.file_names_begin(), e = Asm.file_names_end(); i != e; ++i)
10731073 StrTabBuilder.add(*i);
10741074
1075 StrTabBuilder.finalize();
1075 StrTabBuilder.finalize(StringTableBuilder::ELF);
10761076
10771077 for (auto i = Asm.file_names_begin(), e = Asm.file_names_end(); i != e; ++i)
10781078 FileSymbolData.push_back(StrTabBuilder.getOffset(*i));
14451445 static_cast(it->getSection());
14461446 ShStrTabBuilder.add(Section.getSectionName());
14471447 }
1448 ShStrTabBuilder.finalize();
1448 ShStrTabBuilder.finalize(StringTableBuilder::ELF);
14491449 F->getContents().append(ShStrTabBuilder.data().begin(),
14501450 ShStrTabBuilder.data().end());
14511451 }
88
99 #include "llvm/MC/StringTableBuilder.h"
1010 #include "llvm/ADT/SmallVector.h"
11 #include "llvm/Support/COFF.h"
12 #include "llvm/Support/Endian.h"
1113
1214 using namespace llvm;
1315
2426 return sizeA > sizeB;
2527 }
2628
27 void StringTableBuilder::finalize() {
29 void StringTableBuilder::finalize(Kind kind) {
2830 SmallVector Strings;
31 Strings.reserve(StringIndexMap.size());
32
2933 for (auto i = StringIndexMap.begin(), e = StringIndexMap.end(); i != e; ++i)
3034 Strings.push_back(i->getKey());
3135
3236 std::sort(Strings.begin(), Strings.end(), compareBySuffix);
3337
34 // FIXME: Starting with a null byte is ELF specific. Generalize this so we
35 // can use the class with other object formats.
36 StringTable += '\x00';
38 if (kind == ELF) {
39 // Start the table with a NUL byte.
40 StringTable += '\x00';
41 } else if (kind == WinCOFF) {
42 // Make room to write the table size later.
43 StringTable.append(4, '\x00');
44 }
3745
3846 StringRef Previous;
3947 for (StringRef s : Strings) {
48 if (kind == WinCOFF)
49 assert(s.size() > COFF::NameSize && "Short string in COFF string table!");
50
4051 if (Previous.endswith(s)) {
4152 StringIndexMap[s] = StringTable.size() - 1 - s.size();
4253 continue;
4758 StringTable += '\x00';
4859 Previous = s;
4960 }
61
62 if (kind == WinCOFF) {
63 assert(StringTable.size() <= std::numeric_limits::max());
64 uint32_t size = static_cast(StringTable.size());
65 support::endian::write(
66 StringTable.data(), size);
67 }
5068 }
69
70 void StringTableBuilder::clear() {
71 StringTable.clear();
72 StringIndexMap.clear();
73 }
2525 #include "llvm/MC/MCSectionCOFF.h"
2626 #include "llvm/MC/MCSymbol.h"
2727 #include "llvm/MC/MCValue.h"
28 #include "llvm/MC/StringTableBuilder.h"
2829 #include "llvm/Support/COFF.h"
2930 #include "llvm/Support/Debug.h"
3031 #include "llvm/Support/Endian.h"
101102 static size_t size();
102103 };
103104
104 // This class holds the COFF string table.
105 class StringTable {
106 typedef StringMap map;
107 map Map;
108
109 void update_length();
110 public:
111 std::vector Data;
112
113 StringTable();
114 size_t size() const;
115 size_t insert(StringRef String);
116 void clear() {
117 Map.clear();
118 Data.resize(4);
119 update_length();
120 }
121 };
122
123105 class WinCOFFObjectWriter : public MCObjectWriter {
124106 public:
125107
135117 COFF::header Header;
136118 sections Sections;
137119 symbols Symbols;
138 StringTable Strings;
120 StringTableBuilder Strings;
139121
140122 // Maps used during object file creation.
141123 section_map SectionMap;
167149 void DefineSymbol(MCSymbolData const &SymbolData, MCAssembler &Assembler,
168150 const MCAsmLayout &Layout);
169151
170 void MakeSymbolReal(COFFSymbol &S, size_t Index);
171 void MakeSectionReal(COFFSection &S, size_t Number);
152 void SetSymbolName(COFFSymbol &S);
153 void SetSectionName(COFFSection &S);
172154
173155 bool ExportSymbol(const MCSymbol &Symbol, MCAssembler &Asm);
174156
261243
262244 size_t COFFSection::size() {
263245 return COFF::SectionSize;
264 }
265
266 //------------------------------------------------------------------------------
267 // StringTable class implementation
268
269 /// Write the length of the string table into Data.
270 /// The length of the string table includes uint32 length header.
271 void StringTable::update_length() {
272 write_uint32_le(&Data.front(), Data.size());
273 }
274
275 StringTable::StringTable() {
276 // The string table data begins with the length of the entire string table
277 // including the length header. Allocate space for this header.
278 Data.resize(4);
279 update_length();
280 }
281
282 size_t StringTable::size() const {
283 return Data.size();
284 }
285
286 /// Add String to the table iff it is not already there.
287 /// @returns the index into the string table where the string is now located.
288 size_t StringTable::insert(StringRef String) {
289 map::iterator i = Map.find(String);
290
291 if (i != Map.end())
292 return i->second;
293
294 size_t Offset = Data.size();
295
296 // Insert string data into string table.
297 Data.insert(Data.end(), String.begin(), String.end());
298 Data.push_back('\0');
299
300 // Put a reference to it in the map.
301 Map[String] = Offset;
302
303 // Update the internal length field.
304 update_length();
305
306 return Offset;
307246 }
308247
309248 //------------------------------------------------------------------------------
520459 }
521460 }
522461
523 /// making a section real involves assigned it a number and putting
524 /// name into the string table if needed
525 void WinCOFFObjectWriter::MakeSectionReal(COFFSection &S, size_t Number) {
462 void WinCOFFObjectWriter::SetSectionName(COFFSection &S) {
526463 if (S.Name.size() > COFF::NameSize) {
527 uint64_t StringTableEntry = Strings.insert(S.Name.c_str());
464 uint64_t StringTableEntry = Strings.getOffset(S.Name);
528465
529466 if (StringTableEntry <= Max6DecimalOffset) {
530467 std::sprintf(S.Header.Name, "/%d", unsigned(StringTableEntry));
542479 }
543480 } else
544481 std::memcpy(S.Header.Name, S.Name.c_str(), S.Name.size());
545
546 S.Number = Number;
547 S.Symbol->Data.SectionNumber = S.Number;
548 S.Symbol->Aux[0].Aux.SectionDefinition.Number = S.Number;
549 }
550
551 void WinCOFFObjectWriter::MakeSymbolReal(COFFSymbol &S, size_t Index) {
552 if (S.Name.size() > COFF::NameSize) {
553 size_t StringTableEntry = Strings.insert(S.Name.c_str());
554
555 S.set_name_offset(StringTableEntry);
556 } else
482 }
483
484 void WinCOFFObjectWriter::SetSymbolName(COFFSymbol &S) {
485 if (S.Name.size() > COFF::NameSize)
486 S.set_name_offset(Strings.getOffset(S.Name));
487 else
557488 std::memcpy(S.Data.Name, S.Name.c_str(), S.Name.size());
558 S.Index = Index;
559489 }
560490
561491 bool WinCOFFObjectWriter::ExportSymbol(const MCSymbol &Symbol,
859789
860790 DenseMap SectionIndices(
861791 NextPowerOf2(NumberOfSections));
792
793 // Assign section numbers.
862794 size_t Number = 1;
863795 for (const auto &Section : Sections) {
864796 SectionIndices[Section.get()] = Number;
865 MakeSectionReal(*Section, Number);
797 Section->Number = Number;
798 Section->Symbol->Data.SectionNumber = Number;
799 Section->Symbol->Aux[0].Aux.SectionDefinition.Number = Number;
866800 ++Number;
867801 }
868802
902836 // Update section number & offset for symbols that have them.
903837 if (Symbol->Section)
904838 Symbol->Data.SectionNumber = Symbol->Section->Number;
905
906839 if (Symbol->should_keep()) {
907 MakeSymbolReal(*Symbol, Header.NumberOfSymbols++);
908
840 Symbol->Index = Header.NumberOfSymbols++;
909841 // Update auxiliary symbol info.
910842 Symbol->Data.NumberOfAuxSymbols = Symbol->Aux.size();
911843 Header.NumberOfSymbols += Symbol->Data.NumberOfAuxSymbols;
912844 } else
913845 Symbol->Index = -1;
914846 }
847
848 // Build string table.
849 for (const auto &S : Sections)
850 if (S->Name.size() > COFF::NameSize)
851 Strings.add(S->Name);
852 for (const auto &S : Symbols)
853 if (S->should_keep() && S->Name.size() > COFF::NameSize)
854 Strings.add(S->Name);
855 Strings.finalize(StringTableBuilder::WinCOFF);
856
857 // Set names.
858 for (const auto &S : Sections)
859 SetSectionName(*S);
860 for (auto &S : Symbols)
861 if (S->should_keep())
862 SetSymbolName(*S);
915863
916864 // Fixup weak external references.
917865 for (auto & Symbol : Symbols) {
10751023 if (Symbol->Index != -1)
10761024 WriteSymbol(*Symbol);
10771025
1078 OS.write((char const *)&Strings.Data.front(), Strings.Data.size());
1026 OS.write(Strings.data().data(), Strings.data().size());
10791027 }
10801028
10811029 MCWinCOFFObjectTargetWriter::MCWinCOFFObjectTargetWriter(unsigned Machine_) :
2020 .section s1234567; .long 1
2121
2222
23 // Note: the names in the string table will be sorted in reverse
24 // lexicographical order. Use a suffix letter (z, y, x, ...) to
25 // get the preferred ordering of names in the test.
26
2327 // Base 10 encoding
28 // Ending in z should put the name first in the string table.
2429
2530 // /4
2631 // CHECK: Section {
2732 // CHECK: Number: 6
28 // CHECK: Name: s12345678 (2F 34 00 00 00 00 00 00)
33 // CHECK: Name: s1234567z (2F 34 00 00 00 00 00 00)
2934 // CHECK: }
30 .section s12345678; .long 1
35 .section s1234567z; .long 1
3136
3237
3338 // Generate padding sections to increase the string table size to at least
4651 pad_sections2 \pad\pad\pad\pad\pad\pad\pad\pad\pad\pad\pad\pad\pad\pad\pad\pad\pad\pad\pad\pad
4752 .endm
4853
49 // 1000x 'a'
50 pad_sections aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa
54 // 1000x 'y'
55 pad_sections yyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyy
5156
5257
5358 // /1000029 == 4 + 10 + (5 * (2 + (20 * 10 * 1000) + 1))
5459 // v | | v ~~~~~~~~~~~~~~ v
5560 // table size v v "p0" pad NUL separator
56 // "s12345678\0" # of pad sections
61 // "s1234567z\0" # of pad sections
5762 //
5863 // CHECK: Section {
5964 // CHECK: Number: 12
60 // CHECK: Name: seven_digit (2F 31 30 30 30 30 32 39)
65 // CHECK: Name: sevendigitx (2F 31 30 30 30 30 32 39)
6166 // CHECK: }
62 .section seven_digit; .long 1
67 .section sevendigitx; .long 1
6368
6469
6570 // Generate padding sections to increase the string table size to at least
7075 .endm
7176
7277 // 1000x 'a'
73 pad_sections_ex aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa
78 pad_sections_ex wwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwww
7479
7580
7681 // //AAmJa4 == 1000029 + 12 + (5 * (2 + (9 * 20 * 10 * 1000) + 1)) == 38*64^3 + 9*64^2 + 26*64 + 56
7782 // v | | v ~~~~~~~~~~~~~~~~~~ v
7883 // seven_digit offset v v "p0" pad NUL separator
79 // "seven_digit\0" # of pad sections
84 // "sevendigitx\0" # of pad sections
8085 //
8186 // "2F 2F 41 41 6D 4A 61 34" is "//AAmJa4", which decodes to "0 0 38 9 26 56".
8287 //
8388 // CHECK: Section {
8489 // CHECK: Number: 18
85 // CHECK: Name: double_slash (2F 2F 41 41 6D 4A 61 34)
90 // CHECK: Name: doubleslashv (2F 2F 41 41 6D 4A 61 34)
8691 // CHECK: }
87 .section double_slash; .long 1
92 .section doubleslashv; .long 1
189189
190190 for (const auto &Sec : Doc.Sections)
191191 DotShStrtab.add(Sec->Name);
192 DotShStrtab.finalize();
192 DotShStrtab.finalize(StringTableBuilder::ELF);
193193
194194 for (const auto &Sec : Doc.Sections) {
195195 zero(SHeader);
260260 DotStrtab.add(Sym.Name);
261261 for (const auto &Sym : Doc.Symbols.Weak)
262262 DotStrtab.add(Sym.Name);
263 DotStrtab.finalize();
263 DotStrtab.finalize(StringTableBuilder::ELF);
264264
265265 addSymbols(Doc.Symbols.Local, Syms, ELF::STB_LOCAL);
266266 addSymbols(Doc.Symbols.Global, Syms, ELF::STB_GLOBAL);
88
99 #include "llvm/MC/StringTableBuilder.h"
1010 #include "gtest/gtest.h"
11 #include "llvm/Support/Endian.h"
1112 #include
1213
1314 using namespace llvm;
1415
1516 namespace {
1617
17 TEST(StringTableBuilderTest, Basic) {
18 TEST(StringTableBuilderTest, BasicELF) {
1819 StringTableBuilder B;
1920
2021 B.add("foo");
2122 B.add("bar");
2223 B.add("foobar");
2324
24 B.finalize();
25 B.finalize(StringTableBuilder::ELF);
2526
2627 std::string Expected;
2728 Expected += '\x00';
3637 EXPECT_EQ(8U, B.getOffset("foo"));
3738 }
3839
40 TEST(StringTableBuilderTest, BasicWinCOFF) {
41 StringTableBuilder B;
42
43 // Strings must be 9 chars or longer to go in the table.
44 B.add("hippopotamus");
45 B.add("pygmy hippopotamus");
46 B.add("river horse");
47
48 B.finalize(StringTableBuilder::WinCOFF);
49
50 // size_field + "pygmy hippopotamus\0" + "river horse\0"
51 uint32_t ExpectedSize = 4 + 19 + 12;
52 EXPECT_EQ(ExpectedSize, B.data().size());
53
54 std::string Expected;
55
56 ExpectedSize =
57 support::endian::byte_swap(ExpectedSize);
58 Expected.append((const char*)&ExpectedSize, 4);
59 Expected += "pygmy hippopotamus";
60 Expected += '\x00';
61 Expected += "river horse";
62 Expected += '\x00';
63
64 EXPECT_EQ(Expected, B.data());
65 EXPECT_EQ(4U, B.getOffset("pygmy hippopotamus"));
66 EXPECT_EQ(10U, B.getOffset("hippopotamus"));
67 EXPECT_EQ(23U, B.getOffset("river horse"));
3968 }
69
70 }