<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=""><div class="">Sorry it has taken me so long to reply. I just finished catching up from my leave, I’ll resume the llvm-dsymutil upstreaming work shortly. </div><br class=""><div><blockquote type="cite" class=""><div class="">On Mar 24, 2015, at 6:11 PM, Eric Christopher <<a href="mailto:echristo@gmail.com" class="">echristo@gmail.com</a>> wrote:</div><br class="Apple-interchange-newline"><div class=""><div dir="ltr" class="">Can you comment on this a bit more now? Also, FWIW, gcc (and we're using it) use a different kind of format that includes some useful information in lookup tables that we might want to support outputting. Also, why have the tool able to output pubnames/pubtypes at all. I don't think lldb is using it?</div></div></blockquote><div><br class=""></div><div>llvm-dsymutil is emitting the debug_pubnames/debug_pubtypes sections only as a backward compatibility thing. We aim for initial bit-for-bit compatibility between llvm-dsymtuil and dsymtuil, and we only change dsymutil to fix blatant bugs that would be really wrong to reproduce. Once we have that backward compatibility guarantee in place, I plan to trim/rationalize the llvm-dsymtuil output (I’m adding a lot of FIXMEs in the code, and most are because the logic is really convoluted because of that backward compatibility). The emission of the debug_pub{names|types} is on my list of things to remove once I’m sure that nothing uses it (lldb is not be the sole consumer of debug info). This is also the reason why I didn’t try to reuse the code that’s already there to emit the [gnu]_pub* stuff, I think it will disappear from llvm-dsymutil medium term. If other users than Darwin are willing to reuse the dwarf linking stuff at some point we can revisit that.</div><div><br class=""></div><div>A similar section that I’ll generate but I really think isn’t used is the debug_inlined section. Must be an artifact from the Apple GDB, and it was easier to just replicate the functionality for validation purposes.</div><div><br class=""></div><div>Fred</div><br class=""><blockquote type="cite" class=""><div class=""><div dir="ltr" class=""><div class="">-eric</div></div><br class=""><div class="gmail_quote">On Sun, Mar 15, 2015 at 7:10 PM Frederic Riss <<a href="mailto:friss@apple.com" class="">friss@apple.com</a>> 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: Sun Mar 15 21:05:10 2015<br class="">
New Revision: 232342<br class="">
<br class="">
URL: <a href="https://urldefense.proofpoint.com/v2/url?u=http-3A__llvm.org_viewvc_llvm-2Dproject-3Frev-3D232342-26view-3Drev&d=AwMFaQ&c=8hUWFZcy2Z-Za5rBPlktOQ&r=mQ4LZ2PUj9hpadE3cDHZnIdEwhEBrbAstXeMaFoB9tg&m=9NopLwl8sAwiTF11-CLVp9xjgQtNLht2KPt1n8sPC18&s=NFQXcGNVkemRgUdJwGLq6ZYvcibZ-EGUtaYiXoKjMLg&e=" target="_blank" class="">http://llvm.org/viewvc/llvm-<u class=""></u>project?rev=232342&view=rev</a><br class="">
Log:<br class="">
[dsymutil] Add support to generate .debug_pubnames and .debug_pubtypes<br class="">
<br class="">
The information gathering part of the patch stores a bit more information<br class="">
than what is strictly necessary for these 2 sections. The rest will<br class="">
become useful when we start emitting __apple_* type accelerator tables.<br class="">
<br class="">
Modified:<br class="">
    llvm/trunk/test/tools/<u class=""></u>dsymutil/X86/basic-linking-<u class=""></u>x86.test<br class="">
    llvm/trunk/test/tools/<u class=""></u>dsymutil/X86/basic-lto-dw4-<u class=""></u>linking-x86.test<br class="">
    llvm/trunk/test/tools/<u class=""></u>dsymutil/X86/basic-lto-<u class=""></u>linking-x86.test<br class="">
    llvm/trunk/tools/dsymutil/<u class=""></u>DwarfLinker.cpp<br class="">
<br class="">
Modified: llvm/trunk/test/tools/<u class=""></u>dsymutil/X86/basic-linking-<u class=""></u>x86.test<br class="">
URL: <a href="https://urldefense.proofpoint.com/v2/url?u=http-3A__llvm.org_viewvc_llvm-2Dproject_llvm_trunk_test_tools_dsymutil_X86_basic-2Dlinking-2Dx86.test-3Frev-3D232342-26r1-3D232341-26r2-3D232342-26view-3Ddiff&d=AwMFaQ&c=8hUWFZcy2Z-Za5rBPlktOQ&r=mQ4LZ2PUj9hpadE3cDHZnIdEwhEBrbAstXeMaFoB9tg&m=9NopLwl8sAwiTF11-CLVp9xjgQtNLht2KPt1n8sPC18&s=jgFASiTyl4BczAPqxINHbFix86uJ9EX342qUIQxxA0E&e=" target="_blank" class="">http://llvm.org/viewvc/llvm-<u class=""></u>project/llvm/trunk/test/tools/<u class=""></u>dsymutil/X86/basic-linking-<u class=""></u>x86.test?rev=232342&r1=232341&<u class=""></u>r2=232342&view=diff</a><br class="">
==============================<u class=""></u>==============================<u class=""></u>==================<br class="">
--- llvm/trunk/test/tools/<u class=""></u>dsymutil/X86/basic-linking-<u class=""></u>x86.test (original)<br class="">
+++ llvm/trunk/test/tools/<u class=""></u>dsymutil/X86/basic-linking-<u class=""></u>x86.test Sun Mar 15 21:05:10 2015<br class="">
@@ -186,4 +186,32 @@ CHECK-NEXT: 0x0000000100000f7b     20<br class="">
 CHECK-NEXT: 0x0000000100000f84     20      0      1   0             0  is_stmt end_sequence<br class="">
 CHECK-NEXT: 0x0000000100000f90     11      0      1   0             0  is_stmt<br class="">
 CHECK-NEXT: 0x0000000100000f9b     12      0      1   0             0  is_stmt prologue_end<br class="">
-CHECK-NEXT: 0x0000000100000fa9     12      0      1   0             0  is_stmt end_sequence<br class="">
\ No newline at end of file<br class="">
+CHECK-NEXT: 0x0000000100000fa9     12      0      1   0             0  is_stmt end_sequence<br class="">
+<br class="">
+CHECK: .debug_pubnames contents:<br class="">
+CHECK-NEXT: length = 0x00000017 version = 0x0002 unit_offset = 0x00000000 unit_size = 0x00000081<br class="">
+CHECK-NEXT: Offset     Name<br class="">
+CHECK-NEXT: 0x00000026 "main"<br class="">
+CHECK-NEXT: length = 0x00000036 version = 0x0002 unit_offset = 0x00000081 unit_size = 0x000000a5<br class="">
+CHECK-NEXT: Offset     Name<br class="">
+CHECK-NEXT: 0x0000002d "private_int"<br class="">
+CHECK-NEXT: 0x00000042 "baz"<br class="">
+CHECK-NEXT: 0x00000057 "foo"<br class="">
+CHECK-NEXT: 0x00000086 "inc"<br class="">
+CHECK-NEXT: length = 0x00000026 version = 0x0002 unit_offset = 0x00000126 unit_size = 0x00000096<br class="">
+CHECK-NEXT: Offset     Name<br class="">
+CHECK-NEXT: 0x00000026 "val"<br class="">
+CHECK-NEXT: 0x00000048 "bar"<br class="">
+CHECK-NEXT: 0x00000077 "inc"<br class="">
+<br class="">
+CHECK: .debug_pubtypes contents:<br class="">
+CHECK-NEXT: length = 0x0000001f version = 0x0002 unit_offset = 0x00000000 unit_size = 0x00000081<br class="">
+CHECK-NEXT: Offset     Name<br class="">
+CHECK-NEXT: 0x00000063 "int"<br class="">
+CHECK-NEXT: 0x00000079 "char"<br class="">
+CHECK-NEXT: length = 0x00000016 version = 0x0002 unit_offset = 0x00000081 unit_size = 0x000000a5<br class="">
+CHECK-NEXT: Offset     Name<br class="">
+CHECK-NEXT: 0x00000026 "int"<br class="">
+CHECK-NEXT: length = 0x00000016 version = 0x0002 unit_offset = 0x00000126 unit_size = 0x00000096<br class="">
+CHECK-NEXT: Offset     Name<br class="">
+CHECK-NEXT: 0x00000041 "int"<br class="">
<br class="">
Modified: llvm/trunk/test/tools/<u class=""></u>dsymutil/X86/basic-lto-dw4-<u class=""></u>linking-x86.test<br class="">
URL: <a href="https://urldefense.proofpoint.com/v2/url?u=http-3A__llvm.org_viewvc_llvm-2Dproject_llvm_trunk_test_tools_dsymutil_X86_basic-2Dlto-2Ddw4-2Dlinking-2Dx86.test-3Frev-3D232342-26r1-3D232341-26r2-3D232342-26view-3Ddiff&d=AwMFaQ&c=8hUWFZcy2Z-Za5rBPlktOQ&r=mQ4LZ2PUj9hpadE3cDHZnIdEwhEBrbAstXeMaFoB9tg&m=9NopLwl8sAwiTF11-CLVp9xjgQtNLht2KPt1n8sPC18&s=HLo2U4ocLIoT2U03wiyKYkwzXOnhj64s8kSQ0h_qwKg&e=" target="_blank" class="">http://llvm.org/viewvc/llvm-<u class=""></u>project/llvm/trunk/test/tools/<u class=""></u>dsymutil/X86/basic-lto-dw4-<u class=""></u>linking-x86.test?rev=232342&<u class=""></u>r1=232341&r2=232342&view=diff</a><br class="">
==============================<u class=""></u>==============================<u class=""></u>==================<br class="">
--- llvm/trunk/test/tools/<u class=""></u>dsymutil/X86/basic-lto-dw4-<u class=""></u>linking-x86.test (original)<br class="">
+++ llvm/trunk/test/tools/<u class=""></u>dsymutil/X86/basic-lto-dw4-<u class=""></u>linking-x86.test Sun Mar 15 21:05:10 2015<br class="">
@@ -179,3 +179,25 @@ CHECK-NEXT: 0x0000000100000fa9     19<br class="">
 CHECK-NEXT: 0x0000000100000fab     19     10      1   0             0<br class="">
 CHECK-NEXT: 0x0000000100000fb2     20      1      1   0             0  is_stmt<br class="">
 CHECK-NEXT: 0x0000000100000fb4     20      1      1   0             0  is_stmt end_sequence<br class="">
+<br class="">
+CHECK: .debug_pubnames contents:<br class="">
+CHECK-NEXT: length = 0x00000017 version = 0x0002 unit_offset = 0x00000000 unit_size = 0x00000077<br class="">
+CHECK-NEXT: Offset     Name<br class="">
+CHECK-NEXT: 0x0000002a "main"<br class="">
+CHECK-NEXT: length = 0x0000002e version = 0x0002 unit_offset = 0x00000077 unit_size = 0x000000a4<br class="">
+CHECK-NEXT: Offset     Name<br class="">
+CHECK-NEXT: 0x00000031 "baz"<br class="">
+CHECK-NEXT: 0x00000046 "private_int"<br class="">
+CHECK-NEXT: 0x00000067 "foo"<br class="">
+CHECK-NEXT: length = 0x0000001e version = 0x0002 unit_offset = 0x0000011b unit_size = 0x00000085<br class="">
+CHECK-NEXT: Offset     Name<br class="">
+CHECK-NEXT: 0x0000002a "val"<br class="">
+CHECK-NEXT: 0x00000050 "bar"<br class="">
+<br class="">
+CHECK: .debug_pubtypes contents:<br class="">
+CHECK-NEXT: length = 0x00000017 version = 0x0002 unit_offset = 0x00000000 unit_size = 0x00000077<br class="">
+CHECK-NEXT: Offset     Name<br class="">
+CHECK-NEXT: 0x0000006f "char"<br class="">
+CHECK-NEXT: length = 0x00000016 version = 0x0002 unit_offset = 0x00000077 unit_size = 0x000000a4<br class="">
+CHECK-NEXT: Offset     Name<br class="">
+CHECK-NEXT: 0x0000002a "int"<br class="">
<br class="">
Modified: llvm/trunk/test/tools/<u class=""></u>dsymutil/X86/basic-lto-<u class=""></u>linking-x86.test<br class="">
URL: <a href="https://urldefense.proofpoint.com/v2/url?u=http-3A__llvm.org_viewvc_llvm-2Dproject_llvm_trunk_test_tools_dsymutil_X86_basic-2Dlto-2Dlinking-2Dx86.test-3Frev-3D232342-26r1-3D232341-26r2-3D232342-26view-3Ddiff&d=AwMFaQ&c=8hUWFZcy2Z-Za5rBPlktOQ&r=mQ4LZ2PUj9hpadE3cDHZnIdEwhEBrbAstXeMaFoB9tg&m=9NopLwl8sAwiTF11-CLVp9xjgQtNLht2KPt1n8sPC18&s=-cS-fUKmlngp0nz8YGPE1IoSFeFCRIb6nwPDfEIBt8k&e=" target="_blank" class="">http://llvm.org/viewvc/llvm-<u class=""></u>project/llvm/trunk/test/tools/<u class=""></u>dsymutil/X86/basic-lto-<u class=""></u>linking-x86.test?rev=232342&<u class=""></u>r1=232341&r2=232342&view=diff</a><br class="">
==============================<u class=""></u>==============================<u class=""></u>==================<br class="">
--- llvm/trunk/test/tools/<u class=""></u>dsymutil/X86/basic-lto-<u class=""></u>linking-x86.test (original)<br class="">
+++ llvm/trunk/test/tools/<u class=""></u>dsymutil/X86/basic-lto-<u class=""></u>linking-x86.test Sun Mar 15 21:05:10 2015<br class="">
@@ -184,3 +184,23 @@ CHECK-NEXT: 0x0000000100000fa7     20<br class="">
 CHECK-NEXT: 0x0000000100000fa9     19      0      1   0             0  is_stmt<br class="">
 CHECK-NEXT: 0x0000000100000fb2     20      0      1   0             0  is_stmt<br class="">
 CHECK-NEXT: 0x0000000100000fb4     20      0      1   0             0  is_stmt end_sequence<br class="">
+<br class="">
+CHECK: .debug_pubnames contents:<br class="">
+CHECK-NEXT: length = 0x00000017 version = 0x0002 unit_offset = 0x00000000 unit_size = 0x00000081<br class="">
+CHECK-NEXT: Offset     Name<br class="">
+CHECK-NEXT: 0x00000026 "main"<br class="">
+CHECK-NEXT: length = 0x0000002e version = 0x0002 unit_offset = 0x00000081 unit_size = 0x000000b9<br class="">
+CHECK-NEXT: Offset     Name<br class="">
+CHECK-NEXT: 0x00000026 "private_int"<br class="">
+CHECK-NEXT: 0x0000003f "baz"<br class="">
+CHECK-NEXT: 0x00000058 "foo"<br class="">
+CHECK-NEXT: length = 0x0000001e version = 0x0002 unit_offset = 0x0000013a unit_size = 0x000000ac<br class="">
+CHECK-NEXT: Offset     Name<br class="">
+CHECK-NEXT: 0x00000026 "val"<br class="">
+CHECK-NEXT: 0x00000045 "bar"<br class="">
+<br class="">
+CHECK: .debug_pubtypes contents:<br class="">
+CHECK-NEXT: length = 0x0000001f version = 0x0002 unit_offset = 0x00000000 unit_size = 0x00000081<br class="">
+CHECK-NEXT: Offset     Name<br class="">
+CHECK-NEXT: 0x00000063 "int"<br class="">
+CHECK-NEXT: 0x00000079 "char"<br class="">
<br class="">
Modified: llvm/trunk/tools/dsymutil/<u class=""></u>DwarfLinker.cpp<br class="">
URL: <a href="https://urldefense.proofpoint.com/v2/url?u=http-3A__llvm.org_viewvc_llvm-2Dproject_llvm_trunk_tools_dsymutil_DwarfLinker.cpp-3Frev-3D232342-26r1-3D232341-26r2-3D232342-26view-3Ddiff&d=AwMFaQ&c=8hUWFZcy2Z-Za5rBPlktOQ&r=mQ4LZ2PUj9hpadE3cDHZnIdEwhEBrbAstXeMaFoB9tg&m=9NopLwl8sAwiTF11-CLVp9xjgQtNLht2KPt1n8sPC18&s=298RtFxQ99BvsIYrFg05D9yIBzIaaTGJ-ugn2Nr3jps&e=" target="_blank" class="">http://llvm.org/viewvc/llvm-<u class=""></u>project/llvm/trunk/tools/<u class=""></u>dsymutil/DwarfLinker.cpp?rev=<u class=""></u>232342&r1=232341&r2=232342&<u class=""></u>view=diff</a><br class="">
==============================<u class=""></u>==============================<u class=""></u>==================<br class="">
--- llvm/trunk/tools/dsymutil/<u class=""></u>DwarfLinker.cpp (original)<br class="">
+++ llvm/trunk/tools/dsymutil/<u class=""></u>DwarfLinker.cpp Sun Mar 15 21:05:10 2015<br class="">
@@ -143,6 +143,30 @@ public:<br class="">
   /// list in the debug_loc section.<br class="">
   void noteLocationAttribute(<u class=""></u>DIEInteger *Attr, int64_t PcOffset);<br class="">
<br class="">
+  /// \brief Add a name accelerator entry for \p Die with \p Name<br class="">
+  /// which is stored in the string table at \p Offset.<br class="">
+  void addNameAccelerator(const DIE *Die, const char *Name, uint32_t Offset,<br class="">
+                          bool SkipPubnamesSection = false);<br class="">
+<br class="">
+  /// \brief Add a type accelerator entry for \p Die with \p Name<br class="">
+  /// which is stored in the string table at \p Offset.<br class="">
+  void addTypeAccelerator(const DIE *Die, const char *Name, uint32_t Offset);<br class="">
+<br class="">
+  struct AccelInfo {<br class="">
+    StringRef Name; ///< Name of the entry.<br class="">
+    const DIE *Die; ///< DIE this entry describes.<br class="">
+    uint32_t NameOffset; ///< Offset of Name in the string pool.<br class="">
+    bool SkipPubSection; ///< Emit this entry only in the apple_* sections.<br class="">
+<br class="">
+    AccelInfo(StringRef Name, const DIE *Die, uint32_t NameOffset,<br class="">
+              bool SkipPubSection = false)<br class="">
+        : Name(Name), Die(Die), NameOffset(NameOffset),<br class="">
+          SkipPubSection(SkipPubSection) {}<br class="">
+  };<br class="">
+<br class="">
+  const std::vector<AccelInfo> &getPubnames() const { return Pubnames; }<br class="">
+  const std::vector<AccelInfo> &getPubtypes() const { return Pubtypes; }<br class="">
+<br class="">
 private:<br class="">
   DWARFUnit &OrigUnit;<br class="">
   unsigned ID;<br class="">
@@ -182,6 +206,13 @@ private:<br class="">
   /// along with the PC offset that is to be applied to their<br class="">
   /// function's address.<br class="">
   std::vector<std::pair<<u class=""></u>DIEInteger *, int64_t>> LocationAttributes;<br class="">
+<br class="">
+  /// \brief Accelerator entries for the unit, both for the pub*<br class="">
+  /// sections and the apple* ones.<br class="">
+  /// @{<br class="">
+  std::vector<AccelInfo> Pubnames;<br class="">
+  std::vector<AccelInfo> Pubtypes;<br class="">
+  /// @}<br class="">
 };<br class="">
