1 |
/* BFD back-end for binary objects. |
/* BFD back-end for binary objects. |
2 |
Copyright 1994, 1995, 1996, 1997, 1998, 1999, 2000, 2001, 2002 |
Copyright 1994, 1995, 1996, 1997, 1998, 1999, 2000, 2001, 2002, 2003, |
3 |
Free Software Foundation, Inc. |
2004 Free Software Foundation, Inc. |
4 |
Written by Ian Lance Taylor, Cygnus Support, <ian@cygnus.com> |
Written by Ian Lance Taylor, Cygnus Support, <ian@cygnus.com> |
5 |
|
|
6 |
This file is part of BFD, the Binary File Descriptor library. |
This file is part of BFD, the Binary File Descriptor library. |
7 |
|
|
8 |
This program is free software; you can redistribute it and/or modify |
This program is free software; you can redistribute it and/or modify |
9 |
it under the terms of the GNU General Public License as published by |
it under the terms of the GNU General Public License as published by |
10 |
the Free Software Foundation; either version 2 of the License, or |
the Free Software Foundation; either version 2 of the License, or |
11 |
(at your option) any later version. |
(at your option) any later version. |
12 |
|
|
13 |
This program is distributed in the hope that it will be useful, |
This program is distributed in the hope that it will be useful, |
14 |
but WITHOUT ANY WARRANTY; without even the implied warranty of |
but WITHOUT ANY WARRANTY; without even the implied warranty of |
15 |
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the |
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the |
16 |
GNU General Public License for more details. |
GNU General Public License for more details. |
17 |
|
|
18 |
You should have received a copy of the GNU General Public License |
You should have received a copy of the GNU General Public License |
19 |
along with this program; if not, write to the Free Software |
along with this program; if not, write to the Free Software |
20 |
Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */ |
Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */ |
21 |
|
|
22 |
/* This is a BFD backend which may be used to write binary objects. |
/* This is a BFD backend which may be used to write binary objects. |
23 |
It may only be used for output, not input. The intention is that |
It may only be used for output, not input. The intention is that |
41 |
a start symbol, an end symbol, and an absolute length symbol. */ |
a start symbol, an end symbol, and an absolute length symbol. */ |
42 |
#define BIN_SYMS 3 |
#define BIN_SYMS 3 |
43 |
|
|
44 |
static boolean binary_mkobject PARAMS ((bfd *)); |
static bfd_boolean binary_mkobject PARAMS ((bfd *)); |
45 |
static const bfd_target *binary_object_p PARAMS ((bfd *)); |
static const bfd_target *binary_object_p PARAMS ((bfd *)); |
46 |
static boolean binary_get_section_contents |
static bfd_boolean binary_get_section_contents |
47 |
PARAMS ((bfd *, asection *, PTR, file_ptr, bfd_size_type)); |
PARAMS ((bfd *, asection *, PTR, file_ptr, bfd_size_type)); |
48 |
static long binary_get_symtab_upper_bound PARAMS ((bfd *)); |
static long binary_get_symtab_upper_bound PARAMS ((bfd *)); |
49 |
static char *mangle_name PARAMS ((bfd *, char *)); |
static char *mangle_name PARAMS ((bfd *, char *)); |
50 |
static long binary_get_symtab PARAMS ((bfd *, asymbol **)); |
static long binary_canonicalize_symtab PARAMS ((bfd *, asymbol **)); |
51 |
static void binary_get_symbol_info PARAMS ((bfd *, asymbol *, symbol_info *)); |
static void binary_get_symbol_info PARAMS ((bfd *, asymbol *, symbol_info *)); |
52 |
static boolean binary_set_section_contents |
static bfd_boolean binary_set_section_contents |
53 |
PARAMS ((bfd *, asection *, PTR, file_ptr, bfd_size_type)); |
PARAMS ((bfd *, asection *, const PTR, file_ptr, bfd_size_type)); |
54 |
static int binary_sizeof_headers PARAMS ((bfd *, boolean)); |
static int binary_sizeof_headers PARAMS ((bfd *, bfd_boolean)); |
55 |
|
|
56 |
/* Set by external programs - specifies the BFD architecture |
/* Set by external programs - specifies the BFD architecture and |
57 |
to use when creating binary BFDs. */ |
machine number to be uses when creating binary BFDs. */ |
58 |
enum bfd_architecture bfd_external_binary_architecture = bfd_arch_unknown; |
enum bfd_architecture bfd_external_binary_architecture = bfd_arch_unknown; |
59 |
|
unsigned long bfd_external_machine = 0; |
60 |
|
|
61 |
/* Create a binary object. Invoked via bfd_set_format. */ |
/* Create a binary object. Invoked via bfd_set_format. */ |
62 |
|
|
63 |
static boolean |
static bfd_boolean |
64 |
binary_mkobject (abfd) |
binary_mkobject (abfd) |
65 |
bfd *abfd ATTRIBUTE_UNUSED; |
bfd *abfd ATTRIBUTE_UNUSED; |
66 |
{ |
{ |
67 |
return true; |
return TRUE; |
68 |
} |
} |
69 |
|
|
70 |
/* Any file may be considered to be a binary file, provided the target |
/* Any file may be considered to be a binary file, provided the target |
99 |
return NULL; |
return NULL; |
100 |
sec->flags = SEC_ALLOC | SEC_LOAD | SEC_DATA | SEC_HAS_CONTENTS; |
sec->flags = SEC_ALLOC | SEC_LOAD | SEC_DATA | SEC_HAS_CONTENTS; |
101 |
sec->vma = 0; |
sec->vma = 0; |
102 |
sec->_raw_size = statbuf.st_size; |
sec->size = statbuf.st_size; |
103 |
sec->filepos = 0; |
sec->filepos = 0; |
104 |
|
|
105 |
abfd->tdata.any = (PTR) sec; |
abfd->tdata.any = (PTR) sec; |
108 |
{ |
{ |
109 |
if ((bfd_get_arch_info (abfd)->arch == bfd_arch_unknown) |
if ((bfd_get_arch_info (abfd)->arch == bfd_arch_unknown) |
110 |
&& (bfd_external_binary_architecture != bfd_arch_unknown)) |
&& (bfd_external_binary_architecture != bfd_arch_unknown)) |
111 |
bfd_set_arch_info (abfd, bfd_lookup_arch (bfd_external_binary_architecture, 0)); |
bfd_set_arch_info (abfd, bfd_lookup_arch |
112 |
|
(bfd_external_binary_architecture, bfd_external_machine)); |
113 |
} |
} |
114 |
|
|
115 |
return abfd->xvec; |
return abfd->xvec; |
121 |
|
|
122 |
/* Get contents of the only section. */ |
/* Get contents of the only section. */ |
123 |
|
|
124 |
static boolean |
static bfd_boolean |
125 |
binary_get_section_contents (abfd, section, location, offset, count) |
binary_get_section_contents (abfd, section, location, offset, count) |
126 |
bfd *abfd; |
bfd *abfd; |
127 |
asection *section ATTRIBUTE_UNUSED; |
asection *section ATTRIBUTE_UNUSED; |
131 |
{ |
{ |
132 |
if (bfd_seek (abfd, offset, SEEK_SET) != 0 |
if (bfd_seek (abfd, offset, SEEK_SET) != 0 |
133 |
|| bfd_bread (location, count, abfd) != count) |
|| bfd_bread (location, count, abfd) != count) |
134 |
return false; |
return FALSE; |
135 |
return true; |
return TRUE; |
136 |
} |
} |
137 |
|
|
138 |
/* Return the amount of memory needed to read the symbol table. */ |
/* Return the amount of memory needed to read the symbol table. */ |
176 |
/* Return the symbol table. */ |
/* Return the symbol table. */ |
177 |
|
|
178 |
static long |
static long |
179 |
binary_get_symtab (abfd, alocation) |
binary_canonicalize_symtab (abfd, alocation) |
180 |
bfd *abfd; |
bfd *abfd; |
181 |
asymbol **alocation; |
asymbol **alocation; |
182 |
{ |
{ |
187 |
|
|
188 |
syms = (asymbol *) bfd_alloc (abfd, amt); |
syms = (asymbol *) bfd_alloc (abfd, amt); |
189 |
if (syms == NULL) |
if (syms == NULL) |
190 |
return false; |
return 0; |
191 |
|
|
192 |
/* Start symbol. */ |
/* Start symbol. */ |
193 |
syms[0].the_bfd = abfd; |
syms[0].the_bfd = abfd; |
200 |
/* End symbol. */ |
/* End symbol. */ |
201 |
syms[1].the_bfd = abfd; |
syms[1].the_bfd = abfd; |
202 |
syms[1].name = mangle_name (abfd, "end"); |
syms[1].name = mangle_name (abfd, "end"); |
203 |
syms[1].value = sec->_raw_size; |
syms[1].value = sec->size; |
204 |
syms[1].flags = BSF_GLOBAL; |
syms[1].flags = BSF_GLOBAL; |
205 |
syms[1].section = sec; |
syms[1].section = sec; |
206 |
syms[1].udata.p = NULL; |
syms[1].udata.p = NULL; |
208 |
/* Size symbol. */ |
/* Size symbol. */ |
209 |
syms[2].the_bfd = abfd; |
syms[2].the_bfd = abfd; |
210 |
syms[2].name = mangle_name (abfd, "size"); |
syms[2].name = mangle_name (abfd, "size"); |
211 |
syms[2].value = sec->_raw_size; |
syms[2].value = sec->size; |
212 |
syms[2].flags = BSF_GLOBAL; |
syms[2].flags = BSF_GLOBAL; |
213 |
syms[2].section = bfd_abs_section_ptr; |
syms[2].section = bfd_abs_section_ptr; |
214 |
syms[2].udata.p = NULL; |
syms[2].udata.p = NULL; |
234 |
bfd_symbol_info (symbol, ret); |
bfd_symbol_info (symbol, ret); |
235 |
} |
} |
236 |
|
|
237 |
|
#define binary_bfd_is_target_special_symbol ((bfd_boolean (*) (bfd *, asymbol *)) bfd_false) |
238 |
#define binary_bfd_is_local_label_name bfd_generic_is_local_label_name |
#define binary_bfd_is_local_label_name bfd_generic_is_local_label_name |
239 |
#define binary_get_lineno _bfd_nosymbols_get_lineno |
#define binary_get_lineno _bfd_nosymbols_get_lineno |
240 |
#define binary_find_nearest_line _bfd_nosymbols_find_nearest_line |
#define binary_find_nearest_line _bfd_nosymbols_find_nearest_line |
253 |
|
|
254 |
/* Write section contents of a binary file. */ |
/* Write section contents of a binary file. */ |
255 |
|
|
256 |
static boolean |
static bfd_boolean |
257 |
binary_set_section_contents (abfd, sec, data, offset, size) |
binary_set_section_contents (abfd, sec, data, offset, size) |
258 |
bfd *abfd; |
bfd *abfd; |
259 |
asection *sec; |
asection *sec; |
260 |
PTR data; |
const PTR data; |
261 |
file_ptr offset; |
file_ptr offset; |
262 |
bfd_size_type size; |
bfd_size_type size; |
263 |
{ |
{ |
264 |
if (size == 0) |
if (size == 0) |
265 |
return true; |
return TRUE; |
266 |
|
|
267 |
if (! abfd->output_has_begun) |
if (! abfd->output_has_begun) |
268 |
{ |
{ |
269 |
boolean found_low; |
bfd_boolean found_low; |
270 |
bfd_vma low; |
bfd_vma low; |
271 |
asection *s; |
asection *s; |
272 |
|
|
273 |
/* The lowest section LMA sets the virtual address of the start |
/* The lowest section LMA sets the virtual address of the start |
274 |
of the file. We use this to set the file position of all the |
of the file. We use this to set the file position of all the |
275 |
sections. */ |
sections. */ |
276 |
found_low = false; |
found_low = FALSE; |
277 |
low = 0; |
low = 0; |
278 |
for (s = abfd->sections; s != NULL; s = s->next) |
for (s = abfd->sections; s != NULL; s = s->next) |
279 |
if (((s->flags |
if (((s->flags |
280 |
& (SEC_HAS_CONTENTS | SEC_LOAD | SEC_ALLOC | SEC_NEVER_LOAD)) |
& (SEC_HAS_CONTENTS | SEC_LOAD | SEC_ALLOC | SEC_NEVER_LOAD)) |
281 |
== (SEC_HAS_CONTENTS | SEC_LOAD | SEC_ALLOC)) |
== (SEC_HAS_CONTENTS | SEC_LOAD | SEC_ALLOC)) |
282 |
&& (s->_raw_size > 0) |
&& (s->size > 0) |
283 |
&& (! found_low || s->lma < low)) |
&& (! found_low || s->lma < low)) |
284 |
{ |
{ |
285 |
low = s->lma; |
low = s->lma; |
286 |
found_low = true; |
found_low = TRUE; |
287 |
} |
} |
288 |
|
|
289 |
for (s = abfd->sections; s != NULL; s = s->next) |
for (s = abfd->sections; s != NULL; s = s->next) |
295 |
if ((s->flags |
if ((s->flags |
296 |
& (SEC_HAS_CONTENTS | SEC_ALLOC | SEC_NEVER_LOAD)) |
& (SEC_HAS_CONTENTS | SEC_ALLOC | SEC_NEVER_LOAD)) |
297 |
!= (SEC_HAS_CONTENTS | SEC_ALLOC) |
!= (SEC_HAS_CONTENTS | SEC_ALLOC) |
298 |
|| (s->_raw_size == 0)) |
|| (s->size == 0)) |
299 |
continue; |
continue; |
300 |
|
|
301 |
/* If attempting to generate a binary file from a bfd with |
/* If attempting to generate a binary file from a bfd with |
311 |
(unsigned long) s->filepos); |
(unsigned long) s->filepos); |
312 |
} |
} |
313 |
|
|
314 |
abfd->output_has_begun = true; |
abfd->output_has_begun = TRUE; |
315 |
} |
} |
316 |
|
|
317 |
/* We don't want to output anything for a section that is neither |
/* We don't want to output anything for a section that is neither |
318 |
loaded nor allocated. The contents of such a section are not |
loaded nor allocated. The contents of such a section are not |
319 |
meaningful in the binary format. */ |
meaningful in the binary format. */ |
320 |
if ((sec->flags & (SEC_LOAD | SEC_ALLOC)) == 0) |
if ((sec->flags & (SEC_LOAD | SEC_ALLOC)) == 0) |
321 |
return true; |
return TRUE; |
322 |
if ((sec->flags & SEC_NEVER_LOAD) != 0) |
if ((sec->flags & SEC_NEVER_LOAD) != 0) |
323 |
return true; |
return TRUE; |
324 |
|
|
325 |
return _bfd_generic_set_section_contents (abfd, sec, data, offset, size); |
return _bfd_generic_set_section_contents (abfd, sec, data, offset, size); |
326 |
} |
} |
330 |
static int |
static int |
331 |
binary_sizeof_headers (abfd, exec) |
binary_sizeof_headers (abfd, exec) |
332 |
bfd *abfd ATTRIBUTE_UNUSED; |
bfd *abfd ATTRIBUTE_UNUSED; |
333 |
boolean exec ATTRIBUTE_UNUSED; |
bfd_boolean exec ATTRIBUTE_UNUSED; |
334 |
{ |
{ |
335 |
return 0; |
return 0; |
336 |
} |
} |
340 |
#define binary_bfd_relax_section bfd_generic_relax_section |
#define binary_bfd_relax_section bfd_generic_relax_section |
341 |
#define binary_bfd_gc_sections bfd_generic_gc_sections |
#define binary_bfd_gc_sections bfd_generic_gc_sections |
342 |
#define binary_bfd_merge_sections bfd_generic_merge_sections |
#define binary_bfd_merge_sections bfd_generic_merge_sections |
343 |
|
#define binary_bfd_is_group_section bfd_generic_is_group_section |
344 |
#define binary_bfd_discard_group bfd_generic_discard_group |
#define binary_bfd_discard_group bfd_generic_discard_group |
345 |
|
#define binary_section_already_linked \ |
346 |
|
_bfd_generic_section_already_linked |
347 |
#define binary_bfd_link_hash_table_create _bfd_generic_link_hash_table_create |
#define binary_bfd_link_hash_table_create _bfd_generic_link_hash_table_create |
348 |
#define binary_bfd_link_hash_table_free _bfd_generic_link_hash_table_free |
#define binary_bfd_link_hash_table_free _bfd_generic_link_hash_table_free |
349 |
#define binary_bfd_link_just_syms _bfd_generic_link_just_syms |
#define binary_bfd_link_just_syms _bfd_generic_link_just_syms |