~ubuntu-branches/ubuntu/quantal/gclcvs/quantal

« back to all changes in this revision

Viewing changes to binutils/bfd/binary.c

  • Committer: Bazaar Package Importer
  • Author(s): Camm Maguire
  • Date: 2004-06-24 15:13:46 UTC
  • Revision ID: james.westby@ubuntu.com-20040624151346-xh0xaaktyyp7aorc
Tags: 2.7.0-26
C_GC_OFFSET is 2 on m68k-linux

Show diffs side-by-side

added added

removed removed

Lines of Context:
 
1
/* BFD back-end for binary objects.
 
2
   Copyright 1994, 1995, 1996, 1997, 1998, 1999, 2000, 2001, 2002
 
3
   Free Software Foundation, Inc.
 
4
   Written by Ian Lance Taylor, Cygnus Support, <ian@cygnus.com>
 
5
 
 
6
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
 
9
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
 
11
(at your option) any later version.
 
12
 
 
13
This program is distributed in the hope that it will be useful,
 
14
but WITHOUT ANY WARRANTY; without even the implied warranty of
 
15
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
 
16
GNU General Public License for more details.
 
17
 
 
18
You should have received a copy of the GNU General Public License
 
19
along with this program; if not, write to the Free Software
 
20
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.
 
23
   It may only be used for output, not input.  The intention is that
 
24
   this may be used as an output format for objcopy in order to
 
25
   generate raw binary data.
 
26
 
 
27
   This is very simple.  The only complication is that the real data
 
28
   will start at some address X, and in some cases we will not want to
 
29
   include X zeroes just to get to that point.  Since the start
 
30
   address is not meaningful for this object file format, we use it
 
31
   instead to indicate the number of zeroes to skip at the start of
 
32
   the file.  objcopy cooperates by specially setting the start
 
33
   address to zero by default.  */
 
34
 
 
35
#include "bfd.h"
 
36
#include "sysdep.h"
 
37
#include "safe-ctype.h"
 
38
#include "libbfd.h"
 
39
 
 
40
/* Any bfd we create by reading a binary file has three symbols:
 
41
   a start symbol, an end symbol, and an absolute length symbol.  */
 
42
#define BIN_SYMS 3
 
43
 
 
44
static boolean binary_mkobject PARAMS ((bfd *));
 
45
static const bfd_target *binary_object_p PARAMS ((bfd *));
 
46
static boolean binary_get_section_contents
 
47
  PARAMS ((bfd *, asection *, PTR, file_ptr, bfd_size_type));
 
48
static long binary_get_symtab_upper_bound PARAMS ((bfd *));
 
49
static char *mangle_name PARAMS ((bfd *, char *));
 
50
static long binary_get_symtab PARAMS ((bfd *, asymbol **));
 
51
static void binary_get_symbol_info PARAMS ((bfd *, asymbol *, symbol_info *));
 
52
static boolean binary_set_section_contents
 
53
  PARAMS ((bfd *, asection *, PTR, file_ptr, bfd_size_type));
 
54
static int binary_sizeof_headers PARAMS ((bfd *, boolean));
 
55
 
 
56
/* Set by external programs - specifies the BFD architecture
 
57
   to use when creating binary BFDs.  */
 
58
enum bfd_architecture bfd_external_binary_architecture = bfd_arch_unknown;
 
59
 
 
60
/* Create a binary object.  Invoked via bfd_set_format.  */
 
61
 
 
62
static boolean
 
63
binary_mkobject (abfd)
 
64
     bfd *abfd ATTRIBUTE_UNUSED;
 
65
{
 
66
  return true;
 
67
}
 
68
 
 
69
/* Any file may be considered to be a binary file, provided the target
 
70
   was not defaulted.  That is, it must be explicitly specified as
 
71
   being binary.  */
 
72
 
 
73
static const bfd_target *
 
74
binary_object_p (abfd)
 
75
     bfd *abfd;
 
