daily update
[deliverable/binutils-gdb.git] / bfd / elf32-tic6x.c
index 9163833d87857f2838c2fba76441f8eac4a710f8..3674a3a8ad1787389a3f04ce7a9d229f11da87e1 100644 (file)
@@ -1,6 +1,8 @@
 /* 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.
 
 #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[] =
 {
@@ -153,24 +169,632 @@ static reloc_howto_type elf32_tic6x_howto_table[] =
         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 */
+        "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_H16,      /* type */
-        16,                    /* rightshift */
+  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_H16",     /* name */
-        FALSE,                 /* partial_inplace */
-        0,                     /* src_mask */
+        "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) */
@@ -180,8 +804,8 @@ static reloc_howto_type elf32_tic6x_howto_table[] =
         complain_overflow_unsigned,/* complain_on_overflow */
         bfd_elf_generic_reloc, /* special_function */
         "R_C6000_SBR_U15_B",   /* name */
-        FALSE,                 /* partial_inplace */
-        0,                     /* src_mask */
+        TRUE,                  /* partial_inplace */
+        0x007fff00,            /* src_mask */
         0x007fff00,            /* dst_mask */
         FALSE),                /* pcrel_offset */
   HOWTO (R_C6000_SBR_U15_H,    /* type */
@@ -193,8 +817,8 @@ static reloc_howto_type elf32_tic6x_howto_table[] =
         complain_overflow_unsigned,/* complain_on_overflow */
         bfd_elf_generic_reloc, /* special_function */
         "R_C6000_SBR_U15_H",   /* name */
-        FALSE,                 /* partial_inplace */
-        0,                     /* src_mask */
+        TRUE,                  /* partial_inplace */
+        0x007fff00,            /* src_mask */
         0x007fff00,            /* dst_mask */
         FALSE),                /* pcrel_offset */
   HOWTO (R_C6000_SBR_U15_W,    /* type */
@@ -206,8 +830,8 @@ static reloc_howto_type elf32_tic6x_howto_table[] =
         complain_overflow_unsigned,/* complain_on_overflow */
         bfd_elf_generic_reloc, /* special_function */
         "R_C6000_SBR_U15_W",   /* name */
-        FALSE,                 /* partial_inplace */
-        0,                     /* src_mask */
+        TRUE,                  /* partial_inplace */
+        0x007fff00,            /* src_mask */
         0x007fff00,            /* dst_mask */
         FALSE),                /* pcrel_offset */
   HOWTO (R_C6000_SBR_S16,      /* type */
@@ -219,8 +843,8 @@ static reloc_howto_type elf32_tic6x_howto_table[] =
         complain_overflow_signed,/* complain_on_overflow */
         bfd_elf_generic_reloc, /* special_function */
         "R_C6000_SBR_S16",     /* name */
-        FALSE,                 /* partial_inplace */
-        0,                     /* src_mask */
+        TRUE,                  /* partial_inplace */
+        0x007fff80,            /* src_mask */
         0x007fff80,            /* dst_mask */
         FALSE),                /* pcrel_offset */
   HOWTO (R_C6000_SBR_L16_B,    /* type */
@@ -232,8 +856,8 @@ static reloc_howto_type elf32_tic6x_howto_table[] =
         complain_overflow_dont,/* complain_on_overflow */
         bfd_elf_generic_reloc, /* special_function */
         "R_C6000_SBR_L16_B",   /* name */
-        FALSE,                 /* partial_inplace */
-        0,                     /* src_mask */
+        TRUE,                  /* partial_inplace */
+        0x007fff80,            /* src_mask */
         0x007fff80,            /* dst_mask */
         FALSE),                /* pcrel_offset */
   HOWTO (R_C6000_SBR_L16_H,    /* type */
@@ -245,8 +869,8 @@ static reloc_howto_type elf32_tic6x_howto_table[] =
         complain_overflow_dont,/* complain_on_overflow */
         bfd_elf_generic_reloc, /* special_function */
         "R_C6000_SBR_L16_H",   /* name */
-        FALSE,                 /* partial_inplace */
-        0,                     /* src_mask */
+        TRUE,                  /* partial_inplace */
+        0x007fff80,            /* src_mask */
         0x007fff80,            /* dst_mask */
         FALSE),                /* pcrel_offset */
   HOWTO (R_C6000_SBR_L16_W,    /* type */
@@ -258,49 +882,13 @@ static reloc_howto_type elf32_tic6x_howto_table[] =
         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 */
+        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) */
@@ -310,8 +898,8 @@ static reloc_howto_type elf32_tic6x_howto_table[] =
         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 */
+        TRUE,                  /* partial_inplace */
+        0x007fff00,            /* src_mask */
         0x007fff00,            /* dst_mask */
         FALSE),                /* pcrel_offset */
   HOWTO (R_C6000_SBR_GOT_L16_W,        /* type */
@@ -323,23 +911,11 @@ static reloc_howto_type elf32_tic6x_howto_table[] =
         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 */
+        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) */
@@ -349,7 +925,7 @@ static reloc_howto_type elf32_tic6x_howto_table[] =
         complain_overflow_unsigned,/* complain_on_overflow */
         bfd_elf_generic_reloc, /* special_function */
         "R_C6000_DSBT_INDEX",  /* name */
