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

Subversion Repositories open8_urisc

[/] [open8_urisc/] [trunk/] [gnu/] [binutils/] [bfd/] [mach-o.c] - Blame information for rev 97

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

Line No. Rev Author Line
1 14 khays
/* Mach-O support for BFD.
2
   Copyright 1999, 2000, 2001, 2002, 2003, 2004, 2005, 2006, 2007, 2008,
3
   2009, 2010, 2011
4
   Free Software Foundation, Inc.
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 3 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., 51 Franklin Street - Fifth Floor, Boston,
21
   MA 02110-1301, USA.  */
22
 
23
#include "sysdep.h"
24
#include "mach-o.h"
25
#include "bfd.h"
26
#include "libbfd.h"
27
#include "libiberty.h"
28
#include "aout/stab_gnu.h"
29
#include <ctype.h>
30
 
31
#define bfd_mach_o_object_p bfd_mach_o_gen_object_p
32
#define bfd_mach_o_core_p bfd_mach_o_gen_core_p
33
#define bfd_mach_o_mkobject bfd_mach_o_gen_mkobject
34
 
35
#define FILE_ALIGN(off, algn) \
36
  (((off) + ((file_ptr) 1 << (algn)) - 1) & ((file_ptr) -1 << (algn)))
37
 
38
static int bfd_mach_o_read_symtab_symbols (bfd *);
39
 
40
unsigned int
41
bfd_mach_o_version (bfd *abfd)
42
{
43
  bfd_mach_o_data_struct *mdata = NULL;
44
 
45
  BFD_ASSERT (bfd_mach_o_valid (abfd));
46
  mdata = bfd_mach_o_get_data (abfd);
47
 
48
  return mdata->header.version;
49
}
50
 
51
bfd_boolean
52
bfd_mach_o_valid (bfd *abfd)
53
{
54
  if (abfd == NULL || abfd->xvec == NULL)
55
    return FALSE;
56
 
57
  if (abfd->xvec->flavour != bfd_target_mach_o_flavour)
58
    return FALSE;
59
 
60
  if (bfd_mach_o_get_data (abfd) == NULL)
61
    return FALSE;
62
  return TRUE;
63
}
64
 
65
static INLINE bfd_boolean
66
mach_o_wide_p (bfd_mach_o_header *header)
67
{
68
  switch (header->version)
69
    {
70
    case 1:
71
      return FALSE;
72
    case 2:
73
      return TRUE;
74
    default:
75
      BFD_FAIL ();
76
      return FALSE;
77
    }
78
}
79
 
80
static INLINE bfd_boolean
81
bfd_mach_o_wide_p (bfd *abfd)
82
{
83
  return mach_o_wide_p (&bfd_mach_o_get_data (abfd)->header);
84
}
85
 
86
/* Tables to translate well known Mach-O segment/section names to bfd
87
   names.  Use of canonical names (such as .text or .debug_frame) is required
88
   by gdb.  */
89
 
90
struct mach_o_section_name_xlat
91
{
92
  const char *bfd_name;
93
  const char *mach_o_name;
94
  flagword flags;
95
};
96
 
97
static const struct mach_o_section_name_xlat dwarf_section_names_xlat[] =
98
  {
99
    { ".debug_frame",    "__debug_frame",    SEC_DEBUGGING },
100
    { ".debug_info",     "__debug_info",     SEC_DEBUGGING },
101
    { ".debug_abbrev",   "__debug_abbrev",   SEC_DEBUGGING },
102
    { ".debug_aranges",  "__debug_aranges",  SEC_DEBUGGING },
103
    { ".debug_macinfo",  "__debug_macinfo",  SEC_DEBUGGING },
104
    { ".debug_line",     "__debug_line",     SEC_DEBUGGING },
105
    { ".debug_loc",      "__debug_loc",      SEC_DEBUGGING },
106
    { ".debug_pubnames", "__debug_pubnames", SEC_DEBUGGING },
107
    { ".debug_pubtypes", "__debug_pubtypes", SEC_DEBUGGING },
108
    { ".debug_str",      "__debug_str",      SEC_DEBUGGING },
109
    { ".debug_ranges",   "__debug_ranges",   SEC_DEBUGGING },
110
    { NULL, NULL, 0}
111
  };
112
 
113
static const struct mach_o_section_name_xlat text_section_names_xlat[] =
114
  {
115
    { ".text",     "__text",      SEC_CODE | SEC_LOAD },
116
    { ".const",    "__const",     SEC_READONLY | SEC_DATA | SEC_LOAD },
117
    { ".cstring",  "__cstring",   SEC_READONLY | SEC_DATA | SEC_LOAD },
118
    { ".eh_frame", "__eh_frame",  SEC_READONLY | SEC_LOAD },
119
    { NULL, NULL, 0}
120
  };
121
 
122
static const struct mach_o_section_name_xlat data_section_names_xlat[] =
123
  {
124
    { ".data",                "__data",          SEC_DATA | SEC_LOAD },
125
    { ".const_data",          "__const",         SEC_DATA | SEC_LOAD },
126
    { ".dyld",                "__dyld",          SEC_DATA | SEC_LOAD },
127
    { ".lazy_symbol_ptr",     "__la_symbol_ptr", SEC_DATA | SEC_LOAD },
128
    { ".non_lazy_symbol_ptr", "__nl_symbol_ptr", SEC_DATA | SEC_LOAD },
129
    { ".bss",                 "__bss",           SEC_NO_FLAGS },
130
    { NULL, NULL, 0}
131
  };
132
 
133
struct mach_o_segment_name_xlat
134
{
135
  const char *segname;
136
  const struct mach_o_section_name_xlat *sections;
137
};
138
 
139
static const struct mach_o_segment_name_xlat segsec_names_xlat[] =
140
  {
141
    { "__DWARF", dwarf_section_names_xlat },
142
    { "__TEXT", text_section_names_xlat },
143
    { "__DATA", data_section_names_xlat },
144
    { NULL, NULL }
145
  };
146
 
147
 
148
/* Mach-O to bfd names.  */
149
 
150
static void
151
bfd_mach_o_convert_section_name_to_bfd (bfd *abfd, bfd_mach_o_section *section,
152
                                        char **name, flagword *flags)
153
{
154
  const struct mach_o_segment_name_xlat *seg;
155
  char *res;
156
  unsigned int len;
157
  const char *pfx = "";
158
 
159
  *name = NULL;
160
  *flags = SEC_NO_FLAGS;
161
 
162
  for (seg = segsec_names_xlat; seg->segname; seg++)
163
    {
164
      if (strcmp (seg->segname, section->segname) == 0)
165
        {
166
          const struct mach_o_section_name_xlat *sec;
167
 
168
          for (sec = seg->sections; sec->mach_o_name; sec++)
169
            {
170
              if (strcmp (sec->mach_o_name, section->sectname) == 0)
171
                {
172
                  len = strlen (sec->bfd_name);
173
                  res = bfd_alloc (abfd, len + 1);
174
 
175
                  if (res == NULL)
176
                    return;
177
                  strcpy (res, sec->bfd_name);
178
                  *name = res;
179
                  *flags = sec->flags;
180
                  return;
181
                }
182
            }
183
        }
184
    }
185
 
186
  len = strlen (section->segname) + 1
187
    + strlen (section->sectname) + 1;
188
 
189
  /* Put "LC_SEGMENT." prefix if the segment name is weird (ie doesn't start
190
     with an underscore.  */
191
  if (section->segname[0] != '_')
192
    {
193
      static const char seg_pfx[] = "LC_SEGMENT.";
194
 
195
      pfx = seg_pfx;
196
      len += sizeof (seg_pfx) - 1;
197
    }
198
 
199
  res = bfd_alloc (abfd, len);
200
  if (res == NULL)
201
    return;
202
  snprintf (res, len, "%s%s.%s", pfx, section->segname, section->sectname);
203
  *name = res;
204
}
205
 
206
/* Convert a bfd section name to a Mach-O segment + section name.  */
207
 
208
static void
209
bfd_mach_o_convert_section_name_to_mach_o (bfd *abfd ATTRIBUTE_UNUSED,
210
                                           asection *sect,
211
                                           bfd_mach_o_section *section)
212
{
213
  const struct mach_o_segment_name_xlat *seg;
214
  const char *name = bfd_get_section_name (abfd, sect);
215
  const char *dot;
216
  unsigned int len;
217
  unsigned int seglen;
218
  unsigned int seclen;
219
 
220
  /* List of well known names.  They all start with a dot.  */
221
  if (name[0] == '.')
222
    for (seg = segsec_names_xlat; seg->segname; seg++)
223
      {
224
        const struct mach_o_section_name_xlat *sec;
225
 
226
        for (sec = seg->sections; sec->mach_o_name; sec++)
227
          {
228
            if (strcmp (sec->bfd_name, name) == 0)
229
              {
230
                strcpy (section->segname, seg->segname);
231
                strcpy (section->sectname, sec->mach_o_name);
232
                return;
233
              }
234
          }
235
      }
236
 
237
  /* Strip LC_SEGMENT. prefix.  */
238
  if (strncmp (name, "LC_SEGMENT.", 11) == 0)
239
    name += 11;
240
 
241
  /* Find a dot.  */
242
  dot = strchr (name, '.');
243
  len = strlen (name);
244
 
245
  /* Try to split name into segment and section names.  */
246
  if (dot && dot != name)
247
    {
248
      seglen = dot - name;
249
      seclen = len - (dot + 1 - name);
250
 
251
      if (seglen < 16 && seclen < 16)
252
        {
253
          memcpy (section->segname, name, seglen);
254
          section->segname[seglen] = 0;
255
          memcpy (section->sectname, dot + 1, seclen);
256
          section->sectname[seclen] = 0;
257
          return;
258
        }
259
    }
260
 
261
  if (len > 16)
262
    len = 16;
263
  memcpy (section->segname, name, len);
264
  section->segname[len] = 0;
265
  memcpy (section->sectname, name, len);
266
  section->sectname[len] = 0;
267
}
268
 
269
/* Return the size of an entry for section SEC.
270
   Must be called only for symbol pointer section and symbol stubs
271
   sections.  */
272
 
273
static unsigned int
274
bfd_mach_o_section_get_entry_size (bfd *abfd, bfd_mach_o_section *sec)
275
{
276
  switch (sec->flags & BFD_MACH_O_SECTION_TYPE_MASK)
277
    {
278
    case BFD_MACH_O_S_NON_LAZY_SYMBOL_POINTERS:
279
    case BFD_MACH_O_S_LAZY_SYMBOL_POINTERS:
280
      return bfd_mach_o_wide_p (abfd) ? 8 : 4;
281
    case BFD_MACH_O_S_SYMBOL_STUBS:
282
      return sec->reserved2;
283
    default:
284
      BFD_FAIL ();
285
      return 0;
286
    }
287
}
288
 
289
/* Return the number of indirect symbols for a section.
290
   Must be called only for symbol pointer section and symbol stubs
291
   sections.  */
292
 
293
static unsigned int
294
bfd_mach_o_section_get_nbr_indirect (bfd *abfd, bfd_mach_o_section *sec)
295
{
296
  unsigned int elsz;
297
 
298
  elsz = bfd_mach_o_section_get_entry_size (abfd, sec);
299
  if (elsz == 0)
300
    return 0;
301
  else
302
    return sec->size / elsz;
303
}
304
 
305
 
306
/* Copy any private info we understand from the input symbol
307
   to the output symbol.  */
308
 
309
bfd_boolean
310
bfd_mach_o_bfd_copy_private_symbol_data (bfd *ibfd ATTRIBUTE_UNUSED,
311
                                         asymbol *isymbol ATTRIBUTE_UNUSED,
312
                                         bfd *obfd ATTRIBUTE_UNUSED,
313
                                         asymbol *osymbol ATTRIBUTE_UNUSED)
314
{
315
  return TRUE;
316
}
317
 
318
/* Copy any private info we understand from the input section
319
   to the output section.  */
320
 
321
bfd_boolean
322
bfd_mach_o_bfd_copy_private_section_data (bfd *ibfd ATTRIBUTE_UNUSED,
323
                                          asection *isection ATTRIBUTE_UNUSED,
324
                                          bfd *obfd ATTRIBUTE_UNUSED,
325
                                          asection *osection ATTRIBUTE_UNUSED)
326
{
327
  return TRUE;
328
}
329
 
330
/* Copy any private info we understand from the input bfd
331
   to the output bfd.  */
332
 
333
bfd_boolean
334
bfd_mach_o_bfd_copy_private_bfd_data (bfd *ibfd, bfd *obfd)
335
{
336
  if (bfd_get_flavour (ibfd) != bfd_target_mach_o_flavour
337
      || bfd_get_flavour (obfd) != bfd_target_mach_o_flavour)
338
    return TRUE;
339
 
340
  BFD_ASSERT (bfd_mach_o_valid (ibfd));
341
  BFD_ASSERT (bfd_mach_o_valid (obfd));
342
 
343
  /* FIXME: copy commands.  */
344
 
345
  return TRUE;
346
}
347
 
348
/* Count the total number of symbols.  */
349
 
350
static long
351
bfd_mach_o_count_symbols (bfd *abfd)
352
{
353
  bfd_mach_o_data_struct *mdata = bfd_mach_o_get_data (abfd);
354
 
355
  if (mdata->symtab == NULL)
356
    return 0;
357
  return mdata->symtab->nsyms;
358
}
359
 
360
long
361
bfd_mach_o_get_symtab_upper_bound (bfd *abfd)
362
{
363
  long nsyms = bfd_mach_o_count_symbols (abfd);
364
 
365
  return ((nsyms + 1) * sizeof (asymbol *));
366
}
367
 
368
long
369
bfd_mach_o_canonicalize_symtab (bfd *abfd, asymbol **alocation)
370
{
371
  bfd_mach_o_data_struct *mdata = bfd_mach_o_get_data (abfd);
372
  long nsyms = bfd_mach_o_count_symbols (abfd);
373
  bfd_mach_o_symtab_command *sym = mdata->symtab;
374
  unsigned long j;
375
 
376
  if (nsyms < 0)
377
    return nsyms;
378
 
379
  if (bfd_mach_o_read_symtab_symbols (abfd) != 0)
380
    {
381
      (*_bfd_error_handler) (_("bfd_mach_o_canonicalize_symtab: unable to load symbols"));
382
      return 0;
383
    }
384
 
385
  BFD_ASSERT (sym->symbols != NULL);
386
 
387
  for (j = 0; j < sym->nsyms; j++)
388
    alocation[j] = &sym->symbols[j].symbol;
389
 
390
  alocation[j] = NULL;
391
 
392
  return nsyms;
393
}
394
 
395
long
396
bfd_mach_o_get_synthetic_symtab (bfd *abfd,
397
                                 long symcount ATTRIBUTE_UNUSED,
398
                                 asymbol **syms ATTRIBUTE_UNUSED,
399
                                 long dynsymcount ATTRIBUTE_UNUSED,
400
                                 asymbol **dynsyms ATTRIBUTE_UNUSED,
401
                                 asymbol **ret)
402
{
403
  bfd_mach_o_data_struct *mdata = bfd_mach_o_get_data (abfd);
404
  bfd_mach_o_dysymtab_command *dysymtab = mdata->dysymtab;
405
  bfd_mach_o_symtab_command *symtab = mdata->symtab;
406
  asymbol *s;
407
  unsigned long count, i, j, n;
408
  size_t size;
409
  char *names;
410
  char *nul_name;
411
 
412
  *ret = NULL;
413
 
414
  if (dysymtab == NULL || symtab == NULL || symtab->symbols == NULL)
415
    return 0;
416
 
417
  if (dysymtab->nindirectsyms == 0)
418
    return 0;
419
 
420
  count = dysymtab->nindirectsyms;
421
  size = count * sizeof (asymbol) + 1;
422
 
423
  for (j = 0; j < count; j++)
424
    {
425
      unsigned int isym = dysymtab->indirect_syms[j];
426
 
427
      if (isym < symtab->nsyms && symtab->symbols[isym].symbol.name)
428
        size += strlen (symtab->symbols[isym].symbol.name) + sizeof ("$stub");
429
    }
430
 
431
  s = *ret = (asymbol *) bfd_malloc (size);
432
  if (s == NULL)
433
    return -1;
434
  names = (char *) (s + count);
435
  nul_name = names;
436
  *names++ = 0;
437
 
438
  n = 0;
439
  for (i = 0; i < mdata->nsects; i++)
440
    {
441
      bfd_mach_o_section *sec = mdata->sections[i];
442
      unsigned int first, last;
443
      bfd_vma addr;
444
      bfd_vma entry_size;
445
 
446
      switch (sec->flags & BFD_MACH_O_SECTION_TYPE_MASK)
447
        {
448
        case BFD_MACH_O_S_NON_LAZY_SYMBOL_POINTERS:
449
        case BFD_MACH_O_S_LAZY_SYMBOL_POINTERS:
450
        case BFD_MACH_O_S_SYMBOL_STUBS:
451
          first = sec->reserved1;
452
          last = first + bfd_mach_o_section_get_nbr_indirect (abfd, sec);
453
          addr = sec->addr;
454
          entry_size = bfd_mach_o_section_get_entry_size (abfd, sec);
455
          for (j = first; j < last; j++)
456
            {
457
              unsigned int isym = dysymtab->indirect_syms[j];
458
 
459
              s->flags = BSF_GLOBAL | BSF_SYNTHETIC;
460
              s->section = sec->bfdsection;
461
              s->value = addr - sec->addr;
462
              s->udata.p = NULL;
463
 
464
              if (isym < symtab->nsyms
465
                  && symtab->symbols[isym].symbol.name)
466
                {
467
                  const char *sym = symtab->symbols[isym].symbol.name;
468
                  size_t len;
469
 
470
                  s->name = names;
471
                  len = strlen (sym);
472
                  memcpy (names, sym, len);
473
                  names += len;
474
                  memcpy (names, "$stub", sizeof ("$stub"));
475
                  names += sizeof ("$stub");
476
                }
477
              else
478
                s->name = nul_name;
479
 
480
              addr += entry_size;
481
              s++;
482
              n++;
483
            }
484
          break;
485
        default:
486
          break;
487
        }
488
    }
489
 
490
  return n;
491
}
492
 
493
void
494
bfd_mach_o_get_symbol_info (bfd *abfd ATTRIBUTE_UNUSED,
495
                            asymbol *symbol,
496
                            symbol_info *ret)
497
{
498
  bfd_symbol_info (symbol, ret);
499
}
500
 
501
void
502
bfd_mach_o_print_symbol (bfd *abfd,
503
                         void * afile,
504
                         asymbol *symbol,
505
                         bfd_print_symbol_type how)
506
{
507
  FILE *file = (FILE *) afile;
508
  const char *name;
509
  bfd_mach_o_asymbol *asym = (bfd_mach_o_asymbol *)symbol;
510
 
511
  switch (how)
512
    {
513
    case bfd_print_symbol_name:
514
      fprintf (file, "%s", symbol->name);
515
      break;
516
    default:
517
      bfd_print_symbol_vandf (abfd, (void *) file, symbol);
518
      if (asym->n_type & BFD_MACH_O_N_STAB)
519
        name = bfd_get_stab_name (asym->n_type);
520
      else
521
        switch (asym->n_type & BFD_MACH_O_N_TYPE)
522
          {
523
          case BFD_MACH_O_N_UNDF:
524
            name = "UND";
525
            break;
526
          case BFD_MACH_O_N_ABS:
527
            name = "ABS";
528
            break;
529
          case BFD_MACH_O_N_INDR:
530
            name = "INDR";
531
            break;
532
          case BFD_MACH_O_N_PBUD:
533
            name = "PBUD";
534
            break;
535
          case BFD_MACH_O_N_SECT:
536
            name = "SECT";
537
            break;
538
          default:
539
            name = "???";
540
            break;
541
          }
542
      if (name == NULL)
543
        name = "";
544
      fprintf (file, " %02x %-6s %02x %04x",
545
               asym->n_type, name, asym->n_sect, asym->n_desc);
546
      if ((asym->n_type & BFD_MACH_O_N_STAB) == 0
547
          && (asym->n_type & BFD_MACH_O_N_TYPE) == BFD_MACH_O_N_SECT)
548
        fprintf (file, " %-5s", symbol->section->name);
549
      fprintf (file, " %s", symbol->name);
550
    }
551
}
552
 
553
static void
554
bfd_mach_o_convert_architecture (bfd_mach_o_cpu_type mtype,
555
                                 bfd_mach_o_cpu_subtype msubtype ATTRIBUTE_UNUSED,
556
                                 enum bfd_architecture *type,
557
                                 unsigned long *subtype)
558
{
559
  *subtype = bfd_arch_unknown;
560
 
561
  switch (mtype)
562
    {
563
    case BFD_MACH_O_CPU_TYPE_VAX: *type = bfd_arch_vax; break;
564
    case BFD_MACH_O_CPU_TYPE_MC680x0: *type = bfd_arch_m68k; break;
565
    case BFD_MACH_O_CPU_TYPE_I386:
566
      *type = bfd_arch_i386;
567
      *subtype = bfd_mach_i386_i386;
568
      break;
569
    case BFD_MACH_O_CPU_TYPE_X86_64:
570
      *type = bfd_arch_i386;
571
      *subtype = bfd_mach_x86_64;
572
      break;
573
    case BFD_MACH_O_CPU_TYPE_MIPS: *type = bfd_arch_mips; break;
574
    case BFD_MACH_O_CPU_TYPE_MC98000: *type = bfd_arch_m98k; break;
575
    case BFD_MACH_O_CPU_TYPE_HPPA: *type = bfd_arch_hppa; break;
576
    case BFD_MACH_O_CPU_TYPE_ARM: *type = bfd_arch_arm; break;
577
    case BFD_MACH_O_CPU_TYPE_MC88000: *type = bfd_arch_m88k; break;
578
    case BFD_MACH_O_CPU_TYPE_SPARC:
579
      *type = bfd_arch_sparc;
580
      *subtype = bfd_mach_sparc;
581
      break;
582
    case BFD_MACH_O_CPU_TYPE_I860: *type = bfd_arch_i860; break;
583
    case BFD_MACH_O_CPU_TYPE_ALPHA: *type = bfd_arch_alpha; break;
584
    case BFD_MACH_O_CPU_TYPE_POWERPC:
585
      *type = bfd_arch_powerpc;
586
      *subtype = bfd_mach_ppc;
587
      break;
588
    case BFD_MACH_O_CPU_TYPE_POWERPC_64:
589
      *type = bfd_arch_powerpc;
590
      *subtype = bfd_mach_ppc64;
591
      break;
592
    default:
593
      *type = bfd_arch_unknown;
594
      break;
595
    }
596
}
597
 
