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
|
||||
Length uint32
|
||||
MinInstrLength uint8
|
||||
MaxOpPerInstr uint8
|
||||
InitialIsStmt uint8
|
||||
LineBase int8
|
||||
LineRange uint8
|
||||
@ -102,6 +103,11 @@ func parseDebugLinePrologue(dbl *DebugLineInfo, buf *bytes.Buffer) {
|
||||
p.Version = binary.LittleEndian.Uint16(buf.Next(2))
|
||||
p.Length = binary.LittleEndian.Uint32(buf.Next(4))
|
||||
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.LineBase = int8(buf.Next(1)[0])
|
||||
p.LineRange = uint8(buf.Next(1)[0])
|
||||
|
@ -1,6 +1,7 @@
|
||||
package line
|
||||
|
||||
import (
|
||||
"compress/zlib"
|
||||
"debug/elf"
|
||||
"debug/macho"
|
||||
"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_set_address = 2
|
||||
DW_LINE_define_file = 3
|
||||
DW_LINE_set_discriminator = 4
|
||||
)
|
||||
|
||||
var standardopcodes = map[byte]opcodefn{
|
||||
@ -101,6 +102,7 @@ var extendedopcodes = map[byte]opcodefn{
|
||||
DW_LINE_end_sequence: endsequence,
|
||||
DW_LINE_set_address: setaddress,
|
||||
DW_LINE_define_file: definefile,
|
||||
DW_LINE_set_discriminator: setdiscriminator,
|
||||
}
|
||||
|
||||
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
|
||||
}
|
||||
|
||||
func setdiscriminator(sm *StateMachine, buf *bytes.Buffer) {
|
||||
_, _ = util.DecodeULEB128(buf)
|
||||
}
|
||||
|
||||
func definefile(sm *StateMachine, buf *bytes.Buffer) {
|
||||
entry := readFileEntry(sm.dbl, sm.buf, false)
|
||||
sm.definedFiles = append(sm.definedFiles, entry)
|
||||
|
Loading…
Reference in New Issue
Block a user