-        FALSE,                 /* partial_inplace */
+        TRUE,                  /* partial_inplace */
         0,                     /* src_mask */
         0x007fff00,            /* dst_mask */
         FALSE),                /* pcrel_offset */
@@ -362,7 +938,7 @@ static reloc_howto_type elf32_tic6x_howto_table[] =
         complain_overflow_dont,/* complain_on_overflow */
         bfd_elf_generic_reloc, /* special_function */
         "R_C6000_PREL31",      /* name */
-        FALSE,                 /* partial_inplace */
+        TRUE,                  /* partial_inplace */
         0,                     /* src_mask */
         0x7fffffff,            /* dst_mask */
         FALSE),                /* pcrel_offset */
@@ -375,7 +951,7 @@ static reloc_howto_type elf32_tic6x_howto_table[] =
         complain_overflow_dont,/* complain_on_overflow */
         bfd_elf_generic_reloc, /* special_function */
         "R_C6000_COPY",        /* name */
-        FALSE,                 /* partial_inplace */
+        TRUE,                  /* partial_inplace */
         0,                     /* src_mask */
         0xffffffff,            /* dst_mask */
         FALSE),                /* pcrel_offset */
@@ -614,7 +1190,7 @@ static reloc_howto_type elf32_tic6x_howto_table[] =
         complain_overflow_dont,/* complain_on_overflow */
         bfd_elf_generic_reloc, /* special_function */
         "R_C6000_ALIGN",       /* name */
-        FALSE,                 /* partial_inplace */
+        TRUE,                  /* partial_inplace */
         0,                     /* src_mask */
         0,                     /* dst_mask */
         FALSE),                /* pcrel_offset */
@@ -627,7 +1203,7 @@ static reloc_howto_type elf32_tic6x_howto_table[] =
         complain_overflow_dont,/* complain_on_overflow */
         bfd_elf_generic_reloc, /* special_function */
         "R_C6000_FPHEAD",      /* name */
-        FALSE,                 /* partial_inplace */
+        TRUE,                  /* partial_inplace */
         0,                     /* src_mask */
         0,                     /* dst_mask */
         FALSE),                /* pcrel_offset */
@@ -640,7 +1216,7 @@ static reloc_howto_type elf32_tic6x_howto_table[] =
         complain_overflow_dont,/* complain_on_overflow */
         bfd_elf_generic_reloc, /* special_function */
         "R_C6000_NOCMP",       /* name */
-        FALSE,                 /* partial_inplace */
+        TRUE,                  /* partial_inplace */
         0,                     /* src_mask */
         0,                     /* dst_mask */
         FALSE)                 /* pcrel_offset */
@@ -689,27 +1265,54 @@ static const tic6x_reloc_map elf32_tic6x_reloc_map[] =
   };
 
 static reloc_howto_type *
-elf32_tic6x_reloc_type_lookup (bfd *abfd ATTRIBUTE_UNUSED,
-                              bfd_reloc_code_real_type code)
+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)
-      return &elf32_tic6x_howto_table[elf32_tic6x_reloc_map[i].elf_reloc_val];
+      {
+       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 ATTRIBUTE_UNUSED, const char *r_name)
+elf32_tic6x_reloc_name_lookup (bfd *abfd, const char *r_name)
 {
-  unsigned int i;
+  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); 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];
+      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;
 }
@@ -727,6 +1330,70 @@ elf32_tic6x_info_to_howto (bfd *abfd ATTRIBUTE_UNUSED, arelent *bfd_reloc,
     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,
@@ -761,11 +1428,18 @@ elf32_tic6x_relocate_section (bfd *output_bfd,
       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);
 
-      elf32_tic6x_info_to_howto (input_bfd, &bfd_reloc, rel);
+      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)
        {
@@ -795,19 +1469,24 @@ elf32_tic6x_relocate_section (bfd *output_bfd,
        }
 
       if (sec != NULL && elf_discarded_section (sec))
+       RELOC_AGAINST_DISCARDED_SECTION (info, input_bfd, input_section,
+                                        rel, relend, howto, contents);
+
+      if (info->relocatable)
        {
-         /* For relocs against symbols from removed linkonce sections,
-            or sections discarded by a linker script, we just want the
-            section contents zeroed.  Avoid any special processing.  */
-         _bfd_clear_contents (howto, input_bfd, contents + rel->r_offset);
-         rel->r_info = 0;
-         rel->r_addend = 0;
+         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;
        }
 
-      if (info->relocatable)
-       continue;
-
       switch (r_type)
        {
        case R_C6000_NONE:
@@ -891,6 +1570,7 @@ elf32_tic6x_relocate_section (bfd *output_bfd,
                                    contents, rel->r_offset,
                                    relocation, rel->r_addend);
 
+    done_reloc:
       if (r == bfd_reloc_ok
          && howto->complain_on_overflow == complain_overflow_bitfield)
        {
@@ -978,23 +1658,368 @@ elf32_tic6x_relocate_section (bfd *output_bfd,
   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          _bfd_elf_no_info_to_howto
+#define elf_info_to_howto_rel          elf32_tic6x_info_to_howto_rel
 
 #include "elf32-target.h"
This page took 0.04482 seconds and 4 git commands to generate.