1 |
/* NLM (NetWare Loadable Module) executable support for BFD. |
/* NLM (NetWare Loadable Module) executable support for BFD. |
2 |
Copyright 1993, 1994, 1995, 1998, 2000, 2001, 2002 |
Copyright 1993, 1994, 1995, 1998, 1999, 2000, 2001, 2002, 2003, 2004 |
3 |
Free Software Foundation, Inc. |
Free Software Foundation, Inc. |
4 |
|
|
5 |
Written by Fred Fish @ Cygnus Support, using ELF support as the |
Written by Fred Fish @ Cygnus Support, using ELF support as the |
6 |
template. |
template. |
7 |
|
|
8 |
This file is part of BFD, the Binary File Descriptor library. |
This file is part of BFD, the Binary File Descriptor library. |
9 |
|
|
10 |
This program is free software; you can redistribute it and/or modify |
This program is free software; you can redistribute it and/or modify |
11 |
it under the terms of the GNU General Public License as published by |
it under the terms of the GNU General Public License as published by |
12 |
the Free Software Foundation; either version 2 of the License, or |
the Free Software Foundation; either version 2 of the License, or |
13 |
(at your option) any later version. |
(at your option) any later version. |
14 |
|
|
15 |
This program is distributed in the hope that it will be useful, |
This program is distributed in the hope that it will be useful, |
16 |
but WITHOUT ANY WARRANTY; without even the implied warranty of |
but WITHOUT ANY WARRANTY; without even the implied warranty of |
17 |
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the |
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the |
18 |
GNU General Public License for more details. |
GNU General Public License for more details. |
19 |
|
|
20 |
You should have received a copy of the GNU General Public License |
You should have received a copy of the GNU General Public License |
21 |
along with this program; if not, write to the Free Software |
along with this program; if not, write to the Free Software |
22 |
Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */ |
Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */ |
23 |
|
|
24 |
#include "bfd.h" |
#include "bfd.h" |
25 |
#include "sysdep.h" |
#include "sysdep.h" |
42 |
|
|
43 |
#define nlm_symbol_type nlmNAME(symbol_type) |
#define nlm_symbol_type nlmNAME(symbol_type) |
44 |
#define nlm_get_symtab_upper_bound nlmNAME(get_symtab_upper_bound) |
#define nlm_get_symtab_upper_bound nlmNAME(get_symtab_upper_bound) |
45 |
#define nlm_get_symtab nlmNAME(get_symtab) |
#define nlm_canonicalize_symtab nlmNAME(canonicalize_symtab) |
46 |
#define nlm_make_empty_symbol nlmNAME(make_empty_symbol) |
#define nlm_make_empty_symbol nlmNAME(make_empty_symbol) |
47 |
#define nlm_print_symbol nlmNAME(print_symbol) |
#define nlm_print_symbol nlmNAME(print_symbol) |
48 |
#define nlm_get_symbol_info nlmNAME(get_symbol_info) |
#define nlm_get_symbol_info nlmNAME(get_symbol_info) |
57 |
#define nlm_swap_fixed_header_out(abfd,src,dst) \ |
#define nlm_swap_fixed_header_out(abfd,src,dst) \ |
58 |
(nlm_swap_fixed_header_out_func(abfd)) (abfd,src,dst) |
(nlm_swap_fixed_header_out_func(abfd)) (abfd,src,dst) |
59 |
|
|
60 |
/* Forward declarations of static functions */ |
/* Forward declarations of static functions. */ |
61 |
|
|
62 |
static boolean add_bfd_section |
static bfd_boolean add_bfd_section |
63 |
PARAMS ((bfd *, char *, file_ptr, bfd_size_type, flagword)); |
PARAMS ((bfd *, char *, file_ptr, bfd_size_type, flagword)); |
64 |
static boolean nlm_swap_variable_header_in |
static bfd_boolean nlm_swap_variable_header_in |
65 |
PARAMS ((bfd *)); |
PARAMS ((bfd *)); |
66 |
static boolean nlm_swap_variable_header_out |
static bfd_boolean nlm_swap_variable_header_out |
67 |
PARAMS ((bfd *)); |
PARAMS ((bfd *)); |
68 |
static boolean find_nonzero |
static bfd_boolean find_nonzero |
69 |
PARAMS ((PTR, size_t)); |
PARAMS ((PTR, size_t)); |
70 |
static boolean nlm_swap_auxiliary_headers_in |
static bfd_boolean nlm_swap_auxiliary_headers_in |
71 |
PARAMS ((bfd *)); |
PARAMS ((bfd *)); |
72 |
static boolean nlm_swap_auxiliary_headers_out |
static bfd_boolean nlm_swap_auxiliary_headers_out |
73 |
PARAMS ((bfd *)); |
PARAMS ((bfd *)); |
74 |
static boolean nlm_slurp_symbol_table |
static bfd_boolean nlm_slurp_symbol_table |
75 |
PARAMS ((bfd *)); |
PARAMS ((bfd *)); |
76 |
static boolean nlm_slurp_reloc_fixups |
static bfd_boolean nlm_slurp_reloc_fixups |
77 |
PARAMS ((bfd *)); |
PARAMS ((bfd *)); |
78 |
static boolean nlm_compute_section_file_positions |
static bfd_boolean nlm_compute_section_file_positions |
79 |
PARAMS ((bfd *)); |
PARAMS ((bfd *)); |
80 |
static int nlm_external_reloc_compare |
static int nlm_external_reloc_compare |
81 |
PARAMS ((const void *, const void *)); |
PARAMS ((const void *, const void *)); |
96 |
bfd *abfd; |
bfd *abfd; |
97 |
{ |
{ |
98 |
struct nlm_obj_tdata *preserved_tdata = nlm_tdata (abfd); |
struct nlm_obj_tdata *preserved_tdata = nlm_tdata (abfd); |
99 |
boolean (*backend_object_p) PARAMS ((bfd *)); |
bfd_boolean (*backend_object_p) PARAMS ((bfd *)); |
100 |
PTR x_fxdhdr = NULL; |
PTR x_fxdhdr = NULL; |
101 |
Nlm_Internal_Fixed_Header *i_fxdhdrp; |
Nlm_Internal_Fixed_Header *i_fxdhdrp; |
102 |
struct nlm_obj_tdata *new_tdata = NULL; |
struct nlm_obj_tdata *new_tdata = NULL; |
114 |
} |
} |
115 |
|
|
116 |
/* Read in the fixed length portion of the NLM header in external format. */ |
/* Read in the fixed length portion of the NLM header in external format. */ |
|
|
|
117 |
amt = nlm_fixed_header_size (abfd); |
amt = nlm_fixed_header_size (abfd); |
118 |
x_fxdhdr = (PTR) bfd_malloc (amt); |
x_fxdhdr = (PTR) bfd_malloc (amt); |
119 |
if (x_fxdhdr == NULL) |
if (x_fxdhdr == NULL) |
129 |
|
|
130 |
/* Allocate an instance of the nlm_obj_tdata structure and hook it up to |
/* Allocate an instance of the nlm_obj_tdata structure and hook it up to |
131 |
the tdata pointer in the bfd. */ |
the tdata pointer in the bfd. */ |
|
|
|
132 |
amt = sizeof (struct nlm_obj_tdata); |
amt = sizeof (struct nlm_obj_tdata); |
133 |
new_tdata = (struct nlm_obj_tdata *) bfd_zalloc (abfd, amt); |
new_tdata = (struct nlm_obj_tdata *) bfd_zalloc (abfd, amt); |
134 |
if (new_tdata == NULL) |
if (new_tdata == NULL) |
143 |
|
|
144 |
/* Check to see if we have an NLM file for this backend by matching |
/* Check to see if we have an NLM file for this backend by matching |
145 |
the NLM signature. */ |
the NLM signature. */ |
|
|
|
146 |
signature = nlm_signature (abfd); |
signature = nlm_signature (abfd); |
147 |
if (signature != NULL |
if (signature != NULL |
148 |
&& *signature != '\0' |
&& *signature != '\0' |
152 |
|
|
153 |
/* There's no supported way to discover the endianess of an NLM, so test for |
/* There's no supported way to discover the endianess of an NLM, so test for |
154 |
a sane version number after doing byte swapping appropriate for this |
a sane version number after doing byte swapping appropriate for this |
155 |
XVEC. (Hack alert!) */ |
XVEC. (Hack alert!) */ |
|
|
|
156 |
if (i_fxdhdrp->version > 0xFFFF) |
if (i_fxdhdrp->version > 0xFFFF) |
157 |
goto got_wrong_format_error; |
goto got_wrong_format_error; |
158 |
|
|
159 |
/* There's no supported way to check for 32 bit versus 64 bit addresses, |
/* There's no supported way to check for 32 bit versus 64 bit addresses, |
160 |
so ignore this distinction for now. (FIXME) */ |
so ignore this distinction for now. (FIXME) */ |
|
|
|
161 |
/* Swap in the rest of the required header. */ |
/* Swap in the rest of the required header. */ |
162 |
if (!nlm_swap_variable_header_in (abfd)) |
if (!nlm_swap_variable_header_in (abfd)) |
163 |
{ |
{ |
172 |
additional sections described in the cygnus_ext header. |
additional sections described in the cygnus_ext header. |
173 |
From this point on we assume that we have an NLM, and do not |
From this point on we assume that we have an NLM, and do not |
174 |
treat errors as indicating the wrong format. */ |
treat errors as indicating the wrong format. */ |
|
|
|
175 |
if (!add_bfd_section (abfd, NLM_CODE_NAME, |
if (!add_bfd_section (abfd, NLM_CODE_NAME, |
176 |
i_fxdhdrp->codeImageOffset, |
i_fxdhdrp->codeImageOffset, |
177 |
i_fxdhdrp->codeImageSize, |
i_fxdhdrp->codeImageSize, |
221 |
|
|
222 |
/* Add a section to the bfd. */ |
/* Add a section to the bfd. */ |
223 |
|
|
224 |
static boolean |
static bfd_boolean |
225 |
add_bfd_section (abfd, name, offset, size, flags) |
add_bfd_section (abfd, name, offset, size, flags) |
226 |
bfd *abfd; |
bfd *abfd; |
227 |
char *name; |
char *name; |
233 |
|
|
234 |
newsect = bfd_make_section (abfd, name); |
newsect = bfd_make_section (abfd, name); |
235 |
if (newsect == NULL) |
if (newsect == NULL) |
236 |
{ |
return FALSE; |
237 |
return false; |
|
|
} |
|
238 |
newsect->vma = 0; /* NLM's are relocatable. */ |
newsect->vma = 0; /* NLM's are relocatable. */ |
239 |
newsect->_raw_size = size; |
newsect->size = size; |
240 |
newsect->filepos = offset; |
newsect->filepos = offset; |
241 |
newsect->flags = flags; |
newsect->flags = flags; |
242 |
newsect->alignment_power = bfd_log2 ((bfd_vma) 0); /* FIXME */ |
newsect->alignment_power = bfd_log2 ((bfd_vma) 0); /* FIXME */ |
243 |
return true; |
|
244 |
|
return TRUE; |
245 |
} |
} |
246 |
|
|
247 |
/* Read and swap in the variable length header. All the fields must |
/* Read and swap in the variable length header. All the fields must |
248 |
exist in the NLM, and must exist in the order they are read here. */ |
exist in the NLM, and must exist in the order they are read here. */ |
249 |
|
|
250 |
static boolean |
static bfd_boolean |
251 |
nlm_swap_variable_header_in (abfd) |
nlm_swap_variable_header_in (abfd) |
252 |
bfd *abfd; |
bfd *abfd; |
253 |
{ |
{ |
259 |
amt = sizeof (nlm_variable_header (abfd)->descriptionLength); |
amt = sizeof (nlm_variable_header (abfd)->descriptionLength); |
260 |
if (bfd_bread ((PTR) &nlm_variable_header (abfd)->descriptionLength, |
if (bfd_bread ((PTR) &nlm_variable_header (abfd)->descriptionLength, |
261 |
amt, abfd) != amt) |
amt, abfd) != amt) |
262 |
return false; |
return FALSE; |
263 |
amt = nlm_variable_header (abfd)->descriptionLength + 1; |
amt = nlm_variable_header (abfd)->descriptionLength + 1; |
264 |
if (bfd_bread ((PTR) nlm_variable_header (abfd)->descriptionText, |
if (bfd_bread ((PTR) nlm_variable_header (abfd)->descriptionText, |
265 |
amt, abfd) != amt) |
amt, abfd) != amt) |
266 |
return false; |
return FALSE; |
267 |
|
|
268 |
/* Read and convert the stackSize field. */ |
/* Read and convert the stackSize field. */ |
269 |
|
|
270 |
amt = sizeof (temp); |
amt = sizeof (temp); |
271 |
if (bfd_bread ((PTR) temp, amt, abfd) != amt) |
if (bfd_bread ((PTR) temp, amt, abfd) != amt) |
272 |
return false; |
return FALSE; |
273 |
nlm_variable_header (abfd)->stackSize = get_word (abfd, (bfd_byte *) temp); |
nlm_variable_header (abfd)->stackSize = get_word (abfd, (bfd_byte *) temp); |
274 |
|
|
275 |
/* Read and convert the reserved field. */ |
/* Read and convert the reserved field. */ |
276 |
|
|
277 |
amt = sizeof (temp); |
amt = sizeof (temp); |
278 |
if (bfd_bread ((PTR) temp, amt, abfd) != amt) |
if (bfd_bread ((PTR) temp, amt, abfd) != amt) |
279 |
return false; |
return FALSE; |
280 |
nlm_variable_header (abfd)->reserved = get_word (abfd, (bfd_byte *) temp); |
nlm_variable_header (abfd)->reserved = get_word (abfd, (bfd_byte *) temp); |
281 |
|
|
282 |
/* Read the oldThreadName field. This field is a fixed length string. */ |
/* Read the oldThreadName field. This field is a fixed length string. */ |
284 |
amt = sizeof (nlm_variable_header (abfd)->oldThreadName); |
amt = sizeof (nlm_variable_header (abfd)->oldThreadName); |
285 |
if (bfd_bread ((PTR) nlm_variable_header (abfd)->oldThreadName, |
if (bfd_bread ((PTR) nlm_variable_header (abfd)->oldThreadName, |
286 |
amt, abfd) != amt) |
amt, abfd) != amt) |
287 |
return false; |
return FALSE; |
288 |
|
|
289 |
/* Read the screen name length and text members. */ |
/* Read the screen name length and text members. */ |
290 |
|
|
291 |
amt = sizeof (nlm_variable_header (abfd)->screenNameLength); |
amt = sizeof (nlm_variable_header (abfd)->screenNameLength); |
292 |
if (bfd_bread ((PTR) & nlm_variable_header (abfd)->screenNameLength, |
if (bfd_bread ((PTR) & nlm_variable_header (abfd)->screenNameLength, |
293 |
amt, abfd) != amt) |
amt, abfd) != amt) |
294 |
return false; |
return FALSE; |
295 |
amt = nlm_variable_header (abfd)->screenNameLength + 1; |
amt = nlm_variable_header (abfd)->screenNameLength + 1; |
296 |
if (bfd_bread ((PTR) nlm_variable_header (abfd)->screenName, |
if (bfd_bread ((PTR) nlm_variable_header (abfd)->screenName, |
297 |
amt, abfd) != amt) |
amt, abfd) != amt) |
298 |
return false; |
return FALSE; |
299 |
|
|
300 |
/* Read the thread name length and text members. */ |
/* Read the thread name length and text members. */ |
301 |
|
|
302 |
amt = sizeof (nlm_variable_header (abfd)->threadNameLength); |
amt = sizeof (nlm_variable_header (abfd)->threadNameLength); |
303 |
if (bfd_bread ((PTR) & nlm_variable_header (abfd)->threadNameLength, |
if (bfd_bread ((PTR) & nlm_variable_header (abfd)->threadNameLength, |
304 |
amt, abfd) != amt) |
amt, abfd) != amt) |
305 |
return false; |
return FALSE; |
306 |
amt = nlm_variable_header (abfd)->threadNameLength + 1; |
amt = nlm_variable_header (abfd)->threadNameLength + 1; |
307 |
if (bfd_bread ((PTR) nlm_variable_header (abfd)->threadName, |
if (bfd_bread ((PTR) nlm_variable_header (abfd)->threadName, |
308 |
amt, abfd) != amt) |
amt, abfd) != amt) |
309 |
return false; |
return FALSE; |
310 |
return true; |
return TRUE; |
311 |
} |
} |
312 |
|
|
313 |
/* Swap and write out the variable length header. All the fields must |
/* Swap and write out the variable length header. All the fields must |
314 |
exist in the NLM, and must exist in this order. */ |
exist in the NLM, and must exist in this order. */ |
315 |
|
|
316 |
static boolean |
static bfd_boolean |
317 |
nlm_swap_variable_header_out (abfd) |
nlm_swap_variable_header_out (abfd) |
318 |
bfd *abfd; |
bfd *abfd; |
319 |
{ |
{ |
321 |
bfd_size_type amt; |
bfd_size_type amt; |
322 |
|
|
323 |
/* Write the description length and text members. */ |
/* Write the description length and text members. */ |
|
|
|
324 |
amt = sizeof (nlm_variable_header (abfd)->descriptionLength); |
amt = sizeof (nlm_variable_header (abfd)->descriptionLength); |
325 |
if (bfd_bwrite ((PTR) & nlm_variable_header (abfd)->descriptionLength, amt, |
if (bfd_bwrite ((PTR) & nlm_variable_header (abfd)->descriptionLength, amt, |
326 |
abfd) != amt) |
abfd) != amt) |
327 |
return false; |
return FALSE; |
328 |
amt = nlm_variable_header (abfd)->descriptionLength + 1; |
amt = nlm_variable_header (abfd)->descriptionLength + 1; |
329 |
if (bfd_bwrite ((PTR) nlm_variable_header (abfd)->descriptionText, amt, |
if (bfd_bwrite ((PTR) nlm_variable_header (abfd)->descriptionText, amt, |
330 |
abfd) != amt) |
abfd) != amt) |
331 |
return false; |
return FALSE; |
332 |
|
|
333 |
/* Convert and write the stackSize field. */ |
/* Convert and write the stackSize field. */ |
|
|
|
334 |
put_word (abfd, (bfd_vma) nlm_variable_header (abfd)->stackSize, |
put_word (abfd, (bfd_vma) nlm_variable_header (abfd)->stackSize, |
335 |
(bfd_byte *) temp); |
(bfd_byte *) temp); |
336 |
amt = sizeof (temp); |
amt = sizeof (temp); |
337 |
if (bfd_bwrite ((PTR) temp, amt, abfd) != amt) |
if (bfd_bwrite ((PTR) temp, amt, abfd) != amt) |
338 |
return false; |
return FALSE; |
339 |
|
|
340 |
/* Convert and write the reserved field. */ |
/* Convert and write the reserved field. */ |
|
|
|
341 |
put_word (abfd, (bfd_vma) nlm_variable_header (abfd)->reserved, |
put_word (abfd, (bfd_vma) nlm_variable_header (abfd)->reserved, |
342 |
(bfd_byte *) temp); |
(bfd_byte *) temp); |
343 |
amt = sizeof (temp); |
amt = sizeof (temp); |
344 |
if (bfd_bwrite ((PTR) temp, amt, abfd) != amt) |
if (bfd_bwrite ((PTR) temp, amt, abfd) != amt) |
345 |
return false; |
return FALSE; |
346 |
|
|
347 |
/* Write the oldThreadName field. This field is a fixed length string. */ |
/* Write the oldThreadName field. This field is a fixed length string. */ |
|
|
|
348 |
amt = sizeof (nlm_variable_header (abfd)->oldThreadName); |
amt = sizeof (nlm_variable_header (abfd)->oldThreadName); |
349 |
if (bfd_bwrite ((PTR) nlm_variable_header (abfd)->oldThreadName, amt, |
if (bfd_bwrite ((PTR) nlm_variable_header (abfd)->oldThreadName, amt, |
350 |
abfd) != amt) |
abfd) != amt) |
351 |
return false; |
return FALSE; |
352 |
|
|
353 |
/* Write the screen name length and text members. */ |
/* Write the screen name length and text members. */ |
|
|
|
354 |
amt = sizeof (nlm_variable_header (abfd)->screenNameLength); |
amt = sizeof (nlm_variable_header (abfd)->screenNameLength); |
355 |
if (bfd_bwrite ((PTR) & nlm_variable_header (abfd)->screenNameLength, amt, |
if (bfd_bwrite ((PTR) & nlm_variable_header (abfd)->screenNameLength, amt, |
356 |
abfd) != amt) |
abfd) != amt) |
357 |
return false; |
return FALSE; |
358 |
amt = nlm_variable_header (abfd)->screenNameLength + 1; |
amt = nlm_variable_header (abfd)->screenNameLength + 1; |
359 |
if (bfd_bwrite ((PTR) nlm_variable_header (abfd)->screenName, amt, |
if (bfd_bwrite ((PTR) nlm_variable_header (abfd)->screenName, amt, |
360 |
abfd) != amt) |
abfd) != amt) |
361 |
return false; |
return FALSE; |
362 |
|
|
363 |
/* Write the thread name length and text members. */ |
/* Write the thread name length and text members. */ |
|
|
|
364 |
amt = sizeof (nlm_variable_header (abfd)->threadNameLength); |
amt = sizeof (nlm_variable_header (abfd)->threadNameLength); |
365 |
if (bfd_bwrite ((PTR) & nlm_variable_header (abfd)->threadNameLength, amt, |
if (bfd_bwrite ((PTR) & nlm_variable_header (abfd)->threadNameLength, amt, |
366 |
abfd) != amt) |
abfd) != amt) |
367 |
return false; |
return FALSE; |
368 |
amt = nlm_variable_header (abfd)->threadNameLength + 1; |
amt = nlm_variable_header (abfd)->threadNameLength + 1; |
369 |
if (bfd_bwrite ((PTR) nlm_variable_header (abfd)->threadName, amt, |
if (bfd_bwrite ((PTR) nlm_variable_header (abfd)->threadName, amt, |
370 |
abfd) != amt) |
abfd) != amt) |
371 |
return false; |
return FALSE; |
372 |
return true; |
return TRUE; |
373 |
} |
} |
374 |
|
|
375 |
/* Read and swap in the contents of all the auxiliary headers. Because of |
/* Read and swap in the contents of all the auxiliary headers. Because of |
381 |
of auxiliary header added will break all existing tools that don't |
of auxiliary header added will break all existing tools that don't |
382 |
recognize it. */ |
recognize it. */ |
383 |
|
|
384 |
static boolean |
static bfd_boolean |
385 |
nlm_swap_auxiliary_headers_in (abfd) |
nlm_swap_auxiliary_headers_in (abfd) |
386 |
bfd *abfd; |
bfd *abfd; |
387 |
{ |
{ |
394 |
position = bfd_tell (abfd); |
position = bfd_tell (abfd); |
395 |
amt = sizeof (tempstr); |
amt = sizeof (tempstr); |
396 |
if (bfd_bread ((PTR) tempstr, amt, abfd) != amt) |
if (bfd_bread ((PTR) tempstr, amt, abfd) != amt) |
397 |
return false; |
return FALSE; |
398 |
if (bfd_seek (abfd, position, SEEK_SET) != 0) |
if (bfd_seek (abfd, position, SEEK_SET) != 0) |
399 |
return false; |
return FALSE; |
400 |
if (strncmp (tempstr, "VeRsIoN#", 8) == 0) |
if (strncmp (tempstr, "VeRsIoN#", 8) == 0) |
401 |
{ |
{ |
402 |
Nlm_External_Version_Header thdr; |
Nlm_External_Version_Header thdr; |
403 |
|
|
404 |
amt = sizeof (thdr); |
amt = sizeof (thdr); |
405 |
if (bfd_bread ((PTR) &thdr, amt, abfd) != amt) |
if (bfd_bread ((PTR) &thdr, amt, abfd) != amt) |
406 |
return false; |
return FALSE; |
407 |
memcpy (nlm_version_header (abfd)->stamp, thdr.stamp, |
memcpy (nlm_version_header (abfd)->stamp, thdr.stamp, |
408 |
sizeof (thdr.stamp)); |
sizeof (thdr.stamp)); |
409 |
nlm_version_header (abfd)->majorVersion = |
nlm_version_header (abfd)->majorVersion = |
425 |
|
|
426 |
amt = sizeof (thdr); |
amt = sizeof (thdr); |
427 |
if (bfd_bread ((PTR) &thdr, amt, abfd) != amt) |
if (bfd_bread ((PTR) &thdr, amt, abfd) != amt) |
428 |
return false; |
return FALSE; |
429 |
memcpy (nlm_extended_header (abfd)->stamp, thdr.stamp, |
memcpy (nlm_extended_header (abfd)->stamp, thdr.stamp, |
430 |
sizeof (thdr.stamp)); |
sizeof (thdr.stamp)); |
431 |
nlm_extended_header (abfd)->languageID = |
nlm_extended_header (abfd)->languageID = |
492 |
amt = sizeof (nlm_copyright_header (abfd)->stamp); |
amt = sizeof (nlm_copyright_header (abfd)->stamp); |
493 |
if (bfd_bread ((PTR) nlm_copyright_header (abfd)->stamp, |
if (bfd_bread ((PTR) nlm_copyright_header (abfd)->stamp, |
494 |
amt, abfd) != amt) |
amt, abfd) != amt) |
495 |
return false; |
return FALSE; |
496 |
if (bfd_bread ((PTR) &(nlm_copyright_header (abfd) |
if (bfd_bread ((PTR) &(nlm_copyright_header (abfd) |
497 |
->copyrightMessageLength), |
->copyrightMessageLength), |
498 |
(bfd_size_type) 1, abfd) != 1) |
(bfd_size_type) 1, abfd) != 1) |
499 |
return false; |
return FALSE; |
500 |
/* The copyright message is a variable length string. */ |
/* The copyright message is a variable length string. */ |
501 |
amt = nlm_copyright_header (abfd)->copyrightMessageLength + 1; |
amt = nlm_copyright_header (abfd)->copyrightMessageLength + 1; |
502 |
if (bfd_bread ((PTR) nlm_copyright_header (abfd)->copyrightMessage, |
if (bfd_bread ((PTR) nlm_copyright_header (abfd)->copyrightMessage, |
503 |
amt, abfd) != amt) |
amt, abfd) != amt) |
504 |
return false; |
return FALSE; |
505 |
} |
} |
506 |
else if (strncmp (tempstr, "CuStHeAd", 8) == 0) |
else if (strncmp (tempstr, "CuStHeAd", 8) == 0) |
507 |
{ |
{ |
515 |
/* Read the stamp ("CuStHeAd"). */ |
/* Read the stamp ("CuStHeAd"). */ |
516 |
amt = sizeof (thdr.stamp); |
amt = sizeof (thdr.stamp); |
517 |
if (bfd_bread ((PTR) thdr.stamp, amt, abfd) != amt) |
if (bfd_bread ((PTR) thdr.stamp, amt, abfd) != amt) |
518 |
return false; |
return FALSE; |
519 |
/* Read the length of this custom header. */ |
/* Read the length of this custom header. */ |
520 |
amt = sizeof (thdr.length); |
amt = sizeof (thdr.length); |
521 |
if (bfd_bread ((PTR) thdr.length, amt, abfd) != amt) |
if (bfd_bread ((PTR) thdr.length, amt, abfd) != amt) |
522 |
return false; |
return FALSE; |
523 |
hdrLength = get_word (abfd, (bfd_byte *) thdr.length); |
hdrLength = get_word (abfd, (bfd_byte *) thdr.length); |
524 |
/* Read further fields if we have them. */ |
/* Read further fields if we have them. */ |
525 |
if (hdrLength < NLM_TARGET_LONG_SIZE) |
if (hdrLength < NLM_TARGET_LONG_SIZE) |
528 |
{ |
{ |
529 |
amt = sizeof (thdr.dataOffset); |
amt = sizeof (thdr.dataOffset); |
530 |
if (bfd_bread ((PTR) thdr.dataOffset, amt, abfd) != amt) |
if (bfd_bread ((PTR) thdr.dataOffset, amt, abfd) != amt) |
531 |
return false; |
return FALSE; |
532 |
dataOffset = get_word (abfd, (bfd_byte *) thdr.dataOffset); |
dataOffset = get_word (abfd, (bfd_byte *) thdr.dataOffset); |
533 |
} |
} |
534 |
if (hdrLength < 2 * NLM_TARGET_LONG_SIZE) |
if (hdrLength < 2 * NLM_TARGET_LONG_SIZE) |
537 |
{ |
{ |
538 |
amt = sizeof (thdr.dataLength); |
amt = sizeof (thdr.dataLength); |
539 |
if (bfd_bread ((PTR) thdr.dataLength, amt, abfd) != amt) |
if (bfd_bread ((PTR) thdr.dataLength, amt, abfd) != amt) |
540 |
return false; |
return FALSE; |
541 |
dataLength = get_word (abfd, (bfd_byte *) thdr.dataLength); |
dataLength = get_word (abfd, (bfd_byte *) thdr.dataLength); |
542 |
} |
} |
543 |
if (hdrLength < 2 * NLM_TARGET_LONG_SIZE + 8) |
if (hdrLength < 2 * NLM_TARGET_LONG_SIZE + 8) |
546 |
{ |
{ |
547 |
amt = sizeof (dataStamp); |
amt = sizeof (dataStamp); |
548 |
if (bfd_bread ((PTR) dataStamp, amt, abfd) != amt) |
if (bfd_bread ((PTR) dataStamp, amt, abfd) != amt) |
549 |
return false; |
return FALSE; |
550 |
} |
} |
551 |
|
|
552 |
/* Read the rest of the header, if any. */ |
/* Read the rest of the header, if any. */ |
560 |
hdrLength -= 2 * NLM_TARGET_LONG_SIZE + 8; |
hdrLength -= 2 * NLM_TARGET_LONG_SIZE + 8; |
561 |
hdr = bfd_alloc (abfd, hdrLength); |
hdr = bfd_alloc (abfd, hdrLength); |
562 |
if (hdr == NULL) |
if (hdr == NULL) |
563 |
return false; |
return FALSE; |
564 |
if (bfd_bread (hdr, hdrLength, abfd) != hdrLength) |
if (bfd_bread (hdr, hdrLength, abfd) != hdrLength) |
565 |
return false; |
return FALSE; |
566 |
} |
} |
567 |
|
|
568 |
/* If we have found a Cygnus header, process it. Otherwise, |
/* If we have found a Cygnus header, process it. Otherwise, |
578 |
|
|
579 |
pos = bfd_tell (abfd); |
pos = bfd_tell (abfd); |
580 |
if (bfd_seek (abfd, dataOffset, SEEK_SET) != 0) |
if (bfd_seek (abfd, dataOffset, SEEK_SET) != 0) |
581 |
return false; |
return FALSE; |
582 |
contents = (bfd_byte *) bfd_alloc (abfd, dataLength); |
contents = (bfd_byte *) bfd_alloc (abfd, dataLength); |
583 |
if (contents == NULL) |
if (contents == NULL) |
584 |
return false; |
return FALSE; |
585 |
if (bfd_bread (contents, dataLength, abfd) != dataLength) |
if (bfd_bread (contents, dataLength, abfd) != dataLength) |
586 |
return false; |
return FALSE; |
587 |
if (bfd_seek (abfd, pos, SEEK_SET) != 0) |
if (bfd_seek (abfd, pos, SEEK_SET) != 0) |
588 |
return false; |
return FALSE; |
589 |
|
|
590 |
memcpy (nlm_cygnus_ext_header (abfd), "CyGnUsEx", 8); |
memcpy (nlm_cygnus_ext_header (abfd), "CyGnUsEx", 8); |
591 |
nlm_cygnus_ext_header (abfd)->offset = dataOffset; |
nlm_cygnus_ext_header (abfd)->offset = dataOffset; |
629 |
|
|
630 |
newsec = bfd_make_section_anyway (abfd, name); |
newsec = bfd_make_section_anyway (abfd, name); |
631 |
if (newsec == (asection *) NULL) |
if (newsec == (asection *) NULL) |
632 |
return false; |
return FALSE; |
633 |
newsec->_raw_size = size; |
newsec->size = size; |
634 |
if (filepos != 0) |
if (filepos != 0) |
635 |
{ |
{ |
636 |
newsec->filepos = filepos; |
newsec->filepos = filepos; |
651 |
} |
} |
652 |
} |
} |
653 |
else |
else |
654 |
{ |
break; |
|
break; |
|
|
} |
|
655 |
} |
} |
656 |
return true; |
return TRUE; |
657 |
} |
} |
658 |
|
|
659 |
/* Return whether there is a non-zero byte in a memory block. */ |
/* Return whether there is a non-zero byte in a memory block. */ |
660 |
|
|
661 |
static boolean |
static bfd_boolean |
662 |
find_nonzero (buf, size) |
find_nonzero (buf, size) |
663 |
PTR buf; |
PTR buf; |
664 |
size_t size; |
size_t size; |
667 |
|
|
668 |
while (size-- != 0) |
while (size-- != 0) |
669 |
if (*p++ != 0) |
if (*p++ != 0) |
670 |
return true; |
return TRUE; |
671 |
return false; |
return FALSE; |
672 |
} |
} |
673 |
|
|
674 |
/* Swap out the contents of the auxiliary headers. We create those |
/* Swap out the contents of the auxiliary headers. We create those |
675 |
auxiliary headers which have been set non-zero. We do not require |
auxiliary headers which have been set non-zero. We do not require |
676 |
the caller to set up the stamp fields. */ |
the caller to set up the stamp fields. */ |
677 |
|
|
678 |
static boolean |
static bfd_boolean |
679 |
nlm_swap_auxiliary_headers_out (abfd) |
nlm_swap_auxiliary_headers_out (abfd) |
680 |
bfd *abfd; |
bfd *abfd; |
681 |
{ |
{ |
702 |
(bfd_byte *) thdr.day); |
(bfd_byte *) thdr.day); |
703 |
if (bfd_bwrite ((PTR) &thdr, (bfd_size_type) sizeof (thdr), abfd) |
if (bfd_bwrite ((PTR) &thdr, (bfd_size_type) sizeof (thdr), abfd) |
704 |
!= sizeof (thdr)) |
!= sizeof (thdr)) |
705 |
return false; |
return FALSE; |
706 |
|
} |
707 |
|
|
708 |
|
/* Note - the CoPyRiGhT tag is emitted before the MeSsAgEs |
709 |
|
tag in order to make the NW4.x and NW5.x loaders happy. */ |
710 |
|
|
711 |
|
/* Write out the copyright header if there is one. */ |
712 |
|
if (find_nonzero ((PTR) nlm_copyright_header (abfd), |
713 |
|
sizeof (Nlm_Internal_Copyright_Header))) |
714 |
|
{ |
715 |
|
Nlm_External_Copyright_Header thdr; |
716 |
|
|
717 |
|
memcpy (thdr.stamp, "CoPyRiGhT=", 10); |
718 |
|
amt = sizeof (thdr.stamp); |
719 |
|
if (bfd_bwrite ((PTR) thdr.stamp, amt, abfd) != amt) |
720 |
|
return FALSE; |
721 |
|
thdr.copyrightMessageLength[0] = |
722 |
|
nlm_copyright_header (abfd)->copyrightMessageLength; |
723 |
|
amt = 1; |
724 |
|
if (bfd_bwrite ((PTR) thdr.copyrightMessageLength, amt, abfd) != amt) |
725 |
|
return FALSE; |
726 |
|
/* The copyright message is a variable length string. */ |
727 |
|
amt = nlm_copyright_header (abfd)->copyrightMessageLength + 1; |
728 |
|
if (bfd_bwrite ((PTR) nlm_copyright_header (abfd)->copyrightMessage, |
729 |
|
amt, abfd) != amt) |
730 |
|
return FALSE; |
731 |
} |
} |
732 |
|
|
733 |
/* Write out the extended header if there is one. */ |
/* Write out the extended header if there is one. */ |
826 |
(bfd_byte *) thdr.reserved5); |
(bfd_byte *) thdr.reserved5); |
827 |
if (bfd_bwrite ((PTR) &thdr, (bfd_size_type) sizeof (thdr), abfd) |
if (bfd_bwrite ((PTR) &thdr, (bfd_size_type) sizeof (thdr), abfd) |
828 |
!= sizeof (thdr)) |
!= sizeof (thdr)) |
829 |
return false; |
return FALSE; |
|
} |
|
|
|
|
|
/* Write out the copyright header if there is one. */ |
|
|
if (find_nonzero ((PTR) nlm_copyright_header (abfd), |
|
|
sizeof (Nlm_Internal_Copyright_Header))) |
|
|
{ |
|
|
Nlm_External_Copyright_Header thdr; |
|
|
|
|
|
memcpy (thdr.stamp, "CoPyRiGhT=", 10); |
|
|
amt = sizeof (thdr.stamp); |
|
|
if (bfd_bwrite ((PTR) thdr.stamp, amt, abfd) != amt) |
|
|
return false; |
|
|
thdr.copyrightMessageLength[0] = |
|
|
nlm_copyright_header (abfd)->copyrightMessageLength; |
|
|
amt = 1; |
|
|
if (bfd_bwrite ((PTR) thdr.copyrightMessageLength, amt, abfd) != amt) |
|
|
return false; |
|
|
/* The copyright message is a variable length string. */ |
|
|
amt = nlm_copyright_header (abfd)->copyrightMessageLength + 1; |
|
|
if (bfd_bwrite ((PTR) nlm_copyright_header (abfd)->copyrightMessage, |
|
|
amt, abfd) != amt) |
|
|
return false; |
|
830 |
} |
} |
831 |
|
|
832 |
/* Write out the custom header if there is one. */ |
/* Write out the custom header if there is one. */ |
834 |
sizeof (Nlm_Internal_Custom_Header))) |
sizeof (Nlm_Internal_Custom_Header))) |
835 |
{ |
{ |
836 |
Nlm_External_Custom_Header thdr; |
Nlm_External_Custom_Header thdr; |
837 |
boolean ds; |
bfd_boolean ds; |
838 |
bfd_size_type hdrLength; |
bfd_size_type hdrLength; |
839 |
|
|
840 |
ds = find_nonzero ((PTR) nlm_custom_header (abfd)->dataStamp, |
ds = find_nonzero ((PTR) nlm_custom_header (abfd)->dataStamp, |
852 |
BFD_ASSERT (nlm_custom_header (abfd)->hdrLength == 0); |
BFD_ASSERT (nlm_custom_header (abfd)->hdrLength == 0); |
853 |
amt = sizeof (thdr) - sizeof (thdr.dataStamp); |
amt = sizeof (thdr) - sizeof (thdr.dataStamp); |
854 |
if (bfd_bwrite ((PTR) &thdr, amt, abfd) != amt) |
if (bfd_bwrite ((PTR) &thdr, amt, abfd) != amt) |
855 |
return false; |
return FALSE; |
856 |
} |
} |
857 |
else |
else |
858 |
{ |
{ |
860 |
sizeof (thdr.dataStamp)); |
sizeof (thdr.dataStamp)); |
861 |
amt = sizeof (thdr); |
amt = sizeof (thdr); |
862 |
if (bfd_bwrite ((PTR) &thdr, amt, abfd) != amt) |
if (bfd_bwrite ((PTR) &thdr, amt, abfd) != amt) |
863 |
return false; |
return FALSE; |
864 |
amt = nlm_custom_header (abfd)->hdrLength; |
amt = nlm_custom_header (abfd)->hdrLength; |
865 |
if (bfd_bwrite (nlm_custom_header (abfd)->hdr, amt, abfd) != amt) |
if (bfd_bwrite (nlm_custom_header (abfd)->hdr, amt, abfd) != amt) |
866 |
return false; |
return FALSE; |
867 |
} |
} |
868 |
} |
} |
869 |
|
|
883 |
memcpy (thdr.dataStamp, "CyGnUsEx", 8); |
memcpy (thdr.dataStamp, "CyGnUsEx", 8); |
884 |
amt = sizeof (thdr); |
amt = sizeof (thdr); |
885 |
if (bfd_bwrite ((PTR) &thdr, amt, abfd) != amt) |
if (bfd_bwrite ((PTR) &thdr, amt, abfd) != amt) |
886 |
return false; |
return FALSE; |
887 |
} |
} |
888 |
|
|
889 |
return true; |
return TRUE; |
890 |
} |
} |
891 |
|
|
892 |
/* We read the NLM's public symbols and use it to generate a bfd symbol |
/* We read the NLM's public symbols and use it to generate a bfd symbol |
902 |
nlm_get_symtab_upper_bound (abfd) |
nlm_get_symtab_upper_bound (abfd) |
903 |
bfd *abfd; |
bfd *abfd; |
904 |
{ |
{ |
905 |
Nlm_Internal_Fixed_Header *i_fxdhdrp; /* Nlm file header, internal form */ |
Nlm_Internal_Fixed_Header *i_fxdhdrp; /* Nlm file header, internal form. */ |
906 |
long symcount; |
long symcount; |
907 |
long symtab_size = 0; |
long symtab_size = 0; |
908 |
|
|
918 |
symbol table fails. */ |
symbol table fails. */ |
919 |
|
|
920 |
long |
long |
921 |
nlm_get_symtab (abfd, alocation) |
nlm_canonicalize_symtab (abfd, alocation) |
922 |
bfd *abfd; |
bfd *abfd; |
923 |
asymbol **alocation; |
asymbol **alocation; |
924 |
{ |
{ |
1007 |
The bfd symbols are copied to SYMPTRS. |
The bfd symbols are copied to SYMPTRS. |
1008 |
|
|
1009 |
When we return, the bfd symcount is either zero or contains the correct |
When we return, the bfd symcount is either zero or contains the correct |
1010 |
number of symbols. |
number of symbols. */ |
|
*/ |
|
1011 |
|
|
1012 |
static boolean |
static bfd_boolean |
1013 |
nlm_slurp_symbol_table (abfd) |
nlm_slurp_symbol_table (abfd) |
1014 |
bfd *abfd; |
bfd *abfd; |
1015 |
{ |
{ |
1016 |
Nlm_Internal_Fixed_Header *i_fxdhdrp; /* Nlm file header, internal form */ |
Nlm_Internal_Fixed_Header *i_fxdhdrp; /* Nlm file header, internal form. */ |
1017 |
bfd_size_type totsymcount; /* Number of NLM symbols */ |
bfd_size_type totsymcount; /* Number of NLM symbols. */ |
1018 |
bfd_size_type symcount; /* Counter of NLM symbols */ |
bfd_size_type symcount; /* Counter of NLM symbols. */ |
1019 |
nlm_symbol_type *sym; /* Pointer to current bfd symbol */ |
nlm_symbol_type *sym; /* Pointer to current bfd symbol. */ |
1020 |
unsigned char symlength; /* Symbol length read into here */ |
unsigned char symlength; /* Symbol length read into here. */ |
1021 |
unsigned char symtype; /* Type of debugging symbol */ |
unsigned char symtype; /* Type of debugging symbol. */ |
1022 |
bfd_byte temp[NLM_TARGET_LONG_SIZE]; /* Symbol offsets read into here */ |
bfd_byte temp[NLM_TARGET_LONG_SIZE]; /* Symbol offsets read into here. */ |
1023 |
boolean (*read_import_func) PARAMS ((bfd *, nlm_symbol_type *)); |
bfd_boolean (*read_import_func) PARAMS ((bfd *, nlm_symbol_type *)); |
1024 |
boolean (*set_public_section_func) PARAMS ((bfd *, nlm_symbol_type *)); |
bfd_boolean (*set_public_section_func) PARAMS ((bfd *, nlm_symbol_type *)); |
1025 |
bfd_size_type amt; |
bfd_size_type amt; |
1026 |
|
|
1027 |
if (nlm_get_symbols (abfd) != NULL) |
if (nlm_get_symbols (abfd) != NULL) |
1028 |
return true; |
return TRUE; |
1029 |
|
|
1030 |
/* Read each raw NLM symbol, using the information to create a canonical bfd |
/* Read each raw NLM symbol, using the information to create a canonical bfd |
1031 |
symbol table entry. |
symbol table entry. |
1041 |
+ i_fxdhdrp->numberOfDebugRecords |
+ i_fxdhdrp->numberOfDebugRecords |
1042 |
+ i_fxdhdrp->numberOfExternalReferences); |
+ i_fxdhdrp->numberOfExternalReferences); |
1043 |
if (totsymcount == 0) |
if (totsymcount == 0) |
1044 |
{ |
return TRUE; |
|
return true; |
|
|
} |
|
1045 |
|
|
1046 |
if (bfd_seek (abfd, i_fxdhdrp->publicsOffset, SEEK_SET) != 0) |
if (bfd_seek (abfd, i_fxdhdrp->publicsOffset, SEEK_SET) != 0) |
1047 |
return false; |
return FALSE; |
1048 |
|
|
1049 |
amt = totsymcount * sizeof (nlm_symbol_type); |
amt = totsymcount * sizeof (nlm_symbol_type); |
1050 |
sym = ((nlm_symbol_type *) bfd_zalloc (abfd, amt)); |
sym = ((nlm_symbol_type *) bfd_zalloc (abfd, amt)); |
1051 |
if (!sym) |
if (!sym) |
1052 |
return false; |
return FALSE; |
1053 |
nlm_set_symbols (abfd, sym); |
nlm_set_symbols (abfd, sym); |
1054 |
|
|
1055 |
/* We use the bfd's symcount directly as the control count, so that early |
/* We use the bfd's symcount directly as the control count, so that early |
1062 |
{ |
{ |
1063 |
amt = sizeof (symlength); |
amt = sizeof (symlength); |
1064 |
if (bfd_bread ((PTR) &symlength, amt, abfd) != amt) |
if (bfd_bread ((PTR) &symlength, amt, abfd) != amt) |
1065 |
return false; |
return FALSE; |
1066 |
amt = symlength; |
amt = symlength; |
1067 |
sym->symbol.the_bfd = abfd; |
sym->symbol.the_bfd = abfd; |
1068 |
sym->symbol.name = bfd_alloc (abfd, amt + 1); |
sym->symbol.name = bfd_alloc (abfd, amt + 1); |
1069 |
if (!sym->symbol.name) |
if (!sym->symbol.name) |
1070 |
return false; |
return FALSE; |
1071 |
if (bfd_bread ((PTR) sym->symbol.name, amt, abfd) != amt) |
if (bfd_bread ((PTR) sym->symbol.name, amt, abfd) != amt) |
1072 |
return false; |
return FALSE; |
1073 |
/* Cast away const. */ |
/* Cast away const. */ |
1074 |
((char *) (sym->symbol.name))[symlength] = '\0'; |
((char *) (sym->symbol.name))[symlength] = '\0'; |
1075 |
amt = sizeof (temp); |
amt = sizeof (temp); |
1076 |
if (bfd_bread ((PTR) temp, amt, abfd) != amt) |
if (bfd_bread ((PTR) temp, amt, abfd) != amt) |
1077 |
return false; |
return FALSE; |
1078 |
sym->symbol.flags = BSF_GLOBAL | BSF_EXPORT; |
sym->symbol.flags = BSF_GLOBAL | BSF_EXPORT; |
1079 |
sym->symbol.value = get_word (abfd, temp); |
sym->symbol.value = get_word (abfd, temp); |
1080 |
if (set_public_section_func) |
if (set_public_section_func) |
1082 |
/* Most backends can use the code below, but unfortunately |
/* Most backends can use the code below, but unfortunately |
1083 |
some use a different scheme. */ |
some use a different scheme. */ |
1084 |
if (! (*set_public_section_func) (abfd, sym)) |
if (! (*set_public_section_func) (abfd, sym)) |
1085 |
return false; |
return FALSE; |
1086 |
} |
} |
1087 |
else |
else |
1088 |
{ |
{ |
1109 |
if (i_fxdhdrp->numberOfDebugRecords > 0) |
if (i_fxdhdrp->numberOfDebugRecords > 0) |
1110 |
{ |
{ |
1111 |
if (bfd_seek (abfd, i_fxdhdrp->debugInfoOffset, SEEK_SET) != 0) |
if (bfd_seek (abfd, i_fxdhdrp->debugInfoOffset, SEEK_SET) != 0) |
1112 |
return false; |
return FALSE; |
1113 |
|
|
1114 |
symcount += i_fxdhdrp->numberOfDebugRecords; |
symcount += i_fxdhdrp->numberOfDebugRecords; |
1115 |
while (abfd->symcount < symcount) |
while (abfd->symcount < symcount) |
1116 |
{ |
{ |
1117 |
amt = sizeof (symtype); |
amt = sizeof (symtype); |
1118 |
if (bfd_bread ((PTR) &symtype, amt, abfd) != amt) |
if (bfd_bread ((PTR) &symtype, amt, abfd) != amt) |
1119 |
return false; |
return FALSE; |
1120 |
amt = sizeof (temp); |
amt = sizeof (temp); |
1121 |
if (bfd_bread ((PTR) temp, amt, abfd) != amt) |
if (bfd_bread ((PTR) temp, amt, abfd) != amt) |
1122 |
return false; |
return FALSE; |
1123 |
amt = sizeof (symlength); |
amt = sizeof (symlength); |
1124 |
if (bfd_bread ((PTR) &symlength, amt, abfd) != amt) |
if (bfd_bread ((PTR) &symlength, amt, abfd) != amt) |
1125 |
return false; |
return FALSE; |
1126 |
amt = symlength; |
amt = symlength; |
1127 |
sym->symbol.the_bfd = abfd; |
sym->symbol.the_bfd = abfd; |
1128 |
sym->symbol.name = bfd_alloc (abfd, amt + 1); |
sym->symbol.name = bfd_alloc (abfd, amt + 1); |
1129 |
if (!sym->symbol.name) |
if (!sym->symbol.name) |
1130 |
return false; |
return FALSE; |
1131 |
if (bfd_bread ((PTR) sym->symbol.name, amt, abfd) != amt) |
if (bfd_bread ((PTR) sym->symbol.name, amt, abfd) != amt) |
1132 |
return false; |
return FALSE; |
1133 |
/* Cast away const. */ |
/* Cast away const. */ |
1134 |
((char *) (sym->symbol.name))[symlength] = '\0'; |
((char *) (sym->symbol.name))[symlength] = '\0'; |
1135 |
sym->symbol.flags = BSF_LOCAL; |
sym->symbol.flags = BSF_LOCAL; |
1157 |
|
|
1158 |
/* Read in the import records. We can only do this if we know how |
/* Read in the import records. We can only do this if we know how |
1159 |
to read relocs for this target. */ |
to read relocs for this target. */ |
|
|
|
1160 |
read_import_func = nlm_read_import_func (abfd); |
read_import_func = nlm_read_import_func (abfd); |
1161 |
if (read_import_func != NULL) |
if (read_import_func != NULL) |
1162 |
{ |
{ |
1163 |
if (bfd_seek (abfd, i_fxdhdrp->externalReferencesOffset, SEEK_SET) != 0) |
if (bfd_seek (abfd, i_fxdhdrp->externalReferencesOffset, SEEK_SET) != 0) |
1164 |
return false; |
return FALSE; |
1165 |
|
|
1166 |
symcount += i_fxdhdrp->numberOfExternalReferences; |
symcount += i_fxdhdrp->numberOfExternalReferences; |
1167 |
while (abfd->symcount < symcount) |
while (abfd->symcount < symcount) |
1168 |
{ |
{ |
1169 |
if (! (*read_import_func) (abfd, sym)) |
if (! (*read_import_func) (abfd, sym)) |
1170 |
return false; |
return FALSE; |
1171 |
sym++; |
sym++; |
1172 |
abfd->symcount++; |
abfd->symcount++; |
1173 |
} |
} |
1174 |
} |
} |
1175 |
|
|
1176 |
return true; |
return TRUE; |
1177 |
} |
} |
1178 |
|
|
1179 |
/* Get the relocs for an NLM file. There are two types of relocs. |
/* Get the relocs for an NLM file. There are two types of relocs. |
1189 |
section pointers are needed because the relocs are not sorted by |
section pointers are needed because the relocs are not sorted by |
1190 |
section. */ |
section. */ |
1191 |
|
|
1192 |
static boolean |
static bfd_boolean |
1193 |
nlm_slurp_reloc_fixups (abfd) |
nlm_slurp_reloc_fixups (abfd) |
1194 |
bfd *abfd; |
bfd *abfd; |
1195 |
{ |
{ |
1196 |
boolean (*read_func) PARAMS ((bfd *, nlm_symbol_type *, asection **, |
bfd_boolean (*read_func) |
1197 |
arelent *)); |
PARAMS ((bfd *, nlm_symbol_type *, asection **, arelent *)); |
1198 |
bfd_size_type count, amt; |
bfd_size_type count, amt; |
1199 |
arelent *rels; |
arelent *rels; |
1200 |
asection **secs; |
asection **secs; |
1201 |
|
|
1202 |
if (nlm_relocation_fixups (abfd) != NULL) |
if (nlm_relocation_fixups (abfd) != NULL) |
1203 |
return true; |
return TRUE; |
1204 |
read_func = nlm_read_reloc_func (abfd); |
read_func = nlm_read_reloc_func (abfd); |
1205 |
if (read_func == NULL) |
if (read_func == NULL) |
1206 |
return true; |
return TRUE; |
1207 |
|
|
1208 |
if (bfd_seek (abfd, nlm_fixed_header (abfd)->relocationFixupOffset, |
if (bfd_seek (abfd, nlm_fixed_header (abfd)->relocationFixupOffset, |
1209 |
SEEK_SET) != 0) |
SEEK_SET) != 0) |
1210 |
return false; |
return FALSE; |
1211 |
|
|
1212 |
count = nlm_fixed_header (abfd)->numberOfRelocationFixups; |
count = nlm_fixed_header (abfd)->numberOfRelocationFixups; |
1213 |
amt = count * sizeof (arelent); |
amt = count * sizeof (arelent); |
1215 |
amt = count * sizeof (asection *); |
amt = count * sizeof (asection *); |
1216 |
secs = (asection **) bfd_alloc (abfd, amt); |
secs = (asection **) bfd_alloc (abfd, amt); |
1217 |
if ((rels == NULL || secs == NULL) && count != 0) |
if ((rels == NULL || secs == NULL) && count != 0) |
1218 |
return false; |
return FALSE; |
1219 |
nlm_relocation_fixups (abfd) = rels; |
nlm_relocation_fixups (abfd) = rels; |
1220 |
nlm_relocation_fixup_secs (abfd) = secs; |
nlm_relocation_fixup_secs (abfd) = secs; |
1221 |
|
|
1227 |
{ |
{ |
1228 |
nlm_relocation_fixups (abfd) = NULL; |
nlm_relocation_fixups (abfd) = NULL; |
1229 |
nlm_relocation_fixup_secs (abfd) = NULL; |
nlm_relocation_fixup_secs (abfd) = NULL; |
1230 |
return false; |
return FALSE; |
1231 |
} |
} |
1232 |
++secs; |
++secs; |
1233 |
++rels; |
++rels; |
1234 |
} |
} |
1235 |
|
|
1236 |
return true; |
return TRUE; |
1237 |
} |
} |
1238 |
|
|
1239 |
/* Get the number of relocs. This really just returns an upper bound, |
/* Get the number of relocs. This really just returns an upper bound, |
1358 |
move the symbols at this point so that mangle_relocs can see the |
move the symbols at this point so that mangle_relocs can see the |
1359 |
final values. */ |
final values. */ |
1360 |
|
|
1361 |
static boolean |
static bfd_boolean |
1362 |
nlm_compute_section_file_positions (abfd) |
nlm_compute_section_file_positions (abfd) |
1363 |
bfd *abfd; |
bfd *abfd; |
1364 |
{ |
{ |
1372 |
asymbol **sym_ptr_ptr; |
asymbol **sym_ptr_ptr; |
1373 |
|
|
1374 |
if (abfd->output_has_begun) |
if (abfd->output_has_begun) |
1375 |
return true; |
return TRUE; |
1376 |
|
|
1377 |
/* Make sure we have a section to hold uninitialized data. */ |
/* Make sure we have a section to hold uninitialized data. */ |
1378 |
bss_sec = bfd_get_section_by_name (abfd, NLM_UNINITIALIZED_DATA_NAME); |
bss_sec = bfd_get_section_by_name (abfd, NLM_UNINITIALIZED_DATA_NAME); |
1381 |
if (!add_bfd_section (abfd, NLM_UNINITIALIZED_DATA_NAME, |
if (!add_bfd_section (abfd, NLM_UNINITIALIZED_DATA_NAME, |
1382 |
(file_ptr) 0, (bfd_size_type) 0, |
(file_ptr) 0, (bfd_size_type) 0, |
1383 |
SEC_ALLOC)) |
SEC_ALLOC)) |
1384 |
return false; |
return FALSE; |
1385 |
bss_sec = bfd_get_section_by_name (abfd, NLM_UNINITIALIZED_DATA_NAME); |
bss_sec = bfd_get_section_by_name (abfd, NLM_UNINITIALIZED_DATA_NAME); |
1386 |
} |
} |
1387 |
|
|
1388 |
abfd->output_has_begun = true; |
abfd->output_has_begun = TRUE; |
1389 |
|
|
1390 |
/* The fixed header. */ |
/* The fixed header. */ |
1391 |
sofar = nlm_optional_prefix_size (abfd) + nlm_fixed_header_size (abfd); |
sofar = nlm_optional_prefix_size (abfd) + nlm_fixed_header_size (abfd); |
1437 |
{ |
{ |
1438 |
flagword f; |
flagword f; |
1439 |
|
|
1440 |
sec->_raw_size = BFD_ALIGN (sec->_raw_size, 1 << sec->alignment_power); |
sec->size = BFD_ALIGN (sec->size, 1 << sec->alignment_power); |
1441 |
|
|
1442 |
f = bfd_get_section_flags (abfd, sec); |
f = bfd_get_section_flags (abfd, sec); |
1443 |
if (f & SEC_CODE) |
if (f & SEC_CODE) |
1444 |
{ |
{ |
1445 |
text += sec->_raw_size; |
text += sec->size; |
1446 |
if (bfd_get_section_vma (abfd, sec) < text_low) |
if (bfd_get_section_vma (abfd, sec) < text_low) |
1447 |
text_low = bfd_get_section_vma (abfd, sec); |
text_low = bfd_get_section_vma (abfd, sec); |
1448 |
if (sec->alignment_power > text_align) |
if (sec->alignment_power > text_align) |
1450 |
} |
} |
1451 |
else if (f & SEC_DATA) |
else if (f & SEC_DATA) |
1452 |
{ |
{ |
1453 |
data += sec->_raw_size; |
data += sec->size; |
1454 |
if (bfd_get_section_vma (abfd, sec) < data_low) |
if (bfd_get_section_vma (abfd, sec) < data_low) |
1455 |
data_low = bfd_get_section_vma (abfd, sec); |
data_low = bfd_get_section_vma (abfd, sec); |
1456 |
if (sec->alignment_power > data_align) |
if (sec->alignment_power > data_align) |
1462 |
other_align = sec->alignment_power; |
other_align = sec->alignment_power; |
1463 |
} |
} |
1464 |
else if (f & SEC_ALLOC) |
else if (f & SEC_ALLOC) |
1465 |
bss += sec->_raw_size; |
bss += sec->size; |
1466 |
} |
} |
1467 |
|
|
1468 |
nlm_set_text_low (abfd, text_low); |
nlm_set_text_low (abfd, text_low); |
1498 |
if (f & SEC_CODE) |
if (f & SEC_CODE) |
1499 |
{ |
{ |
1500 |
sec->filepos = text_ptr; |
sec->filepos = text_ptr; |
1501 |
text_ptr += sec->_raw_size; |
text_ptr += sec->size; |
1502 |
} |
} |
1503 |
else if (f & SEC_DATA) |
else if (f & SEC_DATA) |
1504 |
{ |
{ |
1505 |
sec->filepos = data_ptr; |
sec->filepos = data_ptr; |
1506 |
data_ptr += sec->_raw_size; |
data_ptr += sec->size; |
1507 |
} |
} |
1508 |
else if (f & SEC_HAS_CONTENTS) |
else if (f & SEC_HAS_CONTENTS) |
1509 |
{ |
{ |
1510 |
sec->filepos = other_ptr; |
sec->filepos = other_ptr; |
1511 |
other_ptr += sec->_raw_size; |
other_ptr += sec->size; |
1512 |
} |
} |
1513 |
} |
} |
1514 |
|
|
1539 |
symbol (which is the old value of the symbol). */ |
symbol (which is the old value of the symbol). */ |
1540 |
sym->section = bss_sec; |
sym->section = bss_sec; |
1541 |
size = sym->value; |
size = sym->value; |
1542 |
sym->value = bss_sec->_raw_size + add; |
sym->value = bss_sec->size + add; |
1543 |
add += size; |
add += size; |
1544 |
add = BFD_ALIGN (add, 1 << bss_sec->alignment_power); |
add = BFD_ALIGN (add, 1 << bss_sec->alignment_power); |
1545 |
} |
} |
1552 |
abort (); |
abort (); |
1553 |
} |
} |
1554 |
nlm_fixed_header (abfd)->uninitializedDataSize += add; |
nlm_fixed_header (abfd)->uninitializedDataSize += add; |
1555 |
bss_sec->_raw_size += add; |
bss_sec->size += add; |
1556 |
} |
} |
1557 |
} |
} |
1558 |
|
|
1559 |
return true; |
return TRUE; |
1560 |
} |
} |
1561 |
|
|
1562 |
/* Set the contents of a section. To do this we need to know where |
/* Set the contents of a section. To do this we need to know where |
1564 |
that the sizes of all the sections must be set, and all the |
that the sizes of all the sections must be set, and all the |
1565 |
variable size header information must be known. */ |
variable size header information must be known. */ |
1566 |
|
|
1567 |
boolean |
bfd_boolean |
1568 |
nlm_set_section_contents (abfd, section, location, offset, count) |
nlm_set_section_contents (abfd, section, location, offset, count) |
1569 |
bfd *abfd; |
bfd *abfd; |
1570 |
asection *section; |
asection *section; |
1571 |
PTR location; |
const PTR location; |
1572 |
file_ptr offset; |
file_ptr offset; |
1573 |
bfd_size_type count; |
bfd_size_type count; |
1574 |
{ |
{ |
1575 |
if (! abfd->output_has_begun |
if (! abfd->output_has_begun |
1576 |
&& ! nlm_compute_section_file_positions (abfd)) |
&& ! nlm_compute_section_file_positions (abfd)) |
1577 |
return false; |
return FALSE; |
1578 |
|
|
1579 |
if (count == 0) |
if (count == 0) |
1580 |
return true; |
return TRUE; |
1581 |
|
|
1582 |
/* i386 NetWare has a very restricted set of relocs. In order for |
/* i386 NetWare has a very restricted set of relocs. In order for |
1583 |
objcopy to work, the NLM i386 backend needs a chance to rework |
objcopy to work, the NLM i386 backend needs a chance to rework |
1585 |
the relocs are already acceptable, this will not do anything. */ |
the relocs are already acceptable, this will not do anything. */ |
1586 |
if (section->reloc_count != 0) |
if (section->reloc_count != 0) |
1587 |
{ |
{ |
1588 |
boolean (*mangle_relocs_func) PARAMS ((bfd *, asection *, PTR, |
bfd_boolean (*mangle_relocs_func) |
1589 |
bfd_vma, bfd_size_type)); |
PARAMS ((bfd *, asection *, const PTR, bfd_vma, bfd_size_type)); |
1590 |
|
|
1591 |
mangle_relocs_func = nlm_mangle_relocs_func (abfd); |
mangle_relocs_func = nlm_mangle_relocs_func (abfd); |
1592 |
if (mangle_relocs_func != NULL) |
if (mangle_relocs_func != NULL) |
1593 |
{ |
{ |
1594 |
if (!(*mangle_relocs_func) (abfd, section, location, |
if (!(*mangle_relocs_func) (abfd, section, location, |
1595 |
(bfd_vma) offset, count)) |
(bfd_vma) offset, count)) |
1596 |
return false; |
return FALSE; |
1597 |
} |
} |
1598 |
} |
} |
1599 |
|
|
1600 |
if (bfd_seek (abfd, section->filepos + offset, SEEK_SET) != 0 |
if (bfd_seek (abfd, section->filepos + offset, SEEK_SET) != 0 |
1601 |
|| bfd_bwrite (location, count, abfd) != count) |
|| bfd_bwrite (location, count, abfd) != count) |
1602 |
return false; |
return FALSE; |
1603 |
|
|
1604 |
return true; |
return TRUE; |
1605 |
} |
} |
1606 |
|
|
1607 |
/* We need to sort a list of relocs associated with sections when we |
/* We need to sort a list of relocs associated with sections when we |
1655 |
section. The exports and debugging records are obtained from the |
section. The exports and debugging records are obtained from the |
1656 |
list of outsymbols. */ |
list of outsymbols. */ |
1657 |
|
|
1658 |
boolean |
bfd_boolean |
1659 |
nlm_write_object_contents (abfd) |
nlm_write_object_contents (abfd) |
1660 |
bfd *abfd; |
bfd *abfd; |
1661 |
{ |
{ |
1662 |
asection *sec; |
asection *sec; |
1663 |
boolean (*write_import_func) PARAMS ((bfd *, asection *, arelent *)); |
bfd_boolean (*write_import_func) PARAMS ((bfd *, asection *, arelent *)); |
1664 |
bfd_size_type external_reloc_count, internal_reloc_count, i, c; |
bfd_size_type external_reloc_count, internal_reloc_count, i, c; |
1665 |
struct reloc_and_sec *external_relocs; |
struct reloc_and_sec *external_relocs; |
1666 |
asymbol **sym_ptr_ptr; |
asymbol **sym_ptr_ptr; |
1667 |
file_ptr last; |
file_ptr last; |
1668 |
boolean (*write_prefix_func) PARAMS ((bfd *)); |
bfd_boolean (*write_prefix_func) PARAMS ((bfd *)); |
1669 |
unsigned char *fixed_header = NULL; |
unsigned char *fixed_header = NULL; |
1670 |
file_ptr pos; |
file_ptr pos; |
1671 |
bfd_size_type amt; |
bfd_size_type amt; |
1692 |
|
|
1693 |
/* A weak check on whether the section file positions were |
/* A weak check on whether the section file positions were |
1694 |
reasonable. */ |
reasonable. */ |
1695 |
if (bfd_tell (abfd) > (ufile_ptr) nlm_fixed_header (abfd)->codeImageOffset) |
if (bfd_tell (abfd) > nlm_fixed_header (abfd)->codeImageOffset) |
1696 |
{ |
{ |
1697 |
bfd_set_error (bfd_error_invalid_operation); |
bfd_set_error (bfd_error_invalid_operation); |
1698 |
goto error_return; |
goto error_return; |
1831 |
if (sym_ptr_ptr != (asymbol **) NULL) |
if (sym_ptr_ptr != (asymbol **) NULL) |
1832 |
{ |
{ |
1833 |
bfd_vma (*get_public_offset_func) PARAMS ((bfd *, asymbol *)); |
bfd_vma (*get_public_offset_func) PARAMS ((bfd *, asymbol *)); |
1834 |
boolean (*write_export_func) PARAMS ((bfd *, asymbol *, bfd_vma)); |
bfd_boolean (*write_export_func) PARAMS ((bfd *, asymbol *, bfd_vma)); |
1835 |
|
|
1836 |
asymbol **sym_end; |
asymbol **sym_end; |
1837 |
|
|
2034 |
|
|
2035 |
if (fixed_header != NULL) |
if (fixed_header != NULL) |
2036 |
free (fixed_header); |
free (fixed_header); |
2037 |
return true; |
return TRUE; |
2038 |
|
|
2039 |
error_return: |
error_return: |
2040 |
if (fixed_header != NULL) |
if (fixed_header != NULL) |
2041 |
free (fixed_header); |
free (fixed_header); |
2042 |
return false; |
return FALSE; |
2043 |
} |
} |