[llvm] r364225 - llvm-symbolizer: Add a FRAME command.

Peter Collingbourne via llvm-commits llvm-commits at lists.llvm.org
Mon Jun 24 13:03:24 PDT 2019


Author: pcc
Date: Mon Jun 24 13:03:23 2019
New Revision: 364225

URL: http://llvm.org/viewvc/llvm-project?rev=364225&view=rev
Log:
llvm-symbolizer: Add a FRAME command.

This command prints a description of the referenced function's stack frame.
For each formal parameter and local variable, the tool prints:

- function name
- variable name
- file/line of declaration
- FP-relative variable location (if available)
- size in bytes
- HWASAN tag offset

This information will be used by the HWASAN runtime to identify local
variables in UAR reports.

Differential Revision: https://reviews.llvm.org/D63468

Added:
    llvm/trunk/test/tools/llvm-symbolizer/frame-fortran.s
    llvm/trunk/test/tools/llvm-symbolizer/frame-types.s
    llvm/trunk/test/tools/llvm-symbolizer/frame.s
Modified:
    llvm/trunk/include/llvm/DebugInfo/DIContext.h
    llvm/trunk/include/llvm/DebugInfo/DWARF/DWARFContext.h
    llvm/trunk/include/llvm/DebugInfo/PDB/PDBContext.h
    llvm/trunk/include/llvm/DebugInfo/Symbolize/DIPrinter.h
    llvm/trunk/include/llvm/DebugInfo/Symbolize/SymbolizableModule.h
    llvm/trunk/include/llvm/DebugInfo/Symbolize/Symbolize.h
    llvm/trunk/lib/DebugInfo/DWARF/DWARFContext.cpp
    llvm/trunk/lib/DebugInfo/PDB/PDBContext.cpp
    llvm/trunk/lib/DebugInfo/Symbolize/DIPrinter.cpp
    llvm/trunk/lib/DebugInfo/Symbolize/SymbolizableObjectFile.cpp
    llvm/trunk/lib/DebugInfo/Symbolize/SymbolizableObjectFile.h
    llvm/trunk/lib/DebugInfo/Symbolize/Symbolize.cpp
    llvm/trunk/tools/llvm-symbolizer/llvm-symbolizer.cpp

Modified: llvm/trunk/include/llvm/DebugInfo/DIContext.h
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/include/llvm/DebugInfo/DIContext.h?rev=364225&r1=364224&r2=364225&view=diff
==============================================================================
--- llvm/trunk/include/llvm/DebugInfo/DIContext.h (original)
+++ llvm/trunk/include/llvm/DebugInfo/DIContext.h Mon Jun 24 13:03:23 2019
@@ -112,6 +112,16 @@ struct DIGlobal {
   DIGlobal() : Name("<invalid>") {}
 };
 
+struct DILocal {
+  std::string FunctionName;
+  std::string Name;
+  std::string DeclFile;
+  uint64_t DeclLine = 0;
+  Optional<int64_t> FrameOffset;
+  Optional<uint64_t> Size;
+  Optional<uint64_t> TagOffset;
+};
+
 /// A DINameKind is passed to name search methods to specify a
 /// preference regarding the type of name resolution the caller wants.
 enum class DINameKind { None, ShortName, LinkageName };
@@ -216,6 +226,9 @@ public:
       object::SectionedAddress Address,
       DILineInfoSpecifier Specifier = DILineInfoSpecifier()) = 0;
 
+  virtual std::vector<DILocal>
+  getLocalsForAddress(object::SectionedAddress Address) = 0;
+
 private:
   const DIContextKind Kind;
 };

Modified: llvm/trunk/include/llvm/DebugInfo/DWARF/DWARFContext.h
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/include/llvm/DebugInfo/DWARF/DWARFContext.h?rev=364225&r1=364224&r2=364225&view=diff
==============================================================================
--- llvm/trunk/include/llvm/DebugInfo/DWARF/DWARFContext.h (original)
+++ llvm/trunk/include/llvm/DebugInfo/DWARF/DWARFContext.h Mon Jun 24 13:03:23 2019
@@ -331,6 +331,9 @@ public:
       object::SectionedAddress Address,
       DILineInfoSpecifier Specifier = DILineInfoSpecifier()) override;
 
+  std::vector<DILocal>
+  getLocalsForAddress(object::SectionedAddress Address) override;
+
   bool isLittleEndian() const { return DObj->isLittleEndian(); }
   static bool isSupportedVersion(unsigned version) {
     return version == 2 || version == 3 || version == 4 || version == 5;
@@ -374,6 +377,8 @@ private:
   /// TODO: change input parameter from "uint64_t Address"
   ///       into "SectionedAddress Address"
   DWARFCompileUnit *getCompileUnitForAddress(uint64_t Address);
+  void addLocalsForDie(DWARFCompileUnit *CU, DWARFDie Subprogram, DWARFDie Die,
+                       std::vector<DILocal> &Result);
 };
 
 } // end namespace llvm

Modified: llvm/trunk/include/llvm/DebugInfo/PDB/PDBContext.h
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/include/llvm/DebugInfo/PDB/PDBContext.h?rev=364225&r1=364224&r2=364225&view=diff
==============================================================================
--- llvm/trunk/include/llvm/DebugInfo/PDB/PDBContext.h (original)
+++ llvm/trunk/include/llvm/DebugInfo/PDB/PDBContext.h Mon Jun 24 13:03:23 2019
@@ -52,6 +52,9 @@ namespace pdb {
         object::SectionedAddress Address,
         DILineInfoSpecifier Specifier = DILineInfoSpecifier()) override;
 
+    std::vector<DILocal>
+    getLocalsForAddress(object::SectionedAddress Address) override;
+
   private:
     std::string getFunctionName(uint64_t Address, DINameKind NameKind) const;
     std::unique_ptr<IPDBSession> Session;

Modified: llvm/trunk/include/llvm/DebugInfo/Symbolize/DIPrinter.h
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/include/llvm/DebugInfo/Symbolize/DIPrinter.h?rev=364225&r1=364224&r2=364225&view=diff
==============================================================================
--- llvm/trunk/include/llvm/DebugInfo/Symbolize/DIPrinter.h (original)
+++ llvm/trunk/include/llvm/DebugInfo/Symbolize/DIPrinter.h Mon Jun 24 13:03:23 2019
@@ -20,6 +20,7 @@ namespace llvm {
 struct DILineInfo;
 class DIInliningInfo;
 struct DIGlobal;
+struct DILocal;
 
 namespace symbolize {
 
@@ -51,6 +52,7 @@ public:
   DIPrinter &operator<<(const DILineInfo &Info);
   DIPrinter &operator<<(const DIInliningInfo &Info);
   DIPrinter &operator<<(const DIGlobal &Global);
+  DIPrinter &operator<<(const DILocal &Local);
 };
 }
 }

Modified: llvm/trunk/include/llvm/DebugInfo/Symbolize/SymbolizableModule.h
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/include/llvm/DebugInfo/Symbolize/SymbolizableModule.h?rev=364225&r1=364224&r2=364225&view=diff
==============================================================================
--- llvm/trunk/include/llvm/DebugInfo/Symbolize/SymbolizableModule.h (original)
+++ llvm/trunk/include/llvm/DebugInfo/Symbolize/SymbolizableModule.h Mon Jun 24 13:03:23 2019
@@ -32,6 +32,8 @@ public:
                        FunctionNameKind FNKind, bool UseSymbolTable) const = 0;
   virtual DIGlobal
   symbolizeData(object::SectionedAddress ModuleOffset) const = 0;
+  virtual std::vector<DILocal>
+  symbolizeFrame(object::SectionedAddress ModuleOffset) const = 0;
 
   // Return true if this is a 32-bit x86 PE COFF module.
   virtual bool isWin32Module() const = 0;

Modified: llvm/trunk/include/llvm/DebugInfo/Symbolize/Symbolize.h
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/include/llvm/DebugInfo/Symbolize/Symbolize.h?rev=364225&r1=364224&r2=364225&view=diff
==============================================================================
--- llvm/trunk/include/llvm/DebugInfo/Symbolize/Symbolize.h (original)
+++ llvm/trunk/include/llvm/DebugInfo/Symbolize/Symbolize.h Mon Jun 24 13:03:23 2019
@@ -59,6 +59,9 @@ public:
                        object::SectionedAddress ModuleOffset);
   Expected<DIGlobal> symbolizeData(const std::string &ModuleName,
                                    object::SectionedAddress ModuleOffset);
+  Expected<std::vector<DILocal>>
+  symbolizeFrame(const std::string &ModuleName,
+                 object::SectionedAddress ModuleOffset);
   void flush();
 
   static std::string

Modified: llvm/trunk/lib/DebugInfo/DWARF/DWARFContext.cpp
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/DebugInfo/DWARF/DWARFContext.cpp?rev=364225&r1=364224&r2=364225&view=diff
==============================================================================
--- llvm/trunk/lib/DebugInfo/DWARF/DWARFContext.cpp (original)
+++ llvm/trunk/lib/DebugInfo/DWARF/DWARFContext.cpp Mon Jun 24 13:03:23 2019
@@ -41,6 +41,7 @@
 #include "llvm/Support/DataExtractor.h"
 #include "llvm/Support/Error.h"
 #include "llvm/Support/Format.h"
+#include "llvm/Support/LEB128.h"
 #include "llvm/Support/MemoryBuffer.h"
 #include "llvm/Support/Path.h"
 #include "llvm/Support/TargetRegistry.h"
@@ -972,6 +973,124 @@ static bool getFunctionNameAndStartLineF
   return FoundResult;
 }
 
