1 /* 32-bit ELF support for ARM new abi option. 2 Copyright 1999, 2000, 2001, 2002 Free Software Foundation, Inc. 3 4 This file is part of BFD, the Binary File Descriptor library. 5 6 This program is free software; you can redistribute it and/or modify 7 it under the terms of the GNU General Public License as published by 8 the Free Software Foundation; either version 2 of the License, or 9 (at your option) any later version. 10 11 This program is distributed in the hope that it will be useful, 12 but WITHOUT ANY WARRANTY; without even the implied warranty of 13 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 14 GNU General Public License for more details. 15 16 You should have received a copy of the GNU General Public License 17 along with this program; if not, write to the Free Software 18 Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */ 19 20 #include "elf/arm.h" 21 #include "bfd.h" 22 #include "sysdep.h" 23 #include "libbfd.h" 24 #include "elf-bfd.h" 25 26 #ifndef NUM_ELEM 27 #define NUM_ELEM(a) (sizeof (a) / (sizeof (a)[0])) 28 #endif 29 30 #define USE_REL 1 31 32 #define TARGET_LITTLE_SYM bfd_elf32_littlearm_vec 33 #define TARGET_LITTLE_NAME "elf32-littlearm" 34 #define TARGET_BIG_SYM bfd_elf32_bigarm_vec 35 #define TARGET_BIG_NAME "elf32-bigarm" 36 37 #define elf_info_to_howto 0 38 #define elf_info_to_howto_rel elf32_arm_info_to_howto 39 40 #define ARM_ELF_ABI_VERSION 0 41 #define ARM_ELF_OS_ABI_VERSION ELFOSABI_ARM 42 43 static reloc_howto_type * elf32_arm_reloc_type_lookup 44 PARAMS ((bfd * abfd, bfd_reloc_code_real_type code)); 45 static bfd_boolean elf32_arm_nabi_grok_prstatus 46 PARAMS ((bfd *abfd, Elf_Internal_Note *note)); 47 static bfd_boolean elf32_arm_nabi_grok_psinfo 48 PARAMS ((bfd *abfd, Elf_Internal_Note *note)); 49 50 /* Note: code such as elf32_arm_reloc_type_lookup expect to use e.g. 51 R_ARM_PC24 as an index into this, and find the R_ARM_PC24 HOWTO 52 in that slot. */ 53 54 static reloc_howto_type elf32_arm_howto_table[] = 55 { 56 /* No relocation */ 57 HOWTO (R_ARM_NONE, /* type */ 58 0, /* rightshift */ 59 0, /* size (0 = byte, 1 = short, 2 = long) */ 60 0, /* bitsize */ 61 FALSE, /* pc_relative */ 62 0, /* bitpos */ 63 complain_overflow_dont,/* complain_on_overflow */ 64 bfd_elf_generic_reloc, /* special_function */ 65 "R_ARM_NONE", /* name */ 66 FALSE, /* partial_inplace */ 67 0, /* src_mask */ 68 0, /* dst_mask */ 69 FALSE), /* pcrel_offset */ 70 71 HOWTO (R_ARM_PC24, /* type */ 72 2, /* rightshift */ 73 2, /* size (0 = byte, 1 = short, 2 = long) */ 74 24, /* bitsize */ 75 TRUE, /* pc_relative */ 76 0, /* bitpos */ 77 complain_overflow_signed,/* complain_on_overflow */ 78 bfd_elf_generic_reloc, /* special_function */ 79 "R_ARM_PC24", /* name */ 80 FALSE, /* partial_inplace */ 81 0x00ffffff, /* src_mask */ 82 0x00ffffff, /* dst_mask */ 83 TRUE), /* pcrel_offset */ 84 85 /* 32 bit absolute */ 86 HOWTO (R_ARM_ABS32, /* type */ 87 0, /* rightshift */ 88 2, /* size (0 = byte, 1 = short, 2 = long) */ 89 32, /* bitsize */ 90 FALSE, /* pc_relative */ 91 0, /* bitpos */ 92 complain_overflow_bitfield,/* complain_on_overflow */ 93 bfd_elf_generic_reloc, /* special_function */ 94 "R_ARM_ABS32", /* name */ 95 FALSE, /* partial_inplace */ 96 0xffffffff, /* src_mask */ 97 0xffffffff, /* dst_mask */ 98 FALSE), /* pcrel_offset */ 99 100 /* standard 32bit pc-relative reloc */ 101 HOWTO (R_ARM_REL32, /* type */ 102 0, /* rightshift */ 103 2, /* size (0 = byte, 1 = short, 2 = long) */ 104 32, /* bitsize */ 105 TRUE, /* pc_relative */ 106 0, /* bitpos */ 107 complain_overflow_bitfield,/* complain_on_overflow */ 108 bfd_elf_generic_reloc, /* special_function */ 109 "R_ARM_REL32", /* name */ 110 FALSE, /* partial_inplace */ 111 0xffffffff, /* src_mask */ 112 0xffffffff, /* dst_mask */ 113 TRUE), /* pcrel_offset */ 114 115 /* 8 bit absolute */ 116 HOWTO (R_ARM_PC13, /* type */ 117 0, /* rightshift */ 118 0, /* size (0 = byte, 1 = short, 2 = long) */ 119 8, /* bitsize */ 120 FALSE, /* pc_relative */ 121 0, /* bitpos */ 122 complain_overflow_bitfield,/* complain_on_overflow */ 123 bfd_elf_generic_reloc, /* special_function */ 124 "R_ARM_PC13", /* name */ 125 FALSE, /* partial_inplace */ 126 0x000000ff, /* src_mask */ 127 0x000000ff, /* dst_mask */ 128 FALSE), /* pcrel_offset */ 129 130 /* 16 bit absolute */ 131 HOWTO (R_ARM_ABS16, /* type */ 132 0, /* rightshift */ 133 1, /* size (0 = byte, 1 = short, 2 = long) */ 134 16, /* bitsize */ 135 FALSE, /* pc_relative */ 136 0, /* bitpos */ 137 complain_overflow_bitfield,/* complain_on_overflow */ 138 bfd_elf_generic_reloc, /* special_function */ 139 "R_ARM_ABS16", /* name */ 140 FALSE, /* partial_inplace */ 141 0x0000ffff, /* src_mask */ 142 0x0000ffff, /* dst_mask */ 143 FALSE), /* pcrel_offset */ 144 145 /* 12 bit absolute */ 146 HOWTO (R_ARM_ABS12, /* type */ 147 0, /* rightshift */ 148 2, /* size (0 = byte, 1 = short, 2 = long) */ 149 12, /* bitsize */ 150 FALSE, /* pc_relative */ 151 0, /* bitpos */ 152 complain_overflow_bitfield,/* complain_on_overflow */ 153 bfd_elf_generic_reloc, /* special_function */ 154 "R_ARM_ABS12", /* name */ 155 FALSE, /* partial_inplace */ 156 0x000008ff, /* src_mask */ 157 0x000008ff, /* dst_mask */ 158 FALSE), /* pcrel_offset */ 159 160 HOWTO (R_ARM_THM_ABS5, /* type */ 161 6, /* rightshift */ 162 1, /* size (0 = byte, 1 = short, 2 = long) */ 163 5, /* bitsize */ 164 FALSE, /* pc_relative */ 165 0, /* bitpos */ 166 complain_overflow_bitfield,/* complain_on_overflow */ 167 bfd_elf_generic_reloc, /* special_function */ 168 "R_ARM_THM_ABS5", /* name */ 169 FALSE, /* partial_inplace */ 170 0x000007e0, /* src_mask */ 171 0x000007e0, /* dst_mask */ 172 FALSE), /* pcrel_offset */ 173 174 /* 8 bit absolute */ 175 HOWTO (R_ARM_ABS8, /* type */ 176 0, /* rightshift */ 177 0, /* size (0 = byte, 1 = short, 2 = long) */ 178 8, /* bitsize */ 179 FALSE, /* pc_relative */ 180 0, /* bitpos */ 181 complain_overflow_bitfield,/* complain_on_overflow */ 182 bfd_elf_generic_reloc, /* special_function */ 183 "R_ARM_ABS8", /* name */ 184 FALSE, /* partial_inplace */ 185 0x000000ff, /* src_mask */ 186 0x000000ff, /* dst_mask */ 187 FALSE), /* pcrel_offset */ 188 189 HOWTO (R_ARM_SBREL32, /* type */ 190 0, /* rightshift */ 191 0, /* size (0 = byte, 1 = short, 2 = long) */ 192 0, /* bitsize */ 193 FALSE, /* pc_relative */ 194 0, /* bitpos */ 195 complain_overflow_dont,/* complain_on_overflow */ 196 bfd_elf_generic_reloc, /* special_function */ 197 "R_ARM_SBREL32", /* name */ 198 FALSE, /* partial_inplace */ 199 0, /* src_mask */ 200 0, /* dst_mask */ 201 FALSE), /* pcrel_offset */ 202 203 HOWTO (R_ARM_THM_PC22, /* type */ 204 1, /* rightshift */ 205 2, /* size (0 = byte, 1 = short, 2 = long) */ 206 23, /* bitsize */ 207 TRUE, /* pc_relative */ 208 0, /* bitpos */ 209 complain_overflow_signed,/* complain_on_overflow */ 210 bfd_elf_generic_reloc, /* special_function */ 211 "R_ARM_THM_PC22", /* name */ 212 FALSE, /* partial_inplace */ 213 0x07ff07ff, /* src_mask */ 214 0x07ff07ff, /* dst_mask */ 215 TRUE), /* pcrel_offset */ 216 217 HOWTO (R_ARM_THM_PC8, /* type */ 218 1, /* rightshift */ 219 1, /* size (0 = byte, 1 = short, 2 = long) */ 220 8, /* bitsize */ 221 TRUE, /* pc_relative */ 222 0, /* bitpos */ 223 complain_overflow_signed,/* complain_on_overflow */ 224 bfd_elf_generic_reloc, /* special_function */ 225 "R_ARM_THM_PC8", /* name */ 226 FALSE, /* partial_inplace */ 227 0x000000ff, /* src_mask */ 228 0x000000ff, /* dst_mask */ 229 TRUE), /* pcrel_offset */ 230 231 HOWTO (R_ARM_AMP_VCALL9, /* type */ 232 1, /* rightshift */ 233 1, /* size (0 = byte, 1 = short, 2 = long) */ 234 8, /* bitsize */ 235 TRUE, /* pc_relative */ 236 0, /* bitpos */ 237 complain_overflow_signed,/* complain_on_overflow */ 238 bfd_elf_generic_reloc, /* special_function */ 239 "R_ARM_AMP_VCALL9", /* name */ 240 FALSE, /* partial_inplace */ 241 0x000000ff, /* src_mask */ 242 0x000000ff, /* dst_mask */ 243 TRUE), /* pcrel_offset */ 244 245 HOWTO (R_ARM_SWI24, /* type */ 246 0, /* rightshift */ 247 0, /* size (0 = byte, 1 = short, 2 = long) */ 248 0, /* bitsize */ 249 FALSE, /* pc_relative */ 250 0, /* bitpos */ 251 complain_overflow_signed,/* complain_on_overflow */ 252 bfd_elf_generic_reloc, /* special_function */ 253 "R_ARM_SWI24", /* name */ 254 FALSE, /* partial_inplace */ 255 0x00000000, /* src_mask */ 256 0x00000000, /* dst_mask */ 257 FALSE), /* pcrel_offset */ 258 259 HOWTO (R_ARM_THM_SWI8, /* type */ 260 0, /* rightshift */ 261 0, /* size (0 = byte, 1 = short, 2 = long) */ 262 0, /* bitsize */ 263 FALSE, /* pc_relative */ 264 0, /* bitpos */ 265 complain_overflow_signed,/* complain_on_overflow */ 266 bfd_elf_generic_reloc, /* special_function */ 267 "R_ARM_SWI8", /* name */ 268 FALSE, /* partial_inplace */ 269 0x00000000, /* src_mask */ 270 0x00000000, /* dst_mask */ 271 FALSE), /* pcrel_offset */ 272 273 /* BLX instruction for the ARM. */ 274 HOWTO (R_ARM_XPC25, /* type */ 275 2, /* rightshift */ 276 2, /* size (0 = byte, 1 = short, 2 = long) */ 277 25, /* bitsize */ 278 TRUE, /* pc_relative */ 279 0, /* bitpos */ 280 complain_overflow_signed,/* complain_on_overflow */ 281 bfd_elf_generic_reloc, /* special_function */ 282 "R_ARM_XPC25", /* name */ 283 FALSE, /* partial_inplace */ 284 0x00ffffff, /* src_mask */ 285 0x00ffffff, /* dst_mask */ 286 TRUE), /* pcrel_offset */ 287 288 /* BLX instruction for the Thumb. */ 289 HOWTO (R_ARM_THM_XPC22, /* type */ 290 2, /* rightshift */ 291 2, /* size (0 = byte, 1 = short, 2 = long) */ 292 22, /* bitsize */ 293 TRUE, /* pc_relative */ 294 0, /* bitpos */ 295 complain_overflow_signed,/* complain_on_overflow */ 296 bfd_elf_generic_reloc, /* special_function */ 297 "R_ARM_THM_XPC22", /* name */ 298 FALSE, /* partial_inplace */ 299 0x07ff07ff, /* src_mask */ 300 0x07ff07ff, /* dst_mask */ 301 TRUE), /* pcrel_offset */ 302 303 /* These next three relocs are not defined, but we need to fill the space. */ 304 305 HOWTO (R_ARM_NONE, /* type */ 306 0, /* rightshift */ 307 0, /* size (0 = byte, 1 = short, 2 = long) */ 308 0, /* bitsize */ 309 FALSE, /* pc_relative */ 310 0, /* bitpos */ 311 complain_overflow_dont,/* complain_on_overflow */ 312 bfd_elf_generic_reloc, /* special_function */ 313 "R_ARM_unknown_17", /* name */ 314 FALSE, /* partial_inplace */ 315 0, /* src_mask */ 316 0, /* dst_mask */ 317 FALSE), /* pcrel_offset */ 318 319 HOWTO (R_ARM_NONE, /* type */ 320 0, /* rightshift */ 321 0, /* size (0 = byte, 1 = short, 2 = long) */ 322 0, /* bitsize */ 323 FALSE, /* pc_relative */ 324 0, /* bitpos */ 325 complain_overflow_dont,/* complain_on_overflow */ 326 bfd_elf_generic_reloc, /* special_function */ 327 "R_ARM_unknown_18", /* name */ 328 FALSE, /* partial_inplace */ 329 0, /* src_mask */ 330 0, /* dst_mask */ 331 FALSE), /* pcrel_offset */ 332 333 HOWTO (R_ARM_NONE, /* type */ 334 0, /* rightshift */ 335 0, /* size (0 = byte, 1 = short, 2 = long) */ 336 0, /* bitsize */ 337 FALSE, /* pc_relative */ 338 0, /* bitpos */ 339 complain_overflow_dont,/* complain_on_overflow */ 340 bfd_elf_generic_reloc, /* special_function */ 341 "R_ARM_unknown_19", /* name */ 342 FALSE, /* partial_inplace */ 343 0, /* src_mask */ 344 0, /* dst_mask */ 345 FALSE), /* pcrel_offset */ 346 347 /* Relocs used in ARM Linux */ 348 349 HOWTO (R_ARM_COPY, /* type */ 350 0, /* rightshift */ 351 2, /* size (0 = byte, 1 = short, 2 = long) */ 352 32, /* bitsize */ 353 FALSE, /* pc_relative */ 354 0, /* bitpos */ 355 complain_overflow_bitfield,/* complain_on_overflow */ 356 bfd_elf_generic_reloc, /* special_function */ 357 "R_ARM_COPY", /* name */ 358 TRUE, /* partial_inplace */ 359 0xffffffff, /* src_mask */ 360 0xffffffff, /* dst_mask */ 361 FALSE), /* pcrel_offset */ 362 363 HOWTO (R_ARM_GLOB_DAT, /* type */ 364 0, /* rightshift */ 365 2, /* size (0 = byte, 1 = short, 2 = long) */ 366 32, /* bitsize */ 367 FALSE, /* pc_relative */ 368 0, /* bitpos */ 369 complain_overflow_bitfield,/* complain_on_overflow */ 370 bfd_elf_generic_reloc, /* special_function */ 371 "R_ARM_GLOB_DAT", /* name */ 372 TRUE, /* partial_inplace */ 373 0xffffffff, /* src_mask */ 374 0xffffffff, /* dst_mask */ 375 FALSE), /* pcrel_offset */ 376 377 HOWTO (R_ARM_JUMP_SLOT, /* type */ 378 0, /* rightshift */ 379 2, /* size (0 = byte, 1 = short, 2 = long) */ 380 32, /* bitsize */ 381 FALSE, /* pc_relative */ 382 0, /* bitpos */ 383 complain_overflow_bitfield,/* complain_on_overflow */ 384 bfd_elf_generic_reloc, /* special_function */ 385 "R_ARM_JUMP_SLOT", /* name */ 386 TRUE, /* partial_inplace */ 387 0xffffffff, /* src_mask */ 388 0xffffffff, /* dst_mask */ 389 FALSE), /* pcrel_offset */ 390 391 HOWTO (R_ARM_RELATIVE, /* type */ 392 0, /* rightshift */ 393 2, /* size (0 = byte, 1 = short, 2 = long) */ 394 32, /* bitsize */ 395 FALSE, /* pc_relative */ 396 0, /* bitpos */ 397 complain_overflow_bitfield,/* complain_on_overflow */ 398 bfd_elf_generic_reloc, /* special_function */ 399 "R_ARM_RELATIVE", /* name */ 400 TRUE, /* partial_inplace */ 401 0xffffffff, /* src_mask */ 402 0xffffffff, /* dst_mask */ 403 FALSE), /* pcrel_offset */ 404 405 HOWTO (R_ARM_GOTOFF, /* type */ 406 0, /* rightshift */ 407 2, /* size (0 = byte, 1 = short, 2 = long) */ 408 32, /* bitsize */ 409 FALSE, /* pc_relative */ 410 0, /* bitpos */ 411 complain_overflow_bitfield,/* complain_on_overflow */ 412 bfd_elf_generic_reloc, /* special_function */ 413 "R_ARM_GOTOFF", /* name */ 414 TRUE, /* partial_inplace */ 415 0xffffffff, /* src_mask */ 416 0xffffffff, /* dst_mask */ 417 FALSE), /* pcrel_offset */ 418 419 HOWTO (R_ARM_GOTPC, /* type */ 420 0, /* rightshift */ 421 2, /* size (0 = byte, 1 = short, 2 = long) */ 422 32, /* bitsize */ 423 TRUE, /* pc_relative */ 424 0, /* bitpos */ 425 complain_overflow_bitfield,/* complain_on_overflow */ 426 bfd_elf_generic_reloc, /* special_function */ 427 "R_ARM_GOTPC", /* name */ 428 TRUE, /* partial_inplace */ 429 0xffffffff, /* src_mask */ 430 0xffffffff, /* dst_mask */ 431 TRUE), /* pcrel_offset */ 432 433 HOWTO (R_ARM_GOT32, /* type */ 434 0, /* rightshift */ 435 2, /* size (0 = byte, 1 = short, 2 = long) */ 436 32, /* bitsize */ 437 FALSE, /* pc_relative */ 438 0, /* bitpos */ 439 complain_overflow_bitfield,/* complain_on_overflow */ 440 bfd_elf_generic_reloc, /* special_function */ 441 "R_ARM_GOT32", /* name */ 442 TRUE, /* partial_inplace */ 443 0xffffffff, /* src_mask */ 444 0xffffffff, /* dst_mask */ 445 FALSE), /* pcrel_offset */ 446 447 HOWTO (R_ARM_PLT32, /* type */ 448 2, /* rightshift */ 449 2, /* size (0 = byte, 1 = short, 2 = long) */ 450 26, /* bitsize */ 451 TRUE, /* pc_relative */ 452 0, /* bitpos */ 453 complain_overflow_bitfield,/* complain_on_overflow */ 454 bfd_elf_generic_reloc, /* special_function */ 455 "R_ARM_PLT32", /* name */ 456 TRUE, /* partial_inplace */ 457 0x00ffffff, /* src_mask */ 458 0x00ffffff, /* dst_mask */ 459 TRUE), /* pcrel_offset */ 460 461 /* End of relocs used in ARM Linux */ 462 463 HOWTO (R_ARM_RREL32, /* type */ 464 0, /* rightshift */ 465 0, /* size (0 = byte, 1 = short, 2 = long) */ 466 0, /* bitsize */ 467 FALSE, /* pc_relative */ 468 0, /* bitpos */ 469 complain_overflow_dont,/* complain_on_overflow */ 470 bfd_elf_generic_reloc, /* special_function */ 471 "R_ARM_RREL32", /* name */ 472 FALSE, /* partial_inplace */ 473 0, /* src_mask */ 474 0, /* dst_mask */ 475 FALSE), /* pcrel_offset */ 476 477 HOWTO (R_ARM_RABS32, /* type */ 478 0, /* rightshift */ 479 0, /* size (0 = byte, 1 = short, 2 = long) */ 480 0, /* bitsize */ 481 FALSE, /* pc_relative */ 482 0, /* bitpos */ 483 complain_overflow_dont,/* complain_on_overflow */ 484 bfd_elf_generic_reloc, /* special_function */ 485 "R_ARM_RABS32", /* name */ 486 FALSE, /* partial_inplace */ 487 0, /* src_mask */ 488 0, /* dst_mask */ 489 FALSE), /* pcrel_offset */ 490 491 HOWTO (R_ARM_RPC24, /* type */ 492 0, /* rightshift */ 493 0, /* size (0 = byte, 1 = short, 2 = long) */ 494 0, /* bitsize */ 495 FALSE, /* pc_relative */ 496 0, /* bitpos */ 497 complain_overflow_dont,/* complain_on_overflow */ 498 bfd_elf_generic_reloc, /* special_function */ 499 "R_ARM_RPC24", /* name */ 500 FALSE, /* partial_inplace */ 501 0, /* src_mask */ 502 0, /* dst_mask */ 503 FALSE), /* pcrel_offset */ 504 505 HOWTO (R_ARM_RBASE, /* type */ 506 0, /* rightshift */ 507 0, /* size (0 = byte, 1 = short, 2 = long) */ 508 0, /* bitsize */ 509 FALSE, /* pc_relative */ 510 0, /* bitpos */ 511 complain_overflow_dont,/* complain_on_overflow */ 512 bfd_elf_generic_reloc, /* special_function */ 513 "R_ARM_RBASE", /* name */ 514 FALSE, /* partial_inplace */ 515 0, /* src_mask */ 516 0, /* dst_mask */ 517 FALSE), /* pcrel_offset */ 518 519 }; 520 521 /* GNU extension to record C++ vtable hierarchy */ 522 static reloc_howto_type elf32_arm_vtinherit_howto = 523 HOWTO (R_ARM_GNU_VTINHERIT, /* type */ 524 0, /* rightshift */ 525 2, /* size (0 = byte, 1 = short, 2 = long) */ 526 0, /* bitsize */ 527 FALSE, /* pc_relative */ 528 0, /* bitpos */ 529 complain_overflow_dont, /* complain_on_overflow */ 530 NULL, /* special_function */ 531 "R_ARM_GNU_VTINHERIT", /* name */ 532 FALSE, /* partial_inplace */ 533 0, /* src_mask */ 534 0, /* dst_mask */ 535 FALSE); /* pcrel_offset */ 536 537 /* GNU extension to record C++ vtable member usage */ 538 static reloc_howto_type elf32_arm_vtentry_howto = 539 HOWTO (R_ARM_GNU_VTENTRY, /* type */ 540 0, /* rightshift */ 541 2, /* size (0 = byte, 1 = short, 2 = long) */ 542 0, /* bitsize */ 543 FALSE, /* pc_relative */ 544 0, /* bitpos */ 545 complain_overflow_dont, /* complain_on_overflow */ 546 _bfd_elf_rel_vtable_reloc_fn, /* special_function */ 547 "R_ARM_GNU_VTENTRY", /* name */ 548 FALSE, /* partial_inplace */ 549 0, /* src_mask */ 550 0, /* dst_mask */ 551 FALSE); /* pcrel_offset */ 552 553 /* 12 bit pc relative */ 554 static reloc_howto_type elf32_arm_thm_pc11_howto = 555 HOWTO (R_ARM_THM_PC11, /* type */ 556 1, /* rightshift */ 557 1, /* size (0 = byte, 1 = short, 2 = long) */ 558 11, /* bitsize */ 559 TRUE, /* pc_relative */ 560 0, /* bitpos */ 561 complain_overflow_signed, /* complain_on_overflow */ 562 bfd_elf_generic_reloc, /* special_function */ 563 "R_ARM_THM_PC11", /* name */ 564 FALSE, /* partial_inplace */ 565 0x000007ff, /* src_mask */ 566 0x000007ff, /* dst_mask */ 567 TRUE); /* pcrel_offset */ 568 569 /* 12 bit pc relative */ 570 static reloc_howto_type elf32_arm_thm_pc9_howto = 571 HOWTO (R_ARM_THM_PC9, /* type */ 572 1, /* rightshift */ 573 1, /* size (0 = byte, 1 = short, 2 = long) */ 574 8, /* bitsize */ 575 TRUE, /* pc_relative */ 576 0, /* bitpos */ 577 complain_overflow_signed, /* complain_on_overflow */ 578 bfd_elf_generic_reloc, /* special_function */ 579 "R_ARM_THM_PC9", /* name */ 580 FALSE, /* partial_inplace */ 581 0x000000ff, /* src_mask */ 582 0x000000ff, /* dst_mask */ 583 TRUE); /* pcrel_offset */ 584 585 static void elf32_arm_info_to_howto 586 PARAMS ((bfd *, arelent *, Elf_Internal_Rela *)); 587 588 static void 589 elf32_arm_info_to_howto (abfd, bfd_reloc, elf_reloc) 590 bfd * abfd ATTRIBUTE_UNUSED; 591 arelent * bfd_reloc; 592 Elf_Internal_Rela * elf_reloc; 593 { 594 unsigned int r_type; 595 596 r_type = ELF32_R_TYPE (elf_reloc->r_info); 597 598 switch (r_type) 599 { 600 case R_ARM_GNU_VTINHERIT: 601 bfd_reloc->howto = & elf32_arm_vtinherit_howto; 602 break; 603 604 case R_ARM_GNU_VTENTRY: 605 bfd_reloc->howto = & elf32_arm_vtentry_howto; 606 break; 607 608 case R_ARM_THM_PC11: 609 bfd_reloc->howto = & elf32_arm_thm_pc11_howto; 610 break; 611 612 case R_ARM_THM_PC9: 613 bfd_reloc->howto = & elf32_arm_thm_pc9_howto; 614 break; 615 616 default: 617 if (r_type >= NUM_ELEM (elf32_arm_howto_table)) 618 bfd_reloc->howto = NULL; 619 else 620 bfd_reloc->howto = & elf32_arm_howto_table[r_type]; 621 break; 622 } 623 } 624 625 struct elf32_arm_reloc_map 626 { 627 bfd_reloc_code_real_type bfd_reloc_val; 628 unsigned char elf_reloc_val; 629 }; 630 631 static const struct elf32_arm_reloc_map elf32_arm_reloc_map[] = 632 { 633 {BFD_RELOC_NONE, R_ARM_NONE}, 634 {BFD_RELOC_ARM_PCREL_BRANCH, R_ARM_PC24}, 635 {BFD_RELOC_ARM_PCREL_BLX, R_ARM_XPC25}, 636 {BFD_RELOC_THUMB_PCREL_BLX, R_ARM_THM_XPC22}, 637 {BFD_RELOC_32, R_ARM_ABS32}, 638 {BFD_RELOC_32_PCREL, R_ARM_REL32}, 639 {BFD_RELOC_8, R_ARM_ABS8}, 640 {BFD_RELOC_16, R_ARM_ABS16}, 641 {BFD_RELOC_ARM_OFFSET_IMM, R_ARM_ABS12}, 642 {BFD_RELOC_ARM_THUMB_OFFSET, R_ARM_THM_ABS5}, 643 {BFD_RELOC_THUMB_PCREL_BRANCH23, R_ARM_THM_PC22}, 644 {BFD_RELOC_ARM_COPY, R_ARM_COPY}, 645 {BFD_RELOC_ARM_GLOB_DAT, R_ARM_GLOB_DAT}, 646 {BFD_RELOC_ARM_JUMP_SLOT, R_ARM_JUMP_SLOT}, 647 {BFD_RELOC_ARM_RELATIVE, R_ARM_RELATIVE}, 648 {BFD_RELOC_ARM_GOTOFF, R_ARM_GOTOFF}, 649 {BFD_RELOC_ARM_GOTPC, R_ARM_GOTPC}, 650 {BFD_RELOC_ARM_GOT32, R_ARM_GOT32}, 651 {BFD_RELOC_ARM_PLT32, R_ARM_PLT32} 652 }; 653 654 static reloc_howto_type * 655 elf32_arm_reloc_type_lookup (abfd, code) 656 bfd *abfd ATTRIBUTE_UNUSED; 657 bfd_reloc_code_real_type code; 658 { 659 unsigned int i; 660 661 switch (code) 662 { 663 case BFD_RELOC_VTABLE_INHERIT: 664 return & elf32_arm_vtinherit_howto; 665 666 case BFD_RELOC_VTABLE_ENTRY: 667 return & elf32_arm_vtentry_howto; 668 669 case BFD_RELOC_THUMB_PCREL_BRANCH12: 670 return & elf32_arm_thm_pc11_howto; 671 672 case BFD_RELOC_THUMB_PCREL_BRANCH9: 673 return & elf32_arm_thm_pc9_howto; 674 675 default: 676 for (i = 0; i < NUM_ELEM (elf32_arm_reloc_map); i ++) 677 if (elf32_arm_reloc_map[i].bfd_reloc_val == code) 678 return & elf32_arm_howto_table[elf32_arm_reloc_map[i].elf_reloc_val]; 679 680 return NULL; 681 } 682 } 683 684 /* Support for core dump NOTE sections */ 685 static bfd_boolean 686 elf32_arm_nabi_grok_prstatus (abfd, note) 687 bfd *abfd; 688 Elf_Internal_Note *note; 689 { 690 int offset; 691 size_t raw_size; 692 693 switch (note->descsz) 694 { 695 default: 696 return FALSE; 697 698 case 148: /* Linux/ARM 32-bit*/ 699 /* pr_cursig */ 700 elf_tdata (abfd)->core_signal = bfd_get_16 (abfd, note->descdata + 12); 701 702 /* pr_pid */ 703 elf_tdata (abfd)->core_pid = bfd_get_32 (abfd, note->descdata + 24); 704 705 /* pr_reg */ 706 offset = 72; 707 raw_size = 72; 708 709 break; 710 } 711 712 /* Make a ".reg/999" section. */ 713 return _bfd_elfcore_make_pseudosection (abfd, ".reg", 714 raw_size, note->descpos + offset); 715 } 716 717 static bfd_boolean 718 elf32_arm_nabi_grok_psinfo (abfd, note) 719 bfd *abfd; 720 Elf_Internal_Note *note; 721 { 722 switch (note->descsz) 723 { 724 default: 725 return FALSE; 726 727 case 124: /* Linux/ARM elf_prpsinfo */ 728 elf_tdata (abfd)->core_program 729 = _bfd_elfcore_strndup (abfd, note->descdata + 28, 16); 730 elf_tdata (abfd)->core_command 731 = _bfd_elfcore_strndup (abfd, note->descdata + 44, 80); 732 } 733 734 /* Note that for some reason, a spurious space is tacked 735 onto the end of the args in some (at least one anyway) 736 implementations, so strip it off if it exists. */ 737 738 { 739 char *command = elf_tdata (abfd)->core_command; 740 int n = strlen (command); 741 742 if (0 < n && command[n - 1] == ' ') 743 command[n - 1] = '\0'; 744 } 745 746 return TRUE; 747 } 748 749 #define elf_backend_grok_prstatus elf32_arm_nabi_grok_prstatus 750 #define elf_backend_grok_psinfo elf32_arm_nabi_grok_psinfo 751 752 #include "elf32-arm.h" 753