Touches most files in bfd/, so likely will be blamed for everything..
[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 \
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 */ \
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 \
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))
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
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 { \
122 if (bfd_seek (abfd, (file_ptr) (N_SYMOFF(*execp)), SEEK_SET) != 0) \
123 return false; \
124 \
125 if (! NAME(aout,write_syms) (abfd)) return false; \
126 \
127 if (bfd_seek (abfd, (file_ptr) (N_TRELOFF(*execp)), SEEK_SET) != 0) \
128 return false; \
129 \
130 if (! riscix_squirt_out_relocs (abfd, obj_textsec (abfd))) \
131 return false; \
132 if (bfd_seek (abfd, (file_ptr) (N_DRELOFF(*execp)), SEEK_SET) != 0) \
133 return false; \
134 \
135 if (!NAME(aout,squirt_out_relocs) (abfd, obj_datasec (abfd))) \
136 return false; \
137 } \
138 }
139
140 #include "libaout.h"
141 #include "aout/aout64.h"
142
143 static bfd_reloc_status_type
144 riscix_fix_pcrel_26_done PARAMS ((bfd *, arelent *, asymbol *, PTR,
145 asection *, bfd *, char **));
146
147 static bfd_reloc_status_type
148 riscix_fix_pcrel_26 PARAMS ((bfd *, arelent *, asymbol *, PTR,
149 asection *, bfd *, char **));
150 static const bfd_target *
151 MY (object_p) PARAMS ((bfd *));
152
153 reloc_howto_type *
154 riscix_reloc_type_lookup PARAMS ((bfd *, bfd_reloc_code_real_type));
155
156 void
157 riscix_swap_std_reloc_out PARAMS ((bfd *, arelent *, struct reloc_std_external *));
158
159 boolean
160 riscix_squirt_out_relocs PARAMS ((bfd *, asection *));
161
162 long
163 MY (canonicalize_reloc) PARAMS ((bfd *, sec_ptr, arelent **, asymbol **));
164
165 const bfd_target *
166 riscix_some_aout_object_p PARAMS ((bfd *, struct internal_exec *, const bfd_target *(*) (bfd *)));
167
168
169 static 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),
179 EMPTY_HOWTO (-1),
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
187 static bfd_reloc_status_type
188 riscix_fix_pcrel_26_done (abfd, reloc_entry, symbol, data, input_section,
189 output_bfd, error_message)
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;
197 {
198 /* This is dead simple at present. */
199 return bfd_reloc_ok;
200 }
201
202 static bfd_reloc_status_type
203 riscix_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;
211 char **error_message ATTRIBUTE_UNUSED;
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;
217
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 }
247 else if (relocation & ~ (bfd_vma) 0x03ffffff)
248 flag = bfd_reloc_overflow;
249
250 target &= ~0x00ffffff;
251 target |= (relocation >> 2) & 0x00ffffff;
252 bfd_put_32 (abfd, (bfd_vma) target, (bfd_byte *) data + addr);
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];
257
258 return flag;
259 }
260
261 reloc_howto_type *
262 riscix_reloc_type_lookup (abfd, code)
263 bfd *abfd;
264 bfd_reloc_code_real_type code;
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
297 static const bfd_target *riscix_callback PARAMS ((bfd *));
298
299 void
300 riscix_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 */
327
328 if (r_length == 3)
329 r_pcrel = r_pcrel ? 0 : 1;
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
396 boolean
397 riscix_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;
404
405 unsigned int count = section->reloc_count;
406 bfd_size_type natsize;
407
408 if (count == 0) return true;
409
410 each_size = obj_reloc_entry_size (abfd);
411 natsize = each_size;
412 natsize *= count;
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
425 if (bfd_bwrite ((PTR) native, natsize, abfd) != natsize)
426 {
427 bfd_release (abfd, native);
428 return false;
429 }
430
431 bfd_release (abfd, native);
432 return true;
433 }
434
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 */
439 long
440 MY(canonicalize_reloc) (abfd, section, relptr, symbols)
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
450 /* If we have already read in the relocation table, return the values. */
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
468 if (!NAME(aout,slurp_reloc_table) (abfd, section, symbols))
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
485 /* This is the same as NAME(aout,some_aout_object_p), but has different
486 expansions of the macro definitions. */
487
488 const bfd_target *
489 riscix_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;
496 bfd_size_type amt = sizeof (struct aout_data_struct);
497
498 rawptr = (struct aout_data_struct *) bfd_zalloc (abfd, amt);
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
528 if ((execp->a_info & MF_SQUEEZED) != 0) /* Squeezed files aren't supported
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
566 /* The default symbol entry size is that of traditional Unix. */
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
589 result = (*callback_to_real_object_p) (abfd);
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
632 static const bfd_target *
633 MY(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
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 }
647
648 exec.a_info = H_GET_32 (abfd, exec_bytes.e_info);
649
650 if (N_BADMAG (exec)) return 0;
651 #ifdef MACHTYPE_OK
652 if (!(MACHTYPE_OK (N_MACHTYPE (exec)))) return 0;
653 #endif
654
655 NAME(aout,swap_exec_header_in) (abfd, &exec_bytes, &exec);
656
657 target = riscix_some_aout_object_p (abfd, &exec, MY(callback));
658
659 return target;
660 }
661
662 #include "aout-target.h"
This page took 0.044055 seconds and 5 git commands to generate.