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

Subversion Repositories openrisc_me

[/] [openrisc/] [trunk/] [gnu-src/] [binutils-2.20.1/] [bfd/] [i386lynx.c] - Blame information for rev 297

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

Line No. Rev Author Line
1 205 julius
/* BFD back-end for i386 a.out binaries under LynxOS.
2
   Copyright 1990, 1991, 1992, 1993, 1994, 1995, 1996, 1999, 2001, 2002,
3
   2003, 2005, 2007 Free Software Foundation, Inc.
4
 
5
   This file is part of BFD, the Binary File Descriptor library.
6
 
7
   This program is free software; you can redistribute it and/or modify
8
   it under the terms of the GNU General Public License as published by
9
   the Free Software Foundation; either version 3 of the License, or
10
   (at your option) any later version.
11
 
12
   This program is distributed in the hope that it will be useful,
13
   but WITHOUT ANY WARRANTY; without even the implied warranty of
14
   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
15
   GNU General Public License for more details.
16
 
17
   You should have received a copy of the GNU General Public License
18
   along with this program; if not, write to the Free Software
19
   Foundation, Inc., 51 Franklin Street - Fifth Floor, Boston,
20
   MA 02110-1301, USA.  */
21
 
22
#define N_SHARED_LIB(x) 0
23
 
24
#define TEXT_START_ADDR 0
25
#define TARGET_PAGE_SIZE 4096
26
#define SEGMENT_SIZE TARGET_PAGE_SIZE
27
#define DEFAULT_ARCH bfd_arch_i386
28
 
29
/* Do not "beautify" the CONCAT* macro args.  Traditional C will not
30
   remove whitespace added here, and thus will fail to concatenate
31
   the tokens.  */
32
#define MY(OP) CONCAT2 (i386lynx_aout_,OP)
33
#define TARGETNAME "a.out-i386-lynx"
34
 
35
#include "sysdep.h"
36
#include "bfd.h"
37
#include "libbfd.h"
38
 
39
#ifndef WRITE_HEADERS
40
#define WRITE_HEADERS(abfd, execp)                                            \
41
      {                                                                       \
42
        bfd_size_type text_size; /* dummy vars */                             \
43
        file_ptr text_end;                                                    \
44
        if (adata(abfd).magic == undecided_magic)                             \
45
          NAME(aout,adjust_sizes_and_vmas) (abfd, &text_size, &text_end);     \
46
                                                                              \
47
        execp->a_syms = bfd_get_symcount (abfd) * EXTERNAL_NLIST_SIZE;        \
48
        execp->a_entry = bfd_get_start_address (abfd);                        \
49
                                                                              \
50
        execp->a_trsize = ((obj_textsec (abfd)->reloc_count) *                \
51
                           obj_reloc_entry_size (abfd));                      \
52
        execp->a_drsize = ((obj_datasec (abfd)->reloc_count) *                \
53
                           obj_reloc_entry_size (abfd));                      \
54
        NAME(aout,swap_exec_header_out) (abfd, execp, &exec_bytes);           \
55
                                                                              \
56
        if (bfd_seek (abfd, (file_ptr) 0, SEEK_SET) != 0                \
57
            || bfd_bwrite ((PTR) &exec_bytes, (bfd_size_type) EXEC_BYTES_SIZE, \
58
                          abfd) != EXEC_BYTES_SIZE)                           \
59
          return FALSE;                                                       \
60
        /* Now write out reloc info, followed by syms and strings */          \
61
                                                                              \
62
        if (bfd_get_symcount (abfd) != 0)                                      \
63
            {                                                                 \
64
              if (bfd_seek (abfd, (file_ptr) (N_SYMOFF(*execp)), SEEK_SET)    \
65
                  != 0)                                                        \
66
                return FALSE;                                                 \
67
                                                                              \
68
              if (! NAME(aout,write_syms) (abfd)) return FALSE;               \
69
                                                                              \
70
              if (bfd_seek (abfd, (file_ptr) (N_TRELOFF(*execp)), SEEK_SET)   \
71
                  != 0)                                                        \
72
                return FALSE;                                                 \
73
                                                                              \
74
              if (!NAME(lynx,squirt_out_relocs) (abfd, obj_textsec (abfd)))   \
75
                return FALSE;                                                 \
76
              if (bfd_seek (abfd, (file_ptr) (N_DRELOFF(*execp)), SEEK_SET)   \
77
                  != 0)                                                        \
78
                return 0;                                                      \
79
                                                                              \
80
              if (!NAME(lynx,squirt_out_relocs) (abfd, obj_datasec (abfd)))   \
81
                return FALSE;                                                 \
82
            }                                                                 \
83
      }