<br class="">
 uint64_t CompileUnit::<u class=""></u>computeNextUnitOffset() {<br class="">
@@ -230,6 +261,20 @@ void CompileUnit::<u class=""></u>noteLocationAttribute(<br class="">
   LocationAttributes.emplace_<u class=""></u>back(Attr, PcOffset);<br class="">
 }<br class="">
<br class="">
+/// \brief Add a name accelerator entry for \p Die with \p Name<br class="">
+/// which is stored in the string table at \p Offset.<br class="">
+void CompileUnit::<u class=""></u>addNameAccelerator(const DIE *Die, const char *Name,<br class="">
+                                     uint32_t Offset, bool SkipPubSection) {<br class="">
+  Pubnames.emplace_back(Name, Die, Offset, SkipPubSection);<br class="">
+}<br class="">
+<br class="">
+/// \brief Add a type accelerator entry for \p Die with \p Name<br class="">
+/// which is stored in the string table at \p Offset.<br class="">
+void CompileUnit::<u class=""></u>addTypeAccelerator(const DIE *Die, const char *Name,<br class="">
+                                     uint32_t Offset) {<br class="">
+  Pubtypes.emplace_back(Name, Die, Offset, false);<br class="">
+}<br class="">
+<br class="">
 /// \brief A string table that doesn't need relocations.<br class="">
 ///<br class="">
 /// We are doing a final link, no need for a string table that<br class="">
@@ -342,6 +387,12 @@ class DwarfStreamer {<br class="">
   uint32_t LocSectionSize;<br class="">
   uint32_t LineSectionSize;<br class="">
<br class="">
+  /// \brief Emit the pubnames or pubtypes section contribution for \p<br class="">
+  /// Unit into \p Sec. The data is provided in \p Names.<br class="">
+  void emitPubSectionForUnit(const MCSection *Sec, StringRef Name,<br class="">
+                             const CompileUnit &Unit,<br class="">
+                             const std::vector<CompileUnit::<u class=""></u>AccelInfo> &Names);<br class="">
+<br class="">
 public:<br class="">
   /// \brief Actually create the streamer and the ouptut file.<br class="">
   ///<br class="">
@@ -402,6 +453,12 @@ public:<br class="">
                             unsigned AdddressSize);<br class="">
<br class="">
   uint32_t getLineSectionSize() const { return LineSectionSize; }<br class="">
+<br class="">
+  /// \brief Emit the .debug_pubnames contribution for \p Unit.<br class="">
+  void emitPubNamesForUnit(const CompileUnit &Unit);<br class="">
+<br class="">
+  /// \brief Emit the .debug_pubtypes contribution for \p Unit.<br class="">
+  void emitPubTypesForUnit(const CompileUnit &Unit);<br class="">
 };<br class="">
