Automatic date update in version.in
[deliverable/binutils-gdb.git] / bfd / riscix.c
CommitLineData
252b5132 1/* BFD back-end for RISC iX (Acorn, arm) binaries.
2571583a 2 Copyright (C) 1994-2017 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
30#define MF_IMPURE 00200
31#define MF_SQUEEZED 01000
32#define MF_USES_SL 02000
33#define MF_IS_SL 04000
34
35/* Common combinations. */
116c20d2
NC
36
37/* Demand load (impure text). */
38#define IMAGIC (MF_IMPURE | ZMAGIC)
39
40/* OMAGIC with large header.
41 May contain a ref to a shared lib required by the object. */
42#define SPOMAGIC (MF_USES_SL | OMAGIC)
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. */
68ffbac6 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. */
52#define QMAGIC (MF_SQUEEZED | ZMAGIC)
53
54/* Program which uses sl. */
55#define SPZMAGIC (MF_USES_SL | ZMAGIC)
56
57/* Sqeezed ditto. */
58#define SPQMAGIC (MF_USES_SL | QMAGIC)
59
60/* Shared lib part of prog. */
61#define SLZMAGIC (MF_IS_SL | ZMAGIC)
62
63/* Sl which uses another. */
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
AM
102#define N_BADMAG(x) ((((x)->a_info & ~007200) != ZMAGIC) \
103 && (((x)->a_info & ~006000) != OMAGIC) \
104 && ((x)->a_info != NMAGIC))
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); \
dc810e39
AM
115 \
116 execp->a_syms = bfd_get_symcount (abfd) * EXTERNAL_NLIST_SIZE; \
117 execp->a_entry = bfd_get_start_address (abfd); \
118 \
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); \
dc810e39
AM
124 \
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 \
116c20d2 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
NC
137 if (! NAME (aout, write_syms) (abfd)) \
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{
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),
b34976b6
AM
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),
116c20d2 178 HOWTO( 3, 2, 3, 26, TRUE, 0, complain_overflow_signed, riscix_fix_pcrel_26 , "ARM26", TRUE, 0x00ffffff,0x00ffffff, FALSE),
b34976b6
AM
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),
116c20d2
NC
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:
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
NC
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
252b5132 295
116c20d2 296#define MY_bfd_reloc_type_lookup riscix_reloc_type_lookup
6d00b590
AM
297#define MY_bfd_reloc_name_lookup riscix_reloc_name_lookup
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
498 /* Copy the contents of the old tdata struct.
499 In particular, we want the subformat, since for hpux it was set in
500 hp300hpux.c:swap_exec_header_in and will be used in
501 hp300hpux.c:callback. */
502 if (oldrawptr != NULL)
503 *abfd->tdata.aout_data = *oldrawptr;
504
505 abfd->tdata.aout_data->a.hdr = &rawptr->e;
116c20d2
NC
506 /* Copy in the internal_exec struct. */
507 *(abfd->tdata.aout_data->a.hdr) = *execp;
252b5132
RH
508 execp = abfd->tdata.aout_data->a.hdr;
509
116c20d2 510 /* Set the file flags. */
252b5132
RH
511 abfd->flags = BFD_NO_FLAGS;
512 if (execp->a_drsize || execp->a_trsize)
513 abfd->flags |= HAS_RELOC;
116c20d2 514 /* Setting of EXEC_P has been deferred to the bottom of this function. */
252b5132
RH
515 if (execp->a_syms)
516 abfd->flags |= HAS_LINENO | HAS_DEBUG | HAS_SYMS | HAS_LOCALS;
bbb1afc8 517 if (N_DYNAMIC (execp))
252b5132
RH
518 abfd->flags |= DYNAMIC;
519
116c20d2
NC
520 /* Squeezed files aren't supported (yet)! */
521 if ((execp->a_info & MF_SQUEEZED) != 0)
252b5132
RH
522 {
523 bfd_set_error (bfd_error_wrong_format);
524 return NULL;
525 }
116c20d2 526 else if ((execp->a_info & MF_IS_SL) != 0)
252b5132 527 {
116c20d2 528 /* Nor are shared libraries. */
252b5132
RH
529 bfd_set_error (bfd_error_wrong_format);
530 return NULL;
531 }
bbb1afc8 532 else if (N_MAGIC (execp) == ZMAGIC)
252b5132
RH
533 {
534 abfd->flags |= D_PAGED | WP_TEXT;
535 adata (abfd).magic = z_magic;
536 }
bbb1afc8 537 else if (N_MAGIC (execp) == NMAGIC)
252b5132
RH
538 {
539 abfd->flags |= WP_TEXT;
540 adata (abfd).magic = n_magic;
541 }
bbb1afc8 542 else if (N_MAGIC (execp) == OMAGIC)
252b5132
RH
543 adata (abfd).magic = o_magic;
544 else
116c20d2
NC
545 /* Should have been checked with N_BADMAG before this routine
546 was called. */
547 abort ();
252b5132
RH
548
549 bfd_get_start_address (abfd) = execp->a_entry;
550
116c20d2 551 obj_aout_symbols (abfd) = NULL;
252b5132
RH
552 bfd_get_symcount (abfd) = execp->a_syms / sizeof (struct external_nlist);
553
554 /* The default relocation entry size is that of traditional V7 Unix. */
555 obj_reloc_entry_size (abfd) = RELOC_STD_SIZE;
556
3d855632 557 /* The default symbol entry size is that of traditional Unix. */
252b5132
RH
558 obj_symbol_entry_size (abfd) = EXTERNAL_NLIST_SIZE;
559
560 obj_aout_external_syms (abfd) = NULL;
561 obj_aout_external_strings (abfd) = NULL;
562 obj_aout_sym_hashes (abfd) = NULL;
563
116c20d2 564 if (! NAME (aout, make_sections) (abfd))
252b5132
RH
565 return NULL;
566
eea6121a
AM
567 obj_datasec (abfd)->size = execp->a_data;
568 obj_bsssec (abfd)->size = execp->a_bss;
252b5132
RH
569
570 obj_textsec (abfd)->flags =
571 (execp->a_trsize != 0
572 ? (SEC_ALLOC | SEC_LOAD | SEC_CODE | SEC_HAS_CONTENTS | SEC_RELOC)
573 : (SEC_ALLOC | SEC_LOAD | SEC_CODE | SEC_HAS_CONTENTS));
574 obj_datasec (abfd)->flags =
575 (execp->a_drsize != 0
576 ? (SEC_ALLOC | SEC_LOAD | SEC_DATA | SEC_HAS_CONTENTS | SEC_RELOC)
577 : (SEC_ALLOC | SEC_LOAD | SEC_DATA | SEC_HAS_CONTENTS));
578 obj_bsssec (abfd)->flags = SEC_ALLOC;
579
3d855632 580 result = (*callback_to_real_object_p) (abfd);
252b5132
RH
581
582#if defined(MACH) || defined(STAT_FOR_EXEC)
583 /* The original heuristic doesn't work in some important cases. The
116c20d2
NC
584 a.out file has no information about the text start address. For
585 files (like kernels) linked to non-standard addresses (ld -Ttext
586 nnn) the entry point may not be between the default text start
587 (obj_textsec(abfd)->vma) and (obj_textsec(abfd)->vma) + text size
588 This is not just a mach issue. Many kernels are loaded at non
589 standard addresses. */
252b5132
RH
590 {
591 struct stat stat_buf;
116c20d2 592
252b5132
RH
593 if (abfd->iostream != NULL
594 && (abfd->flags & BFD_IN_MEMORY) == 0
595 && (fstat(fileno((FILE *) (abfd->iostream)), &stat_buf) == 0)
596 && ((stat_buf.st_mode & 0111) != 0))
597 abfd->flags |= EXEC_P;
598 }
599#else /* ! MACH */
600 /* Now that the segment addresses have been worked out, take a better
601 guess at whether the file is executable. If the entry point
602 is within the text segment, assume it is. (This makes files
603 executable even if their entry point address is 0, as long as
604 their text starts at zero.)
605
606 At some point we should probably break down and stat the file and
607 declare it executable if (one of) its 'x' bits are on... */
608 if ((execp->a_entry >= obj_textsec(abfd)->vma) &&
eea6121a 609 (execp->a_entry < obj_textsec(abfd)->vma + obj_textsec(abfd)->size))
252b5132
RH
610 abfd->flags |= EXEC_P;
611#endif /* MACH */
116c20d2 612 if (result == NULL)
252b5132
RH
613 {
614 free (rawptr);
615 abfd->tdata.aout_data = oldrawptr;
616 }
617 return result;
618}
619
252b5132 620static const bfd_target *
116c20d2 621MY (object_p) (bfd *abfd)
252b5132 622{
116c20d2
NC
623 struct external_exec exec_bytes; /* Raw exec header from file. */
624 struct internal_exec exec; /* Cleaned-up exec header. */
252b5132
RH
625 const bfd_target *target;
626
116c20d2 627 if (bfd_bread ((void *) &exec_bytes, (bfd_size_type) EXEC_BYTES_SIZE, abfd)
dc810e39
AM
628 != EXEC_BYTES_SIZE)
629 {
630 if (bfd_get_error () != bfd_error_system_call)
631 bfd_set_error (bfd_error_wrong_format);
116c20d2 632 return NULL;
dc810e39 633 }
252b5132 634
dc810e39 635 exec.a_info = H_GET_32 (abfd, exec_bytes.e_info);
252b5132 636
bbb1afc8 637 if (N_BADMAG (&exec))
116c20d2
NC
638 return NULL;
639
252b5132 640#ifdef MACHTYPE_OK
bbb1afc8 641 if (!(MACHTYPE_OK (N_MACHTYPE (&exec))))
116c20d2 642 return NULL;
252b5132
RH
643#endif
644
116c20d2 645 NAME (aout, swap_exec_header_in) (abfd, & exec_bytes, & exec);
252b5132 646
116c20d2 647 target = riscix_some_aout_object_p (abfd, & exec, MY (callback));
252b5132
RH
648
649 return target;
650}
651
252b5132 652#include "aout-target.h"
This page took 1.005724 seconds and 4 git commands to generate.