From 47c699f52a0a226abc93e7e5ecf78569cc4291fe Mon Sep 17 00:00:00 2001 From: Tony Reix Date: Fri, 19 Jan 2018 17:45:24 +0000 Subject: [PATCH] xcoff.c (xcoff_incl_compare): New function. * xcoff.c (xcoff_incl_compare): New function. (xcoff_incl_search): New function. (xcoff_process_linenos): Use bsearch to find include file. (xcoff_initialize_fileline): Sort include file information. From-SVN: r256895 --- libbacktrace/ChangeLog | 7 ++++++ libbacktrace/xcoff.c | 52 ++++++++++++++++++++++++++++++++++-------- 2 files changed, 50 insertions(+), 9 deletions(-) diff --git a/libbacktrace/ChangeLog b/libbacktrace/ChangeLog index 955ff8d47ab..1fcca776759 100644 --- a/libbacktrace/ChangeLog +++ b/libbacktrace/ChangeLog @@ -1,3 +1,10 @@ +2018-01-19 Tony Reix + + * xcoff.c (xcoff_incl_compare): New function. + (xcoff_incl_search): New function. + (xcoff_process_linenos): Use bsearch to find include file. + (xcoff_initialize_fileline): Sort include file information. + 2018-01-16 Ian Lance Taylor * elf.c (codes) [GENERATE_FIXED_HUFFMAN_TABLE]: Fix size to be diff --git a/libbacktrace/xcoff.c b/libbacktrace/xcoff.c index 4b2fdad2cd6..1ae001dd1de 100644 --- a/libbacktrace/xcoff.c +++ b/libbacktrace/xcoff.c @@ -760,6 +760,40 @@ xcoff_fileline (struct backtrace_state *state, uintptr_t pc, return callback (data, pc, NULL, 0, NULL); } +/* Compare struct xcoff_incl for qsort. */ + +static int +xcoff_incl_compare (const void *v1, const void *v2) +{ + const struct xcoff_incl *in1 = (const struct xcoff_incl *) v1; + const struct xcoff_incl *in2 = (const struct xcoff_incl *) v2; + + if (in1->begin < in2->begin) + return -1; + else if (in1->begin > in2->begin) + return 1; + else + return 0; +} + +/* Find a lnnoptr in an include file. */ + +static int +xcoff_incl_search (const void *vkey, const void *ventry) +{ + const uintptr_t *key = (const uintptr_t *) vkey; + const struct xcoff_incl *entry = (const struct xcoff_incl *) ventry; + uintptr_t lnno; + + lnno = *key; + if (lnno < entry->begin) + return -1; + else if (lnno > entry->end) + return 1; + else + return 0; +} + /* Add a new mapping to the vector of line mappings that we are building. Returns 1 on success, 0 on failure. */ @@ -809,7 +843,6 @@ xcoff_process_linenos (struct backtrace_state *state, uintptr_t base_address, uintptr_t pc; uint32_t lnno; int begincl; - size_t i; aux = (const b_xcoff_auxent *) (fsym + 1); lnnoptr = aux->x_fcn.x_lnnoptr; @@ -839,15 +872,13 @@ xcoff_process_linenos (struct backtrace_state *state, uintptr_t base_address, /* If part of a function other than the beginning comes from an include file, the line numbers are absolute, rather than relative to the beginning of the function. */ - for (i = 0; i < vec->count; ++i) - { - incl = (struct xcoff_incl *) vec->vec.base + i; - if (incl->begin <= lnnoptr && lnnoptr <= incl->end) - break; - } + incl = (struct xcoff_incl *) bsearch (&lnnoptr, vec->vec.base, + vec->count, + sizeof (struct xcoff_incl), + xcoff_incl_search); if (begincl == -1) - begincl = (i < vec->count); - if (i < vec->count) + begincl = incl != NULL; + if (incl != NULL) { filename = incl->filename; if (begincl == 1) @@ -935,6 +966,9 @@ xcoff_initialize_fileline (struct backtrace_state *state, i += asym->n_numaux; } + backtrace_qsort (vec.vec.base, vec.count, + sizeof (struct xcoff_incl), xcoff_incl_compare); + filename = NULL; fsym = NULL; for (i = 0; i < nsyms; ++i) -- 2.30.2