New Ticket     Tickets     Wiki     Browse Source     Timeline     Roadmap     Ticket Reports     Search

Changeset 82430


Ignore:
Timestamp:
08/13/11 15:06:07 (4 years ago)
Author:
fotanus@…
Message:

Fixed Mach-O C extension

Also, added some simple test for it,
and commented the source file

Location:
branches/gsoc11-post-destroot/base/src/pextlib1.0
Files:
1 added
2 edited

Legend:

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

    r80618 r82430  
    2323        ${TCLSH} tests/symlink.tcl ${SHLIB_NAME} 
    2424        ${TCLSH} tests/unsetenv.tcl ${SHLIB_NAME} 
     25        ${TCLSH} tests/macho.tcl ${SHLIB_NAME} 
  • branches/gsoc11-post-destroot/base/src/pextlib1.0/macho.c

    r81411 r82430  
    4444        return OSSwapInt32(input); 
    4545} 
    46  
    4746static uint32_t macho_nswap32(uint32_t input) { 
    4847        return input; 
    4948} 
    5049 
    51  
    52 /* If the file is a universal binary, this function is called to call the callback function on each header */ 
     50/* If the file is a universal binary, this function is called to call the callback function on each header. 
     51 * This is needed because an universal file has multiple single file headers, and so to get all the arches 
     52 * and libraries we should parse each one. The callback_func is the function that gets the arches or the libraries 
     53 * */ 
    5354Tcl_Obj * handle_universal(macho_input_t *input, Tcl_Interp * interp,  const struct fat_header * fat_header, 
    5455        Tcl_Obj* (*callback_func)(macho_input_t *, Tcl_Interp *, Tcl_Obj *) ){ 
     
    7980} 
    8081 
    81 Tcl_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  
     82/* For a giver magic, this function takes the file header. Note that if the file is universal,  
     83 * he flag universal is marked as true, and the file header is set on fat_header. If the file  
     84 * is not universal, the flag universal is not set and the file header is set on header. 
     85 */ 
     86 
     87Tcl_Obj * check_magic(const uint32_t magic, macho_input_t **input, bool * universal, uint32_t (**swap32)(uint32_t), const struct mach_header ** header, const struct fat_header ** fat_header, size_t * header_size){ 
    8488        switch (magic) { 
    8589                case MH_CIGAM: 
     90                case MH_CIGAM_64: 
    8691                        *swap32 = macho_swap32; 
    8792                        /* Fall-through */ 
    8893 
    8994                case MH_MAGIC: 
     95                case MH_MAGIC_64: 
    9096                        *header_size = sizeof(**header); 
    91                         *header = macho_read(input, input->data, *header_size); 
     97                        *header = macho_read(*input, (*input)->data, *header_size); 
    9298                        if (*header == NULL) { 
    9399                                return (Tcl_Obj *)TCL_ERROR; 
     
    95101                        break; 
    96102 
    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  
    113103                case FAT_CIGAM: 
    114104                case FAT_MAGIC: 
    115                         *header = macho_read(input, input->data, sizeof(**header)); 
     105                        *fat_header = macho_read(*input, (*input)->data, sizeof(**fat_header)); 
    116106                        *universal = true; 
    117107                        break; 
    118  
    119108                default: 
    120109                        return (Tcl_Obj *)TCL_ERROR; 
    121110        } 
    122 } 
    123 /* Parse a Mach-O header */ 
     111        return (Tcl_Obj *)TCL_OK; 
     112} 
     113 
     114/* This function parses, for a fiven input, its libraries. The last parameter is a Tcl List, 
     115 * that will hold the libraries, and is needed on the recursion. If is the first call, you 
     116 * should use the function without _l. 
     117 */ 
    124118Tcl_Obj * list_macho_dlibs_l(macho_input_t *input, Tcl_Interp * interp, Tcl_Obj * dlibs) { 
     119        /* Read the file type. */ 
     120        const uint32_t *magic = macho_read(input, input->data, sizeof(uint32_t)); 
    125121 
    126122        /* Parse the Mach-O header */ 
    127         const uint32_t *magic; 
    128123        bool universal = false; 
    129124        uint32_t (*swap32)(uint32_t) = macho_nswap32; 
     125 
    130126        const struct mach_header *header; 
     127        const struct fat_header *fat_header; 
    131128        size_t header_size; 
    132129 
     
    136133        uint32_t i; 
    137134 
    138         /* get file header magic */ 
    139         magic = macho_read(input, input->data, sizeof(uint32_t)); 
     135 
    140136        if (magic == NULL) 
    141137                return (Tcl_Obj *)TCL_ERROR; 
    142138 
     139 
    143140        /* Check file header magic */ 
    144         if(check_magic(*magic, input, &universal, &swap32, &header, &header_size) == (Tcl_Obj *)TCL_ERROR){ 
     141        if(check_magic(*magic, &input, &universal, &swap32, &header, &fat_header, &header_size) == (Tcl_Obj *)TCL_ERROR){ 
     142                printf("1\n"); 
    145143                return (Tcl_Obj *)TCL_ERROR; 
    146144        } 
     
    148146        /* Parse universal file. */ 
    149147        if (universal) { 
    150                 return handle_universal(input, interp, &header, list_macho_dlibs_l); 
     148                return handle_universal(input, interp, fat_header, list_macho_dlibs_l); 
    151149        } 
    152150 
     
    236234} 
    237235 
    238 /* List Mach-O archs */ 
     236/* This function parses, for a fiven input, its arches. The last parameter is a Tcl List, 
     237 * that will hold the libraries, and is needed on the recursion. If is the first call, you 
     238 * should use the function without _l. 
     239 */ 
    239240Tcl_Obj * list_macho_archs_l(macho_input_t *input, Tcl_Interp *interp, Tcl_Obj * archs_list) { 
     241        const struct mach_header *header; 
     242        const struct mach_header_64 *header64; 
     243        size_t header_size; 
     244        const NXArchInfo *archInfo; 
     245        const struct fat_header *fat_header; 
     246 
    240247        /* Parse the Mach-O header */ 
    241         const uint32_t *magic; 
    242248        bool universal = false; 
    243249        uint32_t (*swap32)(uint32_t) = macho_nswap32; 
    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)); 
     250 
     251        /* Read the file type. */ 
     252        const uint32_t *magic = macho_read(input, input->data, sizeof(uint32_t)); 
    254253        if (magic == NULL) 
    255                 return (Tcl_Obj *)TCL_ERROR; 
     254                return false; 
     255 
    256256 
    257257        /* Check file header magic */ 
    258         if(check_magic(*magic, input, &universal, &swap32, &header, &header_size) == (Tcl_Obj *)TCL_ERROR){ 
     258        if(check_magic(*magic, &input, &universal, &swap32, &header, &fat_header, &header_size) == (Tcl_Obj *)TCL_ERROR){ 
     259                printf("1\n"); 
    259260                return (Tcl_Obj *)TCL_ERROR; 
    260261        } 
     
    262263        /* Parse universal file. */ 
    263264        if (universal) { 
    264                 return handle_universal(input, interp, &header, list_macho_archs_l); 
     265                return handle_universal(input, interp, fat_header, list_macho_archs_l); 
    265266        } 
    266267 
     
    270271                Tcl_ListObjAppendElement(interp, archs_list, Tcl_NewStringObj(archInfo->name,-1)); 
    271272        } 
    272  
    273273        return archs_list; 
    274274} 
     
    278278} 
    279279 
     280 
     281/* This is the C function for Tcl list_dlibs call. It returns a list of libraries 
     282 * from a given file. Note that the file is a file path, not a file hander. 
     283 */ 
    280284int list_dlibs(ClientData clientData __attribute__((unused)) , Tcl_Interp *interp, int objc, Tcl_Obj *CONST objv[]){ 
    281285        const char *path; 
     
    331335 
    332336 
     337/* This is the C function for Tcl list_archs call. It returns a list of libraries 
     338 * from a given file. Note that the file is a file path, not a file hander. 
     339 */ 
    333340int list_archs(ClientData clientData  __attribute__((unused)), Tcl_Interp *interp, int objc, Tcl_Obj *CONST objv[]){ 
    334341        const char *path; 
Note: See TracChangeset for help on using the changeset viewer.