|
|
|
@ -75,7 +75,7 @@ struct macho_header_64
@@ -75,7 +75,7 @@ struct macho_header_64
|
|
|
|
|
|
|
|
|
|
struct macho_header_fat |
|
|
|
|
{ |
|
|
|
|
uint32_t magic; /* Magic number (MACH_O_MH_MAGIC_FAT) */ |
|
|
|
|
uint32_t magic; /* Magic number (MACH_O_MH_(MAGIC|CIGAM)_FAT(_64)?) */ |
|
|
|
|
uint32_t nfat_arch; /* Number of components */ |
|
|
|
|
}; |
|
|
|
|
|
|
|
|
@ -85,6 +85,8 @@ struct macho_header_fat
@@ -85,6 +85,8 @@ struct macho_header_fat
|
|
|
|
|
#define MACH_O_MH_MAGIC_64 0xfeedfacf |
|
|
|
|
#define MACH_O_MH_MAGIC_FAT 0xcafebabe |
|
|
|
|
#define MACH_O_MH_CIGAM_FAT 0xbebafeca |
|
|
|
|
#define MACH_O_MH_MAGIC_FAT_64 0xcafebabf |
|
|
|
|
#define MACH_O_MH_CIGAM_FAT_64 0xbfbafeca |
|
|
|
|
|
|
|
|
|
/* Value for the header filetype field. */ |
|
|
|
|
|
|
|
|
@ -105,6 +107,20 @@ struct macho_fat_arch
@@ -105,6 +107,20 @@ struct macho_fat_arch
|
|
|
|
|
uint32_t align; /* Alignment of this entry */ |
|
|
|
|
}; |
|
|
|
|
|
|
|
|
|
/* A component of a 64-bit fat file. This is used if the magic field
|
|
|
|
|
is MAGIC_FAT_64. This is only used when some file size or file |
|
|
|
|
offset is too large to represent in the 32-bit format. */ |
|
|
|
|
|
|
|
|
|
struct macho_fat_arch_64 |
|
|
|
|
{ |
|
|
|
|
uint32_t cputype; /* CPU type */ |
|
|
|
|
uint32_t cpusubtype; /* CPU subtype */ |
|
|
|
|
uint64_t offset; /* File offset of this entry */ |
|
|
|
|
uint64_t size; /* Size of this entry */ |
|
|
|
|
uint32_t align; /* Alignment of this entry */ |
|
|
|
|
uint32_t reserved; /* Reserved */ |
|
|
|
|
}; |
|
|
|
|
|
|
|
|
|
/* Values for the fat_arch cputype field (and the header cputype
|
|
|
|
|
field). */ |
|
|
|
|
|
|
|
|
@ -740,14 +756,14 @@ static int
@@ -740,14 +756,14 @@ static int
|
|
|
|
|
macho_add_fat (struct backtrace_state *state, const char *filename, |
|
|
|
|
int descriptor, int swapped, off_t offset, |
|
|
|
|
const unsigned char *match_uuid, uintptr_t base_address, |
|
|
|
|
int skip_symtab, uint32_t nfat_arch, |
|
|
|
|
int skip_symtab, uint32_t nfat_arch, int is_64, |
|
|
|
|
backtrace_error_callback error_callback, void *data, |
|
|
|
|
fileline *fileline_fn, int *found_sym) |
|
|
|
|
{ |
|
|
|
|
int arch_view_valid; |
|
|
|
|
unsigned int cputype; |
|
|
|
|
size_t arch_size; |
|
|
|
|
struct backtrace_view arch_view; |
|
|
|
|
size_t archoffset; |
|
|
|
|
unsigned int i; |
|
|
|
|
|
|
|
|
|
arch_view_valid = 0; |
|
|
|
@ -765,21 +781,39 @@ macho_add_fat (struct backtrace_state *state, const char *filename,
@@ -765,21 +781,39 @@ macho_add_fat (struct backtrace_state *state, const char *filename,
|
|
|
|
|
goto fail; |
|
|
|
|
#endif |
|
|
|
|
|
|
|
|
|
if (is_64) |
|
|
|
|
arch_size = sizeof (struct macho_fat_arch_64); |
|
|
|
|
else |
|
|
|
|
arch_size = sizeof (struct macho_fat_arch); |
|
|
|
|
|
|
|
|
|
if (!backtrace_get_view (state, descriptor, offset, |
|
|
|
|
nfat_arch * sizeof (struct macho_fat_arch), |
|
|
|
|
nfat_arch * arch_size, |
|
|
|
|
error_callback, data, &arch_view)) |
|
|
|
|
goto fail; |
|
|
|
|
|
|
|
|
|
archoffset = 0; |
|
|
|
|
for (i = 0; i < nfat_arch; ++i) |
|
|
|
|
{ |
|
|
|
|
struct macho_fat_arch fat_arch; |
|
|
|
|
struct macho_fat_arch_64 fat_arch; |
|
|
|
|
uint32_t fcputype; |
|
|
|
|
|
|
|
|
|
memcpy (&fat_arch, |
|
|
|
|
((const char *) arch_view.data |
|
|
|
|
+ i * sizeof (struct macho_fat_arch)), |
|
|
|
|
sizeof fat_arch); |
|
|
|
|
if (is_64) |
|
|
|
|
memcpy (&fat_arch, |
|
|
|
|
(const char *) arch_view.data + i * arch_size, |
|
|
|
|
arch_size); |
|
|
|
|
else |
|
|
|
|
{ |
|
|
|
|
struct macho_fat_arch fat_arch_32; |
|
|
|
|
|
|
|
|
|
memcpy (&fat_arch_32, |
|
|
|
|
(const char *) arch_view.data + i * arch_size, |
|
|
|
|
arch_size); |
|
|
|
|
fat_arch.cputype = fat_arch_32.cputype; |
|
|
|
|
fat_arch.cpusubtype = fat_arch_32.cpusubtype; |
|
|
|
|
fat_arch.offset = (uint64_t) fat_arch_32.offset; |
|
|
|
|
fat_arch.size = (uint64_t) fat_arch_32.size; |
|
|
|
|
fat_arch.align = fat_arch_32.align; |
|
|
|
|
fat_arch.reserved = 0; |
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
fcputype = fat_arch.cputype; |
|
|
|
|
if (swapped) |
|
|
|
@ -787,19 +821,17 @@ macho_add_fat (struct backtrace_state *state, const char *filename,
@@ -787,19 +821,17 @@ macho_add_fat (struct backtrace_state *state, const char *filename,
|
|
|
|
|
|
|
|
|
|
if (fcputype == cputype) |
|
|
|
|
{ |
|
|
|
|
uint32_t foffset; |
|
|
|
|
uint64_t foffset; |
|
|
|
|
|
|
|
|
|
/* FIXME: What about cpusubtype? */ |
|
|
|
|
foffset = fat_arch.offset; |
|
|
|
|
if (swapped) |
|
|
|
|
foffset = __builtin_bswap32 (foffset); |
|
|
|
|
foffset = __builtin_bswap64 (foffset); |
|
|
|
|
backtrace_release_view (state, &arch_view, error_callback, data); |
|
|
|
|
return macho_add (state, filename, descriptor, foffset, match_uuid, |
|
|
|
|
base_address, skip_symtab, error_callback, data, |
|
|
|
|
fileline_fn, found_sym); |
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
archoffset += sizeof (struct macho_fat_arch); |
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
error_callback (data, "could not find executable in fat file", 0); |
|
|
|
@ -980,6 +1012,7 @@ macho_add (struct backtrace_state *state, const char *filename, int descriptor,
@@ -980,6 +1012,7 @@ macho_add (struct backtrace_state *state, const char *filename, int descriptor,
|
|
|
|
|
hdroffset = offset + sizeof (struct macho_header_64); |
|
|
|
|
break; |
|
|
|
|
case MACH_O_MH_MAGIC_FAT: |
|
|
|
|
case MACH_O_MH_MAGIC_FAT_64: |
|
|
|
|
{ |
|
|
|
|
struct macho_header_fat fat_header; |
|
|
|
|
|
|
|
|
@ -987,10 +1020,12 @@ macho_add (struct backtrace_state *state, const char *filename, int descriptor,
@@ -987,10 +1020,12 @@ macho_add (struct backtrace_state *state, const char *filename, int descriptor,
|
|
|
|
|
memcpy (&fat_header, &header, sizeof fat_header); |
|
|
|
|
return macho_add_fat (state, filename, descriptor, 0, hdroffset, |
|
|
|
|
match_uuid, base_address, skip_symtab, |
|
|
|
|
fat_header.nfat_arch, error_callback, data, |
|
|
|
|
fileline_fn, found_sym); |
|
|
|
|
fat_header.nfat_arch, |
|
|
|
|
header.magic == MACH_O_MH_MAGIC_FAT_64, |
|
|
|
|
error_callback, data, fileline_fn, found_sym); |
|
|
|
|
} |
|
|
|
|
case MACH_O_MH_CIGAM_FAT: |
|
|
|
|
case MACH_O_MH_CIGAM_FAT_64: |
|
|
|
|
{ |
|
|
|
|
struct macho_header_fat fat_header; |
|
|
|
|
uint32_t nfat_arch; |
|
|
|
@ -1000,8 +1035,9 @@ macho_add (struct backtrace_state *state, const char *filename, int descriptor,
@@ -1000,8 +1035,9 @@ macho_add (struct backtrace_state *state, const char *filename, int descriptor,
|
|
|
|
|
nfat_arch = __builtin_bswap32 (fat_header.nfat_arch); |
|
|
|
|
return macho_add_fat (state, filename, descriptor, 1, hdroffset, |
|
|
|
|
match_uuid, base_address, skip_symtab, |
|
|
|
|
nfat_arch, error_callback, data, |
|
|
|
|
fileline_fn, found_sym); |
|
|
|
|
nfat_arch, |
|
|
|
|
header.magic == MACH_O_MH_CIGAM_FAT_64, |
|
|
|
|
error_callback, data, fileline_fn, found_sym); |
|
|
|
|
} |
|
|
|
|
default: |
|
|
|
|
error_callback (data, "executable file is not in Mach-O format", 0); |
|
|
|
|