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 161

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

powered by: WebSVN 2.1.0

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