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