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