OpenCores
URL https://opencores.org/ocsvn/openrisc_me/openrisc_me/trunk

Subversion Repositories openrisc_me

[/] [openrisc/] [trunk/] [gnu-src/] [gdb-6.8/] [bfd/] [mach-o.c] - Blame information for rev 24

Go to most recent revision | Details | Compare with Previous | View Log

Line No. Rev Author Line
1 24 jeremybenn
/* Mach-O support for BFD.
2
   Copyright 1999, 2000, 2001, 2002, 2003, 2004, 2005, 2006, 2007, 2008
3
   Free Software Foundation, Inc.
4
 
5
   This file is part of BFD, the Binary File Descriptor library.
6
 
7
   This program is free software; you can redistribute it and/or modify
8
   it under the terms of the GNU General Public License as published by
9
   the Free Software Foundation; either version 3 of the License, or
10
   (at your option) any later version.
11
 
12
   This program is distributed in the hope that it will be useful,
13
   but WITHOUT ANY WARRANTY; without even the implied warranty of
14
   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
15
   GNU General Public License for more details.
16
 
17
   You should have received a copy of the GNU General Public License
18
   along with this program; if not, write to the Free Software
19
   Foundation, Inc., 51 Franklin Street - Fifth Floor, Boston,
20
   MA 02110-1301, USA.  */
21
 
22
#include "sysdep.h"
23
#include "mach-o.h"
24
#include "bfd.h"
25
#include "libbfd.h"
26
#include "libiberty.h"
27
#include <ctype.h>
28
 
29
#ifndef BFD_IO_FUNCS
30
#define BFD_IO_FUNCS 0
31
#endif
32
 
33
#define bfd_mach_o_mkarchive                          _bfd_noarchive_mkarchive
34
#define bfd_mach_o_read_ar_hdr                        _bfd_noarchive_read_ar_hdr
35
#define bfd_mach_o_slurp_armap                        _bfd_noarchive_slurp_armap
36
#define bfd_mach_o_slurp_extended_name_table          _bfd_noarchive_slurp_extended_name_table
37
#define bfd_mach_o_construct_extended_name_table      _bfd_noarchive_construct_extended_name_table
38
#define bfd_mach_o_truncate_arname                    _bfd_noarchive_truncate_arname
39
#define bfd_mach_o_write_armap                        _bfd_noarchive_write_armap
40
#define bfd_mach_o_get_elt_at_index                   _bfd_noarchive_get_elt_at_index
41
#define bfd_mach_o_generic_stat_arch_elt              _bfd_noarchive_generic_stat_arch_elt
42
#define bfd_mach_o_update_armap_timestamp             _bfd_noarchive_update_armap_timestamp
43
#define bfd_mach_o_close_and_cleanup                  _bfd_generic_close_and_cleanup
44
#define bfd_mach_o_bfd_free_cached_info               _bfd_generic_bfd_free_cached_info
45
#define bfd_mach_o_new_section_hook                   _bfd_generic_new_section_hook
46
#define bfd_mach_o_get_section_contents_in_window     _bfd_generic_get_section_contents_in_window
47
#define bfd_mach_o_bfd_is_local_label_name            _bfd_nosymbols_bfd_is_local_label_name
48
#define bfd_mach_o_bfd_is_target_special_symbol       ((bfd_boolean (*) (bfd *, asymbol *)) bfd_false)
49
#define bfd_mach_o_bfd_is_local_label_name            _bfd_nosymbols_bfd_is_local_label_name
50
#define bfd_mach_o_get_lineno                         _bfd_nosymbols_get_lineno
51
#define bfd_mach_o_find_nearest_line                  _bfd_nosymbols_find_nearest_line
52
#define bfd_mach_o_find_inliner_info                  _bfd_nosymbols_find_inliner_info
53
#define bfd_mach_o_bfd_make_debug_symbol              _bfd_nosymbols_bfd_make_debug_symbol
54
#define bfd_mach_o_read_minisymbols                   _bfd_generic_read_minisymbols
55
#define bfd_mach_o_minisymbol_to_symbol               _bfd_generic_minisymbol_to_symbol
56
#define bfd_mach_o_bfd_get_relocated_section_contents bfd_generic_get_relocated_section_contents
57
#define bfd_mach_o_bfd_relax_section                  bfd_generic_relax_section
58
#define bfd_mach_o_bfd_link_hash_table_create         _bfd_generic_link_hash_table_create
59
#define bfd_mach_o_bfd_link_hash_table_free           _bfd_generic_link_hash_table_free
60
#define bfd_mach_o_bfd_link_add_symbols               _bfd_generic_link_add_symbols
61
#define bfd_mach_o_bfd_link_just_syms                 _bfd_generic_link_just_syms
62
#define bfd_mach_o_bfd_final_link                     _bfd_generic_final_link
63
#define bfd_mach_o_bfd_link_split_section             _bfd_generic_link_split_section
64
#define bfd_mach_o_set_arch_mach                      bfd_default_set_arch_mach
65
#define bfd_mach_o_bfd_merge_private_bfd_data         _bfd_generic_bfd_merge_private_bfd_data
66
#define bfd_mach_o_bfd_set_private_flags              _bfd_generic_bfd_set_private_flags
67
#define bfd_mach_o_bfd_print_private_bfd_data         _bfd_generic_bfd_print_private_bfd_data
68
#define bfd_mach_o_get_section_contents               _bfd_generic_get_section_contents
69
#define bfd_mach_o_set_section_contents               _bfd_generic_set_section_contents
70
#define bfd_mach_o_bfd_gc_sections                    bfd_generic_gc_sections
71
#define bfd_mach_o_bfd_merge_sections                 bfd_generic_merge_sections
72
#define bfd_mach_o_bfd_is_group_section               bfd_generic_is_group_section
73
#define bfd_mach_o_bfd_discard_group                  bfd_generic_discard_group
74
#define bfd_mach_o_section_already_linked             _bfd_generic_section_already_linked
75
#define bfd_mach_o_bfd_copy_private_header_data       _bfd_generic_bfd_copy_private_header_data
76
#define bfd_mach_o_core_file_matches_executable_p     generic_core_file_matches_executable_p
77
 
78
 
79
/* The flags field of a section structure is separated into two parts a section
80
   type and section attributes.  The section types are mutually exclusive (it
81
   can only have one type) but the section attributes are not (it may have more
82
   than one attribute).  */
83
 
84
#define SECTION_TYPE             0x000000ff     /* 256 section types.  */
85
#define SECTION_ATTRIBUTES       0xffffff00     /*  24 section attributes.  */
86
 
87
/* Constants for the section attributes part of the flags field of a section
88
   structure.  */
89
 
90
#define SECTION_ATTRIBUTES_USR   0xff000000     /* User-settable attributes.  */
91
#define S_ATTR_PURE_INSTRUCTIONS 0x80000000     /* Section contains only true machine instructions.  */
92
#define SECTION_ATTRIBUTES_SYS   0x00ffff00     /* System setable attributes.  */
93
#define S_ATTR_SOME_INSTRUCTIONS 0x00000400     /* Section contains some machine instructions.  */
94
#define S_ATTR_EXT_RELOC         0x00000200     /* Section has external relocation entries.  */
95
#define S_ATTR_LOC_RELOC         0x00000100     /* Section has local relocation entries.  */
96
 
97
#define N_STAB 0xe0
98
#define N_TYPE 0x1e
99
#define N_EXT  0x01
100
#define N_UNDF 0x0
101
#define N_ABS  0x2
102
#define N_SECT 0xe
103
#define N_INDR 0xa
104
 
105
bfd_boolean
106
bfd_mach_o_valid (bfd *abfd)
107
{
108
  if (abfd == NULL || abfd->xvec == NULL)
109
    return 0;
110
 
111
  if (! ((abfd->xvec == &mach_o_be_vec)
112
         || (abfd->xvec == &mach_o_le_vec)
113
         || (abfd->xvec == &mach_o_fat_vec)))
114
    return 0;
115
 
116
  if (abfd->tdata.mach_o_data == NULL)
117
    return 0;
118
  return 1;
119
}
120
 
121
/* Copy any private info we understand from the input symbol
122
   to the output symbol.  */
123
 
124
static bfd_boolean
125
bfd_mach_o_bfd_copy_private_symbol_data (bfd *ibfd ATTRIBUTE_UNUSED,
126
                                         asymbol *isymbol ATTRIBUTE_UNUSED,
127
                                         bfd *obfd ATTRIBUTE_UNUSED,
128
                                         asymbol *osymbol ATTRIBUTE_UNUSED)
129
{
130
  return TRUE;
131
}
132
 
133
/* Copy any private info we understand from the input section
134
   to the output section.  */
135
 
136
static bfd_boolean
137
bfd_mach_o_bfd_copy_private_section_data (bfd *ibfd ATTRIBUTE_UNUSED,
138
                                          asection *isection ATTRIBUTE_UNUSED,
139
                                          bfd *obfd ATTRIBUTE_UNUSED,
140
                                          asection *osection ATTRIBUTE_UNUSED)
141
{
142
  return TRUE;
143
}
144
 
145
/* Copy any private info we understand from the input bfd
146
   to the output bfd.  */
147
 
148
static bfd_boolean
149
bfd_mach_o_bfd_copy_private_bfd_data (bfd *ibfd, bfd *obfd)
150
{
151
  BFD_ASSERT (bfd_mach_o_valid (ibfd));
152
  BFD_ASSERT (bfd_mach_o_valid (obfd));
153
 
154
  obfd->tdata.mach_o_data = ibfd->tdata.mach_o_data;
155
  obfd->tdata.mach_o_data->ibfd = ibfd;
156
  return TRUE;
157
}
158
 
159
static long
160
bfd_mach_o_count_symbols (bfd *abfd)
161
{
162
  bfd_mach_o_data_struct *mdata = NULL;
163
  long nsyms = 0;
164
  unsigned long i;
165
 
166
  BFD_ASSERT (bfd_mach_o_valid (abfd));
167
  mdata = abfd->tdata.mach_o_data;
168
 
169
  for (i = 0; i < mdata->header.ncmds; i++)
170
    if (mdata->commands[i].type == BFD_MACH_O_LC_SYMTAB)
171
      {
172
        bfd_mach_o_symtab_command *sym = &mdata->commands[i].command.symtab;
173
        nsyms += sym->nsyms;
174
      }
175
 
176
  return nsyms;
177
}
178
 
179
static long
180
bfd_mach_o_get_symtab_upper_bound (bfd *abfd)
181
{
182
  long nsyms = bfd_mach_o_count_symbols (abfd);
183
 
184
  if (nsyms < 0)
185
    return nsyms;
186
 
187
  return ((nsyms + 1) * sizeof (asymbol *));
188
}
189
 
