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