rbdc 1.0.0 → 1.1.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- checksums.yaml +5 -5
 - data/dyncall/CMakeLists.txt +3 -3
 - data/dyncall/ChangeLog +33 -0
 - data/dyncall/ChangeLog.orig +274 -0
 - data/dyncall/LICENSE +1 -1
 - data/dyncall/README +3 -5
 - data/dyncall/ToDo +27 -18
 - data/dyncall/ToDo.orig +201 -0
 - data/dyncall/autovar/autovar_ARCH.h +1 -1
 - data/dyncall/buildsys/vs2005/vs2005.sln +0 -9
 - data/dyncall/cconv.lang +36 -0
 - data/dyncall/configure +17 -9
 - data/dyncall/configure.bat +1 -1
 - data/dyncall/dyncall/dyncall.h +2 -1
 - data/dyncall/dyncall/dyncall_call.S +9 -1
 - data/dyncall/dyncall/dyncall_call_mips_n32.S +192 -0
 - data/dyncall/dyncall/dyncall_call_mips_n64.S +197 -0
 - data/dyncall/dyncall/dyncall_call_mips_n64.h +2 -0
 - data/dyncall/dyncall/{dyncall_call_mips_o32_gas.s → dyncall_call_mips_o32.S} +44 -42
 - data/dyncall/dyncall/dyncall_call_mips_o32.h +8 -3
 - data/dyncall/dyncall/dyncall_call_ppc32.S +3 -1
 - data/dyncall/dyncall/dyncall_call_ppc32.h +4 -3
 - data/dyncall/dyncall/dyncall_call_ppc64.S +1 -1
 - data/dyncall/dyncall/dyncall_call_ppc64.h +3 -0
 - data/dyncall/dyncall/dyncall_call_x64.S +27 -2
 - data/dyncall/dyncall/dyncall_call_x64.h +2 -1
 - data/dyncall/dyncall/dyncall_call_x64_generic_masm.asm +13 -2
 - data/dyncall/dyncall/dyncall_call_x86.S +6 -6
 - data/dyncall/dyncall/dyncall_call_x86.h +7 -7
 - data/dyncall/dyncall/dyncall_call_x86_generic_masm.asm +6 -7
 - data/dyncall/dyncall/dyncall_callvm_mips_n64.c +27 -9
 - data/dyncall/dyncall/dyncall_callvm_mips_o32.c +38 -31
 - data/dyncall/dyncall/dyncall_callvm_mips_o32.c.orig +247 -0
 - data/dyncall/dyncall/dyncall_callvm_x64.c +57 -3
 - data/dyncall/dyncall/dyncall_callvm_x86.c +32 -32
 - data/dyncall/dyncall/dyncall_macros.h +11 -8
 - data/dyncall/dyncall/dyncall_struct.c +12 -6
 - data/dyncall/dyncall/dyncall_struct.h +1 -1
 - data/dyncall/dyncall/dyncall_vector.c +13 -12
 - data/dyncall/dyncall/dyncall_vector.c.orig +53 -0
 - data/dyncall/dyncall/gen-masm.sh +4 -5
 - data/dyncall/dyncallback/dyncall_args_mips.h +24 -6
 - data/dyncall/dyncallback/dyncall_args_mips64.c +3 -3
 - data/dyncall/dyncallback/dyncall_args_mips_o32.c +19 -6
 - data/dyncall/dyncallback/dyncall_callback_arch.S +11 -1
 - data/dyncall/dyncallback/{dyncall_callback_mips_n32_gas.s → dyncall_callback_mips_n32.S} +1 -1
 - data/dyncall/dyncallback/{dyncall_callback_mips_n64_gas.s → dyncall_callback_mips_n64.S} +39 -25
 - data/dyncall/dyncallback/{dyncall_callback_mips_o32_gas.s → dyncall_callback_mips_o32.S} +29 -13
 - data/dyncall/dyncallback/dyncall_callback_x86_masm.asm +0 -1
 - data/dyncall/dyncallback/dyncall_thunk.h +1 -1
 - data/dyncall/dyncallback/gen-masm.sh +3 -5
 - data/dyncall/dynload/dynload.3 +16 -4
 - data/dyncall/dynload/dynload_unix.c +101 -53
 - data/dyncall/dynload/dynload_windows.c +76 -3
 - data/dyncall/portasm/README.txt +1 -1
 - data/dyncall/portasm/gen-masm.sh +5 -1
 - metadata +14 -13
 - data/dyncall/buildsys/vs2005/test_plain/test_plain.vcproj +0 -202
 - data/dyncall/dyncall/dyncall_call_mips_gas.S +0 -37
 - data/dyncall/dyncall/dyncall_call_mips_n32_gas.s +0 -192
 - data/dyncall/dyncall/dyncall_call_mips_n64_gas.s +0 -192
 - data/dyncall/dyncallback/dyncall_callback_mips_gas.S +0 -38
 
| 
         @@ -30,7 +30,7 @@ 
     | 
|
| 
       30 
30 
     | 
    
         
             
            DClonglong dcbArgLongLong(DCArgs* p)
         
     | 
| 
       31 
