1 /* Xilinx MicroBlaze-specific support for 32-bit ELF 2 3 Copyright 2009, 2010, 2011, 2012 Free Software Foundation, Inc. 4 5 This file is part of BFD, the Binary File Descriptor library. 6 7 This program is free software; you can redistribute it and/or modify 8 it under the terms of the GNU General Public License as published by 9 the Free Software Foundation; either version 3 of the License, or 10 (at your option) any later version. 11 12 This program is distributed in the hope that it will be useful, 13 but WITHOUT ANY WARRANTY; without even the implied warranty of 14 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 15 GNU General Public License for more details. 16 17 You should have received a copy of the GNU General Public License 18 along with this program; if not, write to the 19 Free Software Foundation, Inc., 51 Franklin Street - Fifth Floor, 20 Boston, MA 02110-1301, USA. */ 21 22 23 int dbg = 0; 24 25 #include "sysdep.h" 26 #include "bfd.h" 27 #include "bfdlink.h" 28 #include "libbfd.h" 29 #include "elf-bfd.h" 30 #include "elf/microblaze.h" 31 #include <assert.h> 32 33 #define USE_RELA /* Only USE_REL is actually significant, but this is 34 here are a reminder... */ 35 #define INST_WORD_SIZE 4 36 37 static int ro_small_data_pointer = 0; 38 static int rw_small_data_pointer = 0; 39 40 static reloc_howto_type * microblaze_elf_howto_table [(int) R_MICROBLAZE_max]; 41 42 static reloc_howto_type microblaze_elf_howto_raw[] = 43 { 44 /* This reloc does nothing. */ 45 HOWTO (R_MICROBLAZE_NONE, /* Type. */ 46 0, /* Rightshift. */ 47 2, /* Size (0 = byte, 1 = short, 2 = long). */ 48 32, /* Bitsize. */ 49 FALSE, /* PC_relative. */ 50 0, /* Bitpos. */ 51 complain_overflow_bitfield, /* Complain on overflow. */ 52 NULL, /* Special Function. */ 53 "R_MICROBLAZE_NONE", /* Name. */ 54 FALSE, /* Partial Inplace. */ 55 0, /* Source Mask. */ 56 0, /* Dest Mask. */ 57 FALSE), /* PC relative offset? */ 58 59 /* A standard 32 bit relocation. */ 60 HOWTO (R_MICROBLAZE_32, /* Type. */ 61 0, /* Rightshift. */ 62 2, /* Size (0 = byte, 1 = short, 2 = long). */ 63 32, /* Bitsize. */ 64 FALSE, /* PC_relative. */ 65 0, /* Bitpos. */ 66 complain_overflow_bitfield, /* Complain on overflow. */ 67 bfd_elf_generic_reloc,/* Special Function. */ 68 "R_MICROBLAZE_32", /* Name. */ 69 FALSE, /* Partial Inplace. */ 70 0, /* Source Mask. */ 71 0xffffffff, /* Dest Mask. */ 72 FALSE), /* PC relative offset? */ 73 74 /* A standard PCREL 32 bit relocation. */ 75 HOWTO (R_MICROBLAZE_32_PCREL,/* Type. */ 76 0, /* Rightshift. */ 77 2, /* Size (0 = byte, 1 = short, 2 = long). */ 78 32, /* Bitsize. */ 79 TRUE, /* PC_relative. */ 80 0, /* Bitpos. */ 81 complain_overflow_bitfield, /* Complain on overflow. */ 82 bfd_elf_generic_reloc,/* Special Function. */ 83 "R_MICROBLAZE_32_PCREL", /* Name. */ 84 TRUE, /* Partial Inplace. */ 85 0, /* Source Mask. */ 86 0xffffffff, /* Dest Mask. */ 87 TRUE), /* PC relative offset? */ 88 89 /* A 64 bit PCREL relocation. Table-entry not really used. */ 90 HOWTO (R_MICROBLAZE_64_PCREL,/* Type. */ 91 0, /* Rightshift. */ 92 2, /* Size (0 = byte, 1 = short, 2 = long). */ 93 16, /* Bitsize. */ 94 TRUE, /* PC_relative. */ 95 0, /* Bitpos. */ 96 complain_overflow_dont, /* Complain on overflow. */ 97 bfd_elf_generic_reloc,/* Special Function. */ 98 "R_MICROBLAZE_64_PCREL", /* Name. */ 99 FALSE, /* Partial Inplace. */ 100 0, /* Source Mask. */ 101 0x0000ffff, /* Dest Mask. */ 102 TRUE), /* PC relative offset? */ 103 104 /* The low half of a PCREL 32 bit relocation. */ 105 HOWTO (R_MICROBLAZE_32_PCREL_LO, /* Type. */ 106 0, /* Rightshift. */ 107 2, /* Size (0 = byte, 1 = short, 2 = long). */ 108 16, /* Bitsize. */ 109 TRUE, /* PC_relative. */ 110 0, /* Bitpos. */ 111 complain_overflow_signed, /* Complain on overflow. */ 112 bfd_elf_generic_reloc, /* Special Function. */ 113 "R_MICROBLAZE_32_PCREL_LO", /* Name. */ 114 FALSE, /* Partial Inplace. */ 115 0, /* Source Mask. */ 116 0x0000ffff, /* Dest Mask. */ 117 TRUE), /* PC relative offset? */ 118 119 /* A 64 bit relocation. Table entry not really used. */ 120 HOWTO (R_MICROBLAZE_64, /* Type. */ 121 0, /* Rightshift. */ 122 2, /* Size (0 = byte, 1 = short, 2 = long). */ 123 16, /* Bitsize. */ 124 FALSE, /* PC_relative. */ 125 0, /* Bitpos. */ 126 complain_overflow_dont, /* Complain on overflow. */ 127 bfd_elf_generic_reloc,/* Special Function. */ 128 "R_MICROBLAZE_64", /* Name. */ 129 FALSE, /* Partial Inplace. */ 130 0, /* Source Mask. */ 131 0x0000ffff, /* Dest Mask. */ 132 FALSE), /* PC relative offset? */ 133 134 /* The low half of a 32 bit relocation. */ 135 HOWTO (R_MICROBLAZE_32_LO, /* Type. */ 136 0, /* Rightshift. */ 137 2, /* Size (0 = byte, 1 = short, 2 = long). */ 138 16, /* Bitsize. */ 139 FALSE, /* PC_relative. */ 140 0, /* Bitpos. */ 141 complain_overflow_signed, /* Complain on overflow. */ 142 bfd_elf_generic_reloc,/* Special Function. */ 143 "R_MICROBLAZE_32_LO", /* Name. */ 144 FALSE, /* Partial Inplace. */ 145 0, /* Source Mask. */ 146 0x0000ffff, /* Dest Mask. */ 147 FALSE), /* PC relative offset? */ 148 149 /* Read-only small data section relocation. */ 150 HOWTO (R_MICROBLAZE_SRO32, /* Type. */ 151 0, /* Rightshift. */ 152 2, /* Size (0 = byte, 1 = short, 2 = long). */ 153 16, /* Bitsize. */ 154 FALSE, /* PC_relative. */ 155 0, /* Bitpos. */ 156 complain_overflow_bitfield, /* Complain on overflow. */ 157 bfd_elf_generic_reloc,/* Special Function. */ 158 "R_MICROBLAZE_SRO32", /* Name. */ 159 FALSE, /* Partial Inplace. */ 160 0, /* Source Mask. */ 161 0x0000ffff, /* Dest Mask. */ 162 FALSE), /* PC relative offset? */ 163 164 /* Read-write small data area relocation. */ 165 HOWTO (R_MICROBLAZE_SRW32, /* Type. */ 166 0, /* Rightshift. */ 167 2, /* Size (0 = byte, 1 = short, 2 = long). */ 168 16, /* Bitsize. */ 169 FALSE, /* PC_relative. */ 170 0, /* Bitpos. */ 171 complain_overflow_bitfield, /* Complain on overflow. */ 172 bfd_elf_generic_reloc,/* Special Function. */ 173 "R_MICROBLAZE_SRW32", /* Name. */ 174 FALSE, /* Partial Inplace. */ 175 0, /* Source Mask. */ 176 0x0000ffff, /* Dest Mask. */ 177 FALSE), /* PC relative offset? */ 178 179 /* This reloc does nothing. Used for relaxation. */ 180 HOWTO (R_MICROBLAZE_64_NONE, /* Type. */ 181 0, /* Rightshift. */ 182 2, /* Size (0 = byte, 1 = short, 2 = long). */ 183 32, /* Bitsize. */ 184 TRUE, /* PC_relative. */ 185 0, /* Bitpos. */ 186 complain_overflow_bitfield, /* Complain on overflow. */ 187 NULL, /* Special Function. */ 188 "R_MICROBLAZE_64_NONE",/* Name. */ 189 FALSE, /* Partial Inplace. */ 190 0, /* Source Mask. */ 191 0, /* Dest Mask. */ 192 FALSE), /* PC relative offset? */ 193 194 /* Symbol Op Symbol relocation. */ 195 HOWTO (R_MICROBLAZE_32_SYM_OP_SYM, /* Type. */ 196 0, /* Rightshift. */ 197 2, /* Size (0 = byte, 1 = short, 2 = long). */ 198 32, /* Bitsize. */ 199 FALSE, /* PC_relative. */ 200 0, /* Bitpos. */ 201 complain_overflow_bitfield, /* Complain on overflow. */ 202 bfd_elf_generic_reloc,/* Special Function. */ 203 "R_MICROBLAZE_32_SYM_OP_SYM", /* Name. */ 204 FALSE, /* Partial Inplace. */ 205 0, /* Source Mask. */ 206 0xffffffff, /* Dest Mask. */ 207 FALSE), /* PC relative offset? */ 208 209 /* GNU extension to record C++ vtable hierarchy. */ 210 HOWTO (R_MICROBLAZE_GNU_VTINHERIT, /* Type. */ 211 0, /* Rightshift. */ 212 2, /* Size (0 = byte, 1 = short, 2 = long). */ 213 0, /* Bitsize. */ 214 FALSE, /* PC_relative. */ 215 0, /* Bitpos. */ 216 complain_overflow_dont,/* Complain on overflow. */ 217 NULL, /* Special Function. */ 218 "R_MICROBLAZE_GNU_VTINHERIT", /* Name. */ 219 FALSE, /* Partial Inplace. */ 220 0, /* Source Mask. */ 221 0, /* Dest Mask. */ 222 FALSE), /* PC relative offset? */ 223 224 /* GNU extension to record C++ vtable member usage. */ 225 HOWTO (R_MICROBLAZE_GNU_VTENTRY, /* Type. */ 226 0, /* Rightshift. */ 227 2, /* Size (0 = byte, 1 = short, 2 = long). */ 228 0, /* Bitsize. */ 229 FALSE, /* PC_relative. */ 230 0, /* Bitpos. */ 231 complain_overflow_dont,/* Complain on overflow. */ 232 _bfd_elf_rel_vtable_reloc_fn, /* Special Function. */ 233 "R_MICROBLAZE_GNU_VTENTRY", /* Name. */ 234 FALSE, /* Partial Inplace. */ 235 0, /* Source Mask. */ 236 0, /* Dest Mask. */ 237 FALSE), /* PC relative offset? */ 238 239 /* A 64 bit GOTPC relocation. Table-entry not really used. */ 240 HOWTO (R_MICROBLAZE_GOTPC_64, /* Type. */ 241 0, /* Rightshift. */ 242 2, /* Size (0 = byte, 1 = short, 2 = long). */ 243 16, /* Bitsize. */ 244 TRUE, /* PC_relative. */ 245 0, /* Bitpos. */ 246 complain_overflow_dont, /* Complain on overflow. */ 247 bfd_elf_generic_reloc, /* Special Function. */ 248 "R_MICROBLAZE_GOTPC_64", /* Name. */ 249 FALSE, /* Partial Inplace. */ 250 0, /* Source Mask. */ 251 0x0000ffff, /* Dest Mask. */ 252 TRUE), /* PC relative offset? */ 253 254 /* A 64 bit GOT relocation. Table-entry not really used. */ 255 HOWTO (R_MICROBLAZE_GOT_64, /* Type. */ 256 0, /* Rightshift. */ 257 2, /* Size (0 = byte, 1 = short, 2 = long). */ 258 16, /* Bitsize. */ 259 FALSE, /* PC_relative. */ 260 0, /* Bitpos. */ 261 complain_overflow_dont, /* Complain on overflow. */ 262 bfd_elf_generic_reloc,/* Special Function. */ 263 "R_MICROBLAZE_GOT_64",/* Name. */ 264 FALSE, /* Partial Inplace. */ 265 0, /* Source Mask. */ 266 0x0000ffff, /* Dest Mask. */ 267 FALSE), /* PC relative offset? */ 268 269 /* A 64 bit PLT relocation. Table-entry not really used. */ 270 HOWTO (R_MICROBLAZE_PLT_64, /* Type. */ 271 0, /* Rightshift. */ 272 2, /* Size (0 = byte, 1 = short, 2 = long). */ 273 16, /* Bitsize. */ 274 TRUE, /* PC_relative. */ 275 0, /* Bitpos. */ 276 complain_overflow_dont, /* Complain on overflow. */ 277 bfd_elf_generic_reloc,/* Special Function. */ 278 "R_MICROBLAZE_PLT_64",/* Name. */ 279 FALSE, /* Partial Inplace. */ 280 0, /* Source Mask. */ 281 0x0000ffff, /* Dest Mask. */ 282 TRUE), /* PC relative offset? */ 283 284 /* Table-entry not really used. */ 285 HOWTO (R_MICROBLAZE_REL, /* Type. */ 286 0, /* Rightshift. */ 287 2, /* Size (0 = byte, 1 = short, 2 = long). */ 288 16, /* Bitsize. */ 289 TRUE, /* PC_relative. */ 290 0, /* Bitpos. */ 291 complain_overflow_dont, /* Complain on overflow. */ 292 bfd_elf_generic_reloc,/* Special Function. */ 293 "R_MICROBLAZE_REL", /* Name. */ 294 FALSE, /* Partial Inplace. */ 295 0, /* Source Mask. */ 296 0x0000ffff, /* Dest Mask. */ 297 TRUE), /* PC relative offset? */ 298 299 /* Table-entry not really used. */ 300 HOWTO (R_MICROBLAZE_JUMP_SLOT,/* Type. */ 301 0, /* Rightshift. */ 302 2, /* Size (0 = byte, 1 = short, 2 = long). */ 303 16, /* Bitsize. */ 304 TRUE, /* PC_relative. */ 305 0, /* Bitpos. */ 306 complain_overflow_dont, /* Complain on overflow. */ 307 bfd_elf_generic_reloc,/* Special Function. */ 308 "R_MICROBLAZE_JUMP_SLOT", /* Name. */ 309 FALSE, /* Partial Inplace. */ 310 0, /* Source Mask. */ 311 0x0000ffff, /* Dest Mask. */ 312 TRUE), /* PC relative offset? */ 313 314 /* Table-entry not really used. */ 315 HOWTO (R_MICROBLAZE_GLOB_DAT,/* Type. */ 316 0, /* Rightshift. */ 317 2, /* Size (0 = byte, 1 = short, 2 = long). */ 318 16, /* Bitsize. */ 319 TRUE, /* PC_relative. */ 320 0, /* Bitpos. */ 321 complain_overflow_dont, /* Complain on overflow. */ 322 bfd_elf_generic_reloc,/* Special Function. */ 323 "R_MICROBLAZE_GLOB_DAT", /* Name. */ 324 FALSE, /* Partial Inplace. */ 325 0, /* Source Mask. */ 326 0x0000ffff, /* Dest Mask. */ 327 TRUE), /* PC relative offset? */ 328 329 /* A 64 bit GOT relative relocation. Table-entry not really used. */ 330 HOWTO (R_MICROBLAZE_GOTOFF_64, /* Type. */ 331 0, /* Rightshift. */ 332 2, /* Size (0 = byte, 1 = short, 2 = long). */ 333 16, /* Bitsize. */ 334 FALSE, /* PC_relative. */ 335 0, /* Bitpos. */ 336 complain_overflow_dont, /* Complain on overflow. */ 337 bfd_elf_generic_reloc,/* Special Function. */ 338 "R_MICROBLAZE_GOTOFF_64", /* Name. */ 339 FALSE, /* Partial Inplace. */ 340 0, /* Source Mask. */ 341 0x0000ffff, /* Dest Mask. */ 342 FALSE), /* PC relative offset? */ 343 344 /* A 32 bit GOT relative relocation. Table-entry not really used. */ 345 HOWTO (R_MICROBLAZE_GOTOFF_32, /* Type. */ 346 0, /* Rightshift. */ 347 2, /* Size (0 = byte, 1 = short, 2 = long). */ 348 16, /* Bitsize. */ 349 FALSE, /* PC_relative. */ 350 0, /* Bitpos. */ 351 complain_overflow_dont, /* Complain on overflow. */ 352 bfd_elf_generic_reloc, /* Special Function. */ 353 "R_MICROBLAZE_GOTOFF_32", /* Name. */ 354 FALSE, /* Partial Inplace. */ 355 0, /* Source Mask. */ 356 0x0000ffff, /* Dest Mask. */ 357 FALSE), /* PC relative offset? */ 358 359 /* COPY relocation. Table-entry not really used. */ 360 HOWTO (R_MICROBLAZE_COPY, /* Type. */ 361 0, /* Rightshift. */ 362 2, /* Size (0 = byte, 1 = short, 2 = long). */ 363 16, /* Bitsize. */ 364 FALSE, /* PC_relative. */ 365 0, /* Bitpos. */ 366 complain_overflow_dont, /* Complain on overflow. */ 367 bfd_elf_generic_reloc,/* Special Function. */ 368 "R_MICROBLAZE_COPY", /* Name. */ 369 FALSE, /* Partial Inplace. */ 370 0, /* Source Mask. */ 371 0x0000ffff, /* Dest Mask. */ 372 FALSE), /* PC relative offset? */ 373 }; 374 375 #ifndef NUM_ELEM 376 #define NUM_ELEM(a) (sizeof (a) / sizeof (a)[0]) 377 #endif 378 379 /* Initialize the microblaze_elf_howto_table, so that linear accesses can be done. */ 380 381 static void 382 microblaze_elf_howto_init (void) 383 { 384 unsigned int i; 385 386 for (i = NUM_ELEM (microblaze_elf_howto_raw); i--;) 387 { 388 unsigned int type; 389 390 type = microblaze_elf_howto_raw[i].type; 391 392 BFD_ASSERT (type < NUM_ELEM (microblaze_elf_howto_table)); 393 394 microblaze_elf_howto_table [type] = & microblaze_elf_howto_raw [i]; 395 } 396 } 397 398 static reloc_howto_type * 399 microblaze_elf_reloc_type_lookup (bfd * abfd ATTRIBUTE_UNUSED, 400 bfd_reloc_code_real_type code) 401 { 402 enum elf_microblaze_reloc_type microblaze_reloc = R_MICROBLAZE_NONE; 403 404 switch (code) 405 { 406 case BFD_RELOC_NONE: 407 microblaze_reloc = R_MICROBLAZE_NONE; 408 break; 409 case BFD_RELOC_MICROBLAZE_64_NONE: 410 microblaze_reloc = R_MICROBLAZE_64_NONE; 411 break; 412 case BFD_RELOC_32: 413 microblaze_reloc = R_MICROBLAZE_32; 414 break; 415 /* RVA is treated the same as 32 */ 416 case BFD_RELOC_RVA: 417 microblaze_reloc = R_MICROBLAZE_32; 418 break; 419 case BFD_RELOC_32_PCREL: 420 microblaze_reloc = R_MICROBLAZE_32_PCREL; 421 break; 422 case BFD_RELOC_64_PCREL: 423 microblaze_reloc = R_MICROBLAZE_64_PCREL; 424 break; 425 case BFD_RELOC_MICROBLAZE_32_LO_PCREL: 426 microblaze_reloc = R_MICROBLAZE_32_PCREL_LO; 427 break; 428 case BFD_RELOC_64: 429 microblaze_reloc = R_MICROBLAZE_64; 430 break; 431 case BFD_RELOC_MICROBLAZE_32_LO: 432 microblaze_reloc = R_MICROBLAZE_32_LO; 433 break; 434 case BFD_RELOC_MICROBLAZE_32_ROSDA: 435 microblaze_reloc = R_MICROBLAZE_SRO32; 436 break; 437 case BFD_RELOC_MICROBLAZE_32_RWSDA: 438 microblaze_reloc = R_MICROBLAZE_SRW32; 439 break; 440 case BFD_RELOC_MICROBLAZE_32_SYM_OP_SYM: 441 microblaze_reloc = R_MICROBLAZE_32_SYM_OP_SYM; 442 break; 443 case BFD_RELOC_VTABLE_INHERIT: 444 microblaze_reloc = R_MICROBLAZE_GNU_VTINHERIT; 445 break; 446 case BFD_RELOC_VTABLE_ENTRY: 447 microblaze_reloc = R_MICROBLAZE_GNU_VTENTRY; 448 break; 449 case BFD_RELOC_MICROBLAZE_64_GOTPC: 450 microblaze_reloc = R_MICROBLAZE_GOTPC_64; 451 break; 452 case BFD_RELOC_MICROBLAZE_64_GOT: 453 microblaze_reloc = R_MICROBLAZE_GOT_64; 454 break; 455 case BFD_RELOC_MICROBLAZE_64_PLT: 456 microblaze_reloc = R_MICROBLAZE_PLT_64; 457 break; 458 case BFD_RELOC_MICROBLAZE_64_GOTOFF: 459 microblaze_reloc = R_MICROBLAZE_GOTOFF_64; 460 break; 461 case BFD_RELOC_MICROBLAZE_32_GOTOFF: 462 microblaze_reloc = R_MICROBLAZE_GOTOFF_32; 463 break; 464 case BFD_RELOC_MICROBLAZE_COPY: 465 microblaze_reloc = R_MICROBLAZE_COPY; 466 break; 467 default: 468 return (reloc_howto_type *) NULL; 469 } 470 471 if (!microblaze_elf_howto_table [R_MICROBLAZE_32]) 472 /* Initialize howto table if needed. */ 473 microblaze_elf_howto_init (); 474 475 return microblaze_elf_howto_table [(int) microblaze_reloc]; 476 }; 477 478 static reloc_howto_type * 479 microblaze_elf_reloc_name_lookup (bfd *abfd ATTRIBUTE_UNUSED, 480 const char *r_name) 481 { 482 unsigned int i; 483 484 for (i = 0; i < NUM_ELEM (microblaze_elf_howto_raw); i++) 485 if (microblaze_elf_howto_raw[i].name != NULL 486 && strcasecmp (microblaze_elf_howto_raw[i].name, r_name) == 0) 487 return µblaze_elf_howto_raw[i]; 488 489 return NULL; 490 } 491 492 /* Set the howto pointer for a RCE ELF reloc. */ 493 494 static void 495 microblaze_elf_info_to_howto (bfd * abfd ATTRIBUTE_UNUSED, 496 arelent * cache_ptr, 497 Elf_Internal_Rela * dst) 498 { 499 if (!microblaze_elf_howto_table [R_MICROBLAZE_32]) 500 /* Initialize howto table if needed. */ 501 microblaze_elf_howto_init (); 502 503 BFD_ASSERT (ELF32_R_TYPE (dst->r_info) < (unsigned int) R_MICROBLAZE_max); 504 505 cache_ptr->howto = microblaze_elf_howto_table [ELF32_R_TYPE (dst->r_info)]; 506 } 507 508 /* Microblaze ELF local labels start with 'L.' or '$L', not '.L'. */ 509 510 static bfd_boolean 511 microblaze_elf_is_local_label_name (bfd *abfd, const char *name) 512 { 513 if (name[0] == 'L' && name[1] == '.') 514 return TRUE; 515 516 if (name[0] == '$' && name[1] == 'L') 517 return TRUE; 518 519 /* With gcc, the labels go back to starting with '.', so we accept 520 the generic ELF local label syntax as well. */ 521 return _bfd_elf_is_local_label_name (abfd, name); 522 } 523 524 /* The microblaze linker (like many others) needs to keep track of 525 the number of relocs that it decides to copy as dynamic relocs in 526 check_relocs for each symbol. This is so that it can later discard 527 them if they are found to be unnecessary. We store the information 528 in a field extending the regular ELF linker hash table. */ 529 530 struct elf32_mb_dyn_relocs 531 { 532 struct elf32_mb_dyn_relocs *next; 533 534 /* The input section of the reloc. */ 535 asection *sec; 536 537 /* Total number of relocs copied for the input section. */ 538 bfd_size_type count; 539 540 /* Number of pc-relative relocs copied for the input section. */ 541 bfd_size_type pc_count; 542 }; 543 544 /* ELF linker hash entry. */ 545 546 struct elf32_mb_link_hash_entry 547 { 548 struct elf_link_hash_entry elf; 549 550 /* Track dynamic relocs copied for this symbol. */ 551 struct elf32_mb_dyn_relocs *dyn_relocs; 552 553 }; 554 555 #define elf32_mb_hash_entry(ent) ((struct elf32_mb_link_hash_entry *)(ent)) 556 557 /* ELF linker hash table. */ 558 559 struct elf32_mb_link_hash_table 560 { 561 struct elf_link_hash_table elf; 562 563 /* Short-cuts to get to dynamic linker sections. */ 564 asection *sgot; 565 asection *sgotplt; 566 asection *srelgot; 567 asection *splt; 568 asection *srelplt; 569 asection *sdynbss; 570 asection *srelbss; 571 572 /* Small local sym to section mapping cache. */ 573 struct sym_cache sym_sec; 574 }; 575 576 /* Get the ELF linker hash table from a link_info structure. */ 577 578 #define elf32_mb_hash_table(p) \ 579 (elf_hash_table_id ((struct elf_link_hash_table *) ((p)->hash)) \ 580 == MICROBLAZE_ELF_DATA ? ((struct elf32_mb_link_hash_table *) ((p)->hash)) : NULL) 581 582 /* Create an entry in a microblaze ELF linker hash table. */ 583 584 static struct bfd_hash_entry * 585 link_hash_newfunc (struct bfd_hash_entry *entry, 586 struct bfd_hash_table *table, 587 const char *string) 588 { 589 /* Allocate the structure if it has not already been allocated by a 590 subclass. */ 591 if (entry == NULL) 592 { 593 entry = bfd_hash_allocate (table, 594 sizeof (struct elf32_mb_link_hash_entry)); 595 if (entry == NULL) 596 return entry; 597 } 598 599 /* Call the allocation method of the superclass. */ 600 entry = _bfd_elf_link_hash_newfunc (entry, table, string); 601 if (entry != NULL) 602 { 603 struct elf32_mb_link_hash_entry *eh; 604 605 eh = (struct elf32_mb_link_hash_entry *) entry; 606 eh->dyn_relocs = NULL; 607 } 608 609 return entry; 610 } 611 612 /* Create a mb ELF linker hash table. */ 613 614 static struct bfd_link_hash_table * 615 microblaze_elf_link_hash_table_create (bfd *abfd) 616 { 617 struct elf32_mb_link_hash_table *ret; 618 bfd_size_type amt = sizeof (struct elf32_mb_link_hash_table); 619 620 ret = (struct elf32_mb_link_hash_table *) bfd_zmalloc (amt); 621 if (ret == NULL) 622 return NULL; 623 624 if (!_bfd_elf_link_hash_table_init (&ret->elf, abfd, link_hash_newfunc, 625 sizeof (struct elf32_mb_link_hash_entry), 626 MICROBLAZE_ELF_DATA)) 627 { 628 free (ret); 629 return NULL; 630 } 631 632 return &ret->elf.root; 633 } 634 635 /* Set the values of the small data pointers. */ 636 637 static void 638 microblaze_elf_final_sdp (struct bfd_link_info *info) 639 { 640 struct bfd_link_hash_entry *h; 641 642 h = bfd_link_hash_lookup (info->hash, RO_SDA_ANCHOR_NAME, FALSE, FALSE, TRUE); 643 if (h != (struct bfd_link_hash_entry *) NULL 644 && h->type == bfd_link_hash_defined) 645 ro_small_data_pointer = (h->u.def.value 646 + h->u.def.section->output_section->vma 647 + h->u.def.section->output_offset); 648 649 h = bfd_link_hash_lookup (info->hash, RW_SDA_ANCHOR_NAME, FALSE, FALSE, TRUE); 650 if (h != (struct bfd_link_hash_entry *) NULL 651 && h->type == bfd_link_hash_defined) 652 rw_small_data_pointer = (h->u.def.value 653 + h->u.def.section->output_section->vma 654 + h->u.def.section->output_offset); 655 } 656 657 /* This code is taken from elf32-m32r.c 658 There is some attempt to make this function usable for many architectures, 659 both USE_REL and USE_RELA ['twould be nice if such a critter existed], 660 if only to serve as a learning tool. 661 662 The RELOCATE_SECTION function is called by the new ELF backend linker 663 to handle the relocations for a section. 664 665 The relocs are always passed as Rela structures; if the section 666 actually uses Rel structures, the r_addend field will always be 667 zero. 668 669 This function is responsible for adjust the section contents as 670 necessary, and (if using Rela relocs and generating a 671 relocatable output file) adjusting the reloc addend as 672 necessary. 673 674 This function does not have to worry about setting the reloc 675 address or the reloc symbol index. 676 677 LOCAL_SYMS is a pointer to the swapped in local symbols. 678 679 LOCAL_SECTIONS is an array giving the section in the input file 680 corresponding to the st_shndx field of each local symbol. 681 682 The global hash table entry for the global symbols can be found 683 via elf_sym_hashes (input_bfd). 684 685 When generating relocatable output, this function must handle 686 STB_LOCAL/STT_SECTION symbols specially. The output symbol is 687 going to be the section symbol corresponding to the output 688 section, which means that the addend must be adjusted 689 accordingly. */ 690 691 static bfd_boolean 692 microblaze_elf_relocate_section (bfd *output_bfd, 693 struct bfd_link_info *info, 694 bfd *input_bfd, 695 asection *input_section, 696 bfd_byte *contents, 697 Elf_Internal_Rela *relocs, 698 Elf_Internal_Sym *local_syms, 699 asection **local_sections) 700 { 701 struct elf32_mb_link_hash_table *htab; 702 Elf_Internal_Shdr *symtab_hdr = &elf_tdata (input_bfd)->symtab_hdr; 703 struct elf_link_hash_entry **sym_hashes = elf_sym_hashes (input_bfd); 704 Elf_Internal_Rela *rel, *relend; 705 /* Assume success. */ 706 bfd_boolean ret = TRUE; 707 asection *sreloc; 708 bfd_vma *local_got_offsets; 709 710 if (!microblaze_elf_howto_table[R_MICROBLAZE_max-1]) 711 microblaze_elf_howto_init (); 712 713 htab = elf32_mb_hash_table (info); 714 if (htab == NULL) 715 return FALSE; 716 717 local_got_offsets = elf_local_got_offsets (input_bfd); 718 719 sreloc = elf_section_data (input_section)->sreloc; 720 721 rel = relocs; 722 relend = relocs + input_section->reloc_count; 723 for (; rel < relend; rel++) 724 { 725 int r_type; 726 reloc_howto_type *howto; 727 unsigned long r_symndx; 728 bfd_vma addend = rel->r_addend; 729 bfd_vma offset = rel->r_offset; 730 struct elf_link_hash_entry *h; 731 Elf_Internal_Sym *sym; 732 asection *sec; 733 const char *sym_name; 734 bfd_reloc_status_type r = bfd_reloc_ok; 735 const char *errmsg = NULL; 736 bfd_boolean unresolved_reloc = FALSE; 737 738 h = NULL; 739 r_type = ELF32_R_TYPE (rel->r_info); 740 if (r_type < 0 || r_type >= (int) R_MICROBLAZE_max) 741 { 742 (*_bfd_error_handler) (_("%s: unknown relocation type %d"), 743 bfd_get_filename (input_bfd), (int) r_type); 744 bfd_set_error (bfd_error_bad_value); 745 ret = FALSE; 746 continue; 747 } 748 749 howto = microblaze_elf_howto_table[r_type]; 750 r_symndx = ELF32_R_SYM (rel->r_info); 751 752 if (info->relocatable) 753 { 754 /* This is a relocatable link. We don't have to change 755 anything, unless the reloc is against a section symbol, 756 in which case we have to adjust according to where the 757 section symbol winds up in the output section. */ 758 sec = NULL; 759 if (r_symndx >= symtab_hdr->sh_info) 760 /* External symbol. */ 761 continue; 762 763 /* Local symbol. */ 764 sym = local_syms + r_symndx; 765 sym_name = "<local symbol>"; 766 /* STT_SECTION: symbol is associated with a section. */ 767 if (ELF_ST_TYPE (sym->st_info) != STT_SECTION) 768 /* Symbol isn't associated with a section. Nothing to do. */ 769 continue; 770 771 sec = local_sections[r_symndx]; 772 addend += sec->output_offset + sym->st_value; 773 #ifndef USE_REL 774 /* This can't be done for USE_REL because it doesn't mean anything 775 and elf_link_input_bfd asserts this stays zero. */ 776 /* rel->r_addend = addend; */ 777 #endif 778 779 #ifndef USE_REL 780 /* Addends are stored with relocs. We're done. */ 781 continue; 782 #else /* USE_REL */ 783 /* If partial_inplace, we need to store any additional addend 784 back in the section. */ 785 if (!howto->partial_inplace) 786 continue; 787 /* ??? Here is a nice place to call a special_function like handler. */ 788 r = _bfd_relocate_contents (howto, input_bfd, addend, 789 contents + offset); 790 #endif /* USE_REL */ 791 } 792 else 793 { 794 bfd_vma relocation; 795 796 /* This is a final link. */ 797 sym = NULL; 798 sec = NULL; 799 unresolved_reloc = FALSE; 800 801 if (r_symndx < symtab_hdr->sh_info) 802 { 803 /* Local symbol. */ 804 sym = local_syms + r_symndx; 805 sec = local_sections[r_symndx]; 806 if (sec == 0) 807 continue; 808 sym_name = "<local symbol>"; 809 relocation = _bfd_elf_rela_local_sym (output_bfd, sym, &sec, rel); 810 /* r_addend may have changed if the reference section was 811 a merge section. */ 812 addend = rel->r_addend; 813 } 814 else 815 { 816 /* External symbol. */ 817 bfd_boolean warned ATTRIBUTE_UNUSED; 818 819 RELOC_FOR_GLOBAL_SYMBOL (info, input_bfd, input_section, rel, 820 r_symndx, symtab_hdr, sym_hashes, 821 h, sec, relocation, 822 unresolved_reloc, warned); 823 sym_name = h->root.root.string; 824 } 825 826 /* Sanity check the address. */ 827 if (offset > bfd_get_section_limit (input_bfd, input_section)) 828 { 829 r = bfd_reloc_outofrange; 830 goto check_reloc; 831 } 832 833 switch ((int) r_type) 834 { 835 case (int) R_MICROBLAZE_SRO32 : 836 { 837 const char *name; 838 839 /* Only relocate if the symbol is defined. */ 840 if (sec) 841 { 842 name = bfd_get_section_name (sec->owner, sec); 843 844 if (strcmp (name, ".sdata2") == 0 845 || strcmp (name, ".sbss2") == 0) 846 { 847 if (ro_small_data_pointer == 0) 848 microblaze_elf_final_sdp (info); 849 if (ro_small_data_pointer == 0) 850 { 851 ret = FALSE; 852 r = bfd_reloc_undefined; 853 goto check_reloc; 854 } 855 856 /* At this point `relocation' contains the object's 857 address. */ 858 relocation -= ro_small_data_pointer; 859 /* Now it contains the offset from _SDA2_BASE_. */ 860 r = _bfd_final_link_relocate (howto, input_bfd, 861 input_section, 862 contents, offset, 863 relocation, addend); 864 } 865 else 866 { 867 (*_bfd_error_handler) (_("%s: The target (%s) of an %s relocation is in the wrong section (%s)"), 868 bfd_get_filename (input_bfd), 869 sym_name, 870 microblaze_elf_howto_table[(int) r_type]->name, 871 bfd_get_section_name (sec->owner, sec)); 872 /*bfd_set_error (bfd_error_bad_value); ??? why? */ 873 ret = FALSE; 874 continue; 875 } 876 } 877 } 878 break; 879 880 case (int) R_MICROBLAZE_SRW32 : 881 { 882 const char *name; 883 884 /* Only relocate if the symbol is defined. */ 885 if (sec) 886 { 887 name = bfd_get_section_name (sec->owner, sec); 888 889 if (strcmp (name, ".sdata") == 0 890 || strcmp (name, ".sbss") == 0) 891 { 892 if (rw_small_data_pointer == 0) 893 microblaze_elf_final_sdp (info); 894 if (rw_small_data_pointer == 0) 895 { 896 ret = FALSE; 897 r = bfd_reloc_undefined; 898 goto check_reloc; 899 } 900 901 /* At this point `relocation' contains the object's 902 address. */ 903 relocation -= rw_small_data_pointer; 904 /* Now it contains the offset from _SDA_BASE_. */ 905 r = _bfd_final_link_relocate (howto, input_bfd, 906 input_section, 907 contents, offset, 908 relocation, addend); 909 } 910 else 911 { 912 (*_bfd_error_handler) (_("%s: The target (%s) of an %s relocation is in the wrong section (%s)"), 913 bfd_get_filename (input_bfd), 914 sym_name, 915 microblaze_elf_howto_table[(int) r_type]->name, 916 bfd_get_section_name (sec->owner, sec)); 917 /*bfd_set_error (bfd_error_bad_value); ??? why? */ 918 ret = FALSE; 919 continue; 920 } 921 } 922 } 923 break; 924 925 case (int) R_MICROBLAZE_32_SYM_OP_SYM: 926 break; /* Do nothing. */ 927 928 case (int) R_MICROBLAZE_GOTPC_64: 929 relocation = htab->sgotplt->output_section->vma 930 + htab->sgotplt->output_offset; 931 relocation -= (input_section->output_section->vma 932 + input_section->output_offset 933 + offset + INST_WORD_SIZE); 934 relocation += addend; 935 bfd_put_16 (input_bfd, (relocation >> 16) & 0xffff, 936 contents + offset + 2); 937 bfd_put_16 (input_bfd, relocation & 0xffff, 938 contents + offset + 2 + INST_WORD_SIZE); 939 break; 940 941 case (int) R_MICROBLAZE_PLT_64: 942 { 943 bfd_vma immediate; 944 if (htab->splt != NULL && h != NULL 945 && h->plt.offset != (bfd_vma) -1) 946 { 947 relocation = (htab->splt->output_section->vma 948 + htab->splt->output_offset 949 + h->plt.offset); 950 unresolved_reloc = FALSE; 951 immediate = relocation - (input_section->output_section->vma 952 + input_section->output_offset 953 + offset + INST_WORD_SIZE); 954 bfd_put_16 (input_bfd, (immediate >> 16) & 0xffff, 955 contents + offset + 2); 956 bfd_put_16 (input_bfd, immediate & 0xffff, 957 contents + offset + 2 + INST_WORD_SIZE); 958 } 959 else 960 { 961 relocation -= (input_section->output_section->vma 962 + input_section->output_offset 963 + offset + INST_WORD_SIZE); 964 immediate = relocation; 965 bfd_put_16 (input_bfd, (immediate >> 16) & 0xffff, 966 contents + offset + 2); 967 bfd_put_16 (input_bfd, immediate & 0xffff, 968 contents + offset + 2 + INST_WORD_SIZE); 969 } 970 break; 971 } 972 973 case (int) R_MICROBLAZE_GOT_64: 974 { 975 if (htab->sgot == NULL) 976 abort (); 977 if (h == NULL) 978 { 979 bfd_vma off; 980 if (local_got_offsets == NULL) 981 abort (); 982 off = local_got_offsets[r_symndx]; 983 /* The LSB indicates whether we've already 984 created relocation. */ 985 if (off & 1) 986 off &= ~1; 987 else 988 { 989 bfd_put_32 (output_bfd, relocation + addend, 990 htab->sgot->contents + off); 991 992 if (info->shared) 993 { 994 Elf_Internal_Rela outrel; 995 bfd_byte *loc; 996 if (htab->srelgot == NULL) 997 abort (); 998 outrel.r_offset = (htab->sgot->output_section->vma 999 + htab->sgot->output_offset 1000 + off); 1001 outrel.r_info = ELF32_R_INFO (0, R_MICROBLAZE_REL); 1002 outrel.r_addend = relocation + addend; 1003 loc = htab->srelgot->contents; 1004 loc += htab->srelgot->reloc_count++ 1005 * sizeof (Elf32_External_Rela); 1006 bfd_elf32_swap_reloca_out (output_bfd, &outrel, loc); 1007 } 1008 local_got_offsets[r_symndx] |= 1; 1009 } 1010 relocation = htab->sgot->output_section->vma 1011 + htab->sgot->output_offset + off 1012 - htab->sgotplt->output_section->vma 1013 - htab->sgotplt->output_offset; 1014 unresolved_reloc = FALSE; 1015 } 1016 else 1017 { 1018 if (htab->sgotplt != NULL && h != NULL 1019 && h->got.offset != (bfd_vma) -1) 1020 { 1021 bfd_put_32 (output_bfd, relocation + addend, 1022 htab->sgot->contents + h->got.offset); 1023 relocation = htab->sgot->output_section->vma 1024 + htab->sgot->output_offset 1025 + h->got.offset 1026 - htab->sgotplt->output_section->vma 1027 - htab->sgotplt->output_offset; 1028 unresolved_reloc = FALSE; 1029 } 1030 else 1031 abort (); /* ??? */ 1032 } 1033 bfd_put_16 (input_bfd, (relocation >> 16) & 0xffff, 1034 contents + offset + 2); 1035 bfd_put_16 (input_bfd, relocation & 0xffff, 1036 contents + offset + 2 + INST_WORD_SIZE); 1037 break; 1038 } 1039 1040 case (int) R_MICROBLAZE_GOTOFF_64: 1041 { 1042 bfd_vma immediate; 1043 unsigned short lo, high; 1044 relocation += addend; 1045 relocation -= htab->sgotplt->output_section->vma 1046 + htab->sgotplt->output_offset; 1047 /* Write this value into correct location. */ 1048 immediate = relocation; 1049 lo = immediate & 0x0000ffff; 1050 high = (immediate >> 16) & 0x0000ffff; 1051 bfd_put_16 (input_bfd, high, contents + offset + 2); 1052 bfd_put_16 (input_bfd, lo, contents + offset + INST_WORD_SIZE + 2); 1053 break; 1054 } 1055 1056 case (int) R_MICROBLAZE_GOTOFF_32: 1057 { 1058 relocation += addend; 1059 relocation -= htab->sgotplt->output_section->vma 1060 + htab->sgotplt->output_offset; 1061 /* Write this value into correct location. */ 1062 bfd_put_32 (input_bfd, relocation, contents + offset); 1063 break; 1064 } 1065 1066 case (int) R_MICROBLAZE_64_PCREL : 1067 case (int) R_MICROBLAZE_64: 1068 case (int) R_MICROBLAZE_32: 1069 { 1070 /* r_symndx will be STN_UNDEF (zero) only for relocs against symbols 1071 from removed linkonce sections, or sections discarded by 1072 a linker script. */ 1073 if (r_symndx == STN_UNDEF || (input_section->flags & SEC_ALLOC) == 0) 1074 { 1075 relocation += addend; 1076 if (r_type == R_MICROBLAZE_32) 1077 bfd_put_32 (input_bfd, relocation, contents + offset); 1078 else 1079 { 1080 if (r_type == R_MICROBLAZE_64_PCREL) 1081 relocation -= (input_section->output_section->vma 1082 + input_section->output_offset 1083 + offset + INST_WORD_SIZE); 1084 bfd_put_16 (input_bfd, (relocation >> 16) & 0xffff, 1085 contents + offset + 2); 1086 bfd_put_16 (input_bfd, relocation & 0xffff, 1087 contents + offset + 2 + INST_WORD_SIZE); 1088 } 1089 break; 1090 } 1091 1092 if ((info->shared 1093 && (h == NULL 1094 || ELF_ST_VISIBILITY (h->other) == STV_DEFAULT 1095 || h->root.type != bfd_link_hash_undefweak) 1096 && (!howto->pc_relative 1097 || (h != NULL 1098 && h->dynindx != -1 1099 && (!info->symbolic 1100 || !h->def_regular)))) 1101 || (!info->shared 1102 && h != NULL 1103 && h->dynindx != -1 1104 && !h->non_got_ref 1105 && ((h->def_dynamic 1106 && !h->def_regular) 1107 || h->root.type == bfd_link_hash_undefweak 1108 || h->root.type == bfd_link_hash_undefined))) 1109 { 1110 Elf_Internal_Rela outrel; 1111 bfd_byte *loc; 1112 bfd_boolean skip; 1113 1114 /* When generating a shared object, these relocations 1115 are copied into the output file to be resolved at run 1116 time. */ 1117 1118 BFD_ASSERT (sreloc != NULL); 1119 1120 skip = FALSE; 1121 1122 outrel.r_offset = 1123 _bfd_elf_section_offset (output_bfd, info, input_section, 1124 rel->r_offset); 1125 if (outrel.r_offset == (bfd_vma) -1) 1126 skip = TRUE; 1127 else if (outrel.r_offset == (bfd_vma) -2) 1128 skip = TRUE; 1129 outrel.r_offset += (input_section->output_section->vma 1130 + input_section->output_offset); 1131 1132 if (skip) 1133 memset (&outrel, 0, sizeof outrel); 1134 /* h->dynindx may be -1 if the symbol was marked to 1135 become local. */ 1136 else if (h != NULL 1137 && ((! info->symbolic && h->dynindx != -1) 1138 || !h->def_regular)) 1139 { 1140 BFD_ASSERT (h->dynindx != -1); 1141 outrel.r_info = ELF32_R_INFO (h->dynindx, r_type); 1142 outrel.r_addend = addend; 1143 } 1144 else 1145 { 1146 if (r_type == R_MICROBLAZE_32) 1147 { 1148 outrel.r_info = ELF32_R_INFO (0, R_MICROBLAZE_REL); 1149 outrel.r_addend = relocation + addend; 1150 } 1151 else 1152 { 1153 BFD_FAIL (); 1154 (*_bfd_error_handler) 1155 (_("%B: probably compiled without -fPIC?"), 1156 input_bfd); 1157 bfd_set_error (bfd_error_bad_value); 1158 return FALSE; 1159 } 1160 } 1161 1162 loc = sreloc->contents; 1163 loc += sreloc->reloc_count++ * sizeof (Elf32_External_Rela); 1164 bfd_elf32_swap_reloca_out (output_bfd, &outrel, loc); 1165 break; 1166 } 1167 else 1168 { 1169 relocation += addend; 1170 if (r_type == R_MICROBLAZE_32) 1171 bfd_put_32 (input_bfd, relocation, contents + offset); 1172 else 1173 { 1174 if (r_type == R_MICROBLAZE_64_PCREL) 1175 relocation -= (input_section->output_section->vma 1176 + input_section->output_offset 1177 + offset + INST_WORD_SIZE); 1178 bfd_put_16 (input_bfd, (relocation >> 16) & 0xffff, 1179 contents + offset + 2); 1180 bfd_put_16 (input_bfd, relocation & 0xffff, 1181 contents + offset + 2 + INST_WORD_SIZE); 1182 } 1183 break; 1184 } 1185 } 1186 1187 default : 1188 r = _bfd_final_link_relocate (howto, input_bfd, input_section, 1189 contents, offset, 1190 relocation, addend); 1191 break; 1192 } 1193 } 1194 1195 check_reloc: 1196 1197 if (r != bfd_reloc_ok) 1198 { 1199 /* FIXME: This should be generic enough to go in a utility. */ 1200 const char *name; 1201 1202 if (h != NULL) 1203 name = h->root.root.string; 1204 else 1205 { 1206 name = (bfd_elf_string_from_elf_section 1207 (input_bfd, symtab_hdr->sh_link, sym->st_name)); 1208 if (name == NULL || *name == '\0') 1209 name = bfd_section_name (input_bfd, sec); 1210 } 1211 1212 if (errmsg != NULL) 1213 goto common_error; 1214 1215 switch (r) 1216 { 1217 case bfd_reloc_overflow: 1218 if (!((*info->callbacks->reloc_overflow) 1219 (info, (h ? &h->root : NULL), name, howto->name, 1220 (bfd_vma) 0, input_bfd, input_section, offset))) 1221 return FALSE; 1222 break; 1223 1224 case bfd_reloc_undefined: 1225 if (!((*info->callbacks->undefined_symbol) 1226 (info, name, input_bfd, input_section, offset, TRUE))) 1227 return FALSE; 1228 break; 1229 1230 case bfd_reloc_outofrange: 1231 errmsg = _("internal error: out of range error"); 1232 goto common_error; 1233 1234 case bfd_reloc_notsupported: 1235 errmsg = _("internal error: unsupported relocation error"); 1236 goto common_error; 1237 1238 case bfd_reloc_dangerous: 1239 errmsg = _("internal error: dangerous error"); 1240 goto common_error; 1241 1242 default: 1243 errmsg = _("internal error: unknown error"); 1244 /* Fall through. */ 1245 common_error: 1246 if (!((*info->callbacks->warning) 1247 (info, errmsg, name, input_bfd, input_section, offset))) 1248 return FALSE; 1249 break; 1250 } 1251 } 1252 } 1253 1254 return ret; 1255 } 1256 1257 /* Calculate fixup value for reference. */ 1258 1259 static int 1260 calc_fixup (bfd_vma addr, asection *sec) 1261 { 1262 int i, fixup = 0; 1263 1264 if (sec == NULL || sec->relax == NULL) 1265 return 0; 1266 1267 /* Look for addr in relax table, total fixup value. */ 1268 for (i = 0; i < sec->relax_count; i++) 1269 { 1270 if (addr <= sec->relax[i].addr) 1271 break; 1272 fixup += sec->relax[i].size; 1273 } 1274 1275 return fixup; 1276 } 1277 1278 static bfd_boolean 1279 microblaze_elf_relax_section (bfd *abfd, 1280 asection *sec, 1281 struct bfd_link_info *link_info, 1282 bfd_boolean *again) 1283 { 1284 Elf_Internal_Shdr *symtab_hdr; 1285 Elf_Internal_Rela *internal_relocs; 1286 Elf_Internal_Rela *free_relocs = NULL; 1287 Elf_Internal_Rela *irel, *irelend; 1288 bfd_byte *contents = NULL; 1289 bfd_byte *free_contents = NULL; 1290 int rel_count; 1291 unsigned int shndx; 1292 int i, sym_index; 1293 asection *o; 1294 struct elf_link_hash_entry *sym_hash; 1295 Elf_Internal_Sym *isymbuf, *isymend; 1296 Elf_Internal_Sym *isym; 1297 int symcount; 1298 int offset; 1299 bfd_vma src, dest; 1300 1301 /* We only do this once per section. We may be able to delete some code 1302 by running multiple passes, but it is not worth it. */ 1303 *again = FALSE; 1304 1305 /* Only do this for a text section. */ 1306 if (link_info->relocatable 1307 || (sec->flags & SEC_RELOC) == 0 1308 || (sec->reloc_count == 0)) 1309 return TRUE; 1310 1311 BFD_ASSERT ((sec->size > 0) || (sec->rawsize > 0)); 1312 1313 /* If this is the first time we have been called for this section, 1314 initialize the cooked size. */ 1315 if (sec->size == 0) 1316 sec->size = sec->rawsize; 1317 1318 /* Get symbols for this section. */ 1319 symtab_hdr = &elf_tdata (abfd)->symtab_hdr; 1320 isymbuf = (Elf_Internal_Sym *) symtab_hdr->contents; 1321 symcount = symtab_hdr->sh_size / sizeof (Elf32_External_Sym); 1322 if (isymbuf == NULL) 1323 isymbuf = bfd_elf_get_elf_syms (abfd, symtab_hdr, symcount, 1324 0, NULL, NULL, NULL); 1325 BFD_ASSERT (isymbuf != NULL); 1326 1327 internal_relocs = _bfd_elf_link_read_relocs (abfd, sec, NULL, NULL, link_info->keep_memory); 1328 if (internal_relocs == NULL) 1329 goto error_return; 1330 if (! link_info->keep_memory) 1331 free_relocs = internal_relocs; 1332 1333 sec->relax = (struct relax_table *) bfd_malloc ((sec->reloc_count + 1) 1334 * sizeof (struct relax_table)); 1335 if (sec->relax == NULL) 1336 goto error_return; 1337 sec->relax_count = 0; 1338 1339 irelend = internal_relocs + sec->reloc_count; 1340 rel_count = 0; 1341 for (irel = internal_relocs; irel < irelend; irel++, rel_count++) 1342 { 1343 bfd_vma symval; 1344 if ((ELF32_R_TYPE (irel->r_info) != (int) R_MICROBLAZE_64_PCREL) 1345 && (ELF32_R_TYPE (irel->r_info) != (int) R_MICROBLAZE_64 )) 1346 continue; /* Can't delete this reloc. */ 1347 1348 /* Get the section contents. */ 1349 if (contents == NULL) 1350 { 1351 if (elf_section_data (sec)->this_hdr.contents != NULL) 1352 contents = elf_section_data (sec)->this_hdr.contents; 1353 else 1354 { 1355 contents = (bfd_byte *) bfd_malloc (sec->size); 1356 if (contents == NULL) 1357 goto error_return; 1358 free_contents = contents; 1359 1360 if (!bfd_get_section_contents (abfd, sec, contents, 1361 (file_ptr) 0, sec->size)) 1362 goto error_return; 1363 elf_section_data (sec)->this_hdr.contents = contents; 1364 } 1365 } 1366 1367 /* Get the value of the symbol referred to by the reloc. */ 1368 if (ELF32_R_SYM (irel->r_info) < symtab_hdr->sh_info) 1369 { 1370 /* A local symbol. */ 1371 asection *sym_sec; 1372 1373 isym = isymbuf + ELF32_R_SYM (irel->r_info); 1374 if (isym->st_shndx == SHN_UNDEF) 1375 sym_sec = bfd_und_section_ptr; 1376 else if (isym->st_shndx == SHN_ABS) 1377 sym_sec = bfd_abs_section_ptr; 1378 else if (isym->st_shndx == SHN_COMMON) 1379 sym_sec = bfd_com_section_ptr; 1380 else 1381 sym_sec = bfd_section_from_elf_index (abfd, isym->st_shndx); 1382 1383 symval = _bfd_elf_rela_local_sym (abfd, isym, &sym_sec, irel); 1384 } 1385 else 1386 { 1387 unsigned long indx; 1388 struct elf_link_hash_entry *h; 1389 1390 indx = ELF32_R_SYM (irel->r_info) - symtab_hdr->sh_info; 1391 h = elf_sym_hashes (abfd)[indx]; 1392 BFD_ASSERT (h != NULL); 1393 1394 if (h->root.type != bfd_link_hash_defined 1395 && h->root.type != bfd_link_hash_defweak) 1396 /* This appears to be a reference to an undefined 1397 symbol. Just ignore it--it will be caught by the 1398 regular reloc processing. */ 1399 continue; 1400 1401 symval = (h->root.u.def.value 1402 + h->root.u.def.section->output_section->vma 1403 + h->root.u.def.section->output_offset); 1404 } 1405 1406 /* If this is a PC-relative reloc, subtract the instr offset from 1407 the symbol value. */ 1408 if (ELF32_R_TYPE (irel->r_info) == (int) R_MICROBLAZE_64_PCREL) 1409 { 1410 symval = symval + irel->r_addend 1411 - (irel->r_offset 1412 + sec->output_section->vma 1413 + sec->output_offset); 1414 } 1415 else 1416 symval += irel->r_addend; 1417 1418 if ((symval & 0xffff8000) == 0 1419 || (symval & 0xffff8000) == 0xffff8000) 1420 { 1421 /* We can delete this instruction. */ 1422 sec->relax[sec->relax_count].addr = irel->r_offset; 1423 sec->relax[sec->relax_count].size = INST_WORD_SIZE; 1424 sec->relax_count++; 1425 1426 /* Rewrite relocation type. */ 1427 switch ((enum elf_microblaze_reloc_type) ELF32_R_TYPE (irel->r_info)) 1428 { 1429 case R_MICROBLAZE_64_PCREL: 1430 irel->r_info = ELF32_R_INFO (ELF32_R_SYM (irel->r_info), 1431 (int) R_MICROBLAZE_32_PCREL_LO); 1432 break; 1433 case R_MICROBLAZE_64: 1434 irel->r_info = ELF32_R_INFO (ELF32_R_SYM (irel->r_info), 1435 (int) R_MICROBLAZE_32_LO); 1436 break; 1437 default: 1438 /* Cannot happen. */ 1439 BFD_ASSERT (FALSE); 1440 } 1441 } 1442 } /* Loop through all relocations. */ 1443 1444 /* Loop through the relocs again, and see if anything needs to change. */ 1445 if (sec->relax_count > 0) 1446 { 1447 shndx = _bfd_elf_section_from_bfd_section (abfd, sec); 1448 rel_count = 0; 1449 sec->relax[sec->relax_count].addr = sec->size; 1450 1451 for (irel = internal_relocs; irel < irelend; irel++, rel_count++) 1452 { 1453 bfd_vma nraddr; 1454 1455 /* Get the new reloc address. */ 1456 nraddr = irel->r_offset - calc_fixup (irel->r_offset, sec); 1457 switch ((enum elf_microblaze_reloc_type) ELF32_R_TYPE (irel->r_info)) 1458 { 1459 default: 1460 break; 1461 case R_MICROBLAZE_64_PCREL: 1462 break; 1463 case R_MICROBLAZE_64: 1464 case R_MICROBLAZE_32_LO: 1465 /* If this reloc is against a symbol defined in this 1466 section, we must check the addend to see it will put the value in 1467 range to be adjusted, and hence must be changed. */ 1468 if (ELF32_R_SYM (irel->r_info) < symtab_hdr->sh_info) 1469 { 1470 isym = isymbuf + ELF32_R_SYM (irel->r_info); 1471 /* Only handle relocs against .text. */ 1472 if (isym->st_shndx == shndx 1473 && ELF32_ST_TYPE (isym->st_info) == STT_SECTION) 1474 irel->r_addend -= calc_fixup (irel->r_addend, sec); 1475 } 1476 break; 1477 case R_MICROBLAZE_NONE: 1478 { 1479 /* This was a PC-relative instruction that was 1480 completely resolved. */ 1481 int sfix, efix; 1482 bfd_vma target_address; 1483 target_address = irel->r_addend + irel->r_offset; 1484 sfix = calc_fixup (irel->r_offset, sec); 1485 efix = calc_fixup (target_address, sec); 1486 irel->r_addend -= (efix - sfix); 1487 /* Should use HOWTO. */ 1488 bfd_put_16 (abfd, irel->r_addend, contents + irel->r_offset + 2); 1489 } 1490 break; 1491 case R_MICROBLAZE_64_NONE: 1492 { 1493 /* This was a PC-relative 64-bit instruction that was 1494 completely resolved. */ 1495 int sfix, efix; 1496 bfd_vma target_address; 1497 target_address = irel->r_addend + irel->r_offset + INST_WORD_SIZE; 1498 sfix = calc_fixup (irel->r_offset + INST_WORD_SIZE, sec); 1499 efix = calc_fixup (target_address, sec); 1500 irel->r_addend -= (efix - sfix); 1501 bfd_put_16 (abfd, irel->r_addend, contents + irel->r_offset 1502 + INST_WORD_SIZE + 2); 1503 } 1504 break; 1505 } 1506 irel->r_offset = nraddr; 1507 } /* Change all relocs in this section. */ 1508 1509 /* Look through all other sections. */ 1510 for (o = abfd->sections; o != NULL; o = o->next) 1511 { 1512 Elf_Internal_Rela *irelocs; 1513 Elf_Internal_Rela *irelscan, *irelscanend; 1514 bfd_byte *ocontents; 1515 1516 if (o == sec 1517 || (o->flags & SEC_RELOC) == 0 1518 || o->reloc_count == 0) 1519 continue; 1520 1521 /* We always cache the relocs. Perhaps, if info->keep_memory is 1522 FALSE, we should free them, if we are permitted to. */ 1523 1524 irelocs = _bfd_elf_link_read_relocs (abfd, o, NULL, NULL, TRUE); 1525 if (irelocs == NULL) 1526 goto error_return; 1527 1528 ocontents = NULL; 1529 irelscanend = irelocs + o->reloc_count; 1530 for (irelscan = irelocs; irelscan < irelscanend; irelscan++) 1531 { 1532 if (ELF32_R_TYPE (irelscan->r_info) == (int) R_MICROBLAZE_32) 1533 { 1534 isym = isymbuf + ELF32_R_SYM (irelscan->r_info); 1535 1536 /* Look at the reloc only if the value has been resolved. */ 1537 if (isym->st_shndx == shndx 1538 && (ELF32_ST_TYPE (isym->st_info) == STT_SECTION)) 1539 { 1540 if (ocontents == NULL) 1541 { 1542 if (elf_section_data (o)->this_hdr.contents != NULL) 1543 ocontents = elf_section_data (o)->this_hdr.contents; 1544 else 1545 { 1546 /* We always cache the section contents. 1547 Perhaps, if info->keep_memory is FALSE, we 1548 should free them, if we are permitted to. */ 1549 if (o->rawsize == 0) 1550 o->rawsize = o->size; 1551 ocontents = (bfd_byte *) bfd_malloc (o->rawsize); 1552 if (ocontents == NULL) 1553 goto error_return; 1554 if (!bfd_get_section_contents (abfd, o, ocontents, 1555 (file_ptr) 0, 1556 o->rawsize)) 1557 goto error_return; 1558 elf_section_data (o)->this_hdr.contents = ocontents; 1559 } 1560 1561 } 1562 irelscan->r_addend -= calc_fixup (irelscan->r_addend, sec); 1563 } 1564 else if (ELF32_R_TYPE (irelscan->r_info) == (int) R_MICROBLAZE_32_SYM_OP_SYM) 1565 { 1566 isym = isymbuf + ELF32_R_SYM (irelscan->r_info); 1567 1568 /* Look at the reloc only if the value has been resolved. */ 1569 if (ocontents == NULL) 1570 { 1571 if (elf_section_data (o)->this_hdr.contents != NULL) 1572 ocontents = elf_section_data (o)->this_hdr.contents; 1573 else 1574 { 1575 /* We always cache the section contents. 1576 Perhaps, if info->keep_memory is FALSE, we 1577 should free them, if we are permitted to. */ 1578 1579 if (o->rawsize == 0) 1580 o->rawsize = o->size; 1581 ocontents = (bfd_byte *) bfd_malloc (o->rawsize); 1582 if (ocontents == NULL) 1583 goto error_return; 1584 if (!bfd_get_section_contents (abfd, o, ocontents, 1585 (file_ptr) 0, 1586 o->rawsize)) 1587 goto error_return; 1588 elf_section_data (o)->this_hdr.contents = ocontents; 1589 } 1590 } 1591 irelscan->r_addend -= calc_fixup (irel->r_addend 1592 + isym->st_value, 1593 sec); 1594 } 1595 } 1596 else if ((ELF32_R_TYPE (irelscan->r_info) == (int) R_MICROBLAZE_32_PCREL_LO) 1597 || (ELF32_R_TYPE (irelscan->r_info) == (int) R_MICROBLAZE_32_LO)) 1598 { 1599 isym = isymbuf + ELF32_R_SYM (irelscan->r_info); 1600 1601 /* Look at the reloc only if the value has been resolved. */ 1602 if (isym->st_shndx == shndx 1603 && (ELF32_ST_TYPE (isym->st_info) == STT_SECTION)) 1604 { 1605 bfd_vma immediate; 1606 bfd_vma target_address; 1607 1608 if (ocontents == NULL) 1609 { 1610 if (elf_section_data (o)->this_hdr.contents != NULL) 1611 ocontents = elf_section_data (o)->this_hdr.contents; 1612 else 1613 { 1614 /* We always cache the section contents. 1615 Perhaps, if info->keep_memory is FALSE, we 1616 should free them, if we are permitted to. */ 1617 if (o->rawsize == 0) 1618 o->rawsize = o->size; 1619 ocontents = (bfd_byte *) bfd_malloc (o->rawsize); 1620 if (ocontents == NULL) 1621 goto error_return; 1622 if (!bfd_get_section_contents (abfd, o, ocontents, 1623 (file_ptr) 0, 1624 o->rawsize)) 1625 goto error_return; 1626 elf_section_data (o)->this_hdr.contents = ocontents; 1627 } 1628 } 1629 1630 immediate = (unsigned short) bfd_get_16 (abfd, ocontents + 1631 irelscan->r_offset + 2); 1632 target_address = immediate; 1633 offset = calc_fixup (target_address, sec); 1634 immediate -= offset; 1635 irelscan->r_addend -= offset; 1636 bfd_put_16 (abfd, immediate, ocontents + irelscan->r_offset + 2); 1637 } 1638 } 1639 1640 if (ELF32_R_TYPE (irelscan->r_info) == (int) R_MICROBLAZE_64) 1641 { 1642 isym = isymbuf + ELF32_R_SYM (irelscan->r_info); 1643 1644 /* Look at the reloc only if the value has been resolved. */ 1645 if (isym->st_shndx == shndx 1646 && (ELF32_ST_TYPE (isym->st_info) == STT_SECTION)) 1647 { 1648 bfd_vma immediate; 1649 1650 if (ocontents == NULL) 1651 { 1652 if (elf_section_data (o)->this_hdr.contents != NULL) 1653 ocontents = elf_section_data (o)->this_hdr.contents; 1654 else 1655 { 1656 /* We always cache the section contents. 1657 Perhaps, if info->keep_memory is FALSE, we 1658 should free them, if we are permitted to. */ 1659 1660 if (o->rawsize == 0) 1661 o->rawsize = o->size; 1662 ocontents = (bfd_byte *) bfd_malloc (o->rawsize); 1663 if (ocontents == NULL) 1664 goto error_return; 1665 if (!bfd_get_section_contents (abfd, o, ocontents, 1666 (file_ptr) 0, 1667 o->rawsize)) 1668 goto error_return; 1669 elf_section_data (o)->this_hdr.contents = ocontents; 1670 } 1671 } 1672 immediate = (unsigned short) (bfd_get_16 (abfd, ocontents 1673 + irelscan->r_offset 1674 + 2) << 16) 1675 & 0xffff0000; 1676 immediate += (unsigned short) (bfd_get_16 (abfd, ocontents 1677 + irelscan->r_offset 1678 + INST_WORD_SIZE + 2)) 1679 & 0x0000ffff; 1680 1681 offset = calc_fixup (irelscan->r_addend, sec); 1682 immediate -= offset; 1683 irelscan->r_addend -= offset; 1684 } 1685 } 1686 else if (ELF32_R_TYPE (irelscan->r_info) == (int) R_MICROBLAZE_64_PCREL) 1687 { 1688 isym = isymbuf + ELF32_R_SYM (irelscan->r_info); 1689 1690 /* Look at the reloc only if the value has been resolved. */ 1691 if (isym->st_shndx == shndx 1692 && (ELF32_ST_TYPE (isym->st_info) == STT_SECTION)) 1693 { 1694 bfd_vma immediate; 1695 bfd_vma target_address; 1696 1697 if (ocontents == NULL) 1698 { 1699 if (elf_section_data (o)->this_hdr.contents != NULL) 1700 ocontents = elf_section_data (o)->this_hdr.contents; 1701 else 1702 { 1703 /* We always cache the section contents. 1704 Perhaps, if info->keep_memory is FALSE, we 1705 should free them, if we are permitted to. */ 1706 if (o->rawsize == 0) 1707 o->rawsize = o->size; 1708 ocontents = (bfd_byte *) bfd_malloc (o->rawsize); 1709 if (ocontents == NULL) 1710 goto error_return; 1711 if (!bfd_get_section_contents (abfd, o, ocontents, 1712 (file_ptr) 0, 1713 o->rawsize)) 1714 goto error_return; 1715 elf_section_data (o)->this_hdr.contents = ocontents; 1716 } 1717 } 1718 1719 immediate = (unsigned short) 1720 (bfd_get_16 (abfd, ocontents + irelscan->r_offset + 2) << 16) 1721 & 0xffff0000; 1722 immediate += (unsigned short) 1723 (bfd_get_16 (abfd, ocontents + irelscan->r_offset 1724 + INST_WORD_SIZE + 2)) 1725 & 0x0000ffff; 1726 target_address = immediate; 1727 offset = calc_fixup (target_address, sec); 1728 immediate -= offset; 1729 irelscan->r_addend -= offset; 1730 bfd_put_16 (abfd, ((immediate >> 16) & 0x0000ffff), 1731 ocontents + irelscan->r_offset + 2); 1732 bfd_put_16 (abfd, (immediate & 0x0000ffff), 1733 ocontents + irelscan->r_offset + INST_WORD_SIZE + 2); 1734 } 1735 } 1736 } 1737 } 1738 1739 /* Adjust the local symbols defined in this section. */ 1740 isymend = isymbuf + symtab_hdr->sh_info; 1741 for (isym = isymbuf; isym < isymend; isym++) 1742 { 1743 if (isym->st_shndx == shndx) 1744 isym->st_value =- calc_fixup (isym->st_value, sec); 1745 } 1746 1747 /* Now adjust the global symbols defined in this section. */ 1748 isym = isymbuf + symtab_hdr->sh_info; 1749 isymend = isymbuf + (symtab_hdr->sh_size / sizeof (Elf32_External_Sym)); 1750 for (sym_index = 0; isym < isymend; isym++, sym_index++) 1751 { 1752 sym_hash = elf_sym_hashes (abfd)[sym_index]; 1753 if (isym->st_shndx == shndx 1754 && (sym_hash->root.type == bfd_link_hash_defined 1755 || sym_hash->root.type == bfd_link_hash_defweak) 1756 && sym_hash->root.u.def.section == sec) 1757 { 1758 sym_hash->root.u.def.value -= calc_fixup (sym_hash->root.u.def.value, 1759 sec); 1760 } 1761 } 1762 1763 /* Physically move the code and change the cooked size. */ 1764 dest = sec->relax[0].addr; 1765 for (i = 0; i < sec->relax_count; i++) 1766 { 1767 int len; 1768 src = sec->relax[i].addr + sec->relax[i].size; 1769 len = sec->relax[i+1].addr - sec->relax[i].addr - sec->relax[i].size; 1770 1771 memmove (contents + dest, contents + src, len); 1772 sec->size -= sec->relax[i].size; 1773 dest += len; 1774 } 1775 1776 elf_section_data (sec)->relocs = internal_relocs; 1777 free_relocs = NULL; 1778 1779 elf_section_data (sec)->this_hdr.contents = contents; 1780 free_contents = NULL; 1781 1782 symtab_hdr->contents = (bfd_byte *) isymbuf; 1783 } 1784 1785 if (free_relocs != NULL) 1786 { 1787 free (free_relocs); 1788 free_relocs = NULL; 1789 } 1790 1791 if (free_contents != NULL) 1792 { 1793 if (!link_info->keep_memory) 1794 free (free_contents); 1795 else 1796 /* Cache the section contents for elf_link_input_bfd. */ 1797 elf_section_data (sec)->this_hdr.contents = contents; 1798 free_contents = NULL; 1799 } 1800 1801 if (sec->relax_count == 0) 1802 { 1803 free (sec->relax); 1804 sec->relax = NULL; 1805 } 1806 return TRUE; 1807 1808 error_return: 1809 if (free_relocs != NULL) 1810 free (free_relocs); 1811 if (free_contents != NULL) 1812 free (free_contents); 1813 if (sec->relax != NULL) 1814 { 1815 free (sec->relax); 1816 sec->relax = NULL; 1817 sec->relax_count = 0; 1818 } 1819 return FALSE; 1820 } 1821 1822 /* Return the section that should be marked against GC for a given 1823 relocation. */ 1824 1825 static asection * 1826 microblaze_elf_gc_mark_hook (asection *sec, 1827 struct bfd_link_info * info, 1828 Elf_Internal_Rela * rel, 1829 struct elf_link_hash_entry * h, 1830 Elf_Internal_Sym * sym) 1831 { 1832 if (h != NULL) 1833 switch (ELF32_R_TYPE (rel->r_info)) 1834 { 1835 case R_MICROBLAZE_GNU_VTINHERIT: 1836 case R_MICROBLAZE_GNU_VTENTRY: 1837 return NULL; 1838 } 1839 1840 return _bfd_elf_gc_mark_hook (sec, info, rel, h, sym); 1841 } 1842 1843 /* Update the got entry reference counts for the section being removed. */ 1844 1845 static bfd_boolean 1846 microblaze_elf_gc_sweep_hook (bfd * abfd ATTRIBUTE_UNUSED, 1847 struct bfd_link_info * info ATTRIBUTE_UNUSED, 1848 asection * sec ATTRIBUTE_UNUSED, 1849 const Elf_Internal_Rela * relocs ATTRIBUTE_UNUSED) 1850 { 1851 return TRUE; 1852 } 1853 1854 /* PIC support. */ 1855 1856 #define PLT_ENTRY_SIZE 16 1857 1858 #define PLT_ENTRY_WORD_0 0xb0000000 /* "imm 0". */ 1859 #define PLT_ENTRY_WORD_1 0xe9940000 /* "lwi r12,r20,0" - relocated to lwi r12,r20,func@GOT. */ 1860 #define PLT_ENTRY_WORD_1_NOPIC 0xe9800000 /* "lwi r12,r0,0" - non-PIC object. */ 1861 #define PLT_ENTRY_WORD_2 0x98186000 /* "brad r12". */ 1862 #define PLT_ENTRY_WORD_3 0x80000000 /* "nop". */ 1863 1864 /* Create .got, .gotplt, and .rela.got sections in DYNOBJ, and set up 1865 shortcuts to them in our hash table. */ 1866 1867 static bfd_boolean 1868 create_got_section (bfd *dynobj, struct bfd_link_info *info) 1869 { 1870 struct elf32_mb_link_hash_table *htab; 1871 1872 if (! _bfd_elf_create_got_section (dynobj, info)) 1873 return FALSE; 1874 htab = elf32_mb_hash_table (info); 1875 if (htab == NULL) 1876 return FALSE; 1877 1878 htab->sgot = bfd_get_linker_section (dynobj, ".got"); 1879 htab->sgotplt = bfd_get_linker_section (dynobj, ".got.plt"); 1880 if (!htab->sgot || !htab->sgotplt) 1881 return FALSE; 1882 1883 if ((htab->srelgot = bfd_get_linker_section (dynobj, ".rela.got")) == NULL) 1884 htab->srelgot = bfd_make_section_anyway (dynobj, ".rela.got"); 1885 if (htab->srelgot == NULL 1886 || ! bfd_set_section_flags (dynobj, htab->srelgot, SEC_ALLOC 1887 | SEC_LOAD 1888 | SEC_HAS_CONTENTS 1889 | SEC_IN_MEMORY 1890 | SEC_LINKER_CREATED 1891 | SEC_READONLY) 1892 || ! bfd_set_section_alignment (dynobj, htab->srelgot, 2)) 1893 return FALSE; 1894 return TRUE; 1895 } 1896 1897 /* Look through the relocs for a section during the first phase. */ 1898 1899 static bfd_boolean 1900 microblaze_elf_check_relocs (bfd * abfd, 1901 struct bfd_link_info * info, 1902 asection * sec, 1903 const Elf_Internal_Rela * relocs) 1904 { 1905 Elf_Internal_Shdr * symtab_hdr; 1906 struct elf_link_hash_entry ** sym_hashes; 1907 struct elf_link_hash_entry ** sym_hashes_end; 1908 const Elf_Internal_Rela * rel; 1909 const Elf_Internal_Rela * rel_end; 1910 struct elf32_mb_link_hash_table *htab; 1911 asection *sreloc = NULL; 1912 1913 if (info->relocatable) 1914 return TRUE; 1915 1916 htab = elf32_mb_hash_table (info); 1917 if (htab == NULL) 1918 return FALSE; 1919 1920 symtab_hdr = & elf_tdata (abfd)->symtab_hdr; 1921 sym_hashes = elf_sym_hashes (abfd); 1922 sym_hashes_end = sym_hashes + symtab_hdr->sh_size / sizeof (Elf32_External_Sym); 1923 if (!elf_bad_symtab (abfd)) 1924 sym_hashes_end -= symtab_hdr->sh_info; 1925 1926 rel_end = relocs + sec->reloc_count; 1927 1928 for (rel = relocs; rel < rel_end; rel++) 1929 { 1930 unsigned int r_type; 1931 struct elf_link_hash_entry * h; 1932 unsigned long r_symndx; 1933 1934 r_symndx = ELF32_R_SYM (rel->r_info); 1935 r_type = ELF32_R_TYPE (rel->r_info); 1936 1937 if (r_symndx < symtab_hdr->sh_info) 1938 h = NULL; 1939 else 1940 h = sym_hashes [r_symndx - symtab_hdr->sh_info]; 1941 1942 switch (r_type) 1943 { 1944 /* This relocation describes the C++ object vtable hierarchy. 1945 Reconstruct it for later use during GC. */ 1946 case R_MICROBLAZE_GNU_VTINHERIT: 1947 if (!bfd_elf_gc_record_vtinherit (abfd, sec, h, rel->r_offset)) 1948 return FALSE; 1949 break; 1950 1951 /* This relocation describes which C++ vtable entries are actually 1952 used. Record for later use during GC. */ 1953 case R_MICROBLAZE_GNU_VTENTRY: 1954 if (!bfd_elf_gc_record_vtentry (abfd, sec, h, rel->r_addend)) 1955 return FALSE; 1956 break; 1957 1958 /* This relocation requires .plt entry. */ 1959 case R_MICROBLAZE_PLT_64: 1960 if (h != NULL) 1961 { 1962 h->needs_plt = 1; 1963 h->plt.refcount += 1; 1964 } 1965 break; 1966 1967 /* This relocation requires .got entry. */ 1968 case R_MICROBLAZE_GOT_64: 1969 if (htab->sgot == NULL) 1970 { 1971 if (htab->elf.dynobj == NULL) 1972 htab->elf.dynobj = abfd; 1973 if (!create_got_section (htab->elf.dynobj, info)) 1974 return FALSE; 1975 } 1976 if (h != NULL) 1977 { 1978 h->got.refcount += 1; 1979 } 1980 else 1981 { 1982 bfd_signed_vma *local_got_refcounts; 1983 1984 /* This is a global offset table entry for a local symbol. */ 1985 local_got_refcounts = elf_local_got_refcounts (abfd); 1986 if (local_got_refcounts == NULL) 1987 { 1988 bfd_size_type size; 1989 1990 size = symtab_hdr->sh_info; 1991 size *= sizeof (bfd_signed_vma); 1992 local_got_refcounts = bfd_zalloc (abfd, size); 1993 if (local_got_refcounts == NULL) 1994 return FALSE; 1995 elf_local_got_refcounts (abfd) = local_got_refcounts; 1996 } 1997 local_got_refcounts[r_symndx] += 1; 1998 } 1999 break; 2000 2001 case R_MICROBLAZE_64: 2002 case R_MICROBLAZE_64_PCREL: 2003 case R_MICROBLAZE_32: 2004 { 2005 if (h != NULL && !info->shared) 2006 { 2007 /* we may need a copy reloc. */ 2008 h->non_got_ref = 1; 2009 2010 /* we may also need a .plt entry. */ 2011 h->plt.refcount += 1; 2012 if (ELF32_R_TYPE (rel->r_info) != R_MICROBLAZE_64_PCREL) 2013 h->pointer_equality_needed = 1; 2014 } 2015 2016 2017 /* If we are creating a shared library, and this is a reloc 2018 against a global symbol, or a non PC relative reloc 2019 against a local symbol, then we need to copy the reloc 2020 into the shared library. However, if we are linking with 2021 -Bsymbolic, we do not need to copy a reloc against a 2022 global symbol which is defined in an object we are 2023 including in the link (i.e., DEF_REGULAR is set). At 2024 this point we have not seen all the input files, so it is 2025 possible that DEF_REGULAR is not set now but will be set 2026 later (it is never cleared). In case of a weak definition, 2027 DEF_REGULAR may be cleared later by a strong definition in 2028 a shared library. We account for that possibility below by 2029 storing information in the relocs_copied field of the hash 2030 table entry. A similar situation occurs when creating 2031 shared libraries and symbol visibility changes render the 2032 symbol local. 2033 2034 If on the other hand, we are creating an executable, we 2035 may need to keep relocations for symbols satisfied by a 2036 dynamic library if we manage to avoid copy relocs for the 2037 symbol. */ 2038 2039 if ((info->shared 2040 && (sec->flags & SEC_ALLOC) != 0 2041 && (r_type != R_MICROBLAZE_64_PCREL 2042 || (h != NULL 2043 && (! info->symbolic 2044 || h->root.type == bfd_link_hash_defweak 2045 || !h->def_regular)))) 2046 || (!info->shared 2047 && (sec->flags & SEC_ALLOC) != 0 2048 && h != NULL 2049 && (h->root.type == bfd_link_hash_defweak 2050 || !h->def_regular))) 2051 { 2052 struct elf32_mb_dyn_relocs *p; 2053 struct elf32_mb_dyn_relocs **head; 2054 2055 /* When creating a shared object, we must copy these 2056 relocs into the output file. We create a reloc 2057 section in dynobj and make room for the reloc. */ 2058 2059 if (sreloc == NULL) 2060 { 2061 const char *name; 2062 bfd *dynobj; 2063 unsigned int strndx = elf_elfheader (abfd)->e_shstrndx; 2064 unsigned int shnam = _bfd_elf_single_rel_hdr (sec)->sh_name; 2065 2066 name = bfd_elf_string_from_elf_section (abfd, strndx, shnam); 2067 if (name == NULL) 2068 return FALSE; 2069 2070 if (strncmp (name, ".rela", 5) != 0 2071 || strcmp (bfd_get_section_name (abfd, sec), 2072 name + 5) != 0) 2073 { 2074 (*_bfd_error_handler) 2075 (_("%B: bad relocation section name `%s\'"), 2076 abfd, name); 2077 } 2078 2079 if (htab->elf.dynobj == NULL) 2080 htab->elf.dynobj = abfd; 2081 dynobj = htab->elf.dynobj; 2082 2083 sreloc = bfd_get_linker_section (dynobj, name); 2084 if (sreloc == NULL) 2085 { 2086 flagword flags; 2087 2088 flags = (SEC_HAS_CONTENTS | SEC_READONLY 2089 | SEC_IN_MEMORY | SEC_LINKER_CREATED); 2090 if ((sec->flags & SEC_ALLOC) != 0) 2091 flags |= SEC_ALLOC | SEC_LOAD; 2092 sreloc = bfd_make_section_anyway_with_flags (dynobj, 2093 name, 2094 flags); 2095 if (sreloc == NULL 2096 || ! bfd_set_section_alignment (dynobj, sreloc, 2)) 2097 return FALSE; 2098 } 2099 elf_section_data (sec)->sreloc = sreloc; 2100 } 2101 2102 /* If this is a global symbol, we count the number of 2103 relocations we need for this symbol. */ 2104 if (h != NULL) 2105 head = &((struct elf32_mb_link_hash_entry *) h)->dyn_relocs; 2106 else 2107 { 2108 /* Track dynamic relocs needed for local syms too. 2109 We really need local syms available to do this 2110 easily. Oh well. */ 2111 2112 asection *s; 2113 Elf_Internal_Sym *isym; 2114 void *vpp; 2115 2116 isym = bfd_sym_from_r_symndx (&htab->sym_sec, 2117 abfd, r_symndx); 2118 if (isym == NULL) 2119 return FALSE; 2120 2121 s = bfd_section_from_elf_index (abfd, isym->st_shndx); 2122 if (s == NULL) 2123 return FALSE; 2124 2125 vpp = &elf_section_data (s)->local_dynrel; 2126 head = (struct elf32_mb_dyn_relocs **) vpp; 2127 } 2128 2129 p = *head; 2130 if (p == NULL || p->sec != sec) 2131 { 2132 bfd_size_type amt = sizeof *p; 2133 p = ((struct elf32_mb_dyn_relocs *) 2134 bfd_alloc (htab->elf.dynobj, amt)); 2135 if (p == NULL) 2136 return FALSE; 2137 p->next = *head; 2138 *head = p; 2139 p->sec = sec; 2140 p->count = 0; 2141 p->pc_count = 0; 2142 } 2143 2144 p->count += 1; 2145 if (r_type == R_MICROBLAZE_64_PCREL) 2146 p->pc_count += 1; 2147 } 2148 } 2149 break; 2150 } 2151 } 2152 2153 return TRUE; 2154 } 2155 2156 static bfd_boolean 2157 microblaze_elf_create_dynamic_sections (bfd *dynobj, struct bfd_link_info *info) 2158 { 2159 struct elf32_mb_link_hash_table *htab; 2160 2161 htab = elf32_mb_hash_table (info); 2162 if (htab == NULL) 2163 return FALSE; 2164 2165 if (!htab->sgot && !create_got_section (dynobj, info)) 2166 return FALSE; 2167 2168 if (!_bfd_elf_create_dynamic_sections (dynobj, info)) 2169 return FALSE; 2170 2171 htab->splt = bfd_get_linker_section (dynobj, ".plt"); 2172 htab->srelplt = bfd_get_linker_section (dynobj, ".rela.plt"); 2173 htab->sdynbss = bfd_get_linker_section (dynobj, ".dynbss"); 2174 if (!info->shared) 2175 htab->srelbss = bfd_get_linker_section (dynobj, ".rela.bss"); 2176 2177 if (!htab->splt || !htab->srelplt || !htab->sdynbss 2178 || (!info->shared && !htab->srelbss)) 2179 abort (); 2180 2181 return TRUE; 2182 } 2183 2184 /* Copy the extra info we tack onto an elf_link_hash_entry. */ 2185 2186 static void 2187 microblaze_elf_copy_indirect_symbol (struct bfd_link_info *info, 2188 struct elf_link_hash_entry *dir, 2189 struct elf_link_hash_entry *ind) 2190 { 2191 struct elf32_mb_link_hash_entry *edir, *eind; 2192 2193 edir = (struct elf32_mb_link_hash_entry *) dir; 2194 eind = (struct elf32_mb_link_hash_entry *) ind; 2195 2196 if (eind->dyn_relocs != NULL) 2197 { 2198 if (edir->dyn_relocs != NULL) 2199 { 2200 struct elf32_mb_dyn_relocs **pp; 2201 struct elf32_mb_dyn_relocs *p; 2202 2203 if (ind->root.type == bfd_link_hash_indirect) 2204 abort (); 2205 2206 /* Add reloc counts against the weak sym to the strong sym 2207 list. Merge any entries against the same section. */ 2208 for (pp = &eind->dyn_relocs; (p = *pp) != NULL; ) 2209 { 2210 struct elf32_mb_dyn_relocs *q; 2211 2212 for (q = edir->dyn_relocs; q != NULL; q = q->next) 2213 if (q->sec == p->sec) 2214 { 2215 q->pc_count += p->pc_count; 2216 q->count += p->count; 2217 *pp = p->next; 2218 break; 2219 } 2220 if (q == NULL) 2221 pp = &p->next; 2222 } 2223 *pp = edir->dyn_relocs; 2224 } 2225 2226 edir->dyn_relocs = eind->dyn_relocs; 2227 eind->dyn_relocs = NULL; 2228 } 2229 2230 _bfd_elf_link_hash_copy_indirect (info, dir, ind); 2231 } 2232 2233 static bfd_boolean 2234 microblaze_elf_adjust_dynamic_symbol (struct bfd_link_info *info, 2235 struct elf_link_hash_entry *h) 2236 { 2237 struct elf32_mb_link_hash_table *htab; 2238 struct elf32_mb_link_hash_entry * eh; 2239 struct elf32_mb_dyn_relocs *p; 2240 asection *sdynbss, *s; 2241 unsigned int power_of_two; 2242 bfd *dynobj; 2243 2244 htab = elf32_mb_hash_table (info); 2245 if (htab == NULL) 2246 return FALSE; 2247 2248 /* If this is a function, put it in the procedure linkage table. We 2249 will fill in the contents of the procedure linkage table later, 2250 when we know the address of the .got section. */ 2251 if (h->type == STT_FUNC 2252 || h->needs_plt) 2253 { 2254 if (h->plt.refcount <= 0 2255 || SYMBOL_CALLS_LOCAL (info, h) 2256 || (ELF_ST_VISIBILITY (h->other) != STV_DEFAULT 2257 && h->root.type == bfd_link_hash_undefweak)) 2258 { 2259 /* This case can occur if we saw a PLT reloc in an input 2260 file, but the symbol was never referred to by a dynamic 2261 object, or if all references were garbage collected. In 2262 such a case, we don't actually need to build a procedure 2263 linkage table, and we can just do a PC32 reloc instead. */ 2264 h->plt.offset = (bfd_vma) -1; 2265 h->needs_plt = 0; 2266 } 2267 2268 return TRUE; 2269 } 2270 else 2271 /* It's possible that we incorrectly decided a .plt reloc was 2272 needed for an R_MICROBLAZE_64_PCREL reloc to a non-function sym in 2273 check_relocs. We can't decide accurately between function and 2274 non-function syms in check-relocs; Objects loaded later in 2275 the link may change h->type. So fix it now. */ 2276 h->plt.offset = (bfd_vma) -1; 2277 2278 /* If this is a weak symbol, and there is a real definition, the 2279 processor independent code will have arranged for us to see the 2280 real definition first, and we can just use the same value. */ 2281 if (h->u.weakdef != NULL) 2282 { 2283 BFD_ASSERT (h->u.weakdef->root.type == bfd_link_hash_defined 2284 || h->u.weakdef->root.type == bfd_link_hash_defweak); 2285 h->root.u.def.section = h->u.weakdef->root.u.def.section; 2286 h->root.u.def.value = h->u.weakdef->root.u.def.value; 2287 return TRUE; 2288 } 2289 2290 /* This is a reference to a symbol defined by a dynamic object which 2291 is not a function. */ 2292 2293 /* If we are creating a shared library, we must presume that the 2294 only references to the symbol are via the global offset table. 2295 For such cases we need not do anything here; the relocations will 2296 be handled correctly by relocate_section. */ 2297 if (info->shared) 2298 return TRUE; 2299 2300 /* If there are no references to this symbol that do not use the 2301 GOT, we don't need to generate a copy reloc. */ 2302 if (!h->non_got_ref) 2303 return TRUE; 2304 2305 /* If -z nocopyreloc was given, we won't generate them either. */ 2306 if (info->nocopyreloc) 2307 { 2308 h->non_got_ref = 0; 2309 return TRUE; 2310 } 2311 2312 eh = (struct elf32_mb_link_hash_entry *) h; 2313 for (p = eh->dyn_relocs; p != NULL; p = p->next) 2314 { 2315 s = p->sec->output_section; 2316 if (s != NULL && (s->flags & SEC_READONLY) != 0) 2317 break; 2318 } 2319 2320 /* If we didn't find any dynamic relocs in read-only sections, then 2321 we'll be keeping the dynamic relocs and avoiding the copy reloc. */ 2322 if (p == NULL) 2323 { 2324 h->non_got_ref = 0; 2325 return TRUE; 2326 } 2327 2328 /* We must allocate the symbol in our .dynbss section, which will 2329 become part of the .bss section of the executable. There will be 2330 an entry for this symbol in the .dynsym section. The dynamic 2331 object will contain position independent code, so all references 2332 from the dynamic object to this symbol will go through the global 2333 offset table. The dynamic linker will use the .dynsym entry to 2334 determine the address it must put in the global offset table, so 2335 both the dynamic object and the regular object will refer to the 2336 same memory location for the variable. */ 2337 2338 /* We must generate a R_MICROBLAZE_COPY reloc to tell the dynamic linker 2339 to copy the initial value out of the dynamic object and into the 2340 runtime process image. */ 2341 dynobj = elf_hash_table (info)->dynobj; 2342 BFD_ASSERT (dynobj != NULL); 2343 if ((h->root.u.def.section->flags & SEC_ALLOC) != 0) 2344 { 2345 htab->srelbss->size += sizeof (Elf32_External_Rela); 2346 h->needs_copy = 1; 2347 } 2348 2349 /* We need to figure out the alignment required for this symbol. I 2350 have no idea how ELF linkers handle this. */ 2351 power_of_two = bfd_log2 (h->size); 2352 if (power_of_two > 3) 2353 power_of_two = 3; 2354 2355 sdynbss = htab->sdynbss; 2356 /* Apply the required alignment. */ 2357 sdynbss->size = BFD_ALIGN (sdynbss->size, (bfd_size_type) (1 << power_of_two)); 2358 if (power_of_two > bfd_get_section_alignment (dynobj, sdynbss)) 2359 { 2360 if (! bfd_set_section_alignment (dynobj, sdynbss, power_of_two)) 2361 return FALSE; 2362 } 2363 2364 /* Define the symbol as being at this point in the section. */ 2365 h->root.u.def.section = sdynbss; 2366 h->root.u.def.value = sdynbss->size; 2367 2368 /* Increment the section size to make room for the symbol. */ 2369 sdynbss->size += h->size; 2370 return TRUE; 2371 } 2372 2373 /* Allocate space in .plt, .got and associated reloc sections for 2374 dynamic relocs. */ 2375 2376 static bfd_boolean 2377 allocate_dynrelocs (struct elf_link_hash_entry *h, void * dat) 2378 { 2379 struct bfd_link_info *info; 2380 struct elf32_mb_link_hash_table *htab; 2381 struct elf32_mb_link_hash_entry *eh; 2382 struct elf32_mb_dyn_relocs *p; 2383 2384 if (h->root.type == bfd_link_hash_indirect) 2385 return TRUE; 2386 2387 info = (struct bfd_link_info *) dat; 2388 htab = elf32_mb_hash_table (info); 2389 if (htab == NULL) 2390 return FALSE; 2391 2392 if (htab->elf.dynamic_sections_created 2393 && h->plt.refcount > 0) 2394 { 2395 /* Make sure this symbol is output as a dynamic symbol. 2396 Undefined weak syms won't yet be marked as dynamic. */ 2397 if (h->dynindx == -1 2398 && !h->forced_local) 2399 { 2400 if (! bfd_elf_link_record_dynamic_symbol (info, h)) 2401 return FALSE; 2402 } 2403 2404 if (WILL_CALL_FINISH_DYNAMIC_SYMBOL (1, info->shared, h)) 2405 { 2406 asection *s = htab->splt; 2407 2408 /* The first entry in .plt is reserved. */ 2409 if (s->size == 0) 2410 s->size = PLT_ENTRY_SIZE; 2411 2412 h->plt.offset = s->size; 2413 2414 /* If this symbol is not defined in a regular file, and we are 2415 not generating a shared library, then set the symbol to this 2416 location in the .plt. This is required to make function 2417 pointers compare as equal between the normal executable and 2418 the shared library. */ 2419 if (! info->shared 2420 && !h->def_regular) 2421 { 2422 h->root.u.def.section = s; 2423 h->root.u.def.value = h->plt.offset; 2424 } 2425 2426 /* Make room for this entry. */ 2427 s->size += PLT_ENTRY_SIZE; 2428 2429 /* We also need to make an entry in the .got.plt section, which 2430 will be placed in the .got section by the linker script. */ 2431 htab->sgotplt->size += 4; 2432 2433 /* We also need to make an entry in the .rel.plt section. */ 2434 htab->srelplt->size += sizeof (Elf32_External_Rela); 2435 } 2436 else 2437 { 2438 h->plt.offset = (bfd_vma) -1; 2439 h->needs_plt = 0; 2440 } 2441 } 2442 else 2443 { 2444 h->plt.offset = (bfd_vma) -1; 2445 h->needs_plt = 0; 2446 } 2447 2448 if (h->got.refcount > 0) 2449 { 2450 asection *s; 2451 2452 /* Make sure this symbol is output as a dynamic symbol. 2453 Undefined weak syms won't yet be marked as dynamic. */ 2454 if (h->dynindx == -1 2455 && !h->forced_local) 2456 { 2457 if (! bfd_elf_link_record_dynamic_symbol (info, h)) 2458 return FALSE; 2459 } 2460 2461 s = htab->sgot; 2462 h->got.offset = s->size; 2463 s->size += 4; 2464 htab->srelgot->size += sizeof (Elf32_External_Rela); 2465 } 2466 else 2467 h->got.offset = (bfd_vma) -1; 2468 2469 eh = (struct elf32_mb_link_hash_entry *) h; 2470 if (eh->dyn_relocs == NULL) 2471 return TRUE; 2472 2473 /* In the shared -Bsymbolic case, discard space allocated for 2474 dynamic pc-relative relocs against symbols which turn out to be 2475 defined in regular objects. For the normal shared case, discard 2476 space for pc-relative relocs that have become local due to symbol 2477 visibility changes. */ 2478 2479 if (info->shared) 2480 { 2481 if (h->def_regular 2482 && (h->forced_local 2483 || info->symbolic)) 2484 { 2485 struct elf32_mb_dyn_relocs **pp; 2486 2487 for (pp = &eh->dyn_relocs; (p = *pp) != NULL; ) 2488 { 2489 p->count -= p->pc_count; 2490 p->pc_count = 0; 2491 if (p->count == 0) 2492 *pp = p->next; 2493 else 2494 pp = &p->next; 2495 } 2496 } 2497 } 2498 else 2499 { 2500 /* For the non-shared case, discard space for relocs against 2501 symbols which turn out to need copy relocs or are not 2502 dynamic. */ 2503 2504 if (!h->non_got_ref 2505 && ((h->def_dynamic 2506 && !h->def_regular) 2507 || (htab->elf.dynamic_sections_created 2508 && (h->root.type == bfd_link_hash_undefweak 2509 || h->root.type == bfd_link_hash_undefined)))) 2510 { 2511 /* Make sure this symbol is output as a dynamic symbol. 2512 Undefined weak syms won't yet be marked as dynamic. */ 2513 if (h->dynindx == -1 2514 && !h->forced_local) 2515 { 2516 if (! bfd_elf_link_record_dynamic_symbol (info, h)) 2517 return FALSE; 2518 } 2519 2520 /* If that succeeded, we know we'll be keeping all the 2521 relocs. */ 2522 if (h->dynindx != -1) 2523 goto keep; 2524 } 2525 2526 eh->dyn_relocs = NULL; 2527 2528 keep: ; 2529 } 2530 2531 /* Finally, allocate space. */ 2532 for (p = eh->dyn_relocs; p != NULL; p = p->next) 2533 { 2534 asection *sreloc = elf_section_data (p->sec)->sreloc; 2535 sreloc->size += p->count * sizeof (Elf32_External_Rela); 2536 } 2537 2538 return TRUE; 2539 } 2540 2541 /* Set the sizes of the dynamic sections. */ 2542 2543 static bfd_boolean 2544 microblaze_elf_size_dynamic_sections (bfd *output_bfd ATTRIBUTE_UNUSED, 2545 struct bfd_link_info *info) 2546 { 2547 struct elf32_mb_link_hash_table *htab; 2548 bfd *dynobj; 2549 asection *s; 2550 bfd *ibfd; 2551 2552 htab = elf32_mb_hash_table (info); 2553 if (htab == NULL) 2554 return FALSE; 2555 2556 dynobj = htab->elf.dynobj; 2557 BFD_ASSERT (dynobj != NULL); 2558 2559 /* Set up .got offsets for local syms, and space for local dynamic 2560 relocs. */ 2561 for (ibfd = info->input_bfds; ibfd != NULL; ibfd = ibfd->link_next) 2562 { 2563 bfd_signed_vma *local_got; 2564 bfd_signed_vma *end_local_got; 2565 bfd_size_type locsymcount; 2566 Elf_Internal_Shdr *symtab_hdr; 2567 asection *srel; 2568 2569 if (bfd_get_flavour (ibfd) != bfd_target_elf_flavour) 2570 continue; 2571 2572 for (s = ibfd->sections; s != NULL; s = s->next) 2573 { 2574 struct elf32_mb_dyn_relocs *p; 2575 2576 for (p = ((struct elf32_mb_dyn_relocs *) 2577 elf_section_data (s)->local_dynrel); 2578 p != NULL; 2579 p = p->next) 2580 { 2581 if (!bfd_is_abs_section (p->sec) 2582 && bfd_is_abs_section (p->sec->output_section)) 2583 { 2584 /* Input section has been discarded, either because 2585 it is a copy of a linkonce section or due to 2586 linker script /DISCARD/, so we'll be discarding 2587 the relocs too. */ 2588 } 2589 else if (p->count != 0) 2590 { 2591 srel = elf_section_data (p->sec)->sreloc; 2592 srel->size += p->count * sizeof (Elf32_External_Rela); 2593 if ((p->sec->output_section->flags & SEC_READONLY) != 0) 2594 info->flags |= DF_TEXTREL; 2595 } 2596 } 2597 } 2598 2599 local_got = elf_local_got_refcounts (ibfd); 2600 if (!local_got) 2601 continue; 2602 2603 symtab_hdr = &elf_tdata (ibfd)->symtab_hdr; 2604 locsymcount = symtab_hdr->sh_info; 2605 end_local_got = local_got + locsymcount; 2606 s = htab->sgot; 2607 srel = htab->srelgot; 2608 2609 for (; local_got < end_local_got; ++local_got) 2610 { 2611 if (*local_got > 0) 2612 { 2613 *local_got = s->size; 2614 s->size += 4; 2615 if (info->shared) 2616 srel->size += sizeof (Elf32_External_Rela); 2617 } 2618 else 2619 *local_got = (bfd_vma) -1; 2620 } 2621 } 2622 2623 /* Allocate global sym .plt and .got entries, and space for global 2624 sym dynamic relocs. */ 2625 elf_link_hash_traverse (elf_hash_table (info), allocate_dynrelocs, info); 2626 2627 if (elf_hash_table (info)->dynamic_sections_created) 2628 { 2629 /* Make space for the trailing nop in .plt. */ 2630 if (htab->splt->size > 0) 2631 htab->splt->size += 4; 2632 } 2633 2634 /* The check_relocs and adjust_dynamic_symbol entry points have 2635 determined the sizes of the various dynamic sections. Allocate 2636 memory for them. */ 2637 for (s = dynobj->sections; s != NULL; s = s->next) 2638 { 2639 const char *name; 2640 bfd_boolean strip = FALSE; 2641 2642 if ((s->flags & SEC_LINKER_CREATED) == 0) 2643 continue; 2644 2645 /* It's OK to base decisions on the section name, because none 2646 of the dynobj section names depend upon the input files. */ 2647 name = bfd_get_section_name (dynobj, s); 2648 2649 if (strncmp (name, ".rela", 5) == 0) 2650 { 2651 if (s->size == 0) 2652 { 2653 /* If we don't need this section, strip it from the 2654 output file. This is to handle .rela.bss and 2655 .rela.plt. We must create it in 2656 create_dynamic_sections, because it must be created 2657 before the linker maps input sections to output 2658 sections. The linker does that before 2659 adjust_dynamic_symbol is called, and it is that 2660 function which decides whether anything needs to go 2661 into these sections. */ 2662 strip = TRUE; 2663 } 2664 else 2665 { 2666 /* We use the reloc_count field as a counter if we need 2667 to copy relocs into the output file. */ 2668 s->reloc_count = 0; 2669 } 2670 } 2671 else if (s != htab->splt && s != htab->sgot && s != htab->sgotplt) 2672 { 2673 /* It's not one of our sections, so don't allocate space. */ 2674 continue; 2675 } 2676 2677 if (strip) 2678 { 2679 s->flags |= SEC_EXCLUDE; 2680 continue; 2681 } 2682 2683 /* Allocate memory for the section contents. */ 2684 /* FIXME: This should be a call to bfd_alloc not bfd_zalloc. 2685 Unused entries should be reclaimed before the section's contents 2686 are written out, but at the moment this does not happen. Thus in 2687 order to prevent writing out garbage, we initialise the section's 2688 contents to zero. */ 2689 s->contents = (bfd_byte *) bfd_zalloc (dynobj, s->size); 2690 if (s->contents == NULL && s->size != 0) 2691 return FALSE; 2692 } 2693 2694 if (elf_hash_table (info)->dynamic_sections_created) 2695 { 2696 /* Add some entries to the .dynamic section. We fill in the 2697 values later, in microblaze_elf_finish_dynamic_sections, but we 2698 must add the entries now so that we get the correct size for 2699 the .dynamic section. The DT_DEBUG entry is filled in by the 2700 dynamic linker and used by the debugger. */ 2701 #define add_dynamic_entry(TAG, VAL) \ 2702 _bfd_elf_add_dynamic_entry (info, TAG, VAL) 2703 2704 if (info->executable) 2705 { 2706 if (!add_dynamic_entry (DT_DEBUG, 0)) 2707 return FALSE; 2708 } 2709 2710 if (!add_dynamic_entry (DT_RELA, 0) 2711 || !add_dynamic_entry (DT_RELASZ, 0) 2712 || !add_dynamic_entry (DT_RELAENT, sizeof (Elf32_External_Rela))) 2713 return FALSE; 2714 2715 if (htab->splt->size != 0) 2716 { 2717 if (!add_dynamic_entry (DT_PLTGOT, 0) 2718 || !add_dynamic_entry (DT_PLTRELSZ, 0) 2719 || !add_dynamic_entry (DT_PLTREL, DT_RELA) 2720 || !add_dynamic_entry (DT_JMPREL, 0) 2721 || !add_dynamic_entry (DT_BIND_NOW, 1)) 2722 return FALSE; 2723 } 2724 2725 if (info->flags & DF_TEXTREL) 2726 { 2727 if (!add_dynamic_entry (DT_TEXTREL, 0)) 2728 return FALSE; 2729 } 2730 } 2731 #undef add_dynamic_entry 2732 return TRUE; 2733 } 2734 2735 /* Finish up dynamic symbol handling. We set the contents of various 2736 dynamic sections here. */ 2737 2738 static bfd_boolean 2739 microblaze_elf_finish_dynamic_symbol (bfd *output_bfd, 2740 struct bfd_link_info *info, 2741 struct elf_link_hash_entry *h, 2742 Elf_Internal_Sym *sym) 2743 { 2744 struct elf32_mb_link_hash_table *htab; 2745 2746 htab = elf32_mb_hash_table (info); 2747 if (htab == NULL) 2748 return FALSE; 2749 2750 if (h->plt.offset != (bfd_vma) -1) 2751 { 2752 asection *splt; 2753 asection *srela; 2754 asection *sgotplt; 2755 Elf_Internal_Rela rela; 2756 bfd_byte *loc; 2757 bfd_vma plt_index; 2758 bfd_vma got_offset; 2759 bfd_vma got_addr; 2760 2761 /* This symbol has an entry in the procedure linkage table. Set 2762 it up. */ 2763 BFD_ASSERT (h->dynindx != -1); 2764 2765 splt = htab->splt; 2766 srela = htab->srelplt; 2767 sgotplt = htab->sgotplt; 2768 BFD_ASSERT (splt != NULL && srela != NULL && sgotplt != NULL); 2769 2770 plt_index = h->plt.offset / PLT_ENTRY_SIZE - 1; /* first entry reserved. */ 2771 got_offset = (plt_index + 3) * 4; /* 3 reserved ??? */ 2772 got_addr = got_offset; 2773 2774 /* For non-PIC objects we need absolute address of the GOT entry. */ 2775 if (!info->shared) 2776 got_addr += htab->sgotplt->output_section->vma + sgotplt->output_offset; 2777 2778 /* Fill in the entry in the procedure linkage table. */ 2779 bfd_put_32 (output_bfd, PLT_ENTRY_WORD_0 + ((got_addr >> 16) & 0xffff), 2780 splt->contents + h->plt.offset); 2781 if (info->shared) 2782 bfd_put_32 (output_bfd, PLT_ENTRY_WORD_1 + (got_addr & 0xffff), 2783 splt->contents + h->plt.offset + 4); 2784 else 2785 bfd_put_32 (output_bfd, PLT_ENTRY_WORD_1_NOPIC + (got_addr & 0xffff), 2786 splt->contents + h->plt.offset + 4); 2787 bfd_put_32 (output_bfd, (bfd_vma) PLT_ENTRY_WORD_2, 2788 splt->contents + h->plt.offset + 8); 2789 bfd_put_32 (output_bfd, (bfd_vma) PLT_ENTRY_WORD_3, 2790 splt->contents + h->plt.offset + 12); 2791 2792 /* Any additions to the .got section??? */ 2793 /* bfd_put_32 (output_bfd, 2794 splt->output_section->vma + splt->output_offset + h->plt.offset + 4, 2795 sgotplt->contents + got_offset); */ 2796 2797 /* Fill in the entry in the .rela.plt section. */ 2798 rela.r_offset = (sgotplt->output_section->vma 2799 + sgotplt->output_offset 2800 + got_offset); 2801 rela.r_info = ELF32_R_INFO (h->dynindx, R_MICROBLAZE_JUMP_SLOT); 2802 rela.r_addend = 0; 2803 loc = srela->contents; 2804 loc += plt_index * sizeof (Elf32_External_Rela); 2805 bfd_elf32_swap_reloca_out (output_bfd, &rela, loc); 2806 2807 if (!h->def_regular) 2808 { 2809 /* Mark the symbol as undefined, rather than as defined in 2810 the .plt section. Zero the value. */ 2811 sym->st_shndx = SHN_UNDEF; 2812 sym->st_value = 0; 2813 } 2814 } 2815 2816 if (h->got.offset != (bfd_vma) -1) 2817 { 2818 asection *sgot; 2819 asection *srela; 2820 Elf_Internal_Rela rela; 2821 bfd_byte *loc; 2822 2823 /* This symbol has an entry in the global offset table. Set it 2824 up. */ 2825 2826 sgot = htab->sgot; 2827 srela = htab->srelgot; 2828 BFD_ASSERT (sgot != NULL && srela != NULL); 2829 2830 rela.r_offset = (sgot->output_section->vma 2831 + sgot->output_offset 2832 + (h->got.offset &~ (bfd_vma) 1)); 2833 2834 /* If this is a -Bsymbolic link, and the symbol is defined 2835 locally, we just want to emit a RELATIVE reloc. Likewise if 2836 the symbol was forced to be local because of a version file. 2837 The entry in the global offset table will already have been 2838 initialized in the relocate_section function. */ 2839 if (info->shared 2840 && (info->symbolic || h->dynindx == -1) 2841 && h->def_regular) 2842 { 2843 asection *sec = h->root.u.def.section; 2844 rela.r_info = ELF32_R_INFO (0, R_MICROBLAZE_REL); 2845 rela.r_addend = (h->root.u.def.value 2846 + sec->output_section->vma 2847 + sec->output_offset); 2848 } 2849 else 2850 { 2851 rela.r_info = ELF32_R_INFO (h->dynindx, R_MICROBLAZE_GLOB_DAT); 2852 rela.r_addend = 0; 2853 } 2854 2855 bfd_put_32 (output_bfd, (bfd_vma) 0, 2856 sgot->contents + (h->got.offset &~ (bfd_vma) 1)); 2857 loc = srela->contents; 2858 loc += srela->reloc_count++ * sizeof (Elf32_External_Rela); 2859 bfd_elf32_swap_reloca_out (output_bfd, &rela, loc); 2860 } 2861 2862 if (h->needs_copy) 2863 { 2864 asection *s; 2865 Elf_Internal_Rela rela; 2866 bfd_byte *loc; 2867 2868 /* This symbols needs a copy reloc. Set it up. */ 2869 2870 BFD_ASSERT (h->dynindx != -1); 2871 2872 s = bfd_get_linker_section (htab->elf.dynobj, ".rela.bss"); 2873 BFD_ASSERT (s != NULL); 2874 2875 rela.r_offset = (h->root.u.def.value 2876 + h->root.u.def.section->output_section->vma 2877 + h->root.u.def.section->output_offset); 2878 rela.r_info = ELF32_R_INFO (h->dynindx, R_MICROBLAZE_COPY); 2879 rela.r_addend = 0; 2880 loc = s->contents + s->reloc_count++ * sizeof (Elf32_External_Rela); 2881 bfd_elf32_swap_reloca_out (output_bfd, &rela, loc); 2882 } 2883 2884 /* Mark some specially defined symbols as absolute. */ 2885 if (strcmp (h->root.root.string, "_DYNAMIC") == 0 2886 || strcmp (h->root.root.string, "_GLOBAL_OFFSET_TABLE_") == 0 2887 || strcmp (h->root.root.string, "_PROCEDURE_LINKAGE_TABLE_") == 0) 2888 sym->st_shndx = SHN_ABS; 2889 2890 return TRUE; 2891 } 2892 2893 2894 /* Finish up the dynamic sections. */ 2895 2896 static bfd_boolean 2897 microblaze_elf_finish_dynamic_sections (bfd *output_bfd, 2898 struct bfd_link_info *info) 2899 { 2900 bfd *dynobj; 2901 asection *sdyn, *sgot; 2902 struct elf32_mb_link_hash_table *htab; 2903 2904 htab = elf32_mb_hash_table (info); 2905 if (htab == NULL) 2906 return FALSE; 2907 2908 dynobj = htab->elf.dynobj; 2909 2910 sdyn = bfd_get_linker_section (dynobj, ".dynamic"); 2911 2912 if (htab->elf.dynamic_sections_created) 2913 { 2914 asection *splt; 2915 Elf32_External_Dyn *dyncon, *dynconend; 2916 2917 splt = bfd_get_linker_section (dynobj, ".plt"); 2918 BFD_ASSERT (splt != NULL && sdyn != NULL); 2919 2920 dyncon = (Elf32_External_Dyn *) sdyn->contents; 2921 dynconend = (Elf32_External_Dyn *) (sdyn->contents + sdyn->size); 2922 for (; dyncon < dynconend; dyncon++) 2923 { 2924 Elf_Internal_Dyn dyn; 2925 const char *name; 2926 bfd_boolean size; 2927 2928 bfd_elf32_swap_dyn_in (dynobj, dyncon, &dyn); 2929 2930 switch (dyn.d_tag) 2931 { 2932 case DT_PLTGOT: name = ".got.plt"; size = FALSE; break; 2933 case DT_PLTRELSZ: name = ".rela.plt"; size = TRUE; break; 2934 case DT_JMPREL: name = ".rela.plt"; size = FALSE; break; 2935 case DT_RELA: name = ".rela.dyn"; size = FALSE; break; 2936 case DT_RELASZ: name = ".rela.dyn"; size = TRUE; break; 2937 default: name = NULL; size = FALSE; break; 2938 } 2939 2940 if (name != NULL) 2941 { 2942 asection *s; 2943 2944 s = bfd_get_section_by_name (output_bfd, name); 2945 if (s == NULL) 2946 dyn.d_un.d_val = 0; 2947 else 2948 { 2949 if (! size) 2950 dyn.d_un.d_ptr = s->vma; 2951 else 2952 dyn.d_un.d_val = s->size; 2953 } 2954 bfd_elf32_swap_dyn_out (output_bfd, &dyn, dyncon); 2955 } 2956 } 2957 2958 /* Clear the first entry in the procedure linkage table, 2959 and put a nop in the last four bytes. */ 2960 if (splt->size > 0) 2961 { 2962 memset (splt->contents, 0, PLT_ENTRY_SIZE); 2963 bfd_put_32 (output_bfd, (bfd_vma) 0x80000000 /* nop. */, 2964 splt->contents + splt->size - 4); 2965 } 2966 2967 elf_section_data (splt->output_section)->this_hdr.sh_entsize = 4; 2968 } 2969 2970 /* Set the first entry in the global offset table to the address of 2971 the dynamic section. */ 2972 sgot = bfd_get_linker_section (dynobj, ".got.plt"); 2973 if (sgot && sgot->size > 0) 2974 { 2975 if (sdyn == NULL) 2976 bfd_put_32 (output_bfd, (bfd_vma) 0, sgot->contents); 2977 else 2978 bfd_put_32 (output_bfd, 2979 sdyn->output_section->vma + sdyn->output_offset, 2980 sgot->contents); 2981 elf_section_data (sgot->output_section)->this_hdr.sh_entsize = 4; 2982 } 2983 2984 if (htab->sgot && htab->sgot->size > 0) 2985 elf_section_data (htab->sgot->output_section)->this_hdr.sh_entsize = 4; 2986 2987 return TRUE; 2988 } 2989 2990 /* Hook called by the linker routine which adds symbols from an object 2991 file. We use it to put .comm items in .sbss, and not .bss. */ 2992 2993 static bfd_boolean 2994 microblaze_elf_add_symbol_hook (bfd *abfd, 2995 struct bfd_link_info *info, 2996 Elf_Internal_Sym *sym, 2997 const char **namep ATTRIBUTE_UNUSED, 2998 flagword *flagsp ATTRIBUTE_UNUSED, 2999 asection **secp, 3000 bfd_vma *valp) 3001 { 3002 if (sym->st_shndx == SHN_COMMON 3003 && !info->relocatable 3004 && sym->st_size <= elf_gp_size (abfd)) 3005 { 3006 /* Common symbols less than or equal to -G nn bytes are automatically 3007 put into .sbss. */ 3008 *secp = bfd_make_section_old_way (abfd, ".sbss"); 3009 if (*secp == NULL 3010 || ! bfd_set_section_flags (abfd, *secp, SEC_IS_COMMON)) 3011 return FALSE; 3012 3013 *valp = sym->st_size; 3014 } 3015 3016 return TRUE; 3017 } 3018 3019 3020 #define TARGET_BIG_SYM bfd_elf32_microblaze_vec 3021 #define TARGET_BIG_NAME "elf32-microblaze" 3022 3023 #define ELF_ARCH bfd_arch_microblaze 3024 #define ELF_TARGET_ID MICROBLAZE_ELF_DATA 3025 #define ELF_MACHINE_CODE EM_MICROBLAZE 3026 #define ELF_MACHINE_ALT1 EM_MICROBLAZE_OLD 3027 #define ELF_MAXPAGESIZE 0x4 /* 4k, if we ever have 'em. */ 3028 #define elf_info_to_howto microblaze_elf_info_to_howto 3029 #define elf_info_to_howto_rel NULL 3030 3031 #define bfd_elf32_bfd_reloc_type_lookup microblaze_elf_reloc_type_lookup 3032 #define bfd_elf32_bfd_is_local_label_name microblaze_elf_is_local_label_name 3033 #define elf_backend_relocate_section microblaze_elf_relocate_section 3034 #define bfd_elf32_bfd_relax_section microblaze_elf_relax_section 3035 #define bfd_elf32_bfd_reloc_name_lookup microblaze_elf_reloc_name_lookup 3036 3037 #define elf_backend_gc_mark_hook microblaze_elf_gc_mark_hook 3038 #define elf_backend_gc_sweep_hook microblaze_elf_gc_sweep_hook 3039 #define elf_backend_check_relocs microblaze_elf_check_relocs 3040 #define elf_backend_copy_indirect_symbol microblaze_elf_copy_indirect_symbol 3041 #define bfd_elf32_bfd_link_hash_table_create microblaze_elf_link_hash_table_create 3042 #define elf_backend_can_gc_sections 1 3043 #define elf_backend_can_refcount 1 3044 #define elf_backend_want_got_plt 1 3045 #define elf_backend_plt_readonly 1 3046 #define elf_backend_got_header_size 12 3047 #define elf_backend_rela_normal 1 3048 3049 #define elf_backend_adjust_dynamic_symbol microblaze_elf_adjust_dynamic_symbol 3050 #define elf_backend_create_dynamic_sections microblaze_elf_create_dynamic_sections 3051 #define elf_backend_finish_dynamic_sections microblaze_elf_finish_dynamic_sections 3052 #define elf_backend_finish_dynamic_symbol microblaze_elf_finish_dynamic_symbol 3053 #define elf_backend_size_dynamic_sections microblaze_elf_size_dynamic_sections 3054 #define elf_backend_add_symbol_hook microblaze_elf_add_symbol_hook 3055 3056 #include "elf32-target.h" 3057