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