31 
     | 
    
         
             
            {
         
     | 
| 
       32 
32 
     | 
    
         
             
              DClonglong value;
         
     | 
| 
       33 
     | 
    
         
            -
              if(p->reg_count <  
     | 
| 
      
 33 
     | 
    
         
            +
              if(p->reg_count < DCARGS_MIPS_NUM_REGS)
         
     | 
| 
       34 
34 
     | 
    
         
             
                value = p->ireg_data[p->reg_count++];
         
     | 
| 
       35 
35 
     | 
    
         
             
              else {
         
     | 
| 
       36 
36 
     | 
    
         
             
                value = *((DClonglong*)p->stackptr);
         
     | 
| 
         @@ -54,7 +54,7 @@ DCpointer   dcbArgPointer(DCArgs* p) { return (DCpointer)dcbArgLongLong(p); } 
     | 
|
| 
       54 
54 
     | 
    
         
             
            DCdouble dcbArgDouble(DCArgs* p)
         
     | 
| 
       55 
55 
     | 
    
         
             
            {
         
     | 
| 
       56 
56 
     | 
    
         
             
              DCdouble result;
         
     | 
| 
       57 
     | 
    
         
            -
              if(p->reg_count <  
     | 
| 
      
 57 
     | 
    
         
            +
              if(p->reg_count < DCARGS_MIPS_NUM_REGS)
         
     | 
| 
       58 
58 
     | 
    
         
             
                result = p->freg_data[p->reg_count++];
         
     | 
| 
       59 
59 
     | 
    
         
             
              else {
         
     | 
| 
       60 
60 
     | 
    
         
             
                result = *((DCdouble*)p->stackptr);
         
     | 
| 
         @@ -65,7 +65,7 @@ DCdouble dcbArgDouble(DCArgs* p) 
     | 
|
| 
       65 
65 
     | 
    
         
             
            DCfloat dcbArgFloat(DCArgs* p)
         
     | 
| 
       66 
66 
     | 
    
         
             
            {
         
     | 
| 
       67 
67 
     | 
    
         
             
              DCfloat result;
         
     | 
| 
       68 
     | 
    
         
            -
              if(p->reg_count <  
     | 
| 
      
 68 
     | 
    
         
            +
              if(p->reg_count < DCARGS_MIPS_NUM_REGS) {
         
     | 
| 
       69 
69 
     | 
    
         
             
                result = ((DCfloat*)&p->freg_data[p->reg_count++])
         
     | 
| 
       70 
70 
     | 
    
         
             
            #if defined(DC__Endian_LITTLE)
         
     | 
| 
       71 
71 
     | 
    
         
             
                  [0];
         
     | 
| 
         @@ -29,7 +29,12 @@ 
     | 
|
| 
       29 
29 
     | 
    
         
             
            DCint dcbArgInt(DCArgs* p)
         
     | 
| 
       30 
30 
     | 
    
         
             
            {
         
     | 
| 
       31 
31 
     | 
    
         
             
              DCint value;
         
     | 
| 
       32 
     | 
    
         
            -
             
     | 
| 
      
 32 
     | 
    
         
            +
             
     | 
| 
      
 33 
     | 
    
         
            +
            #if defined(DC__ABI_HARDFLOAT)
         
     | 
| 
      
 34 
     | 
    
         
            +
              /* first int will disable float reg use. */
         
     | 
| 
      
 35 
     | 
    
         
            +
              p->freg_count = 2;
         
     | 
| 
      
 36 
     | 
    
         
            +
            #endif /* DC__ABI_HARDFLOAT */
         
     | 
| 
      
 37 
     | 
    
         
            +
             
     | 
| 
       33 
38 
     | 
    
         
             
              value = *((int*)p->stackptr);
         
     | 
| 
       34 
39 
     | 
    
         
             
              p->stackptr += sizeof(int);
         
     | 
| 
       35 
40 
     | 
    
         
             
              return value;
         
     | 
| 
         @@ -63,19 +68,23 @@ DCpointer   dcbArgPointer(DCArgs* p) { return (DCpointer)dcbArgUInt(p); } 
     | 
|
| 
       63 
68 
     | 
    
         
             
            DCfloat dcbArgFloat(DCArgs* p)
         
     | 
| 
       64 
69 
     | 
    
         
             
            {
         
     | 
| 
       65 
70 
     | 
    
         
             
              DCfloat result;
         
     | 
| 
      
 71 
     | 
    
         
            +
             
     | 
| 
      
 72 
     | 
    
         
            +
            #if defined(DC__ABI_HARDFLOAT)
         
     | 
| 
       66 
73 
     | 
    
         
             
              if(p->freg_count < 2) {
         
     | 
| 
       67 
74 
     | 
    
         
             
            	/* Stored float regs (max 2) are always 8b aligned. The way we look them up, */
         
     | 
| 
       68 
75 
     | 
    
         
             
            	/* relative to a diverging p->stackptr, we need consider this. Only works    */
         
     | 
| 
       69 
76 
     | 
    
         
             
            	/* with up to two float args, which is all we need. Hacky, but saves us      */
         
     | 
| 
       70 
77 
     | 
    
         
             
            	/* from one more variable and more bookkeeping in DCArgs.                    */
         
     | 
| 
       71 
78 
     | 
    
         
             
                result = ((DCfloat*)(p->stackptr + ((int)p->stackptr & 4)) - 4) /* '-4' b/c those regs are stored right before the args */
         
     | 
| 
       72 
     | 
    
         
            -
            #if defined(DC__Endian_LITTLE)
         
     | 
| 
      
 79 
     | 
    
         
            +
            # if defined(DC__Endian_LITTLE)
         
     | 
| 
       73 
80 
     | 
    
         
             
                  [0];
         
     | 
| 
       74 
     | 
    
         
            -
            #else
         
     | 
| 
      
 81 
     | 
    
         
            +
            # else
         
     | 
| 
       75 
82 
     | 
    
         
             
                  [1];
         
     | 
| 
       76 
     | 
    
         
            -
            #endif
         
     | 
| 
      
 83 
     | 
    
         
            +
            # endif
         
     | 
| 
       77 
84 
     | 
    
         
             
            	++p->freg_count;
         
     | 
| 
       78 
     | 
    
         
            -
              } else 
     | 
| 
      
 85 
     | 
    
         
            +
              } else
         
     | 
| 
      
 86 
     | 
    
         
            +
            #endif /* DC__ABI_HARDFLOAT */
         
     | 
| 
      
 87 
     | 
    
         
            +
              {
         
     | 
| 
       79 
88 
     | 
    
         
             
                result = *((DCfloat*)p->stackptr);
         
     | 
| 
       80 
89 
     | 
    
         
             
              }
         
     | 
| 
       81 
90 
     | 
    
         
             
              p->stackptr += sizeof(DCfloat);
         
     | 
| 
         @@ -88,12 +97,16 @@ DCdouble dcbArgDouble(DCArgs* p) 
     | 
|
| 
       88 
97 
     | 
    
         
             
                DCfloat f[2];
         
     | 
| 
       89 
98 
     | 
    
         
             
              } d;
         
     | 
| 
       90 
99 
     | 
    
         
             
              p->stackptr += ((int)p->stackptr & 4); /* Skip one slot if not aligned. */
         
     | 
| 
      
 100 
     | 
    
         
            +
             
     | 
| 
      
 101 
     | 
    
         
            +
            #if defined(DC__ABI_HARDFLOAT)
         
     | 
| 
       91 
102 
     | 
    
         
             
              if(p->freg_count < 2) {
         
     | 
| 
       92 
103 
     | 
    
         
             
                /*result = *((DCdouble*)p->stackptr-2); this changes the value, slightly*/
         
     | 
| 
       93 
104 
     | 
    
         
             
                d.f[0] = ((DCfloat*)p->stackptr-4)[0]; /* '-4' b/c those regs are stored right before the args */
         
     | 
| 
       94 
105 
     | 
    
         
             
                d.f[1] = ((DCfloat*)p->stackptr-4)[1];
         
     | 
| 
       95 
106 
     | 
    
         
             
                ++p->freg_count;
         
     | 
| 
       96 
     | 
    
         
            -
              } else 
     | 
| 
      
 107 
     | 
    
         
            +
              } else
         
     | 
| 
      
 108 
     | 
    
         
            +
            #endif /* DC__ABI_HARDFLOAT */
         
     | 
| 
      
 109 
     | 
    
         
            +
              {
         
     | 
| 
       97 
110 
     | 
    
         
             
                /*result = *((DCdouble*)p->stackptr); this changes the value, slightly*/
         
     | 
| 
       98 
111 
     | 
    
         
             
                d.f[0] = ((DCfloat*)p->stackptr)[0];
         
     | 
| 
       99 
112 
     | 
    
         
             
                d.f[1] = ((DCfloat*)p->stackptr)[1];
         
     | 
| 
         @@ -65,7 +65,17 @@ 
     | 
|
| 
       65 
65 
     | 
    
         
             
            #  elif defined(DC__Arch_PPC64)
         
     | 
| 
       66 
66 
     | 
    
         
             
            #    include "dyncall_callback_ppc64.S"
         
     | 
| 
       67 
67 
     | 
    
         
             
            #  elif defined(DC__Arch_MIPS) || defined(DC__Arch_MIPS64)
         
     | 
| 
       68 
     | 
    
         
            -
            #     
     | 
| 
      
 68 
     | 
    
         
            +
            #    if defined(DC__ABI_MIPS_O32)
         
     | 
| 
      
 69 
     | 
    
         
            +
            #      include "dyncall_callback_mips_o32.S"
         
     | 
| 
      
 70 
     | 
    
         
            +
            #    elif defined(DC__ABI_MIPS_N64)
         
     | 
| 
      
 71 
     | 
    
         
            +
            #      include "dyncall_callback_mips_n64.S"
         
     | 
| 
      
 72 
     | 
    
         
            +
            #    elif defined(DC__ABI_MIPS_N32)
         
     | 
| 
      
 73 
     | 
    
         
            +
            #      include "dyncall_callback_mips_n32.S"
         
     | 
| 
      
 74 
     | 
    
         
            +
            #    elif defined(DC__ABI_MIPS_EABI)
         
     | 
| 
      
 75 
     | 
    
         
            +
            #      include "dyncall_callback_mips_eabi_gas.s"
         
     | 
| 
      
 76 
     | 
    
         
            +
            #    else
         
     | 
| 
      
 77 
     | 
    
         
            +
            #      error Unknown MIPS ABI.
         
     | 
| 
      
 78 
     | 
    
         
            +
            #    endif
         
     | 
| 
       69 
79 
     | 
    
         
             
            #  elif defined(DC__Arch_ARM_ARM)
         
     | 
| 
       70 
80 
     | 
    
         
             
            #    include "dyncall_callback_arm32_arm_gas.S"
         
     | 
| 
       71 
81 
     | 
    
         
             
            #  elif defined(DC__Arch_ARM_THUMB)
         
     | 
| 
         @@ -2,11 +2,11 @@ 
     | 
|
| 
       2 
2 
     | 
    
         | 
| 
       3 
3 
     | 
    
         
             
             Package: dyncall
         
     | 
| 
       4 
4 
     | 
    
         
             
             Library: dyncallback
         
     | 
| 
       5 
     | 
    
         
            -
             File: dyncallback/ 
     | 
| 
      
 5 
     | 
    
         
            +
             File: dyncallback/dyncall_callback_mips_n64.S
         
     | 
| 
       6 
6 
     | 
    
         
             
             Description: Callback Thunk - Implementation for mips64 n64
         
     | 
| 
       7 
7 
     | 
    
         
             
             License:
         
     | 
| 
       8 
8 
     | 
    
         | 
| 
       9 
     | 
    
         
            -
               Copyright (c) 2016 Tassilo Philipp <tphilipp@potion-studios.com>
         
     | 
| 
      
 9 
     | 
    
         
            +
               Copyright (c) 2016-2018 Tassilo Philipp <tphilipp@potion-studios.com>
         
     | 
| 
       10 
10 
     | 
    
         | 
| 
       11 
11 
     | 
    
         
             
               Permission to use, copy, modify, and distribute this software for any
         
     | 
| 
       12 
12 
     | 
    
         
             
               purpose with or without fee is hereby granted, provided that the above
         
     | 
| 
         @@ -28,6 +28,18 @@ 
     | 
|
| 
       28 
28 
     | 
    
         
             
            		$t8+64 -> userdata
         
     | 
| 
       29 
29 
     | 
    
         
             
            	*/
         
     | 
| 
       30 
30 
     | 
    
         | 
| 
      
 31 
     | 
    
         
            +
            /* Frame size is 160b for hard- and 128b for soft-float, as follows: */
         
     | 
| 
      
 32 
     | 
    
         
            +
            /*   DCargs(fregs:64? + iregs:64 + regcnts:8 + sp:8) + rval:8 + ra:8 */
         
     | 
| 
      
 33 
     | 
    
         
            +
            #if defined(DC__ABI_HARDFLOAT)
         
     | 
| 
      
 34 
     | 
    
         
            +
            SP_SP = 160
         
     | 
| 
      
 35 
     | 
    
         
            +
            #else
         
     | 
| 
      
 36 
     | 
    
         
            +
            SP_SP = 96
         
     | 
| 
      
 37 
     | 
    
         
            +
            #endif
         
     | 
| 
      
 38 
     | 
    
         
            +
            SP_LR     = SP_SP-8
         
     | 
| 
      
 39 
     | 
    
         
            +
            SP_RVAL   = SP_SP-16
         
     | 
| 
      
 40 
     | 
    
         
            +
            SP_ARG_SP = SP_SP-24
         
     | 
| 
      
 41 
     | 
    
         
            +
            SP_ARG_RC = SP_SP-32
         
     | 
| 
      
 42 
     | 
    
         
            +
             
     | 
| 
       31 
43 
     | 
    
         
             
            	.section .mdebug.abi64
         
     | 
| 
       32 
44 
     | 
    
         
             
            	.previous
         
     | 
| 
       33 
45 
     | 
    
         
             
            	.abicalls
         
     | 
| 
         @@ -39,17 +51,15 @@ dcCallbackThunkEntry: 
     | 
|
| 
       39 
51 
     | 
    
         
             
            	.set    noreorder
         
     | 
| 
       40 
52 
     | 
    
         | 
| 
       41 
53 
     | 
    
         
             
            	/* Prolog. */
         
     | 
| 
       42 
     | 
    
         
            -
            	 
     | 
| 
       43 
     | 
    
         
            -
            	 
     | 
| 
       44 
     | 
    
         
            -
            	daddiu $sp, $sp, -160 /* open frame */
         
     | 
| 
       45 
     | 
    
         
            -
            	sd     $ra, 152($sp)  /* save link register */
         
     | 
| 
      
 54 
     | 
    
         
            +
            	daddiu $sp, $sp, -SP_SP   /* open frame */
         
     | 
| 
      
 55 
     | 
    
         
            +
            	sd     $ra, SP_LR($sp)    /* save link register */
         
     | 
| 
       46 
56 
     | 
    
         | 
| 
       47 
     | 
    
         
            -
            	.frame $fp, 
     | 
| 
      
 57 
     | 
    
         
            +
            	.frame $fp,SP_SP,$31  /* specify our frame: fp,size,lr; creates virt $fp */
         
     | 
| 
       48 
58 
     | 
    
         
             
            	                      /* code below doesn't use $fp though, as n/a with -O1 */
         
     | 
| 
       49 
59 
     | 
    
         
             
            	/* Init return value */
         
     | 
| 
       50 
     | 
    
         
            -
            	sd $zero,  
     | 
| 
      
 60 
     | 
    
         
            +
            	sd $zero, SP_RVAL($sp)
         
     | 
| 
       51 
61 
     | 
    
         | 
| 
       52 
     | 
    
         
            -
            	/* Store  
     | 
| 
      
 62 
     | 
    
         
            +
            	/* Store reg args where our DCargs member arrays are, in local stack area */
         
     | 
| 
       53 
63 
     | 
    
         
             
            	sd  $4,     0($sp)
         
     | 
| 
       54 
64 
     | 
    
         
             
            	sd  $5,     8($sp)
         
     | 
| 
       55 
65 
     | 
    
         
             
            	sd  $6,    16($sp)
         
     | 
| 
         @@ -58,6 +68,7 @@ dcCallbackThunkEntry: 
     | 
|
| 
       58 
68 
     | 
    
         
             
            	sd  $9,    40($sp)
         
     | 
| 
       59 
69 
     | 
    
         
             
            	sd $10,    48($sp)
         
     | 
| 
       60 
70 
     | 
    
         
             
            	sd $11,    56($sp)
         
     | 
| 
      
 71 
     | 
    
         
            +
            #if defined(DC__ABI_HARDFLOAT)
         
     | 
| 
       61 
72 
     | 
    
         
             
            	s.d $f12,  64($sp)
         
     | 
| 
       62 
73 
     | 
    
         
             
            	s.d $f13,  72($sp)
         
     | 
| 
       63 
74 
     | 
    
         
             
            	s.d $f14,  80($sp)
         
     | 
| 
         @@ -66,31 +77,34 @@ dcCallbackThunkEntry: 
     | 
|
| 
       66 
77 
     | 
    
         
             
            	s.d $f17, 104($sp)
         
     | 
| 
       67 
78 
     | 
    
         
             
            	s.d $f18, 112($sp)
         
     | 
| 
       68 
79 
     | 
    
         
             
            	s.d $f19, 120($sp)
         
     | 
| 
      
 80 
     | 
    
         
            +
            #endif
         
     | 
| 
       69 
81 
     | 
    
         | 
| 
       70 
82 
     | 
    
         
             
            	/* Init DCarg's reg_counts and stackptr. */
         
     | 
| 
       71 
     | 
    
         
            -
            	sd 
     | 
| 
       72 
     | 
    
         
            -
            	daddiu $4, $sp,  
     | 
| 
       73 
     | 
    
         
            -
            	sd     $4,  
     | 
| 
      
 83 
     | 
    
         
            +
            	sd  $zero, SP_ARG_RC($sp)   /* reg_count */
         
     | 
| 
      
 84 
     | 
    
         
            +
            	daddiu $4, $sp, SP_SP
         
     | 
| 
      
 85 
     | 
    
         
            +
            	sd     $4, SP_ARG_SP($sp)   /* stackptr */
         
     | 
| 
       74 
86 
     | 
    
         | 
| 
       75 
87 
     | 
    
         
             
            	/* Prepare callback handler call. */
         
     | 
| 
       76 
     | 
    
         
            -
            	move   $4, $24 
     | 
| 
       77 
     | 
    
         
            -
            	move   $5, $sp 
     | 
| 
       78 
     | 
    
         
            -
            	daddiu $6, $sp,  
     | 
| 
       79 
     | 
    
         
            -
            	ld     $7, 64($24) 
     | 
| 
      
 88 
     | 
    
         
            +
            	move   $4, $24          /* Param 0 = DCCallback*, $24/$t8 holds DCThunk* */
         
     | 
| 
      
 89 
     | 
    
         
            +
            	move   $5, $sp          /* Param 1 = ptr to where DCArgs* is stored */
         
     | 
| 
      
 90 
     | 
    
         
            +
            	daddiu $6, $sp, SP_RVAL /* Param 2 = results ptr to 8b of local stack data */
         
     | 
| 
      
 91 
     | 
    
         
            +
            	ld     $7, 64($24)      /* Param 3 = userdata pointer */
         
     | 
| 
       80 
92 
     | 
    
         | 
| 
       81 
     | 
    
         
            -
            	ld     $25, 56($24) 
     | 
| 
       82 
     | 
    
         
            -
            	jalr   $25 
     | 
| 
       83 
     | 
    
         
            -
            	nop 
     | 
| 
      
 93 
     | 
    
         
            +
            	ld     $25, 56($24)     /* store handler entry in $25/$t9, required for PIC */
         
     | 
| 
      
 94 
     | 
    
         
            +
            	jalr   $25              /* jump */
         
     | 
| 
      
 95 
     | 
    
         
            +
            	nop                     /* branch delay nop */
         
     | 
| 
       84 
96 
     | 
    
         | 
| 
       85 
97 
     | 
    
         
             
            	/* Copy result in corresponding registers $2-$3 ($v0-$v1) and $f0 */
         
     | 
| 
       86 
     | 
    
         
            -
            	ld     $2,  
     | 
| 
       87 
     | 
    
         
            -
             
     | 
| 
      
 98 
     | 
    
         
            +
            	ld     $2, SP_RVAL($sp)   /* note: ignoring 2nd possible retval in $3, here */
         
     | 
| 
      
 99 
     | 
    
         
            +
            #if defined(DC__ABI_HARDFLOAT)
         
     | 
| 
      
 100 
     | 
    
         
            +
            	l.d    $f0, SP_RVAL($sp)
         
     | 
| 
      
 101 
     | 
    
         
            +
            #endif
         
     | 
| 
       88 
102 
     | 
    
         | 
| 
       89 
103 
     | 
    
         
             
            	/* Epilog. Tear down frame and return. */
         
     | 
| 
       90 
     | 
    
         
            -
            	ld 
     | 
| 
       91 
     | 
    
         
            -
            	daddiu $sp, $sp,  
     | 
| 
       92 
     | 
    
         
            -
            	j 
     | 
| 
       93 
     | 
    
         
            -
            	nop 
     | 
| 
      
 104 
     | 
    
         
            +
            	ld     $ra, SP_LR($sp)  /* restore return address */
         
     | 
| 
      
 105 
     | 
    
         
            +
            	daddiu $sp, $sp, SP_SP  /* close frame */
         
     | 
| 
      
 106 
     | 
    
         
            +
            	j      $ra              /* return */
         
     | 
| 
      
 107 
     | 
    
         
            +
            	nop                     /* branch delay nop */
         
     | 
| 
       94 
108 
     | 
    
         | 
| 
       95 
109 
     | 
    
         
             
            	.set    reorder
         
     | 
| 
       96 
110 
     | 
    
         
             
            	.end    dcCallbackThunkEntry
         
     | 
| 
         @@ -2,7 +2,7 @@ 
     | 
|
| 
       2 
2 
     | 
    
         | 
| 
       3 
3 
     | 
    
         
             
             Package: dyncall
         
     | 
| 
       4 
4 
     | 
    
         
             
             Library: dyncallback
         
     | 
| 
       5 
     | 
    
         
            -
             File: dyncallback/ 
     | 
| 
      
 5 
     | 
    
         
            +
             File: dyncallback/dyncall_callback_mips_o32.S
         
     | 
| 
       6 
6 
     | 
    
         
             
             Description: Callback Thunk - Implementation mips32 o32
         
     | 
| 
       7 
7 
     | 
    
         
             
             License:
         
     | 
| 
       8 
8 
     | 
    
         | 
| 
         @@ -60,18 +60,22 @@ dcCallbackThunkEntry: 
     | 
|
| 
       60 
60 
     | 
    
         
             
            	/* For $4-$7 ($a0-$a3), use dedicated spill area (caller doesn't spill, but */
         
     | 
| 
       61 
61 
     | 
    
         
             
            	/* provides it at end of _caller's_ frame, so $fp points right to it).      */
         
     | 
| 
       62 
62 
     | 
    
         
             
            	/* For $f12 and $f14 use our space (in local data), which is adjacent.      */
         
     | 
| 
       63 
     | 
    
         
            -
             
     | 
| 
       64 
     | 
    
         
            -
            	s.d $ 
     | 
| 
       65 
     | 
    
         
            -
            	 
     | 
| 
       66 
     | 
    
         
            -
             
     | 
| 
       67 
     | 
    
         
            -
            	sw $ 
     | 
| 
       68 
     | 
    
         
            -
            	sw $ 
     | 
| 
      
 63 
     | 
    
         
            +
            #if defined(DC__ABI_HARDFLOAT)
         
     | 
| 
      
 64 
     | 
    
         
            +
            	s.d $f12, 40($sp)   /* -16($fp) */
         
     | 
| 
      
 65 
     | 
    
         
            +
            	s.d $f14, 48($sp)   /*  -8($fp) */
         
     | 
| 
      
 66 
     | 
    
         
            +
            #endif /* DC__ABI_HARDFLOAT */
         
     | 
| 
      
 67 
     | 
    
         
            +
            	sw $4,    56($sp)   /*   0($fp) */
         
     | 
| 
      
 68 
     | 
    
         
            +
            	sw $5,    60($sp)   /*   4($fp) */
         
     | 
| 
      
 69 
     | 
    
         
            +
            	sw $6,    64($sp)   /*   8($fp) */
         
     | 
| 
      
 70 
     | 
    
         
            +
            	sw $7,    68($sp)   /*  12($fp) */
         
     | 
| 
       69 
71 
     | 
    
         | 
| 
       70 
72 
     | 
    
         
             
            	/* Init DCArg, which contains reg_count and stackptr* to the args. Point  */
         
     | 
| 
       71 
73 
     | 
    
         
             
            	/* stackptr to the area where the non-float args start (which is at $fp). */
         
     | 
| 
       72 
     | 
    
         
            -
            	addiu $4, $sp, 56 
     | 
| 
       73 
     | 
    
         
            -
            	sw    $4, 28($sp)  
     | 
| 
       74 
     | 
    
         
            -
             
     | 
| 
      
 74 
     | 
    
         
            +
            	addiu $4, $sp, 56   /* <- non-$fp replacement for: */
         
     | 
| 
      
 75 
     | 
    
         
            +
            	sw    $4, 28($sp)   /* <-   sw $fp, 28($sp)        */
         
     | 
| 
      
 76 
     | 
    
         
            +
            #if defined(DC__ABI_HARDFLOAT)
         
     | 
| 
      
 77 
     | 
    
         
            +
            	sw $zero, 24($sp)   /* init num float-regs (unused for soft-float) */
         
     | 
| 
      
 78 
     | 
    
         
            +
            #endif /* DC__ABI_HARDFLOAT */
         
     | 
| 
       75 
79 
     | 
    
         | 
| 
       76 
80 
     | 
    
         
             
            	/* Prepare callback handler call. */
         
     | 
| 
       77 
81 
     | 
    
         
             
            	move  $4, $12       /* Param 0 = DCCallback*, $12 ($t4) holds pointer to thunk */
         
     | 
| 
         @@ -83,10 +87,22 @@ dcCallbackThunkEntry: 
     | 
|
| 
       83 
87 
     | 
    
         
             
            	jalr  $25           /* jump */
         
     | 
| 
       84 
88 
     | 
    
         
             
            	nop                 /* branch delay nop */
         
     | 
| 
       85 
89 
     | 
    
         | 
| 
       86 
     | 
    
         
            -
            	/* Copy result  
     | 
| 
       87 
     | 
    
         
            -
            	 
     | 
| 
       88 
     | 
    
         
            -
            	 
     | 
| 
      
 90 
     | 
    
         
            +
            	/* Copy result to corresponding registers */
         
     | 
| 
      
 91 
     | 
    
         
            +
            	/* Handle single precision soft-float retvals differently on big-endian */
         
     | 
| 
      
 92 
     | 
    
         
            +
            	/* targets as they are right-justified in their 8b stack lots           */
         
     | 
| 
      
 93 
     | 
    
         
            +
            #if !defined(DC__ABI_HARDFLOAT) && defined(DC__Endian_BIG)
         
     | 
| 
      
 94 
     | 
    
         
            +
            	xori  $4, $2, 'f'   /* $4 = 0 if cb-handler returned 'f' in $2 */
         
     | 
| 
      
 95 
     | 
    
         
            +
            #endif
         
     | 
| 
      
 96 
     | 
    
         
            +
            	lw    $2, 32($sp)
         
     | 
| 
      
 97 
     | 
    
         
            +
            	lw    $3, 36($sp)
         
     | 
| 
      
 98 
     | 
    
         
            +
            #if defined(DC__ABI_HARDFLOAT)
         
     | 
| 
       89 
99 
     | 
    
         
             
            	l.d   $f0, 32($sp)
         
     | 
| 
      
 100 
     | 
    
         
            +
            #elif defined(DC__Endian_BIG)
         
     | 
| 
      
 101 
     | 
    
         
            +
            	bgtz  $4, .nonf32r  /* if no 'f' returned, $2 and $3 are good */
         
     | 
| 
      
 102 
     | 
    
         
            +
            	nop                 /* branch delay nop */
         
     | 
| 
      
 103 
     | 
    
         
            +
            	move  $2, $3
         
     | 
| 
      
 104 
     | 
    
         
            +
            .nonf32r:
         
     | 
| 
      
 105 
     | 
    
         
            +
            #endif /* DC__ABI_HARDFLOAT */
         
     | 
| 
       90 
106 
     | 
    
         | 
| 
       91 
107 
     | 
    
         
             
            	/* Epilog. Tear down frame and return. */
         
     | 
| 
       92 
108 
     | 
    
         
             
            	lw    $ra, 20($sp)  /* restore return address */
         
     | 
| 
         @@ -1,8 +1,6 @@ 
     | 
|
| 
       1 
1 
     | 
    
         
             
            #!/bin/sh
         
     | 
| 
      
 2 
     | 
    
         
            +
            cd `dirname $0`
         
     | 
| 
       2 
3 
     | 
    
         | 
| 
       3 
     | 
    
         
            -
             
     | 
| 
       4 
     | 
    
         
            -
             
     | 
| 
       5 
     | 
    
         
            -
            printf "; auto-generated by `basename $0`\r\n" >dyncall_callback_x64_masm.asm
         
     | 
| 
       6 
     | 
    
         
            -
            gcc -E -P -DGEN_MASM dyncall_callback_x86.S | awk '{printf "%s\r\n", $0}' >> dyncall_callback_x86_masm.asm
         
     | 
| 
       7 
     | 
    
         
            -
            gcc -E -P -DGEN_MASM dyncall_callback_x64.S | awk '{printf "%s\r\n", $0}' >> dyncall_callback_x64_masm.asm
         
     | 
| 
      
 4 
     | 
    
         
            +
            ../portasm/gen-masm.sh dyncall_callback_x86 _masm
         
     | 
| 
      
 5 
     | 
    
         
            +
            ../portasm/gen-masm.sh dyncall_callback_x64 _masm
         
     | 
| 
       8 
6 
     | 
    
         | 
    
        data/dyncall/dynload/dynload.3
    CHANGED
    
    | 
         @@ -54,7 +54,9 @@ and 
     | 
|
| 
       54 
54 
     | 
    
         
             
            .Fn dlFindSymbol
         
     | 
| 
       55 
55 
     | 
    
         
             
            calls. Passing a null pointer for the
         
     | 
| 
       56 
56 
     | 
    
         
             
            .Ar libpath
         
     | 
| 
       57 
     | 
    
         
            -
            argument is valid, and returns a handle to the main executable of the calling code. Also, searching libraries in library paths (e.g. by just passing the library's leaf name) should work, however, they are OS specific.  
     | 
| 
      
 57 
     | 
    
         
            +
            argument is valid, and returns a handle to the main executable of the calling code. Also, searching libraries in library paths (e.g. by just passing the library's leaf name) should work, however, they are OS specific. The
         
     | 
| 
      
 58 
     | 
    
         
            +
            .Ar libPath
         
     | 
| 
      
 59 
     | 
    
         
            +
            argument is expected to be UTF-8 encoded. Returns a null pointer on error.
         
     | 
| 
       58 
60 
     | 
    
         
             
            .Pp
         
     | 
| 
       59 
61 
     | 
    
         
             
            .Fn dlFreeLibrary 
         
     | 
| 
       60 
62 
     | 
    
         
             
            frees the loaded library with handle
         
     | 
| 
         @@ -74,11 +76,13 @@ The parameter 
     | 
|
| 
       74 
76 
     | 
    
         
             
            .Ar sOut
         
     | 
| 
       75 
77 
     | 
    
         
             
            is a pointer to a buffer of size
         
     | 
| 
       76 
78 
     | 
    
         
             
            .Ar bufSize
         
     | 
| 
       77 
     | 
    
         
            -
            (in bytes), to hold the output string. The return value is the size of the buffer (in bytes) needed to hold the null-terminated string, or 0 if it can't be looked up. If
         
     | 
| 
      
 79 
     | 
    
         
            +
            (in bytes), to hold the output string (UTF-8 encoded). The return value is the size of the buffer (in bytes) needed to hold the null-terminated string, or 0 if it can't be looked up. If
         
     | 
| 
       78 
80 
     | 
    
         
             
            .Ar bufSize
         
     | 
| 
       79 
     | 
    
         
            -
            >= return value  
     | 
| 
      
 81 
     | 
    
         
            +
            >= return value >= 1, a null-terminted string with the path to the library should be in
         
     | 
| 
       80 
82 
     | 
    
         
             
            .Ar sOut .
         
     | 
| 
       81 
     | 
    
         
            -
            If it returns 0, the library name wasn't able to be found. Please note that this might happen in some rare cases, so make sure to always check.
         
     | 
| 
      
 83 
     | 
    
         
            +
            If it returns 0, the library name wasn't able to be found. Please note that this might happen in some rare cases, so make sure to always check. Passing a null pointer as
         
     | 
| 
      
 84 
     | 
    
         
            +
            .Ar pLib
         
     | 
| 
      
 85 
     | 
    
         
            +
            returns the path to the executable (not guaranteed to be absolute - if it isn't it's relative to the working directory the process was started in, not the current one).
         
     | 
| 
       82 
86 
     | 
    
         
             
            .Pp
         
     | 
| 
       83 
87 
     | 
    
         
             
            The dlSyms* functions can be used to iterate over symbols. Since they can be used on libraries that are not linked, they are made
         
     | 
| 
       84 
88 
     | 
    
         
             
            for symbol name lookups, not to get symbols' addresses. For that refer to
         
     | 
| 
         @@ -99,14 +103,22 @@ must point to a loaded symbol. 
     | 
|
| 
       99 
103 
     | 
    
         
             
            .Sh BUGS
         
     | 
| 
       100 
104 
     | 
    
         
             
            .Fn dlGetLibraryPath
         
     | 
| 
       101 
105 
     | 
    
         
             
            is not thread-safe on Darwin (macOS, iOS, ...) and OpenBSD.
         
     | 
| 
      
 106 
     | 
    
         
            +
            .Pp
         
     | 
| 
       102 
107 
     | 
    
         
             
            .Fn dlSymsInit
         
     | 
| 
       103 
108 
     | 
    
         
             
            is not thread-safe on Darwin.
         
     | 
| 
      
 109 
     | 
    
         
            +
            .Pp
         
     | 
| 
       104 
110 
     | 
    
         
             
            .Fn dlGetLibraryPath
         
     | 
| 
       105 
111 
     | 
    
         
             
            will not work on the following platforms when the library in question doesn't have the (default)
         
     | 
| 
       106 
112 
     | 
    
         
             
            .Fn _init
         
     | 
| 
       107 
113 
     | 
    
         
             
            and
         
     | 
| 
       108 
114 
     | 
    
         
             
            .Fn _fini
         
     | 
| 
       109 
115 
     | 
    
         
             
            symbols exported (rare, but possible): Haiku (all versions), OpenBSD < 3.7, NetBSD < 5.1, FreeBSD < 4.8
         
     | 
| 
      
 116 
     | 
    
         
            +
            .Pp
         
     | 
| 
      
 117 
     | 
    
         
            +
            Getting the executable's path by passing NULL in
         
     | 
| 
      
 118 
     | 
    
         
            +
            .Ar pLib
         
     | 
| 
      
 119 
     | 
    
         
            +
            to
         
     | 
| 
      
 120 
     | 
    
         
            +
            .Fn dlGetLibraryPath
         
     | 
| 
      
 121 
     | 
    
         
            +
            fails on the following platforms: Haiku (all versions), OpenBSD < 3.7, NetBSD < 5.1, FreeBSD < 4.8
         
     | 
| 
       110 
122 
     | 
    
         
             
            .Sh CONFORMING TO
         
     | 
| 
       111 
123 
     | 
    
         
             
            The dynload library conforms to c99.
         
     | 
| 
       112 
124 
     | 
    
         
             
            .Ed
         
     | 
| 
         @@ -38,7 +38,12 @@ 
     | 
|
| 
       38 
38 
     | 
    
         | 
| 
       39 
39 
     | 
    
         
             
            #include <string.h>
         
     | 
| 
       40 
40 
     | 
    
         | 
| 
       41 
     | 
    
         
            -
            #if defined(__GLIBC__) 
     | 
| 
      
 41 
     | 
    
         
            +
            #if defined(__GLIBC__)
         
     | 
| 
      
 42 
     | 
    
         
            +
            /* @@@ version check glibc more precisely... dl_iterate_phdr(): glibc ver >= 2.2.4*/
         
     | 
| 
      
 43 
     | 
    
         
            +
            #if (__GLIBC__ >= 2) && (__GLIBC_MINOR__ >= 3)
         
     | 
| 
      
 44 
     | 
    
         
            +
            #  define DL_USE_GLIBC_ITER_PHDR
         
     | 
| 
      
 45 
     | 
    
         
            +
            #endif
         
     | 
| 
      
 46 
     | 
    
         
            +
            /* to access dl_iterate_phdr(), and related w/ glibc */
         
     | 
| 
       42 
47 
     | 
    
         
             
            #  define _GNU_SOURCE
         
     | 
| 
       43 
48 
     | 
    
         
             
            #  define __USE_GNU
         
     | 
| 
       44 
49 
     | 
    
         
             
            #endif
         
     | 
| 
         @@ -69,32 +74,42 @@ void dlFreeLibrary(DLLib* pLib) 
     | 
|
| 
       69 
74 
     | 
    
         | 
| 
       70 
75 
     | 
    
         | 
| 
       71 
76 
     | 
    
         | 
| 
       72 
     | 
    
         
            -
            /* for dlopen-based dlGetLibraryPath impls below, prefer RTLD_NOLOAD  
     | 
| 
       73 
     | 
    
         
            -
             
     | 
| 
      
 77 
     | 
    
         
            +
            /* for dlopen-based dlGetLibraryPath impls below, prefer RTLD_NOLOAD that
         
     | 
| 
      
 78 
     | 
    
         
            +
             * merely checks lib names */
         
     | 
| 
       74 
79 
     | 
    
         
             
            #if defined(RTLD_NOLOAD)
         
     | 
| 
       75 
     | 
    
         
            -
            #  define RTLD_LIGHTEST RTLD_NOLOAD
         
     | 
| 
      
 80 
     | 
    
         
            +
            #  define RTLD_LIGHTEST RTLD_LAZY|RTLD_NOLOAD
         
     | 
| 
       76 
81 
     | 
    
         
             
            #else
         
     | 
| 
       77 
82 
     | 
    
         
             
            #  define RTLD_LIGHTEST RTLD_LAZY
         
     | 
| 
       78 
83 
     | 
    
         
             
            #endif
         
     | 
| 
       79 
84 
     | 
    
         | 
| 
       80 
85 
     | 
    
         | 
| 
       81 
     | 
    
         
            -
            /*  
     | 
| 
       82 
     | 
    
         
            -
             
     | 
| 
       83 
     | 
    
         
            -
             
     | 
| 
       84 
     | 
    
         
            -
             
     | 
| 
       85 
     | 
    
         
            -
             
     | 
| 
      
 86 
     | 
    
         
            +
            /* helper copying string if buffer big enough, returning length (without \0) */
         
     | 
| 
      
 87 
     | 
    
         
            +
            static int dl_strlen_strcpy(char* dst, const char* src, int dstSize)
         
     | 
| 
      
 88 
     | 
    
         
            +
            {
         
     | 
| 
      
 89 
     | 
    
         
            +
              int l = strlen(src);
         
     | 
| 
      
 90 
     | 
    
         
            +
              if(l < dstSize) /* l+'\0' <= bufSize */
         
     | 
| 
      
 91 
     | 
    
         
            +
                strcpy(dst, src);
         
     | 
| 
      
 92 
     | 
    
         
            +
              return l;
         
     | 
| 
      
 93 
     | 
    
         
            +
            }
         
     | 
| 
      
 94 
     | 
    
         
            +
             
     | 
| 
      
 95 
     | 
    
         
            +
            /* code for dlGetLibraryPath() is platform specific */
         
     | 
| 
      
 96 
     | 
    
         
            +
             
     | 
| 
      
 97 
     | 
    
         
            +
            /* if dlinfo() exists use it (except on glibc, where it exists since version
         
     | 
| 
      
 98 
     | 
    
         
            +
             * 2.3.3, but its implementation is dangerous, as no checks are done whether
         
     | 
| 
      
 99 
     | 
    
         
            +
             * the handle is valid, thus rendering the returned values useless) check for
         
     | 
| 
      
 100 
     | 
    
         
            +
             * RTLD_DI_LINKMAP which is a #define for dlinfo() on most supported targets,
         
     | 
| 
      
 101 
     | 
    
         
            +
             * or specifically check the OS (e.g. dlinfo() is originally from Solaris) */
         
     | 
| 
      
 102 
     | 
    
         
            +
            #if (defined(RTLD_DI_LINKMAP) || defined(OS_SunOS)) && !defined(DL_USE_GLIBC_ITER_PHDR)
         
     | 
| 
       86 
103 
     | 
    
         | 
| 
       87 
104 
     | 
    
         
             
            #include <link.h>
         
     | 
| 
       88 
105 
     | 
    
         | 
| 
       89 
106 
     | 
    
         
             
            int dlGetLibraryPath(DLLib* pLib, char* sOut, int bufSize)
         
     | 
| 
       90 
107 
     | 
    
         
             
            {
         
     | 
| 
       91 
     | 
    
         
            -
              struct link_map* p;
         
     | 
| 
      
 108 
     | 
    
         
            +
              struct link_map* p = NULL;
         
     | 
| 
       92 
109 
     | 
    
         
             
              int l = -1;
         
     | 
| 
       93 
     | 
    
         
            -
              if(dlinfo(pLib, RTLD_DI_LINKMAP, &p) == 0) 
     | 
| 
       94 
     | 
    
         
            -
                l =  
     | 
| 
       95 
     | 
    
         
            -
             
     | 
| 
       96 
     | 
    
         
            -
                  strcpy(sOut, p->l_name);
         
     | 
| 
       97 
     | 
    
         
            -
              }
         
     | 
| 
      
 110 
     | 
    
         
            +
              if(dlinfo(pLib ? pLib : RTLD_SELF, RTLD_DI_LINKMAP, &p) == 0)
         
     | 
| 
      
 111 
     | 
    
         
            +
                l = dl_strlen_strcpy(sOut, p->l_name, bufSize);
         
     | 
| 
      
 112 
     | 
    
         
            +
             
     | 
| 
       98 
113 
     | 
    
         
             
              return l+1; /* strlen + '\0' */
         
     | 
| 
       99 
114 
     | 
    
         
             
            }
         
     | 
| 
       100 
115 
     | 
    
         | 
| 
         @@ -110,26 +125,30 @@ int dlGetLibraryPath(DLLib* pLib, char* sOut, int bufSize) 
     | 
|
| 
       110 
125 
     | 
    
         
             
              uint32_t i;
         
     | 
| 
       111 
126 
     | 
    
         
             
              int l = -1;
         
     | 
| 
       112 
127 
     | 
    
         | 
| 
       113 
     | 
    
         
            -
              /* 
     | 
| 
       114 
     | 
    
         
            -
             
     | 
| 
       115 
     | 
    
         
            -
             
     | 
| 
       116 
     | 
    
         
            -
             
     | 
| 
       117 
     | 
    
         
            -
             
     | 
| 
       118 
     | 
    
         
            -
               
     | 
| 
       119 
     | 
    
         
            -
               
     | 
| 
       120 
     | 
    
         
            -
             
     | 
| 
       121 
     | 
    
         
            -
             
     | 
| 
       122 
     | 
    
         
            -
             
     | 
| 
       123 
     | 
    
         
            -
             
     | 
| 
       124 
     | 
    
         
            -
                 
     | 
| 
       125 
     | 
    
         
            -
             
     | 
| 
       126 
     | 
    
         
            -
                   
     | 
| 
       127 
     | 
    
         
            -
                   
     | 
| 
       128 
     | 
    
         
            -
                  if( 
     | 
| 
       129 
     | 
    
         
            -
                     
     | 
| 
       130 
     | 
    
         
            -
             
     | 
| 
       131 
     | 
    
         
            -
             
     | 
| 
       132 
     | 
    
         
            -
                     
     | 
| 
      
 128 
     | 
    
         
            +
              /* request info about own process? lookup first loaded image */
         
     | 
| 
      
 129 
     | 
    
         
            +
              if(pLib == NULL) {
         
     | 
| 
      
 130 
     | 
    
         
            +
                const char* libPath = _dyld_get_image_name(0); //@@@ consider using _NSGetExecutablePath()
         
     | 
| 
      
 131 
     | 
    
         
            +
                if(libPath)
         
     | 
| 
      
 132 
     | 
    
         
            +
                  l = dl_strlen_strcpy(sOut, libPath, bufSize);
         
     | 
| 
      
 133 
     | 
    
         
            +
              }
         
     | 
| 
      
 134 
     | 
    
         
            +
              else {
         
     | 
| 
      
 135 
     | 
    
         
            +
                /* Darwin's code doesn't come with (non-standard) dlinfo(), so use dyld(1)
         
     | 
| 
      
 136 
     | 
    
         
            +
                 * code. There doesn't seem to be a direct way to query the library path,
         
     | 
| 
      
 137 
     | 
    
         
            +
                 * so "double-load" temporarily all already loaded images (just increases
         
     | 
| 
      
 138 
     | 
    
         
            +
                 * ref count) and compare handles until we found ours. Return the name. */
         
     | 
| 
      
 139 
     | 
    
         
            +
                for(i=_dyld_image_count(); i>0;) /* backwards, ours is more likely at end */
         
     | 
| 
      
 140 
     | 
    
         
            +
                {
         
     | 
| 
      
 141 
     | 
    
         
            +
                  const char* libPath = _dyld_get_image_name(--i);
         
     | 
| 
      
 142 
     | 
    
         
            +
                  void* lib = dlopen(libPath, RTLD_LIGHTEST);
         
     | 
| 
      
 143 
     | 
    
         
            +
                  if(lib) {
         
     | 
| 
      
 144 
     | 
    
         
            +
                    dlclose(lib);
         
     | 
| 
      
 145 
     | 
    
         
            +
             
     | 
| 
      
 146 
     | 
    
         
            +
                    /* compare handle pointers' high bits (in low 2 bits some flags might */
         
     | 
| 
      
 147 
     | 
    
         
            +
                    /* be stored - should be safe b/c address needs alignment, anyways) */
         
     | 
| 
      
 148 
     | 
    
         
            +
                    if(((uintptr_t)pLib ^ (uintptr_t)lib) < 4) {
         
     | 
| 
      
 149 
     | 
    
         
            +
                      l = dl_strlen_strcpy(sOut, libPath, bufSize);
         
     | 
| 
      
 150 
     | 
    
         
            +
                      break;
         
     | 
| 
      
 151 
     | 
    
         
            +
                    }
         
     | 
| 
       133 
152 
     | 
    
         
             
                  }
         
     | 
| 
       134 
153 
     | 
    
         
             
                }
         
     | 
| 
       135 
154 
     | 
    
         
             
              }
         
     | 
| 
         @@ -138,9 +157,10 @@ int dlGetLibraryPath(DLLib* pLib, char* sOut, int bufSize) 
     | 
|
| 
       138 
157 
     | 
    
         
             
            }
         
     | 
| 
       139 
158 
     | 
    
         | 
| 
       140 
159 
     | 
    
         | 
| 
       141 
     | 
    
         
            -
            /* OpenBSD >= 3.7 has dl_iterate_phdr(),  
     | 
| 
       142 
     | 
    
         
            -
             
     | 
| 
       143 
     | 
    
         
            -
             
     | 
| 
      
 160 
     | 
    
         
            +
            /* OpenBSD >= 3.7 has dl_iterate_phdr(), as well as glibc >= 2.2.4, however
         
     | 
| 
      
 161 
     | 
    
         
            +
             * skip and use on dladdr()-based guessing if if explicitly requested, e.g. by
         
     | 
| 
      
 162 
     | 
    
         
            +
             * ./configure */
         
     | 
| 
      
 163 
     | 
    
         
            +
            #elif !defined(DL_DLADDR_TO_LIBPATH) && (defined(OS_OpenBSD) || defined(DL_USE_GLIBC_ITER_PHDR))
         
     | 
| 
       144 
164 
     | 
    
         | 
| 
       145 
165 
     | 
    
         
             
            #include <sys/types.h>
         
     | 
| 
       146 
166 
     | 
    
         
             
            #include <link.h>
         
     | 
| 
         @@ -155,18 +175,41 @@ static int iter_phdr_cb(struct dl_phdr_info* info, size_t size, void* data) 
     | 
|
| 
       155 
175 
     | 
    
         
             
            {
         
     | 
| 
       156 
176 
     | 
    
         
             
              int l = -1;
         
     | 
| 
       157 
177 
     | 
    
         
             
              iter_phdr_data* d = (iter_phdr_data*)data;
         
     | 
| 
       158 
     | 
    
         
            -
               
     | 
| 
       159 
     | 
    
         
            -
             
     | 
| 
       160 
     | 
    
         
            -
              /*  
     | 
| 
       161 
     | 
    
         
            -
               
     | 
| 
       162 
     | 
    
         
            -
             
     | 
| 
       163 
     | 
    
         
            -
             
     | 
| 
       164 
     | 
    
         
            -
             
     | 
| 
       165 
     | 
    
         
            -
             
     | 
| 
       166 
     | 
    
         
            -
             
     | 
| 
       167 
     | 
    
         
            -
             
     | 
| 
      
 178 
     | 
    
         
            +
              void* lib = NULL;
         
     | 
| 
      
 179 
     | 
    
         
            +
             
     | 
| 
      
 180 
     | 
    
         
            +
              /* get loaded object's handle if not requesting info about process itself */
         
     | 
| 
      
 181 
     | 
    
         
            +
              if(d->pLib != NULL) {
         
     | 
| 
      
 182 
     | 
    
         
            +
                /* unable to relate info->dlpi_addr directly to our dlopen handle, let's
         
     | 
| 
      
 183 
     | 
    
         
            +
                 * do what we do on macOS above, re-dlopen the already loaded lib (just
         
     | 
| 
      
 184 
     | 
    
         
            +
                 * increases ref count) and compare handles */
         
     | 
| 
      
 185 
     | 
    
         
            +
            	/* @@@ might be b/c it's the reloc addr... see below */
         
     | 
| 
      
 186 
     | 
    
         
            +
                lib = dlopen(info->dlpi_name, RTLD_LIGHTEST);
         
     | 
| 
      
 187 
     | 
    
         
            +
                if(lib)
         
     | 
| 
      
 188 
     | 
    
         
            +
                  dlclose(lib);
         
     | 
| 
      
 189 
     | 
    
         
            +
              }
         
     | 
| 
      
 190 
     | 
    
         
            +
             
     | 
| 
      
 191 
     | 
    
         
            +
              /* compare handles and get name if found; if d->pLib == NULL this will
         
     | 
| 
      
 192 
     | 
    
         
            +
                 enter info on first iterated object, which is the process itself */
         
     | 
| 
      
 193 
     | 
    
         
            +
              if(lib == (void*)d->pLib) {
         
     | 
| 
      
 194 
     | 
    
         
            +
                l = dl_strlen_strcpy(d->sOut, info->dlpi_name, d->bufSize);
         
     | 
| 
      
 195 
     | 
    
         
            +
             
     | 
| 
      
 196 
     | 
    
         
            +
                /* if dlpi_name is empty, lookup name via dladdr(proc_load_addr, ...) */
         
     | 
| 
      
 197 
     | 
    
         
            +
                if(l == 0 && d->pLib == NULL) {
         
     | 
| 
      
 198 
     | 
    
         
            +
                  /* dlpi_addr is the reloc base (0 if PIE), find real virtual load addr */
         
     | 
| 
      
 199 
     | 
    
         
            +
                  void* vladdr = (void*)info->dlpi_addr;
         
     | 
| 
      
 200 
     | 
    
         
            +
                  int i = 0;
         
     | 
| 
      
 201 
     | 
    
         
            +
                  for(; i < info->dlpi_phnum; ++i) {
         
     | 
| 
      
 202 
     | 
    
         
            +
                    if(info->dlpi_phdr[i].p_type == PT_LOAD) {
         
     | 
| 
      
 203 
     | 
    
         
            +
                      vladdr = (void*)(info->dlpi_addr + info->dlpi_phdr[i].p_vaddr);
         
     | 
| 
      
 204 
     | 
    
         
            +
                      break;
         
     | 
| 
      
 205 
     | 
    
         
            +
                    }
         
     | 
| 
      
 206 
     | 
    
         
            +
                  }
         
     | 
| 
      
 207 
     | 
    
         
            +
                  Dl_info di;
         
     | 
| 
      
 208 
     | 
    
         
            +
                  if(dladdr(vladdr, &di) != 0)
         
     | 
| 
      
 209 
     | 
    
         
            +
                    l = dl_strlen_strcpy(d->sOut, di.dli_fname, d->bufSize);
         
     | 
| 
       168 
210 
     | 
    
         
             
                }
         
     | 
| 
       169 
211 
     | 
    
         
             
              }
         
     | 
| 
      
 212 
     | 
    
         
            +
             
     | 
| 
       170 
213 
     | 
    
         
             
              return l+1; /* strlen + '\0'; is 0 if lib not found, which continues iter */
         
     | 
| 
       171 
214 
     | 
    
         
             
            }
         
     | 
| 
       172 
215 
     | 
    
         | 
| 
         @@ -177,9 +220,16 @@ int dlGetLibraryPath(DLLib* pLib, char* sOut, int bufSize) 
     | 
|
| 
       177 
220 
     | 
    
         
             
            }
         
     | 
| 
       178 
221 
     | 
    
         | 
| 
       179 
222 
     | 
    
         | 
| 
      
 223 
     | 
    
         
            +
            /* glibc with neither dl_iterate_phdr() nor dlinfo() (latter introduced after former) @@@
         
     | 
| 
      
 224 
     | 
    
         
            +
            #elif defined(__GLIBC__) && !defined(DL_USE_GLIBC_ITER_PHDR)
         
     | 
| 
      
 225 
     | 
    
         
            +
             
     | 
| 
      
 226 
     | 
    
         
            +
            @@@impl */
         
     | 
| 
      
 227 
     | 
    
         
            +
             
     | 
| 
       180 
228 
     | 
    
         
             
            /* fallback to dladdr() hack */
         
     | 
| 
       181 
229 
     | 
    
         
             
            #else
         
     | 
| 
       182 
230 
     | 
    
         | 
| 
      
 231 
     | 
    
         
            +
            #warning "Using non-optimal code for dlGetLibraryPath() b/c of platform limitations."
         
     | 
| 
      
 232 
     | 
    
         
            +
             
     | 
| 
       183 
233 
     | 
    
         
             
            /* if nothing else is available, fall back to guessing using dladdr() - this */
         
     | 
| 
       184 
234 
     | 
    
         
             
            /* might not always work, as it's trying to getit via the _fini() symbol,    */
         
     | 
| 
       185 
235 
     | 
    
         
             
            /* which is usually defined in ELF files, but not guaranteed                 */
         
     | 
| 
         @@ -190,16 +240,14 @@ int dlGetLibraryPath(DLLib* pLib, char* sOut, int bufSize) 
     | 
|
| 
       190 
240 
     | 
    
         | 
| 
       191 
241 
     | 
    
         
             
            int dlGetLibraryPath(DLLib* pLib, char* sOut, int bufSize)
         
     | 
| 
       192 
242 
     | 
    
         
             
            {
         
     | 
| 
      
 243 
     | 
    
         
            +
            /*@@@ missing handler for pLib == NULL*/
         
     | 
| 
       193 
244 
     | 
    
         
             
              /* cross fingers that shared object is standard ELF and look for _fini */
         
     | 
| 
       194 
245 
     | 
    
         
             
              int l = -1;
         
     | 
| 
       195 
246 
     | 
    
         
             
              void* s = dlsym((void*)pLib, "_fini");
         
     | 
| 
       196 
247 
     | 
    
         
             
              if(s) {
         
     | 
| 
       197 
248 
     | 
    
         
             
                Dl_info i;
         
     | 
| 
       198 
     | 
    
         
            -
                if(dladdr(s, &i) != 0) 
     | 
| 
       199 
     | 
    
         
            -
                  l =  
     | 
| 
       200 
     | 
    
         
            -
                  if(l < bufSize) /* l+'\0' <= bufSize */
         
     | 
| 
       201 
     | 
    
         
            -
                    strcpy(sOut, i.dli_fname);
         
     | 
| 
       202 
     | 
    
         
            -
                }
         
     | 
| 
      
 249 
     | 
    
         
            +
                if(dladdr(s, &i) != 0)
         
     | 
| 
      
 250 
     | 
    
         
            +
                  l = dl_strlen_strcpy(sOut, i.dli_fname, bufSize);
         
     | 
| 
       203 
251 
     | 
    
         
             
              }
         
     | 
| 
       204 
252 
     | 
    
         
             
              return l+1; /* strlen + '\0' */
         
     | 
| 
       205 
253 
     | 
    
         
             
            }
         
     |