[llvm] dd55499 - [DWARFYAML] Make the opcode_base and the standard_opcode_lengths fields optional.

Xing GUO via llvm-commits llvm-commits at lists.llvm.org
Thu Oct 8 20:10:32 PDT 2020


Author: Xing GUO
Date: 2020-10-09T11:10:03+08:00
New Revision: dd554994729b6f97c0f3df3365b8b97a08d0a418

URL: https://github.com/llvm/llvm-project/commit/dd554994729b6f97c0f3df3365b8b97a08d0a418
DIFF: https://github.com/llvm/llvm-project/commit/dd554994729b6f97c0f3df3365b8b97a08d0a418.diff

LOG: [DWARFYAML] Make the opcode_base and the standard_opcode_lengths fields optional.

This patch makes the opcode_base and the standard_opcode_lengths fields
of the line table optional. When both of them are not specified,
yaml2obj emits them according to the line table's version.

Reviewed By: jhenderson

Differential Revision: https://reviews.llvm.org/D88355

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 32706c050af8..edb5f00c5e80 100644
--- a/llvm/include/llvm/ObjectYAML/DWARFYAML.h
+++ b/llvm/include/llvm/ObjectYAML/DWARFYAML.h
@@ -145,8 +145,8 @@ struct LineTable {
   uint8_t DefaultIsStmt;
   uint8_t LineBase;
   uint8_t LineRange;
-  uint8_t OpcodeBase;
-  std::vector<uint8_t> StandardOpcodeLengths;
+  Optional<uint8_t> OpcodeBase;
+  Optional<std::vector<uint8_t>> StandardOpcodeLengths;
   std::vector<StringRef> IncludeDirs;
   std::vector<File> Files;
   std::vector<LineTableOpcode> Opcodes;

diff  --git a/llvm/lib/ObjectYAML/DWARFEmitter.cpp b/llvm/lib/ObjectYAML/DWARFEmitter.cpp
index ed7adbb6cce9..ccebcc7f4c8c 100644
--- a/llvm/lib/ObjectYAML/DWARFEmitter.cpp
+++ b/llvm/lib/ObjectYAML/DWARFEmitter.cpp
@@ -552,6 +552,21 @@ static void writeLineTableOpcode(const DWARFYAML::LineTableOpcode &Op,
   }
 }
 
