133965Sjdp/* 8 and 16 bit COFF relocation functions, for BFD. 2130561Sobrien Copyright 1990, 1991, 1992, 1993, 1994, 1995, 1996, 1998, 2000, 2001, 3218822Sdim 2002, 2003, 2004, 2007 Free Software Foundation, Inc. 433965Sjdp Written by Cygnus Support. 533965Sjdp 633965SjdpThis file is part of BFD, the Binary File Descriptor library. 733965Sjdp 833965SjdpThis program is free software; you can redistribute it and/or modify 933965Sjdpit under the terms of the GNU General Public License as published by 1033965Sjdpthe Free Software Foundation; either version 2 of the License, or 1133965Sjdp(at your option) any later version. 1233965Sjdp 1333965SjdpThis program is distributed in the hope that it will be useful, 1433965Sjdpbut WITHOUT ANY WARRANTY; without even the implied warranty of 1533965SjdpMERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 1633965SjdpGNU General Public License for more details. 1733965Sjdp 1833965SjdpYou should have received a copy of the GNU General Public License 1933965Sjdpalong with this program; if not, write to the Free Software 20218822SdimFoundation, Inc., 51 Franklin Street - Fifth Floor, Boston, MA 02110-1301, USA. */ 2133965Sjdp 2277298Sobrien/* Most of this hacked by Steve Chamberlain <sac@cygnus.com>. */ 2333965Sjdp 2433965Sjdp/* These routines are used by coff-h8300 and coff-z8k to do 2533965Sjdp relocation. 2633965Sjdp 2733965Sjdp FIXME: This code should be rewritten to support the new COFF 2833965Sjdp linker. Basically, they need to deal with COFF relocs rather than 2933965Sjdp BFD generic relocs. They should store the relocs in some location 3033965Sjdp where coff_link_input_bfd can find them (and coff_link_input_bfd 3133965Sjdp should be changed to use this location rather than rereading the 32130561Sobrien file) (unless info->keep_memory is FALSE, in which case they should 3333965Sjdp free up the relocs after dealing with them). */ 3433965Sjdp 35218822Sdim#include "sysdep.h" 3633965Sjdp#include "bfd.h" 3733965Sjdp#include "libbfd.h" 3833965Sjdp#include "bfdlink.h" 3933965Sjdp#include "genlink.h" 4033965Sjdp#include "coff/internal.h" 4133965Sjdp#include "libcoff.h" 4233965Sjdp 4333965Sjdpbfd_vma 4433965Sjdpbfd_coff_reloc16_get_value (reloc, link_info, input_section) 4533965Sjdp arelent *reloc; 4633965Sjdp struct bfd_link_info *link_info; 4733965Sjdp asection *input_section; 4833965Sjdp{ 4933965Sjdp bfd_vma value; 5033965Sjdp asymbol *symbol = *(reloc->sym_ptr_ptr); 5133965Sjdp /* A symbol holds a pointer to a section, and an offset from the 5233965Sjdp base of the section. To relocate, we find where the section will 5377298Sobrien live in the output and add that in. */ 5433965Sjdp 5533965Sjdp if (bfd_is_und_section (symbol->section) 5633965Sjdp || bfd_is_com_section (symbol->section)) 5733965Sjdp { 5833965Sjdp struct bfd_link_hash_entry *h; 5933965Sjdp 6033965Sjdp /* The symbol is undefined in this BFD. Look it up in the 6133965Sjdp global linker hash table. FIXME: This should be changed when 6233965Sjdp we convert this stuff to use a specific final_link function 6333965Sjdp and change the interface to bfd_relax_section to not require 6433965Sjdp the generic symbols. */ 6533965Sjdp h = bfd_wrapped_link_hash_lookup (input_section->owner, link_info, 6633965Sjdp bfd_asymbol_name (symbol), 67130561Sobrien FALSE, FALSE, TRUE); 6833965Sjdp if (h != (struct bfd_link_hash_entry *) NULL 6933965Sjdp && (h->type == bfd_link_hash_defined 7033965Sjdp || h->type == bfd_link_hash_defweak)) 7133965Sjdp value = (h->u.def.value 7233965Sjdp + h->u.def.section->output_section->vma 7333965Sjdp + h->u.def.section->output_offset); 7433965Sjdp else if (h != (struct bfd_link_hash_entry *) NULL 7533965Sjdp && h->type == bfd_link_hash_common) 7633965Sjdp value = h->u.c.size; 7733965Sjdp else 7833965Sjdp { 7977298Sobrien if (!((*link_info->callbacks->undefined_symbol) 8077298Sobrien (link_info, bfd_asymbol_name (symbol), 8177298Sobrien input_section->owner, input_section, reloc->address, 82130561Sobrien TRUE))) 8333965Sjdp abort (); 8433965Sjdp value = 0; 8533965Sjdp } 8633965Sjdp } 8777298Sobrien else 8833965Sjdp { 8977298Sobrien value = symbol->value 9077298Sobrien + symbol->section->output_offset 9177298Sobrien + symbol->section->output_section->vma; 9233965Sjdp } 9377298Sobrien 9477298Sobrien /* Add the value contained in the relocation. */ 9533965Sjdp value += reloc->addend; 9677298Sobrien 9733965Sjdp return value; 9833965Sjdp} 9933965Sjdp 10033965Sjdpvoid 10177298Sobrienbfd_perform_slip (abfd, slip, input_section, value) 10233965Sjdp bfd *abfd; 10333965Sjdp unsigned int slip; 10433965Sjdp asection *input_section; 10533965Sjdp bfd_vma value; 10633965Sjdp{ 10733965Sjdp asymbol **s; 10833965Sjdp 10933965Sjdp s = _bfd_generic_link_get_symbols (abfd); 11033965Sjdp BFD_ASSERT (s != (asymbol **) NULL); 11133965Sjdp 11233965Sjdp /* Find all symbols past this point, and make them know 11377298Sobrien what's happened. */ 11477298Sobrien while (*s) 11533965Sjdp { 11633965Sjdp asymbol *p = *s; 11777298Sobrien if (p->section == input_section) 11833965Sjdp { 11977298Sobrien /* This was pointing into this section, so mangle it. */ 12033965Sjdp if (p->value > value) 12133965Sjdp { 12233965Sjdp p->value -= slip; 12333965Sjdp if (p->udata.p != NULL) 12433965Sjdp { 12533965Sjdp struct generic_link_hash_entry *h; 12633965Sjdp 12733965Sjdp h = (struct generic_link_hash_entry *) p->udata.p; 12833965Sjdp BFD_ASSERT (h->root.type == bfd_link_hash_defined 12933965Sjdp || h->root.type == bfd_link_hash_defweak); 13033965Sjdp h->root.u.def.value -= slip; 13133965Sjdp BFD_ASSERT (h->root.u.def.value == p->value); 13233965Sjdp } 13333965Sjdp } 13433965Sjdp } 13533965Sjdp s++; 13677298Sobrien } 13733965Sjdp} 13833965Sjdp 139130561Sobrienbfd_boolean 14089857Sobrienbfd_coff_reloc16_relax_section (abfd, input_section, link_info, again) 14133965Sjdp bfd *abfd; 14289857Sobrien asection *input_section; 14333965Sjdp struct bfd_link_info *link_info; 144130561Sobrien bfd_boolean *again; 14533965Sjdp{ 14677298Sobrien /* Get enough memory to hold the stuff. */ 14789857Sobrien bfd *input_bfd = input_section->owner; 14889857Sobrien unsigned *shrinks; 14989857Sobrien unsigned shrink = 0; 15033965Sjdp long reloc_size = bfd_get_reloc_upper_bound (input_bfd, input_section); 15133965Sjdp arelent **reloc_vector = NULL; 15233965Sjdp long reloc_count; 15333965Sjdp 15433965Sjdp /* We only do global relaxation once. It is not safe to do it multiple 15533965Sjdp times (see discussion of the "shrinks" array below). */ 156130561Sobrien *again = FALSE; 15733965Sjdp 15833965Sjdp if (reloc_size < 0) 159130561Sobrien return FALSE; 16033965Sjdp 16189857Sobrien reloc_vector = (arelent **) bfd_malloc ((bfd_size_type) reloc_size); 16233965Sjdp if (!reloc_vector && reloc_size > 0) 163130561Sobrien return FALSE; 16433965Sjdp 16577298Sobrien /* Get the relocs and think about them. */ 16633965Sjdp reloc_count = 16733965Sjdp bfd_canonicalize_reloc (input_bfd, input_section, reloc_vector, 16833965Sjdp _bfd_generic_link_get_symbols (input_bfd)); 16933965Sjdp if (reloc_count < 0) 17033965Sjdp { 17133965Sjdp free (reloc_vector); 172130561Sobrien return FALSE; 17333965Sjdp } 17433965Sjdp 17533965Sjdp /* The reloc16.c and related relaxing code is very simple, the price 17633965Sjdp for that simplicity is we can only call this function once for 17733965Sjdp each section. 17833965Sjdp 17933965Sjdp So, to get the best results within that limitation, we do multiple 18033965Sjdp relaxing passes over each section here. That involves keeping track 18133965Sjdp of the "shrink" at each reloc in the section. This allows us to 18233965Sjdp accurately determine the relative location of two relocs within 18333965Sjdp this section. 18433965Sjdp 18533965Sjdp In theory, if we kept the "shrinks" array for each section for the 18633965Sjdp entire link, we could use the generic relaxing code in the linker 18733965Sjdp and get better results, particularly for jsr->bsr and 24->16 bit 18833965Sjdp memory reference relaxations. */ 18977298Sobrien 19033965Sjdp if (reloc_count > 0) 19133965Sjdp { 19233965Sjdp int another_pass = 0; 19389857Sobrien bfd_size_type amt; 19433965Sjdp 19560484Sobrien /* Allocate and initialize the shrinks array for this section. 196130561Sobrien The last element is used as an accumulator of shrinks. */ 19789857Sobrien amt = reloc_count + 1; 19889857Sobrien amt *= sizeof (unsigned); 199104834Sobrien shrinks = (unsigned *) bfd_zmalloc (amt); 20033965Sjdp 20133965Sjdp /* Loop until nothing changes in this section. */ 202130561Sobrien do 203130561Sobrien { 204130561Sobrien arelent **parent; 205130561Sobrien unsigned int i; 206130561Sobrien long j; 20733965Sjdp 208130561Sobrien another_pass = 0; 20933965Sjdp 210130561Sobrien for (i = 0, parent = reloc_vector; *parent; parent++, i++) 211130561Sobrien { 212130561Sobrien /* Let the target/machine dependent code examine each reloc 213130561Sobrien in this section and attempt to shrink it. */ 214130561Sobrien shrink = bfd_coff_reloc16_estimate (abfd, input_section, *parent, 215130561Sobrien shrinks[i], link_info); 21633965Sjdp 217130561Sobrien /* If it shrunk, note it in the shrinks array and set up for 218130561Sobrien another pass. */ 219130561Sobrien if (shrink != shrinks[i]) 220130561Sobrien { 221130561Sobrien another_pass = 1; 222130561Sobrien for (j = i + 1; j <= reloc_count; j++) 223130561Sobrien shrinks[j] += shrink - shrinks[i]; 224130561Sobrien } 225130561Sobrien } 226130561Sobrien } 22777298Sobrien while (another_pass); 22833965Sjdp 22960484Sobrien shrink = shrinks[reloc_count]; 23077298Sobrien free ((char *) shrinks); 23133965Sjdp } 23233965Sjdp 233218822Sdim input_section->rawsize = input_section->size; 234218822Sdim input_section->size -= shrink; 23577298Sobrien free ((char *) reloc_vector); 236130561Sobrien return TRUE; 23733965Sjdp} 23833965Sjdp 23933965Sjdpbfd_byte * 240130561Sobrienbfd_coff_reloc16_get_relocated_section_contents (in_abfd, 241130561Sobrien link_info, 242130561Sobrien link_order, 243130561Sobrien data, 244130561Sobrien relocatable, 245130561Sobrien symbols) 24633965Sjdp bfd *in_abfd; 24733965Sjdp struct bfd_link_info *link_info; 24833965Sjdp struct bfd_link_order *link_order; 24933965Sjdp bfd_byte *data; 250130561Sobrien bfd_boolean relocatable; 25133965Sjdp asymbol **symbols; 25233965Sjdp{ 25377298Sobrien /* Get enough memory to hold the stuff. */ 25433965Sjdp bfd *input_bfd = link_order->u.indirect.section->owner; 25533965Sjdp asection *input_section = link_order->u.indirect.section; 25633965Sjdp long reloc_size = bfd_get_reloc_upper_bound (input_bfd, input_section); 25733965Sjdp arelent **reloc_vector; 25833965Sjdp long reloc_count; 259218822Sdim bfd_size_type sz; 26033965Sjdp 26133965Sjdp if (reloc_size < 0) 26233965Sjdp return NULL; 26333965Sjdp 264130561Sobrien /* If producing relocatable output, don't bother to relax. */ 265130561Sobrien if (relocatable) 26633965Sjdp return bfd_generic_get_relocated_section_contents (in_abfd, link_info, 26733965Sjdp link_order, 268130561Sobrien data, relocatable, 26933965Sjdp symbols); 27033965Sjdp 27177298Sobrien /* Read in the section. */ 272218822Sdim sz = input_section->rawsize ? input_section->rawsize : input_section->size; 273218822Sdim if (!bfd_get_section_contents (input_bfd, input_section, data, 0, sz)) 27433965Sjdp return NULL; 27577298Sobrien 27689857Sobrien reloc_vector = (arelent **) bfd_malloc ((bfd_size_type) reloc_size); 27733965Sjdp if (!reloc_vector && reloc_size != 0) 27833965Sjdp return NULL; 27977298Sobrien 28077298Sobrien reloc_count = bfd_canonicalize_reloc (input_bfd, 28133965Sjdp input_section, 28233965Sjdp reloc_vector, 28333965Sjdp symbols); 28433965Sjdp if (reloc_count < 0) 28533965Sjdp { 28633965Sjdp free (reloc_vector); 28733965Sjdp return NULL; 28833965Sjdp } 28977298Sobrien 29033965Sjdp if (reloc_count > 0) 29133965Sjdp { 29233965Sjdp arelent **parent = reloc_vector; 29377298Sobrien arelent *reloc; 29433965Sjdp unsigned int dst_address = 0; 29533965Sjdp unsigned int src_address = 0; 29633965Sjdp unsigned int run; 29733965Sjdp unsigned int idx; 29877298Sobrien 29977298Sobrien /* Find how long a run we can do. */ 30077298Sobrien while (dst_address < link_order->size) 30133965Sjdp { 30233965Sjdp reloc = *parent; 30377298Sobrien if (reloc) 30433965Sjdp { 30533965Sjdp /* Note that the relaxing didn't tie up the addresses in the 30633965Sjdp relocation, so we use the original address to work out the 30777298Sobrien run of non-relocated data. */ 30833965Sjdp run = reloc->address - src_address; 30933965Sjdp parent++; 31033965Sjdp } 31177298Sobrien else 31233965Sjdp { 31333965Sjdp run = link_order->size - dst_address; 31433965Sjdp } 31577298Sobrien 31677298Sobrien /* Copy the bytes. */ 31733965Sjdp for (idx = 0; idx < run; idx++) 31877298Sobrien data[dst_address++] = data[src_address++]; 31977298Sobrien 32077298Sobrien /* Now do the relocation. */ 32177298Sobrien if (reloc) 32233965Sjdp { 32333965Sjdp bfd_coff_reloc16_extra_cases (input_bfd, link_info, link_order, 32433965Sjdp reloc, data, &src_address, 32533965Sjdp &dst_address); 32677298Sobrien } 32733965Sjdp } 32833965Sjdp } 32977298Sobrien free ((char *) reloc_vector); 33033965Sjdp return data; 33133965Sjdp} 332