diff options
author | Ian Lance Taylor <ian@airs.com> | 1995-11-20 19:57:30 +0000 |
---|---|---|
committer | Ian Lance Taylor <ian@airs.com> | 1995-11-20 19:57:30 +0000 |
commit | b5403ad75475a885a050a070de97e640ff3add44 (patch) | |
tree | f4a6ce6898ed4e0fc776c2b60b783d2102d41efb /bfd/xcofflink.c | |
parent | e7b6403a67d83ad3e478f99addefdbe2e5e5f379 (diff) | |
download | gdb-b5403ad75475a885a050a070de97e640ff3add44.zip gdb-b5403ad75475a885a050a070de97e640ff3add44.tar.gz gdb-b5403ad75475a885a050a070de97e640ff3add44.tar.bz2 |
* xcofflink.c (xcoff_link_input_bfd): Adjust the TOC anchor value
if it is not large enough to accomodate the entire TOC area with
signed 16 bit offsets.
(xcoff_write_global_symbol): Handle negative TOC offsets in global
linkage code.
(_bfd_ppc_xcoff_relocate_section): Adjust relocations against a
TOC anchor to use the TOC value used in the output file.
Diffstat (limited to 'bfd/xcofflink.c')
-rw-r--r-- | bfd/xcofflink.c | 49 |
1 files changed, 38 insertions, 11 deletions
diff --git a/bfd/xcofflink.c b/bfd/xcofflink.c index d91e341..78a2a44 100644 --- a/bfd/xcofflink.c +++ b/bfd/xcofflink.c @@ -2477,7 +2477,7 @@ bfd_xcoff_export_symbol (output_bfd, info, harg, syscall) char *fnname; struct xcoff_link_hash_entry *hfn; - fnname = (char *) malloc (strlen (h->root.root.string + 2)); + fnname = (char *) malloc (strlen (h->root.root.string) + 2); if (fnname == NULL) { bfd_set_error (bfd_error_no_memory); @@ -4011,12 +4011,33 @@ xcoff_link_input_bfd (finfo, input_bfd) skip = true; else { + bfd_vma tocval, tocend; + + tocval = ((*csectpp)->output_section->vma + + (*csectpp)->output_offset + + isym.n_value + - (*csectpp)->vma); + /* We want to find out if tocval is a good value to use + as the TOC anchor--that is, whether we can access all + of the TOC using a 16 bit offset from tocval. This + test assumes that the TOC comes at the end of the + output section, as it does in the default linker + script. If the TOC anchor is too far into the .toc + section, the relocation routine will report + overflows. */ + tocend = ((*csectpp)->output_section->vma + + (*csectpp)->output_section->_raw_size); + if (tocval + 0x8000 < tocend) + { + bfd_vma tocadd; + + tocadd = tocend - (tocval + 0x8000); + tocval += tocadd; + isym.n_value += tocadd; + } + finfo->toc_symindx = output_index; - xcoff_data (finfo->output_bfd)->toc = - ((*csectpp)->output_section->vma - + (*csectpp)->output_offset - + isym.n_value - - (*csectpp)->vma); + xcoff_data (finfo->output_bfd)->toc = tocval; xcoff_data (finfo->output_bfd)->toc_section = (*csectpp)->output_section; require = true; @@ -4993,7 +5014,7 @@ xcoff_write_global_symbol (h, p) - xcoff_data (output_bfd)->toc); if ((h->descriptor->flags & XCOFF_SET_TOC) != 0) tocoff += h->descriptor->u.toc_offset; - bfd_put_32 (output_bfd, XCOFF_GLINK_FIRST | tocoff, p); + bfd_put_32 (output_bfd, XCOFF_GLINK_FIRST | (tocoff & 0xffff), p); for (i = 0, p += 4; i < sizeof xcoff_glink_code / sizeof xcoff_glink_code[0]; i++, p += 4) @@ -5568,10 +5589,16 @@ _bfd_ppc_xcoff_relocate_section (output_bfd, info, input_bfd, else { sec = sections[symndx]; - val = (sec->output_section->vma - + sec->output_offset - + sym->n_value - - sec->vma); + /* Hack to make sure we use the right TOC anchor value + if this reloc is against the TOC anchor. */ + if (sec->name[3] == '0' + && strcmp (sec->name, ".tc0") == 0) + val = xcoff_data (output_bfd)->toc; + else + val = (sec->output_section->vma + + sec->output_offset + + sym->n_value + - sec->vma); } } else |