76
{
 
77
  struct stat statbuf;
 
78
  asection *sec;
 
79
 
 
80
  if (abfd->target_defaulted)
 
81
    {
 
82
      bfd_set_error (bfd_error_wrong_format);
 
83
      return NULL;
 
84
    }
 
85
 
 
86
  abfd->symcount = BIN_SYMS;
 
87
 
 
88
  /* Find the file size.  */
 
89
  if (bfd_stat (abfd, &statbuf) < 0)
 
90
    {
 
91
      bfd_set_error (bfd_error_system_call);
 
92
      return NULL;
 
93
    }
 
94
 
 
95
  /* One data section.  */
 
96
  sec = bfd_make_section (abfd, ".data");
 
97
  if (sec == NULL)
 
98
    return NULL;
 
99
  sec->flags = SEC_ALLOC | SEC_LOAD | SEC_DATA | SEC_HAS_CONTENTS;
 
100
  sec->vma = 0;
 
101
  sec->_raw_size = statbuf.st_size;
 
102
  sec->filepos = 0;
 
103
 
 
104
  abfd->tdata.any = (PTR) sec;
 
105
 
 
106
  if (bfd_get_arch_info (abfd) != NULL)
 
107
    {
 
108
      if ((bfd_get_arch_info (abfd)->arch == bfd_arch_unknown)
 
109
          && (bfd_external_binary_architecture != bfd_arch_unknown))
 
110
        bfd_set_arch_info (abfd, bfd_lookup_arch (bfd_external_binary_architecture, 0));
 
111
    }
 
112
 
 
113
  return abfd->xvec;
 
114
}
 
115
 
 
116
#define binary_close_and_cleanup _bfd_generic_close_and_cleanup
 
117
#define binary_bfd_free_cached_info _bfd_generic_bfd_free_cached_info
 
118
#define binary_new_section_hook _bfd_generic_new_section_hook
 
119
 
 
120
/* Get contents of the only section.  */
 
121
 
 
122
static boolean
 
123
binary_get_section_contents (abfd, section, location, offset, count)
 
124
     bfd *abfd;
 
125
     asection *section ATTRIBUTE_UNUSED;
 
126
     PTR location;
 
127
     file_ptr offset;
 
128
     bfd_size_type count;
 
129
{
 
130
  if (bfd_seek (abfd, offset, SEEK_SET) != 0
 
131
      || bfd_bread (location, count, abfd) != count)
 
132
    return false;
 
133
  return true;
 
134
}
 
135
 
 
136
/* Return the amount of memory needed to read the symbol table.  */
 
137
 
 
138
static long
 
139
binary_get_symtab_upper_bound (abfd)
 
140
     bfd *abfd ATTRIBUTE_UNUSED;
 
141
{
 
142
  return (BIN_SYMS + 1) * sizeof (asymbol *);
 
143
}
 
144
 
 
145
/* Create a symbol name based on the bfd's filename.  */
 
146
 
 
147
static char *
 
148
mangle_name (abfd, suffix)
 
149
     bfd *abfd;
 
150
     char *suffix;
 
151
{
 
152
  bfd_size_type size;
 
153
  char *buf;
 
154
  char *p;
 
155
 
 
156
  size = (strlen (bfd_get_filename (abfd))
 
157
          + strlen (suffix)
 
158
          + sizeof "_binary__");
 
159
 
 
160
  buf = (char *) bfd_alloc (abfd, size);
 
161
  if (buf == NULL)
 
162
    return "";
 
163
 
 
164
  sprintf (buf, "_binary_%s_%s", bfd_get_filename (abfd), suffix);
 
165
 
 
166
  /* Change any non-alphanumeric characters to underscores.  */
 
167
  for (p = buf; *p; p++)
 
168
    if (! ISALNUM (*p))
 
169
      *p = '_';
 
170
 
 
171
  return buf;
 
172
}
 
173
 
 
174
/* Return the symbol table.  */
 
175
 
 
176
static long
 
177
binary_get_symtab (abfd, alocation)
 
178
     bfd *abfd;
 
179
     asymbol **alocation;
 
180
{
 
181
  asection *sec = (asection *) abfd->tdata.any;
 
182
  asymbol *syms;
 
183
  unsigned int i;
 
184
  bfd_size_type amt = BIN_SYMS * sizeof (asymbol);
 
185
 
 
186
  syms = (asymbol *) bfd_alloc (abfd, amt);
 
187
  if (syms == NULL)
 
188
    return false;
 
189
 
 
190
  /* Start symbol.  */
 
191
  syms[0].the_bfd = abfd;
 
192
  syms[0].name = mangle_name (abfd, "start");
 
193
  syms[0].value = 0;
 
194
  syms[0].flags = BSF_GLOBAL;
 
195
  syms[0].section = sec;
 
196
  syms[0].udata.p = NULL;
 
197
 
 
198
  /* End symbol.  */
 
199
  syms[1].the_bfd = abfd;
 
200
  syms[1].name = mangle_name (abfd, "end");
 
201
  syms[1].value = sec->_raw_size;
 
202
  syms[1].flags = BSF_GLOBAL;
 
203
  syms[1].section = sec;
 
204
  syms[1].udata.p = NULL;
 
205
 
 
206
  /* Size symbol.  */
 
207
  syms[2].the_bfd = abfd;
 
208
  syms[2].name = mangle_name (abfd, "size");
 
209
  syms[2].value = sec->_raw_size;
 
210
  syms[2].flags = BSF_GLOBAL;
 
211
  syms[2].section = bfd_abs_section_ptr;
 
212
  syms[2].udata.p = NULL;
 
213
 
 
214
  for (i = 0; i < BIN_SYMS; i++)
 
215
    *alocation++ = syms++;
 
216
  *alocation = NULL;
 
217
 
 
218
  return BIN_SYMS;
 
219
}
 
