diff --git a/src/binary/defs/elf_defs.hpp b/src/binary/defs/elf_defs.hpp new file mode 100644 index 0000000..b90efc6 --- /dev/null +++ b/src/binary/defs/elf_defs.hpp @@ -0,0 +1,138 @@ +#ifndef ELF_DEFS_HPP +#define ELF_DEFS_HPP + +#include + +namespace cpptrace { +namespace detail { + + // https://man7.org/linux/man-pages/man5/elf.5.html + // https://github.com/torvalds/linux/blob/master/include/uapi/linux/elf.h + + /* 32-bit ELF base types. */ + typedef std::uint32_t Elf32_Addr; + typedef std::uint16_t Elf32_Half; + typedef std::uint32_t Elf32_Off; + typedef std::int32_t Elf32_Sword; + typedef std::uint32_t Elf32_Word; + + /* 64-bit ELF base types. */ + typedef std::uint64_t Elf64_Addr; + typedef std::uint16_t Elf64_Half; + typedef std::int16_t Elf64_SHalf; + typedef std::uint64_t Elf64_Off; + typedef std::int32_t Elf64_Sword; + typedef std::uint32_t Elf64_Word; + typedef std::uint64_t Elf64_Xword; + typedef std::int64_t Elf64_Sxword; + + #define PT_PHDR 6 + #define EI_NIDENT 16 + #define SHT_SYMTAB 2 + #define SHT_STRTAB 3 + #define SHT_DYNAMIC 6 + + typedef struct { + std::uint32_t p_type; + Elf32_Off p_offset; + Elf32_Addr p_vaddr; + Elf32_Addr p_paddr; + std::uint32_t p_filesz; + std::uint32_t p_memsz; + std::uint32_t p_flags; + std::uint32_t p_align; + } Elf32_Phdr; + + typedef struct { + std::uint32_t p_type; + std::uint32_t p_flags; + Elf64_Off p_offset; + Elf64_Addr p_vaddr; + Elf64_Addr p_paddr; + std::uint64_t p_filesz; + std::uint64_t p_memsz; + std::uint64_t p_align; + } Elf64_Phdr; + + typedef struct elf32_hdr { + unsigned char e_ident[EI_NIDENT]; + Elf32_Half e_type; + Elf32_Half e_machine; + Elf32_Word e_version; + Elf32_Addr e_entry; /* Entry point */ + Elf32_Off e_phoff; + Elf32_Off e_shoff; + Elf32_Word e_flags; + Elf32_Half e_ehsize; + Elf32_Half e_phentsize; + Elf32_Half e_phnum; + Elf32_Half e_shentsize; + Elf32_Half e_shnum; + Elf32_Half e_shstrndx; + } Elf32_Ehdr; + + typedef struct elf64_hdr { + unsigned char e_ident[EI_NIDENT]; /* ELF "magic number" */ + Elf64_Half e_type; + Elf64_Half e_machine; + Elf64_Word e_version; + Elf64_Addr e_entry; /* Entry point virtual address */ + Elf64_Off e_phoff; /* Program header table file offset */ + Elf64_Off e_shoff; /* Section header table file offset */ + Elf64_Word e_flags; + Elf64_Half e_ehsize; + Elf64_Half e_phentsize; + Elf64_Half e_phnum; + Elf64_Half e_shentsize; + Elf64_Half e_shnum; + Elf64_Half e_shstrndx; + } Elf64_Ehdr; + + typedef struct elf32_shdr { + Elf32_Word sh_name; + Elf32_Word sh_type; + Elf32_Word sh_flags; + Elf32_Addr sh_addr; + Elf32_Off sh_offset; + Elf32_Word sh_size; + Elf32_Word sh_link; + Elf32_Word sh_info; + Elf32_Word sh_addralign; + Elf32_Word sh_entsize; + } Elf32_Shdr; + + typedef struct elf64_shdr { + Elf64_Word sh_name; /* Section name, index in string tbl */ + Elf64_Word sh_type; /* Type of section */ + Elf64_Xword sh_flags; /* Miscellaneous section attributes */ + Elf64_Addr sh_addr; /* Section virtual addr at execution */ + Elf64_Off sh_offset; /* Section file offset */ + Elf64_Xword sh_size; /* Size of section in bytes */ + Elf64_Word sh_link; /* Index of another section */ + Elf64_Word sh_info; /* Additional section information */ + Elf64_Xword sh_addralign; /* Section alignment */ + Elf64_Xword sh_entsize; /* Entry size if section holds table */ + } Elf64_Shdr; + + typedef struct elf32_sym { + Elf32_Word st_name; + Elf32_Addr st_value; + Elf32_Word st_size; + unsigned char st_info; + unsigned char st_other; + Elf32_Half st_shndx; + } Elf32_Sym; + + typedef struct elf64_sym { + Elf64_Word st_name; /* Symbol name, index in string tbl */ + unsigned char st_info; /* Type and binding attributes */ + unsigned char st_other; /* No defined meaning, 0 */ + Elf64_Half st_shndx; /* Associated section index */ + Elf64_Addr st_value; /* Value of the symbol */ + Elf64_Xword st_size; /* Associated symbol size */ + } Elf64_Sym; + +} +} + +#endif diff --git a/src/binary/defs/mach-o-defs.hpp b/src/binary/defs/mach-o-defs.hpp new file mode 100644 index 0000000..7c118db --- /dev/null +++ b/src/binary/defs/mach-o-defs.hpp @@ -0,0 +1,242 @@ +#ifndef MACH_O_DEFS_HPP +#define MACH_O_DEFS_HPP + +#include + +// This file contains definitons from various apple headers licensed under APSL +// https://opensource.apple.com/apsl/ + +typedef int32_t integer_t; // https://developer.apple.com/documentation/driverkit/integer_t +typedef integer_t cpu_type_t; // https://developer.apple.com/documentation/kernel/cpu_type_t +typedef integer_t cpu_subtype_t; // https://developer.apple.com/documentation/kernel/cpu_subtype_t + +// https://github.com/apple-oss-distributions/xnu/blob/8d741a5de7ff4191bf97d57b9f54c2f6d4a15585/osfmk/mach/vm_prot.h#L75 +typedef int vm_prot_t; // https://developer.apple.com/documentation/kernel/vm_prot_t + +// https://github.com/apple-oss-distributions/xnu/blob/8d741a5de7ff4191bf97d57b9f54c2f6d4a15585/EXTERNAL_HEADERS/mach-o/loader.h#L65 +#define MH_MAGIC 0xfeedface /* the mach magic number */ +#define MH_CIGAM 0xcefaedfe /* NXSwapInt(MH_MAGIC) */ + +struct mach_header { + uint32_t magic; /* mach magic number identifier */ + cpu_type_t cputype; /* cpu specifier */ + cpu_subtype_t cpusubtype; /* machine specifier */ + uint32_t filetype; /* type of file */ + uint32_t ncmds; /* number of load commands */ + uint32_t sizeofcmds; /* the size of all the load commands */ + uint32_t flags; /* flags */ +}; + +/* Constant for the magic field of the mach_header_64 (64-bit architectures) */ +#define MH_MAGIC_64 0xfeedfacf /* the 64-bit mach magic number */ +#define MH_CIGAM_64 0xcffaedfe /* NXSwapInt(MH_MAGIC_64) */ + +struct mach_header_64 { + uint32_t magic; /* mach magic number identifier */ + cpu_type_t cputype; /* cpu specifier */ + cpu_subtype_t cpusubtype; /* machine specifier */ + uint32_t filetype; /* type of file */ + uint32_t ncmds; /* number of load commands */ + uint32_t sizeofcmds; /* the size of all the load commands */ + uint32_t flags; /* flags */ + uint32_t reserved; /* reserved */ +}; + +// https://github.com/apple-oss-distributions/xnu/blob/8d741a5de7ff4191bf97d57b9f54c2f6d4a15585/EXTERNAL_HEADERS/mach-o/loader.h#L247C1-L250C3 +struct load_command { + uint32_t cmd; /* type of load command */ + uint32_t cmdsize; /* total size of command in bytes */ +}; + +// https://github.com/apple-oss-distributions/xnu/blob/8d741a5de7ff4191bf97d57b9f54c2f6d4a15585/EXTERNAL_HEADERS/mach-o/fat.h#L48 +#define FAT_MAGIC 0xcafebabe +#define FAT_CIGAM 0xbebafeca /* NXSwapLong(FAT_MAGIC) */ +#define FAT_MAGIC_64 0xcafebabf +#define FAT_CIGAM_64 0xbfbafeca /* NXSwapLong(FAT_MAGIC_64) */ + +struct fat_header { + uint32_t magic; /* FAT_MAGIC */ + uint32_t nfat_arch; /* number of structs that follow */ +}; + +struct fat_arch { + cpu_type_t cputype; /* cpu specifier (int) */ + cpu_subtype_t cpusubtype; /* machine specifier (int) */ + uint32_t offset; /* file offset to this object file */ + uint32_t size; /* size of this object file */ + uint32_t align; /* alignment as a power of 2 */ +}; + +struct fat_arch_64 { + cpu_type_t cputype; /* cpu specifier (int) */ + cpu_subtype_t cpusubtype; /* machine specifier (int) */ + uint64_t offset; /* file offset to this object file */ + uint64_t size; /* size of this object file */ + uint32_t align; /* alignment as a power of 2 */ + uint32_t reserved; /* reserved */ +}; + +// https://github.com/apple-oss-distributions/xnu/blob/8d741a5de7ff4191bf97d57b9f54c2f6d4a15585/EXTERNAL_HEADERS/mach-o/loader.h#L355 +struct segment_command { /* for 32-bit architectures */ + uint32_t cmd; /* LC_SEGMENT */ + uint32_t cmdsize; /* includes sizeof section structs */ + char segname[16]; /* segment name */ + uint32_t vmaddr; /* memory address of this segment */ + uint32_t vmsize; /* memory size of this segment */ + uint32_t fileoff; /* file offset of this segment */ + uint32_t filesize; /* amount to map from the file */ + vm_prot_t maxprot; /* maximum VM protection */ + vm_prot_t initprot; /* initial VM protection */ + uint32_t nsects; /* number of sections in segment */ + uint32_t flags; /* flags */ +}; + +struct segment_command_64 { /* for 64-bit architectures */ + uint32_t cmd; /* LC_SEGMENT_64 */ + uint32_t cmdsize; /* includes sizeof section_64 structs */ + char segname[16]; /* segment name */ + uint64_t vmaddr; /* memory address of this segment */ + uint64_t vmsize; /* memory size of this segment */ + uint64_t fileoff; /* file offset of this segment */ + uint64_t filesize; /* amount to map from the file */ + vm_prot_t maxprot; /* maximum VM protection */ + vm_prot_t initprot; /* initial VM protection */ + uint32_t nsects; /* number of sections in segment */ + uint32_t flags; /* flags */ +}; + +// https://github.com/apple-oss-distributions/xnu/blob/8d741a5de7ff4191bf97d57b9f54c2f6d4a15585/EXTERNAL_HEADERS/mach-o/loader.h#L868 +struct symtab_command { + uint32_t cmd; /* LC_SYMTAB */ + uint32_t cmdsize; /* sizeof(struct symtab_command) */ + uint32_t symoff; /* symbol table offset */ + uint32_t nsyms; /* number of symbol table entries */ + uint32_t stroff; /* string table offset */ + uint32_t strsize; /* string table size in bytes */ +}; + +// https://github.com/apple-oss-distributions/xnu/blob/8d741a5de7ff4191bf97d57b9f54c2f6d4a15585/EXTERNAL_HEADERS/mach-o/nlist.h#L92 +struct nlist { + union { +// #ifndef __LP64__ +// char *n_name; /* for use when in-core */ +// #endif + uint32_t n_strx; /* index into the string table */ + } n_un; + uint8_t n_type; /* type flag, see below */ + uint8_t n_sect; /* section number or NO_SECT */ + int16_t n_desc; /* see */ + uint32_t n_value; /* value of this symbol (or stab offset) */ +}; + +struct nlist_64 { + union { + uint32_t n_strx; /* index into the string table */ + } n_un; + uint8_t n_type; /* type flag, see below */ + uint8_t n_sect; /* section number or NO_SECT */ + uint16_t n_desc; /* see */ + uint64_t n_value; /* value of this symbol (or stab offset) */ +}; + +// https://github.com/apple-oss-distributions/xnu/blob/8d741a5de7ff4191bf97d57b9f54c2f6d4a15585/EXTERNAL_HEADERS/mach-o/loader.h#L263 +/* Constants for the cmd field of all load commands, the type */ +#define LC_SEGMENT 0x1 /* segment of this file to be mapped */ +#define LC_SYMTAB 0x2 /* link-edit stab symbol table info */ +#define LC_SYMSEG 0x3 /* link-edit gdb symbol table info (obsolete) */ +#define LC_THREAD 0x4 /* thread */ +#define LC_UNIXTHREAD 0x5 /* unix thread (includes a stack) */ +#define LC_LOADFVMLIB 0x6 /* load a specified fixed VM shared library */ +#define LC_IDFVMLIB 0x7 /* fixed VM shared library identification */ +#define LC_IDENT 0x8 /* object identification info (obsolete) */ +#define LC_FVMFILE 0x9 /* fixed VM file inclusion (internal use) */ +#define LC_PREPAGE 0xa /* prepage command (internal use) */ +#define LC_DYSYMTAB 0xb /* dynamic link-edit symbol table info */ +#define LC_LOAD_DYLIB 0xc /* load a dynamically linked shared library */ +#define LC_ID_DYLIB 0xd /* dynamically linked shared lib ident */ +#define LC_LOAD_DYLINKER 0xe /* load a dynamic linker */ +#define LC_ID_DYLINKER 0xf /* dynamic linker identification */ +#define LC_PREBOUND_DYLIB 0x10 /* modules prebound for a dynamically */ + /* linked shared library */ +#define LC_ROUTINES 0x11 /* image routines */ +#define LC_SUB_FRAMEWORK 0x12 /* sub framework */ +#define LC_SUB_UMBRELLA 0x13 /* sub umbrella */ +#define LC_SUB_CLIENT 0x14 /* sub client */ +#define LC_SUB_LIBRARY 0x15 /* sub library */ +#define LC_TWOLEVEL_HINTS 0x16 /* two-level namespace lookup hints */ +#define LC_PREBIND_CKSUM 0x17 /* prebind checksum */ + +#define LC_SEGMENT_64 0x19 /* 64-bit segment of this file to be */ +#define LC_ROUTINES_64 0x1a /* 64-bit image routines */ +#define LC_UUID 0x1b /* the uuid */ + +// https://github.com/apple-oss-distributions/xnu/blob/8d741a5de7ff4191bf97d57b9f54c2f6d4a15585/EXTERNAL_HEADERS/mach-o/nlist.h#L117 +#define N_STAB 0xe0 /* if any of these bits set, a symbolic debugging entry */ +#define N_PEXT 0x10 /* private external symbol bit */ +#define N_TYPE 0x0e /* mask for the type bits */ +#define N_EXT 0x01 /* external symbol bit, set for external symbols */ + +#define N_UNDF 0x0 /* undefined, n_sect == NO_SECT */ +#define N_ABS 0x2 /* absolute, n_sect == NO_SECT */ +#define N_SECT 0xe /* defined in section number n_sect */ +#define N_PBUD 0xc /* prebound undefined (defined in a dylib) */ +#define N_INDR 0xa /* indirect */ + +// https://github.com/apple-oss-distributions/xnu/blob/8d741a5de7ff4191bf97d57b9f54c2f6d4a15585/EXTERNAL_HEADERS/mach-o/stab.h#L87C1-L116C68 +#define N_GSYM 0x20 /* global symbol: name,,NO_SECT,type,0 */ +#define N_FNAME 0x22 /* procedure name (f77 kludge): name,,NO_SECT,0,0 */ +#define N_FUN 0x24 /* procedure: name,,n_sect,linenumber,address */ +#define N_STSYM 0x26 /* static symbol: name,,n_sect,type,address */ +#define N_LCSYM 0x28 /* .lcomm symbol: name,,n_sect,type,address */ +#define N_BNSYM 0x2e /* begin nsect sym: 0,,n_sect,0,address */ +#define N_AST 0x32 /* AST file path: name,,NO_SECT,0,0 */ +#define N_OPT 0x3c /* emitted with gcc2_compiled and in gcc source */ +#define N_RSYM 0x40 /* register sym: name,,NO_SECT,type,register */ +#define N_SLINE 0x44 /* src line: 0,,n_sect,linenumber,address */ +#define N_ENSYM 0x4e /* end nsect sym: 0,,n_sect,0,address */ +#define N_SSYM 0x60 /* structure elt: name,,NO_SECT,type,struct_offset */ +#define N_SO 0x64 /* source file name: name,,n_sect,0,address */ +#define N_OSO 0x66 /* object file name: name,,0,0,st_mtime */ +#define N_LSYM 0x80 /* local sym: name,,NO_SECT,type,offset */ +#define N_BINCL 0x82 /* include file beginning: name,,NO_SECT,0,sum */ +#define N_SOL 0x84 /* #included file name: name,,n_sect,0,address */ +#define N_PARAMS 0x86 /* compiler parameters: name,,NO_SECT,0,0 */ +#define N_VERSION 0x88 /* compiler version: name,,NO_SECT,0,0 */ +#define N_OLEVEL 0x8A /* compiler -O level: name,,NO_SECT,0,0 */ +#define N_PSYM 0xa0 /* parameter: name,,NO_SECT,type,offset */ +#define N_EINCL 0xa2 /* include file end: name,,NO_SECT,0,0 */ +#define N_ENTRY 0xa4 /* alternate entry: name,,n_sect,linenumber,address */ +#define N_LBRAC 0xc0 /* left bracket: 0,,NO_SECT,nesting level,address */ +#define N_EXCL 0xc2 /* deleted include file: name,,NO_SECT,0,sum */ +#define N_RBRAC 0xe0 /* right bracket: 0,,NO_SECT,nesting level,address */ +#define N_BCOMM 0xe2 /* begin common: name,,NO_SECT,0,0 */ +#define N_ECOMM 0xe4 /* end common: name,,n_sect,0,0 */ +#define N_ECOML 0xe8 /* end common (local name): 0,,n_sect,0,address */ +#define N_LENG 0xfe /* second stab entry with length information */ + +extern "C" { +// There is exceedingly little evidence that this function actually exists. I think I discovered it through +// https://github.com/ruby/ruby/blob/ff64806ae51c2813f0c6334c0c52082b027c255c/addr2line.c#L2359. +// from MacOSX13.1.sdk/usr/include/crt_externs.h +#ifdef __LP64__ +extern struct mach_header_64* _NSGetMachExecuteHeader(void); +#else /* !__LP64__ */ +extern struct mach_header* _NSGetMachExecuteHeader(void); +#endif /* __LP64__ */ + +// MacOSX13.1.sdk/usr/include/mach-o/arch.h +extern struct fat_arch* NXFindBestFatArch( + cpu_type_t cputype, + cpu_subtype_t cpusubtype, + struct fat_arch* fat_archs, + uint32_t nfat_archs +); +extern struct fat_arch_64* NXFindBestFatArch_64( + cpu_type_t cputype, + cpu_subtype_t cpusubtype, + struct fat_arch_64* fat_archs64, + uint32_t nfat_archs +); // __CCTOOLS_DEPRECATED_MSG("use macho_best_slice()") +} + +#endif diff --git a/src/binary/elf.cpp b/src/binary/elf.cpp index 62f1f0f..ccd8766 100644 --- a/src/binary/elf.cpp +++ b/src/binary/elf.cpp @@ -8,7 +8,7 @@ #include #include -#include +#include "binary/defs/elf_defs.hpp" namespace cpptrace { namespace detail { diff --git a/src/binary/mach-o.cpp b/src/binary/mach-o.cpp index d25a41e..53ee532 100644 --- a/src/binary/mach-o.cpp +++ b/src/binary/mach-o.cpp @@ -19,16 +19,20 @@ #include #include -#include -#include -#include -#include -#include -#include -#include +#include "binary/defs/mach-o-defs.hpp" + +// #include +// #include +// #include +// #include +// #include +// #include +// #include namespace cpptrace { namespace detail { + // TODO: 64-bit fat?? + bool is_mach_o(std::uint32_t magic) { switch(magic) { case FAT_MAGIC: @@ -71,27 +75,89 @@ namespace detail { } void swap_mach_header(mach_header_64& header) { - swap_mach_header_64(&header, NX_UnknownByteOrder); + header.magic = byteswap(header.magic); + header.cputype = byteswap(header.cputype); + header.cpusubtype = byteswap(header.cpusubtype); + header.filetype = byteswap(header.filetype); + header.ncmds = byteswap(header.ncmds); + header.sizeofcmds = byteswap(header.sizeofcmds); + header.flags = byteswap(header.flags); + header.reserved = byteswap(header.reserved); } void swap_mach_header(mach_header& header) { - swap_mach_header(&header, NX_UnknownByteOrder); + header.magic = byteswap(header.magic); + header.cputype = byteswap(header.cputype); + header.cpusubtype = byteswap(header.cpusubtype); + header.filetype = byteswap(header.filetype); + header.ncmds = byteswap(header.ncmds); + header.sizeofcmds = byteswap(header.sizeofcmds); + header.flags = byteswap(header.flags); } void swap_segment_command(segment_command_64& segment) { - swap_segment_command_64(&segment, NX_UnknownByteOrder); + segment.cmd = byteswap(segment.cmd); + segment.cmdsize = byteswap(segment.cmdsize); + segment.vmaddr = byteswap(segment.vmaddr); + segment.vmsize = byteswap(segment.vmsize); + segment.fileoff = byteswap(segment.fileoff); + segment.filesize = byteswap(segment.filesize); + segment.maxprot = byteswap(segment.maxprot); + segment.initprot = byteswap(segment.initprot); + segment.nsects = byteswap(segment.nsects); + segment.flags = byteswap(segment.flags); } void swap_segment_command(segment_command& segment) { - swap_segment_command(&segment, NX_UnknownByteOrder); + segment.cmd = byteswap(segment.cmd); + segment.cmdsize = byteswap(segment.cmdsize); + segment.vmaddr = byteswap(segment.vmaddr); + segment.vmsize = byteswap(segment.vmsize); + segment.fileoff = byteswap(segment.fileoff); + segment.filesize = byteswap(segment.filesize); + segment.maxprot = byteswap(segment.maxprot); + segment.initprot = byteswap(segment.initprot); + segment.nsects = byteswap(segment.nsects); + segment.flags = byteswap(segment.flags); } - void swap_nlist(struct nlist& entry) { - swap_nlist(&entry, 1, NX_UnknownByteOrder); + void swap_symtab_command(symtab_command& symtab) { + symtab.cmd = byteswap(symtab.cmd); + symtab.cmdsize = byteswap(symtab.cmdsize); + symtab.symoff = byteswap(symtab.symoff); + symtab.nsyms = byteswap(symtab.nsyms); + symtab.stroff = byteswap(symtab.stroff); + symtab.strsize = byteswap(symtab.strsize); } - void swap_nlist(struct nlist_64& entry) { - swap_nlist_64(&entry, 1, NX_UnknownByteOrder); + void swap_nlist(nlist& entry) { + entry.n_un.n_strx = byteswap(entry.n_un.n_strx); + entry.n_desc = byteswap(entry.n_desc); + entry.n_value = byteswap(entry.n_value); + } + + void swap_nlist(nlist_64& entry) { + entry.n_un.n_strx = byteswap(entry.n_un.n_strx); + entry.n_desc = byteswap(entry.n_desc); + entry.n_value = byteswap(entry.n_value); + } + + void swap_load_command(load_command& command) { + command.cmd = byteswap(command.cmd); + command.cmdsize = byteswap(command.cmdsize); + } + + void swap_fat_header(fat_header& header) { + header.magic = byteswap(header.magic); + header.nfat_arch = byteswap(header.nfat_arch); + } + + void swap_fat_arch(fat_arch& arch) { + arch.cputype = byteswap(arch.cputype); + arch.cpusubtype = byteswap(arch.cpusubtype); + arch.offset = byteswap(arch.offset); + arch.size = byteswap(arch.size); + arch.align = byteswap(arch.align); } #ifdef __LP64__ @@ -491,7 +557,7 @@ namespace detail { } load_command& cmd = load_cmd.unwrap_value(); if(should_swap()) { - swap_load_command(&cmd, NX_UnknownByteOrder); + swap_load_command(cmd); } load_commands.push_back({ actual_offset, cmd.cmd, cmd.cmdsize }); actual_offset += cmd.cmdsize; @@ -508,7 +574,7 @@ namespace detail { } fat_header& header = load_header.unwrap_value(); if(should_swap()) { - swap_fat_header(&header, NX_UnknownByteOrder); + swap_fat_header(header); } // thread_local static struct LP(mach_header)* mhp = _NSGetMachExecuteHeader(); // off_t arch_offset = (off_t)header_size; @@ -546,7 +612,7 @@ namespace detail { } fat_arch& arch = load_arch.unwrap_value(); if(should_swap()) { - swap_fat_arch(&arch, 1, NX_UnknownByteOrder); + swap_fat_arch(arch); } fat_arches.push_back(arch); arch_offset += arch_size; @@ -614,7 +680,7 @@ namespace detail { symtab_command& symtab = load_symtab.unwrap_value(); ASSERT(symtab.cmd == LC_SYMTAB); if(should_swap()) { - swap_symtab_command(&symtab, NX_UnknownByteOrder); + swap_symtab_command(symtab); } return symtab; } diff --git a/src/binary/mach-o.hpp b/src/binary/mach-o.hpp index 82a36c5..fab5124 100644 --- a/src/binary/mach-o.hpp +++ b/src/binary/mach-o.hpp @@ -13,9 +13,7 @@ #include #include -#include -#include -#include +#include "binary/defs/mach-o-defs.hpp" namespace cpptrace { namespace detail { diff --git a/src/platform/program_name.hpp b/src/platform/program_name.hpp index e5dafac..a4241dd 100644 --- a/src/platform/program_name.hpp +++ b/src/platform/program_name.hpp @@ -39,9 +39,13 @@ namespace detail { #elif IS_APPLE #include -#include +// #include #include +// https://github.com/opensource-apple/dyld/blob/3f928f32597888c5eac6003b9199d972d49857b5/include/mach-o/dyld.h#L92C1-L92C62 +// https://developer.apple.com/library/archive/documentation/System/Conceptual/ManPages_iPhoneOS/man3/dyld.3.html +extern int _NSGetExecutablePath(char* buf, uint32_t* bufsize); + #define CPPTRACE_MAX_PATH CPPTRACE_PATH_MAX namespace cpptrace {