llvm.org GIT mirror llvm / a8febf2
ELFObjectWriter: deduplicate suffices in strtab We already do this for shstrtab, so might as well do it for strtab. This extracts the string table building code into a separate class. The idea is to use it for other object formats too. I mostly wanted to do this for the general principle, but it does save a little bit on object file size. I tried this on a clang bootstrap and saved 0.54% on the sum of object file sizes (1.14 MB out of 212 MB for a release build). Differential Revision: http://reviews.llvm.org/D3533 git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@207670 91177308-0d34-0410-b5e6-96231b3b80d8 Hans Wennborg 5 years ago
22 changed file(s) with 300 addition(s) and 183 deletion(s). Raw diff Collapse all Expand all
0 //===-- StringTableBuilder.h - String table building utility ------*- C++ -*-=//
1 //
2 // The LLVM Compiler Infrastructure
3 //
4 // This file is distributed under the University of Illinois Open Source
5 // License. See LICENSE.TXT for details.
6 //
7 //===----------------------------------------------------------------------===//
8
9 #ifndef LLVM_OBJECT_STRINGTABLE_BUILDER_H
10 #define LLVM_OBJECT_STRINGTABLE_BUILDER_H
11
12 #include "llvm/ADT/SmallString.h"
13 #include "llvm/ADT/StringMap.h"
14 #include
15
16 namespace llvm {
17
18 /// \brief Utility for building string tables with deduplicated suffixes.
19 class StringTableBuilder {
20 SmallString<256> StringTable;
21 StringMap StringIndexMap;
22
23 public:
24 /// \brief Add a string to the builder. Returns a StringRef to the internal
25 /// copy of s. Can only be used before the table is finalized.
26 StringRef add(StringRef s) {
27 assert(!isFinalized());
28 return StringIndexMap.GetOrCreateValue(s, 0).getKey();
29 }
30
31 /// \brief Analyze the strings and build the final table. No more strings can
32 /// be added after this point.
33 void finalize();
34
35 /// \brief Retrieve the string table data. Can only be used after the table
36 /// is finalized.
37 StringRef data() {
38 assert(isFinalized());
39 return StringTable;
40 }
41
42 /// \brief Get the offest of a string in the string table. Can only be used
43 /// after the table is finalized.
44 size_t getOffset(StringRef s) {
45 assert(isFinalized());
46 assert(StringIndexMap.count(s) && "String is not in table!");
47 return StringIndexMap[s];
48 }
49
50 private:
51 bool isFinalized() {
52 return !StringTable.empty();
53 }
54 };
55
56 } // end llvm namespace
57
58 #endif
2727 #include "llvm/MC/MCObjectWriter.h"
2828 #include "llvm/MC/MCSectionELF.h"
2929 #include "llvm/MC/MCValue.h"
30 #include "llvm/Object/StringTableBuilder.h"
3031 #include "llvm/Support/Compression.h"
3132 #include "llvm/Support/Debug.h"
3233 #include "llvm/Support/Endian.h"
131132 MCSymbolData *SymbolData;
132133 uint64_t StringIndex;
133134 uint32_t SectionIndex;
135 StringRef Name;
134136
135137 // Support lexicographic sorting.
136138 bool operator<(const ELFSymbolData &RHS) const {
137 return SymbolData->getSymbol().getName() <
138 RHS.SymbolData->getSymbol().getName();
139 return Name < RHS.Name;
139140 }
140141 };
141142
148149
149150 llvm::DenseMap>
150151 Relocations;
151 DenseMap SectionStringTableIndex;
152 StringTableBuilder ShStrTabBuilder;
152153
153154 /// @}
154155 /// @name Symbol Table Data
155156 /// @{
156157
157 SmallString<256> StringTable;
158 StringTableBuilder StrTabBuilder;
158159 std::vector FileSymbolData;
159160 std::vector LocalSymbolData;
160161 std::vector ExternalSymbolData;
675676 SectionIndexMapTy &SectionIndexMap) {
676677 // The string table must be emitted first because we need the index
677678 // into the string table for all the symbol names.
678 assert(StringTable.size() && "Missing string table");
679679
680680 // FIXME: Make sure the start of the symbol table is aligned.
681681
10281028 MCSymbolData &Data = Asm.getOrCreateSymbolData(*Sym);
10291029 Data.setExternal(true);
10301030 MCELF::SetBinding(Data, ELF::STB_GLOBAL);
1031 }
1032
1033 // Index 0 is always the empty string.
1034 StringMap StringIndexMap;
1035 StringTable += '\x00';
1036
1037 // FIXME: We could optimize suffixes in strtab in the same way we
1038 // optimize them in shstrtab.
1039
1040 for (MCAssembler::const_file_name_iterator it = Asm.file_names_begin(),
1041 ie = Asm.file_names_end();
1042 it != ie;
1043 ++it) {
1044 StringRef Name = *it;
1045 uint64_t &Entry = StringIndexMap[Name];
1046 if (!Entry) {
1047 Entry = StringTable.size();
1048 StringTable += Name;
1049 StringTable += '\x00';
1050 }
1051 FileSymbolData.push_back(Entry);
10521031 }
10531032
10541033 // Add the data for the symbols.
11011080 // @@ in defined ones.
11021081 StringRef Name = Symbol.getName();
11031082 SmallString<32> Buf;
1104
11051083 size_t Pos = Name.find("@@@");
11061084 if (Pos != StringRef::npos) {
11071085 Buf += Name.substr(0, Pos);
11091087 Buf += Name.substr(Pos + Skip);
11101088 Name = Buf;
11111089 }
1112
1113 uint64_t &Entry = StringIndexMap[Name];
1114 if (!Entry) {
1115 Entry = StringTable.size();
1116 StringTable += Name;
1117 StringTable += '\x00';
1118 }
1119 MSD.StringIndex = Entry;
1090 MSD.Name = StrTabBuilder.add(Name);
1091
11201092 if (MSD.SectionIndex == ELF::SHN_UNDEF)
11211093 UndefinedSymbolData.push_back(MSD);
11221094 else if (Local)
11241096 else
11251097 ExternalSymbolData.push_back(MSD);
11261098 }
1099
1100 for (auto i = Asm.file_names_begin(), e = Asm.file_names_end(); i != e; ++i)
1101 StrTabBuilder.add(*i);
1102
1103 StrTabBuilder.finalize();
1104
1105 for (auto i = Asm.file_names_begin(), e = Asm.file_names_end(); i != e; ++i)
1106 FileSymbolData.push_back(StrTabBuilder.getOffset(*i));
1107
1108 for (ELFSymbolData& MSD : LocalSymbolData)
1109 MSD.StringIndex = StrTabBuilder.getOffset(MSD.Name);
1110 for (ELFSymbolData& MSD : ExternalSymbolData)
1111 MSD.StringIndex = StrTabBuilder.getOffset(MSD.Name);
1112 for (ELFSymbolData& MSD : UndefinedSymbolData)
1113 MSD.StringIndex = StrTabBuilder.getOffset(MSD.Name);
11271114
11281115 // Symbols are required to be in lexicographic order.
11291116 array_pod_sort(LocalSymbolData.begin(), LocalSymbolData.end());
14351422 }
14361423 }
14371424
1438 static int compareBySuffix(const MCSectionELF *const *a,
1439 const MCSectionELF *const *b) {
1440 const StringRef &NameA = (*a)->getSectionName();
1441 const StringRef &NameB = (*b)->getSectionName();
1442 const unsigned sizeA = NameA.size();
1443 const unsigned sizeB = NameB.size();
1444 const unsigned len = std::min(sizeA, sizeB);
1445 for (unsigned int i = 0; i < len; ++i) {
1446 char ca = NameA[sizeA - i - 1];
1447 char cb = NameB[sizeB - i - 1];
1448 if (ca != cb)
1449 return cb - ca;
1450 }
1451
1452 return sizeB - sizeA;
1453 }
1454
14551425 void ELFObjectWriter::CreateMetadataSections(MCAssembler &Asm,
14561426 MCAsmLayout &Layout,
14571427 SectionIndexMapTy &SectionIndexMap,
14921462 WriteSymbolTable(F, Asm, Layout, SectionIndexMap);
14931463
14941464 F = new MCDataFragment(&StrtabSD);
1495 F->getContents().append(StringTable.begin(), StringTable.end());
1465 F->getContents().append(StrTabBuilder.data().begin(),
1466 StrTabBuilder.data().end());
14961467
14971468 F = new MCDataFragment(&ShstrtabSD);
14981469
1499 std::vector Sections;
1500 for (MCAssembler::const_iterator it = Asm.begin(),
1501 ie = Asm.end(); it != ie; ++it) {
1470 // Section header string table.
1471 for (auto it = Asm.begin(), ie = Asm.end(); it != ie; ++it) {
15021472 const MCSectionELF &Section =
15031473 static_cast(it->getSection());
1504 Sections.push_back(&Section);
1505 }
1506 array_pod_sort(Sections.begin(), Sections.end(), compareBySuffix);
1507
1508 // Section header string table.
1509 //
1510 // The first entry of a string table holds a null character so skip
1511 // section 0.
1512 uint64_t Index = 1;
1513 F->getContents().push_back('\x00');
1514
1515 for (unsigned int I = 0, E = Sections.size(); I != E; ++I) {
1516 const MCSectionELF &Section = *Sections[I];
1517
1518 StringRef Name = Section.getSectionName();
1519 if (I != 0) {
1520 StringRef PreviousName = Sections[I - 1]->getSectionName();
1521 if (PreviousName.endswith(Name)) {
1522 SectionStringTableIndex[&Section] = Index - Name.size() - 1;
1523 continue;
1524 }
1525 }
1526 // Remember the index into the string table so we can write it
1527 // into the sh_name field of the section header table.
1528 SectionStringTableIndex[&Section] = Index;
1529
1530 Index += Name.size() + 1;
1531 F->getContents().append(Name.begin(), Name.end());
1532 F->getContents().push_back('\x00');
1533 }
1474 ShStrTabBuilder.add(Section.getSectionName());
1475 }
1476 ShStrTabBuilder.finalize();
1477 F->getContents().append(ShStrTabBuilder.data().begin(),
1478 ShStrTabBuilder.data().end());
15341479 }
15351480
15361481 void ELFObjectWriter::CreateIndexedSections(MCAssembler &Asm,
15981543
15991544 switch(Section.getType()) {
16001545 case ELF::SHT_DYNAMIC:
1601 sh_link = SectionStringTableIndex[&Section];
1546 sh_link = ShStrTabBuilder.getOffset(Section.getSectionName());
16021547 sh_info = 0;
16031548 break;
16041549
16791624 }
16801625 }
16811626
1682 WriteSecHdrEntry(SectionStringTableIndex[&Section], Section.getType(),
1627 WriteSecHdrEntry(ShStrTabBuilder.getOffset(Section.getSectionName()),
1628 Section.getType(),
16831629 Section.getFlags(), 0, Offset, Size, sh_link, sh_info,
16841630 Alignment, Section.getEntrySize());
16851631 }
1111 MachOUniversal.cpp
1212 Object.cpp
1313 ObjectFile.cpp
14 StringTableBuilder.cpp
1415 SymbolicFile.cpp
1516 YAML.cpp
1617 )
0 //===-- StringTableBuilder.cpp - String table building utility ------------===//
1 //
2 // The LLVM Compiler Infrastructure
3 //
4 // This file is distributed under the University of Illinois Open Source
5 // License. See LICENSE.TXT for details.
6 //
7 //===----------------------------------------------------------------------===//
8
9 #include "llvm/ADT/SmallVector.h"
10 #include "llvm/Object/StringTableBuilder.h"
11
12 using namespace llvm;
13
14 static bool compareBySuffix(StringRef a, StringRef b) {
15 size_t sizeA = a.size();
16 size_t sizeB = b.size();
17 size_t len = std::min(sizeA, sizeB);
18 for (size_t i = 0; i < len; ++i) {
19 char ca = a[sizeA - i - 1];
20 char cb = b[sizeB - i - 1];
21 if (ca != cb)
22 return ca > cb;
23 }
24 return sizeA > sizeB;
25 }
26
27 void StringTableBuilder::finalize() {
28 SmallVector Strings;
29 for (auto i = StringIndexMap.begin(), e = StringIndexMap.end(); i != e; ++i)
30 Strings.push_back(i->getKey());
31
32 std::sort(Strings.begin(), Strings.end(), compareBySuffix);
33
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';
37
38 StringRef Previous;
39 for (StringRef s : Strings) {
40 if (Previous.endswith(s)) {
41 StringIndexMap[s] = StringTable.size() - 1 - s.size();
42 continue;
43 }
44
45 StringIndexMap[s] = StringTable.size();
46 StringTable += s;
47 StringTable += '\x00';
48 Previous = s;
49 }
50 }
542542
543543 // CHECK-ELF: Symbols [
544544 // CHECK-ELF: Symbol {
545 // CHECK-ELF: Name: var (6)
545 // CHECK-ELF: Name: var
546546 // CHECK-ELF-NEXT: Value:
547547 // CHECK-ELF-NEXT: Size:
548548 // CHECK-ELF-NEXT: Binding: Global
312312
313313 // CHECK-ELF: Symbols [
314314 // CHECK-ELF: Symbol {
315 // CHECK-ELF: Name: var (6)
315 // CHECK-ELF: Name: var
316316 // CHECK-ELF-NEXT: Value:
317317 // CHECK-ELF-NEXT: Size:
318318 // CHECK-ELF-NEXT: Binding: Global
4848 // Test that g1 and g2 are local, but g3 is an undefined global.
4949
5050 // CHECK: Symbol {
51 // CHECK: Name: g1 (1)
51 // CHECK: Name: g1
5252 // CHECK-NEXT: Value: 0x0
5353 // CHECK-NEXT: Size: 0
5454 // CHECK-NEXT: Binding: Local
5757 // CHECK-NEXT: Section: .foo (0x7)
5858 // CHECK-NEXT: }
5959 // CHECK-NEXT: Symbol {
60 // CHECK-NEXT: Name: g2 (4)
60 // CHECK-NEXT: Name: g2
6161 // CHECK-NEXT: Value: 0x0
6262 // CHECK-NEXT: Size: 0
6363 // CHECK-NEXT: Binding: Local
6767 // CHECK-NEXT: }
6868
6969 // CHECK: Symbol {
70 // CHECK: Name: g3 (7)
70 // CHECK: Name: g3
7171 // CHECK-NEXT: Value: 0x0
7272 // CHECK-NEXT: Size: 0
7373 // CHECK-NEXT: Binding: Global
88 .comm common1,1,1
99
1010 // CHECK: Symbol {
11 // CHECK: Name: common1 (1)
11 // CHECK: Name: common1
1212 // CHECK-NEXT: Value: 0x0
1313 // CHECK-NEXT: Size: 1
1414 // CHECK-NEXT: Binding: Local
2424 .comm common2,1,1
2525
2626 // CHECK: Symbol {
27 // CHECK: Name: common2 (9)
27 // CHECK: Name: common2
2828 // CHECK-NEXT: Value: 0x1
2929 // CHECK-NEXT: Size: 1
3030 // CHECK-NEXT: Binding: Local
3838 .comm common6,8,16
3939
4040 // CHECK: Symbol {
41 // CHECK: Name: common6 (17)
41 // CHECK: Name: common6
4242 // CHECK-NEXT: Value: 0x10
4343 // CHECK-NEXT: Size: 8
4444 // CHECK-NEXT: Binding: Local
5353 .comm common3,4,4
5454
5555 // CHECK: Symbol {
56 // CHECK: Name: common3 (25)
56 // CHECK: Name: common3
5757 // CHECK-NEXT: Value: 0x4
5858 // CHECK-NEXT: Size: 4
5959 // CHECK-NEXT: Binding: Global
7575 .comm common4,40,16
7676
7777 // CHECK: Symbol {
78 // CHECK: Name: common4 (37)
78 // CHECK: Name: common4
7979 // CHECK-NEXT: Value: 0x10
8080 // CHECK-NEXT: Size: 40
8181 // CHECK-NEXT: Binding: Global
8888 .comm common5,4,4
8989
9090 // CHECK: Symbol {
91 // CHECK: Name: common5 (45)
91 // CHECK: Name: common5
9292 // CHECK-NEXT: Value: 0x4
9393 // CHECK-NEXT: Size: 4
9494 // CHECK-NEXT: Binding: Global
1010 bar.c:
1111
1212 // CHECK: Symbol {
13 // CHECK: Name: foo.c (1)
13 // CHECK: Name: foo.c
1414 // CHECK-NEXT: Value: 0x0
1515 // CHECK-NEXT: Size: 0
1616 // CHECK-NEXT: Binding: Local
1818 // CHECK-NEXT: Other: 0
1919 // CHECK-NEXT: Section: Absolute (0xFFF1)
2020 // CHECK-NEXT: }
21 // CHECK: Name: bar.c (7)
21 // CHECK: Name: bar.c
2222 // CHECK-NEXT: Value: 0x0
2323 // CHECK-NEXT: Size: 0
2424 // CHECK-NEXT: Binding: Local
2727 // CHECK-NEXT: Section: Absolute (0xFFF1)
2828 // CHECK-NEXT: }
2929 // CHECK: Symbol {
30 // CHECK: Name: bar.c (7)
30 // CHECK: Name: bar.c
3131 // CHECK-NEXT: Value: 0x0
3232 // CHECK-NEXT: Size: 0
3333 // CHECK-NEXT: Binding: Global
3636 // CHECK-NEXT: Section: .text (0x1)
3737 // CHECK-NEXT: }
3838 // CHECK: Symbol {
39 // CHECK: Name: foo.c (1)
39 // CHECK: Name: foo.c
4040 // CHECK-NEXT: Value: 0x0
4141 // CHECK-NEXT: Size: 0
4242 // CHECK-NEXT: Binding: Global
33 .lcomm B, 32 << 20
44
55 // CHECK: Symbol {
6 // CHECK: Name: A (1)
6 // CHECK: Name: A
77 // CHECK-NEXT: Value: 0x0
88 // CHECK-NEXT: Size: 5
99 // CHECK-NEXT: Binding: Local
1212 // CHECK-NEXT: Section: .bss (0x3)
1313 // CHECK-NEXT: }
1414 // CHECK: Symbol {
15 // CHECK: Name: B (3)
15 // CHECK: Name: B
1616 // CHECK-NEXT: Value: 0x5
1717 // CHECK-NEXT: Size: 33554432
1818 // CHECK-NEXT: Binding: Local
1111
1212
1313 // Test that both a and b show up in the correct section.
14 // SYMBOLS: Name: a (1)
14 // SYMBOLS: Name: a
1515 // SYMBOLS-NEXT: Value: 0x0
1616 // SYMBOLS-NEXT: Size: 0
1717 // SYMBOLS-NEXT: Binding: Local (0x0)
2020 // SYMBOLS-NEXT: Section: last (0xFF00)
2121 // SYMBOLS-NEXT: }
2222 // SYMBOLS-NEXT: Symbol {
23 // SYMBOLS-NEXT: Name: b (3)
23 // SYMBOLS-NEXT: Name: b
2424 // SYMBOLS-NEXT: Value: 0x1
2525 // SYMBOLS-NEXT: Size: 0
2626 // SYMBOLS-NEXT: Binding: Local (0x0)
3131
3232
3333 // Test that this file has one section too many.
34 // SYMBOLS: Name: last (0)
34 // SYMBOLS: Name: last
3535 // SYMBOLS-NEXT: Value: 0x0
3636 // SYMBOLS-NEXT: Size: 0
3737 // SYMBOLS-NEXT: Binding: Local (0x0)
66 // CHECK-NEXT: ]
77
88 // CHECK: Symbol {
9 // CHECK: Name: baz (5)
9 // CHECK: Name: baz
1010 // CHECK-NEXT: Value: 0x0
1111 // CHECK-NEXT: Size: 0
1212 // CHECK-NEXT: Binding: Global
77
88
99 // CHECK: Symbol {
10 // CHECK: Name: bar (5)
10 // CHECK: Name: bar
1111 // CHECK-NEXT: Value: 0x0
1212 // CHECK-NEXT: Size: 0
1313 // CHECK-NEXT: Binding: Global
1616 // CHECK-NEXT: Section: Undefined (0x0)
1717 // CHECK-NEXT: }
1818 // CHECK-NEXT: Symbol {
19 // CHECK-NEXT: Name: foo (1)
19 // CHECK-NEXT: Name: foo
2020 // CHECK-NEXT: Value: 0x0
2121 // CHECK-NEXT: Size: 0
2222 // CHECK-NEXT: Binding: Global
44 .set kernbase,0xffffffff80000000
55
66 // CHECK: Symbol {
7 // CHECK: Name: kernbase (1)
7 // CHECK: Name: kernbase
88 // CHECK-NEXT: Value: 0xFFFFFFFF80000000
99 // CHECK-NEXT: Size: 0
1010 // CHECK-NEXT: Binding: Local
2525
2626 // Test that there is an undefined reference to bar
2727 // CHECK: Symbol {
28 // CHECK: Name: bar (10)
28 // CHECK: Name: bar
2929 // CHECK-NEXT: Value: 0x0
3030 // CHECK-NEXT: Size: 0
3131 // CHECK-NEXT: Binding: Global
0 // RUN: llvm-mc -filetype=obj -triple i686-pc-linux-gnu %s -o - | llvm-readobj -symbols | FileCheck %s
1
2 .text
3 .globl foobar
4 .align 16, 0x90
5 .type foobar,@function
6 foobar:
7 pushl %ebp
8 movl %esp, %ebp
9 subl $8, %esp
10 calll foo
11 calll bar
12 addl $8, %esp
13 popl %ebp
14 retl
15 .Ltmp3:
16 .size foobar, .Ltmp3-foobar
17
18 // CHECK: Name: foobar (1)
19 // CHECK: Name: bar (4)
20 // CHECK: Name: foo (8)
1717 .long fooE@INDNTPOFF
1818
1919 // CHECK: Symbol {
20 // CHECK: Name: foo1 (1)
20 // CHECK: Name: foo1
2121 // CHECK-NEXT: Value: 0x0
2222 // CHECK-NEXT: Size: 0
2323 // CHECK-NEXT: Binding: Global
2626 // CHECK-NEXT: Section: Undefined (0x0)
2727 // CHECK-NEXT: }
2828 // CHECK-NEXT: Symbol {
29 // CHECK-NEXT: Name: foo2 (6)
29 // CHECK-NEXT: Name: foo2
3030 // CHECK-NEXT: Value: 0x0
3131 // CHECK-NEXT: Size: 0
3232 // CHECK-NEXT: Binding: Global
3535 // CHECK-NEXT: Section: Undefined (0x0)
3636 // CHECK-NEXT: }
3737 // CHECK-NEXT: Symbol {
38 // CHECK-NEXT: Name: foo3 (11)
38 // CHECK-NEXT: Name: foo3
3939 // CHECK-NEXT: Value: 0x0
4040 // CHECK-NEXT: Size: 0
4141 // CHECK-NEXT: Binding: Global
4444 // CHECK-NEXT: Section: Undefined (0x0)
4545 // CHECK-NEXT: }
4646 // CHECK-NEXT: Symbol {
47 // CHECK-NEXT: Name: foo4 (16)
47 // CHECK-NEXT: Name: foo4
4848 // CHECK-NEXT: Value: 0x0
4949 // CHECK-NEXT: Size: 0
5050 // CHECK-NEXT: Binding: Global
5353 // CHECK-NEXT: Section: Undefined (0x0)
5454 // CHECK-NEXT: }
5555 // CHECK-NEXT: Symbol {
56 // CHECK-NEXT: Name: foo5 (21)
56 // CHECK-NEXT: Name: foo5
5757 // CHECK-NEXT: Value: 0x0
5858 // CHECK-NEXT: Size: 0
5959 // CHECK-NEXT: Binding: Global
6262 // CHECK-NEXT: Section: Undefined (0x0)
6363 // CHECK-NEXT: }
6464 // CHECK-NEXT: Symbol {
65 // CHECK-NEXT: Name: foo6 (26)
65 // CHECK-NEXT: Name: foo6
6666 // CHECK-NEXT: Value: 0x0
6767 // CHECK-NEXT: Size: 0
6868 // CHECK-NEXT: Binding: Global
7171 // CHECK-NEXT: Section: Undefined (0x0)
7272 // CHECK-NEXT: }
7373 // CHECK-NEXT: Symbol {
74 // CHECK-NEXT: Name: foo7 (31)
74 // CHECK-NEXT: Name: foo7
7575 // CHECK-NEXT: Value: 0x0
7676 // CHECK-NEXT: Size: 0
7777 // CHECK-NEXT: Binding: Global
8080 // CHECK-NEXT: Section: Undefined (0x0)
8181 // CHECK-NEXT: }
8282 // CHECK-NEXT: Symbol {
83 // CHECK-NEXT: Name: foo8 (36)
83 // CHECK-NEXT: Name: foo8
8484 // CHECK-NEXT: Value: 0x0
8585 // CHECK-NEXT: Size: 0
8686 // CHECK-NEXT: Binding: Global
8989 // CHECK-NEXT: Section: Undefined (0x0)
9090 // CHECK-NEXT: }
9191 // CHECK-NEXT: Symbol {
92 // CHECK-NEXT: Name: foo9 (41)
92 // CHECK-NEXT: Name: foo9
9393 // CHECK-NEXT: Value: 0x0
9494 // CHECK-NEXT: Size: 0
9595 // CHECK-NEXT: Binding: Global
9898 // CHECK-NEXT: Section: Undefined (0x0)
9999 // CHECK-NEXT: }
100100 // CHECK-NEXT: Symbol {
101 // CHECK-NEXT: Name: fooA (46)
101 // CHECK-NEXT: Name: fooA
102102 // CHECK-NEXT: Value: 0x0
103103 // CHECK-NEXT: Size: 0
104104 // CHECK-NEXT: Binding: Global
107107 // CHECK-NEXT: Section: Undefined (0x0)
108108 // CHECK-NEXT: }
109109 // CHECK-NEXT: Symbol {
110 // CHECK-NEXT: Name: fooB (51)
110 // CHECK-NEXT: Name: fooB
111111 // CHECK-NEXT: Value: 0x0
112112 // CHECK-NEXT: Size: 0
113113 // CHECK-NEXT: Binding: Global
116116 // CHECK-NEXT: Section: Undefined (0x0)
117117 // CHECK-NEXT: }
118118 // CHECK-NEXT: Symbol {
119 // CHECK-NEXT: Name: fooC (56)
119 // CHECK-NEXT: Name: fooC
120120 // CHECK-NEXT: Value: 0x0
121121 // CHECK-NEXT: Size: 0
122122 // CHECK-NEXT: Binding: Global
125125 // CHECK-NEXT: Section: Undefined (0x0)
126126 // CHECK-NEXT: }
127127 // CHECK-NEXT: Symbol {
128 // CHECK-NEXT: Name: fooD (61)
128 // CHECK-NEXT: Name: fooD
129129 // CHECK-NEXT: Value: 0x0
130130 // CHECK-NEXT: Size: 0
131131 // CHECK-NEXT: Binding: Global
134134 // CHECK-NEXT: Section: Undefined (0x0)
135135 // CHECK-NEXT: }
136136 // CHECK-NEXT: Symbol {
137 // CHECK-NEXT: Name: fooE (66)
137 // CHECK-NEXT: Name: fooE
138138 // CHECK-NEXT: Value: 0x0
139139 // CHECK-NEXT: Size: 0
140140 // CHECK-NEXT: Binding: Global
1212 .long 43
1313
1414 // CHECK: Symbol {
15 // CHECK: Name: foobar (31)
15 // CHECK: Name: foobar
1616 // CHECK-NEXT: Value: 0x0
1717 // CHECK-NEXT: Size: 0
1818 // CHECK-NEXT: Binding: Local
2222 // CHECK-NEXT: }
2323
2424 // CHECK: Symbol {
25 // CHECK: Name: foo1 (1)
25 // CHECK: Name: foo1
2626 // CHECK-NEXT: Value: 0x0
2727 // CHECK-NEXT: Size: 0
2828 // CHECK-NEXT: Binding: Global
3131 // CHECK-NEXT: Section: Undefined (0x0)
3232 // CHECK-NEXT: }
3333 // CHECK-NEXT: Symbol {
34 // CHECK-NEXT: Name: foo2 (6)
34 // CHECK-NEXT: Name: foo2
3535 // CHECK-NEXT: Value: 0x0
3636 // CHECK-NEXT: Size: 0
3737 // CHECK-NEXT: Binding: Global
4040 // CHECK-NEXT: Section: Undefined (0x0)
4141 // CHECK-NEXT: }
4242 // CHECK-NEXT: Symbol {
43 // CHECK-NEXT: Name: foo3 (11)
43 // CHECK-NEXT: Name: foo3
4444 // CHECK-NEXT: Value: 0x0
4545 // CHECK-NEXT: Size: 0
4646 // CHECK-NEXT: Binding: Global
4949 // CHECK-NEXT: Section: Undefined (0x0)
5050 // CHECK-NEXT: }
5151 // CHECK-NEXT: Symbol {
52 // CHECK-NEXT: Name: foo4 (16)
52 // CHECK-NEXT: Name: foo4
5353 // CHECK-NEXT: Value: 0x0
5454 // CHECK-NEXT: Size: 0
5555 // CHECK-NEXT: Binding: Global
5858 // CHECK-NEXT: Section: Undefined (0x0)
5959 // CHECK-NEXT: }
6060 // CHECK-NEXT: Symbol {
61 // CHECK-NEXT: Name: foo5 (21)
61 // CHECK-NEXT: Name: foo5
6262 // CHECK-NEXT: Value: 0x0
6363 // CHECK-NEXT: Size: 0
6464 // CHECK-NEXT: Binding: Global
6767 // CHECK-NEXT: Section: Undefined (0x0)
6868 // CHECK-NEXT: }
6969 // CHECK-NEXT: Symbol {
70 // CHECK-NEXT: Name: foo6 (26)
70 // CHECK-NEXT: Name: foo6
7171 // CHECK-NEXT: Value: 0x0
7272 // CHECK-NEXT: Size: 0
7373 // CHECK-NEXT: Binding: Global
175175 // CHECK-NEXT: Section: .text (0x1)
176176 // CHECK-NEXT: }
177177 // CHECK-NEXT: Symbol {
178 // CHECK-NEXT: Name: sym1 (54)
178 // CHECK-NEXT: Name: sym1
179179 // CHECK-NEXT: Value: 0x0
180180 // CHECK-NEXT: Size: 0
181181 // CHECK-NEXT: Binding: Global (0x1)
184184 // CHECK-NEXT: Section: .text (0x1)
185185 // CHECK-NEXT: }
186186 // CHECK-NEXT: Symbol {
187 // CHECK-NEXT: Name: sym10 (162)
187 // CHECK-NEXT: Name: sym10
188188 // CHECK-NEXT: Value: 0x0
189189 // CHECK-NEXT: Size: 0
190190 // CHECK-NEXT: Binding: Global (0x1)
193193 // CHECK-NEXT: Section: .text (0x1)
194194 // CHECK-NEXT: }
195195 // CHECK-NEXT: Symbol {
196 // CHECK-NEXT: Name: sym11 (176)
196 // CHECK-NEXT: Name: sym11
197197 // CHECK-NEXT: Value: 0x0
198198 // CHECK-NEXT: Size: 0
199199 // CHECK-NEXT: Binding: Global (0x1)
202202 // CHECK-NEXT: Section: .text (0x1)
203203 // CHECK-NEXT: }
204204 // CHECK-NEXT: Symbol {
205 // CHECK-NEXT: Name: sym12 (190)
205 // CHECK-NEXT: Name: sym12
206206 // CHECK-NEXT: Value: 0x0
207207 // CHECK-NEXT: Size: 0
208208 // CHECK-NEXT: Binding: Global (0x1)
211211 // CHECK-NEXT: Section: .text (0x1)
212212 // CHECK-NEXT: }
213213 // CHECK-NEXT: Symbol {
214 // CHECK-NEXT: Name: sym2 (66)
214 // CHECK-NEXT: Name: sym2
215215 // CHECK-NEXT: Value: 0x0
216216 // CHECK-NEXT: Size: 0
217217 // CHECK-NEXT: Binding: Global (0x1)
220220 // CHECK-NEXT: Section: .text (0x1)
221221 // CHECK-NEXT: }
222222 // CHECK-NEXT: Symbol {
223 // CHECK-NEXT: Name: sym3 (78)
223 // CHECK-NEXT: Name: sym3
224224 // CHECK-NEXT: Value: 0x0
225225 // CHECK-NEXT: Size: 0
226226 // CHECK-NEXT: Binding: Global (0x1)
229229 // CHECK-NEXT: Section: .text (0x1)
230230 // CHECK-NEXT: }
231231 // CHECK-NEXT: Symbol {
232 // CHECK-NEXT: Name: sym4 (90)
232 // CHECK-NEXT: Name: sym4
233233 // CHECK-NEXT: Value: 0x0
234234 // CHECK-NEXT: Size: 0
235235 // CHECK-NEXT: Binding: Global (0x1)
238238 // CHECK-NEXT: Section: .text (0x1)
239239 // CHECK-NEXT: }
240240 // CHECK-NEXT: Symbol {
241 // CHECK-NEXT: Name: sym5 (102)
241 // CHECK-NEXT: Name: sym5
242242 // CHECK-NEXT: Value: 0x0
243243 // CHECK-NEXT: Size: 0
244244 // CHECK-NEXT: Binding: Global (0x1)
247247 // CHECK-NEXT: Section: .text (0x1)
248248 // CHECK-NEXT: }
249249 // CHECK-NEXT: Symbol {
250 // CHECK-NEXT: Name: sym6 (114)
250 // CHECK-NEXT: Name: sym6
251251 // CHECK-NEXT: Value: 0x0
252252 // CHECK-NEXT: Size: 0
253253 // CHECK-NEXT: Binding: Global (0x1)
256256 // CHECK-NEXT: Section: .text (0x1)
257257 // CHECK-NEXT: }
258258 // CHECK-NEXT: Symbol {
259 // CHECK-NEXT: Name: sym7 (126)
259 // CHECK-NEXT: Name: sym7
260260 // CHECK-NEXT: Value: 0x0
261261 // CHECK-NEXT: Size: 0
262262 // CHECK-NEXT: Binding: Global (0x1)
265265 // CHECK-NEXT: Section: .text (0x1)
266266 // CHECK-NEXT: }
267267 // CHECK-NEXT: Symbol {
268 // CHECK-NEXT: Name: sym8 (138)
268 // CHECK-NEXT: Name: sym8
269269 // CHECK-NEXT: Value: 0x0
270270 // CHECK-NEXT: Size: 0
271271 // CHECK-NEXT: Binding: Global (0x1)
274274 // CHECK-NEXT: Section: .text (0x1)
275275 // CHECK-NEXT: }
276276 // CHECK-NEXT: Symbol {
277 // CHECK-NEXT: Name: sym9 (150)
277 // CHECK-NEXT: Name: sym9
278278 // CHECK-NEXT: Value: 0x0
279279 // CHECK-NEXT: Size: 0
280280 // CHECK-NEXT: Binding: Global (0x1)
7979 // CHECK-NEXT: Section: Undefined (0x0)
8080 // CHECK-NEXT: }
8181 // CHECK-NEXT: Symbol {
82 // CHECK-NEXT: Name: bar6 (21)
82 // CHECK-NEXT: Name: bar6
8383 // CHECK-NEXT: Value: 0x18
8484 // CHECK-NEXT: Size: 0
8585 // CHECK-NEXT: Binding: Local
8888 // CHECK-NEXT: Section: .text (0x1)
8989 // CHECK-NEXT: }
9090 // CHECK-NEXT: Symbol {
91 // CHECK-NEXT: Name: bar7 (26)
91 // CHECK-NEXT: Name: bar7
9292 // CHECK-NEXT: Value: 0x18
9393 // CHECK-NEXT: Size: 0
9494 // CHECK-NEXT: Binding: Local
9797 // CHECK-NEXT: Section: .text (0x1)
9898 // CHECK-NEXT: }
9999 // CHECK-NEXT: Symbol {
100 // CHECK-NEXT: Name: bar8 (31)
100 // CHECK-NEXT: Name: bar8
101101 // CHECK-NEXT: Value: 0x1C
102102 // CHECK-NEXT: Size: 0
103103 // CHECK-NEXT: Binding: Local
106106 // CHECK-NEXT: Section: .text (0x1)
107107 // CHECK-NEXT: }
108108 // CHECK-NEXT: Symbol {
109 // CHECK-NEXT: Name: bar9 (36)
109 // CHECK-NEXT: Name: bar9
110110 // CHECK-NEXT: Value: 0x20
111111 // CHECK-NEXT: Size: 0
112112 // CHECK-NEXT: Binding: Local
115115 // CHECK-NEXT: Section: .text (0x1)
116116 // CHECK-NEXT: }
117117 // CHECK-NEXT: Symbol {
118 // CHECK-NEXT: Name: .text (0)
118 // CHECK-NEXT: Name: .text
119119 // CHECK-NEXT: Value: 0x0
120120 // CHECK-NEXT: Size: 0
121121 // CHECK-NEXT: Binding: Local
124124 // CHECK-NEXT: Section: .text (0x1)
125125 // CHECK-NEXT: }
126126 // CHECK-NEXT: Symbol {
127 // CHECK-NEXT: Name: .data (0)
127 // CHECK-NEXT: Name: .data
128128 // CHECK-NEXT: Value: 0x0
129129 // CHECK-NEXT: Size: 0
130130 // CHECK-NEXT: Binding: Local
133133 // CHECK-NEXT: Section: .data (0x3)
134134 // CHECK-NEXT: }
135135 // CHECK-NEXT: Symbol {
136 // CHECK-NEXT: Name: .bss (0)
136 // CHECK-NEXT: Name: .bss
137137 // CHECK-NEXT: Value: 0x0
138138 // CHECK-NEXT: Size: 0
139139 // CHECK-NEXT: Binding: Local
142142 // CHECK-NEXT: Section: .bss (0x4)
143143 // CHECK-NEXT: }
144144 // CHECK-NEXT: Symbol {
145 // CHECK-NEXT: Name: bar10 (41)
145 // CHECK-NEXT: Name: bar10
146146 // CHECK-NEXT: Value: 0x28
147147 // CHECK-NEXT: Size: 0
148148 // CHECK-NEXT: Binding: Global
151151 // CHECK-NEXT: Section: .text (0x1)
152152 // CHECK-NEXT: }
153153 // CHECK-NEXT: Symbol {
154 // CHECK-NEXT: Name: bar11 (47)
154 // CHECK-NEXT: Name: bar11
155155 // CHECK-NEXT: Value: 0x30
156156 // CHECK-NEXT: Size: 0
157157 // CHECK-NEXT: Binding: Global
160160 // CHECK-NEXT: Section: .text (0x1)
161161 // CHECK-NEXT: }
162162 // CHECK-NEXT: Symbol {
163 // CHECK-NEXT: Name: bar12 (53)
163 // CHECK-NEXT: Name: bar12
164164 // CHECK-NEXT: Value: 0x30
165165 // CHECK-NEXT: Size: 0
166166 // CHECK-NEXT: Binding: Global
169169 // CHECK-NEXT: Section: .text (0x1)
170170 // CHECK-NEXT: }
171171 // CHECK-NEXT: Symbol {
172 // CHECK-NEXT: Name: bar13 (59)
172 // CHECK-NEXT: Name: bar13
173173 // CHECK-NEXT: Value: 0x34
174174 // CHECK-NEXT: Size: 0
175175 // CHECK-NEXT: Binding: Global
178178 // CHECK-NEXT: Section: .text (0x1)
179179 // CHECK-NEXT: }
180180 // CHECK-NEXT: Symbol {
181 // CHECK-NEXT: Name: bar14 (65)
181 // CHECK-NEXT: Name: bar14
182182 // CHECK-NEXT: Value: 0x38
183183 // CHECK-NEXT: Size: 0
184184 // CHECK-NEXT: Binding: Global
187187 // CHECK-NEXT: Section: .text (0x1)
188188 // CHECK-NEXT: }
189189 // CHECK-NEXT: Symbol {
190 // CHECK-NEXT: Name: bar15 (71)
190 // CHECK-NEXT: Name: bar15
191191 // CHECK-NEXT: Value: 0x40
192192 // CHECK-NEXT: Size: 0
193193 // CHECK-NEXT: Binding: Global
196196 // CHECK-NEXT: Section: .text (0x1)
197197 // CHECK-NEXT: }
198198 // CHECK-NEXT: Symbol {
199 // CHECK-NEXT: Name: bar2 (1)
200 // CHECK-NEXT: Value: 0x0
201 // CHECK-NEXT: Size: 0
202 // CHECK-NEXT: Binding: Global
203 // CHECK-NEXT: Type: None
204 // CHECK-NEXT: Other: 0
205 // CHECK-NEXT: Section: Undefined (0x0)
206 // CHECK-NEXT: }
207 // CHECK-NEXT: Symbol {
208 // CHECK-NEXT: Name: bar3 (6)
199 // CHECK-NEXT: Name: bar2
200 // CHECK-NEXT: Value: 0x0
201 // CHECK-NEXT: Size: 0
202 // CHECK-NEXT: Binding: Global
203 // CHECK-NEXT: Type: None
204 // CHECK-NEXT: Other: 0
205 // CHECK-NEXT: Section: Undefined (0x0)
206 // CHECK-NEXT: }
207 // CHECK-NEXT: Symbol {
208 // CHECK-NEXT: Name: bar3
209209 // CHECK-NEXT: Value: 0x0
210210 // CHECK-NEXT: Size: 0
211211 // CHECK-NEXT: Binding: Weak
214214 // CHECK-NEXT: Section: Undefined (0x0)
215215 // CHECK-NEXT: }
216216 // CHECK-NEXT: Symbol {
217 // CHECK-NEXT: Name: bar4 (11)
218 // CHECK-NEXT: Value: 0x0
219 // CHECK-NEXT: Size: 0
220 // CHECK-NEXT: Binding: Global
221 // CHECK-NEXT: Type: None
222 // CHECK-NEXT: Other: 0
223 // CHECK-NEXT: Section: Undefined (0x0)
224 // CHECK-NEXT: }
225 // CHECK-NEXT: Symbol {
226 // CHECK-NEXT: Name: bar5 (16)
217 // CHECK-NEXT: Name: bar4
218 // CHECK-NEXT: Value: 0x0
219 // CHECK-NEXT: Size: 0
220 // CHECK-NEXT: Binding: Global
221 // CHECK-NEXT: Type: None
222 // CHECK-NEXT: Other: 0
223 // CHECK-NEXT: Section: Undefined (0x0)
224 // CHECK-NEXT: }
225 // CHECK-NEXT: Symbol {
226 // CHECK-NEXT: Name: bar5
227227 // CHECK-NEXT: Value: 0x0
228228 // CHECK-NEXT: Size: 0
229229 // CHECK-NEXT: Binding: Global
2929 // This class has a deliberately small interface, since a lot of
3030 // implementation variation is possible.
3131 //
32 // TODO: Use an ordered container with a suffix-based comparison in order
33 // to deduplicate suffixes. std::map<> with a custom comparator is likely
34 // to be the simplest implementation, but a suffix trie could be more
35 // suitable for the job.
32 // TODO: Use the StringTable builder from lib/Object instead, since it
33 // will deduplicate suffixes.
3634 namespace {
3735 class StringTableBuilder {
3836 /// \brief Indices of strings currently present in `Buf`.
33 )
44
55 add_llvm_unittest(ObjectTests
6 StringTableBuilderTest.cpp
67 YAMLTest.cpp
78 )
0 //===----------- StringTableBuilderTest.cpp -------------------------------===//
1 //
2 // The LLVM Compiler Infrastructure
3 //
4 // This file is distributed under the University of Illinois Open Source
5 // License. See LICENSE.TXT for details.
6 //
7 //===----------------------------------------------------------------------===//
8
9 #include "gtest/gtest.h"
10 #include "llvm/Object/StringTableBuilder.h"
11 #include
12
13 using namespace llvm;
14
15 namespace {
16
17 TEST(StringTableBuilderTest, Basic) {
18 StringTableBuilder B;
19
20 B.add("foo");
21 B.add("bar");
22 B.add("foobar");
23
24 B.finalize();
25
26 std::string Expected;
27 Expected += '\x00';
28 Expected += "foobar";
29 Expected += '\x00';
30 Expected += "foo";
31 Expected += '\x00';
32
33 EXPECT_EQ(Expected, B.data());
34 EXPECT_EQ(1U, B.getOffset("foobar"));
35 EXPECT_EQ(4U, B.getOffset("bar"));
36 EXPECT_EQ(8U, B.getOffset("foo"));
37 }
38
39 }