[llvm] r239189 - [dsymutil] Have the YAML deserialization rewrite the object address of symbols.

Frederic Riss friss at apple.com
Fri Jun 5 14:12:07 PDT 2015


Author: friss
Date: Fri Jun  5 16:12:07 2015
New Revision: 239189

URL: http://llvm.org/viewvc/llvm-project?rev=239189&view=rev
Log:
[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.

Added:
    llvm/trunk/test/tools/dsymutil/yaml-object-address-rewrite.test
Modified:
    llvm/trunk/tools/dsymutil/DebugMap.cpp

Added: llvm/trunk/test/tools/dsymutil/yaml-object-address-rewrite.test
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/test/tools/dsymutil/yaml-object-address-rewrite.test?rev=239189&view=auto
==============================================================================
--- llvm/trunk/test/tools/dsymutil/yaml-object-address-rewrite.test (added)
+++ llvm/trunk/test/tools/dsymutil/yaml-object-address-rewrite.test Fri Jun  5 16:12:07 2015
@@ -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 }
+...

Modified: llvm/trunk/tools/dsymutil/DebugMap.cpp
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/tools/dsymutil/DebugMap.cpp?rev=239189&r1=239188&r2=239189&view=diff
==============================================================================
--- llvm/trunk/tools/dsymutil/DebugMap.cpp (original)
+++ llvm/trunk/tools/dsymutil/DebugMap.cpp Fri Jun  5 16:12:07 2015
@@ -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) co
 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 In
   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>::
                                                 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<dsymu
     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>:
 
 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;
 }





More information about the llvm-commits mailing list