+static std::vector<uint8_t>
+getStandardOpcodeLengths(uint16_t Version, Optional<uint8_t> OpcodeBase) {
+  // If the opcode_base field isn't specified, we returns the
+  // standard_opcode_lengths array according to the version by default.
+  std::vector<uint8_t> StandardOpcodeLengths{0, 1, 1, 1, 1, 0,
+                                             0, 0, 1, 0, 0, 1};
+  if (Version == 2) {
+    // DWARF v2 uses the same first 9 standard opcodes as v3-5.
+    StandardOpcodeLengths.resize(9);
+  } else if (OpcodeBase) {
+    StandardOpcodeLengths.resize(*OpcodeBase > 0 ? *OpcodeBase - 1 : 0, 0);
+  }
+  return StandardOpcodeLengths;
+}
+
 Error DWARFYAML::emitDebugLine(raw_ostream &OS, const DWARFYAML::Data &DI) {
   for (const DWARFYAML::LineTable &LineTable : DI.DebugLines) {
     // Buffer holds the bytes following the header_length (or prologue_length in
@@ -566,9 +581,15 @@ Error DWARFYAML::emitDebugLine(raw_ostream &OS, const DWARFYAML::Data &DI) {
     writeInteger(LineTable.DefaultIsStmt, BufferOS, DI.IsLittleEndian);
     writeInteger(LineTable.LineBase, BufferOS, DI.IsLittleEndian);
     writeInteger(LineTable.LineRange, BufferOS, DI.IsLittleEndian);
-    writeInteger(LineTable.OpcodeBase, BufferOS, DI.IsLittleEndian);
 
-    for (uint8_t OpcodeLength : LineTable.StandardOpcodeLengths)
+    std::vector<uint8_t> StandardOpcodeLengths =
+        LineTable.StandardOpcodeLengths.getValueOr(
+            getStandardOpcodeLengths(LineTable.Version, LineTable.OpcodeBase));
+    uint8_t OpcodeBase = LineTable.OpcodeBase
+                             ? *LineTable.OpcodeBase
+                             : StandardOpcodeLengths.size() + 1;
+    writeInteger(OpcodeBase, BufferOS, DI.IsLittleEndian);
+    for (uint8_t OpcodeLength : StandardOpcodeLengths)
       writeInteger(OpcodeLength, BufferOS, DI.IsLittleEndian);
 
     for (StringRef IncludeDir : LineTable.IncludeDirs) {
@@ -585,8 +606,8 @@ Error DWARFYAML::emitDebugLine(raw_ostream &OS, const DWARFYAML::Data &DI) {
         LineTable.PrologueLength ? *LineTable.PrologueLength : Buffer.size();
 
     for (const DWARFYAML::LineTableOpcode &Op : LineTable.Opcodes)
-      writeLineTableOpcode(Op, LineTable.OpcodeBase, DI.Is64BitAddrSize ? 8 : 4,
-                           BufferOS, DI.IsLittleEndian);
+      writeLineTableOpcode(Op, OpcodeBase, DI.Is64BitAddrSize ? 8 : 4, BufferOS,
+                           DI.IsLittleEndian);
 
     uint64_t Length;
     if (LineTable.Length) {

diff  --git a/llvm/lib/ObjectYAML/DWARFYAML.cpp b/llvm/lib/ObjectYAML/DWARFYAML.cpp
index b3bf6401b4bc..36da74f904ce 100644
--- a/llvm/lib/ObjectYAML/DWARFYAML.cpp
+++ b/llvm/lib/ObjectYAML/DWARFYAML.cpp
@@ -244,8 +244,8 @@ void MappingTraits<DWARFYAML::LineTable>::mapping(
   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.mapOptional("OpcodeBase", LineTable.OpcodeBase);
+  IO.mapOptional("StandardOpcodeLengths", LineTable.StandardOpcodeLengths);
   IO.mapOptional("IncludeDirs", LineTable.IncludeDirs);
   IO.mapOptional("Files", LineTable.Files);
   IO.mapOptional("Opcodes", LineTable.Opcodes);

diff  --git a/llvm/test/tools/yaml2obj/ELF/DWARF/debug-line.yaml b/llvm/test/tools/yaml2obj/ELF/DWARF/debug-line.yaml
index b2211dc1824d..c4e2fb256237 100644
--- a/llvm/test/tools/yaml2obj/ELF/DWARF/debug-line.yaml
+++ b/llvm/test/tools/yaml2obj/ELF/DWARF/debug-line.yaml
@@ -668,3 +668,163 @@ DWARF:
           ## Specify the ExtLen field.
           ExtLen:    0x1234
           SubOpcode: DW_LNE_end_sequence
+
+## m) Test how yaml2obj generates the opcode_base and the
+## standard_opcode_lengths fields.
+
+## Both the opcode_base and the standard_opcode_lengths fields are not
+## specified (DWARFv2).
+
+# RUN: yaml2obj --docnum=13 -DVERSION=2 -DMAXOPSPERINST='' %s -o %t13.o
+# RUN: llvm-readelf --hex-dump=.debug_line %t13.o | \
+# RUN:   FileCheck %s --check-prefix=OPCODEBASEV2
+
+#      OPCODEBASEV2: Hex dump of section '.debug_line':
+# OPCODEBASEV2-NEXT: 0x00000000 16000000 02001000 00000101 00010a00 ................
+##                                                             ^-   opcode_base (10)
+##                                                               ^- standard_opcode_lengths[DW_LNS_copy] = 0
+# OPCODEBASEV2-NEXT: 0x00000010 01010101 00000001 0000              ..........
+##                              ^-                                  standard_opcode_lengths[DW_LNS_advance_pc] = 1
+##                                ^-                                standard_opcode_lengths[DW_LNS_advance_line] = 1
+##                                  ^-                              standard_opcode_lengths[DW_LNS_set_file] = 1
+##                                    ^-                            standard_opcode_lengths[DW_LNS_set_column] = 1
+##                                       ^-                         standard_opcode_lengths[DW_LNS_negate_stmt] = 0
+##                                         ^-                       standard_opcode_lengths[DW_LNS_set_basic_block] = 0
+##                                           ^-                     standard_opcode_lengths[DW_LNS_const_add_pc] = 0
+##                                             ^-                   standard_opcode_lengths[DW_LNS_fixed_advance_pc] = 1
+##                                                ^---              terminators for include_directories and file_names
+
+--- !ELF
+FileHeader:
+  Class: ELFCLASS64
+  Data:  ELFDATA2LSB
+  Type:  ET_EXEC
+DWARF:
+  debug_line:
+    - Version:               [[VERSION=4]]
+      MinInstLength:         1
+      [[MAXOPSPERINST=MaxOpsPerInst: 0]]
+      DefaultIsStmt:         1
+      LineBase:              0
+      LineRange:             1
+      OpcodeBase:            [[OPCODEBASE=<none>]]
+      StandardOpcodeLengths: [[STANDARDOPCODELENGTHS=<none>]]
+
+## Both the opcode_base and the standard_opcode_lengths fields are not
+## specified (DWARFv3).
+
+# RUN: yaml2obj --docnum=13 -DVERSION=3 -DMAXOPSPERINST='' %s -o %t14.o
+# RUN: llvm-readelf --hex-dump=.debug_line %t14.o | \
+# RUN:   FileCheck %s --check-prefix=OPCODEBASEV3
+
+#      OPCODEBASEV3: Hex dump of section '.debug_line':
+# OPCODEBASEV3-NEXT: 0x00000000 19000000 03001300 00000101 00010d00 ................
+##                                                             ^-   opcode_base (13)
+##                                                               ^- standard_opcode_lengths[DW_LNS_copy] = 0
+# OPCODEBASEV3-NEXT: 0x00000010 01010101 00000001 00000100 00       .............
+##                              ^-                                  standard_opcode_lengths[DW_LNS_advance_pc] = 1
+##                                ^-                                standard_opcode_lengths[DW_LNS_advance_line] = 1
+##                                  ^-                              standard_opcode_lengths[DW_LNS_set_file] = 1
+##                                    ^-                            standard_opcode_lengths[DW_LNS_set_column] = 1
+##                                       ^-                         standard_opcode_lengths[DW_LNS_negate_stmt] = 0
+##                                         ^-                       standard_opcode_lengths[DW_LNS_set_basic_block] = 0
+##                                           ^-                     standard_opcode_lengths[DW_LNS_const_add_pc] = 0
+##                                             ^-                   standard_opcode_lengths[DW_LNS_fixed_advance_pc] = 1
+##                                                ^-                standard_opcode_lengths[DW_LNS_set_prologue_end] = 0
+##                                                  ^-              standard_opcode_lengths[DW_LNS_set_epilogue_begin] = 0
+##                                                    ^-            standard_opcode_lengths[DW_LNS_set_isa] = 1
+##                                                      ^----       terminators for include_directories and file_names
+
+## Both the opcode_base and the standard_opcode_lengths fields are not
+## specified (DWARFv4).
+
+# RUN: yaml2obj --docnum=13 %s -o %t15.o
+# RUN: llvm-readelf --hex-dump=.debug_line %t15.o | \
+# RUN:   FileCheck %s --check-prefix=OPCODEBASEV4
+
+#      OPCODEBASEV4: Hex dump of section '.debug_line':
+# OPCODEBASEV4-NEXT: 0x00000000 1a000000 04001400 00000100 0100010d ................
+##                                                              ^- opcode_base (13)
+# OPCODEBASEV4-NEXT: 0x00000010 00010101 01000000 01000001 0000     ..............
+##                              ^-                                  standard_opcode_lengths[DW_LNS_copy] = 0
+##                                ^-                                standard_opcode_lengths[DW_LNS_advance_pc] = 1
+##                                  ^-                              standard_opcode_lengths[DW_LNS_advance_line] = 1
+##                                    ^-                            standard_opcode_lengths[DW_LNS_set_file] = 1
+##                                       ^-                         standard_opcode_lengths[DW_LNS_set_column] = 1
+##                                         ^-                       standard_opcode_lengths[DW_LNS_negate_stmt] = 0
+##                                           ^-                     standard_opcode_lengths[DW_LNS_set_basic_block] = 0
+##                                             ^-                   standard_opcode_lengths[DW_LNS_const_add_pc] = 0
+##                                                ^-                standard_opcode_lengths[DW_LNS_fixed_advance_pc] = 1
+##                                                  ^-              standard_opcode_lengths[DW_LNS_set_prologue_end] = 0
+##                                                    ^-            standard_opcode_lengths[DW_LNS_set_epilogue_begin] = 0
+##                                                      ^-          standard_opcode_lengths[DW_LNS_set_isa] = 1
+##                                                         ^---     terminators for include_directories and file_names
+
+## Specify the opcode_base field (opcode_base == 0).
+
+# RUN: yaml2obj --docnum=13 -DOPCODEBASE=0 %s -o %t16.o
+# RUN: llvm-readelf --hex-dump=.debug_line %t16.o | \
+# RUN:   FileCheck %s --check-prefix=ZERO-OPCODEBASE
+
+#      ZERO-OPCODEBASE: Hex dump of section '.debug_line':
+# ZERO-OPCODEBASE-NEXT: 0x00000000 0e000000 04000800 00000100 01000100 ................
+##                                                                  ^- opcode_base (0)
+# ZERO-OPCODEBASE-NEXT: 0x00000010 0000                                ..
+##                                 ^---                                terminators for include_directories and file_names
+
+## Specify the opcode_base field (opcode_base != 0, opcode_base - 1 < 12).
+## The standard_opcode_lengths array will be truncated.
+
+# RUN: yaml2obj --docnum=13 -DOPCODEBASE=4 %s -o %t17.o
+# RUN: llvm-readelf --hex-dump=.debug_line %t17.o | \
+# RUN:   FileCheck %s --check-prefix=OPCODEBASE
+
+#      OPCODEBASE: Hex dump of section '.debug_line':
+# OPCODEBASE-NEXT: 0x00000000 11000000 04000b00 00000100 01000104 ................
+##                                                             ^- opcode_base (4)
+# OPCODEBASE-NEXT: 0x00000010 00010100 00                         .....
+##                            ^-----                              standard_opcode_lengths (3-byte)
+##                                  ^----                         terminators for include_directories and file_names
+
+## Specify the opcode_base field (opcode_base != 0, opcode_base - 1 > 12).
+## The standard_opcode_lengths array will be extended.
+
+# RUN: yaml2obj --docnum=13 -DOPCODEBASE=20 %s -o %t18.o
+# RUN: llvm-readelf --hex-dump=.debug_line %t18.o | \
+# RUN:   FileCheck %s --check-prefix=OPCODEBASE1
+
+#      OPCODEBASE1: Hex dump of section '.debug_line':
+# OPCODEBASE1-NEXT: 0x00000000 21000000 04001b00 00000100 01000114 !...............
+##                                                              ^- opcode_base (20)
+# OPCODEBASE1-NEXT: 0x00000010 00010101 01000000 01000001 00000000 ................
+##                             ^-------------------------          standard_opcode_lengths defined in DWARFv5 (12-byte)
+##                                                        ^------- extended standard_opcode_lengths (7-byte)
+# OPCODEBASE1-NEXT: 0x00000020 00000000 00                         .....
+##                             ------
+##                                   ^----                         terminators for include_directories and file_names
+
+## Specify the standard_opcode_lengths field.
+
+# RUN: yaml2obj --docnum=13 -DSTANDARDOPCODELENGTHS=[0,1,0] %s -o %t19.o
+# RUN: llvm-readelf --hex-dump=.debug_line %t19.o | \
+# RUN:   FileCheck %s --check-prefix=OPCODELENGTHS
+
+#      OPCODELENGTHS: Hex dump of section '.debug_line':
+# OPCODELENGTHS-NEXT: 0x00000000 11000000 04000b00 00000100 01000104 ................
+##                                                                ^- opcode_base (4)
+# OPCODELENGTHS-NEXT: 0x00000010 00010000 00                         .....
+##                               ^-----                              standard_opcode_lengths (3-byte)
+##                                     ^----                         terminators for include_directories and file_names
+
+## Specify both the opcode_base and the standard_opcode_lengths fields.
+
+# RUN: yaml2obj --docnum=13 -DOPCODEBASE=2 -DSTANDARDOPCODELENGTHS=[0,1,0] %s -o %t20.o
+# RUN: llvm-readelf --hex-dump=.debug_line %t20.o | \
+# RUN:   FileCheck %s --check-prefix=OPCODEBASE-LENGTHS
+
+#      OPCODEBASE-LENGTHS: Hex dump of section '.debug_line':
+# OPCODEBASE-LENGTHS-NEXT: 0x00000000 11000000 04000b00 00000100 01000102 ................
+##                                                                     ^- opcode_base (2)
+# OPCODEBASE-LENGTHS-NEXT: 0x00000010 00010000 00                         .....
+##                                    ^-----                              standard_opcode_lengths (3-byte)
+##                                          ^----                         terminators for include_directories and file_names

diff  --git a/llvm/tools/obj2yaml/dwarf2yaml.cpp b/llvm/tools/obj2yaml/dwarf2yaml.cpp
index 4078abaf89c8..25733e69b5bc 100644
--- a/llvm/tools/obj2yaml/dwarf2yaml.cpp
+++ b/llvm/tools/obj2yaml/dwarf2yaml.cpp
@@ -378,9 +378,9 @@ void dumpDebugLines(DWARFContext &DCtx, DWARFYAML::Data &Y) {
       DebugLines.LineRange = LineData.getU8(&Offset);
       DebugLines.OpcodeBase = LineData.getU8(&Offset);
 
-      DebugLines.StandardOpcodeLengths.reserve(DebugLines.OpcodeBase - 1);
+      DebugLines.StandardOpcodeLengths.emplace();
       for (uint8_t i = 1; i < DebugLines.OpcodeBase; ++i)
-        DebugLines.StandardOpcodeLengths.push_back(LineData.getU8(&Offset));
+        DebugLines.StandardOpcodeLengths->push_back(LineData.getU8(&Offset));
 
       while (Offset < EndPrologue) {
         StringRef Dir = LineData.getCStr(&Offset);
@@ -422,7 +422,7 @@ void dumpDebugLines(DWARFContext &DCtx, DWARFYAML::Data &Y) {
             while (Offset < StartExt + *NewOp.ExtLen)
               NewOp.UnknownOpcodeData.push_back(LineData.getU8(&Offset));
           }
-        } else if (NewOp.Opcode < DebugLines.OpcodeBase) {
+        } else if (NewOp.Opcode < *DebugLines.OpcodeBase) {
           switch (NewOp.Opcode) {
           case dwarf::DW_LNS_copy:
           case dwarf::DW_LNS_negate_stmt:
@@ -449,7 +449,9 @@ void dumpDebugLines(DWARFContext &DCtx, DWARFYAML::Data &Y) {
 
           default:
             for (uint8_t i = 0;
-                 i < DebugLines.StandardOpcodeLengths[NewOp.Opcode - 1]; ++i)
+                 i <
+                 DebugLines.StandardOpcodeLengths.getValue()[NewOp.Opcode - 1];
+                 ++i)
               NewOp.StandardOpcodeData.push_back(LineData.getULEB128(&Offset));
           }
         }


        


More information about the llvm-commits mailing list