From Ian Roxborough <irox@redhat.com>
[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 */
58#define N_TXTOFF(x) \
59 ((x).a_info == OMAGIC ? 32 \
60 : (N_MAGIC(x) == ZMAGIC) ? TARGET_PAGE_SIZE \
61 : 999)
62
63#define N_TXTADDR(x) \
64 (N_MAGIC(x) != ZMAGIC ? 0 /* object file or NMAGIC */ \
65 /* Programs with shared libs are loaded at the first page after all the \
66 text segments of the shared library programs. Without looking this \
67 up we can't know exactly what the address will be. A reasonable guess \
68 is that a_entry will be in the first page of the executable. */ \
69 : N_SHARED_LIB(x) ? ((x).a_entry & ~(TARGET_PAGE_SIZE - 1)) \
70 : TEXT_START_ADDR)
71
72#define N_SYMOFF(x) \
73 (N_TXTOFF (x) + (x).a_text + (x).a_data + (x).a_trsize + (x).a_drsize)
74
75#define N_STROFF(x) (N_SYMOFF (x) + (x).a_syms)
76
77#define TEXT_START_ADDR 32768
78#define TARGET_PAGE_SIZE 32768
79#define SEGMENT_SIZE TARGET_PAGE_SIZE
80#define DEFAULT_ARCH bfd_arch_arm
81
82#define MY(OP) CAT(riscix_,OP)
83#define TARGETNAME "a.out-riscix"
84#define N_BADMAG(x) ((((x).a_info & ~007200) != ZMAGIC) && \
85 (((x).a_info & ~006000) != OMAGIC) && \
86 ((x).a_info != NMAGIC))
87#define N_MAGIC(x) ((x).a_info & ~07200)
88
89#include "bfd.h"
90#include "sysdep.h"
91#include "libbfd.h"
92
93#define WRITE_HEADERS(abfd, execp) \
94 { \
95 bfd_size_type text_size; /* dummy vars */ \
96 file_ptr text_end; \
97 if (adata(abfd).magic == undecided_magic) \
98 NAME(aout,adjust_sizes_and_vmas) (abfd, &text_size, &text_end); \
99 \
100 execp->a_syms = bfd_get_symcount (abfd) * EXTERNAL_NLIST_SIZE; \
101 execp->a_entry = bfd_get_start_address (abfd); \
102 \
103 execp->a_trsize = ((obj_textsec (abfd)->reloc_count) * \
104 obj_reloc_entry_size (abfd)); \
105 execp->a_drsize = ((obj_datasec (abfd)->reloc_count) * \
106 obj_reloc_entry_size (abfd)); \
107 NAME(aout,swap_exec_header_out) (abfd, execp, &exec_bytes); \
108 \
109 if (bfd_seek (abfd, (file_ptr) 0, SEEK_SET) != 0) return false; \
110 if (bfd_write ((PTR) &exec_bytes, 1, EXEC_BYTES_SIZE, abfd) \
111 != EXEC_BYTES_SIZE) \
112 return false; \
113 /* Now write out reloc info, followed by syms and strings */ \
114 \
115 if (bfd_get_outsymbols (abfd) != (asymbol **) NULL \
116 && bfd_get_symcount (abfd) != 0) \
117 { \
3d855632 118 if (bfd_seek (abfd, (file_ptr) (N_SYMOFF(*execp)), SEEK_SET) != 0) \
252b5132
RH
119 return false; \
120 \
3d855632 121 if (! NAME(aout,write_syms) (abfd)) return false; \
252b5132 122 \
3d855632 123 if (bfd_seek (abfd, (file_ptr) (N_TRELOFF(*execp)), SEEK_SET) != 0) \
252b5132
RH
124 return false; \
125 \
126 if (! riscix_squirt_out_relocs (abfd, obj_textsec (abfd))) \
127 return false; \
3d855632 128 if (bfd_seek (abfd, (file_ptr) (N_DRELOFF(*execp)), SEEK_SET) != 0) \
252b5132
RH
129 return false; \
130 \
3d855632 131 if (!NAME(aout,squirt_out_relocs) (abfd, obj_datasec (abfd))) \
252b5132
RH
132 return false; \
133 } \
134 }
135
136#include "libaout.h"
137#include "aout/aout64.h"
138
139static bfd_reloc_status_type
140riscix_fix_pcrel_26_done PARAMS ((bfd *, arelent *, asymbol *, PTR,
141 asection *, bfd *, char **));
142
143static bfd_reloc_status_type
144riscix_fix_pcrel_26 PARAMS ((bfd *, arelent *, asymbol *, PTR,
145 asection *, bfd *, char **));
42ef282f
NC
146static const bfd_target *
147MY (object_p) PARAMS ((bfd *));
148
149reloc_howto_type *
150riscix_reloc_type_lookup PARAMS ((bfd *, bfd_reloc_code_real_type));
151
152void
153riscix_swap_std_reloc_out PARAMS ((bfd *, arelent *, struct reloc_std_external *));
154
155boolean
156riscix_squirt_out_relocs PARAMS ((bfd *, asection *));
157
158long
159MY (canonicalize_reloc) PARAMS ((bfd *, sec_ptr, arelent **, asymbol **));
160
161const bfd_target *
162riscix_some_aout_object_p PARAMS ((bfd *, struct internal_exec *, const bfd_target *(*) (bfd *)));
163
252b5132
RH
164
165static reloc_howto_type riscix_std_reloc_howto[] = {
166 /* type rs size bsz pcrel bitpos ovrf sf name part_inpl readmask setmask pcdone */
167 HOWTO( 0, 0, 0, 8, false, 0, complain_overflow_bitfield,0,"8", true, 0x000000ff,0x000000ff, false),
168 HOWTO( 1, 0, 1, 16, false, 0, complain_overflow_bitfield,0,"16", true, 0x0000ffff,0x0000ffff, false),
169 HOWTO( 2, 0, 2, 32, false, 0, complain_overflow_bitfield,0,"32", true, 0xffffffff,0xffffffff, false),
170 HOWTO( 3, 2, 3, 26, true, 0, complain_overflow_signed, riscix_fix_pcrel_26 , "ARM26", true, 0x00ffffff,0x00ffffff, false),
171 HOWTO( 4, 0, 0, 8, true, 0, complain_overflow_signed, 0,"DISP8", true, 0x000000ff,0x000000ff, true),
172 HOWTO( 5, 0, 1, 16, true, 0, complain_overflow_signed, 0,"DISP16", true, 0x0000ffff,0x0000ffff, true),
173 HOWTO( 6, 0, 2, 32, true, 0, complain_overflow_signed, 0,"DISP32", true, 0xffffffff,0xffffffff, true),
174 HOWTO( 7, 2, 3, 26, false, 0, complain_overflow_signed, riscix_fix_pcrel_26_done, "ARM26D",true,0x00ffffff,0x00ffffff, false),
5f771d47 175 EMPTY_HOWTO (-1),
252b5132
RH
176 HOWTO( 9, 0, -1, 16, false, 0, complain_overflow_bitfield,0,"NEG16", true, 0x0000ffff,0x0000ffff, false),
177 HOWTO( 10, 0, -2, 32, false, 0, complain_overflow_bitfield,0,"NEG32", true, 0xffffffff,0xffffffff, false)
178};
179
180#define RISCIX_TABLE_SIZE \
181 (sizeof (riscix_std_reloc_howto) / sizeof (reloc_howto_type))
182
252b5132
RH
183static bfd_reloc_status_type
184riscix_fix_pcrel_26_done (abfd, reloc_entry, symbol, data, input_section,
185 output_bfd, error_message)
5f771d47
ILT
186 bfd *abfd ATTRIBUTE_UNUSED;
187 arelent *reloc_entry ATTRIBUTE_UNUSED;
188 asymbol *symbol ATTRIBUTE_UNUSED;
189 PTR data ATTRIBUTE_UNUSED;
190 asection *input_section ATTRIBUTE_UNUSED;
191 bfd *output_bfd ATTRIBUTE_UNUSED;
192 char **error_message ATTRIBUTE_UNUSED;
252b5132
RH
193{
194 /* This is dead simple at present. */
195 return bfd_reloc_ok;
196}
197
198static bfd_reloc_status_type
199riscix_fix_pcrel_26 (abfd, reloc_entry, symbol, data, input_section,
200 output_bfd, error_message)
201 bfd *abfd;
202 arelent *reloc_entry;
203 asymbol *symbol;
204 PTR data;
205 asection *input_section;
206 bfd *output_bfd;
5f771d47 207 char **error_message ATTRIBUTE_UNUSED;
252b5132
RH
208{
209 bfd_vma relocation;
210 bfd_size_type addr = reloc_entry->address;
211 long target = bfd_get_32 (abfd, (bfd_byte *) data + addr);
212 bfd_reloc_status_type flag = bfd_reloc_ok;
3d855632 213
252b5132
RH
214 /* If this is an undefined symbol, return error */
215 if (symbol->section == &bfd_und_section
216 && (symbol->flags & BSF_WEAK) == 0)
217 return output_bfd ? bfd_reloc_continue : bfd_reloc_undefined;
218
219 /* If the sections are different, and we are doing a partial relocation,
220 just ignore it for now. */
221 if (symbol->section->name != input_section->name
222 && output_bfd != (bfd *)NULL)
223 return bfd_reloc_continue;
224
225 relocation = (target & 0x00ffffff) << 2;
226 relocation = (relocation ^ 0x02000000) - 0x02000000; /* Sign extend */
227 relocation += symbol->value;
228 relocation += symbol->section->output_section->vma;
229 relocation += symbol->section->output_offset;
230 relocation += reloc_entry->addend;
231 relocation -= input_section->output_section->vma;
232 relocation -= input_section->output_offset;
233 relocation -= addr;
234 if (relocation & 3)
235 return bfd_reloc_overflow;
236
237 /* Check for overflow */
238 if (relocation & 0x02000000)
239 {
240 if ((relocation & ~ (bfd_vma) 0x03ffffff) != ~ (bfd_vma) 0x03ffffff)
241 flag = bfd_reloc_overflow;
242 }
243 else if (relocation & ~0x03ffffff)
244 flag = bfd_reloc_overflow;
245
246 target &= ~0x00ffffff;
247 target |= (relocation >> 2) & 0x00ffffff;
248 bfd_put_32 (abfd, target, (bfd_byte *) data + addr);
249
250 /* Now the ARM magic... Change the reloc type so that it is marked as done.
251 Strictly this is only necessary if we are doing a partial relocation. */
252 reloc_entry->howto = &riscix_std_reloc_howto[7];
3d855632 253
252b5132
RH
254 return flag;
255}
256
257reloc_howto_type *
27985c55
KH
258riscix_reloc_type_lookup (abfd, code)
259 bfd *abfd;
260 bfd_reloc_code_real_type code;
252b5132
RH
261{
262#define ASTD(i,j) case i: return &riscix_std_reloc_howto[j]
263 if (code == BFD_RELOC_CTOR)
264 switch (bfd_get_arch_info (abfd)->bits_per_address)
265 {
266 case 32:
267 code = BFD_RELOC_32;
268 break;
269 default: return (reloc_howto_type *) NULL;
270 }
271
272 switch (code)
273 {
274 ASTD (BFD_RELOC_16, 1);
275 ASTD (BFD_RELOC_32, 2);
276 ASTD (BFD_RELOC_ARM_PCREL_BRANCH, 3);
277 ASTD (BFD_RELOC_8_PCREL, 4);
278 ASTD (BFD_RELOC_16_PCREL, 5);
279 ASTD (BFD_RELOC_32_PCREL, 6);
280 default: return (reloc_howto_type *) NULL;
281 }
282}
283
284#define MY_bfd_link_hash_table_create _bfd_generic_link_hash_table_create
285#define MY_bfd_link_add_symbols _bfd_generic_link_add_symbols
286#define MY_final_link_callback should_not_be_used
287#define MY_bfd_final_link _bfd_generic_final_link
288
289#define MY_bfd_reloc_type_lookup riscix_reloc_type_lookup
290#define MY_canonicalize_reloc riscix_canonicalize_reloc
291#define MY_object_p riscix_object_p
292
293static const bfd_target *riscix_callback PARAMS ((bfd *));
294
295void
296riscix_swap_std_reloc_out (abfd, g, natptr)
297 bfd *abfd;
298 arelent *g;
299 struct reloc_std_external *natptr;
300{
301 int r_index;
302 asymbol *sym = *(g->sym_ptr_ptr);
303 int r_extern;
304 int r_length;
305 int r_pcrel;
306 int r_neg = 0; /* Negative relocs use the BASEREL bit. */
307 asection *output_section = sym->section->output_section;
308
309 PUT_WORD(abfd, g->address, natptr->r_address);
310
311 r_length = g->howto->size ; /* Size as a power of two */
312 if (r_length < 0)
313 {
314 r_length = -r_length;
315 r_neg = 1;
316 }
317
318 r_pcrel = (int) g->howto->pc_relative; /* Relative to PC? */
319
320 /* For RISC iX, in pc-relative relocs the r_pcrel bit means that the
321 relocation has been done already (Only for the 26-bit one I think)???!!!
322 */
3d855632 323
252b5132
RH
324 if (r_length == 3)
325 r_pcrel = r_pcrel ? 0 : 1;
252b5132
RH
326
327#if 0
328 /* For a standard reloc, the addend is in the object file. */
329 r_addend = g->addend + (*(g->sym_ptr_ptr))->section->output_section->vma;
330#endif
331
332 /* name was clobbered by aout_write_syms to be symbol index */
333
334 /* If this relocation is relative to a symbol then set the
335 r_index to the symbols index, and the r_extern bit.
336
337 Absolute symbols can come in in two ways, either as an offset
338 from the abs section, or as a symbol which has an abs value.
339 check for that here
340 */
341
342 if (bfd_is_com_section (output_section)
343 || output_section == &bfd_abs_section
344 || output_section == &bfd_und_section)
345 {
346 if (bfd_abs_section.symbol == sym)
347 {
348 /* Whoops, looked like an abs symbol, but is really an offset
349 from the abs section */
350 r_index = 0;
351 r_extern = 0;
352 }
353 else
354 {
355 /* Fill in symbol */
356 r_extern = 1;
357 r_index = (*g->sym_ptr_ptr)->udata.i;
358 }
359 }
360 else
361 {
362 /* Just an ordinary section */
363 r_extern = 0;
364 r_index = output_section->target_index;
365 }
366
367 /* now the fun stuff */
368 if (bfd_header_big_endian (abfd))
369 {
370 natptr->r_index[0] = r_index >> 16;
371 natptr->r_index[1] = r_index >> 8;
372 natptr->r_index[2] = r_index;
373 natptr->r_type[0] =
374 ( (r_extern ? RELOC_STD_BITS_EXTERN_BIG: 0)
375 | (r_pcrel ? RELOC_STD_BITS_PCREL_BIG: 0)
376 | (r_neg ? RELOC_STD_BITS_BASEREL_BIG: 0)
377 | (r_length << RELOC_STD_BITS_LENGTH_SH_BIG));
378 }
379 else
380 {
381 natptr->r_index[2] = r_index >> 16;
382 natptr->r_index[1] = r_index >> 8;
383 natptr->r_index[0] = r_index;
384 natptr->r_type[0] =
385 ( (r_extern ? RELOC_STD_BITS_EXTERN_LITTLE: 0)
386 | (r_pcrel ? RELOC_STD_BITS_PCREL_LITTLE: 0)
387 | (r_neg ? RELOC_STD_BITS_BASEREL_LITTLE: 0)
388 | (r_length << RELOC_STD_BITS_LENGTH_SH_LITTLE));
389 }
390}
391
392boolean
393riscix_squirt_out_relocs (abfd, section)
394 bfd *abfd;
395 asection *section;
396{
397 arelent **generic;
398 unsigned char *native, *natptr;
399 size_t each_size;
3d855632 400
252b5132
RH
401 unsigned int count = section->reloc_count;
402 size_t natsize;
403
404 if (count == 0) return true;
405
406 each_size = obj_reloc_entry_size (abfd);
407 natsize = each_size * count;
408 native = (unsigned char *) 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_write ((PTR) native, 1, natsize, abfd) != natsize)
421 {
422 bfd_release(abfd, native);
423 return false;
424 }
425
426 bfd_release (abfd, native);
427 return true;
428}
429
252b5132
RH
430/*
431 * This is just like the standard aoutx.h version but we need to do our
432 * own mapping of external reloc type values to howto entries.
433 */
434long
3d855632 435MY(canonicalize_reloc) (abfd, section, relptr, symbols)
252b5132
RH
436 bfd *abfd;
437 sec_ptr section;
438 arelent **relptr;
439 asymbol **symbols;
440{
441 arelent *tblptr = section->relocation;
442 unsigned int count, c;
443 extern reloc_howto_type NAME(aout,std_howto_table)[];
444
3d855632 445 /* If we have already read in the relocation table, return the values. */
252b5132
RH
446 if (section->flags & SEC_CONSTRUCTOR) {
447 arelent_chain *chain = section->constructor_chain;
448
449 for (count = 0; count < section->reloc_count; count++) {
450 *relptr++ = &chain->relent;
451 chain = chain->next;
452 }
453 *relptr = 0;
454 return section->reloc_count;
455 }
456 if (tblptr && section->reloc_count) {
457 for (count = 0; count++ < section->reloc_count;)
458 *relptr++ = tblptr++;
459 *relptr = 0;
460 return section->reloc_count;
461 }
462
3d855632 463 if (!NAME(aout,slurp_reloc_table) (abfd, section, symbols))
252b5132
RH
464 return -1;
465 tblptr = section->relocation;
466
467 /* fix up howto entries */
468 for (count = 0; count++ < section->reloc_count;)
469 {
470 c = tblptr->howto - NAME(aout,std_howto_table);
471 BFD_ASSERT (c < RISCIX_TABLE_SIZE);
472 tblptr->howto = &riscix_std_reloc_howto[c];
473
474 *relptr++ = tblptr++;
475 }
476 *relptr = 0;
477 return section->reloc_count;
478}
479
3d855632 480/* This is the same as NAME(aout,some_aout_object_p), but has different
252b5132
RH
481 expansions of the macro definitions. */
482
483const bfd_target *
484riscix_some_aout_object_p (abfd, execp, callback_to_real_object_p)
485 bfd *abfd;
486 struct internal_exec *execp;
487 const bfd_target *(*callback_to_real_object_p) PARAMS ((bfd *));
488{
489 struct aout_data_struct *rawptr, *oldrawptr;
490 const bfd_target *result;
491
3d855632 492 rawptr = ((struct aout_data_struct *)
252b5132
RH
493 bfd_zalloc (abfd, sizeof (struct aout_data_struct )));
494
495 if (rawptr == NULL)
496 return 0;
497
498 oldrawptr = abfd->tdata.aout_data;
499 abfd->tdata.aout_data = rawptr;
500
501 /* Copy the contents of the old tdata struct.
502 In particular, we want the subformat, since for hpux it was set in
503 hp300hpux.c:swap_exec_header_in and will be used in
504 hp300hpux.c:callback. */
505 if (oldrawptr != NULL)
506 *abfd->tdata.aout_data = *oldrawptr;
507
508 abfd->tdata.aout_data->a.hdr = &rawptr->e;
509 *(abfd->tdata.aout_data->a.hdr) = *execp; /* Copy in the internal_exec
510 struct */
511 execp = abfd->tdata.aout_data->a.hdr;
512
513 /* Set the file flags */
514 abfd->flags = BFD_NO_FLAGS;
515 if (execp->a_drsize || execp->a_trsize)
516 abfd->flags |= HAS_RELOC;
517 /* Setting of EXEC_P has been deferred to the bottom of this function */
518 if (execp->a_syms)
519 abfd->flags |= HAS_LINENO | HAS_DEBUG | HAS_SYMS | HAS_LOCALS;
520 if (N_DYNAMIC(*execp))
521 abfd->flags |= DYNAMIC;
522
3d855632 523 if ((execp->a_info & MF_SQUEEZED) != 0) /* Squeezed files aren't supported
252b5132
RH
524 (yet)! */
525 {
526 bfd_set_error (bfd_error_wrong_format);
527 return NULL;
528 }
529 else if ((execp->a_info & MF_IS_SL) != 0) /* Nor are shared libraries */
530 {
531 bfd_set_error (bfd_error_wrong_format);
532 return NULL;
533 }
534 else if (N_MAGIC (*execp) == ZMAGIC)
535 {
536 abfd->flags |= D_PAGED | WP_TEXT;
537 adata (abfd).magic = z_magic;
538 }
539 else if (N_MAGIC (*execp) == NMAGIC)
540 {
541 abfd->flags |= WP_TEXT;
542 adata (abfd).magic = n_magic;
543 }
544 else if (N_MAGIC (*execp) == OMAGIC)
545 adata (abfd).magic = o_magic;
546 else
547 {
548 /* Should have been checked with N_BADMAG before this routine
549 was called. */
550 abort ();
551 }
552
553 bfd_get_start_address (abfd) = execp->a_entry;
554
555 obj_aout_symbols (abfd) = (aout_symbol_type *)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
3d855632 561 /* The default symbol entry size is that of traditional Unix. */
252b5132
RH
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)->_raw_size = execp->a_data;
572 obj_bsssec (abfd)->_raw_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
3d855632 584 result = (*callback_to_real_object_p) (abfd);
252b5132
RH
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 {
596 struct stat stat_buf;
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)->_raw_size))
614 abfd->flags |= EXEC_P;
615#endif /* MACH */
616 if (result)
617 {
618 }
619 else
620 {
621 free (rawptr);
622 abfd->tdata.aout_data = oldrawptr;
623 }
624 return result;
625}
626
252b5132
RH
627static const bfd_target *
628MY(object_p) (abfd)
629 bfd *abfd;
630{
631 struct external_exec exec_bytes; /* Raw exec header from file */
632 struct internal_exec exec; /* Cleaned-up exec header */
633 const bfd_target *target;
634
635 if (bfd_read ((PTR) &exec_bytes, 1, EXEC_BYTES_SIZE, abfd)
636 != EXEC_BYTES_SIZE) {
637 if (bfd_get_error () != bfd_error_system_call)
638 bfd_set_error (bfd_error_wrong_format);
639 return 0;
640 }
641
642 exec.a_info = bfd_h_get_32 (abfd, exec_bytes.e_info);
643
644 if (N_BADMAG (exec)) return 0;
645#ifdef MACHTYPE_OK
646 if (!(MACHTYPE_OK (N_MACHTYPE (exec)))) return 0;
647#endif
648
3d855632 649 NAME(aout,swap_exec_header_in) (abfd, &exec_bytes, &exec);
252b5132
RH
650
651 target = riscix_some_aout_object_p (abfd, &exec, MY(callback));
652
653 return target;
654}
655
252b5132 656#include "aout-target.h"
This page took 0.117646 seconds and 4 git commands to generate.