aboutsummaryrefslogtreecommitdiff
path: root/bfd/elf32-mips.c
diff options
context:
space:
mode:
authorIan Lance Taylor <ian@airs.com>1994-03-25 22:37:55 +0000
committerIan Lance Taylor <ian@airs.com>1994-03-25 22:37:55 +0000
commita3a33af390c3a99e00b20847a102e307cfb538c7 (patch)
treeb262eb6f85a5b10fe60cdc47a0f753178e889283 /bfd/elf32-mips.c
parentf078dc7cf26a816ef0bb66be8b819ac549486e86 (diff)
downloadgdb-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.c76
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"