220
 
 
221
#define binary_make_empty_symbol _bfd_generic_make_empty_symbol
 
222
#define binary_print_symbol _bfd_nosymbols_print_symbol
 
223
 
 
224
/* Get information about a symbol.  */
 
225
 
 
226
static void
 
227
binary_get_symbol_info (ignore_abfd, symbol, ret)
 
228
     bfd *ignore_abfd ATTRIBUTE_UNUSED;
 
229
     asymbol *symbol;
 
230
     symbol_info *ret;
 
231
{
 
232
  bfd_symbol_info (symbol, ret);
 
233
}
 
234
 
 
235
#define binary_bfd_is_local_label_name bfd_generic_is_local_label_name
 
236
#define binary_get_lineno _bfd_nosymbols_get_lineno
 
237
#define binary_find_nearest_line _bfd_nosymbols_find_nearest_line
 
238
#define binary_bfd_make_debug_symbol _bfd_nosymbols_bfd_make_debug_symbol
 
239
#define binary_read_minisymbols _bfd_generic_read_minisymbols
 
240
#define binary_minisymbol_to_symbol _bfd_generic_minisymbol_to_symbol
 
241
 
 
242
#define binary_get_reloc_upper_bound \
 
243
  ((long (*) PARAMS ((bfd *, asection *))) bfd_0l)
 
244
#define binary_canonicalize_reloc \
 
245
  ((long (*) PARAMS ((bfd *, asection *, arelent **, asymbol **))) bfd_0l)
 
246
#define binary_bfd_reloc_type_lookup _bfd_norelocs_bfd_reloc_type_lookup
 
247
 
 
248
/* Set the architecture of a binary file.  */
 
249
#define binary_set_arch_mach _bfd_generic_set_arch_mach
 
250
 
 
251
/* Write section contents of a binary file.  */
 
252
 
 
253
static boolean
 
254
binary_set_section_contents (abfd, sec, data, offset, size)
 
255
     bfd *abfd;
 
256
     asection *sec;
 
257
     PTR data;
 
258
     file_ptr offset;
 
259
     bfd_size_type size;
 
260
{
 
261
  if (size == 0)
 
262
    return true;
 
263
 
 
264
  if (! abfd->output_has_begun)
 
265
    {
 
266
      boolean found_low;
 
267
      bfd_vma low;
 
268
      asection *s;
 
269
 
 
270
      /* The lowest section LMA sets the virtual address of the start
 
271
         of the file.  We use this to set the file position of all the
 
272
         sections.  */
 
273
      found_low = false;
 
274
      low = 0;
 
275
      for (s = abfd->sections; s != NULL; s = s->next)
 
276
        if (((s->flags
 
277
              & (SEC_HAS_CONTENTS | SEC_LOAD | SEC_ALLOC | SEC_NEVER_LOAD))
 
278
             == (SEC_HAS_CONTENTS | SEC_LOAD | SEC_ALLOC))
 
279
            && (s->_raw_size > 0)
 
280
            && (! found_low || s->lma < low))
 
281
          {
 
282
            low = s->lma;
 
283
            found_low = true;
 
284
          }
 
285
 
 
286
      for (s = abfd->sections; s != NULL; s = s->next)
 
287
        {
 
288
          s->filepos = s->lma - low;
 
289
 
 
290
          /* Skip following warning check for sections that will not
 
291
             occupy file space.  */
 
292
          if ((s->flags
 
293
               & (SEC_HAS_CONTENTS | SEC_ALLOC | SEC_NEVER_LOAD))
 
294
              != (SEC_HAS_CONTENTS | SEC_ALLOC)
 
295
              || (s->_raw_size == 0))
 
296
            continue;
 
297
 
 
298
          /* If attempting to generate a binary file from a bfd with
 
299
             LMA's all over the place, huge (sparse?) binary files may
 
300
             result.  This condition attempts to detect this situation
 
301
             and print a warning.  Better heuristics would be nice to
 
302
             have.  */
 
303
 
 
304
          if (s->filepos < 0)
 
305
            (*_bfd_error_handler)
 
306
              (_("Warning: Writing section `%s' to huge (ie negative) file offset 0x%lx."),
 
307
               bfd_get_section_name (abfd, s),
 
308
               (unsigned long) s->filepos);
 
309
        }
 
310
 
 
311
      abfd->output_has_begun = true;
 
312
    }
 
313
 
 
314
  /* We don't want to output anything for a section that is neither
 
315
     loaded nor allocated.  The contents of such a section are not
 
316
     meaningful in the binary format.  */
 
317
  if ((sec->flags & (SEC_LOAD | SEC_ALLOC)) == 0)
 
318
    return true;
 
319
  if ((sec->flags & SEC_NEVER_LOAD) != 0)
 
320
    return true;
 
321
 
 
322
  return _bfd_generic_set_section_contents (abfd, sec, data, offset, size);
 
323
}
 
