1 /* 8 and 16 bit COFF relocation functions, for BFD. 2 Copyright 1990, 1991, 1992, 1993, 1994, 1995, 1996, 1998, 2000, 2001, 3 2002, 2003, 2004, 2005, 2007, 2008, 2009, 2012 4 Free Software Foundation, Inc. 5 Written by Cygnus Support. 6 7 This file is part of BFD, the Binary File Descriptor library. 8 9 This program is free software; you can redistribute it and/or modify 10 it under the terms of the GNU General Public License as published by 11 the Free Software Foundation; either version 3 of the License, or 12 (at your option) any later version. 13 14 This program is distributed in the hope that it will be useful, 15 but WITHOUT ANY WARRANTY; without even the implied warranty of 16 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 17 GNU General Public License for more details. 18 19 You should have received a copy of the GNU General Public License 20 along with this program; if not, write to the Free Software 21 Foundation, Inc., 51 Franklin Street - Fifth Floor, Boston, 22 MA 02110-1301, USA. */ 23 24 25 /* Most of this hacked by Steve Chamberlain <sac@cygnus.com>. */ 26 27 /* These routines are used by coff-h8300 and coff-z8k to do 28 relocation. 29 30 FIXME: This code should be rewritten to support the new COFF 31 linker. Basically, they need to deal with COFF relocs rather than 32 BFD generic relocs. They should store the relocs in some location 33 where coff_link_input_bfd can find them (and coff_link_input_bfd 34 should be changed to use this location rather than rereading the 35 file) (unless info->keep_memory is FALSE, in which case they should 36 free up the relocs after dealing with them). */ 37 38 #include "sysdep.h" 39 #include "bfd.h" 40 #include "libbfd.h" 41 #include "bfdlink.h" 42 #include "genlink.h" 43 #include "coff/internal.h" 44 #include "libcoff.h" 45 46 bfd_vma 47 bfd_coff_reloc16_get_value (arelent *reloc, 48 struct bfd_link_info *link_info, 49 asection *input_section) 50 { 51 bfd_vma value; 52 asymbol *symbol = *(reloc->sym_ptr_ptr); 53 /* A symbol holds a pointer to a section, and an offset from the 54 base of the section. To relocate, we find where the section will 55 live in the output and add that in. */ 56 57 if (bfd_is_und_section (symbol->section) 58 || bfd_is_com_section (symbol->section)) 59 { 60 struct bfd_link_hash_entry *h; 61 62 /* The symbol is undefined in this BFD. Look it up in the 63 global linker hash table. FIXME: This should be changed when 64 we convert this stuff to use a specific final_link function 65 and change the interface to bfd_relax_section to not require 66 the generic symbols. */ 67 h = bfd_wrapped_link_hash_lookup (input_section->owner, link_info, 68 bfd_asymbol_name (symbol), 69 FALSE, FALSE, TRUE); 70 if (h != (struct bfd_link_hash_entry *) NULL 71 && (h->type == bfd_link_hash_defined 72 || h->type == bfd_link_hash_defweak)) 73 value = (h->u.def.value 74 + h->u.def.section->output_section->vma 75 + h->u.def.section->output_offset); 76 else if (h != (struct bfd_link_hash_entry *) NULL 77 && h->type == bfd_link_hash_common) 78 value = h->u.c.size; 79 else if (h != (struct bfd_link_hash_entry *) NULL 80 && h->type == bfd_link_hash_undefweak) 81 /* This is a GNU extension. */ 82 value = 0; 83 else 84 { 85 if (!((*link_info->callbacks->undefined_symbol) 86 (link_info, bfd_asymbol_name (symbol), 87 input_section->owner, input_section, reloc->address, 88 TRUE))) 89 abort (); 90 value = 0; 91 } 92 } 93 else 94 { 95 value = symbol->value 96 + symbol->section->output_offset 97 + symbol->section->output_section->vma; 98 } 99 100 /* Add the value contained in the relocation. */ 101 value += reloc->addend; 102 103 return value; 104 } 105 106 void 107 bfd_perform_slip (bfd *abfd, 108 unsigned int slip, 109 asection *input_section, 110 bfd_vma value) 111 { 112 asymbol **s; 113 114 s = _bfd_generic_link_get_symbols (abfd); 115 BFD_ASSERT (s != (asymbol **) NULL); 116 117 /* Find all symbols past this point, and make them know 118 what's happened. */ 119 while (*s) 120 { 121 asymbol *p = *s; 122 if (p->section == input_section) 123 { 124 /* This was pointing into this section, so mangle it. */ 125 if (p->value > value) 126 { 127 p->value -= slip; 128 if (p->udata.p != NULL) 129 { 130 struct generic_link_hash_entry *h; 131 132 h = (struct generic_link_hash_entry *) p->udata.p; 133 BFD_ASSERT (h->root.type == bfd_link_hash_defined 134 || h->root.type == bfd_link_hash_defweak); 135 h->root.u.def.value -= slip; 136 BFD_ASSERT (h->root.u.def.value == p->value); 137 } 138 } 139 } 140 s++; 141 } 142 } 143 144 bfd_boolean 145 bfd_coff_reloc16_relax_section (bfd *abfd, 146 asection *input_section, 147 struct bfd_link_info *link_info, 148 bfd_boolean *again) 149 { 150 /* Get enough memory to hold the stuff. */ 151 bfd *input_bfd = input_section->owner; 152 unsigned *shrinks; 153 unsigned shrink = 0; 154 long reloc_size = bfd_get_reloc_upper_bound (input_bfd, input_section); 155 arelent **reloc_vector = NULL; 156 long reloc_count; 157 158 if (link_info->relocatable) 159 (*link_info->callbacks->einfo) 160 (_("%P%F: --relax and -r may not be used together\n")); 161 162 /* We only do global relaxation once. It is not safe to do it multiple 163 times (see discussion of the "shrinks" array below). */ 164 *again = FALSE; 165 166 if (reloc_size < 0) 167 return FALSE; 168 169 reloc_vector = (arelent **) bfd_malloc ((bfd_size_type) reloc_size); 170 if (!reloc_vector && reloc_size > 0) 171 return FALSE; 172 173 /* Get the relocs and think about them. */ 174 reloc_count = 175 bfd_canonicalize_reloc (input_bfd, input_section, reloc_vector, 176 _bfd_generic_link_get_symbols (input_bfd)); 177 if (reloc_count < 0) 178 { 179 free (reloc_vector); 180 return FALSE; 181 } 182 183 /* The reloc16.c and related relaxing code is very simple, the price 184 for that simplicity is we can only call this function once for 185 each section. 186 187 So, to get the best results within that limitation, we do multiple 188 relaxing passes over each section here. That involves keeping track 189 of the "shrink" at each reloc in the section. This allows us to 190 accurately determine the relative location of two relocs within 191 this section. 192 193 In theory, if we kept the "shrinks" array for each section for the 194 entire link, we could use the generic relaxing code in the linker 195 and get better results, particularly for jsr->bsr and 24->16 bit 196 memory reference relaxations. */ 197 198 if (reloc_count > 0) 199 { 200 int another_pass = 0; 201 bfd_size_type amt; 202 203 /* Allocate and initialize the shrinks array for this section. 204 The last element is used as an accumulator of shrinks. */ 205 amt = reloc_count + 1; 206 amt *= sizeof (unsigned); 207 shrinks = (unsigned *) bfd_zmalloc (amt); 208 209 /* Loop until nothing changes in this section. */ 210 do 211 { 212 arelent **parent; 213 unsigned int i; 214 long j; 215 216 another_pass = 0; 217 218 for (i = 0, parent = reloc_vector; *parent; parent++, i++) 219 { 220 /* Let the target/machine dependent code examine each reloc 221 in this section and attempt to shrink it. */ 222 shrink = bfd_coff_reloc16_estimate (abfd, input_section, *parent, 223 shrinks[i], link_info); 224 225 /* If it shrunk, note it in the shrinks array and set up for 226 another pass. */ 227 if (shrink != shrinks[i]) 228 { 229 another_pass = 1; 230 for (j = i + 1; j <= reloc_count; j++) 231 shrinks[j] += shrink - shrinks[i]; 232 } 233 } 234 } 235 while (another_pass); 236 237 shrink = shrinks[reloc_count]; 238 free ((char *) shrinks); 239 } 240 241 input_section->rawsize = input_section->size; 242 input_section->size -= shrink; 243 free ((char *) reloc_vector); 244 return TRUE; 245 } 246 247 bfd_byte * 248 bfd_coff_reloc16_get_relocated_section_contents 249 (bfd *in_abfd, 250 struct bfd_link_info *link_info, 251 struct bfd_link_order *link_order, 252 bfd_byte *data, 253 bfd_boolean relocatable, 254 asymbol **symbols) 255 { 256 /* Get enough memory to hold the stuff. */ 257 bfd *input_bfd = link_order->u.indirect.section->owner; 258 asection *input_section = link_order->u.indirect.section; 259 long reloc_size = bfd_get_reloc_upper_bound (input_bfd, input_section); 260 arelent **reloc_vector; 261 long reloc_count; 262 bfd_size_type sz; 263 264 if (reloc_size < 0) 265 return NULL; 266 267 /* If producing relocatable output, don't bother to relax. */ 268 if (relocatable) 269 return bfd_generic_get_relocated_section_contents (in_abfd, link_info, 270 link_order, 271 data, relocatable, 272 symbols); 273 274 /* Read in the section. */ 275 sz = input_section->rawsize ? input_section->rawsize : input_section->size; 276 if (!bfd_get_section_contents (input_bfd, input_section, data, 0, sz)) 277 return NULL; 278 279 reloc_vector = (arelent **) bfd_malloc ((bfd_size_type) reloc_size); 280 if (!reloc_vector && reloc_size != 0) 281 return NULL; 282 283 reloc_count = bfd_canonicalize_reloc (input_bfd, 284 input_section, 285 reloc_vector, 286 symbols); 287 if (reloc_count < 0) 288 { 289 free (reloc_vector); 290 return NULL; 291 } 292 293 if (reloc_count > 0) 294 { 295 arelent **parent = reloc_vector; 296 arelent *reloc; 297 unsigned int dst_address = 0; 298 unsigned int src_address = 0; 299 unsigned int run; 300 unsigned int idx; 301 302 /* Find how long a run we can do. */ 303 while (dst_address < link_order->size) 304 { 305 reloc = *parent; 306 if (reloc) 307 { 308 /* Note that the relaxing didn't tie up the addresses in the 309 relocation, so we use the original address to work out the 310 run of non-relocated data. */ 311 run = reloc->address - src_address; 312 parent++; 313 } 314 else 315 { 316 run = link_order->size - dst_address; 317 } 318 319 /* Copy the bytes. */ 320 for (idx = 0; idx < run; idx++) 321 data[dst_address++] = data[src_address++]; 322 323 /* Now do the relocation. */ 324 if (reloc) 325 { 326 bfd_coff_reloc16_extra_cases (input_bfd, link_info, link_order, 327 reloc, data, &src_address, 328 &dst_address); 329 } 330 } 331 } 332 free ((char *) reloc_vector); 333 return data; 334 } 335