1/* elf.c -- Get debug data from a Mach-O file for backtraces.
2   Copyright (C) 2020-2022 Free Software Foundation, Inc.
3   Written by Ian Lance Taylor, Google.
4
5Redistribution and use in source and binary forms, with or without
6modification, are permitted provided that the following conditions are
7met:
8
9    (1) Redistributions of source code must retain the above copyright
10    notice, this list of conditions and the following disclaimer.
11
12    (2) Redistributions in binary form must reproduce the above copyright
13    notice, this list of conditions and the following disclaimer in
14    the documentation and/or other materials provided with the
15    distribution.
16
17    (3) The name of the author may not be used to
18    endorse or promote products derived from this software without
19    specific prior written permission.
20
21THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
22IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
23WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
24DISCLAIMED. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT,
25INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
26(INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
27SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
28HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT,
29STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING
30IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
31POSSIBILITY OF SUCH DAMAGE.  */
32
33#include "config.h"
34
35#include <sys/types.h>
36#include <dirent.h>
37#include <stdlib.h>
38#include <string.h>
39
40#ifdef HAVE_MACH_O_DYLD_H
41#include <mach-o/dyld.h>
42#endif
43
44#include "backtrace.h"
45#include "internal.h"
46
47/* Mach-O file header for a 32-bit executable.  */
48
49struct macho_header_32
50{
51  uint32_t magic;	/* Magic number (MACH_O_MAGIC_32) */
52  uint32_t cputype;	/* CPU type */
53  uint32_t cpusubtype;	/* CPU subtype */
54  uint32_t filetype;	/* Type of file (object, executable) */
55  uint32_t ncmds;	/* Number of load commands */
56  uint32_t sizeofcmds;	/* Total size of load commands */
57  uint32_t flags;	/* Flags for special features */
58};
59
60/* Mach-O file header for a 64-bit executable.  */
61
62struct macho_header_64
63{
64  uint32_t magic;	/* Magic number (MACH_O_MAGIC_64) */
65  uint32_t cputype;	/* CPU type */
66  uint32_t cpusubtype;	/* CPU subtype */
67  uint32_t filetype;	/* Type of file (object, executable) */
68  uint32_t ncmds;	/* Number of load commands */
69  uint32_t sizeofcmds;	/* Total size of load commands */
70  uint32_t flags;	/* Flags for special features */
71  uint32_t reserved;	/* Reserved */
72};
73
74/* Mach-O file header for a fat executable.  */
75
76struct macho_header_fat
77{
78  uint32_t magic;	/* Magic number (MACH_O_MH_(MAGIC|CIGAM)_FAT(_64)?) */
79  uint32_t nfat_arch;   /* Number of components */
80};
81
82/* Values for the header magic field.  */
83
84#define MACH_O_MH_MAGIC_32	0xfeedface
85#define MACH_O_MH_MAGIC_64	0xfeedfacf
86#define MACH_O_MH_MAGIC_FAT	0xcafebabe
87#define MACH_O_MH_CIGAM_FAT	0xbebafeca
88#define MACH_O_MH_MAGIC_FAT_64	0xcafebabf
89#define MACH_O_MH_CIGAM_FAT_64	0xbfbafeca
90
91/* Value for the header filetype field.  */
92
93#define MACH_O_MH_EXECUTE	0x02
94#define MACH_O_MH_DYLIB		0x06
95#define MACH_O_MH_DSYM		0x0a
96
97/* A component of a fat file.  A fat file starts with a
98   macho_header_fat followed by nfat_arch instances of this
99   struct.  */
100
101struct macho_fat_arch
102{
103  uint32_t cputype;	/* CPU type */
104  uint32_t cpusubtype;	/* CPU subtype */
105  uint32_t offset;	/* File offset of this entry */
106  uint32_t size;	/* Size of this entry */
107  uint32_t align;	/* Alignment of this entry */
108};
109
110/* A component of a 64-bit fat file.  This is used if the magic field
111   is MAGIC_FAT_64.  This is only used when some file size or file
112   offset is too large to represent in the 32-bit format.  */
113
114struct macho_fat_arch_64
115{
116  uint32_t cputype;	/* CPU type */
117  uint32_t cpusubtype;	/* CPU subtype */
118  uint64_t offset;	/* File offset of this entry */
119  uint64_t size;	/* Size of this entry */
120  uint32_t align;	/* Alignment of this entry */
121  uint32_t reserved;	/* Reserved */
122};
123
124/* Values for the fat_arch cputype field (and the header cputype
125   field).  */
126
127#define MACH_O_CPU_ARCH_ABI64 0x01000000
128
129#define MACH_O_CPU_TYPE_X86 7
130#define MACH_O_CPU_TYPE_ARM 12
131#define MACH_O_CPU_TYPE_PPC 18
132
133#define MACH_O_CPU_TYPE_X86_64 (MACH_O_CPU_TYPE_X86 | MACH_O_CPU_ARCH_ABI64)
134#define MACH_O_CPU_TYPE_ARM64  (MACH_O_CPU_TYPE_ARM | MACH_O_CPU_ARCH_ABI64)
135#define MACH_O_CPU_TYPE_PPC64  (MACH_O_CPU_TYPE_PPC | MACH_O_CPU_ARCH_ABI64)
136
137/* The header of a load command.  */
138
139struct macho_load_command
140{
141  uint32_t cmd;		/* The type of load command */
142  uint32_t cmdsize;	/* Size in bytes of the entire command */
143};
144
145/* Values for the load_command cmd field.  */
146
147#define MACH_O_LC_SEGMENT	0x01
148#define MACH_O_LC_SYMTAB	0x02
149#define MACH_O_LC_SEGMENT_64	0x19
150#define MACH_O_LC_UUID		0x1b
151
152/* The length of a section of segment name.  */
153
154#define MACH_O_NAMELEN (16)
155
156/* LC_SEGMENT load command.  */
157
158struct macho_segment_command
159{
160  uint32_t cmd;			/* The type of load command (LC_SEGMENT) */
161  uint32_t cmdsize;		/* Size in bytes of the entire command */
162  char segname[MACH_O_NAMELEN];	/* Segment name */
163  uint32_t vmaddr;		/* Virtual memory address */
164  uint32_t vmsize;		/* Virtual memory size */
165  uint32_t fileoff;		/* Offset of data to be mapped */
166  uint32_t filesize;		/* Size of data in file */
167  uint32_t maxprot;		/* Maximum permitted virtual protection */
168  uint32_t initprot;		/* Initial virtual memory protection */
169  uint32_t nsects;		/* Number of sections in this segment */
170  uint32_t flags;		/* Flags */
171};
172
173/* LC_SEGMENT_64 load command.  */
174
175struct macho_segment_64_command
176{
177  uint32_t cmd;			/* The type of load command (LC_SEGMENT) */
178  uint32_t cmdsize;		/* Size in bytes of the entire command */
179  char segname[MACH_O_NAMELEN];	/* Segment name */
180  uint64_t vmaddr;		/* Virtual memory address */
181  uint64_t vmsize;		/* Virtual memory size */
182  uint64_t fileoff;		/* Offset of data to be mapped */
183  uint64_t filesize;		/* Size of data in file */
184  uint32_t maxprot;		/* Maximum permitted virtual protection */
185  uint32_t initprot;		/* Initial virtual memory protection */
186  uint32_t nsects;		/* Number of sections in this segment */
187  uint32_t flags;		/* Flags */
188};
189
190/* LC_SYMTAB load command.  */
191
192struct macho_symtab_command
193{
194  uint32_t cmd;		/* The type of load command (LC_SEGMENT) */
195  uint32_t cmdsize;	/* Size in bytes of the entire command */
196  uint32_t symoff;	/* File offset of symbol table */
197  uint32_t nsyms;	/* Number of symbols */
198  uint32_t stroff;	/* File offset of string table */
199  uint32_t strsize;	/* String table size */
200};
201
202/* The length of a Mach-O uuid.  */
203
204#define MACH_O_UUID_LEN (16)
205
206/* LC_UUID load command.  */
207
208struct macho_uuid_command
209{
210  uint32_t cmd;				/* Type of load command (LC_UUID) */
211  uint32_t cmdsize;			/* Size in bytes of command */
212  unsigned char uuid[MACH_O_UUID_LEN];	/* UUID */
213};
214
215/* 32-bit section header within a LC_SEGMENT segment.  */
216
217struct macho_section
218{
219  char sectname[MACH_O_NAMELEN];	/* Section name */
220  char segment[MACH_O_NAMELEN];		/* Segment of this section */
221  uint32_t addr;			/* Address in memory */
222  uint32_t size;			/* Section size */
223  uint32_t offset;			/* File offset */
224  uint32_t align;			/* Log2 of section alignment */
225  uint32_t reloff;			/* File offset of relocations */
226  uint32_t nreloc;			/* Number of relocs for this section */
227  uint32_t flags;			/* Flags */
228  uint32_t reserved1;
229  uint32_t reserved2;
230};
231
232/* 64-bit section header within a LC_SEGMENT_64 segment.   */
233
234struct macho_section_64
235{
236  char sectname[MACH_O_NAMELEN];	/* Section name */
237  char segment[MACH_O_NAMELEN];		/* Segment of this section */
238  uint64_t addr;			/* Address in memory */
239  uint64_t size;			/* Section size */
240  uint32_t offset;			/* File offset */
241  uint32_t align;			/* Log2 of section alignment */
242  uint32_t reloff;			/* File offset of section relocations */
243  uint32_t nreloc;			/* Number of relocs for this section */
244  uint32_t flags;			/* Flags */
245  uint32_t reserved1;
246  uint32_t reserved2;
247  uint32_t reserved3;
248};
249
250/* 32-bit symbol data.  */
251
252struct macho_nlist
253{
254  uint32_t n_strx;	/* Index of name in string table */
255  uint8_t n_type;	/* Type flag */
256  uint8_t n_sect;	/* Section number */
257  uint16_t n_desc;	/* Stabs description field */
258  uint32_t n_value;	/* Value */
259};
260
261/* 64-bit symbol data.  */
262
263struct macho_nlist_64
264{
265  uint32_t n_strx;	/* Index of name in string table */
266  uint8_t n_type;	/* Type flag */
267  uint8_t n_sect;	/* Section number */
268  uint16_t n_desc;	/* Stabs description field */
269  uint64_t n_value;	/* Value */
270};
271
272/* Value found in nlist n_type field.  */
273
274#define MACH_O_N_EXT	0x01	/* Extern symbol */
275#define MACH_O_N_ABS	0x02	/* Absolute symbol */
276#define MACH_O_N_SECT	0x0e	/* Defined in section */
277
278#define MACH_O_N_TYPE	0x0e	/* Mask for type bits */
279#define MACH_O_N_STAB	0xe0	/* Stabs debugging symbol */
280
281/* Information we keep for a Mach-O symbol.  */
282
283struct macho_symbol
284{
285  const char *name;	/* Symbol name */
286  uintptr_t address;	/* Symbol address */
287};
288
289/* Information to pass to macho_syminfo.  */
290
291struct macho_syminfo_data
292{
293  struct macho_syminfo_data *next;	/* Next module */
294  struct macho_symbol *symbols;		/* Symbols sorted by address */
295  size_t count;				/* Number of symbols */
296};
297
298/* Names of sections, indexed by enum dwarf_section in internal.h.  */
299
300static const char * const dwarf_section_names[DEBUG_MAX] =
301{
302  "__debug_info",
303  "__debug_line",
304  "__debug_abbrev",
305  "__debug_ranges",
306  "__debug_str",
307  "", /* DEBUG_ADDR */
308  "__debug_str_offs",
309  "", /* DEBUG_LINE_STR */
310  "__debug_rnglists"
311};
312
313/* Forward declaration.  */
314
315static int macho_add (struct backtrace_state *, const char *, int, off_t,
316		      const unsigned char *, uintptr_t, int,
317		      backtrace_error_callback, void *, fileline *, int *);
318
319/* A dummy callback function used when we can't find any debug info.  */
320
321static int
322macho_nodebug (struct backtrace_state *state ATTRIBUTE_UNUSED,
323	       uintptr_t pc ATTRIBUTE_UNUSED,
324	       backtrace_full_callback callback ATTRIBUTE_UNUSED,
325	       backtrace_error_callback error_callback, void *data)
326{
327  error_callback (data, "no debug info in Mach-O executable", -1);
328  return 0;
329}
330
331/* A dummy callback function used when we can't find a symbol
332   table.  */
333
334static void
335macho_nosyms (struct backtrace_state *state ATTRIBUTE_UNUSED,
336	      uintptr_t addr ATTRIBUTE_UNUSED,
337	      backtrace_syminfo_callback callback ATTRIBUTE_UNUSED,
338	      backtrace_error_callback error_callback, void *data)
339{
340  error_callback (data, "no symbol table in Mach-O executable", -1);
341}
342
343/* Add a single DWARF section to DWARF_SECTIONS, if we need the
344   section.  Returns 1 on success, 0 on failure.  */
345
346static int
347macho_add_dwarf_section (struct backtrace_state *state, int descriptor,
348			 const char *sectname, uint32_t offset, uint64_t size,
349			 backtrace_error_callback error_callback, void *data,
350			 struct dwarf_sections *dwarf_sections)
351{
352  int i;
353
354  for (i = 0; i < (int) DEBUG_MAX; ++i)
355    {
356      if (dwarf_section_names[i][0] != '\0'
357	  && strncmp (sectname, dwarf_section_names[i], MACH_O_NAMELEN) == 0)
358	{
359	  struct backtrace_view section_view;
360
361	  /* FIXME: Perhaps it would be better to try to use a single
362	     view to read all the DWARF data, as we try to do for
363	     ELF.  */
364
365	  if (!backtrace_get_view (state, descriptor, offset, size,
366				   error_callback, data, &section_view))
367	    return 0;
368	  dwarf_sections->data[i] = (const unsigned char *) section_view.data;
369	  dwarf_sections->size[i] = size;
370	  break;
371	}
372    }
373  return 1;
374}
375
376/* Collect DWARF sections from a DWARF segment.  Returns 1 on success,
377   0 on failure.  */
378
379static int
380macho_add_dwarf_segment (struct backtrace_state *state, int descriptor,
381			 off_t offset, unsigned int cmd, const char *psecs,
382			 size_t sizesecs, unsigned int nsects,
383			 backtrace_error_callback error_callback, void *data,
384			 struct dwarf_sections *dwarf_sections)
385{
386  size_t sec_header_size;
387  size_t secoffset;
388  unsigned int i;
389
390  switch (cmd)
391    {
392    case MACH_O_LC_SEGMENT:
393      sec_header_size = sizeof (struct macho_section);
394      break;
395    case MACH_O_LC_SEGMENT_64:
396      sec_header_size = sizeof (struct macho_section_64);
397      break;
398    default:
399      abort ();
400    }
401
402  secoffset = 0;
403  for (i = 0; i < nsects; ++i)
404    {
405      if (secoffset + sec_header_size > sizesecs)
406	{
407	  error_callback (data, "section overflow withing segment", 0);
408	  return 0;
409	}
410
411      switch (cmd)
412	{
413	case MACH_O_LC_SEGMENT:
414	  {
415	    struct macho_section section;
416
417	    memcpy (&section, psecs + secoffset, sizeof section);
418	    macho_add_dwarf_section (state, descriptor, section.sectname,
419				     offset + section.offset, section.size,
420				     error_callback, data, dwarf_sections);
421	  }
422	  break;
423
424	case MACH_O_LC_SEGMENT_64:
425	  {
426	    struct macho_section_64 section;
427
428	    memcpy (&section, psecs + secoffset, sizeof section);
429	    macho_add_dwarf_section (state, descriptor, section.sectname,
430				     offset + section.offset, section.size,
431				     error_callback, data, dwarf_sections);
432	  }
433	  break;
434
435	default:
436	  abort ();
437	}
438
439      secoffset += sec_header_size;
440    }
441
442  return 1;
443}
444
445/* Compare struct macho_symbol for qsort.  */
446
447static int
448macho_symbol_compare (const void *v1, const void *v2)
449{
450  const struct macho_symbol *m1 = (const struct macho_symbol *) v1;
451  const struct macho_symbol *m2 = (const struct macho_symbol *) v2;
452
453  if (m1->address < m2->address)
454    return -1;
455  else if (m1->address > m2->address)
456    return 1;
457  else
458    return 0;
459}
460
461/* Compare an address against a macho_symbol for bsearch.  We allocate
462   one extra entry in the array so that this can safely look at the
463   next entry.  */
464
465static int
466macho_symbol_search (const void *vkey, const void *ventry)
467{
468  const uintptr_t *key = (const uintptr_t *) vkey;
469  const struct macho_symbol *entry = (const struct macho_symbol *) ventry;
470  uintptr_t addr;
471
472  addr = *key;
473  if (addr < entry->address)
474    return -1;
475  else if (entry->name[0] == '\0'
476	   && entry->address == ~(uintptr_t) 0)
477    return -1;
478  else if ((entry + 1)->name[0] == '\0'
479	   && (entry + 1)->address == ~(uintptr_t) 0)
480    return -1;
481  else if (addr >= (entry + 1)->address)
482    return 1;
483  else
484    return 0;
485}
486
487/* Return whether the symbol type field indicates a symbol table entry
488   that we care about: a function or data symbol.  */
489
490static int
491macho_defined_symbol (uint8_t type)
492{
493  if ((type & MACH_O_N_STAB) != 0)
494    return 0;
495  if ((type & MACH_O_N_EXT) != 0)
496    return 0;
497  switch (type & MACH_O_N_TYPE)
498    {
499    case MACH_O_N_ABS:
500      return 1;
501    case MACH_O_N_SECT:
502      return 1;
503    default:
504      return 0;
505    }
506}
507
508/* Add symbol table information for a Mach-O file.  */
509
510static int
511macho_add_symtab (struct backtrace_state *state, int descriptor,
512		  uintptr_t base_address, int is_64,
513		  off_t symoff, unsigned int nsyms, off_t stroff,
514		  unsigned int strsize,
515		  backtrace_error_callback error_callback, void *data)
516{
517  size_t symsize;
518  struct backtrace_view sym_view;
519  int sym_view_valid;
520  struct backtrace_view str_view;
521  int str_view_valid;
522  size_t ndefs;
523  size_t symtaboff;
524  unsigned int i;
525  size_t macho_symbol_size;
526  struct macho_symbol *macho_symbols;
527  unsigned int j;
528  struct macho_syminfo_data *sdata;
529
530  sym_view_valid = 0;
531  str_view_valid = 0;
532  macho_symbol_size = 0;
533  macho_symbols = NULL;
534
535  if (is_64)
536    symsize = sizeof (struct macho_nlist_64);
537  else
538    symsize = sizeof (struct macho_nlist);
539
540  if (!backtrace_get_view (state, descriptor, symoff, nsyms * symsize,
541			   error_callback, data, &sym_view))
542    goto fail;
543  sym_view_valid = 1;
544
545  if (!backtrace_get_view (state, descriptor, stroff, strsize,
546			   error_callback, data, &str_view))
547    return 0;
548  str_view_valid = 1;
549
550  ndefs = 0;
551  symtaboff = 0;
552  for (i = 0; i < nsyms; ++i, symtaboff += symsize)
553    {
554      if (is_64)
555	{
556	  struct macho_nlist_64 nlist;
557
558	  memcpy (&nlist, (const char *) sym_view.data + symtaboff,
559		  sizeof nlist);
560	  if (macho_defined_symbol (nlist.n_type))
561	    ++ndefs;
562	}
563      else
564	{
565	  struct macho_nlist nlist;
566
567	  memcpy (&nlist, (const char *) sym_view.data + symtaboff,
568		  sizeof nlist);
569	  if (macho_defined_symbol (nlist.n_type))
570	    ++ndefs;
571	}
572    }
573
574  /* Add 1 to ndefs to make room for a sentinel.  */
575  macho_symbol_size = (ndefs + 1) * sizeof (struct macho_symbol);
576  macho_symbols = ((struct macho_symbol *)
577		   backtrace_alloc (state, macho_symbol_size, error_callback,
578				    data));
579  if (macho_symbols == NULL)
580    goto fail;
581
582  j = 0;
583  symtaboff = 0;
584  for (i = 0; i < nsyms; ++i, symtaboff += symsize)
585    {
586      uint32_t strx;
587      uint64_t value;
588      const char *name;
589
590      strx = 0;
591      value = 0;
592      if (is_64)
593	{
594	  struct macho_nlist_64 nlist;
595
596	  memcpy (&nlist, (const char *) sym_view.data + symtaboff,
597		  sizeof nlist);
598	  if (!macho_defined_symbol (nlist.n_type))
599	    continue;
600
601	  strx = nlist.n_strx;
602	  value = nlist.n_value;
603	}
604      else
605	{
606	  struct macho_nlist nlist;
607
608	  memcpy (&nlist, (const char *) sym_view.data + symtaboff,
609		  sizeof nlist);
610	  if (!macho_defined_symbol (nlist.n_type))
611	    continue;
612
613	  strx = nlist.n_strx;
614	  value = nlist.n_value;
615	}
616
617      if (strx >= strsize)
618	{
619	  error_callback (data, "symbol string index out of range", 0);
620	  goto fail;
621	}
622
623      name = (const char *) str_view.data + strx;
624      if (name[0] == '_')
625	++name;
626      macho_symbols[j].name = name;
627      macho_symbols[j].address = value + base_address;
628      ++j;
629    }
630
631  sdata = ((struct macho_syminfo_data *)
632	   backtrace_alloc (state, sizeof *sdata, error_callback, data));
633  if (sdata == NULL)
634    goto fail;
635
636  /* We need to keep the string table since it holds the names, but we
637     can release the symbol table.  */
638
639  backtrace_release_view (state, &sym_view, error_callback, data);
640  sym_view_valid = 0;
641  str_view_valid = 0;
642
643  /* Add a trailing sentinel symbol.  */
644  macho_symbols[j].name = "";
645  macho_symbols[j].address = ~(uintptr_t) 0;
646
647  backtrace_qsort (macho_symbols, ndefs + 1, sizeof (struct macho_symbol),
648		   macho_symbol_compare);
649
650  sdata->next = NULL;
651  sdata->symbols = macho_symbols;
652  sdata->count = ndefs;
653
654  if (!state->threaded)
655    {
656      struct macho_syminfo_data **pp;
657
658      for (pp = (struct macho_syminfo_data **) (void *) &state->syminfo_data;
659	   *pp != NULL;
660	   pp = &(*pp)->next)
661	;
662      *pp = sdata;
663    }
664  else
665    {
666      while (1)
667	{
668	  struct macho_syminfo_data **pp;
669
670	  pp = (struct macho_syminfo_data **) (void *) &state->syminfo_data;
671
672	  while (1)
673	    {
674	      struct macho_syminfo_data *p;
675
676	      p = backtrace_atomic_load_pointer (pp);
677
678	      if (p == NULL)
679		break;
680
681	      pp = &p->next;
682	    }
683
684	  if (__sync_bool_compare_and_swap (pp, NULL, sdata))
685	    break;
686	}
687    }
688
689  return 1;
690
691 fail:
692  if (macho_symbols != NULL)
693    backtrace_free (state, macho_symbols, macho_symbol_size,
694		    error_callback, data);
695  if (sym_view_valid)
696    backtrace_release_view (state, &sym_view, error_callback, data);
697  if (str_view_valid)
698    backtrace_release_view (state, &str_view, error_callback, data);
699  return 0;
700}
701
702/* Return the symbol name and value for an ADDR.  */
703
704static void
705macho_syminfo (struct backtrace_state *state, uintptr_t addr,
706	       backtrace_syminfo_callback callback,
707	       backtrace_error_callback error_callback ATTRIBUTE_UNUSED,
708	       void *data)
709{
710  struct macho_syminfo_data *sdata;
711  struct macho_symbol *sym;
712
713  sym = NULL;
714  if (!state->threaded)
715    {
716      for (sdata = (struct macho_syminfo_data *) state->syminfo_data;
717	   sdata != NULL;
718	   sdata = sdata->next)
719	{
720	  sym = ((struct macho_symbol *)
721		 bsearch (&addr, sdata->symbols, sdata->count,
722			  sizeof (struct macho_symbol), macho_symbol_search));
723	  if (sym != NULL)
724	    break;
725	}
726    }
727  else
728    {
729      struct macho_syminfo_data **pp;
730
731      pp = (struct macho_syminfo_data **) (void *) &state->syminfo_data;
732      while (1)
733	{
734	  sdata = backtrace_atomic_load_pointer (pp);
735	  if (sdata == NULL)
736	    break;
737
738	  sym = ((struct macho_symbol *)
739		 bsearch (&addr, sdata->symbols, sdata->count,
740			  sizeof (struct macho_symbol), macho_symbol_search));
741	  if (sym != NULL)
742	    break;
743
744	  pp = &sdata->next;
745	}
746    }
747
748  if (sym == NULL)
749    callback (data, addr, NULL, 0, 0);
750  else
751    callback (data, addr, sym->name, sym->address, 0);
752}
753
754/* Look through a fat file to find the relevant executable.  Returns 1
755   on success, 0 on failure (in both cases descriptor is closed).  */
756
757static int
758macho_add_fat (struct backtrace_state *state, const char *filename,
759	       int descriptor, int swapped, off_t offset,
760	       const unsigned char *match_uuid, uintptr_t base_address,
761	       int skip_symtab, uint32_t nfat_arch, int is_64,
762	       backtrace_error_callback error_callback, void *data,
763	       fileline *fileline_fn, int *found_sym)
764{
765  int arch_view_valid;
766  unsigned int cputype;
767  size_t arch_size;
768  struct backtrace_view arch_view;
769  unsigned int i;
770
771  arch_view_valid = 0;
772
773#if defined (__x86_64__)
774  cputype = MACH_O_CPU_TYPE_X86_64;
775#elif defined (__i386__)
776  cputype = MACH_O_CPU_TYPE_X86;
777#elif defined (__aarch64__)
778  cputype = MACH_O_CPU_TYPE_ARM64;
779#elif defined (__arm__)
780  cputype = MACH_O_CPU_TYPE_ARM;
781#elif defined (__ppc__)
782  cputype = MACH_O_CPU_TYPE_PPC;
783#elif defined (__ppc64__)
784  cputype = MACH_O_CPU_TYPE_PPC64;
785#else
786  error_callback (data, "unknown Mach-O architecture", 0);
787  goto fail;
788#endif
789
790  if (is_64)
791    arch_size = sizeof (struct macho_fat_arch_64);
792  else
793    arch_size = sizeof (struct macho_fat_arch);
794
795  if (!backtrace_get_view (state, descriptor, offset,
796			   nfat_arch * arch_size,
797			   error_callback, data, &arch_view))
798    goto fail;
799
800  for (i = 0; i < nfat_arch; ++i)
801    {
802      uint32_t fcputype;
803      uint64_t foffset;
804
805      if (is_64)
806	{
807	  struct macho_fat_arch_64 fat_arch_64;
808
809	  memcpy (&fat_arch_64,
810		  (const char *) arch_view.data + i * arch_size,
811		  arch_size);
812	  fcputype = fat_arch_64.cputype;
813	  foffset = fat_arch_64.offset;
814	  if (swapped)
815	    {
816	      fcputype = __builtin_bswap32 (fcputype);
817	      foffset = __builtin_bswap64 (foffset);
818	    }
819	}
820      else
821	{
822	  struct macho_fat_arch fat_arch_32;
823
824	  memcpy (&fat_arch_32,
825		  (const char *) arch_view.data + i * arch_size,
826		  arch_size);
827	  fcputype = fat_arch_32.cputype;
828	  foffset = (uint64_t) fat_arch_32.offset;
829	  if (swapped)
830	    {
831	      fcputype = __builtin_bswap32 (fcputype);
832	      foffset = (uint64_t) __builtin_bswap32 ((uint32_t) foffset);
833	    }
834	}
835
836      if (fcputype == cputype)
837	{
838	  /* FIXME: What about cpusubtype?  */
839	  backtrace_release_view (state, &arch_view, error_callback, data);
840	  return macho_add (state, filename, descriptor, foffset, match_uuid,
841			    base_address, skip_symtab, error_callback, data,
842			    fileline_fn, found_sym);
843	}
844    }
845
846  error_callback (data, "could not find executable in fat file", 0);
847
848 fail:
849  if (arch_view_valid)
850    backtrace_release_view (state, &arch_view, error_callback, data);
851  if (descriptor != -1)
852    backtrace_close (descriptor, error_callback, data);
853  return 0;
854}
855
856/* Look for the dsym file for FILENAME.  This is called if FILENAME
857   does not have debug info or a symbol table.  Returns 1 on success,
858   0 on failure.  */
859
860static int
861macho_add_dsym (struct backtrace_state *state, const char *filename,
862		uintptr_t base_address, const unsigned char *uuid,
863		backtrace_error_callback error_callback, void *data,
864		fileline* fileline_fn)
865{
866  const char *p;
867  const char *dirname;
868  char *diralc;
869  size_t dirnamelen;
870  const char *basename;
871  size_t basenamelen;
872  const char *dsymsuffixdir;
873  size_t dsymsuffixdirlen;
874  size_t dsymlen;
875  char *dsym;
876  char *ps;
877  int d;
878  int does_not_exist;
879  int dummy_found_sym;
880
881  diralc = NULL;
882  dirnamelen = 0;
883  dsym = NULL;
884  dsymlen = 0;
885
886  p = strrchr (filename, '/');
887  if (p == NULL)
888    {
889      dirname = ".";
890      dirnamelen = 1;
891      basename = filename;
892      basenamelen = strlen (basename);
893      diralc = NULL;
894    }
895  else
896    {
897      dirnamelen = p - filename;
898      diralc = backtrace_alloc (state, dirnamelen + 1, error_callback, data);
899      if (diralc == NULL)
900	goto fail;
901      memcpy (diralc, filename, dirnamelen);
902      diralc[dirnamelen] = '\0';
903      dirname = diralc;
904      basename = p + 1;
905      basenamelen = strlen (basename);
906    }
907
908  dsymsuffixdir = ".dSYM/Contents/Resources/DWARF/";
909  dsymsuffixdirlen = strlen (dsymsuffixdir);
910
911  dsymlen = (dirnamelen
912	     + 1
913	     + basenamelen
914	     + dsymsuffixdirlen
915	     + basenamelen
916	     + 1);
917  dsym = backtrace_alloc (state, dsymlen, error_callback, data);
918  if (dsym == NULL)
919    goto fail;
920
921  ps = dsym;
922  memcpy (ps, dirname, dirnamelen);
923  ps += dirnamelen;
924  *ps++ = '/';
925  memcpy (ps, basename, basenamelen);
926  ps += basenamelen;
927  memcpy (ps, dsymsuffixdir, dsymsuffixdirlen);
928  ps += dsymsuffixdirlen;
929  memcpy (ps, basename, basenamelen);
930  ps += basenamelen;
931  *ps = '\0';
932
933  if (diralc != NULL)
934    {
935      backtrace_free (state, diralc, dirnamelen + 1, error_callback, data);
936      diralc = NULL;
937    }
938
939  d = backtrace_open (dsym, error_callback, data, &does_not_exist);
940  if (d < 0)
941    {
942      /* The file does not exist, so we can't read the debug info.
943	 Just return success.  */
944      backtrace_free (state, dsym, dsymlen, error_callback, data);
945      return 1;
946    }
947
948  if (!macho_add (state, dsym, d, 0, uuid, base_address, 1,
949		  error_callback, data, fileline_fn, &dummy_found_sym))
950    goto fail;
951
952  backtrace_free (state, dsym, dsymlen, error_callback, data);
953
954  return 1;
955
956 fail:
957  if (dsym != NULL)
958    backtrace_free (state, dsym, dsymlen, error_callback, data);
959  if (diralc != NULL)
960    backtrace_free (state, diralc, dirnamelen, error_callback, data);
961  return 0;
962}
963
964/* Add the backtrace data for a Macho-O file.  Returns 1 on success, 0
965   on failure (in both cases descriptor is closed).
966
967   FILENAME: the name of the executable.
968   DESCRIPTOR: an open descriptor for the executable, closed here.
969   OFFSET: the offset within the file of this executable, for fat files.
970   MATCH_UUID: if not NULL, UUID that must match.
971   BASE_ADDRESS: the load address of the executable.
972   SKIP_SYMTAB: if non-zero, ignore the symbol table; used for dSYM files.
973   FILELINE_FN: set to the fileline function, by backtrace_dwarf_add.
974   FOUND_SYM: set to non-zero if we found the symbol table.
975*/
976
977static int
978macho_add (struct backtrace_state *state, const char *filename, int descriptor,
979	   off_t offset, const unsigned char *match_uuid,
980	   uintptr_t base_address, int skip_symtab,
981	   backtrace_error_callback error_callback, void *data,
982	   fileline *fileline_fn, int *found_sym)
983{
984  struct backtrace_view header_view;
985  struct macho_header_32 header;
986  off_t hdroffset;
987  int is_64;
988  struct backtrace_view cmds_view;
989  int cmds_view_valid;
990  struct dwarf_sections dwarf_sections;
991  int have_dwarf;
992  unsigned char uuid[MACH_O_UUID_LEN];
993  int have_uuid;
994  size_t cmdoffset;
995  unsigned int i;
996
997  *found_sym = 0;
998
999  cmds_view_valid = 0;
1000
1001  /* The 32-bit and 64-bit file headers start out the same, so we can
1002     just always read the 32-bit version.  A fat header is shorter but
1003     it will always be followed by data, so it's OK to read extra.  */
1004
1005  if (!backtrace_get_view (state, descriptor, offset,
1006			   sizeof (struct macho_header_32),
1007			   error_callback, data, &header_view))
1008    goto fail;
1009
1010  memcpy (&header, header_view.data, sizeof header);
1011
1012  backtrace_release_view (state, &header_view, error_callback, data);
1013
1014  switch (header.magic)
1015    {
1016    case MACH_O_MH_MAGIC_32:
1017      is_64 = 0;
1018      hdroffset = offset + sizeof (struct macho_header_32);
1019      break;
1020    case MACH_O_MH_MAGIC_64:
1021      is_64 = 1;
1022      hdroffset = offset + sizeof (struct macho_header_64);
1023      break;
1024    case MACH_O_MH_MAGIC_FAT:
1025    case MACH_O_MH_MAGIC_FAT_64:
1026      {
1027	struct macho_header_fat fat_header;
1028
1029	hdroffset = offset + sizeof (struct macho_header_fat);
1030	memcpy (&fat_header, &header, sizeof fat_header);
1031	return macho_add_fat (state, filename, descriptor, 0, hdroffset,
1032			      match_uuid, base_address, skip_symtab,
1033			      fat_header.nfat_arch,
1034			      header.magic == MACH_O_MH_MAGIC_FAT_64,
1035			      error_callback, data, fileline_fn, found_sym);
1036      }
1037    case MACH_O_MH_CIGAM_FAT:
1038    case MACH_O_MH_CIGAM_FAT_64:
1039      {
1040	struct macho_header_fat fat_header;
1041	uint32_t nfat_arch;
1042
1043	hdroffset = offset + sizeof (struct macho_header_fat);
1044	memcpy (&fat_header, &header, sizeof fat_header);
1045	nfat_arch = __builtin_bswap32 (fat_header.nfat_arch);
1046	return macho_add_fat (state, filename, descriptor, 1, hdroffset,
1047			      match_uuid, base_address, skip_symtab,
1048			      nfat_arch,
1049			      header.magic == MACH_O_MH_CIGAM_FAT_64,
1050			      error_callback, data, fileline_fn, found_sym);
1051      }
1052    default:
1053      error_callback (data, "executable file is not in Mach-O format", 0);
1054      goto fail;
1055    }
1056
1057  switch (header.filetype)
1058    {
1059    case MACH_O_MH_EXECUTE:
1060    case MACH_O_MH_DYLIB:
1061    case MACH_O_MH_DSYM:
1062      break;
1063    default:
1064      error_callback (data, "executable file is not an executable", 0);
1065      goto fail;
1066    }
1067
1068  if (!backtrace_get_view (state, descriptor, hdroffset, header.sizeofcmds,
1069			   error_callback, data, &cmds_view))
1070    goto fail;
1071  cmds_view_valid = 1;
1072
1073  memset (&dwarf_sections, 0, sizeof dwarf_sections);
1074  have_dwarf = 0;
1075  memset (&uuid, 0, sizeof uuid);
1076  have_uuid = 0;
1077
1078  cmdoffset = 0;
1079  for (i = 0; i < header.ncmds; ++i)
1080    {
1081      const char *pcmd;
1082      struct macho_load_command load_command;
1083
1084      if (cmdoffset + sizeof load_command > header.sizeofcmds)
1085	break;
1086
1087      pcmd = (const char *) cmds_view.data + cmdoffset;
1088      memcpy (&load_command, pcmd, sizeof load_command);
1089
1090      switch (load_command.cmd)
1091	{
1092	case MACH_O_LC_SEGMENT:
1093	  {
1094	    struct macho_segment_command segcmd;
1095
1096	    memcpy (&segcmd, pcmd, sizeof segcmd);
1097	    if (memcmp (segcmd.segname,
1098			"__DWARF\0\0\0\0\0\0\0\0\0",
1099			MACH_O_NAMELEN) == 0)
1100	      {
1101		if (!macho_add_dwarf_segment (state, descriptor, offset,
1102					      load_command.cmd,
1103					      pcmd + sizeof segcmd,
1104					      (load_command.cmdsize
1105					       - sizeof segcmd),
1106					      segcmd.nsects, error_callback,
1107					      data, &dwarf_sections))
1108		  goto fail;
1109		have_dwarf = 1;
1110	      }
1111	  }
1112	  break;
1113
1114	case MACH_O_LC_SEGMENT_64:
1115	  {
1116	    struct macho_segment_64_command segcmd;
1117
1118	    memcpy (&segcmd, pcmd, sizeof segcmd);
1119	    if (memcmp (segcmd.segname,
1120			"__DWARF\0\0\0\0\0\0\0\0\0",
1121			MACH_O_NAMELEN) == 0)
1122	      {
1123		if (!macho_add_dwarf_segment (state, descriptor, offset,
1124					      load_command.cmd,
1125					      pcmd + sizeof segcmd,
1126					      (load_command.cmdsize
1127					       - sizeof segcmd),
1128					      segcmd.nsects, error_callback,
1129					      data, &dwarf_sections))
1130		  goto fail;
1131		have_dwarf = 1;
1132	      }
1133	  }
1134	  break;
1135
1136	case MACH_O_LC_SYMTAB:
1137	  if (!skip_symtab)
1138	    {
1139	      struct macho_symtab_command symcmd;
1140
1141	      memcpy (&symcmd, pcmd, sizeof symcmd);
1142	      if (!macho_add_symtab (state, descriptor, base_address, is_64,
1143				     offset + symcmd.symoff, symcmd.nsyms,
1144				     offset + symcmd.stroff, symcmd.strsize,
1145				     error_callback, data))
1146		goto fail;
1147
1148	      *found_sym = 1;
1149	    }
1150	  break;
1151
1152	case MACH_O_LC_UUID:
1153	  {
1154	    struct macho_uuid_command uuidcmd;
1155
1156	    memcpy (&uuidcmd, pcmd, sizeof uuidcmd);
1157	    memcpy (&uuid[0], &uuidcmd.uuid[0], MACH_O_UUID_LEN);
1158	    have_uuid = 1;
1159	  }
1160	  break;
1161
1162	default:
1163	  break;
1164	}
1165
1166      cmdoffset += load_command.cmdsize;
1167    }
1168
1169  if (!backtrace_close (descriptor, error_callback, data))
1170    goto fail;
1171  descriptor = -1;
1172
1173  backtrace_release_view (state, &cmds_view, error_callback, data);
1174  cmds_view_valid = 0;
1175
1176  if (match_uuid != NULL)
1177    {
1178      /* If we don't have a UUID, or it doesn't match, just ignore
1179	 this file.  */
1180      if (!have_uuid
1181	  || memcmp (match_uuid, &uuid[0], MACH_O_UUID_LEN) != 0)
1182	return 1;
1183    }
1184
1185  if (have_dwarf)
1186    {
1187      int is_big_endian;
1188
1189      is_big_endian = 0;
1190#if defined(__BYTE_ORDER__) && defined(__ORDER_BIG_ENDIAN__)
1191#if __BYTE_ORDER__ == __ORDER_BIG_ENDIAN__
1192      is_big_endian = 1;
1193#endif
1194#endif
1195
1196      if (!backtrace_dwarf_add (state, base_address, &dwarf_sections,
1197				is_big_endian, NULL, error_callback, data,
1198				fileline_fn, NULL))
1199	goto fail;
1200    }
1201
1202  if (!have_dwarf && have_uuid)
1203    {
1204      if (!macho_add_dsym (state, filename, base_address, &uuid[0],
1205			   error_callback, data, fileline_fn))
1206	goto fail;
1207    }
1208
1209  return 1;
1210
1211 fail:
1212  if (cmds_view_valid)
1213    backtrace_release_view (state, &cmds_view, error_callback, data);
1214  if (descriptor != -1)
1215    backtrace_close (descriptor, error_callback, data);
1216  return 0;
1217}
1218
1219#ifdef HAVE_MACH_O_DYLD_H
1220
1221/* Initialize the backtrace data we need from a Mach-O executable
1222   using the dyld support functions.  This closes descriptor.  */
1223
1224int
1225backtrace_initialize (struct backtrace_state *state, const char *filename,
1226		      int descriptor, backtrace_error_callback error_callback,
1227		      void *data, fileline *fileline_fn)
1228{
1229  uint32_t c;
1230  uint32_t i;
1231  int closed_descriptor;
1232  int found_sym;
1233  fileline macho_fileline_fn;
1234
1235  closed_descriptor = 0;
1236  found_sym = 0;
1237  macho_fileline_fn = macho_nodebug;
1238
1239  c = _dyld_image_count ();
1240  for (i = 0; i < c; ++i)
1241    {
1242      uintptr_t base_address;
1243      const char *name;
1244      int d;
1245      fileline mff;
1246      int mfs;
1247
1248      name = _dyld_get_image_name (i);
1249      if (name == NULL)
1250	continue;
1251
1252      if (strcmp (name, filename) == 0 && !closed_descriptor)
1253	{
1254	  d = descriptor;
1255	  closed_descriptor = 1;
1256	}
1257      else
1258	{
1259	  int does_not_exist;
1260
1261	  d = backtrace_open (name, error_callback, data, &does_not_exist);
1262	  if (d < 0)
1263	    continue;
1264	}
1265
1266      base_address = _dyld_get_image_vmaddr_slide (i);
1267
1268      mff = macho_nodebug;
1269      if (!macho_add (state, name, d, 0, NULL, base_address, 0,
1270		      error_callback, data, &mff, &mfs))
1271	return 0;
1272
1273      if (mff != macho_nodebug)
1274	macho_fileline_fn = mff;
1275      if (mfs)
1276	found_sym = 1;
1277    }
1278
1279  if (!closed_descriptor)
1280    backtrace_close (descriptor, error_callback, data);
1281
1282  if (!state->threaded)
1283    {
1284      if (found_sym)
1285	state->syminfo_fn = macho_syminfo;
1286      else if (state->syminfo_fn == NULL)
1287	state->syminfo_fn = macho_nosyms;
1288    }
1289  else
1290    {
1291      if (found_sym)
1292	backtrace_atomic_store_pointer (&state->syminfo_fn, macho_syminfo);
1293      else
1294	(void) __sync_bool_compare_and_swap (&state->syminfo_fn, NULL,
1295					     macho_nosyms);
1296    }
1297
1298  if (!state->threaded)
1299    *fileline_fn = state->fileline_fn;
1300  else
1301    *fileline_fn = backtrace_atomic_load_pointer (&state->fileline_fn);
1302
1303  if (*fileline_fn == NULL || *fileline_fn == macho_nodebug)
1304    *fileline_fn = macho_fileline_fn;
1305
1306  return 1;
1307}
1308
1309#else /* !defined (HAVE_MACH_O_DYLD_H) */
1310
1311/* Initialize the backtrace data we need from a Mach-O executable
1312   without using the dyld support functions.  This closes
1313   descriptor.  */
1314
1315int
1316backtrace_initialize (struct backtrace_state *state, const char *filename,
1317		      int descriptor, backtrace_error_callback error_callback,
1318		      void *data, fileline *fileline_fn)
1319{
1320  fileline macho_fileline_fn;
1321  int found_sym;
1322
1323  macho_fileline_fn = macho_nodebug;
1324  if (!macho_add (state, filename, descriptor, 0, NULL, 0, 0,
1325		  error_callback, data, &macho_fileline_fn, &found_sym))
1326    return 0;
1327
1328  if (!state->threaded)
1329    {
1330      if (found_sym)
1331	state->syminfo_fn = macho_syminfo;
1332      else if (state->syminfo_fn == NULL)
1333	state->syminfo_fn = macho_nosyms;
1334    }
1335  else
1336    {
1337      if (found_sym)
1338	backtrace_atomic_store_pointer (&state->syminfo_fn, macho_syminfo);
1339      else
1340	(void) __sync_bool_compare_and_swap (&state->syminfo_fn, NULL,
1341					     macho_nosyms);
1342    }
1343
1344  if (!state->threaded)
1345    *fileline_fn = state->fileline_fn;
1346  else
1347    *fileline_fn = backtrace_atomic_load_pointer (&state->fileline_fn);
1348
1349  if (*fileline_fn == NULL || *fileline_fn == macho_nodebug)
1350    *fileline_fn = macho_fileline_fn;
1351
1352  return 1;
1353}
1354
1355#endif /* !defined (HAVE_MACH_O_DYLD_H) */
1356