// SeekToType moves the reader to the type specified by the entry, // optionally resolving typedefs and pointer types. If the reader is set // to a struct type the NextMemberVariable call can be used to walk all member data. func (reader *Reader) SeekToType(entry *dwarf.Entry, resolveTypedefs bool, resolvePointerTypes bool) (*dwarf.Entry, error) { offset, ok := entry.Val(dwarf.AttrType).(dwarf.Offset) if !ok { return nil, fmt.Errorf("entry does not have a type attribute") } // Seek to the first type offset reader.Seek(offset) // Walk the types to the base for typeEntry, err := reader.Next(); typeEntry != nil; typeEntry, err = reader.Next() { if err != nil { return nil, err } if typeEntry.Tag == dwarf.TagTypedef && !resolveTypedefs { return typeEntry, nil } if typeEntry.Tag == dwarf.TagPointerType && !resolvePointerTypes { return typeEntry, nil } offset, ok = typeEntry.Val(dwarf.AttrType).(dwarf.Offset) if !ok { return typeEntry, nil } reader.Seek(offset) } return nil, TypeNotFoundErr }
func (reader *Reader) InstructionsForEntry(entry *dwarf.Entry) ([]byte, error) { if entry.Tag == dwarf.TagMember { instructions, ok := entry.Val(dwarf.AttrDataMemberLoc).([]byte) if !ok { return nil, fmt.Errorf("member data has no data member location attribute") } // clone slice to prevent stomping on the dwarf data return append([]byte{}, instructions...), nil } // non-member instructions, ok := entry.Val(dwarf.AttrLocation).([]byte) if !ok { return nil, fmt.Errorf("entry has no location attribute") } // clone slice to prevent stomping on the dwarf data return append([]byte{}, instructions...), nil }
// Extracts the name and type of a variable from a dwarf entry // then executes the instructions given in the DW_AT_location attribute to grab the variable's address func (scope *EvalScope) extractVarInfoFromEntry(entry *dwarf.Entry, rdr *reader.Reader) (*Variable, error) { if entry == nil { return nil, fmt.Errorf("invalid entry") } if entry.Tag != dwarf.TagFormalParameter && entry.Tag != dwarf.TagVariable { return nil, fmt.Errorf("invalid entry tag, only supports FormalParameter and Variable, got %s", entry.Tag.String()) } n, ok := entry.Val(dwarf.AttrName).(string) if !ok { return nil, fmt.Errorf("type assertion failed") } offset, ok := entry.Val(dwarf.AttrType).(dwarf.Offset) if !ok { return nil, fmt.Errorf("type assertion failed") } t, err := scope.Type(offset) if err != nil { return nil, err } instructions, ok := entry.Val(dwarf.AttrLocation).([]byte) if !ok { return nil, fmt.Errorf("type assertion failed") } addr, err := op.ExecuteStackProgram(scope.CFA, instructions) if err != nil { return nil, err } return scope.newVariable(n, uintptr(addr), t), nil }