+ HOWTO (R_C6000_NONE, /* type */
+ 0, /* rightshift */
+ 3, /* 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 */
+ TRUE, /* 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 */
+ TRUE), /* 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 */
+ HOWTO (R_C6000_JUMP_SLOT, /* 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_JUMP_SLOT", /* name */
+ FALSE, /* partial_inplace */
+ 0, /* src_mask */
+ 0xffffffff, /* dst_mask */
+ FALSE), /* pcrel_offset */
+ HOWTO (R_C6000_EHTYPE, /* 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_EHTYPE", /* name */
+ FALSE, /* partial_inplace */
+ 0, /* src_mask */
+ 0xffffffff, /* dst_mask */
+ FALSE), /* pcrel_offset */
+ EMPTY_HOWTO (R_C6000_PCR_H16),
+ EMPTY_HOWTO (R_C6000_PCR_L16),
+ 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_JUMP_SLOT, R_C6000_JUMP_SLOT },
+ { BFD_RELOC_C6000_EHTYPE, R_C6000_EHTYPE },
+ { BFD_RELOC_C6000_PCR_H16, R_C6000_PCR_H16 },
+ { BFD_RELOC_C6000_PCR_L16, R_C6000_PCR_L16 },
+ { 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 bfd_boolean
+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))
+ {
+ /* xgettext:c-format */
+ _bfd_error_handler (_("%pB: unsupported relocation type %#x"),
+ abfd, r_type);
+ bfd_set_error (bfd_error_bad_value);
+ return FALSE;
+ }
+
+ bfd_reloc->howto = &elf32_tic6x_howto_table[r_type];
+ if (bfd_reloc->howto == NULL || bfd_reloc->howto->name == NULL)
+ {
+ /* xgettext:c-format */
+ _bfd_error_handler (_("%pB: unsupported relocation type %#x"),
+ abfd, r_type);
+ bfd_set_error (bfd_error_bad_value);
+ return FALSE;
+ }
+
+ return TRUE;
+}
+
+static bfd_boolean
+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))
+ {
+ /* xgettext:c-format */
+ _bfd_error_handler (_("%pB: unsupported relocation type %#x"),
+ abfd, r_type);
+ bfd_set_error (bfd_error_bad_value);
+ return FALSE;
+ }
+
+ bfd_reloc->howto = &elf32_tic6x_howto_table_rel[r_type];
+ if (bfd_reloc->howto == NULL || bfd_reloc->howto->name == NULL)
+ {
+ /* xgettext:c-format */
+ _bfd_error_handler (_("%pB: unsupported relocation type %#x"),
+ abfd, r_type);
+ bfd_set_error (bfd_error_bad_value);
+ return FALSE;
+ }
+
+ return TRUE;
+}
+
+void
+elf32_tic6x_set_use_rela_p (bfd *abfd, bfd_boolean use_rela_p)
+{
+ elf32_tic6x_tdata (abfd)->use_rela_p = use_rela_p;
+}
+
+/* Create an entry in a C6X ELF linker hash table. */
+
+static struct bfd_hash_entry *
+elf32_tic6x_link_hash_newfunc (struct bfd_hash_entry *entry,
+ struct bfd_hash_table *table,
+ const char *string)
+{
+ /* Allocate the structure if it has not already been allocated by a
+ subclass. */
+ if (entry == NULL)
+ {
+ entry = bfd_hash_allocate (table,
+ sizeof (struct elf32_tic6x_link_hash_entry));
+ if (entry == NULL)
+ return entry;
+ }
+
+ /* Call the allocation method of the superclass. */
+ entry = _bfd_elf_link_hash_newfunc (entry, table, string);
+ if (entry != NULL)
+ {
+ struct elf32_tic6x_link_hash_entry *eh;
+
+ eh = (struct elf32_tic6x_link_hash_entry *) entry;
+ eh->dyn_relocs = NULL;
+ }
+
+ return entry;
+}
+
+/* Create a C6X ELF linker hash table. */
+
+static struct bfd_link_hash_table *
+elf32_tic6x_link_hash_table_create (bfd *abfd)
+{
+ struct elf32_tic6x_link_hash_table *ret;
+ bfd_size_type amt = sizeof (struct elf32_tic6x_link_hash_table);
+
+ ret = bfd_zmalloc (amt);
+ if (ret == NULL)
+ return NULL;
+
+ if (!_bfd_elf_link_hash_table_init (&ret->elf, abfd,
+ elf32_tic6x_link_hash_newfunc,
+ sizeof (struct elf32_tic6x_link_hash_entry),
+ TIC6X_ELF_DATA))
+ {
+ free (ret);
+ return NULL;
+ }
+
+ ret->obfd = abfd;
+ ret->elf.is_relocatable_executable = 1;
+
+ return &ret->elf.root;
+}
+
+static bfd_boolean
+elf32_tic6x_final_link (bfd *abfd, struct bfd_link_info *info)
+{
+ if (bfd_link_pic (info))
+ {
+ obj_attribute *out_attr;
+ out_attr = elf_known_obj_attributes_proc (abfd);
+ if (out_attr[Tag_ABI_PIC].i == 0)
+ {
+ _bfd_error_handler (_("warning: generating a shared library "
+ "containing non-PIC code"));
+ }
+ if (out_attr[Tag_ABI_PID].i == 0)
+ {
+ _bfd_error_handler (_("warning: generating a shared library "
+ "containing non-PID code"));
+ }
+ }
+ /* Invoke the regular ELF backend linker to do all the work. */
+ if (!bfd_elf_final_link (abfd, info))
+ return FALSE;
+
+ return TRUE;
+}
+
+/* Called to pass PARAMS to the backend. We store them in the hash table
+ associated with INFO. */
+
+void
+elf32_tic6x_setup (struct bfd_link_info *info,
+ struct elf32_tic6x_params *params)
+{
+ struct elf32_tic6x_link_hash_table *htab = elf32_tic6x_hash_table (info);
+ htab->params = *params;
+}
+
+/* Determine if we're dealing with a DSBT object. */
+
+static bfd_boolean
+elf32_tic6x_using_dsbt (bfd *abfd)
+{
+ return bfd_elf_get_obj_attr_int (abfd, OBJ_ATTR_PROC,
+ Tag_ABI_DSBT);
+}
+
+/* Create .plt, .rela.plt, .got, .got.plt, .rela.got and .dsbt
+ sections in DYNOBJ, and set up shortcuts to them in our hash
+ table. */
+
+static bfd_boolean
+elf32_tic6x_create_dynamic_sections (bfd *dynobj, struct bfd_link_info *info)
+{
+ struct elf32_tic6x_link_hash_table *htab;
+ flagword flags;
+
+ htab = elf32_tic6x_hash_table (info);
+ if (htab == NULL)
+ return FALSE;
+
+ if (!_bfd_elf_create_dynamic_sections (dynobj, info))
+ return FALSE;
+
+ /* Create .dsbt */
+ flags = (SEC_ALLOC | SEC_LOAD
+ | SEC_HAS_CONTENTS | SEC_IN_MEMORY | SEC_LINKER_CREATED);
+ htab->dsbt = bfd_make_section_anyway_with_flags (dynobj, ".dsbt",
+ flags);
+ if (htab->dsbt == NULL
+ || !bfd_set_section_alignment (htab->dsbt, 2)
+ || !bfd_set_section_alignment (htab->elf.splt, 5))
+ return FALSE;
+
+ return TRUE;
+}
+
+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;
+}
+
+/* Install relocation RELA into section SRELA, incrementing its
+ reloc_count. */
+
+static void
+elf32_tic6x_install_rela (bfd *output_bfd, asection *srela,
+ Elf_Internal_Rela *rela)
+{
+ bfd_byte *loc;
+ bfd_vma off = srela->reloc_count++ * sizeof (Elf32_External_Rela);
+ loc = srela->contents + off;
+ BFD_ASSERT (off < srela->size);
+ bfd_elf32_swap_reloca_out (output_bfd, rela, loc);
+}
+
+/* Create a dynamic reloc against the GOT at offset OFFSET. The contents
+ of the GOT at this offset have been initialized with the relocation. */
+
+static void
+elf32_tic6x_make_got_dynreloc (bfd *output_bfd,
+ struct elf32_tic6x_link_hash_table *htab,
+ asection *sym_sec, bfd_vma offset)
+{
+ asection *sgot = htab->elf.sgot;
+ Elf_Internal_Rela outrel;
+ int dynindx;
+
+ outrel.r_offset = sgot->output_section->vma + sgot->output_offset + offset;
+ outrel.r_addend = bfd_get_32 (output_bfd, sgot->contents + offset);
+ if (sym_sec && sym_sec->output_section
+ && ! bfd_is_abs_section (sym_sec->output_section)
+ && ! bfd_is_und_section (sym_sec->output_section))
+ {
+ dynindx = elf_section_data (sym_sec->output_section)->dynindx;
+ outrel.r_addend -= sym_sec->output_section->vma;
+ }
+ else
+ {
+ dynindx = 0;
+ }
+ outrel.r_info = ELF32_R_INFO (dynindx, R_C6000_ABS32);
+ elf32_tic6x_install_rela (output_bfd, htab->elf.srelgot, &outrel);
+}
+
+/* Finish up dynamic symbol handling. We set the contents of various
+ dynamic sections here. */
+
+static bfd_boolean
+elf32_tic6x_finish_dynamic_symbol (bfd * output_bfd,
+ struct bfd_link_info *info,
+ struct elf_link_hash_entry *h,
+ Elf_Internal_Sym * sym)
+{
+ struct elf32_tic6x_link_hash_table *htab;
+
+ htab = elf32_tic6x_hash_table (info);
+
+ if (h->plt.offset != (bfd_vma) -1)
+ {
+ bfd_vma plt_index;
+ bfd_vma got_section_offset, got_dp_offset, rela_offset;
+ Elf_Internal_Rela rela;
+ bfd_byte *loc;
+ asection *plt, *gotplt, *relplt;
+ const struct elf_backend_data *bed;
+
+ bed = get_elf_backend_data (output_bfd);
+
+ BFD_ASSERT (htab->elf.splt != NULL);
+ plt = htab->elf.splt;
+ gotplt = htab->elf.sgotplt;
+ relplt = htab->elf.srelplt;
+
+ /* This symbol has an entry in the procedure linkage table. Set
+ it up. */
+
+ if ((h->dynindx == -1
+ && !((h->forced_local || bfd_link_executable (info))
+ && h->def_regular
+ && h->type == STT_GNU_IFUNC))
+ || plt == NULL
+ || gotplt == NULL
+ || relplt == NULL)
+ abort ();
+
+ /* Get the index in the procedure linkage table which
+ corresponds to this symbol. This is the index of this symbol
+ in all the symbols for which we are making plt entries. The
+ first entry in the procedure linkage table is reserved.
+
+ Get the offset into the .got table of the entry that
+ corresponds to this function. Each .got entry is 4 bytes.
+ The first three are reserved.
+
+ For static executables, we don't reserve anything. */
+
+ plt_index = h->plt.offset / PLT_ENTRY_SIZE - 1;
+ got_section_offset = plt_index + bed->got_header_size / 4;
+ got_dp_offset = got_section_offset + htab->params.dsbt_size;
+ rela_offset = plt_index * sizeof (Elf32_External_Rela);
+
+ got_section_offset *= 4;
+
+ /* Fill in the entry in the procedure linkage table. */
+
+ /* ldw .d2t2 *+B14($GOT(f)), b2 */
+ bfd_put_32 (output_bfd, got_dp_offset << 8 | 0x0100006e,
+ plt->contents + h->plt.offset);
+ /* mvk .s2 low(rela_offset), b0 */
+ bfd_put_32 (output_bfd, (rela_offset & 0xffff) << 7 | 0x0000002a,
+ plt->contents + h->plt.offset + 4);
+ /* mvkh .s2 high(rela_offset), b0 */
+ bfd_put_32 (output_bfd, ((rela_offset >> 16) & 0xffff) << 7 | 0x0000006a,
+ plt->contents + h->plt.offset + 8);
+ /* nop 2 */
+ bfd_put_32 (output_bfd, 0x00002000,
+ plt->contents + h->plt.offset + 12);
+ /* b .s2 b2 */
+ bfd_put_32 (output_bfd, 0x00080362,
+ plt->contents + h->plt.offset + 16);
+ /* nop 5 */
+ bfd_put_32 (output_bfd, 0x00008000,
+ plt->contents + h->plt.offset + 20);
+
+ /* Fill in the entry in the global offset table. */
+ bfd_put_32 (output_bfd,
+ (plt->output_section->vma + plt->output_offset),
+ gotplt->contents + got_section_offset);
+
+ /* Fill in the entry in the .rel.plt section. */
+ rela.r_offset = (gotplt->output_section->vma
+ + gotplt->output_offset
+ + got_section_offset);
+ rela.r_info = ELF32_R_INFO (h->dynindx, R_C6000_JUMP_SLOT);
+ rela.r_addend = 0;
+ loc = relplt->contents + rela_offset;
+ bfd_elf32_swap_reloca_out (output_bfd, &rela, loc);
+
+ if (!h->def_regular)
+ {
+ /* Mark the symbol as undefined, rather than as defined in
+ the .plt section. */
+ sym->st_shndx = SHN_UNDEF;
+ sym->st_value = 0;
+ }
+ }
+
+ if (h->got.offset != (bfd_vma) -1)
+ {
+ asection *sgot;
+ asection *srela;
+
+ /* This symbol has an entry in the global offset table.
+ Set it up. */
+
+ sgot = htab->elf.sgot;
+ srela = htab->elf.srelgot;
+ BFD_ASSERT (sgot != NULL && srela != NULL);
+
+ /* If this is a -Bsymbolic link, and the symbol is defined
+ locally, we just want to emit a RELATIVE reloc. Likewise if
+ the symbol was forced to be local because of a version file.
+ The entry in the global offset table will already have been
+ initialized in the relocate_section function. */
+ if (bfd_link_pic (info)
+ && (SYMBOLIC_BIND (info, h)
+ || h->dynindx == -1 || h->forced_local) && h->def_regular)
+ {
+ asection *s = h->root.u.def.section;
+ elf32_tic6x_make_got_dynreloc (output_bfd, htab, s,
+ h->got.offset & ~(bfd_vma) 1);
+ }
+ else
+ {
+ Elf_Internal_Rela outrel;
+ bfd_put_32 (output_bfd, (bfd_vma) 0,
+ sgot->contents + (h->got.offset & ~(bfd_vma) 1));
+ outrel.r_offset = (sgot->output_section->vma
+ + sgot->output_offset
+ + (h->got.offset & ~(bfd_vma) 1));
+ outrel.r_info = ELF32_R_INFO (h->dynindx, R_C6000_ABS32);
+ outrel.r_addend = 0;
+
+ elf32_tic6x_install_rela (output_bfd, srela, &outrel);
+ }
+ }
+
+ if (h->needs_copy)
+ {
+ Elf_Internal_Rela rel;
+ asection *s;
+
+ /* This symbol needs a copy reloc. Set it up. */
+
+ if (h->dynindx == -1
+ || (h->root.type != bfd_link_hash_defined
+ && h->root.type != bfd_link_hash_defweak)
+ || htab->elf.srelbss == NULL
+ || htab->elf.sreldynrelro == NULL)
+ abort ();
+
+ rel.r_offset = (h->root.u.def.value
+ + h->root.u.def.section->output_section->vma
+ + h->root.u.def.section->output_offset);
+ rel.r_info = ELF32_R_INFO (h->dynindx, R_C6000_COPY);
+ rel.r_addend = 0;
+ if (h->root.u.def.section == htab->elf.sdynrelro)
+ s = htab->elf.sreldynrelro;
+ else
+ s = htab->elf.srelbss;
+
+ elf32_tic6x_install_rela (output_bfd, s, &rel);
+ }
+
+ /* Mark _DYNAMIC and _GLOBAL_OFFSET_TABLE_ as absolute. */
+ if (h == elf_hash_table (info)->hdynamic
+ || h == elf_hash_table (info)->hgot)
+ sym->st_shndx = SHN_ABS;
+
+ return TRUE;
+}
+
+/* Unwinding tables are not referenced directly. This pass marks them as
+ required if the corresponding code section is marked. */
+
+static bfd_boolean
+elf32_tic6x_gc_mark_extra_sections (struct bfd_link_info *info,
+ elf_gc_mark_hook_fn gc_mark_hook)
+{
+ bfd *sub;
+ Elf_Internal_Shdr **elf_shdrp;
+ bfd_boolean again;
+
+ _bfd_elf_gc_mark_extra_sections (info, gc_mark_hook);
+
+ /* Marking EH data may cause additional code sections to be marked,
+ requiring multiple passes. */
+ again = TRUE;
+ while (again)
+ {
+ again = FALSE;
+ for (sub = info->input_bfds; sub != NULL; sub = sub->link.next)
+ {
+ asection *o;
+
+ if (! is_tic6x_elf (sub))
+ continue;
+
+ elf_shdrp = elf_elfsections (sub);
+ for (o = sub->sections; o != NULL; o = o->next)
+ {
+ Elf_Internal_Shdr *hdr;
+
+ hdr = &elf_section_data (o)->this_hdr;
+ if (hdr->sh_type == SHT_C6000_UNWIND
+ && hdr->sh_link
+ && hdr->sh_link < elf_numsections (sub)
+ && !o->gc_mark
+ && elf_shdrp[hdr->sh_link]->bfd_section->gc_mark)
+ {
+ again = TRUE;
+ if (!_bfd_elf_gc_mark (info, o, gc_mark_hook))
+ return FALSE;
+ }
+ }
+ }
+ }
+
+ return TRUE;
+}
+
+/* Return TRUE if this is an unwinding table index. */
+
+static bfd_boolean
+is_tic6x_elf_unwind_section_name (const char *name)
+{
+ return (CONST_STRNEQ (name, ELF_STRING_C6000_unwind)
+ || CONST_STRNEQ (name, ELF_STRING_C6000_unwind_once));
+}
+
+
+/* Set the type and flags for an unwinding index table. We do this by
+ the section name, which is a hack, but ought to work. */
+
+static bfd_boolean
+elf32_tic6x_fake_sections (bfd *abfd ATTRIBUTE_UNUSED,
+ Elf_Internal_Shdr *hdr, asection *sec)
+{
+ const char * name;
+
+ name = bfd_section_name (sec);
+
+ if (is_tic6x_elf_unwind_section_name (name))
+ {
+ hdr->sh_type = SHT_C6000_UNWIND;
+ hdr->sh_flags |= SHF_LINK_ORDER;
+ }
+
+ return TRUE;
+}
+
+/* Find dynamic relocs for H that apply to read-only sections. */
+
+static asection *
+readonly_dynrelocs (struct elf_link_hash_entry *h)
+{
+ struct elf_dyn_relocs *p;
+ struct elf32_tic6x_link_hash_entry *eh
+ = (struct elf32_tic6x_link_hash_entry *) h;
+
+ for (p = eh->dyn_relocs; p != NULL; p = p->next)
+ {
+ asection *s = p->sec->output_section;
+
+ if (s != NULL && (s->flags & SEC_READONLY) != 0)
+ return p->sec;
+ }
+ return NULL;
+}
+
+/* Adjust a symbol defined by a dynamic object and referenced by a
+ regular object. The current definition is in some section of the
+ dynamic object, but we're not including those sections. We have to
+ change the definition to something the rest of the link can
+ understand. */
+
+static bfd_boolean
+elf32_tic6x_adjust_dynamic_symbol (struct bfd_link_info *info,
+ struct elf_link_hash_entry *h)
+{
+ struct elf32_tic6x_link_hash_table *htab;
+ bfd *dynobj;
+ asection *s, *srel;
+
+ dynobj = elf_hash_table (info)->dynobj;
+
+ /* Make sure we know what is going on here. */
+ BFD_ASSERT (dynobj != NULL
+ && (h->needs_plt
+ || h->is_weakalias
+ || (h->def_dynamic && h->ref_regular && !h->def_regular)));
+
+ /* If this is a function, put it in the procedure linkage table. We
+ will fill in the contents of the procedure linkage table later,
+ when we know the address of the .got section. */
+ if (h->type == STT_FUNC
+ || h->needs_plt)
+ {
+ if (h->plt.refcount <= 0
+ || SYMBOL_CALLS_LOCAL (info, h)
+ || (ELF_ST_VISIBILITY (h->other) != STV_DEFAULT
+ && h->root.type == bfd_link_hash_undefweak))
+ {
+ /* This case can occur if we saw a PLT32 reloc in an input
+ file, but the symbol was never referred to by a dynamic
+ object, or if all references were garbage collected. In
+ such a case, we don't actually need to build a procedure
+ linkage table, and we can just do a PC32 reloc instead. */
+ h->plt.offset = (bfd_vma) -1;
+ h->needs_plt = 0;
+ }
+
+ return TRUE;
+ }
+
+ /* If this is a weak symbol, and there is a real definition, the
+ processor independent code will have arranged for us to see the
+ real definition first, and we can just use the same value. */
+ if (h->is_weakalias)
+ {
+ struct elf_link_hash_entry *def = weakdef (h);
+ BFD_ASSERT (def->root.type == bfd_link_hash_defined);
+ h->root.u.def.section = def->root.u.def.section;
+ h->root.u.def.value = def->root.u.def.value;
+ h->non_got_ref = def->non_got_ref;
+ return TRUE;
+ }
+
+ /* This is a reference to a symbol defined by a dynamic object which
+ is not a function. */
+
+ /* If we are creating a shared library, we must presume that the
+ only references to the symbol are via the global offset table.
+ For such cases we need not do anything here; the relocations will
+ be handled correctly by relocate_section. */
+ if (bfd_link_pic (info))
+ return TRUE;
+
+ /* If there are no references to this symbol that do not use the
+ GOT, we don't need to generate a copy reloc. */
+ if (!h->non_got_ref)
+ return TRUE;
+
+ /* If -z nocopyreloc was given, we won't generate them either. */
+ if (info->nocopyreloc)
+ {
+ h->non_got_ref = 0;
+ return TRUE;
+ }
+
+ htab = elf32_tic6x_hash_table (info);
+ if (htab == NULL)
+ return FALSE;
+
+ /* We must allocate the symbol in our .dynbss section, which will
+ become part of the .bss section of the executable. There will be
+ an entry for this symbol in the .dynsym section. The dynamic
+ object will contain position independent code, so all references
+ from the dynamic object to this symbol will go through the global
+ offset table. The dynamic linker will use the .dynsym entry to
+ determine the address it must put in the global offset table, so
+ both the dynamic object and the regular object will refer to the
+ same memory location for the variable. */
+
+ /* We must generate a R_C6000_COPY reloc to tell the dynamic linker to
+ copy the initial value out of the dynamic object and into the
+ runtime process image. */
+ if ((h->root.u.def.section->flags & SEC_READONLY) != 0)
+ {
+ s = htab->elf.sdynrelro;
+ srel = htab->elf.sreldynrelro;
+ }
+ else
+ {
+ s = htab->elf.sdynbss;
+ srel = htab->elf.srelbss;
+ }
+ if ((h->root.u.def.section->flags & SEC_ALLOC) != 0 && h->size != 0)
+ {
+ srel->size += sizeof (Elf32_External_Rela);
+ h->needs_copy = 1;
+ }
+
+ return _bfd_elf_adjust_dynamic_copy (info, h, s);
+}
+
+static bfd_boolean
+elf32_tic6x_new_section_hook (bfd *abfd, asection *sec)
+{
+ bfd_boolean ret;
+
+ /* Allocate target specific section data. */
+ if (!sec->used_by_bfd)
+ {
+ _tic6x_elf_section_data *sdata;
+ bfd_size_type amt = sizeof (*sdata);
+
+ sdata = (_tic6x_elf_section_data *) bfd_zalloc (abfd, amt);
+ if (sdata == NULL)
+ return FALSE;
+ sec->used_by_bfd = sdata;
+ }
+
+ 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);
+}
+
+/* We need dynamic symbols for every section, since segments can
+ relocate independently. */
+static bfd_boolean
+elf32_tic6x_link_omit_section_dynsym (bfd *output_bfd ATTRIBUTE_UNUSED,
+ struct bfd_link_info *info ATTRIBUTE_UNUSED,
+ asection *p)
+{
+ switch (elf_section_data (p)->this_hdr.sh_type)
+ {
+ case SHT_PROGBITS:
+ case SHT_NOBITS:
+ /* If sh_type is yet undecided, assume it could be
+ SHT_PROGBITS/SHT_NOBITS. */
+ case SHT_NULL:
+ return FALSE;
+
+ /* There shouldn't be section relative relocations
+ against any other section. */
+ default:
+ return TRUE;
+ }
+}
+
+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)
+{
+ struct elf32_tic6x_link_hash_table *htab;
+ Elf_Internal_Shdr *symtab_hdr;
+ struct elf_link_hash_entry **sym_hashes;
+ bfd_vma *local_got_offsets;
+ Elf_Internal_Rela *rel;
+ Elf_Internal_Rela *relend;
+ bfd_boolean ok = TRUE;
+
+ htab = elf32_tic6x_hash_table (info);
+ symtab_hdr = & elf_symtab_hdr (input_bfd);
+ sym_hashes = elf_sym_hashes (input_bfd);
+ local_got_offsets = elf_local_got_offsets (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 off, off2, relocation;
+ bfd_boolean unresolved_reloc;
+ bfd_reloc_status_type r;
+ struct bfd_link_hash_entry *sbh;
+ bfd_boolean is_rel;
+ bfd_boolean res;
+
+ 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)
+ res = elf32_tic6x_info_to_howto_rel (input_bfd, &bfd_reloc, rel);
+ else
+ res = elf32_tic6x_info_to_howto (input_bfd, &bfd_reloc, rel);
+
+ if (!res || (howto = bfd_reloc.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, ignored;
+
+ RELOC_FOR_GLOBAL_SYMBOL (info, input_bfd, input_section, rel,
+ r_symndx, symtab_hdr, sym_hashes,
+ h, sec, relocation,
+ unresolved_reloc, warned, ignored);
+ }
+
+ if (sec != NULL && discarded_section (sec))
+ RELOC_AGAINST_DISCARDED_SECTION (info, input_bfd, input_section,
+ rel, 1, relend, howto, 0, contents);
+
+ if (bfd_link_relocatable (info))
+ {
+ 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:
+ /* A branch to an undefined weak symbol is turned into a
+ "b .s2 B3" instruction if the existing insn is of the
+ form "b .s2 symbol". */
+ if (h ? h->root.type == bfd_link_hash_undefweak
+ && (htab->elf.splt == NULL || h->plt.offset == (bfd_vma) -1)
+ : r_symndx != STN_UNDEF && bfd_is_und_section (sec))
+ {
+ unsigned long oldval;
+ oldval = bfd_get_32 (input_bfd, contents + rel->r_offset);
+
+ if ((oldval & 0x7e) == 0x12)
+ {
+ oldval &= 0xF0000001;
+ bfd_put_32 (input_bfd, oldval | 0x000c0362,
+ contents + rel->r_offset);
+ r = bfd_reloc_ok;
+ goto done_reloc;
+ }
+ }
+ /* Fall through. */
+
+ case R_C6000_PCR_S12:
+ case R_C6000_PCR_S10:
+ case R_C6000_PCR_S7:
+ if (h != NULL
+ && h->plt.offset != (bfd_vma) -1
+ && htab->elf.splt != NULL)
+ {
+ relocation = (htab->elf.splt->output_section->vma
+ + htab->elf.splt->output_offset
+ + h->plt.offset);
+ }
+
+ /* 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;
+ unresolved_reloc = FALSE;
+ break;
+
+ case R_C6000_PCR_H16:
+ case R_C6000_PCR_L16:
+ off = (input_section->output_section->vma
+ + input_section->output_offset
+ + rel->r_offset);
+ /* These must be calculated as R = S - FP(FP(PC) - A).
+ PC, here, is the value we just computed in OFF. RELOCATION
+ has the address of S + A. */
+ relocation -= rel->r_addend;
+ off2 = ((off & ~(bfd_vma)0x1f) - rel->r_addend) & (bfd_vma)~0x1f;
+ off2 = relocation - off2;
+ relocation = off + off2;
+ break;
+
+ case R_C6000_DSBT_INDEX:
+ relocation = elf32_tic6x_hash_table (info)->params.dsbt_index;
+ if (!bfd_link_pic (info) || relocation != 0)
+ break;
+
+ /* 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:
+ /* When generating a shared object or relocatable executable, these
+ relocations are copied into the output file to be resolved at
+ run time. */
+ if ((bfd_link_pic (info) || elf32_tic6x_using_dsbt (output_bfd))
+ && (input_section->flags & SEC_ALLOC)
+ && (h == NULL
+ || ELF_ST_VISIBILITY (h->other) == STV_DEFAULT
+ || h->root.type != bfd_link_hash_undefweak))
+ {
+ Elf_Internal_Rela outrel;
+ bfd_boolean skip, relocate;
+ asection *sreloc;
+
+ unresolved_reloc = FALSE;
+
+ sreloc = elf_section_data (input_section)->sreloc;
+ BFD_ASSERT (sreloc != NULL && sreloc->contents != NULL);
+
+ skip = FALSE;
+ relocate = FALSE;
+
+ outrel.r_offset =
+ _bfd_elf_section_offset (output_bfd, info, input_section,
+ rel->r_offset);
+ if (outrel.r_offset == (bfd_vma) -1)
+ skip = TRUE;
+ else if (outrel.r_offset == (bfd_vma) -2)
+ skip = TRUE, relocate = TRUE;
+ outrel.r_offset += (input_section->output_section->vma
+ + input_section->output_offset);
+
+ if (skip)
+ memset (&outrel, 0, sizeof outrel);
+ else if (h != NULL
+ && h->dynindx != -1
+ && (!bfd_link_pic (info)
+ || !SYMBOLIC_BIND (info, h)
+ || !h->def_regular))
+ {
+ outrel.r_info = ELF32_R_INFO (h->dynindx, r_type);
+ outrel.r_addend = rel->r_addend;
+ }
+ else
+ {
+ long indx;
+
+ outrel.r_addend = relocation + rel->r_addend;
+
+ if (bfd_is_abs_section (sec))
+ indx = 0;
+ else if (sec == NULL || sec->owner == NULL)
+ {
+ bfd_set_error (bfd_error_bad_value);
+ return FALSE;
+ }
+ else
+ {
+ asection *osec;
+
+ osec = sec->output_section;
+ indx = elf_section_data (osec)->dynindx;
+ outrel.r_addend -= osec->vma;
+ BFD_ASSERT (indx != 0);
+ }
+
+ outrel.r_info = ELF32_R_INFO (indx, r_type);
+ }
+
+ elf32_tic6x_install_rela (output_bfd, sreloc, &outrel);
+
+ /* If this reloc is against an external symbol, we do not want to
+ fiddle with the addend. Otherwise, we need to include the symbol
+ value so that it becomes an addend for the dynamic reloc. */
+ if (! relocate)
+ continue;
+ }
+
+ /* Generic logic OK. */
+ break;
+
+ case R_C6000_SBR_U15_B:
+ case R_C6000_SBR_U15_H: