[llvm] r290204 - [ObjectYAML] Support for DWARF debug_info section

Chris Bieneman via llvm-commits llvm-commits at lists.llvm.org
Sun Jan 8 22:43:02 PST 2017


> On Jan 4, 2017, at 11:01 AM, Adrian Prantl <aprantl at apple.com> wrote:
> 
> 
>> On Jan 3, 2017, at 5:57 PM, Chris Bieneman <beanz at apple.com> wrote:
>> 
>> Adrian,
>> 
>> I had a lengthy discussion with David and Chandler at Google a few weeks back discussing the YAML approach. It solves several problems that the assembly and IR testing approaches don't.
> 
> Thanks, that explains why I missed this :-)
> When we have an off-list conversation it is sometimes useful to post a summary to the list to explain where we are going to the rest of the community.

Since the on-list conversation was only between myself and David, I didn't think it was necessary to recap, but in responding you below I'll probably touch on pretty much everything that was discussed between David, Chandler, Reid, myself and the other present Google engineers.

> 
>> 
>> First and foremost it allows for bit-for-bit identical conversion of debug information into yaml and back into binary. Doing bit-for-bit identical round-tripping is required for being using the infrastructure to test debug information generated by multiple compilers. In particular because the structure of the DWARF from an IR file could change as LLVM changes, we need to be able to have stable tests for DWARF that are insulated from that change.
>> 
>> In terms of the YAML syntax being verbose. I suggested previously that we could come back later and construct a less verbose syntax that would be more suited for hand writing tests. This syntax is mostly targeted for generating a test case from a binary. It also can be used to make slight modifications, but there are restrictions on the modifications that can be safely made.
> 
> So to summarize in my own words, the idea (or short-term goal) is to not write testcases by hand, but to use different compilers to generate object files and then use obj2yaml to convert them into a textual representation that can be checked in to a repository?

Mostly, but the textual representations can also be modified in limited situations which can make it easier to craft test cases that would be hard to produce more naturally. For example you could create test cases with nonsensical values in DWARF fields, or generally malformed DWARF data by modifying the YAML. This would be really useful for adding tests that cover the failure modes in the DWARF parser, which we have very little of today.

> 
> Then let me repeat my original question: What does this syntax add over just using (well-commented) assembler directly?
> Is the assumption correct that this will be primarily used for well-formed DWARF?

This actually adds a number of things over using the assembler. One of the being that it is possible to generate malformed DWARF data easily. Another big thing is actually something you touched on, the YAML representation will be capable of testing things that we currently have no infrastructure to test. Like the DWARF line table state machine parsing. I have a patch that I wrote while on vacation last week, and intend to commit tomorrow that adds support for the debug_line section, and the YAML representation preserves opcodes and their data. I think this is huge because we currently don't have a way to test the state machine evaluation of specific opcode sequences except by manually encoding them as hex values in gtests.

