#include "defs.h"
#include "bfd.h"
#include "symtab.h"
#include "symfile.h"
#include "objfiles.h"
#include "gdb-stabs.h"
#include "target.h"
#include "gdbcmd.h"
#include "bcache.h"
#include "mdebugread.h"
#include "gdb_assert.h"
#include <sys/types.h>
#include "gdb_stat.h"
#include <fcntl.h>
#include "gdb_obstack.h"
#include "gdb_string.h"
#include "buildsym.h"
#include "hashtab.h"
#include "varobj.h"
#include "breakpoint.h"
#include "block.h"
#include "dictionary.h"
#include "db-access-functions.h"
#ifdef MACOSX_DYLD
#include "inferior.h"
#include "macosx-nat-dyld.h"
#include "mach-o.h"
#endif
static void objfile_alloc_data (struct objfile *objfile);
static void objfile_free_data (struct objfile *objfile);
struct objfile *create_objfile (bfd *abfd);
struct objfile *create_objfile_using_objfile (struct objfile *objfile, bfd *abfd);
static void objfile_remove_from_restrict_list (struct objfile *);
static char *cached_symfile_path = NULL;
int mapped_symbol_files = 0;
int use_mapped_symbol_files = 0;
extern struct cmd_list_element *setshliblist;
extern struct cmd_list_element *showshliblist;
extern struct cmd_list_element *infoshliblist;
extern struct cmd_list_element *shliblist;
#ifndef TEXT_SECTION_NAME
#define TEXT_SECTION_NAME ".text"
#endif
#ifndef DATA_SECTION_NAME
#define DATA_SECTION_NAME ".data"
#endif
struct objfile *object_files;
struct objfile *current_objfile;
struct objfile *symfile_objfile;
struct objfile *rt_common_objfile;
#ifndef TARGET_KEEP_SECTION
#define TARGET_KEEP_SECTION(ASECT) 0
#endif
struct ordered_obj_section
{
struct obj_section *obj_section;
struct bfd_section *the_bfd_section;
CORE_ADDR addr;
CORE_ADDR endaddr;
};
static struct ordered_obj_section *ordered_sections;
static int num_ordered_sections = 0;
#define ORDERED_SECTIONS_CHUNK_SIZE 3000
static int max_num_ordered_sections = ORDERED_SECTIONS_CHUNK_SIZE;
static int find_in_ordered_sections_index (CORE_ADDR addr, struct bfd_section *bfd_section);
static int get_insert_index_in_ordered_sections (struct obj_section *section);
struct obj_section_with_index
{
int index;
struct obj_section *section;
};
#if 0
static void
add_to_objfile_sections (struct bfd *abfd, struct bfd_section *asect,
void *objfile_p_char)
{
struct objfile *objfile = (struct objfile *) objfile_p_char;
struct obj_section section;
flagword aflag;
aflag = bfd_get_section_flags (abfd, asect);
if (!(aflag & SEC_ALLOC) && !(TARGET_KEEP_SECTION (asect)))
return;
if (0 == bfd_section_size (abfd, asect))
return;
section.offset = 0;
section.objfile = objfile;
section.the_bfd_section = asect;
section.ovly_mapped = 0;
section.addr = bfd_section_vma (abfd, asect);
section.endaddr = section.addr + bfd_section_size (abfd, asect);
obstack_grow (&objfile->objfile_obstack, (char *) §ion, sizeof (section));
objfile->sections_end = (struct obj_section *) (((unsigned long) objfile->sections_end) + 1);
}
#endif
int
objfile_keeps_section (bfd *abfd, asection *asect)
{
flagword aflag;
aflag = bfd_get_section_flags (abfd, asect);
if (!(aflag & SEC_ALLOC) && !(TARGET_KEEP_SECTION (asect)))
return 0;
if (0 == bfd_section_size (abfd, asect))
return 0;
return 1;
}
int
build_objfile_section_table (struct objfile *objfile)
{
asection *asect;
unsigned int i = 0;
bfd *abfd;
if (objfile->separate_debug_objfile_backlink == NULL)
abfd = objfile->obfd;
else
abfd = objfile->separate_debug_objfile_backlink->obfd;
i = 0;
for (asect = abfd->sections; asect != NULL; asect = asect->next)
i++;
objfile->sections = xmalloc (sizeof (struct obj_section) * i);
objfile->sections_end = objfile->sections;
i = 0;
for (asect = abfd->sections; asect != NULL; asect = asect->next)
{
struct obj_section section;
if (!objfile_keeps_section (abfd, asect))
continue;
section.offset = 0;
section.objfile = objfile;
section.the_bfd_section = asect;
section.ovly_mapped = 0;
section.addr = bfd_section_vma (abfd, asect);
section.endaddr = section.addr + bfd_section_size (abfd, asect);
objfile->sections[i++] = section;
objfile->sections_end = objfile->sections + i;
}
objfile_add_to_ordered_sections (objfile);
return 0;
}
struct objfile *
allocate_objfile_internal (struct objfile *objfile,
bfd *abfd, int flags,
int symflags, CORE_ADDR mapaddr,
const char *prefix)
{
objfile->symflags = symflags;
objfile->flags |= flags;
objfile->obfd = abfd;
if (objfile->name)
objfile->name = xstrdup (objfile->name);
else
objfile->name = xstrdup (bfd_get_filename (abfd));
objfile->mtime = bfd_get_mtime (abfd);
if (build_objfile_section_table (objfile))
error ("Can't find the file sections in `%s': %s",
objfile->name, bfd_errmsg (bfd_get_error ()));
if (objfile->name != NULL &&
(strstr (objfile->name, "libSystem") != NULL
|| strstr (objfile->name, "/usr/lib/system") == objfile->name))
objfile->check_for_equivalence = 1;
else
objfile->check_for_equivalence = 0;
objfile->equivalence_table = NULL;
objfile->syms_only_objfile = 0;
objfile->not_loaded_kext_filename = NULL;
return (objfile);
}
struct objfile *
allocate_objfile (bfd *abfd, int flags, int symflags, CORE_ADDR mapaddr,
const char *prefix)
{
struct objfile *objfile = NULL;
objfile = create_objfile (abfd);
objfile = allocate_objfile_internal (objfile, abfd, flags,
symflags, mapaddr, prefix);
link_objfile (objfile);
return objfile;
}
struct objfile *
allocate_objfile_using_objfile (struct objfile *objfile,
bfd *abfd, int flags,
int symflags, CORE_ADDR mapaddr,
const char *prefix)
{
create_objfile_using_objfile (objfile, abfd);
return allocate_objfile_internal (objfile, abfd, flags,
symflags, mapaddr, prefix);
}
struct objfile *
create_objfile (bfd *abfd)
{
struct objfile *objfile;
objfile = (struct objfile *) xmalloc (sizeof (struct objfile));
memset (objfile, 0, sizeof (struct objfile));
return create_objfile_using_objfile (objfile, abfd);
}
struct objfile *
create_objfile_using_objfile (struct objfile *objfile, bfd *abfd)
{
objfile->md = NULL;
objfile->psymbol_cache = bcache_xmalloc (NULL);
objfile->macro_cache = bcache_xmalloc (NULL);
bcache_specify_allocation (objfile->psymbol_cache, xmalloc, xfree);
bcache_specify_allocation (objfile->macro_cache, xmalloc, xfree);
obstack_specify_allocation (&objfile->objfile_obstack, 0, 0, xmalloc,
xfree);
objfile_alloc_data (objfile);
objfile->sect_index_text = -1;
objfile->sect_index_data = -1;
objfile->sect_index_bss = -1;
objfile->sect_index_rodata = -1;
objfile->uses_sql_repository = 0;
return objfile;
}
static int
backward_section_compare (const void *left_ptr,
const void *right_ptr)
{
struct obj_section_with_index *left
= (struct obj_section_with_index *) left_ptr;
struct obj_section_with_index * right
= (struct obj_section_with_index *) right_ptr;
if (left->section->addr > right->section->addr)
return -1;
else if (left->section->addr < right->section->addr)
return 1;
else
return 0;
}
static int
forward_int_compare (const void *left_ptr,
const void *right_ptr)
{
int *left = (int *) left_ptr;
int *right = (int *) right_ptr;
if (*left < *right)
return -1;
else if (*left > *right)
return 1;
else
return 0;
}
static int
number_of_dots (const char *s)
{
int numdots = 0;
while (*s != '\0')
{
if (*s == '.')
numdots++;
s++;
}
return numdots;
}
#define STATIC_DELETE_LIST_SIZE 256
void
objfile_delete_from_ordered_sections (struct objfile *objfile)
{
int i;
int ndeleted;
int delete_list_size;
int static_delete_list[STATIC_DELETE_LIST_SIZE];
int *delete_list = static_delete_list;
struct obj_section *s;
if (objfile->separate_debug_objfile_backlink ||
objfile->flags & OBJF_SEPARATE_DEBUG_FILE)
return;
delete_list_size = objfile->sections_end - objfile->sections;
if (delete_list_size > STATIC_DELETE_LIST_SIZE)
delete_list = (int *) xmalloc (delete_list_size * sizeof (int));
ndeleted = 0;
ALL_OBJFILE_OSECTIONS (objfile, s)
{
int index;
if (s->the_bfd_section && s->the_bfd_section->name &&
number_of_dots (s->the_bfd_section->name) == 1)
continue;
index = find_in_ordered_sections_index (s->addr, s->the_bfd_section);
if (index == -1)
warning ("Trying to remove a section from"
" the ordered section list that did not exist"
" at 0x%s.", paddr_nz (s->addr));
else
{
delete_list[ndeleted] = index;
ndeleted++;
}
}
qsort (delete_list, ndeleted, sizeof (int),
forward_int_compare);
delete_list[ndeleted] = num_ordered_sections;
for (i = 0; i < ndeleted; i++)
{
struct ordered_obj_section *src, *dest;
size_t len;
src = &(ordered_sections[delete_list[i] + 1]);
dest = &(ordered_sections[delete_list[i] - i]);
len = (delete_list[i+1] - delete_list[i] - 1)
* sizeof (struct ordered_obj_section);
bcopy (src, dest, len);
}
num_ordered_sections -= ndeleted;
if (delete_list != static_delete_list)
xfree (delete_list);
}
static int
get_insert_index_in_ordered_sections (struct obj_section *section)
{
int insert = -1;
if (num_ordered_sections > 0)
{
int bot = 0;
int top = num_ordered_sections - 1;
do
{
int mid = (top + bot) / 2;
if (ordered_sections[mid].addr < section->addr)
{
if ((mid == num_ordered_sections - 1)
|| (ordered_sections[mid + 1].addr >= section->addr))
{
insert = mid;
break;
}
else if (mid + 1 == num_ordered_sections - 1)
{
insert = mid + 1;
break;
}
bot = mid + 1;
}
else
{
if (mid == 0 || ordered_sections[mid - 1].addr <= section->addr)
{
insert = mid - 1;
break;
}
top = mid - 1;
}
} while (top > bot);
}
return insert + 1;
}
#define STATIC_INSERT_LIST_SIZE 256
void
objfile_add_to_ordered_sections (struct objfile *objfile)
{
struct obj_section *s;
int i, num_left, total;
struct obj_section_with_index static_insert_list[STATIC_INSERT_LIST_SIZE];
struct obj_section_with_index *insert_list = static_insert_list;
int insert_list_size;
if (objfile->separate_debug_objfile_backlink ||
objfile->flags & OBJF_SEPARATE_DEBUG_FILE)
return;
CHECK_FATAL (objfile != NULL);
insert_list_size = objfile->sections_end - objfile->sections;
if (insert_list_size > STATIC_INSERT_LIST_SIZE)
insert_list = (struct obj_section_with_index *)
xmalloc (insert_list_size * sizeof (struct obj_section_with_index));
total = 0;
ALL_OBJFILE_OSECTIONS (objfile, s)
{
if (s->the_bfd_section && s->the_bfd_section->segment_mark == 1)
continue;
insert_list[total].index = get_insert_index_in_ordered_sections (s);
insert_list[total].section = s;
total++;
}
qsort (insert_list, total, sizeof (struct obj_section_with_index),
backward_section_compare);
if (ordered_sections == NULL)
{
max_num_ordered_sections = ORDERED_SECTIONS_CHUNK_SIZE;
ordered_sections = (struct ordered_obj_section *)
xmalloc (max_num_ordered_sections
* sizeof (struct ordered_obj_section));
}
else if (num_ordered_sections + total >= max_num_ordered_sections)
{
max_num_ordered_sections += ORDERED_SECTIONS_CHUNK_SIZE + total;
ordered_sections = (struct ordered_obj_section *)
xrealloc (ordered_sections,
max_num_ordered_sections
* sizeof (struct ordered_obj_section));
}
num_left = total;
for (i = 0; i < total; i++)
{
struct ordered_obj_section *src;
struct ordered_obj_section *dest;
struct obj_section *s;
size_t len;
int pos;
src = &(ordered_sections[insert_list[i].index]);
dest = &(ordered_sections[insert_list[i].index + num_left]);
if (i == 0)
len = num_ordered_sections - insert_list[i].index;
else
len = insert_list[i - 1].index - insert_list[i].index;
len *= sizeof (struct ordered_obj_section);
bcopy (src, dest, len);
s = insert_list[i].section;
pos = insert_list[i].index + num_left - 1;
ordered_sections[pos].addr = s->addr;
ordered_sections[pos].endaddr = s->endaddr;
ordered_sections[pos].obj_section = s;
ordered_sections[pos].the_bfd_section = s->the_bfd_section;
num_left--;
if (num_left == 0)
break;
}
num_ordered_sections += total;
if (insert_list != static_insert_list)
xfree (insert_list);
}
static int
find_in_ordered_sections_index (CORE_ADDR addr, struct bfd_section *bfd_section)
{
int bot = 0;
int top = num_ordered_sections;
struct ordered_obj_section *obj_sect_ptr;
if (num_ordered_sections == 0)
return -1;
do
{
int mid = (top + bot) / 2;
obj_sect_ptr = &ordered_sections[mid];
if (obj_sect_ptr->addr <= addr)
{
if (addr < obj_sect_ptr->endaddr)
{
if ((bfd_section == NULL )
|| (bfd_section == obj_sect_ptr->the_bfd_section))
return mid;
else
{
int pos;
for (pos = mid + 1; pos < num_ordered_sections; pos++)
{
if (ordered_sections[pos].addr > addr)
break;
else if ((ordered_sections[pos].endaddr > addr)
&& (ordered_sections[pos].the_bfd_section == bfd_section))
return pos;
}
for (pos = mid - 1; pos >= 0; pos--)
{
if ((ordered_sections[pos].endaddr > addr)
&& (ordered_sections[pos].the_bfd_section == bfd_section))
return pos;
}
return -1;
}
}
bot = mid + 1;
}
else
{
top = mid - 1;
}
} while (bot <= top);
return -1;
}
struct obj_section *
find_pc_sect_in_ordered_sections (CORE_ADDR addr, struct bfd_section *bfd_section)
{
int index = find_in_ordered_sections_index (addr, bfd_section);
if (index == -1)
return NULL;
else
return ordered_sections[index].obj_section;
}
void
init_entry_point_info (struct objfile *objfile)
{
if (bfd_get_file_flags (objfile->obfd) & EXEC_P)
{
objfile->ei.entry_point = bfd_get_start_address (objfile->obfd);
}
else
{
objfile->ei.entry_point = INVALID_ENTRY_POINT;
}
objfile->ei.main_func_lowpc = INVALID_ENTRY_LOWPC;
objfile->ei.main_func_highpc = INVALID_ENTRY_HIGHPC;
}
CORE_ADDR
entry_point_address (void)
{
return symfile_objfile ? symfile_objfile->ei.entry_point : 0;
}
void
terminate_minimal_symbol_table (struct objfile *objfile)
{
if (! objfile->msymbols)
objfile->msymbols = ((struct minimal_symbol *)
obstack_alloc (&objfile->objfile_obstack,
sizeof (objfile->msymbols[0])));
{
struct minimal_symbol *m
= &objfile->msymbols[objfile->minimal_symbol_count];
memset (m, 0, sizeof (*m));
MSYMBOL_TYPE (m) = mst_unknown;
SYMBOL_INIT_LANGUAGE_SPECIFIC (m, language_unknown);
}
}
void
put_objfile_before (struct objfile *objfile, struct objfile *before_this)
{
struct objfile **objp;
unlink_objfile (objfile);
for (objp = &object_files; *objp != NULL; objp = &((*objp)->next))
{
if (*objp == before_this)
{
objfile->next = *objp;
*objp = objfile;
return;
}
}
internal_error (__FILE__, __LINE__,
_("put_objfile_before: before objfile not in list"));
}
void
objfile_to_front (struct objfile *objfile)
{
struct objfile **objp;
for (objp = &object_files; *objp != NULL; objp = &((*objp)->next))
{
if (*objp == objfile)
{
*objp = objfile->next;
objfile->next = object_files;
object_files = objfile;
break;
}
}
}
void
link_objfile (struct objfile *objfile)
{
struct objfile *last_one = NULL;
struct objfile *o, *temp;
ALL_OBJFILES_SAFE (o, temp)
if (objfile == o)
internal_error (__FILE__, __LINE__,
"link_objfile: objfile already linked");
if (objfile->next != NULL)
internal_error (__FILE__, __LINE__,
"link_objfile: objfile already linked");
objfile->next = NULL;
if (object_files == NULL)
object_files = objfile;
else
{
for (last_one = object_files;
last_one->next;
last_one = last_one->next);
last_one->next = objfile;
}
}
void
unlink_objfile (struct objfile *objfile)
{
struct objfile **objpp;
for (objpp = &object_files; *objpp != NULL; objpp = &((*objpp)->next))
{
if (*objpp == objfile)
{
*objpp = (*objpp)->next;
objfile->next = NULL;
return;
}
}
internal_error (__FILE__, __LINE__,
_("unlink_objfile: objfile already unlinked"));
}
static void
free_objfile_internal (struct objfile *objfile)
{
if (objfile->sf != NULL)
{
(*objfile->sf->sym_finish) (objfile);
}
varobj_delete_objfiles_vars (objfile);
objfile_delete_from_ordered_sections (objfile);
if (objfile->obfd != NULL)
{
char *name = bfd_get_filename (objfile->obfd);
remove_target_sections (objfile->obfd);
if (!bfd_close (objfile->obfd))
warning (_("cannot close \"%s\": %s"),
name, bfd_errmsg (bfd_get_error ()));
xfree (name);
}
objfile_remove_from_restrict_list (objfile);
equivalence_table_delete (objfile);
if (objfile == rt_common_objfile)
rt_common_objfile = NULL;
clear_pc_function_cache ();
objfile_free_data (objfile);
if (objfile->name != NULL)
{
xfree (objfile->name);
}
if (objfile->global_psymbols.list)
xfree (objfile->global_psymbols.list);
if (objfile->static_psymbols.list)
xfree (objfile->static_psymbols.list);
bcache_xfree (objfile->psymbol_cache);
bcache_xfree (objfile->macro_cache);
equivalence_table_delete (objfile);
if (objfile->demangled_names_hash)
htab_delete (objfile->demangled_names_hash);
obstack_free (&objfile->objfile_obstack, 0);
if (objfile->uses_sql_repository)
close_dwarf_repositories (objfile);
if (objfile->inlined_subroutine_data)
inlined_subroutine_free_objfile_data (objfile->inlined_subroutine_data);
if (objfile->inlined_call_sites)
inlined_subroutine_free_objfile_call_sites (objfile->inlined_call_sites);
symtab_clear_cached_lookup_values ();
}
void
clear_objfile (struct objfile *objfile)
{
struct objfile *next_tmp, *separate_tmp, *backlink_tmp;
if (objfile->separate_debug_objfile)
{
clear_objfile (objfile->separate_debug_objfile);
}
free_objfile_internal (objfile);
next_tmp = objfile->next;
separate_tmp = objfile->separate_debug_objfile;
backlink_tmp = objfile->separate_debug_objfile_backlink;
memset (objfile, 0, sizeof (struct objfile));
objfile->next = next_tmp;
objfile->separate_debug_objfile = separate_tmp;
objfile->separate_debug_objfile_backlink = backlink_tmp;
}
void
free_objfile (struct objfile *objfile)
{
tell_breakpoints_objfile_removed (objfile);
if (objfile->separate_debug_objfile)
{
free_objfile (objfile->separate_debug_objfile);
objfile->separate_debug_objfile = NULL;
}
if (objfile->separate_debug_objfile_backlink)
{
objfile->separate_debug_objfile_backlink->separate_debug_objfile = NULL;
}
free_objfile_internal (objfile);
unlink_objfile (objfile);
xfree (objfile);
objfile = NULL;
}
static void
do_free_objfile_cleanup (void *obj)
{
free_objfile (obj);
}
struct cleanup *
make_cleanup_free_objfile (struct objfile *obj)
{
return make_cleanup (do_free_objfile_cleanup, obj);
}
void
free_all_objfiles (void)
{
struct objfile *objfile, *temp;
ALL_OBJFILES_SAFE (objfile, temp)
{
free_objfile (objfile);
}
clear_symtab_users ();
}
void
objfile_relocate (struct objfile *objfile, struct section_offsets *new_offsets)
{
struct section_offsets *delta =
((struct section_offsets *)
alloca (SIZEOF_N_SECTION_OFFSETS (objfile->num_sections)));
{
int i;
int something_changed = 0;
for (i = 0; i < objfile->num_sections; ++i)
{
delta->offsets[i] =
ANOFFSET (new_offsets, i) - ANOFFSET (objfile->section_offsets, i);
if (ANOFFSET (delta, i) != 0)
something_changed = 1;
}
if (!something_changed)
return;
}
breakpoints_relocate (objfile, delta);
inlined_subroutine_objfile_relocate (objfile,
objfile->inlined_subroutine_data,
delta);
{
struct symtab *s;
ALL_OBJFILE_SYMTABS (objfile, s)
{
struct linetable *l;
struct blockvector *bv;
int i;
l = LINETABLE (s);
if (l)
{
unsigned int num_discontinuities = 0;
int discontinuity_index = -1;
for (i = 0; i < l->nitems; ++i)
{
l->item[i].pc += ANOFFSET (delta, s->block_line_section);
if (l->item[i].end_pc != 0)
l->item[i].end_pc += ANOFFSET (delta, s->block_line_section);
}
for (i = 0; i < (l->nitems - 1); ++i)
if (l->item[i].pc > l->item[i + 1].pc)
{
num_discontinuities++;
discontinuity_index = i + 1;
}
if (num_discontinuities == 1)
{
struct linetable *new_linetable = NULL;
size_t size = ((l->nitems - 1) * sizeof (struct linetable_entry))
+ sizeof (struct linetable);
new_linetable = (struct linetable *) xmalloc (size);
memcpy (new_linetable, l, sizeof (struct linetable));
memcpy (new_linetable->item,
l->item + discontinuity_index,
(l->nitems - discontinuity_index) * sizeof (struct linetable_entry));
memcpy (new_linetable->item + (l->nitems - discontinuity_index),
l->item,
discontinuity_index * sizeof (struct linetable_entry));
memcpy (l->item, new_linetable->item, l->nitems * sizeof (struct linetable_entry));
xfree (new_linetable);
}
else if (num_discontinuities > 0)
{
warning ("line table was not properly sorted; re-sorting");
qsort (l->item, l->nitems, sizeof (struct linetable_entry), compare_line_numbers);
}
}
if (!s->primary)
continue;
bv = BLOCKVECTOR (s);
for (i = 0; i < BLOCKVECTOR_NBLOCKS (bv); ++i)
{
struct block *b;
struct symbol *sym;
struct dict_iterator iter;
b = BLOCKVECTOR_BLOCK (bv, i);
BLOCK_START (b) += ANOFFSET (delta, s->block_line_section);
BLOCK_END (b) += ANOFFSET (delta, s->block_line_section);
if (BLOCK_RANGES (b))
{
int j;
for (j = 0; j < BLOCK_RANGES (b)->nelts; j++)
{
BLOCK_RANGE_START (b, j) += ANOFFSET (delta,
s->block_line_section);
BLOCK_RANGE_END (b, j) += ANOFFSET (delta,
s->block_line_section);
}
}
ALL_BLOCK_SYMBOLS (b, iter, sym)
{
fixup_symbol_section (sym, objfile);
if ((SYMBOL_CLASS (sym) == LOC_LABEL
|| SYMBOL_CLASS (sym) == LOC_STATIC
|| SYMBOL_CLASS (sym) == LOC_INDIRECT)
&& SYMBOL_SECTION (sym) >= 0)
{
SYMBOL_VALUE_ADDRESS (sym) +=
ANOFFSET (delta, SYMBOL_SECTION (sym));
}
}
}
}
}
{
struct partial_symtab *p;
ALL_OBJFILE_PSYMTABS (objfile, p)
{
p->textlow += ANOFFSET (delta, SECT_OFF_TEXT (objfile));
p->texthigh += ANOFFSET (delta, SECT_OFF_TEXT (objfile));
}
}
{
struct partial_symbol **psym;
for (psym = objfile->global_psymbols.list;
psym < objfile->global_psymbols.next;
psym++)
{
fixup_psymbol_section (*psym, objfile);
if (SYMBOL_SECTION (*psym) >= 0)
SYMBOL_VALUE_ADDRESS (*psym) += ANOFFSET (delta,
SYMBOL_SECTION (*psym));
}
for (psym = objfile->static_psymbols.list;
psym < objfile->static_psymbols.next;
psym++)
{
fixup_psymbol_section (*psym, objfile);
if (SYMBOL_SECTION (*psym) >= 0)
SYMBOL_VALUE_ADDRESS (*psym) += ANOFFSET (delta,
SYMBOL_SECTION (*psym));
}
}
{
struct minimal_symbol *msym;
ALL_OBJFILE_MSYMBOLS (objfile, msym)
if (SYMBOL_SECTION (msym) >= 0)
SYMBOL_VALUE_ADDRESS (msym) += ANOFFSET (delta, SYMBOL_SECTION (msym));
}
msymbols_sort (objfile);
{
int i;
for (i = 0; i < objfile->num_sections; ++i)
(objfile->section_offsets)->offsets[i] = ANOFFSET (new_offsets, i);
}
if (objfile->ei.entry_point != ~(CORE_ADDR) 0)
{
struct obj_section *s;
s = find_pc_section (objfile->ei.entry_point);
if (s)
objfile->ei.entry_point += ANOFFSET (delta, s->the_bfd_section->index);
else
objfile->ei.entry_point += ANOFFSET (delta, SECT_OFF_TEXT (objfile));
}
DBX_TEXT_ADDR (objfile) += ANOFFSET (delta, SECT_OFF_TEXT (objfile));
if (DBX_COALESCED_TEXT_ADDR (objfile) != 0)
{
DBX_COALESCED_TEXT_ADDR (objfile) += ANOFFSET (delta,
SECT_OFF_TEXT (objfile));
}
{
struct obj_section *s;
bfd *abfd;
int idx = 0;
abfd = objfile->obfd;
objfile_delete_from_ordered_sections (objfile);
ALL_OBJFILE_OSECTIONS (objfile, s)
{
s->addr += ANOFFSET (delta, idx);
s->endaddr += ANOFFSET (delta, idx);
idx++;
}
objfile_add_to_ordered_sections (objfile);
}
breakpoint_re_set (objfile);
}
int
have_partial_symbols (void)
{
struct objfile *ofp;
ALL_OBJFILES (ofp)
{
if (ofp->psymtabs != NULL)
{
return 1;
}
}
return 0;
}
int
have_full_symbols (void)
{
struct objfile *ofp;
ALL_OBJFILES (ofp)
{
if (ofp->symtabs != NULL)
{
return 1;
}
}
return 0;
}
void
objfile_purge_solibs (void)
{
struct objfile *objf;
struct objfile *temp;
ALL_OBJFILES_SAFE (objf, temp)
{
}
}
int
have_minimal_symbols (void)
{
struct objfile *ofp;
ALL_OBJFILES (ofp)
{
if (ofp->minimal_symbol_count > 0)
{
return 1;
}
}
return 0;
}
struct obj_section *
find_pc_sect_section (CORE_ADDR pc, struct bfd_section *section)
{
struct obj_section *s;
struct objfile *objfile;
if (pc == last_sect_section_lookup_pc
&& pc == last_mapped_section_lookup_pc
&& section == cached_mapped_section)
return cached_sect_section;
last_sect_section_lookup_pc = pc;
s = find_pc_sect_in_ordered_sections (pc, section);
if (s != NULL)
{
cached_sect_section = s;
return (s);
}
ALL_OBJSECTIONS (objfile, s)
if (objfile->separate_debug_objfile_backlink == NULL
&& (section == 0 || section == s->the_bfd_section)
&& s->addr <= pc && pc < s->endaddr)
{
cached_sect_section = s;
return (s);
}
last_sect_section_lookup_pc = INVALID_ADDRESS;
cached_sect_section = NULL;
return (NULL);
}
struct obj_section *
find_pc_section (CORE_ADDR pc)
{
return find_pc_sect_section (pc, find_pc_mapped_section (pc));
}
int
in_plt_section (CORE_ADDR pc, char *name)
{
struct obj_section *s;
int retval = 0;
s = find_pc_section (pc);
retval = (s != NULL
&& s->the_bfd_section->name != NULL
&& strcmp (s->the_bfd_section->name, ".plt") == 0);
return (retval);
}
int
is_in_import_list (char *name, struct objfile *objfile)
{
int i;
if (!objfile || !name || !*name)
return 0;
for (i = 0; i < objfile->import_list_size; i++)
if (objfile->import_list[i] && DEPRECATED_STREQ (name, objfile->import_list[i]))
return 1;
return 0;
}
static struct objfile_list *objfile_list_ptr;
static int restrict_search = 0;
struct objfile_list *objfile_list;
int
objfile_restrict_search (int on)
{
int old = restrict_search;
restrict_search = on;
return old;
}
void
objfile_add_to_restrict_list (struct objfile *objfile)
{
struct objfile_list *new_objfile;
if (objfile->separate_debug_objfile_backlink ||
objfile->flags & OBJF_SEPARATE_DEBUG_FILE)
{
if (objfile->separate_debug_objfile_backlink)
objfile_add_to_restrict_list (objfile->separate_debug_objfile_backlink);
return;
}
for (new_objfile = objfile_list;
new_objfile != NULL;
new_objfile = new_objfile->next)
{
if (new_objfile->objfile == objfile)
return;
}
new_objfile = (struct objfile_list *) xmalloc (sizeof (struct objfile_list));
new_objfile->next = objfile_list;
new_objfile->objfile = objfile;
objfile_list = new_objfile;
}
static void
objfile_remove_from_restrict_list (struct objfile *objfile)
{
struct objfile_list **objpp;
struct objfile_list *i;
for (objpp = &objfile_list; *objpp != NULL; objpp = &((*objpp)->next))
{
if ((*objpp)->objfile == objfile)
{
i = *objpp;
*objpp = (*objpp)->next;
xfree (i);
return;
}
}
}
void
objfile_clear_restrict_list ()
{
while (objfile_list != NULL)
{
struct objfile_list *list_ptr;
list_ptr = objfile_list;
objfile_list = list_ptr->next;
xfree (list_ptr);
}
}
static struct objfile_list *
objfile_set_restrict_list (struct objfile_list *objlist)
{
struct objfile_list *tmp_list;
tmp_list = objfile_list;
objfile_list = objlist;
return tmp_list;
}
struct swap_objfile_list_cleanup
{
struct objfile_list *old_list;
int restrict_state;
};
void
do_cleanup_restrict_to_objfile (void *arg)
{
struct swap_objfile_list_cleanup *data =
(struct swap_objfile_list_cleanup *) arg;
objfile_clear_restrict_list ();
objfile_list = data->old_list;
objfile_restrict_search (data->restrict_state);
}
struct cleanup *
make_cleanup_restrict_to_objfile (struct objfile *objfile)
{
struct swap_objfile_list_cleanup *data
= (struct swap_objfile_list_cleanup *) xmalloc (sizeof (struct swap_objfile_list_cleanup));
data->old_list = objfile_list;
objfile_list = NULL;
objfile_add_to_restrict_list (objfile);
data->restrict_state = objfile_restrict_search (1);
return make_cleanup (do_cleanup_restrict_to_objfile, (void *) data);
}
struct objfile *
find_objfile_by_name (const char *name, int exact)
{
struct objfile *o, *temp;
if (name == NULL || *name == '\0')
return NULL;
ALL_OBJFILES_SAFE (o, temp)
{
enum objfile_matches_name_return r;
r = objfile_matches_name (o, name);
if (exact && r == objfile_match_exact)
return o;
if (!exact && r == objfile_match_base)
return o;
}
const char *memobj_str = "[memory object \"";
int memobj_strlen = strlen (memobj_str);
char buf[PATH_MAX + 1];
ALL_OBJFILES_SAFE (o, temp)
{
if (o->name == NULL)
continue;
if (strncmp (memobj_str, o->name, memobj_strlen) != 0)
continue;
strcpy (buf, o->name + memobj_strlen);
buf[PATH_MAX] = '\0';
char *t = strchr (buf, '"');
if (t == NULL)
continue;
*t = '\0';
if (strcmp (buf, name) == 0)
return o;
if (exact == 0 && strstr (buf, name) != NULL)
return o;
}
return NULL;
}
struct objfile *
find_objfile_by_uuid (uuid_t uuid)
{
struct objfile *o, *temp;
ALL_OBJFILES_SAFE (o, temp)
{
uuid_t bfd_uuid;
if (bfd_mach_o_get_uuid (o->obfd, bfd_uuid, sizeof (uuid_t))
&& memcmp (bfd_uuid, uuid, sizeof (uuid_t)) == 0)
{
if (o->separate_debug_objfile_backlink)
return o->separate_debug_objfile_backlink;
else
return o;
}
}
return NULL;
}
struct cleanup *
make_cleanup_restrict_to_objfile_by_name (char *objfile_name)
{
struct objfile *objfile = NULL;
struct swap_objfile_list_cleanup *data
= (struct swap_objfile_list_cleanup *) xmalloc (sizeof (struct swap_objfile_list_cleanup));
data->old_list = objfile_list;
objfile_list = NULL;
objfile = find_objfile_by_name (objfile_name, 1);
if (objfile)
{
objfile_add_to_restrict_list (objfile);
data->restrict_state = objfile_restrict_search (1);
return make_cleanup (do_cleanup_restrict_to_objfile, (void *) data);
}
else
return make_cleanup (null_cleanup, NULL);
}
struct cleanup *
make_cleanup_restrict_to_objfile_list (struct objfile_list *objlist)
{
struct swap_objfile_list_cleanup *data
= (struct swap_objfile_list_cleanup *) xmalloc (sizeof (struct swap_objfile_list_cleanup));
data->old_list = objfile_set_restrict_list (objlist);
data->restrict_state = objfile_restrict_search (1);
return make_cleanup (do_cleanup_restrict_to_objfile, (void *) data);
}
enum objfile_matches_name_return
objfile_matches_name (struct objfile *objfile, char *name)
{
const char *filename;
const char *bundlename;
const char *real_name;
if (objfile->name == NULL)
return objfile_no_match;
real_name = objfile->name;
if (strcmp (real_name, name) == 0)
return objfile_match_exact;
bundlename = bundle_basename (real_name);
if (bundlename && strcmp (bundlename, name) == 0)
return objfile_match_base;
filename = lbasename (real_name);
if (filename == NULL)
return objfile_no_match;
if (strcmp (filename, name) == 0)
return objfile_match_base;
return objfile_no_match;
}
void
push_front_restrict_list (struct objfile_list **requested_list_head,
struct objfile *objfile)
{
struct objfile_list *new_requested_list_head
= (struct objfile_list *) xmalloc (sizeof (struct objfile_list));
new_requested_list_head->objfile = objfile;
new_requested_list_head->next = *requested_list_head;
*requested_list_head = new_requested_list_head;
}
void clear_restrict_list (struct objfile_list **requested_list_head)
{
while (*requested_list_head != NULL)
{
struct objfile_list *list_ptr;
list_ptr = *requested_list_head;
*requested_list_head = list_ptr->next;
xfree (list_ptr);
}
}
struct cleanup *
make_cleanup_restrict_to_shlib (char *requested_shlib)
{
struct objfile_list *requested_list = NULL;
struct objfile *requested_objfile = NULL;
struct objfile *tmp_obj;
if (requested_shlib == NULL)
return NULL;
ALL_OBJFILES (tmp_obj)
{
enum objfile_matches_name_return match =
objfile_matches_name (tmp_obj, requested_shlib);
if (match == objfile_match_exact)
{
clear_restrict_list (&requested_list);
if (tmp_obj->separate_debug_objfile_backlink)
requested_objfile = tmp_obj->separate_debug_objfile_backlink;
else
requested_objfile = tmp_obj;
break;
}
else if (match == objfile_match_base)
{
if (tmp_obj->separate_debug_objfile_backlink == NULL)
{
push_front_restrict_list (&requested_list, tmp_obj);
}
}
}
if (requested_objfile != NULL)
return make_cleanup_restrict_to_objfile (requested_objfile);
else if (requested_list != NULL)
return make_cleanup_restrict_to_objfile_list (requested_list);
else
return (void *) -1;
}
struct objfile *
objfile_get_first ()
{
if (!restrict_search || objfile_list == NULL)
return object_files;
else
{
objfile_list_ptr = objfile_list->next;
if (objfile_list->objfile
&& objfile_list->objfile->separate_debug_objfile)
return objfile_list->objfile->separate_debug_objfile;
else
return objfile_list->objfile;
}
}
struct objfile *
objfile_get_next (struct objfile *in_objfile)
{
struct objfile *objfile = NULL;
if (!restrict_search || objfile_list == NULL)
{
if (in_objfile)
return in_objfile->next;
else
return NULL;
}
if (in_objfile->separate_debug_objfile_backlink)
objfile = in_objfile->separate_debug_objfile_backlink;
else
{
while (objfile_list_ptr)
{
objfile = objfile_list_ptr->objfile;
objfile_list_ptr = objfile_list_ptr->next;
if (objfile->separate_debug_objfile_backlink == NULL)
break;
if (objfile_list_ptr == NULL)
return NULL;
}
if (objfile && objfile->separate_debug_objfile)
objfile = objfile->separate_debug_objfile;
}
return objfile;
}
static int should_auto_raise_load_state = 0;
int
objfile_set_load_state (struct objfile *o, int load_state, int force)
{
if (!force && !should_auto_raise_load_state)
return -2;
if (o->symflags & OBJF_SYM_DONT_CHANGE)
return -2;
if (o->symflags >= load_state)
return load_state;
#ifdef MACOSX_DYLD
return dyld_objfile_set_load_state (o, load_state);
#else
return -1;
#endif
}
int
pc_set_load_state (CORE_ADDR pc, int load_state, int force)
{
struct obj_section *s;
if (!force && !should_auto_raise_load_state)
return -1;
s = find_pc_section (pc);
if (s == NULL)
return -1;
if (s->objfile == NULL)
return -1;
return objfile_set_load_state (s->objfile, load_state, force);
}
int
objfile_name_set_load_state (char *name, int load_state, int force)
{
struct objfile *tmp_obj;
if (!force && !should_auto_raise_load_state)
return -2;
if (name == NULL)
return -1;
ALL_OBJFILES (tmp_obj)
{
enum objfile_matches_name_return match
= objfile_matches_name (tmp_obj, name);
if (match == objfile_match_exact || match == objfile_match_base)
return objfile_set_load_state (tmp_obj, load_state, force);
}
return -1;
}
struct symtab *
symtab_get_first (struct objfile *objfile, int skip_obsolete)
{
struct symtab *s;
s = objfile->symtabs;
while (s != NULL && skip_obsolete && SYMTAB_OBSOLETED (s) == 51)
{
s = s->next;
}
return (s);
}
struct symtab *
symtab_get_next (struct symtab *s, int skip_obsolete)
{
if (s == NULL)
return NULL;
s = s->next;
while (s != NULL && skip_obsolete && SYMTAB_OBSOLETED (s) == 51)
{
s = s->next;
}
return s;
}
struct partial_symtab *
psymtab_get_first (struct objfile *objfile, int skip_obsolete)
{
struct partial_symtab *ps;
ps = objfile->psymtabs;
while (ps != NULL && skip_obsolete && PSYMTAB_OBSOLETED (ps) == 51)
{
ps = ps->next;
}
return (ps);
}
struct partial_symtab *
psymtab_get_next (struct partial_symtab *ps, int skip_obsolete)
{
if (ps == NULL)
return NULL;
ps = ps->next;
while (ps != NULL && skip_obsolete && PSYMTAB_OBSOLETED (ps) == 51)
{
ps = ps->next;
}
return ps;
}
struct objfile_data
{
unsigned index;
};
struct objfile_data_registration
{
struct objfile_data *data;
struct objfile_data_registration *next;
};
struct objfile_data_registry
{
struct objfile_data_registration *registrations;
unsigned num_registrations;
};
static struct objfile_data_registry objfile_data_registry = { NULL, 0 };
const struct objfile_data *
register_objfile_data (void)
{
struct objfile_data_registration **curr;
for (curr = &objfile_data_registry.registrations;
*curr != NULL; curr = &(*curr)->next);
*curr = XMALLOC (struct objfile_data_registration);
(*curr)->next = NULL;
(*curr)->data = XMALLOC (struct objfile_data);
(*curr)->data->index = objfile_data_registry.num_registrations++;
return (*curr)->data;
}
static void
objfile_alloc_data (struct objfile *objfile)
{
gdb_assert (objfile->data == NULL);
objfile->num_data = objfile_data_registry.num_registrations;
objfile->data = XCALLOC (objfile->num_data, void *);
}
static void
objfile_free_data (struct objfile *objfile)
{
gdb_assert (objfile->data != NULL);
xfree (objfile->data);
objfile->data = NULL;
}
unsigned
get_objfile_registry_num_registrations (void)
{
return objfile_data_registry.num_registrations;
}
void
clear_objfile_data (struct objfile *objfile)
{
gdb_assert (objfile->data != NULL);
memset (objfile->data, 0, objfile->num_data * sizeof (void *));
}
void
set_objfile_data (struct objfile *objfile, const struct objfile_data *data,
void *value)
{
gdb_assert (data->index < objfile->num_data);
objfile->data[data->index] = value;
}
void *
objfile_data (struct objfile *objfile, const struct objfile_data *data)
{
gdb_assert (data->index < objfile->num_data);
return objfile->data[data->index];
}
struct objfile *
executable_objfile (struct objfile *objfile)
{
if (objfile && objfile->separate_debug_objfile_backlink)
return objfile->separate_debug_objfile_backlink;
return objfile;
}
struct objfile *
separate_debug_objfile (struct objfile *objfile)
{
if (objfile && objfile->separate_debug_objfile)
return objfile->separate_debug_objfile;
return objfile;
}
CORE_ADDR
objfile_section_offset (struct objfile *objfile, int sect_idx)
{
const char* err_str = NULL;
struct objfile *exec_objfile = executable_objfile (objfile);
if (exec_objfile == NULL)
err_str = _("NULL objfile");
else
{
if (exec_objfile->section_offsets == NULL)
err_str = _("Objfile section offsets are uninitialized");
else if (sect_idx < 0)
err_str = _("Section index is uninitialized");
else if (sect_idx >= exec_objfile->num_sections)
err_str = _("Section index is out of range for objfile");
}
if (err_str != NULL)
{
internal_error (__FILE__, __LINE__, "%s (exec_objfile '%s' objfile '%s')",
err_str,
(exec_objfile ? exec_objfile->name : ""),
objfile->name);
return (CORE_ADDR) -1;
}
if (exec_objfile != objfile &&
bfd_mach_o_in_shared_cached_memory (exec_objfile->obfd))
{
gdb_assert (exec_objfile->num_sections <= objfile->num_sections);
gdb_assert (sect_idx < objfile->num_sections);
return objfile->section_offsets->offsets[sect_idx];
}
return exec_objfile->section_offsets->offsets[sect_idx];
}
CORE_ADDR
objfile_text_section_offset (struct objfile *objfile)
{
return objfile_section_offset (objfile, SECT_OFF_TEXT (objfile));
}
CORE_ADDR
objfile_data_section_offset (struct objfile *objfile)
{
return objfile_section_offset (objfile, SECT_OFF_DATA (objfile));
}
CORE_ADDR
objfile_rodata_section_offset (struct objfile *objfile)
{
return objfile_section_offset (objfile, SECT_OFF_RODATA (objfile));
}
CORE_ADDR
objfile_bss_section_offset (struct objfile *objfile)
{
return objfile_section_offset (objfile, SECT_OFF_BSS (objfile));
}
struct objfile_hitlist
{
int num_elem;
struct objfile *ofiles[];
};
static struct objfile_hitlist *cur_objfile_hitlist;
static int hitlist_max_elem;
#define HITLIST_INITIAL_MAX_ELEM 1
static void
objfile_init_hitlist ()
{
if (cur_objfile_hitlist != NULL)
internal_error (__FILE__, __LINE__,
"Tried to initialize hit list without "
"closing previous hitlist.");
cur_objfile_hitlist = xmalloc (sizeof (struct objfile_hitlist)
+ HITLIST_INITIAL_MAX_ELEM * sizeof (struct objfile *));
hitlist_max_elem = HITLIST_INITIAL_MAX_ELEM;
cur_objfile_hitlist->num_elem = 0;
}
void
objfile_add_to_hitlist (struct objfile *ofile)
{
int ctr;
if (cur_objfile_hitlist == NULL)
return;
if (ofile == NULL)
return;
if (cur_objfile_hitlist->num_elem == hitlist_max_elem)
{
hitlist_max_elem
+= hitlist_max_elem;
cur_objfile_hitlist = xrealloc (cur_objfile_hitlist, sizeof (struct objfile_hitlist)
+ hitlist_max_elem * sizeof (struct objfile *));
}
for (ctr = 0; ctr < cur_objfile_hitlist->num_elem; ctr++)
{
if (cur_objfile_hitlist->ofiles[ctr] == ofile)
return;
}
cur_objfile_hitlist->ofiles[ctr] = ofile;
cur_objfile_hitlist->num_elem += 1;
}
struct objfile_hitlist *
objfile_detach_hitlist ()
{
struct objfile_hitlist *thislist;
thislist = cur_objfile_hitlist;
cur_objfile_hitlist = NULL;
hitlist_max_elem = HITLIST_INITIAL_MAX_ELEM;
return thislist;
}
static void
objfile_clear_hitlist (void *notused)
{
struct objfile_hitlist *hitlist;
hitlist = objfile_detach_hitlist ();
if (hitlist != NULL)
xfree (hitlist);
}
struct cleanup *
make_cleanup_objfile_init_clear_hitlist ()
{
objfile_init_hitlist ();
return make_cleanup (objfile_clear_hitlist, NULL);
}
int
objfile_on_hitlist_p (struct objfile_hitlist *hitlist,
struct objfile *ofile)
{
int ctr;
for (ctr = 0; ctr < hitlist->num_elem; ctr++)
{
if (hitlist->ofiles[ctr] == ofile)
return 1;
}
return 0;
}
static int
compare_psymbol_ptrs (const void *s1p, const void *s2p)
{
struct partial_symbol *s1 = *(struct partial_symbol **) s1p;
struct partial_symbol *s2 = *(struct partial_symbol **) s2p;
if (s1 < s2)
return -1;
if (s1 == s2)
return 0;
return 1;
}
void
sort_objfile_thumb_psyms (struct objfile *objfile)
{
if (objfile->num_thumb_psyms > 1)
{
qsort (objfile->thumb_psyms,
objfile->num_thumb_psyms,
sizeof (struct partial_symbol *),
compare_psymbol_ptrs);
}
}
#define MSYMBOL_THUMB_FUNCTION 0x80000000
char *
partial_symbol_special_info (struct objfile *objfile,
struct partial_symbol *psym)
{
if (objfile->num_thumb_psyms == 0)
return NULL;
if (PSYMBOL_DOMAIN (psym) != VAR_DOMAIN
&& PSYMBOL_DOMAIN (psym) != FUNCTIONS_DOMAIN
&& PSYMBOL_DOMAIN (psym) != METHODS_DOMAIN)
return NULL;
if (PSYMBOL_CLASS (psym) != LOC_BLOCK)
return NULL;
if (SYMBOL_VALUE_ADDRESS (psym) == 0
|| SYMBOL_VALUE_ADDRESS (psym) == INVALID_ADDRESS)
return NULL;
struct partial_symbol *i;
i = bsearch (&psym, objfile->thumb_psyms,
objfile->num_thumb_psyms, sizeof (struct partial_symbol *),
compare_psymbol_ptrs);
if (i)
return (char *) (MSYMBOL_THUMB_FUNCTION);
return NULL;
}
void
objfile_add_special_psym (struct objfile *objfile,
struct partial_symbol *psym,
int short isa_value)
{
int max_size = objfile->max_thumb_psyms;
int size = objfile->num_thumb_psyms;
if (PSYMBOL_DOMAIN (psym) != VAR_DOMAIN
&& PSYMBOL_DOMAIN (psym) != FUNCTIONS_DOMAIN
&& PSYMBOL_DOMAIN (psym) != METHODS_DOMAIN)
return;
if (PSYMBOL_CLASS (psym) != LOC_BLOCK)
return;
if (isa_value != DW_ISA_ARM_thumb)
return;
if (max_size == 0)
{
max_size = 100;
objfile->thumb_psyms = (struct partial_symbol **) malloc
(max_size * sizeof (struct partial_symbol*));
}
else if (size >= max_size)
{
max_size = 2 * max_size;
objfile->thumb_psyms = (struct partial_symbol **) realloc
(objfile->thumb_psyms, max_size * sizeof (struct partial_symbol *));
}
objfile->max_thumb_psyms = max_size;
objfile->thumb_psyms[size++] = psym;
objfile->num_thumb_psyms = size;
}
void
_initialize_objfiles (void)
{
cached_symfile_path =
xstrdup ("./gdb-symfile-cache:./syms:/usr/libexec/gdb/symfiles");
add_setshow_boolean_cmd ("auto-raise-load-levels", class_obscure,
&should_auto_raise_load_state, _("\
Set if GDB should raise the symbol loading level on all frames found in backtraces."), _("\
Show if GDB should raise the symbol loading level on all frames found in backtraces."), NULL,
NULL, NULL, &setlist, &showlist);
}