1 |
/* BFD backend for SunOS binaries. |
/* BFD backend for SunOS binaries. |
2 |
Copyright 1990, 1991, 1992, 1994, 1995, 1996, 1997, 1998, 2000, 2001, |
Copyright 1990, 1991, 1992, 1994, 1995, 1996, 1997, 1998, 1999, 2000, |
3 |
2002 |
2001, 2002, 2003, 2004 Free Software Foundation, Inc. |
|
Free Software Foundation, Inc. |
|
4 |
Written by Cygnus Support. |
Written by Cygnus Support. |
5 |
|
|
6 |
This file is part of BFD, the Binary File Descriptor library. |
This file is part of BFD, the Binary File Descriptor library. |
32 |
|
|
33 |
/* Static routines defined in this file. */ |
/* Static routines defined in this file. */ |
34 |
|
|
35 |
static boolean sunos_read_dynamic_info PARAMS ((bfd *)); |
static bfd_boolean sunos_read_dynamic_info PARAMS ((bfd *)); |
36 |
static long sunos_get_dynamic_symtab_upper_bound PARAMS ((bfd *)); |
static long sunos_get_dynamic_symtab_upper_bound PARAMS ((bfd *)); |
37 |
static boolean sunos_slurp_dynamic_symtab PARAMS ((bfd *)); |
static bfd_boolean sunos_slurp_dynamic_symtab PARAMS ((bfd *)); |
38 |
static long sunos_canonicalize_dynamic_symtab PARAMS ((bfd *, asymbol **)); |
static long sunos_canonicalize_dynamic_symtab PARAMS ((bfd *, asymbol **)); |
39 |
static long sunos_get_dynamic_reloc_upper_bound PARAMS ((bfd *)); |
static long sunos_get_dynamic_reloc_upper_bound PARAMS ((bfd *)); |
40 |
static long sunos_canonicalize_dynamic_reloc |
static long sunos_canonicalize_dynamic_reloc |
43 |
PARAMS ((struct bfd_hash_entry *, struct bfd_hash_table *, const char *)); |
PARAMS ((struct bfd_hash_entry *, struct bfd_hash_table *, const char *)); |
44 |
static struct bfd_link_hash_table *sunos_link_hash_table_create |
static struct bfd_link_hash_table *sunos_link_hash_table_create |
45 |
PARAMS ((bfd *)); |
PARAMS ((bfd *)); |
46 |
static boolean sunos_create_dynamic_sections |
static bfd_boolean sunos_create_dynamic_sections |
47 |
PARAMS ((bfd *, struct bfd_link_info *, boolean)); |
PARAMS ((bfd *, struct bfd_link_info *, bfd_boolean)); |
48 |
static boolean sunos_add_dynamic_symbols |
static bfd_boolean sunos_add_dynamic_symbols |
49 |
PARAMS ((bfd *, struct bfd_link_info *, struct external_nlist **, |
PARAMS ((bfd *, struct bfd_link_info *, struct external_nlist **, |
50 |
bfd_size_type *, char **)); |
bfd_size_type *, char **)); |
51 |
static boolean sunos_add_one_symbol |
static bfd_boolean sunos_add_one_symbol |
52 |
PARAMS ((struct bfd_link_info *, bfd *, const char *, flagword, asection *, |
PARAMS ((struct bfd_link_info *, bfd *, const char *, flagword, asection *, |
53 |
bfd_vma, const char *, boolean, boolean, |
bfd_vma, const char *, bfd_boolean, bfd_boolean, |
54 |
struct bfd_link_hash_entry **)); |
struct bfd_link_hash_entry **)); |
55 |
static boolean sunos_scan_relocs |
static bfd_boolean sunos_scan_relocs |
56 |
PARAMS ((struct bfd_link_info *, bfd *, asection *, bfd_size_type)); |
PARAMS ((struct bfd_link_info *, bfd *, asection *, bfd_size_type)); |
57 |
static boolean sunos_scan_std_relocs |
static bfd_boolean sunos_scan_std_relocs |
58 |
PARAMS ((struct bfd_link_info *, bfd *, asection *, |
PARAMS ((struct bfd_link_info *, bfd *, asection *, |
59 |
const struct reloc_std_external *, bfd_size_type)); |
const struct reloc_std_external *, bfd_size_type)); |
60 |
static boolean sunos_scan_ext_relocs |
static bfd_boolean sunos_scan_ext_relocs |
61 |
PARAMS ((struct bfd_link_info *, bfd *, asection *, |
PARAMS ((struct bfd_link_info *, bfd *, asection *, |
62 |
const struct reloc_ext_external *, bfd_size_type)); |
const struct reloc_ext_external *, bfd_size_type)); |
63 |
static boolean sunos_link_dynamic_object |
static bfd_boolean sunos_link_dynamic_object |
64 |
PARAMS ((struct bfd_link_info *, bfd *)); |
PARAMS ((struct bfd_link_info *, bfd *)); |
65 |
static boolean sunos_write_dynamic_symbol |
static bfd_boolean sunos_write_dynamic_symbol |
66 |
PARAMS ((bfd *, struct bfd_link_info *, struct aout_link_hash_entry *)); |
PARAMS ((bfd *, struct bfd_link_info *, struct aout_link_hash_entry *)); |
67 |
static boolean sunos_check_dynamic_reloc |
static bfd_boolean sunos_check_dynamic_reloc |
68 |
PARAMS ((struct bfd_link_info *, bfd *, asection *, |
PARAMS ((struct bfd_link_info *, bfd *, asection *, |
69 |
struct aout_link_hash_entry *, PTR, bfd_byte *, boolean *, |
struct aout_link_hash_entry *, PTR, bfd_byte *, bfd_boolean *, |
70 |
bfd_vma *)); |
bfd_vma *)); |
71 |
static boolean sunos_finish_dynamic_link |
static bfd_boolean sunos_finish_dynamic_link |
72 |
PARAMS ((bfd *, struct bfd_link_info *)); |
PARAMS ((bfd *, struct bfd_link_info *)); |
73 |
|
|
74 |
#define MY_get_dynamic_symtab_upper_bound sunos_get_dynamic_symtab_upper_bound |
#define MY_get_dynamic_symtab_upper_bound sunos_get_dynamic_symtab_upper_bound |
75 |
#define MY_canonicalize_dynamic_symtab sunos_canonicalize_dynamic_symtab |
#define MY_canonicalize_dynamic_symtab sunos_canonicalize_dynamic_symtab |
76 |
|
#define MY_get_synthetic_symtab _bfd_nodynamic_get_synthetic_symtab |
77 |
#define MY_get_dynamic_reloc_upper_bound sunos_get_dynamic_reloc_upper_bound |
#define MY_get_dynamic_reloc_upper_bound sunos_get_dynamic_reloc_upper_bound |
78 |
#define MY_canonicalize_dynamic_reloc sunos_canonicalize_dynamic_reloc |
#define MY_canonicalize_dynamic_reloc sunos_canonicalize_dynamic_reloc |
79 |
#define MY_bfd_link_hash_table_create sunos_link_hash_table_create |
#define MY_bfd_link_hash_table_create sunos_link_hash_table_create |
106 |
struct sunos_dynamic_info |
struct sunos_dynamic_info |
107 |
{ |
{ |
108 |
/* Whether we found any dynamic information. */ |
/* Whether we found any dynamic information. */ |
109 |
boolean valid; |
bfd_boolean valid; |
110 |
/* Dynamic information. */ |
/* Dynamic information. */ |
111 |
struct internal_sun4_dynamic_link dyninfo; |
struct internal_sun4_dynamic_link dyninfo; |
112 |
/* Number of dynamic symbols. */ |
/* Number of dynamic symbols. */ |
135 |
structure and uses it to find the dynamic_link structure. It |
structure and uses it to find the dynamic_link structure. It |
136 |
creates and saves a sunos_dynamic_info structure. If it can't find |
creates and saves a sunos_dynamic_info structure. If it can't find |
137 |
__DYNAMIC, it sets the valid field of the sunos_dynamic_info |
__DYNAMIC, it sets the valid field of the sunos_dynamic_info |
138 |
structure to false to avoid doing this work again. */ |
structure to FALSE to avoid doing this work again. */ |
139 |
|
|
140 |
static boolean |
static bfd_boolean |
141 |
sunos_read_dynamic_info (abfd) |
sunos_read_dynamic_info (abfd) |
142 |
bfd *abfd; |
bfd *abfd; |
143 |
{ |
{ |
150 |
bfd_size_type amt; |
bfd_size_type amt; |
151 |
|
|
152 |
if (obj_aout_dynamic_info (abfd) != (PTR) NULL) |
if (obj_aout_dynamic_info (abfd) != (PTR) NULL) |
153 |
return true; |
return TRUE; |
154 |
|
|
155 |
if ((abfd->flags & DYNAMIC) == 0) |
if ((abfd->flags & DYNAMIC) == 0) |
156 |
{ |
{ |
157 |
bfd_set_error (bfd_error_invalid_operation); |
bfd_set_error (bfd_error_invalid_operation); |
158 |
return false; |
return FALSE; |
159 |
} |
} |
160 |
|
|
161 |
amt = sizeof (struct sunos_dynamic_info); |
amt = sizeof (struct sunos_dynamic_info); |
162 |
info = (struct sunos_dynamic_info *) bfd_zalloc (abfd, amt); |
info = (struct sunos_dynamic_info *) bfd_zalloc (abfd, amt); |
163 |
if (!info) |
if (!info) |
164 |
return false; |
return FALSE; |
165 |
info->valid = false; |
info->valid = FALSE; |
166 |
info->dynsym = NULL; |
info->dynsym = NULL; |
167 |
info->dynstr = NULL; |
info->dynstr = NULL; |
168 |
info->canonical_dynsym = NULL; |
info->canonical_dynsym = NULL; |
178 |
We could verify this assumption later by looking through the dynamic |
We could verify this assumption later by looking through the dynamic |
179 |
symbols for the __DYNAMIC symbol. */ |
symbols for the __DYNAMIC symbol. */ |
180 |
if ((abfd->flags & DYNAMIC) == 0) |
if ((abfd->flags & DYNAMIC) == 0) |
181 |
return true; |
return TRUE; |
182 |
if (! bfd_get_section_contents (abfd, obj_datasec (abfd), (PTR) &dyninfo, |
if (! bfd_get_section_contents (abfd, obj_datasec (abfd), (PTR) &dyninfo, |
183 |
(file_ptr) 0, |
(file_ptr) 0, |
184 |
(bfd_size_type) sizeof dyninfo)) |
(bfd_size_type) sizeof dyninfo)) |
185 |
return true; |
return TRUE; |
186 |
|
|
187 |
dynver = GET_WORD (abfd, dyninfo.ld_version); |
dynver = GET_WORD (abfd, dyninfo.ld_version); |
188 |
if (dynver != 2 && dynver != 3) |
if (dynver != 2 && dynver != 3) |
189 |
return true; |
return TRUE; |
190 |
|
|
191 |
dynoff = GET_WORD (abfd, dyninfo.ld); |
dynoff = GET_WORD (abfd, dyninfo.ld); |
192 |
|
|
197 |
else |
else |
198 |
dynsec = obj_datasec (abfd); |
dynsec = obj_datasec (abfd); |
199 |
dynoff -= bfd_get_section_vma (abfd, dynsec); |
dynoff -= bfd_get_section_vma (abfd, dynsec); |
200 |
if (dynoff > bfd_section_size (abfd, dynsec)) |
if (dynoff > dynsec->size) |
201 |
return true; |
return TRUE; |
202 |
|
|
203 |
/* This executable appears to be dynamically linked in a way that we |
/* This executable appears to be dynamically linked in a way that we |
204 |
can understand. */ |
can understand. */ |
205 |
if (! bfd_get_section_contents (abfd, dynsec, (PTR) &linkinfo, |
if (! bfd_get_section_contents (abfd, dynsec, (PTR) &linkinfo, |
206 |
(file_ptr) dynoff, |
(file_ptr) dynoff, |
207 |
(bfd_size_type) sizeof linkinfo)) |
(bfd_size_type) sizeof linkinfo)) |
208 |
return true; |
return TRUE; |
209 |
|
|
210 |
/* Swap in the dynamic link information. */ |
/* Swap in the dynamic link information. */ |
211 |
info->dyninfo.ld_loaded = GET_WORD (abfd, linkinfo.ld_loaded); |
info->dyninfo.ld_loaded = GET_WORD (abfd, linkinfo.ld_loaded); |
252 |
== (unsigned long) (info->dyninfo.ld_hash |
== (unsigned long) (info->dyninfo.ld_hash |
253 |
- info->dyninfo.ld_rel)); |
- info->dyninfo.ld_rel)); |
254 |
|
|
255 |
info->valid = true; |
info->valid = TRUE; |
256 |
|
|
257 |
return true; |
return TRUE; |
258 |
} |
} |
259 |
|
|
260 |
/* Return the amount of memory required for the dynamic symbols. */ |
/* Return the amount of memory required for the dynamic symbols. */ |
280 |
|
|
281 |
/* Read the external dynamic symbols. */ |
/* Read the external dynamic symbols. */ |
282 |
|
|
283 |
static boolean |
static bfd_boolean |
284 |
sunos_slurp_dynamic_symtab (abfd) |
sunos_slurp_dynamic_symtab (abfd) |
285 |
bfd *abfd; |
bfd *abfd; |
286 |
{ |
{ |
291 |
if (obj_aout_dynamic_info (abfd) == NULL) |
if (obj_aout_dynamic_info (abfd) == NULL) |
292 |
{ |
{ |
293 |
if (! sunos_read_dynamic_info (abfd)) |
if (! sunos_read_dynamic_info (abfd)) |
294 |
return false; |
return FALSE; |
295 |
} |
} |
296 |
|
|
297 |
info = (struct sunos_dynamic_info *) obj_aout_dynamic_info (abfd); |
info = (struct sunos_dynamic_info *) obj_aout_dynamic_info (abfd); |
298 |
if (! info->valid) |
if (! info->valid) |
299 |
{ |
{ |
300 |
bfd_set_error (bfd_error_no_symbols); |
bfd_set_error (bfd_error_no_symbols); |
301 |
return false; |
return FALSE; |
302 |
} |
} |
303 |
|
|
304 |
/* Get the dynamic nlist structures. */ |
/* Get the dynamic nlist structures. */ |
307 |
amt = (bfd_size_type) info->dynsym_count * EXTERNAL_NLIST_SIZE; |
amt = (bfd_size_type) info->dynsym_count * EXTERNAL_NLIST_SIZE; |
308 |
info->dynsym = (struct external_nlist *) bfd_alloc (abfd, amt); |
info->dynsym = (struct external_nlist *) bfd_alloc (abfd, amt); |
309 |
if (info->dynsym == NULL && info->dynsym_count != 0) |
if (info->dynsym == NULL && info->dynsym_count != 0) |
310 |
return false; |
return FALSE; |
311 |
if (bfd_seek (abfd, (file_ptr) info->dyninfo.ld_stab, SEEK_SET) != 0 |
if (bfd_seek (abfd, (file_ptr) info->dyninfo.ld_stab, SEEK_SET) != 0 |
312 |
|| bfd_bread ((PTR) info->dynsym, amt, abfd) != amt) |
|| bfd_bread ((PTR) info->dynsym, amt, abfd) != amt) |
313 |
{ |
{ |
316 |
bfd_release (abfd, info->dynsym); |
bfd_release (abfd, info->dynsym); |
317 |
info->dynsym = NULL; |
info->dynsym = NULL; |
318 |
} |
} |
319 |
return false; |
return FALSE; |
320 |
} |
} |
321 |
} |
} |
322 |
|
|
326 |
amt = info->dyninfo.ld_symb_size; |
amt = info->dyninfo.ld_symb_size; |
327 |
info->dynstr = (char *) bfd_alloc (abfd, amt); |
info->dynstr = (char *) bfd_alloc (abfd, amt); |
328 |
if (info->dynstr == NULL && info->dyninfo.ld_symb_size != 0) |
if (info->dynstr == NULL && info->dyninfo.ld_symb_size != 0) |
329 |
return false; |
return FALSE; |
330 |
if (bfd_seek (abfd, (file_ptr) info->dyninfo.ld_symbols, SEEK_SET) != 0 |
if (bfd_seek (abfd, (file_ptr) info->dyninfo.ld_symbols, SEEK_SET) != 0 |
331 |
|| bfd_bread ((PTR) info->dynstr, amt, abfd) != amt) |
|| bfd_bread ((PTR) info->dynstr, amt, abfd) != amt) |
332 |
{ |
{ |
335 |
bfd_release (abfd, info->dynstr); |
bfd_release (abfd, info->dynstr); |
336 |
info->dynstr = NULL; |
info->dynstr = NULL; |
337 |
} |
} |
338 |
return false; |
return FALSE; |
339 |
} |
} |
340 |
} |
} |
341 |
|
|
342 |
return true; |
return TRUE; |
343 |
} |
} |
344 |
|
|
345 |
/* Read in the dynamic symbols. */ |
/* Read in the dynamic symbols. */ |
413 |
if (! aout_32_translate_symbol_table (abfd, info->canonical_dynsym, |
if (! aout_32_translate_symbol_table (abfd, info->canonical_dynsym, |
414 |
info->dynsym, |
info->dynsym, |
415 |
(bfd_size_type) info->dynsym_count, |
(bfd_size_type) info->dynsym_count, |
416 |
info->dynstr, strsize, true)) |
info->dynstr, strsize, TRUE)) |
417 |
{ |
{ |
418 |
if (info->canonical_dynsym != NULL) |
if (info->canonical_dynsym != NULL) |
419 |
{ |
{ |
651 |
bfd *dynobj; |
bfd *dynobj; |
652 |
|
|
653 |
/* Whether we have created the dynamic sections. */ |
/* Whether we have created the dynamic sections. */ |
654 |
boolean dynamic_sections_created; |
bfd_boolean dynamic_sections_created; |
655 |
|
|
656 |
/* Whether we need the dynamic sections. */ |
/* Whether we need the dynamic sections. */ |
657 |
boolean dynamic_sections_needed; |
bfd_boolean dynamic_sections_needed; |
658 |
|
|
659 |
/* Whether we need the .got table. */ |
/* Whether we need the .got table. */ |
660 |
boolean got_needed; |
bfd_boolean got_needed; |
661 |
|
|
662 |
/* The number of dynamic symbols. */ |
/* The number of dynamic symbols. */ |
663 |
size_t dynsymcount; |
size_t dynsymcount; |
728 |
} |
} |
729 |
|
|
730 |
ret->dynobj = NULL; |
ret->dynobj = NULL; |
731 |
ret->dynamic_sections_created = false; |
ret->dynamic_sections_created = FALSE; |
732 |
ret->dynamic_sections_needed = false; |
ret->dynamic_sections_needed = FALSE; |
733 |
ret->got_needed = false; |
ret->got_needed = FALSE; |
734 |
ret->dynsymcount = 0; |
ret->dynsymcount = 0; |
735 |
ret->bucketcount = 0; |
ret->bucketcount = 0; |
736 |
ret->needed = NULL; |
ret->needed = NULL; |
751 |
#define sunos_link_hash_traverse(table, func, info) \ |
#define sunos_link_hash_traverse(table, func, info) \ |
752 |
(aout_link_hash_traverse \ |
(aout_link_hash_traverse \ |
753 |
(&(table)->root, \ |
(&(table)->root, \ |
754 |
(boolean (*) PARAMS ((struct aout_link_hash_entry *, PTR))) (func), \ |
(bfd_boolean (*) PARAMS ((struct aout_link_hash_entry *, PTR))) (func), \ |
755 |
(info))) |
(info))) |
756 |
|
|
757 |
/* Get the SunOS link hash table from the info structure. This is |
/* Get the SunOS link hash table from the info structure. This is |
759 |
|
|
760 |
#define sunos_hash_table(p) ((struct sunos_link_hash_table *) ((p)->hash)) |
#define sunos_hash_table(p) ((struct sunos_link_hash_table *) ((p)->hash)) |
761 |
|
|
762 |
static boolean sunos_scan_dynamic_symbol |
static bfd_boolean sunos_scan_dynamic_symbol |
763 |
PARAMS ((struct sunos_link_hash_entry *, PTR)); |
PARAMS ((struct sunos_link_hash_entry *, PTR)); |
764 |
|
|
765 |
/* Create the dynamic sections needed if we are linking against a |
/* Create the dynamic sections needed if we are linking against a |
769 |
place in the output file. See include/aout/sun4.h for more details |
place in the output file. See include/aout/sun4.h for more details |
770 |
of the dynamic linking information. */ |
of the dynamic linking information. */ |
771 |
|
|
772 |
static boolean |
static bfd_boolean |
773 |
sunos_create_dynamic_sections (abfd, info, needed) |
sunos_create_dynamic_sections (abfd, info, needed) |
774 |
bfd *abfd; |
bfd *abfd; |
775 |
struct bfd_link_info *info; |
struct bfd_link_info *info; |
776 |
boolean needed; |
bfd_boolean needed; |
777 |
{ |
{ |
778 |
asection *s; |
asection *s; |
779 |
|
|
793 |
if (s == NULL |
if (s == NULL |
794 |
|| ! bfd_set_section_flags (abfd, s, flags) |
|| ! bfd_set_section_flags (abfd, s, flags) |
795 |
|| ! bfd_set_section_alignment (abfd, s, 2)) |
|| ! bfd_set_section_alignment (abfd, s, 2)) |
796 |
return false; |
return FALSE; |
797 |
|
|
798 |
/* The .got section holds the global offset table. The address |
/* The .got section holds the global offset table. The address |
799 |
is put in the ld_got field. */ |
is put in the ld_got field. */ |
801 |
if (s == NULL |
if (s == NULL |
802 |
|| ! bfd_set_section_flags (abfd, s, flags) |
|| ! bfd_set_section_flags (abfd, s, flags) |
803 |
|| ! bfd_set_section_alignment (abfd, s, 2)) |
|| ! bfd_set_section_alignment (abfd, s, 2)) |
804 |
return false; |
return FALSE; |
805 |
|
|
806 |
/* The .plt section holds the procedure linkage table. The |
/* The .plt section holds the procedure linkage table. The |
807 |
address is put in the ld_plt field. */ |
address is put in the ld_plt field. */ |
809 |
if (s == NULL |
if (s == NULL |
810 |
|| ! bfd_set_section_flags (abfd, s, flags | SEC_CODE) |
|| ! bfd_set_section_flags (abfd, s, flags | SEC_CODE) |
811 |
|| ! bfd_set_section_alignment (abfd, s, 2)) |
|| ! bfd_set_section_alignment (abfd, s, 2)) |
812 |
return false; |
return FALSE; |
813 |
|
|
814 |
/* The .dynrel section holds the dynamic relocs. The address is |
/* The .dynrel section holds the dynamic relocs. The address is |
815 |
put in the ld_rel field. */ |
put in the ld_rel field. */ |
817 |
if (s == NULL |
if (s == NULL |
818 |
|| ! bfd_set_section_flags (abfd, s, flags | SEC_READONLY) |
|| ! bfd_set_section_flags (abfd, s, flags | SEC_READONLY) |
819 |
|| ! bfd_set_section_alignment (abfd, s, 2)) |
|| ! bfd_set_section_alignment (abfd, s, 2)) |
820 |
return false; |
return FALSE; |
821 |
|
|
822 |
/* The .hash section holds the dynamic hash table. The address |
/* The .hash section holds the dynamic hash table. The address |
823 |
is put in the ld_hash field. */ |
is put in the ld_hash field. */ |
825 |
if (s == NULL |
if (s == NULL |
826 |
|| ! bfd_set_section_flags (abfd, s, flags | SEC_READONLY) |
|| ! bfd_set_section_flags (abfd, s, flags | SEC_READONLY) |
827 |
|| ! bfd_set_section_alignment (abfd, s, 2)) |
|| ! bfd_set_section_alignment (abfd, s, 2)) |
828 |
return false; |
return FALSE; |
829 |
|
|
830 |
/* The .dynsym section holds the dynamic symbols. The address |
/* The .dynsym section holds the dynamic symbols. The address |
831 |
is put in the ld_stab field. */ |
is put in the ld_stab field. */ |
833 |
if (s == NULL |
if (s == NULL |
834 |
|| ! bfd_set_section_flags (abfd, s, flags | SEC_READONLY) |
|| ! bfd_set_section_flags (abfd, s, flags | SEC_READONLY) |
835 |
|| ! bfd_set_section_alignment (abfd, s, 2)) |
|| ! bfd_set_section_alignment (abfd, s, 2)) |
836 |
return false; |
return FALSE; |
837 |
|
|
838 |
/* The .dynstr section holds the dynamic symbol string table. |
/* The .dynstr section holds the dynamic symbol string table. |
839 |
The address is put in the ld_symbols field. */ |
The address is put in the ld_symbols field. */ |
841 |
if (s == NULL |
if (s == NULL |
842 |
|| ! bfd_set_section_flags (abfd, s, flags | SEC_READONLY) |
|| ! bfd_set_section_flags (abfd, s, flags | SEC_READONLY) |
843 |
|| ! bfd_set_section_alignment (abfd, s, 2)) |
|| ! bfd_set_section_alignment (abfd, s, 2)) |
844 |
return false; |
return FALSE; |
845 |
|
|
846 |
sunos_hash_table (info)->dynamic_sections_created = true; |
sunos_hash_table (info)->dynamic_sections_created = TRUE; |
847 |
} |
} |
848 |
|
|
849 |
if ((needed && ! sunos_hash_table (info)->dynamic_sections_needed) |
if ((needed && ! sunos_hash_table (info)->dynamic_sections_needed) |
854 |
dynobj = sunos_hash_table (info)->dynobj; |
dynobj = sunos_hash_table (info)->dynobj; |
855 |
|
|
856 |
s = bfd_get_section_by_name (dynobj, ".got"); |
s = bfd_get_section_by_name (dynobj, ".got"); |
857 |
if (s->_raw_size == 0) |
if (s->size == 0) |
858 |
s->_raw_size = BYTES_IN_WORD; |
s->size = BYTES_IN_WORD; |
859 |
|
|
860 |
sunos_hash_table (info)->dynamic_sections_needed = true; |
sunos_hash_table (info)->dynamic_sections_needed = TRUE; |
861 |
sunos_hash_table (info)->got_needed = true; |
sunos_hash_table (info)->got_needed = TRUE; |
862 |
} |
} |
863 |
|
|
864 |
return true; |
return TRUE; |
865 |
} |
} |
866 |
|
|
867 |
/* Add dynamic symbols during a link. This is called by the a.out |
/* Add dynamic symbols during a link. This is called by the a.out |
868 |
backend linker for each object it encounters. */ |
backend linker for each object it encounters. */ |
869 |
|
|
870 |
static boolean |
static bfd_boolean |
871 |
sunos_add_dynamic_symbols (abfd, info, symsp, sym_countp, stringsp) |
sunos_add_dynamic_symbols (abfd, info, symsp, sym_countp, stringsp) |
872 |
bfd *abfd; |
bfd *abfd; |
873 |
struct bfd_link_info *info; |
struct bfd_link_info *info; |
884 |
if (info->hash->creator == abfd->xvec) |
if (info->hash->creator == abfd->xvec) |
885 |
{ |
{ |
886 |
if (! sunos_create_dynamic_sections (abfd, info, |
if (! sunos_create_dynamic_sections (abfd, info, |
887 |
(((abfd->flags & DYNAMIC) != 0 |
((abfd->flags & DYNAMIC) != 0 |
888 |
&& ! info->relocateable) |
&& !info->relocatable))) |
889 |
? true |
return FALSE; |
|
: false))) |
|
|
return false; |
|
890 |
} |
} |
891 |
|
|
892 |
/* There is nothing else to do for a normal object. */ |
/* There is nothing else to do for a normal object. */ |
893 |
if ((abfd->flags & DYNAMIC) == 0) |
if ((abfd->flags & DYNAMIC) == 0) |
894 |
return true; |
return TRUE; |
895 |
|
|
896 |
dynobj = sunos_hash_table (info)->dynobj; |
dynobj = sunos_hash_table (info)->dynobj; |
897 |
|
|
912 |
|
|
913 |
/* The native linker seems to just ignore dynamic objects when -r is |
/* The native linker seems to just ignore dynamic objects when -r is |
914 |
used. */ |
used. */ |
915 |
if (info->relocateable) |
if (info->relocatable) |
916 |
return true; |
return TRUE; |
917 |
|
|
918 |
/* There's no hope of using a dynamic object which does not exactly |
/* There's no hope of using a dynamic object which does not exactly |
919 |
match the format of the output file. */ |
match the format of the output file. */ |
920 |
if (info->hash->creator != abfd->xvec) |
if (info->hash->creator != abfd->xvec) |
921 |
{ |
{ |
922 |
bfd_set_error (bfd_error_invalid_operation); |
bfd_set_error (bfd_error_invalid_operation); |
923 |
return false; |
return FALSE; |
924 |
} |
} |
925 |
|
|
926 |
/* Make sure we have a .need and a .rules sections. These are only |
/* Make sure we have a .need and a .rules sections. These are only |
940 |
| SEC_IN_MEMORY |
| SEC_IN_MEMORY |
941 |
| SEC_READONLY)) |
| SEC_READONLY)) |
942 |
|| ! bfd_set_section_alignment (dynobj, s, 2)) |
|| ! bfd_set_section_alignment (dynobj, s, 2)) |
943 |
return false; |
return FALSE; |
944 |
} |
} |
945 |
|
|
946 |
if (bfd_get_section_by_name (dynobj, ".rules") == NULL) |
if (bfd_get_section_by_name (dynobj, ".rules") == NULL) |
957 |
| SEC_IN_MEMORY |
| SEC_IN_MEMORY |
958 |
| SEC_READONLY)) |
| SEC_READONLY)) |
959 |
|| ! bfd_set_section_alignment (dynobj, s, 2)) |
|| ! bfd_set_section_alignment (dynobj, s, 2)) |
960 |
return false; |
return FALSE; |
961 |
} |
} |
962 |
|
|
963 |
/* Pick up the dynamic symbols and return them to the caller. */ |
/* Pick up the dynamic symbols and return them to the caller. */ |
964 |
if (! sunos_slurp_dynamic_symtab (abfd)) |
if (! sunos_slurp_dynamic_symtab (abfd)) |
965 |
return false; |
return FALSE; |
966 |
|
|
967 |
dinfo = (struct sunos_dynamic_info *) obj_aout_dynamic_info (abfd); |
dinfo = (struct sunos_dynamic_info *) obj_aout_dynamic_info (abfd); |
968 |
*symsp = dinfo->dynsym; |
*symsp = dinfo->dynsym; |
984 |
|
|
985 |
if (bfd_seek (abfd, (file_ptr) need, SEEK_SET) != 0 |
if (bfd_seek (abfd, (file_ptr) need, SEEK_SET) != 0 |
986 |
|| bfd_bread (buf, (bfd_size_type) 16, abfd) != 16) |
|| bfd_bread (buf, (bfd_size_type) 16, abfd) != 16) |
987 |
return false; |
return FALSE; |
988 |
|
|
989 |
/* For the format of an ld_need entry, see aout/sun4.h. We |
/* For the format of an ld_need entry, see aout/sun4.h. We |
990 |
should probably define structs for this manipulation. */ |
should probably define structs for this manipulation. */ |
991 |
|
|
992 |
name = bfd_get_32 (abfd, buf); |
name = bfd_get_32 (abfd, buf); |
993 |
flags = bfd_get_32 (abfd, buf + 4); |
flags = bfd_get_32 (abfd, buf + 4); |
998 |
alc = sizeof (struct bfd_link_needed_list); |
alc = sizeof (struct bfd_link_needed_list); |
999 |
needed = (struct bfd_link_needed_list *) bfd_alloc (abfd, alc); |
needed = (struct bfd_link_needed_list *) bfd_alloc (abfd, alc); |
1000 |
if (needed == NULL) |
if (needed == NULL) |
1001 |
return false; |
return FALSE; |
1002 |
needed->by = abfd; |
needed->by = abfd; |
1003 |
|
|
1004 |
/* We return the name as [-l]name[.maj][.min]. */ |
/* We return the name as [-l]name[.maj][.min]. */ |
1005 |
alc = 30; |
alc = 30; |
1006 |
namebuf = (char *) bfd_malloc (alc + 1); |
namebuf = (char *) bfd_malloc (alc + 1); |
1007 |
if (namebuf == NULL) |
if (namebuf == NULL) |
1008 |
return false; |
return FALSE; |
1009 |
p = namebuf; |
p = namebuf; |
1010 |
|
|
1011 |
if ((flags & 0x80000000) != 0) |
if ((flags & 0x80000000) != 0) |
1016 |
if (bfd_seek (abfd, (file_ptr) name, SEEK_SET) != 0) |
if (bfd_seek (abfd, (file_ptr) name, SEEK_SET) != 0) |
1017 |
{ |
{ |
1018 |
free (namebuf); |
free (namebuf); |
1019 |
return false; |
return FALSE; |
1020 |
} |
} |
1021 |
|
|
1022 |
do |
do |
1024 |
if (bfd_bread (&b, (bfd_size_type) 1, abfd) != 1) |
if (bfd_bread (&b, (bfd_size_type) 1, abfd) != 1) |
1025 |
{ |
{ |
1026 |
free (namebuf); |
free (namebuf); |
1027 |
return false; |
return FALSE; |
1028 |
} |
} |
1029 |
|
|
1030 |
if ((bfd_size_type) (p - namebuf) >= alc) |
if ((bfd_size_type) (p - namebuf) >= alc) |
1036 |
if (n == NULL) |
if (n == NULL) |
1037 |
{ |
{ |
1038 |
free (namebuf); |
free (namebuf); |
1039 |
return false; |
return FALSE; |
1040 |
} |
} |
1041 |
p = n + (p - namebuf); |
p = n + (p - namebuf); |
1042 |
namebuf = n; |
namebuf = n; |
1068 |
if (n == NULL) |
if (n == NULL) |
1069 |
{ |
{ |
1070 |
free (namebuf); |
free (namebuf); |
1071 |
return false; |
return FALSE; |
1072 |
} |
} |
1073 |
p = n + (p - namebuf); |
p = n + (p - namebuf); |
1074 |
namebuf = n; |
namebuf = n; |
1082 |
if (namecopy == NULL) |
if (namecopy == NULL) |
1083 |
{ |
{ |
1084 |
free (namebuf); |
free (namebuf); |
1085 |
return false; |
return FALSE; |
1086 |
} |
} |
1087 |
strcpy (namecopy, namebuf); |
strcpy (namecopy, namebuf); |
1088 |
free (namebuf); |
free (namebuf); |
1097 |
*pp = needed; |
*pp = needed; |
1098 |
} |
} |
1099 |
|
|
1100 |
return true; |
return TRUE; |
1101 |
} |
} |
1102 |
|
|
1103 |
/* Function to add a single symbol to the linker hash table. This is |
/* Function to add a single symbol to the linker hash table. This is |
1104 |
a wrapper around _bfd_generic_link_add_one_symbol which handles the |
a wrapper around _bfd_generic_link_add_one_symbol which handles the |
1105 |
tweaking needed for dynamic linking support. */ |
tweaking needed for dynamic linking support. */ |
1106 |
|
|
1107 |
static boolean |
static bfd_boolean |
1108 |
sunos_add_one_symbol (info, abfd, name, flags, section, value, string, |
sunos_add_one_symbol (info, abfd, name, flags, section, value, string, |
1109 |
copy, collect, hashp) |
copy, collect, hashp) |
1110 |
struct bfd_link_info *info; |
struct bfd_link_info *info; |
1114 |
asection *section; |
asection *section; |
1115 |
bfd_vma value; |
bfd_vma value; |
1116 |
const char *string; |
const char *string; |
1117 |
boolean copy; |
bfd_boolean copy; |
1118 |
boolean collect; |
bfd_boolean collect; |
1119 |
struct bfd_link_hash_entry **hashp; |
struct bfd_link_hash_entry **hashp; |
1120 |
{ |
{ |
1121 |
struct sunos_link_hash_entry *h; |
struct sunos_link_hash_entry *h; |
1123 |
|
|
1124 |
if ((flags & (BSF_INDIRECT | BSF_WARNING | BSF_CONSTRUCTOR)) != 0 |
if ((flags & (BSF_INDIRECT | BSF_WARNING | BSF_CONSTRUCTOR)) != 0 |
1125 |
|| ! bfd_is_und_section (section)) |
|| ! bfd_is_und_section (section)) |
1126 |
h = sunos_link_hash_lookup (sunos_hash_table (info), name, true, copy, |
h = sunos_link_hash_lookup (sunos_hash_table (info), name, TRUE, copy, |
1127 |
false); |
FALSE); |
1128 |
else |
else |
1129 |
h = ((struct sunos_link_hash_entry *) |
h = ((struct sunos_link_hash_entry *) |
1130 |
bfd_wrapped_link_hash_lookup (abfd, info, name, true, copy, false)); |
bfd_wrapped_link_hash_lookup (abfd, info, name, TRUE, copy, FALSE)); |
1131 |
if (h == NULL) |
if (h == NULL) |
1132 |
return false; |
return FALSE; |
1133 |
|
|
1134 |
if (hashp != NULL) |
if (hashp != NULL) |
1135 |
*hashp = (struct bfd_link_hash_entry *) h; |
*hashp = (struct bfd_link_hash_entry *) h; |
1183 |
&& (h->flags & SUNOS_CONSTRUCTOR) != 0) |
&& (h->flags & SUNOS_CONSTRUCTOR) != 0) |
1184 |
{ |
{ |
1185 |
/* The existing symbol is a constructor symbol, and this symbol |
/* The existing symbol is a constructor symbol, and this symbol |
1186 |
is from a dynamic object. A constructor symbol is actually a |
is from a dynamic object. A constructor symbol is actually a |
1187 |
definition, although the type will be bfd_link_hash_undefined |
definition, although the type will be bfd_link_hash_undefined |
1188 |
at this point. We want to ignore the definition from the |
at this point. We want to ignore the definition from the |
1189 |
dynamic object. */ |
dynamic object. */ |
1190 |
section = bfd_und_section_ptr; |
section = bfd_und_section_ptr; |
1191 |
} |
} |
1192 |
else if ((flags & BSF_CONSTRUCTOR) != 0 |
else if ((flags & BSF_CONSTRUCTOR) != 0 |
1196 |
&& (h->root.root.u.def.section->owner->flags & DYNAMIC) != 0) |
&& (h->root.root.u.def.section->owner->flags & DYNAMIC) != 0) |
1197 |
{ |
{ |
1198 |
/* The existing symbol is defined by a dynamic object, and this |
/* The existing symbol is defined by a dynamic object, and this |
1199 |
is a constructor symbol. As above, we want to force the use |
is a constructor symbol. As above, we want to force the use |
1200 |
of the constructor symbol from the regular object. */ |
of the constructor symbol from the regular object. */ |
1201 |
h->root.root.type = bfd_link_hash_new; |
h->root.root.type = bfd_link_hash_new; |
1202 |
} |
} |
1203 |
|
|
1205 |
if (! _bfd_generic_link_add_one_symbol (info, abfd, name, flags, section, |
if (! _bfd_generic_link_add_one_symbol (info, abfd, name, flags, section, |
1206 |
value, string, copy, collect, |
value, string, copy, collect, |
1207 |
hashp)) |
hashp)) |
1208 |
return false; |
return FALSE; |
1209 |
|
|
1210 |
if (abfd->xvec == info->hash->creator) |
if (abfd->xvec == info->hash->creator) |
1211 |
{ |
{ |
1242 |
h->flags |= SUNOS_CONSTRUCTOR; |
h->flags |= SUNOS_CONSTRUCTOR; |
1243 |
} |
} |
1244 |
|
|
1245 |
return true; |
return TRUE; |
1246 |
} |
} |
1247 |
|
|
1248 |
/* Return the list of objects needed by BFD. */ |
/* Return the list of objects needed by BFD. */ |
1249 |
|
|
|
/*ARGSUSED*/ |
|
1250 |
struct bfd_link_needed_list * |
struct bfd_link_needed_list * |
1251 |
bfd_sunos_get_needed_list (abfd, info) |
bfd_sunos_get_needed_list (abfd, info) |
1252 |
bfd *abfd ATTRIBUTE_UNUSED; |
bfd *abfd ATTRIBUTE_UNUSED; |
1260 |
/* Record an assignment made to a symbol by a linker script. We need |
/* Record an assignment made to a symbol by a linker script. We need |
1261 |
this in case some dynamic object refers to this symbol. */ |
this in case some dynamic object refers to this symbol. */ |
1262 |
|
|
1263 |
boolean |
bfd_boolean |
1264 |
bfd_sunos_record_link_assignment (output_bfd, info, name) |
bfd_sunos_record_link_assignment (output_bfd, info, name) |
1265 |
bfd *output_bfd; |
bfd *output_bfd; |
1266 |
struct bfd_link_info *info; |
struct bfd_link_info *info; |
1269 |
struct sunos_link_hash_entry *h; |
struct sunos_link_hash_entry *h; |
1270 |
|
|
1271 |
if (output_bfd->xvec != &MY(vec)) |
if (output_bfd->xvec != &MY(vec)) |
1272 |
return true; |
return TRUE; |
1273 |
|
|
1274 |
/* This is called after we have examined all the input objects. If |
/* This is called after we have examined all the input objects. If |
1275 |
the symbol does not exist, it merely means that no object refers |
the symbol does not exist, it merely means that no object refers |
1276 |
to it, and we can just ignore it at this point. */ |
to it, and we can just ignore it at this point. */ |
1277 |
h = sunos_link_hash_lookup (sunos_hash_table (info), name, |
h = sunos_link_hash_lookup (sunos_hash_table (info), name, |
1278 |
false, false, false); |
FALSE, FALSE, FALSE); |
1279 |
if (h == NULL) |
if (h == NULL) |
1280 |
return true; |
return TRUE; |
1281 |
|
|
1282 |
/* In a shared library, the __DYNAMIC symbol does not appear in the |
/* In a shared library, the __DYNAMIC symbol does not appear in the |
1283 |
dynamic symbol table. */ |
dynamic symbol table. */ |
1292 |
} |
} |
1293 |
} |
} |
1294 |
|
|
1295 |
return true; |
return TRUE; |
1296 |
} |
} |
1297 |
|
|
1298 |
/* Set up the sizes and contents of the dynamic sections created in |
/* Set up the sizes and contents of the dynamic sections created in |
1301 |
sections before the linker sets the addresses of the various |
sections before the linker sets the addresses of the various |
1302 |
sections. This unfortunately requires reading all the relocs so |
sections. This unfortunately requires reading all the relocs so |
1303 |
that we can work out which ones need to become dynamic relocs. If |
that we can work out which ones need to become dynamic relocs. If |
1304 |
info->keep_memory is true, we keep the relocs in memory; otherwise, |
info->keep_memory is TRUE, we keep the relocs in memory; otherwise, |
1305 |
we discard them, and will read them again later. */ |
we discard them, and will read them again later. */ |
1306 |
|
|
1307 |
boolean |
bfd_boolean |
1308 |
bfd_sunos_size_dynamic_sections (output_bfd, info, sdynptr, sneedptr, |
bfd_sunos_size_dynamic_sections (output_bfd, info, sdynptr, sneedptr, |
1309 |
srulesptr) |
srulesptr) |
1310 |
bfd *output_bfd; |
bfd *output_bfd; |
1326 |
*sneedptr = NULL; |
*sneedptr = NULL; |
1327 |
*srulesptr = NULL; |
*srulesptr = NULL; |
1328 |
|
|
1329 |
if (info->relocateable) |
if (info->relocatable) |
1330 |
return true; |
return TRUE; |
1331 |
|
|
1332 |
if (output_bfd->xvec != &MY(vec)) |
if (output_bfd->xvec != &MY(vec)) |
1333 |
return true; |
return TRUE; |
1334 |
|
|
1335 |
/* Look through all the input BFD's and read their relocs. It would |
/* Look through all the input BFD's and read their relocs. It would |
1336 |
be better if we didn't have to do this, but there is no other way |
be better if we didn't have to do this, but there is no other way |
1346 |
exec_hdr (sub)->a_trsize) |
exec_hdr (sub)->a_trsize) |
1347 |
|| ! sunos_scan_relocs (info, sub, obj_datasec (sub), |
|| ! sunos_scan_relocs (info, sub, obj_datasec (sub), |
1348 |
exec_hdr (sub)->a_drsize)) |
exec_hdr (sub)->a_drsize)) |
1349 |
return false; |
return FALSE; |
1350 |
} |
} |
1351 |
} |
} |
1352 |
|
|
1357 |
to build a global offset table, there is nothing to do here. */ |
to build a global offset table, there is nothing to do here. */ |
1358 |
if (! sunos_hash_table (info)->dynamic_sections_needed |
if (! sunos_hash_table (info)->dynamic_sections_needed |
1359 |
&& ! sunos_hash_table (info)->got_needed) |
&& ! sunos_hash_table (info)->got_needed) |
1360 |
return true; |
return TRUE; |
1361 |
|
|
1362 |
/* If __GLOBAL_OFFSET_TABLE_ was mentioned, define it. */ |
/* If __GLOBAL_OFFSET_TABLE_ was mentioned, define it. */ |
1363 |
h = sunos_link_hash_lookup (sunos_hash_table (info), |
h = sunos_link_hash_lookup (sunos_hash_table (info), |
1364 |
"__GLOBAL_OFFSET_TABLE_", false, false, false); |
"__GLOBAL_OFFSET_TABLE_", FALSE, FALSE, FALSE); |
1365 |
if (h != NULL && (h->flags & SUNOS_REF_REGULAR) != 0) |
if (h != NULL && (h->flags & SUNOS_REF_REGULAR) != 0) |
1366 |
{ |
{ |
1367 |
h->flags |= SUNOS_DEF_REGULAR; |
h->flags |= SUNOS_DEF_REGULAR; |
1374 |
h->root.root.u.def.section = bfd_get_section_by_name (dynobj, ".got"); |
h->root.root.u.def.section = bfd_get_section_by_name (dynobj, ".got"); |
1375 |
|
|
1376 |
/* If the .got section is more than 0x1000 bytes, we set |
/* If the .got section is more than 0x1000 bytes, we set |
1377 |
__GLOBAL_OFFSET_TABLE_ to be 0x1000 bytes into the section, |
__GLOBAL_OFFSET_TABLE_ to be 0x1000 bytes into the section, |
1378 |
so that 13 bit relocations have a greater chance of working. */ |
so that 13 bit relocations have a greater chance of working. */ |
1379 |
s = bfd_get_section_by_name (dynobj, ".got"); |
s = bfd_get_section_by_name (dynobj, ".got"); |
1380 |
BFD_ASSERT (s != NULL); |
BFD_ASSERT (s != NULL); |
1381 |
if (s->_raw_size >= 0x1000) |
if (s->size >= 0x1000) |
1382 |
h->root.root.u.def.value = 0x1000; |
h->root.root.u.def.value = 0x1000; |
1383 |
else |
else |
1384 |
h->root.root.u.def.value = 0; |
h->root.root.u.def.value = 0; |
1395 |
/* The .dynamic section is always the same size. */ |
/* The .dynamic section is always the same size. */ |
1396 |
s = *sdynptr; |
s = *sdynptr; |
1397 |
BFD_ASSERT (s != NULL); |
BFD_ASSERT (s != NULL); |
1398 |
s->_raw_size = (sizeof (struct external_sun4_dynamic) |
s->size = (sizeof (struct external_sun4_dynamic) |
1399 |
+ EXTERNAL_SUN4_DYNAMIC_DEBUGGER_SIZE |
+ EXTERNAL_SUN4_DYNAMIC_DEBUGGER_SIZE |
1400 |
+ sizeof (struct external_sun4_dynamic_link)); |
+ sizeof (struct external_sun4_dynamic_link)); |
1401 |
|
|
1409 |
sunos_scan_dynamic_symbol. */ |
sunos_scan_dynamic_symbol. */ |
1410 |
s = bfd_get_section_by_name (dynobj, ".dynsym"); |
s = bfd_get_section_by_name (dynobj, ".dynsym"); |
1411 |
BFD_ASSERT (s != NULL); |
BFD_ASSERT (s != NULL); |
1412 |
s->_raw_size = dynsymcount * sizeof (struct external_nlist); |
s->size = dynsymcount * sizeof (struct external_nlist); |
1413 |
s->contents = (bfd_byte *) bfd_alloc (output_bfd, s->_raw_size); |
s->contents = (bfd_byte *) bfd_alloc (output_bfd, s->size); |
1414 |
if (s->contents == NULL && s->_raw_size != 0) |
if (s->contents == NULL && s->size != 0) |
1415 |
return false; |
return FALSE; |
1416 |
|
|
1417 |
/* The number of buckets is just the number of symbols divided |
/* The number of buckets is just the number of symbols divided |
1418 |
by four. To compute the final size of the hash table, we |
by four. To compute the final size of the hash table, we |
1433 |
hashalloc = (dynsymcount + bucketcount - 1) * HASH_ENTRY_SIZE; |
hashalloc = (dynsymcount + bucketcount - 1) * HASH_ENTRY_SIZE; |
1434 |
s->contents = (bfd_byte *) bfd_zalloc (dynobj, hashalloc); |
s->contents = (bfd_byte *) bfd_zalloc (dynobj, hashalloc); |
1435 |
if (s->contents == NULL && dynsymcount > 0) |
if (s->contents == NULL && dynsymcount > 0) |
1436 |
return false; |
return FALSE; |
1437 |
for (i = 0; i < bucketcount; i++) |
for (i = 0; i < bucketcount; i++) |
1438 |
PUT_WORD (output_bfd, (bfd_vma) -1, s->contents + i * HASH_ENTRY_SIZE); |
PUT_WORD (output_bfd, (bfd_vma) -1, s->contents + i * HASH_ENTRY_SIZE); |
1439 |
s->_raw_size = bucketcount * HASH_ENTRY_SIZE; |
s->size = bucketcount * HASH_ENTRY_SIZE; |
1440 |
|
|
1441 |
sunos_hash_table (info)->bucketcount = bucketcount; |
sunos_hash_table (info)->bucketcount = bucketcount; |
1442 |
|
|
1454 |
important, but it can't hurt much. */ |
important, but it can't hurt much. */ |
1455 |
s = bfd_get_section_by_name (dynobj, ".dynstr"); |
s = bfd_get_section_by_name (dynobj, ".dynstr"); |
1456 |
BFD_ASSERT (s != NULL); |
BFD_ASSERT (s != NULL); |
1457 |
if ((s->_raw_size & 7) != 0) |
if ((s->size & 7) != 0) |
1458 |
{ |
{ |
1459 |
bfd_size_type add; |
bfd_size_type add; |
1460 |
bfd_byte *contents; |
bfd_byte *contents; |
1461 |
|
|
1462 |
add = 8 - (s->_raw_size & 7); |
add = 8 - (s->size & 7); |
1463 |
contents = (bfd_byte *) bfd_realloc (s->contents, |
contents = (bfd_byte *) bfd_realloc (s->contents, |
1464 |
s->_raw_size + add); |
s->size + add); |
1465 |
if (contents == NULL) |
if (contents == NULL) |
1466 |
return false; |
return FALSE; |
1467 |
memset (contents + s->_raw_size, 0, (size_t) add); |
memset (contents + s->size, 0, (size_t) add); |
1468 |
s->contents = contents; |
s->contents = contents; |
1469 |
s->_raw_size += add; |
s->size += add; |
1470 |
} |
} |
1471 |
} |
} |
1472 |
|
|
1474 |
table and the dynamic relocs, allocate storage for them. */ |
table and the dynamic relocs, allocate storage for them. */ |
1475 |
s = bfd_get_section_by_name (dynobj, ".plt"); |
s = bfd_get_section_by_name (dynobj, ".plt"); |
1476 |
BFD_ASSERT (s != NULL); |
BFD_ASSERT (s != NULL); |
1477 |
if (s->_raw_size != 0) |
if (s->size != 0) |
1478 |
{ |
{ |
1479 |
s->contents = (bfd_byte *) bfd_alloc (dynobj, s->_raw_size); |
s->contents = (bfd_byte *) bfd_alloc (dynobj, s->size); |
1480 |
if (s->contents == NULL) |
if (s->contents == NULL) |
1481 |
return false; |
return FALSE; |
1482 |
|
|
1483 |
/* Fill in the first entry in the table. */ |
/* Fill in the first entry in the table. */ |
1484 |
switch (bfd_get_arch (dynobj)) |
switch (bfd_get_arch (dynobj)) |
1497 |
} |
} |
1498 |
|
|
1499 |
s = bfd_get_section_by_name (dynobj, ".dynrel"); |
s = bfd_get_section_by_name (dynobj, ".dynrel"); |
1500 |
if (s->_raw_size != 0) |
if (s->size != 0) |
1501 |
{ |
{ |
1502 |
s->contents = (bfd_byte *) bfd_alloc (dynobj, s->_raw_size); |
s->contents = (bfd_byte *) bfd_alloc (dynobj, s->size); |
1503 |
if (s->contents == NULL) |
if (s->contents == NULL) |
1504 |
return false; |
return FALSE; |
1505 |
} |
} |
1506 |
/* We use the reloc_count field to keep track of how many of the |
/* We use the reloc_count field to keep track of how many of the |
1507 |
relocs we have output so far. */ |
relocs we have output so far. */ |
1509 |
|
|
1510 |
/* Make space for the global offset table. */ |
/* Make space for the global offset table. */ |
1511 |
s = bfd_get_section_by_name (dynobj, ".got"); |
s = bfd_get_section_by_name (dynobj, ".got"); |
1512 |
s->contents = (bfd_byte *) bfd_alloc (dynobj, s->_raw_size); |
s->contents = (bfd_byte *) bfd_alloc (dynobj, s->size); |
1513 |
if (s->contents == NULL) |
if (s->contents == NULL) |
1514 |
return false; |
return FALSE; |
1515 |
|
|
1516 |
*sneedptr = bfd_get_section_by_name (dynobj, ".need"); |
*sneedptr = bfd_get_section_by_name (dynobj, ".need"); |
1517 |
*srulesptr = bfd_get_section_by_name (dynobj, ".rules"); |
*srulesptr = bfd_get_section_by_name (dynobj, ".rules"); |
1518 |
|
|
1519 |
return true; |
return TRUE; |
1520 |
} |
} |
1521 |
|
|
1522 |
/* Scan the relocs for an input section. */ |
/* Scan the relocs for an input section. */ |
1523 |
|
|
1524 |
static boolean |
static bfd_boolean |
1525 |
sunos_scan_relocs (info, abfd, sec, rel_size) |
sunos_scan_relocs (info, abfd, sec, rel_size) |
1526 |
struct bfd_link_info *info; |
struct bfd_link_info *info; |
1527 |
bfd *abfd; |
bfd *abfd; |
1532 |
PTR free_relocs = NULL; |
PTR free_relocs = NULL; |
1533 |
|
|
1534 |
if (rel_size == 0) |
if (rel_size == 0) |
1535 |
return true; |
return TRUE; |
1536 |
|
|
1537 |
if (! info->keep_memory) |
if (! info->keep_memory) |
1538 |
relocs = free_relocs = bfd_malloc (rel_size); |
relocs = free_relocs = bfd_malloc (rel_size); |
1552 |
} |
} |
1553 |
} |
} |
1554 |
if (relocs == NULL) |
if (relocs == NULL) |
1555 |
return false; |
return FALSE; |
1556 |
|
|
1557 |
if (bfd_seek (abfd, sec->rel_filepos, SEEK_SET) != 0 |
if (bfd_seek (abfd, sec->rel_filepos, SEEK_SET) != 0 |
1558 |
|| bfd_bread (relocs, rel_size, abfd) != rel_size) |
|| bfd_bread (relocs, rel_size, abfd) != rel_size) |
1576 |
if (free_relocs != NULL) |
if (free_relocs != NULL) |
1577 |
free (free_relocs); |
free (free_relocs); |
1578 |
|
|
1579 |
return true; |
return TRUE; |
1580 |
|
|
1581 |
error_return: |
error_return: |
1582 |
if (free_relocs != NULL) |
if (free_relocs != NULL) |
1583 |
free (free_relocs); |
free (free_relocs); |
1584 |
return false; |
return FALSE; |
1585 |
} |
} |
1586 |
|
|
1587 |
/* Scan the relocs for an input section using standard relocs. We |
/* Scan the relocs for an input section using standard relocs. We |
1594 |
reloc. FIXME: We should also handle the PIC relocs here by |
reloc. FIXME: We should also handle the PIC relocs here by |
1595 |
building global offset table entries. */ |
building global offset table entries. */ |
1596 |
|
|
1597 |
static boolean |
static bfd_boolean |
1598 |
sunos_scan_std_relocs (info, abfd, sec, relocs, rel_size) |
sunos_scan_std_relocs (info, abfd, sec, relocs, rel_size) |
1599 |
struct bfd_link_info *info; |
struct bfd_link_info *info; |
1600 |
bfd *abfd; |
bfd *abfd; |
1612 |
if (bfd_get_arch (abfd) != bfd_arch_m68k) |
if (bfd_get_arch (abfd) != bfd_arch_m68k) |
1613 |
{ |
{ |
1614 |
bfd_set_error (bfd_error_invalid_target); |
bfd_set_error (bfd_error_invalid_target); |
1615 |
return false; |
return FALSE; |
1616 |
} |
} |
1617 |
|
|
1618 |
dynobj = NULL; |
dynobj = NULL; |
1674 |
{ |
{ |
1675 |
asection *sgot; |
asection *sgot; |
1676 |
|
|
1677 |
if (! sunos_create_dynamic_sections (abfd, info, false)) |
if (! sunos_create_dynamic_sections (abfd, info, FALSE)) |
1678 |
return false; |
return FALSE; |
1679 |
dynobj = sunos_hash_table (info)->dynobj; |
dynobj = sunos_hash_table (info)->dynobj; |
1680 |
splt = bfd_get_section_by_name (dynobj, ".plt"); |
splt = bfd_get_section_by_name (dynobj, ".plt"); |
1681 |
srel = bfd_get_section_by_name (dynobj, ".dynrel"); |
srel = bfd_get_section_by_name (dynobj, ".dynrel"); |
1683 |
|
|
1684 |
sgot = bfd_get_section_by_name (dynobj, ".got"); |
sgot = bfd_get_section_by_name (dynobj, ".got"); |
1685 |
BFD_ASSERT (sgot != NULL); |
BFD_ASSERT (sgot != NULL); |
1686 |
if (sgot->_raw_size == 0) |
if (sgot->size == 0) |
1687 |
sgot->_raw_size = BYTES_IN_WORD; |
sgot->size = BYTES_IN_WORD; |
1688 |
sunos_hash_table (info)->got_needed = true; |
sunos_hash_table (info)->got_needed = TRUE; |
1689 |
} |
} |
1690 |
|
|
1691 |
BFD_ASSERT ((h->flags & SUNOS_REF_REGULAR) != 0); |
BFD_ASSERT ((h->flags & SUNOS_REF_REGULAR) != 0); |
1703 |
{ |
{ |
1704 |
/* Presumably this symbol was marked as being undefined by |
/* Presumably this symbol was marked as being undefined by |
1705 |
an earlier reloc. */ |
an earlier reloc. */ |
1706 |
srel->_raw_size += RELOC_STD_SIZE; |
srel->size += RELOC_STD_SIZE; |
1707 |
} |
} |
1708 |
else if ((h->root.root.u.def.section->flags & SEC_CODE) == 0) |
else if ((h->root.root.u.def.section->flags & SEC_CODE) == 0) |
1709 |
{ |
{ |
1712 |
/* This reloc is not in the .text section. It must be |
/* This reloc is not in the .text section. It must be |
1713 |
copied into the dynamic relocs. We mark the symbol as |
copied into the dynamic relocs. We mark the symbol as |
1714 |
being undefined. */ |
being undefined. */ |
1715 |
srel->_raw_size += RELOC_STD_SIZE; |
srel->size += RELOC_STD_SIZE; |
1716 |
sub = h->root.root.u.def.section->owner; |
sub = h->root.root.u.def.section->owner; |
1717 |
h->root.root.type = bfd_link_hash_undefined; |
h->root.root.type = bfd_link_hash_undefined; |
1718 |
h->root.root.u.undef.abfd = sub; |
h->root.root.u.undef.abfd = sub; |
1726 |
be handled correctly. */ |
be handled correctly. */ |
1727 |
if (h->plt_offset == 0) |
if (h->plt_offset == 0) |
1728 |
{ |
{ |
1729 |
if (splt->_raw_size == 0) |
if (splt->size == 0) |
1730 |
splt->_raw_size = M68K_PLT_ENTRY_SIZE; |
splt->size = M68K_PLT_ENTRY_SIZE; |
1731 |
h->plt_offset = splt->_raw_size; |
h->plt_offset = splt->size; |
1732 |
|
|
1733 |
if ((h->flags & SUNOS_DEF_REGULAR) == 0) |
if ((h->flags & SUNOS_DEF_REGULAR) == 0) |
1734 |
{ |
{ |
1735 |
h->root.root.u.def.section = splt; |
h->root.root.u.def.section = splt; |
1736 |
h->root.root.u.def.value = splt->_raw_size; |
h->root.root.u.def.value = splt->size; |
1737 |
} |
} |
1738 |
|
|
1739 |
splt->_raw_size += M68K_PLT_ENTRY_SIZE; |
splt->size += M68K_PLT_ENTRY_SIZE; |
1740 |
|
|
1741 |
/* We may also need a dynamic reloc entry. */ |
/* We may also need a dynamic reloc entry. */ |
1742 |
if ((h->flags & SUNOS_DEF_REGULAR) == 0) |
if ((h->flags & SUNOS_DEF_REGULAR) == 0) |
1743 |
srel->_raw_size += RELOC_STD_SIZE; |
srel->size += RELOC_STD_SIZE; |
1744 |
} |
} |
1745 |
} |
} |
1746 |
} |
} |
1747 |
|
|
1748 |
return true; |
return TRUE; |
1749 |
} |
} |
1750 |
|
|
1751 |
/* Scan the relocs for an input section using extended relocs. We |
/* Scan the relocs for an input section using extended relocs. We |
1754 |
section, an entry is made in the procedure linkage table. |
section, an entry is made in the procedure linkage table. |
1755 |
Otherwise, we must preserve the reloc as a dynamic reloc. */ |
Otherwise, we must preserve the reloc as a dynamic reloc. */ |
1756 |
|
|
1757 |
static boolean |
static bfd_boolean |
1758 |
sunos_scan_ext_relocs (info, abfd, sec, relocs, rel_size) |
sunos_scan_ext_relocs (info, abfd, sec, relocs, rel_size) |
1759 |
struct bfd_link_info *info; |
struct bfd_link_info *info; |
1760 |
bfd *abfd; |
bfd *abfd; |
1774 |
if (bfd_get_arch (abfd) != bfd_arch_sparc) |
if (bfd_get_arch (abfd) != bfd_arch_sparc) |
1775 |
{ |
{ |
1776 |
bfd_set_error (bfd_error_invalid_target); |
bfd_set_error (bfd_error_invalid_target); |
1777 |
return false; |
return FALSE; |
1778 |
} |
} |
1779 |
|
|
1780 |
dynobj = NULL; |
dynobj = NULL; |
1821 |
} |
} |
1822 |
|
|
1823 |
/* If this is a base relative reloc, we need to make an entry in |
/* If this is a base relative reloc, we need to make an entry in |
1824 |
the .got section. */ |
the .got section. */ |
1825 |
if (r_type == RELOC_BASE10 |
if (r_type == RELOC_BASE10 |
1826 |
|| r_type == RELOC_BASE13 |
|| r_type == RELOC_BASE13 |
1827 |
|| r_type == RELOC_BASE22) |
|| r_type == RELOC_BASE22) |
1828 |
{ |
{ |
1829 |
if (dynobj == NULL) |
if (dynobj == NULL) |
1830 |
{ |
{ |
1831 |
if (! sunos_create_dynamic_sections (abfd, info, false)) |
if (! sunos_create_dynamic_sections (abfd, info, FALSE)) |
1832 |
return false; |
return FALSE; |
1833 |
dynobj = sunos_hash_table (info)->dynobj; |
dynobj = sunos_hash_table (info)->dynobj; |
1834 |
splt = bfd_get_section_by_name (dynobj, ".plt"); |
splt = bfd_get_section_by_name (dynobj, ".plt"); |
1835 |
sgot = bfd_get_section_by_name (dynobj, ".got"); |
sgot = bfd_get_section_by_name (dynobj, ".got"); |
1837 |
BFD_ASSERT (splt != NULL && sgot != NULL && srel != NULL); |
BFD_ASSERT (splt != NULL && sgot != NULL && srel != NULL); |
1838 |
|
|
1839 |
/* Make sure we have an initial entry in the .got table. */ |
/* Make sure we have an initial entry in the .got table. */ |
1840 |
if (sgot->_raw_size == 0) |
if (sgot->size == 0) |
1841 |
sgot->_raw_size = BYTES_IN_WORD; |
sgot->size = BYTES_IN_WORD; |
1842 |
sunos_hash_table (info)->got_needed = true; |
sunos_hash_table (info)->got_needed = TRUE; |
1843 |
} |
} |
1844 |
|
|
1845 |
if (r_extern) |
if (r_extern) |
1847 |
if (h->got_offset != 0) |
if (h->got_offset != 0) |
1848 |
continue; |
continue; |
1849 |
|
|
1850 |
h->got_offset = sgot->_raw_size; |
h->got_offset = sgot->size; |
1851 |
} |
} |
1852 |
else |
else |
1853 |
{ |
{ |
1865 |
adata (abfd).local_got_offsets = |
adata (abfd).local_got_offsets = |
1866 |
(bfd_vma *) bfd_zalloc (abfd, amt); |
(bfd_vma *) bfd_zalloc (abfd, amt); |
1867 |
if (adata (abfd).local_got_offsets == NULL) |
if (adata (abfd).local_got_offsets == NULL) |
1868 |
return false; |
return FALSE; |
1869 |
} |
} |
1870 |
|
|
1871 |
if (adata (abfd).local_got_offsets[r_index] != 0) |
if (adata (abfd).local_got_offsets[r_index] != 0) |
1872 |
continue; |
continue; |
1873 |
|
|
1874 |
adata (abfd).local_got_offsets[r_index] = sgot->_raw_size; |
adata (abfd).local_got_offsets[r_index] = sgot->size; |
1875 |
} |
} |
1876 |
|
|
1877 |
sgot->_raw_size += BYTES_IN_WORD; |
sgot->size += BYTES_IN_WORD; |
1878 |
|
|
1879 |
/* If we are making a shared library, or if the symbol is |
/* If we are making a shared library, or if the symbol is |
1880 |
defined by a dynamic object, we will need a dynamic reloc |
defined by a dynamic object, we will need a dynamic reloc |
1883 |
|| (h != NULL |
|| (h != NULL |
1884 |
&& (h->flags & SUNOS_DEF_DYNAMIC) != 0 |
&& (h->flags & SUNOS_DEF_DYNAMIC) != 0 |
1885 |
&& (h->flags & SUNOS_DEF_REGULAR) == 0)) |
&& (h->flags & SUNOS_DEF_REGULAR) == 0)) |
1886 |
srel->_raw_size += RELOC_EXT_SIZE; |
srel->size += RELOC_EXT_SIZE; |
1887 |
|
|
1888 |
continue; |
continue; |
1889 |
} |
} |
1890 |
|
|
1891 |
/* Otherwise, we are only interested in relocs against symbols |
/* Otherwise, we are only interested in relocs against symbols |
1892 |
defined in dynamic objects but not in regular objects. We |
defined in dynamic objects but not in regular objects. We |
1893 |
only need to consider relocs against external symbols. */ |
only need to consider relocs against external symbols. */ |
1894 |
if (! r_extern) |
if (! r_extern) |
1895 |
{ |
{ |
1896 |
/* But, if we are creating a shared library, we need to |
/* But, if we are creating a shared library, we need to |
1897 |
generate an absolute reloc. */ |
generate an absolute reloc. */ |
1898 |
if (info->shared) |
if (info->shared) |
1899 |
{ |
{ |
1900 |
if (dynobj == NULL) |
if (dynobj == NULL) |
1901 |
{ |
{ |
1902 |
if (! sunos_create_dynamic_sections (abfd, info, true)) |
if (! sunos_create_dynamic_sections (abfd, info, TRUE)) |
1903 |
return false; |
return FALSE; |
1904 |
dynobj = sunos_hash_table (info)->dynobj; |
dynobj = sunos_hash_table (info)->dynobj; |
1905 |
splt = bfd_get_section_by_name (dynobj, ".plt"); |
splt = bfd_get_section_by_name (dynobj, ".plt"); |
1906 |
sgot = bfd_get_section_by_name (dynobj, ".got"); |
sgot = bfd_get_section_by_name (dynobj, ".got"); |
1908 |
BFD_ASSERT (splt != NULL && sgot != NULL && srel != NULL); |
BFD_ASSERT (splt != NULL && sgot != NULL && srel != NULL); |
1909 |
} |
} |
1910 |
|
|
1911 |
srel->_raw_size += RELOC_EXT_SIZE; |
srel->size += RELOC_EXT_SIZE; |
1912 |
} |
} |
1913 |
|
|
1914 |
continue; |
continue; |
1936 |
&& (h->flags & SUNOS_DEF_REGULAR) == 0) |
&& (h->flags & SUNOS_DEF_REGULAR) == 0) |
1937 |
{ |
{ |
1938 |
/* This symbol is apparently undefined. Don't do anything |
/* This symbol is apparently undefined. Don't do anything |
1939 |
here; just let the relocation routine report an undefined |
here; just let the relocation routine report an undefined |
1940 |
symbol. */ |
symbol. */ |
1941 |
continue; |
continue; |
1942 |
} |
} |
1943 |
|
|
1946 |
|
|
1947 |
if (dynobj == NULL) |
if (dynobj == NULL) |
1948 |
{ |
{ |
1949 |
if (! sunos_create_dynamic_sections (abfd, info, false)) |
if (! sunos_create_dynamic_sections (abfd, info, FALSE)) |
1950 |
return false; |
return FALSE; |
1951 |
dynobj = sunos_hash_table (info)->dynobj; |
dynobj = sunos_hash_table (info)->dynobj; |
1952 |
splt = bfd_get_section_by_name (dynobj, ".plt"); |
splt = bfd_get_section_by_name (dynobj, ".plt"); |
1953 |
sgot = bfd_get_section_by_name (dynobj, ".got"); |
sgot = bfd_get_section_by_name (dynobj, ".got"); |
1955 |
BFD_ASSERT (splt != NULL && sgot != NULL && srel != NULL); |
BFD_ASSERT (splt != NULL && sgot != NULL && srel != NULL); |
1956 |
|
|
1957 |
/* Make sure we have an initial entry in the .got table. */ |
/* Make sure we have an initial entry in the .got table. */ |
1958 |
if (sgot->_raw_size == 0) |
if (sgot->size == 0) |
1959 |
sgot->_raw_size = BYTES_IN_WORD; |
sgot->size = BYTES_IN_WORD; |
1960 |
sunos_hash_table (info)->got_needed = true; |
sunos_hash_table (info)->got_needed = TRUE; |
1961 |
} |
} |
1962 |
|
|
1963 |
BFD_ASSERT (r_type == RELOC_JMP_TBL |
BFD_ASSERT (r_type == RELOC_JMP_TBL |
1980 |
{ |
{ |
1981 |
/* Presumably this symbol was marked as being undefined by |
/* Presumably this symbol was marked as being undefined by |
1982 |
an earlier reloc. */ |
an earlier reloc. */ |
1983 |
srel->_raw_size += RELOC_EXT_SIZE; |
srel->size += RELOC_EXT_SIZE; |
1984 |
} |
} |
1985 |
else if (r_type != RELOC_JMP_TBL |
else if (r_type != RELOC_JMP_TBL |
1986 |
&& (h->root.root.u.def.section->flags & SEC_CODE) == 0) |
&& (h->root.root.u.def.section->flags & SEC_CODE) == 0) |
1990 |
/* This reloc is not in the .text section. It must be |
/* This reloc is not in the .text section. It must be |
1991 |
copied into the dynamic relocs. We mark the symbol as |
copied into the dynamic relocs. We mark the symbol as |
1992 |
being undefined. */ |
being undefined. */ |
1993 |
srel->_raw_size += RELOC_EXT_SIZE; |
srel->size += RELOC_EXT_SIZE; |
1994 |
if ((h->flags & SUNOS_DEF_REGULAR) == 0) |
if ((h->flags & SUNOS_DEF_REGULAR) == 0) |
1995 |
{ |
{ |
1996 |
sub = h->root.root.u.def.section->owner; |
sub = h->root.root.u.def.section->owner; |
2007 |
be handled correctly. */ |
be handled correctly. */ |
2008 |
if (h->plt_offset == 0) |
if (h->plt_offset == 0) |
2009 |
{ |
{ |
2010 |
if (splt->_raw_size == 0) |
if (splt->size == 0) |
2011 |
splt->_raw_size = SPARC_PLT_ENTRY_SIZE; |
splt->size = SPARC_PLT_ENTRY_SIZE; |
2012 |
h->plt_offset = splt->_raw_size; |
h->plt_offset = splt->size; |
2013 |
|
|
2014 |
if ((h->flags & SUNOS_DEF_REGULAR) == 0) |
if ((h->flags & SUNOS_DEF_REGULAR) == 0) |
2015 |
{ |
{ |
2016 |
if (h->root.root.type == bfd_link_hash_undefined) |
if (h->root.root.type == bfd_link_hash_undefined) |
2017 |
h->root.root.type = bfd_link_hash_defined; |
h->root.root.type = bfd_link_hash_defined; |
2018 |
h->root.root.u.def.section = splt; |
h->root.root.u.def.section = splt; |
2019 |
h->root.root.u.def.value = splt->_raw_size; |
h->root.root.u.def.value = splt->size; |
2020 |
} |
} |
2021 |
|
|
2022 |
splt->_raw_size += SPARC_PLT_ENTRY_SIZE; |
splt->size += SPARC_PLT_ENTRY_SIZE; |
2023 |
|
|
2024 |
/* We will also need a dynamic reloc entry, unless this |
/* We will also need a dynamic reloc entry, unless this |
2025 |
is a JMP_TBL reloc produced by linking PIC compiled |
is a JMP_TBL reloc produced by linking PIC compiled |
2026 |
code, and we are not making a shared library. */ |
code, and we are not making a shared library. */ |
2027 |
if (info->shared || (h->flags & SUNOS_DEF_REGULAR) == 0) |
if (info->shared || (h->flags & SUNOS_DEF_REGULAR) == 0) |
2028 |
srel->_raw_size += RELOC_EXT_SIZE; |
srel->size += RELOC_EXT_SIZE; |
2029 |
} |
} |
2030 |
|
|
2031 |
/* If we are creating a shared library, we need to copy over |
/* If we are creating a shared library, we need to copy over |
2032 |
any reloc other than a jump table reloc. */ |
any reloc other than a jump table reloc. */ |
2033 |
if (info->shared && r_type != RELOC_JMP_TBL) |
if (info->shared && r_type != RELOC_JMP_TBL) |
2034 |
srel->_raw_size += RELOC_EXT_SIZE; |
srel->size += RELOC_EXT_SIZE; |
2035 |
} |
} |
2036 |
} |
} |
2037 |
|
|
2038 |
return true; |
return TRUE; |
2039 |
} |
} |
2040 |
|
|
2041 |
/* Build the hash table of dynamic symbols, and to mark as written all |
/* Build the hash table of dynamic symbols, and to mark as written all |
2042 |
symbols from dynamic objects which we do not plan to write out. */ |
symbols from dynamic objects which we do not plan to write out. */ |
2043 |
|
|
2044 |
static boolean |
static bfd_boolean |
2045 |
sunos_scan_dynamic_symbol (h, data) |
sunos_scan_dynamic_symbol (h, data) |
2046 |
struct sunos_link_hash_entry *h; |
struct sunos_link_hash_entry *h; |
2047 |
PTR data; |
PTR data; |
2063 |
if ((h->flags & SUNOS_DEF_REGULAR) == 0 |
if ((h->flags & SUNOS_DEF_REGULAR) == 0 |
2064 |
&& (h->flags & SUNOS_DEF_DYNAMIC) != 0 |
&& (h->flags & SUNOS_DEF_DYNAMIC) != 0 |
2065 |
&& strcmp (h->root.root.root.string, "__DYNAMIC") != 0) |
&& strcmp (h->root.root.root.string, "__DYNAMIC") != 0) |
2066 |
h->root.written = true; |
h->root.written = TRUE; |
2067 |
|
|
2068 |
/* If this symbol is defined by a dynamic object and referenced by a |
/* If this symbol is defined by a dynamic object and referenced by a |
2069 |
regular object, see whether we gave it a reasonable value while |
regular object, see whether we gave it a reasonable value while |
2120 |
s = bfd_get_section_by_name (dynobj, ".dynstr"); |
s = bfd_get_section_by_name (dynobj, ".dynstr"); |
2121 |
BFD_ASSERT (s != NULL); |
BFD_ASSERT (s != NULL); |
2122 |
contents = (bfd_byte *) bfd_realloc (s->contents, |
contents = (bfd_byte *) bfd_realloc (s->contents, |
2123 |
s->_raw_size + len + 1); |
s->size + len + 1); |
2124 |
if (contents == NULL) |
if (contents == NULL) |
2125 |
return false; |
return FALSE; |
2126 |
s->contents = contents; |
s->contents = contents; |
2127 |
|
|
2128 |
h->dynstr_index = s->_raw_size; |
h->dynstr_index = s->size; |
2129 |
strcpy ((char *) contents + s->_raw_size, h->root.root.root.string); |
strcpy ((char *) contents + s->size, h->root.root.root.string); |
2130 |
s->_raw_size += len + 1; |
s->size += len + 1; |
2131 |
|
|
2132 |
/* Add it to the dynamic hash table. */ |
/* Add it to the dynamic hash table. */ |
2133 |
name = (unsigned char *) h->root.root.root.string; |
name = (unsigned char *) h->root.root.root.string; |
2150 |
(s->contents |
(s->contents |
2151 |
+ hash * HASH_ENTRY_SIZE |
+ hash * HASH_ENTRY_SIZE |
2152 |
+ BYTES_IN_WORD)); |
+ BYTES_IN_WORD)); |
2153 |
PUT_WORD (dynobj, s->_raw_size / HASH_ENTRY_SIZE, |
PUT_WORD (dynobj, s->size / HASH_ENTRY_SIZE, |
2154 |
s->contents + hash * HASH_ENTRY_SIZE + BYTES_IN_WORD); |
s->contents + hash * HASH_ENTRY_SIZE + BYTES_IN_WORD); |
2155 |
PUT_WORD (dynobj, h->dynindx, s->contents + s->_raw_size); |
PUT_WORD (dynobj, h->dynindx, s->contents + s->size); |
2156 |
PUT_WORD (dynobj, next, s->contents + s->_raw_size + BYTES_IN_WORD); |
PUT_WORD (dynobj, next, s->contents + s->size + BYTES_IN_WORD); |
2157 |
s->_raw_size += HASH_ENTRY_SIZE; |
s->size += HASH_ENTRY_SIZE; |
2158 |
} |
} |
2159 |
} |
} |
2160 |
|
|
2161 |
return true; |
return TRUE; |
2162 |
} |
} |
2163 |
|
|
2164 |
/* Link a dynamic object. We actually don't have anything to do at |
/* Link a dynamic object. We actually don't have anything to do at |
2165 |
this point. This entry point exists to prevent the regular linker |
this point. This entry point exists to prevent the regular linker |
2166 |
code from doing anything with the object. */ |
code from doing anything with the object. */ |
2167 |
|
|
2168 |
/*ARGSUSED*/ |
static bfd_boolean |
|
static boolean |
|
2169 |
sunos_link_dynamic_object (info, abfd) |
sunos_link_dynamic_object (info, abfd) |
2170 |
struct bfd_link_info *info ATTRIBUTE_UNUSED; |
struct bfd_link_info *info ATTRIBUTE_UNUSED; |
2171 |
bfd *abfd ATTRIBUTE_UNUSED; |
bfd *abfd ATTRIBUTE_UNUSED; |
2172 |
{ |
{ |
2173 |
return true; |
return TRUE; |
2174 |
} |
} |
2175 |
|
|
2176 |
/* Write out a dynamic symbol. This is called by the final traversal |
/* Write out a dynamic symbol. This is called by the final traversal |
2177 |
over the symbol table. */ |
over the symbol table. */ |
2178 |
|
|
2179 |
static boolean |
static bfd_boolean |
2180 |
sunos_write_dynamic_symbol (output_bfd, info, harg) |
sunos_write_dynamic_symbol (output_bfd, info, harg) |
2181 |
bfd *output_bfd; |
bfd *output_bfd; |
2182 |
struct bfd_link_info *info; |
struct bfd_link_info *info; |
2250 |
} |
} |
2251 |
|
|
2252 |
/* We also need to add a jump table reloc, unless this is the |
/* We also need to add a jump table reloc, unless this is the |
2253 |
result of a JMP_TBL reloc from PIC compiled code. */ |
result of a JMP_TBL reloc from PIC compiled code. */ |
2254 |
if (info->shared || (h->flags & SUNOS_DEF_REGULAR) == 0) |
if (info->shared || (h->flags & SUNOS_DEF_REGULAR) == 0) |
2255 |
{ |
{ |
2256 |
BFD_ASSERT (h->dynindx >= 0); |
BFD_ASSERT (h->dynindx >= 0); |
2257 |
BFD_ASSERT (s->reloc_count * obj_reloc_entry_size (dynobj) |
BFD_ASSERT (s->reloc_count * obj_reloc_entry_size (dynobj) |
2258 |
< s->_raw_size); |
< s->size); |
2259 |
p = s->contents + s->reloc_count * obj_reloc_entry_size (output_bfd); |
p = s->contents + s->reloc_count * obj_reloc_entry_size (output_bfd); |
2260 |
if (obj_reloc_entry_size (output_bfd) == RELOC_STD_SIZE) |
if (obj_reloc_entry_size (output_bfd) == RELOC_STD_SIZE) |
2261 |
{ |
{ |
2316 |
we can have a PLT entry for a nondynamic symbol when linking PIC |
we can have a PLT entry for a nondynamic symbol when linking PIC |
2317 |
compiled code from a regular object. */ |
compiled code from a regular object. */ |
2318 |
if (h->dynindx < 0) |
if (h->dynindx < 0) |
2319 |
return true; |
return TRUE; |
2320 |
|
|
2321 |
switch (h->root.root.type) |
switch (h->root.root.type) |
2322 |
{ |
{ |
2324 |
case bfd_link_hash_new: |
case bfd_link_hash_new: |
2325 |
abort (); |
abort (); |
2326 |
/* Avoid variable not initialized warnings. */ |
/* Avoid variable not initialized warnings. */ |
2327 |
return true; |
return TRUE; |
2328 |
case bfd_link_hash_undefined: |
case bfd_link_hash_undefined: |
2329 |
type = N_UNDF | N_EXT; |
type = N_UNDF | N_EXT; |
2330 |
val = 0; |
val = 0; |
2382 |
case bfd_link_hash_warning: |
case bfd_link_hash_warning: |
2383 |
/* FIXME: Ignore these for now. The circumstances under which |
/* FIXME: Ignore these for now. The circumstances under which |
2384 |
they should be written out are not clear to me. */ |
they should be written out are not clear to me. */ |
2385 |
return true; |
return TRUE; |
2386 |
} |
} |
2387 |
|
|
2388 |
s = bfd_get_section_by_name (sunos_hash_table (info)->dynobj, ".dynsym"); |
s = bfd_get_section_by_name (sunos_hash_table (info)->dynobj, ".dynsym"); |
2401 |
PUT_WORD (output_bfd, h->dynstr_index, outsym->e_strx); |
PUT_WORD (output_bfd, h->dynstr_index, outsym->e_strx); |
2402 |
PUT_WORD (output_bfd, val, outsym->e_value); |
PUT_WORD (output_bfd, val, outsym->e_value); |
2403 |
|
|
2404 |
return true; |
return TRUE; |
2405 |
} |
} |
2406 |
|
|
2407 |
/* This is called for each reloc against an external symbol. If this |
/* This is called for each reloc against an external symbol. If this |
2409 |
copy it over, and tell the caller to not bother processing this |
copy it over, and tell the caller to not bother processing this |
2410 |
reloc. */ |
reloc. */ |
2411 |
|
|
2412 |
/*ARGSUSED*/ |
static bfd_boolean |
|
static boolean |
|
2413 |
sunos_check_dynamic_reloc (info, input_bfd, input_section, harg, reloc, |
sunos_check_dynamic_reloc (info, input_bfd, input_section, harg, reloc, |
2414 |
contents, skip, relocationp) |
contents, skip, relocationp) |
2415 |
struct bfd_link_info *info; |
struct bfd_link_info *info; |
2418 |
struct aout_link_hash_entry *harg; |
struct aout_link_hash_entry *harg; |
2419 |
PTR reloc; |
PTR reloc; |
2420 |
bfd_byte *contents ATTRIBUTE_UNUSED; |
bfd_byte *contents ATTRIBUTE_UNUSED; |
2421 |
boolean *skip; |
bfd_boolean *skip; |
2422 |
bfd_vma *relocationp; |
bfd_vma *relocationp; |
2423 |
{ |
{ |
2424 |
struct sunos_link_hash_entry *h = (struct sunos_link_hash_entry *) harg; |
struct sunos_link_hash_entry *h = (struct sunos_link_hash_entry *) harg; |
2425 |
bfd *dynobj; |
bfd *dynobj; |
2426 |
boolean baserel; |
bfd_boolean baserel; |
2427 |
boolean jmptbl; |
bfd_boolean jmptbl; |
2428 |
boolean pcrel; |
bfd_boolean pcrel; |
2429 |
asection *s; |
asection *s; |
2430 |
bfd_byte *p; |
bfd_byte *p; |
2431 |
long indx; |
long indx; |
2432 |
|
|
2433 |
*skip = false; |
*skip = FALSE; |
2434 |
|
|
2435 |
dynobj = sunos_hash_table (info)->dynobj; |
dynobj = sunos_hash_table (info)->dynobj; |
2436 |
|
|
2488 |
|| r_type == RELOC_WDISP30 |
|| r_type == RELOC_WDISP30 |
2489 |
|| r_type == RELOC_WDISP22); |
|| r_type == RELOC_WDISP22); |
2490 |
/* We don't consider the PC10 and PC22 types to be PC relative, |
/* We don't consider the PC10 and PC22 types to be PC relative, |
2491 |
because they are pcrel_offset. */ |
because they are pcrel_offset. */ |
2492 |
} |
} |
2493 |
|
|
2494 |
if (baserel) |
if (baserel) |
2557 |
&& (h->flags & SUNOS_DEF_REGULAR) == 0)) |
&& (h->flags & SUNOS_DEF_REGULAR) == 0)) |
2558 |
{ |
{ |
2559 |
/* We need to create a GLOB_DAT or 32 reloc to tell the |
/* We need to create a GLOB_DAT or 32 reloc to tell the |
2560 |
dynamic linker to fill in this entry in the table. */ |
dynamic linker to fill in this entry in the table. */ |
2561 |
|
|
2562 |
s = bfd_get_section_by_name (dynobj, ".dynrel"); |
s = bfd_get_section_by_name (dynobj, ".dynrel"); |
2563 |
BFD_ASSERT (s != NULL); |
BFD_ASSERT (s != NULL); |
2564 |
BFD_ASSERT (s->reloc_count * obj_reloc_entry_size (dynobj) |
BFD_ASSERT (s->reloc_count * obj_reloc_entry_size (dynobj) |
2565 |
< s->_raw_size); |
< s->size); |
2566 |
|
|
2567 |
p = (s->contents |
p = (s->contents |
2568 |
+ s->reloc_count * obj_reloc_entry_size (dynobj)); |
+ s->reloc_count * obj_reloc_entry_size (dynobj)); |
2662 |
- sunos_hash_table (info)->got_base); |
- sunos_hash_table (info)->got_base); |
2663 |
|
|
2664 |
/* There is nothing else to do for a base relative reloc. */ |
/* There is nothing else to do for a base relative reloc. */ |
2665 |
return true; |
return TRUE; |
2666 |
} |
} |
2667 |
|
|
2668 |
if (! sunos_hash_table (info)->dynamic_sections_needed) |
if (! sunos_hash_table (info)->dynamic_sections_needed) |
2669 |
return true; |
return TRUE; |
2670 |
if (! info->shared) |
if (! info->shared) |
2671 |
{ |
{ |
2672 |
if (h == NULL |
if (h == NULL |
2675 |
|| (h->flags & SUNOS_DEF_REGULAR) != 0 |
|| (h->flags & SUNOS_DEF_REGULAR) != 0 |
2676 |
|| (h->flags & SUNOS_DEF_DYNAMIC) == 0 |
|| (h->flags & SUNOS_DEF_DYNAMIC) == 0 |
2677 |
|| (h->root.root.u.undef.abfd->flags & DYNAMIC) == 0) |
|| (h->root.root.u.undef.abfd->flags & DYNAMIC) == 0) |
2678 |
return true; |
return TRUE; |
2679 |
} |
} |
2680 |
else |
else |
2681 |
{ |
{ |
2684 |
|| jmptbl |
|| jmptbl |
2685 |
|| strcmp (h->root.root.root.string, |
|| strcmp (h->root.root.root.string, |
2686 |
"__GLOBAL_OFFSET_TABLE_") == 0)) |
"__GLOBAL_OFFSET_TABLE_") == 0)) |
2687 |
return true; |
return TRUE; |
2688 |
} |
} |
2689 |
|
|
2690 |
/* It looks like this is a reloc we are supposed to copy. */ |
/* It looks like this is a reloc we are supposed to copy. */ |
2691 |
|
|
2692 |
s = bfd_get_section_by_name (dynobj, ".dynrel"); |
s = bfd_get_section_by_name (dynobj, ".dynrel"); |
2693 |
BFD_ASSERT (s != NULL); |
BFD_ASSERT (s != NULL); |
2694 |
BFD_ASSERT (s->reloc_count * obj_reloc_entry_size (dynobj) < s->_raw_size); |
BFD_ASSERT (s->reloc_count * obj_reloc_entry_size (dynobj) < s->size); |
2695 |
|
|
2696 |
p = s->contents + s->reloc_count * obj_reloc_entry_size (dynobj); |
p = s->contents + s->reloc_count * obj_reloc_entry_size (dynobj); |
2697 |
|
|
2727 |
srel->r_index[0] = (bfd_byte)indx; |
srel->r_index[0] = (bfd_byte)indx; |
2728 |
} |
} |
2729 |
/* FIXME: We may have to change the addend for a PC relative |
/* FIXME: We may have to change the addend for a PC relative |
2730 |
reloc. */ |
reloc. */ |
2731 |
} |
} |
2732 |
else |
else |
2733 |
{ |
{ |
2766 |
++s->reloc_count; |
++s->reloc_count; |
2767 |
|
|
2768 |
if (h != NULL) |
if (h != NULL) |
2769 |
*skip = true; |
*skip = TRUE; |
2770 |
|
|
2771 |
return true; |
return TRUE; |
2772 |
} |
} |
2773 |
|
|
2774 |
/* Finish up the dynamic linking information. */ |
/* Finish up the dynamic linking information. */ |
2775 |
|
|
2776 |
static boolean |
static bfd_boolean |
2777 |
sunos_finish_dynamic_link (abfd, info) |
sunos_finish_dynamic_link (abfd, info) |
2778 |
bfd *abfd; |
bfd *abfd; |
2779 |
struct bfd_link_info *info; |
struct bfd_link_info *info; |
2785 |
|
|
2786 |
if (! sunos_hash_table (info)->dynamic_sections_needed |
if (! sunos_hash_table (info)->dynamic_sections_needed |
2787 |
&& ! sunos_hash_table (info)->got_needed) |
&& ! sunos_hash_table (info)->got_needed) |
2788 |
return true; |
return TRUE; |
2789 |
|
|
2790 |
dynobj = sunos_hash_table (info)->dynobj; |
dynobj = sunos_hash_table (info)->dynobj; |
2791 |
|
|
2797 |
real addresses. Now that we know the section location, we can |
real addresses. Now that we know the section location, we can |
2798 |
fill in the final values. */ |
fill in the final values. */ |
2799 |
s = bfd_get_section_by_name (dynobj, ".need"); |
s = bfd_get_section_by_name (dynobj, ".need"); |
2800 |
if (s != NULL && s->_raw_size != 0) |
if (s != NULL && s->size != 0) |
2801 |
{ |
{ |
2802 |
file_ptr filepos; |
file_ptr filepos; |
2803 |
bfd_byte *p; |
bfd_byte *p; |
2821 |
dynamic information, unless this is a shared library. */ |
dynamic information, unless this is a shared library. */ |
2822 |
s = bfd_get_section_by_name (dynobj, ".got"); |
s = bfd_get_section_by_name (dynobj, ".got"); |
2823 |
BFD_ASSERT (s != NULL); |
BFD_ASSERT (s != NULL); |
2824 |
if (info->shared || sdyn->_raw_size == 0) |
if (info->shared || sdyn->size == 0) |
2825 |
PUT_WORD (dynobj, 0, s->contents); |
PUT_WORD (dynobj, 0, s->contents); |
2826 |
else |
else |
2827 |
PUT_WORD (dynobj, sdyn->output_section->vma + sdyn->output_offset, |
PUT_WORD (dynobj, sdyn->output_section->vma + sdyn->output_offset, |
2837 |
if (! bfd_set_section_contents (abfd, o->output_section, |
if (! bfd_set_section_contents (abfd, o->output_section, |
2838 |
o->contents, |
o->contents, |
2839 |
(file_ptr) o->output_offset, |
(file_ptr) o->output_offset, |
2840 |
o->_raw_size)) |
o->size)) |
2841 |
return false; |
return FALSE; |
2842 |
} |
} |
2843 |
} |
} |
2844 |
|
|
2845 |
if (sdyn->_raw_size > 0) |
if (sdyn->size > 0) |
2846 |
{ |
{ |
2847 |
struct external_sun4_dynamic esd; |
struct external_sun4_dynamic esd; |
2848 |
struct external_sun4_dynamic_link esdl; |
struct external_sun4_dynamic_link esdl; |
2863 |
if (! bfd_set_section_contents (abfd, sdyn->output_section, &esd, |
if (! bfd_set_section_contents (abfd, sdyn->output_section, &esd, |
2864 |
(file_ptr) sdyn->output_offset, |
(file_ptr) sdyn->output_offset, |
2865 |
(bfd_size_type) sizeof esd)) |
(bfd_size_type) sizeof esd)) |
2866 |
return false; |
return FALSE; |
2867 |
|
|
2868 |
PUT_WORD (dynobj, (bfd_vma) 0, esdl.ld_loaded); |
PUT_WORD (dynobj, (bfd_vma) 0, esdl.ld_loaded); |
2869 |
|
|
2870 |
s = bfd_get_section_by_name (dynobj, ".need"); |
s = bfd_get_section_by_name (dynobj, ".need"); |
2871 |
if (s == NULL || s->_raw_size == 0) |
if (s == NULL || s->size == 0) |
2872 |
PUT_WORD (dynobj, (bfd_vma) 0, esdl.ld_need); |
PUT_WORD (dynobj, (bfd_vma) 0, esdl.ld_need); |
2873 |
else |
else |
2874 |
PUT_WORD (dynobj, s->output_section->filepos + s->output_offset, |
PUT_WORD (dynobj, s->output_section->filepos + s->output_offset, |
2875 |
esdl.ld_need); |
esdl.ld_need); |
2876 |
|
|
2877 |
s = bfd_get_section_by_name (dynobj, ".rules"); |
s = bfd_get_section_by_name (dynobj, ".rules"); |
2878 |
if (s == NULL || s->_raw_size == 0) |
if (s == NULL || s->size == 0) |
2879 |
PUT_WORD (dynobj, (bfd_vma) 0, esdl.ld_rules); |
PUT_WORD (dynobj, (bfd_vma) 0, esdl.ld_rules); |
2880 |
else |
else |
2881 |
PUT_WORD (dynobj, s->output_section->filepos + s->output_offset, |
PUT_WORD (dynobj, s->output_section->filepos + s->output_offset, |
2890 |
BFD_ASSERT (s != NULL); |
BFD_ASSERT (s != NULL); |
2891 |
PUT_WORD (dynobj, s->output_section->vma + s->output_offset, |
PUT_WORD (dynobj, s->output_section->vma + s->output_offset, |
2892 |
esdl.ld_plt); |
esdl.ld_plt); |
2893 |
PUT_WORD (dynobj, s->_raw_size, esdl.ld_plt_sz); |
PUT_WORD (dynobj, s->size, esdl.ld_plt_sz); |
2894 |
|
|
2895 |
s = bfd_get_section_by_name (dynobj, ".dynrel"); |
s = bfd_get_section_by_name (dynobj, ".dynrel"); |
2896 |
BFD_ASSERT (s != NULL); |
BFD_ASSERT (s != NULL); |
2897 |
BFD_ASSERT (s->reloc_count * obj_reloc_entry_size (dynobj) |
BFD_ASSERT (s->reloc_count * obj_reloc_entry_size (dynobj) |
2898 |
== s->_raw_size); |
== s->size); |
2899 |
PUT_WORD (dynobj, s->output_section->filepos + s->output_offset, |
PUT_WORD (dynobj, s->output_section->filepos + s->output_offset, |
2900 |
esdl.ld_rel); |
esdl.ld_rel); |
2901 |
|
|
2918 |
BFD_ASSERT (s != NULL); |
BFD_ASSERT (s != NULL); |
2919 |
PUT_WORD (dynobj, s->output_section->filepos + s->output_offset, |
PUT_WORD (dynobj, s->output_section->filepos + s->output_offset, |
2920 |
esdl.ld_symbols); |
esdl.ld_symbols); |
2921 |
PUT_WORD (dynobj, s->_raw_size, esdl.ld_symb_size); |
PUT_WORD (dynobj, s->size, esdl.ld_symb_size); |
2922 |
|
|
2923 |
/* The size of the text area is the size of the .text section |
/* The size of the text area is the size of the .text section |
2924 |
rounded up to a page boundary. FIXME: Should the page size be |
rounded up to a page boundary. FIXME: Should the page size be |
2925 |
conditional on something? */ |
conditional on something? */ |
2926 |
PUT_WORD (dynobj, |
PUT_WORD (dynobj, |
2927 |
BFD_ALIGN (obj_textsec (abfd)->_raw_size, 0x2000), |
BFD_ALIGN (obj_textsec (abfd)->size, 0x2000), |
2928 |
esdl.ld_text); |
esdl.ld_text); |
2929 |
|
|
2930 |
pos = sdyn->output_offset; |
pos = sdyn->output_offset; |
2931 |
pos += sizeof esd + EXTERNAL_SUN4_DYNAMIC_DEBUGGER_SIZE; |
pos += sizeof esd + EXTERNAL_SUN4_DYNAMIC_DEBUGGER_SIZE; |
2932 |
if (! bfd_set_section_contents (abfd, sdyn->output_section, &esdl, |
if (! bfd_set_section_contents (abfd, sdyn->output_section, &esdl, |
2933 |
pos, (bfd_size_type) sizeof esdl)) |
pos, (bfd_size_type) sizeof esdl)) |
2934 |
return false; |
return FALSE; |
2935 |
|
|
2936 |
abfd->flags |= DYNAMIC; |
abfd->flags |= DYNAMIC; |
2937 |
} |
} |
2938 |
|
|
2939 |
return true; |
return TRUE; |
2940 |
} |
} |