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>
|
||||
|
||||
PR other/86198
|
||||
|
|
|
@ -338,27 +338,32 @@ struct xcoff_incl_vector
|
|||
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. */
|
||||
uintptr_t pc;
|
||||
/* File name. Many entries in the array are expected to point to
|
||||
the same file name. */
|
||||
const char *filename;
|
||||
/* The size of the function. */
|
||||
size_t size;
|
||||
/* Function name. */
|
||||
const char *function;
|
||||
/* Line number. */
|
||||
int lineno;
|
||||
const char *name;
|
||||
/* File name. */
|
||||
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
|
||||
reading the line numbers. */
|
||||
/* A growable vector of function information. This is used while
|
||||
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;
|
||||
/* Number of valid mappings. */
|
||||
size_t count;
|
||||
|
@ -370,8 +375,16 @@ struct xcoff_fileline_data
|
|||
{
|
||||
/* The data for the next file we know about. */
|
||||
struct xcoff_fileline_data *next;
|
||||
/* Line number information. */
|
||||
struct xcoff_line_vector vec;
|
||||
/* Functions information. */
|
||||
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. */
|
||||
|
@ -509,6 +522,7 @@ xcoff_syminfo (struct backtrace_state *state ATTRIBUTE_UNUSED, uintptr_t addr,
|
|||
{
|
||||
struct xcoff_syminfo_data *edata;
|
||||
struct xcoff_symbol *sym = NULL;
|
||||
const char *name;
|
||||
|
||||
if (!state->threaded)
|
||||
{
|
||||
|
@ -547,7 +561,13 @@ xcoff_syminfo (struct backtrace_state *state ATTRIBUTE_UNUSED, uintptr_t addr,
|
|||
if (sym == NULL)
|
||||
callback (data, addr, NULL, 0, 0);
|
||||
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. */
|
||||
|
@ -640,43 +660,76 @@ xcoff_initialize_syminfo (struct backtrace_state *state,
|
|||
return 1;
|
||||
}
|
||||
|
||||
/* Compare struct xcoff_line for qsort. */
|
||||
/* Compare struct xcoff_func for qsort. */
|
||||
|
||||
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_line *ln2 = (const struct xcoff_line *) v2;
|
||||
const struct xcoff_func *fn1 = (const struct xcoff_func *) v1;
|
||||
const struct xcoff_func *fn2 = (const struct xcoff_func *) v2;
|
||||
|
||||
if (ln1->pc < ln2->pc)
|
||||
if (fn1->pc < fn2->pc)
|
||||
return -1;
|
||||
else if (ln1->pc > ln2->pc)
|
||||
else if (fn1->pc > fn2->pc)
|
||||
return 1;
|
||||
else
|
||||
return 0;
|
||||
}
|
||||
|
||||
/* Find a PC in a line vector. We always allocate an extra entry at
|
||||
the end of the lines vector, so that this routine can safely look
|
||||
at the next entry. */
|
||||
/* Compare a PC against an xcoff_func for bsearch. */
|
||||
|
||||
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 struct xcoff_line *entry = (const struct xcoff_line *) ventry;
|
||||
const struct xcoff_func *entry = (const struct xcoff_func *) ventry;
|
||||
uintptr_t pc;
|
||||
|
||||
pc = *key;
|
||||
if (pc < entry->pc)
|
||||
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;
|
||||
else
|
||||
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
|
||||
ERROR_CALLBACK and return 0. Sets *FOUND to 1 if the PC is found,
|
||||
0 if not. */
|
||||
|
@ -688,26 +741,82 @@ xcoff_lookup_pc (struct backtrace_state *state ATTRIBUTE_UNUSED,
|
|||
backtrace_error_callback error_callback ATTRIBUTE_UNUSED,
|
||||
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 *filename;
|
||||
uintptr_t lnnoptr, match;
|
||||
uint32_t lnno = 0;
|
||||
|
||||
*found = 1;
|
||||
|
||||
ln = (struct xcoff_line *) bsearch (&pc, fdata->vec.vec.base,
|
||||
fdata->vec.count,
|
||||
sizeof (struct xcoff_line),
|
||||
xcoff_line_search);
|
||||
if (ln == NULL)
|
||||
if ((pc & 3) != 0)
|
||||
++pc;
|
||||
|
||||
/* Find the function first. */
|
||||
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;
|
||||
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. */
|
||||
if (*function == '.')
|
||||
if (function != NULL && *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
|
||||
|
@ -760,146 +869,7 @@ 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. */
|
||||
|
||||
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. */
|
||||
/* Initialize the function vector info for xcoff_fileline. */
|
||||
|
||||
static int
|
||||
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)
|
||||
{
|
||||
struct xcoff_fileline_data *fdata;
|
||||
struct xcoff_incl_vector vec;
|
||||
struct xcoff_line *ln;
|
||||
struct xcoff_func *fn;
|
||||
const b_xcoff_syment *fsym;
|
||||
const b_xcoff_auxent *aux;
|
||||
const char *filename;
|
||||
const char *name;
|
||||
struct xcoff_incl *incl;
|
||||
uintptr_t begin, end;
|
||||
uintptr_t lnno;
|
||||
uintptr_t lnno, lnnoptr;
|
||||
uint32_t fsize;
|
||||
size_t i;
|
||||
|
||||
fdata = ((struct xcoff_fileline_data *)
|
||||
|
@ -928,13 +898,17 @@ xcoff_initialize_fileline (struct backtrace_state *state,
|
|||
error_callback, data));
|
||||
if (fdata == NULL)
|
||||
return 0;
|
||||
|
||||
memset (fdata, 0, sizeof *fdata);
|
||||
memset (&vec, 0, sizeof vec);
|
||||
|
||||
/* Process include files first. */
|
||||
fdata->base_address = base_address;
|
||||
fdata->linenos = linenos;
|
||||
fdata->linenos_size = linenos_size;
|
||||
fdata->lnnoptr0 = lnnoptr0;
|
||||
|
||||
begin = 0;
|
||||
filename = NULL;
|
||||
fsym = NULL;
|
||||
lnnoptr = 0;
|
||||
fsize = 0;
|
||||
for (i = 0; i < nsyms; ++i)
|
||||
{
|
||||
const b_xcoff_syment *asym = &syms[i];
|
||||
|
@ -951,32 +925,18 @@ xcoff_initialize_fileline (struct backtrace_state *state,
|
|||
end = asym->n_value;
|
||||
incl = ((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)
|
||||
{
|
||||
incl->filename = xcoff_symname (asym, strtab, strtab_size);
|
||||
incl->begin = begin;
|
||||
incl->end = end;
|
||||
++vec.count;
|
||||
++fdata->incl_vec.count;
|
||||
}
|
||||
begin = 0;
|
||||
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:
|
||||
filename = xcoff_symname (asym, strtab, strtab_size);
|
||||
if (filename == NULL)
|
||||
|
@ -988,7 +948,7 @@ xcoff_initialize_fileline (struct backtrace_state *state,
|
|||
file auxiliary entry (by convention) contains the source
|
||||
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);
|
||||
if (aux->x_file._x.x_zeroes != 0)
|
||||
|
@ -1010,10 +970,20 @@ xcoff_initialize_fileline (struct backtrace_state *state,
|
|||
case C_HIDEXT:
|
||||
case C_WEAKEXT:
|
||||
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;
|
||||
if (filename == NULL)
|
||||
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;
|
||||
break;
|
||||
|
||||
|
@ -1023,8 +993,11 @@ xcoff_initialize_fileline (struct backtrace_state *state,
|
|||
if (fsym == NULL)
|
||||
break;
|
||||
name = xcoff_symname (asym, strtab, strtab_size);
|
||||
if (name == NULL)
|
||||
break;
|
||||
if (name == NULL || strcmp (name, ".bf") != 0)
|
||||
{
|
||||
fsym = NULL;
|
||||
break;
|
||||
}
|
||||
aux = (const b_xcoff_auxent *) (asym + 1);
|
||||
#if BACKTRACE_XCOFF_SIZE == 32
|
||||
lnno = (uint32_t) aux->x_block.x_lnnohi << 16
|
||||
|
@ -1032,39 +1005,37 @@ xcoff_initialize_fileline (struct backtrace_state *state,
|
|||
#else
|
||||
lnno = aux->x_block.x_lnno;
|
||||
#endif
|
||||
if (!strcmp (name, ".bf"))
|
||||
{
|
||||
xcoff_process_linenos (state, base_address, fsym, filename,
|
||||
sects, strtab, strtab_size, lnno, &vec,
|
||||
&fdata->vec, linenos, linenos_size,
|
||||
lnnoptr0, error_callback, data);
|
||||
}
|
||||
else if (!strcmp (name, ".ef"))
|
||||
{
|
||||
fsym = NULL;
|
||||
}
|
||||
fn = ((struct xcoff_func *)
|
||||
backtrace_vector_grow (state, sizeof (struct xcoff_func),
|
||||
error_callback, data,
|
||||
&fdata->func_vec.vec));
|
||||
if (fn == NULL)
|
||||
break;
|
||||
fn->name = xcoff_symname (fsym, strtab, strtab_size);
|
||||
fn->filename = filename;
|
||||
fn->sect_base = sects[fsym->n_scnum - 1].s_paddr;
|
||||
fn->pc = base_address + fsym->n_value - fn->sect_base;
|
||||
fn->size = fsize;
|
||||
fn->lnno = lnno;
|
||||
fn->lnnoptr = lnnoptr;
|
||||
++fdata->func_vec.count;
|
||||
break;
|
||||
}
|
||||
|
||||
i += asym->n_numaux;
|
||||
}
|
||||
|
||||
/* Allocate one extra entry at the end. */
|
||||
ln = ((struct xcoff_line *)
|
||||
backtrace_vector_grow (state, sizeof (struct xcoff_line),
|
||||
error_callback, data, &fdata->vec.vec));
|
||||
if (ln == NULL)
|
||||
if (!backtrace_vector_release (state, &fdata->func_vec.vec, error_callback,
|
||||
data))
|
||||
goto fail;
|
||||
ln->pc = (uintptr_t) -1;
|
||||
ln->filename = NULL;
|
||||
ln->function = NULL;
|
||||
ln->lineno = 0;
|
||||
backtrace_qsort (fdata->func_vec.vec.base, fdata->func_vec.count,
|
||||
sizeof (struct xcoff_func), xcoff_func_compare);
|
||||
|
||||
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;
|
||||
|
||||
backtrace_qsort (fdata->vec.vec.base, fdata->vec.count,
|
||||
sizeof (struct xcoff_line), xcoff_line_compare);
|
||||
backtrace_qsort (fdata->incl_vec.vec.base, fdata->incl_vec.count,
|
||||
sizeof (struct xcoff_incl), xcoff_incl_compare);
|
||||
|
||||
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;
|
||||
|
||||
/* We never release this view. */
|
||||
if (!backtrace_get_view (state, descriptor, offset + lnnoptr,
|
||||
linenos_size,
|
||||
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,
|
||||
lnnoptr, error_callback, data))
|
||||
*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);
|
||||
|
|
Loading…
Add table
Reference in a new issue