Home | History | Annotate | Line # | Download | only in bfd
coff-z80.c revision 1.12
      1   1.1  christos /* BFD back-end for Zilog Z80 COFF binaries.
      2  1.11  christos    Copyright (C) 2005-2024 Free Software Foundation, Inc.
      3   1.1  christos    Contributed by Arnold Metselaar <arnold_m (at) operamail.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 "libbfd.h"
     25   1.1  christos #include "bfdlink.h"
     26   1.1  christos #include "coff/z80.h"
     27   1.1  christos #include "coff/internal.h"
     28   1.1  christos #include "libcoff.h"
     29   1.9  christos #include "libiberty.h"
     30   1.1  christos 
     31   1.1  christos #define COFF_DEFAULT_SECTION_ALIGNMENT_POWER 0
     32   1.1  christos 
     33  1.10  christos typedef const struct {
     34   1.9  christos   bfd_reloc_code_real_type r_type;
     35   1.9  christos   reloc_howto_type howto;
     36   1.9  christos } bfd_howto_type;
     37   1.1  christos 
     38   1.9  christos #define BFD_EMPTY_HOWTO(rt,x) {rt, EMPTY_HOWTO(x)}
     39   1.9  christos #define BFD_HOWTO(rt,a,b,c,d,e,f,g,h,i,j,k,l,m) {rt, HOWTO(a,b,c,d,e,f,g,h,i,j,k,l,m)}
     40   1.9  christos 
     41   1.9  christos static bfd_howto_type howto_table[] =
     42   1.9  christos {
     43   1.9  christos   BFD_EMPTY_HOWTO (BFD_RELOC_NONE, 0),
     44   1.9  christos 
     45   1.9  christos   BFD_HOWTO (BFD_RELOC_32,
     46   1.9  christos      R_IMM32,		/* type */
     47   1.9  christos      0,			/* rightshift */
     48  1.10  christos      4,			/* size */
     49   1.9  christos      32,		/* bitsize */
     50  1.10  christos      false,		/* pc_relative */
     51   1.9  christos      0,			/* bitpos */
     52   1.9  christos      complain_overflow_bitfield, /* complain_on_overflow */
     53   1.9  christos      0,			/* special_function */
     54   1.9  christos      "r_imm32",		/* name */
     55  1.10  christos      false,		/* partial_inplace */
     56   1.9  christos      0xffffffff,	/* src_mask */
     57   1.9  christos      0xffffffff,	/* dst_mask */
     58  1.10  christos      false),		/* pcrel_offset */
     59   1.9  christos 
     60   1.9  christos   BFD_HOWTO (BFD_RELOC_24,
     61   1.9  christos      R_IMM24,		/* type */
     62   1.9  christos      0,			/* rightshift */
     63  1.10  christos      3,			/* size */
     64   1.9  christos      24,		/* bitsize */
     65  1.10  christos      false,		/* pc_relative */
     66   1.9  christos      0,			/* bitpos */
     67   1.9  christos      complain_overflow_bitfield, /* complain_on_overflow */
     68   1.9  christos      0,			/* special_function */
     69   1.9  christos      "r_imm24",		/* name */
     70  1.10  christos      false,		/* partial_inplace */
     71   1.9  christos      0x00ffffff,	/* src_mask */
     72   1.9  christos      0x00ffffff,	/* dst_mask */
     73  1.10  christos      false),		/* pcrel_offset */
     74   1.9  christos 
     75   1.9  christos   BFD_HOWTO (BFD_RELOC_16,
     76   1.9  christos      R_IMM16,		/* type */
     77   1.9  christos      0,			/* rightshift */
     78  1.10  christos      2,			/* size */
     79   1.9  christos      16,		/* bitsize */
     80  1.10  christos      false,		/* pc_relative */
     81   1.9  christos      0,			/* bitpos */
     82   1.9  christos      complain_overflow_bitfield, /* complain_on_overflow */
     83   1.9  christos      0,			/* special_function */
     84   1.9  christos      "r_imm16",		/* name */
     85  1.10  christos      false,		/* partial_inplace */
     86   1.9  christos      0x0000ffff,	/* src_mask */
     87   1.9  christos      0x0000ffff,	/* dst_mask */
     88  1.10  christos      false),		/* pcrel_offset */
     89   1.9  christos 
     90   1.9  christos   BFD_HOWTO (BFD_RELOC_8,
     91   1.9  christos      R_IMM8,		/* type */
     92   1.9  christos      0,			/* rightshift */
     93  1.10  christos      1,			/* size */
     94   1.9  christos      8,			/* bitsize */
     95  1.10  christos      false,		/* pc_relative */
     96   1.9  christos      0,			/* bitpos */
     97   1.9  christos      complain_overflow_bitfield, /* complain_on_overflow */
     98   1.9  christos      0,			/* special_function */
     99   1.9  christos      "r_imm8",		/* name */
    100  1.10  christos      false,		/* partial_inplace */
    101   1.9  christos      0x000000ff,	/* src_mask */
    102   1.9  christos      0x000000ff,	/* dst_mask */
    103  1.10  christos      false),		/* pcrel_offset */
    104   1.9  christos 
    105   1.9  christos   BFD_HOWTO (BFD_RELOC_8_PCREL,
    106   1.9  christos      R_JR,		/* type */
    107   1.9  christos      0,			/* rightshift */
    108  1.10  christos      1,			/* size */
    109   1.9  christos      8,			/* bitsize */
    110  1.10  christos      true,		/* pc_relative */
    111   1.9  christos      0,			/* bitpos */
    112   1.9  christos      complain_overflow_signed, /* complain_on_overflow */
    113   1.9  christos      0,			/* special_function */
    114   1.9  christos      "r_jr",		/* name */
    115  1.10  christos      false,		/* partial_inplace */
    116   1.9  christos      0,			/* src_mask */
    117   1.9  christos      0xFF,		/* dst_mask */
    118  1.10  christos      true),		/* pcrel_offset */
    119   1.9  christos 
    120   1.9  christos   BFD_HOWTO (BFD_RELOC_Z80_DISP8,
    121   1.9  christos      R_OFF8,		/* type */
    122   1.9  christos      0,			/* rightshift */
    123  1.10  christos      1,			/* size */
    124   1.9  christos      8,			/* bitsize */
    125  1.10  christos      false,		/* pc_relative */
    126   1.9  christos      0,			/* bitpos */
    127   1.9  christos      complain_overflow_signed, /* complain_on_overflow */
    128   1.9  christos      0,			/* special_function */
    129   1.9  christos      "r_off8",		/* name */
    130  1.10  christos      false,		/* partial_inplace */
    131   1.9  christos      0,			/* src_mask */
    132   1.9  christos      0xff,		/* dst_mask */
    133  1.10  christos      false),		/* pcrel_offset */
    134   1.9  christos 
    135   1.9  christos   BFD_HOWTO (BFD_RELOC_Z80_BYTE0,
    136   1.9  christos      R_BYTE0,		/* type */
    137   1.9  christos      0,			/* rightshift */
    138  1.10  christos      1,			/* size */
    139   1.9  christos      8,			/* bitsize */
    140  1.10  christos      false,		/* pc_relative */
    141   1.9  christos      0,			/* bitpos */
    142   1.9  christos      complain_overflow_dont, /* complain_on_overflow */
    143   1.9  christos      0,			/* special_function */
    144   1.9  christos      "r_byte0",		/* name */
    145  1.10  christos      false,		/* partial_inplace */
    146   1.9  christos      0,			/* src_mask */
    147   1.9  christos      0xff,		/* dst_mask */
    148  1.10  christos      false),		/* pcrel_offset */
    149   1.9  christos 
    150   1.9  christos   BFD_HOWTO (BFD_RELOC_Z80_BYTE1,
    151   1.9  christos      R_BYTE1,		/* type */
    152   1.9  christos      8,			/* rightshift */
    153  1.10  christos      1,			/* size */
    154   1.9  christos      8,			/* bitsize */
    155  1.10  christos      false,		/* pc_relative */
    156   1.9  christos      0,			/* bitpos */
    157   1.9  christos      complain_overflow_dont, /* complain_on_overflow */
    158   1.9  christos      0,			/* special_function */
    159   1.9  christos      "r_byte1",		/* name */
    160  1.10  christos      false,		/* partial_inplace */
    161   1.9  christos      0,			/* src_mask */
    162   1.9  christos      0xff,		/* dst_mask */
    163  1.10  christos      false),		/* pcrel_offset */
    164   1.9  christos 
    165   1.9  christos   BFD_HOWTO (BFD_RELOC_Z80_BYTE2,
    166   1.9  christos      R_BYTE2,		/* type */
    167   1.9  christos      16,		/* rightshift */
    168  1.10  christos      1,			/* size */
    169   1.9  christos      8,			/* bitsize */
    170  1.10  christos      false,		/* pc_relative */
    171   1.9  christos      0,			/* bitpos */
    172   1.9  christos      complain_overflow_dont, /* complain_on_overflow */
    173   1.9  christos      0,			/* special_function */
    174   1.9  christos      "r_byte2",		/* name */
    175  1.10  christos      false,		/* partial_inplace */
    176   1.9  christos      0,			/* src_mask */
    177   1.9  christos      0xff,		/* dst_mask */
    178  1.10  christos      false),		/* pcrel_offset */
    179   1.9  christos 
    180   1.9  christos   BFD_HOWTO (BFD_RELOC_Z80_BYTE3,
    181   1.9  christos      R_BYTE3,		/* type */
    182   1.9  christos      24,		/* rightshift */
    183  1.10  christos      1,			/* size */
    184   1.9  christos      8,			/* bitsize */
    185  1.10  christos      false,		/* pc_relative */
    186   1.9  christos      0,			/* bitpos */
    187   1.9  christos      complain_overflow_dont, /* complain_on_overflow */
    188   1.9  christos      0,			/* special_function */
    189   1.9  christos      "r_byte3",		/* name */
    190  1.10  christos      false,		/* partial_inplace */
    191   1.9  christos      0,			/* src_mask */
    192   1.9  christos      0xff,		/* dst_mask */
    193  1.10  christos      false),		/* pcrel_offset */
    194   1.9  christos 
    195   1.9  christos   BFD_HOWTO (BFD_RELOC_Z80_WORD0,
    196   1.9  christos      R_WORD0,		/* type */
    197   1.9  christos      0,			/* rightshift */
    198  1.10  christos      2,			/* size */
    199   1.9  christos      16,		/* bitsize */
    200  1.10  christos      false,		/* pc_relative */
    201   1.9  christos      0,			/* bitpos */
    202   1.9  christos      complain_overflow_dont, /* complain_on_overflow */
    203   1.9  christos      0,			/* special_function */
    204   1.9  christos      "r_word0",		/* name */
    205  1.10  christos      false,		/* partial_inplace */
    206   1.9  christos      0,			/* src_mask */
    207   1.9  christos      0xffff,		/* dst_mask */
    208  1.10  christos      false),		/* pcrel_offset */
    209   1.9  christos 
    210   1.9  christos   BFD_HOWTO (BFD_RELOC_Z80_WORD1,
    211   1.9  christos      R_WORD1,		/* type */
    212   1.9  christos      16,		/* rightshift */
    213  1.10  christos      2,			/* size */
    214   1.9  christos      16,		/* bitsize */
    215  1.10  christos      false,		/* pc_relative */
    216   1.9  christos      0,			/* bitpos */
    217   1.9  christos      complain_overflow_dont, /* complain_on_overflow */
    218   1.9  christos      0,			/* special_function */
    219   1.9  christos      "r_word1",		/* name */
    220  1.10  christos      false,		/* partial_inplace */
    221   1.9  christos      0,			/* src_mask */
    222   1.9  christos      0xffff,		/* dst_mask */
    223  1.10  christos      false),		/* pcrel_offset */
    224   1.9  christos 
    225   1.9  christos   BFD_HOWTO (BFD_RELOC_Z80_16_BE,
    226   1.9  christos      R_IMM16BE,		/* type */
    227   1.9  christos      0,			/* rightshift */
    228  1.10  christos      2,			/* size */
    229   1.9  christos      16,		/* bitsize */
    230  1.10  christos      false,		/* pc_relative */
    231   1.9  christos      0,			/* bitpos */
    232   1.9  christos      complain_overflow_bitfield, /* complain_on_overflow */
    233   1.9  christos      0,			/* special_function */
    234   1.9  christos      "r_imm16be",	/* name */
    235  1.10  christos      false,		/* partial_inplace */
    236   1.9  christos      0x0000ffff,	/* src_mask */
    237   1.9  christos      0x0000ffff,	/* dst_mask */
    238  1.10  christos      false),		/* pcrel_offset */
    239   1.9  christos };
    240   1.9  christos 
    241   1.9  christos #define NUM_HOWTOS ARRAY_SIZE (howto_table)
    242   1.1  christos 
    243   1.1  christos #define BADMAG(x) Z80BADMAG(x)
    244   1.1  christos #define Z80 1			/* Customize coffcode.h.  */
    245   1.1  christos #define __A_MAGIC_SET__
    246   1.1  christos 
    247   1.1  christos /* Code to swap in the reloc.  */
    248   1.1  christos 
    249   1.1  christos #define SWAP_IN_RELOC_OFFSET	H_GET_32
    250   1.1  christos #define SWAP_OUT_RELOC_OFFSET	H_PUT_32
    251   1.1  christos 
    252   1.1  christos #define SWAP_OUT_RELOC_EXTRA(abfd, src, dst) \
    253   1.1  christos   dst->r_stuff[0] = 'S'; \
    254   1.1  christos   dst->r_stuff[1] = 'C';
    255   1.1  christos 
    256   1.1  christos /* Code to turn a r_type into a howto ptr, uses the above howto table.  */
    257   1.1  christos static void
    258   1.1  christos rtype2howto (arelent *internal, struct internal_reloc *dst)
    259   1.1  christos {
    260   1.9  christos   unsigned i;
    261   1.9  christos   for (i = 0; i < NUM_HOWTOS; i++)
    262   1.1  christos     {
    263   1.9  christos       if (howto_table[i].howto.type == dst->r_type)
    264   1.9  christos         {
    265   1.9  christos           internal->howto = &howto_table[i].howto;
    266   1.9  christos           return;
    267   1.9  christos         }
    268   1.1  christos     }
    269   1.9  christos   internal->howto = NULL;
    270   1.1  christos }
    271   1.1  christos 
    272   1.1  christos #define RTYPE2HOWTO(internal, relocentry) rtype2howto (internal, relocentry)
    273   1.1  christos 
    274   1.1  christos static reloc_howto_type *
    275   1.1  christos coff_z80_reloc_type_lookup (bfd *abfd ATTRIBUTE_UNUSED,
    276   1.1  christos 			    bfd_reloc_code_real_type code)
    277   1.1  christos {
    278   1.9  christos   unsigned i;
    279   1.9  christos   for (i = 0; i < NUM_HOWTOS; i++)
    280   1.9  christos     if (howto_table[i].r_type == code)
    281   1.9  christos       return &howto_table[i].howto;
    282   1.9  christos 
    283   1.9  christos   BFD_FAIL ();
    284   1.9  christos   return NULL;
    285   1.1  christos }
    286   1.1  christos 
    287   1.1  christos static reloc_howto_type *
    288   1.1  christos coff_z80_reloc_name_lookup (bfd *abfd ATTRIBUTE_UNUSED,
    289   1.1  christos 			    const char *r_name)
    290   1.1  christos {
    291   1.9  christos   unsigned i;
    292   1.9  christos   for (i = 0; i < NUM_HOWTOS; i++)
    293   1.9  christos     if (strcasecmp(howto_table[i].howto.name, r_name) == 0)
    294   1.9  christos       return &howto_table[i].howto;
    295   1.1  christos 
    296   1.1  christos   return NULL;
    297   1.1  christos }
    298   1.1  christos 
    299   1.1  christos /* Perform any necessary magic to the addend in a reloc entry.  */
    300   1.1  christos 
    301   1.1  christos #define CALC_ADDEND(abfd, symbol, ext_reloc, cache_ptr) \
    302   1.1  christos  cache_ptr->addend =  ext_reloc.r_offset;
    303   1.1  christos 
    304   1.1  christos #define RELOC_PROCESSING(relent,reloc,symbols,abfd,section) \
    305   1.1  christos  reloc_processing(relent, reloc, symbols, abfd, section)
    306   1.1  christos 
    307   1.1  christos static void
    308   1.1  christos reloc_processing (arelent *relent,
    309   1.8  christos 		  struct internal_reloc *reloc,
    310   1.8  christos 		  asymbol **symbols,
    311   1.8  christos 		  bfd *abfd,
    312   1.8  christos 		  asection *section)
    313   1.1  christos {
    314   1.1  christos   relent->address = reloc->r_vaddr;
    315   1.1  christos   rtype2howto (relent, reloc);
    316   1.1  christos 
    317  1.10  christos   if (reloc->r_symndx == -1 || symbols == NULL)
    318  1.12  christos     relent->sym_ptr_ptr = &bfd_abs_section_ptr->symbol;
    319  1.10  christos   else if (reloc->r_symndx >= 0 && reloc->r_symndx < obj_conv_table_size (abfd))
    320   1.1  christos     relent->sym_ptr_ptr = symbols + obj_convert (abfd)[reloc->r_symndx];
    321   1.1  christos   else
    322  1.10  christos     {
    323  1.10  christos       _bfd_error_handler
    324  1.10  christos 	/* xgettext:c-format */
    325  1.10  christos 	(_("%pB: warning: illegal symbol index %ld in relocs"),
    326  1.10  christos 	 abfd, reloc->r_symndx);
    327  1.12  christos       relent->sym_ptr_ptr = &bfd_abs_section_ptr->symbol;
    328  1.10  christos     }
    329   1.1  christos   relent->addend = reloc->r_offset;
    330   1.1  christos   relent->address -= section->vma;
    331   1.1  christos }
    332   1.1  christos 
    333  1.11  christos static bool
    334   1.1  christos extra_case (bfd *in_abfd,
    335   1.8  christos 	    struct bfd_link_info *link_info,
    336   1.8  christos 	    struct bfd_link_order *link_order,
    337   1.8  christos 	    arelent *reloc,
    338   1.8  christos 	    bfd_byte *data,
    339  1.11  christos 	    size_t *src_ptr,
    340  1.11  christos 	    size_t *dst_ptr)
    341   1.1  christos {
    342   1.1  christos   asection * input_section = link_order->u.indirect.section;
    343  1.11  christos   bfd_size_type end = bfd_get_section_limit_octets (in_abfd, input_section);
    344  1.11  christos   bfd_size_type reloc_size = bfd_get_reloc_size (reloc->howto);
    345  1.11  christos 
    346  1.11  christos   if (*src_ptr > end
    347  1.11  christos       || reloc_size > end - *src_ptr)
    348  1.11  christos     {
    349  1.11  christos       link_info->callbacks->einfo
    350  1.11  christos 	/* xgettext:c-format */
    351  1.11  christos 	(_("%X%P: %pB(%pA): relocation \"%pR\" goes out of range\n"),
    352  1.11  christos 	 in_abfd, input_section, reloc);
    353  1.11  christos       return false;
    354  1.11  christos     }
    355  1.11  christos 
    356   1.9  christos   int val = bfd_coff_reloc16_get_value (reloc, link_info, input_section);
    357   1.1  christos   switch (reloc->howto->type)
    358   1.1  christos     {
    359   1.1  christos     case R_OFF8:
    360   1.9  christos       if (reloc->howto->partial_inplace)
    361  1.11  christos 	val += (signed char) (bfd_get_8 (in_abfd, data + *src_ptr)
    362  1.11  christos 			      & reloc->howto->src_mask);
    363  1.11  christos       if (val > 127 || val < -128)
    364  1.11  christos 	{
    365  1.11  christos 	  link_info->callbacks->reloc_overflow
    366   1.6  christos 	    (link_info, NULL, bfd_asymbol_name (*reloc->sym_ptr_ptr),
    367   1.6  christos 	     reloc->howto->name, reloc->addend, input_section->owner,
    368   1.6  christos 	     input_section, reloc->address);
    369  1.11  christos 	  return false;
    370  1.11  christos 	}
    371   1.6  christos 
    372  1.11  christos       bfd_put_8 (in_abfd, val, data + *dst_ptr);
    373  1.11  christos       *dst_ptr += 1;
    374  1.11  christos       *src_ptr += 1;
    375   1.1  christos       break;
    376   1.1  christos 
    377   1.9  christos     case R_BYTE3:
    378   1.9  christos       bfd_put_8 (in_abfd, val >> 24, data + *dst_ptr);
    379  1.11  christos       *dst_ptr += 1;
    380  1.11  christos       *src_ptr += 1;
    381   1.9  christos       break;
    382   1.9  christos 
    383   1.9  christos     case R_BYTE2:
    384   1.9  christos       bfd_put_8 (in_abfd, val >> 16, data + *dst_ptr);
    385  1.11  christos       *dst_ptr += 1;
    386  1.11  christos       *src_ptr += 1;
    387   1.9  christos       break;
    388   1.9  christos 
    389   1.9  christos     case R_BYTE1:
    390   1.9  christos       bfd_put_8 (in_abfd, val >> 8, data + *dst_ptr);
    391  1.11  christos       *dst_ptr += 1;
    392  1.11  christos       *src_ptr += 1;
    393   1.9  christos       break;
    394   1.9  christos 
    395   1.1  christos     case R_IMM8:
    396   1.9  christos       if (reloc->howto->partial_inplace)
    397  1.11  christos 	val += bfd_get_8 (in_abfd, data + *src_ptr) & reloc->howto->src_mask;
    398   1.9  christos       /* Fall through.  */
    399   1.9  christos     case R_BYTE0:
    400   1.1  christos       bfd_put_8 (in_abfd, val, data + *dst_ptr);
    401  1.11  christos       *dst_ptr += 1;
    402  1.11  christos       *src_ptr += 1;
    403   1.1  christos       break;
    404   1.1  christos 
    405   1.9  christos     case R_WORD1:
    406   1.9  christos       bfd_put_16 (in_abfd, val >> 16, data + *dst_ptr);
    407  1.11  christos       *dst_ptr += 2;
    408  1.11  christos       *src_ptr += 2;
    409   1.9  christos       break;
    410   1.9  christos 
    411   1.1  christos     case R_IMM16:
    412   1.9  christos       if (reloc->howto->partial_inplace)
    413  1.11  christos 	val += bfd_get_16 (in_abfd, data + *src_ptr) & reloc->howto->src_mask;
    414   1.9  christos       /* Fall through.  */
    415   1.9  christos     case R_WORD0:
    416   1.1  christos       bfd_put_16 (in_abfd, val, data + *dst_ptr);
    417  1.11  christos       *dst_ptr += 2;
    418  1.11  christos       *src_ptr += 2;
    419   1.1  christos       break;
    420   1.1  christos 
    421   1.1  christos     case R_IMM24:
    422   1.9  christos       if (reloc->howto->partial_inplace)
    423  1.10  christos 	val += (bfd_get_24 (in_abfd, data + *src_ptr)
    424  1.10  christos 		& reloc->howto->src_mask);
    425  1.10  christos       bfd_put_24 (in_abfd, val, data + *dst_ptr);
    426  1.11  christos       *dst_ptr += 3;
    427  1.11  christos       *src_ptr += 3;
    428   1.1  christos       break;
    429   1.1  christos 
    430   1.1  christos     case R_IMM32:
    431   1.9  christos       if (reloc->howto->partial_inplace)
    432  1.11  christos 	val += bfd_get_32 (in_abfd, data + *src_ptr) & reloc->howto->src_mask;
    433   1.1  christos       bfd_put_32 (in_abfd, val, data + *dst_ptr);
    434  1.11  christos       *dst_ptr += 4;
    435  1.11  christos       *src_ptr += 4;
    436   1.1  christos       break;
    437   1.1  christos 
    438   1.1  christos     case R_JR:
    439   1.1  christos       {
    440  1.11  christos 	if (reloc->howto->partial_inplace)
    441  1.11  christos 	  val += (signed char) (bfd_get_8 (in_abfd, data + *src_ptr)
    442  1.11  christos 				& reloc->howto->src_mask);
    443   1.1  christos 	bfd_vma dot = (*dst_ptr
    444   1.1  christos 		       + input_section->output_offset
    445   1.1  christos 		       + input_section->output_section->vma);
    446  1.11  christos 	bfd_signed_vma gap = val - dot;
    447   1.1  christos 	if (gap >= 128 || gap < -128)
    448  1.11  christos 	  {
    449  1.11  christos 	    link_info->callbacks->reloc_overflow
    450  1.11  christos 	      (link_info, NULL, bfd_asymbol_name (*reloc->sym_ptr_ptr),
    451  1.11  christos 	       reloc->howto->name, reloc->addend, input_section->owner,
    452  1.11  christos 	       input_section, reloc->address);
    453  1.11  christos 	    return false;
    454  1.11  christos 	  }
    455   1.6  christos 
    456   1.1  christos 	bfd_put_8 (in_abfd, gap, data + *dst_ptr);
    457  1.11  christos 	*dst_ptr += 1;
    458  1.11  christos 	*src_ptr += 1;
    459   1.1  christos 	break;
    460   1.1  christos       }
    461   1.1  christos 
    462   1.9  christos     case R_IMM16BE:
    463   1.9  christos       if (reloc->howto->partial_inplace)
    464  1.11  christos 	val += ((bfd_get_8 (in_abfd, data + *src_ptr + 0) * 0x100
    465  1.11  christos 		 + bfd_get_8 (in_abfd, data + *src_ptr + 1))
    466  1.11  christos 		& reloc->howto->src_mask);
    467   1.9  christos 
    468  1.11  christos       bfd_put_8 (in_abfd, val >> 8, data + *dst_ptr + 0);
    469  1.11  christos       bfd_put_8 (in_abfd, val, data + *dst_ptr + 1);
    470  1.11  christos       *dst_ptr += 2;
    471  1.11  christos       *src_ptr += 2;
    472   1.9  christos       break;
    473   1.9  christos 
    474   1.1  christos     default:
    475  1.11  christos       link_info->callbacks->einfo
    476  1.11  christos 	/* xgettext:c-format */
    477  1.11  christos 	(_("%X%P: %pB(%pA): relocation \"%pR\" is not supported\n"),
    478  1.11  christos 	 in_abfd, input_section, reloc);
    479  1.11  christos       return false;
    480   1.1  christos     }
    481  1.11  christos   return true;
    482   1.1  christos }
    483   1.1  christos 
    484  1.10  christos static bool
    485   1.9  christos z80_is_local_label_name (bfd *        abfd ATTRIBUTE_UNUSED,
    486   1.9  christos                          const char * name)
    487   1.9  christos {
    488   1.9  christos   return (name[0] == '.' && name[1] == 'L') ||
    489   1.9  christos          _bfd_coff_is_local_label_name (abfd, name);
    490   1.9  christos }
    491   1.9  christos 
    492   1.9  christos #define coff_bfd_is_local_label_name z80_is_local_label_name
    493   1.9  christos 
    494   1.1  christos #define coff_reloc16_extra_cases    extra_case
    495   1.1  christos #define coff_bfd_reloc_type_lookup  coff_z80_reloc_type_lookup
    496   1.1  christos #define coff_bfd_reloc_name_lookup coff_z80_reloc_name_lookup
    497   1.1  christos 
    498   1.1  christos #ifndef bfd_pe_print_pdata
    499   1.1  christos #define bfd_pe_print_pdata	NULL
    500   1.1  christos #endif
    501   1.1  christos 
    502   1.1  christos #include "coffcode.h"
    503   1.1  christos 
    504   1.1  christos #undef  coff_bfd_get_relocated_section_contents
    505   1.1  christos #define coff_bfd_get_relocated_section_contents \
    506   1.1  christos   bfd_coff_reloc16_get_relocated_section_contents
    507   1.1  christos 
    508   1.1  christos #undef  coff_bfd_relax_section
    509   1.1  christos #define coff_bfd_relax_section bfd_coff_reloc16_relax_section
    510   1.1  christos 
    511   1.3  christos CREATE_LITTLE_COFF_TARGET_VEC (z80_coff_vec, "coff-z80", 0,
    512   1.1  christos 			       SEC_CODE | SEC_DATA, '\0', NULL,
    513   1.1  christos 			       COFF_SWAP_TABLE)
    514   1.1  christos 
    515