Home | History | Annotate | Line # | Download | only in bfd
      1   1.1  christos /* Freescale XGATE-specific support for 32-bit ELF
      2  1.11  christos    Copyright (C) 2010-2024 Free Software Foundation, Inc.
      3   1.1  christos    Contributed by Sean Keys(skeys (at) ipdatasys.com)
      4   1.1  christos 
      5   1.1  christos    This file is part of BFD, the Binary File Descriptor library.
      6   1.1  christos 
      7   1.1  christos    This program is free software; you can redistribute it and/or modify
      8   1.1  christos    it under the terms of the GNU General Public License as published by
      9   1.1  christos    the Free Software Foundation; either version 3 of the License, or
     10   1.1  christos    (at your option) any later version.
     11   1.1  christos 
     12   1.1  christos    This program is distributed in the hope that it will be useful,
     13   1.1  christos    but WITHOUT ANY WARRANTY; without even the implied warranty of
     14   1.1  christos    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
     15   1.1  christos    GNU General Public License for more details.
     16   1.1  christos 
     17   1.1  christos    You should have received a copy of the GNU General Public License
     18   1.1  christos    along with this program; if not, write to the Free Software
     19   1.1  christos    Foundation, Inc., 51 Franklin Street - Fifth Floor, Boston,
     20   1.1  christos    MA 02110-1301, USA.  */
     21   1.1  christos 
     22   1.1  christos #include "sysdep.h"
     23   1.1  christos #include "bfd.h"
     24   1.1  christos #include "bfdlink.h"
     25   1.1  christos #include "libbfd.h"
     26   1.1  christos #include "elf-bfd.h"
     27   1.1  christos #include "elf/xgate.h"
     28   1.1  christos #include "opcode/xgate.h"
     29   1.1  christos #include "libiberty.h"
     30   1.1  christos 
     31   1.8  christos /* Forward declarations.  */
     32   1.8  christos static bfd_reloc_status_type xgate_elf_ignore_reloc
     33   1.8  christos   (bfd *, arelent *, asymbol *, void *, asection *, bfd *, char **);
     34   1.8  christos static bfd_reloc_status_type xgate_elf_special_reloc
     35   1.8  christos   (bfd *, arelent *, asymbol *, void *, asection *, bfd *, char **);
     36   1.1  christos 
     37   1.1  christos /* Use REL instead of RELA to save space */
     38   1.1  christos #define USE_REL	1
     39   1.1  christos 
     40   1.1  christos static reloc_howto_type elf_xgate_howto_table[] =
     41   1.1  christos {
     42   1.1  christos   /* This reloc does nothing.  */
     43   1.1  christos   HOWTO (R_XGATE_NONE, /* type */
     44   1.1  christos 	 0, /* rightshift */
     45  1.10  christos 	 0, /* size */
     46   1.5  christos 	 0, /* bitsize */
     47  1.10  christos 	 false, /* pc_relative */
     48   1.1  christos 	 0, /* bitpos */
     49   1.1  christos 	 complain_overflow_dont,/* complain_on_overflow */
     50   1.1  christos 	 bfd_elf_generic_reloc, /* special_function */
     51   1.1  christos 	 "R_XGATE_NONE", /* name */
     52  1.10  christos 	 false, /* partial_inplace */
     53   1.1  christos 	 0, /* src_mask */
     54   1.1  christos 	 0, /* dst_mask */
     55  1.10  christos 	 false), /* pcrel_offset */
     56   1.1  christos 
     57   1.1  christos   /* A 8 bit absolute relocation.  */
     58   1.1  christos   HOWTO (R_XGATE_8, /* type */
     59   1.1  christos 	 0, /* rightshift */
     60  1.10  christos 	 1, /* size */
     61   1.1  christos 	 8, /* bitsize */
     62  1.10  christos 	 false, /* pc_relative */
     63   1.1  christos 	 0, /* bitpos */
     64   1.1  christos 	 complain_overflow_bitfield, /* complain_on_overflow */
     65   1.1  christos 	 bfd_elf_generic_reloc, /* special_function */
     66   1.1  christos 	 "R_XGATE_8", /* name */
     67  1.10  christos 	 false, /* partial_inplace */
     68   1.1  christos 	 0x00ff, /* src_mask */
     69   1.1  christos 	 0x00ff, /* dst_mask */
     70  1.10  christos 	 false), /* pcrel_offset */
     71   1.1  christos 
     72   1.1  christos   /* A 8 bit PC-rel relocation.  */
     73   1.1  christos   HOWTO (R_XGATE_PCREL_8, /* type */
     74   1.1  christos 	 0, /* rightshift */
     75  1.10  christos 	 1, /* size */
     76   1.1  christos 	 8, /* bitsize */
     77  1.10  christos 	 true, /* pc_relative */
     78   1.1  christos 	 0, /* bitpos */
     79   1.1  christos 	 complain_overflow_bitfield, /* complain_on_overflow */
     80   1.1  christos 	 bfd_elf_generic_reloc, /* special_function */
     81   1.1  christos 	 "R_XGATE_PCREL_8", /* name */
     82  1.10  christos 	 false, /* partial_inplace */
     83   1.1  christos 	 0x00ff, /* src_mask */
     84   1.1  christos 	 0x00ff, /* dst_mask */
     85  1.10  christos 	 true), /* pcrel_offset */
     86   1.1  christos 
     87   1.1  christos   /* A 16 bit absolute relocation.  */
     88   1.1  christos   HOWTO (R_XGATE_16, /* type */
     89   1.1  christos 	 0, /* rightshift */
     90  1.10  christos 	 2, /* size */
     91   1.1  christos 	 16, /* bitsize */
     92  1.10  christos 	 false, /* pc_relative */
     93   1.1  christos 	 0, /* bitpos */
     94   1.1  christos 	 complain_overflow_dont /*bitfield */, /* complain_on_overflow */
     95   1.1  christos 	 bfd_elf_generic_reloc, /* special_function */
     96   1.1  christos 	 "R_XGATE_16", /* name */
     97  1.10  christos 	 false, /* partial_inplace */
     98   1.1  christos 	 0xffff, /* src_mask */
     99   1.1  christos 	 0xffff, /* dst_mask */
    100  1.10  christos 	 false), /* pcrel_offset */
    101   1.1  christos 
    102   1.1  christos   /* A 32 bit absolute relocation.  This one is never used for the
    103   1.1  christos      code relocation.  It's used by gas for -gstabs generation.  */
    104   1.1  christos   HOWTO (R_XGATE_32, /* type */
    105   1.1  christos 	 0, /* rightshift */
    106  1.10  christos 	 4, /* size */
    107   1.1  christos 	 32, /* bitsize */
    108  1.10  christos 	 false, /* pc_relative */
    109   1.1  christos 	 0, /* bitpos */
    110   1.1  christos 	 complain_overflow_bitfield, /* complain_on_overflow */
    111   1.1  christos 	 bfd_elf_generic_reloc, /* special_function */
    112   1.1  christos 	 "R_XGATE_32", /* name */
    113  1.10  christos 	 false, /* partial_inplace */
    114   1.1  christos 	 0xffffffff, /* src_mask */
    115   1.1  christos 	 0xffffffff, /* dst_mask */
    116  1.10  christos 	 false), /* pcrel_offset */
    117   1.1  christos 
    118   1.1  christos   /* A 16 bit PC-rel relocation.  */
    119   1.1  christos   HOWTO (R_XGATE_PCREL_16, /* type */
    120   1.1  christos 	 0, /* rightshift */
    121  1.10  christos 	 2, /* size */
    122   1.1  christos 	 16, /* bitsize */
    123  1.10  christos 	 true, /* pc_relative */
    124   1.1  christos 	 0, /* bitpos */
    125   1.1  christos 	 complain_overflow_dont, /* complain_on_overflow */
    126   1.1  christos 	 bfd_elf_generic_reloc, /* special_function */
    127   1.1  christos 	 "R_XGATE_PCREL_16", /* name */
    128  1.10  christos 	 false, /* partial_inplace */
    129   1.1  christos 	 0xffff, /* src_mask */
    130   1.1  christos 	 0xffff, /* dst_mask */
    131  1.10  christos 	 true), /* pcrel_offset */
    132   1.1  christos 
    133   1.1  christos   /* GNU extension to record C++ vtable hierarchy.  */
    134   1.1  christos   HOWTO (R_XGATE_GNU_VTINHERIT, /* type */
    135   1.1  christos 	 0, /* rightshift */
    136  1.10  christos 	 2, /* size */
    137   1.1  christos 	 0, /* bitsize */
    138  1.10  christos 	 false, /* pc_relative */
    139   1.1  christos 	 0, /* bitpos */
    140   1.1  christos 	 complain_overflow_dont, /* complain_on_overflow */
    141   1.1  christos 	 NULL, /* special_function */
    142   1.1  christos 	 "R_XGATE_GNU_VTINHERIT", /* name */
    143  1.10  christos 	 false, /* partial_inplace */
    144   1.1  christos 	 0, /* src_mask */
    145   1.1  christos 	 0, /* dst_mask */
    146  1.10  christos 	 false), /* pcrel_offset */
    147   1.1  christos 
    148   1.1  christos   /* GNU extension to record C++ vtable member usage.  */
    149   1.1  christos   HOWTO (R_XGATE_GNU_VTENTRY, /* type */
    150   1.1  christos 	 0, /* rightshift */
    151  1.10  christos 	 2, /* size */
    152   1.1  christos 	 0, /* bitsize */
    153  1.10  christos 	 false, /* pc_relative */
    154   1.1  christos 	 0, /* bitpos */
    155   1.1  christos 	 complain_overflow_dont, /* complain_on_overflow */
    156   1.1  christos 	 _bfd_elf_rel_vtable_reloc_fn, /* special_function */
    157   1.1  christos 	 "R_XGATE_GNU_VTENTRY", /* name */
    158  1.10  christos 	 false, /* partial_inplace */
    159   1.1  christos 	 0, /* src_mask */
    160   1.1  christos 	 0, /* dst_mask */
    161  1.10  christos 	 false), /* pcrel_offset */
    162   1.1  christos 
    163   1.1  christos   /* A 24 bit relocation.  */
    164   1.1  christos   HOWTO (R_XGATE_24, /* type */
    165   1.1  christos 	 0, /* rightshift */
    166  1.10  christos 	 2, /* size */
    167   1.1  christos 	 16, /* bitsize */
    168  1.10  christos 	 false, /* pc_relative */
    169   1.1  christos 	 0, /* bitpos */
    170   1.1  christos 	 complain_overflow_dont, /* complain_on_overflow */
    171   1.1  christos 	 bfd_elf_generic_reloc, /* special_function */
    172   1.1  christos 	 "R_XGATE_IMM8_LO", /* name */
    173  1.10  christos 	 false, /* partial_inplace */
    174   1.1  christos 	 0x00ff, /* src_mask */
    175   1.1  christos 	 0x00ff, /* dst_mask */
    176  1.10  christos 	 false), /* pcrel_offset */
    177   1.1  christos 
    178   1.1  christos   /* A 16-bit low relocation.  */
    179   1.1  christos   HOWTO (R_XGATE_LO16, /* type */
    180   1.1  christos 	 8, /* rightshift */
    181  1.10  christos 	 2, /* size */
    182   1.1  christos 	 16, /* bitsize */
    183  1.10  christos 	 false, /* pc_relative */
    184   1.1  christos 	 0, /* bitpos */
    185   1.1  christos 	 complain_overflow_dont, /* complain_on_overflow */
    186   1.1  christos 	 bfd_elf_generic_reloc, /* special_function */
    187   1.1  christos 	 "R_XGATE_IMM8_HI", /* name */
    188  1.10  christos 	 false, /* partial_inplace */
    189   1.1  christos 	 0x00ff, /* src_mask */
    190   1.1  christos 	 0x00ff, /* dst_mask */
    191  1.10  christos 	 false), /* pcrel_offset */
    192   1.1  christos 
    193   1.1  christos   /* A page relocation.  */
    194   1.1  christos   HOWTO (R_XGATE_GPAGE, /* type */
    195   1.1  christos 	 0, /* rightshift */
    196  1.10  christos 	 1, /* size */
    197   1.1  christos 	 8, /* bitsize */
    198  1.10  christos 	 false, /* pc_relative */
    199   1.1  christos 	 0, /* bitpos */
    200   1.1  christos 	 complain_overflow_dont, /* complain_on_overflow */
    201   1.1  christos 	 xgate_elf_special_reloc,/* special_function */
    202   1.1  christos 	 "R_XGATE_GPAGE", /* name */
    203  1.10  christos 	 false, /* partial_inplace */
    204   1.1  christos 	 0x00ff, /* src_mask */
    205   1.1  christos 	 0x00ff, /* dst_mask */
    206  1.10  christos 	 false), /* pcrel_offset */
    207   1.1  christos 
    208   1.1  christos   /* A 9 bit absolute relocation.   */
    209   1.1  christos   HOWTO (R_XGATE_PCREL_9, /* type */
    210   1.1  christos 	 0, /* rightshift */
    211  1.10  christos 	 2, /* size */
    212   1.1  christos 	 9, /* bitsize */
    213  1.10  christos 	 true, /* pc_relative */
    214   1.1  christos 	 0, /* bitpos */
    215   1.1  christos 	 complain_overflow_bitfield, /* complain_on_overflow */
    216   1.1  christos 	 bfd_elf_generic_reloc, /* special_function */
    217   1.1  christos 	 "R_XGATE_PCREL_9", /* name */
    218  1.10  christos 	 false, /* partial_inplace */
    219   1.1  christos 	 0xffff, /* src_mask */
    220   1.1  christos 	 0xffff, /* dst_mask */
    221  1.10  christos 	 true), /* pcrel_offset */
    222   1.1  christos 
    223   1.1  christos   /* A 8 bit absolute relocation (upper address).  */
    224   1.1  christos   HOWTO (R_XGATE_PCREL_10, /* type */
    225   1.1  christos 	 8, /* rightshift */
    226  1.10  christos 	 1, /* size */
    227   1.1  christos 	 10, /* bitsize */
    228  1.10  christos 	 true, /* pc_relative */
    229   1.1  christos 	 0, /* bitpos */
    230   1.1  christos 	 complain_overflow_dont, /* complain_on_overflow */
    231   1.1  christos 	 bfd_elf_generic_reloc, /* special_function */
    232   1.1  christos 	 "R_XGATE_PCREL_10", /* name */
    233  1.10  christos 	 false, /* partial_inplace */
    234   1.1  christos 	 0x00ff, /* src_mask */
    235   1.1  christos 	 0x00ff, /* dst_mask */
    236  1.10  christos 	 true), /* pcrel_offset */
    237   1.1  christos 
    238   1.1  christos   /* A 8 bit absolute relocation.  */
    239   1.1  christos   HOWTO (R_XGATE_IMM8_LO, /* type */
    240   1.1  christos 	 0, /* rightshift */
    241  1.10  christos 	 2, /* size */
    242   1.1  christos 	 16, /* bitsize */
    243  1.10  christos 	 false, /* pc_relative */
    244   1.1  christos 	 0, /* bitpos */
    245   1.1  christos 	 complain_overflow_dont, /* complain_on_overflow */
    246   1.1  christos 	 bfd_elf_generic_reloc, /* special_function */
    247   1.1  christos 	 "R_XGATE_IMM8_LO", /* name */
    248  1.10  christos 	 false, /* partial_inplace */
    249   1.1  christos 	 0xffff, /* src_mask */
    250   1.1  christos 	 0xffff, /* dst_mask */
    251  1.10  christos 	 false), /* pcrel_offset */
    252   1.1  christos 
    253   1.1  christos   /* A 16 bit absolute relocation (upper address).  */
    254   1.1  christos   HOWTO (R_XGATE_IMM8_HI, /* type */
    255   1.1  christos 	 8, /* rightshift */
    256  1.10  christos 	 2, /* size */
    257   1.1  christos 	 16, /* bitsize */
    258  1.10  christos 	 false, /* pc_relative */
    259   1.1  christos 	 0, /* bitpos */
    260   1.1  christos 	 complain_overflow_dont, /* complain_on_overflow */
    261   1.1  christos 	 bfd_elf_generic_reloc, /* special_function */
    262   1.1  christos 	 "R_XGATE_IMM8_HI", /* name */
    263  1.10  christos 	 false, /* partial_inplace */
    264   1.1  christos 	 0x00ff, /* src_mask */
    265   1.1  christos 	 0x00ff, /* dst_mask */
    266  1.10  christos 	 false), /* pcrel_offset */
    267   1.1  christos 
    268   1.1  christos   /* A 3 bit absolute relocation.  */
    269   1.1  christos   HOWTO (R_XGATE_IMM3, /* type */
    270   1.1  christos 	 8, /* rightshift */
    271  1.10  christos 	 2, /* size */
    272   1.1  christos 	 16, /* bitsize */
    273  1.10  christos 	 false, /* pc_relative */
    274   1.1  christos 	 0, /* bitpos */
    275   1.1  christos 	 complain_overflow_dont, /* complain_on_overflow */
    276   1.1  christos 	 bfd_elf_generic_reloc, /* special_function */
    277   1.1  christos 	 "R_XGATE_IMM3", /* name */
    278  1.10  christos 	 false, /* partial_inplace */
    279   1.1  christos 	 0x00ff, /* src_mask */
    280   1.1  christos 	 0x00ff, /* dst_mask */
    281  1.10  christos 	 false), /* pcrel_offset */
    282   1.1  christos 
    283   1.1  christos   /* A 4 bit absolute relocation.  */
    284   1.1  christos   HOWTO (R_XGATE_IMM4, /* type */
    285   1.1  christos 	 8, /* rightshift */
    286  1.10  christos 	 2, /* size */
    287   1.1  christos 	 16, /* bitsize */
    288  1.10  christos 	 false, /* pc_relative */
    289   1.1  christos 	 0, /* bitpos */
    290   1.1  christos 	 complain_overflow_dont, /* complain_on_overflow */
    291   1.1  christos 	 bfd_elf_generic_reloc, /* special_function */
    292   1.1  christos 	 "R_XGATE_IMM4", /* name */
    293  1.10  christos 	 false, /* partial_inplace */
    294   1.1  christos 	 0x00ff, /* src_mask */
    295   1.1  christos 	 0x00ff, /* dst_mask */
    296  1.10  christos 	 false), /* pcrel_offset */
    297   1.1  christos 
    298   1.1  christos   /* A 5 bit absolute relocation.  */
    299   1.1  christos   HOWTO (R_XGATE_IMM5, /* type */
    300   1.1  christos 	 8, /* rightshift */
    301  1.10  christos 	 2, /* size */
    302   1.1  christos 	 16, /* bitsize */
    303  1.10  christos 	 false, /* pc_relative */
    304   1.1  christos 	 0, /* bitpos */
    305   1.1  christos 	 complain_overflow_dont, /* complain_on_overflow */
    306   1.1  christos 	 bfd_elf_generic_reloc, /* special_function */
    307   1.1  christos 	 "R_XGATE_IMM5", /* name */
    308  1.10  christos 	 false, /* partial_inplace */
    309   1.1  christos 	 0x00ff, /* src_mask */
    310   1.1  christos 	 0x00ff, /* dst_mask */
    311  1.10  christos 	 false), /* pcrel_offset */
    312   1.1  christos 
    313   1.1  christos   /* Mark beginning of a jump instruction (any form).  */
    314   1.1  christos   HOWTO (R_XGATE_RL_JUMP, /* type */
    315   1.1  christos 	 0, /* rightshift */
    316  1.10  christos 	 2, /* size */
    317   1.1  christos 	 0, /* bitsize */
    318  1.10  christos 	 false, /* pc_relative */
    319   1.1  christos 	 0, /* bitpos */
    320   1.1  christos 	 complain_overflow_dont, /* complain_on_overflow */
    321   1.1  christos 	 xgate_elf_ignore_reloc, /* special_function */
    322   1.1  christos 	 "R_XGATE_RL_JUMP", /* name */
    323  1.10  christos 	 true, /* partial_inplace */
    324   1.1  christos 	 0, /* src_mask */
    325   1.1  christos 	 0, /* dst_mask */
    326  1.10  christos 	 true), /* pcrel_offset */
    327   1.1  christos 
    328   1.1  christos   /* Mark beginning of Gcc relaxation group instruction.  */
    329   1.1  christos   HOWTO (R_XGATE_RL_GROUP, /* type */
    330   1.1  christos 	 0, /* rightshift */
    331  1.10  christos 	 2, /* size */
    332   1.1  christos 	 0, /* bitsize */
    333  1.10  christos 	 false, /* pc_relative */
    334   1.1  christos 	 0, /* bitpos */
    335   1.1  christos 	 complain_overflow_dont, /* complain_on_overflow */
    336   1.1  christos 	 xgate_elf_ignore_reloc, /* special_function */
    337   1.1  christos 	 "R_XGATE_RL_GROUP", /* name */
    338  1.10  christos 	 true, /* partial_inplace */
    339   1.1  christos 	 0, /* src_mask */
    340   1.1  christos 	 0, /* dst_mask */
    341  1.10  christos 	 true), /* pcrel_offset */
    342   1.1  christos };
    343   1.1  christos 
    344   1.1  christos /* Map BFD reloc types to XGATE ELF reloc types.  */
    345   1.1  christos 
    346   1.1  christos struct xgate_reloc_map
    347   1.1  christos {
    348   1.1  christos   bfd_reloc_code_real_type bfd_reloc_val;
    349   1.1  christos   unsigned char elf_reloc_val;
    350   1.1  christos };
    351   1.1  christos 
    352   1.1  christos static const struct xgate_reloc_map xgate_reloc_map[] =
    353   1.1  christos {
    354   1.1  christos   {BFD_RELOC_NONE, R_XGATE_NONE},
    355   1.1  christos   {BFD_RELOC_8, R_XGATE_8},
    356   1.1  christos   {BFD_RELOC_8_PCREL, R_XGATE_PCREL_8},
    357   1.1  christos   {BFD_RELOC_16_PCREL, R_XGATE_PCREL_16},
    358   1.1  christos   {BFD_RELOC_16, R_XGATE_16},
    359   1.1  christos   {BFD_RELOC_32, R_XGATE_32},
    360   1.1  christos 
    361   1.1  christos   {BFD_RELOC_VTABLE_INHERIT, R_XGATE_GNU_VTINHERIT},
    362   1.1  christos   {BFD_RELOC_VTABLE_ENTRY, R_XGATE_GNU_VTENTRY},
    363   1.1  christos 
    364   1.1  christos   {BFD_RELOC_XGATE_LO16, R_XGATE_LO16},
    365   1.1  christos   {BFD_RELOC_XGATE_GPAGE, R_XGATE_GPAGE},
    366   1.1  christos   {BFD_RELOC_XGATE_24, R_XGATE_24},
    367   1.1  christos   {BFD_RELOC_XGATE_PCREL_9, R_XGATE_PCREL_9},
    368   1.1  christos   {BFD_RELOC_XGATE_PCREL_10,  R_XGATE_PCREL_10},
    369   1.1  christos   {BFD_RELOC_XGATE_IMM8_LO, R_XGATE_IMM8_LO},
    370   1.1  christos   {BFD_RELOC_XGATE_IMM8_HI, R_XGATE_IMM8_HI},
    371   1.1  christos   {BFD_RELOC_XGATE_IMM3, R_XGATE_IMM3},
    372   1.1  christos   {BFD_RELOC_XGATE_IMM4, R_XGATE_IMM4},
    373   1.1  christos   {BFD_RELOC_XGATE_IMM5, R_XGATE_IMM5},
    374   1.1  christos 
    375   1.1  christos   {BFD_RELOC_XGATE_RL_JUMP, R_XGATE_RL_JUMP},
    376   1.1  christos   {BFD_RELOC_XGATE_RL_GROUP, R_XGATE_RL_GROUP},
    377   1.1  christos };
    378   1.1  christos 
    379   1.1  christos static reloc_howto_type *
    380   1.1  christos bfd_elf32_bfd_reloc_type_lookup (bfd *abfd ATTRIBUTE_UNUSED,
    381   1.1  christos 				 bfd_reloc_code_real_type code)
    382   1.1  christos {
    383   1.1  christos   unsigned int i;
    384   1.1  christos 
    385   1.1  christos   for (i = 0; i < ARRAY_SIZE (xgate_reloc_map); i++)
    386   1.1  christos     if (xgate_reloc_map[i].bfd_reloc_val == code)
    387   1.1  christos       return &elf_xgate_howto_table[xgate_reloc_map[i].elf_reloc_val];
    388   1.9  christos 
    389   1.1  christos   return NULL;
    390   1.1  christos }
    391   1.1  christos 
    392   1.1  christos static reloc_howto_type *
    393   1.1  christos bfd_elf32_bfd_reloc_name_lookup (bfd *abfd ATTRIBUTE_UNUSED, const char *r_name)
    394   1.1  christos {
    395   1.1  christos   unsigned int i;
    396   1.1  christos 
    397   1.1  christos   for (i = 0; i < ARRAY_SIZE (elf_xgate_howto_table); i++)
    398   1.1  christos     if (elf_xgate_howto_table[i].name != NULL
    399   1.8  christos 	&& strcasecmp (elf_xgate_howto_table[i].name, r_name) == 0)
    400   1.1  christos       return &elf_xgate_howto_table[i];
    401   1.1  christos 
    402   1.1  christos   return NULL;
    403   1.1  christos }
    404   1.1  christos 
    405   1.1  christos /* Set the howto pointer for an XGATE ELF reloc.  */
    406   1.1  christos 
    407  1.10  christos static bool
    408   1.8  christos xgate_info_to_howto_rel (bfd *abfd,
    409   1.1  christos 			 arelent *cache_ptr,
    410   1.1  christos 			 Elf_Internal_Rela *dst)
    411   1.1  christos {
    412   1.1  christos   unsigned int r_type;
    413   1.1  christos 
    414   1.1  christos   r_type = ELF32_R_TYPE (dst->r_info);
    415   1.3  christos   if (r_type >= (unsigned int) R_XGATE_max)
    416   1.3  christos     {
    417   1.7  christos       /* xgettext:c-format */
    418   1.8  christos       _bfd_error_handler (_("%pB: unsupported relocation type %#x"),
    419   1.8  christos 			  abfd, r_type);
    420   1.8  christos       bfd_set_error (bfd_error_bad_value);
    421  1.10  christos       return false;
    422   1.3  christos     }
    423   1.1  christos   cache_ptr->howto = &elf_xgate_howto_table[r_type];
    424  1.10  christos   return true;
    425   1.1  christos }
    426   1.1  christos 
    427   1.1  christos /* Specific sections:
    428   1.1  christos  - The .page0 is a data section that is mapped in [0x0000..0x00FF].
    429   1.1  christos    Page0 accesses are faster on the M68HC12.
    430   1.1  christos  - The .vectors is the section that represents the interrupt
    431   1.1  christos    vectors.
    432   1.1  christos  - The .xgate section is starts in 0xE08800 or as xgate sees it 0x0800. */
    433   1.1  christos static const struct bfd_elf_special_section elf32_xgate_special_sections[] =
    434   1.1  christos {
    435   1.1  christos   { STRING_COMMA_LEN (".eeprom"), 0, SHT_PROGBITS, SHF_ALLOC + SHF_WRITE },
    436   1.1  christos   { STRING_COMMA_LEN (".page0"), 0, SHT_PROGBITS, SHF_ALLOC + SHF_WRITE },
    437   1.1  christos   { STRING_COMMA_LEN (".softregs"), 0, SHT_NOBITS, SHF_ALLOC + SHF_WRITE },
    438   1.1  christos   { STRING_COMMA_LEN (".vectors"), 0, SHT_PROGBITS, SHF_ALLOC },
    439   1.1  christos /*{ STRING_COMMA_LEN (".xgate"),    0, SHT_PROGBITS, SHF_ALLOC + SHF_WRITE },
    440   1.1  christos   TODO finish this implementation */
    441   1.1  christos   { NULL, 0, 0, 0, 0 }
    442   1.1  christos };
    443   1.1  christos 
    444   1.8  christos /* Hook called when reading symbols. */
    445   1.1  christos 
    446   1.8  christos static void
    447   1.8  christos elf32_xgate_backend_symbol_processing (bfd *abfd ATTRIBUTE_UNUSED,
    448   1.8  christos 				       asymbol *sym)
    449   1.1  christos {
    450   1.8  christos   /* Mark xgate symbols.  */
    451   1.8  christos   ((elf_symbol_type *) sym)->internal_elf_sym.st_target_internal = 1;
    452   1.1  christos }
    453   1.1  christos 
    454   1.1  christos /* This function is used for relocs which are only used for relaxing,
    455   1.1  christos    which the linker should otherwise ignore.  */
    456   1.1  christos 
    457   1.8  christos static bfd_reloc_status_type
    458   1.1  christos xgate_elf_ignore_reloc (bfd *abfd ATTRIBUTE_UNUSED,
    459   1.1  christos 			arelent *reloc_entry,
    460   1.1  christos 			asymbol *symbol ATTRIBUTE_UNUSED,
    461   1.1  christos 			void *data ATTRIBUTE_UNUSED,
    462   1.1  christos 			asection *input_section,
    463   1.1  christos 			bfd *output_bfd,
    464   1.1  christos 			char **error_message ATTRIBUTE_UNUSED)
    465   1.1  christos {
    466   1.1  christos   if (output_bfd != NULL)
    467   1.1  christos     reloc_entry->address += input_section->output_offset;
    468   1.1  christos   return bfd_reloc_ok;
    469   1.1  christos }
    470   1.1  christos 
    471   1.8  christos static bfd_reloc_status_type
    472   1.1  christos xgate_elf_special_reloc (bfd *abfd ATTRIBUTE_UNUSED,
    473   1.1  christos 			 arelent *reloc_entry ATTRIBUTE_UNUSED,
    474   1.1  christos 			 asymbol *symbol ATTRIBUTE_UNUSED,
    475   1.1  christos 			 void *data ATTRIBUTE_UNUSED,
    476   1.1  christos 			 asection *input_section ATTRIBUTE_UNUSED,
    477   1.1  christos 			 bfd *output_bfd ATTRIBUTE_UNUSED,
    478   1.1  christos 			 char **error_message ATTRIBUTE_UNUSED)
    479   1.1  christos {
    480   1.1  christos   abort ();
    481   1.1  christos }
    482   1.1  christos 
    483  1.10  christos static bool
    484   1.1  christos _bfd_xgate_elf_print_private_bfd_data (bfd *abfd, void *ptr)
    485   1.1  christos {
    486   1.1  christos   FILE *file = (FILE *) ptr;
    487   1.1  christos 
    488   1.1  christos   BFD_ASSERT (abfd != NULL && ptr != NULL);
    489   1.1  christos 
    490   1.1  christos   /* Print normal ELF private data.  */
    491   1.1  christos   _bfd_elf_print_private_bfd_data (abfd, ptr);
    492   1.1  christos 
    493   1.1  christos   /* xgettext:c-format */
    494   1.1  christos   fprintf (file, _("private flags = %lx:"), elf_elfheader (abfd)->e_flags);
    495   1.1  christos 
    496   1.1  christos   if (elf_elfheader (abfd)->e_flags & E_XGATE_I32)
    497   1.1  christos     fprintf (file, _("[abi=32-bit int, "));
    498   1.1  christos   else
    499   1.1  christos     fprintf (file, _("[abi=16-bit int, "));
    500   1.1  christos 
    501   1.1  christos   if (elf_elfheader (abfd)->e_flags & E_XGATE_F64)
    502   1.1  christos     fprintf (file, _("64-bit double, "));
    503   1.1  christos   else
    504   1.1  christos     fprintf (file, _("32-bit double, "));
    505   1.1  christos   if (elf_elfheader (abfd)->e_flags & EF_XGATE_MACH)
    506   1.1  christos     fprintf (file, _("cpu=XGATE]"));
    507   1.1  christos   else
    508   1.1  christos     fprintf (file, _("error reading cpu type from elf private data"));
    509   1.1  christos   fputc ('\n', file);
    510   1.1  christos 
    511  1.10  christos   return true;
    512   1.1  christos }
    513   1.1  christos 
    514   1.8  christos #define ELF_ARCH			     bfd_arch_xgate
    515   1.8  christos #define ELF_MACHINE_CODE		     EM_XGATE
    516   1.1  christos 
    517   1.8  christos #define ELF_MAXPAGESIZE			     0x1000
    518   1.1  christos 
    519   1.8  christos #define TARGET_BIG_SYM			     xgate_elf32_vec
    520   1.8  christos #define TARGET_BIG_NAME			     "elf32-xgate"
    521   1.1  christos 
    522   1.8  christos #define elf_info_to_howto_rel		     xgate_info_to_howto_rel
    523   1.8  christos #define elf_backend_special_sections	     elf32_xgate_special_sections
    524   1.8  christos #define elf_backend_symbol_processing	     elf32_xgate_backend_symbol_processing
    525   1.1  christos #define bfd_elf32_bfd_print_private_bfd_data _bfd_xgate_elf_print_private_bfd_data
    526   1.1  christos 
    527   1.1  christos #include "elf32-target.h"
    528