From e84d6fca26caaf6b02718efa0f1a4fb0d344348c Mon Sep 17 00:00:00 2001 From: Alan Modra Date: Tue, 12 Nov 2002 15:44:24 +0000 Subject: * 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. --- bfd/bfd.c | 130 ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 130 insertions(+) (limited to 'bfd/bfd.c') diff --git a/bfd/bfd.c b/bfd/bfd.c index cff7119..5412ac8 100644 --- a/bfd/bfd.c +++ b/bfd/bfd.c @@ -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); +} -- cgit v1.1