<br class="">
 bool DwarfStreamer::init(Triple TheTriple, StringRef OutputFilename) {<br class="">
@@ -851,6 +908,59 @@ void DwarfStreamer::<u class=""></u>emitLineTableForUnit<br class="">
   MS->EmitLabel(LineEndSym);<br class="">
 }<br class="">
<br class="">
+/// \brief Emit the pubnames or pubtypes section contribution for \p<br class="">
+/// Unit into \p Sec. The data is provided in \p Names.<br class="">
+void DwarfStreamer::<u class=""></u>emitPubSectionForUnit(<br class="">
+    const MCSection *Sec, StringRef SecName, const CompileUnit &Unit,<br class="">
+    const std::vector<CompileUnit::<u class=""></u>AccelInfo> &Names) {<br class="">
+  if (Names.empty())<br class="">
+    return;<br class="">
+<br class="">
+  // Start the dwarf pubnames section.<br class="">
+  Asm->OutStreamer.<u class=""></u>SwitchSection(Sec);<br class="">
+  MCSymbol *BeginLabel =<br class="">
+      Asm->GetTempSymbol("pub" + SecName + "_begin", Unit.getUniqueID());<br class="">
+  MCSymbol *EndLabel =<br class="">
+      Asm->GetTempSymbol("pub" + SecName + "_end", Unit.getUniqueID());<br class="">
+<br class="">
+  bool HeaderEmitted = false;<br class="">
+  // Emit the pubnames for this compilation unit.<br class="">
+  for (const auto &Name : Names) {<br class="">
+    if (Name.SkipPubSection)<br class="">
+      continue;<br class="">
+<br class="">
+    if (!HeaderEmitted) {<br class="">
+      // Emit the header.<br class="">
+      Asm->EmitLabelDifference(<u class=""></u>EndLabel, BeginLabel, 4); // Length<br class="">
+      Asm->OutStreamer.EmitLabel(<u class=""></u>BeginLabel);<br class="">
+      Asm->EmitInt16(dwarf::DW_<u class=""></u>PUBNAMES_VERSION); // Version<br class="">
+      Asm->EmitInt32(Unit.<u class=""></u>getStartOffset()); // Unit offset<br class="">
+      Asm->EmitInt32(Unit.<u class=""></u>getNextUnitOffset() - Unit.getStartOffset()); // Size<br class="">
+      HeaderEmitted = true;<br class="">
+    }<br class="">
+    Asm->EmitInt32(Name.Die-><u class=""></u>getOffset());<br class="">
+    Asm->OutStreamer.EmitBytes(<br class="">
+        StringRef(Name.Name.data(), Name.Name.size() + 1));<br class="">
+  }<br class="">
+<br class="">
+  if (!HeaderEmitted)<br class="">
+    return;<br class="">
+  Asm->EmitInt32(0); // End marker.<br class="">
+  Asm->OutStreamer.EmitLabel(<u class=""></u>EndLabel);<br class="">
+}<br class="">
+<br class="">
+/// \brief Emit .debug_pubnames for \p Unit.<br class="">
+void DwarfStreamer::<u class=""></u>emitPubNamesForUnit(const CompileUnit &Unit) {<br class="">
+  emitPubSectionForUnit(MC-><u class=""></u>getObjectFileInfo()-><u class=""></u>getDwarfPubNamesSection(),<br class="">
+                        "names", Unit, Unit.getPubnames());<br class="">
+}<br class="">
+<br class="">
+/// \brief Emit .debug_pubtypes for \p Unit.<br class="">
+void DwarfStreamer::<u class=""></u>emitPubTypesForUnit(const CompileUnit &Unit) {<br class="">
+  emitPubSectionForUnit(MC-><u class=""></u>getObjectFileInfo()-><u class=""></u>getDwarfPubTypesSection(),<br class="">
+                        "types", Unit, Unit.getPubtypes());<br class="">
+}<br class="">
+<br class="">
 /// \brief The core of the Dwarf linking logic.<br class="">
 ///<br class="">
 /// The link of the dwarf information from the object files will be<br class="">
