MemCompare
Description
Compare memory regions. A zero byte count returns 0 without reading either pointer.
Parameters
| Name | Direction | Description |
|---|---|---|
p1 |
in | First memory region. |
p2 |
in | Second memory region. |
n |
in | Number of bytes to compare. |
Success
Returns 0 if equal, <0 if p1<p2, >0 if p1>p2.
Failure
Aborts via LOG_FATAL when n > 0 and either p1 or p2 is NULL.
Usage example (Cross-references)
Usage examples (Cross-references)
__attribute__((used)) int memcmp(const void *a, const void *b, freestanding_size_t n) {
return (int)MemCompare(a, b, (size)n);
}- In
Memory.c:10:
#include <Misra/Std/Memory.h>
i32 MemCompare(const void *p1, const void *p2, size n) {
if (n == 0) {
return 0;- In
Zstr.c:356:
continue;
}
if (MemCompare(haystack + pos, needle, needle_len) == 0) {
return haystack + pos;
}- In
Str.c:193:
min = StrLen(a) < StrLen(b) ? StrLen(a) : StrLen(b);
cmp = MemCompare(StrBegin(a), StrBegin(b), min);
if (cmp != 0) {- In
Str.c:437:
static inline bool starts_with(Zstr data, size data_len, Zstr prefix, size prefix_len) {
return data_len >= prefix_len && MemCompare(data, prefix, prefix_len) == 0;
}- In
Str.c:441:
static inline bool ends_with(Zstr data, size data_len, Zstr suffix, size suffix_len) {
return data_len >= suffix_len && MemCompare(data + data_len - suffix_len, suffix, suffix_len) == 0;
}- In
Str.c:480:
while (i + match_len <= s->length && replaced < count) {
if (MemCompare(s->data + i, match, match_len) == 0) {
StrDeleteRange(s, i, match_len);
StrInsertMany(s, replacement, replacement_len, i);- In
PdbCache.c:83:
const PeCodeViewInfo *pe_cv = PeCodeView(&entry->pe);
const PdbInfo *pdb_inf = PdbInfoStream(&entry->pdb);
if (pe_cv->age != pdb_inf->age || MemCompare(pe_cv->guid, pdb_inf->guid, 16) != 0) {
LOG_ERROR("PdbCache: GUID/age mismatch between PE and PDB for {}", entry->module_path);
PdbDeinit(&entry->pdb); if (main->build_id_size != sidecar->build_id_size)
return false;
return MemCompare(main->build_id, sidecar->build_id, main->build_id_size) == 0;
}- In
MachoCache.c:94:
StrDeinit(&path);
if (!MachoHasUuid(&e->dsym) || MemCompare(MachoUuid(&e->dsym), MachoUuid(&e->main), 16) != 0) {
LOG_ERROR("MachoCache: dSYM UUID mismatch for {}", e->module_path);
MachoDeinit(&e->dsym);- In
Dns.c:274:
char sep;
if (StrIterRemainingLength(&si) > kw_len &&
MemCompare(StrIterDataAt(&si, StrIterIndex(&si)), NS_KEYWORD, kw_len) == 0 &&
StrIterPeekAt(&si, (i64)kw_len, &sep) && (sep == ' ' || sep == '\t')) {
StrIterMustMove(&si, (i64)kw_len);- In
Pdb.c:147:
return false;
}
if (MemCompare(BufData(&self->data), MSF_MAGIC_7, sizeof(MSF_MAGIC_7)) != 0) {
LOG_ERROR("PDB: bad MSF magic (not 7.00)");
return false;- In
Int.Convert.c:69:
bool result = written == 4;
result = result && (MemCompare(out, bytes, sizeof(bytes)) == 0);
result = result && (ZstrCompare(StrBegin(&text), "cdef1234") == 0);- In
Int.Convert.c:90:
bool result = written == 4;
result = result && (MemCompare(out, bytes, sizeof(bytes)) == 0);
result = result && (ZstrCompare(StrBegin(&text), "12345678") == 0);- In
Socket.c:80:
char buf[64];
i64 got = SocketRecv(&server, buf, sizeof(buf));
bool ok = got == (i64)n && MemCompare(buf, payload, n) == 0;
SocketClose(&server);- In
MachO.c:134:
ok = m.cputype == 0x01000007u && m.filetype == MACHO_FILE_TYPE_EXECUTE;
ok = ok && m.has_uuid && MemCompare(m.uuid, kUuid, 16) == 0;
ok = ok && VecLen(&m.segments) == 1;
ok = ok && ZstrCompare(VecPtrAt(&m.segments, 0)->name, "__TEXT") == 0;- In
Buf.c:44:
0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07, 0x08, // u64 BE
};
bool ok = BufLength(&b) == sizeof(expect) && MemCompare(BufData(&b), expect, sizeof(expect)) == 0;
BufDeinit(&b);
DefaultAllocatorDeinit(&alloc);- In
Buf.c:58:
BufWriteULeb128(&b, 16384);
const u8 expect_uleb[] = {0x00, 0x7F, 0x80, 0x01, 0x80, 0x80, 0x01};
if (BufLength(&b) != sizeof(expect_uleb) || MemCompare(BufData(&b), expect_uleb, sizeof(expect_uleb)) != 0) {
BufDeinit(&b);
DefaultAllocatorDeinit(&alloc);- In
Buf.c:70:
BufWriteSLeb128(&b, -64);
const u8 expect_sleb[] = {0x00, 0x7F, 0xC0, 0x00, 0x40};
bool ok = BufLength(&b) == sizeof(expect_sleb) && MemCompare(BufData(&b), expect_sleb, sizeof(expect_sleb)) == 0;
BufDeinit(&b);- In
Buf.c:82:
BufWriteZstr(&b, "hi");
const u8 expect[] = {'h', 'i', 0};
bool ok = BufLength(&b) == sizeof(expect) && MemCompare(BufData(&b), expect, sizeof(expect)) == 0;
BufDeinit(&b);
DefaultAllocatorDeinit(&alloc);- In
Buf.c:158:
bool ok = BufAppendFmt(&b, "{<2r}{>4r}", (u16)0xCAFE, (u32)0xDEADBEEF);
const u8 expect[] = {0x99, 0xFE, 0xCA, 0xDE, 0xAD, 0xBE, 0xEF};
ok = ok && BufLength(&b) == sizeof(expect) && MemCompare(BufData(&b), expect, sizeof(expect)) == 0;
BufDeinit(&b);
DefaultAllocatorDeinit(&alloc);- In
Buf.c:172:
bool ok = BufWriteFmt(&b, "{<2r}", (u16)0x1234);
const u8 expect[] = {0x34, 0x12};
ok = ok && BufLength(&b) == sizeof(expect) && MemCompare(BufData(&b), expect, sizeof(expect)) == 0;
BufDeinit(&b);
DefaultAllocatorDeinit(&alloc);- In
Buf.c:200:
0x11
};
ok = ok && BufLength(&b) == sizeof(expect) && MemCompare(BufData(&b), expect, sizeof(expect)) == 0;
// Out-of-range patch must fail and leave the buf unchanged.
- In
Buf.c:207:
ok = ok && !BufPatchFmt(&b, BufLength(&b), "{<2r}", (u16)0);
ok = ok && BufLength(&b) == BufLength(&snapshot);
ok = ok && MemCompare(BufData(&b), BufData(&snapshot), BufLength(&b)) == 0;
BufDeinit(&snapshot);- In
Pdb.c:110:
ok = ok && pdb.info.signature == 0xdeadbeef;
ok = ok && pdb.info.age == 0x42;
ok = ok && MemCompare(pdb.info.guid, kGuid, 16) == 0;
PdbDeinit(&pdb);- In
Pe.c:174:
ok = ok && pe.codeview.present;
ok = ok && pe.codeview.age == 0x2a;
ok = ok && MemCompare(pe.codeview.guid, kGuid, 16) == 0;
ok = ok && pe.codeview.pdb_path && ZstrCompare(pe.codeview.pdb_path, kPdbPath) == 0;
Last updated on