190
static long
191
bfd_mach_o_canonicalize_symtab (bfd *abfd, asymbol **alocation)
192
{
193
  bfd_mach_o_data_struct *mdata = abfd->tdata.mach_o_data;
194
  long nsyms = bfd_mach_o_count_symbols (abfd);
195
  asymbol **csym = alocation;
196
  unsigned long i, j;
197
 
198
  if (nsyms < 0)
199
    return nsyms;
200
 
201
  for (i = 0; i < mdata->header.ncmds; i++)
202
    {
203
      if (mdata->commands[i].type == BFD_MACH_O_LC_SYMTAB)
204
        {
205
          bfd_mach_o_symtab_command *sym = &mdata->commands[i].command.symtab;
206
 
207
          if (bfd_mach_o_scan_read_symtab_symbols (abfd, &mdata->commands[i].command.symtab) != 0)
208
            {
209
              fprintf (stderr, "bfd_mach_o_canonicalize_symtab: unable to load symbols for section %lu\n", i);
210
              return 0;
211
            }
212
 
213
          BFD_ASSERT (sym->symbols != NULL);
214
 
215
          for (j = 0; j < sym->nsyms; j++)
216
            {
217
              BFD_ASSERT (csym < (alocation + nsyms));
218
              *csym++ = &sym->symbols[j];
219
            }
220
        }
221
    }
222
 
223
  *csym++ = NULL;
224
 
225
  return nsyms;
226
}
227
 
228
static void
229
bfd_mach_o_get_symbol_info (bfd *abfd ATTRIBUTE_UNUSED,
230
                            asymbol *symbol,
231
                            symbol_info *ret)
232
{
233
  bfd_symbol_info (symbol, ret);
234
}
235
 
236
static void
237
bfd_mach_o_print_symbol (bfd *abfd,
238
                         PTR afile,
239
                         asymbol *symbol,
240
                         bfd_print_symbol_type how)
241
{
242
  FILE *file = (FILE *) afile;
243
 
244
  switch (how)
245
    {
246
    case bfd_print_symbol_name:
247
      fprintf (file, "%s", symbol->name);
248
      break;
249
    default:
250
      bfd_print_symbol_vandf (abfd, (PTR) file, symbol);
251
      fprintf (file, " %-5s %s", symbol->section->name, symbol->name);
252
    }
253
}
254
 
255
static void
256
bfd_mach_o_convert_architecture (bfd_mach_o_cpu_type mtype,
257
                                 bfd_mach_o_cpu_subtype msubtype ATTRIBUTE_UNUSED,
258
                                 enum bfd_architecture *type,
259
                                 unsigned long *subtype)
260
{
261
  *subtype = bfd_arch_unknown;
262
 
263
  switch (mtype)
264
    {
265
    case BFD_MACH_O_CPU_TYPE_VAX: *type = bfd_arch_vax; break;
266
    case BFD_MACH_O_CPU_TYPE_MC680x0: *type = bfd_arch_m68k; break;
267
    case BFD_MACH_O_CPU_TYPE_I386: *type = bfd_arch_i386; break;
268
    case BFD_MACH_O_CPU_TYPE_MIPS: *type = bfd_arch_mips; break;
269
    case BFD_MACH_O_CPU_TYPE_MC98000: *type = bfd_arch_m98k; break;
270
    case BFD_MACH_O_CPU_TYPE_HPPA: *type = bfd_arch_hppa; break;
271
    case BFD_MACH_O_CPU_TYPE_ARM: *type = bfd_arch_arm; break;
272
    case BFD_MACH_O_CPU_TYPE_MC88000: *type = bfd_arch_m88k; break;
273
    case BFD_MACH_O_CPU_TYPE_SPARC: *type = bfd_arch_sparc; break;
274
    case BFD_MACH_O_CPU_TYPE_I860: *type = bfd_arch_i860; break;
275
    case BFD_MACH_O_CPU_TYPE_ALPHA: *type = bfd_arch_alpha; break;
276
    case BFD_MACH_O_CPU_TYPE_POWERPC: *type = bfd_arch_powerpc; break;
277
    default: *type = bfd_arch_unknown; break;
278
    }
279
 
280
  switch (*type)
281
    {
282
    case bfd_arch_i386: *subtype = bfd_mach_i386_i386; break;
283
    case bfd_arch_sparc: *subtype = bfd_mach_sparc; break;
284
    default:
285
      *subtype = bfd_arch_unknown;
286
    }
287
}
288
 
289
static int
290
bfd_mach_o_write_header (bfd *abfd, bfd_mach_o_header *header)
291
{
292
  unsigned char buf[28];
293
 
294
  bfd_h_put_32 (abfd, header->magic, buf + 0);
295
  bfd_h_put_32 (abfd, header->cputype, buf + 4);
296
  bfd_h_put_32 (abfd, header->cpusubtype, buf + 8);
297
  bfd_h_put_32 (abfd, header->filetype, buf + 12);
298
  bfd_h_put_32 (abfd, header->ncmds, buf + 16);
299
  bfd_h_put_32 (abfd, header->sizeofcmds, buf + 20);
300
  bfd_h_put_32 (abfd, header->flags, buf + 24);
301
 
302
  bfd_seek (abfd, 0, SEEK_SET);
303
  if (bfd_bwrite ((PTR) buf, 28, abfd) != 28)
304
    return -1;
305
 
306
  return 0;
307
}
308
 
309
static int
310
bfd_mach_o_scan_write_thread (bfd *abfd,
311
                              bfd_mach_o_load_command *command)
312
{
313
  bfd_mach_o_thread_command *cmd = &command->command.thread;
314
  unsigned int i;
315
  unsigned char buf[8];
316
  bfd_vma offset;
317
  unsigned int nflavours;
318
 
319
  BFD_ASSERT ((command->type == BFD_MACH_O_LC_THREAD)
320
              || (command->type == BFD_MACH_O_LC_UNIXTHREAD));
321
 
322
  offset = 8;
323
  nflavours = 0;
324
  for (i = 0; i < cmd->nflavours; i++)
325
    {
326
      BFD_ASSERT ((cmd->flavours[i].size % 4) == 0);
327
      BFD_ASSERT (cmd->flavours[i].offset == (command->offset + offset + 8));
328
 
329
      bfd_h_put_32 (abfd, cmd->flavours[i].flavour, buf);
330
      bfd_h_put_32 (abfd, (cmd->flavours[i].size / 4), buf + 4);
331
 
332
      bfd_seek (abfd, command->offset + offset, SEEK_SET);
333
      if (bfd_bwrite ((PTR) buf, 8, abfd) != 8)
334
        return -1;
335
 
336
      offset += cmd->flavours[i].size + 8;
337
    }
338
 
339
  return 0;
340
}
341
 
342
static int
343
bfd_mach_o_scan_write_section (bfd *abfd,
344
                               bfd_mach_o_section *section,
345
                               bfd_vma offset)
346
{
347
  unsigned char buf[68];
348
 
349
  memcpy (buf, section->sectname, 16);
350
  memcpy (buf + 16, section->segname, 16);
351
  bfd_h_put_32 (abfd, section->addr, buf + 32);
352
  bfd_h_put_32 (abfd, section->size, buf + 36);
353
  bfd_h_put_32 (abfd, section->offset, buf + 40);
354
  bfd_h_put_32 (abfd, section->align, buf + 44);
355
  bfd_h_put_32 (abfd, section->reloff, buf + 48);
356
  bfd_h_put_32 (abfd, section->nreloc, buf + 52);
357
  bfd_h_put_32 (abfd, section->flags, buf + 56);
358
  /* bfd_h_put_32 (abfd, section->reserved1, buf + 60); */
359
  /* bfd_h_put_32 (abfd, section->reserved2, buf + 64); */
360
 
361
  bfd_seek (abfd, offset, SEEK_SET);
362
  if (bfd_bwrite ((PTR) buf, 68, abfd) != 68)
363
    return -1;
364
 
365
  return 0;
366
}
367
 
368
static int
369
bfd_mach_o_scan_write_segment (bfd *abfd, bfd_mach_o_load_command *command)
370
{
371
  unsigned char buf[48];
372
  bfd_mach_o_segment_command *seg = &command->command.segment;
373
  unsigned long i;
374
 
375
  BFD_ASSERT (command->type == BFD_MACH_O_LC_SEGMENT);
376
 
377
  memcpy (buf, seg->segname, 16);
378
  bfd_h_put_32 (abfd, seg->vmaddr, buf + 16);
379
  bfd_h_put_32 (abfd, seg->vmsize, buf + 20);
380
  bfd_h_put_32 (abfd, seg->fileoff, buf + 24);
381
  bfd_h_put_32 (abfd, seg->filesize, buf + 28);
382
  bfd_h_put_32 (abfd, 0 /* seg->maxprot */, buf + 32);
383
  bfd_h_put_32 (abfd, 0 /* seg->initprot */, buf + 36);
384
  bfd_h_put_32 (abfd, seg->nsects, buf + 40);
385
  bfd_h_put_32 (abfd, seg->flags, buf + 44);
386
 
387
  bfd_seek (abfd, command->offset + 8, SEEK_SET);
388
  if (bfd_bwrite ((PTR) buf, 48, abfd) != 48)
389
    return -1;
390
 
391
  {
392
    char buf[1024];
393
    bfd_vma nbytes = seg->filesize;
394
    bfd_vma curoff = seg->fileoff;
395
 
396
    while (nbytes > 0)
397
      {
398
        bfd_vma thisread = nbytes;
399
 
400
        if (thisread > 1024)
401
          thisread = 1024;
402
 
403
        bfd_seek (abfd, curoff, SEEK_SET);
404
        if (bfd_bread ((PTR) buf, thisread, abfd) != thisread)
405
          return -1;
406
 
407
        bfd_seek (abfd, curoff, SEEK_SET);
408
        if (bfd_bwrite ((PTR) buf, thisread, abfd) != thisread)
409
          return -1;
410
 
411
        nbytes -= thisread;
412
        curoff += thisread;
413
      }
414
  }
415
 
416
  for (i = 0; i < seg->nsects; i++)
417
    {
418
      bfd_vma segoff = command->offset + 48 + 8 + (i * 68);
419
 
420
      if (bfd_mach_o_scan_write_section (abfd, &seg->sections[i], segoff) != 0)
421
        return -1;
422
    }
423
 
424
  return 0;
425
}
426
 
427
static int
428
bfd_mach_o_scan_write_symtab_symbols (bfd *abfd,
429
                                      bfd_mach_o_load_command *command)
430
{
431
  bfd_mach_o_symtab_command *sym = &command->command.symtab;
432
  asymbol *s = NULL;
433
  unsigned long i;
434
 
435
  for (i = 0; i < sym->nsyms; i++)
436
    {
437
      unsigned char buf[12];
438
      bfd_vma symoff = sym->symoff + (i * 12);
439
      unsigned char ntype = 0;
440
      unsigned char nsect = 0;
441
      short ndesc = 0;
442
 
443
      s = &sym->symbols[i];
444
 
445
      /* Instead just set from the stored values.  */
446
      ntype = (s->udata.i >> 24) & 0xff;
447
      nsect = (s->udata.i >> 16) & 0xff;
448
      ndesc = s->udata.i & 0xffff;
449
 
450
      bfd_h_put_32 (abfd, s->name - sym->strtab, buf);
451
      bfd_h_put_8 (abfd, ntype, buf + 4);
452
      bfd_h_put_8 (abfd, nsect, buf + 5);
453
      bfd_h_put_16 (abfd, ndesc, buf + 6);
454
      bfd_h_put_32 (abfd, s->section->vma + s->value, buf + 8);
455
 
456
      bfd_seek (abfd, symoff, SEEK_SET);
457
      if (bfd_bwrite ((PTR) buf, 12, abfd) != 12)
458
        {
459
          fprintf (stderr, "bfd_mach_o_scan_write_symtab_symbols: unable to write %d bytes at %lu\n",
460
                   12, (unsigned long) symoff);
461
          return -1;
462
        }
463
    }
464
 
465
  return 0;
466
}
467
 
