Changeset 81411
- Timestamp:
- 07/29/11 21:26:36 (4 years ago)
- File:
-
- 1 edited
Legend:
- Unmodified
- Added
- Removed
-
branches/gsoc11-post-destroot/base/src/pextlib1.0/macho.c
r80963 r81411 40 40 } 41 41 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 49 42 /* Some byteswap wrappers */ 50 43 static uint32_t macho_swap32 (uint32_t input) { … … 56 49 } 57 50 51 52 /* If the file is a universal binary, this function is called to call the callback function on each header */ 53 Tcl_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 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 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 } 58 123 /* Parse a Mach-O header */ 59 124 Tcl_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));62 125 63 126 /* Parse the Mach-O header */ 64 bool m64 = false;127 const uint32_t *magic; 65 128 bool universal = false; 66 129 uint32_t (*swap32)(uint32_t) = macho_nswap32; 67 68 130 const struct mach_header *header; 69 const struct mach_header_64 *header64;70 131 size_t header_size; 71 const struct fat_header *fat_header;72 132 73 133 const NXArchInfo *archInfo; … … 76 136 uint32_t i; 77 137 78 138 /* get file header magic */ 139 magic = macho_read(input, input->data, sizeof(uint32_t)); 79 140 if (magic == NULL) 80 141 return (Tcl_Obj *)TCL_ERROR; 81 142 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; 120 146 } 121 147 122 148 /* Parse universal file. */ 123 149 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); 148 151 } 149 152 … … 235 238 /* List Mach-O archs */ 236 239 Tcl_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 243 240 /* Parse the Mach-O header */ 241 const uint32_t *magic; 244 242 bool universal = false; 245 243 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)); 249 254 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; 291 260 } 292 261 293 262 /* Parse universal file. */ 294 263 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); 321 265 } 322 266 … … 326 270 Tcl_ListObjAppendElement(interp, archs_list, Tcl_NewStringObj(archInfo->name,-1)); 327 271 } 272 328 273 return archs_list; 329 274 }
Note: See TracChangeset
for help on using the changeset viewer.

