summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorStephen Webb <swebb@blackberry.com>2022-05-25 15:17:43 -0400
committerStephen M. Webb <stephen.webb@bregmasoft.ca>2022-06-24 21:56:32 -0400
commit9c7245b97d515c9bdb9f8b63dc1d4e35e2fafa56 (patch)
tree91d3d14b08a74203a0f08da7f1d57ee73e4d488f
parentfa905e5c03f4d8b09d70ba8a04d96fd71910c28a (diff)
downloadlibunwind-9c7245b97d515c9bdb9f8b63dc1d4e35e2fafa56.tar.gz
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 <swebb@blackberry.com>
-rw-r--r--configure.ac2
-rw-r--r--src/coredump/_UCD_create.c8
-rw-r--r--src/coredump/_UCD_get_threadinfo_prstatus.c48
-rw-r--r--src/coredump/_UCD_internal.h32
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 <link.h>])
-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 <sys/procfs.h>
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;
};