Miscellaneous debug_line improvements (#1999)
* dwarf/line: implement DW_LNE_set_discriminator We don't use the discriminator field in any way but we need to at least parse it to support debub_line programs that use it. * dwarf/line: support parsing DWARF4 debug_line sections There is an extra field maximum_operations_per_instruction that is used for VLIW CPUs. We don't support this feature but we have to at least parse the field to not crash.
This commit is contained in:
parent
bc30b53926
commit
c3a4d726e2
BIN
_fixtures/zdebug_line_dwarf4
Normal file
BIN
_fixtures/zdebug_line_dwarf4
Normal file
Binary file not shown.
@ -14,6 +14,7 @@ type DebugLinePrologue struct {
|
|||||||
Version uint16
|
Version uint16
|
||||||
Length uint32
|
Length uint32
|
||||||
MinInstrLength uint8
|
MinInstrLength uint8
|
||||||
|
MaxOpPerInstr uint8
|
||||||
InitialIsStmt uint8
|
InitialIsStmt uint8
|
||||||
LineBase int8
|
LineBase int8
|
||||||
LineRange uint8
|
LineRange uint8
|
||||||
@ -102,6 +103,11 @@ func parseDebugLinePrologue(dbl *DebugLineInfo, buf *bytes.Buffer) {
|
|||||||
p.Version = binary.LittleEndian.Uint16(buf.Next(2))
|
p.Version = binary.LittleEndian.Uint16(buf.Next(2))
|
||||||
p.Length = binary.LittleEndian.Uint32(buf.Next(4))
|
p.Length = binary.LittleEndian.Uint32(buf.Next(4))
|
||||||
p.MinInstrLength = uint8(buf.Next(1)[0])
|
p.MinInstrLength = uint8(buf.Next(1)[0])
|
||||||
|
if p.Version == 4 {
|
||||||
|
p.MaxOpPerInstr = uint8(buf.Next(1)[0])
|
||||||
|
} else {
|
||||||
|
p.MaxOpPerInstr = 1
|
||||||
|
}
|
||||||
p.InitialIsStmt = uint8(buf.Next(1)[0])
|
p.InitialIsStmt = uint8(buf.Next(1)[0])
|
||||||
p.LineBase = int8(buf.Next(1)[0])
|
p.LineBase = int8(buf.Next(1)[0])
|
||||||
p.LineRange = uint8(buf.Next(1)[0])
|
p.LineRange = uint8(buf.Next(1)[0])
|
||||||
|
@ -1,6 +1,7 @@
|
|||||||
package line
|
package line
|
||||||
|
|
||||||
import (
|
import (
|
||||||
|
"compress/zlib"
|
||||||
"debug/elf"
|
"debug/elf"
|
||||||
"debug/macho"
|
"debug/macho"
|
||||||
"debug/pe"
|
"debug/pe"
|
||||||
@ -342,3 +343,38 @@ func TestDebugLineC(t *testing.T) {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
func TestDebugLineDwarf4(t *testing.T) {
|
||||||
|
p, err := filepath.Abs("../../../_fixtures/zdebug_line_dwarf4")
|
||||||
|
if err != nil {
|
||||||
|
t.Fatal("Could not find test data", p, err)
|
||||||
|
}
|
||||||
|
fh, err := os.Open(p)
|
||||||
|
if err != nil {
|
||||||
|
t.Fatal("Could not open test data", err)
|
||||||
|
}
|
||||||
|
defer fh.Close()
|
||||||
|
fh.Seek(12, 0) // skip "ZLIB" magic signature and length
|
||||||
|
r, err := zlib.NewReader(fh)
|
||||||
|
if err != nil {
|
||||||
|
t.Fatal("Could not open test data (zlib)", err)
|
||||||
|
}
|
||||||
|
data, err := ioutil.ReadAll(r)
|
||||||
|
if err != nil {
|
||||||
|
t.Fatal("Could not read test data", err)
|
||||||
|
}
|
||||||
|
|
||||||
|
debugLines := ParseAll(data, nil, 0, true, 8)
|
||||||
|
|
||||||
|
for _, dbl := range debugLines {
|
||||||
|
if dbl.Prologue.Version == 4 {
|
||||||
|
if dbl.Prologue.LineBase != -5 {
|
||||||
|
t.Errorf("Wrong LineBase %d\n", dbl.Prologue.LineBase)
|
||||||
|
}
|
||||||
|
if dbl.Prologue.LineRange != 14 {
|
||||||
|
t.Errorf("Wrong LineRange %d\n", dbl.Prologue.LineRange)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
@ -80,6 +80,7 @@ const (
|
|||||||
DW_LINE_end_sequence = 1
|
DW_LINE_end_sequence = 1
|
||||||
DW_LINE_set_address = 2
|
DW_LINE_set_address = 2
|
||||||
DW_LINE_define_file = 3
|
DW_LINE_define_file = 3
|
||||||
|
DW_LINE_set_discriminator = 4
|
||||||
)
|
)
|
||||||
|
|
||||||
var standardopcodes = map[byte]opcodefn{
|
var standardopcodes = map[byte]opcodefn{
|
||||||
@ -101,6 +102,7 @@ var extendedopcodes = map[byte]opcodefn{
|
|||||||
DW_LINE_end_sequence: endsequence,
|
DW_LINE_end_sequence: endsequence,
|
||||||
DW_LINE_set_address: setaddress,
|
DW_LINE_set_address: setaddress,
|
||||||
DW_LINE_define_file: definefile,
|
DW_LINE_define_file: definefile,
|
||||||
|
DW_LINE_set_discriminator: setdiscriminator,
|
||||||
}
|
}
|
||||||
|
|
||||||
func newStateMachine(dbl *DebugLineInfo, instructions []byte, ptrSize int) *StateMachine {
|
func newStateMachine(dbl *DebugLineInfo, instructions []byte, ptrSize int) *StateMachine {
|
||||||
@ -548,6 +550,10 @@ func setaddress(sm *StateMachine, buf *bytes.Buffer) {
|
|||||||
sm.address = addr + sm.dbl.staticBase
|
sm.address = addr + sm.dbl.staticBase
|
||||||
}
|
}
|
||||||
|
|
||||||
|
func setdiscriminator(sm *StateMachine, buf *bytes.Buffer) {
|
||||||
|
_, _ = util.DecodeULEB128(buf)
|
||||||
|
}
|
||||||
|
|
||||||
func definefile(sm *StateMachine, buf *bytes.Buffer) {
|
func definefile(sm *StateMachine, buf *bytes.Buffer) {
|
||||||
entry := readFileEntry(sm.dbl, sm.buf, false)
|
entry := readFileEntry(sm.dbl, sm.buf, false)
|
||||||
sm.definedFiles = append(sm.definedFiles, entry)
|
sm.definedFiles = append(sm.definedFiles, entry)
|
||||||
|
Loading…
Reference in New Issue
Block a user