This is the mail archive of the
binutils@sourceware.org
mailing list for the binutils project.
Re: Segfault in objdump?
- From: Alan Modra <amodra at gmail dot com>
- To: binutils at sourceware dot org
- Date: Tue, 24 Sep 2013 16:28:39 +0930
- Subject: Re: Segfault in objdump?
- Authentication-results: sourceware.org; auth=none
- References: <20130601102116 dot 53e02e09 at cyssor> <20130602045333 dot GQ6878 at bubble dot grove dot modra dot org> <20130602144028 dot 44f528d1 at cyssor> <20130602230635 dot GR6878 at bubble dot grove dot modra dot org> <20130602162955 dot 0f82b1a3 at cyssor> <20130603005909 dot GS6878 at bubble dot grove dot modra dot org> <20130603040605 dot GT6878 at bubble dot grove dot modra dot org>
When writing https://sourceware.org/ml/binutils/2013-06/msg00005.html
I noticed that the initial loop sizing the entry table didn't exactly
match the loop filling the table. This patch corrects that problem,
and makes sure we terminate the table in an odd corner case.
* syms.c (_bfd_stab_section_find_nearest_line): Ignore partial
stabs at end of .stab. Tidy variable usage. Don't drop the need
for a NULL function name stab if If N_FUN stab is ignored.
Ensure index entry count loop matches write loop.
Index: bfd/syms.c
===================================================================
RCS file: /cvs/src/src/bfd/syms.c,v
retrieving revision 1.59
diff -u -p -r1.59 syms.c
--- bfd/syms.c 3 Jun 2013 04:11:09 -0000 1.59
+++ bfd/syms.c 3 Jun 2013 11:27:46 -0000
@@ -934,12 +934,11 @@ _bfd_stab_section_find_nearest_line (bfd
struct stab_find_info *info;
bfd_size_type stabsize, strsize;
bfd_byte *stab, *str;
- bfd_byte *last_stab, *last_str;
+ bfd_byte *nul_fun, *nul_str;
bfd_size_type stroff;
struct indexentry *indexentry;
char *file_name;
char *directory_name;
- int saw_fun;
bfd_boolean saw_line, saw_func;
*pfound = FALSE;
@@ -988,7 +987,6 @@ _bfd_stab_section_find_nearest_line (bfd
long reloc_size, reloc_count;
arelent **reloc_vector;
int i;
- char *name;
char *function_name;
bfd_size_type amt = sizeof *info;
@@ -1021,6 +1019,7 @@ _bfd_stab_section_find_nearest_line (bfd
stabsize = (info->stabsec->rawsize
? info->stabsec->rawsize
: info->stabsec->size);
+ stabsize = (stabsize / STABSIZE) * STABSIZE;
strsize = (info->strsec->rawsize
? info->strsec->rawsize
: info->strsec->size);
@@ -1102,36 +1101,37 @@ _bfd_stab_section_find_nearest_line (bfd
table. */
info->indextablesize = 0;
- saw_fun = 1;
+ nul_fun = NULL;
for (stab = info->stabs; stab < info->stabs + stabsize; stab += STABSIZE)
{
if (stab[TYPEOFF] == (bfd_byte) N_SO)
{
- /* N_SO with null name indicates EOF */
- if (bfd_get_32 (abfd, stab + STRDXOFF) == 0)
- continue;
-
/* if we did not see a function def, leave space for one. */
- if (saw_fun == 0)
+ if (nul_fun != NULL)
++info->indextablesize;
- saw_fun = 0;
-
- /* two N_SO's in a row is a filename and directory. Skip */
- if (stab + STABSIZE < info->stabs + stabsize
- && *(stab + STABSIZE + TYPEOFF) == (bfd_byte) N_SO)
+ /* N_SO with null name indicates EOF */
+ if (bfd_get_32 (abfd, stab + STRDXOFF) == 0)
+ nul_fun = NULL;
+ else
{
- stab += STABSIZE;
+ nul_fun = stab;
+
+ /* two N_SO's in a row is a filename and directory. Skip */
+ if (stab + STABSIZE + TYPEOFF < info->stabs + stabsize
+ && *(stab + STABSIZE + TYPEOFF) == (bfd_byte) N_SO)
+ stab += STABSIZE;
}
}
- else if (stab[TYPEOFF] == (bfd_byte) N_FUN)
+ else if (stab[TYPEOFF] == (bfd_byte) N_FUN
+ && bfd_get_32 (abfd, stab + STRDXOFF) != 0)
{
- saw_fun = 1;
+ nul_fun = NULL;
++info->indextablesize;
}
}
- if (saw_fun == 0)
+ if (nul_fun != NULL)
++info->indextablesize;
if (info->indextablesize == 0)
@@ -1146,10 +1146,10 @@ _bfd_stab_section_find_nearest_line (bfd
file_name = NULL;
directory_name = NULL;
- saw_fun = 1;
+ nul_fun = NULL;
stroff = 0;
- for (i = 0, last_stab = stab = info->stabs, last_str = str = info->strs;
+ for (i = 0, stab = info->stabs, nul_str = str = info->strs;
i < info->indextablesize && stab < info->stabs + stabsize;
stab += STABSIZE)
{
@@ -1171,35 +1171,30 @@ _bfd_stab_section_find_nearest_line (bfd
Note that a N_SO without a file name is an EOF and
there could be 2 N_SO following it with the new filename
and directory. */
- if (saw_fun == 0)
+ if (nul_fun != NULL)
{
- info->indextable[i].val = bfd_get_32 (abfd, last_stab + VALOFF);
- info->indextable[i].stab = last_stab;
- info->indextable[i].str = last_str;
+ info->indextable[i].val = bfd_get_32 (abfd, nul_fun + VALOFF);
+ info->indextable[i].stab = nul_fun;
+ info->indextable[i].str = nul_str;
info->indextable[i].directory_name = directory_name;
info->indextable[i].file_name = file_name;
info->indextable[i].function_name = NULL;
++i;
}
- saw_fun = 0;
+ directory_name = NULL;
file_name = (char *) str + bfd_get_32 (abfd, stab + STRDXOFF);
- if (*file_name == '\0')
+ if (file_name == (char *) str)
{
- directory_name = NULL;
file_name = NULL;
- saw_fun = 1;
+ nul_fun = NULL;
}
else
{
- last_stab = stab;
- last_str = str;
- if (stab + STABSIZE >= info->stabs + stabsize
- || *(stab + STABSIZE + TYPEOFF) != (bfd_byte) N_SO)
- {
- directory_name = NULL;
- }
- else
+ nul_fun = stab;
+ nul_str = str;
+ if (stab + STABSIZE + TYPEOFF < info->stabs + stabsize
+ && *(stab + STABSIZE + TYPEOFF) == (bfd_byte) N_SO)
{
/* Two consecutive N_SOs are a directory and a
file name. */
@@ -1218,17 +1213,11 @@ _bfd_stab_section_find_nearest_line (bfd
case N_FUN:
/* A function name. */
- saw_fun = 1;
- name = (char *) str + bfd_get_32 (abfd, stab + STRDXOFF);
-
- if (*name == '\0')
- name = NULL;
-
- function_name = name;
-
- if (name == NULL)
+ function_name = (char *) str + bfd_get_32 (abfd, stab + STRDXOFF);
+ if (function_name == (char *) str)
continue;
+ nul_fun = NULL;
info->indextable[i].val = bfd_get_32 (abfd, stab + VALOFF);
info->indextable[i].stab = stab;
info->indextable[i].str = str;
@@ -1240,11 +1229,11 @@ _bfd_stab_section_find_nearest_line (bfd
}
}
- if (saw_fun == 0)
+ if (nul_fun != NULL)
{
- info->indextable[i].val = bfd_get_32 (abfd, last_stab + VALOFF);
- info->indextable[i].stab = last_stab;
- info->indextable[i].str = last_str;
+ info->indextable[i].val = bfd_get_32 (abfd, nul_fun + VALOFF);
+ info->indextable[i].stab = nul_fun;
+ info->indextable[i].str = nul_str;
info->indextable[i].directory_name = directory_name;
info->indextable[i].file_name = file_name;
info->indextable[i].function_name = NULL;
--
Alan Modra
Australia Development Lab, IBM