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

Subversion Repositories openrisc_me

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

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

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

powered by: WebSVN 2.1.0

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