84
#endif
85
 
86
#include "libaout.h"
87
#include "aout/aout64.h"
88
 
89
void NAME (lynx,swap_std_reloc_out)
90
  PARAMS ((bfd *, arelent *, struct reloc_std_external *));
91
void NAME (lynx,swap_ext_reloc_out)
92
  PARAMS ((bfd *, arelent *, struct reloc_ext_external *));
93
void NAME (lynx,swap_ext_reloc_in)
94
  PARAMS ((bfd *, struct reloc_ext_external *, arelent *, asymbol **,
95
           bfd_size_type));
96
void NAME (lynx,swap_std_reloc_in)
97
  PARAMS ((bfd *, struct reloc_std_external *, arelent *, asymbol **,
98
           bfd_size_type));
99
bfd_boolean NAME (lynx,slurp_reloc_table)
100
  PARAMS ((bfd *, sec_ptr, asymbol **));
101
bfd_boolean NAME (lynx,squirt_out_relocs)
102
  PARAMS ((bfd *, asection *));
103
long NAME (lynx,canonicalize_reloc)
104
  PARAMS ((bfd *, sec_ptr, arelent **, asymbol **));
105
 
106
#ifdef LYNX_CORE
107
 
108
char *lynx_core_file_failing_command ();
109
int lynx_core_file_failing_signal ();
110
bfd_boolean lynx_core_file_matches_executable_p ();
111
const bfd_target *lynx_core_file_p ();
112
 
113
#define MY_core_file_failing_command lynx_core_file_failing_command
114
#define MY_core_file_failing_signal lynx_core_file_failing_signal
115
#define MY_core_file_matches_executable_p lynx_core_file_matches_executable_p
116
#define MY_core_file_p lynx_core_file_p
117
 
118
#endif /* LYNX_CORE */
119
 
120
 
121
#define KEEPIT udata.i
122
 
123
extern reloc_howto_type aout_32_ext_howto_table[];
124
extern reloc_howto_type aout_32_std_howto_table[];
125
 
126
/* Standard reloc stuff */
127
/* Output standard relocation information to a file in target byte order. */
128
 
129
void
130
NAME(lynx,swap_std_reloc_out) (abfd, g, natptr)
131
     bfd *abfd;
132
     arelent *g;
133
     struct reloc_std_external *natptr;