468
static int
469
bfd_mach_o_scan_write_symtab (bfd *abfd, bfd_mach_o_load_command *command)
470
{
471
  bfd_mach_o_symtab_command *seg = &command->command.symtab;
472
  unsigned char buf[16];
473
 
474
  BFD_ASSERT (command->type == BFD_MACH_O_LC_SYMTAB);
475
 
476
  bfd_h_put_32 (abfd, seg->symoff, buf);
477
  bfd_h_put_32 (abfd, seg->nsyms, buf + 4);
478
  bfd_h_put_32 (abfd, seg->stroff, buf + 8);
479
  bfd_h_put_32 (abfd, seg->strsize, buf + 12);
480
 
481
  bfd_seek (abfd, command->offset + 8, SEEK_SET);
482
  if (bfd_bwrite ((PTR) buf, 16, abfd) != 16)
483
    return -1;
484
 
485
  if (bfd_mach_o_scan_write_symtab_symbols (abfd, command) != 0)
486
    return -1;
487
 
488
  return 0;
489
}
490
 
491
static bfd_boolean
492
bfd_mach_o_write_contents (bfd *abfd)
493
{
494
  unsigned int i;
495
  asection *s;
496
 
497
  bfd_mach_o_data_struct *mdata = abfd->tdata.mach_o_data;
498
 
499
  /* Write data sections first in case they overlap header data to be
500
     written later.  */
501
 
502
  for (s = abfd->sections; s != (asection *) NULL; s = s->next)
503
    ;
504
 
505
  /* Now write header information.  */
506
  if (bfd_mach_o_write_header (abfd, &mdata->header) != 0)
507
    return FALSE;
508
 
509
  for (i = 0; i < mdata->header.ncmds; i++)
510
    {
511
      unsigned char buf[8];
512
      bfd_mach_o_load_command *cur = &mdata->commands[i];
513
      unsigned long typeflag;
514
 
515
      typeflag = cur->type_required ? cur->type & BFD_MACH_O_LC_REQ_DYLD : cur->type;
516
 
517
      bfd_h_put_32 (abfd, typeflag, buf);
518
      bfd_h_put_32 (abfd, cur->len, buf + 4);
519
 
520
      bfd_seek (abfd, cur->offset, SEEK_SET);
521
      if (bfd_bwrite ((PTR) buf, 8, abfd) != 8)
522
        return FALSE;
523
 
524
      switch (cur->type)
525
        {
526
        case BFD_MACH_O_LC_SEGMENT:
527
          if (bfd_mach_o_scan_write_segment (abfd, cur) != 0)
528
            return FALSE;
529
          break;
530
        case BFD_MACH_O_LC_SYMTAB:
531
          if (bfd_mach_o_scan_write_symtab (abfd, cur) != 0)
532
            return FALSE;
533
          break;
534
        case BFD_MACH_O_LC_SYMSEG:
535
          break;
536
        case BFD_MACH_O_LC_THREAD:
537
        case BFD_MACH_O_LC_UNIXTHREAD:
538
          if (bfd_mach_o_scan_write_thread (abfd, cur) != 0)
539
            return FALSE;
540
          break;
541
        case BFD_MACH_O_LC_LOADFVMLIB:
542
        case BFD_MACH_O_LC_IDFVMLIB:
543
        case BFD_MACH_O_LC_IDENT:
544
        case BFD_MACH_O_LC_FVMFILE:
545
        case BFD_MACH_O_LC_PREPAGE:
546
        case BFD_MACH_O_LC_DYSYMTAB:
547
        case BFD_MACH_O_LC_LOAD_DYLIB:
548
        case BFD_MACH_O_LC_LOAD_WEAK_DYLIB:
549
        case BFD_MACH_O_LC_ID_DYLIB:
550
        case BFD_MACH_O_LC_LOAD_DYLINKER:
551
        case BFD_MACH_O_LC_ID_DYLINKER:
552
        case BFD_MACH_O_LC_PREBOUND_DYLIB:
553
        case BFD_MACH_O_LC_ROUTINES:
554
        case BFD_MACH_O_LC_SUB_FRAMEWORK:
555
          break;
556
        default:
557
          fprintf (stderr,
558
                   "unable to write unknown load command 0x%lx\n",
559
                   (long) cur->type);
560
          return FALSE;
561
        }
562
    }
563
 
564
  return TRUE;
565
}
566
 
567
static int
568
bfd_mach_o_sizeof_headers (bfd *a ATTRIBUTE_UNUSED,
569
                           struct bfd_link_info *info ATTRIBUTE_UNUSED)
570
{
571
  return 0;
572
}
573
 
574
/* Make an empty symbol.  This is required only because
575
   bfd_make_section_anyway wants to create a symbol for the section.  */
576
 
577
static asymbol *
578
bfd_mach_o_make_empty_symbol (bfd *abfd)
579
{
580
  asymbol *new;
581
 
582
  new = bfd_zalloc (abfd, sizeof (* new));
583
  if (new == NULL)
584
    return new;
585
  new->the_bfd = abfd;
586
  return new;
587
}
588
 
589
static int
590
bfd_mach_o_read_header (bfd *abfd, bfd_mach_o_header *header)
591
{
592
  unsigned char buf[28];
593
  bfd_vma (*get32) (const void *) = NULL;
594
 
595
  bfd_seek (abfd, 0, SEEK_SET);
596
 
597
  if (bfd_bread ((PTR) buf, 28, abfd) != 28)
598
    return -1;
599
 
600
  if (bfd_getb32 (buf) == 0xfeedface)
601
    {
602
      header->byteorder = BFD_ENDIAN_BIG;
603
      header->magic = 0xfeedface;
604
      get32 = bfd_getb32;
605
    }
606
  else if (bfd_getl32 (buf) == 0xfeedface)
607
    {
608
      header->byteorder = BFD_ENDIAN_LITTLE;
609
      header->magic = 0xfeedface;
610
      get32 = bfd_getl32;
611
    }
612
  else
613
    {
614
      header->byteorder = BFD_ENDIAN_UNKNOWN;
615
      return -1;
616
    }
617
 
618
  header->cputype = (*get32) (buf + 4);
619
  header->cpusubtype = (*get32) (buf + 8);
620
  header->filetype = (*get32) (buf + 12);
621
  header->ncmds = (*get32) (buf + 16);
622
  header->sizeofcmds = (*get32) (buf + 20);
623
  header->flags = (*get32) (buf + 24);
624
 
625
  return 0;
626
}
627
 
628
static asection *
629
bfd_mach_o_make_bfd_section (bfd *abfd, bfd_mach_o_section *section)
630
{
631
  asection *bfdsec;
632
  char *sname;
633
  const char *prefix = "LC_SEGMENT";
634
  unsigned int snamelen;
635
  flagword flags;
636
 
637
  snamelen = strlen (prefix) + 1
638
    + strlen (section->segname) + 1
639
    + strlen (section->sectname) + 1;
640
 
641
  sname = bfd_alloc (abfd, snamelen);
642
  if (sname == NULL)
643
    return NULL;
644
  sprintf (sname, "%s.%s.%s", prefix, section->segname, section->sectname);
645
 
646
  flags = SEC_ALLOC;
647
  if ((section->flags & SECTION_TYPE) != BFD_MACH_O_S_ZEROFILL)
648
    flags = SEC_HAS_CONTENTS | SEC_LOAD | SEC_ALLOC | SEC_CODE;
649
  bfdsec = bfd_make_section_anyway_with_flags (abfd, sname, flags);
650
  if (bfdsec == NULL)
651
    return NULL;
652
 
653
  bfdsec->vma = section->addr;
654
  bfdsec->lma = section->addr;
655
  bfdsec->size = section->size;
656
  bfdsec->filepos = section->offset;
657
  bfdsec->alignment_power = section->align;
658
 
659
  return bfdsec;
660
}
661
 
662
static int
663
bfd_mach_o_scan_read_section (bfd *abfd,
664
                              bfd_mach_o_section *section,
665
                              bfd_vma offset)
666
{
667
  unsigned char buf[68];
668
 
669
  bfd_seek (abfd, offset, SEEK_SET);
670
  if (bfd_bread ((PTR) buf, 68, abfd) != 68)
671
    return -1;
672
 
673
  memcpy (section->sectname, buf, 16);
674
  section->sectname[16] = '\0';
675
  memcpy (section->segname, buf + 16, 16);
676
  section->segname[16] = '\0';
677
  section->addr = bfd_h_get_32 (abfd, buf + 32);
678
  section->size = bfd_h_get_32 (abfd, buf + 36);
679
  section->offset = bfd_h_get_32 (abfd, buf + 40);
680
  section->align = bfd_h_get_32 (abfd, buf + 44);
681
  section->reloff = bfd_h_get_32 (abfd, buf + 48);
682
  section->nreloc = bfd_h_get_32 (abfd, buf + 52);
683
  section->flags = bfd_h_get_32 (abfd, buf + 56);
684
  section->reserved1 = bfd_h_get_32 (abfd, buf + 60);
685
  section->reserved2 = bfd_h_get_32 (abfd, buf + 64);
686
  section->bfdsection = bfd_mach_o_make_bfd_section (abfd, section);
687
 
688
  if (section->bfdsection == NULL)
689
    return -1;
690
 
691
  return 0;
692
}
693
 
694
int
695
bfd_mach_o_scan_read_symtab_symbol (bfd *abfd,
696
                                    bfd_mach_o_symtab_command *sym,
697
                                    asymbol *s,
698
                                    unsigned long i)
