]> Cypherpunks repositories - gostls13.git/commitdiff
debug/elf: handle missing shstrndx in core files
authorDave Cheney <dave@cheney.net>
Mon, 17 Dec 2012 20:58:22 +0000 (07:58 +1100)
committerDave Cheney <dave@cheney.net>
Mon, 17 Dec 2012 20:58:22 +0000 (07:58 +1100)
Fixes #4481.

hello-world-core.gz was generated with a simple hello world c program and core dumped as suggested in the issue.

Also: add support for gz compressed test fixtures.

R=minux.ma, rsc, iant
CC=golang-dev
https://golang.org/cl/6936058

src/pkg/debug/elf/file.go
src/pkg/debug/elf/file_test.go
src/pkg/debug/elf/testdata/hello-world-core.gz [new file with mode: 0644]

index b030b043dfc1204828f1d04dc1ae35ca1a58ece6..acb9817af024432e9af1da25ef20abd4b9401847 100644 (file)
@@ -272,7 +272,8 @@ func NewFile(r io.ReaderAt) (*File, error) {
                shnum = int(hdr.Shnum)
                shstrndx = int(hdr.Shstrndx)
        }
-       if shstrndx < 0 || shstrndx >= shnum {
+
+       if shnum > 0 && shoff > 0 && (shstrndx < 0 || shstrndx >= shnum) {
                return nil, &FormatError{0, "invalid ELF shstrndx", shstrndx}
        }
 
@@ -367,6 +368,10 @@ func NewFile(r io.ReaderAt) (*File, error) {
                f.Sections[i] = s
        }
 
+       if len(f.Sections) == 0 {
+               return f, nil
+       }
+
        // Load section header string table.
        shstrtab, err := f.Sections[shstrndx].Data()
        if err != nil {
index 810a2f9b9a36d5f932f01d0a6c46143c4beaa80f..f9aa7265af09f9cd8d81f83df933e1aeb7fb6f18 100644 (file)
@@ -5,10 +5,14 @@
 package elf
 
 import (
+       "bytes"
+       "compress/gzip"
        "debug/dwarf"
        "encoding/binary"
+       "io"
        "net"
        "os"
+       "path"
        "reflect"
        "runtime"
        "testing"
@@ -121,15 +125,49 @@ var fileTests = []fileTest{
                },
                []string{"libc.so.6"},
        },
+       {
+               "testdata/hello-world-core.gz",
+               FileHeader{ELFCLASS64, ELFDATA2LSB, EV_CURRENT, ELFOSABI_NONE, 0x0, binary.LittleEndian, ET_CORE, EM_X86_64, 0x0},
+               []SectionHeader{},
+               []ProgHeader{
+                       {Type: PT_NOTE, Flags: 0x0, Off: 0x3f8, Vaddr: 0x0, Paddr: 0x0, Filesz: 0x8ac, Memsz: 0x0, Align: 0x0},
+                       {Type: PT_LOAD, Flags: PF_X + PF_R, Off: 0x1000, Vaddr: 0x400000, Paddr: 0x0, Filesz: 0x0, Memsz: 0x1000, Align: 0x1000},
+                       {Type: PT_LOAD, Flags: PF_R, Off: 0x1000, Vaddr: 0x401000, Paddr: 0x0, Filesz: 0x1000, Memsz: 0x1000, Align: 0x1000},
+                       {Type: PT_LOAD, Flags: PF_W + PF_R, Off: 0x2000, Vaddr: 0x402000, Paddr: 0x0, Filesz: 0x1000, Memsz: 0x1000, Align: 0x1000},
+                       {Type: PT_LOAD, Flags: PF_X + PF_R, Off: 0x3000, Vaddr: 0x7f54078b8000, Paddr: 0x0, Filesz: 0x0, Memsz: 0x1b5000, Align: 0x1000},
+                       {Type: PT_LOAD, Flags: 0x0, Off: 0x3000, Vaddr: 0x7f5407a6d000, Paddr: 0x0, Filesz: 0x0, Memsz: 0x1ff000, Align: 0x1000},
+                       {Type: PT_LOAD, Flags: PF_R, Off: 0x3000, Vaddr: 0x7f5407c6c000, Paddr: 0x0, Filesz: 0x4000, Memsz: 0x4000, Align: 0x1000},
+                       {Type: PT_LOAD, Flags: PF_W + PF_R, Off: 0x7000, Vaddr: 0x7f5407c70000, Paddr: 0x0, Filesz: 0x2000, Memsz: 0x2000, Align: 0x1000},
+                       {Type: PT_LOAD, Flags: PF_W + PF_R, Off: 0x9000, Vaddr: 0x7f5407c72000, Paddr: 0x0, Filesz: 0x5000, Memsz: 0x5000, Align: 0x1000},
+                       {Type: PT_LOAD, Flags: PF_X + PF_R, Off: 0xe000, Vaddr: 0x7f5407c77000, Paddr: 0x0, Filesz: 0x0, Memsz: 0x22000, Align: 0x1000},
+                       {Type: PT_LOAD, Flags: PF_W + PF_R, Off: 0xe000, Vaddr: 0x7f5407e81000, Paddr: 0x0, Filesz: 0x3000, Memsz: 0x3000, Align: 0x1000},
+                       {Type: PT_LOAD, Flags: PF_W + PF_R, Off: 0x11000, Vaddr: 0x7f5407e96000, Paddr: 0x0, Filesz: 0x3000, Memsz: 0x3000, Align: 0x1000},
+                       {Type: PT_LOAD, Flags: PF_R, Off: 0x14000, Vaddr: 0x7f5407e99000, Paddr: 0x0, Filesz: 0x1000, Memsz: 0x1000, Align: 0x1000},
+                       {Type: PT_LOAD, Flags: PF_W + PF_R, Off: 0x15000, Vaddr: 0x7f5407e9a000, Paddr: 0x0, Filesz: 0x2000, Memsz: 0x2000, Align: 0x1000},
+                       {Type: PT_LOAD, Flags: PF_W + PF_R, Off: 0x17000, Vaddr: 0x7fff79972000, Paddr: 0x0, Filesz: 0x23000, Memsz: 0x23000, Align: 0x1000},
+                       {Type: PT_LOAD, Flags: PF_X + PF_R, Off: 0x3a000, Vaddr: 0x7fff799f8000, Paddr: 0x0, Filesz: 0x1000, Memsz: 0x1000, Align: 0x1000},
+                       {Type: PT_LOAD, Flags: PF_X + PF_R, Off: 0x3b000, Vaddr: 0xffffffffff600000, Paddr: 0x0, Filesz: 0x1000, Memsz: 0x1000, Align: 0x1000},
+               },
+               nil,
+       },
 }
 
 func TestOpen(t *testing.T) {
        for i := range fileTests {
                tt := &fileTests[i]
 
-               f, err := Open(tt.file)
+               var f *File
+               var err error
+               if path.Ext(tt.file) == ".gz" {
+                       var r io.ReaderAt
+                       if r, err = decompress(tt.file); err == nil {
+                               f, err = NewFile(r)
+                       }
+               } else {
+                       f, err = Open(tt.file)
+               }
                if err != nil {
-                       t.Error(err)
+                       t.Errorf("cannot open file %s: %v", tt.file, err)
                        continue
                }
                if !reflect.DeepEqual(f.FileHeader, tt.hdr) {
@@ -175,6 +213,23 @@ func TestOpen(t *testing.T) {
        }
 }
 
+// elf.NewFile requires io.ReaderAt, which compress/gzip cannot
+// provide. Decompress the file to a bytes.Reader.
+func decompress(gz string) (io.ReaderAt, error) {
+       in, err := os.Open(gz)
+       if err != nil {
+               return nil, err
+       }
+       defer in.Close()
+       r, err := gzip.NewReader(in)
+       if err != nil {
+               return nil, err
+       }
+       var out bytes.Buffer
+       _, err = io.Copy(&out, r)
+       return bytes.NewReader(out.Bytes()), err
+}
+
 type relocationTestEntry struct {
        entryNumber int
        entry       *dwarf.Entry
diff --git a/src/pkg/debug/elf/testdata/hello-world-core.gz b/src/pkg/debug/elf/testdata/hello-world-core.gz
new file mode 100644 (file)
index 0000000..806af6e
Binary files /dev/null and b/src/pkg/debug/elf/testdata/hello-world-core.gz differ