134
{
135
  int r_index;
136
  asymbol *sym = *(g->sym_ptr_ptr);
137
  int r_extern;
138
  unsigned int r_length;
139
  int r_pcrel;
140
  int r_baserel, r_jmptable, r_relative;
141
  unsigned int r_addend;
142
  asection *output_section = sym->section->output_section;
143
 
144
  PUT_WORD (abfd, g->address, natptr->r_address);
145
 
146
  r_length = g->howto->size;    /* Size as a power of two */
147
  r_pcrel = (int) g->howto->pc_relative;        /* Relative to PC? */
148
  /* r_baserel, r_jmptable, r_relative???  FIXME-soon */
149
  r_baserel = 0;
150
  r_jmptable = 0;
151
  r_relative = 0;
152
 
153
  r_addend = g->addend + (*(g->sym_ptr_ptr))->section->output_section->vma;
154
 
155
  /* name was clobbered by aout_write_syms to be symbol index */
156
 
157
  /* If this relocation is relative to a symbol then set the
158
     r_index to the symbols index, and the r_extern bit.
159
 
160
     Absolute symbols can come in in two ways, either as an offset
161
     from the abs section, or as a symbol which has an abs value.
162
     check for that here
163
  */
164
 
165
 
166
  if (bfd_is_com_section (output_section)
167
      || bfd_is_abs_section (output_section)
168
      || bfd_is_und_section (output_section))
169
    {
170
      if (bfd_abs_section_ptr->symbol == sym)
171
        {
172
          /* Whoops, looked like an abs symbol, but is really an offset
173
             from the abs section */
174
          r_index = 0;
175
          r_extern = 0;
176
        }
177
      else
178
        {
179
          /* Fill in symbol */
180
          r_extern = 1;
181
          r_index = (*g->sym_ptr_ptr)->KEEPIT;
182
        }
183
    }
184
  else
185
    {
186
      /* Just an ordinary section */
187
      r_extern = 0;
188
      r_index = output_section->target_index;
189
    }
190
 
191
  /* now the fun stuff */
192
  if (bfd_header_big_endian (abfd))
193
    {
194
      natptr->r_index[0] = r_index >> 16;
195
      natptr->r_index[1] = r_index >> 8;
196
      natptr->r_index[2] = r_index;
197
      natptr->r_type[0] =
198
        (r_extern ? RELOC_STD_BITS_EXTERN_BIG : 0)
199
        | (r_pcrel ? RELOC_STD_BITS_PCREL_BIG : 0)
200
        | (r_baserel ? RELOC_STD_BITS_BASEREL_BIG : 0)
201
        | (r_jmptable ? RELOC_STD_BITS_JMPTABLE_BIG : 0)
202
        | (r_relative ? RELOC_STD_BITS_RELATIVE_BIG : 0)
203
        | (r_length << RELOC_STD_BITS_LENGTH_SH_BIG);
204
    }
205
  else
206
    {
207
      natptr->r_index[2] = r_index >> 16;
208
      natptr->r_index[1] = r_index >> 8;
209
      natptr->r_index[0] = r_index;
210
      natptr->r_type[0] =
211
        (r_extern ? RELOC_STD_BITS_EXTERN_LITTLE : 0)
212
        | (r_pcrel ? RELOC_STD_BITS_PCREL_LITTLE : 0)
213
        | (r_baserel ? RELOC_STD_BITS_BASEREL_LITTLE : 0)
214
        | (r_jmptable ? RELOC_STD_BITS_JMPTABLE_LITTLE : 0)
215
        | (r_relative ? RELOC_STD_BITS_RELATIVE_LITTLE : 0)
216
        | (r_length << RELOC_STD_BITS_LENGTH_SH_LITTLE);
217
    }
218
}
219
 
220
 
221
/* Extended stuff */
222
/* Output extended relocation information to a file in target byte order. */
223
 
224
void
225
NAME(lynx,swap_ext_reloc_out) (abfd, g, natptr)
226
     bfd *abfd;
227
     arelent *g;
228
     register struct reloc_ext_external *natptr;
229
{
230
  int r_index;
231
  int r_extern;
232
  unsigned int r_type;
233
  unsigned int r_addend;
234
  asymbol *sym = *(g->sym_ptr_ptr);
235
  asection *output_section = sym->section->output_section;
236
 
237
  PUT_WORD (abfd, g->address, natptr->r_address);
238
 
239
  r_type = (unsigned int) g->howto->type;
240
 
241
  r_addend = g->addend + (*(g->sym_ptr_ptr))->section->output_section->vma;
242
 
243
 
244
  /* If this relocation is relative to a symbol then set the
245
     r_index to the symbols index, and the r_extern bit.
246
 
247
     Absolute symbols can come in in two ways, either as an offset
248
     from the abs section, or as a symbol which has an abs value.
249
     check for that here
250
     */
251
 
252
  if (bfd_is_com_section (output_section)
253
      || bfd_is_abs_section (output_section)
254
      || bfd_is_und_section (output_section))
255
    {
256
      if (bfd_abs_section_ptr->symbol == sym)
257
        {
258
          /* Whoops, looked like an abs symbol, but is really an offset
259
         from the abs section */
260
          r_index = 0;
261
          r_extern = 0;
262
        }
263
      else
264
        {
265
          r_extern = 1;
266
          r_index = (*g->sym_ptr_ptr)->KEEPIT;
267
        }
268
    }
269
  else
270
    {
271
      /* Just an ordinary section */
272
      r_extern = 0;
273
      r_index = output_section->target_index;
274
    }
275
 
276
 
277
  /* now the fun stuff */
278
  if (bfd_header_big_endian (abfd))
279
    {
280
      natptr->r_index[0] = r_index >> 16;
281
      natptr->r_index[1] = r_index >> 8;
282
      natptr->r_index[2] = r_index;
283
      natptr->r_type[0] =
284
        (r_extern ? RELOC_EXT_BITS_EXTERN_BIG : 0)
285
        | (r_type << RELOC_EXT_BITS_TYPE_SH_BIG);
286
    }
287
  else
288
    {
289
      natptr->r_index[2] = r_index >> 16;
290
      natptr->r_index[1] = r_index >> 8;
291
      natptr->r_index[0] = r_index;
292
      natptr->r_type[0] =
293
        (r_extern ? RELOC_EXT_BITS_EXTERN_LITTLE : 0)
294
        | (r_type << RELOC_EXT_BITS_TYPE_SH_LITTLE);
295
    }
296
 
297
  PUT_WORD (abfd, r_addend, natptr->r_addend);
298
}
299
 
