Changeset 82430
- Timestamp:
- 08/13/11 15:06:07 (4 years ago)
- Location:
- branches/gsoc11-post-destroot/base/src/pextlib1.0
- Files:
-
- 1 added
- 2 edited
-
Makefile (modified) (1 diff)
-
macho.c (modified) (10 diffs)
-
tests/macho.tcl (added)
Legend:
- Unmodified
- Added
- Removed
-
branches/gsoc11-post-destroot/base/src/pextlib1.0/Makefile
r80618 r82430 23 23 ${TCLSH} tests/symlink.tcl ${SHLIB_NAME} 24 24 ${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 44 44 return OSSwapInt32(input); 45 45 } 46 47 46 static uint32_t macho_nswap32(uint32_t input) { 48 47 return input; 49 48 } 50 49 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 * */ 53 54 Tcl_Obj * handle_universal(macho_input_t *input, Tcl_Interp * interp, const struct fat_header * fat_header, 54 55 Tcl_Obj* (*callback_func)(macho_input_t *, Tcl_Interp *, Tcl_Obj *) ){ … … 79 80 } 80 81 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 87 Tcl_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){ 84 88 switch (magic) { 85 89 case MH_CIGAM: 90 case MH_CIGAM_64: 86 91 *swap32 = macho_swap32; 87 92 /* Fall-through */ 88 93 89 94 case MH_MAGIC: 95 case MH_MAGIC_64: 90 96 *header_size = sizeof(**header); 91 *header = macho_read( input, input->data, *header_size);97 *header = macho_read(*input, (*input)->data, *header_size); 92 98 if (*header == NULL) { 93 99 return (Tcl_Obj *)TCL_ERROR; … … 95 101 break; 96 102 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 103 case FAT_CIGAM: 114 104 case FAT_MAGIC: 115 * header = macho_read(input, input->data, sizeof(**header));105 *fat_header = macho_read(*input, (*input)->data, sizeof(**fat_header)); 116 106 *universal = true; 117 107 break; 118 119 108 default: 120 109 return (Tcl_Obj *)TCL_ERROR; 121 110 } 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 */ 124 118 Tcl_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)); 125 121 126 122 /* Parse the Mach-O header */ 127 const uint32_t *magic;128 123 bool universal = false; 129 124 uint32_t (*swap32)(uint32_t) = macho_nswap32; 125 130 126 const struct mach_header *header; 127 const struct fat_header *fat_header; 131 128 size_t header_size; 132 129 … … 136 133 uint32_t i; 137 134 138 /* get file header magic */ 139 magic = macho_read(input, input->data, sizeof(uint32_t)); 135 140 136 if (magic == NULL) 141 137 return (Tcl_Obj *)TCL_ERROR; 142 138 139 143 140 /* 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"); 145 143 return (Tcl_Obj *)TCL_ERROR; 146 144 } … … 148 146 /* Parse universal file. */ 149 147 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); 151 149 } 152 150 … … 236 234 } 237 235 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 */ 239 240 Tcl_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 240 247 /* Parse the Mach-O header */ 241 const uint32_t *magic;242 248 bool universal = false; 243 249 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)); 254 253 if (magic == NULL) 255 return (Tcl_Obj *)TCL_ERROR; 254 return false; 255 256 256 257 257 /* 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"); 259 260 return (Tcl_Obj *)TCL_ERROR; 260 261 } … … 262 263 /* Parse universal file. */ 263 264 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); 265 266 } 266 267 … … 270 271 Tcl_ListObjAppendElement(interp, archs_list, Tcl_NewStringObj(archInfo->name,-1)); 271 272 } 272 273 273 return archs_list; 274 274 } … … 278 278 } 279 279 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 */ 280 284 int list_dlibs(ClientData clientData __attribute__((unused)) , Tcl_Interp *interp, int objc, Tcl_Obj *CONST objv[]){ 281 285 const char *path; … … 331 335 332 336 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 */ 333 340 int list_archs(ClientData clientData __attribute__((unused)), Tcl_Interp *interp, int objc, Tcl_Obj *CONST objv[]){ 334 341 const char *path;
Note: See TracChangeset
for help on using the changeset viewer.

