Skip to content

Commit

Permalink
i#7046: Add loadable segment program headers to memory dump file. (#7104
Browse files Browse the repository at this point in the history
)

Add loadable segment program headers to memory dump file. Set the entry
point address in the ELF file header based on the PC value.

Update the unit test to check loadable segment program header.

Here's the output of readelf -l using the unit test output from a X86
machine:

$ readelf -l logs/simple_app.3281609.00000000.elf

Elf file type is CORE (Core file)
Entry point 0x7fcd05936320
There are 47 program headers, starting at offset 64

Program Headers:
  Type           Offset             VirtAddr           PhysAddr
                 FileSiz            MemSiz              Flags  Align
NOTE 0x0000000000000a88 0x0000000000000000 0x0000000000000000
                 0x0000000000000378 0x0000000000000378         0x2
LOAD 0x0000000000000e00 0x00007fcac1000000 0x00007fcac1000000
                 0x0000000000040000 0x0000000000040000  RW     0x1000
LOAD 0x0000000000040e00 0x00007fcac1041000 0x00007fcac1041000
                 0x0000000000006000 0x0000000000006000  RW     0x1000
LOAD 0x0000000000046e00 0x00007fcac1049000 0x00007fcac1049000
                 0x0000000000004000 0x0000000000004000  RW     0x1000
LOAD 0x000000000004ae00 0x00007fcac1051000 0x00007fcac1051000
                 0x0000000000006000 0x0000000000006000  RW     0x1000
LOAD 0x0000000000050e00 0x00007fcac1059000 0x00007fcac1059000
                 0x0000000000018000 0x0000000000018000  RW     0x1000
LOAD 0x0000000000068e00 0x00007fcac1073000 0x00007fcac1073000
                 0x000000000000e000 0x000000000000e000  RW     0x1000
LOAD 0x0000000000076e00 0x00007fcac1083000 0x00007fcac1083000
                 0x0000000000003000 0x0000000000003000  RW     0x1000
LOAD 0x0000000000079e00 0x00007fcac1091000 0x00007fcac1091000
                 0x000000000000c000 0x000000000000c000  RW     0x1000
LOAD 0x0000000000085e00 0x00007fcac109f000 0x00007fcac109f000
                 0x0000000000001000 0x0000000000001000  RW     0x1000
LOAD 0x0000000000086e00 0x00007fcac10a2000 0x00007fcac10a2000
                 0x0000000000002000 0x0000000000002000  RW     0x1000
LOAD 0x0000000000088e00 0x00007fcac10a6000 0x00007fcac10a6000
                 0x000000000000e000 0x000000000000e000  RW     0x1000
LOAD 0x0000000000096e00 0x00007fcac10b6000 0x00007fcac10b6000
                 0x0000000000004000 0x0000000000004000  RW     0x1000
LOAD 0x000000000009ae00 0x00007fcac10be000 0x00007fcac10be000
                 0x0000000000002000 0x0000000000002000  RW     0x1000
LOAD 0x000000000009ce00 0x00007fcac10c3000 0x00007fcac10c3000
                 0x0000000000001000 0x0000000000001000  RW     0x1000
LOAD 0x000000000009de00 0x00007fcac10c8000 0x00007fcac10c8000
                 0x0000000000008000 0x0000000000008000  RW     0x1000
LOAD 0x00000000000a5e00 0x00007fcac10d2000 0x00007fcac10d2000
                 0x0000000000018000 0x0000000000018000  RW     0x1000
LOAD 0x00000000000bde00 0x00007fccc1200000 0x00007fccc1200000
                 0x0000000000008000 0x0000000000008000  RW     0x1000
LOAD 0x00000000000c5e00 0x00007fccc1208000 0x00007fccc1208000
                 0x0000000000001000 0x0000000000001000  R      0x1000
LOAD 0x00000000000c6e00 0x00007fccc1209000 0x00007fccc1209000
                 0x0000000000001000 0x0000000000001000  R E    0x1000
LOAD 0x00000000000c7e00 0x00007fccc120a000 0x00007fccc120a000
                 0x0000000000001000 0x0000000000001000  R      0x1000
LOAD 0x00000000000c8e00 0x00007fccc120b000 0x00007fccc120b000
                 0x0000000000002000 0x0000000000002000  RW     0x1000
LOAD 0x00000000000cae00 0x00007fccc120f000 0x00007fccc120f000
                 0x0000000000001000 0x0000000000001000  RW     0x1000
