xcoff.c (struct xcoff_line, [...]): Remove.
* xcoff.c (struct xcoff_line, struct xcoff_line_vector): Remove. (struct xcoff_func, struct xcoff_func_vector): New structs. (xcoff_syminfo): Drop leading dot from symbol name. (xcoff_line_compare, xcoff_line_search): Remove. (xcoff_func_compare, xcoff_func_search): New static functions. (xcoff_lookup_pc): Search function table. (xcoff_add_line, xcoff_process_linenos): Remove. (xcoff_initialize_fileline): Build function table. From-SVN: r263238
This commit is contained in:
parent
701d080a4b
commit
ca9a1314ec
2 changed files with 212 additions and 232 deletions
|
@ -1,3 +1,14 @@
|
||||||
|
2018-08-01 Tony Reix <tony.reix@atos.net>
|
||||||
|
|
||||||
|
* xcoff.c (struct xcoff_line, struct xcoff_line_vector): Remove.
|
||||||
|
(struct xcoff_func, struct xcoff_func_vector): New structs.
|
||||||
|
(xcoff_syminfo): Drop leading dot from symbol name.
|
||||||
|
(xcoff_line_compare, xcoff_line_search): Remove.
|
||||||
|
(xcoff_func_compare, xcoff_func_search): New static functions.
|
||||||
|
(xcoff_lookup_pc): Search function table.
|
||||||
|
(xcoff_add_line, xcoff_process_linenos): Remove.
|
||||||
|
(xcoff_initialize_fileline): Build function table.
|
||||||
|
|
||||||
2018-06-21 Denis Khalikov <d.khalikov@partner.samsung.com>
|
2018-06-21 Denis Khalikov <d.khalikov@partner.samsung.com>
|
||||||
|
|
||||||
PR other/86198
|
PR other/86198
|
||||||
|
|
|
@ -338,27 +338,32 @@ struct xcoff_incl_vector
|
||||||
size_t count;
|
size_t count;
|
||||||
};
|
};
|
||||||
|
|
||||||
/* Map a single PC value to a file/function/line. */
|
/* A growable vector of functions information. */
|
||||||
|
|
||||||
struct xcoff_line
|
struct xcoff_func
|
||||||
{
|
{
|
||||||
/* PC. */
|
/* PC. */
|
||||||
uintptr_t pc;
|
uintptr_t pc;
|
||||||
/* File name. Many entries in the array are expected to point to
|
/* The size of the function. */
|
||||||
the same file name. */
|
size_t size;
|
||||||
const char *filename;
|
|
||||||
/* Function name. */
|
/* Function name. */
|
||||||
const char *function;
|
const char *name;
|
||||||
/* Line number. */
|
/* File name. */
|
||||||
int lineno;
|
const char *filename;
|
||||||
|
/* Pointer to first lnno entry. */
|
||||||
|
uintptr_t lnnoptr;
|
||||||
|
/* Base address of containing section. */
|
||||||
|
uintptr_t sect_base;
|
||||||
|
/* Starting source line number. */
|
||||||
|
int lnno;
|
||||||
};
|
};
|
||||||
|
|
||||||
/* A growable vector of line number information. This is used while
|
/* A growable vector of function information. This is used while
|
||||||
reading the line numbers. */
|
reading the function symbols. */
|
||||||
|
|
||||||
struct xcoff_line_vector
|
struct xcoff_func_vector
|
||||||
{
|
{
|
||||||
/* Memory. This is an array of struct xcoff_line. */
|
/* Memory. This is an array of struct xcoff_func. */
|
||||||
struct backtrace_vector vec;
|
struct backtrace_vector vec;
|
||||||
/* Number of valid mappings. */
|
/* Number of valid mappings. */
|
||||||
size_t count;
|
size_t count;
|
||||||
|
@ -370,8 +375,16 @@ struct xcoff_fileline_data
|
||||||
{
|
{
|
||||||
/* The data for the next file we know about. */
|
/* The data for the next file we know about. */
|
||||||
struct xcoff_fileline_data *next;
|
struct xcoff_fileline_data *next;
|
||||||
/* Line number information. */
|
/* Functions information. */
|
||||||
struct xcoff_line_vector vec;
|
struct xcoff_func_vector func_vec;
|
||||||
|
/* Include files information. */
|
||||||
|
struct xcoff_incl_vector incl_vec;
|
||||||
|
/* Line numbers information. */
|
||||||
|
const unsigned char *linenos;
|
||||||
|
size_t linenos_size;
|
||||||
|
uint64_t lnnoptr0;
|
||||||
|
/* Loader address. */
|
||||||
|
uintptr_t base_address;
|
||||||
};
|
};
|
||||||
|
|
||||||
/* An index of DWARF sections we care about. */
|
/* An index of DWARF sections we care about. */
|
||||||
|
@ -509,6 +522,7 @@ xcoff_syminfo (struct backtrace_state *state ATTRIBUTE_UNUSED, uintptr_t addr,
|
||||||
{
|
{
|
||||||
struct xcoff_syminfo_data *edata;
|
struct xcoff_syminfo_data *edata;
|
||||||
struct xcoff_symbol *sym = NULL;
|
struct xcoff_symbol *sym = NULL;
|
||||||
|
const char *name;
|
||||||
|
|
||||||
if (!state->threaded)
|
if (!state->threaded)
|
||||||
{
|
{
|
||||||
|
@ -547,7 +561,13 @@ xcoff_syminfo (struct backtrace_state *state ATTRIBUTE_UNUSED, uintptr_t addr,
|
||||||
if (sym == NULL)
|
if (sym == NULL)
|
||||||
callback (data, addr, NULL, 0, 0);
|
callback (data, addr, NULL, 0, 0);
|
||||||
else
|
else
|
||||||
callback (data, addr, sym->name, sym->address, sym->size);
|
{
|
||||||
|
name = sym->name;
|
||||||
|
/* AIX prepends a '.' to function entry points, remove it. */
|
||||||
|
if (name && *name == '.')
|
||||||
|
++name;
|
||||||
|
callback (data, addr, name, sym->address, sym->size);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
/* Return the name of an XCOFF symbol. */
|
/* Return the name of an XCOFF symbol. */
|
||||||
|
@ -640,43 +660,76 @@ xcoff_initialize_syminfo (struct backtrace_state *state,
|
||||||
return 1;
|
return 1;
|
||||||
}
|
}
|
||||||
|
|
||||||
/* Compare struct xcoff_line for qsort. */
|
/* Compare struct xcoff_func for qsort. */
|
||||||
|
|
||||||
static int
|
static int
|
||||||
xcoff_line_compare (const void *v1, const void *v2)
|
xcoff_func_compare (const void *v1, const void *v2)
|
||||||
{
|
{
|
||||||
const struct xcoff_line *ln1 = (const struct xcoff_line *) v1;
|
const struct xcoff_func *fn1 = (const struct xcoff_func *) v1;
|
||||||
const struct xcoff_line *ln2 = (const struct xcoff_line *) v2;
|
const struct xcoff_func *fn2 = (const struct xcoff_func *) v2;
|
||||||
|
|
||||||
if (ln1->pc < ln2->pc)
|
if (fn1->pc < fn2->pc)
|
||||||
return -1;
|
return -1;
|
||||||
else if (ln1->pc > ln2->pc)
|
else if (fn1->pc > fn2->pc)
|
||||||
return 1;
|
return 1;
|
||||||
else
|
else
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
/* Find a PC in a line vector. We always allocate an extra entry at
|
/* Compare a PC against an xcoff_func for bsearch. */
|
||||||
the end of the lines vector, so that this routine can safely look
|
|
||||||
at the next entry. */
|
|
||||||
|
|
||||||
static int
|
static int
|
||||||
xcoff_line_search (const void *vkey, const void *ventry)
|
xcoff_func_search (const void *vkey, const void *ventry)
|
||||||
{
|
{
|
||||||
const uintptr_t *key = (const uintptr_t *) vkey;
|
const uintptr_t *key = (const uintptr_t *) vkey;
|
||||||
const struct xcoff_line *entry = (const struct xcoff_line *) ventry;
|
const struct xcoff_func *entry = (const struct xcoff_func *) ventry;
|
||||||
uintptr_t pc;
|
uintptr_t pc;
|
||||||
|
|
||||||
pc = *key;
|
pc = *key;
|
||||||
if (pc < entry->pc)
|
if (pc < entry->pc)
|
||||||
return -1;
|
return -1;
|
||||||
else if ((entry + 1)->pc == (uintptr_t) -1 || pc >= (entry + 1)->pc)
|
else if ((entry->size == 0 && pc > entry->pc)
|
||||||
|
|| (entry->size > 0 && pc >= entry->pc + entry->size))
|
||||||
return 1;
|
return 1;
|
||||||
else
|
else
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
/* Look for a PC in the line vector for one module. On success,
|
/* 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;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Look for a PC in the function vector for one module. On success,
|
||||||
call CALLBACK and return whatever it returns. On error, call
|
call CALLBACK and return whatever it returns. On error, call
|
||||||
ERROR_CALLBACK and return 0. Sets *FOUND to 1 if the PC is found,
|
ERROR_CALLBACK and return 0. Sets *FOUND to 1 if the PC is found,
|
||||||
0 if not. */
|
0 if not. */
|
||||||
|
@ -688,26 +741,82 @@ xcoff_lookup_pc (struct backtrace_state *state ATTRIBUTE_UNUSED,
|
||||||
backtrace_error_callback error_callback ATTRIBUTE_UNUSED,
|
backtrace_error_callback error_callback ATTRIBUTE_UNUSED,
|
||||||
void *data, int *found)
|
void *data, int *found)
|
||||||
{
|
{
|
||||||
const struct xcoff_line *ln;
|
const struct xcoff_incl *incl, *bincl;
|
||||||
|
const struct xcoff_func *fn;
|
||||||
|
const b_xcoff_lineno *lineno;
|
||||||
|
const unsigned char *lineptr;
|
||||||
const char *function;
|
const char *function;
|
||||||
|
const char *filename;
|
||||||
|
uintptr_t lnnoptr, match;
|
||||||
|
uint32_t lnno = 0;
|
||||||
|
|
||||||
*found = 1;
|
*found = 1;
|
||||||
|
|
||||||
ln = (struct xcoff_line *) bsearch (&pc, fdata->vec.vec.base,
|
if ((pc & 3) != 0)
|
||||||
fdata->vec.count,
|
++pc;
|
||||||
sizeof (struct xcoff_line),
|
|
||||||
xcoff_line_search);
|
/* Find the function first. */
|
||||||
if (ln == NULL)
|
fn = ((struct xcoff_func *)
|
||||||
|
bsearch (&pc, fdata->func_vec.vec.base, fdata->func_vec.count,
|
||||||
|
sizeof (struct xcoff_func), xcoff_func_search));
|
||||||
|
if (fn == NULL)
|
||||||
{
|
{
|
||||||
*found = 0;
|
*found = 0;
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
function = ln->function;
|
filename = fn->filename;
|
||||||
|
|
||||||
|
/* Find the line number next. */
|
||||||
|
|
||||||
|
/* Skip first entry that points to symtab. */
|
||||||
|
lnnoptr = fn->lnnoptr + LINESZ;
|
||||||
|
match = lnnoptr;
|
||||||
|
|
||||||
|
lineptr = fdata->linenos + (lnnoptr - fdata->lnnoptr0);
|
||||||
|
while (lineptr + LINESZ <= fdata->linenos + fdata->linenos_size)
|
||||||
|
{
|
||||||
|
lineno = (const b_xcoff_lineno *) lineptr;
|
||||||
|
if (lineno->l_lnno == 0)
|
||||||
|
break;
|
||||||
|
if (pc <= fdata->base_address + lineno->l_addr.l_paddr - fn->sect_base)
|
||||||
|
break;
|
||||||
|
match = lnnoptr;
|
||||||
|
lnno = lineno->l_lnno;
|
||||||
|
|
||||||
|
lnnoptr += LINESZ;
|
||||||
|
lineptr += LINESZ;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* 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. */
|
||||||
|
incl = ((struct xcoff_incl *)
|
||||||
|
bsearch (&match, fdata->incl_vec.vec.base,
|
||||||
|
fdata->incl_vec.count, sizeof (struct xcoff_incl),
|
||||||
|
xcoff_incl_search));
|
||||||
|
if (incl != NULL)
|
||||||
|
{
|
||||||
|
bincl = ((struct xcoff_incl *)
|
||||||
|
bsearch (&fn->lnnoptr, fdata->incl_vec.vec.base,
|
||||||
|
fdata->incl_vec.count, sizeof (struct xcoff_incl),
|
||||||
|
xcoff_incl_search));
|
||||||
|
if (bincl != NULL && strcmp (incl->filename, bincl->filename) == 0)
|
||||||
|
{
|
||||||
|
lnno += fn->lnno - 1;
|
||||||
|
}
|
||||||
|
filename = incl->filename;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
lnno += fn->lnno - 1;
|
||||||
|
}
|
||||||
|
|
||||||
|
function = fn->name;
|
||||||
/* AIX prepends a '.' to function entry points, remove it. */
|
/* AIX prepends a '.' to function entry points, remove it. */
|
||||||
if (*function == '.')
|
if (function != NULL && *function == '.')
|
||||||
++function;
|
++function;
|
||||||
return callback (data, pc, ln->filename, ln->lineno, function);
|
return callback (data, pc, filename, lnno, function);
|
||||||
}
|
}
|
||||||
|
|
||||||
/* Return the file/line information for a PC using the XCOFF lineno
|
/* Return the file/line information for a PC using the XCOFF lineno
|
||||||
|
@ -760,146 +869,7 @@ xcoff_fileline (struct backtrace_state *state, uintptr_t pc,
|
||||||
return callback (data, pc, NULL, 0, NULL);
|
return callback (data, pc, NULL, 0, NULL);
|
||||||
}
|
}
|
||||||
|
|
||||||
/* Compare struct xcoff_incl for qsort. */
|
/* Initialize the function vector info for xcoff_fileline. */
|
||||||
|
|
||||||
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. */
|
|
||||||
|
|
||||||
static int
|
|
||||||
xcoff_add_line (struct backtrace_state *state, uintptr_t pc,
|
|
||||||
const char *filename, const char *function, uint32_t lnno,
|
|
||||||
backtrace_error_callback error_callback, void *data,
|
|
||||||
struct xcoff_line_vector *vec)
|
|
||||||
{
|
|
||||||
struct xcoff_line *ln;
|
|
||||||
|
|
||||||
ln = ((struct xcoff_line *)
|
|
||||||
backtrace_vector_grow (state, sizeof (struct xcoff_line),
|
|
||||||
error_callback, data, &vec->vec));
|
|
||||||
if (ln == NULL)
|
|
||||||
return 0;
|
|
||||||
|
|
||||||
ln->pc = pc;
|
|
||||||
ln->filename = filename;
|
|
||||||
ln->function = function;
|
|
||||||
ln->lineno = lnno;
|
|
||||||
|
|
||||||
++vec->count;
|
|
||||||
|
|
||||||
return 1;
|
|
||||||
}
|
|
||||||
|
|
||||||
/* Add the line number entries for a function to the line vector. */
|
|
||||||
|
|
||||||
static int
|
|
||||||
xcoff_process_linenos (struct backtrace_state *state, uintptr_t base_address,
|
|
||||||
const b_xcoff_syment *fsym, const char *filename,
|
|
||||||
const b_xcoff_scnhdr *sects,
|
|
||||||
const unsigned char *strtab, size_t strtab_size,
|
|
||||||
uint32_t fcn_lnno, struct xcoff_incl_vector *vec,
|
|
||||||
struct xcoff_line_vector *lvec,
|
|
||||||
const unsigned char *linenos, size_t linenos_size,
|
|
||||||
uintptr_t lnnoptr0,
|
|
||||||
backtrace_error_callback error_callback, void *data)
|
|
||||||
{
|
|
||||||
const b_xcoff_auxent *aux;
|
|
||||||
const b_xcoff_lineno *lineno;
|
|
||||||
const unsigned char *lineptr;
|
|
||||||
const char *function;
|
|
||||||
struct xcoff_incl *incl = NULL;
|
|
||||||
uintptr_t lnnoptr;
|
|
||||||
uintptr_t pc;
|
|
||||||
uint32_t lnno;
|
|
||||||
int begincl;
|
|
||||||
|
|
||||||
aux = (const b_xcoff_auxent *) (fsym + 1);
|
|
||||||
lnnoptr = aux->x_fcn.x_lnnoptr;
|
|
||||||
|
|
||||||
if (lnnoptr < lnnoptr0 || lnnoptr + LINESZ > lnnoptr0 + linenos_size)
|
|
||||||
return 0;
|
|
||||||
|
|
||||||
function = xcoff_symname (fsym, strtab, strtab_size);
|
|
||||||
if (function == NULL)
|
|
||||||
return 0;
|
|
||||||
|
|
||||||
/* Skip first entry that points to symtab. */
|
|
||||||
|
|
||||||
lnnoptr += LINESZ;
|
|
||||||
|
|
||||||
lineptr = linenos + (lnnoptr - lnnoptr0);
|
|
||||||
|
|
||||||
begincl = -1;
|
|
||||||
while (lineptr + LINESZ <= linenos + linenos_size)
|
|
||||||
{
|
|
||||||
lineno = (const b_xcoff_lineno *) lineptr;
|
|
||||||
|
|
||||||
lnno = lineno->l_lnno;
|
|
||||||
if (lnno == 0)
|
|
||||||
break;
|
|
||||||
|
|
||||||
/* 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. */
|
|
||||||
incl = (struct xcoff_incl *) bsearch (&lnnoptr, vec->vec.base,
|
|
||||||
vec->count,
|
|
||||||
sizeof (struct xcoff_incl),
|
|
||||||
xcoff_incl_search);
|
|
||||||
if (begincl == -1)
|
|
||||||
begincl = incl != NULL;
|
|
||||||
if (incl != NULL)
|
|
||||||
{
|
|
||||||
filename = incl->filename;
|
|
||||||
if (begincl == 1)
|
|
||||||
lnno += fcn_lnno - 1;
|
|
||||||
}
|
|
||||||
else
|
|
||||||
lnno += fcn_lnno - 1;
|
|
||||||
|
|
||||||
pc = base_address + lineno->l_addr.l_paddr
|
|
||||||
- sects[fsym->n_scnum - 1].s_paddr;
|
|
||||||
xcoff_add_line (state, pc, filename, function, lnno, error_callback,
|
|
||||||
data, lvec);
|
|
||||||
|
|
||||||
lnnoptr += LINESZ;
|
|
||||||
lineptr += LINESZ;
|
|
||||||
}
|
|
||||||
|
|
||||||
return 1;
|
|
||||||
}
|
|
||||||
|
|
||||||
/* Initialize the line vector info for xcoff_fileline. */
|
|
||||||
|
|
||||||
static int
|
static int
|
||||||
xcoff_initialize_fileline (struct backtrace_state *state,
|
xcoff_initialize_fileline (struct backtrace_state *state,
|
||||||
|
@ -912,15 +882,15 @@ xcoff_initialize_fileline (struct backtrace_state *state,
|
||||||
backtrace_error_callback error_callback, void *data)
|
backtrace_error_callback error_callback, void *data)
|
||||||
{
|
{
|
||||||
struct xcoff_fileline_data *fdata;
|
struct xcoff_fileline_data *fdata;
|
||||||
struct xcoff_incl_vector vec;
|
struct xcoff_func *fn;
|
||||||
struct xcoff_line *ln;
|
|
||||||
const b_xcoff_syment *fsym;
|
const b_xcoff_syment *fsym;
|
||||||
const b_xcoff_auxent *aux;
|
const b_xcoff_auxent *aux;
|
||||||
const char *filename;
|
const char *filename;
|
||||||
const char *name;
|
const char *name;
|
||||||
struct xcoff_incl *incl;
|
struct xcoff_incl *incl;
|
||||||
uintptr_t begin, end;
|
uintptr_t begin, end;
|
||||||
uintptr_t lnno;
|
uintptr_t lnno, lnnoptr;
|
||||||
|
uint32_t fsize;
|
||||||
size_t i;
|
size_t i;
|
||||||
|
|
||||||
fdata = ((struct xcoff_fileline_data *)
|
fdata = ((struct xcoff_fileline_data *)
|
||||||
|
@ -928,13 +898,17 @@ xcoff_initialize_fileline (struct backtrace_state *state,
|
||||||
error_callback, data));
|
error_callback, data));
|
||||||
if (fdata == NULL)
|
if (fdata == NULL)
|
||||||
return 0;
|
return 0;
|
||||||
|
|
||||||
memset (fdata, 0, sizeof *fdata);
|
memset (fdata, 0, sizeof *fdata);
|
||||||
memset (&vec, 0, sizeof vec);
|
fdata->base_address = base_address;
|
||||||
|
fdata->linenos = linenos;
|
||||||
/* Process include files first. */
|
fdata->linenos_size = linenos_size;
|
||||||
|
fdata->lnnoptr0 = lnnoptr0;
|
||||||
|
|
||||||
begin = 0;
|
begin = 0;
|
||||||
|
filename = NULL;
|
||||||
|
fsym = NULL;
|
||||||
|
lnnoptr = 0;
|
||||||
|
fsize = 0;
|
||||||
for (i = 0; i < nsyms; ++i)
|
for (i = 0; i < nsyms; ++i)
|
||||||
{
|
{
|
||||||
const b_xcoff_syment *asym = &syms[i];
|
const b_xcoff_syment *asym = &syms[i];
|
||||||
|
@ -951,32 +925,18 @@ xcoff_initialize_fileline (struct backtrace_state *state,
|
||||||
end = asym->n_value;
|
end = asym->n_value;
|
||||||
incl = ((struct xcoff_incl *)
|
incl = ((struct xcoff_incl *)
|
||||||
backtrace_vector_grow (state, sizeof (struct xcoff_incl),
|
backtrace_vector_grow (state, sizeof (struct xcoff_incl),
|
||||||
error_callback, data, &vec.vec));
|
error_callback, data,
|
||||||
|
&fdata->incl_vec.vec));
|
||||||
if (incl != NULL)
|
if (incl != NULL)
|
||||||
{
|
{
|
||||||
incl->filename = xcoff_symname (asym, strtab, strtab_size);
|
incl->filename = xcoff_symname (asym, strtab, strtab_size);
|
||||||
incl->begin = begin;
|
incl->begin = begin;
|
||||||
incl->end = end;
|
incl->end = end;
|
||||||
++vec.count;
|
++fdata->incl_vec.count;
|
||||||
}
|
}
|
||||||
begin = 0;
|
begin = 0;
|
||||||
break;
|
break;
|
||||||
}
|
|
||||||
|
|
||||||
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)
|
|
||||||
{
|
|
||||||
const b_xcoff_syment *asym = &syms[i];
|
|
||||||
|
|
||||||
switch (asym->n_sclass)
|
|
||||||
{
|
|
||||||
case C_FILE:
|
case C_FILE:
|
||||||
filename = xcoff_symname (asym, strtab, strtab_size);
|
filename = xcoff_symname (asym, strtab, strtab_size);
|
||||||
if (filename == NULL)
|
if (filename == NULL)
|
||||||
|
@ -988,7 +948,7 @@ xcoff_initialize_fileline (struct backtrace_state *state,
|
||||||
file auxiliary entry (by convention) contains the source
|
file auxiliary entry (by convention) contains the source
|
||||||
file name. */
|
file name. */
|
||||||
|
|
||||||
if (asym->n_numaux > 0 && !strcmp (filename, ".file"))
|
if (asym->n_numaux > 0 && strcmp (filename, ".file") == 0)
|
||||||
{
|
{
|
||||||
aux = (const b_xcoff_auxent *) (asym + 1);
|
aux = (const b_xcoff_auxent *) (asym + 1);
|
||||||
if (aux->x_file._x.x_zeroes != 0)
|
if (aux->x_file._x.x_zeroes != 0)
|
||||||
|
@ -1010,10 +970,20 @@ xcoff_initialize_fileline (struct backtrace_state *state,
|
||||||
case C_HIDEXT:
|
case C_HIDEXT:
|
||||||
case C_WEAKEXT:
|
case C_WEAKEXT:
|
||||||
fsym = NULL;
|
fsym = NULL;
|
||||||
if (!ISFCN (asym->n_type) || asym->n_numaux == 0)
|
lnnoptr = 0;
|
||||||
|
fsize = 0;
|
||||||
|
if (!ISFCN (asym->n_type) || asym->n_numaux == 0
|
||||||
|
|| asym->n_scnum <= 0)
|
||||||
break;
|
break;
|
||||||
if (filename == NULL)
|
if (filename == NULL)
|
||||||
break;
|
break;
|
||||||
|
aux = (const b_xcoff_auxent *) (asym + 1);
|
||||||
|
lnnoptr = aux->x_fcn.x_lnnoptr;
|
||||||
|
if (lnnoptr < lnnoptr0
|
||||||
|
|| lnnoptr + LINESZ > lnnoptr0 + linenos_size)
|
||||||
|
break;
|
||||||
|
/* x_fsize will be 0 if there is no debug information. */
|
||||||
|
fsize = aux->x_fcn.x_fsize;
|
||||||
fsym = asym;
|
fsym = asym;
|
||||||
break;
|
break;
|
||||||
|
|
||||||
|
@ -1023,8 +993,11 @@ xcoff_initialize_fileline (struct backtrace_state *state,
|
||||||
if (fsym == NULL)
|
if (fsym == NULL)
|
||||||
break;
|
break;
|
||||||
name = xcoff_symname (asym, strtab, strtab_size);
|
name = xcoff_symname (asym, strtab, strtab_size);
|
||||||
if (name == NULL)
|
if (name == NULL || strcmp (name, ".bf") != 0)
|
||||||
break;
|
{
|
||||||
|
fsym = NULL;
|
||||||
|
break;
|
||||||
|
}
|
||||||
aux = (const b_xcoff_auxent *) (asym + 1);
|
aux = (const b_xcoff_auxent *) (asym + 1);
|
||||||
#if BACKTRACE_XCOFF_SIZE == 32
|
#if BACKTRACE_XCOFF_SIZE == 32
|
||||||
lnno = (uint32_t) aux->x_block.x_lnnohi << 16
|
lnno = (uint32_t) aux->x_block.x_lnnohi << 16
|
||||||
|
@ -1032,39 +1005,37 @@ xcoff_initialize_fileline (struct backtrace_state *state,
|
||||||
#else
|
#else
|
||||||
lnno = aux->x_block.x_lnno;
|
lnno = aux->x_block.x_lnno;
|
||||||
#endif
|
#endif
|
||||||
if (!strcmp (name, ".bf"))
|
fn = ((struct xcoff_func *)
|
||||||
{
|
backtrace_vector_grow (state, sizeof (struct xcoff_func),
|
||||||
xcoff_process_linenos (state, base_address, fsym, filename,
|
error_callback, data,
|
||||||
sects, strtab, strtab_size, lnno, &vec,
|
&fdata->func_vec.vec));
|
||||||
&fdata->vec, linenos, linenos_size,
|
if (fn == NULL)
|
||||||
lnnoptr0, error_callback, data);
|
break;
|
||||||
}
|
fn->name = xcoff_symname (fsym, strtab, strtab_size);
|
||||||
else if (!strcmp (name, ".ef"))
|
fn->filename = filename;
|
||||||
{
|
fn->sect_base = sects[fsym->n_scnum - 1].s_paddr;
|
||||||
fsym = NULL;
|
fn->pc = base_address + fsym->n_value - fn->sect_base;
|
||||||
}
|
fn->size = fsize;
|
||||||
|
fn->lnno = lnno;
|
||||||
|
fn->lnnoptr = lnnoptr;
|
||||||
|
++fdata->func_vec.count;
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
|
||||||
i += asym->n_numaux;
|
i += asym->n_numaux;
|
||||||
}
|
}
|
||||||
|
|
||||||
/* Allocate one extra entry at the end. */
|
if (!backtrace_vector_release (state, &fdata->func_vec.vec, error_callback,
|
||||||
ln = ((struct xcoff_line *)
|
data))
|
||||||
backtrace_vector_grow (state, sizeof (struct xcoff_line),
|
|
||||||
error_callback, data, &fdata->vec.vec));
|
|
||||||
if (ln == NULL)
|
|
||||||
goto fail;
|
goto fail;
|
||||||
ln->pc = (uintptr_t) -1;
|
backtrace_qsort (fdata->func_vec.vec.base, fdata->func_vec.count,
|
||||||
ln->filename = NULL;
|
sizeof (struct xcoff_func), xcoff_func_compare);
|
||||||
ln->function = NULL;
|
|
||||||
ln->lineno = 0;
|
|
||||||
|
|
||||||
if (!backtrace_vector_release (state, &fdata->vec.vec, error_callback, data))
|
if (!backtrace_vector_release (state, &fdata->incl_vec.vec, error_callback,
|
||||||
|
data))
|
||||||
goto fail;
|
goto fail;
|
||||||
|
backtrace_qsort (fdata->incl_vec.vec.base, fdata->incl_vec.count,
|
||||||
backtrace_qsort (fdata->vec.vec.base, fdata->vec.count,
|
sizeof (struct xcoff_incl), xcoff_incl_compare);
|
||||||
sizeof (struct xcoff_line), xcoff_line_compare);
|
|
||||||
|
|
||||||
if (!state->threaded)
|
if (!state->threaded)
|
||||||
{
|
{
|
||||||
|
@ -1354,6 +1325,7 @@ xcoff_add (struct backtrace_state *state, int descriptor, off_t offset,
|
||||||
{
|
{
|
||||||
size_t linenos_size = (size_t) nlnno * LINESZ;
|
size_t linenos_size = (size_t) nlnno * LINESZ;
|
||||||
|
|
||||||
|
/* We never release this view. */
|
||||||
if (!backtrace_get_view (state, descriptor, offset + lnnoptr,
|
if (!backtrace_get_view (state, descriptor, offset + lnnoptr,
|
||||||
linenos_size,
|
linenos_size,
|
||||||
error_callback, data, &linenos_view))
|
error_callback, data, &linenos_view))
|
||||||
|
@ -1366,9 +1338,6 @@ xcoff_add (struct backtrace_state *state, int descriptor, off_t offset,
|
||||||
linenos_view.data, linenos_size,
|
linenos_view.data, linenos_size,
|
||||||
lnnoptr, error_callback, data))
|
lnnoptr, error_callback, data))
|
||||||
*fileline_fn = xcoff_fileline;
|
*fileline_fn = xcoff_fileline;
|
||||||
|
|
||||||
backtrace_release_view (state, &linenos_view, error_callback, data);
|
|
||||||
linenos_view_valid = 0;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
backtrace_release_view (state, §s_view, error_callback, data);
|
backtrace_release_view (state, §s_view, error_callback, data);
|
||||||
|
|
Loading…
Add table
Reference in a new issue