--- /dev/null
+# 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 }
+...
//
//===----------------------------------------------------------------------===//
#include "DebugMap.h"
+#include "BinaryHolder.h"
#include "llvm/ADT/STLExtras.h"
#include "llvm/ADT/iterator_range.h"
#include "llvm/Support/DataTypes.h"
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) {
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())
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(
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(
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;
}