699
{
700
  bfd_mach_o_data_struct *mdata = abfd->tdata.mach_o_data;
701
  bfd_vma symoff = sym->symoff + (i * 12);
702
  unsigned char buf[12];
703
  unsigned char type = -1;
704
  unsigned char section = -1;
705
  short desc = -1;
706
  unsigned long value = -1;
707
  unsigned long stroff = -1;
708
  unsigned int symtype = -1;
709
 
710
  BFD_ASSERT (sym->strtab != NULL);
711
 
712
  bfd_seek (abfd, symoff, SEEK_SET);
713
  if (bfd_bread ((PTR) buf, 12, abfd) != 12)
714
    {
715
      fprintf (stderr, "bfd_mach_o_scan_read_symtab_symbol: unable to read %d bytes at %lu\n",
716
               12, (unsigned long) symoff);
717
      return -1;
718
    }
719
 
720
  stroff = bfd_h_get_32 (abfd, buf);
721
  type = bfd_h_get_8 (abfd, buf + 4);
722
  symtype = (type & 0x0e);
723
  section = bfd_h_get_8 (abfd, buf + 5) - 1;
724
  desc = bfd_h_get_16 (abfd, buf + 6);
725
  value = bfd_h_get_32 (abfd, buf + 8);
726
 
727
  if (stroff >= sym->strsize)
728
    {
729
      fprintf (stderr, "bfd_mach_o_scan_read_symtab_symbol: symbol name out of range (%lu >= %lu)\n",
730
               (unsigned long) stroff, (unsigned long) sym->strsize);
731
      return -1;
732
    }
733
 
734
  s->the_bfd = abfd;
735
  s->name = sym->strtab + stroff;
736
  s->value = value;
737
  s->udata.i = (type << 24) | (section << 16) | desc;
738
  s->flags = 0x0;
739
 
740
  if (type & BFD_MACH_O_N_STAB)
741
    {
742
      s->flags |= BSF_DEBUGGING;
743
      s->section = bfd_und_section_ptr;
744
    }
745
  else
746
    {
747
      if (type & BFD_MACH_O_N_PEXT)
748
        {
749
          type &= ~BFD_MACH_O_N_PEXT;
750
          s->flags |= BSF_GLOBAL;
751
        }
752
 
753
      if (type & BFD_MACH_O_N_EXT)
754
        {
755
          type &= ~BFD_MACH_O_N_EXT;
756
          s->flags |= BSF_GLOBAL;
757
        }
758
 
759
      switch (symtype)
760
        {
761
        case BFD_MACH_O_N_UNDF:
762
          s->section = bfd_und_section_ptr;
763
          break;
764
        case BFD_MACH_O_N_PBUD:
765
          s->section = bfd_und_section_ptr;
766
          break;
767
        case BFD_MACH_O_N_ABS:
768
          s->section = bfd_abs_section_ptr;
769
          break;
770
        case BFD_MACH_O_N_SECT:
771
          if ((section > 0) && (section <= mdata->nsects))
772
            {
773
              s->section = mdata->sections[section - 1]->bfdsection;
774
              s->value = s->value - mdata->sections[section - 1]->addr;
775
            }
776
          else
777
            {
778
              /* Mach-O uses 0 to mean "no section"; not an error.  */
779
              if (section != 0)
780
                {
781
                  fprintf (stderr, "bfd_mach_o_scan_read_symtab_symbol: "
782
                           "symbol \"%s\" specified invalid section %d (max %lu): setting to undefined\n",
783
                           s->name, section, mdata->nsects);
784
                }
785
              s->section = bfd_und_section_ptr;
786
            }
787
          break;
788
        case BFD_MACH_O_N_INDR:
789
          fprintf (stderr, "bfd_mach_o_scan_read_symtab_symbol: "
790
                   "symbol \"%s\" is unsupported 'indirect' reference: setting to undefined\n",
791
                   s->name);
792
          s->section = bfd_und_section_ptr;
793
          break;
794
        default:
795
          fprintf (stderr, "bfd_mach_o_scan_read_symtab_symbol: "
796
                   "symbol \"%s\" specified invalid type field 0x%x: setting to undefined\n",
797
                   s->name, symtype);
798
          s->section = bfd_und_section_ptr;
799
          break;
800
        }
801
    }
802
 
803
  return 0;
804
}
805
 
806
int
807
bfd_mach_o_scan_read_symtab_strtab (bfd *abfd,
808
                                    bfd_mach_o_symtab_command *sym)
809
{
810
  BFD_ASSERT (sym->strtab == NULL);
811
 
812
  if (abfd->flags & BFD_IN_MEMORY)
813
    {
814
      struct bfd_in_memory *b;
815
 
816
      b = (struct bfd_in_memory *) abfd->iostream;
817
 
818
      if ((sym->stroff + sym->strsize) > b->size)
819
        {
820
          bfd_set_error (bfd_error_file_truncated);
821
          return -1;
822
        }
823
      sym->strtab = (char *) b->buffer + sym->stroff;
824
      return 0;
825
    }
826
 
827
  sym->strtab = bfd_alloc (abfd, sym->strsize);
828
  if (sym->strtab == NULL)
829
    return -1;
830
 
831
  bfd_seek (abfd, sym->stroff, SEEK_SET);
832
  if (bfd_bread ((PTR) sym->strtab, sym->strsize, abfd) != sym->strsize)
833
    {
834
      fprintf (stderr, "bfd_mach_o_scan_read_symtab_strtab: unable to read %lu bytes at %lu\n",
835
               sym->strsize, sym->stroff);
836
      return -1;
837
    }
838
 
839
  return 0;
840
}
841
 
842
int
843
bfd_mach_o_scan_read_symtab_symbols (bfd *abfd,
844
                                     bfd_mach_o_symtab_command *sym)
845
{
846
  unsigned long i;
847
  int ret;
848
 
849
  BFD_ASSERT (sym->symbols == NULL);
850
  sym->symbols = bfd_alloc (abfd, sym->nsyms * sizeof (asymbol));
851
 
852
  if (sym->symbols == NULL)
853
    {
854
      fprintf (stderr, "bfd_mach_o_scan_read_symtab_symbols: unable to allocate memory for symbols\n");
855
      return -1;
856
    }
857
 
858
  ret = bfd_mach_o_scan_read_symtab_strtab (abfd, sym);
859
  if (ret != 0)
860
    return ret;
861
 
862
  for (i = 0; i < sym->nsyms; i++)
863
    {
864
      ret = bfd_mach_o_scan_read_symtab_symbol (abfd, sym, &sym->symbols[i], i);
865
      if (ret != 0)
866
        return ret;
867
    }
868
 
869
  return 0;
870
}
871
 
872
int
873
bfd_mach_o_scan_read_dysymtab_symbol (bfd *abfd,
874
                                      bfd_mach_o_dysymtab_command *dysym,
875
                                      bfd_mach_o_symtab_command *sym,
876
                                      asymbol *s,
877
                                      unsigned long i)
878
{
879
  unsigned long isymoff = dysym->indirectsymoff + (i * 4);
880
  unsigned long symindex;
881
  unsigned char buf[4];
882
 
883
  BFD_ASSERT (i < dysym->nindirectsyms);
884
 
885
  bfd_seek (abfd, isymoff, SEEK_SET);
886
  if (bfd_bread ((PTR) buf, 4, abfd) != 4)
887
    {
888
      fprintf (stderr, "bfd_mach_o_scan_read_dysymtab_symbol: unable to read %lu bytes at %lu\n",
889
               (unsigned long) 4, isymoff);
890
      return -1;
891
    }
892
  symindex = bfd_h_get_32 (abfd, buf);
893
 
894
  return bfd_mach_o_scan_read_symtab_symbol (abfd, sym, s, symindex);
895
}
896
 
897
static const char *
898
bfd_mach_o_i386_flavour_string (unsigned int flavour)
899
{
900
  switch ((int) flavour)
901
    {
902
    case BFD_MACH_O_i386_NEW_THREAD_STATE: return "i386_NEW_THREAD_STATE";
903
    case BFD_MACH_O_i386_FLOAT_STATE: return "i386_FLOAT_STATE";
904
    case BFD_MACH_O_i386_ISA_PORT_MAP_STATE: return "i386_ISA_PORT_MAP_STATE";
905
    case BFD_MACH_O_i386_V86_ASSIST_STATE: return "i386_V86_ASSIST_STATE";
906
    case BFD_MACH_O_i386_REGS_SEGS_STATE: return "i386_REGS_SEGS_STATE";
907
    case BFD_MACH_O_i386_THREAD_SYSCALL_STATE: return "i386_THREAD_SYSCALL_STATE";
908
    case BFD_MACH_O_i386_THREAD_STATE_NONE: return "i386_THREAD_STATE_NONE";
909
    case BFD_MACH_O_i386_SAVED_STATE: return "i386_SAVED_STATE";
910
    case BFD_MACH_O_i386_THREAD_STATE: return "i386_THREAD_STATE";
911
    case BFD_MACH_O_i386_THREAD_FPSTATE: return "i386_THREAD_FPSTATE";
912
    case BFD_MACH_O_i386_THREAD_EXCEPTSTATE: return "i386_THREAD_EXCEPTSTATE";
913
    case BFD_MACH_O_i386_THREAD_CTHREADSTATE: return "i386_THREAD_CTHREADSTATE";
914
    default: return "UNKNOWN";
915
    }
916
}
917
 
918
static const char *
919
bfd_mach_o_ppc_flavour_string (unsigned int flavour)
920
{
921
  switch ((int) flavour)
922
    {
923
    case BFD_MACH_O_PPC_THREAD_STATE: return "PPC_THREAD_STATE";
924
    case BFD_MACH_O_PPC_FLOAT_STATE: return "PPC_FLOAT_STATE";
925
    case BFD_MACH_O_PPC_EXCEPTION_STATE: return "PPC_EXCEPTION_STATE";
926
    case BFD_MACH_O_PPC_VECTOR_STATE: return "PPC_VECTOR_STATE";
927
    default: return "UNKNOWN";
928
    }
929
}
930
 
931
static int
932
bfd_mach_o_scan_read_dylinker (bfd *abfd,
933
                               bfd_mach_o_load_command *command)
934
{
935
  bfd_mach_o_dylinker_command *cmd = &command->command.dylinker;
936
  unsigned char buf[4];
937
  unsigned int nameoff;
938
  asection *bfdsec;
939
  char *sname;
940
  const char *prefix;
941
 
942
  BFD_ASSERT ((command->type == BFD_MACH_O_LC_ID_DYLINKER)
943
              || (command->type == BFD_MACH_O_LC_LOAD_DYLINKER));
944
 
945
  bfd_seek (abfd, command->offset + 8, SEEK_SET);
946
  if (bfd_bread ((PTR) buf, 4, abfd) != 4)
947
    return -1;
948
 
949
  nameoff = bfd_h_get_32 (abfd, buf + 0);
950
 
951
  cmd->name_offset = command->offset + nameoff;
952
  cmd->name_len = command->len - nameoff;
953
 
954
  if (command->type == BFD_MACH_O_LC_LOAD_DYLINKER)
955
    prefix = "LC_LOAD_DYLINKER";
956
  else if (command->type == BFD_MACH_O_LC_ID_DYLINKER)
957
    prefix = "LC_ID_DYLINKER";
958
  else
959
    abort ();
960
 
961
  sname = bfd_alloc (abfd, strlen (prefix) + 1);
962
  if (sname == NULL)
963
    return -1;
964
  strcpy (sname, prefix);
965
 
966
  bfdsec = bfd_make_section_anyway_with_flags (abfd, sname, SEC_HAS_CONTENTS);
967
  if (bfdsec == NULL)
968
    return -1;
969
 
970
  bfdsec->vma = 0;
971
  bfdsec->lma = 0;
972
  bfdsec->size = command->len - 8;
973
  bfdsec->filepos = command->offset + 8;
974
  bfdsec->alignment_power = 0;
975
 
976
  cmd->section = bfdsec;
977
 
978
  return 0;
979
}
980
 