324
 
 
325
/* No space is required for header information.  */
 
326
 
 
327
static int
 
328
binary_sizeof_headers (abfd, exec)
 
329
     bfd *abfd ATTRIBUTE_UNUSED;
 
330
     boolean exec ATTRIBUTE_UNUSED;
 
331
{
 
332
  return 0;
 
333
}
 
334
 
 
335
#define binary_bfd_get_relocated_section_contents \
 
336
  bfd_generic_get_relocated_section_contents
 
337
#define binary_bfd_relax_section bfd_generic_relax_section
 
338
#define binary_bfd_gc_sections bfd_generic_gc_sections
 
339
#define binary_bfd_merge_sections bfd_generic_merge_sections
 
340
#define binary_bfd_discard_group bfd_generic_discard_group
 
341
#define binary_bfd_link_hash_table_create _bfd_generic_link_hash_table_create
 
342
#define binary_bfd_link_hash_table_free _bfd_generic_link_hash_table_free
 
343
#define binary_bfd_link_just_syms _bfd_generic_link_just_syms
 
344
#define binary_bfd_link_add_symbols _bfd_generic_link_add_symbols
 
345
#define binary_bfd_final_link _bfd_generic_final_link
 
346
#define binary_bfd_link_split_section _bfd_generic_link_split_section
 
347
#define binary_get_section_contents_in_window \
 
348
  _bfd_generic_get_section_contents_in_window
 
349
 
 
350
const bfd_target binary_vec =
 
351
{
 
352
  "binary",                     /* name */
 
353
  bfd_target_unknown_flavour,   /* flavour */
 
354
  BFD_ENDIAN_UNKNOWN,           /* byteorder */
 
355
  BFD_ENDIAN_UNKNOWN,           /* header_byteorder */
 
356
  EXEC_P,                       /* object_flags */
 
357
  (SEC_ALLOC | SEC_LOAD | SEC_READONLY | SEC_CODE | SEC_DATA
 
358
   | SEC_ROM | SEC_HAS_CONTENTS), /* section_flags */
 
359
  0,                            /* symbol_leading_char */
 
360
  ' ',                          /* ar_pad_char */
 
361
  16,                           /* ar_max_namelen */
 
362
  bfd_getb64, bfd_getb_signed_64, bfd_putb64,
 
363
  bfd_getb32, bfd_getb_signed_32, bfd_putb32,
 
364
  bfd_getb16, bfd_getb_signed_16, bfd_putb16,   /* data */
 
365
  bfd_getb64, bfd_getb_signed_64, bfd_putb64,
 
366
  bfd_getb32, bfd_getb_signed_32, bfd_putb32,
 
367
  bfd_getb16, bfd_getb_signed_16, bfd_putb16,   /* hdrs */
 
368
  {                             /* bfd_check_format */
 
369
    _bfd_dummy_target,
 
370
    binary_object_p,            /* bfd_check_format */
 
371
    _bfd_dummy_target,
 
372
    _bfd_dummy_target,
 
373
  },
 
374
  {                             /* bfd_set_format */
 
375
    bfd_false,
 
376
    binary_mkobject,
 
377
    bfd_false,
 
378
    bfd_false,
 
379
  },
 
380
  {                             /* bfd_write_contents */
 
381
    bfd_false,
 
382
    bfd_true,
 
383
    bfd_false,
 
384
    bfd_false,
 
385
  },
 
386
 
 
387
  BFD_JUMP_TABLE_GENERIC (binary),
 
388
  BFD_JUMP_TABLE_COPY (_bfd_generic),
 
389
  BFD_JUMP_TABLE_CORE (_bfd_nocore),
 
390
  BFD_JUMP_TABLE_ARCHIVE (_bfd_noarchive),
 
391
  BFD_JUMP_TABLE_SYMBOLS (binary),
 
392
  BFD_JUMP_TABLE_RELOCS (binary),
 
393
  BFD_JUMP_TABLE_WRITE (binary),
 
394
  BFD_JUMP_TABLE_LINK (binary),
 
395
  BFD_JUMP_TABLE_DYNAMIC (_bfd_nodynamic),
 
396
 
 
397
  NULL,
 
398
 
 
399
  NULL
 
400
};