Make sure we output symbols in the same order on 32 and 64 bit builds.

llvm-svn: 246264
This commit is contained in:
Rafael Espindola 2015-08-28 02:46:41 +00:00
parent 52a980a97f
commit 871765c321
2 changed files with 57 additions and 36 deletions

View File

@ -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<Is64Bits>::writeTo(uint8_t *Buf) {
memcpy(Buf, Data.data(), Data.size());
}
template <class ELFT>
static int compareSym(const typename ELFFile<ELFT>::Elf_Sym *A,
const typename ELFFile<ELFT>::Elf_Sym *B) {
uint32_t AN = A->st_name;
uint32_t BN = B->st_name;
assert(AN != BN);
return AN - BN;
}
template <class ELFT> void SymbolTableSection<ELFT>::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 <class ELFT> void SymbolTableSection<ELFT>::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<Elf_Sym *>(BufStart);
++Syms;
array_pod_sort(Syms, Syms + Table.getSymbols().size(), compareSym<ELFT>);
}
template <bool Is64Bits>

View File

@ -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