summaryrefslogtreecommitdiff
path: root/tools/yaml2obj
diff options
context:
space:
mode:
authorChris Bieneman <beanz@apple.com>2017-01-10 05:25:24 +0000
committerChris Bieneman <beanz@apple.com>2017-01-10 05:25:24 +0000
commite8209239b1bec45de27282f71c6ee5419d11786b (patch)
tree33c122d8189b1b88c084a22209881c8dcf7a1a89 /tools/yaml2obj
parent9213bb6c36cfb7afa7437dda79c45b51e759ff58 (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.cpp95
-rw-r--r--tools/yaml2obj/yaml2macho.cpp2
-rw-r--r--tools/yaml2obj/yaml2obj.h1
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