598
static bfd_boolean
599
bfd_mach_o_write_header (bfd *abfd, bfd_mach_o_header *header)
600
{
601
  unsigned char buf[32];
602
  unsigned int size;
603
 
604
  size = mach_o_wide_p (header) ?
605
    BFD_MACH_O_HEADER_64_SIZE : BFD_MACH_O_HEADER_SIZE;
606
 
607
  bfd_h_put_32 (abfd, header->magic, buf + 0);
608
  bfd_h_put_32 (abfd, header->cputype, buf + 4);
609
  bfd_h_put_32 (abfd, header->cpusubtype, buf + 8);
610
  bfd_h_put_32 (abfd, header->filetype, buf + 12);
611
  bfd_h_put_32 (abfd, header->ncmds, buf + 16);
612
  bfd_h_put_32 (abfd, header->sizeofcmds, buf + 20);
613
  bfd_h_put_32 (abfd, header->flags, buf + 24);
614
 
615
  if (mach_o_wide_p (header))
616
    bfd_h_put_32 (abfd, header->reserved, buf + 28);
617
 
618
  if (bfd_seek (abfd, 0, SEEK_SET) != 0
619
      || bfd_bwrite ((void *) buf, size, abfd) != size)
620
    return FALSE;
621
 
622
  return TRUE;
623
}
624
 
625
static int
626
bfd_mach_o_write_thread (bfd *abfd, bfd_mach_o_load_command *command)
627
{
628
  bfd_mach_o_thread_command *cmd = &command->command.thread;
629
  unsigned int i;
630
  unsigned char buf[8];
631
  unsigned int offset;
632
 
633
  BFD_ASSERT ((command->type == BFD_MACH_O_LC_THREAD)
634
              || (command->type == BFD_MACH_O_LC_UNIXTHREAD));
635
 
636
  offset = 8;
637
  for (i = 0; i < cmd->nflavours; i++)
638
    {
639
      BFD_ASSERT ((cmd->flavours[i].size % 4) == 0);
640
      BFD_ASSERT (cmd->flavours[i].offset == (command->offset + offset + 8));
641
 
642
      bfd_h_put_32 (abfd, cmd->flavours[i].flavour, buf);
643
      bfd_h_put_32 (abfd, (cmd->flavours[i].size / 4), buf + 4);
644
 
645
      if (bfd_seek (abfd, command->offset + offset, SEEK_SET) != 0
646
          || bfd_bwrite ((void *) buf, 8, abfd) != 8)
647
        return -1;
648
 
649
      offset += cmd->flavours[i].size + 8;
650
    }
651
 
652
  return 0;
653
}
654
 
655
long
656
bfd_mach_o_get_reloc_upper_bound (bfd *abfd ATTRIBUTE_UNUSED,
657
                                  asection *asect)
658
{
659
  return (asect->reloc_count + 1) * sizeof (arelent *);
660
}
661
 
662
static int
663
bfd_mach_o_canonicalize_one_reloc (bfd *abfd, char *buf,
664
                                   arelent *res, asymbol **syms)
665
{
666
  bfd_mach_o_data_struct *mdata = bfd_mach_o_get_data (abfd);
667
  bfd_mach_o_backend_data *bed = bfd_mach_o_get_backend_data (abfd);
668
  bfd_mach_o_reloc_info reloc;
669
  bfd_vma addr;
670
  bfd_vma symnum;
671
  asymbol **sym;
672
 
673
  addr = bfd_get_32 (abfd, buf + 0);
674
  symnum = bfd_get_32 (abfd, buf + 4);
675
 
676
  if (addr & BFD_MACH_O_SR_SCATTERED)
677
    {
678
      unsigned int j;
679
 
680
      /* Scattered relocation.
681
         Extract section and offset from r_value.  */
682
      res->sym_ptr_ptr = NULL;
683
      res->addend = 0;
684
      for (j = 0; j < mdata->nsects; j++)
685
        {
686
          bfd_mach_o_section *sect = mdata->sections[j];
687
          if (symnum >= sect->addr && symnum < sect->addr + sect->size)
688
            {
689
              res->sym_ptr_ptr = sect->bfdsection->symbol_ptr_ptr;
690
              res->addend = symnum - sect->addr;
691
              break;
692
            }
693
        }
694
      res->address = BFD_MACH_O_GET_SR_ADDRESS (addr);
695
      reloc.r_type = BFD_MACH_O_GET_SR_TYPE (addr);
696
      reloc.r_length = BFD_MACH_O_GET_SR_LENGTH (addr);
697
      reloc.r_pcrel = addr & BFD_MACH_O_SR_PCREL;
698
      reloc.r_scattered = 1;
699
    }
700
  else
701
    {
702
      unsigned int num = BFD_MACH_O_GET_R_SYMBOLNUM (symnum);
703
      res->addend = 0;
704
      res->address = addr;
705
      if (symnum & BFD_MACH_O_R_EXTERN)
706
        {
707
          sym = syms + num;
708
          reloc.r_extern = 1;
709
        }
710
      else
711
        {
712
          BFD_ASSERT (num != 0);
713
          BFD_ASSERT (num <= mdata->nsects);
714
          sym = mdata->sections[num - 1]->bfdsection->symbol_ptr_ptr;
715
          /* For a symbol defined in section S, the addend (stored in the
716
             binary) contains the address of the section.  To comply with
717
             bfd conventio, substract the section address.
718
             Use the address from the header, so that the user can modify
719
             the vma of the section.  */
720
          res->addend = -mdata->sections[num - 1]->addr;
721
          reloc.r_extern = 0;
722
        }
723
      res->sym_ptr_ptr = sym;
724
      reloc.r_type = BFD_MACH_O_GET_R_TYPE (symnum);
725
      reloc.r_length = BFD_MACH_O_GET_R_LENGTH (symnum);
726
      reloc.r_pcrel = (symnum & BFD_MACH_O_R_PCREL) ? 1 : 0;
727
      reloc.r_scattered = 0;
728
    }
729
 
730
  if (!(*bed->_bfd_mach_o_swap_reloc_in)(res, &reloc))
731
    return -1;
732
  return 0;
733
}
734
 
735
static int
736
bfd_mach_o_canonicalize_relocs (bfd *abfd, unsigned long filepos,
737
                                unsigned long count,
738
                                arelent *res, asymbol **syms)
739
{
740
  unsigned long i;
741
  char *native_relocs;
742
  bfd_size_type native_size;
743
 
744
  /* Allocate and read relocs.  */
745
  native_size = count * BFD_MACH_O_RELENT_SIZE;
746
  native_relocs = bfd_malloc (native_size);
747
  if (native_relocs == NULL)
748
    return -1;
749
 
750
  if (bfd_seek (abfd, filepos, SEEK_SET) != 0
751
      || bfd_bread (native_relocs, native_size, abfd) != native_size)
752
    goto err;
753
 
754
  for (i = 0; i < count; i++)
755
    {
756
      char *buf = native_relocs + BFD_MACH_O_RELENT_SIZE * i;
757
 
758
      if (bfd_mach_o_canonicalize_one_reloc (abfd, buf, &res[i], syms) < 0)
759
        goto err;
760
    }
761
  free (native_relocs);
762
  return i;
763
 err:
764
  free (native_relocs);
765
  return -1;
766
}
767
 
768
long
769
bfd_mach_o_canonicalize_reloc (bfd *abfd, asection *asect,
770
                               arelent **rels, asymbol **syms)
771
{
772
  bfd_mach_o_backend_data *bed = bfd_mach_o_get_backend_data (abfd);
773
  unsigned long i;
774
  arelent *res;
775
 
776
  if (asect->reloc_count == 0)
777
    return 0;
778
 
779
  /* No need to go further if we don't know how to read relocs.  */
780
  if (bed->_bfd_mach_o_swap_reloc_in == NULL)
781
    return 0;
782
 
783
  res = bfd_malloc (asect->reloc_count * sizeof (arelent));
784
  if (res == NULL)
785
    return -1;
786
 
787
  if (bfd_mach_o_canonicalize_relocs (abfd, asect->rel_filepos,
788
                                      asect->reloc_count, res, syms) < 0)
789
    {
790
      free (res);
791
      return -1;
792
    }
793
 
794
  for (i = 0; i < asect->reloc_count; i++)
795
    rels[i] = &res[i];
796
  rels[i] = NULL;
797
  asect->relocation = res;
798
 
799
  return i;
800
}
801
 
802
long
803
bfd_mach_o_get_dynamic_reloc_upper_bound (bfd *abfd)
804
{
805
  bfd_mach_o_data_struct *mdata = bfd_mach_o_get_data (abfd);
806
 
807
  if (mdata->dysymtab == NULL)
808
    return 1;
809
  return (mdata->dysymtab->nextrel + mdata->dysymtab->nlocrel)
810
    * sizeof (arelent *);
811
}
812
 
813
long
814
bfd_mach_o_canonicalize_dynamic_reloc (bfd *abfd, arelent **rels,
815
                                       struct bfd_symbol **syms)
816
{
817
  bfd_mach_o_data_struct *mdata = bfd_mach_o_get_data (abfd);
818
  bfd_mach_o_dysymtab_command *dysymtab = mdata->dysymtab;
819
  bfd_mach_o_backend_data *bed = bfd_mach_o_get_backend_data (abfd);
820
  unsigned long i;
821
  arelent *res;
822
 
823
  if (dysymtab == NULL)
824
    return 0;
825
  if (dysymtab->nextrel == 0 && dysymtab->nlocrel == 0)
826
    return 0;
827
 
828
  /* No need to go further if we don't know how to read relocs.  */
829
  if (bed->_bfd_mach_o_swap_reloc_in == NULL)
830
    return 0;
831
 
832
  res = bfd_malloc ((dysymtab->nextrel + dysymtab->nlocrel) * sizeof (arelent));
833
  if (res == NULL)
834
    return -1;
835
 
836
  if (bfd_mach_o_canonicalize_relocs (abfd, dysymtab->extreloff,
837
                                      dysymtab->nextrel, res, syms) < 0)
838
    {
839
      free (res);
840
      return -1;
841
    }
842
 
843
  if (bfd_mach_o_canonicalize_relocs (abfd, dysymtab->locreloff,
844
                                      dysymtab->nlocrel,
845
                                      res + dysymtab->nextrel, syms) < 0)
846
    {
847
      free (res);
848
      return -1;
849
    }
850
 
851
  for (i = 0; i < dysymtab->nextrel + dysymtab->nlocrel; i++)
852
    rels[i] = &res[i];
853
  rels[i] = NULL;
854
  return i;
855
}
856
 
857
static bfd_boolean
858
bfd_mach_o_write_relocs (bfd *abfd, bfd_mach_o_section *section)
859
{
860
  bfd_mach_o_data_struct *mdata = bfd_mach_o_get_data (abfd);
861
  unsigned int i;
862
  arelent **entries;
863
  asection *sec;
864
  bfd_mach_o_backend_data *bed = bfd_mach_o_get_backend_data (abfd);
865
 
866
  sec = section->bfdsection;
867
  if (sec->reloc_count == 0)
868
    return TRUE;
869
 
870
  if (bed->_bfd_mach_o_swap_reloc_out == NULL)
871
    return TRUE;
872
 
873
  /* Allocate relocation room.  */
874
  mdata->filelen = FILE_ALIGN(mdata->filelen, 2);
875
  section->nreloc = sec->reloc_count;
876
  sec->rel_filepos = mdata->filelen;
877
  section->reloff = sec->rel_filepos;
878
  mdata->filelen += sec->reloc_count * BFD_MACH_O_RELENT_SIZE;
879
 
880
  if (bfd_seek (abfd, section->reloff, SEEK_SET) != 0)
881
    return FALSE;
882
 
883
  /* Convert and write.  */
884
  entries = section->bfdsection->orelocation;
885
  for (i = 0; i < section->nreloc; i++)
886
    {
887
      arelent *rel = entries[i];
888
      char buf[8];
889
      bfd_mach_o_reloc_info info, *pinfo = &info;
890
 
891
      /* Convert relocation to an intermediate representation.  */
892
      if (!(*bed->_bfd_mach_o_swap_reloc_out) (rel, pinfo))
893
        return FALSE;
894
 
895
      /* Lower the relocation info.  */
896
      if (pinfo->r_scattered)
897
        {
898
          unsigned long v;
899
 
900
          v = BFD_MACH_O_SR_SCATTERED
901
            | (pinfo->r_pcrel ? BFD_MACH_O_SR_PCREL : 0)
902
            | BFD_MACH_O_SET_SR_LENGTH(pinfo->r_length)
903
            | BFD_MACH_O_SET_SR_TYPE(pinfo->r_type)
904
            | BFD_MACH_O_SET_SR_ADDRESS(pinfo->r_address);
905
          bfd_put_32 (abfd, v, buf);
906
          bfd_put_32 (abfd, pinfo->r_value, buf + 4);
907
        }
908
      else
909
        {
910
          unsigned long v;
911
 
912
          bfd_put_32 (abfd, pinfo->r_address, buf);
913
          v = BFD_MACH_O_SET_R_SYMBOLNUM (pinfo->r_value)
914
            | (pinfo->r_pcrel ? BFD_MACH_O_R_PCREL : 0)
915
            | BFD_MACH_O_SET_R_LENGTH (pinfo->r_length)
916
            | (pinfo->r_extern ? BFD_MACH_O_R_EXTERN : 0)
917
            | BFD_MACH_O_SET_R_TYPE (pinfo->r_type);
918
          bfd_put_32 (abfd, v, buf + 4);
919
        }
920
 
921
      if (bfd_bwrite ((void *) buf, BFD_MACH_O_RELENT_SIZE, abfd)
922
          != BFD_MACH_O_RELENT_SIZE)
923
        return FALSE;
924
    }
925
  return TRUE;
926
}
927
 
928
static int
929
bfd_mach_o_write_section_32 (bfd *abfd, bfd_mach_o_section *section)
930
{
931
  unsigned char buf[BFD_MACH_O_SECTION_SIZE];
932
 
933
  memcpy (buf, section->sectname, 16);
934
  memcpy (buf + 16, section->segname, 16);
935
  bfd_h_put_32 (abfd, section->addr, buf + 32);
936
  bfd_h_put_32 (abfd, section->size, buf + 36);
937
  bfd_h_put_32 (abfd, section->offset, buf + 40);
938
  bfd_h_put_32 (abfd, section->align, buf + 44);
939
  bfd_h_put_32 (abfd, section->reloff, buf + 48);
940
  bfd_h_put_32 (abfd, section->nreloc, buf + 52);
941
  bfd_h_put_32 (abfd, section->flags, buf + 56);
942
  bfd_h_put_32 (abfd, section->reserved1, buf + 60);
943
  bfd_h_put_32 (abfd, section->reserved2, buf + 64);
944
 
945
  if (bfd_bwrite ((void *) buf, BFD_MACH_O_SECTION_SIZE, abfd)
946
      != BFD_MACH_O_SECTION_SIZE)
947
    return -1;
948
 
949
  return 0;
950
}
951
 
952
static int
953
bfd_mach_o_write_section_64 (bfd *abfd, bfd_mach_o_section *section)
954
{
955
  unsigned char buf[BFD_MACH_O_SECTION_64_SIZE];
956
 
957
  memcpy (buf, section->sectname, 16);
958
  memcpy (buf + 16, section->segname, 16);
959
  bfd_h_put_64 (abfd, section->addr, buf + 32);
960
  bfd_h_put_64 (abfd, section->size, buf + 40);
961
  bfd_h_put_32 (abfd, section->offset, buf + 48);
962
  bfd_h_put_32 (abfd, section->align, buf + 52);
963
  bfd_h_put_32 (abfd, section->reloff, buf + 56);
964
  bfd_h_put_32 (abfd, section->nreloc, buf + 60);
965
  bfd_h_put_32 (abfd, section->flags, buf + 64);
966
  bfd_h_put_32 (abfd, section->reserved1, buf + 68);
967
  bfd_h_put_32 (abfd, section->reserved2, buf + 72);
968
  bfd_h_put_32 (abfd, section->reserved3, buf + 76);
969
 
970
  if (bfd_bwrite ((void *) buf, BFD_MACH_O_SECTION_64_SIZE, abfd)
971
      != BFD_MACH_O_SECTION_64_SIZE)
972
    return -1;
973
 
974
  return 0;
975
}
976
 
977
static int
978
bfd_mach_o_write_segment_32 (bfd *abfd, bfd_mach_o_load_command *command)
979
{
980
  unsigned char buf[BFD_MACH_O_LC_SEGMENT_SIZE];
981
  bfd_mach_o_segment_command *seg = &command->command.segment;
982
  unsigned long i;
983
 
984
  BFD_ASSERT (command->type == BFD_MACH_O_LC_SEGMENT);
985
 
986
  for (i = 0; i < seg->nsects; i++)
987
    if (!bfd_mach_o_write_relocs (abfd, &seg->sections[i]))
988
      return -1;
989
 
990
  memcpy (buf, seg->segname, 16);
991
  bfd_h_put_32 (abfd, seg->vmaddr, buf + 16);
992
  bfd_h_put_32 (abfd, seg->vmsize, buf + 20);
993
  bfd_h_put_32 (abfd, seg->fileoff, buf + 24);
994
  bfd_h_put_32 (abfd, seg->filesize, buf + 28);
995
  bfd_h_put_32 (abfd, seg->maxprot, buf + 32);
996
  bfd_h_put_32 (abfd, seg->initprot, buf + 36);
997
  bfd_h_put_32 (abfd, seg->nsects, buf + 40);
998
  bfd_h_put_32 (abfd, seg->flags, buf + 44);
999
 
1000
  if (bfd_seek (abfd, command->offset + 8, SEEK_SET) != 0
1001
      || (bfd_bwrite ((void *) buf, BFD_MACH_O_LC_SEGMENT_SIZE - 8, abfd)
1002
          != BFD_MACH_O_LC_SEGMENT_SIZE - 8))
1003
    return -1;
1004
 
1005
  for (i = 0; i < seg->nsects; i++)
1006
    if (bfd_mach_o_write_section_32 (abfd, &seg->sections[i]))
1007
      return -1;
1008
 
1009
  return 0;
1010
}
1011
 
1012
static int
1013
bfd_mach_o_write_segment_64 (bfd *abfd, bfd_mach_o_load_command *command)
1014
{
1015
  unsigned char buf[BFD_MACH_O_LC_SEGMENT_64_SIZE];
1016
  bfd_mach_o_segment_command *seg = &command->command.segment;
1017
  unsigned long i;
1018
 
1019
  BFD_ASSERT (command->type == BFD_MACH_O_LC_SEGMENT_64);
1020
 
1021
  for (i = 0; i < seg->nsects; i++)
1022
    if (!bfd_mach_o_write_relocs (abfd, &seg->sections[i]))
1023
      return -1;
1024
 
1025
  memcpy (buf, seg->segname, 16);
1026
  bfd_h_put_64 (abfd, seg->vmaddr, buf + 16);
1027
  bfd_h_put_64 (abfd, seg->vmsize, buf + 24);
1028
  bfd_h_put_64 (abfd, seg->fileoff, buf + 32);
1029
  bfd_h_put_64 (abfd, seg->filesize, buf + 40);
1030
  bfd_h_put_32 (abfd, seg->maxprot, buf + 48);
1031
  bfd_h_put_32 (abfd, seg->initprot, buf + 52);
1032
  bfd_h_put_32 (abfd, seg->nsects, buf + 56);
1033
  bfd_h_put_32 (abfd, seg->flags, buf + 60);
1034
 
1035
  if (bfd_seek (abfd, command->offset + 8, SEEK_SET) != 0
1036
      || (bfd_bwrite ((void *) buf, BFD_MACH_O_LC_SEGMENT_64_SIZE - 8, abfd)
1037
          != BFD_MACH_O_LC_SEGMENT_64_SIZE - 8))
1038
    return -1;
1039
 
1040
  for (i = 0; i < seg->nsects; i++)
1041
    if (bfd_mach_o_write_section_64 (abfd, &seg->sections[i]))
1042
      return -1;
1043
 
1044
  return 0;
1045
}
1046
 
1047
static bfd_boolean
1048
bfd_mach_o_write_symtab (bfd *abfd, bfd_mach_o_load_command *command)
1049
{
1050
  bfd_mach_o_data_struct *mdata = bfd_mach_o_get_data (abfd);
1051
  bfd_mach_o_symtab_command *sym = &command->command.symtab;
1052
  unsigned char buf[16];
1053
  unsigned long i;
1054
  unsigned int wide = bfd_mach_o_wide_p (abfd);
1055
  unsigned int symlen = wide ? BFD_MACH_O_NLIST_64_SIZE : BFD_MACH_O_NLIST_SIZE;
1056
  struct bfd_strtab_hash *strtab;
1057
  asymbol **symbols = bfd_get_outsymbols (abfd);
1058
 
1059
  BFD_ASSERT (command->type == BFD_MACH_O_LC_SYMTAB);
1060
 
1061
  /* Write the symbols first.  */
1062
  mdata->filelen = FILE_ALIGN(mdata->filelen, wide ? 3 : 2);
1063
  sym->symoff = mdata->filelen;
1064
  if (bfd_seek (abfd, sym->symoff, SEEK_SET) != 0)
1065
    return FALSE;
1066
 
1067
  sym->nsyms = bfd_get_symcount (abfd);
1068
  mdata->filelen += sym->nsyms * symlen;
1069
 
1070
  strtab = _bfd_stringtab_init ();
1071
  if (strtab == NULL)
1072
    return FALSE;
1073
 
1074
  for (i = 0; i < sym->nsyms; i++)
1075
    {
1076
      bfd_size_type str_index;
1077
      bfd_mach_o_asymbol *s = (bfd_mach_o_asymbol *)symbols[i];
1078
 
1079
      /* Compute name index.  */
1080
      /* An index of 0 always means the empty string.  */
1081
      if (s->symbol.name == 0 || s->symbol.name[0] == '\0')
1082
        str_index = 0;
1083
      else
1084
        {
1085
          str_index = _bfd_stringtab_add (strtab, s->symbol.name, TRUE, FALSE);
1086
          if (str_index == (bfd_size_type) -1)
1087
            goto err;
1088
        }
1089
      bfd_h_put_32 (abfd, str_index, buf);
1090
      bfd_h_put_8 (abfd, s->n_type, buf + 4);
1091
      bfd_h_put_8 (abfd, s->n_sect, buf + 5);
1092
      bfd_h_put_16 (abfd, s->n_desc, buf + 6);
1093
      if (wide)
1094
        bfd_h_put_64 (abfd, s->symbol.section->vma + s->symbol.value, buf + 8);
1095
      else
1096
        bfd_h_put_32 (abfd, s->symbol.section->vma + s->symbol.value, buf + 8);
1097
 
1098
      if (bfd_bwrite ((void *) buf, symlen, abfd) != symlen)
1099
        goto err;
1100
    }
1101
  sym->strsize = _bfd_stringtab_size (strtab);
1102
  sym->stroff = mdata->filelen;
1103
  mdata->filelen += sym->strsize;
1104
 
1105
  if (_bfd_stringtab_emit (abfd, strtab) != TRUE)
1106
    goto err;
1107
  _bfd_stringtab_free (strtab);
1108
 
1109
  /* The command.  */
1110
  bfd_h_put_32 (abfd, sym->symoff, buf);
1111
  bfd_h_put_32 (abfd, sym->nsyms, buf + 4);
1112
  bfd_h_put_32 (abfd, sym->stroff, buf + 8);
1113
  bfd_h_put_32 (abfd, sym->strsize, buf + 12);
1114
 
1115
  if (bfd_seek (abfd, command->offset + 8, SEEK_SET) != 0
1116
      || bfd_bwrite ((void *) buf, 16, abfd) != 16)
1117
    return FALSE;
1118
 
1119
  return TRUE;
1120
 
1121
 err:
1122
  _bfd_stringtab_free (strtab);
1123
  return FALSE;
1124
}
1125
 
