Changeset 2954
- Timestamp:
- Feb 7, 2007, 5:42:32 AM (19 years ago)
- Location:
- trunk/kLdr
- Files:
-
- 7 edited
Legend:
- Unmodified
- Added
- Removed
-
trunk/kLdr/Makefile.kmk
r2952 r2954 35 35 # 36 36 TEMPLATE_TST = Testcase template 37 ifneq ($(filter win nt win32 win64,$(BUILD_TARGET)),)37 ifneq ($(filter win,$(BUILD_TARGET)),) 38 38 TEMPLATE_TST_TOOL = VCC70 39 39 TEMPLATE_TST_CFLAGS = -W3 -Zi -Zl -MD … … 41 41 TEMPLATE_TST_ASFLAGS = -f win 42 42 TEMPLATE_TST_DEFS = __WIN__ 43 TEMPLATE_SDKS.x86 = WIN32SDK W2K3DDKX86 44 TEMPLATE_SDKS.amd64 = WIN64SDK W2K3DDKAMD64 43 TEMPLATE_TST_SDKS = WINPSDK W2K3DDK 45 44 46 45 ## @todo this is a kBuild bug? $$(PATH_TOOL_VCC70_LIB) … … 112 111 kLdrMod.c \ 113 112 kLdrModLX.c \ 114 kLdrModPE.c \115 113 kLdrModMachO.c \ 116 kLdrModNative.c 114 kLdrModNative.c \ 115 kLdrModPE.c 117 116 kLdr_SOURCES.os2 = \ 118 117 kLdr-os2.def \ -
trunk/kLdr/kLdr.h
r2952 r2954 1117 1117 /** The mach-o image format isn't supported by this kLdr build. */ 1118 1118 #define KLDR_ERR_MACHO_NOT_SUPPORTED (KLDR_ERR_BASE + 7) 1119 /** The mach-o image format isn't supported by this kLdr build. */ 1120 #define KLDR_ERR_AOUT_NOT_SUPPORTED (KLDR_ERR_BASE + 8) 1119 /** The FAT image format isn't supported by this kLdr build or 1120 * a direct open was attempt without going thru the FAT file provider. 1121 * FAT images are also known as Universal Binaries. */ 1122 #define KLDR_ERR_FAT_NOT_SUPPORTED (KLDR_ERR_BASE + 8) 1123 /** The a.out image format isn't supported by this kLdr build. */ 1124 #define KLDR_ERR_AOUT_NOT_SUPPORTED (KLDR_ERR_BASE + 9) 1121 1125 1122 1126 /** Invalid parameter to a kLdr API. */ … … 1237 1241 * @{ */ 1238 1242 #define KLDR_ERR_MACHO_BASE (KLDR_ERR_LX_BASE + 12) 1239 /** Only native endian M ACH-O files are supported. */1243 /** Only native endian Mach-O files are supported. */ 1240 1244 #define KLDR_ERR_MACHO_OTHER_ENDIAN_NOT_SUPPORTED (KLDR_ERR_MACHO_BASE + 0) 1241 /** 64-bit M ACH-O files aren't supported yet. */1245 /** 64-bit Mach-O files aren't supported yet. */ 1242 1246 #define KLDR_ERR_MACHO_64BIT_NOT_SUPPORTED (KLDR_ERR_MACHO_BASE + 1) 1243 /** The M ACH-O header is bad or contains new and unsupported features. */1247 /** The Mach-O header is bad or contains new and unsupported features. */ 1244 1248 #define KLDR_ERR_MACHO_BAD_HEADER (KLDR_ERR_MACHO_BASE + 2) 1245 1249 /** The file type isn't supported. */ … … 1247 1251 /** The machine (cputype / cpusubtype combination) isn't supported. */ 1248 1252 #define KLDR_ERR_MACHO_UNSUPPORTED_MACHINE (KLDR_ERR_MACHO_BASE + 4) 1253 /** Bad load command(s). */ 1254 #define KLDR_ERR_MACHO_BAD_LOAD_COMMAND (KLDR_ERR_MACHO_BASE + 5) 1255 /** Encountered an unknown load command.*/ 1256 #define KLDR_ERR_MACHO_UNKNOWN_LOAD_COMMAND (KLDR_ERR_MACHO_BASE + 6) 1257 /** Encountered a load command that's not implemented.*/ 1258 #define KLDR_ERR_MACHO_UNSUPPORTED_LOAD_COMMAND (KLDR_ERR_MACHO_BASE + 7) 1259 /** Bad section. */ 1260 #define KLDR_ERR_MACHO_BAD_SECTION (KLDR_ERR_MACHO_BASE + 8) 1261 /** Encountered a section type that's not implemented.*/ 1262 #define KLDR_ERR_MACHO_UNSUPPORTED_SECTION (KLDR_ERR_MACHO_BASE + 9) 1263 /** Encountered a section type that's not known to the loader. (probably invalid) */ 1264 #define KLDR_ERR_MACHO_UNKNOWN_SECTION (KLDR_ERR_MACHO_BASE + 10) 1265 /** The sections aren't ordered by segment as expected by the loader. */ 1266 #define KLDR_ERR_MACHO_BAD_SECTION_ORDER (KLDR_ERR_MACHO_BASE + 11) 1249 1267 /** @} */ 1250 1268 1251 1269 /** End of the valid kLdr status codes. */ 1252 #define KLDR_ERR_END (KLDR_ERR_ LX_BASE + 12)1270 #define KLDR_ERR_END (KLDR_ERR_MACHO_BASE + 12) 1253 1271 1254 1272 /** @} */ -
trunk/kLdr/kLdrHlp.h
r2944 r2954 46 46 #define KLDR_ELEMENTS(a) ( sizeof(a) / sizeof((a)[0]) ) 47 47 48 /** @def KLDRHLP_LE2H_U16 49 * Unsigned 16-bit little-endian to host translation. */ 50 /** @def KLDRHLP_LE2H_U32 51 * Unsigned 32-bit little-endian to host translation. */ 52 #if 1 53 # define KLDRHLP_LE2H_U16(u16) ((uint16_t)(u16)) 54 # define KLDRHLP_ LE2H_U32(u32) ((uint32_t)(u32))55 #else 56 # define KLDRHLP_LE2H_U16(u16) ( (uint16_t) (((u16) >> 8) | ((u16) << 8)) ) 57 # define KLDRHLP_ LE2H_U32(u32)( ( ((u32) & UINT32_C(0xff000000)) >> 24 ) \48 49 /** @name Endian Conversion 50 * @{ */ 51 52 /** @def KLDRHLP_E2E_U16 53 * Convert the endian of an unsigned 16-bit value. */ 54 # define KLDRHLP_E2E_U16(u16) ( (uint16_t) (((u16) >> 8) | ((u16) << 8)) ) 55 /** @def KLDRHLP_E2E_U32 56 * Convert the endian of an unsigned 32-bit value. */ 57 # define KLDRHLP_E2E_U32(u32) ( ( ((u32) & UINT32_C(0xff000000)) >> 24 ) \ 58 58 | ( ((u32) & UINT32_C(0x00ff0000)) >> 8 ) \ 59 59 | ( ((u32) & UINT32_C(0x0000ff00)) << 8 ) \ 60 60 | ( ((u32) & UINT32_C(0x000000ff)) << 24 ) \ 61 61 ) 62 #endif 62 /** @def KLDRHLP_E2E_U64 63 * Convert the endian of an unsigned 64-bit value. */ 64 # define KLDRHLP_E2E_U64(u64) ( ( ((u64) & UINT64_C(0xff00000000000000)) >> 56 ) \ 65 | ( ((u64) & UINT64_C(0x00ff000000000000)) >> 40 ) \ 66 | ( ((u64) & UINT64_C(0x0000ff0000000000)) >> 24 ) \ 67 | ( ((u64) & UINT64_C(0x000000ff00000000)) >> 8 ) \ 68 | ( ((u64) & UINT64_C(0x00000000ff000000)) << 8 ) \ 69 | ( ((u64) & UINT64_C(0x0000000000ff0000)) << 24 ) \ 70 | ( ((u64) & UINT64_C(0x000000000000ff00)) << 40 ) \ 71 | ( ((u64) & UINT64_C(0x00000000000000ff)) << 56 ) \ 72 ) 73 74 /** @def KLDRHLP_LE2H_U16 75 * Unsigned 16-bit little-endian to host endian. */ 76 /** @def KLDRHLP_LE2H_U32 77 * Unsigned 32-bit little-endian to host endian. */ 78 /** @def KLDRHLP_LE2H_U64 79 * Unsigned 64-bit little-endian to host endian. */ 80 /** @def KLDRHLP_BE2H_U16 81 * Unsigned 16-bit big-endian to host endian. */ 82 /** @def KLDRHLP_BE2H_U32 83 * Unsigned 32-bit big-endian to host endian. */ 84 /** @def KLDRHLP_BE2H_U64 85 * Unsigned 64-bit big-endian to host endian. */ 86 #if 1 87 # define KLDRHLP_LE2H_U16(u16) ((uint16_t)(u16)) 88 # define KLDRHLP_LE2H_U32(u32) ((uint32_t)(u32)) 89 # define KLDRHLP_LE2H_U64(u64) ((uint32_t)(u32)) 90 # define KLDRHLP_BE2H_U16(u16) KLDRHLP_E2E_U16(u16) 91 # define KLDRHLP_BE2H_U32(u32) KLDRHLP_E2E_U32(u32) 92 # define KLDRHLP_BE2H_U64(u64) KLDRHLP_E2E_U64(u64) 93 #else 94 # define KLDRHLP_LE2H_U16(u16) KLDRHLP_E2E_U16(u16) 95 # define KLDRHLP_LE2H_U32(u32) KLDRHLP_E2E_U32(u32) 96 # define KLDRHLP_LE2H_U32(u64) KLDRHLP_E2E_U64(u64) 97 # define KLDRHLP_BE2H_U16(u16) ((uint16_t)(u16)) 98 # define KLDRHLP_BE2H_U32(u32) ((uint32_t)(u32)) 99 # define KLDRHLP_BE2H_U64(u64) ((uint32_t)(u32)) 100 #endif 101 102 /** @} */ 103 63 104 64 105 /* … … 174 215 # ifdef __GNUC__ 175 216 # define kldrHlpBreakpoint() do { __asm__ __volatile__ ("int3\n\tnop"); } while (0) 176 # endif 217 # endif 177 218 # ifdef _MSC_VER 178 219 # define kldrHlpBreakpoint() __debugbreak() 179 # endif 180 181 #endif 220 # endif 221 222 #endif 182 223 183 224 #if (!defined(kLdrHlpMemChr) && !defined(kLdrHlpStrChr_needed))\ … … 196 237 #ifdef __cplusplus 197 238 extern "C" { 198 #endif 239 #endif 199 240 200 241 int kLdrHlpMemIComp(const void *pv1, const void *pv2, size_t cb); … … 230 271 #ifdef __cplusplus 231 272 } 232 #endif 273 #endif 233 274 234 275 -
trunk/kLdr/kLdrInternal.h
r2944 r2954 50 50 * @{ */ 51 51 /** ELF signature ("\x7fELF"). */ 52 #define IMAGE_ELF_SIGNATURE KLDRHLP_LE2H_U32(0x7f | ('E' << 8) | ((uint32_t)'L' << 16) | ((uint32_t)'F' << 24))52 #define IMAGE_ELF_SIGNATURE KLDRHLP_LE2H_U32(0x7f | ('E' << 8) | ((uint32_t)'L' << 16) | ((uint32_t)'F' << 24)) 53 53 /** PE signature ("PE\0\0"). */ 54 #define IMAGE_NT_SIGNATURE KLDRHLP_LE2H_U32('P' | ('E' << 8))54 #define IMAGE_NT_SIGNATURE KLDRHLP_LE2H_U32('P' | ('E' << 8)) 55 55 /** LX signature ("LX") */ 56 #define IMAGE_LX_SIGNATURE KLDRHLP_LE2H_U16('L' | ('X' << 8))56 #define IMAGE_LX_SIGNATURE KLDRHLP_LE2H_U16('L' | ('X' << 8)) 57 57 /** LE signature ("LE") */ 58 #define IMAGE_LE_SIGNATURE KLDRHLP_LE2H_U16('L' | ('E' << 8))58 #define IMAGE_LE_SIGNATURE KLDRHLP_LE2H_U16('L' | ('E' << 8)) 59 59 /** NE signature ("NE") */ 60 #define IMAGE_NE_SIGNATURE KLDRHLP_LE2H_U16('N' | ('E' << 8))60 #define IMAGE_NE_SIGNATURE KLDRHLP_LE2H_U16('N' | ('E' << 8)) 61 61 /** MZ signature ("MZ"). */ 62 #define IMAGE_DOS_SIGNATURE KLDRHLP_LE2H_U16('M' | ('Z' << 8)) 62 #define IMAGE_DOS_SIGNATURE KLDRHLP_LE2H_U16('M' | ('Z' << 8)) 63 /** The FAT signature (universal binaries). */ 64 #define IMAGE_FAT_SIGNATURE UINT32_C(0xcafebabe) 65 /** The FAT signature (universal binaries), other endian. */ 66 #define IMAGE_FAT_SIGNATURE_OE UINT32_C(0xbebafeca) 67 /** The 32-bit Mach-O signature. */ 68 #define IMAGE_MACHO32_SIGNATURE UINT32_C(0xfeedface) 69 /** The 32-bit Mach-O signature, other endian. */ 70 #define IMAGE_MACHO32_SIGNATURE_OE UINT32_C(0xcefaedfe) 71 /** The 64-bit Mach-O signature. */ 72 #define IMAGE_MACHO64_SIGNATURE UINT32_C(0xfeedfacf) 73 /** The 64-bit Mach-O signature, other endian. */ 74 #define IMAGE_MACHO64_SIGNATURE_OE UINT32_C(0xfefaedfe) 63 75 /** @} */ 64 76 … … 424 436 /** @name Module interpreter method tables 425 437 * @{ */ 438 extern KLDRMODOPS g_kLdrModLXOps; 439 extern KLDRMODOPS g_kLdrModMachOOps; 440 extern KLDRMODOPS g_kLdrModNativeOps; 426 441 extern KLDRMODOPS g_kLdrModPEOps; 427 extern KLDRMODOPS g_kLdrModLXOps;428 extern KLDRMODOPS g_kLdrModNativeOps;429 442 /** @} */ 430 443 -
trunk/kLdr/kLdrMod.c
r2946 r2954 38 38 # include "kLdrModELF32.h" 39 39 # include "kLdrModELF64.h" 40 # include "kLdrModMachO.h" 40 41 #endif 41 42 … … 184 185 else if (u.u32 == IMAGE_NT_SIGNATURE) 185 186 rc = g_kLdrModPEOps.pfnCreate(&g_kLdrModPEOps, pRdr, offHdr, ppMod); 187 else if ( u.u32 == IMAGE_MACHO32_SIGNATURE 188 || u.u32 == IMAGE_MACHO32_SIGNATURE_OE 189 || u.u32 == IMAGE_MACHO64_SIGNATURE 190 || u.u32 == IMAGE_MACHO64_SIGNATURE_OE) 191 rc = g_kLdrModMachOOps.pfnCreate(&g_kLdrModMachOOps, pRdr, offHdr, ppMod); 186 192 else if (u.u32 == IMAGE_ELF_SIGNATURE) 187 193 rc = KLDR_ERR_ELF_NOT_SUPPORTED; 194 else if ( u.u32 == IMAGE_FAT_SIGNATURE 195 || u.u32 == IMAGE_FAT_SIGNATURE_OE) 196 rc = KLDR_ERR_FAT_NOT_SUPPORTED; 188 197 else 189 198 rc = KLDR_ERR_UNKNOWN_FORMAT; -
trunk/kLdr/kLdrModMachO.c
r2952 r2954 33 33 #include "kLdrInternal.h" 34 34 #include "kLdrModMachO.h" 35 36 /* quick hack for now. */ 37 typedef struct nlist 38 { 39 uint32_t n_strx; 40 uint8_t n_type; 41 int8_t n_other; 42 int16_t n_desc; 43 uint32_t n_value; 44 } nlist_t; 35 45 36 46 … … 75 85 *******************************************************************************/ 76 86 /** 77 * Instance data for the M ACH-O MH_OBJECT module interpreter.87 * Instance data for the Mach-O MH_OBJECT module interpreter. 78 88 * @todo interpret the other MH_* formats. 79 89 */ … … 121 131 122 132 static int kldrModMachODoCreate(PKLDRRDR pRdr, PKLDRMODMACHO *ppMod); 123 static int kldrModMachOPreParseLoadCommands(uint8_t *pbLoadCommands, const mach_header_32_t *pHdr, 133 static int kldrModMachOPreParseLoadCommands(uint8_t *pbLoadCommands, const mach_header_32_t *pHdr, PKLDRRDR pRdr, 124 134 uint32_t *pcSegments, uint32_t *pcbStringPool); 125 135 static int kldrModMachOParseLoadCommands(PKLDRMODMACHO pModMachO, char *pbStringPool, uint32_t cbStringPool); … … 243 253 ? sizeof(mach_header_32_t) : sizeof(mach_header_64_t)); 244 254 if (!rc) 245 rc = kldrModMachOPreParseLoadCommands(pbLoadCommands, &s.Hdr32, &cSegments, &cbStringPool);255 rc = kldrModMachOPreParseLoadCommands(pbLoadCommands, &s.Hdr32, pRdr, &cSegments, &cbStringPool); 246 256 if (rc) 247 257 { … … 375 385 * @param pbLoadCommands The load commands to parse. 376 386 * @param pHdr The header. 387 * @param pRdr The file reader. 377 388 * @param pcSegments Where to store the segment count. 378 389 * @param pcbStringPool Where to store the string pool size. 379 390 */ 380 static int kldrModMachOPreParseLoadCommands(uint8_t *pbLoadCommands, const mach_header_32_t *pHdr, 391 static int kldrModMachOPreParseLoadCommands(uint8_t *pbLoadCommands, const mach_header_32_t *pHdr, PKLDRRDR pRdr, 381 392 uint32_t *pcSegments, uint32_t *pcbStringPool) 382 393 { 394 union 395 { 396 uint8_t *pb; 397 load_command_t *pLoadCmd; 398 segment_command_32_t *pSeg32; 399 segment_command_64_t *pSeg64; 400 thread_command_t *pThread; 401 symtab_command_t *pSymTab; 402 uuid_command_t *pUuid; 403 } u; 404 const uint64_t cbFile = kLdrRdrSize(pRdr); 405 uint32_t cSegments = 0; 406 uint32_t cbStringPool = 0; 407 uint32_t cLeft = pHdr->ncmds; 408 uint32_t cbLeft = pHdr->sizeofcmds; 409 uint8_t *pb = pbLoadCommands; 410 int fConvertEndian = pHdr->magic == IMAGE_MACHO32_SIGNATURE_OE 411 || pHdr->magic == IMAGE_MACHO64_SIGNATURE_OE; 412 383 413 *pcSegments = 0; 384 414 *pcbStringPool = 0; 415 416 while (cLeft-- > 0) 417 { 418 u.pb = pb; 419 420 /* 421 * Convert and validate command header. 422 */ 423 if (cbLeft < sizeof(load_command_t)) 424 return KLDR_ERR_MACHO_BAD_LOAD_COMMAND; 425 if (fConvertEndian) 426 { 427 u.pLoadCmd->cmd = KLDRHLP_E2E_U32(u.pLoadCmd->cmd); 428 u.pLoadCmd->cmdsize = KLDRHLP_E2E_U32(u.pLoadCmd->cmdsize); 429 } 430 if (u.pLoadCmd->cmdsize > cbLeft) 431 return KLDR_ERR_MACHO_BAD_LOAD_COMMAND; 432 cbLeft -= u.pLoadCmd->cmdsize; 433 pb += u.pLoadCmd->cmdsize; 434 435 /* 436 * Convert endian if needed, parse and validate the command. 437 */ 438 switch (u.pLoadCmd->cmd) 439 { 440 case LC_SEGMENT_32: 441 { 442 section_32_t *pSect; 443 section_32_t *pFirstSect; 444 uint32_t cSectionsLeft; 445 446 /* convert and verify*/ 447 if (u.pLoadCmd->cmdsize < sizeof(segment_command_32_t)) 448 return KLDR_ERR_MACHO_BAD_LOAD_COMMAND; 449 if (fConvertEndian) 450 { 451 u.pSeg32->vmaddr = KLDRHLP_E2E_U32(u.pSeg32->vmaddr); 452 u.pSeg32->vmsize = KLDRHLP_E2E_U32(u.pSeg32->vmsize); 453 u.pSeg32->fileoff = KLDRHLP_E2E_U32(u.pSeg32->fileoff); 454 u.pSeg32->filesize = KLDRHLP_E2E_U32(u.pSeg32->filesize); 455 u.pSeg32->maxprot = KLDRHLP_E2E_U32(u.pSeg32->maxprot); 456 u.pSeg32->initprot = KLDRHLP_E2E_U32(u.pSeg32->initprot); 457 u.pSeg32->nsects = KLDRHLP_E2E_U32(u.pSeg32->nsects); 458 u.pSeg32->flags = KLDRHLP_E2E_U32(u.pSeg32->flags); 459 } 460 461 if ( u.pSeg32->filesize 462 && ( u.pSeg32->fileoff > cbFile 463 || (uint64_t)u.pSeg32->fileoff + u.pSeg32->filesize > cbFile)) 464 return KLDR_ERR_MACHO_BAD_LOAD_COMMAND; 465 if (!u.pSeg32->filesize && u.pSeg32->fileoff) 466 return KLDR_ERR_MACHO_BAD_LOAD_COMMAND; 467 if (u.pSeg32->vmsize < u.pSeg32->filesize) 468 return KLDR_ERR_MACHO_BAD_LOAD_COMMAND; 469 if ((u.pSeg32->maxprot & u.pSeg32->initprot) != u.pSeg32->initprot) 470 return KLDR_ERR_MACHO_BAD_LOAD_COMMAND; 471 if (u.pSeg32->flags & ~(SG_HIGHVM | SG_FVMLIB | SG_NORELOC | SG_PROTECTED_VERSION_1)) 472 return KLDR_ERR_MACHO_BAD_LOAD_COMMAND; 473 if (u.pSeg32->nsects * sizeof(section_32_t) > u.pLoadCmd->cmdsize - sizeof(segment_command_32_t)) 474 return KLDR_ERR_MACHO_BAD_LOAD_COMMAND; 475 476 /* 477 * convert, validate and parse the sections. 478 */ 479 cSectionsLeft = u.pSeg32->nsects; 480 pFirstSect = pSect = (section_32_t *)(u.pSeg32 + 1); 481 while (cSectionsLeft-- > 0) 482 { 483 int fFileBits; 484 485 if (fConvertEndian) 486 { 487 pSect->addr = KLDRHLP_E2E_U32(pSect->addr); 488 pSect->size = KLDRHLP_E2E_U32(pSect->size); 489 pSect->offset = KLDRHLP_E2E_U32(pSect->offset); 490 pSect->align = KLDRHLP_E2E_U32(pSect->align); 491 pSect->reloff = KLDRHLP_E2E_U32(pSect->reloff); 492 pSect->nreloc = KLDRHLP_E2E_U32(pSect->nreloc); 493 pSect->flags = KLDRHLP_E2E_U32(pSect->flags); 494 pSect->reserved1 = KLDRHLP_E2E_U32(pSect->reserved1); 495 pSect->reserved2 = KLDRHLP_E2E_U32(pSect->reserved2); 496 } 497 498 /* validate */ 499 switch (pSect->flags & SECTION_TYPE) 500 { 501 case S_ZEROFILL: 502 if (pSect->reserved1 || pSect->reserved2) 503 return KLDR_ERR_MACHO_BAD_SECTION; 504 fFileBits = 0; 505 break; 506 case S_REGULAR: 507 case S_CSTRING_LITERALS: 508 if (pSect->reserved1 || pSect->reserved2) 509 return KLDR_ERR_MACHO_BAD_SECTION; 510 fFileBits = 1; 511 break; 512 513 case S_LITERAL_POINTERS: 514 case S_INTERPOSING: 515 case S_GB_ZEROFILL: 516 case S_NON_LAZY_SYMBOL_POINTERS: 517 case S_LAZY_SYMBOL_POINTERS: 518 case S_4BYTE_LITERALS: 519 case S_8BYTE_LITERALS: 520 case S_16BYTE_LITERALS: 521 case S_SYMBOL_STUBS: 522 case S_COALESCED: 523 case S_MOD_INIT_FUNC_POINTERS: 524 case S_MOD_TERM_FUNC_POINTERS: 525 return KLDR_ERR_MACHO_UNSUPPORTED_SECTION; 526 527 default: 528 return KLDR_ERR_MACHO_UNKNOWN_SECTION; 529 } 530 if (pSect->flags & ~( S_ATTR_PURE_INSTRUCTIONS | S_ATTR_NO_TOC | S_ATTR_STRIP_STATIC_SYMS 531 | S_ATTR_NO_DEAD_STRIP | S_ATTR_LIVE_SUPPORT | S_ATTR_SELF_MODIFYING_CODE 532 | S_ATTR_DEBUG | S_ATTR_SOME_INSTRUCTIONS | S_ATTR_EXT_RELOC 533 | S_ATTR_LOC_RELOC | SECTION_TYPE)) 534 return KLDR_ERR_MACHO_BAD_SECTION; 535 if (!pSect->size) 536 return KLDR_ERR_MACHO_BAD_SECTION; 537 if ( pSect->addr - u.pSeg32->vmaddr > u.pSeg32->vmsize 538 || pSect->addr - u.pSeg32->vmaddr + pSect->size > u.pSeg32->vmsize) 539 return KLDR_ERR_MACHO_BAD_SECTION; 540 if ( pSect->align >= 31 541 || (((1 << pSect->align) - 1) & pSect->addr) 542 || (((1 << pSect->align) - 1) & u.pSeg32->vmaddr)) 543 return KLDR_ERR_MACHO_BAD_SECTION; 544 if ( fFileBits 545 && ( pSect->offset > cbFile 546 || (uint64_t)pSect->offset + pSect->size > cbFile)) 547 return KLDR_ERR_MACHO_BAD_SECTION; 548 if (!fFileBits && pSect->offset) 549 return KLDR_ERR_MACHO_BAD_SECTION; 550 if (!pSect->nreloc && pSect->reloff) 551 return KLDR_ERR_MACHO_BAD_SECTION; 552 if ( pSect->nreloc 553 && ( pSect->reloff > cbFile 554 || (uint64_t)pSect->reloff + (off_t)pSect->nreloc * sizeof(nlist_t)) > cbFile) 555 return KLDR_ERR_MACHO_BAD_SECTION; 556 557 558 /* count segments and strings */ 559 switch (pHdr->filetype) 560 { 561 case MH_OBJECT: 562 { 563 /* Don't load debug symbols. (test this) */ 564 if (pSect->flags & S_ATTR_DEBUG) 565 break; 566 567 /* a new segment? */ 568 if ( pSect == pFirstSect 569 || kLdrHlpStrNComp(pSect->segname, (pSect - 1)->segname, sizeof(pSect->segname))) 570 { 571 /* verify that the linker/assembler has ordered sections correctly. */ 572 section_32_t *pCur = (pSect - 2); 573 while ((uintptr_t)pCur >= (uintptr_t)pFirstSect) 574 { 575 if (!kLdrHlpStrNComp(pCur->segname, pSect->segname, sizeof(pSect->segname))) 576 return KLDR_ERR_MACHO_BAD_SECTION_ORDER; 577 pCur--; 578 } 579 580 /* ok. count it and the string. */ 581 cSegments++; 582 cbStringPool += kLdrHlpStrLen(pSect->segname) + 1; 583 } 584 break; 585 } 586 587 default: 588 return KLDR_ERR_INVALID_PARAMETER; 589 } 590 591 /* next */ 592 pSect++; 593 } 594 break; 595 } 596 597 case LC_SEGMENT_64: 598 /* copy 32-bit code */ 599 break; 600 601 case LC_SYMTAB: 602 if (fConvertEndian) 603 { 604 u.pSymTab->symoff = KLDRHLP_E2E_U32(u.pSymTab->symoff); 605 u.pSymTab->nsyms = KLDRHLP_E2E_U32(u.pSymTab->nsyms); 606 u.pSymTab->stroff = KLDRHLP_E2E_U32(u.pSymTab->stroff); 607 u.pSymTab->strsize = KLDRHLP_E2E_U32(u.pSymTab->strsize); 608 } 609 610 /* verify */ 611 if ( u.pSymTab->symoff >= cbFile 612 || (uint64_t)u.pSymTab->symoff + u.pSymTab->nsyms * sizeof(nlist_t) > kLdrRdrSize(pRdr)) 613 return KLDR_ERR_MACHO_BAD_LOAD_COMMAND; 614 if ( u.pSymTab->stroff >= cbFile 615 || (uint64_t)u.pSymTab->stroff + u.pSymTab->strsize > cbFile) 616 return KLDR_ERR_MACHO_BAD_LOAD_COMMAND; 617 break; 618 619 case LC_THREAD: 620 case LC_UNIXTHREAD: 621 { 622 uint32_t *pu32 = (uint32_t *)(u.pb + sizeof(load_command_t)); 623 uint32_t cItemsLeft = (u.pThread->cmdsize - sizeof(load_command_t)) / sizeof(uint32_t); 624 while (cItemsLeft) 625 { 626 /* convert & verify header items ([0] == flavor, [1] == uint32_t count). */ 627 if (cItemsLeft < 2) 628 return KLDR_ERR_MACHO_BAD_LOAD_COMMAND; 629 if (fConvertEndian) 630 { 631 pu32[0] = KLDRHLP_E2E_U32(pu32[0]); 632 pu32[1] = KLDRHLP_E2E_U32(pu32[1]); 633 } 634 if (pu32[1] + 2 > cItemsLeft) 635 return KLDR_ERR_MACHO_BAD_LOAD_COMMAND; 636 637 /* convert & verify according to flavor. */ 638 switch (pu32[0]) 639 { 640 /** @todo */ 641 default: 642 break; 643 } 644 645 /* next */ 646 cItemsLeft -= pu32[1] + 2; 647 pu32 += pu32[1] + 2; 648 } 649 break; 650 } 651 652 case LC_UUID: 653 if (u.pUuid->cmdsize != sizeof(uuid_command_t)) 654 return KLDR_ERR_MACHO_BAD_LOAD_COMMAND; 655 /** @todo Check anything here need converting? */ 656 break; 657 658 case LC_LOADFVMLIB: 659 case LC_IDFVMLIB: 660 case LC_IDENT: 661 case LC_FVMFILE: 662 case LC_PREPAGE: 663 case LC_DYSYMTAB: 664 case LC_LOAD_DYLIB: 665 case LC_ID_DYLIB: 666 case LC_LOAD_DYLINKER: 667 case LC_ID_DYLINKER: 668 case LC_PREBOUND_DYLIB: 669 case LC_ROUTINES: 670 case LC_ROUTINES_64: 671 case LC_SUB_FRAMEWORK: 672 case LC_SUB_UMBRELLA: 673 case LC_SUB_CLIENT: 674 case LC_SUB_LIBRARY: 675 case LC_TWOLEVEL_HINTS: 676 case LC_PREBIND_CKSUM: 677 case LC_LOAD_WEAK_DYLIB: 678 case LC_SYMSEG: 679 return KLDR_ERR_MACHO_UNSUPPORTED_LOAD_COMMAND; 680 681 default: 682 return KLDR_ERR_MACHO_UNKNOWN_LOAD_COMMAND; 683 } 684 } 685 686 /* be strict (for now). */ 687 if (cbLeft) 688 return KLDR_ERR_MACHO_BAD_LOAD_COMMAND; 689 690 *pcSegments = cSegments; 691 *pcbStringPool = cLeft; 692 385 693 return 0; 386 694 } … … 1723 2031 /** @copydoc kLdrModRelocateBits */ 1724 2032 static int kldrModMachORelocateBits(PKLDRMOD pMod, void *pvBits, KLDRADDR NewBaseAddress, KLDRADDR OldBaseAddress, 1725 PFNKLDRMODGETIMPORT pfnGetImport, void *pvUser)2033 PFNKLDRMODGETIMPORT pfnGetImport, void *pvUser) 1726 2034 { 1727 2035 PKLDRMODMACHO pModMachO = (PKLDRMODMACHO)pMod->pvData; … … 1740 2048 1741 2049 /** 1742 * The PEmodule interpreter method table.2050 * The Mach-O module interpreter method table. 1743 2051 */ 1744 KLDRMODOPS g_kLdrMod PEOps =1745 { 1746 " PE",2052 KLDRMODOPS g_kLdrModMachOOps = 2053 { 2054 "Mach-O", 1747 2055 NULL, 1748 2056 kldrModMachOCreate, -
trunk/kLdr/kLdrModMachO.h
r2952 r2954 283 283 { 284 284 uint32_t cmd; /**< The load command id. */ 285 uint32_t cmdsize; /**< The size of the command (including this header ?). */285 uint32_t cmdsize; /**< The size of the command (including this header). */ 286 286 } load_command_t; 287 287 … … 308 308 #define LC_ID_DYLIB UINT32_C(0x0d) /**< Dynamically linked share library ident. See dylib_command. */ 309 309 #define LC_LOAD_DYLINKER UINT32_C(0x0e) /**< Load a dynamical link editor. See dylinker_command. */ 310 #define LC_ID_DYLINKER UIN t32_C(0x0f) /**< Dynamic link editor ident. See dylinker_command. */310 #define LC_ID_DYLINKER UINT32_C(0x0f) /**< Dynamic link editor ident. See dylinker_command. */ 311 311 #define LC_PREBOUND_DYLIB UINT32_C(0x10) /**< Prebound modules for dynamically linking of a shared lib. See prebound_dylib_command. */ 312 312 #define LC_ROUTINES UINT32_C(0x11) /**< Image routines. See routines_command_32. */
Note:
See TracChangeset
for help on using the changeset viewer.