mirror of
https://github.com/ruby/ruby.git
synced 2022-11-09 12:17:21 -05:00
Support Universal Binary for macOS
git-svn-id: svn+ssh://ci.ruby-lang.org/ruby/trunk@65896 b2dd03c8-39d4-4d8f-98ff-823fe69b080e
This commit is contained in:
parent
26adef94fa
commit
529adb6872
1 changed files with 39 additions and 5 deletions
44
addr2line.c
44
addr2line.c
|
@ -66,6 +66,8 @@ void *alloca();
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
#ifdef HAVE_MACH_O_LOADER_H
|
#ifdef HAVE_MACH_O_LOADER_H
|
||||||
|
# include <mach-o/fat.h>
|
||||||
|
# include <mach-o/ldsyms.h>
|
||||||
# include <mach-o/loader.h>
|
# include <mach-o/loader.h>
|
||||||
# include <mach-o/nlist.h>
|
# include <mach-o/nlist.h>
|
||||||
# include <mach-o/stab.h>
|
# include <mach-o/stab.h>
|
||||||
|
@ -1829,7 +1831,7 @@ fill_lines(int num_traces, void **traces, int check_debuglink,
|
||||||
# endif
|
# endif
|
||||||
int fd;
|
int fd;
|
||||||
off_t filesize;
|
off_t filesize;
|
||||||
char *file, *p;
|
char *file, *p = NULL;
|
||||||
obj_info_t *obj = *objp;
|
obj_info_t *obj = *objp;
|
||||||
struct LP(mach_header) *header;
|
struct LP(mach_header) *header;
|
||||||
uintptr_t dladdr_fbase = 0;
|
uintptr_t dladdr_fbase = 0;
|
||||||
|
@ -1890,8 +1892,38 @@ fill_lines(int num_traces, void **traces, int check_debuglink,
|
||||||
obj->mapped_size = (size_t)filesize;
|
obj->mapped_size = (size_t)filesize;
|
||||||
|
|
||||||
header = (struct LP(mach_header) *)file;
|
header = (struct LP(mach_header) *)file;
|
||||||
if (header->magic != LP(MH_MAGIC)) {
|
if (header->magic == LP(MH_MAGIC)) {
|
||||||
/* TODO: universal binaries */
|
/* non universal binary */
|
||||||
|
p = file;
|
||||||
|
}
|
||||||
|
else if (header->magic == FAT_CIGAM) {
|
||||||
|
struct fat_header *fat = (struct fat_header *)file;
|
||||||
|
char *q = file + sizeof(*fat);
|
||||||
|
uint32_t nfat_arch = __builtin_bswap32(fat->nfat_arch);
|
||||||
|
/* fprintf(stderr,"%d: fat:%s %d\n",__LINE__, binary_filename,nfat_arch); */
|
||||||
|
for (uint32_t i = 0; i < nfat_arch; i++) {
|
||||||
|
struct fat_arch *arch = (struct fat_arch *)q;
|
||||||
|
cpu_type_t cputype = __builtin_bswap32(arch->cputype);
|
||||||
|
cpu_subtype_t cpusubtype = __builtin_bswap32(arch->cpusubtype);
|
||||||
|
uint32_t offset = __builtin_bswap32(arch->offset);
|
||||||
|
/* fprintf(stderr,"%d: fat %d %x/%x %x/%x\n",__LINE__, i, _mh_execute_header.cputype,_mh_execute_header.cpusubtype, cputype,cpusubtype); */
|
||||||
|
if (_mh_execute_header.cputype == cputype &&
|
||||||
|
(_mh_execute_header.cpusubtype & ~CPU_SUBTYPE_MASK) == cpusubtype) {
|
||||||
|
p = file + offset;
|
||||||
|
file = p;
|
||||||
|
header = (struct LP(mach_header) *)p;
|
||||||
|
if (header->magic == LP(MH_MAGIC)) {
|
||||||
|
goto found_mach_header;
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
q += sizeof(*arch);
|
||||||
|
}
|
||||||
|
kprintf("'%s' is not a Mach-O universal binary file!\n",binary_filename);
|
||||||
|
close(fd);
|
||||||
|
goto fail;
|
||||||
|
}
|
||||||
|
else {
|
||||||
kprintf("'%s' is not a "
|
kprintf("'%s' is not a "
|
||||||
# ifdef __LP64__
|
# ifdef __LP64__
|
||||||
"64"
|
"64"
|
||||||
|
@ -1902,8 +1934,9 @@ fill_lines(int num_traces, void **traces, int check_debuglink,
|
||||||
close(fd);
|
close(fd);
|
||||||
goto fail;
|
goto fail;
|
||||||
}
|
}
|
||||||
|
found_mach_header:
|
||||||
|
p += sizeof(*header);
|
||||||
|
|
||||||
p = file + sizeof(*header);
|
|
||||||
for (uint32_t i = 0; i < (uint32_t)header->ncmds; i++) {
|
for (uint32_t i = 0; i < (uint32_t)header->ncmds; i++) {
|
||||||
struct load_command *lcmd = (struct load_command *)p;
|
struct load_command *lcmd = (struct load_command *)p;
|
||||||
switch (lcmd->cmd) {
|
switch (lcmd->cmd) {
|
||||||
|
@ -1955,13 +1988,14 @@ fill_lines(int num_traces, void **traces, int check_debuglink,
|
||||||
for (j = 0; j < cmd->nsyms; j++) {
|
for (j = 0; j < cmd->nsyms; j++) {
|
||||||
uintptr_t symsize, d;
|
uintptr_t symsize, d;
|
||||||
struct LP(nlist) *e = &nl[j];
|
struct LP(nlist) *e = &nl[j];
|
||||||
|
/* kprintf("[%2d][%4d]: %02x/%x/%x: %s %llx\n", i, j, e->n_type,e->n_sect,e->n_desc,strtab+e->n_un.n_strx,e->n_value); */
|
||||||
if (e->n_type != N_FUN) continue;
|
if (e->n_type != N_FUN) continue;
|
||||||
if (e->n_sect) {
|
if (e->n_sect) {
|
||||||
saddr = (uintptr_t)e->n_value + obj->base_addr - obj->vmaddr;
|
saddr = (uintptr_t)e->n_value + obj->base_addr - obj->vmaddr;
|
||||||
sname = strtab + e->n_un.n_strx;
|
sname = strtab + e->n_un.n_strx;
|
||||||
|
/* kprintf("[%2d][%4d]: %02x/%x/%x: %s %llx\n", i, j, e->n_type,e->n_sect,e->n_desc,strtab+e->n_un.n_strx,e->n_value); */
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
/* kprintf("[%2d][%4d]: %02x/%x/%x: %s %llx\n", i, j, e->n_type,e->n_sect,e->n_desc,strtab+e->n_un.n_strx,e->n_value); */
|
|
||||||
for (int k = offset; k < num_traces; k++) {
|
for (int k = offset; k < num_traces; k++) {
|
||||||
d = (uintptr_t)traces[k] - saddr;
|
d = (uintptr_t)traces[k] - saddr;
|
||||||
symsize = e->n_value;
|
symsize = e->n_value;
|
||||||
|
|
Loading…
Reference in a new issue