From 9c7245b97d515c9bdb9f8b63dc1d4e35e2fafa56 Mon Sep 17 00:00:00 2001 From: Stephen Webb Date: Wed, 25 May 2022 15:17:43 -0400 Subject: Add autodetection of procfs_status type Instead of struct elf_prstatus or struct prstatus, QNX has a procfs_status typedef. Added autoconfigury to detect that and switched using a preprocessor macro to define the type used as a typedef of UCD_proc_status_t instead. Also changed some field name references where required. Signed-off-by: Stephen Webb --- configure.ac | 2 +- src/coredump/_UCD_create.c | 8 +++++ src/coredump/_UCD_get_threadinfo_prstatus.c | 48 ++++++++++++++--------------- src/coredump/_UCD_internal.h | 32 ++++++++++--------- 4 files changed, 50 insertions(+), 40 deletions(-) diff --git a/configure.ac b/configure.ac index 3bff80ba..bc4bef3a 100644 --- a/configure.ac +++ b/configure.ac @@ -48,7 +48,7 @@ AC_CHECK_SIZEOF(off_t) CPPFLAGS="${CPPFLAGS} -D_GNU_SOURCE" AC_CHECK_MEMBERS([struct dl_phdr_info.dlpi_subs],,,[#include ]) -AC_CHECK_TYPES([struct elf_prstatus, struct prstatus], [], [], +AC_CHECK_TYPES([struct elf_prstatus, struct prstatus, procfs_status], [], [], [$ac_includes_default #if HAVE_SYS_PROCFS_H # include diff --git a/src/coredump/_UCD_create.c b/src/coredump/_UCD_create.c index 21fd0b92..9994b6cb 100644 --- a/src/coredump/_UCD_create.c +++ b/src/coredump/_UCD_create.c @@ -243,12 +243,20 @@ void _UCD_select_thread(struct UCD_info *ui, int n) pid_t _UCD_get_pid(struct UCD_info *ui) { +#if defined(HAVE_PROCFS_STATUS) + return ui->prstatus->pid; +#else return ui->prstatus->pr_pid; +#endif } int _UCD_get_cursig(struct UCD_info *ui) { +#if defined(HAVE_PROCFS_STATUS) + return 0; +#else return ui->prstatus->pr_cursig; +#endif } int _UCD_add_backing_file_at_segment(struct UCD_info *ui, int phdr_no, const char *filename) diff --git a/src/coredump/_UCD_get_threadinfo_prstatus.c b/src/coredump/_UCD_get_threadinfo_prstatus.c index cd03ce36..50833d84 100644 --- a/src/coredump/_UCD_get_threadinfo_prstatus.c +++ b/src/coredump/_UCD_get_threadinfo_prstatus.c @@ -62,7 +62,7 @@ _save_thread_notes(uint32_t n_namesz, uint32_t n_descsz, uint32_t n_type, char * struct UCD_info *ui = (struct UCD_info *)arg; if (n_type == NT_PRSTATUS) { - memcpy(&ui->threads[ui->n_threads].prstatus, desc, sizeof(struct PRSTATUS_STRUCT)); + memcpy(&ui->threads[ui->n_threads].prstatus, desc, sizeof(UCD_proc_status_t)); ++ui->n_threads; } if (n_type == NT_FPREGSET) @@ -93,33 +93,33 @@ _UCD_get_threadinfo(struct UCD_info *ui, coredump_phdr_t *phdrs, unsigned phdr_s int ret = -UNW_ENOINFO; for (unsigned i = 0; i < phdr_size; ++i) - { - Debug(8, "phdr[%03d]: type:%d", i, phdrs[i].p_type); - if (phdrs[i].p_type == PT_NOTE) { - size_t thread_count = 0; - uint8_t *segment; - size_t segment_size; - ret = _UCD_elf_read_segment(ui, &phdrs[i], &segment, &segment_size); - if (ret == UNW_ESUCCESS) - { - _UCD_elf_visit_notes(segment, segment_size, _count_thread_notes, &thread_count); - Debug(2, "found %zu threads\n", thread_count); + Debug(8, "phdr[%03d]: type:%d", i, phdrs[i].p_type); + if (phdrs[i].p_type == PT_NOTE) + { + size_t thread_count = 0; + uint8_t *segment; + size_t segment_size; + ret = _UCD_elf_read_segment(ui, &phdrs[i], &segment, &segment_size); + if (ret == UNW_ESUCCESS) + { + _UCD_elf_visit_notes(segment, segment_size, _count_thread_notes, &thread_count); + Debug(2, "found %zu threads\n", thread_count); - size_t new_size = sizeof(struct UCD_thread_info) * (ui->n_threads + thread_count); - ui->threads = realloc(ui->threads, new_size); - if (ui->threads == NULL) - { - Debug(0, "error allocating %zu bytes of memory \n", new_size); - free(segment); - return -UNW_EUNSPEC; - } - _UCD_elf_visit_notes(segment, segment_size, _save_thread_notes, ui); + size_t new_size = sizeof(struct UCD_thread_info) * (ui->n_threads + thread_count); + ui->threads = realloc(ui->threads, new_size); + if (ui->threads == NULL) + { + Debug(0, "error allocating %zu bytes of memory \n", new_size); + free(segment); + return -UNW_EUNSPEC; + } + _UCD_elf_visit_notes(segment, segment_size, _save_thread_notes, ui); - free(segment); - } + free(segment); + } + } } - } return ret; } diff --git a/src/coredump/_UCD_internal.h b/src/coredump/_UCD_internal.h index e980aa29..6ac04b9e 100644 --- a/src/coredump/_UCD_internal.h +++ b/src/coredump/_UCD_internal.h @@ -78,32 +78,34 @@ struct coredump_phdr typedef struct coredump_phdr coredump_phdr_t; #if defined(HAVE_STRUCT_ELF_PRSTATUS) -#define PRSTATUS_STRUCT elf_prstatus +typedef struct elf_prstatus UCD_proc_status_t; #elif defined(HAVE_STRUCT_PRSTATUS) -#define PRSTATUS_STRUCT prstatus +typedef struct prstatus UCD_proc_status_t; +#elif defined(HAVE_PROCFS_STATUS) +typedef procfs_status UCD_proc_status_t; #else -#define PRSTATUS_STRUCT non_existent +# error UCD_proc_status_t undefined #endif struct UCD_thread_info { - struct PRSTATUS_STRUCT prstatus; - elf_fpregset_t fpregset; + UCD_proc_status_t prstatus; + elf_fpregset_t fpregset; }; struct UCD_info { - int big_endian; /* bool */ - int coredump_fd; - char *coredump_filename; /* for error meesages only */ - coredump_phdr_t *phdrs; /* array, allocated */ - unsigned phdrs_count; - void *note_phdr; /* allocated or NULL */ - struct PRSTATUS_STRUCT *prstatus; /* points inside note_phdr */ - elf_fpregset_t *fpregset; - int n_threads; + int big_endian; /* bool */ + int coredump_fd; + char *coredump_filename; /* for error meesages only */ + coredump_phdr_t *phdrs; /* array, allocated */ + unsigned phdrs_count; + void *note_phdr; /* allocated or NULL */ + UCD_proc_status_t *prstatus; /* points inside note_phdr */ + elf_fpregset_t *fpregset; + int n_threads; struct UCD_thread_info *threads; - struct elf_dyn_info edi; + struct elf_dyn_info edi; }; -- cgit v1.2.1