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
This commit is contained in:
Hans Wennborg 2014-04-30 16:25:02 +00:00
parent b1c1b8a78d
commit a8febf2283
22 changed files with 282 additions and 165 deletions

View File

@ -0,0 +1,59 @@
//===-- StringTableBuilder.h - String table building utility ------*- C++ -*-=//
//
// The LLVM Compiler Infrastructure
//
// This file is distributed under the University of Illinois Open Source
// License. See LICENSE.TXT for details.
//
//===----------------------------------------------------------------------===//
#ifndef LLVM_OBJECT_STRINGTABLE_BUILDER_H
#define LLVM_OBJECT_STRINGTABLE_BUILDER_H
#include "llvm/ADT/SmallString.h"
#include "llvm/ADT/StringMap.h"
#include <cassert>
namespace llvm {
/// \brief Utility for building string tables with deduplicated suffixes.
class StringTableBuilder {
SmallString<256> StringTable;
StringMap<size_t> StringIndexMap;
public:
/// \brief Add a string to the builder. Returns a StringRef to the internal
/// copy of s. Can only be used before the table is finalized.
StringRef add(StringRef s) {
assert(!isFinalized());
return StringIndexMap.GetOrCreateValue(s, 0).getKey();
}
/// \brief Analyze the strings and build the final table. No more strings can
/// be added after this point.
void finalize();
/// \brief Retrieve the string table data. Can only be used after the table
/// is finalized.
StringRef data() {
assert(isFinalized());
return StringTable;
}
/// \brief Get the offest of a string in the string table. Can only be used
/// after the table is finalized.
size_t getOffset(StringRef s) {
assert(isFinalized());
assert(StringIndexMap.count(s) && "String is not in table!");
return StringIndexMap[s];
}
private:
bool isFinalized() {
return !StringTable.empty();
}
};
} // end llvm namespace
#endif

View File

@ -28,6 +28,7 @@
#include "llvm/MC/MCObjectWriter.h" #include "llvm/MC/MCObjectWriter.h"
#include "llvm/MC/MCSectionELF.h" #include "llvm/MC/MCSectionELF.h"
#include "llvm/MC/MCValue.h" #include "llvm/MC/MCValue.h"
#include "llvm/Object/StringTableBuilder.h"
#include "llvm/Support/Compression.h" #include "llvm/Support/Compression.h"
#include "llvm/Support/Debug.h" #include "llvm/Support/Debug.h"
#include "llvm/Support/Endian.h" #include "llvm/Support/Endian.h"
@ -132,11 +133,11 @@ class ELFObjectWriter : public MCObjectWriter {
MCSymbolData *SymbolData; MCSymbolData *SymbolData;
uint64_t StringIndex; uint64_t StringIndex;
uint32_t SectionIndex; uint32_t SectionIndex;
StringRef Name;
// Support lexicographic sorting. // Support lexicographic sorting.
bool operator<(const ELFSymbolData &RHS) const { bool operator<(const ELFSymbolData &RHS) const {
return SymbolData->getSymbol().getName() < return Name < RHS.Name;
RHS.SymbolData->getSymbol().getName();
} }
}; };
@ -149,13 +150,13 @@ class ELFObjectWriter : public MCObjectWriter {
llvm::DenseMap<const MCSectionData *, std::vector<ELFRelocationEntry>> llvm::DenseMap<const MCSectionData *, std::vector<ELFRelocationEntry>>
Relocations; Relocations;
DenseMap<const MCSection*, uint64_t> SectionStringTableIndex; StringTableBuilder ShStrTabBuilder;
/// @} /// @}
/// @name Symbol Table Data /// @name Symbol Table Data
/// @{ /// @{
SmallString<256> StringTable; StringTableBuilder StrTabBuilder;
std::vector<uint64_t> FileSymbolData; std::vector<uint64_t> FileSymbolData;
std::vector<ELFSymbolData> LocalSymbolData; std::vector<ELFSymbolData> LocalSymbolData;
std::vector<ELFSymbolData> ExternalSymbolData; std::vector<ELFSymbolData> ExternalSymbolData;
@ -676,7 +677,6 @@ void ELFObjectWriter::WriteSymbolTable(MCDataFragment *SymtabF,
SectionIndexMapTy &SectionIndexMap) { SectionIndexMapTy &SectionIndexMap) {
// The string table must be emitted first because we need the index // The string table must be emitted first because we need the index
// into the string table for all the symbol names. // into the string table for all the symbol names.
assert(StringTable.size() && "Missing string table");
// FIXME: Make sure the start of the symbol table is aligned. // FIXME: Make sure the start of the symbol table is aligned.
@ -1031,27 +1031,6 @@ ELFObjectWriter::computeSymbolTable(MCAssembler &Asm, const MCAsmLayout &Layout,
MCELF::SetBinding(Data, ELF::STB_GLOBAL); MCELF::SetBinding(Data, ELF::STB_GLOBAL);
} }
// Index 0 is always the empty string.
StringMap<uint64_t> StringIndexMap;
StringTable += '\x00';
// FIXME: We could optimize suffixes in strtab in the same way we
// optimize them in shstrtab.
for (MCAssembler::const_file_name_iterator it = Asm.file_names_begin(),
ie = Asm.file_names_end();
it != ie;
++it) {
StringRef Name = *it;
uint64_t &Entry = StringIndexMap[Name];
if (!Entry) {
Entry = StringTable.size();
StringTable += Name;
StringTable += '\x00';
}
FileSymbolData.push_back(Entry);
}
// Add the data for the symbols. // Add the data for the symbols.
for (MCSymbolData &SD : Asm.symbols()) { for (MCSymbolData &SD : Asm.symbols()) {
const MCSymbol &Symbol = SD.getSymbol(); const MCSymbol &Symbol = SD.getSymbol();
@ -1102,7 +1081,6 @@ ELFObjectWriter::computeSymbolTable(MCAssembler &Asm, const MCAsmLayout &Layout,
// @@ in defined ones. // @@ in defined ones.
StringRef Name = Symbol.getName(); StringRef Name = Symbol.getName();
SmallString<32> Buf; SmallString<32> Buf;
size_t Pos = Name.find("@@@"); size_t Pos = Name.find("@@@");
if (Pos != StringRef::npos) { if (Pos != StringRef::npos) {
Buf += Name.substr(0, Pos); Buf += Name.substr(0, Pos);
@ -1110,14 +1088,8 @@ ELFObjectWriter::computeSymbolTable(MCAssembler &Asm, const MCAsmLayout &Layout,
Buf += Name.substr(Pos + Skip); Buf += Name.substr(Pos + Skip);
Name = Buf; Name = Buf;
} }
MSD.Name = StrTabBuilder.add(Name);
uint64_t &Entry = StringIndexMap[Name];
if (!Entry) {
Entry = StringTable.size();
StringTable += Name;
StringTable += '\x00';
}
MSD.StringIndex = Entry;
if (MSD.SectionIndex == ELF::SHN_UNDEF) if (MSD.SectionIndex == ELF::SHN_UNDEF)
UndefinedSymbolData.push_back(MSD); UndefinedSymbolData.push_back(MSD);
else if (Local) else if (Local)
@ -1126,6 +1098,21 @@ ELFObjectWriter::computeSymbolTable(MCAssembler &Asm, const MCAsmLayout &Layout,
ExternalSymbolData.push_back(MSD); ExternalSymbolData.push_back(MSD);
} }
for (auto i = Asm.file_names_begin(), e = Asm.file_names_end(); i != e; ++i)
StrTabBuilder.add(*i);
StrTabBuilder.finalize();
for (auto i = Asm.file_names_begin(), e = Asm.file_names_end(); i != e; ++i)
FileSymbolData.push_back(StrTabBuilder.getOffset(*i));
for (ELFSymbolData& MSD : LocalSymbolData)
MSD.StringIndex = StrTabBuilder.getOffset(MSD.Name);
for (ELFSymbolData& MSD : ExternalSymbolData)
MSD.StringIndex = StrTabBuilder.getOffset(MSD.Name);
for (ELFSymbolData& MSD : UndefinedSymbolData)
MSD.StringIndex = StrTabBuilder.getOffset(MSD.Name);
// Symbols are required to be in lexicographic order. // Symbols are required to be in lexicographic order.
array_pod_sort(LocalSymbolData.begin(), LocalSymbolData.end()); array_pod_sort(LocalSymbolData.begin(), LocalSymbolData.end());
array_pod_sort(ExternalSymbolData.begin(), ExternalSymbolData.end()); array_pod_sort(ExternalSymbolData.begin(), ExternalSymbolData.end());
@ -1436,23 +1423,6 @@ void ELFObjectWriter::WriteRelocationsFragment(const MCAssembler &Asm,
} }
} }
static int compareBySuffix(const MCSectionELF *const *a,
const MCSectionELF *const *b) {
const StringRef &NameA = (*a)->getSectionName();
const StringRef &NameB = (*b)->getSectionName();
const unsigned sizeA = NameA.size();
const unsigned sizeB = NameB.size();
const unsigned len = std::min(sizeA, sizeB);
for (unsigned int i = 0; i < len; ++i) {
char ca = NameA[sizeA - i - 1];
char cb = NameB[sizeB - i - 1];
if (ca != cb)
return cb - ca;
}
return sizeB - sizeA;
}
void ELFObjectWriter::CreateMetadataSections(MCAssembler &Asm, void ELFObjectWriter::CreateMetadataSections(MCAssembler &Asm,
MCAsmLayout &Layout, MCAsmLayout &Layout,
SectionIndexMapTy &SectionIndexMap, SectionIndexMapTy &SectionIndexMap,
@ -1493,45 +1463,20 @@ void ELFObjectWriter::CreateMetadataSections(MCAssembler &Asm,
WriteSymbolTable(F, Asm, Layout, SectionIndexMap); WriteSymbolTable(F, Asm, Layout, SectionIndexMap);
F = new MCDataFragment(&StrtabSD); F = new MCDataFragment(&StrtabSD);
F->getContents().append(StringTable.begin(), StringTable.end()); F->getContents().append(StrTabBuilder.data().begin(),
StrTabBuilder.data().end());
F = new MCDataFragment(&ShstrtabSD); F = new MCDataFragment(&ShstrtabSD);
std::vector<const MCSectionELF*> Sections; // Section header string table.
for (MCAssembler::const_iterator it = Asm.begin(), for (auto it = Asm.begin(), ie = Asm.end(); it != ie; ++it) {
ie = Asm.end(); it != ie; ++it) {
const MCSectionELF &Section = const MCSectionELF &Section =
static_cast<const MCSectionELF&>(it->getSection()); static_cast<const MCSectionELF&>(it->getSection());
Sections.push_back(&Section); ShStrTabBuilder.add(Section.getSectionName());
}
array_pod_sort(Sections.begin(), Sections.end(), compareBySuffix);
// Section header string table.
//
// The first entry of a string table holds a null character so skip
// section 0.
uint64_t Index = 1;
F->getContents().push_back('\x00');
for (unsigned int I = 0, E = Sections.size(); I != E; ++I) {
const MCSectionELF &Section = *Sections[I];
StringRef Name = Section.getSectionName();
if (I != 0) {
StringRef PreviousName = Sections[I - 1]->getSectionName();
if (PreviousName.endswith(Name)) {
SectionStringTableIndex[&Section] = Index - Name.size() - 1;
continue;
}
}
// Remember the index into the string table so we can write it
// into the sh_name field of the section header table.
SectionStringTableIndex[&Section] = Index;
Index += Name.size() + 1;
F->getContents().append(Name.begin(), Name.end());
F->getContents().push_back('\x00');
} }
ShStrTabBuilder.finalize();
F->getContents().append(ShStrTabBuilder.data().begin(),
ShStrTabBuilder.data().end());
} }
void ELFObjectWriter::CreateIndexedSections(MCAssembler &Asm, void ELFObjectWriter::CreateIndexedSections(MCAssembler &Asm,
@ -1599,7 +1544,7 @@ void ELFObjectWriter::WriteSection(MCAssembler &Asm,
switch(Section.getType()) { switch(Section.getType()) {
case ELF::SHT_DYNAMIC: case ELF::SHT_DYNAMIC:
sh_link = SectionStringTableIndex[&Section]; sh_link = ShStrTabBuilder.getOffset(Section.getSectionName());
sh_info = 0; sh_info = 0;
break; break;
@ -1680,7 +1625,8 @@ void ELFObjectWriter::WriteSection(MCAssembler &Asm,
} }
} }
WriteSecHdrEntry(SectionStringTableIndex[&Section], Section.getType(), WriteSecHdrEntry(ShStrTabBuilder.getOffset(Section.getSectionName()),
Section.getType(),
Section.getFlags(), 0, Offset, Size, sh_link, sh_info, Section.getFlags(), 0, Offset, Size, sh_link, sh_info,
Alignment, Section.getEntrySize()); Alignment, Section.getEntrySize());
} }

View File

@ -12,6 +12,7 @@ add_llvm_library(LLVMObject
MachOUniversal.cpp MachOUniversal.cpp
Object.cpp Object.cpp
ObjectFile.cpp ObjectFile.cpp
StringTableBuilder.cpp
SymbolicFile.cpp SymbolicFile.cpp
YAML.cpp YAML.cpp
) )

View File

@ -0,0 +1,51 @@
//===-- StringTableBuilder.cpp - String table building utility ------------===//
//
// The LLVM Compiler Infrastructure
//
// This file is distributed under the University of Illinois Open Source
// License. See LICENSE.TXT for details.
//
//===----------------------------------------------------------------------===//
#include "llvm/ADT/SmallVector.h"
#include "llvm/Object/StringTableBuilder.h"
using namespace llvm;
static bool compareBySuffix(StringRef a, StringRef b) {
size_t sizeA = a.size();
size_t sizeB = b.size();
size_t len = std::min(sizeA, sizeB);
for (size_t i = 0; i < len; ++i) {
char ca = a[sizeA - i - 1];
char cb = b[sizeB - i - 1];
if (ca != cb)
return ca > cb;
}
return sizeA > sizeB;
}
void StringTableBuilder::finalize() {
SmallVector<StringRef, 8> Strings;
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';
StringRef Previous;
for (StringRef s : Strings) {
if (Previous.endswith(s)) {
StringIndexMap[s] = StringTable.size() - 1 - s.size();
continue;
}
StringIndexMap[s] = StringTable.size();
StringTable += s;
StringTable += '\x00';
Previous = s;
}
}

View File

@ -543,7 +543,7 @@
// CHECK-ELF: Symbols [ // CHECK-ELF: Symbols [
// CHECK-ELF: Symbol { // CHECK-ELF: Symbol {
// CHECK-ELF: Name: var (6) // CHECK-ELF: Name: var
// CHECK-ELF-NEXT: Value: // CHECK-ELF-NEXT: Value:
// CHECK-ELF-NEXT: Size: // CHECK-ELF-NEXT: Size:
// CHECK-ELF-NEXT: Binding: Global // CHECK-ELF-NEXT: Binding: Global

View File

@ -313,7 +313,7 @@
// CHECK-ELF: Symbols [ // CHECK-ELF: Symbols [
// CHECK-ELF: Symbol { // CHECK-ELF: Symbol {
// CHECK-ELF: Name: var (6) // CHECK-ELF: Name: var
// CHECK-ELF-NEXT: Value: // CHECK-ELF-NEXT: Value:
// CHECK-ELF-NEXT: Size: // CHECK-ELF-NEXT: Size:
// CHECK-ELF-NEXT: Binding: Global // CHECK-ELF-NEXT: Binding: Global

View File

@ -49,7 +49,7 @@
// Test that g1 and g2 are local, but g3 is an undefined global. // Test that g1 and g2 are local, but g3 is an undefined global.
// CHECK: Symbol { // CHECK: Symbol {
// CHECK: Name: g1 (1) // CHECK: Name: g1
// CHECK-NEXT: Value: 0x0 // CHECK-NEXT: Value: 0x0
// CHECK-NEXT: Size: 0 // CHECK-NEXT: Size: 0
// CHECK-NEXT: Binding: Local // CHECK-NEXT: Binding: Local
@ -58,7 +58,7 @@
// CHECK-NEXT: Section: .foo (0x7) // CHECK-NEXT: Section: .foo (0x7)
// CHECK-NEXT: } // CHECK-NEXT: }
// CHECK-NEXT: Symbol { // CHECK-NEXT: Symbol {
// CHECK-NEXT: Name: g2 (4) // CHECK-NEXT: Name: g2
// CHECK-NEXT: Value: 0x0 // CHECK-NEXT: Value: 0x0
// CHECK-NEXT: Size: 0 // CHECK-NEXT: Size: 0
// CHECK-NEXT: Binding: Local // CHECK-NEXT: Binding: Local
@ -68,7 +68,7 @@
// CHECK-NEXT: } // CHECK-NEXT: }
// CHECK: Symbol { // CHECK: Symbol {
// CHECK: Name: g3 (7) // CHECK: Name: g3
// CHECK-NEXT: Value: 0x0 // CHECK-NEXT: Value: 0x0
// CHECK-NEXT: Size: 0 // CHECK-NEXT: Size: 0
// CHECK-NEXT: Binding: Global // CHECK-NEXT: Binding: Global

View File

@ -9,7 +9,7 @@
.comm common1,1,1 .comm common1,1,1
// CHECK: Symbol { // CHECK: Symbol {
// CHECK: Name: common1 (1) // CHECK: Name: common1
// CHECK-NEXT: Value: 0x0 // CHECK-NEXT: Value: 0x0
// CHECK-NEXT: Size: 1 // CHECK-NEXT: Size: 1
// CHECK-NEXT: Binding: Local // CHECK-NEXT: Binding: Local
@ -25,7 +25,7 @@
.comm common2,1,1 .comm common2,1,1
// CHECK: Symbol { // CHECK: Symbol {
// CHECK: Name: common2 (9) // CHECK: Name: common2
// CHECK-NEXT: Value: 0x1 // CHECK-NEXT: Value: 0x1
// CHECK-NEXT: Size: 1 // CHECK-NEXT: Size: 1
// CHECK-NEXT: Binding: Local // CHECK-NEXT: Binding: Local
@ -39,7 +39,7 @@
.comm common6,8,16 .comm common6,8,16
// CHECK: Symbol { // CHECK: Symbol {
// CHECK: Name: common6 (17) // CHECK: Name: common6
// CHECK-NEXT: Value: 0x10 // CHECK-NEXT: Value: 0x10
// CHECK-NEXT: Size: 8 // CHECK-NEXT: Size: 8
// CHECK-NEXT: Binding: Local // CHECK-NEXT: Binding: Local
@ -54,7 +54,7 @@
.comm common3,4,4 .comm common3,4,4
// CHECK: Symbol { // CHECK: Symbol {
// CHECK: Name: common3 (25) // CHECK: Name: common3
// CHECK-NEXT: Value: 0x4 // CHECK-NEXT: Value: 0x4
// CHECK-NEXT: Size: 4 // CHECK-NEXT: Size: 4
// CHECK-NEXT: Binding: Global // CHECK-NEXT: Binding: Global
@ -76,7 +76,7 @@ foo:
.comm common4,40,16 .comm common4,40,16
// CHECK: Symbol { // CHECK: Symbol {
// CHECK: Name: common4 (37) // CHECK: Name: common4
// CHECK-NEXT: Value: 0x10 // CHECK-NEXT: Value: 0x10
// CHECK-NEXT: Size: 40 // CHECK-NEXT: Size: 40
// CHECK-NEXT: Binding: Global // CHECK-NEXT: Binding: Global
@ -89,7 +89,7 @@ foo:
.comm common5,4,4 .comm common5,4,4
// CHECK: Symbol { // CHECK: Symbol {
// CHECK: Name: common5 (45) // CHECK: Name: common5
// CHECK-NEXT: Value: 0x4 // CHECK-NEXT: Value: 0x4
// CHECK-NEXT: Size: 4 // CHECK-NEXT: Size: 4
// CHECK-NEXT: Binding: Global // CHECK-NEXT: Binding: Global

View File

@ -11,7 +11,7 @@ foo.c:
bar.c: bar.c:
// CHECK: Symbol { // CHECK: Symbol {
// CHECK: Name: foo.c (1) // CHECK: Name: foo.c
// CHECK-NEXT: Value: 0x0 // CHECK-NEXT: Value: 0x0
// CHECK-NEXT: Size: 0 // CHECK-NEXT: Size: 0
// CHECK-NEXT: Binding: Local // CHECK-NEXT: Binding: Local
@ -19,7 +19,7 @@ bar.c:
// CHECK-NEXT: Other: 0 // CHECK-NEXT: Other: 0
// CHECK-NEXT: Section: Absolute (0xFFF1) // CHECK-NEXT: Section: Absolute (0xFFF1)
// CHECK-NEXT: } // CHECK-NEXT: }
// CHECK: Name: bar.c (7) // CHECK: Name: bar.c
// CHECK-NEXT: Value: 0x0 // CHECK-NEXT: Value: 0x0
// CHECK-NEXT: Size: 0 // CHECK-NEXT: Size: 0
// CHECK-NEXT: Binding: Local // CHECK-NEXT: Binding: Local
@ -28,7 +28,7 @@ bar.c:
// CHECK-NEXT: Section: Absolute (0xFFF1) // CHECK-NEXT: Section: Absolute (0xFFF1)
// CHECK-NEXT: } // CHECK-NEXT: }
// CHECK: Symbol { // CHECK: Symbol {
// CHECK: Name: bar.c (7) // CHECK: Name: bar.c
// CHECK-NEXT: Value: 0x0 // CHECK-NEXT: Value: 0x0
// CHECK-NEXT: Size: 0 // CHECK-NEXT: Size: 0
// CHECK-NEXT: Binding: Global // CHECK-NEXT: Binding: Global
@ -37,7 +37,7 @@ bar.c:
// CHECK-NEXT: Section: .text (0x1) // CHECK-NEXT: Section: .text (0x1)
// CHECK-NEXT: } // CHECK-NEXT: }
// CHECK: Symbol { // CHECK: Symbol {
// CHECK: Name: foo.c (1) // CHECK: Name: foo.c
// CHECK-NEXT: Value: 0x0 // CHECK-NEXT: Value: 0x0
// CHECK-NEXT: Size: 0 // CHECK-NEXT: Size: 0
// CHECK-NEXT: Binding: Global // CHECK-NEXT: Binding: Global

View File

@ -4,7 +4,7 @@
.lcomm B, 32 << 20 .lcomm B, 32 << 20
// CHECK: Symbol { // CHECK: Symbol {
// CHECK: Name: A (1) // CHECK: Name: A
// CHECK-NEXT: Value: 0x0 // CHECK-NEXT: Value: 0x0
// CHECK-NEXT: Size: 5 // CHECK-NEXT: Size: 5
// CHECK-NEXT: Binding: Local // CHECK-NEXT: Binding: Local
@ -13,7 +13,7 @@
// CHECK-NEXT: Section: .bss (0x3) // CHECK-NEXT: Section: .bss (0x3)
// CHECK-NEXT: } // CHECK-NEXT: }
// CHECK: Symbol { // CHECK: Symbol {
// CHECK: Name: B (3) // CHECK: Name: B
// CHECK-NEXT: Value: 0x5 // CHECK-NEXT: Value: 0x5
// CHECK-NEXT: Size: 33554432 // CHECK-NEXT: Size: 33554432
// CHECK-NEXT: Binding: Local // CHECK-NEXT: Binding: Local

View File

@ -12,7 +12,7 @@
// Test that both a and b show up in the correct section. // Test that both a and b show up in the correct section.
// SYMBOLS: Name: a (1) // SYMBOLS: Name: a
// SYMBOLS-NEXT: Value: 0x0 // SYMBOLS-NEXT: Value: 0x0
// SYMBOLS-NEXT: Size: 0 // SYMBOLS-NEXT: Size: 0
// SYMBOLS-NEXT: Binding: Local (0x0) // SYMBOLS-NEXT: Binding: Local (0x0)
@ -21,7 +21,7 @@
// SYMBOLS-NEXT: Section: last (0xFF00) // SYMBOLS-NEXT: Section: last (0xFF00)
// SYMBOLS-NEXT: } // SYMBOLS-NEXT: }
// SYMBOLS-NEXT: Symbol { // SYMBOLS-NEXT: Symbol {
// SYMBOLS-NEXT: Name: b (3) // SYMBOLS-NEXT: Name: b
// SYMBOLS-NEXT: Value: 0x1 // SYMBOLS-NEXT: Value: 0x1
// SYMBOLS-NEXT: Size: 0 // SYMBOLS-NEXT: Size: 0
// SYMBOLS-NEXT: Binding: Local (0x0) // SYMBOLS-NEXT: Binding: Local (0x0)
@ -32,7 +32,7 @@
// Test that this file has one section too many. // Test that this file has one section too many.
// SYMBOLS: Name: last (0) // SYMBOLS: Name: last
// SYMBOLS-NEXT: Value: 0x0 // SYMBOLS-NEXT: Value: 0x0
// SYMBOLS-NEXT: Size: 0 // SYMBOLS-NEXT: Size: 0
// SYMBOLS-NEXT: Binding: Local (0x0) // SYMBOLS-NEXT: Binding: Local (0x0)

View File

@ -7,7 +7,7 @@
// CHECK-NEXT: ] // CHECK-NEXT: ]
// CHECK: Symbol { // CHECK: Symbol {
// CHECK: Name: baz (5) // CHECK: Name: baz
// CHECK-NEXT: Value: 0x0 // CHECK-NEXT: Value: 0x0
// CHECK-NEXT: Size: 0 // CHECK-NEXT: Size: 0
// CHECK-NEXT: Binding: Global // CHECK-NEXT: Binding: Global

View File

@ -8,7 +8,7 @@ mov %eax,bar
// CHECK: Symbol { // CHECK: Symbol {
// CHECK: Name: bar (5) // CHECK: Name: bar
// CHECK-NEXT: Value: 0x0 // CHECK-NEXT: Value: 0x0
// CHECK-NEXT: Size: 0 // CHECK-NEXT: Size: 0
// CHECK-NEXT: Binding: Global // CHECK-NEXT: Binding: Global
@ -17,7 +17,7 @@ mov %eax,bar
// CHECK-NEXT: Section: Undefined (0x0) // CHECK-NEXT: Section: Undefined (0x0)
// CHECK-NEXT: } // CHECK-NEXT: }
// CHECK-NEXT: Symbol { // CHECK-NEXT: Symbol {
// CHECK-NEXT: Name: foo (1) // CHECK-NEXT: Name: foo
// CHECK-NEXT: Value: 0x0 // CHECK-NEXT: Value: 0x0
// CHECK-NEXT: Size: 0 // CHECK-NEXT: Size: 0
// CHECK-NEXT: Binding: Global // CHECK-NEXT: Binding: Global

View File

@ -5,7 +5,7 @@
.set kernbase,0xffffffff80000000 .set kernbase,0xffffffff80000000
// CHECK: Symbol { // CHECK: Symbol {
// CHECK: Name: kernbase (1) // CHECK: Name: kernbase
// CHECK-NEXT: Value: 0xFFFFFFFF80000000 // CHECK-NEXT: Value: 0xFFFFFFFF80000000
// CHECK-NEXT: Size: 0 // CHECK-NEXT: Size: 0
// CHECK-NEXT: Binding: Local // CHECK-NEXT: Binding: Local
@ -26,7 +26,7 @@
// Test that there is an undefined reference to bar // Test that there is an undefined reference to bar
// CHECK: Symbol { // CHECK: Symbol {
// CHECK: Name: bar (10) // CHECK: Name: bar
// CHECK-NEXT: Value: 0x0 // CHECK-NEXT: Value: 0x0
// CHECK-NEXT: Size: 0 // CHECK-NEXT: Size: 0
// CHECK-NEXT: Binding: Global // CHECK-NEXT: Binding: Global

View File

@ -0,0 +1,21 @@
// RUN: llvm-mc -filetype=obj -triple i686-pc-linux-gnu %s -o - | llvm-readobj -symbols | FileCheck %s
.text
.globl foobar
.align 16, 0x90
.type foobar,@function
foobar:
pushl %ebp
movl %esp, %ebp
subl $8, %esp
calll foo
calll bar
addl $8, %esp
popl %ebp
retl
.Ltmp3:
.size foobar, .Ltmp3-foobar
// CHECK: Name: foobar (1)
// CHECK: Name: bar (4)
// CHECK: Name: foo (8)

View File

@ -18,7 +18,7 @@
.long fooE@INDNTPOFF .long fooE@INDNTPOFF
// CHECK: Symbol { // CHECK: Symbol {
// CHECK: Name: foo1 (1) // CHECK: Name: foo1
// CHECK-NEXT: Value: 0x0 // CHECK-NEXT: Value: 0x0
// CHECK-NEXT: Size: 0 // CHECK-NEXT: Size: 0
// CHECK-NEXT: Binding: Global // CHECK-NEXT: Binding: Global
@ -27,7 +27,7 @@
// CHECK-NEXT: Section: Undefined (0x0) // CHECK-NEXT: Section: Undefined (0x0)
// CHECK-NEXT: } // CHECK-NEXT: }
// CHECK-NEXT: Symbol { // CHECK-NEXT: Symbol {
// CHECK-NEXT: Name: foo2 (6) // CHECK-NEXT: Name: foo2
// CHECK-NEXT: Value: 0x0 // CHECK-NEXT: Value: 0x0
// CHECK-NEXT: Size: 0 // CHECK-NEXT: Size: 0
// CHECK-NEXT: Binding: Global // CHECK-NEXT: Binding: Global
@ -36,7 +36,7 @@
// CHECK-NEXT: Section: Undefined (0x0) // CHECK-NEXT: Section: Undefined (0x0)
// CHECK-NEXT: } // CHECK-NEXT: }
// CHECK-NEXT: Symbol { // CHECK-NEXT: Symbol {
// CHECK-NEXT: Name: foo3 (11) // CHECK-NEXT: Name: foo3
// CHECK-NEXT: Value: 0x0 // CHECK-NEXT: Value: 0x0
// CHECK-NEXT: Size: 0 // CHECK-NEXT: Size: 0
// CHECK-NEXT: Binding: Global // CHECK-NEXT: Binding: Global
@ -45,7 +45,7 @@
// CHECK-NEXT: Section: Undefined (0x0) // CHECK-NEXT: Section: Undefined (0x0)
// CHECK-NEXT: } // CHECK-NEXT: }
// CHECK-NEXT: Symbol { // CHECK-NEXT: Symbol {
// CHECK-NEXT: Name: foo4 (16) // CHECK-NEXT: Name: foo4
// CHECK-NEXT: Value: 0x0 // CHECK-NEXT: Value: 0x0
// CHECK-NEXT: Size: 0 // CHECK-NEXT: Size: 0
// CHECK-NEXT: Binding: Global // CHECK-NEXT: Binding: Global
@ -54,7 +54,7 @@
// CHECK-NEXT: Section: Undefined (0x0) // CHECK-NEXT: Section: Undefined (0x0)
// CHECK-NEXT: } // CHECK-NEXT: }
// CHECK-NEXT: Symbol { // CHECK-NEXT: Symbol {
// CHECK-NEXT: Name: foo5 (21) // CHECK-NEXT: Name: foo5
// CHECK-NEXT: Value: 0x0 // CHECK-NEXT: Value: 0x0
// CHECK-NEXT: Size: 0 // CHECK-NEXT: Size: 0
// CHECK-NEXT: Binding: Global // CHECK-NEXT: Binding: Global
@ -63,7 +63,7 @@
// CHECK-NEXT: Section: Undefined (0x0) // CHECK-NEXT: Section: Undefined (0x0)
// CHECK-NEXT: } // CHECK-NEXT: }
// CHECK-NEXT: Symbol { // CHECK-NEXT: Symbol {
// CHECK-NEXT: Name: foo6 (26) // CHECK-NEXT: Name: foo6
// CHECK-NEXT: Value: 0x0 // CHECK-NEXT: Value: 0x0
// CHECK-NEXT: Size: 0 // CHECK-NEXT: Size: 0
// CHECK-NEXT: Binding: Global // CHECK-NEXT: Binding: Global
@ -72,7 +72,7 @@
// CHECK-NEXT: Section: Undefined (0x0) // CHECK-NEXT: Section: Undefined (0x0)
// CHECK-NEXT: } // CHECK-NEXT: }
// CHECK-NEXT: Symbol { // CHECK-NEXT: Symbol {
// CHECK-NEXT: Name: foo7 (31) // CHECK-NEXT: Name: foo7
// CHECK-NEXT: Value: 0x0 // CHECK-NEXT: Value: 0x0
// CHECK-NEXT: Size: 0 // CHECK-NEXT: Size: 0
// CHECK-NEXT: Binding: Global // CHECK-NEXT: Binding: Global
@ -81,7 +81,7 @@
// CHECK-NEXT: Section: Undefined (0x0) // CHECK-NEXT: Section: Undefined (0x0)
// CHECK-NEXT: } // CHECK-NEXT: }
// CHECK-NEXT: Symbol { // CHECK-NEXT: Symbol {
// CHECK-NEXT: Name: foo8 (36) // CHECK-NEXT: Name: foo8
// CHECK-NEXT: Value: 0x0 // CHECK-NEXT: Value: 0x0
// CHECK-NEXT: Size: 0 // CHECK-NEXT: Size: 0
// CHECK-NEXT: Binding: Global // CHECK-NEXT: Binding: Global
@ -90,7 +90,7 @@
// CHECK-NEXT: Section: Undefined (0x0) // CHECK-NEXT: Section: Undefined (0x0)
// CHECK-NEXT: } // CHECK-NEXT: }
// CHECK-NEXT: Symbol { // CHECK-NEXT: Symbol {
// CHECK-NEXT: Name: foo9 (41) // CHECK-NEXT: Name: foo9
// CHECK-NEXT: Value: 0x0 // CHECK-NEXT: Value: 0x0
// CHECK-NEXT: Size: 0 // CHECK-NEXT: Size: 0
// CHECK-NEXT: Binding: Global // CHECK-NEXT: Binding: Global
@ -99,7 +99,7 @@
// CHECK-NEXT: Section: Undefined (0x0) // CHECK-NEXT: Section: Undefined (0x0)
// CHECK-NEXT: } // CHECK-NEXT: }
// CHECK-NEXT: Symbol { // CHECK-NEXT: Symbol {
// CHECK-NEXT: Name: fooA (46) // CHECK-NEXT: Name: fooA
// CHECK-NEXT: Value: 0x0 // CHECK-NEXT: Value: 0x0
// CHECK-NEXT: Size: 0 // CHECK-NEXT: Size: 0
// CHECK-NEXT: Binding: Global // CHECK-NEXT: Binding: Global
@ -108,7 +108,7 @@
// CHECK-NEXT: Section: Undefined (0x0) // CHECK-NEXT: Section: Undefined (0x0)
// CHECK-NEXT: } // CHECK-NEXT: }
// CHECK-NEXT: Symbol { // CHECK-NEXT: Symbol {
// CHECK-NEXT: Name: fooB (51) // CHECK-NEXT: Name: fooB
// CHECK-NEXT: Value: 0x0 // CHECK-NEXT: Value: 0x0
// CHECK-NEXT: Size: 0 // CHECK-NEXT: Size: 0
// CHECK-NEXT: Binding: Global // CHECK-NEXT: Binding: Global
@ -117,7 +117,7 @@
// CHECK-NEXT: Section: Undefined (0x0) // CHECK-NEXT: Section: Undefined (0x0)
// CHECK-NEXT: } // CHECK-NEXT: }
// CHECK-NEXT: Symbol { // CHECK-NEXT: Symbol {
// CHECK-NEXT: Name: fooC (56) // CHECK-NEXT: Name: fooC
// CHECK-NEXT: Value: 0x0 // CHECK-NEXT: Value: 0x0
// CHECK-NEXT: Size: 0 // CHECK-NEXT: Size: 0
// CHECK-NEXT: Binding: Global // CHECK-NEXT: Binding: Global
@ -126,7 +126,7 @@
// CHECK-NEXT: Section: Undefined (0x0) // CHECK-NEXT: Section: Undefined (0x0)
// CHECK-NEXT: } // CHECK-NEXT: }
// CHECK-NEXT: Symbol { // CHECK-NEXT: Symbol {
// CHECK-NEXT: Name: fooD (61) // CHECK-NEXT: Name: fooD
// CHECK-NEXT: Value: 0x0 // CHECK-NEXT: Value: 0x0
// CHECK-NEXT: Size: 0 // CHECK-NEXT: Size: 0
// CHECK-NEXT: Binding: Global // CHECK-NEXT: Binding: Global
@ -135,7 +135,7 @@
// CHECK-NEXT: Section: Undefined (0x0) // CHECK-NEXT: Section: Undefined (0x0)
// CHECK-NEXT: } // CHECK-NEXT: }
// CHECK-NEXT: Symbol { // CHECK-NEXT: Symbol {
// CHECK-NEXT: Name: fooE (66) // CHECK-NEXT: Name: fooE
// CHECK-NEXT: Value: 0x0 // CHECK-NEXT: Value: 0x0
// CHECK-NEXT: Size: 0 // CHECK-NEXT: Size: 0
// CHECK-NEXT: Binding: Global // CHECK-NEXT: Binding: Global

View File

@ -13,7 +13,7 @@ foobar:
.long 43 .long 43
// CHECK: Symbol { // CHECK: Symbol {
// CHECK: Name: foobar (31) // CHECK: Name: foobar
// CHECK-NEXT: Value: 0x0 // CHECK-NEXT: Value: 0x0
// CHECK-NEXT: Size: 0 // CHECK-NEXT: Size: 0
// CHECK-NEXT: Binding: Local // CHECK-NEXT: Binding: Local
@ -23,7 +23,7 @@ foobar:
// CHECK-NEXT: } // CHECK-NEXT: }
// CHECK: Symbol { // CHECK: Symbol {
// CHECK: Name: foo1 (1) // CHECK: Name: foo1
// CHECK-NEXT: Value: 0x0 // CHECK-NEXT: Value: 0x0
// CHECK-NEXT: Size: 0 // CHECK-NEXT: Size: 0
// CHECK-NEXT: Binding: Global // CHECK-NEXT: Binding: Global
@ -32,7 +32,7 @@ foobar:
// CHECK-NEXT: Section: Undefined (0x0) // CHECK-NEXT: Section: Undefined (0x0)
// CHECK-NEXT: } // CHECK-NEXT: }
// CHECK-NEXT: Symbol { // CHECK-NEXT: Symbol {
// CHECK-NEXT: Name: foo2 (6) // CHECK-NEXT: Name: foo2
// CHECK-NEXT: Value: 0x0 // CHECK-NEXT: Value: 0x0
// CHECK-NEXT: Size: 0 // CHECK-NEXT: Size: 0
// CHECK-NEXT: Binding: Global // CHECK-NEXT: Binding: Global
@ -41,7 +41,7 @@ foobar:
// CHECK-NEXT: Section: Undefined (0x0) // CHECK-NEXT: Section: Undefined (0x0)
// CHECK-NEXT: } // CHECK-NEXT: }
// CHECK-NEXT: Symbol { // CHECK-NEXT: Symbol {
// CHECK-NEXT: Name: foo3 (11) // CHECK-NEXT: Name: foo3
// CHECK-NEXT: Value: 0x0 // CHECK-NEXT: Value: 0x0
// CHECK-NEXT: Size: 0 // CHECK-NEXT: Size: 0
// CHECK-NEXT: Binding: Global // CHECK-NEXT: Binding: Global
@ -50,7 +50,7 @@ foobar:
// CHECK-NEXT: Section: Undefined (0x0) // CHECK-NEXT: Section: Undefined (0x0)
// CHECK-NEXT: } // CHECK-NEXT: }
// CHECK-NEXT: Symbol { // CHECK-NEXT: Symbol {
// CHECK-NEXT: Name: foo4 (16) // CHECK-NEXT: Name: foo4
// CHECK-NEXT: Value: 0x0 // CHECK-NEXT: Value: 0x0
// CHECK-NEXT: Size: 0 // CHECK-NEXT: Size: 0
// CHECK-NEXT: Binding: Global // CHECK-NEXT: Binding: Global
@ -59,7 +59,7 @@ foobar:
// CHECK-NEXT: Section: Undefined (0x0) // CHECK-NEXT: Section: Undefined (0x0)
// CHECK-NEXT: } // CHECK-NEXT: }
// CHECK-NEXT: Symbol { // CHECK-NEXT: Symbol {
// CHECK-NEXT: Name: foo5 (21) // CHECK-NEXT: Name: foo5
// CHECK-NEXT: Value: 0x0 // CHECK-NEXT: Value: 0x0
// CHECK-NEXT: Size: 0 // CHECK-NEXT: Size: 0
// CHECK-NEXT: Binding: Global // CHECK-NEXT: Binding: Global
@ -68,7 +68,7 @@ foobar:
// CHECK-NEXT: Section: Undefined (0x0) // CHECK-NEXT: Section: Undefined (0x0)
// CHECK-NEXT: } // CHECK-NEXT: }
// CHECK-NEXT: Symbol { // CHECK-NEXT: Symbol {
// CHECK-NEXT: Name: foo6 (26) // CHECK-NEXT: Name: foo6
// CHECK-NEXT: Value: 0x0 // CHECK-NEXT: Value: 0x0
// CHECK-NEXT: Size: 0 // CHECK-NEXT: Size: 0
// CHECK-NEXT: Binding: Global // CHECK-NEXT: Binding: Global

View File

@ -176,7 +176,7 @@ alias12:
// CHECK-NEXT: Section: .text (0x1) // CHECK-NEXT: Section: .text (0x1)
// CHECK-NEXT: } // CHECK-NEXT: }
// CHECK-NEXT: Symbol { // CHECK-NEXT: Symbol {
// CHECK-NEXT: Name: sym1 (54) // CHECK-NEXT: Name: sym1
// CHECK-NEXT: Value: 0x0 // CHECK-NEXT: Value: 0x0
// CHECK-NEXT: Size: 0 // CHECK-NEXT: Size: 0
// CHECK-NEXT: Binding: Global (0x1) // CHECK-NEXT: Binding: Global (0x1)
@ -185,7 +185,7 @@ alias12:
// CHECK-NEXT: Section: .text (0x1) // CHECK-NEXT: Section: .text (0x1)
// CHECK-NEXT: } // CHECK-NEXT: }
// CHECK-NEXT: Symbol { // CHECK-NEXT: Symbol {
// CHECK-NEXT: Name: sym10 (162) // CHECK-NEXT: Name: sym10
// CHECK-NEXT: Value: 0x0 // CHECK-NEXT: Value: 0x0
// CHECK-NEXT: Size: 0 // CHECK-NEXT: Size: 0
// CHECK-NEXT: Binding: Global (0x1) // CHECK-NEXT: Binding: Global (0x1)
@ -194,7 +194,7 @@ alias12:
// CHECK-NEXT: Section: .text (0x1) // CHECK-NEXT: Section: .text (0x1)
// CHECK-NEXT: } // CHECK-NEXT: }
// CHECK-NEXT: Symbol { // CHECK-NEXT: Symbol {
// CHECK-NEXT: Name: sym11 (176) // CHECK-NEXT: Name: sym11
// CHECK-NEXT: Value: 0x0 // CHECK-NEXT: Value: 0x0
// CHECK-NEXT: Size: 0 // CHECK-NEXT: Size: 0
// CHECK-NEXT: Binding: Global (0x1) // CHECK-NEXT: Binding: Global (0x1)
@ -203,7 +203,7 @@ alias12:
// CHECK-NEXT: Section: .text (0x1) // CHECK-NEXT: Section: .text (0x1)
// CHECK-NEXT: } // CHECK-NEXT: }
// CHECK-NEXT: Symbol { // CHECK-NEXT: Symbol {
// CHECK-NEXT: Name: sym12 (190) // CHECK-NEXT: Name: sym12
// CHECK-NEXT: Value: 0x0 // CHECK-NEXT: Value: 0x0
// CHECK-NEXT: Size: 0 // CHECK-NEXT: Size: 0
// CHECK-NEXT: Binding: Global (0x1) // CHECK-NEXT: Binding: Global (0x1)
@ -212,7 +212,7 @@ alias12:
// CHECK-NEXT: Section: .text (0x1) // CHECK-NEXT: Section: .text (0x1)
// CHECK-NEXT: } // CHECK-NEXT: }
// CHECK-NEXT: Symbol { // CHECK-NEXT: Symbol {
// CHECK-NEXT: Name: sym2 (66) // CHECK-NEXT: Name: sym2
// CHECK-NEXT: Value: 0x0 // CHECK-NEXT: Value: 0x0
// CHECK-NEXT: Size: 0 // CHECK-NEXT: Size: 0
// CHECK-NEXT: Binding: Global (0x1) // CHECK-NEXT: Binding: Global (0x1)
@ -221,7 +221,7 @@ alias12:
// CHECK-NEXT: Section: .text (0x1) // CHECK-NEXT: Section: .text (0x1)
// CHECK-NEXT: } // CHECK-NEXT: }
// CHECK-NEXT: Symbol { // CHECK-NEXT: Symbol {
// CHECK-NEXT: Name: sym3 (78) // CHECK-NEXT: Name: sym3
// CHECK-NEXT: Value: 0x0 // CHECK-NEXT: Value: 0x0
// CHECK-NEXT: Size: 0 // CHECK-NEXT: Size: 0
// CHECK-NEXT: Binding: Global (0x1) // CHECK-NEXT: Binding: Global (0x1)
@ -230,7 +230,7 @@ alias12:
// CHECK-NEXT: Section: .text (0x1) // CHECK-NEXT: Section: .text (0x1)
// CHECK-NEXT: } // CHECK-NEXT: }
// CHECK-NEXT: Symbol { // CHECK-NEXT: Symbol {
// CHECK-NEXT: Name: sym4 (90) // CHECK-NEXT: Name: sym4
// CHECK-NEXT: Value: 0x0 // CHECK-NEXT: Value: 0x0
// CHECK-NEXT: Size: 0 // CHECK-NEXT: Size: 0
// CHECK-NEXT: Binding: Global (0x1) // CHECK-NEXT: Binding: Global (0x1)
@ -239,7 +239,7 @@ alias12:
// CHECK-NEXT: Section: .text (0x1) // CHECK-NEXT: Section: .text (0x1)
// CHECK-NEXT: } // CHECK-NEXT: }
// CHECK-NEXT: Symbol { // CHECK-NEXT: Symbol {
// CHECK-NEXT: Name: sym5 (102) // CHECK-NEXT: Name: sym5
// CHECK-NEXT: Value: 0x0 // CHECK-NEXT: Value: 0x0
// CHECK-NEXT: Size: 0 // CHECK-NEXT: Size: 0
// CHECK-NEXT: Binding: Global (0x1) // CHECK-NEXT: Binding: Global (0x1)
@ -248,7 +248,7 @@ alias12:
// CHECK-NEXT: Section: .text (0x1) // CHECK-NEXT: Section: .text (0x1)
// CHECK-NEXT: } // CHECK-NEXT: }
// CHECK-NEXT: Symbol { // CHECK-NEXT: Symbol {
// CHECK-NEXT: Name: sym6 (114) // CHECK-NEXT: Name: sym6
// CHECK-NEXT: Value: 0x0 // CHECK-NEXT: Value: 0x0
// CHECK-NEXT: Size: 0 // CHECK-NEXT: Size: 0
// CHECK-NEXT: Binding: Global (0x1) // CHECK-NEXT: Binding: Global (0x1)
@ -257,7 +257,7 @@ alias12:
// CHECK-NEXT: Section: .text (0x1) // CHECK-NEXT: Section: .text (0x1)
// CHECK-NEXT: } // CHECK-NEXT: }
// CHECK-NEXT: Symbol { // CHECK-NEXT: Symbol {
// CHECK-NEXT: Name: sym7 (126) // CHECK-NEXT: Name: sym7
// CHECK-NEXT: Value: 0x0 // CHECK-NEXT: Value: 0x0
// CHECK-NEXT: Size: 0 // CHECK-NEXT: Size: 0
// CHECK-NEXT: Binding: Global (0x1) // CHECK-NEXT: Binding: Global (0x1)
@ -266,7 +266,7 @@ alias12:
// CHECK-NEXT: Section: .text (0x1) // CHECK-NEXT: Section: .text (0x1)
// CHECK-NEXT: } // CHECK-NEXT: }
// CHECK-NEXT: Symbol { // CHECK-NEXT: Symbol {
// CHECK-NEXT: Name: sym8 (138) // CHECK-NEXT: Name: sym8
// CHECK-NEXT: Value: 0x0 // CHECK-NEXT: Value: 0x0
// CHECK-NEXT: Size: 0 // CHECK-NEXT: Size: 0
// CHECK-NEXT: Binding: Global (0x1) // CHECK-NEXT: Binding: Global (0x1)
@ -275,7 +275,7 @@ alias12:
// CHECK-NEXT: Section: .text (0x1) // CHECK-NEXT: Section: .text (0x1)
// CHECK-NEXT: } // CHECK-NEXT: }
// CHECK-NEXT: Symbol { // CHECK-NEXT: Symbol {
// CHECK-NEXT: Name: sym9 (150) // CHECK-NEXT: Name: sym9
// CHECK-NEXT: Value: 0x0 // CHECK-NEXT: Value: 0x0
// CHECK-NEXT: Size: 0 // CHECK-NEXT: Size: 0
// CHECK-NEXT: Binding: Global (0x1) // CHECK-NEXT: Binding: Global (0x1)

View File

@ -80,7 +80,7 @@ bar15:
// CHECK-NEXT: Section: Undefined (0x0) // CHECK-NEXT: Section: Undefined (0x0)
// CHECK-NEXT: } // CHECK-NEXT: }
// CHECK-NEXT: Symbol { // CHECK-NEXT: Symbol {
// CHECK-NEXT: Name: bar6 (21) // CHECK-NEXT: Name: bar6
// CHECK-NEXT: Value: 0x18 // CHECK-NEXT: Value: 0x18
// CHECK-NEXT: Size: 0 // CHECK-NEXT: Size: 0
// CHECK-NEXT: Binding: Local // CHECK-NEXT: Binding: Local
@ -89,7 +89,7 @@ bar15:
// CHECK-NEXT: Section: .text (0x1) // CHECK-NEXT: Section: .text (0x1)
// CHECK-NEXT: } // CHECK-NEXT: }
// CHECK-NEXT: Symbol { // CHECK-NEXT: Symbol {
// CHECK-NEXT: Name: bar7 (26) // CHECK-NEXT: Name: bar7
// CHECK-NEXT: Value: 0x18 // CHECK-NEXT: Value: 0x18
// CHECK-NEXT: Size: 0 // CHECK-NEXT: Size: 0
// CHECK-NEXT: Binding: Local // CHECK-NEXT: Binding: Local
@ -98,7 +98,7 @@ bar15:
// CHECK-NEXT: Section: .text (0x1) // CHECK-NEXT: Section: .text (0x1)
// CHECK-NEXT: } // CHECK-NEXT: }
// CHECK-NEXT: Symbol { // CHECK-NEXT: Symbol {
// CHECK-NEXT: Name: bar8 (31) // CHECK-NEXT: Name: bar8
// CHECK-NEXT: Value: 0x1C // CHECK-NEXT: Value: 0x1C
// CHECK-NEXT: Size: 0 // CHECK-NEXT: Size: 0
// CHECK-NEXT: Binding: Local // CHECK-NEXT: Binding: Local
@ -107,7 +107,7 @@ bar15:
// CHECK-NEXT: Section: .text (0x1) // CHECK-NEXT: Section: .text (0x1)
// CHECK-NEXT: } // CHECK-NEXT: }
// CHECK-NEXT: Symbol { // CHECK-NEXT: Symbol {
// CHECK-NEXT: Name: bar9 (36) // CHECK-NEXT: Name: bar9
// CHECK-NEXT: Value: 0x20 // CHECK-NEXT: Value: 0x20
// CHECK-NEXT: Size: 0 // CHECK-NEXT: Size: 0
// CHECK-NEXT: Binding: Local // CHECK-NEXT: Binding: Local
@ -116,7 +116,7 @@ bar15:
// CHECK-NEXT: Section: .text (0x1) // CHECK-NEXT: Section: .text (0x1)
// CHECK-NEXT: } // CHECK-NEXT: }
// CHECK-NEXT: Symbol { // CHECK-NEXT: Symbol {
// CHECK-NEXT: Name: .text (0) // CHECK-NEXT: Name: .text
// CHECK-NEXT: Value: 0x0 // CHECK-NEXT: Value: 0x0
// CHECK-NEXT: Size: 0 // CHECK-NEXT: Size: 0
// CHECK-NEXT: Binding: Local // CHECK-NEXT: Binding: Local
@ -125,7 +125,7 @@ bar15:
// CHECK-NEXT: Section: .text (0x1) // CHECK-NEXT: Section: .text (0x1)
// CHECK-NEXT: } // CHECK-NEXT: }
// CHECK-NEXT: Symbol { // CHECK-NEXT: Symbol {
// CHECK-NEXT: Name: .data (0) // CHECK-NEXT: Name: .data
// CHECK-NEXT: Value: 0x0 // CHECK-NEXT: Value: 0x0
// CHECK-NEXT: Size: 0 // CHECK-NEXT: Size: 0
// CHECK-NEXT: Binding: Local // CHECK-NEXT: Binding: Local
@ -134,7 +134,7 @@ bar15:
// CHECK-NEXT: Section: .data (0x3) // CHECK-NEXT: Section: .data (0x3)
// CHECK-NEXT: } // CHECK-NEXT: }
// CHECK-NEXT: Symbol { // CHECK-NEXT: Symbol {
// CHECK-NEXT: Name: .bss (0) // CHECK-NEXT: Name: .bss
// CHECK-NEXT: Value: 0x0 // CHECK-NEXT: Value: 0x0
// CHECK-NEXT: Size: 0 // CHECK-NEXT: Size: 0
// CHECK-NEXT: Binding: Local // CHECK-NEXT: Binding: Local
@ -143,7 +143,7 @@ bar15:
// CHECK-NEXT: Section: .bss (0x4) // CHECK-NEXT: Section: .bss (0x4)
// CHECK-NEXT: } // CHECK-NEXT: }
// CHECK-NEXT: Symbol { // CHECK-NEXT: Symbol {
// CHECK-NEXT: Name: bar10 (41) // CHECK-NEXT: Name: bar10
// CHECK-NEXT: Value: 0x28 // CHECK-NEXT: Value: 0x28
// CHECK-NEXT: Size: 0 // CHECK-NEXT: Size: 0
// CHECK-NEXT: Binding: Global // CHECK-NEXT: Binding: Global
@ -152,7 +152,7 @@ bar15:
// CHECK-NEXT: Section: .text (0x1) // CHECK-NEXT: Section: .text (0x1)
// CHECK-NEXT: } // CHECK-NEXT: }
// CHECK-NEXT: Symbol { // CHECK-NEXT: Symbol {
// CHECK-NEXT: Name: bar11 (47) // CHECK-NEXT: Name: bar11
// CHECK-NEXT: Value: 0x30 // CHECK-NEXT: Value: 0x30
// CHECK-NEXT: Size: 0 // CHECK-NEXT: Size: 0
// CHECK-NEXT: Binding: Global // CHECK-NEXT: Binding: Global
@ -161,7 +161,7 @@ bar15:
// CHECK-NEXT: Section: .text (0x1) // CHECK-NEXT: Section: .text (0x1)
// CHECK-NEXT: } // CHECK-NEXT: }
// CHECK-NEXT: Symbol { // CHECK-NEXT: Symbol {
// CHECK-NEXT: Name: bar12 (53) // CHECK-NEXT: Name: bar12
// CHECK-NEXT: Value: 0x30 // CHECK-NEXT: Value: 0x30
// CHECK-NEXT: Size: 0 // CHECK-NEXT: Size: 0
// CHECK-NEXT: Binding: Global // CHECK-NEXT: Binding: Global
@ -170,7 +170,7 @@ bar15:
// CHECK-NEXT: Section: .text (0x1) // CHECK-NEXT: Section: .text (0x1)
// CHECK-NEXT: } // CHECK-NEXT: }
// CHECK-NEXT: Symbol { // CHECK-NEXT: Symbol {
// CHECK-NEXT: Name: bar13 (59) // CHECK-NEXT: Name: bar13
// CHECK-NEXT: Value: 0x34 // CHECK-NEXT: Value: 0x34
// CHECK-NEXT: Size: 0 // CHECK-NEXT: Size: 0
// CHECK-NEXT: Binding: Global // CHECK-NEXT: Binding: Global
@ -179,7 +179,7 @@ bar15:
// CHECK-NEXT: Section: .text (0x1) // CHECK-NEXT: Section: .text (0x1)
// CHECK-NEXT: } // CHECK-NEXT: }
// CHECK-NEXT: Symbol { // CHECK-NEXT: Symbol {
// CHECK-NEXT: Name: bar14 (65) // CHECK-NEXT: Name: bar14
// CHECK-NEXT: Value: 0x38 // CHECK-NEXT: Value: 0x38
// CHECK-NEXT: Size: 0 // CHECK-NEXT: Size: 0
// CHECK-NEXT: Binding: Global // CHECK-NEXT: Binding: Global
@ -188,7 +188,7 @@ bar15:
// CHECK-NEXT: Section: .text (0x1) // CHECK-NEXT: Section: .text (0x1)
// CHECK-NEXT: } // CHECK-NEXT: }
// CHECK-NEXT: Symbol { // CHECK-NEXT: Symbol {
// CHECK-NEXT: Name: bar15 (71) // CHECK-NEXT: Name: bar15
// CHECK-NEXT: Value: 0x40 // CHECK-NEXT: Value: 0x40
// CHECK-NEXT: Size: 0 // CHECK-NEXT: Size: 0
// CHECK-NEXT: Binding: Global // CHECK-NEXT: Binding: Global
@ -197,7 +197,7 @@ bar15:
// CHECK-NEXT: Section: .text (0x1) // CHECK-NEXT: Section: .text (0x1)
// CHECK-NEXT: } // CHECK-NEXT: }
// CHECK-NEXT: Symbol { // CHECK-NEXT: Symbol {
// CHECK-NEXT: Name: bar2 (1) // CHECK-NEXT: Name: bar2
// CHECK-NEXT: Value: 0x0 // CHECK-NEXT: Value: 0x0
// CHECK-NEXT: Size: 0 // CHECK-NEXT: Size: 0
// CHECK-NEXT: Binding: Global // CHECK-NEXT: Binding: Global
@ -206,7 +206,7 @@ bar15:
// CHECK-NEXT: Section: Undefined (0x0) // CHECK-NEXT: Section: Undefined (0x0)
// CHECK-NEXT: } // CHECK-NEXT: }
// CHECK-NEXT: Symbol { // CHECK-NEXT: Symbol {
// CHECK-NEXT: Name: bar3 (6) // CHECK-NEXT: Name: bar3
// CHECK-NEXT: Value: 0x0 // CHECK-NEXT: Value: 0x0
// CHECK-NEXT: Size: 0 // CHECK-NEXT: Size: 0
// CHECK-NEXT: Binding: Weak // CHECK-NEXT: Binding: Weak
@ -215,7 +215,7 @@ bar15:
// CHECK-NEXT: Section: Undefined (0x0) // CHECK-NEXT: Section: Undefined (0x0)
// CHECK-NEXT: } // CHECK-NEXT: }
// CHECK-NEXT: Symbol { // CHECK-NEXT: Symbol {
// CHECK-NEXT: Name: bar4 (11) // CHECK-NEXT: Name: bar4
// CHECK-NEXT: Value: 0x0 // CHECK-NEXT: Value: 0x0
// CHECK-NEXT: Size: 0 // CHECK-NEXT: Size: 0
// CHECK-NEXT: Binding: Global // CHECK-NEXT: Binding: Global
@ -224,7 +224,7 @@ bar15:
// CHECK-NEXT: Section: Undefined (0x0) // CHECK-NEXT: Section: Undefined (0x0)
// CHECK-NEXT: } // CHECK-NEXT: }
// CHECK-NEXT: Symbol { // CHECK-NEXT: Symbol {
// CHECK-NEXT: Name: bar5 (16) // CHECK-NEXT: Name: bar5
// CHECK-NEXT: Value: 0x0 // CHECK-NEXT: Value: 0x0
// CHECK-NEXT: Size: 0 // CHECK-NEXT: Size: 0
// CHECK-NEXT: Binding: Global // CHECK-NEXT: Binding: Global

View File

@ -30,10 +30,8 @@ using namespace llvm;
// This class has a deliberately small interface, since a lot of // This class has a deliberately small interface, since a lot of
// implementation variation is possible. // implementation variation is possible.
// //
// TODO: Use an ordered container with a suffix-based comparison in order // TODO: Use the StringTable builder from lib/Object instead, since it
// to deduplicate suffixes. std::map<> with a custom comparator is likely // will deduplicate suffixes.
// to be the simplest implementation, but a suffix trie could be more
// suitable for the job.
namespace { namespace {
class StringTableBuilder { class StringTableBuilder {
/// \brief Indices of strings currently present in `Buf`. /// \brief Indices of strings currently present in `Buf`.

View File

@ -4,5 +4,6 @@ set(LLVM_LINK_COMPONENTS
) )
add_llvm_unittest(ObjectTests add_llvm_unittest(ObjectTests
StringTableBuilderTest.cpp
YAMLTest.cpp YAMLTest.cpp
) )

View File

@ -0,0 +1,40 @@
//===----------- StringTableBuilderTest.cpp -------------------------------===//
//
// The LLVM Compiler Infrastructure
//
// This file is distributed under the University of Illinois Open Source
// License. See LICENSE.TXT for details.
//
//===----------------------------------------------------------------------===//
#include "gtest/gtest.h"
#include "llvm/Object/StringTableBuilder.h"
#include <string>
using namespace llvm;
namespace {
TEST(StringTableBuilderTest, Basic) {
StringTableBuilder B;
B.add("foo");
B.add("bar");
B.add("foobar");
B.finalize();
std::string Expected;
Expected += '\x00';
Expected += "foobar";
Expected += '\x00';
Expected += "foo";
Expected += '\x00';
EXPECT_EQ(Expected, B.data());
EXPECT_EQ(1U, B.getOffset("foobar"));
EXPECT_EQ(4U, B.getOffset("bar"));
EXPECT_EQ(8U, B.getOffset("foo"));
}
}