diff options
author | Tristan Gingold <gingold@adacore.com> | 2011-12-15 11:01:14 +0000 |
---|---|---|
committer | Tristan Gingold <gingold@adacore.com> | 2011-12-15 11:01:14 +0000 |
commit | fa2ec0ad0b2a0e4768a9a5a673b092843994d333 (patch) | |
tree | 88f1dc799a2ee22c8e77a6b79ecabd2100a8f54c /bfd/mach-o.c | |
parent | 65fcfbd8e78197cd19e94b4e9250344a391d0377 (diff) | |
download | gdb-fa2ec0ad0b2a0e4768a9a5a673b092843994d333.tar.gz |
2011-12-15 Shinichiro Hamaji <shinichiro.hamaji@gmail.com>
* mach-o.c (bfd_mach_o_canonicalize_reloc): Update relocation
table only when there isn't the cahce.
(bfd_mach_o_get_dynamic_reloc_upper_bound): Need one more space
for a pointer for the watchdog.
(bfd_mach_o_canonicalize_dynamic_reloc): Utilize cache like
bfd_mach_o_canonicalize_reloc.
(bfd_mach_o_close_and_cleanup): Call bfd_mach_o_free_cached_info.
(bfd_mach_o_free_cached_info): Free up cache data.
* mach-o.h (reloc_cache): A place to store cache of dynamic relocs.
(bfd_mach_o_free_cached_info): Add declaration.
Diffstat (limited to 'bfd/mach-o.c')
-rw-r--r-- | bfd/mach-o.c | 78 |
1 files changed, 53 insertions, 25 deletions
diff --git a/bfd/mach-o.c b/bfd/mach-o.c index 0c2c2f77e66..182f0efc2df 100644 --- a/bfd/mach-o.c +++ b/bfd/mach-o.c @@ -1040,21 +1040,25 @@ bfd_mach_o_canonicalize_reloc (bfd *abfd, asection *asect, if (bed->_bfd_mach_o_swap_reloc_in == NULL) return 0; - res = bfd_malloc (asect->reloc_count * sizeof (arelent)); - if (res == NULL) - return -1; - - if (bfd_mach_o_canonicalize_relocs (abfd, asect->rel_filepos, - asect->reloc_count, res, syms) < 0) + if (asect->relocation == NULL) { - free (res); - return -1; + res = bfd_malloc (asect->reloc_count * sizeof (arelent)); + if (res == NULL) + return -1; + + if (bfd_mach_o_canonicalize_relocs (abfd, asect->rel_filepos, + asect->reloc_count, res, syms) < 0) + { + free (res); + return -1; + } + asect->relocation = res; } + res = asect->relocation; for (i = 0; i < asect->reloc_count; i++) rels[i] = &res[i]; rels[i] = NULL; - asect->relocation = res; return i; } @@ -1066,7 +1070,7 @@ bfd_mach_o_get_dynamic_reloc_upper_bound (bfd *abfd) if (mdata->dysymtab == NULL) return 1; - return (mdata->dysymtab->nextrel + mdata->dysymtab->nlocrel) + return (mdata->dysymtab->nextrel + mdata->dysymtab->nlocrel + 1) * sizeof (arelent *); } @@ -1089,25 +1093,32 @@ bfd_mach_o_canonicalize_dynamic_reloc (bfd *abfd, arelent **rels, if (bed->_bfd_mach_o_swap_reloc_in == NULL) return 0; - res = bfd_malloc ((dysymtab->nextrel + dysymtab->nlocrel) * sizeof (arelent)); - if (res == NULL) - return -1; - - if (bfd_mach_o_canonicalize_relocs (abfd, dysymtab->extreloff, - dysymtab->nextrel, res, syms) < 0) + if (mdata->dyn_reloc_cache == NULL) { - free (res); - return -1; - } + res = bfd_malloc ((dysymtab->nextrel + dysymtab->nlocrel) + * sizeof (arelent)); + if (res == NULL) + return -1; - if (bfd_mach_o_canonicalize_relocs (abfd, dysymtab->locreloff, - dysymtab->nlocrel, - res + dysymtab->nextrel, syms) < 0) - { - free (res); - return -1; + if (bfd_mach_o_canonicalize_relocs (abfd, dysymtab->extreloff, + dysymtab->nextrel, res, syms) < 0) + { + free (res); + return -1; + } + + if (bfd_mach_o_canonicalize_relocs (abfd, dysymtab->locreloff, + dysymtab->nlocrel, + res + dysymtab->nextrel, syms) < 0) + { + free (res); + return -1; + } + + mdata->dyn_reloc_cache = res; } + res = mdata->dyn_reloc_cache; for (i = 0; i < dysymtab->nextrel + dysymtab->nlocrel; i++) rels[i] = &res[i]; rels[i] = NULL; @@ -3756,9 +3767,26 @@ bfd_mach_o_close_and_cleanup (bfd *abfd) if (bfd_get_format (abfd) == bfd_object && mdata != NULL) _bfd_dwarf2_cleanup_debug_info (abfd, &mdata->dwarf2_find_line_info); + bfd_mach_o_free_cached_info (abfd); + return _bfd_generic_close_and_cleanup (abfd); } +bfd_boolean bfd_mach_o_free_cached_info (bfd *abfd) +{ + bfd_mach_o_data_struct *mdata = bfd_mach_o_get_data (abfd); + asection *asect; + free (mdata->dyn_reloc_cache); + mdata->dyn_reloc_cache = NULL; + for (asect = abfd->sections; asect != NULL; asect = asect->next) + { + free (asect->relocation); + asect->relocation = NULL; + } + + return TRUE; +} + #define bfd_mach_o_bfd_reloc_type_lookup _bfd_norelocs_bfd_reloc_type_lookup #define bfd_mach_o_bfd_reloc_name_lookup _bfd_norelocs_bfd_reloc_name_lookup |