Back to index

cell-binutils  2.17cvs20070401
riscix.c
Go to the documentation of this file.
00001 /* BFD back-end for RISC iX (Acorn, arm) binaries.
00002    Copyright 1994, 1995, 1996, 1997, 1998, 1999, 2000, 2001, 2002, 2004,
00003    2005, 2007 Free Software Foundation, Inc.
00004    Contributed by Richard Earnshaw (rwe@pegasus.esprit.ec.org)
00005 
00006    This file is part of BFD, the Binary File Descriptor library.
00007 
00008    This program is free software; you can redistribute it and/or modify
00009    it under the terms of the GNU General Public License as published by
00010    the Free Software Foundation; either version 2 of the License, or
00011    (at your option) any later version.
00012 
00013    This program is distributed in the hope that it will be useful,
00014    but WITHOUT ANY WARRANTY; without even the implied warranty of
00015    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
00016    GNU General Public License for more details.
00017 
00018    You should have received a copy of the GNU General Public License
00019    along with this program; if not, write to the Free Software
00020    Foundation, Inc., 51 Franklin Street - Fifth Floor, Boston, MA 02110-1301, USA.  */
00021 
00022 /* RISC iX overloads the MAGIC field to indicate more than just the usual
00023    [ZNO]MAGIC values.  Also included are squeezing information and
00024    shared library usage.  */
00025 
00026 /* The following come from the man page.  */
00027 #define SHLIBLEN 60
00028 
00029 #define MF_IMPURE       00200
00030 #define MF_SQUEEZED     01000
00031 #define MF_USES_SL      02000
00032 #define MF_IS_SL        04000
00033 
00034 /* Common combinations.  */
00035 
00036 /* Demand load (impure text).  */
00037 #define IMAGIC          (MF_IMPURE | ZMAGIC)
00038 
00039 /* OMAGIC with large header.
00040    May contain a ref to a shared lib required by the object.  */
00041 #define SPOMAGIC        (MF_USES_SL | OMAGIC)
00042 
00043 /* A reference to a shared library.
00044    The text portion of the object contains "overflow text" from
00045    the shared library to be linked in with an object.  */
00046 #define SLOMAGIC        (MF_IS_SL | OMAGIC) 
00047 
00048 /* Sqeezed demand paged.
00049    NOTE: This interpretation of QMAGIC seems to be at variance
00050    with that used on other architectures.  */
00051 #define QMAGIC          (MF_SQUEEZED | ZMAGIC)
00052 
00053 /* Program which uses sl.  */
00054 #define SPZMAGIC        (MF_USES_SL | ZMAGIC)
00055 
00056 /* Sqeezed ditto.  */
00057 #define SPQMAGIC        (MF_USES_SL | QMAGIC)
00058 
00059 /* Shared lib part of prog.  */
00060 #define SLZMAGIC        (MF_IS_SL | ZMAGIC)
00061 
00062 /* Sl which uses another.  */
00063 #define SLPZMAGIC       (MF_USES_SL | SLZMAGIC)
00064 
00065 #define N_SHARED_LIB(x) ((x).a_info & MF_USES_SL)
00066 
00067 /* Only a pure OMAGIC file has the minimal header.  */
00068 #define N_TXTOFF(x)         \
00069  ((x).a_info == OMAGIC             \
00070   ? 32                      \
00071   : (N_MAGIC(x) == ZMAGIC   \
00072      ? TARGET_PAGE_SIZE            \
00073      : 999))
00074 
00075 #define N_TXTADDR(x)                                                \
00076   (N_MAGIC(x) != ZMAGIC                                                    \
00077    ? (bfd_vma) 0 /* object file or NMAGIC */                               \
00078    /* Programs with shared libs are loaded at the first page after all the   \
00079       text segments of the shared library programs.  Without looking this    \
00080       up we can't know exactly what the address will be.  A reasonable guess \
00081       is that a_entry will be in the first page of the executable.  */            \
00082    : (N_SHARED_LIB(x)                                                      \
00083       ? ((x).a_entry & ~(bfd_vma) (TARGET_PAGE_SIZE - 1))                  \
00084       : (bfd_vma) TEXT_START_ADDR))
00085 
00086 #define N_SYMOFF(x) \
00087   (N_TXTOFF (x) + (x).a_text + (x).a_data + (x).a_trsize + (x).a_drsize)
00088 
00089 #define N_STROFF(x) (N_SYMOFF (x) + (x).a_syms)
00090 
00091 #define TEXT_START_ADDR   32768
00092 #define TARGET_PAGE_SIZE  32768
00093 #define SEGMENT_SIZE      TARGET_PAGE_SIZE
00094 #define DEFAULT_ARCH      bfd_arch_arm
00095 
00096 /* Do not "beautify" the CONCAT* macro args.  Traditional C will not
00097    remove whitespace added here, and thus will fail to concatenate
00098    the tokens.  */
00099 #define MY(OP) CONCAT2 (riscix_,OP)
00100 #define TARGETNAME "a.out-riscix"
00101 #define N_BADMAG(x) ((((x).a_info & ~007200) != ZMAGIC) \
00102                   && (((x).a_info & ~006000) != OMAGIC) \
00103                   && ((x).a_info != NMAGIC))
00104 #define N_MAGIC(x) ((x).a_info & ~07200)
00105 
00106 #include "bfd.h"
00107 #include "sysdep.h"
00108 #include "libbfd.h"
00109 
00110 #define WRITE_HEADERS(abfd, execp)                                 \
00111   {                                                                \
00112     bfd_size_type text_size; /* Dummy vars.  */                           \
00113     file_ptr text_end;                                                    \
00114                                                                    \
00115     if (adata (abfd).magic == undecided_magic)                            \
00116       NAME (aout, adjust_sizes_and_vmas) (abfd, & text_size, & text_end);   \
00117                                                                    \
00118     execp->a_syms = bfd_get_symcount (abfd) * EXTERNAL_NLIST_SIZE;        \
00119     execp->a_entry = bfd_get_start_address (abfd);                        \
00120                                                                    \
00121     execp->a_trsize = ((obj_textsec (abfd)->reloc_count) *                \
00122                      obj_reloc_entry_size (abfd));                        \
00123     execp->a_drsize = ((obj_datasec (abfd)->reloc_count) *                \
00124                      obj_reloc_entry_size (abfd));                        \
00125     NAME (aout, swap_exec_header_out) (abfd, execp, & exec_bytes);        \
00126                                                                    \
00127     if (bfd_seek (abfd, (file_ptr) 0, SEEK_SET) != 0                      \
00128        || bfd_bwrite ((void *) & exec_bytes, (bfd_size_type) EXEC_BYTES_SIZE,  \
00129                     abfd) != EXEC_BYTES_SIZE)                             \
00130       return FALSE;                                                \
00131     /* Now write out reloc info, followed by syms and strings.  */        \
00132                                                                    \
00133     if (bfd_get_outsymbols (abfd) != NULL                          \
00134        && bfd_get_symcount (abfd) != 0)                            \
00135       {                                                                   \
00136        if (bfd_seek (abfd, (file_ptr) (N_SYMOFF (* execp)), SEEK_SET) != 0)\
00137          return FALSE;                                                    \
00138                                                                    \
00139        if (! NAME (aout, write_syms) (abfd))                              \
00140           return FALSE;                                                   \
00141                                                                    \
00142        if (bfd_seek (abfd, (file_ptr) (N_TRELOFF (* execp)), SEEK_SET) != 0)\
00143          return FALSE;                                                    \
00144                                                                    \
00145        if (! riscix_squirt_out_relocs (abfd, obj_textsec (abfd)))         \
00146          return FALSE;                                                    \
00147        if (bfd_seek (abfd, (file_ptr) (N_DRELOFF (* execp)), SEEK_SET) != 0)\
00148          return FALSE;                                                    \
00149                                                                    \
00150        if (!NAME (aout, squirt_out_relocs) (abfd, obj_datasec (abfd)))           \
00151          return FALSE;                                                    \
00152       }                                                                   \
00153   }
00154 
00155 #include "libaout.h"
00156 #include "aout/aout64.h"
00157 
00158 static bfd_reloc_status_type
00159 riscix_fix_pcrel_26_done (bfd *abfd ATTRIBUTE_UNUSED,
00160                        arelent *reloc_entry ATTRIBUTE_UNUSED,
00161                        asymbol *symbol ATTRIBUTE_UNUSED,
00162                        void * data ATTRIBUTE_UNUSED,
00163                        asection *input_section ATTRIBUTE_UNUSED,
00164                        bfd *output_bfd ATTRIBUTE_UNUSED,
00165                        char **error_message ATTRIBUTE_UNUSED)
00166 {
00167   /* This is dead simple at present.  */
00168   return bfd_reloc_ok;
00169 }
00170 
00171 static bfd_reloc_status_type riscix_fix_pcrel_26 (bfd *, arelent *, asymbol *, void *, asection *, bfd *, char **);
00172 static const bfd_target *riscix_callback (bfd *);
00173 
00174 static reloc_howto_type riscix_std_reloc_howto[] =
00175 {
00176   /* Type              rs size bsz  pcrel bitpos ovrf                     sf name     part_inpl readmask  setmask    pcdone */
00177   HOWTO( 0,              0,  0,   8,  FALSE, 0, complain_overflow_bitfield,0,"8",         TRUE, 0x000000ff,0x000000ff, FALSE),
00178   HOWTO( 1,              0,  1,   16, FALSE, 0, complain_overflow_bitfield,0,"16",        TRUE, 0x0000ffff,0x0000ffff, FALSE),
00179   HOWTO( 2,              0,  2,   32, FALSE, 0, complain_overflow_bitfield,0,"32",        TRUE, 0xffffffff,0xffffffff, FALSE),
00180   HOWTO( 3,              2,  3,   26, TRUE,  0, complain_overflow_signed,  riscix_fix_pcrel_26 , "ARM26",      TRUE, 0x00ffffff,0x00ffffff, FALSE),
00181   HOWTO( 4,              0,  0,   8,  TRUE,  0, complain_overflow_signed,  0,"DISP8",     TRUE, 0x000000ff,0x000000ff, TRUE),
00182   HOWTO( 5,              0,  1,   16, TRUE,  0, complain_overflow_signed,  0,"DISP16",    TRUE, 0x0000ffff,0x0000ffff, TRUE),
00183   HOWTO( 6,              0,  2,   32, TRUE,  0, complain_overflow_signed,  0,"DISP32",    TRUE, 0xffffffff,0xffffffff, TRUE),
00184   HOWTO( 7,              2,  3,   26, FALSE, 0, complain_overflow_signed,  riscix_fix_pcrel_26_done, "ARM26D",TRUE,0x00ffffff,0x00ffffff, FALSE),
00185   EMPTY_HOWTO (-1),
00186   HOWTO( 9,              0, -1,   16, FALSE, 0, complain_overflow_bitfield,0,"NEG16",     TRUE, 0x0000ffff,0x0000ffff, FALSE),
00187   HOWTO( 10,              0, -2,  32, FALSE, 0, complain_overflow_bitfield,0,"NEG32",     TRUE, 0xffffffff,0xffffffff, FALSE)
00188 };
00189 
00190 #define RISCIX_TABLE_SIZE \
00191   (sizeof (riscix_std_reloc_howto) / sizeof (reloc_howto_type))
00192 
00193 static bfd_reloc_status_type
00194 riscix_fix_pcrel_26 (bfd *abfd,
00195                    arelent *reloc_entry,
00196                    asymbol *symbol,
00197                    void * data,
00198                    asection *input_section,
00199                    bfd *output_bfd,
00200                    char **error_message ATTRIBUTE_UNUSED)
00201 {
00202   bfd_vma relocation;
00203   bfd_size_type addr = reloc_entry->address;
00204   long target = bfd_get_32 (abfd, (bfd_byte *) data + addr);
00205   bfd_reloc_status_type flag = bfd_reloc_ok;
00206 
00207   /* If this is an undefined symbol, return error.  */
00208   if (symbol->section == &bfd_und_section
00209       && (symbol->flags & BSF_WEAK) == 0)
00210     return output_bfd ? bfd_reloc_continue : bfd_reloc_undefined;
00211 
00212   /* If the sections are different, and we are doing a partial relocation,
00213      just ignore it for now.  */
00214   if (symbol->section->name != input_section->name
00215       && output_bfd != NULL)
00216     return bfd_reloc_continue;
00217 
00218   relocation = (target & 0x00ffffff) << 2;
00219   relocation = (relocation ^ 0x02000000) - 0x02000000; /* Sign extend.  */
00220   relocation += symbol->value;
00221   relocation += symbol->section->output_section->vma;
00222   relocation += symbol->section->output_offset;
00223   relocation += reloc_entry->addend;
00224   relocation -= input_section->output_section->vma;
00225   relocation -= input_section->output_offset;
00226   relocation -= addr;
00227   if (relocation & 3)
00228     return bfd_reloc_overflow;
00229 
00230   /* Check for overflow.  */
00231   if (relocation & 0x02000000)
00232     {
00233       if ((relocation & ~ (bfd_vma) 0x03ffffff) != ~ (bfd_vma) 0x03ffffff)
00234        flag = bfd_reloc_overflow;
00235     }
00236   else if (relocation & ~ (bfd_vma) 0x03ffffff)
00237     flag = bfd_reloc_overflow;
00238 
00239   target &= ~0x00ffffff;
00240   target |= (relocation >> 2) & 0x00ffffff;
00241   bfd_put_32 (abfd, (bfd_vma) target, (bfd_byte *) data + addr);
00242 
00243   /* Now the ARM magic... Change the reloc type so that it is marked as done.
00244      Strictly this is only necessary if we are doing a partial relocation.  */
00245   reloc_entry->howto = &riscix_std_reloc_howto[7];
00246 
00247   return flag;
00248 }
00249 
00250 static reloc_howto_type *
00251 riscix_reloc_type_lookup (bfd *abfd, bfd_reloc_code_real_type code)
00252 {
00253 #define ASTD(i,j)       case i: return &riscix_std_reloc_howto[j]
00254   if (code == BFD_RELOC_CTOR)
00255     switch (bfd_get_arch_info (abfd)->bits_per_address)
00256       {
00257       case 32:
00258         code = BFD_RELOC_32;
00259         break;
00260       default:
00261        return NULL;
00262       }
00263 
00264   switch (code)
00265     {
00266       ASTD (BFD_RELOC_16, 1);
00267       ASTD (BFD_RELOC_32, 2);
00268       ASTD (BFD_RELOC_ARM_PCREL_BRANCH, 3);
00269       ASTD (BFD_RELOC_8_PCREL, 4);
00270       ASTD (BFD_RELOC_16_PCREL, 5);
00271       ASTD (BFD_RELOC_32_PCREL, 6);
00272     default:
00273       return NULL;
00274     }
00275 }
00276 
00277 static reloc_howto_type *
00278 riscix_reloc_name_lookup (bfd *abfd ATTRIBUTE_UNUSED,
00279                        const char *r_name)
00280 {
00281   unsigned int i;
00282 
00283   for (i = 0;
00284        i < sizeof (riscix_std_reloc_howto) / sizeof (riscix_std_reloc_howto[0]);
00285        i++)
00286     if (riscix_std_reloc_howto[i].name != NULL
00287        && strcasecmp (riscix_std_reloc_howto[i].name, r_name) == 0)
00288       return &riscix_std_reloc_howto[i];
00289 
00290   return NULL;
00291 }
00292 
00293 #define MY_bfd_link_hash_table_create  _bfd_generic_link_hash_table_create
00294 #define MY_bfd_link_add_symbols        _bfd_generic_link_add_symbols
00295 #define MY_final_link_callback         should_not_be_used
00296 #define MY_bfd_final_link              _bfd_generic_final_link
00297 
00298 #define MY_bfd_reloc_type_lookup       riscix_reloc_type_lookup
00299 #define MY_bfd_reloc_name_lookup riscix_reloc_name_lookup
00300 #define MY_canonicalize_reloc          riscix_canonicalize_reloc
00301 #define MY_object_p                    riscix_object_p
00302 
00303 static void
00304 riscix_swap_std_reloc_out (bfd *abfd,
00305                         arelent *g,
00306                         struct reloc_std_external *natptr)
00307 {
00308   int r_index;
00309   asymbol *sym = *(g->sym_ptr_ptr);
00310   int r_extern;
00311   int r_length;
00312   int r_pcrel;
00313   int r_neg = 0;     /* Negative relocs use the BASEREL bit.  */
00314   asection *output_section = sym->section->output_section;
00315 
00316   PUT_WORD(abfd, g->address, natptr->r_address);
00317 
00318   r_length = g->howto->size ;   /* Size as a power of two.  */
00319   if (r_length < 0)
00320     {
00321       r_length = -r_length;
00322       r_neg = 1;
00323     }
00324 
00325   r_pcrel  = (int) g->howto->pc_relative; /* Relative to PC?  */
00326 
00327   /* For RISC iX, in pc-relative relocs the r_pcrel bit means that the
00328      relocation has been done already (Only for the 26-bit one I think)?  */
00329   if (r_length == 3)
00330     r_pcrel = r_pcrel ? 0 : 1;
00331 
00332   /* Name was clobbered by aout_write_syms to be symbol index.  */
00333 
00334   /* If this relocation is relative to a symbol then set the
00335      r_index to the symbols index, and the r_extern bit.
00336 
00337      Absolute symbols can come in in two ways, either as an offset
00338      from the abs section, or as a symbol which has an abs value.
00339      check for that here.  */
00340 
00341   if (bfd_is_com_section (output_section)
00342       || output_section == & bfd_abs_section
00343       || output_section == & bfd_und_section)
00344     {
00345       if (bfd_abs_section.symbol == sym)
00346        {
00347          /* Whoops, looked like an abs symbol, but is really an offset
00348             from the abs section.  */
00349          r_index = 0;
00350          r_extern = 0;
00351        }
00352       else
00353        {
00354          /* Fill in symbol.  */
00355          r_extern = 1;
00356          r_index = (*g->sym_ptr_ptr)->udata.i;
00357        }
00358     }
00359   else
00360     {
00361       /* Just an ordinary section.  */
00362       r_extern = 0;
00363       r_index  = output_section->target_index;
00364     }
00365 
00366   /* Now the fun stuff.  */
00367   if (bfd_header_big_endian (abfd))
00368     {
00369       natptr->r_index[0] = r_index >> 16;
00370       natptr->r_index[1] = r_index >> 8;
00371       natptr->r_index[2] = r_index;
00372       natptr->r_type[0] =
00373        (  (r_extern ?   RELOC_STD_BITS_EXTERN_BIG: 0)
00374         | (r_pcrel  ?   RELOC_STD_BITS_PCREL_BIG: 0)
00375         | (r_neg    ?   RELOC_STD_BITS_BASEREL_BIG: 0)
00376         | (r_length <<  RELOC_STD_BITS_LENGTH_SH_BIG));
00377     }
00378   else
00379     {
00380       natptr->r_index[2] = r_index >> 16;
00381       natptr->r_index[1] = r_index >> 8;
00382       natptr->r_index[0] = r_index;
00383       natptr->r_type[0] =
00384        (  (r_extern ?   RELOC_STD_BITS_EXTERN_LITTLE: 0)
00385         | (r_pcrel  ?   RELOC_STD_BITS_PCREL_LITTLE: 0)
00386         | (r_neg    ?   RELOC_STD_BITS_BASEREL_LITTLE: 0)
00387         | (r_length <<  RELOC_STD_BITS_LENGTH_SH_LITTLE));
00388     }
00389 }
00390 
00391 static bfd_boolean
00392 riscix_squirt_out_relocs (bfd *abfd, asection *section)
00393 {
00394   arelent **generic;
00395   unsigned char *native, *natptr;
00396   size_t each_size;
00397   unsigned int count = section->reloc_count;
00398   bfd_size_type natsize;
00399 
00400   if (count == 0)
00401     return TRUE;
00402 
00403   each_size = obj_reloc_entry_size (abfd);
00404   natsize = each_size;
00405   natsize *= count;
00406   native = bfd_zalloc (abfd, natsize);
00407   if (!native)
00408     return FALSE;
00409 
00410   generic = section->orelocation;
00411 
00412   for (natptr = native;
00413        count != 0;
00414        --count, natptr += each_size, ++generic)
00415     riscix_swap_std_reloc_out (abfd, *generic,
00416                             (struct reloc_std_external *) natptr);
00417 
00418   if (bfd_bwrite ((void *) native, natsize, abfd) != natsize)
00419     {
00420       bfd_release (abfd, native);
00421       return FALSE;
00422     }
00423 
00424   bfd_release (abfd, native);
00425   return TRUE;
00426 }
00427 
00428 /* This is just like the standard aoutx.h version but we need to do our
00429    own mapping of external reloc type values to howto entries.  */
00430 
00431 static long
00432 MY (canonicalize_reloc) (bfd *abfd,
00433                       sec_ptr section,
00434                       arelent **relptr,
00435                       asymbol **symbols)
00436 {
00437   arelent *tblptr = section->relocation;
00438   unsigned int count, c;
00439   extern reloc_howto_type NAME (aout, std_howto_table)[];
00440 
00441   /* If we have already read in the relocation table, return the values.  */
00442   if (section->flags & SEC_CONSTRUCTOR)
00443     {
00444       arelent_chain *chain = section->constructor_chain;
00445 
00446       for (count = 0; count < section->reloc_count; count++)
00447        {
00448          *relptr++ = &chain->relent;
00449          chain = chain->next;
00450        }
00451       *relptr = 0;
00452       return section->reloc_count;
00453     }
00454 
00455   if (tblptr && section->reloc_count)
00456     {
00457       for (count = 0; count++ < section->reloc_count;)
00458        *relptr++ = tblptr++;
00459       *relptr = 0;
00460       return section->reloc_count;
00461     }
00462 
00463   if (!NAME (aout, slurp_reloc_table) (abfd, section, symbols))
00464     return -1;
00465   tblptr = section->relocation;
00466 
00467   /* Fix up howto entries.  */
00468   for (count = 0; count++ < section->reloc_count;)
00469     {
00470       c = tblptr->howto - NAME(aout,std_howto_table);
00471       BFD_ASSERT (c < RISCIX_TABLE_SIZE);
00472       tblptr->howto = &riscix_std_reloc_howto[c];
00473 
00474       *relptr++ = tblptr++;
00475     }
00476   *relptr = 0;
00477   return section->reloc_count;
00478 }
00479 
00480 /* This is the same as NAME(aout,some_aout_object_p), but has different
00481    expansions of the macro definitions.  */
00482 
00483 static const bfd_target *
00484 riscix_some_aout_object_p (bfd *abfd,
00485                         struct internal_exec *execp,
00486                         const bfd_target *(*callback_to_real_object_p) (bfd *))
00487 {
00488   struct aout_data_struct *rawptr, *oldrawptr;
00489   const bfd_target *result;
00490   bfd_size_type amt = sizeof (struct aout_data_struct);
00491 
00492   rawptr = bfd_zalloc (abfd, amt);
00493 
00494   if (rawptr == NULL)
00495     return NULL;
00496 
00497   oldrawptr = abfd->tdata.aout_data;
00498   abfd->tdata.aout_data = rawptr;
00499 
00500   /* Copy the contents of the old tdata struct.
00501      In particular, we want the subformat, since for hpux it was set in
00502      hp300hpux.c:swap_exec_header_in and will be used in
00503      hp300hpux.c:callback.  */
00504   if (oldrawptr != NULL)
00505     *abfd->tdata.aout_data = *oldrawptr;
00506 
00507   abfd->tdata.aout_data->a.hdr = &rawptr->e;
00508   /* Copy in the internal_exec struct.  */
00509   *(abfd->tdata.aout_data->a.hdr) = *execp;
00510   execp = abfd->tdata.aout_data->a.hdr;
00511 
00512   /* Set the file flags.  */
00513   abfd->flags = BFD_NO_FLAGS;
00514   if (execp->a_drsize || execp->a_trsize)
00515     abfd->flags |= HAS_RELOC;
00516   /* Setting of EXEC_P has been deferred to the bottom of this function.  */
00517   if (execp->a_syms)
00518     abfd->flags |= HAS_LINENO | HAS_DEBUG | HAS_SYMS | HAS_LOCALS;
00519   if (N_DYNAMIC(*execp))
00520     abfd->flags |= DYNAMIC;
00521 
00522  /* Squeezed files aren't supported (yet)!  */
00523   if ((execp->a_info & MF_SQUEEZED) != 0)
00524     {
00525       bfd_set_error (bfd_error_wrong_format);
00526       return NULL;
00527     }
00528   else if ((execp->a_info & MF_IS_SL) != 0)
00529     {
00530       /* Nor are shared libraries.  */
00531       bfd_set_error (bfd_error_wrong_format);
00532       return NULL;
00533     }
00534   else if (N_MAGIC (*execp) == ZMAGIC)
00535     {
00536       abfd->flags |= D_PAGED | WP_TEXT;
00537       adata (abfd).magic = z_magic;
00538     }
00539   else if (N_MAGIC (*execp) == NMAGIC)
00540     {
00541       abfd->flags |= WP_TEXT;
00542       adata (abfd).magic = n_magic;
00543     }
00544   else if (N_MAGIC (*execp) == OMAGIC)
00545     adata (abfd).magic = o_magic;
00546   else
00547     /* Should have been checked with N_BADMAG before this routine
00548        was called.  */
00549     abort ();
00550 
00551   bfd_get_start_address (abfd) = execp->a_entry;
00552 
00553   obj_aout_symbols (abfd) = NULL;
00554   bfd_get_symcount (abfd) = execp->a_syms / sizeof (struct external_nlist);
00555 
00556   /* The default relocation entry size is that of traditional V7 Unix.  */
00557   obj_reloc_entry_size (abfd) = RELOC_STD_SIZE;
00558 
00559   /* The default symbol entry size is that of traditional Unix.  */
00560   obj_symbol_entry_size (abfd) = EXTERNAL_NLIST_SIZE;
00561 
00562   obj_aout_external_syms (abfd) = NULL;
00563   obj_aout_external_strings (abfd) = NULL;
00564   obj_aout_sym_hashes (abfd) = NULL;
00565 
00566   if (! NAME (aout, make_sections) (abfd))
00567     return NULL;
00568 
00569   obj_datasec (abfd)->size = execp->a_data;
00570   obj_bsssec (abfd)->size = execp->a_bss;
00571 
00572   obj_textsec (abfd)->flags =
00573     (execp->a_trsize != 0
00574      ? (SEC_ALLOC | SEC_LOAD | SEC_CODE | SEC_HAS_CONTENTS | SEC_RELOC)
00575      : (SEC_ALLOC | SEC_LOAD | SEC_CODE | SEC_HAS_CONTENTS));
00576   obj_datasec (abfd)->flags =
00577     (execp->a_drsize != 0
00578      ? (SEC_ALLOC | SEC_LOAD | SEC_DATA | SEC_HAS_CONTENTS | SEC_RELOC)
00579      : (SEC_ALLOC | SEC_LOAD | SEC_DATA | SEC_HAS_CONTENTS));
00580   obj_bsssec (abfd)->flags = SEC_ALLOC;
00581 
00582   result = (*callback_to_real_object_p) (abfd);
00583 
00584 #if defined(MACH) || defined(STAT_FOR_EXEC)
00585   /* The original heuristic doesn't work in some important cases. The
00586      a.out file has no information about the text start address. For
00587      files (like kernels) linked to non-standard addresses (ld -Ttext
00588      nnn) the entry point may not be between the default text start
00589      (obj_textsec(abfd)->vma) and (obj_textsec(abfd)->vma) + text size
00590      This is not just a mach issue. Many kernels are loaded at non
00591      standard addresses.  */
00592   {
00593     struct stat stat_buf;
00594 
00595     if (abfd->iostream != NULL
00596        && (abfd->flags & BFD_IN_MEMORY) == 0
00597         && (fstat(fileno((FILE *) (abfd->iostream)), &stat_buf) == 0)
00598         && ((stat_buf.st_mode & 0111) != 0))
00599       abfd->flags |= EXEC_P;
00600   }
00601 #else /* ! MACH */
00602   /* Now that the segment addresses have been worked out, take a better
00603      guess at whether the file is executable.  If the entry point
00604      is within the text segment, assume it is.  (This makes files
00605      executable even if their entry point address is 0, as long as
00606      their text starts at zero.)
00607 
00608      At some point we should probably break down and stat the file and
00609      declare it executable if (one of) its 'x' bits are on...  */
00610   if ((execp->a_entry >= obj_textsec(abfd)->vma) &&
00611       (execp->a_entry < obj_textsec(abfd)->vma + obj_textsec(abfd)->size))
00612     abfd->flags |= EXEC_P;
00613 #endif /* MACH */
00614   if (result == NULL)
00615     {
00616       free (rawptr);
00617       abfd->tdata.aout_data = oldrawptr;
00618     }
00619   return result;
00620 }
00621 
00622 static const bfd_target *
00623 MY (object_p) (bfd *abfd)
00624 {
00625   struct external_exec exec_bytes;      /* Raw exec header from file.  */
00626   struct internal_exec exec;            /* Cleaned-up exec header.  */
00627   const bfd_target *target;
00628 
00629   if (bfd_bread ((void *) &exec_bytes, (bfd_size_type) EXEC_BYTES_SIZE, abfd)
00630       != EXEC_BYTES_SIZE)
00631     {
00632       if (bfd_get_error () != bfd_error_system_call)
00633        bfd_set_error (bfd_error_wrong_format);
00634       return NULL;
00635     }
00636 
00637   exec.a_info = H_GET_32 (abfd, exec_bytes.e_info);
00638 
00639   if (N_BADMAG (exec))
00640     return NULL;
00641 
00642 #ifdef MACHTYPE_OK
00643   if (!(MACHTYPE_OK (N_MACHTYPE (exec))))
00644     return NULL;
00645 #endif
00646 
00647   NAME (aout, swap_exec_header_in) (abfd, & exec_bytes, & exec);
00648 
00649   target = riscix_some_aout_object_p (abfd, & exec, MY (callback));
00650 
00651   return target;
00652 }
00653 
00654 #include "aout-target.h"