[llvm] 505ac22 - [DWARFYAML] Make the ExtLen field of extended opcodes optional.
Xing GUO via llvm-commits
llvm-commits at lists.llvm.org
Wed Sep 23 23:20:06 PDT 2020
Author: Xing GUO
Date: 2020-09-24T14:13:26+08:00
New Revision: 505ac22f1a1ada261280d979862d8af541016f77
URL: https://github.com/llvm/llvm-project/commit/505ac22f1a1ada261280d979862d8af541016f77
DIFF: https://github.com/llvm/llvm-project/commit/505ac22f1a1ada261280d979862d8af541016f77.diff
LOG: [DWARFYAML] Make the ExtLen field of extended opcodes optional.
This patch makes the 'ExtLen' field of extended opcodes optional. We
don't need to manually calculate it in the future.
Reviewed By: jhenderson, MaskRay
Differential Revision: https://reviews.llvm.org/D88136
Added:
Modified:
llvm/include/llvm/ObjectYAML/DWARFYAML.h
llvm/lib/ObjectYAML/DWARFEmitter.cpp
llvm/lib/ObjectYAML/DWARFYAML.cpp
llvm/test/tools/yaml2obj/ELF/DWARF/debug-line.yaml
llvm/tools/obj2yaml/dwarf2yaml.cpp
Removed:
################################################################################
diff --git a/llvm/include/llvm/ObjectYAML/DWARFYAML.h b/llvm/include/llvm/ObjectYAML/DWARFYAML.h
index 3e5be41b8fa3..32706c050af8 100644
--- a/llvm/include/llvm/ObjectYAML/DWARFYAML.h
+++ b/llvm/include/llvm/ObjectYAML/DWARFYAML.h
@@ -126,7 +126,7 @@ struct File {
struct LineTableOpcode {
dwarf::LineNumberOps Opcode;
- uint64_t ExtLen;
+ Optional<uint64_t> ExtLen;
dwarf::LineNumberExtendedOps SubOpcode;
uint64_t Data;
int64_t SData;
diff --git a/llvm/lib/ObjectYAML/DWARFEmitter.cpp b/llvm/lib/ObjectYAML/DWARFEmitter.cpp
index ce9a4ba7ebef..ed7adbb6cce9 100644
--- a/llvm/lib/ObjectYAML/DWARFEmitter.cpp
+++ b/llvm/lib/ObjectYAML/DWARFEmitter.cpp
@@ -480,30 +480,45 @@ static void emitFileEntry(raw_ostream &OS, const DWARFYAML::File &File) {
encodeULEB128(File.Length, OS);
}
+static void writeExtendedOpcode(const DWARFYAML::LineTableOpcode &Op,
+ uint8_t AddrSize, bool IsLittleEndian,
+ raw_ostream &OS) {
+ // The first byte of extended opcodes is a zero byte. The next bytes are an
+ // ULEB128 integer giving the number of bytes in the instruction itself (does
+ // not include the first zero byte or the size). We serialize the instruction
+ // itself into the OpBuffer and then write the size of the buffer and the
+ // buffer to the real output stream.
+ std::string OpBuffer;
+ raw_string_ostream OpBufferOS(OpBuffer);
+ writeInteger((uint8_t)Op.SubOpcode, OpBufferOS, IsLittleEndian);
+ switch (Op.SubOpcode) {
+ case dwarf::DW_LNE_set_address:
+ cantFail(writeVariableSizedInteger(Op.Data, AddrSize, OpBufferOS,
+ IsLittleEndian));
+ break;
+ case dwarf::DW_LNE_define_file:
+ emitFileEntry(OpBufferOS, Op.FileEntry);
+ break;
+ case dwarf::DW_LNE_set_discriminator:
+ encodeULEB128(Op.Data, OpBufferOS);
+ break;
+ case dwarf::DW_LNE_end_sequence:
+ break;
+ default:
+ for (auto OpByte : Op.UnknownOpcodeData)
+ writeInteger((uint8_t)OpByte, OpBufferOS, IsLittleEndian);
+ }
+ uint64_t ExtLen = Op.ExtLen.getValueOr(OpBuffer.size());
+ encodeULEB128(ExtLen, OS);
+ OS.write(OpBuffer.data(), OpBuffer.size());
+}
+
static void writeLineTableOpcode(const DWARFYAML::LineTableOpcode &Op,
uint8_t OpcodeBase, uint8_t AddrSize,
raw_ostream &OS, bool IsLittleEndian) {
writeInteger((uint8_t)Op.Opcode, OS, IsLittleEndian);
if (Op.Opcode == 0) {
- encodeULEB128(Op.ExtLen, OS);
- writeInteger((uint8_t)Op.SubOpcode, OS, IsLittleEndian);
- switch (Op.SubOpcode) {
- case dwarf::DW_LNE_set_address:
- cantFail(
- writeVariableSizedInteger(Op.Data, AddrSize, OS, IsLittleEndian));
- break;
- case dwarf::DW_LNE_define_file:
- emitFileEntry(OS, Op.FileEntry);
- break;
- case dwarf::DW_LNE_set_discriminator:
- encodeULEB128(Op.Data, OS);
- break;
- case dwarf::DW_LNE_end_sequence:
- break;
- default:
- for (auto OpByte : Op.UnknownOpcodeData)
- writeInteger((uint8_t)OpByte, OS, IsLittleEndian);
- }
+ writeExtendedOpcode(Op, AddrSize, IsLittleEndian, OS);
} else if (Op.Opcode < OpcodeBase) {
switch (Op.Opcode) {
case dwarf::DW_LNS_copy:
diff --git a/llvm/lib/ObjectYAML/DWARFYAML.cpp b/llvm/lib/ObjectYAML/DWARFYAML.cpp
index 067423e2e7a2..b3bf6401b4bc 100644
--- a/llvm/lib/ObjectYAML/DWARFYAML.cpp
+++ b/llvm/lib/ObjectYAML/DWARFYAML.cpp
@@ -217,7 +217,7 @@ 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.mapOptional("ExtLen", LineTableOpcode.ExtLen);
IO.mapRequired("SubOpcode", LineTableOpcode.SubOpcode);
}
diff --git a/llvm/test/tools/yaml2obj/ELF/DWARF/debug-line.yaml b/llvm/test/tools/yaml2obj/ELF/DWARF/debug-line.yaml
index 02c9e8ed72ee..b2211dc1824d 100644
--- a/llvm/test/tools/yaml2obj/ELF/DWARF/debug-line.yaml
+++ b/llvm/test/tools/yaml2obj/ELF/DWARF/debug-line.yaml
@@ -616,3 +616,55 @@ DWARF:
LineRange: 14
OpcodeBase: 4
StandardOpcodeLengths: [ 0, 1, 1 ]
+
+## l) Test that we can specify or omit the ExtLen field of extended opcodes.
+
+# RUN: yaml2obj --docnum=12 %s -o %t12.o
+# RUN: llvm-readelf --hex-dump=.debug_line %t12.o | \
+# RUN: FileCheck %s --check-prefix=EXTLEN --strict-whitespace
+
+# EXTLEN: Hex dump of section '.debug_line':
+# EXTLEN-NEXT: 0x00000000 20000000 04000800 00000101 01fb0e01
+## ^---------------------------------- line number program header
+# EXTLEN-NEXT: 0x00000010 0000000c 03616263 6400b424 b424b424
+## ----
+## ^- DW_LNS_extended_op
+## ^- extended opcode length (ULEB128) 12
+## ^- DW_LNE_define_file
+## ^---------- "abcd\0"
+## ^--- directory index (ULEB128) 0x1234
+## ^--- modification time (ULEB128) 0x1234
+## ^--- file length (ULEB128) 0x1234
+# EXTLEN-NEXT: 0x00000020 00b42401{{ }}
+## ^- DW_LNS_extended_op
+## ^--- extended opcode length (ULEB128) 0x1234
+## ^- DW_LNE_end_sequence
+
+--- !ELF
+FileHeader:
+ Class: ELFCLASS64
+ Data: ELFDATA2LSB
+ Type: ET_EXEC
+DWARF:
+ debug_line:
+ - Version: 4
+ MinInstLength: 1
+ MaxOpsPerInst: 1
+ DefaultIsStmt: 1
+ LineBase: 251
+ LineRange: 14
+ OpcodeBase: 1
+ StandardOpcodeLengths: []
+ Opcodes:
+ - Opcode: DW_LNS_extended_op
+ ## Omit the ExtLen field.
+ SubOpcode: DW_LNE_define_file
+ FileEntry:
+ Name: abcd
+ DirIdx: 0x1234
+ ModTime: 0x1234
+ Length: 0x1234
+ - Opcode: DW_LNS_extended_op
+ ## Specify the ExtLen field.
+ ExtLen: 0x1234
+ SubOpcode: DW_LNE_end_sequence
diff --git a/llvm/tools/obj2yaml/dwarf2yaml.cpp b/llvm/tools/obj2yaml/dwarf2yaml.cpp
index 10e8ecaeec08..4078abaf89c8 100644
--- a/llvm/tools/obj2yaml/dwarf2yaml.cpp
+++ b/llvm/tools/obj2yaml/dwarf2yaml.cpp
@@ -419,7 +419,7 @@ void dumpDebugLines(DWARFContext &DCtx, DWARFYAML::Data &Y) {
case dwarf::DW_LNE_end_sequence:
break;
default:
- while (Offset < StartExt + NewOp.ExtLen)
+ while (Offset < StartExt + *NewOp.ExtLen)
NewOp.UnknownOpcodeData.push_back(LineData.getU8(&Offset));
}
} else if (NewOp.Opcode < DebugLines.OpcodeBase) {
More information about the llvm-commits
mailing list