Skip to content

Commit

Permalink
[ObjectYAML] Support for DWARF line tables
Browse files Browse the repository at this point in the history
One more try... relanding r291541 with a fix to properly gate MaxOpsPerInst on DWARF version.

Description from r291541:

This patch re-lands r291470, which failed on Linux bots. The issue (I believe) was undefined behavior because the size of llvm::dwarf::LineNumberOps was not explcitly specified or consistently respected. The updated patch adds an explcit underlying type to the enum and preserves the size more correctly.

Original description:

This patch adds support for the DWARF debug_lines section. The line table state machine opcodes are preserved, so this can be used to test the state machine evaluation directly.

git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@291546 91177308-0d34-0410-b5e6-96231b3b80d8
  • Loading branch information
Chris Bieneman committed Jan 10, 2017
1 parent 1d928ef commit 6c9c3a7
Show file tree
Hide file tree
Showing 10 changed files with 1,004 additions and 13 deletions.
73 changes: 73 additions & 0 deletions include/llvm/ObjectYAML/DWARFYAML.h
Original file line number Diff line number Diff line change
Expand Up @@ -85,6 +85,41 @@ struct Unit {
std::vector<Entry> Entries;
};

struct File {
StringRef Name;
uint64_t DirIdx;
uint64_t ModTime;
uint64_t Length;
};

struct LineTableOpcode {
dwarf::LineNumberOps Opcode;
uint64_t ExtLen;
dwarf::LineNumberExtendedOps SubOpcode;
uint64_t Data;
int64_t SData;
File FileEntry;
std::vector<llvm::yaml::Hex8> UnknownOpcodeData;
std::vector<llvm::yaml::Hex64> StandardOpcodeData;
};

struct LineTable {
uint32_t TotalLength;
uint64_t TotalLength64;
uint16_t Version;
uint64_t PrologueLength;
uint8_t MinInstLength;
uint8_t MaxOpsPerInst;
uint8_t DefaultIsStmt;
uint8_t LineBase;
uint8_t LineRange;
uint8_t OpcodeBase;
std::vector<uint8_t> StandardOpcodeLengths;
std::vector<StringRef> IncludeDirs;
std::vector<File> Files;
std::vector<LineTableOpcode> Opcodes;
};

struct Data {
bool IsLittleEndian;
std::vector<Abbrev> AbbrevDecls;
Expand All @@ -98,13 +133,16 @@ struct Data {

std::vector<Unit> CompileUnits;

std::vector<LineTable> DebugLines;

bool isEmpty() const;
};

} // namespace llvm::DWARFYAML
} // namespace llvm

LLVM_YAML_IS_SEQUENCE_VECTOR(uint8_t)
LLVM_YAML_IS_SEQUENCE_VECTOR(llvm::yaml::Hex64)
LLVM_YAML_IS_SEQUENCE_VECTOR(llvm::StringRef)
LLVM_YAML_IS_SEQUENCE_VECTOR(llvm::yaml::Hex8)
LLVM_YAML_IS_SEQUENCE_VECTOR(llvm::DWARFYAML::AttributeAbbrev)
Expand All @@ -115,6 +153,9 @@ 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)
LLVM_YAML_IS_SEQUENCE_VECTOR(llvm::DWARFYAML::File)
LLVM_YAML_IS_SEQUENCE_VECTOR(llvm::DWARFYAML::LineTable)
LLVM_YAML_IS_SEQUENCE_VECTOR(llvm::DWARFYAML::LineTableOpcode)

