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/elf32-mips.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/elf32-mips.c')
-rw-r--r-- | bfd/elf32-mips.c | 76 |
1 files changed, 60 insertions, 16 deletions
diff --git a/bfd/elf32-mips.c b/bfd/elf32-mips.c index 57734bc..15debf8 100644 --- a/bfd/elf32-mips.c +++ b/bfd/elf32-mips.c @@ -1028,16 +1028,21 @@ mips_elf_read_ecoff_info (abfd, section, debug) { HDRR *symhdr; const struct ecoff_debug_swap *swap; - char *ext_hdr; + char *ext_hdr = NULL; swap = get_elf_backend_data (abfd)->elf_backend_ecoff_debug_swap; - ext_hdr = (char *) alloca (swap->external_hdr_size); + ext_hdr = (char *) malloc (swap->external_hdr_size); + if (ext_hdr == NULL && swap->external_hdr_size != 0) + { + bfd_set_error (bfd_error_no_memory); + goto error_return; + } if (bfd_get_section_contents (abfd, section, ext_hdr, (file_ptr) 0, swap->external_hdr_size) == false) - return false; + goto error_return; symhdr = &debug->symbolic_header; (*swap->swap_hdr_in) (abfd, ext_hdr, symhdr); @@ -1052,13 +1057,13 @@ mips_elf_read_ecoff_info (abfd, section, debug) debug->ptr = (type) malloc (size * symhdr->count); \ if (debug->ptr == NULL) \ { \ - bfd_error = no_memory; \ - return false; \ + bfd_set_error (bfd_error_no_memory); \ + goto error_return; \ } \ if (bfd_seek (abfd, (file_ptr) symhdr->offset, SEEK_SET) != 0 \ || (bfd_read (debug->ptr, size, symhdr->count, \ abfd) != size * symhdr->count)) \ - return false; \ + goto error_return; \ } READ (external_ext, cbExtOffset, iextMax, swap->external_ext_size, PTR); @@ -1075,8 +1080,36 @@ mips_elf_read_ecoff_info (abfd, section, debug) READ (external_rfd, cbRfdOffset, crfd, swap->external_rfd_size, PTR); debug->fdr = NULL; + debug->adjust = NULL; return true; + + error_return: + if (ext_hdr != NULL) + free (ext_hdr); + if (debug->external_ext != NULL) + free (debug->external_ext); + if (debug->line != NULL) + free (debug->line); + if (debug->external_dnr != NULL) + free (debug->external_dnr); + if (debug->external_pdr != NULL) + free (debug->external_pdr); + if (debug->external_sym != NULL) + free (debug->external_sym); + if (debug->external_opt != NULL) + free (debug->external_opt); + if (debug->external_aux != NULL) + free (debug->external_aux); + if (debug->ss != NULL) + free (debug->ss); + if (debug->ssext != NULL) + free (debug->ssext); + if (debug->external_fdr != NULL) + free (debug->external_fdr); + if (debug->external_rfd != NULL) + free (debug->external_rfd); + return false; } /* Get EXTR information for a symbol. */ @@ -1301,10 +1334,6 @@ mips_elf_final_link (abfd, info) if (p->type != bfd_indirect_link_order) continue; -#ifndef alloca - alloca (0); -#endif - input_section = p->u.indirect.section; input_bfd = input_section->owner; @@ -1433,7 +1462,10 @@ mips_elf_final_link (abfd, info) p != (struct bfd_link_order *) NULL; p = p->next) { - if (p->type == bfd_indirect_link_order) + if (p->type == bfd_section_reloc_link_order + || p->type == bfd_symbol_reloc_link_order) + ++o->reloc_count; + else if (p->type == bfd_indirect_link_order) { asection *input_section; bfd *input_bfd; @@ -1446,9 +1478,9 @@ mips_elf_final_link (abfd, info) relsize = bfd_get_reloc_upper_bound (input_bfd, input_section); relocs = (arelent **) malloc (relsize); - if (!relocs) + if (!relocs && relsize != 0) { - bfd_error = no_memory; + bfd_set_error (bfd_error_no_memory); return false; } reloc_count = @@ -1468,9 +1500,10 @@ mips_elf_final_link (abfd, info) * sizeof (arelent *)))); if (!o->orelocation) { - bfd_error = no_memory; + bfd_set_error (bfd_error_no_memory); return false; } + o->flags |= SEC_RELOC; /* Reset the count so that it can be used as an index when putting in the output relocs. */ o->reloc_count = 0; @@ -1515,8 +1548,18 @@ mips_elf_final_link (abfd, info) p != (struct bfd_link_order *) NULL; p = p->next) { - if (! _bfd_default_link_order (abfd, info, o, p)) - return false; + switch (p->type) + { + case bfd_section_reloc_link_order: + case bfd_symbol_reloc_link_order: + if (! _bfd_generic_reloc_link_order (abfd, info, o, p)) + return false; + break; + default: + if (! _bfd_default_link_order (abfd, info, o, p)) + return false; + break; + } } } @@ -1661,6 +1704,7 @@ static const struct ecoff_debug_swap mips_elf_ecoff_debug_swap = mips_elf_final_write_processing #define elf_backend_ecoff_debug_swap &mips_elf_ecoff_debug_swap +#define bfd_elf32_bfd_link_add_symbols _bfd_generic_link_add_symbols_collect #define bfd_elf32_bfd_final_link mips_elf_final_link #include "elf32-target.h" |