300
/* BFD deals internally with all things based from the section they're
301
   in. so, something in 10 bytes into a text section  with a base of
302
   50 would have a symbol (.text+10) and know .text vma was 50.
303
 
304
   Aout keeps all it's symbols based from zero, so the symbol would
305
   contain 60. This macro subs the base of each section from the value
306
   to give the true offset from the section */
307
 
308
 
309
#define MOVE_ADDRESS(ad)                                                \
310
  if (r_extern) {                                                       \
311
   /* undefined symbol */                                               \
312
     cache_ptr->sym_ptr_ptr = symbols + r_index;                        \
313
     cache_ptr->addend = ad;                                            \
314
     } else {                                                           \
315
    /* defined, section relative. replace symbol with pointer to        \
316
       symbol which points to section  */                               \
317
    switch (r_index) {                                                  \
318
    case N_TEXT:                                                        \
319
    case N_TEXT | N_EXT:                                                \
320
      cache_ptr->sym_ptr_ptr  = obj_textsec(abfd)->symbol_ptr_ptr;      \
321
      cache_ptr->addend = ad  - su->textsec->vma;                       \
322
      break;                                                            \
323
    case N_DATA:                                                        \
324
    case N_DATA | N_EXT:                                                \
325
      cache_ptr->sym_ptr_ptr  = obj_datasec(abfd)->symbol_ptr_ptr;      \
326
      cache_ptr->addend = ad - su->datasec->vma;                        \
327
      break;                                                            \
328
    case N_BSS:                                                         \
329
    case N_BSS | N_EXT:                                                 \
330
      cache_ptr->sym_ptr_ptr  = obj_bsssec(abfd)->symbol_ptr_ptr;       \
331
      cache_ptr->addend = ad - su->bsssec->vma;                         \
332
      break;                                                            \
333
    default:                                                            \
334
    case N_ABS:                                                         \
335
    case N_ABS | N_EXT:                                                 \
336
     cache_ptr->sym_ptr_ptr = bfd_abs_section_ptr->symbol_ptr_ptr;      \
337
      cache_ptr->addend = ad;                                           \
338
      break;                                                            \
339
    }                                                                   \
340
  }                                                                     \
341
 
342
void
343
NAME(lynx,swap_ext_reloc_in) (abfd, bytes, cache_ptr, symbols, symcount)
344
     bfd *abfd;
345
     struct reloc_ext_external *bytes;
346
     arelent *cache_ptr;
347
     asymbol **symbols;
348
     bfd_size_type symcount ATTRIBUTE_UNUSED;
349
{
350
  int r_index;
351
  int r_extern;
352
  unsigned int r_type;
353
  struct aoutdata *su = &(abfd->tdata.aout_data->a);
354
 
355
  cache_ptr->address = (GET_SWORD (abfd, bytes->r_address));
356
 
357
  r_index = bytes->r_index[1];
358
  r_extern = (0 != (bytes->r_index[0] & RELOC_EXT_BITS_EXTERN_BIG));
359
  r_type = (bytes->r_index[0] & RELOC_EXT_BITS_TYPE_BIG)
360
    >> RELOC_EXT_BITS_TYPE_SH_BIG;
361
 
362
  cache_ptr->howto = aout_32_ext_howto_table + r_type;
363
  MOVE_ADDRESS (GET_SWORD (abfd, bytes->r_addend));
364
}
365
 
