00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
00020 #include "elf/arm.h"
00021 #include "bfd.h"
00022 #include "sysdep.h"
00023 #include "libbfd.h"
00024 #include "elf-bfd.h"
00025
00026 #ifndef NUM_ELEM
00027 #define NUM_ELEM(a) (sizeof (a) / (sizeof (a)[0]))
00028 #endif
00029
00030 #define USE_REL 1
00031
00032 #define TARGET_LITTLE_SYM bfd_elf32_littlearm_vec
00033 #define TARGET_LITTLE_NAME "elf32-littlearm"
00034 #define TARGET_BIG_SYM bfd_elf32_bigarm_vec
00035 #define TARGET_BIG_NAME "elf32-bigarm"
00036
00037 #define elf_info_to_howto 0
00038 #define elf_info_to_howto_rel elf32_arm_info_to_howto
00039
00040 #define ARM_ELF_ABI_VERSION 0
00041 #define ARM_ELF_OS_ABI_VERSION ELFOSABI_ARM
00042
00043 static reloc_howto_type * elf32_arm_reloc_type_lookup
00044 PARAMS ((bfd * abfd, bfd_reloc_code_real_type code));
00045 static bfd_boolean elf32_arm_nabi_grok_prstatus
00046 PARAMS ((bfd *abfd, Elf_Internal_Note *note));
00047 static bfd_boolean elf32_arm_nabi_grok_psinfo
00048 PARAMS ((bfd *abfd, Elf_Internal_Note *note));
00049
00050
00051
00052
00053
00054 static reloc_howto_type elf32_arm_howto_table[] =
00055 {
00056
00057 HOWTO (R_ARM_NONE,
00058 0,
00059 0,
00060 0,
00061 FALSE,
00062 0,
00063 complain_overflow_dont,
00064 bfd_elf_generic_reloc,
00065 "R_ARM_NONE",
00066 FALSE,
00067 0,
00068 0,
00069 FALSE),
00070
00071 HOWTO (R_ARM_PC24,
00072 2,
00073 2,
00074 24,
00075 TRUE,
00076 0,
00077 complain_overflow_signed,
00078 bfd_elf_generic_reloc,
00079 "R_ARM_PC24",
00080 FALSE,
00081 0x00ffffff,
00082 0x00ffffff,
00083 TRUE),
00084
00085
00086 HOWTO (R_ARM_ABS32,
00087 0,
00088 2,
00089 32,
00090 FALSE,
00091 0,
00092 complain_overflow_bitfield,
00093 bfd_elf_generic_reloc,
00094 "R_ARM_ABS32",
00095 FALSE,
00096 0xffffffff,
00097 0xffffffff,
00098 FALSE),
00099
00100
00101 HOWTO (R_ARM_REL32,
00102 0,
00103 2,
00104 32,
00105 TRUE,
00106 0,
00107 complain_overflow_bitfield,
00108 bfd_elf_generic_reloc,
00109 "R_ARM_REL32",
00110 FALSE,
00111 0xffffffff,
00112 0xffffffff,
00113 TRUE),
00114
00115
00116 HOWTO (R_ARM_PC13,
00117 0,
00118 0,
00119 8,
00120 FALSE,
00121 0,
00122 complain_overflow_bitfield,
00123 bfd_elf_generic_reloc,
00124 "R_ARM_PC13",
00125 FALSE,
00126 0x000000ff,
00127 0x000000ff,
00128 FALSE),
00129
00130
00131 HOWTO (R_ARM_ABS16,
00132 0,
00133 1,
00134 16,
00135 FALSE,
00136 0,
00137 complain_overflow_bitfield,
00138 bfd_elf_generic_reloc,
00139 "R_ARM_ABS16",
00140 FALSE,
00141 0x0000ffff,
00142 0x0000ffff,
00143 FALSE),
00144
00145
00146 HOWTO (R_ARM_ABS12,
00147 0,
00148 2,
00149 12,
00150 FALSE,
00151 0,
00152 complain_overflow_bitfield,
00153 bfd_elf_generic_reloc,
00154 "R_ARM_ABS12",
00155 FALSE,
00156 0x000008ff,
00157 0x000008ff,
00158 FALSE),
00159
00160 HOWTO (R_ARM_THM_ABS5,
00161 6,
00162 1,
00163 5,
00164 FALSE,
00165 0,
00166 complain_overflow_bitfield,
00167 bfd_elf_generic_reloc,
00168 "R_ARM_THM_ABS5",
00169 FALSE,
00170 0x000007e0,
00171 0x000007e0,
00172 FALSE),
00173
00174
00175 HOWTO (R_ARM_ABS8,
00176 0,
00177 0,
00178 8,
00179 FALSE,
00180 0,
00181 complain_overflow_bitfield,
00182 bfd_elf_generic_reloc,
00183 "R_ARM_ABS8",
00184 FALSE,
00185 0x000000ff,
00186 0x000000ff,
00187 FALSE),
00188
00189 HOWTO (R_ARM_SBREL32,
00190 0,
00191 0,
00192 0,
00193 FALSE,
00194 0,
00195 complain_overflow_dont,
00196 bfd_elf_generic_reloc,
00197 "R_ARM_SBREL32",
00198 FALSE,
00199 0,
00200 0,
00201 FALSE),
00202
00203 HOWTO (R_ARM_THM_PC22,
00204 1,
00205 2,
00206 23,
00207 TRUE,
00208 0,
00209 complain_overflow_signed,
00210 bfd_elf_generic_reloc,
00211 "R_ARM_THM_PC22",
00212 FALSE,
00213 0x07ff07ff,
00214 0x07ff07ff,
00215 TRUE),
00216
00217 HOWTO (R_ARM_THM_PC8,
00218 1,
00219 1,
00220 8,
00221 TRUE,
00222 0,
00223 complain_overflow_signed,
00224 bfd_elf_generic_reloc,
00225 "R_ARM_THM_PC8",
00226 FALSE,
00227 0x000000ff,
00228 0x000000ff,
00229 TRUE),
00230
00231 HOWTO (R_ARM_AMP_VCALL9,
00232 1,
00233 1,
00234 8,
00235 TRUE,
00236 0,
00237 complain_overflow_signed,
00238 bfd_elf_generic_reloc,
00239 "R_ARM_AMP_VCALL9",
00240 FALSE,
00241 0x000000ff,
00242 0x000000ff,
00243 TRUE),
00244
00245 HOWTO (R_ARM_SWI24,
00246 0,
00247 0,
00248 0,
00249 FALSE,
00250 0,
00251 complain_overflow_signed,
00252 bfd_elf_generic_reloc,
00253 "R_ARM_SWI24",
00254 FALSE,
00255 0x00000000,
00256 0x00000000,
00257 FALSE),
00258
00259 HOWTO (R_ARM_THM_SWI8,
00260 0,
00261 0,
00262 0,
00263 FALSE,
00264 0,
00265 complain_overflow_signed,
00266 bfd_elf_generic_reloc,
00267 "R_ARM_SWI8",
00268 FALSE,
00269 0x00000000,
00270 0x00000000,
00271 FALSE),
00272
00273
00274 HOWTO (R_ARM_XPC25,
00275 2,
00276 2,
00277 25,
00278 TRUE,
00279 0,
00280 complain_overflow_signed,
00281 bfd_elf_generic_reloc,
00282 "R_ARM_XPC25",
00283 FALSE,
00284 0x00ffffff,
00285 0x00ffffff,
00286 TRUE),
00287
00288
00289 HOWTO (R_ARM_THM_XPC22,
00290 2,
00291 2,
00292 22,
00293 TRUE,
00294 0,
00295 complain_overflow_signed,
00296 bfd_elf_generic_reloc,
00297 "R_ARM_THM_XPC22",
00298 FALSE,
00299 0x07ff07ff,
00300 0x07ff07ff,
00301 TRUE),
00302
00303
00304
00305 HOWTO (R_ARM_NONE,
00306 0,
00307 0,
00308 0,
00309 FALSE,
00310 0,
00311 complain_overflow_dont,
00312 bfd_elf_generic_reloc,
00313 "R_ARM_unknown_17",
00314 FALSE,
00315 0,
00316 0,
00317 FALSE),
00318
00319 HOWTO (R_ARM_NONE,
00320 0,
00321 0,
00322 0,
00323 FALSE,
00324 0,
00325 complain_overflow_dont,
00326 bfd_elf_generic_reloc,
00327 "R_ARM_unknown_18",
00328 FALSE,
00329 0,
00330 0,
00331 FALSE),
00332
00333 HOWTO (R_ARM_NONE,
00334 0,
00335 0,
00336 0,
00337 FALSE,
00338 0,
00339 complain_overflow_dont,
00340 bfd_elf_generic_reloc,
00341 "R_ARM_unknown_19",
00342 FALSE,
00343 0,
00344 0,
00345 FALSE),
00346
00347
00348
00349 HOWTO (R_ARM_COPY,
00350 0,
00351 2,
00352 32,
00353 FALSE,
00354 0,
00355 complain_overflow_bitfield,
00356 bfd_elf_generic_reloc,
00357 "R_ARM_COPY",
00358 TRUE,
00359 0xffffffff,
00360 0xffffffff,
00361 FALSE),
00362
00363 HOWTO (R_ARM_GLOB_DAT,
00364 0,
00365 2,
00366 32,
00367 FALSE,
00368 0,
00369 complain_overflow_bitfield,
00370 bfd_elf_generic_reloc,
00371 "R_ARM_GLOB_DAT",
00372 TRUE,
00373 0xffffffff,
00374 0xffffffff,
00375 FALSE),
00376
00377 HOWTO (R_ARM_JUMP_SLOT,
00378 0,
00379 2,
00380 32,
00381 FALSE,
00382 0,
00383 complain_overflow_bitfield,
00384 bfd_elf_generic_reloc,
00385 "R_ARM_JUMP_SLOT",
00386 TRUE,
00387 0xffffffff,
00388 0xffffffff,
00389 FALSE),
00390
00391 HOWTO (R_ARM_RELATIVE,
00392 0,
00393 2,
00394 32,
00395 FALSE,
00396 0,
00397 complain_overflow_bitfield,
00398 bfd_elf_generic_reloc,
00399 "R_ARM_RELATIVE",
00400 TRUE,
00401 0xffffffff,
00402 0xffffffff,
00403 FALSE),
00404
00405 HOWTO (R_ARM_GOTOFF,
00406 0,
00407 2,
00408 32,
00409 FALSE,
00410 0,
00411 complain_overflow_bitfield,
00412 bfd_elf_generic_reloc,
00413 "R_ARM_GOTOFF",
00414 TRUE,
00415 0xffffffff,
00416 0xffffffff,
00417 FALSE),
00418
00419 HOWTO (R_ARM_GOTPC,
00420 0,
00421 2,
00422 32,
00423 TRUE,
00424 0,
00425 complain_overflow_bitfield,
00426 bfd_elf_generic_reloc,
00427 "R_ARM_GOTPC",
00428 TRUE,
00429 0xffffffff,
00430 0xffffffff,
00431 TRUE),
00432
00433 HOWTO (R_ARM_GOT32,
00434 0,
00435 2,
00436 32,
00437 FALSE,
00438 0,
00439 complain_overflow_bitfield,
00440 bfd_elf_generic_reloc,
00441 "R_ARM_GOT32",
00442 TRUE,
00443 0xffffffff,
00444 0xffffffff,
00445 FALSE),
00446
00447 HOWTO (R_ARM_PLT32,
00448 2,
00449 2,
00450 26,
00451 TRUE,
00452 0,
00453 complain_overflow_bitfield,
00454 bfd_elf_generic_reloc,
00455 "R_ARM_PLT32",
00456 TRUE,
00457 0x00ffffff,
00458 0x00ffffff,
00459 TRUE),
00460
00461
00462
00463 HOWTO (R_ARM_RREL32,
00464 0,
00465 0,
00466 0,
00467 FALSE,
00468 0,
00469 complain_overflow_dont,
00470 bfd_elf_generic_reloc,
00471 "R_ARM_RREL32",
00472 FALSE,
00473 0,
00474 0,
00475 FALSE),
00476
00477 HOWTO (R_ARM_RABS32,
00478 0,
00479 0,
00480 0,
00481 FALSE,
00482 0,
00483 complain_overflow_dont,
00484 bfd_elf_generic_reloc,
00485 "R_ARM_RABS32",
00486 FALSE,
00487 0,
00488 0,
00489 FALSE),
00490
00491 HOWTO (R_ARM_RPC24,
00492 0,
00493 0,
00494 0,
00495 FALSE,
00496 0,
00497 complain_overflow_dont,
00498 bfd_elf_generic_reloc,
00499 "R_ARM_RPC24",
00500 FALSE,
00501 0,
00502 0,
00503 FALSE),
00504
00505 HOWTO (R_ARM_RBASE,
00506 0,
00507 0,
00508 0,
00509 FALSE,
00510 0,
00511 complain_overflow_dont,
00512 bfd_elf_generic_reloc,
00513 "R_ARM_RBASE",
00514 FALSE,
00515 0,
00516 0,
00517 FALSE),
00518
00519 };
00520
00521
00522 static reloc_howto_type elf32_arm_vtinherit_howto =
00523 HOWTO (R_ARM_GNU_VTINHERIT,
00524 0,
00525 2,
00526 0,
00527 FALSE,
00528 0,
00529 complain_overflow_dont,
00530 NULL,
00531 "R_ARM_GNU_VTINHERIT",
00532 FALSE,
00533 0,
00534 0,
00535 FALSE);
00536
00537
00538 static reloc_howto_type elf32_arm_vtentry_howto =
00539 HOWTO (R_ARM_GNU_VTENTRY,
00540 0,
00541 2,
00542 0,
00543 FALSE,
00544 0,
00545 complain_overflow_dont,
00546 _bfd_elf_rel_vtable_reloc_fn,
00547 "R_ARM_GNU_VTENTRY",
00548 FALSE,
00549 0,
00550 0,
00551 FALSE);
00552
00553
00554 static reloc_howto_type elf32_arm_thm_pc11_howto =
00555 HOWTO (R_ARM_THM_PC11,
00556 1,
00557 1,
00558 11,
00559 TRUE,
00560 0,
00561 complain_overflow_signed,
00562 bfd_elf_generic_reloc,
00563 "R_ARM_THM_PC11",
00564 FALSE,
00565 0x000007ff,
00566 0x000007ff,
00567 TRUE);
00568
00569
00570 static reloc_howto_type elf32_arm_thm_pc9_howto =
00571 HOWTO (R_ARM_THM_PC9,
00572 1,
00573 1,
00574 8,
00575 TRUE,
00576 0,
00577 complain_overflow_signed,
00578 bfd_elf_generic_reloc,
00579 "R_ARM_THM_PC9",
00580 FALSE,
00581 0x000000ff,
00582 0x000000ff,
00583 TRUE);
00584
00585 static void elf32_arm_info_to_howto
00586 PARAMS ((bfd *, arelent *, Elf_Internal_Rela *));
00587
00588 static void
00589 elf32_arm_info_to_howto (abfd, bfd_reloc, elf_reloc)
00590 bfd * abfd ATTRIBUTE_UNUSED;
00591 arelent * bfd_reloc;
00592 Elf_Internal_Rela * elf_reloc;
00593 {
00594 unsigned int r_type;
00595
00596 r_type = ELF32_R_TYPE (elf_reloc->r_info);
00597
00598 switch (r_type)
00599 {
00600 case R_ARM_GNU_VTINHERIT:
00601 bfd_reloc->howto = & elf32_arm_vtinherit_howto;
00602 break;
00603
00604 case R_ARM_GNU_VTENTRY:
00605 bfd_reloc->howto = & elf32_arm_vtentry_howto;
00606 break;
00607
00608 case R_ARM_THM_PC11:
00609 bfd_reloc->howto = & elf32_arm_thm_pc11_howto;
00610 break;
00611
00612 case R_ARM_THM_PC9:
00613 bfd_reloc->howto = & elf32_arm_thm_pc9_howto;
00614 break;
00615
00616 default:
00617 if (r_type >= NUM_ELEM (elf32_arm_howto_table))
00618 bfd_reloc->howto = NULL;
00619 else
00620 bfd_reloc->howto = & elf32_arm_howto_table[r_type];
00621 break;
00622 }
00623 }
00624
00625 struct elf32_arm_reloc_map
00626 {
00627 bfd_reloc_code_real_type bfd_reloc_val;
00628 unsigned char elf_reloc_val;
00629 };
00630
00631 static const struct elf32_arm_reloc_map elf32_arm_reloc_map[] =
00632 {
00633 {BFD_RELOC_NONE, R_ARM_NONE},
00634 {BFD_RELOC_ARM_PCREL_BRANCH, R_ARM_PC24},
00635 {BFD_RELOC_ARM_PCREL_BLX, R_ARM_XPC25},
00636 {BFD_RELOC_THUMB_PCREL_BLX, R_ARM_THM_XPC22},
00637 {BFD_RELOC_32, R_ARM_ABS32},
00638 {BFD_RELOC_32_PCREL, R_ARM_REL32},
00639 {BFD_RELOC_8, R_ARM_ABS8},
00640 {BFD_RELOC_16, R_ARM_ABS16},
00641 {BFD_RELOC_ARM_OFFSET_IMM, R_ARM_ABS12},
00642 {BFD_RELOC_ARM_THUMB_OFFSET, R_ARM_THM_ABS5},
00643 {BFD_RELOC_THUMB_PCREL_BRANCH23, R_ARM_THM_PC22},
00644 {BFD_RELOC_ARM_COPY, R_ARM_COPY},
00645 {BFD_RELOC_ARM_GLOB_DAT, R_ARM_GLOB_DAT},
00646 {BFD_RELOC_ARM_JUMP_SLOT, R_ARM_JUMP_SLOT},
00647 {BFD_RELOC_ARM_RELATIVE, R_ARM_RELATIVE},
00648 {BFD_RELOC_ARM_GOTOFF, R_ARM_GOTOFF},
00649 {BFD_RELOC_ARM_GOTPC, R_ARM_GOTPC},
00650 {BFD_RELOC_ARM_GOT32, R_ARM_GOT32},
00651 {BFD_RELOC_ARM_PLT32, R_ARM_PLT32}
00652 };
00653
00654 static reloc_howto_type *
00655 elf32_arm_reloc_type_lookup (abfd, code)
00656 bfd *abfd ATTRIBUTE_UNUSED;
00657 bfd_reloc_code_real_type code;
00658 {
00659 unsigned int i;
00660
00661 switch (code)
00662 {
00663 case BFD_RELOC_VTABLE_INHERIT:
00664 return & elf32_arm_vtinherit_howto;
00665
00666 case BFD_RELOC_VTABLE_ENTRY:
00667 return & elf32_arm_vtentry_howto;
00668
00669 case BFD_RELOC_THUMB_PCREL_BRANCH12:
00670 return & elf32_arm_thm_pc11_howto;
00671
00672 case BFD_RELOC_THUMB_PCREL_BRANCH9:
00673 return & elf32_arm_thm_pc9_howto;
00674
00675 default:
00676 for (i = 0; i < NUM_ELEM (elf32_arm_reloc_map); i ++)
00677 if (elf32_arm_reloc_map[i].bfd_reloc_val == code)
00678 return & elf32_arm_howto_table[elf32_arm_reloc_map[i].elf_reloc_val];
00679
00680 return NULL;
00681 }
00682 }
00683
00684
00685 static bfd_boolean
00686 elf32_arm_nabi_grok_prstatus (abfd, note)
00687 bfd *abfd;
00688 Elf_Internal_Note *note;
00689 {
00690 int offset;
00691 size_t raw_size;
00692
00693 switch (note->descsz)
00694 {
00695 default:
00696 return FALSE;
00697
00698 case 148:
00699
00700 elf_tdata (abfd)->core_signal = bfd_get_16 (abfd, note->descdata + 12);
00701
00702
00703 elf_tdata (abfd)->core_pid = bfd_get_32 (abfd, note->descdata + 24);
00704
00705
00706 offset = 72;
00707 raw_size = 72;
00708
00709 break;
00710 }
00711
00712
00713 return _bfd_elfcore_make_pseudosection (abfd, ".reg",
00714 raw_size, note->descpos + offset);
00715 }
00716
00717 static bfd_boolean
00718 elf32_arm_nabi_grok_psinfo (abfd, note)
00719 bfd *abfd;
00720 Elf_Internal_Note *note;
00721 {
00722 switch (note->descsz)
00723 {
00724 default:
00725 return FALSE;
00726
00727 case 124:
00728 elf_tdata (abfd)->core_program
00729 = _bfd_elfcore_strndup (abfd, note->descdata + 28, 16);
00730 elf_tdata (abfd)->core_command
00731 = _bfd_elfcore_strndup (abfd, note->descdata + 44, 80);
00732 }
00733
00734
00735
00736
00737
00738 {
00739 char *command = elf_tdata (abfd)->core_command;
00740 int n = strlen (command);
00741
00742 if (0 < n && command[n - 1] == ' ')
00743 command[n - 1] = '\0';
00744 }
00745
00746 return TRUE;
00747 }
00748
00749 #define elf_backend_grok_prstatus elf32_arm_nabi_grok_prstatus
00750 #define elf_backend_grok_psinfo elf32_arm_nabi_grok_psinfo
00751
00752 #include "elf32-arm.h"