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/coff-alpha.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/coff-alpha.c')
-rw-r--r-- | bfd/coff-alpha.c | 44 |
1 files changed, 36 insertions, 8 deletions
diff --git a/bfd/coff-alpha.c b/bfd/coff-alpha.c index 64ab840..4353078 100644 --- a/bfd/coff-alpha.c +++ b/bfd/coff-alpha.c @@ -715,16 +715,23 @@ alpha_ecoff_get_relocated_section_contents (abfd, link_info, link_order, bfd *input_bfd = link_order->u.indirect.section->owner; asection *input_section = link_order->u.indirect.section; size_t reloc_size = bfd_get_reloc_upper_bound (input_bfd, input_section); - arelent **reloc_vector = (arelent **) alloca (reloc_size); + arelent **reloc_vector = NULL; bfd *output_bfd = relocateable ? abfd : (bfd *) NULL; bfd_vma gp; boolean gp_undefined; bfd_vma stack[RELOC_STACKSIZE]; int tos = 0; + reloc_vector = (arelent **) malloc (reloc_size); + if (reloc_vector == NULL && reloc_size != 0) + { + bfd_set_error (bfd_error_no_memory); + goto error_return; + } + if (! bfd_get_section_contents (input_bfd, input_section, data, (file_ptr) 0, input_section->_raw_size)) - return NULL; + goto error_return; /* The section size is not going to change. */ input_section->_cooked_size = input_section->_raw_size; @@ -733,7 +740,7 @@ alpha_ecoff_get_relocated_section_contents (abfd, link_info, link_order, if (bfd_canonicalize_reloc (input_bfd, input_section, reloc_vector, symbols) == 0) - return data; + goto successful_return; /* Get the GP value for the output BFD. */ gp_undefined = false; @@ -1080,20 +1087,20 @@ alpha_ecoff_get_relocated_section_contents (abfd, link_info, link_order, if (! ((*link_info->callbacks->undefined_symbol) (link_info, bfd_asymbol_name (*rel->sym_ptr_ptr), input_bfd, input_section, rel->address))) - return NULL; + goto error_return; break; case bfd_reloc_dangerous: if (! ((*link_info->callbacks->reloc_dangerous) (link_info, err, input_bfd, input_section, rel->address))) - return NULL; + goto error_return; break; case bfd_reloc_overflow: if (! ((*link_info->callbacks->reloc_overflow) (link_info, bfd_asymbol_name (*rel->sym_ptr_ptr), rel->howto->name, rel->addend, input_bfd, input_section, rel->address))) - return NULL; + goto error_return; break; case bfd_reloc_outofrange: default: @@ -1106,7 +1113,15 @@ alpha_ecoff_get_relocated_section_contents (abfd, link_info, link_order, if (tos != 0) abort (); + successful_return: + if (reloc_vector != NULL) + free (reloc_vector); return data; + + error_return: + if (reloc_vector != NULL) + free (reloc_vector); + return NULL; } /* Get the howto structure for a generic reloc type. */ @@ -1124,6 +1139,7 @@ alpha_bfd_reloc_type_lookup (abfd, code) alpha_type = ALPHA_R_REFLONG; break; case BFD_RELOC_64: + case BFD_RELOC_CTOR: alpha_type = ALPHA_R_REFQUAD; break; case BFD_RELOC_GPREL32: @@ -1658,17 +1674,26 @@ alpha_relocate_section (output_bfd, info, input_bfd, input_section, adjust the address of the reloc. */ if (! info->relocateable) { + bfd_vma mask; bfd_vma val; if (tos == 0) abort (); + /* Get the relocation mask. The separate steps and the + casts to bfd_vma are attempts to avoid a bug in the + Alpha OSF 1.3 C compiler. See reloc.c for more + details. */ + mask = 1; + mask <<= (bfd_vma) r_size; + mask -= 1; + /* FIXME: I don't know what kind of overflow checking, if any, should be done here. */ val = bfd_get_64 (input_bfd, contents + r_vaddr - input_section->vma); - val &=~ (((1 << r_size) - 1) << r_offset); - val |= (stack[--tos] & ((1 << r_size) - 1)) << r_offset; + val &=~ mask << (bfd_vma) r_offset; + val |= (stack[--tos] & mask) << (bfd_vma) r_offset; bfd_put_64 (input_bfd, val, contents + r_vaddr - input_section->vma); } @@ -1961,6 +1986,9 @@ static const struct ecoff_backend_data alpha_ecoff_backend_data = #define ecoff_bfd_get_relocated_section_contents \ alpha_ecoff_get_relocated_section_contents +/* Relaxing sections is generic. */ +#define ecoff_bfd_relax_section bfd_generic_relax_section + bfd_target ecoffalpha_little_vec = { "ecoff-littlealpha", /* name */ |