main.cpp revision 1685d00d0a6b905a820a76c9686b6b4b077dfe4a
1fd65a4e22d8afef028b84c018519468a5f6545f0Christopher Ferris/* 2fd65a4e22d8afef028b84c018519468a5f6545f0Christopher Ferris** Copyright 2013 The Android Open Source Project 3fd65a4e22d8afef028b84c018519468a5f6545f0Christopher Ferris** 4fd65a4e22d8afef028b84c018519468a5f6545f0Christopher Ferris** Licensed under the Apache License, Version 2.0 (the "License"); 5fd65a4e22d8afef028b84c018519468a5f6545f0Christopher Ferris** you may not use this file except in compliance with the License. 6fd65a4e22d8afef028b84c018519468a5f6545f0Christopher Ferris** You may obtain a copy of the License at 7fd65a4e22d8afef028b84c018519468a5f6545f0Christopher Ferris** 8fd65a4e22d8afef028b84c018519468a5f6545f0Christopher Ferris** http://www.apache.org/licenses/LICENSE-2.0 9fd65a4e22d8afef028b84c018519468a5f6545f0Christopher Ferris** 10fd65a4e22d8afef028b84c018519468a5f6545f0Christopher Ferris** Unless required by applicable law or agreed to in writing, software 11fd65a4e22d8afef028b84c018519468a5f6545f0Christopher Ferris** distributed under the License is distributed on an "AS IS" BASIS, 12fd65a4e22d8afef028b84c018519468a5f6545f0Christopher Ferris** WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13fd65a4e22d8afef028b84c018519468a5f6545f0Christopher Ferris** See the License for the specific language governing permissions and 14fd65a4e22d8afef028b84c018519468a5f6545f0Christopher Ferris** limitations under the License. 15fd65a4e22d8afef028b84c018519468a5f6545f0Christopher Ferris*/ 16fd65a4e22d8afef028b84c018519468a5f6545f0Christopher Ferris 17fd65a4e22d8afef028b84c018519468a5f6545f0Christopher Ferris#include <stdio.h> 18fd65a4e22d8afef028b84c018519468a5f6545f0Christopher Ferris#include <stdlib.h> 19fd65a4e22d8afef028b84c018519468a5f6545f0Christopher Ferris#include <unistd.h> 20fd65a4e22d8afef028b84c018519468a5f6545f0Christopher Ferris#include <sys/mman.h> 21fd65a4e22d8afef028b84c018519468a5f6545f0Christopher Ferris 22fd65a4e22d8afef028b84c018519468a5f6545f0Christopher Ferris// Put any local test functions into the extern below. 23fd65a4e22d8afef028b84c018519468a5f6545f0Christopher Ferrisextern "C" { 24fd65a4e22d8afef028b84c018519468a5f6545f0Christopher Ferris} 25fd65a4e22d8afef028b84c018519468a5f6545f0Christopher Ferris 26f0b2c68c83e6ced8f988f014bc235393ca231958Christopher Ferris#define FENCEPOST_LENGTH 8 27f0b2c68c83e6ced8f988f014bc235393ca231958Christopher Ferris 28fd65a4e22d8afef028b84c018519468a5f6545f0Christopher Ferris#define MAX_MEMCPY_TEST_SIZE 2048 29fd65a4e22d8afef028b84c018519468a5f6545f0Christopher Ferris#define MAX_MEMCPY_BUFFER_SIZE (3 * MAX_MEMCPY_TEST_SIZE) 30fd65a4e22d8afef028b84c018519468a5f6545f0Christopher Ferris 31cd0530e6b72ed9ff4c38f15feea0f231c710af1fChristopher Ferris#define MAX_MEMSET_TEST_SIZE 2048 32cd0530e6b72ed9ff4c38f15feea0f231c710af1fChristopher Ferris#define MAX_MEMSET_BUFFER_SIZE (3 * MAX_MEMSET_TEST_SIZE) 33cd0530e6b72ed9ff4c38f15feea0f231c710af1fChristopher Ferris 34fd65a4e22d8afef028b84c018519468a5f6545f0Christopher Ferris#define MAX_STRCMP_TEST_SIZE 1024 35fd65a4e22d8afef028b84c018519468a5f6545f0Christopher Ferris#define MAX_STRCMP_BUFFER_SIZE (3 * MAX_STRCMP_TEST_SIZE) 36fd65a4e22d8afef028b84c018519468a5f6545f0Christopher Ferris 37fd65a4e22d8afef028b84c018519468a5f6545f0Christopher Ferris// Return a pointer into the current string with the specified alignment. 38fd65a4e22d8afef028b84c018519468a5f6545f0Christopher Ferrisvoid *getAlignedPtr(void *orig_ptr, int alignment, int or_mask) { 39fd65a4e22d8afef028b84c018519468a5f6545f0Christopher Ferris uint64_t ptr = reinterpret_cast<uint64_t>(orig_ptr); 40fd65a4e22d8afef028b84c018519468a5f6545f0Christopher Ferris if (alignment > 0) { 41fd65a4e22d8afef028b84c018519468a5f6545f0Christopher Ferris // When setting the alignment, set it to exactly the alignment chosen. 42fd65a4e22d8afef028b84c018519468a5f6545f0Christopher Ferris // The pointer returned will be guaranteed not to be aligned to anything 43fd65a4e22d8afef028b84c018519468a5f6545f0Christopher Ferris // more than that. 44fd65a4e22d8afef028b84c018519468a5f6545f0Christopher Ferris ptr += alignment - (ptr & (alignment - 1)); 45fd65a4e22d8afef028b84c018519468a5f6545f0Christopher Ferris ptr |= alignment | or_mask; 46fd65a4e22d8afef028b84c018519468a5f6545f0Christopher Ferris } 47fd65a4e22d8afef028b84c018519468a5f6545f0Christopher Ferris 48fd65a4e22d8afef028b84c018519468a5f6545f0Christopher Ferris return reinterpret_cast<void*>(ptr); 49fd65a4e22d8afef028b84c018519468a5f6545f0Christopher Ferris} 50fd65a4e22d8afef028b84c018519468a5f6545f0Christopher Ferris 51f0b2c68c83e6ced8f988f014bc235393ca231958Christopher Ferrisvoid setFencepost(uint8_t *buffer) { 52f0b2c68c83e6ced8f988f014bc235393ca231958Christopher Ferris for (int i = 0; i < FENCEPOST_LENGTH; i += 2) { 53f0b2c68c83e6ced8f988f014bc235393ca231958Christopher Ferris buffer[i] = 0xde; 54f0b2c68c83e6ced8f988f014bc235393ca231958Christopher Ferris buffer[i+1] = 0xad; 55f0b2c68c83e6ced8f988f014bc235393ca231958Christopher Ferris } 56f0b2c68c83e6ced8f988f014bc235393ca231958Christopher Ferris} 57f0b2c68c83e6ced8f988f014bc235393ca231958Christopher Ferris 58f0b2c68c83e6ced8f988f014bc235393ca231958Christopher Ferrisbool verifyFencepost(uint8_t *buffer) { 59f0b2c68c83e6ced8f988f014bc235393ca231958Christopher Ferris for (int i = 0; i < FENCEPOST_LENGTH; i += 2) { 60f0b2c68c83e6ced8f988f014bc235393ca231958Christopher Ferris if (buffer[i] != 0xde || buffer[i+1] != 0xad) { 61f0b2c68c83e6ced8f988f014bc235393ca231958Christopher Ferris uint8_t expected_value; 62f0b2c68c83e6ced8f988f014bc235393ca231958Christopher Ferris if (buffer[i] == 0xde) { 63f0b2c68c83e6ced8f988f014bc235393ca231958Christopher Ferris i++; 64f0b2c68c83e6ced8f988f014bc235393ca231958Christopher Ferris expected_value = 0xad; 65f0b2c68c83e6ced8f988f014bc235393ca231958Christopher Ferris } else { 66f0b2c68c83e6ced8f988f014bc235393ca231958Christopher Ferris expected_value = 0xde; 67f0b2c68c83e6ced8f988f014bc235393ca231958Christopher Ferris } 68f0b2c68c83e6ced8f988f014bc235393ca231958Christopher Ferris printf(" mismatch at fencepost[%d], expected %d found %d\n", 69f0b2c68c83e6ced8f988f014bc235393ca231958Christopher Ferris i, expected_value, buffer[i]); 70f0b2c68c83e6ced8f988f014bc235393ca231958Christopher Ferris return false; 71f0b2c68c83e6ced8f988f014bc235393ca231958Christopher Ferris } 72f0b2c68c83e6ced8f988f014bc235393ca231958Christopher Ferris } 73f0b2c68c83e6ced8f988f014bc235393ca231958Christopher Ferris return true; 74f0b2c68c83e6ced8f988f014bc235393ca231958Christopher Ferris} 75f0b2c68c83e6ced8f988f014bc235393ca231958Christopher Ferris 76fd65a4e22d8afef028b84c018519468a5f6545f0Christopher Ferrisbool doStrcmpExpectEqual(char *string1, char *string2, int align[4], 77f0b2c68c83e6ced8f988f014bc235393ca231958Christopher Ferris int (*test_strcmp)(const char *s1, const char *s2), 78f0b2c68c83e6ced8f988f014bc235393ca231958Christopher Ferris bool verbose) { 79fd65a4e22d8afef028b84c018519468a5f6545f0Christopher Ferris char *align_str1 = (char*)getAlignedPtr(string1, align[0], align[1]); 80fd65a4e22d8afef028b84c018519468a5f6545f0Christopher Ferris char *align_str2 = (char*)getAlignedPtr(string2, align[2], align[3]); 81fd65a4e22d8afef028b84c018519468a5f6545f0Christopher Ferris 82f0b2c68c83e6ced8f988f014bc235393ca231958Christopher Ferris for (size_t i = 0; i < MAX_STRCMP_TEST_SIZE; i++) { 83f0b2c68c83e6ced8f988f014bc235393ca231958Christopher Ferris for (size_t j = 0; j < i; j++) { 84fd65a4e22d8afef028b84c018519468a5f6545f0Christopher Ferris align_str1[j] = (char)(32 + (j % 96)); 85fd65a4e22d8afef028b84c018519468a5f6545f0Christopher Ferris align_str2[j] = align_str1[j]; 86fd65a4e22d8afef028b84c018519468a5f6545f0Christopher Ferris } 87fd65a4e22d8afef028b84c018519468a5f6545f0Christopher Ferris align_str1[i] = '\0'; 88fd65a4e22d8afef028b84c018519468a5f6545f0Christopher Ferris align_str2[i] = '\0'; 89f0b2c68c83e6ced8f988f014bc235393ca231958Christopher Ferris 90fd65a4e22d8afef028b84c018519468a5f6545f0Christopher Ferris // Set the characters after the string terminates to different values 91fd65a4e22d8afef028b84c018519468a5f6545f0Christopher Ferris // to verify that the strcmp is not over checking. 92f0b2c68c83e6ced8f988f014bc235393ca231958Christopher Ferris for (size_t j = i+1; j < i+64; j++) { 93fd65a4e22d8afef028b84c018519468a5f6545f0Christopher Ferris align_str1[j] = (char)(32 + j); 94fd65a4e22d8afef028b84c018519468a5f6545f0Christopher Ferris align_str2[j] = (char)(40 + j); 95fd65a4e22d8afef028b84c018519468a5f6545f0Christopher Ferris } 96fd65a4e22d8afef028b84c018519468a5f6545f0Christopher Ferris 97f0b2c68c83e6ced8f988f014bc235393ca231958Christopher Ferris if (verbose) { 98f0b2c68c83e6ced8f988f014bc235393ca231958Christopher Ferris printf("Testing size %d, align_str1=%p[%d,%d], align_str2=%p[%d,%d]\n", 99f0b2c68c83e6ced8f988f014bc235393ca231958Christopher Ferris i, align_str1, align[0], align[1], align_str2, align[2], align[3]); 100f0b2c68c83e6ced8f988f014bc235393ca231958Christopher Ferris } 101f0b2c68c83e6ced8f988f014bc235393ca231958Christopher Ferris 102fd65a4e22d8afef028b84c018519468a5f6545f0Christopher Ferris if (test_strcmp(align_str1, align_str2) != 0) { 103fd65a4e22d8afef028b84c018519468a5f6545f0Christopher Ferris printf(" Failed at size %d, src1 %p, src2 %p\n", 104fd65a4e22d8afef028b84c018519468a5f6545f0Christopher Ferris i, align_str1, align_str2); 105f0b2c68c83e6ced8f988f014bc235393ca231958Christopher Ferris return false; 106fd65a4e22d8afef028b84c018519468a5f6545f0Christopher Ferris } 107fd65a4e22d8afef028b84c018519468a5f6545f0Christopher Ferris } 108f0b2c68c83e6ced8f988f014bc235393ca231958Christopher Ferris 109f0b2c68c83e6ced8f988f014bc235393ca231958Christopher Ferris return true; 110fd65a4e22d8afef028b84c018519468a5f6545f0Christopher Ferris} 111fd65a4e22d8afef028b84c018519468a5f6545f0Christopher Ferris 112fd65a4e22d8afef028b84c018519468a5f6545f0Christopher Ferrisbool doStrcmpExpectDiff(char *string1, char *string2, int diff_align[2], 113fd65a4e22d8afef028b84c018519468a5f6545f0Christopher Ferris int align[4], char diff_char, 114f0b2c68c83e6ced8f988f014bc235393ca231958Christopher Ferris int (*test_strcmp)(const char *s1, const char *s2), 115f0b2c68c83e6ced8f988f014bc235393ca231958Christopher Ferris bool verbose) { 116fd65a4e22d8afef028b84c018519468a5f6545f0Christopher Ferris char *align_str1 = (char*)getAlignedPtr(string1, align[0], align[1]); 117fd65a4e22d8afef028b84c018519468a5f6545f0Christopher Ferris char *align_str2 = (char*)getAlignedPtr(string2, align[2], align[3]); 118fd65a4e22d8afef028b84c018519468a5f6545f0Christopher Ferris 119fd65a4e22d8afef028b84c018519468a5f6545f0Christopher Ferris for (int i = 0; i < MAX_STRCMP_TEST_SIZE; i++) { 120fd65a4e22d8afef028b84c018519468a5f6545f0Christopher Ferris // Use valid ascii characters, no unprintables characters. 121fd65a4e22d8afef028b84c018519468a5f6545f0Christopher Ferris align_str1[i] = (char)(32 + (i % 96)); 122fd65a4e22d8afef028b84c018519468a5f6545f0Christopher Ferris if (align_str1[i] == diff_char) { 123fd65a4e22d8afef028b84c018519468a5f6545f0Christopher Ferris // Assumes that one less than the diff character is still a valid 124fd65a4e22d8afef028b84c018519468a5f6545f0Christopher Ferris // character. 125fd65a4e22d8afef028b84c018519468a5f6545f0Christopher Ferris align_str1[i] = diff_char-1; 126fd65a4e22d8afef028b84c018519468a5f6545f0Christopher Ferris } 127fd65a4e22d8afef028b84c018519468a5f6545f0Christopher Ferris align_str2[i] = align_str1[i]; 128fd65a4e22d8afef028b84c018519468a5f6545f0Christopher Ferris } 129fd65a4e22d8afef028b84c018519468a5f6545f0Christopher Ferris align_str1[MAX_STRCMP_TEST_SIZE] = '\0'; 130fd65a4e22d8afef028b84c018519468a5f6545f0Christopher Ferris align_str2[MAX_STRCMP_TEST_SIZE] = '\0'; 131fd65a4e22d8afef028b84c018519468a5f6545f0Christopher Ferris 132fd65a4e22d8afef028b84c018519468a5f6545f0Christopher Ferris // Quick check to make sure that the strcmp knows that everything is 133fd65a4e22d8afef028b84c018519468a5f6545f0Christopher Ferris // equal. If it's so broken that it already thinks the strings are 134fd65a4e22d8afef028b84c018519468a5f6545f0Christopher Ferris // different, then there is no point running any of the other tests. 135fd65a4e22d8afef028b84c018519468a5f6545f0Christopher Ferris if (test_strcmp(align_str1, align_str2) != 0) { 136fd65a4e22d8afef028b84c018519468a5f6545f0Christopher Ferris printf(" strcmp is too broken to do difference testing.\n"); 137fd65a4e22d8afef028b84c018519468a5f6545f0Christopher Ferris return false; 138fd65a4e22d8afef028b84c018519468a5f6545f0Christopher Ferris } 139fd65a4e22d8afef028b84c018519468a5f6545f0Christopher Ferris 140fd65a4e22d8afef028b84c018519468a5f6545f0Christopher Ferris // Get a pointer into the string at the specified alignment. 141f0b2c68c83e6ced8f988f014bc235393ca231958Christopher Ferris char *bad = (char*)getAlignedPtr(align_str1+MAX_STRCMP_TEST_SIZE/2, 142f0b2c68c83e6ced8f988f014bc235393ca231958Christopher Ferris diff_align[0], diff_align[1]); 143fd65a4e22d8afef028b84c018519468a5f6545f0Christopher Ferris 144fd65a4e22d8afef028b84c018519468a5f6545f0Christopher Ferris char saved_char = bad[0]; 145fd65a4e22d8afef028b84c018519468a5f6545f0Christopher Ferris bad[0] = diff_char; 146f0b2c68c83e6ced8f988f014bc235393ca231958Christopher Ferris 147f0b2c68c83e6ced8f988f014bc235393ca231958Christopher Ferris if (verbose) { 148f0b2c68c83e6ced8f988f014bc235393ca231958Christopher Ferris printf("Testing difference, align_str1=%p[%d,%d], align_str2=%p[%d,%d]\n", 149f0b2c68c83e6ced8f988f014bc235393ca231958Christopher Ferris align_str1, align[0], align[1], align_str2, align[2], align[3]); 150f0b2c68c83e6ced8f988f014bc235393ca231958Christopher Ferris } 151fd65a4e22d8afef028b84c018519468a5f6545f0Christopher Ferris if (test_strcmp(align_str1, align_str2) == 0) { 152fd65a4e22d8afef028b84c018519468a5f6545f0Christopher Ferris printf(" Did not miscompare at size %d, src1 %p, src2 %p, diff %p\n", 153fd65a4e22d8afef028b84c018519468a5f6545f0Christopher Ferris MAX_STRCMP_TEST_SIZE, align_str1, align_str2, bad); 154f0b2c68c83e6ced8f988f014bc235393ca231958Christopher Ferris return false; 155fd65a4e22d8afef028b84c018519468a5f6545f0Christopher Ferris } 156fd65a4e22d8afef028b84c018519468a5f6545f0Christopher Ferris bad[0] = saved_char; 157fd65a4e22d8afef028b84c018519468a5f6545f0Christopher Ferris 158fd65a4e22d8afef028b84c018519468a5f6545f0Christopher Ferris // Re-verify that something hasn't gone horribly wrong. 159fd65a4e22d8afef028b84c018519468a5f6545f0Christopher Ferris if (test_strcmp(align_str1, align_str2) != 0) { 160fd65a4e22d8afef028b84c018519468a5f6545f0Christopher Ferris printf(" strcmp is too broken to do difference testing.\n"); 161fd65a4e22d8afef028b84c018519468a5f6545f0Christopher Ferris return false; 162fd65a4e22d8afef028b84c018519468a5f6545f0Christopher Ferris } 163fd65a4e22d8afef028b84c018519468a5f6545f0Christopher Ferris 164fd65a4e22d8afef028b84c018519468a5f6545f0Christopher Ferris bad = (char*)getAlignedPtr(align_str2+MAX_STRCMP_TEST_SIZE/2, diff_align[0], 165fd65a4e22d8afef028b84c018519468a5f6545f0Christopher Ferris diff_align[1]); 166fd65a4e22d8afef028b84c018519468a5f6545f0Christopher Ferris bad[0] = diff_char; 167f0b2c68c83e6ced8f988f014bc235393ca231958Christopher Ferris 168f0b2c68c83e6ced8f988f014bc235393ca231958Christopher Ferris if (verbose) { 169f0b2c68c83e6ced8f988f014bc235393ca231958Christopher Ferris printf("Testing reverse difference, align_str1=%p[%d,%d], align_str2=%p[%d,%d]\n", 170f0b2c68c83e6ced8f988f014bc235393ca231958Christopher Ferris align_str1, align[0], align[1], align_str2, align[2], align[3]); 171f0b2c68c83e6ced8f988f014bc235393ca231958Christopher Ferris } 172fd65a4e22d8afef028b84c018519468a5f6545f0Christopher Ferris if (test_strcmp(align_str1, align_str2) == 0) { 173fd65a4e22d8afef028b84c018519468a5f6545f0Christopher Ferris printf(" Did not miscompare at size %d, src1 %p, src2 %p, diff %p\n", 174fd65a4e22d8afef028b84c018519468a5f6545f0Christopher Ferris MAX_STRCMP_TEST_SIZE, align_str1, align_str2, bad); 175f0b2c68c83e6ced8f988f014bc235393ca231958Christopher Ferris return false; 176fd65a4e22d8afef028b84c018519468a5f6545f0Christopher Ferris } 177fd65a4e22d8afef028b84c018519468a5f6545f0Christopher Ferris 178f0b2c68c83e6ced8f988f014bc235393ca231958Christopher Ferris return true; 179fd65a4e22d8afef028b84c018519468a5f6545f0Christopher Ferris} 180fd65a4e22d8afef028b84c018519468a5f6545f0Christopher Ferris 181f0b2c68c83e6ced8f988f014bc235393ca231958Christopher Ferrisbool doStrcmpCheckRead(int (*test_strcmp)(const char *s1, const char *s2), 182f0b2c68c83e6ced8f988f014bc235393ca231958Christopher Ferris bool verbose) { 183fd65a4e22d8afef028b84c018519468a5f6545f0Christopher Ferris // In order to verify that the strcmp is not reading past the end of the 184fd65a4e22d8afef028b84c018519468a5f6545f0Christopher Ferris // string, create some strings that end near unreadable memory. 185fd65a4e22d8afef028b84c018519468a5f6545f0Christopher Ferris long pagesize = sysconf(_SC_PAGE_SIZE); 186fd65a4e22d8afef028b84c018519468a5f6545f0Christopher Ferris char *memory = (char*)memalign(pagesize, 2 * pagesize); 187fd65a4e22d8afef028b84c018519468a5f6545f0Christopher Ferris if (memory == NULL) { 188fd65a4e22d8afef028b84c018519468a5f6545f0Christopher Ferris perror("Unable to allocate memory.\n"); 189fd65a4e22d8afef028b84c018519468a5f6545f0Christopher Ferris return false; 190fd65a4e22d8afef028b84c018519468a5f6545f0Christopher Ferris } 191fd65a4e22d8afef028b84c018519468a5f6545f0Christopher Ferris 192fd65a4e22d8afef028b84c018519468a5f6545f0Christopher Ferris // Make the second page unreadable and unwritable. 193fd65a4e22d8afef028b84c018519468a5f6545f0Christopher Ferris if (mprotect(&memory[pagesize], pagesize, PROT_NONE) != 0) { 194fd65a4e22d8afef028b84c018519468a5f6545f0Christopher Ferris perror("Unable to set protection of page.\n"); 195fd65a4e22d8afef028b84c018519468a5f6545f0Christopher Ferris return false; 196fd65a4e22d8afef028b84c018519468a5f6545f0Christopher Ferris } 197fd65a4e22d8afef028b84c018519468a5f6545f0Christopher Ferris 198f0b2c68c83e6ced8f988f014bc235393ca231958Christopher Ferris size_t max_size = pagesize < MAX_STRCMP_TEST_SIZE ? pagesize-1 : MAX_STRCMP_TEST_SIZE; 199fd65a4e22d8afef028b84c018519468a5f6545f0Christopher Ferris // Allocate an extra byte beyond the string terminator to allow us to 200fd65a4e22d8afef028b84c018519468a5f6545f0Christopher Ferris // extend the string to be larger than our protected string. 201fd65a4e22d8afef028b84c018519468a5f6545f0Christopher Ferris char *other_string = (char *)malloc(max_size+2); 202fd65a4e22d8afef028b84c018519468a5f6545f0Christopher Ferris if (other_string == NULL) { 203fd65a4e22d8afef028b84c018519468a5f6545f0Christopher Ferris perror("Unable to allocate memory.\n"); 204fd65a4e22d8afef028b84c018519468a5f6545f0Christopher Ferris return false; 205fd65a4e22d8afef028b84c018519468a5f6545f0Christopher Ferris } 206f0b2c68c83e6ced8f988f014bc235393ca231958Christopher Ferris char *string; 207f0b2c68c83e6ced8f988f014bc235393ca231958Christopher Ferris for (size_t i = 0; i <= max_size; i++) { 208fd65a4e22d8afef028b84c018519468a5f6545f0Christopher Ferris string = &memory[pagesize-i-1]; 209f0b2c68c83e6ced8f988f014bc235393ca231958Christopher Ferris for (size_t j = 0; j < i; j++) { 210fd65a4e22d8afef028b84c018519468a5f6545f0Christopher Ferris other_string[j] = (char)(32 + (j % 96)); 211fd65a4e22d8afef028b84c018519468a5f6545f0Christopher Ferris string[j] = other_string[j]; 212fd65a4e22d8afef028b84c018519468a5f6545f0Christopher Ferris } 213fd65a4e22d8afef028b84c018519468a5f6545f0Christopher Ferris other_string[i] = '\0'; 214fd65a4e22d8afef028b84c018519468a5f6545f0Christopher Ferris string[i] = '\0'; 215fd65a4e22d8afef028b84c018519468a5f6545f0Christopher Ferris 216f0b2c68c83e6ced8f988f014bc235393ca231958Christopher Ferris if (verbose) { 217f0b2c68c83e6ced8f988f014bc235393ca231958Christopher Ferris printf("Testing size %d, strings equal.\n", i); 218f0b2c68c83e6ced8f988f014bc235393ca231958Christopher Ferris } 219fd65a4e22d8afef028b84c018519468a5f6545f0Christopher Ferris if (test_strcmp(other_string, string) != 0) { 220fd65a4e22d8afef028b84c018519468a5f6545f0Christopher Ferris printf(" Failed at size %d, src1 %p, src2 %p\n", i, other_string, string); 221f0b2c68c83e6ced8f988f014bc235393ca231958Christopher Ferris return false; 222f0b2c68c83e6ced8f988f014bc235393ca231958Christopher Ferris } 223f0b2c68c83e6ced8f988f014bc235393ca231958Christopher Ferris 224f0b2c68c83e6ced8f988f014bc235393ca231958Christopher Ferris if (verbose) { 225f0b2c68c83e6ced8f988f014bc235393ca231958Christopher Ferris printf("Testing size %d, strings equal reverse strings.\n", i); 226fd65a4e22d8afef028b84c018519468a5f6545f0Christopher Ferris } 227fd65a4e22d8afef028b84c018519468a5f6545f0Christopher Ferris if (test_strcmp(string, other_string) != 0) { 228fd65a4e22d8afef028b84c018519468a5f6545f0Christopher Ferris printf(" Failed at size %d, src1 %p, src2 %p\n", i, string, other_string); 229f0b2c68c83e6ced8f988f014bc235393ca231958Christopher Ferris return false; 230fd65a4e22d8afef028b84c018519468a5f6545f0Christopher Ferris } 231fd65a4e22d8afef028b84c018519468a5f6545f0Christopher Ferris 232fd65a4e22d8afef028b84c018519468a5f6545f0Christopher Ferris // Now make other_string longer than our protected string. 233fd65a4e22d8afef028b84c018519468a5f6545f0Christopher Ferris other_string[i] = '1'; 234fd65a4e22d8afef028b84c018519468a5f6545f0Christopher Ferris other_string[i+1] = '\0'; 235fd65a4e22d8afef028b84c018519468a5f6545f0Christopher Ferris 236f0b2c68c83e6ced8f988f014bc235393ca231958Christopher Ferris if (verbose) { 237f0b2c68c83e6ced8f988f014bc235393ca231958Christopher Ferris printf("Testing size %d, strings not equal.\n", i); 238f0b2c68c83e6ced8f988f014bc235393ca231958Christopher Ferris } 239fd65a4e22d8afef028b84c018519468a5f6545f0Christopher Ferris if (test_strcmp(other_string, string) == 0) { 240fd65a4e22d8afef028b84c018519468a5f6545f0Christopher Ferris printf(" Failed at size %d, src1 %p, src2 %p\n", i, other_string, string); 241f0b2c68c83e6ced8f988f014bc235393ca231958Christopher Ferris return false; 242f0b2c68c83e6ced8f988f014bc235393ca231958Christopher Ferris } 243f0b2c68c83e6ced8f988f014bc235393ca231958Christopher Ferris 244f0b2c68c83e6ced8f988f014bc235393ca231958Christopher Ferris if (verbose) { 245f0b2c68c83e6ced8f988f014bc235393ca231958Christopher Ferris printf("Testing size %d, strings not equal reverse the strings.\n", i); 246fd65a4e22d8afef028b84c018519468a5f6545f0Christopher Ferris } 247fd65a4e22d8afef028b84c018519468a5f6545f0Christopher Ferris if (test_strcmp(string, other_string) == 0) { 248fd65a4e22d8afef028b84c018519468a5f6545f0Christopher Ferris printf(" Failed at size %d, src1 %p, src2 %p\n", i, string, other_string); 249f0b2c68c83e6ced8f988f014bc235393ca231958Christopher Ferris return false; 250fd65a4e22d8afef028b84c018519468a5f6545f0Christopher Ferris } 251fd65a4e22d8afef028b84c018519468a5f6545f0Christopher Ferris } 252f0b2c68c83e6ced8f988f014bc235393ca231958Christopher Ferris return true; 253fd65a4e22d8afef028b84c018519468a5f6545f0Christopher Ferris} 254fd65a4e22d8afef028b84c018519468a5f6545f0Christopher Ferris 255f0b2c68c83e6ced8f988f014bc235393ca231958Christopher Ferrisbool runStrcmpTest(int (*test_strcmp)(const char *s1, const char *s2), 256f0b2c68c83e6ced8f988f014bc235393ca231958Christopher Ferris bool verbose) { 257fd65a4e22d8afef028b84c018519468a5f6545f0Christopher Ferris // Allocate two large buffers to hold the two strings. 258fd65a4e22d8afef028b84c018519468a5f6545f0Christopher Ferris char *string1 = reinterpret_cast<char*>(malloc(MAX_STRCMP_BUFFER_SIZE+1)); 259fd65a4e22d8afef028b84c018519468a5f6545f0Christopher Ferris char *string2 = reinterpret_cast<char*>(malloc(MAX_STRCMP_BUFFER_SIZE+1)); 260fd65a4e22d8afef028b84c018519468a5f6545f0Christopher Ferris if (string1 == NULL || string2 == NULL) { 261fd65a4e22d8afef028b84c018519468a5f6545f0Christopher Ferris perror("Unable to allocate memory.\n"); 262fd65a4e22d8afef028b84c018519468a5f6545f0Christopher Ferris return false; 263fd65a4e22d8afef028b84c018519468a5f6545f0Christopher Ferris } 264fd65a4e22d8afef028b84c018519468a5f6545f0Christopher Ferris 265fd65a4e22d8afef028b84c018519468a5f6545f0Christopher Ferris // Initialize the strings to be exactly the same. 266fd65a4e22d8afef028b84c018519468a5f6545f0Christopher Ferris for (int i = 0; i < MAX_STRCMP_BUFFER_SIZE; i++) { 267fd65a4e22d8afef028b84c018519468a5f6545f0Christopher Ferris string1[i] = (char)(32 + (i % 96)); 268fd65a4e22d8afef028b84c018519468a5f6545f0Christopher Ferris string2[i] = string1[i]; 269fd65a4e22d8afef028b84c018519468a5f6545f0Christopher Ferris } 270fd65a4e22d8afef028b84c018519468a5f6545f0Christopher Ferris string1[MAX_STRCMP_BUFFER_SIZE] = '\0'; 271fd65a4e22d8afef028b84c018519468a5f6545f0Christopher Ferris string2[MAX_STRCMP_BUFFER_SIZE] = '\0'; 272fd65a4e22d8afef028b84c018519468a5f6545f0Christopher Ferris 273f0b2c68c83e6ced8f988f014bc235393ca231958Christopher Ferris // Check different string alignments. All zeroes indicates that the 274f0b2c68c83e6ced8f988f014bc235393ca231958Christopher Ferris // unmodified malloc values should be used. 275fd65a4e22d8afef028b84c018519468a5f6545f0Christopher Ferris int string_aligns[][4] = { 276f0b2c68c83e6ced8f988f014bc235393ca231958Christopher Ferris // All zeroes to use the values returned from malloc. 277f0b2c68c83e6ced8f988f014bc235393ca231958Christopher Ferris { 0, 0, 0, 0 }, 278f0b2c68c83e6ced8f988f014bc235393ca231958Christopher Ferris 279fd65a4e22d8afef028b84c018519468a5f6545f0Christopher Ferris { 1, 0, 1, 0 }, 280fd65a4e22d8afef028b84c018519468a5f6545f0Christopher Ferris { 2, 0, 2, 0 }, 281fd65a4e22d8afef028b84c018519468a5f6545f0Christopher Ferris { 4, 0, 4, 0 }, 282fd65a4e22d8afef028b84c018519468a5f6545f0Christopher Ferris { 8, 0, 8, 0 }, 283fd65a4e22d8afef028b84c018519468a5f6545f0Christopher Ferris 284fd65a4e22d8afef028b84c018519468a5f6545f0Christopher Ferris { 8, 0, 4, 0 }, 285fd65a4e22d8afef028b84c018519468a5f6545f0Christopher Ferris { 4, 0, 8, 0 }, 286fd65a4e22d8afef028b84c018519468a5f6545f0Christopher Ferris 287fd65a4e22d8afef028b84c018519468a5f6545f0Christopher Ferris { 8, 0, 8, 1 }, 288fd65a4e22d8afef028b84c018519468a5f6545f0Christopher Ferris { 8, 0, 8, 2 }, 289fd65a4e22d8afef028b84c018519468a5f6545f0Christopher Ferris { 8, 0, 8, 3 }, 290fd65a4e22d8afef028b84c018519468a5f6545f0Christopher Ferris { 8, 1, 8, 0 }, 291fd65a4e22d8afef028b84c018519468a5f6545f0Christopher Ferris { 8, 2, 8, 0 }, 292fd65a4e22d8afef028b84c018519468a5f6545f0Christopher Ferris { 8, 3, 8, 0 }, 293fd65a4e22d8afef028b84c018519468a5f6545f0Christopher Ferris 294fd65a4e22d8afef028b84c018519468a5f6545f0Christopher Ferris { 4, 0, 4, 1 }, 295fd65a4e22d8afef028b84c018519468a5f6545f0Christopher Ferris { 4, 0, 4, 2 }, 296fd65a4e22d8afef028b84c018519468a5f6545f0Christopher Ferris { 4, 0, 4, 3 }, 297fd65a4e22d8afef028b84c018519468a5f6545f0Christopher Ferris { 4, 1, 4, 0 }, 298fd65a4e22d8afef028b84c018519468a5f6545f0Christopher Ferris { 4, 2, 4, 0 }, 299fd65a4e22d8afef028b84c018519468a5f6545f0Christopher Ferris { 4, 3, 4, 0 }, 300fd65a4e22d8afef028b84c018519468a5f6545f0Christopher Ferris }; 301fd65a4e22d8afef028b84c018519468a5f6545f0Christopher Ferris 302fd65a4e22d8afef028b84c018519468a5f6545f0Christopher Ferris printf(" Verifying equal sized strings at different alignments.\n"); 303fd65a4e22d8afef028b84c018519468a5f6545f0Christopher Ferris for (size_t i = 0; i < sizeof(string_aligns)/sizeof(int[4]); i++) { 304f0b2c68c83e6ced8f988f014bc235393ca231958Christopher Ferris if (!doStrcmpExpectEqual(string1, string2, string_aligns[i], test_strcmp, 305f0b2c68c83e6ced8f988f014bc235393ca231958Christopher Ferris verbose)) { 306f0b2c68c83e6ced8f988f014bc235393ca231958Christopher Ferris return false; 307f0b2c68c83e6ced8f988f014bc235393ca231958Christopher Ferris } 308fd65a4e22d8afef028b84c018519468a5f6545f0Christopher Ferris } 309fd65a4e22d8afef028b84c018519468a5f6545f0Christopher Ferris 310f0b2c68c83e6ced8f988f014bc235393ca231958Christopher Ferris // Test the function finds strings with differences at specific locations. 311fd65a4e22d8afef028b84c018519468a5f6545f0Christopher Ferris int diff_aligns[][2] = { 312fd65a4e22d8afef028b84c018519468a5f6545f0Christopher Ferris { 4, 0 }, 313fd65a4e22d8afef028b84c018519468a5f6545f0Christopher Ferris { 4, 1 }, 314fd65a4e22d8afef028b84c018519468a5f6545f0Christopher Ferris { 4, 2 }, 315fd65a4e22d8afef028b84c018519468a5f6545f0Christopher Ferris { 4, 3 }, 316fd65a4e22d8afef028b84c018519468a5f6545f0Christopher Ferris { 8, 0 }, 317fd65a4e22d8afef028b84c018519468a5f6545f0Christopher Ferris { 8, 1 }, 318fd65a4e22d8afef028b84c018519468a5f6545f0Christopher Ferris { 8, 2 }, 319fd65a4e22d8afef028b84c018519468a5f6545f0Christopher Ferris { 8, 3 }, 320fd65a4e22d8afef028b84c018519468a5f6545f0Christopher Ferris }; 321fd65a4e22d8afef028b84c018519468a5f6545f0Christopher Ferris printf(" Verifying different strings at different alignments.\n"); 322f0b2c68c83e6ced8f988f014bc235393ca231958Christopher Ferris for (size_t i = 0; i < sizeof(diff_aligns)/sizeof(int[2]); i++) { 323fd65a4e22d8afef028b84c018519468a5f6545f0Christopher Ferris // First loop put the string terminator at the chosen alignment. 324f0b2c68c83e6ced8f988f014bc235393ca231958Christopher Ferris for (size_t j = 0; j < sizeof(string_aligns)/sizeof(int[4]); j++) { 325f0b2c68c83e6ced8f988f014bc235393ca231958Christopher Ferris if (!doStrcmpExpectDiff(string1, string2, diff_aligns[i], 326f0b2c68c83e6ced8f988f014bc235393ca231958Christopher Ferris string_aligns[j], '\0', test_strcmp, verbose)) { 327f0b2c68c83e6ced8f988f014bc235393ca231958Christopher Ferris return false; 328f0b2c68c83e6ced8f988f014bc235393ca231958Christopher Ferris } 329fd65a4e22d8afef028b84c018519468a5f6545f0Christopher Ferris } 330fd65a4e22d8afef028b84c018519468a5f6545f0Christopher Ferris // Second loop put a different character at the chosen alignment. 331fd65a4e22d8afef028b84c018519468a5f6545f0Christopher Ferris // This character is guaranteed not to be in the original string. 332f0b2c68c83e6ced8f988f014bc235393ca231958Christopher Ferris for (size_t j = 0; j < sizeof(string_aligns)/sizeof(int[4]); j++) { 333f0b2c68c83e6ced8f988f014bc235393ca231958Christopher Ferris if (!doStrcmpExpectDiff(string1, string2, diff_aligns[i], 334f0b2c68c83e6ced8f988f014bc235393ca231958Christopher Ferris string_aligns[j], '\0', test_strcmp, verbose)) { 335f0b2c68c83e6ced8f988f014bc235393ca231958Christopher Ferris return false; 336f0b2c68c83e6ced8f988f014bc235393ca231958Christopher Ferris } 337fd65a4e22d8afef028b84c018519468a5f6545f0Christopher Ferris } 338fd65a4e22d8afef028b84c018519468a5f6545f0Christopher Ferris } 339fd65a4e22d8afef028b84c018519468a5f6545f0Christopher Ferris 340fd65a4e22d8afef028b84c018519468a5f6545f0Christopher Ferris printf(" Verifying strcmp does not read too many bytes.\n"); 341f0b2c68c83e6ced8f988f014bc235393ca231958Christopher Ferris if (!doStrcmpCheckRead(test_strcmp, verbose)) { 342f0b2c68c83e6ced8f988f014bc235393ca231958Christopher Ferris return false; 343fd65a4e22d8afef028b84c018519468a5f6545f0Christopher Ferris } 344fd65a4e22d8afef028b84c018519468a5f6545f0Christopher Ferris 345f0b2c68c83e6ced8f988f014bc235393ca231958Christopher Ferris printf(" All tests pass.\n"); 346f0b2c68c83e6ced8f988f014bc235393ca231958Christopher Ferris 347f0b2c68c83e6ced8f988f014bc235393ca231958Christopher Ferris return true; 348fd65a4e22d8afef028b84c018519468a5f6545f0Christopher Ferris} 349fd65a4e22d8afef028b84c018519468a5f6545f0Christopher Ferris 350f0b2c68c83e6ced8f988f014bc235393ca231958Christopher Ferrisbool runMemcpyTest(void* (*test_memcpy)(void *dst, const void *src, size_t n), 351f0b2c68c83e6ced8f988f014bc235393ca231958Christopher Ferris bool verbose) { 352fd65a4e22d8afef028b84c018519468a5f6545f0Christopher Ferris // Allocate two large buffers to hold the dst and src. 353fd65a4e22d8afef028b84c018519468a5f6545f0Christopher Ferris uint8_t *dst = reinterpret_cast<uint8_t*>(malloc(MAX_MEMCPY_BUFFER_SIZE)); 354fd65a4e22d8afef028b84c018519468a5f6545f0Christopher Ferris uint8_t *src = reinterpret_cast<uint8_t*>(malloc(MAX_MEMCPY_BUFFER_SIZE)); 355fd65a4e22d8afef028b84c018519468a5f6545f0Christopher Ferris if (dst == NULL || src == NULL) { 356fd65a4e22d8afef028b84c018519468a5f6545f0Christopher Ferris perror("Unable to allocate memory.\n"); 357fd65a4e22d8afef028b84c018519468a5f6545f0Christopher Ferris return false; 358fd65a4e22d8afef028b84c018519468a5f6545f0Christopher Ferris } 359fd65a4e22d8afef028b84c018519468a5f6545f0Christopher Ferris 360f0b2c68c83e6ced8f988f014bc235393ca231958Christopher Ferris // Set the source to a known pattern once. The assumption is that the 361f0b2c68c83e6ced8f988f014bc235393ca231958Christopher Ferris // memcpy is not so broken that it will write in to the source buffer. 362f0b2c68c83e6ced8f988f014bc235393ca231958Christopher Ferris // However, do not write zeroes into the source so a very quick can be 363f0b2c68c83e6ced8f988f014bc235393ca231958Christopher Ferris // made to verify the source has not been modified. 364fd65a4e22d8afef028b84c018519468a5f6545f0Christopher Ferris for (int i = 0; i < MAX_MEMCPY_BUFFER_SIZE; i++) { 365fd65a4e22d8afef028b84c018519468a5f6545f0Christopher Ferris src[i] = i % 256; 366fd65a4e22d8afef028b84c018519468a5f6545f0Christopher Ferris if (src[i] == 0) { 367fd65a4e22d8afef028b84c018519468a5f6545f0Christopher Ferris src[i] = 0xaa; 368fd65a4e22d8afef028b84c018519468a5f6545f0Christopher Ferris } 369fd65a4e22d8afef028b84c018519468a5f6545f0Christopher Ferris } 370fd65a4e22d8afef028b84c018519468a5f6545f0Christopher Ferris 371fd65a4e22d8afef028b84c018519468a5f6545f0Christopher Ferris int aligns[][4] = { 372f0b2c68c83e6ced8f988f014bc235393ca231958Christopher Ferris // Src and dst use pointers returned by malloc. 373f0b2c68c83e6ced8f988f014bc235393ca231958Christopher Ferris { 0, 0, 0, 0 }, 374f0b2c68c83e6ced8f988f014bc235393ca231958Christopher Ferris 375f0b2c68c83e6ced8f988f014bc235393ca231958Christopher Ferris // Src and dst at same alignment. 376fd65a4e22d8afef028b84c018519468a5f6545f0Christopher Ferris { 1, 0, 1, 0 }, 377fd65a4e22d8afef028b84c018519468a5f6545f0Christopher Ferris { 2, 0, 2, 0 }, 378fd65a4e22d8afef028b84c018519468a5f6545f0Christopher Ferris { 4, 0, 4, 0 }, 379fd65a4e22d8afef028b84c018519468a5f6545f0Christopher Ferris { 8, 0, 8, 0 }, 380fd65a4e22d8afef028b84c018519468a5f6545f0Christopher Ferris { 16, 0, 16, 0 }, 381fd65a4e22d8afef028b84c018519468a5f6545f0Christopher Ferris { 32, 0, 32, 0 }, 382fd65a4e22d8afef028b84c018519468a5f6545f0Christopher Ferris { 64, 0, 64, 0 }, 383fd65a4e22d8afef028b84c018519468a5f6545f0Christopher Ferris { 128, 0, 128, 0 }, 384fd65a4e22d8afef028b84c018519468a5f6545f0Christopher Ferris 385fd65a4e22d8afef028b84c018519468a5f6545f0Christopher Ferris // Different alignments between src and dst. 386fd65a4e22d8afef028b84c018519468a5f6545f0Christopher Ferris { 8, 0, 4, 0 }, 387fd65a4e22d8afef028b84c018519468a5f6545f0Christopher Ferris { 4, 0, 8, 0 }, 388fd65a4e22d8afef028b84c018519468a5f6545f0Christopher Ferris { 16, 0, 4, 0 }, 389fd65a4e22d8afef028b84c018519468a5f6545f0Christopher Ferris { 4, 0, 16, 0 }, 390fd65a4e22d8afef028b84c018519468a5f6545f0Christopher Ferris 391fd65a4e22d8afef028b84c018519468a5f6545f0Christopher Ferris // General unaligned cases. 392fd65a4e22d8afef028b84c018519468a5f6545f0Christopher Ferris { 4, 0, 4, 1 }, 393fd65a4e22d8afef028b84c018519468a5f6545f0Christopher Ferris { 4, 0, 4, 2 }, 394fd65a4e22d8afef028b84c018519468a5f6545f0Christopher Ferris { 4, 0, 4, 3 }, 395fd65a4e22d8afef028b84c018519468a5f6545f0Christopher Ferris { 4, 1, 4, 0 }, 396fd65a4e22d8afef028b84c018519468a5f6545f0Christopher Ferris { 4, 2, 4, 0 }, 397fd65a4e22d8afef028b84c018519468a5f6545f0Christopher Ferris { 4, 3, 4, 0 }, 398fd65a4e22d8afef028b84c018519468a5f6545f0Christopher Ferris 399fd65a4e22d8afef028b84c018519468a5f6545f0Christopher Ferris // All non-word aligned cases. 400fd65a4e22d8afef028b84c018519468a5f6545f0Christopher Ferris { 4, 1, 4, 0 }, 401fd65a4e22d8afef028b84c018519468a5f6545f0Christopher Ferris { 4, 1, 4, 1 }, 402fd65a4e22d8afef028b84c018519468a5f6545f0Christopher Ferris { 4, 1, 4, 2 }, 403fd65a4e22d8afef028b84c018519468a5f6545f0Christopher Ferris { 4, 1, 4, 3 }, 404fd65a4e22d8afef028b84c018519468a5f6545f0Christopher Ferris 405fd65a4e22d8afef028b84c018519468a5f6545f0Christopher Ferris { 4, 2, 4, 0 }, 406fd65a4e22d8afef028b84c018519468a5f6545f0Christopher Ferris { 4, 2, 4, 1 }, 407fd65a4e22d8afef028b84c018519468a5f6545f0Christopher Ferris { 4, 2, 4, 2 }, 408fd65a4e22d8afef028b84c018519468a5f6545f0Christopher Ferris { 4, 2, 4, 3 }, 409fd65a4e22d8afef028b84c018519468a5f6545f0Christopher Ferris 410fd65a4e22d8afef028b84c018519468a5f6545f0Christopher Ferris { 4, 3, 4, 0 }, 411fd65a4e22d8afef028b84c018519468a5f6545f0Christopher Ferris { 4, 3, 4, 1 }, 412fd65a4e22d8afef028b84c018519468a5f6545f0Christopher Ferris { 4, 3, 4, 2 }, 413fd65a4e22d8afef028b84c018519468a5f6545f0Christopher Ferris { 4, 3, 4, 3 }, 414fd65a4e22d8afef028b84c018519468a5f6545f0Christopher Ferris 415fd65a4e22d8afef028b84c018519468a5f6545f0Christopher Ferris { 2, 0, 4, 0 }, 416fd65a4e22d8afef028b84c018519468a5f6545f0Christopher Ferris { 4, 0, 2, 0 }, 417fd65a4e22d8afef028b84c018519468a5f6545f0Christopher Ferris { 2, 0, 2, 0 }, 418fd65a4e22d8afef028b84c018519468a5f6545f0Christopher Ferris 419fd65a4e22d8afef028b84c018519468a5f6545f0Christopher Ferris // Invoke the unaligned case where the code needs to align dst to 0x10. 420fd65a4e22d8afef028b84c018519468a5f6545f0Christopher Ferris { 128, 1, 128, 4 }, 421fd65a4e22d8afef028b84c018519468a5f6545f0Christopher Ferris { 128, 1, 128, 8 }, 422fd65a4e22d8afef028b84c018519468a5f6545f0Christopher Ferris { 128, 1, 128, 12 }, 423fd65a4e22d8afef028b84c018519468a5f6545f0Christopher Ferris { 128, 1, 128, 16 }, 424fd65a4e22d8afef028b84c018519468a5f6545f0Christopher Ferris }; 425fd65a4e22d8afef028b84c018519468a5f6545f0Christopher Ferris 426fd65a4e22d8afef028b84c018519468a5f6545f0Christopher Ferris printf(" Verifying variable sized copies at different alignments.\n"); 427fd65a4e22d8afef028b84c018519468a5f6545f0Christopher Ferris uint8_t *src_align, *dst_align; 428fd65a4e22d8afef028b84c018519468a5f6545f0Christopher Ferris for (size_t i = 0; i < sizeof(aligns)/sizeof(int[4]); i++) { 429f0b2c68c83e6ced8f988f014bc235393ca231958Christopher Ferris for (size_t len = 0; len <= MAX_MEMCPY_TEST_SIZE; len++) { 430f0b2c68c83e6ced8f988f014bc235393ca231958Christopher Ferris if (aligns[i][0]) { 431f0b2c68c83e6ced8f988f014bc235393ca231958Christopher Ferris src_align = (uint8_t*)getAlignedPtr(src+FENCEPOST_LENGTH, aligns[i][0], 432f0b2c68c83e6ced8f988f014bc235393ca231958Christopher Ferris aligns[i][1]); 433f0b2c68c83e6ced8f988f014bc235393ca231958Christopher Ferris dst_align = (uint8_t*)getAlignedPtr(dst+FENCEPOST_LENGTH, aligns[i][2], 434f0b2c68c83e6ced8f988f014bc235393ca231958Christopher Ferris aligns[i][3]); 435f0b2c68c83e6ced8f988f014bc235393ca231958Christopher Ferris } else { 436f0b2c68c83e6ced8f988f014bc235393ca231958Christopher Ferris src_align = src; 437f0b2c68c83e6ced8f988f014bc235393ca231958Christopher Ferris dst_align = dst; 438f0b2c68c83e6ced8f988f014bc235393ca231958Christopher Ferris } 439f0b2c68c83e6ced8f988f014bc235393ca231958Christopher Ferris 440f0b2c68c83e6ced8f988f014bc235393ca231958Christopher Ferris if (verbose) { 441f0b2c68c83e6ced8f988f014bc235393ca231958Christopher Ferris printf("Testing size %d, src_align=%p[%d,%d], dst_align=%p[%d,%d]\n", 442f0b2c68c83e6ced8f988f014bc235393ca231958Christopher Ferris len, src_align, aligns[i][0], aligns[i][1], 443f0b2c68c83e6ced8f988f014bc235393ca231958Christopher Ferris dst_align, aligns[i][2], aligns[i][3]); 444f0b2c68c83e6ced8f988f014bc235393ca231958Christopher Ferris } 445f0b2c68c83e6ced8f988f014bc235393ca231958Christopher Ferris 446fd65a4e22d8afef028b84c018519468a5f6545f0Christopher Ferris memset(dst_align, 0, len); 447f0b2c68c83e6ced8f988f014bc235393ca231958Christopher Ferris 448f0b2c68c83e6ced8f988f014bc235393ca231958Christopher Ferris // Don't add a pre fencepost if we are using the value from the malloc. 449f0b2c68c83e6ced8f988f014bc235393ca231958Christopher Ferris if (dst_align != dst) { 4501685d00d0a6b905a820a76c9686b6b4b077dfe4aChristopher Ferris setFencepost(&dst_align[-8]); 451f0b2c68c83e6ced8f988f014bc235393ca231958Christopher Ferris } 452f0b2c68c83e6ced8f988f014bc235393ca231958Christopher Ferris setFencepost(&dst_align[len]); 453fd65a4e22d8afef028b84c018519468a5f6545f0Christopher Ferris 454fd65a4e22d8afef028b84c018519468a5f6545f0Christopher Ferris test_memcpy(dst_align, src_align, len); 455fd65a4e22d8afef028b84c018519468a5f6545f0Christopher Ferris 456f0b2c68c83e6ced8f988f014bc235393ca231958Christopher Ferris for (size_t j = 0; j < len; j++) { 457fd65a4e22d8afef028b84c018519468a5f6545f0Christopher Ferris if (dst_align[j] != src_align[j] || !src_align[j]) { 458fd65a4e22d8afef028b84c018519468a5f6545f0Christopher Ferris if (!src_align[j]) { 459fd65a4e22d8afef028b84c018519468a5f6545f0Christopher Ferris printf(" src_align[%d] is 0, memcpy wrote into the source.\n", j); 460f0b2c68c83e6ced8f988f014bc235393ca231958Christopher Ferris } else { 461f0b2c68c83e6ced8f988f014bc235393ca231958Christopher Ferris printf(" mismatch at %d, expected %d found %d\n", j, 462f0b2c68c83e6ced8f988f014bc235393ca231958Christopher Ferris src_align[j], dst_align[j]); 463fd65a4e22d8afef028b84c018519468a5f6545f0Christopher Ferris } 464fd65a4e22d8afef028b84c018519468a5f6545f0Christopher Ferris printf(" Failed at size %d, src_align=%p[%d,%d], dst_align=%p[%d,%d]\n", 465fd65a4e22d8afef028b84c018519468a5f6545f0Christopher Ferris len, src_align, aligns[i][0], aligns[i][1], 466fd65a4e22d8afef028b84c018519468a5f6545f0Christopher Ferris dst_align, aligns[i][2], aligns[i][3]); 467f0b2c68c83e6ced8f988f014bc235393ca231958Christopher Ferris return false; 468fd65a4e22d8afef028b84c018519468a5f6545f0Christopher Ferris } 469fd65a4e22d8afef028b84c018519468a5f6545f0Christopher Ferris } 470f0b2c68c83e6ced8f988f014bc235393ca231958Christopher Ferris if (dst_align != dst && !verifyFencepost(&dst_align[-8])) { 471f0b2c68c83e6ced8f988f014bc235393ca231958Christopher Ferris printf(" wrote before the array.\n"); 472f0b2c68c83e6ced8f988f014bc235393ca231958Christopher Ferris printf(" Failed at size %d, src_align=%p[%d,%d], dst_align=%p[%d,%d]\n", 473fd65a4e22d8afef028b84c018519468a5f6545f0Christopher Ferris len, src_align, aligns[i][0], aligns[i][1], 474f0b2c68c83e6ced8f988f014bc235393ca231958Christopher Ferris dst_align, aligns[i][2], aligns[i][3]); 475f0b2c68c83e6ced8f988f014bc235393ca231958Christopher Ferris return false; 476f0b2c68c83e6ced8f988f014bc235393ca231958Christopher Ferris } 477f0b2c68c83e6ced8f988f014bc235393ca231958Christopher Ferris if (!verifyFencepost(&dst_align[len])) { 478f0b2c68c83e6ced8f988f014bc235393ca231958Christopher Ferris printf(" wrote past the end of the array.\n"); 479f0b2c68c83e6ced8f988f014bc235393ca231958Christopher Ferris printf(" Failed at size %d, src_align=%p[%d,%d], dst_align=%p[%d,%d]\n", 480f0b2c68c83e6ced8f988f014bc235393ca231958Christopher Ferris len, src_align, aligns[i][0], aligns[i][1], 481f0b2c68c83e6ced8f988f014bc235393ca231958Christopher Ferris dst_align, aligns[i][2], aligns[i][3]); 482f0b2c68c83e6ced8f988f014bc235393ca231958Christopher Ferris return false; 483fd65a4e22d8afef028b84c018519468a5f6545f0Christopher Ferris } 484fd65a4e22d8afef028b84c018519468a5f6545f0Christopher Ferris } 485fd65a4e22d8afef028b84c018519468a5f6545f0Christopher Ferris } 486fd65a4e22d8afef028b84c018519468a5f6545f0Christopher Ferris 487f0b2c68c83e6ced8f988f014bc235393ca231958Christopher Ferris printf(" All tests pass.\n"); 488fd65a4e22d8afef028b84c018519468a5f6545f0Christopher Ferris 489f0b2c68c83e6ced8f988f014bc235393ca231958Christopher Ferris return true; 490fd65a4e22d8afef028b84c018519468a5f6545f0Christopher Ferris} 491fd65a4e22d8afef028b84c018519468a5f6545f0Christopher Ferris 492f0b2c68c83e6ced8f988f014bc235393ca231958Christopher Ferrisbool runMemsetTest(void* (*test_memset)(void *s, int c, size_t n), 493f0b2c68c83e6ced8f988f014bc235393ca231958Christopher Ferris bool verbose) { 494cd0530e6b72ed9ff4c38f15feea0f231c710af1fChristopher Ferris // Allocate one large buffer to hold the dst. 495cd0530e6b72ed9ff4c38f15feea0f231c710af1fChristopher Ferris uint8_t *buf = reinterpret_cast<uint8_t*>(malloc(MAX_MEMSET_BUFFER_SIZE)); 496cd0530e6b72ed9ff4c38f15feea0f231c710af1fChristopher Ferris if (buf == NULL) { 497cd0530e6b72ed9ff4c38f15feea0f231c710af1fChristopher Ferris perror("Unable to allocate memory.\n"); 498cd0530e6b72ed9ff4c38f15feea0f231c710af1fChristopher Ferris return false; 499cd0530e6b72ed9ff4c38f15feea0f231c710af1fChristopher Ferris } 500cd0530e6b72ed9ff4c38f15feea0f231c710af1fChristopher Ferris 501cd0530e6b72ed9ff4c38f15feea0f231c710af1fChristopher Ferris int aligns[][2] = { 502f0b2c68c83e6ced8f988f014bc235393ca231958Christopher Ferris // Use malloc return values unaltered. 503f0b2c68c83e6ced8f988f014bc235393ca231958Christopher Ferris { 0, 0 }, 504f0b2c68c83e6ced8f988f014bc235393ca231958Christopher Ferris 505cd0530e6b72ed9ff4c38f15feea0f231c710af1fChristopher Ferris // Different alignments. 506cd0530e6b72ed9ff4c38f15feea0f231c710af1fChristopher Ferris { 1, 0 }, 507cd0530e6b72ed9ff4c38f15feea0f231c710af1fChristopher Ferris { 2, 0 }, 508cd0530e6b72ed9ff4c38f15feea0f231c710af1fChristopher Ferris { 4, 0 }, 509cd0530e6b72ed9ff4c38f15feea0f231c710af1fChristopher Ferris { 8, 0 }, 510cd0530e6b72ed9ff4c38f15feea0f231c710af1fChristopher Ferris { 16, 0 }, 511cd0530e6b72ed9ff4c38f15feea0f231c710af1fChristopher Ferris { 32, 0 }, 512cd0530e6b72ed9ff4c38f15feea0f231c710af1fChristopher Ferris { 64, 0 }, 513cd0530e6b72ed9ff4c38f15feea0f231c710af1fChristopher Ferris 514cd0530e6b72ed9ff4c38f15feea0f231c710af1fChristopher Ferris // Different alignments between src and dst. 515cd0530e6b72ed9ff4c38f15feea0f231c710af1fChristopher Ferris { 8, 1 }, 516cd0530e6b72ed9ff4c38f15feea0f231c710af1fChristopher Ferris { 8, 2 }, 517cd0530e6b72ed9ff4c38f15feea0f231c710af1fChristopher Ferris { 8, 3 }, 518cd0530e6b72ed9ff4c38f15feea0f231c710af1fChristopher Ferris { 8, 4 }, 519cd0530e6b72ed9ff4c38f15feea0f231c710af1fChristopher Ferris { 8, 5 }, 520cd0530e6b72ed9ff4c38f15feea0f231c710af1fChristopher Ferris { 8, 6 }, 521cd0530e6b72ed9ff4c38f15feea0f231c710af1fChristopher Ferris { 8, 7 }, 522cd0530e6b72ed9ff4c38f15feea0f231c710af1fChristopher Ferris }; 523cd0530e6b72ed9ff4c38f15feea0f231c710af1fChristopher Ferris 524cd0530e6b72ed9ff4c38f15feea0f231c710af1fChristopher Ferris printf(" Verifying variable sized memsets at different alignments.\n"); 525cd0530e6b72ed9ff4c38f15feea0f231c710af1fChristopher Ferris uint8_t *buf_align; 526cd0530e6b72ed9ff4c38f15feea0f231c710af1fChristopher Ferris for (size_t i = 0; i < sizeof(aligns)/sizeof(int[2]); i++) { 527f0b2c68c83e6ced8f988f014bc235393ca231958Christopher Ferris for (size_t len = 0; len <= MAX_MEMSET_TEST_SIZE; len++) { 528f0b2c68c83e6ced8f988f014bc235393ca231958Christopher Ferris if (aligns[i]) { 529f0b2c68c83e6ced8f988f014bc235393ca231958Christopher Ferris buf_align = (uint8_t*)getAlignedPtr(buf+FENCEPOST_LENGTH, aligns[i][0], 530f0b2c68c83e6ced8f988f014bc235393ca231958Christopher Ferris aligns[i][1]); 531f0b2c68c83e6ced8f988f014bc235393ca231958Christopher Ferris } else { 532f0b2c68c83e6ced8f988f014bc235393ca231958Christopher Ferris buf_align = buf; 533f0b2c68c83e6ced8f988f014bc235393ca231958Christopher Ferris } 534f0b2c68c83e6ced8f988f014bc235393ca231958Christopher Ferris 535f0b2c68c83e6ced8f988f014bc235393ca231958Christopher Ferris if (verbose) { 536f0b2c68c83e6ced8f988f014bc235393ca231958Christopher Ferris printf("Testing size %d, buf_align=%p[%d,%d]\n", 537f0b2c68c83e6ced8f988f014bc235393ca231958Christopher Ferris len, buf_align, aligns[i][0], aligns[i][1]); 538f0b2c68c83e6ced8f988f014bc235393ca231958Christopher Ferris } 539cd0530e6b72ed9ff4c38f15feea0f231c710af1fChristopher Ferris 540cd0530e6b72ed9ff4c38f15feea0f231c710af1fChristopher Ferris // Set the buffer to all zero without memset since it might be the 541cd0530e6b72ed9ff4c38f15feea0f231c710af1fChristopher Ferris // function we are testing. 542f0b2c68c83e6ced8f988f014bc235393ca231958Christopher Ferris for (size_t j = 0; j < len; j++) { 543cd0530e6b72ed9ff4c38f15feea0f231c710af1fChristopher Ferris buf_align[j] = 0; 544cd0530e6b72ed9ff4c38f15feea0f231c710af1fChristopher Ferris } 545cd0530e6b72ed9ff4c38f15feea0f231c710af1fChristopher Ferris 546f0b2c68c83e6ced8f988f014bc235393ca231958Christopher Ferris // Don't add a pre fencepost if we are using the value from the malloc. 547f0b2c68c83e6ced8f988f014bc235393ca231958Christopher Ferris if (buf_align != buf) { 5481685d00d0a6b905a820a76c9686b6b4b077dfe4aChristopher Ferris setFencepost(&buf_align[-8]); 549f0b2c68c83e6ced8f988f014bc235393ca231958Christopher Ferris } 550f0b2c68c83e6ced8f988f014bc235393ca231958Christopher Ferris setFencepost(&buf_align[len]); 551f0b2c68c83e6ced8f988f014bc235393ca231958Christopher Ferris 552f0b2c68c83e6ced8f988f014bc235393ca231958Christopher Ferris int value = (len % 255) + 1; 553cd0530e6b72ed9ff4c38f15feea0f231c710af1fChristopher Ferris test_memset(buf_align, value, len); 554cd0530e6b72ed9ff4c38f15feea0f231c710af1fChristopher Ferris 555f0b2c68c83e6ced8f988f014bc235393ca231958Christopher Ferris for (size_t j = 0; j < len; j++) { 556cd0530e6b72ed9ff4c38f15feea0f231c710af1fChristopher Ferris if (buf_align[j] != value) { 557cd0530e6b72ed9ff4c38f15feea0f231c710af1fChristopher Ferris printf(" Failed at size %d[%d,%d!=%d], buf_align=%p[%d,%d]\n", 558cd0530e6b72ed9ff4c38f15feea0f231c710af1fChristopher Ferris len, j, buf_align[j], value, buf_align, aligns[i][0], 559cd0530e6b72ed9ff4c38f15feea0f231c710af1fChristopher Ferris aligns[i][1]); 560f0b2c68c83e6ced8f988f014bc235393ca231958Christopher Ferris return false; 561cd0530e6b72ed9ff4c38f15feea0f231c710af1fChristopher Ferris } 562cd0530e6b72ed9ff4c38f15feea0f231c710af1fChristopher Ferris } 563f0b2c68c83e6ced8f988f014bc235393ca231958Christopher Ferris if (buf_align != buf && !verifyFencepost(&buf_align[-8])) { 564f0b2c68c83e6ced8f988f014bc235393ca231958Christopher Ferris printf(" wrote before the beginning of the array.\n"); 565f0b2c68c83e6ced8f988f014bc235393ca231958Christopher Ferris printf(" Failed at size %d, buf_align=%p[%d,%d]\n", 566f0b2c68c83e6ced8f988f014bc235393ca231958Christopher Ferris len, buf_align, aligns[i][0], aligns[i][1]); 567f0b2c68c83e6ced8f988f014bc235393ca231958Christopher Ferris return false; 568f0b2c68c83e6ced8f988f014bc235393ca231958Christopher Ferris } 569f0b2c68c83e6ced8f988f014bc235393ca231958Christopher Ferris if (!verifyFencepost(&buf_align[len])) { 570f0b2c68c83e6ced8f988f014bc235393ca231958Christopher Ferris printf(" wrote after the end of the array.\n"); 571cd0530e6b72ed9ff4c38f15feea0f231c710af1fChristopher Ferris printf(" Failed at size %d, buf_align=%p[%d,%d]\n", 572cd0530e6b72ed9ff4c38f15feea0f231c710af1fChristopher Ferris len, buf_align, aligns[i][0], aligns[i][1]); 573f0b2c68c83e6ced8f988f014bc235393ca231958Christopher Ferris return false; 574cd0530e6b72ed9ff4c38f15feea0f231c710af1fChristopher Ferris } 575cd0530e6b72ed9ff4c38f15feea0f231c710af1fChristopher Ferris } 576cd0530e6b72ed9ff4c38f15feea0f231c710af1fChristopher Ferris } 577cd0530e6b72ed9ff4c38f15feea0f231c710af1fChristopher Ferris 578f0b2c68c83e6ced8f988f014bc235393ca231958Christopher Ferris printf(" All tests pass.\n"); 579cd0530e6b72ed9ff4c38f15feea0f231c710af1fChristopher Ferris 580f0b2c68c83e6ced8f988f014bc235393ca231958Christopher Ferris return true; 581cd0530e6b72ed9ff4c38f15feea0f231c710af1fChristopher Ferris} 582cd0530e6b72ed9ff4c38f15feea0f231c710af1fChristopher Ferris 583fd65a4e22d8afef028b84c018519468a5f6545f0Christopher Ferrisint main(int argc, char **argv) { 584f0b2c68c83e6ced8f988f014bc235393ca231958Christopher Ferris bool verbose = false; 585f0b2c68c83e6ced8f988f014bc235393ca231958Christopher Ferris if (argc == 2 && strcmp(argv[1], "-v") == 0) { 586f0b2c68c83e6ced8f988f014bc235393ca231958Christopher Ferris verbose = true; 587f0b2c68c83e6ced8f988f014bc235393ca231958Christopher Ferris } 588fd65a4e22d8afef028b84c018519468a5f6545f0Christopher Ferris 589f0b2c68c83e6ced8f988f014bc235393ca231958Christopher Ferris bool tests_passing = true; 590fd65a4e22d8afef028b84c018519468a5f6545f0Christopher Ferris printf("Testing strcmp...\n"); 591f0b2c68c83e6ced8f988f014bc235393ca231958Christopher Ferris tests_passing = runStrcmpTest(strcmp, verbose) && tests_passing; 592fd65a4e22d8afef028b84c018519468a5f6545f0Christopher Ferris 593fd65a4e22d8afef028b84c018519468a5f6545f0Christopher Ferris printf("Testing memcpy...\n"); 594f0b2c68c83e6ced8f988f014bc235393ca231958Christopher Ferris tests_passing = runMemcpyTest(memcpy, verbose) && tests_passing; 595fd65a4e22d8afef028b84c018519468a5f6545f0Christopher Ferris 596cd0530e6b72ed9ff4c38f15feea0f231c710af1fChristopher Ferris printf("Testing memset...\n"); 597f0b2c68c83e6ced8f988f014bc235393ca231958Christopher Ferris tests_passing = runMemsetTest(memset, verbose) && tests_passing; 598cd0530e6b72ed9ff4c38f15feea0f231c710af1fChristopher Ferris 599fd65a4e22d8afef028b84c018519468a5f6545f0Christopher Ferris return (tests_passing ? 0 : 1); 600fd65a4e22d8afef028b84c018519468a5f6545f0Christopher Ferris} 601