Line 0
Link Here
|
|
|
1 |
/* BFD backend for traditional MiNT executables. |
2 |
Copyright 1998, 2007, 2008, 2009 Free Software Foundation, Inc. |
3 |
Originally written by Guido Flohr (guido@freemint.de). |
4 |
Modified by Vincent Riviere (vincent.riviere@freesbee.fr). |
5 |
|
6 |
This file is part of BFD, the Binary File Descriptor library. |
7 |
|
8 |
This program is free software; you can redistribute it and/or modify |
9 |
it under the terms of the GNU General Public License as published by |
10 |
the Free Software Foundation; either version 3 of the License, or |
11 |
(at your option) any later version. |
12 |
|
13 |
This program is distributed in the hope that it will be useful, |
14 |
but WITHOUT ANY WARRANTY; without even the implied warranty of |
15 |
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the |
16 |
GNU General Public License for more details. |
17 |
|
18 |
You should have received a copy of the GNU General Public License |
19 |
along with this program; if not, write to the Free Software |
20 |
Foundation, Inc., 51 Franklin Street - Fifth Floor, Boston, |
21 |
MA 02110-1301, USA. */ |
22 |
|
23 |
/* The format of executables on Atari is actually not a.out, it is |
24 |
only chosen as an approach which comes close enough. The layout of a |
25 |
program image on disk looked like this: |
26 |
|
27 |
+-----------------+ |
28 |
| 28 Bytes Header | |
29 |
+-----------------+ |
30 |
| Text segment | |
31 |
+-----------------+ |
32 |
| Data segment | |
33 |
+-----------------+ |
34 |
| BSS | |
35 |
+-----------------+ |
36 |
| Symbol table | |
37 |
+-----------------+ |
38 |
| TPA relocation | |
39 |
+-----------------+ |
40 |
|
41 |
The 28 byte exec header used to look like this: |
42 |
|
43 |
struct old_exec_header |
44 |
{ |
45 |
bfd_byte a_magic[2]; |
46 |
bfd_byte a_text[4]; |
47 |
bfd_byte a_data[4]; |
48 |
bfd_byte a_bss[4]; |
49 |
bfd_byte a_syms[4]; |
50 |
bfd_byte a_resvd[4]; |
51 |
bfd_byte a_abs[2]; |
52 |
}; |
53 |
|
54 |
The first two bytes (A_MAGIC) contained an assembler branch |
55 |
instruction to the beginning of the text segment. Because the |
56 |
exec header had a fixed size and the text entry point was constant |
57 |
this assembler instruction also had a constant value (0x601a). |
58 |
In fact the operating system never really executed the branch |
59 |
instruction but used this value (0x601a) as a magic value. |
60 |
|
61 |
TEXT, DATA and BSS were as one would expect them. The symbol |
62 |
table wasn't. Several different formats were in use, none of them |
63 |
very efficient, none of them powerful enough to support source |
64 |
level debugging. I've changed that and the GNU symbol table will |
65 |
now be used instead (unless the --traditional-format option was |
66 |
given to the linker). |
67 |
|
68 |
If the last member A_ABS of the exec header is zero the program |
69 |
image contains an additional table with relocation information |
70 |
at the end of the image. The kernel can load program images at |
71 |
virtually any address in the address space. In fact it will load |
72 |
it at the start of the biggest block of free memory. This block |
73 |
is then called the Transient Program Area TPA and the image has |
74 |
to be relocated against the TPA at runtime. The relocation info |
75 |
itself is in a simply way compressed: It starts with a four-byte |
76 |
value, the first address within the image to be relocated. Now |
77 |
following are one-byte offsets to the last address. The special |
78 |
value of 1 (which is impossible as an offset) signifies that 254 |
79 |
has to be added to the next offset. The table is finished with |
80 |
a zero-byte. |
81 |
|
82 |
I now simply extended the header from its old 28 bytes to 256 |
83 |
bytes. The first 28 bytes give home to a standard Atari header, |
84 |
the rest is for extensions. The extension header starts with |
85 |
a ``real'' assembler instruction, a far jump to the text entry |
86 |
point. The extension header gives home to a standard a.out |
87 |
exec header (currently NMAGIC) plus some extra |
88 |
more or less useful fields plus space to future extensions. |
89 |
For the OS the extension header will already belong to the text |
90 |
segment, for BFD backends the text segment is 228 (or 0xe4) |
91 |
bytes smaller than for the OS. This explains for example the |
92 |
funny TEXT_START_ADDR 0xe4. |
93 |
|
94 |
The TARGET_PAGE_SIZE is 2 which is only fake. There is currently |
95 |
no such thing as memory paging on the Atari (and this is why |
96 |
ZMAGICs are disabled for now to allow for future enhancements). |
97 |
|
98 |
If you think that this whole file looks quite like a big hack |
99 |
you're probably right. But the results (mainly the output of |
100 |
the linker) seem to work and they allow to use up-to-date |
101 |
binutils on the Atari until a better executable format (maybe |
102 |
ELF) has been established for this machine. */ |
103 |
|
104 |
#include "sysdep.h" |
105 |
#include "bfd.h" |
106 |
|
107 |
#define N_HEADER_IN_TEXT(x) 0 |
108 |
#define BYTES_IN_WORD 4 |
109 |
#define ENTRY_CAN_BE_ZERO |
110 |
#define N_SHARED_LIB(x) 0 |
111 |
#define TEXT_START_ADDR 0xe4 |
112 |
#define TARGET_PAGE_SIZE 2 |
113 |
#define TARGET_IS_BIG_ENDIAN_P |
114 |
#define DEFAULT_ARCH bfd_arch_m68k |
115 |
#define N_TXTADDR(x) TEXT_START_ADDR |
116 |
|
117 |
/* Do not "beautify" the CONCAT* macro args. Traditional C will not |
118 |
remove whitespace added here, and thus will fail to concatenate |
119 |
the tokens. */ |
120 |
#define MY(OP) CONCAT2 (m68kmint_prg_,OP) |
121 |
#define TARGETNAME "a.out-mintprg" |
122 |
#define NAME(x,y) CONCAT3 (mintprg,_32_,y) |
123 |
|
124 |
/* We have to do quite a lot of magic to make the Atari format |
125 |
for GEMDOS executables fit into the standard a.out format. |
126 |
We start with the original header. */ |
127 |
#define external_exec mint_external_exec |
128 |
struct mint_external_exec |
129 |
{ |
130 |
bfd_byte g_branch[2]; /* 0x601a. */ |
131 |
bfd_byte g_text[4]; /* Length of text section. */ |
132 |
bfd_byte g_data[4]; /* Length of data section. */ |
133 |
bfd_byte g_bss[4]; /* Length of bss section. */ |
134 |
bfd_byte g_syms[4]; /* Length of symbol table. */ |
135 |
bfd_byte g_extmagic[4]; /* Always 0x4d694e54 |
136 |
(in ASCII: ``MiNT''). */ |
137 |
bfd_byte g_flags[4]; /* Atari special flags. */ |
138 |
bfd_byte g_abs[2]; /* Non-zero if absolute (no relocation |
139 |
info. */ |
140 |
|
141 |
/* We extend this header now to provide the information that the |
142 |
binutils want to see. Everything following will actually be part |
143 |
of the text segment (from MiNT's point of view). As a |
144 |
consequence the text section has 228 bytes of redundancy. |
145 |
|
146 |
The following eight bytes should be treated as opaque. |
147 |
If the word ``opaque'' always attracts your curiosity in |
148 |
typedefs and structs, here's the explanation: These eight bytes |
149 |
are really two assembler instructions. The first one moves |
150 |
the contents of e_entry into register d0, the second one |
151 |
jumps (pc-relative) to the entry point. See swap_exec_header_out |
152 |
for details. */ |
153 |
bfd_byte g_jump_entry[8]; |
154 |
|
155 |
/* Now following a standard a.out header. Note that the values |
156 |
may differ from the one given on top. The traditional header |
157 |
contains the values that the OS wants to see, the values below |
158 |
are the values that make the binutils work. */ |
159 |
bfd_byte e_info[4]; /* Magic number and stuff. */ |
160 |
bfd_byte e_text[4]; /* Length of text section in bytes. */ |
161 |
bfd_byte e_data[4]; /* Length of data section. */ |
162 |
bfd_byte e_bss[4]; /* Length of standard symbol |
163 |
table. */ |
164 |
bfd_byte e_syms[4]; /* Length of symbol table. */ |
165 |
bfd_byte e_entry[4]; /* Start address. */ |
166 |
bfd_byte e_trsize[4]; /* Length of text relocation |
167 |
info. */ |
168 |
bfd_byte e_drsize[4]; /* Length of data relocation |
169 |
info. */ |
170 |
|
171 |
bfd_byte g_tparel_pos[4]; /* File position of TPA relative |
172 |
relocation info. */ |
173 |
bfd_byte g_tparel_size[4]; /* Length of TPA relative relocation |
174 |
info. */ |
175 |
|
176 |
/* This is for extensions. */ |
177 |
bfd_byte g_stkpos[4]; /* If stacksize is hardcoded into |
178 |
the executable you will find it |
179 |
at file offset g_stkpos. If |
180 |
not this is NULL. */ |
181 |
|
182 |
bfd_byte g_symbol_format[4]; /* Format of the symbol table. See |
183 |
definitions for _MINT_SYMBOL_FORMAT* |
184 |
above. */ |
185 |
|
186 |
/* Pad with zeros. */ |
187 |
bfd_byte g_pad0[172]; |
188 |
}; |
189 |
#define EXEC_BYTES_SIZE 256 |
190 |
#define GEMDOS_HEADER_SIZE 28 |
191 |
|
192 |
/* The following defines are required by aoutx.h. |
193 |
They are not automatically defined in aout/aout64.h |
194 |
if external_exec is defined. */ |
195 |
|
196 |
#define OMAGIC 0407 /* Object file or impure executable. */ |
197 |
#define NMAGIC 0410 /* Code indicating pure executable. */ |
198 |
#define ZMAGIC 0413 /* Code indicating demand-paged executable. */ |
199 |
#define BMAGIC 0415 /* Used by a b.out object. */ |
200 |
#define QMAGIC 0314 /* Like ZMAGIC but with N_HEADER_IN_TEXT true. */ |
201 |
|
202 |
/* Files using the following magic flags will not be loaded. */ |
203 |
#define N_BADMAG(x) (N_MAGIC(x) != NMAGIC) |
204 |
|
205 |
/* For DRI symbol table format. */ |
206 |
struct dri_symbol |
207 |
{ |
208 |
bfd_byte a_name[8]; /* Symbol name */ |
209 |
bfd_byte a_type[2]; /* Type flag, i.e. A_TEXT etc; see below. */ |
210 |
bfd_byte a_value[4]; /* value of this symbol (or sdb offset). */ |
211 |
}; |
212 |
#define DRI_SYMBOL_SIZE 14 |
213 |
|
214 |
/* Simple values for a_type. */ |
215 |
#define A_UNDF 0 |
216 |
#define A_BSS 0x0100 |
217 |
#define A_TEXT 0x0200 |
218 |
#define A_DATA 0x0400 |
219 |
#define A_EXT 0x0800 /* External. */ |
220 |
#define A_EQREG 0x1000 /* Equated register. */ |
221 |
#define A_GLOBL 0x2000 /* Global. */ |
222 |
#define A_EQU 0x4000 /* Equated. */ |
223 |
#define A_DEF 0x8000 /* Defined. */ |
224 |
#define A_LNAM 0x0048 /* GST compatible long name. */ |
225 |
/* File symbols ala aln. */ |
226 |
#define A_TFILE 0x0280 /* Text file corresponding to object module. */ |
227 |
#define A_TFARC 0x02C0 /* Text file archive. Unfortunately this |
228 |
conflicts with the bits in A_LNAM. */ |
229 |
|
230 |
/* The following include contains the definitions for internal a.out structures |
231 |
as well as the prototypes for the NAME(...) functions defined in aoutx.h. */ |
232 |
|
233 |
#include "libaout.h" |
234 |
|
235 |
/* The following function is similar to _bfd_final_link_relocate, except it |
236 |
adds the reloc structure as an additional parameter. |
237 |
It will be used int aoutx.h. */ |
238 |
|
239 |
static bfd_reloc_status_type |
240 |
m68kmint_prg_final_link_relocate_rel (reloc_howto_type *howto, |
241 |
bfd *input_bfd, |
242 |
asection *input_section, |
243 |
bfd_byte *contents, |
244 |
bfd_vma address, |
245 |
bfd_vma value, |
246 |
bfd_vma addend, |
247 |
struct reloc_std_external *rel); |
248 |
|
249 |
#define MY_final_link_relocate_rel m68kmint_prg_final_link_relocate_rel |
250 |
|
251 |
/* The following include contains the definitions for the NAME(...) functions. */ |
252 |
|
253 |
#include "aoutx.h" |
254 |
|
255 |
/* Data structure that holds some private information for us. */ |
256 |
struct mint_internal_info |
257 |
{ |
258 |
struct bfd_link_info *linkinfo; /* Remembered from final_link. */ |
259 |
bfd_boolean traditional_format; /* Saved from link info. */ |
260 |
int symbol_format; /* Format of the symbol table. */ |
261 |
void *tparel; /* Data for TPA relative relocation |
262 |
information. */ |
263 |
file_ptr tparel_pos; /* File position of TPA relative |
264 |
relocation information. */ |
265 |
bfd_size_type tparel_size; /* Size of TPA relative relocation |
266 |
information. */ |
267 |
bfd_size_type dri_symtab_size; /* Size of traditional symbol table. */ |
268 |
|
269 |
#define MINT_RELOC_CHUNKSIZE 0x1000 |
270 |
bfd_vma *relocs; /* Array of address relocations. */ |
271 |
unsigned long relocs_used; /* Number of relocation entries |
272 |
already used up. */ |
273 |
unsigned long relocs_allocated; /* Number of relocation entries |
274 |
allocated. */ |
275 |
|
276 |
bfd_vma stkpos; /* File offset to value of _stksize. */ |
277 |
|
278 |
flagword prg_flags; /* Standard GEMDOS flags. */ |
279 |
|
280 |
bfd_boolean override_stack_size; /* TRUE if the executable stack size |
281 |
must be overriden with stack_size. */ |
282 |
bfd_signed_vma stack_size; |
283 |
|
284 |
bfd_boolean reloc_error; /* TRUE if an unhandled error during |
285 |
relocation occured. */ |
286 |
}; |
287 |
|
288 |
/* If --traditional-format was given to the linker an old-style DRI |
289 |
symbol table is written into the executable. This is with respect |
290 |
to many old debugging tools or disassemblers which expect this format. |
291 |
Although created by the linker, these symbols will be ignored from |
292 |
input files. */ |
293 |
#define _MINT_SYMBOL_FORMAT_GNU 0 |
294 |
#define _MINT_SYMBOL_FORMAT_DRI 1 |
295 |
|
296 |
/* Declarations for the variables and functions |
297 |
defined later in aout-target.h. */ |
298 |
|
299 |
static const bfd_target * |
300 |
m68kmint_prg_callback (bfd *abfd); |
301 |
|
302 |
static void |
303 |
MY_final_link_callback (bfd *abfd, |
304 |
file_ptr *ptreloff, |
305 |
file_ptr *pdreloff, |
306 |
file_ptr *psymoff); |
307 |
|
308 |
extern const bfd_target m68kmint_prg_vec; |
309 |
|
310 |
/* Initialize a new BFD using our file format. */ |
311 |
|
312 |
#define MY_mkobject m68kmint_prg_mkobject |
313 |
|
314 |
static bfd_boolean |
315 |
m68kmint_prg_mkobject (bfd *abfd) |
316 |
{ |
317 |
struct mint_internal_info *myinfo; |
318 |
|
319 |
if (!NAME (aout, mkobject (abfd))) |
320 |
return FALSE; |
321 |
|
322 |
/* Allocate our private BFD data. */ |
323 |
myinfo = bfd_zalloc (abfd, sizeof (*myinfo)); |
324 |
if (myinfo == NULL) |
325 |
return FALSE; |
326 |
obj_aout_ext (abfd) = myinfo; |
327 |
|
328 |
return TRUE; |
329 |
} |
330 |
|
331 |
/* Finish up the reading of an a.out file header. */ |
332 |
|
333 |
#define MY_object_p m68kmint_prg_object_p |
334 |
|
335 |
static const bfd_target * |
336 |
m68kmint_prg_object_p (bfd *abfd) |
337 |
{ |
338 |
struct external_exec exec_bytes; /* Raw exec header from file. */ |
339 |
struct internal_exec exec; /* Cleaned-up exec header. */ |
340 |
const bfd_target *target; |
341 |
bfd_size_type amt = EXEC_BYTES_SIZE; |
342 |
struct mint_internal_info *myinfo; |
343 |
|
344 |
/* Read the exec bytesd from the file. */ |
345 |
if (bfd_bread (&exec_bytes, amt, abfd) != amt) |
346 |
{ |
347 |
if (bfd_get_error () != bfd_error_system_call) |
348 |
bfd_set_error (bfd_error_wrong_format); |
349 |
return NULL; |
350 |
} |
351 |
|
352 |
/* Instead of byte-swapping we compare bytes. */ |
353 |
if (exec_bytes.g_branch[0] != 0x60 |
354 |
|| exec_bytes.g_branch[1] != 0x1a |
355 |
|| exec_bytes.g_extmagic[0] != 'M' |
356 |
|| exec_bytes.g_extmagic[1] != 'i' |
357 |
|| exec_bytes.g_extmagic[2] != 'N' |
358 |
|| exec_bytes.g_extmagic[3] != 'T') |
359 |
{ |
360 |
bfd_set_error (bfd_error_wrong_format); |
361 |
return NULL; |
362 |
} |
363 |
|
364 |
/* Swap the standard a.out fields. */ |
365 |
NAME (aout, swap_exec_header_in) (abfd, &exec_bytes, &exec); |
366 |
|
367 |
/* Check a.out magic value. */ |
368 |
if (N_BADMAG (exec)) |
369 |
{ |
370 |
bfd_set_error (bfd_error_wrong_format); |
371 |
return NULL; |
372 |
} |
373 |
|
374 |
/* Initialize this BFD with the exec values. */ |
375 |
target = NAME (aout, some_aout_object_p) (abfd, &exec, m68kmint_prg_callback); |
376 |
|
377 |
/* Allocate our private BFD data. */ |
378 |
myinfo = bfd_zalloc (abfd, sizeof (*myinfo)); |
379 |
if (myinfo == NULL) |
380 |
return NULL; |
381 |
obj_aout_ext (abfd) = myinfo; |
382 |
|
383 |
/* Now get the missing information. */ |
384 |
myinfo->prg_flags = bfd_h_get_32 (abfd, exec_bytes.g_flags); |
385 |
myinfo->stkpos = bfd_h_get_32 (abfd, exec_bytes.g_stkpos); |
386 |
myinfo->symbol_format = bfd_h_get_32 (abfd, exec_bytes.g_symbol_format); |
387 |
|
388 |
/* TPA relocation information. */ |
389 |
myinfo->tparel_pos = bfd_h_get_32 (abfd, exec_bytes.g_tparel_pos); |
390 |
myinfo->tparel_size = bfd_h_get_32 (abfd, exec_bytes.g_tparel_size); |
391 |
|
392 |
/* FIXME: Currently we always read the TPA relative relocation |
393 |
information. This is suboptimal because often times there |
394 |
is no need for it. Read it only if need be! Maybe this should |
395 |
also depend on abfd->cacheable? */ |
396 |
if (myinfo->tparel_size == 0) |
397 |
myinfo->tparel = bfd_zalloc (abfd, 4); |
398 |
else |
399 |
myinfo->tparel = bfd_alloc (abfd, myinfo->tparel_size); |
400 |
|
401 |
if (myinfo->tparel == NULL) |
402 |
return NULL; |
403 |
|
404 |
if (myinfo->tparel_size == 0) |
405 |
{ |
406 |
myinfo->tparel_size = 4; |
407 |
} |
408 |
else |
409 |
{ |
410 |
/* Read the information from the bfd. */ |
411 |
if (bfd_seek (abfd, myinfo->tparel_pos, SEEK_SET) != 0 |
412 |
|| (bfd_bread (myinfo->tparel, myinfo->tparel_size, abfd) |
413 |
!= myinfo->tparel_size)) |
414 |
return NULL; |
415 |
} |
416 |
|
417 |
return target; |
418 |
} |
419 |
|
420 |
/* Free all information we have cached for this BFD. We can always |
421 |
read it again later if we need it. */ |
422 |
|
423 |
#define MY_bfd_free_cached_info m68kmint_prg_bfd_free_cached_info |
424 |
|
425 |
static bfd_boolean |
426 |
m68kmint_prg_bfd_free_cached_info (bfd *abfd) |
427 |
{ |
428 |
struct mint_internal_info *myinfo = obj_aout_ext (abfd); |
429 |
|
430 |
if (myinfo != NULL && myinfo->relocs != NULL) |
431 |
{ |
432 |
free (myinfo->relocs); |
433 |
myinfo->relocs = NULL; |
434 |
} |
435 |
|
436 |
/* myinfo itself has been allocated by bfd_zalloc() |
437 |
so will be automatically freed along with the BFD. |
438 |
Same for myinfo->tparel. */ |
439 |
|
440 |
return NAME (aout, bfd_free_cached_info) (abfd); |
441 |
} |
442 |
|
443 |
/* Write a DRI symbol with TYPE and VALUE. If the NAME of the |
444 |
symbol exceeds 8 characters write a long symbol. If it |
445 |
exceeds 22 characters truncate the name. */ |
446 |
|
447 |
static int |
448 |
write_dri_symbol (bfd *abfd, const char *name, int type, bfd_vma value) |
449 |
{ |
450 |
int written_bytes = 0; |
451 |
struct dri_symbol sym; |
452 |
int is_long_name = strlen (name) > sizeof (sym.a_name); |
453 |
|
454 |
if (is_long_name) |
455 |
type |= A_LNAM; |
456 |
|
457 |
strncpy ((char*)sym.a_name, name, sizeof (sym.a_name)); |
458 |
bfd_put_16 (abfd, type, sym.a_type); |
459 |
bfd_put_32 (abfd, value, sym.a_value); |
460 |
|
461 |
if (bfd_bwrite (&sym, DRI_SYMBOL_SIZE, abfd) != DRI_SYMBOL_SIZE) |
462 |
return -1; |
463 |
written_bytes += DRI_SYMBOL_SIZE; |
464 |
|
465 |
if (is_long_name) |
466 |
{ |
467 |
char more_name[DRI_SYMBOL_SIZE]; |
468 |
|
469 |
strncpy (more_name, name + sizeof (sym.a_name), DRI_SYMBOL_SIZE); |
470 |
|
471 |
if (bfd_bwrite (more_name, DRI_SYMBOL_SIZE, abfd) != DRI_SYMBOL_SIZE) |
472 |
return -1; |
473 |
written_bytes += DRI_SYMBOL_SIZE; |
474 |
} |
475 |
|
476 |
return written_bytes; |
477 |
} |
478 |
|
479 |
/* Emit a traditional DRI symbol table while linking. |
480 |
Most of this code comes from aout_link_write_symbols() in aoutx.h. */ |
481 |
|
482 |
static bfd_boolean |
483 |
link_write_traditional_syms (bfd *abfd, struct bfd_link_info *info) |
484 |
{ |
485 |
bfd *input_bfd; |
486 |
enum bfd_link_strip strip = info->strip; |
487 |
enum bfd_link_discard discard = info->discard; |
488 |
struct mint_internal_info *myinfo = obj_aout_ext (abfd); |
489 |
bfd *last_archive = NULL; |
490 |
|
491 |
/* Position file pointer. */ |
492 |
if (bfd_seek (abfd, obj_sym_filepos (abfd), SEEK_SET) != 0) |
493 |
return FALSE; |
494 |
|
495 |
myinfo->dri_symtab_size = 0; |
496 |
|
497 |
for (input_bfd = info->input_bfds; input_bfd != NULL; input_bfd = input_bfd->link_next) |
498 |
{ |
499 |
bfd_size_type sym_count = obj_aout_external_sym_count (input_bfd); |
500 |
char *strings = obj_aout_external_strings (input_bfd); |
501 |
struct external_nlist *sym = obj_aout_external_syms (input_bfd); |
502 |
struct external_nlist *sym_end = sym + sym_count; |
503 |
struct aout_link_hash_entry **sym_hash = obj_aout_sym_hashes (input_bfd); |
504 |
bfd_boolean pass = FALSE; |
505 |
bfd_boolean skip = FALSE; |
506 |
bfd_boolean skip_next = FALSE; |
507 |
int written_bytes; |
508 |
int a_type; |
509 |
bfd_boolean write_archive_name = FALSE; |
510 |
bfd_vma val = 0; |
511 |
|
512 |
/* First write out a symbol for the archive if we do not |
513 |
strip these symbols and if it differs from the last |
514 |
one. */ |
515 |
if (input_bfd->my_archive != last_archive |
516 |
&& input_bfd->my_archive != NULL) |
517 |
{ |
518 |
write_archive_name = TRUE; |
519 |
last_archive = input_bfd->my_archive; |
520 |
} |
521 |
|
522 |
if (write_archive_name |
523 |
&& strip != strip_all |
524 |
&& (strip != strip_some |
525 |
|| bfd_hash_lookup (info->keep_hash, |
526 |
input_bfd->my_archive->filename, |
527 |
FALSE, FALSE) != NULL) |
528 |
&& discard != discard_all) |
529 |
{ |
530 |
val = bfd_get_section_vma (abfd, |
531 |
obj_textsec (input_bfd)->output_section) |
532 |
+ obj_textsec (input_bfd)->output_offset; |
533 |
|
534 |
written_bytes = write_dri_symbol (abfd, |
535 |
input_bfd->my_archive->filename, |
536 |
A_TFILE, val); |
537 |
|
538 |
if (written_bytes < 0) |
539 |
return FALSE; |
540 |
else |
541 |
myinfo->dri_symtab_size += written_bytes; |
542 |
} |
543 |
|
544 |
/* Now write out a symbol for the object file if we do not |
545 |
strip these symbols. */ |
546 |
if (strip != strip_all |
547 |
&& (strip != strip_some |
548 |
|| bfd_hash_lookup (info->keep_hash, input_bfd->filename, |
549 |
FALSE, FALSE) != NULL) |
550 |
&& discard != discard_all) |
551 |
{ |
552 |
val = bfd_get_section_vma (abfd, |
553 |
obj_textsec (input_bfd)->output_section) |
554 |
+ obj_textsec (input_bfd)->output_offset; |
555 |
|
556 |
written_bytes = write_dri_symbol (abfd, input_bfd->filename, |
557 |
A_TFILE, val); |
558 |
if (written_bytes < 0) |
559 |
return FALSE; |
560 |
else |
561 |
myinfo->dri_symtab_size += written_bytes; |
562 |
} |
563 |
|
564 |
/* Now we have a problem. All symbols that we see have already |
565 |
been marked written (because we write them a second time |
566 |
here. If we would do it the clean way we would have |
567 |
to traverse the entire symbol map and reset the written |
568 |
flag. We hack here instead... */ |
569 |
#define mark_written(h) (* (int *) &h->written = (int) TRUE + 1) |
570 |
#define is_written(h) ((int) h->written == (int) TRUE + 1) |
571 |
for (; sym < sym_end; sym++, sym_hash++) |
572 |
{ |
573 |
const char *name; |
574 |
int type; |
575 |
struct aout_link_hash_entry *h; |
576 |
asection *symsec; |
577 |
val = 0; |
578 |
|
579 |
type = H_GET_8 (input_bfd, sym->e_type); |
580 |
name = strings + GET_WORD (input_bfd, sym->e_strx); |
581 |
|
582 |
h = NULL; |
583 |
|
584 |
if (pass) |
585 |
{ |
586 |
/* Pass this symbol through. It is the target of an |
587 |
indirect or warning symbol. */ |
588 |
val = GET_WORD (input_bfd, sym->e_value); |
589 |
pass = FALSE; |
590 |
} |
591 |
else if (skip_next) |
592 |
{ |
593 |
/* Skip this symbol, which is the target of an indirect |
594 |
symbol that we have changed to no longer be an indirect |
595 |
symbol. */ |
596 |
skip_next = FALSE; |
597 |
continue; |
598 |
} |
599 |
else |
600 |
{ |
601 |
struct aout_link_hash_entry *hresolve = *sym_hash; |
602 |
|
603 |
/* We have saved the hash table entry for this symbol, if |
604 |
there is one. Note that we could just look it up again |
605 |
in the hash table, provided we first check that it is an |
606 |
external symbol. */ |
607 |
h = *sym_hash; |
608 |
|
609 |
/* Use the name from the hash table, in case the symbol was |
610 |
wrapped. */ |
611 |
if (h != NULL |
612 |
&& h->root.type != bfd_link_hash_warning) |
613 |
name = h->root.root.string; |
614 |
|
615 |
/* If this is an indirect or warning symbol, then change |
616 |
hresolve to the base symbol. */ |
617 |
hresolve = h; |
618 |
if (h != (struct aout_link_hash_entry *) NULL |
619 |
&& (h->root.type == bfd_link_hash_indirect |
620 |
|| h->root.type == bfd_link_hash_warning)) |
621 |
{ |
622 |
hresolve = (struct aout_link_hash_entry*) h->root.u.i.link; |
623 |
while (hresolve->root.type == bfd_link_hash_indirect |
624 |
|| hresolve->root.type == bfd_link_hash_warning) |
625 |
hresolve = ((struct aout_link_hash_entry*) |
626 |
hresolve->root.u.i.link); |
627 |
} |
628 |
|
629 |
/* If the symbol has already been written out skip it. */ |
630 |
if (h != NULL |
631 |
&& is_written (h)) |
632 |
{ |
633 |
if ((type & N_TYPE) == N_INDR |
634 |
|| type == N_WARNING) |
635 |
skip_next = TRUE; |
636 |
continue; |
637 |
} |
638 |
|
639 |
/* See if we are stripping this symbol. */ |
640 |
skip = FALSE; |
641 |
|
642 |
/* Skip all debugger symbols. No way to output them in |
643 |
DRI format. This will also reduce a lot of headaches. */ |
644 |
if ((type & N_STAB) != 0) |
645 |
skip = TRUE; |
646 |
|
647 |
switch (strip) |
648 |
{ |
649 |
case strip_none: |
650 |
case strip_debugger: |
651 |
break; |
652 |
case strip_some: |
653 |
if (bfd_hash_lookup (info->keep_hash, name, FALSE, FALSE) |
654 |
== NULL) |
655 |
skip = TRUE; |
656 |
break; |
657 |
case strip_all: |
658 |
skip = TRUE; |
659 |
break; |
660 |
} |
661 |
|
662 |
if (skip) |
663 |
{ |
664 |
if (h != NULL) |
665 |
mark_written (h); |
666 |
continue; |
667 |
} |
668 |
|
669 |
/* Get the value of the symbol. */ |
670 |
if ((type & N_TYPE) == N_TEXT |
671 |
|| type == N_WEAKT) |
672 |
symsec = obj_textsec (input_bfd); |
673 |
else if ((type & N_TYPE) == N_DATA |
674 |
|| type == N_WEAKD) |
675 |
symsec = obj_datasec (input_bfd); |
676 |
else if ((type & N_TYPE) == N_BSS |
677 |
|| type == N_WEAKB) |
678 |
symsec = obj_bsssec (input_bfd); |
679 |
else if ((type & N_TYPE) == N_ABS |
680 |
|| type == N_WEAKA) |
681 |
symsec = bfd_abs_section_ptr; |
682 |
else if (((type & N_TYPE) == N_INDR |
683 |
&& (hresolve == NULL |
684 |
|| (hresolve->root.type != bfd_link_hash_defined |
685 |
&& hresolve->root.type != bfd_link_hash_defweak |
686 |
&& hresolve->root.type != bfd_link_hash_common))) |
687 |
|| type == N_WARNING) |
688 |
{ |
689 |
/* Pass the next symbol through unchanged. The |
690 |
condition above for indirect symbols is so that if |
691 |
the indirect symbol was defined, we output it with |
692 |
the correct definition so the debugger will |
693 |
understand it. */ |
694 |
pass = TRUE; |
695 |
val = GET_WORD (input_bfd, sym->e_value); |
696 |
symsec = NULL; |
697 |
} |
698 |
else |
699 |
{ |
700 |
/* If we get here with an indirect symbol, it means that |
701 |
we are outputting it with a real definition. In such |
702 |
a case we do not want to output the next symbol, |
703 |
which is the target of the indirection. */ |
704 |
if ((type & N_TYPE) == N_INDR) |
705 |
skip_next = TRUE; |
706 |
|
707 |
symsec = NULL; |
708 |
|
709 |
/* We need to get the value from the hash table. We use |
710 |
hresolve so that if we have defined an indirect |
711 |
symbol we output the final definition. */ |
712 |
if (h == NULL) |
713 |
{ |
714 |
switch (type & N_TYPE) |
715 |
{ |
716 |
case N_SETT: |
717 |
symsec = obj_textsec (input_bfd); |
718 |
break; |
719 |
case N_SETD: |
720 |
symsec = obj_datasec (input_bfd); |
721 |
break; |
722 |
case N_SETB: |
723 |
symsec = obj_bsssec (input_bfd); |
724 |
break; |
725 |
case N_SETA: |
726 |
symsec = bfd_abs_section_ptr; |
727 |
break; |
728 |
default: |
729 |
val = 0; |
730 |
break; |
731 |
} |
732 |
} |
733 |
else if (hresolve->root.type == bfd_link_hash_defined |
734 |
|| hresolve->root.type == bfd_link_hash_defweak) |
735 |
{ |
736 |
asection *input_section; |
737 |
asection *output_section; |
738 |
|
739 |
/* This case usually means a common symbol which was |
740 |
turned into a defined symbol. */ |
741 |
input_section = hresolve->root.u.def.section; |
742 |
output_section = input_section->output_section; |
743 |
BFD_ASSERT (bfd_is_abs_section (output_section) |
744 |
|| output_section->owner == abfd); |
745 |
|
746 |
/* The following reference to the output section VMA |
747 |
is commented out because DRI symbols are relative |
748 |
to the beginning of the section. */ |
749 |
val = (hresolve->root.u.def.value |
750 |
/*+ bfd_get_section_vma (abfd, output_section)*/ |
751 |
+ input_section->output_offset); |
752 |
|
753 |
/* TEXT symbols values must be adjusted |
754 |
by adding the size of the extended header. */ |
755 |
if (output_section == obj_textsec (abfd)) |
756 |
val += TEXT_START_ADDR; |
757 |
|
758 |
/* Get the correct type based on the section. If |
759 |
this is a constructed set, force it to be |
760 |
globally visible. */ |
761 |
if (type == N_SETT |
762 |
|| type == N_SETD |
763 |
|| type == N_SETB |
764 |
|| type == N_SETA) |
765 |
type |= N_EXT; |
766 |
|
767 |
type &=~ N_TYPE; |
768 |
|
769 |
if (output_section == obj_textsec (abfd)) |
770 |
type |= N_TEXT; |
771 |
else if (output_section == obj_datasec (abfd)) |
772 |
type |= N_DATA; |
773 |
else if (output_section == obj_bsssec (abfd)) |
774 |
type |= N_BSS; |
775 |
else |
776 |
type |= N_ABS; |
777 |
} |
778 |
else if (hresolve->root.type == bfd_link_hash_common) |
779 |
val = hresolve->root.u.c.size; |
780 |
else if (hresolve->root.type == bfd_link_hash_undefweak) |
781 |
{ |
782 |
val = 0; |
783 |
type = N_UNDF; |
784 |
} |
785 |
else |
786 |
val = 0; |
787 |
} |
788 |
if (symsec != NULL) |
789 |
{ |
790 |
/* The following reference to the output section VMA |
791 |
is commented out because DRI symbols are relative |
792 |
to the beginning of the section. */ |
793 |
val = (/*symsec->output_section->vma |
794 |
+*/ symsec->output_offset |
795 |
+ (GET_WORD (input_bfd, sym->e_value) |
796 |
- symsec->vma)); |
797 |
|
798 |
/* TEXT symbols values must be adjusted |
799 |
by adding the size of the extended header. */ |
800 |
if (symsec == obj_textsec (input_bfd)) |
801 |
val += TEXT_START_ADDR; |
802 |
} |
803 |
|
804 |
/* If this is a global symbol set the written flag, and if |
805 |
it is a local symbol see if we should discard it. */ |
806 |
if (h != NULL) |
807 |
{ |
808 |
mark_written (h); |
809 |
} |
810 |
else if ((type & N_TYPE) != N_SETT |
811 |
&& (type & N_TYPE) != N_SETD |
812 |
&& (type & N_TYPE) != N_SETB |
813 |
&& (type & N_TYPE) != N_SETA) |
814 |
{ |
815 |
switch (discard) |
816 |
{ |
817 |
case discard_none: |
818 |
case discard_sec_merge: |
819 |
break; |
820 |
case discard_l: |
821 |
if (bfd_is_local_label_name (input_bfd, name)) |
822 |
skip = TRUE; |
823 |
break; |
824 |
default: |
825 |
case discard_all: |
826 |
skip = TRUE; |
827 |
break; |
828 |
} |
829 |
if (skip) |
830 |
{ |
831 |
pass = FALSE; |
832 |
continue; |
833 |
} |
834 |
} |
835 |
} |
836 |
|
837 |
/* Now find the nearest type in DRI format. */ |
838 |
switch (type) |
839 |
{ |
840 |
case N_ABS: |
841 |
case N_ABS | N_EXT: |
842 |
case N_SETA: |
843 |
case N_SETA | N_EXT: |
844 |
case N_WEAKA: |
845 |
a_type = A_EQU | A_DEF | A_GLOBL; |
846 |
break; |
847 |
case N_TEXT: |
848 |
case N_TEXT | N_EXT: |
849 |
case N_SETT: |
850 |
case N_SETT | N_EXT: |
851 |
case N_WEAKT: |
852 |
a_type = A_TEXT | A_DEF | A_GLOBL; |
853 |
break; |
854 |
case N_DATA: |
855 |
case N_DATA | N_EXT: |
856 |
case N_SETD: |
857 |
case N_SETD | N_EXT: |
858 |
case N_WEAKD: |
859 |
a_type = A_DATA | A_DEF | A_GLOBL; |
860 |
break; |
861 |
case N_BSS: |
862 |
case N_BSS | N_EXT: |
863 |
case N_SETB: |
864 |
case N_SETB | N_EXT: |
865 |
case N_WEAKB: |
866 |
a_type = A_BSS | A_DEF | A_GLOBL; |
867 |
break; |
868 |
default: |
869 |
continue; |
870 |
} |
871 |
|
872 |
written_bytes = write_dri_symbol (abfd, name, a_type, val); |
873 |
if (written_bytes < 0) |
874 |
return FALSE; |
875 |
|
876 |
myinfo->dri_symtab_size += written_bytes; |
877 |
} |
878 |
} |
879 |
|
880 |
obj_aout_external_string_size (abfd) = 0; |
881 |
return TRUE; |
882 |
} |
883 |
|
884 |
/* This is used for qsort() to sort addresses |
885 |
for the TPA relocation table. */ |
886 |
|
887 |
static int |
888 |
vma_cmp (const void *v1, const void *v2) |
889 |
{ |
890 |
return (int) ((*((bfd_vma *) v1)) - (*((bfd_vma *) v2))); |
891 |
} |
892 |
|
893 |
/* Alloc and fill the TPA relocation table. */ |
894 |
|
895 |
static bfd_boolean |
896 |
fill_tparel (bfd *abfd) |
897 |
{ |
898 |
struct mint_internal_info *myinfo = obj_aout_ext (abfd); |
899 |
unsigned long i; |
900 |
bfd_size_type bytes; |
901 |
unsigned char *ptr; |
902 |
|
903 |
/* Sort the relocation info. */ |
904 |
if (myinfo->relocs != NULL) |
905 |
qsort (myinfo->relocs, myinfo->relocs_used, sizeof (bfd_vma), |
906 |
vma_cmp); |
907 |
|
908 |
/* Now calculate the number of bytes we need. The relocation info |
909 |
is encoded as follows: The first entry is a 32-bit value |
910 |
denoting the first offset to relocate. All following entries |
911 |
are relative to the preceding one. For relative offsets of |
912 |
more than 254 bytes a value of 1 is used. The OS will then |
913 |
add 254 bytes to the current offset. The list is then terminated |
914 |
with the byte 0. */ |
915 |
bytes = 4; /* First entry is a long. */ |
916 |
for (i = 1; i < myinfo->relocs_used; i++) |
917 |
{ |
918 |
unsigned long diff = myinfo->relocs[i] - myinfo->relocs[i - 1]; |
919 |
BFD_ASSERT(diff > 0); |
920 |
bytes += (diff + 253) / 254; |
921 |
} |
922 |
/* Last entry is (bfd_byte) 0 if there are some relocations. */ |
923 |
if (myinfo->relocs_used > 0) |
924 |
bytes++; |
925 |
|
926 |
myinfo->tparel_size = bytes; |
927 |
myinfo->tparel = bfd_alloc (abfd, bytes); |
928 |
if (myinfo->tparel == NULL) |
929 |
return FALSE; |
930 |
|
931 |
/* Now fill the array. */ |
932 |
ptr = (bfd_byte*) myinfo->tparel; |
933 |
if (myinfo->relocs != NULL) |
934 |
bfd_put_32 (abfd, myinfo->relocs[0], ptr); |
935 |
else |
936 |
bfd_put_32 (abfd, 0, ptr); |
937 |
ptr += 4; |
938 |
|
939 |
for (i = 1; i < myinfo->relocs_used; i++) |
940 |
{ |
941 |
unsigned long diff = myinfo->relocs[i] - myinfo->relocs[i - 1]; |
942 |
while (diff > 254) |
943 |
{ |
944 |
*ptr++ = 1; |
945 |
diff -= 254; |
946 |
} |
947 |
*ptr++ = (bfd_byte) diff; |
948 |
} |
949 |
|
950 |
if (myinfo->relocs_used > 0) |
951 |
*ptr = 0; |
952 |
|
953 |
return TRUE; |
954 |
} |
955 |
|
956 |
/* Final link routine. We need to use a call back to get the correct |
957 |
offsets in the output file. And we need to malloc some internal |
958 |
buffers. */ |
959 |
|
960 |
#define MY_bfd_final_link m68kmint_prg_bfd_final_link |
961 |
|
962 |
static bfd_boolean |
963 |
m68kmint_prg_bfd_final_link (bfd *abfd, struct bfd_link_info *info) |
964 |
{ |
965 |
struct mint_internal_info *myinfo = obj_aout_ext (abfd); |
966 |
struct bfd_link_hash_table *hash = info->hash; |
967 |
enum bfd_link_strip original_strip = info->strip; |
968 |
|
969 |
if (info->relocatable) |
970 |
{ |
971 |
_bfd_error_handler ("%B: relocatable output is not supported by format %s", |
972 |
abfd, bfd_get_target (abfd)); |
973 |
bfd_set_error (bfd_error_invalid_operation); |
974 |
return FALSE; |
975 |
} |
976 |
|
977 |
myinfo->linkinfo = info; |
978 |
|
979 |
/* Make sure that for now we never write zmagics. */ |
980 |
abfd->flags &= ~D_PAGED; |
981 |
|
982 |
/* Find the __stksize symbol. This symbol is used for a MiNT |
983 |
special kludge. The libc defines this symbol in an object file |
984 |
initialized to a default value to make sure it is defined in |
985 |
every output file. The start-up code in crtinit() then simply |
986 |
sets the stacksize accordingly. In your programs (if they need |
987 |
an unusual stacksize) you can then simply code: |
988 |
|
989 |
long _stksize = 0x2000; |
990 |
|
991 |
This will create a program stack of 2k. Since MiNT cannot detect |
992 |
a stack overflow this is the only way to prevent program crashes |
993 |
caused by a stack that is too small. |
994 |
|
995 |
The ancient linker ignored this feature, the ancient strip |
996 |
program paid heed to it. By default, strip never stripped this |
997 |
special symbol from the binary. |
998 |
|
999 |
Another program called ``printstk'' and its colleague ``fixstk'' |
1000 |
could be used to either print the current value of the stacksize |
1001 |
or to modify it without recompiling and rebuilding. These |
1002 |
programs traversed the symbol table and then took the appropriate |
1003 |
measures if the symbol was found. |
1004 |
|
1005 |
Here we do a different approach. Since we already expanded the |
1006 |
standard executable header we now hardcode the address (as a file |
1007 |
offset) that the __stksize symbol points to into the header. We |
1008 |
can now let strip safely remove the entry from the symbol table |
1009 |
and we're not dependent on a special format of the symbol table. |
1010 |
Because the address is kept in the header we will always be able |
1011 |
to manipulate the stacksize value later. */ |
1012 |
if (hash != NULL) |
1013 |
{ |
1014 |
struct aout_link_hash_entry *h = |
1015 |
aout_link_hash_lookup (aout_hash_table (info), "__stksize", |
1016 |
FALSE, FALSE, FALSE); |
1017 |
asection *sec; |
1018 |
|
1019 |
if (h != NULL) |
1020 |
{ |
1021 |
switch (h->root.type) |
1022 |
{ |
1023 |
case bfd_link_hash_defined: |
1024 |
case bfd_link_hash_defweak: |
1025 |
sec = h->root.u.def.section->output_section; |
1026 |
BFD_ASSERT (sec->owner == abfd); |
1027 |
|
1028 |
myinfo->stkpos = (h->root.u.def.value + sec->vma |
1029 |
+ h->root.u.def.section->output_offset |
1030 |
+ GEMDOS_HEADER_SIZE); |
1031 |
break; |
1032 |
default: /* Ignore other types. */ |
1033 |
break; |
1034 |
} |
1035 |
} |
1036 |
} |
1037 |
|
1038 |
if ((abfd->flags & BFD_TRADITIONAL_FORMAT) != 0) |
1039 |
{ |
1040 |
myinfo->traditional_format = TRUE; |
1041 |
myinfo->symbol_format = _MINT_SYMBOL_FORMAT_DRI; |
1042 |
} |
1043 |
|
1044 |
/* Unconditionally unset the traditional flag. The only effect in |
1045 |
the a.out code is to disable string hashing (with respect to |
1046 |
SunOS gdx). This is not necessary for us. */ |
1047 |
|
1048 |
abfd->flags &= ~BFD_TRADITIONAL_FORMAT; |
1049 |
|
1050 |
/* Do not write GNU symbols in traditional format. */ |
1051 |
if (myinfo->traditional_format) |
1052 |
info->strip = strip_all; |
1053 |
|
1054 |
if (NAME(aout,final_link) (abfd, info, MY_final_link_callback) |
1055 |
!= TRUE) |
1056 |
return FALSE; |
1057 |
|
1058 |
if (myinfo->reloc_error) |
1059 |
return FALSE; |
1060 |
|
1061 |
/* Restore the strip status for the traditional symbols. */ |
1062 |
info->strip = original_strip; |
1063 |
|
1064 |
if (myinfo->traditional_format |
1065 |
&& link_write_traditional_syms (abfd, info) != TRUE) |
1066 |
return FALSE; |
1067 |
|
1068 |
if (fill_tparel (abfd) != TRUE) |
1069 |
return FALSE; |
1070 |
|
1071 |
return TRUE; |
1072 |
} |
1073 |
|
1074 |
/* Copy private BFD header information from the input BFD. */ |
1075 |
|
1076 |
#define MY_bfd_copy_private_header_data m68kmint_prg_bfd_copy_private_header_data |
1077 |
|
1078 |
static bfd_boolean |
1079 |
m68kmint_prg_bfd_copy_private_header_data (bfd *ibfd, bfd *obfd) |
1080 |
{ |
1081 |
(void)obfd; /* Unused. */ |
1082 |
|
1083 |
/* We can only copy BFD files using our own file format. */ |
1084 |
if (ibfd->xvec != &m68kmint_prg_vec) |
1085 |
{ |
1086 |
_bfd_error_handler ("%B: cannot convert from format %s to format %s", |
1087 |
ibfd, bfd_get_target (ibfd), bfd_get_target (obfd)); |
1088 |
bfd_set_error (bfd_error_invalid_operation); |
1089 |
return FALSE; |
1090 |
} |
1091 |
|
1092 |
return TRUE; |
1093 |
} |
1094 |
|
1095 |
/* Copy backend specific data from one object module to another. |
1096 |
This function is used by objcopy and strip. */ |
1097 |
|
1098 |
#define MY_bfd_copy_private_bfd_data m68kmint_prg_bfd_copy_private_bfd_data |
1099 |
|
1100 |
static bfd_boolean |
1101 |
m68kmint_prg_bfd_copy_private_bfd_data (bfd *ibfd, bfd *obfd) |
1102 |
{ |
1103 |
struct mint_internal_info *myinfo_in; |
1104 |
struct mint_internal_info *myinfo_out; |
1105 |
|
1106 |
/* obfd uses our file format, ibfd may be foreign. */ |
1107 |
if (ibfd->xvec != &m68kmint_prg_vec) |
1108 |
return TRUE; |
1109 |
|
1110 |
myinfo_in = obj_aout_ext (ibfd); |
1111 |
BFD_ASSERT (myinfo_in != NULL); |
1112 |
|
1113 |
myinfo_out = obj_aout_ext (obfd); |
1114 |
BFD_ASSERT (myinfo_out != NULL); |
1115 |
|
1116 |
/* Copy myinfo. */ |
1117 |
memcpy (myinfo_out, myinfo_in, sizeof (*myinfo_out)); |
1118 |
|
1119 |
/* Copy tparel. */ |
1120 |
myinfo_out->tparel = bfd_alloc (obfd, myinfo_out->tparel_size); |
1121 |
if (myinfo_out->tparel == NULL) |
1122 |
return FALSE; |
1123 |
memcpy (myinfo_out->tparel, myinfo_in->tparel, myinfo_out->tparel_size); |
1124 |
|
1125 |
/* Normalize the type of empty symbols. */ |
1126 |
if (bfd_get_symcount (obfd) == 0) |
1127 |
myinfo_out->symbol_format = _MINT_SYMBOL_FORMAT_GNU; |
1128 |
|
1129 |
return TRUE; /* _bfd_generic_bfd_copy_private_bfd_data (ibfd, obfd); */ |
1130 |
} |
1131 |
|
1132 |
/* Merge private BFD information from an input BFD to the output BFD when linking. */ |
1133 |
|
1134 |
#define MY_bfd_merge_private_bfd_data m68kmint_prg_merge_private_bfd_data |
1135 |
|
1136 |
static bfd_boolean |
1137 |
m68kmint_prg_merge_private_bfd_data (bfd *ibfd, bfd *obfd) |
1138 |
{ |
1139 |
(void)obfd; /* Unused. */ |
1140 |
|
1141 |
/* Our file format cannot be used as linker input. */ |
1142 |
if (ibfd->xvec == &m68kmint_prg_vec) |
1143 |
{ |
1144 |
_bfd_error_handler ("%B: file format %s cannot be used as linker input", |
1145 |
ibfd, bfd_get_target (ibfd)); |
1146 |
bfd_set_error (bfd_error_invalid_operation); |
1147 |
return FALSE; |
1148 |
} |
1149 |
|
1150 |
return TRUE; /* _bfd_generic_bfd_merge_private_bfd_data (ibfd, obfd); */ |
1151 |
} |
1152 |
|
1153 |
/* Find out the symbol name. */ |
1154 |
|
1155 |
static const char * |
1156 |
find_symbol_name (reloc_howto_type *howto, bfd *input_bfd, |
1157 |
bfd_byte *location, struct reloc_std_external *rel) |
1158 |
{ |
1159 |
struct external_nlist *syms = obj_aout_external_syms (input_bfd); |
1160 |
char *strings = obj_aout_external_strings (input_bfd); |
1161 |
struct aout_link_hash_entry **sym_hashes |
1162 |
= obj_aout_sym_hashes (input_bfd); |
1163 |
struct aout_link_hash_entry *h = NULL; |
1164 |
const char *name; |
1165 |
bfd_size_type r_index; |
1166 |
int r_extern; |
1167 |
|
1168 |
if (bfd_get_reloc_size (howto) != 4) |
1169 |
return "(not a symbol)"; |
1170 |
|
1171 |
/* The input bfd is always big-endian. There is no need to |
1172 |
call bfd_header_big_endian (input_bfd). */ |
1173 |
r_index = ((rel->r_index[0] << 16) |
1174 |
| (rel->r_index[1] << 8) |
1175 |
| (rel->r_index[2])); |
1176 |
r_extern = (0 != (rel->r_type[0] & RELOC_STD_BITS_EXTERN_BIG)); |
1177 |
|
1178 |
if (sym_hashes != NULL) |
1179 |
h = sym_hashes[r_index]; |
1180 |
|
1181 |
if (!r_extern) |
1182 |
{ |
1183 |
bfd_size_type i; |
1184 |
bfd_vma wanted_value = bfd_get_32 (input_bfd, location); |
1185 |
|
1186 |
name = NULL; |
1187 |
for (i = 0; i < obj_aout_external_sym_count (input_bfd); i++) |
1188 |
{ |
1189 |
bfd_vma this_value = bfd_get_32 (input_bfd, syms[i].e_value); |
1190 |
|
1191 |
if (this_value == wanted_value) |
1192 |
{ |
1193 |
bfd_byte symtype = bfd_get_8 (input_bfd, syms[i].e_type); |
1194 |
|
1195 |
/* Skip debug symbols and the like. */ |
1196 |
if ((symtype & N_STAB) != 0) |
1197 |
continue; |
1198 |
|
1199 |
/* This is dirty but preferable to a plethoria of |
1200 |
single comparisons. */ |
1201 |
if (symtype <= (N_BSS | N_EXT) |
1202 |
|| (symtype >= N_WEAKU && symtype <= N_COMM)) |
1203 |
{ |
1204 |
name = strings + GET_WORD (input_bfd, syms[i].e_strx); |
1205 |
break; |
1206 |
} |
1207 |
} |
1208 |
} |
1209 |
|
1210 |
/* FIXME: If the relocation is against a section there is |
1211 |
probably a symbol for that section floating around somewhere |
1212 |
in the bfd jungle. */ |
1213 |
if (name == NULL) |
1214 |
{ |
1215 |
switch ((r_index & N_TYPE) & ~N_EXT) |
1216 |
{ |
1217 |
case N_TEXT: |
1218 |
name = "text section"; |
1219 |
break; |
1220 |
case N_DATA: |
1221 |
name = "data section"; |
1222 |
break; |
1223 |
case N_BSS: |
1224 |
name = "bss section"; |
1225 |
break; |
1226 |
case N_ABS: |
1227 |
name = "absolute section"; |
1228 |
break; |
1229 |
default: |
1230 |
name = "unknown section"; |
1231 |
break; |
1232 |
} |
1233 |
} |
1234 |
} |
1235 |
else if (h != NULL) |
1236 |
name = h->root.root.string; |
1237 |
else if (r_index >= obj_aout_external_sym_count (input_bfd)) |
1238 |
name = "(unknown symbol)"; /* Shouldn't happen. */ |
1239 |
else |
1240 |
name = strings + GET_WORD (input_bfd, syms[r_index].e_strx); |
1241 |
|
1242 |
return name; |
1243 |
} |
1244 |
|
1245 |
/* This relocation routine is used by some of the backend linkers. |
1246 |
They do not construct asymbol or arelent structures, so there is no |
1247 |
reason for them to use bfd_perform_relocation. Also, |
1248 |
bfd_perform_relocation is so hacked up it is easier to write a new |
1249 |
function than to try to deal with it. |
1250 |
|
1251 |
This routine does a final relocation. Whether it is useful for a |
1252 |
relocatable link depends upon how the object format defines |
1253 |
relocations. |
1254 |
|
1255 |
FIXME: This routine ignores any special_function in the HOWTO, |
1256 |
since the existing special_function values have been written for |
1257 |
bfd_perform_relocation. |
1258 |
|
1259 |
HOWTO is the reloc howto information. |
1260 |
INPUT_BFD is the BFD which the reloc applies to. |
1261 |
INPUT_SECTION is the section which the reloc applies to. |
1262 |
CONTENTS is the contents of the section. |
1263 |
ADDRESS is the address of the reloc within INPUT_SECTION. |
1264 |
VALUE is the value of the symbol the reloc refers to. |
1265 |
ADDEND is the addend of the reloc. */ |
1266 |
|
1267 |
/* The additional parameter REL is specific to this backend. |
1268 |
This function is derived from _bfd_final_link_relocate() |
1269 |
found in reloc.c. It adds additional checking for dangerous |
1270 |
relocations in MiNT sharable text sections, then it records |
1271 |
the relocated offset in myinfo->relocs[] for further processing. */ |
1272 |
|
1273 |
static bfd_reloc_status_type |
1274 |
m68kmint_prg_final_link_relocate_rel (reloc_howto_type *howto, |
1275 |
bfd *input_bfd, |
1276 |
asection *input_section, |
1277 |
bfd_byte *contents, |
1278 |
bfd_vma address, |
1279 |
bfd_vma value, |
1280 |
bfd_vma addend, |
1281 |
struct reloc_std_external *rel) |
1282 |
{ |
1283 |
bfd_vma relocation; |
1284 |
bfd *output_bfd = input_section->output_section->owner; |
1285 |
struct mint_internal_info *myinfo = obj_aout_ext (output_bfd); |
1286 |
bfd_reloc_status_type retval; |
1287 |
int r_index; |
1288 |
int r_extern; |
1289 |
bfd_boolean need_tpa_relocation; |
1290 |
|
1291 |
/* The input bfd is always big-endian. There is no need to |
1292 |
call bfd_header_big_endian (input_bfd). */ |
1293 |
r_index = ((rel->r_index[0] << 16) |
1294 |
| (rel->r_index[1] << 8) |
1295 |
| (rel->r_index[2])); |
1296 |
r_extern = (0 != (rel->r_type[0] & RELOC_STD_BITS_EXTERN_BIG)); |
1297 |
|
1298 |
#define _MINT_F_SHTEXT 0x800 |
1299 |
|
1300 |
/* Sanity check the address. */ |
1301 |
if (address > bfd_get_section_limit (input_bfd, input_section)) |
1302 |
return bfd_reloc_outofrange; |
1303 |
|
1304 |
/* This function assumes that we are dealing with a basic relocation |
1305 |
against a symbol. We want to compute the value of the symbol to |
1306 |
relocate to. This is just VALUE, the value of the symbol, plus |
1307 |
ADDEND, any addend associated with the reloc. */ |
1308 |
relocation = value + addend; |
1309 |
|
1310 |
/* Check for dangerous relocations in images with a sharable |
1311 |
text section. */ |
1312 |
if ((myinfo->prg_flags & _MINT_F_SHTEXT) != 0 |
1313 |
&& bfd_get_reloc_size (howto) == 4) |
1314 |
{ |
1315 |
bfd_boolean error_found = FALSE; |
1316 |
const char *name = NULL; |
1317 |
|
1318 |
if (input_section == obj_textsec (input_bfd)) |
1319 |
{ |
1320 |
if (!r_extern) |
1321 |
{ |
1322 |
/* This is a relocation against another section. Only |
1323 |
relocations against the text section are allowed. */ |
1324 |
if (r_index != N_TEXT && r_index != (N_TEXT | N_EXT)) |
1325 |
error_found = TRUE; |
1326 |
} |
1327 |
else if (relocation > (input_section->output_section->vma |
1328 |
+ input_section->output_section->size)) |
1329 |
{ |
1330 |
error_found = TRUE; |
1331 |
} |
1332 |
else if (relocation == (input_section->output_section->vma |
1333 |
+ input_section->output_section->size)) |
1334 |
{ |
1335 |
name = find_symbol_name (howto, input_bfd, |
1336 |
contents + address, |
1337 |
rel); |
1338 |
if (strcmp (name, "_etext") == 0) |
1339 |
error_found = FALSE; |
1340 |
} |
1341 |
} |
1342 |
|
1343 |
if (error_found) |
1344 |
{ |
1345 |
const struct bfd_link_callbacks *callbacks |
1346 |
= myinfo->linkinfo->callbacks; |
1347 |
|
1348 |
myinfo->reloc_error = TRUE; |
1349 |
|
1350 |
if (callbacks->reloc_dangerous != NULL) |
1351 |
{ |
1352 |
if (name == NULL) |
1353 |
name = find_symbol_name (howto, input_bfd, |
1354 |
contents + address, |
1355 |
rel); |
1356 |
|
1357 |
callbacks->reloc_dangerous (myinfo->linkinfo, name, |
1358 |
input_bfd, |
1359 |
input_section, address); |
1360 |
} |
1361 |
} |
1362 |
} |
1363 |
|
1364 |
/* If the relocation is PC relative, we want to set RELOCATION to |
1365 |
the distance between the symbol (currently in RELOCATION) and the |
1366 |
location we are relocating. Some targets (e.g., i386-aout) |
1367 |
arrange for the contents of the section to be the negative of the |
1368 |
offset of the location within the section; for such targets |
1369 |
pcrel_offset is FALSE. Other targets (e.g., m88kbcs or ELF) |
1370 |
simply leave the contents of the section as zero; for such |
1371 |
targets pcrel_offset is TRUE. If pcrel_offset is FALSE we do not |
1372 |
need to subtract out the offset of the location within the |
1373 |
section (which is just ADDRESS). */ |
1374 |
if (howto->pc_relative) |
1375 |
{ |
1376 |
relocation -= (input_section->output_section->vma |
1377 |
+ input_section->output_offset); |
1378 |
if (howto->pcrel_offset) |
1379 |
relocation -= address; |
1380 |
} |
1381 |
|
1382 |
retval = _bfd_relocate_contents (howto, input_bfd, relocation, |
1383 |
contents + address); |
1384 |
|
1385 |
/* The symbol has to be relocated again iff the length of the relocation |
1386 |
is 2 words and it is not pc relative. */ |
1387 |
need_tpa_relocation = FALSE; |
1388 |
if (!howto->pc_relative && bfd_get_reloc_size (howto) == 4) |
1389 |
{ |
1390 |
if (r_extern) |
1391 |
{ |
1392 |
struct aout_link_hash_entry **sym_hashes = obj_aout_sym_hashes (input_bfd); |
1393 |
struct aout_link_hash_entry *h = sym_hashes[r_index]; |
1394 |
asection *output_section = h->root.u.def.section->output_section; |
1395 |
|
1396 |
/* Do not relocate absolute symbols. */ |
1397 |
if (output_section == obj_textsec (output_bfd) |
1398 |
|| output_section == obj_datasec (output_bfd) |
1399 |
|| output_section == obj_bsssec (output_bfd)) |
1400 |
{ |
1401 |
need_tpa_relocation = TRUE; |
1402 |
} |
1403 |
} |
1404 |
else |
1405 |
{ |
1406 |
need_tpa_relocation = TRUE; |
1407 |
} |
1408 |
} |
1409 |
|
1410 |
/* Here we add the TPA relocation entries for the address references |
1411 |
located inside the input sections. Note that if some references |
1412 |
to addresses are generated using data statements in the linker |
1413 |
script, they will not be relocated here because they do not |
1414 |
belong to any input section. */ |
1415 |
if (need_tpa_relocation) |
1416 |
{ |
1417 |
bfd_vma tpa_address = input_section->output_section->vma |
1418 |
+ input_section->output_offset + address; |
1419 |
|
1420 |
if (!bfd_m68kmint_add_tpa_relocation_entry(output_bfd, tpa_address)) |
1421 |
return bfd_reloc_other; |
1422 |
} |
1423 |
|
1424 |
return retval; |
1425 |
} |
1426 |
|
1427 |
/* Write out the TPA relocation table. */ |
1428 |
|
1429 |
static bfd_boolean |
1430 |
write_tparel (bfd *abfd, struct internal_exec *execp) |
1431 |
{ |
1432 |
struct mint_internal_info* myinfo = obj_aout_ext (abfd); |
1433 |
|
1434 |
if (myinfo->dri_symtab_size == 0) |
1435 |
myinfo->tparel_pos = N_STROFF (*execp) |
1436 |
+ obj_aout_external_string_size (abfd); |
1437 |
else |
1438 |
myinfo->tparel_pos = N_SYMOFF (*execp) |
1439 |
+ myinfo->dri_symtab_size; |
1440 |
|
1441 |
if (bfd_seek (abfd, myinfo->tparel_pos, SEEK_SET) != 0) |
1442 |
return FALSE; |
1443 |
|
1444 |
if (bfd_bwrite (myinfo->tparel, myinfo->tparel_size, abfd) |
1445 |
!= myinfo->tparel_size) |
1446 |
return FALSE; |
1447 |
|
1448 |
return TRUE; |
1449 |
} |
1450 |
|
1451 |
/* Write the full exec header. |
1452 |
This function must be called last to ensure that we have all the |
1453 |
information needed to fill the MiNT-specific header fields. */ |
1454 |
|
1455 |
static bfd_boolean |
1456 |
write_exec_header (bfd *abfd, struct internal_exec *execp, struct external_exec *exec_bytes) |
1457 |
{ |
1458 |
struct mint_internal_info *myinfo = obj_aout_ext (abfd); |
1459 |
bfd_size_type symtab_size; |
1460 |
|
1461 |
bfd_h_put_16 (abfd, 0x601a, exec_bytes->g_branch); |
1462 |
|
1463 |
/* The OS will load our extension header fields into the text segment. */ |
1464 |
bfd_h_put_32 (abfd, execp->a_text + (EXEC_BYTES_SIZE - GEMDOS_HEADER_SIZE), |
1465 |
exec_bytes->g_text); |
1466 |
bfd_h_put_32 (abfd, execp->a_data, exec_bytes->g_data); |
1467 |
bfd_h_put_32 (abfd, execp->a_bss, exec_bytes->g_bss); |
1468 |
|
1469 |
/* The OS' notion of the size of the symbol table is another than |
1470 |
the bfd library's. We have to fill in the size of the table |
1471 |
itself plus the size of the string table but only if we have not written |
1472 |
a traditional symbol table. If we have written a traditional symbol |
1473 |
table we know the size. */ |
1474 |
if (myinfo->dri_symtab_size != 0) |
1475 |
symtab_size = myinfo->dri_symtab_size; |
1476 |
else |
1477 |
symtab_size = myinfo->tparel_pos - N_SYMOFF (*execp); |
1478 |
|
1479 |
bfd_h_put_32 (abfd, symtab_size, exec_bytes->g_syms); |
1480 |
|
1481 |
bfd_h_put_32 (abfd, 0x4d694e54, exec_bytes->g_extmagic); |
1482 |
bfd_h_put_32 (abfd, myinfo->prg_flags, exec_bytes->g_flags); |
1483 |
bfd_h_put_16 (abfd, 0, exec_bytes->g_abs); |
1484 |
|
1485 |
/* Generate the jump instruction to the entry point. In m68k |
1486 |
assembler mnemnonics it looks more or less like this: |
1487 |
|
1488 |
move.l exec_bytes->e_entry(pc),d0 |
1489 |
jmp -6(pc,d0.l) |
1490 |
|
1491 |
Sorry for the wrong syntax. As a real assembler addict I |
1492 |
never actually use an assembler. I edit my binaries manually |
1493 |
with a hex editor, looks much cooler and it strengthens your |
1494 |
abstraction abilities. */ |
1495 |
|
1496 |
exec_bytes->g_jump_entry[0] = 0x20; |
1497 |
exec_bytes->g_jump_entry[1] = 0x3a; |
1498 |
exec_bytes->g_jump_entry[2] = 0x00; |
1499 |
exec_bytes->g_jump_entry[3] = 0x1a; |
1500 |
exec_bytes->g_jump_entry[4] = 0x4e; |
1501 |
exec_bytes->g_jump_entry[5] = 0xfb; |
1502 |
exec_bytes->g_jump_entry[6] = 0x08; |
1503 |
exec_bytes->g_jump_entry[7] = 0xfa; |
1504 |
|
1505 |
bfd_h_put_32 (abfd, myinfo->tparel_pos, exec_bytes->g_tparel_pos); |
1506 |
bfd_h_put_32 (abfd, myinfo->tparel_size, exec_bytes->g_tparel_size); |
1507 |
bfd_h_put_32 (abfd, myinfo->stkpos, exec_bytes->g_stkpos); |
1508 |
|
1509 |
/* If there are no symbols, pretend they are in GNU format. */ |
1510 |
if (symtab_size == 0) |
1511 |
myinfo->symbol_format = _MINT_SYMBOL_FORMAT_GNU; |
1512 |
|
1513 |
bfd_h_put_32 (abfd, myinfo->symbol_format, exec_bytes->g_symbol_format); |
1514 |
|
1515 |
memset (&exec_bytes->g_pad0, 0, sizeof (exec_bytes->g_pad0)); |
1516 |
|
1517 |
/* The standard stuff. */ |
1518 |
NAME(aout, swap_exec_header_out) (abfd, execp, exec_bytes); |
1519 |
if (myinfo->symbol_format != _MINT_SYMBOL_FORMAT_GNU) |
1520 |
PUT_WORD (abfd, 0, exec_bytes->e_syms); |
1521 |
|
1522 |
if (bfd_seek (abfd, (file_ptr) 0, SEEK_SET) != 0) |
1523 |
return FALSE; |
1524 |
|
1525 |
if (bfd_bwrite (exec_bytes, (bfd_size_type) EXEC_BYTES_SIZE, abfd) |
1526 |
!= EXEC_BYTES_SIZE) |
1527 |
return FALSE; |
1528 |
|
1529 |
/* Override the stack size. */ |
1530 |
if (myinfo->override_stack_size && myinfo->stkpos) |
1531 |
{ |
1532 |
bfd_byte big_endian_stack_size[4]; |
1533 |
|
1534 |
bfd_put_32 (abfd, myinfo->stack_size, &big_endian_stack_size); |
1535 |
|
1536 |
if (bfd_seek (abfd, (file_ptr) myinfo->stkpos, SEEK_SET) != 0) |
1537 |
return FALSE; |
1538 |
|
1539 |
if (bfd_bwrite (big_endian_stack_size, 4, abfd) != 4) |
1540 |
return FALSE; |
1541 |
} |
1542 |
|
1543 |
return TRUE; |
1544 |
} |
1545 |
|
1546 |
/* Write an object file. |
1547 |
Section contents have already been written. We write the |
1548 |
file header, symbols, and relocation. */ |
1549 |
|
1550 |
#define MY_write_object_contents m68kmint_prg_write_object_contents |
1551 |
|
1552 |
static bfd_boolean |
1553 |
m68kmint_prg_write_object_contents (bfd *abfd) |
1554 |
{ |
1555 |
struct external_exec exec_bytes; |
1556 |
struct internal_exec *execp = exec_hdr (abfd); |
1557 |
bfd_size_type text_size; |
1558 |
file_ptr text_end; |
1559 |
|
1560 |
BFD_ASSERT (obj_aout_ext (abfd) != NULL); |
1561 |
|
1562 |
obj_reloc_entry_size (abfd) = RELOC_STD_SIZE; |
1563 |
|
1564 |
/* Most of the following code come from the WRITE_HEADERS macro |
1565 |
found in libaout.h. */ |
1566 |
|
1567 |
if (adata(abfd).magic == undecided_magic) |
1568 |
NAME (aout, adjust_sizes_and_vmas) (abfd, & text_size, & text_end); |
1569 |
|
1570 |
execp->a_syms = bfd_get_symcount (abfd) * EXTERNAL_NLIST_SIZE; |
1571 |
execp->a_entry = bfd_get_start_address (abfd); |
1572 |
|
1573 |
execp->a_trsize = ((obj_textsec (abfd)->reloc_count) * |
1574 |
obj_reloc_entry_size (abfd)); |
1575 |
execp->a_drsize = ((obj_datasec (abfd)->reloc_count) * |
1576 |
obj_reloc_entry_size (abfd)); |
1577 |
|
1578 |
/* Now write out reloc info, followed by syms and strings. */ |
1579 |
|
1580 |
if (bfd_get_outsymbols (abfd) != NULL |
1581 |
&& bfd_get_symcount (abfd) != 0) |
1582 |
{ |
1583 |
if (bfd_seek (abfd, (file_ptr) (N_SYMOFF(*execp)), SEEK_SET) != 0) |
1584 |
return FALSE; |
1585 |
|
1586 |
if (! NAME (aout, write_syms) (abfd)) |
1587 |
return FALSE; |
1588 |
} |
1589 |
|
1590 |
if (bfd_seek (abfd, (file_ptr) (N_TRELOFF (*execp)), SEEK_SET) != 0) |
1591 |
return FALSE; |
1592 |
if (!NAME (aout, squirt_out_relocs) (abfd, obj_textsec (abfd))) |
1593 |
return FALSE; |
1594 |
|
1595 |
if (bfd_seek (abfd, (file_ptr) (N_DRELOFF (*execp)), SEEK_SET) != 0) |
1596 |
return FALSE; |
1597 |
if (!NAME (aout, squirt_out_relocs) (abfd, obj_datasec (abfd))) |
1598 |
return FALSE; |
1599 |
|
1600 |
if (write_tparel (abfd, execp) != TRUE) |
1601 |
return FALSE; |
1602 |
|
1603 |
if (write_exec_header (abfd, execp, &exec_bytes) != TRUE) |
1604 |
return FALSE; |
1605 |
|
1606 |
return TRUE; |
1607 |
} |
1608 |
|
1609 |
/* Print private BFD data. Used by objdump -p. */ |
1610 |
|
1611 |
#define MY_bfd_print_private_bfd_data m68kmint_prg_print_private_bfd_data |
1612 |
|
1613 |
static bfd_boolean |
1614 |
m68kmint_prg_print_private_bfd_data (bfd *abfd, void *ptr) |
1615 |
{ |
1616 |
FILE *file = (FILE *) ptr; |
1617 |
struct mint_internal_info *myinfo = obj_aout_ext (abfd); |
1618 |
const char* symbol_format; |
1619 |
long stksize = 0; |
1620 |
|
1621 |
fprintf (file, "\n"); |
1622 |
|
1623 |
fprintf (file, " GEMDOS flags: 0x%08lx\n", (unsigned long) myinfo->prg_flags); |
1624 |
fprintf (file, "Start address: 0x%08lx\n", bfd_get_start_address (abfd)); |
1625 |
|
1626 |
/* Stack size. */ |
1627 |
if (myinfo->stkpos != 0) |
1628 |
{ |
1629 |
if (bfd_seek (abfd, myinfo->stkpos, SEEK_SET) != 0 |
1630 |
|| (bfd_bread (&stksize, sizeof(long), abfd) != sizeof(long))) |
1631 |
return FALSE; |
1632 |
|
1633 |
stksize = bfd_get_signed_32 (abfd, &stksize); |
1634 |
} |
1635 |
fprintf (file, " Stack size: %ld\n", stksize); |
1636 |
|
1637 |
/* Symbol format. */ |
1638 |
switch (myinfo->symbol_format) |
1639 |
{ |
1640 |
case _MINT_SYMBOL_FORMAT_GNU: symbol_format = "stabs"; break; |
1641 |
case _MINT_SYMBOL_FORMAT_DRI: symbol_format = "DRI"; break; |
1642 |
default: symbol_format = "?"; break; |
1643 |
} |
1644 |
fprintf (file, "Symbol format: %s\n", symbol_format); |
1645 |
|
1646 |
return TRUE; |
1647 |
} |
1648 |
|
1649 |
/* Special case for NAME (aout, get_section_contents) |
1650 |
It is not declared in libaout.h, neither implemented in aoutx.h. |
1651 |
Instead, a macro named aout_32_get_section_contents is defined in libaout.h. |
1652 |
So the default value of MY_get_section_contents provided by aout-target.h |
1653 |
is not correct, it has to be defined here with the right value. */ |
1654 |
|
1655 |
#define MY_get_section_contents aout_32_get_section_contents |
1656 |
|
1657 |
/* The following include will define m68kmint_prg_vec |
1658 |
and a default implementation for all the MY_ functions |
1659 |
not overriden here. */ |
1660 |
|
1661 |
#include "aout-target.h" |
1662 |
|
1663 |
/* Set the GEMDOS executable flags. |
1664 |
It is called by the linker emulation script. */ |
1665 |
|
1666 |
bfd_boolean |
1667 |
bfd_m68kmint_set_extended_flags (bfd *abfd, flagword prg_flags) |
1668 |
{ |
1669 |
struct mint_internal_info *myinfo; |
1670 |
|
1671 |
BFD_ASSERT(abfd->xvec == &m68kmint_prg_vec); |
1672 |
myinfo = obj_aout_ext (abfd); |
1673 |
BFD_ASSERT(myinfo != NULL); |
1674 |
|
1675 |
myinfo->prg_flags = prg_flags; |
1676 |
|
1677 |
return TRUE; |
1678 |
} |
1679 |
|
1680 |
/* Override the stack size. |
1681 |
It is called by the linker emulation script. */ |
1682 |
|
1683 |
bfd_boolean |
1684 |
bfd_m68kmint_set_stack_size (bfd *abfd, bfd_signed_vma stack_size) |
1685 |
{ |
1686 |
struct mint_internal_info *myinfo; |
1687 |
|
1688 |
BFD_ASSERT(abfd->xvec == &m68kmint_prg_vec); |
1689 |
myinfo = obj_aout_ext (abfd); |
1690 |
BFD_ASSERT(myinfo != NULL); |
1691 |
|
1692 |
myinfo->stack_size = stack_size; |
1693 |
myinfo->override_stack_size = TRUE; |
1694 |
|
1695 |
return TRUE; |
1696 |
} |
1697 |
|
1698 |
/* Add a TPA relocation entry. |
1699 |
It is called by BFD when linking the input sections, and by the |
1700 |
linker when it generates a reference to an address (in particular, |
1701 |
when building the constructors list). */ |
1702 |
|
1703 |
bfd_boolean |
1704 |
bfd_m68kmint_add_tpa_relocation_entry (bfd *abfd, bfd_vma address) |
1705 |
{ |
1706 |
struct mint_internal_info *myinfo; |
1707 |
|
1708 |
BFD_ASSERT(abfd->xvec == &m68kmint_prg_vec); |
1709 |
myinfo = obj_aout_ext (abfd); |
1710 |
BFD_ASSERT(myinfo != NULL); |
1711 |
|
1712 |
/* Enlarge the buffer if necessary. */ |
1713 |
if (myinfo->relocs_used * sizeof (bfd_vma) >= myinfo->relocs_allocated) |
1714 |
{ |
1715 |
bfd_vma *newbuf; |
1716 |
myinfo->relocs_allocated += MINT_RELOC_CHUNKSIZE; |
1717 |
newbuf = bfd_realloc (myinfo->relocs, myinfo->relocs_allocated); |
1718 |
if (newbuf == NULL) |
1719 |
return FALSE; |
1720 |
|
1721 |
myinfo->relocs = newbuf; |
1722 |
} |
1723 |
|
1724 |
/* The TPA relative relocation actually just adds the address of |
1725 |
the text segment (i. e. beginning of the executable in memory) |
1726 |
to the addresses at the specified locations. This allows an |
1727 |
executable to be loaded everywhere in the address space without |
1728 |
memory management. */ |
1729 |
myinfo->relocs[myinfo->relocs_used++] = address; |
1730 |
|
1731 |
return TRUE; |
1732 |
} |