mirror of
https://github.com/golang/go
synced 2024-11-14 08:40:27 -07:00
add DWARF method to elf.File.
test both ELF and Mach-O in dwarf package. R=r DELTA=83 (44 added, 10 deleted, 29 changed) OCL=34717 CL=34790
This commit is contained in:
parent
bf69025825
commit
92f773dc77
@ -18,22 +18,23 @@ crypto/md5.install: hash.install os.install
|
|||||||
crypto/sha1.install: hash.install os.install
|
crypto/sha1.install: hash.install os.install
|
||||||
datafmt.install: bytes.install container/vector.install fmt.install go/scanner.install go/token.install io.install os.install reflect.install runtime.install strconv.install strings.install
|
datafmt.install: bytes.install container/vector.install fmt.install go/scanner.install go/token.install io.install os.install reflect.install runtime.install strconv.install strings.install
|
||||||
debug/binary.install: io.install math.install os.install reflect.install
|
debug/binary.install: io.install math.install os.install reflect.install
|
||||||
debug/dwarf.install: debug/binary.install fmt.install os.install strconv.install
|
debug/dwarf.install: debug/binary.install os.install strconv.install
|
||||||
debug/elf.install: debug/binary.install fmt.install io.install os.install strconv.install
|
debug/macho.install: bytes.install debug/binary.install debug/dwarf.install fmt.install io.install os.install strconv.install
|
||||||
debug/gosym.install: debug/binary.install fmt.install io.install os.install strconv.install strings.install
|
debug/elf.install: debug/binary.install debug/dwarf.install fmt.install io.install os.install strconv.install
|
||||||
|
debug/gosym.install: debug/binary.install fmt.install os.install strconv.install strings.install
|
||||||
debug/proc.install: container/vector.install fmt.install io.install os.install runtime.install strconv.install strings.install sync.install syscall.install
|
debug/proc.install: container/vector.install fmt.install io.install os.install runtime.install strconv.install strings.install sync.install syscall.install
|
||||||
ebnf.install: container/vector.install fmt.install go/scanner.install go/token.install os.install strconv.install strings.install unicode.install utf8.install
|
ebnf.install: container/vector.install go/scanner.install go/token.install os.install strconv.install unicode.install utf8.install
|
||||||
exec.install: os.install strings.install
|
exec.install: os.install strings.install
|
||||||
exvar.install: bytes.install fmt.install http.install io.install log.install strconv.install sync.install
|
exvar.install: bytes.install fmt.install http.install log.install strconv.install sync.install
|
||||||
flag.install: fmt.install os.install strconv.install
|
flag.install: fmt.install os.install strconv.install
|
||||||
fmt.install: io.install os.install reflect.install strconv.install utf8.install
|
fmt.install: io.install os.install reflect.install strconv.install utf8.install
|
||||||
go/ast.install: go/token.install unicode.install utf8.install
|
go/ast.install: go/token.install unicode.install utf8.install
|
||||||
go/doc.install: container/vector.install fmt.install go/ast.install go/token.install io.install once.install regexp.install sort.install strings.install template.install
|
go/doc.install: container/vector.install go/ast.install go/token.install io.install once.install regexp.install sort.install strings.install template.install
|
||||||
go/parser.install: bytes.install container/vector.install fmt.install go/ast.install go/scanner.install go/token.install io.install os.install path.install strings.install
|
go/parser.install: bytes.install container/vector.install fmt.install go/ast.install go/scanner.install go/token.install io.install os.install path.install strings.install
|
||||||
go/printer.install: container/vector.install fmt.install go/ast.install go/token.install io.install os.install reflect.install strings.install tabwriter.install
|
go/printer.install: container/vector.install fmt.install go/ast.install go/token.install io.install os.install reflect.install strings.install tabwriter.install
|
||||||
go/scanner.install: bytes.install container/vector.install fmt.install go/token.install io.install os.install sort.install strconv.install unicode.install utf8.install
|
go/scanner.install: bytes.install container/vector.install fmt.install go/token.install io.install os.install sort.install strconv.install unicode.install utf8.install
|
||||||
go/token.install: fmt.install strconv.install
|
go/token.install: fmt.install strconv.install
|
||||||
gob.install: bytes.install fmt.install io.install math.install os.install reflect.install strings.install sync.install unicode.install
|
gob.install: bytes.install fmt.install io.install math.install os.install reflect.install sync.install
|
||||||
hash.install: io.install
|
hash.install: io.install
|
||||||
hash/adler32.install: hash.install os.install
|
hash/adler32.install: hash.install os.install
|
||||||
hash/crc32.install: hash.install os.install
|
hash/crc32.install: hash.install os.install
|
||||||
@ -50,9 +51,9 @@ once.install: sync.install
|
|||||||
os.install: once.install syscall.install
|
os.install: once.install syscall.install
|
||||||
path.install: strings.install
|
path.install: strings.install
|
||||||
rand.install:
|
rand.install:
|
||||||
reflect.install: runtime.install strconv.install strings.install
|
reflect.install: runtime.install strconv.install
|
||||||
regexp.install: bytes.install container/vector.install io.install os.install runtime.install utf8.install
|
regexp.install: bytes.install container/vector.install io.install os.install runtime.install utf8.install
|
||||||
rpc.install: bufio.install fmt.install gob.install http.install io.install log.install net.install os.install reflect.install sort.install strconv.install strings.install sync.install template.install unicode.install utf8.install
|
rpc.install: bufio.install fmt.install gob.install http.install io.install log.install net.install os.install reflect.install sort.install strings.install sync.install template.install unicode.install utf8.install
|
||||||
runtime.install:
|
runtime.install:
|
||||||
sort.install:
|
sort.install:
|
||||||
strconv.install: bytes.install math.install os.install unicode.install utf8.install
|
strconv.install: bytes.install math.install os.install unicode.install utf8.install
|
||||||
|
@ -33,6 +33,7 @@ DIRS=\
|
|||||||
datafmt\
|
datafmt\
|
||||||
debug/binary\
|
debug/binary\
|
||||||
debug/dwarf\
|
debug/dwarf\
|
||||||
|
debug/macho\
|
||||||
debug/elf\
|
debug/elf\
|
||||||
debug/gosym\
|
debug/gosym\
|
||||||
debug/proc\
|
debug/proc\
|
||||||
|
6
src/pkg/debug/dwarf/testdata/typedef.c
vendored
6
src/pkg/debug/dwarf/testdata/typedef.c
vendored
@ -3,7 +3,11 @@
|
|||||||
// license that can be found in the LICENSE file.
|
// license that can be found in the LICENSE file.
|
||||||
|
|
||||||
/*
|
/*
|
||||||
gcc -gdwarf-2 -c typedef.c && gcc -gdwarf-2 -o typedef.elf typedef.o
|
Linux ELF:
|
||||||
|
gcc -gdwarf-2 -m64 -c typedef.c && gcc -gdwarf-2 -m64 -o typedef.elf typedef.o
|
||||||
|
|
||||||
|
OS X Mach-O:
|
||||||
|
gcc -gdwarf-2 -m64 -c typedef.c -o typedef.macho
|
||||||
*/
|
*/
|
||||||
|
|
||||||
typedef volatile int* t_ptr_volatile_int;
|
typedef volatile int* t_ptr_volatile_int;
|
||||||
|
@ -103,7 +103,7 @@ type ArrayType struct {
|
|||||||
CommonType;
|
CommonType;
|
||||||
Type Type;
|
Type Type;
|
||||||
StrideBitSize int64; // if > 0, number of bits to hold each element
|
StrideBitSize int64; // if > 0, number of bits to hold each element
|
||||||
Count int64;
|
Count int64; // if == -1, an incomplete array, like char x[].
|
||||||
}
|
}
|
||||||
|
|
||||||
func (t *ArrayType) String() string {
|
func (t *ArrayType) String() string {
|
||||||
@ -111,8 +111,6 @@ func (t *ArrayType) String() string {
|
|||||||
}
|
}
|
||||||
|
|
||||||
// A VoidType represents the C void type.
|
// A VoidType represents the C void type.
|
||||||
// It is only used as the subtype for a pointer:
|
|
||||||
// a FuncType that returns no value has a nil ReturnType.
|
|
||||||
type VoidType struct {
|
type VoidType struct {
|
||||||
CommonType;
|
CommonType;
|
||||||
}
|
}
|
||||||
@ -306,8 +304,8 @@ func (d *Data) Type(off Offset) (Type, os.Error) {
|
|||||||
typeOf := func(e *Entry) Type {
|
typeOf := func(e *Entry) Type {
|
||||||
toff, ok := e.Val(AttrType).(Offset);
|
toff, ok := e.Val(AttrType).(Offset);
|
||||||
if !ok {
|
if !ok {
|
||||||
err = DecodeError{"info", e.Offset, "missing type attribute"};
|
// It appears that no Type means "void".
|
||||||
return nil;
|
return new(VoidType);
|
||||||
}
|
}
|
||||||
var t Type;
|
var t Type;
|
||||||
if t, err = d.Type(toff); err != nil {
|
if t, err = d.Type(toff); err != nil {
|
||||||
@ -343,8 +341,7 @@ func (d *Data) Type(off Offset) (Type, os.Error) {
|
|||||||
case TagSubrangeType:
|
case TagSubrangeType:
|
||||||
max, ok := kid.Val(AttrUpperBound).(int64);
|
max, ok := kid.Val(AttrUpperBound).(int64);
|
||||||
if !ok {
|
if !ok {
|
||||||
err = DecodeError{"info", kid.Offset, "missing upper bound"};
|
max = -2; // Count == -1, as in x[].
|
||||||
goto Error;
|
|
||||||
}
|
}
|
||||||
if ndim == 0 {
|
if ndim == 0 {
|
||||||
t.Count = max+1;
|
t.Count = max+1;
|
||||||
@ -548,11 +545,9 @@ func (d *Data) Type(off Offset) (Type, os.Error) {
|
|||||||
t := new(FuncType);
|
t := new(FuncType);
|
||||||
typ = t;
|
typ = t;
|
||||||
d.typeCache[off] = t;
|
d.typeCache[off] = t;
|
||||||
if e.Val(AttrType) != nil {
|
|
||||||
if t.ReturnType = typeOf(e); err != nil {
|
if t.ReturnType = typeOf(e); err != nil {
|
||||||
goto Error;
|
goto Error;
|
||||||
}
|
}
|
||||||
}
|
|
||||||
t.ParamType = make([]Type, 0, 8);
|
t.ParamType = make([]Type, 0, 8);
|
||||||
for kid := next(); kid != nil; kid = next() {
|
for kid := next(); kid != nil; kid = next() {
|
||||||
var tkid Type;
|
var tkid Type;
|
||||||
|
@ -2,10 +2,12 @@
|
|||||||
// Use of this source code is governed by a BSD-style
|
// Use of this source code is governed by a BSD-style
|
||||||
// license that can be found in the LICENSE file.
|
// license that can be found in the LICENSE file.
|
||||||
|
|
||||||
package dwarf
|
package dwarf_test
|
||||||
|
|
||||||
import (
|
import (
|
||||||
|
. "debug/dwarf";
|
||||||
"debug/elf";
|
"debug/elf";
|
||||||
|
"debug/macho";
|
||||||
"testing";
|
"testing";
|
||||||
)
|
)
|
||||||
|
|
||||||
@ -33,29 +35,36 @@ func elfData(t *testing.T, name string) *Data {
|
|||||||
t.Fatal(err);
|
t.Fatal(err);
|
||||||
}
|
}
|
||||||
|
|
||||||
dat := func(name string) []byte {
|
d, err := f.DWARF();
|
||||||
s := f.Section(".debug_" + name);
|
|
||||||
if s == nil {
|
|
||||||
return nil
|
|
||||||
}
|
|
||||||
b, err := s.Data();
|
|
||||||
if err != nil {
|
if err != nil {
|
||||||
t.Fatal(".debug_"+name+":", err);
|
t.Fatal(err);
|
||||||
}
|
}
|
||||||
return b;
|
return d;
|
||||||
};
|
}
|
||||||
|
|
||||||
d, err := New(dat("abbrev"), nil, nil, dat("info"), nil, nil, nil, dat("str"));
|
func machoData(t *testing.T, name string) *Data {
|
||||||
|
f, err := macho.Open(name);
|
||||||
if err != nil {
|
if err != nil {
|
||||||
t.Fatal("New:", err);
|
t.Fatal(err);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
d, err := f.DWARF();
|
||||||
|
if err != nil {
|
||||||
|
t.Fatal(err);
|
||||||
|
}
|
||||||
return d;
|
return d;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
func TestTypedefs(t *testing.T) {
|
func TestTypedefsELF(t *testing.T) {
|
||||||
d := elfData(t, "testdata/typedef.elf");
|
testTypedefs(t, elfData(t, "testdata/typedef.elf"));
|
||||||
|
}
|
||||||
|
|
||||||
|
func TestTypedefsMachO(t *testing.T) {
|
||||||
|
testTypedefs(t, machoData(t, "testdata/typedef.macho"));
|
||||||
|
}
|
||||||
|
|
||||||
|
func testTypedefs(t *testing.T, d *Data) {
|
||||||
r := d.Reader();
|
r := d.Reader();
|
||||||
seen := make(map[string]bool);
|
seen := make(map[string]bool);
|
||||||
for {
|
for {
|
||||||
|
@ -7,6 +7,7 @@ package elf
|
|||||||
|
|
||||||
import (
|
import (
|
||||||
"debug/binary";
|
"debug/binary";
|
||||||
|
"debug/dwarf";
|
||||||
"fmt";
|
"fmt";
|
||||||
"io";
|
"io";
|
||||||
"os";
|
"os";
|
||||||
@ -330,3 +331,26 @@ func (f *File) Section(name string) *Section {
|
|||||||
}
|
}
|
||||||
return nil;
|
return nil;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
func (f *File) DWARF() (*dwarf.Data, os.Error) {
|
||||||
|
// There are many other DWARF sections, but these
|
||||||
|
// are the required ones, and the debug/dwarf package
|
||||||
|
// does not use the others, so don't bother loading them.
|
||||||
|
var names = [...]string{"abbrev", "info", "str"};
|
||||||
|
var dat [len(names)][]byte;
|
||||||
|
for i, name := range names {
|
||||||
|
name = ".debug_" + name;
|
||||||
|
s := f.Section(name);
|
||||||
|
if s == nil {
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
b, err := s.Data();
|
||||||
|
if err != nil && uint64(len(b)) < s.Size {
|
||||||
|
return nil, err;
|
||||||
|
}
|
||||||
|
dat[i] = b;
|
||||||
|
}
|
||||||
|
|
||||||
|
abbrev, info, str := dat[0], dat[1], dat[2];
|
||||||
|
return dwarf.New(abbrev, nil, nil, info, nil, nil, nil, str);
|
||||||
|
}
|
||||||
|
Loading…
Reference in New Issue
Block a user