1126
/* Process the symbols and generate Mach-O specific fields.
1127
   Number them.  */
1128
 
1129
static bfd_boolean
1130
bfd_mach_o_mangle_symbols (bfd *abfd)
1131
{
1132
  unsigned long i;
1133
  asymbol **symbols = bfd_get_outsymbols (abfd);
1134
 
1135
  for (i = 0; i < bfd_get_symcount (abfd); i++)
1136
    {
1137
      bfd_mach_o_asymbol *s = (bfd_mach_o_asymbol *)symbols[i];
1138
 
1139
      if (s->n_type == BFD_MACH_O_N_UNDF && !(s->symbol.flags & BSF_DEBUGGING))
1140
        {
1141
          /* As genuine Mach-O symbols type shouldn't be N_UNDF (undefined
1142
             symbols should be N_UNDEF | N_EXT), we suppose the back-end
1143
             values haven't been set.  */
1144
          if (s->symbol.section == bfd_abs_section_ptr)
1145
            s->n_type = BFD_MACH_O_N_ABS;
1146
          else if (s->symbol.section == bfd_und_section_ptr)
1147
            {
1148
              s->n_type = BFD_MACH_O_N_UNDF;
1149
              if (s->symbol.flags & BSF_WEAK)
1150
                s->n_desc |= BFD_MACH_O_N_WEAK_REF;
1151
            }
1152
          else if (s->symbol.section == bfd_com_section_ptr)
1153
            s->n_type = BFD_MACH_O_N_UNDF | BFD_MACH_O_N_EXT;
1154
          else
1155
            s->n_type = BFD_MACH_O_N_SECT;
1156
 
1157
          if (s->symbol.flags & BSF_GLOBAL)
1158
            s->n_type |= BFD_MACH_O_N_EXT;
1159
        }
1160
 
1161
      /* Compute section index.  */
1162
      if (s->symbol.section != bfd_abs_section_ptr
1163
          && s->symbol.section != bfd_und_section_ptr
1164
          && s->symbol.section != bfd_com_section_ptr)
1165
        s->n_sect = s->symbol.section->target_index;
1166
 
1167
      /* Number symbols.  */
1168
      s->symbol.udata.i = i;
1169
    }
1170
  return TRUE;
1171
}
1172
 
1173
bfd_boolean
1174
bfd_mach_o_write_contents (bfd *abfd)
1175
{
1176
  unsigned int i;
1177
  bfd_mach_o_data_struct *mdata = bfd_mach_o_get_data (abfd);
1178
 
1179
  if (mdata->header.ncmds == 0)
1180
    if (!bfd_mach_o_build_commands (abfd))
1181
      return FALSE;
1182
 
1183
  /* Now write header information.  */
1184
  if (mdata->header.filetype == 0)
1185
    {
1186
      if (abfd->flags & EXEC_P)
1187
        mdata->header.filetype = BFD_MACH_O_MH_EXECUTE;
1188
      else if (abfd->flags & DYNAMIC)
1189
        mdata->header.filetype = BFD_MACH_O_MH_DYLIB;
1190
      else
1191
        mdata->header.filetype = BFD_MACH_O_MH_OBJECT;
1192
    }
1193
  if (!bfd_mach_o_write_header (abfd, &mdata->header))
1194
    return FALSE;
1195
 
1196
  /* Assign a number to each symbols.  */
1197
  if (!bfd_mach_o_mangle_symbols (abfd))
1198
    return FALSE;
1199
 
1200
  for (i = 0; i < mdata->header.ncmds; i++)
1201
    {
1202
      unsigned char buf[8];
1203
      bfd_mach_o_load_command *cur = &mdata->commands[i];
1204
      unsigned long typeflag;
1205
 
1206
      typeflag = cur->type | (cur->type_required ? BFD_MACH_O_LC_REQ_DYLD : 0);
1207
 
1208
      bfd_h_put_32 (abfd, typeflag, buf);
1209
      bfd_h_put_32 (abfd, cur->len, buf + 4);
1210
 
1211
      if (bfd_seek (abfd, cur->offset, SEEK_SET) != 0
1212
          || bfd_bwrite ((void *) buf, 8, abfd) != 8)
1213
        return FALSE;
1214
 
1215
      switch (cur->type)
1216
        {
1217
        case BFD_MACH_O_LC_SEGMENT:
1218
          if (bfd_mach_o_write_segment_32 (abfd, cur) != 0)
1219
            return FALSE;
1220
          break;
1221
        case BFD_MACH_O_LC_SEGMENT_64:
1222
          if (bfd_mach_o_write_segment_64 (abfd, cur) != 0)
1223
            return FALSE;
1224
          break;
1225
        case BFD_MACH_O_LC_SYMTAB:
1226
          if (!bfd_mach_o_write_symtab (abfd, cur))
1227
            return FALSE;
1228
          break;
1229
        case BFD_MACH_O_LC_SYMSEG:
1230
          break;
1231
        case BFD_MACH_O_LC_THREAD:
1232
        case BFD_MACH_O_LC_UNIXTHREAD:
1233
          if (bfd_mach_o_write_thread (abfd, cur) != 0)
1234
            return FALSE;
1235
          break;
1236
        case BFD_MACH_O_LC_LOADFVMLIB:
1237
        case BFD_MACH_O_LC_IDFVMLIB:
1238
        case BFD_MACH_O_LC_IDENT:
1239
        case BFD_MACH_O_LC_FVMFILE:
1240
        case BFD_MACH_O_LC_PREPAGE:
1241
        case BFD_MACH_O_LC_DYSYMTAB:
1242
        case BFD_MACH_O_LC_LOAD_DYLIB:
1243
        case BFD_MACH_O_LC_LOAD_WEAK_DYLIB:
1244
        case BFD_MACH_O_LC_ID_DYLIB:
1245
        case BFD_MACH_O_LC_REEXPORT_DYLIB:
1246
        case BFD_MACH_O_LC_LOAD_DYLINKER:
1247
        case BFD_MACH_O_LC_ID_DYLINKER:
1248
        case BFD_MACH_O_LC_PREBOUND_DYLIB:
1249
        case BFD_MACH_O_LC_ROUTINES:
1250
        case BFD_MACH_O_LC_SUB_FRAMEWORK:
1251
          break;
1252
        default:
1253
          (*_bfd_error_handler) (_("unable to write unknown load command 0x%lx"),
1254
                                 (unsigned long) cur->type);
1255
          return FALSE;
1256
        }
1257
    }
1258
 
1259
  return TRUE;
1260
}
1261
 
1262
/* Build Mach-O load commands from the sections.  */
1263
 
1264
bfd_boolean
1265
bfd_mach_o_build_commands (bfd *abfd)
1266
{
1267
  bfd_mach_o_data_struct *mdata = bfd_mach_o_get_data (abfd);
1268
  unsigned int wide = mach_o_wide_p (&mdata->header);
1269
  bfd_mach_o_segment_command *seg;
1270
  bfd_mach_o_section *sections;
1271
  asection *sec;
1272
  bfd_mach_o_load_command *cmd;
1273
  bfd_mach_o_load_command *symtab_cmd;
1274
  int target_index;
1275
 
1276
  /* Return now if commands are already built.  */
1277
  if (mdata->header.ncmds)
1278
    return FALSE;
1279
 
1280
  /* Very simple version: 1 command (segment) containing all sections.  */
1281
  mdata->header.ncmds = 2;
1282
  mdata->commands = bfd_alloc (abfd, mdata->header.ncmds
1283
                               * sizeof (bfd_mach_o_load_command));
1284
  if (mdata->commands == NULL)
1285
    return FALSE;
1286
  cmd = &mdata->commands[0];
1287
  seg = &cmd->command.segment;
1288
 
1289
  seg->nsects = bfd_count_sections (abfd);
1290
  sections = bfd_alloc (abfd, seg->nsects * sizeof (bfd_mach_o_section));
1291
  if (sections == NULL)
1292
    return FALSE;
1293
  seg->sections = sections;
1294
 
1295
  /* Set segment command.  */
1296
  if (wide)
1297
    {
1298
      cmd->type = BFD_MACH_O_LC_SEGMENT_64;
1299
      cmd->offset = BFD_MACH_O_HEADER_64_SIZE;
1300
      cmd->len = BFD_MACH_O_LC_SEGMENT_64_SIZE
1301
        + BFD_MACH_O_SECTION_64_SIZE * seg->nsects;
1302
    }
1303
  else
1304
    {
1305
      cmd->type = BFD_MACH_O_LC_SEGMENT;
1306
      cmd->offset = BFD_MACH_O_HEADER_SIZE;
1307
      cmd->len = BFD_MACH_O_LC_SEGMENT_SIZE
1308
        + BFD_MACH_O_SECTION_SIZE * seg->nsects;
1309
    }
1310
  cmd->type_required = FALSE;
1311
  mdata->header.sizeofcmds = cmd->len;
1312
  mdata->filelen = cmd->offset + cmd->len;
1313
 
1314
  /* Set symtab command.  */
1315
  symtab_cmd = &mdata->commands[1];
1316
 
1317
  symtab_cmd->type = BFD_MACH_O_LC_SYMTAB;
1318
  symtab_cmd->offset = cmd->offset + cmd->len;
1319
  symtab_cmd->len = 6 * 4;
1320
  symtab_cmd->type_required = FALSE;
1321
 
1322
  mdata->header.sizeofcmds += symtab_cmd->len;
1323
  mdata->filelen += symtab_cmd->len;
1324
 
1325
  /* Fill segment command.  */
1326
  memset (seg->segname, 0, sizeof (seg->segname));
1327
  seg->vmaddr = 0;
1328
  seg->fileoff = mdata->filelen;
1329
  seg->filesize = 0;
1330
  seg->maxprot = BFD_MACH_O_PROT_READ | BFD_MACH_O_PROT_WRITE
1331
    | BFD_MACH_O_PROT_EXECUTE;
1332
  seg->initprot = seg->maxprot;
1333
  seg->flags = 0;
1334
 
1335
  /* Create Mach-O sections.  */
1336
  target_index = 0;
1337
  for (sec = abfd->sections; sec; sec = sec->next)
1338
    {
1339
      sections->bfdsection = sec;
1340
      bfd_mach_o_convert_section_name_to_mach_o (abfd, sec, sections);
1341
      sections->addr = bfd_get_section_vma (abfd, sec);
1342
      sections->size = bfd_get_section_size (sec);
1343
      sections->align = bfd_get_section_alignment (abfd, sec);
1344
 
1345
      if (sections->size != 0)
1346
        {
1347
          mdata->filelen = FILE_ALIGN (mdata->filelen, sections->align);
1348
          sections->offset = mdata->filelen;
1349
        }
1350
      else
1351
        sections->offset = 0;
1352
      sections->reloff = 0;
1353
      sections->nreloc = 0;
1354
      sections->reserved1 = 0;
1355
      sections->reserved2 = 0;
1356
      sections->reserved3 = 0;
1357
 
1358
      sec->filepos = sections->offset;
1359
      sec->target_index = ++target_index;
1360
 
1361
      mdata->filelen += sections->size;
1362
      sections++;
1363
    }
1364
  seg->filesize = mdata->filelen - seg->fileoff;
1365
  seg->vmsize = seg->filesize;
1366
 
1367
  return TRUE;
1368
}
1369
 
1370
/* Set the contents of a section.  */
1371
 
1372
bfd_boolean
1373
bfd_mach_o_set_section_contents (bfd *abfd,
1374
                                 asection *section,
1375
                                 const void * location,
1376
                                 file_ptr offset,
1377
                                 bfd_size_type count)
1378
{
1379
  file_ptr pos;
1380
 
1381
  /* This must be done first, because bfd_set_section_contents is
1382
     going to set output_has_begun to TRUE.  */
1383
  if (! abfd->output_has_begun && ! bfd_mach_o_build_commands (abfd))
1384
    return FALSE;
1385
 
1386
  if (count == 0)
1387
    return TRUE;
1388
 
1389
  pos = section->filepos + offset;
1390
  if (bfd_seek (abfd, pos, SEEK_SET) != 0
1391
      || bfd_bwrite (location, count, abfd) != count)
1392
    return FALSE;
1393
 
1394
  return TRUE;
1395
}
1396
 
1397
int
1398
bfd_mach_o_sizeof_headers (bfd *a ATTRIBUTE_UNUSED,
1399
                           struct bfd_link_info *info ATTRIBUTE_UNUSED)
1400
{
1401
  return 0;
1402
}
1403
 
1404
/* Make an empty symbol.  This is required only because
1405
   bfd_make_section_anyway wants to create a symbol for the section.  */
1406
 
1407
asymbol *
1408
bfd_mach_o_make_empty_symbol (bfd *abfd)
1409
{
1410
  asymbol *new_symbol;
1411
 
1412
  new_symbol = bfd_zalloc (abfd, sizeof (bfd_mach_o_asymbol));
1413
  if (new_symbol == NULL)
1414
    return new_symbol;
1415
  new_symbol->the_bfd = abfd;
1416
  new_symbol->udata.i = 0;
1417
  return new_symbol;
1418
}
1419
 
1420
static bfd_boolean
1421
bfd_mach_o_read_header (bfd *abfd, bfd_mach_o_header *header)
1422
{
1423
  unsigned char buf[32];
1424
  unsigned int size;
1425
  bfd_vma (*get32) (const void *) = NULL;
1426
 
1427
  /* Just read the magic number.  */
1428
  if (bfd_seek (abfd, 0, SEEK_SET) != 0
1429
      || bfd_bread ((void *) buf, 4, abfd) != 4)
1430
    return FALSE;
1431
 
1432
  if (bfd_getb32 (buf) == BFD_MACH_O_MH_MAGIC)
1433
    {
1434
      header->byteorder = BFD_ENDIAN_BIG;
1435
      header->magic = BFD_MACH_O_MH_MAGIC;
1436
      header->version = 1;
1437
      get32 = bfd_getb32;
1438
    }
1439
  else if (bfd_getl32 (buf) == BFD_MACH_O_MH_MAGIC)
1440
    {
1441
      header->byteorder = BFD_ENDIAN_LITTLE;
1442
      header->magic = BFD_MACH_O_MH_MAGIC;
1443
      header->version = 1;
1444
      get32 = bfd_getl32;
1445
    }
1446
  else if (bfd_getb32 (buf) == BFD_MACH_O_MH_MAGIC_64)
1447
    {
1448
      header->byteorder = BFD_ENDIAN_BIG;
1449
      header->magic = BFD_MACH_O_MH_MAGIC_64;
1450
      header->version = 2;
1451
      get32 = bfd_getb32;
1452
    }
1453
  else if (bfd_getl32 (buf) == BFD_MACH_O_MH_MAGIC_64)
1454
    {
1455
      header->byteorder = BFD_ENDIAN_LITTLE;
1456
      header->magic = BFD_MACH_O_MH_MAGIC_64;
1457
      header->version = 2;
1458
      get32 = bfd_getl32;
1459
    }
1460
  else
1461
    {
1462
      header->byteorder = BFD_ENDIAN_UNKNOWN;
1463
      return FALSE;
1464
    }
1465
 
1466
  /* Once the size of the header is known, read the full header.  */
1467
  size = mach_o_wide_p (header) ?
1468
    BFD_MACH_O_HEADER_64_SIZE : BFD_MACH_O_HEADER_SIZE;
1469
 
1470
  if (bfd_seek (abfd, 0, SEEK_SET) != 0
1471
      || bfd_bread ((void *) buf, size, abfd) != size)
1472
    return FALSE;
1473
 
1474
  header->cputype = (*get32) (buf + 4);
1475
  header->cpusubtype = (*get32) (buf + 8);
1476
  header->filetype = (*get32) (buf + 12);
1477
  header->ncmds = (*get32) (buf + 16);
1478
  header->sizeofcmds = (*get32) (buf + 20);
1479
  header->flags = (*get32) (buf + 24);
1480
 
1481
  if (mach_o_wide_p (header))
1482
    header->reserved = (*get32) (buf + 28);
1483
 
1484
  return TRUE;
1485
}
1486
 
1487
static asection *
1488
bfd_mach_o_make_bfd_section (bfd *abfd, bfd_mach_o_section *section,
1489
                             unsigned long prot)
1490
{
1491
  asection *bfdsec;
1492
  char *sname;
1493
  flagword flags;
1494
 
1495
  bfd_mach_o_convert_section_name_to_bfd (abfd, section, &sname, &flags);
1496
  if (sname == NULL)
1497
    return NULL;
1498
 
1499
  if (flags == SEC_NO_FLAGS)
1500
    {
1501
      /* Try to guess flags.  */
1502
      if (section->flags & BFD_MACH_O_S_ATTR_DEBUG)
1503
        flags = SEC_DEBUGGING;
1504
      else
1505
        {
1506
          flags = SEC_ALLOC;
1507
          if ((section->flags & BFD_MACH_O_SECTION_TYPE_MASK)
1508
              != BFD_MACH_O_S_ZEROFILL)
1509
            {
1510
              flags |= SEC_LOAD;
1511
              if (prot & BFD_MACH_O_PROT_EXECUTE)
1512
                flags |= SEC_CODE;
1513
              if (prot & BFD_MACH_O_PROT_WRITE)
1514
                flags |= SEC_DATA;
1515
              else if (prot & BFD_MACH_O_PROT_READ)
1516
                flags |= SEC_READONLY;
1517
            }
1518
        }
1519
    }
1520
  else
1521
    {
1522
      if ((flags & SEC_DEBUGGING) == 0)
1523
        flags |= SEC_ALLOC;
1524
    }
1525
 
1526
  if (section->offset != 0)
1527
    flags |= SEC_HAS_CONTENTS;
1528
  if (section->nreloc != 0)
1529
    flags |= SEC_RELOC;
1530
 
1531
  bfdsec = bfd_make_section_anyway_with_flags (abfd, sname, flags);
1532
  if (bfdsec == NULL)
1533
    return NULL;
1534
 
1535
  bfdsec->vma = section->addr;
1536
  bfdsec->lma = section->addr;
1537
  bfdsec->size = section->size;
1538
  bfdsec->filepos = section->offset;
1539
  bfdsec->alignment_power = section->align;
1540
  bfdsec->segment_mark = 0;
1541
  bfdsec->reloc_count = section->nreloc;
1542
  bfdsec->rel_filepos = section->reloff;
1543
 
1544
  return bfdsec;
1545
}
1546
 
1547
static int
1548
bfd_mach_o_read_section_32 (bfd *abfd,
1549
                            bfd_mach_o_section *section,
1550
                            unsigned int offset,
1551
                            unsigned long prot)
1552
{
1553
  unsigned char buf[BFD_MACH_O_SECTION_SIZE];
1554
 
1555
  if (bfd_seek (abfd, offset, SEEK_SET) != 0
1556
      || (bfd_bread ((void *) buf, BFD_MACH_O_SECTION_SIZE, abfd)
1557
          != BFD_MACH_O_SECTION_SIZE))
1558
    return -1;
1559
 
1560
  memcpy (section->sectname, buf, 16);
1561
  section->sectname[16] = '\0';
1562
  memcpy (section->segname, buf + 16, 16);
1563
  section->segname[16] = '\0';
1564
  section->addr = bfd_h_get_32 (abfd, buf + 32);
1565
  section->size = bfd_h_get_32 (abfd, buf + 36);
1566
  section->offset = bfd_h_get_32 (abfd, buf + 40);
1567
  section->align = bfd_h_get_32 (abfd, buf + 44);
1568
  section->reloff = bfd_h_get_32 (abfd, buf + 48);
1569
  section->nreloc = bfd_h_get_32 (abfd, buf + 52);
1570
  section->flags = bfd_h_get_32 (abfd, buf + 56);
1571
  section->reserved1 = bfd_h_get_32 (abfd, buf + 60);
1572
  section->reserved2 = bfd_h_get_32 (abfd, buf + 64);
1573
  section->reserved3 = 0;
1574
  section->bfdsection = bfd_mach_o_make_bfd_section (abfd, section, prot);
1575
 
1576
  if (section->bfdsection == NULL)
1577
    return -1;
1578
 
1579
  return 0;
1580
}
1581
 
1582
static int
1583
bfd_mach_o_read_section_64 (bfd *abfd,
1584
                            bfd_mach_o_section *section,
1585
                            unsigned int offset,
1586
                            unsigned long prot)
1587
{
1588
  unsigned char buf[BFD_MACH_O_SECTION_64_SIZE];
1589
 
1590
  if (bfd_seek (abfd, offset, SEEK_SET) != 0
1591
      || (bfd_bread ((void *) buf, BFD_MACH_O_SECTION_64_SIZE, abfd)
1592
          != BFD_MACH_O_SECTION_64_SIZE))
1593
    return -1;
1594
 
1595
  memcpy (section->sectname, buf, 16);
1596
  section->sectname[16] = '\0';
1597
  memcpy (section->segname, buf + 16, 16);
1598
  section->segname[16] = '\0';
1599
  section->addr = bfd_h_get_64 (abfd, buf + 32);
1600
  section->size = bfd_h_get_64 (abfd, buf + 40);
1601
  section->offset = bfd_h_get_32 (abfd, buf + 48);
1602
  section->align = bfd_h_get_32 (abfd, buf + 52);
1603
  section->reloff = bfd_h_get_32 (abfd, buf + 56);
1604
  section->nreloc = bfd_h_get_32 (abfd, buf + 60);
1605
  section->flags = bfd_h_get_32 (abfd, buf + 64);
1606
  section->reserved1 = bfd_h_get_32 (abfd, buf + 68);
1607
  section->reserved2 = bfd_h_get_32 (abfd, buf + 72);
1608
  section->reserved3 = bfd_h_get_32 (abfd, buf + 76);
1609
  section->bfdsection = bfd_mach_o_make_bfd_section (abfd, section, prot);
1610
 
1611
  if (section->bfdsection == NULL)
1612
    return -1;
1613
 
1614
  return 0;
1615
}
1616
 
