forked from OSchip/llvm-project
[dsymutil] Have the YAML deserialization rewrite the object address of symbols.
The main use of the YAML debug map format is for testing inside LLVM. If we have IR files in the tests used to generate object files, then we obviously don't know the addresses of the symbols inside the object files beforehand. This change lets the YAML import lookup the addresses in the object files and rewrite them. This will allow to have test that really don't need any binary input. llvm-svn: 239189
This commit is contained in:
parent
bb2cc9cf56
commit
4f5874a51f
|
@ -0,0 +1,44 @@
|
|||
# RUN: llvm-dsymutil -v -dump-debug-map -oso-prepend-path=%p -y %s | FileCheck %s
|
||||
#
|
||||
# The YAML debug map bellow is the one from basic-archive.macho.x86_64 with
|
||||
# the object addresses set to zero. Check that the YAML import is able to
|
||||
# rewrite these addresses to the right values.
|
||||
#
|
||||
# CHECK: ---
|
||||
# CHECK-NEXT: triple:{{.*}}'x86_64-unknown-unknown-macho'
|
||||
# CHECK-NEXT: objects:
|
||||
# CHECK-NEXT: filename:{{.*}}/Inputs/basic1.macho.x86_64.o
|
||||
# CHECK-NEXT: symbols:
|
||||
# CHECK-NEXT: sym: _main, objAddr: 0x0000000000000000, binAddr: 0x0000000100000EA0, size: 0x00000024
|
||||
# CHECK-NEXT: filename:{{.*}}/Inputs/./libbasic.a(basic2.macho.x86_64.o)'
|
||||
# CHECK-NEXT: symbols:
|
||||
# CHECK-DAG: sym: _foo, objAddr: 0x0000000000000020, binAddr: 0x0000000100000ED0, size: 0x00000050
|
||||
# CHECK-DAG: sym: _private_int, objAddr: 0x0000000000000560, binAddr: 0x0000000100001004, size: 0x00000000
|
||||
# CHECK-DAG: sym: _inc, objAddr: 0x0000000000000070, binAddr: 0x0000000100000F20, size: 0x00000017
|
||||
# CHECK-DAG: sym: _baz, objAddr: 0x0000000000000310, binAddr: 0x0000000100001000, size: 0x00000000
|
||||
# CHECK-NOT: { sym:
|
||||
# CHECK-NEXT: filename:{{.*}}/Inputs/./libbasic.a(basic3.macho.x86_64.o)'
|
||||
# CHECK-NEXT: symbols:
|
||||
# CHECK-DAG: sym: _val, objAddr: 0x0000000000000004, binAddr: 0x0000000100001008, size: 0x00000000
|
||||
# CHECK-DAG: sym: _bar, objAddr: 0x0000000000000020, binAddr: 0x0000000100000F40, size: 0x00000050
|
||||
# CHECK-DAG: sym: _inc, objAddr: 0x0000000000000070, binAddr: 0x0000000100000F90, size: 0x00000019
|
||||
# CHECK-NOT: { sym:
|
||||
# CHECK-NEXT: ...
|
||||
---
|
||||
triple: 'x86_64-unknown-unknown-macho'
|
||||
objects:
|
||||
- filename: /Inputs/basic1.macho.x86_64.o
|
||||
symbols:
|
||||
- { sym: _main, objAddr: 0x0, binAddr: 0x0000000100000EA0, size: 0x00000024 }
|
||||
- filename: /Inputs/./libbasic.a(basic2.macho.x86_64.o)
|
||||
symbols:
|
||||
- { sym: _foo, objAddr: 0x0, binAddr: 0x0000000100000ED0, size: 0x00000050 }
|
||||
- { sym: _private_int, objAddr: 0x0, binAddr: 0x0000000100001004, size: 0x00000000 }
|
||||
- { sym: _inc, objAddr: 0x0, binAddr: 0x0000000100000F20, size: 0x00000017 }
|
||||
- { sym: _baz, objAddr: 0x0, binAddr: 0x0000000100001000, size: 0x00000000 }
|
||||
- filename: /Inputs/./libbasic.a(basic3.macho.x86_64.o)
|
||||
symbols:
|
||||
- { sym: _val, objAddr: 0x0, binAddr: 0x0000000100001008, size: 0x00000000 }
|
||||
- { sym: _bar, objAddr: 0x0, binAddr: 0x0000000100000F40, size: 0x00000050 }
|
||||
- { sym: _inc, objAddr: 0x0, binAddr: 0x0000000100000F90, size: 0x00000019 }
|
||||
...
|
|
@ -7,6 +7,7 @@
|
|||
//
|
||||
//===----------------------------------------------------------------------===//
|
||||
#include "DebugMap.h"
|
||||
#include "BinaryHolder.h"
|
||||
#include "llvm/ADT/STLExtras.h"
|
||||
#include "llvm/ADT/iterator_range.h"
|
||||
#include "llvm/Support/DataTypes.h"
|
||||
|
@ -87,6 +88,13 @@ void DebugMap::print(raw_ostream &OS) const {
|
|||
void DebugMap::dump() const { print(errs()); }
|
||||
#endif
|
||||
|
||||
namespace {
|
||||
struct YAMLContext {
|
||||
StringRef PrependPath;
|
||||
Triple Triple;
|
||||
};
|
||||
}
|
||||
|
||||
ErrorOr<std::unique_ptr<DebugMap>>
|
||||
DebugMap::parseYAMLDebugMap(StringRef InputFile, StringRef PrependPath,
|
||||
bool Verbose) {
|
||||
|
@ -94,8 +102,12 @@ DebugMap::parseYAMLDebugMap(StringRef InputFile, StringRef PrependPath,
|
|||
if (auto Err = ErrOrFile.getError())
|
||||
return Err;
|
||||
|
||||
YAMLContext Ctxt;
|
||||
|
||||
Ctxt.PrependPath = PrependPath;
|
||||
|
||||
std::unique_ptr<DebugMap> Res;
|
||||
yaml::Input yin((*ErrOrFile)->getBuffer(), &PrependPath);
|
||||
yaml::Input yin((*ErrOrFile)->getBuffer(), &Ctxt);
|
||||
yin >> Res;
|
||||
|
||||
if (auto EC = yin.error())
|
||||
|
@ -163,6 +175,8 @@ void MappingTraits<dsymutil::DebugMap>::mapping(IO &io,
|
|||
dsymutil::DebugMap &DM) {
|
||||
io.mapRequired("triple", DM.BinaryTriple);
|
||||
io.mapOptional("objects", DM.Objects);
|
||||
if (void *Ctxt = io.getContext())
|
||||
reinterpret_cast<YAMLContext *>(Ctxt)->Triple = DM.BinaryTriple;
|
||||
}
|
||||
|
||||
void MappingTraits<std::unique_ptr<dsymutil::DebugMap>>::mapping(
|
||||
|
@ -171,6 +185,8 @@ void MappingTraits<std::unique_ptr<dsymutil::DebugMap>>::mapping(
|
|||
DM.reset(new DebugMap());
|
||||
io.mapRequired("triple", DM->BinaryTriple);
|
||||
io.mapOptional("objects", DM->Objects);
|
||||
if (void *Ctxt = io.getContext())
|
||||
reinterpret_cast<YAMLContext *>(Ctxt)->Triple = DM->BinaryTriple;
|
||||
}
|
||||
|
||||
MappingTraits<dsymutil::DebugMapObject>::YamlDMO::YamlDMO(
|
||||
|
@ -183,15 +199,39 @@ MappingTraits<dsymutil::DebugMapObject>::YamlDMO::YamlDMO(
|
|||
|
||||
dsymutil::DebugMapObject
|
||||
MappingTraits<dsymutil::DebugMapObject>::YamlDMO::denormalize(IO &IO) {
|
||||
void *Ctxt = IO.getContext();
|
||||
StringRef PrependPath = *reinterpret_cast<StringRef *>(Ctxt);
|
||||
SmallString<80> Path(PrependPath);
|
||||
BinaryHolder BinHolder(/* Verbose =*/false);
|
||||
const auto &Ctxt = *reinterpret_cast<YAMLContext *>(IO.getContext());
|
||||
SmallString<80> Path(Ctxt.PrependPath);
|
||||
StringMap<uint64_t> SymbolAddresses;
|
||||
|
||||
sys::path::append(Path, Filename);
|
||||
auto ErrOrObjectFile = BinHolder.GetObjectFile(Path);
|
||||
if (auto EC = ErrOrObjectFile.getError()) {
|
||||
llvm::errs() << "warning: Unable to open " << Path << " " << EC.message()
|
||||
<< '\n';
|
||||
} else {
|
||||
// Rewrite the object file symbol addresses in the debug map. The
|
||||
// YAML input is mainly used to test llvm-dsymutil without
|
||||
// requiring binaries checked-in. If we generate the object files
|
||||
// during the test, we can't hardcode the symbols addresses, so
|
||||
// look them up here and rewrite them.
|
||||
for (const auto &Sym : ErrOrObjectFile->symbols()) {
|
||||
StringRef Name;
|
||||
uint64_t Address;
|
||||
if (Sym.getName(Name) || Sym.getAddress(Address))
|
||||
continue;
|
||||
SymbolAddresses[Name] = Address;
|
||||
}
|
||||
}
|
||||
|
||||
dsymutil::DebugMapObject Res(Path);
|
||||
for (auto &Entry : Entries) {
|
||||
auto &Mapping = Entry.second;
|
||||
Res.addSymbol(Entry.first, Mapping.ObjectAddress, Mapping.BinaryAddress,
|
||||
Mapping.Size);
|
||||
uint64_t ObjAddress = Mapping.ObjectAddress;
|
||||
auto AddressIt = SymbolAddresses.find(Entry.first);
|
||||
if (AddressIt != SymbolAddresses.end())
|
||||
ObjAddress = AddressIt->getValue();
|
||||
Res.addSymbol(Entry.first, ObjAddress, Mapping.BinaryAddress, Mapping.Size);
|
||||
}
|
||||
return Res;
|
||||
}
|
||||
|
|
Loading…
Reference in New Issue