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