/* 32-bit ELF support for TI C6X Copyright 2010 Free Software Foundation, Inc. Contributed by Joseph Myers <joseph@codesourcery.com> Bernd Schmidt <bernds@codesourcery.com> This file is part of BFD, the Binary File Descriptor library. This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation; either version 3 of the License, or (at your option) any later version. This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. You should have received a copy of the GNU General Public License along with this program; if not, write to the Free Software Foundation, Inc., 51 Franklin Street - Fifth Floor, Boston, MA 02110-1301, USA. */ #include "sysdep.h" #include "bfd.h" #include "libbfd.h" #include "libiberty.h" #include "elf-bfd.h" #include "elf/tic6x.h" #include "elf32-tic6x.h" struct elf32_tic6x_obj_tdata { struct elf_obj_tdata root; /* Whether to use RELA relocations when generating relocations. This is a per-object flag to allow the assembler to generate REL relocations for use in linker testcases. */ bfd_boolean use_rela_p; }; #define elf32_tic6x_tdata(abfd) \ ((struct elf32_tic6x_obj_tdata *) (abfd)->tdata.any) static reloc_howto_type elf32_tic6x_howto_table[] = { HOWTO (R_C6000_NONE, /* type */ 0, /* rightshift */ 0, /* size (0 = byte, 1 = short, 2 = long) */ 0, /* bitsize */ FALSE, /* pc_relative */ 0, /* bitpos */ complain_overflow_dont,/* complain_on_overflow */ bfd_elf_generic_reloc, /* special_function */ "R_C6000_NONE", /* name */ FALSE, /* partial_inplace */ 0, /* src_mask */ 0, /* dst_mask */ FALSE), /* pcrel_offset */ HOWTO (R_C6000_ABS32, /* type */ 0, /* rightshift */ 2, /* size (0 = byte, 1 = short, 2 = long) */ 32, /* bitsize */ FALSE, /* pc_relative */ 0, /* bitpos */ complain_overflow_dont,/* complain_on_overflow */ bfd_elf_generic_reloc, /* special_function */ "R_C6000_ABS32", /* name */ FALSE, /* partial_inplace */ 0, /* src_mask */ 0xffffffff, /* dst_mask */ FALSE), /* pcrel_offset */ HOWTO (R_C6000_ABS16, /* type */ 0, /* rightshift */ 1, /* size (0 = byte, 1 = short, 2 = long) */ 16, /* bitsize */ FALSE, /* pc_relative */ 0, /* bitpos */ complain_overflow_bitfield,/* complain_on_overflow */ bfd_elf_generic_reloc, /* special_function */ "R_C6000_ABS16", /* name */ FALSE, /* partial_inplace */ 0, /* src_mask */ 0x0000ffff, /* dst_mask */ FALSE), /* pcrel_offset */ HOWTO (R_C6000_ABS8, /* type */ 0, /* rightshift */ 0, /* size (0 = byte, 1 = short, 2 = long) */ 8, /* bitsize */ FALSE, /* pc_relative */ 0, /* bitpos */ complain_overflow_bitfield,/* complain_on_overflow */ bfd_elf_generic_reloc, /* special_function */ "R_C6000_ABS8", /* name */ FALSE, /* partial_inplace */ 0, /* src_mask */ 0x000000ff, /* dst_mask */ FALSE), /* pcrel_offset */ HOWTO (R_C6000_PCR_S21, /* type */ 2, /* rightshift */ 2, /* size (0 = byte, 1 = short, 2 = long) */ 21, /* bitsize */ TRUE, /* pc_relative */ 7, /* bitpos */ complain_overflow_signed,/* complain_on_overflow */ bfd_elf_generic_reloc, /* special_function */ "R_C6000_PCR_S21", /* name */ FALSE, /* partial_inplace */ 0, /* src_mask */ 0x0fffff80, /* dst_mask */ TRUE), /* pcrel_offset */ HOWTO (R_C6000_PCR_S12, /* type */ 2, /* rightshift */ 2, /* size (0 = byte, 1 = short, 2 = long) */ 12, /* bitsize */ TRUE, /* pc_relative */ 16, /* bitpos */ complain_overflow_signed,/* complain_on_overflow */ bfd_elf_generic_reloc, /* special_function */ "R_C6000_PCR_S12", /* name */ FALSE, /* partial_inplace */ 0, /* src_mask */ 0x0fff0000, /* dst_mask */ TRUE), /* pcrel_offset */ HOWTO (R_C6000_PCR_S10, /* type */ 2, /* rightshift */ 2, /* size (0 = byte, 1 = short, 2 = long) */ 10, /* bitsize */ TRUE, /* pc_relative */ 13, /* bitpos */ complain_overflow_signed,/* complain_on_overflow */ bfd_elf_generic_reloc, /* special_function */ "R_C6000_PCR_S10", /* name */ FALSE, /* partial_inplace */ 0, /* src_mask */ 0x007fe000, /* dst_mask */ TRUE), /* pcrel_offset */ HOWTO (R_C6000_PCR_S7, /* type */ 2, /* rightshift */ 2, /* size (0 = byte, 1 = short, 2 = long) */ 7, /* bitsize */ TRUE, /* pc_relative */ 16, /* bitpos */ complain_overflow_signed,/* complain_on_overflow */ bfd_elf_generic_reloc, /* special_function */ "R_C6000_PCR_S7", /* name */ FALSE, /* partial_inplace */ 0, /* src_mask */ 0x007f0000, /* dst_mask */ TRUE), /* pcrel_offset */ HOWTO (R_C6000_ABS_S16, /* type */ 0, /* rightshift */ 2, /* size (0 = byte, 1 = short, 2 = long) */ 16, /* bitsize */ FALSE, /* pc_relative */ 7, /* bitpos */ complain_overflow_signed,/* complain_on_overflow */ bfd_elf_generic_reloc, /* special_function */ "R_C6000_ABS_S16", /* name */ FALSE, /* partial_inplace */ 0, /* src_mask */ 0x007fff80, /* dst_mask */ FALSE), /* pcrel_offset */ HOWTO (R_C6000_ABS_L16, /* type */ 0, /* rightshift */ 2, /* size (0 = byte, 1 = short, 2 = long) */ 16, /* bitsize */ FALSE, /* pc_relative */ 7, /* bitpos */ complain_overflow_dont,/* complain_on_overflow */ bfd_elf_generic_reloc, /* special_function */ "R_C6000_ABS_L16", /* name */ FALSE, /* partial_inplace */ 0, /* src_mask */ 0x007fff80, /* dst_mask */ FALSE), /* pcrel_offset */ HOWTO (R_C6000_ABS_H16, /* type */ 16, /* rightshift */ 2, /* size (0 = byte, 1 = short, 2 = long) */ 16, /* bitsize */ FALSE, /* pc_relative */ 7, /* bitpos */ complain_overflow_dont,/* complain_on_overflow */ bfd_elf_generic_reloc, /* special_function */ "R_C6000_ABS_H16", /* name */ FALSE, /* partial_inplace */ 0, /* src_mask */ 0x007fff80, /* dst_mask */ FALSE), /* pcrel_offset */ HOWTO (R_C6000_SBR_U15_B, /* type */ 0, /* rightshift */ 2, /* size (0 = byte, 1 = short, 2 = long) */ 15, /* bitsize */ FALSE, /* pc_relative */ 8, /* bitpos */ complain_overflow_unsigned,/* complain_on_overflow */ bfd_elf_generic_reloc, /* special_function */ "R_C6000_SBR_U15_B", /* name */ FALSE, /* partial_inplace */ 0, /* src_mask */ 0x007fff00, /* dst_mask */ FALSE), /* pcrel_offset */ HOWTO (R_C6000_SBR_U15_H, /* type */ 1, /* rightshift */ 2, /* size (0 = byte, 1 = short, 2 = long) */ 15, /* bitsize */ FALSE, /* pc_relative */ 8, /* bitpos */ complain_overflow_unsigned,/* complain_on_overflow */ bfd_elf_generic_reloc, /* special_function */ "R_C6000_SBR_U15_H", /* name */ FALSE, /* partial_inplace */ 0, /* src_mask */ 0x007fff00, /* dst_mask */ FALSE), /* pcrel_offset */ HOWTO (R_C6000_SBR_U15_W, /* type */ 2, /* rightshift */ 2, /* size (0 = byte, 1 = short, 2 = long) */ 15, /* bitsize */ FALSE, /* pc_relative */ 8, /* bitpos */ complain_overflow_unsigned,/* complain_on_overflow */ bfd_elf_generic_reloc, /* special_function */ "R_C6000_SBR_U15_W", /* name */ FALSE, /* partial_inplace */ 0, /* src_mask */ 0x007fff00, /* dst_mask */ FALSE), /* pcrel_offset */ HOWTO (R_C6000_SBR_S16, /* type */ 0, /* rightshift */ 2, /* size (0 = byte, 1 = short, 2 = long) */ 16, /* bitsize */ FALSE, /* pc_relative */ 7, /* bitpos */ complain_overflow_signed,/* complain_on_overflow */ bfd_elf_generic_reloc, /* special_function */ "R_C6000_SBR_S16", /* name */ FALSE, /* partial_inplace */ 0, /* src_mask */ 0x007fff80, /* dst_mask */ FALSE), /* pcrel_offset */ HOWTO (R_C6000_SBR_L16_B, /* type */ 0, /* rightshift */ 2, /* size (0 = byte, 1 = short, 2 = long) */ 16, /* bitsize */ FALSE, /* pc_relative */ 7, /* bitpos */ complain_overflow_dont,/* complain_on_overflow */ bfd_elf_generic_reloc, /* special_function */ "R_C6000_SBR_L16_B", /* name */ FALSE, /* partial_inplace */ 0, /* src_mask */ 0x007fff80, /* dst_mask */ FALSE), /* pcrel_offset */ HOWTO (R_C6000_SBR_L16_H, /* type */ 1, /* rightshift */ 2, /* size (0 = byte, 1 = short, 2 = long) */ 16, /* bitsize */ FALSE, /* pc_relative */ 7, /* bitpos */ complain_overflow_dont,/* complain_on_overflow */ bfd_elf_generic_reloc, /* special_function */ "R_C6000_SBR_L16_H", /* name */ FALSE, /* partial_inplace */ 0, /* src_mask */ 0x007fff80, /* dst_mask */ FALSE), /* pcrel_offset */ HOWTO (R_C6000_SBR_L16_W, /* type */ 2, /* rightshift */ 2, /* size (0 = byte, 1 = short, 2 = long) */ 16, /* bitsize */ FALSE, /* pc_relative */ 7, /* bitpos */ complain_overflow_dont,/* complain_on_overflow */ bfd_elf_generic_reloc, /* special_function */ "R_C6000_SBR_L16_W", /* name */ FALSE, /* partial_inplace */ 0, /* src_mask */ 0x007fff80, /* dst_mask */ FALSE), /* pcrel_offset */ HOWTO (R_C6000_SBR_H16_B, /* type */ 16, /* rightshift */ 2, /* size (0 = byte, 1 = short, 2 = long) */ 16, /* bitsize */ FALSE, /* pc_relative */ 7, /* bitpos */ complain_overflow_dont,/* complain_on_overflow */ bfd_elf_generic_reloc, /* special_function */ "R_C6000_SBR_H16_B", /* name */ FALSE, /* partial_inplace */ 0, /* src_mask */ 0x007fff80, /* dst_mask */ FALSE), /* pcrel_offset */ HOWTO (R_C6000_SBR_H16_H, /* type */ 17, /* rightshift */ 2, /* size (0 = byte, 1 = short, 2 = long) */ 16, /* bitsize */ FALSE, /* pc_relative */ 7, /* bitpos */ complain_overflow_dont,/* complain_on_overflow */ bfd_elf_generic_reloc, /* special_function */ "R_C6000_SBR_H16_H", /* name */ FALSE, /* partial_inplace */ 0, /* src_mask */ 0x007fff80, /* dst_mask */ FALSE), /* pcrel_offset */ HOWTO (R_C6000_SBR_H16_W, /* type */ 18, /* rightshift */ 2, /* size (0 = byte, 1 = short, 2 = long) */ 16, /* bitsize */ FALSE, /* pc_relative */ 7, /* bitpos */ complain_overflow_dont,/* complain_on_overflow */ bfd_elf_generic_reloc, /* special_function */ "R_C6000_SBR_H16_W", /* name */ FALSE, /* partial_inplace */ 0, /* src_mask */ 0x007fff80, /* dst_mask */ FALSE), /* pcrel_offset */ HOWTO (R_C6000_SBR_GOT_U15_W, /* type */ 2, /* rightshift */ 2, /* size (0 = byte, 1 = short, 2 = long) */ 15, /* bitsize */ FALSE, /* pc_relative */ 8, /* bitpos */ complain_overflow_unsigned,/* complain_on_overflow */ bfd_elf_generic_reloc, /* special_function */ "R_C6000_SBR_GOT_U15_W",/* name */ FALSE, /* partial_inplace */ 0, /* src_mask */ 0x007fff00, /* dst_mask */ FALSE), /* pcrel_offset */ HOWTO (R_C6000_SBR_GOT_L16_W, /* type */ 2, /* rightshift */ 2, /* size (0 = byte, 1 = short, 2 = long) */ 16, /* bitsize */ FALSE, /* pc_relative */ 7, /* bitpos */ complain_overflow_dont,/* complain_on_overflow */ bfd_elf_generic_reloc, /* special_function */ "R_C6000_SBR_GOT_L16_W",/* name */ FALSE, /* partial_inplace */ 0, /* src_mask */ 0x007fff80, /* dst_mask */ FALSE), /* pcrel_offset */ HOWTO (R_C6000_SBR_GOT_H16_W, /* type */ 18, /* rightshift */ 2, /* size (0 = byte, 1 = short, 2 = long) */ 16, /* bitsize */ FALSE, /* pc_relative */ 7, /* bitpos */ complain_overflow_dont,/* complain_on_overflow */ bfd_elf_generic_reloc, /* special_function */ "R_C6000_SBR_GOT_H16_W",/* name */ FALSE, /* partial_inplace */ 0, /* src_mask */ 0x007fff80, /* dst_mask */ FALSE), /* pcrel_offset */ HOWTO (R_C6000_DSBT_INDEX, /* type */ 0, /* rightshift */ 2, /* size (0 = byte, 1 = short, 2 = long) */ 15, /* bitsize */ FALSE, /* pc_relative */ 8, /* bitpos */ complain_overflow_unsigned,/* complain_on_overflow */ bfd_elf_generic_reloc, /* special_function */ "R_C6000_DSBT_INDEX", /* name */ FALSE, /* partial_inplace */ 0, /* src_mask */ 0x007fff00, /* dst_mask */ FALSE), /* pcrel_offset */ HOWTO (R_C6000_PREL31, /* type */ 1, /* rightshift */ 2, /* size (0 = byte, 1 = short, 2 = long) */ 31, /* bitsize */ FALSE, /* pc_relative */ 0, /* bitpos */ complain_overflow_dont,/* complain_on_overflow */ bfd_elf_generic_reloc, /* special_function */ "R_C6000_PREL31", /* name */ FALSE, /* partial_inplace */ 0, /* src_mask */ 0x7fffffff, /* dst_mask */ FALSE), /* pcrel_offset */ HOWTO (R_C6000_COPY, /* type */ 0, /* rightshift */ 2, /* size (0 = byte, 1 = short, 2 = long) */ 32, /* bitsize */ FALSE, /* pc_relative */ 0, /* bitpos */ complain_overflow_dont,/* complain_on_overflow */ bfd_elf_generic_reloc, /* special_function */ "R_C6000_COPY", /* name */ FALSE, /* partial_inplace */ 0, /* src_mask */ 0xffffffff, /* dst_mask */ FALSE), /* pcrel_offset */ EMPTY_HOWTO (27), EMPTY_HOWTO (28), EMPTY_HOWTO (29), EMPTY_HOWTO (30), EMPTY_HOWTO (31), EMPTY_HOWTO (32), EMPTY_HOWTO (33), EMPTY_HOWTO (34), EMPTY_HOWTO (35), EMPTY_HOWTO (36), EMPTY_HOWTO (37), EMPTY_HOWTO (38), EMPTY_HOWTO (39), EMPTY_HOWTO (40), EMPTY_HOWTO (41), EMPTY_HOWTO (42), EMPTY_HOWTO (43), EMPTY_HOWTO (44), EMPTY_HOWTO (45), EMPTY_HOWTO (46), EMPTY_HOWTO (47), EMPTY_HOWTO (48), EMPTY_HOWTO (49), EMPTY_HOWTO (50), EMPTY_HOWTO (51), EMPTY_HOWTO (52), EMPTY_HOWTO (53), EMPTY_HOWTO (54), EMPTY_HOWTO (55), EMPTY_HOWTO (56), EMPTY_HOWTO (57), EMPTY_HOWTO (58), EMPTY_HOWTO (59), EMPTY_HOWTO (60), EMPTY_HOWTO (61), EMPTY_HOWTO (62), EMPTY_HOWTO (63), EMPTY_HOWTO (64), EMPTY_HOWTO (65), EMPTY_HOWTO (66), EMPTY_HOWTO (67), EMPTY_HOWTO (68), EMPTY_HOWTO (69), EMPTY_HOWTO (70), EMPTY_HOWTO (71), EMPTY_HOWTO (72), EMPTY_HOWTO (73), EMPTY_HOWTO (74), EMPTY_HOWTO (75), EMPTY_HOWTO (76), EMPTY_HOWTO (77), EMPTY_HOWTO (78), EMPTY_HOWTO (79), EMPTY_HOWTO (80), EMPTY_HOWTO (81), EMPTY_HOWTO (82), EMPTY_HOWTO (83), EMPTY_HOWTO (84), EMPTY_HOWTO (85), EMPTY_HOWTO (86), EMPTY_HOWTO (87), EMPTY_HOWTO (88), EMPTY_HOWTO (89), EMPTY_HOWTO (90), EMPTY_HOWTO (91), EMPTY_HOWTO (92), EMPTY_HOWTO (93), EMPTY_HOWTO (94), EMPTY_HOWTO (95), EMPTY_HOWTO (96), EMPTY_HOWTO (97), EMPTY_HOWTO (98), EMPTY_HOWTO (99), EMPTY_HOWTO (100), EMPTY_HOWTO (101), EMPTY_HOWTO (102), EMPTY_HOWTO (103), EMPTY_HOWTO (104), EMPTY_HOWTO (105), EMPTY_HOWTO (106), EMPTY_HOWTO (107), EMPTY_HOWTO (108), EMPTY_HOWTO (109), EMPTY_HOWTO (110), EMPTY_HOWTO (111), EMPTY_HOWTO (112), EMPTY_HOWTO (113), EMPTY_HOWTO (114), EMPTY_HOWTO (115), EMPTY_HOWTO (116), EMPTY_HOWTO (117), EMPTY_HOWTO (118), EMPTY_HOWTO (119), EMPTY_HOWTO (120), EMPTY_HOWTO (121), EMPTY_HOWTO (122), EMPTY_HOWTO (123), EMPTY_HOWTO (124), EMPTY_HOWTO (125), EMPTY_HOWTO (126), EMPTY_HOWTO (127), EMPTY_HOWTO (128), EMPTY_HOWTO (129), EMPTY_HOWTO (130), EMPTY_HOWTO (131), EMPTY_HOWTO (132), EMPTY_HOWTO (133), EMPTY_HOWTO (134), EMPTY_HOWTO (135), EMPTY_HOWTO (136), EMPTY_HOWTO (137), EMPTY_HOWTO (138), EMPTY_HOWTO (139), EMPTY_HOWTO (140), EMPTY_HOWTO (141), EMPTY_HOWTO (142), EMPTY_HOWTO (143), EMPTY_HOWTO (144), EMPTY_HOWTO (145), EMPTY_HOWTO (146), EMPTY_HOWTO (147), EMPTY_HOWTO (148), EMPTY_HOWTO (149), EMPTY_HOWTO (150), EMPTY_HOWTO (151), EMPTY_HOWTO (152), EMPTY_HOWTO (153), EMPTY_HOWTO (154), EMPTY_HOWTO (155), EMPTY_HOWTO (156), EMPTY_HOWTO (157), EMPTY_HOWTO (158), EMPTY_HOWTO (159), EMPTY_HOWTO (160), EMPTY_HOWTO (161), EMPTY_HOWTO (162), EMPTY_HOWTO (163), EMPTY_HOWTO (164), EMPTY_HOWTO (165), EMPTY_HOWTO (166), EMPTY_HOWTO (167), EMPTY_HOWTO (168), EMPTY_HOWTO (169), EMPTY_HOWTO (170), EMPTY_HOWTO (171), EMPTY_HOWTO (172), EMPTY_HOWTO (173), EMPTY_HOWTO (174), EMPTY_HOWTO (175), EMPTY_HOWTO (176), EMPTY_HOWTO (177), EMPTY_HOWTO (178), EMPTY_HOWTO (179), EMPTY_HOWTO (180), EMPTY_HOWTO (181), EMPTY_HOWTO (182), EMPTY_HOWTO (183), EMPTY_HOWTO (184), EMPTY_HOWTO (185), EMPTY_HOWTO (186), EMPTY_HOWTO (187), EMPTY_HOWTO (188), EMPTY_HOWTO (189), EMPTY_HOWTO (190), EMPTY_HOWTO (191), EMPTY_HOWTO (192), EMPTY_HOWTO (193), EMPTY_HOWTO (194), EMPTY_HOWTO (195), EMPTY_HOWTO (196), EMPTY_HOWTO (197), EMPTY_HOWTO (198), EMPTY_HOWTO (199), EMPTY_HOWTO (200), EMPTY_HOWTO (201), EMPTY_HOWTO (202), EMPTY_HOWTO (203), EMPTY_HOWTO (204), EMPTY_HOWTO (205), EMPTY_HOWTO (206), EMPTY_HOWTO (207), EMPTY_HOWTO (208), EMPTY_HOWTO (209), EMPTY_HOWTO (210), EMPTY_HOWTO (211), EMPTY_HOWTO (212), EMPTY_HOWTO (213), EMPTY_HOWTO (214), EMPTY_HOWTO (215), EMPTY_HOWTO (216), EMPTY_HOWTO (217), EMPTY_HOWTO (218), EMPTY_HOWTO (219), EMPTY_HOWTO (220), EMPTY_HOWTO (221), EMPTY_HOWTO (222), EMPTY_HOWTO (223), EMPTY_HOWTO (224), EMPTY_HOWTO (225), EMPTY_HOWTO (226), EMPTY_HOWTO (227), EMPTY_HOWTO (228), EMPTY_HOWTO (229), EMPTY_HOWTO (230), EMPTY_HOWTO (231), EMPTY_HOWTO (232), EMPTY_HOWTO (233), EMPTY_HOWTO (234), EMPTY_HOWTO (235), EMPTY_HOWTO (236), EMPTY_HOWTO (237), EMPTY_HOWTO (238), EMPTY_HOWTO (239), EMPTY_HOWTO (240), EMPTY_HOWTO (241), EMPTY_HOWTO (242), EMPTY_HOWTO (243), EMPTY_HOWTO (244), EMPTY_HOWTO (245), EMPTY_HOWTO (246), EMPTY_HOWTO (247), EMPTY_HOWTO (248), EMPTY_HOWTO (249), EMPTY_HOWTO (250), EMPTY_HOWTO (251), EMPTY_HOWTO (252), HOWTO (R_C6000_ALIGN, /* type */ 0, /* rightshift */ 0, /* size (0 = byte, 1 = short, 2 = long) */ 0, /* bitsize */ FALSE, /* pc_relative */ 0, /* bitpos */ complain_overflow_dont,/* complain_on_overflow */ bfd_elf_generic_reloc, /* special_function */ "R_C6000_ALIGN", /* name */ FALSE, /* partial_inplace */ 0, /* src_mask */ 0, /* dst_mask */ FALSE), /* pcrel_offset */ HOWTO (R_C6000_FPHEAD, /* type */ 0, /* rightshift */ 0, /* size (0 = byte, 1 = short, 2 = long) */ 0, /* bitsize */ FALSE, /* pc_relative */ 0, /* bitpos */ complain_overflow_dont,/* complain_on_overflow */ bfd_elf_generic_reloc, /* special_function */ "R_C6000_FPHEAD", /* name */ FALSE, /* partial_inplace */ 0, /* src_mask */ 0, /* dst_mask */ FALSE), /* pcrel_offset */ HOWTO (R_C6000_NOCMP, /* type */ 0, /* rightshift */ 0, /* size (0 = byte, 1 = short, 2 = long) */ 0, /* bitsize */ FALSE, /* pc_relative */ 0, /* bitpos */ complain_overflow_dont,/* complain_on_overflow */ bfd_elf_generic_reloc, /* special_function */ "R_C6000_NOCMP", /* name */ FALSE, /* partial_inplace */ 0, /* src_mask */ 0, /* dst_mask */ FALSE) /* pcrel_offset */ }; static reloc_howto_type elf32_tic6x_howto_table_rel[] = { HOWTO (R_C6000_NONE, /* type */ 0, /* rightshift */ 0, /* size (0 = byte, 1 = short, 2 = long) */ 0, /* bitsize */ FALSE, /* pc_relative */ 0, /* bitpos */ complain_overflow_dont,/* complain_on_overflow */ bfd_elf_generic_reloc, /* special_function */ "R_C6000_NONE", /* name */ TRUE, /* partial_inplace */ 0, /* src_mask */ 0, /* dst_mask */ FALSE), /* pcrel_offset */ HOWTO (R_C6000_ABS32, /* type */ 0, /* rightshift */ 2, /* size (0 = byte, 1 = short, 2 = long) */ 32, /* bitsize */ FALSE, /* pc_relative */ 0, /* bitpos */ complain_overflow_dont,/* complain_on_overflow */ bfd_elf_generic_reloc, /* special_function */ "R_C6000_ABS32", /* name */ TRUE, /* partial_inplace */ 0xffffffff, /* src_mask */ 0xffffffff, /* dst_mask */ FALSE), /* pcrel_offset */ HOWTO (R_C6000_ABS16, /* type */ 0, /* rightshift */ 1, /* size (0 = byte, 1 = short, 2 = long) */ 16, /* bitsize */ FALSE, /* pc_relative */ 0, /* bitpos */ complain_overflow_bitfield,/* complain_on_overflow */ bfd_elf_generic_reloc, /* special_function */ "R_C6000_ABS16", /* name */ TRUE, /* partial_inplace */ 0x0000ffff, /* src_mask */ 0x0000ffff, /* dst_mask */ FALSE), /* pcrel_offset */ HOWTO (R_C6000_ABS8, /* type */ 0, /* rightshift */ 0, /* size (0 = byte, 1 = short, 2 = long) */ 8, /* bitsize */ FALSE, /* pc_relative */ 0, /* bitpos */ complain_overflow_bitfield,/* complain_on_overflow */ bfd_elf_generic_reloc, /* special_function */ "R_C6000_ABS8", /* name */ TRUE, /* partial_inplace */ 0x000000ff, /* src_mask */ 0x000000ff, /* dst_mask */ FALSE), /* pcrel_offset */ HOWTO (R_C6000_PCR_S21, /* type */ 2, /* rightshift */ 2, /* size (0 = byte, 1 = short, 2 = long) */ 21, /* bitsize */ TRUE, /* pc_relative */ 7, /* bitpos */ complain_overflow_signed,/* complain_on_overflow */ bfd_elf_generic_reloc, /* special_function */ "R_C6000_PCR_S21", /* name */ TRUE, /* partial_inplace */ 0x0fffff80, /* src_mask */ 0x0fffff80, /* dst_mask */ TRUE), /* pcrel_offset */ HOWTO (R_C6000_PCR_S12, /* type */ 2, /* rightshift */ 2, /* size (0 = byte, 1 = short, 2 = long) */ 12, /* bitsize */ TRUE, /* pc_relative */ 16, /* bitpos */ complain_overflow_signed,/* complain_on_overflow */ bfd_elf_generic_reloc, /* special_function */ "R_C6000_PCR_S12", /* name */ TRUE, /* partial_inplace */ 0x0fff0000, /* src_mask */ 0x0fff0000, /* dst_mask */ TRUE), /* pcrel_offset */ HOWTO (R_C6000_PCR_S10, /* type */ 2, /* rightshift */ 2, /* size (0 = byte, 1 = short, 2 = long) */ 10, /* bitsize */ TRUE, /* pc_relative */ 13, /* bitpos */ complain_overflow_signed,/* complain_on_overflow */ bfd_elf_generic_reloc, /* special_function */ "R_C6000_PCR_S10", /* name */ TRUE, /* partial_inplace */ 0x007fe000, /* src_mask */ 0x007fe000, /* dst_mask */ TRUE), /* pcrel_offset */ HOWTO (R_C6000_PCR_S7, /* type */ 2, /* rightshift */ 2, /* size (0 = byte, 1 = short, 2 = long) */ 7, /* bitsize */ TRUE, /* pc_relative */ 16, /* bitpos */ complain_overflow_signed,/* complain_on_overflow */ bfd_elf_generic_reloc, /* special_function */ "R_C6000_PCR_S7", /* name */ TRUE, /* partial_inplace */ 0x007f0000, /* src_mask */ 0x007f0000, /* dst_mask */ TRUE), /* pcrel_offset */ HOWTO (R_C6000_ABS_S16, /* type */ 0, /* rightshift */ 2, /* size (0 = byte, 1 = short, 2 = long) */ 16, /* bitsize */ FALSE, /* pc_relative */ 7, /* bitpos */ complain_overflow_signed,/* complain_on_overflow */ bfd_elf_generic_reloc, /* special_function */ "R_C6000_ABS_S16", /* name */ TRUE, /* partial_inplace */ 0x007fff80, /* src_mask */ 0x007fff80, /* dst_mask */ FALSE), /* pcrel_offset */ HOWTO (R_C6000_ABS_L16, /* type */ 0, /* rightshift */ 2, /* size (0 = byte, 1 = short, 2 = long) */ 16, /* bitsize */ FALSE, /* pc_relative */ 7, /* bitpos */ complain_overflow_dont,/* complain_on_overflow */ bfd_elf_generic_reloc, /* special_function */ "R_C6000_ABS_L16", /* name */ TRUE, /* partial_inplace */ 0x007fff80, /* src_mask */ 0x007fff80, /* dst_mask */ FALSE), /* pcrel_offset */ EMPTY_HOWTO (R_C6000_ABS_H16), HOWTO (R_C6000_SBR_U15_B, /* type */ 0, /* rightshift */ 2, /* size (0 = byte, 1 = short, 2 = long) */ 15, /* bitsize */ FALSE, /* pc_relative */ 8, /* bitpos */ complain_overflow_unsigned,/* complain_on_overflow */ bfd_elf_generic_reloc, /* special_function */ "R_C6000_SBR_U15_B", /* name */ TRUE, /* partial_inplace */ 0x007fff00, /* src_mask */ 0x007fff00, /* dst_mask */ FALSE), /* pcrel_offset */ HOWTO (R_C6000_SBR_U15_H, /* type */ 1, /* rightshift */ 2, /* size (0 = byte, 1 = short, 2 = long) */ 15, /* bitsize */ FALSE, /* pc_relative */ 8, /* bitpos */ complain_overflow_unsigned,/* complain_on_overflow */ bfd_elf_generic_reloc, /* special_function */ "R_C6000_SBR_U15_H", /* name */ TRUE, /* partial_inplace */ 0x007fff00, /* src_mask */ 0x007fff00, /* dst_mask */ FALSE), /* pcrel_offset */ HOWTO (R_C6000_SBR_U15_W, /* type */ 2, /* rightshift */ 2, /* size (0 = byte, 1 = short, 2 = long) */ 15, /* bitsize */ FALSE, /* pc_relative */ 8, /* bitpos */ complain_overflow_unsigned,/* complain_on_overflow */ bfd_elf_generic_reloc, /* special_function */ "R_C6000_SBR_U15_W", /* name */ TRUE, /* partial_inplace */ 0x007fff00, /* src_mask */ 0x007fff00, /* dst_mask */ FALSE), /* pcrel_offset */ HOWTO (R_C6000_SBR_S16, /* type */ 0, /* rightshift */ 2, /* size (0 = byte, 1 = short, 2 = long) */ 16, /* bitsize */ FALSE, /* pc_relative */ 7, /* bitpos */ complain_overflow_signed,/* complain_on_overflow */ bfd_elf_generic_reloc, /* special_function */ "R_C6000_SBR_S16", /* name */ TRUE, /* partial_inplace */ 0x007fff80, /* src_mask */ 0x007fff80, /* dst_mask */ FALSE), /* pcrel_offset */ HOWTO (R_C6000_SBR_L16_B, /* type */ 0, /* rightshift */ 2, /* size (0 = byte, 1 = short, 2 = long) */ 16, /* bitsize */ FALSE, /* pc_relative */ 7, /* bitpos */ complain_overflow_dont,/* complain_on_overflow */ bfd_elf_generic_reloc, /* special_function */ "R_C6000_SBR_L16_B", /* name */ TRUE, /* partial_inplace */ 0x007fff80, /* src_mask */ 0x007fff80, /* dst_mask */ FALSE), /* pcrel_offset */ HOWTO (R_C6000_SBR_L16_H, /* type */ 1, /* rightshift */ 2, /* size (0 = byte, 1 = short, 2 = long) */ 16, /* bitsize */ FALSE, /* pc_relative */ 7, /* bitpos */ complain_overflow_dont,/* complain_on_overflow */ bfd_elf_generic_reloc, /* special_function */ "R_C6000_SBR_L16_H", /* name */ TRUE, /* partial_inplace */ 0x007fff80, /* src_mask */ 0x007fff80, /* dst_mask */ FALSE), /* pcrel_offset */ HOWTO (R_C6000_SBR_L16_W, /* type */ 2, /* rightshift */ 2, /* size (0 = byte, 1 = short, 2 = long) */ 16, /* bitsize */ FALSE, /* pc_relative */ 7, /* bitpos */ complain_overflow_dont,/* complain_on_overflow */ bfd_elf_generic_reloc, /* special_function */ "R_C6000_SBR_L16_W", /* name */ TRUE, /* partial_inplace */ 0x007fff80, /* src_mask */ 0x007fff80, /* dst_mask */ FALSE), /* pcrel_offset */ EMPTY_HOWTO (R_C6000_SBR_H16_B), EMPTY_HOWTO (R_C6000_SBR_H16_H), EMPTY_HOWTO (R_C6000_SBR_H16_W), HOWTO (R_C6000_SBR_GOT_U15_W, /* type */ 2, /* rightshift */ 2, /* size (0 = byte, 1 = short, 2 = long) */ 15, /* bitsize */ FALSE, /* pc_relative */ 8, /* bitpos */ complain_overflow_unsigned,/* complain_on_overflow */ bfd_elf_generic_reloc, /* special_function */ "R_C6000_SBR_GOT_U15_W",/* name */ TRUE, /* partial_inplace */ 0x007fff00, /* src_mask */ 0x007fff00, /* dst_mask */ FALSE), /* pcrel_offset */ HOWTO (R_C6000_SBR_GOT_L16_W, /* type */ 2, /* rightshift */ 2, /* size (0 = byte, 1 = short, 2 = long) */ 16, /* bitsize */ FALSE, /* pc_relative */ 7, /* bitpos */ complain_overflow_dont,/* complain_on_overflow */ bfd_elf_generic_reloc, /* special_function */ "R_C6000_SBR_GOT_L16_W",/* name */ TRUE, /* partial_inplace */ 0x007fff80, /* src_mask */ 0x007fff80, /* dst_mask */ FALSE), /* pcrel_offset */ EMPTY_HOWTO (R_C6000_SBR_GOT_H16_W), HOWTO (R_C6000_DSBT_INDEX, /* type */ 0, /* rightshift */ 2, /* size (0 = byte, 1 = short, 2 = long) */ 15, /* bitsize */ FALSE, /* pc_relative */ 8, /* bitpos */ complain_overflow_unsigned,/* complain_on_overflow */ bfd_elf_generic_reloc, /* special_function */ "R_C6000_DSBT_INDEX", /* name */ TRUE, /* partial_inplace */ 0, /* src_mask */ 0x007fff00, /* dst_mask */ FALSE), /* pcrel_offset */ HOWTO (R_C6000_PREL31, /* type */ 1, /* rightshift */ 2, /* size (0 = byte, 1 = short, 2 = long) */ 31, /* bitsize */ FALSE, /* pc_relative */ 0, /* bitpos */ complain_overflow_dont,/* complain_on_overflow */ bfd_elf_generic_reloc, /* special_function */ "R_C6000_PREL31", /* name */ TRUE, /* partial_inplace */ 0, /* src_mask */ 0x7fffffff, /* dst_mask */ FALSE), /* pcrel_offset */ HOWTO (R_C6000_COPY, /* type */ 0, /* rightshift */ 2, /* size (0 = byte, 1 = short, 2 = long) */ 32, /* bitsize */ FALSE, /* pc_relative */ 0, /* bitpos */ complain_overflow_dont,/* complain_on_overflow */ bfd_elf_generic_reloc, /* special_function */ "R_C6000_COPY", /* name */ TRUE, /* partial_inplace */ 0, /* src_mask */ 0xffffffff, /* dst_mask */ FALSE), /* pcrel_offset */ EMPTY_HOWTO (27), EMPTY_HOWTO (28), EMPTY_HOWTO (29), EMPTY_HOWTO (30), EMPTY_HOWTO (31), EMPTY_HOWTO (32), EMPTY_HOWTO (33), EMPTY_HOWTO (34), EMPTY_HOWTO (35), EMPTY_HOWTO (36), EMPTY_HOWTO (37), EMPTY_HOWTO (38), EMPTY_HOWTO (39), EMPTY_HOWTO (40), EMPTY_HOWTO (41), EMPTY_HOWTO (42), EMPTY_HOWTO (43), EMPTY_HOWTO (44), EMPTY_HOWTO (45), EMPTY_HOWTO (46), EMPTY_HOWTO (47), EMPTY_HOWTO (48), EMPTY_HOWTO (49), EMPTY_HOWTO (50), EMPTY_HOWTO (51), EMPTY_HOWTO (52), EMPTY_HOWTO (53), EMPTY_HOWTO (54), EMPTY_HOWTO (55), EMPTY_HOWTO (56), EMPTY_HOWTO (57), EMPTY_HOWTO (58), EMPTY_HOWTO (59), EMPTY_HOWTO (60), EMPTY_HOWTO (61), EMPTY_HOWTO (62), EMPTY_HOWTO (63), EMPTY_HOWTO (64), EMPTY_HOWTO (65), EMPTY_HOWTO (66), EMPTY_HOWTO (67), EMPTY_HOWTO (68), EMPTY_HOWTO (69), EMPTY_HOWTO (70), EMPTY_HOWTO (71), EMPTY_HOWTO (72), EMPTY_HOWTO (73), EMPTY_HOWTO (74), EMPTY_HOWTO (75), EMPTY_HOWTO (76), EMPTY_HOWTO (77), EMPTY_HOWTO (78), EMPTY_HOWTO (79), EMPTY_HOWTO (80), EMPTY_HOWTO (81), EMPTY_HOWTO (82), EMPTY_HOWTO (83), EMPTY_HOWTO (84), EMPTY_HOWTO (85), EMPTY_HOWTO (86), EMPTY_HOWTO (87), EMPTY_HOWTO (88), EMPTY_HOWTO (89), EMPTY_HOWTO (90), EMPTY_HOWTO (91), EMPTY_HOWTO (92), EMPTY_HOWTO (93), EMPTY_HOWTO (94), EMPTY_HOWTO (95), EMPTY_HOWTO (96), EMPTY_HOWTO (97), EMPTY_HOWTO (98), EMPTY_HOWTO (99), EMPTY_HOWTO (100), EMPTY_HOWTO (101), EMPTY_HOWTO (102), EMPTY_HOWTO (103), EMPTY_HOWTO (104), EMPTY_HOWTO (105), EMPTY_HOWTO (106), EMPTY_HOWTO (107), EMPTY_HOWTO (108), EMPTY_HOWTO (109), EMPTY_HOWTO (110), EMPTY_HOWTO (111), EMPTY_HOWTO (112), EMPTY_HOWTO (113), EMPTY_HOWTO (114), EMPTY_HOWTO (115), EMPTY_HOWTO (116), EMPTY_HOWTO (117), EMPTY_HOWTO (118), EMPTY_HOWTO (119), EMPTY_HOWTO (120), EMPTY_HOWTO (121), EMPTY_HOWTO (122), EMPTY_HOWTO (123), EMPTY_HOWTO (124), EMPTY_HOWTO (125), EMPTY_HOWTO (126), EMPTY_HOWTO (127), EMPTY_HOWTO (128), EMPTY_HOWTO (129), EMPTY_HOWTO (130), EMPTY_HOWTO (131), EMPTY_HOWTO (132), EMPTY_HOWTO (133), EMPTY_HOWTO (134), EMPTY_HOWTO (135), EMPTY_HOWTO (136), EMPTY_HOWTO (137), EMPTY_HOWTO (138), EMPTY_HOWTO (139), EMPTY_HOWTO (140), EMPTY_HOWTO (141), EMPTY_HOWTO (142), EMPTY_HOWTO (143), EMPTY_HOWTO (144), EMPTY_HOWTO (145), EMPTY_HOWTO (146), EMPTY_HOWTO (147), EMPTY_HOWTO (148), EMPTY_HOWTO (149), EMPTY_HOWTO (150), EMPTY_HOWTO (151), EMPTY_HOWTO (152), EMPTY_HOWTO (153), EMPTY_HOWTO (154), EMPTY_HOWTO (155), EMPTY_HOWTO (156), EMPTY_HOWTO (157), EMPTY_HOWTO (158), EMPTY_HOWTO (159), EMPTY_HOWTO (160), EMPTY_HOWTO (161), EMPTY_HOWTO (162), EMPTY_HOWTO (163), EMPTY_HOWTO (164), EMPTY_HOWTO (165), EMPTY_HOWTO (166), EMPTY_HOWTO (167), EMPTY_HOWTO (168), EMPTY_HOWTO (169), EMPTY_HOWTO (170), EMPTY_HOWTO (171), EMPTY_HOWTO (172), EMPTY_HOWTO (173), EMPTY_HOWTO (174), EMPTY_HOWTO (175), EMPTY_HOWTO (176), EMPTY_HOWTO (177), EMPTY_HOWTO (178), EMPTY_HOWTO (179), EMPTY_HOWTO (180), EMPTY_HOWTO (181), EMPTY_HOWTO (182), EMPTY_HOWTO (183), EMPTY_HOWTO (184), EMPTY_HOWTO (185), EMPTY_HOWTO (186), EMPTY_HOWTO (187), EMPTY_HOWTO (188), EMPTY_HOWTO (189), EMPTY_HOWTO (190), EMPTY_HOWTO (191), EMPTY_HOWTO (192), EMPTY_HOWTO (193), EMPTY_HOWTO (194), EMPTY_HOWTO (195), EMPTY_HOWTO (196), EMPTY_HOWTO (197), EMPTY_HOWTO (198), EMPTY_HOWTO (199), EMPTY_HOWTO (200), EMPTY_HOWTO (201), EMPTY_HOWTO (202), EMPTY_HOWTO (203), EMPTY_HOWTO (204), EMPTY_HOWTO (205), EMPTY_HOWTO (206), EMPTY_HOWTO (207), EMPTY_HOWTO (208), EMPTY_HOWTO (209), EMPTY_HOWTO (210), EMPTY_HOWTO (211), EMPTY_HOWTO (212), EMPTY_HOWTO (213), EMPTY_HOWTO (214), EMPTY_HOWTO (215), EMPTY_HOWTO (216), EMPTY_HOWTO (217), EMPTY_HOWTO (218), EMPTY_HOWTO (219), EMPTY_HOWTO (220), EMPTY_HOWTO (221), EMPTY_HOWTO (222), EMPTY_HOWTO (223), EMPTY_HOWTO (224), EMPTY_HOWTO (225), EMPTY_HOWTO (226), EMPTY_HOWTO (227), EMPTY_HOWTO (228), EMPTY_HOWTO (229), EMPTY_HOWTO (230), EMPTY_HOWTO (231), EMPTY_HOWTO (232), EMPTY_HOWTO (233), EMPTY_HOWTO (234), EMPTY_HOWTO (235), EMPTY_HOWTO (236), EMPTY_HOWTO (237), EMPTY_HOWTO (238), EMPTY_HOWTO (239), EMPTY_HOWTO (240), EMPTY_HOWTO (241), EMPTY_HOWTO (242), EMPTY_HOWTO (243), EMPTY_HOWTO (244), EMPTY_HOWTO (245), EMPTY_HOWTO (246), EMPTY_HOWTO (247), EMPTY_HOWTO (248), EMPTY_HOWTO (249), EMPTY_HOWTO (250), EMPTY_HOWTO (251), EMPTY_HOWTO (252), HOWTO (R_C6000_ALIGN, /* type */ 0, /* rightshift */ 0, /* size (0 = byte, 1 = short, 2 = long) */ 0, /* bitsize */ FALSE, /* pc_relative */ 0, /* bitpos */ complain_overflow_dont,/* complain_on_overflow */ bfd_elf_generic_reloc, /* special_function */ "R_C6000_ALIGN", /* name */ TRUE, /* partial_inplace */ 0, /* src_mask */ 0, /* dst_mask */ FALSE), /* pcrel_offset */ HOWTO (R_C6000_FPHEAD, /* type */ 0, /* rightshift */ 0, /* size (0 = byte, 1 = short, 2 = long) */ 0, /* bitsize */ FALSE, /* pc_relative */ 0, /* bitpos */ complain_overflow_dont,/* complain_on_overflow */ bfd_elf_generic_reloc, /* special_function */ "R_C6000_FPHEAD", /* name */ TRUE, /* partial_inplace */ 0, /* src_mask */ 0, /* dst_mask */ FALSE), /* pcrel_offset */ HOWTO (R_C6000_NOCMP, /* type */ 0, /* rightshift */ 0, /* size (0 = byte, 1 = short, 2 = long) */ 0, /* bitsize */ FALSE, /* pc_relative */ 0, /* bitpos */ complain_overflow_dont,/* complain_on_overflow */ bfd_elf_generic_reloc, /* special_function */ "R_C6000_NOCMP", /* name */ TRUE, /* partial_inplace */ 0, /* src_mask */ 0, /* dst_mask */ FALSE) /* pcrel_offset */ }; /* Map BFD relocations to ELF relocations. */ typedef struct { bfd_reloc_code_real_type bfd_reloc_val; enum elf_tic6x_reloc_type elf_reloc_val; } tic6x_reloc_map; static const tic6x_reloc_map elf32_tic6x_reloc_map[] = { { BFD_RELOC_NONE, R_C6000_NONE }, { BFD_RELOC_32, R_C6000_ABS32 }, { BFD_RELOC_16, R_C6000_ABS16 }, { BFD_RELOC_8, R_C6000_ABS8 }, { BFD_RELOC_C6000_PCR_S21, R_C6000_PCR_S21 }, { BFD_RELOC_C6000_PCR_S12, R_C6000_PCR_S12 }, { BFD_RELOC_C6000_PCR_S10, R_C6000_PCR_S10 }, { BFD_RELOC_C6000_PCR_S7, R_C6000_PCR_S7 }, { BFD_RELOC_C6000_ABS_S16, R_C6000_ABS_S16 }, { BFD_RELOC_C6000_ABS_L16, R_C6000_ABS_L16 }, { BFD_RELOC_C6000_ABS_H16, R_C6000_ABS_H16 }, { BFD_RELOC_C6000_SBR_U15_B, R_C6000_SBR_U15_B }, { BFD_RELOC_C6000_SBR_U15_H, R_C6000_SBR_U15_H }, { BFD_RELOC_C6000_SBR_U15_W, R_C6000_SBR_U15_W }, { BFD_RELOC_C6000_SBR_S16, R_C6000_SBR_S16 }, { BFD_RELOC_C6000_SBR_L16_B, R_C6000_SBR_L16_B }, { BFD_RELOC_C6000_SBR_L16_H, R_C6000_SBR_L16_H }, { BFD_RELOC_C6000_SBR_L16_W, R_C6000_SBR_L16_W }, { BFD_RELOC_C6000_SBR_H16_B, R_C6000_SBR_H16_B }, { BFD_RELOC_C6000_SBR_H16_H, R_C6000_SBR_H16_H }, { BFD_RELOC_C6000_SBR_H16_W, R_C6000_SBR_H16_W }, { BFD_RELOC_C6000_SBR_GOT_U15_W, R_C6000_SBR_GOT_U15_W }, { BFD_RELOC_C6000_SBR_GOT_L16_W, R_C6000_SBR_GOT_L16_W }, { BFD_RELOC_C6000_SBR_GOT_H16_W, R_C6000_SBR_GOT_H16_W }, { BFD_RELOC_C6000_DSBT_INDEX, R_C6000_DSBT_INDEX }, { BFD_RELOC_C6000_PREL31, R_C6000_PREL31 }, { BFD_RELOC_C6000_COPY, R_C6000_COPY }, { BFD_RELOC_C6000_ALIGN, R_C6000_ALIGN }, { BFD_RELOC_C6000_FPHEAD, R_C6000_FPHEAD }, { BFD_RELOC_C6000_NOCMP, R_C6000_NOCMP } }; static reloc_howto_type * elf32_tic6x_reloc_type_lookup (bfd *abfd, bfd_reloc_code_real_type code) { unsigned int i; for (i = 0; i < ARRAY_SIZE (elf32_tic6x_reloc_map); i++) if (elf32_tic6x_reloc_map[i].bfd_reloc_val == code) { enum elf_tic6x_reloc_type elf_reloc_val; reloc_howto_type *howto; elf_reloc_val = elf32_tic6x_reloc_map[i].elf_reloc_val; if (elf32_tic6x_tdata (abfd)->use_rela_p) howto = &elf32_tic6x_howto_table[elf_reloc_val]; else howto = &elf32_tic6x_howto_table_rel[elf_reloc_val]; /* Some relocations are RELA-only; do not return them for REL. */ if (howto->name == NULL) howto = NULL; return howto; } return NULL; } static reloc_howto_type * elf32_tic6x_reloc_name_lookup (bfd *abfd, const char *r_name) { if (elf32_tic6x_tdata (abfd)->use_rela_p) { unsigned int i; for (i = 0; i < ARRAY_SIZE (elf32_tic6x_howto_table); i++) if (elf32_tic6x_howto_table[i].name != NULL && strcasecmp (elf32_tic6x_howto_table[i].name, r_name) == 0) return &elf32_tic6x_howto_table[i]; } else { unsigned int i; for (i = 0; i < ARRAY_SIZE (elf32_tic6x_howto_table_rel); i++) if (elf32_tic6x_howto_table_rel[i].name != NULL && strcasecmp (elf32_tic6x_howto_table_rel[i].name, r_name) == 0) return &elf32_tic6x_howto_table_rel[i]; } return NULL; } static void elf32_tic6x_info_to_howto (bfd *abfd ATTRIBUTE_UNUSED, arelent *bfd_reloc, Elf_Internal_Rela *elf_reloc) { unsigned int r_type; r_type = ELF32_R_TYPE (elf_reloc->r_info); if (r_type >= ARRAY_SIZE (elf32_tic6x_howto_table)) bfd_reloc->howto = NULL; else bfd_reloc->howto = &elf32_tic6x_howto_table[r_type]; } static void elf32_tic6x_info_to_howto_rel (bfd *abfd ATTRIBUTE_UNUSED, arelent *bfd_reloc, Elf_Internal_Rela *elf_reloc) { unsigned int r_type; r_type = ELF32_R_TYPE (elf_reloc->r_info); if (r_type >= ARRAY_SIZE (elf32_tic6x_howto_table_rel)) bfd_reloc->howto = NULL; else bfd_reloc->howto = &elf32_tic6x_howto_table_rel[r_type]; } void elf32_tic6x_set_use_rela_p (bfd *abfd, bfd_boolean use_rela_p) { elf32_tic6x_tdata (abfd)->use_rela_p = use_rela_p; } static bfd_boolean elf32_tic6x_mkobject (bfd *abfd) { bfd_boolean ret; ret = bfd_elf_allocate_object (abfd, sizeof (struct elf32_tic6x_obj_tdata), TIC6X_ELF_DATA); if (ret) elf32_tic6x_set_use_rela_p (abfd, TRUE); return ret; } static bfd_boolean elf32_tic6x_new_section_hook (bfd *abfd, asection *sec) { bfd_boolean ret; ret = _bfd_elf_new_section_hook (abfd, sec); sec->use_rela_p = elf32_tic6x_tdata (abfd)->use_rela_p; return ret; } /* Return true if relocation REL against section SEC is a REL rather than RELA relocation. RELOCS is the first relocation in the section and ABFD is the bfd that contains SEC. */ static bfd_boolean elf32_tic6x_rel_relocation_p (bfd *abfd, asection *sec, const Elf_Internal_Rela *relocs, const Elf_Internal_Rela *rel) { Elf_Internal_Shdr *rel_hdr; const struct elf_backend_data *bed; /* To determine which flavor of relocation this is, we depend on the fact that the INPUT_SECTION's REL_HDR is read before RELA_HDR. */ rel_hdr = elf_section_data (sec)->rel.hdr; if (rel_hdr == NULL) return FALSE; bed = get_elf_backend_data (abfd); return ((size_t) (rel - relocs) < NUM_SHDR_ENTRIES (rel_hdr) * bed->s->int_rels_per_ext_rel); } static bfd_boolean elf32_tic6x_relocate_section (bfd *output_bfd, struct bfd_link_info *info, bfd *input_bfd, asection *input_section, bfd_byte *contents, Elf_Internal_Rela *relocs, Elf_Internal_Sym *local_syms, asection **local_sections) { Elf_Internal_Shdr *symtab_hdr; struct elf_link_hash_entry **sym_hashes; Elf_Internal_Rela *rel; Elf_Internal_Rela *relend; bfd_boolean ok = TRUE; symtab_hdr = & elf_symtab_hdr (input_bfd); sym_hashes = elf_sym_hashes (input_bfd); relend = relocs + input_section->reloc_count; for (rel = relocs; rel < relend; rel ++) { int r_type; unsigned long r_symndx; arelent bfd_reloc; reloc_howto_type *howto; Elf_Internal_Sym *sym; asection *sec; struct elf_link_hash_entry *h; bfd_vma relocation; bfd_boolean unresolved_reloc; bfd_reloc_status_type r; struct bfd_link_hash_entry *sbh; bfd_boolean is_rel; r_type = ELF32_R_TYPE (rel->r_info); r_symndx = ELF32_R_SYM (rel->r_info); is_rel = elf32_tic6x_rel_relocation_p (input_bfd, input_section, relocs, rel); if (is_rel) elf32_tic6x_info_to_howto_rel (input_bfd, &bfd_reloc, rel); else elf32_tic6x_info_to_howto (input_bfd, &bfd_reloc, rel); howto = bfd_reloc.howto; if (howto == NULL) { bfd_set_error (bfd_error_bad_value); return FALSE; } h = NULL; sym = NULL; sec = NULL; unresolved_reloc = FALSE; if (r_symndx < symtab_hdr->sh_info) { sym = local_syms + r_symndx; sec = local_sections[r_symndx]; relocation = _bfd_elf_rela_local_sym (output_bfd, sym, &sec, rel); } else { bfd_boolean warned; RELOC_FOR_GLOBAL_SYMBOL (info, input_bfd, input_section, rel, r_symndx, symtab_hdr, sym_hashes, h, sec, relocation, unresolved_reloc, warned); } if (sec != NULL && elf_discarded_section (sec)) RELOC_AGAINST_DISCARDED_SECTION (info, input_bfd, input_section, rel, relend, howto, contents); if (info->relocatable) { if (is_rel && sym != NULL && ELF_ST_TYPE (sym->st_info) == STT_SECTION) { rel->r_addend = 0; relocation = sec->output_offset + sym->st_value; r = _bfd_relocate_contents (howto, input_bfd, relocation, contents + rel->r_offset); goto done_reloc; } continue; } switch (r_type) { case R_C6000_NONE: case R_C6000_ALIGN: case R_C6000_FPHEAD: case R_C6000_NOCMP: /* No action needed. */ continue; case R_C6000_PCR_S21: case R_C6000_PCR_S12: case R_C6000_PCR_S10: case R_C6000_PCR_S7: /* Generic PC-relative handling produces a value relative to the exact location of the relocation. Adjust it to be relative to the start of the fetch packet instead. */ relocation += (input_section->output_section->vma + input_section->output_offset + rel->r_offset) & 0x1f; /* Fall through. */ case R_C6000_ABS32: case R_C6000_ABS16: case R_C6000_ABS8: case R_C6000_ABS_S16: case R_C6000_ABS_L16: case R_C6000_ABS_H16: /* Generic logic OK. */ break; case R_C6000_SBR_U15_B: case R_C6000_SBR_U15_H: case R_C6000_SBR_U15_W: case R_C6000_SBR_S16: case R_C6000_SBR_L16_B: case R_C6000_SBR_L16_H: case R_C6000_SBR_L16_W: case R_C6000_SBR_H16_B: case R_C6000_SBR_H16_H: case R_C6000_SBR_H16_W: sbh = bfd_link_hash_lookup (info->hash, "__c6xabi_DSBT_BASE", FALSE, FALSE, TRUE); if (sbh != NULL && (sbh->type == bfd_link_hash_defined || sbh->type == bfd_link_hash_defweak)) relocation -= (sbh->u.def.value + sbh->u.def.section->output_section->vma + sbh->u.def.section->output_offset); else { (*_bfd_error_handler) (_("%B: SB-relative relocation but " "__c6xabi_DSBT_BASE not defined"), input_bfd); ok = FALSE; continue; } break; case R_C6000_SBR_GOT_U15_W: case R_C6000_SBR_GOT_L16_W: case R_C6000_SBR_GOT_H16_W: case R_C6000_DSBT_INDEX: case R_C6000_PREL31: /* Shared libraries and exception handling support not implemented. */ (*_bfd_error_handler) (_("%B: relocation type %d not implemented"), input_bfd, r_type); ok = FALSE; continue; case R_C6000_COPY: /* Invalid in relocatable object. */ default: /* Unknown relocation. */ (*_bfd_error_handler) (_("%B: invalid relocation type %d"), input_bfd, r_type); ok = FALSE; continue; } r = _bfd_final_link_relocate (howto, input_bfd, input_section, contents, rel->r_offset, relocation, rel->r_addend); done_reloc: if (r == bfd_reloc_ok && howto->complain_on_overflow == complain_overflow_bitfield) { /* Generic overflow handling accepts cases the ABI says should be rejected for R_C6000_ABS16 and R_C6000_ABS8. */ bfd_vma value = (relocation + rel->r_addend) & 0xffffffff; bfd_vma sbit = 1 << (howto->bitsize - 1); bfd_vma sbits = (-(bfd_vma) sbit) & 0xffffffff; bfd_vma value_sbits = value & sbits; if (value_sbits != 0 && value_sbits != sbit && value_sbits != sbits) r = bfd_reloc_overflow; } if (r != bfd_reloc_ok) { const char *name; const char *error_message; if (h != NULL) name = h->root.root.string; else { name = bfd_elf_string_from_elf_section (input_bfd, symtab_hdr->sh_link, sym->st_name); if (name == NULL) return FALSE; if (*name == '\0') name = bfd_section_name (input_bfd, sec); } switch (r) { case bfd_reloc_overflow: /* If the overflowing reloc was to an undefined symbol, we have already printed one error message and there is no point complaining again. */ if ((! h || h->root.type != bfd_link_hash_undefined) && (!((*info->callbacks->reloc_overflow) (info, (h ? &h->root : NULL), name, howto->name, (bfd_vma) 0, input_bfd, input_section, rel->r_offset)))) return FALSE; break; case bfd_reloc_undefined: if (!((*info->callbacks->undefined_symbol) (info, name, input_bfd, input_section, rel->r_offset, TRUE))) return FALSE; break; case bfd_reloc_outofrange: error_message = _("out of range"); goto common_error; case bfd_reloc_notsupported: error_message = _("unsupported relocation"); goto common_error; case bfd_reloc_dangerous: error_message = _("dangerous relocation"); goto common_error; default: error_message = _("unknown error"); /* Fall through. */ common_error: BFD_ASSERT (error_message != NULL); if (!((*info->callbacks->reloc_dangerous) (info, error_message, input_bfd, input_section, rel->r_offset))) return FALSE; break; } } } return ok; } static int elf32_tic6x_obj_attrs_arg_type (int tag) { if (tag == Tag_ABI_compatibility) return ATTR_TYPE_FLAG_INT_VAL | ATTR_TYPE_FLAG_STR_VAL; else if (tag & 1) return ATTR_TYPE_FLAG_STR_VAL; else return ATTR_TYPE_FLAG_INT_VAL; } static int elf32_tic6x_obj_attrs_order (int num) { if (num == LEAST_KNOWN_OBJ_ATTRIBUTE) return Tag_ABI_conformance; if ((num - 1) < Tag_ABI_conformance) return num - 1; return num; } static bfd_boolean elf32_tic6x_obj_attrs_handle_unknown (bfd *abfd, int tag) { if ((tag & 127) < 64) { _bfd_error_handler (_("%B: error: unknown mandatory EABI object attribute %d"), abfd, tag); bfd_set_error (bfd_error_bad_value); return FALSE; } else { _bfd_error_handler (_("%B: warning: unknown EABI object attribute %d"), abfd, tag); return TRUE; } } /* Merge the Tag_ISA attribute values ARCH1 and ARCH2 and return the merged value. At present, all merges succeed, so no return value for errors is defined. */ int elf32_tic6x_merge_arch_attributes (int arch1, int arch2) { int min_arch, max_arch; min_arch = (arch1 < arch2 ? arch1 : arch2); max_arch = (arch1 > arch2 ? arch1 : arch2); /* In most cases, the numerically greatest value is the correct merged value, but merging C64 and C67 results in C674X. */ if ((min_arch == C6XABI_Tag_ISA_C67X || min_arch == C6XABI_Tag_ISA_C67XP) && (max_arch == C6XABI_Tag_ISA_C64X || max_arch == C6XABI_Tag_ISA_C64XP)) return C6XABI_Tag_ISA_C674X; return max_arch; } /* Convert a Tag_ABI_array_object_alignment or Tag_ABI_array_object_align_expected tag value TAG to a corresponding alignment value; return the alignment, or -1 for an unknown tag value. */ static int elf32_tic6x_tag_to_array_alignment (int tag) { switch (tag) { case 0: return 8; case 1: return 4; case 2: return 16; default: return -1; } } /* Convert a Tag_ABI_array_object_alignment or Tag_ABI_array_object_align_expected alignment ALIGN to a corresponding tag value; return the tag value. */ static int elf32_tic6x_array_alignment_to_tag (int align) { switch (align) { case 8: return 0; case 4: return 1; case 16: return 2; default: abort (); } } /* Merge attributes from IBFD and OBFD, returning TRUE if the merge succeeded, FALSE otherwise. */ static bfd_boolean elf32_tic6x_merge_attributes (bfd *ibfd, bfd *obfd) { bfd_boolean result = TRUE; obj_attribute *in_attr; obj_attribute *out_attr; int i; int array_align_in, array_align_out, array_expect_in, array_expect_out; if (!elf_known_obj_attributes_proc (obfd)[0].i) { /* This is the first object. Copy the attributes. */ _bfd_elf_copy_obj_attributes (ibfd, obfd); out_attr = elf_known_obj_attributes_proc (obfd); /* Use the Tag_null value to indicate the attributes have been initialized. */ out_attr[0].i = 1; return TRUE; } in_attr = elf_known_obj_attributes_proc (ibfd); out_attr = elf_known_obj_attributes_proc (obfd); /* No specification yet for handling of unknown attributes, so just ignore them and handle known ones. */ if (out_attr[Tag_ABI_stack_align_preserved].i < in_attr[Tag_ABI_stack_align_needed].i) { _bfd_error_handler (_("error: %B requires more stack alignment than %B preserves"), ibfd, obfd); result = FALSE; } if (in_attr[Tag_ABI_stack_align_preserved].i < out_attr[Tag_ABI_stack_align_needed].i) { _bfd_error_handler (_("error: %B requires more stack alignment than %B preserves"), obfd, ibfd); result = FALSE; } array_align_in = elf32_tic6x_tag_to_array_alignment (in_attr[Tag_ABI_array_object_alignment].i); if (array_align_in == -1) { _bfd_error_handler (_("error: unknown Tag_ABI_array_object_alignment value in %B"), ibfd); result = FALSE; } array_align_out = elf32_tic6x_tag_to_array_alignment (out_attr[Tag_ABI_array_object_alignment].i); if (array_align_out == -1) { _bfd_error_handler (_("error: unknown Tag_ABI_array_object_alignment value in %B"), obfd); result = FALSE; } array_expect_in = elf32_tic6x_tag_to_array_alignment (in_attr[Tag_ABI_array_object_align_expected].i); if (array_expect_in == -1) { _bfd_error_handler (_("error: unknown Tag_ABI_array_object_align_expected value in %B"), ibfd); result = FALSE; } array_expect_out = elf32_tic6x_tag_to_array_alignment (out_attr[Tag_ABI_array_object_align_expected].i); if (array_expect_out == -1) { _bfd_error_handler (_("error: unknown Tag_ABI_array_object_align_expected value in %B"), obfd); result = FALSE; } if (array_align_out < array_expect_in) { _bfd_error_handler (_("error: %B requires more array alignment than %B preserves"), ibfd, obfd); result = FALSE; } if (array_align_in < array_expect_out) { _bfd_error_handler (_("error: %B requires more array alignment than %B preserves"), obfd, ibfd); result = FALSE; } for (i = LEAST_KNOWN_OBJ_ATTRIBUTE; i < NUM_KNOWN_OBJ_ATTRIBUTES; i++) { switch (i) { case Tag_ISA: out_attr[i].i = elf32_tic6x_merge_arch_attributes (in_attr[i].i, out_attr[i].i); break; case Tag_ABI_wchar_t: if (out_attr[i].i == 0) out_attr[i].i = in_attr[i].i; if (out_attr[i].i != 0 && in_attr[i].i != 0 && out_attr[i].i != in_attr[i].i) { _bfd_error_handler (_("warning: %B and %B differ in wchar_t size"), obfd, ibfd); } break; case Tag_ABI_stack_align_needed: if (out_attr[i].i < in_attr[i].i) out_attr[i].i = in_attr[i].i; break; case Tag_ABI_stack_align_preserved: if (out_attr[i].i > in_attr[i].i) out_attr[i].i = in_attr[i].i; break; case Tag_ABI_DSBT: if (out_attr[i].i != in_attr[i].i) { _bfd_error_handler (_("warning: %B and %B differ in whether code is " "compiled for DSBT"), obfd, ibfd); } break; case Tag_ABI_PID: if (out_attr[i].i != in_attr[i].i) { _bfd_error_handler (_("warning: %B and %B differ in position-dependence of " "data addressing"), obfd, ibfd); } break; case Tag_ABI_PIC: if (out_attr[i].i != in_attr[i].i) { _bfd_error_handler (_("warning: %B and %B differ in position-dependence of " "code addressing"), obfd, ibfd); } break; case Tag_ABI_array_object_alignment: if (array_align_out != -1 && array_align_in != -1 && array_align_out > array_align_in) out_attr[i].i = elf32_tic6x_array_alignment_to_tag (array_align_in); break; case Tag_ABI_array_object_align_expected: if (array_expect_out != -1 && array_expect_in != -1 && array_expect_out < array_expect_in) out_attr[i].i = elf32_tic6x_array_alignment_to_tag (array_expect_in); break; case Tag_ABI_conformance: /* Merging for this attribute is not specified. As on ARM, treat a missing attribute as no claim to conform and only merge identical values. */ if (out_attr[i].s == NULL || in_attr[i].s == NULL || strcmp (out_attr[i].s, in_attr[i].s) != 0) out_attr[i].s = NULL; break; case Tag_ABI_compatibility: /* Merged in _bfd_elf_merge_object_attributes. */ break; default: result = result && _bfd_elf_merge_unknown_attribute_low (ibfd, obfd, i); break; } if (in_attr[i].type && !out_attr[i].type) out_attr[i].type = in_attr[i].type; } /* Merge Tag_ABI_compatibility attributes and any common GNU ones. */ if (!_bfd_elf_merge_object_attributes (ibfd, obfd)) return FALSE; result &= _bfd_elf_merge_unknown_attribute_list (ibfd, obfd); return result; } static bfd_boolean elf32_tic6x_merge_private_bfd_data (bfd *ibfd, bfd *obfd) { if (!_bfd_generic_verify_endian_match (ibfd, obfd)) return FALSE; if (!elf32_tic6x_merge_attributes (ibfd, obfd)) return FALSE; return TRUE; } #define TARGET_LITTLE_SYM bfd_elf32_tic6x_le_vec #define TARGET_LITTLE_NAME "elf32-tic6x-le" #define TARGET_BIG_SYM bfd_elf32_tic6x_be_vec #define TARGET_BIG_NAME "elf32-tic6x-be" #define ELF_ARCH bfd_arch_tic6x #define ELF_TARGET_ID TIC6X_ELF_DATA #define ELF_MACHINE_CODE EM_TI_C6000 #define ELF_MAXPAGESIZE 1 #define bfd_elf32_bfd_reloc_type_lookup elf32_tic6x_reloc_type_lookup #define bfd_elf32_bfd_reloc_name_lookup elf32_tic6x_reloc_name_lookup #define bfd_elf32_bfd_merge_private_bfd_data elf32_tic6x_merge_private_bfd_data #define bfd_elf32_mkobject elf32_tic6x_mkobject #define bfd_elf32_new_section_hook elf32_tic6x_new_section_hook #define elf_backend_can_gc_sections 1 #define elf_backend_default_use_rela_p 1 #define elf_backend_may_use_rel_p 1 #define elf_backend_may_use_rela_p 1 #define elf_backend_obj_attrs_arg_type elf32_tic6x_obj_attrs_arg_type #define elf_backend_obj_attrs_handle_unknown elf32_tic6x_obj_attrs_handle_unknown #define elf_backend_obj_attrs_order elf32_tic6x_obj_attrs_order #define elf_backend_obj_attrs_section ".c6xabi.attributes" #define elf_backend_obj_attrs_section_type SHT_C6000_ATTRIBUTES #define elf_backend_obj_attrs_vendor "c6xabi" #define elf_backend_rela_normal 1 #define elf_backend_relocate_section elf32_tic6x_relocate_section #define elf_info_to_howto elf32_tic6x_info_to_howto #define elf_info_to_howto_rel elf32_tic6x_info_to_howto_rel #include "elf32-target.h"