/* Generic symbol-table support for the BFD library.
- Copyright 1990, 1991, 1992, 1993, 1994, 1995, 1996, 1997, 1998, 1999,
- 2000, 2001, 2002, 2003, 2004, 2005, 2007, 2008, 2009
- Free Software Foundation, Inc.
+ Copyright (C) 1990-2015 Free Software Foundation, Inc.
Written by Cygnus Support.
This file is part of BFD, the Binary File Descriptor library.
|
| if (storage_needed == 0)
| return;
-|
+|
| symbol_table = xmalloc (storage_needed);
| ...
| number_of_symbols =
which has been created using <<bfd_make_empty_symbol>>. Here is an
example showing the creation of a symbol table with only one element:
+| #include "sysdep.h"
| #include "bfd.h"
| int main (void)
| {
*minisymsp = syms;
*sizep = sizeof (asymbol *);
+
return symcount;
error_return:
struct stab_find_info *info;
bfd_size_type stabsize, strsize;
bfd_byte *stab, *str;
- bfd_byte *last_stab = NULL;
+ 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;
long reloc_size, reloc_count;
arelent **reloc_vector;
int i;
- char *name;
char *function_name;
bfd_size_type amt = sizeof *info;
/* Try SOM section names. */
info->stabsec = bfd_get_section_by_name (abfd, "$GDB_SYMBOLS$");
info->strsec = bfd_get_section_by_name (abfd, "$GDB_STRINGS$");
-
+
if (info->stabsec == NULL || info->strsec == NULL)
{
/* No stabs debugging information. Set *pinfo so that we
stabsize = (info->stabsec->rawsize
? info->stabsec->rawsize
: info->stabsec->size);
+ stabsize = (stabsize / STABSIZE) * STABSIZE;
strsize = (info->strsec->rawsize
? info->strsec->rawsize
: info->strsec->size);
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)
file_name = NULL;
directory_name = NULL;
- saw_fun = 1;
+ nul_fun = NULL;
+ stroff = 0;
- for (i = 0, stroff = 0, stab = info->stabs, str = info->strs;
+ for (i = 0, stab = info->stabs, nul_str = str = info->strs;
i < info->indextablesize && stab < info->stabs + stabsize;
stab += STABSIZE)
{
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 = 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;
- if (stab + STABSIZE >= info->stabs + stabsize
- || *(stab + STABSIZE + TYPEOFF) != (bfd_byte) N_SO)
- {
- directory_name = NULL;
- }
- else
+ nul_fun = stab;
+ nul_str = str;
+ if (file_name >= (char *) info->strs + strsize || file_name < (char *) str)
+ file_name = NULL;
+ 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. */
directory_name = file_name;
file_name = ((char *) str
+ bfd_get_32 (abfd, stab + STRDXOFF));
+ if (file_name >= (char *) info->strs + strsize || file_name < (char *) str)
+ file_name = NULL;
}
}
break;
case N_SOL:
/* The name of an include file. */
file_name = (char *) str + bfd_get_32 (abfd, stab + STRDXOFF);
+ /* PR 17512: file: 0c680a1f. */
+ /* PR 17512: file: 5da8aec4. */
+ if (file_name >= (char *) info->strs + strsize || file_name < (char *) str)
+ file_name = NULL;
break;
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;
+ if (function_name >= (char *) info->strs + strsize)
+ function_name = NULL;
+ nul_fun = NULL;
info->indextable[i].val = bfd_get_32 (abfd, stab + VALOFF);
info->indextable[i].stab = stab;
info->indextable[i].str = str;
}
}
- 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 = 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;
if (val <= offset)
{
file_name = (char *) str + bfd_get_32 (abfd, stab + STRDXOFF);
+ if (file_name >= (char *) info->strs + strsize || file_name < (char *) str)
+ file_name = NULL;
*pline = 0;
}
break;