
This current implementation does not cover the following: * Setting correct breakpoint when exiting loop * Setting correct breakpoint when returning from function * All facilities are available for this, it just is not taken into account in the current `next` implementation.
99 lines
2.1 KiB
Go
99 lines
2.1 KiB
Go
package line
|
|
|
|
import (
|
|
"bytes"
|
|
"encoding/binary"
|
|
|
|
"github.com/derekparker/dbg/dwarf/util"
|
|
)
|
|
|
|
type DebugLinePrologue struct {
|
|
Length uint32
|
|
Version uint16
|
|
PrologueLength uint32
|
|
MinInstrLength uint8
|
|
InitialIsStmt uint8
|
|
LineBase int8
|
|
LineRange uint8
|
|
OpcodeBase uint8
|
|
StdOpLengths []uint8
|
|
}
|
|
|
|
type DebugLineInfo struct {
|
|
Prologue *DebugLinePrologue
|
|
IncludeDirs []string
|
|
FileNames []*FileEntry
|
|
Instructions []byte
|
|
}
|
|
|
|
type FileEntry struct {
|
|
Name string
|
|
DirIdx uint64
|
|
LastModTime uint64
|
|
Length uint64
|
|
}
|
|
|
|
func Parse(data []byte) *DebugLineInfo {
|
|
var (
|
|
dbl = &DebugLineInfo{}
|
|
buf = bytes.NewBuffer(data)
|
|
)
|
|
|
|
parseDebugLinePrologue(dbl, buf)
|
|
parseIncludeDirs(dbl, buf)
|
|
parseFileEntries(dbl, buf)
|
|
dbl.Instructions = buf.Bytes()
|
|
|
|
return dbl
|
|
}
|
|
|
|
func parseDebugLinePrologue(dbl *DebugLineInfo, buf *bytes.Buffer) {
|
|
p := &DebugLinePrologue{}
|
|
|
|
binary.Read(buf, binary.LittleEndian, &p.Length)
|
|
binary.Read(buf, binary.LittleEndian, &p.Version)
|
|
binary.Read(buf, binary.LittleEndian, &p.PrologueLength)
|
|
binary.Read(buf, binary.LittleEndian, &p.MinInstrLength)
|
|
binary.Read(buf, binary.LittleEndian, &p.InitialIsStmt)
|
|
binary.Read(buf, binary.LittleEndian, &p.LineBase)
|
|
binary.Read(buf, binary.LittleEndian, &p.LineRange)
|
|
binary.Read(buf, binary.LittleEndian, &p.OpcodeBase)
|
|
binary.Read(buf, binary.LittleEndian, &p.StdOpLengths)
|
|
|
|
p.StdOpLengths = make([]uint8, p.OpcodeBase-1)
|
|
for i := uint8(0); i < p.OpcodeBase-1; i++ {
|
|
binary.Read(buf, binary.LittleEndian, &p.StdOpLengths[i])
|
|
}
|
|
|
|
dbl.Prologue = p
|
|
}
|
|
|
|
func parseIncludeDirs(info *DebugLineInfo, buf *bytes.Buffer) {
|
|
for {
|
|
str, _ := util.ParseString(buf)
|
|
if str == "" {
|
|
break
|
|
}
|
|
|
|
info.IncludeDirs = append(info.IncludeDirs, str)
|
|
}
|
|
}
|
|
|
|
func parseFileEntries(info *DebugLineInfo, buf *bytes.Buffer) {
|
|
for {
|
|
entry := FileEntry{}
|
|
|
|
name, _ := util.ParseString(buf)
|
|
if name == "" {
|
|
break
|
|
}
|
|
|
|
entry.Name = name
|
|
entry.DirIdx, _ = util.DecodeULEB128(buf)
|
|
entry.LastModTime, _ = util.DecodeULEB128(buf)
|
|
entry.Length, _ = util.DecodeULEB128(buf)
|
|
|
|
info.FileNames = append(info.FileNames, &entry)
|
|
}
|
|
}
|