mirror of
https://github.com/RPCS3/llvm-mirror.git
synced 2024-10-19 19:12:56 +02:00
Re-land "[dsymutil] Fix handling of common symbols in multiple object files."
The original patch got reverted because it hit a long-standing legacy issue on Windows that prevents files from being named `com`. Thanks Kristina & Jeremy for pointing this out. llvm-svn: 374178
This commit is contained in:
parent
5f91d66ebc
commit
8a6c6bbbd4
BIN
test/tools/dsymutil/Inputs/private/tmp/common/common.x86_64
Executable file
BIN
test/tools/dsymutil/Inputs/private/tmp/common/common.x86_64
Executable file
Binary file not shown.
BIN
test/tools/dsymutil/Inputs/private/tmp/common/common1.o
Normal file
BIN
test/tools/dsymutil/Inputs/private/tmp/common/common1.o
Normal file
Binary file not shown.
BIN
test/tools/dsymutil/Inputs/private/tmp/common/common2.o
Normal file
BIN
test/tools/dsymutil/Inputs/private/tmp/common/common2.o
Normal file
Binary file not shown.
39
test/tools/dsymutil/X86/common-sym-multi.test
Normal file
39
test/tools/dsymutil/X86/common-sym-multi.test
Normal file
@ -0,0 +1,39 @@
|
||||
RUN: dsymutil -oso-prepend-path %p/../Inputs %p/../Inputs/private/tmp/common/common.x86_64 -f -o - | llvm-dwarfdump -debug-info - | FileCheck %s
|
||||
RUN: dsymutil -oso-prepend-path %p/../Inputs %p/../Inputs/private/tmp/common/common.x86_64 -dump-debug-map | FileCheck %s --check-prefix DEBUGMAP
|
||||
|
||||
The test was compiled from two source files:
|
||||
$ cd /private/tmp/common
|
||||
$ cat common1.c
|
||||
int i[1000];
|
||||
int main() {
|
||||
return i[1];
|
||||
}
|
||||
$ cat common2.c
|
||||
extern int i[1000];
|
||||
int bar() {
|
||||
return i[0];
|
||||
}
|
||||
$ clang -fcommon -g -c common1.c -o common1.o
|
||||
$ clang -fcommon -g -c common2.c -o common2.o
|
||||
$ clang -fcommon -g common1.o common2.o -o common.x86_64
|
||||
|
||||
CHECK: DW_TAG_compile_unit
|
||||
CHECK: DW_TAG_variable
|
||||
CHECK-NOT: {{NULL|DW_TAG}}
|
||||
CHECK: DW_AT_name{{.*}}"i"
|
||||
CHECK-NOT: {{NULL|DW_TAG}}
|
||||
CHECK: DW_AT_location{{.*}}DW_OP_addr 0x100001000)
|
||||
|
||||
CHECK: DW_TAG_compile_unit
|
||||
CHECK: DW_TAG_variable
|
||||
CHECK-NOT: {{NULL|DW_TAG}}
|
||||
CHECK: DW_AT_name{{.*}}"i"
|
||||
CHECK-NOT: {{NULL|DW_TAG}}
|
||||
CHECK: DW_AT_location{{.*}}DW_OP_addr 0x100001000)
|
||||
|
||||
DEBUGMAP: filename:{{.*}}common1.o
|
||||
DEBUGMAP: symbols:
|
||||
DEBUGMAP: sym: _i, binAddr: 0x0000000100001000, size: 0x00000000
|
||||
DEBUGMAP: filename:{{.*}}common2.o
|
||||
DEBUGMAP: symbols:
|
||||
DEBUGMAP: sym: _i, binAddr: 0x0000000100001000, size: 0x00000000
|
@ -14,6 +14,7 @@
|
||||
#include "llvm/Support/Path.h"
|
||||
#include "llvm/Support/WithColor.h"
|
||||
#include "llvm/Support/raw_ostream.h"
|
||||
#include <vector>
|
||||
|
||||
namespace {
|
||||
using namespace llvm;
|
||||
@ -51,6 +52,8 @@ private:
|
||||
StringRef MainBinaryStrings;
|
||||
/// The constructed DebugMap.
|
||||
std::unique_ptr<DebugMap> Result;
|
||||
/// List of common symbols that need to be added to the debug map.
|
||||
std::vector<std::string> CommonSymbols;
|
||||
|
||||
/// Map of the currently processed object file symbol addresses.
|
||||
StringMap<Optional<uint64_t>> CurrentObjectAddresses;
|
||||
@ -81,6 +84,8 @@ private:
|
||||
STE.n_value);
|
||||
}
|
||||
|
||||
void addCommonSymbols();
|
||||
|
||||
/// Dump the symbol table output header.
|
||||
void dumpSymTabHeader(raw_ostream &OS, StringRef Arch);
|
||||
|
||||
@ -122,11 +127,32 @@ void MachODebugMapParser::resetParserState() {
|
||||
CurrentDebugMapObject = nullptr;
|
||||
}
|
||||
|
||||
/// Commons symbols won't show up in the symbol map but might need to be
|
||||
/// relocated. We can add them to the symbol table ourselves by combining the
|
||||
/// information in the object file (the symbol name) and the main binary (the
|
||||
/// address).
|
||||
void MachODebugMapParser::addCommonSymbols() {
|
||||
for (auto &CommonSymbol : CommonSymbols) {
|
||||
uint64_t CommonAddr = getMainBinarySymbolAddress(CommonSymbol);
|
||||
if (CommonAddr == 0) {
|
||||
// The main binary doesn't have an address for the given symbol.
|
||||
continue;
|
||||
}
|
||||
if (!CurrentDebugMapObject->addSymbol(CommonSymbol, None /*ObjectAddress*/,
|
||||
CommonAddr, 0 /*size*/)) {
|
||||
// The symbol is already present.
|
||||
continue;
|
||||
}
|
||||
}
|
||||
CommonSymbols.clear();
|
||||
}
|
||||
|
||||
/// Create a new DebugMapObject. This function resets the state of the
|
||||
/// parser that was referring to the last object file and sets
|
||||
/// everything up to add symbols to the new one.
|
||||
void MachODebugMapParser::switchToNewDebugMapObject(
|
||||
StringRef Filename, sys::TimePoint<std::chrono::seconds> Timestamp) {
|
||||
addCommonSymbols();
|
||||
resetParserState();
|
||||
|
||||
SmallString<80> Path(PathPrefix);
|
||||
@ -466,11 +492,16 @@ void MachODebugMapParser::loadCurrentObjectFileSymbols(
|
||||
// relocations will use the symbol itself, and won't need an
|
||||
// object file address. The object file address field is optional
|
||||
// in the DebugMap, leave it unassigned for these symbols.
|
||||
if (Sym.getFlags() & (SymbolRef::SF_Absolute | SymbolRef::SF_Common))
|
||||
uint32_t Flags = Sym.getFlags();
|
||||
if (Flags & SymbolRef::SF_Absolute) {
|
||||
CurrentObjectAddresses[*Name] = None;
|
||||
else
|
||||
} else if (Flags & SymbolRef::SF_Common) {
|
||||
CurrentObjectAddresses[*Name] = None;
|
||||
CommonSymbols.push_back(*Name);
|
||||
} else {
|
||||
CurrentObjectAddresses[*Name] = Addr;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/// Lookup a symbol address in the main binary symbol table. The
|
||||
|
Loading…
Reference in New Issue
Block a user