From 22ec861d28c0aa0cdf76b9618151b9ee87ba2221 Mon Sep 17 00:00:00 2001 From: Xing GUO Date: Tue, 28 Jul 2020 22:10:44 +0800 Subject: [PATCH] [DWARFYAML] Add support for emitting custom range list content. This patch adds support for emitting custom range list content. We are able to handcraft a custom range list via the following syntax. ``` debug_rnglists: - Lists: - Entries: - Operator: DW_RLE_startx_endx Values: [ 0x1234, 0x1234 ] - Content: '1234567890abcdef' - Content: 'abcdef1234567890' ``` Reviewed By: jhenderson Differential Revision: https://reviews.llvm.org/D84618 --- llvm/include/llvm/ObjectYAML/DWARFYAML.h | 6 ++- llvm/lib/ObjectYAML/DWARFEmitter.cpp | 17 +++--- llvm/lib/ObjectYAML/DWARFYAML.cpp | 9 ++++ .../tools/yaml2obj/ELF/DWARF/debug-rnglists.yaml | 61 ++++++++++++++++++++++ 4 files changed, 86 insertions(+), 7 deletions(-) diff --git a/llvm/include/llvm/ObjectYAML/DWARFYAML.h b/llvm/include/llvm/ObjectYAML/DWARFYAML.h index 88ac404..f4ace73 100644 --- a/llvm/include/llvm/ObjectYAML/DWARFYAML.h +++ b/llvm/include/llvm/ObjectYAML/DWARFYAML.h @@ -18,6 +18,7 @@ #include "llvm/ADT/SetVector.h" #include "llvm/ADT/StringRef.h" #include "llvm/BinaryFormat/Dwarf.h" +#include "llvm/ObjectYAML/YAML.h" #include "llvm/Support/YAMLTraits.h" #include #include @@ -189,7 +190,8 @@ struct RnglistEntry { }; template struct ListEntries { - std::vector Entries; + Optional> Entries; + Optional Content; }; template struct ListTable { @@ -328,6 +330,8 @@ struct MappingTraits> { template struct MappingTraits> { static void mapping(IO &IO, DWARFYAML::ListEntries &ListEntries); + static StringRef validate(IO &IO, + DWARFYAML::ListEntries &ListEntries); }; template <> struct MappingTraits { diff --git a/llvm/lib/ObjectYAML/DWARFEmitter.cpp b/llvm/lib/ObjectYAML/DWARFEmitter.cpp index f611910..b39bb00 100644 --- a/llvm/lib/ObjectYAML/DWARFEmitter.cpp +++ b/llvm/lib/ObjectYAML/DWARFEmitter.cpp @@ -658,12 +658,17 @@ Error writeDWARFLists(raw_ostream &OS, for (const DWARFYAML::ListEntries &List : Table.Lists) { Offsets.push_back(ListBufferOS.tell()); - for (const EntryType &Entry : List.Entries) { - Expected EntrySize = - writeListEntry(ListBufferOS, Entry, AddrSize, IsLittleEndian); - if (!EntrySize) - return EntrySize.takeError(); - Length += *EntrySize; + if (List.Content) { + List.Content->writeAsBinary(ListBufferOS, UINT64_MAX); + Length += List.Content->binary_size(); + } else if (List.Entries) { + for (const EntryType &Entry : *List.Entries) { + Expected EntrySize = + writeListEntry(ListBufferOS, Entry, AddrSize, IsLittleEndian); + if (!EntrySize) + return EntrySize.takeError(); + Length += *EntrySize; + } } } diff --git a/llvm/lib/ObjectYAML/DWARFYAML.cpp b/llvm/lib/ObjectYAML/DWARFYAML.cpp index e5c77bc..adc1672 100644 --- a/llvm/lib/ObjectYAML/DWARFYAML.cpp +++ b/llvm/lib/ObjectYAML/DWARFYAML.cpp @@ -246,6 +246,15 @@ template void MappingTraits>::mapping( IO &IO, DWARFYAML::ListEntries &ListEntries) { IO.mapOptional("Entries", ListEntries.Entries); + IO.mapOptional("Content", ListEntries.Content); +} + +template +StringRef MappingTraits>::validate( + IO &IO, DWARFYAML::ListEntries &ListEntries) { + if (ListEntries.Entries && ListEntries.Content) + return "Entries and Content can't be used together"; + return StringRef(); } template diff --git a/llvm/test/tools/yaml2obj/ELF/DWARF/debug-rnglists.yaml b/llvm/test/tools/yaml2obj/ELF/DWARF/debug-rnglists.yaml index 80dc9b9..248cb19 100644 --- a/llvm/test/tools/yaml2obj/ELF/DWARF/debug-rnglists.yaml +++ b/llvm/test/tools/yaml2obj/ELF/DWARF/debug-rnglists.yaml @@ -608,3 +608,64 @@ FileHeader: Machine: EM_X86_64 DWARF: debug_rnglists: [] + +## s) Test that we are able to generate a range list via raw binary data. + +# RUN: yaml2obj --docnum=17 %s -o %t17.o +# RUN: llvm-readelf --hex-dump=.debug_rnglists %t17.o | \ +# RUN: FileCheck %s --check-prefix=CUSTOM-LIST + +# CUSTOM-LIST: Hex dump of section '.debug_rnglists': +# CUSTOM-LIST-NEXT: 0x00000000 29000000 05000800 03000000 0c000000 )............... +## ^------- unit_length (4-byte) +## ^--- version (2-byte) +## ^- address_size (1-byte) +## ^- segment_selector_size (1-byte) +## ^------- offset_entry_count (4-byte) +## ^------- offsets[0] (4-byte) +# CUSTOM-LIST-NEXT: 0x00000010 11000000 19000000 02b424b4 24123456 ..........$.$.4V +## ^------- offsets[1] (4-byte) +## ^------- offsets[2] (4-byte) +## ^- DW_RLE_startx_endx +## ^--- operands[0] (ULEB128) 0x1234 +## ^---- operands[1] (ULEB128) 0x1234 +## ^----- custom list content +# CUSTOM-LIST-NEXT: 0x00000020 7890abcd efabcdef 12345678 90 x........4Vx. +## ----------- +## ^----------------- custom list content + +--- !ELF +FileHeader: + Class: ELFCLASS64 + Data: ELFDATA2LSB + Type: ET_EXEC + Machine: EM_X86_64 +DWARF: + debug_rnglists: + - Lists: + - Entries: + - Operator: DW_RLE_startx_endx + Values: [ 0x1234, 0x1234 ] + - Content: '1234567890abcdef' + - Content: 'abcdef1234567890' + +## t) Test that yaml2obj emits an error message when 'Content' and 'Entries' are specified +## at the same time. + +# RUN: not yaml2obj --docnum=18 %s 2>&1 | FileCheck %s --check-prefix=ERR + +# ERR: YAML:{{.*}}: error: Entries and Content can't be used together +# ERR-NEXT: - Entries: [] +# ERR-NEXT: ^ + +--- !ELF +FileHeader: + Class: ELFCLASS64 + Data: ELFDATA2LSB + Type: ET_EXEC + Machine: EM_X86_64 +DWARF: + debug_rnglists: + - Lists: + - Entries: [] + Content: '' -- 2.7.4