1617
static int
1618
bfd_mach_o_read_section (bfd *abfd,
1619
                         bfd_mach_o_section *section,
1620
                         unsigned int offset,
1621
                         unsigned long prot,
1622
                         unsigned int wide)
1623
{
1624
  if (wide)
1625
    return bfd_mach_o_read_section_64 (abfd, section, offset, prot);
1626
  else
1627
    return bfd_mach_o_read_section_32 (abfd, section, offset, prot);
1628
}
1629
 
1630
static int
1631
bfd_mach_o_read_symtab_symbol (bfd *abfd,
1632
                               bfd_mach_o_symtab_command *sym,
1633
                               bfd_mach_o_asymbol *s,
1634
                               unsigned long i)
1635
{
1636
  bfd_mach_o_data_struct *mdata = bfd_mach_o_get_data (abfd);
1637
  unsigned int wide = mach_o_wide_p (&mdata->header);
1638
  unsigned int symwidth =
1639
    wide ? BFD_MACH_O_NLIST_64_SIZE : BFD_MACH_O_NLIST_SIZE;
1640
  unsigned int symoff = sym->symoff + (i * symwidth);
1641
  unsigned char buf[16];
1642
  unsigned char type = -1;
1643
  unsigned char section = -1;
1644
  short desc = -1;
1645
  symvalue value = -1;
1646
  unsigned long stroff = -1;
1647
  unsigned int symtype = -1;
1648
 
1649
  BFD_ASSERT (sym->strtab != NULL);
1650
 
1651
  if (bfd_seek (abfd, symoff, SEEK_SET) != 0
1652
      || bfd_bread ((void *) buf, symwidth, abfd) != symwidth)
1653
    {
1654
      (*_bfd_error_handler) (_("bfd_mach_o_read_symtab_symbol: unable to read %d bytes at %lu"),
1655
                             symwidth, (unsigned long) symoff);
1656
      return -1;
1657
    }
1658
 
1659
  stroff = bfd_h_get_32 (abfd, buf);
1660
  type = bfd_h_get_8 (abfd, buf + 4);
1661
  symtype = type & BFD_MACH_O_N_TYPE;
1662
  section = bfd_h_get_8 (abfd, buf + 5);
1663
  desc = bfd_h_get_16 (abfd, buf + 6);
1664
  if (wide)
1665
    value = bfd_h_get_64 (abfd, buf + 8);
1666
  else
1667
    value = bfd_h_get_32 (abfd, buf + 8);
1668
 
1669
  if (stroff >= sym->strsize)
1670
    {
1671
      (*_bfd_error_handler) (_("bfd_mach_o_read_symtab_symbol: symbol name out of range (%lu >= %lu)"),
1672
                             (unsigned long) stroff,
1673
                             (unsigned long) sym->strsize);
1674
      return -1;
1675
    }
1676
 
1677
  s->symbol.the_bfd = abfd;
1678
  s->symbol.name = sym->strtab + stroff;
1679
  s->symbol.value = value;
1680
  s->symbol.flags = 0x0;
1681
  s->symbol.udata.i = 0;
1682
  s->n_type = type;
1683
  s->n_sect = section;
1684
  s->n_desc = desc;
1685
 
1686
  if (type & BFD_MACH_O_N_STAB)
1687
    {
1688
      s->symbol.flags |= BSF_DEBUGGING;
1689
      s->symbol.section = bfd_und_section_ptr;
1690
      switch (type)
1691
        {
1692
        case N_FUN:
1693
        case N_STSYM:
1694
        case N_LCSYM:
1695
        case N_BNSYM:
1696
        case N_SLINE:
1697
        case N_ENSYM:
1698
        case N_ECOMM:
1699
        case N_ECOML:
1700
        case N_GSYM:
1701
          if ((section > 0) && (section <= mdata->nsects))
1702
            {
1703
              s->symbol.section = mdata->sections[section - 1]->bfdsection;
1704
              s->symbol.value =
1705
                s->symbol.value - mdata->sections[section - 1]->addr;
1706
            }
1707
          break;
1708
        }
1709
    }
1710
  else
1711
    {
1712
      if (type & BFD_MACH_O_N_PEXT)
1713
        s->symbol.flags |= BSF_GLOBAL;
1714
 
1715
      if (type & BFD_MACH_O_N_EXT)
1716
        s->symbol.flags |= BSF_GLOBAL;
1717
 
1718
      if (!(type & (BFD_MACH_O_N_PEXT | BFD_MACH_O_N_EXT)))
1719
        s->symbol.flags |= BSF_LOCAL;
1720
 
1721
      switch (symtype)
1722
        {
1723
        case BFD_MACH_O_N_UNDF:
1724
          if (type == (BFD_MACH_O_N_UNDF | BFD_MACH_O_N_EXT)
1725
              && s->symbol.value != 0)
1726
            {
1727
              /* A common symbol.  */
1728
              s->symbol.section = bfd_com_section_ptr;
1729
              s->symbol.flags = BSF_NO_FLAGS;
1730
            }
1731
          else
1732
            {
1733
              s->symbol.section = bfd_und_section_ptr;
1734
              if (s->n_desc & BFD_MACH_O_N_WEAK_REF)
1735
                s->symbol.flags |= BSF_WEAK;
1736
            }
1737
          break;
1738
        case BFD_MACH_O_N_PBUD:
1739
          s->symbol.section = bfd_und_section_ptr;
1740
          break;
1741
        case BFD_MACH_O_N_ABS:
1742
          s->symbol.section = bfd_abs_section_ptr;
1743
          break;
1744
        case BFD_MACH_O_N_SECT:
1745
          if ((section > 0) && (section <= mdata->nsects))
1746
            {
1747
              s->symbol.section = mdata->sections[section - 1]->bfdsection;
1748
              s->symbol.value =
1749
                s->symbol.value - mdata->sections[section - 1]->addr;
1750
            }
1751
          else
1752
            {
1753
              /* Mach-O uses 0 to mean "no section"; not an error.  */
1754
              if (section != 0)
1755
                {
1756
                  (*_bfd_error_handler) (_("bfd_mach_o_read_symtab_symbol: "
1757
                                           "symbol \"%s\" specified invalid section %d (max %lu): setting to undefined"),
1758
                                         s->symbol.name, section, mdata->nsects);
1759
                }
1760
              s->symbol.section = bfd_und_section_ptr;
1761
            }
1762
          break;
1763
        case BFD_MACH_O_N_INDR:
1764
          (*_bfd_error_handler) (_("bfd_mach_o_read_symtab_symbol: "
1765
                                   "symbol \"%s\" is unsupported 'indirect' reference: setting to undefined"),
1766
                                 s->symbol.name);
1767
          s->symbol.section = bfd_und_section_ptr;
1768
          break;
1769
        default:
1770
          (*_bfd_error_handler) (_("bfd_mach_o_read_symtab_symbol: "
1771
                                   "symbol \"%s\" specified invalid type field 0x%x: setting to undefined"),
1772
                                 s->symbol.name, symtype);
1773
          s->symbol.section = bfd_und_section_ptr;
1774
          break;
1775
        }
1776
    }
1777
 
1778
  return 0;
1779
}
1780
 
1781
static int
1782
bfd_mach_o_read_symtab_strtab (bfd *abfd)
1783
{
1784
  bfd_mach_o_data_struct *mdata = bfd_mach_o_get_data (abfd);
1785
  bfd_mach_o_symtab_command *sym = mdata->symtab;
1786
 
1787
  /* Fail if there is no symtab.  */
1788
  if (sym == NULL)
1789
    return -1;
1790
 
1791
  /* Success if already loaded.  */
1792
  if (sym->strtab)
1793
    return 0;
1794
 
1795
  if (abfd->flags & BFD_IN_MEMORY)
1796
    {
1797
      struct bfd_in_memory *b;
1798
 
1799
      b = (struct bfd_in_memory *) abfd->iostream;
1800
 
1801
      if ((sym->stroff + sym->strsize) > b->size)
1802
        {
1803
          bfd_set_error (bfd_error_file_truncated);
1804
          return -1;
1805
        }
1806
      sym->strtab = (char *) b->buffer + sym->stroff;
1807
    }
1808
  else
1809
    {
1810
      sym->strtab = bfd_alloc (abfd, sym->strsize);
1811
      if (sym->strtab == NULL)
1812
        return -1;
1813
 
1814
      if (bfd_seek (abfd, sym->stroff, SEEK_SET) != 0
1815
          || bfd_bread ((void *) sym->strtab, sym->strsize, abfd) != sym->strsize)
1816
        {
1817
          bfd_set_error (bfd_error_file_truncated);
1818
          return -1;
1819
        }
1820
    }
1821
 
1822
  return 0;
1823
}
1824
 
1825
static int
1826
bfd_mach_o_read_symtab_symbols (bfd *abfd)
1827
{
1828
  bfd_mach_o_data_struct *mdata = bfd_mach_o_get_data (abfd);
1829
  bfd_mach_o_symtab_command *sym = mdata->symtab;
1830
  unsigned long i;
1831
  int ret;
1832
 
1833
  if (sym->symbols)
1834
    return 0;
1835
 
1836
  sym->symbols = bfd_alloc (abfd, sym->nsyms * sizeof (bfd_mach_o_asymbol));
1837
 
1838
  if (sym->symbols == NULL)
1839
    {
1840
      (*_bfd_error_handler) (_("bfd_mach_o_read_symtab_symbols: unable to allocate memory for symbols"));
1841
      return -1;
1842
    }
1843
 
1844
  ret = bfd_mach_o_read_symtab_strtab (abfd);
1845
  if (ret != 0)
1846
    return ret;
1847
 
1848
  for (i = 0; i < sym->nsyms; i++)
1849
    {
1850
      ret = bfd_mach_o_read_symtab_symbol (abfd, sym, &sym->symbols[i], i);
1851
      if (ret != 0)
1852
        return ret;
1853
    }
1854
 
1855
  return 0;
1856
}
1857
 
1858
int
1859
bfd_mach_o_read_dysymtab_symbol (bfd *abfd,
1860
                                 bfd_mach_o_dysymtab_command *dysym,
1861
                                 bfd_mach_o_symtab_command *sym,
1862
                                 bfd_mach_o_asymbol *s,
1863
                                 unsigned long i)
1864
{
1865
  unsigned long isymoff = dysym->indirectsymoff + (i * 4);
1866
  unsigned long sym_index;
1867
  unsigned char buf[4];
1868
 
1869
  BFD_ASSERT (i < dysym->nindirectsyms);
1870
 
1871
  if (bfd_seek (abfd, isymoff, SEEK_SET) != 0
1872
      || bfd_bread ((void *) buf, 4, abfd) != 4)
1873
    {
1874
      (*_bfd_error_handler) (_("bfd_mach_o_read_dysymtab_symbol: unable to read %lu bytes at %lu"),
1875
                               (unsigned long) 4, isymoff);
1876
      return -1;
1877
    }
1878
  sym_index = bfd_h_get_32 (abfd, buf);
1879
 
1880
  return bfd_mach_o_read_symtab_symbol (abfd, sym, s, sym_index);
1881
}
1882
 
1883
static const char *
1884
bfd_mach_o_i386_flavour_string (unsigned int flavour)
1885
{
1886
  switch ((int) flavour)
1887
    {
1888
    case BFD_MACH_O_x86_THREAD_STATE32:    return "x86_THREAD_STATE32";
1889
    case BFD_MACH_O_x86_FLOAT_STATE32:     return "x86_FLOAT_STATE32";
1890
    case BFD_MACH_O_x86_EXCEPTION_STATE32: return "x86_EXCEPTION_STATE32";
1891
    case BFD_MACH_O_x86_THREAD_STATE64:    return "x86_THREAD_STATE64";
1892
    case BFD_MACH_O_x86_FLOAT_STATE64:     return "x86_FLOAT_STATE64";
1893
    case BFD_MACH_O_x86_EXCEPTION_STATE64: return "x86_EXCEPTION_STATE64";
1894
    case BFD_MACH_O_x86_THREAD_STATE:      return "x86_THREAD_STATE";
1895
    case BFD_MACH_O_x86_FLOAT_STATE:       return "x86_FLOAT_STATE";
1896
    case BFD_MACH_O_x86_EXCEPTION_STATE:   return "x86_EXCEPTION_STATE";
1897
    case BFD_MACH_O_x86_DEBUG_STATE32:     return "x86_DEBUG_STATE32";
1898
    case BFD_MACH_O_x86_DEBUG_STATE64:     return "x86_DEBUG_STATE64";
1899
    case BFD_MACH_O_x86_DEBUG_STATE:       return "x86_DEBUG_STATE";
1900
    case BFD_MACH_O_x86_THREAD_STATE_NONE: return "x86_THREAD_STATE_NONE";
1901
    default: return "UNKNOWN";
1902
    }
1903
}
1904
 
1905
static const char *
1906
bfd_mach_o_ppc_flavour_string (unsigned int flavour)
1907
{
1908
  switch ((int) flavour)
1909
    {
1910
    case BFD_MACH_O_PPC_THREAD_STATE:      return "PPC_THREAD_STATE";
1911
    case BFD_MACH_O_PPC_FLOAT_STATE:       return "PPC_FLOAT_STATE";
1912
    case BFD_MACH_O_PPC_EXCEPTION_STATE:   return "PPC_EXCEPTION_STATE";
1913
    case BFD_MACH_O_PPC_VECTOR_STATE:      return "PPC_VECTOR_STATE";
1914
    case BFD_MACH_O_PPC_THREAD_STATE64:    return "PPC_THREAD_STATE64";
1915
    case BFD_MACH_O_PPC_EXCEPTION_STATE64: return "PPC_EXCEPTION_STATE64";
1916
    default: return "UNKNOWN";
1917
    }
1918
}
1919
 
1920
static int
1921
bfd_mach_o_read_dylinker (bfd *abfd, bfd_mach_o_load_command *command)
1922
{
1923
  bfd_mach_o_dylinker_command *cmd = &command->command.dylinker;
1924
  unsigned char buf[4];
1925
  unsigned int nameoff;
1926
 
1927
  BFD_ASSERT ((command->type == BFD_MACH_O_LC_ID_DYLINKER)
1928
              || (command->type == BFD_MACH_O_LC_LOAD_DYLINKER));
1929
 
1930
  if (bfd_seek (abfd, command->offset + 8, SEEK_SET) != 0
1931
      || bfd_bread ((void *) buf, 4, abfd) != 4)
1932
    return -1;
1933
 
1934
  nameoff = bfd_h_get_32 (abfd, buf + 0);
1935
 
1936
  cmd->name_offset = command->offset + nameoff;
1937
  cmd->name_len = command->len - nameoff;
1938
  cmd->name_str = bfd_alloc (abfd, cmd->name_len);
1939
  if (cmd->name_str == NULL)
1940
    return -1;
1941
  if (bfd_seek (abfd, cmd->name_offset, SEEK_SET) != 0
1942
      || bfd_bread (cmd->name_str, cmd->name_len, abfd) != cmd->name_len)
1943
    return -1;
1944
  return 0;
1945
}
1946
 
1947
static int
1948
bfd_mach_o_read_dylib (bfd *abfd, bfd_mach_o_load_command *command)
1949
{
1950
  bfd_mach_o_dylib_command *cmd = &command->command.dylib;
1951
  unsigned char buf[16];
1952
  unsigned int nameoff;
1953
 
1954
  switch (command->type)
1955
    {
1956
    case BFD_MACH_O_LC_LOAD_DYLIB:
1957
    case BFD_MACH_O_LC_LOAD_WEAK_DYLIB:
1958
    case BFD_MACH_O_LC_ID_DYLIB:
1959
    case BFD_MACH_O_LC_REEXPORT_DYLIB:
1960
      break;
1961
    default:
1962
      BFD_FAIL ();
1963
      return -1;
1964
    }
1965
 
1966
  if (bfd_seek (abfd, command->offset + 8, SEEK_SET) != 0
1967
      || bfd_bread ((void *) buf, 16, abfd) != 16)
1968
    return -1;
1969
 
1970
  nameoff = bfd_h_get_32 (abfd, buf + 0);
1971
  cmd->timestamp = bfd_h_get_32 (abfd, buf + 4);
1972
  cmd->current_version = bfd_h_get_32 (abfd, buf + 8);
1973
  cmd->compatibility_version = bfd_h_get_32 (abfd, buf + 12);
1974
 
1975
  cmd->name_offset = command->offset + nameoff;
1976
  cmd->name_len = command->len - nameoff;
1977
  cmd->name_str = bfd_alloc (abfd, cmd->name_len);
1978
  if (cmd->name_str == NULL)
1979
    return -1;
1980
  if (bfd_seek (abfd, cmd->name_offset, SEEK_SET) != 0
1981
      || bfd_bread (cmd->name_str, cmd->name_len, abfd) != cmd->name_len)
1982
    return -1;
1983
  return 0;
1984
}
1985
 
1986
static int
1987
bfd_mach_o_read_prebound_dylib (bfd *abfd ATTRIBUTE_UNUSED,
1988
                                bfd_mach_o_load_command *command ATTRIBUTE_UNUSED)
1989
{
1990
  /* bfd_mach_o_prebound_dylib_command *cmd = &command->command.prebound_dylib; */
1991
 
1992
  BFD_ASSERT (command->type == BFD_MACH_O_LC_PREBOUND_DYLIB);
1993
  return 0;
1994
}
1995
 
1996
static int
1997
bfd_mach_o_read_thread (bfd *abfd, bfd_mach_o_load_command *command)
1998
{
1999
  bfd_mach_o_data_struct *mdata = bfd_mach_o_get_data (abfd);
2000
  bfd_mach_o_thread_command *cmd = &command->command.thread;
2001
  unsigned char buf[8];
2002
  unsigned int offset;
2003
  unsigned int nflavours;
2004
  unsigned int i;
2005
 
2006
  BFD_ASSERT ((command->type == BFD_MACH_O_LC_THREAD)
2007
              || (command->type == BFD_MACH_O_LC_UNIXTHREAD));
2008
 
2009
  /* Count the number of threads.  */
2010
  offset = 8;
2011
  nflavours = 0;
2012
  while (offset != command->len)
2013
    {
2014
      if (offset >= command->len)
2015
        return -1;
2016
 
2017
      if (bfd_seek (abfd, command->offset + offset, SEEK_SET) != 0
2018
          || bfd_bread ((void *) buf, 8, abfd) != 8)
2019
        return -1;
2020
 
2021
      offset += 8 + bfd_h_get_32 (abfd, buf + 4) * 4;
2022
      nflavours++;
2023
    }
2024
 
2025
  /* Allocate threads.  */
2026
  cmd->flavours = bfd_alloc
2027
    (abfd, nflavours * sizeof (bfd_mach_o_thread_flavour));
2028
  if (cmd->flavours == NULL)
2029
    return -1;
2030
  cmd->nflavours = nflavours;
2031
 
2032
  offset = 8;
2033
  nflavours = 0;
2034
  while (offset != command->len)
2035
    {
2036
      if (offset >= command->len)
2037
        return -1;
2038
 
2039
      if (nflavours >= cmd->nflavours)
2040
        return -1;
2041
 
2042
      if (bfd_seek (abfd, command->offset + offset, SEEK_SET) != 0
2043
          || bfd_bread ((void *) buf, 8, abfd) != 8)
2044
        return -1;
2045
 
2046
      cmd->flavours[nflavours].flavour = bfd_h_get_32 (abfd, buf);
2047
      cmd->flavours[nflavours].offset = command->offset + offset + 8;
2048
      cmd->flavours[nflavours].size = bfd_h_get_32 (abfd, buf + 4) * 4;
2049
      offset += cmd->flavours[nflavours].size + 8;
2050
      nflavours++;
2051
    }
2052
 
2053
  for (i = 0; i < nflavours; i++)
2054
    {
2055
      asection *bfdsec;
2056
      unsigned int snamelen;
2057
      char *sname;
2058
      const char *flavourstr;
2059
      const char *prefix = "LC_THREAD";
2060
      unsigned int j = 0;
2061
 
2062
      switch (mdata->header.cputype)
2063
        {
2064
        case BFD_MACH_O_CPU_TYPE_POWERPC:
2065
        case BFD_MACH_O_CPU_TYPE_POWERPC_64:
2066
          flavourstr = bfd_mach_o_ppc_flavour_string (cmd->flavours[i].flavour);
2067
          break;
2068
        case BFD_MACH_O_CPU_TYPE_I386:
2069
        case BFD_MACH_O_CPU_TYPE_X86_64:
2070
          flavourstr = bfd_mach_o_i386_flavour_string (cmd->flavours[i].flavour);
2071
          break;
2072
        default:
2073
          flavourstr = "UNKNOWN_ARCHITECTURE";
2074
          break;
2075
        }
2076
 
2077
      snamelen = strlen (prefix) + 1 + 20 + 1 + strlen (flavourstr) + 1;
2078
      sname = bfd_alloc (abfd, snamelen);
2079
      if (sname == NULL)
2080
        return -1;
2081
 
2082
      for (;;)
2083
        {
2084
          sprintf (sname, "%s.%s.%u", prefix, flavourstr, j);
2085
          if (bfd_get_section_by_name (abfd, sname) == NULL)
2086
            break;
2087
          j++;
2088
        }
2089
 
2090
      bfdsec = bfd_make_section_with_flags (abfd, sname, SEC_HAS_CONTENTS);
2091
 
2092
      bfdsec->vma = 0;
2093
      bfdsec->lma = 0;
2094
      bfdsec->size = cmd->flavours[i].size;
2095
      bfdsec->filepos = cmd->flavours[i].offset;
2096
      bfdsec->alignment_power = 0x0;
2097
 
2098
      cmd->section = bfdsec;
2099
    }
2100
 
2101
  return 0;
2102
}
2103
 
