summaryrefslogtreecommitdiff
path: root/bfd/mach-o.c
diff options
context:
space:
mode:
authorTristan Gingold <gingold@adacore.com>2011-12-15 11:01:14 +0000
committerTristan Gingold <gingold@adacore.com>2011-12-15 11:01:14 +0000
commitfa2ec0ad0b2a0e4768a9a5a673b092843994d333 (patch)
tree88f1dc799a2ee22c8e77a6b79ecabd2100a8f54c /bfd/mach-o.c
parent65fcfbd8e78197cd19e94b4e9250344a391d0377 (diff)
downloadgdb-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.c78
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