diff options
Diffstat (limited to 'gdb/objfiles.c')
-rw-r--r-- | gdb/objfiles.c | 91 |
1 files changed, 90 insertions, 1 deletions
diff --git a/gdb/objfiles.c b/gdb/objfiles.c index 278aa44..7fb53e7 100644 --- a/gdb/objfiles.c +++ b/gdb/objfiles.c @@ -341,7 +341,96 @@ free_all_objfiles () free_objfile (objfile); } } - + +/* Relocate OBJFILE to NEW_OFFSETS. There should be OBJFILE->NUM_SECTIONS + entries in new_offsets. */ +void +objfile_relocate (objfile, new_offsets) + struct objfile *objfile; + struct section_offsets *new_offsets; +{ + struct section_offsets *delta = (struct section_offsets *) alloca + (sizeof (struct section_offsets) + + objfile->num_sections * sizeof (delta->offsets)); + + { + int i; + int something_changed = 0; + for (i = 0; i < objfile->num_sections; ++i) + { + ANOFFSET (delta, i) = + ANOFFSET (new_offsets, i) - ANOFFSET (objfile->section_offsets, i); + if (ANOFFSET (delta, i) != 0) + something_changed = 1; + } + if (!something_changed) + return; + } + + /* OK, get all the symtabs. */ + { + struct symtab *s; + + for (s = objfile->symtabs; s; s = s->next) + { + struct linetable *l; + struct blockvector *bv; + int i; + + /* First the line table. */ + l = LINETABLE (s); + if (l) + { + for (i = 0; i < l->nitems; ++i) + l->item[i].pc += ANOFFSET (delta, s->block_line_section); + } + + /* Don't relocate a shared blockvector more than once. */ + if (!s->primary) + continue; + + bv = BLOCKVECTOR (s); + for (i = 0; i < BLOCKVECTOR_NBLOCKS (bv); ++i) + { + struct block *b; + int j; + + b = BLOCKVECTOR_BLOCK (bv, i); + BLOCK_START (b) += ANOFFSET (delta, s->block_line_section); + BLOCK_END (b) += ANOFFSET (delta, s->block_line_section); + + for (j = 0; j < BLOCK_NSYMS (b); ++j) + { + struct symbol *sym = BLOCK_SYM (b, j); + /* The RS6000 code from which this was taken skipped + any symbols in STRUCT_NAMESPACE or UNDEF_NAMESPACE. + But I'm leaving out that test, on the theory that + they can't possibly pass the tests below. */ + if ((SYMBOL_CLASS (sym) == LOC_LABEL + || SYMBOL_CLASS (sym) == LOC_STATIC) + && SYMBOL_SECTION (sym) >= 0) + { + SYMBOL_VALUE_ADDRESS (sym) += + ANOFFSET (delta, SYMBOL_SECTION (sym)); + } + } + } + } + } + + { + struct minimal_symbol *msym; + ALL_OBJFILE_MSYMBOLS (objfile, msym) + SYMBOL_VALUE_ADDRESS (msym) += ANOFFSET (delta, SYMBOL_SECTION (msym)); + } + + { + int i; + for (i = 0; i < objfile->num_sections; ++i) + ANOFFSET (objfile->section_offsets, i) = ANOFFSET (new_offsets, i); + } +} + /* Many places in gdb want to test just to see if we have any partial symbols available. This function returns zero if none are currently available, nonzero otherwise. */ |