981
static int
982
bfd_mach_o_scan_read_dylib (bfd *abfd, bfd_mach_o_load_command *command)
983
{
984
  bfd_mach_o_dylib_command *cmd = &command->command.dylib;
985
  unsigned char buf[16];
986
  unsigned int nameoff;
987
  asection *bfdsec;
988
  char *sname;
989
  const char *prefix;
990
 
991
  BFD_ASSERT ((command->type == BFD_MACH_O_LC_ID_DYLIB)
992
              || (command->type == BFD_MACH_O_LC_LOAD_DYLIB)
993
              || (command->type == BFD_MACH_O_LC_LOAD_WEAK_DYLIB));
994
 
995
  bfd_seek (abfd, command->offset + 8, SEEK_SET);
996
  if (bfd_bread ((PTR) buf, 16, abfd) != 16)
997
    return -1;
998
 
999
  nameoff = bfd_h_get_32 (abfd, buf + 0);
1000
  cmd->timestamp = bfd_h_get_32 (abfd, buf + 4);
1001
  cmd->current_version = bfd_h_get_32 (abfd, buf + 8);
1002
  cmd->compatibility_version = bfd_h_get_32 (abfd, buf + 12);
1003
 
1004
  cmd->name_offset = command->offset + nameoff;
1005
  cmd->name_len = command->len - nameoff;
1006
 
1007
  if (command->type == BFD_MACH_O_LC_LOAD_DYLIB)
1008
    prefix = "LC_LOAD_DYLIB";
1009
  else if (command->type == BFD_MACH_O_LC_LOAD_WEAK_DYLIB)
1010
    prefix = "LC_LOAD_WEAK_DYLIB";
1011
  else if (command->type == BFD_MACH_O_LC_ID_DYLIB)
1012
    prefix = "LC_ID_DYLIB";
1013
  else
1014
    abort ();
1015
 
1016
  sname = bfd_alloc (abfd, strlen (prefix) + 1);
1017
  if (sname == NULL)
1018
    return -1;
1019
  strcpy (sname, prefix);
1020
 
1021
  bfdsec = bfd_make_section_anyway_with_flags (abfd, sname, SEC_HAS_CONTENTS);
1022
  if (bfdsec == NULL)
1023
    return -1;
1024
 
1025
  bfdsec->vma = 0;
1026
  bfdsec->lma = 0;
1027
  bfdsec->size = command->len - 8;
1028
  bfdsec->filepos = command->offset + 8;
1029
  bfdsec->alignment_power = 0;
1030
 
1031
  cmd->section = bfdsec;
1032
 
1033
  return 0;
1034
}
1035
 
1036
static int
1037
bfd_mach_o_scan_read_prebound_dylib (bfd *abfd ATTRIBUTE_UNUSED,
1038
                                     bfd_mach_o_load_command *command ATTRIBUTE_UNUSED)
1039
{
1040
  /* bfd_mach_o_prebound_dylib_command *cmd = &command->command.prebound_dylib; */
1041
 
1042
  BFD_ASSERT (command->type == BFD_MACH_O_LC_PREBOUND_DYLIB);
1043
  return 0;
1044
}
1045
 
1046
static int
1047
bfd_mach_o_scan_read_thread (bfd *abfd, bfd_mach_o_load_command *command)
1048
{
1049
  bfd_mach_o_data_struct *mdata = NULL;
1050
  bfd_mach_o_thread_command *cmd = &command->command.thread;
1051
  unsigned char buf[8];
1052
  bfd_vma offset;
1053
  unsigned int nflavours;
1054
  unsigned int i;
1055
 
1056
  BFD_ASSERT ((command->type == BFD_MACH_O_LC_THREAD)
1057
              || (command->type == BFD_MACH_O_LC_UNIXTHREAD));
1058
 
1059
  BFD_ASSERT (bfd_mach_o_valid (abfd));
1060
  mdata = abfd->tdata.mach_o_data;
1061
 
1062
  offset = 8;
1063
  nflavours = 0;
1064
  while (offset != command->len)
1065
    {
1066
      if (offset >= command->len)
1067
        return -1;
1068
 
1069
      bfd_seek (abfd, command->offset + offset, SEEK_SET);
1070
 
1071
      if (bfd_bread ((PTR) buf, 8, abfd) != 8)
1072
        return -1;
1073
 
1074
      offset += 8 + bfd_h_get_32 (abfd, buf + 4) * 4;
1075
      nflavours++;
1076
    }
1077
 
1078
  cmd->flavours = bfd_alloc (abfd, nflavours * sizeof (bfd_mach_o_thread_flavour));
1079
  if (cmd->flavours == NULL)
1080
    return -1;
1081
  cmd->nflavours = nflavours;
1082
 
1083
  offset = 8;
1084
  nflavours = 0;
1085
  while (offset != command->len)
1086
    {
1087
      if (offset >= command->len)
1088
        return -1;
1089
 
1090
      if (nflavours >= cmd->nflavours)
1091
        return -1;
1092
 
1093
      bfd_seek (abfd, command->offset + offset, SEEK_SET);
1094
 
1095
      if (bfd_bread ((PTR) buf, 8, abfd) != 8)
1096
        return -1;
1097
 
1098
      cmd->flavours[nflavours].flavour = bfd_h_get_32 (abfd, buf);
1099
      cmd->flavours[nflavours].offset = command->offset + offset + 8;
1100
      cmd->flavours[nflavours].size = bfd_h_get_32 (abfd, buf + 4) * 4;
1101
      offset += cmd->flavours[nflavours].size + 8;
1102
      nflavours++;
1103
    }
1104
 
1105
  for (i = 0; i < nflavours; i++)
1106
    {
1107
      asection *bfdsec;
1108
      unsigned int snamelen;
1109
      char *sname;
1110
      const char *flavourstr;
1111
      const char *prefix = "LC_THREAD";
1112
      unsigned int j = 0;
1113
 
1114
      switch (mdata->header.cputype)
1115
        {
1116
        case BFD_MACH_O_CPU_TYPE_POWERPC:
1117
          flavourstr = bfd_mach_o_ppc_flavour_string (cmd->flavours[i].flavour);
1118
          break;
1119
        case BFD_MACH_O_CPU_TYPE_I386:
1120
          flavourstr = bfd_mach_o_i386_flavour_string (cmd->flavours[i].flavour);
1121
          break;
1122
        default:
1123
          flavourstr = "UNKNOWN_ARCHITECTURE";
1124
          break;
1125
        }
1126
 
1127
      snamelen = strlen (prefix) + 1 + 20 + 1 + strlen (flavourstr) + 1;
1128
      sname = bfd_alloc (abfd, snamelen);
1129
      if (sname == NULL)
1130
        return -1;
1131
 
1132
      for (;;)
1133
        {
1134
          sprintf (sname, "%s.%s.%u", prefix, flavourstr, j);
1135
          if (bfd_get_section_by_name (abfd, sname) == NULL)
1136
            break;
1137
          j++;
1138
        }
1139
 
1140
      bfdsec = bfd_make_section_with_flags (abfd, sname, SEC_HAS_CONTENTS);
1141
 
1142
      bfdsec->vma = 0;
1143
      bfdsec->lma = 0;
1144
      bfdsec->size = cmd->flavours[i].size;
1145
      bfdsec->filepos = cmd->flavours[i].offset;
1146
      bfdsec->alignment_power = 0x0;
1147
 
1148
      cmd->section = bfdsec;
1149
    }
1150
 
1151
  return 0;
1152
}
1153
 
1154
static int
1155
bfd_mach_o_scan_read_dysymtab (bfd *abfd, bfd_mach_o_load_command *command)
1156
{
1157
  bfd_mach_o_dysymtab_command *seg = &command->command.dysymtab;
1158
  unsigned char buf[72];
1159
 
1160
  BFD_ASSERT (command->type == BFD_MACH_O_LC_DYSYMTAB);
1161
 
1162
  bfd_seek (abfd, command->offset + 8, SEEK_SET);
1163
  if (bfd_bread ((PTR) buf, 72, abfd) != 72)
1164
    return -1;
1165
 
1166
  seg->ilocalsym = bfd_h_get_32 (abfd, buf + 0);
1167
  seg->nlocalsym = bfd_h_get_32 (abfd, buf + 4);
1168
  seg->iextdefsym = bfd_h_get_32 (abfd, buf + 8);
1169
  seg->nextdefsym = bfd_h_get_32 (abfd, buf + 12);
1170
  seg->iundefsym = bfd_h_get_32 (abfd, buf + 16);
1171
  seg->nundefsym = bfd_h_get_32 (abfd, buf + 20);
1172
  seg->tocoff = bfd_h_get_32 (abfd, buf + 24);
1173
  seg->ntoc = bfd_h_get_32 (abfd, buf + 28);
1174
  seg->modtaboff = bfd_h_get_32 (abfd, buf + 32);
1175
  seg->nmodtab = bfd_h_get_32 (abfd, buf + 36);
1176
  seg->extrefsymoff = bfd_h_get_32 (abfd, buf + 40);
1177
  seg->nextrefsyms = bfd_h_get_32 (abfd, buf + 44);
1178
  seg->indirectsymoff = bfd_h_get_32 (abfd, buf + 48);
1179
  seg->nindirectsyms = bfd_h_get_32 (abfd, buf + 52);
1180
  seg->extreloff = bfd_h_get_32 (abfd, buf + 56);
1181
  seg->nextrel = bfd_h_get_32 (abfd, buf + 60);
1182
  seg->locreloff = bfd_h_get_32 (abfd, buf + 64);
1183
  seg->nlocrel = bfd_h_get_32 (abfd, buf + 68);
1184
 
1185
  return 0;
1186
}
1187
 
