mirror of
https://github.com/RPCS3/llvm-mirror.git
synced 2025-01-31 20:51:52 +01:00
Fix llvm-symbolizer to correctly sort a symbol array and calculate symbol sizes
Sometimes, llvm-symbolizer gives wrong results due to incorrect sizes of some symbols. The reason for that was an incorrectly sorted array in computeSymbolSizes. The comparison function used subtraction of unsigned types, which is incorrect. Let's change this to return explicit -1 or 1. Differential Revision: https://reviews.llvm.org/D26537 llvm-svn: 287028
This commit is contained in:
parent
ffed4c378b
commit
763ff400ea
@ -15,8 +15,19 @@
|
||||
|
||||
namespace llvm {
|
||||
namespace object {
|
||||
|
||||
struct SymEntry {
|
||||
symbol_iterator I;
|
||||
uint64_t Address;
|
||||
unsigned Number;
|
||||
unsigned SectionID;
|
||||
};
|
||||
|
||||
int compareAddress(const SymEntry *A, const SymEntry *B);
|
||||
|
||||
std::vector<std::pair<SymbolRef, uint64_t>>
|
||||
computeSymbolSizes(const ObjectFile &O);
|
||||
|
||||
}
|
||||
} // namespace llvm
|
||||
|
||||
|
@ -16,19 +16,13 @@
|
||||
using namespace llvm;
|
||||
using namespace object;
|
||||
|
||||
namespace {
|
||||
struct SymEntry {
|
||||
symbol_iterator I;
|
||||
uint64_t Address;
|
||||
unsigned Number;
|
||||
unsigned SectionID;
|
||||
};
|
||||
}
|
||||
|
||||
static int compareAddress(const SymEntry *A, const SymEntry *B) {
|
||||
// Orders increasingly by (SectionID, Address).
|
||||
int llvm::object::compareAddress(const SymEntry *A, const SymEntry *B) {
|
||||
if (A->SectionID != B->SectionID)
|
||||
return A->SectionID - B->SectionID;
|
||||
return A->Address - B->Address;
|
||||
return A->SectionID < B->SectionID ? -1 : 1;
|
||||
if (A->Address != B->Address)
|
||||
return A->Address < B->Address ? -1 : 1;
|
||||
return 0;
|
||||
}
|
||||
|
||||
static unsigned getSectionID(const ObjectFile &O, SectionRef Sec) {
|
||||
|
@ -17,6 +17,7 @@ add_subdirectory(LineEditor)
|
||||
add_subdirectory(Linker)
|
||||
add_subdirectory(MC)
|
||||
add_subdirectory(MI)
|
||||
add_subdirectory(Object)
|
||||
add_subdirectory(ObjectYAML)
|
||||
add_subdirectory(Option)
|
||||
add_subdirectory(ProfileData)
|
||||
|
8
unittests/Object/CMakeLists.txt
Normal file
8
unittests/Object/CMakeLists.txt
Normal file
@ -0,0 +1,8 @@
|
||||
set(LLVM_LINK_COMPONENTS
|
||||
Object
|
||||
)
|
||||
|
||||
add_llvm_unittest(ObjectTests
|
||||
SymbolSizeTest.cpp
|
||||
)
|
||||
|
33
unittests/Object/SymbolSizeTest.cpp
Normal file
33
unittests/Object/SymbolSizeTest.cpp
Normal file
@ -0,0 +1,33 @@
|
||||
//===- SymbolSizeTest.cpp - Tests for SymbolSize.cpp ----------------------===//
|
||||
//
|
||||
// The LLVM Compiler Infrastructure
|
||||
//
|
||||
// This file is distributed under the University of Illinois Open Source
|
||||
// License. See LICENSE.TXT for details.
|
||||
//
|
||||
//===----------------------------------------------------------------------===//
|
||||
|
||||
#include "llvm/Object/SymbolSize.h"
|
||||
#include "gtest/gtest.h"
|
||||
|
||||
using namespace llvm;
|
||||
using namespace llvm::object;
|
||||
|
||||
TEST(Object, SymbolSizeSort) {
|
||||
auto it = symbol_iterator(SymbolRef());
|
||||
std::vector<SymEntry> Syms{
|
||||
SymEntry{it, 0xffffffff00000000ull, 1, 0},
|
||||
SymEntry{it, 0x00ffffff00000000ull, 2, 0},
|
||||
SymEntry{it, 0x00ffffff000000ffull, 3, 0},
|
||||
SymEntry{it, 0x0000000100000000ull, 4, 0},
|
||||
SymEntry{it, 0x00000000000000ffull, 5, 0},
|
||||
SymEntry{it, 0x00000001000000ffull, 6, 0},
|
||||
SymEntry{it, 0x000000010000ffffull, 7, 0},
|
||||
};
|
||||
|
||||
array_pod_sort(Syms.begin(), Syms.end(), compareAddress);
|
||||
|
||||
for (unsigned I = 0, N = Syms.size(); I < N - 1; ++I) {
|
||||
EXPECT_LE(Syms[I].Address, Syms[I + 1].Address);
|
||||
}
|
||||
}
|
Loading…
x
Reference in New Issue
Block a user