From cf06750372c054f0faa9c79f0f957a2114b68b46 Mon Sep 17 00:00:00 2001 From: Mike Rosset Date: Fri, 3 Aug 2012 14:46:20 -0400 Subject: [PATCH] debug/elf: Add support for getting DynTag string table values. R=rsc CC=golang-dev https://golang.org/cl/6430064 --- src/pkg/debug/elf/file.go | 31 ++++++++++++++++++++++--------- src/pkg/debug/elf/file_test.go | 11 +++++++++++ 2 files changed, 33 insertions(+), 9 deletions(-) diff --git a/src/pkg/debug/elf/file.go b/src/pkg/debug/elf/file.go index 241430e5c65..d38da4bf8e9 100644 --- a/src/pkg/debug/elf/file.go +++ b/src/pkg/debug/elf/file.go @@ -726,6 +726,20 @@ func (f *File) gnuVersion(i int, sym *ImportedSymbol) { // referred to by the binary f that are expected to be // linked with the binary at dynamic link time. func (f *File) ImportedLibraries() ([]string, error) { + return f.DynString(DT_NEEDED) +} + +// DynString returns the strings listed for the given tag in the file's dynamic +// section. +// +// The tag must be one that takes string values: DT_NEEDED, DT_SONAME, DT_RPATH, or +// DT_RUNPATH. +func (f *File) DynString(tag DynTag) ([]string, error) { + switch tag { + case DT_NEEDED, DT_SONAME, DT_RPATH, DT_RUNPATH: + default: + return nil, fmt.Errorf("non-string-valued tag %v", tag) + } ds := f.SectionByType(SHT_DYNAMIC) if ds == nil { // not dynamic, so no libraries @@ -741,25 +755,24 @@ func (f *File) ImportedLibraries() ([]string, error) { } var all []string for len(d) > 0 { - var tag DynTag - var value uint64 + var t DynTag + var v uint64 switch f.Class { case ELFCLASS32: - tag = DynTag(f.ByteOrder.Uint32(d[0:4])) - value = uint64(f.ByteOrder.Uint32(d[4:8])) + t = DynTag(f.ByteOrder.Uint32(d[0:4])) + v = uint64(f.ByteOrder.Uint32(d[4:8])) d = d[8:] case ELFCLASS64: - tag = DynTag(f.ByteOrder.Uint64(d[0:8])) - value = f.ByteOrder.Uint64(d[8:16]) + t = DynTag(f.ByteOrder.Uint64(d[0:8])) + v = f.ByteOrder.Uint64(d[8:16]) d = d[16:] } - if tag == DT_NEEDED { - s, ok := getString(str, int(value)) + if t == tag { + s, ok := getString(str, int(v)) if ok { all = append(all, s) } } } - return all, nil } diff --git a/src/pkg/debug/elf/file_test.go b/src/pkg/debug/elf/file_test.go index 6ec5f4f62cb..12036e816b4 100644 --- a/src/pkg/debug/elf/file_test.go +++ b/src/pkg/debug/elf/file_test.go @@ -19,6 +19,7 @@ type fileTest struct { hdr FileHeader sections []SectionHeader progs []ProgHeader + needed []string } var fileTests = []fileTest{ @@ -64,6 +65,7 @@ var fileTests = []fileTest{ {PT_LOAD, PF_R + PF_W, 0x5fc, 0x80495fc, 0x80495fc, 0xd8, 0xf8, 0x1000}, {PT_DYNAMIC, PF_R + PF_W, 0x60c, 0x804960c, 0x804960c, 0x98, 0x98, 0x4}, }, + []string{"libc.so.6"}, }, { "testdata/gcc-amd64-linux-exec", @@ -117,6 +119,7 @@ var fileTests = []fileTest{ {PT_LOOS + 0x474E550, PF_R, 0x5b8, 0x4005b8, 0x4005b8, 0x24, 0x24, 0x4}, {PT_LOOS + 0x474E551, PF_R + PF_W, 0x0, 0x0, 0x0, 0x0, 0x0, 0x8}, }, + []string{"libc.so.6"}, }, } @@ -161,6 +164,14 @@ func TestOpen(t *testing.T) { if tn != fn { t.Errorf("open %s: len(Progs) = %d, want %d", tt.file, fn, tn) } + tl := tt.needed + fl, err := f.ImportedLibraries() + if err != nil { + t.Error(err) + } + if !reflect.DeepEqual(tl, fl) { + t.Errorf("open %s: DT_NEEDED = %v, want %v", tt.file, tl, fl) + } } }