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