diff options
author | Chris Bieneman <beanz@apple.com> | 2017-01-10 05:25:24 +0000 |
---|---|---|
committer | Chris Bieneman <beanz@apple.com> | 2017-01-10 05:25:24 +0000 |
commit | e8209239b1bec45de27282f71c6ee5419d11786b (patch) | |
tree | 33c122d8189b1b88c084a22209881c8dcf7a1a89 /tools/yaml2obj | |
parent | 9213bb6c36cfb7afa7437dda79c45b51e759ff58 (diff) |
[ObjectYAML] Support for DWARF line tables
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@291541 91177308-0d34-0410-b5e6-96231b3b80d8
Diffstat (limited to 'tools/yaml2obj')
-rw-r--r-- | tools/yaml2obj/yaml2dwarf.cpp | 95 | ||||
-rw-r--r-- | tools/yaml2obj/yaml2macho.cpp | 2 | ||||
-rw-r--r-- | tools/yaml2obj/yaml2obj.h | 1 |
3 files changed, 98 insertions, 0 deletions
diff --git a/tools/yaml2obj/yaml2dwarf.cpp b/tools/yaml2obj/yaml2dwarf.cpp index 8ba1190c56a..3ceb7772b96 100644 --- a/tools/yaml2obj/yaml2dwarf.cpp +++ b/tools/yaml2obj/yaml2dwarf.cpp @@ -233,3 +233,98 @@ void yaml2debug_info(raw_ostream &OS, const DWARFYAML::Data &DI) { } } } + +void yaml2FileEntry(raw_ostream &OS, const DWARFYAML::File &File) { + OS.write(File.Name.data(), File.Name.size()); + OS.write('\0'); + encodeULEB128(File.DirIdx, OS); + encodeULEB128(File.ModTime, OS); + encodeULEB128(File.Length, OS); +} + +void yaml2debug_line(raw_ostream &OS, const DWARFYAML::Data &DI) { + for (const auto LineTable : DI.DebugLines) { + writeInteger((uint32_t)LineTable.TotalLength, OS, DI.IsLittleEndian); + uint64_t SizeOfPrologueLength = 4; + if (LineTable.TotalLength == UINT32_MAX) { + writeInteger((uint64_t)LineTable.TotalLength64, OS, DI.IsLittleEndian); + SizeOfPrologueLength = 8; + } + writeInteger((uint16_t)LineTable.Version, OS, DI.IsLittleEndian); + writeVariableSizedInteger(LineTable.PrologueLength, SizeOfPrologueLength, + OS, DI.IsLittleEndian); + writeInteger((uint8_t)LineTable.MinInstLength, OS, DI.IsLittleEndian); + if (LineTable.Version >= 4) + writeInteger((uint8_t)LineTable.MaxOpsPerInst, OS, DI.IsLittleEndian); + writeInteger((uint8_t)LineTable.DefaultIsStmt, OS, DI.IsLittleEndian); + writeInteger((uint8_t)LineTable.LineBase, OS, DI.IsLittleEndian); + writeInteger((uint8_t)LineTable.LineRange, OS, DI.IsLittleEndian); + writeInteger((uint8_t)LineTable.OpcodeBase, OS, DI.IsLittleEndian); + + for (auto OpcodeLength : LineTable.StandardOpcodeLengths) + writeInteger((uint8_t)OpcodeLength, OS, DI.IsLittleEndian); + + for (auto IncludeDir : LineTable.IncludeDirs) { + OS.write(IncludeDir.data(), IncludeDir.size()); + OS.write('\0'); + } + OS.write('\0'); + + for (auto File : LineTable.Files) + yaml2FileEntry(OS, File); + OS.write('\0'); + + for (auto Op : LineTable.Opcodes) { + writeInteger((uint8_t)Op.Opcode, OS, DI.IsLittleEndian); + if (Op.Opcode == 0) { + encodeULEB128(Op.ExtLen, OS); + writeInteger((uint8_t)Op.SubOpcode, OS, DI.IsLittleEndian); + switch (Op.SubOpcode) { + case dwarf::DW_LNE_set_address: + case dwarf::DW_LNE_set_discriminator: + writeVariableSizedInteger(Op.Data, DI.CompileUnits[0].AddrSize, OS, + DI.IsLittleEndian); + break; + case dwarf::DW_LNE_define_file: + yaml2FileEntry(OS, Op.FileEntry); + break; + case dwarf::DW_LNE_end_sequence: + break; + default: + for (auto OpByte : Op.UnknownOpcodeData) + writeInteger((uint8_t)OpByte, OS, DI.IsLittleEndian); + } + } else if (Op.Opcode < LineTable.OpcodeBase) { + switch (Op.Opcode) { + case dwarf::DW_LNS_copy: + case dwarf::DW_LNS_negate_stmt: + case dwarf::DW_LNS_set_basic_block: + case dwarf::DW_LNS_const_add_pc: + case dwarf::DW_LNS_set_prologue_end: + case dwarf::DW_LNS_set_epilogue_begin: + break; + + case dwarf::DW_LNS_advance_pc: + case dwarf::DW_LNS_set_file: + case dwarf::DW_LNS_set_column: + case dwarf::DW_LNS_set_isa: + encodeULEB128(Op.Data, OS); + break; + + case dwarf::DW_LNS_advance_line: + encodeSLEB128(Op.SData, OS); + break; + + case dwarf::DW_LNS_fixed_advance_pc: + writeInteger((uint16_t)Op.Data, OS, DI.IsLittleEndian); + break; + + default: + for (auto OpData : Op.StandardOpcodeData) { + encodeULEB128(OpData, OS); + } + } + } + } + } +} diff --git a/tools/yaml2obj/yaml2macho.cpp b/tools/yaml2obj/yaml2macho.cpp index a41ec55d73b..cbc4d7ff50d 100644 --- a/tools/yaml2obj/yaml2macho.cpp +++ b/tools/yaml2obj/yaml2macho.cpp @@ -280,6 +280,8 @@ Error MachOWriter::writeSectionData(raw_ostream &OS) { yaml2pubsection(OS, Obj.DWARF.PubTypes, Obj.IsLittleEndian); } else if (0 == strncmp(&Sec.sectname[0], "__debug_info", 16)) { yaml2debug_info(OS, Obj.DWARF); + } else if (0 == strncmp(&Sec.sectname[0], "__debug_line", 16)) { + yaml2debug_line(OS, Obj.DWARF); } } else { // Fills section data with 0xDEADBEEF diff --git a/tools/yaml2obj/yaml2obj.h b/tools/yaml2obj/yaml2obj.h index 7cad4ca8675..4a637366e1a 100644 --- a/tools/yaml2obj/yaml2obj.h +++ b/tools/yaml2obj/yaml2obj.h @@ -46,5 +46,6 @@ void yaml2pubsection(llvm::raw_ostream &OS, const llvm::DWARFYAML::PubSection &Sect, bool IsLittleEndian); void yaml2debug_info(llvm::raw_ostream &OS, const llvm::DWARFYAML::Data &DI); +void yaml2debug_line(llvm::raw_ostream &OS, const llvm::DWARFYAML::Data &DI); #endif |