namespace llvm {
namespace yaml {
Expand Down Expand Up @@ -159,6 +200,18 @@ template <> struct MappingTraits<DWARFYAML::FormValue> {
static void mapping(IO &IO, DWARFYAML::FormValue &FormValue);
};

template <> struct MappingTraits<DWARFYAML::File> {
static void mapping(IO &IO, DWARFYAML::File &File);
};

template <> struct MappingTraits<DWARFYAML::LineTableOpcode> {
static void mapping(IO &IO, DWARFYAML::LineTableOpcode &LineTableOpcode);
};

template <> struct MappingTraits<DWARFYAML::LineTable> {
static void mapping(IO &IO, DWARFYAML::LineTable &LineTable);
};

#define HANDLE_DW_TAG(unused, name) \
io.enumCase(value, "DW_TAG_" #name, dwarf::DW_TAG_##name);

Expand All @@ -169,6 +222,26 @@ template <> struct ScalarEnumerationTraits<dwarf::Tag> {
}
};

#define HANDLE_DW_LNS(unused, name) \
io.enumCase(value, "DW_LNS_" #name, dwarf::DW_LNS_##name);

template <> struct ScalarEnumerationTraits<dwarf::LineNumberOps> {
static void enumeration(IO &io, dwarf::LineNumberOps &value) {
#include "llvm/Support/Dwarf.def"
io.enumFallback<Hex8>(value);
}
};

#define HANDLE_DW_LNE(unused, name) \
io.enumCase(value, "DW_LNE_" #name, dwarf::DW_LNE_##name);

template <> struct ScalarEnumerationTraits<dwarf::LineNumberExtendedOps> {
static void enumeration(IO &io, dwarf::LineNumberExtendedOps &value) {
#include "llvm/Support/Dwarf.def"
io.enumFallback<Hex16>(value);
}
};

#define HANDLE_DW_AT(unused, name) \
io.enumCase(value, "DW_AT_" #name, dwarf::DW_AT_##name);

Expand Down
1 change: 0 additions & 1 deletion include/llvm/ObjectYAML/MachOYAML.h
Original file line number Diff line number Diff line change
Expand Up @@ -139,7 +139,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::Hex64)
LLVM_YAML_IS_SEQUENCE_VECTOR(int64_t)
LLVM_YAML_IS_SEQUENCE_VECTOR(llvm::MachOYAML::RebaseOpcode)
LLVM_YAML_IS_SEQUENCE_VECTOR(llvm::MachOYAML::BindOpcode)
Expand Down
2 changes: 1 addition & 1 deletion include/llvm/Support/Dwarf.h
Original file line number Diff line number Diff line change
Expand Up @@ -207,7 +207,7 @@ enum DiscriminantList {
};

/// Line Number Standard Opcode Encodings.
enum LineNumberOps {
enum LineNumberOps : uint8_t {
#define HANDLE_DW_LNS(ID, NAME) DW_LNS_##NAME = ID,
#include "llvm/Support/Dwarf.def"
};
Expand Down
67 changes: 57 additions & 10 deletions lib/ObjectYAML/DWARFYAML.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -27,17 +27,18 @@ void MappingTraits<DWARFYAML::Data>::mapping(IO &IO, DWARFYAML::Data &DWARF) {
IO.setContext(&DWARF);
IO.mapOptional("debug_str", DWARF.DebugStrings);
IO.mapOptional("debug_abbrev", DWARF.AbbrevDecls);
if(!DWARF.ARanges.empty() || !IO.outputting())
if (!DWARF.ARanges.empty() || !IO.outputting())
IO.mapOptional("debug_aranges", DWARF.ARanges);
if(!DWARF.PubNames.Entries.empty() || !IO.outputting())
if (!DWARF.PubNames.Entries.empty() || !IO.outputting())
IO.mapOptional("debug_pubnames", DWARF.PubNames);
if(!DWARF.PubTypes.Entries.empty() || !IO.outputting())
if (!DWARF.PubTypes.Entries.empty() || !IO.outputting())
IO.mapOptional("debug_pubtypes", DWARF.PubTypes);
if(!DWARF.GNUPubNames.Entries.empty() || !IO.outputting())
if (!DWARF.GNUPubNames.Entries.empty() || !IO.outputting())
IO.mapOptional("debug_gnu_pubnames", DWARF.GNUPubNames);
if(!DWARF.GNUPubTypes.Entries.empty() || !IO.outputting())
if (!DWARF.GNUPubTypes.Entries.empty() || !IO.outputting())
IO.mapOptional("debug_gnu_pubtypes", DWARF.GNUPubTypes);
IO.mapOptional("debug_info", DWARF.CompileUnits);
IO.mapOptional("debug_line", DWARF.DebugLines);
IO.setContext(&oldContext);
}

Expand All @@ -62,7 +63,7 @@ void MappingTraits<DWARFYAML::ARangeDescriptor>::mapping(
}

void MappingTraits<DWARFYAML::ARange>::mapping(IO &IO,
DWARFYAML::ARange &Range) {
DWARFYAML::ARange &Range) {
IO.mapRequired("Length", Range.Length);
IO.mapRequired("Version", Range.Version);
IO.mapRequired("CuOffset", Range.CuOffset);
Expand Down Expand Up @@ -106,15 +107,61 @@ void MappingTraits<DWARFYAML::Entry>::mapping(IO &IO, DWARFYAML::Entry &Entry) {
IO.mapRequired("Values", Entry.Values);
}

void MappingTraits<DWARFYAML::FormValue>::mapping(IO &IO,
DWARFYAML::FormValue &FormValue) {
void MappingTraits<DWARFYAML::FormValue>::mapping(
IO &IO, DWARFYAML::FormValue &FormValue) {
IO.mapOptional("Value", FormValue.Value);
if(!FormValue.CStr.empty() || !IO.outputting())
if (!FormValue.CStr.empty() || !IO.outputting())
IO.mapOptional("CStr", FormValue.CStr);
if(!FormValue.BlockData.empty() || !IO.outputting())
if (!FormValue.BlockData.empty() || !IO.outputting())
IO.mapOptional("BlockData", FormValue.BlockData);
}

void MappingTraits<DWARFYAML::File>::mapping(IO &IO, DWARFYAML::File &File) {
IO.mapRequired("Name", File.Name);
IO.mapRequired("DirIdx", File.DirIdx);
IO.mapRequired("ModTime", File.ModTime);
IO.mapRequired("Length", File.Length);
}

void MappingTraits<DWARFYAML::LineTableOpcode>::mapping(
IO &IO, DWARFYAML::LineTableOpcode &LineTableOpcode) {
IO.mapRequired("Opcode", LineTableOpcode.Opcode);
if (LineTableOpcode.Opcode == dwarf::DW_LNS_extended_op) {
IO.mapRequired("ExtLen", LineTableOpcode.ExtLen);
IO.mapRequired("SubOpcode", LineTableOpcode.SubOpcode);
}

if (!LineTableOpcode.UnknownOpcodeData.empty() || !IO.outputting())
IO.mapOptional("UnknownOpcodeData", LineTableOpcode.UnknownOpcodeData);
if (!LineTableOpcode.UnknownOpcodeData.empty() || !IO.outputting())
IO.mapOptional("StandardOpcodeData", LineTableOpcode.StandardOpcodeData);
if (!LineTableOpcode.FileEntry.Name.empty() || !IO.outputting())
IO.mapOptional("FileEntry", LineTableOpcode.FileEntry);
if (LineTableOpcode.Opcode == dwarf::DW_LNS_advance_line || !IO.outputting())
IO.mapOptional("SData", LineTableOpcode.SData);
IO.mapOptional("Data", LineTableOpcode.Data);
}

void MappingTraits<DWARFYAML::LineTable>::mapping(
IO &IO, DWARFYAML::LineTable &LineTable) {
IO.mapRequired("TotalLength", LineTable.TotalLength);
if (LineTable.TotalLength == UINT32_MAX)
IO.mapRequired("TotalLength64", LineTable.TotalLength64);
IO.mapRequired("Version", LineTable.Version);
IO.mapRequired("PrologueLength", LineTable.PrologueLength);
IO.mapRequired("MinInstLength", LineTable.MinInstLength);
if(LineTable.Version >= 4)
IO.mapRequired("MaxOpsPerInst", LineTable.MaxOpsPerInst);
IO.mapRequired("DefaultIsStmt", LineTable.DefaultIsStmt);
IO.mapRequired("LineBase", LineTable.LineBase);
IO.mapRequired("LineRange", LineTable.LineRange);
IO.mapRequired("OpcodeBase", LineTable.OpcodeBase);
IO.mapRequired("StandardOpcodeLengths", LineTable.StandardOpcodeLengths);
IO.mapRequired("IncludeDirs", LineTable.IncludeDirs);
IO.mapRequired("Files", LineTable.Files);
IO.mapRequired("Opcodes", LineTable.Opcodes);
}

} // namespace llvm::yaml

} // namespace llvm
52 changes: 52 additions & 0 deletions test/ObjectYAML/MachO/DWARF-debug_info.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -451,6 +451,58 @@ DWARF:
- Value: 0x0000000000000001
- AbbrCode: 0x00000000
Values:
debug_line:
- TotalLength: 65
Version: 2
PrologueLength: 36
MinInstLength: 1
DefaultIsStmt: 1
LineBase: 251
LineRange: 14
OpcodeBase: 13
StandardOpcodeLengths:
- 0
- 1
- 1
- 1
- 1
- 0
- 0
- 0
- 1
- 0
- 0
- 1
IncludeDirs:
Files:
- Name: hello_world.c
DirIdx: 0
ModTime: 0
Length: 0
Opcodes:
- Opcode: DW_LNS_extended_op
ExtLen: 9
SubOpcode: DW_LNE_set_address
Data: 4294971216
- Opcode: 0x14
Data: 4294971216
- Opcode: DW_LNS_set_column
Data: 3
- Opcode: DW_LNS_set_prologue_end
Data: 3
- Opcode: DW_LNS_const_add_pc
Data: 3
- Opcode: 0xBB
Data: 3
- Opcode: 0xBB
Data: 3
- Opcode: DW_LNS_advance_pc
Data: 11
- Opcode: DW_LNS_extended_op
ExtLen: 1
SubOpcode: DW_LNE_end_sequence
Data: 11
...
...


Expand Down
Loading

0 comments on commit 6c9c3a7

Please sign in to comment.