@@ -989,10 +1099,19 @@ private:<br class="">
   /// \brief Information gathered and exchanged between the various<br class="">
   /// clone*Attributes helpers about the attributes of a particular DIE.<br class="">
   struct AttributesInfo {<br class="">
+    const char *Name, *MangledName;         ///< Names.<br class="">
+    uint32_t NameOffset, MangledNameOffset; ///< Offsets in the string pool.<br class="">
+<br class="">
     uint64_t OrigHighPc; ///< Value of AT_high_pc in the input DIE<br class="">
     int64_t PCOffset;    ///< Offset to apply to PC addresses inside a function.<br class="">
<br class="">
-    AttributesInfo() : OrigHighPc(0), PCOffset(0) {}<br class="">
+    bool HasLowPc;      ///< Does the DIE have a low_pc attribute?<br class="">
+    bool IsDeclaration; ///< Is this DIE only a declaration?<br class="">
+<br class="">
+    AttributesInfo()<br class="">
+        : Name(nullptr), MangledName(nullptr), NameOffset(0),<br class="">
+          MangledNameOffset(0), OrigHighPc(0), PCOffset(0), HasLowPc(false),<br class="">
+          IsDeclaration(false) {}<br class="">
   };<br class="">
<br class="">
   /// \brief Helper for cloneDIE.<br class="">
