xref: /openbsd-src/gnu/usr.bin/binutils/bfd/aout-arm.c (revision 007c2a4539b8b8aaa95c5e73e77620090abe113b)
12159047fSniklas /* BFD back-end for raw ARM a.out binaries.
2c074d1c9Sdrahn    Copyright 1994, 1995, 1997, 1998, 1999, 2000, 2001, 2002
3b55d4692Sfgsch    Free Software Foundation, Inc.
42159047fSniklas    Contributed by Richard Earnshaw (rwe@pegasus.esprit.ec.org)
52159047fSniklas 
62159047fSniklas This file is part of BFD, the Binary File Descriptor library.
72159047fSniklas 
82159047fSniklas This program is free software; you can redistribute it and/or modify
92159047fSniklas it under the terms of the GNU General Public License as published by
102159047fSniklas the Free Software Foundation; either version 2 of the License, or
112159047fSniklas (at your option) any later version.
122159047fSniklas 
132159047fSniklas This program is distributed in the hope that it will be useful,
142159047fSniklas but WITHOUT ANY WARRANTY; without even the implied warranty of
152159047fSniklas MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
162159047fSniklas GNU General Public License for more details.
172159047fSniklas 
182159047fSniklas You should have received a copy of the GNU General Public License
192159047fSniklas along with this program; if not, write to the Free Software
202159047fSniklas Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.  */
212159047fSniklas 
22c074d1c9Sdrahn #include "bfd.h"
23c074d1c9Sdrahn #include "sysdep.h"
24c074d1c9Sdrahn 
25*007c2a45Smiod /* Avoid multiple definitions from aoutx if supporting standard a.out
26c074d1c9Sdrahn    as well as our own.  */
27c074d1c9Sdrahn /* Do not "beautify" the CONCAT* macro args.  Traditional C will not
28c074d1c9Sdrahn    remove whitespace added here, and thus will fail to concatenate
29c074d1c9Sdrahn    the tokens.  */
30c074d1c9Sdrahn #define NAME(x,y) CONCAT3 (aoutarm,_32_,y)
31c074d1c9Sdrahn 
322159047fSniklas #define N_TXTADDR(x)						\
33c074d1c9Sdrahn   ((N_MAGIC (x) == NMAGIC)					\
34c074d1c9Sdrahn    ? (bfd_vma) 0x8000						\
35c074d1c9Sdrahn    : ((N_MAGIC (x) != ZMAGIC)					\
36c074d1c9Sdrahn       ? (bfd_vma) 0						\
37c074d1c9Sdrahn       : ((N_SHARED_LIB (x))					\
38c074d1c9Sdrahn 	 ? ((x).a_entry & ~(bfd_vma) (TARGET_PAGE_SIZE - 1))	\
39c074d1c9Sdrahn 	 : (bfd_vma) TEXT_START_ADDR)))
402159047fSniklas 
412159047fSniklas #define TEXT_START_ADDR 0x8000
422159047fSniklas #define TARGET_PAGE_SIZE 0x8000
432159047fSniklas #define SEGMENT_SIZE TARGET_PAGE_SIZE
442159047fSniklas #define DEFAULT_ARCH bfd_arch_arm
452159047fSniklas 
46c074d1c9Sdrahn #define MY(OP) CONCAT2 (aoutarm_,OP)
472159047fSniklas #define N_BADMAG(x) ((((x).a_info & ~007200) != ZMAGIC) && \
482159047fSniklas                      (((x).a_info & ~006000) != OMAGIC) && \
492159047fSniklas                      ((x).a_info != NMAGIC))
502159047fSniklas #define N_MAGIC(x) ((x).a_info & ~07200)
512159047fSniklas 
522159047fSniklas #define MY_bfd_reloc_type_lookup aoutarm_bfd_reloc_type_lookup
532159047fSniklas 
542159047fSniklas #include "libaout.h"
552159047fSniklas #include "aout/aout64.h"
562159047fSniklas 
57c074d1c9Sdrahn static bfd_boolean MY(write_object_contents)
58c074d1c9Sdrahn   PARAMS ((bfd *));
59c074d1c9Sdrahn static bfd_reloc_status_type MY(fix_pcrel_26_done)
60c074d1c9Sdrahn   PARAMS ((bfd *, arelent *, asymbol *, PTR, asection *, bfd *, char **));
61c074d1c9Sdrahn static bfd_reloc_status_type MY(fix_pcrel_26)
62c074d1c9Sdrahn   PARAMS ((bfd *, arelent *, asymbol *, PTR, asection *, bfd *, char **));
63c074d1c9Sdrahn static void MY(swap_std_reloc_in)
64c074d1c9Sdrahn   PARAMS ((bfd *, struct reloc_std_external *, arelent *, asymbol **,
652159047fSniklas 	   bfd_size_type));
66c074d1c9Sdrahn reloc_howto_type *MY(bfd_reloc_type_lookup)
67c074d1c9Sdrahn   PARAMS ((bfd *, bfd_reloc_code_real_type));
68c074d1c9Sdrahn reloc_howto_type * MY(reloc_howto)
69c074d1c9Sdrahn   PARAMS ((bfd *, struct reloc_std_external *, int *, int *, int *));
70c074d1c9Sdrahn void MY(put_reloc)
71c074d1c9Sdrahn   PARAMS ((bfd *, int, int, bfd_vma, reloc_howto_type *,
722159047fSniklas 	   struct reloc_std_external *));
73c074d1c9Sdrahn void MY(relocatable_reloc)
74c074d1c9Sdrahn   PARAMS ((reloc_howto_type *, bfd *, struct reloc_std_external *, bfd_vma *,
75c074d1c9Sdrahn 	   bfd_vma));
76c074d1c9Sdrahn void MY(swap_std_reloc_out)
77c074d1c9Sdrahn   PARAMS ((bfd *, arelent *, struct reloc_std_external *));
78c074d1c9Sdrahn 
792159047fSniklas reloc_howto_type MY(howto_table)[] =
802159047fSniklas   {
81c074d1c9Sdrahn     /* Type rs size bsz pcrel bitpos ovrf sf name part_inpl
82c074d1c9Sdrahn        readmask setmask pcdone.  */
83c074d1c9Sdrahn     HOWTO (0, 0, 0, 8, FALSE, 0, complain_overflow_bitfield, 0, "8", TRUE,
84c074d1c9Sdrahn 	   0x000000ff, 0x000000ff, FALSE),
85c074d1c9Sdrahn     HOWTO (1, 0, 1, 16, FALSE, 0, complain_overflow_bitfield, 0, "16", TRUE,
86c074d1c9Sdrahn 	   0x0000ffff, 0x0000ffff, FALSE),
87c074d1c9Sdrahn     HOWTO (2, 0, 2, 32, FALSE, 0, complain_overflow_bitfield, 0, "32", TRUE,
88c074d1c9Sdrahn 	   0xffffffff, 0xffffffff, FALSE),
89c074d1c9Sdrahn     HOWTO (3, 2, 2, 26, TRUE, 0, complain_overflow_signed, MY(fix_pcrel_26),
90c074d1c9Sdrahn 	   "ARM26", TRUE, 0x00ffffff, 0x00ffffff, TRUE),
91c074d1c9Sdrahn     HOWTO (4, 0, 0, 8, TRUE, 0, complain_overflow_signed, 0, "DISP8", TRUE,
92c074d1c9Sdrahn 	   0x000000ff, 0x000000ff, TRUE),
93c074d1c9Sdrahn     HOWTO (5, 0, 1, 16, TRUE, 0, complain_overflow_signed, 0, "DISP16", TRUE,
94c074d1c9Sdrahn 	   0x0000ffff, 0x0000ffff, TRUE),
95c074d1c9Sdrahn     HOWTO (6, 0, 2, 32, TRUE, 0, complain_overflow_signed, 0, "DISP32", TRUE,
96c074d1c9Sdrahn 	   0xffffffff, 0xffffffff, TRUE),
97c074d1c9Sdrahn     HOWTO (7, 2, 2, 26, FALSE, 0, complain_overflow_signed,
98c074d1c9Sdrahn 	   MY(fix_pcrel_26_done), "ARM26D", TRUE, 0x0, 0x0,
99c074d1c9Sdrahn 	   FALSE),
100b305b0f1Sespie     EMPTY_HOWTO (-1),
101c074d1c9Sdrahn     HOWTO (9, 0, -1, 16, FALSE, 0, complain_overflow_bitfield, 0, "NEG16", TRUE,
102c074d1c9Sdrahn 	   0x0000ffff, 0x0000ffff, FALSE),
103c074d1c9Sdrahn     HOWTO (10, 0, -2, 32, FALSE, 0, complain_overflow_bitfield, 0, "NEG32", TRUE,
104c074d1c9Sdrahn 	   0xffffffff, 0xffffffff, FALSE)
1052159047fSniklas   };
1062159047fSniklas 
1072159047fSniklas #define RELOC_ARM_BITS_NEG_BIG      ((unsigned int) 0x08)
1082159047fSniklas #define RELOC_ARM_BITS_NEG_LITTLE   ((unsigned int) 0x10)
1092159047fSniklas 
1102159047fSniklas reloc_howto_type *
1112159047fSniklas MY(reloc_howto) (abfd, rel, r_index, r_extern, r_pcrel)
1122159047fSniklas      bfd *abfd;
1132159047fSniklas      struct reloc_std_external *rel;
1142159047fSniklas      int *r_index;
1152159047fSniklas      int *r_extern;
1162159047fSniklas      int *r_pcrel;
1172159047fSniklas {
1182159047fSniklas   unsigned int r_length;
1192159047fSniklas   unsigned int r_pcrel_done;
1202159047fSniklas   unsigned int r_neg;
1212159047fSniklas   int index;
1222159047fSniklas 
1232159047fSniklas   *r_pcrel = 0;
124c88b1d6cSniklas   if (bfd_header_big_endian (abfd))
1252159047fSniklas     {
1262159047fSniklas       *r_index     =  ((rel->r_index[0] << 16)
1272159047fSniklas 		       | (rel->r_index[1] << 8)
1282159047fSniklas 		       | rel->r_index[2]);
1292159047fSniklas       *r_extern    = (0 != (rel->r_type[0] & RELOC_STD_BITS_EXTERN_BIG));
1302159047fSniklas       r_pcrel_done = (0 != (rel->r_type[0] & RELOC_STD_BITS_PCREL_BIG));
1312159047fSniklas       r_neg 	   = (0 != (rel->r_type[0] & RELOC_ARM_BITS_NEG_BIG));
1322159047fSniklas       r_length     = ((rel->r_type[0] & RELOC_STD_BITS_LENGTH_BIG)
1332159047fSniklas 		      >> RELOC_STD_BITS_LENGTH_SH_BIG);
1342159047fSniklas     }
1352159047fSniklas   else
1362159047fSniklas     {
1372159047fSniklas       *r_index     = ((rel->r_index[2] << 16)
1382159047fSniklas 		      | (rel->r_index[1] << 8)
1392159047fSniklas 		      | rel->r_index[0]);
1402159047fSniklas       *r_extern    = (0 != (rel->r_type[0] & RELOC_STD_BITS_EXTERN_LITTLE));
1412159047fSniklas       r_pcrel_done = (0 != (rel->r_type[0] & RELOC_STD_BITS_PCREL_LITTLE));
1422159047fSniklas       r_neg 	   = (0 != (rel->r_type[0] & RELOC_ARM_BITS_NEG_LITTLE));
1432159047fSniklas       r_length     = ((rel->r_type[0] & RELOC_STD_BITS_LENGTH_LITTLE)
1442159047fSniklas 		      >> RELOC_STD_BITS_LENGTH_SH_LITTLE);
1452159047fSniklas     }
1462159047fSniklas   index = r_length + 4 * r_pcrel_done + 8 * r_neg;
1472159047fSniklas   if (index == 3)
1482159047fSniklas     *r_pcrel = 1;
1492159047fSniklas 
1502159047fSniklas   return MY(howto_table) + index;
1512159047fSniklas }
1522159047fSniklas 
1532159047fSniklas #define MY_reloc_howto(BFD, REL, IN, EX, PC) \
1542159047fSniklas 	MY(reloc_howto) (BFD, REL, &IN, &EX, &PC)
1552159047fSniklas 
1562159047fSniklas void
1572159047fSniklas MY(put_reloc) (abfd, r_extern, r_index, value, howto, reloc)
1582159047fSniklas      bfd *abfd;
1592159047fSniklas      int r_extern;
1602159047fSniklas      int r_index;
161c074d1c9Sdrahn      bfd_vma value;
1622159047fSniklas      reloc_howto_type *howto;
1632159047fSniklas      struct reloc_std_external *reloc;
1642159047fSniklas {
1652159047fSniklas   unsigned int r_length;
1662159047fSniklas   int r_pcrel;
1672159047fSniklas   int r_neg;
1682159047fSniklas 
1692159047fSniklas   PUT_WORD (abfd, value, reloc->r_address);
170c074d1c9Sdrahn   /* Size as a power of two.  */
171c074d1c9Sdrahn   r_length = howto->size;
1722159047fSniklas 
1732159047fSniklas   /* Special case for branch relocations.  */
1742159047fSniklas   if (howto->type == 3 || howto->type == 7)
1752159047fSniklas     r_length = 3;
1762159047fSniklas 
1772159047fSniklas   r_pcrel  = howto->type & 4; 	/* PC Relative done?  */
178c074d1c9Sdrahn   r_neg = howto->type & 8;	/* Negative relocation.  */
179c074d1c9Sdrahn 
180c88b1d6cSniklas   if (bfd_header_big_endian (abfd))
1812159047fSniklas     {
1822159047fSniklas       reloc->r_index[0] = r_index >> 16;
1832159047fSniklas       reloc->r_index[1] = r_index >> 8;
1842159047fSniklas       reloc->r_index[2] = r_index;
1852159047fSniklas       reloc->r_type[0] =
1862159047fSniklas 	((r_extern ?     RELOC_STD_BITS_EXTERN_BIG : 0)
1872159047fSniklas 	 | (r_pcrel ?    RELOC_STD_BITS_PCREL_BIG : 0)
1882159047fSniklas 	 | (r_neg ?	 RELOC_ARM_BITS_NEG_BIG : 0)
1892159047fSniklas 	 | (r_length <<  RELOC_STD_BITS_LENGTH_SH_BIG));
1902159047fSniklas     }
1912159047fSniklas   else
1922159047fSniklas     {
1932159047fSniklas       reloc->r_index[2] = r_index >> 16;
1942159047fSniklas       reloc->r_index[1] = r_index >> 8;
1952159047fSniklas       reloc->r_index[0] = r_index;
1962159047fSniklas       reloc->r_type[0] =
1972159047fSniklas 	((r_extern ?     RELOC_STD_BITS_EXTERN_LITTLE : 0)
1982159047fSniklas 	 | (r_pcrel ?    RELOC_STD_BITS_PCREL_LITTLE : 0)
1992159047fSniklas 	 | (r_neg ?	 RELOC_ARM_BITS_NEG_LITTLE : 0)
2002159047fSniklas 	 | (r_length <<  RELOC_STD_BITS_LENGTH_SH_LITTLE));
2012159047fSniklas     }
2022159047fSniklas }
2032159047fSniklas 
2042159047fSniklas #define MY_put_reloc(BFD, EXT, IDX, VAL, HOWTO, RELOC) \
2052159047fSniklas   MY(put_reloc) (BFD, EXT, IDX, VAL, HOWTO, RELOC)
2062159047fSniklas 
2072159047fSniklas void
2082159047fSniklas MY(relocatable_reloc) (howto, abfd, reloc, amount, r_addr)
2092159047fSniklas      reloc_howto_type *howto;
2102159047fSniklas      bfd *abfd;
2112159047fSniklas      struct reloc_std_external *reloc;
2122159047fSniklas      bfd_vma *amount;
2132159047fSniklas      bfd_vma r_addr;
2142159047fSniklas {
2152159047fSniklas   if (howto->type == 3)
2162159047fSniklas     {
2172159047fSniklas       if (reloc->r_type[0]
218c88b1d6cSniklas 	  & (bfd_header_big_endian (abfd)
2192159047fSniklas 	     ? RELOC_STD_BITS_EXTERN_BIG : RELOC_STD_BITS_EXTERN_LITTLE))
2202159047fSniklas 	{
2212159047fSniklas 	  /* The reloc is still external, so don't modify anything.  */
2222159047fSniklas 	  *amount = 0;
2232159047fSniklas 	}
2242159047fSniklas       else
2252159047fSniklas 	{
2262159047fSniklas 	  *amount -= r_addr;
2272159047fSniklas 	  /* Change the r_pcrel value -- on the ARM, this bit is set once the
2282159047fSniklas 	     relocation is done.  */
229c88b1d6cSniklas 	  if (bfd_header_big_endian (abfd))
2302159047fSniklas 	    reloc->r_type[0] |= RELOC_STD_BITS_PCREL_BIG;
2312159047fSniklas 	  else
2322159047fSniklas 	    reloc->r_type[0] |= RELOC_STD_BITS_PCREL_LITTLE;
2332159047fSniklas 	}
2342159047fSniklas     }
2352159047fSniklas   else if (howto->type == 7)
2362159047fSniklas     *amount = 0;
2372159047fSniklas }
2382159047fSniklas 
2392159047fSniklas #define MY_relocatable_reloc(HOW, BFD, REL, AMOUNT, ADDR) \
2402159047fSniklas   MY(relocatable_reloc) (HOW, BFD, REL, &(AMOUNT), ADDR)
2412159047fSniklas 
2422159047fSniklas static bfd_reloc_status_type
2432159047fSniklas MY(fix_pcrel_26_done) (abfd, reloc_entry, symbol, data, input_section,
2442159047fSniklas 		       output_bfd, error_message)
245b305b0f1Sespie      bfd *abfd ATTRIBUTE_UNUSED;
246b305b0f1Sespie      arelent *reloc_entry ATTRIBUTE_UNUSED;
247b305b0f1Sespie      asymbol *symbol ATTRIBUTE_UNUSED;
248b305b0f1Sespie      PTR data ATTRIBUTE_UNUSED;
249b305b0f1Sespie      asection *input_section ATTRIBUTE_UNUSED;
250b305b0f1Sespie      bfd *output_bfd ATTRIBUTE_UNUSED;
251b305b0f1Sespie      char **error_message ATTRIBUTE_UNUSED;
2522159047fSniklas {
2532159047fSniklas   /* This is dead simple at present.  */
2542159047fSniklas   return bfd_reloc_ok;
2552159047fSniklas }
2562159047fSniklas 
2572159047fSniklas static bfd_reloc_status_type
2582159047fSniklas MY(fix_pcrel_26) (abfd, reloc_entry, symbol, data, input_section,
2592159047fSniklas 		  output_bfd, error_message)
2602159047fSniklas      bfd *abfd;
2612159047fSniklas      arelent *reloc_entry;
2622159047fSniklas      asymbol *symbol;
2632159047fSniklas      PTR data;
2642159047fSniklas      asection *input_section;
2652159047fSniklas      bfd *output_bfd;
266b305b0f1Sespie      char **error_message ATTRIBUTE_UNUSED;
2672159047fSniklas {
2682159047fSniklas   bfd_vma relocation;
2692159047fSniklas   bfd_size_type addr = reloc_entry->address;
270c074d1c9Sdrahn   bfd_vma target = bfd_get_32 (abfd, (bfd_byte *) data + addr);
2712159047fSniklas   bfd_reloc_status_type flag = bfd_reloc_ok;
2722159047fSniklas 
273c074d1c9Sdrahn   /* If this is an undefined symbol, return error.  */
2742159047fSniklas   if (symbol->section == &bfd_und_section
2752159047fSniklas       && (symbol->flags & BSF_WEAK) == 0)
2762159047fSniklas     return output_bfd ? bfd_reloc_ok : bfd_reloc_undefined;
2772159047fSniklas 
2782159047fSniklas   /* If the sections are different, and we are doing a partial relocation,
2792159047fSniklas      just ignore it for now.  */
2802159047fSniklas   if (symbol->section->name != input_section->name
2812159047fSniklas       && output_bfd != (bfd *)NULL)
2822159047fSniklas     return bfd_reloc_ok;
2832159047fSniklas 
2842159047fSniklas   relocation = (target & 0x00ffffff) << 2;
285c074d1c9Sdrahn   relocation = (relocation ^ 0x02000000) - 0x02000000; /* Sign extend.  */
2862159047fSniklas   relocation += symbol->value;
2872159047fSniklas   relocation += symbol->section->output_section->vma;
2882159047fSniklas   relocation += symbol->section->output_offset;
2892159047fSniklas   relocation += reloc_entry->addend;
2902159047fSniklas   relocation -= input_section->output_section->vma;
2912159047fSniklas   relocation -= input_section->output_offset;
2922159047fSniklas   relocation -= addr;
2932159047fSniklas   if (relocation & 3)
2942159047fSniklas     return bfd_reloc_overflow;
2952159047fSniklas 
296c074d1c9Sdrahn   /* Check for overflow.  */
2972159047fSniklas   if (relocation & 0x02000000)
2982159047fSniklas     {
299b305b0f1Sespie       if ((relocation & ~ (bfd_vma) 0x03ffffff) != ~ (bfd_vma) 0x03ffffff)
3002159047fSniklas 	flag = bfd_reloc_overflow;
3012159047fSniklas     }
302c074d1c9Sdrahn   else if (relocation & ~ (bfd_vma) 0x03ffffff)
3032159047fSniklas     flag = bfd_reloc_overflow;
3042159047fSniklas 
305c074d1c9Sdrahn   target &= ~ (bfd_vma) 0x00ffffff;
3062159047fSniklas   target |= (relocation >> 2) & 0x00ffffff;
3072159047fSniklas   bfd_put_32 (abfd, target, (bfd_byte *) data + addr);
3082159047fSniklas 
3092159047fSniklas   /* Now the ARM magic... Change the reloc type so that it is marked as done.
3102159047fSniklas      Strictly this is only necessary if we are doing a partial relocation.  */
3112159047fSniklas   reloc_entry->howto = &MY(howto_table)[7];
3122159047fSniklas 
3132159047fSniklas   return flag;
3142159047fSniklas }
3152159047fSniklas 
3162159047fSniklas reloc_howto_type *
3172159047fSniklas MY(bfd_reloc_type_lookup) (abfd,code)
3182159047fSniklas      bfd *abfd;
3192159047fSniklas      bfd_reloc_code_real_type code;
3202159047fSniklas {
3212159047fSniklas #define ASTD(i,j)       case i: return &MY(howto_table)[j]
3222159047fSniklas   if (code == BFD_RELOC_CTOR)
3232159047fSniklas     switch (bfd_get_arch_info (abfd)->bits_per_address)
3242159047fSniklas       {
3252159047fSniklas       case 32:
3262159047fSniklas         code = BFD_RELOC_32;
3272159047fSniklas         break;
328c074d1c9Sdrahn       default:
329c074d1c9Sdrahn 	return (const struct reloc_howto_struct *) 0;
3302159047fSniklas       }
3312159047fSniklas 
3322159047fSniklas   switch (code)
3332159047fSniklas     {
3342159047fSniklas       ASTD (BFD_RELOC_16, 1);
3352159047fSniklas       ASTD (BFD_RELOC_32, 2);
3362159047fSniklas       ASTD (BFD_RELOC_ARM_PCREL_BRANCH, 3);
3372159047fSniklas       ASTD (BFD_RELOC_8_PCREL, 4);
3382159047fSniklas       ASTD (BFD_RELOC_16_PCREL, 5);
3392159047fSniklas       ASTD (BFD_RELOC_32_PCREL, 6);
340c074d1c9Sdrahn     default:
341c074d1c9Sdrahn       return (const struct reloc_howto_struct *) 0;
3422159047fSniklas     }
3432159047fSniklas }
3442159047fSniklas 
3452159047fSniklas #define MY_swap_std_reloc_in MY(swap_std_reloc_in)
3462159047fSniklas #define MY_swap_std_reloc_out MY(swap_std_reloc_out)
3472159047fSniklas #define MY_get_section_contents _bfd_generic_get_section_contents
3482159047fSniklas /* #define MY_bfd_link_hash_table_create _bfd_generic_link_hash_table_create */
3492159047fSniklas /* #define MY_bfd_link_add_symbols _bfd_generic_link_add_symbols */
3502159047fSniklas /* #define MY_bfd_final_link _bfd_generic_final_link */
3512159047fSniklas 
3522159047fSniklas #include "aoutx.h"
3532159047fSniklas 
3542159047fSniklas static void
MY_swap_std_reloc_in(abfd,bytes,cache_ptr,symbols,symcount)3552159047fSniklas MY_swap_std_reloc_in (abfd, bytes, cache_ptr, symbols, symcount)
3562159047fSniklas      bfd *abfd;
3572159047fSniklas      struct reloc_std_external *bytes;
3582159047fSniklas      arelent *cache_ptr;
3592159047fSniklas      asymbol **symbols;
360b305b0f1Sespie      bfd_size_type symcount ATTRIBUTE_UNUSED;
3612159047fSniklas {
3622159047fSniklas   int r_index;
3632159047fSniklas   int r_extern;
3642159047fSniklas   int r_pcrel;
3652159047fSniklas   struct aoutdata *su = &(abfd->tdata.aout_data->a);
3662159047fSniklas 
367c074d1c9Sdrahn   cache_ptr->address = H_GET_32 (abfd, bytes->r_address);
3682159047fSniklas 
3692159047fSniklas   cache_ptr->howto = MY_reloc_howto (abfd, bytes, r_index, r_extern, r_pcrel);
3702159047fSniklas 
3712159047fSniklas   MOVE_ADDRESS (0);
3722159047fSniklas }
3732159047fSniklas 
3742159047fSniklas void
MY_swap_std_reloc_out(abfd,g,natptr)3752159047fSniklas MY_swap_std_reloc_out (abfd, g, natptr)
3762159047fSniklas      bfd *abfd;
3772159047fSniklas      arelent *g;
3782159047fSniklas      struct reloc_std_external *natptr;
3792159047fSniklas {
3802159047fSniklas   int r_index;
3812159047fSniklas   asymbol *sym = *(g->sym_ptr_ptr);
3822159047fSniklas   int r_extern;
3832159047fSniklas   int r_length;
3842159047fSniklas   int r_pcrel;
3852159047fSniklas   int r_neg = 0;	/* Negative relocs use the BASEREL bit.  */
3862159047fSniklas   asection *output_section = sym->section->output_section;
3872159047fSniklas 
3882159047fSniklas   PUT_WORD(abfd, g->address, natptr->r_address);
3892159047fSniklas 
3902159047fSniklas   r_length = g->howto->size ;   /* Size as a power of two */
3912159047fSniklas   if (r_length < 0)
3922159047fSniklas     {
3932159047fSniklas       r_length = -r_length;
3942159047fSniklas       r_neg = 1;
3952159047fSniklas     }
3962159047fSniklas 
3972159047fSniklas   r_pcrel  = (int) g->howto->pc_relative; /* Relative to PC? */
3982159047fSniklas 
3992159047fSniklas   /* For RISC iX, in pc-relative relocs the r_pcrel bit means that the
4002159047fSniklas      relocation has been done already (Only for the 26-bit one I think)???!!!
4012159047fSniklas      */
4022159047fSniklas 
4032159047fSniklas   if (g->howto->type == 3)
4042159047fSniklas     {
4052159047fSniklas       r_length = 3;
4062159047fSniklas       r_pcrel = 0;
4072159047fSniklas     }
4082159047fSniklas   else if (g->howto->type == 7)
4092159047fSniklas     {
4102159047fSniklas       r_length = 3;
4112159047fSniklas       r_pcrel = 1;
4122159047fSniklas     }
4132159047fSniklas 
4142159047fSniklas #if 0
4152159047fSniklas   /* For a standard reloc, the addend is in the object file.  */
4162159047fSniklas   r_addend = g->addend + (*(g->sym_ptr_ptr))->section->output_section->vma;
4172159047fSniklas #endif
4182159047fSniklas 
4192159047fSniklas   /* name was clobbered by aout_write_syms to be symbol index */
4202159047fSniklas 
4212159047fSniklas   /* If this relocation is relative to a symbol then set the
4222159047fSniklas      r_index to the symbols index, and the r_extern bit.
4232159047fSniklas 
4242159047fSniklas      Absolute symbols can come in in two ways, either as an offset
4252159047fSniklas      from the abs section, or as a symbol which has an abs value.
4262159047fSniklas      check for that here
4272159047fSniklas      */
4282159047fSniklas 
4292159047fSniklas   if (bfd_is_com_section (output_section)
4302159047fSniklas       || output_section == &bfd_abs_section
4312159047fSniklas       || output_section == &bfd_und_section)
4322159047fSniklas     {
4332159047fSniklas       if (bfd_abs_section.symbol == sym)
4342159047fSniklas 	{
4352159047fSniklas 	  /* Whoops, looked like an abs symbol, but is really an offset
436c074d1c9Sdrahn 	     from the abs section.  */
4372159047fSniklas 	  r_index = 0;
4382159047fSniklas 	  r_extern = 0;
4392159047fSniklas 	}
4402159047fSniklas       else
4412159047fSniklas 	{
442c074d1c9Sdrahn 	  /* Fill in symbol.  */
4432159047fSniklas 	  r_extern = 1;
444c88b1d6cSniklas 	  r_index = (*(g->sym_ptr_ptr))->KEEPIT;
4452159047fSniklas 	}
4462159047fSniklas     }
4472159047fSniklas   else
4482159047fSniklas     {
449c074d1c9Sdrahn       /* Just an ordinary section.  */
4502159047fSniklas       r_extern = 0;
4512159047fSniklas       r_index  = output_section->target_index;
4522159047fSniklas     }
4532159047fSniklas 
454c074d1c9Sdrahn   /* Now the fun stuff.  */
455c88b1d6cSniklas   if (bfd_header_big_endian (abfd))
4562159047fSniklas     {
4572159047fSniklas       natptr->r_index[0] = r_index >> 16;
4582159047fSniklas       natptr->r_index[1] = r_index >> 8;
4592159047fSniklas       natptr->r_index[2] = r_index;
4602159047fSniklas       natptr->r_type[0] =
4612159047fSniklas 	(  (r_extern ?   RELOC_STD_BITS_EXTERN_BIG: 0)
4622159047fSniklas 	 | (r_pcrel  ?   RELOC_STD_BITS_PCREL_BIG: 0)
4632159047fSniklas 	 | (r_neg    ?   RELOC_ARM_BITS_NEG_BIG: 0)
4642159047fSniklas 	 | (r_length <<  RELOC_STD_BITS_LENGTH_SH_BIG));
4652159047fSniklas     }
4662159047fSniklas   else
4672159047fSniklas     {
4682159047fSniklas       natptr->r_index[2] = r_index >> 16;
4692159047fSniklas       natptr->r_index[1] = r_index >> 8;
4702159047fSniklas       natptr->r_index[0] = r_index;
4712159047fSniklas       natptr->r_type[0] =
4722159047fSniklas 	(  (r_extern ?   RELOC_STD_BITS_EXTERN_LITTLE: 0)
4732159047fSniklas 	 | (r_pcrel  ?   RELOC_STD_BITS_PCREL_LITTLE: 0)
4742159047fSniklas 	 | (r_neg    ?   RELOC_ARM_BITS_NEG_LITTLE: 0)
4752159047fSniklas 	 | (r_length <<  RELOC_STD_BITS_LENGTH_SH_LITTLE));
4762159047fSniklas     }
4772159047fSniklas }
4782159047fSniklas 
4792159047fSniklas #define MY_BFD_TARGET
4802159047fSniklas 
4812159047fSniklas #include "aout-target.h"
4822159047fSniklas 
483b305b0f1Sespie extern const bfd_target aout_arm_big_vec;
484b305b0f1Sespie 
4852159047fSniklas const bfd_target aout_arm_little_vec =
4862159047fSniklas   {
4872159047fSniklas     "a.out-arm-little",           /* name */
4882159047fSniklas     bfd_target_aout_flavour,
489c88b1d6cSniklas     BFD_ENDIAN_LITTLE,            /* target byte order (little) */
490c88b1d6cSniklas     BFD_ENDIAN_LITTLE,            /* target headers byte order (little) */
4912159047fSniklas     (HAS_RELOC | EXEC_P |         /* object flags */
4922159047fSniklas      HAS_LINENO | HAS_DEBUG |
4932159047fSniklas      HAS_SYMS | HAS_LOCALS | DYNAMIC | WP_TEXT | D_PAGED),
494b305b0f1Sespie     (SEC_HAS_CONTENTS | SEC_ALLOC | SEC_LOAD | SEC_RELOC | SEC_CODE | SEC_DATA),
4952159047fSniklas     MY_symbol_leading_char,
4962159047fSniklas     AR_PAD_CHAR,                  /* ar_pad_char */
4972159047fSniklas     15,                           /* ar_max_namelen */
4982159047fSniklas     bfd_getl64, bfd_getl_signed_64, bfd_putl64,
4992159047fSniklas     bfd_getl32, bfd_getl_signed_32, bfd_putl32,
5002159047fSniklas     bfd_getl16, bfd_getl_signed_16, bfd_putl16,	/* data */
5012159047fSniklas     bfd_getl64, bfd_getl_signed_64, bfd_putl64,
5022159047fSniklas     bfd_getl32, bfd_getl_signed_32, bfd_putl32,
5032159047fSniklas     bfd_getl16, bfd_getl_signed_16, bfd_putl16,	/* hdrs */
5042159047fSniklas     {_bfd_dummy_target, MY_object_p,		/* bfd_check_format */
5052159047fSniklas      bfd_generic_archive_p, MY_core_file_p},
5062159047fSniklas     {bfd_false, MY_mkobject,			/* bfd_set_format */
5072159047fSniklas      _bfd_generic_mkarchive, bfd_false},
5082159047fSniklas     {bfd_false, MY_write_object_contents,	/* bfd_write_contents */
5092159047fSniklas      _bfd_write_archive_contents, bfd_false},
5102159047fSniklas 
5112159047fSniklas     BFD_JUMP_TABLE_GENERIC (MY),
5122159047fSniklas     BFD_JUMP_TABLE_COPY (MY),
5132159047fSniklas     BFD_JUMP_TABLE_CORE (MY),
5142159047fSniklas     BFD_JUMP_TABLE_ARCHIVE (MY),
5152159047fSniklas     BFD_JUMP_TABLE_SYMBOLS (MY),
5162159047fSniklas     BFD_JUMP_TABLE_RELOCS (MY),
5172159047fSniklas     BFD_JUMP_TABLE_WRITE (MY),
5182159047fSniklas     BFD_JUMP_TABLE_LINK (MY),
5192159047fSniklas     BFD_JUMP_TABLE_DYNAMIC (MY),
5202159047fSniklas 
521b305b0f1Sespie     & aout_arm_big_vec,
522b305b0f1Sespie 
5232159047fSniklas     (PTR) MY_backend_data,
5242159047fSniklas   };
5252159047fSniklas 
5262159047fSniklas const bfd_target aout_arm_big_vec =
5272159047fSniklas   {
5282159047fSniklas     "a.out-arm-big",              /* name */
5292159047fSniklas     bfd_target_aout_flavour,
530c88b1d6cSniklas     BFD_ENDIAN_BIG,               /* target byte order (big) */
531c88b1d6cSniklas     BFD_ENDIAN_BIG,               /* target headers byte order (big) */
5322159047fSniklas     (HAS_RELOC | EXEC_P |         /* object flags */
5332159047fSniklas      HAS_LINENO | HAS_DEBUG |
5342159047fSniklas      HAS_SYMS | HAS_LOCALS | DYNAMIC | WP_TEXT | D_PAGED),
535b305b0f1Sespie     (SEC_HAS_CONTENTS | SEC_ALLOC | SEC_LOAD | SEC_RELOC | SEC_CODE | SEC_DATA),
5362159047fSniklas     MY_symbol_leading_char,
5372159047fSniklas     AR_PAD_CHAR,                  		/* ar_pad_char */
5382159047fSniklas     15,                           		/* ar_max_namelen */
5392159047fSniklas     bfd_getb64, bfd_getb_signed_64, bfd_putb64,
5402159047fSniklas     bfd_getb32, bfd_getb_signed_32, bfd_putb32,
5412159047fSniklas     bfd_getb16, bfd_getb_signed_16, bfd_putb16,	/* data */
5422159047fSniklas     bfd_getb64, bfd_getb_signed_64, bfd_putb64,
5432159047fSniklas     bfd_getb32, bfd_getb_signed_32, bfd_putb32,
5442159047fSniklas     bfd_getb16, bfd_getb_signed_16, bfd_putb16,	/* hdrs */
5452159047fSniklas     {_bfd_dummy_target, MY_object_p,		/* bfd_check_format */
5462159047fSniklas      bfd_generic_archive_p, MY_core_file_p},
5472159047fSniklas     {bfd_false, MY_mkobject,			/* bfd_set_format */
5482159047fSniklas      _bfd_generic_mkarchive, bfd_false},
5492159047fSniklas     {bfd_false, MY_write_object_contents,	/* bfd_write_contents */
5502159047fSniklas      _bfd_write_archive_contents, bfd_false},
5512159047fSniklas 
5522159047fSniklas     BFD_JUMP_TABLE_GENERIC (MY),
5532159047fSniklas     BFD_JUMP_TABLE_COPY (MY),
5542159047fSniklas     BFD_JUMP_TABLE_CORE (MY),
5552159047fSniklas     BFD_JUMP_TABLE_ARCHIVE (MY),
5562159047fSniklas     BFD_JUMP_TABLE_SYMBOLS (MY),
5572159047fSniklas     BFD_JUMP_TABLE_RELOCS (MY),
5582159047fSniklas     BFD_JUMP_TABLE_WRITE (MY),
5592159047fSniklas     BFD_JUMP_TABLE_LINK (MY),
5602159047fSniklas     BFD_JUMP_TABLE_DYNAMIC (MY),
5612159047fSniklas 
562b305b0f1Sespie     & aout_arm_little_vec,
563b305b0f1Sespie 
5642159047fSniklas     (PTR) MY_backend_data,
5652159047fSniklas   };
566