2104
static int
2105
bfd_mach_o_read_dysymtab (bfd *abfd, bfd_mach_o_load_command *command)
2106
{
2107
  bfd_mach_o_dysymtab_command *cmd = &command->command.dysymtab;
2108
  bfd_mach_o_data_struct *mdata = bfd_mach_o_get_data (abfd);
2109
  unsigned char buf[72];
2110
 
2111
  BFD_ASSERT (command->type == BFD_MACH_O_LC_DYSYMTAB);
2112
 
2113
  if (bfd_seek (abfd, command->offset + 8, SEEK_SET) != 0
2114
      || bfd_bread ((void *) buf, 72, abfd) != 72)
2115
    return -1;
2116
 
2117
  cmd->ilocalsym = bfd_h_get_32 (abfd, buf + 0);
2118
  cmd->nlocalsym = bfd_h_get_32 (abfd, buf + 4);
2119
  cmd->iextdefsym = bfd_h_get_32 (abfd, buf + 8);
2120
  cmd->nextdefsym = bfd_h_get_32 (abfd, buf + 12);
2121
  cmd->iundefsym = bfd_h_get_32 (abfd, buf + 16);
2122
  cmd->nundefsym = bfd_h_get_32 (abfd, buf + 20);
2123
  cmd->tocoff = bfd_h_get_32 (abfd, buf + 24);
2124
  cmd->ntoc = bfd_h_get_32 (abfd, buf + 28);
2125
  cmd->modtaboff = bfd_h_get_32 (abfd, buf + 32);
2126
  cmd->nmodtab = bfd_h_get_32 (abfd, buf + 36);
2127
  cmd->extrefsymoff = bfd_h_get_32 (abfd, buf + 40);
2128
  cmd->nextrefsyms = bfd_h_get_32 (abfd, buf + 44);
2129
  cmd->indirectsymoff = bfd_h_get_32 (abfd, buf + 48);
2130
  cmd->nindirectsyms = bfd_h_get_32 (abfd, buf + 52);
2131
  cmd->extreloff = bfd_h_get_32 (abfd, buf + 56);
2132
  cmd->nextrel = bfd_h_get_32 (abfd, buf + 60);
2133
  cmd->locreloff = bfd_h_get_32 (abfd, buf + 64);
2134
  cmd->nlocrel = bfd_h_get_32 (abfd, buf + 68);
2135
 
2136
  if (cmd->nmodtab != 0)
2137
    {
2138
      unsigned int i;
2139
      int wide = bfd_mach_o_wide_p (abfd);
2140
      unsigned int module_len = wide ? 56 : 52;
2141
 
2142
      cmd->dylib_module =
2143
        bfd_alloc (abfd, cmd->nmodtab * sizeof (bfd_mach_o_dylib_module));
2144
      if (cmd->dylib_module == NULL)
2145
        return -1;
2146
 
2147
      if (bfd_seek (abfd, cmd->modtaboff, SEEK_SET) != 0)
2148
        return -1;
2149
 
2150
      for (i = 0; i < cmd->nmodtab; i++)
2151
        {
2152
          bfd_mach_o_dylib_module *module = &cmd->dylib_module[i];
2153
          unsigned long v;
2154
 
2155
          if (bfd_bread ((void *) buf, module_len, abfd) != module_len)
2156
            return -1;
2157
 
2158
          module->module_name_idx = bfd_h_get_32 (abfd, buf + 0);
2159
          module->iextdefsym = bfd_h_get_32 (abfd, buf + 4);
2160
          module->nextdefsym = bfd_h_get_32 (abfd, buf + 8);
2161
          module->irefsym = bfd_h_get_32 (abfd, buf + 12);
2162
          module->nrefsym = bfd_h_get_32 (abfd, buf + 16);
2163
          module->ilocalsym = bfd_h_get_32 (abfd, buf + 20);
2164
          module->nlocalsym = bfd_h_get_32 (abfd, buf + 24);
2165
          module->iextrel = bfd_h_get_32 (abfd, buf + 28);
2166
          module->nextrel = bfd_h_get_32 (abfd, buf + 32);
2167
          v = bfd_h_get_32 (abfd, buf +36);
2168
          module->iinit = v & 0xffff;
2169
          module->iterm = (v >> 16) & 0xffff;
2170
          v = bfd_h_get_32 (abfd, buf + 40);
2171
          module->ninit = v & 0xffff;
2172
          module->nterm = (v >> 16) & 0xffff;
2173
          if (wide)
2174
            {
2175
              module->objc_module_info_size = bfd_h_get_32 (abfd, buf + 44);
2176
              module->objc_module_info_addr = bfd_h_get_64 (abfd, buf + 48);
2177
            }
2178
          else
2179
            {
2180
              module->objc_module_info_addr = bfd_h_get_32 (abfd, buf + 44);
2181
              module->objc_module_info_size = bfd_h_get_32 (abfd, buf + 48);
2182
            }
2183
        }
2184
    }
2185
 
2186
  if (cmd->ntoc != 0)
2187
    {
2188
      unsigned int i;
2189
 
2190
      cmd->dylib_toc = bfd_alloc
2191
        (abfd, cmd->ntoc * sizeof (bfd_mach_o_dylib_table_of_content));
2192
      if (cmd->dylib_toc == NULL)
2193
        return -1;
2194
 
2195
      if (bfd_seek (abfd, cmd->tocoff, SEEK_SET) != 0)
2196
        return -1;
2197
 
2198
      for (i = 0; i < cmd->ntoc; i++)
2199
        {
2200
          bfd_mach_o_dylib_table_of_content *toc = &cmd->dylib_toc[i];
2201
 
2202
          if (bfd_bread ((void *) buf, 8, abfd) != 8)
2203
            return -1;
2204
 
2205
          toc->symbol_index = bfd_h_get_32 (abfd, buf + 0);
2206
          toc->module_index = bfd_h_get_32 (abfd, buf + 4);
2207
        }
2208
    }
2209
 
2210
  if (cmd->nindirectsyms != 0)
2211
    {
2212
      unsigned int i;
2213
 
2214
      cmd->indirect_syms = bfd_alloc
2215
        (abfd, cmd->nindirectsyms * sizeof (unsigned int));
2216
      if (cmd->indirect_syms == NULL)
2217
        return -1;
2218
 
2219
      if (bfd_seek (abfd, cmd->indirectsymoff, SEEK_SET) != 0)
2220
        return -1;
2221
 
2222
      for (i = 0; i < cmd->nindirectsyms; i++)
2223
        {
2224
          unsigned int *is = &cmd->indirect_syms[i];
2225
 
2226
          if (bfd_bread ((void *) buf, 4, abfd) != 4)
2227
            return -1;
2228
 
2229
          *is = bfd_h_get_32 (abfd, buf + 0);
2230
        }
2231
    }
2232
 
2233
  if (cmd->nextrefsyms != 0)
2234
    {
2235
      unsigned long v;
2236
      unsigned int i;
2237
 
2238
      cmd->ext_refs = bfd_alloc
2239
        (abfd, cmd->nextrefsyms * sizeof (bfd_mach_o_dylib_reference));
2240
      if (cmd->ext_refs == NULL)
2241
        return -1;
2242
 
2243
      if (bfd_seek (abfd, cmd->extrefsymoff, SEEK_SET) != 0)
2244
        return -1;
2245
 
2246
      for (i = 0; i < cmd->nextrefsyms; i++)
2247
        {
2248
          bfd_mach_o_dylib_reference *ref = &cmd->ext_refs[i];
2249
 
2250
          if (bfd_bread ((void *) buf, 4, abfd) != 4)
2251
            return -1;
2252
 
2253
          /* Fields isym and flags are written as bit-fields, thus we need
2254
             a specific processing for endianness.  */
2255
          v = bfd_h_get_32 (abfd, buf + 0);
2256
          if (bfd_big_endian (abfd))
2257
            {
2258
              ref->isym = (v >> 8) & 0xffffff;
2259
              ref->flags = v & 0xff;
2260
            }
2261
          else
2262
            {
2263
              ref->isym = v & 0xffffff;
2264
              ref->flags = (v >> 24) & 0xff;
2265
            }
2266
        }
2267
    }
2268
 
2269
  if (mdata->dysymtab)
2270
    return -1;
2271
  mdata->dysymtab = cmd;
2272
 
2273
  return 0;
2274
}
2275
 
2276
static int
2277
bfd_mach_o_read_symtab (bfd *abfd, bfd_mach_o_load_command *command)
2278
{
2279
  bfd_mach_o_symtab_command *symtab = &command->command.symtab;
2280
  bfd_mach_o_data_struct *mdata = bfd_mach_o_get_data (abfd);
2281
  unsigned char buf[16];
2282
 
2283
  BFD_ASSERT (command->type == BFD_MACH_O_LC_SYMTAB);
2284
 
2285
  if (bfd_seek (abfd, command->offset + 8, SEEK_SET) != 0
2286
      || bfd_bread ((void *) buf, 16, abfd) != 16)
2287
    return -1;
2288
 
2289
  symtab->symoff = bfd_h_get_32 (abfd, buf);
2290
  symtab->nsyms = bfd_h_get_32 (abfd, buf + 4);
2291
  symtab->stroff = bfd_h_get_32 (abfd, buf + 8);
2292
  symtab->strsize = bfd_h_get_32 (abfd, buf + 12);
2293
  symtab->symbols = NULL;
2294
  symtab->strtab = NULL;
2295
 
2296
  if (symtab->nsyms != 0)
2297
    abfd->flags |= HAS_SYMS;
2298
 
2299
  if (mdata->symtab)
2300
    return -1;
2301
  mdata->symtab = symtab;
2302
  return 0;
2303
}
2304
 
2305
static int
2306
bfd_mach_o_read_uuid (bfd *abfd, bfd_mach_o_load_command *command)
2307
{
2308
  bfd_mach_o_uuid_command *cmd = &command->command.uuid;
2309
 
2310
  BFD_ASSERT (command->type == BFD_MACH_O_LC_UUID);
2311
 
2312
  if (bfd_seek (abfd, command->offset + 8, SEEK_SET) != 0
2313
      || bfd_bread ((void *) cmd->uuid, 16, abfd) != 16)
2314
    return -1;
2315
 
2316
  return 0;
2317
}
2318
 
2319
static int
2320
bfd_mach_o_read_linkedit (bfd *abfd, bfd_mach_o_load_command *command)
2321
{
2322
  bfd_mach_o_linkedit_command *cmd = &command->command.linkedit;
2323
  char buf[8];
2324
 
2325
  if (bfd_seek (abfd, command->offset + 8, SEEK_SET) != 0
2326
      || bfd_bread ((void *) buf, 8, abfd) != 8)
2327
    return -1;
2328
 
2329
  cmd->dataoff = bfd_get_32 (abfd, buf + 0);
2330
  cmd->datasize = bfd_get_32 (abfd, buf + 4);
2331
  return 0;
2332
}
2333
 
2334
static int
2335
bfd_mach_o_read_str (bfd *abfd, bfd_mach_o_load_command *command)
2336
{
2337
  bfd_mach_o_str_command *cmd = &command->command.str;
2338
  char buf[4];
2339
  unsigned long off;
2340
 
2341
  if (bfd_seek (abfd, command->offset + 8, SEEK_SET) != 0
2342
      || bfd_bread ((void *) buf, 4, abfd) != 4)
2343
    return -1;
2344
 
2345
  off = bfd_get_32 (abfd, buf + 0);
2346
  cmd->stroff = command->offset + off;
2347
  cmd->str_len = command->len - off;
2348
  cmd->str = bfd_alloc (abfd, cmd->str_len);
2349
  if (cmd->str == NULL)
2350
    return -1;
2351
  if (bfd_seek (abfd, cmd->stroff, SEEK_SET) != 0
2352
      || bfd_bread ((void *) cmd->str, cmd->str_len, abfd) != cmd->str_len)
2353
    return -1;
2354
  return 0;
2355
}
2356
 
2357
static int
2358
bfd_mach_o_read_dyld_info (bfd *abfd, bfd_mach_o_load_command *command)
2359
{
2360
  bfd_mach_o_dyld_info_command *cmd = &command->command.dyld_info;
2361
  char buf[40];
2362
 
2363
  if (bfd_seek (abfd, command->offset + 8, SEEK_SET) != 0
2364
      || bfd_bread ((void *) buf, sizeof (buf), abfd) != sizeof (buf))
2365
    return -1;
2366
 
2367
  cmd->rebase_off = bfd_get_32 (abfd, buf + 0);
2368
  cmd->rebase_size = bfd_get_32 (abfd, buf + 4);
2369
  cmd->bind_off = bfd_get_32 (abfd, buf + 8);
2370
  cmd->bind_size = bfd_get_32 (abfd, buf + 12);
2371
  cmd->weak_bind_off = bfd_get_32 (abfd, buf + 16);
2372
  cmd->weak_bind_size = bfd_get_32 (abfd, buf + 20);
2373
  cmd->lazy_bind_off = bfd_get_32 (abfd, buf + 24);
2374
  cmd->lazy_bind_size = bfd_get_32 (abfd, buf + 28);
2375
  cmd->export_off = bfd_get_32 (abfd, buf + 32);
2376
  cmd->export_size = bfd_get_32 (abfd, buf + 36);
2377
  return 0;
2378
}
2379
 
2380
static int
2381
bfd_mach_o_read_segment (bfd *abfd,
2382
                         bfd_mach_o_load_command *command,
2383
                         unsigned int wide)
2384
{
2385
  unsigned char buf[64];
2386
  bfd_mach_o_segment_command *seg = &command->command.segment;
2387
  unsigned long i;
2388
 
2389
  if (wide)
2390
    {
2391
      BFD_ASSERT (command->type == BFD_MACH_O_LC_SEGMENT_64);
2392
 
2393
      if (bfd_seek (abfd, command->offset + 8, SEEK_SET) != 0
2394
          || bfd_bread ((void *) buf, 64, abfd) != 64)
2395
        return -1;
2396
 
2397
      memcpy (seg->segname, buf, 16);
2398
      seg->segname[16] = '\0';
2399
 
2400
      seg->vmaddr = bfd_h_get_64 (abfd, buf + 16);
2401
      seg->vmsize = bfd_h_get_64 (abfd, buf + 24);
2402
      seg->fileoff = bfd_h_get_64 (abfd, buf + 32);
2403
      seg->filesize = bfd_h_get_64 (abfd, buf + 40);
2404
      seg->maxprot = bfd_h_get_32 (abfd, buf + 48);
2405
      seg->initprot = bfd_h_get_32 (abfd, buf + 52);
2406
      seg->nsects = bfd_h_get_32 (abfd, buf + 56);
2407
      seg->flags = bfd_h_get_32 (abfd, buf + 60);
2408
    }
2409
  else
2410
    {
2411
      BFD_ASSERT (command->type == BFD_MACH_O_LC_SEGMENT);
2412
 
2413
      if (bfd_seek (abfd, command->offset + 8, SEEK_SET) != 0
2414
          || bfd_bread ((void *) buf, 48, abfd) != 48)
2415
        return -1;
2416
 
2417
      memcpy (seg->segname, buf, 16);
2418
      seg->segname[16] = '\0';
2419
 
2420
      seg->vmaddr = bfd_h_get_32 (abfd, buf + 16);
2421
      seg->vmsize = bfd_h_get_32 (abfd, buf + 20);
2422
      seg->fileoff = bfd_h_get_32 (abfd, buf + 24);
2423
      seg->filesize = bfd_h_get_32 (abfd, buf +  28);
2424
      seg->maxprot = bfd_h_get_32 (abfd, buf + 32);
2425
      seg->initprot = bfd_h_get_32 (abfd, buf + 36);
2426
      seg->nsects = bfd_h_get_32 (abfd, buf + 40);
2427
      seg->flags = bfd_h_get_32 (abfd, buf + 44);
2428
    }
2429
 
2430
  if (seg->nsects != 0)
2431
    {
2432
      seg->sections = bfd_alloc (abfd, seg->nsects
2433
                                 * sizeof (bfd_mach_o_section));
2434
      if (seg->sections == NULL)
2435
        return -1;
2436
 
2437
      for (i = 0; i < seg->nsects; i++)
2438
        {
2439
          bfd_vma segoff;
2440
          if (wide)
2441
            segoff = command->offset + BFD_MACH_O_LC_SEGMENT_64_SIZE
2442
              + (i * BFD_MACH_O_SECTION_64_SIZE);
2443
          else
2444
            segoff = command->offset + BFD_MACH_O_LC_SEGMENT_SIZE
2445
              + (i * BFD_MACH_O_SECTION_SIZE);
2446
 
2447
          if (bfd_mach_o_read_section
2448
              (abfd, &seg->sections[i], segoff, seg->initprot, wide) != 0)
2449
            return -1;
2450
        }
2451
    }
2452
 
2453
  return 0;
2454
}
2455
 
2456
static int
2457
bfd_mach_o_read_segment_32 (bfd *abfd, bfd_mach_o_load_command *command)
2458
{
2459
  return bfd_mach_o_read_segment (abfd, command, 0);
2460
}
2461
 
2462
static int
2463
bfd_mach_o_read_segment_64 (bfd *abfd, bfd_mach_o_load_command *command)
2464
{
2465
  return bfd_mach_o_read_segment (abfd, command, 1);
2466
}
2467
 
2468
static int
2469
bfd_mach_o_read_command (bfd *abfd, bfd_mach_o_load_command *command)
2470
{
2471
  unsigned char buf[8];
2472
 
2473
  /* Read command type and length.  */
2474
  if (bfd_seek (abfd, command->offset, SEEK_SET) != 0
2475
      || bfd_bread ((void *) buf, 8, abfd) != 8)
2476
    return -1;
2477
 
2478
  command->type = bfd_h_get_32 (abfd, buf) & ~BFD_MACH_O_LC_REQ_DYLD;
2479
  command->type_required = (bfd_h_get_32 (abfd, buf) & BFD_MACH_O_LC_REQ_DYLD
2480
                            ? TRUE : FALSE);
2481
  command->len = bfd_h_get_32 (abfd, buf + 4);
2482
 
2483
  switch (command->type)
2484
    {
2485
    case BFD_MACH_O_LC_SEGMENT:
2486
      if (bfd_mach_o_read_segment_32 (abfd, command) != 0)
2487
        return -1;
2488
      break;
2489
    case BFD_MACH_O_LC_SEGMENT_64:
2490
      if (bfd_mach_o_read_segment_64 (abfd, command) != 0)
2491
        return -1;
2492
      break;
2493
    case BFD_MACH_O_LC_SYMTAB:
2494
      if (bfd_mach_o_read_symtab (abfd, command) != 0)
2495
        return -1;
2496
      break;
2497
    case BFD_MACH_O_LC_SYMSEG:
2498
      break;
2499
    case BFD_MACH_O_LC_THREAD:
2500
    case BFD_MACH_O_LC_UNIXTHREAD:
2501
      if (bfd_mach_o_read_thread (abfd, command) != 0)
2502
        return -1;
2503
      break;
2504
    case BFD_MACH_O_LC_LOAD_DYLINKER:
2505
    case BFD_MACH_O_LC_ID_DYLINKER:
2506
      if (bfd_mach_o_read_dylinker (abfd, command) != 0)
2507
        return -1;
2508
      break;
2509
    case BFD_MACH_O_LC_LOAD_DYLIB:
2510
    case BFD_MACH_O_LC_ID_DYLIB:
2511
    case BFD_MACH_O_LC_LOAD_WEAK_DYLIB:
2512
    case BFD_MACH_O_LC_REEXPORT_DYLIB:
2513
      if (bfd_mach_o_read_dylib (abfd, command) != 0)
2514
        return -1;
2515
      break;
2516
    case BFD_MACH_O_LC_PREBOUND_DYLIB:
2517
      if (bfd_mach_o_read_prebound_dylib (abfd, command) != 0)
2518
        return -1;
2519
      break;
2520
    case BFD_MACH_O_LC_LOADFVMLIB:
2521
    case BFD_MACH_O_LC_IDFVMLIB:
2522
    case BFD_MACH_O_LC_IDENT:
2523
    case BFD_MACH_O_LC_FVMFILE:
2524
    case BFD_MACH_O_LC_PREPAGE:
2525
    case BFD_MACH_O_LC_ROUTINES:
2526
      break;
2527
    case BFD_MACH_O_LC_SUB_FRAMEWORK:
2528
    case BFD_MACH_O_LC_SUB_UMBRELLA:
2529
    case BFD_MACH_O_LC_SUB_LIBRARY:
2530
    case BFD_MACH_O_LC_SUB_CLIENT:
2531
    case BFD_MACH_O_LC_RPATH:
2532
      if (bfd_mach_o_read_str (abfd, command) != 0)
2533
        return -1;
2534
      break;
2535
    case BFD_MACH_O_LC_DYSYMTAB:
2536
      if (bfd_mach_o_read_dysymtab (abfd, command) != 0)
2537
        return -1;
2538
      break;
2539
    case BFD_MACH_O_LC_TWOLEVEL_HINTS:
2540
    case BFD_MACH_O_LC_PREBIND_CKSUM:
2541
      break;
2542
    case BFD_MACH_O_LC_UUID:
2543
      if (bfd_mach_o_read_uuid (abfd, command) != 0)
2544
        return -1;
2545
      break;
2546
    case BFD_MACH_O_LC_CODE_SIGNATURE:
2547
    case BFD_MACH_O_LC_SEGMENT_SPLIT_INFO:
2548
      if (bfd_mach_o_read_linkedit (abfd, command) != 0)
2549
        return -1;
2550
      break;
2551
    case BFD_MACH_O_LC_DYLD_INFO:
2552
      if (bfd_mach_o_read_dyld_info (abfd, command) != 0)
2553
        return -1;
2554
      break;
2555
    default:
2556
      (*_bfd_error_handler) (_("unable to read unknown load command 0x%lx"),
2557
                             (unsigned long) command->type);
2558
      break;
2559
    }
2560
 
2561
  return 0;
2562
}
2563
 
2564
static void
2565
bfd_mach_o_flatten_sections (bfd *abfd)
2566
{
2567
  bfd_mach_o_data_struct *mdata = bfd_mach_o_get_data (abfd);
2568
  long csect = 0;
2569
  unsigned long i, j;
2570
 
2571
  /* Count total number of sections.  */
2572
  mdata->nsects = 0;
2573
 
2574
  for (i = 0; i < mdata->header.ncmds; i++)
2575
    {
2576
      if (mdata->commands[i].type == BFD_MACH_O_LC_SEGMENT
2577
          || mdata->commands[i].type == BFD_MACH_O_LC_SEGMENT_64)
2578
        {
2579
          bfd_mach_o_segment_command *seg;
2580
 
2581
          seg = &mdata->commands[i].command.segment;
2582
          mdata->nsects += seg->nsects;
2583
        }
2584
    }
2585
 
2586
  /* Allocate sections array.  */
2587
  mdata->sections = bfd_alloc (abfd,
2588
                               mdata->nsects * sizeof (bfd_mach_o_section *));
2589
 
2590
  /* Fill the array.  */
2591
  csect = 0;
2592
 
2593
  for (i = 0; i < mdata->header.ncmds; i++)
2594
    {
2595
      if (mdata->commands[i].type == BFD_MACH_O_LC_SEGMENT
2596
          || mdata->commands[i].type == BFD_MACH_O_LC_SEGMENT_64)
2597
        {
2598
          bfd_mach_o_segment_command *seg;
2599
 
2600
          seg = &mdata->commands[i].command.segment;
2601
          BFD_ASSERT (csect + seg->nsects <= mdata->nsects);
2602
 
2603
          for (j = 0; j < seg->nsects; j++)
2604
            mdata->sections[csect++] = &seg->sections[j];
2605
        }
2606
    }
2607
}
2608
 