LOAD 0x00000000000cbe00 0x00007fccc1217000 0x00007fccc1217000
                 0x0000000000001000 0x0000000000001000  RWE    0x1000
LOAD 0x00000000000cce00 0x00007fccc1218000 0x00007fccc1218000
                 0x0000000000002000 0x0000000000002000  R E    0x1000
LOAD 0x00000000000cee00 0x00007fccc121a000 0x00007fccc121a000
                 0x0000000000001000 0x0000000000001000  RWE    0x1000
LOAD 0x00000000000cfe00 0x00007fccc121e000 0x00007fccc121e000
                 0x0000000000001000 0x0000000000001000  RWE    0x1000
LOAD 0x00000000000d0e00 0x00007fccc122e000 0x00007fccc122e000
                 0x0000000000001000 0x0000000000001000  RWE    0x1000
LOAD 0x00000000000d1e00 0x00007fccc123e000 0x00007fccc123e000
                 0x0000000000001000 0x0000000000001000  RWE    0x1000
LOAD 0x00000000000d2e00 0x00007fccc1241000 0x00007fccc1241000
                 0x0000000000001000 0x0000000000001000  RWE    0x1000
LOAD 0x00000000000d3e00 0x00007fccc1244000 0x00007fccc1244000
                 0x0000000000001000 0x0000000000001000  RW     0x1000
LOAD 0x00000000000d4e00 0x00007fcd01200000 0x00007fcd01200000
                 0x0000000000001000 0x0000000000001000  R      0x1000
LOAD 0x00000000000d5e00 0x00007fcd01201000 0x00007fcd01201000
                 0x0000000000002000 0x0000000000002000  R E    0x1000
LOAD 0x00000000000d7e00 0x00007fcd01203000 0x00007fcd01203000
                 0x0000000000001000 0x0000000000001000  R      0x1000
LOAD 0x00000000000d8e00 0x00007fcd01204000 0x00007fcd01204000
                 0x0000000000002000 0x0000000000002000  RW     0x1000
LOAD 0x00000000000dae00 0x00007fcd01207000 0x00007fcd01207000
                 0x0000000000400000 0x0000000000400000  RW     0x1000
LOAD 0x00000000004dae00 0x00007fcd05400000 0x00007fcd05400000
                 0x000000000004e000 0x000000000004e000  R      0x1000
LOAD 0x0000000000528e00 0x00007fcd0544e000 0x00007fcd0544e000
                 0x00000000002e9000 0x00000000002e9000  R E    0x1000
LOAD 0x0000000000811e00 0x00007fcd05737000 0x00007fcd05737000
                 0x00000000000cb000 0x00000000000cb000  R      0x1000
LOAD 0x00000000008dce00 0x00007fcd05802000 0x00007fcd05802000
                 0x000000000007f000 0x000000000007f000  RW     0x1000
LOAD 0x000000000095be00 0x00007fcd05881000 0x00007fcd05881000
                 0x0000000000039000 0x0000000000039000  RW     0x1000
LOAD 0x0000000000994e00 0x00007fcd0591b000 0x00007fcd0591b000
                 0x0000000000001000 0x0000000000001000  R      0x1000
LOAD 0x0000000000995e00 0x00007fcd0591c000 0x00007fcd0591c000
                 0x0000000000026000 0x0000000000026000  R E    0x1000
LOAD 0x00000000009bbe00 0x00007fcd05942000 0x00007fcd05942000
                 0x000000000000b000 0x000000000000b000  R      0x1000
LOAD 0x00000000009c6e00 0x00007fcd0594d000 0x00007fcd0594d000
                 0x0000000000004000 0x0000000000004000  RW     0x1000
LOAD 0x00000000009cae00 0x00007fcd0595b000 0x00007fcd0595b000
                 0x0000000000002000 0x0000000000002000  R E    0x1000
LOAD 0x00000000009cce00 0x00007ffe60f10000 0x00007ffe60f10000
                 0x0000000000022000 0x0000000000022000  RW     0x1000

 Section to Segment mapping:
  Segment Sections...
   00     
   01     
   02      
   03      
   04      
   05      
   06      
   07      
   08      
   09      
   10      
   11      
   12      
   13      
   14      
   15      
   16      
   17      
