Fix typos
[platform/upstream/binutils.git] / bfd / riscix.c
1 /* BFD back-end for RISC iX (Acorn, arm) binaries.
2    Copyright 1994, 1995, 1996, 1997, 1998, 2000, 2001
3    Free Software Foundation, Inc.
4    Contributed by Richard Earnshaw (rwe@pegasus.esprit.ec.org)
5
6 This file is part of BFD, the Binary File Descriptor library.
7
8 This program is free software; you can redistribute it and/or modify
9 it under the terms of the GNU General Public License as published by
10 the Free Software Foundation; either version 2 of the License, or
11 (at your option) any later version.
12
13 This program is distributed in the hope that it will be useful,
14 but WITHOUT ANY WARRANTY; without even the implied warranty of
15 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
16 GNU General Public License for more details.
17
18 You should have received a copy of the GNU General Public License
19 along with this program; if not, write to the Free Software
20 Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.  */
21
22 /* RISC iX overloads the MAGIC field to indicate more than just the usual
23    [ZNO]MAGIC values.  Also included are squeezing information and
24    shared library usage.  */
25
26 /* The following come from the man page.  */
27 #define SHLIBLEN 60
28
29 #define MF_IMPURE       00200
30 #define MF_SQUEEZED     01000
31 #define MF_USES_SL      02000
32 #define MF_IS_SL        04000
33
34 /* Common combinations.  */
35 #define IMAGIC          (MF_IMPURE|ZMAGIC)      /* Demand load (impure text) */
36 #define SPOMAGIC        (MF_USES_SL|OMAGIC)     /* OMAGIC with large header */
37                                         /* -- may contain a ref to a */
38                                         /* shared lib required by the */
39                                         /* object.  */
40 #define SLOMAGIC        (MF_IS_SL|OMAGIC) /* A reference to a shared library */
41                                           /* The text portion of the object */
42                                           /* contains "overflow text" from */
43                                           /* the shared library to be linked */
44                                           /* in with an object */
45 #define QMAGIC          (MF_SQUEEZED|ZMAGIC)    /* Sqeezed demand paged.  */
46                                           /* NOTE: This interpretation of */
47                                           /* QMAGIC seems to be at variance */
48                                           /* With that used on other */
49                                           /* architectures.  */
50 #define SPZMAGIC        (MF_USES_SL|ZMAGIC)     /* program which uses sl */
51 #define SPQMAGIC        (MF_USES_SL|QMAGIC)     /* sqeezed ditto */
52 #define SLZMAGIC        (MF_IS_SL|ZMAGIC)       /* shared lib part of prog */
53 #define SLPZMAGIC       (MF_USES_SL|SLZMAGIC)   /* sl which uses another */
54
55 #define N_SHARED_LIB(x) ((x).a_info & MF_USES_SL)
56
57 /* Only a pure OMAGIC file has the minimal header */
58 #define N_TXTOFF(x)                     \
59  ((x).a_info == OMAGIC ? 32             \
60   : (N_MAGIC(x) == ZMAGIC) ? TARGET_PAGE_SIZE  \
61   : 999)
62
63 #define N_TXTADDR(x)                                                         \
64   (N_MAGIC(x) != ZMAGIC ? 0 /* object file or NMAGIC */                      \
65    /* Programs with shared libs are loaded at the first page after all the   \
66       text segments of the shared library programs.  Without looking this    \
67       up we can't know exactly what the address will be.  A reasonable guess \
68       is that a_entry will be in the first page of the executable.  */       \
69    : N_SHARED_LIB(x) ? ((x).a_entry & ~(TARGET_PAGE_SIZE - 1))                      \
70    : TEXT_START_ADDR)
71
72 #define N_SYMOFF(x) \
73   (N_TXTOFF (x) + (x).a_text + (x).a_data + (x).a_trsize + (x).a_drsize)
74
75 #define N_STROFF(x) (N_SYMOFF (x) + (x).a_syms)
76
77 #define TEXT_START_ADDR 32768
78 #define TARGET_PAGE_SIZE 32768
79 #define SEGMENT_SIZE TARGET_PAGE_SIZE
80 #define DEFAULT_ARCH bfd_arch_arm
81
82 #define MY(OP) CAT(riscix_,OP)
83 #define TARGETNAME "a.out-riscix"
84 #define N_BADMAG(x) ((((x).a_info & ~007200) != ZMAGIC) && \
85                      (((x).a_info & ~006000) != OMAGIC) && \
86                      ((x).a_info != NMAGIC))
87 #define N_MAGIC(x) ((x).a_info & ~07200)
88
89 #include "bfd.h"
90 #include "sysdep.h"
91 #include "libbfd.h"
92
93 #define WRITE_HEADERS(abfd, execp)                                         \
94   {                                                                        \
95     bfd_size_type text_size; /* dummy vars */                              \
96     file_ptr text_end;                                                     \
97     if (adata(abfd).magic == undecided_magic)                              \
98       NAME(aout,adjust_sizes_and_vmas) (abfd, &text_size, &text_end);      \
99                                                                            \
100     execp->a_syms = bfd_get_symcount (abfd) * EXTERNAL_NLIST_SIZE;         \
101     execp->a_entry = bfd_get_start_address (abfd);                         \
102                                                                            \
103     execp->a_trsize = ((obj_textsec (abfd)->reloc_count) *                 \
104                        obj_reloc_entry_size (abfd));                       \
105     execp->a_drsize = ((obj_datasec (abfd)->reloc_count) *                 \
106                        obj_reloc_entry_size (abfd));                       \
107     NAME(aout,swap_exec_header_out) (abfd, execp, &exec_bytes);            \
108                                                                            \
109     if (bfd_seek (abfd, (file_ptr) 0, SEEK_SET) != 0) return false;        \
110     if (bfd_write ((PTR) &exec_bytes, 1, EXEC_BYTES_SIZE, abfd)            \
111         != EXEC_BYTES_SIZE)                                                \
112       return false;                                                        \
113     /* Now write out reloc info, followed by syms and strings */           \
114                                                                            \
115     if (bfd_get_outsymbols (abfd) != (asymbol **) NULL                     \
116         && bfd_get_symcount (abfd) != 0)                                   \
117       {                                                                    \
118         if (bfd_seek (abfd, (file_ptr) (N_SYMOFF(*execp)), SEEK_SET) != 0)  \
119           return false;                                                    \
120                                                                            \
121         if (! NAME(aout,write_syms) (abfd)) return false;                  \
122                                                                            \
123         if (bfd_seek (abfd, (file_ptr) (N_TRELOFF(*execp)), SEEK_SET) != 0) \
124           return false;                                                    \
125                                                                            \
126         if (! riscix_squirt_out_relocs (abfd, obj_textsec (abfd)))         \
127           return false;                                                    \
128         if (bfd_seek (abfd, (file_ptr) (N_DRELOFF(*execp)), SEEK_SET) != 0) \
129           return false;                                                    \
130                                                                            \
131         if (!NAME(aout,squirt_out_relocs) (abfd, obj_datasec (abfd)))      \
132           return false;                                                    \
133       }                                                                    \
134   }
135
136 #include "libaout.h"
137 #include "aout/aout64.h"
138
139 static bfd_reloc_status_type
140 riscix_fix_pcrel_26_done PARAMS ((bfd *, arelent *, asymbol *, PTR,
141                                   asection *, bfd *, char **));
142
143 static bfd_reloc_status_type
144 riscix_fix_pcrel_26 PARAMS ((bfd *, arelent *, asymbol *, PTR,
145                              asection *, bfd *, char **));
146
147 static reloc_howto_type riscix_std_reloc_howto[] = {
148   /* type              rs size bsz  pcrel bitpos ovrf                     sf name     part_inpl readmask  setmask    pcdone */
149   HOWTO( 0,              0,  0,   8,  false, 0, complain_overflow_bitfield,0,"8",        true, 0x000000ff,0x000000ff, false),
150   HOWTO( 1,              0,  1,   16, false, 0, complain_overflow_bitfield,0,"16",        true, 0x0000ffff,0x0000ffff, false),
151   HOWTO( 2,              0,  2,   32, false, 0, complain_overflow_bitfield,0,"32",        true, 0xffffffff,0xffffffff, false),
152   HOWTO( 3,              2,  3,   26, true, 0, complain_overflow_signed,  riscix_fix_pcrel_26 , "ARM26",      true, 0x00ffffff,0x00ffffff, false),
153   HOWTO( 4,              0,  0,   8,  true,  0, complain_overflow_signed,  0,"DISP8",     true, 0x000000ff,0x000000ff, true),
154   HOWTO( 5,              0,  1,   16, true,  0, complain_overflow_signed,  0,"DISP16",    true, 0x0000ffff,0x0000ffff, true),
155   HOWTO( 6,              0,  2,   32, true,  0, complain_overflow_signed,  0,"DISP32",    true, 0xffffffff,0xffffffff, true),
156   HOWTO( 7,              2,  3,   26, false, 0, complain_overflow_signed,  riscix_fix_pcrel_26_done, "ARM26D",true,0x00ffffff,0x00ffffff, false),
157   EMPTY_HOWTO (-1),
158   HOWTO( 9,              0, -1,   16, false, 0, complain_overflow_bitfield,0,"NEG16",        true, 0x0000ffff,0x0000ffff, false),
159   HOWTO( 10,              0, -2,   32, false, 0, complain_overflow_bitfield,0,"NEG32",        true, 0xffffffff,0xffffffff, false)
160 };
161
162 #define RISCIX_TABLE_SIZE \
163   (sizeof (riscix_std_reloc_howto) / sizeof (reloc_howto_type))
164
165 static bfd_reloc_status_type
166 riscix_fix_pcrel_26_done (abfd, reloc_entry, symbol, data, input_section,
167                           output_bfd, error_message)
168      bfd *abfd ATTRIBUTE_UNUSED;
169      arelent *reloc_entry ATTRIBUTE_UNUSED;
170      asymbol *symbol ATTRIBUTE_UNUSED;
171      PTR data ATTRIBUTE_UNUSED;
172      asection *input_section ATTRIBUTE_UNUSED;
173      bfd *output_bfd ATTRIBUTE_UNUSED;
174      char **error_message ATTRIBUTE_UNUSED;
175 {
176   /* This is dead simple at present.  */
177   return bfd_reloc_ok;
178 }
179
180 static bfd_reloc_status_type
181 riscix_fix_pcrel_26 (abfd, reloc_entry, symbol, data, input_section,
182                      output_bfd, error_message)
183      bfd *abfd;
184      arelent *reloc_entry;
185      asymbol *symbol;
186      PTR data;
187      asection *input_section;
188      bfd *output_bfd;
189      char **error_message ATTRIBUTE_UNUSED;
190 {
191   bfd_vma relocation;
192   bfd_size_type addr = reloc_entry->address;
193   long target = bfd_get_32 (abfd, (bfd_byte *) data + addr);
194   bfd_reloc_status_type flag = bfd_reloc_ok;
195
196   /* If this is an undefined symbol, return error */
197   if (symbol->section == &bfd_und_section
198       && (symbol->flags & BSF_WEAK) == 0)
199     return output_bfd ? bfd_reloc_continue : bfd_reloc_undefined;
200
201   /* If the sections are different, and we are doing a partial relocation,
202      just ignore it for now.  */
203   if (symbol->section->name != input_section->name
204       && output_bfd != (bfd *)NULL)
205     return bfd_reloc_continue;
206
207   relocation = (target & 0x00ffffff) << 2;
208   relocation = (relocation ^ 0x02000000) - 0x02000000; /* Sign extend */
209   relocation += symbol->value;
210   relocation += symbol->section->output_section->vma;
211   relocation += symbol->section->output_offset;
212   relocation += reloc_entry->addend;
213   relocation -= input_section->output_section->vma;
214   relocation -= input_section->output_offset;
215   relocation -= addr;
216   if (relocation & 3)
217     return bfd_reloc_overflow;
218
219   /* Check for overflow */
220   if (relocation & 0x02000000)
221     {
222       if ((relocation & ~ (bfd_vma) 0x03ffffff) != ~ (bfd_vma) 0x03ffffff)
223         flag = bfd_reloc_overflow;
224     }
225   else if (relocation & ~0x03ffffff)
226     flag = bfd_reloc_overflow;
227
228   target &= ~0x00ffffff;
229   target |= (relocation >> 2) & 0x00ffffff;
230   bfd_put_32 (abfd, target, (bfd_byte *) data + addr);
231
232   /* Now the ARM magic... Change the reloc type so that it is marked as done.
233      Strictly this is only necessary if we are doing a partial relocation.  */
234   reloc_entry->howto = &riscix_std_reloc_howto[7];
235
236   return flag;
237 }
238
239 reloc_howto_type *
240 riscix_reloc_type_lookup (abfd, code)
241      bfd *abfd;
242      bfd_reloc_code_real_type code;
243 {
244 #define ASTD(i,j)       case i: return &riscix_std_reloc_howto[j]
245   if (code == BFD_RELOC_CTOR)
246     switch (bfd_get_arch_info (abfd)->bits_per_address)
247       {
248       case 32:
249         code = BFD_RELOC_32;
250         break;
251       default: return (reloc_howto_type *) NULL;
252       }
253
254   switch (code)
255     {
256       ASTD (BFD_RELOC_16, 1);
257       ASTD (BFD_RELOC_32, 2);
258       ASTD (BFD_RELOC_ARM_PCREL_BRANCH, 3);
259       ASTD (BFD_RELOC_8_PCREL, 4);
260       ASTD (BFD_RELOC_16_PCREL, 5);
261       ASTD (BFD_RELOC_32_PCREL, 6);
262     default: return (reloc_howto_type *) NULL;
263     }
264 }
265
266 #define MY_bfd_link_hash_table_create _bfd_generic_link_hash_table_create
267 #define MY_bfd_link_add_symbols _bfd_generic_link_add_symbols
268 #define MY_final_link_callback should_not_be_used
269 #define MY_bfd_final_link _bfd_generic_final_link
270
271 #define MY_bfd_reloc_type_lookup riscix_reloc_type_lookup
272 #define MY_canonicalize_reloc riscix_canonicalize_reloc
273 #define MY_object_p riscix_object_p
274
275 static const bfd_target *riscix_callback PARAMS ((bfd *));
276
277 void
278 riscix_swap_std_reloc_out (abfd, g, natptr)
279      bfd *abfd;
280      arelent *g;
281      struct reloc_std_external *natptr;
282 {
283   int r_index;
284   asymbol *sym = *(g->sym_ptr_ptr);
285   int r_extern;
286   int r_length;
287   int r_pcrel;
288   int r_neg = 0;        /* Negative relocs use the BASEREL bit.  */
289   asection *output_section = sym->section->output_section;
290
291   PUT_WORD(abfd, g->address, natptr->r_address);
292
293   r_length = g->howto->size ;   /* Size as a power of two */
294   if (r_length < 0)
295     {
296       r_length = -r_length;
297       r_neg = 1;
298     }
299
300   r_pcrel  = (int) g->howto->pc_relative; /* Relative to PC? */
301
302   /* For RISC iX, in pc-relative relocs the r_pcrel bit means that the
303      relocation has been done already (Only for the 26-bit one I think)???!!!
304      */
305
306   if (r_length == 3)
307     r_pcrel = r_pcrel ? 0 : 1;
308
309 #if 0
310   /* For a standard reloc, the addend is in the object file.  */
311   r_addend = g->addend + (*(g->sym_ptr_ptr))->section->output_section->vma;
312 #endif
313
314   /* name was clobbered by aout_write_syms to be symbol index */
315
316   /* If this relocation is relative to a symbol then set the
317      r_index to the symbols index, and the r_extern bit.
318
319      Absolute symbols can come in in two ways, either as an offset
320      from the abs section, or as a symbol which has an abs value.
321      check for that here
322      */
323
324   if (bfd_is_com_section (output_section)
325       || output_section == &bfd_abs_section
326       || output_section == &bfd_und_section)
327     {
328       if (bfd_abs_section.symbol == sym)
329         {
330           /* Whoops, looked like an abs symbol, but is really an offset
331              from the abs section */
332           r_index = 0;
333           r_extern = 0;
334         }
335       else
336         {
337           /* Fill in symbol */
338           r_extern = 1;
339           r_index = (*g->sym_ptr_ptr)->udata.i;
340         }
341     }
342   else
343     {
344       /* Just an ordinary section */
345       r_extern = 0;
346       r_index  = output_section->target_index;
347     }
348
349   /* now the fun stuff */
350   if (bfd_header_big_endian (abfd))
351     {
352       natptr->r_index[0] = r_index >> 16;
353       natptr->r_index[1] = r_index >> 8;
354       natptr->r_index[2] = r_index;
355       natptr->r_type[0] =
356         (  (r_extern ?   RELOC_STD_BITS_EXTERN_BIG: 0)
357          | (r_pcrel  ?   RELOC_STD_BITS_PCREL_BIG: 0)
358          | (r_neg    ?   RELOC_STD_BITS_BASEREL_BIG: 0)
359          | (r_length <<  RELOC_STD_BITS_LENGTH_SH_BIG));
360     }
361   else
362     {
363       natptr->r_index[2] = r_index >> 16;
364       natptr->r_index[1] = r_index >> 8;
365       natptr->r_index[0] = r_index;
366       natptr->r_type[0] =
367         (  (r_extern ?   RELOC_STD_BITS_EXTERN_LITTLE: 0)
368          | (r_pcrel  ?   RELOC_STD_BITS_PCREL_LITTLE: 0)
369          | (r_neg    ?   RELOC_STD_BITS_BASEREL_LITTLE: 0)
370          | (r_length <<  RELOC_STD_BITS_LENGTH_SH_LITTLE));
371     }
372 }
373
374 boolean
375 riscix_squirt_out_relocs (abfd, section)
376      bfd *abfd;
377      asection *section;
378 {
379   arelent **generic;
380   unsigned char *native, *natptr;
381   size_t each_size;
382
383   unsigned int count = section->reloc_count;
384   size_t natsize;
385
386   if (count == 0) return true;
387
388   each_size = obj_reloc_entry_size (abfd);
389   natsize = each_size * count;
390   native = (unsigned char *) bfd_zalloc (abfd, natsize);
391   if (!native)
392     return false;
393
394   generic = section->orelocation;
395
396   for (natptr = native;
397        count != 0;
398        --count, natptr += each_size, ++generic)
399     riscix_swap_std_reloc_out (abfd, *generic,
400                                (struct reloc_std_external *) natptr);
401
402   if ( bfd_write ((PTR) native, 1, natsize, abfd) != natsize)
403     {
404       bfd_release(abfd, native);
405       return false;
406     }
407
408   bfd_release (abfd, native);
409   return true;
410 }
411
412 /*
413  * This is just like the standard aoutx.h version but we need to do our
414  * own mapping of external reloc type values to howto entries.
415  */
416 long
417 MY(canonicalize_reloc) (abfd, section, relptr, symbols)
418       bfd *abfd;
419       sec_ptr section;
420       arelent **relptr;
421       asymbol **symbols;
422 {
423   arelent *tblptr = section->relocation;
424   unsigned int count, c;
425   extern reloc_howto_type NAME(aout,std_howto_table)[];
426
427   /* If we have already read in the relocation table, return the values.  */
428   if (section->flags & SEC_CONSTRUCTOR) {
429     arelent_chain *chain = section->constructor_chain;
430
431     for (count = 0; count < section->reloc_count; count++) {
432       *relptr++ = &chain->relent;
433       chain = chain->next;
434     }
435     *relptr = 0;
436     return section->reloc_count;
437   }
438   if (tblptr && section->reloc_count) {
439     for (count = 0; count++ < section->reloc_count;)
440       *relptr++ = tblptr++;
441     *relptr = 0;
442     return section->reloc_count;
443   }
444
445   if (!NAME(aout,slurp_reloc_table) (abfd, section, symbols))
446     return -1;
447   tblptr = section->relocation;
448
449   /* fix up howto entries */
450   for (count = 0; count++ < section->reloc_count;)
451     {
452       c = tblptr->howto - NAME(aout,std_howto_table);
453       BFD_ASSERT (c < RISCIX_TABLE_SIZE);
454       tblptr->howto = &riscix_std_reloc_howto[c];
455
456       *relptr++ = tblptr++;
457     }
458   *relptr = 0;
459   return section->reloc_count;
460 }
461
462 /* This is the same as NAME(aout,some_aout_object_p), but has different
463    expansions of the macro definitions.  */
464
465 const bfd_target *
466 riscix_some_aout_object_p (abfd, execp, callback_to_real_object_p)
467      bfd *abfd;
468      struct internal_exec *execp;
469      const bfd_target *(*callback_to_real_object_p) PARAMS ((bfd *));
470 {
471   struct aout_data_struct *rawptr, *oldrawptr;
472   const bfd_target *result;
473
474   rawptr = ((struct aout_data_struct  *)
475             bfd_zalloc (abfd, sizeof (struct aout_data_struct )));
476
477   if (rawptr == NULL)
478     return 0;
479
480   oldrawptr = abfd->tdata.aout_data;
481   abfd->tdata.aout_data = rawptr;
482
483   /* Copy the contents of the old tdata struct.
484      In particular, we want the subformat, since for hpux it was set in
485      hp300hpux.c:swap_exec_header_in and will be used in
486      hp300hpux.c:callback.  */
487   if (oldrawptr != NULL)
488     *abfd->tdata.aout_data = *oldrawptr;
489
490   abfd->tdata.aout_data->a.hdr = &rawptr->e;
491   *(abfd->tdata.aout_data->a.hdr) = *execp;     /* Copy in the internal_exec
492                                                    struct */
493   execp = abfd->tdata.aout_data->a.hdr;
494
495   /* Set the file flags */
496   abfd->flags = BFD_NO_FLAGS;
497   if (execp->a_drsize || execp->a_trsize)
498     abfd->flags |= HAS_RELOC;
499   /* Setting of EXEC_P has been deferred to the bottom of this function */
500   if (execp->a_syms)
501     abfd->flags |= HAS_LINENO | HAS_DEBUG | HAS_SYMS | HAS_LOCALS;
502   if (N_DYNAMIC(*execp))
503     abfd->flags |= DYNAMIC;
504
505   if ((execp->a_info & MF_SQUEEZED) != 0) /* Squeezed files aren't supported
506                                              (yet)! */
507     {
508       bfd_set_error (bfd_error_wrong_format);
509       return NULL;
510     }
511   else if ((execp->a_info & MF_IS_SL) != 0)     /* Nor are shared libraries */
512     {
513       bfd_set_error (bfd_error_wrong_format);
514       return NULL;
515     }
516   else if (N_MAGIC (*execp) == ZMAGIC)
517     {
518       abfd->flags |= D_PAGED | WP_TEXT;
519       adata (abfd).magic = z_magic;
520     }
521   else if (N_MAGIC (*execp) == NMAGIC)
522     {
523       abfd->flags |= WP_TEXT;
524       adata (abfd).magic = n_magic;
525     }
526   else if (N_MAGIC (*execp) == OMAGIC)
527     adata (abfd).magic = o_magic;
528   else
529     {
530       /* Should have been checked with N_BADMAG before this routine
531          was called.  */
532       abort ();
533     }
534
535   bfd_get_start_address (abfd) = execp->a_entry;
536
537   obj_aout_symbols (abfd) = (aout_symbol_type *)NULL;
538   bfd_get_symcount (abfd) = execp->a_syms / sizeof (struct external_nlist);
539
540   /* The default relocation entry size is that of traditional V7 Unix.  */
541   obj_reloc_entry_size (abfd) = RELOC_STD_SIZE;
542
543   /* The default symbol entry size is that of traditional Unix.  */
544   obj_symbol_entry_size (abfd) = EXTERNAL_NLIST_SIZE;
545
546   obj_aout_external_syms (abfd) = NULL;
547   obj_aout_external_strings (abfd) = NULL;
548   obj_aout_sym_hashes (abfd) = NULL;
549
550   if (! NAME(aout,make_sections) (abfd))
551     return NULL;
552
553   obj_datasec (abfd)->_raw_size = execp->a_data;
554   obj_bsssec (abfd)->_raw_size = execp->a_bss;
555
556   obj_textsec (abfd)->flags =
557     (execp->a_trsize != 0
558      ? (SEC_ALLOC | SEC_LOAD | SEC_CODE | SEC_HAS_CONTENTS | SEC_RELOC)
559      : (SEC_ALLOC | SEC_LOAD | SEC_CODE | SEC_HAS_CONTENTS));
560   obj_datasec (abfd)->flags =
561     (execp->a_drsize != 0
562      ? (SEC_ALLOC | SEC_LOAD | SEC_DATA | SEC_HAS_CONTENTS | SEC_RELOC)
563      : (SEC_ALLOC | SEC_LOAD | SEC_DATA | SEC_HAS_CONTENTS));
564   obj_bsssec (abfd)->flags = SEC_ALLOC;
565
566   result = (*callback_to_real_object_p) (abfd);
567
568 #if defined(MACH) || defined(STAT_FOR_EXEC)
569   /* The original heuristic doesn't work in some important cases. The
570    * a.out file has no information about the text start address. For
571    * files (like kernels) linked to non-standard addresses (ld -Ttext
572    * nnn) the entry point may not be between the default text start
573    * (obj_textsec(abfd)->vma) and (obj_textsec(abfd)->vma) + text size
574    * This is not just a mach issue. Many kernels are loaded at non
575    * standard addresses.
576    */
577   {
578     struct stat stat_buf;
579     if (abfd->iostream != NULL
580         && (abfd->flags & BFD_IN_MEMORY) == 0
581         && (fstat(fileno((FILE *) (abfd->iostream)), &stat_buf) == 0)
582         && ((stat_buf.st_mode & 0111) != 0))
583       abfd->flags |= EXEC_P;
584   }
585 #else /* ! MACH */
586   /* Now that the segment addresses have been worked out, take a better
587      guess at whether the file is executable.  If the entry point
588      is within the text segment, assume it is.  (This makes files
589      executable even if their entry point address is 0, as long as
590      their text starts at zero.)
591
592      At some point we should probably break down and stat the file and
593      declare it executable if (one of) its 'x' bits are on...  */
594   if ((execp->a_entry >= obj_textsec(abfd)->vma) &&
595       (execp->a_entry < obj_textsec(abfd)->vma + obj_textsec(abfd)->_raw_size))
596     abfd->flags |= EXEC_P;
597 #endif /* MACH */
598   if (result)
599     {
600     }
601   else
602     {
603       free (rawptr);
604       abfd->tdata.aout_data = oldrawptr;
605     }
606   return result;
607 }
608
609 static const bfd_target *
610 MY(object_p) (abfd)
611      bfd *abfd;
612 {
613   struct external_exec exec_bytes;      /* Raw exec header from file */
614   struct internal_exec exec;            /* Cleaned-up exec header */
615   const bfd_target *target;
616
617   if (bfd_read ((PTR) &exec_bytes, 1, EXEC_BYTES_SIZE, abfd)
618       != EXEC_BYTES_SIZE) {
619     if (bfd_get_error () != bfd_error_system_call)
620       bfd_set_error (bfd_error_wrong_format);
621     return 0;
622   }
623
624   exec.a_info = bfd_h_get_32 (abfd, exec_bytes.e_info);
625
626   if (N_BADMAG (exec)) return 0;
627 #ifdef MACHTYPE_OK
628   if (!(MACHTYPE_OK (N_MACHTYPE (exec)))) return 0;
629 #endif
630
631   NAME(aout,swap_exec_header_in) (abfd, &exec_bytes, &exec);
632
633   target = riscix_some_aout_object_p (abfd, &exec, MY(callback));
634
635   return target;
636 }
637
638 #include "aout-target.h"