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