Index: branches/cparm/Chameleon.xcodeproj/project.pbxproj =================================================================== --- branches/cparm/Chameleon.xcodeproj/project.pbxproj (revision 2111) +++ branches/cparm/Chameleon.xcodeproj/project.pbxproj (revision 2112) @@ -30,6 +30,18 @@ AB021459161C3B9F007F5325 /* user.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = user.h; sourceTree = ""; }; AB02145A161C3B9F007F5325 /* util.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = util.h; sourceTree = ""; }; AB0E930C14C6223500F798D7 /* cpu_intel_amd.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; path = cpu_intel_amd.c; sourceTree = ""; }; + AB19DD0816392AFD00CF3455 /* __bzero.s */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.asm; path = __bzero.s; sourceTree = ""; }; + AB19DD3A1639360E00CF3455 /* strcmp.s */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.asm; path = strcmp.s; sourceTree = ""; }; + AB19DD451639370A00CF3455 /* strcpy.s */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.asm; path = strcpy.s; sourceTree = ""; }; + AB19DD461639375500CF3455 /* strlcat.s */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.asm; path = strlcat.s; sourceTree = ""; }; + AB19DD47163937C800CF3455 /* strlcpy.s */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.asm; path = strlcpy.s; sourceTree = ""; }; + AB19DD481639382000CF3455 /* strlen.s */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.asm; path = strlen.s; sourceTree = ""; }; + AB19DD491639389500CF3455 /* strncmp.s */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.asm; path = strncmp.s; sourceTree = ""; }; + AB19DD4A163938D300CF3455 /* strncpy.s */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.asm; path = strncpy.s; sourceTree = ""; }; + AB19DD4B16393A1500CF3455 /* memcmp.s */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.asm; path = memcmp.s; sourceTree = ""; }; + AB19DD5D16393CD800CF3455 /* memset.s */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.asm; path = memset.s; sourceTree = ""; }; + AB19DD6616393D6400CF3455 /* memset_pattern_sse2.s */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.asm; path = memset_pattern_sse2.s; sourceTree = ""; }; + AB19DD6B16393E1400CF3455 /* bzero_scalar.s */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.asm; path = bzero_scalar.s; sourceTree = ""; }; AB22095D15334C9E00AA9851 /* md5.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = md5.h; sourceTree = ""; }; AB3117CF15DBCBDE00DA0817 /* fake_crt.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; path = fake_crt.c; sourceTree = ""; }; AB42D02115187F2C0078E84A /* background.png */ = {isa = PBXFileReference; lastKnownFileType = image.png; path = background.png; sourceTree = ""; }; @@ -461,8 +473,6 @@ AB43B3E414C37E530018D529 /* Symbols.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; path = Symbols.c; sourceTree = ""; }; AB43B3E514C37E530018D529 /* WKdm.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = WKdm.h; sourceTree = ""; }; AB43B3E614C37E530018D529 /* WKdmDecompress.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; path = WKdmDecompress.c; sourceTree = ""; }; - AB43B3EC14C383120018D529 /* bcopy.s */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.asm; path = bcopy.s; sourceTree = ""; }; - AB43B3ED14C383120018D529 /* bzero.s */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.asm; path = bzero.s; sourceTree = ""; }; AB43B3EE14C383120018D529 /* divdi3.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; path = divdi3.c; sourceTree = ""; }; AB43B3EF14C383120018D529 /* moddi3.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; path = moddi3.c; sourceTree = ""; }; AB43B3F014C383120018D529 /* qdivrem.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; path = qdivrem.c; sourceTree = ""; }; @@ -470,6 +480,7 @@ AB43B3F214C383120018D529 /* udivdi3.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; path = udivdi3.c; sourceTree = ""; }; AB43B3F314C383120018D529 /* umoddi3.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; path = umoddi3.c; sourceTree = ""; }; AB43B3F814C384040018D529 /* stack_protector.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; path = stack_protector.c; sourceTree = ""; }; + AB6DE3E6163976A80065E17F /* bcopy_scalar.s */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.asm; path = bcopy_scalar.s; sourceTree = ""; }; AB79217514F38CF200F5EB39 /* bootXnu.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = bootXnu.h; sourceTree = ""; }; AB79219214F3919E00F5EB39 /* ModuleHelp.txt */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = text; path = ModuleHelp.txt; sourceTree = ""; }; ABA0C7BF1568190C003440AF /* arc4random-fbsd.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; path = "arc4random-fbsd.c"; sourceTree = ""; }; @@ -993,24 +1004,35 @@ AB43B2DE14C37E520018D529 /* libsa */ = { isa = PBXGroup; children = ( - AB43B3EC14C383120018D529 /* bcopy.s */, - AB43B3ED14C383120018D529 /* bzero.s */, + AB6DE3E6163976A80065E17F /* bcopy_scalar.s */, + AB19DD0816392AFD00CF3455 /* __bzero.s */, + AB19DD6B16393E1400CF3455 /* bzero_scalar.s */, AB43B3EE14C383120018D529 /* divdi3.c */, - AB43B3EF14C383120018D529 /* moddi3.c */, - AB43B3F014C383120018D529 /* qdivrem.c */, - AB43B3F114C383120018D529 /* quad.h */, - AB43B3F214C383120018D529 /* udivdi3.c */, - AB43B3F314C383120018D529 /* umoddi3.c */, AB43B2DF14C37E520018D529 /* efi_tables.c */, AB43B2E014C37E520018D529 /* efi_tables.h */, AB43B2E214C37E520018D529 /* libsa.h */, AB43B2E314C37E520018D529 /* Makefile */, AB43B2E414C37E520018D529 /* memory.h */, + AB19DD4B16393A1500CF3455 /* memcmp.s */, + AB19DD5D16393CD800CF3455 /* memset.s */, + AB19DD6616393D6400CF3455 /* memset_pattern_sse2.s */, + AB43B3EF14C383120018D529 /* moddi3.c */, AB43B2E614C37E520018D529 /* printf.c */, + AB43B3F014C383120018D529 /* qdivrem.c */, AB43B2E714C37E520018D529 /* qsort.c */, + AB43B3F114C383120018D529 /* quad.h */, AB43B2E914C37E520018D529 /* setjmp.s */, + AB19DD3A1639360E00CF3455 /* strcmp.s */, + AB19DD451639370A00CF3455 /* strcpy.s */, + AB19DD461639375500CF3455 /* strlcat.s */, + AB19DD47163937C800CF3455 /* strlcpy.s */, + AB19DD481639382000CF3455 /* strlen.s */, + AB19DD491639389500CF3455 /* strncmp.s */, + AB19DD4A163938D300CF3455 /* strncpy.s */, AB43B2EA14C37E520018D529 /* string.c */, AB43B2EB14C37E520018D529 /* strtol.c */, + AB43B3F214C383120018D529 /* udivdi3.c */, + AB43B3F314C383120018D529 /* umoddi3.c */, AB43B2EC14C37E520018D529 /* zalloc.c */, ); path = libsa; Index: branches/cparm/CHANGES =================================================================== --- branches/cparm/CHANGES (revision 2111) +++ branches/cparm/CHANGES (revision 2112) @@ -1,5 +1,10 @@ - Security fixes +- Using of optimized version for bcopy, bzero, strcmp, strcpy, strncpy, strlcat, strlcpy, strlen, strncmp, memset and memcmp +- Replaced strcmp (deprecated and unsecure) by strncmp as far as possible +- Decided to keep ld_classic to keep the compatibility with the apple's compiler from snow leopard (xcode 3.x) to Mountain lion (xcode 4.5) (in fact this has not changed since the last commit ;-) ) +- Security fixes + - Few security fixes - Fixed a serious bug in picopng - Fixed a bug in gui.c, related to the images loading Index: branches/cparm/i386/libsaio/xml.c =================================================================== --- branches/cparm/i386/libsaio/xml.c (revision 2111) +++ branches/cparm/i386/libsaio/xml.c (revision 2112) @@ -305,7 +305,7 @@ length = 0; } /***** dict ****/ - else if (!strcmp(tagName, kXMLTagDict)) + else if (!strncmp(tagName, kXMLTagDict, sizeof(kXMLTagDict))) { length = ParseTagList(buffer + pos, tag, kTagTypeDict, 0); } @@ -318,13 +318,13 @@ length = ParseTagList(buffer + pos, tag, kTagTypeDict, 0); } /***** key ****/ - else if (!strcmp(tagName, kXMLTagKey)) + else if (!strncmp(tagName, kXMLTagKey, sizeof(kXMLTagKey))) { length = ParseTagKey(buffer + pos, tag); } /***** string ****/ - else if (!strcmp(tagName, kXMLTagString)) + else if (!strncmp(tagName, kXMLTagString, sizeof(kXMLTagString))) { length = ParseTagString(buffer + pos, tag); } @@ -398,7 +398,7 @@ } /***** integer ****/ - else if (!strcmp(tagName, kXMLTagInteger)) + else if (!strncmp(tagName, kXMLTagInteger, sizeof(kXMLTagInteger))) { length = ParseTagInteger(buffer + pos, tag); } @@ -477,7 +477,7 @@ } /***** data ****/ - else if (!strcmp(tagName, kXMLTagData)) + else if (!strncmp(tagName, kXMLTagData, sizeof(kXMLTagData))) { length = ParseTagData(buffer + pos, tag); } @@ -485,7 +485,7 @@ { length = ParseTagData(buffer + pos, tag); } - else if (!strcmp(tagName, kXMLTagDate)) + else if (!strncmp(tagName, kXMLTagDate, sizeof(kXMLTagDate))) { length = ParseTagDate(buffer + pos, tag); } @@ -497,18 +497,18 @@ } /***** false ****/ - else if (!strcmp(tagName, kXMLTagFalse)) + else if (!strncmp(tagName, kXMLTagFalse, sizeof(kXMLTagFalse))) { length = ParseTagBoolean(buffer + pos, tag, kTagTypeFalse); } /***** true ****/ - else if (!strcmp(tagName, kXMLTagTrue)) + else if (!strncmp(tagName, kXMLTagTrue, sizeof(kXMLTagTrue))) { length = ParseTagBoolean(buffer + pos, tag, kTagTypeTrue); } /***** array ****/ - else if (!strcmp(tagName, kXMLTagArray)) + else if (!strncmp(tagName, kXMLTagArray, sizeof(kXMLTagArray) )) { length = ParseTagList(buffer + pos, tag, kTagTypeArray, 0); } @@ -516,7 +516,7 @@ { length = ParseTagList(buffer + pos, tag, kTagTypeArray, 0); } - else if (!strcmp(tagName, kXMLTagArray "/")) + else if (!strncmp(tagName, kXMLTagArray "/", strlen(kXMLTagArray "/"))) { length = ParseTagList(buffer + pos, tag, kTagTypeArray, 1); } Index: branches/cparm/i386/libsaio/device_tree.c =================================================================== --- branches/cparm/i386/libsaio/device_tree.c (revision 2111) +++ branches/cparm/i386/libsaio/device_tree.c (revision 2112) @@ -311,7 +311,7 @@ //DPRINTF("Node properties = 0x%x\n", node->properties); for (prop = node->properties; prop; prop = prop->next) { //DPRINTF("Prop '%s'\n", prop->name); - if (strcmp(prop->name, "name") == 0) { + if (strncmp(prop->name, "name",sizeof("name")) == 0) { return prop->value; } } @@ -384,7 +384,7 @@ for (prop = node->properties; prop; prop = prop->next) { char c = *((char *)prop->value); if (prop->length < 64 && ( - strcmp(prop->name, "name") == 0 || + strncmp(prop->name, "name",sizeof("name") ) == 0 || (c >= '0' && c <= '9') || (c >= 'a' && c <= 'z') || (c >= 'A' && c <= 'Z') || c == '_')) { Index: branches/cparm/i386/libsaio/modules.c =================================================================== --- branches/cparm/i386/libsaio/modules.c (revision 2111) +++ branches/cparm/i386/libsaio/modules.c (revision 2112) @@ -195,14 +195,14 @@ // Make sure this is not a directory. if ((flags & kFileTypeMask) == kFileTypeDirectory) continue; - if ((strcmp("Symbols.dylib",name)) == 0) continue; // if we found Symbols.dylib, just skip it + if ((strncmp("Symbols.dylib",name, sizeof("Symbols.dylib"))) == 0) continue; // if we found Symbols.dylib, just skip it if (is_dylib_loaded(name) == EFI_SUCCESS) continue; // Make sure this is a kext. length = strlen(name); - if (strcmp(name + length - 6, ".dylib")) continue; + if (strncmp(name + length - 6, ".dylib", 6)) continue; char *tmp = newStringWithFormat( "/Extra/modules/%s",name); if (!tmp) { @@ -269,14 +269,20 @@ module_base = (char*) malloc(moduleSize); } - if (module_base && read(fh, module_base, moduleSize) == moduleSize) + if (!module_base) { + goto out; + } + + if (read(fh, module_base, moduleSize) == moduleSize) + { DBG("Module %s read in.\n", module); // Module loaded into memory, parse it - module_start = parse_mach(name, module_base, &add_symbol); - + module_start = parse_mach(name, module_base, &add_symbol); + + } else { @@ -284,9 +290,10 @@ #if DEBUG_MODULES getc(); #endif - module_start = 0xFFFFFFFF; + free(module_base); } } +out: close(fh); return module_start; } @@ -412,9 +419,15 @@ * symbols will still be available (TODO: fix this). This should not * happen as all dependencies are verified before the sybols are read in. */ +#if macho_64 unsigned int parse_mach(char *module, void* binary, long long(*symbol_handler)(char*, char*, long long, char)) // TODO: add param to specify valid archs +#else +unsigned int parse_mach(char *module, void* binary, long long(*symbol_handler)(char*, char*, long long)) // TODO: add param to specify valid archs +#endif { +#if macho_64 char is64 = false; +#endif unsigned int module_start = 0xFFFFFFFF; EFI_STATUS bind_status = EFI_SUCCESS; @@ -424,7 +437,9 @@ { struct segment_command *segCommand = NULL; +#if macho_64 struct segment_command_64 *segCommand64 = NULL; +#endif struct load_command *loadCommand = NULL; UInt32 binaryIndex = 0; UInt16 cmd = 0; @@ -432,15 +447,19 @@ // Parse through the load commands if(((struct mach_header*)binary)->magic == MH_MAGIC) { +#if macho_64 is64 = false; +#endif binaryIndex += sizeof(struct mach_header); } +#if macho_64 else if(((struct mach_header_64*)binary)->magic == MH_MAGIC_64) { // NOTE: modules cannot be 64bit... is64 = true; binaryIndex += sizeof(struct mach_header_64); } +#endif else { printf("Modules: Invalid mach magic\n"); @@ -477,7 +496,7 @@ //printf("Segment name is %s\n", segCommand->segname); - if(strcmp("__TEXT", segCommand->segname) == 0) + if(strncmp("__TEXT", segCommand->segname, sizeof("__TEXT")) == 0) { UInt32 sectionIndex; @@ -509,7 +528,7 @@ sectionIndex += sizeof(struct section); - if(strcmp("__text", sect->sectname) == 0) + if(strncmp("__text", sect->sectname,sizeof("__text")) == 0) { // __TEXT,__text found, save the offset and address for when looking for the calls. textSection = sect->offset; @@ -519,14 +538,15 @@ } } break; - } + } +#if macho_64 case LC_SEGMENT_64: // 64bit macho's { segCommand64 = binary + binaryIndex; //printf("Segment name is %s\n", segCommand->segname); - if(strcmp("__TEXT", segCommand64->segname) == 0) + if(strncmp("__TEXT", segCommand64->segname, sizeof("__TEXT")) == 0) { UInt32 sectionIndex; @@ -558,7 +578,7 @@ sectionIndex += sizeof(struct section_64); - if(strcmp("__text", sect->sectname) == 0) + if(strncmp("__text", sect->sectname, sizeof("__text")) == 0) { // __TEXT,__text found, save the offset and address for when looking for the calls. textSection = sect->offset; @@ -570,7 +590,8 @@ } break; - } + } +#endif case LC_DYSYMTAB: break; @@ -605,8 +626,11 @@ } // bind_macho uses the symbols. +#if macho_64 module_start = handle_symtable(module, (UInt32)binary, symtabCommand, symbol_handler, is64); - +#else + module_start = handle_symtable(module, (UInt32)binary, symtabCommand, symbol_handler); +#endif // Rebase the module before binding it. if(dyldInfoCommand && dyldInfoCommand->rebase_off) { @@ -991,7 +1015,7 @@ bind_location((UInt32*)address, (char*)symbolAddr, addend, BIND_TYPE_POINTER); } - else if(symbolName && (strcmp(symbolName, SYMBOL_DYLD_STUB_BINDER) != 0)) + else if(symbolName && (strncmp(symbolName, SYMBOL_DYLD_STUB_BINDER,sizeof(SYMBOL_DYLD_STUB_BINDER)) != 0)) { printf("Unable to bind symbol %s needed by %s\n", symbolName, module); getc(); @@ -1024,7 +1048,7 @@ bind_location((UInt32*)address, (char*)symbolAddr, addend, BIND_TYPE_POINTER); } - else if(symbolName && (strcmp(symbolName, SYMBOL_DYLD_STUB_BINDER) != 0)) + else if(symbolName && (strncmp(symbolName, SYMBOL_DYLD_STUB_BINDER,sizeof(SYMBOL_DYLD_STUB_BINDER)) != 0)) { printf("Unable to bind symbol %s needed by %s\n", symbolName, module); getc(); @@ -1048,7 +1072,7 @@ bind_location((UInt32*)address, (char*)symbolAddr, addend, BIND_TYPE_POINTER); } - else if(symbolName && (strcmp(symbolName, SYMBOL_DYLD_STUB_BINDER) != 0)) + else if(symbolName && (strncmp(symbolName, SYMBOL_DYLD_STUB_BINDER,sizeof(SYMBOL_DYLD_STUB_BINDER)) != 0)) { printf("Unable to bind symbol %s needed by %s\n", symbolName, module); getc(); @@ -1096,7 +1120,7 @@ segmentAddress += tmp2 + sizeof(void*); } } - else if(symbolName && (strcmp(symbolName, SYMBOL_DYLD_STUB_BINDER) != 0)) + else if(symbolName && (strncmp(symbolName, SYMBOL_DYLD_STUB_BINDER,sizeof(SYMBOL_DYLD_STUB_BINDER)) != 0)) { printf("Unable to bind symbol %s needed by %s\n", symbolName, module); getc(); @@ -1159,10 +1183,15 @@ * adjust it's internal symbol list (sort) to optimize locating new symbols * NOTE: returns the address if the symbol is "start", else returns 0xFFFFFFFF */ +#if macho_64 long long add_symbol(char* module,char* symbol, long long addr, char is64) +#else +long long add_symbol(char* module,char* symbol, long long addr) +#endif { +#if macho_64 if(is64) return 0xFFFFFFFF; // Fixme - +#endif // This only can handle 32bit symbols symbolList_t* new_entry= malloc(sizeof(symbolList_t)); DBG("Adding symbol %s at 0x%X\n", symbol, addr); @@ -1191,7 +1220,7 @@ do { - if ((module != NULL) && (strcmp(module,SYMBOLS_BUNDLE) != 0)) + if ((module != NULL) && (strncmp(module,SYMBOLS_BUNDLE,sizeof(SYMBOLS_BUNDLE)) != 0)) break; if(lookup_symbol && (UInt32)lookup_symbol != 0xFFFFFFFF) @@ -1232,7 +1261,7 @@ } #if DEBUG_MODULES - if(strcmp(name, SYMBOL_DYLD_STUB_BINDER) != 0) + if(strncmp(name, SYMBOL_DYLD_STUB_BINDER, sizeof(SYMBOL_DYLD_STUB_BINDER)) != 0) { verbose("Unable to locate symbol %s\n", name); getc(); @@ -1248,8 +1277,11 @@ * parse the symbol table * Lookup any undefined symbols */ - +#if macho_64 unsigned int handle_symtable(char *module, UInt32 base, struct symtab_command* symtabCommand, long long(*symbol_handler)(char*, char*, long long, char), char is64) +#else +unsigned int handle_symtable(char *module, UInt32 base, struct symtab_command* symtabCommand, long long(*symbol_handler)(char*, char*, long long)) +#endif { unsigned int module_start = 0xFFFFFFFF; @@ -1258,22 +1290,28 @@ return 0xFFFFFFFF; } char* symbolString = base + (char*)symtabCommand->stroff; - //char* symbolTable = base + symtabCommand->symoff; +#if macho_64 if(!is64) +#endif { struct nlist* symbolEntry = (void*)base + symtabCommand->symoff; while(symbolIndex < symtabCommand->nsyms) { if(symbolEntry->n_value) { - if(strstr(symbolString + symbolEntry->n_un.n_strx, "module_start") || (strcmp(symbolString + symbolEntry->n_un.n_strx, "start") == 0)) + if(strstr(symbolString + symbolEntry->n_un.n_strx, "module_start") || (strncmp(symbolString + symbolEntry->n_un.n_strx, "start", sizeof("start")) == 0)) { module_start = base + symbolEntry->n_value; DBG("n_value %x module_start %x\n", (unsigned)symbolEntry->n_value, (unsigned)module_start); } else { +#if macho_64 symbol_handler(module, symbolString + symbolEntry->n_un.n_strx, (long long)base + symbolEntry->n_value, is64); +#else + symbol_handler(module, symbolString + symbolEntry->n_un.n_strx, (long long)base + symbolEntry->n_value); +#endif + } #if DEBUG_MODULES bool isTexT = (((unsigned)symbolEntry->n_value > (unsigned)vmaddr) && ((unsigned)(vmaddr + vmsize) > (unsigned)symbolEntry->n_value )); @@ -1301,6 +1339,7 @@ symbolIndex++; // TODO remove } } +#if macho_64 else { struct nlist_64* symbolEntry = (void*)base + symtabCommand->symoff; @@ -1308,7 +1347,7 @@ while(symbolIndex < symtabCommand->nsyms) { - if(strstr(symbolString + symbolEntry->n_un.n_strx, "module_start") || (strcmp(symbolString + symbolEntry->n_un.n_strx, "start") == 0)) + if(strstr(symbolString + symbolEntry->n_un.n_strx, "module_start") || (strncmp(symbolString + symbolEntry->n_un.n_strx, "start",sizeof("start")) == 0)) { module_start = (unsigned int)(base + symbolEntry->n_value); } @@ -1321,6 +1360,7 @@ symbolIndex++; // TODO remove } } +#endif return module_start; @@ -1552,7 +1592,7 @@ // Make sure this is a kext. length = strlen(name); - if (strcmp(name + length - 7, ".bundle")) continue; + if (strncmp(name + length - 7, ".bundle",7)) continue; // Save the file name. strlcpy(gFileName, name, DEFAULT_BUNDLE_SPEC_SIZE); @@ -2034,12 +2074,12 @@ prop = XMLGetProperty(moduleDict, kPropNSPrincipalClass); if ((prop != 0) && prop->string) { - if (!strcmp(prop->string,SYSLIB_CLASS)) + if (!strncmp(prop->string,SYSLIB_CLASS, sizeof(SYSLIB_CLASS))) { tmpModule->willLoad = BundlePrioritySystemLib; break; } - if (!strcmp(prop->string,SYS_CLASS)) + if (!strncmp(prop->string,SYS_CLASS, sizeof(SYS_CLASS))) { tmpModule->willLoad = BundlePrioritySystem; break; Index: branches/cparm/i386/libsaio/modules.h =================================================================== --- branches/cparm/i386/libsaio/modules.h (revision 2111) +++ branches/cparm/i386/libsaio/modules.h (revision 2112) @@ -24,8 +24,8 @@ #include "efi.h" #define DEFAULT_BUNDLE_SPEC_SIZE 4096 +#define macho_64 1 - extern unsigned long long textAddress; extern unsigned long long textSection; @@ -80,14 +80,28 @@ void rebase_macho(void* base, char* rebase_stream, UInt32 size); EFI_STATUS bind_macho(char* module, void* base, char* bind_stream, UInt32 size); +#if macho_64 long long add_symbol(char* module,char* symbol, long long addr, char is64); +#else +long long add_symbol(char* module,char* symbol, long long addr); +#endif +#if macho_64 unsigned int parse_mach(char *module, void* binary, long long(*symbol_handler)(char*, char*, long long, char)); +#else +unsigned int parse_mach(char *module, void* binary, long long(*symbol_handler)(char*, char*, long long)); +#endif +#if macho_64 unsigned int handle_symtable(char *module, UInt32 base, struct symtab_command* symtabCommand, long long(*symbol_handler)(char*, char*, long long, char), char is64); +#else +unsigned int handle_symtable(char *module, UInt32 base, + struct symtab_command* symtabCommand, + long long(*symbol_handler)(char*, char*, long long)); +#endif unsigned int lookup_all_symbols(const char* module, const char* name); Index: branches/cparm/i386/libsaio/load.c =================================================================== --- branches/cparm/i386/libsaio/load.c (revision 2111) +++ branches/cparm/i386/libsaio/load.c (revision 2112) @@ -272,7 +272,7 @@ stop("Kernel overflows available space"); } - if (vmsize && (strcmp(segname, "__PRELINK") == 0 || strcmp(segname, "__PRELINK_INFO") == 0)) + if (vmsize && (strncmp(segname, "__PRELINK", sizeof("__PRELINK")) == 0 || strncmp(segname, "__PRELINK_INFO", sizeof("__PRELINK_INFO")) == 0)) safe_set_env(envgHaveKernelCache, true); // Copy from file load area. Index: branches/cparm/i386/libsaio/platform.c =================================================================== --- branches/cparm/i386/libsaio/platform.c (revision 2111) +++ branches/cparm/i386/libsaio/platform.c (revision 2112) @@ -393,7 +393,7 @@ struct env_struct *current_var; for(current_var=platform_env;current_var;current_var=(struct env_struct*)(current_var->hh.next)) { - if (strcmp(current_var->name, envConsoleErr) == 0) { + if (strncmp(current_var->name, envConsoleErr, sizeof(envConsoleErr)) == 0) { if (current_var->Type == kEnvPtr) { printf("stderr: %s \n",(char*)(uint32_t)current_var->ptr); } Index: branches/cparm/i386/libsaio/disk.c =================================================================== --- branches/cparm/i386/libsaio/disk.c (revision 2111) +++ branches/cparm/i386/libsaio/disk.c (revision 2112) @@ -265,13 +265,13 @@ static const char * bios_error(int errnum) { - static char errorstr[] = "Error 0x00"; + static char errorstr[11]; const char * errname; errname = getNameForValue( bios_errors, errnum ); if ( errname ) return errname; - sprintf(errorstr, "Error 0x%02x", errnum); + snprintf(errorstr, sizeof(errorstr), "Error 0x%02x", errnum); return errorstr; // No string, print error code only } @@ -1162,7 +1162,7 @@ dpme.dpme_boot_block); */ - if (strcmp(dpme_p->dpme_type, "Apple_HFS") == 0) { + if (strncmp(dpme_p->dpme_type, "Apple_HFS",sizeof("Apple_HFS")) == 0) { bvr = newAPMBVRef(biosdev, i, OSSwapBigToHostInt32(dpme_p->dpme_pblock_start) * factor, @@ -1706,6 +1706,7 @@ #ifdef BOOT_HELPER_SUPPORT int ret; char label[BVSTRLEN]; + char dirSpec[256]; int fh, fileSize, error; #endif for (bvr = chain; bvr < (BVRef)ULONG_MAX; bvr = bvr->next) { @@ -1720,12 +1721,14 @@ // if (bvr->flags & kBVFlagBooter) { - sprintf(dirSpec, "hd(%d,%d)/System/Library/CoreServices/", BIOS_DEV_UNIT(bvr), bvr->part_no); - strcpy(fileSpec, ".disk_label.contentDetails"); + snprintf(dirSpec, sizeof(dirsSpec),"hd(%d,%d)/System/Library/CoreServices/", BIOS_DEV_UNIT(bvr), bvr->part_no); + strlcpy(fileSpec, ".disk_label.contentDetails", sizeof(fileSpec)); ret = GetFileInfo(dirSpec, fileSpec, &flags, &time); if (!ret) { - fh = open(strcat(dirSpec, fileSpec)); + strlcat(dirSpec, fileSpec, sizeof(dirSpec)); + + fh = open(dirSpec); fileSize = file_size(fh); if (fileSize > 0 && fileSize < BVSTRLEN) { @@ -1740,7 +1743,7 @@ if (!error) { label[fileSize] = '\0'; - strcpy(bvr->altlabel, label); + strlcpy(bvr->altlabel, label, sizeof(bvr->altlabel)); } } } Index: branches/cparm/i386/libsaio/fake_efi.c =================================================================== --- branches/cparm/i386/libsaio/fake_efi.c (revision 2111) +++ branches/cparm/i386/libsaio/fake_efi.c (revision 2112) @@ -604,12 +604,12 @@ static EFI_CHAR16* getSmbiosChar16(const char * key, size_t* len) { - if (!GetgPlatformName() && strcmp(key, "SMproductname") == 0) + if (!GetgPlatformName() && strncmp(key, "SMproductname", sizeof("SMproductname")) == 0) readSMBIOS(thePlatformName); const char *PlatformName = GetgPlatformName() ; - const char *src = (strcmp(key, "SMproductname") == 0) ? PlatformName : getStringForKey(key, DEFAULT_SMBIOS_CONFIG); + const char *src = (strncmp(key, "SMproductname", sizeof("SMproductname")) == 0) ? PlatformName : getStringForKey(key, DEFAULT_SMBIOS_CONFIG); EFI_CHAR16* dst = 0; Index: branches/cparm/i386/MakeInc.dir =================================================================== --- branches/cparm/i386/MakeInc.dir (revision 2111) +++ branches/cparm/i386/MakeInc.dir (revision 2112) @@ -21,6 +21,10 @@ OMIT_FRAME_POINTER_CFLAG= HAVE_MD = YES +##CC = clang +##CC = llvm-gcc +##CC = gcc + installsrc:: $(SRCROOT) cp $(ALLSRC) $(SRCROOT) cd $(SRCROOT); chmod a-w $(ALLSRC) Index: branches/cparm/i386/boot2/boot.c =================================================================== --- branches/cparm/i386/boot2/boot.c (revision 2111) +++ branches/cparm/i386/boot2/boot.c (revision 2112) @@ -112,11 +112,25 @@ static void zeroBSS(void) { +#if (defined(__clang__)) /* WARNING : must be first, __GNUC__ seems to be also defined */ + + extern char bss_start __asm("section$start$__DATA$__bss"); + extern char bss_end __asm("section$end$__DATA$__bss"); + extern char common_start __asm("section$start$__DATA$__common"); + extern char common_end __asm("section$end$__DATA$__common"); + + bzero(&bss_start, (&bss_end - &bss_start)); + bzero(&common_start, (&common_end - &common_start)); + +#elif (defined(__GNUC__)) || (defined(__llvm__)) + extern char _DATA__bss__begin, _DATA__bss__end; extern char _DATA__common__begin, _DATA__common__end; bzero(&_DATA__bss__begin, (&_DATA__bss__end - &_DATA__bss__begin)); bzero(&_DATA__common__begin, (&_DATA__common__end - &_DATA__common__begin)); + +#endif } //========================================================================== @@ -242,7 +256,7 @@ { wait = true; - if (strval && ((strcmp(strval, "no") == 0) || (strcmp(strval, "No") == 0))) + if (strval && ((strncmp(strval, "no", sizeof("no")) == 0) || (strncmp(strval, "No", sizeof("No")) == 0))) { wait = false; } @@ -618,7 +632,7 @@ long cachetime, kerneltime = 0, exttime; if (trycache && !forcecache) do { - if (strcmp(bootInfo->bootFile, kDefaultKernel) != 0) { + if (strncmp(bootInfo->bootFile, kDefaultKernel,sizeof(kDefaultKernel)) != 0) { // if we haven't found the kernel yet, don't use the cache ret = GetFileInfo(NULL, bootInfo->bootFile, &flags, &kerneltime); if ((ret != 0) || ((flags & kFileTypeMask) != kFileTypeFlat)) @@ -1026,7 +1040,7 @@ // Make sure this is a kext or mkext. length = strlen(name); - if (strcmp(name + length - ext_size, ext)) continue; + if (strncmp(name + length - ext_size, ext, ext_size)) continue; if (name_to_compare) { Index: branches/cparm/i386/boot2/drivers.c =================================================================== --- branches/cparm/i386/boot2/drivers.c (revision 2111) +++ branches/cparm/i386/boot2/drivers.c (revision 2112) @@ -319,7 +319,7 @@ // Make sure this is a kext. length = strlen(name); - if (strcmp(name + length - 5, ".kext")) continue; + if (strncmp(name + length - 5, ".kext", 5)) continue; // Save the file name. strlcpy(gFileName, name, DEFAULT_DRIVER_SPEC_SIZE); @@ -744,7 +744,7 @@ required = XMLGetProperty(moduleDict, kPropOSBundleRequired); if ( (required == 0) || (required->type != kTagTypeString) || - !strcmp(required->string, "Safe Boot")) + !strncmp(required->string, "Safe Boot", sizeof("Safe Boot"))) { XMLFreeTag(moduleDict); return -2; Index: branches/cparm/i386/boot2/options.c =================================================================== --- branches/cparm/i386/boot2/options.c (revision 2111) +++ branches/cparm/i386/boot2/options.c (revision 2112) @@ -853,30 +853,30 @@ * TODO: this needs to be refactored. */ #if UNUSED - if (strcmp( booterCommand, "video" ) == 0) + if (strncmp( booterCommand, "video", sizeof("video") ) == 0) { printVBEModeInfo(); } else #endif - if ( strcmp( booterCommand, "memory" ) == 0) + if ( strncmp( booterCommand, "memory", sizeof("memory") ) == 0) { printMemoryInfo(); } - else if (strcmp(booterCommand, "lspci") == 0) + else if (strncmp(booterCommand, "lspci", sizeof( "lspci")) == 0) { lspci(); } - else if (strcmp(booterCommand, "more") == 0) + else if (strncmp(booterCommand, "more", sizeof("more")) == 0) { showTextFile(booterParam); } - else if (strcmp(booterCommand, "rd") == 0) + else if (strncmp(booterCommand, "rd", sizeof("rd")) == 0) { if (execute_hook("processRAMDiskCommand", (void*)argPtr, &booterParam, NULL, NULL, NULL, NULL) != EFI_SUCCESS) showMessage("ramdisk module not found, please install RamdiskLoader.dylib in /Extra/modules/"); } - else if (strcmp(booterCommand, "norescan") == 0) + else if (strncmp(booterCommand, "norescan", sizeof("norescan")) == 0) { if (get_env(envgEnableCDROMRescan)) { @@ -1063,7 +1063,7 @@ } else { if ( getValueForKey( kKernelNameKey, &val, &cnt, DEFAULT_BOOT_CONFIG ) ) { strlcpy( bootInfo->bootFile, val, sizeof(bootInfo->bootFile) ); - if (strcmp( bootInfo->bootFile, kDefaultKernel ) != 0) { + if (strncmp( bootInfo->bootFile, kDefaultKernel, sizeof(kDefaultKernel) ) != 0) { safe_set_env(envgOverrideKernel,true); } } else if (((BVRef)(uint32_t)get_env(envgBootVolume))->kernelfound == true) { Index: branches/cparm/i386/modules/RamDiskLoader/ramdisk.c =================================================================== --- branches/cparm/i386/modules/RamDiskLoader/ramdisk.c (revision 2111) +++ branches/cparm/i386/modules/RamDiskLoader/ramdisk.c (revision 2112) @@ -308,27 +308,27 @@ char param[1024]; getNextArg(&ptr, param); - if (strcmp(cmd, "m") == 0) + if (strncmp(cmd, "m",sizeof("m")) == 0) { mountRAMDisk(param); sleep(2); } - else if (strcmp(cmd, "u") == 0) + else if (strncmp(cmd, "u", sizeof("u")) == 0) { umountRAMDisk(); sleep(2); } - else if (strcmp(cmd, "e") == 0) + else if (strncmp(cmd, "e", sizeof("e")) == 0) { setRAMDiskBTHook(true); sleep(2); } - else if (strcmp(cmd, "d") == 0) + else if (strncmp(cmd, "d", sizeof("d")) == 0) { setRAMDiskBTHook(false); sleep(2); } - else if (strcmp(cmd, "i") == 0) + else if (strncmp(cmd, "i", sizeof("i")) == 0) { setActiveDisplayPage(1); clearScreenRows(0, 24); Index: branches/cparm/i386/modules/KextPatcher/kext_patcher.c =================================================================== --- branches/cparm/i386/modules/KextPatcher/kext_patcher.c (revision 2111) +++ branches/cparm/i386/modules/KextPatcher/kext_patcher.c (revision 2112) @@ -377,8 +377,8 @@ #if UNUSED if(/*patch_gma_deviceid &&*/ ( - (strcmp(bundleID, "com.apple.driver.AppleIntelGMA950") == 0) || - (strcmp(bundleID, "com.apple.driver.AppleIntelIntegratedFramebuffer") == 0) + (strncmp(bundleID, "com.apple.driver.AppleIntelGMA950", sizeof( "com.apple.driver.AppleIntelGMA950")) == 0) || + (strncmp(bundleID, "com.apple.driver.AppleIntelIntegratedFramebuffer",sizeof("com.apple.driver.AppleIntelIntegratedFramebuffer")) == 0) ) ) { Index: branches/cparm/i386/modules/GUI/gui.c =================================================================== --- branches/cparm/i386/modules/GUI/gui.c (revision 2111) +++ branches/cparm/i386/modules/GUI/gui.c (revision 2112) @@ -427,7 +427,7 @@ int i; for (i = 0; (unsigned)i < sizeof(images) / sizeof(images[0]); i++) { - if (strcmp(name, images[i].name) == 0) + if (strncmp(name, images[i].name, sizeof(images[i].name)) == 0) return i; // found the name } return -1; @@ -444,7 +444,7 @@ // NOTE: This algorithm assumes that the embeddedImages is sorted. // This is currently done using the make file. If the array is every // manualy generated, this *will* fail to work properly. - while((result = strcmp(name, embeddedImages[compareIndex].name)) != 0) + while((result = strncmp(name, embeddedImages[compareIndex].name, sizeof(embeddedImages[compareIndex].name))) != 0) { if(result > 0) // We need to search a HIGHER index { @@ -503,7 +503,7 @@ return 1; } } - sprintf(dirspec, "%s/%s/%s.png", src, theme_name, image); + snprintf(dirspec, sizeof(dirspec),"%s/%s/%s.png", src, theme_name, image); width = 0; height = 0; @@ -847,7 +847,7 @@ // check layout for horizontal or vertical gui.layout = HorizontalLayout; if(getValueForKey( "devices_layout", &string, &len, theme)) { - if (!strcmp (string, "vertical")) { + if (!strncmp (string, "vertical",sizeof("vertical"))) { gui.layout = VerticalLayout; } } @@ -1181,17 +1181,17 @@ retry: ret = GetFileInfo("rd(0,0)/Extra/", "Themes", &flags, &time); if ((ret == 0) && ((flags & kFileTypeMask) == kFileTypeDirectory)) { - sprintf(dirsrc, "rd(0,0)/Extra/Themes"); + snprintf(dirsrc,sizeof(dirsrc), "rd(0,0)/Extra/Themes"); } else { ret = GetFileInfo("/Extra/", "Themes", &flags, &time); if ((ret == 0) && ((flags & kFileTypeMask) == kFileTypeDirectory)) { - sprintf(dirsrc, "/Extra/Themes"); + snprintf(dirsrc,sizeof(dirsrc), "/Extra/Themes"); } else { ret = GetFileInfo("bt(0,0)/Extra/", "Themes", &flags, &time); if ((ret == 0) && ((flags & kFileTypeMask) == kFileTypeDirectory)) { - sprintf(dirsrc, "bt(0,0)/Extra/Themes"); + snprintf(dirsrc,sizeof(dirsrc), "bt(0,0)/Extra/Themes"); } else { printf("Failed to find the /extra/Themes folder\n"); @@ -1205,17 +1205,17 @@ { ret = GetFileInfo("rd(0,0)/Extra/Themes/", theme_name, &flags, &time); if ((ret == 0) && ((flags & kFileTypeMask) == kFileTypeDirectory)) { - sprintf(dirsrc, "rd(0,0)/Extra/Themes"); + snprintf(dirsrc,sizeof(dirsrc), "rd(0,0)/Extra/Themes"); } else { ret = GetFileInfo("/Extra/Themes/", theme_name, &flags, &time); if ((ret == 0) && ((flags & kFileTypeMask) == kFileTypeDirectory)) { - sprintf(dirsrc, "/Extra/Themes"); + snprintf(dirsrc,sizeof(dirsrc), "/Extra/Themes"); } else { ret = GetFileInfo("bt(0,0)/Extra/Themes/", theme_name, &flags, &time); if ((ret == 0) && ((flags & kFileTypeMask) == kFileTypeDirectory)) { - sprintf(dirsrc, "bt(0,0)/Extra/Themes"); + snprintf(dirsrc,sizeof(dirsrc), "bt(0,0)/Extra/Themes"); } else { printf("Failed to find the /extra/Themes/%s folder\n",theme_name); @@ -1265,7 +1265,7 @@ } #endif - if (ret && (strcmp(theme_name, THEME_NAME_DEFAULT) != 0)) { + if (ret && (strncmp(theme_name, THEME_NAME_DEFAULT,sizeof(THEME_NAME_DEFAULT)) != 0)) { theme_name = THEME_NAME_DEFAULT; ret = startGUI(); @@ -1287,7 +1287,7 @@ return 1; } - sprintf(dirspec, "%s/%s/theme.plist", dirsrc ,theme_name); + snprintf(dirspec, sizeof(dirspec), "%s/%s/theme.plist", dirsrc ,theme_name); if (loadConfigFile(dirspec, &themeConfig) != 0) { @@ -2582,7 +2582,7 @@ usePngImage = false; return; } - sprintf(dirspec, "%s/%s/boot.png", src, theme_name); + snprintf(dirspec, sizeof(dirspec), "%s/%s/boot.png", src, theme_name); if ((strlen(theme_name) == 0) || (loadPngImage(dirspec, &bootImageWidth, &bootImageHeight, &bootImageData) == -1)) { #ifdef EMBED_THEME if ((loadEmbeddedPngImage(__boot_png, __boot_png_len, &bootImageWidth, &bootImageHeight, &bootImageData)) == -1) Index: branches/cparm/i386/modules/GUI/GUI_module.c =================================================================== --- branches/cparm/i386/modules/GUI/GUI_module.c (revision 2111) +++ branches/cparm/i386/modules/GUI/GUI_module.c (revision 2112) @@ -810,7 +810,8 @@ char *name = NULL; int cnt; - if (getValueForKey(kCDROMPromptKey, &val, &cnt, DEFAULT_BOOT_CONFIG)) { + if (getValueForKey(kCDROMPromptKey, &val, &cnt, DEFAULT_BOOT_CONFIG)) + { prompt = malloc(cnt + 1); if (!prompt) { stop("Couldn't allocate memory for the prompt\n"); //TODO: Find a better stategie @@ -830,7 +831,7 @@ stop("Couldn't allocate memory for the prompt\n"); //TODO: Find a better stategie return -1; } - sprintf(prompt, "Press ENTER to start up from %s, or press any key to enter startup options.", name); + snprintf(prompt, 256 ,"Press ENTER to start up from %s, or press any key to enter startup options.", name); free(name); } @@ -1038,7 +1039,7 @@ /* * TODO: this needs to be refactored. */ - if (strcmp( booterCommand, "video" ) == 0) + if (strncmp( booterCommand, "video", sizeof("video") ) == 0) { if (getVideoMode() == GRAPHICS_MODE) { @@ -1049,7 +1050,7 @@ printVBEModeInfo(); } } - else if ( strcmp( booterCommand, "memory" ) == 0) + else if ( strncmp( booterCommand, "memory", sizeof("memory") ) == 0) { if (getVideoMode() == GRAPHICS_MODE ) { @@ -1060,20 +1061,20 @@ printMemoryInfo(); } } - else if (strcmp(booterCommand, "lspci") == 0) + else if (strncmp(booterCommand, "lspci", sizeof( "lspci")) == 0) { lspci(); } - else if (strcmp(booterCommand, "more") == 0) + else if (strncmp(booterCommand, "more", sizeof("more")) == 0) { showTextFile(booterParam); } - else if (strcmp(booterCommand, "rd") == 0) + else if (strncmp(booterCommand, "rd", sizeof("rd")) == 0) { if (execute_hook("processRAMDiskCommand", (void*)argPtr, &booterParam, NULL, NULL, NULL, NULL) != EFI_SUCCESS) showMessage("ramdisk module not found, please install RamdiskLoader.dylib in /Extra/modules/"); } - else if (strcmp(booterCommand, "norescan") == 0) + else if (strncmp(booterCommand, "norescan", sizeof("norescan")) == 0) { if (get_env(envgEnableCDROMRescan)) { Index: branches/cparm/i386/modules/GraphicsEnabler/gma.c =================================================================== --- branches/cparm/i386/modules/GraphicsEnabler/gma.c (revision 2111) +++ branches/cparm/i386/modules/GraphicsEnabler/gma.c (revision 2112) @@ -128,21 +128,21 @@ devprop_add_value(device, "model", (uint8_t*)model, (strlen(model) + 1)); devprop_add_value(device, "device_type", (uint8_t*)"display", 8); - if ((strcmp(model, "Mobile GMA950") == 0) || - (strcmp(model, "Mobile GMA3150") == 0)) + if ((strncmp(model, "Mobile GMA950", sizeof("Mobile GMA950")) == 0) || + (strncmp(model, "Mobile GMA3150", sizeof("Mobile GMA3150")) == 0)) { devprop_add_value(device, "AAPL,HasPanel", reg_TRUE, 4); devprop_add_value(device, "built-in", &BuiltIn, 1); devprop_add_value(device, "class-code", ClassFix, 4); } - else if ((strcmp(model, "Desktop GMA950")== 0) || - (strcmp(model, "Desktop GMA3150") == 0)) + else if ((strncmp(model, "Desktop GMA950",sizeof("Desktop GMA950"))== 0) || + (strncmp(model, "Desktop GMA3150",sizeof("Desktop GMA3150")) == 0)) { BuiltIn = 0x01; devprop_add_value(device, "built-in", &BuiltIn, 1); devprop_add_value(device, "class-code", ClassFix, 4); } - else if ( strcmp(model, "GMAX3100") == 0 ) + else if ( strncmp(model, "GMAX3100", sizeof("GMAX3100")) == 0 ) { devprop_add_value(device, "AAPL,HasPanel",GMAX3100_vals[0], 4); devprop_add_value(device, "AAPL,SelfRefreshSupported",GMAX3100_vals[1], 4); @@ -168,7 +168,7 @@ devprop_add_value(device, "AAPL01,Stretch",GMAX3100_vals[21], 4); devprop_add_value(device, "class-code", ClassFix, 4); } - else if (strcmp(model, "Intel HD Graphics 3000") == 0) + else if (strncmp(model, "Intel HD Graphics 3000", sizeof("Intel HD Graphics 3000")) == 0) { devprop_add_value(device, "AAPL,os-info", HD3000_os_info, 20); } Index: branches/cparm/i386/modules/GraphicsEnabler/nvidia.c =================================================================== --- branches/cparm/i386/modules/GraphicsEnabler/nvidia.c (revision 2111) +++ branches/cparm/i386/modules/GraphicsEnabler/nvidia.c (revision 2112) @@ -1044,7 +1044,7 @@ strncpy(sig, (char *)&dcbtable[-7], 7); recordlength = 10; - if (strcmp(sig, "DEV_REC")) { + if (strncmp(sig, "DEV_REC",sizeof("DEV_REC"))) { printf("Bad Display Configuration Block signature (%s)\n", sig); return PATCH_ROM_FAILED; } Index: branches/cparm/i386/modules/SMBiosGetters/mysmbios.c =================================================================== --- branches/cparm/i386/modules/SMBiosGetters/mysmbios.c (revision 2111) +++ branches/cparm/i386/modules/SMBiosGetters/mysmbios.c (revision 2112) @@ -739,11 +739,11 @@ { sm_chosen = sm_macbook_defaults ; } - else if (!strcmp ("iMac12,1", str)) + else if (!strncmp ("iMac12,1", str,sizeof("iMac12,1"))) { sm_chosen = sm_imac_sandy_defaults ; } - else if (!strcmp ("iMac11,1", str)) + else if (!strncmp ("iMac11,1", str, sizeof("iMac11,1"))) { sm_chosen = sm_imac_core_defaults ; } @@ -919,7 +919,7 @@ if (SMBSetters[idx].keyString) { - if ((SMBSetters[idx].defaultValue) && *(SMBSetters[idx].defaultValue) && randomSerial && (!strcmp ("SMserial", SMBSetters[idx].keyString))) + if ((SMBSetters[idx].defaultValue) && *(SMBSetters[idx].defaultValue) && randomSerial && (!strncmp ("SMserial", SMBSetters[idx].keyString, sizeof("SMserial")))) { string = *(SMBSetters[idx].defaultValue); break; Index: branches/cparm/i386/modules/Keymapper/Keylayout.c =================================================================== --- branches/cparm/i386/modules/Keymapper/Keylayout.c (revision 2111) +++ branches/cparm/i386/modules/Keymapper/Keylayout.c (revision 2112) @@ -145,7 +145,7 @@ { snprintf(layoutPath, sizeof(layoutPath),"/Extra/Keymaps/%s", val); // Add the extension if needed - if (len <= 4 || strcmp(val+len-4,".lyt") != 0) + if (len <= 4 || strncmp(val+len-4,".lyt", sizeof(".lyt")) != 0) strlcat(layoutPath, ".lyt", sizeof(layoutPath)); if (!load_keyboard_layout_file(layoutPath)) Index: branches/cparm/i386/modules/Keymapper/Keymapper.c =================================================================== --- branches/cparm/i386/modules/Keymapper/Keymapper.c (revision 2111) +++ branches/cparm/i386/modules/Keymapper/Keymapper.c (revision 2112) @@ -230,7 +230,7 @@ map_kb_type = "NONE"; // Default to QWERTY } - if (map_kb_type && (strcmp(map_kb_type, "AZERTY") == 0)) + if (map_kb_type && (strncmp(map_kb_type, "AZERTY",sizeof("AZERTY")) == 0)) c = AZERTY_switch(c); out: Index: branches/cparm/i386/modules/SMBiosPatcher/smbios_patcher.c =================================================================== --- branches/cparm/i386/modules/SMBiosPatcher/smbios_patcher.c (revision 2111) +++ branches/cparm/i386/modules/SMBiosPatcher/smbios_patcher.c (revision 2112) @@ -505,11 +505,11 @@ { sm_chosen = sm_macbook_defaults ; } - else if (!strcmp ("iMac12,1", str)) + else if (!strncmp ("iMac12,1", str, sizeof("iMac12,1"))) { sm_chosen = sm_imac_sandy_defaults ; } - else if (!strcmp ("iMac11,1", str)) + else if (!strncmp ("iMac11,1", str,sizeof("iMac11,1"))) { sm_chosen = sm_imac_core_defaults ; } @@ -535,7 +535,7 @@ } - if (!strcmp ("SMserial", key)) { + if (!strncmp ("SMserial", key, sizeof("SMserial"))) { if (!serial_done) { bzero (fake_serial,sizeof(fake_serial)); @@ -970,7 +970,7 @@ snprintf(altname, sizeof(altname),"%s_%d",smbios_properties[j].name, tablespresent[cur->type] + 1); if (smbios_properties[j].table_type == cur->type && smbios_properties[j].value_type == SMSTRING && - smbios_properties[j].auto_str && randomSerial && (!strcmp ("SMserial", smbios_properties[j].name))) { + smbios_properties[j].auto_str && randomSerial && (!strncmp ("SMserial", smbios_properties[j].name, sizeof("SMserial")))) { stringlen += strlen(smbios_properties[j].auto_str(smbios_properties[j].name, tablespresent[cur->type])) + 1; @@ -1022,7 +1022,7 @@ snprintf(altname, sizeof(altname), "%s_%d",smbios_properties[j].name, tablespresent[smbios_table_descriptions[i].type] + 1); if (smbios_properties[j].table_type == smbios_table_descriptions[i].type && smbios_properties[j].value_type==SMSTRING && - smbios_properties[j].auto_str && randomSerial && (!strcmp ("SMserial", smbios_properties[j].name))) { + smbios_properties[j].auto_str && randomSerial && (!strncmp ("SMserial", smbios_properties[j].name, sizeof("SMserial")))) { stringlen += strlen(smbios_properties[j].auto_str(smbios_properties[j].name, tablespresent[smbios_table_descriptions[i].type])) + 1; @@ -1139,7 +1139,7 @@ if (smbios_properties[j].table_type == newcur->type) { switch (smbios_properties[j].value_type) { case SMSTRING: - if (smbios_properties[j].auto_str && randomSerial && (!strcmp ("SMserial", smbios_properties[j].name))) + if (smbios_properties[j].auto_str && randomSerial && (!strncmp ("SMserial", smbios_properties[j].name,sizeof("SMserial")))) { str = smbios_properties[j].auto_str(smbios_properties[j].name, tablespresent[newcur->type]); size = strlen(str); @@ -1265,7 +1265,7 @@ if (smbios_properties[j].table_type == newcur->type) { switch (smbios_properties[j].value_type) { case SMSTRING: - if (smbios_properties[j].auto_str && randomSerial && (!strcmp ("SMserial", smbios_properties[j].name))) + if (smbios_properties[j].auto_str && randomSerial && (!strncmp ("SMserial", smbios_properties[j].name,sizeof("SMserial")))) { str = smbios_properties[j].auto_str(smbios_properties[j].name, tablespresent[newcur->type]); size = strlen(str); Index: branches/cparm/i386/modules/Resolution/915resolution.c =================================================================== --- branches/cparm/i386/modules/Resolution/915resolution.c (revision 2111) +++ branches/cparm/i386/modules/Resolution/915resolution.c (revision 2112) @@ -287,7 +287,7 @@ */ map->ati_tables.base = map->bios_ptr; map->ati_tables.AtomRomHeader = (ATOM_ROM_HEADER *) (map->bios_ptr + *(unsigned short *) (map->bios_ptr + OFFSET_TO_POINTER_TO_ATOM_ROM_HEADER)); - if (strcmp ((char *) map->ati_tables.AtomRomHeader->uaFirmWareSignature, "ATOM") == 0) + if (strncmp ((char *) map->ati_tables.AtomRomHeader->uaFirmWareSignature, "ATOM", sizeof("ATOM")) == 0) { // ATI Radeon Card map->bios = BT_ATI_1; Index: branches/cparm/i386/modules/ACPICodec/acpi_codec.c =================================================================== --- branches/cparm/i386/modules/ACPICodec/acpi_codec.c (revision 2111) +++ branches/cparm/i386/modules/ACPICodec/acpi_codec.c (revision 2112) @@ -182,7 +182,7 @@ resolve_##s(unsigned u defaultentry, char *str, int base) \ { \ unsigned u entry = defaultentry; \ -if (str && (strcmp(str,"Default") != 0)) { \ +if (str && (strncmp(str,"Default",sizeof("Default")) != 0)) { \ entry = strtoul((const char *)str, NULL,base); \ } \ return entry; \ @@ -1601,7 +1601,7 @@ { char *tmpstr = XMLCastString(XMLGetProperty(PstateTag, (const char*)"Mode")); - if (strcmp(tmpstr,"Expert") == 0) + if (strncmp(tmpstr,"Expert",sizeof("Expert")) == 0) { p_states_count = pstate_tag_count - 1 ; // - 1 = - ("Mode" tag) expert = 1; @@ -4420,7 +4420,7 @@ if ( match_drop ) { char *tmp = XMLCastString(match_drop); - if (tmp && (strcmp(tmp,"No") != 0)) + if (tmp && (strncmp(tmp,"No",sizeof("No")) != 0)) { dropoffset++; DBG(" %s table dropped\n",tableSig); @@ -4598,7 +4598,7 @@ if ( match_drop ) { char *tmp = XMLCastString(match_drop); - if (strcmp(tmp,"No") != 0) + if (strncmp(tmp,"No",sizeof("No")) != 0) { dropoffset++; DBG(" %s table dropped\n",tableSig); @@ -4801,7 +4801,7 @@ // Make sure this is a kext. length = strlen(name); - if (strcmp(name + length - 4, ".aml")) + if (strncmp(name + length - 4, ".aml",sizeof(".aml")) != 0) { #if DEBUG_ACPI printf("Ignoring %s\n", name); Index: branches/cparm/i386/libsa/bzero.s =================================================================== --- branches/cparm/i386/libsa/bzero.s (revision 2111) +++ branches/cparm/i386/libsa/bzero.s (revision 2112) @@ -1,110 +0,0 @@ -/* - * Copyright (c) 2000 Apple Computer, Inc. All rights reserved. - * - * @APPLE_OSREFERENCE_LICENSE_HEADER_START@ - * - * This file contains Original Code and/or Modifications of Original Code - * as defined in and that are subject to the Apple Public Source License - * Version 2.0 (the 'License'). You may not use this file except in - * compliance with the License. The rights granted to you under the License - * may not be used to create, or enable the creation or redistribution of, - * unlawful or unlicensed copies of an Apple operating system, or to - * circumvent, violate, or enable the circumvention or violation of, any - * terms of an Apple operating system software license agreement. - * - * Please obtain a copy of the License at - * http://www.opensource.apple.com/apsl/ and read it before using this file. - * - * The Original Code and all software distributed under the License are - * distributed on an 'AS IS' basis, WITHOUT WARRANTY OF ANY KIND, EITHER - * EXPRESS OR IMPLIED, AND APPLE HEREBY DISCLAIMS ALL SUCH WARRANTIES, - * INCLUDING WITHOUT LIMITATION, ANY WARRANTIES OF MERCHANTABILITY, - * FITNESS FOR A PARTICULAR PURPOSE, QUIET ENJOYMENT OR NON-INFRINGEMENT. - * Please see the License for the specific language governing rights and - * limitations under the License. - * - * @APPLE_OSREFERENCE_LICENSE_HEADER_END@ - */ - /* - * @OSF_COPYRIGHT@ - */ -/* - * Mach Operating System - * Copyright (c) 1991,1990 Carnegie Mellon University - * All Rights Reserved. - * - * Permission to use, copy, modify and distribute this software and its - * documentation is hereby granted, provided that both the copyright - * notice and this permission notice appear in all copies of the - * software, derivative works or modified versions, and any portions - * thereof, and that both notices appear in supporting documentation. - * - * CARNEGIE MELLON ALLOWS FREE USE OF THIS SOFTWARE IN ITS "AS IS" - * CONDITION. CARNEGIE MELLON DISCLAIMS ANY LIABILITY OF ANY KIND FOR - * ANY DAMAGES WHATSOEVER RESULTING FROM THE USE OF THIS SOFTWARE. - * - * Carnegie Mellon requests users of this software to return to - * - * Software Distribution Coordinator or Software.Distribution@CS.CMU.EDU - * School of Computer Science - * Carnegie Mellon University - * Pittsburgh PA 15213-3890 - * - * any improvements or extensions that they make and grant Carnegie Mellon - * the rights to redistribute these changes. - */ -/* - */ - -#include - -/* - * void *memset(void * addr, int pattern, size_t length) - */ - -LABEL(_memset) - pushl %edi - movl 4+ 4(%esp),%edi /* addr */ - movb 4+ 8(%esp),%al /* pattern */ - movl 4+ 12(%esp),%edx /* length */ - movb %al,%ah - movw %ax,%cx - shll $16,%eax - movw %cx,%ax - cld -/* zero longs */ - movl %edx,%ecx - shrl $2,%ecx - rep - stosl -/* zero bytes */ - movl %edx,%ecx - andl $3,%ecx - rep - stosb - movl 4+ 4(%esp),%eax /* returns its first argument */ - popl %edi - ret - -/* - * void bzero(char * addr, size_t length) - */ -LABEL(___bzero) /* only for a compatibility issue */ -LABEL(_bzero) - pushl %edi - movl 4+ 4(%esp),%edi /* addr */ - movl 4+ 8(%esp),%edx /* length */ - xorl %eax,%eax - cld -/* zero longs */ - movl %edx,%ecx - shrl $2,%ecx - rep - stosl -/* zero bytes */ - movl %edx,%ecx - andl $3,%ecx - rep - stosb - popl %edi - ret \ No newline at end of file Index: branches/cparm/i386/libsa/bcopy.s =================================================================== --- branches/cparm/i386/libsa/bcopy.s (revision 2111) +++ branches/cparm/i386/libsa/bcopy.s (revision 2112) @@ -1,168 +0,0 @@ -/* - * Copyright (c) 2000 Apple Computer, Inc. All rights reserved. - * - * @APPLE_OSREFERENCE_LICENSE_HEADER_START@ - * - * This file contains Original Code and/or Modifications of Original Code - * as defined in and that are subject to the Apple Public Source License - * Version 2.0 (the 'License'). You may not use this file except in - * compliance with the License. The rights granted to you under the License - * may not be used to create, or enable the creation or redistribution of, - * unlawful or unlicensed copies of an Apple operating system, or to - * circumvent, violate, or enable the circumvention or violation of, any - * terms of an Apple operating system software license agreement. - * - * Please obtain a copy of the License at - * http://www.opensource.apple.com/apsl/ and read it before using this file. - * - * The Original Code and all software distributed under the License are - * distributed on an 'AS IS' basis, WITHOUT WARRANTY OF ANY KIND, EITHER - * EXPRESS OR IMPLIED, AND APPLE HEREBY DISCLAIMS ALL SUCH WARRANTIES, - * INCLUDING WITHOUT LIMITATION, ANY WARRANTIES OF MERCHANTABILITY, - * FITNESS FOR A PARTICULAR PURPOSE, QUIET ENJOYMENT OR NON-INFRINGEMENT. - * Please see the License for the specific language governing rights and - * limitations under the License. - * - * @APPLE_OSREFERENCE_LICENSE_HEADER_END@ - */ -/* - * @OSF_COPYRIGHT@ - */ -/* - * Mach Operating System - * Copyright (c) 1991,1990 Carnegie Mellon University - * All Rights Reserved. - * - * Permission to use, copy, modify and distribute this software and its - * documentation is hereby granted, provided that both the copyright - * notice and this permission notice appear in all copies of the - * software, derivative works or modified versions, and any portions - * thereof, and that both notices appear in supporting documentation. - * - * CARNEGIE MELLON ALLOWS FREE USE OF THIS SOFTWARE IN ITS "AS IS" - * CONDITION. CARNEGIE MELLON DISCLAIMS ANY LIABILITY OF ANY KIND FOR - * ANY DAMAGES WHATSOEVER RESULTING FROM THE USE OF THIS SOFTWARE. - * - * Carnegie Mellon requests users of this software to return to - * - * Software Distribution Coordinator or Software.Distribution@CS.CMU.EDU - * School of Computer Science - * Carnegie Mellon University - * Pittsburgh PA 15213-3890 - * - * any improvements or extensions that they make and grant Carnegie Mellon - * the rights to redistribute these changes. - */ -/* - */ - -#include - -/* void *memcpy((void *) to, (const void *) from, (size_t) bcount) */ - -LABEL(_memcpy) - pushl %edi - pushl %esi - movl 8+ 4(%esp),%edi /* to */ - movl %edi,%eax /* returns its first argument */ - movl 8+ 8(%esp),%esi /* from */ -memcpy_common: - movl 8+ 12(%esp),%edx /* number of bytes */ - cld -/* move longs*/ - movl %edx,%ecx - shrl $2,%ecx - rep - movsl -/* move bytes*/ - movl %edx,%ecx - andl $3,%ecx - rep - movsb - popl %esi - popl %edi - ret - -/* void bcopy((const char *) from, (char *) to, (unsigned int) count) */ - -LABEL(_bcopy_no_overwrite) - pushl %edi - pushl %esi - movl 8+ 8(%esp),%edi /* to */ - movl 8+ 4(%esp),%esi /* from */ - jmp memcpy_common - -/* bcopy16(from, to, bcount) using word moves */ - -LABEL(_bcopy16) - pushl %edi - pushl %esi - movl 8+12(%esp),%edx /* 8 for the two pushes above */ - movl 8+ 8(%esp),%edi - movl 8+ 4(%esp),%esi -/* move words */ -0: cld - movl %edx,%ecx - shrl $1,%ecx - rep - movsw -/* move bytes */ - movl %edx,%ecx - andl $1,%ecx - rep - movsb - popl %esi - popl %edi - ret - - - /* - * Based on NetBSD's bcopy.S from their libc. - * bcopy(src, dst, cnt) - * ws@tools.de (Wolfgang Solfrank, TooLs GmbH) +49-228-985800 - */ -LABEL(_bcopy) - pushl %esi - pushl %edi - movl 12(%esp),%esi - movl 16(%esp),%edi - movl 20(%esp),%ecx - - movl %edi,%edx - subl %esi,%edx - cmpl %ecx,%edx /* overlapping && src < dst? */ - movl %ecx,%edx - jb 1f - - shrl $2,%ecx /* copy by 32-bit words */ - cld /* nope, copy forwards */ - rep - movsl - movl %edx,%ecx - andl $3,%ecx /* any bytes left? */ - rep - movsb - popl %edi - popl %esi - ret - - -1: - addl %ecx,%edi /* copy backwards */ - addl %ecx,%esi - decl %edi - decl %esi - andl $3,%ecx /* any fractional bytes? */ - std - rep - movsb - movl %edx,%ecx /* copy remainder by 32-bit words */ - shrl $2,%ecx - subl $3,%esi - subl $3,%edi - rep - movsl - popl %edi - popl %esi - cld - ret Index: branches/cparm/i386/libsa/memcmp.s =================================================================== --- branches/cparm/i386/libsa/memcmp.s (revision 0) +++ branches/cparm/i386/libsa/memcmp.s (revision 2112) @@ -0,0 +1,185 @@ +/* + * Copyright (c) 2005 Apple Computer, Inc. All rights reserved. + * + * @APPLE_LICENSE_HEADER_START@ + * + * This file contains Original Code and/or Modifications of Original Code + * as defined in and that are subject to the Apple Public Source License + * Version 2.0 (the 'License'). You may not use this file except in + * compliance with the License. Please obtain a copy of the License at + * http://www.opensource.apple.com/apsl/ and read it before using this + * file. + * + * The Original Code and all software distributed under the License are + * distributed on an 'AS IS' basis, WITHOUT WARRANTY OF ANY KIND, EITHER + * EXPRESS OR IMPLIED, AND APPLE HEREBY DISCLAIMS ALL SUCH WARRANTIES, + * INCLUDING WITHOUT LIMITATION, ANY WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE, QUIET ENJOYMENT OR NON-INFRINGEMENT. + * Please see the License for the specific language governing rights and + * limitations under the License. + * + * @APPLE_LICENSE_HEADER_END@ + */ + + +// *************** *********** +// * M E M C M P * and * B C M P * +// *************** *********** +// +// int memcmp(const char *s1, const char *s2, size_t len); +// int bcmp(const char *s1, const char *s2, size_t len); +// +// Bcmp returns (+,0,-), whereas memcmp returns the true difference +// between the first differing bytes, but we treat them identically. +// +// We optimize the compare by doing it with SSE. This introduces +// a complication: if we blindly did vector loads from both sides until +// finding a difference, we might get a spurious page fault by +// reading bytes past the difference. To avoid this, we never do a load +// that crosses a page boundary. + +#define kShort 18 // too short for vectors (must be >16) + + .text + .align 4 + + .globl _memcmp + .globl _bcmp + +_memcmp: // int memcmp(const char *s1,const char *s2,size_t len); +_bcmp: // int bcmp(const char *s1,const char *s2,size_t len); + pushl %esi + pushl %edi + movl 20(%esp),%ecx // get length + movl 12(%esp),%esi // get LHS ptr + movl 16(%esp),%edi // get RHS ptr + cmpl $(kShort),%ecx // worth accelerating? + ja LNotShort // yes + + +// Too short to bother with parallel compares. Loop over bytes. +// %esi = LHS ptr +// %edi = RHS ptr +// %ecx = length (<= kShort) + +LShort: + testl %ecx,%ecx // 0-length? + jnz LShortLoop // no + xorl %eax,%eax // return 0 + jmp LExit + .align 4,0x90 // align inner loops to optimize I-fetch +LShortLoop: // loop over bytes + movzb (%esi),%eax // get LHS byte + movzb (%edi),%edx // get RHS byte + incl %esi + incl %edi + subl %edx,%eax // compare them + jnz LExit // done if not equal + decl %ecx // decrement length + jnz LShortLoop +LExit: // return value is in %eax + popl %edi + popl %esi + ret + +LNotEqual: // here from LLoopOverBytes with LHS in eax + movzb (%edi),%edx // get RHS byte + subl %edx,%eax // generate return value (nonzero) + popl %edi + popl %esi + ret + + +// Loop over bytes until we reach end of a page. +// %esi = LHS ptr +// %edi = RHS ptr +// %ecx = length remaining after end of loop (ie, already adjusted) +// %edx = #bytes until next page (1..15) + + .align 4,0x90 // align inner loops to optimize I-fetch +LLoopOverBytes: + movzb (%esi),%eax // get LHS byte + inc %esi + cmpb (%edi),%al // compare to RHS byte + jnz LNotEqual // done if not equal + inc %edi + dec %edx // more to go? + jnz LLoopOverBytes + + +// Long enough to justify overhead of setting up vector compares. In order to +// avoid spurious page faults, we loop over: +// +// min( length, bytes_in_LHS_page, bytes_in_RHS_page) >> 4 +// +// 16-byte chunks. When we near a page end, we have to revert to a byte-by-byte +// comparison until reaching the next page, then resume the vector comparison. +// %esi = LHS ptr +// %edi = RHS ptr +// %ecx = length (> kShort) + +LNotShort: + movl %esi,%eax // copy ptrs + movl %edi,%edx + andl $4095,%eax // mask down to page offsets + andl $4095,%edx + cmpl %eax,%edx // which is bigger? + cmova %edx,%eax // %eax = max(LHS offset, RHS offset); + movl $4096,%edx + subl %eax,%edx // get #bytes to next page crossing + cmpl %ecx,%edx // will operand run out first? + cmova %ecx,%edx // get min(length remaining, bytes to page end) + movl %edx,%eax + shrl $4,%edx // get #chunks till end of operand or page + jnz LLoopOverChunks // enter vector loop + +// Too near page end for vectors. + + subl %eax,%ecx // adjust length remaining + movl %eax,%edx // %edx <- #bytes to page end + cmpl $(kShort),%ecx // will there be enough after we cross page for vectors? + ja LLoopOverBytes // yes + addl %eax,%ecx // no, restore total length remaining + jmp LShortLoop // compare rest byte-by-byte (%ecx != 0) + + +// Loop over 16-byte chunks. +// %esi = LHS ptr +// %edi = RHS ptr +// %ecx = length remaining +// %edx = chunk count + + .align 4,0x90 // align inner loops to optimize I-fetch +LLoopOverChunks: + movdqu (%esi),%xmm0 // get LHS + movdqu (%edi),%xmm1 // get RHS + addl $16,%esi + pcmpeqb %xmm1,%xmm0 // compare LHS to RHS + addl $16,%edi + pmovmskb %xmm0,%eax // collect comparison result bits (1 if equal) + subl $16,%ecx // adjust length remaining + xorl $0xFFFF,%eax // all equal? + jne LDifferent // no, we found differing bytes + dec %edx // more to go? + jnz LLoopOverChunks + + cmpl $(kShort),%ecx // a lot more to compare? + jbe LShort // no + jmp LNotShort // compute distance to next page crossing etc + + +// Found a difference. +// %esi = LHS ptr, already advanced by 16 +// %edi = RHS ptr, already advanced by 16 +// %eax = complemented compare vector (ie, 0 == equal) + +LDifferent: + bsf %eax,%edx // which byte differed? + subl $16,%esi // point to byte 0 while we wait for bit scan + subl $16,%edi + movzb (%esi,%edx),%eax // get LHS byte + movzb (%edi,%edx),%ecx // get RHS byte + subl %ecx,%eax // compute difference (ie, return value) + popl %edi + popl %esi + ret Index: branches/cparm/i386/libsa/__bzero.s =================================================================== --- branches/cparm/i386/libsa/__bzero.s (revision 0) +++ branches/cparm/i386/libsa/__bzero.s (revision 2112) @@ -0,0 +1,3 @@ + .globl ___bzero +___bzero: + jmp _bzero Index: branches/cparm/i386/libsa/memset_pattern_sse2.s =================================================================== --- branches/cparm/i386/libsa/memset_pattern_sse2.s (revision 0) +++ branches/cparm/i386/libsa/memset_pattern_sse2.s (revision 2112) @@ -0,0 +1,180 @@ +/* + * Copyright (c) 2005-2006 Apple Computer, Inc. All rights reserved. + * + * @APPLE_OSREFERENCE_LICENSE_HEADER_START@ + * + * This file contains Original Code and/or Modifications of Original Code + * as defined in and that are subject to the Apple Public Source License + * Version 2.0 (the 'License'). You may not use this file except in + * compliance with the License. The rights granted to you under the License + * may not be used to create, or enable the creation or redistribution of, + * unlawful or unlicensed copies of an Apple operating system, or to + * circumvent, violate, or enable the circumvention or violation of, any + * terms of an Apple operating system software license agreement. + * + * Please obtain a copy of the License at + * http://www.opensource.apple.com/apsl/ and read it before using this file. + * + * The Original Code and all software distributed under the License are + * distributed on an 'AS IS' basis, WITHOUT WARRANTY OF ANY KIND, EITHER + * EXPRESS OR IMPLIED, AND APPLE HEREBY DISCLAIMS ALL SUCH WARRANTIES, + * INCLUDING WITHOUT LIMITATION, ANY WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE, QUIET ENJOYMENT OR NON-INFRINGEMENT. + * Please see the License for the specific language governing rights and + * limitations under the License. + * + * @APPLE_OSREFERENCE_LICENSE_HEADER_END@ + */ + +/* The common path for nonzero memset and the memset_pattern routines, + * tuned for Pentium-M class processors with SSE2 and 64-byte cache lines. + * This is used by the following functions: + * + * void *memset(void *b, int c, size_t len); // when c!=0 + * void memset_pattern4(void *b, const void *c4, size_t len); + * void memset_pattern8(void *b, const void *c8, size_t len); + * void memset_pattern16(void *b, const void *c16, size_t len); + * + * Note bzero() and memset() of 0 are handled separately. + */ + +#define kShort 63 +#define kVeryLong (1024*1024) + +// Initial entry from Libc with parameters passed in registers. Although we +// correctly handle misaligned ptrs and short operands, they are inefficient. +// Therefore our caller should filter out short operands and exploit local +// knowledge (ie, original pattern length) to align the ptr if possible. +// When called, we expect: +// %edi = ptr to memory to set (not necessarily aligned) +// %edx = length (may be short or even 0) +// %xmm0 = the pattern to store +// Return conditions: +// %eax, %edi, %esi, %ecx, and %edx all trashed + + .align 5 + .private_extern _memset_pattern +_memset_pattern: + cmpl $(kShort),%edx // long enough to bother aligning? + ja LNotShort // yes + jmp LShort // no + +// Here for short operands or the end of long ones. +// %edx = length +// %edi = ptr (may not be not aligned) +// %xmm0 = pattern + +LUnalignedStore16: + movdqu %xmm0,(%edi) // stuff in another 16 bytes + subl $16,%edx + addl $16,%edi +LShort: + cmpl $16,%edx // room for another vector? + jge LUnalignedStore16 // yes +LLessThan16: // here at end of copy with < 16 bytes remaining + test $8,%dl // 8-byte store required? + jz 2f // no + movq %xmm0,(%edi) // pack in 8 low bytes + psrldq $8,%xmm0 // then shift vector down 8 bytes + addl $8,%edi +2: + test $4,%dl // 4-byte store required? + jz 3f // no + movd %xmm0,(%edi) // pack in 4 low bytes + psrldq $4,%xmm0 // then shift vector down 4 bytes + addl $4,%edi +3: + andl $3,%edx // more to go? + jz 5f // no + movd %xmm0,%eax // move remainders out into %eax +4: // loop on up to three bytes + movb %al,(%edi) // pack in next byte + shrl $8,%eax // shift next byte into position + inc %edi + dec %edx + jnz 4b +5: ret + +// Long enough to justify aligning ptr. Note that we have to rotate the +// pattern to account for any alignment. We do this by doing two unaligned +// stores, and then an aligned load from the middle of the two stores. +// This will stall on store forwarding alignment mismatch, and the unaligned +// stores can be pretty slow too, but the alternatives aren't any better. +// Fortunately, in most cases our caller has already aligned the ptr. +// %edx = length (> kShort) +// %edi = ptr (may not be aligned) +// %xmm0 = pattern + +LNotShort: + movl %edi,%ecx // copy dest ptr + negl %ecx + andl $15,%ecx // mask down to #bytes to 16-byte align + jz LAligned // skip if already aligned + movdqu %xmm0,(%edi) // store 16 unaligned bytes + movdqu %xmm0,16(%edi) // and 16 more, to be sure we have an aligned chunk + addl %ecx,%edi // now point to the aligned chunk + subl %ecx,%edx // adjust remaining count + movdqa (%edi),%xmm0 // get the rotated pattern (probably stalling) + addl $16,%edi // skip past the aligned chunk + subl $16,%edx + +// Set up for 64-byte loops. +// %edx = length remaining +// %edi = ptr (aligned) +// %xmm0 = rotated pattern + +LAligned: + movl %edx,%ecx // copy length remaining + andl $63,%edx // mask down to residual length (0..63) + andl $-64,%ecx // %ecx <- #bytes we will zero in by-64 loop + jz LNoMoreChunks // no 64-byte chunks + addl %ecx,%edi // increment ptr by length to move + cmpl $(kVeryLong),%ecx // long enough to justify non-temporal stores? + jge LVeryLong // yes + negl %ecx // negate length to move + jmp 1f + +// Loop over 64-byte chunks, storing into cache. + + .align 4,0x90 // keep inner loops 16-byte aligned +1: + movdqa %xmm0,(%edi,%ecx) + movdqa %xmm0,16(%edi,%ecx) + movdqa %xmm0,32(%edi,%ecx) + movdqa %xmm0,48(%edi,%ecx) + addl $64,%ecx + jne 1b + + jmp LNoMoreChunks + +// Very long operands: use non-temporal stores to bypass cache. + +LVeryLong: + negl %ecx // negate length to move + jmp 1f + + .align 4,0x90 // keep inner loops 16-byte aligned +1: + movntdq %xmm0,(%edi,%ecx) + movntdq %xmm0,16(%edi,%ecx) + movntdq %xmm0,32(%edi,%ecx) + movntdq %xmm0,48(%edi,%ecx) + addl $64,%ecx + jne 1b + + sfence // required by non-temporal stores + jmp LNoMoreChunks + +// Handle leftovers: loop by 16. +// %edx = length remaining (<64) +// %edi = ptr (aligned) +// %xmm0 = rotated pattern + +LLoopBy16: + movdqa %xmm0,(%edi) // pack in 16 more bytes + subl $16,%edx // decrement count + addl $16,%edi // increment ptr +LNoMoreChunks: + cmpl $16,%edx // more to go? + jge LLoopBy16 // yes + jmp LLessThan16 // handle up to 15 remaining bytes Index: branches/cparm/i386/libsa/strcpy.s =================================================================== --- branches/cparm/i386/libsa/strcpy.s (revision 0) +++ branches/cparm/i386/libsa/strcpy.s (revision 2112) @@ -0,0 +1,151 @@ +/* + * Copyright (c) 2005 Apple Computer, Inc. All rights reserved. + * + * @APPLE_LICENSE_HEADER_START@ + * + * This file contains Original Code and/or Modifications of Original Code + * as defined in and that are subject to the Apple Public Source License + * Version 2.0 (the 'License'). You may not use this file except in + * compliance with the License. Please obtain a copy of the License at + * http://www.opensource.apple.com/apsl/ and read it before using this + * file. + * + * The Original Code and all software distributed under the License are + * distributed on an 'AS IS' basis, WITHOUT WARRANTY OF ANY KIND, EITHER + * EXPRESS OR IMPLIED, AND APPLE HEREBY DISCLAIMS ALL SUCH WARRANTIES, + * INCLUDING WITHOUT LIMITATION, ANY WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE, QUIET ENJOYMENT OR NON-INFRINGEMENT. + * Please see the License for the specific language governing rights and + * limitations under the License. + * + * @APPLE_LICENSE_HEADER_END@ + */ + + +// *************** +// * S T R C P Y * +// *************** +// +// char *strcpy(const char *dst, const char *src); +// +// We optimize the move by doing it vector parallel. This introduces +// a complication: if we blindly did vector load/stores until finding +// a 0, we might get a spurious page fault by touching bytes past it. +// To avoid this, we never do a load that crosses a page boundary, +// and never store a byte we don't have to. +// +// We align the destination, because unaligned vector stores are slow. + + .text + .globl _strcpy + + .align 4 +_strcpy: // char *strcpy(const char *dst, const char *src); + pushl %edi + movl 8(%esp),%edi // get dest ptr + movl 12(%esp),%ecx // get source ptr + movl %edi,%edx // copy dest ptr + negl %edx + andl $15,%edx // how many bytes to align dest ptr? + jnz LLoopOverBytes // not aligned, so go do so + + +// In order to avoid spurious page faults, we loop until nearing the source page +// end. Then we revert to a byte-by-byte loop for 16 bytes until the page is crossed, +// then resume the vector loop. +// %ecx = source ptr (unaligned) +// %edi = dest ptr (aligned) + +LNextChunk: + movl %ecx,%eax // copy source ptr + movl $4096,%edx + andl $4095,%eax // get offset into source page + subl %eax,%edx // get #bytes remaining in source page + shrl $4,%edx // get #chunks till end of page + jnz LLoopOverChunks // enter vector loop + movl $16,%edx // move 16 bytes to cross page but keep dest aligned + jmp LLoopOverBytes + + +// Loop over bytes. +// %ecx = source ptr +// %edi = dest ptr +// %edx = byte count + + .align 4,0x90 // align inner loops to optimize I-fetch +LLoopOverBytes: + movzb (%ecx),%eax // get source byte + inc %ecx + movb %al,(%edi) // pack into dest + inc %edi + testl %eax,%eax // 0? + jz LDone // yes, we're done + dec %edx // more to go? + jnz LLoopOverBytes + + jmp LNextChunk // we've come to end of page + + +// Loop over 16-byte chunks. +// %ecx = source ptr (unaligned) +// %edi = dest ptr (aligned) +// %edx = chunk count + + .align 4,0x90 // align inner loops to optimize I-fetch +LLoopOverChunks: + movdqu (%ecx),%xmm1 // get source + pxor %xmm0,%xmm0 // get some 0s + addl $16,%ecx + pcmpeqb %xmm1,%xmm0 // compare source to 0s + pmovmskb %xmm0,%eax // get result mask for 0 check + testl %eax,%eax // any 0s? + jnz LFound0 // yes, exit loop + movdqa %xmm1,(%edi) // no 0s so do aligned store into destination + addl $16,%edi + dec %edx // more to go? + jnz LLoopOverChunks + + movl $16,%edx // move 16 bytes + jmp LLoopOverBytes // cross page but keep dest aligned + + +// Found a zero in the vector. Figure out where it is, and store the bytes +// up to it. +// %edi = dest ptr (aligned) +// %eax = result mask +// %xmm1 = source vector + +LFound0: + bsf %eax,%edx // find first 0 + inc %edx // we need to store the 0 too + test $16,%dl // was 0 last byte? + jz 8f // no + movdqa %xmm1,(%edi) // yes, store entire vector + jmp LDone +8: + test $8,%dl // 8-byte store required? + jz 4f // no + movq %xmm1,(%edi) // pack in 8 low bytes + psrldq $8,%xmm1 // then shift vector down 8 bytes + addl $8,%edi +4: + test $4,%dl // 4-byte store required? + jz 3f // no + movd %xmm1,(%edi) // pack in 4 low bytes + psrldq $4,%xmm1 // then shift vector down 4 bytes + addl $4,%edi +3: + andl $3,%edx // more to go? + jz LDone // no + movd %xmm1,%eax // move remainders out of vector into %eax +1: // loop on up to three bytes + movb %al,(%edi) // pack in next byte + shrl $8,%eax // shift next byte into position + inc %edi + dec %edx + jnz 1b + +LDone: + movl 8(%esp),%eax // original dest ptr is return value + popl %edi + ret Index: branches/cparm/i386/libsa/strncmp.s =================================================================== --- branches/cparm/i386/libsa/strncmp.s (revision 0) +++ branches/cparm/i386/libsa/strncmp.s (revision 2112) @@ -0,0 +1,191 @@ +/* + * Copyright (c) 2005 Apple Computer, Inc. All rights reserved. + * + * @APPLE_LICENSE_HEADER_START@ + * + * This file contains Original Code and/or Modifications of Original Code + * as defined in and that are subject to the Apple Public Source License + * Version 2.0 (the 'License'). You may not use this file except in + * compliance with the License. Please obtain a copy of the License at + * http://www.opensource.apple.com/apsl/ and read it before using this + * file. + * + * The Original Code and all software distributed under the License are + * distributed on an 'AS IS' basis, WITHOUT WARRANTY OF ANY KIND, EITHER + * EXPRESS OR IMPLIED, AND APPLE HEREBY DISCLAIMS ALL SUCH WARRANTIES, + * INCLUDING WITHOUT LIMITATION, ANY WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE, QUIET ENJOYMENT OR NON-INFRINGEMENT. + * Please see the License for the specific language governing rights and + * limitations under the License. + * + * @APPLE_LICENSE_HEADER_END@ + */ + + +// ***************** +// * S T R N C M P * +// ***************** +// +// int strncmp(const char *s1, const char *s2, size_t len); +// +// We optimize the compare by doing it vector parallel. This introduces +// a complication: if we blindly did vector loads from both sides until +// finding a difference (or 0), we might get a spurious page fault by +// reading bytes past the difference. To avoid this, we never do a load +// that crosses a page boundary. + +#define kShort 20 // too short for vectors (must be >16) + + .text + .globl _strncmp + + .align 4 +_strncmp: // int strncmp(const char *s1, const char *s2, size_t len); + pushl %esi + pushl %edi + movl 20(%esp),%ecx // get length + movl 12(%esp),%esi // get LHS ptr + movl 16(%esp),%edi // get RHS ptr + push %ebx + cmpl $(kShort),%ecx // worth accelerating? + ja LNotShort // yes + + +// Too short to bother with parallel compares. Loop over bytes. +// %esi = LHS ptr +// %edi = RHS ptr +// %ecx = length (<= kShort) + +LShort: + testl %ecx,%ecx // 0-length? + jnz LShortLoop // no + jmp LReturn0 // yes, return 0 + .align 4,0x90 // align inner loops to optimize I-fetch +LShortLoop: // loop over bytes + movzb (%esi),%eax // get LHS byte + movzb (%edi),%ebx // get RHS byte + incl %esi + incl %edi + testl %eax,%eax // LHS==0 ? + jz LNotEqual // yes, this terminates comparison + subl %ebx,%eax // compare them + jnz LExit // done if not equal + decl %ecx // decrement length + jnz LShortLoop +LReturn0: + xorl %eax,%eax // all bytes equal, so return 0 +LExit: // return value is in %eax + popl %ebx + popl %edi + popl %esi + ret + +LNotEqual: // LHS in eax, RHS in ebx + subl %ebx,%eax // generate return value (nonzero) + popl %ebx + popl %edi + popl %esi + ret + + +// Loop over bytes until we reach end of a page. +// %esi = LHS ptr +// %edi = RHS ptr +// %ecx = length remaining after end of loop (ie, already adjusted) +// %edx = #bytes until next page (1..15) + + .align 4,0x90 // align inner loops to optimize I-fetch +LLoopOverBytes: + movzb (%esi),%eax // get LHS byte + movzb (%edi),%ebx // get RHS byte + inc %esi + inc %edi + testl %eax,%eax // LHS==0 ? + jz LNotEqual // yes, this terminates comparison + subl %ebx,%eax // compare them + jnz LExit // done if not equal + dec %edx // more to go? + jnz LLoopOverBytes + + +// Long enough to justify overhead of setting up vector compares. In order to +// avoid spurious page faults, we loop over: +// +// min( length, bytes_in_LHS_page, bytes_in_RHS_page) >> 4 +// +// 16-byte chunks. When we near a page end, we have to revert to a byte-by-byte +// comparison until reaching the next page, then resume the vector comparison. +// %esi = LHS ptr +// %edi = RHS ptr +// %ecx = length (> kShort) + +LNotShort: + movl %esi,%eax // copy ptrs + movl %edi,%edx + andl $4095,%eax // mask down to page offsets + andl $4095,%edx + cmpl %eax,%edx // which is bigger? + cmova %edx,%eax // %eax = max(LHS offset, RHS offset); + movl $4096,%edx + subl %eax,%edx // get #bytes to next page crossing + cmpl %ecx,%edx // will operand run out first? + cmova %ecx,%edx // get min(length remaining, bytes to page end) + movl %edx,%eax + shrl $4,%edx // get #chunks till end of operand or page + jnz LLoopOverChunks // enter vector loop + +// Too near page end for vectors. + + subl %eax,%ecx // adjust length remaining + movl %eax,%edx // %edx <- #bytes to page end + cmpl $(kShort),%ecx // will there be enough after we cross page for vectors? + ja LLoopOverBytes // yes + addl %eax,%ecx // no, restore total length remaining + jmp LShortLoop // compare rest byte-by-byte (%ecx != 0) + + +// Loop over 16-byte chunks. +// %esi = LHS ptr +// %edi = RHS ptr +// %ecx = length remaining +// %edx = chunk count + + .align 4,0x90 // align inner loops to optimize I-fetch +LLoopOverChunks: + movdqu (%esi),%xmm1 // get LHS + movdqu (%edi),%xmm2 // get RHS + pxor %xmm0,%xmm0 // get some 0s in the shadow of the loads + addl $16,%esi + pcmpeqb %xmm1,%xmm2 // compare LHS to RHS + pcmpeqb %xmm1,%xmm0 // compare LHS to 0s + addl $16,%edi + pmovmskb %xmm2,%eax // get result mask for comparison of LHS and RHS + pmovmskb %xmm0,%ebx // get result mask for 0 check + subl $16,%ecx // decrement length remaining + xorl $0xFFFF,%eax // complement compare mask so 1 means "not equal" + orl %ebx,%eax // combine the masks and check for 1-bits + jnz LFoundDiffOr0 // we found differing bytes or a 0-byte + dec %edx // more to go? + jnz LLoopOverChunks // yes + + cmpl $(kShort),%ecx // a lot more to compare? + jbe LShort // no + jmp LNotShort // compute distance to next page crossing etc + + +// Found a zero and/or a difference in vector compare. +// %esi = LHS ptr, already advanced by 16 +// %edi = RHS ptr, already advanced by 16 +// %eax = bit n set if bytes n differed or were 0 + +LFoundDiffOr0: + bsf %eax,%edx // which byte differed or was 0? + subl $16,%esi // point to start of vectors while we wait for bit scan + subl $16,%edi + movzb (%esi,%edx),%eax // get LHS byte + movzb (%edi,%edx),%ecx // get RHS byte + popl %ebx + popl %edi + subl %ecx,%eax // compute difference (ie, return value) + popl %esi + ret Index: branches/cparm/i386/libsa/string.c =================================================================== --- branches/cparm/i386/libsa/string.c (revision 2111) +++ branches/cparm/i386/libsa/string.c (revision 2112) @@ -25,9 +25,9 @@ #include "libsa.h" -static int _mach_strlen(const char *str); static char *STRDUP(const char *string); +#if 0 /* * Abstract: * strcmp (s1, s2) compares the strings "s1" and "s2". @@ -91,7 +91,6 @@ return 0; } - /* * Abstract: * strcpy copies the contents of the string "from" including @@ -170,6 +169,7 @@ return(s - src - 1); /* count does not include NUL */ } +#endif /* * History: @@ -200,12 +200,15 @@ return (const char *) (in - 1); } +#if 0 void * memmove(void *dst, const void *src, size_t ulen) { bcopy(src, dst, ulen); return dst; } +#endif + #if UNUSED int ptol(const char *str) @@ -277,6 +280,8 @@ return str; } #endif + +#if 0 /* * Appends src to string dst of size siz (unlike strncat, siz is the * full size of dst, not space left). At most siz-1 characters @@ -311,6 +316,7 @@ return(dlen + (s - src)); /* count does not include NUL */ } +#endif /* * @@ -334,6 +340,8 @@ return(os1); } +#if 0 +static int _mach_strlen(const char *str); static int _mach_strlen(const char *str) { @@ -351,6 +359,8 @@ { return (size_t)_mach_strlen(str); } +#endif + #if UNUSED /* * Does the same thing as strlen, except only looks up @@ -585,6 +595,7 @@ * SUCH DAMAGE. */ +#if 0 /* * Compare memory regions. */ @@ -601,7 +612,7 @@ } return (0); } - +#endif /* * Perform a binary search. * Index: branches/cparm/i386/libsa/memset.s =================================================================== --- branches/cparm/i386/libsa/memset.s (revision 0) +++ branches/cparm/i386/libsa/memset.s (revision 2112) @@ -0,0 +1,235 @@ +/* + * Copyright (c) 2005 Apple Computer, Inc. All rights reserved. + * + * @APPLE_LICENSE_HEADER_START@ + * + * The contents of this file constitute Original Code as defined in and + * are subject to the Apple Public Source License Version 1.1 (the + * "License"). You may not use this file except in compliance with the + * License. Please obtain a copy of the License at + * http://www.apple.com/publicsource and read it before using this file. + * + * This Original Code and all software distributed under the License are + * distributed on an "AS IS" basis, WITHOUT WARRANTY OF ANY KIND, EITHER + * EXPRESS OR IMPLIED, AND APPLE HEREBY DISCLAIMS ALL SUCH WARRANTIES, + * INCLUDING WITHOUT LIMITATION, ANY WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE OR NON-INFRINGEMENT. Please see the + * License for the specific language governing rights and limitations + * under the License. + * + * @APPLE_LICENSE_HEADER_END@ + */ + +/* This file contains the following functions: + * + * void *memset(void *b, int c, size_t len); + * void memset_pattern4(void *b, const void *c4, size_t len); + * void memset_pattern8(void *b, const void *c8, size_t len); + * void memset_pattern16(void *b, const void *c16, size_t len); + * + * Calls of memset() with c==0 are routed to the bzero() routine. Most of the + * others go to _memset_pattern, which is entered as follows: + * %edi = ptr to memory to set (aligned) + * %edx = length (which can be short, though we bias in favor of long operands) + * %xmm0 = the pattern to store + * Return conditions: + * %eax, %edi, %esi, %ecx, and %edx all trashed + * + * NB: we avoid "stos" family of instructions (stosl, stosb), as they are very slow + * on P4s and probably other processors. + */ + + #define kShort 255 // for nonzero memset(), too short for commpage + + + .text + .globl _memset + .align 2 +_memset: // void *memset(void *b, int c, size_t len); + movl 8(%esp),%eax // get 1-byte pattern + movl 12(%esp),%edx // get length + andl $0xFF,%eax // (c==0) ? + jnz LNonzero // not a bzero + + movl %edx,8(%esp) // put count where bzero() expects it + jmp _bzero // enter _bzero + + + // Handle memset of a nonzero value. + +LNonzero: + pushl %edi // save a few nonvolatiles + pushl %esi + movl %eax,%esi // replicate byte in %al into all four bytes + movl 12(%esp),%edi // point to operand + shll $8,%esi + orl %esi,%eax + movl %eax,%esi + shll $16,%esi + orl %esi,%eax // now %eax has "c" in all 4 bytes + cmpl $(kShort),%edx // is operand too short for SSE? + ja LCallCommpage // no + +// Nonzero memset() too short to call commpage. +// %eax = replicated 4-byte pattern +// %edi = ptr +// %edx = length (<= kShort) + + cmpl $16,%edx // long enough to word align? + jge 3f // yes + test %edx,%edx // length==0? + jz 6f +1: + movb %al,(%edi) // pack in a byte + inc %edi + dec %edx + jnz 1b + jmp 6f +2: + movb %al,(%edi) // pack in a byte + inc %edi + dec %edx +3: + test $3,%edi // is ptr doubleword aligned? + jnz 2b // no + movl %edx,%ecx // copy length + shrl $2,%edx // #doublewords to store +4: + movl %eax,(%edi) // store aligned doubleword + addl $4,%edi + dec %edx + jnz 4b + andl $3,%ecx // any leftover bytes? + jz 6f // no +5: + movb %al,(%edi) // pack in a byte + inc %edi + dec %ecx + jnz 5b +6: + movl 12(%esp),%eax // get return value (ie, original ptr) + popl %esi + popl %edi + ret + +// Nonzero memset() is long enough to call commpage. +// %eax = replicated 4-byte pattern +// %edi = ptr +// %edx = length (> kShort) + +LCallCommpage: + movd %eax,%xmm0 // move %eax to low 4 bytes of %xmm0 + pshufd $(0x00),%xmm0,%xmm0 // replicate across the vector + movl %edi,%ecx // copy dest ptr + negl %ecx + andl $15,%ecx // get #bytes to align ptr + jz 2f // skip if already aligned + subl %ecx,%edx // decrement length +1: + movb %al,(%edi) // pack in a byte + inc %edi + dec %ecx + jnz 1b +2: // ptr aligned, length long enough to justify + call _memset_pattern // call commpage to do the heavy lifting + movl 12(%esp),%eax // get return value (ie, original ptr) + popl %esi + popl %edi + ret + + +// Handle memset of a 16-byte pattern. + + .globl _memset_pattern16 + .align 2, 0x90 +_memset_pattern16: // void memset_pattern16(void *b, const void *c16, size_t len); + pushl %edi + pushl %esi + movl 20(%esp),%edx // get length + movl 16(%esp),%esi // get ptr to 16-byte pattern + movl 12(%esp),%edi // point to operand + movdqu (%esi),%xmm0 // load the pattern + jmp LAlignPtr + + +// Handle memset of an 8-byte pattern. + + .globl _memset_pattern8 + .align 2, 0x90 +_memset_pattern8: // void memset_pattern8(void *b, const void *c8, size_t len); + pushl %edi + pushl %esi + movl 20(%esp),%edx // get length + movl 16(%esp),%esi // get ptr to 8-byte pattern + movl 12(%esp),%edi // point to operand + movq (%esi),%xmm0 // load pattern into low 8 bytes + punpcklqdq %xmm0,%xmm0 // replicate into all 16 + jmp LAlignPtr + +// Handle memset of a 4-byte pattern. + + .globl _memset_pattern4 + .align 2, 0x90 +_memset_pattern4: // void memset_pattern4(void *b, const void *c4, size_t len); + pushl %edi + pushl %esi + movl 20(%esp),%edx // get length + movl 16(%esp),%esi // get ptr to 4-byte pattern + movl 12(%esp),%edi // point to operand + movd (%esi),%xmm0 // load pattern into low 4 bytes + pshufd $(0x00),%xmm0,%xmm0 // replicate the 4 bytes across the vector + + +// Align ptr if necessary. We must rotate the pattern right for each byte we +// store while aligning the ptr. Since there is no rotate instruction in SSE3, +// we have to synthesize the rotates. +// %edi = ptr +// %edx = length +// %xmm0 = pattern + +LAlignPtr: // NB: can drop down to here! + cmpl $100,%edx // long enough to bother aligning ptr? + movl %edi,%ecx // copy ptr + jb LReady // not long enough + negl %ecx + andl $15,%ecx // get #bytes to align ptr + jz LReady // already aligned + subl %ecx,%edx // adjust length + + test $1,%cl // 1-byte store required? + movd %xmm0,%eax // get 4 low bytes in %eax + jz 2f // no + movdqa %xmm0,%xmm1 // copy pattern so we can shift in both directions + movb %al,(%edi) // pack in the low-order byte + psrldq $1,%xmm0 // shift pattern right 1 byte + inc %edi + pslldq $15,%xmm1 // shift pattern left 15 bytes + shrl $8,%eax // in case 2-byte store is required + por %xmm1,%xmm0 // complete right rotate of pattern by 1 byte +2: + test $2,%cl // 2-byte store required? + jz 4f // no + psrldq $2,%xmm0 // shift pattern down 2 bytes + movw %ax,(%edi) // pack in next two bytes + pinsrw $7,%eax,%xmm0 // insert low word of %eax into high word of %xmm0 + addl $2,%edi // adjust ptr +4: + test $4,%cl // 4-byte store required? + jz 8f // no + movd %xmm0,(%edi) // store low 4 bytes of %xmm0 + pshufd $(0x39),%xmm0,%xmm0 // rotate %xmm0 right 4 bytes (mask == 00 11 10 01) + addl $4,%edi // adjust ptr +8: + test $8,%cl // 8-byte store required? + jz LReady // no + movq %xmm0,(%edi) // store low 8 bytes of %xmm0 + pshufd $(0x4e),%xmm0,%xmm0 // rotate %xmm0 right 8 bytes (mask == 01 00 11 10) + addl $8,%edi // adjust ptr + +// Ptr is aligned if practical, we're ready to call commpage to do the heavy lifting. + +LReady: + call _memset_pattern // call commpage to do the heavy lifting + popl %esi + popl %edi + ret Index: branches/cparm/i386/libsa/memory.h =================================================================== --- branches/cparm/i386/libsa/memory.h (revision 2111) +++ branches/cparm/i386/libsa/memory.h (revision 2112) @@ -93,9 +93,15 @@ #define LOAD_ADDR 0x18100000 // 64M File load buffer #define LOAD_LEN 0x04000000 +#define SANDBOX_ADDR 0x1C100000 // 256M modules sandbox aera, +#define SANDBOX_LEN 0x10000000 + +#define SANDBOX_PER_MODULE 0x1000000 // 16M per module + +#define SANDBOX_MAX_MODULE SANDBOX_LEN/SANDBOX_PER_MODULE // Max nb of module + // Location of data fed to boot2 by the prebooter -#define PREBOOT_DATA 0x1C100000 // Still have enough room for a 63M ramdisk image - // in case of 512MB system memory. +#define PREBOOT_DATA 0x2C100000 #define TFTP_ADDR LOAD_ADDR // tftp download buffer #define TFTP_LEN LOAD_LEN Index: branches/cparm/i386/libsa/strlcpy.s =================================================================== --- branches/cparm/i386/libsa/strlcpy.s (revision 0) +++ branches/cparm/i386/libsa/strlcpy.s (revision 2112) @@ -0,0 +1,167 @@ +/* + * Copyright (c) 2007 Apple Inc. All rights reserved. + * + * @APPLE_LICENSE_HEADER_START@ + * + * This file contains Original Code and/or Modifications of Original Code + * as defined in and that are subject to the Apple Public Source License + * Version 2.0 (the 'License'). You may not use this file except in + * compliance with the License. Please obtain a copy of the License at + * http://www.opensource.apple.com/apsl/ and read it before using this + * file. + * + * The Original Code and all software distributed under the License are + * distributed on an 'AS IS' basis, WITHOUT WARRANTY OF ANY KIND, EITHER + * EXPRESS OR IMPLIED, AND APPLE HEREBY DISCLAIMS ALL SUCH WARRANTIES, + * INCLUDING WITHOUT LIMITATION, ANY WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE, QUIET ENJOYMENT OR NON-INFRINGEMENT. + * Please see the License for the specific language governing rights and + * limitations under the License. + * + * @APPLE_LICENSE_HEADER_END@ + */ + + +// ***************** +// * S T R L C P Y * +// ***************** +// +// size_t strlcpy(char *dst, const char *src, size_t size); +// +// We optimize the move by doing it word parallel. This introduces +// a complication: if we blindly did word load/stores until finding +// a 0, we might get a spurious page fault by touching bytes past it. +// To avoid this, we never do a load that crosses a page boundary, +// or store unnecessary bytes. +// +// The test for 0s relies on the following inobvious but very efficient +// word-parallel test: +// x = dataWord + 0xFEFEFEFF +// y = ~dataWord & 0x80808080 +// if (x & y) == 0 then no zero found +// The test maps any non-zero byte to zero, and any zero byte to 0x80, +// with one exception: 0x01 bytes preceeding the first zero are also +// mapped to 0x80. +// +// On Core2 class machines, this word-parallel implementation seems to +// be slightly faster than using SSE up to about 100 bytes. +// It is faster than the naive byte-by-byte implementation for +// operands longer than about 8 bytes. + + .text + .globl _strlcpy + + .align 4 +_strlcpy: // size_t *strlcpy(char *dst, const char *src, size_t size); + pushl %edi + pushl %esi + pushl %ebx + movl 16(%esp),%edi // get dest ptr + movl 20(%esp),%esi // get source ptr + movl 24(%esp),%ecx // get length of buffer + movl %esi,%edx // copy source ptr + negl %edx + andl $3,%edx // how many bytes to align source ptr? + jz LAligned // already aligned + + +// Loop over bytes. +// %edi = dest ptr +// %esi = source ptr +// %ecx = length remaining in buffer +// %edx = number of bytes to copy (>0, may not fit in buffer) + +LLoopOverBytes: + movzb (%esi),%eax // get source byte before checking buffer length + testl %ecx,%ecx // buffer full? + jz L0NotFound // yes + inc %esi + dec %ecx + movb %al,(%edi) // pack into dest + inc %edi + testl %eax,%eax // 0? + jz LDone // yes, done + dec %edx // more to go? + jnz LLoopOverBytes + + +// Source is aligned. Loop over words until end of buffer. We +// align the source, rather than the dest, to avoid getting spurious page faults. +// %edi = dest ptr (unaligned) +// %esi = source ptr (word aligned) +// %ecx = length remaining in buffer + +LAligned: + movl $5,%edx // if buffer almost exhausted, prepare to copy rest byte-by-byte + cmpl $4,%ecx // enough for at least one word? + jb LLoopOverBytes + + +// Loop over words. +// %edi = dest ptr (unaligned) +// %esi = source ptr (word aligned) +// %ecx = length remaining in buffer (>=4) + +LLoopOverWords: + movl (%esi),%eax // get next 4 bytes of source + subl $4,%ecx + addl $4,%esi + movl %eax,%edx // make 2 copies of word + movl %eax,%ebx + notl %edx // use magic word-parallel test for 0s + addl $0xFEFEFEFF,%ebx + andl $0x80808080,%edx + testl %ebx,%edx + jnz L0Found // one of the bytes of %eax is a 0 + movl %eax,(%edi) // pack 4 bytes into destination + addl $4,%edi + cmpl $4,%ecx // room in buffer for another word? + jae LLoopOverWords // yes + + movl %ecx,%edx // copy leftovers in byte loop + jmp LLoopOverBytes + +// Found a 0-byte in the word of source. Store a byte at a time until the 0. +// %edi = dest ptr (unaligned) +// %eax = last word of source, known to have a 0-byte + +LNextByte: + shrl $8,%eax // next byte +L0Found: + movb %al,(%edi) // pack in next byte + incl %edi + testb %al,%al // 0? + jnz LNextByte + +// Done storing string. +// %edi = ptr to byte after 0-byte + +LDone: + subl 16(%esp),%edi // subtract original dest ptr to get length stored + decl %edi // don't count the 0-byte + movl %edi,%eax // copy to return value +LExit: + popl %ebx + popl %esi + popl %edi + ret + +// Buffer filled but 0-byte not found. We return the length of the source string. +// This is not optimized, as it is an error condition. +// %edi = dest ptr (ie, 1 past end of buffer) +// %esi = source ptr (ptr to 1st byte that does not fit) + +L0NotFound: + movl 24(%esp),%eax // reload buffer length + testl %eax,%eax // null? + jz 1f // yes, cannot store a 0 + xorl %edx,%edx // get a 0 + movb %dl,-1(%edi) // store a 0 at end of buffer to delimit string +1: + movzb (%esi),%edx // get next byte of source + incl %esi + incl %eax + testl %edx,%edx // 0? + jnz 1b + decl %eax // don't count the 0-byte + jmp LExit Index: branches/cparm/i386/libsa/bcopy_scalar.s =================================================================== --- branches/cparm/i386/libsa/bcopy_scalar.s (revision 0) +++ branches/cparm/i386/libsa/bcopy_scalar.s (revision 2112) @@ -0,0 +1,129 @@ +/* + * Copyright (c) 2003-2006 Apple Computer, Inc. All rights reserved. + * + * @APPLE_OSREFERENCE_LICENSE_HEADER_START@ + * + * This file contains Original Code and/or Modifications of Original Code + * as defined in and that are subject to the Apple Public Source License + * Version 2.0 (the 'License'). You may not use this file except in + * compliance with the License. The rights granted to you under the License + * may not be used to create, or enable the creation or redistribution of, + * unlawful or unlicensed copies of an Apple operating system, or to + * circumvent, violate, or enable the circumvention or violation of, any + * terms of an Apple operating system software license agreement. + * + * Please obtain a copy of the License at + * http://www.opensource.apple.com/apsl/ and read it before using this file. + * + * The Original Code and all software distributed under the License are + * distributed on an 'AS IS' basis, WITHOUT WARRANTY OF ANY KIND, EITHER + * EXPRESS OR IMPLIED, AND APPLE HEREBY DISCLAIMS ALL SUCH WARRANTIES, + * INCLUDING WITHOUT LIMITATION, ANY WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE, QUIET ENJOYMENT OR NON-INFRINGEMENT. + * Please see the License for the specific language governing rights and + * limitations under the License. + * + * @APPLE_OSREFERENCE_LICENSE_HEADER_END@ + */ + +/*- + * Copyright (c) 1990 The Regents of the University of California. + * All rights reserved. + * + * This code is derived from locore.s. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * 3. All advertising materials mentioning features or use of this software + * must display the following acknowledgement: + * This product includes software developed by the University of + * California, Berkeley and its contributors. + * 4. Neither the name of the University nor the names of its contributors + * may be used to endorse or promote products derived from this software + * without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND + * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE + * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL + * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS + * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY + * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF + * SUCH DAMAGE. + */ + +#include + + + /* + * (ov)bcopy (src,dst,cnt) + * ws@tools.de (Wolfgang Solfrank, TooLs GmbH) +49-228-985800 + */ + +LABEL(_bcopy) + pushl %ebp /* set up a frame for backtraces */ + movl %esp,%ebp + pushl %esi + pushl %edi + movl 8(%ebp),%esi + movl 12(%ebp),%edi + jmp 1f + +LABEL(_memcpy) +LABEL(_memmove) + pushl %ebp /* set up a frame for backtraces */ + movl %esp,%ebp + pushl %esi + pushl %edi + movl 8(%ebp),%edi + movl 12(%ebp),%esi + movl %edi,%eax +1: + movl 16(%ebp),%ecx + movl %edi,%edx + subl %esi,%edx + cmpl %ecx,%edx /* overlapping? */ + jb 2f + cld /* nope, copy forwards. */ + movl %ecx,%edx + shrl $2,%ecx /* copy by words */ + rep + movsl + movl %edx,%ecx + andl $3,%ecx /* any bytes left? */ + rep + movsb + popl %edi + popl %esi + popl %ebp + ret +2: + addl %ecx,%edi /* copy backwards. */ + addl %ecx,%esi + std + movl %ecx,%edx + andl $3,%ecx /* any fractional bytes? */ + decl %edi + decl %esi + rep + movsb + movl %edx,%ecx /* copy remainder by words */ + shrl $2,%ecx + subl $3,%esi + subl $3,%edi + rep + movsl + popl %edi + popl %esi + popl %ebp + cld + ret Index: branches/cparm/i386/libsa/strncpy.s =================================================================== --- branches/cparm/i386/libsa/strncpy.s (revision 0) +++ branches/cparm/i386/libsa/strncpy.s (revision 2112) @@ -0,0 +1,186 @@ +/* + * Copyright (c) 2005 Apple Computer, Inc. All rights reserved. + * + * @APPLE_LICENSE_HEADER_START@ + * + * This file contains Original Code and/or Modifications of Original Code + * as defined in and that are subject to the Apple Public Source License + * Version 2.0 (the 'License'). You may not use this file except in + * compliance with the License. Please obtain a copy of the License at + * http://www.opensource.apple.com/apsl/ and read it before using this + * file. + * + * The Original Code and all software distributed under the License are + * distributed on an 'AS IS' basis, WITHOUT WARRANTY OF ANY KIND, EITHER + * EXPRESS OR IMPLIED, AND APPLE HEREBY DISCLAIMS ALL SUCH WARRANTIES, + * INCLUDING WITHOUT LIMITATION, ANY WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE, QUIET ENJOYMENT OR NON-INFRINGEMENT. + * Please see the License for the specific language governing rights and + * limitations under the License. + * + * @APPLE_LICENSE_HEADER_END@ + */ + +// ***************** +// * S T R N C P Y * +// ***************** +// +// char *strncpy(const char *dst, const char *src, size_t n); +// +// We optimize the move by doing it vector parallel. This introduces +// a complication: if we blindly did vector load/stores until finding +// a 0, we might get a spurious page fault by touching bytes past it. +// To avoid this, we never do a load that crosses a page boundary, +// and never store a byte we don't have to. +// +// We align the destination, because unaligned vector stores are slow. +// +// Recall that strncpy() zero fills the remainder of the dest buffer, +// and does not terminate the string if it's length is greater than or +// equal to n. + +#define kShort 31 // too short to bother with vector loop + + .text + .globl _strncpy + + .align 4 +_strncpy: // char *strncpy(const char *dst, const char *src, size_t n); + pushl %edi + pushl %esi + movl 12(%esp),%edi // get dest ptr + movl 16(%esp),%esi // get source ptr + movl 20(%esp),%ecx // get length + movl %edi,%edx // copy dest ptr + negl %edx + andl $15,%edx // how many bytes to align dest ptr? + jnz LCheckShortCopy // align destination first + + +// In order to avoid spurious page faults, we loop until nearing the source page +// end. Then we revert to a byte-by-byte loop for 16 bytes until the page is crossed, +// then resume the vector loop. +// %esi = source ptr (unaligned) +// %edi = dest ptr (aligned) +// %ecx = buffer length remaining + +LNextChunk: // NB: can drop down to here + movl %esi,%eax // copy source ptr + movl $4096,%edx + andl $4095,%eax // get offset into source page + subl %eax,%edx // get #bytes remaining in source page + cmpl %ecx,%edx // will buffer run out before the page end? + cmova %ecx,%edx // get min(length remaining, bytes to page end) + shrl $4,%edx // get #chunks till end of page + jnz LLoopOverChunks // enter vector loop + +// We can't use the chunk loop yet. Check for short and empty buffers, then use byte loop. + +LCrossPage: // if buffer is large enough, cross source page + movl $16,%edx // move 16 bytes to cross page but keep dest aligned +LCheckShortCopy: // we propose to copy %edx bytes in byte loop + cmpl $(kShort),%ecx // much left? + ja LLoopOverBytes // yes, loop over bytes then more chunks + movl %ecx,%edx // no, use the byte loop for everything + testl %ecx,%ecx // have we filled buffer? + jnz LLoopOverBytes // no + jmp LDone + + +// Loop over bytes. +// %esi = source ptr +// %edi = dest ptr +// %ecx = buffer length remaining +// %edx = count of bytes to loop over (<= buffer length) + + .align 4,0x90 // align inner loops to optimize I-fetch +LLoopOverBytes: + movzb (%esi),%eax // get source byte + inc %esi + dec %ecx // decrement length + movb %al,(%edi) // pack into dest + inc %edi + testl %eax,%eax // 0? + jz LZeroBuffer // yes, we're done copying string + dec %edx // more to go? + jnz LLoopOverBytes + + testl %ecx,%ecx // at end of buffer? + jnz LNextChunk // no, xfer chunks + jmp LDone // yes + + +// Loop over 16-byte chunks. +// %esi = source ptr (unaligned) +// %edi = dest ptr (aligned) +// %ecx = buffer length remaining +// %edx = chunk count + + .align 4,0x90 // align inner loops to optimize I-fetch +LLoopOverChunks: + movdqu (%esi),%xmm1 // get source + pxor %xmm0,%xmm0 // get some 0s + addl $16,%esi + pcmpeqb %xmm1,%xmm0 // compare source to 0s + pmovmskb %xmm0,%eax // get result mask for 0 check + testl %eax,%eax // any 0s? + jnz LFound0 // yes, exit loop + movdqa %xmm1,(%edi) // no 0s so do aligned store into destination + addl $16,%edi + subl $16,%ecx // decrement length remaining + dec %edx // more to go? + jnz LLoopOverChunks + + jmp LCrossPage // cross page but keep dest aligned + + +// Found a zero in the vector. Figure out where it is, and store the bytes +// up to it. It is possible that we should check to be sure (%ecx >= 16), and +// just do an aligned store of %xmm1 if so. But if we did, we'd be doing byte +// stores into the same double quadword in bzero(), which might hit a hazard. +// Experimentation needed. +// %edi = dest ptr (aligned) +// %eax = result mask +// %ecx = buffer length remaining +// %xmm1 = source vector + +LFound0: + bsf %eax,%edx // find first 0 + subl %edx,%ecx // decrement remaining buffer length + test $8,%dl // 8-byte store required? + jz 4f // no + movq %xmm1,(%edi) // pack in 8 low bytes + psrldq $8,%xmm1 // then shift vector down 8 bytes + addl $8,%edi +4: + test $4,%dl // 4-byte store required? + jz 3f // no + movd %xmm1,(%edi) // pack in 4 low bytes + psrldq $4,%xmm1 // then shift vector down 4 bytes + addl $4,%edi +3: + andl $3,%edx // more to go? + jz LZeroBuffer // no + movd %xmm1,%eax // move remainders out of vector into %eax +1: // loop on up to three bytes + movb %al,(%edi) // pack in next byte + shrl $8,%eax // shift next byte into position + inc %edi + dec %edx + jnz 1b + +// We've copied the string. Now zero the rest of the buffer, using commpage bzero(). +// %edi = dest ptr +// %ecx = buffer length remaining + +LZeroBuffer: + pushl %ecx // remaining buffer size + pushl %edi // ptr to 1st unstored byte + call _bzero + addl $8,%esp // pop off the arguments + +LDone: + movl 12(%esp),%eax // original dest ptr is return value + popl %esi + popl %edi + ret Index: branches/cparm/i386/libsa/bzero_scalar.s =================================================================== --- branches/cparm/i386/libsa/bzero_scalar.s (revision 0) +++ branches/cparm/i386/libsa/bzero_scalar.s (revision 2112) @@ -0,0 +1,111 @@ +/* + * Copyright (c) 2003-2006 Apple Computer, Inc. All rights reserved. + * + * @APPLE_OSREFERENCE_LICENSE_HEADER_START@ + * + * This file contains Original Code and/or Modifications of Original Code + * as defined in and that are subject to the Apple Public Source License + * Version 2.0 (the 'License'). You may not use this file except in + * compliance with the License. The rights granted to you under the License + * may not be used to create, or enable the creation or redistribution of, + * unlawful or unlicensed copies of an Apple operating system, or to + * circumvent, violate, or enable the circumvention or violation of, any + * terms of an Apple operating system software license agreement. + * + * Please obtain a copy of the License at + * http://www.opensource.apple.com/apsl/ and read it before using this file. + * + * The Original Code and all software distributed under the License are + * distributed on an 'AS IS' basis, WITHOUT WARRANTY OF ANY KIND, EITHER + * EXPRESS OR IMPLIED, AND APPLE HEREBY DISCLAIMS ALL SUCH WARRANTIES, + * INCLUDING WITHOUT LIMITATION, ANY WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE, QUIET ENJOYMENT OR NON-INFRINGEMENT. + * Please see the License for the specific language governing rights and + * limitations under the License. + * + * @APPLE_OSREFERENCE_LICENSE_HEADER_END@ + */ +/* + * Copyright (c) 1993 Winning Strategies, Inc. + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * 3. All advertising materials mentioning features or use of this software + * must display the following acknowledgement: + * This product includes software developed by Winning Strategies, Inc. + * 4. The name of the author may not be used to endorse or promote products + * derived from this software withough specific prior written permission + * + * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR + * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES + * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. + * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, + * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT + * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, + * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY + * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF + * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + * + */ +#include + + +/* + * bzero (void *b, size_t len) + * write len zero bytes to the string b. + * + * Written by: + * J.T. Conklin (jtc@wimsey.com), Winning Strategies, Inc. + */ + +LABEL(_bzero) + pushl %ebp /* set up a frame for backtraces */ + movl %esp,%ebp + pushl %edi + pushl %ebx + movl 8(%ebp),%edi + movl 12(%ebp),%ecx + + cld /* set fill direction forward */ + xorl %eax,%eax /* set fill data to 0 */ + + /* + * if the string is too short, it's really not worth the overhead + * of aligning to word boundries, etc. So we jump to a plain + * unaligned set. + */ + cmpl $0x0f,%ecx + jbe L1 + + movl %edi,%edx /* compute misalignment */ + negl %edx + andl $3,%edx + movl %ecx,%ebx + subl %edx,%ebx + + movl %edx,%ecx /* zero until word aligned */ + rep + stosb + + movl %ebx,%ecx /* zero by words */ + shrl $2,%ecx + rep + stosl + + movl %ebx,%ecx + andl $3,%ecx /* zero remainder by bytes */ +L1: rep + stosb + + popl %ebx + popl %edi + popl %ebp + ret Index: branches/cparm/i386/libsa/strlen.s =================================================================== --- branches/cparm/i386/libsa/strlen.s (revision 0) +++ branches/cparm/i386/libsa/strlen.s (revision 2112) @@ -0,0 +1,78 @@ +/* + * Copyright (c) 2005 Apple Computer, Inc. All rights reserved. + * + * @APPLE_LICENSE_HEADER_START@ + * + * The contents of this file constitute Original Code as defined in and + * are subject to the Apple Public Source License Version 1.1 (the + * "License"). You may not use this file except in compliance with the + * License. Please obtain a copy of the License at + * http://www.apple.com/publicsource and read it before using this file. + * + * This Original Code and all software distributed under the License are + * distributed on an "AS IS" basis, WITHOUT WARRANTY OF ANY KIND, EITHER + * EXPRESS OR IMPLIED, AND APPLE HEREBY DISCLAIMS ALL SUCH WARRANTIES, + * INCLUDING WITHOUT LIMITATION, ANY WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE OR NON-INFRINGEMENT. Please see the + * License for the specific language governing rights and limitations + * under the License. + * + * @APPLE_LICENSE_HEADER_END@ + */ + +/* + * Strlen, for processors with SSE3. + * + * Note that all memory references must be aligned, in order to avoid spurious + * page faults. Thus we have to load the aligned 16-byte chunk containing the + * first byte of the operand, then mask out false 0s that may occur before the + * first byte. + * + * We favor the fall-through (ie, short operand) path. + */ + + .text + .globl _strlen + .align 4, 0x90 +_strlen: // size_t strlen(char *b); + movl 4(%esp),%edx // get ptr to string + pxor %xmm0,%xmm0 // zero %xmm0 + movl %edx,%ecx // copy ptr + andl $(-16),%edx // 16-byte align ptr + orl $(-1),%eax + pcmpeqb (%edx),%xmm0 // check whole qw for 0s + andl $15,%ecx // get #bytes in aligned dq before operand + shl %cl,%eax // create mask for the bytes of aligned dq in operand + pmovmskb %xmm0,%ecx // collect mask of 0-bytes + andl %eax,%ecx // mask out any 0s that occur before 1st byte + jz LEnterLoop // no 0-bytes (ie, 1-bits), so enter by-16 loop + +// We've found a 0-byte. +// %edx = aligned address of 16-byte block containing the terminating 0-byte +// %ecx = compare bit vector + +LFoundIt: + bsf %ecx,%eax // find first 1-bit (ie, first 0-byte) + movl 4(%esp),%ecx // recover ptr to 1st byte in string + addl %edx,%eax // get address of the 0-byte + subl %ecx,%eax // subtract address of 1st byte to get string length + ret + +// Loop over aligned 16-byte blocks: +// %edx = address of previous block + +LEnterLoop: + pxor %xmm0,%xmm0 // get some 0-bytes + addl $16,%edx // advance ptr +LLoop: + movdqa (%edx),%xmm1 // get next chunk + addl $16,%edx + pcmpeqb %xmm0,%xmm1 // check for 0s + pmovmskb %xmm1,%ecx // collect mask of 0-bytes + test %ecx,%ecx // any 0-bytes? + jz LLoop // no 0-bytes, so get next dq + + subl $16,%edx // back up ptr + jmp LFoundIt + + \ No newline at end of file Index: branches/cparm/i386/libsa/strcmp.s =================================================================== --- branches/cparm/i386/libsa/strcmp.s (revision 0) +++ branches/cparm/i386/libsa/strcmp.s (revision 2112) @@ -0,0 +1,145 @@ +/* + * Copyright (c) 2005 Apple Computer, Inc. All rights reserved. + * + * @APPLE_LICENSE_HEADER_START@ + * + * This file contains Original Code and/or Modifications of Original Code + * as defined in and that are subject to the Apple Public Source License + * Version 2.0 (the 'License'). You may not use this file except in + * compliance with the License. Please obtain a copy of the License at + * http://www.opensource.apple.com/apsl/ and read it before using this + * file. + * + * The Original Code and all software distributed under the License are + * distributed on an 'AS IS' basis, WITHOUT WARRANTY OF ANY KIND, EITHER + * EXPRESS OR IMPLIED, AND APPLE HEREBY DISCLAIMS ALL SUCH WARRANTIES, + * INCLUDING WITHOUT LIMITATION, ANY WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE, QUIET ENJOYMENT OR NON-INFRINGEMENT. + * Please see the License for the specific language governing rights and + * limitations under the License. + * + * @APPLE_LICENSE_HEADER_END@ + */ + + +// *************** +// * S T R C M P * +// *************** +// +// int strcmp(const char *s1, const char *s2); +// +// We optimize the compare by doing it in parallel, using SSE. This introduces +// a complication: if we blindly did vector loads from both sides until +// finding a difference (or 0), we might get a spurious page fault by +// reading bytes past the difference. To avoid this, we never do a load +// that crosses a page boundary. + + .text + .globl _strcmp + + .align 4 +_strcmp: // int strcmp(const char *s1,const char *s2); + pushl %esi + pushl %edi + movl 12(%esp),%esi // get LHS ptr + movl 16(%esp),%edi // get RHS ptr + + +// In order to avoid spurious page faults, we loop over: +// +// min( bytes_in_LHS_page, bytes_in_RHS_page) >> 4 +// +// 16-byte chunks. When we near a page end, we have to revert to a byte-by-byte +// comparison until reaching the next page, then resume the vector comparison. +// %esi = LHS ptr +// %edi = RHS ptr + +LNextChunk: + movl %esi,%eax // copy ptrs + movl %edi,%edx + andl $4095,%eax // mask down to page offsets + andl $4095,%edx + cmpl %eax,%edx // which is bigger? + cmova %edx,%eax // %eax = max(LHS offset, RHS offset); + movl $4096,%edx + subl %eax,%edx // get #bytes to next page crossing + movl %edx,%eax + shrl $4,%edx // get #chunks till end of operand or page + jnz LLoopOverChunks // enter vector loop + movl %eax,%edx // no chunks... + jmp LLoopOverBytes // ...so loop over bytes until page end + + +// Loop over bytes. +// %esi = LHS ptr +// %edi = RHS ptr +// %edx = byte count + + .align 4,0x90 // align inner loops to optimize I-fetch +LLoopOverBytes: + movzb (%esi),%eax // get LHS byte + movzb (%edi),%ecx // get RHS byte + inc %esi + inc %edi + testl %eax,%eax // 0? + jz LExit0 // yes, we're done + subl %ecx,%eax // compare them + jnz LExit // done if not equal + dec %edx // more to go? + jnz LLoopOverBytes + + jmp LNextChunk // we've come to end of page + + +// Loop over 16-byte chunks. +// %esi = LHS ptr +// %edi = RHS ptr +// %edx = chunk count + + .align 4,0x90 // align inner loops to optimize I-fetch +LLoopOverChunks: + movdqu (%esi),%xmm1 // get LHS + movdqu (%edi),%xmm2 // get RHS + pxor %xmm0,%xmm0 // get some 0s in the shadow of the loads + addl $16,%esi + pcmpeqb %xmm1,%xmm2 // compare LHS to RHS + pcmpeqb %xmm1,%xmm0 // compare LHS to 0s + addl $16,%edi + pmovmskb %xmm2,%eax // get result mask for comparison of LHS and RHS + pmovmskb %xmm0,%ecx // get result mask for 0 check + xorl $0xFFFF,%eax // complement compare mask so 1 means "not equal" + orl %ecx,%eax // combine the masks and check for 1-bits + jnz LFoundDiffOr0 // we found differing bytes or a 0-byte + dec %edx // more to go? + jnz LLoopOverChunks + + jmp LNextChunk // compare up to next page boundary + + +// Found a zero and/or a difference in vector compare. +// %esi = LHS ptr, already advanced by 16 +// %edi = RHS ptr, already advanced by 16 +// %eax = bit n set if bytes n differed or were 0 + +LFoundDiffOr0: + bsf %eax,%edx // which byte differed or was 0? + subl $16,%esi // point to start of vectors while we wait for bit scan + subl $16,%edi + movzb (%esi,%edx),%eax // get LHS byte + movzb (%edi,%edx),%ecx // get RHS byte + subl %ecx,%eax // compute difference (ie, return value) + popl %edi + popl %esi + ret + + +// Found a zero and/or difference in byte loop. +// %eax = LHS byte +// %ecx = RHS byte + +LExit0: + subl %ecx,%eax // compute difference (ie, return value) +LExit: // here with difference already in %eax + popl %edi + popl %esi + ret Index: branches/cparm/i386/libsa/Makefile =================================================================== --- branches/cparm/i386/libsa/Makefile (revision 2111) +++ branches/cparm/i386/libsa/Makefile (revision 2112) @@ -25,11 +25,11 @@ VPATH = $(OBJROOT):$(SYMROOT) -SA_OBJS = qdivrem.o umoddi3.o udivdi3.o divdi3.o moddi3.o bzero.o bcopy.o printf.o zalloc.o\ +SA_OBJS = qdivrem.o umoddi3.o udivdi3.o divdi3.o moddi3.o __bzero.o bzero_scalar.o strcmp.o strcpy.o strncpy.o strlcpy.o strncmp.o strlcat.o bcopy_scalar.o memcmp.o memset.o memset_pattern_sse2.o strlen.o printf.o zalloc.o\ string.o strtol.o \ setjmp.o qsort.o efi_tables.o -SFILES = setjmp.s bzero.s bcopy.s +SFILES = setjmp.s bzero.s bcopy.s __bzero.s bzero_scalar.s strcmp.s strcpy.s strncpy.s strlcpy.s strncmp.s strlcat.s memcmp.s memset.s memset_pattern_sse2.s strlen.s CFILES = qdivrem.c umoddi3.c udivdi3.c divdi3.c moddi3.c prf.c printf.c zalloc.c \ string.c strtol.c \ qsort.c efi_tables.c Index: branches/cparm/i386/libsa/strlcat.s =================================================================== --- branches/cparm/i386/libsa/strlcat.s (revision 0) +++ branches/cparm/i386/libsa/strlcat.s (revision 2112) @@ -0,0 +1,243 @@ +/* + * Copyright (c) 2007 Apple Inc. All rights reserved. + * + * @APPLE_LICENSE_HEADER_START@ + * + * This file contains Original Code and/or Modifications of Original Code + * as defined in and that are subject to the Apple Public Source License + * Version 2.0 (the 'License'). You may not use this file except in + * compliance with the License. Please obtain a copy of the License at + * http://www.opensource.apple.com/apsl/ and read it before using this + * file. + * + * The Original Code and all software distributed under the License are + * distributed on an 'AS IS' basis, WITHOUT WARRANTY OF ANY KIND, EITHER + * EXPRESS OR IMPLIED, AND APPLE HEREBY DISCLAIMS ALL SUCH WARRANTIES, + * INCLUDING WITHOUT LIMITATION, ANY WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE, QUIET ENJOYMENT OR NON-INFRINGEMENT. + * Please see the License for the specific language governing rights and + * limitations under the License. + * + * @APPLE_LICENSE_HEADER_END@ + */ + + +// ***************** +// * S T R L C A T * +// ***************** +// +// size_t strlcat(char *dst, const char *src, size_t size); +// +// We use SSE to do the initial strlen(), and word-parallel copies +// to do the move. This appears to be faster than either all SSE +// or all word-parallel, at least on Core2 class machines. +// +// Using 4- or 16-byte parallel loops introduce a complication: +// if we blindly did parallel load/stores until finding +// a 0, we might get a spurious page fault by touching bytes past it. +// To avoid this, we never do a load that crosses a page boundary, +// or store unnecessary bytes. +// +// The word parallel test for 0s relies on the following inobvious +// but very efficient test: +// x = dataWord + 0xFEFEFEFF +// y = ~dataWord & 0x80808080 +// if (x & y) == 0 then no zero found +// The test maps any non-zero byte to zero, and any zero byte to 0x80, +// with one exception: 0x01 bytes preceeding the first zero are also +// mapped to 0x80. +// +// On Core2 class machines, this algorithm seems to be faster than the +// naive byte-by-byte version for operands longer than about 10 bytes. + + .text + .globl _strlcat + + .align 4 +_strlcat: // size_t *strlcat(char *dst, const char *src, size_t size); + pushl %edi + pushl %esi + pushl %ebx + movl 16(%esp),%edi // get dest ptr + movl 20(%esp),%esi // get source ptr + movl 24(%esp),%ebx // get length of buffer + + +// Use SSE to find the 0-byte at current end of buffer. +// This is just a minor variant of strlen(). + + movl %edi,%ecx // copy buffer ptr + andl $(-16),%edi // 16-byte align buffer ptr + pxor %xmm0,%xmm0 // get some 0s + andl $15,%ecx // get #bytes in dq before start of buffer + movl $16,%edx + orl $(-1),%eax + subl %ecx,%edx // #bytes from buffer start to end of dq + subl %edx,%ebx // does buffer end before end of dq? + jb LShortBuf1 // yes, drop into byte-by-byte mode + movdqa (%edi),%xmm1 // get first aligned chunk of buffer + addl $16,%edi + pcmpeqb %xmm0,%xmm1 // check for 0s + shl %cl,%eax // create mask for the bytes of aligned dq in operand + pmovmskb %xmm1,%ecx // collect mask of 0-bytes + andl %eax,%ecx // mask out any 0s that occur before buffer start + jnz 2f // found end of buffer +1: + subl $16,%ebx // another dq in buffer? + jb LShortBuf2 // no, drop into byte-by-byte mode + movdqa (%edi),%xmm1 // get next chunk + addl $16,%edi + pcmpeqb %xmm0,%xmm1 // check for 0s + pmovmskb %xmm1,%ecx // collect mask of 0-bytes + testl %ecx,%ecx // any 0-bytes? + jz 1b // no +2: + bsf %ecx,%edx // find first 1-bit (ie, first 0-byte) + subl $16,%edi // back up ptr into buffer + addl $16,%ebx // recover length remaining as of start of dq + addl %edx,%edi // point to 0-byte + subl %edx,%ebx // compute #bytes remaining in buffer + + +// Copy byte-by-byte until source is 4-byte aligned. +// %edi = points to 1st byte available in buffer +// %esi = src ptr +// %ebx = buffer length remaining (ie, starting at %edi) +// +// NB: the rest of this code is cut-and-pasted from strlcpy(). + + movl %esi,%edx // copy source ptr + negl %edx + andl $3,%edx // how many bytes to align source ptr? + jz LAligned // already aligned + + +// Loop over bytes. +// %edi = dest ptr +// %esi = source ptr +// %ebx = length remaining in buffer +// %edx = number of bytes to copy (>0, may not fit in buffer) + +LLoopOverBytes: + movzb (%esi),%eax // get source byte before checking buffer length + testl %ebx,%ebx // buffer full? + jz L0NotFound // yes + inc %esi + dec %ebx + movb %al,(%edi) // pack into dest + inc %edi + testl %eax,%eax // 0? + jz LDone // yes, done + dec %edx // more to go? + jnz LLoopOverBytes + + +// Source is aligned. Loop over words until end of buffer. We +// align the source, rather than the dest, to avoid getting spurious page faults. +// %edi = dest ptr (unaligned) +// %esi = source ptr (word aligned) +// %ebx = length remaining in buffer + +LAligned: + movl $5,%edx // if buffer almost exhausted, prepare to copy rest byte-by-byte + cmpl $4,%ebx // enough for at least one word? + jb LLoopOverBytes + + +// Loop over words. +// %edi = dest ptr (unaligned) +// %esi = source ptr (word aligned) +// %ebx = length remaining in buffer (>=4) + +LLoopOverWords: + movl (%esi),%eax // get next 4 bytes of source + subl $4,%ebx + addl $4,%esi + movl %eax,%edx // make 2 copies of word + movl %eax,%ecx + notl %edx // use magic word-parallel test for 0s + addl $0xFEFEFEFF,%ecx + andl $0x80808080,%edx + testl %ecx,%edx + jnz L0Found // one of the bytes of %eax is a 0 + movl %eax,(%edi) // pack 4 bytes into destination + addl $4,%edi + cmpl $4,%ebx // room in buffer for another word? + jae LLoopOverWords // yes + + movl %ebx,%edx // copy leftovers in byte loop + jmp LLoopOverBytes + +// Found a 0-byte in the word of source. Store a byte at a time until the 0. +// %edi = dest ptr (unaligned) +// %eax = last word of source, known to have a 0-byte + +LNextByte: + shrl $8,%eax // next byte +L0Found: + movb %al,(%edi) // pack in next byte + incl %edi + testb %al,%al // 0? + jnz LNextByte + +// Done storing string. +// %edi = ptr to byte after 0-byte + +LDone: + subl 16(%esp),%edi // subtract original dest ptr to get length stored + decl %edi // don't count the 0-byte + movl %edi,%eax // copy to return value +LExit: + popl %ebx + popl %esi + popl %edi + ret + +// Buffer filled but 0-byte not found. We return the length of the buffer plus the length +// of the source string. This is not optimized, as it is an error condition. +// %edi = dest ptr (ie, 1 past end of buffer) +// %esi = source ptr (ptr to 1st byte that does not fit) + +L0NotFound: + movl 24(%esp),%eax // reload buffer length + testl %eax,%eax // null? + jz LScanSourceTo0 // yes, cannot store a 0 + xorl %edx,%edx // get a 0 + movb %dl,-1(%edi) // store a 0 at end of buffer to delimit string +LScanSourceTo0: + movzb (%esi),%edx // get next byte of source + incl %esi + incl %eax + testl %edx,%edx // 0? + jnz LScanSourceTo0 + decl %eax // don't count the 0-byte + jmp LExit + + +// Buffer too short to reach end of even one 16-byte aligned chunk. +// %esi = src ptr + +LShortBuf1: + movl 16(%esp),%edi // recover ptr to start of buffer + movl 24(%esp),%ebx // recover buffer length + jmp LShortBuf3 + + +// Out of aligned dq's of buffer, 0-byte still not found. +// %esi = src ptr +// %edi = 1st buffer byte not checked for 0 +// %ebx = length remaining - 16 + +LShortBuf2: + addl $16,%ebx // length remaining +LShortBuf3: + movl 24(%esp),%eax // recover original buffer length, in case 0-byte not found + movl $17,%edx // buffer almost exhausted, prepare to copy byte-by-byte +1: + testl %ebx,%ebx // no 0s in buffer at all? + jz LScanSourceTo0 // yes, cannot store a 0 + cmpb $0,(%edi) // is this the 0? + jz LLoopOverBytes // yes, append source + incl %edi + decl %ebx + jmp 1b // loop looking for 0 Index: branches/cparm/i386/util/fdisk/user.c =================================================================== --- branches/cparm/i386/util/fdisk/user.c (revision 2111) +++ branches/cparm/i386/util/fdisk/user.c (revision 2112) @@ -166,7 +166,7 @@ if (mbr->signature != MBR_SIGNATURE) { int yn = ask_yn("The signature for this MBR is invalid.\nWould you like to initialize the partition table?", 1); if (yn) { - strcpy(cmd.cmd, "erase"); + strlcpy(cmd.cmd, "erase", sizeof(cmd.cmd)); cmd.args[0] = '\0'; st /* false positive ?? */ = Xerase(&cmd, disk, mbr, tt, offset); modified = 1; @@ -189,7 +189,7 @@ break; /* Quick hack to put in '?' == 'help' */ - if (!strcmp(cmd.cmd, "?")) + if (!strncmp(cmd.cmd, "?", sizeof("?"))) i = 0; /* Check for valid command */ @@ -197,7 +197,7 @@ printf("Invalid command '%s'. Try 'help'.\n", cmd.cmd); continue; } else - strcpy(cmd.cmd, cmd_table[i].cmd); + strlcpy(cmd.cmd, cmd_table[i].cmd, sizeof(cmd.cmd)); /* Call function */ st = cmd_table[i].fcn(&cmd, disk, mbr, tt, offset); Index: branches/cparm/i386/util/md.c =================================================================== --- branches/cparm/i386/util/md.c (revision 2111) +++ branches/cparm/i386/util/md.c (revision 2112) @@ -441,7 +441,7 @@ if (c) cp[-1]=0;/* end component C style */ /* ignore . */; - if (!strcmp(path_component[i], ".")) + if (!strncmp(path_component[i], ".", sizeof("."))) ; /* if "component" != .. */ else /* don't reduce /component/.. to nothing */ i++; /* there could be symbolic links! */ Index: branches/cparm/i386/util/machOconv.c =================================================================== --- branches/cparm/i386/util/machOconv.c (revision 2111) +++ branches/cparm/i386/util/machOconv.c (revision 2112) @@ -119,7 +119,7 @@ case LC_SEGMENT: #define scp ((struct segment_command *)cp) - isDATA = (strcmp(scp->segname, "__DATA") == 0); + isDATA = (strncmp(scp->segname, "__DATA", sizeof("__DATA")) == 0); if (isDATA) vmsize = swap(scp->filesize); else Index: branches/cparm/xcode3_sym.zip =================================================================== Cannot display: file marked as a binary type. svn:mime-type = application/octet-stream