@@ -1026,7 +1145,7 @@ private:<br class="">
                                 const DWARFDebugInfoEntryMinimal &InputDIE,<br class="">
                                 CompileUnit &U, AttributeSpec AttrSpec,<br class="">
                                 const DWARFFormValue &Val, unsigned AttrSize,<br class="">
-                                const AttributesInfo &Info);<br class="">
+                                AttributesInfo &Info);<br class="">
<br class="">
   /// \brief Helper for cloneDIE.<br class="">
   bool applyValidRelocs(<u class=""></u>MutableArrayRef<char> Data, uint32_t BaseOffset,<br class="">
@@ -1055,6 +1174,9 @@ private:<br class="">
   /// emit the result in the debug_line section.<br class="">
   void patchLineTableForUnit(<u class=""></u>CompileUnit &Unit, DWARFContext &OrigDwarf);<br class="">
<br class="">
+  /// \brief Emit the accelerator entries for \p Unit.<br class="">
+  void emitAcceleratorEntriesForUnit(<u class=""></u>CompileUnit &Unit);<br class="">
+<br class="">
   /// \brief DIELoc objects that need to be destructed (but not freed!).<br class="">
   std::vector<DIELoc *> DIELocs;<br class="">
   /// \brief DIEBlock objects that need to be destructed (but not freed!).<br class="">
@@ -1073,6 +1195,9 @@ private:<br class="">
<br class="">
   CompileUnit *getUnitForOffset(unsigned Offset);<br class="">
<br class="">
+  bool getDIENames(const DWARFDebugInfoEntryMinimal &Die, DWARFUnit &U,<br class="">
+                   AttributesInfo &Info);<br class="">
+<br class="">
   void reportWarning(const Twine &Warning, const DWARFUnit *Unit = nullptr,<br class="">
                      const DWARFDebugInfoEntryMinimal *DIE = nullptr) const;<br class="">
<br class="">
@@ -1132,6 +1257,24 @@ const DWARFDebugInfoEntryMinimal *DwarfL<br class="">
   return nullptr;<br class="">
 }<br class="">