18
/usr/local/google/home/kyluk/trace2checkpoint/dynamorio/build/suite/tests/bin/libclient.memory_dump_test.dll.so
19
/usr/local/google/home/kyluk/trace2checkpoint/dynamorio/build/suite/tests/bin/libclient.memory_dump_test.dll.so
20
/usr/local/google/home/kyluk/trace2checkpoint/dynamorio/build/suite/tests/bin/libclient.memory_dump_test.dll.so
21
/usr/local/google/home/kyluk/trace2checkpoint/dynamorio/build/suite/tests/bin/libclient.memory_dump_test.dll.so
   22      
   23      
   24      
   25      
   26      
   27      
   28      
   29      
   30      
31
/usr/local/google/home/kyluk/trace2checkpoint/dynamorio/build/suite/tests/bin/simple_app
32
/usr/local/google/home/kyluk/trace2checkpoint/dynamorio/build/suite/tests/bin/simple_app
33
/usr/local/google/home/kyluk/trace2checkpoint/dynamorio/build/suite/tests/bin/simple_app
34
/usr/local/google/home/kyluk/trace2checkpoint/dynamorio/build/suite/tests/bin/simple_app
   35      
36
/usr/local/google/home/kyluk/trace2checkpoint/dynamorio/build/lib64/debug/libdynamorio.so
37
/usr/local/google/home/kyluk/trace2checkpoint/dynamorio/build/lib64/debug/libdynamorio.so
38
/usr/local/google/home/kyluk/trace2checkpoint/dynamorio/build/lib64/debug/libdynamorio.so
39
/usr/local/google/home/kyluk/trace2checkpoint/dynamorio/build/lib64/debug/libdynamorio.so
   40      
   41     /usr/lib/x86_64-linux-gnu/ld-linux-x86-64.so.2 
   42     /usr/lib/x86_64-linux-gnu/ld-linux-x86-64.so.2 
   43     /usr/lib/x86_64-linux-gnu/ld-linux-x86-64.so.2 
   44     /usr/lib/x86_64-linux-gnu/ld-linux-x86-64.so.2 
   45     [vdso] 
   46     [stack] 


Issue: #7046
  • Loading branch information
ivankyluk authored Dec 5, 2024
1 parent 100cac0 commit 6002bb8
Show file tree
Hide file tree
Showing 2 changed files with 61 additions and 12 deletions.
68 changes: 58 additions & 10 deletions core/unix/coredump.c
Original file line number Diff line number Diff line change
Expand Up @@ -71,8 +71,6 @@
#define PROGRAM_HEADER_NOTE_LENGTH \
(sizeof(ELF_NOTE_HEADER_TYPE) + NOTE_OWNER_LENGTH + sizeof(struct elf_prstatus) + \
sizeof(ELF_NOTE_HEADER_TYPE) + NOTE_OWNER_LENGTH + sizeof(elf_fpregset_t))
#define PROGRAM_HEADER_LENGTH \
(sizeof(ELF_PROGRAM_HEADER_TYPE) + PROGRAM_HEADER_NOTE_LENGTH)

typedef struct _section_header_info_t {
app_pc vm_start;
Expand Down Expand Up @@ -478,27 +476,73 @@ os_dump_core_internal(dcontext_t *dcontext)
SYSLOG_INTERNAL_ERROR("Unable to open the core dump file.");
return false;
}

