📄 memory.c
字号:
l = __mp_roundup(l + ((char *) p - (char *) t), i->page);#if TARGET == TARGET_UNIX if (a == MA_NOACCESS) n = PROT_NONE; else if (a == MA_READONLY) n = PROT_READ; else n = PROT_READ | PROT_WRITE; if (mprotect(t, l, n) == -1) return 0;#elif TARGET == TARGET_WINDOWS if (a == MA_NOACCESS) n = PAGE_NOACCESS; else if (a == MA_READONLY) n = PAGE_READONLY; else n = PAGE_READWRITE; if (!VirtualProtect(t, l, n, (unsigned long *) &n)) return 0;#endif /* TARGET */#endif /* TARGET */ return 1;}/* Notify the operating system to watch a specified group of bytes with the * supplied access permission. */MP_GLOBALint__mp_memwatch(meminfo *i, void *p, size_t l, memaccess a){#if MP_WATCH_SUPPORT watchcmd w;#endif /* MP_WATCH_SUPPORT */#if MP_WATCH_SUPPORT if (l == 0) return 1;#if SYSTEM == SYSTEM_SOLARIS w.cmd = PCWATCH; w.data.pr_vaddr = (uintptr_t) p; w.data.pr_size = l; if (a == MA_NOACCESS) w.data.pr_wflags = WA_READ | WA_WRITE | WA_TRAPAFTER; else if (a == MA_READONLY) w.data.pr_wflags = WA_WRITE | WA_TRAPAFTER; else w.data.pr_wflags = 0; if ((i->wfile == -1) || (write(i->wfile, (void *) &w, sizeof(watchcmd)) != sizeof(watchcmd))) return 0;#else /* SYSTEM */ w.cmd = PIOCSWATCH; w.data.pr_vaddr = (caddr_t) p; if (a == MA_NOACCESS) { w.data.pr_size = l; w.data.pr_wflags = MA_READ | MA_WRITE; } else if (a == MA_READONLY) { w.data.pr_size = l; w.data.pr_wflags = MA_WRITE; } else { w.data.pr_size = 0; w.data.pr_wflags = 0; } if ((i->wfile == -1) || (ioctl(i->wfile, w.cmd, &w.data) == -1)) return 0;#endif /* SYSTEM */#endif /* MP_WATCH_SUPPORT */ return 1;}/* Check that a block of memory only contains a specific byte. */MP_GLOBALvoid *__mp_memcheck(void *t, char c, size_t l){ long *w; char *p; size_t i, n; long b; /* This used to be a simple loop to compare each byte individually, but * that is less efficient than attempting to compare words at a time. * Therefore, if the number of bytes to compare is larger than a certain * number then this routine will attempt to compare as many words as * possible. */ if (l > sizeof(long) * sizeof(long)) { /* Check all bytes that occur before the first word. */ if ((n = (unsigned long) t & (sizeof(long) - 1)) > 0) { if ((n = sizeof(long) - n) > l) n = l; for (p = (char *) t, t = (char *) t + n; p < (char *) t; p++) if (*p != c) return p; l -= n; } if (l == 0) return NULL; /* Check all words that occur in the memory block. */ if ((n = l / sizeof(long)) > 0) { /* Build up the word that we will be checking against. */ for (p = (char *) &b, i = 0; i < sizeof(long); p++, i++) *p = c; for (w = (long *) t, t = (long *) t + n; w < (long *) t; w++) if (*w != b) { /* Locate the exact byte that caused the test to fail. */ for (p = (char *) w, i = 0; i < sizeof(long); p++, i++) if (*p != c) return p; /* The above loop should never exit, but just in case it * does, return the address of the word that caused the test * to fail. */ return w; } l -= n * sizeof(long); } } if (l == 0) return NULL; /* Check all remaining bytes. */ for (p = (char *) t, t = (char *) t + l; p < (char *) t; p++) if (*p != c) return p; return NULL;}/* Compare two blocks of memory. */MP_GLOBALvoid *__mp_memcompare(void *t, void *s, size_t l){ char *p; size_t n; /* This used to be a simple loop to compare each byte individually, but * that is less efficient than attempting to compare words at a time. * Therefore, if the number of bytes to compare is larger than a certain * number then this routine will attempt to compare as many words as * possible. */ if ((s == t) || (l == 0)) return NULL; n = (unsigned long) s & (sizeof(long) - 1); if ((n == ((unsigned long) t & (sizeof(long) - 1))) && (l > sizeof(long) * sizeof(long))) { /* We can only compare words if the two blocks have the same alignment. * This also guarantees that there is at least one word of difference * between the two pointers. */ if ((n > 0) && ((n = sizeof(long) - n) > l)) n = l; /* Compare all bytes that occur before the first word. */ while (n > 0) { if (*((char *) t) != *((char *) s)) return t; s = (char *) s + 1; t = (char *) t + 1; n--; l--; } /* Compare all words that occur in the memory blocks. */ while (l >= sizeof(long)) { if (*((long *) t) != *((long *) s)) { /* Locate the exact byte that caused the test to fail. */ for (p = (char *) t, n = 0; n < sizeof(long); p++, n++) if (*p != ((char *) s)[n]) return p; /* The above loop should never exit, but just in case it * does, return the address of the word that caused the test * to fail. */ return t; } s = (long *) s + 1; t = (long *) t + 1; l -= sizeof(long); } } /* Compare all remaining bytes. */ while (l > 0) { if (*((char *) t) != *((char *) s)) return t; s = (char *) s + 1; t = (char *) t + 1; l--; } return NULL;}/* Attempt to locate the position of one block of memory in another block. */MP_GLOBALvoid *__mp_memfind(void *t, size_t l, void *s, size_t m){ if (m > 0) while (l >= m) { if ((*((char *) t) == *((char *) s)) && ((m == 1) || (!__mp_memcompare((char *) t + 1, (char *) s + 1, m - 1)))) return t; t = (char *) t + 1; l--; } return NULL;}/* Set a block of memory to contain a specific byte. */MP_GLOBALvoid__mp_memset(void *t, char c, size_t l){ long *w; char *p; size_t i, n; long b; /* This used to be a simple loop to set each byte individually, but * that is less efficient than attempting to set words at a time. * Therefore, if the number of bytes to set is larger than a certain * number then this routine will attempt to set as many words as * possible. */ if (l > sizeof(long) * sizeof(long)) { /* Set all bytes that occur before the first word. */ if ((n = (unsigned long) t & (sizeof(long) - 1)) > 0) { if ((n = sizeof(long) - n) > l) n = l; for (p = (char *) t, t = (char *) t + n; p < (char *) t; *p++ = c); l -= n; } if (l == 0) return; /* Set all words that occur in the memory block. */ if ((n = l / sizeof(long)) > 0) { /* Build up the word that we will be writing to memory. */ for (p = (char *) &b, i = 0; i < sizeof(long); *p++ = c, i++); for (w = (long *) t, t = (long *) t + n; w < (long *) t; *w++ = b); l -= n * sizeof(long); } } if (l == 0) return; /* Set all remaining bytes. */ for (p = (char *) t, t = (char *) t + l; p < (char *) t; *p++ = c);}/* Copy a block of memory from one address to another. */MP_GLOBALvoid__mp_memcopy(void *t, void *s, size_t l){ size_t n; if ((s == t) || (l == 0)) return; /* This used to be a simple loop to copy each byte individually, but * that is less efficient than attempting to copy words at a time. * Therefore, if the number of bytes to copy is larger than a certain * number then this routine will attempt to copy as many words as * possible. */ if ((s < t) && ((char *) s + l > (char *) t)) { /* The end of the source block overlaps with the beginning of the * destination block, so we have to copy from the end. */ s = (char *) s + l; t = (char *) t + l; n = (unsigned long) s & (sizeof(long) - 1); if ((n == ((unsigned long) t & (sizeof(long) - 1))) && (l > sizeof(long) * sizeof(long))) { /* We can only copy words if the source and destination have the * same alignment. This also guarantees that there is at least one * word of difference between the source and destination pointers. */ if (n > l) n = l; /* Copy all bytes that occur after the last word. */ while (n > 0) { s = (char *) s - 1; t = (char *) t - 1; *((char *) t) = *((char *) s); n--; l--; } /* Copy all words that occur in the memory block. */ while (l >= sizeof(long)) { s = (long *) s - 1; t = (long *) t - 1; *((long *) t) = *((long *) s); l -= sizeof(long); } } /* Copy all remaining bytes. */ while (l > 0) { s = (char *) s - 1; t = (char *) t - 1; *((char *) t) = *((char *) s); l--; } } else { /* The end of the destination block overlaps with the beginning of the * source block, or there is no overlap at all, so we can copy from * the beginning. */ n = (unsigned long) s & (sizeof(long) - 1); if ((n == ((unsigned long) t & (sizeof(long) - 1))) && (l > sizeof(long) * sizeof(long))) { /* We can only copy words if the source and destination have the * same alignment. This also guarantees that there is at least one * word of difference between the source and destination pointers. */ if ((n > 0) && ((n = sizeof(long) - n) > l)) n = l; /* Copy all bytes that occur before the first word. */ while (n > 0) { *((char *) t) = *((char *) s); s = (char *) s + 1; t = (char *) t + 1; n--; l--; } /* Copy all words that occur in the memory block. */ while (l >= sizeof(long)) { *((long *) t) = *((long *) s); s = (long *) s + 1; t = (long *) t + 1; l -= sizeof(long); } } /* Copy all remaining bytes. */ while (l > 0) { *((char *) t) = *((char *) s); s = (char *) s + 1; t = (char *) t + 1; l--; } }}#ifdef __cplusplus}#endif /* __cplusplus */
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -