]> Cypherpunks.ru repositories - gostls13.git/commitdiff
debug/elf: retrieve values for dynamic section tags
authorFlorin Papa <fpapa@google.com>
Mon, 21 Nov 2022 20:54:11 +0000 (12:54 -0800)
committerGopher Robot <gobot@golang.org>
Tue, 7 Mar 2023 18:26:40 +0000 (18:26 +0000)
Add functionality to retrieve values for .dynamic entries that don't
correspond to entries in the string table.

Fixes #56892

Change-Id: I6edabc8ca331c819e442d06e19b7f4df8343372b
Reviewed-on: https://go-review.googlesource.com/c/go/+/452617
Auto-Submit: Ian Lance Taylor <iant@google.com>
Run-TryBot: Ian Lance Taylor <iant@google.com>
Reviewed-by: Ian Lance Taylor <iant@google.com>
TryBot-Result: Gopher Robot <gobot@golang.org>

api/next/56892.txt [new file with mode: 0644]
src/debug/elf/file.go
src/debug/elf/file_test.go

diff --git a/api/next/56892.txt b/api/next/56892.txt
new file mode 100644 (file)
index 0000000..b911312
--- /dev/null
@@ -0,0 +1 @@
+pkg debug/elf, method (*File) DynValue(DynTag) ([]uint64, error) #56892
index 88b957657b85b876baff2016064f1fa15296f4e0..3ff5f9554b31dca86fd65c2d7413dbef5e7ceaa8 100644 (file)
@@ -1642,6 +1642,40 @@ func (f *File) DynString(tag DynTag) ([]string, error) {
        return all, nil
 }
 
+// DynValue returns the values listed for the given tag in the file's dynamic
+// section.
+func (f *File) DynValue(tag DynTag) ([]uint64, error) {
+       ds := f.SectionByType(SHT_DYNAMIC)
+       if ds == nil {
+               return nil, nil
+       }
+       d, err := ds.Data()
+       if err != nil {
+               return nil, err
+       }
+
+       // Parse the .dynamic section as a string of bytes.
+       var vals []uint64
+       for len(d) > 0 {
+               var t DynTag
+               var v uint64
+               switch f.Class {
+               case ELFCLASS32:
+                       t = DynTag(f.ByteOrder.Uint32(d[0:4]))
+                       v = uint64(f.ByteOrder.Uint32(d[4:8]))
+                       d = d[8:]
+               case ELFCLASS64:
+                       t = DynTag(f.ByteOrder.Uint64(d[0:8]))
+                       v = f.ByteOrder.Uint64(d[8:16])
+                       d = d[16:]
+               }
+               if t == tag {
+                       vals = append(vals, v)
+               }
+       }
+       return vals, nil
+}
+
 type nobitsSectionReader struct{}
 
 func (*nobitsSectionReader) ReadAt(p []byte, off int64) (n int, err error) {
index 282e1fccd91e3697dea3380cd1ef862da18104b8..f591f05a2ec4ff75b44a4459ce942eeb254f606a 100644 (file)
@@ -1224,3 +1224,21 @@ func TestIssue10996(t *testing.T) {
                t.Fatalf("opening invalid ELF file unexpectedly succeeded")
        }
 }
+
+func TestDynValue(t *testing.T) {
+       const testdata = "testdata/gcc-amd64-linux-exec"
+       f, err := Open(testdata)
+       if err != nil {
+               t.Fatalf("could not read %s: %v", testdata, err)
+       }
+       defer f.Close()
+
+       vals, err := f.DynValue(DT_VERNEEDNUM)
+       if err != nil {
+               t.Fatalf("DynValue(DT_VERNEEDNUM): got unexpected error %v", err)
+       }
+
+       if len(vals) != 1 || vals[0] != 1 {
+               t.Errorf("DynValue(DT_VERNEEDNUM): got %v, want [1]", vals)
+       }
+}