133965Sjdp/* BFD back-end for binary objects.
2218822Sdim   Copyright 1994, 1995, 1996, 1997, 1998, 1999, 2000, 2001, 2002, 2003,
3218822Sdim   2004, 2005, 2006, 2007 Free Software Foundation, Inc.
433965Sjdp   Written by Ian Lance Taylor, Cygnus Support, <ian@cygnus.com>
533965Sjdp
6130561Sobrien   This file is part of BFD, the Binary File Descriptor library.
733965Sjdp
8130561Sobrien   This program is free software; you can redistribute it and/or modify
9130561Sobrien   it under the terms of the GNU General Public License as published by
10130561Sobrien   the Free Software Foundation; either version 2 of the License, or
11130561Sobrien   (at your option) any later version.
1233965Sjdp
13130561Sobrien   This program is distributed in the hope that it will be useful,
14130561Sobrien   but WITHOUT ANY WARRANTY; without even the implied warranty of
15130561Sobrien   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
16130561Sobrien   GNU General Public License for more details.
1733965Sjdp
18130561Sobrien   You should have received a copy of the GNU General Public License
19130561Sobrien   along with this program; if not, write to the Free Software
20218822Sdim   Foundation, Inc., 51 Franklin Street - Fifth Floor, Boston, MA 02110-1301, USA.  */
2133965Sjdp
2233965Sjdp/* This is a BFD backend which may be used to write binary objects.
2333965Sjdp   It may only be used for output, not input.  The intention is that
2433965Sjdp   this may be used as an output format for objcopy in order to
2533965Sjdp   generate raw binary data.
2633965Sjdp
2733965Sjdp   This is very simple.  The only complication is that the real data
2833965Sjdp   will start at some address X, and in some cases we will not want to
2933965Sjdp   include X zeroes just to get to that point.  Since the start
3033965Sjdp   address is not meaningful for this object file format, we use it
3133965Sjdp   instead to indicate the number of zeroes to skip at the start of
3233965Sjdp   the file.  objcopy cooperates by specially setting the start
3333965Sjdp   address to zero by default.  */
3433965Sjdp
35218822Sdim#include "sysdep.h"
3633965Sjdp#include "bfd.h"
3789857Sobrien#include "safe-ctype.h"
3833965Sjdp#include "libbfd.h"
3933965Sjdp
4033965Sjdp/* Any bfd we create by reading a binary file has three symbols:
4133965Sjdp   a start symbol, an end symbol, and an absolute length symbol.  */
4233965Sjdp#define BIN_SYMS 3
4333965Sjdp
44130561Sobrien/* Set by external programs - specifies the BFD architecture and
45130561Sobrien   machine number to be uses when creating binary BFDs.  */
46130561Sobrienenum bfd_architecture  bfd_external_binary_architecture = bfd_arch_unknown;
47130561Sobrienunsigned long          bfd_external_machine = 0;
4889857Sobrien
4933965Sjdp/* Create a binary object.  Invoked via bfd_set_format.  */
5033965Sjdp
51130561Sobrienstatic bfd_boolean
52218822Sdimbinary_mkobject (bfd *abfd ATTRIBUTE_UNUSED)
5333965Sjdp{
54130561Sobrien  return TRUE;
5533965Sjdp}
5633965Sjdp
5733965Sjdp/* Any file may be considered to be a binary file, provided the target
5833965Sjdp   was not defaulted.  That is, it must be explicitly specified as
5933965Sjdp   being binary.  */
6033965Sjdp
6133965Sjdpstatic const bfd_target *
62218822Sdimbinary_object_p (bfd *abfd)
6333965Sjdp{
6433965Sjdp  struct stat statbuf;
6533965Sjdp  asection *sec;
66218822Sdim  flagword flags;
6733965Sjdp
6833965Sjdp  if (abfd->target_defaulted)
6933965Sjdp    {
7033965Sjdp      bfd_set_error (bfd_error_wrong_format);
7133965Sjdp      return NULL;
7233965Sjdp    }
7333965Sjdp
7433965Sjdp  abfd->symcount = BIN_SYMS;
7533965Sjdp
7633965Sjdp  /* Find the file size.  */
7733965Sjdp  if (bfd_stat (abfd, &statbuf) < 0)
7833965Sjdp    {
7933965Sjdp      bfd_set_error (bfd_error_system_call);
8033965Sjdp      return NULL;
8133965Sjdp    }
8233965Sjdp
8333965Sjdp  /* One data section.  */
84218822Sdim  flags = SEC_ALLOC | SEC_LOAD | SEC_DATA | SEC_HAS_CONTENTS;
85218822Sdim  sec = bfd_make_section_with_flags (abfd, ".data", flags);
8633965Sjdp  if (sec == NULL)
8733965Sjdp    return NULL;
8833965Sjdp  sec->vma = 0;
89218822Sdim  sec->size = statbuf.st_size;
9033965Sjdp  sec->filepos = 0;
9133965Sjdp
92218822Sdim  abfd->tdata.any = (void *) sec;
9333965Sjdp
9489857Sobrien  if (bfd_get_arch_info (abfd) != NULL)
9589857Sobrien    {
9689857Sobrien      if ((bfd_get_arch_info (abfd)->arch == bfd_arch_unknown)
9789857Sobrien          && (bfd_external_binary_architecture != bfd_arch_unknown))
98130561Sobrien        bfd_set_arch_info (abfd, bfd_lookup_arch
99130561Sobrien			   (bfd_external_binary_architecture, bfd_external_machine));
10089857Sobrien    }
10189857Sobrien
10233965Sjdp  return abfd->xvec;
10333965Sjdp}
10433965Sjdp
105218822Sdim#define binary_close_and_cleanup     _bfd_generic_close_and_cleanup
106218822Sdim#define binary_bfd_free_cached_info  _bfd_generic_bfd_free_cached_info
107218822Sdim#define binary_new_section_hook      _bfd_generic_new_section_hook
10833965Sjdp
10933965Sjdp/* Get contents of the only section.  */
11033965Sjdp
111130561Sobrienstatic bfd_boolean
112218822Sdimbinary_get_section_contents (bfd *abfd,
113218822Sdim			     asection *section ATTRIBUTE_UNUSED,
114218822Sdim			     void * location,
115218822Sdim			     file_ptr offset,
116218822Sdim			     bfd_size_type count)
11733965Sjdp{
11833965Sjdp  if (bfd_seek (abfd, offset, SEEK_SET) != 0
11989857Sobrien      || bfd_bread (location, count, abfd) != count)
120130561Sobrien    return FALSE;
121130561Sobrien  return TRUE;
12233965Sjdp}
12333965Sjdp
12433965Sjdp/* Return the amount of memory needed to read the symbol table.  */
12533965Sjdp
12633965Sjdpstatic long
127218822Sdimbinary_get_symtab_upper_bound (bfd *abfd ATTRIBUTE_UNUSED)
12833965Sjdp{
12933965Sjdp  return (BIN_SYMS + 1) * sizeof (asymbol *);
13033965Sjdp}
13133965Sjdp
13233965Sjdp/* Create a symbol name based on the bfd's filename.  */
13333965Sjdp
13433965Sjdpstatic char *
135218822Sdimmangle_name (bfd *abfd, char *suffix)
13633965Sjdp{
13789857Sobrien  bfd_size_type size;
13833965Sjdp  char *buf;
13933965Sjdp  char *p;
14033965Sjdp
14133965Sjdp  size = (strlen (bfd_get_filename (abfd))
14233965Sjdp	  + strlen (suffix)
14333965Sjdp	  + sizeof "_binary__");
14433965Sjdp
145218822Sdim  buf = bfd_alloc (abfd, size);
14633965Sjdp  if (buf == NULL)
14733965Sjdp    return "";
14833965Sjdp
14933965Sjdp  sprintf (buf, "_binary_%s_%s", bfd_get_filename (abfd), suffix);
15033965Sjdp
15133965Sjdp  /* Change any non-alphanumeric characters to underscores.  */
15233965Sjdp  for (p = buf; *p; p++)
15389857Sobrien    if (! ISALNUM (*p))
15433965Sjdp      *p = '_';
15533965Sjdp
15633965Sjdp  return buf;
15733965Sjdp}
15833965Sjdp
15933965Sjdp/* Return the symbol table.  */
16033965Sjdp
16133965Sjdpstatic long
162218822Sdimbinary_canonicalize_symtab (bfd *abfd, asymbol **alocation)
16333965Sjdp{
16433965Sjdp  asection *sec = (asection *) abfd->tdata.any;
16533965Sjdp  asymbol *syms;
16633965Sjdp  unsigned int i;
16789857Sobrien  bfd_size_type amt = BIN_SYMS * sizeof (asymbol);
16833965Sjdp
169218822Sdim  syms = bfd_alloc (abfd, amt);
17033965Sjdp  if (syms == NULL)
171130561Sobrien    return 0;
17233965Sjdp
17333965Sjdp  /* Start symbol.  */
17433965Sjdp  syms[0].the_bfd = abfd;
17533965Sjdp  syms[0].name = mangle_name (abfd, "start");
17633965Sjdp  syms[0].value = 0;
17733965Sjdp  syms[0].flags = BSF_GLOBAL;
17833965Sjdp  syms[0].section = sec;
17933965Sjdp  syms[0].udata.p = NULL;
18033965Sjdp
18133965Sjdp  /* End symbol.  */
18233965Sjdp  syms[1].the_bfd = abfd;
18333965Sjdp  syms[1].name = mangle_name (abfd, "end");
184218822Sdim  syms[1].value = sec->size;
18533965Sjdp  syms[1].flags = BSF_GLOBAL;
18633965Sjdp  syms[1].section = sec;
18733965Sjdp  syms[1].udata.p = NULL;
18833965Sjdp
18933965Sjdp  /* Size symbol.  */
19033965Sjdp  syms[2].the_bfd = abfd;
19133965Sjdp  syms[2].name = mangle_name (abfd, "size");
192218822Sdim  syms[2].value = sec->size;
19333965Sjdp  syms[2].flags = BSF_GLOBAL;
19433965Sjdp  syms[2].section = bfd_abs_section_ptr;
19533965Sjdp  syms[2].udata.p = NULL;
19633965Sjdp
19733965Sjdp  for (i = 0; i < BIN_SYMS; i++)
19833965Sjdp    *alocation++ = syms++;
19933965Sjdp  *alocation = NULL;
20033965Sjdp
20133965Sjdp  return BIN_SYMS;
20233965Sjdp}
20333965Sjdp
204218822Sdim#define binary_make_empty_symbol  _bfd_generic_make_empty_symbol
205218822Sdim#define binary_print_symbol       _bfd_nosymbols_print_symbol
20633965Sjdp
20733965Sjdp/* Get information about a symbol.  */
20833965Sjdp
20933965Sjdpstatic void
210218822Sdimbinary_get_symbol_info (bfd *ignore_abfd ATTRIBUTE_UNUSED,
211218822Sdim			asymbol *symbol,
212218822Sdim			symbol_info *ret)
21333965Sjdp{
21433965Sjdp  bfd_symbol_info (symbol, ret);
21533965Sjdp}
21633965Sjdp
217218822Sdim#define binary_bfd_is_local_label_name      bfd_generic_is_local_label_name
218218822Sdim#define binary_get_lineno                  _bfd_nosymbols_get_lineno
219218822Sdim#define binary_find_nearest_line           _bfd_nosymbols_find_nearest_line
220218822Sdim#define binary_find_inliner_info           _bfd_nosymbols_find_inliner_info
221218822Sdim#define binary_bfd_make_debug_symbol       _bfd_nosymbols_bfd_make_debug_symbol
222218822Sdim#define binary_read_minisymbols            _bfd_generic_read_minisymbols
223218822Sdim#define binary_minisymbol_to_symbol        _bfd_generic_minisymbol_to_symbol
224218822Sdim#define binary_bfd_is_target_special_symbol ((bfd_boolean (*) (bfd *, asymbol *)) bfd_false)
22533965Sjdp
22633965Sjdp/* Set the architecture of a binary file.  */
22733965Sjdp#define binary_set_arch_mach _bfd_generic_set_arch_mach
22833965Sjdp
22933965Sjdp/* Write section contents of a binary file.  */
23033965Sjdp
231130561Sobrienstatic bfd_boolean
232218822Sdimbinary_set_section_contents (bfd *abfd,
233218822Sdim			     asection *sec,
234218822Sdim			     const void * data,
235218822Sdim			     file_ptr offset,
236218822Sdim			     bfd_size_type size)
23733965Sjdp{
23877298Sobrien  if (size == 0)
239130561Sobrien    return TRUE;
24077298Sobrien
24133965Sjdp  if (! abfd->output_has_begun)
24233965Sjdp    {
243130561Sobrien      bfd_boolean found_low;
24433965Sjdp      bfd_vma low;
24533965Sjdp      asection *s;
24633965Sjdp
24733965Sjdp      /* The lowest section LMA sets the virtual address of the start
24833965Sjdp         of the file.  We use this to set the file position of all the
24933965Sjdp         sections.  */
250130561Sobrien      found_low = FALSE;
25133965Sjdp      low = 0;
25233965Sjdp      for (s = abfd->sections; s != NULL; s = s->next)
25360484Sobrien	if (((s->flags
25460484Sobrien	      & (SEC_HAS_CONTENTS | SEC_LOAD | SEC_ALLOC | SEC_NEVER_LOAD))
25533965Sjdp	     == (SEC_HAS_CONTENTS | SEC_LOAD | SEC_ALLOC))
256218822Sdim	    && (s->size > 0)
25733965Sjdp	    && (! found_low || s->lma < low))
25833965Sjdp	  {
25933965Sjdp	    low = s->lma;
260130561Sobrien	    found_low = TRUE;
26133965Sjdp	  }
26233965Sjdp
26333965Sjdp      for (s = abfd->sections; s != NULL; s = s->next)
26460484Sobrien	{
26560484Sobrien	  s->filepos = s->lma - low;
26633965Sjdp
26760484Sobrien	  /* Skip following warning check for sections that will not
26877298Sobrien	     occupy file space.  */
26960484Sobrien	  if ((s->flags
27060484Sobrien	       & (SEC_HAS_CONTENTS | SEC_ALLOC | SEC_NEVER_LOAD))
27177298Sobrien	      != (SEC_HAS_CONTENTS | SEC_ALLOC)
272218822Sdim	      || (s->size == 0))
27360484Sobrien	    continue;
27460484Sobrien
27560484Sobrien	  /* If attempting to generate a binary file from a bfd with
27660484Sobrien	     LMA's all over the place, huge (sparse?) binary files may
27760484Sobrien	     result.  This condition attempts to detect this situation
27860484Sobrien	     and print a warning.  Better heuristics would be nice to
27977298Sobrien	     have.  */
28060484Sobrien
28160484Sobrien	  if (s->filepos < 0)
28260484Sobrien	    (*_bfd_error_handler)
28360484Sobrien	      (_("Warning: Writing section `%s' to huge (ie negative) file offset 0x%lx."),
28460484Sobrien	       bfd_get_section_name (abfd, s),
28560484Sobrien	       (unsigned long) s->filepos);
28660484Sobrien	}
28760484Sobrien
288130561Sobrien      abfd->output_has_begun = TRUE;
28933965Sjdp    }
29033965Sjdp
29160484Sobrien  /* We don't want to output anything for a section that is neither
29260484Sobrien     loaded nor allocated.  The contents of such a section are not
29360484Sobrien     meaningful in the binary format.  */
29460484Sobrien  if ((sec->flags & (SEC_LOAD | SEC_ALLOC)) == 0)
295130561Sobrien    return TRUE;
29660484Sobrien  if ((sec->flags & SEC_NEVER_LOAD) != 0)
297130561Sobrien    return TRUE;
29860484Sobrien
29933965Sjdp  return _bfd_generic_set_section_contents (abfd, sec, data, offset, size);
30033965Sjdp}
30133965Sjdp
30233965Sjdp/* No space is required for header information.  */
30333965Sjdp
30433965Sjdpstatic int
305218822Sdimbinary_sizeof_headers (bfd *abfd ATTRIBUTE_UNUSED,
306218822Sdim		       struct bfd_link_info *info ATTRIBUTE_UNUSED)
30733965Sjdp{
30833965Sjdp  return 0;
30933965Sjdp}
31033965Sjdp
311218822Sdim#define binary_bfd_get_relocated_section_contents  bfd_generic_get_relocated_section_contents
312218822Sdim#define binary_bfd_relax_section                   bfd_generic_relax_section
313218822Sdim#define binary_bfd_gc_sections                     bfd_generic_gc_sections
314218822Sdim#define binary_bfd_merge_sections                  bfd_generic_merge_sections
315218822Sdim#define binary_bfd_is_group_section                bfd_generic_is_group_section
316218822Sdim#define binary_bfd_discard_group                   bfd_generic_discard_group
317218822Sdim#define binary_section_already_linked             _bfd_generic_section_already_linked
318218822Sdim#define binary_bfd_link_hash_table_create         _bfd_generic_link_hash_table_create
319218822Sdim#define binary_bfd_link_hash_table_free           _bfd_generic_link_hash_table_free
320218822Sdim#define binary_bfd_link_just_syms                 _bfd_generic_link_just_syms
321218822Sdim#define binary_bfd_link_add_symbols               _bfd_generic_link_add_symbols
322218822Sdim#define binary_bfd_final_link                     _bfd_generic_final_link
323218822Sdim#define binary_bfd_link_split_section             _bfd_generic_link_split_section
324218822Sdim#define binary_get_section_contents_in_window     _bfd_generic_get_section_contents_in_window
32533965Sjdp
32633965Sjdpconst bfd_target binary_vec =
32733965Sjdp{
32833965Sjdp  "binary",			/* name */
32933965Sjdp  bfd_target_unknown_flavour,	/* flavour */
33033965Sjdp  BFD_ENDIAN_UNKNOWN,		/* byteorder */
33133965Sjdp  BFD_ENDIAN_UNKNOWN,		/* header_byteorder */
33233965Sjdp  EXEC_P,			/* object_flags */
33333965Sjdp  (SEC_ALLOC | SEC_LOAD | SEC_READONLY | SEC_CODE | SEC_DATA
33433965Sjdp   | SEC_ROM | SEC_HAS_CONTENTS), /* section_flags */
33533965Sjdp  0,				/* symbol_leading_char */
33633965Sjdp  ' ',				/* ar_pad_char */
33733965Sjdp  16,				/* ar_max_namelen */
33833965Sjdp  bfd_getb64, bfd_getb_signed_64, bfd_putb64,
33933965Sjdp  bfd_getb32, bfd_getb_signed_32, bfd_putb32,
34033965Sjdp  bfd_getb16, bfd_getb_signed_16, bfd_putb16,	/* data */
34133965Sjdp  bfd_getb64, bfd_getb_signed_64, bfd_putb64,
34233965Sjdp  bfd_getb32, bfd_getb_signed_32, bfd_putb32,
34333965Sjdp  bfd_getb16, bfd_getb_signed_16, bfd_putb16,	/* hdrs */
34433965Sjdp  {				/* bfd_check_format */
34533965Sjdp    _bfd_dummy_target,
346218822Sdim    binary_object_p,
34733965Sjdp    _bfd_dummy_target,
34833965Sjdp    _bfd_dummy_target,
34933965Sjdp  },
35033965Sjdp  {				/* bfd_set_format */
35133965Sjdp    bfd_false,
35233965Sjdp    binary_mkobject,
35333965Sjdp    bfd_false,
35433965Sjdp    bfd_false,
35533965Sjdp  },
35633965Sjdp  {				/* bfd_write_contents */
35733965Sjdp    bfd_false,
35833965Sjdp    bfd_true,
35933965Sjdp    bfd_false,
36033965Sjdp    bfd_false,
36133965Sjdp  },
36233965Sjdp
36333965Sjdp  BFD_JUMP_TABLE_GENERIC (binary),
36433965Sjdp  BFD_JUMP_TABLE_COPY (_bfd_generic),
36533965Sjdp  BFD_JUMP_TABLE_CORE (_bfd_nocore),
36633965Sjdp  BFD_JUMP_TABLE_ARCHIVE (_bfd_noarchive),
36733965Sjdp  BFD_JUMP_TABLE_SYMBOLS (binary),
368218822Sdim  BFD_JUMP_TABLE_RELOCS (_bfd_norelocs),
36933965Sjdp  BFD_JUMP_TABLE_WRITE (binary),
37033965Sjdp  BFD_JUMP_TABLE_LINK (binary),
37133965Sjdp  BFD_JUMP_TABLE_DYNAMIC (_bfd_nodynamic),
37233965Sjdp
37360484Sobrien  NULL,
37477298Sobrien
37533965Sjdp  NULL
37633965Sjdp};
377