in internal/core/process.go [262:331]
func (p *Process) readCore(core *os.File) error {
e, err := elf.NewFile(core)
if err != nil {
return err
}
if e.Type != elf.ET_CORE {
return fmt.Errorf("%s is not a core file", core.Name())
}
switch e.Class {
case elf.ELFCLASS32:
p.ptrSize = 4
p.logPtrSize = 2
case elf.ELFCLASS64:
p.ptrSize = 8
p.logPtrSize = 3
default:
return fmt.Errorf("unknown elf class %s\n", e.Class)
}
switch e.Machine {
case elf.EM_386:
p.arch = "386"
case elf.EM_X86_64:
p.arch = "amd64"
// TODO: detect amd64p32?
case elf.EM_ARM:
p.arch = "arm"
case elf.EM_AARCH64:
p.arch = "arm64"
case elf.EM_MIPS:
p.arch = "mips"
case elf.EM_MIPS_RS3_LE:
p.arch = "mipsle"
// TODO: value for mips64?
case elf.EM_PPC64:
if e.ByteOrder.String() == "LittleEndian" {
p.arch = "ppc64le"
} else {
p.arch = "ppc64"
}
case elf.EM_S390:
p.arch = "s390x"
default:
return fmt.Errorf("unknown arch %s\n", e.Machine)
}
p.byteOrder = e.ByteOrder
// We also compute explicitly what byte order the inferior is.
// Just using p.byteOrder to decode fields makes any arguments passed to it
// escape to the heap. We use explicit binary.{Little,Big}Endian.UintXX
// calls when we want to avoid heap-allocating the buffer.
p.littleEndian = e.ByteOrder.String() == "LittleEndian"
// Load virtual memory mappings.
for _, prog := range e.Progs {
if prog.Type == elf.PT_LOAD {
if err := p.readLoad(core, e, prog); err != nil {
return err
}
}
}
// Load notes (includes file mapping information).
for _, prog := range e.Progs {
if prog.Type == elf.PT_NOTE {
if err := p.readNote(core, e, prog.Off, prog.Filesz); err != nil {
return err
}
}
}
return nil
}