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