[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