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