2609
int
2610
bfd_mach_o_scan_start_address (bfd *abfd)
2611
{
2612
  bfd_mach_o_data_struct *mdata = bfd_mach_o_get_data (abfd);
2613
  bfd_mach_o_thread_command *cmd = NULL;
2614
  unsigned long i;
2615
 
2616
  for (i = 0; i < mdata->header.ncmds; i++)
2617
    {
2618
      if ((mdata->commands[i].type == BFD_MACH_O_LC_THREAD) ||
2619
          (mdata->commands[i].type == BFD_MACH_O_LC_UNIXTHREAD))
2620
        {
2621
          if (cmd == NULL)
2622
            cmd = &mdata->commands[i].command.thread;
2623
          else
2624
            return 0;
2625
        }
2626
    }
2627
 
2628
  if (cmd == NULL)
2629
    return 0;
2630
 
2631
  for (i = 0; i < cmd->nflavours; i++)
2632
    {
2633
      if ((mdata->header.cputype == BFD_MACH_O_CPU_TYPE_I386)
2634
          && (cmd->flavours[i].flavour
2635
              == (unsigned long) BFD_MACH_O_x86_THREAD_STATE32))
2636
        {
2637
          unsigned char buf[4];
2638
 
2639
          if (bfd_seek (abfd, cmd->flavours[i].offset + 40, SEEK_SET) != 0
2640
              || bfd_bread (buf, 4, abfd) != 4)
2641
            return -1;
2642
 
2643
          abfd->start_address = bfd_h_get_32 (abfd, buf);
2644
        }
2645
      else if ((mdata->header.cputype == BFD_MACH_O_CPU_TYPE_POWERPC)
2646
               && (cmd->flavours[i].flavour == BFD_MACH_O_PPC_THREAD_STATE))
2647
        {
2648
          unsigned char buf[4];
2649
 
2650
          if (bfd_seek (abfd, cmd->flavours[i].offset + 0, SEEK_SET) != 0
2651
              || bfd_bread (buf, 4, abfd) != 4)
2652
            return -1;
2653
 
2654
          abfd->start_address = bfd_h_get_32 (abfd, buf);
2655
        }
2656
      else if ((mdata->header.cputype == BFD_MACH_O_CPU_TYPE_POWERPC_64)
2657
               && (cmd->flavours[i].flavour == BFD_MACH_O_PPC_THREAD_STATE64))
2658
        {
2659
          unsigned char buf[8];
2660
 
2661
          if (bfd_seek (abfd, cmd->flavours[i].offset + 0, SEEK_SET) != 0
2662
              || bfd_bread (buf, 8, abfd) != 8)
2663
            return -1;
2664
 
2665
          abfd->start_address = bfd_h_get_64 (abfd, buf);
2666
        }
2667
      else if ((mdata->header.cputype == BFD_MACH_O_CPU_TYPE_X86_64)
2668
               && (cmd->flavours[i].flavour == BFD_MACH_O_x86_THREAD_STATE64))
2669
        {
2670
          unsigned char buf[8];
2671
 
2672
          if (bfd_seek (abfd, cmd->flavours[i].offset + (16 * 8), SEEK_SET) != 0
2673
              || bfd_bread (buf, 8, abfd) != 8)
2674
            return -1;
2675
 
2676
          abfd->start_address = bfd_h_get_64 (abfd, buf);
2677
        }
2678
    }
2679
 
2680
  return 0;
2681
}
2682
 
2683
bfd_boolean
2684
bfd_mach_o_set_arch_mach (bfd *abfd,
2685
                          enum bfd_architecture arch,
2686
                          unsigned long machine)
2687
{
2688
  bfd_mach_o_backend_data *bed = bfd_mach_o_get_backend_data (abfd);
2689
 
2690
  /* If this isn't the right architecture for this backend, and this
2691
     isn't the generic backend, fail.  */
2692
  if (arch != bed->arch
2693
      && arch != bfd_arch_unknown
2694
      && bed->arch != bfd_arch_unknown)
2695
    return FALSE;
2696
 
2697
  return bfd_default_set_arch_mach (abfd, arch, machine);
2698
}
2699
 
2700
int
2701
bfd_mach_o_scan (bfd *abfd,
2702
                 bfd_mach_o_header *header,
2703
                 bfd_mach_o_data_struct *mdata)
2704
{
2705
  unsigned int i;
2706
  enum bfd_architecture cputype;
2707
  unsigned long cpusubtype;
2708
  unsigned int hdrsize;
2709
 
2710
  hdrsize = mach_o_wide_p (header) ?
2711
    BFD_MACH_O_HEADER_64_SIZE : BFD_MACH_O_HEADER_SIZE;
2712
 
2713
  mdata->header = *header;
2714
 
2715
  abfd->flags = abfd->flags & BFD_IN_MEMORY;
2716
  switch (header->filetype)
2717
    {
2718
    case BFD_MACH_O_MH_OBJECT:
2719
      abfd->flags |= HAS_RELOC;
2720
      break;
2721
    case BFD_MACH_O_MH_EXECUTE:
2722
      abfd->flags |= EXEC_P;
2723
      break;
2724
    case BFD_MACH_O_MH_DYLIB:
2725
    case BFD_MACH_O_MH_BUNDLE:
2726
      abfd->flags |= DYNAMIC;
2727
      break;
2728
    }
2729
 
2730
  abfd->tdata.mach_o_data = mdata;
2731
 
2732
  bfd_mach_o_convert_architecture (header->cputype, header->cpusubtype,
2733
                                   &cputype, &cpusubtype);
2734
  if (cputype == bfd_arch_unknown)
2735
    {
2736
      (*_bfd_error_handler) (_("bfd_mach_o_scan: unknown architecture 0x%lx/0x%lx"),
2737
                             header->cputype, header->cpusubtype);
2738
      return -1;
2739
    }
2740
 
2741
  bfd_set_arch_mach (abfd, cputype, cpusubtype);
2742
 
2743
  if (header->ncmds != 0)
2744
    {
2745
      mdata->commands = bfd_alloc
2746
        (abfd, header->ncmds * sizeof (bfd_mach_o_load_command));
2747
      if (mdata->commands == NULL)
2748
        return -1;
2749
 
2750
      for (i = 0; i < header->ncmds; i++)
2751
        {
2752
          bfd_mach_o_load_command *cur = &mdata->commands[i];
2753
 
2754
          if (i == 0)
2755
            cur->offset = hdrsize;
2756
          else
2757
            {
2758
              bfd_mach_o_load_command *prev = &mdata->commands[i - 1];
2759
              cur->offset = prev->offset + prev->len;
2760
            }
2761
 
2762
          if (bfd_mach_o_read_command (abfd, cur) < 0)
2763
            return -1;
2764
        }
2765
    }
2766
 
2767
  if (bfd_mach_o_scan_start_address (abfd) < 0)
2768
    return -1;
2769
 
2770
  bfd_mach_o_flatten_sections (abfd);
2771
  return 0;
2772
}
2773
 
2774
bfd_boolean
2775
bfd_mach_o_mkobject_init (bfd *abfd)
2776
{
2777
  bfd_mach_o_data_struct *mdata = NULL;
2778
 
2779
  mdata = bfd_alloc (abfd, sizeof (bfd_mach_o_data_struct));
2780
  if (mdata == NULL)
2781
    return FALSE;
2782
  abfd->tdata.mach_o_data = mdata;
2783
 
2784
  mdata->header.magic = 0;
2785
  mdata->header.cputype = 0;
2786
  mdata->header.cpusubtype = 0;
2787
  mdata->header.filetype = 0;
2788
  mdata->header.ncmds = 0;
2789
  mdata->header.sizeofcmds = 0;
2790
  mdata->header.flags = 0;
2791
  mdata->header.byteorder = BFD_ENDIAN_UNKNOWN;
2792
  mdata->commands = NULL;
2793
  mdata->nsects = 0;
2794
  mdata->sections = NULL;
2795
 
2796
  return TRUE;
2797
}
2798
 
2799
static bfd_boolean
2800
bfd_mach_o_gen_mkobject (bfd *abfd)
2801
{
2802
  bfd_mach_o_data_struct *mdata;
2803
 
2804
  if (!bfd_mach_o_mkobject_init (abfd))
2805
    return FALSE;
2806
 
2807
  mdata = bfd_mach_o_get_data (abfd);
2808
  mdata->header.magic = BFD_MACH_O_MH_MAGIC;
2809
  mdata->header.cputype = 0;
2810
  mdata->header.cpusubtype = 0;
2811
  mdata->header.byteorder = abfd->xvec->byteorder;
2812
  mdata->header.version = 1;
2813
 
2814
  return TRUE;
2815
}
2816
 
2817
const bfd_target *
2818
bfd_mach_o_header_p (bfd *abfd,
2819
                     bfd_mach_o_filetype filetype,
2820
                     bfd_mach_o_cpu_type cputype)
2821
{
2822
  struct bfd_preserve preserve;
2823
  bfd_mach_o_header header;
2824
 
2825
  preserve.marker = NULL;
2826
  if (!bfd_mach_o_read_header (abfd, &header))
2827
    goto wrong;
2828
 
2829
  if (! (header.byteorder == BFD_ENDIAN_BIG
2830
         || header.byteorder == BFD_ENDIAN_LITTLE))
2831
    {
2832
      (*_bfd_error_handler) (_("unknown header byte-order value 0x%lx"),
2833
                             (unsigned long) header.byteorder);
2834
      goto wrong;
2835
    }
2836
 
2837
  if (! ((header.byteorder == BFD_ENDIAN_BIG
2838
          && abfd->xvec->byteorder == BFD_ENDIAN_BIG
2839
          && abfd->xvec->header_byteorder == BFD_ENDIAN_BIG)
2840
         || (header.byteorder == BFD_ENDIAN_LITTLE
2841
             && abfd->xvec->byteorder == BFD_ENDIAN_LITTLE
2842
             && abfd->xvec->header_byteorder == BFD_ENDIAN_LITTLE)))
2843
    goto wrong;
2844
 
2845
  /* Check cputype and filetype.
2846
     In case of wildcard, do not accept magics that are handled by existing
2847
     targets.  */
2848
  if (cputype)
2849
    {
2850
      if (header.cputype != cputype)
2851
        goto wrong;
2852
    }
2853
  else
2854
    {
2855
      switch (header.cputype)
2856
        {
2857
        case BFD_MACH_O_CPU_TYPE_I386:
2858
          /* Handled by mach-o-i386 */
2859
          goto wrong;
2860
        default:
2861
          break;
2862
        }
2863
    }
2864
  if (filetype)
2865
    {
2866
      if (header.filetype != filetype)
2867
        goto wrong;
2868
    }
2869
  else
2870
    {
2871
      switch (header.filetype)
2872
        {
2873
        case BFD_MACH_O_MH_CORE:
2874
          /* Handled by core_p */
2875
          goto wrong;
2876
        default:
2877
          break;
2878
        }
2879
    }
2880
 
2881
  preserve.marker = bfd_zalloc (abfd, sizeof (bfd_mach_o_data_struct));
2882
  if (preserve.marker == NULL
2883
      || !bfd_preserve_save (abfd, &preserve))
2884
    goto fail;
2885
 
2886
  if (bfd_mach_o_scan (abfd, &header,
2887
                       (bfd_mach_o_data_struct *) preserve.marker) != 0)
2888
    goto wrong;
2889
 
2890
  bfd_preserve_finish (abfd, &preserve);
2891
  return abfd->xvec;
2892
 
2893
 wrong:
2894
  bfd_set_error (bfd_error_wrong_format);
2895
 
2896
 fail:
2897
  if (preserve.marker != NULL)
2898
    bfd_preserve_restore (abfd, &preserve);
2899
  return NULL;
2900
}
2901
 
2902
static const bfd_target *
2903
bfd_mach_o_gen_object_p (bfd *abfd)
2904
{
2905
  return bfd_mach_o_header_p (abfd, 0, 0);
2906
}
2907
 
2908
static const bfd_target *
2909
bfd_mach_o_gen_core_p (bfd *abfd)
2910
{
2911
  return bfd_mach_o_header_p (abfd, BFD_MACH_O_MH_CORE, 0);
2912
}
2913
 
2914
typedef struct mach_o_fat_archentry
2915
{
2916
  unsigned long cputype;
2917
  unsigned long cpusubtype;
2918
  unsigned long offset;
2919
  unsigned long size;
2920
  unsigned long align;
2921
} mach_o_fat_archentry;
2922
 
2923
typedef struct mach_o_fat_data_struct
2924
{
2925
  unsigned long magic;
2926
  unsigned long nfat_arch;
2927
  mach_o_fat_archentry *archentries;
2928
} mach_o_fat_data_struct;
2929
 
2930
const bfd_target *
2931
bfd_mach_o_archive_p (bfd *abfd)
2932
{
2933
  mach_o_fat_data_struct *adata = NULL;
2934
  unsigned char buf[20];
2935
  unsigned long i;
2936
 
2937
  if (bfd_seek (abfd, 0, SEEK_SET) != 0
2938
      || bfd_bread ((void *) buf, 8, abfd) != 8)
2939
    goto error;
2940
 
2941
  adata = bfd_alloc (abfd, sizeof (mach_o_fat_data_struct));
2942
  if (adata == NULL)
2943
    goto error;
2944
 
2945
  adata->magic = bfd_getb32 (buf);
2946
  adata->nfat_arch = bfd_getb32 (buf + 4);
2947
  if (adata->magic != 0xcafebabe)
2948
    goto error;
2949
  /* Avoid matching Java bytecode files, which have the same magic number.
2950
     In the Java bytecode file format this field contains the JVM version,
2951
     which starts at 43.0.  */
2952
  if (adata->nfat_arch > 30)
2953
    goto error;
2954
 
2955
  adata->archentries =
2956
    bfd_alloc (abfd, adata->nfat_arch * sizeof (mach_o_fat_archentry));
2957
  if (adata->archentries == NULL)
2958
    goto error;
2959
 
2960
  for (i = 0; i < adata->nfat_arch; i++)
2961
    {
2962
      if (bfd_seek (abfd, 8 + 20 * i, SEEK_SET) != 0
2963
          || bfd_bread ((void *) buf, 20, abfd) != 20)
2964
        goto error;
2965
      adata->archentries[i].cputype = bfd_getb32 (buf);
2966
      adata->archentries[i].cpusubtype = bfd_getb32 (buf + 4);
2967
      adata->archentries[i].offset = bfd_getb32 (buf + 8);
2968
      adata->archentries[i].size = bfd_getb32 (buf + 12);
2969
      adata->archentries[i].align = bfd_getb32 (buf + 16);
2970
    }
2971
 
2972
  abfd->tdata.mach_o_fat_data = adata;
2973
  return abfd->xvec;
2974
 
2975
 error:
2976
  if (adata != NULL)
2977
    bfd_release (abfd, adata);
2978
  bfd_set_error (bfd_error_wrong_format);
2979
  return NULL;
2980
}
2981
 
2982
bfd *
2983
bfd_mach_o_openr_next_archived_file (bfd *archive, bfd *prev)
2984
{
2985
  mach_o_fat_data_struct *adata;
2986
  mach_o_fat_archentry *entry = NULL;
2987
  unsigned long i;
2988
  bfd *nbfd;
2989
  enum bfd_architecture arch_type;
2990
  unsigned long arch_subtype;
2991
 
2992
  adata = (mach_o_fat_data_struct *) archive->tdata.mach_o_fat_data;
2993
  BFD_ASSERT (adata != NULL);
2994
 
2995
  /* Find index of previous entry.  */
2996
  if (prev == NULL)
2997
    i = 0;       /* Start at first one.  */
2998
  else
2999
    {
3000
      for (i = 0; i < adata->nfat_arch; i++)
3001
        {
3002
          if (adata->archentries[i].offset == prev->origin)
3003
            break;
3004
        }
3005
 
3006
      if (i == adata->nfat_arch)
3007
        {
3008
          /* Not found.  */
3009
          bfd_set_error (bfd_error_bad_value);
3010
          return NULL;
3011
        }
3012
    i++;        /* Get next entry.  */
3013
  }
3014
 
3015
  if (i >= adata->nfat_arch)
3016
    {
3017
      bfd_set_error (bfd_error_no_more_archived_files);
3018
      return NULL;
3019
    }
3020
 
3021
  entry = &adata->archentries[i];
3022
  nbfd = _bfd_new_bfd_contained_in (archive);
3023
  if (nbfd == NULL)
3024
    return NULL;
3025
 
3026
  nbfd->origin = entry->offset;
3027
 
3028
  bfd_mach_o_convert_architecture (entry->cputype, entry->cpusubtype,
3029
                                   &arch_type, &arch_subtype);
3030
  /* Create the member filename.
3031
     Use FILENAME:ARCH_NAME.  */
3032
  {
3033
    char *s = NULL;
3034
    const char *arch_name;
3035
    size_t arch_file_len = strlen (bfd_get_filename (archive));
3036
 
3037
    arch_name = bfd_printable_arch_mach (arch_type, arch_subtype);
3038
    s = bfd_malloc (arch_file_len + 1 + strlen (arch_name) + 1);
3039
    if (s == NULL)
3040
      return NULL;
3041
    memcpy (s, bfd_get_filename (archive), arch_file_len);
3042
    s[arch_file_len] = ':';
3043
    strcpy (s + arch_file_len + 1, arch_name);
3044
    nbfd->filename = s;
3045
  }
3046
  nbfd->iostream = NULL;
3047
  bfd_set_arch_mach (nbfd, arch_type, arch_subtype);
3048
 
3049
  return nbfd;
3050
}
3051
 
3052
/* If ABFD format is FORMAT and architecture is ARCH, return it.
3053
   If ABFD is a fat image containing a member that corresponds to FORMAT
3054
   and ARCH, returns it.
3055
   In other case, returns NULL.
3056
   This function allows transparent uses of fat images.  */
3057
bfd *
3058
bfd_mach_o_fat_extract (bfd *abfd,
3059
                        bfd_format format,
3060
                        const bfd_arch_info_type *arch)
3061
{
3062
  bfd *res;
3063
  mach_o_fat_data_struct *adata;
3064
  unsigned int i;
3065
 
3066
  if (bfd_check_format (abfd, format))
3067
    {
3068
      if (bfd_get_arch_info (abfd) == arch)
3069
        return abfd;
3070
      return NULL;
3071
    }
3072
  if (!bfd_check_format (abfd, bfd_archive)
3073
      || abfd->xvec != &mach_o_fat_vec)
3074
    return NULL;
3075
 
3076
  /* This is a Mach-O fat image.  */
3077
  adata = (mach_o_fat_data_struct *) abfd->tdata.mach_o_fat_data;
3078
  BFD_ASSERT (adata != NULL);
3079
 
3080
  for (i = 0; i < adata->nfat_arch; i++)
3081
    {
3082
      struct mach_o_fat_archentry *e = &adata->archentries[i];
3083
      enum bfd_architecture cpu_type;
3084
      unsigned long cpu_subtype;
3085
 
3086
      bfd_mach_o_convert_architecture (e->cputype, e->cpusubtype,
3087
                                       &cpu_type, &cpu_subtype);
3088
      if (cpu_type != arch->arch || cpu_subtype != arch->mach)
3089
        continue;
3090
 
3091
      /* The architecture is found.  */
3092
      res = _bfd_new_bfd_contained_in (abfd);
3093
      if (res == NULL)
3094
        return NULL;
3095
 
3096
      res->origin = e->offset;
3097
 
3098
      res->filename = strdup (abfd->filename);
3099
      res->iostream = NULL;
3100
 
3101
      if (bfd_check_format (res, format))
3102
        {
3103
          BFD_ASSERT (bfd_get_arch_info (res) == arch);
3104
          return res;
3105
        }
3106
      bfd_close (res);
3107
      return NULL;
3108
    }
3109
 
3110
  return NULL;
3111
}
3112
 
3113
int
3114
bfd_mach_o_lookup_section (bfd *abfd,
3115
                           asection *section,
3116
                           bfd_mach_o_load_command **mcommand,
3117
                           bfd_mach_o_section **msection)
3118
{
3119
  struct mach_o_data_struct *md = bfd_mach_o_get_data (abfd);
3120
  unsigned int i, j, num;
3121
 
3122
  bfd_mach_o_load_command *ncmd = NULL;
3123
  bfd_mach_o_section *nsect = NULL;
3124
 
3125
  BFD_ASSERT (mcommand != NULL);
3126
  BFD_ASSERT (msection != NULL);
3127
 
3128
  num = 0;
3129
  for (i = 0; i < md->header.ncmds; i++)
3130
    {
3131
      struct bfd_mach_o_load_command *cmd = &md->commands[i];
3132
      struct bfd_mach_o_segment_command *seg = NULL;
3133
 
3134
      if (cmd->type != BFD_MACH_O_LC_SEGMENT
3135
          || cmd->type != BFD_MACH_O_LC_SEGMENT_64)
3136
        continue;
3137
      seg = &cmd->command.segment;
3138
 
3139
      for (j = 0; j < seg->nsects; j++)
3140
        {
3141
          struct bfd_mach_o_section *sect = &seg->sections[j];
3142
 
3143
          if (sect->bfdsection == section)
3144
            {
3145
              if (num == 0)
3146
                {
3147
                  nsect = sect;
3148
                  ncmd = cmd;
3149
                }
3150
              num++;
3151
            }
3152
        }
3153
    }
3154
 
3155
  *mcommand = ncmd;
3156
  *msection = nsect;
3157
  return num;
3158
}
3159
 
3160
int
3161
bfd_mach_o_lookup_command (bfd *abfd,
3162
                           bfd_mach_o_load_command_type type,
3163
                           bfd_mach_o_load_command **mcommand)
3164
{
3165
  struct mach_o_data_struct *md = bfd_mach_o_get_data (abfd);
3166
  bfd_mach_o_load_command *ncmd = NULL;
3167
  unsigned int i, num;
3168
 
3169
  BFD_ASSERT (md != NULL);
3170
  BFD_ASSERT (mcommand != NULL);
3171
 
3172
  num = 0;
3173
  for (i = 0; i < md->header.ncmds; i++)
3174
    {
3175
      struct bfd_mach_o_load_command *cmd = &md->commands[i];
3176
 
3177
      if (cmd->type != type)
3178
        continue;
3179
 
3180
      if (num == 0)
3181
        ncmd = cmd;
3182
      num++;
3183
    }
3184
 
3185
  *mcommand = ncmd;
3186
  return num;
3187
}
3188
 