> 
> In my (limited) experience different compilers differ not so much in the very low-level representation (this is pretty much dictated by the DWARF specification) but in much higher-level details, such as the order/nesting in which DIEs are emitted and the choices when to emit full definitions vs. declarations, and in which attributes are supported. The line table is the only section where I have seen different compilers make different low-level choices (and this would also be an example where the assembler's .loc directives are too high-level to express the representational differences).
> 
>> My intent for building the verbose syntax at the starting point is that it can be used for a much wider variety of test cases. While it may not be as ideal as a simplified syntax for simple tests, it is applicable to a much wider variety of tests.
> 
> I think it is great that you are working on this, and I am very much in favor of having a better way to express DWARF testcases for LLDB and dsymutil — I'm just not yet convinced that what we are building right now is going into the right direction to be useful. It is of course possible that my envisioned use-cases are different from your goals, but I can't tell yet because it is not clear to me what use-case this language is being designed for.
> 
> 1. Is this representation aiming at testing the DWARF binary stream parser?

Aiming isn't necessarily the right word, but I do intend to use it for testing the DWARF parser. If I can find time I'd actually like to feed LLVM::Error through the DWARF parser and having YAML tests that represent bad data would be a useful way of testing the failure modes. At the moment I find the DWARF parser's error handling frustrating and in some places scary.

> 2. Is it supposed to (also) be useful for writing higher-level tests for LLDB?

One of the primary use cases that this infrastructure will be critical for is testing LLDB functionality that has compatibility requirements across different compilers and versions of compilers. These tools are designed to be able to reproduce bit-for-bit identical DWARF. This is *huge* for being able to build a test suite that everyone can run, and uses inputs that match the output formats from a variety of compilers. The goal of this is to alleviate a whole class of errors that people only ever find on CI bots today by having tests that can be run locally.

> 
> For the latter use case, I personally would like to have a much higher-level representation that understands about DIEs and can fill in low-level details such as abbreviations and CU headers automatically. This would be useful to replace the exisiting dsymutil binary testcases with. It would also be useful for creating a testsuite for LLDB's DWARF expression parser, which is pretty much untested at the moment because DWARF expressions mostly show up in optimized code and it is impossible to create source-based testcases for this in the face of ever-changing compiler optimizations.

My goal in writing this YAML solution is to write *one* testing infrastructure that can meet a wide variety of needs. It isn't necessarily ideal for all use cases, but starting at the lower level (less human friendly) means that the system is useful in a much wider variety of situations. It is possible to come back later and add a simplified representation that doesn't have the bit-for-bit reproduction requirement, but in the interest of efficiency starting with a low-level solution that can meet a wider set of use cases seems prudent. A similar sentiment was expressed by Chandler during our lunch at Google in December.

> 
> It is possible that these two goals are too different from each other to cram into one syntax. Perhaps it is best to have one really low-level representation to test just the parser, and add new assembler syntax (something like a .die directive) to test higher-level features.
> 
> What do you think?

I am very much in favor of having many different ways to write tests so that every aspect of a system is easy to test. I also generally want to see high levels of code re-use, and avoid duplication or wildly different methods of testing. Starting with low-level testing interfaces allows us to build infrastructure that can test things we couldn't test before. Adding a higher-level syntax to the YAML representation is completely possible, and it is something that I'd like to look into at a later date. A higher-level YAML syntax would actually cover the use cases that Greg wrote the DwarfGenerator for quite nicely, and I think that covering that simplified use case should be an eventual goal.

At the moment my focus is on getting infrastructure that is capable of testing largely un-tested and untestable (with current tools) code.

I'll be in the office again on Tuesday, maybe we can grab a cup of coffee and discuss this in more detail in person?

-Chris

> -- adrian
> 
>> 
>>> On Jan 3, 2017, at 3:23 PM, Adrian Prantl <aprantl at apple.com> wrote:
>>> 
>>>> 
>>>> On Dec 20, 2016, at 1:35 PM, Chris Bieneman via llvm-commits <llvm-commits at lists.llvm.org> wrote:
>>>> 
>>>> Author: cbieneman
>>>> Date: Tue Dec 20 15:35:31 2016
>>>> New Revision: 290204
>>>> 
>>>> URL: http://llvm.org/viewvc/llvm-project?rev=290204&view=rev
>>>> Log:
>>>> [ObjectYAML] Support for DWARF debug_info section
>>>> 
>>>> This patch adds support for YAML<->DWARF for debug_info sections.
>>>> 
>>>> This re-lands r290147, after fixing the issue that caused bots to fail (thank you UBSan!).
>>>> 
>>>> Added:
>>>>  llvm/trunk/test/ObjectYAML/MachO/DWARF-debug_info.yaml
>>>> Modified:
>>>>  llvm/trunk/include/llvm/DebugInfo/DWARF/DWARFFormValue.h
>>>>  llvm/trunk/include/llvm/DebugInfo/DWARF/DWARFUnit.h
>>>>  llvm/trunk/include/llvm/ObjectYAML/DWARFYAML.h
>>>>  llvm/trunk/include/llvm/ObjectYAML/MachOYAML.h
>>>>  llvm/trunk/lib/DebugInfo/DWARF/DWARFFormValue.cpp
>>>>  llvm/trunk/lib/ObjectYAML/DWARFYAML.cpp
>>>>  llvm/trunk/tools/obj2yaml/dwarf2yaml.cpp
>>>>  llvm/trunk/tools/yaml2obj/yaml2dwarf.cpp
>>>>  llvm/trunk/tools/yaml2obj/yaml2macho.cpp
>>>>  llvm/trunk/tools/yaml2obj/yaml2obj.h
>>>> 
>>>> Modified: llvm/trunk/include/llvm/DebugInfo/DWARF/DWARFFormValue.h
>>>> URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/include/llvm/DebugInfo/DWARF/DWARFFormValue.h?rev=290204&r1=290203&r2=290204&view=diff
>>>> ==============================================================================
>>>> --- llvm/trunk/include/llvm/DebugInfo/DWARF/DWARFFormValue.h (original)
>>>> +++ llvm/trunk/include/llvm/DebugInfo/DWARF/DWARFFormValue.h Tue Dec 20 15:35:31 2016
>>>> @@ -82,6 +82,8 @@ public:
>>>> Optional<uint64_t> getAsAddress() const;
>>>> Optional<uint64_t> getAsSectionOffset() const;
>>>> Optional<ArrayRef<uint8_t>> getAsBlock() const;
>>>> +  Optional<uint64_t> getAsCStringOffset() const;
>>>> +  Optional<uint64_t> getAsReferenceUVal() const;
>>>> /// Get the fixed byte size for a given form.
>>>> ///
>>>> /// If the form always has a fixed valid byte size that doesn't depend on a
>>>> 
>>>> Modified: llvm/trunk/include/llvm/DebugInfo/DWARF/DWARFUnit.h
>>>> URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/include/llvm/DebugInfo/DWARF/DWARFUnit.h?rev=290204&r1=290203&r2=290204&view=diff
>>>> ==============================================================================
>>>> --- llvm/trunk/include/llvm/DebugInfo/DWARF/DWARFUnit.h (original)
>>>> +++ llvm/trunk/include/llvm/DebugInfo/DWARF/DWARFUnit.h Tue Dec 20 15:35:31 2016
>>>> @@ -11,6 +11,7 @@
>>>> #define LLVM_LIB_DEBUGINFO_DWARFUNIT_H
>>>> 
>>>> #include "llvm/ADT/Optional.h"
>>>> +#include "llvm/ADT/iterator_range.h"
>>>> #include "llvm/ADT/STLExtras.h"
>>>> #include "llvm/DebugInfo/DWARF/DWARFDebugAbbrev.h"
>>>> #include "llvm/DebugInfo/DWARF/DWARFDebugInfoEntry.h"
>>>> @@ -127,6 +128,8 @@ class DWARFUnit {
>>>> uint64_t BaseAddr;
>>>> // The compile unit debug information entry items.
>>>> std::vector<DWARFDebugInfoEntry> DieArray;
>>>> +  typedef iterator_range<std::vector<DWARFDebugInfoEntry>::iterator>
>>>> +      die_iterator_range;
>>>> 
>>>> class DWOHolder {
>>>>   object::OwningBinary<object::ObjectFile> DWOFile;
>>>> @@ -288,6 +291,11 @@ public:
>>>>   return 0;
>>>> }
>>>> 
>>>> +  die_iterator_range dies() {
>>>> +    extractDIEsIfNeeded(false);
>>>> +    return die_iterator_range(DieArray.begin(), DieArray.end());
>>>> +  }
>>>> +
>>>> private:
>>>> /// Size in bytes of the .debug_info data associated with this compile unit.
>>>> size_t getDebugInfoSize() const { return Length + 4 - getHeaderSize(); }
>>>> 
>>>> Modified: llvm/trunk/include/llvm/ObjectYAML/DWARFYAML.h
>>>> URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/include/llvm/ObjectYAML/DWARFYAML.h?rev=290204&r1=290203&r2=290204&view=diff
>>>> ==============================================================================
>>>> --- llvm/trunk/include/llvm/ObjectYAML/DWARFYAML.h (original)
>>>> +++ llvm/trunk/include/llvm/ObjectYAML/DWARFYAML.h Tue Dec 20 15:35:31 2016
>>>> @@ -66,6 +66,25 @@ struct PubSection {
>>>> std::vector<PubEntry> Entries;
>>>> };
>>>> 
>>>> +struct FormValue {
>>>> +  llvm::yaml::Hex64 Value;
>>>> +  StringRef CStr;
>>>> +  std::vector<llvm::yaml::Hex8> BlockData;
>>>> +};
>>>> +
>>>> +struct Entry {
>>>> +  llvm::yaml::Hex32 AbbrCode;
>>>> +  std::vector<FormValue> Values;
>>>> +};
>>>> +
>>>> +struct Unit {
>>>> +  uint32_t Length;
>>>> +  uint16_t Version;
>>>> +  uint32_t AbbrOffset;
>>>> +  uint8_t AddrSize;
>>>> +  std::vector<Entry> Entries;
>>>> +};
>>>> +
>>>> struct Data {
>>>> std::vector<Abbrev> AbbrevDecls;
>>>> std::vector<StringRef> DebugStrings;
>>>> @@ -75,6 +94,8 @@ struct Data {
>>>> 
>>>> PubSection GNUPubNames;
>>>> PubSection GNUPubTypes;
>>>> +  
>>>> +  std::vector<Unit> CompileUnits;
>>>> 
>>>> bool isEmpty() const;
>>>> };
>>>> @@ -82,12 +103,17 @@ struct Data {
>>>> } // namespace llvm::DWARFYAML
>>>> } // namespace llvm
>>>> 
>>>> +LLVM_YAML_IS_SEQUENCE_VECTOR(uint8_t)
>>>> LLVM_YAML_IS_SEQUENCE_VECTOR(llvm::StringRef)
>>>> +LLVM_YAML_IS_SEQUENCE_VECTOR(llvm::yaml::Hex8)
>>>> LLVM_YAML_IS_SEQUENCE_VECTOR(llvm::DWARFYAML::AttributeAbbrev)
>>>> LLVM_YAML_IS_SEQUENCE_VECTOR(llvm::DWARFYAML::Abbrev)
>>>> LLVM_YAML_IS_SEQUENCE_VECTOR(llvm::DWARFYAML::ARangeDescriptor)
>>>> LLVM_YAML_IS_SEQUENCE_VECTOR(llvm::DWARFYAML::ARange)
>>>> LLVM_YAML_IS_SEQUENCE_VECTOR(llvm::DWARFYAML::PubEntry)
>>>> +LLVM_YAML_IS_SEQUENCE_VECTOR(llvm::DWARFYAML::Unit)
>>>> +LLVM_YAML_IS_SEQUENCE_VECTOR(llvm::DWARFYAML::FormValue)
>>>> +LLVM_YAML_IS_SEQUENCE_VECTOR(llvm::DWARFYAML::Entry)
>>>> 
>>>> namespace llvm {
>>>> namespace yaml {
>>>> @@ -120,6 +146,18 @@ template <> struct MappingTraits<DWARFYA
>>>> static void mapping(IO &IO, DWARFYAML::PubSection &Section);
>>>> };
>>>> 
>>>> +template <> struct MappingTraits<DWARFYAML::Unit> {
>>>> +  static void mapping(IO &IO, DWARFYAML::Unit &Unit);
>>>> +};
>>>> +
>>>> +template <> struct MappingTraits<DWARFYAML::Entry> {
>>>> +  static void mapping(IO &IO, DWARFYAML::Entry &Entry);
>>>> +};
>>>> +
>>>> +template <> struct MappingTraits<DWARFYAML::FormValue> {
>>>> +  static void mapping(IO &IO, DWARFYAML::FormValue &FormValue);
>>>> +};
>>>> +
>>>> #define HANDLE_DW_TAG(unused, name)                                            \
>>>> io.enumCase(value, "DW_TAG_" #name, dwarf::DW_TAG_##name);
>>>> 
>>>> 
>>>> Modified: llvm/trunk/include/llvm/ObjectYAML/MachOYAML.h
>>>> URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/include/llvm/ObjectYAML/MachOYAML.h?rev=290204&r1=290203&r2=290204&view=diff
>>>> ==============================================================================
>>>> --- llvm/trunk/include/llvm/ObjectYAML/MachOYAML.h (original)
>>>> +++ llvm/trunk/include/llvm/ObjectYAML/MachOYAML.h Tue Dec 20 15:35:31 2016
>>>> @@ -138,7 +138,6 @@ struct UniversalBinary {
>>>> 
>>>> LLVM_YAML_IS_SEQUENCE_VECTOR(llvm::MachOYAML::LoadCommand)
>>>> LLVM_YAML_IS_SEQUENCE_VECTOR(llvm::MachOYAML::Section)
>>>> -LLVM_YAML_IS_SEQUENCE_VECTOR(llvm::yaml::Hex8)
>>>> LLVM_YAML_IS_SEQUENCE_VECTOR(llvm::yaml::Hex64)
>>>> LLVM_YAML_IS_SEQUENCE_VECTOR(int64_t)
>>>> LLVM_YAML_IS_SEQUENCE_VECTOR(llvm::MachOYAML::RebaseOpcode)
>>>> 
>>>> Modified: llvm/trunk/lib/DebugInfo/DWARF/DWARFFormValue.cpp
>>>> URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/DebugInfo/DWARF/DWARFFormValue.cpp?rev=290204&r1=290203&r2=290204&view=diff
>>>> ==============================================================================
>>>> --- llvm/trunk/lib/DebugInfo/DWARF/DWARFFormValue.cpp (original)
>>>> +++ llvm/trunk/lib/DebugInfo/DWARF/DWARFFormValue.cpp Tue Dec 20 15:35:31 2016
>>>> @@ -661,3 +661,15 @@ Optional<ArrayRef<uint8_t>> DWARFFormVal
>>>> return makeArrayRef(Value.data, Value.uval);
>>>> }
>>>> 
>>>> +Optional<uint64_t> DWARFFormValue::getAsCStringOffset() const {
>>>> +  if (!isFormClass(FC_String) && Form == DW_FORM_string)
>>>> +    return None;
>>>> +  return Value.uval;
>>>> +}
>>>> +
>>>> +Optional<uint64_t> DWARFFormValue::getAsReferenceUVal() const {
>>>> +  if (!isFormClass(FC_Reference))
>>>> +    return None;
>>>> +  return Value.uval;
>>>> +}
>>>> +
>>>> 
>>>> Modified: llvm/trunk/lib/ObjectYAML/DWARFYAML.cpp
>>>> URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/ObjectYAML/DWARFYAML.cpp?rev=290204&r1=290203&r2=290204&view=diff
>>>> ==============================================================================
>>>> --- llvm/trunk/lib/ObjectYAML/DWARFYAML.cpp (original)
>>>> +++ llvm/trunk/lib/ObjectYAML/DWARFYAML.cpp Tue Dec 20 15:35:31 2016
>>>> @@ -22,8 +22,9 @@ bool DWARFYAML::Data::isEmpty() const {
>>>> 
>>>> namespace yaml {
>>>> 
>>>> -void MappingTraits<DWARFYAML::Data>::mapping(
>>>> -    IO &IO, DWARFYAML::Data &DWARF) {
>>>> +void MappingTraits<DWARFYAML::Data>::mapping(IO &IO, DWARFYAML::Data &DWARF) {
>>>> +  auto oldContext = IO.getContext();
>>>> +  IO.setContext(&DWARF);
>>>> IO.mapOptional("debug_str", DWARF.DebugStrings);
>>>> IO.mapOptional("debug_abbrev", DWARF.AbbrevDecls);
>>>> if(!DWARF.ARanges.empty() || !IO.outputting())
>>>> @@ -36,10 +37,12 @@ void MappingTraits<DWARFYAML::Data>::map
>>>>   IO.mapOptional("debug_gnu_pubnames", DWARF.GNUPubNames);
>>>> if(!DWARF.GNUPubTypes.Entries.empty() || !IO.outputting())
>>>>   IO.mapOptional("debug_gnu_pubtypes", DWARF.GNUPubTypes);
>>>> +  IO.mapOptional("debug_info", DWARF.CompileUnits);
>>>> +  IO.setContext(&oldContext);
>>>> }
>>>> 
>>>> -void MappingTraits<DWARFYAML::Abbrev>::mapping(
>>>> -    IO &IO, DWARFYAML::Abbrev &Abbrev) {
>>>> +void MappingTraits<DWARFYAML::Abbrev>::mapping(IO &IO,
>>>> +                                               DWARFYAML::Abbrev &Abbrev) {
>>>> IO.mapRequired("Code", Abbrev.Code);
>>>> IO.mapRequired("Tag", Abbrev.Tag);
>>>> IO.mapRequired("Children", Abbrev.Children);
>>>> @@ -90,6 +93,28 @@ void MappingTraits<DWARFYAML::PubSection
>>>> IO.setContext(OldContext);
>>>> }
>>>> 
>>>> +void MappingTraits<DWARFYAML::Unit>::mapping(IO &IO, DWARFYAML::Unit &Unit) {
>>>> +  IO.mapRequired("Length", Unit.Length);
>>>> +  IO.mapRequired("Version", Unit.Version);
>>>> +  IO.mapRequired("AbbrOffset", Unit.AbbrOffset);
>>>> +  IO.mapRequired("AddrSize", Unit.AddrSize);
>>>> +  IO.mapOptional("Entries", Unit.Entries);
>>>> +}
>>>> +
>>>> +void MappingTraits<DWARFYAML::Entry>::mapping(IO &IO, DWARFYAML::Entry &Entry) {
>>>> +  IO.mapRequired("AbbrCode", Entry.AbbrCode);
>>>> +  IO.mapRequired("Values", Entry.Values);
>>>> +}
>>>> +
>>>> +void MappingTraits<DWARFYAML::FormValue>::mapping(IO &IO,
>>>> +                                             DWARFYAML::FormValue &FormValue) {
>>>> +  IO.mapOptional("Value", FormValue.Value);
>>>> +  if(!FormValue.CStr.empty() || !IO.outputting())
>>>> +    IO.mapOptional("CStr", FormValue.CStr);
>>>> +  if(!FormValue.BlockData.empty() || !IO.outputting())
>>>> +    IO.mapOptional("BlockData", FormValue.BlockData);
>>>> +}
>>>> +
>>>> } // namespace llvm::yaml
>>>> 
>>>> } // namespace llvm
>>>> 
>>>> Added: llvm/trunk/test/ObjectYAML/MachO/DWARF-debug_info.yaml
>>>> URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/test/ObjectYAML/MachO/DWARF-debug_info.yaml?rev=290204&view=auto
>>>> ==============================================================================
>>>> --- llvm/trunk/test/ObjectYAML/MachO/DWARF-debug_info.yaml (added)
>>>> +++ llvm/trunk/test/ObjectYAML/MachO/DWARF-debug_info.yaml Tue Dec 20 15:35:31 2016
>>>> @@ -0,0 +1,525 @@
>>>> +# RUN: yaml2obj %s | obj2yaml | FileCheck %s
>>>> +
>>>> +--- !mach-o
>>>> +FileHeader:      
>>>> +  magic:           0xFEEDFACF
>>>> +  cputype:         0x01000007
>>>> +  cpusubtype:      0x00000003
>>>> +  filetype:        0x0000000A
>>>> +  ncmds:           5
>>>> +  sizeofcmds:      1800
>>>> +  flags:           0x00000000
>>>> +  reserved:        0x00000000
>>>> +LoadCommands:    
>>>> +  - cmd:             LC_SEGMENT_64
>>>> +    cmdsize:         72
>>>> +    segname:         __PAGEZERO
>>>> +    vmaddr:          0
>>>> +    vmsize:          4294967296
>>>> +    fileoff:         0
>>>> +    filesize:        0
>>>> +    maxprot:         0
>>>> +    initprot:        0
>>>> +    nsects:          0
>>>> +    flags:           0
>>>> +  - cmd:             LC_SEGMENT_64
>>>> +    cmdsize:         472
>>>> +    segname:         __TEXT
>>>> +    vmaddr:          4294967296
>>>> +    vmsize:          4096
>>>> +    fileoff:         0
>>>> +    filesize:        0
>>>> +    maxprot:         7
>>>> +    initprot:        5
>>>> +    nsects:          5
>>>> +    flags:           0
>>>> +    Sections:        
>>>> +      - sectname:        __text
>>>> +        segname:         __TEXT
>>>> +        addr:            0x0000000100000F50
>>>> +        size:            52
>>>> +        offset:          0x00000000
>>>> +        align:           4
>>>> +        reloff:          0x00000000
>>>> +        nreloc:          0
>>>> +        flags:           0x80000400
>>>> +        reserved1:       0x00000000
>>>> +        reserved2:       0x00000000
>>>> +        reserved3:       0x00000000
>>>> +      - sectname:        __stubs
>>>> +        segname:         __TEXT
>>>> +        addr:            0x0000000100000F84
>>>> +        size:            6
>>>> +        offset:          0x00000000
>>>> +        align:           1
>>>> +        reloff:          0x00000000
>>>> +        nreloc:          0
>>>> +        flags:           0x80000408
>>>> +        reserved1:       0x00000000
>>>> +        reserved2:       0x00000006
>>>> +        reserved3:       0x00000000
>>>> +      - sectname:        __stub_helper
>>>> +        segname:         __TEXT
>>>> +        addr:            0x0000000100000F8C
>>>> +        size:            26
>>>> +        offset:          0x00000000
>>>> +        align:           2
>>>> +        reloff:          0x00000000
>>>> +        nreloc:          0
>>>> +        flags:           0x80000400
>>>> +        reserved1:       0x00000000
>>>> +        reserved2:       0x00000000
>>>> +        reserved3:       0x00000000
>>>> +      - sectname:        __cstring
>>>> +        segname:         __TEXT
>>>> +        addr:            0x0000000100000FA6
>>>> +        size:            14
>>>> +        offset:          0x00000000
>>>> +        align:           0
>>>> +        reloff:          0x00000000
>>>> +        nreloc:          0
>>>> +        flags:           0x00000002
>>>> +        reserved1:       0x00000000
>>>> +        reserved2:       0x00000000
>>>> +        reserved3:       0x00000000
>>>> +      - sectname:        __unwind_info
>>>> +        segname:         __TEXT
>>>> +        addr:            0x0000000100000FB4
>>>> +        size:            72
>>>> +        offset:          0x00000000
>>>> +        align:           2
>>>> +        reloff:          0x00000000
>>>> +        nreloc:          0
>>>> +        flags:           0x00000000
>>>> +        reserved1:       0x00000000
>>>> +        reserved2:       0x00000000
>>>> +        reserved3:       0x00000000
>>>> +  - cmd:             LC_SEGMENT_64
>>>> +    cmdsize:         232
>>>> +    segname:         __DATA
>>>> +    vmaddr:          4294971392
>>>> +    vmsize:          4096
>>>> +    fileoff:         0
>>>> +    filesize:        0
>>>> +    maxprot:         7
>>>> +    initprot:        3
>>>> +    nsects:          2
>>>> +    flags:           0
>>>> +    Sections:        
>>>> +      - sectname:        __nl_symbol_ptr
>>>> +        segname:         __DATA
>>>> +        addr:            0x0000000100001000
>>>> +        size:            16
>>>> +        offset:          0x00000000
>>>> +        align:           3
>>>> +        reloff:          0x00000000
>>>> +        nreloc:          0
>>>> +        flags:           0x00000006
>>>> +        reserved1:       0x00000001
>>>> +        reserved2:       0x00000000
>>>> +        reserved3:       0x00000000
>>>> +      - sectname:        __la_symbol_ptr
>>>> +        segname:         __DATA
>>>> +        addr:            0x0000000100001010
>>>> +        size:            8
>>>> +        offset:          0x00000000
>>>> +        align:           3
>>>> +        reloff:          0x00000000
>>>> +        nreloc:          0
>>>> +        flags:           0x00000007
>>>> +        reserved1:       0x00000003
>>>> +        reserved2:       0x00000000
>>>> +        reserved3:       0x00000000
>>>> +  - cmd:             LC_SEGMENT_64
>>>> +    cmdsize:         72
>>>> +    segname:         __LINKEDIT
>>>> +    vmaddr:          4294975488
>>>> +    vmsize:          4096
>>>> +    fileoff:         4096
>>>> +    filesize:        60
>>>> +    maxprot:         7
>>>> +    initprot:        1
>>>> +    nsects:          0
>>>> +    flags:           0
>>>> +  - cmd:             LC_SEGMENT_64
>>>> +    cmdsize:         952
>>>> +    segname:         __DWARF
>>>> +    vmaddr:          4294979584
>>>> +    vmsize:          4096
>>>> +    fileoff:         8192
>>>> +    filesize:        764
>>>> +    maxprot:         7
>>>> +    initprot:        3
>>>> +    nsects:          11
>>>> +    flags:           0
>>>> +    Sections:        
>>>> +      - sectname:        __debug_line
>>>> +        segname:         __DWARF
>>>> +        addr:            0x0000000100003000
>>>> +        size:            69
>>>> +        offset:          0x00002000
>>>> +        align:           0
>>>> +        reloff:          0x00000000
>>>> +        nreloc:          0
>>>> +        flags:           0x00000000
>>>> +        reserved1:       0x00000000
>>>> +        reserved2:       0x00000000
>>>> +        reserved3:       0x00000000
>>>> +      - sectname:        __debug_pubnames
>>>> +        segname:         __DWARF
>>>> +        addr:            0x0000000100003045
>>>> +        size:            27
>>>> +        offset:          0x00002045
>>>> +        align:           0
>>>> +        reloff:          0x00000000
>>>> +        nreloc:          0
>>>> +        flags:           0x00000000
>>>> +        reserved1:       0x00000000
>>>> +        reserved2:       0x00000000
>>>> +        reserved3:       0x00000000
>>>> +      - sectname:        __debug_pubtypes
>>>> +        segname:         __DWARF
>>>> +        addr:            0x0000000100003060
>>>> +        size:            35
>>>> +        offset:          0x00002060
>>>> +        align:           0
>>>> +        reloff:          0x00000000
>>>> +        nreloc:          0
>>>> +        flags:           0x00000000
>>>> +        reserved1:       0x00000000
>>>> +        reserved2:       0x00000000
>>>> +        reserved3:       0x00000000
>>>> +      - sectname:        __debug_aranges
>>>> +        segname:         __DWARF
>>>> +        addr:            0x0000000100003083
>>>> +        size:            48
>>>> +        offset:          0x00002083
>>>> +        align:           0
>>>> +        reloff:          0x00000000
>>>> +        nreloc:          0
>>>> +        flags:           0x00000000
>>>> +        reserved1:       0x00000000
>>>> +        reserved2:       0x00000000
>>>> +        reserved3:       0x00000000
>>>> +      - sectname:        __debug_info
>>>> +        segname:         __DWARF
>>>> +        addr:            0x00000001000030B3
>>>> +        size:            121
>>>> +        offset:          0x000020B3
>>>> +        align:           0
>>>> +        reloff:          0x00000000
>>>> +        nreloc:          0
>>>> +        flags:           0x00000000
>>>> +        reserved1:       0x00000000
>>>> +        reserved2:       0x00000000
>>>> +        reserved3:       0x00000000
>>>> +      - sectname:        __debug_abbrev
>>>> +        segname:         __DWARF
>>>> +        addr:            0x000000010000312C
>>>> +        size:            76
>>>> +        offset:          0x0000212C
>>>> +        align:           0
>>>> +        reloff:          0x00000000
>>>> +        nreloc:          0
>>>> +        flags:           0x00000000
>>>> +        reserved1:       0x00000000
>>>> +        reserved2:       0x00000000
>>>> +        reserved3:       0x00000000
>>>> +      - sectname:        __debug_str
>>>> +        segname:         __DWARF
>>>> +        addr:            0x0000000100003178
>>>> +        size:            142
>>>> +        offset:          0x00002178
>>>> +        align:           0
>>>> +        reloff:          0x00000000
>>>> +        nreloc:          0
>>>> +        flags:           0x00000000
>>>> +        reserved1:       0x00000000
>>>> +        reserved2:       0x00000000
>>>> +        reserved3:       0x00000000
>>>> +      - sectname:        __apple_names
>>>> +        segname:         __DWARF
>>>> +        addr:            0x0000000100003206
>>>> +        size:            60
>>>> +        offset:          0x00002206
>>>> +        align:           0
>>>> +        reloff:          0x00000000
>>>> +        nreloc:          0
>>>> +        flags:           0x00000000
>>>> +        reserved1:       0x00000000
>>>> +        reserved2:       0x00000000
>>>> +        reserved3:       0x00000000
>>>> +      - sectname:        __apple_namespac
>>>> +        segname:         __DWARF
>>>> +        addr:            0x0000000100003242
>>>> +        size:            36
>>>> +        offset:          0x00002242
>>>> +        align:           0
>>>> +        reloff:          0x00000000
>>>> +        nreloc:          0
>>>> +        flags:           0x00000000
>>>> +        reserved1:       0x00000000
>>>> +        reserved2:       0x00000000
>>>> +        reserved3:       0x00000000
>>>> +      - sectname:        __apple_types
>>>> +        segname:         __DWARF
>>>> +        addr:            0x0000000100003266
>>>> +        size:            114
>>>> +        offset:          0x00002266
>>>> +        align:           0
>>>> +        reloff:          0x00000000
>>>> +        nreloc:          0
>>>> +        flags:           0x00000000
>>>> +        reserved1:       0x00000000
>>>> +        reserved2:       0x00000000
>>>> +        reserved3:       0x00000000
>>>> +      - sectname:        __apple_objc
>>>> +        segname:         __DWARF
>>>> +        addr:            0x00000001000032D8
>>>> +        size:            36
>>>> +        offset:          0x000022D8
>>>> +        align:           0
>>>> +        reloff:          0x00000000
>>>> +        nreloc:          0
>>>> +        flags:           0x00000000
>>>> +        reserved1:       0x00000000
>>>> +        reserved2:       0x00000000
>>>> +        reserved3:       0x00000000
>>>> +LinkEditData:    
>>>> +  NameList:        
>>>> +    - n_strx:          2
>>>> +      n_type:          0x0F
>>>> +      n_sect:          1
>>>> +      n_desc:          16
>>>> +      n_value:         4294967296
>>>> +    - n_strx:          22
>>>> +      n_type:          0x0F
>>>> +      n_sect:          1
>>>> +      n_desc:          0
>>>> +      n_value:         4294971216
>>>> +  StringTable:     
>>>> +    - ''
>>>> +    - ''
>>>> +    - __mh_execute_header
>>>> +    - _main
>>>> +DWARF:           
>>>> +  debug_abbrev:    
>>>> +    - Code:            0x00000001
>>>> +      Tag:             DW_TAG_compile_unit
>>>> +      Children:        DW_CHILDREN_yes
>>>> +      Attributes:      
>>>> +        - Attribute:       DW_AT_producer
>>>> +          Form:            DW_FORM_strp
>>>> +        - Attribute:       DW_AT_language
>>>> +          Form:            DW_FORM_data2
>>>> +        - Attribute:       DW_AT_name
>>>> +          Form:            DW_FORM_strp
>>>> +        - Attribute:       DW_AT_stmt_list
>>>> +          Form:            DW_FORM_sec_offset
>>>> +        - Attribute:       DW_AT_comp_dir
>>>> +          Form:            DW_FORM_strp
>>>> +        - Attribute:       DW_AT_low_pc
>>>> +          Form:            DW_FORM_addr
>>>> +        - Attribute:       DW_AT_high_pc
>>>> +          Form:            DW_FORM_data4
>>>> +    - Code:            0x00000002
>>>> +      Tag:             DW_TAG_subprogram
>>>> +      Children:        DW_CHILDREN_yes
>>>> +      Attributes:      
>>>> +        - Attribute:       DW_AT_low_pc
>>>> +          Form:            DW_FORM_addr
>>>> +        - Attribute:       DW_AT_high_pc
>>>> +          Form:            DW_FORM_data4
>>>> +        - Attribute:       DW_AT_frame_base
>>>> +          Form:            DW_FORM_exprloc
>>>> +        - Attribute:       DW_AT_name
>>>> +          Form:            DW_FORM_strp
>>>> +        - Attribute:       DW_AT_decl_file
>>>> +          Form:            DW_FORM_data1
>>>> +        - Attribute:       DW_AT_decl_line
>>>> +          Form:            DW_FORM_data1
>>>> +        - Attribute:       DW_AT_prototyped
>>>> +          Form:            DW_FORM_flag_present
>>>> +        - Attribute:       DW_AT_type
>>>> +          Form:            DW_FORM_ref4
>>>> +        - Attribute:       DW_AT_external
>>>> +          Form:            DW_FORM_flag_present
>>>> +    - Code:            0x00000003
>>>> +      Tag:             DW_TAG_formal_parameter
>>>> +      Children:        DW_CHILDREN_no
>>>> +      Attributes:      
>>>> +        - Attribute:       DW_AT_location
>>>> +          Form:            DW_FORM_exprloc
>>>> +        - Attribute:       DW_AT_name
>>>> +          Form:            DW_FORM_strp
>>>> +        - Attribute:       DW_AT_decl_file
>>>> +          Form:            DW_FORM_data1
>>>> +        - Attribute:       DW_AT_decl_line
>>>> +          Form:            DW_FORM_data1
>>>> +        - Attribute:       DW_AT_type
>>>> +          Form:            DW_FORM_ref4
>>>> +    - Code:            0x00000004
>>>> +      Tag:             DW_TAG_base_type
>>>> +      Children:        DW_CHILDREN_no
>>>> +      Attributes:      
>>>> +        - Attribute:       DW_AT_name
>>>> +          Form:            DW_FORM_strp
>>>> +        - Attribute:       DW_AT_encoding
>>>> +          Form:            DW_FORM_data1
>>>> +        - Attribute:       DW_AT_byte_size
>>>> +          Form:            DW_FORM_data1
>>>> +    - Code:            0x00000005
>>>> +      Tag:             DW_TAG_pointer_type
>>>> +      Children:        DW_CHILDREN_no
>>>> +      Attributes:      
>>>> +        - Attribute:       DW_AT_type
>>>> +          Form:            DW_FORM_ref4
>>>> +  debug_aranges:   
>>>> +    - Length:          44
>>>> +      Version:         2
>>>> +      CuOffset:        0
>>>> +      AddrSize:        8
>>>> +      SegSize:         0
>>>> +      Descriptors:     
>>>> +        - Address:         0x0000000100000F50
>>>> +          Length:          52
>>>> +  debug_info:      
>>>> +    - Length:          117
>>>> +      Version:         4
>>>> +      AbbrOffset:      0
>>>> +      AddrSize:        8
>>>> +      Entries:         
>>>> +        - AbbrCode:        0x00000001
>>>> +          Values:          
>>>> +            - Value:           0x0000000000000001
>>>> +            - Value:           0x000000000000000C
>>>> +            - Value:           0x0000000000000038
>>>> +            - Value:           0x0000000000000000
>>>> +            - Value:           0x0000000000000046
>>>> +            - Value:           0x0000000100000F50
>>>> +            - Value:           0x0000000000000034
>>>> +        - AbbrCode:        0x00000002
>>>> +          Values:          
>>>> +            - Value:           0x0000000100000F50
>>>> +            - Value:           0x0000000000000034
>>>> +            - Value:           0x0000000000000001
>>>> +              BlockData:       
>>>> +                - 0x56
>>>> +            - Value:           0x0000000000000076
>>>> +            - Value:           0x0000000000000001
>>>> +            - Value:           0x0000000000000003
>>>> +            - Value:           0x0000000000000001
>>>> +            - Value:           0x0000000000000060
>>>> +            - Value:           0x0000000000000001
>>>> +        - AbbrCode:        0x00000003
>>>> +          Values:          
>>>> +            - Value:           0x0000000000000002
>>>> +              BlockData:       
>>>> +                - 0x91
>>>> +                - 0x78
>>>> +            - Value:           0x000000000000007B
>>>> +            - Value:           0x0000000000000001
>>>> +            - Value:           0x0000000000000003
>>>> +            - Value:           0x0000000000000060
>>>> +        - AbbrCode:        0x00000003
>>>> +          Values:          
>>>> +            - Value:           0x0000000000000002
>>>> +              BlockData:       
>>>> +                - 0x91
>>>> +                - 0x70
>>>> +            - Value:           0x0000000000000080
>>>> +            - Value:           0x0000000000000001
>>>> +            - Value:           0x0000000000000003
>>>> +            - Value:           0x0000000000000067
>>>> +        - AbbrCode:        0x00000000
>>>> +          Values:          
>>>> +        - AbbrCode:        0x00000004
>>>> +          Values:          
>>>> +            - Value:           0x0000000000000085
>>>> +            - Value:           0x0000000000000005
>>>> +            - Value:           0x0000000000000004
>>>> +        - AbbrCode:        0x00000005
>>>> +          Values:          
>>>> +            - Value:           0x000000000000006C
>>>> +        - AbbrCode:        0x00000005
>>>> +          Values:          
>>>> +            - Value:           0x0000000000000071
>>>> +        - AbbrCode:        0x00000004
>>>> +          Values:          
>>>> +            - Value:           0x0000000000000089
>>>> +            - Value:           0x0000000000000006
>>>> +            - Value:           0x0000000000000001
>>>> +        - AbbrCode:        0x00000000
>>>> +          Values:          
>>>> +...
>>>> +
>>>> +
>>> 
>>> Hi Chris,
>>> 
>>> sorry for replying to this so late, I think I missed the original discussion of this feature. Is there a review/proposal thread that outlines were you are going with this syntax?
>>> 
>>> Looking at these examples I'm starting to be afraid that this doesn't really add much over just checking in tests written in assembler (+ perhaps some preprocessor macros for better readability). When I first heard of the YAML->Obj I was envisioning a slightly more higher-level syntax; for example, I would not have expected having to write abbreviations by hand or having to calculate any offsets by hand. I understand that being able to change all fields is useful to test the robustness of the parser, but for such very low-level tests, assembler is probably fine, too.
>>> 
>>> Let me know if I'm misunderstanding the purpose of this syntax (and/or if this isn't the final form of it yet). What kind of tests is this syntax designed for?
>>> 
>>>> +#CHECK: DWARF:           
>>>> +#CHECK:   debug_info:      
>>>> +#CHECK:     - Length:          117
>>>> +#CHECK:       Version:         4
>>>> +#CHECK:       AbbrOffset:      0
>>>> +#CHECK:       AddrSize:        8
>>> 
>>> FYI: Are you aware that the format of the CU header is different in different DWARF major versions?
>> 
>> All of the code I've written for reading and writing DWARF data is based on the DWARF parsing code in libDebugInfo. From reading that code (DWARFUnit.cpp) it does not seem to me that there is anything conditional on version.
>> 
>> There are things in the compile units themselves, specifically the use of AddrSize or offset byte size, which I'm not correctly handling because I need to have line tables working first to identify DWARF32 or DWARF64. I have TODO's in the code marking where that needs to be corrected.
>> 
>> -Chris
>> 
>>> 
>>> -- adrian
>>> 
>>>> +#CHECK:       Entries:         
>>>> +#CHECK:         - AbbrCode:        0x00000001
>>>> +#CHECK:           Values:          
>>>> +#CHECK:             - Value:           0x0000000000000001
>>>> +#CHECK:             - Value:           0x000000000000000C
>>>> +#CHECK:             - Value:           0x0000000000000038
>>>> +#CHECK:             - Value:           0x0000000000000000
>>>> +#CHECK:             - Value:           0x0000000000000046
>>>> +#CHECK:             - Value:           0x0000000100000F50
>>>> +#CHECK:             - Value:           0x0000000000000034
>>>> +#CHECK:         - AbbrCode:        0x00000002
>>> 
>>> 
>>> 
>>> 
>>>> +#CHECK:           Values:          
>>>> +#CHECK:             - Value:           0x0000000100000F50
>>>> +#CHECK:             - Value:           0x0000000000000034
>>>> +#CHECK:             - Value:           0x0000000000000001
>>>> +#CHECK:               BlockData:       
>>>> +#CHECK:                 - 0x56
>>>> +#CHECK:             - Value:           0x0000000000000076
>>>> +#CHECK:             - Value:           0x0000000000000001
>>>> +#CHECK:             - Value:           0x0000000000000003
>>>> +#CHECK:             - Value:           0x0000000000000001
>>>> +#CHECK:             - Value:           0x0000000000000060
>>>> +#CHECK:             - Value:           0x0000000000000001
>>>> +#CHECK:         - AbbrCode:        0x00000003
>>>> +#CHECK:           Values:          
>>>> +#CHECK:             - Value:           0x0000000000000002
>>>> +#CHECK:               BlockData:       
>>>> +#CHECK:                 - 0x91
>>>> +#CHECK:                 - 0x78
>>>> +#CHECK:             - Value:           0x000000000000007B
>>>> +#CHECK:             - Value:           0x0000000000000001
>>>> +#CHECK:             - Value:           0x0000000000000003
>>>> +#CHECK:             - Value:           0x0000000000000060
>>>> +#CHECK:         - AbbrCode:        0x00000003
>>>> +#CHECK:           Values:          
>>>> +#CHECK:             - Value:           0x0000000000000002
>>>> +#CHECK:               BlockData:       
>>>> +#CHECK:                 - 0x91
>>>> +#CHECK:                 - 0x70
>>>> +#CHECK:             - Value:           0x0000000000000080
>>>> +#CHECK:             - Value:           0x0000000000000001
>>>> +#CHECK:             - Value:           0x0000000000000003
>>>> +#CHECK:             - Value:           0x0000000000000067
>>>> +#CHECK:         - AbbrCode:        0x00000000
>>>> +#CHECK:           Values:          
>>>> +#CHECK:         - AbbrCode:        0x00000004
>>>> +#CHECK:           Values:          
>>>> +#CHECK:             - Value:           0x0000000000000085
>>>> +#CHECK:             - Value:           0x0000000000000005
>>>> +#CHECK:             - Value:           0x0000000000000004
>>>> +#CHECK:         - AbbrCode:        0x00000005
>>>> +#CHECK:           Values:          
>>>> +#CHECK:             - Value:           0x000000000000006C
>>>> +#CHECK:         - AbbrCode:        0x00000005
>>>> +#CHECK:           Values:          
>>>> +#CHECK:             - Value:           0x0000000000000071
>>>> +#CHECK:         - AbbrCode:        0x00000004
>>>> +#CHECK:           Values:          
>>>> +#CHECK:             - Value:           0x0000000000000089
>>>> +#CHECK:             - Value:           0x0000000000000006
>>>> +#CHECK:             - Value:           0x0000000000000001
>>>> +#CHECK:         - AbbrCode:        0x00000000
>>>> +#CHECK:           Values:          
>>>> 
>>>> Modified: llvm/trunk/tools/obj2yaml/dwarf2yaml.cpp
>>>> URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/tools/obj2yaml/dwarf2yaml.cpp?rev=290204&r1=290203&r2=290204&view=diff
>>>> ==============================================================================
>>>> --- llvm/trunk/tools/obj2yaml/dwarf2yaml.cpp (original)
>>>> +++ llvm/trunk/tools/obj2yaml/dwarf2yaml.cpp Tue Dec 20 15:35:31 2016
>>>> @@ -10,8 +10,11 @@
>>>> #include "Error.h"
>>>> #include "llvm/DebugInfo/DWARF/DWARFContext.h"
>>>> #include "llvm/DebugInfo/DWARF/DWARFDebugArangeSet.h"
>>>> +#include "llvm/DebugInfo/DWARF/DWARFFormValue.h"
>>>> #include "llvm/ObjectYAML/DWARFYAML.h"
>>>> 
>>>> +#include <algorithm>
>>>> +
>>>> using namespace llvm;
>>>> 
>>>> void dumpDebugAbbrev(DWARFContextInMemory &DCtx, DWARFYAML::Data &Y) {
>>>> @@ -99,12 +102,120 @@ void dumpDebugPubSections(DWARFContextIn
>>>> dumpPubSection(DCtx, Y.GNUPubTypes, DCtx.getGnuPubTypesSection());
>>>> }
>>>> 
>>>> -std::error_code dwarf2yaml(DWARFContextInMemory &DCtx,
>>>> -                           DWARFYAML::Data &Y) {
>>>> +void dumpDebugInfo(DWARFContextInMemory &DCtx, DWARFYAML::Data &Y) {
>>>> +  for (const auto &CU : DCtx.compile_units()) {
>>>> +    DWARFYAML::Unit NewUnit;
>>>> +    NewUnit.Length = CU->getLength();
>>>> +    NewUnit.Version = CU->getVersion();
>>>> +    NewUnit.AbbrOffset = CU->getAbbreviations()->getOffset();
>>>> +    NewUnit.AddrSize = CU->getAddressByteSize();
>>>> +    for (auto DIE : CU->dies()) {
>>>> +      DWARFYAML::Entry NewEntry;
>>>> +      DataExtractor EntryData = CU->getDebugInfoExtractor();
>>>> +      uint32_t offset = DIE.getOffset();
>>>> +
>>>> +      assert(EntryData.isValidOffset(offset) && "Invalid DIE Offset");
>>>> +      if (!EntryData.isValidOffset(offset))
>>>> +        continue;
>>>> +
>>>> +      NewEntry.AbbrCode = EntryData.getULEB128(&offset);
>>>> +
>>>> +      auto AbbrevDecl = DIE.getAbbreviationDeclarationPtr();
>>>> +      if (AbbrevDecl) {
>>>> +        for (const auto &AttrSpec : AbbrevDecl->attributes()) {
>>>> +          DWARFYAML::FormValue NewValue;
>>>> +          NewValue.Value = 0xDEADBEEFDEADBEEF;
>>>> +          DWARFDie DIEWrapper(CU.get(), &DIE);
>>>> +          auto FormValue = DIEWrapper.getAttributeValue(AttrSpec.Attr);
>>>> +          if(!FormValue)
>>>> +            return;
>>>> +          auto Form = FormValue.getValue().getForm();
>>>> +          bool indirect = false;
>>>> +          do {
>>>> +            indirect = false;
>>>> +            switch (Form) {
>>>> +            case dwarf::DW_FORM_addr:
>>>> +            case dwarf::DW_FORM_GNU_addr_index:
>>>> +              if (auto Val = FormValue.getValue().getAsAddress())
>>>> +                NewValue.Value = Val.getValue();
>>>> +              break;
>>>> +            case dwarf::DW_FORM_ref_addr:
>>>> +            case dwarf::DW_FORM_ref1:
>>>> +            case dwarf::DW_FORM_ref2:
>>>> +            case dwarf::DW_FORM_ref4:
>>>> +            case dwarf::DW_FORM_ref8:
>>>> +            case dwarf::DW_FORM_ref_udata:
>>>> +            case dwarf::DW_FORM_ref_sig8:
>>>> +              if (auto Val = FormValue.getValue().getAsReferenceUVal())
>>>> +                NewValue.Value = Val.getValue();
>>>> +              break;
>>>> +            case dwarf::DW_FORM_exprloc:
>>>> +            case dwarf::DW_FORM_block:
>>>> +            case dwarf::DW_FORM_block1:
>>>> +            case dwarf::DW_FORM_block2:
>>>> +            case dwarf::DW_FORM_block4:
>>>> +              if (auto Val = FormValue.getValue().getAsBlock()) {
>>>> +                auto BlockData = Val.getValue();
>>>> +                std::copy(BlockData.begin(), BlockData.end(),
>>>> +                          std::back_inserter(NewValue.BlockData));
>>>> +              }
>>>> +              NewValue.Value = NewValue.BlockData.size();
>>>> +              break;
>>>> +            case dwarf::DW_FORM_data1:
>>>> +            case dwarf::DW_FORM_flag:
>>>> +            case dwarf::DW_FORM_data2:
>>>> +            case dwarf::DW_FORM_data4:
>>>> +            case dwarf::DW_FORM_data8:
>>>> +            case dwarf::DW_FORM_sdata:
>>>> +            case dwarf::DW_FORM_udata:
>>>> +              if (auto Val = FormValue.getValue().getAsUnsignedConstant())
>>>> +                NewValue.Value = Val.getValue();
>>>> +              break;
>>>> +            case dwarf::DW_FORM_string:
>>>> +              if (auto Val = FormValue.getValue().getAsCString())
>>>> +                NewValue.CStr = Val.getValue();
>>>> +              break;
>>>> +            case dwarf::DW_FORM_indirect:
>>>> +              indirect = true;
>>>> +              if (auto Val = FormValue.getValue().getAsUnsignedConstant()) {
>>>> +                NewValue.Value = Val.getValue();
>>>> +                NewEntry.Values.push_back(NewValue);
>>>> +                Form = static_cast<dwarf::Form>(Val.getValue());
>>>> +              }
>>>> +              break;
>>>> +            case dwarf::DW_FORM_strp:
>>>> +            case dwarf::DW_FORM_sec_offset:
>>>> +            case dwarf::DW_FORM_GNU_ref_alt:
>>>> +            case dwarf::DW_FORM_GNU_strp_alt:
>>>> +            case dwarf::DW_FORM_line_strp:
>>>> +            case dwarf::DW_FORM_strp_sup:
>>>> +            case dwarf::DW_FORM_ref_sup:
>>>> +            case dwarf::DW_FORM_GNU_str_index:
>>>> +              if (auto Val = FormValue.getValue().getAsCStringOffset())
>>>> +                NewValue.Value = Val.getValue();
>>>> +              break;
>>>> +            case dwarf::DW_FORM_flag_present:
>>>> +              NewValue.Value = 1;
>>>> +              break;
>>>> +            default:
>>>> +              break;
>>>> +            }
>>>> +          } while (indirect);
>>>> +          NewEntry.Values.push_back(NewValue);
>>>> +        }
>>>> +      }
>>>> +
>>>> +      NewUnit.Entries.push_back(NewEntry);
>>>> +    }
>>>> +    Y.CompileUnits.push_back(NewUnit);
>>>> +  }
>>>> +}
>>>> +
>>>> +std::error_code dwarf2yaml(DWARFContextInMemory &DCtx, DWARFYAML::Data &Y) {
>>>> dumpDebugAbbrev(DCtx, Y);
>>>> dumpDebugStrings(DCtx, Y);
>>>> dumpDebugARanges(DCtx, Y);
>>>> dumpDebugPubSections(DCtx, Y);
>>>> -
>>>> +  dumpDebugInfo(DCtx, Y);
>>>> return obj2yaml_error::success;
>>>> }
>>>> 
>>>> Modified: llvm/trunk/tools/yaml2obj/yaml2dwarf.cpp
>>>> URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/tools/yaml2obj/yaml2dwarf.cpp?rev=290204&r1=290203&r2=290204&view=diff
>>>> ==============================================================================
>>>> --- llvm/trunk/tools/yaml2obj/yaml2dwarf.cpp (original)
>>>> +++ llvm/trunk/tools/yaml2obj/yaml2dwarf.cpp Tue Dec 20 15:35:31 2016
>>>> @@ -17,6 +17,8 @@
>>>> #include "llvm/Support/LEB128.h"
>>>> #include "llvm/Support/raw_ostream.h"
>>>> 
>>>> +#include <algorithm>
>>>> +
>>>> using namespace llvm;
>>>> 
>>>> void ZeroFillBytes(raw_ostream &OS, size_t Size) {
>>>> @@ -80,3 +82,127 @@ void yaml2pubsection(raw_ostream &OS, co
>>>>   OS.write('\0');
>>>> }
>>>> }
>>>> +
>>>> +void yaml2debug_info(raw_ostream &OS, const DWARFYAML::Data &DI) {
>>>> +
>>>> +  for (auto CU : DI.CompileUnits) {
>>>> +    OS.write(reinterpret_cast<char *>(&CU.Length), 4);
>>>> +    OS.write(reinterpret_cast<char *>(&CU.Version), 2);
>>>> +    OS.write(reinterpret_cast<char *>(&CU.AbbrOffset), 4);
>>>> +    OS.write(reinterpret_cast<char *>(&CU.AddrSize), 1);
>>>> +
>>>> +    auto FirstAbbrevCode = CU.Entries[0].AbbrCode;
>>>> +
>>>> +    for (auto Entry : CU.Entries) {
>>>> +      encodeULEB128(Entry.AbbrCode, OS);
>>>> +      if(Entry.AbbrCode == 0u)
>>>> +        continue;
>>>> +      bool Indirect = false;
>>>> +      assert(Entry.AbbrCode-FirstAbbrevCode < DI.AbbrevDecls.size() &&
>>>> +        "Out of range AbbCode");
>>>> +      auto &Abbrev = DI.AbbrevDecls[Entry.AbbrCode-FirstAbbrevCode];
>>>> +
>>>> +      auto FormVal = Entry.Values.begin();
>>>> +      auto AbbrForm = Abbrev.Attributes.begin();
>>>> +      for (;
>>>> +           FormVal != Entry.Values.end() && AbbrForm != Abbrev.Attributes.end();
>>>> +           ++FormVal, ++AbbrForm) {
>>>> +        dwarf::Form Form = AbbrForm->Form;
>>>> +        do {
>>>> +          bool Indirect = false;
>>>> +          switch (Form) {
>>>> +          case dwarf::DW_FORM_addr:
>>>> +            OS.write(reinterpret_cast<char *>(&FormVal->Value), CU.AddrSize);
>>>> +            break;
>>>> +          case dwarf::DW_FORM_ref_addr: {
>>>> +            // TODO: Handle DWARF32/DWARF64 after Line Table data is done
>>>> +            auto writeSize = CU.Version == 2 ? CU.AddrSize : 4;
>>>> +            OS.write(reinterpret_cast<char *>(&FormVal->Value), writeSize);
>>>> +            break;
>>>> +          }
>>>> +          case dwarf::DW_FORM_exprloc:
>>>> +          case dwarf::DW_FORM_block:
>>>> +            encodeULEB128(FormVal->BlockData.size(), OS);
>>>> +            OS.write(reinterpret_cast<char *>(&FormVal->BlockData[0]),
>>>> +                     FormVal->BlockData.size());
>>>> +            break;
>>>> +          case dwarf::DW_FORM_block1: {
>>>> +            auto writeSize = FormVal->BlockData.size();
>>>> +            OS.write(reinterpret_cast<char *>(&writeSize), 1);
>>>> +            OS.write(reinterpret_cast<char *>(&FormVal->BlockData[0]),
>>>> +                     FormVal->BlockData.size());
>>>> +            break;
>>>> +          }
>>>> +          case dwarf::DW_FORM_block2: {
>>>> +            auto writeSize = FormVal->BlockData.size();
>>>> +            OS.write(reinterpret_cast<char *>(&writeSize), 2);
>>>> +            OS.write(reinterpret_cast<char *>(&FormVal->BlockData[0]),
>>>> +                     FormVal->BlockData.size());
>>>> +            break;
>>>> +          }
>>>> +          case dwarf::DW_FORM_block4: {
>>>> +            auto writeSize = FormVal->BlockData.size();
>>>> +            OS.write(reinterpret_cast<char *>(&writeSize), 4);
>>>> +            OS.write(reinterpret_cast<char *>(&FormVal->BlockData[0]),
>>>> +                     FormVal->BlockData.size());
>>>> +            break;
>>>> +          }
>>>> +          case dwarf::DW_FORM_data1:
>>>> +          case dwarf::DW_FORM_ref1:
>>>> +          case dwarf::DW_FORM_flag:
>>>> +            OS.write(reinterpret_cast<char *>(&FormVal->Value), 1);
>>>> +            break;
>>>> +          case dwarf::DW_FORM_data2:
>>>> +          case dwarf::DW_FORM_ref2:
>>>> +            OS.write(reinterpret_cast<char *>(&FormVal->Value), 2);
>>>> +            break;
>>>> +          case dwarf::DW_FORM_data4:
>>>> +          case dwarf::DW_FORM_ref4:
>>>> +            OS.write(reinterpret_cast<char *>(&FormVal->Value), 4);
>>>> +            break;
>>>> +          case dwarf::DW_FORM_data8:
>>>> +          case dwarf::DW_FORM_ref8:
>>>> +            OS.write(reinterpret_cast<char *>(&FormVal->Value), 8);
>>>> +            break;
>>>> +          case dwarf::DW_FORM_sdata:
>>>> +            encodeSLEB128(FormVal->Value, OS);
>>>> +            break;
>>>> +          case dwarf::DW_FORM_udata:
>>>> +          case dwarf::DW_FORM_ref_udata:
>>>> +            encodeULEB128(FormVal->Value, OS);
>>>> +            break;
>>>> +          case dwarf::DW_FORM_string:
>>>> +            OS.write(FormVal->CStr.data(), FormVal->CStr.size());
>>>> +            OS.write('\0');
>>>> +            break;
>>>> +          case dwarf::DW_FORM_indirect:
>>>> +            encodeULEB128(FormVal->Value, OS);
>>>> +            Indirect = true;
>>>> +            Form = static_cast<dwarf::Form>((uint64_t)FormVal->Value);
>>>> +            ++FormVal;
>>>> +            break;
>>>> +          case dwarf::DW_FORM_strp:
>>>> +          case dwarf::DW_FORM_sec_offset:
>>>> +          case dwarf::DW_FORM_GNU_ref_alt:
>>>> +          case dwarf::DW_FORM_GNU_strp_alt:
>>>> +          case dwarf::DW_FORM_line_strp:
>>>> +          case dwarf::DW_FORM_strp_sup:
>>>> +          case dwarf::DW_FORM_ref_sup:
>>>> +            // TODO: Handle DWARF32/64
>>>> +            OS.write(reinterpret_cast<char *>(&FormVal->Value), 4);
>>>> +            break;
>>>> +          case dwarf::DW_FORM_ref_sig8:
>>>> +            OS.write(reinterpret_cast<char *>(&FormVal->Value), 8);
>>>> +            break;
>>>> +          case dwarf::DW_FORM_GNU_addr_index:
>>>> +          case dwarf::DW_FORM_GNU_str_index:
>>>> +            encodeULEB128(FormVal->Value, OS);
>>>> +            break;
>>>> +          default:
>>>> +            break;
>>>> +          }
>>>> +        } while (Indirect);
>>>> +      }
>>>> +    }
>>>> +  }
>>>> +}
>>>> 
>>>> Modified: llvm/trunk/tools/yaml2obj/yaml2macho.cpp
>>>> URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/tools/yaml2obj/yaml2macho.cpp?rev=290204&r1=290203&r2=290204&view=diff
>>>> ==============================================================================
>>>> --- llvm/trunk/tools/yaml2obj/yaml2macho.cpp (original)
>>>> +++ llvm/trunk/tools/yaml2obj/yaml2macho.cpp Tue Dec 20 15:35:31 2016
>>>> @@ -398,6 +398,8 @@ Error MachOWriter::writeDWARFData(raw_os
>>>>     yaml2pubsection(OS, Obj.DWARF.PubNames);
>>>>   } else if (0 == strncmp(&Section.sectname[0], "__debug_pubtypes", 16)) {
>>>>     yaml2pubsection(OS, Obj.DWARF.PubTypes);
>>>> +    } else if (0 == strncmp(&Section.sectname[0], "__debug_info", 16)) {
>>>> +      yaml2debug_info(OS, Obj.DWARF);
>>>>   }
>>>> }
>>>> return Error::success();
>>>> 
>>>> Modified: llvm/trunk/tools/yaml2obj/yaml2obj.h
>>>> URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/tools/yaml2obj/yaml2obj.h?rev=290204&r1=290203&r2=290204&view=diff
>>>> ==============================================================================
>>>> --- llvm/trunk/tools/yaml2obj/yaml2obj.h (original)
>>>> +++ llvm/trunk/tools/yaml2obj/yaml2obj.h Tue Dec 20 15:35:31 2016
>>>> @@ -46,5 +46,6 @@ void yaml2debug_str(llvm::raw_ostream &O
>>>> void yaml2debug_aranges(llvm::raw_ostream &OS, const llvm::DWARFYAML::Data &DI);
>>>> void yaml2pubsection(llvm::raw_ostream &OS,
>>>>                    const llvm::DWARFYAML::PubSection &Sect);
>>>> +void yaml2debug_info(llvm::raw_ostream &OS, const llvm::DWARFYAML::Data &DI);
>>>> 
>>>> #endif
>>>> 
>>>> 
>>>> _______________________________________________
>>>> llvm-commits mailing list
>>>> llvm-commits at lists.llvm.org
>>>> http://lists.llvm.org/cgi-bin/mailman/listinfo/llvm-commits
>> 
> 



More information about the llvm-commits mailing list