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