Skip to content

Commit

Permalink
Merge pull request #1519 from darlinghq/coredump_cpp_and_fixes
Browse files Browse the repository at this point in the history
Coredump: Migrate To C++ & Bug Fix
  • Loading branch information
CuriousTommy authored Jun 13, 2024
2 parents 65c5198 + eff1cab commit 203af1f
Show file tree
Hide file tree
Showing 2 changed files with 43 additions and 28 deletions.
6 changes: 5 additions & 1 deletion src/hosttools/CMakeLists.txt
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,11 @@ project(hosttools)
option(DARLING_COREDUMP_SANITIZE "Enable/disable ASAN and UBSAN in darling-coredump" OFF)

add_executable(darling-coredump
src/coredump/main.c
src/coredump/main.cpp
)

target_compile_options(darling-coredump PRIVATE
-std=c++17
)

target_include_directories(darling-coredump PRIVATE
Expand Down
Original file line number Diff line number Diff line change
@@ -1,3 +1,5 @@
#include <filesystem>

#include <stdio.h>
#include <unistd.h>
#include <fcntl.h>
Expand Down Expand Up @@ -248,10 +250,23 @@ static int open_file(struct coredump_params* cprm, const char* filename, size_t

// if that fails, try to see if it refers to the mounted prefix; if it does, try the lower layer
if (fd < 0 && filename_length >= cprm->prefix_length && strncmp(filename, cprm->prefix, cprm->prefix_length) == 0) {
char* temp_filename = malloc(sizeof(LIBEXEC_PATH "/") + (filename_length - cprm->prefix_length));
sprintf(temp_filename, "%s/%s", LIBEXEC_PATH, &filename[cprm->prefix_length]);
fd = open(temp_filename, O_RDONLY);
free(temp_filename);
std::filesystem::path temp_filename = std::filesystem::path() / LIBEXEC_PATH / &filename[cprm->prefix_length];
fd = open(temp_filename.c_str(), O_RDONLY);

// Sometimes the absolute path may actually be the macOS path
} else if (fd < 0 && filename[0] == '/') {
const char* relative_macos_path = &filename[1]; // Convert the absolute path into a relative path
std::filesystem::path temp_filename;

// Let's see if the file exists in the upper layer
temp_filename = std::filesystem::path(cprm->prefix) / relative_macos_path;
fd = open(temp_filename.c_str(), O_RDONLY);

// Otherwise, check the lower layer
if (fd < 0) {
temp_filename = std::filesystem::path(LIBEXEC_PATH) / relative_macos_path;
fd = open(temp_filename.c_str(), O_RDONLY);
}
}

return fd;
Expand Down Expand Up @@ -318,7 +333,7 @@ int main(int argc, char** argv) {
return 1;
}

cprm.universal_header = cprm.input_corefile_mapping;
cprm.universal_header = (const struct elf_universal_header*)cprm.input_corefile_mapping;

if (
cprm.universal_header->e_ident[EI_MAG0] != ELFMAG0 ||
Expand All @@ -345,18 +360,18 @@ int main(int argc, char** argv) {
switch (get_elf_machine_type(&cprm)) {
case EM_X86_64:
case EM_386:
cprm.input_header = cprm.input_corefile_mapping;
cprm.input_header = (const union Elf_Ehdr*)cprm.input_corefile_mapping;
break;
default:
fprintf(stderr, "Unexpected e_machine (%d) detected, aborting.\n", cprm.universal_header->e_machine);
return 1;
}

cprm.input_program_headers = (const void*)((const char*)cprm.input_corefile_mapping + cprm_elf(cprm.is_64_bit, cprm.input_header, e_phoff));
cprm.input_program_headers_end = (const void*)((const char*)cprm.input_program_headers + (cprm_elf(cprm.is_64_bit, cprm.input_header, e_phentsize) * cprm_elf(cprm.is_64_bit, cprm.input_header, e_phnum)));
cprm.input_program_headers = (const union Elf_Phdr*)((const char*)cprm.input_corefile_mapping + cprm_elf(cprm.is_64_bit, cprm.input_header, e_phoff));
cprm.input_program_headers_end = (const union Elf_Phdr*)((const char*)cprm.input_program_headers + (cprm_elf(cprm.is_64_bit, cprm.input_header, e_phentsize) * cprm_elf(cprm.is_64_bit, cprm.input_header, e_phnum)));

// first, count how many VM areas we have
for (const union Elf_Phdr* program_header = cprm.input_program_headers; program_header < cprm.input_program_headers_end; program_header = (const void*)((const char*)program_header + cprm_elf(cprm.is_64_bit, cprm.input_header, e_phentsize))) {
for (const union Elf_Phdr* program_header = cprm.input_program_headers; program_header < cprm.input_program_headers_end; program_header = (const union Elf_Phdr*)((const char*)program_header + cprm_elf(cprm.is_64_bit, cprm.input_header, e_phentsize))) {
if (cprm_elf(cprm.is_64_bit, program_header, p_type) == PT_LOAD) {
++cprm.vm_area_count;
} else if (cprm_elf(cprm.is_64_bit, program_header, p_type) == PT_NOTE) {
Expand All @@ -368,7 +383,7 @@ int main(int argc, char** argv) {
continue;
}

cprm.input_notes = (const void*)((const char*)cprm.input_corefile_mapping + cprm_elf(cprm.is_64_bit, program_header, p_offset));
cprm.input_notes = (const union Elf_Nhdr*)((const char*)cprm.input_corefile_mapping + cprm_elf(cprm.is_64_bit, program_header, p_offset));
cprm.input_notes_size = cprm_elf(cprm.is_64_bit, program_header, p_filesz);
}
}
Expand All @@ -381,14 +396,14 @@ int main(int argc, char** argv) {
for (const union Elf_Nhdr* note_header = cprm.input_notes; note_header < (const union Elf_Nhdr*)((const char*)cprm.input_notes + cprm.input_notes_size); note_header = find_next_note(&cprm, note_header)) {
if (cprm_elf(cprm.is_64_bit, note_header, n_type) == NT_FILE) {
// allocate a copy for alignment purposes
cprm.nt_file = malloc(cprm_elf(cprm.is_64_bit, note_header, n_descsz));
cprm.nt_file = (union nt_file_header*)malloc(cprm_elf(cprm.is_64_bit, note_header, n_descsz));
if (!cprm.nt_file) {
perror("malloc");
return 1;
}
memcpy(cprm.nt_file, note_data(&cprm, note_header), cprm_elf(cprm.is_64_bit, note_header, n_descsz));

cprm.nt_file_filenames = malloc(cprm_elf(cprm.is_64_bit, cprm.nt_file, count) * sizeof(const char*));
cprm.nt_file_filenames = (const char**)malloc(cprm_elf(cprm.is_64_bit, cprm.nt_file, count) * sizeof(const char*));
if (!cprm.nt_file_filenames) {
perror("malloc");
return 1;
Expand All @@ -411,7 +426,7 @@ int main(int argc, char** argv) {
return 1;
}

cprm.thread_infos = malloc(sizeof(struct thread_info) * cprm.thread_info_count);
cprm.thread_infos = (struct thread_info*)malloc(sizeof(struct thread_info) * cprm.thread_info_count);
if (!cprm.thread_infos) {
perror("malloc");
return 1;
Expand All @@ -421,7 +436,7 @@ int main(int argc, char** argv) {
for (const union Elf_Nhdr* note_header = cprm.input_notes; note_header < (const union Elf_Nhdr*)((const char*)cprm.input_notes + cprm.input_notes_size); note_header = find_next_note(&cprm, note_header)) {
if (cprm_elf(cprm.is_64_bit, note_header, n_type) == NT_PRSTATUS) {
// allocate a copy for alignment purposes
union nt_prstatus* prstatus = malloc(cprm_elf(cprm.is_64_bit, note_header, n_descsz));
union nt_prstatus* prstatus = (union nt_prstatus*)malloc(cprm_elf(cprm.is_64_bit, note_header, n_descsz));
if (!prstatus) {
perror("malloc");
return 1;
Expand Down Expand Up @@ -482,7 +497,7 @@ int main(int argc, char** argv) {
}

// now allocate the VM area array
cprm.vm_areas = malloc(sizeof(*cprm.vm_areas) * cprm.vm_area_count);
cprm.vm_areas = (struct vm_area*)malloc(sizeof(*cprm.vm_areas) * cprm.vm_area_count);
if (!cprm.vm_areas) {
perror("malloc");
return 1;
Expand Down Expand Up @@ -798,7 +813,7 @@ bool macho_dump_headers32(struct coredump_params* cprm)
}

if (!dump_emit(cprm, &mh, sizeof(mh)))
goto fail;
return false;

uint32_t file_offset = round_up_pow2(mh.sizeofcmds + sizeof(mh), align_page_size);

Expand Down Expand Up @@ -837,13 +852,13 @@ bool macho_dump_headers32(struct coredump_params* cprm)
sc.maxprot = sc.initprot;

if (!dump_emit(cprm, &sc, sizeof(sc)))
goto fail;
return false;

file_offset += round_up_pow2(sc.filesize, align_page_size);
}

const int memsize = sizeof(struct thread_command) + statesize;
uint8_t* buffer = malloc(memsize);
uint8_t* buffer = (uint8_t*)malloc(memsize);

for (size_t i = 0; i < cprm->thread_info_count; ++i) {
const struct thread_info* thread_info = &cprm->thread_infos[i];
Expand Down Expand Up @@ -880,14 +895,12 @@ bool macho_dump_headers32(struct coredump_params* cprm)
if (!dump_emit(cprm, buffer, memsize))
{
free(buffer);
goto fail;
return false;
}
}
free(buffer);

return true;
fail:
return false;
}

static
Expand Down Expand Up @@ -948,7 +961,7 @@ bool macho_dump_headers64(struct coredump_params* cprm)
}

if (!dump_emit(cprm, &mh, sizeof(mh)))
goto fail;
return false;

uint64_t file_offset = round_up_pow2(mh.sizeofcmds + sizeof(mh), align_page_size);

Expand Down Expand Up @@ -985,13 +998,13 @@ bool macho_dump_headers64(struct coredump_params* cprm)
sc.maxprot = sc.initprot;

if (!dump_emit(cprm, &sc, sizeof(sc)))
goto fail;
return false;

file_offset += round_up_pow2(sc.filesize, align_page_size);
}

const int memsize = sizeof(struct thread_command) + statesize;
uint8_t* buffer = malloc(memsize);
uint8_t* buffer = (uint8_t*)malloc(memsize);

for (size_t i = 0; i < cprm->thread_info_count; ++i) {
const struct thread_info* thread_info = &cprm->thread_infos[i];
Expand Down Expand Up @@ -1028,14 +1041,12 @@ bool macho_dump_headers64(struct coredump_params* cprm)
if (!dump_emit(cprm, buffer, memsize))
{
free(buffer);
goto fail;
return false;
}
}
free(buffer);

return true;
fail:
return false;
}

void macho_coredump(struct coredump_params* cprm)
Expand Down

0 comments on commit 203af1f

Please sign in to comment.