1377e23a2Schristos /* BFD backend for CRIS a.out binaries.
2*1424dfb3Schristos Copyright (C) 2000-2020 Free Software Foundation, Inc.
3377e23a2Schristos Contributed by Axis Communications AB.
4377e23a2Schristos Written by Hans-Peter Nilsson.
5377e23a2Schristos
6377e23a2Schristos This file is part of BFD, the Binary File Descriptor library.
7377e23a2Schristos
8377e23a2Schristos This program is free software; you can redistribute it and/or modify
9377e23a2Schristos it under the terms of the GNU General Public License as published by
10377e23a2Schristos the Free Software Foundation; either version 3 of the License, or
11377e23a2Schristos (at your option) any later version.
12377e23a2Schristos
13377e23a2Schristos This program is distributed in the hope that it will be useful,
14377e23a2Schristos but WITHOUT ANY WARRANTY; without even the implied warranty of
15377e23a2Schristos MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
16377e23a2Schristos GNU General Public License for more details.
17377e23a2Schristos
18377e23a2Schristos You should have received a copy of the GNU General Public License
19377e23a2Schristos along with this program; if not, write to the Free Software
20377e23a2Schristos Foundation, Inc., 51 Franklin Street - Fifth Floor, Boston,
21377e23a2Schristos MA 02110-1301, USA. */
22377e23a2Schristos
23377e23a2Schristos /* See info in the file PORTING for documentation of these macros and
24377e23a2Schristos functions. Beware; some of the information there is outdated. */
25377e23a2Schristos
26377e23a2Schristos #define N_HEADER_IN_TEXT(x) 0
27377e23a2Schristos #define N_TXTOFF(x) 32
28377e23a2Schristos #define ENTRY_CAN_BE_ZERO
29377e23a2Schristos #define TEXT_START_ADDR 0
30377e23a2Schristos
31377e23a2Schristos /* Without reading symbols to get the text start symbol, there is no way
32377e23a2Schristos to know where the text segment starts in an a.out file. Defaulting to
33377e23a2Schristos anything as constant as TEXT_START_ADDR is bad. But we can guess from
34377e23a2Schristos the entry point, which is usually within the first 64k of the text
35377e23a2Schristos segment. We also assume here that the text segment is 64k-aligned.
36377e23a2Schristos FIXME: It is also wrong to assume that data and bss follow immediately
37377e23a2Schristos after text, but with those, we don't have any choice besides reading
38377e23a2Schristos symbol info, and luckily there's no pressing need for correctness for
39377e23a2Schristos those vma:s at this time. */
40c03b94e9Schristos #define N_TXTADDR(x) ((x)->a_entry & ~(bfd_vma) 0xffff)
41377e23a2Schristos
42377e23a2Schristos /* If you change this to 4, you can not link to an address N*4+2. */
43377e23a2Schristos #define SEGMENT_SIZE 2
44377e23a2Schristos
45377e23a2Schristos /* For some reason, if the a.out file has Z_MAGIC, then
46377e23a2Schristos adata(abfd).exec_bytes_size is not used, but rather
47377e23a2Schristos adata(abfd).zmagic_disk_block_size, even though the exec_header is
48377e23a2Schristos *not* included in the text segment. A simple workaround is to
49377e23a2Schristos #define ZMAGIC_DISK_BLOCK_SIZE, which is used if defined; otherwise
50377e23a2Schristos TARGET_PAGE_SIZE is used. */
51377e23a2Schristos #define ZMAGIC_DISK_BLOCK_SIZE N_TXTOFF (0)
52377e23a2Schristos
53377e23a2Schristos /* It seems odd at first to set a page-size this low, but gives greater
54377e23a2Schristos freedom in where things can be linked. The drawback is that you have
55377e23a2Schristos to set alignment and padding in linker scripts. */
56377e23a2Schristos #define TARGET_PAGE_SIZE SEGMENT_SIZE
57377e23a2Schristos #define TARGETNAME "a.out-cris"
58377e23a2Schristos
59377e23a2Schristos /* Do not "beautify" the CONCAT* macro args. Traditional C will not
60377e23a2Schristos remove whitespace added here, and thus will fail to concatenate
61377e23a2Schristos the tokens. */
62377e23a2Schristos #define MY(OP) CONCAT2 (cris_aout_,OP)
63377e23a2Schristos #define NAME(x, y) CONCAT3 (cris_aout,_32_,y)
64377e23a2Schristos
6548596154Schristos #include "sysdep.h"
66377e23a2Schristos #include "bfd.h"
67377e23a2Schristos
68377e23a2Schristos /* Version 1 of the header. */
69377e23a2Schristos #define MY_exec_hdr_flags 1
70377e23a2Schristos
71377e23a2Schristos #define MY_write_object_contents MY (write_object_contents)
72377e23a2Schristos static bfd_boolean MY (write_object_contents) (bfd *);
73377e23a2Schristos
74377e23a2Schristos /* Forward this, so we can use a pointer to it in PARAMS. */
75377e23a2Schristos struct reloc_ext_external;
76377e23a2Schristos
77377e23a2Schristos #define MY_swap_ext_reloc_out MY (swap_ext_reloc_out)
78377e23a2Schristos static void MY (swap_ext_reloc_out) (bfd *, arelent *, struct reloc_ext_external *);
79377e23a2Schristos
80377e23a2Schristos #define MY_swap_ext_reloc_in MY (swap_ext_reloc_in)
81377e23a2Schristos static void MY (swap_ext_reloc_in) (bfd *, struct reloc_ext_external *,
82377e23a2Schristos arelent *, asymbol **, bfd_size_type);
83377e23a2Schristos
84377e23a2Schristos #define MY_set_sizes MY (set_sizes)
85377e23a2Schristos static bfd_boolean MY (set_sizes) (bfd *);
86377e23a2Schristos
87377e23a2Schristos /* To set back reloc_size to ext, we make MY (set_sizes) be called
88377e23a2Schristos through this construct. Note that MY_set_arch_mach is only called
89377e23a2Schristos through SET_ARCH_MACH. The default bfd_default_set_arch_mach will
90377e23a2Schristos not call set_sizes. */
91377e23a2Schristos
92c03b94e9Schristos #define SET_ARCH_MACH(BFD, EXECP) \
93*1424dfb3Schristos bfd_set_arch_mach (BFD, bfd_arch_cris, N_MACHTYPE (EXECP))
94377e23a2Schristos
95377e23a2Schristos /* These macros describe the binary layout of the reloc information we
96377e23a2Schristos use in a file. */
97377e23a2Schristos #define RELOC_EXT_BITS_EXTERN_LITTLE 0x80
98377e23a2Schristos #define RELOC_EXT_BITS_TYPE_LITTLE 3
99377e23a2Schristos #define RELOC_EXT_BITS_TYPE_SH_LITTLE 0
100377e23a2Schristos
101377e23a2Schristos #ifndef MY_get_section_contents
102377e23a2Schristos #define MY_get_section_contents aout_32_get_section_contents
103377e23a2Schristos #endif
104377e23a2Schristos
105377e23a2Schristos #define MACHTYPE_OK(mtype) ((mtype) == M_CRIS)
106377e23a2Schristos
107377e23a2Schristos /* Include generic functions (some are overridden above). */
108377e23a2Schristos #include "aout32.c"
109377e23a2Schristos #include "aout-target.h"
110377e23a2Schristos
111377e23a2Schristos /* We need our own version to set header flags. */
112377e23a2Schristos
113377e23a2Schristos static bfd_boolean
MY(write_object_contents)114377e23a2Schristos MY (write_object_contents) (bfd *abfd)
115377e23a2Schristos {
116377e23a2Schristos struct external_exec exec_bytes;
117377e23a2Schristos struct internal_exec *execp = exec_hdr (abfd);
118377e23a2Schristos
119377e23a2Schristos /* We set the reloc type to RELOC_EXT_SIZE, although setting it at all
120377e23a2Schristos seems unnecessary when inspecting as and ld behavior (not an
121377e23a2Schristos exhaustive inspection). The default write_object_contents
122377e23a2Schristos definition sets RELOC_EXT_SIZE, so we follow suite and set it too. */
123377e23a2Schristos obj_reloc_entry_size (abfd) = RELOC_EXT_SIZE;
124377e23a2Schristos
125377e23a2Schristos /* Setting N_SET_MACHTYPE and using N_SET_FLAGS is not performed by
126377e23a2Schristos the default definition. */
127377e23a2Schristos if (bfd_get_arch (abfd) == bfd_arch_cris)
128c03b94e9Schristos N_SET_MACHTYPE (execp, M_CRIS);
129377e23a2Schristos
130c03b94e9Schristos N_SET_FLAGS (execp, aout_backend_info (abfd)->exec_hdr_flags);
131377e23a2Schristos
132377e23a2Schristos WRITE_HEADERS (abfd, execp);
133377e23a2Schristos
134377e23a2Schristos return TRUE;
135377e23a2Schristos }
136377e23a2Schristos
137377e23a2Schristos /* We need our own for these reasons:
138377e23a2Schristos - Assert that a normal 8, 16 or 32 reloc is output.
139377e23a2Schristos - Fix what seems to be a weak-bug (perhaps there for valid reasons). */
140377e23a2Schristos
141377e23a2Schristos static void
MY(swap_ext_reloc_out)142377e23a2Schristos MY (swap_ext_reloc_out) (bfd *abfd,
143377e23a2Schristos arelent *g,
144377e23a2Schristos struct reloc_ext_external *natptr)
145377e23a2Schristos {
146377e23a2Schristos int r_index;
147377e23a2Schristos int r_extern;
148377e23a2Schristos unsigned int r_type;
149377e23a2Schristos bfd_vma r_addend;
150377e23a2Schristos asymbol *sym = *(g->sym_ptr_ptr);
151377e23a2Schristos asection *output_section = sym->section->output_section;
152377e23a2Schristos
153377e23a2Schristos PUT_WORD (abfd, g->address, natptr->r_address);
154377e23a2Schristos
155377e23a2Schristos r_type = (unsigned int) g->howto->type;
156377e23a2Schristos
157377e23a2Schristos r_addend = g->addend;
158377e23a2Schristos if ((sym->flags & BSF_SECTION_SYM) != 0)
159377e23a2Schristos r_addend += (*(g->sym_ptr_ptr))->section->output_section->vma;
160377e23a2Schristos
161377e23a2Schristos /* If this relocation is relative to a symbol then set the
162377e23a2Schristos r_index to the symbols index, and the r_extern bit.
163377e23a2Schristos
164377e23a2Schristos Absolute symbols can come in in two ways, either as an offset
165377e23a2Schristos from the abs section, or as a symbol which has an abs value.
166377e23a2Schristos check for that here. */
167377e23a2Schristos
168*1424dfb3Schristos if (bfd_is_abs_section (bfd_asymbol_section (sym)))
169377e23a2Schristos {
170377e23a2Schristos r_extern = 0;
171377e23a2Schristos r_index = N_ABS;
172377e23a2Schristos }
173377e23a2Schristos else if ((sym->flags & BSF_SECTION_SYM) == 0)
174377e23a2Schristos {
175*1424dfb3Schristos if (bfd_is_und_section (bfd_asymbol_section (sym))
176377e23a2Schristos /* Remember to check for weak symbols; they count as global. */
177377e23a2Schristos || (sym->flags & (BSF_GLOBAL | BSF_WEAK)) != 0)
178377e23a2Schristos r_extern = 1;
179377e23a2Schristos else
180377e23a2Schristos r_extern = 0;
181377e23a2Schristos r_index = (*(g->sym_ptr_ptr))->KEEPIT;
182377e23a2Schristos }
183377e23a2Schristos else
184377e23a2Schristos {
185377e23a2Schristos /* Just an ordinary section. */
186377e23a2Schristos r_extern = 0;
187377e23a2Schristos r_index = output_section->target_index;
188377e23a2Schristos }
189377e23a2Schristos
190377e23a2Schristos /* The relocation type is the same as the canonical ones, but only
191377e23a2Schristos the first 3 are used: RELOC_8, RELOC_16, RELOC_32.
192377e23a2Schristos We may change this later, but assert this for the moment. */
193377e23a2Schristos if (r_type > 2)
194377e23a2Schristos {
1951c468f90Schristos /* xgettext:c-format */
19607163879Schristos _bfd_error_handler (_("%pB: unsupported relocation type exported: %#x"),
1971c468f90Schristos abfd, r_type);
198377e23a2Schristos
199377e23a2Schristos bfd_set_error (bfd_error_wrong_format);
200377e23a2Schristos }
201377e23a2Schristos
202377e23a2Schristos /* Now the fun stuff. */
203377e23a2Schristos natptr->r_index[2] = r_index >> 16;
204377e23a2Schristos natptr->r_index[1] = r_index >> 8;
205377e23a2Schristos natptr->r_index[0] = r_index;
206377e23a2Schristos natptr->r_type[0] =
207377e23a2Schristos (r_extern ? RELOC_EXT_BITS_EXTERN_LITTLE : 0)
208377e23a2Schristos | (r_type << RELOC_EXT_BITS_TYPE_SH_LITTLE);
209377e23a2Schristos
210377e23a2Schristos PUT_WORD (abfd, r_addend, natptr->r_addend);
211377e23a2Schristos }
212377e23a2Schristos
213377e23a2Schristos /* We need our own to assert that a normal 8, 16 or 32 reloc is input. */
214377e23a2Schristos
215377e23a2Schristos static void
MY(swap_ext_reloc_in)216377e23a2Schristos MY (swap_ext_reloc_in) (bfd *abfd,
217377e23a2Schristos struct reloc_ext_external *bytes,
218377e23a2Schristos arelent *cache_ptr,
219377e23a2Schristos asymbol **symbols,
220377e23a2Schristos bfd_size_type symcount)
221377e23a2Schristos {
222377e23a2Schristos unsigned int r_index;
223377e23a2Schristos int r_extern;
224377e23a2Schristos unsigned int r_type;
225377e23a2Schristos struct aoutdata *su = &(abfd->tdata.aout_data->a);
226377e23a2Schristos
227377e23a2Schristos cache_ptr->address = (GET_SWORD (abfd, bytes->r_address));
228377e23a2Schristos
229377e23a2Schristos /* Now the fun stuff. */
230*1424dfb3Schristos r_index = (((unsigned int) bytes->r_index[2] << 16)
231*1424dfb3Schristos | ((unsigned int) bytes->r_index[1] << 8)
232*1424dfb3Schristos | bytes->r_index[0]);
233*1424dfb3Schristos
234377e23a2Schristos r_extern = (0 != (bytes->r_type[0] & RELOC_EXT_BITS_EXTERN_LITTLE));
235*1424dfb3Schristos
236*1424dfb3Schristos r_type = ((bytes->r_type[0] & RELOC_EXT_BITS_TYPE_LITTLE)
237*1424dfb3Schristos >> RELOC_EXT_BITS_TYPE_SH_LITTLE);
238377e23a2Schristos
239377e23a2Schristos if (r_type > 2)
240377e23a2Schristos {
2411c468f90Schristos /* xgettext:c-format */
24207163879Schristos _bfd_error_handler (_("%pB: unsupported relocation type imported: %#x"),
243377e23a2Schristos abfd, r_type);
244377e23a2Schristos
245377e23a2Schristos bfd_set_error (bfd_error_wrong_format);
246377e23a2Schristos }
247377e23a2Schristos
248377e23a2Schristos cache_ptr->howto = howto_table_ext + r_type;
249377e23a2Schristos
250377e23a2Schristos if (r_extern && r_index > symcount)
251377e23a2Schristos {
2521c468f90Schristos _bfd_error_handler
2531c468f90Schristos /* xgettext:c-format */
25407163879Schristos (_("%pB: bad relocation record imported: %d"), abfd, r_index);
255377e23a2Schristos
256377e23a2Schristos bfd_set_error (bfd_error_wrong_format);
257377e23a2Schristos
258377e23a2Schristos /* We continue, so we can catch further errors. */
259377e23a2Schristos r_extern = 0;
260377e23a2Schristos r_index = N_ABS;
261377e23a2Schristos }
262377e23a2Schristos
263377e23a2Schristos /* Magically uses r_extern, symbols etc. Ugly, but it's what's in the
264377e23a2Schristos default. */
265377e23a2Schristos MOVE_ADDRESS (GET_SWORD (abfd, bytes->r_addend));
266377e23a2Schristos }
267377e23a2Schristos
268377e23a2Schristos /* We use the same as the default, except that we also set
269377e23a2Schristos "obj_reloc_entry_size (abfd) = RELOC_EXT_SIZE;", to avoid changing
270377e23a2Schristos NAME (aout, set_arch_mach) in aoutx. */
271377e23a2Schristos
272377e23a2Schristos static bfd_boolean
MY(set_sizes)273377e23a2Schristos MY (set_sizes) (bfd *abfd)
274377e23a2Schristos {
275377e23a2Schristos /* Just as the default in aout-target.h (with some #ifdefs folded)... */
276377e23a2Schristos
277377e23a2Schristos adata (abfd).page_size = TARGET_PAGE_SIZE;
278377e23a2Schristos adata (abfd).segment_size = SEGMENT_SIZE;
279377e23a2Schristos adata (abfd).zmagic_disk_block_size = ZMAGIC_DISK_BLOCK_SIZE;
280377e23a2Schristos adata (abfd).exec_bytes_size = EXEC_BYTES_SIZE;
281377e23a2Schristos
282377e23a2Schristos /* ... except for that we have the extended reloc. The alternative
283377e23a2Schristos would be to add a check on bfd_arch_cris in NAME (aout,
284377e23a2Schristos set_arch_mach) in aoutx.h, but I don't want to do that since
285377e23a2Schristos target-specific things should not be added there. */
286377e23a2Schristos
287377e23a2Schristos obj_reloc_entry_size (abfd) = RELOC_EXT_SIZE;
288377e23a2Schristos
289377e23a2Schristos return TRUE;
290377e23a2Schristos }
291