1188
static int
1189
bfd_mach_o_scan_read_symtab (bfd *abfd, bfd_mach_o_load_command *command)
1190
{
1191
  bfd_mach_o_symtab_command *seg = &command->command.symtab;
1192
  unsigned char buf[16];
1193
  asection *bfdsec;
1194
  char *sname;
1195
  const char *prefix = "LC_SYMTAB.stabs";
1196
 
1197
  BFD_ASSERT (command->type == BFD_MACH_O_LC_SYMTAB);
1198
 
1199
  bfd_seek (abfd, command->offset + 8, SEEK_SET);
1200
  if (bfd_bread ((PTR) buf, 16, abfd) != 16)
1201
    return -1;
1202
 
1203
  seg->symoff = bfd_h_get_32 (abfd, buf);
1204
  seg->nsyms = bfd_h_get_32 (abfd, buf + 4);
1205
  seg->stroff = bfd_h_get_32 (abfd, buf + 8);
1206
  seg->strsize = bfd_h_get_32 (abfd, buf + 12);
1207
  seg->symbols = NULL;
1208
  seg->strtab = NULL;
1209
 
1210
  sname = bfd_alloc (abfd, strlen (prefix) + 1);
1211
  if (sname == NULL)
1212
    return -1;
1213
  strcpy (sname, prefix);
1214
 
1215
  bfdsec = bfd_make_section_anyway_with_flags (abfd, sname, SEC_HAS_CONTENTS);
1216
  if (bfdsec == NULL)
1217
    return -1;
1218
 
1219
  bfdsec->vma = 0;
1220
  bfdsec->lma = 0;
1221
  bfdsec->size = seg->nsyms * 12;
1222
  bfdsec->filepos = seg->symoff;
1223
  bfdsec->alignment_power = 0;
1224
 
1225
  seg->stabs_segment = bfdsec;
1226
 
1227
  prefix = "LC_SYMTAB.stabstr";
1228
  sname = bfd_alloc (abfd, strlen (prefix) + 1);
1229
  if (sname == NULL)
1230
    return -1;
1231
  strcpy (sname, prefix);
1232
 
1233
  bfdsec = bfd_make_section_anyway_with_flags (abfd, sname, SEC_HAS_CONTENTS);
1234
  if (bfdsec == NULL)
1235
    return -1;
1236
 
1237
  bfdsec->vma = 0;
1238
  bfdsec->lma = 0;
1239
  bfdsec->size = seg->strsize;
1240
  bfdsec->filepos = seg->stroff;
1241
  bfdsec->alignment_power = 0;
1242
 
1243
  seg->stabstr_segment = bfdsec;
1244
 
1245
  return 0;
1246
}
1247
 
1248
static int
1249
bfd_mach_o_scan_read_segment (bfd *abfd, bfd_mach_o_load_command *command)
1250
{
1251
  unsigned char buf[48];
1252
  bfd_mach_o_segment_command *seg = &command->command.segment;
1253
  unsigned long i;
1254
  asection *bfdsec;
1255
  char *sname;
1256
  const char *prefix = "LC_SEGMENT";
1257
  unsigned int snamelen;
1258
  flagword flags;
1259
 
1260
  BFD_ASSERT (command->type == BFD_MACH_O_LC_SEGMENT);
1261
 
1262
  bfd_seek (abfd, command->offset + 8, SEEK_SET);
1263
  if (bfd_bread ((PTR) buf, 48, abfd) != 48)
1264
    return -1;
1265
 
1266
  memcpy (seg->segname, buf, 16);
1267
  seg->vmaddr = bfd_h_get_32 (abfd, buf + 16);
1268
  seg->vmsize = bfd_h_get_32 (abfd, buf + 20);
1269
  seg->fileoff = bfd_h_get_32 (abfd, buf + 24);
1270
  seg->filesize = bfd_h_get_32 (abfd, buf +  28);
1271
  /* seg->maxprot = bfd_h_get_32 (abfd, buf + 32); */
1272
  /* seg->initprot = bfd_h_get_32 (abfd, buf + 36); */
1273
  seg->nsects = bfd_h_get_32 (abfd, buf + 40);
1274
  seg->flags = bfd_h_get_32 (abfd, buf + 44);
1275
 
1276
  snamelen = strlen (prefix) + 1 + strlen (seg->segname) + 1;
1277
  sname = bfd_alloc (abfd, snamelen);
1278
  if (sname == NULL)
1279
    return -1;
1280
  sprintf (sname, "%s.%s", prefix, seg->segname);
1281
 
1282
  flags = SEC_HAS_CONTENTS | SEC_LOAD | SEC_ALLOC | SEC_CODE;
1283
  bfdsec = bfd_make_section_anyway_with_flags (abfd, sname, flags);
1284
  if (bfdsec == NULL)
1285
    return -1;
1286
 
1287
  bfdsec->vma = seg->vmaddr;
1288
  bfdsec->lma = seg->vmaddr;
1289
  bfdsec->size = seg->filesize;
1290
  bfdsec->filepos = seg->fileoff;
1291
  bfdsec->alignment_power = 0x0;
1292
 
1293
  seg->segment = bfdsec;
1294
 
1295
  if (seg->nsects != 0)
1296
    {
1297
      seg->sections = bfd_alloc (abfd, seg->nsects * sizeof (bfd_mach_o_section));
1298
      if (seg->sections == NULL)
1299
        return -1;
1300
 
1301
      for (i = 0; i < seg->nsects; i++)
1302
        {
1303
          bfd_vma segoff = command->offset + 48 + 8 + (i * 68);
1304
 
1305
          if (bfd_mach_o_scan_read_section (abfd, &seg->sections[i],
1306
                                            segoff) != 0)
1307
            return -1;
1308
        }
1309
    }
1310
 
1311
  return 0;
1312
}
1313
 
1314
static int
1315
bfd_mach_o_scan_read_command (bfd *abfd, bfd_mach_o_load_command *command)
1316
{
1317
  unsigned char buf[8];
1318
 
1319
  bfd_seek (abfd, command->offset, SEEK_SET);
1320
  if (bfd_bread ((PTR) buf, 8, abfd) != 8)
1321
    return -1;
1322
 
1323
  command->type = (bfd_h_get_32 (abfd, buf) & ~BFD_MACH_O_LC_REQ_DYLD);
1324
  command->type_required = (bfd_h_get_32 (abfd, buf) & BFD_MACH_O_LC_REQ_DYLD
1325
                            ? 1 : 0);
1326
  command->len = bfd_h_get_32 (abfd, buf + 4);
1327
 
1328
  switch (command->type)
1329
    {
1330
    case BFD_MACH_O_LC_SEGMENT:
1331
      if (bfd_mach_o_scan_read_segment (abfd, command) != 0)
1332
        return -1;
1333
      break;
1334
    case BFD_MACH_O_LC_SYMTAB:
1335
      if (bfd_mach_o_scan_read_symtab (abfd, command) != 0)
1336
        return -1;
1337
      break;
1338
    case BFD_MACH_O_LC_SYMSEG:
1339
      break;
1340
    case BFD_MACH_O_LC_THREAD:
1341
    case BFD_MACH_O_LC_UNIXTHREAD:
1342
      if (bfd_mach_o_scan_read_thread (abfd, command) != 0)
1343
        return -1;
1344
      break;
1345
    case BFD_MACH_O_LC_LOAD_DYLINKER:
1346
    case BFD_MACH_O_LC_ID_DYLINKER:
1347
      if (bfd_mach_o_scan_read_dylinker (abfd, command) != 0)
1348
        return -1;
1349
      break;
1350
    case BFD_MACH_O_LC_LOAD_DYLIB:
1351
    case BFD_MACH_O_LC_ID_DYLIB:
1352
    case BFD_MACH_O_LC_LOAD_WEAK_DYLIB:
1353
      if (bfd_mach_o_scan_read_dylib (abfd, command) != 0)
1354
        return -1;
1355
      break;
1356
    case BFD_MACH_O_LC_PREBOUND_DYLIB:
1357
      if (bfd_mach_o_scan_read_prebound_dylib (abfd, command) != 0)
1358
        return -1;
1359
      break;
1360
    case BFD_MACH_O_LC_LOADFVMLIB:
1361
    case BFD_MACH_O_LC_IDFVMLIB:
1362
    case BFD_MACH_O_LC_IDENT:
1363
    case BFD_MACH_O_LC_FVMFILE:
1364
    case BFD_MACH_O_LC_PREPAGE:
1365
    case BFD_MACH_O_LC_ROUTINES:
1366
    case BFD_MACH_O_LC_SUB_FRAMEWORK:
1367
      break;
1368
    case BFD_MACH_O_LC_DYSYMTAB:
1369
      if (bfd_mach_o_scan_read_dysymtab (abfd, command) != 0)
1370
        return -1;
1371
      break;
1372
    case BFD_MACH_O_LC_SUB_UMBRELLA:
1373
    case BFD_MACH_O_LC_SUB_CLIENT:
1374
    case BFD_MACH_O_LC_SUB_LIBRARY:
1375
    case BFD_MACH_O_LC_TWOLEVEL_HINTS:
1376
    case BFD_MACH_O_LC_PREBIND_CKSUM:
1377
      break;
1378
    default:
1379
      fprintf (stderr, "unable to read unknown load command 0x%lx\n",
1380
               (unsigned long) command->type);
1381
      break;
1382
    }
1383
 
1384
  return 0;
1385
}
1386
 
1387
static void
1388
bfd_mach_o_flatten_sections (bfd *abfd)
1389
{
1390
  bfd_mach_o_data_struct *mdata = abfd->tdata.mach_o_data;
1391
  long csect = 0;
1392
  unsigned long i, j;
1393
 
1394
  mdata->nsects = 0;
1395
 
1396
  for (i = 0; i < mdata->header.ncmds; i++)
1397
    {
1398
      if (mdata->commands[i].type == BFD_MACH_O_LC_SEGMENT)
1399
        {
1400
          bfd_mach_o_segment_command *seg;
1401
 
1402
          seg = &mdata->commands[i].command.segment;
1403
          mdata->nsects += seg->nsects;
1404
        }
1405
    }
1406
 
1407
  mdata->sections = bfd_alloc (abfd,
1408
                               mdata->nsects * sizeof (bfd_mach_o_section *));
1409
  csect = 0;
1410
 
1411
  for (i = 0; i < mdata->header.ncmds; i++)
1412
    {
1413
      if (mdata->commands[i].type == BFD_MACH_O_LC_SEGMENT)
1414
        {
1415
          bfd_mach_o_segment_command *seg;
1416
 
1417
          seg = &mdata->commands[i].command.segment;
1418
          BFD_ASSERT (csect + seg->nsects <= mdata->nsects);
1419
 
1420
          for (j = 0; j < seg->nsects; j++)
1421
            mdata->sections[csect++] = &seg->sections[j];
1422
        }
1423
    }
1424
}
1425
 
1426
int
1427
bfd_mach_o_scan_start_address (bfd *abfd)
1428
{
1429
  bfd_mach_o_data_struct *mdata = abfd->tdata.mach_o_data;
1430
  bfd_mach_o_thread_command *cmd = NULL;
1431
  unsigned long i;
1432
 
1433
  for (i = 0; i < mdata->header.ncmds; i++)
1434
    {
1435
      if ((mdata->commands[i].type == BFD_MACH_O_LC_THREAD) ||
1436
          (mdata->commands[i].type == BFD_MACH_O_LC_UNIXTHREAD))
1437
        {
1438
          if (cmd == NULL)
1439
            cmd = &mdata->commands[i].command.thread;
1440
          else
1441
            return 0;
1442
        }
1443
    }
1444
 
1445
  if (cmd == NULL)
1446
    return 0;
1447
 
1448
  for (i = 0; i < cmd->nflavours; i++)
1449
    {
1450
      if ((mdata->header.cputype == BFD_MACH_O_CPU_TYPE_I386)
1451
          && (cmd->flavours[i].flavour
1452
              == (unsigned long) BFD_MACH_O_i386_THREAD_STATE))
1453
        {
1454
          unsigned char buf[4];
1455
 
1456
          bfd_seek (abfd, cmd->flavours[i].offset + 40, SEEK_SET);
1457
 
1458
          if (bfd_bread (buf, 4, abfd) != 4)
1459
            return -1;
1460
 
1461
          abfd->start_address = bfd_h_get_32 (abfd, buf);
1462
        }
1463
      else if ((mdata->header.cputype == BFD_MACH_O_CPU_TYPE_POWERPC)
1464
               && (cmd->flavours[i].flavour == BFD_MACH_O_PPC_THREAD_STATE))
1465
        {
1466
          unsigned char buf[4];
1467
 
1468
          bfd_seek (abfd, cmd->flavours[i].offset + 0, SEEK_SET);
1469
 
1470
          if (bfd_bread (buf, 4, abfd) != 4)
1471
            return -1;
1472
 
1473
          abfd->start_address = bfd_h_get_32 (abfd, buf);
1474
        }
1475
    }
1476
 
1477
  return 0;
1478
}
1479
 
