<div dir="ltr">Please revert, see my comment on your review thread. The review had not concluded.</div><div class="gmail_extra"><br><div class="gmail_quote">On Tue, Dec 9, 2014 at 6:03 PM, Frederic Riss <span dir="ltr"><<a href="mailto:friss@apple.com" target="_blank">friss@apple.com</a>></span> wrote:<br><blockquote class="gmail_quote" style="margin:0 0 0 .8ex;border-left:1px #ccc solid;padding-left:1ex">Author: friss<br>
Date: Tue Dec  9 11:03:30 2014<br>
New Revision: 223793<br>
<br>
URL: <a href="http://llvm.org/viewvc/llvm-project?rev=223793&view=rev" target="_blank">http://llvm.org/viewvc/llvm-project?rev=223793&view=rev</a><br>
Log:<br>
Initial dsymutil tool commit.<br>
<br>
The goal of this tool is to replicate Darwin's dsymutil functionality<br>
based on LLVM. dsymutil is a DWARF linker. Darwin's linker (ld64) does<br>
not link the debug information, it leaves it in the object files in<br>
relocatable form, but embbeds a `debug map` into the executable that<br>
describes where to find the debug information and how to relocate it.<br>
When releasing/archiving a binary, dsymutil is called to link all the DWARF<br>
information into a `dsym bundle` that can distributed/stored along with<br>
the binary.<br>
<br>
With this commit, the LLVM based dsymutil is just able to parse the STABS<br>
debug maps embedded by ld64 in linked binaries (and not all of them, for<br>
example archives aren't supported yet).<br>
<br>
Note that the tool directory is called dsymutil, but the executable is<br>
currently called llvm-dsymutil. This discrepancy will disappear once the<br>
tool will be feature complete. At this point the executable will be renamed<br>
to dsymutil, but until then you do not want it to override the system one.<br>
<br>
    Differential Revision: <a href="http://reviews.llvm.org/D6242" target="_blank">http://reviews.llvm.org/D6242</a><br>
<br>
Added:<br>
    llvm/trunk/test/tools/dsymutil/<br>
    llvm/trunk/test/tools/dsymutil/Inputs/<br>
    llvm/trunk/test/tools/dsymutil/Inputs/basic-lto.macho.x86_64   (with props)<br>
    llvm/trunk/test/tools/dsymutil/Inputs/basic-lto.macho.x86_64.o<br>
    llvm/trunk/test/tools/dsymutil/Inputs/basic.macho.x86_64   (with props)<br>
    llvm/trunk/test/tools/dsymutil/Inputs/basic1.c<br>
    llvm/trunk/test/tools/dsymutil/Inputs/basic1.macho.x86_64.o<br>
    llvm/trunk/test/tools/dsymutil/Inputs/basic2.c<br>
    llvm/trunk/test/tools/dsymutil/Inputs/basic2.macho.x86_64.o<br>
    llvm/trunk/test/tools/dsymutil/Inputs/basic3.c<br>
    llvm/trunk/test/tools/dsymutil/Inputs/basic3.macho.x86_64.o<br>
    llvm/trunk/test/tools/dsymutil/debug-map-parsing.test<br>
    llvm/trunk/tools/dsymutil/<br>
    llvm/trunk/tools/dsymutil/CMakeLists.txt<br>
    llvm/trunk/tools/dsymutil/DebugMap.cpp<br>
    llvm/trunk/tools/dsymutil/DebugMap.h<br>
    llvm/trunk/tools/dsymutil/DwarfLinker.cpp<br>
    llvm/trunk/tools/dsymutil/DwarfLinker.h<br>
    llvm/trunk/tools/dsymutil/LLVMBuild.txt<br>
      - copied, changed from r223790, llvm/trunk/tools/LLVMBuild.txt<br>
    llvm/trunk/tools/dsymutil/MachODebugMapParser.cpp<br>
    llvm/trunk/tools/dsymutil/MachODebugMapParser.h<br>
    llvm/trunk/tools/dsymutil/Makefile<br>
    llvm/trunk/tools/dsymutil/dsymutil.cpp<br>
Modified:<br>
    llvm/trunk/tools/CMakeLists.txt<br>
    llvm/trunk/tools/LLVMBuild.txt<br>
    llvm/trunk/tools/Makefile<br>
<br>
Added: llvm/trunk/test/tools/dsymutil/Inputs/basic-lto.macho.x86_64<br>
URL: <a href="http://llvm.org/viewvc/llvm-project/llvm/trunk/test/tools/dsymutil/Inputs/basic-lto.macho.x86_64?rev=223793&view=auto" target="_blank">http://llvm.org/viewvc/llvm-project/llvm/trunk/test/tools/dsymutil/Inputs/basic-lto.macho.x86_64?rev=223793&view=auto</a><br>
==============================================================================<br>
Binary files llvm/trunk/test/tools/dsymutil/Inputs/basic-lto.macho.x86_64 (added) and llvm/trunk/test/tools/dsymutil/Inputs/basic-lto.macho.x86_64 Tue Dec  9 11:03:30 2014 differ<br>
<br>
Propchange: llvm/trunk/test/tools/dsymutil/Inputs/basic-lto.macho.x86_64<br>
------------------------------------------------------------------------------<br>
    svn:executable = *<br>
<br>
Added: llvm/trunk/test/tools/dsymutil/Inputs/basic-lto.macho.x86_64.o<br>
URL: <a href="http://llvm.org/viewvc/llvm-project/llvm/trunk/test/tools/dsymutil/Inputs/basic-lto.macho.x86_64.o?rev=223793&view=auto" target="_blank">http://llvm.org/viewvc/llvm-project/llvm/trunk/test/tools/dsymutil/Inputs/basic-lto.macho.x86_64.o?rev=223793&view=auto</a><br>
==============================================================================<br>
Binary files llvm/trunk/test/tools/dsymutil/Inputs/basic-lto.macho.x86_64.o (added) and llvm/trunk/test/tools/dsymutil/Inputs/basic-lto.macho.x86_64.o Tue Dec  9 11:03:30 2014 differ<br>
<br>
Added: llvm/trunk/test/tools/dsymutil/Inputs/basic.macho.x86_64<br>
URL: <a href="http://llvm.org/viewvc/llvm-project/llvm/trunk/test/tools/dsymutil/Inputs/basic.macho.x86_64?rev=223793&view=auto" target="_blank">http://llvm.org/viewvc/llvm-project/llvm/trunk/test/tools/dsymutil/Inputs/basic.macho.x86_64?rev=223793&view=auto</a><br>
==============================================================================<br>
Binary files llvm/trunk/test/tools/dsymutil/Inputs/basic.macho.x86_64 (added) and llvm/trunk/test/tools/dsymutil/Inputs/basic.macho.x86_64 Tue Dec  9 11:03:30 2014 differ<br>
<br>
Propchange: llvm/trunk/test/tools/dsymutil/Inputs/basic.macho.x86_64<br>
------------------------------------------------------------------------------<br>
    svn:executable = *<br>
<br>
Added: llvm/trunk/test/tools/dsymutil/Inputs/basic1.c<br>
URL: <a href="http://llvm.org/viewvc/llvm-project/llvm/trunk/test/tools/dsymutil/Inputs/basic1.c?rev=223793&view=auto" target="_blank">http://llvm.org/viewvc/llvm-project/llvm/trunk/test/tools/dsymutil/Inputs/basic1.c?rev=223793&view=auto</a><br>
==============================================================================<br>
--- llvm/trunk/test/tools/dsymutil/Inputs/basic1.c (added)<br>
+++ llvm/trunk/test/tools/dsymutil/Inputs/basic1.c Tue Dec  9 11:03:30 2014<br>
@@ -0,0 +1,25 @@<br>
+/* This is the main file used to produce the basic* objects that are<br>
+   used for the dsymutil tests.<br>
+<br>
+   These are compiled in a couple of different ways (always on a<br>
+   Darwin system):<br>
+   Basic compilation:<br>
+      for FILE in basic1.c basic2.c basic3.c; do<br>
+         clang -g -c $FILE -o ${FILE%.c}.macho.x86_64.o<br>
+      done<br>
+      clang basic1.macho.x86_64.o basic2.macho.x86_64.o basic3.macho.x86_64.o -o basic.macho.x86_64 -Wl,-dead_strip<br>
+<br>
+   LTO compilation:<br>
+      for FILE in basic1.c basic2.c basic3.c; do<br>
+         clang -g -c -flto $FILE -o ${FILE%.c}-lto.o<br>
+      done<br>
+      clang basic1-lto.o basic2-lto.o basic3-lto.o -o basic-lto.macho.x86_64 -Wl,-object_path_lto,$PWD/basic-lto.macho.x86_64.o -Wl,-dead_strip<br>
+      rm basic1-lto.o basic2-lto.o basic3-lto.o<br>
+<br>
+*/<br>
+<br>
+int foo(int);<br>
+<br>
+int main(int argc, const char *argv[]) {<br>
+  return foo(argc);<br>
+}<br>
<br>
Added: llvm/trunk/test/tools/dsymutil/Inputs/basic1.macho.x86_64.o<br>
URL: <a href="http://llvm.org/viewvc/llvm-project/llvm/trunk/test/tools/dsymutil/Inputs/basic1.macho.x86_64.o?rev=223793&view=auto" target="_blank">http://llvm.org/viewvc/llvm-project/llvm/trunk/test/tools/dsymutil/Inputs/basic1.macho.x86_64.o?rev=223793&view=auto</a><br>
==============================================================================<br>
Binary files llvm/trunk/test/tools/dsymutil/Inputs/basic1.macho.x86_64.o (added) and llvm/trunk/test/tools/dsymutil/Inputs/basic1.macho.x86_64.o Tue Dec  9 11:03:30 2014 differ<br>
<br>
Added: llvm/trunk/test/tools/dsymutil/Inputs/basic2.c<br>
URL: <a href="http://llvm.org/viewvc/llvm-project/llvm/trunk/test/tools/dsymutil/Inputs/basic2.c?rev=223793&view=auto" target="_blank">http://llvm.org/viewvc/llvm-project/llvm/trunk/test/tools/dsymutil/Inputs/basic2.c?rev=223793&view=auto</a><br>
==============================================================================<br>
--- llvm/trunk/test/tools/dsymutil/Inputs/basic2.c (added)<br>
+++ llvm/trunk/test/tools/dsymutil/Inputs/basic2.c Tue Dec  9 11:03:30 2014<br>
@@ -0,0 +1,22 @@<br>
+/* For compilation instructions see basic1.c. */<br>
+<br>
+static int baz = 42;<br>
+static int private_int;<br>
+extern volatile int val;<br>
+int unused_data = 1;<br>
+<br>
+int bar(int);<br>
+<br>
+void unused1() {<br>
+  bar(baz);<br>
+}<br>
+<br>
+static int inc() {<br>
+  return ++private_int;<br>
+}<br>
+<br>
+__attribute__((noinline))<br>
+int foo(int arg) {<br>
+  return bar(arg+val) + inc() + baz++;<br>
+}<br>
+<br>
<br>
Added: llvm/trunk/test/tools/dsymutil/Inputs/basic2.macho.x86_64.o<br>
URL: <a href="http://llvm.org/viewvc/llvm-project/llvm/trunk/test/tools/dsymutil/Inputs/basic2.macho.x86_64.o?rev=223793&view=auto" target="_blank">http://llvm.org/viewvc/llvm-project/llvm/trunk/test/tools/dsymutil/Inputs/basic2.macho.x86_64.o?rev=223793&view=auto</a><br>
==============================================================================<br>
Binary files llvm/trunk/test/tools/dsymutil/Inputs/basic2.macho.x86_64.o (added) and llvm/trunk/test/tools/dsymutil/Inputs/basic2.macho.x86_64.o Tue Dec  9 11:03:30 2014 differ<br>
<br>
Added: llvm/trunk/test/tools/dsymutil/Inputs/basic3.c<br>
URL: <a href="http://llvm.org/viewvc/llvm-project/llvm/trunk/test/tools/dsymutil/Inputs/basic3.c?rev=223793&view=auto" target="_blank">http://llvm.org/viewvc/llvm-project/llvm/trunk/test/tools/dsymutil/Inputs/basic3.c?rev=223793&view=auto</a><br>
==============================================================================<br>
--- llvm/trunk/test/tools/dsymutil/Inputs/basic3.c (added)<br>
+++ llvm/trunk/test/tools/dsymutil/Inputs/basic3.c Tue Dec  9 11:03:30 2014<br>
@@ -0,0 +1,20 @@<br>
+/* For compilation instructions see basic1.c. */<br>
+<br>
+volatile int val;<br>
+<br>
+extern int foo(int);<br>
+<br>
+int unused2() {<br>
+  return foo(val);<br>
+}<br>
+<br>
+static int inc() {<br>
+  return ++val;<br>
+}<br>
+<br>
+__attribute__((noinline))<br>
+int bar(int arg) {<br>
+  if (arg > 42)<br>
+    return inc();<br>
+  return foo(val + arg);<br>
+}<br>
<br>
Added: llvm/trunk/test/tools/dsymutil/Inputs/basic3.macho.x86_64.o<br>
URL: <a href="http://llvm.org/viewvc/llvm-project/llvm/trunk/test/tools/dsymutil/Inputs/basic3.macho.x86_64.o?rev=223793&view=auto" target="_blank">http://llvm.org/viewvc/llvm-project/llvm/trunk/test/tools/dsymutil/Inputs/basic3.macho.x86_64.o?rev=223793&view=auto</a><br>
==============================================================================<br>
Binary files llvm/trunk/test/tools/dsymutil/Inputs/basic3.macho.x86_64.o (added) and llvm/trunk/test/tools/dsymutil/Inputs/basic3.macho.x86_64.o Tue Dec  9 11:03:30 2014 differ<br>
<br>
Added: llvm/trunk/test/tools/dsymutil/debug-map-parsing.test<br>
URL: <a href="http://llvm.org/viewvc/llvm-project/llvm/trunk/test/tools/dsymutil/debug-map-parsing.test?rev=223793&view=auto" target="_blank">http://llvm.org/viewvc/llvm-project/llvm/trunk/test/tools/dsymutil/debug-map-parsing.test?rev=223793&view=auto</a><br>
==============================================================================<br>
--- llvm/trunk/test/tools/dsymutil/debug-map-parsing.test (added)<br>
+++ llvm/trunk/test/tools/dsymutil/debug-map-parsing.test Tue Dec  9 11:03:30 2014<br>
@@ -0,0 +1,48 @@<br>
+RUN: llvm-dsymutil -v -parse-only -oso-prepend-path=%p %p/Inputs/basic.macho.x86_64 | FileCheck %s<br>
+RUN: llvm-dsymutil -v -parse-only -oso-prepend-path=%p %p/Inputs/basic-lto.macho.x86_64 | FileCheck %s --check-prefix=CHECK-LTO<br>
+RUN: llvm-dsymutil -v -parse-only %p/Inputs/basic.macho.x86_64 2>&1 | FileCheck %s --check-prefix=NOT-FOUND<br>
+RUN: not llvm-dsymutil -v -parse-only %p/Inputs/inexistant 2>&1 | FileCheck %s --check-prefix=NO-EXECUTABLE<br>
+Check that We can parse the debug map of the basic executable.<br>
+<br>
+CHECK-NOT: error<br>
+CHECK: DEBUG MAP:<br>
+CHECK: /Inputs/basic1.macho.x86_64.o:<br>
+CHECK:         0000000000000000 => 0000000100000ea0    _main<br>
+CHECK: /Inputs/basic2.macho.x86_64.o:<br>
+CHECK:         0000000000000310 => 0000000100001000    _baz<br>
+CHECK:         0000000000000020 => 0000000100000ed0    _foo<br>
+CHECK:         0000000000000070 => 0000000100000f20    _inc<br>
+CHECK:         0000000000000560 => 0000000100001008    _private_int<br>
+CHECK: /Inputs/basic3.macho.x86_64.o:<br>
+CHECK:         0000000000000020 => 0000000100000f40    _bar<br>
+CHECK:         0000000000000070 => 0000000100000f90    _inc<br>
+CHECK:         0000000000000004 => 0000000100001004    _val<br>
+CHECK: END DEBUG MAP<br>
+<br>
+<br>
+Check that we can parse the debug-map of the basic-lto executable<br>
+<br>
+CHECK-LTO-NOT: error<br>
+CHECK-LTO: DEBUG MAP:<br>
+CHECK-LTO: /Inputs/basic-lto.macho.x86_64.o:<br>
+CHECK-LTO:     0000000000000050 => 0000000100000f90    _bar<br>
+CHECK-LTO:     0000000000000658 => 0000000100001000    _baz<br>
+CHECK-LTO:     0000000000000010 => 0000000100000f50    _foo<br>
+CHECK-LTO:     0000000000000000 => 0000000100000f40    _main<br>
+CHECK-LTO:     00000000000008e8 => 0000000100001008    _private_int<br>
+CHECK-LTO:     00000000000008ec => 0000000100001004    _val<br>
+CHECK-LTO: END DEBUG MAP<br>
+<br>
+Check that we warn about missing object files (this presumes that the files aren't<br>
+present in the machine's /Inputs/ folder, which should be a pretty safe bet).<br>
+<br>
+NOT-FOUND: cannot open{{.*}}"/Inputs/basic1.macho.x86_64.o": No such file<br>
+NOT-FOUND: cannot open{{.*}}"/Inputs/basic2.macho.x86_64.o": No such file<br>
+NOT-FOUND: cannot open{{.*}}"/Inputs/basic3.macho.x86_64.o": No such file<br>
+NOT-FOUND: DEBUG MAP:<br>
+NOT-FOUND-NEXT: END DEBUG MAP<br>
+<br>
+Check that we correctly error out on invalid executatble.<br>
+<br>
+NO-EXECUTABLE: cannot parse{{.*}}/inexistant": No such file<br>
+NO-EXECUTABLE-NOT: DEBUG MAP<br>
<br>
Modified: llvm/trunk/tools/CMakeLists.txt<br>
URL: <a href="http://llvm.org/viewvc/llvm-project/llvm/trunk/tools/CMakeLists.txt?rev=223793&r1=223792&r2=223793&view=diff" target="_blank">http://llvm.org/viewvc/llvm-project/llvm/trunk/tools/CMakeLists.txt?rev=223793&r1=223792&r2=223793&view=diff</a><br>
==============================================================================<br>
--- llvm/trunk/tools/CMakeLists.txt (original)<br>
+++ llvm/trunk/tools/CMakeLists.txt Tue Dec  9 11:03:30 2014<br>
@@ -36,6 +36,7 @@ add_llvm_tool_subdirectory(llvm-objdump)<br>
 add_llvm_tool_subdirectory(llvm-readobj)<br>
 add_llvm_tool_subdirectory(llvm-rtdyld)<br>
 add_llvm_tool_subdirectory(llvm-dwarfdump)<br>
+add_llvm_tool_subdirectory(dsymutil)<br>
 add_llvm_tool_subdirectory(llvm-vtabledump)<br>
 if( LLVM_USE_INTEL_JITEVENTS )<br>
   add_llvm_tool_subdirectory(llvm-jitlistener)<br>
<br>
Modified: llvm/trunk/tools/LLVMBuild.txt<br>
URL: <a href="http://llvm.org/viewvc/llvm-project/llvm/trunk/tools/LLVMBuild.txt?rev=223793&r1=223792&r2=223793&view=diff" target="_blank">http://llvm.org/viewvc/llvm-project/llvm/trunk/tools/LLVMBuild.txt?rev=223793&r1=223792&r2=223793&view=diff</a><br>
==============================================================================<br>
--- llvm/trunk/tools/LLVMBuild.txt (original)<br>
+++ llvm/trunk/tools/LLVMBuild.txt Tue Dec  9 11:03:30 2014<br>
@@ -16,7 +16,7 @@<br>
 ;===------------------------------------------------------------------------===;<br>
<br>
 [common]<br>
-subdirectories = bugpoint llc lli llvm-ar llvm-as llvm-bcanalyzer llvm-cov llvm-diff llvm-dis llvm-dwarfdump llvm-extract llvm-jitlistener llvm-link llvm-lto llvm-mc llvm-nm llvm-objdump llvm-profdata llvm-rtdyld llvm-size macho-dump opt llvm-mcmarkup verify-uselistorder<br>
+subdirectories = bugpoint llc lli llvm-ar llvm-as llvm-bcanalyzer llvm-cov llvm-diff llvm-dis llvm-dwarfdump llvm-extract llvm-jitlistener llvm-link llvm-lto llvm-mc llvm-nm llvm-objdump llvm-profdata llvm-rtdyld llvm-size macho-dump opt llvm-mcmarkup verify-uselistorder dsymutil<br>
<br>
 [component_0]<br>
 type = Group<br>
<br>
Modified: llvm/trunk/tools/Makefile<br>
URL: <a href="http://llvm.org/viewvc/llvm-project/llvm/trunk/tools/Makefile?rev=223793&r1=223792&r2=223793&view=diff" target="_blank">http://llvm.org/viewvc/llvm-project/llvm/trunk/tools/Makefile?rev=223793&r1=223792&r2=223793&view=diff</a><br>
==============================================================================<br>
--- llvm/trunk/tools/Makefile (original)<br>
+++ llvm/trunk/tools/Makefile Tue Dec  9 11:03:30 2014<br>
@@ -33,7 +33,7 @@ PARALLEL_DIRS := opt llvm-as llvm-dis ll<br>
                  macho-dump llvm-objdump llvm-readobj llvm-rtdyld \<br>
                  llvm-dwarfdump llvm-cov llvm-size llvm-stress llvm-mcmarkup \<br>
                  llvm-profdata llvm-symbolizer obj2yaml yaml2obj llvm-c-test \<br>
-                 llvm-vtabledump verify-uselistorder<br>
+                 llvm-vtabledump verify-uselistorder dsymutil<br>
<br>
 # If Intel JIT Events support is configured, build an extra tool to test it.<br>
 ifeq ($(USE_INTEL_JITEVENTS), 1)<br>
<br>
Added: llvm/trunk/tools/dsymutil/CMakeLists.txt<br>
URL: <a href="http://llvm.org/viewvc/llvm-project/llvm/trunk/tools/dsymutil/CMakeLists.txt?rev=223793&view=auto" target="_blank">http://llvm.org/viewvc/llvm-project/llvm/trunk/tools/dsymutil/CMakeLists.txt?rev=223793&view=auto</a><br>
==============================================================================<br>
--- llvm/trunk/tools/dsymutil/CMakeLists.txt (added)<br>
+++ llvm/trunk/tools/dsymutil/CMakeLists.txt Tue Dec  9 11:03:30 2014<br>
@@ -0,0 +1,12 @@<br>
+set(LLVM_LINK_COMPONENTS<br>
+  Object<br>
+  Support<br>
+  )<br>
+<br>
+add_llvm_tool(llvm-dsymutil<br>
+  dsymutil.cpp<br>
+  DebugMap.cpp<br>
+  DwarfLinker.cpp<br>
+  MachODebugMapParser.cpp<br>
+  )<br>
+<br>
<br>
Added: llvm/trunk/tools/dsymutil/DebugMap.cpp<br>
URL: <a href="http://llvm.org/viewvc/llvm-project/llvm/trunk/tools/dsymutil/DebugMap.cpp?rev=223793&view=auto" target="_blank">http://llvm.org/viewvc/llvm-project/llvm/trunk/tools/dsymutil/DebugMap.cpp?rev=223793&view=auto</a><br>
==============================================================================<br>
--- llvm/trunk/tools/dsymutil/DebugMap.cpp (added)<br>
+++ llvm/trunk/tools/dsymutil/DebugMap.cpp Tue Dec  9 11:03:30 2014<br>
@@ -0,0 +1,84 @@<br>
+//===- tools/dsymutil/DebugMap.cpp - Generic debug map representation -----===//<br>
+//<br>
+//                             The LLVM Linker<br>
+//<br>
+// This file is distributed under the University of Illinois Open Source<br>
+// License. See LICENSE.TXT for details.<br>
+//<br>
+//===----------------------------------------------------------------------===//<br>
+#include "DebugMap.h"<br>
+<br>
+#include "llvm/ADT/STLExtras.h"<br>
+#include "llvm/Support/DataTypes.h"<br>
+#include "llvm/Support/Format.h"<br>
+#include "llvm/Support/raw_ostream.h"<br>
+#include <algorithm><br>
+<br>
+namespace llvm {<br>
+<br>
+using namespace llvm::object;<br>
+<br>
+DebugMapObject::DebugMapObject(StringRef ObjectFilename)<br>
+  : Filename(ObjectFilename) {}<br>
+<br>
+bool DebugMapObject::addSymbol(StringRef Name, uint64_t ObjectAddress,<br>
+                               uint64_t LinkedAddress) {<br>
+  auto InsertResult = Symbols.insert(std::make_pair(Name,<br>
+                                                    SymbolMapping{ObjectAddress,<br>
+                                                                  LinkedAddress}));<br>
+  return InsertResult.second;<br>
+}<br>
+<br>
+void DebugMapObject::print(raw_ostream& OS) const {<br>
+  OS << getObjectFilename() << ":\n";<br>
+  // Sort the symbols in alphabetical order, like llvm-nm (and to get<br>
+  // deterministic output for testing).<br>
+  typedef StringMapEntry<SymbolMapping> MapEntryTy;<br>
+  std::vector<const MapEntryTy *> Entries;<br>
+  Entries.reserve(Symbols.getNumItems());<br>
+  for (auto SymIt = Symbols.begin(), End = Symbols.end(); SymIt != End; ++SymIt)<br>
+    Entries.push_back(&*SymIt);<br>
+  std::sort(Entries.begin(), Entries.end(),<br>
+            [] (const MapEntryTy *LHS, const MapEntryTy *RHS) {<br>
+              return LHS->getKey() < RHS->getKey();<br>
+            });<br>
+  for (const auto *Entry: Entries) {<br>
+    const auto &Sym = Entry->getValue();<br>
+    OS << format("\t%016" PRIx64 " => %016" PRIx64 "\t%s\n",<br>
+                     Sym.ObjectAddress, Sym.BinaryAddress, Entry->getKeyData());<br>
+  }<br>
+  OS << '\n';<br>
+}<br>
+<br>
+#ifndef NDEBUG<br>
+void DebugMapObject::dump() const {<br>
+  print(errs());<br>
+}<br>
+#endif<br>
+<br>
+DebugMapObject& DebugMap::addDebugMapObject(StringRef ObjectFilePath) {<br>
+  Objects.emplace_back(new DebugMapObject(ObjectFilePath));<br>
+  return *Objects.back();<br>
+}<br>
+<br>
+const DebugMapObject::SymbolMapping *<br>
+DebugMapObject::lookupSymbol(StringRef SymbolName) const {<br>
+  StringMap<SymbolMapping>::const_iterator Sym = Symbols.find(SymbolName);<br>
+  if (Sym == Symbols.end())<br>
+    return nullptr;<br>
+  return &Sym->getValue();<br>
+}<br>
+<br>
+void DebugMap::print(raw_ostream& OS) const {<br>
+  OS << "DEBUG MAP:   object addr =>  executable addr\tsymbol name\n";<br>
+  for (const auto &Obj: objects())<br>
+    Obj->print(OS);<br>
+  OS << "END DEBUG MAP\n";<br>
+}<br>
+<br>
+#ifndef NDEBUG<br>
+void DebugMap::dump() const {<br>
+  print(errs());<br>
+}<br>
+#endif<br>
+}<br>
<br>
Added: llvm/trunk/tools/dsymutil/DebugMap.h<br>
URL: <a href="http://llvm.org/viewvc/llvm-project/llvm/trunk/tools/dsymutil/DebugMap.h?rev=223793&view=auto" target="_blank">http://llvm.org/viewvc/llvm-project/llvm/trunk/tools/dsymutil/DebugMap.h?rev=223793&view=auto</a><br>
==============================================================================<br>
--- llvm/trunk/tools/dsymutil/DebugMap.h (added)<br>
+++ llvm/trunk/tools/dsymutil/DebugMap.h Tue Dec  9 11:03:30 2014<br>
@@ -0,0 +1,131 @@<br>
+//===- tools/dsymutil/DebugMap.h - Generic debug map representation -------===//<br>
+//<br>
+//                             The LLVM Linker<br>
+//<br>
+// This file is distributed under the University of Illinois Open Source<br>
+// License. See LICENSE.TXT for details.<br>
+//<br>
+//===----------------------------------------------------------------------===//<br>
+///<br>
+/// \file<br>
+///<br>
+/// This file contains the class declaration of the DebugMap<br>
+/// entity. A DebugMap lists all the object files linked together to<br>
+/// produce an executable along with the linked address of all the<br>
+/// atoms used in these object files.<br>
+/// The DebugMap is an input to the DwarfLinker class that will<br>
+/// extract the Dwarf debug information from the referenced object<br>
+/// files and link their usefull debug info together.<br>
+///<br>
+//===----------------------------------------------------------------------===//<br>
+#ifndef DSYMUTIL_DEBUGMAP_H<br>
+#define DSYMUTIL_DEBUGMAP_H<br>
+<br>
+#include "llvm/ADT/StringMap.h"<br>
+#include "llvm/Object/ObjectFile.h"<br>
+#include "llvm/Support/ErrorOr.h"<br>
+#include "llvm/Support/Format.h"<br>
+#include "llvm/ADT/iterator_range.h"<br>
+#include <vector><br>
+<br>
+namespace llvm {<br>
+<br>
+class raw_ostream;<br>
+<br>
+class DebugMapObject;<br>
+<br>
+/// \brief The DebugMap object stores the list of object files to<br>
+/// query for debug information along with the mapping between the<br>
+/// symbols' addresses in the object file to their linked address in<br>
+/// the linked binary.<br>
+///<br>
+/// A DebugMap producer could look like this:<br>
+/// DebugMap *DM = new DebugMap();<br>
+/// for (const auto &Obj: LinkedObjects) {<br>
+///     DebugMapObject &DMO = DM->addDebugMapObject(Obj.getPath());<br>
+///     for (const auto &Sym: Obj.getLinkedSymbols())<br>
+///         DMO.addSymbol(Sym.getName(), Sym.getObjectFileAddress(),<br>
+///                       Sym.getBinaryAddress());<br>
+/// }<br>
+///<br>
+/// A DebugMap consumer can then use the map to link the debug<br>
+/// information. For example something along the lines of:<br>
+/// for (const auto &DMO: DM->objects()) {<br>
+///     auto Obj = createBinary(DMO.getObjectFilename());<br>
+///     for (auto &DIE: Obj.getDwarfDIEs()) {<br>
+///         if (SymbolMapping *Sym = DMO.lookup(DIE.getName()))<br>
+///             DIE.relocate(Sym->ObjectAddress, Sym->BinaryAddress);<br>
+///         else<br>
+///             DIE.discardSubtree();<br>
+///     }<br>
+/// }<br>
+class DebugMap<br>
+{<br>
+  typedef std::vector<std::unique_ptr<DebugMapObject>> ObjectContainer;<br>
+  ObjectContainer Objects;<br>
+<br>
+public:<br>
+  typedef ObjectContainer::const_iterator const_iterator;<br>
+<br>
+  iterator_range<const_iterator> objects() const {<br>
+    return make_range(begin(), end());<br>
+  }<br>
+<br>
+  const_iterator begin() const {<br>
+    return Objects.begin();<br>
+  }<br>
+<br>
+  const_iterator end() const {<br>
+    return Objects.end();<br>
+  }<br>
+<br>
+  /// This function adds an DebugMapObject to the list owned by this<br>
+  /// debug map.<br>
+  DebugMapObject& addDebugMapObject(StringRef ObjectFilePath);<br>
+<br>
+  void print(raw_ostream& OS) const;<br>
+<br>
+#ifndef NDEBUG<br>
+  void dump() const;<br>
+#endif<br>
+};<br>
+<br>
+/// \brief The DebugMapObject represents one object file described by<br>
+/// the DebugMap. It contains a list of mappings between addresses in<br>
+/// the object file and in the linked binary for all the linked atoms<br>
+/// in this object file.<br>
+class DebugMapObject {<br>
+public:<br>
+  struct SymbolMapping {<br>
+    uint64_t ObjectAddress;<br>
+    uint64_t BinaryAddress;<br>
+  };<br>
+<br>
+  /// \brief Adds a symbol mapping to this DebugMapObject.<br>
+  /// \returns false if the symbol was already registered. The request<br>
+  /// is discarded in this case.<br>
+  bool addSymbol(llvm::StringRef SymName, uint64_t ObjectAddress,<br>
+                 uint64_t LinkedAddress);<br>
+<br>
+  /// \bried Lookup a symbol mapping.<br>
+  /// \returns null if the symbol isn't found.<br>
+  const SymbolMapping *lookupSymbol(StringRef SymbolName) const;<br>
+<br>
+  llvm::StringRef getObjectFilename() const { return Filename; }<br>
+<br>
+  void print(raw_ostream& OS) const;<br>
+#ifndef NDEBUG<br>
+  void dump() const;<br>
+#endif<br>
+private:<br>
+  friend class DebugMap;<br>
+  /// DebugMapObjects can only be constructed by the owning DebugMap.<br>
+  DebugMapObject(StringRef ObjectFilename);<br>
+<br>
+  std::string Filename;<br>
+  StringMap<SymbolMapping> Symbols;<br>
+};<br>
+<br>
+}<br>
+<br>
+#endif // DSYMUTIL_DEBUGMAP_H<br>
<br>
Added: llvm/trunk/tools/dsymutil/DwarfLinker.cpp<br>
URL: <a href="http://llvm.org/viewvc/llvm-project/llvm/trunk/tools/dsymutil/DwarfLinker.cpp?rev=223793&view=auto" target="_blank">http://llvm.org/viewvc/llvm-project/llvm/trunk/tools/dsymutil/DwarfLinker.cpp?rev=223793&view=auto</a><br>
==============================================================================<br>
--- llvm/trunk/tools/dsymutil/DwarfLinker.cpp (added)<br>
+++ llvm/trunk/tools/dsymutil/DwarfLinker.cpp Tue Dec  9 11:03:30 2014<br>
@@ -0,0 +1,22 @@<br>
+//===- tools/dsymutil/DwarfLinker.cpp - Dwarf debug info linker -----------===//<br>
+//<br>
+//                             The LLVM Linker<br>
+//<br>
+// This file is distributed under the University of Illinois Open Source<br>
+// License. See LICENSE.TXT for details.<br>
+//<br>
+//===----------------------------------------------------------------------===//<br>
+#include "DwarfLinker.h"<br>
+#include "DebugMap.h"<br>
+<br>
+namespace llvm {<br>
+<br>
+DwarfLinker::DwarfLinker(StringRef OutputFilename)<br>
+  : OutputFilename(OutputFilename)<br>
+{}<br>
+<br>
+bool DwarfLinker::link(const DebugMap &Map) {<br>
+  return true;<br>
+}<br>
+<br>
+}<br>
<br>
Added: llvm/trunk/tools/dsymutil/DwarfLinker.h<br>
URL: <a href="http://llvm.org/viewvc/llvm-project/llvm/trunk/tools/dsymutil/DwarfLinker.h?rev=223793&view=auto" target="_blank">http://llvm.org/viewvc/llvm-project/llvm/trunk/tools/dsymutil/DwarfLinker.h?rev=223793&view=auto</a><br>
==============================================================================<br>
--- llvm/trunk/tools/dsymutil/DwarfLinker.h (added)<br>
+++ llvm/trunk/tools/dsymutil/DwarfLinker.h Tue Dec  9 11:03:30 2014<br>
@@ -0,0 +1,40 @@<br>
+//===- tools/dsymutil/DwarfLinker.h - Dwarf debug info linker -------------===//<br>
+//<br>
+//                             The LLVM Linker<br>
+//<br>
+// This file is distributed under the University of Illinois Open Source<br>
+// License. See LICENSE.TXT for details.<br>
+//<br>
+//===----------------------------------------------------------------------===//<br>
+///<br>
+/// \file<br>
+///<br>
+/// This file contains the class declaration of the DwarfLinker<br>
+/// object. A DwarfLinker takes a DebugMap as input and links the<br>
+/// debug information of all the referenced object files together. It<br>
+/// may drop and rewrite some parts of the debug info tree in the<br>
+/// process.<br>
+///<br>
+//===----------------------------------------------------------------------===//<br>
+#ifndef DSYMUTIL_DWARFLINKER_H<br>
+#define DSYMUTIL_DWARFLINKER_H<br>
+<br>
+#include "llvm/ADT/StringRef.h"<br>
+<br>
+namespace llvm {<br>
+<br>
+class DebugMap;<br>
+<br>
+class DwarfLinker {<br>
+  std::string OutputFilename;<br>
+public:<br>
+  DwarfLinker(StringRef OutputFilename);<br>
+<br>
+  /// \brief Link the passed debug map into the ouptut file.<br>
+  /// \returns false if the link encountered a fatal error.<br>
+  bool link(const DebugMap&);<br>
+};<br>
+<br>
+}<br>
+<br>
+#endif<br>
<br>
Copied: llvm/trunk/tools/dsymutil/LLVMBuild.txt (from r223790, llvm/trunk/tools/LLVMBuild.txt)<br>
URL: <a href="http://llvm.org/viewvc/llvm-project/llvm/trunk/tools/dsymutil/LLVMBuild.txt?p2=llvm/trunk/tools/dsymutil/LLVMBuild.txt&p1=llvm/trunk/tools/LLVMBuild.txt&r1=223790&r2=223793&rev=223793&view=diff" target="_blank">http://llvm.org/viewvc/llvm-project/llvm/trunk/tools/dsymutil/LLVMBuild.txt?p2=llvm/trunk/tools/dsymutil/LLVMBuild.txt&p1=llvm/trunk/tools/LLVMBuild.txt&r1=223790&r2=223793&rev=223793&view=diff</a><br>
==============================================================================<br>
--- llvm/trunk/tools/LLVMBuild.txt (original)<br>
+++ llvm/trunk/tools/dsymutil/LLVMBuild.txt Tue Dec  9 11:03:30 2014<br>
@@ -1,4 +1,4 @@<br>
-;===- ./tools/LLVMBuild.txt ------------------------------------*- Conf -*--===;<br>
+;===- ./tools/dsymutil/LLVMBuild.txt ---------------------*- Conf -*--===;<br>
 ;<br>
 ;                     The LLVM Compiler Infrastructure<br>
 ;<br>
@@ -15,10 +15,8 @@<br>
 ;<br>
 ;===------------------------------------------------------------------------===;<br>
<br>
-[common]<br>
-subdirectories = bugpoint llc lli llvm-ar llvm-as llvm-bcanalyzer llvm-cov llvm-diff llvm-dis llvm-dwarfdump llvm-extract llvm-jitlistener llvm-link llvm-lto llvm-mc llvm-nm llvm-objdump llvm-profdata llvm-rtdyld llvm-size macho-dump opt llvm-mcmarkup verify-uselistorder<br>
-<br>
 [component_0]<br>
-type = Group<br>
-name = Tools<br>
-parent = $ROOT<br>
+type = Tool<br>
+name = dsymutil<br>
+parent = Tools<br>
+required_libraries = Object Support<br>
<br>
Added: llvm/trunk/tools/dsymutil/MachODebugMapParser.cpp<br>
URL: <a href="http://llvm.org/viewvc/llvm-project/llvm/trunk/tools/dsymutil/MachODebugMapParser.cpp?rev=223793&view=auto" target="_blank">http://llvm.org/viewvc/llvm-project/llvm/trunk/tools/dsymutil/MachODebugMapParser.cpp?rev=223793&view=auto</a><br>
==============================================================================<br>
--- llvm/trunk/tools/dsymutil/MachODebugMapParser.cpp (added)<br>
+++ llvm/trunk/tools/dsymutil/MachODebugMapParser.cpp Tue Dec  9 11:03:30 2014<br>
@@ -0,0 +1,194 @@<br>
+//===- tools/dsymutil/MachODebugMapParser.cpp - Parse STABS debug maps ----===//<br>
+//<br>
+//                             The LLVM Linker<br>
+//<br>
+// This file is distributed under the University of Illinois Open Source<br>
+// License. See LICENSE.TXT for details.<br>
+//<br>
+//===----------------------------------------------------------------------===//<br>
+<br>
+#include "MachODebugMapParser.h"<br>
+#include "llvm/Support/Path.h"<br>
+#include "llvm/Support/raw_ostream.h"<br>
+<br>
+using namespace llvm::object;<br>
+<br>
+namespace llvm {<br>
+<br>
+static void Warning(const Twine &Msg) { errs() << "warning: " + Msg + "\n"; }<br>
+<br>
+static ErrorOr<OwningBinary<MachOObjectFile>> createMachOBinary(StringRef file) {<br>
+  ErrorOr<OwningBinary<Binary>> BinaryOrErr = createBinary(file);<br>
+  if (BinaryOrErr.getError())<br>
+    return BinaryOrErr.getError();<br>
+<br>
+  std::unique_ptr<Binary> Bin;<br>
+  std::unique_ptr<MemoryBuffer> Buf;<br>
+  std::tie(Bin, Buf) = BinaryOrErr->takeBinary();<br>
+  if (!isa<MachOObjectFile>(Bin.get()))<br>
+    return make_error_code(object_error::invalid_file_type);<br>
+<br>
+  std::unique_ptr<MachOObjectFile> MachOFile(cast<MachOObjectFile>(Bin.release()));<br>
+  return OwningBinary<MachOObjectFile>(std::move(MachOFile), std::move(Buf));<br>
+}<br>
+<br>
+/// Reset the parser state coresponding to the current object<br>
+/// file. This is to be called after an object file is finished<br>
+/// processing.<br>
+void MachODebugMapParser::resetParserState() {<br>
+  CurrentObjectFile = OwningBinary<object::MachOObjectFile>();<br>
+  CurrentObjectAddresses.clear();<br>
+  CurrentDebugMapObject = nullptr;<br>
+}<br>
+<br>
+/// Create a new DebugMapObject. This function resets the state of the<br>
+/// parser that was referring to the last object file and sets<br>
+/// everything up to add symbols to the new one.<br>
+void MachODebugMapParser::switchToNewDebugMapObject(StringRef Filename) {<br>
+  resetParserState();<br>
+<br>
+  std::string Path = Filename;<br>
+  if (!PathPrefix.empty())<br>
+    Path = PathPrefix + sys::path::get_separator().data() + Path;<br>
+<br>
+  auto MachOOrError = createMachOBinary(Path);<br>
+  if (auto Error = MachOOrError.getError()) {<br>
+    Warning(Twine("cannot open debug object \"") + Path + "\": "<br>
+            + Error.message() + "\n");<br>
+    return;<br>
+  }<br>
+<br>
+  CurrentObjectFile = std::move(*MachOOrError);<br>
+  loadCurrentObjectFileSymbols();<br>
+  CurrentDebugMapObject = &Result->addDebugMapObject(Path);<br>
+}<br>
+<br>
+/// This main parsing routine tries to open the main binary and if<br>
+/// successful iterates over the STAB entries. The real parsing is<br>
+/// done in handleStabSymbolTableEntry.<br>
+ErrorOr<std::unique_ptr<DebugMap>> MachODebugMapParser::parse() {<br>
+  auto MainBinaryOrError = createMachOBinary(BinaryPath);<br>
+  if (MainBinaryOrError.getError())<br>
+    return MainBinaryOrError.getError();<br>
+<br>
+  MainOwningBinary = std::move(*MainBinaryOrError);<br>
+  Result = make_unique<DebugMap>();<br>
+  const auto &MainBinary = *MainOwningBinary.getBinary();<br>
+  for (const SymbolRef &Symbol : MainBinary.symbols()) {<br>
+    const DataRefImpl &DRI = Symbol.getRawDataRefImpl();<br>
+    if (MainBinary.is64Bit())<br>
+      handleStabDebugMapEntry(MainBinary.getSymbol64TableEntry(DRI));<br>
+    else<br>
+      handleStabDebugMapEntry(MainBinary.getSymbolTableEntry(DRI));<br>
+  }<br>
+<br>
+  resetParserState();<br>
+  return std::move(Result);<br>
+}<br>
+<br>
+/// Interpret the STAB entries to fill the DebugMap.<br>
+void MachODebugMapParser::handleStabSymbolTableEntry(uint32_t StringIndex,<br>
+                                                     uint8_t Type,<br>
+                                                     uint8_t SectionIndex,<br>
+                                                     uint16_t Flags,<br>
+                                                     uint64_t Value) {<br>
+  if (!(Type & MachO::N_STAB))<br>
+    return;<br>
+<br>
+  const MachOObjectFile &MachOBinary = *MainOwningBinary.getBinary();<br>
+  const char *Name = &MachOBinary.getStringTableData().data()[StringIndex];<br>
+<br>
+  // An N_OSO entry represents the start of a new object file description.<br>
+  if (Type == MachO::N_OSO)<br>
+    return switchToNewDebugMapObject(Name);<br>
+<br>
+  // If the last N_OSO object file wasn't found,<br>
+  // CurrentDebugMapObject will be null. Do not update anything<br>
+  // until we find the next valid N_OSO entry.<br>
+  if (!CurrentDebugMapObject)<br>
+    return;<br>
+<br>
+  switch (Type) {<br>
+  case MachO::N_GSYM:<br>
+    // This is a global variable. We need to query the main binary<br>
+    // symbol table to find its address as it might not be in the<br>
+    // debug map (for common symbols).<br>
+    Value = getMainBinarySymbolAddress(Name);<br>
+    if (Value == UnknownAddressOrSize)<br>
+      return;<br>
+    break;<br>
+  case MachO::N_FUN:<br>
+    // Functions are scopes in STABS. They have an end marker that we<br>
+    // need to ignore.<br>
+    if (Name[0] == '\0')<br>
+      return;<br>
+    break;<br>
+  case MachO::N_STSYM:<br>
+    break;<br>
+  default:<br>
+    return;<br>
+  }<br>
+<br>
+  auto ObjectSymIt = CurrentObjectAddresses.find(Name);<br>
+  if (ObjectSymIt == CurrentObjectAddresses.end())<br>
+    return Warning("could not find object file symbol for symbol " +<br>
+                   Twine(Name));<br>
+  if (!CurrentDebugMapObject->addSymbol(Name, ObjectSymIt->getValue(), Value))<br>
+    return Warning(Twine("failed to insert symbol '") + Name + "' in the debug map.");<br>
+}<br>
+<br>
+/// Load the current object file symbols into CurrentObjectAddresses.<br>
+void MachODebugMapParser::loadCurrentObjectFileSymbols() {<br>
+  CurrentObjectAddresses.clear();<br>
+  const auto &Binary = *CurrentObjectFile.getBinary();<br>
+<br>
+  for (auto Sym : Binary.symbols()) {<br>
+    StringRef Name;<br>
+    uint64_t Addr;<br>
+    if (Sym.getAddress(Addr) || Addr == UnknownAddressOrSize ||<br>
+        Sym.getName(Name))<br>
+      continue;<br>
+    CurrentObjectAddresses[Name] = Addr;<br>
+  }<br>
+}<br>
+<br>
+/// Lookup a symbol address in the main binary symbol table. The<br>
+/// parser only needs to query common symbols, thus not every symbol's<br>
+/// address is available through this function.<br>
+uint64_t MachODebugMapParser::getMainBinarySymbolAddress(StringRef Name) {<br>
+  if (MainBinarySymbolAddresses.empty())<br>
+    loadMainBinarySymbols();<br>
+<br>
+  auto Sym = MainBinarySymbolAddresses.find(Name);<br>
+  if (Sym == MainBinarySymbolAddresses.end())<br>
+    return UnknownAddressOrSize;<br>
+  return Sym->second;<br>
+}<br>
+<br>
+/// Load the interesting main binary symbols' addresses into<br>
+/// MainBinarySymbolAddresses.<br>
+void MachODebugMapParser::loadMainBinarySymbols() {<br>
+  const MachOObjectFile &Binary = *MainOwningBinary.getBinary();<br>
+  section_iterator Section = Binary.section_end();<br>
+  for (const auto &Sym : Binary.symbols()) {<br>
+    SymbolRef::Type Type;<br>
+    // Skip undefined and STAB entries.<br>
+    if (Sym.getType(Type) || (Type & SymbolRef::ST_Debug) ||<br>
+        (Type & SymbolRef::ST_Unknown))<br>
+      continue;<br>
+    StringRef Name;<br>
+    uint64_t Addr;<br>
+    // The only symbols of interest are the global variables. These<br>
+    // are the only ones that need to be queried because the address<br>
+    // of common data won't be described in the debug map. All other<br>
+    // addresses should be fetched for the debug map.<br>
+    if (Sym.getAddress(Addr) || Addr == UnknownAddressOrSize ||<br>
+        !(Sym.getFlags() & SymbolRef::SF_Global) ||<br>
+        Sym.getSection(Section) || Section->isText() || Sym.getName(Name) ||<br>
+        Name.size() == 0 || Name[0] == '\0')<br>
+      continue;<br>
+    MainBinarySymbolAddresses[Name] = Addr;<br>
+  }<br>
+}<br>
+<br>
+}<br>
<br>
Added: llvm/trunk/tools/dsymutil/MachODebugMapParser.h<br>
URL: <a href="http://llvm.org/viewvc/llvm-project/llvm/trunk/tools/dsymutil/MachODebugMapParser.h?rev=223793&view=auto" target="_blank">http://llvm.org/viewvc/llvm-project/llvm/trunk/tools/dsymutil/MachODebugMapParser.h?rev=223793&view=auto</a><br>
==============================================================================<br>
--- llvm/trunk/tools/dsymutil/MachODebugMapParser.h (added)<br>
+++ llvm/trunk/tools/dsymutil/MachODebugMapParser.h Tue Dec  9 11:03:30 2014<br>
@@ -0,0 +1,76 @@<br>
+//===- tools/dsymutil/MachODebugMapParser.h - Parse STABS debug maps ------===//<br>
+//<br>
+//                             The LLVM Linker<br>
+//<br>
+// This file is distributed under the University of Illinois Open Source<br>
+// License. See LICENSE.TXT for details.<br>
+//<br>
+//===----------------------------------------------------------------------===//<br>
+///<br>
+/// \file<br>
+///<br>
+/// This file contains the class declaration for the code that parses STABS<br>
+/// debug maps that are embedded in the binaries symbol tables.<br>
+///<br>
+//===----------------------------------------------------------------------===//<br>
+#ifndef DSYMUTIL_MACHODEBUGMAPPARSER_H<br>
+#define DSYMUTIL_MACHODEBUGMAPPARSER_H<br>
+<br>
+#include "DebugMap.h"<br>
+<br>
+#include "llvm/ADT/StringMap.h"<br>
+#include "llvm/Object/MachO.h"<br>
+#include "llvm/Object/Error.h"<br>
+<br>
+namespace llvm {<br>
+<br>
+class MachODebugMapParser {<br>
+public:<br>
+ MachODebugMapParser(StringRef BinaryPath)<br>
+   : BinaryPath(BinaryPath) {}<br>
+<br>
+  /// \brief Add a prefix to every object file path before trying to<br>
+  /// open it.<br>
+  void setPreprendPath(StringRef Prefix) { PathPrefix = Prefix; }<br>
+<br>
+  /// \brief Parses and returns the DebugMap of the input binary.<br>
+  /// \returns an error in case the provided BinaryPath doesn't exist<br>
+  /// or isn't of a supported type.<br>
+  ErrorOr<std::unique_ptr<DebugMap>> parse();<br>
+<br>
+private:<br>
+  std::string BinaryPath;<br>
+  std::string PathPrefix;<br>
+<br>
+  /// OwningBinary constructed from the BinaryPath.<br>
+  object::OwningBinary<object::MachOObjectFile> MainOwningBinary;<br>
+  /// Map of the binary symbol addresses.<br>
+  StringMap<uint64_t> MainBinarySymbolAddresses;<br>
+  /// The constructed DebugMap.<br>
+  std::unique_ptr<DebugMap> Result;<br>
+<br>
+  /// Handle to the currently processed object file.<br>
+  object::OwningBinary<object::MachOObjectFile> CurrentObjectFile;<br>
+  /// Map of the currently processed object file symbol addresses.<br>
+  StringMap<uint64_t> CurrentObjectAddresses;<br>
+  /// Element of the debug map corresponfing to the current object file.<br>
+  DebugMapObject *CurrentDebugMapObject;<br>
+<br>
+  void switchToNewDebugMapObject(StringRef Filename);<br>
+  void resetParserState();<br>
+  uint64_t getMainBinarySymbolAddress(StringRef Name);<br>
+  void loadMainBinarySymbols();<br>
+  void loadCurrentObjectFileSymbols();<br>
+  void handleStabSymbolTableEntry(uint32_t StringIndex, uint8_t Type,<br>
+                                  uint8_t SectionIndex, uint16_t Flags,<br>
+                                  uint64_t Value);<br>
+<br>
+  template <typename STEType> void handleStabDebugMapEntry(const STEType &STE) {<br>
+    handleStabSymbolTableEntry(STE.n_strx, STE.n_type, STE.n_sect, STE.n_desc,<br>
+                               STE.n_value);<br>
+  }<br>
+};<br>
+<br>
+}<br>
+<br>
+#endif // DSYMUTIL_MACHODEBUGMAPPARSER_H<br>
<br>
Added: llvm/trunk/tools/dsymutil/Makefile<br>
URL: <a href="http://llvm.org/viewvc/llvm-project/llvm/trunk/tools/dsymutil/Makefile?rev=223793&view=auto" target="_blank">http://llvm.org/viewvc/llvm-project/llvm/trunk/tools/dsymutil/Makefile?rev=223793&view=auto</a><br>
==============================================================================<br>
--- llvm/trunk/tools/dsymutil/Makefile (added)<br>
+++ llvm/trunk/tools/dsymutil/Makefile Tue Dec  9 11:03:30 2014<br>
@@ -0,0 +1,17 @@<br>
+##===- tools/dsymutil/Makefile -----------------------------*- Makefile -*-===##<br>
+#<br>
+#                     The LLVM Compiler Infrastructure<br>
+#<br>
+# This file is distributed under the University of Illinois Open Source<br>
+# License. See LICENSE.TXT for details.<br>
+#<br>
+##===----------------------------------------------------------------------===##<br>
+<br>
+LEVEL := ../..<br>
+TOOLNAME := llvm-dsymutil<br>
+LINK_COMPONENTS := Object Support<br>
+<br>
+# This tool has no plugins, optimize startup time.<br>
+TOOL_NO_EXPORTS := 1<br>
+<br>
+include $(LEVEL)/Makefile.common<br>
<br>
Added: llvm/trunk/tools/dsymutil/dsymutil.cpp<br>
URL: <a href="http://llvm.org/viewvc/llvm-project/llvm/trunk/tools/dsymutil/dsymutil.cpp?rev=223793&view=auto" target="_blank">http://llvm.org/viewvc/llvm-project/llvm/trunk/tools/dsymutil/dsymutil.cpp?rev=223793&view=auto</a><br>
==============================================================================<br>
--- llvm/trunk/tools/dsymutil/dsymutil.cpp (added)<br>
+++ llvm/trunk/tools/dsymutil/dsymutil.cpp Tue Dec  9 11:03:30 2014<br>
@@ -0,0 +1,67 @@<br>
+//===-- dsymutil.cpp - Debug info dumping utility for llvm ----------------===//<br>
+//<br>
+//                     The LLVM Compiler Infrastructure<br>
+//<br>
+// This file is distributed under the University of Illinois Open Source<br>
+// License. See LICENSE.TXT for details.<br>
+//<br>
+//===----------------------------------------------------------------------===//<br>
+//<br>
+// This program is a utility that aims to be a dropin replacement for<br>
+// Darwin's dsymutil.<br>
+//<br>
+//===----------------------------------------------------------------------===//<br>
+<br>
+#include "DebugMap.h"<br>
+#include "DwarfLinker.h"<br>
+#include "MachODebugMapParser.h"<br>
+<br>
+#include "llvm/Support/ManagedStatic.h"<br>
+#include "llvm/Support/PrettyStackTrace.h"<br>
+#include "llvm/Support/Options.h"<br>
+#include "llvm/Support/raw_ostream.h"<br>
+#include "llvm/Support/Signals.h"<br>
+<br>
+#include <string><br>
+<br>
+static llvm::cl::opt<std::string> InputFile(llvm::cl::Positional,<br>
+                                            llvm::cl::desc("<input file>"),<br>
+                                            llvm::cl::init("-"));<br>
+<br>
+static llvm::cl::opt<std::string> OsoPrependPath("oso-prepend-path",<br>
+                                                 llvm::cl::desc("<path>"));<br>
+<br>
+static llvm::cl::opt<bool> Verbose("v", llvm::cl::desc("Verbosity level"),<br>
+                                   llvm::cl::init(false));<br>
+<br>
+static llvm::cl::opt<bool> ParseOnly("parse-only",<br>
+                                     llvm::cl::desc("Only parse the debug map, do "<br>
+                                                    "not actaully link the DWARF."),<br>
+                                     llvm::cl::init(false));<br>
+<br>
+int main(int argc, char **argv) {<br>
+  llvm::sys::PrintStackTraceOnErrorSignal();<br>
+  llvm::PrettyStackTraceProgram StackPrinter(argc, argv);<br>
+  llvm::llvm_shutdown_obj Shutdown;<br>
+<br>
+  llvm::cl::ParseCommandLineOptions(argc, argv, "llvm dsymutil\n");<br>
+<br>
+  llvm::MachODebugMapParser Parser(InputFile);<br>
+  Parser.setPreprendPath(OsoPrependPath);<br>
+  llvm::ErrorOr<std::unique_ptr<llvm::DebugMap>> DebugMap = Parser.parse();<br>
+<br>
+  if (auto EC = DebugMap.getError()) {<br>
+    llvm::errs() << "error: cannot parse the debug map for \"" << InputFile <<<br>
+      "\": " << EC.message() << '\n';<br>
+    return 1;<br>
+  }<br>
+<br>
+  if (Verbose)<br>
+    (*DebugMap)->print(llvm::outs());<br>
+<br>
+  if (ParseOnly)<br>
+    return 0;<br>
+<br>
+  llvm::DwarfLinker Linker(InputFile + ".dwarf");<br>
+  return !Linker.link(*DebugMap.get());<br>
+}<br>
<br>
<br>
_______________________________________________<br>
llvm-commits mailing list<br>
<a href="mailto:llvm-commits@cs.uiuc.edu">llvm-commits@cs.uiuc.edu</a><br>
<a href="http://lists.cs.uiuc.edu/mailman/listinfo/llvm-commits" target="_blank">http://lists.cs.uiuc.edu/mailman/listinfo/llvm-commits</a><br>
</blockquote></div><br></div>