New Ticket     Tickets     Wiki     Browse Source     Timeline     Roadmap     Ticket Reports     Search

Changeset 81411


Ignore:
Timestamp:
07/29/11 21:26:36 (4 years ago)
Author:
fotanus@…
Message:

Cleanup on C extension

More might be done, but this cleanup removes some code duplicity

File:
1 edited

Legend:

Unmodified
Added
Removed
  • branches/gsoc11-post-destroot/base/src/pextlib1.0/macho.c

    r80963 r81411  
    4040} 
    4141 
    42 /* return a human readable formatted version number. the result must be free()'d. */ 
    43 char *macho_format_dylib_version (uint32_t version) { 
    44         char *result; 
    45         asprintf(&result, "%"PRIu32".%"PRIu32".%"PRIu32, (version >> 16) & 0xFF, (version >> 8) & 0xFF, version & 0xFF); 
    46         return result; 
    47 } 
    48  
    4942/* Some byteswap wrappers */ 
    5043static uint32_t macho_swap32 (uint32_t input) { 
     
    5649} 
    5750 
     51 
     52/* If the file is a universal binary, this function is called to call the callback function on each header */ 
     53Tcl_Obj * handle_universal(macho_input_t *input, Tcl_Interp * interp,  const struct fat_header * fat_header, 
     54        Tcl_Obj* (*callback_func)(macho_input_t *, Tcl_Interp *, Tcl_Obj *) ){ 
     55        uint32_t i; 
     56        uint32_t nfat = OSSwapBigToHostInt32(fat_header->nfat_arch); 
     57        const struct fat_arch *archs = macho_offset(input, fat_header, sizeof(struct fat_header), sizeof(struct fat_arch)); 
     58        Tcl_Obj * return_list = Tcl_NewListObj(0,NULL); 
     59        if (archs == NULL) 
     60                return (Tcl_Obj *)TCL_ERROR; 
     61 
     62        for (i = 0; i < nfat; i++) { 
     63                const struct fat_arch *arch = macho_read(input, archs + i, sizeof(struct fat_arch)); 
     64                macho_input_t arch_input; 
     65                if (arch == NULL) 
     66                        return (Tcl_Obj *)TCL_ERROR; 
     67 
     68                /* Fetch a pointer to the architecture's Mach-O header. */ 
     69                arch_input.length = OSSwapBigToHostInt32(arch->size); 
     70                arch_input.data = macho_offset(input, input->data, OSSwapBigToHostInt32(arch->offset), arch_input.length); 
     71                if (arch_input.data == NULL) 
     72                        return (Tcl_Obj *)TCL_ERROR; 
     73 
     74                /* Parse the architecture's Mach-O header */ 
     75                if (!callback_func(&arch_input, interp, return_list)) 
     76                        return (Tcl_Obj *)TCL_ERROR; 
     77        } 
     78        return return_list; 
     79} 
     80 
     81Tcl_Obj * check_magic(const uint32_t magic, macho_input_t *input, bool * universal, uint32_t (**swap32)(uint32_t), const struct mach_header ** header, size_t * header_size){ 
     82        const struct mach_header_64 *header64; 
     83 
     84        switch (magic) { 
     85                case MH_CIGAM: 
     86                        *swap32 = macho_swap32; 
     87                        /* Fall-through */ 
     88 
     89                case MH_MAGIC: 
     90                        *header_size = sizeof(**header); 
     91                        *header = macho_read(input, input->data, *header_size); 
     92                        if (*header == NULL) { 
     93                                return (Tcl_Obj *)TCL_ERROR; 
     94                        } 
     95                        break; 
     96 
     97                case MH_CIGAM_64: 
     98                        *swap32 = macho_swap32; 
     99                        /* Fall-through */ 
     100 
     101                case MH_MAGIC_64: 
     102                        *header_size = sizeof(*header64); 
     103                        header64 = macho_read(input, input->data, sizeof(*header64)); 
     104                        if (header64 == NULL) 
     105                                return (Tcl_Obj *)TCL_ERROR; 
     106 
     107                        /* The 64-bit header is a direct superset of the 32-bit header */ 
     108 
     109                        *header = (struct mach_header *) header64; 
     110 
     111                        break; 
     112 
     113                case FAT_CIGAM: 
     114                case FAT_MAGIC: 
     115                        *header = macho_read(input, input->data, sizeof(**header)); 
     116                        *universal = true; 
     117                        break; 
     118 
     119                default: 
     120                        return (Tcl_Obj *)TCL_ERROR; 
     121        } 
     122} 
    58123/* Parse a Mach-O header */ 
    59124Tcl_Obj * list_macho_dlibs_l(macho_input_t *input, Tcl_Interp * interp, Tcl_Obj * dlibs) { 
    60         /* Read the file type. */ 
    61         const uint32_t *magic = macho_read(input, input->data, sizeof(uint32_t)); 
    62125 
    63126        /* Parse the Mach-O header */ 
    64         bool m64 = false; 
     127        const uint32_t *magic; 
    65128        bool universal = false; 
    66129        uint32_t (*swap32)(uint32_t) = macho_nswap32; 
    67  
    68130        const struct mach_header *header; 
    69         const struct mach_header_64 *header64; 
    70131        size_t header_size; 
    71         const struct fat_header *fat_header; 
    72132 
    73133        const NXArchInfo *archInfo; 
     
    76136        uint32_t i; 
    77137 
    78  
     138        /* get file header magic */ 
     139        magic = macho_read(input, input->data, sizeof(uint32_t)); 
    79140        if (magic == NULL) 
    80141                return (Tcl_Obj *)TCL_ERROR; 
    81142 
    82         switch (*magic) { 
    83                 case MH_CIGAM: 
    84                         swap32 = macho_swap32; 
    85                         /* Fall-through */ 
    86  
    87                 case MH_MAGIC: 
    88                         header_size = sizeof(*header); 
    89                         header = macho_read(input, input->data, header_size); 
    90                         if (header == NULL) { 
    91                                 return false; 
    92                         } 
    93                         break; 
    94  
    95                 case MH_CIGAM_64: 
    96                         swap32 = macho_swap32; 
    97                         /* Fall-through */ 
    98  
    99                 case MH_MAGIC_64: 
    100                         header_size = sizeof(*header64); 
    101                         header64 = macho_read(input, input->data, sizeof(*header64)); 
    102                         if (header64 == NULL) 
    103                                 return false; 
    104  
    105                         /* The 64-bit header is a direct superset of the 32-bit header */ 
    106  
    107                         header = (struct mach_header *) header64; 
    108  
    109                         m64 = true; 
    110                         break; 
    111  
    112                 case FAT_CIGAM: 
    113                 case FAT_MAGIC: 
    114                         fat_header = macho_read(input, input->data, sizeof(*fat_header)); 
    115                         universal = true; 
    116                         break; 
    117  
    118                 default: 
    119                         return (Tcl_Obj *)TCL_ERROR; 
     143        /* Check file header magic */ 
     144        if(check_magic(*magic, input, &universal, &swap32, &header, &header_size) == (Tcl_Obj *)TCL_ERROR){ 
     145                return (Tcl_Obj *)TCL_ERROR; 
    120146        } 
    121147 
    122148        /* Parse universal file. */ 
    123149        if (universal) { 
    124                 uint32_t i; 
    125                 uint32_t nfat = OSSwapBigToHostInt32(fat_header->nfat_arch); 
    126                 const struct fat_arch *archs = macho_offset(input, fat_header, sizeof(struct fat_header), sizeof(struct fat_arch)); 
    127                 if (archs == NULL) 
    128                         return false; 
    129  
    130                 for (i = 0; i < nfat; i++) { 
    131                         const struct fat_arch *arch = macho_read(input, archs + i, sizeof(struct fat_arch)); 
    132                         macho_input_t arch_input; 
    133                         if (arch == NULL) 
    134                                 return false; 
    135  
    136                         /* Fetch a pointer to the architecture's Mach-O header. */ 
    137                         arch_input.length = OSSwapBigToHostInt32(arch->size); 
    138                         arch_input.data = macho_offset(input, input->data, OSSwapBigToHostInt32(arch->offset), arch_input.length); 
    139                         if (arch_input.data == NULL) 
    140                                 return false; 
    141  
    142                         /* Parse the architecture's Mach-O header */ 
    143                         if (!list_macho_dlibs_l(&arch_input, interp, dlibs)) 
    144                                 return false; 
    145                 } 
    146  
    147                 return dlibs; 
     150                return handle_universal(input, interp, &header, list_macho_dlibs_l); 
    148151        } 
    149152 
     
    235238/* List Mach-O archs */ 
    236239Tcl_Obj * list_macho_archs_l(macho_input_t *input, Tcl_Interp *interp, Tcl_Obj * archs_list) { 
    237         const struct mach_header *header; 
    238         const struct mach_header_64 *header64; 
    239         size_t header_size; 
    240         const NXArchInfo *archInfo; 
    241         const struct fat_header *fat_header; 
    242  
    243240        /* Parse the Mach-O header */ 
     241        const uint32_t *magic; 
    244242        bool universal = false; 
    245243        uint32_t (*swap32)(uint32_t) = macho_nswap32; 
    246  
    247         /* Read the file type. */ 
    248         const uint32_t *magic = macho_read(input, input->data, sizeof(uint32_t)); 
     244        const struct mach_header *header; 
     245        size_t header_size; 
     246 
     247        const NXArchInfo *archInfo; 
     248        const struct load_command *cmd; 
     249        uint32_t ncmds; 
     250        uint32_t i; 
     251 
     252        /* get file header magic */ 
     253        magic = macho_read(input, input->data, sizeof(uint32_t)); 
    249254        if (magic == NULL) 
    250                 return false; 
    251  
    252  
    253  
    254         switch (*magic) { 
    255                 case MH_CIGAM: 
    256                         swap32 = macho_swap32; 
    257                         /* Fall-through */ 
    258  
    259                 case MH_MAGIC: 
    260                         header_size = sizeof(*header); 
    261                         header = macho_read(input, input->data, header_size); 
    262                         if (header == NULL) { 
    263                                 return (Tcl_Obj *)TCL_ERROR; 
    264                         } 
    265                         break; 
    266  
    267  
    268                 case MH_CIGAM_64: 
    269                         swap32 = macho_swap32; 
    270                         /* Fall-through */ 
    271  
    272                 case MH_MAGIC_64: 
    273                         header_size = sizeof(*header64); 
    274                         header64 = macho_read(input, input->data, sizeof(*header64)); 
    275                         if (header64 == NULL) 
    276                                 return (Tcl_Obj *)TCL_ERROR; 
    277  
    278                         /* The 64-bit header is a direct superset of the 32-bit header */ 
    279                         header = (struct mach_header *) header64; 
    280  
    281                         break; 
    282  
    283                 case FAT_CIGAM: 
    284                 case FAT_MAGIC: 
    285                         fat_header = macho_read(input, input->data, sizeof(*fat_header)); 
    286                         universal = true; 
    287                         break; 
    288  
    289                 default: 
    290                         return (Tcl_Obj *)TCL_ERROR; 
     255                return (Tcl_Obj *)TCL_ERROR; 
     256 
     257        /* Check file header magic */ 
     258        if(check_magic(*magic, input, &universal, &swap32, &header, &header_size) == (Tcl_Obj *)TCL_ERROR){ 
     259                return (Tcl_Obj *)TCL_ERROR; 
    291260        } 
    292261 
    293262        /* Parse universal file. */ 
    294263        if (universal) { 
    295                 uint32_t nfat = OSSwapBigToHostInt32(fat_header->nfat_arch); 
    296                 const struct fat_arch *archs = macho_offset(input, fat_header, sizeof(struct fat_header), sizeof(struct fat_arch)); 
    297                 uint32_t i; 
    298                 const struct fat_arch *arch; 
    299                 macho_input_t arch_input; 
    300  
    301                 if (archs == NULL) 
    302                         return (Tcl_Obj *)TCL_ERROR; 
    303  
    304                 for (i = 0; i < nfat; i++) { 
    305                         arch = macho_read(input, archs + i, sizeof(struct fat_arch)); 
    306                         if (arch == NULL) 
    307                                 return (Tcl_Obj *)TCL_ERROR; 
    308  
    309                         /* Fetch a pointer to the architecture's Mach-O header. */ 
    310                         arch_input.length = OSSwapBigToHostInt32(arch->size); 
    311                         arch_input.data = macho_offset(input, input->data, OSSwapBigToHostInt32(arch->offset), arch_input.length); 
    312                         if (arch_input.data == NULL) 
    313                                 return (Tcl_Obj *)TCL_ERROR; 
    314  
    315                         /* Parse the architecture's Mach-O header */ 
    316                         if (!list_macho_archs_l(&arch_input, interp, archs_list)) 
    317                                 return (Tcl_Obj *)TCL_ERROR; 
    318                 } 
    319  
    320                 return archs_list; 
     264                return handle_universal(input, interp, &header, list_macho_archs_l); 
    321265        } 
    322266 
     
    326270                Tcl_ListObjAppendElement(interp, archs_list, Tcl_NewStringObj(archInfo->name,-1)); 
    327271        } 
     272 
    328273        return archs_list; 
    329274} 
Note: See TracChangeset for help on using the changeset viewer.