i386lynx.c revision 1.1.1.2 1 1.1 christos /* BFD back-end for i386 a.out binaries under LynxOS.
2 1.1.1.2 christos Copyright (C) 1990-2015 Free Software Foundation, Inc.
3 1.1 christos
4 1.1 christos This file is part of BFD, the Binary File Descriptor library.
5 1.1 christos
6 1.1 christos This program is free software; you can redistribute it and/or modify
7 1.1 christos it under the terms of the GNU General Public License as published by
8 1.1 christos the Free Software Foundation; either version 3 of the License, or
9 1.1 christos (at your option) any later version.
10 1.1 christos
11 1.1 christos This program is distributed in the hope that it will be useful,
12 1.1 christos but WITHOUT ANY WARRANTY; without even the implied warranty of
13 1.1 christos MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
14 1.1 christos GNU General Public License for more details.
15 1.1 christos
16 1.1 christos You should have received a copy of the GNU General Public License
17 1.1 christos along with this program; if not, write to the Free Software
18 1.1 christos Foundation, Inc., 51 Franklin Street - Fifth Floor, Boston,
19 1.1 christos MA 02110-1301, USA. */
20 1.1 christos
21 1.1 christos #define TEXT_START_ADDR 0
22 1.1 christos #define TARGET_PAGE_SIZE 4096
23 1.1 christos #define SEGMENT_SIZE TARGET_PAGE_SIZE
24 1.1 christos #define DEFAULT_ARCH bfd_arch_i386
25 1.1 christos
26 1.1 christos /* Do not "beautify" the CONCAT* macro args. Traditional C will not
27 1.1 christos remove whitespace added here, and thus will fail to concatenate
28 1.1 christos the tokens. */
29 1.1.1.2 christos #define MY(OP) CONCAT2 (i386_aout_lynx_,OP)
30 1.1 christos #define TARGETNAME "a.out-i386-lynx"
31 1.1 christos
32 1.1 christos #include "sysdep.h"
33 1.1 christos #include "bfd.h"
34 1.1 christos #include "libbfd.h"
35 1.1 christos
36 1.1 christos #ifndef WRITE_HEADERS
37 1.1 christos #define WRITE_HEADERS(abfd, execp) \
38 1.1 christos { \
39 1.1 christos bfd_size_type text_size; /* dummy vars */ \
40 1.1 christos file_ptr text_end; \
41 1.1 christos if (adata(abfd).magic == undecided_magic) \
42 1.1 christos NAME(aout,adjust_sizes_and_vmas) (abfd, &text_size, &text_end); \
43 1.1 christos \
44 1.1 christos execp->a_syms = bfd_get_symcount (abfd) * EXTERNAL_NLIST_SIZE; \
45 1.1 christos execp->a_entry = bfd_get_start_address (abfd); \
46 1.1 christos \
47 1.1 christos execp->a_trsize = ((obj_textsec (abfd)->reloc_count) * \
48 1.1 christos obj_reloc_entry_size (abfd)); \
49 1.1 christos execp->a_drsize = ((obj_datasec (abfd)->reloc_count) * \
50 1.1 christos obj_reloc_entry_size (abfd)); \
51 1.1 christos NAME(aout,swap_exec_header_out) (abfd, execp, &exec_bytes); \
52 1.1 christos \
53 1.1 christos if (bfd_seek (abfd, (file_ptr) 0, SEEK_SET) != 0 \
54 1.1 christos || bfd_bwrite (&exec_bytes, (bfd_size_type) EXEC_BYTES_SIZE, \
55 1.1 christos abfd) != EXEC_BYTES_SIZE) \
56 1.1 christos return FALSE; \
57 1.1 christos /* Now write out reloc info, followed by syms and strings */ \
58 1.1 christos \
59 1.1 christos if (bfd_get_symcount (abfd) != 0) \
60 1.1 christos { \
61 1.1 christos if (bfd_seek (abfd, (file_ptr) (N_SYMOFF(*execp)), SEEK_SET) \
62 1.1 christos != 0) \
63 1.1 christos return FALSE; \
64 1.1 christos \
65 1.1 christos if (! NAME(aout,write_syms) (abfd)) return FALSE; \
66 1.1 christos \
67 1.1 christos if (bfd_seek (abfd, (file_ptr) (N_TRELOFF(*execp)), SEEK_SET) \
68 1.1 christos != 0) \
69 1.1 christos return FALSE; \
70 1.1 christos \
71 1.1 christos if (!NAME(lynx,squirt_out_relocs) (abfd, obj_textsec (abfd))) \
72 1.1 christos return FALSE; \
73 1.1 christos if (bfd_seek (abfd, (file_ptr) (N_DRELOFF(*execp)), SEEK_SET) \
74 1.1 christos != 0) \
75 1.1 christos return 0; \
76 1.1 christos \
77 1.1 christos if (!NAME(lynx,squirt_out_relocs) (abfd, obj_datasec (abfd))) \
78 1.1 christos return FALSE; \
79 1.1 christos } \
80 1.1 christos }
81 1.1 christos #endif
82 1.1 christos
83 1.1 christos #include "libaout.h"
84 1.1 christos #include "aout/aout64.h"
85 1.1 christos
86 1.1 christos
87 1.1 christos #ifdef LYNX_CORE
88 1.1 christos
89 1.1 christos char *lynx_core_file_failing_command ();
90 1.1 christos int lynx_core_file_failing_signal ();
91 1.1 christos bfd_boolean lynx_core_file_matches_executable_p ();
92 1.1 christos const bfd_target *lynx_core_file_p ();
93 1.1 christos
94 1.1 christos #define MY_core_file_failing_command lynx_core_file_failing_command
95 1.1 christos #define MY_core_file_failing_signal lynx_core_file_failing_signal
96 1.1 christos #define MY_core_file_matches_executable_p lynx_core_file_matches_executable_p
97 1.1 christos #define MY_core_file_p lynx_core_file_p
98 1.1 christos
99 1.1 christos #endif /* LYNX_CORE */
100 1.1 christos
101 1.1 christos
103 1.1 christos #define KEEPIT udata.i
104 1.1 christos
105 1.1 christos extern reloc_howto_type aout_32_ext_howto_table[];
106 1.1 christos extern reloc_howto_type aout_32_std_howto_table[];
107 1.1 christos
108 1.1 christos /* Standard reloc stuff */
109 1.1 christos /* Output standard relocation information to a file in target byte order. */
110 1.1 christos
111 1.1 christos static void
112 1.1 christos NAME(lynx,swap_std_reloc_out) (bfd *abfd,
113 1.1 christos arelent *g,
114 1.1 christos struct reloc_std_external *natptr)
115 1.1 christos {
116 1.1 christos int r_index;
117 1.1 christos asymbol *sym = *(g->sym_ptr_ptr);
118 1.1 christos int r_extern;
119 1.1 christos unsigned int r_length;
120 1.1 christos int r_pcrel;
121 1.1 christos int r_baserel, r_jmptable, r_relative;
122 1.1 christos asection *output_section = sym->section->output_section;
123 1.1 christos
124 1.1 christos PUT_WORD (abfd, g->address, natptr->r_address);
125 1.1 christos
126 1.1 christos r_length = g->howto->size; /* Size as a power of two */
127 1.1 christos r_pcrel = (int) g->howto->pc_relative; /* Relative to PC? */
128 1.1 christos /* r_baserel, r_jmptable, r_relative??? FIXME-soon */
129 1.1 christos r_baserel = 0;
130 1.1 christos r_jmptable = 0;
131 1.1 christos r_relative = 0;
132 1.1 christos
133 1.1 christos /* name was clobbered by aout_write_syms to be symbol index */
134 1.1 christos
135 1.1 christos /* If this relocation is relative to a symbol then set the
136 1.1 christos r_index to the symbols index, and the r_extern bit.
137 1.1 christos
138 1.1 christos Absolute symbols can come in in two ways, either as an offset
139 1.1 christos from the abs section, or as a symbol which has an abs value.
140 1.1 christos check for that here
141 1.1 christos */
142 1.1 christos
143 1.1 christos if (bfd_is_com_section (output_section)
144 1.1 christos || bfd_is_abs_section (output_section)
145 1.1 christos || bfd_is_und_section (output_section))
146 1.1 christos {
147 1.1 christos if (bfd_abs_section_ptr->symbol == sym)
148 1.1 christos {
149 1.1 christos /* Whoops, looked like an abs symbol, but is really an offset
150 1.1 christos from the abs section */
151 1.1 christos r_index = 0;
152 1.1 christos r_extern = 0;
153 1.1 christos }
154 1.1 christos else
155 1.1 christos {
156 1.1 christos /* Fill in symbol */
157 1.1 christos r_extern = 1;
158 1.1 christos r_index = (*g->sym_ptr_ptr)->KEEPIT;
159 1.1 christos }
160 1.1 christos }
161 1.1 christos else
162 1.1 christos {
163 1.1 christos /* Just an ordinary section */
164 1.1 christos r_extern = 0;
165 1.1 christos r_index = output_section->target_index;
166 1.1 christos }
167 1.1 christos
168 1.1 christos /* now the fun stuff */
169 1.1 christos if (bfd_header_big_endian (abfd))
170 1.1 christos {
171 1.1 christos natptr->r_index[0] = r_index >> 16;
172 1.1 christos natptr->r_index[1] = r_index >> 8;
173 1.1 christos natptr->r_index[2] = r_index;
174 1.1 christos natptr->r_type[0] =
175 1.1 christos (r_extern ? RELOC_STD_BITS_EXTERN_BIG : 0)
176 1.1 christos | (r_pcrel ? RELOC_STD_BITS_PCREL_BIG : 0)
177 1.1 christos | (r_baserel ? RELOC_STD_BITS_BASEREL_BIG : 0)
178 1.1 christos | (r_jmptable ? RELOC_STD_BITS_JMPTABLE_BIG : 0)
179 1.1 christos | (r_relative ? RELOC_STD_BITS_RELATIVE_BIG : 0)
180 1.1 christos | (r_length << RELOC_STD_BITS_LENGTH_SH_BIG);
181 1.1 christos }
182 1.1 christos else
183 1.1 christos {
184 1.1 christos natptr->r_index[2] = r_index >> 16;
185 1.1 christos natptr->r_index[1] = r_index >> 8;
186 1.1 christos natptr->r_index[0] = r_index;
187 1.1 christos natptr->r_type[0] =
188 1.1 christos (r_extern ? RELOC_STD_BITS_EXTERN_LITTLE : 0)
189 1.1 christos | (r_pcrel ? RELOC_STD_BITS_PCREL_LITTLE : 0)
190 1.1 christos | (r_baserel ? RELOC_STD_BITS_BASEREL_LITTLE : 0)
191 1.1 christos | (r_jmptable ? RELOC_STD_BITS_JMPTABLE_LITTLE : 0)
192 1.1 christos | (r_relative ? RELOC_STD_BITS_RELATIVE_LITTLE : 0)
193 1.1 christos | (r_length << RELOC_STD_BITS_LENGTH_SH_LITTLE);
194 1.1 christos }
195 1.1 christos }
196 1.1 christos
197 1.1 christos
198 1.1 christos /* Extended stuff */
199 1.1 christos /* Output extended relocation information to a file in target byte order. */
200 1.1 christos
201 1.1 christos static void
202 1.1 christos NAME(lynx,swap_ext_reloc_out) (bfd *abfd,
203 1.1 christos arelent *g,
204 1.1 christos struct reloc_ext_external *natptr)
205 1.1 christos {
206 1.1 christos int r_index;
207 1.1 christos int r_extern;
208 1.1 christos unsigned int r_type;
209 1.1 christos unsigned int r_addend;
210 1.1 christos asymbol *sym = *(g->sym_ptr_ptr);
211 1.1 christos asection *output_section = sym->section->output_section;
212 1.1 christos
213 1.1 christos PUT_WORD (abfd, g->address, natptr->r_address);
214 1.1 christos
215 1.1 christos r_type = (unsigned int) g->howto->type;
216 1.1 christos
217 1.1 christos r_addend = g->addend + (*(g->sym_ptr_ptr))->section->output_section->vma;
218 1.1 christos
219 1.1 christos
220 1.1 christos /* If this relocation is relative to a symbol then set the
221 1.1 christos r_index to the symbols index, and the r_extern bit.
222 1.1 christos
223 1.1 christos Absolute symbols can come in in two ways, either as an offset
224 1.1 christos from the abs section, or as a symbol which has an abs value.
225 1.1 christos check for that here
226 1.1 christos */
227 1.1 christos
228 1.1 christos if (bfd_is_com_section (output_section)
229 1.1 christos || bfd_is_abs_section (output_section)
230 1.1 christos || bfd_is_und_section (output_section))
231 1.1 christos {
232 1.1 christos if (bfd_abs_section_ptr->symbol == sym)
233 1.1 christos {
234 1.1 christos /* Whoops, looked like an abs symbol, but is really an offset
235 1.1 christos from the abs section */
236 1.1 christos r_index = 0;
237 1.1 christos r_extern = 0;
238 1.1 christos }
239 1.1 christos else
240 1.1 christos {
241 1.1 christos r_extern = 1;
242 1.1 christos r_index = (*g->sym_ptr_ptr)->KEEPIT;
243 1.1 christos }
244 1.1 christos }
245 1.1 christos else
246 1.1 christos {
247 1.1 christos /* Just an ordinary section */
248 1.1 christos r_extern = 0;
249 1.1 christos r_index = output_section->target_index;
250 1.1 christos }
251 1.1 christos
252 1.1 christos
253 1.1 christos /* now the fun stuff */
254 1.1 christos if (bfd_header_big_endian (abfd))
255 1.1 christos {
256 1.1 christos natptr->r_index[0] = r_index >> 16;
257 1.1 christos natptr->r_index[1] = r_index >> 8;
258 1.1 christos natptr->r_index[2] = r_index;
259 1.1 christos natptr->r_type[0] =
260 1.1 christos (r_extern ? RELOC_EXT_BITS_EXTERN_BIG : 0)
261 1.1 christos | (r_type << RELOC_EXT_BITS_TYPE_SH_BIG);
262 1.1 christos }
263 1.1 christos else
264 1.1 christos {
265 1.1 christos natptr->r_index[2] = r_index >> 16;
266 1.1 christos natptr->r_index[1] = r_index >> 8;
267 1.1 christos natptr->r_index[0] = r_index;
268 1.1 christos natptr->r_type[0] =
269 1.1 christos (r_extern ? RELOC_EXT_BITS_EXTERN_LITTLE : 0)
270 1.1 christos | (r_type << RELOC_EXT_BITS_TYPE_SH_LITTLE);
271 1.1 christos }
272 1.1 christos
273 1.1 christos PUT_WORD (abfd, r_addend, natptr->r_addend);
274 1.1 christos }
275 1.1 christos
276 1.1 christos /* BFD deals internally with all things based from the section they're
277 1.1 christos in. so, something in 10 bytes into a text section with a base of
278 1.1 christos 50 would have a symbol (.text+10) and know .text vma was 50.
279 1.1 christos
280 1.1 christos Aout keeps all it's symbols based from zero, so the symbol would
281 1.1 christos contain 60. This macro subs the base of each section from the value
282 1.1 christos to give the true offset from the section */
283 1.1 christos
284 1.1 christos
285 1.1 christos #define MOVE_ADDRESS(ad) \
286 1.1 christos if (r_extern) \
287 1.1 christos { \
288 1.1 christos /* undefined symbol */ \
289 1.1 christos cache_ptr->sym_ptr_ptr = symbols + r_index; \
290 1.1 christos cache_ptr->addend = ad; \
291 1.1 christos } \
292 1.1 christos else \
293 1.1 christos { \
294 1.1 christos /* defined, section relative. replace symbol with pointer to \
295 1.1 christos symbol which points to section */ \
296 1.1 christos switch (r_index) { \
297 1.1 christos case N_TEXT: \
298 1.1 christos case N_TEXT | N_EXT: \
299 1.1 christos cache_ptr->sym_ptr_ptr = obj_textsec(abfd)->symbol_ptr_ptr; \
300 1.1 christos cache_ptr->addend = ad - su->textsec->vma; \
301 1.1 christos break; \
302 1.1 christos case N_DATA: \
303 1.1 christos case N_DATA | N_EXT: \
304 1.1 christos cache_ptr->sym_ptr_ptr = obj_datasec(abfd)->symbol_ptr_ptr; \
305 1.1 christos cache_ptr->addend = ad - su->datasec->vma; \
306 1.1 christos break; \
307 1.1 christos case N_BSS: \
308 1.1 christos case N_BSS | N_EXT: \
309 1.1 christos cache_ptr->sym_ptr_ptr = obj_bsssec(abfd)->symbol_ptr_ptr; \
310 1.1 christos cache_ptr->addend = ad - su->bsssec->vma; \
311 1.1 christos break; \
312 1.1 christos default: \
313 1.1 christos case N_ABS: \
314 1.1 christos case N_ABS | N_EXT: \
315 1.1 christos cache_ptr->sym_ptr_ptr = bfd_abs_section_ptr->symbol_ptr_ptr; \
316 1.1 christos cache_ptr->addend = ad; \
317 1.1 christos break; \
318 1.1 christos } \
319 1.1 christos } \
320 1.1 christos
321 1.1 christos static void
322 1.1 christos NAME(lynx,swap_ext_reloc_in) (bfd *abfd,
323 1.1 christos struct reloc_ext_external *bytes,
324 1.1 christos arelent *cache_ptr,
325 1.1 christos asymbol **symbols,
326 1.1 christos bfd_size_type symcount ATTRIBUTE_UNUSED)
327 1.1 christos {
328 1.1 christos int r_index;
329 1.1 christos int r_extern;
330 1.1 christos unsigned int r_type;
331 1.1 christos struct aoutdata *su = &(abfd->tdata.aout_data->a);
332 1.1 christos
333 1.1 christos cache_ptr->address = (GET_SWORD (abfd, bytes->r_address));
334 1.1 christos
335 1.1 christos r_index = bytes->r_index[1];
336 1.1 christos r_extern = (0 != (bytes->r_index[0] & RELOC_EXT_BITS_EXTERN_BIG));
337 1.1 christos r_type = (bytes->r_index[0] & RELOC_EXT_BITS_TYPE_BIG)
338 1.1 christos >> RELOC_EXT_BITS_TYPE_SH_BIG;
339 1.1 christos
340 1.1 christos cache_ptr->howto = aout_32_ext_howto_table + r_type;
341 1.1 christos MOVE_ADDRESS (GET_SWORD (abfd, bytes->r_addend));
342 1.1 christos }
343 1.1 christos
344 1.1 christos static void
345 1.1 christos NAME(lynx,swap_std_reloc_in) (bfd *abfd,
346 1.1 christos struct reloc_std_external *bytes,
347 1.1 christos arelent *cache_ptr,
348 1.1 christos asymbol **symbols,
349 1.1 christos bfd_size_type symcount ATTRIBUTE_UNUSED)
350 1.1 christos {
351 1.1 christos int r_index;
352 1.1 christos int r_extern;
353 1.1 christos unsigned int r_length;
354 1.1 christos int r_pcrel;
355 1.1 christos struct aoutdata *su = &(abfd->tdata.aout_data->a);
356 1.1 christos
357 1.1 christos cache_ptr->address = H_GET_32 (abfd, bytes->r_address);
358 1.1 christos
359 1.1 christos r_index = bytes->r_index[1];
360 1.1 christos r_extern = (0 != (bytes->r_index[0] & RELOC_STD_BITS_EXTERN_BIG));
361 1.1 christos r_pcrel = (0 != (bytes->r_index[0] & RELOC_STD_BITS_PCREL_BIG));
362 1.1 christos r_length = (bytes->r_index[0] & RELOC_STD_BITS_LENGTH_BIG)
363 1.1 christos >> RELOC_STD_BITS_LENGTH_SH_BIG;
364 1.1 christos
365 1.1 christos cache_ptr->howto = aout_32_std_howto_table + r_length + 4 * r_pcrel;
366 1.1 christos /* FIXME-soon: Roll baserel, jmptable, relative bits into howto setting */
367 1.1 christos
368 1.1 christos MOVE_ADDRESS (0);
369 1.1 christos }
370 1.1 christos
371 1.1 christos /* Reloc hackery */
372 1.1 christos
373 1.1 christos static bfd_boolean
374 1.1 christos NAME(lynx,slurp_reloc_table) (bfd *abfd,
375 1.1 christos sec_ptr asect,
376 1.1 christos asymbol **symbols)
377 1.1 christos {
378 1.1 christos bfd_size_type count;
379 1.1 christos bfd_size_type reloc_size;
380 1.1 christos void * relocs;
381 1.1 christos arelent *reloc_cache;
382 1.1 christos size_t each_size;
383 1.1 christos
384 1.1 christos if (asect->relocation)
385 1.1 christos return TRUE;
386 1.1 christos
387 1.1 christos if (asect->flags & SEC_CONSTRUCTOR)
388 1.1 christos return TRUE;
389 1.1 christos
390 1.1 christos if (asect == obj_datasec (abfd))
391 1.1 christos {
392 1.1 christos reloc_size = exec_hdr (abfd)->a_drsize;
393 1.1 christos goto doit;
394 1.1 christos }
395 1.1 christos
396 1.1 christos if (asect == obj_textsec (abfd))
397 1.1 christos {
398 1.1 christos reloc_size = exec_hdr (abfd)->a_trsize;
399 1.1 christos goto doit;
400 1.1 christos }
401 1.1 christos
402 1.1 christos bfd_set_error (bfd_error_invalid_operation);
403 1.1 christos return FALSE;
404 1.1 christos
405 1.1 christos doit:
406 1.1 christos if (bfd_seek (abfd, asect->rel_filepos, SEEK_SET) != 0)
407 1.1 christos return FALSE;
408 1.1 christos each_size = obj_reloc_entry_size (abfd);
409 1.1 christos
410 1.1 christos count = reloc_size / each_size;
411 1.1 christos
412 1.1 christos
413 1.1 christos reloc_cache = (arelent *) bfd_zmalloc (count * sizeof (arelent));
414 1.1 christos if (!reloc_cache && count != 0)
415 1.1 christos return FALSE;
416 1.1 christos
417 1.1 christos relocs = bfd_alloc (abfd, reloc_size);
418 1.1 christos if (!relocs && reloc_size != 0)
419 1.1 christos {
420 1.1 christos free (reloc_cache);
421 1.1 christos return FALSE;
422 1.1 christos }
423 1.1 christos
424 1.1 christos if (bfd_bread (relocs, reloc_size, abfd) != reloc_size)
425 1.1 christos {
426 1.1 christos bfd_release (abfd, relocs);
427 1.1 christos free (reloc_cache);
428 1.1 christos return FALSE;
429 1.1 christos }
430 1.1 christos
431 1.1 christos if (each_size == RELOC_EXT_SIZE)
432 1.1 christos {
433 1.1 christos struct reloc_ext_external *rptr = (struct reloc_ext_external *) relocs;
434 1.1 christos unsigned int counter = 0;
435 1.1 christos arelent *cache_ptr = reloc_cache;
436 1.1 christos
437 1.1 christos for (; counter < count; counter++, rptr++, cache_ptr++)
438 1.1 christos {
439 1.1 christos NAME(lynx,swap_ext_reloc_in) (abfd, rptr, cache_ptr, symbols,
440 1.1 christos (bfd_size_type) bfd_get_symcount (abfd));
441 1.1 christos }
442 1.1 christos }
443 1.1 christos else
444 1.1 christos {
445 1.1 christos struct reloc_std_external *rptr = (struct reloc_std_external *) relocs;
446 1.1 christos unsigned int counter = 0;
447 1.1 christos arelent *cache_ptr = reloc_cache;
448 1.1 christos
449 1.1 christos for (; counter < count; counter++, rptr++, cache_ptr++)
450 1.1 christos {
451 1.1 christos NAME(lynx,swap_std_reloc_in) (abfd, rptr, cache_ptr, symbols,
452 1.1 christos (bfd_size_type) bfd_get_symcount (abfd));
453 1.1 christos }
454 1.1 christos
455 1.1 christos }
456 1.1 christos
457 1.1 christos bfd_release (abfd, relocs);
458 1.1 christos asect->relocation = reloc_cache;
459 1.1 christos asect->reloc_count = count;
460 1.1 christos return TRUE;
461 1.1 christos }
462 1.1 christos
463 1.1 christos
464 1.1 christos
465 1.1 christos /* Write out a relocation section into an object file. */
466 1.1 christos
467 1.1 christos static bfd_boolean
468 1.1 christos NAME(lynx,squirt_out_relocs) (bfd *abfd, asection *section)
469 1.1 christos {
470 1.1 christos arelent **generic;
471 1.1 christos unsigned char *native, *natptr;
472 1.1 christos size_t each_size;
473 1.1 christos unsigned int count = section->reloc_count;
474 1.1 christos bfd_size_type natsize;
475 1.1 christos
476 1.1 christos if (count == 0)
477 1.1 christos return TRUE;
478 1.1 christos
479 1.1 christos each_size = obj_reloc_entry_size (abfd);
480 1.1 christos natsize = count;
481 1.1 christos natsize *= each_size;
482 1.1 christos native = (unsigned char *) bfd_zalloc (abfd, natsize);
483 1.1 christos if (!native)
484 1.1 christos return FALSE;
485 1.1 christos
486 1.1 christos generic = section->orelocation;
487 1.1 christos
488 1.1 christos if (each_size == RELOC_EXT_SIZE)
489 1.1 christos {
490 1.1 christos for (natptr = native;
491 1.1 christos count != 0;
492 1.1 christos --count, natptr += each_size, ++generic)
493 1.1 christos NAME(lynx,swap_ext_reloc_out) (abfd, *generic, (struct reloc_ext_external *) natptr);
494 1.1 christos }
495 1.1 christos else
496 1.1 christos {
497 1.1 christos for (natptr = native;
498 1.1 christos count != 0;
499 1.1 christos --count, natptr += each_size, ++generic)
500 1.1 christos NAME(lynx,swap_std_reloc_out) (abfd, *generic, (struct reloc_std_external *) natptr);
501 1.1 christos }
502 1.1 christos
503 1.1 christos if (bfd_bwrite (native, natsize, abfd) != natsize)
504 1.1 christos {
505 1.1 christos bfd_release (abfd, native);
506 1.1 christos return FALSE;
507 1.1 christos }
508 1.1 christos bfd_release (abfd, native);
509 1.1 christos
510 1.1 christos return TRUE;
511 1.1 christos }
512 1.1 christos
513 1.1 christos /* This is stupid. This function should be a boolean predicate */
514 1.1 christos static long
515 1.1 christos NAME(lynx,canonicalize_reloc) (bfd *abfd,
516 1.1 christos sec_ptr section,
517 1.1 christos arelent **relptr,
518 1.1 christos asymbol **symbols)
519 1.1 christos {
520 1.1 christos arelent *tblptr = section->relocation;
521 1.1 christos unsigned int count;
522 1.1 christos
523 1.1 christos if (!(tblptr || NAME(lynx,slurp_reloc_table) (abfd, section, symbols)))
524 1.1 christos return -1;
525 1.1 christos
526 1.1 christos if (section->flags & SEC_CONSTRUCTOR)
527 1.1 christos {
528 1.1 christos arelent_chain *chain = section->constructor_chain;
529 1.1 christos for (count = 0; count < section->reloc_count; count++)
530 1.1 christos {
531 1.1 christos *relptr++ = &chain->relent;
532 1.1 christos chain = chain->next;
533 1.1 christos }
534 1.1 christos }
535 1.1 christos else
536 1.1 christos {
537 1.1 christos tblptr = section->relocation;
538 1.1 christos
539 1.1 christos for (count = 0; count++ < section->reloc_count;)
540 1.1 christos {
541 1.1 christos *relptr++ = tblptr++;
542 1.1 christos }
543 1.1 christos }
544 1.1 christos *relptr = 0;
545 1.1 christos
546 1.1 christos return section->reloc_count;
547 1.1 christos }
548 1.1 christos
549 1.1 christos #define MY_canonicalize_reloc NAME(lynx,canonicalize_reloc)
550 1.1 christos
551 #include "aout-target.h"
552