+static Optional<uint64_t> getTypeSize(DWARFDie Type, uint64_t PointerSize) {
+  if (auto SizeAttr = Type.find(DW_AT_byte_size))
+    if (Optional<uint64_t> Size = SizeAttr->getAsUnsignedConstant())
+      return Size;
+
+  switch (Type.getTag()) {
+  case DW_TAG_pointer_type:
+  case DW_TAG_reference_type:
+  case DW_TAG_rvalue_reference_type:
+    return PointerSize;
+  case DW_TAG_ptr_to_member_type: {
+    if (DWARFDie BaseType = Type.getAttributeValueAsReferencedDie(DW_AT_type))
+      if (BaseType.getTag() == DW_TAG_subroutine_type)
+        return 2 * PointerSize;
+    return PointerSize;
+  }
+  case DW_TAG_const_type:
+  case DW_TAG_volatile_type:
+  case DW_TAG_restrict_type:
+  case DW_TAG_typedef: {
+    if (DWARFDie BaseType = Type.getAttributeValueAsReferencedDie(DW_AT_type))
+      return getTypeSize(BaseType, PointerSize);
+    break;
+  }
+  case DW_TAG_array_type: {
+    DWARFDie BaseType = Type.getAttributeValueAsReferencedDie(DW_AT_type);
+    if (!BaseType)
+      return Optional<uint64_t>();
+    Optional<uint64_t> BaseSize = getTypeSize(BaseType, PointerSize);
+    if (!BaseSize)
+      return Optional<uint64_t>();
+    uint64_t Size = *BaseSize;
+    for (DWARFDie Child : Type) {
+      if (Child.getTag() != DW_TAG_subrange_type)
+        continue;
+
+      if (auto ElemCountAttr = Child.find(DW_AT_count))
+        if (Optional<uint64_t> ElemCount =
+                ElemCountAttr->getAsUnsignedConstant())
+          Size *= *ElemCount;
+      if (auto UpperBoundAttr = Child.find(DW_AT_upper_bound))
+        if (Optional<int64_t> UpperBound =
+                UpperBoundAttr->getAsSignedConstant()) {
+          int64_t LowerBound = 0;
+          if (auto LowerBoundAttr = Child.find(DW_AT_lower_bound))
+            LowerBound = LowerBoundAttr->getAsSignedConstant().getValueOr(0);
+          Size *= *UpperBound - LowerBound + 1;
+        }
+    }
+    return Size;
+  }
+  default:
+    break;
+  }
+  return Optional<uint64_t>();
+}
+
+void DWARFContext::addLocalsForDie(DWARFCompileUnit *CU, DWARFDie Subprogram,
+                                   DWARFDie Die, std::vector<DILocal> &Result) {
+  if (Die.getTag() == DW_TAG_variable ||
+      Die.getTag() == DW_TAG_formal_parameter) {
+    DILocal Local;
+    if (auto NameAttr = Subprogram.find(DW_AT_name))
+      if (Optional<const char *> Name = NameAttr->getAsCString())
+        Local.FunctionName = *Name;
+    if (auto LocationAttr = Die.find(DW_AT_location))
+      if (Optional<ArrayRef<uint8_t>> Location = LocationAttr->getAsBlock())
+        if (!Location->empty() && (*Location)[0] == DW_OP_fbreg)
+          Local.FrameOffset =
+              decodeSLEB128(Location->data() + 1, nullptr, Location->end());
+    if (auto TagOffsetAttr = Die.find(DW_AT_LLVM_tag_offset))
+      Local.TagOffset = TagOffsetAttr->getAsUnsignedConstant();
+
+    if (auto Origin =
+            Die.getAttributeValueAsReferencedDie(DW_AT_abstract_origin))
+      Die = Origin;
+    if (auto NameAttr = Die.find(DW_AT_name))
+      if (Optional<const char *> Name = NameAttr->getAsCString())
+        Local.Name = *Name;
+    if (auto Type = Die.getAttributeValueAsReferencedDie(DW_AT_type))
+      Local.Size = getTypeSize(Type, getCUAddrSize());
+    if (auto DeclFileAttr = Die.find(DW_AT_decl_file)) {
+      if (const auto *LT = CU->getContext().getLineTableForUnit(CU))
+        LT->getFileNameByIndex(
+            DeclFileAttr->getAsUnsignedConstant().getValue(),
+            CU->getCompilationDir(),
+            DILineInfoSpecifier::FileLineInfoKind::AbsoluteFilePath,
+            Local.DeclFile);
+    }
+    if (auto DeclLineAttr = Die.find(DW_AT_decl_line))
+      Local.DeclLine = DeclLineAttr->getAsUnsignedConstant().getValue();
+
+    Result.push_back(Local);
+    return;
+  }
+
+  if (Die.getTag() == DW_TAG_inlined_subroutine)
+    if (auto Origin =
+            Die.getAttributeValueAsReferencedDie(DW_AT_abstract_origin))
+      Subprogram = Origin;
+
+  for (auto Child : Die)
+    addLocalsForDie(CU, Subprogram, Child, Result);
+}
+
+std::vector<DILocal>
+DWARFContext::getLocalsForAddress(object::SectionedAddress Address) {
+  std::vector<DILocal> Result;
+  DWARFCompileUnit *CU = getCompileUnitForAddress(Address.Address);
+  if (!CU)
+    return Result;
+
+  DWARFDie Subprogram = CU->getSubroutineForAddress(Address.Address);
+  if (Subprogram.isValid())
+    addLocalsForDie(CU, Subprogram, Subprogram, Result);
+  return Result;
+}
+
 DILineInfo DWARFContext::getLineInfoForAddress(object::SectionedAddress Address,
                                                DILineInfoSpecifier Spec) {
   DILineInfo Result;

Modified: llvm/trunk/lib/DebugInfo/PDB/PDBContext.cpp
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/DebugInfo/PDB/PDBContext.cpp?rev=364225&r1=364224&r2=364225&view=diff
==============================================================================
--- llvm/trunk/lib/DebugInfo/PDB/PDBContext.cpp (original)
+++ llvm/trunk/lib/DebugInfo/PDB/PDBContext.cpp Mon Jun 24 13:03:23 2019
@@ -91,6 +91,11 @@ PDBContext::getInliningInfoForAddress(ob
   return InlineInfo;
 }
 
+std::vector<DILocal>
+PDBContext::getLocalsForAddress(object::SectionedAddress Address) {
+  return std::vector<DILocal>();
+}
+
 std::string PDBContext::getFunctionName(uint64_t Address,
                                         DINameKind NameKind) const {
   if (NameKind == DINameKind::None)

Modified: llvm/trunk/lib/DebugInfo/Symbolize/DIPrinter.cpp
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/DebugInfo/Symbolize/DIPrinter.cpp?rev=364225&r1=364224&r2=364225&view=diff
==============================================================================
--- llvm/trunk/lib/DebugInfo/Symbolize/DIPrinter.cpp (original)
+++ llvm/trunk/lib/DebugInfo/Symbolize/DIPrinter.cpp Mon Jun 24 13:03:23 2019
@@ -122,5 +122,28 @@ DIPrinter &DIPrinter::operator<<(const D
   return *this;
 }
 
+DIPrinter &DIPrinter::operator<<(const DILocal &Local) {
+  OS << Local.FunctionName << '\n';
+  OS << Local.Name << '\n';
+  if (Local.DeclFile.empty())
+    OS << "??";
+  else
+    OS << Local.DeclFile;
+  OS << ':' << Local.DeclLine << '\n';
+  if (Local.FrameOffset)
+    OS << *Local.FrameOffset << ' ';
+  else
+    OS << "?? ";
+  if (Local.Size)
+    OS << *Local.Size << ' ';
+  else
+    OS << "?? ";
+  if (Local.TagOffset)
+    OS << *Local.TagOffset << '\n';
+  else
+    OS << "??\n";
+  return *this;
+}
+
 } // end namespace symbolize
 } // end namespace llvm

Modified: llvm/trunk/lib/DebugInfo/Symbolize/SymbolizableObjectFile.cpp
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/DebugInfo/Symbolize/SymbolizableObjectFile.cpp?rev=364225&r1=364224&r2=364225&view=diff
==============================================================================
--- llvm/trunk/lib/DebugInfo/Symbolize/SymbolizableObjectFile.cpp (original)
+++ llvm/trunk/lib/DebugInfo/Symbolize/SymbolizableObjectFile.cpp Mon Jun 24 13:03:23 2019
@@ -298,6 +298,14 @@ DIGlobal SymbolizableObjectFile::symboli
   return Res;
 }
 
+std::vector<DILocal> SymbolizableObjectFile::symbolizeFrame(
+    object::SectionedAddress ModuleOffset) const {
+  if (ModuleOffset.SectionIndex == object::SectionedAddress::UndefSection)
+    ModuleOffset.SectionIndex =
+        getModuleSectionIndexForAddress(ModuleOffset.Address);
+  return DebugInfoContext->getLocalsForAddress(ModuleOffset);
+}
+
 /// Search for the first occurence of specified Address in ObjectFile.
 uint64_t SymbolizableObjectFile::getModuleSectionIndexForAddress(
     uint64_t Address) const {

Modified: llvm/trunk/lib/DebugInfo/Symbolize/SymbolizableObjectFile.h
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/DebugInfo/Symbolize/SymbolizableObjectFile.h?rev=364225&r1=364224&r2=364225&view=diff
==============================================================================
--- llvm/trunk/lib/DebugInfo/Symbolize/SymbolizableObjectFile.h (original)
+++ llvm/trunk/lib/DebugInfo/Symbolize/SymbolizableObjectFile.h Mon Jun 24 13:03:23 2019
@@ -40,6 +40,8 @@ public:
                                       FunctionNameKind FNKind,
                                       bool UseSymbolTable) const override;
   DIGlobal symbolizeData(object::SectionedAddress ModuleOffset) const override;
+  std::vector<DILocal>
+  symbolizeFrame(object::SectionedAddress ModuleOffset) const override;
 
   // Return true if this is a 32-bit x86 PE COFF module.
   bool isWin32Module() const override;

Modified: llvm/trunk/lib/DebugInfo/Symbolize/Symbolize.cpp
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/DebugInfo/Symbolize/Symbolize.cpp?rev=364225&r1=364224&r2=364225&view=diff
==============================================================================
--- llvm/trunk/lib/DebugInfo/Symbolize/Symbolize.cpp (original)
+++ llvm/trunk/lib/DebugInfo/Symbolize/Symbolize.cpp Mon Jun 24 13:03:23 2019
@@ -133,6 +133,29 @@ LLVMSymbolizer::symbolizeData(const std:
   return Global;
 }
 
