Commit 7e9d9eb1 authored by Dave Cheney's avatar Dave Cheney

debug/elf: handle missing shstrndx in core files

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
parent 2d3bdab0
...@@ -272,7 +272,8 @@ func NewFile(r io.ReaderAt) (*File, error) { ...@@ -272,7 +272,8 @@ func NewFile(r io.ReaderAt) (*File, error) {
shnum = int(hdr.Shnum) shnum = int(hdr.Shnum)
shstrndx = int(hdr.Shstrndx) 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} return nil, &FormatError{0, "invalid ELF shstrndx", shstrndx}
} }
...@@ -367,6 +368,10 @@ func NewFile(r io.ReaderAt) (*File, error) { ...@@ -367,6 +368,10 @@ func NewFile(r io.ReaderAt) (*File, error) {
f.Sections[i] = s f.Sections[i] = s
} }
if len(f.Sections) == 0 {
return f, nil
}
// Load section header string table. // Load section header string table.
shstrtab, err := f.Sections[shstrndx].Data() shstrtab, err := f.Sections[shstrndx].Data()
if err != nil { if err != nil {
......
...@@ -5,10 +5,14 @@ ...@@ -5,10 +5,14 @@
package elf package elf
import ( import (
"bytes"
"compress/gzip"
"debug/dwarf" "debug/dwarf"
"encoding/binary" "encoding/binary"
"io"
"net" "net"
"os" "os"
"path"
"reflect" "reflect"
"runtime" "runtime"
"testing" "testing"
...@@ -121,15 +125,49 @@ var fileTests = []fileTest{ ...@@ -121,15 +125,49 @@ var fileTests = []fileTest{
}, },
[]string{"libc.so.6"}, []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) { func TestOpen(t *testing.T) {
for i := range fileTests { for i := range fileTests {
tt := &fileTests[i] 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 { if err != nil {
t.Error(err) t.Errorf("cannot open file %s: %v", tt.file, err)
continue continue
} }
if !reflect.DeepEqual(f.FileHeader, tt.hdr) { if !reflect.DeepEqual(f.FileHeader, tt.hdr) {
...@@ -175,6 +213,23 @@ func TestOpen(t *testing.T) { ...@@ -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 { type relocationTestEntry struct {
entryNumber int entryNumber int
entry *dwarf.Entry entry *dwarf.Entry
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment