Ticket #19395: erlang-r13a.diff

File erlang-r13a.diff, 32.6 KB (added by nottwo (Trannie Carter), 15 years ago)
  • dports/lang/erlang/Portfile

    diff --git a/dports/lang/erlang/Portfile b/dports/lang/erlang/Portfile
    index ed3309c..f8e07f0 100644
    a b  
    1 # $Id$
     1# $Id: Portfile 44939 2009-01-04 23:22:47Z bfulgham@macports.org $
    22
    33PortSystem 1.0
    44name            erlang
    5 version         R12B-5
     5version         R13A
    66revision        1
    77categories      lang erlang
    88maintainers     bfulgham@macports.org
    distfiles otp_src_${version}${extract.suffix} \ 
    3232                otp_doc_man_${version}${extract.suffix}                \
    3333                otp_doc_html_${version}${extract.suffix}
    3434
    35 checksums       otp_src_R12B-5.tar.gz \
    36                     md5     3751ea3fea669d2b25c67eeb883734bb \
    37                     sha1    6c45509acf70d35d5def2cbefd86ada093c1ac3a \
    38                     rmd160  7265ae8ebd045ec5b977148a7c9b995eb7ef2d2d \
    39                 otp_doc_man_R12B-5.tar.gz \
    40                     md5     6231cb172847040395cc34b20781aa3b \
    41                     sha1    ae7036bd2afc9d1fca97f0de2eca84f56656def8 \
    42                     rmd160  e28d555d0a86fc69e0ee091864828c8eaa58d2be \
    43                 otp_doc_html_R12B-5.tar.gz \
    44                     md5     fb0c5454bbd865e881b6712295f6d41f \
    45                     sha1    0bd369d02051e01bac58c9b8665bd3538e116f51 \
    46                     rmd160  b460906043171b27735332ec90c45e38d888869a
     35checksums       otp_src_R13A.tar.gz \
     36                    md5     76804ff9c18710184cf0c0230a0443fc \
     37                    sha1    9fa0db27611559d697fe269c3fb9a405ae24d147 \
     38                    rmd160  42ba3c4815fa702d19281f1d42faaec72a75c703 \
     39                otp_doc_man_R13A.tar.gz \
     40                    md5     883e097796abd2cda4727fe3527dc1b6 \
     41                    sha1    98ce2fbc2daf7ec88ca38334412b9e85ca9cd53c \
     42                    rmd160  c082bda26b85cd6bd2ede8dd2c538e2ef50bbd2c \
     43                otp_doc_html_R13A.tar.gz \
     44                    md5     2bbecc1c5537e0cd1c0fc406082b6c56 \
     45                    sha1    fb3ed9c0d619d8bbd70af5c6b0e4e90c49771e0d \
     46                    rmd160  873b30cd8c5f2617c62aba0314197c54097a27cf
    4747
    4848extract.only    otp_src_${version}${extract.suffix}
    4949
    patchfiles patch-toolbar.erl \ 
    5959                patch-lib_ssl_c_src_Makefile.in \
    6060                patch-decode_big.c.diff \
    6161                patch-decode_fun.c.diff \
    62                 patch-eunit_xml.diff
     62                patch-eunit_xml.diff \
     63                patch-erts_configure.diff
    6364
    6465configure.args  --prefix=${destroot}${prefix}   \
    6566                --enable-kernel-poll            \
    variant ssl { 
    7879}
    7980
    8081variant no-hipe {
    81         # Currently produces bus errors in 10.5.3 due to changes in
    82         # signal handling
    8382        configure.args-delete   --enable-hipe
    8483}
    8584
    8685
    87 platform i386 {
    88    pre-configure {
    89       file copy ${filespath}/mach_override.h ${workpath}/${name}-${version}/erts/emulator/hipe
    90       file copy ${filespath}/mach_override.c ${workpath}/${name}-${version}/erts/emulator/hipe
    91    }
    92 }
    93 
    94 
    9586
    96 depends_build   port:gawk
     87depends_build   port:gawk \
     88                port:wxWidgets
    9789depends_run     port:tk
    9890
    9991post-destroot   {
    10092        system "tar -C ${destroot}${prefix}/lib/erlang -zxvf ${distpath}/otp_doc_html_${version}${extract.suffix}"
    10193        system "tar -C ${destroot}${prefix}/lib/erlang -zxvf ${distpath}/otp_doc_man_${version}${extract.suffix}"
    10294 
    103         set erts_dir   erts-5.6.5
     95        set erts_dir   erts-5.7
    10496
    10597        reinplace s|${destroot}|| ${destroot}${prefix}/lib/erlang/bin/erl
    10698        reinplace s|${destroot}|| ${destroot}${prefix}/lib/erlang/bin/start
  • deleted file dports/lang/erlang/files/mach_override.c

    diff --git a/dports/lang/erlang/files/mach_override.c b/dports/lang/erlang/files/mach_override.c
    deleted file mode 100644
    index 06f9b74..0000000
    + -  
    1 /*******************************************************************************
    2         mach_override.c
    3                 Copyright (c) 2003-2005 Jonathan 'Wolf' Rentzsch: <http://rentzsch.com>
    4                 Some rights reserved: <http://creativecommons.org/licenses/by/2.0/>
    5 
    6         ***************************************************************************/
    7 
    8 #include "mach_override.h"
    9 
    10 #include <mach-o/dyld.h>
    11 #include <mach/mach_host.h>
    12 #include <mach/mach_init.h>
    13 #include <mach/vm_map.h>
    14 #include <sys/mman.h>
    15 
    16 #include <CoreServices/CoreServices.h>
    17 
    18 /**************************
    19 *       
    20 *       Constants
    21 *       
    22 **************************/
    23 #pragma mark    -
    24 #pragma mark    (Constants)
    25 
    26 #if defined(__ppc__) || defined(__POWERPC__)
    27 
    28 long kIslandTemplate[] = {
    29         0x9001FFFC,     //      stw             r0,-4(SP)
    30         0x3C00DEAD,     //      lis             r0,0xDEAD
    31         0x6000BEEF,     //      ori             r0,r0,0xBEEF
    32         0x7C0903A6,     //      mtctr   r0
    33         0x8001FFFC,     //      lwz             r0,-4(SP)
    34         0x60000000,     //      nop             ; optionally replaced
    35         0x4E800420      //      bctr
    36 };
    37 
    38 #define kAddressHi                      3
    39 #define kAddressLo                      5
    40 #define kInstructionHi          10
    41 #define kInstructionLo          11
    42 
    43 #elif defined(__i386__)
    44 
    45 #define kOriginalInstructionsSize 16
    46 
    47 char kIslandTemplate[] = {
    48         // kOriginalInstructionsSize nop instructions so that we
    49         // should have enough space to host original instructions
    50         0x90, 0x90, 0x90, 0x90, 0x90, 0x90, 0x90, 0x90,
    51         0x90, 0x90, 0x90, 0x90, 0x90, 0x90, 0x90, 0x90,
    52         // Now the real jump instruction
    53         0xE9, 0xEF, 0xBE, 0xAD, 0xDE
    54 };
    55 
    56 #define kInstructions   0
    57 #define kJumpAddress    kInstructions + kOriginalInstructionsSize + 1
    58 #endif
    59 
    60 
    61 #define kAllocateHigh           1
    62 #define kAllocateNormal         0
    63 
    64 /**************************
    65 *       
    66 *       Data Types
    67 *       
    68 **************************/
    69 #pragma mark    -
    70 #pragma mark    (Data Types)
    71 
    72 typedef struct  {
    73         char    instructions[sizeof(kIslandTemplate)];
    74         int             allocatedHigh;
    75 }       BranchIsland;
    76 
    77 /**************************
    78 *       
    79 *       Funky Protos
    80 *       
    81 **************************/
    82 #pragma mark    -
    83 #pragma mark    (Funky Protos)
    84 
    85         mach_error_t
    86 allocateBranchIsland(
    87                 BranchIsland    **island,
    88                 int                             allocateHigh );
    89 
    90         mach_error_t
    91 freeBranchIsland(
    92                 BranchIsland    *island );
    93 
    94 #if defined(__ppc__) || defined(__POWERPC__)
    95         mach_error_t
    96 setBranchIslandTarget(
    97                 BranchIsland    *island,
    98                 const void              *branchTo,
    99                 long                    instruction );
    100 #endif
    101 
    102 #if defined(__i386__)
    103 mach_error_t
    104 setBranchIslandTarget_i386(
    105                                                    BranchIsland *island,
    106                                                    const void           *branchTo,
    107                                                    char*                        instructions );
    108 void
    109 atomic_mov64(
    110                 uint64_t *targetAddress,
    111                 uint64_t value );
    112 
    113         static Boolean
    114 eatKnownInstructions(
    115         unsigned char   *code,
    116         uint64_t                *newInstruction,
    117         int                             *howManyEaten,
    118         char                    *originalInstructions );
    119 #endif
    120 
    121 /*******************************************************************************
    122 *       
    123 *       Interface
    124 *       
    125 *******************************************************************************/
    126 #pragma mark    -
    127 #pragma mark    (Interface)
    128 
    129         mach_error_t
    130 mach_override(
    131                 char *originalFunctionSymbolName,
    132                 const char *originalFunctionLibraryNameHint,
    133                 const void *overrideFunctionAddress,
    134                 void **originalFunctionReentryIsland )
    135 {
    136         assert( originalFunctionSymbolName );
    137         assert( strlen( originalFunctionSymbolName ) );
    138         assert( overrideFunctionAddress );
    139        
    140         //      Lookup the original function's code pointer.
    141         long    *originalFunctionPtr;
    142         if( originalFunctionLibraryNameHint )
    143                 _dyld_lookup_and_bind_with_hint(
    144                         originalFunctionSymbolName,
    145                         originalFunctionLibraryNameHint,
    146                         (void*) &originalFunctionPtr,
    147                         NULL );
    148         else
    149                 _dyld_lookup_and_bind(
    150                         originalFunctionSymbolName,
    151                         (void*) &originalFunctionPtr,
    152                         NULL );
    153        
    154         return mach_override_ptr( originalFunctionPtr, overrideFunctionAddress,
    155                 originalFunctionReentryIsland );
    156 }
    157 
    158     mach_error_t
    159 mach_override_ptr(
    160         void *originalFunctionAddress,
    161     const void *overrideFunctionAddress,
    162     void **originalFunctionReentryIsland )
    163 {
    164         assert( originalFunctionAddress );
    165         assert( overrideFunctionAddress );
    166        
    167         long    *originalFunctionPtr = (long*) originalFunctionAddress;
    168         mach_error_t    err = err_none;
    169        
    170 #if defined(__ppc__) || defined(__POWERPC__)
    171         //      Ensure first instruction isn't 'mfctr'.
    172         #define kMFCTRMask                      0xfc1fffff
    173         #define kMFCTRInstruction       0x7c0903a6
    174        
    175         long    originalInstruction = *originalFunctionPtr;
    176         if( !err && ((originalInstruction & kMFCTRMask) == kMFCTRInstruction) )
    177                 err = err_cannot_override;
    178 #elif defined (__i386__)
    179         int eatenCount = 0;
    180         char originalInstructions[kOriginalInstructionsSize];
    181         uint64_t jumpRelativeInstruction = 0; // JMP
    182 
    183         Boolean overridePossible = eatKnownInstructions ((unsigned char *)originalFunctionPtr,
    184                                                                                 &jumpRelativeInstruction, &eatenCount, originalInstructions);
    185         if (eatenCount > kOriginalInstructionsSize) {
    186                 //printf ("Too many instructions eaten\n");
    187                 overridePossible = false;
    188         }
    189         if (!overridePossible) err = err_cannot_override;
    190 #endif
    191        
    192         //      Make the original function implementation writable.
    193         if( !err ) {
    194                 err = vm_protect( mach_task_self(),
    195                                 (vm_address_t) originalFunctionPtr,
    196                                 sizeof(long), false, (VM_PROT_ALL | VM_PROT_COPY) );
    197                 if( err )
    198                         err = vm_protect( mach_task_self(),
    199                                         (vm_address_t) originalFunctionPtr, sizeof(long), false,
    200                                         (VM_PROT_DEFAULT | VM_PROT_COPY) );
    201         }
    202        
    203         //      Allocate and target the escape island to the overriding function.
    204         BranchIsland    *escapeIsland = NULL;
    205         if( !err )     
    206                 err = allocateBranchIsland( &escapeIsland, kAllocateHigh );
    207        
    208 #if defined(__ppc__) || defined(__POWERPC__)
    209         if( !err )
    210                 err = setBranchIslandTarget( escapeIsland, overrideFunctionAddress, 0 );
    211 
    212         //      Build the branch absolute instruction to the escape island.
    213         long    branchAbsoluteInstruction = 0; // Set to 0 just to silence warning.
    214         if( !err ) {
    215                 long escapeIslandAddress = ((long) escapeIsland) & 0x3FFFFFF;
    216                 branchAbsoluteInstruction = 0x48000002 | escapeIslandAddress;
    217         }
    218 #elif defined (__i386__)
    219         if( !err )
    220                 err = setBranchIslandTarget_i386( escapeIsland, overrideFunctionAddress, 0 );
    221  
    222         // Build the jump relative instruction to the escape island
    223         if (!err) {
    224                 int32_t addressOffset = ((int32_t)escapeIsland - (int32_t)originalFunctionPtr - 5);
    225                 addressOffset = OSSwapInt32(addressOffset);
    226                
    227                 jumpRelativeInstruction |= 0xE900000000000000LL;
    228                 jumpRelativeInstruction |= ((uint64_t)addressOffset & 0xffffffff) << 24;
    229                 jumpRelativeInstruction = OSSwapInt64(jumpRelativeInstruction);         
    230         }
    231 #endif
    232        
    233         //      Optionally allocate & return the reentry island.
    234         BranchIsland    *reentryIsland = NULL;
    235         if( !err && originalFunctionReentryIsland ) {
    236                 err = allocateBranchIsland( &reentryIsland, kAllocateNormal );
    237                 if( !err )
    238                         *originalFunctionReentryIsland = reentryIsland;
    239         }
    240        
    241 #if defined(__ppc__) || defined(__POWERPC__)   
    242         //      Atomically:
    243         //      o If the reentry island was allocated:
    244         //              o Insert the original instruction into the reentry island.
    245         //              o Target the reentry island at the 2nd instruction of the
    246         //                original function.
    247         //      o Replace the original instruction with the branch absolute.
    248         if( !err ) {
    249                 int escapeIslandEngaged = false;
    250                 do {
    251                         if( reentryIsland )
    252                                 err = setBranchIslandTarget( reentryIsland,
    253                                                 (void*) (originalFunctionPtr+1), originalInstruction );
    254                         if( !err ) {
    255                                 escapeIslandEngaged = CompareAndSwap( originalInstruction,
    256                                                                                 branchAbsoluteInstruction,
    257                                                                                 (UInt32*)originalFunctionPtr );
    258                                 if( !escapeIslandEngaged ) {
    259                                         //      Someone replaced the instruction out from under us,
    260                                         //      re-read the instruction, make sure it's still not
    261                                         //      'mfctr' and try again.
    262                                         originalInstruction = *originalFunctionPtr;
    263                                         if( (originalInstruction & kMFCTRMask) == kMFCTRInstruction)
    264                                                 err = err_cannot_override;
    265                                 }
    266                         }
    267                 } while( !err && !escapeIslandEngaged );
    268         }
    269 #elif defined (__i386__)
    270         // Atomically:
    271         //      o If the reentry island was allocated:
    272         //              o Insert the original instructions into the reentry island.
    273         //              o Target the reentry island at the first non-replaced
    274         //        instruction of the original function.
    275         //      o Replace the original first instructions with the jump relative.
    276         //
    277         // Note that on i386, we do not support someone else changing the code under our feet
    278         if ( !err ) {
    279                 if( reentryIsland )
    280                         err = setBranchIslandTarget_i386( reentryIsland,
    281                                                                                  (void*) ((char *)originalFunctionPtr+eatenCount), originalInstructions );
    282                 if ( !err )
    283                         atomic_mov64((uint64_t *)originalFunctionPtr, jumpRelativeInstruction);
    284         }
    285 #endif
    286        
    287         //      Clean up on error.
    288         if( err ) {
    289                 if( reentryIsland )
    290                         freeBranchIsland( reentryIsland );
    291                 if( escapeIsland )
    292                         freeBranchIsland( escapeIsland );
    293         }
    294        
    295         return err;
    296 }
    297 
    298 /*******************************************************************************
    299 *       
    300 *       Implementation
    301 *       
    302 *******************************************************************************/
    303 #pragma mark    -
    304 #pragma mark    (Implementation)
    305 
    306 /***************************************************************************//**
    307         Implementation: Allocates memory for a branch island.
    308        
    309         @param  island                  <-      The allocated island.
    310         @param  allocateHigh    ->      Whether to allocate the island at the end of the
    311                                                                 address space (for use with the branch absolute
    312                                                                 instruction).
    313         @result                                 <-      mach_error_t
    314 
    315         ***************************************************************************/
    316 
    317         mach_error_t
    318 allocateBranchIsland(
    319                 BranchIsland    **island,
    320                 int                             allocateHigh )
    321 {
    322         assert( island );
    323        
    324         mach_error_t    err = err_none;
    325        
    326         if( allocateHigh ) {
    327                 vm_size_t pageSize;
    328                 err = host_page_size( mach_host_self(), &pageSize );
    329                 if( !err ) {
    330                         assert( sizeof( BranchIsland ) <= pageSize );
    331                         vm_address_t first = 0xfeffffff;
    332                         vm_address_t last = 0xfe000000 + pageSize;
    333                         vm_address_t page = first;
    334                         int allocated = 0;
    335                         vm_map_t task_self = mach_task_self();
    336                        
    337                         while( !err && !allocated && page != last ) {
    338                                 err = vm_allocate( task_self, &page, pageSize, 0 );
    339                                 if( err == err_none )
    340                                         allocated = 1;
    341                                 else if( err == KERN_NO_SPACE ) {
    342                                         page += pageSize;
    343                                         err = err_none;
    344                                 }
    345                         }
    346                         if( allocated )
    347                                 *island = (void*) page;
    348                         else if( !allocated && !err )
    349                                 err = KERN_NO_SPACE;
    350                 }
    351         } else {
    352                 void *block = malloc( sizeof( BranchIsland ) );
    353                 if( block )
    354                         *island = block;
    355                 else
    356                         err = KERN_NO_SPACE;
    357         }
    358         if( !err )
    359                 (**island).allocatedHigh = allocateHigh;
    360        
    361         return err;
    362 }
    363 
    364 /***************************************************************************//**
    365         Implementation: Deallocates memory for a branch island.
    366        
    367         @param  island  ->      The island to deallocate.
    368         @result                 <-      mach_error_t
    369 
    370         ***************************************************************************/
    371 
    372         mach_error_t
    373 freeBranchIsland(
    374                 BranchIsland    *island )
    375 {
    376         assert( island );
    377         assert( (*(long*)&island->instructions[0]) == kIslandTemplate[0] );
    378         assert( island->allocatedHigh );
    379        
    380         mach_error_t    err = err_none;
    381        
    382         if( island->allocatedHigh ) {
    383                 vm_size_t pageSize;
    384                 err = host_page_size( mach_host_self(), &pageSize );
    385                 if( !err ) {
    386                         assert( sizeof( BranchIsland ) <= pageSize );
    387                         err = vm_deallocate(
    388                                         mach_task_self(),
    389                                         (vm_address_t) island, pageSize );
    390                 }
    391         } else {
    392                 free( island );
    393         }
    394        
    395         return err;
    396 }
    397 
    398 /***************************************************************************//**
    399         Implementation: Sets the branch island's target, with an optional
    400         instruction.
    401        
    402         @param  island          ->      The branch island to insert target into.
    403         @param  branchTo        ->      The address of the target.
    404         @param  instruction     ->      Optional instruction to execute prior to branch. Set
    405                                                         to zero for nop.
    406         @result                         <-      mach_error_t
    407 
    408         ***************************************************************************/
    409 #if defined(__ppc__) || defined(__POWERPC__)
    410         mach_error_t
    411 setBranchIslandTarget(
    412                 BranchIsland    *island,
    413                 const void              *branchTo,
    414                 long                    instruction )
    415 {
    416         //      Copy over the template code.
    417     bcopy( kIslandTemplate, island->instructions, sizeof( kIslandTemplate ) );
    418    
    419     //  Fill in the address.
    420     ((short*)island->instructions)[kAddressLo] = ((long) branchTo) & 0x0000FFFF;
    421     ((short*)island->instructions)[kAddressHi]
    422         = (((long) branchTo) >> 16) & 0x0000FFFF;
    423    
    424     //  Fill in the (optional) instuction.
    425     if( instruction != 0 ) {
    426         ((short*)island->instructions)[kInstructionLo]
    427                 = instruction & 0x0000FFFF;
    428         ((short*)island->instructions)[kInstructionHi]
    429                 = (instruction >> 16) & 0x0000FFFF;
    430     }
    431    
    432     //MakeDataExecutable( island->instructions, sizeof( kIslandTemplate ) );
    433         msync( island->instructions, sizeof( kIslandTemplate ), MS_INVALIDATE );
    434    
    435     return err_none;
    436 }
    437 #endif
    438 
    439 #if defined(__i386__)
    440         mach_error_t
    441 setBranchIslandTarget_i386(
    442         BranchIsland    *island,
    443         const void              *branchTo,
    444         char*                   instructions )
    445 {
    446 
    447         //      Copy over the template code.
    448     bcopy( kIslandTemplate, island->instructions, sizeof( kIslandTemplate ) );
    449    
    450         // copy original instructions
    451         if (instructions) {
    452                 bcopy (instructions, island->instructions + kInstructions, kOriginalInstructionsSize);
    453         }
    454        
    455     //  Fill in the address.
    456         int32_t addressOffset = (char *)branchTo - (island->instructions + kJumpAddress + 4);
    457         *((int32_t *)(island->instructions + kJumpAddress)) = addressOffset;
    458        
    459     //MakeDataExecutable( island->instructions, sizeof( kIslandTemplate ) );
    460         msync( island->instructions, sizeof( kIslandTemplate ), MS_INVALIDATE );
    461 
    462     return err_none;
    463 }
    464 #endif
    465 
    466 
    467 #if defined (__i386__)
    468 // simplistic instruction matching
    469 typedef struct {
    470         unsigned int length; // max 15
    471         unsigned char mask[15]; // sequence of bytes in memory order
    472         unsigned char constraint[15]; // sequence of bytes in memory order
    473 }       AsmInstructionMatch;
    474 
    475 static AsmInstructionMatch possibleInstructions[] = {
    476         { 0x1, {0xFF}, {0x90} },                                                        // nop
    477         { 0x1, {0xFF}, {0x55} },                                                        // push %esp
    478         { 0x2, {0xFF, 0xFF}, {0x89, 0xE5} },                            // mov %esp,%ebp
    479         { 0x1, {0xFF}, {0x53} },                                                        // push %ebx
    480         { 0x3, {0xFF, 0xFF, 0x00}, {0x83, 0xEC, 0x00} },        // sub 0x??, %esp
    481         { 0x1, {0xFF}, {0x57} },                                                        // push %edi
    482         { 0x1, {0xFF}, {0x56} },                                                        // push %esi
    483         { 0x0 }
    484 };
    485 
    486 static Boolean codeMatchesInstruction(unsigned char *code, AsmInstructionMatch* instruction)
    487 {
    488         Boolean match = true;
    489        
    490         int i;
    491         for (i=0; i<instruction->length; i++) {
    492                 unsigned char mask = instruction->mask[i];
    493                 unsigned char constraint = instruction->constraint[i];
    494                 unsigned char codeValue = code[i];
    495                 match = ((codeValue & mask) == constraint);
    496                 if (!match) break;
    497         }
    498        
    499         return match;
    500 }
    501 
    502         static Boolean
    503 eatKnownInstructions(
    504         unsigned char *code,
    505         uint64_t* newInstruction,
    506         int* howManyEaten,
    507         char* originalInstructions )
    508 {
    509         Boolean allInstructionsKnown = true;
    510         int totalEaten = 0;
    511         unsigned char* ptr = code;
    512         int remainsToEat = 5; // a JMP instruction takes 5 bytes
    513        
    514         if (howManyEaten) *howManyEaten = 0;
    515         while (remainsToEat > 0) {
    516                 Boolean curInstructionKnown = false;
    517                
    518                 // See if instruction matches one  we know
    519                 AsmInstructionMatch* curInstr = possibleInstructions;
    520                 do {
    521                         if (curInstructionKnown = codeMatchesInstruction(ptr, curInstr)) break;
    522                         curInstr++;
    523                 } while (curInstr->length > 0);
    524                
    525                 // if all instruction matches failed, we don't know current instruction then, stop here
    526                 if (!curInstructionKnown) {
    527                         allInstructionsKnown = false;
    528                         break;
    529                 }
    530                
    531                 // At this point, we've matched curInstr
    532                 int eaten = curInstr->length;
    533                 ptr += eaten;
    534                 remainsToEat -= eaten;
    535                 totalEaten += eaten;
    536         }
    537 
    538 
    539         if (howManyEaten) *howManyEaten = totalEaten;
    540 
    541         if (originalInstructions) {
    542                 Boolean enoughSpaceForOriginalInstructions = (totalEaten < kOriginalInstructionsSize);
    543                
    544                 if (enoughSpaceForOriginalInstructions) {
    545                         memset(originalInstructions, 0x90 /* NOP */, kOriginalInstructionsSize); // fill instructions with NOP
    546                         bcopy(code, originalInstructions, totalEaten);
    547                 } else {
    548                         // printf ("Not enough space in island to store original instructions. Adapt the island definition and kOriginalInstructionsSize\n");
    549                         return false;
    550                 }
    551         }
    552        
    553         if (allInstructionsKnown) {
    554                 // save last 3 bytes of first 64bits of codre we'll replace
    555                 uint64_t currentFirst64BitsOfCode = *((uint64_t *)code);
    556                 currentFirst64BitsOfCode = OSSwapInt64(currentFirst64BitsOfCode); // back to memory representation
    557                 currentFirst64BitsOfCode &= 0x0000000000FFFFFFLL;
    558                
    559                 // keep only last 3 instructions bytes, first 5 will be replaced by JMP instr
    560                 *newInstruction &= 0xFFFFFFFFFF000000LL; // clear last 3 bytes
    561                 *newInstruction |= (currentFirst64BitsOfCode & 0x0000000000FFFFFFLL); // set last 3 bytes
    562         }
    563 
    564         return allInstructionsKnown;
    565 }
    566 
    567 asm(           
    568                         ".text;"
    569                         ".align 2, 0x90;"
    570                         ".globl _atomic_mov64;"
    571                         "_atomic_mov64:;"
    572                         "       pushl %ebp;"
    573                         "       movl %esp, %ebp;"
    574                         "       pushl %esi;"
    575                         "       pushl %ebx;"
    576                         "       pushl %ecx;"
    577                         "       pushl %eax;"
    578                         "       pushl %edx;"
    579        
    580                         // atomic push of value to an address
    581                         // we use cmpxchg8b, which compares content of an address with
    582                         // edx:eax. If they are equal, it atomically puts 64bit value
    583                         // ecx:ebx in address.
    584                         // We thus put contents of address in edx:eax to force ecx:ebx
    585                         // in address
    586                         "       mov             8(%ebp), %esi;"  // esi contains target address
    587                         "       mov             12(%ebp), %ebx;"
    588                         "       mov             16(%ebp), %ecx;" // ecx:ebx now contains value to put in target address
    589                         "       mov             (%esi), %eax;"
    590                         "       mov             4(%esi), %edx;"  // edx:eax now contains value currently contained in target address
    591                         "       lock; cmpxchg8b (%esi);" // atomic move.
    592                        
    593                         // restore registers
    594                         "       popl %edx;"
    595                         "       popl %eax;"
    596                         "       popl %ecx;"
    597                         "       popl %ebx;"
    598                         "       popl %esi;"
    599                         "       popl %ebp;"
    600                         "       ret"
    601 );
    602 
    603 #endif
  • deleted file dports/lang/erlang/files/mach_override.h

    diff --git a/dports/lang/erlang/files/mach_override.h b/dports/lang/erlang/files/mach_override.h
    deleted file mode 100644
    index c07a9af..0000000
    + -  
    1 /*******************************************************************************
    2         mach_override.h
    3                 Copyright (c) 2003-2005 Jonathan 'Wolf' Rentzsch: <http://rentzsch.com>
    4                 Some rights reserved: <http://creativecommons.org/licenses/by/2.0/>
    5 
    6         ***************************************************************************/
    7 
    8 /***************************************************************************//**
    9         @mainpage       mach_override
    10         @author         Jonathan 'Wolf' Rentzsch: <http://rentzsch.com>
    11        
    12         This package, coded in C to the Mach API, allows you to override ("patch")
    13         program- and system-supplied functions at runtime. You can fully replace
    14         functions with your implementations, or merely head- or tail-patch the
    15         original implementations.
    16        
    17         Use it by #include'ing mach_override.h from your .c, .m or .mm file(s).
    18        
    19         @todo   Discontinue use of Carbon's MakeDataExecutable() and
    20                         CompareAndSwap() calls and start using the Mach equivalents, if they
    21                         exist. If they don't, write them and roll them in. That way, this
    22                         code will be pure Mach, which will make it easier to use everywhere.
    23                         Update: MakeDataExecutable() has been replaced by
    24                         msync(MS_INVALIDATE). There is an OSCompareAndSwap in libkern, but
    25                         I'm currently unsure if I can link against it. May have to roll in
    26                         my own version...
    27         @todo   Stop using an entire 4K high-allocated VM page per 28-byte escape
    28                         branch island. Done right, this will dramatically speed up escape
    29                         island allocations when they number over 250. Then again, if you're
    30                         overriding more than 250 functions, maybe speed isn't your main
    31                         concern...
    32         @todo   Add detection of: b, bl, bla, bc, bcl, bcla, bcctrl, bclrl
    33                         first-instructions. Initially, we should refuse to override
    34                         functions beginning with these instructions. Eventually, we should
    35                         dynamically rewrite them to make them position-independent.
    36         @todo   Write mach_unoverride(), which would remove an override placed on a
    37                         function. Must be multiple-override aware, which means an almost
    38                         complete rewrite under the covers, because the target address can't
    39                         be spread across two load instructions like it is now since it will
    40                         need to be atomically updatable.
    41         @todo   Add non-rentry variants of overrides to test_mach_override.
    42 
    43         ***************************************************************************/
    44 
    45 #ifndef         _mach_override_
    46 #define         _mach_override_
    47 
    48 #include <sys/types.h>
    49 #include <mach/error.h>
    50 
    51 #ifdef  __cplusplus
    52         extern  "C"     {
    53 #endif
    54 
    55 /**
    56         Returned if the function to be overrided begins with a 'mfctr' instruction.
    57 */
    58 #define err_cannot_override     (err_local|1)
    59 
    60 /***************************************************************************//**
    61         Dynamically overrides the function implementation referenced by
    62         originalFunctionSymbolName with the implentation pointed to by
    63         overrideFunctionAddress. Optionally returns a pointer to a "reentry island"
    64         which, if jumped to, will resume the original implementation.
    65        
    66         @param  originalFunctionSymbolName              ->      Required symbol name of the
    67                                                                                                 function to override (with
    68                                                                                                 overrideFunctionAddress).
    69                                                                                                 Remember, C function name
    70                                                                                                 symbols are prepended with an
    71                                                                                                 underscore.
    72         @param  originalFunctionLibraryNameHint ->      Optional name of the library
    73                                                                                                 which contains
    74                                                                                                 originalFunctionSymbolName. Can
    75                                                                                                 be NULL, but this may result in
    76                                                                                                 the wrong function being
    77                                                                                                 overridden and/or a crash.
    78         @param  overrideFunctionAddress                 ->      Required address to the
    79                                                                                                 overriding function.
    80         @param  originalFunctionReentryIsland   <-      Optional pointer to pointer to
    81                                                                                                 the reentry island. Can be NULL.
    82         @result                                                                 <-      err_cannot_override if the
    83                                                                                                 original function's
    84                                                                                                 implementation begins with the
    85                                                                                                 'mfctr' instruction.
    86 
    87         ***************************************************************************/
    88          
    89     mach_error_t
    90 mach_override(
    91     char *originalFunctionSymbolName,
    92     const char *originalFunctionLibraryNameHint,
    93     const void *overrideFunctionAddress,
    94     void **originalFunctionReentryIsland );
    95 
    96 /************************************************************************************//**
    97         Dynamically overrides the function implementation referenced by
    98         originalFunctionAddress with the implentation pointed to by overrideFunctionAddress.
    99         Optionally returns a pointer to a "reentry island" which, if jumped to, will resume
    100         the original implementation.
    101        
    102         @param  originalFunctionAddress                 ->      Required address of the function to
    103                                                                                                 override (with overrideFunctionAddress).
    104         @param  overrideFunctionAddress                 ->      Required address to the overriding
    105                                                                                                 function.
    106         @param  originalFunctionReentryIsland   <-      Optional pointer to pointer to the
    107                                                                                                 reentry island. Can be NULL.
    108         @result                                                                 <-      err_cannot_override if the original
    109                                                                                                 function's implementation begins with
    110                                                                                                 the 'mfctr' instruction.
    111 
    112         ************************************************************************************/
    113 
    114     mach_error_t
    115 mach_override_ptr(
    116         void *originalFunctionAddress,
    117     const void *overrideFunctionAddress,
    118     void **originalFunctionReentryIsland );
    119  
    120 #ifdef  __cplusplus
    121         }
    122 #endif
    123 #endif  //      _mach_override_
    124  No newline at end of file
  • new file dports/lang/erlang/files/patch-erts_configure.diff

    diff --git a/dports/lang/erlang/files/patch-erts_configure.diff b/dports/lang/erlang/files/patch-erts_configure.diff
    new file mode 100644
    index 0000000..60d5e7c
    - +  
     1--- erts/configure.orig 2009-04-21 11:33:14.000000000 -0400
     2+++ erts/configure      2009-04-21 10:49:56.000000000 -0400
     3@@ -19528,6 +19742,91 @@
     4        esac
     5   fi
     6 fi
     7+
     8+case $ARCH-$OPSYS in
     9+       amd64-darwin*|x86-darwin*)
     10+               { $as_echo "$as_me:$LINENO: checking For modern (leopard) style mcontext_t" >&5
     11+$as_echo_n "checking For modern (leopard) style mcontext_t... " >&6; }
     12+               cat >conftest.$ac_ext <<_ACEOF
     13+/* confdefs.h.  */
     14+_ACEOF
     15+cat confdefs.h >>conftest.$ac_ext
     16+cat >>conftest.$ac_ext <<_ACEOF
     17+/* end confdefs.h.  */
     18+
     19+                               #include <stdlib.h>
     20+                               #include <sys/types.h>
     21+                               #include <unistd.h>
     22+                               #include <mach/mach.h>
     23+                               #include <pthread.h>
     24+                               #include <machine/signal.h>
     25+                               #include <ucontext.h>
     26+
     27+int
     28+main ()
     29+{
     30+
     31+                               #if defined(__APPLE__) && defined(__MACH__) && !defined(__DARWIN__)
     32+                               #define __DARWIN__ 1
     33+                               #endif
     34+
     35+                               #ifndef __DARWIN__
     36+                               #error inpossible
     37+                               #else
     38+
     39+                               mcontext_t mc = NULL;
     40+                               int x = mc->__fs.__fpu_mxcsr;
     41+
     42+                               #endif
     43+
     44+  ;
     45+  return 0;
     46+}
     47+_ACEOF
     48+rm -f conftest.$ac_objext
     49+if { (ac_try="$ac_compile"
     50+case "(($ac_try" in
     51+  *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;;
     52+  *) ac_try_echo=$ac_try;;
     53+esac
     54+eval ac_try_echo="\"\$as_me:$LINENO: $ac_try_echo\""
     55+$as_echo "$ac_try_echo") >&5
     56+  (eval "$ac_compile") 2>conftest.er1
     57+  ac_status=$?
     58+  grep -v '^ *+' conftest.er1 >conftest.err
     59+  rm -f conftest.er1
     60+  cat conftest.err >&5
     61+  $as_echo "$as_me:$LINENO: \$? = $ac_status" >&5
     62+  (exit $ac_status); } && {
     63+        test -z "$ac_c_werror_flag" ||
     64+        test ! -s conftest.err
     65+       } && test -s conftest.$ac_objext; then
     66+  darwin_mcontext_leopard=yes
     67+else
     68+  $as_echo "$as_me: failed program was:" >&5
     69+sed 's/^/| /' conftest.$ac_ext >&5
     70+
     71+       darwin_mcontext_leopard=no
     72+fi
     73+
     74+rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext
     75+                               if test X"$darwin_mcontext_leopard" = X"yes"; then
     76+
     77+cat >>confdefs.h <<\_ACEOF
     78+#define DARWIN_MODERN_MCONTEXT /**/
     79+_ACEOF
     80+
     81+                                  { $as_echo "$as_me:$LINENO: result: yes" >&5
     82+$as_echo "yes" >&6; }
     83+                               else
     84+                                  { $as_echo "$as_me:$LINENO: result: no" >&5
     85+$as_echo "no" >&6; }
     86+                               fi
     87+               ;;
     88+       *)
     89+               darwin_mcontext_leopard=no
     90+               ;;
     91+esac
     92 if test X${enable_fp_exceptions} = Xauto ; then
     93    if test X${enable_hipe} = Xyes; then
     94       enable_fp_exceptions=yes
     95@@ -19920,6 +20219,7 @@
     96     regs[PT_FPSCR] = 0x80|0x40|0x10;   /* VE, OE, ZE; not UE or XE */
     97 #endif
     98 #elif defined(__DARWIN__)
     99+#if defined(DARWIN_MODERN_MCONTEXT)
     100 #if defined(__x86_64__)
     101      mcontext_t mc = uc->uc_mcontext;
     102     struct __darwin_x86_float_state64 *fpstate = &mc->__fs;
     103@@ -19935,6 +20235,23 @@
     104     mc->ss.srr0 += 4;
     105     mc->fs.fpscr = 0x80|0x40|0x10;
     106 #endif
     107+#else
     108+#if defined(__x86_64__)
     109+    mcontext_t mc = uc->uc_mcontext;
     110+    struct x86_float_state64_t *fpstate = &mc->fs;
     111+    fpstate->fpu_mxcsr = 0x1F80;
     112+    *(unsigned short *)&fpstate->fpu_fsw &= ~0xFF;
     113+#elif defined(__i386__)
     114+    mcontext_t mc = uc->uc_mcontext;
     115+    x86_float_state32_t        *fpstate = &mc->fs;
     116+    fpstate->fpu_mxcsr = 0x1F80;
     117+    *(unsigned short *)&fpstate->fpu_fsw &= ~0xFF;
     118+#elif defined(__ppc__)
     119+    mcontext_t mc = uc->uc_mcontext;
     120+    mc->ss.srr0 += 4;
     121+    mc->fs.fpscr = 0x80|0x40|0x10;
     122+#endif
     123+#endif
     124 #elif defined(__FreeBSD__) && defined(__x86_64__)
     125     mcontext_t *mc = &uc->uc_mcontext;
     126     struct savefpu *savefpu = (struct savefpu*)&mc->mc_fpstate;
     127@@ -20069,93 +20400,6 @@
     128     fi
     129 fi
     130 
     131-case $ARCH-$OPSYS in
     132-       amd64-darwin*|x86-darwin*)
     133-               echo "$as_me:$LINENO: checking For modern (leopard) style mcontext_t" >&5
     134-echo $ECHO_N "checking For modern (leopard) style mcontext_t... $ECHO_C" >&6
     135-               cat >conftest.$ac_ext <<_ACEOF
     136-/* confdefs.h.  */
     137-_ACEOF
     138-cat confdefs.h >>conftest.$ac_ext
     139-cat >>conftest.$ac_ext <<_ACEOF
     140-/* end confdefs.h.  */
     141-
     142-                               #include <stdlib.h>
     143-                               #include <sys/types.h>
     144-                               #include <unistd.h>
     145-                               #include <mach/mach.h>
     146-                               #include <pthread.h>
     147-                               #include <machine/signal.h>
     148-                               #include <ucontext.h>
     149-
     150-int
     151-main ()
     152-{
     153-
     154-                               #if defined(__APPLE__) && defined(__MACH__) && !defined(__DARWIN__)
     155-                               #define __DARWIN__ 1
     156-                               #endif
     157-
     158-                               #ifndef __DARWIN__
     159-                               #error inpossible
     160-                               #else
     161-
     162-                               mcontext_t mc = NULL;
     163-                               int x = mc->__fs.__fpu_mxcsr;
     164-
     165-                               #endif
     166-
     167-  ;
     168-  return 0;
     169-}
     170-_ACEOF
     171-rm -f conftest.$ac_objext
     172-if { (eval echo "$as_me:$LINENO: \"$ac_compile\"") >&5
     173-  (eval $ac_compile) 2>conftest.er1
     174-  ac_status=$?
     175-  grep -v '^ *+' conftest.er1 >conftest.err
     176-  rm -f conftest.er1
     177-  cat conftest.err >&5
     178-  echo "$as_me:$LINENO: \$? = $ac_status" >&5
     179-  (exit $ac_status); } &&
     180-        { ac_try='test -z "$ac_c_werror_flag"
     181-                        || test ! -s conftest.err'
     182-  { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5
     183-  (eval $ac_try) 2>&5
     184-  ac_status=$?
     185-  echo "$as_me:$LINENO: \$? = $ac_status" >&5
     186-  (exit $ac_status); }; } &&
     187-        { ac_try='test -s conftest.$ac_objext'
     188-  { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5
     189-  (eval $ac_try) 2>&5
     190-  ac_status=$?
     191-  echo "$as_me:$LINENO: \$? = $ac_status" >&5
     192-  (exit $ac_status); }; }; then
     193-  darwin_mcontext_leopard=yes
     194-else
     195-  echo "$as_me: failed program was:" >&5
     196-sed 's/^/| /' conftest.$ac_ext >&5
     197-
     198-darwin_mcontext_leopard=no
     199-fi
     200-rm -f conftest.err conftest.$ac_objext conftest.$ac_ext
     201-                               if test X"$darwin_mcontext_leopard" = X"yes"; then
     202-
     203-cat >>confdefs.h <<\_ACEOF
     204-#define DARWIN_MODERN_MCONTEXT
     205-_ACEOF
     206-
     207-                                  echo "$as_me:$LINENO: result: yes" >&5
     208-echo "${ECHO_T}yes" >&6
     209-                               else
     210-                                  echo "$as_me:$LINENO: result: no" >&5
     211-echo "${ECHO_T}no" >&6
     212-                               fi
     213-               ;;
     214-       *)
     215-               darwin_mcontext_leopard=no
     216-               ;;
     217-esac
     218 
     219 
     220