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

Subversion Repositories or1k

[/] [or1k/] [trunk/] [gdb-5.3/] [bfd/] [i386lynx.c] - Blame information for rev 1765

Details | Compare with Previous | View Log

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

powered by: WebSVN 2.1.0

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