Skip to content

Commit

Permalink
[DWARFYAML] Add support for emitting custom range list content.
Browse files Browse the repository at this point in the history
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
  • Loading branch information
higuoxing committed Jul 28, 2020
1 parent d28f867 commit 22ec861
Show file tree
Hide file tree
Showing 4 changed files with 86 additions and 7 deletions.
6 changes: 5 additions & 1 deletion llvm/include/llvm/ObjectYAML/DWARFYAML.h
Expand Up @@ -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 <cstdint>
#include <vector>
Expand Down Expand Up @@ -189,7 +190,8 @@ struct RnglistEntry {
};

template <typename EntryType> struct ListEntries {
std::vector<EntryType> Entries;
Optional<std::vector<EntryType>> Entries;
Optional<yaml::BinaryRef> Content;
};

template <typename EntryType> struct ListTable {
Expand Down Expand Up @@ -328,6 +330,8 @@ struct MappingTraits<DWARFYAML::ListTable<EntryType>> {
template <typename EntryType>
struct MappingTraits<DWARFYAML::ListEntries<EntryType>> {
static void mapping(IO &IO, DWARFYAML::ListEntries<EntryType> &ListEntries);
static StringRef validate(IO &IO,
DWARFYAML::ListEntries<EntryType> &ListEntries);
};

template <> struct MappingTraits<DWARFYAML::RnglistEntry> {
Expand Down
17 changes: 11 additions & 6 deletions llvm/lib/ObjectYAML/DWARFEmitter.cpp
Expand Up @@ -658,12 +658,17 @@ Error writeDWARFLists(raw_ostream &OS,

for (const DWARFYAML::ListEntries<EntryType> &List : Table.Lists) {
Offsets.push_back(ListBufferOS.tell());
for (const EntryType &Entry : List.Entries) {
Expected<uint64_t> 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<uint64_t> EntrySize =
writeListEntry(ListBufferOS, Entry, AddrSize, IsLittleEndian);
if (!EntrySize)
return EntrySize.takeError();
Length += *EntrySize;
}
}
}

Expand Down
9 changes: 9 additions & 0 deletions llvm/lib/ObjectYAML/DWARFYAML.cpp
Expand Up @@ -246,6 +246,15 @@ template <typename EntryType>
void MappingTraits<DWARFYAML::ListEntries<EntryType>>::mapping(
IO &IO, DWARFYAML::ListEntries<EntryType> &ListEntries) {
IO.mapOptional("Entries", ListEntries.Entries);
IO.mapOptional("Content", ListEntries.Content);
}

template <typename EntryType>
StringRef MappingTraits<DWARFYAML::ListEntries<EntryType>>::validate(
IO &IO, DWARFYAML::ListEntries<EntryType> &ListEntries) {
if (ListEntries.Entries && ListEntries.Content)
return "Entries and Content can't be used together";
return StringRef();
}

template <typename EntryType>
Expand Down
61 changes: 61 additions & 0 deletions llvm/test/tools/yaml2obj/ELF/DWARF/debug-rnglists.yaml
Expand Up @@ -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: ''

0 comments on commit 22ec861

Please sign in to comment.