<br class="">
+/// \brief Get the potential name and mangled name for the entity<br class="">
+/// described by \p Die and store them in \Info if they are not<br class="">
+/// already there.<br class="">
+/// \returns is a name was found.<br class="">
+bool DwarfLinker::getDIENames(const DWARFDebugInfoEntryMinimal &Die,<br class="">
+                              DWARFUnit &U, AttributesInfo &Info) {<br class="">
+  // FIXME: a bit wastefull as the first getName might return the<br class="">
+  // short name.<br class="">
+  if (!Info.MangledName &&<br class="">
+      (Info.MangledName = Die.getName(&U, DINameKind::LinkageName)))<br class="">
+    Info.MangledNameOffset = StringPool.getStringOffset(<u class=""></u>Info.MangledName);<br class="">
+<br class="">
+  if (!Info.Name && (Info.Name = Die.getName(&U, DINameKind::ShortName)))<br class="">
+    Info.NameOffset = StringPool.getStringOffset(<u class=""></u>Info.Name);<br class="">
+<br class="">
+  return Info.Name || Info.MangledName;<br class="">
+}<br class="">
+<br class="">
 /// \brief Report a warning to the user, optionaly including<br class="">
 /// information about a specific \p DIE related to the warning.<br class="">
 void DwarfLinker::reportWarning(<u class=""></u>const Twine &Warning, const DWARFUnit *Unit,<br class="">
@@ -1735,6 +1878,7 @@ unsigned DwarfLinker::<u class=""></u>cloneAddressAttrib<br class="">
       if (Addr == UINT64_MAX)<br class="">
         return 0;<br class="">
     }<br class="">
