1 1.1 christos /* MSP430-specific support for 32-bit ELF 2 1.11 christos Copyright (C) 2002-2024 Free Software Foundation, Inc. 3 1.1 christos Contributed by Dmitry Diky <diwil (at) mail.ru> 4 1.1 christos 5 1.1 christos This file is part of BFD, the Binary File Descriptor library. 6 1.1 christos 7 1.1 christos This program is free software; you can redistribute it and/or modify 8 1.1 christos it under the terms of the GNU General Public License as published by 9 1.1 christos the Free Software Foundation; either version 3 of the License, or 10 1.1 christos (at your option) any later version. 11 1.1 christos 12 1.1 christos This program is distributed in the hope that it will be useful, 13 1.1 christos but WITHOUT ANY WARRANTY; without even the implied warranty of 14 1.1 christos MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 15 1.1 christos GNU General Public License for more details. 16 1.1 christos 17 1.1 christos You should have received a copy of the GNU General Public License 18 1.1 christos along with this program; if not, write to the Free Software 19 1.1 christos Foundation, Inc., 51 Franklin Street - Fifth Floor, Boston, 20 1.1 christos MA 02110-1301, USA. */ 21 1.1 christos 22 1.1 christos #include "sysdep.h" 23 1.1 christos #include "bfd.h" 24 1.1 christos #include "libiberty.h" 25 1.1 christos #include "libbfd.h" 26 1.1 christos #include "elf-bfd.h" 27 1.1 christos #include "elf/msp430.h" 28 1.1 christos 29 1.10 christos static bool debug_relocs = 0; 30 1.9 christos 31 1.9 christos /* All users of this file have bfd_octets_per_byte (abfd, sec) == 1. */ 32 1.9 christos #define OCTETS_PER_BYTE(ABFD, SEC) 1 33 1.9 christos 34 1.5 christos static bfd_reloc_status_type 35 1.5 christos rl78_sym_diff_handler (bfd * abfd, 36 1.5 christos arelent * reloc, 37 1.5 christos asymbol * sym ATTRIBUTE_UNUSED, 38 1.5 christos void * addr ATTRIBUTE_UNUSED, 39 1.5 christos asection * input_sec, 40 1.5 christos bfd * out_bfd ATTRIBUTE_UNUSED, 41 1.5 christos char ** error_message ATTRIBUTE_UNUSED) 42 1.5 christos { 43 1.5 christos bfd_size_type octets; 44 1.9 christos octets = reloc->address * OCTETS_PER_BYTE (abfd, input_sec); 45 1.5 christos 46 1.5 christos /* Catch the case where bfd_install_relocation would return 47 1.5 christos bfd_reloc_outofrange because the SYM_DIFF reloc is being used in a very 48 1.5 christos small section. It does not actually matter if this happens because all 49 1.5 christos that SYM_DIFF does is compute a (4-byte) value. A second reloc then uses 50 1.5 christos this value, and it is that reloc that must fit into the section. 51 1.5 christos 52 1.5 christos This happens in eg, gcc/testsuite/gcc.c-torture/compile/labels-3.c. */ 53 1.5 christos if ((octets + bfd_get_reloc_size (reloc->howto)) 54 1.5 christos > bfd_get_section_limit_octets (abfd, input_sec)) 55 1.5 christos return bfd_reloc_ok; 56 1.5 christos return bfd_reloc_continue; 57 1.5 christos } 58 1.5 christos 59 1.9 christos /* Special handler for relocations which don't have to be relocated. 60 1.9 christos This function just simply returns bfd_reloc_ok. */ 61 1.9 christos static bfd_reloc_status_type 62 1.9 christos msp430_elf_ignore_reloc (bfd *abfd ATTRIBUTE_UNUSED, arelent *reloc_entry, 63 1.9 christos asymbol *symbol ATTRIBUTE_UNUSED, 64 1.9 christos void *data ATTRIBUTE_UNUSED, asection *input_section, 65 1.9 christos bfd *output_bfd, char **error_message ATTRIBUTE_UNUSED) 66 1.9 christos { 67 1.9 christos if (output_bfd != NULL) 68 1.9 christos reloc_entry->address += input_section->output_offset; 69 1.9 christos 70 1.9 christos return bfd_reloc_ok; 71 1.9 christos } 72 1.9 christos 73 1.1 christos static reloc_howto_type elf_msp430_howto_table[] = 74 1.1 christos { 75 1.1 christos HOWTO (R_MSP430_NONE, /* type */ 76 1.1 christos 0, /* rightshift */ 77 1.10 christos 0, /* size */ 78 1.5 christos 0, /* bitsize */ 79 1.10 christos false, /* pc_relative */ 80 1.1 christos 0, /* bitpos */ 81 1.5 christos complain_overflow_dont,/* complain_on_overflow */ 82 1.1 christos bfd_elf_generic_reloc, /* special_function */ 83 1.1 christos "R_MSP430_NONE", /* name */ 84 1.10 christos false, /* partial_inplace */ 85 1.1 christos 0, /* src_mask */ 86 1.1 christos 0, /* dst_mask */ 87 1.10 christos false), /* pcrel_offset */ 88 1.1 christos 89 1.1 christos HOWTO (R_MSP430_32, /* type */ 90 1.1 christos 0, /* rightshift */ 91 1.10 christos 4, /* size */ 92 1.1 christos 32, /* bitsize */ 93 1.10 christos false, /* pc_relative */ 94 1.1 christos 0, /* bitpos */ 95 1.1 christos complain_overflow_bitfield,/* complain_on_overflow */ 96 1.1 christos bfd_elf_generic_reloc, /* special_function */ 97 1.1 christos "R_MSP430_32", /* name */ 98 1.10 christos false, /* partial_inplace */ 99 1.1 christos 0xffffffff, /* src_mask */ 100 1.1 christos 0xffffffff, /* dst_mask */ 101 1.10 christos false), /* pcrel_offset */ 102 1.1 christos 103 1.1 christos /* A 10 bit PC relative relocation. */ 104 1.1 christos HOWTO (R_MSP430_10_PCREL, /* type */ 105 1.1 christos 1, /* rightshift */ 106 1.10 christos 2, /* size */ 107 1.1 christos 10, /* bitsize */ 108 1.10 christos true, /* pc_relative */ 109 1.1 christos 0, /* bitpos */ 110 1.1 christos complain_overflow_bitfield,/* complain_on_overflow */ 111 1.1 christos bfd_elf_generic_reloc, /* special_function */ 112 1.1 christos "R_MSP430_10_PCREL", /* name */ 113 1.10 christos false, /* partial_inplace */ 114 1.1 christos 0x3ff, /* src_mask */ 115 1.1 christos 0x3ff, /* dst_mask */ 116 1.10 christos true), /* pcrel_offset */ 117 1.1 christos 118 1.1 christos /* A 16 bit absolute relocation. */ 119 1.1 christos HOWTO (R_MSP430_16, /* type */ 120 1.1 christos 0, /* rightshift */ 121 1.10 christos 2, /* size */ 122 1.1 christos 16, /* bitsize */ 123 1.10 christos false, /* pc_relative */ 124 1.1 christos 0, /* bitpos */ 125 1.1 christos complain_overflow_dont,/* complain_on_overflow */ 126 1.1 christos bfd_elf_generic_reloc, /* special_function */ 127 1.1 christos "R_MSP430_16", /* name */ 128 1.10 christos false, /* partial_inplace */ 129 1.1 christos 0, /* src_mask */ 130 1.1 christos 0xffff, /* dst_mask */ 131 1.10 christos false), /* pcrel_offset */ 132 1.1 christos 133 1.1 christos /* A 16 bit PC relative relocation for command address. */ 134 1.1 christos HOWTO (R_MSP430_16_PCREL, /* type */ 135 1.1 christos 1, /* rightshift */ 136 1.10 christos 2, /* size */ 137 1.1 christos 16, /* bitsize */ 138 1.10 christos true, /* pc_relative */ 139 1.1 christos 0, /* bitpos */ 140 1.1 christos complain_overflow_dont,/* complain_on_overflow */ 141 1.1 christos bfd_elf_generic_reloc, /* special_function */ 142 1.1 christos "R_MSP430_16_PCREL", /* name */ 143 1.10 christos false, /* partial_inplace */ 144 1.1 christos 0, /* src_mask */ 145 1.1 christos 0xffff, /* dst_mask */ 146 1.10 christos true), /* pcrel_offset */ 147 1.1 christos 148 1.1 christos /* A 16 bit absolute relocation, byte operations. */ 149 1.1 christos HOWTO (R_MSP430_16_BYTE, /* type */ 150 1.1 christos 0, /* rightshift */ 151 1.10 christos 2, /* size */ 152 1.1 christos 16, /* bitsize */ 153 1.10 christos false, /* pc_relative */ 154 1.1 christos 0, /* bitpos */ 155 1.1 christos complain_overflow_dont,/* complain_on_overflow */ 156 1.1 christos bfd_elf_generic_reloc, /* special_function */ 157 1.1 christos "R_MSP430_16_BYTE", /* name */ 158 1.10 christos false, /* partial_inplace */ 159 1.1 christos 0xffff, /* src_mask */ 160 1.1 christos 0xffff, /* dst_mask */ 161 1.10 christos false), /* pcrel_offset */ 162 1.1 christos 163 1.1 christos /* A 16 bit absolute relocation for command address. */ 164 1.1 christos HOWTO (R_MSP430_16_PCREL_BYTE,/* type */ 165 1.1 christos 1, /* rightshift */ 166 1.10 christos 2, /* size */ 167 1.1 christos 16, /* bitsize */ 168 1.10 christos true, /* pc_relative */ 169 1.1 christos 0, /* bitpos */ 170 1.1 christos complain_overflow_dont,/* complain_on_overflow */ 171 1.1 christos bfd_elf_generic_reloc, /* special_function */ 172 1.1 christos "R_MSP430_16_PCREL_BYTE",/* name */ 173 1.10 christos false, /* partial_inplace */ 174 1.1 christos 0xffff, /* src_mask */ 175 1.1 christos 0xffff, /* dst_mask */ 176 1.10 christos true), /* pcrel_offset */ 177 1.1 christos 178 1.1 christos /* A 10 bit PC relative relocation for complicated polymorphs. */ 179 1.1 christos HOWTO (R_MSP430_2X_PCREL, /* type */ 180 1.1 christos 1, /* rightshift */ 181 1.10 christos 4, /* size */ 182 1.1 christos 10, /* bitsize */ 183 1.10 christos true, /* pc_relative */ 184 1.1 christos 0, /* bitpos */ 185 1.1 christos complain_overflow_bitfield,/* complain_on_overflow */ 186 1.1 christos bfd_elf_generic_reloc, /* special_function */ 187 1.1 christos "R_MSP430_2X_PCREL", /* name */ 188 1.10 christos false, /* partial_inplace */ 189 1.1 christos 0x3ff, /* src_mask */ 190 1.1 christos 0x3ff, /* dst_mask */ 191 1.10 christos true), /* pcrel_offset */ 192 1.1 christos 193 1.1 christos /* A 16 bit relaxable relocation for command address. */ 194 1.1 christos HOWTO (R_MSP430_RL_PCREL, /* type */ 195 1.1 christos 1, /* rightshift */ 196 1.10 christos 2, /* size */ 197 1.1 christos 16, /* bitsize */ 198 1.10 christos true, /* pc_relative */ 199 1.1 christos 0, /* bitpos */ 200 1.1 christos complain_overflow_dont,/* complain_on_overflow */ 201 1.1 christos bfd_elf_generic_reloc, /* special_function */ 202 1.1 christos "R_MSP430_RL_PCREL", /* name */ 203 1.10 christos false, /* partial_inplace */ 204 1.1 christos 0, /* src_mask */ 205 1.1 christos 0xffff, /* dst_mask */ 206 1.10 christos true) /* pcrel_offset */ 207 1.1 christos 208 1.1 christos /* A 8-bit absolute relocation. */ 209 1.1 christos , HOWTO (R_MSP430_8, /* type */ 210 1.1 christos 0, /* rightshift */ 211 1.10 christos 1, /* size */ 212 1.1 christos 8, /* bitsize */ 213 1.10 christos false, /* pc_relative */ 214 1.1 christos 0, /* bitpos */ 215 1.1 christos complain_overflow_dont,/* complain_on_overflow */ 216 1.1 christos bfd_elf_generic_reloc, /* special_function */ 217 1.1 christos "R_MSP430_8", /* name */ 218 1.10 christos false, /* partial_inplace */ 219 1.1 christos 0, /* src_mask */ 220 1.1 christos 0xffff, /* dst_mask */ 221 1.10 christos false), /* pcrel_offset */ 222 1.1 christos 223 1.1 christos /* Together with a following reloc, allows for the difference 224 1.1 christos between two symbols to be the real addend of the second reloc. */ 225 1.1 christos HOWTO (R_MSP430_SYM_DIFF, /* type */ 226 1.1 christos 0, /* rightshift */ 227 1.10 christos 4, /* size */ 228 1.1 christos 32, /* bitsize */ 229 1.10 christos false, /* pc_relative */ 230 1.1 christos 0, /* bitpos */ 231 1.1 christos complain_overflow_dont,/* complain_on_overflow */ 232 1.5 christos rl78_sym_diff_handler, /* special handler. */ 233 1.1 christos "R_MSP430_SYM_DIFF", /* name */ 234 1.10 christos false, /* partial_inplace */ 235 1.1 christos 0xffffffff, /* src_mask */ 236 1.1 christos 0xffffffff, /* dst_mask */ 237 1.10 christos false), /* pcrel_offset */ 238 1.9 christos 239 1.9 christos /* The length of unsigned-leb128 is variable, just assume the 240 1.9 christos size is one byte here. */ 241 1.9 christos HOWTO (R_MSP430_GNU_SET_ULEB128, /* type */ 242 1.9 christos 0, /* rightshift */ 243 1.10 christos 1, /* size */ 244 1.9 christos 0, /* bitsize */ 245 1.10 christos false, /* pc_relative */ 246 1.9 christos 0, /* bitpos */ 247 1.9 christos complain_overflow_dont, /* complain_on_overflow */ 248 1.9 christos msp430_elf_ignore_reloc, /* special handler. */ 249 1.9 christos "R_MSP430_GNU_SET_ULEB128", /* name */ 250 1.10 christos false, /* partial_inplace */ 251 1.9 christos 0, /* src_mask */ 252 1.9 christos 0, /* dst_mask */ 253 1.10 christos false), /* pcrel_offset */ 254 1.9 christos 255 1.9 christos /* The length of unsigned-leb128 is variable, just assume the 256 1.9 christos size is one byte here. */ 257 1.9 christos HOWTO (R_MSP430_GNU_SUB_ULEB128, /* type */ 258 1.9 christos 0, /* rightshift */ 259 1.10 christos 1, /* size */ 260 1.9 christos 0, /* bitsize */ 261 1.10 christos false, /* pc_relative */ 262 1.9 christos 0, /* bitpos */ 263 1.9 christos complain_overflow_dont, /* complain_on_overflow */ 264 1.9 christos msp430_elf_ignore_reloc, /* special handler. */ 265 1.9 christos "R_MSP430_GNU_SUB_ULEB128", /* name */ 266 1.10 christos false, /* partial_inplace */ 267 1.9 christos 0, /* src_mask */ 268 1.9 christos 0, /* dst_mask */ 269 1.10 christos false), /* pcrel_offset */ 270 1.9 christos 271 1.1 christos }; 272 1.1 christos 273 1.1 christos static reloc_howto_type elf_msp430x_howto_table[] = 274 1.1 christos { 275 1.1 christos HOWTO (R_MSP430_NONE, /* type */ 276 1.1 christos 0, /* rightshift */ 277 1.10 christos 0, /* size */ 278 1.5 christos 0, /* bitsize */ 279 1.10 christos false, /* pc_relative */ 280 1.1 christos 0, /* bitpos */ 281 1.5 christos complain_overflow_dont,/* complain_on_overflow */ 282 1.1 christos bfd_elf_generic_reloc, /* special_function */ 283 1.1 christos "R_MSP430_NONE", /* name */ 284 1.10 christos false, /* partial_inplace */ 285 1.1 christos 0, /* src_mask */ 286 1.1 christos 0, /* dst_mask */ 287 1.10 christos false), /* pcrel_offset */ 288 1.1 christos 289 1.1 christos HOWTO (R_MSP430_ABS32, /* type */ 290 1.1 christos 0, /* rightshift */ 291 1.10 christos 4, /* size */ 292 1.1 christos 32, /* bitsize */ 293 1.10 christos false, /* pc_relative */ 294 1.1 christos 0, /* bitpos */ 295 1.1 christos complain_overflow_bitfield,/* complain_on_overflow */ 296 1.1 christos bfd_elf_generic_reloc, /* special_function */ 297 1.1 christos "R_MSP430_ABS32", /* name */ 298 1.10 christos false, /* partial_inplace */ 299 1.1 christos 0xffffffff, /* src_mask */ 300 1.1 christos 0xffffffff, /* dst_mask */ 301 1.10 christos false), /* pcrel_offset */ 302 1.1 christos 303 1.1 christos HOWTO (R_MSP430_ABS16, /* type */ 304 1.1 christos 0, /* rightshift */ 305 1.10 christos 2, /* size */ 306 1.1 christos 16, /* bitsize */ 307 1.10 christos false, /* pc_relative */ 308 1.1 christos 0, /* bitpos */ 309 1.1 christos complain_overflow_dont,/* complain_on_overflow */ 310 1.1 christos bfd_elf_generic_reloc, /* special_function */ 311 1.1 christos "R_MSP430_ABS16", /* name */ 312 1.10 christos false, /* partial_inplace */ 313 1.1 christos 0, /* src_mask */ 314 1.1 christos 0xffff, /* dst_mask */ 315 1.10 christos false), /* pcrel_offset */ 316 1.1 christos 317 1.1 christos HOWTO (R_MSP430_ABS8, /* type */ 318 1.1 christos 0, /* rightshift */ 319 1.10 christos 1, /* size */ 320 1.1 christos 8, /* bitsize */ 321 1.10 christos false, /* pc_relative */ 322 1.1 christos 0, /* bitpos */ 323 1.1 christos complain_overflow_bitfield,/* complain_on_overflow */ 324 1.1 christos bfd_elf_generic_reloc, /* special_function */ 325 1.1 christos "R_MSP430_ABS8", /* name */ 326 1.10 christos false, /* partial_inplace */ 327 1.1 christos 0xff, /* src_mask */ 328 1.1 christos 0xff, /* dst_mask */ 329 1.10 christos false), /* pcrel_offset */ 330 1.1 christos 331 1.1 christos HOWTO (R_MSP430_PCR16, /* type */ 332 1.1 christos 1, /* rightshift */ 333 1.10 christos 2, /* size */ 334 1.1 christos 16, /* bitsize */ 335 1.10 christos true, /* pc_relative */ 336 1.1 christos 0, /* bitpos */ 337 1.1 christos complain_overflow_dont,/* complain_on_overflow */ 338 1.1 christos bfd_elf_generic_reloc, /* special_function */ 339 1.1 christos "R_MSP430_PCR16", /* name */ 340 1.10 christos false, /* partial_inplace */ 341 1.1 christos 0, /* src_mask */ 342 1.1 christos 0xffff, /* dst_mask */ 343 1.10 christos true), /* pcrel_offset */ 344 1.1 christos 345 1.1 christos HOWTO (R_MSP430X_PCR20_EXT_SRC,/* type */ 346 1.1 christos 0, /* rightshift */ 347 1.10 christos 4, /* size */ 348 1.1 christos 32, /* bitsize */ 349 1.10 christos true, /* pc_relative */ 350 1.1 christos 0, /* bitpos */ 351 1.1 christos complain_overflow_dont,/* complain_on_overflow */ 352 1.1 christos bfd_elf_generic_reloc, /* special_function */ 353 1.1 christos "R_MSP430X_PCR20_EXT_SRC",/* name */ 354 1.10 christos false, /* partial_inplace */ 355 1.1 christos 0, /* src_mask */ 356 1.1 christos 0xffff, /* dst_mask */ 357 1.10 christos true), /* pcrel_offset */ 358 1.1 christos 359 1.1 christos HOWTO (R_MSP430X_PCR20_EXT_DST,/* type */ 360 1.1 christos 0, /* rightshift */ 361 1.10 christos 4, /* size */ 362 1.1 christos 32, /* bitsize */ 363 1.10 christos true, /* pc_relative */ 364 1.1 christos 0, /* bitpos */ 365 1.1 christos complain_overflow_dont,/* complain_on_overflow */ 366 1.1 christos bfd_elf_generic_reloc, /* special_function */ 367 1.1 christos "R_MSP430X_PCR20_EXT_DST",/* name */ 368 1.10 christos false, /* partial_inplace */ 369 1.1 christos 0, /* src_mask */ 370 1.1 christos 0xffff, /* dst_mask */ 371 1.10 christos true), /* pcrel_offset */ 372 1.1 christos 373 1.1 christos HOWTO (R_MSP430X_PCR20_EXT_ODST,/* type */ 374 1.1 christos 0, /* rightshift */ 375 1.10 christos 4, /* size */ 376 1.1 christos 32, /* bitsize */ 377 1.10 christos true, /* pc_relative */ 378 1.1 christos 0, /* bitpos */ 379 1.1 christos complain_overflow_dont,/* complain_on_overflow */ 380 1.1 christos bfd_elf_generic_reloc, /* special_function */ 381 1.1 christos "R_MSP430X_PCR20_EXT_ODST",/* name */ 382 1.10 christos false, /* partial_inplace */ 383 1.1 christos 0, /* src_mask */ 384 1.1 christos 0xffff, /* dst_mask */ 385 1.10 christos true), /* pcrel_offset */ 386 1.1 christos 387 1.1 christos HOWTO (R_MSP430X_ABS20_EXT_SRC,/* type */ 388 1.1 christos 0, /* rightshift */ 389 1.10 christos 4, /* size */ 390 1.1 christos 32, /* bitsize */ 391 1.10 christos true, /* pc_relative */ 392 1.1 christos 0, /* bitpos */ 393 1.1 christos complain_overflow_dont,/* complain_on_overflow */ 394 1.1 christos bfd_elf_generic_reloc, /* special_function */ 395 1.1 christos "R_MSP430X_ABS20_EXT_SRC",/* name */ 396 1.10 christos false, /* partial_inplace */ 397 1.1 christos 0, /* src_mask */ 398 1.1 christos 0xffff, /* dst_mask */ 399 1.10 christos true), /* pcrel_offset */ 400 1.1 christos 401 1.1 christos HOWTO (R_MSP430X_ABS20_EXT_DST,/* type */ 402 1.1 christos 0, /* rightshift */ 403 1.10 christos 4, /* size */ 404 1.1 christos 32, /* bitsize */ 405 1.10 christos true, /* pc_relative */ 406 1.1 christos 0, /* bitpos */ 407 1.1 christos complain_overflow_dont,/* complain_on_overflow */ 408 1.1 christos bfd_elf_generic_reloc, /* special_function */ 409 1.1 christos "R_MSP430X_ABS20_EXT_DST",/* name */ 410 1.10 christos false, /* partial_inplace */ 411 1.1 christos 0, /* src_mask */ 412 1.1 christos 0xffff, /* dst_mask */ 413 1.10 christos true), /* pcrel_offset */ 414 1.1 christos 415 1.1 christos HOWTO (R_MSP430X_ABS20_EXT_ODST,/* type */ 416 1.1 christos 0, /* rightshift */ 417 1.10 christos 4, /* size */ 418 1.1 christos 32, /* bitsize */ 419 1.10 christos true, /* pc_relative */ 420 1.1 christos 0, /* bitpos */ 421 1.1 christos complain_overflow_dont,/* complain_on_overflow */ 422 1.1 christos bfd_elf_generic_reloc, /* special_function */ 423 1.1 christos "R_MSP430X_ABS20_EXT_ODST",/* name */ 424 1.10 christos false, /* partial_inplace */ 425 1.1 christos 0, /* src_mask */ 426 1.1 christos 0xffff, /* dst_mask */ 427 1.10 christos true), /* pcrel_offset */ 428 1.1 christos 429 1.1 christos HOWTO (R_MSP430X_ABS20_ADR_SRC,/* type */ 430 1.1 christos 0, /* rightshift */ 431 1.10 christos 4, /* size */ 432 1.1 christos 32, /* bitsize */ 433 1.10 christos true, /* pc_relative */ 434 1.1 christos 0, /* bitpos */ 435 1.1 christos complain_overflow_dont,/* complain_on_overflow */ 436 1.1 christos bfd_elf_generic_reloc, /* special_function */ 437 1.1 christos "R_MSP430X_ABS20_ADR_SRC",/* name */ 438 1.10 christos false, /* partial_inplace */ 439 1.1 christos 0, /* src_mask */ 440 1.1 christos 0xffff, /* dst_mask */ 441 1.10 christos true), /* pcrel_offset */ 442 1.1 christos 443 1.1 christos HOWTO (R_MSP430X_ABS20_ADR_DST,/* type */ 444 1.1 christos 0, /* rightshift */ 445 1.10 christos 4, /* size */ 446 1.1 christos 32, /* bitsize */ 447 1.10 christos true, /* pc_relative */ 448 1.1 christos 0, /* bitpos */ 449 1.1 christos complain_overflow_dont,/* complain_on_overflow */ 450 1.1 christos bfd_elf_generic_reloc, /* special_function */ 451 1.1 christos "R_MSP430X_ABS20_ADR_DST",/* name */ 452 1.10 christos false, /* partial_inplace */ 453 1.1 christos 0, /* src_mask */ 454 1.1 christos 0xffff, /* dst_mask */ 455 1.10 christos true), /* pcrel_offset */ 456 1.1 christos 457 1.1 christos HOWTO (R_MSP430X_PCR16, /* type */ 458 1.1 christos 0, /* rightshift */ 459 1.10 christos 4, /* size */ 460 1.1 christos 32, /* bitsize */ 461 1.10 christos true, /* pc_relative */ 462 1.1 christos 0, /* bitpos */ 463 1.1 christos complain_overflow_dont,/* complain_on_overflow */ 464 1.1 christos bfd_elf_generic_reloc, /* special_function */ 465 1.1 christos "R_MSP430X_PCR16", /* name */ 466 1.10 christos false, /* partial_inplace */ 467 1.1 christos 0, /* src_mask */ 468 1.1 christos 0xffff, /* dst_mask */ 469 1.10 christos true), /* pcrel_offset */ 470 1.1 christos 471 1.1 christos HOWTO (R_MSP430X_PCR20_CALL, /* type */ 472 1.1 christos 0, /* rightshift */ 473 1.10 christos 4, /* size */ 474 1.1 christos 32, /* bitsize */ 475 1.10 christos true, /* pc_relative */ 476 1.1 christos 0, /* bitpos */ 477 1.1 christos complain_overflow_dont,/* complain_on_overflow */ 478 1.1 christos bfd_elf_generic_reloc, /* special_function */ 479 1.1 christos "R_MSP430X_PCR20_CALL",/* name */ 480 1.10 christos false, /* partial_inplace */ 481 1.1 christos 0, /* src_mask */ 482 1.1 christos 0xffff, /* dst_mask */ 483 1.10 christos true), /* pcrel_offset */ 484 1.1 christos 485 1.1 christos HOWTO (R_MSP430X_ABS16, /* type */ 486 1.1 christos 0, /* rightshift */ 487 1.10 christos 4, /* size */ 488 1.1 christos 32, /* bitsize */ 489 1.10 christos true, /* pc_relative */ 490 1.1 christos 0, /* bitpos */ 491 1.1 christos complain_overflow_dont,/* complain_on_overflow */ 492 1.1 christos bfd_elf_generic_reloc, /* special_function */ 493 1.1 christos "R_MSP430X_ABS16", /* name */ 494 1.10 christos false, /* partial_inplace */ 495 1.1 christos 0, /* src_mask */ 496 1.1 christos 0xffff, /* dst_mask */ 497 1.10 christos true), /* pcrel_offset */ 498 1.1 christos 499 1.1 christos HOWTO (R_MSP430_ABS_HI16, /* type */ 500 1.1 christos 0, /* rightshift */ 501 1.10 christos 4, /* size */ 502 1.1 christos 32, /* bitsize */ 503 1.10 christos true, /* pc_relative */ 504 1.1 christos 0, /* bitpos */ 505 1.1 christos complain_overflow_dont,/* complain_on_overflow */ 506 1.1 christos bfd_elf_generic_reloc, /* special_function */ 507 1.1 christos "R_MSP430_ABS_HI16", /* name */ 508 1.10 christos false, /* partial_inplace */ 509 1.1 christos 0, /* src_mask */ 510 1.1 christos 0xffff, /* dst_mask */ 511 1.10 christos true), /* pcrel_offset */ 512 1.1 christos 513 1.1 christos HOWTO (R_MSP430_PREL31, /* type */ 514 1.1 christos 0, /* rightshift */ 515 1.10 christos 4, /* size */ 516 1.1 christos 32, /* bitsize */ 517 1.10 christos true, /* pc_relative */ 518 1.1 christos 0, /* bitpos */ 519 1.1 christos complain_overflow_dont,/* complain_on_overflow */ 520 1.1 christos bfd_elf_generic_reloc, /* special_function */ 521 1.1 christos "R_MSP430_PREL31", /* name */ 522 1.10 christos false, /* partial_inplace */ 523 1.1 christos 0, /* src_mask */ 524 1.1 christos 0xffff, /* dst_mask */ 525 1.10 christos true), /* pcrel_offset */ 526 1.1 christos 527 1.1 christos EMPTY_HOWTO (R_MSP430_EHTYPE), 528 1.6 christos 529 1.1 christos /* A 10 bit PC relative relocation. */ 530 1.1 christos HOWTO (R_MSP430X_10_PCREL, /* type */ 531 1.1 christos 1, /* rightshift */ 532 1.10 christos 2, /* size */ 533 1.1 christos 10, /* bitsize */ 534 1.10 christos true, /* pc_relative */ 535 1.1 christos 0, /* bitpos */ 536 1.1 christos complain_overflow_bitfield,/* complain_on_overflow */ 537 1.1 christos bfd_elf_generic_reloc, /* special_function */ 538 1.1 christos "R_MSP430X_10_PCREL", /* name */ 539 1.10 christos false, /* partial_inplace */ 540 1.1 christos 0x3ff, /* src_mask */ 541 1.1 christos 0x3ff, /* dst_mask */ 542 1.10 christos true), /* pcrel_offset */ 543 1.1 christos 544 1.1 christos /* A 10 bit PC relative relocation for complicated polymorphs. */ 545 1.1 christos HOWTO (R_MSP430X_2X_PCREL, /* type */ 546 1.1 christos 1, /* rightshift */ 547 1.10 christos 4, /* size */ 548 1.1 christos 10, /* bitsize */ 549 1.10 christos true, /* pc_relative */ 550 1.1 christos 0, /* bitpos */ 551 1.1 christos complain_overflow_bitfield,/* complain_on_overflow */ 552 1.1 christos bfd_elf_generic_reloc, /* special_function */ 553 1.1 christos "R_MSP430X_2X_PCREL", /* name */ 554 1.10 christos false, /* partial_inplace */ 555 1.1 christos 0x3ff, /* src_mask */ 556 1.1 christos 0x3ff, /* dst_mask */ 557 1.10 christos true), /* pcrel_offset */ 558 1.1 christos 559 1.1 christos /* Together with a following reloc, allows for the difference 560 1.1 christos between two symbols to be the real addend of the second reloc. */ 561 1.1 christos HOWTO (R_MSP430X_SYM_DIFF, /* type */ 562 1.1 christos 0, /* rightshift */ 563 1.10 christos 4, /* size */ 564 1.1 christos 32, /* bitsize */ 565 1.10 christos false, /* pc_relative */ 566 1.1 christos 0, /* bitpos */ 567 1.1 christos complain_overflow_dont,/* complain_on_overflow */ 568 1.5 christos rl78_sym_diff_handler, /* special handler. */ 569 1.1 christos "R_MSP430X_SYM_DIFF", /* name */ 570 1.10 christos false, /* partial_inplace */ 571 1.1 christos 0xffffffff, /* src_mask */ 572 1.1 christos 0xffffffff, /* dst_mask */ 573 1.10 christos false), /* pcrel_offset */ 574 1.9 christos 575 1.9 christos /* The length of unsigned-leb128 is variable, just assume the 576 1.9 christos size is one byte here. */ 577 1.9 christos HOWTO (R_MSP430X_GNU_SET_ULEB128, /* type */ 578 1.9 christos 0, /* rightshift */ 579 1.10 christos 1, /* size */ 580 1.9 christos 0, /* bitsize */ 581 1.10 christos false, /* pc_relative */ 582 1.9 christos 0, /* bitpos */ 583 1.9 christos complain_overflow_dont, /* complain_on_overflow */ 584 1.9 christos msp430_elf_ignore_reloc, /* special handler. */ 585 1.9 christos "R_MSP430X_GNU_SET_ULEB128", /* name */ 586 1.10 christos false, /* partial_inplace */ 587 1.9 christos 0, /* src_mask */ 588 1.9 christos 0, /* dst_mask */ 589 1.10 christos false), /* pcrel_offset */ 590 1.9 christos 591 1.9 christos /* The length of unsigned-leb128 is variable, just assume the 592 1.9 christos size is one byte here. */ 593 1.9 christos HOWTO (R_MSP430X_GNU_SUB_ULEB128, /* type */ 594 1.9 christos 0, /* rightshift */ 595 1.10 christos 1, /* size */ 596 1.9 christos 0, /* bitsize */ 597 1.10 christos false, /* pc_relative */ 598 1.9 christos 0, /* bitpos */ 599 1.9 christos complain_overflow_dont, /* complain_on_overflow */ 600 1.9 christos msp430_elf_ignore_reloc, /* special handler. */ 601 1.9 christos "R_MSP430X_GNU_SUB_ULEB128", /* name */ 602 1.10 christos false, /* partial_inplace */ 603 1.9 christos 0, /* src_mask */ 604 1.9 christos 0, /* dst_mask */ 605 1.10 christos false), /* pcrel_offset */ 606 1.9 christos 607 1.1 christos }; 608 1.1 christos 609 1.1 christos /* Map BFD reloc types to MSP430 ELF reloc types. */ 610 1.1 christos 611 1.1 christos struct msp430_reloc_map 612 1.1 christos { 613 1.1 christos bfd_reloc_code_real_type bfd_reloc_val; 614 1.1 christos unsigned int elf_reloc_val; 615 1.1 christos }; 616 1.1 christos 617 1.1 christos static const struct msp430_reloc_map msp430_reloc_map[] = 618 1.1 christos { 619 1.8 christos {BFD_RELOC_NONE, R_MSP430_NONE}, 620 1.8 christos {BFD_RELOC_32, R_MSP430_32}, 621 1.8 christos {BFD_RELOC_MSP430_10_PCREL, R_MSP430_10_PCREL}, 622 1.8 christos {BFD_RELOC_16, R_MSP430_16_BYTE}, 623 1.8 christos {BFD_RELOC_MSP430_16_PCREL, R_MSP430_16_PCREL}, 624 1.8 christos {BFD_RELOC_MSP430_16, R_MSP430_16}, 625 1.1 christos {BFD_RELOC_MSP430_16_PCREL_BYTE, R_MSP430_16_PCREL_BYTE}, 626 1.8 christos {BFD_RELOC_MSP430_16_BYTE, R_MSP430_16_BYTE}, 627 1.8 christos {BFD_RELOC_MSP430_2X_PCREL, R_MSP430_2X_PCREL}, 628 1.8 christos {BFD_RELOC_MSP430_RL_PCREL, R_MSP430_RL_PCREL}, 629 1.8 christos {BFD_RELOC_8, R_MSP430_8}, 630 1.9 christos {BFD_RELOC_MSP430_SYM_DIFF, R_MSP430_SYM_DIFF}, 631 1.9 christos {BFD_RELOC_MSP430_SET_ULEB128, R_MSP430_GNU_SET_ULEB128 }, 632 1.9 christos {BFD_RELOC_MSP430_SUB_ULEB128, R_MSP430_GNU_SUB_ULEB128 } 633 1.1 christos }; 634 1.1 christos 635 1.1 christos static const struct msp430_reloc_map msp430x_reloc_map[] = 636 1.1 christos { 637 1.8 christos {BFD_RELOC_NONE, R_MSP430_NONE}, 638 1.8 christos {BFD_RELOC_32, R_MSP430_ABS32}, 639 1.8 christos {BFD_RELOC_16, R_MSP430_ABS16}, 640 1.8 christos {BFD_RELOC_8, R_MSP430_ABS8}, 641 1.8 christos {BFD_RELOC_MSP430_ABS8, R_MSP430_ABS8}, 642 1.1 christos {BFD_RELOC_MSP430X_PCR20_EXT_SRC, R_MSP430X_PCR20_EXT_SRC}, 643 1.1 christos {BFD_RELOC_MSP430X_PCR20_EXT_DST, R_MSP430X_PCR20_EXT_DST}, 644 1.1 christos {BFD_RELOC_MSP430X_PCR20_EXT_ODST, R_MSP430X_PCR20_EXT_ODST}, 645 1.1 christos {BFD_RELOC_MSP430X_ABS20_EXT_SRC, R_MSP430X_ABS20_EXT_SRC}, 646 1.1 christos {BFD_RELOC_MSP430X_ABS20_EXT_DST, R_MSP430X_ABS20_EXT_DST}, 647 1.1 christos {BFD_RELOC_MSP430X_ABS20_EXT_ODST, R_MSP430X_ABS20_EXT_ODST}, 648 1.1 christos {BFD_RELOC_MSP430X_ABS20_ADR_SRC, R_MSP430X_ABS20_ADR_SRC}, 649 1.1 christos {BFD_RELOC_MSP430X_ABS20_ADR_DST, R_MSP430X_ABS20_ADR_DST}, 650 1.8 christos {BFD_RELOC_MSP430X_PCR16, R_MSP430X_PCR16}, 651 1.1 christos {BFD_RELOC_MSP430X_PCR20_CALL, R_MSP430X_PCR20_CALL}, 652 1.8 christos {BFD_RELOC_MSP430X_ABS16, R_MSP430X_ABS16}, 653 1.8 christos {BFD_RELOC_MSP430_ABS_HI16, R_MSP430_ABS_HI16}, 654 1.8 christos {BFD_RELOC_MSP430_PREL31, R_MSP430_PREL31}, 655 1.8 christos {BFD_RELOC_MSP430_10_PCREL, R_MSP430X_10_PCREL}, 656 1.8 christos {BFD_RELOC_MSP430_2X_PCREL, R_MSP430X_2X_PCREL}, 657 1.8 christos {BFD_RELOC_MSP430_RL_PCREL, R_MSP430X_PCR16}, 658 1.9 christos {BFD_RELOC_MSP430_SYM_DIFF, R_MSP430X_SYM_DIFF}, 659 1.9 christos {BFD_RELOC_MSP430_SET_ULEB128, R_MSP430X_GNU_SET_ULEB128 }, 660 1.9 christos {BFD_RELOC_MSP430_SUB_ULEB128, R_MSP430X_GNU_SUB_ULEB128 } 661 1.1 christos }; 662 1.1 christos 663 1.10 christos static inline bool 664 1.1 christos uses_msp430x_relocs (bfd * abfd) 665 1.1 christos { 666 1.3 christos extern const bfd_target msp430_elf32_ti_vec; 667 1.1 christos 668 1.1 christos return bfd_get_mach (abfd) == bfd_mach_msp430x 669 1.3 christos || abfd->xvec == & msp430_elf32_ti_vec; 670 1.1 christos } 671 1.1 christos 672 1.1 christos static reloc_howto_type * 673 1.1 christos bfd_elf32_bfd_reloc_type_lookup (bfd * abfd ATTRIBUTE_UNUSED, 674 1.1 christos bfd_reloc_code_real_type code) 675 1.1 christos { 676 1.1 christos unsigned int i; 677 1.1 christos 678 1.1 christos if (uses_msp430x_relocs (abfd)) 679 1.1 christos { 680 1.1 christos for (i = ARRAY_SIZE (msp430x_reloc_map); i--;) 681 1.1 christos if (msp430x_reloc_map[i].bfd_reloc_val == code) 682 1.1 christos return elf_msp430x_howto_table + msp430x_reloc_map[i].elf_reloc_val; 683 1.1 christos } 684 1.1 christos else 685 1.1 christos { 686 1.1 christos for (i = 0; i < ARRAY_SIZE (msp430_reloc_map); i++) 687 1.1 christos if (msp430_reloc_map[i].bfd_reloc_val == code) 688 1.1 christos return &elf_msp430_howto_table[msp430_reloc_map[i].elf_reloc_val]; 689 1.1 christos } 690 1.1 christos 691 1.1 christos return NULL; 692 1.1 christos } 693 1.1 christos 694 1.1 christos static reloc_howto_type * 695 1.1 christos bfd_elf32_bfd_reloc_name_lookup (bfd *abfd ATTRIBUTE_UNUSED, 696 1.1 christos const char *r_name) 697 1.1 christos { 698 1.1 christos unsigned int i; 699 1.1 christos 700 1.1 christos if (uses_msp430x_relocs (abfd)) 701 1.1 christos { 702 1.1 christos for (i = ARRAY_SIZE (elf_msp430x_howto_table); i--;) 703 1.1 christos if (elf_msp430x_howto_table[i].name != NULL 704 1.1 christos && strcasecmp (elf_msp430x_howto_table[i].name, r_name) == 0) 705 1.1 christos return elf_msp430x_howto_table + i; 706 1.1 christos } 707 1.1 christos else 708 1.1 christos { 709 1.1 christos for (i = 0; 710 1.1 christos i < (sizeof (elf_msp430_howto_table) 711 1.1 christos / sizeof (elf_msp430_howto_table[0])); 712 1.1 christos i++) 713 1.1 christos if (elf_msp430_howto_table[i].name != NULL 714 1.1 christos && strcasecmp (elf_msp430_howto_table[i].name, r_name) == 0) 715 1.1 christos return &elf_msp430_howto_table[i]; 716 1.1 christos } 717 1.1 christos 718 1.1 christos return NULL; 719 1.1 christos } 720 1.1 christos 721 1.1 christos /* Set the howto pointer for an MSP430 ELF reloc. */ 722 1.1 christos 723 1.10 christos static bool 724 1.8 christos msp430_info_to_howto_rela (bfd * abfd, 725 1.1 christos arelent * cache_ptr, 726 1.1 christos Elf_Internal_Rela * dst) 727 1.1 christos { 728 1.1 christos unsigned int r_type; 729 1.1 christos 730 1.1 christos r_type = ELF32_R_TYPE (dst->r_info); 731 1.1 christos 732 1.1 christos if (uses_msp430x_relocs (abfd)) 733 1.1 christos { 734 1.3 christos if (r_type >= (unsigned int) R_MSP430x_max) 735 1.3 christos { 736 1.7 christos /* xgettext:c-format */ 737 1.8 christos _bfd_error_handler (_("%pB: unsupported relocation type %#x"), 738 1.8 christos abfd, r_type); 739 1.8 christos bfd_set_error (bfd_error_bad_value); 740 1.10 christos return false; 741 1.3 christos } 742 1.1 christos cache_ptr->howto = elf_msp430x_howto_table + r_type; 743 1.1 christos } 744 1.8 christos else if (r_type >= (unsigned int) R_MSP430_max) 745 1.3 christos { 746 1.7 christos /* xgettext:c-format */ 747 1.8 christos _bfd_error_handler (_("%pB: unsupported relocation type %#x"), 748 1.8 christos abfd, r_type); 749 1.8 christos bfd_set_error (bfd_error_bad_value); 750 1.10 christos return false; 751 1.3 christos } 752 1.8 christos else 753 1.8 christos cache_ptr->howto = &elf_msp430_howto_table[r_type]; 754 1.8 christos 755 1.10 christos return true; 756 1.1 christos } 757 1.1 christos 758 1.1 christos /* Look through the relocs for a section during the first phase. 759 1.1 christos Since we don't do .gots or .plts, we just need to consider the 760 1.1 christos virtual table relocs for gc. */ 761 1.1 christos 762 1.10 christos static bool 763 1.1 christos elf32_msp430_check_relocs (bfd * abfd, struct bfd_link_info * info, 764 1.1 christos asection * sec, const Elf_Internal_Rela * relocs) 765 1.1 christos { 766 1.1 christos Elf_Internal_Shdr *symtab_hdr; 767 1.1 christos struct elf_link_hash_entry **sym_hashes; 768 1.1 christos const Elf_Internal_Rela *rel; 769 1.1 christos const Elf_Internal_Rela *rel_end; 770 1.1 christos 771 1.6 christos if (bfd_link_relocatable (info)) 772 1.10 christos return true; 773 1.1 christos 774 1.1 christos symtab_hdr = &elf_tdata (abfd)->symtab_hdr; 775 1.1 christos sym_hashes = elf_sym_hashes (abfd); 776 1.1 christos 777 1.1 christos rel_end = relocs + sec->reloc_count; 778 1.1 christos for (rel = relocs; rel < rel_end; rel++) 779 1.1 christos { 780 1.1 christos struct elf_link_hash_entry *h; 781 1.1 christos unsigned long r_symndx; 782 1.1 christos 783 1.1 christos r_symndx = ELF32_R_SYM (rel->r_info); 784 1.1 christos if (r_symndx < symtab_hdr->sh_info) 785 1.1 christos h = NULL; 786 1.1 christos else 787 1.1 christos { 788 1.1 christos h = sym_hashes[r_symndx - symtab_hdr->sh_info]; 789 1.1 christos while (h->root.type == bfd_link_hash_indirect 790 1.1 christos || h->root.type == bfd_link_hash_warning) 791 1.1 christos h = (struct elf_link_hash_entry *) h->root.u.i.link; 792 1.1 christos } 793 1.1 christos } 794 1.1 christos 795 1.10 christos return true; 796 1.1 christos } 797 1.1 christos 798 1.1 christos /* Perform a single relocation. By default we use the standard BFD 799 1.1 christos routines, but a few relocs, we have to do them ourselves. */ 800 1.1 christos 801 1.1 christos static bfd_reloc_status_type 802 1.8 christos msp430_final_link_relocate (reloc_howto_type * howto, 803 1.8 christos bfd * input_bfd, 804 1.8 christos asection * input_section, 805 1.8 christos bfd_byte * contents, 806 1.8 christos Elf_Internal_Rela * rel, 807 1.8 christos bfd_vma relocation, 808 1.1 christos struct bfd_link_info * info) 809 1.1 christos { 810 1.1 christos static asection * sym_diff_section; 811 1.1 christos static bfd_vma sym_diff_value; 812 1.1 christos 813 1.1 christos struct bfd_elf_section_data * esd = elf_section_data (input_section); 814 1.1 christos bfd_reloc_status_type r = bfd_reloc_ok; 815 1.1 christos bfd_vma x; 816 1.1 christos bfd_signed_vma srel; 817 1.10 christos bool is_rel_reloc = false; 818 1.1 christos 819 1.1 christos if (uses_msp430x_relocs (input_bfd)) 820 1.1 christos { 821 1.1 christos /* See if we have a REL type relocation. */ 822 1.1 christos is_rel_reloc = (esd->rel.hdr != NULL); 823 1.1 christos /* Sanity check - only one type of relocation per section. 824 1.1 christos FIXME: Theoretically it is possible to have both types, 825 1.1 christos but if that happens how can we distinguish between the two ? */ 826 1.1 christos BFD_ASSERT (! is_rel_reloc || ! esd->rela.hdr); 827 1.1 christos /* If we are using a REL relocation then the addend should be empty. */ 828 1.1 christos BFD_ASSERT (! is_rel_reloc || rel->r_addend == 0); 829 1.1 christos } 830 1.1 christos 831 1.9 christos if (debug_relocs) 832 1.9 christos printf ("writing relocation (%p) at 0x%lx type: %d\n", rel, 833 1.9 christos (long) (input_section->output_section->vma + input_section->output_offset 834 1.9 christos + rel->r_offset), howto->type); 835 1.1 christos if (sym_diff_section != NULL) 836 1.1 christos { 837 1.1 christos BFD_ASSERT (sym_diff_section == input_section); 838 1.6 christos 839 1.1 christos if (uses_msp430x_relocs (input_bfd)) 840 1.1 christos switch (howto->type) 841 1.1 christos { 842 1.9 christos case R_MSP430X_GNU_SET_ULEB128: 843 1.9 christos relocation += (!is_rel_reloc ? rel->r_addend : 0); 844 1.9 christos /* Fall through. */ 845 1.1 christos case R_MSP430_ABS32: 846 1.1 christos /* If we are computing a 32-bit value for the location lists 847 1.1 christos and the result is 0 then we add one to the value. A zero 848 1.1 christos value can result because of linker relaxation deleteing 849 1.1 christos prologue instructions and using a value of 1 (for the begin 850 1.1 christos and end offsets in the location list entry) results in a 851 1.1 christos nul entry which does not prevent the following entries from 852 1.1 christos being parsed. */ 853 1.1 christos if (relocation == sym_diff_value 854 1.1 christos && strcmp (input_section->name, ".debug_loc") == 0) 855 1.1 christos ++ relocation; 856 1.1 christos /* Fall through. */ 857 1.1 christos case R_MSP430_ABS16: 858 1.1 christos case R_MSP430X_ABS16: 859 1.1 christos case R_MSP430_ABS8: 860 1.1 christos BFD_ASSERT (! is_rel_reloc); 861 1.1 christos relocation -= sym_diff_value; 862 1.1 christos break; 863 1.1 christos 864 1.1 christos default: 865 1.1 christos return bfd_reloc_dangerous; 866 1.1 christos } 867 1.1 christos else 868 1.1 christos switch (howto->type) 869 1.1 christos { 870 1.9 christos case R_MSP430_GNU_SET_ULEB128: 871 1.9 christos relocation += (!is_rel_reloc ? rel->r_addend : 0); 872 1.9 christos /* Fall through. */ 873 1.1 christos case R_MSP430_32: 874 1.1 christos case R_MSP430_16: 875 1.1 christos case R_MSP430_16_BYTE: 876 1.1 christos case R_MSP430_8: 877 1.1 christos relocation -= sym_diff_value; 878 1.1 christos break; 879 1.1 christos 880 1.1 christos default: 881 1.1 christos return bfd_reloc_dangerous; 882 1.1 christos } 883 1.6 christos 884 1.1 christos sym_diff_section = NULL; 885 1.1 christos } 886 1.1 christos 887 1.9 christos if ((uses_msp430x_relocs (input_bfd) 888 1.9 christos && howto->type == R_MSP430X_GNU_SET_ULEB128) 889 1.9 christos || (!uses_msp430x_relocs (input_bfd) 890 1.9 christos && howto->type == R_MSP430_GNU_SET_ULEB128)) 891 1.9 christos { 892 1.9 christos unsigned int len, new_len = 0; 893 1.9 christos bfd_byte *endp, *p; 894 1.9 christos unsigned int val = relocation; 895 1.9 christos 896 1.9 christos _bfd_read_unsigned_leb128 (input_bfd, contents + rel->r_offset, &len); 897 1.9 christos 898 1.9 christos /* Clean the contents value to zero. Do not reduce the length. */ 899 1.9 christos p = contents + rel->r_offset; 900 1.9 christos endp = (p + len) - 1; 901 1.9 christos memset (p, 0x80, len - 1); 902 1.9 christos *(endp) = 0; 903 1.9 christos 904 1.9 christos /* Get the length of the new uleb128 value. */ 905 1.9 christos do 906 1.9 christos { 907 1.9 christos new_len++; 908 1.9 christos val >>= 7; 909 1.9 christos } while (val); 910 1.9 christos 911 1.9 christos if (new_len > len) 912 1.9 christos { 913 1.9 christos _bfd_error_handler 914 1.9 christos (_("error: final size of uleb128 value at offset 0x%lx in %pA " 915 1.9 christos "from %pB exceeds available space"), 916 1.9 christos (long) rel->r_offset, input_section, input_bfd); 917 1.9 christos } 918 1.9 christos else 919 1.9 christos { 920 1.9 christos /* If the number of bytes required to store the new value has 921 1.9 christos decreased, "right align" the new value within the available space, 922 1.9 christos so the MSB side is padded with uleb128 zeros (0x80). */ 923 1.9 christos p = _bfd_write_unsigned_leb128 (p + (len - new_len), endp, 924 1.9 christos relocation); 925 1.9 christos /* We checked there is enough space for the new value above, so this 926 1.9 christos should never be NULL. */ 927 1.9 christos BFD_ASSERT (p); 928 1.9 christos } 929 1.9 christos 930 1.9 christos return bfd_reloc_ok; 931 1.9 christos } 932 1.9 christos else if (uses_msp430x_relocs (input_bfd)) 933 1.1 christos switch (howto->type) 934 1.1 christos { 935 1.1 christos case R_MSP430X_SYM_DIFF: 936 1.9 christos case R_MSP430X_GNU_SUB_ULEB128: 937 1.1 christos /* Cache the input section and value. 938 1.1 christos The offset is unreliable, since relaxation may 939 1.1 christos have reduced the following reloc's offset. */ 940 1.1 christos BFD_ASSERT (! is_rel_reloc); 941 1.1 christos sym_diff_section = input_section; 942 1.9 christos sym_diff_value = relocation + (howto->type == R_MSP430X_GNU_SUB_ULEB128 943 1.9 christos ? rel->r_addend : 0); 944 1.1 christos return bfd_reloc_ok; 945 1.1 christos 946 1.1 christos case R_MSP430_ABS16: 947 1.1 christos contents += rel->r_offset; 948 1.1 christos srel = (bfd_signed_vma) relocation; 949 1.1 christos if (is_rel_reloc) 950 1.1 christos srel += bfd_get_16 (input_bfd, contents); 951 1.1 christos else 952 1.1 christos srel += rel->r_addend; 953 1.1 christos bfd_put_16 (input_bfd, srel & 0xffff, contents); 954 1.1 christos break; 955 1.1 christos 956 1.1 christos case R_MSP430X_10_PCREL: 957 1.1 christos contents += rel->r_offset; 958 1.1 christos srel = (bfd_signed_vma) relocation; 959 1.1 christos if (is_rel_reloc) 960 1.1 christos srel += bfd_get_16 (input_bfd, contents) & 0x3ff; 961 1.1 christos else 962 1.1 christos srel += rel->r_addend; 963 1.1 christos srel -= rel->r_offset; 964 1.1 christos srel -= 2; /* Branch instructions add 2 to the PC... */ 965 1.1 christos srel -= (input_section->output_section->vma + 966 1.1 christos input_section->output_offset); 967 1.1 christos if (srel & 1) 968 1.1 christos return bfd_reloc_outofrange; 969 1.1 christos 970 1.1 christos /* MSP430 addresses commands as words. */ 971 1.1 christos srel >>= 1; 972 1.1 christos 973 1.1 christos /* Check for an overflow. */ 974 1.1 christos if (srel < -512 || srel > 511) 975 1.1 christos { 976 1.1 christos if (info->disable_target_specific_optimizations < 0) 977 1.1 christos { 978 1.10 christos static bool warned = false; 979 1.1 christos if (! warned) 980 1.1 christos { 981 1.1 christos info->callbacks->warning 982 1.1 christos (info, 983 1.8 christos _("try enabling relaxation to avoid relocation truncations"), 984 1.1 christos NULL, input_bfd, input_section, relocation); 985 1.10 christos warned = true; 986 1.1 christos } 987 1.1 christos } 988 1.1 christos return bfd_reloc_overflow; 989 1.1 christos } 990 1.1 christos 991 1.1 christos x = bfd_get_16 (input_bfd, contents); 992 1.1 christos x = (x & 0xfc00) | (srel & 0x3ff); 993 1.1 christos bfd_put_16 (input_bfd, x, contents); 994 1.1 christos break; 995 1.1 christos 996 1.1 christos case R_MSP430X_PCR20_EXT_ODST: 997 1.5 christos /* [0,4]+[48,16] = ---F ---- ---- FFFF */ 998 1.1 christos contents += rel->r_offset; 999 1.1 christos srel = (bfd_signed_vma) relocation; 1000 1.1 christos if (is_rel_reloc) 1001 1.1 christos { 1002 1.1 christos bfd_vma addend; 1003 1.1 christos addend = (bfd_get_16 (input_bfd, contents) & 0xf) << 16; 1004 1.5 christos addend |= bfd_get_16 (input_bfd, contents + 6); 1005 1.1 christos srel += addend; 1006 1.6 christos 1007 1.1 christos } 1008 1.1 christos else 1009 1.1 christos srel += rel->r_addend; 1010 1.1 christos srel -= rel->r_offset; 1011 1.1 christos srel -= (input_section->output_section->vma + 1012 1.1 christos input_section->output_offset); 1013 1.1 christos bfd_put_16 (input_bfd, (srel & 0xffff), contents + 6); 1014 1.1 christos x = bfd_get_16 (input_bfd, contents); 1015 1.1 christos x = (x & 0xfff0) | ((srel >> 16) & 0xf); 1016 1.1 christos bfd_put_16 (input_bfd, x, contents); 1017 1.1 christos break; 1018 1.1 christos 1019 1.1 christos case R_MSP430X_ABS20_EXT_SRC: 1020 1.5 christos /* [7,4]+[32,16] = -78- ---- FFFF */ 1021 1.1 christos contents += rel->r_offset; 1022 1.1 christos srel = (bfd_signed_vma) relocation; 1023 1.1 christos if (is_rel_reloc) 1024 1.1 christos { 1025 1.1 christos bfd_vma addend; 1026 1.1 christos addend = (bfd_get_16 (input_bfd, contents) & 0x0780) << 9; 1027 1.5 christos addend |= bfd_get_16 (input_bfd, contents + 4); 1028 1.1 christos srel += addend; 1029 1.1 christos } 1030 1.1 christos else 1031 1.1 christos srel += rel->r_addend; 1032 1.1 christos bfd_put_16 (input_bfd, (srel & 0xffff), contents + 4); 1033 1.1 christos srel >>= 16; 1034 1.1 christos x = bfd_get_16 (input_bfd, contents); 1035 1.1 christos x = (x & 0xf87f) | ((srel << 7) & 0x0780); 1036 1.1 christos bfd_put_16 (input_bfd, x, contents); 1037 1.1 christos break; 1038 1.1 christos 1039 1.1 christos case R_MSP430_16_PCREL: 1040 1.1 christos contents += rel->r_offset; 1041 1.1 christos srel = (bfd_signed_vma) relocation; 1042 1.1 christos if (is_rel_reloc) 1043 1.1 christos srel += bfd_get_16 (input_bfd, contents); 1044 1.1 christos else 1045 1.1 christos srel += rel->r_addend; 1046 1.1 christos srel -= rel->r_offset; 1047 1.1 christos /* Only branch instructions add 2 to the PC... */ 1048 1.1 christos srel -= (input_section->output_section->vma + 1049 1.1 christos input_section->output_offset); 1050 1.1 christos if (srel & 1) 1051 1.1 christos return bfd_reloc_outofrange; 1052 1.1 christos bfd_put_16 (input_bfd, srel & 0xffff, contents); 1053 1.1 christos break; 1054 1.1 christos 1055 1.1 christos case R_MSP430X_PCR20_EXT_DST: 1056 1.5 christos /* [0,4]+[32,16] = ---F ---- FFFF */ 1057 1.1 christos contents += rel->r_offset; 1058 1.1 christos srel = (bfd_signed_vma) relocation; 1059 1.1 christos if (is_rel_reloc) 1060 1.1 christos { 1061 1.1 christos bfd_vma addend; 1062 1.1 christos addend = (bfd_get_16 (input_bfd, contents) & 0xf) << 16; 1063 1.5 christos addend |= bfd_get_16 (input_bfd, contents + 4); 1064 1.1 christos srel += addend; 1065 1.1 christos } 1066 1.1 christos else 1067 1.1 christos srel += rel->r_addend; 1068 1.1 christos srel -= rel->r_offset; 1069 1.1 christos srel -= (input_section->output_section->vma + 1070 1.1 christos input_section->output_offset); 1071 1.1 christos bfd_put_16 (input_bfd, (srel & 0xffff), contents + 4); 1072 1.1 christos srel >>= 16; 1073 1.1 christos x = bfd_get_16 (input_bfd, contents); 1074 1.1 christos x = (x & 0xfff0) | (srel & 0xf); 1075 1.1 christos bfd_put_16 (input_bfd, x, contents); 1076 1.1 christos break; 1077 1.1 christos 1078 1.1 christos case R_MSP430X_PCR20_EXT_SRC: 1079 1.5 christos /* [7,4]+[32,16] = -78- ---- FFFF */ 1080 1.1 christos contents += rel->r_offset; 1081 1.1 christos srel = (bfd_signed_vma) relocation; 1082 1.1 christos if (is_rel_reloc) 1083 1.1 christos { 1084 1.1 christos bfd_vma addend; 1085 1.1 christos addend = ((bfd_get_16 (input_bfd, contents) & 0x0780) << 9); 1086 1.5 christos addend |= bfd_get_16 (input_bfd, contents + 4); 1087 1.1 christos srel += addend;; 1088 1.1 christos } 1089 1.1 christos else 1090 1.1 christos srel += rel->r_addend; 1091 1.1 christos srel -= rel->r_offset; 1092 1.1 christos /* Only branch instructions add 2 to the PC... */ 1093 1.1 christos srel -= (input_section->output_section->vma + 1094 1.1 christos input_section->output_offset); 1095 1.1 christos bfd_put_16 (input_bfd, (srel & 0xffff), contents + 4); 1096 1.1 christos srel >>= 16; 1097 1.1 christos x = bfd_get_16 (input_bfd, contents); 1098 1.1 christos x = (x & 0xf87f) | ((srel << 7) & 0x0780); 1099 1.1 christos bfd_put_16 (input_bfd, x, contents); 1100 1.1 christos break; 1101 1.1 christos 1102 1.1 christos case R_MSP430_ABS8: 1103 1.1 christos contents += rel->r_offset; 1104 1.1 christos srel = (bfd_signed_vma) relocation; 1105 1.1 christos if (is_rel_reloc) 1106 1.1 christos srel += bfd_get_8 (input_bfd, contents); 1107 1.1 christos else 1108 1.1 christos srel += rel->r_addend; 1109 1.1 christos bfd_put_8 (input_bfd, srel & 0xff, contents); 1110 1.1 christos break; 1111 1.1 christos 1112 1.1 christos case R_MSP430X_ABS20_EXT_DST: 1113 1.5 christos /* [0,4]+[32,16] = ---F ---- FFFF */ 1114 1.1 christos contents += rel->r_offset; 1115 1.1 christos srel = (bfd_signed_vma) relocation; 1116 1.1 christos if (is_rel_reloc) 1117 1.5 christos { 1118 1.5 christos bfd_vma addend; 1119 1.5 christos addend = (bfd_get_16 (input_bfd, contents) & 0xf) << 16; 1120 1.5 christos addend |= bfd_get_16 (input_bfd, contents + 4); 1121 1.5 christos srel += addend; 1122 1.5 christos } 1123 1.1 christos else 1124 1.1 christos srel += rel->r_addend; 1125 1.1 christos bfd_put_16 (input_bfd, (srel & 0xffff), contents + 4); 1126 1.1 christos srel >>= 16; 1127 1.1 christos x = bfd_get_16 (input_bfd, contents); 1128 1.1 christos x = (x & 0xfff0) | (srel & 0xf); 1129 1.1 christos bfd_put_16 (input_bfd, x, contents); 1130 1.1 christos break; 1131 1.1 christos 1132 1.1 christos case R_MSP430X_ABS20_EXT_ODST: 1133 1.5 christos /* [0,4]+[48,16] = ---F ---- ---- FFFF */ 1134 1.1 christos contents += rel->r_offset; 1135 1.1 christos srel = (bfd_signed_vma) relocation; 1136 1.1 christos if (is_rel_reloc) 1137 1.1 christos { 1138 1.1 christos bfd_vma addend; 1139 1.1 christos addend = (bfd_get_16 (input_bfd, contents) & 0xf) << 16; 1140 1.5 christos addend |= bfd_get_16 (input_bfd, contents + 6); 1141 1.1 christos srel += addend; 1142 1.1 christos } 1143 1.1 christos else 1144 1.1 christos srel += rel->r_addend; 1145 1.1 christos bfd_put_16 (input_bfd, (srel & 0xffff), contents + 6); 1146 1.1 christos srel >>= 16; 1147 1.1 christos x = bfd_get_16 (input_bfd, contents); 1148 1.1 christos x = (x & 0xfff0) | (srel & 0xf); 1149 1.1 christos bfd_put_16 (input_bfd, x, contents); 1150 1.1 christos break; 1151 1.1 christos 1152 1.1 christos case R_MSP430X_ABS20_ADR_SRC: 1153 1.5 christos /* [8,4]+[16,16] = -F-- FFFF */ 1154 1.1 christos contents += rel->r_offset; 1155 1.1 christos srel = (bfd_signed_vma) relocation; 1156 1.1 christos if (is_rel_reloc) 1157 1.1 christos { 1158 1.1 christos bfd_vma addend; 1159 1.1 christos 1160 1.1 christos addend = ((bfd_get_16 (input_bfd, contents) & 0xf00) << 8); 1161 1.5 christos addend |= bfd_get_16 (input_bfd, contents + 2); 1162 1.1 christos srel += addend; 1163 1.1 christos } 1164 1.1 christos else 1165 1.1 christos srel += rel->r_addend; 1166 1.1 christos bfd_put_16 (input_bfd, (srel & 0xffff), contents + 2); 1167 1.1 christos srel >>= 16; 1168 1.1 christos x = bfd_get_16 (input_bfd, contents); 1169 1.1 christos x = (x & 0xf0ff) | ((srel << 8) & 0x0f00); 1170 1.1 christos bfd_put_16 (input_bfd, x, contents); 1171 1.1 christos break; 1172 1.1 christos 1173 1.1 christos case R_MSP430X_ABS20_ADR_DST: 1174 1.5 christos /* [0,4]+[16,16] = ---F FFFF */ 1175 1.1 christos contents += rel->r_offset; 1176 1.1 christos srel = (bfd_signed_vma) relocation; 1177 1.1 christos if (is_rel_reloc) 1178 1.1 christos { 1179 1.1 christos bfd_vma addend; 1180 1.1 christos addend = ((bfd_get_16 (input_bfd, contents) & 0xf) << 16); 1181 1.5 christos addend |= bfd_get_16 (input_bfd, contents + 2); 1182 1.1 christos srel += addend; 1183 1.1 christos } 1184 1.1 christos else 1185 1.1 christos srel += rel->r_addend; 1186 1.1 christos bfd_put_16 (input_bfd, (srel & 0xffff), contents + 2); 1187 1.1 christos srel >>= 16; 1188 1.1 christos x = bfd_get_16 (input_bfd, contents); 1189 1.1 christos x = (x & 0xfff0) | (srel & 0xf); 1190 1.1 christos bfd_put_16 (input_bfd, x, contents); 1191 1.1 christos break; 1192 1.1 christos 1193 1.1 christos case R_MSP430X_ABS16: 1194 1.1 christos contents += rel->r_offset; 1195 1.1 christos srel = (bfd_signed_vma) relocation; 1196 1.1 christos if (is_rel_reloc) 1197 1.1 christos srel += bfd_get_16 (input_bfd, contents); 1198 1.1 christos else 1199 1.1 christos srel += rel->r_addend; 1200 1.1 christos x = srel; 1201 1.1 christos if (x > 0xffff) 1202 1.6 christos return bfd_reloc_overflow; 1203 1.1 christos bfd_put_16 (input_bfd, srel & 0xffff, contents); 1204 1.1 christos break; 1205 1.1 christos 1206 1.1 christos case R_MSP430_ABS_HI16: 1207 1.1 christos /* The EABI specifies that this must be a RELA reloc. */ 1208 1.1 christos BFD_ASSERT (! is_rel_reloc); 1209 1.1 christos contents += rel->r_offset; 1210 1.1 christos srel = (bfd_signed_vma) relocation; 1211 1.1 christos srel += rel->r_addend; 1212 1.1 christos bfd_put_16 (input_bfd, (srel >> 16) & 0xffff, contents); 1213 1.1 christos break; 1214 1.6 christos 1215 1.1 christos case R_MSP430X_PCR20_CALL: 1216 1.5 christos /* [0,4]+[16,16] = ---F FFFF*/ 1217 1.1 christos contents += rel->r_offset; 1218 1.1 christos srel = (bfd_signed_vma) relocation; 1219 1.1 christos if (is_rel_reloc) 1220 1.1 christos { 1221 1.1 christos bfd_vma addend; 1222 1.1 christos addend = (bfd_get_16 (input_bfd, contents) & 0xf) << 16; 1223 1.5 christos addend |= bfd_get_16 (input_bfd, contents + 2); 1224 1.1 christos srel += addend; 1225 1.1 christos } 1226 1.1 christos else 1227 1.1 christos srel += rel->r_addend; 1228 1.1 christos srel -= rel->r_offset; 1229 1.1 christos srel -= (input_section->output_section->vma + 1230 1.1 christos input_section->output_offset); 1231 1.1 christos bfd_put_16 (input_bfd, srel & 0xffff, contents + 2); 1232 1.1 christos srel >>= 16; 1233 1.1 christos x = bfd_get_16 (input_bfd, contents); 1234 1.1 christos x = (x & 0xfff0) | (srel & 0xf); 1235 1.1 christos bfd_put_16 (input_bfd, x, contents); 1236 1.1 christos break; 1237 1.6 christos 1238 1.1 christos case R_MSP430X_PCR16: 1239 1.1 christos contents += rel->r_offset; 1240 1.1 christos srel = (bfd_signed_vma) relocation; 1241 1.1 christos if (is_rel_reloc) 1242 1.1 christos srel += bfd_get_16 (input_bfd, contents); 1243 1.1 christos else 1244 1.1 christos srel += rel->r_addend; 1245 1.1 christos srel -= rel->r_offset; 1246 1.1 christos srel -= (input_section->output_section->vma + 1247 1.1 christos input_section->output_offset); 1248 1.1 christos bfd_put_16 (input_bfd, srel & 0xffff, contents); 1249 1.1 christos break; 1250 1.6 christos 1251 1.1 christos case R_MSP430_PREL31: 1252 1.1 christos contents += rel->r_offset; 1253 1.1 christos srel = (bfd_signed_vma) relocation; 1254 1.1 christos if (is_rel_reloc) 1255 1.1 christos srel += (bfd_get_32 (input_bfd, contents) & 0x7fffffff); 1256 1.1 christos else 1257 1.1 christos srel += rel->r_addend; 1258 1.1 christos srel += rel->r_addend; 1259 1.1 christos x = bfd_get_32 (input_bfd, contents); 1260 1.1 christos x = (x & 0x80000000) | ((srel >> 31) & 0x7fffffff); 1261 1.1 christos bfd_put_32 (input_bfd, x, contents); 1262 1.1 christos break; 1263 1.6 christos 1264 1.1 christos default: 1265 1.1 christos r = _bfd_final_link_relocate (howto, input_bfd, input_section, 1266 1.1 christos contents, rel->r_offset, 1267 1.1 christos relocation, rel->r_addend); 1268 1.1 christos } 1269 1.1 christos else 1270 1.1 christos switch (howto->type) 1271 1.1 christos { 1272 1.1 christos case R_MSP430_10_PCREL: 1273 1.1 christos contents += rel->r_offset; 1274 1.1 christos srel = (bfd_signed_vma) relocation; 1275 1.1 christos srel += rel->r_addend; 1276 1.1 christos srel -= rel->r_offset; 1277 1.1 christos srel -= 2; /* Branch instructions add 2 to the PC... */ 1278 1.1 christos srel -= (input_section->output_section->vma + 1279 1.1 christos input_section->output_offset); 1280 1.1 christos 1281 1.1 christos if (srel & 1) 1282 1.1 christos return bfd_reloc_outofrange; 1283 1.1 christos 1284 1.1 christos /* MSP430 addresses commands as words. */ 1285 1.1 christos srel >>= 1; 1286 1.1 christos 1287 1.1 christos /* Check for an overflow. */ 1288 1.1 christos if (srel < -512 || srel > 511) 1289 1.1 christos { 1290 1.1 christos if (info->disable_target_specific_optimizations < 0) 1291 1.1 christos { 1292 1.10 christos static bool warned = false; 1293 1.1 christos if (! warned) 1294 1.1 christos { 1295 1.1 christos info->callbacks->warning 1296 1.1 christos (info, 1297 1.8 christos _("try enabling relaxation to avoid relocation truncations"), 1298 1.1 christos NULL, input_bfd, input_section, relocation); 1299 1.10 christos warned = true; 1300 1.1 christos } 1301 1.1 christos } 1302 1.1 christos return bfd_reloc_overflow; 1303 1.1 christos } 1304 1.6 christos 1305 1.1 christos x = bfd_get_16 (input_bfd, contents); 1306 1.1 christos x = (x & 0xfc00) | (srel & 0x3ff); 1307 1.1 christos bfd_put_16 (input_bfd, x, contents); 1308 1.1 christos break; 1309 1.1 christos 1310 1.1 christos case R_MSP430_2X_PCREL: 1311 1.1 christos contents += rel->r_offset; 1312 1.1 christos srel = (bfd_signed_vma) relocation; 1313 1.1 christos srel += rel->r_addend; 1314 1.1 christos srel -= rel->r_offset; 1315 1.1 christos srel -= 2; /* Branch instructions add 2 to the PC... */ 1316 1.1 christos srel -= (input_section->output_section->vma + 1317 1.1 christos input_section->output_offset); 1318 1.1 christos 1319 1.1 christos if (srel & 1) 1320 1.1 christos return bfd_reloc_outofrange; 1321 1.1 christos 1322 1.1 christos /* MSP430 addresses commands as words. */ 1323 1.1 christos srel >>= 1; 1324 1.1 christos 1325 1.1 christos /* Check for an overflow. */ 1326 1.1 christos if (srel < -512 || srel > 511) 1327 1.1 christos return bfd_reloc_overflow; 1328 1.1 christos 1329 1.1 christos x = bfd_get_16 (input_bfd, contents); 1330 1.1 christos x = (x & 0xfc00) | (srel & 0x3ff); 1331 1.1 christos bfd_put_16 (input_bfd, x, contents); 1332 1.1 christos /* Handle second jump instruction. */ 1333 1.1 christos x = bfd_get_16 (input_bfd, contents - 2); 1334 1.1 christos srel += 1; 1335 1.1 christos x = (x & 0xfc00) | (srel & 0x3ff); 1336 1.1 christos bfd_put_16 (input_bfd, x, contents - 2); 1337 1.1 christos break; 1338 1.1 christos 1339 1.1 christos case R_MSP430_RL_PCREL: 1340 1.1 christos case R_MSP430_16_PCREL: 1341 1.1 christos contents += rel->r_offset; 1342 1.1 christos srel = (bfd_signed_vma) relocation; 1343 1.1 christos srel += rel->r_addend; 1344 1.1 christos srel -= rel->r_offset; 1345 1.1 christos /* Only branch instructions add 2 to the PC... */ 1346 1.1 christos srel -= (input_section->output_section->vma + 1347 1.1 christos input_section->output_offset); 1348 1.1 christos 1349 1.1 christos if (srel & 1) 1350 1.1 christos return bfd_reloc_outofrange; 1351 1.1 christos 1352 1.1 christos bfd_put_16 (input_bfd, srel & 0xffff, contents); 1353 1.1 christos break; 1354 1.1 christos 1355 1.1 christos case R_MSP430_16_PCREL_BYTE: 1356 1.1 christos contents += rel->r_offset; 1357 1.1 christos srel = (bfd_signed_vma) relocation; 1358 1.1 christos srel += rel->r_addend; 1359 1.1 christos srel -= rel->r_offset; 1360 1.1 christos /* Only branch instructions add 2 to the PC... */ 1361 1.1 christos srel -= (input_section->output_section->vma + 1362 1.1 christos input_section->output_offset); 1363 1.1 christos 1364 1.1 christos bfd_put_16 (input_bfd, srel & 0xffff, contents); 1365 1.1 christos break; 1366 1.1 christos 1367 1.1 christos case R_MSP430_16_BYTE: 1368 1.1 christos contents += rel->r_offset; 1369 1.1 christos srel = (bfd_signed_vma) relocation; 1370 1.1 christos srel += rel->r_addend; 1371 1.1 christos bfd_put_16 (input_bfd, srel & 0xffff, contents); 1372 1.1 christos break; 1373 1.1 christos 1374 1.1 christos case R_MSP430_16: 1375 1.1 christos contents += rel->r_offset; 1376 1.1 christos srel = (bfd_signed_vma) relocation; 1377 1.1 christos srel += rel->r_addend; 1378 1.1 christos 1379 1.1 christos if (srel & 1) 1380 1.1 christos return bfd_reloc_notsupported; 1381 1.1 christos 1382 1.1 christos bfd_put_16 (input_bfd, srel & 0xffff, contents); 1383 1.1 christos break; 1384 1.1 christos 1385 1.1 christos case R_MSP430_8: 1386 1.1 christos contents += rel->r_offset; 1387 1.1 christos srel = (bfd_signed_vma) relocation; 1388 1.1 christos srel += rel->r_addend; 1389 1.1 christos 1390 1.1 christos bfd_put_8 (input_bfd, srel & 0xff, contents); 1391 1.1 christos break; 1392 1.6 christos 1393 1.1 christos case R_MSP430_SYM_DIFF: 1394 1.9 christos case R_MSP430_GNU_SUB_ULEB128: 1395 1.1 christos /* Cache the input section and value. 1396 1.1 christos The offset is unreliable, since relaxation may 1397 1.1 christos have reduced the following reloc's offset. */ 1398 1.1 christos sym_diff_section = input_section; 1399 1.9 christos sym_diff_value = relocation + (howto->type == R_MSP430_GNU_SUB_ULEB128 1400 1.9 christos ? rel->r_addend : 0); 1401 1.1 christos return bfd_reloc_ok; 1402 1.1 christos 1403 1.1 christos default: 1404 1.1 christos r = _bfd_final_link_relocate (howto, input_bfd, input_section, 1405 1.1 christos contents, rel->r_offset, 1406 1.1 christos relocation, rel->r_addend); 1407 1.1 christos } 1408 1.1 christos 1409 1.1 christos return r; 1410 1.1 christos } 1411 1.1 christos 1412 1.1 christos /* Relocate an MSP430 ELF section. */ 1413 1.1 christos 1414 1.10 christos static int 1415 1.1 christos elf32_msp430_relocate_section (bfd * output_bfd ATTRIBUTE_UNUSED, 1416 1.1 christos struct bfd_link_info * info, 1417 1.1 christos bfd * input_bfd, 1418 1.1 christos asection * input_section, 1419 1.1 christos bfd_byte * contents, 1420 1.1 christos Elf_Internal_Rela * relocs, 1421 1.1 christos Elf_Internal_Sym * local_syms, 1422 1.1 christos asection ** local_sections) 1423 1.1 christos { 1424 1.1 christos Elf_Internal_Shdr *symtab_hdr; 1425 1.1 christos struct elf_link_hash_entry **sym_hashes; 1426 1.1 christos Elf_Internal_Rela *rel; 1427 1.1 christos Elf_Internal_Rela *relend; 1428 1.1 christos 1429 1.1 christos symtab_hdr = &elf_tdata (input_bfd)->symtab_hdr; 1430 1.1 christos sym_hashes = elf_sym_hashes (input_bfd); 1431 1.1 christos relend = relocs + input_section->reloc_count; 1432 1.1 christos 1433 1.1 christos for (rel = relocs; rel < relend; rel++) 1434 1.1 christos { 1435 1.1 christos reloc_howto_type *howto; 1436 1.1 christos unsigned long r_symndx; 1437 1.1 christos Elf_Internal_Sym *sym; 1438 1.1 christos asection *sec; 1439 1.1 christos struct elf_link_hash_entry *h; 1440 1.1 christos bfd_vma relocation; 1441 1.1 christos bfd_reloc_status_type r; 1442 1.1 christos const char *name = NULL; 1443 1.1 christos int r_type; 1444 1.1 christos 1445 1.1 christos r_type = ELF32_R_TYPE (rel->r_info); 1446 1.1 christos r_symndx = ELF32_R_SYM (rel->r_info); 1447 1.1 christos 1448 1.1 christos if (uses_msp430x_relocs (input_bfd)) 1449 1.1 christos howto = elf_msp430x_howto_table + r_type; 1450 1.1 christos else 1451 1.1 christos howto = elf_msp430_howto_table + r_type; 1452 1.1 christos 1453 1.1 christos h = NULL; 1454 1.1 christos sym = NULL; 1455 1.1 christos sec = NULL; 1456 1.1 christos 1457 1.1 christos if (r_symndx < symtab_hdr->sh_info) 1458 1.1 christos { 1459 1.1 christos sym = local_syms + r_symndx; 1460 1.1 christos sec = local_sections[r_symndx]; 1461 1.1 christos relocation = _bfd_elf_rela_local_sym (output_bfd, sym, &sec, rel); 1462 1.1 christos 1463 1.1 christos name = bfd_elf_string_from_elf_section 1464 1.1 christos (input_bfd, symtab_hdr->sh_link, sym->st_name); 1465 1.9 christos name = name == NULL || *name == 0 ? bfd_section_name (sec) : name; 1466 1.1 christos } 1467 1.1 christos else 1468 1.1 christos { 1469 1.10 christos bool unresolved_reloc, warned, ignored; 1470 1.1 christos 1471 1.1 christos RELOC_FOR_GLOBAL_SYMBOL (info, input_bfd, input_section, rel, 1472 1.1 christos r_symndx, symtab_hdr, sym_hashes, 1473 1.1 christos h, sec, relocation, 1474 1.1 christos unresolved_reloc, warned, ignored); 1475 1.1 christos name = h->root.root.string; 1476 1.1 christos } 1477 1.1 christos 1478 1.1 christos if (sec != NULL && discarded_section (sec)) 1479 1.1 christos RELOC_AGAINST_DISCARDED_SECTION (info, input_bfd, input_section, 1480 1.1 christos rel, 1, relend, howto, 0, contents); 1481 1.1 christos 1482 1.6 christos if (bfd_link_relocatable (info)) 1483 1.1 christos continue; 1484 1.1 christos 1485 1.1 christos r = msp430_final_link_relocate (howto, input_bfd, input_section, 1486 1.1 christos contents, rel, relocation, info); 1487 1.1 christos 1488 1.1 christos if (r != bfd_reloc_ok) 1489 1.1 christos { 1490 1.1 christos const char *msg = (const char *) NULL; 1491 1.1 christos 1492 1.1 christos switch (r) 1493 1.1 christos { 1494 1.1 christos case bfd_reloc_overflow: 1495 1.6 christos (*info->callbacks->reloc_overflow) 1496 1.1 christos (info, (h ? &h->root : NULL), name, howto->name, 1497 1.6 christos (bfd_vma) 0, input_bfd, input_section, rel->r_offset); 1498 1.1 christos break; 1499 1.1 christos 1500 1.1 christos case bfd_reloc_undefined: 1501 1.6 christos (*info->callbacks->undefined_symbol) 1502 1.10 christos (info, name, input_bfd, input_section, rel->r_offset, true); 1503 1.1 christos break; 1504 1.1 christos 1505 1.1 christos case bfd_reloc_outofrange: 1506 1.1 christos msg = _("internal error: branch/jump to an odd address detected"); 1507 1.1 christos break; 1508 1.1 christos 1509 1.1 christos case bfd_reloc_notsupported: 1510 1.1 christos msg = _("internal error: unsupported relocation error"); 1511 1.1 christos break; 1512 1.1 christos 1513 1.1 christos case bfd_reloc_dangerous: 1514 1.1 christos msg = _("internal error: dangerous relocation"); 1515 1.1 christos break; 1516 1.1 christos 1517 1.1 christos default: 1518 1.1 christos msg = _("internal error: unknown error"); 1519 1.1 christos break; 1520 1.1 christos } 1521 1.1 christos 1522 1.1 christos if (msg) 1523 1.6 christos (*info->callbacks->warning) (info, msg, name, input_bfd, 1524 1.6 christos input_section, rel->r_offset); 1525 1.1 christos } 1526 1.1 christos 1527 1.1 christos } 1528 1.1 christos 1529 1.10 christos return true; 1530 1.1 christos } 1531 1.1 christos 1532 1.1 christos /* The final processing done just before writing out a MSP430 ELF object 1533 1.1 christos file. This gets the MSP430 architecture right based on the machine 1534 1.1 christos number. */ 1535 1.1 christos 1536 1.10 christos static bool 1537 1.9 christos bfd_elf_msp430_final_write_processing (bfd *abfd) 1538 1.1 christos { 1539 1.1 christos unsigned long val; 1540 1.1 christos 1541 1.1 christos switch (bfd_get_mach (abfd)) 1542 1.1 christos { 1543 1.1 christos default: 1544 1.1 christos case bfd_mach_msp110: val = E_MSP430_MACH_MSP430x11x1; break; 1545 1.1 christos case bfd_mach_msp11: val = E_MSP430_MACH_MSP430x11; break; 1546 1.1 christos case bfd_mach_msp12: val = E_MSP430_MACH_MSP430x12; break; 1547 1.1 christos case bfd_mach_msp13: val = E_MSP430_MACH_MSP430x13; break; 1548 1.1 christos case bfd_mach_msp14: val = E_MSP430_MACH_MSP430x14; break; 1549 1.1 christos case bfd_mach_msp15: val = E_MSP430_MACH_MSP430x15; break; 1550 1.1 christos case bfd_mach_msp16: val = E_MSP430_MACH_MSP430x16; break; 1551 1.1 christos case bfd_mach_msp31: val = E_MSP430_MACH_MSP430x31; break; 1552 1.1 christos case bfd_mach_msp32: val = E_MSP430_MACH_MSP430x32; break; 1553 1.1 christos case bfd_mach_msp33: val = E_MSP430_MACH_MSP430x33; break; 1554 1.1 christos case bfd_mach_msp41: val = E_MSP430_MACH_MSP430x41; break; 1555 1.1 christos case bfd_mach_msp42: val = E_MSP430_MACH_MSP430x42; break; 1556 1.1 christos case bfd_mach_msp43: val = E_MSP430_MACH_MSP430x43; break; 1557 1.1 christos case bfd_mach_msp44: val = E_MSP430_MACH_MSP430x44; break; 1558 1.1 christos case bfd_mach_msp20: val = E_MSP430_MACH_MSP430x20; break; 1559 1.1 christos case bfd_mach_msp22: val = E_MSP430_MACH_MSP430x22; break; 1560 1.1 christos case bfd_mach_msp23: val = E_MSP430_MACH_MSP430x23; break; 1561 1.1 christos case bfd_mach_msp24: val = E_MSP430_MACH_MSP430x24; break; 1562 1.1 christos case bfd_mach_msp26: val = E_MSP430_MACH_MSP430x26; break; 1563 1.1 christos case bfd_mach_msp46: val = E_MSP430_MACH_MSP430x46; break; 1564 1.1 christos case bfd_mach_msp47: val = E_MSP430_MACH_MSP430x47; break; 1565 1.1 christos case bfd_mach_msp54: val = E_MSP430_MACH_MSP430x54; break; 1566 1.1 christos case bfd_mach_msp430x: val = E_MSP430_MACH_MSP430X; break; 1567 1.1 christos } 1568 1.1 christos 1569 1.1 christos elf_elfheader (abfd)->e_machine = EM_MSP430; 1570 1.1 christos elf_elfheader (abfd)->e_flags &= ~EF_MSP430_MACH; 1571 1.1 christos elf_elfheader (abfd)->e_flags |= val; 1572 1.9 christos return _bfd_elf_final_write_processing (abfd); 1573 1.1 christos } 1574 1.1 christos 1575 1.1 christos /* Set the right machine number. */ 1576 1.1 christos 1577 1.10 christos static bool 1578 1.1 christos elf32_msp430_object_p (bfd * abfd) 1579 1.1 christos { 1580 1.1 christos int e_set = bfd_mach_msp14; 1581 1.1 christos 1582 1.1 christos if (elf_elfheader (abfd)->e_machine == EM_MSP430 1583 1.1 christos || elf_elfheader (abfd)->e_machine == EM_MSP430_OLD) 1584 1.1 christos { 1585 1.1 christos int e_mach = elf_elfheader (abfd)->e_flags & EF_MSP430_MACH; 1586 1.1 christos 1587 1.1 christos switch (e_mach) 1588 1.1 christos { 1589 1.1 christos default: 1590 1.1 christos case E_MSP430_MACH_MSP430x11: e_set = bfd_mach_msp11; break; 1591 1.1 christos case E_MSP430_MACH_MSP430x11x1: e_set = bfd_mach_msp110; break; 1592 1.1 christos case E_MSP430_MACH_MSP430x12: e_set = bfd_mach_msp12; break; 1593 1.1 christos case E_MSP430_MACH_MSP430x13: e_set = bfd_mach_msp13; break; 1594 1.1 christos case E_MSP430_MACH_MSP430x14: e_set = bfd_mach_msp14; break; 1595 1.1 christos case E_MSP430_MACH_MSP430x15: e_set = bfd_mach_msp15; break; 1596 1.1 christos case E_MSP430_MACH_MSP430x16: e_set = bfd_mach_msp16; break; 1597 1.1 christos case E_MSP430_MACH_MSP430x31: e_set = bfd_mach_msp31; break; 1598 1.1 christos case E_MSP430_MACH_MSP430x32: e_set = bfd_mach_msp32; break; 1599 1.1 christos case E_MSP430_MACH_MSP430x33: e_set = bfd_mach_msp33; break; 1600 1.1 christos case E_MSP430_MACH_MSP430x41: e_set = bfd_mach_msp41; break; 1601 1.1 christos case E_MSP430_MACH_MSP430x42: e_set = bfd_mach_msp42; break; 1602 1.1 christos case E_MSP430_MACH_MSP430x43: e_set = bfd_mach_msp43; break; 1603 1.1 christos case E_MSP430_MACH_MSP430x44: e_set = bfd_mach_msp44; break; 1604 1.1 christos case E_MSP430_MACH_MSP430x20: e_set = bfd_mach_msp20; break; 1605 1.1 christos case E_MSP430_MACH_MSP430x22: e_set = bfd_mach_msp22; break; 1606 1.1 christos case E_MSP430_MACH_MSP430x23: e_set = bfd_mach_msp23; break; 1607 1.1 christos case E_MSP430_MACH_MSP430x24: e_set = bfd_mach_msp24; break; 1608 1.1 christos case E_MSP430_MACH_MSP430x26: e_set = bfd_mach_msp26; break; 1609 1.1 christos case E_MSP430_MACH_MSP430x46: e_set = bfd_mach_msp46; break; 1610 1.1 christos case E_MSP430_MACH_MSP430x47: e_set = bfd_mach_msp47; break; 1611 1.1 christos case E_MSP430_MACH_MSP430x54: e_set = bfd_mach_msp54; break; 1612 1.1 christos case E_MSP430_MACH_MSP430X: e_set = bfd_mach_msp430x; break; 1613 1.1 christos } 1614 1.1 christos } 1615 1.6 christos 1616 1.1 christos return bfd_default_set_arch_mach (abfd, bfd_arch_msp430, e_set); 1617 1.1 christos } 1618 1.1 christos 1619 1.1 christos /* These functions handle relaxing for the msp430. 1620 1.1 christos Relaxation required only in two cases: 1621 1.1 christos - Bad hand coding like jumps from one section to another or 1622 1.1 christos from file to file. 1623 1.1 christos - Sibling calls. This will affect only 'jump label' polymorph. Without 1624 1.1 christos relaxing this enlarges code by 2 bytes. Sibcalls implemented but 1625 1.1 christos do not work in gcc's port by the reason I do not know. 1626 1.1 christos - To convert out of range conditional jump instructions (found inside 1627 1.1 christos a function) into inverted jumps over an unconditional branch instruction. 1628 1.1 christos Anyway, if a relaxation required, user should pass -relax option to the 1629 1.1 christos linker. 1630 1.1 christos 1631 1.1 christos There are quite a few relaxing opportunities available on the msp430: 1632 1.1 christos 1633 1.1 christos ================================================================ 1634 1.1 christos 1635 1.1 christos 1. 3 words -> 1 word 1636 1.1 christos 1637 1.8 christos eq == jeq label jne +4; br lab 1638 1.8 christos ne != jne label jeq +4; br lab 1639 1.8 christos lt < jl label jge +4; br lab 1640 1.8 christos ltu < jlo label lhs +4; br lab 1641 1.8 christos ge >= jge label jl +4; br lab 1642 1.8 christos geu >= jhs label jlo +4; br lab 1643 1.1 christos 1644 1.1 christos 2. 4 words -> 1 word 1645 1.1 christos 1646 1.8 christos ltn < jn jn +2; jmp +4; br lab 1647 1.1 christos 1648 1.1 christos 3. 4 words -> 2 words 1649 1.1 christos 1650 1.8 christos gt > jeq +2; jge label jeq +6; jl +4; br label 1651 1.8 christos gtu > jeq +2; jhs label jeq +6; jlo +4; br label 1652 1.1 christos 1653 1.1 christos 4. 4 words -> 2 words and 2 labels 1654 1.1 christos 1655 1.8 christos leu <= jeq label; jlo label jeq +2; jhs +4; br label 1656 1.8 christos le <= jeq label; jl label jeq +2; jge +4; br label 1657 1.1 christos ================================================================= 1658 1.1 christos 1659 1.1 christos codemap for first cases is (labels masked ): 1660 1.1 christos eq: 0x2002,0x4010,0x0000 -> 0x2400 1661 1.1 christos ne: 0x2402,0x4010,0x0000 -> 0x2000 1662 1.1 christos lt: 0x3402,0x4010,0x0000 -> 0x3800 1663 1.1 christos ltu: 0x2c02,0x4010,0x0000 -> 0x2800 1664 1.1 christos ge: 0x3802,0x4010,0x0000 -> 0x3400 1665 1.1 christos geu: 0x2802,0x4010,0x0000 -> 0x2c00 1666 1.1 christos 1667 1.1 christos second case: 1668 1.1 christos ltn: 0x3001,0x3c02,0x4010,0x0000 -> 0x3000 1669 1.1 christos 1670 1.1 christos third case: 1671 1.1 christos gt: 0x2403,0x3802,0x4010,0x0000 -> 0x2401,0x3400 1672 1.1 christos gtu: 0x2403,0x2802,0x4010,0x0000 -> 0x2401,0x2c00 1673 1.1 christos 1674 1.1 christos fourth case: 1675 1.1 christos leu: 0x2401,0x2c02,0x4010,0x0000 -> 0x2400,0x2800 1676 1.1 christos le: 0x2401,0x3402,0x4010,0x0000 -> 0x2400,0x3800 1677 1.1 christos 1678 1.1 christos Unspecified case :) 1679 1.1 christos jump: 0x4010,0x0000 -> 0x3c00. */ 1680 1.1 christos 1681 1.1 christos #define NUMB_RELAX_CODES 12 1682 1.1 christos static struct rcodes_s 1683 1.1 christos { 1684 1.1 christos int f0, f1; /* From code. */ 1685 1.1 christos int t0, t1; /* To code. */ 1686 1.1 christos int labels; /* Position of labels: 1 - one label at first 1687 1.1 christos word, 2 - one at second word, 3 - two 1688 1.1 christos labels at both. */ 1689 1.1 christos int cdx; /* Words to match. */ 1690 1.1 christos int bs; /* Shrink bytes. */ 1691 1.1 christos int off; /* Offset from old label for new code. */ 1692 1.1 christos int ncl; /* New code length. */ 1693 1.1 christos } rcode[] = 1694 1.8 christos {/* lab,cdx,bs,off,ncl */ 1695 1.1 christos { 0x0000, 0x0000, 0x3c00, 0x0000, 1, 0, 2, 2, 2}, /* jump */ 1696 1.1 christos { 0x0000, 0x2002, 0x2400, 0x0000, 1, 1, 4, 4, 2}, /* eq */ 1697 1.1 christos { 0x0000, 0x2402, 0x2000, 0x0000, 1, 1, 4, 4, 2}, /* ne */ 1698 1.1 christos { 0x0000, 0x3402, 0x3800, 0x0000, 1, 1, 4, 4, 2}, /* lt */ 1699 1.1 christos { 0x0000, 0x2c02, 0x2800, 0x0000, 1, 1, 4, 4, 2}, /* ltu */ 1700 1.1 christos { 0x0000, 0x3802, 0x3400, 0x0000, 1, 1, 4, 4, 2}, /* ge */ 1701 1.1 christos { 0x0000, 0x2802, 0x2c00, 0x0000, 1, 1, 4, 4, 2}, /* geu */ 1702 1.1 christos { 0x3001, 0x3c02, 0x3000, 0x0000, 1, 2, 6, 6, 2}, /* ltn */ 1703 1.1 christos { 0x2403, 0x3802, 0x2401, 0x3400, 2, 2, 4, 6, 4}, /* gt */ 1704 1.1 christos { 0x2403, 0x2802, 0x2401, 0x2c00, 2, 2, 4, 6, 4}, /* gtu */ 1705 1.1 christos { 0x2401, 0x2c02, 0x2400, 0x2800, 3, 2, 4, 6, 4}, /* leu , 2 labels */ 1706 1.1 christos { 0x2401, 0x2c02, 0x2400, 0x2800, 3, 2, 4, 6, 4}, /* le , 2 labels */ 1707 1.8 christos { 0, 0, 0, 0, 0, 0, 0, 0, 0} 1708 1.1 christos }; 1709 1.1 christos 1710 1.1 christos /* Return TRUE if a symbol exists at the given address. */ 1711 1.1 christos 1712 1.10 christos static bool 1713 1.1 christos msp430_elf_symbol_address_p (bfd * abfd, 1714 1.1 christos asection * sec, 1715 1.1 christos Elf_Internal_Sym * isym, 1716 1.1 christos bfd_vma addr) 1717 1.1 christos { 1718 1.1 christos Elf_Internal_Shdr *symtab_hdr; 1719 1.1 christos unsigned int sec_shndx; 1720 1.1 christos Elf_Internal_Sym *isymend; 1721 1.1 christos struct elf_link_hash_entry **sym_hashes; 1722 1.1 christos struct elf_link_hash_entry **end_hashes; 1723 1.1 christos unsigned int symcount; 1724 1.1 christos 1725 1.1 christos sec_shndx = _bfd_elf_section_from_bfd_section (abfd, sec); 1726 1.1 christos 1727 1.1 christos /* Examine all the local symbols. */ 1728 1.1 christos symtab_hdr = &elf_tdata (abfd)->symtab_hdr; 1729 1.1 christos for (isymend = isym + symtab_hdr->sh_info; isym < isymend; isym++) 1730 1.1 christos if (isym->st_shndx == sec_shndx && isym->st_value == addr) 1731 1.10 christos return true; 1732 1.1 christos 1733 1.1 christos symcount = (symtab_hdr->sh_size / sizeof (Elf32_External_Sym) 1734 1.1 christos - symtab_hdr->sh_info); 1735 1.1 christos sym_hashes = elf_sym_hashes (abfd); 1736 1.1 christos end_hashes = sym_hashes + symcount; 1737 1.1 christos for (; sym_hashes < end_hashes; sym_hashes++) 1738 1.1 christos { 1739 1.1 christos struct elf_link_hash_entry *sym_hash = *sym_hashes; 1740 1.1 christos 1741 1.1 christos if ((sym_hash->root.type == bfd_link_hash_defined 1742 1.1 christos || sym_hash->root.type == bfd_link_hash_defweak) 1743 1.1 christos && sym_hash->root.u.def.section == sec 1744 1.1 christos && sym_hash->root.u.def.value == addr) 1745 1.10 christos return true; 1746 1.1 christos } 1747 1.1 christos 1748 1.10 christos return false; 1749 1.1 christos } 1750 1.1 christos 1751 1.1 christos /* Adjust all local symbols defined as '.section + 0xXXXX' (.section has 1752 1.1 christos sec_shndx) referenced from current and other sections. */ 1753 1.1 christos 1754 1.10 christos static bool 1755 1.1 christos msp430_elf_relax_adjust_locals (bfd * abfd, asection * sec, bfd_vma addr, 1756 1.1 christos int count, unsigned int sec_shndx, 1757 1.1 christos bfd_vma toaddr) 1758 1.1 christos { 1759 1.1 christos Elf_Internal_Shdr *symtab_hdr; 1760 1.1 christos Elf_Internal_Rela *irel; 1761 1.1 christos Elf_Internal_Rela *irelend; 1762 1.1 christos Elf_Internal_Sym *isym; 1763 1.1 christos 1764 1.1 christos irel = elf_section_data (sec)->relocs; 1765 1.1 christos if (irel == NULL) 1766 1.10 christos return true; 1767 1.1 christos 1768 1.1 christos irelend = irel + sec->reloc_count; 1769 1.1 christos symtab_hdr = & elf_tdata (abfd)->symtab_hdr; 1770 1.1 christos isym = (Elf_Internal_Sym *) symtab_hdr->contents; 1771 1.3 christos 1772 1.1 christos for (;irel < irelend; irel++) 1773 1.1 christos { 1774 1.3 christos unsigned int sidx = ELF32_R_SYM(irel->r_info); 1775 1.1 christos Elf_Internal_Sym *lsym = isym + sidx; 1776 1.3 christos 1777 1.5 christos /* Adjust symbols referenced by .sec+0xXX. */ 1778 1.3 christos if (irel->r_addend > addr && irel->r_addend < toaddr 1779 1.3 christos && sidx < symtab_hdr->sh_info 1780 1.1 christos && lsym->st_shndx == sec_shndx) 1781 1.1 christos irel->r_addend -= count; 1782 1.1 christos } 1783 1.6 christos 1784 1.10 christos return true; 1785 1.1 christos } 1786 1.1 christos 1787 1.1 christos /* Delete some bytes from a section while relaxing. */ 1788 1.1 christos 1789 1.10 christos static bool 1790 1.1 christos msp430_elf_relax_delete_bytes (bfd * abfd, asection * sec, bfd_vma addr, 1791 1.1 christos int count) 1792 1.1 christos { 1793 1.1 christos Elf_Internal_Shdr *symtab_hdr; 1794 1.1 christos unsigned int sec_shndx; 1795 1.1 christos bfd_byte *contents; 1796 1.1 christos Elf_Internal_Rela *irel; 1797 1.1 christos Elf_Internal_Rela *irelend; 1798 1.1 christos bfd_vma toaddr; 1799 1.1 christos Elf_Internal_Sym *isym; 1800 1.1 christos Elf_Internal_Sym *isymend; 1801 1.1 christos struct elf_link_hash_entry **sym_hashes; 1802 1.1 christos struct elf_link_hash_entry **end_hashes; 1803 1.1 christos unsigned int symcount; 1804 1.1 christos asection *p; 1805 1.1 christos 1806 1.1 christos sec_shndx = _bfd_elf_section_from_bfd_section (abfd, sec); 1807 1.1 christos 1808 1.1 christos contents = elf_section_data (sec)->this_hdr.contents; 1809 1.1 christos 1810 1.1 christos toaddr = sec->size; 1811 1.9 christos if (debug_relocs) 1812 1.9 christos printf (" deleting %d bytes between 0x%lx to 0x%lx\n", 1813 1.9 christos count, (long) addr, (long) toaddr); 1814 1.1 christos 1815 1.1 christos irel = elf_section_data (sec)->relocs; 1816 1.1 christos irelend = irel + sec->reloc_count; 1817 1.1 christos 1818 1.1 christos /* Actually delete the bytes. */ 1819 1.1 christos memmove (contents + addr, contents + addr + count, 1820 1.1 christos (size_t) (toaddr - addr - count)); 1821 1.1 christos sec->size -= count; 1822 1.1 christos 1823 1.1 christos /* Adjust all the relocs. */ 1824 1.1 christos symtab_hdr = & elf_tdata (abfd)->symtab_hdr; 1825 1.1 christos isym = (Elf_Internal_Sym *) symtab_hdr->contents; 1826 1.1 christos for (; irel < irelend; irel++) 1827 1.1 christos { 1828 1.1 christos /* Get the new reloc address. */ 1829 1.1 christos if ((irel->r_offset > addr && irel->r_offset < toaddr)) 1830 1.1 christos irel->r_offset -= count; 1831 1.1 christos } 1832 1.1 christos 1833 1.1 christos for (p = abfd->sections; p != NULL; p = p->next) 1834 1.1 christos msp430_elf_relax_adjust_locals (abfd,p,addr,count,sec_shndx,toaddr); 1835 1.6 christos 1836 1.1 christos /* Adjust the local symbols defined in this section. */ 1837 1.1 christos symtab_hdr = & elf_tdata (abfd)->symtab_hdr; 1838 1.1 christos isym = (Elf_Internal_Sym *) symtab_hdr->contents; 1839 1.1 christos for (isymend = isym + symtab_hdr->sh_info; isym < isymend; isym++) 1840 1.5 christos { 1841 1.5 christos const char * name; 1842 1.5 christos 1843 1.5 christos name = bfd_elf_string_from_elf_section 1844 1.5 christos (abfd, symtab_hdr->sh_link, isym->st_name); 1845 1.9 christos name = name == NULL || *name == 0 ? bfd_section_name (sec) : name; 1846 1.5 christos 1847 1.5 christos if (isym->st_shndx != sec_shndx) 1848 1.5 christos continue; 1849 1.6 christos 1850 1.5 christos if (isym->st_value > addr 1851 1.5 christos && (isym->st_value < toaddr 1852 1.5 christos /* We also adjust a symbol at the end of the section if its name is 1853 1.5 christos on the list below. These symbols are used for debug info 1854 1.5 christos generation and they refer to the end of the current section, not 1855 1.5 christos the start of the next section. */ 1856 1.5 christos || (isym->st_value == toaddr 1857 1.5 christos && name != NULL 1858 1.10 christos && (startswith (name, ".Letext") 1859 1.10 christos || startswith (name, ".LFE"))))) 1860 1.5 christos { 1861 1.9 christos if (debug_relocs) 1862 1.9 christos printf (" adjusting value of local symbol %s from 0x%lx ", 1863 1.9 christos name, (long) isym->st_value); 1864 1.5 christos if (isym->st_value < addr + count) 1865 1.5 christos isym->st_value = addr; 1866 1.5 christos else 1867 1.5 christos isym->st_value -= count; 1868 1.9 christos if (debug_relocs) 1869 1.9 christos printf ("to 0x%lx\n", (long) isym->st_value); 1870 1.5 christos } 1871 1.5 christos /* Adjust the function symbol's size as well. */ 1872 1.5 christos else if (ELF_ST_TYPE (isym->st_info) == STT_FUNC 1873 1.5 christos && isym->st_value + isym->st_size > addr 1874 1.5 christos && isym->st_value + isym->st_size < toaddr) 1875 1.5 christos isym->st_size -= count; 1876 1.5 christos } 1877 1.1 christos 1878 1.1 christos /* Now adjust the global symbols defined in this section. */ 1879 1.1 christos symcount = (symtab_hdr->sh_size / sizeof (Elf32_External_Sym) 1880 1.1 christos - symtab_hdr->sh_info); 1881 1.1 christos sym_hashes = elf_sym_hashes (abfd); 1882 1.1 christos end_hashes = sym_hashes + symcount; 1883 1.1 christos for (; sym_hashes < end_hashes; sym_hashes++) 1884 1.1 christos { 1885 1.1 christos struct elf_link_hash_entry *sym_hash = *sym_hashes; 1886 1.1 christos 1887 1.1 christos if ((sym_hash->root.type == bfd_link_hash_defined 1888 1.1 christos || sym_hash->root.type == bfd_link_hash_defweak) 1889 1.1 christos && sym_hash->root.u.def.section == sec 1890 1.1 christos && sym_hash->root.u.def.value > addr 1891 1.1 christos && sym_hash->root.u.def.value < toaddr) 1892 1.5 christos { 1893 1.5 christos if (sym_hash->root.u.def.value < addr + count) 1894 1.5 christos sym_hash->root.u.def.value = addr; 1895 1.5 christos else 1896 1.5 christos sym_hash->root.u.def.value -= count; 1897 1.5 christos } 1898 1.5 christos /* Adjust the function symbol's size as well. */ 1899 1.5 christos else if (sym_hash->root.type == bfd_link_hash_defined 1900 1.5 christos && sym_hash->root.u.def.section == sec 1901 1.5 christos && sym_hash->type == STT_FUNC 1902 1.5 christos && sym_hash->root.u.def.value + sym_hash->size > addr 1903 1.5 christos && sym_hash->root.u.def.value + sym_hash->size < toaddr) 1904 1.5 christos sym_hash->size -= count; 1905 1.1 christos } 1906 1.1 christos 1907 1.10 christos return true; 1908 1.1 christos } 1909 1.1 christos 1910 1.9 christos /* Insert one or two words into a section whilst relaxing. */ 1911 1.1 christos 1912 1.1 christos static bfd_byte * 1913 1.9 christos msp430_elf_relax_add_words (bfd * abfd, asection * sec, bfd_vma addr, 1914 1.9 christos int num_words, int word1, int word2) 1915 1.1 christos { 1916 1.1 christos Elf_Internal_Shdr *symtab_hdr; 1917 1.1 christos unsigned int sec_shndx; 1918 1.1 christos bfd_byte *contents; 1919 1.1 christos Elf_Internal_Rela *irel; 1920 1.1 christos Elf_Internal_Rela *irelend; 1921 1.1 christos Elf_Internal_Sym *isym; 1922 1.1 christos Elf_Internal_Sym *isymend; 1923 1.1 christos struct elf_link_hash_entry **sym_hashes; 1924 1.1 christos struct elf_link_hash_entry **end_hashes; 1925 1.1 christos unsigned int symcount; 1926 1.1 christos bfd_vma sec_end; 1927 1.1 christos asection *p; 1928 1.9 christos if (debug_relocs) 1929 1.9 christos printf (" adding %d words at 0x%lx\n", num_words, 1930 1.9 christos (long) (sec->output_section->vma + sec->output_offset + addr)); 1931 1.1 christos 1932 1.1 christos contents = elf_section_data (sec)->this_hdr.contents; 1933 1.1 christos sec_end = sec->size; 1934 1.9 christos int num_bytes = num_words * 2; 1935 1.1 christos 1936 1.1 christos /* Make space for the new words. */ 1937 1.9 christos contents = bfd_realloc (contents, sec_end + num_bytes); 1938 1.9 christos memmove (contents + addr + num_bytes, contents + addr, sec_end - addr); 1939 1.1 christos 1940 1.1 christos /* Insert the new words. */ 1941 1.1 christos bfd_put_16 (abfd, word1, contents + addr); 1942 1.9 christos if (num_words == 2) 1943 1.9 christos bfd_put_16 (abfd, word2, contents + addr + 2); 1944 1.1 christos 1945 1.1 christos /* Update the section information. */ 1946 1.9 christos sec->size += num_bytes; 1947 1.6 christos elf_section_data (sec)->this_hdr.contents = contents; 1948 1.1 christos 1949 1.1 christos /* Adjust all the relocs. */ 1950 1.1 christos irel = elf_section_data (sec)->relocs; 1951 1.1 christos irelend = irel + sec->reloc_count; 1952 1.1 christos 1953 1.1 christos for (; irel < irelend; irel++) 1954 1.1 christos if ((irel->r_offset >= addr && irel->r_offset < sec_end)) 1955 1.9 christos irel->r_offset += num_bytes; 1956 1.1 christos 1957 1.1 christos /* Adjust the local symbols defined in this section. */ 1958 1.1 christos sec_shndx = _bfd_elf_section_from_bfd_section (abfd, sec); 1959 1.1 christos for (p = abfd->sections; p != NULL; p = p->next) 1960 1.9 christos msp430_elf_relax_adjust_locals (abfd, p, addr, -num_bytes, 1961 1.1 christos sec_shndx, sec_end); 1962 1.1 christos 1963 1.1 christos /* Adjust the global symbols affected by the move. */ 1964 1.1 christos symtab_hdr = & elf_tdata (abfd)->symtab_hdr; 1965 1.1 christos isym = (Elf_Internal_Sym *) symtab_hdr->contents; 1966 1.1 christos for (isymend = isym + symtab_hdr->sh_info; isym < isymend; isym++) 1967 1.1 christos if (isym->st_shndx == sec_shndx 1968 1.1 christos && isym->st_value >= addr && isym->st_value < sec_end) 1969 1.9 christos { 1970 1.9 christos if (debug_relocs) 1971 1.9 christos printf (" adjusting value of local symbol %s from 0x%lx to " 1972 1.9 christos "0x%lx\n", bfd_elf_string_from_elf_section 1973 1.9 christos (abfd, symtab_hdr->sh_link, isym->st_name), 1974 1.9 christos (long) isym->st_value, (long)(isym->st_value + num_bytes)); 1975 1.9 christos isym->st_value += num_bytes; 1976 1.9 christos } 1977 1.1 christos 1978 1.1 christos /* Now adjust the global symbols defined in this section. */ 1979 1.1 christos symcount = (symtab_hdr->sh_size / sizeof (Elf32_External_Sym) 1980 1.1 christos - symtab_hdr->sh_info); 1981 1.1 christos sym_hashes = elf_sym_hashes (abfd); 1982 1.1 christos end_hashes = sym_hashes + symcount; 1983 1.1 christos for (; sym_hashes < end_hashes; sym_hashes++) 1984 1.1 christos { 1985 1.1 christos struct elf_link_hash_entry *sym_hash = *sym_hashes; 1986 1.1 christos 1987 1.1 christos if ((sym_hash->root.type == bfd_link_hash_defined 1988 1.1 christos || sym_hash->root.type == bfd_link_hash_defweak) 1989 1.1 christos && sym_hash->root.u.def.section == sec 1990 1.1 christos && sym_hash->root.u.def.value >= addr 1991 1.1 christos && sym_hash->root.u.def.value < sec_end) 1992 1.9 christos sym_hash->root.u.def.value += num_bytes; 1993 1.1 christos } 1994 1.1 christos 1995 1.1 christos return contents; 1996 1.1 christos } 1997 1.6 christos 1998 1.10 christos static bool 1999 1.1 christos msp430_elf_relax_section (bfd * abfd, asection * sec, 2000 1.1 christos struct bfd_link_info * link_info, 2001 1.10 christos bool * again) 2002 1.1 christos { 2003 1.1 christos Elf_Internal_Shdr * symtab_hdr; 2004 1.1 christos Elf_Internal_Rela * internal_relocs; 2005 1.1 christos Elf_Internal_Rela * irel; 2006 1.1 christos Elf_Internal_Rela * irelend; 2007 1.8 christos bfd_byte * contents = NULL; 2008 1.1 christos Elf_Internal_Sym * isymbuf = NULL; 2009 1.1 christos 2010 1.1 christos /* Assume nothing changes. */ 2011 1.10 christos *again = false; 2012 1.1 christos 2013 1.1 christos /* We don't have to do anything for a relocatable link, if 2014 1.1 christos this section does not have relocs, or if this is not a 2015 1.1 christos code section. */ 2016 1.6 christos if (bfd_link_relocatable (link_info) 2017 1.11 christos || sec->reloc_count == 0 2018 1.11 christos || (sec->flags & SEC_RELOC) == 0 2019 1.11 christos || (sec->flags & SEC_HAS_CONTENTS) == 0 2020 1.11 christos || (sec->flags & SEC_CODE) == 0) 2021 1.10 christos return true; 2022 1.1 christos 2023 1.9 christos if (debug_relocs) 2024 1.9 christos printf ("Relaxing %s (%p), output_offset: 0x%lx sec size: 0x%lx\n", 2025 1.9 christos sec->name, sec, (long) sec->output_offset, (long) sec->size); 2026 1.9 christos 2027 1.1 christos symtab_hdr = & elf_tdata (abfd)->symtab_hdr; 2028 1.1 christos 2029 1.1 christos /* Get a copy of the native relocations. */ 2030 1.1 christos internal_relocs = 2031 1.1 christos _bfd_elf_link_read_relocs (abfd, sec, NULL, NULL, link_info->keep_memory); 2032 1.1 christos if (internal_relocs == NULL) 2033 1.1 christos goto error_return; 2034 1.1 christos 2035 1.1 christos /* Walk through them looking for relaxing opportunities. */ 2036 1.1 christos irelend = internal_relocs + sec->reloc_count; 2037 1.1 christos 2038 1.9 christos if (debug_relocs) 2039 1.9 christos printf (" trying code size growing relocs\n"); 2040 1.1 christos /* Do code size growing relocs first. */ 2041 1.1 christos for (irel = internal_relocs; irel < irelend; irel++) 2042 1.1 christos { 2043 1.1 christos bfd_vma symval; 2044 1.1 christos 2045 1.1 christos /* If this isn't something that can be relaxed, then ignore 2046 1.8 christos this reloc. */ 2047 1.1 christos if (uses_msp430x_relocs (abfd) 2048 1.8 christos && ELF32_R_TYPE (irel->r_info) == (int) R_MSP430X_10_PCREL) 2049 1.1 christos ; 2050 1.1 christos else if (! uses_msp430x_relocs (abfd) 2051 1.8 christos && ELF32_R_TYPE (irel->r_info) == (int) R_MSP430_10_PCREL) 2052 1.1 christos ; 2053 1.1 christos else 2054 1.1 christos continue; 2055 1.1 christos 2056 1.1 christos /* Get the section contents if we haven't done so already. */ 2057 1.1 christos if (contents == NULL) 2058 1.1 christos { 2059 1.1 christos /* Get cached copy if it exists. */ 2060 1.1 christos if (elf_section_data (sec)->this_hdr.contents != NULL) 2061 1.1 christos contents = elf_section_data (sec)->this_hdr.contents; 2062 1.1 christos else if (! bfd_malloc_and_get_section (abfd, sec, &contents)) 2063 1.1 christos goto error_return; 2064 1.1 christos } 2065 1.1 christos 2066 1.1 christos /* Read this BFD's local symbols if we haven't done so already. */ 2067 1.1 christos if (isymbuf == NULL && symtab_hdr->sh_info != 0) 2068 1.1 christos { 2069 1.1 christos isymbuf = (Elf_Internal_Sym *) symtab_hdr->contents; 2070 1.1 christos if (isymbuf == NULL) 2071 1.1 christos isymbuf = bfd_elf_get_elf_syms (abfd, symtab_hdr, 2072 1.1 christos symtab_hdr->sh_info, 0, 2073 1.1 christos NULL, NULL, NULL); 2074 1.1 christos if (isymbuf == NULL) 2075 1.1 christos goto error_return; 2076 1.1 christos } 2077 1.1 christos 2078 1.1 christos /* Get the value of the symbol referred to by the reloc. */ 2079 1.1 christos if (ELF32_R_SYM (irel->r_info) < symtab_hdr->sh_info) 2080 1.1 christos { 2081 1.1 christos /* A local symbol. */ 2082 1.1 christos Elf_Internal_Sym *isym; 2083 1.1 christos asection *sym_sec; 2084 1.1 christos 2085 1.1 christos isym = isymbuf + ELF32_R_SYM (irel->r_info); 2086 1.1 christos if (isym->st_shndx == SHN_UNDEF) 2087 1.1 christos sym_sec = bfd_und_section_ptr; 2088 1.1 christos else if (isym->st_shndx == SHN_ABS) 2089 1.1 christos sym_sec = bfd_abs_section_ptr; 2090 1.1 christos else if (isym->st_shndx == SHN_COMMON) 2091 1.1 christos sym_sec = bfd_com_section_ptr; 2092 1.1 christos else 2093 1.1 christos sym_sec = bfd_section_from_elf_index (abfd, isym->st_shndx); 2094 1.1 christos symval = (isym->st_value 2095 1.1 christos + sym_sec->output_section->vma + sym_sec->output_offset); 2096 1.9 christos 2097 1.9 christos if (debug_relocs) 2098 1.9 christos printf (" processing reloc at 0x%lx for local sym: %s " 2099 1.9 christos "st_value: 0x%lx adj value: 0x%lx\n", 2100 1.9 christos (long) (sec->output_offset + sec->output_section->vma 2101 1.9 christos + irel->r_offset), 2102 1.9 christos bfd_elf_string_from_elf_section (abfd, symtab_hdr->sh_link, 2103 1.9 christos isym->st_name), 2104 1.9 christos (long) isym->st_value, (long) symval); 2105 1.1 christos } 2106 1.1 christos else 2107 1.1 christos { 2108 1.1 christos unsigned long indx; 2109 1.1 christos struct elf_link_hash_entry *h; 2110 1.1 christos 2111 1.1 christos /* An external symbol. */ 2112 1.1 christos indx = ELF32_R_SYM (irel->r_info) - symtab_hdr->sh_info; 2113 1.1 christos h = elf_sym_hashes (abfd)[indx]; 2114 1.1 christos BFD_ASSERT (h != NULL); 2115 1.1 christos 2116 1.1 christos if (h->root.type != bfd_link_hash_defined 2117 1.1 christos && h->root.type != bfd_link_hash_defweak) 2118 1.1 christos /* This appears to be a reference to an undefined 2119 1.1 christos symbol. Just ignore it--it will be caught by the 2120 1.1 christos regular reloc processing. */ 2121 1.1 christos continue; 2122 1.1 christos 2123 1.1 christos symval = (h->root.u.def.value 2124 1.1 christos + h->root.u.def.section->output_section->vma 2125 1.1 christos + h->root.u.def.section->output_offset); 2126 1.9 christos if (debug_relocs) 2127 1.9 christos printf (" processing reloc at 0x%lx for global sym: %s " 2128 1.9 christos "st_value: 0x%lx adj value: 0x%lx\n", 2129 1.9 christos (long) (sec->output_offset + sec->output_section->vma 2130 1.9 christos + irel->r_offset), 2131 1.9 christos h->root.root.string, (long) h->root.u.def.value, 2132 1.9 christos (long) symval); 2133 1.1 christos } 2134 1.1 christos 2135 1.1 christos /* For simplicity of coding, we are going to modify the section 2136 1.8 christos contents, the section relocs, and the BFD symbol table. We 2137 1.8 christos must tell the rest of the code not to free up this 2138 1.8 christos information. It would be possible to instead create a table 2139 1.8 christos of changes which have to be made, as is done in coff-mips.c; 2140 1.8 christos that would be more work, but would require less memory when 2141 1.8 christos the linker is run. */ 2142 1.1 christos 2143 1.1 christos bfd_signed_vma value = symval; 2144 1.1 christos int opcode; 2145 1.1 christos 2146 1.1 christos /* Compute the value that will be relocated. */ 2147 1.1 christos value += irel->r_addend; 2148 1.1 christos /* Convert to PC relative. */ 2149 1.1 christos value -= (sec->output_section->vma + sec->output_offset); 2150 1.1 christos value -= irel->r_offset; 2151 1.1 christos value -= 2; 2152 1.9 christos 2153 1.1 christos /* Scale. */ 2154 1.1 christos value >>= 1; 2155 1.1 christos 2156 1.1 christos /* If it is in range then no modifications are needed. */ 2157 1.1 christos if (value >= -512 && value <= 511) 2158 1.1 christos continue; 2159 1.1 christos 2160 1.1 christos /* Get the opcode. */ 2161 1.1 christos opcode = bfd_get_16 (abfd, contents + irel->r_offset); 2162 1.6 christos 2163 1.1 christos /* Compute the new opcode. We are going to convert: 2164 1.9 christos JMP label 2165 1.9 christos into: 2166 1.9 christos BR[A] label 2167 1.9 christos or 2168 1.1 christos J<cond> label 2169 1.9 christos into: 2170 1.1 christos J<inv-cond> 1f 2171 1.1 christos BR[A] #label 2172 1.8 christos 1: */ 2173 1.1 christos switch (opcode & 0xfc00) 2174 1.1 christos { 2175 1.6 christos case 0x3800: opcode = 0x3402; break; /* Jl -> Jge +2 */ 2176 1.1 christos case 0x3400: opcode = 0x3802; break; /* Jge -> Jl +2 */ 2177 1.1 christos case 0x2c00: opcode = 0x2802; break; /* Jhs -> Jlo +2 */ 2178 1.1 christos case 0x2800: opcode = 0x2c02; break; /* Jlo -> Jhs +2 */ 2179 1.1 christos case 0x2400: opcode = 0x2002; break; /* Jeq -> Jne +2 */ 2180 1.1 christos case 0x2000: opcode = 0x2402; break; /* jne -> Jeq +2 */ 2181 1.1 christos case 0x3000: /* jn */ 2182 1.1 christos /* There is no direct inverse of the Jn insn. 2183 1.1 christos FIXME: we could do this as: 2184 1.8 christos Jn 1f 2185 1.8 christos br 2f 2186 1.1 christos 1: br label 2187 1.8 christos 2: */ 2188 1.1 christos continue; 2189 1.9 christos case 0x3c00: 2190 1.9 christos if (uses_msp430x_relocs (abfd)) 2191 1.9 christos opcode = 0x0080; /* JMP -> BRA */ 2192 1.9 christos else 2193 1.9 christos opcode = 0x4030; /* JMP -> BR */ 2194 1.9 christos break; 2195 1.1 christos default: 2196 1.9 christos /* Unhandled branch instruction. */ 2197 1.1 christos /* fprintf (stderr, "unrecog: %x\n", opcode); */ 2198 1.5 christos continue; 2199 1.1 christos } 2200 1.1 christos 2201 1.1 christos /* Note that we've changed the relocs, section contents, etc. */ 2202 1.1 christos elf_section_data (sec)->relocs = internal_relocs; 2203 1.1 christos elf_section_data (sec)->this_hdr.contents = contents; 2204 1.1 christos symtab_hdr->contents = (unsigned char *) isymbuf; 2205 1.1 christos 2206 1.1 christos /* Install the new opcode. */ 2207 1.1 christos bfd_put_16 (abfd, opcode, contents + irel->r_offset); 2208 1.1 christos 2209 1.1 christos /* Insert the new branch instruction. */ 2210 1.1 christos if (uses_msp430x_relocs (abfd)) 2211 1.1 christos { 2212 1.9 christos if (debug_relocs) 2213 1.9 christos printf (" R_MSP430X_10_PCREL -> R_MSP430X_ABS20_ADR_SRC " 2214 1.9 christos "(growing with new opcode 0x%x)\n", opcode); 2215 1.9 christos 2216 1.9 christos /* Insert an absolute branch (aka MOVA) instruction. 2217 1.9 christos Note that bits 19:16 of the address are stored in the first word 2218 1.9 christos of the insn, so this is where r_offset will point to. */ 2219 1.9 christos if (opcode == 0x0080) 2220 1.9 christos { 2221 1.9 christos /* If we're inserting a BRA because we are converting from a JMP, 2222 1.9 christos then only add one word for destination address; the BRA opcode 2223 1.9 christos has already been written. */ 2224 1.9 christos contents = msp430_elf_relax_add_words 2225 1.9 christos (abfd, sec, irel->r_offset + 2, 1, 0x0000, 0); 2226 1.9 christos } 2227 1.9 christos else 2228 1.9 christos { 2229 1.9 christos contents = msp430_elf_relax_add_words 2230 1.9 christos (abfd, sec, irel->r_offset + 2, 2, 0x0080, 0x0000); 2231 1.9 christos /* Update the relocation to point to the inserted branch 2232 1.9 christos instruction. Note - we are changing a PC-relative reloc 2233 1.9 christos into an absolute reloc, but this is OK because we have 2234 1.9 christos arranged with the assembler to have the reloc's value be 2235 1.9 christos a (local) symbol, not a section+offset value. */ 2236 1.9 christos irel->r_offset += 2; 2237 1.9 christos } 2238 1.9 christos 2239 1.1 christos irel->r_info = ELF32_R_INFO (ELF32_R_SYM (irel->r_info), 2240 1.1 christos R_MSP430X_ABS20_ADR_SRC); 2241 1.1 christos } 2242 1.1 christos else 2243 1.1 christos { 2244 1.9 christos if (debug_relocs) 2245 1.9 christos printf (" R_MSP430_10_PCREL -> R_MSP430_16 " 2246 1.9 christos "(growing with new opcode 0x%x)\n", opcode); 2247 1.9 christos if (opcode == 0x4030) 2248 1.9 christos { 2249 1.9 christos /* If we're inserting a BR because we are converting from a JMP, 2250 1.9 christos then only add one word for destination address; the BR opcode 2251 1.9 christos has already been written. */ 2252 1.9 christos contents = msp430_elf_relax_add_words 2253 1.9 christos (abfd, sec, irel->r_offset + 2, 1, 0x0000, 0); 2254 1.9 christos irel->r_offset += 2; 2255 1.9 christos } 2256 1.9 christos else 2257 1.9 christos { 2258 1.9 christos contents = msp430_elf_relax_add_words 2259 1.9 christos (abfd, sec, irel->r_offset + 2, 2, 0x4030, 0x0000); 2260 1.9 christos /* See comment above about converting a 10-bit PC-rel 2261 1.9 christos relocation into a 16-bit absolute relocation. */ 2262 1.9 christos irel->r_offset += 4; 2263 1.9 christos } 2264 1.1 christos irel->r_info = ELF32_R_INFO (ELF32_R_SYM (irel->r_info), 2265 1.1 christos R_MSP430_16); 2266 1.1 christos } 2267 1.1 christos 2268 1.1 christos /* Growing the section may mean that other 2269 1.1 christos conditional branches need to be fixed. */ 2270 1.10 christos *again = true; 2271 1.1 christos } 2272 1.1 christos 2273 1.9 christos if (debug_relocs) 2274 1.9 christos printf (" trying code size shrinking relocs\n"); 2275 1.9 christos 2276 1.1 christos for (irel = internal_relocs; irel < irelend; irel++) 2277 1.1 christos { 2278 1.1 christos bfd_vma symval; 2279 1.1 christos 2280 1.1 christos /* Get the section contents if we haven't done so already. */ 2281 1.1 christos if (contents == NULL) 2282 1.1 christos { 2283 1.1 christos /* Get cached copy if it exists. */ 2284 1.1 christos if (elf_section_data (sec)->this_hdr.contents != NULL) 2285 1.1 christos contents = elf_section_data (sec)->this_hdr.contents; 2286 1.1 christos else if (! bfd_malloc_and_get_section (abfd, sec, &contents)) 2287 1.1 christos goto error_return; 2288 1.1 christos } 2289 1.1 christos 2290 1.1 christos /* Read this BFD's local symbols if we haven't done so already. */ 2291 1.1 christos if (isymbuf == NULL && symtab_hdr->sh_info != 0) 2292 1.1 christos { 2293 1.1 christos isymbuf = (Elf_Internal_Sym *) symtab_hdr->contents; 2294 1.1 christos if (isymbuf == NULL) 2295 1.1 christos isymbuf = bfd_elf_get_elf_syms (abfd, symtab_hdr, 2296 1.1 christos symtab_hdr->sh_info, 0, 2297 1.1 christos NULL, NULL, NULL); 2298 1.1 christos if (isymbuf == NULL) 2299 1.1 christos goto error_return; 2300 1.1 christos } 2301 1.1 christos 2302 1.1 christos /* Get the value of the symbol referred to by the reloc. */ 2303 1.1 christos if (ELF32_R_SYM (irel->r_info) < symtab_hdr->sh_info) 2304 1.1 christos { 2305 1.1 christos /* A local symbol. */ 2306 1.1 christos Elf_Internal_Sym *isym; 2307 1.1 christos asection *sym_sec; 2308 1.1 christos 2309 1.1 christos isym = isymbuf + ELF32_R_SYM (irel->r_info); 2310 1.1 christos if (isym->st_shndx == SHN_UNDEF) 2311 1.1 christos sym_sec = bfd_und_section_ptr; 2312 1.1 christos else if (isym->st_shndx == SHN_ABS) 2313 1.1 christos sym_sec = bfd_abs_section_ptr; 2314 1.1 christos else if (isym->st_shndx == SHN_COMMON) 2315 1.1 christos sym_sec = bfd_com_section_ptr; 2316 1.1 christos else 2317 1.1 christos sym_sec = bfd_section_from_elf_index (abfd, isym->st_shndx); 2318 1.1 christos symval = (isym->st_value 2319 1.1 christos + sym_sec->output_section->vma + sym_sec->output_offset); 2320 1.9 christos 2321 1.9 christos if (debug_relocs) 2322 1.9 christos printf (" processing reloc at 0x%lx for local sym: %s " 2323 1.9 christos "st_value: 0x%lx adj value: 0x%lx\n", 2324 1.9 christos (long) (sec->output_offset + sec->output_section->vma 2325 1.9 christos + irel->r_offset), 2326 1.9 christos bfd_elf_string_from_elf_section 2327 1.9 christos (abfd, symtab_hdr->sh_link, isym->st_name), 2328 1.9 christos (long) isym->st_value, (long) symval); 2329 1.1 christos } 2330 1.1 christos else 2331 1.1 christos { 2332 1.1 christos unsigned long indx; 2333 1.1 christos struct elf_link_hash_entry *h; 2334 1.1 christos 2335 1.1 christos /* An external symbol. */ 2336 1.1 christos indx = ELF32_R_SYM (irel->r_info) - symtab_hdr->sh_info; 2337 1.1 christos h = elf_sym_hashes (abfd)[indx]; 2338 1.1 christos BFD_ASSERT (h != NULL); 2339 1.1 christos 2340 1.1 christos if (h->root.type != bfd_link_hash_defined 2341 1.1 christos && h->root.type != bfd_link_hash_defweak) 2342 1.1 christos /* This appears to be a reference to an undefined 2343 1.1 christos symbol. Just ignore it--it will be caught by the 2344 1.1 christos regular reloc processing. */ 2345 1.1 christos continue; 2346 1.1 christos 2347 1.1 christos symval = (h->root.u.def.value 2348 1.1 christos + h->root.u.def.section->output_section->vma 2349 1.1 christos + h->root.u.def.section->output_offset); 2350 1.9 christos if (debug_relocs) 2351 1.9 christos printf (" processing reloc at 0x%lx for global sym: %s " 2352 1.9 christos "st_value: 0x%lx adj value: 0x%lx\n", (long) 2353 1.9 christos (sec->output_offset + sec->output_section->vma 2354 1.9 christos + irel->r_offset), 2355 1.9 christos h->root.root.string, (long) h->root.u.def.value, 2356 1.9 christos (long) symval); 2357 1.1 christos } 2358 1.1 christos 2359 1.1 christos /* For simplicity of coding, we are going to modify the section 2360 1.1 christos contents, the section relocs, and the BFD symbol table. We 2361 1.1 christos must tell the rest of the code not to free up this 2362 1.1 christos information. It would be possible to instead create a table 2363 1.1 christos of changes which have to be made, as is done in coff-mips.c; 2364 1.1 christos that would be more work, but would require less memory when 2365 1.1 christos the linker is run. */ 2366 1.1 christos 2367 1.1 christos /* Try to turn a 16bit pc-relative branch into a 10bit pc-relative 2368 1.1 christos branch. */ 2369 1.6 christos /* Paranoia? paranoia... */ 2370 1.3 christos if (! uses_msp430x_relocs (abfd) 2371 1.3 christos && ELF32_R_TYPE (irel->r_info) == (int) R_MSP430_RL_PCREL) 2372 1.1 christos { 2373 1.1 christos bfd_vma value = symval; 2374 1.1 christos 2375 1.1 christos /* Deal with pc-relative gunk. */ 2376 1.1 christos value -= (sec->output_section->vma + sec->output_offset); 2377 1.1 christos value -= irel->r_offset; 2378 1.1 christos value += irel->r_addend; 2379 1.1 christos 2380 1.1 christos /* See if the value will fit in 10 bits, note the high value is 2381 1.1 christos 1016 as the target will be two bytes closer if we are 2382 1.1 christos able to relax. */ 2383 1.1 christos if ((long) value < 1016 && (long) value > -1016) 2384 1.1 christos { 2385 1.1 christos int code0 = 0, code1 = 0, code2 = 0; 2386 1.1 christos int i; 2387 1.1 christos struct rcodes_s *rx; 2388 1.1 christos 2389 1.1 christos /* Get the opcode. */ 2390 1.1 christos if (irel->r_offset >= 6) 2391 1.1 christos code0 = bfd_get_16 (abfd, contents + irel->r_offset - 6); 2392 1.1 christos 2393 1.1 christos if (irel->r_offset >= 4) 2394 1.1 christos code1 = bfd_get_16 (abfd, contents + irel->r_offset - 4); 2395 1.1 christos 2396 1.1 christos code2 = bfd_get_16 (abfd, contents + irel->r_offset - 2); 2397 1.1 christos 2398 1.1 christos if (code2 != 0x4010) 2399 1.1 christos continue; 2400 1.1 christos 2401 1.1 christos /* Check r4 and r3. */ 2402 1.1 christos for (i = NUMB_RELAX_CODES - 1; i >= 0; i--) 2403 1.1 christos { 2404 1.1 christos rx = &rcode[i]; 2405 1.1 christos if (rx->cdx == 2 && rx->f0 == code0 && rx->f1 == code1) 2406 1.1 christos break; 2407 1.1 christos else if (rx->cdx == 1 && rx->f1 == code1) 2408 1.1 christos break; 2409 1.1 christos else if (rx->cdx == 0) /* This is an unconditional jump. */ 2410 1.1 christos break; 2411 1.1 christos } 2412 1.1 christos 2413 1.1 christos /* Check labels: 2414 1.1 christos .Label0: ; we do not care about this label 2415 1.1 christos jeq +6 2416 1.1 christos .Label1: ; make sure there is no label here 2417 1.1 christos jl +4 2418 1.1 christos .Label2: ; make sure there is no label here 2419 1.1 christos br .Label_dst 2420 1.1 christos 2421 1.1 christos So, if there is .Label1 or .Label2 we cannot relax this code. 2422 1.1 christos This actually should not happen, cause for relaxable 2423 1.1 christos instructions we use RL_PCREL reloc instead of 16_PCREL. 2424 1.1 christos Will change this in the future. */ 2425 1.1 christos 2426 1.1 christos if (rx->cdx > 0 2427 1.1 christos && msp430_elf_symbol_address_p (abfd, sec, isymbuf, 2428 1.1 christos irel->r_offset - 2)) 2429 1.1 christos continue; 2430 1.1 christos if (rx->cdx > 1 2431 1.1 christos && msp430_elf_symbol_address_p (abfd, sec, isymbuf, 2432 1.1 christos irel->r_offset - 4)) 2433 1.1 christos continue; 2434 1.1 christos 2435 1.1 christos /* Note that we've changed the relocs, section contents, etc. */ 2436 1.1 christos elf_section_data (sec)->relocs = internal_relocs; 2437 1.1 christos elf_section_data (sec)->this_hdr.contents = contents; 2438 1.1 christos symtab_hdr->contents = (unsigned char *) isymbuf; 2439 1.1 christos 2440 1.9 christos if (debug_relocs) 2441 1.9 christos printf (" R_MSP430_RL_PCREL -> "); 2442 1.1 christos /* Fix the relocation's type. */ 2443 1.1 christos if (uses_msp430x_relocs (abfd)) 2444 1.1 christos { 2445 1.1 christos if (rx->labels == 3) /* Handle special cases. */ 2446 1.1 christos irel->r_info = ELF32_R_INFO (ELF32_R_SYM (irel->r_info), 2447 1.1 christos R_MSP430X_2X_PCREL); 2448 1.1 christos else 2449 1.1 christos irel->r_info = ELF32_R_INFO (ELF32_R_SYM (irel->r_info), 2450 1.1 christos R_MSP430X_10_PCREL); 2451 1.1 christos } 2452 1.1 christos else 2453 1.1 christos { 2454 1.1 christos if (rx->labels == 3) /* Handle special cases. */ 2455 1.9 christos { 2456 1.9 christos irel->r_info = ELF32_R_INFO (ELF32_R_SYM (irel->r_info), 2457 1.9 christos R_MSP430_2X_PCREL); 2458 1.9 christos if (debug_relocs) 2459 1.9 christos printf ("R_MSP430_2X_PCREL (shrinking with new opcode" 2460 1.9 christos " 0x%x)\n", rx->t0); 2461 1.9 christos } 2462 1.1 christos else 2463 1.9 christos { 2464 1.9 christos irel->r_info = ELF32_R_INFO (ELF32_R_SYM (irel->r_info), 2465 1.9 christos R_MSP430_10_PCREL); 2466 1.9 christos if (debug_relocs) 2467 1.9 christos printf ("R_MSP430_10_PCREL (shrinking with new opcode" 2468 1.9 christos " 0x%x)\n", rx->t0); 2469 1.9 christos } 2470 1.1 christos } 2471 1.1 christos 2472 1.1 christos /* Fix the opcode right way. */ 2473 1.1 christos bfd_put_16 (abfd, rx->t0, contents + irel->r_offset - rx->off); 2474 1.1 christos if (rx->t1) 2475 1.1 christos bfd_put_16 (abfd, rx->t1, 2476 1.1 christos contents + irel->r_offset - rx->off + 2); 2477 1.1 christos 2478 1.1 christos /* Delete bytes. */ 2479 1.1 christos if (!msp430_elf_relax_delete_bytes (abfd, sec, 2480 1.1 christos irel->r_offset - rx->off + 2481 1.1 christos rx->ncl, rx->bs)) 2482 1.1 christos goto error_return; 2483 1.1 christos 2484 1.1 christos /* Handle unconditional jumps. */ 2485 1.1 christos if (rx->cdx == 0) 2486 1.1 christos irel->r_offset -= 2; 2487 1.1 christos 2488 1.1 christos /* That will change things, so, we should relax again. 2489 1.1 christos Note that this is not required, and it may be slow. */ 2490 1.10 christos *again = true; 2491 1.1 christos } 2492 1.1 christos } 2493 1.3 christos 2494 1.3 christos /* Try to turn a 16-bit absolute branch into a 10-bit pc-relative 2495 1.3 christos branch. */ 2496 1.8 christos if ((uses_msp430x_relocs (abfd) 2497 1.8 christos && ELF32_R_TYPE (irel->r_info) == R_MSP430X_ABS16) 2498 1.8 christos || (! uses_msp430x_relocs (abfd) 2499 1.8 christos && ELF32_R_TYPE (irel->r_info) == R_MSP430_16)) 2500 1.3 christos { 2501 1.3 christos bfd_vma value = symval; 2502 1.3 christos 2503 1.5 christos value -= (sec->output_section->vma + sec->output_offset); 2504 1.3 christos value -= irel->r_offset; 2505 1.3 christos value += irel->r_addend; 2506 1.6 christos 2507 1.3 christos /* See if the value will fit in 10 bits, note the high value is 2508 1.3 christos 1016 as the target will be two bytes closer if we are 2509 1.3 christos able to relax. */ 2510 1.3 christos if ((long) value < 1016 && (long) value > -1016) 2511 1.3 christos { 2512 1.9 christos int code1, code2, opcode; 2513 1.3 christos 2514 1.3 christos /* Get the opcode. */ 2515 1.3 christos code2 = bfd_get_16 (abfd, contents + irel->r_offset - 2); 2516 1.9 christos if (code2 != 0x4030) /* BR -> JMP */ 2517 1.3 christos continue; 2518 1.3 christos /* FIXME: check r4 and r3 ? */ 2519 1.3 christos /* FIXME: Handle 0x4010 as well ? */ 2520 1.3 christos 2521 1.3 christos /* Note that we've changed the relocs, section contents, etc. */ 2522 1.3 christos elf_section_data (sec)->relocs = internal_relocs; 2523 1.3 christos elf_section_data (sec)->this_hdr.contents = contents; 2524 1.3 christos symtab_hdr->contents = (unsigned char *) isymbuf; 2525 1.3 christos 2526 1.3 christos /* Fix the relocation's type. */ 2527 1.3 christos if (uses_msp430x_relocs (abfd)) 2528 1.3 christos { 2529 1.3 christos irel->r_info = ELF32_R_INFO (ELF32_R_SYM (irel->r_info), 2530 1.3 christos R_MSP430X_10_PCREL); 2531 1.9 christos if (debug_relocs) 2532 1.9 christos printf (" R_MSP430X_16 -> R_MSP430X_10_PCREL "); 2533 1.3 christos } 2534 1.3 christos else 2535 1.3 christos { 2536 1.3 christos irel->r_info = ELF32_R_INFO (ELF32_R_SYM (irel->r_info), 2537 1.3 christos R_MSP430_10_PCREL); 2538 1.9 christos if (debug_relocs) 2539 1.9 christos printf (" R_MSP430_16 -> R_MSP430_10_PCREL "); 2540 1.3 christos } 2541 1.9 christos /* If we're trying to shrink a BR[A] after previously having 2542 1.9 christos grown a JMP for this reloc, then we have a sequence like 2543 1.9 christos this: 2544 1.9 christos J<cond> 1f 2545 1.9 christos BR[A] 2546 1.9 christos 1: 2547 1.9 christos The opcode for J<cond> has the target hard-coded as 2 words 2548 1.9 christos ahead of the insn, instead of using a reloc. 2549 1.9 christos This means we cannot rely on any of the helper functions to 2550 1.9 christos update this hard-coded jump destination if we remove the 2551 1.9 christos BR[A] insn, so we must explicitly update it here. 2552 1.9 christos This does mean that we can remove the entire branch 2553 1.9 christos instruction, and invert the conditional jump, saving us 4 2554 1.9 christos bytes rather than only 2 if we detected this in the normal 2555 1.9 christos way. */ 2556 1.9 christos code1 = bfd_get_16 (abfd, contents + irel->r_offset - 4); 2557 1.9 christos switch (code1) 2558 1.9 christos { 2559 1.9 christos case 0x3802: opcode = 0x3401; break; /* Jl +2 -> Jge +1 */ 2560 1.9 christos case 0x3402: opcode = 0x3801; break; /* Jge +2 -> Jl +1 */ 2561 1.9 christos case 0x2c02: opcode = 0x2801; break; /* Jhs +2 -> Jlo +1 */ 2562 1.9 christos case 0x2802: opcode = 0x2c01; break; /* Jlo +2 -> Jhs +1 */ 2563 1.9 christos case 0x2402: opcode = 0x2001; break; /* Jeq +2 -> Jne +1 */ 2564 1.9 christos case 0x2002: opcode = 0x2401; break; /* jne +2 -> Jeq +1 */ 2565 1.9 christos case 0x3002: /* jn +2 */ 2566 1.9 christos /* FIXME: There is no direct inverse of the Jn insn. */ 2567 1.9 christos continue; 2568 1.9 christos default: 2569 1.9 christos /* The previous opcode does not have a hard-coded jump 2570 1.9 christos that we added when previously relaxing, so relax the 2571 1.9 christos current branch as normal. */ 2572 1.9 christos opcode = 0x3c00; 2573 1.9 christos break; 2574 1.9 christos } 2575 1.9 christos if (debug_relocs) 2576 1.9 christos printf ("(shrinking with new opcode 0x%x)\n", opcode); 2577 1.3 christos 2578 1.9 christos if (opcode != 0x3c00) 2579 1.9 christos { 2580 1.9 christos /* Invert the opcode of the conditional jump. */ 2581 1.9 christos bfd_put_16 (abfd, opcode, contents + irel->r_offset - 4); 2582 1.9 christos irel->r_offset -= 4; 2583 1.9 christos 2584 1.9 christos /* Delete 4 bytes - the full BR insn. */ 2585 1.9 christos if (!msp430_elf_relax_delete_bytes (abfd, sec, 2586 1.9 christos irel->r_offset + 2, 4)) 2587 1.9 christos goto error_return; 2588 1.9 christos } 2589 1.9 christos else 2590 1.9 christos { 2591 1.9 christos /* Fix the opcode right way. */ 2592 1.9 christos bfd_put_16 (abfd, opcode, contents + irel->r_offset - 2); 2593 1.9 christos irel->r_offset -= 2; 2594 1.9 christos 2595 1.9 christos /* Delete bytes. */ 2596 1.9 christos if (!msp430_elf_relax_delete_bytes (abfd, sec, 2597 1.9 christos irel->r_offset + 2, 2)) 2598 1.9 christos goto error_return; 2599 1.9 christos } 2600 1.3 christos 2601 1.3 christos /* That will change things, so, we should relax again. 2602 1.3 christos Note that this is not required, and it may be slow. */ 2603 1.10 christos *again = true; 2604 1.3 christos } 2605 1.3 christos } 2606 1.1 christos } 2607 1.1 christos 2608 1.1 christos if (isymbuf != NULL && symtab_hdr->contents != (unsigned char *) isymbuf) 2609 1.1 christos { 2610 1.1 christos if (!link_info->keep_memory) 2611 1.1 christos free (isymbuf); 2612 1.1 christos else 2613 1.1 christos { 2614 1.1 christos /* Cache the symbols for elf_link_input_bfd. */ 2615 1.1 christos symtab_hdr->contents = (unsigned char *) isymbuf; 2616 1.1 christos } 2617 1.1 christos } 2618 1.1 christos 2619 1.1 christos if (contents != NULL 2620 1.1 christos && elf_section_data (sec)->this_hdr.contents != contents) 2621 1.1 christos { 2622 1.1 christos if (!link_info->keep_memory) 2623 1.1 christos free (contents); 2624 1.1 christos else 2625 1.1 christos { 2626 1.1 christos /* Cache the section contents for elf_link_input_bfd. */ 2627 1.1 christos elf_section_data (sec)->this_hdr.contents = contents; 2628 1.1 christos } 2629 1.1 christos } 2630 1.1 christos 2631 1.9 christos if (elf_section_data (sec)->relocs != internal_relocs) 2632 1.1 christos free (internal_relocs); 2633 1.1 christos 2634 1.10 christos return true; 2635 1.1 christos 2636 1.9 christos error_return: 2637 1.9 christos if (symtab_hdr->contents != (unsigned char *) isymbuf) 2638 1.1 christos free (isymbuf); 2639 1.9 christos if (elf_section_data (sec)->this_hdr.contents != contents) 2640 1.1 christos free (contents); 2641 1.9 christos if (elf_section_data (sec)->relocs != internal_relocs) 2642 1.1 christos free (internal_relocs); 2643 1.1 christos 2644 1.10 christos return false; 2645 1.1 christos } 2646 1.1 christos 2647 1.1 christos /* Handle an MSP430 specific section when reading an object file. 2648 1.1 christos This is called when bfd_section_from_shdr finds a section with 2649 1.1 christos an unknown type. */ 2650 1.1 christos 2651 1.10 christos static bool 2652 1.1 christos elf32_msp430_section_from_shdr (bfd *abfd, 2653 1.1 christos Elf_Internal_Shdr * hdr, 2654 1.1 christos const char *name, 2655 1.1 christos int shindex) 2656 1.1 christos { 2657 1.1 christos switch (hdr->sh_type) 2658 1.1 christos { 2659 1.1 christos case SHT_MSP430_SEC_FLAGS: 2660 1.1 christos case SHT_MSP430_SYM_ALIASES: 2661 1.1 christos case SHT_MSP430_ATTRIBUTES: 2662 1.1 christos return _bfd_elf_make_section_from_shdr (abfd, hdr, name, shindex); 2663 1.1 christos default: 2664 1.10 christos return false; 2665 1.1 christos } 2666 1.1 christos } 2667 1.1 christos 2668 1.10 christos static bool 2669 1.1 christos elf32_msp430_obj_attrs_handle_unknown (bfd *abfd, int tag) 2670 1.1 christos { 2671 1.1 christos _bfd_error_handler 2672 1.7 christos /* xgettext:c-format */ 2673 1.8 christos (_("warning: %pB: unknown MSPABI object attribute %d"), 2674 1.1 christos abfd, tag); 2675 1.10 christos return true; 2676 1.1 christos } 2677 1.1 christos 2678 1.1 christos /* Determine whether an object attribute tag takes an integer, a 2679 1.1 christos string or both. */ 2680 1.1 christos 2681 1.1 christos static int 2682 1.1 christos elf32_msp430_obj_attrs_arg_type (int tag) 2683 1.1 christos { 2684 1.1 christos if (tag == Tag_compatibility) 2685 1.1 christos return ATTR_TYPE_FLAG_INT_VAL | ATTR_TYPE_FLAG_STR_VAL; 2686 1.1 christos 2687 1.1 christos if (tag < 32) 2688 1.1 christos return ATTR_TYPE_FLAG_INT_VAL; 2689 1.1 christos 2690 1.1 christos return (tag & 1) != 0 ? ATTR_TYPE_FLAG_STR_VAL : ATTR_TYPE_FLAG_INT_VAL; 2691 1.1 christos } 2692 1.1 christos 2693 1.1 christos static inline const char * 2694 1.1 christos isa_type (int isa) 2695 1.1 christos { 2696 1.1 christos switch (isa) 2697 1.1 christos { 2698 1.1 christos case 1: return "MSP430"; 2699 1.1 christos case 2: return "MSP430X"; 2700 1.1 christos default: return "unknown"; 2701 1.1 christos } 2702 1.1 christos } 2703 1.1 christos 2704 1.1 christos static inline const char * 2705 1.1 christos code_model (int model) 2706 1.1 christos { 2707 1.1 christos switch (model) 2708 1.1 christos { 2709 1.1 christos case 1: return "small"; 2710 1.1 christos case 2: return "large"; 2711 1.1 christos default: return "unknown"; 2712 1.1 christos } 2713 1.1 christos } 2714 1.1 christos 2715 1.1 christos static inline const char * 2716 1.1 christos data_model (int model) 2717 1.1 christos { 2718 1.1 christos switch (model) 2719 1.1 christos { 2720 1.1 christos case 1: return "small"; 2721 1.1 christos case 2: return "large"; 2722 1.1 christos case 3: return "restricted large"; 2723 1.1 christos default: return "unknown"; 2724 1.1 christos } 2725 1.1 christos } 2726 1.1 christos 2727 1.9 christos /* Merge MSPABI and GNU object attributes from IBFD into OBFD. 2728 1.1 christos Raise an error if there are conflicting attributes. */ 2729 1.1 christos 2730 1.10 christos static bool 2731 1.9 christos elf32_msp430_merge_msp430_attributes (bfd *ibfd, struct bfd_link_info *info) 2732 1.1 christos { 2733 1.7 christos bfd *obfd = info->output_bfd; 2734 1.9 christos obj_attribute *in_msp_attr, *in_gnu_attr; 2735 1.9 christos obj_attribute *out_msp_attr, *out_gnu_attr; 2736 1.10 christos bool result = true; 2737 1.1 christos static bfd * first_input_bfd = NULL; 2738 1.1 christos 2739 1.1 christos /* Skip linker created files. */ 2740 1.1 christos if (ibfd->flags & BFD_LINKER_CREATED) 2741 1.10 christos return true; 2742 1.1 christos 2743 1.8 christos /* LTO can create temporary files for linking which may not have an attribute 2744 1.8 christos section. */ 2745 1.8 christos if (ibfd->lto_output 2746 1.8 christos && bfd_get_section_by_name (ibfd, ".MSP430.attributes") == NULL) 2747 1.10 christos return true; 2748 1.8 christos 2749 1.1 christos /* If this is the first real object just copy the attributes. */ 2750 1.1 christos if (!elf_known_obj_attributes_proc (obfd)[0].i) 2751 1.1 christos { 2752 1.1 christos _bfd_elf_copy_obj_attributes (ibfd, obfd); 2753 1.1 christos 2754 1.9 christos out_msp_attr = elf_known_obj_attributes_proc (obfd); 2755 1.1 christos 2756 1.1 christos /* Use the Tag_null value to indicate that 2757 1.1 christos the attributes have been initialized. */ 2758 1.9 christos out_msp_attr[0].i = 1; 2759 1.1 christos 2760 1.1 christos first_input_bfd = ibfd; 2761 1.10 christos return true; 2762 1.1 christos } 2763 1.1 christos 2764 1.9 christos in_msp_attr = elf_known_obj_attributes_proc (ibfd); 2765 1.9 christos out_msp_attr = elf_known_obj_attributes_proc (obfd); 2766 1.9 christos in_gnu_attr = elf_known_obj_attributes (ibfd) [OBJ_ATTR_GNU]; 2767 1.9 christos out_gnu_attr = elf_known_obj_attributes (obfd) [OBJ_ATTR_GNU]; 2768 1.1 christos 2769 1.1 christos /* The ISAs must be the same. */ 2770 1.9 christos if (in_msp_attr[OFBA_MSPABI_Tag_ISA].i != out_msp_attr[OFBA_MSPABI_Tag_ISA].i) 2771 1.1 christos { 2772 1.1 christos _bfd_error_handler 2773 1.7 christos /* xgettext:c-format */ 2774 1.8 christos (_("error: %pB uses %s instructions but %pB uses %s"), 2775 1.9 christos ibfd, isa_type (in_msp_attr[OFBA_MSPABI_Tag_ISA].i), 2776 1.9 christos first_input_bfd, isa_type (out_msp_attr[OFBA_MSPABI_Tag_ISA].i)); 2777 1.10 christos result = false; 2778 1.1 christos } 2779 1.1 christos 2780 1.1 christos /* The code models must be the same. */ 2781 1.9 christos if (in_msp_attr[OFBA_MSPABI_Tag_Code_Model].i 2782 1.9 christos != out_msp_attr[OFBA_MSPABI_Tag_Code_Model].i) 2783 1.1 christos { 2784 1.1 christos _bfd_error_handler 2785 1.7 christos /* xgettext:c-format */ 2786 1.8 christos (_("error: %pB uses the %s code model whereas %pB uses the %s code model"), 2787 1.9 christos ibfd, code_model (in_msp_attr[OFBA_MSPABI_Tag_Code_Model].i), 2788 1.9 christos first_input_bfd, 2789 1.9 christos code_model (out_msp_attr[OFBA_MSPABI_Tag_Code_Model].i)); 2790 1.10 christos result = false; 2791 1.1 christos } 2792 1.1 christos 2793 1.1 christos /* The large code model is only supported by the MSP430X. */ 2794 1.9 christos if (in_msp_attr[OFBA_MSPABI_Tag_Code_Model].i == 2 2795 1.9 christos && out_msp_attr[OFBA_MSPABI_Tag_ISA].i != 2) 2796 1.1 christos { 2797 1.1 christos _bfd_error_handler 2798 1.7 christos /* xgettext:c-format */ 2799 1.8 christos (_("error: %pB uses the large code model but %pB uses MSP430 instructions"), 2800 1.1 christos ibfd, first_input_bfd); 2801 1.10 christos result = false; 2802 1.1 christos } 2803 1.1 christos 2804 1.1 christos /* The data models must be the same. */ 2805 1.9 christos if (in_msp_attr[OFBA_MSPABI_Tag_Data_Model].i 2806 1.9 christos != out_msp_attr[OFBA_MSPABI_Tag_Data_Model].i) 2807 1.1 christos { 2808 1.1 christos _bfd_error_handler 2809 1.7 christos /* xgettext:c-format */ 2810 1.8 christos (_("error: %pB uses the %s data model whereas %pB uses the %s data model"), 2811 1.9 christos ibfd, data_model (in_msp_attr[OFBA_MSPABI_Tag_Data_Model].i), 2812 1.9 christos first_input_bfd, 2813 1.9 christos data_model (out_msp_attr[OFBA_MSPABI_Tag_Data_Model].i)); 2814 1.10 christos result = false; 2815 1.1 christos } 2816 1.1 christos 2817 1.1 christos /* The small code model requires the use of the small data model. */ 2818 1.9 christos if (in_msp_attr[OFBA_MSPABI_Tag_Code_Model].i == 1 2819 1.9 christos && out_msp_attr[OFBA_MSPABI_Tag_Data_Model].i != 1) 2820 1.1 christos { 2821 1.1 christos _bfd_error_handler 2822 1.7 christos /* xgettext:c-format */ 2823 1.8 christos (_("error: %pB uses the small code model but %pB uses the %s data model"), 2824 1.1 christos ibfd, first_input_bfd, 2825 1.9 christos data_model (out_msp_attr[OFBA_MSPABI_Tag_Data_Model].i)); 2826 1.10 christos result = false; 2827 1.1 christos } 2828 1.1 christos 2829 1.1 christos /* The large data models are only supported by the MSP430X. */ 2830 1.9 christos if (in_msp_attr[OFBA_MSPABI_Tag_Data_Model].i > 1 2831 1.9 christos && out_msp_attr[OFBA_MSPABI_Tag_ISA].i != 2) 2832 1.1 christos { 2833 1.1 christos _bfd_error_handler 2834 1.7 christos /* xgettext:c-format */ 2835 1.8 christos (_("error: %pB uses the %s data model but %pB only uses MSP430 instructions"), 2836 1.9 christos ibfd, data_model (in_msp_attr[OFBA_MSPABI_Tag_Data_Model].i), 2837 1.7 christos first_input_bfd); 2838 1.10 christos result = false; 2839 1.1 christos } 2840 1.6 christos 2841 1.9 christos /* Just ignore the data region unless the large memory model is in use. 2842 1.9 christos We have already checked that ibfd and obfd use the same memory model. */ 2843 1.9 christos if ((in_msp_attr[OFBA_MSPABI_Tag_Code_Model].i 2844 1.9 christos == OFBA_MSPABI_Val_Code_Model_LARGE) 2845 1.9 christos && (in_msp_attr[OFBA_MSPABI_Tag_Data_Model].i 2846 1.9 christos == OFBA_MSPABI_Val_Data_Model_LARGE)) 2847 1.9 christos { 2848 1.9 christos /* We cannot allow "lower region only" to be linked with any other 2849 1.9 christos values (i.e. ANY or NONE). 2850 1.9 christos Before this attribute existed, "ANY" region was the default. */ 2851 1.10 christos bool ibfd_lower_region_used 2852 1.9 christos = (in_gnu_attr[Tag_GNU_MSP430_Data_Region].i 2853 1.9 christos == Val_GNU_MSP430_Data_Region_Lower); 2854 1.10 christos bool obfd_lower_region_used 2855 1.9 christos = (out_gnu_attr[Tag_GNU_MSP430_Data_Region].i 2856 1.9 christos == Val_GNU_MSP430_Data_Region_Lower); 2857 1.9 christos if (ibfd_lower_region_used != obfd_lower_region_used) 2858 1.9 christos { 2859 1.9 christos _bfd_error_handler 2860 1.9 christos (_("error: %pB can use the upper region for data, " 2861 1.9 christos "but %pB assumes data is exclusively in lower memory"), 2862 1.9 christos ibfd_lower_region_used ? obfd : ibfd, 2863 1.9 christos ibfd_lower_region_used ? ibfd : obfd); 2864 1.10 christos result = false; 2865 1.9 christos } 2866 1.9 christos } 2867 1.9 christos 2868 1.1 christos return result; 2869 1.1 christos } 2870 1.1 christos 2871 1.1 christos /* Merge backend specific data from an object file to the output 2872 1.1 christos object file when linking. */ 2873 1.1 christos 2874 1.10 christos static bool 2875 1.7 christos elf32_msp430_merge_private_bfd_data (bfd *ibfd, struct bfd_link_info *info) 2876 1.1 christos { 2877 1.7 christos bfd *obfd = info->output_bfd; 2878 1.1 christos /* Make sure that the machine number reflects the most 2879 1.1 christos advanced version of the MSP architecture required. */ 2880 1.1 christos #define max(a,b) ((a) > (b) ? (a) : (b)) 2881 1.1 christos if (bfd_get_mach (ibfd) != bfd_get_mach (obfd)) 2882 1.1 christos bfd_default_set_arch_mach (obfd, bfd_get_arch (obfd), 2883 1.1 christos max (bfd_get_mach (ibfd), bfd_get_mach (obfd))); 2884 1.1 christos #undef max 2885 1.1 christos 2886 1.9 christos return elf32_msp430_merge_msp430_attributes (ibfd, info); 2887 1.1 christos } 2888 1.1 christos 2889 1.10 christos static bool 2890 1.1 christos msp430_elf_is_target_special_symbol (bfd *abfd, asymbol *sym) 2891 1.1 christos { 2892 1.1 christos return _bfd_elf_is_local_label_name (abfd, sym->name); 2893 1.1 christos } 2894 1.1 christos 2895 1.10 christos static bool 2896 1.6 christos uses_large_model (bfd *abfd) 2897 1.6 christos { 2898 1.6 christos obj_attribute * attr; 2899 1.6 christos 2900 1.6 christos if (abfd->flags & BFD_LINKER_CREATED) 2901 1.10 christos return false; 2902 1.6 christos 2903 1.6 christos attr = elf_known_obj_attributes_proc (abfd); 2904 1.6 christos if (attr == NULL) 2905 1.10 christos return false; 2906 1.6 christos 2907 1.6 christos return attr[OFBA_MSPABI_Tag_Code_Model].i == 2; 2908 1.6 christos } 2909 1.6 christos 2910 1.6 christos static unsigned int 2911 1.8 christos elf32_msp430_eh_frame_address_size (bfd *abfd, 2912 1.8 christos const asection *sec ATTRIBUTE_UNUSED) 2913 1.6 christos { 2914 1.6 christos return uses_large_model (abfd) ? 4 : 2; 2915 1.6 christos } 2916 1.6 christos 2917 1.1 christos /* This is gross. The MSP430 EABI says that (sec 11.5): 2918 1.1 christos 2919 1.1 christos "An implementation may choose to use Rel or Rela 2920 1.1 christos type relocations for other relocations." 2921 1.1 christos 2922 1.1 christos But it also says that: 2923 1.6 christos 2924 1.1 christos "Certain relocations are identified as Rela only. [snip] 2925 1.1 christos Where Rela is specified, an implementation must honor 2926 1.1 christos this requirement." 2927 1.1 christos 2928 1.1 christos There is one relocation marked as requiring RELA - R_MSP430_ABS_HI16 - but 2929 1.1 christos to keep things simple we choose to use RELA relocations throughout. The 2930 1.1 christos problem is that the TI compiler generates REL relocations, so we have to 2931 1.1 christos be able to accept those as well. */ 2932 1.1 christos 2933 1.1 christos #define elf_backend_may_use_rel_p 1 2934 1.1 christos #define elf_backend_may_use_rela_p 1 2935 1.1 christos #define elf_backend_default_use_rela_p 1 2936 1.1 christos 2937 1.8 christos #undef elf_backend_obj_attrs_vendor 2938 1.1 christos #define elf_backend_obj_attrs_vendor "mspabi" 2939 1.8 christos #undef elf_backend_obj_attrs_section 2940 1.1 christos #define elf_backend_obj_attrs_section ".MSP430.attributes" 2941 1.8 christos #undef elf_backend_obj_attrs_section_type 2942 1.1 christos #define elf_backend_obj_attrs_section_type SHT_MSP430_ATTRIBUTES 2943 1.8 christos #define elf_backend_section_from_shdr elf32_msp430_section_from_shdr 2944 1.8 christos #define elf_backend_obj_attrs_handle_unknown elf32_msp430_obj_attrs_handle_unknown 2945 1.8 christos #undef elf_backend_obj_attrs_arg_type 2946 1.1 christos #define elf_backend_obj_attrs_arg_type elf32_msp430_obj_attrs_arg_type 2947 1.1 christos #define bfd_elf32_bfd_merge_private_bfd_data elf32_msp430_merge_private_bfd_data 2948 1.6 christos #define elf_backend_eh_frame_address_size elf32_msp430_eh_frame_address_size 2949 1.1 christos 2950 1.1 christos #define ELF_ARCH bfd_arch_msp430 2951 1.1 christos #define ELF_MACHINE_CODE EM_MSP430 2952 1.1 christos #define ELF_MACHINE_ALT1 EM_MSP430_OLD 2953 1.1 christos #define ELF_MAXPAGESIZE 4 2954 1.1 christos #define ELF_OSABI ELFOSABI_STANDALONE 2955 1.1 christos 2956 1.8 christos #define TARGET_LITTLE_SYM msp430_elf32_vec 2957 1.1 christos #define TARGET_LITTLE_NAME "elf32-msp430" 2958 1.1 christos 2959 1.8 christos #define elf_info_to_howto msp430_info_to_howto_rela 2960 1.8 christos #define elf_info_to_howto_rel NULL 2961 1.8 christos #define elf_backend_relocate_section elf32_msp430_relocate_section 2962 1.8 christos #define elf_backend_check_relocs elf32_msp430_check_relocs 2963 1.8 christos #define elf_backend_can_gc_sections 1 2964 1.1 christos #define elf_backend_final_write_processing bfd_elf_msp430_final_write_processing 2965 1.1 christos #define elf_backend_object_p elf32_msp430_object_p 2966 1.1 christos #define bfd_elf32_bfd_relax_section msp430_elf_relax_section 2967 1.1 christos #define bfd_elf32_bfd_is_target_special_symbol msp430_elf_is_target_special_symbol 2968 1.1 christos 2969 1.8 christos #undef elf32_bed 2970 1.1 christos #define elf32_bed elf32_msp430_bed 2971 1.1 christos 2972 1.1 christos #include "elf32-target.h" 2973 1.1 christos 2974 1.1 christos /* The TI compiler sets the OSABI field to ELFOSABI_NONE. */ 2975 1.8 christos #undef TARGET_LITTLE_SYM 2976 1.8 christos #define TARGET_LITTLE_SYM msp430_elf32_ti_vec 2977 1.1 christos 2978 1.8 christos #undef elf32_bed 2979 1.1 christos #define elf32_bed elf32_msp430_ti_bed 2980 1.1 christos 2981 1.6 christos #undef ELF_OSABI 2982 1.1 christos #define ELF_OSABI ELFOSABI_NONE 2983 1.1 christos 2984 1.1 christos static const struct bfd_elf_special_section msp430_ti_elf_special_sections[] = 2985 1.1 christos { 2986 1.8 christos /* prefix, prefix_length, suffix_len, type, attributes. */ 2987 1.1 christos { STRING_COMMA_LEN (".TI.symbol.alias"), 0, SHT_MSP430_SYM_ALIASES, 0 }, 2988 1.1 christos { STRING_COMMA_LEN (".TI.section.flags"), 0, SHT_MSP430_SEC_FLAGS, 0 }, 2989 1.1 christos { STRING_COMMA_LEN ("_TI_build_attrib"), 0, SHT_MSP430_ATTRIBUTES, 0 }, 2990 1.8 christos { NULL, 0, 0, 0, 0 } 2991 1.1 christos }; 2992 1.1 christos 2993 1.8 christos #undef elf_backend_special_sections 2994 1.8 christos #define elf_backend_special_sections msp430_ti_elf_special_sections 2995 1.6 christos 2996 1.1 christos #include "elf32-target.h" 2997