1480
int
1481
bfd_mach_o_scan (bfd *abfd,
1482
                 bfd_mach_o_header *header,
1483
                 bfd_mach_o_data_struct *mdata)
1484
{
1485
  unsigned int i;
1486
  enum bfd_architecture cputype;
1487
  unsigned long cpusubtype;
1488
 
1489
  mdata->header = *header;
1490
  mdata->symbols = NULL;
1491
 
1492
  abfd->flags = (abfd->xvec->object_flags
1493
                 | (abfd->flags & (BFD_IN_MEMORY | BFD_IO_FUNCS)));
1494
  abfd->tdata.mach_o_data = mdata;
1495
 
1496
  bfd_mach_o_convert_architecture (header->cputype, header->cpusubtype,
1497
                                   &cputype, &cpusubtype);
1498
  if (cputype == bfd_arch_unknown)
1499
    {
1500
      fprintf (stderr, "bfd_mach_o_scan: unknown architecture 0x%lx/0x%lx\n",
1501
               header->cputype, header->cpusubtype);
1502
      return -1;
1503
    }
1504
 
1505
  bfd_set_arch_mach (abfd, cputype, cpusubtype);
1506
 
1507
  if (header->ncmds != 0)
1508
    {
1509
      mdata->commands = bfd_alloc (abfd, header->ncmds * sizeof (bfd_mach_o_load_command));
1510
      if (mdata->commands == NULL)
1511
        return -1;
1512
 
1513
      for (i = 0; i < header->ncmds; i++)
1514
        {
1515
          bfd_mach_o_load_command *cur = &mdata->commands[i];
1516
 
1517
          if (i == 0)
1518
            cur->offset = 28;
1519
          else
1520
            {
1521
              bfd_mach_o_load_command *prev = &mdata->commands[i - 1];
1522
              cur->offset = prev->offset + prev->len;
1523
            }
1524
 
1525
          if (bfd_mach_o_scan_read_command (abfd, cur) < 0)
1526
            return -1;
1527
        }
1528
    }
1529
 
1530
  if (bfd_mach_o_scan_start_address (abfd) < 0)
1531
    return -1;
1532
 
1533
  bfd_mach_o_flatten_sections (abfd);
1534
  return 0;
1535
}
1536
 
1537
bfd_boolean
1538
bfd_mach_o_mkobject (bfd *abfd)
1539
{
1540
  bfd_mach_o_data_struct *mdata = NULL;
1541
 
1542
  mdata = bfd_alloc (abfd, sizeof (bfd_mach_o_data_struct));
1543
  if (mdata == NULL)
1544
    return FALSE;
1545
  abfd->tdata.mach_o_data = mdata;
1546
 
1547
  mdata->header.magic = 0;
1548
  mdata->header.cputype = 0;
1549
  mdata->header.cpusubtype = 0;
1550
  mdata->header.filetype = 0;
1551
  mdata->header.ncmds = 0;
1552
  mdata->header.sizeofcmds = 0;
1553
  mdata->header.flags = 0;
1554
  mdata->header.byteorder = BFD_ENDIAN_UNKNOWN;
1555
  mdata->commands = NULL;
1556
  mdata->nsymbols = 0;
1557
  mdata->symbols = NULL;
1558
  mdata->nsects = 0;
1559
  mdata->sections = NULL;
1560
  mdata->ibfd = NULL;
1561
 
1562
  return TRUE;
1563
}
1564
 
1565
const bfd_target *
1566
bfd_mach_o_object_p (bfd *abfd)
1567
{
1568
  struct bfd_preserve preserve;
1569
  bfd_mach_o_header header;
1570
 
1571
  preserve.marker = NULL;
1572
  if (bfd_mach_o_read_header (abfd, &header) != 0)
1573
    goto wrong;
1574
 
1575
  if (! (header.byteorder == BFD_ENDIAN_BIG
1576
         || header.byteorder == BFD_ENDIAN_LITTLE))
1577
    {
1578
      fprintf (stderr, "unknown header byte-order value 0x%lx\n",
1579
               (long) header.byteorder);
1580
      goto wrong;
1581
    }
1582
 
1583
  if (! ((header.byteorder == BFD_ENDIAN_BIG
1584
          && abfd->xvec->byteorder == BFD_ENDIAN_BIG
1585
          && abfd->xvec->header_byteorder == BFD_ENDIAN_BIG)
1586
         || (header.byteorder == BFD_ENDIAN_LITTLE
1587
             && abfd->xvec->byteorder == BFD_ENDIAN_LITTLE
1588
             && abfd->xvec->header_byteorder == BFD_ENDIAN_LITTLE)))
1589
    goto wrong;
1590
 
1591
  preserve.marker = bfd_zalloc (abfd, sizeof (bfd_mach_o_data_struct));
1592
  if (preserve.marker == NULL
1593
      || !bfd_preserve_save (abfd, &preserve))
1594
    goto fail;
1595
 
1596
  if (bfd_mach_o_scan (abfd, &header,
1597
                       (bfd_mach_o_data_struct *) preserve.marker) != 0)
1598
    goto wrong;
1599
 
1600
  bfd_preserve_finish (abfd, &preserve);
1601
  return abfd->xvec;
1602
 
1603
 wrong:
1604
  bfd_set_error (bfd_error_wrong_format);
1605
 
1606
 fail:
1607
  if (preserve.marker != NULL)
1608
    bfd_preserve_restore (abfd, &preserve);
1609
  return NULL;
1610
}
1611
 
1612
const bfd_target *
1613
bfd_mach_o_core_p (bfd *abfd)
1614
{
1615
  struct bfd_preserve preserve;
1616
  bfd_mach_o_header header;
1617
 
1618
  preserve.marker = NULL;
1619
  if (bfd_mach_o_read_header (abfd, &header) != 0)
1620
    goto wrong;
1621
 
1622
  if (! (header.byteorder == BFD_ENDIAN_BIG
1623
         || header.byteorder == BFD_ENDIAN_LITTLE))
1624
    {
1625
      fprintf (stderr, "unknown header byte-order value 0x%lx\n",
1626
               (long) header.byteorder);
1627
      abort ();
1628
    }
1629
 
1630
  if (! ((header.byteorder == BFD_ENDIAN_BIG
1631
          && abfd->xvec->byteorder == BFD_ENDIAN_BIG
1632
          && abfd->xvec->header_byteorder == BFD_ENDIAN_BIG)
1633
         || (header.byteorder == BFD_ENDIAN_LITTLE
1634
             && abfd->xvec->byteorder == BFD_ENDIAN_LITTLE
1635
             && abfd->xvec->header_byteorder == BFD_ENDIAN_LITTLE)))
1636
    goto wrong;
1637
 
1638
  if (header.filetype != BFD_MACH_O_MH_CORE)
1639
    goto wrong;
1640
 
1641
  preserve.marker = bfd_zalloc (abfd, sizeof (bfd_mach_o_data_struct));
1642
  if (preserve.marker == NULL
1643
      || !bfd_preserve_save (abfd, &preserve))
1644
    goto fail;
1645
 
1646
  if (bfd_mach_o_scan (abfd, &header,
1647
                       (bfd_mach_o_data_struct *) preserve.marker) != 0)
1648
    goto wrong;
1649
 
1650
  bfd_preserve_finish (abfd, &preserve);
1651
  return abfd->xvec;
1652
 
1653
 wrong:
1654
  bfd_set_error (bfd_error_wrong_format);
1655
 
1656
 fail:
1657
  if (preserve.marker != NULL)
1658
    bfd_preserve_restore (abfd, &preserve);
1659
  return NULL;
1660
}
1661
 
1662
typedef struct mach_o_fat_archentry
1663
{
1664
  unsigned long cputype;
1665
  unsigned long cpusubtype;
1666
  unsigned long offset;
1667
  unsigned long size;
1668
  unsigned long align;
1669
  bfd *abfd;
1670
} mach_o_fat_archentry;
1671
 
1672
typedef struct mach_o_fat_data_struct
1673
{
1674
  unsigned long magic;
1675
  unsigned long nfat_arch;
1676
  mach_o_fat_archentry *archentries;
1677
} mach_o_fat_data_struct;
1678
 
1679
const bfd_target *
1680
bfd_mach_o_archive_p (bfd *abfd)
1681
{
1682
  mach_o_fat_data_struct *adata = NULL;
1683
  unsigned char buf[20];
1684
  unsigned long i;
1685
 
1686
  bfd_seek (abfd, 0, SEEK_SET);
1687
  if (bfd_bread ((PTR) buf, 8, abfd) != 8)
1688
    goto error;
1689
 
1690
  adata = bfd_alloc (abfd, sizeof (mach_o_fat_data_struct));
1691
  if (adata == NULL)
1692
    goto error;
1693
 
1694
  adata->magic = bfd_getb32 (buf);
1695
  adata->nfat_arch = bfd_getb32 (buf + 4);
1696
  if (adata->magic != 0xcafebabe)
1697
    goto error;
1698
 
1699
  adata->archentries =
1700
    bfd_alloc (abfd, adata->nfat_arch * sizeof (mach_o_fat_archentry));
1701
  if (adata->archentries == NULL)
1702
    goto error;
1703
 
1704
  for (i = 0; i < adata->nfat_arch; i++)
1705
    {
1706
      bfd_seek (abfd, 8 + 20 * i, SEEK_SET);
1707
 
1708
      if (bfd_bread ((PTR) buf, 20, abfd) != 20)
1709
        goto error;
1710
      adata->archentries[i].cputype = bfd_getb32 (buf);
1711
      adata->archentries[i].cpusubtype = bfd_getb32 (buf + 4);
1712
      adata->archentries[i].offset = bfd_getb32 (buf + 8);
1713
      adata->archentries[i].size = bfd_getb32 (buf + 12);
1714
      adata->archentries[i].align = bfd_getb32 (buf + 16);
1715
      adata->archentries[i].abfd = NULL;
1716
    }
1717
 
1718
  abfd->tdata.mach_o_fat_data = adata;
1719
  return abfd->xvec;
1720
 
1721
 error:
1722
  if (adata != NULL)
1723
    bfd_release (abfd, adata);
1724
  bfd_set_error (bfd_error_wrong_format);
1725
  return NULL;
1726
}
1727
 
