1 1.1 christos /* BFD back-end for ARM COFF files. 2 1.11 christos Copyright (C) 1990-2024 Free Software Foundation, Inc. 3 1.1 christos Written by Cygnus Support. 4 1.1 christos 5 1.1 christos This file is part of BFD, the Binary File Descriptor library. 6 1.1 christos 7 1.1 christos This program is free software; you can redistribute it and/or modify 8 1.1 christos it under the terms of the GNU General Public License as published by 9 1.1 christos the Free Software Foundation; either version 3 of the License, or 10 1.1 christos (at your option) any later version. 11 1.1 christos 12 1.1 christos This program is distributed in the hope that it will be useful, 13 1.1 christos but WITHOUT ANY WARRANTY; without even the implied warranty of 14 1.1 christos MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 15 1.1 christos GNU General Public License for more details. 16 1.1 christos 17 1.1 christos You should have received a copy of the GNU General Public License 18 1.1 christos along with this program; if not, write to the Free Software 19 1.1 christos Foundation, Inc., 51 Franklin Street - Fifth Floor, Boston, 20 1.1 christos MA 02110-1301, USA. */ 21 1.1 christos 22 1.1 christos #include "sysdep.h" 23 1.1 christos #include "bfd.h" 24 1.1 christos #include "libbfd.h" 25 1.1 christos #include "coff/arm.h" 26 1.1 christos #include "coff/internal.h" 27 1.9 christos #include "cpu-arm.h" 28 1.9 christos #include "coff-arm.h" 29 1.1 christos 30 1.1 christos #ifdef COFF_WITH_PE 31 1.1 christos #include "coff/pe.h" 32 1.1 christos #endif 33 1.1 christos 34 1.1 christos #include "libcoff.h" 35 1.1 christos 36 1.9 christos /* All users of this file have bfd_octets_per_byte (abfd, sec) == 1. */ 37 1.9 christos #define OCTETS_PER_BYTE(ABFD, SEC) 1 38 1.9 christos 39 1.1 christos /* Macros for manipulation the bits in the flags field of the coff data 40 1.1 christos structure. */ 41 1.1 christos #define APCS_26_FLAG(abfd) \ 42 1.1 christos (coff_data (abfd)->flags & F_APCS_26) 43 1.1 christos 44 1.1 christos #define APCS_FLOAT_FLAG(abfd) \ 45 1.1 christos (coff_data (abfd)->flags & F_APCS_FLOAT) 46 1.1 christos 47 1.1 christos #define PIC_FLAG(abfd) \ 48 1.1 christos (coff_data (abfd)->flags & F_PIC) 49 1.1 christos 50 1.1 christos #define APCS_SET(abfd) \ 51 1.1 christos (coff_data (abfd)->flags & F_APCS_SET) 52 1.1 christos 53 1.1 christos #define SET_APCS_FLAGS(abfd, flgs) \ 54 1.1 christos do \ 55 1.1 christos { \ 56 1.1 christos coff_data (abfd)->flags &= ~(F_APCS_26 | F_APCS_FLOAT | F_PIC); \ 57 1.1 christos coff_data (abfd)->flags |= (flgs) | F_APCS_SET; \ 58 1.1 christos } \ 59 1.1 christos while (0) 60 1.1 christos 61 1.1 christos #define INTERWORK_FLAG(abfd) \ 62 1.1 christos (coff_data (abfd)->flags & F_INTERWORK) 63 1.1 christos 64 1.1 christos #define INTERWORK_SET(abfd) \ 65 1.1 christos (coff_data (abfd)->flags & F_INTERWORK_SET) 66 1.1 christos 67 1.1 christos #define SET_INTERWORK_FLAG(abfd, flg) \ 68 1.1 christos do \ 69 1.1 christos { \ 70 1.1 christos coff_data (abfd)->flags &= ~F_INTERWORK; \ 71 1.1 christos coff_data (abfd)->flags |= (flg) | F_INTERWORK_SET; \ 72 1.1 christos } \ 73 1.1 christos while (0) 74 1.1 christos 75 1.1 christos #ifndef NUM_ELEM 76 1.1 christos #define NUM_ELEM(a) ((sizeof (a)) / sizeof ((a)[0])) 77 1.1 christos #endif 78 1.1 christos 79 1.1 christos typedef enum {bunknown, b9, b12, b23} thumb_pcrel_branchtype; 80 1.1 christos /* Some typedefs for holding instructions. */ 81 1.1 christos typedef unsigned long int insn32; 82 1.1 christos typedef unsigned short int insn16; 83 1.1 christos 84 1.1 christos /* The linker script knows the section names for placement. 85 1.1 christos The entry_names are used to do simple name mangling on the stubs. 86 1.1 christos Given a function name, and its type, the stub can be found. The 87 1.1 christos name can be changed. The only requirement is the %s be present. */ 88 1.1 christos 89 1.1 christos #define THUMB2ARM_GLUE_SECTION_NAME ".glue_7t" 90 1.1 christos #define THUMB2ARM_GLUE_ENTRY_NAME "__%s_from_thumb" 91 1.1 christos 92 1.1 christos #define ARM2THUMB_GLUE_SECTION_NAME ".glue_7" 93 1.1 christos #define ARM2THUMB_GLUE_ENTRY_NAME "__%s_from_arm" 94 1.1 christos 95 1.1 christos /* Used by the assembler. */ 96 1.1 christos 97 1.1 christos static bfd_reloc_status_type 98 1.1 christos coff_arm_reloc (bfd *abfd, 99 1.1 christos arelent *reloc_entry, 100 1.1 christos asymbol *symbol ATTRIBUTE_UNUSED, 101 1.1 christos void * data, 102 1.9 christos asection *input_section, 103 1.1 christos bfd *output_bfd, 104 1.1 christos char **error_message ATTRIBUTE_UNUSED) 105 1.1 christos { 106 1.1 christos symvalue diff; 107 1.1 christos 108 1.1 christos if (output_bfd == NULL) 109 1.1 christos return bfd_reloc_continue; 110 1.1 christos 111 1.1 christos diff = reloc_entry->addend; 112 1.1 christos 113 1.1 christos #define DOIT(x) \ 114 1.1 christos x = ((x & ~howto->dst_mask) \ 115 1.1 christos | (((x & howto->src_mask) + diff) & howto->dst_mask)) 116 1.1 christos 117 1.8 christos if (diff != 0) 118 1.8 christos { 119 1.8 christos reloc_howto_type *howto = reloc_entry->howto; 120 1.9 christos bfd_size_type octets = (reloc_entry->address 121 1.9 christos * OCTETS_PER_BYTE (abfd, input_section)); 122 1.9 christos unsigned char *addr = (unsigned char *) data + octets; 123 1.8 christos 124 1.9 christos if (!bfd_reloc_offset_in_range (howto, abfd, input_section, octets)) 125 1.8 christos return bfd_reloc_outofrange; 126 1.1 christos 127 1.10 christos switch (bfd_get_reloc_size (howto)) 128 1.8 christos { 129 1.10 christos case 1: 130 1.1 christos { 131 1.8 christos char x = bfd_get_8 (abfd, addr); 132 1.8 christos DOIT (x); 133 1.8 christos bfd_put_8 (abfd, x, addr); 134 1.8 christos } 135 1.8 christos break; 136 1.1 christos 137 1.10 christos case 2: 138 1.8 christos { 139 1.8 christos short x = bfd_get_16 (abfd, addr); 140 1.8 christos DOIT (x); 141 1.8 christos bfd_put_16 (abfd, (bfd_vma) x, addr); 142 1.8 christos } 143 1.8 christos break; 144 1.1 christos 145 1.10 christos case 4: 146 1.8 christos { 147 1.8 christos long x = bfd_get_32 (abfd, addr); 148 1.8 christos DOIT (x); 149 1.8 christos bfd_put_32 (abfd, (bfd_vma) x, addr); 150 1.8 christos } 151 1.8 christos break; 152 1.1 christos 153 1.8 christos default: 154 1.8 christos abort (); 155 1.8 christos } 156 1.8 christos } 157 1.1 christos 158 1.1 christos /* Now let bfd_perform_relocation finish everything up. */ 159 1.1 christos return bfd_reloc_continue; 160 1.1 christos } 161 1.1 christos 162 1.1 christos /* If USER_LABEL_PREFIX is defined as "_" (see coff_arm_is_local_label_name() 163 1.1 christos in this file), then TARGET_UNDERSCORE should be defined, otherwise it 164 1.1 christos should not. */ 165 1.1 christos #ifndef TARGET_UNDERSCORE 166 1.1 christos #define TARGET_UNDERSCORE '_' 167 1.1 christos #endif 168 1.1 christos 169 1.1 christos #ifndef PCRELOFFSET 170 1.10 christos #define PCRELOFFSET true 171 1.1 christos #endif 172 1.1 christos 173 1.1 christos /* These most certainly belong somewhere else. Just had to get rid of 174 1.1 christos the manifest constants in the code. */ 175 1.1 christos 176 1.1 christos #ifdef ARM_WINCE 177 1.1 christos 178 1.1 christos #define ARM_26D 0 179 1.1 christos #define ARM_32 1 180 1.1 christos #define ARM_RVA32 2 181 1.1 christos #define ARM_26 3 182 1.1 christos #define ARM_THUMB12 4 183 1.1 christos #define ARM_SECTION 14 184 1.1 christos #define ARM_SECREL 15 185 1.1 christos 186 1.1 christos #else 187 1.1 christos 188 1.8 christos #define ARM_8 0 189 1.8 christos #define ARM_16 1 190 1.8 christos #define ARM_32 2 191 1.8 christos #define ARM_26 3 192 1.1 christos #define ARM_DISP8 4 193 1.1 christos #define ARM_DISP16 5 194 1.1 christos #define ARM_DISP32 6 195 1.8 christos #define ARM_26D 7 196 1.1 christos /* 8 is unused. */ 197 1.1 christos #define ARM_NEG16 9 198 1.1 christos #define ARM_NEG32 10 199 1.1 christos #define ARM_RVA32 11 200 1.1 christos #define ARM_THUMB9 12 201 1.1 christos #define ARM_THUMB12 13 202 1.1 christos #define ARM_THUMB23 14 203 1.1 christos 204 1.1 christos #endif 205 1.1 christos 206 1.1 christos static bfd_reloc_status_type aoutarm_fix_pcrel_26_done 207 1.1 christos (bfd *, arelent *, asymbol *, void *, asection *, bfd *, char **); 208 1.1 christos static bfd_reloc_status_type aoutarm_fix_pcrel_26 209 1.1 christos (bfd *, arelent *, asymbol *, void *, asection *, bfd *, char **); 210 1.1 christos static bfd_reloc_status_type coff_thumb_pcrel_12 211 1.1 christos (bfd *, arelent *, asymbol *, void *, asection *, bfd *, char **); 212 1.1 christos #ifndef ARM_WINCE 213 1.1 christos static bfd_reloc_status_type coff_thumb_pcrel_9 214 1.1 christos (bfd *, arelent *, asymbol *, void *, asection *, bfd *, char **); 215 1.1 christos static bfd_reloc_status_type coff_thumb_pcrel_23 216 1.1 christos (bfd *, arelent *, asymbol *, void *, asection *, bfd *, char **); 217 1.1 christos #endif 218 1.1 christos 219 1.1 christos static reloc_howto_type aoutarm_std_reloc_howto[] = 220 1.1 christos { 221 1.1 christos #ifdef ARM_WINCE 222 1.1 christos HOWTO (ARM_26D, 223 1.1 christos 2, 224 1.10 christos 4, 225 1.1 christos 24, 226 1.10 christos true, 227 1.1 christos 0, 228 1.1 christos complain_overflow_dont, 229 1.1 christos aoutarm_fix_pcrel_26_done, 230 1.1 christos "ARM_26D", 231 1.10 christos true, /* partial_inplace. */ 232 1.1 christos 0x00ffffff, 233 1.1 christos 0x0, 234 1.1 christos PCRELOFFSET), 235 1.1 christos HOWTO (ARM_32, 236 1.1 christos 0, 237 1.10 christos 4, 238 1.1 christos 32, 239 1.10 christos false, 240 1.1 christos 0, 241 1.1 christos complain_overflow_bitfield, 242 1.1 christos coff_arm_reloc, 243 1.1 christos "ARM_32", 244 1.10 christos true, /* partial_inplace. */ 245 1.1 christos 0xffffffff, 246 1.1 christos 0xffffffff, 247 1.1 christos PCRELOFFSET), 248 1.1 christos HOWTO (ARM_RVA32, 249 1.1 christos 0, 250 1.10 christos 4, 251 1.1 christos 32, 252 1.10 christos false, 253 1.1 christos 0, 254 1.1 christos complain_overflow_bitfield, 255 1.1 christos coff_arm_reloc, 256 1.1 christos "ARM_RVA32", 257 1.10 christos true, /* partial_inplace. */ 258 1.1 christos 0xffffffff, 259 1.1 christos 0xffffffff, 260 1.1 christos PCRELOFFSET), 261 1.1 christos HOWTO (ARM_26, 262 1.1 christos 2, 263 1.10 christos 4, 264 1.1 christos 24, 265 1.10 christos true, 266 1.1 christos 0, 267 1.1 christos complain_overflow_signed, 268 1.1 christos aoutarm_fix_pcrel_26 , 269 1.1 christos "ARM_26", 270 1.10 christos false, 271 1.1 christos 0x00ffffff, 272 1.1 christos 0x00ffffff, 273 1.1 christos PCRELOFFSET), 274 1.1 christos HOWTO (ARM_THUMB12, 275 1.1 christos 1, 276 1.10 christos 2, 277 1.1 christos 11, 278 1.10 christos true, 279 1.1 christos 0, 280 1.1 christos complain_overflow_signed, 281 1.1 christos coff_thumb_pcrel_12 , 282 1.1 christos "ARM_THUMB12", 283 1.10 christos false, 284 1.1 christos 0x000007ff, 285 1.1 christos 0x000007ff, 286 1.1 christos PCRELOFFSET), 287 1.1 christos EMPTY_HOWTO (-1), 288 1.1 christos EMPTY_HOWTO (-1), 289 1.1 christos EMPTY_HOWTO (-1), 290 1.1 christos EMPTY_HOWTO (-1), 291 1.1 christos EMPTY_HOWTO (-1), 292 1.1 christos EMPTY_HOWTO (-1), 293 1.1 christos EMPTY_HOWTO (-1), 294 1.1 christos EMPTY_HOWTO (-1), 295 1.1 christos EMPTY_HOWTO (-1), 296 1.1 christos HOWTO (ARM_SECTION, 297 1.1 christos 0, 298 1.10 christos 2, 299 1.1 christos 16, 300 1.10 christos false, 301 1.1 christos 0, 302 1.1 christos complain_overflow_bitfield, 303 1.1 christos coff_arm_reloc, 304 1.1 christos "ARM_SECTION", 305 1.10 christos true, /* partial_inplace. */ 306 1.1 christos 0x0000ffff, 307 1.1 christos 0x0000ffff, 308 1.1 christos PCRELOFFSET), 309 1.1 christos HOWTO (ARM_SECREL, 310 1.1 christos 0, 311 1.10 christos 4, 312 1.1 christos 32, 313 1.10 christos false, 314 1.1 christos 0, 315 1.1 christos complain_overflow_bitfield, 316 1.1 christos coff_arm_reloc, 317 1.1 christos "ARM_SECREL", 318 1.10 christos true, /* partial_inplace. */ 319 1.1 christos 0xffffffff, 320 1.1 christos 0xffffffff, 321 1.1 christos PCRELOFFSET), 322 1.1 christos #else /* not ARM_WINCE */ 323 1.1 christos HOWTO (ARM_8, 324 1.1 christos 0, 325 1.10 christos 1, 326 1.1 christos 8, 327 1.10 christos false, 328 1.1 christos 0, 329 1.1 christos complain_overflow_bitfield, 330 1.1 christos coff_arm_reloc, 331 1.1 christos "ARM_8", 332 1.10 christos true, 333 1.1 christos 0x000000ff, 334 1.1 christos 0x000000ff, 335 1.1 christos PCRELOFFSET), 336 1.1 christos HOWTO (ARM_16, 337 1.1 christos 0, 338 1.10 christos 2, 339 1.1 christos 16, 340 1.10 christos false, 341 1.1 christos 0, 342 1.1 christos complain_overflow_bitfield, 343 1.1 christos coff_arm_reloc, 344 1.1 christos "ARM_16", 345 1.10 christos true, 346 1.1 christos 0x0000ffff, 347 1.1 christos 0x0000ffff, 348 1.1 christos PCRELOFFSET), 349 1.1 christos HOWTO (ARM_32, 350 1.1 christos 0, 351 1.10 christos 4, 352 1.1 christos 32, 353 1.10 christos false, 354 1.1 christos 0, 355 1.1 christos complain_overflow_bitfield, 356 1.1 christos coff_arm_reloc, 357 1.1 christos "ARM_32", 358 1.10 christos true, 359 1.1 christos 0xffffffff, 360 1.1 christos 0xffffffff, 361 1.1 christos PCRELOFFSET), 362 1.1 christos HOWTO (ARM_26, 363 1.1 christos 2, 364 1.10 christos 4, 365 1.1 christos 24, 366 1.10 christos true, 367 1.1 christos 0, 368 1.1 christos complain_overflow_signed, 369 1.1 christos aoutarm_fix_pcrel_26 , 370 1.1 christos "ARM_26", 371 1.10 christos false, 372 1.1 christos 0x00ffffff, 373 1.1 christos 0x00ffffff, 374 1.1 christos PCRELOFFSET), 375 1.1 christos HOWTO (ARM_DISP8, 376 1.1 christos 0, 377 1.10 christos 1, 378 1.1 christos 8, 379 1.10 christos true, 380 1.1 christos 0, 381 1.1 christos complain_overflow_signed, 382 1.1 christos coff_arm_reloc, 383 1.1 christos "ARM_DISP8", 384 1.10 christos true, 385 1.1 christos 0x000000ff, 386 1.1 christos 0x000000ff, 387 1.10 christos true), 388 1.1 christos HOWTO (ARM_DISP16, 389 1.1 christos 0, 390 1.10 christos 2, 391 1.1 christos 16, 392 1.10 christos true, 393 1.1 christos 0, 394 1.1 christos complain_overflow_signed, 395 1.1 christos coff_arm_reloc, 396 1.1 christos "ARM_DISP16", 397 1.10 christos true, 398 1.1 christos 0x0000ffff, 399 1.1 christos 0x0000ffff, 400 1.10 christos true), 401 1.1 christos HOWTO (ARM_DISP32, 402 1.1 christos 0, 403 1.10 christos 4, 404 1.1 christos 32, 405 1.10 christos true, 406 1.1 christos 0, 407 1.1 christos complain_overflow_signed, 408 1.1 christos coff_arm_reloc, 409 1.1 christos "ARM_DISP32", 410 1.10 christos true, 411 1.1 christos 0xffffffff, 412 1.1 christos 0xffffffff, 413 1.10 christos true), 414 1.1 christos HOWTO (ARM_26D, 415 1.1 christos 2, 416 1.10 christos 4, 417 1.1 christos 24, 418 1.10 christos false, 419 1.1 christos 0, 420 1.1 christos complain_overflow_dont, 421 1.1 christos aoutarm_fix_pcrel_26_done, 422 1.1 christos "ARM_26D", 423 1.10 christos true, 424 1.1 christos 0x00ffffff, 425 1.1 christos 0x0, 426 1.10 christos false), 427 1.1 christos /* 8 is unused */ 428 1.1 christos EMPTY_HOWTO (-1), 429 1.1 christos HOWTO (ARM_NEG16, 430 1.1 christos 0, 431 1.10 christos -2, 432 1.1 christos 16, 433 1.10 christos false, 434 1.1 christos 0, 435 1.1 christos complain_overflow_bitfield, 436 1.1 christos coff_arm_reloc, 437 1.1 christos "ARM_NEG16", 438 1.10 christos true, 439 1.1 christos 0x0000ffff, 440 1.1 christos 0x0000ffff, 441 1.10 christos false), 442 1.1 christos HOWTO (ARM_NEG32, 443 1.1 christos 0, 444 1.10 christos -4, 445 1.1 christos 32, 446 1.10 christos false, 447 1.1 christos 0, 448 1.1 christos complain_overflow_bitfield, 449 1.1 christos coff_arm_reloc, 450 1.1 christos "ARM_NEG32", 451 1.10 christos true, 452 1.1 christos 0xffffffff, 453 1.1 christos 0xffffffff, 454 1.10 christos false), 455 1.1 christos HOWTO (ARM_RVA32, 456 1.1 christos 0, 457 1.10 christos 4, 458 1.1 christos 32, 459 1.10 christos false, 460 1.1 christos 0, 461 1.1 christos complain_overflow_bitfield, 462 1.1 christos coff_arm_reloc, 463 1.1 christos "ARM_RVA32", 464 1.10 christos true, 465 1.1 christos 0xffffffff, 466 1.1 christos 0xffffffff, 467 1.1 christos PCRELOFFSET), 468 1.1 christos HOWTO (ARM_THUMB9, 469 1.1 christos 1, 470 1.10 christos 2, 471 1.1 christos 8, 472 1.10 christos true, 473 1.1 christos 0, 474 1.1 christos complain_overflow_signed, 475 1.1 christos coff_thumb_pcrel_9 , 476 1.1 christos "ARM_THUMB9", 477 1.10 christos false, 478 1.1 christos 0x000000ff, 479 1.1 christos 0x000000ff, 480 1.1 christos PCRELOFFSET), 481 1.1 christos HOWTO (ARM_THUMB12, 482 1.1 christos 1, 483 1.10 christos 2, 484 1.1 christos 11, 485 1.10 christos true, 486 1.1 christos 0, 487 1.1 christos complain_overflow_signed, 488 1.1 christos coff_thumb_pcrel_12 , 489 1.1 christos "ARM_THUMB12", 490 1.10 christos false, 491 1.1 christos 0x000007ff, 492 1.1 christos 0x000007ff, 493 1.1 christos PCRELOFFSET), 494 1.1 christos HOWTO (ARM_THUMB23, 495 1.1 christos 1, 496 1.10 christos 4, 497 1.1 christos 22, 498 1.10 christos true, 499 1.1 christos 0, 500 1.1 christos complain_overflow_signed, 501 1.1 christos coff_thumb_pcrel_23 , 502 1.1 christos "ARM_THUMB23", 503 1.10 christos false, 504 1.1 christos 0x07ff07ff, 505 1.1 christos 0x07ff07ff, 506 1.1 christos PCRELOFFSET) 507 1.1 christos #endif /* not ARM_WINCE */ 508 1.1 christos }; 509 1.1 christos 510 1.1 christos #define NUM_RELOCS NUM_ELEM (aoutarm_std_reloc_howto) 511 1.1 christos 512 1.1 christos #ifdef COFF_WITH_PE 513 1.1 christos /* Return TRUE if this relocation should 514 1.1 christos appear in the output .reloc section. */ 515 1.1 christos 516 1.10 christos static bool 517 1.1 christos in_reloc_p (bfd * abfd ATTRIBUTE_UNUSED, 518 1.1 christos reloc_howto_type * howto) 519 1.1 christos { 520 1.1 christos return !howto->pc_relative && howto->type != ARM_RVA32; 521 1.1 christos } 522 1.1 christos #endif 523 1.1 christos 524 1.1 christos #define RTYPE2HOWTO(cache_ptr, dst) \ 525 1.1 christos (cache_ptr)->howto = \ 526 1.1 christos (dst)->r_type < NUM_RELOCS \ 527 1.1 christos ? aoutarm_std_reloc_howto + (dst)->r_type \ 528 1.1 christos : NULL 529 1.1 christos 530 1.1 christos #define coff_rtype_to_howto coff_arm_rtype_to_howto 531 1.1 christos 532 1.1 christos static reloc_howto_type * 533 1.1 christos coff_arm_rtype_to_howto (bfd *abfd ATTRIBUTE_UNUSED, 534 1.1 christos asection *sec, 535 1.1 christos struct internal_reloc *rel, 536 1.1 christos struct coff_link_hash_entry *h ATTRIBUTE_UNUSED, 537 1.1 christos struct internal_syment *sym ATTRIBUTE_UNUSED, 538 1.1 christos bfd_vma *addendp) 539 1.1 christos { 540 1.1 christos reloc_howto_type * howto; 541 1.1 christos 542 1.1 christos if (rel->r_type >= NUM_RELOCS) 543 1.1 christos return NULL; 544 1.1 christos 545 1.1 christos howto = aoutarm_std_reloc_howto + rel->r_type; 546 1.1 christos 547 1.1 christos if (rel->r_type == ARM_RVA32) 548 1.1 christos *addendp -= pe_data (sec->output_section->owner)->pe_opthdr.ImageBase; 549 1.1 christos 550 1.1 christos #if defined COFF_WITH_PE && defined ARM_WINCE 551 1.1 christos if (rel->r_type == ARM_SECREL) 552 1.1 christos { 553 1.1 christos bfd_vma osect_vma; 554 1.1 christos 555 1.1 christos if (h && (h->type == bfd_link_hash_defined 556 1.1 christos || h->type == bfd_link_hash_defweak)) 557 1.1 christos osect_vma = h->root.u.def.section->output_section->vma; 558 1.1 christos else 559 1.1 christos { 560 1.1 christos int i; 561 1.1 christos 562 1.1 christos /* Sigh, the only way to get the section to offset against 563 1.1 christos is to find it the hard way. */ 564 1.1 christos 565 1.1 christos for (sec = abfd->sections, i = 1; i < sym->n_scnum; i++) 566 1.1 christos sec = sec->next; 567 1.1 christos 568 1.1 christos osect_vma = sec->output_section->vma; 569 1.1 christos } 570 1.1 christos 571 1.1 christos *addendp -= osect_vma; 572 1.1 christos } 573 1.1 christos #endif 574 1.1 christos 575 1.1 christos return howto; 576 1.1 christos } 577 1.1 christos 578 1.1 christos /* Used by the assembler. */ 579 1.1 christos 580 1.1 christos static bfd_reloc_status_type 581 1.1 christos aoutarm_fix_pcrel_26_done (bfd *abfd ATTRIBUTE_UNUSED, 582 1.1 christos arelent *reloc_entry ATTRIBUTE_UNUSED, 583 1.1 christos asymbol *symbol ATTRIBUTE_UNUSED, 584 1.1 christos void * data ATTRIBUTE_UNUSED, 585 1.1 christos asection *input_section ATTRIBUTE_UNUSED, 586 1.1 christos bfd *output_bfd ATTRIBUTE_UNUSED, 587 1.1 christos char **error_message ATTRIBUTE_UNUSED) 588 1.1 christos { 589 1.1 christos /* This is dead simple at present. */ 590 1.1 christos return bfd_reloc_ok; 591 1.1 christos } 592 1.1 christos 593 1.1 christos /* Used by the assembler. */ 594 1.1 christos 595 1.1 christos static bfd_reloc_status_type 596 1.1 christos aoutarm_fix_pcrel_26 (bfd *abfd, 597 1.1 christos arelent *reloc_entry, 598 1.1 christos asymbol *symbol, 599 1.1 christos void * data, 600 1.1 christos asection *input_section, 601 1.1 christos bfd *output_bfd, 602 1.1 christos char **error_message ATTRIBUTE_UNUSED) 603 1.1 christos { 604 1.1 christos bfd_vma relocation; 605 1.1 christos bfd_size_type addr = reloc_entry->address; 606 1.1 christos long target = bfd_get_32 (abfd, (bfd_byte *) data + addr); 607 1.1 christos bfd_reloc_status_type flag = bfd_reloc_ok; 608 1.1 christos 609 1.1 christos /* If this is an undefined symbol, return error. */ 610 1.1 christos if (bfd_is_und_section (symbol->section) 611 1.1 christos && (symbol->flags & BSF_WEAK) == 0) 612 1.1 christos return output_bfd ? bfd_reloc_continue : bfd_reloc_undefined; 613 1.1 christos 614 1.1 christos /* If the sections are different, and we are doing a partial relocation, 615 1.1 christos just ignore it for now. */ 616 1.1 christos if (symbol->section->name != input_section->name 617 1.1 christos && output_bfd != (bfd *)NULL) 618 1.1 christos return bfd_reloc_continue; 619 1.1 christos 620 1.1 christos relocation = (target & 0x00ffffff) << 2; 621 1.1 christos relocation = (relocation ^ 0x02000000) - 0x02000000; /* Sign extend. */ 622 1.1 christos relocation += symbol->value; 623 1.1 christos relocation += symbol->section->output_section->vma; 624 1.1 christos relocation += symbol->section->output_offset; 625 1.1 christos relocation += reloc_entry->addend; 626 1.1 christos relocation -= input_section->output_section->vma; 627 1.1 christos relocation -= input_section->output_offset; 628 1.1 christos relocation -= addr; 629 1.1 christos 630 1.1 christos if (relocation & 3) 631 1.1 christos return bfd_reloc_overflow; 632 1.1 christos 633 1.1 christos /* Check for overflow. */ 634 1.1 christos if (relocation & 0x02000000) 635 1.1 christos { 636 1.1 christos if ((relocation & ~ (bfd_vma) 0x03ffffff) != ~ (bfd_vma) 0x03ffffff) 637 1.1 christos flag = bfd_reloc_overflow; 638 1.1 christos } 639 1.1 christos else if (relocation & ~(bfd_vma) 0x03ffffff) 640 1.1 christos flag = bfd_reloc_overflow; 641 1.1 christos 642 1.1 christos target &= ~0x00ffffff; 643 1.1 christos target |= (relocation >> 2) & 0x00ffffff; 644 1.1 christos bfd_put_32 (abfd, (bfd_vma) target, (bfd_byte *) data + addr); 645 1.1 christos 646 1.1 christos /* Now the ARM magic... Change the reloc type so that it is marked as done. 647 1.1 christos Strictly this is only necessary if we are doing a partial relocation. */ 648 1.1 christos reloc_entry->howto = &aoutarm_std_reloc_howto[ARM_26D]; 649 1.1 christos 650 1.1 christos return flag; 651 1.1 christos } 652 1.1 christos 653 1.1 christos static bfd_reloc_status_type 654 1.1 christos coff_thumb_pcrel_common (bfd *abfd, 655 1.1 christos arelent *reloc_entry, 656 1.1 christos asymbol *symbol, 657 1.1 christos void * data, 658 1.1 christos asection *input_section, 659 1.1 christos bfd *output_bfd, 660 1.1 christos char **error_message ATTRIBUTE_UNUSED, 661 1.1 christos thumb_pcrel_branchtype btype) 662 1.1 christos { 663 1.1 christos bfd_vma relocation = 0; 664 1.1 christos bfd_size_type addr = reloc_entry->address; 665 1.1 christos long target = bfd_get_32 (abfd, (bfd_byte *) data + addr); 666 1.1 christos bfd_reloc_status_type flag = bfd_reloc_ok; 667 1.1 christos bfd_vma dstmsk; 668 1.1 christos bfd_vma offmsk; 669 1.1 christos bfd_vma signbit; 670 1.1 christos 671 1.1 christos /* NOTE: This routine is currently used by GAS, but not by the link 672 1.1 christos phase. */ 673 1.1 christos switch (btype) 674 1.1 christos { 675 1.1 christos case b9: 676 1.1 christos dstmsk = 0x000000ff; 677 1.1 christos offmsk = 0x000001fe; 678 1.1 christos signbit = 0x00000100; 679 1.1 christos break; 680 1.1 christos 681 1.1 christos case b12: 682 1.1 christos dstmsk = 0x000007ff; 683 1.1 christos offmsk = 0x00000ffe; 684 1.1 christos signbit = 0x00000800; 685 1.1 christos break; 686 1.1 christos 687 1.1 christos case b23: 688 1.1 christos dstmsk = 0x07ff07ff; 689 1.1 christos offmsk = 0x007fffff; 690 1.1 christos signbit = 0x00400000; 691 1.1 christos break; 692 1.1 christos 693 1.1 christos default: 694 1.1 christos abort (); 695 1.1 christos } 696 1.1 christos 697 1.1 christos /* If this is an undefined symbol, return error. */ 698 1.1 christos if (bfd_is_und_section (symbol->section) 699 1.1 christos && (symbol->flags & BSF_WEAK) == 0) 700 1.1 christos return output_bfd ? bfd_reloc_continue : bfd_reloc_undefined; 701 1.1 christos 702 1.1 christos /* If the sections are different, and we are doing a partial relocation, 703 1.1 christos just ignore it for now. */ 704 1.1 christos if (symbol->section->name != input_section->name 705 1.1 christos && output_bfd != (bfd *)NULL) 706 1.1 christos return bfd_reloc_continue; 707 1.1 christos 708 1.1 christos switch (btype) 709 1.1 christos { 710 1.1 christos case b9: 711 1.1 christos case b12: 712 1.1 christos relocation = ((target & dstmsk) << 1); 713 1.1 christos break; 714 1.1 christos 715 1.1 christos case b23: 716 1.1 christos if (bfd_big_endian (abfd)) 717 1.1 christos relocation = ((target & 0x7ff) << 1) | ((target & 0x07ff0000) >> 4); 718 1.1 christos else 719 1.1 christos relocation = ((target & 0x7ff) << 12) | ((target & 0x07ff0000) >> 15); 720 1.1 christos break; 721 1.1 christos 722 1.1 christos default: 723 1.1 christos abort (); 724 1.1 christos } 725 1.1 christos 726 1.1 christos relocation = (relocation ^ signbit) - signbit; /* Sign extend. */ 727 1.1 christos relocation += symbol->value; 728 1.1 christos relocation += symbol->section->output_section->vma; 729 1.1 christos relocation += symbol->section->output_offset; 730 1.1 christos relocation += reloc_entry->addend; 731 1.1 christos relocation -= input_section->output_section->vma; 732 1.1 christos relocation -= input_section->output_offset; 733 1.1 christos relocation -= addr; 734 1.1 christos 735 1.1 christos if (relocation & 1) 736 1.1 christos return bfd_reloc_overflow; 737 1.1 christos 738 1.1 christos /* Check for overflow. */ 739 1.1 christos if (relocation & signbit) 740 1.1 christos { 741 1.1 christos if ((relocation & ~offmsk) != ~offmsk) 742 1.1 christos flag = bfd_reloc_overflow; 743 1.1 christos } 744 1.1 christos else if (relocation & ~offmsk) 745 1.1 christos flag = bfd_reloc_overflow; 746 1.1 christos 747 1.1 christos target &= ~dstmsk; 748 1.1 christos switch (btype) 749 1.1 christos { 750 1.1 christos case b9: 751 1.1 christos case b12: 752 1.1 christos target |= (relocation >> 1); 753 1.1 christos break; 754 1.1 christos 755 1.1 christos case b23: 756 1.1 christos if (bfd_big_endian (abfd)) 757 1.1 christos target |= (((relocation & 0xfff) >> 1) 758 1.1 christos | ((relocation << 4) & 0x07ff0000)); 759 1.1 christos else 760 1.1 christos target |= (((relocation & 0xffe) << 15) 761 1.1 christos | ((relocation >> 12) & 0x7ff)); 762 1.1 christos break; 763 1.1 christos 764 1.1 christos default: 765 1.1 christos abort (); 766 1.1 christos } 767 1.1 christos 768 1.1 christos bfd_put_32 (abfd, (bfd_vma) target, (bfd_byte *) data + addr); 769 1.1 christos 770 1.1 christos /* Now the ARM magic... Change the reloc type so that it is marked as done. 771 1.1 christos Strictly this is only necessary if we are doing a partial relocation. */ 772 1.1 christos reloc_entry->howto = & aoutarm_std_reloc_howto [ARM_26D]; 773 1.1 christos 774 1.1 christos /* TODO: We should possibly have DONE entries for the THUMB PCREL relocations. */ 775 1.1 christos return flag; 776 1.1 christos } 777 1.1 christos 778 1.1 christos #ifndef ARM_WINCE 779 1.1 christos static bfd_reloc_status_type 780 1.1 christos coff_thumb_pcrel_23 (bfd *abfd, 781 1.1 christos arelent *reloc_entry, 782 1.1 christos asymbol *symbol, 783 1.1 christos void * data, 784 1.1 christos asection *input_section, 785 1.1 christos bfd *output_bfd, 786 1.1 christos char **error_message) 787 1.1 christos { 788 1.1 christos return coff_thumb_pcrel_common (abfd, reloc_entry, symbol, data, 789 1.8 christos input_section, output_bfd, error_message, 790 1.1 christos b23); 791 1.1 christos } 792 1.1 christos 793 1.1 christos static bfd_reloc_status_type 794 1.1 christos coff_thumb_pcrel_9 (bfd *abfd, 795 1.1 christos arelent *reloc_entry, 796 1.1 christos asymbol *symbol, 797 1.1 christos void * data, 798 1.1 christos asection *input_section, 799 1.1 christos bfd *output_bfd, 800 1.1 christos char **error_message) 801 1.1 christos { 802 1.1 christos return coff_thumb_pcrel_common (abfd, reloc_entry, symbol, data, 803 1.8 christos input_section, output_bfd, error_message, 804 1.1 christos b9); 805 1.1 christos } 806 1.1 christos #endif /* not ARM_WINCE */ 807 1.1 christos 808 1.1 christos static bfd_reloc_status_type 809 1.1 christos coff_thumb_pcrel_12 (bfd *abfd, 810 1.1 christos arelent *reloc_entry, 811 1.1 christos asymbol *symbol, 812 1.1 christos void * data, 813 1.1 christos asection *input_section, 814 1.1 christos bfd *output_bfd, 815 1.1 christos char **error_message) 816 1.1 christos { 817 1.1 christos return coff_thumb_pcrel_common (abfd, reloc_entry, symbol, data, 818 1.8 christos input_section, output_bfd, error_message, 819 1.1 christos b12); 820 1.1 christos } 821 1.1 christos 822 1.8 christos static reloc_howto_type * 823 1.1 christos coff_arm_reloc_type_lookup (bfd * abfd, bfd_reloc_code_real_type code) 824 1.1 christos { 825 1.1 christos #define ASTD(i,j) case i: return aoutarm_std_reloc_howto + j 826 1.1 christos 827 1.1 christos if (code == BFD_RELOC_CTOR) 828 1.1 christos switch (bfd_arch_bits_per_address (abfd)) 829 1.1 christos { 830 1.1 christos case 32: 831 1.8 christos code = BFD_RELOC_32; 832 1.8 christos break; 833 1.1 christos default: 834 1.1 christos return NULL; 835 1.1 christos } 836 1.1 christos 837 1.1 christos switch (code) 838 1.1 christos { 839 1.1 christos #ifdef ARM_WINCE 840 1.8 christos ASTD (BFD_RELOC_32, ARM_32); 841 1.8 christos ASTD (BFD_RELOC_RVA, ARM_RVA32); 842 1.8 christos ASTD (BFD_RELOC_ARM_PCREL_BRANCH, ARM_26); 843 1.1 christos ASTD (BFD_RELOC_THUMB_PCREL_BRANCH12, ARM_THUMB12); 844 1.8 christos ASTD (BFD_RELOC_32_SECREL, ARM_SECREL); 845 1.1 christos #else 846 1.8 christos ASTD (BFD_RELOC_8, ARM_8); 847 1.8 christos ASTD (BFD_RELOC_16, ARM_16); 848 1.8 christos ASTD (BFD_RELOC_32, ARM_32); 849 1.8 christos ASTD (BFD_RELOC_ARM_PCREL_BRANCH, ARM_26); 850 1.8 christos ASTD (BFD_RELOC_ARM_PCREL_BLX, ARM_26); 851 1.8 christos ASTD (BFD_RELOC_8_PCREL, ARM_DISP8); 852 1.8 christos ASTD (BFD_RELOC_16_PCREL, ARM_DISP16); 853 1.8 christos ASTD (BFD_RELOC_32_PCREL, ARM_DISP32); 854 1.8 christos ASTD (BFD_RELOC_RVA, ARM_RVA32); 855 1.1 christos ASTD (BFD_RELOC_THUMB_PCREL_BRANCH9, ARM_THUMB9); 856 1.1 christos ASTD (BFD_RELOC_THUMB_PCREL_BRANCH12, ARM_THUMB12); 857 1.1 christos ASTD (BFD_RELOC_THUMB_PCREL_BRANCH23, ARM_THUMB23); 858 1.8 christos ASTD (BFD_RELOC_THUMB_PCREL_BLX, ARM_THUMB23); 859 1.1 christos #endif 860 1.1 christos default: return NULL; 861 1.1 christos } 862 1.1 christos } 863 1.1 christos 864 1.1 christos static reloc_howto_type * 865 1.1 christos coff_arm_reloc_name_lookup (bfd *abfd ATTRIBUTE_UNUSED, 866 1.1 christos const char *r_name) 867 1.1 christos { 868 1.1 christos unsigned int i; 869 1.1 christos 870 1.1 christos for (i = 0; 871 1.1 christos i < (sizeof (aoutarm_std_reloc_howto) 872 1.1 christos / sizeof (aoutarm_std_reloc_howto[0])); 873 1.1 christos i++) 874 1.1 christos if (aoutarm_std_reloc_howto[i].name != NULL 875 1.1 christos && strcasecmp (aoutarm_std_reloc_howto[i].name, r_name) == 0) 876 1.1 christos return &aoutarm_std_reloc_howto[i]; 877 1.1 christos 878 1.1 christos return NULL; 879 1.1 christos } 880 1.1 christos 881 1.1 christos #define COFF_DEFAULT_SECTION_ALIGNMENT_POWER 2 882 1.8 christos #define COFF_PAGE_SIZE 0x1000 883 1.1 christos 884 1.1 christos /* Turn a howto into a reloc nunmber. */ 885 1.1 christos #define SELECT_RELOC(x,howto) { x.r_type = howto->type; } 886 1.8 christos #define BADMAG(x) ARMBADMAG(x) 887 1.8 christos #define ARM 1 /* Customize coffcode.h. */ 888 1.1 christos 889 1.1 christos #ifndef ARM_WINCE 890 1.1 christos /* Make sure that the 'r_offset' field is copied properly 891 1.1 christos so that identical binaries will compare the same. */ 892 1.1 christos #define SWAP_IN_RELOC_OFFSET H_GET_32 893 1.1 christos #define SWAP_OUT_RELOC_OFFSET H_PUT_32 894 1.1 christos #endif 895 1.1 christos 896 1.1 christos /* Extend the coff_link_hash_table structure with a few ARM specific fields. 897 1.1 christos This allows us to store global data here without actually creating any 898 1.1 christos global variables, which is a no-no in the BFD world. */ 899 1.1 christos struct coff_arm_link_hash_table 900 1.1 christos { 901 1.1 christos /* The original coff_link_hash_table structure. MUST be first field. */ 902 1.1 christos struct coff_link_hash_table root; 903 1.1 christos 904 1.1 christos /* The size in bytes of the section containing the Thumb-to-ARM glue. */ 905 1.1 christos bfd_size_type thumb_glue_size; 906 1.1 christos 907 1.1 christos /* The size in bytes of the section containing the ARM-to-Thumb glue. */ 908 1.1 christos bfd_size_type arm_glue_size; 909 1.1 christos 910 1.1 christos /* An arbitrary input BFD chosen to hold the glue sections. */ 911 1.1 christos bfd * bfd_of_glue_owner; 912 1.1 christos 913 1.1 christos /* Support interworking with old, non-interworking aware ARM code. */ 914 1.8 christos int support_old_code; 915 1.1 christos }; 916 1.1 christos 917 1.1 christos /* Get the ARM coff linker hash table from a link_info structure. */ 918 1.1 christos #define coff_arm_hash_table(info) \ 919 1.1 christos ((struct coff_arm_link_hash_table *) ((info)->hash)) 920 1.1 christos 921 1.1 christos /* Create an ARM coff linker hash table. */ 922 1.1 christos 923 1.1 christos static struct bfd_link_hash_table * 924 1.1 christos coff_arm_link_hash_table_create (bfd * abfd) 925 1.1 christos { 926 1.1 christos struct coff_arm_link_hash_table * ret; 927 1.9 christos size_t amt = sizeof (struct coff_arm_link_hash_table); 928 1.1 christos 929 1.1 christos ret = bfd_zmalloc (amt); 930 1.1 christos if (ret == NULL) 931 1.1 christos return NULL; 932 1.1 christos 933 1.1 christos if (!_bfd_coff_link_hash_table_init (&ret->root, 934 1.1 christos abfd, 935 1.1 christos _bfd_coff_link_hash_newfunc, 936 1.1 christos sizeof (struct coff_link_hash_entry))) 937 1.1 christos { 938 1.1 christos free (ret); 939 1.1 christos return NULL; 940 1.1 christos } 941 1.1 christos 942 1.1 christos return & ret->root.root; 943 1.1 christos } 944 1.1 christos 945 1.10 christos static bool 946 1.1 christos arm_emit_base_file_entry (struct bfd_link_info *info, 947 1.1 christos bfd *output_bfd, 948 1.1 christos asection *input_section, 949 1.1 christos bfd_vma reloc_offset) 950 1.1 christos { 951 1.1 christos bfd_vma addr = (reloc_offset 952 1.1 christos - input_section->vma 953 1.1 christos + input_section->output_offset 954 1.1 christos + input_section->output_section->vma); 955 1.1 christos 956 1.11 christos if (obj_pe (output_bfd)) 957 1.1 christos addr -= pe_data (output_bfd)->pe_opthdr.ImageBase; 958 1.1 christos if (fwrite (&addr, sizeof (addr), 1, (FILE *) info->base_file) == 1) 959 1.10 christos return true; 960 1.1 christos 961 1.1 christos bfd_set_error (bfd_error_system_call); 962 1.10 christos return false; 963 1.1 christos } 964 1.1 christos 965 1.1 christos #ifndef ARM_WINCE 967 1.1 christos /* The thumb form of a long branch is a bit finicky, because the offset 968 1.1 christos encoding is split over two fields, each in it's own instruction. They 969 1.1 christos can occur in any order. So given a thumb form of long branch, and an 970 1.1 christos offset, insert the offset into the thumb branch and return finished 971 1.1 christos instruction. 972 1.1 christos 973 1.1 christos It takes two thumb instructions to encode the target address. Each has 974 1.1 christos 11 bits to invest. The upper 11 bits are stored in one (identified by 975 1.1 christos H-0.. see below), the lower 11 bits are stored in the other (identified 976 1.1 christos by H-1). 977 1.1 christos 978 1.1 christos Combine together and shifted left by 1 (it's a half word address) and 979 1.1 christos there you have it. 980 1.1 christos 981 1.1 christos Op: 1111 = F, 982 1.1 christos H-0, upper address-0 = 000 983 1.1 christos Op: 1111 = F, 984 1.1 christos H-1, lower address-0 = 800 985 1.1 christos 986 1.1 christos They can be ordered either way, but the arm tools I've seen always put 987 1.1 christos the lower one first. It probably doesn't matter. krk (at) cygnus.com 988 1.1 christos 989 1.1 christos XXX: Actually the order does matter. The second instruction (H-1) 990 1.1 christos moves the computed address into the PC, so it must be the second one 991 1.1 christos in the sequence. The problem, however is that whilst little endian code 992 1.1 christos stores the instructions in HI then LOW order, big endian code does the 993 1.1 christos reverse. nickc (at) cygnus.com. */ 994 1.1 christos 995 1.1 christos #define LOW_HI_ORDER 0xF800F000 996 1.1 christos #define HI_LOW_ORDER 0xF000F800 997 1.1 christos 998 1.1 christos static insn32 999 1.1 christos insert_thumb_branch (insn32 br_insn, int rel_off) 1000 1.1 christos { 1001 1.1 christos unsigned int low_bits; 1002 1.1 christos unsigned int high_bits; 1003 1.1 christos 1004 1.1 christos BFD_ASSERT ((rel_off & 1) != 1); 1005 1.8 christos 1006 1.8 christos rel_off >>= 1; /* Half word aligned address. */ 1007 1.1 christos low_bits = rel_off & 0x000007FF; /* The bottom 11 bits. */ 1008 1.1 christos high_bits = (rel_off >> 11) & 0x000007FF; /* The top 11 bits. */ 1009 1.1 christos 1010 1.1 christos if ((br_insn & LOW_HI_ORDER) == LOW_HI_ORDER) 1011 1.1 christos br_insn = LOW_HI_ORDER | (low_bits << 16) | high_bits; 1012 1.1 christos else if ((br_insn & HI_LOW_ORDER) == HI_LOW_ORDER) 1013 1.1 christos br_insn = HI_LOW_ORDER | (high_bits << 16) | low_bits; 1014 1.1 christos else 1015 1.1 christos /* FIXME: the BFD library should never abort except for internal errors 1016 1.1 christos - it should return an error status. */ 1017 1.1 christos abort (); /* Error - not a valid branch instruction form. */ 1018 1.1 christos 1019 1.1 christos return br_insn; 1020 1.1 christos } 1021 1.1 christos 1022 1.1 christos 1023 1.1 christos static struct coff_link_hash_entry * 1025 1.1 christos find_thumb_glue (struct bfd_link_info *info, 1026 1.1 christos const char *name, 1027 1.1 christos bfd *input_bfd) 1028 1.1 christos { 1029 1.9 christos char *tmp_name; 1030 1.1 christos struct coff_link_hash_entry *myh; 1031 1.1 christos size_t amt = strlen (name) + strlen (THUMB2ARM_GLUE_ENTRY_NAME) + 1; 1032 1.1 christos 1033 1.1 christos tmp_name = bfd_malloc (amt); 1034 1.1 christos 1035 1.1 christos BFD_ASSERT (tmp_name); 1036 1.1 christos 1037 1.1 christos sprintf (tmp_name, THUMB2ARM_GLUE_ENTRY_NAME, name); 1038 1.10 christos 1039 1.1 christos myh = coff_link_hash_lookup 1040 1.1 christos (coff_hash_table (info), tmp_name, false, false, true); 1041 1.1 christos 1042 1.8 christos if (myh == NULL) 1043 1.1 christos /* xgettext:c-format */ 1044 1.1 christos _bfd_error_handler (_("%pB: unable to find THUMB glue '%s' for `%s'"), 1045 1.1 christos input_bfd, tmp_name, name); 1046 1.1 christos 1047 1.1 christos free (tmp_name); 1048 1.1 christos 1049 1.1 christos return myh; 1050 1.1 christos } 1051 1.1 christos #endif /* not ARM_WINCE */ 1052 1.1 christos 1053 1.1 christos static struct coff_link_hash_entry * 1054 1.1 christos find_arm_glue (struct bfd_link_info *info, 1055 1.1 christos const char *name, 1056 1.1 christos bfd *input_bfd) 1057 1.1 christos { 1058 1.9 christos char *tmp_name; 1059 1.1 christos struct coff_link_hash_entry * myh; 1060 1.1 christos size_t amt = strlen (name) + strlen (ARM2THUMB_GLUE_ENTRY_NAME) + 1; 1061 1.1 christos 1062 1.1 christos tmp_name = bfd_malloc (amt); 1063 1.1 christos 1064 1.1 christos BFD_ASSERT (tmp_name); 1065 1.1 christos 1066 1.1 christos sprintf (tmp_name, ARM2THUMB_GLUE_ENTRY_NAME, name); 1067 1.10 christos 1068 1.1 christos myh = coff_link_hash_lookup 1069 1.1 christos (coff_hash_table (info), tmp_name, false, false, true); 1070 1.1 christos 1071 1.8 christos if (myh == NULL) 1072 1.1 christos /* xgettext:c-format */ 1073 1.1 christos _bfd_error_handler (_("%pB: unable to find ARM glue '%s' for `%s'"), 1074 1.1 christos input_bfd, tmp_name, name); 1075 1.1 christos 1076 1.1 christos free (tmp_name); 1077 1.1 christos 1078 1.1 christos return myh; 1079 1.1 christos } 1080 1.1 christos 1081 1.1 christos /* 1082 1.1 christos ARM->Thumb glue: 1083 1.1 christos 1084 1.1 christos .arm 1085 1.1 christos __func_from_arm: 1086 1.1 christos ldr r12, __func_addr 1087 1.8 christos bx r12 1088 1.1 christos __func_addr: 1089 1.1 christos .word func @ behave as if you saw a ARM_32 reloc 1090 1.1 christos */ 1091 1.1 christos 1092 1.1 christos #define ARM2THUMB_GLUE_SIZE 12 1093 1.1 christos static const insn32 a2t1_ldr_insn = 0xe59fc000; 1094 1.1 christos static const insn32 a2t2_bx_r12_insn = 0xe12fff1c; 1095 1.1 christos static const insn32 a2t3_func_addr_insn = 0x00000001; 1096 1.1 christos 1097 1.1 christos /* 1098 1.1 christos Thumb->ARM: Thumb->(non-interworking aware) ARM 1099 1.1 christos 1100 1.1 christos .thumb .thumb 1101 1.1 christos .align 2 .align 2 1102 1.1 christos __func_from_thumb: __func_from_thumb: 1103 1.1 christos bx pc push {r6, lr} 1104 1.1 christos nop ldr r6, __func_addr 1105 1.8 christos .arm mov lr, pc 1106 1.1 christos __func_change_to_arm: bx r6 1107 1.8 christos b func .arm 1108 1.8 christos __func_back_to_thumb: 1109 1.8 christos ldmia r13! {r6, lr} 1110 1.8 christos bx lr 1111 1.1 christos __func_addr: 1112 1.1 christos .word func 1113 1.1 christos */ 1114 1.1 christos 1115 1.1 christos #define THUMB2ARM_GLUE_SIZE (globals->support_old_code ? 20 : 8) 1116 1.1 christos #ifndef ARM_WINCE 1117 1.1 christos static const insn16 t2a1_bx_pc_insn = 0x4778; 1118 1.1 christos static const insn16 t2a2_noop_insn = 0x46c0; 1119 1.1 christos static const insn32 t2a3_b_insn = 0xea000000; 1120 1.1 christos 1121 1.1 christos static const insn16 t2a1_push_insn = 0xb540; 1122 1.1 christos static const insn16 t2a2_ldr_insn = 0x4e03; 1123 1.1 christos static const insn16 t2a3_mov_insn = 0x46fe; 1124 1.1 christos static const insn16 t2a4_bx_insn = 0x4730; 1125 1.1 christos static const insn32 t2a5_pop_insn = 0xe8bd4040; 1126 1.1 christos static const insn32 t2a6_bx_insn = 0xe12fff1e; 1127 1.1 christos #endif 1128 1.1 christos 1129 1.1 christos /* TODO: 1130 1.1 christos We should really create new local (static) symbols in destination 1131 1.1 christos object for each stub we create. We should also create local 1132 1.1 christos (static) symbols within the stubs when switching between ARM and 1133 1.1 christos Thumb code. This will ensure that the debugger and disassembler 1134 1.1 christos can present a better view of stubs. 1135 1.1 christos 1136 1.1 christos We can treat stubs like literal sections, and for the THUMB9 ones 1137 1.1 christos (short addressing range) we should be able to insert the stubs 1138 1.1 christos between sections. i.e. the simplest approach (since relocations 1139 1.1 christos are done on a section basis) is to dump the stubs at the end of 1140 1.1 christos processing a section. That way we can always try and minimise the 1141 1.1 christos offset to and from a stub. However, this does not map well onto 1142 1.1 christos the way that the linker/BFD does its work: mapping all input 1143 1.1 christos sections to output sections via the linker script before doing 1144 1.1 christos all the processing. 1145 1.1 christos 1146 1.1 christos Unfortunately it may be easier to just to disallow short range 1147 1.1 christos Thumb->ARM stubs (i.e. no conditional inter-working branches, 1148 1.1 christos only branch-and-link (BL) calls. This will simplify the processing 1149 1.1 christos since we can then put all of the stubs into their own section. 1150 1.1 christos 1151 1.1 christos TODO: 1152 1.1 christos On a different subject, rather than complaining when a 1153 1.1 christos branch cannot fit in the number of bits available for the 1154 1.1 christos instruction we should generate a trampoline stub (needed to 1155 1.1 christos address the complete 32bit address space). */ 1156 1.1 christos 1157 1.9 christos /* The standard COFF backend linker does not cope with the special 1158 1.1 christos Thumb BRANCH23 relocation. The alternative would be to split the 1159 1.1 christos BRANCH23 into separate HI23 and LO23 relocations. However, it is a 1160 1.1 christos bit simpler simply providing our own relocation driver. */ 1161 1.1 christos 1162 1.1 christos /* The reloc processing routine for the ARM/Thumb COFF linker. NOTE: 1163 1.1 christos This code is a very slightly modified copy of 1164 1.1 christos _bfd_coff_generic_relocate_section. It would be a much more 1165 1.1 christos maintainable solution to have a MACRO that could be expanded within 1166 1.1 christos _bfd_coff_generic_relocate_section that would only be provided for 1167 1.1 christos ARM/Thumb builds. It is only the code marked THUMBEXTENSION that 1168 1.10 christos is different from the original. */ 1169 1.1 christos 1170 1.1 christos static bool 1171 1.1 christos coff_arm_relocate_section (bfd *output_bfd, 1172 1.1 christos struct bfd_link_info *info, 1173 1.1 christos bfd *input_bfd, 1174 1.1 christos asection *input_section, 1175 1.1 christos bfd_byte *contents, 1176 1.1 christos struct internal_reloc *relocs, 1177 1.1 christos struct internal_syment *syms, 1178 1.1 christos asection **sections) 1179 1.1 christos { 1180 1.1 christos struct internal_reloc * rel; 1181 1.1 christos struct internal_reloc * relend; 1182 1.1 christos #ifndef ARM_WINCE 1183 1.1 christos bfd_vma high_address = bfd_get_section_limit (input_bfd, input_section); 1184 1.1 christos #endif 1185 1.1 christos 1186 1.1 christos rel = relocs; 1187 1.1 christos relend = rel + input_section->reloc_count; 1188 1.1 christos 1189 1.8 christos for (; rel < relend; rel++) 1190 1.8 christos { 1191 1.1 christos int done = 0; 1192 1.8 christos long symndx; 1193 1.8 christos struct coff_link_hash_entry * h; 1194 1.8 christos struct internal_syment * sym; 1195 1.8 christos bfd_vma addend; 1196 1.8 christos bfd_vma val; 1197 1.8 christos reloc_howto_type * howto; 1198 1.1 christos bfd_reloc_status_type rstat; 1199 1.1 christos bfd_vma h_val; 1200 1.1 christos 1201 1.1 christos symndx = rel->r_symndx; 1202 1.1 christos 1203 1.1 christos if (symndx == -1) 1204 1.1 christos { 1205 1.1 christos h = NULL; 1206 1.1 christos sym = NULL; 1207 1.1 christos } 1208 1.1 christos else 1209 1.1 christos { 1210 1.1 christos h = obj_coff_sym_hashes (input_bfd)[symndx]; 1211 1.1 christos sym = syms + symndx; 1212 1.1 christos } 1213 1.8 christos 1214 1.8 christos /* COFF treats common symbols in one of two ways. Either the 1215 1.8 christos size of the symbol is included in the section contents, or it 1216 1.1 christos is not. We assume that the size is not included, and force 1217 1.1 christos the rtype_to_howto function to adjust the addend as needed. */ 1218 1.1 christos 1219 1.1 christos if (sym != NULL && sym->n_scnum != 0) 1220 1.1 christos addend = - sym->n_value; 1221 1.1 christos else 1222 1.1 christos addend = 0; 1223 1.1 christos 1224 1.1 christos howto = coff_rtype_to_howto (input_bfd, input_section, rel, h, 1225 1.10 christos sym, &addend); 1226 1.1 christos if (howto == NULL) 1227 1.1 christos return false; 1228 1.8 christos 1229 1.8 christos /* The relocation_section function will skip pcrel_offset relocs 1230 1.8 christos when doing a relocatable link. However, we want to convert 1231 1.8 christos ARM_26 to ARM_26D relocs if possible. We return a fake howto in 1232 1.8 christos this case without pcrel_offset set, and adjust the addend to 1233 1.1 christos compensate. 'partial_inplace' is also set, since we want 'done' 1234 1.8 christos relocations to be reflected in section's data. */ 1235 1.8 christos if (rel->r_type == ARM_26 1236 1.8 christos && h != NULL 1237 1.1 christos && bfd_link_relocatable (info) 1238 1.8 christos && (h->root.type == bfd_link_hash_defined 1239 1.1 christos || h->root.type == bfd_link_hash_defweak) 1240 1.8 christos && (h->root.u.def.section->output_section 1241 1.8 christos == input_section->output_section)) 1242 1.1 christos { 1243 1.8 christos static reloc_howto_type fake_arm26_reloc = 1244 1.10 christos HOWTO (ARM_26, 1245 1.8 christos 2, 1246 1.10 christos 4, 1247 1.8 christos 24, 1248 1.8 christos true, 1249 1.8 christos 0, 1250 1.8 christos complain_overflow_signed, 1251 1.10 christos aoutarm_fix_pcrel_26 , 1252 1.8 christos "ARM_26", 1253 1.8 christos true, 1254 1.10 christos 0x00ffffff, 1255 1.1 christos 0x00ffffff, 1256 1.8 christos false); 1257 1.1 christos 1258 1.8 christos addend -= rel->r_vaddr - input_section->vma; 1259 1.8 christos #ifdef ARM_WINCE 1260 1.8 christos /* FIXME: I don't know why, but the hack is necessary for correct 1261 1.1 christos generation of bl's instruction offset. */ 1262 1.8 christos addend -= 8; 1263 1.8 christos #endif 1264 1.1 christos howto = & fake_arm26_reloc; 1265 1.1 christos } 1266 1.1 christos 1267 1.1 christos #ifdef ARM_WINCE 1268 1.6 christos /* MS ARM-CE makes the reloc relative to the opcode's pc, not 1269 1.1 christos the next opcode's pc, so is off by one. */ 1270 1.1 christos if (howto->pc_relative && !bfd_link_relocatable (info)) 1271 1.1 christos addend -= 8; 1272 1.1 christos #endif 1273 1.8 christos 1274 1.8 christos /* If we are doing a relocatable link, then we can just ignore 1275 1.8 christos a PC relative reloc that is pcrel_offset. It will already 1276 1.1 christos have the correct value. If this is not a relocatable link, 1277 1.8 christos then we should ignore the symbol value. */ 1278 1.8 christos if (howto->pc_relative && howto->pcrel_offset) 1279 1.8 christos { 1280 1.1 christos if (bfd_link_relocatable (info)) 1281 1.1 christos continue; 1282 1.8 christos /* FIXME - it is not clear which targets need this next test 1283 1.8 christos and which do not. It is known that it is needed for the 1284 1.1 christos VxWorks targets but it is also known that it was suppressed 1285 1.1 christos for other ARM targets. This ought to be sorted out one day. */ 1286 1.1 christos #ifdef ARM_COFF_BUGFIX 1287 1.1 christos /* We must not ignore the symbol value. If the symbol is 1288 1.1 christos within the same section, the relocation should have already 1289 1.1 christos been fixed, but if it is not, we'll be handed a reloc into 1290 1.1 christos the beginning of the symbol's section, so we must not cancel 1291 1.8 christos out the symbol's value, otherwise we'll be adding it in 1292 1.8 christos twice. */ 1293 1.1 christos if (sym != NULL && sym->n_scnum != 0) 1294 1.8 christos addend += sym->n_value; 1295 1.1 christos #endif 1296 1.1 christos } 1297 1.1 christos 1298 1.1 christos val = 0; 1299 1.1 christos 1300 1.1 christos if (h == NULL) 1301 1.1 christos { 1302 1.1 christos asection *sec; 1303 1.1 christos 1304 1.1 christos if (symndx == -1) 1305 1.1 christos { 1306 1.1 christos sec = bfd_abs_section_ptr; 1307 1.1 christos val = 0; 1308 1.1 christos } 1309 1.1 christos else 1310 1.8 christos { 1311 1.1 christos sec = sections[symndx]; 1312 1.1 christos val = (sec->output_section->vma 1313 1.1 christos + sec->output_offset 1314 1.1 christos + sym->n_value 1315 1.1 christos - sec->vma); 1316 1.1 christos } 1317 1.1 christos } 1318 1.8 christos else 1319 1.8 christos { 1320 1.8 christos /* We don't output the stubs if we are generating a 1321 1.1 christos relocatable output file, since we may as well leave the 1322 1.1 christos stub generation to the final linker pass. If we fail to 1323 1.8 christos verify that the name is defined, we'll try to build stubs 1324 1.1 christos for an undefined name... */ 1325 1.1 christos if (! bfd_link_relocatable (info) 1326 1.8 christos && ( h->root.type == bfd_link_hash_defined 1327 1.1 christos || h->root.type == bfd_link_hash_defweak)) 1328 1.1 christos { 1329 1.1 christos asection * h_sec = h->root.u.def.section; 1330 1.1 christos const char * name = h->root.root.string; 1331 1.1 christos 1332 1.1 christos /* h locates the symbol referenced in the reloc. */ 1333 1.1 christos h_val = (h->root.u.def.value 1334 1.1 christos + h_sec->output_section->vma 1335 1.8 christos + h_sec->output_offset); 1336 1.8 christos 1337 1.8 christos if (howto->type == ARM_26) 1338 1.1 christos { 1339 1.1 christos if ( h->symbol_class == C_THUMBSTATFUNC 1340 1.1 christos || h->symbol_class == C_THUMBEXTFUNC) 1341 1.8 christos { 1342 1.8 christos /* Arm code calling a Thumb function. */ 1343 1.8 christos unsigned long int tmp; 1344 1.8 christos bfd_vma my_offset; 1345 1.8 christos asection * s; 1346 1.1 christos long int ret_offset; 1347 1.1 christos struct coff_link_hash_entry * myh; 1348 1.1 christos struct coff_arm_link_hash_table * globals; 1349 1.1 christos 1350 1.10 christos myh = find_arm_glue (info, name, input_bfd); 1351 1.1 christos if (myh == NULL) 1352 1.1 christos return false; 1353 1.1 christos 1354 1.1 christos globals = coff_arm_hash_table (info); 1355 1.1 christos 1356 1.1 christos BFD_ASSERT (globals != NULL); 1357 1.1 christos BFD_ASSERT (globals->bfd_of_glue_owner != NULL); 1358 1.1 christos 1359 1.1 christos my_offset = myh->root.u.def.value; 1360 1.1 christos 1361 1.1 christos s = bfd_get_section_by_name (globals->bfd_of_glue_owner, 1362 1.1 christos ARM2THUMB_GLUE_SECTION_NAME); 1363 1.1 christos BFD_ASSERT (s != NULL); 1364 1.1 christos BFD_ASSERT (s->contents != NULL); 1365 1.1 christos BFD_ASSERT (s->output_section != NULL); 1366 1.1 christos 1367 1.1 christos if ((my_offset & 0x01) == 0x01) 1368 1.1 christos { 1369 1.1 christos if (h_sec->owner != NULL 1370 1.1 christos && INTERWORK_SET (h_sec->owner) 1371 1.1 christos && ! INTERWORK_FLAG (h_sec->owner)) 1372 1.8 christos _bfd_error_handler 1373 1.8 christos /* xgettext:c-format */ 1374 1.7 christos (_("%pB(%s): warning: interworking not enabled; " 1375 1.1 christos "first occurrence: %pB: arm call to thumb"), 1376 1.1 christos h_sec->owner, name, input_bfd); 1377 1.1 christos 1378 1.1 christos --my_offset; 1379 1.1 christos myh->root.u.def.value = my_offset; 1380 1.1 christos 1381 1.1 christos bfd_put_32 (output_bfd, (bfd_vma) a2t1_ldr_insn, 1382 1.1 christos s->contents + my_offset); 1383 1.1 christos 1384 1.1 christos bfd_put_32 (output_bfd, (bfd_vma) a2t2_bx_r12_insn, 1385 1.1 christos s->contents + my_offset + 4); 1386 1.1 christos 1387 1.1 christos /* It's a thumb address. Add the low order bit. */ 1388 1.1 christos bfd_put_32 (output_bfd, h_val | a2t3_func_addr_insn, 1389 1.8 christos s->contents + my_offset + 8); 1390 1.1 christos 1391 1.1 christos if (info->base_file 1392 1.10 christos && !arm_emit_base_file_entry (info, output_bfd, 1393 1.1 christos s, my_offset + 8)) 1394 1.1 christos return false; 1395 1.1 christos } 1396 1.1 christos 1397 1.1 christos BFD_ASSERT (my_offset <= globals->arm_glue_size); 1398 1.1 christos 1399 1.1 christos tmp = bfd_get_32 (input_bfd, contents + rel->r_vaddr 1400 1.1 christos - input_section->vma); 1401 1.1 christos 1402 1.1 christos tmp = tmp & 0xFF000000; 1403 1.1 christos 1404 1.1 christos /* Somehow these are both 4 too far, so subtract 8. */ 1405 1.1 christos ret_offset = 1406 1.1 christos s->output_offset 1407 1.1 christos + my_offset 1408 1.1 christos + s->output_section->vma 1409 1.1 christos - (input_section->output_offset 1410 1.1 christos + input_section->output_section->vma 1411 1.1 christos + rel->r_vaddr) 1412 1.1 christos - 8; 1413 1.1 christos 1414 1.1 christos tmp = tmp | ((ret_offset >> 2) & 0x00FFFFFF); 1415 1.1 christos 1416 1.1 christos bfd_put_32 (output_bfd, (bfd_vma) tmp, 1417 1.1 christos contents + rel->r_vaddr - input_section->vma); 1418 1.8 christos done = 1; 1419 1.1 christos } 1420 1.1 christos } 1421 1.1 christos 1422 1.8 christos #ifndef ARM_WINCE 1423 1.8 christos /* Note: We used to check for ARM_THUMB9 and ARM_THUMB12. */ 1424 1.8 christos else if (howto->type == ARM_THUMB23) 1425 1.1 christos { 1426 1.1 christos if ( h->symbol_class == C_EXT 1427 1.1 christos || h->symbol_class == C_STAT 1428 1.1 christos || h->symbol_class == C_LABEL) 1429 1.8 christos { 1430 1.8 christos /* Thumb code calling an ARM function. */ 1431 1.8 christos asection * s = 0; 1432 1.8 christos bfd_vma my_offset; 1433 1.8 christos unsigned long int tmp; 1434 1.8 christos long int ret_offset; 1435 1.1 christos struct coff_link_hash_entry * myh; 1436 1.1 christos struct coff_arm_link_hash_table * globals; 1437 1.1 christos 1438 1.10 christos myh = find_thumb_glue (info, name, input_bfd); 1439 1.1 christos if (myh == NULL) 1440 1.1 christos return false; 1441 1.1 christos 1442 1.1 christos globals = coff_arm_hash_table (info); 1443 1.1 christos 1444 1.1 christos BFD_ASSERT (globals != NULL); 1445 1.1 christos BFD_ASSERT (globals->bfd_of_glue_owner != NULL); 1446 1.1 christos 1447 1.1 christos my_offset = myh->root.u.def.value; 1448 1.1 christos 1449 1.1 christos s = bfd_get_section_by_name (globals->bfd_of_glue_owner, 1450 1.1 christos THUMB2ARM_GLUE_SECTION_NAME); 1451 1.1 christos 1452 1.1 christos BFD_ASSERT (s != NULL); 1453 1.1 christos BFD_ASSERT (s->contents != NULL); 1454 1.1 christos BFD_ASSERT (s->output_section != NULL); 1455 1.1 christos 1456 1.1 christos if ((my_offset & 0x01) == 0x01) 1457 1.1 christos { 1458 1.1 christos if (h_sec->owner != NULL 1459 1.1 christos && INTERWORK_SET (h_sec->owner) 1460 1.1 christos && ! INTERWORK_FLAG (h_sec->owner) 1461 1.1 christos && ! globals->support_old_code) 1462 1.8 christos _bfd_error_handler 1463 1.8 christos /* xgettext:c-format */ 1464 1.8 christos (_("%pB(%s): warning: interworking not enabled; " 1465 1.8 christos "first occurrence: %pB: thumb call to arm; " 1466 1.7 christos "consider relinking with --support-old-code " 1467 1.1 christos "enabled"), 1468 1.1 christos h_sec->owner, name, input_bfd); 1469 1.1 christos 1470 1.1 christos -- my_offset; 1471 1.1 christos myh->root.u.def.value = my_offset; 1472 1.1 christos 1473 1.1 christos if (globals->support_old_code) 1474 1.1 christos { 1475 1.1 christos bfd_put_16 (output_bfd, (bfd_vma) t2a1_push_insn, 1476 1.1 christos s->contents + my_offset); 1477 1.1 christos 1478 1.1 christos bfd_put_16 (output_bfd, (bfd_vma) t2a2_ldr_insn, 1479 1.1 christos s->contents + my_offset + 2); 1480 1.1 christos 1481 1.1 christos bfd_put_16 (output_bfd, (bfd_vma) t2a3_mov_insn, 1482 1.1 christos s->contents + my_offset + 4); 1483 1.1 christos 1484 1.1 christos bfd_put_16 (output_bfd, (bfd_vma) t2a4_bx_insn, 1485 1.1 christos s->contents + my_offset + 6); 1486 1.1 christos 1487 1.1 christos bfd_put_32 (output_bfd, (bfd_vma) t2a5_pop_insn, 1488 1.1 christos s->contents + my_offset + 8); 1489 1.1 christos 1490 1.1 christos bfd_put_32 (output_bfd, (bfd_vma) t2a6_bx_insn, 1491 1.1 christos s->contents + my_offset + 12); 1492 1.1 christos 1493 1.1 christos /* Store the address of the function in the last word of the stub. */ 1494 1.1 christos bfd_put_32 (output_bfd, h_val, 1495 1.8 christos s->contents + my_offset + 16); 1496 1.1 christos 1497 1.1 christos if (info->base_file 1498 1.1 christos && !arm_emit_base_file_entry (info, 1499 1.10 christos output_bfd, s, 1500 1.1 christos my_offset + 16)) 1501 1.1 christos return false; 1502 1.1 christos } 1503 1.1 christos else 1504 1.1 christos { 1505 1.1 christos bfd_put_16 (output_bfd, (bfd_vma) t2a1_bx_pc_insn, 1506 1.1 christos s->contents + my_offset); 1507 1.1 christos 1508 1.1 christos bfd_put_16 (output_bfd, (bfd_vma) t2a2_noop_insn, 1509 1.1 christos s->contents + my_offset + 2); 1510 1.1 christos 1511 1.1 christos ret_offset = 1512 1.1 christos /* Address of destination of the stub. */ 1513 1.1 christos ((bfd_signed_vma) h_val) 1514 1.1 christos - ((bfd_signed_vma) 1515 1.1 christos /* Offset from the start of the current section to the start of the stubs. */ 1516 1.1 christos (s->output_offset 1517 1.1 christos /* Offset of the start of this stub from the start of the stubs. */ 1518 1.1 christos + my_offset 1519 1.1 christos /* Address of the start of the current section. */ 1520 1.1 christos + s->output_section->vma) 1521 1.1 christos /* The branch instruction is 4 bytes into the stub. */ 1522 1.1 christos + 4 1523 1.1 christos /* ARM branches work from the pc of the instruction + 8. */ 1524 1.1 christos + 8); 1525 1.1 christos 1526 1.1 christos bfd_put_32 (output_bfd, 1527 1.1 christos (bfd_vma) t2a3_b_insn | ((ret_offset >> 2) & 0x00FFFFFF), 1528 1.1 christos s->contents + my_offset + 4); 1529 1.1 christos 1530 1.1 christos } 1531 1.1 christos } 1532 1.1 christos 1533 1.1 christos BFD_ASSERT (my_offset <= globals->thumb_glue_size); 1534 1.1 christos 1535 1.1 christos /* Now go back and fix up the original BL insn to point 1536 1.1 christos to here. */ 1537 1.1 christos ret_offset = 1538 1.1 christos s->output_offset 1539 1.1 christos + my_offset 1540 1.1 christos - (input_section->output_offset 1541 1.1 christos + rel->r_vaddr) 1542 1.1 christos -4; 1543 1.1 christos 1544 1.1 christos tmp = bfd_get_32 (input_bfd, contents + rel->r_vaddr 1545 1.1 christos - input_section->vma); 1546 1.1 christos 1547 1.1 christos bfd_put_32 (output_bfd, 1548 1.1 christos (bfd_vma) insert_thumb_branch (tmp, 1549 1.1 christos ret_offset), 1550 1.1 christos contents + rel->r_vaddr - input_section->vma); 1551 1.8 christos 1552 1.8 christos done = 1; 1553 1.1 christos } 1554 1.8 christos } 1555 1.1 christos #endif 1556 1.8 christos } 1557 1.8 christos 1558 1.8 christos /* If the relocation type and destination symbol does not 1559 1.1 christos fall into one of the above categories, then we can just 1560 1.1 christos perform a direct link. */ 1561 1.1 christos 1562 1.1 christos if (done) 1563 1.1 christos rstat = bfd_reloc_ok; 1564 1.1 christos else 1565 1.1 christos if ( h->root.type == bfd_link_hash_defined 1566 1.1 christos || h->root.type == bfd_link_hash_defweak) 1567 1.1 christos { 1568 1.1 christos asection *sec; 1569 1.1 christos 1570 1.1 christos sec = h->root.u.def.section; 1571 1.1 christos val = (h->root.u.def.value 1572 1.1 christos + sec->output_section->vma 1573 1.1 christos + sec->output_offset); 1574 1.6 christos } 1575 1.6 christos 1576 1.6 christos else if (! bfd_link_relocatable (info)) 1577 1.10 christos (*info->callbacks->undefined_symbol) 1578 1.1 christos (info, h->root.root.string, input_bfd, input_section, 1579 1.1 christos rel->r_vaddr - input_section->vma, true); 1580 1.1 christos } 1581 1.1 christos 1582 1.1 christos /* Emit a reloc if the backend thinks it needs it. */ 1583 1.1 christos if (info->base_file 1584 1.1 christos && sym 1585 1.1 christos && pe_data(output_bfd)->in_reloc_p(output_bfd, howto) 1586 1.10 christos && !arm_emit_base_file_entry (info, output_bfd, input_section, 1587 1.1 christos rel->r_vaddr)) 1588 1.1 christos return false; 1589 1.1 christos 1590 1.1 christos if (done) 1591 1.1 christos rstat = bfd_reloc_ok; 1592 1.6 christos #ifndef ARM_WINCE 1593 1.1 christos /* Only perform this fix during the final link, not a relocatable link. */ 1594 1.8 christos else if (! bfd_link_relocatable (info) 1595 1.8 christos && howto->type == ARM_THUMB23) 1596 1.8 christos { 1597 1.8 christos /* This is pretty much a copy of what the default 1598 1.8 christos _bfd_final_link_relocate and _bfd_relocate_contents 1599 1.8 christos routines do to perform a relocation, with special 1600 1.8 christos processing for the split addressing of the Thumb BL 1601 1.8 christos instruction. Again, it would probably be simpler adding a 1602 1.1 christos ThumbBRANCH23 specific macro expansion into the default 1603 1.8 christos code. */ 1604 1.1 christos 1605 1.1 christos bfd_vma address = rel->r_vaddr - input_section->vma; 1606 1.1 christos 1607 1.8 christos if (address > high_address) 1608 1.8 christos rstat = bfd_reloc_outofrange; 1609 1.8 christos else 1610 1.1 christos { 1611 1.10 christos bfd_vma relocation = val + addend; 1612 1.1 christos int size = bfd_get_reloc_size (howto); 1613 1.1 christos bool overflow = false; 1614 1.1 christos bfd_byte *location = contents + address; 1615 1.1 christos bfd_vma x = bfd_get_32 (input_bfd, location); 1616 1.1 christos bfd_vma src_mask = 0x007FFFFE; 1617 1.1 christos bfd_signed_vma reloc_signed_max = (1 << (howto->bitsize - 1)) - 1; 1618 1.1 christos bfd_signed_vma reloc_signed_min = ~reloc_signed_max; 1619 1.1 christos bfd_vma check; 1620 1.1 christos bfd_signed_vma signed_check; 1621 1.1 christos bfd_vma add; 1622 1.1 christos bfd_signed_vma signed_add; 1623 1.1 christos 1624 1.8 christos BFD_ASSERT (size == 4); 1625 1.8 christos 1626 1.8 christos /* howto->pc_relative should be TRUE for type 14 BRANCH23. */ 1627 1.1 christos relocation -= (input_section->output_section->vma 1628 1.8 christos + input_section->output_offset); 1629 1.8 christos 1630 1.1 christos /* howto->pcrel_offset should be TRUE for type 14 BRANCH23. */ 1631 1.1 christos relocation -= address; 1632 1.1 christos 1633 1.1 christos /* No need to negate the relocation with BRANCH23. */ 1634 1.1 christos /* howto->complain_on_overflow == complain_overflow_signed for BRANCH23. */ 1635 1.1 christos /* howto->rightshift == 1 */ 1636 1.1 christos 1637 1.1 christos /* Drop unwanted bits from the value we are relocating to. */ 1638 1.1 christos check = relocation >> howto->rightshift; 1639 1.1 christos 1640 1.1 christos /* If this is a signed value, the rightshift just dropped 1641 1.1 christos leading 1 bits (assuming twos complement). */ 1642 1.1 christos if ((bfd_signed_vma) relocation >= 0) 1643 1.1 christos signed_check = check; 1644 1.1 christos else 1645 1.1 christos signed_check = (check 1646 1.1 christos | ((bfd_vma) - 1 1647 1.1 christos & ~((bfd_vma) - 1 >> howto->rightshift))); 1648 1.1 christos 1649 1.1 christos /* Get the value from the object file. */ 1650 1.1 christos if (bfd_big_endian (input_bfd)) 1651 1.1 christos add = (((x) & 0x07ff0000) >> 4) | (((x) & 0x7ff) << 1); 1652 1.1 christos else 1653 1.1 christos add = ((((x) & 0x7ff) << 12) | (((x) & 0x07ff0000) >> 15)); 1654 1.1 christos 1655 1.1 christos /* Get the value from the object file with an appropriate sign. 1656 1.1 christos The expression involving howto->src_mask isolates the upper 1657 1.1 christos bit of src_mask. If that bit is set in the value we are 1658 1.1 christos adding, it is negative, and we subtract out that number times 1659 1.1 christos two. If src_mask includes the highest possible bit, then we 1660 1.1 christos can not get the upper bit, but that does not matter since 1661 1.1 christos signed_add needs no adjustment to become negative in that 1662 1.1 christos case. */ 1663 1.1 christos signed_add = add; 1664 1.1 christos 1665 1.1 christos if ((add & (((~ src_mask) >> 1) & src_mask)) != 0) 1666 1.1 christos signed_add -= (((~ src_mask) >> 1) & src_mask) << 1; 1667 1.1 christos 1668 1.1 christos /* howto->bitpos == 0 */ 1669 1.1 christos /* Add the value from the object file, shifted so that it is a 1670 1.1 christos straight number. */ 1671 1.1 christos signed_check += signed_add; 1672 1.1 christos relocation += signed_add; 1673 1.1 christos 1674 1.1 christos BFD_ASSERT (howto->complain_on_overflow == complain_overflow_signed); 1675 1.1 christos 1676 1.1 christos /* Assumes two's complement. */ 1677 1.10 christos if ( signed_check > reloc_signed_max 1678 1.1 christos || signed_check < reloc_signed_min) 1679 1.1 christos overflow = true; 1680 1.1 christos 1681 1.1 christos /* Put the relocation into the correct bits. 1682 1.1 christos For a BLX instruction, make sure that the relocation is rounded up 1683 1.1 christos to a word boundary. This follows the semantics of the instruction 1684 1.1 christos which specifies that bit 1 of the target address will come from bit 1685 1.8 christos 1 of the base address. */ 1686 1.1 christos if (bfd_big_endian (input_bfd)) 1687 1.1 christos { 1688 1.1 christos if ((x & 0x1800) == 0x0800 && (relocation & 0x02)) 1689 1.1 christos relocation += 2; 1690 1.1 christos relocation = (((relocation & 0xffe) >> 1) | ((relocation << 4) & 0x07ff0000)); 1691 1.8 christos } 1692 1.1 christos else 1693 1.1 christos { 1694 1.1 christos if ((x & 0x18000000) == 0x08000000 && (relocation & 0x02)) 1695 1.1 christos relocation += 2; 1696 1.1 christos relocation = (((relocation & 0xffe) << 15) | ((relocation >> 12) & 0x7ff)); 1697 1.1 christos } 1698 1.1 christos 1699 1.1 christos /* Add the relocation to the correct bits of X. */ 1700 1.1 christos x = ((x & ~howto->dst_mask) | relocation); 1701 1.1 christos 1702 1.1 christos /* Put the relocated value back in the object file. */ 1703 1.1 christos bfd_put_32 (input_bfd, x, location); 1704 1.8 christos 1705 1.8 christos rstat = overflow ? bfd_reloc_overflow : bfd_reloc_ok; 1706 1.1 christos } 1707 1.1 christos } 1708 1.8 christos #endif 1709 1.8 christos else 1710 1.8 christos if (bfd_link_relocatable (info) && ! howto->partial_inplace) 1711 1.1 christos rstat = bfd_reloc_ok; 1712 1.1 christos else 1713 1.1 christos rstat = _bfd_final_link_relocate (howto, input_bfd, input_section, 1714 1.1 christos contents, 1715 1.1 christos rel->r_vaddr - input_section->vma, 1716 1.6 christos val, addend); 1717 1.1 christos /* Only perform this fix during the final link, not a relocatable link. */ 1718 1.1 christos if (! bfd_link_relocatable (info) 1719 1.1 christos && (rel->r_type == ARM_32 || rel->r_type == ARM_RVA32)) 1720 1.1 christos { 1721 1.10 christos /* Determine if we need to set the bottom bit of a relocated address 1722 1.1 christos because the address is the address of a Thumb code symbol. */ 1723 1.1 christos int patchit = false; 1724 1.1 christos 1725 1.1 christos if (h != NULL 1726 1.1 christos && ( h->symbol_class == C_THUMBSTATFUNC 1727 1.10 christos || h->symbol_class == C_THUMBEXTFUNC)) 1728 1.1 christos { 1729 1.1 christos patchit = true; 1730 1.1 christos } 1731 1.1 christos else if (sym != NULL 1732 1.1 christos && sym->n_scnum > N_UNDEF) 1733 1.1 christos { 1734 1.1 christos /* No hash entry - use the symbol instead. */ 1735 1.10 christos if ( sym->n_sclass == C_THUMBSTATFUNC 1736 1.1 christos || sym->n_sclass == C_THUMBEXTFUNC) 1737 1.1 christos patchit = true; 1738 1.1 christos } 1739 1.1 christos 1740 1.1 christos if (patchit) 1741 1.8 christos { 1742 1.1 christos bfd_byte * location = contents + rel->r_vaddr - input_section->vma; 1743 1.1 christos bfd_vma x = bfd_get_32 (input_bfd, location); 1744 1.1 christos 1745 1.1 christos bfd_put_32 (input_bfd, x | 1, location); 1746 1.1 christos } 1747 1.1 christos } 1748 1.1 christos 1749 1.1 christos switch (rstat) 1750 1.1 christos { 1751 1.1 christos default: 1752 1.1 christos abort (); 1753 1.1 christos case bfd_reloc_ok: 1754 1.7 christos break; 1755 1.7 christos case bfd_reloc_outofrange: 1756 1.8 christos _bfd_error_handler 1757 1.8 christos /* xgettext:c-format */ 1758 1.10 christos (_("%pB: bad reloc address %#" PRIx64 " in section `%pA'"), 1759 1.1 christos input_bfd, (uint64_t) rel->r_vaddr, input_section); 1760 1.1 christos return false; 1761 1.1 christos case bfd_reloc_overflow: 1762 1.1 christos { 1763 1.1 christos const char *name; 1764 1.1 christos char buf[SYMNMLEN + 1]; 1765 1.1 christos 1766 1.1 christos if (symndx == -1) 1767 1.1 christos name = "*ABS*"; 1768 1.1 christos else if (h != NULL) 1769 1.1 christos name = NULL; 1770 1.1 christos else 1771 1.1 christos { 1772 1.10 christos name = _bfd_coff_internal_syment_name (input_bfd, sym, buf); 1773 1.1 christos if (name == NULL) 1774 1.1 christos return false; 1775 1.6 christos } 1776 1.6 christos 1777 1.6 christos (*info->callbacks->reloc_overflow) 1778 1.6 christos (info, (h ? &h->root : NULL), name, howto->name, 1779 1.1 christos (bfd_vma) 0, input_bfd, input_section, 1780 1.1 christos rel->r_vaddr - input_section->vma); 1781 1.1 christos } 1782 1.1 christos } 1783 1.10 christos } 1784 1.1 christos 1785 1.1 christos return true; 1786 1.1 christos } 1787 1.1 christos 1788 1.10 christos #ifndef COFF_IMAGE_WITH_PE 1789 1.1 christos 1790 1.1 christos bool 1791 1.8 christos bfd_arm_allocate_interworking_sections (struct bfd_link_info * info) 1792 1.8 christos { 1793 1.1 christos asection * s; 1794 1.1 christos bfd_byte * foo; 1795 1.1 christos struct coff_arm_link_hash_table * globals; 1796 1.1 christos 1797 1.1 christos globals = coff_arm_hash_table (info); 1798 1.1 christos 1799 1.1 christos BFD_ASSERT (globals != NULL); 1800 1.1 christos 1801 1.1 christos if (globals->arm_glue_size != 0) 1802 1.1 christos { 1803 1.1 christos BFD_ASSERT (globals->bfd_of_glue_owner != NULL); 1804 1.1 christos 1805 1.1 christos s = bfd_get_section_by_name 1806 1.1 christos (globals->bfd_of_glue_owner, ARM2THUMB_GLUE_SECTION_NAME); 1807 1.1 christos 1808 1.1 christos BFD_ASSERT (s != NULL); 1809 1.1 christos 1810 1.1 christos foo = bfd_alloc (globals->bfd_of_glue_owner, globals->arm_glue_size); 1811 1.1 christos 1812 1.1 christos s->size = globals->arm_glue_size; 1813 1.1 christos s->contents = foo; 1814 1.1 christos } 1815 1.1 christos 1816 1.1 christos if (globals->thumb_glue_size != 0) 1817 1.1 christos { 1818 1.1 christos BFD_ASSERT (globals->bfd_of_glue_owner != NULL); 1819 1.1 christos 1820 1.1 christos s = bfd_get_section_by_name 1821 1.1 christos (globals->bfd_of_glue_owner, THUMB2ARM_GLUE_SECTION_NAME); 1822 1.1 christos 1823 1.1 christos BFD_ASSERT (s != NULL); 1824 1.1 christos 1825 1.1 christos foo = bfd_alloc (globals->bfd_of_glue_owner, globals->thumb_glue_size); 1826 1.1 christos 1827 1.1 christos s->size = globals->thumb_glue_size; 1828 1.1 christos s->contents = foo; 1829 1.10 christos } 1830 1.1 christos 1831 1.1 christos return true; 1832 1.1 christos } 1833 1.8 christos 1834 1.1 christos static void 1835 1.1 christos record_arm_to_thumb_glue (struct bfd_link_info * info, 1836 1.8 christos struct coff_link_hash_entry * h) 1837 1.8 christos { 1838 1.8 christos const char * name = h->root.root.string; 1839 1.8 christos register asection * s; 1840 1.8 christos char * tmp_name; 1841 1.1 christos struct coff_link_hash_entry * myh; 1842 1.1 christos struct bfd_link_hash_entry * bh; 1843 1.9 christos struct coff_arm_link_hash_table * globals; 1844 1.1 christos bfd_vma val; 1845 1.1 christos size_t amt; 1846 1.1 christos 1847 1.1 christos globals = coff_arm_hash_table (info); 1848 1.1 christos 1849 1.1 christos BFD_ASSERT (globals != NULL); 1850 1.1 christos BFD_ASSERT (globals->bfd_of_glue_owner != NULL); 1851 1.1 christos 1852 1.1 christos s = bfd_get_section_by_name 1853 1.1 christos (globals->bfd_of_glue_owner, ARM2THUMB_GLUE_SECTION_NAME); 1854 1.1 christos 1855 1.1 christos BFD_ASSERT (s != NULL); 1856 1.1 christos 1857 1.1 christos amt = strlen (name) + strlen (ARM2THUMB_GLUE_ENTRY_NAME) + 1; 1858 1.1 christos tmp_name = bfd_malloc (amt); 1859 1.1 christos 1860 1.1 christos BFD_ASSERT (tmp_name); 1861 1.1 christos 1862 1.1 christos sprintf (tmp_name, ARM2THUMB_GLUE_ENTRY_NAME, name); 1863 1.10 christos 1864 1.1 christos myh = coff_link_hash_lookup 1865 1.1 christos (coff_hash_table (info), tmp_name, false, false, true); 1866 1.1 christos 1867 1.1 christos if (myh != NULL) 1868 1.1 christos { 1869 1.1 christos free (tmp_name); 1870 1.1 christos /* We've already seen this guy. */ 1871 1.1 christos return; 1872 1.1 christos } 1873 1.1 christos 1874 1.1 christos /* The only trick here is using globals->arm_glue_size as the value. Even 1875 1.1 christos though the section isn't allocated yet, this is where we will be putting 1876 1.1 christos it. */ 1877 1.1 christos bh = NULL; 1878 1.10 christos val = globals->arm_glue_size + 1; 1879 1.1 christos bfd_coff_link_add_one_symbol (info, globals->bfd_of_glue_owner, tmp_name, 1880 1.1 christos BSF_GLOBAL, s, val, NULL, true, false, &bh); 1881 1.1 christos 1882 1.1 christos free (tmp_name); 1883 1.1 christos 1884 1.1 christos globals->arm_glue_size += ARM2THUMB_GLUE_SIZE; 1885 1.1 christos 1886 1.1 christos return; 1887 1.1 christos } 1888 1.1 christos 1889 1.8 christos #ifndef ARM_WINCE 1890 1.1 christos static void 1891 1.1 christos record_thumb_to_arm_glue (struct bfd_link_info * info, 1892 1.8 christos struct coff_link_hash_entry * h) 1893 1.8 christos { 1894 1.8 christos const char * name = h->root.root.string; 1895 1.8 christos asection * s; 1896 1.8 christos char * tmp_name; 1897 1.1 christos struct coff_link_hash_entry * myh; 1898 1.1 christos struct bfd_link_hash_entry * bh; 1899 1.9 christos struct coff_arm_link_hash_table * globals; 1900 1.1 christos bfd_vma val; 1901 1.1 christos size_t amt; 1902 1.1 christos 1903 1.1 christos globals = coff_arm_hash_table (info); 1904 1.1 christos 1905 1.1 christos BFD_ASSERT (globals != NULL); 1906 1.1 christos BFD_ASSERT (globals->bfd_of_glue_owner != NULL); 1907 1.1 christos 1908 1.1 christos s = bfd_get_section_by_name 1909 1.1 christos (globals->bfd_of_glue_owner, THUMB2ARM_GLUE_SECTION_NAME); 1910 1.1 christos 1911 1.1 christos BFD_ASSERT (s != NULL); 1912 1.1 christos 1913 1.1 christos amt = strlen (name) + strlen (THUMB2ARM_GLUE_ENTRY_NAME) + 1; 1914 1.1 christos tmp_name = bfd_malloc (amt); 1915 1.1 christos 1916 1.1 christos BFD_ASSERT (tmp_name); 1917 1.1 christos 1918 1.1 christos sprintf (tmp_name, THUMB2ARM_GLUE_ENTRY_NAME, name); 1919 1.10 christos 1920 1.1 christos myh = coff_link_hash_lookup 1921 1.1 christos (coff_hash_table (info), tmp_name, false, false, true); 1922 1.1 christos 1923 1.1 christos if (myh != NULL) 1924 1.1 christos { 1925 1.1 christos free (tmp_name); 1926 1.1 christos /* We've already seen this guy. */ 1927 1.1 christos return; 1928 1.1 christos } 1929 1.1 christos 1930 1.1 christos bh = NULL; 1931 1.10 christos val = globals->thumb_glue_size + 1; 1932 1.1 christos bfd_coff_link_add_one_symbol (info, globals->bfd_of_glue_owner, tmp_name, 1933 1.1 christos BSF_GLOBAL, s, val, NULL, true, false, &bh); 1934 1.1 christos 1935 1.1 christos /* If we mark it 'thumb', the disassembler will do a better job. */ 1936 1.1 christos myh = (struct coff_link_hash_entry *) bh; 1937 1.1 christos myh->symbol_class = C_THUMBEXTFUNC; 1938 1.1 christos 1939 1.1 christos free (tmp_name); 1940 1.1 christos 1941 1.1 christos /* Allocate another symbol to mark where we switch to arm mode. */ 1942 1.1 christos 1943 1.1 christos #define CHANGE_TO_ARM "__%s_change_to_arm" 1944 1.1 christos #define BACK_FROM_ARM "__%s_back_from_arm" 1945 1.1 christos 1946 1.1 christos amt = strlen (name) + strlen (CHANGE_TO_ARM) + 1; 1947 1.1 christos tmp_name = bfd_malloc (amt); 1948 1.1 christos 1949 1.1 christos BFD_ASSERT (tmp_name); 1950 1.1 christos 1951 1.1 christos sprintf (tmp_name, globals->support_old_code ? BACK_FROM_ARM : CHANGE_TO_ARM, name); 1952 1.1 christos 1953 1.1 christos bh = NULL; 1954 1.10 christos val = globals->thumb_glue_size + (globals->support_old_code ? 8 : 4); 1955 1.1 christos bfd_coff_link_add_one_symbol (info, globals->bfd_of_glue_owner, tmp_name, 1956 1.1 christos BSF_LOCAL, s, val, NULL, true, false, &bh); 1957 1.1 christos 1958 1.1 christos free (tmp_name); 1959 1.1 christos 1960 1.1 christos globals->thumb_glue_size += THUMB2ARM_GLUE_SIZE; 1961 1.1 christos 1962 1.1 christos return; 1963 1.1 christos } 1964 1.1 christos #endif /* not ARM_WINCE */ 1965 1.1 christos 1966 1.1 christos /* Select a BFD to be used to hold the sections used by the glue code. 1967 1.1 christos This function is called from the linker scripts in ld/emultempl/ 1968 1.10 christos {armcoff/pe}.em */ 1969 1.8 christos 1970 1.1 christos bool 1971 1.1 christos bfd_arm_get_bfd_for_interworking (bfd * abfd, 1972 1.1 christos struct bfd_link_info * info) 1973 1.8 christos { 1974 1.8 christos struct coff_arm_link_hash_table * globals; 1975 1.1 christos flagword flags; 1976 1.1 christos asection * sec; 1977 1.1 christos 1978 1.6 christos /* If we are only performing a partial link do not bother 1979 1.10 christos getting a bfd to hold the glue. */ 1980 1.1 christos if (bfd_link_relocatable (info)) 1981 1.1 christos return true; 1982 1.1 christos 1983 1.1 christos globals = coff_arm_hash_table (info); 1984 1.1 christos 1985 1.1 christos BFD_ASSERT (globals != NULL); 1986 1.10 christos 1987 1.1 christos if (globals->bfd_of_glue_owner != NULL) 1988 1.1 christos return true; 1989 1.1 christos 1990 1.1 christos sec = bfd_get_section_by_name (abfd, ARM2THUMB_GLUE_SECTION_NAME); 1991 1.1 christos 1992 1.1 christos if (sec == NULL) 1993 1.1 christos { 1994 1.1 christos flags = (SEC_ALLOC | SEC_LOAD | SEC_HAS_CONTENTS | SEC_IN_MEMORY 1995 1.1 christos | SEC_CODE | SEC_READONLY); 1996 1.1 christos sec = bfd_make_section_with_flags (abfd, ARM2THUMB_GLUE_SECTION_NAME, 1997 1.9 christos flags); 1998 1.10 christos if (sec == NULL 1999 1.1 christos || !bfd_set_section_alignment (sec, 2)) 2000 1.1 christos return false; 2001 1.1 christos } 2002 1.1 christos 2003 1.1 christos sec = bfd_get_section_by_name (abfd, THUMB2ARM_GLUE_SECTION_NAME); 2004 1.1 christos 2005 1.1 christos if (sec == NULL) 2006 1.1 christos { 2007 1.1 christos flags = (SEC_ALLOC | SEC_LOAD | SEC_HAS_CONTENTS | SEC_IN_MEMORY 2008 1.1 christos | SEC_CODE | SEC_READONLY); 2009 1.1 christos sec = bfd_make_section_with_flags (abfd, THUMB2ARM_GLUE_SECTION_NAME, 2010 1.1 christos flags); 2011 1.9 christos 2012 1.10 christos if (sec == NULL 2013 1.1 christos || !bfd_set_section_alignment (sec, 2)) 2014 1.1 christos return false; 2015 1.1 christos } 2016 1.1 christos 2017 1.1 christos /* Save the bfd for later use. */ 2018 1.10 christos globals->bfd_of_glue_owner = abfd; 2019 1.1 christos 2020 1.1 christos return true; 2021 1.10 christos } 2022 1.8 christos 2023 1.1 christos bool 2024 1.8 christos bfd_arm_process_before_allocation (bfd * abfd, 2025 1.1 christos struct bfd_link_info * info, 2026 1.1 christos int support_old_code) 2027 1.1 christos { 2028 1.1 christos asection * sec; 2029 1.1 christos struct coff_arm_link_hash_table * globals; 2030 1.1 christos 2031 1.6 christos /* If we are only performing a partial link do not bother 2032 1.10 christos to construct any glue. */ 2033 1.1 christos if (bfd_link_relocatable (info)) 2034 1.1 christos return true; 2035 1.1 christos 2036 1.1 christos /* Here we have a bfd that is to be included on the link. We have a hook 2037 1.1 christos to do reloc rummaging, before section sizes are nailed down. */ 2038 1.1 christos _bfd_coff_get_external_symbols (abfd); 2039 1.1 christos 2040 1.1 christos globals = coff_arm_hash_table (info); 2041 1.1 christos 2042 1.1 christos BFD_ASSERT (globals != NULL); 2043 1.1 christos BFD_ASSERT (globals->bfd_of_glue_owner != NULL); 2044 1.1 christos 2045 1.1 christos globals->support_old_code = support_old_code; 2046 1.1 christos 2047 1.1 christos /* Rummage around all the relocs and map the glue vectors. */ 2048 1.1 christos sec = abfd->sections; 2049 1.10 christos 2050 1.1 christos if (sec == NULL) 2051 1.1 christos return true; 2052 1.1 christos 2053 1.1 christos for (; sec != NULL; sec = sec->next) 2054 1.1 christos { 2055 1.1 christos struct internal_reloc * i; 2056 1.1 christos struct internal_reloc * rel; 2057 1.1 christos 2058 1.1 christos if (sec->reloc_count == 0) 2059 1.1 christos continue; 2060 1.1 christos 2061 1.1 christos /* Load the relocs. */ 2062 1.1 christos /* FIXME: there may be a storage leak here. */ 2063 1.1 christos i = _bfd_coff_read_internal_relocs (abfd, sec, 1, 0, 0, 0); 2064 1.1 christos 2065 1.1 christos BFD_ASSERT (i != 0); 2066 1.1 christos 2067 1.8 christos for (rel = i; rel < i + sec->reloc_count; ++rel) 2068 1.8 christos { 2069 1.8 christos unsigned short r_type = rel->r_type; 2070 1.1 christos long symndx; 2071 1.1 christos struct coff_link_hash_entry * h; 2072 1.1 christos 2073 1.1 christos symndx = rel->r_symndx; 2074 1.1 christos 2075 1.1 christos /* If the relocation is not against a symbol it cannot concern us. */ 2076 1.1 christos if (symndx == -1) 2077 1.1 christos continue; 2078 1.1 christos 2079 1.1 christos /* If the index is outside of the range of our table, something has gone wrong. */ 2080 1.7 christos if (symndx >= obj_conv_table_size (abfd)) 2081 1.8 christos { 2082 1.1 christos /* xgettext:c-format */ 2083 1.1 christos _bfd_error_handler (_("%pB: illegal symbol index in reloc: %ld"), 2084 1.1 christos abfd, symndx); 2085 1.1 christos continue; 2086 1.1 christos } 2087 1.1 christos 2088 1.1 christos h = obj_coff_sym_hashes (abfd)[symndx]; 2089 1.1 christos 2090 1.1 christos /* If the relocation is against a static symbol it must be within 2091 1.1 christos the current section and so cannot be a cross ARM/Thumb relocation. */ 2092 1.1 christos if (h == NULL) 2093 1.1 christos continue; 2094 1.1 christos 2095 1.1 christos switch (r_type) 2096 1.1 christos { 2097 1.1 christos case ARM_26: 2098 1.1 christos /* This one is a call from arm code. We need to look up 2099 1.1 christos the target of the call. If it is a thumb target, we 2100 1.1 christos insert glue. */ 2101 1.1 christos 2102 1.1 christos if (h->symbol_class == C_THUMBEXTFUNC) 2103 1.1 christos record_arm_to_thumb_glue (info, h); 2104 1.1 christos break; 2105 1.1 christos 2106 1.1 christos #ifndef ARM_WINCE 2107 1.1 christos case ARM_THUMB23: 2108 1.1 christos /* This one is a call from thumb code. We used to look 2109 1.1 christos for ARM_THUMB9 and ARM_THUMB12 as well. We need to look 2110 1.1 christos up the target of the call. If it is an arm target, we 2111 1.1 christos insert glue. If the symbol does not exist it will be 2112 1.1 christos given a class of C_EXT and so we will generate a stub 2113 1.1 christos for it. This is not really a problem, since the link 2114 1.1 christos is doomed anyway. */ 2115 1.1 christos 2116 1.1 christos switch (h->symbol_class) 2117 1.1 christos { 2118 1.1 christos case C_EXT: 2119 1.1 christos case C_STAT: 2120 1.1 christos case C_LABEL: 2121 1.1 christos record_thumb_to_arm_glue (info, h); 2122 1.1 christos break; 2123 1.1 christos default: 2124 1.1 christos ; 2125 1.1 christos } 2126 1.1 christos break; 2127 1.1 christos #endif 2128 1.1 christos 2129 1.1 christos default: 2130 1.1 christos break; 2131 1.1 christos } 2132 1.1 christos } 2133 1.10 christos } 2134 1.1 christos 2135 1.1 christos return true; 2136 1.1 christos } 2137 1.1 christos 2138 1.8 christos #endif /* ! defined (COFF_IMAGE_WITH_PE) */ 2139 1.8 christos 2140 1.8 christos #define coff_bfd_reloc_type_lookup coff_arm_reloc_type_lookup 2141 1.8 christos #define coff_bfd_reloc_name_lookup coff_arm_reloc_name_lookup 2142 1.1 christos #define coff_relocate_section coff_arm_relocate_section 2143 1.8 christos #define coff_bfd_is_local_label_name coff_arm_is_local_label_name 2144 1.1 christos #define coff_adjust_symndx coff_arm_adjust_symndx 2145 1.1 christos #define coff_link_output_has_begun coff_arm_link_output_has_begun 2146 1.1 christos #define coff_final_link_postscript coff_arm_final_link_postscript 2147 1.8 christos #define coff_bfd_merge_private_bfd_data coff_arm_merge_private_bfd_data 2148 1.8 christos #define coff_bfd_print_private_bfd_data coff_arm_print_private_bfd_data 2149 1.1 christos #define coff_bfd_set_private_flags _bfd_coff_arm_set_private_flags 2150 1.1 christos #define coff_bfd_copy_private_bfd_data coff_arm_copy_private_bfd_data 2151 1.1 christos #define coff_bfd_link_hash_table_create coff_arm_link_hash_table_create 2152 1.1 christos 2153 1.1 christos /* When doing a relocatable link, we want to convert ARM_26 relocs 2154 1.10 christos into ARM_26D relocs. */ 2155 1.1 christos 2156 1.1 christos static bool 2157 1.1 christos coff_arm_adjust_symndx (bfd *obfd ATTRIBUTE_UNUSED, 2158 1.1 christos struct bfd_link_info *info ATTRIBUTE_UNUSED, 2159 1.1 christos bfd *ibfd, 2160 1.10 christos asection *sec, 2161 1.1 christos struct internal_reloc *irel, 2162 1.1 christos bool *adjustedp) 2163 1.1 christos { 2164 1.1 christos if (irel->r_type == ARM_26) 2165 1.1 christos { 2166 1.1 christos struct coff_link_hash_entry *h; 2167 1.1 christos 2168 1.1 christos h = obj_coff_sym_hashes (ibfd)[irel->r_symndx]; 2169 1.1 christos if (h != NULL 2170 1.1 christos && (h->root.type == bfd_link_hash_defined 2171 1.1 christos || h->root.type == bfd_link_hash_defweak) 2172 1.1 christos && h->root.u.def.section->output_section == sec->output_section) 2173 1.10 christos irel->r_type = ARM_26D; 2174 1.10 christos } 2175 1.1 christos *adjustedp = false; 2176 1.1 christos return true; 2177 1.1 christos } 2178 1.1 christos 2179 1.1 christos /* Called when merging the private data areas of two BFDs. 2180 1.1 christos This is important as it allows us to detect if we are 2181 1.1 christos attempting to merge binaries compiled for different ARM 2182 1.10 christos targets, eg different CPUs or different APCS's. */ 2183 1.7 christos 2184 1.1 christos static bool 2185 1.7 christos coff_arm_merge_private_bfd_data (bfd * ibfd, struct bfd_link_info *info) 2186 1.1 christos { 2187 1.1 christos bfd *obfd = info->output_bfd; 2188 1.1 christos BFD_ASSERT (ibfd != NULL && obfd != NULL); 2189 1.10 christos 2190 1.1 christos if (ibfd == obfd) 2191 1.1 christos return true; 2192 1.1 christos 2193 1.1 christos /* If the two formats are different we cannot merge anything. 2194 1.1 christos This is not an error, since it is permissable to change the 2195 1.1 christos input and output formats. */ 2196 1.10 christos if ( ibfd->xvec->flavour != bfd_target_coff_flavour 2197 1.1 christos || obfd->xvec->flavour != bfd_target_coff_flavour) 2198 1.1 christos return true; 2199 1.1 christos 2200 1.1 christos /* Determine what should happen if the input ARM architecture 2201 1.10 christos does not match the output ARM architecture. */ 2202 1.1 christos if (! bfd_arm_merge_machines (ibfd, obfd)) 2203 1.1 christos return false; 2204 1.1 christos 2205 1.1 christos /* Verify that the APCS is the same for the two BFDs. */ 2206 1.1 christos if (APCS_SET (ibfd)) 2207 1.1 christos { 2208 1.1 christos if (APCS_SET (obfd)) 2209 1.1 christos { 2210 1.1 christos /* If the src and dest have different APCS flag bits set, fail. */ 2211 1.1 christos if (APCS_26_FLAG (obfd) != APCS_26_FLAG (ibfd)) 2212 1.1 christos { 2213 1.9 christos _bfd_error_handler 2214 1.9 christos /* xgettext: c-format */ 2215 1.7 christos (_("error: %pB is compiled for APCS-%d, " 2216 1.7 christos "whereas %pB is compiled for APCS-%d"), 2217 1.1 christos ibfd, APCS_26_FLAG (ibfd) ? 26 : 32, 2218 1.1 christos obfd, APCS_26_FLAG (obfd) ? 26 : 32 2219 1.1 christos ); 2220 1.10 christos 2221 1.1 christos bfd_set_error (bfd_error_wrong_format); 2222 1.1 christos return false; 2223 1.1 christos } 2224 1.1 christos 2225 1.1 christos if (APCS_FLOAT_FLAG (obfd) != APCS_FLOAT_FLAG (ibfd)) 2226 1.1 christos { 2227 1.9 christos if (APCS_FLOAT_FLAG (ibfd)) 2228 1.9 christos /* xgettext: c-format */ 2229 1.9 christos _bfd_error_handler 2230 1.9 christos (_("error: %pB passes floats in float registers, " 2231 1.1 christos "whereas %pB passes them in integer registers"), 2232 1.1 christos ibfd, obfd); 2233 1.9 christos else 2234 1.9 christos /* xgettext: c-format */ 2235 1.9 christos _bfd_error_handler 2236 1.9 christos (_("error: %pB passes floats in integer registers, " 2237 1.1 christos "whereas %pB passes them in float registers"), 2238 1.1 christos ibfd, obfd); 2239 1.10 christos 2240 1.1 christos bfd_set_error (bfd_error_wrong_format); 2241 1.1 christos return false; 2242 1.1 christos } 2243 1.1 christos 2244 1.1 christos if (PIC_FLAG (obfd) != PIC_FLAG (ibfd)) 2245 1.1 christos { 2246 1.9 christos if (PIC_FLAG (ibfd)) 2247 1.9 christos /* xgettext: c-format */ 2248 1.9 christos _bfd_error_handler 2249 1.9 christos (_("error: %pB is compiled as position independent code, " 2250 1.1 christos "whereas target %pB is absolute position"), 2251 1.1 christos ibfd, obfd); 2252 1.9 christos else 2253 1.9 christos /* xgettext: c-format */ 2254 1.9 christos _bfd_error_handler 2255 1.9 christos (_("error: %pB is compiled as absolute position code, " 2256 1.1 christos "whereas target %pB is position independent"), 2257 1.1 christos ibfd, obfd); 2258 1.10 christos 2259 1.1 christos bfd_set_error (bfd_error_wrong_format); 2260 1.1 christos return false; 2261 1.1 christos } 2262 1.1 christos } 2263 1.1 christos else 2264 1.1 christos { 2265 1.1 christos SET_APCS_FLAGS (obfd, APCS_26_FLAG (ibfd) | APCS_FLOAT_FLAG (ibfd) | PIC_FLAG (ibfd)); 2266 1.1 christos 2267 1.1 christos /* Set up the arch and fields as well as these are probably wrong. */ 2268 1.1 christos bfd_set_arch_mach (obfd, bfd_get_arch (ibfd), bfd_get_mach (ibfd)); 2269 1.1 christos } 2270 1.1 christos } 2271 1.1 christos 2272 1.1 christos /* Check the interworking support. */ 2273 1.1 christos if (INTERWORK_SET (ibfd)) 2274 1.1 christos { 2275 1.1 christos if (INTERWORK_SET (obfd)) 2276 1.1 christos { 2277 1.1 christos /* If the src and dest differ in their interworking issue a warning. */ 2278 1.1 christos if (INTERWORK_FLAG (obfd) != INTERWORK_FLAG (ibfd)) 2279 1.1 christos { 2280 1.9 christos if (INTERWORK_FLAG (ibfd)) 2281 1.9 christos /* xgettext: c-format */ 2282 1.7 christos _bfd_error_handler (_("warning: %pB supports interworking, " 2283 1.1 christos "whereas %pB does not"), 2284 1.1 christos ibfd, obfd); 2285 1.9 christos else 2286 1.9 christos /* xgettext: c-format */ 2287 1.9 christos _bfd_error_handler 2288 1.9 christos (_("warning: %pB does not support interworking, " 2289 1.1 christos "whereas %pB does"), 2290 1.1 christos ibfd, obfd); 2291 1.1 christos } 2292 1.1 christos } 2293 1.1 christos else 2294 1.1 christos { 2295 1.1 christos SET_INTERWORK_FLAG (obfd, INTERWORK_FLAG (ibfd)); 2296 1.1 christos } 2297 1.10 christos } 2298 1.1 christos 2299 1.1 christos return true; 2300 1.1 christos } 2301 1.1 christos 2302 1.10 christos /* Display the flags field. */ 2303 1.1 christos 2304 1.1 christos static bool 2305 1.1 christos coff_arm_print_private_bfd_data (bfd * abfd, void * ptr) 2306 1.1 christos { 2307 1.1 christos FILE * file = (FILE *) ptr; 2308 1.1 christos 2309 1.1 christos BFD_ASSERT (abfd != NULL && ptr != NULL); 2310 1.1 christos 2311 1.1 christos fprintf (file, _("private flags = %x:"), coff_data (abfd)->flags); 2312 1.1 christos 2313 1.1 christos if (APCS_SET (abfd)) 2314 1.1 christos { 2315 1.1 christos /* xgettext: APCS is ARM Procedure Call Standard, it should not be translated. */ 2316 1.1 christos fprintf (file, " [APCS-%d]", APCS_26_FLAG (abfd) ? 26 : 32); 2317 1.1 christos 2318 1.1 christos if (APCS_FLOAT_FLAG (abfd)) 2319 1.1 christos fprintf (file, _(" [floats passed in float registers]")); 2320 1.1 christos else 2321 1.1 christos fprintf (file, _(" [floats passed in integer registers]")); 2322 1.1 christos 2323 1.1 christos if (PIC_FLAG (abfd)) 2324 1.1 christos fprintf (file, _(" [position independent]")); 2325 1.1 christos else 2326 1.1 christos fprintf (file, _(" [absolute position]")); 2327 1.1 christos } 2328 1.1 christos 2329 1.1 christos if (! INTERWORK_SET (abfd)) 2330 1.1 christos fprintf (file, _(" [interworking flag not initialised]")); 2331 1.1 christos else if (INTERWORK_FLAG (abfd)) 2332 1.1 christos fprintf (file, _(" [interworking supported]")); 2333 1.1 christos else 2334 1.1 christos fprintf (file, _(" [interworking not supported]")); 2335 1.1 christos 2336 1.10 christos fputc ('\n', file); 2337 1.1 christos 2338 1.1 christos return true; 2339 1.1 christos } 2340 1.1 christos 2341 1.1 christos /* Copies the given flags into the coff_tdata.flags field. 2342 1.1 christos Typically these flags come from the f_flags[] field of 2343 1.1 christos the COFF filehdr structure, which contains important, 2344 1.1 christos target specific information. 2345 1.1 christos Note: Although this function is static, it is explicitly 2346 1.10 christos called from both coffcode.h and peicode.h. */ 2347 1.1 christos 2348 1.1 christos static bool 2349 1.1 christos _bfd_coff_arm_set_private_flags (bfd * abfd, flagword flags) 2350 1.1 christos { 2351 1.1 christos flagword flag; 2352 1.1 christos 2353 1.1 christos BFD_ASSERT (abfd != NULL); 2354 1.1 christos 2355 1.1 christos flag = (flags & F_APCS26) ? F_APCS_26 : 0; 2356 1.1 christos 2357 1.1 christos /* Make sure that the APCS field has not been initialised to the opposite 2358 1.1 christos value. */ 2359 1.1 christos if (APCS_SET (abfd) 2360 1.8 christos && ( (APCS_26_FLAG (abfd) != flag) 2361 1.1 christos || (APCS_FLOAT_FLAG (abfd) != (flags & F_APCS_FLOAT)) 2362 1.10 christos || (PIC_FLAG (abfd) != (flags & F_PIC)) 2363 1.1 christos )) 2364 1.1 christos return false; 2365 1.1 christos 2366 1.1 christos flag |= (flags & (F_APCS_FLOAT | F_PIC)); 2367 1.1 christos 2368 1.1 christos SET_APCS_FLAGS (abfd, flag); 2369 1.1 christos 2370 1.1 christos flag = (flags & F_INTERWORK); 2371 1.1 christos 2372 1.1 christos /* If the BFD has already had its interworking flag set, but it 2373 1.1 christos is different from the value that we have been asked to set, 2374 1.1 christos then assume that that merged code will not support interworking 2375 1.1 christos and set the flag accordingly. */ 2376 1.1 christos if (INTERWORK_SET (abfd) && (INTERWORK_FLAG (abfd) != flag)) 2377 1.8 christos { 2378 1.1 christos if (flag) 2379 1.1 christos _bfd_error_handler (_("warning: not setting interworking flag of %pB since it has already been specified as non-interworking"), 2380 1.8 christos abfd); 2381 1.1 christos else 2382 1.1 christos _bfd_error_handler (_("warning: clearing the interworking flag of %pB due to outside request"), 2383 1.1 christos abfd); 2384 1.1 christos flag = 0; 2385 1.1 christos } 2386 1.1 christos 2387 1.10 christos SET_INTERWORK_FLAG (abfd, flag); 2388 1.1 christos 2389 1.1 christos return true; 2390 1.1 christos } 2391 1.1 christos 2392 1.1 christos /* Copy the important parts of the target specific data 2393 1.10 christos from one instance of a BFD to another. */ 2394 1.1 christos 2395 1.1 christos static bool 2396 1.1 christos coff_arm_copy_private_bfd_data (bfd * src, bfd * dest) 2397 1.1 christos { 2398 1.1 christos BFD_ASSERT (src != NULL && dest != NULL); 2399 1.10 christos 2400 1.1 christos if (src == dest) 2401 1.1 christos return true; 2402 1.1 christos 2403 1.1 christos /* If the destination is not in the same format as the source, do not do 2404 1.10 christos the copy. */ 2405 1.1 christos if (src->xvec != dest->xvec) 2406 1.1 christos return true; 2407 1.1 christos 2408 1.1 christos /* Copy the flags field. */ 2409 1.1 christos if (APCS_SET (src)) 2410 1.1 christos { 2411 1.1 christos if (APCS_SET (dest)) 2412 1.1 christos { 2413 1.10 christos /* If the src and dest have different APCS flag bits set, fail. */ 2414 1.1 christos if (APCS_26_FLAG (dest) != APCS_26_FLAG (src)) 2415 1.1 christos return false; 2416 1.10 christos 2417 1.1 christos if (APCS_FLOAT_FLAG (dest) != APCS_FLOAT_FLAG (src)) 2418 1.1 christos return false; 2419 1.10 christos 2420 1.1 christos if (PIC_FLAG (dest) != PIC_FLAG (src)) 2421 1.1 christos return false; 2422 1.1 christos } 2423 1.1 christos else 2424 1.1 christos SET_APCS_FLAGS (dest, APCS_26_FLAG (src) | APCS_FLOAT_FLAG (src) 2425 1.1 christos | PIC_FLAG (src)); 2426 1.1 christos } 2427 1.1 christos 2428 1.1 christos if (INTERWORK_SET (src)) 2429 1.1 christos { 2430 1.1 christos if (INTERWORK_SET (dest)) 2431 1.1 christos { 2432 1.1 christos /* If the src and dest have different interworking flags then turn 2433 1.1 christos off the interworking bit. */ 2434 1.1 christos if (INTERWORK_FLAG (dest) != INTERWORK_FLAG (src)) 2435 1.1 christos { 2436 1.1 christos if (INTERWORK_FLAG (dest)) 2437 1.9 christos { 2438 1.9 christos /* xgettext:c-format */ 2439 1.9 christos _bfd_error_handler 2440 1.9 christos (_("warning: clearing the interworking flag of %pB " 2441 1.9 christos "because non-interworking code in %pB has been " 2442 1.1 christos "linked with it"), 2443 1.1 christos dest, src); 2444 1.1 christos } 2445 1.1 christos 2446 1.1 christos SET_INTERWORK_FLAG (dest, 0); 2447 1.1 christos } 2448 1.1 christos } 2449 1.1 christos else 2450 1.1 christos { 2451 1.1 christos SET_INTERWORK_FLAG (dest, INTERWORK_FLAG (src)); 2452 1.1 christos } 2453 1.10 christos } 2454 1.1 christos 2455 1.1 christos return true; 2456 1.1 christos } 2457 1.1 christos 2458 1.1 christos /* Note: the definitions here of LOCAL_LABEL_PREFIX and USER_LABEL_PREIFX 2459 1.1 christos *must* match the definitions in gcc/config/arm/{coff|semi|aout}.h. */ 2460 1.1 christos #ifndef LOCAL_LABEL_PREFIX 2461 1.1 christos #define LOCAL_LABEL_PREFIX "" 2462 1.1 christos #endif 2463 1.1 christos #ifndef USER_LABEL_PREFIX 2464 1.1 christos #define USER_LABEL_PREFIX "_" 2465 1.1 christos #endif 2466 1.1 christos 2467 1.1 christos /* Like _bfd_coff_is_local_label_name, but 2468 1.1 christos a) test against USER_LABEL_PREFIX, to avoid stripping labels known to be 2469 1.1 christos non-local. 2470 1.1 christos b) Allow other prefixes than ".", e.g. an empty prefix would cause all 2471 1.10 christos labels of the form Lxxx to be stripped. */ 2472 1.8 christos 2473 1.1 christos static bool 2474 1.1 christos coff_arm_is_local_label_name (bfd * abfd ATTRIBUTE_UNUSED, 2475 1.1 christos const char * name) 2476 1.1 christos { 2477 1.1 christos #ifdef USER_LABEL_PREFIX 2478 1.1 christos if (USER_LABEL_PREFIX[0] != 0) 2479 1.1 christos { 2480 1.1 christos size_t len = strlen (USER_LABEL_PREFIX); 2481 1.10 christos 2482 1.1 christos if (strncmp (name, USER_LABEL_PREFIX, len) == 0) 2483 1.1 christos return false; 2484 1.1 christos } 2485 1.1 christos #endif 2486 1.1 christos 2487 1.1 christos #ifdef LOCAL_LABEL_PREFIX 2488 1.1 christos /* If there is a prefix for local labels then look for this. 2489 1.1 christos If the prefix exists, but it is empty, then ignore the test. */ 2490 1.1 christos 2491 1.1 christos if (LOCAL_LABEL_PREFIX[0] != 0) 2492 1.1 christos { 2493 1.1 christos size_t len = strlen (LOCAL_LABEL_PREFIX); 2494 1.10 christos 2495 1.1 christos if (strncmp (name, LOCAL_LABEL_PREFIX, len) != 0) 2496 1.1 christos return false; 2497 1.1 christos 2498 1.1 christos /* Perform the checks below for the rest of the name. */ 2499 1.1 christos name += len; 2500 1.1 christos } 2501 1.1 christos #endif 2502 1.1 christos 2503 1.1 christos return name[0] == 'L'; 2504 1.1 christos } 2505 1.1 christos 2506 1.1 christos /* This piece of machinery exists only to guarantee that the bfd that holds 2507 1.1 christos the glue section is written last. 2508 1.1 christos 2509 1.1 christos This does depend on bfd_make_section attaching a new section to the 2510 1.10 christos end of the section list for the bfd. */ 2511 1.1 christos 2512 1.1 christos static bool 2513 1.1 christos coff_arm_link_output_has_begun (bfd * sub, struct coff_final_link_info * info) 2514 1.1 christos { 2515 1.1 christos return (sub->output_has_begun 2516 1.1 christos || sub == coff_arm_hash_table (info->info)->bfd_of_glue_owner); 2517 1.10 christos } 2518 1.1 christos 2519 1.1 christos static bool 2520 1.1 christos coff_arm_final_link_postscript (bfd * abfd ATTRIBUTE_UNUSED, 2521 1.1 christos struct coff_final_link_info * pfinfo) 2522 1.1 christos { 2523 1.1 christos struct coff_arm_link_hash_table * globals; 2524 1.1 christos 2525 1.1 christos globals = coff_arm_hash_table (pfinfo->info); 2526 1.1 christos 2527 1.1 christos BFD_ASSERT (globals != NULL); 2528 1.1 christos 2529 1.1 christos if (globals->bfd_of_glue_owner != NULL) 2530 1.10 christos { 2531 1.1 christos if (! _bfd_coff_link_input_bfd (pfinfo, globals->bfd_of_glue_owner)) 2532 1.10 christos return false; 2533 1.1 christos 2534 1.1 christos globals->bfd_of_glue_owner->output_has_begun = true; 2535 1.1 christos } 2536 1.1 christos 2537 1.1 christos return bfd_arm_update_notes (abfd, ARM_NOTE_SECTION); 2538 1.1 christos } 2539 1.1 christos 2540 1.1 christos #ifndef bfd_pe_print_pdata 2541 1.1 christos #define bfd_pe_print_pdata NULL 2542 1.1 christos #endif 2543 1.1 christos 2544 1.1 christos #include "coffcode.h" 2545 1.3 christos 2546 1.1 christos #ifndef TARGET_LITTLE_SYM 2547 1.1 christos #define TARGET_LITTLE_SYM arm_coff_le_vec 2548 1.1 christos #endif 2549 1.1 christos #ifndef TARGET_LITTLE_NAME 2550 1.1 christos #define TARGET_LITTLE_NAME "coff-arm-little" 2551 1.3 christos #endif 2552 1.1 christos #ifndef TARGET_BIG_SYM 2553 1.1 christos #define TARGET_BIG_SYM arm_coff_be_vec 2554 1.1 christos #endif 2555 1.1 christos #ifndef TARGET_BIG_NAME 2556 1.1 christos #define TARGET_BIG_NAME "coff-arm-big" 2557 1.1 christos #endif 2558 1.1 christos 2559 1.1 christos #ifndef TARGET_UNDERSCORE 2560 1.1 christos #define TARGET_UNDERSCORE 0 2561 1.1 christos #endif 2562 1.1 christos 2563 1.1 christos #ifndef EXTRA_S_FLAGS 2564 1.1 christos #ifdef COFF_WITH_PE 2565 1.1 christos #define EXTRA_S_FLAGS (SEC_CODE | SEC_LINK_ONCE | SEC_LINK_DUPLICATES) 2566 1.1 christos #else 2567 1.1 christos #define EXTRA_S_FLAGS SEC_CODE 2568 1.1 christos #endif 2569 1.1 christos #endif 2570 1.1 christos 2571 1.1 christos /* Forward declaration for use initialising alternative_target field. */ 2572 1.1 christos extern const bfd_target TARGET_BIG_SYM ; 2573 1.1 christos 2574 1.1 christos /* Target vectors. */ 2575 CREATE_LITTLE_COFF_TARGET_VEC (TARGET_LITTLE_SYM, TARGET_LITTLE_NAME, D_PAGED, EXTRA_S_FLAGS, TARGET_UNDERSCORE, & TARGET_BIG_SYM, COFF_SWAP_TABLE) 2576 CREATE_BIG_COFF_TARGET_VEC (TARGET_BIG_SYM, TARGET_BIG_NAME, D_PAGED, EXTRA_S_FLAGS, TARGET_UNDERSCORE, & TARGET_LITTLE_SYM, COFF_SWAP_TABLE) 2577