OpenCores
URL https://opencores.org/ocsvn/openrisc_me/openrisc_me/trunk

Subversion Repositories openrisc_me

[/] [openrisc/] [trunk/] [gnu-src/] [gdb-6.8/] [bfd/] [riscix.c] - Blame information for rev 24

Go to most recent revision | Details | Compare with Previous | View Log

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

powered by: WebSVN 2.1.0

© copyright 1999-2024 OpenCores.org, equivalent to Oliscience, all rights reserved. OpenCores®, registered trademark.