Refactor extractValue so OP_DW_addr will work

This commit is contained in:
epipho
2014-12-31 02:37:27 -05:00
parent 07940dc59e
commit c0fd1a0295

View File

@ -464,27 +464,27 @@ func (thread *ThreadContext) extractVariableFromEntry(entry *dwarf.Entry) (*Vari
// Extracts the value from the instructions given in the DW_AT_location entry. // Extracts the value from the instructions given in the DW_AT_location entry.
// We execute the stack program described in the DW_OP_* instruction stream, and // We execute the stack program described in the DW_OP_* instruction stream, and
// then grab the value from the other processes memory. // then grab the value from the other processes memory.
func (thread *ThreadContext) extractValue(instructions []byte, off int64, typ interface{}) (string, error) { func (thread *ThreadContext) extractValue(instructions []byte, addr int64, typ interface{}) (string, error) {
regs, err := thread.Registers() address := addr
if err != nil {
return "", err
}
fde, err := thread.Process.FrameEntries.FDEForPC(regs.PC()) if address == 0 {
if err != nil { regs, err := thread.Registers()
return "", err if err != nil {
} return "", err
}
fctx := fde.EstablishFrame(regs.PC())
cfaOffset := fctx.CFAOffset() fde, err := thread.Process.FrameEntries.FDEForPC(regs.PC())
if err != nil {
offset := off return "", err
if off == 0 { }
offset, err = op.ExecuteStackProgram(cfaOffset, instructions)
fctx := fde.EstablishFrame(regs.PC())
cfaOffset := fctx.CFAOffset() + int64(regs.SP())
address, err = op.ExecuteStackProgram(cfaOffset, instructions)
if err != nil { if err != nil {
return "", err return "", err
} }
offset = int64(regs.SP()) + offset
} }
// If we have a user defined type, find the // If we have a user defined type, find the
@ -493,15 +493,14 @@ func (thread *ThreadContext) extractValue(instructions []byte, off int64, typ in
typ = tt.Type typ = tt.Type
} }
offaddr := uintptr(offset) ptraddress := uintptr(address)
switch t := typ.(type) { switch t := typ.(type) {
case *dwarf.PtrType: case *dwarf.PtrType:
addr, err := thread.readMemory(offaddr, ptrsize) ptr, err := thread.readMemory(ptraddress, ptrsize)
if err != nil { if err != nil {
return "", err return "", err
} }
adr := binary.LittleEndian.Uint64(addr) val, err := thread.extractValue(nil, int64(binary.LittleEndian.Uint64(ptr)), t.Type)
val, err := thread.extractValue(nil, int64(adr), t.Type)
if err != nil { if err != nil {
return "", err return "", err
} }
@ -511,15 +510,15 @@ func (thread *ThreadContext) extractValue(instructions []byte, off int64, typ in
case *dwarf.StructType: case *dwarf.StructType:
switch t.StructName { switch t.StructName {
case "string": case "string":
return thread.readString(offaddr, t.ByteSize) return thread.readString(ptraddress, t.ByteSize)
case "[]int": case "[]int":
return thread.readIntSlice(offaddr, t) return thread.readIntSlice(ptraddress, t)
default: default:
// Recursively call extractValue to grab // Recursively call extractValue to grab
// the value of all the members of the struct. // the value of all the members of the struct.
fields := make([]string, 0, len(t.Field)) fields := make([]string, 0, len(t.Field))
for _, field := range t.Field { for _, field := range t.Field {
val, err := thread.extractValue(nil, field.ByteOffset+offset, field.Type) val, err := thread.extractValue(nil, field.ByteOffset+address, field.Type)
if err != nil { if err != nil {
return "", err return "", err
} }
@ -530,11 +529,11 @@ func (thread *ThreadContext) extractValue(instructions []byte, off int64, typ in
return retstr, nil return retstr, nil
} }
case *dwarf.ArrayType: case *dwarf.ArrayType:
return thread.readIntArray(offaddr, t) return thread.readIntArray(ptraddress, t)
case *dwarf.IntType: case *dwarf.IntType:
return thread.readInt(offaddr, t.ByteSize) return thread.readInt(ptraddress, t.ByteSize)
case *dwarf.FloatType: case *dwarf.FloatType:
return thread.readFloat(offaddr, t.ByteSize) return thread.readFloat(ptraddress, t.ByteSize)
} }
return "", fmt.Errorf("could not find value for type %s", typ) return "", fmt.Errorf("could not find value for type %s", typ)