366
void
367
NAME(lynx,swap_std_reloc_in) (abfd, bytes, cache_ptr, symbols, symcount)
368
     bfd *abfd;
369
     struct reloc_std_external *bytes;
370
     arelent *cache_ptr;
371
     asymbol **symbols;
372
     bfd_size_type symcount ATTRIBUTE_UNUSED;
373
{
374
  int r_index;
375
  int r_extern;
376
  unsigned int r_length;
377
  int r_pcrel;
378
  int r_baserel, r_jmptable, r_relative;
379
  struct aoutdata *su = &(abfd->tdata.aout_data->a);
380
 
381
  cache_ptr->address = H_GET_32 (abfd, bytes->r_address);
382
 
383
  r_index = bytes->r_index[1];
384
  r_extern = (0 != (bytes->r_index[0] & RELOC_STD_BITS_EXTERN_BIG));
385
  r_pcrel = (0 != (bytes->r_index[0] & RELOC_STD_BITS_PCREL_BIG));
386
  r_baserel = (0 != (bytes->r_index[0] & RELOC_STD_BITS_BASEREL_BIG));
387
  r_jmptable = (0 != (bytes->r_index[0] & RELOC_STD_BITS_JMPTABLE_BIG));
388
  r_relative = (0 != (bytes->r_index[0] & RELOC_STD_BITS_RELATIVE_BIG));
389
  r_length = (bytes->r_index[0] & RELOC_STD_BITS_LENGTH_BIG)
390
    >> RELOC_STD_BITS_LENGTH_SH_BIG;
391
 
392
  cache_ptr->howto = aout_32_std_howto_table + r_length + 4 * r_pcrel;
393
  /* FIXME-soon:  Roll baserel, jmptable, relative bits into howto setting */
394
 
395
  MOVE_ADDRESS (0);
396
}
397
 
398
/* Reloc hackery */
399
 
400
bfd_boolean
401
NAME(lynx,slurp_reloc_table) (abfd, asect, symbols)
402
     bfd *abfd;
403
     sec_ptr asect;
404
     asymbol **symbols;
405
{
406
  bfd_size_type count;
407
  bfd_size_type reloc_size;
408
  PTR relocs;
409
  arelent *reloc_cache;
410
  size_t each_size;
411
 
412
  if (asect->relocation)
413
    return TRUE;
414
 
415
  if (asect->flags & SEC_CONSTRUCTOR)
416
    return TRUE;
417
 
418
  if (asect == obj_datasec (abfd))
419
    {
420
      reloc_size = exec_hdr (abfd)->a_drsize;
421
      goto doit;
422
    }
423
 
424
  if (asect == obj_textsec (abfd))
425
    {
426
      reloc_size = exec_hdr (abfd)->a_trsize;
427
      goto doit;
428
    }
429
 
430
  bfd_set_error (bfd_error_invalid_operation);
431
  return FALSE;
432
 
433
doit:
434
  if (bfd_seek (abfd, asect->rel_filepos, SEEK_SET) != 0)
435
    return FALSE;
436
  each_size = obj_reloc_entry_size (abfd);
437
 
438
  count = reloc_size / each_size;
439
 
440
 
441
  reloc_cache = (arelent *) bfd_zmalloc (count * sizeof (arelent));
442
  if (!reloc_cache && count != 0)
443
    return FALSE;
444
 
445
  relocs = (PTR) bfd_alloc (abfd, reloc_size);
446
  if (!relocs && reloc_size != 0)
447
    {
448
      free (reloc_cache);
449
      return FALSE;
450
    }
451
 
452
  if (bfd_bread (relocs, reloc_size, abfd) != reloc_size)
453
    {
454
      bfd_release (abfd, relocs);
455
      free (reloc_cache);
456
      return FALSE;
457
    }
458
 
459
  if (each_size == RELOC_EXT_SIZE)
460
    {
461
      register struct reloc_ext_external *rptr = (struct reloc_ext_external *) relocs;
462
      unsigned int counter = 0;
463
      arelent *cache_ptr = reloc_cache;
464
 
465
      for (; counter < count; counter++, rptr++, cache_ptr++)
466
        {
467
          NAME(lynx,swap_ext_reloc_in) (abfd, rptr, cache_ptr, symbols,
468
                                        (bfd_size_type) bfd_get_symcount (abfd));
469
        }
470
    }
471
  else
472
    {
473
      register struct reloc_std_external *rptr = (struct reloc_std_external *) relocs;
474
      unsigned int counter = 0;
475
      arelent *cache_ptr = reloc_cache;
476
 
477
      for (; counter < count; counter++, rptr++, cache_ptr++)
478
        {
479
          NAME(lynx,swap_std_reloc_in) (abfd, rptr, cache_ptr, symbols,
480
                                        (bfd_size_type) bfd_get_symcount (abfd));
481
        }
482
 
483
    }
484
 
485
  bfd_release (abfd, relocs);
486
  asect->relocation = reloc_cache;
487
  asect->reloc_count = count;
488
  return TRUE;
489
}
490
 
