12159047fSniklas /* BFD back-end for binary objects.
2*007c2a45Smiod Copyright 1994, 1995, 1996, 1997, 1998, 1999, 2000, 2001, 2002, 2003
3b55d4692Sfgsch Free Software Foundation, Inc.
42159047fSniklas Written by Ian Lance Taylor, Cygnus Support, <ian@cygnus.com>
52159047fSniklas
62159047fSniklas This file is part of BFD, the Binary File Descriptor library.
72159047fSniklas
82159047fSniklas This program is free software; you can redistribute it and/or modify
92159047fSniklas it under the terms of the GNU General Public License as published by
102159047fSniklas the Free Software Foundation; either version 2 of the License, or
112159047fSniklas (at your option) any later version.
122159047fSniklas
132159047fSniklas This program is distributed in the hope that it will be useful,
142159047fSniklas but WITHOUT ANY WARRANTY; without even the implied warranty of
152159047fSniklas MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
162159047fSniklas GNU General Public License for more details.
172159047fSniklas
182159047fSniklas You should have received a copy of the GNU General Public License
192159047fSniklas along with this program; if not, write to the Free Software
202159047fSniklas Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */
212159047fSniklas
222159047fSniklas /* This is a BFD backend which may be used to write binary objects.
232159047fSniklas It may only be used for output, not input. The intention is that
242159047fSniklas this may be used as an output format for objcopy in order to
252159047fSniklas generate raw binary data.
262159047fSniklas
272159047fSniklas This is very simple. The only complication is that the real data
282159047fSniklas will start at some address X, and in some cases we will not want to
292159047fSniklas include X zeroes just to get to that point. Since the start
302159047fSniklas address is not meaningful for this object file format, we use it
312159047fSniklas instead to indicate the number of zeroes to skip at the start of
322159047fSniklas the file. objcopy cooperates by specially setting the start
332159047fSniklas address to zero by default. */
342159047fSniklas
352159047fSniklas #include "bfd.h"
362159047fSniklas #include "sysdep.h"
37c074d1c9Sdrahn #include "safe-ctype.h"
382159047fSniklas #include "libbfd.h"
392159047fSniklas
402159047fSniklas /* Any bfd we create by reading a binary file has three symbols:
412159047fSniklas a start symbol, an end symbol, and an absolute length symbol. */
422159047fSniklas #define BIN_SYMS 3
432159047fSniklas
44c074d1c9Sdrahn static bfd_boolean binary_mkobject PARAMS ((bfd *));
452159047fSniklas static const bfd_target *binary_object_p PARAMS ((bfd *));
46c074d1c9Sdrahn static bfd_boolean binary_get_section_contents
472159047fSniklas PARAMS ((bfd *, asection *, PTR, file_ptr, bfd_size_type));
482159047fSniklas static long binary_get_symtab_upper_bound PARAMS ((bfd *));
492159047fSniklas static char *mangle_name PARAMS ((bfd *, char *));
50*007c2a45Smiod static long binary_canonicalize_symtab PARAMS ((bfd *, asymbol **));
512159047fSniklas static void binary_get_symbol_info PARAMS ((bfd *, asymbol *, symbol_info *));
52c074d1c9Sdrahn static bfd_boolean binary_set_section_contents
53*007c2a45Smiod PARAMS ((bfd *, asection *, const PTR, file_ptr, bfd_size_type));
54c074d1c9Sdrahn static int binary_sizeof_headers PARAMS ((bfd *, bfd_boolean));
55c074d1c9Sdrahn
56*007c2a45Smiod /* Set by external programs - specifies the BFD architecture and
57*007c2a45Smiod machine number to be uses when creating binary BFDs. */
58c074d1c9Sdrahn enum bfd_architecture bfd_external_binary_architecture = bfd_arch_unknown;
59*007c2a45Smiod unsigned long bfd_external_machine = 0;
602159047fSniklas
612159047fSniklas /* Create a binary object. Invoked via bfd_set_format. */
622159047fSniklas
63c074d1c9Sdrahn static bfd_boolean
binary_mkobject(abfd)642159047fSniklas binary_mkobject (abfd)
65b305b0f1Sespie bfd *abfd ATTRIBUTE_UNUSED;
662159047fSniklas {
67c074d1c9Sdrahn return TRUE;
682159047fSniklas }
692159047fSniklas
702159047fSniklas /* Any file may be considered to be a binary file, provided the target
712159047fSniklas was not defaulted. That is, it must be explicitly specified as
722159047fSniklas being binary. */
732159047fSniklas
742159047fSniklas static const bfd_target *
binary_object_p(abfd)752159047fSniklas binary_object_p (abfd)
762159047fSniklas bfd *abfd;
772159047fSniklas {
782159047fSniklas struct stat statbuf;
792159047fSniklas asection *sec;
802159047fSniklas
812159047fSniklas if (abfd->target_defaulted)
822159047fSniklas {
832159047fSniklas bfd_set_error (bfd_error_wrong_format);
842159047fSniklas return NULL;
852159047fSniklas }
862159047fSniklas
872159047fSniklas abfd->symcount = BIN_SYMS;
882159047fSniklas
892159047fSniklas /* Find the file size. */
902159047fSniklas if (bfd_stat (abfd, &statbuf) < 0)
912159047fSniklas {
922159047fSniklas bfd_set_error (bfd_error_system_call);
932159047fSniklas return NULL;
942159047fSniklas }
952159047fSniklas
962159047fSniklas /* One data section. */
972159047fSniklas sec = bfd_make_section (abfd, ".data");
982159047fSniklas if (sec == NULL)
992159047fSniklas return NULL;
1002159047fSniklas sec->flags = SEC_ALLOC | SEC_LOAD | SEC_DATA | SEC_HAS_CONTENTS;
1012159047fSniklas sec->vma = 0;
1022159047fSniklas sec->_raw_size = statbuf.st_size;
1032159047fSniklas sec->filepos = 0;
1042159047fSniklas
1052159047fSniklas abfd->tdata.any = (PTR) sec;
1062159047fSniklas
107c074d1c9Sdrahn if (bfd_get_arch_info (abfd) != NULL)
108c074d1c9Sdrahn {
109c074d1c9Sdrahn if ((bfd_get_arch_info (abfd)->arch == bfd_arch_unknown)
110c074d1c9Sdrahn && (bfd_external_binary_architecture != bfd_arch_unknown))
111*007c2a45Smiod bfd_set_arch_info (abfd, bfd_lookup_arch
112*007c2a45Smiod (bfd_external_binary_architecture, bfd_external_machine));
113c074d1c9Sdrahn }
114c074d1c9Sdrahn
1152159047fSniklas return abfd->xvec;
1162159047fSniklas }
1172159047fSniklas
1182159047fSniklas #define binary_close_and_cleanup _bfd_generic_close_and_cleanup
1192159047fSniklas #define binary_bfd_free_cached_info _bfd_generic_bfd_free_cached_info
1202159047fSniklas #define binary_new_section_hook _bfd_generic_new_section_hook
1212159047fSniklas
1222159047fSniklas /* Get contents of the only section. */
1232159047fSniklas
124c074d1c9Sdrahn static bfd_boolean
binary_get_section_contents(abfd,section,location,offset,count)1252159047fSniklas binary_get_section_contents (abfd, section, location, offset, count)
1262159047fSniklas bfd *abfd;
127b305b0f1Sespie asection *section ATTRIBUTE_UNUSED;
1282159047fSniklas PTR location;
1292159047fSniklas file_ptr offset;
1302159047fSniklas bfd_size_type count;
1312159047fSniklas {
1322159047fSniklas if (bfd_seek (abfd, offset, SEEK_SET) != 0
133c074d1c9Sdrahn || bfd_bread (location, count, abfd) != count)
134c074d1c9Sdrahn return FALSE;
135c074d1c9Sdrahn return TRUE;
1362159047fSniklas }
1372159047fSniklas
1382159047fSniklas /* Return the amount of memory needed to read the symbol table. */
1392159047fSniklas
1402159047fSniklas static long
binary_get_symtab_upper_bound(abfd)1412159047fSniklas binary_get_symtab_upper_bound (abfd)
142b305b0f1Sespie bfd *abfd ATTRIBUTE_UNUSED;
1432159047fSniklas {
1442159047fSniklas return (BIN_SYMS + 1) * sizeof (asymbol *);
1452159047fSniklas }
1462159047fSniklas
1472159047fSniklas /* Create a symbol name based on the bfd's filename. */
1482159047fSniklas
1492159047fSniklas static char *
mangle_name(abfd,suffix)1502159047fSniklas mangle_name (abfd, suffix)
1512159047fSniklas bfd *abfd;
1522159047fSniklas char *suffix;
1532159047fSniklas {
154c074d1c9Sdrahn bfd_size_type size;
1552159047fSniklas char *buf;
1562159047fSniklas char *p;
1572159047fSniklas
1582159047fSniklas size = (strlen (bfd_get_filename (abfd))
1592159047fSniklas + strlen (suffix)
1602159047fSniklas + sizeof "_binary__");
1612159047fSniklas
1622159047fSniklas buf = (char *) bfd_alloc (abfd, size);
1632159047fSniklas if (buf == NULL)
1642159047fSniklas return "";
1652159047fSniklas
1662159047fSniklas sprintf (buf, "_binary_%s_%s", bfd_get_filename (abfd), suffix);
1672159047fSniklas
1682159047fSniklas /* Change any non-alphanumeric characters to underscores. */
1692159047fSniklas for (p = buf; *p; p++)
170c074d1c9Sdrahn if (! ISALNUM (*p))
1712159047fSniklas *p = '_';
1722159047fSniklas
1732159047fSniklas return buf;
1742159047fSniklas }
1752159047fSniklas
1762159047fSniklas /* Return the symbol table. */
1772159047fSniklas
1782159047fSniklas static long
binary_canonicalize_symtab(abfd,alocation)179*007c2a45Smiod binary_canonicalize_symtab (abfd, alocation)
1802159047fSniklas bfd *abfd;
1812159047fSniklas asymbol **alocation;
1822159047fSniklas {
1832159047fSniklas asection *sec = (asection *) abfd->tdata.any;
1842159047fSniklas asymbol *syms;
1852159047fSniklas unsigned int i;
186c074d1c9Sdrahn bfd_size_type amt = BIN_SYMS * sizeof (asymbol);
1872159047fSniklas
188c074d1c9Sdrahn syms = (asymbol *) bfd_alloc (abfd, amt);
1892159047fSniklas if (syms == NULL)
190c074d1c9Sdrahn return 0;
1912159047fSniklas
1922159047fSniklas /* Start symbol. */
1932159047fSniklas syms[0].the_bfd = abfd;
1942159047fSniklas syms[0].name = mangle_name (abfd, "start");
1952159047fSniklas syms[0].value = 0;
1962159047fSniklas syms[0].flags = BSF_GLOBAL;
1972159047fSniklas syms[0].section = sec;
1982159047fSniklas syms[0].udata.p = NULL;
1992159047fSniklas
2002159047fSniklas /* End symbol. */
2012159047fSniklas syms[1].the_bfd = abfd;
2022159047fSniklas syms[1].name = mangle_name (abfd, "end");
2032159047fSniklas syms[1].value = sec->_raw_size;
2042159047fSniklas syms[1].flags = BSF_GLOBAL;
2052159047fSniklas syms[1].section = sec;
2062159047fSniklas syms[1].udata.p = NULL;
2072159047fSniklas
2082159047fSniklas /* Size symbol. */
2092159047fSniklas syms[2].the_bfd = abfd;
2102159047fSniklas syms[2].name = mangle_name (abfd, "size");
2112159047fSniklas syms[2].value = sec->_raw_size;
2122159047fSniklas syms[2].flags = BSF_GLOBAL;
2132159047fSniklas syms[2].section = bfd_abs_section_ptr;
2142159047fSniklas syms[2].udata.p = NULL;
2152159047fSniklas
2162159047fSniklas for (i = 0; i < BIN_SYMS; i++)
2172159047fSniklas *alocation++ = syms++;
2182159047fSniklas *alocation = NULL;
2192159047fSniklas
2202159047fSniklas return BIN_SYMS;
2212159047fSniklas }
2222159047fSniklas
223c074d1c9Sdrahn #define binary_make_empty_symbol _bfd_generic_make_empty_symbol
2242159047fSniklas #define binary_print_symbol _bfd_nosymbols_print_symbol
2252159047fSniklas
2262159047fSniklas /* Get information about a symbol. */
2272159047fSniklas
2282159047fSniklas static void
binary_get_symbol_info(ignore_abfd,symbol,ret)2292159047fSniklas binary_get_symbol_info (ignore_abfd, symbol, ret)
230b305b0f1Sespie bfd *ignore_abfd ATTRIBUTE_UNUSED;
2312159047fSniklas asymbol *symbol;
2322159047fSniklas symbol_info *ret;
2332159047fSniklas {
2342159047fSniklas bfd_symbol_info (symbol, ret);
2352159047fSniklas }
2362159047fSniklas
237b305b0f1Sespie #define binary_bfd_is_local_label_name bfd_generic_is_local_label_name
2382159047fSniklas #define binary_get_lineno _bfd_nosymbols_get_lineno
2392159047fSniklas #define binary_find_nearest_line _bfd_nosymbols_find_nearest_line
2402159047fSniklas #define binary_bfd_make_debug_symbol _bfd_nosymbols_bfd_make_debug_symbol
2412159047fSniklas #define binary_read_minisymbols _bfd_generic_read_minisymbols
2422159047fSniklas #define binary_minisymbol_to_symbol _bfd_generic_minisymbol_to_symbol
2432159047fSniklas
2442159047fSniklas #define binary_get_reloc_upper_bound \
2452159047fSniklas ((long (*) PARAMS ((bfd *, asection *))) bfd_0l)
2462159047fSniklas #define binary_canonicalize_reloc \
2472159047fSniklas ((long (*) PARAMS ((bfd *, asection *, arelent **, asymbol **))) bfd_0l)
2482159047fSniklas #define binary_bfd_reloc_type_lookup _bfd_norelocs_bfd_reloc_type_lookup
2492159047fSniklas
2502159047fSniklas /* Set the architecture of a binary file. */
2512159047fSniklas #define binary_set_arch_mach _bfd_generic_set_arch_mach
2522159047fSniklas
2532159047fSniklas /* Write section contents of a binary file. */
2542159047fSniklas
255c074d1c9Sdrahn static bfd_boolean
binary_set_section_contents(abfd,sec,data,offset,size)2562159047fSniklas binary_set_section_contents (abfd, sec, data, offset, size)
2572159047fSniklas bfd *abfd;
2582159047fSniklas asection *sec;
259*007c2a45Smiod const PTR data;
2602159047fSniklas file_ptr offset;
2612159047fSniklas bfd_size_type size;
2622159047fSniklas {
263b55d4692Sfgsch if (size == 0)
264c074d1c9Sdrahn return TRUE;
265b55d4692Sfgsch
2662159047fSniklas if (! abfd->output_has_begun)
2672159047fSniklas {
268c074d1c9Sdrahn bfd_boolean found_low;
2692159047fSniklas bfd_vma low;
2702159047fSniklas asection *s;
2712159047fSniklas
2720c6d0228Sniklas /* The lowest section LMA sets the virtual address of the start
2730c6d0228Sniklas of the file. We use this to set the file position of all the
2742159047fSniklas sections. */
275c074d1c9Sdrahn found_low = FALSE;
276b305b0f1Sespie low = 0;
277b305b0f1Sespie for (s = abfd->sections; s != NULL; s = s->next)
278b305b0f1Sespie if (((s->flags
279b305b0f1Sespie & (SEC_HAS_CONTENTS | SEC_LOAD | SEC_ALLOC | SEC_NEVER_LOAD))
280e93f7393Sniklas == (SEC_HAS_CONTENTS | SEC_LOAD | SEC_ALLOC))
281b55d4692Sfgsch && (s->_raw_size > 0)
282b305b0f1Sespie && (! found_low || s->lma < low))
283b305b0f1Sespie {
2840c6d0228Sniklas low = s->lma;
285c074d1c9Sdrahn found_low = TRUE;
286b305b0f1Sespie }
2872159047fSniklas
2882159047fSniklas for (s = abfd->sections; s != NULL; s = s->next)
289b305b0f1Sespie {
2900c6d0228Sniklas s->filepos = s->lma - low;
2912159047fSniklas
292b305b0f1Sespie /* Skip following warning check for sections that will not
293b305b0f1Sespie occupy file space. */
294b305b0f1Sespie if ((s->flags
295b305b0f1Sespie & (SEC_HAS_CONTENTS | SEC_ALLOC | SEC_NEVER_LOAD))
296b55d4692Sfgsch != (SEC_HAS_CONTENTS | SEC_ALLOC)
297b55d4692Sfgsch || (s->_raw_size == 0))
298b305b0f1Sespie continue;
299b305b0f1Sespie
300b305b0f1Sespie /* If attempting to generate a binary file from a bfd with
301b305b0f1Sespie LMA's all over the place, huge (sparse?) binary files may
302b305b0f1Sespie result. This condition attempts to detect this situation
303b305b0f1Sespie and print a warning. Better heuristics would be nice to
304b305b0f1Sespie have. */
305b305b0f1Sespie
306b305b0f1Sespie if (s->filepos < 0)
307b305b0f1Sespie (*_bfd_error_handler)
308b305b0f1Sespie (_("Warning: Writing section `%s' to huge (ie negative) file offset 0x%lx."),
309b305b0f1Sespie bfd_get_section_name (abfd, s),
310b305b0f1Sespie (unsigned long) s->filepos);
311b305b0f1Sespie }
312b305b0f1Sespie
313c074d1c9Sdrahn abfd->output_has_begun = TRUE;
3142159047fSniklas }
3152159047fSniklas
316b305b0f1Sespie /* We don't want to output anything for a section that is neither
317b305b0f1Sespie loaded nor allocated. The contents of such a section are not
318b305b0f1Sespie meaningful in the binary format. */
319b305b0f1Sespie if ((sec->flags & (SEC_LOAD | SEC_ALLOC)) == 0)
320c074d1c9Sdrahn return TRUE;
321b305b0f1Sespie if ((sec->flags & SEC_NEVER_LOAD) != 0)
322c074d1c9Sdrahn return TRUE;
323b305b0f1Sespie
3242159047fSniklas return _bfd_generic_set_section_contents (abfd, sec, data, offset, size);
3252159047fSniklas }
3262159047fSniklas
3272159047fSniklas /* No space is required for header information. */
3282159047fSniklas
3292159047fSniklas static int
binary_sizeof_headers(abfd,exec)3302159047fSniklas binary_sizeof_headers (abfd, exec)
331b305b0f1Sespie bfd *abfd ATTRIBUTE_UNUSED;
332c074d1c9Sdrahn bfd_boolean exec ATTRIBUTE_UNUSED;
3332159047fSniklas {
3342159047fSniklas return 0;
3352159047fSniklas }
3362159047fSniklas
3372159047fSniklas #define binary_bfd_get_relocated_section_contents \
3382159047fSniklas bfd_generic_get_relocated_section_contents
3392159047fSniklas #define binary_bfd_relax_section bfd_generic_relax_section
340b305b0f1Sespie #define binary_bfd_gc_sections bfd_generic_gc_sections
341c074d1c9Sdrahn #define binary_bfd_merge_sections bfd_generic_merge_sections
342c074d1c9Sdrahn #define binary_bfd_discard_group bfd_generic_discard_group
3432159047fSniklas #define binary_bfd_link_hash_table_create _bfd_generic_link_hash_table_create
344c074d1c9Sdrahn #define binary_bfd_link_hash_table_free _bfd_generic_link_hash_table_free
345c074d1c9Sdrahn #define binary_bfd_link_just_syms _bfd_generic_link_just_syms
3462159047fSniklas #define binary_bfd_link_add_symbols _bfd_generic_link_add_symbols
3472159047fSniklas #define binary_bfd_final_link _bfd_generic_final_link
3482159047fSniklas #define binary_bfd_link_split_section _bfd_generic_link_split_section
3492159047fSniklas #define binary_get_section_contents_in_window \
3502159047fSniklas _bfd_generic_get_section_contents_in_window
3512159047fSniklas
3522159047fSniklas const bfd_target binary_vec =
3532159047fSniklas {
3542159047fSniklas "binary", /* name */
3552159047fSniklas bfd_target_unknown_flavour, /* flavour */
356c88b1d6cSniklas BFD_ENDIAN_UNKNOWN, /* byteorder */
357c88b1d6cSniklas BFD_ENDIAN_UNKNOWN, /* header_byteorder */
3582159047fSniklas EXEC_P, /* object_flags */
3592159047fSniklas (SEC_ALLOC | SEC_LOAD | SEC_READONLY | SEC_CODE | SEC_DATA
3602159047fSniklas | SEC_ROM | SEC_HAS_CONTENTS), /* section_flags */
3612159047fSniklas 0, /* symbol_leading_char */
3622159047fSniklas ' ', /* ar_pad_char */
3632159047fSniklas 16, /* ar_max_namelen */
3642159047fSniklas bfd_getb64, bfd_getb_signed_64, bfd_putb64,
3652159047fSniklas bfd_getb32, bfd_getb_signed_32, bfd_putb32,
3662159047fSniklas bfd_getb16, bfd_getb_signed_16, bfd_putb16, /* data */
3672159047fSniklas bfd_getb64, bfd_getb_signed_64, bfd_putb64,
3682159047fSniklas bfd_getb32, bfd_getb_signed_32, bfd_putb32,
3692159047fSniklas bfd_getb16, bfd_getb_signed_16, bfd_putb16, /* hdrs */
3702159047fSniklas { /* bfd_check_format */
3712159047fSniklas _bfd_dummy_target,
3722159047fSniklas binary_object_p, /* bfd_check_format */
3732159047fSniklas _bfd_dummy_target,
3742159047fSniklas _bfd_dummy_target,
3752159047fSniklas },
3762159047fSniklas { /* bfd_set_format */
3772159047fSniklas bfd_false,
3782159047fSniklas binary_mkobject,
3792159047fSniklas bfd_false,
3802159047fSniklas bfd_false,
3812159047fSniklas },
3822159047fSniklas { /* bfd_write_contents */
3832159047fSniklas bfd_false,
3842159047fSniklas bfd_true,
3852159047fSniklas bfd_false,
3862159047fSniklas bfd_false,
3872159047fSniklas },
3882159047fSniklas
3892159047fSniklas BFD_JUMP_TABLE_GENERIC (binary),
3902159047fSniklas BFD_JUMP_TABLE_COPY (_bfd_generic),
3912159047fSniklas BFD_JUMP_TABLE_CORE (_bfd_nocore),
3922159047fSniklas BFD_JUMP_TABLE_ARCHIVE (_bfd_noarchive),
3932159047fSniklas BFD_JUMP_TABLE_SYMBOLS (binary),
3942159047fSniklas BFD_JUMP_TABLE_RELOCS (binary),
3952159047fSniklas BFD_JUMP_TABLE_WRITE (binary),
3962159047fSniklas BFD_JUMP_TABLE_LINK (binary),
3972159047fSniklas BFD_JUMP_TABLE_DYNAMIC (_bfd_nodynamic),
3982159047fSniklas
399b305b0f1Sespie NULL,
400b305b0f1Sespie
4012159047fSniklas NULL
4022159047fSniklas };
403