1 |
/* bfd back-end for HP PA-RISC SOM objects. |
/* bfd back-end for HP PA-RISC SOM objects. |
2 |
Copyright 1990, 1991, 1992, 1993, 1994, 1995, 1996, 1997, 1998, 1999, |
Copyright 1990, 1991, 1992, 1993, 1994, 1995, 1996, 1997, 1998, 1999, |
3 |
2000, 2001, 2002 |
2000, 2001, 2002, 2003, 2004, 2005 |
4 |
Free Software Foundation, Inc. |
Free Software Foundation, Inc. |
5 |
|
|
6 |
Contributed by the Center for Software Science at the |
Contributed by the Center for Software Science at the |
38 |
#include <machine/reg.h> |
#include <machine/reg.h> |
39 |
#include <sys/file.h> |
#include <sys/file.h> |
40 |
|
|
41 |
/* Magic not defined in standard HP-UX header files until 8.0 */ |
/* Magic not defined in standard HP-UX header files until 8.0. */ |
42 |
|
|
43 |
#ifndef CPU_PA_RISC1_0 |
#ifndef CPU_PA_RISC1_0 |
44 |
#define CPU_PA_RISC1_0 0x20B |
#define CPU_PA_RISC1_0 0x20B |
146 |
unsigned int symbol_value; |
unsigned int symbol_value; |
147 |
unsigned int priv_level; |
unsigned int priv_level; |
148 |
unsigned int secondary_def; |
unsigned int secondary_def; |
149 |
|
unsigned int is_comdat; |
150 |
|
unsigned int is_common; |
151 |
|
unsigned int dup_common; |
152 |
}; |
}; |
153 |
|
|
154 |
/* Forward declarations */ |
/* Forward declarations. */ |
155 |
|
|
156 |
static boolean som_mkobject PARAMS ((bfd *)); |
static bfd_boolean som_mkobject |
157 |
static const bfd_target * som_object_setup PARAMS ((bfd *, |
PARAMS ((bfd *)); |
158 |
struct header *, |
static const bfd_target * som_object_setup |
159 |
struct som_exec_auxhdr *, |
PARAMS ((bfd *, struct header *, struct som_exec_auxhdr *, unsigned long)); |
160 |
unsigned long)); |
static bfd_boolean setup_sections |
161 |
static boolean setup_sections PARAMS ((bfd *, struct header *, unsigned long)); |
PARAMS ((bfd *, struct header *, unsigned long)); |
162 |
static const bfd_target * som_object_p PARAMS ((bfd *)); |
static const bfd_target * som_object_p |
163 |
static boolean som_write_object_contents PARAMS ((bfd *)); |
PARAMS ((bfd *)); |
164 |
static boolean som_slurp_string_table PARAMS ((bfd *)); |
static bfd_boolean som_write_object_contents |
165 |
static unsigned int som_slurp_symbol_table PARAMS ((bfd *)); |
PARAMS ((bfd *)); |
166 |
static long som_get_symtab_upper_bound PARAMS ((bfd *)); |
static bfd_boolean som_slurp_string_table |
167 |
static long som_canonicalize_reloc PARAMS ((bfd *, sec_ptr, |
PARAMS ((bfd *)); |
168 |
arelent **, asymbol **)); |
static unsigned int som_slurp_symbol_table |
169 |
static long som_get_reloc_upper_bound PARAMS ((bfd *, sec_ptr)); |
PARAMS ((bfd *)); |
170 |
static unsigned int som_set_reloc_info PARAMS ((unsigned char *, unsigned int, |
static long som_get_symtab_upper_bound |
171 |
arelent *, asection *, |
PARAMS ((bfd *)); |
172 |
asymbol **, boolean)); |
static long som_canonicalize_reloc |
173 |
static boolean som_slurp_reloc_table PARAMS ((bfd *, asection *, |
PARAMS ((bfd *, sec_ptr, arelent **, asymbol **)); |
174 |
asymbol **, boolean)); |
static long som_get_reloc_upper_bound |
175 |
static long som_get_symtab PARAMS ((bfd *, asymbol **)); |
PARAMS ((bfd *, sec_ptr)); |
176 |
static asymbol * som_make_empty_symbol PARAMS ((bfd *)); |
static unsigned int som_set_reloc_info |
177 |
static void som_print_symbol PARAMS ((bfd *, PTR, |
PARAMS ((unsigned char *, unsigned int, arelent *, asection *, |
178 |
asymbol *, bfd_print_symbol_type)); |
asymbol **, bfd_boolean)); |
179 |
static boolean som_new_section_hook PARAMS ((bfd *, asection *)); |
static bfd_boolean som_slurp_reloc_table |
180 |
static boolean som_bfd_copy_private_symbol_data PARAMS ((bfd *, asymbol *, |
PARAMS ((bfd *, asection *, asymbol **, bfd_boolean)); |
181 |
bfd *, asymbol *)); |
static long som_canonicalize_symtab |
182 |
static boolean som_bfd_copy_private_section_data PARAMS ((bfd *, asection *, |
PARAMS ((bfd *, asymbol **)); |
183 |
bfd *, asection *)); |
static asymbol * som_make_empty_symbol |
184 |
static boolean som_bfd_copy_private_bfd_data PARAMS ((bfd *, bfd *)); |
PARAMS ((bfd *)); |
185 |
|
static void som_print_symbol |
186 |
|
PARAMS ((bfd *, PTR, asymbol *, bfd_print_symbol_type)); |
187 |
|
static bfd_boolean som_new_section_hook |
188 |
|
PARAMS ((bfd *, asection *)); |
189 |
|
static bfd_boolean som_bfd_copy_private_symbol_data |
190 |
|
PARAMS ((bfd *, asymbol *, bfd *, asymbol *)); |
191 |
|
static bfd_boolean som_bfd_copy_private_section_data |
192 |
|
PARAMS ((bfd *, asection *, bfd *, asection *)); |
193 |
|
static bfd_boolean som_bfd_copy_private_bfd_data |
194 |
|
PARAMS ((bfd *, bfd *)); |
195 |
|
#define som_bfd_copy_private_header_data \ |
196 |
|
_bfd_generic_bfd_copy_private_header_data |
197 |
#define som_bfd_merge_private_bfd_data _bfd_generic_bfd_merge_private_bfd_data |
#define som_bfd_merge_private_bfd_data _bfd_generic_bfd_merge_private_bfd_data |
198 |
#define som_bfd_set_private_flags _bfd_generic_bfd_set_private_flags |
#define som_bfd_set_private_flags _bfd_generic_bfd_set_private_flags |
199 |
static boolean som_bfd_is_local_label_name PARAMS ((bfd *, const char *)); |
static bfd_boolean som_bfd_print_private_bfd_data |
200 |
static boolean som_set_section_contents PARAMS ((bfd *, sec_ptr, PTR, |
(bfd *, void *); |
201 |
file_ptr, bfd_size_type)); |
static bfd_boolean som_bfd_is_local_label_name |
202 |
static boolean som_get_section_contents PARAMS ((bfd *, sec_ptr, PTR, |
PARAMS ((bfd *, const char *)); |
203 |
file_ptr, bfd_size_type)); |
static bfd_boolean som_set_section_contents |
204 |
static boolean som_set_arch_mach PARAMS ((bfd *, enum bfd_architecture, |
PARAMS ((bfd *, sec_ptr, const PTR, file_ptr, bfd_size_type)); |
205 |
unsigned long)); |
static bfd_boolean som_get_section_contents |
206 |
static boolean som_find_nearest_line PARAMS ((bfd *, asection *, |
PARAMS ((bfd *, sec_ptr, PTR, file_ptr, bfd_size_type)); |
207 |
asymbol **, bfd_vma, |
static bfd_boolean som_set_arch_mach |
208 |
const char **, |
PARAMS ((bfd *, enum bfd_architecture, unsigned long)); |
209 |
const char **, |
static bfd_boolean som_find_nearest_line |
210 |
unsigned int *)); |
PARAMS ((bfd *, asection *, asymbol **, bfd_vma, const char **, |
211 |
static void som_get_symbol_info PARAMS ((bfd *, asymbol *, symbol_info *)); |
const char **, unsigned int *)); |
212 |
static asection * bfd_section_from_som_symbol PARAMS ((bfd *, |
static void som_get_symbol_info |
213 |
struct symbol_dictionary_record *)); |
PARAMS ((bfd *, asymbol *, symbol_info *)); |
214 |
static int log2 PARAMS ((unsigned int)); |
static asection * bfd_section_from_som_symbol |
215 |
static bfd_reloc_status_type hppa_som_reloc PARAMS ((bfd *, arelent *, |
PARAMS ((bfd *, struct symbol_dictionary_record *)); |
216 |
asymbol *, PTR, |
static int exact_log2 |
217 |
asection *, bfd *, |
PARAMS ((unsigned int)); |
218 |
char **)); |
static bfd_reloc_status_type hppa_som_reloc |
219 |
static void som_initialize_reloc_queue PARAMS ((struct reloc_queue *)); |
PARAMS ((bfd *, arelent *, asymbol *, PTR, asection *, bfd *, char **)); |
220 |
static void som_reloc_queue_insert PARAMS ((unsigned char *, unsigned int, |
static void som_initialize_reloc_queue |
221 |
struct reloc_queue *)); |
PARAMS ((struct reloc_queue *)); |
222 |
static void som_reloc_queue_fix PARAMS ((struct reloc_queue *, unsigned int)); |
static void som_reloc_queue_insert |
223 |
static int som_reloc_queue_find PARAMS ((unsigned char *, unsigned int, |
PARAMS ((unsigned char *, unsigned int, struct reloc_queue *)); |
224 |
struct reloc_queue *)); |
static void som_reloc_queue_fix |
225 |
static unsigned char * try_prev_fixup PARAMS ((bfd *, int *, unsigned char *, |
PARAMS ((struct reloc_queue *, unsigned int)); |
226 |
unsigned int, |
static int som_reloc_queue_find |
227 |
struct reloc_queue *)); |
PARAMS ((unsigned char *, unsigned int, struct reloc_queue *)); |
228 |
|
static unsigned char * try_prev_fixup |
229 |
static unsigned char * som_reloc_skip PARAMS ((bfd *, unsigned int, |
PARAMS ((bfd *, int *, unsigned char *, unsigned int, struct reloc_queue *)); |
230 |
unsigned char *, unsigned int *, |
static unsigned char * som_reloc_skip |
231 |
struct reloc_queue *)); |
PARAMS ((bfd *, unsigned int, unsigned char *, unsigned int *, |
232 |
static unsigned char * som_reloc_addend PARAMS ((bfd *, bfd_vma, |
struct reloc_queue *)); |
233 |
unsigned char *, |
static unsigned char * som_reloc_addend |
234 |
unsigned int *, |
PARAMS ((bfd *, bfd_vma, unsigned char *, unsigned int *, |
235 |
struct reloc_queue *)); |
struct reloc_queue *)); |
236 |
static unsigned char * som_reloc_call PARAMS ((bfd *, unsigned char *, |
static unsigned char * som_reloc_call |
237 |
unsigned int *, |
PARAMS ((bfd *, unsigned char *, unsigned int *, arelent *, int, |
238 |
arelent *, int, |
struct reloc_queue *)); |
239 |
struct reloc_queue *)); |
static unsigned long som_count_spaces |
240 |
static unsigned long som_count_spaces PARAMS ((bfd *)); |
PARAMS ((bfd *)); |
241 |
static unsigned long som_count_subspaces PARAMS ((bfd *)); |
static unsigned long som_count_subspaces |
242 |
static int compare_syms PARAMS ((const void *, const void *)); |
PARAMS ((bfd *)); |
243 |
static int compare_subspaces PARAMS ((const void *, const void *)); |
static int compare_syms |
244 |
static unsigned long som_compute_checksum PARAMS ((bfd *)); |
PARAMS ((const void *, const void *)); |
245 |
static boolean som_prep_headers PARAMS ((bfd *)); |
static int compare_subspaces |
246 |
static int som_sizeof_headers PARAMS ((bfd *, boolean)); |
PARAMS ((const void *, const void *)); |
247 |
static boolean som_finish_writing PARAMS ((bfd *)); |
static unsigned long som_compute_checksum |
248 |
static boolean som_build_and_write_symbol_table PARAMS ((bfd *)); |
PARAMS ((bfd *)); |
249 |
static void som_prep_for_fixups PARAMS ((bfd *, asymbol **, unsigned long)); |
static bfd_boolean som_prep_headers |
250 |
static boolean som_write_fixups PARAMS ((bfd *, unsigned long, unsigned int *)); |
PARAMS ((bfd *)); |
251 |
static boolean som_write_space_strings PARAMS ((bfd *, unsigned long, |
static int som_sizeof_headers |
252 |
unsigned int *)); |
PARAMS ((bfd *, bfd_boolean)); |
253 |
static boolean som_write_symbol_strings PARAMS ((bfd *, unsigned long, |
static bfd_boolean som_finish_writing |
254 |
asymbol **, unsigned int, |
PARAMS ((bfd *)); |
255 |
unsigned *, |
static bfd_boolean som_build_and_write_symbol_table |
256 |
COMPUNIT *)); |
PARAMS ((bfd *)); |
257 |
static boolean som_begin_writing PARAMS ((bfd *)); |
static void som_prep_for_fixups |
258 |
|
PARAMS ((bfd *, asymbol **, unsigned long)); |
259 |
|
static bfd_boolean som_write_fixups |
260 |
|
PARAMS ((bfd *, unsigned long, unsigned int *)); |
261 |
|
static bfd_boolean som_write_space_strings |
262 |
|
PARAMS ((bfd *, unsigned long, unsigned int *)); |
263 |
|
static bfd_boolean som_write_symbol_strings |
264 |
|
PARAMS ((bfd *, unsigned long, asymbol **, unsigned int, unsigned *, |
265 |
|
COMPUNIT *)); |
266 |
|
static bfd_boolean som_begin_writing |
267 |
|
PARAMS ((bfd *)); |
268 |
static reloc_howto_type * som_bfd_reloc_type_lookup |
static reloc_howto_type * som_bfd_reloc_type_lookup |
269 |
PARAMS ((bfd *, bfd_reloc_code_real_type)); |
PARAMS ((bfd *, bfd_reloc_code_real_type)); |
270 |
static char som_section_type PARAMS ((const char *)); |
static char som_section_type |
271 |
static int som_decode_symclass PARAMS ((asymbol *)); |
PARAMS ((const char *)); |
272 |
static boolean som_bfd_count_ar_symbols PARAMS ((bfd *, struct lst_header *, |
static int som_decode_symclass |
273 |
symindex *)); |
PARAMS ((asymbol *)); |
274 |
|
static bfd_boolean som_bfd_count_ar_symbols |
275 |
static boolean som_bfd_fill_in_ar_symbols PARAMS ((bfd *, struct lst_header *, |
PARAMS ((bfd *, struct lst_header *, symindex *)); |
276 |
carsym **syms)); |
static bfd_boolean som_bfd_fill_in_ar_symbols |
277 |
static boolean som_slurp_armap PARAMS ((bfd *)); |
PARAMS ((bfd *, struct lst_header *, carsym **)); |
278 |
static boolean som_write_armap PARAMS ((bfd *, unsigned int, struct orl *, |
static bfd_boolean som_slurp_armap |
279 |
unsigned int, int)); |
PARAMS ((bfd *)); |
280 |
static void som_bfd_derive_misc_symbol_info PARAMS ((bfd *, asymbol *, |
static bfd_boolean som_write_armap |
281 |
struct som_misc_symbol_info *)); |
PARAMS ((bfd *, unsigned int, struct orl *, unsigned int, int)); |
282 |
static boolean som_bfd_prep_for_ar_write PARAMS ((bfd *, unsigned int *, |
static void som_bfd_derive_misc_symbol_info |
283 |
unsigned int *)); |
PARAMS ((bfd *, asymbol *, struct som_misc_symbol_info *)); |
284 |
static unsigned int som_bfd_ar_symbol_hash PARAMS ((asymbol *)); |
static bfd_boolean som_bfd_prep_for_ar_write |
285 |
static boolean som_bfd_ar_write_symbol_stuff PARAMS ((bfd *, unsigned int, |
PARAMS ((bfd *, unsigned int *, unsigned int *)); |
286 |
unsigned int, |
static unsigned int som_bfd_ar_symbol_hash |
287 |
struct lst_header, |
PARAMS ((asymbol *)); |
288 |
unsigned int)); |
static bfd_boolean som_bfd_ar_write_symbol_stuff |
289 |
static boolean som_is_space PARAMS ((asection *)); |
PARAMS ((bfd *, unsigned int, unsigned int, struct lst_header, |
290 |
static boolean som_is_subspace PARAMS ((asection *)); |
unsigned int)); |
291 |
static boolean som_is_container PARAMS ((asection *, asection *)); |
static bfd_boolean som_is_space |
292 |
static boolean som_bfd_free_cached_info PARAMS ((bfd *)); |
PARAMS ((asection *)); |
293 |
static boolean som_bfd_link_split_section PARAMS ((bfd *, asection *)); |
static bfd_boolean som_is_subspace |
294 |
|
PARAMS ((asection *)); |
295 |
|
static bfd_boolean som_is_container |
296 |
|
PARAMS ((asection *, asection *)); |
297 |
|
static bfd_boolean som_bfd_free_cached_info |
298 |
|
PARAMS ((bfd *)); |
299 |
|
static bfd_boolean som_bfd_link_split_section |
300 |
|
PARAMS ((bfd *, asection *)); |
301 |
|
|
302 |
/* Map SOM section names to POSIX/BSD single-character symbol types. |
/* Map SOM section names to POSIX/BSD single-character symbol types. |
303 |
|
|
664 |
/* R_TRANSLATED */ |
/* R_TRANSLATED */ |
665 |
{ 0, "" }, /* 0xce */ |
{ 0, "" }, /* 0xce */ |
666 |
/* R_AUX_UNWIND */ |
/* R_AUX_UNWIND */ |
667 |
{ 0,"Sd=Vf=Ef=" }, /* 0xcf */ |
{ 0,"Sd=Ve=Ee=" }, /* 0xcf */ |
668 |
/* R_COMP1 */ |
/* R_COMP1 */ |
669 |
{ 0, "Ob=" }, /* 0xd0 */ |
{ 0, "Ob=" }, /* 0xd0 */ |
670 |
/* R_COMP2 */ |
/* R_COMP2 */ |
689 |
/* R_LTP_OVERRIDE */ |
/* R_LTP_OVERRIDE */ |
690 |
{ 0, "" }, /* 0xdc */ |
{ 0, "" }, /* 0xdc */ |
691 |
/* R_COMMENT */ |
/* R_COMMENT */ |
692 |
{ 0, "Ob=Ve=" }, /* 0xdd */ |
{ 0, "Ob=Vf=" }, /* 0xdd */ |
693 |
/* R_RESERVED */ |
/* R_RESERVED */ |
694 |
{ 0, "" }, /* 0xde */ |
{ 0, "" }, /* 0xde */ |
695 |
{ 0, "" }, /* 0xdf */ |
{ 0, "" }, /* 0xdf */ |
810 |
#endif |
#endif |
811 |
|
|
812 |
#define SOM_HOWTO(TYPE, NAME) \ |
#define SOM_HOWTO(TYPE, NAME) \ |
813 |
HOWTO(TYPE, 0, 0, 32, false, 0, 0, hppa_som_reloc, NAME, false, 0, 0, false) |
HOWTO(TYPE, 0, 0, 32, FALSE, 0, 0, hppa_som_reloc, NAME, FALSE, 0, 0, FALSE) |
814 |
|
|
815 |
static reloc_howto_type som_hppa_howto_table[] = { |
static reloc_howto_type som_hppa_howto_table[] = { |
816 |
SOM_HOWTO (R_NO_RELOCATION, "R_NO_RELOCATION"), |
SOM_HOWTO (R_NO_RELOCATION, "R_NO_RELOCATION"), |
1435 |
return p; |
return p; |
1436 |
} |
} |
1437 |
|
|
1438 |
/* Return the logarithm of X, base 2, considering X unsigned. |
/* Return the logarithm of X, base 2, considering X unsigned, |
1439 |
Abort -1 if X is not a power or two or is zero. */ |
if X is a power of 2. Otherwise, returns -1. */ |
1440 |
|
|
1441 |
static int |
static int |
1442 |
log2 (x) |
exact_log2 (x) |
1443 |
unsigned int x; |
unsigned int x; |
1444 |
{ |
{ |
1445 |
int log = 0; |
int log = 0; |
1596 |
final_types[3] = NULL; |
final_types[3] = NULL; |
1597 |
*final_type = base_type; |
*final_type = base_type; |
1598 |
break; |
break; |
1599 |
|
|
1600 |
|
/* FIXME: These two field selectors are not currently supported. */ |
1601 |
|
case e_ltpsel: |
1602 |
|
case e_rtpsel: |
1603 |
|
abort (); |
1604 |
} |
} |
1605 |
|
|
1606 |
switch (base_type) |
switch (base_type) |
1727 |
#ifndef NO_PCREL_MODES |
#ifndef NO_PCREL_MODES |
1728 |
/* If we have short and long pcrel modes, then generate the proper |
/* If we have short and long pcrel modes, then generate the proper |
1729 |
mode selector, then the pcrel relocation. Redundant selectors |
mode selector, then the pcrel relocation. Redundant selectors |
1730 |
will be eliminted as the relocs are sized and emitted. */ |
will be eliminated as the relocs are sized and emitted. */ |
1731 |
bfd_size_type amt = sizeof (int); |
bfd_size_type amt = sizeof (int); |
1732 |
final_types[0] = (int *) bfd_alloc (abfd, amt); |
final_types[0] = (int *) bfd_alloc (abfd, amt); |
1733 |
if (!final_types[0]) |
if (!final_types[0]) |
1774 |
unsigned long current_offset; |
unsigned long current_offset; |
1775 |
{ |
{ |
1776 |
asection *section; |
asection *section; |
|
int found; |
|
1777 |
|
|
1778 |
/* som_mkobject will set bfd_error if som_mkobject fails. */ |
/* som_mkobject will set bfd_error if som_mkobject fails. */ |
1779 |
if (! som_mkobject (abfd)) |
if (! som_mkobject (abfd)) |
1811 |
break; |
break; |
1812 |
} |
} |
1813 |
|
|
1814 |
|
/* Save the auxiliary header. */ |
1815 |
|
obj_som_exec_hdr (abfd) = aux_hdrp; |
1816 |
|
|
1817 |
/* Allocate space to hold the saved exec header information. */ |
/* Allocate space to hold the saved exec header information. */ |
1818 |
obj_som_exec_data (abfd) = (struct som_exec_data *) |
obj_som_exec_data (abfd) = (struct som_exec_data *) |
1819 |
bfd_zalloc (abfd, (bfd_size_type) sizeof (struct som_exec_data)); |
bfd_zalloc (abfd, (bfd_size_type) sizeof (struct som_exec_data)); |
1828 |
It's about time, OSF has used the new id since at least 1992; |
It's about time, OSF has used the new id since at least 1992; |
1829 |
HPUX didn't start till nearly 1995!. |
HPUX didn't start till nearly 1995!. |
1830 |
|
|
1831 |
The new approach examines the entry field. If it's zero or not 4 |
The new approach examines the entry field for an executable. If |
1832 |
byte aligned then it's not a proper code address and we guess it's |
it is not 4-byte aligned then it's not a proper code address and |
1833 |
really the executable flags. */ |
we guess it's really the executable flags. For a main program, |
1834 |
found = 0; |
we also consider zero to be indicative of a buggy linker, since |
1835 |
for (section = abfd->sections; section; section = section->next) |
that is not a valid entry point. The entry point for a shared |
1836 |
{ |
library, however, can be zero so we do not consider that to be |
1837 |
if ((section->flags & SEC_CODE) == 0) |
indicative of a buggy linker. */ |
1838 |
continue; |
if (aux_hdrp) |
|
if (aux_hdrp->exec_entry >= section->vma |
|
|
&& aux_hdrp->exec_entry < section->vma + section->_cooked_size) |
|
|
found = 1; |
|
|
} |
|
|
if (aux_hdrp->exec_entry == 0 |
|
|
|| (aux_hdrp->exec_entry & 0x3) != 0 |
|
|
|| ! found) |
|
|
{ |
|
|
bfd_get_start_address (abfd) = aux_hdrp->exec_flags; |
|
|
obj_som_exec_data (abfd)->exec_flags = aux_hdrp->exec_entry; |
|
|
} |
|
|
else |
|
1839 |
{ |
{ |
1840 |
bfd_get_start_address (abfd) = aux_hdrp->exec_entry + current_offset; |
int found = 0; |
1841 |
obj_som_exec_data (abfd)->exec_flags = aux_hdrp->exec_flags; |
|
1842 |
|
for (section = abfd->sections; section; section = section->next) |
1843 |
|
{ |
1844 |
|
bfd_vma entry; |
1845 |
|
|
1846 |
|
if ((section->flags & SEC_CODE) == 0) |
1847 |
|
continue; |
1848 |
|
entry = aux_hdrp->exec_entry + aux_hdrp->exec_tmem; |
1849 |
|
if (entry >= section->vma |
1850 |
|
&& entry < section->vma + section->size) |
1851 |
|
found = 1; |
1852 |
|
} |
1853 |
|
if ((aux_hdrp->exec_entry == 0 && !(abfd->flags & DYNAMIC)) |
1854 |
|
|| (aux_hdrp->exec_entry & 0x3) != 0 |
1855 |
|
|| ! found) |
1856 |
|
{ |
1857 |
|
bfd_get_start_address (abfd) = aux_hdrp->exec_flags; |
1858 |
|
obj_som_exec_data (abfd)->exec_flags = aux_hdrp->exec_entry; |
1859 |
|
} |
1860 |
|
else |
1861 |
|
{ |
1862 |
|
bfd_get_start_address (abfd) = aux_hdrp->exec_entry + current_offset; |
1863 |
|
obj_som_exec_data (abfd)->exec_flags = aux_hdrp->exec_flags; |
1864 |
|
} |
1865 |
} |
} |
1866 |
|
|
1867 |
obj_som_exec_data (abfd)->version_id = file_hdrp->version_id; |
obj_som_exec_data (abfd)->version_id = file_hdrp->version_id; |
1892 |
BFD sections which correspond to spaces will overlap the sections for the |
BFD sections which correspond to spaces will overlap the sections for the |
1893 |
associated subspaces. */ |
associated subspaces. */ |
1894 |
|
|
1895 |
static boolean |
static bfd_boolean |
1896 |
setup_sections (abfd, file_hdr, current_offset) |
setup_sections (abfd, file_hdr, current_offset) |
1897 |
bfd *abfd; |
bfd *abfd; |
1898 |
struct header *file_hdr; |
struct header *file_hdr; |
1922 |
for (space_index = 0; space_index < file_hdr->space_total; space_index++) |
for (space_index = 0; space_index < file_hdr->space_total; space_index++) |
1923 |
{ |
{ |
1924 |
struct space_dictionary_record space; |
struct space_dictionary_record space; |
1925 |
struct subspace_dictionary_record subspace, save_subspace; |
struct som_subspace_dictionary_record subspace, save_subspace; |
1926 |
int subspace_index; |
unsigned int subspace_index; |
1927 |
asection *space_asect; |
asection *space_asect; |
1928 |
|
bfd_size_type space_size = 0; |
1929 |
char *newname; |
char *newname; |
1930 |
|
|
1931 |
/* Read the space dictionary element. */ |
/* Read the space dictionary element. */ |
1982 |
goto error_return; |
goto error_return; |
1983 |
|
|
1984 |
/* Setup the start address and file loc from the first subspace |
/* Setup the start address and file loc from the first subspace |
1985 |
record. */ |
record. */ |
1986 |
space_asect->vma = subspace.subspace_start; |
space_asect->vma = subspace.subspace_start; |
1987 |
space_asect->filepos = subspace.file_loc_init_value + current_offset; |
space_asect->filepos = subspace.file_loc_init_value + current_offset; |
1988 |
space_asect->alignment_power = log2 (subspace.alignment); |
space_asect->alignment_power = exact_log2 (subspace.alignment); |
1989 |
if (space_asect->alignment_power == (unsigned) -1) |
if (space_asect->alignment_power == (unsigned) -1) |
1990 |
goto error_return; |
goto error_return; |
1991 |
|
|
1992 |
/* Initialize save_subspace so we can reliably determine if this |
/* Initialize save_subspace so we can reliably determine if this |
1993 |
loop placed any useful values into it. */ |
loop placed any useful values into it. */ |
1994 |
memset (&save_subspace, 0, sizeof (struct subspace_dictionary_record)); |
memset (&save_subspace, 0, sizeof (save_subspace)); |
1995 |
|
|
1996 |
/* Loop over the rest of the subspaces, building up more sections. */ |
/* Loop over the rest of the subspaces, building up more sections. */ |
1997 |
for (subspace_index = 0; subspace_index < space.subspace_quantity; |
for (subspace_index = 0; subspace_index < space.subspace_quantity; |
2022 |
if (! bfd_som_set_subsection_attributes (subspace_asect, space_asect, |
if (! bfd_som_set_subsection_attributes (subspace_asect, space_asect, |
2023 |
subspace.access_control_bits, |
subspace.access_control_bits, |
2024 |
subspace.sort_key, |
subspace.sort_key, |
2025 |
subspace.quadrant)) |
subspace.quadrant, |
2026 |
|
subspace.is_comdat, |
2027 |
|
subspace.is_common, |
2028 |
|
subspace.dup_common)) |
2029 |
goto error_return; |
goto error_return; |
2030 |
|
|
2031 |
/* Keep an easy mapping between subspaces and sections. |
/* Keep an easy mapping between subspaces and sections. |
2071 |
break; |
break; |
2072 |
} |
} |
2073 |
|
|
2074 |
if (subspace.dup_common || subspace.is_common) |
if (subspace.is_comdat || subspace.is_common || subspace.dup_common) |
2075 |
subspace_asect->flags |= SEC_IS_COMMON; |
subspace_asect->flags |= SEC_LINK_ONCE; |
2076 |
else if (subspace.subspace_length > 0) |
|
2077 |
|
if (subspace.subspace_length > 0) |
2078 |
subspace_asect->flags |= SEC_HAS_CONTENTS; |
subspace_asect->flags |= SEC_HAS_CONTENTS; |
2079 |
|
|
2080 |
if (subspace.is_loadable) |
if (subspace.is_loadable) |
2111 |
save_subspace = subspace; |
save_subspace = subspace; |
2112 |
|
|
2113 |
subspace_asect->vma = subspace.subspace_start; |
subspace_asect->vma = subspace.subspace_start; |
2114 |
subspace_asect->_cooked_size = subspace.subspace_length; |
subspace_asect->size = subspace.subspace_length; |
|
subspace_asect->_raw_size = subspace.subspace_length; |
|
2115 |
subspace_asect->filepos = (subspace.file_loc_init_value |
subspace_asect->filepos = (subspace.file_loc_init_value |
2116 |
+ current_offset); |
+ current_offset); |
2117 |
subspace_asect->alignment_power = log2 (subspace.alignment); |
subspace_asect->alignment_power = exact_log2 (subspace.alignment); |
2118 |
if (subspace_asect->alignment_power == (unsigned) -1) |
if (subspace_asect->alignment_power == (unsigned) -1) |
2119 |
goto error_return; |
goto error_return; |
2120 |
|
|
2121 |
|
/* Keep track of the accumulated sizes of the sections. */ |
2122 |
|
space_size += subspace.subspace_length; |
2123 |
} |
} |
2124 |
|
|
2125 |
/* This can happen for a .o which defines symbols in otherwise |
/* This can happen for a .o which defines symbols in otherwise |
2126 |
empty subspaces. */ |
empty subspaces. */ |
2127 |
if (!save_subspace.file_loc_init_value) |
if (!save_subspace.file_loc_init_value) |
2128 |
{ |
space_asect->size = 0; |
|
space_asect->_cooked_size = 0; |
|
|
space_asect->_raw_size = 0; |
|
|
} |
|
2129 |
else |
else |
2130 |
{ |
{ |
2131 |
/* Setup the sizes for the space section based upon the info in the |
if (file_hdr->a_magic != RELOC_MAGIC) |
2132 |
last subspace of the space. */ |
{ |
2133 |
space_asect->_cooked_size = (save_subspace.subspace_start |
/* Setup the size for the space section based upon the info |
2134 |
- space_asect->vma |
in the last subspace of the space. */ |
2135 |
+ save_subspace.subspace_length); |
space_asect->size = (save_subspace.subspace_start |
2136 |
space_asect->_raw_size = (save_subspace.file_loc_init_value |
- space_asect->vma |
2137 |
- space_asect->filepos |
+ save_subspace.subspace_length); |
2138 |
+ save_subspace.initialization_length); |
} |
2139 |
|
else |
2140 |
|
{ |
2141 |
|
/* The subspace_start field is not initialised in relocatable |
2142 |
|
only objects, so it cannot be used for length calculations. |
2143 |
|
Instead we use the space_size value which we have been |
2144 |
|
accumulating. This isn't an accurate estimate since it |
2145 |
|
ignores alignment and ordering issues. */ |
2146 |
|
space_asect->size = space_size; |
2147 |
|
} |
2148 |
} |
} |
2149 |
} |
} |
2150 |
/* Now that we've read in all the subspace records, we need to assign |
/* Now that we've read in all the subspace records, we need to assign |
2177 |
if (subspace_sections != NULL) |
if (subspace_sections != NULL) |
2178 |
free (subspace_sections); |
free (subspace_sections); |
2179 |
|
|
2180 |
return true; |
return TRUE; |
2181 |
|
|
2182 |
error_return: |
error_return: |
2183 |
if (space_strings != NULL) |
if (space_strings != NULL) |
2185 |
|
|
2186 |
if (subspace_sections != NULL) |
if (subspace_sections != NULL) |
2187 |
free (subspace_sections); |
free (subspace_sections); |
2188 |
return false; |
return FALSE; |
2189 |
} |
} |
2190 |
|
|
2191 |
/* Read in a SOM object and make it into a BFD. */ |
/* Read in a SOM object and make it into a BFD. */ |
2195 |
bfd *abfd; |
bfd *abfd; |
2196 |
{ |
{ |
2197 |
struct header file_hdr; |
struct header file_hdr; |
2198 |
struct som_exec_auxhdr aux_hdr; |
struct som_exec_auxhdr *aux_hdr_ptr = NULL; |
2199 |
unsigned long current_offset = 0; |
unsigned long current_offset = 0; |
2200 |
struct lst_header lst_header; |
struct lst_header lst_header; |
2201 |
struct som_entry som_entry; |
struct som_entry som_entry; |
2307 |
/* If the aux_header_size field in the file header is zero, then this |
/* If the aux_header_size field in the file header is zero, then this |
2308 |
object is an incomplete executable (a .o file). Do not try to read |
object is an incomplete executable (a .o file). Do not try to read |
2309 |
a non-existant auxiliary header. */ |
a non-existant auxiliary header. */ |
|
memset (&aux_hdr, 0, sizeof (struct som_exec_auxhdr)); |
|
2310 |
if (file_hdr.aux_header_size != 0) |
if (file_hdr.aux_header_size != 0) |
2311 |
{ |
{ |
2312 |
|
aux_hdr_ptr = bfd_zalloc (abfd, |
2313 |
|
(bfd_size_type) sizeof (*aux_hdr_ptr)); |
2314 |
|
if (aux_hdr_ptr == NULL) |
2315 |
|
return NULL; |
2316 |
amt = AUX_HDR_SIZE; |
amt = AUX_HDR_SIZE; |
2317 |
if (bfd_bread ((PTR) &aux_hdr, amt, abfd) != amt) |
if (bfd_bread ((PTR) aux_hdr_ptr, amt, abfd) != amt) |
2318 |
{ |
{ |
2319 |
if (bfd_get_error () != bfd_error_system_call) |
if (bfd_get_error () != bfd_error_system_call) |
2320 |
bfd_set_error (bfd_error_wrong_format); |
bfd_set_error (bfd_error_wrong_format); |
2330 |
} |
} |
2331 |
|
|
2332 |
/* This appears to be a valid SOM object. Do some initialization. */ |
/* This appears to be a valid SOM object. Do some initialization. */ |
2333 |
return som_object_setup (abfd, &file_hdr, &aux_hdr, current_offset); |
return som_object_setup (abfd, &file_hdr, aux_hdr_ptr, current_offset); |
2334 |
} |
} |
2335 |
|
|
2336 |
/* Create a SOM object. */ |
/* Create a SOM object. */ |
2337 |
|
|
2338 |
static boolean |
static bfd_boolean |
2339 |
som_mkobject (abfd) |
som_mkobject (abfd) |
2340 |
bfd *abfd; |
bfd *abfd; |
2341 |
{ |
{ |
2343 |
abfd->tdata.som_data = (struct som_data_struct *) |
abfd->tdata.som_data = (struct som_data_struct *) |
2344 |
bfd_zalloc (abfd, (bfd_size_type) sizeof (struct som_data_struct)); |
bfd_zalloc (abfd, (bfd_size_type) sizeof (struct som_data_struct)); |
2345 |
if (abfd->tdata.som_data == NULL) |
if (abfd->tdata.som_data == NULL) |
2346 |
return false; |
return FALSE; |
2347 |
return true; |
return TRUE; |
2348 |
} |
} |
2349 |
|
|
2350 |
/* Initialize some information in the file header. This routine makes |
/* Initialize some information in the file header. This routine makes |
2351 |
not attempt at doing the right thing for a full executable; it |
not attempt at doing the right thing for a full executable; it |
2352 |
is only meant to handle relocatable objects. */ |
is only meant to handle relocatable objects. */ |
2353 |
|
|
2354 |
static boolean |
static bfd_boolean |
2355 |
som_prep_headers (abfd) |
som_prep_headers (abfd) |
2356 |
bfd *abfd; |
bfd *abfd; |
2357 |
{ |
{ |
2362 |
/* Make and attach a file header to the BFD. */ |
/* Make and attach a file header to the BFD. */ |
2363 |
file_hdr = (struct header *) bfd_zalloc (abfd, amt); |
file_hdr = (struct header *) bfd_zalloc (abfd, amt); |
2364 |
if (file_hdr == NULL) |
if (file_hdr == NULL) |
2365 |
return false; |
return FALSE; |
2366 |
obj_som_file_hdr (abfd) = file_hdr; |
obj_som_file_hdr (abfd) = file_hdr; |
2367 |
|
|
2368 |
if (abfd->flags & (EXEC_P | DYNAMIC)) |
if (abfd->flags & (EXEC_P | DYNAMIC)) |
2369 |
{ |
{ |
|
|
|
2370 |
/* Make and attach an exec header to the BFD. */ |
/* Make and attach an exec header to the BFD. */ |
2371 |
amt = sizeof (struct som_exec_auxhdr); |
amt = sizeof (struct som_exec_auxhdr); |
2372 |
obj_som_exec_hdr (abfd) = |
obj_som_exec_hdr (abfd) = |
2373 |
(struct som_exec_auxhdr *) bfd_zalloc (abfd, amt); |
(struct som_exec_auxhdr *) bfd_zalloc (abfd, amt); |
2374 |
if (obj_som_exec_hdr (abfd) == NULL) |
if (obj_som_exec_hdr (abfd) == NULL) |
2375 |
return false; |
return FALSE; |
2376 |
|
|
2377 |
if (abfd->flags & D_PAGED) |
if (abfd->flags & D_PAGED) |
2378 |
file_hdr->a_magic = DEMAND_MAGIC; |
file_hdr->a_magic = DEMAND_MAGIC; |
2416 |
som_section_data (section)->space_dict = |
som_section_data (section)->space_dict = |
2417 |
(struct space_dictionary_record *) bfd_zalloc (abfd, amt); |
(struct space_dictionary_record *) bfd_zalloc (abfd, amt); |
2418 |
if (som_section_data (section)->space_dict == NULL) |
if (som_section_data (section)->space_dict == NULL) |
2419 |
return false; |
return FALSE; |
2420 |
/* Set space attributes. Note most attributes of SOM spaces |
/* Set space attributes. Note most attributes of SOM spaces |
2421 |
are set based on the subspaces it contains. */ |
are set based on the subspaces it contains. */ |
2422 |
som_section_data (section)->space_dict->loader_fix_index = -1; |
som_section_data (section)->space_dict->loader_fix_index = -1; |
2435 |
else |
else |
2436 |
{ |
{ |
2437 |
/* Allocate space for the subspace dictionary. */ |
/* Allocate space for the subspace dictionary. */ |
2438 |
amt = sizeof (struct subspace_dictionary_record); |
amt = sizeof (struct som_subspace_dictionary_record); |
2439 |
som_section_data (section)->subspace_dict = |
som_section_data (section)->subspace_dict = |
2440 |
(struct subspace_dictionary_record *) bfd_zalloc (abfd, amt); |
(struct som_subspace_dictionary_record *) bfd_zalloc (abfd, amt); |
2441 |
if (som_section_data (section)->subspace_dict == NULL) |
if (som_section_data (section)->subspace_dict == NULL) |
2442 |
return false; |
return FALSE; |
2443 |
|
|
2444 |
/* Set subspace attributes. Basic stuff is done here, additional |
/* Set subspace attributes. Basic stuff is done here, additional |
2445 |
attributes are filled in later as more information becomes |
attributes are filled in later as more information becomes |
2446 |
available. */ |
available. */ |
|
if (section->flags & SEC_IS_COMMON) |
|
|
{ |
|
|
som_section_data (section)->subspace_dict->dup_common = 1; |
|
|
som_section_data (section)->subspace_dict->is_common = 1; |
|
|
} |
|
|
|
|
2447 |
if (section->flags & SEC_ALLOC) |
if (section->flags & SEC_ALLOC) |
2448 |
som_section_data (section)->subspace_dict->is_loadable = 1; |
som_section_data (section)->subspace_dict->is_loadable = 1; |
2449 |
|
|
2453 |
som_section_data (section)->subspace_dict->subspace_start = |
som_section_data (section)->subspace_dict->subspace_start = |
2454 |
section->vma; |
section->vma; |
2455 |
som_section_data (section)->subspace_dict->subspace_length = |
som_section_data (section)->subspace_dict->subspace_length = |
2456 |
bfd_section_size (abfd, section); |
section->size; |
2457 |
som_section_data (section)->subspace_dict->initialization_length = |
som_section_data (section)->subspace_dict->initialization_length = |
2458 |
bfd_section_size (abfd, section); |
section->size; |
2459 |
som_section_data (section)->subspace_dict->alignment = |
som_section_data (section)->subspace_dict->alignment = |
2460 |
1 << section->alignment_power; |
1 << section->alignment_power; |
2461 |
|
|
2466 |
som_section_data (section)->copy_data->access_control_bits; |
som_section_data (section)->copy_data->access_control_bits; |
2467 |
som_section_data (section)->subspace_dict->quadrant = |
som_section_data (section)->subspace_dict->quadrant = |
2468 |
som_section_data (section)->copy_data->quadrant; |
som_section_data (section)->copy_data->quadrant; |
2469 |
|
som_section_data (section)->subspace_dict->is_comdat = |
2470 |
|
som_section_data (section)->copy_data->is_comdat; |
2471 |
|
som_section_data (section)->subspace_dict->is_common = |
2472 |
|
som_section_data (section)->copy_data->is_common; |
2473 |
|
som_section_data (section)->subspace_dict->dup_common = |
2474 |
|
som_section_data (section)->copy_data->dup_common; |
2475 |
} |
} |
2476 |
} |
} |
2477 |
return true; |
return TRUE; |
2478 |
} |
} |
2479 |
|
|
2480 |
/* Return true if the given section is a SOM space, false otherwise. */ |
/* Return TRUE if the given section is a SOM space, FALSE otherwise. */ |
2481 |
|
|
2482 |
static boolean |
static bfd_boolean |
2483 |
som_is_space (section) |
som_is_space (section) |
2484 |
asection *section; |
asection *section; |
2485 |
{ |
{ |
2486 |
/* If no copy data is available, then it's neither a space nor a |
/* If no copy data is available, then it's neither a space nor a |
2487 |
subspace. */ |
subspace. */ |
2488 |
if (som_section_data (section)->copy_data == NULL) |
if (som_section_data (section)->copy_data == NULL) |
2489 |
return false; |
return FALSE; |
2490 |
|
|
2491 |
/* If the containing space isn't the same as the given section, |
/* If the containing space isn't the same as the given section, |
2492 |
then this isn't a space. */ |
then this isn't a space. */ |
2493 |
if (som_section_data (section)->copy_data->container != section |
if (som_section_data (section)->copy_data->container != section |
2494 |
&& (som_section_data (section)->copy_data->container->output_section |
&& (som_section_data (section)->copy_data->container->output_section |
2495 |
!= section)) |
!= section)) |
2496 |
return false; |
return FALSE; |
2497 |
|
|
2498 |
/* OK. Must be a space. */ |
/* OK. Must be a space. */ |
2499 |
return true; |
return TRUE; |
2500 |
} |
} |
2501 |
|
|
2502 |
/* Return true if the given section is a SOM subspace, false otherwise. */ |
/* Return TRUE if the given section is a SOM subspace, FALSE otherwise. */ |
2503 |
|
|
2504 |
static boolean |
static bfd_boolean |
2505 |
som_is_subspace (section) |
som_is_subspace (section) |
2506 |
asection *section; |
asection *section; |
2507 |
{ |
{ |
2508 |
/* If no copy data is available, then it's neither a space nor a |
/* If no copy data is available, then it's neither a space nor a |
2509 |
subspace. */ |
subspace. */ |
2510 |
if (som_section_data (section)->copy_data == NULL) |
if (som_section_data (section)->copy_data == NULL) |
2511 |
return false; |
return FALSE; |
2512 |
|
|
2513 |
/* If the containing space is the same as the given section, |
/* If the containing space is the same as the given section, |
2514 |
then this isn't a subspace. */ |
then this isn't a subspace. */ |
2515 |
if (som_section_data (section)->copy_data->container == section |
if (som_section_data (section)->copy_data->container == section |
2516 |
|| (som_section_data (section)->copy_data->container->output_section |
|| (som_section_data (section)->copy_data->container->output_section |
2517 |
== section)) |
== section)) |
2518 |
return false; |
return FALSE; |
2519 |
|
|
2520 |
/* OK. Must be a subspace. */ |
/* OK. Must be a subspace. */ |
2521 |
return true; |
return TRUE; |
2522 |
} |
} |
2523 |
|
|
2524 |
/* Return true if the given space containins the given subspace. It |
/* Return TRUE if the given space contains the given subspace. It |
2525 |
is safe to assume space really is a space, and subspace really |
is safe to assume space really is a space, and subspace really |
2526 |
is a subspace. */ |
is a subspace. */ |
2527 |
|
|
2528 |
static boolean |
static bfd_boolean |
2529 |
som_is_container (space, subspace) |
som_is_container (space, subspace) |
2530 |
asection *space, *subspace; |
asection *space, *subspace; |
2531 |
{ |
{ |
2723 |
} |
} |
2724 |
} |
} |
2725 |
|
|
2726 |
static boolean |
static bfd_boolean |
2727 |
som_write_fixups (abfd, current_offset, total_reloc_sizep) |
som_write_fixups (abfd, current_offset, total_reloc_sizep) |
2728 |
bfd *abfd; |
bfd *abfd; |
2729 |
unsigned long current_offset; |
unsigned long current_offset; |
2766 |
int reloc_offset; |
int reloc_offset; |
2767 |
unsigned int current_rounding_mode; |
unsigned int current_rounding_mode; |
2768 |
#ifndef NO_PCREL_MODES |
#ifndef NO_PCREL_MODES |
2769 |
int current_call_mode; |
unsigned int current_call_mode; |
2770 |
#endif |
#endif |
2771 |
|
|
2772 |
/* Find a subspace of this space. */ |
/* Find a subspace of this space. */ |
2775 |
continue; |
continue; |
2776 |
|
|
2777 |
/* If this subspace does not have real data, then we are |
/* If this subspace does not have real data, then we are |
2778 |
finised with it. */ |
finished with it. */ |
2779 |
if ((subsection->flags & SEC_HAS_CONTENTS) == 0) |
if ((subsection->flags & SEC_HAS_CONTENTS) == 0) |
2780 |
{ |
{ |
2781 |
som_section_data (subsection)->subspace_dict->fixup_request_index |
som_section_data (subsection)->subspace_dict->fixup_request_index |
2793 |
for this subspace in preparation for writing out its fixup |
for this subspace in preparation for writing out its fixup |
2794 |
stream. */ |
stream. */ |
2795 |
if (bfd_seek (abfd, current_offset + total_reloc_size, SEEK_SET) != 0) |
if (bfd_seek (abfd, current_offset + total_reloc_size, SEEK_SET) != 0) |
2796 |
return false; |
return FALSE; |
2797 |
|
|
2798 |
/* Buffer space has already been allocated. Just perform some |
/* Buffer space has already been allocated. Just perform some |
2799 |
initialization here. */ |
initialization here. */ |
2832 |
{ |
{ |
2833 |
amt = p - tmp_space; |
amt = p - tmp_space; |
2834 |
if (bfd_bwrite ((PTR) tmp_space, amt, abfd) != amt) |
if (bfd_bwrite ((PTR) tmp_space, amt, abfd) != amt) |
2835 |
return false; |
return FALSE; |
2836 |
|
|
2837 |
p = tmp_space; |
p = tmp_space; |
2838 |
som_initialize_reloc_queue (reloc_queue); |
som_initialize_reloc_queue (reloc_queue); |
3093 |
|
|
3094 |
/* Last BFD relocation for a subspace has been processed. |
/* Last BFD relocation for a subspace has been processed. |
3095 |
Map the rest of the subspace with R_NO_RELOCATION fixups. */ |
Map the rest of the subspace with R_NO_RELOCATION fixups. */ |
3096 |
p = som_reloc_skip (abfd, bfd_section_size (abfd, subsection) |
p = som_reloc_skip (abfd, subsection->size - reloc_offset, |
|
- reloc_offset, |
|
3097 |
p, &subspace_reloc_size, reloc_queue); |
p, &subspace_reloc_size, reloc_queue); |
3098 |
|
|
3099 |
/* Scribble out the relocations. */ |
/* Scribble out the relocations. */ |
3100 |
amt = p - tmp_space; |
amt = p - tmp_space; |
3101 |
if (bfd_bwrite ((PTR) tmp_space, amt, abfd) != amt) |
if (bfd_bwrite ((PTR) tmp_space, amt, abfd) != amt) |
3102 |
return false; |
return FALSE; |
3103 |
p = tmp_space; |
p = tmp_space; |
3104 |
|
|
3105 |
total_reloc_size += subspace_reloc_size; |
total_reloc_size += subspace_reloc_size; |
3109 |
section = section->next; |
section = section->next; |
3110 |
} |
} |
3111 |
*total_reloc_sizep = total_reloc_size; |
*total_reloc_sizep = total_reloc_size; |
3112 |
return true; |
return TRUE; |
3113 |
} |
} |
3114 |
|
|
3115 |
/* Write out the space/subspace string table. */ |
/* Write out the space/subspace string table. */ |
3116 |
|
|
3117 |
static boolean |
static bfd_boolean |
3118 |
som_write_space_strings (abfd, current_offset, string_sizep) |
som_write_space_strings (abfd, current_offset, string_sizep) |
3119 |
bfd *abfd; |
bfd *abfd; |
3120 |
unsigned long current_offset; |
unsigned long current_offset; |
3132 |
/* Seek to the start of the space strings in preparation for writing |
/* Seek to the start of the space strings in preparation for writing |
3133 |
them out. */ |
them out. */ |
3134 |
if (bfd_seek (abfd, (file_ptr) current_offset, SEEK_SET) != 0) |
if (bfd_seek (abfd, (file_ptr) current_offset, SEEK_SET) != 0) |
3135 |
return false; |
return FALSE; |
3136 |
|
|
3137 |
/* Walk through all the spaces and subspaces (order is not important) |
/* Walk through all the spaces and subspaces (order is not important) |
3138 |
building up and writing string table entries for their names. */ |
building up and writing string table entries for their names. */ |
3149 |
length = strlen (section->name); |
length = strlen (section->name); |
3150 |
|
|
3151 |
/* If there is not enough room for the next entry, then dump the |
/* If there is not enough room for the next entry, then dump the |
3152 |
current buffer contents now and maybe allocate a larger |
current buffer contents now and maybe allocate a larger |
3153 |
buffer. Each entry will take 4 bytes to hold the string |
buffer. Each entry will take 4 bytes to hold the string |
3154 |
length + the string itself + null terminator. */ |
length + the string itself + null terminator. */ |
3155 |
if (p - tmp_space + 5 + length > tmp_space_size) |
if (p - tmp_space + 5 + length > tmp_space_size) |
3156 |
{ |
{ |
3157 |
/* Flush buffer before refilling or reallocating. */ |
/* Flush buffer before refilling or reallocating. */ |
3158 |
amt = p - tmp_space; |
amt = p - tmp_space; |
3159 |
if (bfd_bwrite ((PTR) &tmp_space[0], amt, abfd) != amt) |
if (bfd_bwrite ((PTR) &tmp_space[0], amt, abfd) != amt) |
3160 |
return false; |
return FALSE; |
3161 |
|
|
3162 |
/* Reallocate if now empty buffer still too small. */ |
/* Reallocate if now empty buffer still too small. */ |
3163 |
if (5 + length > tmp_space_size) |
if (5 + length > tmp_space_size) |
3164 |
{ |
{ |
3165 |
/* Ensure a minimum growth factor to avoid O(n**2) space |
/* Ensure a minimum growth factor to avoid O(n**2) space |
3166 |
consumption for n strings. The optimal minimum |
consumption for n strings. The optimal minimum |
3167 |
factor seems to be 2, as no other value can guarantee |
factor seems to be 2, as no other value can guarantee |
3168 |
wasting less than 50% space. (Note that we cannot |
wasting less than 50% space. (Note that we cannot |
3169 |
deallocate space allocated by `alloca' without |
deallocate space allocated by `alloca' without |
3170 |
returning from this function.) The same technique is |
returning from this function.) The same technique is |
3171 |
used a few more times below when a buffer is |
used a few more times below when a buffer is |
3172 |
reallocated. */ |
reallocated. */ |
3173 |
tmp_space_size = MAX (2 * tmp_space_size, 5 + length); |
tmp_space_size = MAX (2 * tmp_space_size, 5 + length); |
3174 |
tmp_space = alloca (tmp_space_size); |
tmp_space = alloca (tmp_space_size); |
3175 |
} |
} |
3208 |
contained in a partial block. */ |
contained in a partial block. */ |
3209 |
amt = p - tmp_space; |
amt = p - tmp_space; |
3210 |
if (bfd_bwrite ((PTR) &tmp_space[0], amt, abfd) != amt) |
if (bfd_bwrite ((PTR) &tmp_space[0], amt, abfd) != amt) |
3211 |
return false; |
return FALSE; |
3212 |
*string_sizep = strings_size; |
*string_sizep = strings_size; |
3213 |
return true; |
return TRUE; |
3214 |
} |
} |
3215 |
|
|
3216 |
/* Write out the symbol string table. */ |
/* Write out the symbol string table. */ |
3217 |
|
|
3218 |
static boolean |
static bfd_boolean |
3219 |
som_write_symbol_strings (abfd, current_offset, syms, num_syms, string_sizep, |
som_write_symbol_strings (abfd, current_offset, syms, num_syms, string_sizep, |
3220 |
compilation_unit) |
compilation_unit) |
3221 |
bfd *abfd; |
bfd *abfd; |
3240 |
/* This gets a bit gruesome because of the compilation unit. The |
/* This gets a bit gruesome because of the compilation unit. The |
3241 |
strings within the compilation unit are part of the symbol |
strings within the compilation unit are part of the symbol |
3242 |
strings, but don't have symbol_dictionary entries. So, manually |
strings, but don't have symbol_dictionary entries. So, manually |
3243 |
write them and update the compliation unit header. On input, the |
write them and update the compilation unit header. On input, the |
3244 |
compilation unit header contains local copies of the strings. |
compilation unit header contains local copies of the strings. |
3245 |
Move them aside. */ |
Move them aside. */ |
3246 |
if (compilation_unit) |
if (compilation_unit) |
3254 |
/* Seek to the start of the space strings in preparation for writing |
/* Seek to the start of the space strings in preparation for writing |
3255 |
them out. */ |
them out. */ |
3256 |
if (bfd_seek (abfd, (file_ptr) current_offset, SEEK_SET) != 0) |
if (bfd_seek (abfd, (file_ptr) current_offset, SEEK_SET) != 0) |
3257 |
return false; |
return FALSE; |
3258 |
|
|
3259 |
if (compilation_unit) |
if (compilation_unit) |
3260 |
{ |
{ |
3270 |
/* Flush buffer before refilling or reallocating. */ |
/* Flush buffer before refilling or reallocating. */ |
3271 |
amt = p - tmp_space; |
amt = p - tmp_space; |
3272 |
if (bfd_bwrite ((PTR) &tmp_space[0], amt, abfd) != amt) |
if (bfd_bwrite ((PTR) &tmp_space[0], amt, abfd) != amt) |
3273 |
return false; |
return FALSE; |
3274 |
|
|
3275 |
/* Reallocate if now empty buffer still too small. */ |
/* Reallocate if now empty buffer still too small. */ |
3276 |
if (5 + length > tmp_space_size) |
if (5 + length > tmp_space_size) |
3281 |
} |
} |
3282 |
|
|
3283 |
/* Reset to beginning of the (possibly new) buffer |
/* Reset to beginning of the (possibly new) buffer |
3284 |
space. */ |
space. */ |
3285 |
p = tmp_space; |
p = tmp_space; |
3286 |
} |
} |
3287 |
|
|
3339 |
/* Flush buffer before refilling or reallocating. */ |
/* Flush buffer before refilling or reallocating. */ |
3340 |
amt = p - tmp_space; |
amt = p - tmp_space; |
3341 |
if (bfd_bwrite ((PTR) &tmp_space[0], amt, abfd) != amt) |
if (bfd_bwrite ((PTR) &tmp_space[0], amt, abfd) != amt) |
3342 |
return false; |
return FALSE; |
3343 |
|
|
3344 |
/* Reallocate if now empty buffer still too small. */ |
/* Reallocate if now empty buffer still too small. */ |
3345 |
if (5 + length > tmp_space_size) |
if (5 + length > tmp_space_size) |
3380 |
/* Scribble out any partial block. */ |
/* Scribble out any partial block. */ |
3381 |
amt = p - tmp_space; |
amt = p - tmp_space; |
3382 |
if (bfd_bwrite ((PTR) &tmp_space[0], amt, abfd) != amt) |
if (bfd_bwrite ((PTR) &tmp_space[0], amt, abfd) != amt) |
3383 |
return false; |
return FALSE; |
3384 |
|
|
3385 |
*string_sizep = strings_size; |
*string_sizep = strings_size; |
3386 |
return true; |
return TRUE; |
3387 |
} |
} |
3388 |
|
|
3389 |
/* Compute variable information to be placed in the SOM headers, |
/* Compute variable information to be placed in the SOM headers, |
3390 |
space/subspace dictionaries, relocation streams, etc. Begin |
space/subspace dictionaries, relocation streams, etc. Begin |
3391 |
writing parts of the object file. */ |
writing parts of the object file. */ |
3392 |
|
|
3393 |
static boolean |
static bfd_boolean |
3394 |
som_begin_writing (abfd) |
som_begin_writing (abfd) |
3395 |
bfd *abfd; |
bfd *abfd; |
3396 |
{ |
{ |
3436 |
bfd_size_type len; |
bfd_size_type len; |
3437 |
|
|
3438 |
if (bfd_seek (abfd, (file_ptr) current_offset, SEEK_SET) != 0) |
if (bfd_seek (abfd, (file_ptr) current_offset, SEEK_SET) != 0) |
3439 |
return false; |
return FALSE; |
3440 |
|
|
3441 |
/* Write the aux_id structure and the string length. */ |
/* Write the aux_id structure and the string length. */ |
3442 |
len = sizeof (struct aux_id) + sizeof (unsigned int); |
len = sizeof (struct aux_id) + sizeof (unsigned int); |
3443 |
obj_som_file_hdr (abfd)->aux_header_size += len; |
obj_som_file_hdr (abfd)->aux_header_size += len; |
3444 |
current_offset += len; |
current_offset += len; |
3445 |
if (bfd_bwrite ((PTR) obj_som_version_hdr (abfd), len, abfd) != len) |
if (bfd_bwrite ((PTR) obj_som_version_hdr (abfd), len, abfd) != len) |
3446 |
return false; |
return FALSE; |
3447 |
|
|
3448 |
/* Write the version string. */ |
/* Write the version string. */ |
3449 |
len = obj_som_version_hdr (abfd)->header_id.length - sizeof (int); |
len = obj_som_version_hdr (abfd)->header_id.length - sizeof (int); |
3451 |
current_offset += len; |
current_offset += len; |
3452 |
if (bfd_bwrite ((PTR) obj_som_version_hdr (abfd)->user_string, len, abfd) |
if (bfd_bwrite ((PTR) obj_som_version_hdr (abfd)->user_string, len, abfd) |
3453 |
!= len) |
!= len) |
3454 |
return false; |
return FALSE; |
3455 |
} |
} |
3456 |
|
|
3457 |
if (obj_som_copyright_hdr (abfd) != NULL) |
if (obj_som_copyright_hdr (abfd) != NULL) |
3459 |
bfd_size_type len; |
bfd_size_type len; |
3460 |
|
|
3461 |
if (bfd_seek (abfd, (file_ptr) current_offset, SEEK_SET) != 0) |
if (bfd_seek (abfd, (file_ptr) current_offset, SEEK_SET) != 0) |
3462 |
return false; |
return FALSE; |
3463 |
|
|
3464 |
/* Write the aux_id structure and the string length. */ |
/* Write the aux_id structure and the string length. */ |
3465 |
len = sizeof (struct aux_id) + sizeof (unsigned int); |
len = sizeof (struct aux_id) + sizeof (unsigned int); |
3466 |
obj_som_file_hdr (abfd)->aux_header_size += len; |
obj_som_file_hdr (abfd)->aux_header_size += len; |
3467 |
current_offset += len; |
current_offset += len; |
3468 |
if (bfd_bwrite ((PTR) obj_som_copyright_hdr (abfd), len, abfd) != len) |
if (bfd_bwrite ((PTR) obj_som_copyright_hdr (abfd), len, abfd) != len) |
3469 |
return false; |
return FALSE; |
3470 |
|
|
3471 |
/* Write the copyright string. */ |
/* Write the copyright string. */ |
3472 |
len = obj_som_copyright_hdr (abfd)->header_id.length - sizeof (int); |
len = obj_som_copyright_hdr (abfd)->header_id.length - sizeof (int); |
3474 |
current_offset += len; |
current_offset += len; |
3475 |
if (bfd_bwrite ((PTR) obj_som_copyright_hdr (abfd)->copyright, len, abfd) |
if (bfd_bwrite ((PTR) obj_som_copyright_hdr (abfd)->copyright, len, abfd) |
3476 |
!= len) |
!= len) |
3477 |
return false; |
return FALSE; |
3478 |
} |
} |
3479 |
|
|
3480 |
/* Next comes the initialization pointers; we have no initialization |
/* Next comes the initialization pointers; we have no initialization |
3506 |
num_subspaces = som_count_subspaces (abfd); |
num_subspaces = som_count_subspaces (abfd); |
3507 |
obj_som_file_hdr (abfd)->subspace_location = current_offset; |
obj_som_file_hdr (abfd)->subspace_location = current_offset; |
3508 |
obj_som_file_hdr (abfd)->subspace_total = num_subspaces; |
obj_som_file_hdr (abfd)->subspace_total = num_subspaces; |
3509 |
current_offset += num_subspaces * sizeof (struct subspace_dictionary_record); |
current_offset |
3510 |
|
+= num_subspaces * sizeof (struct som_subspace_dictionary_record); |
3511 |
|
|
3512 |
/* Next is the string table for the space/subspace names. We will |
/* Next is the string table for the space/subspace names. We will |
3513 |
build and write the string table on the fly. At the same time |
build and write the string table on the fly. At the same time |
3523 |
|
|
3524 |
/* Scribble out the space strings. */ |
/* Scribble out the space strings. */ |
3525 |
if (! som_write_space_strings (abfd, current_offset, &strings_size)) |
if (! som_write_space_strings (abfd, current_offset, &strings_size)) |
3526 |
return false; |
return FALSE; |
3527 |
|
|
3528 |
/* Record total string table size in the header and update the |
/* Record total string table size in the header and update the |
3529 |
current offset. */ |
current offset. */ |
3634 |
/* Update the size of the code & data. */ |
/* Update the size of the code & data. */ |
3635 |
if (abfd->flags & (EXEC_P | DYNAMIC) |
if (abfd->flags & (EXEC_P | DYNAMIC) |
3636 |
&& subsection->flags & SEC_CODE) |
&& subsection->flags & SEC_CODE) |
3637 |
exec_header->exec_tsize += subsection->_cooked_size; |
exec_header->exec_tsize += subsection->size; |
3638 |
else if (abfd->flags & (EXEC_P | DYNAMIC) |
else if (abfd->flags & (EXEC_P | DYNAMIC) |
3639 |
&& subsection->flags & SEC_DATA) |
&& subsection->flags & SEC_DATA) |
3640 |
exec_header->exec_dsize += subsection->_cooked_size; |
exec_header->exec_dsize += subsection->size; |
3641 |
som_section_data (subsection)->subspace_dict->file_loc_init_value |
som_section_data (subsection)->subspace_dict->file_loc_init_value |
3642 |
= current_offset; |
= current_offset; |
3643 |
subsection->filepos = current_offset; |
subsection->filepos = current_offset; |
3644 |
current_offset += bfd_section_size (abfd, subsection); |
current_offset += subsection->size; |
3645 |
subspace_offset += bfd_section_size (abfd, subsection); |
subspace_offset += subsection->size; |
3646 |
} |
} |
3647 |
/* Looks like uninitialized data. */ |
/* Looks like uninitialized data. */ |
3648 |
else |
else |
3649 |
{ |
{ |
3650 |
/* Update the size of the bss section. */ |
/* Update the size of the bss section. */ |
3651 |
if (abfd->flags & (EXEC_P | DYNAMIC)) |
if (abfd->flags & (EXEC_P | DYNAMIC)) |
3652 |
exec_header->exec_bsize += subsection->_cooked_size; |
exec_header->exec_bsize += subsection->size; |
3653 |
|
|
3654 |
som_section_data (subsection)->subspace_dict->file_loc_init_value |
som_section_data (subsection)->subspace_dict->file_loc_init_value |
3655 |
= 0; |
= 0; |
3699 |
som_section_data (subsection)->subspace_dict->file_loc_init_value |
som_section_data (subsection)->subspace_dict->file_loc_init_value |
3700 |
= current_offset; |
= current_offset; |
3701 |
subsection->filepos = current_offset; |
subsection->filepos = current_offset; |
3702 |
current_offset += bfd_section_size (abfd, subsection); |
current_offset += subsection->size; |
3703 |
} |
} |
3704 |
/* Looks like uninitialized data. */ |
/* Looks like uninitialized data. */ |
3705 |
else |
else |
3707 |
som_section_data (subsection)->subspace_dict->file_loc_init_value |
som_section_data (subsection)->subspace_dict->file_loc_init_value |
3708 |
= 0; |
= 0; |
3709 |
som_section_data (subsection)->subspace_dict-> |
som_section_data (subsection)->subspace_dict-> |
3710 |
initialization_length = bfd_section_size (abfd, subsection); |
initialization_length = subsection->size; |
3711 |
} |
} |
3712 |
} |
} |
3713 |
/* Goto the next section. */ |
/* Goto the next section. */ |
3720 |
if (abfd->flags & (EXEC_P | DYNAMIC)) |
if (abfd->flags & (EXEC_P | DYNAMIC)) |
3721 |
current_offset = SOM_ALIGN (current_offset, PA_PAGESIZE); |
current_offset = SOM_ALIGN (current_offset, PA_PAGESIZE); |
3722 |
if (bfd_seek (abfd, (file_ptr) current_offset - 1, SEEK_SET) != 0) |
if (bfd_seek (abfd, (file_ptr) current_offset - 1, SEEK_SET) != 0) |
3723 |
return false; |
return FALSE; |
3724 |
if (bfd_bwrite ((PTR) "", (bfd_size_type) 1, abfd) != 1) |
if (bfd_bwrite ((PTR) "", (bfd_size_type) 1, abfd) != 1) |
3725 |
return false; |
return FALSE; |
3726 |
|
|
3727 |
obj_som_file_hdr (abfd)->unloadable_sp_size |
obj_som_file_hdr (abfd)->unloadable_sp_size |
3728 |
= current_offset - obj_som_file_hdr (abfd)->unloadable_sp_location; |
= current_offset - obj_som_file_hdr (abfd)->unloadable_sp_location; |
3734 |
/* Done. Store the total size of the SOM so far. */ |
/* Done. Store the total size of the SOM so far. */ |
3735 |
obj_som_file_hdr (abfd)->som_length = current_offset; |
obj_som_file_hdr (abfd)->som_length = current_offset; |
3736 |
|
|
3737 |
return true; |
return TRUE; |
3738 |
} |
} |
3739 |
|
|
3740 |
/* Finally, scribble out the various headers to the disk. */ |
/* Finally, scribble out the various headers to the disk. */ |
3741 |
|
|
3742 |
static boolean |
static bfd_boolean |
3743 |
som_finish_writing (abfd) |
som_finish_writing (abfd) |
3744 |
bfd *abfd; |
bfd *abfd; |
3745 |
{ |
{ |
3795 |
if (! som_write_symbol_strings (abfd, current_offset, syms, |
if (! som_write_symbol_strings (abfd, current_offset, syms, |
3796 |
num_syms, &strings_size, |
num_syms, &strings_size, |
3797 |
obj_som_compilation_unit (abfd))) |
obj_som_compilation_unit (abfd))) |
3798 |
return false; |
return FALSE; |
3799 |
|
|
3800 |
/* Record total string table size in header and update the |
/* Record total string table size in header and update the |
3801 |
current offset. */ |
current offset. */ |
3816 |
/* Write the fixups and update fields in subspace headers which |
/* Write the fixups and update fields in subspace headers which |
3817 |
relate to the fixup stream. */ |
relate to the fixup stream. */ |
3818 |
if (! som_write_fixups (abfd, current_offset, &total_reloc_size)) |
if (! som_write_fixups (abfd, current_offset, &total_reloc_size)) |
3819 |
return false; |
return FALSE; |
3820 |
|
|
3821 |
/* Record the total size of the fixup stream in the file header. */ |
/* Record the total size of the fixup stream in the file header. */ |
3822 |
obj_som_file_hdr (abfd)->fixup_request_total = total_reloc_size; |
obj_som_file_hdr (abfd)->fixup_request_total = total_reloc_size; |
3827 |
/* Now that the symbol table information is complete, build and |
/* Now that the symbol table information is complete, build and |
3828 |
write the symbol table. */ |
write the symbol table. */ |
3829 |
if (! som_build_and_write_symbol_table (abfd)) |
if (! som_build_and_write_symbol_table (abfd)) |
3830 |
return false; |
return FALSE; |
3831 |
|
|
3832 |
/* Subspaces are written first so that we can set up information |
/* Subspaces are written first so that we can set up information |
3833 |
about them in their containing spaces as the subspace is written. */ |
about them in their containing spaces as the subspace is written. */ |
3835 |
/* Seek to the start of the subspace dictionary records. */ |
/* Seek to the start of the subspace dictionary records. */ |
3836 |
location = obj_som_file_hdr (abfd)->subspace_location; |
location = obj_som_file_hdr (abfd)->subspace_location; |
3837 |
if (bfd_seek (abfd, location, SEEK_SET) != 0) |
if (bfd_seek (abfd, location, SEEK_SET) != 0) |
3838 |
return false; |
return FALSE; |
3839 |
|
|
3840 |
section = abfd->sections; |
section = abfd->sections; |
3841 |
/* Now for each loadable space write out records for its subspaces. */ |
/* Now for each loadable space write out records for its subspaces. */ |
3882 |
som_section_data (subsection)->subspace_dict->space_index = i; |
som_section_data (subsection)->subspace_dict->space_index = i; |
3883 |
|
|
3884 |
/* Dump the current subspace header. */ |
/* Dump the current subspace header. */ |
3885 |
amt = sizeof (struct subspace_dictionary_record); |
amt = sizeof (struct som_subspace_dictionary_record); |
3886 |
if (bfd_bwrite ((PTR) som_section_data (subsection)->subspace_dict, |
if (bfd_bwrite ((PTR) som_section_data (subsection)->subspace_dict, |
3887 |
amt, abfd) != amt) |
amt, abfd) != amt) |
3888 |
return false; |
return FALSE; |
3889 |
} |
} |
3890 |
/* Goto the next section. */ |
/* Goto the next section. */ |
3891 |
section = section->next; |
section = section->next; |
3938 |
som_section_data (subsection)->subspace_dict->space_index = i; |
som_section_data (subsection)->subspace_dict->space_index = i; |
3939 |
|
|
3940 |
/* Dump this subspace header. */ |
/* Dump this subspace header. */ |
3941 |
amt = sizeof (struct subspace_dictionary_record); |
amt = sizeof (struct som_subspace_dictionary_record); |
3942 |
if (bfd_bwrite ((PTR) som_section_data (subsection)->subspace_dict, |
if (bfd_bwrite ((PTR) som_section_data (subsection)->subspace_dict, |
3943 |
amt, abfd) != amt) |
amt, abfd) != amt) |
3944 |
return false; |
return FALSE; |
3945 |
} |
} |
3946 |
/* Goto the next section. */ |
/* Goto the next section. */ |
3947 |
section = section->next; |
section = section->next; |
3948 |
} |
} |
3949 |
|
|
3950 |
/* All the subspace dictiondary records are written, and all the |
/* All the subspace dictionary records are written, and all the |
3951 |
fields are set up in the space dictionary records. |
fields are set up in the space dictionary records. |
3952 |
|
|
3953 |
Seek to the right location and start writing the space |
Seek to the right location and start writing the space |
3954 |
dictionary records. */ |
dictionary records. */ |
3955 |
location = obj_som_file_hdr (abfd)->space_location; |
location = obj_som_file_hdr (abfd)->space_location; |
3956 |
if (bfd_seek (abfd, location, SEEK_SET) != 0) |
if (bfd_seek (abfd, location, SEEK_SET) != 0) |
3957 |
return false; |
return FALSE; |
3958 |
|
|
3959 |
section = abfd->sections; |
section = abfd->sections; |
3960 |
for (i = 0; i < num_spaces; i++) |
for (i = 0; i < num_spaces; i++) |
3967 |
amt = sizeof (struct space_dictionary_record); |
amt = sizeof (struct space_dictionary_record); |
3968 |
if (bfd_bwrite ((PTR) som_section_data (section)->space_dict, |
if (bfd_bwrite ((PTR) som_section_data (section)->space_dict, |
3969 |
amt, abfd) != amt) |
amt, abfd) != amt) |
3970 |
return false; |
return FALSE; |
3971 |
|
|
3972 |
/* Goto the next section. */ |
/* Goto the next section. */ |
3973 |
section = section->next; |
section = section->next; |
3978 |
{ |
{ |
3979 |
location = obj_som_file_hdr (abfd)->compiler_location; |
location = obj_som_file_hdr (abfd)->compiler_location; |
3980 |
if (bfd_seek (abfd, location, SEEK_SET) != 0) |
if (bfd_seek (abfd, location, SEEK_SET) != 0) |
3981 |
return false; |
return FALSE; |
3982 |
|
|
3983 |
amt = COMPUNITSZ; |
amt = COMPUNITSZ; |
3984 |
if (bfd_bwrite ((PTR) obj_som_compilation_unit (abfd), amt, abfd) != amt) |
if (bfd_bwrite ((PTR) obj_som_compilation_unit (abfd), amt, abfd) != amt) |
3985 |
return false; |
return FALSE; |
3986 |
} |
} |
3987 |
|
|
3988 |
/* Setting of the system_id has to happen very late now that copying of |
/* Setting of the system_id has to happen very late now that copying of |
4003 |
/* Only thing left to do is write out the file header. It is always |
/* Only thing left to do is write out the file header. It is always |
4004 |
at location zero. Seek there and write it. */ |
at location zero. Seek there and write it. */ |
4005 |
if (bfd_seek (abfd, (file_ptr) 0, SEEK_SET) != 0) |
if (bfd_seek (abfd, (file_ptr) 0, SEEK_SET) != 0) |
4006 |
return false; |
return FALSE; |
4007 |
amt = sizeof (struct header); |
amt = sizeof (struct header); |
4008 |
if (bfd_bwrite ((PTR) obj_som_file_hdr (abfd), amt, abfd) != amt) |
if (bfd_bwrite ((PTR) obj_som_file_hdr (abfd), amt, abfd) != amt) |
4009 |
return false; |
return FALSE; |
4010 |
|
|
4011 |
/* Now write the exec header. */ |
/* Now write the exec header. */ |
4012 |
if (abfd->flags & (EXEC_P | DYNAMIC)) |
if (abfd->flags & (EXEC_P | DYNAMIC)) |
4019 |
exec_header->exec_flags = obj_som_exec_data (abfd)->exec_flags; |
exec_header->exec_flags = obj_som_exec_data (abfd)->exec_flags; |
4020 |
|
|
4021 |
/* Oh joys. Ram some of the BSS data into the DATA section |
/* Oh joys. Ram some of the BSS data into the DATA section |
4022 |
to be compatable with how the hp linker makes objects |
to be compatible with how the hp linker makes objects |
4023 |
(saves memory space). */ |
(saves memory space). */ |
4024 |
tmp = exec_header->exec_dsize; |
tmp = exec_header->exec_dsize; |
4025 |
tmp = SOM_ALIGN (tmp, PA_PAGESIZE); |
tmp = SOM_ALIGN (tmp, PA_PAGESIZE); |
4035 |
|| exec_header->exec_dfile + exec_header->exec_dsize > som_length) |
|| exec_header->exec_dfile + exec_header->exec_dsize > som_length) |
4036 |
{ |
{ |
4037 |
bfd_set_error (bfd_error_bad_value); |
bfd_set_error (bfd_error_bad_value); |
4038 |
return false; |
return FALSE; |
4039 |
} |
} |
4040 |
|
|
4041 |
if (bfd_seek (abfd, obj_som_file_hdr (abfd)->aux_header_location, |
if (bfd_seek (abfd, obj_som_file_hdr (abfd)->aux_header_location, |
4042 |
SEEK_SET) != 0) |
SEEK_SET) != 0) |
4043 |
return false; |
return FALSE; |
4044 |
|
|
4045 |
amt = AUX_HDR_SIZE; |
amt = AUX_HDR_SIZE; |
4046 |
if (bfd_bwrite ((PTR) exec_header, amt, abfd) != amt) |
if (bfd_bwrite ((PTR) exec_header, amt, abfd) != amt) |
4047 |
return false; |
return FALSE; |
4048 |
} |
} |
4049 |
return true; |
return TRUE; |
4050 |
} |
} |
4051 |
|
|
4052 |
/* Compute and return the checksum for a SOM file header. */ |
/* Compute and return the checksum for a SOM file header. */ |
4086 |
info->symbol_type = ST_DATA; |
info->symbol_type = ST_DATA; |
4087 |
else |
else |
4088 |
{ |
{ |
4089 |
/* Common symbols must have scope SS_UNSAT and type |
/* For BFD style common, the linker will choke unless we set the |
4090 |
ST_STORAGE or the linker will choke. */ |
type and scope to ST_STORAGE and SS_UNSAT, respectively. */ |
4091 |
if (bfd_is_com_section (sym->section)) |
if (bfd_is_com_section (sym->section)) |
4092 |
{ |
{ |
|
info->symbol_scope = SS_UNSAT; |
|
4093 |
info->symbol_type = ST_STORAGE; |
info->symbol_type = ST_STORAGE; |
4094 |
|
info->symbol_scope = SS_UNSAT; |
4095 |
} |
} |
4096 |
|
|
4097 |
/* It is possible to have a symbol without an associated |
/* It is possible to have a symbol without an associated |
4130 |
info->symbol_type = ST_DATA; |
info->symbol_type = ST_DATA; |
4131 |
} |
} |
4132 |
|
|
|
else if (som_symbol_data (sym)->som_type == SYMBOL_TYPE_UNKNOWN) |
|
|
info->symbol_type = ST_DATA; |
|
|
|
|
4133 |
/* From now on it's a very simple mapping. */ |
/* From now on it's a very simple mapping. */ |
4134 |
else if (som_symbol_data (sym)->som_type == SYMBOL_TYPE_ABSOLUTE) |
else if (som_symbol_data (sym)->som_type == SYMBOL_TYPE_ABSOLUTE) |
4135 |
info->symbol_type = ST_ABSOLUTE; |
info->symbol_type = ST_ABSOLUTE; |
4150 |
/* Now handle the symbol's scope. Exported data which is not |
/* Now handle the symbol's scope. Exported data which is not |
4151 |
in the common section has scope SS_UNIVERSAL. Note scope |
in the common section has scope SS_UNIVERSAL. Note scope |
4152 |
of common symbols was handled earlier! */ |
of common symbols was handled earlier! */ |
4153 |
if (bfd_is_und_section (sym->section)) |
if (bfd_is_com_section (sym->section)) |
4154 |
|
; |
4155 |
|
else if (bfd_is_und_section (sym->section)) |
4156 |
info->symbol_scope = SS_UNSAT; |
info->symbol_scope = SS_UNSAT; |
4157 |
else if (sym->flags & (BSF_EXPORT | BSF_WEAK) |
else if (sym->flags & (BSF_EXPORT | BSF_WEAK)) |
|
&& ! bfd_is_com_section (sym->section)) |
|
4158 |
info->symbol_scope = SS_UNIVERSAL; |
info->symbol_scope = SS_UNIVERSAL; |
4159 |
/* Anything else which is not in the common section has scope |
/* Anything else which is not in the common section has scope |
4160 |
SS_LOCAL. */ |
SS_LOCAL. */ |
4161 |
else if (! bfd_is_com_section (sym->section)) |
else |
4162 |
info->symbol_scope = SS_LOCAL; |
info->symbol_scope = SS_LOCAL; |
4163 |
|
|
4164 |
/* Now set the symbol_info field. It has no real meaning |
/* Now set the symbol_info field. It has no real meaning |
4177 |
/* Set the symbol's value. */ |
/* Set the symbol's value. */ |
4178 |
info->symbol_value = sym->value + sym->section->vma; |
info->symbol_value = sym->value + sym->section->vma; |
4179 |
|
|
4180 |
/* The secondary_def field is for weak symbols. */ |
/* The secondary_def field is for "weak" symbols. */ |
4181 |
if (sym->flags & BSF_WEAK) |
if (sym->flags & BSF_WEAK) |
4182 |
info->secondary_def = true; |
info->secondary_def = TRUE; |
4183 |
else |
else |
4184 |
info->secondary_def = false; |
info->secondary_def = FALSE; |
4185 |
|
|
4186 |
|
/* The is_comdat, is_common and dup_common fields provide various |
4187 |
|
flavors of common. |
4188 |
|
|
4189 |
|
For data symbols, setting IS_COMMON provides Fortran style common |
4190 |
|
(duplicate definitions and overlapped initialization). Setting both |
4191 |
|
IS_COMMON and DUP_COMMON provides Cobol style common (duplicate |
4192 |
|
definitions as long as they are all the same length). In a shared |
4193 |
|
link data symbols retain their IS_COMMON and DUP_COMMON flags. |
4194 |
|
An IS_COMDAT data symbol is similar to a IS_COMMON | DUP_COMMON |
4195 |
|
symbol except in that it loses its IS_COMDAT flag in a shared link. |
4196 |
|
|
4197 |
|
For code symbols, IS_COMDAT and DUP_COMMON have effect. Universal |
4198 |
|
DUP_COMMON code symbols are not exported from shared libraries. |
4199 |
|
IS_COMDAT symbols are exported but they lose their IS_COMDAT flag. |
4200 |
|
|
4201 |
|
We take a simplified approach to setting the is_comdat, is_common |
4202 |
|
and dup_common flags in symbols based on the flag settings of their |
4203 |
|
subspace. This avoids having to add directives like `.comdat' but |
4204 |
|
the linker behavior is probably undefined if there is more than one |
4205 |
|
universal symbol (comdat key sysmbol) in a subspace. |
4206 |
|
|
4207 |
|
The behavior of these flags is not well documentmented, so there |
4208 |
|
may be bugs and some surprising interactions with other flags. */ |
4209 |
|
if (som_section_data (sym->section) |
4210 |
|
&& som_section_data (sym->section)->subspace_dict |
4211 |
|
&& info->symbol_scope == SS_UNIVERSAL |
4212 |
|
&& (info->symbol_type == ST_ENTRY |
4213 |
|
|| info->symbol_type == ST_CODE |
4214 |
|
|| info->symbol_type == ST_DATA)) |
4215 |
|
{ |
4216 |
|
info->is_comdat |
4217 |
|
= som_section_data (sym->section)->subspace_dict->is_comdat; |
4218 |
|
info->is_common |
4219 |
|
= som_section_data (sym->section)->subspace_dict->is_common; |
4220 |
|
info->dup_common |
4221 |
|
= som_section_data (sym->section)->subspace_dict->dup_common; |
4222 |
|
} |
4223 |
} |
} |
4224 |
|
|
4225 |
/* Build and write, in one big chunk, the entire symbol table for |
/* Build and write, in one big chunk, the entire symbol table for |
4226 |
this BFD. */ |
this BFD. */ |
4227 |
|
|
4228 |
static boolean |
static bfd_boolean |
4229 |
som_build_and_write_symbol_table (abfd) |
som_build_and_write_symbol_table (abfd) |
4230 |
bfd *abfd; |
bfd *abfd; |
4231 |
{ |
{ |
4265 |
som_symtab[i].xleast = 3; |
som_symtab[i].xleast = 3; |
4266 |
som_symtab[i].symbol_value = info.symbol_value | info.priv_level; |
som_symtab[i].symbol_value = info.symbol_value | info.priv_level; |
4267 |
som_symtab[i].secondary_def = info.secondary_def; |
som_symtab[i].secondary_def = info.secondary_def; |
4268 |
|
som_symtab[i].is_comdat = info.is_comdat; |
4269 |
|
som_symtab[i].is_common = info.is_common; |
4270 |
|
som_symtab[i].dup_common = info.dup_common; |
4271 |
} |
} |
4272 |
|
|
4273 |
/* Everything is ready, seek to the right location and |
/* Everything is ready, seek to the right location and |
4274 |
scribble out the symbol table. */ |
scribble out the symbol table. */ |
4275 |
if (bfd_seek (abfd, symtab_location, SEEK_SET) != 0) |
if (bfd_seek (abfd, symtab_location, SEEK_SET) != 0) |
4276 |
return false; |
return FALSE; |
4277 |
|
|
4278 |
if (bfd_bwrite ((PTR) som_symtab, symtab_size, abfd) != symtab_size) |
if (bfd_bwrite ((PTR) som_symtab, symtab_size, abfd) != symtab_size) |
4279 |
goto error_return; |
goto error_return; |
4280 |
|
|
4281 |
if (som_symtab != NULL) |
if (som_symtab != NULL) |
4282 |
free (som_symtab); |
free (som_symtab); |
4283 |
return true; |
return TRUE; |
4284 |
error_return: |
error_return: |
4285 |
if (som_symtab != NULL) |
if (som_symtab != NULL) |
4286 |
free (som_symtab); |
free (som_symtab); |
4287 |
return false; |
return FALSE; |
4288 |
} |
} |
4289 |
|
|
4290 |
/* Write an object in SOM format. */ |
/* Write an object in SOM format. */ |
4291 |
|
|
4292 |
static boolean |
static bfd_boolean |
4293 |
som_write_object_contents (abfd) |
som_write_object_contents (abfd) |
4294 |
bfd *abfd; |
bfd *abfd; |
4295 |
{ |
{ |
4298 |
/* Set up fixed parts of the file, space, and subspace headers. |
/* Set up fixed parts of the file, space, and subspace headers. |
4299 |
Notify the world that output has begun. */ |
Notify the world that output has begun. */ |
4300 |
som_prep_headers (abfd); |
som_prep_headers (abfd); |
4301 |
abfd->output_has_begun = true; |
abfd->output_has_begun = TRUE; |
4302 |
/* Start writing the object file. This include all the string |
/* Start writing the object file. This include all the string |
4303 |
tables, fixup streams, and other portions of the object file. */ |
tables, fixup streams, and other portions of the object file. */ |
4304 |
som_begin_writing (abfd); |
som_begin_writing (abfd); |
4309 |
|
|
4310 |
/* Read and save the string table associated with the given BFD. */ |
/* Read and save the string table associated with the given BFD. */ |
4311 |
|
|
4312 |
static boolean |
static bfd_boolean |
4313 |
som_slurp_string_table (abfd) |
som_slurp_string_table (abfd) |
4314 |
bfd *abfd; |
bfd *abfd; |
4315 |
{ |
{ |
4318 |
|
|
4319 |
/* Use the saved version if its available. */ |
/* Use the saved version if its available. */ |
4320 |
if (obj_som_stringtab (abfd) != NULL) |
if (obj_som_stringtab (abfd) != NULL) |
4321 |
return true; |
return TRUE; |
4322 |
|
|
4323 |
/* I don't think this can currently happen, and I'm not sure it should |
/* I don't think this can currently happen, and I'm not sure it should |
4324 |
really be an error, but it's better than getting unpredictable results |
really be an error, but it's better than getting unpredictable results |
4326 |
if (obj_som_stringtab_size (abfd) == 0) |
if (obj_som_stringtab_size (abfd) == 0) |
4327 |
{ |
{ |
4328 |
bfd_set_error (bfd_error_no_symbols); |
bfd_set_error (bfd_error_no_symbols); |
4329 |
return false; |
return FALSE; |
4330 |
} |
} |
4331 |
|
|
4332 |
/* Allocate and read in the string table. */ |
/* Allocate and read in the string table. */ |
4333 |
amt = obj_som_stringtab_size (abfd); |
amt = obj_som_stringtab_size (abfd); |
4334 |
stringtab = bfd_zmalloc (amt); |
stringtab = bfd_zmalloc (amt); |
4335 |
if (stringtab == NULL) |
if (stringtab == NULL) |
4336 |
return false; |
return FALSE; |
4337 |
|
|
4338 |
if (bfd_seek (abfd, obj_som_str_filepos (abfd), SEEK_SET) != 0) |
if (bfd_seek (abfd, obj_som_str_filepos (abfd), SEEK_SET) != 0) |
4339 |
return false; |
return FALSE; |
4340 |
|
|
4341 |
if (bfd_bread (stringtab, amt, abfd) != amt) |
if (bfd_bread (stringtab, amt, abfd) != amt) |
4342 |
return false; |
return FALSE; |
4343 |
|
|
4344 |
/* Save our results and return success. */ |
/* Save our results and return success. */ |
4345 |
obj_som_stringtab (abfd) = stringtab; |
obj_som_stringtab (abfd) = stringtab; |
4346 |
return true; |
return TRUE; |
4347 |
} |
} |
4348 |
|
|
4349 |
/* Return the amount of data (in bytes) required to hold the symbol |
/* Return the amount of data (in bytes) required to hold the symbol |
4377 |
&& symbol->symbol_type != ST_SEC_PROG |
&& symbol->symbol_type != ST_SEC_PROG |
4378 |
&& symbol->symbol_type != ST_MILLICODE)) |
&& symbol->symbol_type != ST_MILLICODE)) |
4379 |
{ |
{ |
4380 |
unsigned int index = symbol->symbol_info; |
int index = symbol->symbol_info; |
4381 |
for (section = abfd->sections; section != NULL; section = section->next) |
for (section = abfd->sections; section != NULL; section = section->next) |
4382 |
if (section->target_index == index && som_is_subspace (section)) |
if (section->target_index == index && som_is_subspace (section)) |
4383 |
return section; |
return section; |
4396 |
for (section = abfd->sections; section; section = section->next) |
for (section = abfd->sections; section; section = section->next) |
4397 |
{ |
{ |
4398 |
if (value >= section->vma |
if (value >= section->vma |
4399 |
&& value <= section->vma + section->_cooked_size |
&& value <= section->vma + section->size |
4400 |
&& som_is_subspace (section)) |
&& som_is_subspace (section)) |
4401 |
return section; |
return section; |
4402 |
} |
} |
4543 |
sym->symbol.value -= sym->symbol.section->vma; |
sym->symbol.value -= sym->symbol.section->vma; |
4544 |
break; |
break; |
4545 |
|
|
|
#if 0 |
|
|
/* SS_GLOBAL and SS_LOCAL are two names for the same thing. |
|
|
Sound dumb? It is. */ |
|
|
case SS_GLOBAL: |
|
|
#endif |
|
4546 |
case SS_LOCAL: |
case SS_LOCAL: |
4547 |
sym->symbol.flags |= BSF_LOCAL; |
sym->symbol.flags |= BSF_LOCAL; |
4548 |
sym->symbol.section = bfd_section_from_som_symbol (abfd, bufp); |
sym->symbol.section = bfd_section_from_som_symbol (abfd, bufp); |
4569 |
sym->symbol.flags |= BSF_DEBUGGING; |
sym->symbol.flags |= BSF_DEBUGGING; |
4570 |
|
|
4571 |
/* Note increment at bottom of loop, since we skip some symbols |
/* Note increment at bottom of loop, since we skip some symbols |
4572 |
we can not include it as part of the for statement. */ |
we can not include it as part of the for statement. */ |
4573 |
sym++; |
sym++; |
4574 |
} |
} |
4575 |
|
|
4582 |
successful_return: |
successful_return: |
4583 |
if (buf != NULL) |
if (buf != NULL) |
4584 |
free (buf); |
free (buf); |
4585 |
return (true); |
return (TRUE); |
4586 |
|
|
4587 |
error_return: |
error_return: |
4588 |
if (buf != NULL) |
if (buf != NULL) |
4589 |
free (buf); |
free (buf); |
4590 |
return false; |
return FALSE; |
4591 |
} |
} |
4592 |
|
|
4593 |
/* Canonicalize a SOM symbol table. Return the number of entries |
/* Canonicalize a SOM symbol table. Return the number of entries |
4594 |
in the symbol table. */ |
in the symbol table. */ |
4595 |
|
|
4596 |
static long |
static long |
4597 |
som_get_symtab (abfd, location) |
som_canonicalize_symtab (abfd, location) |
4598 |
bfd *abfd; |
bfd *abfd; |
4599 |
asymbol **location; |
asymbol **location; |
4600 |
{ |
{ |
4661 |
} |
} |
4662 |
} |
} |
4663 |
|
|
4664 |
static boolean |
static bfd_boolean |
4665 |
som_bfd_is_local_label_name (abfd, name) |
som_bfd_is_local_label_name (abfd, name) |
4666 |
bfd *abfd ATTRIBUTE_UNUSED; |
bfd *abfd ATTRIBUTE_UNUSED; |
4667 |
const char *name; |
const char *name; |
4689 |
arelent *internal_relocs; |
arelent *internal_relocs; |
4690 |
asection *section; |
asection *section; |
4691 |
asymbol **symbols; |
asymbol **symbols; |
4692 |
boolean just_count; |
bfd_boolean just_count; |
4693 |
{ |
{ |
4694 |
unsigned int op, varname, deallocate_contents = 0; |
unsigned int op, varname, deallocate_contents = 0; |
4695 |
unsigned char *end_fixups = &fixup[end]; |
unsigned char *end_fixups = &fixup[end]; |
4979 |
if (rptr->addend == 0 && !section->contents) |
if (rptr->addend == 0 && !section->contents) |
4980 |
{ |
{ |
4981 |
/* Got to read the damn contents first. We don't |
/* Got to read the damn contents first. We don't |
4982 |
bother saving the contents (yet). Add it one |
bother saving the contents (yet). Add it one |
4983 |
day if the need arises. */ |
day if the need arises. */ |
4984 |
section->contents = bfd_malloc (section->_raw_size); |
bfd_byte *contents; |
4985 |
if (section->contents == NULL) |
if (!bfd_malloc_and_get_section (section->owner, section, |
4986 |
return (unsigned) -1; |
&contents)) |
4987 |
|
{ |
4988 |
|
if (contents != NULL) |
4989 |
|
free (contents); |
4990 |
|
return (unsigned) -1; |
4991 |
|
} |
4992 |
|
section->contents = contents; |
4993 |
deallocate_contents = 1; |
deallocate_contents = 1; |
|
bfd_get_section_contents (section->owner, |
|
|
section, |
|
|
section->contents, |
|
|
(bfd_vma) 0, |
|
|
section->_raw_size); |
|
4994 |
} |
} |
4995 |
else if (rptr->addend == 0) |
else if (rptr->addend == 0) |
4996 |
rptr->addend = bfd_get_32 (section->owner, |
rptr->addend = bfd_get_32 (section->owner, |
5023 |
/* Read in the relocs (aka fixups in SOM terms) for a section. |
/* Read in the relocs (aka fixups in SOM terms) for a section. |
5024 |
|
|
5025 |
som_get_reloc_upper_bound calls this routine with JUST_COUNT |
som_get_reloc_upper_bound calls this routine with JUST_COUNT |
5026 |
set to true to indicate it only needs a count of the number |
set to TRUE to indicate it only needs a count of the number |
5027 |
of actual relocations. */ |
of actual relocations. */ |
5028 |
|
|
5029 |
static boolean |
static bfd_boolean |
5030 |
som_slurp_reloc_table (abfd, section, symbols, just_count) |
som_slurp_reloc_table (abfd, section, symbols, just_count) |
5031 |
bfd *abfd; |
bfd *abfd; |
5032 |
asection *section; |
asection *section; |
5033 |
asymbol **symbols; |
asymbol **symbols; |
5034 |
boolean just_count; |
bfd_boolean just_count; |
5035 |
{ |
{ |
5036 |
char *external_relocs; |
char *external_relocs; |
5037 |
unsigned int fixup_stream_size; |
unsigned int fixup_stream_size; |
5042 |
fixup_stream_size = som_section_data (section)->reloc_size; |
fixup_stream_size = som_section_data (section)->reloc_size; |
5043 |
/* If there were no relocations, then there is nothing to do. */ |
/* If there were no relocations, then there is nothing to do. */ |
5044 |
if (section->reloc_count == 0) |
if (section->reloc_count == 0) |
5045 |
return true; |
return TRUE; |
5046 |
|
|
5047 |
/* If reloc_count is -1, then the relocation stream has not been |
/* If reloc_count is -1, then the relocation stream has not been |
5048 |
parsed. We must do so now to know how many relocations exist. */ |
parsed. We must do so now to know how many relocations exist. */ |
5051 |
amt = fixup_stream_size; |
amt = fixup_stream_size; |
5052 |
external_relocs = (char *) bfd_malloc (amt); |
external_relocs = (char *) bfd_malloc (amt); |
5053 |
if (external_relocs == (char *) NULL) |
if (external_relocs == (char *) NULL) |
5054 |
return false; |
return FALSE; |
5055 |
/* Read in the external forms. */ |
/* Read in the external forms. */ |
5056 |
if (bfd_seek (abfd, |
if (bfd_seek (abfd, |
5057 |
obj_som_reloc_filepos (abfd) + section->rel_filepos, |
obj_som_reloc_filepos (abfd) + section->rel_filepos, |
5058 |
SEEK_SET) |
SEEK_SET) |
5059 |
!= 0) |
!= 0) |
5060 |
return false; |
return FALSE; |
5061 |
if (bfd_bread (external_relocs, amt, abfd) != amt) |
if (bfd_bread (external_relocs, amt, abfd) != amt) |
5062 |
return false; |
return FALSE; |
5063 |
|
|
5064 |
/* Let callers know how many relocations found. |
/* Let callers know how many relocations found. |
5065 |
also save the relocation stream as we will |
also save the relocation stream as we will |
5066 |
need it again. */ |
need it again. */ |
5067 |
section->reloc_count = som_set_reloc_info (external_relocs, |
section->reloc_count = som_set_reloc_info (external_relocs, |
5068 |
fixup_stream_size, |
fixup_stream_size, |
5069 |
NULL, NULL, NULL, true); |
NULL, NULL, NULL, TRUE); |
5070 |
|
|
5071 |
som_section_data (section)->reloc_stream = external_relocs; |
som_section_data (section)->reloc_stream = external_relocs; |
5072 |
} |
} |
5073 |
|
|
5074 |
/* If the caller only wanted a count, then return now. */ |
/* If the caller only wanted a count, then return now. */ |
5075 |
if (just_count) |
if (just_count) |
5076 |
return true; |
return TRUE; |
5077 |
|
|
5078 |
num_relocs = section->reloc_count; |
num_relocs = section->reloc_count; |
5079 |
external_relocs = som_section_data (section)->reloc_stream; |
external_relocs = som_section_data (section)->reloc_stream; |
5080 |
/* Return saved information about the relocations if it is available. */ |
/* Return saved information about the relocations if it is available. */ |
5081 |
if (section->relocation != (arelent *) NULL) |
if (section->relocation != (arelent *) NULL) |
5082 |
return true; |
return TRUE; |
5083 |
|
|
5084 |
amt = num_relocs; |
amt = num_relocs; |
5085 |
amt *= sizeof (arelent); |
amt *= sizeof (arelent); |
5086 |
internal_relocs = (arelent *) bfd_zalloc (abfd, (amt)); |
internal_relocs = (arelent *) bfd_zalloc (abfd, (amt)); |
5087 |
if (internal_relocs == (arelent *) NULL) |
if (internal_relocs == (arelent *) NULL) |
5088 |
return false; |
return FALSE; |
5089 |
|
|
5090 |
/* Process and internalize the relocations. */ |
/* Process and internalize the relocations. */ |
5091 |
som_set_reloc_info (external_relocs, fixup_stream_size, |
som_set_reloc_info (external_relocs, fixup_stream_size, |
5092 |
internal_relocs, section, symbols, false); |
internal_relocs, section, symbols, FALSE); |
5093 |
|
|
5094 |
/* We're done with the external relocations. Free them. */ |
/* We're done with the external relocations. Free them. */ |
5095 |
free (external_relocs); |
free (external_relocs); |
5097 |
|
|
5098 |
/* Save our results and return success. */ |
/* Save our results and return success. */ |
5099 |
section->relocation = internal_relocs; |
section->relocation = internal_relocs; |
5100 |
return (true); |
return TRUE; |
5101 |
} |
} |
5102 |
|
|
5103 |
/* Return the number of bytes required to store the relocation |
/* Return the number of bytes required to store the relocation |
5112 |
and parse it to determine how many relocations exist. */ |
and parse it to determine how many relocations exist. */ |
5113 |
if (asect->flags & SEC_RELOC) |
if (asect->flags & SEC_RELOC) |
5114 |
{ |
{ |
5115 |
if (! som_slurp_reloc_table (abfd, asect, NULL, true)) |
if (! som_slurp_reloc_table (abfd, asect, NULL, TRUE)) |
5116 |
return -1; |
return -1; |
5117 |
return (asect->reloc_count + 1) * sizeof (arelent *); |
return (asect->reloc_count + 1) * sizeof (arelent *); |
5118 |
} |
} |
5133 |
arelent *tblptr; |
arelent *tblptr; |
5134 |
int count; |
int count; |
5135 |
|
|
5136 |
if (! som_slurp_reloc_table (abfd, section, symbols, false)) |
if (! som_slurp_reloc_table (abfd, section, symbols, FALSE)) |
5137 |
return -1; |
return -1; |
5138 |
|
|
5139 |
count = section->reloc_count; |
count = section->reloc_count; |
5150 |
|
|
5151 |
/* A hook to set up object file dependent section information. */ |
/* A hook to set up object file dependent section information. */ |
5152 |
|
|
5153 |
static boolean |
static bfd_boolean |
5154 |
som_new_section_hook (abfd, newsect) |
som_new_section_hook (abfd, newsect) |
5155 |
bfd *abfd; |
bfd *abfd; |
5156 |
asection *newsect; |
asection *newsect; |
5158 |
bfd_size_type amt = sizeof (struct som_section_data_struct); |
bfd_size_type amt = sizeof (struct som_section_data_struct); |
5159 |
newsect->used_by_bfd = (PTR) bfd_zalloc (abfd, amt); |
newsect->used_by_bfd = (PTR) bfd_zalloc (abfd, amt); |
5160 |
if (!newsect->used_by_bfd) |
if (!newsect->used_by_bfd) |
5161 |
return false; |
return FALSE; |
5162 |
newsect->alignment_power = 3; |
newsect->alignment_power = 3; |
5163 |
|
|
5164 |
/* We allow more than three sections internally. */ |
/* We allow more than three sections internally. */ |
5165 |
return true; |
return TRUE; |
5166 |
} |
} |
5167 |
|
|
5168 |
/* Copy any private info we understand from the input symbol |
/* Copy any private info we understand from the input symbol |
5169 |
to the output symbol. */ |
to the output symbol. */ |
5170 |
|
|
5171 |
static boolean |
static bfd_boolean |
5172 |
som_bfd_copy_private_symbol_data (ibfd, isymbol, obfd, osymbol) |
som_bfd_copy_private_symbol_data (ibfd, isymbol, obfd, osymbol) |
5173 |
bfd *ibfd; |
bfd *ibfd; |
5174 |
asymbol *isymbol; |
asymbol *isymbol; |
5181 |
/* One day we may try to grok other private data. */ |
/* One day we may try to grok other private data. */ |
5182 |
if (ibfd->xvec->flavour != bfd_target_som_flavour |
if (ibfd->xvec->flavour != bfd_target_som_flavour |
5183 |
|| obfd->xvec->flavour != bfd_target_som_flavour) |
|| obfd->xvec->flavour != bfd_target_som_flavour) |
5184 |
return false; |
return FALSE; |
5185 |
|
|
5186 |
/* The only private information we need to copy is the argument relocation |
/* The only private information we need to copy is the argument relocation |
5187 |
bits. */ |
bits. */ |
5188 |
output_symbol->tc_data.ap.hppa_arg_reloc = |
output_symbol->tc_data.ap.hppa_arg_reloc = |
5189 |
input_symbol->tc_data.ap.hppa_arg_reloc; |
input_symbol->tc_data.ap.hppa_arg_reloc; |
5190 |
|
|
5191 |
return true; |
return TRUE; |
5192 |
} |
} |
5193 |
|
|
5194 |
/* Copy any private info we understand from the input section |
/* Copy any private info we understand from the input section |
5195 |
to the output section. */ |
to the output section. */ |
5196 |
|
|
5197 |
static boolean |
static bfd_boolean |
5198 |
som_bfd_copy_private_section_data (ibfd, isection, obfd, osection) |
som_bfd_copy_private_section_data (ibfd, isection, obfd, osection) |
5199 |
bfd *ibfd; |
bfd *ibfd; |
5200 |
asection *isection; |
asection *isection; |
5207 |
if (ibfd->xvec->flavour != bfd_target_som_flavour |
if (ibfd->xvec->flavour != bfd_target_som_flavour |
5208 |
|| obfd->xvec->flavour != bfd_target_som_flavour |
|| obfd->xvec->flavour != bfd_target_som_flavour |
5209 |
|| (!som_is_space (isection) && !som_is_subspace (isection))) |
|| (!som_is_space (isection) && !som_is_subspace (isection))) |
5210 |
return true; |
return TRUE; |
5211 |
|
|
5212 |
amt = sizeof (struct som_copyable_section_data_struct); |
amt = sizeof (struct som_copyable_section_data_struct); |
5213 |
som_section_data (osection)->copy_data = |
som_section_data (osection)->copy_data = |
5214 |
(struct som_copyable_section_data_struct *) bfd_zalloc (obfd, amt); |
(struct som_copyable_section_data_struct *) bfd_zalloc (obfd, amt); |
5215 |
if (som_section_data (osection)->copy_data == NULL) |
if (som_section_data (osection)->copy_data == NULL) |
5216 |
return false; |
return FALSE; |
5217 |
|
|
5218 |
memcpy (som_section_data (osection)->copy_data, |
memcpy (som_section_data (osection)->copy_data, |
5219 |
som_section_data (isection)->copy_data, |
som_section_data (isection)->copy_data, |
5224 |
som_section_data (osection)->copy_data->container = |
som_section_data (osection)->copy_data->container = |
5225 |
som_section_data (osection)->copy_data->container->output_section; |
som_section_data (osection)->copy_data->container->output_section; |
5226 |
|
|
5227 |
return true; |
return TRUE; |
5228 |
} |
} |
5229 |
|
|
5230 |
/* Copy any private info we understand from the input bfd |
/* Copy any private info we understand from the input bfd |
5231 |
to the output bfd. */ |
to the output bfd. */ |
5232 |
|
|
5233 |
static boolean |
static bfd_boolean |
5234 |
som_bfd_copy_private_bfd_data (ibfd, obfd) |
som_bfd_copy_private_bfd_data (ibfd, obfd) |
5235 |
bfd *ibfd, *obfd; |
bfd *ibfd, *obfd; |
5236 |
{ |
{ |
5237 |
/* One day we may try to grok other private data. */ |
/* One day we may try to grok other private data. */ |
5238 |
if (ibfd->xvec->flavour != bfd_target_som_flavour |
if (ibfd->xvec->flavour != bfd_target_som_flavour |
5239 |
|| obfd->xvec->flavour != bfd_target_som_flavour) |
|| obfd->xvec->flavour != bfd_target_som_flavour) |
5240 |
return true; |
return TRUE; |
5241 |
|
|
5242 |
/* Allocate some memory to hold the data we need. */ |
/* Allocate some memory to hold the data we need. */ |
5243 |
obj_som_exec_data (obfd) = (struct som_exec_data *) |
obj_som_exec_data (obfd) = (struct som_exec_data *) |
5244 |
bfd_zalloc (obfd, (bfd_size_type) sizeof (struct som_exec_data)); |
bfd_zalloc (obfd, (bfd_size_type) sizeof (struct som_exec_data)); |
5245 |
if (obj_som_exec_data (obfd) == NULL) |
if (obj_som_exec_data (obfd) == NULL) |
5246 |
return false; |
return FALSE; |
5247 |
|
|
5248 |
/* Now copy the data. */ |
/* Now copy the data. */ |
5249 |
memcpy (obj_som_exec_data (obfd), obj_som_exec_data (ibfd), |
memcpy (obj_som_exec_data (obfd), obj_som_exec_data (ibfd), |
5250 |
sizeof (struct som_exec_data)); |
sizeof (struct som_exec_data)); |
5251 |
|
|
5252 |
return true; |
return TRUE; |
5253 |
|
} |
5254 |
|
|
5255 |
|
/* Display the SOM header. */ |
5256 |
|
|
5257 |
|
static bfd_boolean |
5258 |
|
som_bfd_print_private_bfd_data (bfd *abfd, void *farg) |
5259 |
|
{ |
5260 |
|
struct som_exec_auxhdr *exec_header; |
5261 |
|
struct aux_id* auxhdr; |
5262 |
|
FILE *f; |
5263 |
|
|
5264 |
|
f = (FILE *) farg; |
5265 |
|
|
5266 |
|
exec_header = obj_som_exec_hdr (abfd); |
5267 |
|
if (exec_header) |
5268 |
|
{ |
5269 |
|
fprintf (f, _("\nExec Auxiliary Header\n")); |
5270 |
|
fprintf (f, " flags "); |
5271 |
|
auxhdr = &exec_header->som_auxhdr; |
5272 |
|
if (auxhdr->mandatory) |
5273 |
|
fprintf (f, "mandatory "); |
5274 |
|
if (auxhdr->copy) |
5275 |
|
fprintf (f, "copy "); |
5276 |
|
if (auxhdr->append) |
5277 |
|
fprintf (f, "append "); |
5278 |
|
if (auxhdr->ignore) |
5279 |
|
fprintf (f, "ignore "); |
5280 |
|
fprintf (f, "\n"); |
5281 |
|
fprintf (f, " type %#x\n", auxhdr->type); |
5282 |
|
fprintf (f, " length %#x\n", auxhdr->length); |
5283 |
|
fprintf (f, " text size %#x\n", exec_header->exec_tsize); |
5284 |
|
fprintf (f, " text memory offset %#x\n", exec_header->exec_tmem); |
5285 |
|
fprintf (f, " text file offset %#x\n", exec_header->exec_tfile); |
5286 |
|
fprintf (f, " data size %#x\n", exec_header->exec_dsize); |
5287 |
|
fprintf (f, " data memory offset %#x\n", exec_header->exec_dmem); |
5288 |
|
fprintf (f, " data file offset %#x\n", exec_header->exec_dfile); |
5289 |
|
fprintf (f, " bss size %#x\n", exec_header->exec_bsize); |
5290 |
|
fprintf (f, " entry point %#x\n", exec_header->exec_entry); |
5291 |
|
fprintf (f, " loader flags %#x\n", exec_header->exec_flags); |
5292 |
|
fprintf (f, " bss initializer %#x\n", exec_header->exec_bfill); |
5293 |
|
} |
5294 |
|
|
5295 |
|
return TRUE; |
5296 |
} |
} |
5297 |
|
|
5298 |
/* Set backend info for sections which can not be described |
/* Set backend info for sections which can not be described |
5299 |
in the BFD data structures. */ |
in the BFD data structures. */ |
5300 |
|
|
5301 |
boolean |
bfd_boolean |
5302 |
bfd_som_set_section_attributes (section, defined, private, sort_key, spnum) |
bfd_som_set_section_attributes (section, defined, private, sort_key, spnum) |
5303 |
asection *section; |
asection *section; |
5304 |
int defined; |
int defined; |
5314 |
(struct som_copyable_section_data_struct *) bfd_zalloc (section->owner, |
(struct som_copyable_section_data_struct *) bfd_zalloc (section->owner, |
5315 |
amt); |
amt); |
5316 |
if (som_section_data (section)->copy_data == NULL) |
if (som_section_data (section)->copy_data == NULL) |
5317 |
return false; |
return FALSE; |
5318 |
} |
} |
5319 |
som_section_data (section)->copy_data->sort_key = sort_key; |
som_section_data (section)->copy_data->sort_key = sort_key; |
5320 |
som_section_data (section)->copy_data->is_defined = defined; |
som_section_data (section)->copy_data->is_defined = defined; |
5321 |
som_section_data (section)->copy_data->is_private = private; |
som_section_data (section)->copy_data->is_private = private; |
5322 |
som_section_data (section)->copy_data->container = section; |
som_section_data (section)->copy_data->container = section; |
5323 |
som_section_data (section)->copy_data->space_number = spnum; |
som_section_data (section)->copy_data->space_number = spnum; |
5324 |
return true; |
return TRUE; |
5325 |
} |
} |
5326 |
|
|
5327 |
/* Set backend info for subsections which can not be described |
/* Set backend info for subsections which can not be described |
5328 |
in the BFD data structures. */ |
in the BFD data structures. */ |
5329 |
|
|
5330 |
boolean |
bfd_boolean |
5331 |
bfd_som_set_subsection_attributes (section, container, access, |
bfd_som_set_subsection_attributes (section, container, access, |
5332 |
sort_key, quadrant) |
sort_key, quadrant, comdat, |
5333 |
|
common, dup_common) |
5334 |
asection *section; |
asection *section; |
5335 |
asection *container; |
asection *container; |
5336 |
int access; |
int access; |
5337 |
unsigned int sort_key; |
unsigned int sort_key; |
5338 |
int quadrant; |
int quadrant, comdat, common, dup_common; |
5339 |
{ |
{ |
5340 |
/* Allocate memory to hold the magic information. */ |
/* Allocate memory to hold the magic information. */ |
5341 |
if (som_section_data (section)->copy_data == NULL) |
if (som_section_data (section)->copy_data == NULL) |
5345 |
(struct som_copyable_section_data_struct *) bfd_zalloc (section->owner, |
(struct som_copyable_section_data_struct *) bfd_zalloc (section->owner, |
5346 |
amt); |
amt); |
5347 |
if (som_section_data (section)->copy_data == NULL) |
if (som_section_data (section)->copy_data == NULL) |
5348 |
return false; |
return FALSE; |
5349 |
} |
} |
5350 |
som_section_data (section)->copy_data->sort_key = sort_key; |
som_section_data (section)->copy_data->sort_key = sort_key; |
5351 |
som_section_data (section)->copy_data->access_control_bits = access; |
som_section_data (section)->copy_data->access_control_bits = access; |
5352 |
som_section_data (section)->copy_data->quadrant = quadrant; |
som_section_data (section)->copy_data->quadrant = quadrant; |
5353 |
som_section_data (section)->copy_data->container = container; |
som_section_data (section)->copy_data->container = container; |
5354 |
return true; |
som_section_data (section)->copy_data->is_comdat = comdat; |
5355 |
|
som_section_data (section)->copy_data->is_common = common; |
5356 |
|
som_section_data (section)->copy_data->dup_common = dup_common; |
5357 |
|
return TRUE; |
5358 |
} |
} |
5359 |
|
|
5360 |
/* Set the full SOM symbol type. SOM needs far more symbol information |
/* Set the full SOM symbol type. SOM needs far more symbol information |
5374 |
/* Attach an auxiliary header to the BFD backend so that it may be |
/* Attach an auxiliary header to the BFD backend so that it may be |
5375 |
written into the object file. */ |
written into the object file. */ |
5376 |
|
|
5377 |
boolean |
bfd_boolean |
5378 |
bfd_som_attach_aux_hdr (abfd, type, string) |
bfd_som_attach_aux_hdr (abfd, type, string) |
5379 |
bfd *abfd; |
bfd *abfd; |
5380 |
int type; |
int type; |
5393 |
obj_som_version_hdr (abfd) = |
obj_som_version_hdr (abfd) = |
5394 |
(struct user_string_aux_hdr *) bfd_zalloc (abfd, amt); |
(struct user_string_aux_hdr *) bfd_zalloc (abfd, amt); |
5395 |
if (!obj_som_version_hdr (abfd)) |
if (!obj_som_version_hdr (abfd)) |
5396 |
return false; |
return FALSE; |
5397 |
obj_som_version_hdr (abfd)->header_id.type = VERSION_AUX_ID; |
obj_som_version_hdr (abfd)->header_id.type = VERSION_AUX_ID; |
5398 |
obj_som_version_hdr (abfd)->header_id.length = len + pad; |
obj_som_version_hdr (abfd)->header_id.length = len + pad; |
5399 |
obj_som_version_hdr (abfd)->header_id.length += sizeof (int); |
obj_som_version_hdr (abfd)->header_id.length += sizeof (int); |
5411 |
obj_som_copyright_hdr (abfd) = |
obj_som_copyright_hdr (abfd) = |
5412 |
(struct copyright_aux_hdr *) bfd_zalloc (abfd, amt); |
(struct copyright_aux_hdr *) bfd_zalloc (abfd, amt); |
5413 |
if (!obj_som_copyright_hdr (abfd)) |
if (!obj_som_copyright_hdr (abfd)) |
5414 |
return false; |
return FALSE; |
5415 |
obj_som_copyright_hdr (abfd)->header_id.type = COPYRIGHT_AUX_ID; |
obj_som_copyright_hdr (abfd)->header_id.type = COPYRIGHT_AUX_ID; |
5416 |
obj_som_copyright_hdr (abfd)->header_id.length = len + pad; |
obj_som_copyright_hdr (abfd)->header_id.length = len + pad; |
5417 |
obj_som_copyright_hdr (abfd)->header_id.length += sizeof (int); |
obj_som_copyright_hdr (abfd)->header_id.length += sizeof (int); |
5418 |
obj_som_copyright_hdr (abfd)->string_length = len; |
obj_som_copyright_hdr (abfd)->string_length = len; |
5419 |
strcpy (obj_som_copyright_hdr (abfd)->copyright, string); |
strcpy (obj_som_copyright_hdr (abfd)->copyright, string); |
5420 |
} |
} |
5421 |
return true; |
return TRUE; |
5422 |
} |
} |
5423 |
|
|
5424 |
/* Attach an compilation unit header to the BFD backend so that it may be |
/* Attach a compilation unit header to the BFD backend so that it may be |
5425 |
written into the object file. */ |
written into the object file. */ |
5426 |
|
|
5427 |
boolean |
bfd_boolean |
5428 |
bfd_som_attach_compilation_unit (abfd, name, language_name, product_id, |
bfd_som_attach_compilation_unit (abfd, name, language_name, product_id, |
5429 |
version_id) |
version_id) |
5430 |
bfd *abfd; |
bfd *abfd; |
5435 |
{ |
{ |
5436 |
COMPUNIT *n = (COMPUNIT *) bfd_zalloc (abfd, (bfd_size_type) COMPUNITSZ); |
COMPUNIT *n = (COMPUNIT *) bfd_zalloc (abfd, (bfd_size_type) COMPUNITSZ); |
5437 |
if (n == NULL) |
if (n == NULL) |
5438 |
return false; |
return FALSE; |
5439 |
|
|
5440 |
#define STRDUP(f) \ |
#define STRDUP(f) \ |
5441 |
if (f != NULL) \ |
if (f != NULL) \ |
5442 |
{ \ |
{ \ |
5443 |
n->f.n_name = bfd_alloc (abfd, (bfd_size_type) strlen (f) + 1); \ |
n->f.n_name = bfd_alloc (abfd, (bfd_size_type) strlen (f) + 1); \ |
5444 |
if (n->f.n_name == NULL) \ |
if (n->f.n_name == NULL) \ |
5445 |
return false; \ |
return FALSE; \ |
5446 |
strcpy (n->f.n_name, f); \ |
strcpy (n->f.n_name, f); \ |
5447 |
} |
} |
5448 |
|
|
5455 |
|
|
5456 |
obj_som_compilation_unit (abfd) = n; |
obj_som_compilation_unit (abfd) = n; |
5457 |
|
|
5458 |
return true; |
return TRUE; |
5459 |
} |
} |
5460 |
|
|
5461 |
static boolean |
static bfd_boolean |
5462 |
som_get_section_contents (abfd, section, location, offset, count) |
som_get_section_contents (abfd, section, location, offset, count) |
5463 |
bfd *abfd; |
bfd *abfd; |
5464 |
sec_ptr section; |
sec_ptr section; |
5467 |
bfd_size_type count; |
bfd_size_type count; |
5468 |
{ |
{ |
5469 |
if (count == 0 || ((section->flags & SEC_HAS_CONTENTS) == 0)) |
if (count == 0 || ((section->flags & SEC_HAS_CONTENTS) == 0)) |
5470 |
return true; |
return TRUE; |
5471 |
if ((bfd_size_type) (offset+count) > section->_raw_size |
if ((bfd_size_type) (offset+count) > section->size |
5472 |
|| bfd_seek (abfd, (file_ptr) (section->filepos + offset), SEEK_SET) != 0 |
|| bfd_seek (abfd, (file_ptr) (section->filepos + offset), SEEK_SET) != 0 |
5473 |
|| bfd_bread (location, count, abfd) != count) |
|| bfd_bread (location, count, abfd) != count) |
5474 |
return (false); /* on error */ |
return FALSE; /* On error. */ |
5475 |
return (true); |
return TRUE; |
5476 |
} |
} |
5477 |
|
|
5478 |
static boolean |
static bfd_boolean |
5479 |
som_set_section_contents (abfd, section, location, offset, count) |
som_set_section_contents (abfd, section, location, offset, count) |
5480 |
bfd *abfd; |
bfd *abfd; |
5481 |
sec_ptr section; |
sec_ptr section; |
5482 |
PTR location; |
const PTR location; |
5483 |
file_ptr offset; |
file_ptr offset; |
5484 |
bfd_size_type count; |
bfd_size_type count; |
5485 |
{ |
{ |
5488 |
/* Set up fixed parts of the file, space, and subspace headers. |
/* Set up fixed parts of the file, space, and subspace headers. |
5489 |
Notify the world that output has begun. */ |
Notify the world that output has begun. */ |
5490 |
som_prep_headers (abfd); |
som_prep_headers (abfd); |
5491 |
abfd->output_has_begun = true; |
abfd->output_has_begun = TRUE; |
5492 |
/* Start writing the object file. This include all the string |
/* Start writing the object file. This include all the string |
5493 |
tables, fixup streams, and other portions of the object file. */ |
tables, fixup streams, and other portions of the object file. */ |
5494 |
som_begin_writing (abfd); |
som_begin_writing (abfd); |
5498 |
are not generated at run time by the OS). */ |
are not generated at run time by the OS). */ |
5499 |
if (!som_is_subspace (section) |
if (!som_is_subspace (section) |
5500 |
|| ((section->flags & SEC_HAS_CONTENTS) == 0)) |
|| ((section->flags & SEC_HAS_CONTENTS) == 0)) |
5501 |
return true; |
return TRUE; |
5502 |
|
|
5503 |
/* Seek to the proper offset within the object file and write the |
/* Seek to the proper offset within the object file and write the |
5504 |
data. */ |
data. */ |
5505 |
offset += som_section_data (section)->subspace_dict->file_loc_init_value; |
offset += som_section_data (section)->subspace_dict->file_loc_init_value; |
5506 |
if (bfd_seek (abfd, offset, SEEK_SET) != 0) |
if (bfd_seek (abfd, offset, SEEK_SET) != 0) |
5507 |
return false; |
return FALSE; |
5508 |
|
|
5509 |
if (bfd_bwrite ((PTR) location, count, abfd) != count) |
if (bfd_bwrite (location, count, abfd) != count) |
5510 |
return false; |
return FALSE; |
5511 |
return true; |
return TRUE; |
5512 |
} |
} |
5513 |
|
|
5514 |
static boolean |
static bfd_boolean |
5515 |
som_set_arch_mach (abfd, arch, machine) |
som_set_arch_mach (abfd, arch, machine) |
5516 |
bfd *abfd; |
bfd *abfd; |
5517 |
enum bfd_architecture arch; |
enum bfd_architecture arch; |
5521 |
return bfd_default_set_arch_mach (abfd, arch, machine); |
return bfd_default_set_arch_mach (abfd, arch, machine); |
5522 |
} |
} |
5523 |
|
|
5524 |
static boolean |
static bfd_boolean |
5525 |
som_find_nearest_line (abfd, section, symbols, offset, filename_ptr, |
som_find_nearest_line (abfd, section, symbols, offset, filename_ptr, |
5526 |
functionname_ptr, line_ptr) |
functionname_ptr, line_ptr) |
5527 |
bfd *abfd ATTRIBUTE_UNUSED; |
bfd *abfd ATTRIBUTE_UNUSED; |
5532 |
const char **functionname_ptr ATTRIBUTE_UNUSED; |
const char **functionname_ptr ATTRIBUTE_UNUSED; |
5533 |
unsigned int *line_ptr ATTRIBUTE_UNUSED; |
unsigned int *line_ptr ATTRIBUTE_UNUSED; |
5534 |
{ |
{ |
5535 |
return (false); |
return FALSE; |
5536 |
} |
} |
5537 |
|
|
5538 |
static int |
static int |
5539 |
som_sizeof_headers (abfd, reloc) |
som_sizeof_headers (abfd, reloc) |
5540 |
bfd *abfd ATTRIBUTE_UNUSED; |
bfd *abfd ATTRIBUTE_UNUSED; |
5541 |
boolean reloc ATTRIBUTE_UNUSED; |
bfd_boolean reloc ATTRIBUTE_UNUSED; |
5542 |
{ |
{ |
5543 |
(*_bfd_error_handler) (_("som_sizeof_headers unimplemented")); |
(*_bfd_error_handler) (_("som_sizeof_headers unimplemented")); |
5544 |
fflush (stderr); |
fflush (stderr); |
5545 |
abort (); |
abort (); |
5546 |
return (0); |
return 0; |
5547 |
} |
} |
5548 |
|
|
5549 |
/* Return the single-character symbol type corresponding to |
/* Return the single-character symbol type corresponding to |
5610 |
/* Count the number of symbols in the archive symbol table. Necessary |
/* Count the number of symbols in the archive symbol table. Necessary |
5611 |
so that we can allocate space for all the carsyms at once. */ |
so that we can allocate space for all the carsyms at once. */ |
5612 |
|
|
5613 |
static boolean |
static bfd_boolean |
5614 |
som_bfd_count_ar_symbols (abfd, lst_header, count) |
som_bfd_count_ar_symbols (abfd, lst_header, count) |
5615 |
bfd *abfd; |
bfd *abfd; |
5616 |
struct lst_header *lst_header; |
struct lst_header *lst_header; |
5675 |
} |
} |
5676 |
if (hash_table != NULL) |
if (hash_table != NULL) |
5677 |
free (hash_table); |
free (hash_table); |
5678 |
return true; |
return TRUE; |
5679 |
|
|
5680 |
error_return: |
error_return: |
5681 |
if (hash_table != NULL) |
if (hash_table != NULL) |
5682 |
free (hash_table); |
free (hash_table); |
5683 |
return false; |
return FALSE; |
5684 |
} |
} |
5685 |
|
|
5686 |
/* Fill in the canonical archive symbols (SYMS) from the archive described |
/* Fill in the canonical archive symbols (SYMS) from the archive described |
5687 |
by ABFD and LST_HEADER. */ |
by ABFD and LST_HEADER. */ |
5688 |
|
|
5689 |
static boolean |
static bfd_boolean |
5690 |
som_bfd_fill_in_ar_symbols (abfd, lst_header, syms) |
som_bfd_fill_in_ar_symbols (abfd, lst_header, syms) |
5691 |
bfd *abfd; |
bfd *abfd; |
5692 |
struct lst_header *lst_header; |
struct lst_header *lst_header; |
5816 |
free (hash_table); |
free (hash_table); |
5817 |
if (som_dict != NULL) |
if (som_dict != NULL) |
5818 |
free (som_dict); |
free (som_dict); |
5819 |
return true; |
return TRUE; |
5820 |
|
|
5821 |
error_return: |
error_return: |
5822 |
if (hash_table != NULL) |
if (hash_table != NULL) |
5823 |
free (hash_table); |
free (hash_table); |
5824 |
if (som_dict != NULL) |
if (som_dict != NULL) |
5825 |
free (som_dict); |
free (som_dict); |
5826 |
return false; |
return FALSE; |
5827 |
} |
} |
5828 |
|
|
5829 |
/* Read in the LST from the archive. */ |
/* Read in the LST from the archive. */ |
5830 |
|
|
5831 |
static boolean |
static bfd_boolean |
5832 |
som_slurp_armap (abfd) |
som_slurp_armap (abfd) |
5833 |
bfd *abfd; |
bfd *abfd; |
5834 |
{ |
{ |
5842 |
|
|
5843 |
/* Special cases. */ |
/* Special cases. */ |
5844 |
if (i == 0) |
if (i == 0) |
5845 |
return true; |
return TRUE; |
5846 |
if (i != 16) |
if (i != 16) |
5847 |
return false; |
return FALSE; |
5848 |
|
|
5849 |
if (bfd_seek (abfd, (file_ptr) -16, SEEK_CUR) != 0) |
if (bfd_seek (abfd, (file_ptr) -16, SEEK_CUR) != 0) |
5850 |
return false; |
return FALSE; |
5851 |
|
|
5852 |
/* For archives without .o files there is no symbol table. */ |
/* For archives without .o files there is no symbol table. */ |
5853 |
if (strncmp (nextname, "/ ", 16)) |
if (strncmp (nextname, "/ ", 16)) |
5854 |
{ |
{ |
5855 |
bfd_has_map (abfd) = false; |
bfd_has_map (abfd) = FALSE; |
5856 |
return true; |
return TRUE; |
5857 |
} |
} |
5858 |
|
|
5859 |
/* Read in and sanity check the archive header. */ |
/* Read in and sanity check the archive header. */ |
5860 |
amt = sizeof (struct ar_hdr); |
amt = sizeof (struct ar_hdr); |
5861 |
if (bfd_bread ((PTR) &ar_header, amt, abfd) != amt) |
if (bfd_bread ((PTR) &ar_header, amt, abfd) != amt) |
5862 |
return false; |
return FALSE; |
5863 |
|
|
5864 |
if (strncmp (ar_header.ar_fmag, ARFMAG, 2)) |
if (strncmp (ar_header.ar_fmag, ARFMAG, 2)) |
5865 |
{ |
{ |
5866 |
bfd_set_error (bfd_error_malformed_archive); |
bfd_set_error (bfd_error_malformed_archive); |
5867 |
return false; |
return FALSE; |
5868 |
} |
} |
5869 |
|
|
5870 |
/* How big is the archive symbol table entry? */ |
/* How big is the archive symbol table entry? */ |
5873 |
if (errno != 0) |
if (errno != 0) |
5874 |
{ |
{ |
5875 |
bfd_set_error (bfd_error_malformed_archive); |
bfd_set_error (bfd_error_malformed_archive); |
5876 |
return false; |
return FALSE; |
5877 |
} |
} |
5878 |
|
|
5879 |
/* Save off the file offset of the first real user data. */ |
/* Save off the file offset of the first real user data. */ |
5883 |
in just a minute. */ |
in just a minute. */ |
5884 |
amt = sizeof (struct lst_header); |
amt = sizeof (struct lst_header); |
5885 |
if (bfd_bread ((PTR) &lst_header, amt, abfd) != amt) |
if (bfd_bread ((PTR) &lst_header, amt, abfd) != amt) |
5886 |
return false; |
return FALSE; |
5887 |
|
|
5888 |
/* Sanity check. */ |
/* Sanity check. */ |
5889 |
if (lst_header.a_magic != LIBMAGIC) |
if (lst_header.a_magic != LIBMAGIC) |
5890 |
{ |
{ |
5891 |
bfd_set_error (bfd_error_malformed_archive); |
bfd_set_error (bfd_error_malformed_archive); |
5892 |
return false; |
return FALSE; |
5893 |
} |
} |
5894 |
|
|
5895 |
/* Count the number of symbols in the library symbol table. */ |
/* Count the number of symbols in the library symbol table. */ |
5896 |
if (! som_bfd_count_ar_symbols (abfd, &lst_header, &ardata->symdef_count)) |
if (! som_bfd_count_ar_symbols (abfd, &lst_header, &ardata->symdef_count)) |
5897 |
return false; |
return FALSE; |
5898 |
|
|
5899 |
/* Get back to the start of the library symbol table. */ |
/* Get back to the start of the library symbol table. */ |
5900 |
if (bfd_seek (abfd, (ardata->first_file_filepos - parsed_size |
if (bfd_seek (abfd, (ardata->first_file_filepos - parsed_size |
5901 |
+ sizeof (struct lst_header)), SEEK_SET) != 0) |
+ sizeof (struct lst_header)), SEEK_SET) != 0) |
5902 |
return false; |
return FALSE; |
5903 |
|
|
5904 |
/* Initializae the cache and allocate space for the library symbols. */ |
/* Initialize the cache and allocate space for the library symbols. */ |
5905 |
ardata->cache = 0; |
ardata->cache = 0; |
5906 |
amt = ardata->symdef_count; |
amt = ardata->symdef_count; |
5907 |
amt *= sizeof (carsym); |
amt *= sizeof (carsym); |
5908 |
ardata->symdefs = (carsym *) bfd_alloc (abfd, amt); |
ardata->symdefs = (carsym *) bfd_alloc (abfd, amt); |
5909 |
if (!ardata->symdefs) |
if (!ardata->symdefs) |
5910 |
return false; |
return FALSE; |
5911 |
|
|
5912 |
/* Now fill in the canonical archive symbols. */ |
/* Now fill in the canonical archive symbols. */ |
5913 |
if (! som_bfd_fill_in_ar_symbols (abfd, &lst_header, &ardata->symdefs)) |
if (! som_bfd_fill_in_ar_symbols (abfd, &lst_header, &ardata->symdefs)) |
5914 |
return false; |
return FALSE; |
5915 |
|
|
5916 |
/* Seek back to the "first" file in the archive. Note the "first" |
/* Seek back to the "first" file in the archive. Note the "first" |
5917 |
file may be the extended name table. */ |
file may be the extended name table. */ |
5918 |
if (bfd_seek (abfd, ardata->first_file_filepos, SEEK_SET) != 0) |
if (bfd_seek (abfd, ardata->first_file_filepos, SEEK_SET) != 0) |
5919 |
return false; |
return FALSE; |
5920 |
|
|
5921 |
/* Notify the generic archive code that we have a symbol map. */ |
/* Notify the generic archive code that we have a symbol map. */ |
5922 |
bfd_has_map (abfd) = true; |
bfd_has_map (abfd) = TRUE; |
5923 |
return true; |
return TRUE; |
5924 |
} |
} |
5925 |
|
|
5926 |
/* Begin preparing to write a SOM library symbol table. |
/* Begin preparing to write a SOM library symbol table. |
5928 |
As part of the prep work we need to determine the number of symbols |
As part of the prep work we need to determine the number of symbols |
5929 |
and the size of the associated string section. */ |
and the size of the associated string section. */ |
5930 |
|
|
5931 |
static boolean |
static bfd_boolean |
5932 |
som_bfd_prep_for_ar_write (abfd, num_syms, stringsize) |
som_bfd_prep_for_ar_write (abfd, num_syms, stringsize) |
5933 |
bfd *abfd; |
bfd *abfd; |
5934 |
unsigned int *num_syms, *stringsize; |
unsigned int *num_syms, *stringsize; |
5957 |
to it. It's a little slimey to grab the symbols via obj_som_symtab, |
to it. It's a little slimey to grab the symbols via obj_som_symtab, |
5958 |
but doing so avoids allocating lots of extra memory. */ |
but doing so avoids allocating lots of extra memory. */ |
5959 |
if (! som_slurp_symbol_table (curr_bfd)) |
if (! som_slurp_symbol_table (curr_bfd)) |
5960 |
return false; |
return FALSE; |
5961 |
|
|
5962 |
sym = obj_som_symtab (curr_bfd); |
sym = obj_som_symtab (curr_bfd); |
5963 |
curr_count = bfd_get_symcount (curr_bfd); |
curr_count = bfd_get_symcount (curr_bfd); |
5996 |
|
|
5997 |
curr_bfd = curr_bfd->next; |
curr_bfd = curr_bfd->next; |
5998 |
} |
} |
5999 |
return true; |
return TRUE; |
6000 |
} |
} |
6001 |
|
|
6002 |
/* Hash a symbol name based on the hashing algorithm presented in the |
/* Hash a symbol name based on the hashing algorithm presented in the |
6019 |
/* Do the bulk of the work required to write the SOM library |
/* Do the bulk of the work required to write the SOM library |
6020 |
symbol table. */ |
symbol table. */ |
6021 |
|
|
6022 |
static boolean |
static bfd_boolean |
6023 |
som_bfd_ar_write_symbol_stuff (abfd, nsyms, string_size, lst, elength) |
som_bfd_ar_write_symbol_stuff (abfd, nsyms, string_size, lst, elength) |
6024 |
bfd *abfd; |
bfd *abfd; |
6025 |
unsigned int nsyms, string_size; |
unsigned int nsyms, string_size; |
6157 |
curr_lst_sym->initially_frozen = 0; |
curr_lst_sym->initially_frozen = 0; |
6158 |
curr_lst_sym->memory_resident = 0; |
curr_lst_sym->memory_resident = 0; |
6159 |
curr_lst_sym->is_common = bfd_is_com_section (sym->symbol.section); |
curr_lst_sym->is_common = bfd_is_com_section (sym->symbol.section); |
6160 |
curr_lst_sym->dup_common = 0; |
curr_lst_sym->dup_common = info.dup_common; |
6161 |
curr_lst_sym->xleast = 3; |
curr_lst_sym->xleast = 3; |
6162 |
curr_lst_sym->arg_reloc = info.arg_reloc; |
curr_lst_sym->arg_reloc = info.arg_reloc; |
6163 |
curr_lst_sym->name.n_strx = p - strings + 4; |
curr_lst_sym->name.n_strx = p - strings + 4; |
6256 |
free (lst_syms); |
free (lst_syms); |
6257 |
if (strings != NULL) |
if (strings != NULL) |
6258 |
free (strings); |
free (strings); |
6259 |
return true; |
return TRUE; |
6260 |
|
|
6261 |
error_return: |
error_return: |
6262 |
if (hash_table != NULL) |
if (hash_table != NULL) |
6270 |
if (strings != NULL) |
if (strings != NULL) |
6271 |
free (strings); |
free (strings); |
6272 |
|
|
6273 |
return false; |
return FALSE; |
6274 |
} |
} |
6275 |
|
|
6276 |
/* Write out the LST for the archive. |
/* Write out the LST for the archive. |
6277 |
|
|
6278 |
You'll never believe this is really how armaps are handled in SOM... */ |
You'll never believe this is really how armaps are handled in SOM... */ |
6279 |
|
|
6280 |
static boolean |
static bfd_boolean |
6281 |
som_write_armap (abfd, elength, map, orl_count, stridx) |
som_write_armap (abfd, elength, map, orl_count, stridx) |
6282 |
bfd *abfd; |
bfd *abfd; |
6283 |
unsigned int elength; |
unsigned int elength; |
6297 |
if (stat (abfd->filename, &statbuf) != 0) |
if (stat (abfd->filename, &statbuf) != 0) |
6298 |
{ |
{ |
6299 |
bfd_set_error (bfd_error_system_call); |
bfd_set_error (bfd_error_system_call); |
6300 |
return false; |
return FALSE; |
6301 |
} |
} |
6302 |
/* Fudge factor. */ |
/* Fudge factor. */ |
6303 |
bfd_ardata (abfd)->armap_timestamp = statbuf.st_mtime + 60; |
bfd_ardata (abfd)->armap_timestamp = statbuf.st_mtime + 60; |
6348 |
/* Count how many symbols we will have on the hash chains and the |
/* Count how many symbols we will have on the hash chains and the |
6349 |
size of the associated string table. */ |
size of the associated string table. */ |
6350 |
if (! som_bfd_prep_for_ar_write (abfd, &nsyms, &stringsize)) |
if (! som_bfd_prep_for_ar_write (abfd, &nsyms, &stringsize)) |
6351 |
return false; |
return FALSE; |
6352 |
|
|
6353 |
lst_size += sizeof (struct lst_symbol_record) * nsyms; |
lst_size += sizeof (struct lst_symbol_record) * nsyms; |
6354 |
|
|
6386 |
/* Scribble out the ar header. */ |
/* Scribble out the ar header. */ |
6387 |
amt = sizeof (struct ar_hdr); |
amt = sizeof (struct ar_hdr); |
6388 |
if (bfd_bwrite ((PTR) &hdr, amt, abfd) != amt) |
if (bfd_bwrite ((PTR) &hdr, amt, abfd) != amt) |
6389 |
return false; |
return FALSE; |
6390 |
|
|
6391 |
/* Now scribble out the lst header. */ |
/* Now scribble out the lst header. */ |
6392 |
amt = sizeof (struct lst_header); |
amt = sizeof (struct lst_header); |
6393 |
if (bfd_bwrite ((PTR) &lst, amt, abfd) != amt) |
if (bfd_bwrite ((PTR) &lst, amt, abfd) != amt) |
6394 |
return false; |
return FALSE; |
6395 |
|
|
6396 |
/* Build and write the armap. */ |
/* Build and write the armap. */ |
6397 |
if (!som_bfd_ar_write_symbol_stuff (abfd, nsyms, stringsize, lst, elength)) |
if (!som_bfd_ar_write_symbol_stuff (abfd, nsyms, stringsize, lst, elength)) |
6398 |
return false; |
return FALSE; |
6399 |
|
|
6400 |
/* Done. */ |
/* Done. */ |
6401 |
return true; |
return TRUE; |
6402 |
} |
} |
6403 |
|
|
6404 |
/* Free all information we have cached for this BFD. We can always |
/* Free all information we have cached for this BFD. We can always |
6405 |
read it again later if we need it. */ |
read it again later if we need it. */ |
6406 |
|
|
6407 |
static boolean |
static bfd_boolean |
6408 |
som_bfd_free_cached_info (abfd) |
som_bfd_free_cached_info (abfd) |
6409 |
bfd *abfd; |
bfd *abfd; |
6410 |
{ |
{ |
6411 |
asection *o; |
asection *o; |
6412 |
|
|
6413 |
if (bfd_get_format (abfd) != bfd_object) |
if (bfd_get_format (abfd) != bfd_object) |
6414 |
return true; |
return TRUE; |
6415 |
|
|
6416 |
#define FREE(x) if (x != NULL) { free (x); x = NULL; } |
#define FREE(x) if (x != NULL) { free (x); x = NULL; } |
6417 |
/* Free the native string and symbol tables. */ |
/* Free the native string and symbol tables. */ |
6427 |
} |
} |
6428 |
#undef FREE |
#undef FREE |
6429 |
|
|
6430 |
return true; |
return TRUE; |
6431 |
} |
} |
6432 |
|
|
6433 |
/* End of miscellaneous support functions. */ |
/* End of miscellaneous support functions. */ |
6434 |
|
|
6435 |
/* Linker support functions. */ |
/* Linker support functions. */ |
6436 |
|
|
6437 |
static boolean |
static bfd_boolean |
6438 |
som_bfd_link_split_section (abfd, sec) |
som_bfd_link_split_section (abfd, sec) |
6439 |
bfd *abfd ATTRIBUTE_UNUSED; |
bfd *abfd ATTRIBUTE_UNUSED; |
6440 |
asection *sec; |
asection *sec; |
6441 |
{ |
{ |
6442 |
return (som_is_subspace (sec) && sec->_raw_size > 240000); |
return (som_is_subspace (sec) && sec->size > 240000); |
6443 |
} |
} |
6444 |
|
|
6445 |
#define som_close_and_cleanup som_bfd_free_cached_info |
#define som_close_and_cleanup som_bfd_free_cached_info |
6453 |
#define som_construct_extended_name_table \ |
#define som_construct_extended_name_table \ |
6454 |
_bfd_archive_coff_construct_extended_name_table |
_bfd_archive_coff_construct_extended_name_table |
6455 |
#define som_update_armap_timestamp bfd_true |
#define som_update_armap_timestamp bfd_true |
|
#define som_bfd_print_private_bfd_data _bfd_generic_bfd_print_private_bfd_data |
|
6456 |
|
|
6457 |
#define som_get_lineno _bfd_nosymbols_get_lineno |
#define som_bfd_is_target_special_symbol \ |
6458 |
|
((bfd_boolean (*) (bfd *, asymbol *)) bfd_false) |
6459 |
|
#define som_get_lineno _bfd_nosymbols_get_lineno |
6460 |
#define som_bfd_make_debug_symbol _bfd_nosymbols_bfd_make_debug_symbol |
#define som_bfd_make_debug_symbol _bfd_nosymbols_bfd_make_debug_symbol |
6461 |
#define som_read_minisymbols _bfd_generic_read_minisymbols |
#define som_read_minisymbols _bfd_generic_read_minisymbols |
6462 |
#define som_minisymbol_to_symbol _bfd_generic_minisymbol_to_symbol |
#define som_minisymbol_to_symbol _bfd_generic_minisymbol_to_symbol |
6474 |
|
|
6475 |
#define som_bfd_gc_sections bfd_generic_gc_sections |
#define som_bfd_gc_sections bfd_generic_gc_sections |
6476 |
#define som_bfd_merge_sections bfd_generic_merge_sections |
#define som_bfd_merge_sections bfd_generic_merge_sections |
6477 |
|
#define som_bfd_is_group_section bfd_generic_is_group_section |
6478 |
#define som_bfd_discard_group bfd_generic_discard_group |
#define som_bfd_discard_group bfd_generic_discard_group |
6479 |
|
#define som_section_already_linked \ |
6480 |
|
_bfd_generic_section_already_linked |
6481 |
|
|
6482 |
const bfd_target som_vec = { |
const bfd_target som_vec = { |
6483 |
"som", /* name */ |
"som", /* name */ |
6487 |
(HAS_RELOC | EXEC_P | /* object flags */ |
(HAS_RELOC | EXEC_P | /* object flags */ |
6488 |
HAS_LINENO | HAS_DEBUG | |
HAS_LINENO | HAS_DEBUG | |
6489 |
HAS_SYMS | HAS_LOCALS | WP_TEXT | D_PAGED | DYNAMIC), |
HAS_SYMS | HAS_LOCALS | WP_TEXT | D_PAGED | DYNAMIC), |
6490 |
(SEC_CODE | SEC_DATA | SEC_ROM | SEC_HAS_CONTENTS |
(SEC_CODE | SEC_DATA | SEC_ROM | SEC_HAS_CONTENTS | SEC_LINK_ONCE |
6491 |
| SEC_ALLOC | SEC_LOAD | SEC_RELOC), /* section flags */ |
| SEC_ALLOC | SEC_LOAD | SEC_RELOC), /* section flags */ |
6492 |
|
|
6493 |
/* leading_symbol_char: is the first char of a user symbol |
/* leading_symbol_char: is the first char of a user symbol |
6494 |
predictable, and if so what is it */ |
predictable, and if so what is it. */ |
6495 |
0, |
0, |
6496 |
'/', /* ar_pad_char */ |
'/', /* ar_pad_char */ |
6497 |
14, /* ar_max_namelen */ |
14, /* ar_max_namelen */ |