Following my question about manually generating a core dump file, I decided to dive into it and get my hands dirty.
I am able to build the basic core dump structure and get my dead program's memory back into the core dump within a big LOAD section. When debugging in GDB, my variables are back, no problem with that. Here comes the tricky part, how do I get GDB to retrieve information about where the program was when it crashed.
I know that the note section of the core dump contains this information (cpu registers among others). Here is what a objdump -h gives for a "real" core dump :
core.28339: file format elf32-i386 Sections: Idx Name Size VMA LMA File off Algn 0 note0 000001e8 00000000 00000000 000000f4 2**0 CONTENTS, READONLY 1 .reg/28339 00000044 00000000 00000000 00000150 2**2 CONTENTS 2 .reg 00000044 00000000 00000000 00000150 2**2 CONTENTS 3 .auxv 000000a0 00000000 00000000 0000023c 2**2 CONTENTS 4 load1a 00001000 08010000 00000000 00001000 2**12 CONTENTS, ALLOC, LOAD, READONLY, CODE .. other load sections ...
I figured out thanks to readelf that those .reg sections contain data mapped from some structures :
Notes at offset 0x000000f4 with length 0x000001e8: Owner Data size Description CORE 0x00000090 NT_PRSTATUS (prstatus structure) CORE 0x0000007c NT_PRPSINFO (prpsinfo structure) CORE 0x000000a0 NT_AUXV (auxiliary vector)
Can someone give me directions on how is structured the Notes section ? I tried writing directly those structures to my file, it did not work and I am obviously missing something here. I looked at the Google Coredumper code and took some bits of it, but writing the note section is not that simple and any detailed information about what it exactly contains and its format are welcomed.
Edit #1 : following 1st comment
I figured out my Elf file should be structured as follows :
Then i will have to put 3 note records, one for the prstatus, one for prpsinfo and one for the auxiliary vector.
This seems to be the right way as readelf gives me a similar output as what I got above with the real core dump.
Edit #2 : after getting the correct structure
I am now struggling with the different structures composing the note records.
Here is what I get when running a eu-readelf --notes on my core dump :
Note segment of 540 bytes at offset 0x74: Owner Data size Type CORE 336 PRSTATUS CORE 136 PRPSINFO CORE 8 AUXV NULL
Here is what I get when running the same command on the real core dump :
Note segment of 488 bytes at offset 0xf4: Owner Data size Type CORE 144 PRSTATUS info.si_signo: 11, info.si_code: 0, info.si_errno: 0, cursig: 11 sigpend: <> sighold: <> pid: 28339, ppid: 41446, pgrp: 28339, sid: 41446 utime: 0.000000, stime: 0.000000, cutime: 0.000000, cstime: 0.000000 orig_eax: -1, fpvalid: 0 ebx: -1 ecx: 0 edx: 0 esi: 0 edi: 0 ebp: 0xffb9fcbc eax: -1 eip: 0x08014b26 eflags: 0x00010286 esp: 0xffb9fcb4 ds: 0x002b es: 0x002b fs: 0x0000 gs: 0x0000 cs: 0x0023 ss: 0x002b CORE 124 PRPSINFO state: 0, sname: R, zomb: 0, nice: 0, flag: 0x00400400 uid: 9432, gid: 6246, pid: 28339, ppid: 41446, pgrp: 28339, sid: 41446 fname: pikeos_app, psargs: ./pikeos_app CORE 160 AUXV SYSINFO: 0xf7768420 SYSINFO_EHDR: 0xf7768000 HWCAP: 0xbfebfbff <fpu vme de pse tsc msr pae mce cx8 apic sep mtrr pge mca cmov pat pse36 clflush dts acpi mmx fxsr sse sse2 ss ht tm pbe> PAGESZ: 4096 CLKTCK: 100 PHDR: 0x8010034 PHENT: 32 PHNUM: 2 BASE: 0 FLAGS: 0 ENTRY: 0x80100be UID: 9432 EUID: 9432 GID: 6246 EGID: 6246 SECURE: 0 RANDOM: 0xffb9ffab EXECFN: 0xffba1feb PLATFORM: 0xffb9ffbb NULL
Does someone have any clue or explanations about why my note records are not read properly ? I thought it might be due to incorrect offsets, but then why would the records be correctly listed ?
Was having same troubles some time ago with my project of converting CRIU images into core dumps. It is fully written in python(even elf structures are in ctypes), so it could be used as a guide. See https://github.com/efiop/criu-coredump .I.e. how everything is structured could be seen here https://github.com/efiop/criu-coredump/blob/master/criu_coredump/core_dump.py .
Can someone give me directions on how is structured the Notes section?
The notes section is a concatenation of variable-sized note records. Each note record begins with
ElfW(Nhdr) structure, followed by (variable sized) name (of length
.n_namesz, padded so total size of name on disk is divisible by 4) and data (of length
.n_descsz, similarly padded).
After some tests I figured things out, answering for anyone looking for this information :
Can someone confirm I am going the right way structuring my Elf file this way ?
As GDB is accepting the file, this seems to be the right way of doing. Results shown by readelf -a show the correct structure, good so far.
I am not sure about where should lay the data (note & program sections) into my file : is there a mandatory order, or is this my program headers offset that define where the data is ?
Offsets given to
Phdr.p_offset should point where the data lays in the Elf file. They start at the very beginning of the file.
For example :
The p_offset for the
PT_NOTE program header should be set at
sizeof(ElfW(Ehdr)) + ehdr.e_phnum*sizeof(ElfW(Phdr)).
ehdr.e_phnum being the number of program header present in the Elf file.
PT_LOAD program header, this is a bit longer, cause we will also have to add length of all the note sections. For a "standard" core dump with a note segment containg
NT_AUXV sections, offset for the PT_LOAD data (
Phdr.p_offset) will be :
sizeof(ElfW(Ehdr)) + ehdr.e_phnum*sizeof(ElfW(Phdr)) + sizeof(ElfW(Nhdr)) + sizeof(name_of_section) + sizeof(struct prstatus) + sizeof(ElfW(Nhdr)) + sizeof(name_of_section) + sizeof(struct prpsinfo) + sizeof(ElfW(Nhdr)) + sizeof(name_of_section) + sizeof(struct auxv_t)
User contributions licensed under CC BY-SA 3.0