if (!write_elf_header(elf_file, /*entry_point=*/0,
// We use two types of program headers. NOTE is used to store prstatus
// structure and floating point registers. LOAD is used to specify loadable
// segments. All but one section (shstrtab which stores section names)
// require a corresponding LOAD program header. The total number of
// program headers equals the number of NOTE program header (1) and the number
// of LOAD program header (number of sections minus one since shstrtab does not
// require a LOAD header).
const ELF_OFF program_header_count = section_count;
if (!write_elf_header(elf_file, /*entry_point=*/(uint64_t)mc.pc,
/*section_header_table_offset*/ sizeof(ELF_HEADER_TYPE) +
PROGRAM_HEADER_LENGTH + section_data_size,
PROGRAM_HEADER_NOTE_LENGTH +
sizeof(ELF_PROGRAM_HEADER_TYPE) * program_header_count +
section_data_size,
/*flags=*/0,
/*program_header_count=*/1,
/*program_header_count=*/program_header_count,
/*section_header_count=*/section_count,
/*section_string_table_index=*/section_count - 1)) {
os_close(elf_file);
return false;
}
// Write program header table entry.
if (!write_program_header(elf_file, PT_NOTE, /*flags=*/0,
/*offset=*/sizeof(ELF_HEADER_TYPE) +
sizeof(ELF_PROGRAM_HEADER_TYPE),
sizeof(ELF_PROGRAM_HEADER_TYPE) * program_header_count,
/*virtual_address=*/0,
/*physical_address=*/0,
/*file_size=*/PROGRAM_HEADER_NOTE_LENGTH,
/*memory_size=*/0, /*alignment=*/4)) {
/*memory_size=*/PROGRAM_HEADER_NOTE_LENGTH,
/*alignment=*/sizeof(ELF_HALF))) {
os_close(elf_file);
return false;
}
// Write loadable program segment program headers.
ELF_OFF file_offset = sizeof(ELF_HEADER_TYPE) +
sizeof(ELF_PROGRAM_HEADER_TYPE) * program_header_count +
PROGRAM_HEADER_NOTE_LENGTH;
// TODO i#7046: Merge adjacent sections with the same prot values.
// The last section is shstrtab which stores the section names and it does
// not require a LOAD program header.
for (int section_index = 0; section_index < section_count - 1; ++section_index) {
ELF_WORD flags = 0;
if (TEST(PROT_EXEC, section_header_info[section_index].prot)) {
flags |= PF_X;
}
if (TEST(PROT_WRITE, section_header_info[section_index].prot)) {
flags |= PF_W;
}
if (TEST(PROT_READ, section_header_info[section_index].prot)) {
flags |= PF_R;
}
const ELF_WORD size = section_header_info[section_index].vm_end -
section_header_info[section_index].vm_start;
if (!write_program_header(
elf_file, PT_LOAD, flags,
/*offset=*/file_offset,
/*virtual_address=*/(ELF_ADDR)section_header_info[section_index].vm_start,
/*physical_address=*/
(ELF_ADDR)section_header_info[section_index].vm_start,
/*file_size=*/size,
/*memory_size=*/size,
/*alignment=*/os_page_size())) {
os_close(elf_file);
return false;
}
file_offset += section_header_info[section_index].vm_end -
section_header_info[section_index].vm_start;
}
if (!write_prstatus_note(&mc, elf_file)) {
os_close(elf_file);
return false;
Expand Down Expand Up @@ -533,8 +577,9 @@ os_dump_core_internal(dcontext_t *dcontext)
return false;
}
// Write section headers to the core dump file.
// TODO i#7046: Handle multiple program headers.
ELF_OFF file_offset = sizeof(ELF_HEADER_TYPE) + PROGRAM_HEADER_LENGTH;
file_offset = sizeof(ELF_HEADER_TYPE) +
sizeof(ELF_PROGRAM_HEADER_TYPE) * program_header_count +
PROGRAM_HEADER_NOTE_LENGTH;

// The section_count includes the section name section, so we need to skip
// it in the loop. The section name section is handled differently after
Expand All @@ -544,6 +589,9 @@ os_dump_core_internal(dcontext_t *dcontext)
if (TEST(PROT_WRITE, section_header_info[section_index].prot)) {
flags |= SHF_WRITE;
}
if (TEST(PROT_EXEC, section_header_info[section_index].prot)) {
flags |= SHF_EXECINSTR;
}
if (!write_section_header(
elf_file, section_header_info[section_index].name_offset, SHT_PROGBITS,
flags, (ELF_ADDR)section_header_info[section_index].vm_start, file_offset,
Expand Down
5 changes: 3 additions & 2 deletions suite/tests/client-interface/memory_dump_test.templatex
Original file line number Diff line number Diff line change
Expand Up @@ -14,13 +14,13 @@ ELF Header:
Type: CORE \(Core file\)
Machine: .*
Version: 0x1
Entry point address: 0x0
Entry point address: 0x[0-9a-f]+
Start of program headers: 64 \(bytes into file\)
Start of section headers: [0-9]+ \(bytes into file\)
Flags: 0x0
Size of this header: 64 \(bytes\)
Size of program headers: 56 \(bytes\)
Number of program headers: 1
Number of program headers: [0-9]+
Size of section headers: 64 \(bytes\)
Number of section headers: [0-9]+
Section header string table index: [0-9]+
Expand All @@ -33,6 +33,7 @@ Program Headers:
Type Offset VirtAddr PhysAddr
FileSiz MemSiz Flags Align
NOTE.*
LOAD.*
.*
Displaying notes found at file offset 0x[0-9a-f]+ with length 0x[0-9a-f]+:
Owner.*Data size.*Description
Expand Down

0 comments on commit 6002bb8

Please sign in to comment.