3189
unsigned long
3190
bfd_mach_o_stack_addr (enum bfd_mach_o_cpu_type type)
3191
{
3192
  switch (type)
3193
    {
3194
    case BFD_MACH_O_CPU_TYPE_MC680x0:
3195
      return 0x04000000;
3196
    case BFD_MACH_O_CPU_TYPE_MC88000:
3197
      return 0xffffe000;
3198
    case BFD_MACH_O_CPU_TYPE_POWERPC:
3199
      return 0xc0000000;
3200
    case BFD_MACH_O_CPU_TYPE_I386:
3201
      return 0xc0000000;
3202
    case BFD_MACH_O_CPU_TYPE_SPARC:
3203
      return 0xf0000000;
3204
    case BFD_MACH_O_CPU_TYPE_I860:
3205
      return 0;
3206
    case BFD_MACH_O_CPU_TYPE_HPPA:
3207
      return 0xc0000000 - 0x04000000;
3208
    default:
3209
      return 0;
3210
    }
3211
}
3212
 
3213
typedef struct bfd_mach_o_xlat_name
3214
{
3215
  const char *name;
3216
  unsigned long val;
3217
}
3218
bfd_mach_o_xlat_name;
3219
 
3220
static void
3221
bfd_mach_o_print_flags (const bfd_mach_o_xlat_name *table,
3222
                        unsigned long val,
3223
                        FILE *file)
3224
{
3225
  int first = 1;
3226
 
3227
  for (; table->name; table++)
3228
    {
3229
      if (table->val & val)
3230
        {
3231
          if (!first)
3232
            fprintf (file, "+");
3233
          fprintf (file, "%s", table->name);
3234
          val &= ~table->val;
3235
          first = 0;
3236
        }
3237
    }
3238
  if (val)
3239
    {
3240
      if (!first)
3241
        fprintf (file, "+");
3242
      fprintf (file, "0x%lx", val);
3243
      return;
3244
    }
3245
  if (first)
3246
    fprintf (file, "-");
3247
}
3248
 
3249
static const char *
3250
bfd_mach_o_get_name (const bfd_mach_o_xlat_name *table, unsigned long val)
3251
{
3252
  for (; table->name; table++)
3253
    if (table->val == val)
3254
      return table->name;
3255
  return "*UNKNOWN*";
3256
}
3257
 
3258
static bfd_mach_o_xlat_name bfd_mach_o_cpu_name[] =
3259
{
3260
  { "vax", BFD_MACH_O_CPU_TYPE_VAX },
3261
  { "mc680x0", BFD_MACH_O_CPU_TYPE_MC680x0 },
3262
  { "i386", BFD_MACH_O_CPU_TYPE_I386 },
3263
  { "mips", BFD_MACH_O_CPU_TYPE_MIPS },
3264
  { "mc98000", BFD_MACH_O_CPU_TYPE_MC98000 },
3265
  { "hppa", BFD_MACH_O_CPU_TYPE_HPPA },
3266
  { "arm", BFD_MACH_O_CPU_TYPE_ARM },
3267
  { "mc88000", BFD_MACH_O_CPU_TYPE_MC88000 },
3268
  { "sparc", BFD_MACH_O_CPU_TYPE_SPARC },
3269
  { "i860", BFD_MACH_O_CPU_TYPE_I860 },
3270
  { "alpha", BFD_MACH_O_CPU_TYPE_ALPHA },
3271
  { "powerpc", BFD_MACH_O_CPU_TYPE_POWERPC },
3272
  { "powerpc_64", BFD_MACH_O_CPU_TYPE_POWERPC_64 },
3273
  { "x86_64", BFD_MACH_O_CPU_TYPE_X86_64 },
3274
  { NULL, 0}
3275
};
3276
 
3277
static bfd_mach_o_xlat_name bfd_mach_o_filetype_name[] =
3278
{
3279
  { "object", BFD_MACH_O_MH_OBJECT },
3280
  { "execute", BFD_MACH_O_MH_EXECUTE },
3281
  { "fvmlib", BFD_MACH_O_MH_FVMLIB },
3282
  { "core", BFD_MACH_O_MH_CORE },
3283
  { "preload", BFD_MACH_O_MH_PRELOAD },
3284
  { "dylib", BFD_MACH_O_MH_DYLIB },
3285
  { "dylinker", BFD_MACH_O_MH_DYLINKER },
3286
  { "bundle", BFD_MACH_O_MH_BUNDLE },
3287
  { "dylib_stub", BFD_MACH_O_MH_DYLIB_STUB },
3288
  { "dym", BFD_MACH_O_MH_DSYM },
3289
  { "kext_bundle", BFD_MACH_O_MH_KEXT_BUNDLE },
3290
  { NULL, 0}
3291
};
3292
 
3293
static bfd_mach_o_xlat_name bfd_mach_o_header_flags_name[] =
3294
{
3295
  { "noundefs", BFD_MACH_O_MH_NOUNDEFS },
3296
  { "incrlink", BFD_MACH_O_MH_INCRLINK },
3297
  { "dyldlink", BFD_MACH_O_MH_DYLDLINK },
3298
  { "bindatload", BFD_MACH_O_MH_BINDATLOAD },
3299
  { "prebound", BFD_MACH_O_MH_PREBOUND },
3300
  { "split_segs", BFD_MACH_O_MH_SPLIT_SEGS },
3301
  { "lazy_init", BFD_MACH_O_MH_LAZY_INIT },
3302
  { "twolevel", BFD_MACH_O_MH_TWOLEVEL },
3303
  { "force_flat", BFD_MACH_O_MH_FORCE_FLAT },
3304
  { "nomultidefs", BFD_MACH_O_MH_NOMULTIDEFS },
3305
  { "nofixprebinding", BFD_MACH_O_MH_NOFIXPREBINDING },
3306
  { "prebindable", BFD_MACH_O_MH_PREBINDABLE },
3307
  { "allmodsbound", BFD_MACH_O_MH_ALLMODSBOUND },
3308
  { "subsections_via_symbols", BFD_MACH_O_MH_SUBSECTIONS_VIA_SYMBOLS },
3309
  { "canonical", BFD_MACH_O_MH_CANONICAL },
3310
  { "weak_defines", BFD_MACH_O_MH_WEAK_DEFINES },
3311
  { "binds_to_weak", BFD_MACH_O_MH_BINDS_TO_WEAK },
3312
  { "allow_stack_execution", BFD_MACH_O_MH_ALLOW_STACK_EXECUTION },
3313
  { "root_safe", BFD_MACH_O_MH_ROOT_SAFE },
3314
  { "setuid_safe", BFD_MACH_O_MH_SETUID_SAFE },
3315
  { "no_reexported_dylibs", BFD_MACH_O_MH_NO_REEXPORTED_DYLIBS },
3316
  { "pie", BFD_MACH_O_MH_PIE },
3317
  { NULL, 0}
3318
};
3319
 
3320
static bfd_mach_o_xlat_name bfd_mach_o_section_type_name[] =
3321
{
3322
  { "regular", BFD_MACH_O_S_REGULAR},
3323
  { "zerofill", BFD_MACH_O_S_ZEROFILL},
3324
  { "cstring_literals", BFD_MACH_O_S_CSTRING_LITERALS},
3325
  { "4byte_literals", BFD_MACH_O_S_4BYTE_LITERALS},
3326
  { "8byte_literals", BFD_MACH_O_S_8BYTE_LITERALS},
3327
  { "literal_pointers", BFD_MACH_O_S_LITERAL_POINTERS},
3328
  { "non_lazy_symbol_pointers", BFD_MACH_O_S_NON_LAZY_SYMBOL_POINTERS},
3329
  { "lazy_symbol_pointers", BFD_MACH_O_S_LAZY_SYMBOL_POINTERS},
3330
  { "symbol_stubs", BFD_MACH_O_S_SYMBOL_STUBS},
3331
  { "mod_init_func_pointers", BFD_MACH_O_S_MOD_INIT_FUNC_POINTERS},
3332
  { "mod_fini_func_pointers", BFD_MACH_O_S_MOD_FINI_FUNC_POINTERS},
3333
  { "coalesced", BFD_MACH_O_S_COALESCED},
3334
  { "gb_zerofill", BFD_MACH_O_S_GB_ZEROFILL},
3335
  { "interposing", BFD_MACH_O_S_INTERPOSING},
3336
  { "16byte_literals", BFD_MACH_O_S_16BYTE_LITERALS},
3337
  { "dtrace_dof", BFD_MACH_O_S_DTRACE_DOF},
3338
  { "lazy_dylib_symbol_pointers", BFD_MACH_O_S_LAZY_DYLIB_SYMBOL_POINTERS},
3339
  { NULL, 0}
3340
};
3341
 
3342
static bfd_mach_o_xlat_name bfd_mach_o_section_attribute_name[] =
3343
{
3344
  { "loc_reloc", BFD_MACH_O_S_ATTR_LOC_RELOC },
3345
  { "ext_reloc", BFD_MACH_O_S_ATTR_EXT_RELOC },
3346
  { "some_instructions", BFD_MACH_O_S_ATTR_SOME_INSTRUCTIONS },
3347
  { "debug", BFD_MACH_O_S_ATTR_DEBUG },
3348
  { "modifying_code", BFD_MACH_O_S_SELF_MODIFYING_CODE },
3349
  { "live_support", BFD_MACH_O_S_ATTR_LIVE_SUPPORT },
3350
  { "no_dead_strip", BFD_MACH_O_S_ATTR_NO_DEAD_STRIP },
3351
  { "strip_static_syms", BFD_MACH_O_S_ATTR_STRIP_STATIC_SYMS },
3352
  { "no_toc", BFD_MACH_O_S_ATTR_NO_TOC },
3353
  { "pure_instructions", BFD_MACH_O_S_ATTR_PURE_INSTRUCTIONS },
3354
  { NULL, 0}
3355
};
3356
 
3357
static bfd_mach_o_xlat_name bfd_mach_o_load_command_name[] =
3358
{
3359
  { "segment", BFD_MACH_O_LC_SEGMENT},
3360
  { "symtab", BFD_MACH_O_LC_SYMTAB},
3361
  { "symseg", BFD_MACH_O_LC_SYMSEG},
3362
  { "thread", BFD_MACH_O_LC_THREAD},
3363
  { "unixthread", BFD_MACH_O_LC_UNIXTHREAD},
3364
  { "loadfvmlib", BFD_MACH_O_LC_LOADFVMLIB},
3365
  { "idfvmlib", BFD_MACH_O_LC_IDFVMLIB},
3366
  { "ident", BFD_MACH_O_LC_IDENT},
3367
  { "fvmfile", BFD_MACH_O_LC_FVMFILE},
3368
  { "prepage", BFD_MACH_O_LC_PREPAGE},
3369
  { "dysymtab", BFD_MACH_O_LC_DYSYMTAB},
3370
  { "load_dylib", BFD_MACH_O_LC_LOAD_DYLIB},
3371
  { "id_dylib", BFD_MACH_O_LC_ID_DYLIB},
3372
  { "load_dylinker", BFD_MACH_O_LC_LOAD_DYLINKER},
3373
  { "id_dylinker", BFD_MACH_O_LC_ID_DYLINKER},
3374
  { "prebound_dylib", BFD_MACH_O_LC_PREBOUND_DYLIB},
3375
  { "routines", BFD_MACH_O_LC_ROUTINES},
3376
  { "sub_framework", BFD_MACH_O_LC_SUB_FRAMEWORK},
3377
  { "sub_umbrella", BFD_MACH_O_LC_SUB_UMBRELLA},
3378
  { "sub_client", BFD_MACH_O_LC_SUB_CLIENT},
3379
  { "sub_library", BFD_MACH_O_LC_SUB_LIBRARY},
3380
  { "twolevel_hints", BFD_MACH_O_LC_TWOLEVEL_HINTS},
3381
  { "prebind_cksum", BFD_MACH_O_LC_PREBIND_CKSUM},
3382
  { "load_weak_dylib", BFD_MACH_O_LC_LOAD_WEAK_DYLIB},
3383
  { "segment_64", BFD_MACH_O_LC_SEGMENT_64},
3384
  { "routines_64", BFD_MACH_O_LC_ROUTINES_64},
3385
  { "uuid", BFD_MACH_O_LC_UUID},
3386
  { "rpath", BFD_MACH_O_LC_RPATH},
3387
  { "code_signature", BFD_MACH_O_LC_CODE_SIGNATURE},
3388
  { "segment_split_info", BFD_MACH_O_LC_SEGMENT_SPLIT_INFO},
3389
  { "reexport_dylib", BFD_MACH_O_LC_REEXPORT_DYLIB},
3390
  { "lazy_load_dylib", BFD_MACH_O_LC_LAZY_LOAD_DYLIB},
3391
  { "encryption_info", BFD_MACH_O_LC_ENCRYPTION_INFO},
3392
  { "dyld_info", BFD_MACH_O_LC_DYLD_INFO},
3393
  { NULL, 0}
3394
};
3395
 
3396
static void
3397
bfd_mach_o_print_private_header (bfd *abfd, FILE *file)
3398
{
3399
  bfd_mach_o_data_struct *mdata = bfd_mach_o_get_data (abfd);
3400
  bfd_mach_o_header *h = &mdata->header;
3401
 
3402
  fputs (_("Mach-O header:\n"), file);
3403
  fprintf (file, _(" magic     : %08lx\n"), h->magic);
3404
  fprintf (file, _(" cputype   : %08lx (%s)\n"), h->cputype,
3405
           bfd_mach_o_get_name (bfd_mach_o_cpu_name, h->cputype));
3406
  fprintf (file, _(" cpusubtype: %08lx\n"), h->cpusubtype);
3407
  fprintf (file, _(" filetype  : %08lx (%s)\n"),
3408
           h->filetype,
3409
           bfd_mach_o_get_name (bfd_mach_o_filetype_name, h->filetype));
3410
  fprintf (file, _(" ncmds     : %08lx (%lu)\n"), h->ncmds, h->ncmds);
3411
  fprintf (file, _(" sizeofcmds: %08lx\n"), h->sizeofcmds);
3412
  fprintf (file, _(" flags     : %08lx ("), h->flags);
3413
  bfd_mach_o_print_flags (bfd_mach_o_header_flags_name, h->flags, file);
3414
  fputs (_(")\n"), file);
3415
  fprintf (file, _(" reserved  : %08x\n"), h->reserved);
3416
}
3417
 
3418
static void
3419
bfd_mach_o_print_section_map (bfd *abfd, FILE *file)
3420
{
3421
  bfd_mach_o_data_struct *mdata = bfd_mach_o_get_data (abfd);
3422
  unsigned int i, j;
3423
  unsigned int sec_nbr = 0;
3424
 
3425
  fputs (_("Segments and Sections:\n"), file);
3426
  fputs (_(" #: Segment name     Section name     Address\n"), file);
3427
 
3428
  for (i = 0; i < mdata->header.ncmds; i++)
3429
    {
3430
      bfd_mach_o_segment_command *seg;
3431
 
3432
      if (mdata->commands[i].type != BFD_MACH_O_LC_SEGMENT
3433
          && mdata->commands[i].type != BFD_MACH_O_LC_SEGMENT_64)
3434
        continue;
3435
 
3436
      seg = &mdata->commands[i].command.segment;
3437
 
3438
      fprintf (file, "[Segment %-16s ", seg->segname);
3439
      fprintf_vma (file, seg->vmaddr);
3440
      fprintf (file, "-");
3441
      fprintf_vma  (file, seg->vmaddr + seg->vmsize - 1);
3442
      fputc (' ', file);
3443
      fputc (seg->initprot & BFD_MACH_O_PROT_READ ? 'r' : '-', file);
3444
      fputc (seg->initprot & BFD_MACH_O_PROT_WRITE ? 'w' : '-', file);
3445
      fputc (seg->initprot & BFD_MACH_O_PROT_EXECUTE ? 'x' : '-', file);
3446
      fprintf (file, "]\n");
3447
      for (j = 0; j < seg->nsects; j++)
3448
        {
3449
          bfd_mach_o_section *sec = &seg->sections[j];
3450
          fprintf (file, "%02u: %-16s %-16s ", ++sec_nbr,
3451
                   sec->segname, sec->sectname);
3452
          fprintf_vma (file, sec->addr);
3453
          fprintf (file, " ");
3454
          fprintf_vma  (file, sec->size);
3455
          fprintf (file, " %08lx\n", sec->flags);
3456
        }
3457
    }
3458
}
3459
 
3460
static void
3461
bfd_mach_o_print_section (bfd *abfd ATTRIBUTE_UNUSED,
3462
                          bfd_mach_o_section *sec, FILE *file)
3463
{
3464
  fprintf (file, " Section: %-16s %-16s (bfdname: %s)\n",
3465
           sec->sectname, sec->segname, sec->bfdsection->name);
3466
  fprintf (file, "  addr: ");
3467
  fprintf_vma (file, sec->addr);
3468
  fprintf (file, " size: ");
3469
  fprintf_vma  (file, sec->size);
3470
  fprintf (file, " offset: ");
3471
  fprintf_vma (file, sec->offset);
3472
  fprintf (file, "\n");
3473
  fprintf (file, "  align: %ld", sec->align);
3474
  fprintf (file, "  nreloc: %lu  reloff: ", sec->nreloc);
3475
  fprintf_vma (file, sec->reloff);
3476
  fprintf (file, "\n");
3477
  fprintf (file, "  flags: %08lx (type: %s", sec->flags,
3478
           bfd_mach_o_get_name (bfd_mach_o_section_type_name,
3479
                                sec->flags & BFD_MACH_O_SECTION_TYPE_MASK));
3480
  fprintf (file, " attr: ");
3481
  bfd_mach_o_print_flags (bfd_mach_o_section_attribute_name,
3482
                          sec->flags & BFD_MACH_O_SECTION_ATTRIBUTES_MASK,
3483
                          file);
3484
  fprintf (file, ")\n");
3485
  switch (sec->flags & BFD_MACH_O_SECTION_TYPE_MASK)
3486
    {
3487
    case BFD_MACH_O_S_NON_LAZY_SYMBOL_POINTERS:
3488
    case BFD_MACH_O_S_LAZY_SYMBOL_POINTERS:
3489
    case BFD_MACH_O_S_SYMBOL_STUBS:
3490
      fprintf (file, "  first indirect sym: %lu", sec->reserved1);
3491
      fprintf (file, " (%u entries)",
3492
               bfd_mach_o_section_get_nbr_indirect (abfd, sec));
3493
      break;
3494
    default:
3495
      fprintf (file, "  reserved1: 0x%lx", sec->reserved1);
3496
      break;
3497
    }
3498
  switch (sec->flags & BFD_MACH_O_SECTION_TYPE_MASK)
3499
    {
3500
    case BFD_MACH_O_S_SYMBOL_STUBS:
3501
      fprintf (file, "  stub size: %lu", sec->reserved2);
3502
      break;
3503
    default:
3504
      fprintf (file, "  reserved2: 0x%lx", sec->reserved2);
3505
      break;
3506
    }
3507
  fprintf (file, "  reserved3: 0x%lx\n", sec->reserved3);
3508
}
3509
 
3510
static void
3511
bfd_mach_o_print_segment (bfd *abfd ATTRIBUTE_UNUSED,
3512
                          bfd_mach_o_load_command *cmd, FILE *file)
3513
{
3514
  bfd_mach_o_segment_command *seg = &cmd->command.segment;
3515
  unsigned int i;
3516
 
3517
  fprintf (file, " name: %s\n", *seg->segname ? seg->segname : "*none*");
3518
  fprintf (file, "    vmaddr: ");
3519
  fprintf_vma (file, seg->vmaddr);
3520
  fprintf (file, "   vmsize: ");
3521
  fprintf_vma  (file, seg->vmsize);
3522
  fprintf (file, "\n");
3523
  fprintf (file, "   fileoff: ");
3524
  fprintf_vma (file, seg->fileoff);
3525
  fprintf (file, " filesize: ");
3526
  fprintf_vma (file, (bfd_vma)seg->filesize);
3527
  fprintf (file, " endoff: ");
3528
  fprintf_vma (file, (bfd_vma)(seg->fileoff + seg->filesize));
3529
  fprintf (file, "\n");
3530
  fprintf (file, "   nsects: %lu  ", seg->nsects);
3531
  fprintf (file, " flags: %lx\n", seg->flags);
3532
  for (i = 0; i < seg->nsects; i++)
3533
    bfd_mach_o_print_section (abfd, &seg->sections[i], file);
3534
}
3535
 
3536
static void
3537
bfd_mach_o_print_dysymtab (bfd *abfd ATTRIBUTE_UNUSED,
3538
                           bfd_mach_o_load_command *cmd, FILE *file)