491
 
492
 
493
/* Write out a relocation section into an object file.  */
494
 
495
bfd_boolean
496
NAME(lynx,squirt_out_relocs) (abfd, section)
497
     bfd *abfd;
498
     asection *section;
499
{
500
  arelent **generic;
501
  unsigned char *native, *natptr;
502
  size_t each_size;
503
 
504
  unsigned int count = section->reloc_count;
505
  bfd_size_type natsize;
506
 
507
  if (count == 0)
508
    return TRUE;
509
 
510
  each_size = obj_reloc_entry_size (abfd);
511
  natsize = count;
512
  natsize *= each_size;
513
  native = (unsigned char *) bfd_zalloc (abfd, natsize);
514
  if (!native)
515
    return FALSE;
516
 
517
  generic = section->orelocation;
518
 
519
  if (each_size == RELOC_EXT_SIZE)
520
    {
521
      for (natptr = native;
522
           count != 0;
523
           --count, natptr += each_size, ++generic)
524
        NAME(lynx,swap_ext_reloc_out) (abfd, *generic, (struct reloc_ext_external *) natptr);
525
    }
526
  else
527
    {
528
      for (natptr = native;
529
           count != 0;
530
           --count, natptr += each_size, ++generic)
531
        NAME(lynx,swap_std_reloc_out) (abfd, *generic, (struct reloc_std_external *) natptr);
532
    }
533
 
534
  if (bfd_bwrite ((PTR) native, natsize, abfd) != natsize)
535
    {
536
      bfd_release (abfd, native);
537
      return FALSE;
538
    }
539
  bfd_release (abfd, native);
540
 
541
  return TRUE;
542
}
543
 
544
/* This is stupid.  This function should be a boolean predicate */
545
long
546
NAME(lynx,canonicalize_reloc) (abfd, section, relptr, symbols)
547
     bfd *abfd;
548
     sec_ptr section;
549
     arelent **relptr;
550
     asymbol **symbols;
551
{
552
  arelent *tblptr = section->relocation;
553
  unsigned int count;
554
 
555
  if (!(tblptr || NAME(lynx,slurp_reloc_table) (abfd, section, symbols)))
556
    return -1;
557
 
558
  if (section->flags & SEC_CONSTRUCTOR)
559
    {
560
      arelent_chain *chain = section->constructor_chain;
561
      for (count = 0; count < section->reloc_count; count++)
562
        {
563
          *relptr++ = &chain->relent;
564
          chain = chain->next;
565
        }
566
    }
567
  else
568
    {
569
      tblptr = section->relocation;
570
 
571
      for (count = 0; count++ < section->reloc_count;)
572
        {
573
          *relptr++ = tblptr++;
574
        }
575
    }
576
  *relptr = 0;
577
 
578
  return section->reloc_count;
579
}
580
 
581
#define MY_canonicalize_reloc NAME(lynx,canonicalize_reloc)
582
 
583
#include "aout-target.h"

powered by: WebSVN 2.1.0

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