1214571Sdim/* BFD back-end for National Semiconductor's CR16 ELF 2214571Sdim Copyright 2007 Free Software Foundation, Inc. 3214571Sdim Written by M R Swami Reddy. 4214571Sdim 5214571Sdim This file is part of BFD, the Binary File Descriptor library. 6214571Sdim 7214571Sdim This program is free software; you can redistribute it and/or modify 8214571Sdim it under the terms of the GNU General Public License as published by 9214571Sdim the Free Software Foundation; either version 2 of the License, or 10214571Sdim (at your option) any later version. 11214571Sdim 12214571Sdim This program is distributed in the hope that it will be useful, 13214571Sdim but WITHOUT ANY WARRANTY; without even the implied warranty of 14214571Sdim MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 15214571Sdim GNU General Public License for more details. 16214571Sdim 17214571Sdim You should have received a copy of the GNU General Public License 18214571Sdim along with this program; if not, write to the Free Software Foundation, 19214571Sdim Inc., 51 Franklin Street - Fifth Floor, Boston, MA 02110-1301, USA. */ 20214571Sdim 21214571Sdim#include "sysdep.h" 22214571Sdim#include "bfd.h" 23214571Sdim#include "bfdlink.h" 24214571Sdim#include "libbfd.h" 25214571Sdim#include "libiberty.h" 26214571Sdim#include "elf-bfd.h" 27214571Sdim#include "elf/cr16.h" 28214571Sdim 29214571Sdim/* cr16_reloc_map array maps BFD relocation enum into a CRGAS relocation type. */ 30214571Sdim 31214571Sdimstruct cr16_reloc_map 32214571Sdim{ 33214571Sdim bfd_reloc_code_real_type bfd_reloc_enum; /* BFD relocation enum. */ 34214571Sdim unsigned short cr16_reloc_type; /* CR16 relocation type. */ 35214571Sdim}; 36214571Sdim 37214571Sdimstatic const struct cr16_reloc_map cr16_reloc_map[R_CR16_MAX] = 38214571Sdim{ 39214571Sdim {BFD_RELOC_NONE, R_CR16_NONE}, 40214571Sdim {BFD_RELOC_CR16_NUM8, R_CR16_NUM8}, 41214571Sdim {BFD_RELOC_CR16_NUM16, R_CR16_NUM16}, 42214571Sdim {BFD_RELOC_CR16_NUM32, R_CR16_NUM32}, 43214571Sdim {BFD_RELOC_CR16_NUM32a, R_CR16_NUM32a}, 44214571Sdim {BFD_RELOC_CR16_REGREL4, R_CR16_REGREL4}, 45214571Sdim {BFD_RELOC_CR16_REGREL4a, R_CR16_REGREL4a}, 46214571Sdim {BFD_RELOC_CR16_REGREL14, R_CR16_REGREL14}, 47214571Sdim {BFD_RELOC_CR16_REGREL14a, R_CR16_REGREL14a}, 48214571Sdim {BFD_RELOC_CR16_REGREL16, R_CR16_REGREL16}, 49214571Sdim {BFD_RELOC_CR16_REGREL20, R_CR16_REGREL20}, 50214571Sdim {BFD_RELOC_CR16_REGREL20a, R_CR16_REGREL20a}, 51214571Sdim {BFD_RELOC_CR16_ABS20, R_CR16_ABS20}, 52214571Sdim {BFD_RELOC_CR16_ABS24, R_CR16_ABS24}, 53214571Sdim {BFD_RELOC_CR16_IMM4, R_CR16_IMM4}, 54214571Sdim {BFD_RELOC_CR16_IMM8, R_CR16_IMM8}, 55214571Sdim {BFD_RELOC_CR16_IMM16, R_CR16_IMM16}, 56214571Sdim {BFD_RELOC_CR16_IMM20, R_CR16_IMM20}, 57214571Sdim {BFD_RELOC_CR16_IMM24, R_CR16_IMM24}, 58214571Sdim {BFD_RELOC_CR16_IMM32, R_CR16_IMM32}, 59214571Sdim {BFD_RELOC_CR16_IMM32a, R_CR16_IMM32a}, 60214571Sdim {BFD_RELOC_CR16_DISP4, R_CR16_DISP4}, 61214571Sdim {BFD_RELOC_CR16_DISP8, R_CR16_DISP8}, 62214571Sdim {BFD_RELOC_CR16_DISP16, R_CR16_DISP16}, 63214571Sdim {BFD_RELOC_CR16_DISP24, R_CR16_DISP24}, 64214571Sdim {BFD_RELOC_CR16_DISP24a, R_CR16_DISP24a} 65214571Sdim}; 66214571Sdim 67214571Sdimstatic reloc_howto_type cr16_elf_howto_table[] = 68214571Sdim{ 69214571Sdim HOWTO (R_CR16_NONE, /* type */ 70214571Sdim 0, /* rightshift */ 71214571Sdim 2, /* size */ 72214571Sdim 32, /* bitsize */ 73214571Sdim FALSE, /* pc_relative */ 74214571Sdim 0, /* bitpos */ 75214571Sdim complain_overflow_dont, /* complain_on_overflow */ 76214571Sdim bfd_elf_generic_reloc, /* special_function */ 77214571Sdim "R_CR16_NONE", /* name */ 78214571Sdim FALSE, /* partial_inplace */ 79214571Sdim 0, /* src_mask */ 80214571Sdim 0, /* dst_mask */ 81214571Sdim FALSE), /* pcrel_offset */ 82214571Sdim 83214571Sdim HOWTO (R_CR16_NUM8, /* type */ 84214571Sdim 0, /* rightshift */ 85214571Sdim 0, /* size */ 86214571Sdim 8, /* bitsize */ 87214571Sdim FALSE, /* pc_relative */ 88214571Sdim 0, /* bitpos */ 89214571Sdim complain_overflow_bitfield,/* complain_on_overflow */ 90214571Sdim bfd_elf_generic_reloc, /* special_function */ 91214571Sdim "R_CR16_NUM8", /* name */ 92214571Sdim FALSE, /* partial_inplace */ 93214571Sdim 0xff, /* src_mask */ 94214571Sdim 0xff, /* dst_mask */ 95214571Sdim FALSE), /* pcrel_offset */ 96214571Sdim 97214571Sdim HOWTO (R_CR16_NUM16, /* type */ 98214571Sdim 0, /* rightshift */ 99214571Sdim 1, /* size */ 100214571Sdim 16, /* bitsize */ 101214571Sdim FALSE, /* pc_relative */ 102214571Sdim 0, /* bitpos */ 103214571Sdim complain_overflow_bitfield,/* complain_on_overflow */ 104214571Sdim bfd_elf_generic_reloc, /* special_function */ 105214571Sdim "R_CR16_NUM16", /* name */ 106214571Sdim FALSE, /* partial_inplace */ 107214571Sdim 0xffff, /* src_mask */ 108214571Sdim 0xffff, /* dst_mask */ 109214571Sdim FALSE), /* pcrel_offset */ 110214571Sdim 111214571Sdim HOWTO (R_CR16_NUM32, /* type */ 112214571Sdim 0, /* rightshift */ 113214571Sdim 2, /* size */ 114214571Sdim 32, /* bitsize */ 115214571Sdim FALSE, /* pc_relative */ 116214571Sdim 0, /* bitpos */ 117214571Sdim complain_overflow_bitfield,/* complain_on_overflow */ 118214571Sdim bfd_elf_generic_reloc, /* special_function */ 119214571Sdim "R_CR16_NUM32", /* name */ 120214571Sdim FALSE, /* partial_inplace */ 121214571Sdim 0xffffffff, /* src_mask */ 122214571Sdim 0xffffffff, /* dst_mask */ 123214571Sdim FALSE), /* pcrel_offset */ 124214571Sdim 125214571Sdim HOWTO (R_CR16_NUM32a, /* type */ 126214571Sdim 1, /* rightshift */ 127214571Sdim 2, /* size */ 128214571Sdim 32, /* bitsize */ 129214571Sdim FALSE, /* pc_relative */ 130214571Sdim 0, /* bitpos */ 131214571Sdim complain_overflow_bitfield,/* complain_on_overflow */ 132214571Sdim bfd_elf_generic_reloc, /* special_function */ 133214571Sdim "R_CR16_NUM32a", /* name */ 134214571Sdim FALSE, /* partial_inplace */ 135214571Sdim 0xffffffff, /* src_mask */ 136214571Sdim 0xffffffff, /* dst_mask */ 137214571Sdim FALSE), /* pcrel_offset */ 138214571Sdim 139214571Sdim HOWTO (R_CR16_REGREL4, /* type */ 140214571Sdim 0, /* rightshift */ 141214571Sdim 0, /* size */ 142214571Sdim 4, /* bitsize */ 143214571Sdim FALSE, /* pc_relative */ 144214571Sdim 0, /* bitpos */ 145214571Sdim complain_overflow_bitfield,/* complain_on_overflow */ 146214571Sdim bfd_elf_generic_reloc, /* special_function */ 147214571Sdim "R_CR16_REGREL4", /* name */ 148214571Sdim FALSE, /* partial_inplace */ 149214571Sdim 0xf, /* src_mask */ 150214571Sdim 0xf, /* dst_mask */ 151214571Sdim FALSE), /* pcrel_offset */ 152214571Sdim 153214571Sdim HOWTO (R_CR16_REGREL4a, /* type */ 154214571Sdim 0, /* rightshift */ 155214571Sdim 0, /* size */ 156214571Sdim 4, /* bitsize */ 157214571Sdim FALSE, /* pc_relative */ 158214571Sdim 0, /* bitpos */ 159214571Sdim complain_overflow_bitfield,/* complain_on_overflow */ 160214571Sdim bfd_elf_generic_reloc, /* special_function */ 161214571Sdim "R_CR16_REGREL4a", /* name */ 162214571Sdim FALSE, /* partial_inplace */ 163214571Sdim 0xf, /* src_mask */ 164214571Sdim 0xf, /* dst_mask */ 165214571Sdim FALSE), /* pcrel_offset */ 166214571Sdim 167214571Sdim HOWTO (R_CR16_REGREL14, /* type */ 168214571Sdim 0, /* rightshift */ 169214571Sdim 1, /* size */ 170214571Sdim 14, /* bitsize */ 171214571Sdim FALSE, /* pc_relative */ 172214571Sdim 0, /* bitpos */ 173214571Sdim complain_overflow_bitfield,/* complain_on_overflow */ 174214571Sdim bfd_elf_generic_reloc, /* special_function */ 175214571Sdim "R_CR16_REGREL14", /* name */ 176214571Sdim FALSE, /* partial_inplace */ 177214571Sdim 0x3fff, /* src_mask */ 178214571Sdim 0x3fff, /* dst_mask */ 179214571Sdim FALSE), /* pcrel_offset */ 180214571Sdim 181214571Sdim HOWTO (R_CR16_REGREL14a, /* type */ 182214571Sdim 0, /* rightshift */ 183214571Sdim 1, /* size */ 184214571Sdim 14, /* bitsize */ 185214571Sdim FALSE, /* pc_relative */ 186214571Sdim 0, /* bitpos */ 187214571Sdim complain_overflow_bitfield,/* complain_on_overflow */ 188214571Sdim bfd_elf_generic_reloc, /* special_function */ 189214571Sdim "R_CR16_REGREL14a", /* name */ 190214571Sdim FALSE, /* partial_inplace */ 191214571Sdim 0x3fff, /* src_mask */ 192214571Sdim 0x3fff, /* dst_mask */ 193214571Sdim FALSE), /* pcrel_offset */ 194214571Sdim 195214571Sdim HOWTO (R_CR16_REGREL16, /* type */ 196214571Sdim 0, /* rightshift */ 197214571Sdim 1, /* size */ 198214571Sdim 16, /* bitsize */ 199214571Sdim FALSE, /* pc_relative */ 200214571Sdim 0, /* bitpos */ 201214571Sdim complain_overflow_bitfield,/* complain_on_overflow */ 202214571Sdim bfd_elf_generic_reloc, /* special_function */ 203214571Sdim "R_CR16_REGREL16", /* name */ 204214571Sdim FALSE, /* partial_inplace */ 205214571Sdim 0xffff, /* src_mask */ 206214571Sdim 0xffff, /* dst_mask */ 207214571Sdim FALSE), /* pcrel_offset */ 208214571Sdim 209214571Sdim HOWTO (R_CR16_REGREL20, /* type */ 210214571Sdim 0, /* rightshift */ 211214571Sdim 2, /* size */ 212214571Sdim 20, /* bitsize */ 213214571Sdim FALSE, /* pc_relative */ 214214571Sdim 0, /* bitpos */ 215214571Sdim complain_overflow_bitfield,/* complain_on_overflow */ 216214571Sdim bfd_elf_generic_reloc, /* special_function */ 217214571Sdim "R_CR16_REGREL20", /* name */ 218214571Sdim FALSE, /* partial_inplace */ 219214571Sdim 0xfffff, /* src_mask */ 220214571Sdim 0xfffff, /* dst_mask */ 221214571Sdim FALSE), /* pcrel_offset */ 222214571Sdim 223214571Sdim HOWTO (R_CR16_REGREL20a, /* type */ 224214571Sdim 0, /* rightshift */ 225214571Sdim 2, /* size */ 226214571Sdim 20, /* bitsize */ 227214571Sdim FALSE, /* pc_relative */ 228214571Sdim 0, /* bitpos */ 229214571Sdim complain_overflow_bitfield,/* complain_on_overflow */ 230214571Sdim bfd_elf_generic_reloc, /* special_function */ 231214571Sdim "R_CR16_REGREL20a", /* name */ 232214571Sdim FALSE, /* partial_inplace */ 233214571Sdim 0xfffff, /* src_mask */ 234214571Sdim 0xfffff, /* dst_mask */ 235214571Sdim FALSE), /* pcrel_offset */ 236214571Sdim 237214571Sdim HOWTO (R_CR16_ABS20, /* type */ 238214571Sdim 0, /* rightshift */ 239214571Sdim 2, /* size */ 240214571Sdim 20, /* bitsize */ 241214571Sdim FALSE, /* pc_relative */ 242214571Sdim 0, /* bitpos */ 243214571Sdim complain_overflow_bitfield,/* complain_on_overflow */ 244214571Sdim bfd_elf_generic_reloc, /* special_function */ 245214571Sdim "R_CR16_ABS20", /* name */ 246214571Sdim FALSE, /* partial_inplace */ 247214571Sdim 0xfffff, /* src_mask */ 248214571Sdim 0xfffff, /* dst_mask */ 249214571Sdim FALSE), /* pcrel_offset */ 250214571Sdim 251214571Sdim HOWTO (R_CR16_ABS24, /* type */ 252214571Sdim 0, /* rightshift */ 253214571Sdim 2, /* size */ 254214571Sdim 24, /* bitsize */ 255214571Sdim FALSE, /* pc_relative */ 256214571Sdim 0, /* bitpos */ 257214571Sdim complain_overflow_bitfield,/* complain_on_overflow */ 258214571Sdim bfd_elf_generic_reloc, /* special_function */ 259214571Sdim "R_CR16_ABS24", /* name */ 260214571Sdim FALSE, /* partial_inplace */ 261214571Sdim 0xffffff, /* src_mask */ 262214571Sdim 0xffffff, /* dst_mask */ 263214571Sdim FALSE), /* pcrel_offset */ 264214571Sdim 265214571Sdim HOWTO (R_CR16_IMM4, /* type */ 266214571Sdim 0, /* rightshift */ 267214571Sdim 0, /* size */ 268214571Sdim 4, /* bitsize */ 269214571Sdim FALSE, /* pc_relative */ 270214571Sdim 0, /* bitpos */ 271214571Sdim complain_overflow_bitfield,/* complain_on_overflow */ 272214571Sdim bfd_elf_generic_reloc, /* special_function */ 273214571Sdim "R_CR16_IMM4", /* name */ 274214571Sdim FALSE, /* partial_inplace */ 275214571Sdim 0xf, /* src_mask */ 276214571Sdim 0xf, /* dst_mask */ 277214571Sdim FALSE), /* pcrel_offset */ 278214571Sdim 279214571Sdim HOWTO (R_CR16_IMM8, /* type */ 280214571Sdim 0, /* rightshift */ 281214571Sdim 0, /* size */ 282214571Sdim 8, /* bitsize */ 283214571Sdim FALSE, /* pc_relative */ 284214571Sdim 0, /* bitpos */ 285214571Sdim complain_overflow_bitfield,/* complain_on_overflow */ 286214571Sdim bfd_elf_generic_reloc, /* special_function */ 287214571Sdim "R_CR16_IMM8", /* name */ 288214571Sdim FALSE, /* partial_inplace */ 289214571Sdim 0xff, /* src_mask */ 290214571Sdim 0xff, /* dst_mask */ 291214571Sdim FALSE), /* pcrel_offset */ 292214571Sdim 293214571Sdim HOWTO (R_CR16_IMM16, /* type */ 294214571Sdim 0, /* rightshift */ 295214571Sdim 1, /* size */ 296214571Sdim 16, /* bitsize */ 297214571Sdim FALSE, /* pc_relative */ 298214571Sdim 0, /* bitpos */ 299214571Sdim complain_overflow_bitfield,/* complain_on_overflow */ 300214571Sdim bfd_elf_generic_reloc, /* special_function */ 301214571Sdim "R_CR16_IMM16", /* name */ 302214571Sdim FALSE, /* partial_inplace */ 303214571Sdim 0xffff, /* src_mask */ 304214571Sdim 0xffff, /* dst_mask */ 305214571Sdim FALSE), /* pcrel_offset */ 306214571Sdim 307214571Sdim HOWTO (R_CR16_IMM20, /* type */ 308214571Sdim 0, /* rightshift */ 309214571Sdim 2, /* size */ 310214571Sdim 20, /* bitsize */ 311214571Sdim FALSE, /* pc_relative */ 312214571Sdim 0, /* bitpos */ 313214571Sdim complain_overflow_bitfield,/* complain_on_overflow */ 314214571Sdim bfd_elf_generic_reloc, /* special_function */ 315214571Sdim "R_CR16_IMM20", /* name */ 316214571Sdim FALSE, /* partial_inplace */ 317214571Sdim 0xfffff, /* src_mask */ 318214571Sdim 0xfffff, /* dst_mask */ 319214571Sdim FALSE), /* pcrel_offset */ 320214571Sdim 321214571Sdim HOWTO (R_CR16_IMM24, /* type */ 322214571Sdim 0, /* rightshift */ 323214571Sdim 2, /* size */ 324214571Sdim 24, /* bitsize */ 325214571Sdim FALSE, /* pc_relative */ 326214571Sdim 0, /* bitpos */ 327214571Sdim complain_overflow_bitfield,/* complain_on_overflow */ 328214571Sdim bfd_elf_generic_reloc, /* special_function */ 329214571Sdim "R_CR16_IMM24", /* name */ 330214571Sdim FALSE, /* partial_inplace */ 331214571Sdim 0xffffff, /* src_mask */ 332214571Sdim 0xffffff, /* dst_mask */ 333214571Sdim FALSE), /* pcrel_offset */ 334214571Sdim 335214571Sdim HOWTO (R_CR16_IMM32, /* type */ 336214571Sdim 0, /* rightshift */ 337214571Sdim 2, /* size */ 338214571Sdim 32, /* bitsize */ 339214571Sdim FALSE, /* pc_relative */ 340214571Sdim 0, /* bitpos */ 341214571Sdim complain_overflow_bitfield,/* complain_on_overflow */ 342214571Sdim bfd_elf_generic_reloc, /* special_function */ 343214571Sdim "R_CR16_IMM32", /* name */ 344214571Sdim FALSE, /* partial_inplace */ 345214571Sdim 0xffffffff, /* src_mask */ 346214571Sdim 0xffffffff, /* dst_mask */ 347214571Sdim FALSE), /* pcrel_offset */ 348214571Sdim 349214571Sdim HOWTO (R_CR16_IMM32a, /* type */ 350214571Sdim 1, /* rightshift */ 351214571Sdim 2, /* size */ 352214571Sdim 32, /* bitsize */ 353214571Sdim FALSE, /* pc_relative */ 354214571Sdim 0, /* bitpos */ 355214571Sdim complain_overflow_bitfield,/* complain_on_overflow */ 356214571Sdim bfd_elf_generic_reloc, /* special_function */ 357214571Sdim "R_CR16_IMM32a", /* name */ 358214571Sdim FALSE, /* partial_inplace */ 359214571Sdim 0xffffffff, /* src_mask */ 360214571Sdim 0xffffffff, /* dst_mask */ 361214571Sdim FALSE), /* pcrel_offset */ 362214571Sdim 363214571Sdim HOWTO (R_CR16_DISP4, /* type */ 364214571Sdim 1, /* rightshift */ 365214571Sdim 0, /* size (0 = byte, 1 = short, 2 = long) */ 366214571Sdim 4, /* bitsize */ 367214571Sdim TRUE, /* pc_relative */ 368214571Sdim 0, /* bitpos */ 369214571Sdim complain_overflow_unsigned, /* complain_on_overflow */ 370214571Sdim bfd_elf_generic_reloc, /* special_function */ 371214571Sdim "R_CR16_DISP4", /* name */ 372214571Sdim FALSE, /* partial_inplace */ 373214571Sdim 0xf, /* src_mask */ 374214571Sdim 0xf, /* dst_mask */ 375214571Sdim FALSE), /* pcrel_offset */ 376214571Sdim 377214571Sdim HOWTO (R_CR16_DISP8, /* type */ 378214571Sdim 1, /* rightshift */ 379214571Sdim 0, /* size (0 = byte, 1 = short, 2 = long) */ 380214571Sdim 8, /* bitsize */ 381214571Sdim TRUE, /* pc_relative */ 382214571Sdim 0, /* bitpos */ 383214571Sdim complain_overflow_unsigned, /* complain_on_overflow */ 384214571Sdim bfd_elf_generic_reloc, /* special_function */ 385214571Sdim "R_CR16_DISP8", /* name */ 386214571Sdim FALSE, /* partial_inplace */ 387214571Sdim 0x1ff, /* src_mask */ 388214571Sdim 0x1ff, /* dst_mask */ 389214571Sdim FALSE), /* pcrel_offset */ 390214571Sdim 391214571Sdim HOWTO (R_CR16_DISP16, /* type */ 392214571Sdim 0, /* rightshift REVIITS: To sync with WinIDEA*/ 393214571Sdim 1, /* size (0 = byte, 1 = short, 2 = long) */ 394214571Sdim 16, /* bitsize */ 395214571Sdim TRUE, /* pc_relative */ 396214571Sdim 0, /* bitpos */ 397214571Sdim complain_overflow_unsigned, /* complain_on_overflow */ 398214571Sdim bfd_elf_generic_reloc, /* special_function */ 399214571Sdim "R_CR16_DISP16", /* name */ 400214571Sdim FALSE, /* partial_inplace */ 401214571Sdim 0x1ffff, /* src_mask */ 402214571Sdim 0x1ffff, /* dst_mask */ 403214571Sdim FALSE), /* pcrel_offset */ 404214571Sdim /* REVISIT: DISP24 should be left-shift by 2 as per ISA doc 405214571Sdim but its not done, to sync with WinIDEA and CR16 4.1 tools */ 406214571Sdim HOWTO (R_CR16_DISP24, /* type */ 407214571Sdim 0, /* rightshift */ 408214571Sdim 2, /* size (0 = byte, 1 = short, 2 = long) */ 409214571Sdim 24, /* bitsize */ 410214571Sdim TRUE, /* pc_relative */ 411214571Sdim 0, /* bitpos */ 412214571Sdim complain_overflow_unsigned, /* complain_on_overflow */ 413214571Sdim bfd_elf_generic_reloc, /* special_function */ 414214571Sdim "R_CR16_DISP24", /* name */ 415214571Sdim FALSE, /* partial_inplace */ 416214571Sdim 0x1ffffff, /* src_mask */ 417214571Sdim 0x1ffffff, /* dst_mask */ 418214571Sdim FALSE), /* pcrel_offset */ 419214571Sdim 420214571Sdim HOWTO (R_CR16_DISP24a, /* type */ 421214571Sdim 0, /* rightshift */ 422214571Sdim 2, /* size (0 = byte, 1 = short, 2 = long) */ 423214571Sdim 24, /* bitsize */ 424214571Sdim TRUE, /* pc_relative */ 425214571Sdim 0, /* bitpos */ 426214571Sdim complain_overflow_unsigned, /* complain_on_overflow */ 427214571Sdim bfd_elf_generic_reloc, /* special_function */ 428214571Sdim "R_CR16_DISP24a", /* name */ 429214571Sdim FALSE, /* partial_inplace */ 430214571Sdim 0xffffff, /* src_mask */ 431214571Sdim 0xffffff, /* dst_mask */ 432214571Sdim FALSE) /* pcrel_offset */ 433214571Sdim}; 434214571Sdim 435214571Sdim/* Retrieve a howto ptr using a BFD reloc_code. */ 436214571Sdim 437214571Sdimstatic reloc_howto_type * 438214571Sdimelf_cr16_reloc_type_lookup (bfd *abfd ATTRIBUTE_UNUSED, 439214571Sdim bfd_reloc_code_real_type code) 440214571Sdim{ 441214571Sdim unsigned int i; 442214571Sdim 443214571Sdim for (i = 0; i < R_CR16_MAX; i++) 444214571Sdim if (code == cr16_reloc_map[i].bfd_reloc_enum) 445214571Sdim return &cr16_elf_howto_table[cr16_reloc_map[i].cr16_reloc_type]; 446214571Sdim 447214571Sdim _bfd_error_handler ("Unsupported CR16 relocation type: 0x%x\n", code); 448214571Sdim return NULL; 449214571Sdim} 450214571Sdim 451214571Sdimstatic reloc_howto_type * 452214571Sdimelf_cr16_reloc_name_lookup (bfd *abfd ATTRIBUTE_UNUSED, 453214571Sdim const char *r_name) 454214571Sdim{ 455214571Sdim unsigned int i; 456214571Sdim 457214571Sdim for (i = 0; ARRAY_SIZE (cr16_elf_howto_table); i++) 458214571Sdim if (cr16_elf_howto_table[i].name != NULL 459214571Sdim && strcasecmp (cr16_elf_howto_table[i].name, r_name) == 0) 460214571Sdim return cr16_elf_howto_table + i; 461214571Sdim 462214571Sdim return NULL; 463214571Sdim} 464214571Sdim 465214571Sdim/* Retrieve a howto ptr using an internal relocation entry. */ 466214571Sdim 467214571Sdimstatic void 468214571Sdimelf_cr16_info_to_howto (bfd *abfd ATTRIBUTE_UNUSED, arelent *cache_ptr, 469214571Sdim Elf_Internal_Rela *dst) 470214571Sdim{ 471214571Sdim unsigned int r_type = ELF32_R_TYPE (dst->r_info); 472214571Sdim 473214571Sdim BFD_ASSERT (r_type < (unsigned int) R_CR16_MAX); 474214571Sdim cache_ptr->howto = &cr16_elf_howto_table[r_type]; 475214571Sdim} 476214571Sdim 477214571Sdim/* Perform a relocation as part of a final link. */ 478214571Sdim 479214571Sdimstatic bfd_reloc_status_type 480214571Sdimcr16_elf_final_link_relocate (reloc_howto_type *howto, 481214571Sdim bfd *input_bfd, 482214571Sdim bfd *output_bfd ATTRIBUTE_UNUSED, 483214571Sdim asection *input_section, 484214571Sdim bfd_byte *contents, 485214571Sdim bfd_vma offset, 486214571Sdim bfd_vma Rvalue, 487214571Sdim bfd_vma addend, 488214571Sdim struct bfd_link_info *info ATTRIBUTE_UNUSED, 489214571Sdim asection *sec ATTRIBUTE_UNUSED, 490214571Sdim int is_local ATTRIBUTE_UNUSED) 491214571Sdim{ 492214571Sdim unsigned short r_type = howto->type; 493214571Sdim bfd_byte *hit_data = contents + offset; 494214571Sdim bfd_vma reloc_bits, check, Rvalue1; 495214571Sdim 496214571Sdim switch (r_type) 497214571Sdim { 498214571Sdim case R_CR16_IMM4: 499214571Sdim case R_CR16_IMM8: 500214571Sdim case R_CR16_IMM16: 501214571Sdim case R_CR16_IMM20: 502214571Sdim case R_CR16_IMM32: 503214571Sdim case R_CR16_IMM32a: 504214571Sdim case R_CR16_REGREL4: 505214571Sdim case R_CR16_REGREL4a: 506214571Sdim case R_CR16_REGREL14: 507214571Sdim case R_CR16_REGREL14a: 508214571Sdim case R_CR16_REGREL16: 509214571Sdim case R_CR16_REGREL20: 510214571Sdim case R_CR16_ABS20: 511214571Sdim case R_CR16_ABS24: 512214571Sdim case R_CR16_DISP16: 513214571Sdim case R_CR16_DISP24: 514214571Sdim /* 'hit_data' is relative to the start of the instruction, not the 515214571Sdim relocation offset. Advance it to account for the exact offset. */ 516214571Sdim hit_data += 2; 517214571Sdim break; 518214571Sdim 519214571Sdim case R_CR16_NONE: 520214571Sdim return bfd_reloc_ok; 521214571Sdim break; 522214571Sdim 523214571Sdim case R_CR16_DISP4: 524214571Sdim case R_CR16_DISP8: 525214571Sdim case R_CR16_DISP24a: 526214571Sdim /* We only care about the addend, where the difference between 527214571Sdim expressions is kept. */ 528214571Sdim if (is_local) Rvalue -= -1; 529214571Sdim 530214571Sdim default: 531214571Sdim break; 532214571Sdim } 533214571Sdim 534214571Sdim if (howto->pc_relative) 535214571Sdim { 536214571Sdim /* Subtract the address of the section containing the location. */ 537214571Sdim Rvalue -= (input_section->output_section->vma 538214571Sdim + input_section->output_offset); 539214571Sdim /* Subtract the position of the location within the section. */ 540214571Sdim Rvalue -= offset; 541214571Sdim } 542214571Sdim 543214571Sdim /* Add in supplied addend. */ 544214571Sdim Rvalue += addend; 545214571Sdim 546214571Sdim /* Complain if the bitfield overflows, whether it is considered 547214571Sdim as signed or unsigned. */ 548214571Sdim check = Rvalue >> howto->rightshift; 549214571Sdim 550214571Sdim /* Assumes two's complement. This expression avoids 551214571Sdim overflow if howto->bitsize is the number of bits in 552214571Sdim bfd_vma. */ 553214571Sdim reloc_bits = (((1 << (howto->bitsize - 1)) - 1) << 1) | 1; 554214571Sdim 555214571Sdim if (((bfd_vma) check & ~reloc_bits) != 0 556214571Sdim && (((bfd_vma) check & ~reloc_bits) 557214571Sdim != (-(bfd_vma) 1 & ~reloc_bits))) 558214571Sdim { 559214571Sdim /* The above right shift is incorrect for a signed 560214571Sdim value. See if turning on the upper bits fixes the 561214571Sdim overflow. */ 562214571Sdim if (howto->rightshift && (bfd_signed_vma) Rvalue < 0) 563214571Sdim { 564214571Sdim check |= ((bfd_vma) - 1 565214571Sdim & ~((bfd_vma) - 1 566214571Sdim >> howto->rightshift)); 567214571Sdim 568214571Sdim if (((bfd_vma) check & ~reloc_bits) 569214571Sdim != (-(bfd_vma) 1 & ~reloc_bits)) 570214571Sdim return bfd_reloc_overflow; 571214571Sdim } 572214571Sdim else 573214571Sdim return bfd_reloc_overflow; 574214571Sdim } 575214571Sdim 576214571Sdim /* Drop unwanted bits from the value we are relocating to. */ 577214571Sdim Rvalue >>= (bfd_vma) howto->rightshift; 578214571Sdim 579214571Sdim /* Apply dst_mask to select only relocatable part of the insn. */ 580214571Sdim Rvalue &= howto->dst_mask; 581214571Sdim 582214571Sdim switch (howto->size) 583214571Sdim { 584214571Sdim case 0: 585214571Sdim if ((r_type == R_CR16_IMM4) 586214571Sdim || (r_type == R_CR16_DISP4) 587214571Sdim || (r_type == R_CR16_DISP8)) 588214571Sdim { 589214571Sdim Rvalue1 = bfd_get_16 (input_bfd, hit_data); 590214571Sdim Rvalue = ((Rvalue1 & 0xf000) | ((Rvalue << 4) & 0xf00) 591214571Sdim | (Rvalue1 & 0x00f0) | (Rvalue & 0xf)); 592214571Sdim bfd_put_16 (input_bfd, Rvalue, hit_data); 593214571Sdim } 594214571Sdim break; 595214571Sdim 596214571Sdim case 1: 597214571Sdim if (r_type == R_CR16_DISP16) 598214571Sdim { 599214571Sdim Rvalue |= (bfd_get_16 (input_bfd, hit_data)); 600214571Sdim Rvalue = ((Rvalue & 0xfffe) | ((Rvalue >> 16) & 0x1)); 601214571Sdim 602214571Sdim bfd_put_16 (input_bfd, Rvalue, hit_data); 603214571Sdim } 604214571Sdim break; 605214571Sdim 606214571Sdim case 2: 607214571Sdim if (r_type == R_CR16_ABS20) 608214571Sdim { 609214571Sdim Rvalue |= (((bfd_get_16 (input_bfd, hit_data) << 16) 610214571Sdim | (bfd_get_16 (input_bfd, hit_data + 2))) 611214571Sdim & ~howto->dst_mask); 612214571Sdim Rvalue |= (bfd_get_16 (input_bfd, hit_data + 2) << 16); 613214571Sdim 614214571Sdim /* Relocation on INSTRUCTIONS is different : Instructions are 615214571Sdim word-addressable, that is, each word itself is arranged according 616214571Sdim to little-endian convention, whereas the words are arranged with 617214571Sdim respect to one another in BIG ENDIAN fashion. 618214571Sdim When there is an immediate value that spans a word boundary, 619214571Sdim it is split in a big-endian way with respect to the words. */ 620214571Sdim bfd_put_16 (input_bfd, (Rvalue) & 0xffff, hit_data); 621214571Sdim bfd_put_16 (input_bfd, (Rvalue >> 16)& 0xffff, hit_data + 2); 622214571Sdim } 623214571Sdim else if (r_type == R_CR16_ABS24) 624214571Sdim { 625214571Sdim Rvalue = ((((Rvalue >> 20)& 0xf) 626214571Sdim | (((Rvalue >> 16) & 0xf) << 8) 627214571Sdim | (bfd_get_16 (input_bfd, hit_data))) 628214571Sdim | ((Rvalue & 0xffff) << 16)); 629214571Sdim 630214571Sdim bfd_put_32 (input_bfd, Rvalue, hit_data); 631214571Sdim } 632214571Sdim else if (r_type == R_CR16_DISP24) 633214571Sdim { 634214571Sdim Rvalue = ((((Rvalue >> 20)& 0xf) | (((Rvalue >> 16) & 0xf)<<8) 635214571Sdim | (bfd_get_16 (input_bfd, hit_data))) 636214571Sdim | (((Rvalue & 0xfffE) | ((Rvalue >> 24) & 0x1)) << 16)); 637214571Sdim 638214571Sdim bfd_put_32 (input_bfd, Rvalue, hit_data); 639214571Sdim } 640214571Sdim else if ((r_type == R_CR16_IMM32) || (r_type == R_CR16_IMM32a)) 641214571Sdim { 642214571Sdim Rvalue = (((Rvalue >> 16)& 0xffff) 643214571Sdim | (bfd_get_16 (input_bfd, hit_data))) 644214571Sdim | ((Rvalue & 0xffff) << 16); 645214571Sdim bfd_put_32 (input_bfd, Rvalue, hit_data); 646214571Sdim } 647214571Sdim else if (r_type == R_CR16_DISP24a) 648214571Sdim { 649214571Sdim Rvalue = (((Rvalue & 0xfffffe) | (Rvalue >> 23))); 650214571Sdim Rvalue = ((Rvalue >> 16) & 0xff) | ((Rvalue & 0xffff) << 16) 651214571Sdim | (bfd_get_32 (input_bfd, hit_data)); 652214571Sdim 653214571Sdim bfd_put_32 (input_bfd, Rvalue, hit_data); 654214571Sdim } 655214571Sdim else if ((r_type == R_CR16_NUM32) || (r_type == R_CR16_NUM32a)) 656214571Sdim { 657214571Sdim bfd_put_32 (input_bfd, Rvalue, hit_data); 658214571Sdim } 659214571Sdim break; 660214571Sdim 661214571Sdim default: 662214571Sdim return bfd_reloc_notsupported; 663214571Sdim } 664214571Sdim 665214571Sdim return bfd_reloc_ok; 666214571Sdim} 667214571Sdim 668214571Sdim/* Delete some bytes from a section while relaxing. */ 669214571Sdim 670214571Sdimstatic bfd_boolean 671214571Sdimelf32_cr16_relax_delete_bytes (struct bfd_link_info *link_info, bfd *abfd, 672214571Sdim asection *sec, bfd_vma addr, int count) 673214571Sdim{ 674214571Sdim Elf_Internal_Shdr *symtab_hdr; 675214571Sdim unsigned int sec_shndx; 676214571Sdim bfd_byte *contents; 677214571Sdim Elf_Internal_Rela *irel, *irelend; 678214571Sdim Elf_Internal_Rela *irelalign; 679214571Sdim bfd_vma toaddr; 680214571Sdim Elf_Internal_Sym *isym; 681214571Sdim Elf_Internal_Sym *isymend; 682214571Sdim struct elf_link_hash_entry **sym_hashes; 683214571Sdim struct elf_link_hash_entry **end_hashes; 684214571Sdim struct elf_link_hash_entry **start_hashes; 685214571Sdim unsigned int symcount; 686214571Sdim 687214571Sdim sec_shndx = _bfd_elf_section_from_bfd_section (abfd, sec); 688214571Sdim 689214571Sdim contents = elf_section_data (sec)->this_hdr.contents; 690214571Sdim 691214571Sdim /* The deletion must stop at the next ALIGN reloc for an aligment 692214571Sdim power larger than the number of bytes we are deleting. */ 693214571Sdim irelalign = NULL; 694214571Sdim toaddr = sec->size; 695214571Sdim 696214571Sdim irel = elf_section_data (sec)->relocs; 697214571Sdim irelend = irel + sec->reloc_count; 698214571Sdim 699214571Sdim /* Actually delete the bytes. */ 700214571Sdim memmove (contents + addr, contents + addr + count, 701214571Sdim (size_t) (toaddr - addr - count)); 702214571Sdim sec->size -= count; 703214571Sdim 704214571Sdim /* Adjust all the relocs. */ 705214571Sdim for (irel = elf_section_data (sec)->relocs; irel < irelend; irel++) 706214571Sdim /* Get the new reloc address. */ 707214571Sdim if ((irel->r_offset > addr && irel->r_offset < toaddr)) 708214571Sdim irel->r_offset -= count; 709214571Sdim 710214571Sdim /* Adjust the local symbols defined in this section. */ 711214571Sdim symtab_hdr = &elf_tdata (abfd)->symtab_hdr; 712214571Sdim isym = (Elf_Internal_Sym *) symtab_hdr->contents; 713214571Sdim for (isymend = isym + symtab_hdr->sh_info; isym < isymend; isym++) 714214571Sdim { 715214571Sdim if (isym->st_shndx == sec_shndx 716214571Sdim && isym->st_value > addr 717214571Sdim && isym->st_value < toaddr) 718214571Sdim { 719214571Sdim /* Adjust the addend of SWITCH relocations in this section, 720214571Sdim which reference this local symbol. */ 721214571Sdim for (irel = elf_section_data (sec)->relocs; irel < irelend; irel++) 722214571Sdim { 723214571Sdim unsigned long r_symndx; 724214571Sdim Elf_Internal_Sym *rsym; 725214571Sdim bfd_vma addsym, subsym; 726214571Sdim 727214571Sdim r_symndx = ELF32_R_SYM (irel->r_info); 728214571Sdim rsym = (Elf_Internal_Sym *) symtab_hdr->contents + r_symndx; 729214571Sdim 730214571Sdim /* Skip if not the local adjusted symbol. */ 731214571Sdim if (rsym != isym) 732214571Sdim continue; 733214571Sdim 734214571Sdim addsym = isym->st_value; 735214571Sdim subsym = addsym - irel->r_addend; 736214571Sdim 737214571Sdim /* Fix the addend only when -->> (addsym > addr >= subsym). */ 738214571Sdim if (subsym <= addr) 739214571Sdim irel->r_addend -= count; 740214571Sdim else 741214571Sdim continue; 742214571Sdim } 743214571Sdim 744214571Sdim isym->st_value -= count; 745214571Sdim } 746214571Sdim } 747214571Sdim 748214571Sdim /* Now adjust the global symbols defined in this section. */ 749214571Sdim symcount = (symtab_hdr->sh_size / sizeof (Elf32_External_Sym) 750214571Sdim - symtab_hdr->sh_info); 751214571Sdim sym_hashes = start_hashes = elf_sym_hashes (abfd); 752214571Sdim end_hashes = sym_hashes + symcount; 753214571Sdim 754214571Sdim for (; sym_hashes < end_hashes; sym_hashes++) 755214571Sdim { 756214571Sdim struct elf_link_hash_entry *sym_hash = *sym_hashes; 757214571Sdim 758214571Sdim /* The '--wrap SYMBOL' option is causing a pain when the object file, 759214571Sdim containing the definition of __wrap_SYMBOL, includes a direct 760214571Sdim call to SYMBOL as well. Since both __wrap_SYMBOL and SYMBOL reference 761214571Sdim the same symbol (which is __wrap_SYMBOL), but still exist as two 762214571Sdim different symbols in 'sym_hashes', we don't want to adjust 763214571Sdim the global symbol __wrap_SYMBOL twice. 764214571Sdim This check is only relevant when symbols are being wrapped. */ 765214571Sdim if (link_info->wrap_hash != NULL) 766214571Sdim { 767214571Sdim struct elf_link_hash_entry **cur_sym_hashes; 768214571Sdim 769214571Sdim /* Loop only over the symbols whom been already checked. */ 770214571Sdim for (cur_sym_hashes = start_hashes; cur_sym_hashes < sym_hashes; 771214571Sdim cur_sym_hashes++) 772214571Sdim /* If the current symbol is identical to 'sym_hash', that means 773214571Sdim the symbol was already adjusted (or at least checked). */ 774214571Sdim if (*cur_sym_hashes == sym_hash) 775214571Sdim break; 776214571Sdim 777214571Sdim /* Don't adjust the symbol again. */ 778214571Sdim if (cur_sym_hashes < sym_hashes) 779214571Sdim continue; 780214571Sdim } 781214571Sdim 782214571Sdim if ((sym_hash->root.type == bfd_link_hash_defined 783214571Sdim || sym_hash->root.type == bfd_link_hash_defweak) 784214571Sdim && sym_hash->root.u.def.section == sec 785214571Sdim && sym_hash->root.u.def.value > addr 786214571Sdim && sym_hash->root.u.def.value < toaddr) 787214571Sdim sym_hash->root.u.def.value -= count; 788214571Sdim } 789214571Sdim 790214571Sdim return TRUE; 791214571Sdim} 792214571Sdim 793214571Sdim/* Relocate a CR16 ELF section. */ 794214571Sdim 795214571Sdimstatic bfd_boolean 796214571Sdimelf32_cr16_relocate_section (bfd *output_bfd, struct bfd_link_info *info, 797214571Sdim bfd *input_bfd, asection *input_section, 798214571Sdim bfd_byte *contents, Elf_Internal_Rela *relocs, 799214571Sdim Elf_Internal_Sym *local_syms, 800214571Sdim asection **local_sections) 801214571Sdim{ 802214571Sdim Elf_Internal_Shdr *symtab_hdr; 803214571Sdim struct elf_link_hash_entry **sym_hashes; 804214571Sdim Elf_Internal_Rela *rel, *relend; 805214571Sdim 806214571Sdim if (info->relocatable) 807214571Sdim return TRUE; 808214571Sdim 809214571Sdim symtab_hdr = &elf_tdata (input_bfd)->symtab_hdr; 810214571Sdim sym_hashes = elf_sym_hashes (input_bfd); 811214571Sdim 812214571Sdim rel = relocs; 813214571Sdim relend = relocs + input_section->reloc_count; 814214571Sdim for (; rel < relend; rel++) 815214571Sdim { 816214571Sdim int r_type; 817214571Sdim reloc_howto_type *howto; 818214571Sdim unsigned long r_symndx; 819214571Sdim Elf_Internal_Sym *sym; 820214571Sdim asection *sec; 821214571Sdim struct elf_link_hash_entry *h; 822214571Sdim bfd_vma relocation; 823214571Sdim bfd_reloc_status_type r; 824214571Sdim 825214571Sdim r_symndx = ELF32_R_SYM (rel->r_info); 826214571Sdim r_type = ELF32_R_TYPE (rel->r_info); 827214571Sdim howto = cr16_elf_howto_table + (r_type); 828214571Sdim 829214571Sdim h = NULL; 830214571Sdim sym = NULL; 831214571Sdim sec = NULL; 832214571Sdim if (r_symndx < symtab_hdr->sh_info) 833214571Sdim { 834214571Sdim sym = local_syms + r_symndx; 835214571Sdim sec = local_sections[r_symndx]; 836214571Sdim relocation = _bfd_elf_rela_local_sym (output_bfd, sym, &sec, rel); 837214571Sdim } 838214571Sdim else 839214571Sdim { 840214571Sdim bfd_boolean unresolved_reloc, warned; 841214571Sdim 842214571Sdim RELOC_FOR_GLOBAL_SYMBOL (info, input_bfd, input_section, rel, 843214571Sdim r_symndx, symtab_hdr, sym_hashes, 844214571Sdim h, sec, relocation, 845214571Sdim unresolved_reloc, warned); 846214571Sdim } 847214571Sdim 848214571Sdim r = cr16_elf_final_link_relocate (howto, input_bfd, output_bfd, 849214571Sdim input_section, 850214571Sdim contents, rel->r_offset, 851214571Sdim relocation, rel->r_addend, 852214571Sdim info, sec, h == NULL); 853214571Sdim 854214571Sdim if (r != bfd_reloc_ok) 855214571Sdim { 856214571Sdim const char *name; 857214571Sdim const char *msg = NULL; 858214571Sdim 859214571Sdim if (h != NULL) 860214571Sdim name = h->root.root.string; 861214571Sdim else 862214571Sdim { 863214571Sdim name = (bfd_elf_string_from_elf_section 864214571Sdim (input_bfd, symtab_hdr->sh_link, sym->st_name)); 865214571Sdim if (name == NULL || *name == '\0') 866214571Sdim name = bfd_section_name (input_bfd, sec); 867214571Sdim } 868214571Sdim 869214571Sdim switch (r) 870214571Sdim { 871214571Sdim case bfd_reloc_overflow: 872214571Sdim if (!((*info->callbacks->reloc_overflow) 873214571Sdim (info, (h ? &h->root : NULL), name, howto->name, 874214571Sdim (bfd_vma) 0, input_bfd, input_section, 875214571Sdim rel->r_offset))) 876214571Sdim return FALSE; 877214571Sdim break; 878214571Sdim 879214571Sdim case bfd_reloc_undefined: 880214571Sdim if (!((*info->callbacks->undefined_symbol) 881214571Sdim (info, name, input_bfd, input_section, 882214571Sdim rel->r_offset, TRUE))) 883214571Sdim return FALSE; 884214571Sdim break; 885214571Sdim 886214571Sdim case bfd_reloc_outofrange: 887214571Sdim msg = _("internal error: out of range error"); 888214571Sdim goto common_error; 889214571Sdim 890214571Sdim case bfd_reloc_notsupported: 891214571Sdim msg = _("internal error: unsupported relocation error"); 892214571Sdim goto common_error; 893214571Sdim 894214571Sdim case bfd_reloc_dangerous: 895214571Sdim msg = _("internal error: dangerous error"); 896214571Sdim goto common_error; 897214571Sdim 898214571Sdim default: 899214571Sdim msg = _("internal error: unknown error"); 900214571Sdim /* Fall through. */ 901214571Sdim 902214571Sdim common_error: 903214571Sdim if (!((*info->callbacks->warning) 904214571Sdim (info, msg, name, input_bfd, input_section, 905214571Sdim rel->r_offset))) 906214571Sdim return FALSE; 907214571Sdim break; 908214571Sdim } 909214571Sdim } 910214571Sdim } 911214571Sdim 912214571Sdim return TRUE; 913214571Sdim} 914214571Sdim 915214571Sdim/* This is a version of bfd_generic_get_relocated_section_contents 916214571Sdim which uses elf32_cr16_relocate_section. */ 917214571Sdim 918214571Sdimstatic bfd_byte * 919214571Sdimelf32_cr16_get_relocated_section_contents (bfd *output_bfd, 920214571Sdim struct bfd_link_info *link_info, 921214571Sdim struct bfd_link_order *link_order, 922214571Sdim bfd_byte *data, 923214571Sdim bfd_boolean relocatable, 924214571Sdim asymbol **symbols) 925214571Sdim{ 926214571Sdim Elf_Internal_Shdr *symtab_hdr; 927214571Sdim asection *input_section = link_order->u.indirect.section; 928214571Sdim bfd *input_bfd = input_section->owner; 929214571Sdim asection **sections = NULL; 930214571Sdim Elf_Internal_Rela *internal_relocs = NULL; 931214571Sdim Elf_Internal_Sym *isymbuf = NULL; 932214571Sdim 933214571Sdim /* We only need to handle the case of relaxing, or of having a 934214571Sdim particular set of section contents, specially. */ 935214571Sdim if (relocatable 936214571Sdim || elf_section_data (input_section)->this_hdr.contents == NULL) 937214571Sdim return bfd_generic_get_relocated_section_contents (output_bfd, link_info, 938214571Sdim link_order, data, 939214571Sdim relocatable, 940214571Sdim symbols); 941214571Sdim 942214571Sdim symtab_hdr = &elf_tdata (input_bfd)->symtab_hdr; 943214571Sdim 944214571Sdim memcpy (data, elf_section_data (input_section)->this_hdr.contents, 945214571Sdim (size_t) input_section->size); 946214571Sdim 947214571Sdim if ((input_section->flags & SEC_RELOC) != 0 948214571Sdim && input_section->reloc_count > 0) 949214571Sdim { 950214571Sdim Elf_Internal_Sym *isym; 951214571Sdim Elf_Internal_Sym *isymend; 952214571Sdim asection **secpp; 953214571Sdim bfd_size_type amt; 954214571Sdim 955214571Sdim internal_relocs = _bfd_elf_link_read_relocs (input_bfd, input_section, 956214571Sdim NULL, NULL, FALSE); 957214571Sdim if (internal_relocs == NULL) 958214571Sdim goto error_return; 959214571Sdim 960214571Sdim if (symtab_hdr->sh_info != 0) 961214571Sdim { 962214571Sdim isymbuf = (Elf_Internal_Sym *) symtab_hdr->contents; 963214571Sdim if (isymbuf == NULL) 964214571Sdim isymbuf = bfd_elf_get_elf_syms (input_bfd, symtab_hdr, 965214571Sdim symtab_hdr->sh_info, 0, 966214571Sdim NULL, NULL, NULL); 967214571Sdim if (isymbuf == NULL) 968214571Sdim goto error_return; 969214571Sdim } 970214571Sdim 971214571Sdim amt = symtab_hdr->sh_info; 972214571Sdim amt *= sizeof (asection *); 973214571Sdim sections = bfd_malloc (amt); 974214571Sdim if (sections == NULL && amt != 0) 975214571Sdim goto error_return; 976214571Sdim 977214571Sdim isymend = isymbuf + symtab_hdr->sh_info; 978214571Sdim for (isym = isymbuf, secpp = sections; isym < isymend; ++isym, ++secpp) 979214571Sdim { 980214571Sdim asection *isec; 981214571Sdim 982214571Sdim if (isym->st_shndx == SHN_UNDEF) 983214571Sdim isec = bfd_und_section_ptr; 984214571Sdim else if (isym->st_shndx == SHN_ABS) 985214571Sdim isec = bfd_abs_section_ptr; 986214571Sdim else if (isym->st_shndx == SHN_COMMON) 987214571Sdim isec = bfd_com_section_ptr; 988214571Sdim else 989214571Sdim isec = bfd_section_from_elf_index (input_bfd, isym->st_shndx); 990214571Sdim 991214571Sdim *secpp = isec; 992214571Sdim } 993214571Sdim 994214571Sdim if (! elf32_cr16_relocate_section (output_bfd, link_info, input_bfd, 995214571Sdim input_section, data, internal_relocs, 996214571Sdim isymbuf, sections)) 997214571Sdim goto error_return; 998214571Sdim 999214571Sdim if (sections != NULL) 1000214571Sdim free (sections); 1001214571Sdim if (isymbuf != NULL 1002214571Sdim && symtab_hdr->contents != (unsigned char *) isymbuf) 1003214571Sdim free (isymbuf); 1004214571Sdim if (elf_section_data (input_section)->relocs != internal_relocs) 1005214571Sdim free (internal_relocs); 1006214571Sdim } 1007214571Sdim 1008214571Sdim return data; 1009214571Sdim 1010214571Sdim error_return: 1011214571Sdim if (sections != NULL) 1012214571Sdim free (sections); 1013214571Sdim if (isymbuf != NULL 1014214571Sdim && symtab_hdr->contents != (unsigned char *) isymbuf) 1015214571Sdim free (isymbuf); 1016214571Sdim if (internal_relocs != NULL 1017214571Sdim && elf_section_data (input_section)->relocs != internal_relocs) 1018214571Sdim free (internal_relocs); 1019214571Sdim return NULL; 1020214571Sdim} 1021214571Sdim 1022214571Sdim/* This function handles relaxing for the CR16. 1023214571Sdim 1024214571Sdim There's quite a few relaxing opportunites available on the CR16: 1025214571Sdim 1026214571Sdim * bcond:24 -> bcond:16 2 bytes 1027214571Sdim * bcond:16 -> bcond:8 2 bytes 1028214571Sdim * arithmetic imm32 -> arithmetic imm16 2 bytes 1029214571Sdim 1030214571Sdim Symbol- and reloc-reading infrastructure copied from elf-m10200.c. */ 1031214571Sdim 1032214571Sdimstatic bfd_boolean 1033214571Sdimelf32_cr16_relax_section (bfd *abfd, asection *sec, 1034214571Sdim struct bfd_link_info *link_info, bfd_boolean *again) 1035214571Sdim{ 1036214571Sdim Elf_Internal_Shdr *symtab_hdr; 1037214571Sdim Elf_Internal_Rela *internal_relocs; 1038214571Sdim Elf_Internal_Rela *irel, *irelend; 1039214571Sdim bfd_byte *contents = NULL; 1040214571Sdim Elf_Internal_Sym *isymbuf = NULL; 1041214571Sdim 1042214571Sdim /* Assume nothing changes. */ 1043214571Sdim *again = FALSE; 1044214571Sdim 1045214571Sdim /* We don't have to do anything for a relocatable link, if 1046214571Sdim this section does not have relocs, or if this is not a 1047214571Sdim code section. */ 1048214571Sdim if (link_info->relocatable 1049214571Sdim || (sec->flags & SEC_RELOC) == 0 1050214571Sdim || sec->reloc_count == 0 1051214571Sdim || (sec->flags & SEC_CODE) == 0) 1052214571Sdim return TRUE; 1053214571Sdim 1054214571Sdim symtab_hdr = &elf_tdata (abfd)->symtab_hdr; 1055214571Sdim 1056214571Sdim /* Get a copy of the native relocations. */ 1057214571Sdim internal_relocs = _bfd_elf_link_read_relocs (abfd, sec, NULL, NULL, 1058214571Sdim link_info->keep_memory); 1059214571Sdim if (internal_relocs == NULL) 1060214571Sdim goto error_return; 1061214571Sdim 1062214571Sdim /* Walk through them looking for relaxing opportunities. */ 1063214571Sdim irelend = internal_relocs + sec->reloc_count; 1064214571Sdim for (irel = internal_relocs; irel < irelend; irel++) 1065214571Sdim { 1066214571Sdim bfd_vma symval; 1067214571Sdim 1068214571Sdim /* If this isn't something that can be relaxed, then ignore 1069214571Sdim this reloc. */ 1070214571Sdim if (ELF32_R_TYPE (irel->r_info) != (int) R_CR16_DISP16 1071214571Sdim && ELF32_R_TYPE (irel->r_info) != (int) R_CR16_DISP24) 1072214571Sdim continue; 1073214571Sdim 1074214571Sdim /* Get the section contents if we haven't done so already. */ 1075214571Sdim if (contents == NULL) 1076214571Sdim { 1077214571Sdim /* Get cached copy if it exists. */ 1078214571Sdim if (elf_section_data (sec)->this_hdr.contents != NULL) 1079214571Sdim contents = elf_section_data (sec)->this_hdr.contents; 1080214571Sdim /* Go get them off disk. */ 1081214571Sdim else if (!bfd_malloc_and_get_section (abfd, sec, &contents)) 1082214571Sdim goto error_return; 1083214571Sdim } 1084214571Sdim 1085214571Sdim /* Read this BFD's local symbols if we haven't done so already. */ 1086214571Sdim if (isymbuf == NULL && symtab_hdr->sh_info != 0) 1087214571Sdim { 1088214571Sdim isymbuf = (Elf_Internal_Sym *) symtab_hdr->contents; 1089214571Sdim if (isymbuf == NULL) 1090214571Sdim isymbuf = bfd_elf_get_elf_syms (abfd, symtab_hdr, 1091214571Sdim symtab_hdr->sh_info, 0, 1092214571Sdim NULL, NULL, NULL); 1093214571Sdim if (isymbuf == NULL) 1094214571Sdim goto error_return; 1095214571Sdim } 1096214571Sdim 1097214571Sdim /* Get the value of the symbol referred to by the reloc. */ 1098214571Sdim if (ELF32_R_SYM (irel->r_info) < symtab_hdr->sh_info) 1099214571Sdim { 1100214571Sdim /* A local symbol. */ 1101214571Sdim Elf_Internal_Sym *isym; 1102214571Sdim asection *sym_sec; 1103214571Sdim 1104214571Sdim isym = isymbuf + ELF32_R_SYM (irel->r_info); 1105214571Sdim if (isym->st_shndx == SHN_UNDEF) 1106214571Sdim sym_sec = bfd_und_section_ptr; 1107214571Sdim else if (isym->st_shndx == SHN_ABS) 1108214571Sdim sym_sec = bfd_abs_section_ptr; 1109214571Sdim else if (isym->st_shndx == SHN_COMMON) 1110214571Sdim sym_sec = bfd_com_section_ptr; 1111214571Sdim else 1112214571Sdim sym_sec = bfd_section_from_elf_index (abfd, isym->st_shndx); 1113214571Sdim symval = (isym->st_value 1114214571Sdim + sym_sec->output_section->vma 1115214571Sdim + sym_sec->output_offset); 1116214571Sdim } 1117214571Sdim else 1118214571Sdim { 1119214571Sdim unsigned long indx; 1120214571Sdim struct elf_link_hash_entry *h; 1121214571Sdim 1122214571Sdim /* An external symbol. */ 1123214571Sdim indx = ELF32_R_SYM (irel->r_info) - symtab_hdr->sh_info; 1124214571Sdim h = elf_sym_hashes (abfd)[indx]; 1125214571Sdim BFD_ASSERT (h != NULL); 1126214571Sdim 1127214571Sdim if (h->root.type != bfd_link_hash_defined 1128214571Sdim && h->root.type != bfd_link_hash_defweak) 1129214571Sdim /* This appears to be a reference to an undefined 1130214571Sdim symbol. Just ignore it--it will be caught by the 1131214571Sdim regular reloc processing. */ 1132214571Sdim continue; 1133214571Sdim 1134214571Sdim symval = (h->root.u.def.value 1135214571Sdim + h->root.u.def.section->output_section->vma 1136214571Sdim + h->root.u.def.section->output_offset); 1137214571Sdim } 1138214571Sdim 1139214571Sdim /* For simplicity of coding, we are going to modify the section 1140214571Sdim contents, the section relocs, and the BFD symbol table. We 1141214571Sdim must tell the rest of the code not to free up this 1142214571Sdim information. It would be possible to instead create a table 1143214571Sdim of changes which have to be made, as is done in coff-mips.c; 1144214571Sdim that would be more work, but would require less memory when 1145214571Sdim the linker is run. */ 1146214571Sdim 1147214571Sdim /* Try to turn a 24 branch/call into a 16bit relative 1148214571Sdim * branch/call. */ 1149214571Sdim if (ELF32_R_TYPE (irel->r_info) == (int) R_CR16_DISP24) 1150214571Sdim { 1151214571Sdim bfd_vma value = symval; 1152214571Sdim 1153214571Sdim /* Deal with pc-relative gunk. */ 1154214571Sdim value -= (sec->output_section->vma + sec->output_offset); 1155214571Sdim value -= irel->r_offset; 1156214571Sdim value += irel->r_addend; 1157214571Sdim 1158214571Sdim /* See if the value will fit in 16 bits, note the high value is 1159214571Sdim 0xfffe + 2 as the target will be two bytes closer if we are 1160214571Sdim able to relax. */ 1161214571Sdim if ((long) value < 0x10000 && (long) value > -0x10002) 1162214571Sdim { 1163214571Sdim unsigned int code; 1164214571Sdim 1165214571Sdim /* Get the opcode. */ 1166214571Sdim code = (unsigned int) bfd_get_32 (abfd, contents + irel->r_offset); 1167214571Sdim 1168214571Sdim /* Verify it's a 'bcond' and fix the opcode. */ 1169214571Sdim if ((code & 0xffff) == 0x0010) 1170214571Sdim { 1171214571Sdim bfd_put_16 (abfd, 0x1800 | ((0xf & (code >>20))<<4), contents + irel->r_offset); 1172214571Sdim bfd_put_16 (abfd, value, contents + irel->r_offset+2); 1173214571Sdim } 1174214571Sdim else 1175214571Sdim continue; 1176214571Sdim 1177214571Sdim /* Note that we've changed the relocs, section contents, etc. */ 1178214571Sdim elf_section_data (sec)->relocs = internal_relocs; 1179214571Sdim elf_section_data (sec)->this_hdr.contents = contents; 1180214571Sdim symtab_hdr->contents = (unsigned char *) isymbuf; 1181214571Sdim 1182214571Sdim /* Fix the relocation's type. */ 1183214571Sdim irel->r_info = ELF32_R_INFO (ELF32_R_SYM (irel->r_info), 1184214571Sdim R_CR16_DISP16); 1185214571Sdim 1186214571Sdim /* Delete two bytes of data. */ 1187214571Sdim if (!elf32_cr16_relax_delete_bytes (link_info, abfd, sec, 1188214571Sdim irel->r_offset + 2, 2)) 1189214571Sdim goto error_return; 1190214571Sdim 1191214571Sdim /* That will change things, so, we should relax again. 1192214571Sdim Note that this is not required, and it may be slow. */ 1193214571Sdim *again = TRUE; 1194214571Sdim } 1195214571Sdim } 1196214571Sdim 1197214571Sdim /* Try to turn a 16bit pc-relative branch into an 1198214571Sdim 8bit pc-relative branch. */ 1199214571Sdim if (ELF32_R_TYPE (irel->r_info) == (int) R_CR16_DISP16) 1200214571Sdim { 1201214571Sdim bfd_vma value = symval; 1202214571Sdim 1203214571Sdim /* Deal with pc-relative gunk. */ 1204214571Sdim value -= (sec->output_section->vma + sec->output_offset); 1205214571Sdim value -= irel->r_offset; 1206214571Sdim value += irel->r_addend; 1207214571Sdim 1208214571Sdim /* See if the value will fit in 8 bits, note the high value is 1209214571Sdim 0xfc + 2 as the target will be two bytes closer if we are 1210214571Sdim able to relax. */ 1211214571Sdim if ((long) value < 0xfe && (long) value > -0x100) 1212214571Sdim { 1213214571Sdim unsigned short code; 1214214571Sdim 1215214571Sdim /* Get the opcode. */ 1216214571Sdim code = (unsigned short) bfd_get_16 (abfd, contents + irel->r_offset); 1217214571Sdim 1218214571Sdim /* Verify it's a 'bcond' opcode. */ 1219214571Sdim if ((code & 0xff00) == 0x1800) 1220214571Sdim { 1221214571Sdim bfd_put_8 (abfd, 0x1 | ((0xf & (code>>4))<<4), contents + irel->r_offset); 1222214571Sdim bfd_put_8 (abfd, value, contents + irel->r_offset+2); 1223214571Sdim } 1224214571Sdim else 1225214571Sdim continue; 1226214571Sdim 1227214571Sdim /* Note that we've changed the relocs, section contents, etc. */ 1228214571Sdim elf_section_data (sec)->relocs = internal_relocs; 1229214571Sdim elf_section_data (sec)->this_hdr.contents = contents; 1230214571Sdim symtab_hdr->contents = (unsigned char *) isymbuf; 1231214571Sdim 1232214571Sdim /* Fix the relocation's type. */ 1233214571Sdim irel->r_info = ELF32_R_INFO (ELF32_R_SYM (irel->r_info), 1234214571Sdim R_CR16_DISP8); 1235214571Sdim 1236214571Sdim /* Delete two bytes of data. */ 1237214571Sdim if (!elf32_cr16_relax_delete_bytes (link_info, abfd, sec, 1238214571Sdim irel->r_offset + 2, 2)) 1239214571Sdim goto error_return; 1240214571Sdim 1241214571Sdim /* That will change things, so, we should relax again. 1242214571Sdim Note that this is not required, and it may be slow. */ 1243214571Sdim *again = TRUE; 1244214571Sdim } 1245214571Sdim } 1246214571Sdim 1247214571Sdim#if 0 // REVISIT: To support IMM relaxation in CR16 target 1248214571Sdim /* Try to turn a 32bit immediate address into 1249214571Sdim a 20bit immediate address. */ 1250214571Sdim if (ELF32_R_TYPE (irel->r_info) == (int) R_CR16_IMM32) 1251214571Sdim { 1252214571Sdim bfd_vma value = symval; 1253214571Sdim 1254214571Sdim /* See if the value will fit in 20 bits. */ 1255214571Sdim if ((long) value < 0x7ffff && (long) value > -0x80000) 1256214571Sdim { 1257214571Sdim unsigned short code; 1258214571Sdim 1259214571Sdim /* Get the opcode. */ 1260214571Sdim code = (unsigned short) bfd_get_16 (abfd, contents + irel->r_offset); 1261214571Sdim 1262214571Sdim /* Verify it's a 'arithmetic double'. */ 1263214571Sdim if ((code & 0xfff0) != 0x0070) 1264214571Sdim continue; 1265214571Sdim 1266214571Sdim /* Note that we've changed the relocs, section contents, etc. */ 1267214571Sdim elf_section_data (sec)->relocs = internal_relocs; 1268214571Sdim elf_section_data (sec)->this_hdr.contents = contents; 1269214571Sdim symtab_hdr->contents = (unsigned char *) isymbuf; 1270214571Sdim 1271214571Sdim /* Fix the opcode. */ 1272214571Sdim bfd_put_8 (abfd, (code & 0xff) - 0x10, contents + irel->r_offset); 1273214571Sdim 1274214571Sdim /* Fix the relocation's type. */ 1275214571Sdim irel->r_info = ELF32_R_INFO (ELF32_R_SYM (irel->r_info), 1276214571Sdim R_CR16_IMM20); 1277214571Sdim 1278214571Sdim /* Delete two bytes of data. */ 1279214571Sdim if (!elf32_cr16_relax_delete_bytes (link_info, abfd, sec, 1280214571Sdim irel->r_offset + 2, 2)) 1281214571Sdim goto error_return; 1282214571Sdim 1283214571Sdim /* That will change things, so, we should relax again. 1284214571Sdim Note that this is not required, and it may be slow. */ 1285214571Sdim *again = TRUE; 1286214571Sdim } 1287214571Sdim } 1288214571Sdim /* Try to turn a 20bit/16bit immediate address into 1289214571Sdim a 4bit immediate address. */ 1290214571Sdim if ((ELF32_R_TYPE (irel->r_info) == (int) R_CR16_IMM20) 1291214571Sdim || (ELF32_R_TYPE (irel->r_info) == (int) R_CR16_IMM16)) 1292214571Sdim { 1293214571Sdim bfd_vma value = symval; 1294214571Sdim 1295214571Sdim /* See if the value will fit in 4 bits. */ 1296214571Sdim if ((long) value < 0x7 && (long) value > -0x8) 1297214571Sdim { 1298214571Sdim unsigned short code; 1299214571Sdim 1300214571Sdim /* Get the opcode. */ 1301214571Sdim code = (unsigned short) bfd_get_8 (abfd, contents + irel->r_offset); 1302214571Sdim 1303214571Sdim /* Verify it's a 'arithmetic double'. */ 1304214571Sdim if (((code & 0xff) != 0x50) || ((code & 0xff) != 0x45)) 1305214571Sdim continue; 1306214571Sdim 1307214571Sdim /* Note that we've changed the relocs, section contents, etc. */ 1308214571Sdim elf_section_data (sec)->relocs = internal_relocs; 1309214571Sdim elf_section_data (sec)->this_hdr.contents = contents; 1310214571Sdim symtab_hdr->contents = (unsigned char *) isymbuf; 1311214571Sdim 1312214571Sdim /* Fix the opcode. */ 1313214571Sdim bfd_put_8 (abfd, (code & 0xff) - 0x10, contents + irel->r_offset); 1314214571Sdim 1315214571Sdim /* Fix the relocation's type. */ 1316214571Sdim irel->r_info = ELF32_R_INFO (ELF32_R_SYM (irel->r_info), 1317214571Sdim R_CR16_IMM4); 1318214571Sdim 1319214571Sdim /* Delete two bytes of data. */ 1320214571Sdim if (!elf32_cr16_relax_delete_bytes (link_info, abfd, sec, 1321214571Sdim irel->r_offset + 2, 2)) 1322214571Sdim goto error_return; 1323214571Sdim 1324214571Sdim /* That will change things, so, we should relax again. 1325214571Sdim Note that this is not required, and it may be slow. */ 1326214571Sdim *again = TRUE; 1327214571Sdim } 1328214571Sdim } 1329214571Sdim#endif 1330214571Sdim } 1331214571Sdim 1332214571Sdim if (isymbuf != NULL 1333214571Sdim && symtab_hdr->contents != (unsigned char *) isymbuf) 1334214571Sdim { 1335214571Sdim if (! link_info->keep_memory) 1336214571Sdim free (isymbuf); 1337214571Sdim else 1338214571Sdim { 1339214571Sdim /* Cache the symbols for elf_link_input_bfd. */ 1340214571Sdim symtab_hdr->contents = (unsigned char *) isymbuf; 1341214571Sdim } 1342214571Sdim } 1343214571Sdim 1344214571Sdim if (contents != NULL 1345214571Sdim && elf_section_data (sec)->this_hdr.contents != contents) 1346214571Sdim { 1347214571Sdim if (! link_info->keep_memory) 1348214571Sdim free (contents); 1349214571Sdim else 1350214571Sdim { 1351214571Sdim /* Cache the section contents for elf_link_input_bfd. */ 1352214571Sdim elf_section_data (sec)->this_hdr.contents = contents; 1353214571Sdim } 1354214571Sdim } 1355214571Sdim 1356214571Sdim if (internal_relocs != NULL 1357214571Sdim && elf_section_data (sec)->relocs != internal_relocs) 1358214571Sdim free (internal_relocs); 1359214571Sdim 1360214571Sdim return TRUE; 1361214571Sdim 1362214571Sdim error_return: 1363214571Sdim if (isymbuf != NULL 1364214571Sdim && symtab_hdr->contents != (unsigned char *) isymbuf) 1365214571Sdim free (isymbuf); 1366214571Sdim if (contents != NULL 1367214571Sdim && elf_section_data (sec)->this_hdr.contents != contents) 1368214571Sdim free (contents); 1369214571Sdim if (internal_relocs != NULL 1370214571Sdim && elf_section_data (sec)->relocs != internal_relocs) 1371214571Sdim free (internal_relocs); 1372214571Sdim 1373214571Sdim return FALSE; 1374214571Sdim} 1375214571Sdim 1376214571Sdimstatic asection * 1377214571Sdimelf32_cr16_gc_mark_hook (asection *sec, 1378214571Sdim struct bfd_link_info *info ATTRIBUTE_UNUSED, 1379214571Sdim Elf_Internal_Rela *rel ATTRIBUTE_UNUSED, 1380214571Sdim struct elf_link_hash_entry *h, 1381214571Sdim Elf_Internal_Sym *sym) 1382214571Sdim{ 1383214571Sdim if (h == NULL) 1384214571Sdim return bfd_section_from_elf_index (sec->owner, sym->st_shndx); 1385214571Sdim 1386214571Sdim switch (h->root.type) 1387214571Sdim { 1388214571Sdim case bfd_link_hash_defined: 1389214571Sdim case bfd_link_hash_defweak: 1390214571Sdim return h->root.u.def.section; 1391214571Sdim 1392214571Sdim case bfd_link_hash_common: 1393214571Sdim return h->root.u.c.p->section; 1394214571Sdim 1395214571Sdim default: 1396214571Sdim return NULL; 1397214571Sdim } 1398214571Sdim} 1399214571Sdim 1400214571Sdim/* Update the got entry reference counts for the section being removed. */ 1401214571Sdim 1402214571Sdimstatic bfd_boolean 1403214571Sdimelf32_cr16_gc_sweep_hook (bfd *abfd ATTRIBUTE_UNUSED, 1404214571Sdim struct bfd_link_info *info ATTRIBUTE_UNUSED, 1405214571Sdim asection *sec ATTRIBUTE_UNUSED, 1406214571Sdim const Elf_Internal_Rela *relocs ATTRIBUTE_UNUSED) 1407214571Sdim{ 1408214571Sdim /* We don't support garbage collection of GOT and PLT relocs yet. */ 1409214571Sdim return TRUE; 1410214571Sdim} 1411214571Sdim 1412214571Sdim/* Definitions for setting CR16 target vector. */ 1413214571Sdim#define TARGET_LITTLE_SYM bfd_elf32_cr16_vec 1414214571Sdim#define TARGET_LITTLE_NAME "elf32-cr16" 1415214571Sdim#define ELF_ARCH bfd_arch_cr16 1416214571Sdim#define ELF_MACHINE_CODE EM_CR16 1417214571Sdim#define ELF_MAXPAGESIZE 0x1 1418214571Sdim#define elf_symbol_leading_char '_' 1419214571Sdim 1420214571Sdim#define bfd_elf32_bfd_reloc_type_lookup elf_cr16_reloc_type_lookup 1421214571Sdim#define bfd_elf32_bfd_reloc_name_lookup elf_cr16_reloc_name_lookup 1422214571Sdim#define elf_info_to_howto elf_cr16_info_to_howto 1423214571Sdim#define elf_info_to_howto_rel 0 1424214571Sdim#define elf_backend_relocate_section elf32_cr16_relocate_section 1425214571Sdim#define bfd_elf32_bfd_relax_section elf32_cr16_relax_section 1426214571Sdim#define bfd_elf32_bfd_get_relocated_section_contents \ 1427214571Sdim elf32_cr16_get_relocated_section_contents 1428214571Sdim#define elf_backend_gc_mark_hook elf32_cr16_gc_mark_hook 1429214571Sdim#define elf_backend_gc_sweep_hook elf32_cr16_gc_sweep_hook 1430214571Sdim#define elf_backend_can_gc_sections 1 1431214571Sdim#define elf_backend_rela_normal 1 1432214571Sdim 1433214571Sdim#include "elf32-target.h" 1434