From 871765c3214fbc03cbbab339a74974b282512be7 Mon Sep 17 00:00:00 2001 From: Rafael Espindola Date: Fri, 28 Aug 2015 02:46:41 +0000 Subject: [PATCH] Make sure we output symbols in the same order on 32 and 64 bit builds. llvm-svn: 246264 --- lld/ELF/Writer.cpp | 21 ++++++++++++ lld/test/elf2/symbols.s | 72 ++++++++++++++++++++--------------------- 2 files changed, 57 insertions(+), 36 deletions(-) diff --git a/lld/ELF/Writer.cpp b/lld/ELF/Writer.cpp index c42b0e647c48..244d4fd462d0 100644 --- a/lld/ELF/Writer.cpp +++ b/lld/ELF/Writer.cpp @@ -16,6 +16,7 @@ #include "Symbols.h" #include "llvm/ADT/DenseMap.h" +#include "llvm/ADT/STLExtras.h" #include "llvm/Support/FileOutputBuffer.h" #include "llvm/Support/raw_ostream.h" @@ -273,7 +274,18 @@ void StringTableSection::writeTo(uint8_t *Buf) { memcpy(Buf, Data.data(), Data.size()); } +template +static int compareSym(const typename ELFFile::Elf_Sym *A, + const typename ELFFile::Elf_Sym *B) { + uint32_t AN = A->st_name; + uint32_t BN = B->st_name; + assert(AN != BN); + return AN - BN; +} + template void SymbolTableSection::writeTo(uint8_t *Buf) { + uint8_t *BufStart = Buf; + Buf += sizeof(Elf_Sym); llvm::StringTableBuilder &Builder = Table.getStringBuilder(); for (auto &P : Table.getSymbols()) { @@ -326,6 +338,15 @@ template void SymbolTableSection::writeTo(uint8_t *Buf) { Buf += sizeof(Elf_Sym); } + + // The order the global symbols are in is not defined. We can use an arbitrary + // order, but it has to be reproducible. That is true even when cross linking. + // The default hashing of StringRef produces different results on 32 and 64 + // bit systems so we sort by st_name. That is arbitrary but deterministic. + // FIXME: Experiment with passing in a custom hashing instead. + auto *Syms = reinterpret_cast(BufStart); + ++Syms; + array_pod_sort(Syms, Syms + Table.getSymbols().size(), compareSym); } template diff --git a/lld/test/elf2/symbols.s b/lld/test/elf2/symbols.s index 44a478757e80..5d1ef3a630e2 100644 --- a/lld/test/elf2/symbols.s +++ b/lld/test/elf2/symbols.s @@ -57,6 +57,42 @@ abs = 0x123 // CHECK-NEXT: Section: Undefined (0x0) // CHECK-NEXT: } // CHECK-NEXT: Symbol { +// CHECK-NEXT: Name: _start +// CHECK-NEXT: Value: 0x1000 +// CHECK-NEXT: Size: 0 +// CHECK-NEXT: Binding: Global (0x1) +// CHECK-NEXT: Type: Function +// CHECK-NEXT: Other: 0 +// CHECK-NEXT: Section: .text +// CHECK-NEXT: } +// CHECK-NEXT: Symbol { +// CHECK-NEXT: Name: abs +// CHECK-NEXT: Value: 0x123 +// CHECK-NEXT: Size: 0 +// CHECK-NEXT: Binding: Global +// CHECK-NEXT: Type: None +// CHECK-NEXT: Other: 0 +// CHECK-NEXT: Section: Absolute +// CHECK-NEXT: } +// CHECK-NEXT: Symbol { +// CHECK-NEXT: Name: bar +// CHECK-NEXT: Value: 0x0 +// CHECK-NEXT: Size: 0 +// CHECK-NEXT: Binding: Weak (0x2) +// CHECK-NEXT: Type: Object (0x1) +// CHECK-NEXT: Other: 0 +// CHECK-NEXT: Section: Undefined (0x0) +// CHECK-NEXT: } +// CHECK-NEXT: Symbol { +// CHECK-NEXT: Name: foo +// CHECK-NEXT: Value: 0x1000 +// CHECK-NEXT: Size: 0 +// CHECK-NEXT: Binding: Weak (0x2) +// CHECK-NEXT: Type: Object +// CHECK-NEXT: Other: 0 +// CHECK-NEXT: Section: .text +// CHECK-NEXT: } +// CHECK-NEXT: Symbol { // CHECK-NEXT: Name: zed // CHECK-NEXT: Value: 0x1004 // CHECK-NEXT: Size: 0 @@ -75,42 +111,6 @@ abs = 0x123 // CHECK-NEXT: Section: foobar // CHECK-NEXT: } // CHECK-NEXT: Symbol { -// CHECK-NEXT: Name: _start -// CHECK-NEXT: Value: 0x1000 -// CHECK-NEXT: Size: 0 -// CHECK-NEXT: Binding: Global (0x1) -// CHECK-NEXT: Type: Function -// CHECK-NEXT: Other: 0 -// CHECK-NEXT: Section: .text -// CHECK-NEXT: } -// CHECK-NEXT: Symbol { -// CHECK-NEXT: Name: bar -// CHECK-NEXT: Value: 0x0 -// CHECK-NEXT: Size: 0 -// CHECK-NEXT: Binding: Weak (0x2) -// CHECK-NEXT: Type: Object (0x1) -// CHECK-NEXT: Other: 0 -// CHECK-NEXT: Section: Undefined (0x0) -// CHECK-NEXT: } -// CHECK-NEXT: Symbol { -// CHECK-NEXT: Name: abs -// CHECK-NEXT: Value: 0x123 -// CHECK-NEXT: Size: 0 -// CHECK-NEXT: Binding: Global -// CHECK-NEXT: Type: None -// CHECK-NEXT: Other: 0 -// CHECK-NEXT: Section: Absolute -// CHECK-NEXT: } -// CHECK-NEXT: Symbol { -// CHECK-NEXT: Name: foo -// CHECK-NEXT: Value: 0x1000 -// CHECK-NEXT: Size: 0 -// CHECK-NEXT: Binding: Weak (0x2) -// CHECK-NEXT: Type: Object -// CHECK-NEXT: Other: 0 -// CHECK-NEXT: Section: .text -// CHECK-NEXT: } -// CHECK-NEXT: Symbol { // CHECK-NEXT: Name: zed2 // CHECK-NEXT: Value: 0x1008 // CHECK-NEXT: Size: 0