diff --git a/pkg/proc/core/linux_amd64_core.go b/pkg/proc/core/linux_amd64_core.go index b1eca1ef..e2f3257d 100644 --- a/pkg/proc/core/linux_amd64_core.go +++ b/pkg/proc/core/linux_amd64_core.go @@ -256,16 +256,23 @@ func readCore(corePath, exePath string) (*Core, error) { if err != nil { return nil, err } + exeELF, err := elf.NewFile(exe) + if err != nil { + return nil, err + } if coreFile.Type != elf.ET_CORE { return nil, fmt.Errorf("%v is not a core file", coreFile) } + if exeELF.Type != elf.ET_EXEC { + return nil, fmt.Errorf("%v is not an exe file", exeELF) + } notes, err := readNotes(coreFile) if err != nil { return nil, err } - memory := buildMemory(coreFile, exe, notes) + memory := buildMemory(coreFile, exeELF, exe, notes) core := &Core{ MemoryReader: memory, @@ -417,7 +424,7 @@ func skipPadding(r io.ReadSeeker, pad int64) error { return nil } -func buildMemory(core *elf.File, exe io.ReaderAt, notes []*Note) proc.MemoryReader { +func buildMemory(core, exeELF *elf.File, exe io.ReaderAt, notes []*Note) proc.MemoryReader { memory := &SplicedMemory{} // For now, assume all file mappings are to the exe. @@ -434,16 +441,21 @@ func buildMemory(core *elf.File, exe io.ReaderAt, notes []*Note) proc.MemoryRead } } - for _, prog := range core.Progs { - if prog.Type == elf.PT_LOAD { - if prog.Filesz == 0 { - continue + + // Load memory segments from exe and then from the core file, + // allowing the corefile to overwrite previously loaded segments + for _, elfFile := range []*elf.File{exeELF, core} { + for _, prog := range elfFile.Progs { + if prog.Type == elf.PT_LOAD { + if prog.Filesz == 0 { + continue + } + r := &OffsetReaderAt{ + reader: prog.ReaderAt, + offset: uintptr(prog.Vaddr), + } + memory.Add(r, uintptr(prog.Vaddr), uintptr(prog.Filesz)) } - r := &OffsetReaderAt{ - reader: prog.ReaderAt, - offset: uintptr(prog.Vaddr), - } - memory.Add(r, uintptr(prog.Vaddr), uintptr(prog.Filesz)) } } return memory