[patch] Merge identical strings
Rafael EspĂndola via llvm-commits
llvm-commits at lists.llvm.org
Thu Jan 28 08:45:31 PST 2016
>> When linking clang on a Opteron this goes from 1.090608063 to
>> 1.135082244 seconds (1.04X slower)
>>
>> and strtab goes from 5426172 to 5319595 bytes (1.02X smaller).
>>
>> Linking scylladb goes from 8.104377098 to 8.116767958 (1.0015X slower)
>> and the strtab goes from 14824893 to 14443221 (1.026X smaller).
>>
>
> The savings are relatively small, but still greater than zero. For a
> small increase in cost, at least for scylladb.
> For clang the link time increases a little bit more but I still feel
> that tolerable. We can always re-evaluate this in the future if it
> shows up being a problem.
Yesterday Rui remarked that global symbol names are already uniqued in
the symbol table. I first thought about reusing the hash, but then
decided to try something even simpler: don't unique strings from the
symbol table. This means we would duplicate a string if a local symbol
has the same name as a global, but merge other cases.
In both clang and scylladb I get the same exact same strtab sizes
(1.02X smaller and 1.026X smaller), but now the slowdowns are just
1.0058X and 1.00106X.
Cheers,
Rafael
-------------- next part --------------
diff --git a/ELF/InputFiles.h b/ELF/InputFiles.h
index 7ca166a..e50669f 100644
--- a/ELF/InputFiles.h
+++ b/ELF/InputFiles.h
@@ -129,7 +129,7 @@ public:
// R_MIPS_GPREL16 / R_MIPS_GPREL32 relocations.
uint32_t getMipsGp0() const;
- std::vector<const Elf_Sym *> KeptLocalSyms;
+ std::vector<std::pair<const Elf_Sym *, unsigned>> KeptLocalSyms;
private:
void initializeSections(llvm::DenseSet<StringRef> &ComdatGroups);
diff --git a/ELF/OutputSections.cpp b/ELF/OutputSections.cpp
index fb2516c..42bb0bc 100644
--- a/ELF/OutputSections.cpp
+++ b/ELF/OutputSections.cpp
@@ -379,7 +379,6 @@ InterpSection<ELFT>::InterpSection()
template <class ELFT>
void OutputSectionBase<ELFT>::writeHeaderTo(Elf_Shdr *SHdr) {
- Header.sh_name = Out<ELFT>::ShStrTab->addString(Name);
*SHdr = Header;
}
@@ -428,7 +427,9 @@ template <class ELFT> void HashTableSection<ELFT>::writeTo(uint8_t *Buf) {
Elf_Word *Buckets = P;
Elf_Word *Chains = P + NumSymbols;
- for (SymbolBody *Body : Out<ELFT>::DynSymTab->getSymbols()) {
+ for (const std::pair<SymbolBody *, unsigned> &P :
+ Out<ELFT>::DynSymTab->getSymbols()) {
+ SymbolBody *Body = P.first;
StringRef Name = Body->getName();
unsigned I = Body->DynamicSymbolTableIndex;
uint32_t Hash = hashSysv(Name) % NumSymbols;
@@ -560,15 +561,18 @@ static bool includeInGnuHashTable(SymbolBody *B) {
}
template <class ELFT>
-void GnuHashTableSection<ELFT>::addSymbols(std::vector<SymbolBody *> &Symbols) {
- std::vector<SymbolBody *> NotHashed;
+void GnuHashTableSection<ELFT>::addSymbols(
+ std::vector<std::pair<SymbolBody *, unsigned>> &Symbols) {
+ std::vector<std::pair<SymbolBody *, unsigned>> NotHashed;
NotHashed.reserve(Symbols.size());
HashedSymbols.reserve(Symbols.size());
- for (SymbolBody *B : Symbols) {
+ for (const std::pair<SymbolBody *, unsigned> &P : Symbols) {
+ SymbolBody *B = P.first;
if (includeInGnuHashTable(B))
- HashedSymbols.push_back(HashedSymbolData{B, hashGnu(B->getName())});
+ HashedSymbols.push_back(
+ HashedSymbolData{B, P.second, hashGnu(B->getName())});
else
- NotHashed.push_back(B);
+ NotHashed.push_back(P);
}
if (HashedSymbols.empty())
return;
@@ -581,7 +585,7 @@ void GnuHashTableSection<ELFT>::addSymbols(std::vector<SymbolBody *> &Symbols) {
Symbols = std::move(NotHashed);
for (const HashedSymbolData &Item : HashedSymbols)
- Symbols.push_back(Item.Body);
+ Symbols.push_back(std::make_pair(Item.Body, Item.STName));
}
template <class ELFT>
@@ -606,18 +610,21 @@ template <class ELFT> void DynamicSection<ELFT>::finalize() {
Elf_Shdr &Header = this->Header;
Header.sh_link = Out<ELFT>::DynStrTab->SectionIndex;
+ auto Add = [=](Entry E) { Entries.push_back(E); };
+
// Reserve strings. We know that these are the last string to be added to
// DynStrTab and doing this here allows this function to set DT_STRSZ.
if (!Config->RPath.empty())
- Out<ELFT>::DynStrTab->reserve(Config->RPath);
- if (!Config->SoName.empty())
- Out<ELFT>::DynStrTab->reserve(Config->SoName);
+ Add({Config->EnableNewDtags ? DT_RUNPATH : DT_RPATH,
+ Out<ELFT>::DynStrTab->addString(Config->RPath)});
for (const std::unique_ptr<SharedFile<ELFT>> &F : SymTab.getSharedFiles())
if (F->isNeeded())
- Out<ELFT>::DynStrTab->reserve(F->getSoName());
+ Add({DT_NEEDED, Out<ELFT>::DynStrTab->addString(F->getSoName())});
+ if (!Config->SoName.empty())
+ Add({DT_SONAME, Out<ELFT>::DynStrTab->addString(Config->SoName)});
+
Out<ELFT>::DynStrTab->finalize();
- auto Add = [=](Entry E) { Entries.push_back(E); };
if (Out<ELFT>::RelaDyn->hasRelocs()) {
bool IsRela = Out<ELFT>::RelaDyn->isRela();
@@ -643,13 +650,6 @@ template <class ELFT> void DynamicSection<ELFT>::finalize() {
if (Out<ELFT>::HashTab)
Add({DT_HASH, Out<ELFT>::HashTab});
- if (!Config->RPath.empty())
- Add({Config->EnableNewDtags ? DT_RUNPATH : DT_RPATH,
- Out<ELFT>::DynStrTab->addString(Config->RPath)});
-
- if (!Config->SoName.empty())
- Add({DT_SONAME, Out<ELFT>::DynStrTab->addString(Config->SoName)});
-
if (PreInitArraySec) {
Add({DT_PREINIT_ARRAY, PreInitArraySec});
Add({DT_PREINIT_ARRAYSZ, PreInitArraySec->getSize()});
@@ -663,10 +663,6 @@ template <class ELFT> void DynamicSection<ELFT>::finalize() {
Add({DT_FINI_ARRAYSZ, (uintX_t)FiniArraySec->getSize()});
}
- for (const std::unique_ptr<SharedFile<ELFT>> &F : SymTab.getSharedFiles())
- if (F->isNeeded())
- Add({DT_NEEDED, Out<ELFT>::DynStrTab->addString(F->getSoName())});
-
if (SymbolBody *B = SymTab.find(Config->Init))
Add({DT_INIT, B});
if (SymbolBody *B = SymTab.find(Config->Fini))
@@ -1207,13 +1203,15 @@ template <class ELFT>
void EHOutputSection<ELFT>::addSection(InputSectionBase<ELFT> *C) {
auto *S = cast<EHInputSection<ELFT>>(C);
const Elf_Shdr *RelSec = S->RelocSection;
- if (!RelSec)
- return addSectionAux(
- S, make_range((const Elf_Rela *)nullptr, (const Elf_Rela *)nullptr));
+ if (!RelSec) {
+ addSectionAux(S, make_range<const Elf_Rela *>(nullptr, nullptr));
+ return;
+ }
ELFFile<ELFT> &Obj = S->getFile()->getObj();
if (RelSec->sh_type == SHT_RELA)
- return addSectionAux(S, Obj.relas(RelSec));
- return addSectionAux(S, Obj.rels(RelSec));
+ addSectionAux(S, Obj.relas(RelSec));
+ else
+ addSectionAux(S, Obj.rels(RelSec));
}
template <class ELFT>
@@ -1347,30 +1345,18 @@ StringTableSection<ELFT>::StringTableSection(StringRef Name, bool Dynamic)
this->Header.sh_addralign = 1;
}
-// String tables are created in two phases. First you call reserve()
-// to reserve room in the string table, and then call addString() to actually
-// add that string.
-//
-// Why two phases? We want to know the size of the string table as early as
-// possible to fix file layout. So we have separated finalize(), which
-// determines the size of the section, from writeTo(), which writes the section
-// contents to the output buffer. If we merge reserve() with addString(),
-// we need a plumbing work for finalize() and writeTo() so that offsets
-// we obtained in the former function can be written in the latter.
-// This design eliminated that need.
-template <class ELFT> void StringTableSection<ELFT>::reserve(StringRef S) {
- Reserved += S.size() + 1; // +1 for NUL
-}
-
-// Adds a string to the string table. You must call reserve() with the
-// same string before calling addString().
-template <class ELFT> size_t StringTableSection<ELFT>::addString(StringRef S) {
- size_t Pos = Used;
+// Adds a string to the string table.
+template <class ELFT>
+size_t StringTableSection<ELFT>::addString(StringRef S, bool HashIt) {
+ if (HashIt) {
+ auto R = StringMap.insert(std::make_pair(S, Size));
+ if (!R.second)
+ return R.first->second;
+ }
+ size_t Ret = Size;
+ Size += S.size() + 1;
Strings.push_back(S);
- Used += S.size() + 1;
- Reserved -= S.size() + 1;
- assert((int64_t)Reserved >= 0);
- return Pos;
+ return Ret;
}
template <class ELFT> void StringTableSection<ELFT>::writeTo(uint8_t *Buf) {
@@ -1388,7 +1374,7 @@ SymbolTableSection<ELFT>::SymbolTableSection(
: OutputSectionBase<ELFT>(StrTabSec.isDynamic() ? ".dynsym" : ".symtab",
StrTabSec.isDynamic() ? SHT_DYNSYM : SHT_SYMTAB,
StrTabSec.isDynamic() ? (uintX_t)SHF_ALLOC : 0),
- Table(Table), StrTabSec(StrTabSec) {
+ StrTabSec(StrTabSec), Table(Table) {
this->Header.sh_entsize = sizeof(Elf_Sym);
this->Header.sh_addralign = ELFT::Is64Bits ? 8 : 4;
}
@@ -1398,10 +1384,11 @@ SymbolTableSection<ELFT>::SymbolTableSection(
// See "Global Offset Table" in Chapter 5 in the following document
// for detailed description:
// ftp://www.linux-mips.org/pub/linux/mips/doc/ABI/mipsabi.pdf
-static bool sortMipsSymbols(SymbolBody *L, SymbolBody *R) {
- if (!L->isInGot() || !R->isInGot())
- return R->isInGot();
- return L->GotIndex < R->GotIndex;
+static bool sortMipsSymbols(const std::pair<SymbolBody *, unsigned> &L,
+ const std::pair<SymbolBody *, unsigned> &R) {
+ if (!L.first->isInGot() || !R.first->isInGot())
+ return R.first->isInGot();
+ return L.first->GotIndex < R.first->GotIndex;
}
template <class ELFT> void SymbolTableSection<ELFT>::finalize() {
@@ -1414,9 +1401,10 @@ template <class ELFT> void SymbolTableSection<ELFT>::finalize() {
if (!StrTabSec.isDynamic()) {
std::stable_sort(Symbols.begin(), Symbols.end(),
- [](SymbolBody *L, SymbolBody *R) {
- return getSymbolBinding(L) == STB_LOCAL &&
- getSymbolBinding(R) != STB_LOCAL;
+ [](const std::pair<SymbolBody *, unsigned> &L,
+ const std::pair<SymbolBody *, unsigned> &R) {
+ return getSymbolBinding(L.first) == STB_LOCAL &&
+ getSymbolBinding(R.first) != STB_LOCAL;
});
return;
}
@@ -1426,20 +1414,14 @@ template <class ELFT> void SymbolTableSection<ELFT>::finalize() {
else if (Config->EMachine == EM_MIPS)
std::stable_sort(Symbols.begin(), Symbols.end(), sortMipsSymbols);
size_t I = 0;
- for (SymbolBody *B : Symbols)
- B->DynamicSymbolTableIndex = ++I;
-}
-
-template <class ELFT>
-void SymbolTableSection<ELFT>::addLocalSymbol(StringRef Name) {
- StrTabSec.reserve(Name);
- ++NumLocals;
+ for (const std::pair<SymbolBody *, unsigned> &P : Symbols)
+ P.first->DynamicSymbolTableIndex = ++I;
}
template <class ELFT>
void SymbolTableSection<ELFT>::addSymbol(SymbolBody *Body) {
- StrTabSec.reserve(Body->getName());
- Symbols.push_back(Body);
+ Symbols.push_back(
+ std::make_pair(Body, StrTabSec.addString(Body->getName(), false)));
}
template <class ELFT> void SymbolTableSection<ELFT>::writeTo(uint8_t *Buf) {
@@ -1458,10 +1440,8 @@ void SymbolTableSection<ELFT>::writeLocalSymbols(uint8_t *&Buf) {
// Iterate over all input object files to copy their local symbols
// to the output symbol table pointed by Buf.
for (const std::unique_ptr<ObjectFile<ELFT>> &File : Table.getObjectFiles()) {
- for (const Elf_Sym *Sym : File->KeptLocalSyms) {
- ErrorOr<StringRef> SymNameOrErr = Sym->getName(File->getStringTable());
- error(SymNameOrErr);
- StringRef SymName = *SymNameOrErr;
+ for (const std::pair<const Elf_Sym *, unsigned> &P : File->KeptLocalSyms) {
+ const Elf_Sym *Sym = P.first;
auto *ESym = reinterpret_cast<Elf_Sym *>(Buf);
uintX_t VA = 0;
@@ -1478,7 +1458,7 @@ void SymbolTableSection<ELFT>::writeLocalSymbols(uint8_t *&Buf) {
if (Config->EMachine != EM_AMDGPU)
VA += OutSec->getVA();
}
- ESym->st_name = StrTabSec.addString(SymName);
+ ESym->st_name = P.second;
ESym->st_size = Sym->st_size;
ESym->setBindingAndType(Sym->getBinding(), Sym->getType());
ESym->st_value = VA;
@@ -1502,7 +1482,8 @@ void SymbolTableSection<ELFT>::writeGlobalSymbols(uint8_t *Buf) {
// Write the internal symbol table contents to the output symbol table
// pointed by Buf.
auto *ESym = reinterpret_cast<Elf_Sym *>(Buf);
- for (SymbolBody *Body : Symbols) {
+ for (const std::pair<SymbolBody *, unsigned> &P : Symbols) {
+ SymbolBody *Body = P.first;
const OutputSectionBase<ELFT> *OutSec = nullptr;
switch (Body->kind()) {
@@ -1532,8 +1513,7 @@ void SymbolTableSection<ELFT>::writeGlobalSymbols(uint8_t *Buf) {
break;
}
- StringRef Name = Body->getName();
- ESym->st_name = StrTabSec.addString(Name);
+ ESym->st_name = P.second;
unsigned char Type = STT_NOTYPE;
uintX_t Size = 0;
diff --git a/ELF/OutputSections.h b/ELF/OutputSections.h
index 10f55a9..0fb9c4a 100644
--- a/ELF/OutputSections.h
+++ b/ELF/OutputSections.h
@@ -12,7 +12,6 @@
#include "lld/Core/LLVM.h"
-#include "llvm/ADT/MapVector.h"
#include "llvm/MC/StringTableBuilder.h"
#include "llvm/Object/ELF.h"
@@ -73,6 +72,7 @@ public:
void setVA(uintX_t VA) { Header.sh_addr = VA; }
uintX_t getVA() const { return Header.sh_addr; }
void setFileOffset(uintX_t Off) { Header.sh_offset = Off; }
+ void setSHName(unsigned Val) { Header.sh_name = Val; }
void writeHeaderTo(Elf_Shdr *SHdr);
StringRef getName() { return Name; }
@@ -195,12 +195,16 @@ public:
void finalize() override;
void writeTo(uint8_t *Buf) override;
- void addLocalSymbol(StringRef Name);
void addSymbol(SymbolBody *Body);
StringTableSection<ELFT> &getStrTabSec() const { return StrTabSec; }
unsigned getNumSymbols() const { return NumLocals + Symbols.size() + 1; }
- ArrayRef<SymbolBody *> getSymbols() const { return Symbols; }
+ ArrayRef<std::pair<SymbolBody *, unsigned>> getSymbols() const {
+ return Symbols;
+ }
+
+ unsigned NumLocals = 0;
+ StringTableSection<ELFT> &StrTabSec;
private:
void writeLocalSymbols(uint8_t *&Buf);
@@ -209,9 +213,7 @@ private:
static uint8_t getSymbolBinding(SymbolBody *Body);
SymbolTable<ELFT> &Table;
- StringTableSection<ELFT> &StrTabSec;
- std::vector<SymbolBody *> Symbols;
- unsigned NumLocals = 0;
+ std::vector<std::pair<SymbolBody *, unsigned>> Symbols;
};
template <class ELFT>
@@ -328,18 +330,17 @@ class StringTableSection final : public OutputSectionBase<ELFT> {
public:
typedef typename llvm::object::ELFFile<ELFT>::uintX_t uintX_t;
StringTableSection(StringRef Name, bool Dynamic);
- void reserve(StringRef S);
- size_t addString(StringRef S);
+ size_t addString(StringRef S, bool HashIt = true);
void writeTo(uint8_t *Buf) override;
- size_t getSize() const { return Used + Reserved; }
+ size_t getSize() const { return Size; }
void finalize() override { this->Header.sh_size = getSize(); }
bool isDynamic() const { return Dynamic; }
private:
const bool Dynamic;
+ llvm::DenseMap<StringRef, size_t> StringMap;
std::vector<StringRef> Strings;
- size_t Used = 1; // ELF string tables start with a NUL byte, so 1.
- size_t Reserved = 0;
+ size_t Size = 1; // ELF string tables start with a NUL byte, so 1.
};
template <class ELFT>
@@ -367,7 +368,7 @@ public:
// Adds symbols to the hash table.
// Sorts the input to satisfy GNU hash section requirements.
- void addSymbols(std::vector<SymbolBody *> &Symbols);
+ void addSymbols(std::vector<std::pair<SymbolBody *, unsigned>> &Symbols);
private:
static unsigned calcNBuckets(unsigned NumHashed);
@@ -379,6 +380,7 @@ private:
struct HashedSymbolData {
SymbolBody *Body;
+ unsigned STName;
uint32_t Hash;
};
diff --git a/ELF/Writer.cpp b/ELF/Writer.cpp
index a616fdc..e3ab542 100644
--- a/ELF/Writer.cpp
+++ b/ELF/Writer.cpp
@@ -430,8 +430,9 @@ template <class ELFT> void Writer<ELFT>::copyLocalSymbols() {
if (!Section->isLive())
continue;
}
- Out<ELFT>::SymTab->addLocalSymbol(SymName);
- F->KeptLocalSyms.push_back(&Sym);
+ ++Out<ELFT>::SymTab->NumLocals;
+ F->KeptLocalSyms.push_back(std::make_pair(
+ &Sym, Out<ELFT>::SymTab->StrTabSec.addString(SymName)));
}
}
}
@@ -903,7 +904,7 @@ template <class ELFT> void Writer<ELFT>::createSections() {
}
for (OutputSectionBase<ELFT> *Sec : OutputSections)
- Out<ELFT>::ShStrTab->reserve(Sec->getName());
+ Sec->setSHName(Out<ELFT>::ShStrTab->addString(Sec->getName()));
// Finalizers fix each section's size.
// .dynsym is finalized early since that may fill up .gnu.hash.
diff --git a/test/ELF/dynamic-reloc.s b/test/ELF/dynamic-reloc.s
index 2953960..5e23ba9 100644
--- a/test/ELF/dynamic-reloc.s
+++ b/test/ELF/dynamic-reloc.s
@@ -43,6 +43,7 @@
// CHECK: DynamicSection [
// CHECK-NEXT: Tag Type Name/Value
+// CHECK-NEXT: 0x0000000000000001 NEEDED SharedLibrary ({{.*}}2.so)
// CHECK-NEXT: 0x0000000000000017 JMPREL
// CHECK-NEXT: 0x0000000000000002 PLTRELSZ 24 (bytes)
// CHECK-NEXT: 0x0000000000000003 PLTGOT
@@ -52,7 +53,6 @@
// CHECK-NEXT: 0x0000000000000005 STRTAB
// CHECK-NEXT: 0x000000000000000A STRSZ
// CHECK-NEXT: 0x0000000000000004 HASH
-// CHECK-NEXT: 0x0000000000000001 NEEDED SharedLibrary ({{.*}}2.so)
// CHECK-NEXT: 0x0000000000000015 DEBUG 0x0
// CHECK-NEXT: 0x0000000000000000 NULL 0x0
// CHECK-NEXT: ]
diff --git a/test/ELF/linkerscript-sections.s b/test/ELF/linkerscript-sections.s
index 165ec33..ea9ae2b 100644
--- a/test/ELF/linkerscript-sections.s
+++ b/test/ELF/linkerscript-sections.s
@@ -22,7 +22,7 @@
# SEC-DEFAULT: 4 .bss 00000002 {{[0-9a-f]*}} BSS
# SEC-DEFAULT: 5 .shstrtab 00000002 {{[0-9a-f]*}}
# SEC-DEFAULT: 6 .symtab 00000030 {{[0-9a-f]*}}
-# SEC-DEFAULT: 7 .shstrtab 0000003c {{[0-9a-f]*}}
+# SEC-DEFAULT: 7 .shstrtab 00000032 {{[0-9a-f]*}}
# SEC-DEFAULT: 8 .strtab 00000008 {{[0-9a-f]*}}
# Sections are put in order specified in linker script.
@@ -42,7 +42,7 @@
# SEC-ORDER: 1 .bss 00000002 {{[0-9a-f]*}} BSS
# SEC-ORDER: 2 other 00000003 {{[0-9a-f]*}} DATA
# SEC-ORDER: 3 .shstrtab 00000002 {{[0-9a-f]*}}
-# SEC-ORDER: 4 .shstrtab 0000003c {{[0-9a-f]*}}
+# SEC-ORDER: 4 .shstrtab 00000032 {{[0-9a-f]*}}
# SEC-ORDER: 5 .symtab 00000030 {{[0-9a-f]*}}
# SEC-ORDER: 6 .strtab 00000008 {{[0-9a-f]*}}
# SEC-ORDER: 7 .data 00000020 {{[0-9a-f]*}} DATA
@@ -63,7 +63,7 @@
# SEC-SWAP-NAMES: 4 .bss 00000002 {{[0-9a-f]*}} BSS
# SEC-SWAP-NAMES: 5 .shstrtab 00000002 {{[0-9a-f]*}}
# SEC-SWAP-NAMES: 6 .symtab 00000030 {{[0-9a-f]*}}
-# SEC-SWAP-NAMES: 7 .shstrtab 0000003c {{[0-9a-f]*}}
+# SEC-SWAP-NAMES: 7 .shstrtab 00000032 {{[0-9a-f]*}}
# SEC-SWAP-NAMES: 8 .strtab 00000008 {{[0-9a-f]*}}
# .shstrtab from the input object file is discarded.
@@ -100,7 +100,7 @@
# SEC-MULTI: 3 .bss 00000002 {{[0-9a-f]*}} BSS
# SEC-MULTI: 4 .shstrtab 00000002 {{[0-9a-f]*}}
# SEC-MULTI: 5 .symtab 00000030 {{[0-9a-f]*}}
-# SEC-MULTI: 6 .shstrtab 00000036 {{[0-9a-f]*}}
+# SEC-MULTI: 6 .shstrtab 0000002c {{[0-9a-f]*}}
# SEC-MULTI: 7 .strtab 00000008 {{[0-9a-f]*}}
.globl _start;
diff --git a/test/ELF/shared-be.s b/test/ELF/shared-be.s
index 0f57a4b..945f365 100644
--- a/test/ELF/shared-be.s
+++ b/test/ELF/shared-be.s
@@ -20,12 +20,12 @@
// CHECK: DynamicSection [
// CHECK-NEXT: Tag Type Name/Value
+// CHECK-NEXT: 0x000000000000001D RUNPATH foo:bar
+// CHECK-NEXT: 0x0000000000000001 NEEDED SharedLibrary ({{.*}}2.so)
// CHECK-NEXT: 0x0000000000000007 RELA [[RELADDR]]
// CHECK-NEXT: 0x0000000000000008 RELASZ [[RELSIZE]] (bytes)
// CHECK-NEXT: 0x0000000000000009 RELAENT [[RELENT]] (bytes)
-// CHECK: 0x000000000000001D RUNPATH foo:bar
-// CHECK-NEXT: 0x0000000000000001 NEEDED SharedLibrary ({{.*}}2.so)
-// CHECK-NEXT: 0x0000000000000015 DEBUG 0x0
+// CHECK: 0x0000000000000015 DEBUG 0x0
// CHECK-NEXT: 0x0000000000000000 NULL 0x0
// CHECK-NEXT: ]
diff --git a/test/ELF/shared.s b/test/ELF/shared.s
index 1bf5bd1..850c637 100644
--- a/test/ELF/shared.s
+++ b/test/ELF/shared.s
@@ -243,6 +243,8 @@
// CHECK: DynamicSection [
// CHECK-NEXT: Tag Type Name/Value
+// CHECK-NEXT: 0x0000001D RUNPATH foo:bar
+// CHECK-NEXT: 0x00000001 NEEDED SharedLibrary ({{.*}}2.so)
// CHECK-NEXT: 0x00000011 REL [[RELADDR]]
// CHECK-NEXT: 0x00000012 RELSZ [[RELSIZE]] (bytes)
// CHECK-NEXT: 0x00000013 RELENT [[RELENT]] (bytes)
@@ -251,8 +253,6 @@
// CHECK-NEXT: 0x00000005 STRTAB [[DYNSTRADDR]]
// CHECK-NEXT: 0x0000000A STRSZ
// CHECK-NEXT: 0x00000004 HASH [[HASHADDR]]
-// CHECK-NEXT: 0x0000001D RUNPATH foo:bar
-// CHECK-NEXT: 0x00000001 NEEDED SharedLibrary ({{.*}}2.so)
// CHECK-NEXT: 0x00000015 DEBUG 0x0
// CHECK-NEXT: 0x00000000 NULL 0x0
// CHECK-NEXT: ]
diff --git a/test/ELF/string-table.s b/test/ELF/string-table.s
index 8393d6d..892c348 100644
--- a/test/ELF/string-table.s
+++ b/test/ELF/string-table.s
@@ -59,9 +59,8 @@ _start:
// CHECK-NEXT: EntrySize: 0
// CHECK-NEXT: SectionData (
// CHECK-NEXT: 0000: 00626172 002E7465 78740066 6F6F6261 |.bar..text.fooba|
-// CHECK-NEXT: 0010: 7200666F 6F626172 00666F6F 62617200 |r.foobar.foobar.|
-// CHECK-NEXT: 0020: 2E73796D 74616200 2E736873 74727461 |.symtab..shstrta|
-// CHECK-NEXT: 0030: 62002E73 74727461 6200 |b..strtab.|
+// CHECK-NEXT: 0010: 72002E73 796D7461 62002E73 68737472 |r..symtab..shstr|
+// CHECK-NEXT: 0020: 74616200 2E737472 74616200 |tab..strtab.|
// CHECK-NEXT: )
// CHECK-NEXT:}
// CHECK: Name: .strtab
More information about the llvm-commits
mailing list