diff options
author | Alan Modra <amodra@gmail.com> | 2002-11-12 15:44:24 +0000 |
---|---|---|
committer | Alan Modra <amodra@gmail.com> | 2002-11-12 15:44:24 +0000 |
commit | e84d6fca26caaf6b02718efa0f1a4fb0d344348c (patch) | |
tree | 7dfaac5631eded3e7fcacfd1097415db98d4841a /bfd/bfd.c | |
parent | c4c41219636642438223c7b46a2c8e1467faba06 (diff) | |
download | gdb-e84d6fca26caaf6b02718efa0f1a4fb0d344348c.zip gdb-e84d6fca26caaf6b02718efa0f1a4fb0d344348c.tar.gz gdb-e84d6fca26caaf6b02718efa0f1a4fb0d344348c.tar.bz2 |
* bfd.c (struct bfd_preserve): New.
(bfd_preserve_save): New function.
(bfd_preserve_restore): Ditto.
(bfd_preserve_finish): Ditto.
* bfd-in2.h: Regenerate.
* mach-o.c: Formatting.
(bfd_mach_o_scan_read_symtab_symbol): Make "value" unsigned.
(bfd_mach_o_object_p): Use bfd_preserve_save/restore/finish.
(bfd_mach_o_core_p): Ditto.
(bfd_mach_o_scan): Pass in mdata.
* mach-o.h (bfd_mach_o_scan): Update prototype.
* pef.c: Formatting.
(bfd_pef_object_p): Use bfd_preserve_save/restore/finish.
(bfd_pef_xlib_object_p): Ditto.
(bfd_pef_scan): Pass in mdata. Move version check to bfd_pef_object_p.
* pef.h (bfd_pef_scan): Update prototype.
* xsym.c: Formatting, K&R fixes.
(bfd_sym_object_p): Use bfd_preserve_save/restore/finish.
(bfd_sym_scan): New function split out from bfd_sym_object_p.
* xsym.h (bfd_sym_scan): Declare.
* elfcode.h (elf_object_p): Use bfd_preserve_save/restore/finish.
(elf_core_file_p): Likewise.
* targets.c (_bfd_target_vector): Revert 2002-11-08 change.
Diffstat (limited to 'bfd/bfd.c')
-rw-r--r-- | bfd/bfd.c | 130 |
1 files changed, 130 insertions, 0 deletions
@@ -1392,3 +1392,133 @@ bfd_alt_mach_code (abfd, alternative) return false; } + +/* +CODE_FRAGMENT + +.struct bfd_preserve +.{ +. PTR marker; +. PTR tdata; +. flagword flags; +. const struct bfd_arch_info *arch_info; +. struct sec *sections; +. struct sec **section_tail; +. unsigned int section_count; +. struct bfd_hash_table section_htab; +.}; +. +*/ + +/* +FUNCTION + bfd_preserve_save + +SYNOPSIS + boolean bfd_preserve_save (bfd *, struct bfd_preserve *); + +DESCRIPTION + When testing an object for compatibility with a particular + target back-end, the back-end object_p function needs to set + up certain fields in the bfd on successfully recognizing the + object. This typically happens in a piecemeal fashion, with + failures possible at many points. On failure, the bfd is + supposed to be restored to its initial state, which is + virtually impossible. However, restoring a subset of the bfd + state works in practice. This function stores the subset and + reinitializes the bfd. + +*/ + +boolean +bfd_preserve_save (abfd, preserve) + bfd *abfd; + struct bfd_preserve *preserve; +{ + preserve->tdata = abfd->tdata.any; + preserve->arch_info = abfd->arch_info; + preserve->flags = abfd->flags; + + preserve->sections = abfd->sections; + preserve->section_tail = abfd->section_tail; + preserve->section_count = abfd->section_count; + preserve->section_htab = abfd->section_htab; + + if (! bfd_hash_table_init (&abfd->section_htab, bfd_section_hash_newfunc)) + return false; + + abfd->tdata.any = NULL; + abfd->arch_info = &bfd_default_arch_struct; + abfd->flags = 0; + + abfd->sections = NULL; + abfd->section_tail = &abfd->sections; + abfd->section_count = 0; + + return true; +} + +/* +FUNCTION + bfd_preserve_restore + +SYNOPSIS + void bfd_preserve_restore (bfd *, struct bfd_preserve *); + +DESCRIPTION + This function restores bfd state saved by bfd_preserve_save. + If MARKER is non-NULL in struct bfd_preserve then that block + and all subsequently bfd_alloc'd memory is freed. + +*/ + +void +bfd_preserve_restore (abfd, preserve) + bfd *abfd; + struct bfd_preserve *preserve; +{ + bfd_hash_table_free (&abfd->section_htab); + + abfd->tdata.any = preserve->tdata; + abfd->arch_info = preserve->arch_info; + abfd->flags = preserve->flags; + + abfd->section_htab = preserve->section_htab; + abfd->sections = preserve->sections; + abfd->section_tail = preserve->section_tail; + abfd->section_count = preserve->section_count; + + /* bfd_release frees all memory more recently bfd_alloc'd than + its arg, as well as its arg. */ + if (preserve->marker != NULL) + { + bfd_release (abfd, preserve->marker); + preserve->marker = NULL; + } +} + +/* +FUNCTION + bfd_preserve_finish + +SYNOPSIS + void bfd_preserve_finish (bfd *, struct bfd_preserve *); + +DESCRIPTION + This function should be called when the bfd state saved by + bfd_preserve_save is no longer needed. ie. when the back-end + object_p function returns with success. + +*/ + +void +bfd_preserve_finish (abfd, preserve) + bfd *abfd ATTRIBUTE_UNUSED; + struct bfd_preserve *preserve; +{ + /* It would be nice to be able to free more memory here, eg. old + tdata, but that's not possible since these blocks are sitting + inside bfd_alloc'd memory. The section hash is on a separate + objalloc. */ + bfd_hash_table_free (&preserve->section_htab); +} |