#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 "gdbtypes.h"
#include "gdb_stat.h"
#include "obstack.h"
#include <fcntl.h>
#include <sys/mman.h>
#include "cached-symfile.h"
#include "macosx-nat-dyld.h"
#ifdef USE_MMALLOC
#include "mmprivate.h"
#endif
#define MAPPED_SYMFILES (USE_MMALLOC && HAVE_MMAP)
#define MMALLOC_SHARED (1 << 1)
#if MAPPED_SYMFILES
static void
move_objfile (struct relocation_context *r, struct objfile *o);
static inline int
relocate (struct relocation_context *r, void *ptr, void **new);
#endif
static char *cached_symfile_path = NULL;
static char *cached_symfile_dir = NULL;
#ifndef FSF_OBJFILES
static unsigned long cached_symfile_version = 5;
extern int mapped_symbol_files;
extern int use_mapped_symbol_files;
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 TARGET_KEEP_SECTION
#define TARGET_KEEP_SECTION(ASECT) 0
#endif
int
build_objfile_section_table (struct objfile *objfile)
{
asection *asect;
unsigned int i = 0;
bfd *abfd = objfile->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;
flagword aflag;
aflag = bfd_get_section_flags (abfd, asect);
if (!(aflag & SEC_ALLOC) && !(TARGET_KEEP_SECTION (asect)))
continue;
if (0 == bfd_section_size (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;
}
return 0;
}
void init_objfile (struct objfile *objfile)
{
objfile->sect_index_text = -1;
objfile->sect_index_data = -1;
objfile->sect_index_bss = -1;
objfile->sect_index_rodata = -1;
}
struct objfile *
allocate_objfile (bfd *abfd, int flags, int symflags, CORE_ADDR mapaddr, const char *prefix)
{
struct objfile *objfile = NULL;
if (mapped_symbol_files)
flags |= OBJF_MAPPED;
#if MAPPED_SYMFILES
if (use_mapped_symbol_files)
objfile = open_mapped_objfile (bfd_get_filename (abfd), abfd, bfd_get_mtime (abfd), mapaddr);
if ((objfile == NULL) && (flags & OBJF_MAPPED))
{
mkdir (cached_symfile_dir, 0777);
objfile = cache_bfd (abfd, prefix, symflags, 0, 0, cached_symfile_dir);
}
#endif
if (objfile == NULL)
{
objfile = create_objfile (abfd);
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 ()));
link_objfile (objfile);
}
return (objfile);
}
#if MAPPED_SYMFILES
void mmalloc_protect (PTR md, int flags)
{
size_t start, end;
int ret;
mmalloc_endpoints (md, &start, &end);
ret = mprotect (start, end - start, flags);
if (ret < 0)
perror ("setting memory protection");
}
struct objfile *
open_objfile_from_mmalloc_pool (PTR md, bfd *abfd, int fd, time_t mtime, char *filename)
{
struct symtab *s;
struct partial_symtab *p;
struct objfile *orig_objfile;
struct objfile *objfile;
time_t timestamp = 0;
unsigned long version;
void *mapto;
struct minimal_symbol *ms;
size_t start = 0;
size_t end = 0;
struct mdesc *mdp = MD_TO_MDP (md);
mapto = (void *) mmalloc_getkey (md, 0);
orig_objfile = (struct objfile *) mmalloc_getkey (md, 1);
if (orig_objfile == NULL)
{
warning ("Unable to read objfile from \"%s\"; ignoring", filename);
return NULL;
}
timestamp = (time_t) mmalloc_getkey (md, 2);
if (mtime != timestamp)
{
char *str1 = xstrdup (ctime (&mtime));
char *str2 = xstrdup (ctime (×tamp));
str1[strlen(str1) - 1] = '\0';
str2[strlen(str2) - 1] = '\0';
warning ("Pre-compiled symbol file \"%s\" is out of date (%s vs. %s); ignoring",
filename, str1, str2);
xfree (str1);
xfree (str2);
return NULL;
}
version = (unsigned long) mmalloc_getkey (md, 3);
if (version != cached_symfile_version)
{
warning ("Mapped symbol file \"%s\" is for a different version of GDB; ignoring", filename);
return NULL;
}
mmalloc_endpoints (md, &start, &end);
if (md != mapto)
{
struct relocation_context r;
r.len = end - start;
r.from_start = (size_t) mapto;
r.to_start = start;
r.mapped_start = start;
orig_objfile = objfile_reposition (orig_objfile, &r);
}
objfile = (struct objfile *) xmalloc (sizeof (struct objfile));
*objfile = *orig_objfile;
for (ms = objfile->msymbols; (ms->ginfo.name != NULL); ms++)
ms->ginfo.bfd_section = NULL;
objfile->md = NULL;
objfile->mmfd = fd;
objfile->sf = NULL;
objfile->obfd = abfd;
objfile->name = filename;
objfile->flags |= OBJF_MAPPED;
if (build_objfile_section_table (objfile))
error ("Can't find the file sections in `%s': %s",
objfile->name, bfd_errmsg (bfd_get_error ()));
ALL_OBJFILE_SYMTABS (objfile, s)
s->objfile = objfile;
ALL_OBJFILE_PSYMTABS (objfile, p)
p->objfile = objfile;
mdp->mmalloc_hook = (void *) abort;
mdp->mrealloc_hook = (void *) abort;
mdp->mfree_hook = (void *) abort;
#if 0
bcache_specify_allocation_with_arg
(objfile->psymbol_cache, abort, abort, objfile->md);
bcache_specify_allocation_with_arg
(objfile->macro_cache, abort, abort, objfile->md);
obstack_specify_allocation_with_arg
(&objfile->psymbol_obstack, 0, 0, abort, abort, objfile->md);
obstack_specify_allocation_with_arg
(&objfile->symbol_obstack, 0, 0, abort, abort, objfile->md);
obstack_specify_allocation_with_arg
(&objfile->type_obstack, 0, 0, abort, abort, objfile->md);
#endif
link_objfile (objfile);
return objfile;
}
struct objfile *
open_mapped_objfile (const char *filename, bfd *abfd, time_t mtime, CORE_ADDR mapaddr)
{
const char *symsfilename = NULL;
const char *resolved = NULL;
struct stat sbuf;
int fd = -1;
PTR md = NULL;
if ((strlen (filename) >= 5) && (strcmp (filename + (strlen (filename) - 5), ".syms") == 0))
symsfilename = filename;
else
symsfilename = concat (basename (filename), ".syms", (char *) NULL);
fd = openp (cached_symfile_path, 1, symsfilename, 0, O_RDWR, &resolved);
if (fstat (fd, &sbuf) != 0)
return NULL;
if (sbuf.st_mtime < mtime)
{
char *str1 = xstrdup (ctime (&sbuf.st_mtime));
char *str2 = xstrdup (ctime (&mtime));
str1[strlen(str1) - 1] = '\0';
str2[strlen(str2) - 1] = '\0';
warning ("Pre-compiled symbol file \"%s\" is out of date (%s vs. %s); ignoring\n",
symsfilename, str1, str2);
xfree (str1);
xfree (str2);
return NULL;
}
md = mmalloc_attach (fd, 0, MMALLOC_SHARED);
if (md == NULL)
{
warning ("Unable to attach to mapped file; ignoring");
return NULL;
}
return open_objfile_from_mmalloc_pool (md, abfd, fd, mtime, resolved);
}
struct objfile *
create_objfile_from_mmalloc_pool (bfd *abfd, PTR md, int fd, CORE_ADDR mapaddr)
{
struct objfile *objfile;
objfile = (struct objfile *) xmmalloc (md, sizeof (struct objfile));
memset (objfile, 0, sizeof (struct objfile));
objfile->md = md;
objfile->mmfd = fd;
objfile->obfd = abfd;
objfile->flags |= OBJF_MAPPED;
objfile->md = init_malloc (md);
mmalloc_setkey (md, 0, (void *) (((unsigned char *) 0) + mapaddr));
mmalloc_setkey (md, 1, (void *) objfile);
mmalloc_setkey (md, 2, (void *) bfd_get_mtime (abfd));
mmalloc_setkey (md, 3, (void *) cached_symfile_version);
objfile->psymbol_cache = bcache_xmalloc (objfile->md);
objfile->macro_cache = bcache_xmalloc (objfile->md);
bcache_specify_allocation_with_arg
(objfile->psymbol_cache, xmmalloc, xmfree, objfile->md);
bcache_specify_allocation_with_arg
(objfile->macro_cache, xmmalloc, xmfree, objfile->md);
obstack_specify_allocation_with_arg
(&objfile->psymbol_obstack, 0, 0, xmmalloc, xmfree, objfile->md);
obstack_specify_allocation_with_arg
(&objfile->symbol_obstack, 0, 0, xmmalloc, xmfree, objfile->md);
obstack_specify_allocation_with_arg
(&objfile->type_obstack, 0, 0, xmmalloc, xmfree, objfile->md);
return objfile;
}
struct objfile *cache_bfd (bfd *abfd, const char *prefix, int symflags,
size_t addr, size_t mapaddr, const char *dest)
{
unsigned int i;
struct section_addr_info addrs;
struct objfile *objfile = NULL;
struct symtab *s = NULL;
struct partial_symtab *p = NULL;
const char *filename = NULL;
const char *temp_filename = NULL;
PTR md = NULL;
int fd = -1;
size_t start, end;
struct stat st;
struct objfile *repositioned = NULL;
time_t mtime;
struct relocation_context r;
if ((dest[0] != '\0') && (dest[strlen(dest) - 1] == '/'))
filename = concat (dest, basename (bfd_get_filename (abfd)), ".syms", (char *) NULL);
else if ((stat (dest, &st) == 0) && S_ISDIR (st.st_mode))
filename = concat (dest, "/", basename (bfd_get_filename (abfd)), ".syms", (char *) NULL);
else
filename = dest;
temp_filename = concat (filename, ".new", (char *) NULL);
fd = open (temp_filename, O_RDWR | O_CREAT | O_TRUNC, 0666);
if (fd < 0)
{
warning ("Unable to open \"%s\"", filename);
return NULL;
}
if (mapaddr == 0)
mapaddr = mmalloc_findbase (256 * 1024 * 1024, 0);
if (info_verbose)
{
printf ("Mapping \"%s\" ...", filename);
fflush (stdout);
}
md = mmalloc_attach (fd, ((unsigned char *) 0) + mapaddr, 0);
if (md == NULL)
{
warning ("Unable to map symbol file at 0x%lx", (unsigned long) mapaddr);
return NULL;
}
objfile = create_objfile_from_mmalloc_pool (abfd, md, fd, mapaddr);
if (objfile == NULL)
{
warning ("Unable to create objfile");
return NULL;
}
swapout_gdbarch_swap (current_gdbarch);
clear_gdbarch_swap (current_gdbarch);
builtin_type_void =
init_type (TYPE_CODE_VOID, 1,
0,
"void", objfile);
builtin_type_int =
init_type (TYPE_CODE_INT, TARGET_INT_BIT / TARGET_CHAR_BIT,
0, "int", objfile);
builtin_type_error =
init_type (TYPE_CODE_ERROR, 0, 0, "<unknown type>", objfile);
builtin_type_char =
init_type (TYPE_CODE_INT, TARGET_CHAR_BIT / TARGET_CHAR_BIT,
(TYPE_FLAG_NOSIGN
| (TARGET_CHAR_SIGNED ? 0 : TYPE_FLAG_UNSIGNED)),
"char", objfile);
objfile->symflags = symflags;
objfile->obfd = abfd;
objfile->name = mstrsave (objfile->md, filename);
objfile->mtime = bfd_get_mtime (abfd);
objfile->prefix = prefix;
if (build_objfile_section_table (objfile))
error ("Unable to find the file sections in `%s': %s",
objfile->name, bfd_errmsg (bfd_get_error ()));
for (i = 0; i < MAX_SECTIONS; i++)
{
addrs.other[i].name = NULL;
addrs.other[i].addr = addr;
addrs.other[i].sectindex = 0;
addrs.addrs_are_offsets = 0;
}
syms_from_objfile (objfile, &addrs, 0, 0, 0, 0);
ALL_OBJFILE_PSYMTABS (objfile, p)
s = PSYMTAB_TO_SYMTAB (p);
objfile_demangle_msymbols (objfile);
filename = xstrdup (objfile->name);
mtime = bfd_get_mtime (abfd);
mmalloc_endpoints (objfile->md, &start, &end);
r.len = end - start;
r.mapped_start = start;
r.from_start = start;
r.to_start = 0;
repositioned = objfile_reposition (objfile, &r);
mmalloc_setkey (objfile->md, 0, 0);
mmalloc_setkey (objfile->md, 1, repositioned);
link_objfile (objfile);
objfile->obfd = NULL;
free_objfile (objfile);
if (rename (temp_filename, filename) != 0) {
warning ("unable to rename created temporary file");
unlink (temp_filename);
return NULL;
}
objfile = open_mapped_objfile (filename, abfd, mtime, 0);
if (objfile == NULL) {
warning ("unable to read mapped objfile");
return NULL;
}
if (info_verbose)
printf (" done\n");
swapin_gdbarch_swap (current_gdbarch);
return objfile;
}
#endif
struct objfile *
create_objfile (bfd *abfd)
{
struct objfile *objfile;
objfile = (struct objfile *) xmalloc (sizeof (struct objfile));
memset (objfile, 0, sizeof (struct objfile));
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->psymbol_obstack, 0, 0, xmalloc, xfree);
obstack_specify_allocation (&objfile->symbol_obstack, 0, 0, xmalloc, xfree);
obstack_specify_allocation (&objfile->type_obstack, 0, 0, xmalloc, xfree);
init_objfile (objfile);
return objfile;
}
#endif
static inline void validate_context (struct relocation_context *r)
{
if (((r->to_start >= r->from_start) && (r->to_start <= (r->from_start + r->len)))
|| ((r->from_start >= r->to_start) && (r->from_start <= (r->to_start + r->len))))
{
internal_error (__FILE__, __LINE__, "relocation contained overlapping regions");
}
}
static inline int
relocate (struct relocation_context *r, void *ptr, void **new)
{
size_t addr = (size_t) ptr;
if (ptr == NULL)
return 0;
if ((addr >= r->to_start) && (addr <= (r->to_start + r->len)))
{
return 0;
}
if ((addr >= r->from_start) && (addr <= (r->from_start + r->len)))
{
*new = (void *) (addr + r->to_start - r->from_start);
return 1;
}
internal_error (__FILE__, __LINE__, "relocation was not in valid range");
}
static size_t
lookup (struct relocation_context *r, void *ptr)
{
size_t addr = (size_t) ptr;
if (ptr == NULL)
return 0;
if ((addr >= r->from_start) && (addr <= (r->from_start + r->len)))
return (addr - r->from_start + r->mapped_start);
if ((addr >= r->to_start) && (addr <= (r->to_start + r->len)))
return (addr - r->to_start + r->mapped_start);
internal_error (__FILE__, __LINE__, "relocation was not in valid range");
}
#define RELOCATE(x) (relocate (r, x, (void **) &x))
#define LOOKUP(x) ((typeof (x)) lookup (r, x))
static void
move_type (struct relocation_context *r, struct type *t);
static void
move_field (struct relocation_context *r, struct field *f)
{
if (f->static_kind != 0)
RELOCATE (f->loc.physname);
if (RELOCATE (f->type))
move_type (r, LOOKUP (f->type));
RELOCATE (f->name);
}
static void
move_cplus_struct (struct relocation_context *r, struct cplus_struct_type *cp)
{
unsigned int i, j;
if (cp == NULL)
return;
RELOCATE (cp->virtual_field_bits);
RELOCATE (cp->private_field_bits);
RELOCATE (cp->protected_field_bits);
RELOCATE (cp->ignore_field_bits);
if (RELOCATE (cp->fn_fieldlists))
{
struct fn_fieldlist *fn = LOOKUP (cp->fn_fieldlists);
for (i = 0; i < cp->nfn_fields; i++)
{
RELOCATE (fn[i].name);
if (RELOCATE (fn[i].fn_fields))
{
struct fn_field *fld = LOOKUP (fn[i].fn_fields);
for (j = 0; j < fn[i].length; j++)
{
RELOCATE (fld[j].physname);
RELOCATE (fld[j].type);
RELOCATE (fld[j].fcontext);
}
}
}
}
if (RELOCATE (cp->template_args))
for (i = 0; i < cp->ntemplate_args; i++)
{
RELOCATE (LOOKUP (cp->template_args)[i].name);
RELOCATE (LOOKUP (cp->template_args)[i].type);
}
if (RELOCATE (cp->instantiations))
for (i = 0; i < cp->ninstantiations; i++)
RELOCATE (LOOKUP (cp->instantiations)[i]);
if (RELOCATE (cp->runtime_ptr))
{
RELOCATE (LOOKUP (cp->runtime_ptr)->primary_base);
RELOCATE (LOOKUP (cp->runtime_ptr)->virtual_base_list);
}
if (RELOCATE (cp->localtype_ptr))
RELOCATE (LOOKUP (cp->localtype_ptr)->file);
}
static void
move_main_type (struct relocation_context *r, struct main_type *m)
{
unsigned int i;
if (m == NULL)
return;
RELOCATE (m->name);
RELOCATE (m->tag_name);
RELOCATE (m->objfile);
if (RELOCATE (m->target_type))
move_type (r, LOOKUP (m->target_type));
if (RELOCATE (m->fields))
{
for (i = 0; i < m->nfields; i++)
move_field (r, LOOKUP (m->fields) + i);
}
if (RELOCATE (m->vptr_basetype))
move_type (r, LOOKUP (m->vptr_basetype));
if ((m->code == TYPE_CODE_STRUCT)
|| (m->code == TYPE_CODE_UNION))
if (RELOCATE (m->type_specific.cplus_stuff))
move_cplus_struct (r, LOOKUP (m->type_specific.cplus_stuff));
}
static void
move_type (struct relocation_context *r, struct type *t)
{
if (t == NULL)
return;
if (RELOCATE (t->pointer_type))
move_type (r, LOOKUP (t->pointer_type));
if (RELOCATE (t->reference_type))
move_type (r, LOOKUP (t->reference_type));
if (RELOCATE (t->chain))
move_type (r, LOOKUP (t->chain));
if (RELOCATE (t->main_type))
move_main_type (r, LOOKUP (t->main_type));
}
static void
move_symbol_general (struct relocation_context *r,
struct general_symbol_info *g)
{
if (g == NULL)
return;
g->bfd_section = NULL;
RELOCATE (g->name);
RELOCATE (g->language_specific.cplus_specific.demangled_name);
}
static void
move_msymbol (struct relocation_context *r, struct minimal_symbol *m)
{
if (m == NULL)
return;
move_symbol_general (r, &m->ginfo);
if (RELOCATE (m->hash_next))
move_msymbol (r, LOOKUP (m->hash_next));
if (RELOCATE (m->demangled_hash_next))
move_msymbol (r, LOOKUP (m->demangled_hash_next));
}
static void
move_psymbol (struct relocation_context *r, struct partial_symbol *p)
{
if (p == NULL)
return;
move_symbol_general (r, &p->ginfo);
}
static void
move_symbol (struct relocation_context *r, struct symbol *s)
{
if (s == NULL)
return;
move_symbol_general (r, &s->ginfo);
if (s->aclass == LOC_BLOCK)
RELOCATE (s->ginfo.value.block);
if (RELOCATE (s->type))
move_type (r, LOOKUP (s->type));
if (RELOCATE (s->hash_next))
move_symbol (r, LOOKUP (s->hash_next));
}
static void
move_block (struct relocation_context *r, struct block *b)
{
unsigned int i;
if (b == NULL)
return;
RELOCATE (BLOCK_FUNCTION (b));
RELOCATE (BLOCK_SUPERBLOCK (b));
for (i = 0; i < BLOCK_NSYMS (b); i++)
{
if (RELOCATE (b->sym[i]))
move_symbol (r, LOOKUP (b->sym[i]));
}
}
void
move_blockvector (struct relocation_context *r, struct blockvector *b)
{
unsigned int i;
if (b == NULL)
return;
for (i = 0; i < b->nblocks; i++)
{
if (RELOCATE (b->block[i]))
move_block (r, LOOKUP (b->block[i]));
}
}
void
move_psymtab (struct relocation_context *r, struct partial_symtab *p)
{
unsigned int i;
if (p == NULL)
return;
RELOCATE (p->filename);
RELOCATE (p->fullname);
RELOCATE (p->objfile);
RELOCATE (p->section_offsets);
RELOCATE (p->symtab);
RELOCATE (p->read_symtab_private);
RELOCATE (p->dependencies);
for (i = 0; i < p->number_of_dependencies; i++)
RELOCATE (LOOKUP (p->dependencies)[i]);
}
void
move_symtab (struct relocation_context *r, struct symtab *s)
{
if (s == NULL)
return;
if (RELOCATE (s->blockvector))
move_blockvector (r, LOOKUP (s->blockvector));
RELOCATE (s->linetable);
RELOCATE (s->filename);
RELOCATE (s->dirname);
RELOCATE (s->free_ptr);
RELOCATE (s->line_charpos);
RELOCATE (s->debugformat);
RELOCATE (s->version);
RELOCATE (s->fullname);
RELOCATE (s->objfile);
}
static void
move_psymbol_allocation_list (struct relocation_context *r,
struct psymbol_allocation_list *l)
{
unsigned int i;
if (l == NULL)
return;
RELOCATE (l->list);
RELOCATE (l->next);
for (i = 0; i < l->size; i++)
{
if (RELOCATE (LOOKUP (l->list)[i]))
move_psymbol (r, LOOKUP (LOOKUP (l->list)[i]));
}
}
static void
move_objfile (struct relocation_context *r, struct objfile *o)
{
unsigned int i;
struct minimal_symbol *ms;
struct partial_symtab *ps;
struct symtab *ss;
validate_context (r);
if (o == NULL)
return;
RELOCATE (o->msymbols);
for (ms = LOOKUP (o->msymbols); (ms->ginfo.name != NULL); ms++) {
move_msymbol (r, ms);
}
for (i = 0; i < MINIMAL_SYMBOL_HASH_SIZE; i++) {
RELOCATE (o->msymbol_hash[i]);
}
for (i = 0; i < MINIMAL_SYMBOL_HASH_SIZE; i++) {
RELOCATE (o->msymbol_demangled_hash[i]);
}
RELOCATE (o->section_offsets);
o->sections = NULL;
o->sections_end = NULL;
RELOCATE (o->psymbol_cache);
RELOCATE (o->macro_cache);
RELOCATE (o->sym_stab_info);
RELOCATE (o->sym_private);
move_psymbol_allocation_list (r, &o->global_psymbols);
move_psymbol_allocation_list (r, &o->static_psymbols);
RELOCATE (o->psymtabs);
ps = LOOKUP (o->psymtabs);
while (ps != NULL) {
move_psymtab (r, ps);
RELOCATE (ps->next);
ps = LOOKUP (ps->next);
}
RELOCATE (o->symtabs);
ss = LOOKUP (o->symtabs);
while (ss != NULL) {
move_symtab (r, ss);
RELOCATE (ss->next);
ss = LOOKUP (ss->next);
}
}
#if MAPPED_SYMFILES
static void verify (struct objfile *o, void (* f) (struct relocation_context *, void *), void *p)
{
size_t start = 0;
size_t end = 0;
struct relocation_context r;
if (o->md == NULL)
error ("Objfile may not be verified if not in memory.");
mmalloc_endpoints (o->md, &start, &end);
r.mapped_start = start;
r.from_start = start;
r.to_start = 0xf0000000;
r.len = end - start;
relocate (&r, p, (void **) &p);
(* f) (&r, (void *) lookup (&r, p));
r.mapped_start = start;
r.from_start = 0xf0000000;
r.to_start = start;
relocate (&r, p, (void **) &p);
(* f) (&r, (void **) lookup (&r, p));
}
void objfile_verify (struct objfile *o)
{
verify (o, move_objfile, (void *) o);
}
void symbol_verify (struct objfile *o, struct symbol *s)
{
verify (o, move_symbol, (void *) s);
}
void type_verify (struct objfile *o, struct type *t)
{
verify (o, move_type, (void *) t);
}
struct objfile *objfile_reposition (struct objfile *o, struct relocation_context *r)
{
if (o->md == NULL)
error ("Objfile may not be moved in memory.");
validate_context (r);
RELOCATE (o);
move_objfile (r, LOOKUP (o));
return o;
}
#endif
void
_initialize_cached_symfile ()
{
add_show_from_set
(add_set_cmd ("cached-symfile-path", class_support, var_string,
(char *) &cached_symfile_path,
"Set list of directories to search for cached symbol files.",
&setlist),
&showlist);
cached_symfile_path = xstrdup ("./gdb-symfile-cache:./syms:/usr/libexec/gdb/symfiles");
add_show_from_set
(add_set_cmd ("cached-symfile-dir", class_support, var_string,
(char *) &cached_symfile_path,
"Set directory in which to generate cached symbol files.",
&setlist),
&showlist);
cached_symfile_dir = xstrdup ("./gdb-symfile-cache");
}