3539
{
3540
  bfd_mach_o_dysymtab_command *dysymtab = &cmd->command.dysymtab;
3541
  bfd_mach_o_data_struct *mdata = bfd_mach_o_get_data (abfd);
3542
  unsigned int i;
3543
 
3544
  fprintf (file, "              local symbols: idx: %10lu  num: %-8lu",
3545
           dysymtab->ilocalsym, dysymtab->nlocalsym);
3546
  fprintf (file, " (nxtidx: %lu)\n",
3547
           dysymtab->ilocalsym + dysymtab->nlocalsym);
3548
  fprintf (file, "           external symbols: idx: %10lu  num: %-8lu",
3549
           dysymtab->iextdefsym, dysymtab->nextdefsym);
3550
  fprintf (file, " (nxtidx: %lu)\n",
3551
           dysymtab->iextdefsym + dysymtab->nextdefsym);
3552
  fprintf (file, "          undefined symbols: idx: %10lu  num: %-8lu",
3553
           dysymtab->iundefsym, dysymtab->nundefsym);
3554
  fprintf (file, " (nxtidx: %lu)\n",
3555
           dysymtab->iundefsym + dysymtab->nundefsym);
3556
  fprintf (file, "           table of content: off: 0x%08lx  num: %-8lu",
3557
           dysymtab->tocoff, dysymtab->ntoc);
3558
  fprintf (file, " (endoff: 0x%08lx)\n",
3559
           dysymtab->tocoff
3560
           + dysymtab->ntoc * BFD_MACH_O_TABLE_OF_CONTENT_SIZE);
3561
  fprintf (file, "               module table: off: 0x%08lx  num: %-8lu",
3562
           dysymtab->modtaboff, dysymtab->nmodtab);
3563
  fprintf (file, " (endoff: 0x%08lx)\n",
3564
           dysymtab->modtaboff + dysymtab->nmodtab
3565
           * (mach_o_wide_p (&mdata->header) ?
3566
              BFD_MACH_O_DYLIB_MODULE_64_SIZE : BFD_MACH_O_DYLIB_MODULE_SIZE));
3567
  fprintf (file, "   external reference table: off: 0x%08lx  num: %-8lu",
3568
           dysymtab->extrefsymoff, dysymtab->nextrefsyms);
3569
  fprintf (file, " (endoff: 0x%08lx)\n",
3570
           dysymtab->extrefsymoff
3571
           + dysymtab->nextrefsyms * BFD_MACH_O_REFERENCE_SIZE);
3572
  fprintf (file, "      indirect symbol table: off: 0x%08lx  num: %-8lu",
3573
           dysymtab->indirectsymoff, dysymtab->nindirectsyms);
3574
  fprintf (file, " (endoff: 0x%08lx)\n",
3575
           dysymtab->indirectsymoff
3576
           + dysymtab->nindirectsyms * BFD_MACH_O_INDIRECT_SYMBOL_SIZE);
3577
  fprintf (file, "  external relocation table: off: 0x%08lx  num: %-8lu",
3578
           dysymtab->extreloff, dysymtab->nextrel);
3579
  fprintf (file, " (endoff: 0x%08lx)\n",
3580
           dysymtab->extreloff + dysymtab->nextrel * BFD_MACH_O_RELENT_SIZE);
3581
  fprintf (file, "     local relocation table: off: 0x%08lx  num: %-8lu",
3582
           dysymtab->locreloff, dysymtab->nlocrel);
3583
  fprintf (file, " (endoff: 0x%08lx)\n",
3584
           dysymtab->locreloff + dysymtab->nlocrel * BFD_MACH_O_RELENT_SIZE);
3585
 
3586
  if (dysymtab->ntoc > 0
3587
      || dysymtab->nindirectsyms > 0
3588
      || dysymtab->nextrefsyms > 0)
3589
    {
3590
      /* Try to read the symbols to display the toc or indirect symbols.  */
3591
      bfd_mach_o_read_symtab_symbols (abfd);
3592
    }
3593
  else if (dysymtab->nmodtab > 0)
3594
    {
3595
      /* Try to read the strtab to display modules name.  */
3596
      bfd_mach_o_read_symtab_strtab (abfd);
3597
    }
3598
 
3599
  for (i = 0; i < dysymtab->nmodtab; i++)
3600
    {
3601
      bfd_mach_o_dylib_module *module = &dysymtab->dylib_module[i];
3602
      fprintf (file, "  module %u:\n", i);
3603
      fprintf (file, "   name: %lu", module->module_name_idx);
3604
      if (mdata->symtab && mdata->symtab->strtab)
3605
        fprintf (file, ": %s",
3606
                 mdata->symtab->strtab + module->module_name_idx);
3607
      fprintf (file, "\n");
3608
      fprintf (file, "   extdefsym: idx: %8lu  num: %lu\n",
3609
               module->iextdefsym, module->nextdefsym);
3610
      fprintf (file, "      refsym: idx: %8lu  num: %lu\n",
3611
               module->irefsym, module->nrefsym);
3612
      fprintf (file, "    localsym: idx: %8lu  num: %lu\n",
3613
               module->ilocalsym, module->nlocalsym);
3614
      fprintf (file, "      extrel: idx: %8lu  num: %lu\n",
3615
               module->iextrel, module->nextrel);
3616
      fprintf (file, "        init: idx: %8u  num: %u\n",
3617
               module->iinit, module->ninit);
3618
      fprintf (file, "        term: idx: %8u  num: %u\n",
3619
               module->iterm, module->nterm);
3620
      fprintf (file, "   objc_module_info: addr: ");
3621
      fprintf_vma (file, module->objc_module_info_addr);
3622
      fprintf (file, "  size: %lu\n", module->objc_module_info_size);
3623
    }
3624
 
3625
  if (dysymtab->ntoc > 0)
3626
    {
3627
      bfd_mach_o_symtab_command *symtab = mdata->symtab;
3628
 
3629
      fprintf (file, "  table of content: (symbol/module)\n");
3630
      for (i = 0; i < dysymtab->ntoc; i++)
3631
        {
3632
          bfd_mach_o_dylib_table_of_content *toc = &dysymtab->dylib_toc[i];
3633
 
3634
          fprintf (file, "   %4u: ", i);
3635
          if (symtab && symtab->symbols && toc->symbol_index < symtab->nsyms)
3636
            {
3637
              const char *name = symtab->symbols[toc->symbol_index].symbol.name;
3638
              fprintf (file, "%s (%lu)", name ? name : "*invalid*",
3639
                       toc->symbol_index);
3640
            }
3641
          else
3642
            fprintf (file, "%lu", toc->symbol_index);
3643
 
3644
          fprintf (file, " / ");
3645
          if (symtab && symtab->strtab
3646
              && toc->module_index < dysymtab->nmodtab)
3647
            {
3648
              bfd_mach_o_dylib_module *mod;
3649
              mod = &dysymtab->dylib_module[toc->module_index];
3650
              fprintf (file, "%s (%lu)",
3651
                       symtab->strtab + mod->module_name_idx,
3652
                       toc->module_index);
3653
            }
3654
          else
3655
            fprintf (file, "%lu", toc->module_index);
3656
 
3657
          fprintf (file, "\n");
3658
        }
3659
    }
3660
 
3661
  if (dysymtab->nindirectsyms != 0)
3662
    {
3663
      fprintf (file, "  indirect symbols:\n");
3664
 
3665
      for (i = 0; i < mdata->nsects; i++)
3666
        {
3667
          bfd_mach_o_section *sec = mdata->sections[i];
3668
          unsigned int j, first, last;
3669
          bfd_mach_o_symtab_command *symtab = mdata->symtab;
3670
          bfd_vma addr;
3671
          bfd_vma entry_size;
3672
 
3673
          switch (sec->flags & BFD_MACH_O_SECTION_TYPE_MASK)
3674
            {
3675
            case BFD_MACH_O_S_NON_LAZY_SYMBOL_POINTERS:
3676
            case BFD_MACH_O_S_LAZY_SYMBOL_POINTERS:
3677
            case BFD_MACH_O_S_SYMBOL_STUBS:
3678
              first = sec->reserved1;
3679
              last = first + bfd_mach_o_section_get_nbr_indirect (abfd, sec);
3680
              addr = sec->addr;
3681
              entry_size = bfd_mach_o_section_get_entry_size (abfd, sec);
3682
              fprintf (file, "  for section %s.%s:\n",
3683
                       sec->segname, sec->sectname);
3684
              for (j = first; j < last; j++)
3685
                {
3686
                  unsigned int isym = dysymtab->indirect_syms[j];
3687
 
3688
                  fprintf (file, "   ");
3689
                  fprintf_vma (file, addr);
3690
                  fprintf (file, " %5u: 0x%08x", j, isym);
3691
                  if (isym & BFD_MACH_O_INDIRECT_SYMBOL_LOCAL)
3692
                    fprintf (file, " LOCAL");
3693
                  if (isym & BFD_MACH_O_INDIRECT_SYMBOL_ABS)
3694
                    fprintf (file, " ABSOLUTE");
3695
                  if (symtab && symtab->symbols
3696
                      && isym < symtab->nsyms
3697
                      && symtab->symbols[isym].symbol.name)
3698
                    fprintf (file, " %s", symtab->symbols[isym].symbol.name);
3699
                  fprintf (file, "\n");
3700
                  addr += entry_size;
3701
                }
3702
              break;
3703
            default:
3704
              break;
3705
            }
3706
        }
3707
    }
3708
  if (dysymtab->nextrefsyms > 0)
3709
    {
3710
      bfd_mach_o_symtab_command *symtab = mdata->symtab;
3711
 
3712
      fprintf (file, "  external reference table: (symbol flags)\n");
3713
      for (i = 0; i < dysymtab->nextrefsyms; i++)
3714
        {
3715
          bfd_mach_o_dylib_reference *ref = &dysymtab->ext_refs[i];
3716
 
3717
          fprintf (file, "   %4u: %5lu 0x%02lx", i, ref->isym, ref->flags);
3718
          if (symtab && symtab->symbols
3719
              && ref->isym < symtab->nsyms
3720
              && symtab->symbols[ref->isym].symbol.name)
3721
            fprintf (file, " %s", symtab->symbols[ref->isym].symbol.name);
3722
          fprintf (file, "\n");
3723
        }
3724
    }
3725
 
3726
}
3727
 
3728
static void
3729
bfd_mach_o_print_dyld_info (bfd *abfd ATTRIBUTE_UNUSED,
3730
                            bfd_mach_o_load_command *cmd, FILE *file)
3731
{
3732
  bfd_mach_o_dyld_info_command *info = &cmd->command.dyld_info;
3733
 
3734
  fprintf (file, "       rebase: off: 0x%08x  size: %-8u\n",
3735
           info->rebase_off, info->rebase_size);
3736
  fprintf (file, "         bind: off: 0x%08x  size: %-8u\n",
3737
           info->bind_off, info->bind_size);
3738
  fprintf (file, "    weak bind: off: 0x%08x  size: %-8u\n",
3739
           info->weak_bind_off, info->weak_bind_size);
3740
  fprintf (file, "    lazy bind: off: 0x%08x  size: %-8u\n",
3741
           info->lazy_bind_off, info->lazy_bind_size);
3742
  fprintf (file, "       export: off: 0x%08x  size: %-8u\n",
3743
           info->export_off, info->export_size);
3744
}
3745
 
3746
bfd_boolean
3747
bfd_mach_o_bfd_print_private_bfd_data (bfd *abfd, void * ptr)
3748
{
3749
  bfd_mach_o_data_struct *mdata = bfd_mach_o_get_data (abfd);
3750
  FILE *file = (FILE *) ptr;
3751
  unsigned int i;
3752
 
3753
  bfd_mach_o_print_private_header (abfd, file);
3754
  fputc ('\n', file);
3755
 
3756
  for (i = 0; i < mdata->header.ncmds; i++)
3757
    {
3758
      bfd_mach_o_load_command *cmd = &mdata->commands[i];
3759
 
3760
      fprintf (file, "Load command %s:",
3761
               bfd_mach_o_get_name (bfd_mach_o_load_command_name, cmd->type));
3762
      switch (cmd->type)
3763
        {
3764
        case BFD_MACH_O_LC_SEGMENT:
3765
        case BFD_MACH_O_LC_SEGMENT_64:
3766
          bfd_mach_o_print_segment (abfd, cmd, file);
3767
          break;
3768
        case BFD_MACH_O_LC_UUID:
3769
          {
3770
            bfd_mach_o_uuid_command *uuid = &cmd->command.uuid;
3771
            unsigned int j;
3772
 
3773
            for (j = 0; j < sizeof (uuid->uuid); j ++)
3774
              fprintf (file, " %02x", uuid->uuid[j]);
3775
            fputc ('\n', file);
3776
          }
3777
          break;
3778
        case BFD_MACH_O_LC_LOAD_DYLIB:
3779
        case BFD_MACH_O_LC_LOAD_WEAK_DYLIB:
3780
        case BFD_MACH_O_LC_REEXPORT_DYLIB:
3781
        case BFD_MACH_O_LC_ID_DYLIB:
3782
          {
3783
            bfd_mach_o_dylib_command *dylib = &cmd->command.dylib;
3784
            fprintf (file, " %s\n", dylib->name_str);
3785
            fprintf (file, "            time stamp: 0x%08lx\n",
3786
                     dylib->timestamp);
3787
            fprintf (file, "       current version: 0x%08lx\n",
3788
                     dylib->current_version);
3789
            fprintf (file, "  comptibility version: 0x%08lx\n",
3790
                     dylib->compatibility_version);
3791
            break;
3792
          }
3793
        case BFD_MACH_O_LC_LOAD_DYLINKER:
3794
        case BFD_MACH_O_LC_ID_DYLINKER:
3795
          fprintf (file, " %s\n", cmd->command.dylinker.name_str);
3796
          break;
3797
        case BFD_MACH_O_LC_SYMTAB:
3798
          {
3799
            bfd_mach_o_symtab_command *symtab = &cmd->command.symtab;
3800
            fprintf (file,
3801
                     "\n"
3802
                     "   symoff: 0x%08x    nsyms: %8u  (endoff: 0x%08x)\n",
3803
                     symtab->symoff, symtab->nsyms,
3804
                     symtab->symoff + symtab->nsyms
3805
                     * (mach_o_wide_p (&mdata->header)
3806
                        ? BFD_MACH_O_NLIST_64_SIZE : BFD_MACH_O_NLIST_SIZE));
3807
            fprintf (file,
3808
                     "   stroff: 0x%08x  strsize: %8u  (endoff: 0x%08x)\n",
3809
                     symtab->stroff, symtab->strsize,
3810
                     symtab->stroff + symtab->strsize);
3811
            break;
3812
          }
3813
        case BFD_MACH_O_LC_DYSYMTAB:
3814
          fprintf (file, "\n");
3815
          bfd_mach_o_print_dysymtab (abfd, cmd, file);
3816
          break;
3817
        case BFD_MACH_O_LC_CODE_SIGNATURE:
3818
        case BFD_MACH_O_LC_SEGMENT_SPLIT_INFO:
3819
          {
3820
            bfd_mach_o_linkedit_command *linkedit = &cmd->command.linkedit;
3821
            fprintf
3822
              (file, "\n"
3823
               "  dataoff: 0x%08lx  datasize: 0x%08lx  (endoff: 0x%08lx)\n",
3824
               linkedit->dataoff, linkedit->datasize,
3825
               linkedit->dataoff + linkedit->datasize);
3826
            break;
3827
          }
3828
        case BFD_MACH_O_LC_SUB_FRAMEWORK:
3829
        case BFD_MACH_O_LC_SUB_UMBRELLA:
3830
        case BFD_MACH_O_LC_SUB_LIBRARY:
3831
        case BFD_MACH_O_LC_SUB_CLIENT:
3832
        case BFD_MACH_O_LC_RPATH:
3833
          {
3834
            bfd_mach_o_str_command *str = &cmd->command.str;
3835
            fprintf (file, " %s\n", str->str);
3836
            break;
3837
          }
3838
        case BFD_MACH_O_LC_THREAD:
3839
        case BFD_MACH_O_LC_UNIXTHREAD:
3840
          {
3841
            bfd_mach_o_thread_command *thread = &cmd->command.thread;
3842
            unsigned int j;
3843
            bfd_mach_o_backend_data *bed = bfd_mach_o_get_backend_data (abfd);
3844
 
3845
            fprintf (file, " nflavours: %lu\n", thread->nflavours);
3846
            for (j = 0; j < thread->nflavours; j++)
3847
              {
3848
                bfd_mach_o_thread_flavour *flavour = &thread->flavours[j];
3849
 
3850
                fprintf (file, "  %2u: flavour: 0x%08lx  offset: 0x%08lx"
3851
                         "  size: 0x%08lx\n",
3852
                         j, flavour->flavour, flavour->offset,
3853
                         flavour->size);
3854
                if (bed->_bfd_mach_o_print_thread)
3855
                  {
3856
                    char *buf = bfd_malloc (flavour->size);
3857
 
3858
                    if (buf
3859
                        && bfd_seek (abfd, flavour->offset, SEEK_SET) == 0
3860
                        && (bfd_bread (buf, flavour->size, abfd)
3861
                            == flavour->size))
3862
                      (*bed->_bfd_mach_o_print_thread)(abfd, flavour,
3863
                                                       file, buf);
3864
                    free (buf);
3865
                  }
3866
              }
3867
            break;
3868
          }
3869
        case BFD_MACH_O_LC_DYLD_INFO:
3870
          fprintf (file, "\n");
3871
          bfd_mach_o_print_dyld_info (abfd, cmd, file);
3872
          break;
3873
        default:
3874
          fprintf (file, "\n");
3875
          break;
3876
        }
3877
      fputc ('\n', file);
3878
    }
3879
 
3880
  bfd_mach_o_print_section_map (abfd, file);
3881
 
3882
  return TRUE;
3883
}
3884
 
3885
int
3886
bfd_mach_o_core_fetch_environment (bfd *abfd,
3887
                                   unsigned char **rbuf,
3888
                                   unsigned int *rlen)
3889
{
3890
  bfd_mach_o_data_struct *mdata = bfd_mach_o_get_data (abfd);
3891
  unsigned long stackaddr = bfd_mach_o_stack_addr (mdata->header.cputype);
3892
  unsigned int i = 0;
3893
 
3894
  for (i = 0; i < mdata->header.ncmds; i++)
3895
    {
3896
      bfd_mach_o_load_command *cur = &mdata->commands[i];
3897
      bfd_mach_o_segment_command *seg = NULL;
3898
 
3899
      if (cur->type != BFD_MACH_O_LC_SEGMENT)
3900
        continue;
3901
 
3902
      seg = &cur->command.segment;
3903
 
3904
      if ((seg->vmaddr + seg->vmsize) == stackaddr)
3905
        {
3906
          unsigned long start = seg->fileoff;
3907
          unsigned long end = seg->fileoff + seg->filesize;
3908
          unsigned char *buf = bfd_malloc (1024);
3909
          unsigned long size = 1024;
3910
 
3911
          for (;;)
3912
            {
3913
              bfd_size_type nread = 0;
3914
              unsigned long offset;
3915
              int found_nonnull = 0;
3916
 
3917
              if (size > (end - start))
3918
                size = (end - start);
3919
 
3920
              buf = bfd_realloc_or_free (buf, size);
3921
              if (buf == NULL)
3922
                return -1;
3923
 
3924
              if (bfd_seek (abfd, end - size, SEEK_SET) != 0)
3925
                {
3926
                  free (buf);
3927
                  return -1;
3928
                }
3929
 
3930
              nread = bfd_bread (buf, size, abfd);
3931
 
3932
              if (nread != size)
3933
                {
3934
                  free (buf);
3935
                  return -1;
3936
                }
3937
 
3938
              for (offset = 4; offset <= size; offset += 4)
3939
                {
3940
                  unsigned long val;
3941
 
3942
                  val = *((unsigned long *) (buf + size - offset));
3943
                  if (! found_nonnull)
3944
                    {
3945
                      if (val != 0)
3946
                        found_nonnull = 1;
3947
                    }
3948
                  else if (val == 0x0)
3949
                    {
3950
                      unsigned long bottom;
3951
                      unsigned long top;
3952
 
3953
                      bottom = seg->fileoff + seg->filesize - offset;
3954
                      top = seg->fileoff + seg->filesize - 4;
3955
                      *rbuf = bfd_malloc (top - bottom);
3956
                      *rlen = top - bottom;
3957
 
3958
                      memcpy (*rbuf, buf + size - *rlen, *rlen);
3959
                      free (buf);
3960
                      return 0;
3961
                    }
3962
                }
3963
 
3964
              if (size == (end - start))
3965
                break;
3966
 
3967
              size *= 2;
3968
            }
3969
 
3970
          free (buf);
3971
        }
3972
    }
3973
 
3974
  return -1;
3975
}
3976
 
3977
char *
3978
bfd_mach_o_core_file_failing_command (bfd *abfd)
3979
{
3980
  unsigned char *buf = NULL;
3981
  unsigned int len = 0;
3982
  int ret = -1;
3983
 
3984
  ret = bfd_mach_o_core_fetch_environment (abfd, &buf, &len);
3985
  if (ret < 0)
3986
    return NULL;
3987
 
3988
  return (char *) buf;
3989
}
3990
 
3991
int
3992
bfd_mach_o_core_file_failing_signal (bfd *abfd ATTRIBUTE_UNUSED)
3993
{
3994
  return 0;
3995
}
3996
 
3997
#define bfd_mach_o_bfd_reloc_type_lookup _bfd_norelocs_bfd_reloc_type_lookup 
3998
#define bfd_mach_o_bfd_reloc_name_lookup _bfd_norelocs_bfd_reloc_name_lookup
3999
 
4000
#define bfd_mach_o_swap_reloc_in NULL
4001
#define bfd_mach_o_swap_reloc_out NULL
4002
#define bfd_mach_o_print_thread NULL
4003
 
4004
#define TARGET_NAME             mach_o_be_vec
4005
#define TARGET_STRING           "mach-o-be"
4006
#define TARGET_ARCHITECTURE     bfd_arch_unknown
4007
#define TARGET_BIG_ENDIAN       1
4008
#define TARGET_ARCHIVE          0
4009
#include "mach-o-target.c"
4010
 
4011
#undef TARGET_NAME
4012
#undef TARGET_STRING
4013
#undef TARGET_ARCHITECTURE
4014
#undef TARGET_BIG_ENDIAN
4015
#undef TARGET_ARCHIVE
4016
 
4017
#define TARGET_NAME             mach_o_le_vec
4018
#define TARGET_STRING           "mach-o-le"
4019
#define TARGET_ARCHITECTURE     bfd_arch_unknown
4020
#define TARGET_BIG_ENDIAN       0
4021
#define TARGET_ARCHIVE          0
4022
 
4023
#include "mach-o-target.c"
4024
 
4025
#undef TARGET_NAME
4026
#undef TARGET_STRING
4027
#undef TARGET_ARCHITECTURE
4028
#undef TARGET_BIG_ENDIAN
4029
#undef TARGET_ARCHIVE
4030
 
4031
/* Not yet handled: creating an archive.  */
4032
#define bfd_mach_o_mkarchive                      _bfd_noarchive_mkarchive
4033
 
4034
/* Not used.  */
4035
#define bfd_mach_o_read_ar_hdr                    _bfd_noarchive_read_ar_hdr
4036
#define bfd_mach_o_write_ar_hdr                   _bfd_noarchive_write_ar_hdr
4037
#define bfd_mach_o_slurp_armap                    _bfd_noarchive_slurp_armap
4038
#define bfd_mach_o_slurp_extended_name_table      _bfd_noarchive_slurp_extended_name_table
4039
#define bfd_mach_o_construct_extended_name_table  _bfd_noarchive_construct_extended_name_table
4040
#define bfd_mach_o_truncate_arname                _bfd_noarchive_truncate_arname
4041
#define bfd_mach_o_write_armap                    _bfd_noarchive_write_armap
4042
#define bfd_mach_o_get_elt_at_index               _bfd_noarchive_get_elt_at_index
4043
#define bfd_mach_o_generic_stat_arch_elt          _bfd_noarchive_generic_stat_arch_elt
4044
#define bfd_mach_o_update_armap_timestamp         _bfd_noarchive_update_armap_timestamp
4045
 
4046
#define TARGET_NAME             mach_o_fat_vec
4047
#define TARGET_STRING           "mach-o-fat"
4048
#define TARGET_ARCHITECTURE     bfd_arch_unknown
4049
#define TARGET_BIG_ENDIAN       1
4050
#define TARGET_ARCHIVE          1
4051
 
4052
#include "mach-o-target.c"
4053
 
4054
#undef TARGET_NAME
4055
#undef TARGET_STRING
4056
#undef TARGET_ARCHITECTURE
4057
#undef TARGET_BIG_ENDIAN
4058
#undef TARGET_ARCHIVE

powered by: WebSVN 2.1.0

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