[前][次][番号順一覧][スレッド一覧]

ruby-changes:53680

From: naruse <ko1@a...>
Date: Wed, 21 Nov 2018 07:40:28 +0900 (JST)
Subject: [ruby-changes:53680] naruse:r65896 (trunk): Support Universal Binary for macOS

naruse	2018-11-21 07:40:20 +0900 (Wed, 21 Nov 2018)

  New Revision: 65896

  https://svn.ruby-lang.org/cgi-bin/viewvc.cgi?view=revision&revision=65896

  Log:
    Support Universal Binary for macOS

  Modified files:
    trunk/addr2line.c
Index: addr2line.c
===================================================================
--- addr2line.c	(revision 65895)
+++ addr2line.c	(revision 65896)
@@ -66,6 +66,8 @@ void *alloca(); https://github.com/ruby/ruby/blob/trunk/addr2line.c#L66
 #endif
 
 #ifdef HAVE_MACH_O_LOADER_H
+# include <mach-o/fat.h>
+# include <mach-o/ldsyms.h>
 # include <mach-o/loader.h>
 # include <mach-o/nlist.h>
 # include <mach-o/stab.h>
@@ -1829,7 +1831,7 @@ fill_lines(int num_traces, void **traces https://github.com/ruby/ruby/blob/trunk/addr2line.c#L1831
 # endif
     int fd;
     off_t filesize;
-    char *file, *p;
+    char *file, *p = NULL;
     obj_info_t *obj = *objp;
     struct LP(mach_header) *header;
     uintptr_t dladdr_fbase = 0;
@@ -1890,8 +1892,38 @@ fill_lines(int num_traces, void **traces https://github.com/ruby/ruby/blob/trunk/addr2line.c#L1892
     obj->mapped_size = (size_t)filesize;
 
     header = (struct LP(mach_header) *)file;
-    if (header->magic != LP(MH_MAGIC)) {
-        /* TODO: universal binaries */
+    if (header->magic == LP(MH_MAGIC)) {
+        /* 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 "
 # ifdef __LP64__
                 "64"
@@ -1902,8 +1934,9 @@ fill_lines(int num_traces, void **traces https://github.com/ruby/ruby/blob/trunk/addr2line.c#L1934
         close(fd);
         goto fail;
     }
+found_mach_header:
+    p += sizeof(*header);
 
-    p = file + sizeof(*header);
     for (uint32_t i = 0; i < (uint32_t)header->ncmds; i++) {
         struct load_command *lcmd = (struct load_command *)p;
         switch (lcmd->cmd) {
@@ -1955,13 +1988,14 @@ fill_lines(int num_traces, void **traces https://github.com/ruby/ruby/blob/trunk/addr2line.c#L1988
                 for (j = 0; j < cmd->nsyms; j++) {
                     uintptr_t symsize, d;
                     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_sect) {
                         saddr = (uintptr_t)e->n_value + obj->base_addr - obj->vmaddr;
                         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;
                     }
-                    /* 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++) {
                         d = (uintptr_t)traces[k] - saddr;
                         symsize = e->n_value;

--
ML: ruby-changes@q...
Info: http://www.atdot.net/~ko1/quickml/

[前][次][番号順一覧][スレッド一覧]