+Expected<std::vector<DILocal>>
+LLVMSymbolizer::symbolizeFrame(const std::string &ModuleName,
+                               object::SectionedAddress ModuleOffset) {
+  SymbolizableModule *Info;
+  if (auto InfoOrErr = getOrCreateModuleInfo(ModuleName))
+    Info = InfoOrErr.get();
+  else
+    return InfoOrErr.takeError();
+
+  // A null module means an error has already been reported. Return an empty
+  // result.
+  if (!Info)
+    return std::vector<DILocal>();
+
+  // If the user is giving us relative addresses, add the preferred base of
+  // the object to the offset before we do the query. It's what DIContext
+  // expects.
+  if (Opts.RelativeAddresses)
+    ModuleOffset.Address += Info->getModulePreferredBase();
+
+  return Info->symbolizeFrame(ModuleOffset);
+}
+
 void LLVMSymbolizer::flush() {
   ObjectForUBPathAndArch.clear();
   BinaryForPath.clear();

Added: llvm/trunk/test/tools/llvm-symbolizer/frame-fortran.s
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/test/tools/llvm-symbolizer/frame-fortran.s?rev=364225&view=auto
==============================================================================
--- llvm/trunk/test/tools/llvm-symbolizer/frame-fortran.s (added)
+++ llvm/trunk/test/tools/llvm-symbolizer/frame-fortran.s Mon Jun 24 13:03:23 2019
@@ -0,0 +1,230 @@
+// REQUIRES: x86-registered-target
+
+// RUN: llvm-mc -filetype=obj -triple=x86_64-linux-gnu -o %t.o %s
+// RUN: echo 'FRAME %t.o 0' | llvm-symbolizer | FileCheck %s
+
+// Generated with:
+//
+// function foo(array)
+//   integer, intent(in), dimension(2:3) :: array
+// end function foo
+//
+// gcc -x f95 -g -S
+
+// CHECK: foo
+// CHECK-NEXT: array
+// CHECK-NEXT: /home/ubuntu/./example.cpp:1
+// CHECK-NEXT: -24 8 ??
+
+        .file   "example.cpp"
+        .text
+.Ltext0:
+        .globl  foo_
+        .type   foo_, @function
+foo_:
+.LFB0:
+        .file 1 "./example.cpp"
+        .loc 1 1 0
+        .cfi_startproc
+        pushq   %rbp
+        .cfi_def_cfa_offset 16
+        .cfi_offset 6, -16
+        movq    %rsp, %rbp
+        .cfi_def_cfa_register 6
+        movq    %rdi, -8(%rbp)
+        .loc 1 3 0
+        nop
+        popq    %rbp
+        .cfi_def_cfa 7, 8
+        ret
+        .cfi_endproc
+.LFE0:
+        .size   foo_, .-foo_
+.Letext0:
+        .section        .debug_info,"", at progbits
+.Ldebug_info0:
+        .long   0x86
+        .value  0x4
+        .long   .Ldebug_abbrev0
+        .byte   0x8
+        .uleb128 0x1
+        .long   .LASF3
+        .byte   0xe
+        .byte   0x2
+        .long   .LASF4
+        .long   .LASF5
+        .quad   .Ltext0
+        .quad   .Letext0-.Ltext0
+        .long   .Ldebug_line0
+        .uleb128 0x2
+        .string "foo"
+        .byte   0x1
+        .byte   0x1
+        .long   .LASF6
+        .long   0x63
+        .quad   .LFB0
+        .quad   .LFE0-.LFB0
+        .uleb128 0x1
+        .byte   0x9c
+        .long   0x63
+        .uleb128 0x3
+        .long   .LASF7
+        .byte   0x1
+        .byte   0x1
+        .long   0x6a
+        .uleb128 0x3
+        .byte   0x91
+        .sleb128 -24
+        .byte   0x6
+        .byte   0
+        .uleb128 0x4
+        .byte   0x4
+        .byte   0x4
+        .long   .LASF0
+        .uleb128 0x5
+        .long   0x82
+        .long   0x7b
+        .uleb128 0x6
+        .long   0x7b
+        .sleb128 2
+        .sleb128 3
+        .byte   0
+        .uleb128 0x4
+        .byte   0x8
+        .byte   0x5
+        .long   .LASF1
+        .uleb128 0x4
+        .byte   0x4
+        .byte   0x5
+        .long   .LASF2
+        .byte   0
+        .section        .debug_abbrev,"", at progbits
+.Ldebug_abbrev0:
+        .uleb128 0x1
+        .uleb128 0x11
+        .byte   0x1
+        .uleb128 0x25
+        .uleb128 0xe
+        .uleb128 0x13
+        .uleb128 0xb
+        .uleb128 0x42
+        .uleb128 0xb
+        .uleb128 0x3
+        .uleb128 0xe
+        .uleb128 0x1b
+        .uleb128 0xe
+        .uleb128 0x11
+        .uleb128 0x1
+        .uleb128 0x12
+        .uleb128 0x7
+        .uleb128 0x10
+        .uleb128 0x17
+        .byte   0
+        .byte   0
+        .uleb128 0x2
+        .uleb128 0x2e
+        .byte   0x1
+        .uleb128 0x3f
+        .uleb128 0x19
+        .uleb128 0x3
+        .uleb128 0x8
+        .uleb128 0x3a
+        .uleb128 0xb
+        .uleb128 0x3b
+        .uleb128 0xb
+        .uleb128 0x6e
+        .uleb128 0xe
+        .uleb128 0x49
+        .uleb128 0x13
+        .uleb128 0x11
+        .uleb128 0x1
+        .uleb128 0x12
+        .uleb128 0x7
+        .uleb128 0x40
+        .uleb128 0x18
+        .uleb128 0x2117
+        .uleb128 0x19
+        .uleb128 0x1
+        .uleb128 0x13
+        .byte   0
+        .byte   0
+        .uleb128 0x3
+        .uleb128 0x5
+        .byte   0
+        .uleb128 0x3
+        .uleb128 0xe
+        .uleb128 0x3a
+        .uleb128 0xb
+        .uleb128 0x3b
+        .uleb128 0xb
+        .uleb128 0x49
+        .uleb128 0x13
+        .uleb128 0x2
+        .uleb128 0x18
+        .byte   0
+        .byte   0
+        .uleb128 0x4
+        .uleb128 0x24
+        .byte   0
+        .uleb128 0xb
+        .uleb128 0xb
+        .uleb128 0x3e
+        .uleb128 0xb
+        .uleb128 0x3
+        .uleb128 0xe
+        .byte   0
+        .byte   0
+        .uleb128 0x5
+        .uleb128 0x1
+        .byte   0x1
+        .uleb128 0x49
+        .uleb128 0x13
+        .uleb128 0x1
+        .uleb128 0x13
+        .byte   0
+        .byte   0
+        .uleb128 0x6
+        .uleb128 0x21
+        .byte   0
+        .uleb128 0x49
+        .uleb128 0x13
+        .uleb128 0x22
+        .uleb128 0xd
+        .uleb128 0x2f
+        .uleb128 0xd
+        .byte   0
+        .byte   0
+        .byte   0
+        .section        .debug_aranges,"", at progbits
+        .long   0x2c
+        .value  0x2
+        .long   .Ldebug_info0
+        .byte   0x8
+        .byte   0
+        .value  0
+        .value  0
+        .quad   .Ltext0
+        .quad   .Letext0-.Ltext0
+        .quad   0
+        .quad   0
+        .section        .debug_line,"", at progbits
+.Ldebug_line0:
+        .section        .debug_str,"MS", at progbits,1
+.LASF5:
+        .string "/home/ubuntu"
+.LASF7:
+        .string "array"
+.LASF0:
+        .string "real(kind=4)"
+.LASF2:
+        .string "integer(kind=4)"
+.LASF6:
+        .string "foo_"
+.LASF1:
+        .string "integer(kind=8)"
+.LASF3:
+        .string "GNU Fortran2008 9.1.0 -mtune=generic -march=x86-64 -g -g -fintrinsic-modules-path /opt/compiler-explorer/gcc-9.1.0/bin/../lib/gcc/x86_64-linux-gnu/9.1.0/finclude"
+.LASF4:
+        .string "./example.cpp"
+        .ident  "GCC: (Compiler-Explorer-Build) 9.1.0"
+        .section        .note.GNU-stack,"", at progbits

Added: llvm/trunk/test/tools/llvm-symbolizer/frame-types.s
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/test/tools/llvm-symbolizer/frame-types.s?rev=364225&view=auto
==============================================================================
--- llvm/trunk/test/tools/llvm-symbolizer/frame-types.s (added)
+++ llvm/trunk/test/tools/llvm-symbolizer/frame-types.s Mon Jun 24 13:03:23 2019
@@ -0,0 +1,532 @@
+// REQUIRES: x86-registered-target
+
+// RUN: llvm-mc -filetype=obj -triple=i386-linux-gnu -o %t.o %s
+// RUN: echo 'FRAME %t.o 0' | llvm-symbolizer | FileCheck %s
+
+// CHECK: f
+// CHECK-NEXT: a
+// CHECK-NEXT: /tmp/frame-types.cpp:4
+// CHECK-NEXT: -1 1 ??
+// CHECK-NEXT: f
+// CHECK-NEXT: b
+// CHECK-NEXT: /tmp/frame-types.cpp:5
+// CHECK-NEXT: -8 4 ??
+// CHECK-NEXT: f
+// CHECK-NEXT: c
+// CHECK-NEXT: /tmp/frame-types.cpp:6
+// CHECK-NEXT: -12 4 ??
+// CHECK-NEXT: f
+// CHECK-NEXT: d
+// CHECK-NEXT: /tmp/frame-types.cpp:7
+// CHECK-NEXT: -16 4 ??
+// CHECK-NEXT: f
+// CHECK-NEXT: e
+// CHECK-NEXT: /tmp/frame-types.cpp:8
+// CHECK-NEXT: -32 8 ??
+// CHECK-NEXT: f
+// CHECK-NEXT: f
+// CHECK-NEXT: /tmp/frame-types.cpp:9
+// CHECK-NEXT: -36 4 ??
+// CHECK-NEXT: f
+// CHECK-NEXT: g
+// CHECK-NEXT: /tmp/frame-types.cpp:10
+// CHECK-NEXT: -37 1 ??
+// CHECK-NEXT: f
+// CHECK-NEXT: h
+// CHECK-NEXT: /tmp/frame-types.cpp:11
+// CHECK-NEXT: -38 1 ??
+// CHECK-NEXT: f
+// CHECK-NEXT: i
+// CHECK-NEXT: /tmp/frame-types.cpp:12
+// CHECK-NEXT: -44 4 ??
+// CHECK-NEXT: f
+// CHECK-NEXT: j
+// CHECK-NEXT: /tmp/frame-types.cpp:14
+// CHECK-NEXT: -45 1 ??
+// CHECK-NEXT: f
+// CHECK-NEXT: k
+// CHECK-NEXT: /tmp/frame-types.cpp:15
+// CHECK-NEXT: -57 12 ??
+// CHECK-NEXT: f
+// CHECK-NEXT: l
+// CHECK-NEXT: /tmp/frame-types.cpp:16
+// CHECK-NEXT: -345 288 ??
+
+// Generated from:
+//
+// struct S;
+//
+// void f() {
+//   char a;
+//   char *b;
+//   char &c = a;
+//   char &&d = 1;
+//   char (S::*e)();
+//   char S::*f;
+//   const char g = 2;
+//   volatile char h;
+//   char *__restrict i;
+//   typedef char char_typedef;
+//   char_typedef j;
+//   char k[12];
+//   char l[12][24];
+// }
+//
+// clang++ --target=i386-linux-gnu frame-types.cpp -g -std=c++11 -S -o frame-types.s 
+
+	.text
+	.file	"frame-types.cpp"
+	.globl	_Z1fv                   # -- Begin function _Z1fv
+	.p2align	4, 0x90
+	.type	_Z1fv, at function
+_Z1fv:                                  # @_Z1fv
+.Lfunc_begin0:
+	.file	1 "/tmp" "frame-types.cpp"
+	.loc	1 3 0                   # frame-types.cpp:3:0
+	.cfi_sections .debug_frame
+	.cfi_startproc
+# %bb.0:                                # %entry
+	pushl	%ebp
+	.cfi_def_cfa_offset 8
+	.cfi_offset %ebp, -8
+	movl	%esp, %ebp
+	.cfi_def_cfa_register %ebp
+	subl	$352, %esp              # imm = 0x160
+.Ltmp0:
+	.loc	1 6 9 prologue_end      # frame-types.cpp:6:9
+	leal	-1(%ebp), %eax
+.Ltmp1:
+	#DEBUG_VALUE: f:a <- [$eax+0]
+	movl	%eax, -12(%ebp)
+	.loc	1 7 14                  # frame-types.cpp:7:14
+	movb	$1, -17(%ebp)
+	.loc	1 7 10 is_stmt 0        # frame-types.cpp:7:10
+	leal	-17(%ebp), %eax
+.Ltmp2:
+	movl	%eax, -16(%ebp)
+	.loc	1 10 14 is_stmt 1       # frame-types.cpp:10:14
+	movb	$2, -37(%ebp)
+	.loc	1 17 1                  # frame-types.cpp:17:1
+	addl	$352, %esp              # imm = 0x160
+	popl	%ebp
+	.cfi_def_cfa %esp, 4
+	retl
+.Ltmp3:
+.Lfunc_end0:
+	.size	_Z1fv, .Lfunc_end0-_Z1fv
+	.cfi_endproc
+                                        # -- End function
+	.section	.debug_str,"MS", at progbits,1
+.Linfo_string0:
+	.asciz	"clang version 9.0.0 "  # string offset=0
+.Linfo_string1:
+	.asciz	"frame-types.cpp"       # string offset=21
+.Linfo_string2:
+	.asciz	"/tmp"                  # string offset=37
+.Linfo_string3:
+	.asciz	"_Z1fv"                 # string offset=42
+.Linfo_string4:
+	.asciz	"f"                     # string offset=48
+.Linfo_string5:
+	.asciz	"a"                     # string offset=50
+.Linfo_string6:
+	.asciz	"char"                  # string offset=52
+.Linfo_string7:
+	.asciz	"b"                     # string offset=57
+.Linfo_string8:
+	.asciz	"c"                     # string offset=59
+.Linfo_string9:
+	.asciz	"d"                     # string offset=61
+.Linfo_string10:
+	.asciz	"e"                     # string offset=63
+.Linfo_string11:
+	.asciz	"S"                     # string offset=65
+.Linfo_string12:
+	.asciz	"g"                     # string offset=67
+.Linfo_string13:
+	.asciz	"h"                     # string offset=69
+.Linfo_string14:
+	.asciz	"i"                     # string offset=71
+.Linfo_string15:
+	.asciz	"j"                     # string offset=73
+.Linfo_string16:
+	.asciz	"char_typedef"          # string offset=75
+.Linfo_string17:
+	.asciz	"k"                     # string offset=88
+.Linfo_string18:
+	.asciz	"__ARRAY_SIZE_TYPE__"   # string offset=90
+.Linfo_string19:
+	.asciz	"l"                     # string offset=110
+	.section	.debug_abbrev,"", at progbits
+	.byte	1                       # Abbreviation Code
+	.byte	17                      # DW_TAG_compile_unit
+	.byte	1                       # DW_CHILDREN_yes
+	.byte	37                      # DW_AT_producer
+	.byte	14                      # DW_FORM_strp
+	.byte	19                      # DW_AT_language
+	.byte	5                       # DW_FORM_data2
+	.byte	3                       # DW_AT_name
+	.byte	14                      # DW_FORM_strp
+	.byte	16                      # DW_AT_stmt_list
+	.byte	23                      # DW_FORM_sec_offset
+	.byte	27                      # DW_AT_comp_dir
+	.byte	14                      # DW_FORM_strp
+	.byte	17                      # DW_AT_low_pc
+	.byte	1                       # DW_FORM_addr
+	.byte	18                      # DW_AT_high_pc
+	.byte	6                       # DW_FORM_data4
+	.byte	0                       # EOM(1)
+	.byte	0                       # EOM(2)
+	.byte	2                       # Abbreviation Code
+	.byte	46                      # DW_TAG_subprogram
+	.byte	1                       # DW_CHILDREN_yes
+	.byte	17                      # DW_AT_low_pc
+	.byte	1                       # DW_FORM_addr
+	.byte	18                      # DW_AT_high_pc
+	.byte	6                       # DW_FORM_data4
+	.byte	64                      # DW_AT_frame_base
+	.byte	24                      # DW_FORM_exprloc
+	.byte	110                     # DW_AT_linkage_name
+	.byte	14                      # DW_FORM_strp
+	.byte	3                       # DW_AT_name
+	.byte	14                      # DW_FORM_strp
+	.byte	58                      # DW_AT_decl_file
+	.byte	11                      # DW_FORM_data1
+	.byte	59                      # DW_AT_decl_line
+	.byte	11                      # DW_FORM_data1
+	.byte	63                      # DW_AT_external
+	.byte	25                      # DW_FORM_flag_present
+	.byte	0                       # EOM(1)
+	.byte	0                       # EOM(2)
+	.byte	3                       # Abbreviation Code
+	.byte	52                      # DW_TAG_variable
+	.byte	0                       # DW_CHILDREN_no
+	.byte	2                       # DW_AT_location
+	.byte	24                      # DW_FORM_exprloc
+	.byte	3                       # DW_AT_name
+	.byte	14                      # DW_FORM_strp
+	.byte	58                      # DW_AT_decl_file
+	.byte	11                      # DW_FORM_data1
+	.byte	59                      # DW_AT_decl_line
+	.byte	11                      # DW_FORM_data1
+	.byte	73                      # DW_AT_type
+	.byte	19                      # DW_FORM_ref4
+	.byte	0                       # EOM(1)
+	.byte	0                       # EOM(2)
+	.byte	4                       # Abbreviation Code
+	.byte	22                      # DW_TAG_typedef
+	.byte	0                       # DW_CHILDREN_no
+	.byte	73                      # DW_AT_type
+	.byte	19                      # DW_FORM_ref4
+	.byte	3                       # DW_AT_name
+	.byte	14                      # DW_FORM_strp
+	.byte	58                      # DW_AT_decl_file
+	.byte	11                      # DW_FORM_data1
+	.byte	59                      # DW_AT_decl_line
+	.byte	11                      # DW_FORM_data1
+	.byte	0                       # EOM(1)
+	.byte	0                       # EOM(2)
+	.byte	5                       # Abbreviation Code
+	.byte	36                      # DW_TAG_base_type
+	.byte	0                       # DW_CHILDREN_no
+	.byte	3                       # DW_AT_name
+	.byte	14                      # DW_FORM_strp
+	.byte	62                      # DW_AT_encoding
+	.byte	11                      # DW_FORM_data1
+	.byte	11                      # DW_AT_byte_size
+	.byte	11                      # DW_FORM_data1
+	.byte	0                       # EOM(1)
+	.byte	0                       # EOM(2)
+	.byte	6                       # Abbreviation Code
+	.byte	15                      # DW_TAG_pointer_type
+	.byte	0                       # DW_CHILDREN_no
+	.byte	73                      # DW_AT_type
+	.byte	19                      # DW_FORM_ref4
+	.byte	0                       # EOM(1)
+	.byte	0                       # EOM(2)
+	.byte	7                       # Abbreviation Code
+	.byte	16                      # DW_TAG_reference_type
+	.byte	0                       # DW_CHILDREN_no
+	.byte	73                      # DW_AT_type
+	.byte	19                      # DW_FORM_ref4
+	.byte	0                       # EOM(1)
+	.byte	0                       # EOM(2)
+	.byte	8                       # Abbreviation Code
+	.byte	66                      # DW_TAG_rvalue_reference_type
+	.byte	0                       # DW_CHILDREN_no
+	.byte	73                      # DW_AT_type
+	.byte	19                      # DW_FORM_ref4
+	.byte	0                       # EOM(1)
+	.byte	0                       # EOM(2)
+	.byte	9                       # Abbreviation Code
+	.byte	31                      # DW_TAG_ptr_to_member_type
+	.byte	0                       # DW_CHILDREN_no
+	.byte	73                      # DW_AT_type
+	.byte	19                      # DW_FORM_ref4
+	.byte	29                      # DW_AT_containing_type
+	.byte	19                      # DW_FORM_ref4
+	.byte	0                       # EOM(1)
+	.byte	0                       # EOM(2)
+	.byte	10                      # Abbreviation Code
+	.byte	21                      # DW_TAG_subroutine_type
+	.byte	1                       # DW_CHILDREN_yes
+	.byte	73                      # DW_AT_type
+	.byte	19                      # DW_FORM_ref4
+	.byte	0                       # EOM(1)
+	.byte	0                       # EOM(2)
+	.byte	11                      # Abbreviation Code
+	.byte	5                       # DW_TAG_formal_parameter
+	.byte	0                       # DW_CHILDREN_no
+	.byte	73                      # DW_AT_type
+	.byte	19                      # DW_FORM_ref4
+	.byte	52                      # DW_AT_artificial
+	.byte	25                      # DW_FORM_flag_present
+	.byte	0                       # EOM(1)
+	.byte	0                       # EOM(2)
+	.byte	12                      # Abbreviation Code
+	.byte	19                      # DW_TAG_structure_type
+	.byte	0                       # DW_CHILDREN_no
+	.byte	3                       # DW_AT_name
+	.byte	14                      # DW_FORM_strp
+	.byte	60                      # DW_AT_declaration
+	.byte	25                      # DW_FORM_flag_present
+	.byte	0                       # EOM(1)
+	.byte	0                       # EOM(2)
+	.byte	13                      # Abbreviation Code
+	.byte	38                      # DW_TAG_const_type
+	.byte	0                       # DW_CHILDREN_no
+	.byte	73                      # DW_AT_type
+	.byte	19                      # DW_FORM_ref4
+	.byte	0                       # EOM(1)
+	.byte	0                       # EOM(2)
+	.byte	14                      # Abbreviation Code
+	.byte	53                      # DW_TAG_volatile_type
+	.byte	0                       # DW_CHILDREN_no
+	.byte	73                      # DW_AT_type
+	.byte	19                      # DW_FORM_ref4
+	.byte	0                       # EOM(1)
+	.byte	0                       # EOM(2)
+	.byte	15                      # Abbreviation Code
+	.byte	55                      # DW_TAG_restrict_type
+	.byte	0                       # DW_CHILDREN_no
+	.byte	73                      # DW_AT_type
+	.byte	19                      # DW_FORM_ref4
+	.byte	0                       # EOM(1)
+	.byte	0                       # EOM(2)
+	.byte	16                      # Abbreviation Code
+	.byte	1                       # DW_TAG_array_type
+	.byte	1                       # DW_CHILDREN_yes
+	.byte	73                      # DW_AT_type
+	.byte	19                      # DW_FORM_ref4
+	.byte	0                       # EOM(1)
+	.byte	0                       # EOM(2)
+	.byte	17                      # Abbreviation Code
+	.byte	33                      # DW_TAG_subrange_type
+	.byte	0                       # DW_CHILDREN_no
+	.byte	73                      # DW_AT_type
+	.byte	19                      # DW_FORM_ref4
+	.byte	55                      # DW_AT_count
+	.byte	11                      # DW_FORM_data1
+	.byte	0                       # EOM(1)
+	.byte	0                       # EOM(2)
+	.byte	18                      # Abbreviation Code
+	.byte	36                      # DW_TAG_base_type
+	.byte	0                       # DW_CHILDREN_no
+	.byte	3                       # DW_AT_name
+	.byte	14                      # DW_FORM_strp
+	.byte	11                      # DW_AT_byte_size
+	.byte	11                      # DW_FORM_data1
+	.byte	62                      # DW_AT_encoding
+	.byte	11                      # DW_FORM_data1
+	.byte	0                       # EOM(1)
+	.byte	0                       # EOM(2)
+	.byte	0                       # EOM(3)
+	.section	.debug_info,"", at progbits
+.Lcu_begin0:
+	.long	.Ldebug_info_end0-.Ldebug_info_start0 # Length of Unit
+.Ldebug_info_start0:
+	.short	4                       # DWARF version number
+	.long	.debug_abbrev           # Offset Into Abbrev. Section
+	.byte	4                       # Address Size (in bytes)
+	.byte	1                       # Abbrev [1] 0xb:0x157 DW_TAG_compile_unit
+	.long	.Linfo_string0          # DW_AT_producer
+	.short	4                       # DW_AT_language
+	.long	.Linfo_string1          # DW_AT_name
+	.long	.Lline_table_start0     # DW_AT_stmt_list
+	.long	.Linfo_string2          # DW_AT_comp_dir
+	.long	.Lfunc_begin0           # DW_AT_low_pc
+	.long	.Lfunc_end0-.Lfunc_begin0 # DW_AT_high_pc
+	.byte	2                       # Abbrev [2] 0x26:0xca DW_TAG_subprogram
+	.long	.Lfunc_begin0           # DW_AT_low_pc
+	.long	.Lfunc_end0-.Lfunc_begin0 # DW_AT_high_pc
+	.byte	1                       # DW_AT_frame_base
+	.byte	85
+	.long	.Linfo_string3          # DW_AT_linkage_name
+	.long	.Linfo_string4          # DW_AT_name
+	.byte	1                       # DW_AT_decl_file
+	.byte	3                       # DW_AT_decl_line
+                                        # DW_AT_external
+	.byte	3                       # Abbrev [3] 0x3b:0xe DW_TAG_variable
+	.byte	2                       # DW_AT_location
+	.byte	145
+	.byte	127
+	.long	.Linfo_string5          # DW_AT_name
+	.byte	1                       # DW_AT_decl_file
+	.byte	4                       # DW_AT_decl_line
+	.long	240                     # DW_AT_type
+	.byte	3                       # Abbrev [3] 0x49:0xe DW_TAG_variable
+	.byte	2                       # DW_AT_location
+	.byte	145
+	.byte	120
+	.long	.Linfo_string7          # DW_AT_name
+	.byte	1                       # DW_AT_decl_file
+	.byte	5                       # DW_AT_decl_line
+	.long	247                     # DW_AT_type
+	.byte	3                       # Abbrev [3] 0x57:0xe DW_TAG_variable
+	.byte	2                       # DW_AT_location
+	.byte	145
+	.byte	116
+	.long	.Linfo_string8          # DW_AT_name
+	.byte	1                       # DW_AT_decl_file
+	.byte	6                       # DW_AT_decl_line
+	.long	252                     # DW_AT_type
+	.byte	3                       # Abbrev [3] 0x65:0xe DW_TAG_variable
+	.byte	2                       # DW_AT_location
+	.byte	145
+	.byte	112
+	.long	.Linfo_string9          # DW_AT_name
+	.byte	1                       # DW_AT_decl_file
+	.byte	7                       # DW_AT_decl_line
+	.long	257                     # DW_AT_type
+	.byte	3                       # Abbrev [3] 0x73:0xe DW_TAG_variable
+	.byte	2                       # DW_AT_location
+	.byte	145
+	.byte	96
+	.long	.Linfo_string10         # DW_AT_name
+	.byte	1                       # DW_AT_decl_file
+	.byte	8                       # DW_AT_decl_line
+	.long	262                     # DW_AT_type
+	.byte	3                       # Abbrev [3] 0x81:0xe DW_TAG_variable
+	.byte	2                       # DW_AT_location
+	.byte	145
+	.byte	92
+	.long	.Linfo_string4          # DW_AT_name
+	.byte	1                       # DW_AT_decl_file
+	.byte	9                       # DW_AT_decl_line
+	.long	292                     # DW_AT_type
+	.byte	3                       # Abbrev [3] 0x8f:0xe DW_TAG_variable
+	.byte	2                       # DW_AT_location
+	.byte	145
+	.byte	91
+	.long	.Linfo_string12         # DW_AT_name
+	.byte	1                       # DW_AT_decl_file
+	.byte	10                      # DW_AT_decl_line
+	.long	301                     # DW_AT_type
+	.byte	3                       # Abbrev [3] 0x9d:0xe DW_TAG_variable
+	.byte	2                       # DW_AT_location
+	.byte	145
+	.byte	90
+	.long	.Linfo_string13         # DW_AT_name
+	.byte	1                       # DW_AT_decl_file
+	.byte	11                      # DW_AT_decl_line
+	.long	306                     # DW_AT_type
+	.byte	3                       # Abbrev [3] 0xab:0xe DW_TAG_variable
+	.byte	2                       # DW_AT_location
+	.byte	145
+	.byte	84
+	.long	.Linfo_string14         # DW_AT_name
+	.byte	1                       # DW_AT_decl_file
+	.byte	12                      # DW_AT_decl_line
+	.long	311                     # DW_AT_type
+	.byte	3                       # Abbrev [3] 0xb9:0xe DW_TAG_variable
+	.byte	2                       # DW_AT_location
+	.byte	145
+	.byte	83
+	.long	.Linfo_string15         # DW_AT_name
+	.byte	1                       # DW_AT_decl_file
+	.byte	14                      # DW_AT_decl_line
+	.long	228                     # DW_AT_type
+	.byte	3                       # Abbrev [3] 0xc7:0xe DW_TAG_variable
+	.byte	2                       # DW_AT_location
+	.byte	145
+	.byte	71
+	.long	.Linfo_string17         # DW_AT_name
+	.byte	1                       # DW_AT_decl_file
+	.byte	15                      # DW_AT_decl_line
+	.long	316                     # DW_AT_type
+	.byte	3                       # Abbrev [3] 0xd5:0xf DW_TAG_variable
+	.byte	3                       # DW_AT_location
+	.byte	145
+	.ascii	"\247}"
+	.long	.Linfo_string19         # DW_AT_name
+	.byte	1                       # DW_AT_decl_file
+	.byte	16                      # DW_AT_decl_line
+	.long	335                     # DW_AT_type
+	.byte	4                       # Abbrev [4] 0xe4:0xb DW_TAG_typedef
+	.long	240                     # DW_AT_type
+	.long	.Linfo_string16         # DW_AT_name
+	.byte	1                       # DW_AT_decl_file
+	.byte	13                      # DW_AT_decl_line
+	.byte	0                       # End Of Children Mark
+	.byte	5                       # Abbrev [5] 0xf0:0x7 DW_TAG_base_type
+	.long	.Linfo_string6          # DW_AT_name
+	.byte	6                       # DW_AT_encoding
+	.byte	1                       # DW_AT_byte_size
+	.byte	6                       # Abbrev [6] 0xf7:0x5 DW_TAG_pointer_type
+	.long	240                     # DW_AT_type
+	.byte	7                       # Abbrev [7] 0xfc:0x5 DW_TAG_reference_type
+	.long	240                     # DW_AT_type
+	.byte	8                       # Abbrev [8] 0x101:0x5 DW_TAG_rvalue_reference_type
+	.long	240                     # DW_AT_type
+	.byte	9                       # Abbrev [9] 0x106:0x9 DW_TAG_ptr_to_member_type
+	.long	271                     # DW_AT_type
+	.long	287                     # DW_AT_containing_type
+	.byte	10                      # Abbrev [10] 0x10f:0xb DW_TAG_subroutine_type
+	.long	240                     # DW_AT_type
+	.byte	11                      # Abbrev [11] 0x114:0x5 DW_TAG_formal_parameter
+	.long	282                     # DW_AT_type
+                                        # DW_AT_artificial
+	.byte	0                       # End Of Children Mark
+	.byte	6                       # Abbrev [6] 0x11a:0x5 DW_TAG_pointer_type
+	.long	287                     # DW_AT_type
+	.byte	12                      # Abbrev [12] 0x11f:0x5 DW_TAG_structure_type
+	.long	.Linfo_string11         # DW_AT_name
+                                        # DW_AT_declaration
+	.byte	9                       # Abbrev [9] 0x124:0x9 DW_TAG_ptr_to_member_type
+	.long	240                     # DW_AT_type
+	.long	287                     # DW_AT_containing_type
+	.byte	13                      # Abbrev [13] 0x12d:0x5 DW_TAG_const_type
+	.long	240                     # DW_AT_type
+	.byte	14                      # Abbrev [14] 0x132:0x5 DW_TAG_volatile_type
+	.long	240                     # DW_AT_type
+	.byte	15                      # Abbrev [15] 0x137:0x5 DW_TAG_restrict_type
+	.long	247                     # DW_AT_type
+	.byte	16                      # Abbrev [16] 0x13c:0xc DW_TAG_array_type
+	.long	240                     # DW_AT_type
+	.byte	17                      # Abbrev [17] 0x141:0x6 DW_TAG_subrange_type
+	.long	328                     # DW_AT_type
+	.byte	12                      # DW_AT_count
+	.byte	0                       # End Of Children Mark
+	.byte	18                      # Abbrev [18] 0x148:0x7 DW_TAG_base_type
+	.long	.Linfo_string18         # DW_AT_name
+	.byte	8                       # DW_AT_byte_size
+	.byte	7                       # DW_AT_encoding
+	.byte	16                      # Abbrev [16] 0x14f:0x12 DW_TAG_array_type
+	.long	240                     # DW_AT_type
+	.byte	17                      # Abbrev [17] 0x154:0x6 DW_TAG_subrange_type
+	.long	328                     # DW_AT_type
+	.byte	12                      # DW_AT_count
+	.byte	17                      # Abbrev [17] 0x15a:0x6 DW_TAG_subrange_type
+	.long	328                     # DW_AT_type
+	.byte	24                      # DW_AT_count
+	.byte	0                       # End Of Children Mark
+	.byte	0                       # End Of Children Mark
+.Ldebug_info_end0:
+	.section	.debug_macinfo,"", at progbits
+	.byte	0                       # End Of Macro List Mark
+
+	.ident	"clang version 9.0.0 "
+	.section	".note.GNU-stack","", at progbits
+	.addrsig
+	.section	.debug_line,"", at progbits
+.Lline_table_start0:

Added: llvm/trunk/test/tools/llvm-symbolizer/frame.s
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/test/tools/llvm-symbolizer/frame.s?rev=364225&view=auto
==============================================================================
--- llvm/trunk/test/tools/llvm-symbolizer/frame.s (added)
+++ llvm/trunk/test/tools/llvm-symbolizer/frame.s Mon Jun 24 13:03:23 2019
@@ -0,0 +1,687 @@
+// REQUIRES: aarch64-registered-target
+
+// RUN: llvm-mc -filetype=obj -triple=aarch64-linux-android -o %t.o %s
+// RUN: echo 'FRAME %t.o 0' | llvm-symbolizer | FileCheck %s
+
+// CHECK: f
+// CHECK-NEXT: a
+// CHECK-NEXT: /tmp/stack.c:20
+// CHECK-NEXT: -192 32 192
+// CHECK-NEXT: g
+// CHECK-NEXT: p
+// CHECK-NEXT: /tmp/stack.c:8
+// CHECK-NEXT: ?? 8 ??
+// CHECK-NEXT: g
+// CHECK-NEXT: b
+// CHECK-NEXT: /tmp/stack.c:10
+// CHECK-NEXT: -128 32 128
+// CHECK-NEXT: h
+// CHECK-NEXT: p1
+// CHECK-NEXT: /tmp/stack.c:3
+// CHECK-NEXT: ?? 8 ??
+// CHECK-NEXT: h
+// CHECK-NEXT: p2
+// CHECK-NEXT: /tmp/stack.c:3
+// CHECK-NEXT: ?? 8 ??
+// CHECK-NEXT: h
+// CHECK-NEXT: d
+// CHECK-NEXT: /tmp/stack.c:4
+// CHECK-NEXT: -96 32 0
+// CHECK-NEXT: g
+// CHECK-NEXT: c
+// CHECK-NEXT: /tmp/stack.c:14
+// CHECK-NEXT: -160 32 64
+// CHECK-NEXT: h
+// CHECK-NEXT: p1
+// CHECK-NEXT: /tmp/stack.c:3
+// CHECK-NEXT: ?? 8 ??
+// CHECK-NEXT: h
+// CHECK-NEXT: p2
+// CHECK-NEXT: /tmp/stack.c:3
+// CHECK-NEXT: ?? 8 ??
+// CHECK-NEXT: h
+// CHECK-NEXT: d
+// CHECK-NEXT: /tmp/stack.c:4
+// CHECK-NEXT: -96 32 0
+
+// Generated from:
+//
+// void i(void *, void *, void *);
+//
+// static void h(void *p1, void *p2) {
+//   char d[32];
+//   i(d, p1, p2);
+// }
+//
+// static void g(void *p) {
+//   {
+//     char b[32];
+//     h(b, p);
+//   }
+//   {
+//     char c[32];
+//     h(c, p);
+//   }
+// }
+//
+// clang -S -o - -fsanitize=hwaddress --target=aarch64-linux-android /tmp/stack.c -O -fsanitize-hwaddress-abi=platform -g
+
+	.text
+	.file	"stack.c"
+	.globl	f                       // -- Begin function f
+	.p2align	2
+	.type	f, at function
+f:                                      // @f
+.Lfunc_begin0:
+	.file	1 "/tmp" "stack.c"
+	.loc	1 19 0                  // stack.c:19:0
+	.cfi_startproc
+// %bb.0:                               // %entry
+	sub	sp, sp, #208            // =208
+	stp	x26, x25, [sp, #128]    // 16-byte Folded Spill
+	stp	x24, x23, [sp, #144]    // 16-byte Folded Spill
+	stp	x22, x21, [sp, #160]    // 16-byte Folded Spill
+	stp	x20, x19, [sp, #176]    // 16-byte Folded Spill
+	stp	x29, x30, [sp, #192]    // 16-byte Folded Spill
+	add	x29, sp, #192           // =192
+	.cfi_def_cfa w29, 16
+	.cfi_offset w30, -8
+	.cfi_offset w29, -16
+	.cfi_offset w19, -24
+	.cfi_offset w20, -32
+	.cfi_offset w21, -40
+	.cfi_offset w22, -48
+	.cfi_offset w23, -56
+	.cfi_offset w24, -64
+	.cfi_offset w25, -72
+	.cfi_offset w26, -80
+	mrs	x8, TPIDR_EL0
+	ldr	x12, [x8, #48]
+.Ltmp0:
+	adr	x14, .Ltmp0
+	orr	x14, x14, x29, lsl #44
+	add	x9, sp, #96             // =96
+	asr	x15, x12, #3
+	asr	x16, x12, #56
+	orr	x17, x12, #0xffffffff
+	str	x14, [x12], #8
+	bic	x12, x12, x16, lsl #12
+	str	x12, [x8, #48]
+.Ltmp1:
+	.loc	1 4 8 prologue_end      // stack.c:4:8
+	and	w8, w15, #0xff
+	lsr	x22, x9, #4
+	add	x25, x17, #1            // =1
+	bfi	w8, w8, #8, #8
+	add	x10, sp, #64            // =64
+	strh	w8, [x25, x22]
+.Ltmp2:
+	.loc	1 10 10                 // stack.c:10:10
+	eor	x8, x15, #0x80
+	orr	x1, x10, x8, lsl #56
+	and	w8, w8, #0xff
+	lsr	x23, x10, #4
+	bfi	w8, w8, #8, #8
+	add	x11, sp, #32            // =32
+	strh	w8, [x25, x23]
+.Ltmp3:
+	.loc	1 14 10                 // stack.c:14:10
+	eor	x8, x15, #0x40
+	orr	x19, x11, x8, lsl #56
+	and	w8, w8, #0xff
+	lsr	x24, x11, #4
+	bfi	w8, w8, #8, #8
+	mov	x13, sp
+	strh	w8, [x25, x24]
+.Ltmp4:
+	.loc	1 20 3                  // stack.c:20:3
+	eor	x8, x15, #0xc0
+.Ltmp5:
+	.loc	1 4 8                   // stack.c:4:8
+	orr	x20, x9, x15, lsl #56
+.Ltmp6:
+	.loc	1 20 3                  // stack.c:20:3
+	orr	x21, x13, x8, lsl #56
+	and	w8, w8, #0xff
+	lsr	x26, x13, #4
+	bfi	w8, w8, #8, #8
+.Ltmp7:
+	.loc	1 5 3                   // stack.c:5:3
+	mov	x0, x20
+	mov	x2, x21
+.Ltmp8:
+	.loc	1 20 3                  // stack.c:20:3
+	strh	w8, [x25, x26]
+.Ltmp9:
+	//DEBUG_VALUE: h:p1 <- $x1
+	//DEBUG_VALUE: g:p <- $x21
+	//DEBUG_VALUE: h:p2 <- $x21
+	//DEBUG_VALUE: h:p2 <- $x21
+	.loc	1 5 3                   // stack.c:5:3
+	bl	i
+.Ltmp10:
+	//DEBUG_VALUE: h:p1 <- $x19
+	.loc	1 5 3 is_stmt 0         // stack.c:5:3
+	mov	x0, x20
+	mov	x1, x19
+	mov	x2, x21
+	bl	i
+.Ltmp11:
+	.loc	1 22 1 is_stmt 1        // stack.c:22:1
+	strh	wzr, [x25, x22]
+	strh	wzr, [x25, x23]
+	strh	wzr, [x25, x24]
+	strh	wzr, [x25, x26]
+	ldp	x29, x30, [sp, #192]    // 16-byte Folded Reload
+	ldp	x20, x19, [sp, #176]    // 16-byte Folded Reload
+.Ltmp12:
+	ldp	x22, x21, [sp, #160]    // 16-byte Folded Reload
+.Ltmp13:
+	ldp	x24, x23, [sp, #144]    // 16-byte Folded Reload
+	ldp	x26, x25, [sp, #128]    // 16-byte Folded Reload
+	add	sp, sp, #208            // =208
+	ret
+.Ltmp14:
+.Lfunc_end0:
+	.size	f, .Lfunc_end0-f
+	.cfi_endproc
+                                        // -- End function
+	.section	.text.hwasan.module_ctor,"axG", at progbits,hwasan.module_ctor,comdat
+	.p2align	2               // -- Begin function hwasan.module_ctor
+	.type	hwasan.module_ctor, at function
+hwasan.module_ctor:                     // @hwasan.module_ctor
+.Lfunc_begin1:
+	.cfi_startproc
+// %bb.0:
+	str	x30, [sp, #-16]!        // 8-byte Folded Spill
+	.cfi_def_cfa_offset 16
+	.cfi_offset w30, -16
+	bl	__hwasan_init
+	ldr	x30, [sp], #16          // 8-byte Folded Reload
+	ret
+.Lfunc_end1:
+	.size	hwasan.module_ctor, .Lfunc_end1-hwasan.module_ctor
+	.cfi_endproc
+                                        // -- End function
+	.section	.init_array.0,"aGw", at init_array,hwasan.module_ctor,comdat
+	.p2align	3
+	.xword	hwasan.module_ctor
+	.section	.debug_str,"MS", at progbits,1
+.Linfo_string0:
+	.asciz	"clang version 9.0.0 "  // string offset=0
+.Linfo_string1:
+	.asciz	"stack.c"               // string offset=21
+.Linfo_string2:
+	.asciz	"/tmp"                  // string offset=29
+.Linfo_string3:
+	.asciz	"h"                     // string offset=34
+.Linfo_string4:
+	.asciz	"p1"                    // string offset=36
+.Linfo_string5:
+	.asciz	"p2"                    // string offset=39
+.Linfo_string6:
+	.asciz	"d"                     // string offset=42
+.Linfo_string7:
+	.asciz	"char"                  // string offset=44
+.Linfo_string8:
+	.asciz	"__ARRAY_SIZE_TYPE__"   // string offset=49
+.Linfo_string9:
+	.asciz	"g"                     // string offset=69
+.Linfo_string10:
+	.asciz	"p"                     // string offset=71
+.Linfo_string11:
+	.asciz	"b"                     // string offset=73
+.Linfo_string12:
+	.asciz	"c"                     // string offset=75
+.Linfo_string13:
+	.asciz	"f"                     // string offset=77
+.Linfo_string14:
+	.asciz	"a"                     // string offset=79
+	.section	.debug_loc,"", at progbits
+.Ldebug_loc0:
+	.xword	.Ltmp9-.Lfunc_begin0
+	.xword	.Ltmp10-.Lfunc_begin0
+	.hword	1                       // Loc expr size
+	.byte	81                      // DW_OP_reg1
+	.xword	0
+	.xword	0
+.Ldebug_loc1:
+	.xword	.Ltmp9-.Lfunc_begin0
+	.xword	.Ltmp13-.Lfunc_begin0
+	.hword	1                       // Loc expr size
+	.byte	101                     // DW_OP_reg21
+	.xword	0
+	.xword	0
+.Ldebug_loc2:
+	.xword	.Ltmp9-.Lfunc_begin0
+	.xword	.Ltmp13-.Lfunc_begin0
+	.hword	1                       // Loc expr size
+	.byte	101                     // DW_OP_reg21
+	.xword	0
+	.xword	0
+.Ldebug_loc3:
+	.xword	.Ltmp9-.Lfunc_begin0
+	.xword	.Ltmp13-.Lfunc_begin0
+	.hword	1                       // Loc expr size
+	.byte	101                     // DW_OP_reg21
+	.xword	0
+	.xword	0
+.Ldebug_loc4:
+	.xword	.Ltmp10-.Lfunc_begin0
+	.xword	.Ltmp12-.Lfunc_begin0
+	.hword	1                       // Loc expr size
+	.byte	99                      // DW_OP_reg19
+	.xword	0
+	.xword	0
+	.section	.debug_abbrev,"", at progbits
+	.byte	1                       // Abbreviation Code
+	.byte	17                      // DW_TAG_compile_unit
+	.byte	1                       // DW_CHILDREN_yes
+	.byte	37                      // DW_AT_producer
+	.byte	14                      // DW_FORM_strp
+	.byte	19                      // DW_AT_language
+	.byte	5                       // DW_FORM_data2
+	.byte	3                       // DW_AT_name
+	.byte	14                      // DW_FORM_strp
+	.byte	16                      // DW_AT_stmt_list
+	.byte	23                      // DW_FORM_sec_offset
+	.byte	27                      // DW_AT_comp_dir
+	.byte	14                      // DW_FORM_strp
+	.byte	17                      // DW_AT_low_pc
+	.byte	1                       // DW_FORM_addr
+	.byte	18                      // DW_AT_high_pc
+	.byte	6                       // DW_FORM_data4
+	.byte	0                       // EOM(1)
+	.byte	0                       // EOM(2)
+	.byte	2                       // Abbreviation Code
+	.byte	46                      // DW_TAG_subprogram
+	.byte	1                       // DW_CHILDREN_yes
+	.byte	3                       // DW_AT_name
+	.byte	14                      // DW_FORM_strp
+	.byte	58                      // DW_AT_decl_file
+	.byte	11                      // DW_FORM_data1
+	.byte	59                      // DW_AT_decl_line
+	.byte	11                      // DW_FORM_data1
+	.byte	39                      // DW_AT_prototyped
+	.byte	25                      // DW_FORM_flag_present
+	.byte	32                      // DW_AT_inline
+	.byte	11                      // DW_FORM_data1
+	.byte	0                       // EOM(1)
+	.byte	0                       // EOM(2)
+	.byte	3                       // Abbreviation Code
+	.byte	5                       // DW_TAG_formal_parameter
+	.byte	0                       // DW_CHILDREN_no
+	.byte	3                       // DW_AT_name
+	.byte	14                      // DW_FORM_strp
+	.byte	58                      // DW_AT_decl_file
+	.byte	11                      // DW_FORM_data1
+	.byte	59                      // DW_AT_decl_line
+	.byte	11                      // DW_FORM_data1
+	.byte	73                      // DW_AT_type
+	.byte	19                      // DW_FORM_ref4
+	.byte	0                       // EOM(1)
+	.byte	0                       // EOM(2)
+	.byte	4                       // Abbreviation Code
+	.byte	52                      // DW_TAG_variable
+	.byte	0                       // DW_CHILDREN_no
+	.byte	3                       // DW_AT_name
+	.byte	14                      // DW_FORM_strp
+	.byte	58                      // DW_AT_decl_file
+	.byte	11                      // DW_FORM_data1
+	.byte	59                      // DW_AT_decl_line
+	.byte	11                      // DW_FORM_data1
+	.byte	73                      // DW_AT_type
+	.byte	19                      // DW_FORM_ref4
+	.byte	0                       // EOM(1)
+	.byte	0                       // EOM(2)
+	.byte	5                       // Abbreviation Code
+	.byte	15                      // DW_TAG_pointer_type
+	.byte	0                       // DW_CHILDREN_no
+	.byte	0                       // EOM(1)
+	.byte	0                       // EOM(2)
+	.byte	6                       // Abbreviation Code
+	.byte	1                       // DW_TAG_array_type
+	.byte	1                       // DW_CHILDREN_yes
+	.byte	73                      // DW_AT_type
+	.byte	19                      // DW_FORM_ref4
+	.byte	0                       // EOM(1)
+	.byte	0                       // EOM(2)
+	.byte	7                       // Abbreviation Code
+	.byte	33                      // DW_TAG_subrange_type
+	.byte	0                       // DW_CHILDREN_no
+	.byte	73                      // DW_AT_type
+	.byte	19                      // DW_FORM_ref4
+	.byte	55                      // DW_AT_count
+	.byte	11                      // DW_FORM_data1
+	.byte	0                       // EOM(1)
+	.byte	0                       // EOM(2)
+	.byte	8                       // Abbreviation Code
+	.byte	36                      // DW_TAG_base_type
+	.byte	0                       // DW_CHILDREN_no
+	.byte	3                       // DW_AT_name
+	.byte	14                      // DW_FORM_strp
+	.byte	62                      // DW_AT_encoding
+	.byte	11                      // DW_FORM_data1
+	.byte	11                      // DW_AT_byte_size
+	.byte	11                      // DW_FORM_data1
+	.byte	0                       // EOM(1)
+	.byte	0                       // EOM(2)
+	.byte	9                       // Abbreviation Code
+	.byte	36                      // DW_TAG_base_type
+	.byte	0                       // DW_CHILDREN_no
+	.byte	3                       // DW_AT_name
+	.byte	14                      // DW_FORM_strp
+	.byte	11                      // DW_AT_byte_size
+	.byte	11                      // DW_FORM_data1
+	.byte	62                      // DW_AT_encoding
+	.byte	11                      // DW_FORM_data1
+	.byte	0                       // EOM(1)
+	.byte	0                       // EOM(2)
+	.byte	10                      // Abbreviation Code
+	.byte	11                      // DW_TAG_lexical_block
+	.byte	1                       // DW_CHILDREN_yes
+	.byte	0                       // EOM(1)
+	.byte	0                       // EOM(2)
+	.byte	11                      // Abbreviation Code
+	.byte	46                      // DW_TAG_subprogram
+	.byte	1                       // DW_CHILDREN_yes
+	.byte	17                      // DW_AT_low_pc
+	.byte	1                       // DW_FORM_addr
+	.byte	18                      // DW_AT_high_pc
+	.byte	6                       // DW_FORM_data4
+	.byte	64                      // DW_AT_frame_base
+	.byte	24                      // DW_FORM_exprloc
+	.byte	3                       // DW_AT_name
+	.byte	14                      // DW_FORM_strp
+	.byte	58                      // DW_AT_decl_file
+	.byte	11                      // DW_FORM_data1
+	.byte	59                      // DW_AT_decl_line
+	.byte	11                      // DW_FORM_data1
+	.byte	63                      // DW_AT_external
+	.byte	25                      // DW_FORM_flag_present
+	.byte	0                       // EOM(1)
+	.byte	0                       // EOM(2)
+	.byte	12                      // Abbreviation Code
+	.byte	52                      // DW_TAG_variable
+	.byte	0                       // DW_CHILDREN_no
+	.byte	2                       // DW_AT_location
+	.byte	24                      // DW_FORM_exprloc
+	.ascii	"\203|"                 // DW_AT_LLVM_tag_offset
+	.byte	11                      // DW_FORM_data1
+	.byte	3                       // DW_AT_name
+	.byte	14                      // DW_FORM_strp
+	.byte	58                      // DW_AT_decl_file
+	.byte	11                      // DW_FORM_data1
+	.byte	59                      // DW_AT_decl_line
+	.byte	11                      // DW_FORM_data1
+	.byte	73                      // DW_AT_type
+	.byte	19                      // DW_FORM_ref4
+	.byte	0                       // EOM(1)
+	.byte	0                       // EOM(2)
+	.byte	13                      // Abbreviation Code
+	.byte	29                      // DW_TAG_inlined_subroutine
+	.byte	1                       // DW_CHILDREN_yes
+	.byte	49                      // DW_AT_abstract_origin
+	.byte	19                      // DW_FORM_ref4
+	.byte	85                      // DW_AT_ranges
+	.byte	23                      // DW_FORM_sec_offset
+	.byte	88                      // DW_AT_call_file
+	.byte	11                      // DW_FORM_data1
+	.byte	89                      // DW_AT_call_line
+	.byte	11                      // DW_FORM_data1
+	.byte	0                       // EOM(1)
+	.byte	0                       // EOM(2)
+	.byte	14                      // Abbreviation Code
+	.byte	5                       // DW_TAG_formal_parameter
+	.byte	0                       // DW_CHILDREN_no
+	.byte	2                       // DW_AT_location
+	.byte	23                      // DW_FORM_sec_offset
+	.byte	49                      // DW_AT_abstract_origin
+	.byte	19                      // DW_FORM_ref4
+	.byte	0                       // EOM(1)
+	.byte	0                       // EOM(2)
+	.byte	15                      // Abbreviation Code
+	.byte	11                      // DW_TAG_lexical_block
+	.byte	1                       // DW_CHILDREN_yes
+	.byte	85                      // DW_AT_ranges
+	.byte	23                      // DW_FORM_sec_offset
+	.byte	0                       // EOM(1)
+	.byte	0                       // EOM(2)
+	.byte	16                      // Abbreviation Code
+	.byte	52                      // DW_TAG_variable
+	.byte	0                       // DW_CHILDREN_no
+	.byte	2                       // DW_AT_location
+	.byte	24                      // DW_FORM_exprloc
+	.ascii	"\203|"                 // DW_AT_LLVM_tag_offset
+	.byte	11                      // DW_FORM_data1
+	.byte	49                      // DW_AT_abstract_origin
+	.byte	19                      // DW_FORM_ref4
+	.byte	0                       // EOM(1)
+	.byte	0                       // EOM(2)
+	.byte	17                      // Abbreviation Code
+	.byte	29                      // DW_TAG_inlined_subroutine
+	.byte	1                       // DW_CHILDREN_yes
+	.byte	49                      // DW_AT_abstract_origin
+	.byte	19                      // DW_FORM_ref4
+	.byte	17                      // DW_AT_low_pc
+	.byte	1                       // DW_FORM_addr
+	.byte	18                      // DW_AT_high_pc
+	.byte	6                       // DW_FORM_data4
+	.byte	88                      // DW_AT_call_file
+	.byte	11                      // DW_FORM_data1
+	.byte	89                      // DW_AT_call_line
+	.byte	11                      // DW_FORM_data1
+	.byte	0                       // EOM(1)
+	.byte	0                       // EOM(2)
+	.byte	0                       // EOM(3)
+	.section	.debug_info,"", at progbits
+.Lcu_begin0:
+	.word	.Ldebug_info_end0-.Ldebug_info_start0 // Length of Unit
+.Ldebug_info_start0:
+	.hword	4                       // DWARF version number
+	.word	.debug_abbrev           // Offset Into Abbrev. Section
+	.byte	8                       // Address Size (in bytes)
+	.byte	1                       // Abbrev [1] 0xb:0x146 DW_TAG_compile_unit
+	.word	.Linfo_string0          // DW_AT_producer
+	.hword	12                      // DW_AT_language
+	.word	.Linfo_string1          // DW_AT_name
+	.word	.Lline_table_start0     // DW_AT_stmt_list
+	.word	.Linfo_string2          // DW_AT_comp_dir
+	.xword	.Lfunc_begin0           // DW_AT_low_pc
+	.word	.Lfunc_end0-.Lfunc_begin0 // DW_AT_high_pc
+	.byte	2                       // Abbrev [2] 0x2a:0x2a DW_TAG_subprogram
+	.word	.Linfo_string3          // DW_AT_name
+	.byte	1                       // DW_AT_decl_file
+	.byte	3                       // DW_AT_decl_line
+                                        // DW_AT_prototyped
+	.byte	1                       // DW_AT_inline
+	.byte	3                       // Abbrev [3] 0x32:0xb DW_TAG_formal_parameter
+	.word	.Linfo_string4          // DW_AT_name
+	.byte	1                       // DW_AT_decl_file
+	.byte	3                       // DW_AT_decl_line
+	.word	84                      // DW_AT_type
+	.byte	3                       // Abbrev [3] 0x3d:0xb DW_TAG_formal_parameter
+	.word	.Linfo_string5          // DW_AT_name
+	.byte	1                       // DW_AT_decl_file
+	.byte	3                       // DW_AT_decl_line
+	.word	84                      // DW_AT_type
+	.byte	4                       // Abbrev [4] 0x48:0xb DW_TAG_variable
+	.word	.Linfo_string6          // DW_AT_name
+	.byte	1                       // DW_AT_decl_file
+	.byte	4                       // DW_AT_decl_line
+	.word	85                      // DW_AT_type
+	.byte	0                       // End Of Children Mark
+	.byte	5                       // Abbrev [5] 0x54:0x1 DW_TAG_pointer_type
+	.byte	6                       // Abbrev [6] 0x55:0xc DW_TAG_array_type
+	.word	97                      // DW_AT_type
+	.byte	7                       // Abbrev [7] 0x5a:0x6 DW_TAG_subrange_type
+	.word	104                     // DW_AT_type
+	.byte	32                      // DW_AT_count
+	.byte	0                       // End Of Children Mark
+	.byte	8                       // Abbrev [8] 0x61:0x7 DW_TAG_base_type
+	.word	.Linfo_string7          // DW_AT_name
+	.byte	8                       // DW_AT_encoding
+	.byte	1                       // DW_AT_byte_size
+	.byte	9                       // Abbrev [9] 0x68:0x7 DW_TAG_base_type
+	.word	.Linfo_string8          // DW_AT_name
+	.byte	8                       // DW_AT_byte_size
+	.byte	7                       // DW_AT_encoding
+	.byte	2                       // Abbrev [2] 0x6f:0x2e DW_TAG_subprogram
+	.word	.Linfo_string9          // DW_AT_name
+	.byte	1                       // DW_AT_decl_file
+	.byte	8                       // DW_AT_decl_line
+                                        // DW_AT_prototyped
+	.byte	1                       // DW_AT_inline
+	.byte	3                       // Abbrev [3] 0x77:0xb DW_TAG_formal_parameter
+	.word	.Linfo_string10         // DW_AT_name
+	.byte	1                       // DW_AT_decl_file
+	.byte	8                       // DW_AT_decl_line
+	.word	84                      // DW_AT_type
+	.byte	10                      // Abbrev [10] 0x82:0xd DW_TAG_lexical_block
+	.byte	4                       // Abbrev [4] 0x83:0xb DW_TAG_variable
+	.word	.Linfo_string11         // DW_AT_name
+	.byte	1                       // DW_AT_decl_file
+	.byte	10                      // DW_AT_decl_line
+	.word	85                      // DW_AT_type
+	.byte	0                       // End Of Children Mark
+	.byte	10                      // Abbrev [10] 0x8f:0xd DW_TAG_lexical_block
+	.byte	4                       // Abbrev [4] 0x90:0xb DW_TAG_variable
+	.word	.Linfo_string12         // DW_AT_name
+	.byte	1                       // DW_AT_decl_file
+	.byte	14                      // DW_AT_decl_line
+	.word	85                      // DW_AT_type
+	.byte	0                       // End Of Children Mark
+	.byte	0                       // End Of Children Mark
+	.byte	11                      // Abbrev [11] 0x9d:0xb3 DW_TAG_subprogram
+	.xword	.Lfunc_begin0           // DW_AT_low_pc
+	.word	.Lfunc_end0-.Lfunc_begin0 // DW_AT_high_pc
+	.byte	1                       // DW_AT_frame_base
+	.byte	109
+	.word	.Linfo_string13         // DW_AT_name
+	.byte	1                       // DW_AT_decl_file
+	.byte	19                      // DW_AT_decl_line
+                                        // DW_AT_external
+	.byte	12                      // Abbrev [12] 0xb2:0x10 DW_TAG_variable
+	.byte	3                       // DW_AT_location
+	.byte	145
+	.ascii	"\300~"
+	.byte	192                     // DW_AT_LLVM_tag_offset
+	.word	.Linfo_string14         // DW_AT_name
+	.byte	1                       // DW_AT_decl_file
+	.byte	20                      // DW_AT_decl_line
+	.word	85                      // DW_AT_type
+	.byte	13                      // Abbrev [13] 0xc2:0x8d DW_TAG_inlined_subroutine
+	.word	111                     // DW_AT_abstract_origin
+	.word	.Ldebug_ranges0         // DW_AT_ranges
+	.byte	1                       // DW_AT_call_file
+	.byte	21                      // DW_AT_call_line
+	.byte	14                      // Abbrev [14] 0xcd:0x9 DW_TAG_formal_parameter
+	.word	.Ldebug_loc1            // DW_AT_location
+	.word	119                     // DW_AT_abstract_origin
+	.byte	15                      // Abbrev [15] 0xd6:0x38 DW_TAG_lexical_block
+	.word	.Ldebug_ranges2         // DW_AT_ranges
+	.byte	16                      // Abbrev [16] 0xdb:0xa DW_TAG_variable
+	.byte	3                       // DW_AT_location
+	.byte	145
+	.ascii	"\200\177"
+	.byte	128                     // DW_AT_LLVM_tag_offset
+	.word	131                     // DW_AT_abstract_origin
+	.byte	13                      // Abbrev [13] 0xe5:0x28 DW_TAG_inlined_subroutine
+	.word	42                      // DW_AT_abstract_origin
+	.word	.Ldebug_ranges1         // DW_AT_ranges
+	.byte	1                       // DW_AT_call_file
+	.byte	11                      // DW_AT_call_line
+	.byte	14                      // Abbrev [14] 0xf0:0x9 DW_TAG_formal_parameter
+	.word	.Ldebug_loc0            // DW_AT_location
+	.word	50                      // DW_AT_abstract_origin
+	.byte	14                      // Abbrev [14] 0xf9:0x9 DW_TAG_formal_parameter
+	.word	.Ldebug_loc2            // DW_AT_location
+	.word	61                      // DW_AT_abstract_origin
+	.byte	16                      // Abbrev [16] 0x102:0xa DW_TAG_variable
+	.byte	3                       // DW_AT_location
+	.byte	145
+	.ascii	"\240\177"
+	.byte	0                       // DW_AT_LLVM_tag_offset
+	.word	72                      // DW_AT_abstract_origin
+	.byte	0                       // End Of Children Mark
+	.byte	0                       // End Of Children Mark
+	.byte	15                      // Abbrev [15] 0x10e:0x40 DW_TAG_lexical_block
+	.word	.Ldebug_ranges3         // DW_AT_ranges
+	.byte	16                      // Abbrev [16] 0x113:0xa DW_TAG_variable
+	.byte	3                       // DW_AT_location
+	.byte	145
+	.ascii	"\340~"
+	.byte	64                      // DW_AT_LLVM_tag_offset
+	.word	144                     // DW_AT_abstract_origin
+	.byte	17                      // Abbrev [17] 0x11d:0x30 DW_TAG_inlined_subroutine
+	.word	42                      // DW_AT_abstract_origin
+	.xword	.Ltmp10                 // DW_AT_low_pc
+	.word	.Ltmp11-.Ltmp10         // DW_AT_high_pc
+	.byte	1                       // DW_AT_call_file
+	.byte	15                      // DW_AT_call_line
+	.byte	14                      // Abbrev [14] 0x130:0x9 DW_TAG_formal_parameter
+	.word	.Ldebug_loc4            // DW_AT_location
+	.word	50                      // DW_AT_abstract_origin
+	.byte	14                      // Abbrev [14] 0x139:0x9 DW_TAG_formal_parameter
+	.word	.Ldebug_loc3            // DW_AT_location
+	.word	61                      // DW_AT_abstract_origin
+	.byte	16                      // Abbrev [16] 0x142:0xa DW_TAG_variable
+	.byte	3                       // DW_AT_location
+	.byte	145
+	.ascii	"\240\177"
+	.byte	0                       // DW_AT_LLVM_tag_offset
+	.word	72                      // DW_AT_abstract_origin
+	.byte	0                       // End Of Children Mark
+	.byte	0                       // End Of Children Mark
+	.byte	0                       // End Of Children Mark
+	.byte	0                       // End Of Children Mark
+	.byte	0                       // End Of Children Mark
+.Ldebug_info_end0:
+	.section	.debug_ranges,"", at progbits
+.Ldebug_ranges0:
+	.xword	.Ltmp1-.Lfunc_begin0
+	.xword	.Ltmp4-.Lfunc_begin0
+	.xword	.Ltmp5-.Lfunc_begin0
+	.xword	.Ltmp6-.Lfunc_begin0
+	.xword	.Ltmp7-.Lfunc_begin0
+	.xword	.Ltmp8-.Lfunc_begin0
+	.xword	.Ltmp9-.Lfunc_begin0
+	.xword	.Ltmp11-.Lfunc_begin0
+	.xword	0
+	.xword	0
+.Ldebug_ranges1:
+	.xword	.Ltmp1-.Lfunc_begin0
+	.xword	.Ltmp2-.Lfunc_begin0
+	.xword	.Ltmp5-.Lfunc_begin0
+	.xword	.Ltmp6-.Lfunc_begin0
+	.xword	.Ltmp7-.Lfunc_begin0
+	.xword	.Ltmp8-.Lfunc_begin0
+	.xword	.Ltmp9-.Lfunc_begin0
+	.xword	.Ltmp10-.Lfunc_begin0
+	.xword	0
+	.xword	0
+.Ldebug_ranges2:
+	.xword	.Ltmp1-.Lfunc_begin0
+	.xword	.Ltmp3-.Lfunc_begin0
+	.xword	.Ltmp5-.Lfunc_begin0
+	.xword	.Ltmp6-.Lfunc_begin0
+	.xword	.Ltmp7-.Lfunc_begin0
+	.xword	.Ltmp8-.Lfunc_begin0
+	.xword	.Ltmp9-.Lfunc_begin0
+	.xword	.Ltmp10-.Lfunc_begin0
+	.xword	0
+	.xword	0
+.Ldebug_ranges3:
+	.xword	.Ltmp3-.Lfunc_begin0
+	.xword	.Ltmp4-.Lfunc_begin0
+	.xword	.Ltmp10-.Lfunc_begin0
+	.xword	.Ltmp11-.Lfunc_begin0
+	.xword	0
+	.xword	0
+	.section	.debug_macinfo,"", at progbits
+	.byte	0                       // End Of Macro List Mark
+
+	.ident	"clang version 9.0.0 "
+	.section	".note.GNU-stack","", at progbits
+	.section	.debug_line,"", at progbits
+.Lline_table_start0:

Modified: llvm/trunk/tools/llvm-symbolizer/llvm-symbolizer.cpp
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/tools/llvm-symbolizer/llvm-symbolizer.cpp?rev=364225&r1=364224&r2=364225&view=diff
==============================================================================
--- llvm/trunk/tools/llvm-symbolizer/llvm-symbolizer.cpp (original)
+++ llvm/trunk/tools/llvm-symbolizer/llvm-symbolizer.cpp Mon Jun 24 13:03:23 2019
@@ -166,17 +166,25 @@ static bool error(Expected<T> &ResOrErr)
   return true;
 }
 
-static bool parseCommand(StringRef InputString, bool &IsData,
+enum class Command {
+  Code,
+  Data,
+  Frame,
+};
+
+static bool parseCommand(StringRef InputString, Command &Cmd,
                          std::string &ModuleName, uint64_t &ModuleOffset) {
   const char kDelimiters[] = " \n\r";
   ModuleName = "";
   if (InputString.consume_front("CODE ")) {
-    IsData = false;
+    Cmd = Command::Code;
   } else if (InputString.consume_front("DATA ")) {
-    IsData = true;
+    Cmd = Command::Data;
+  } else if (InputString.consume_front("FRAME ")) {
+    Cmd = Command::Frame;
   } else {
     // If no cmd, assume it's CODE.
-    IsData = false;
+    Cmd = Command::Code;
   }
   const char *pos = InputString.data();
   // Skip delimiters and parse input filename (if needed).
@@ -206,10 +214,10 @@ static bool parseCommand(StringRef Input
 
 static void symbolizeInput(StringRef InputString, LLVMSymbolizer &Symbolizer,
                            DIPrinter &Printer) {
-  bool IsData = false;
+  Command Cmd;
   std::string ModuleName;
   uint64_t Offset = 0;
-  if (!parseCommand(StringRef(InputString), IsData, ModuleName, Offset)) {
+  if (!parseCommand(StringRef(InputString), Cmd, ModuleName, Offset)) {
     outs() << InputString;
     return;
   }
@@ -221,10 +229,19 @@ static void symbolizeInput(StringRef Inp
     outs() << Delimiter;
   }
   Offset -= ClAdjustVMA;
-  if (IsData) {
+  if (Cmd == Command::Data) {
     auto ResOrErr = Symbolizer.symbolizeData(
         ModuleName, {Offset, object::SectionedAddress::UndefSection});
     Printer << (error(ResOrErr) ? DIGlobal() : ResOrErr.get());
+  } else if (Cmd == Command::Frame) {
+    auto ResOrErr = Symbolizer.symbolizeFrame(
+        ModuleName, {Offset, object::SectionedAddress::UndefSection});
+    if (!error(ResOrErr)) {
+      for (DILocal Local : *ResOrErr)
+        Printer << Local;
+      if (ResOrErr->empty())
+        outs() << "??\n";
+    }
   } else if (ClPrintInlining) {
     auto ResOrErr = Symbolizer.symbolizeInlinedCode(
         ModuleName, {Offset, object::SectionedAddress::UndefSection});




More information about the llvm-commits mailing list