diff options
author | Ian Lance Taylor <ian@airs.com> | 1994-03-25 22:37:55 +0000 |
---|---|---|
committer | Ian Lance Taylor <ian@airs.com> | 1994-03-25 22:37:55 +0000 |
commit | a3a33af390c3a99e00b20847a102e307cfb538c7 (patch) | |
tree | b262eb6f85a5b10fe60cdc47a0f753178e889283 /bfd/ecofflink.c | |
parent | f078dc7cf26a816ef0bb66be8b819ac549486e86 (diff) | |
download | gdb-a3a33af390c3a99e00b20847a102e307cfb538c7.zip gdb-a3a33af390c3a99e00b20847a102e307cfb538c7.tar.gz gdb-a3a33af390c3a99e00b20847a102e307cfb538c7.tar.bz2 |
Changes to support linker relaxing of embedded MIPS PIC code to
use a five instruction sequence for funtion calls which are out of
range of the bal instruction.
* libecoff.h (struct ecoff_section_tdata): Define.
(ecoff_section_data): Define.
(ecoff_bfd_relax_section): Don't define.
* ecoff.c (ecoff_final_link_debug_accumulate): Don't read or free
the debugging information if it has already been read.
(ecoff_indirect_link_order): Handle _cooked_size being different
from _raw_size. Don't reread the contents or the relocs if they
have already been read in.
* coff-mips.c (mips_howto_table): Change bitsize of PCREL16 from
18 to 16.
(PCREL16_EXPANSION_ADJUSTMENT): Define.
(mips_relocate_refhi): Take adjust argument.
(mips_relocate_section): Handle reloc offsets stored in section
used_by_bfd field. Call mips_relax_pcrel16 to handle details of
expanding an out of range PCREL16. Keep trace of adjustments
required by expansions. Set s and unset h when converting a reloc
from undefined to section. Change handling of PC relative relocs:
if against a section, they are correct in the object file, if
against an external symbol they are pcrel_offset.
(mips_relax_section): New function.
(mips_relax_pcrel16): New function.
(ecoff_bfd_relax_section): Define.
* coff-alpha.c (ecoff_bfd_relax_section): Define.
* ecofflink.c (bfd_ecoff_debug_accumulate): Handle adjustments
built by mips_relax_section when writing out addresses.
* elf32-mips.c (mips_elf_read_ecoff_info): Clear adjust field.
Diffstat (limited to 'bfd/ecofflink.c')
-rw-r--r-- | bfd/ecofflink.c | 128 |
1 files changed, 108 insertions, 20 deletions
diff --git a/bfd/ecofflink.c b/bfd/ecofflink.c index a4507ea..4b14dcd 100644 --- a/bfd/ecofflink.c +++ b/bfd/ecofflink.c @@ -519,10 +519,17 @@ bfd_ecoff_debug_accumulate (handle, output_bfd, output_debug, output_swap, hash reduces the chance that we will merge symbol information that should not be merged. */ name = input_debug->ss + fdr.issBase + fdr.rss; - lookup = (char *) alloca (strlen (name) + 20); + + lookup = (char *) malloc (strlen (name) + 20); + if (lookup == NULL) + { + bfd_set_error (bfd_error_no_memory); + return false; + } sprintf (lookup, "%s %lx", name, fdr.csym); fh = string_hash_lookup (&ainfo->fdr_hash, lookup, true, true); + free (lookup); if (fh == (struct string_hash_entry *) NULL) return false; @@ -600,6 +607,22 @@ bfd_ecoff_debug_accumulate (handle, output_bfd, output_debug, output_swap, else (*input_swap->swap_fdr_in) (input_bfd, (PTR) fdr_ptr, &fdr); + /* Adjust the FDR address for any changes that may have been + made by relaxing. */ + if (input_debug->adjust != (struct ecoff_value_adjust *) NULL) + { + bfd_vma adr; + struct ecoff_value_adjust *adjust; + + adr = fdr.adr; + for (adjust = input_debug->adjust; + adjust != (struct ecoff_value_adjust *) NULL; + adjust = adjust->next) + if (adr >= adjust->start + && adr < adjust->end) + fdr.adr += adjust->adjust; + } + /* FIXME: It is conceivable that this FDR points to the .init or .fini section, in which case this will not do the right thing. */ @@ -641,6 +664,19 @@ bfd_ecoff_debug_accumulate (handle, output_bfd, output_debug, output_swap, case stLabel: case stProc: case stStaticProc: + if (input_debug->adjust != (struct ecoff_value_adjust *) NULL) + { + bfd_vma value; + struct ecoff_value_adjust *adjust; + + value = internal_sym.value; + for (adjust = input_debug->adjust; + adjust != (struct ecoff_value_adjust *) NULL; + adjust = adjust->next) + if (value >= adjust->start + && value < adjust->end) + internal_sym.value += adjust->adjust; + } internal_sym.value += section_adjust[internal_sym.sc]; break; @@ -1253,7 +1289,7 @@ ecoff_write_symhdr (abfd, debug, swap, where) file_ptr where; { HDRR * const symhdr = &debug->symbolic_header; - char *buff; + char *buff = NULL; ecoff_align_debug (abfd, debug, swap); @@ -1288,13 +1324,25 @@ ecoff_write_symhdr (abfd, debug, swap, where) SET (cbExtOffset, iextMax, swap->external_ext_size); #undef SET - buff = (PTR) alloca (swap->external_hdr_size); + buff = (PTR) malloc (swap->external_hdr_size); + if (buff == NULL && swap->external_hdr_size != 0) + { + bfd_set_error (bfd_error_no_memory); + goto error_return; + } + (*swap->swap_hdr_out) (abfd, symhdr, buff); if (bfd_write (buff, 1, swap->external_hdr_size, abfd) != swap->external_hdr_size) - return false; + goto error_return; + if (buff != NULL) + free (buff); return true; + error_return: + if (buff != NULL) + free (buff); + return false; } /* Write out the ECOFF debugging information. This function assumes @@ -1377,10 +1425,20 @@ ecoff_write_shuffle (abfd, swap, shuffle, space) bfd_byte *s; i = swap->debug_align - (total & (swap->debug_align - 1)); - s = (bfd_byte *) alloca (i); + s = (bfd_byte *) malloc (i); + if (s == NULL && i != 0) + { + bfd_set_error (bfd_error_no_memory); + return false; + } + memset ((PTR) s, 0, i); if (bfd_write ((PTR) s, 1, i, abfd) != i) - return false; + { + free (s); + return false; + } + free (s); } return true; @@ -1399,19 +1457,24 @@ bfd_ecoff_write_accumulated_debug (handle, abfd, debug, swap, info, where) file_ptr where; { struct accumulate *ainfo = (struct accumulate *) handle; - PTR space; + PTR space = NULL; if (! ecoff_write_symhdr (abfd, debug, swap, where)) - return false; + goto error_return; - space = (PTR) alloca (ainfo->largest_file_shuffle); + space = (PTR) malloc (ainfo->largest_file_shuffle); + if (space == NULL && ainfo->largest_file_shuffle != 0) + { + bfd_set_error (bfd_error_no_memory); + goto error_return; + } if (! ecoff_write_shuffle (abfd, swap, ainfo->line, space) || ! ecoff_write_shuffle (abfd, swap, ainfo->pdr, space) || ! ecoff_write_shuffle (abfd, swap, ainfo->sym, space) || ! ecoff_write_shuffle (abfd, swap, ainfo->opt, space) || ! ecoff_write_shuffle (abfd, swap, ainfo->aux, space)) - return false; + goto error_return; /* The string table is written out from the hash table if this is a final link. */ @@ -1419,7 +1482,7 @@ bfd_ecoff_write_accumulated_debug (handle, abfd, debug, swap, info, where) { BFD_ASSERT (ainfo->ss_hash == (struct string_hash_entry *) NULL); if (! ecoff_write_shuffle (abfd, swap, ainfo->ss, space)) - return false; + goto error_return; } else { @@ -1430,7 +1493,7 @@ bfd_ecoff_write_accumulated_debug (handle, abfd, debug, swap, info, where) BFD_ASSERT (ainfo->ss == (struct shuffle *) NULL); null = 0; if (bfd_write ((PTR) &null, 1, 1, abfd) != 1) - return false; + goto error_return; total = 1; BFD_ASSERT (ainfo->ss_hash == NULL || ainfo->ss_hash->val == 1); for (sh = ainfo->ss_hash; @@ -1441,7 +1504,7 @@ bfd_ecoff_write_accumulated_debug (handle, abfd, debug, swap, info, where) len = strlen (sh->root.string); if (bfd_write ((PTR) sh->root.string, 1, len + 1, abfd) != len + 1) - return false; + goto error_return; total += len + 1; } @@ -1451,10 +1514,19 @@ bfd_ecoff_write_accumulated_debug (handle, abfd, debug, swap, info, where) bfd_byte *s; i = swap->debug_align - (total & (swap->debug_align - 1)); - s = (bfd_byte *) alloca (i); + s = (bfd_byte *) malloc (i); + if (s == NULL && i != 0) + { + bfd_set_error (bfd_error_no_memory); + goto error_return; + } memset ((PTR) s, 0, i); if (bfd_write ((PTR) s, 1, i, abfd) != i) - return false; + { + free (s); + goto error_return; + } + free (s); } } @@ -1462,7 +1534,7 @@ bfd_ecoff_write_accumulated_debug (handle, abfd, debug, swap, info, where) shuffles. FIXME: They probably should be. */ if (bfd_write (debug->ssext, 1, debug->symbolic_header.issExtMax, abfd) != debug->symbolic_header.issExtMax) - return false; + goto error_return; if ((debug->symbolic_header.issExtMax & (swap->debug_align - 1)) != 0) { int i; @@ -1470,15 +1542,24 @@ bfd_ecoff_write_accumulated_debug (handle, abfd, debug, swap, info, where) i = (swap->debug_align - (debug->symbolic_header.issExtMax & (swap->debug_align - 1))); - s = (bfd_byte *) alloca (i); + s = (bfd_byte *) malloc (i); + if (s == NULL && i != 0) + { + bfd_set_error (bfd_error_no_memory); + goto error_return; + } memset ((PTR) s, 0, i); if (bfd_write ((PTR) s, 1, i, abfd) != i) - return false; + { + free (s); + goto error_return; + } + free (s); } if (! ecoff_write_shuffle (abfd, swap, ainfo->fdr, space) || ! ecoff_write_shuffle (abfd, swap, ainfo->rfd, space)) - return false; + goto error_return; BFD_ASSERT (debug->symbolic_header.cbExtOffset == 0 || debug->symbolic_header.cbExtOffset == bfd_tell (abfd)); @@ -1486,7 +1567,14 @@ bfd_ecoff_write_accumulated_debug (handle, abfd, debug, swap, info, where) if (bfd_write (debug->external_ext, swap->external_ext_size, debug->symbolic_header.iextMax, abfd) != debug->symbolic_header.iextMax * swap->external_ext_size) - return false; + goto error_return; + if (space != NULL) + free (space); return true; + + error_return: + if (space != NULL) + free (space); + return false; } |