1728
bfd *
1729
bfd_mach_o_openr_next_archived_file (bfd *archive, bfd *prev)
1730
{
1731
  mach_o_fat_data_struct *adata;
1732
  mach_o_fat_archentry *entry = NULL;
1733
  unsigned long i;
1734
 
1735
  adata = (mach_o_fat_data_struct *) archive->tdata.mach_o_fat_data;
1736
  BFD_ASSERT (adata != NULL);
1737
 
1738
  /* Find index of previous entry.  */
1739
  if (prev == NULL)
1740
    i = 0;       /* Start at first one.  */
1741
  else
1742
    {
1743
      for (i = 0; i < adata->nfat_arch; i++)
1744
        {
1745
          if (adata->archentries[i].abfd == prev)
1746
            break;
1747
        }
1748
 
1749
      if (i == adata->nfat_arch)
1750
        {
1751
          /* Not found.  */
1752
          bfd_set_error (bfd_error_bad_value);
1753
          return NULL;
1754
        }
1755
    i++;        /* Get next entry.  */
1756
  }
1757
 
1758
  if (i >= adata->nfat_arch)
1759
    {
1760
      bfd_set_error (bfd_error_no_more_archived_files);
1761
      return NULL;
1762
    }
1763
 
1764
  entry = &adata->archentries[i];
1765
  if (entry->abfd == NULL)
1766
    {
1767
      bfd *nbfd = _bfd_new_bfd_contained_in (archive);
1768
      char *s = NULL;
1769
 
1770
      if (nbfd == NULL)
1771
        return NULL;
1772
 
1773
      nbfd->origin = entry->offset;
1774
      s = bfd_malloc (strlen (archive->filename) + 1);
1775
      if (s == NULL)
1776
        return NULL;
1777
      strcpy (s, archive->filename);
1778
      nbfd->filename = s;
1779
      nbfd->iostream = NULL;
1780
      entry->abfd = nbfd;
1781
    }
1782
 
1783
  return entry->abfd;
1784
}
1785
 
1786
int
1787
bfd_mach_o_lookup_section (bfd *abfd,
1788
                           asection *section,
1789
                           bfd_mach_o_load_command **mcommand,
1790
                           bfd_mach_o_section **msection)
1791
{
1792
  struct mach_o_data_struct *md = abfd->tdata.mach_o_data;
1793
  unsigned int i, j, num;
1794
 
1795
  bfd_mach_o_load_command *ncmd = NULL;
1796
  bfd_mach_o_section *nsect = NULL;
1797
 
1798
  BFD_ASSERT (mcommand != NULL);
1799
  BFD_ASSERT (msection != NULL);
1800
 
1801
  num = 0;
1802
  for (i = 0; i < md->header.ncmds; i++)
1803
    {
1804
      struct bfd_mach_o_load_command *cmd = &md->commands[i];
1805
      struct bfd_mach_o_segment_command *seg = NULL;
1806
 
1807
      if (cmd->type != BFD_MACH_O_LC_SEGMENT)
1808
        continue;
1809
      seg = &cmd->command.segment;
1810
 
1811
      if (seg->segment == section)
1812
        {
1813
          if (num == 0)
1814
            ncmd = cmd;
1815
          num++;
1816
        }
1817
 
1818
      for (j = 0; j < seg->nsects; j++)
1819
        {
1820
          struct bfd_mach_o_section *sect = &seg->sections[j];
1821
 
1822
          if (sect->bfdsection == section)
1823
            {
1824
              if (num == 0)
1825
                nsect = sect;
1826
              num++;
1827
            }
1828
        }
1829
    }
1830
 
1831
  *mcommand = ncmd;
1832
  *msection = nsect;
1833
  return num;
1834
}
1835
 
1836
int
1837
bfd_mach_o_lookup_command (bfd *abfd,
1838
                           bfd_mach_o_load_command_type type,
1839
                           bfd_mach_o_load_command **mcommand)
1840
{
1841
  struct mach_o_data_struct *md = NULL;
1842
  bfd_mach_o_load_command *ncmd = NULL;
1843
  unsigned int i, num;
1844
 
1845
  md = abfd->tdata.mach_o_data;
1846
 
1847
  BFD_ASSERT (md != NULL);
1848
  BFD_ASSERT (mcommand != NULL);
1849
 
1850
  num = 0;
1851
  for (i = 0; i < md->header.ncmds; i++)
1852
    {
1853
      struct bfd_mach_o_load_command *cmd = &md->commands[i];
1854
 
1855
      if (cmd->type != type)
1856
        continue;
1857
 
1858
      if (num == 0)
1859
        ncmd = cmd;
1860
      num++;
1861
    }
1862
 
1863
  *mcommand = ncmd;
1864
  return num;
1865
}
1866
 
1867
unsigned long
1868
bfd_mach_o_stack_addr (enum bfd_mach_o_cpu_type type)
1869
{
1870
  switch (type)
1871
    {
1872
    case BFD_MACH_O_CPU_TYPE_MC680x0:
1873
      return 0x04000000;
1874
    case BFD_MACH_O_CPU_TYPE_MC88000:
1875
      return 0xffffe000;
1876
    case BFD_MACH_O_CPU_TYPE_POWERPC:
1877
      return 0xc0000000;
1878
    case BFD_MACH_O_CPU_TYPE_I386:
1879
      return 0xc0000000;
1880
    case BFD_MACH_O_CPU_TYPE_SPARC:
1881
      return 0xf0000000;
1882
    case BFD_MACH_O_CPU_TYPE_I860:
1883
      return 0;
1884
    case BFD_MACH_O_CPU_TYPE_HPPA:
1885
      return 0xc0000000 - 0x04000000;
1886
    default:
1887
      return 0;
1888
    }
1889
}
1890
 
1891
int
1892
bfd_mach_o_core_fetch_environment (bfd *abfd,
1893
                                   unsigned char **rbuf,
1894
                                   unsigned int *rlen)
1895
{
1896
  bfd_mach_o_data_struct *mdata = abfd->tdata.mach_o_data;
1897
  unsigned long stackaddr = bfd_mach_o_stack_addr (mdata->header.cputype);
1898
  unsigned int i = 0;
1899
 
1900
  for (i = 0; i < mdata->header.ncmds; i++)
1901
    {
1902
      bfd_mach_o_load_command *cur = &mdata->commands[i];
1903
      bfd_mach_o_segment_command *seg = NULL;
1904
 
1905
      if (cur->type != BFD_MACH_O_LC_SEGMENT)
1906
        continue;
1907
 
1908
      seg = &cur->command.segment;
1909
 
1910
      if ((seg->vmaddr + seg->vmsize) == stackaddr)
1911
        {
1912
          unsigned long start = seg->fileoff;
1913
          unsigned long end = seg->fileoff + seg->filesize;
1914
          unsigned char *buf = bfd_malloc (1024);
1915
          unsigned long size = 1024;
1916
 
1917
          for (;;)
1918
            {
1919
              bfd_size_type nread = 0;
1920
              unsigned long offset;
1921
              int found_nonnull = 0;
1922
 
1923
              if (size > (end - start))
1924
                size = (end - start);
1925
 
1926
              buf = bfd_realloc_or_free (buf, size);
1927
              if (buf == NULL)
1928
                return -1;
1929
 
1930
              bfd_seek (abfd, end - size, SEEK_SET);
1931
              nread = bfd_bread (buf, size, abfd);
1932
 
1933
              if (nread != size)
1934
                {
1935
                  free (buf);
1936
                  return -1;
1937
                }
1938
 
1939
              for (offset = 4; offset <= size; offset += 4)
1940
                {
1941
                  unsigned long val;
1942
 
1943
                  val = *((unsigned long *) (buf + size - offset));
1944
                  if (! found_nonnull)
1945
                    {
1946
                      if (val != 0)
1947
                        found_nonnull = 1;
1948
                    }
1949
                  else if (val == 0x0)
1950
                    {
1951
                      unsigned long bottom;
1952
                      unsigned long top;
1953
 
1954
                      bottom = seg->fileoff + seg->filesize - offset;
1955
                      top = seg->fileoff + seg->filesize - 4;
1956
                      *rbuf = bfd_malloc (top - bottom);
1957
                      *rlen = top - bottom;
1958
 
1959
                      memcpy (*rbuf, buf + size - *rlen, *rlen);
1960
                      free (buf);
1961
                      return 0;
1962
                    }
1963
                }
1964
 
1965
              if (size == (end - start))
1966
                break;
1967
 
1968
              size *= 2;
1969
            }
1970
 
1971
          free (buf);
1972
        }
1973
    }
1974
 
1975
  return -1;
1976
}
1977
 
1978
char *
1979
bfd_mach_o_core_file_failing_command (bfd *abfd)
1980
{
1981
  unsigned char *buf = NULL;
1982
  unsigned int len = 0;
1983
  int ret = -1;
1984
 
1985
  ret = bfd_mach_o_core_fetch_environment (abfd, &buf, &len);
1986
  if (ret < 0)
1987
    return NULL;
1988
 
1989
  return (char *) buf;
1990
}
1991
 
1992
int
1993
bfd_mach_o_core_file_failing_signal (bfd *abfd ATTRIBUTE_UNUSED)
1994
{
1995
  return 0;
1996
}
1997
 
1998
#define TARGET_NAME             mach_o_be_vec
1999
#define TARGET_STRING           "mach-o-be"
2000
#define TARGET_BIG_ENDIAN       1
2001
#define TARGET_ARCHIVE          0
2002
 
2003
#include "mach-o-target.c"
2004
 
2005
#undef TARGET_NAME
2006
#undef TARGET_STRING
2007
#undef TARGET_BIG_ENDIAN
2008
#undef TARGET_ARCHIVE
2009
 
2010
#define TARGET_NAME             mach_o_le_vec
2011
#define TARGET_STRING           "mach-o-le"
2012
#define TARGET_BIG_ENDIAN       0
2013
#define TARGET_ARCHIVE          0
2014
 
2015
#include "mach-o-target.c"
2016
 
2017
#undef TARGET_NAME
2018
#undef TARGET_STRING
2019
#undef TARGET_BIG_ENDIAN
2020
#undef TARGET_ARCHIVE
2021
 
2022
#define TARGET_NAME             mach_o_fat_vec
2023
#define TARGET_STRING           "mach-o-fat"
2024
#define TARGET_BIG_ENDIAN       1
2025
#define TARGET_ARCHIVE          1
2026
 
2027
#include "mach-o-target.c"
2028
 
2029
#undef TARGET_NAME
2030
#undef TARGET_STRING
2031
#undef TARGET_BIG_ENDIAN
2032
#undef TARGET_ARCHIVE

powered by: WebSVN 2.1.0

© copyright 1999-2024 OpenCores.org, equivalent to Oliscience, all rights reserved. OpenCores®, registered trademark.