+    Info.HasLowPc = true;<br class="">
   } else if (AttrSpec.Attr == dwarf::DW_AT_high_pc) {<br class="">
     if (Die.getTag() == dwarf::DW_TAG_compile_unit) {<br class="">
       if (uint64_t HighPc = Unit.getHighPc())<br class="">
@@ -1759,7 +1903,7 @@ unsigned DwarfLinker::<u class=""></u>cloneAddressAttrib<br class="">
 unsigned DwarfLinker::<u class=""></u>cloneScalarAttribute(<br class="">
     DIE &Die, const DWARFDebugInfoEntryMinimal &InputDIE, CompileUnit &Unit,<br class="">
     AttributeSpec AttrSpec, const DWARFFormValue &Val, unsigned AttrSize,<br class="">
-    const AttributesInfo &Info) {<br class="">
+    AttributesInfo &Info) {<br class="">
   uint64_t Value;<br class="">
   if (AttrSpec.Attr == dwarf::DW_AT_high_pc &&<br class="">
       Die.getTag() == dwarf::DW_TAG_compile_unit) {<br class="">
@@ -1787,6 +1931,8 @@ unsigned DwarfLinker::<u class=""></u>cloneScalarAttribu<br class="">
   else if (AttrSpec.Attr == dwarf::DW_AT_location ||<br class="">
            AttrSpec.Attr == dwarf::DW_AT_frame_base)<br class="">
     Unit.noteLocationAttribute(<u class=""></u>Attr, Info.PCOffset);<br class="">
+  else if (AttrSpec.Attr == dwarf::DW_AT_declaration && Value)<br class="">
+    Info.IsDeclaration = true;<br class="">
<br class="">
   Die.addValue(dwarf::Attribute(<u class=""></u>AttrSpec.Attr), dwarf::Form(AttrSpec.Form),<br class="">
                Attr);<br class="">
@@ -1886,6 +2032,39 @@ bool DwarfLinker::applyValidRelocs(<u class=""></u>Mutab<br class="">
   return Applied;<br class="">
 }<br class="">
<br class="">
+static bool isTypeTag(uint16_t Tag) {<br class="">
+  switch (Tag) {<br class="">
+  case dwarf::DW_TAG_array_type:<br class="">
+  case dwarf::DW_TAG_class_type:<br class="">
+  case dwarf::DW_TAG_enumeration_<u class=""></u>type:<br class="">
+  case dwarf::DW_TAG_pointer_type:<br class="">
+  case dwarf::DW_TAG_reference_type:<br class="">
+  case dwarf::DW_TAG_string_type:<br class="">
+  case dwarf::DW_TAG_structure_type:<br class="">
+  case dwarf::DW_TAG_subroutine_type:<br class="">
+  case dwarf::DW_TAG_typedef:<br class="">
+  case dwarf::DW_TAG_union_type:<br class="">
+  case dwarf::DW_TAG_ptr_to_member_<u class=""></u>type:<br class="">
+  case dwarf::DW_TAG_set_type:<br class="">
+  case dwarf::DW_TAG_subrange_type:<br class="">
+  case dwarf::DW_TAG_base_type:<br class="">
+  case dwarf::DW_TAG_const_type:<br class="">
+  case dwarf::DW_TAG_constant:<br class="">
+  case dwarf::DW_TAG_file_type:<br class="">
+  case dwarf::DW_TAG_namelist:<br class="">
+  case dwarf::DW_TAG_packed_type:<br class="">
+  case dwarf::DW_TAG_volatile_type:<br class="">
+  case dwarf::DW_TAG_restrict_type:<br class="">
+  case dwarf::DW_TAG_interface_type:<br class="">
+  case dwarf::DW_TAG_unspecified_<u class=""></u>type:<br class="">
+  case dwarf::DW_TAG_shared_type:<br class="">
+    return true;<br class="">
+  default:<br class="">
+    break;<br class="">
+  }<br class="">
+  return false;<br class="">
+}<br class="">
+<br class="">
 /// \brief Recursively clone \p InputDIE's subtrees that have been<br class="">
 /// selected to appear in the linked output.<br class="">
 ///<br class="">
@@ -1958,6 +2137,26 @@ DIE *DwarfLinker::cloneDIE(const DWARFDe<br class="">
         cloneAttribute(*Die, InputDIE, Unit, Val, AttrSpec, AttrSize, AttrInfo);<br class="">
   }<br class="">
<br class="">
+  // Look for accelerator entries.<br class="">
+  uint16_t Tag = InputDIE.getTag();<br class="">
+  // FIXME: This is slightly wrong. An inline_subroutine without a<br class="">
+  // low_pc, but with AT_ranges might be interesting to get into the<br class="">
+  // accelerator tables too. For now stick with dsymutil's behavior.<br class="">
+  if ((Info.InDebugMap || AttrInfo.HasLowPc) &&<br class="">
+      Tag != dwarf::DW_TAG_compile_unit &&<br class="">
+      getDIENames(InputDIE, Unit.getOrigUnit(), AttrInfo)) {<br class="">
+    if (AttrInfo.MangledName && AttrInfo.MangledName != AttrInfo.Name)<br class="">
+      Unit.addNameAccelerator(Die, AttrInfo.MangledName,<br class="">
+                              AttrInfo.MangledNameOffset,<br class="">
+                              Tag == dwarf::DW_TAG_inlined_<u class=""></u>subroutine);<br class="">
+    if (AttrInfo.Name)<br class="">
+      Unit.addNameAccelerator(Die, AttrInfo.Name, AttrInfo.NameOffset,<br class="">
+                              Tag == dwarf::DW_TAG_inlined_<u class=""></u>subroutine);<br class="">
+  } else if (isTypeTag(Tag) && !AttrInfo.IsDeclaration &&<br class="">
+             getDIENames(InputDIE, Unit.getOrigUnit(), AttrInfo)) {<br class="">
+    Unit.addTypeAccelerator(Die, AttrInfo.Name, AttrInfo.NameOffset);<br class="">
+  }<br class="">
+<br class="">
   DIEAbbrev &NewAbbrev = Die->getAbbrev();<br class="">
   // If a scope DIE is kept, we must have kept at least one child. If<br class="">
   // it's not the case, we'll just be emitting one wasteful end of<br class="">
@@ -2218,6 +2417,11 @@ void DwarfLinker::<u class=""></u>patchLineTableForUnit(<br class="">
                                    Unit.getOrigUnit().<u class=""></u>getAddressByteSize());<br class="">
 }<br class="">
<br class="">
+void DwarfLinker::<u class=""></u>emitAcceleratorEntriesForUnit(<u class=""></u>CompileUnit &Unit) {<br class="">
+  Streamer->emitPubNamesForUnit(<u class=""></u>Unit);<br class="">
+  Streamer->emitPubTypesForUnit(<u class=""></u>Unit);<br class="">
+}<br class="">
+<br class="">
 bool DwarfLinker::link(const DebugMap &Map) {<br class="">
<br class="">
   if (Map.begin() == Map.end()) {<br class="">
@@ -2301,6 +2505,7 @@ bool DwarfLinker::link(const DebugMap &M<br class="">
           continue;<br class="">
         patchRangesForUnit(<u class=""></u>CurrentUnit, DwarfContext);<br class="">
         Streamer-><u class=""></u>emitLocationsForUnit(<u class=""></u>CurrentUnit, DwarfContext);<br class="">
+        emitAcceleratorEntriesForUnit(<u class=""></u>CurrentUnit);<br class="">
       }<br class="">
<br class="">
     // Emit all the compile unit's debug information.<br class="">
<br class="">
<br class="">
______________________________<u class=""></u>_________________<br class="">
llvm-commits mailing list<br class="">
<a href="mailto:llvm-commits@cs.uiuc.edu" target="_blank" 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/<u class=""></u>mailman/listinfo/llvm-commits</a><br class="">
</blockquote></div>
</div></blockquote></div><br class=""></body></html>