OSDN Git Service

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