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

Subversion Repositories openrisc

[/] [openrisc/] [trunk/] [gnu-old/] [gdb-7.1/] [bfd/] [i386lynx.c] - Blame information for rev 868

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

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

powered by: WebSVN 2.1.0

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