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

Subversion Repositories open8_urisc

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

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

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

powered by: WebSVN 2.1.0

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