Experimenting with pulling elf and mach-o definitions into the project instead of relying on system headers
This commit is contained in:
parent
18046688f6
commit
30130b4929
138
src/binary/defs/elf_defs.hpp
Normal file
138
src/binary/defs/elf_defs.hpp
Normal file
@ -0,0 +1,138 @@
|
||||
#ifndef ELF_DEFS_HPP
|
||||
#define ELF_DEFS_HPP
|
||||
|
||||
#include <cstdint>
|
||||
|
||||
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
|
||||
242
src/binary/defs/mach-o-defs.hpp
Normal file
242
src/binary/defs/mach-o-defs.hpp
Normal file
@ -0,0 +1,242 @@
|
||||
#ifndef MACH_O_DEFS_HPP
|
||||
#define MACH_O_DEFS_HPP
|
||||
|
||||
#include <cstdint>
|
||||
|
||||
// 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 <mach-o/stab.h> */
|
||||
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 <mach-o/stab.h> */
|
||||
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
|
||||
@ -8,7 +8,7 @@
|
||||
#include <cstring>
|
||||
#include <type_traits>
|
||||
|
||||
#include <elf.h>
|
||||
#include "binary/defs/elf_defs.hpp"
|
||||
|
||||
namespace cpptrace {
|
||||
namespace detail {
|
||||
|
||||
@ -19,16 +19,20 @@
|
||||
#include <iostream>
|
||||
#include <iomanip>
|
||||
|
||||
#include <mach-o/loader.h>
|
||||
#include <mach-o/swap.h>
|
||||
#include <mach-o/fat.h>
|
||||
#include <crt_externs.h>
|
||||
#include <mach-o/nlist.h>
|
||||
#include <mach-o/stab.h>
|
||||
#include <mach-o/arch.h>
|
||||
#include "binary/defs/mach-o-defs.hpp"
|
||||
|
||||
// #include <mach-o/loader.h>
|
||||
// #include <mach-o/swap.h>
|
||||
// #include <mach-o/fat.h>
|
||||
// #include <crt_externs.h>
|
||||
// #include <mach-o/nlist.h>
|
||||
// #include <mach-o/stab.h>
|
||||
// #include <mach-o/arch.h>
|
||||
|
||||
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;
|
||||
}
|
||||
|
||||
@ -13,9 +13,7 @@
|
||||
#include <unordered_map>
|
||||
#include <vector>
|
||||
|
||||
#include <mach-o/arch.h>
|
||||
#include <mach-o/loader.h>
|
||||
#include <mach-o/nlist.h>
|
||||
#include "binary/defs/mach-o-defs.hpp"
|
||||
|
||||
namespace cpptrace {
|
||||
namespace detail {
|
||||
|
||||
@ -39,9 +39,13 @@ namespace detail {
|
||||
#elif IS_APPLE
|
||||
|
||||
#include <cstdint>
|
||||
#include <mach-o/dyld.h>
|
||||
// #include <mach-o/dyld.h>
|
||||
#include <sys/syslimits.h>
|
||||
|
||||
// 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 {
|
||||
|
||||
Loading…
Reference in New Issue
Block a user