*** empty log message ***
[deliverable/binutils-gdb.git] / bfd / riscix.c
1 /* BFD back-end for RISC iX (Acorn, arm) binaries.
2 Copyright 1994, 1995, 1996, 1997, 1998, 2000, 2001
3 Free Software Foundation, Inc.
4 Contributed by Richard Earnshaw (rwe@pegasus.esprit.ec.org)
5
6 This file is part of BFD, the Binary File Descriptor library.
7
8 This program is free software; you can redistribute it and/or modify
9 it under the terms of the GNU General Public License as published by
10 the Free Software Foundation; either version 2 of the License, or
11 (at your option) any later version.
12
13 This program is distributed in the hope that it will be useful,
14 but WITHOUT ANY WARRANTY; without even the implied warranty of
15 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
16 GNU General Public License for more details.
17
18 You should have received a copy of the GNU General Public License
19 along with this program; if not, write to the Free Software
20 Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */
21
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 */
39 /* object. */
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 */
45 #define QMAGIC (MF_SQUEEZED|ZMAGIC) /* Sqeezed demand paged. */
46 /* NOTE: This interpretation of */
47 /* QMAGIC seems to be at variance */
48 /* With that used on other */
49 /* architectures. */
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 { \
118 if (bfd_seek (abfd, (file_ptr) (N_SYMOFF(*execp)), SEEK_SET) != 0) \
119 return false; \
120 \
121 if (! NAME(aout,write_syms) (abfd)) return false; \
122 \
123 if (bfd_seek (abfd, (file_ptr) (N_TRELOFF(*execp)), SEEK_SET) != 0) \
124 return false; \
125 \
126 if (! riscix_squirt_out_relocs (abfd, obj_textsec (abfd))) \
127 return false; \
128 if (bfd_seek (abfd, (file_ptr) (N_DRELOFF(*execp)), SEEK_SET) != 0) \
129 return false; \
130 \
131 if (!NAME(aout,squirt_out_relocs) (abfd, obj_datasec (abfd))) \
132 return false; \
133 } \
134 }
135
136 #include "libaout.h"
137 #include "aout/aout64.h"
138
139 static bfd_reloc_status_type
140 riscix_fix_pcrel_26_done PARAMS ((bfd *, arelent *, asymbol *, PTR,
141 asection *, bfd *, char **));
142
143 static bfd_reloc_status_type
144 riscix_fix_pcrel_26 PARAMS ((bfd *, arelent *, asymbol *, PTR,
145 asection *, bfd *, char **));
146 static const bfd_target *
147 MY (object_p) PARAMS ((bfd *));
148
149 reloc_howto_type *
150 riscix_reloc_type_lookup PARAMS ((bfd *, bfd_reloc_code_real_type));
151
152 void
153 riscix_swap_std_reloc_out PARAMS ((bfd *, arelent *, struct reloc_std_external *));
154
155 boolean
156 riscix_squirt_out_relocs PARAMS ((bfd *, asection *));
157
158 long
159 MY (canonicalize_reloc) PARAMS ((bfd *, sec_ptr, arelent **, asymbol **));
160
161 const bfd_target *
162 riscix_some_aout_object_p PARAMS ((bfd *, struct internal_exec *, const bfd_target *(*) (bfd *)));
163
164
165 static 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),
175 EMPTY_HOWTO (-1),
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
183 static bfd_reloc_status_type
184 riscix_fix_pcrel_26_done (abfd, reloc_entry, symbol, data, input_section,
185 output_bfd, error_message)
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;
193 {
194 /* This is dead simple at present. */
195 return bfd_reloc_ok;
196 }
197
198 static bfd_reloc_status_type
199 riscix_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;
207 char **error_message ATTRIBUTE_UNUSED;
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;
213
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];
253
254 return flag;
255 }
256
257 reloc_howto_type *
258 riscix_reloc_type_lookup (abfd, code)
259 bfd *abfd;
260 bfd_reloc_code_real_type code;
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
293 static const bfd_target *riscix_callback PARAMS ((bfd *));
294
295 void
296 riscix_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 */
323
324 if (r_length == 3)
325 r_pcrel = r_pcrel ? 0 : 1;
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
392 boolean
393 riscix_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;
400
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
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 */
434 long
435 MY(canonicalize_reloc) (abfd, section, relptr, symbols)
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
445 /* If we have already read in the relocation table, return the values. */
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
463 if (!NAME(aout,slurp_reloc_table) (abfd, section, symbols))
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
480 /* This is the same as NAME(aout,some_aout_object_p), but has different
481 expansions of the macro definitions. */
482
483 const bfd_target *
484 riscix_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
492 rawptr = ((struct aout_data_struct *)
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
523 if ((execp->a_info & MF_SQUEEZED) != 0) /* Squeezed files aren't supported
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
561 /* The default symbol entry size is that of traditional Unix. */
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
584 result = (*callback_to_real_object_p) (abfd);
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
627 static const bfd_target *
628 MY(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
649 NAME(aout,swap_exec_header_in) (abfd, &exec_bytes, &exec);
650
651 target = riscix_some_aout_object_p (abfd, &exec, MY(callback));
652
653 return target;
654 }
655
656 #include "aout-target.h"
This page took 0.042931 seconds and 4 git commands to generate.