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

Subversion Repositories openrisc_me

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

Details | Compare with Previous | View Log

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

powered by: WebSVN 2.1.0

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