mirror of
https://github.com/RPCS3/llvm-mirror.git
synced 2024-11-25 20:23:11 +01:00
47d98c2dc3
Reviewed by: dblaikie, JDevlieghere, espindola Differential Revision: https://reviews.llvm.org/D44560 Summary: The .debug_line parser previously reported errors by printing to stderr and return false. This is not particularly helpful for clients of the library code, as it prevents them from handling the errors in a manner based on the calling context. This change switches to using llvm::Error and callbacks to indicate what problems were detected during parsing, and has updated clients to handle the errors in a location-specific manner. In general, this means that they continue to do the same thing to external users. Below, I have outlined what the known behaviour changes are, relating to this change. There are two levels of "errors" in the new error mechanism, to broadly distinguish between different fail states of the parser, since not every failure will prevent parsing of the unit, or of subsequent unit. Malformed table errors that prevent reading the remainder of the table (reported by returning them) and other minor issues representing problems with parsing that do not prevent attempting to continue reading the table (reported by calling a specified callback funciton). The only example of this currently is when the last sequence of a unit is unterminated. However, I think it would be good to change the handling of unrecognised opcodes to report as minor issues as well, rather than just printing to the stream if --verbose is used (this would be a subsequent change however). I have substantially extended the DwarfGenerator to be able to handle custom-crafted .debug_line sections, allowing for comprehensive unit-testing of the parser code. For now, I am just adding unit tests to cover the basic error reporting, and positive cases, and do not currently intend to test every part of the parser, although the framework should be sufficient to do so at a later point. Known behaviour changes: - The dump function in DWARFContext now does not attempt to read subsequent tables when searching for a specific offset, if the unit length field of a table before the specified offset is a reserved value. - getOrParseLineTable now returns a useful Error if an invalid offset is encountered, rather than simply a nullptr. - The parse functions no longer use `WithColor::warning` directly to report errors, allowing LLD to call its own warning function. - The existing parse error messages have been updated to not specifically include "warning" in their message, allowing consumers to determine what severity the problem is. - If the line table version field appears to have a value less than 2, an informative error is returned, instead of just false. - If the line table unit length field uses a reserved value, an informative error is returned, instead of just false. - Dumping of .debug_line.dwo sections is now implemented the same as regular .debug_line sections. - Verbose dumping of .debug_line[.dwo] sections now prints the prologue, if there is a prologue error, just like non-verbose dumping. As a helper for the generator code, I have re-added emitInt64 to the AsmPrinter code. This previously existed, but was removed way back in r100296, presumably because it was dead at the time. This change also requires a change to LLD, which will be committed separately. llvm-svn: 331971
153 lines
5.1 KiB
ArmAsm
153 lines
5.1 KiB
ArmAsm
# Test object to verify dwarfdump handles a syntactically correct line-number
|
|
# program containing unrecognized extended opcodes.
|
|
# RUN: llvm-mc -triple x86_64-unknown-linux %s -filetype=obj -o %t.o
|
|
# RUN: llvm-dwarfdump -v %t.o | FileCheck %s
|
|
# RUN: llvm-dwarfdump -v %t.o 2>&1 | FileCheck %s --check-prefix=ERR
|
|
|
|
.section .text
|
|
# Dummy function
|
|
foo: ret
|
|
|
|
# FIXME: When we can dump a line-table without a unit, we could remove
|
|
# the .debug_abbrev and .debug_info sections from this test.
|
|
.section .debug_abbrev,"",@progbits
|
|
.byte 0x01 # Abbrev code
|
|
.byte 0x11 # DW_TAG_compile_unit
|
|
.byte 0x00 # DW_CHILDREN_no
|
|
.byte 0x10 # DW_AT_stmt_list
|
|
.byte 0x17 # DW_FORM_sec_offset
|
|
.byte 0x00 # EOM(1)
|
|
.byte 0x00 # EOM(2)
|
|
|
|
.section .debug_info,"",@progbits
|
|
.long CU_end-CU_version # Length of Unit
|
|
CU_version:
|
|
.short 4 # DWARF version number
|
|
.long .debug_abbrev # Offset Into Abbrev. Section
|
|
.byte 8 # Address Size (in bytes)
|
|
# The compile-unit DIE, with DW_AT_stmt_list.
|
|
.byte 1
|
|
.long LT_start
|
|
.byte 0 # NULL
|
|
CU_end:
|
|
|
|
.long CU2_end-CU2_version # Length of Unit
|
|
CU2_version:
|
|
.short 4 # DWARF version number
|
|
.long .debug_abbrev # Offset Into Abbrev. Section
|
|
.byte 8 # Address Size (in bytes)
|
|
# The compile-unit DIE, with DW_AT_stmt_list.
|
|
.byte 1
|
|
.long LT2_start
|
|
.byte 0 # NULL
|
|
CU2_end:
|
|
|
|
.section .debug_line,"",@progbits
|
|
# CHECK-LABEL: .debug_line contents:
|
|
|
|
# DWARF v4 line-table header.
|
|
LT_start:
|
|
.long LT_end-LT_version # Length of Unit (DWARF-32 format)
|
|
LT_version:
|
|
.short 4 # DWARF version number
|
|
.long LT_header_end-LT_params # Length of Prologue
|
|
LT_params:
|
|
.byte 1 # Minimum Instruction Length
|
|
.byte 1 # Maximum Operations per Instruction
|
|
.byte 1 # Default is_stmt
|
|
.byte -5 # Line Base
|
|
.byte 14 # Line Range
|
|
.byte 13 # Opcode Base
|
|
.byte 0 # Standard Opcode Lengths
|
|
.byte 1
|
|
.byte 1
|
|
.byte 1
|
|
.byte 1
|
|
.byte 0
|
|
.byte 0
|
|
.byte 0
|
|
.byte 1
|
|
.byte 0
|
|
.byte 0
|
|
.byte 1
|
|
# No directories.
|
|
.byte 0
|
|
# No files.
|
|
.byte 0
|
|
LT_header_end:
|
|
# Bogus extended opcode with zero length.
|
|
.byte 0 # Extended opcode indicator.
|
|
.byte 0 # LEB length of extended opcode + operands.
|
|
# Real opcode and operand.
|
|
.byte 0
|
|
.byte 9
|
|
.byte 2 # DW_LNE_set_address
|
|
.quad .text
|
|
# Bogus extended opcode with multibyte LEB length.
|
|
.byte 0
|
|
.byte 0x82 # Length of 2 but with additional length byte.
|
|
.byte 0 # Additional length byte.
|
|
.byte 0x47 # Unrecognized opcode...
|
|
.byte 0 # with its 1-byte operand.
|
|
# Proper end-sequence opcode.
|
|
.byte 0
|
|
.byte 1
|
|
.byte 1 # DW_LNE_end_sequence
|
|
LT_end:
|
|
|
|
# CHECK: Line table prologue:
|
|
# CHECK: version: 4
|
|
# Exact prologue length isn't important but it tells us where to expect the
|
|
# line-number program to start, and we do want to verify those offsets.
|
|
# CHECK-NEXT: prologue_length: 0x00000014
|
|
# CHECK: 0x0000001e: 00 Badly formed extended line op
|
|
# CHECK-NEXT: 0x00000020: 00 DW_LNE_set_address
|
|
# CHECK-NEXT: 0x0000002b: 00 Unrecognized extended op 0x47 length 2
|
|
# CHECK-NEXT: 0x00000030: 00 DW_LNE_end_sequence
|
|
# CHECK-NEXT: 0x0000000000000000 {{.*}} is_stmt end_sequence
|
|
|
|
|
|
# DWARF v4 line-table header #2.
|
|
LT2_start:
|
|
.long LT2_end-LT2_version # Length of Unit (DWARF-32 format)
|
|
LT2_version:
|
|
.short 4 # DWARF version number
|
|
.long LT2_header_end-LT2_params # Length of Prologue
|
|
LT2_params:
|
|
.byte 1 # Minimum Instruction Length
|
|
.byte 1 # Maximum Operations per Instruction
|
|
.byte 1 # Default is_stmt
|
|
.byte -5 # Line Base
|
|
.byte 14 # Line Range
|
|
.byte 13 # Opcode Base
|
|
.byte 0 # Standard Opcode Lengths
|
|
.byte 1
|
|
.byte 1
|
|
.byte 1
|
|
.byte 1
|
|
.byte 0
|
|
.byte 0
|
|
.byte 0
|
|
.byte 1
|
|
.byte 0
|
|
.byte 0
|
|
.byte 1
|
|
# No directories.
|
|
.byte 0
|
|
# No files.
|
|
.byte 0
|
|
LT2_header_end:
|
|
# Real opcode and operand.
|
|
.byte 0
|
|
.byte 9
|
|
.byte 2 # DW_LNE_set_address
|
|
.quad .text
|
|
# Real opcode with incorrect length.
|
|
.byte 0
|
|
.byte 2 # Wrong length, should be 1.
|
|
.byte 1 # DW_LNE_end_sequence
|
|
LT2_end:
|
|
|
|
# ERR: warning: unexpected line op length at offset 0x0000005e
|
|
# ERR-SAME: expected 0x02 found 0x01
|