Skip to content

Commit

Permalink
Merge branch 'master' into iX-evex-vaes-vpclmulqdq
Browse files Browse the repository at this point in the history
  • Loading branch information
khuey authored Dec 18, 2024
2 parents b6c158e + 291ec3d commit 53ce419
Showing 1 changed file with 37 additions and 12 deletions.
49 changes: 37 additions & 12 deletions core/unix/coredump.c
Original file line number Diff line number Diff line change
Expand Up @@ -51,6 +51,7 @@
# error Unsupported architecture
#endif

#define MAX_BUFFER_SIZE 4096
#define MAX_SECTION_HEADERS 300
#define MAX_SECTION_NAME_BUFFER_SIZE 8192
#define SECTION_HEADER_TABLE ".shstrtab"
Expand Down Expand Up @@ -484,11 +485,23 @@ os_dump_core_internal(dcontext_t *dcontext)
// 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;
// core_file_offset is the current offset of the core file to write the next
// section data.
ELF_OFF core_file_offset = sizeof(ELF_HEADER_TYPE) +
sizeof(ELF_PROGRAM_HEADER_TYPE) * program_header_count +
PROGRAM_HEADER_NOTE_LENGTH;
// We add padding to the core file so that loadable segments in the
// core file are page size aligned. The p_align field in the program header
// is applied to both memory and the offset to the core file.
const size_t loadable_segment_padding =
ALIGN_FORWARD(core_file_offset, os_page_size()) - core_file_offset;
core_file_offset = ALIGN_FORWARD(core_file_offset, os_page_size());

if (!write_elf_header(elf_file, /*entry_point=*/(uint64_t)mc.pc,
/*section_header_table_offset*/ sizeof(ELF_HEADER_TYPE) +
/*section_header_table_offset=*/sizeof(ELF_HEADER_TYPE) +
PROGRAM_HEADER_NOTE_LENGTH +
sizeof(ELF_PROGRAM_HEADER_TYPE) * program_header_count +
section_data_size,
loadable_segment_padding + section_data_size,
/*flags=*/0,
/*program_header_count=*/program_header_count,
/*section_header_count=*/section_count,
Expand All @@ -509,9 +522,6 @@ os_dump_core_internal(dcontext_t *dcontext)
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.
Expand All @@ -530,7 +540,7 @@ os_dump_core_internal(dcontext_t *dcontext)
section_header_info[section_index].vm_start;
if (!write_program_header(
elf_file, PT_LOAD, flags,
/*offset=*/file_offset,
/*offset=*/core_file_offset,
/*virtual_address=*/(ELF_ADDR)section_header_info[section_index].vm_start,
/*physical_address=*/
(ELF_ADDR)section_header_info[section_index].vm_start,
Expand All @@ -540,7 +550,7 @@ os_dump_core_internal(dcontext_t *dcontext)
os_close(elf_file);
return false;
}
file_offset += section_header_info[section_index].vm_end -
core_file_offset += section_header_info[section_index].vm_end -
section_header_info[section_index].vm_start;
}
if (!write_prstatus_note(&mc, elf_file)) {
Expand All @@ -551,6 +561,20 @@ os_dump_core_internal(dcontext_t *dcontext)
os_close(elf_file);
return false;
}
// Add padding to the core file such that loadable segments are aligned to
// the page size in the core file.
char buffer[MAX_BUFFER_SIZE];
size_t remaining_bytes = loadable_segment_padding;
memset(buffer, 0, MIN(MAX_BUFFER_SIZE, loadable_segment_padding));
while (remaining_bytes > 0) {
const size_t bytes = MIN(remaining_bytes, MAX_BUFFER_SIZE);
if (os_write(elf_file, buffer, bytes) != bytes) {
SYSLOG_INTERNAL_ERROR("Failed to add padding to the core dump file.");
os_close(elf_file);
return false;
}
remaining_bytes -= bytes;
}
// Write memory content to the core dump file.
for (int section_index = 0; section_index < section_count - 1; ++section_index) {
const size_t length = section_header_info[section_index].vm_end -
Expand All @@ -577,9 +601,9 @@ os_dump_core_internal(dcontext_t *dcontext)
return false;
}
// Write section headers to the core dump file.
file_offset = sizeof(ELF_HEADER_TYPE) +
core_file_offset = sizeof(ELF_HEADER_TYPE) +
sizeof(ELF_PROGRAM_HEADER_TYPE) * program_header_count +
PROGRAM_HEADER_NOTE_LENGTH;
PROGRAM_HEADER_NOTE_LENGTH + loadable_segment_padding;

// 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 @@ -594,7 +618,8 @@ os_dump_core_internal(dcontext_t *dcontext)
}
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,
flags, (ELF_ADDR)section_header_info[section_index].vm_start,
core_file_offset,
section_header_info[section_index].vm_end -
section_header_info[section_index].vm_start,
/*link=*/0,
Expand All @@ -603,13 +628,13 @@ os_dump_core_internal(dcontext_t *dcontext)
os_close(elf_file);
return false;
}
file_offset += section_header_info[section_index].vm_end -
core_file_offset += section_header_info[section_index].vm_end -
section_header_info[section_index].vm_start;
}
// Write the section name section.
if (!write_section_header(
elf_file, string_table_offset - strlen(SECTION_HEADER_TABLE), SHT_STRTAB,
/*flags=*/0, /*virtual_address=*/0, file_offset,
/*flags=*/0, /*virtual_address=*/0, core_file_offset,
/*section_size=*/string_table_offset, /*link=*/0,
/*info=*/0, /*alignment=*/1,
/*entry_size=*/0)) {
Expand Down

0 comments on commit 53ce419

Please sign in to comment.