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