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