mirror of
https://github.com/upx/upx
synced 2025-09-28 19:06:07 +08:00
All find*() and patch*() routines now return the buffer offset as an `int'.
committer: mfx <mfx> 976592518 +0000
This commit is contained in:
parent
1efd7f5cfa
commit
b2e0f807f2
|
@ -453,7 +453,8 @@ void PackExe::pack(OutputFile *fo)
|
|||
}
|
||||
|
||||
putPackHeader(loader,lsize);
|
||||
upx_bytep p = find_le32(loader,lsize,get_le32("IPCS"));
|
||||
// upx_bytep p = find_le32(loader,lsize,get_le32("IPCS"));
|
||||
upx_bytep p = NULL;
|
||||
if (p == NULL)
|
||||
throwBadLoader();
|
||||
if (flag & USEJUMP)
|
||||
|
|
|
@ -89,8 +89,7 @@ void PackSys::patchLoader(OutputFile *fo,
|
|||
patch_le16(loader,lsize,"CT",calls);
|
||||
}
|
||||
|
||||
unsigned jmp_pos;
|
||||
jmp_pos = find_le16(loader,e_len,get_le16("JM")) - loader;
|
||||
const unsigned jmp_pos = find_le16(loader,e_len,get_le16("JM"));
|
||||
patch_le16(loader,e_len,"JM",ph.u_len+overlapoh+2-jmp_pos-2);
|
||||
loader[getLoaderSection("SYSSUBSI") - 1] = (upx_byte) -e_len;
|
||||
patch_le16(loader,e_len,"DI",copy_to);
|
||||
|
|
|
@ -232,7 +232,7 @@ void PackTmt::pack(OutputFile *fo)
|
|||
patch_le32(loader,lsize,"TEXL",(ft.id & 0xf) % 3 == 0 ? ft.calls :
|
||||
ft.lastcall - ft.calls * 4);
|
||||
}
|
||||
const unsigned jmp_pos = find_le32(loader,e_len,get_le32("JMPD")) - loader;
|
||||
const unsigned jmp_pos = find_le32(loader,e_len,get_le32("JMPD"));
|
||||
patch_le32(loader,e_len,"JMPD",ph.u_len+overlapoh-jmp_pos-4);
|
||||
|
||||
patch_le32(loader,e_len,"ECX0",ph.c_len+d_len);
|
||||
|
|
|
@ -180,20 +180,21 @@ bool PackTos::checkFileHeader()
|
|||
//
|
||||
**************************************************************************/
|
||||
|
||||
unsigned PackTos::patch_d0_subq(void *l, int llen, unsigned d0,
|
||||
unsigned PackTos::patch_d0_subq(void *b, int blen, unsigned d0,
|
||||
const char *subq_marker)
|
||||
{
|
||||
// patch a "subq.l #1,d0" or "subq.w #1,d0".
|
||||
// also convert into "dbra" if possible
|
||||
upx_byte *p;
|
||||
|
||||
assert((int)d0 > 0);
|
||||
p = find_be16(l, llen, get_be16(subq_marker));
|
||||
int boff = find_be16(b, blen, get_be16(subq_marker));
|
||||
if (boff < 0)
|
||||
throwBadLoader();
|
||||
|
||||
unsigned char *p = (unsigned char *)b + boff;
|
||||
if (p[2] == 0x66) // bne.b XXX
|
||||
checkPatch(l, p, 4);
|
||||
checkPatch(b, blen, boff, 4);
|
||||
else
|
||||
checkPatch(l, p, 2);
|
||||
checkPatch(b, blen, boff, 2);
|
||||
|
||||
if (d0 > 65536)
|
||||
{
|
||||
|
@ -220,17 +221,18 @@ unsigned PackTos::patch_d0_subq(void *l, int llen, unsigned d0,
|
|||
}
|
||||
|
||||
|
||||
unsigned PackTos::patch_d0_loop(void *l, int llen, unsigned d0,
|
||||
unsigned PackTos::patch_d0_loop(void *b, int blen, unsigned d0,
|
||||
const char *d0_marker, const char *subq_marker)
|
||||
{
|
||||
upx_byte *p;
|
||||
d0 = patch_d0_subq(b, blen, d0, subq_marker);
|
||||
|
||||
d0 = patch_d0_subq(l, llen, d0, subq_marker);
|
||||
int boff = find_be32(b, blen, get_be32(d0_marker));
|
||||
checkPatch(b, blen, boff, 4);
|
||||
|
||||
p = find_be32(l, llen, get_be32(d0_marker));
|
||||
unsigned char *p = (unsigned char *)b + boff;
|
||||
assert(get_be16(p - 2) == 0x203c); // move.l #XXXXXXXX,d0
|
||||
checkPatch(l, p, 4);
|
||||
set_be32(p, d0);
|
||||
|
||||
return d0;
|
||||
}
|
||||
|
||||
|
|
|
@ -73,8 +73,8 @@ protected:
|
|||
} ih, oh;
|
||||
|
||||
protected:
|
||||
unsigned patch_d0_subq(void *l, int llen, unsigned, const char*);
|
||||
unsigned patch_d0_loop(void *l, int llen, unsigned, const char*, const char*);
|
||||
unsigned patch_d0_subq(void *b, int blen, unsigned, const char*);
|
||||
unsigned patch_d0_loop(void *b, int blen, unsigned, const char*, const char*);
|
||||
};
|
||||
|
||||
|
||||
|
|
|
@ -1708,8 +1708,7 @@ void PackW32Pe::pack(OutputFile *fo)
|
|||
// patch loader
|
||||
if (ih.entry)
|
||||
{
|
||||
unsigned jmp_pos;
|
||||
jmp_pos = ptr_diff(find_le32(loader,codesize + 4,get_le32("JMPO")),loader);
|
||||
unsigned jmp_pos = find_le32(loader,codesize + 4,get_le32("JMPO"));
|
||||
patch_le32(loader,codesize + 4,"JMPO",ih.entry - upxsection - jmp_pos - 4);
|
||||
}
|
||||
if (big_relocs & 6)
|
||||
|
@ -1957,8 +1956,8 @@ int PackW32Pe::canUnpack()
|
|||
static const char magic[] = "\x8b\x1e\x83\xee\xfc\x11\xdb";
|
||||
// mov ebx, [esi]; sub esi, -4; adc ebx,ebx
|
||||
|
||||
unsigned char *p = find(buf, sizeof(buf), magic, 7);
|
||||
if (p && find(p + 1, buf - p + sizeof(buf) - 1, magic, 7))
|
||||
int offset = find(buf, sizeof(buf), magic, 7);
|
||||
if (offset >= 0 && find(buf + offset + 1, sizeof(buf) - offset - 1, magic, 7) >= 0)
|
||||
x = true;
|
||||
} catch (...) {
|
||||
//x = true;
|
||||
|
|
|
@ -526,7 +526,7 @@ void PackWcle::pack(OutputFile *fo)
|
|||
}
|
||||
patch_le32(p,d_len,"RELO",mps*pages);
|
||||
|
||||
unsigned jpos = find_le32(oimage,e_len,get_le32("JMPD")) - oimage;
|
||||
unsigned jpos = find_le32(oimage,e_len,get_le32("JMPD"));
|
||||
patch_le32(oimage,e_len,"JMPD",ic-jpos-4);
|
||||
|
||||
jpos = (((ph.c_len+3)&~3) + d_len+3)/4;
|
||||
|
|
125
src/packer.cpp
125
src/packer.cpp
|
@ -630,113 +630,138 @@ bool Packer::readPackHeader(unsigned len, off_t seek_offset, upx_byte *buf)
|
|||
// patch util for loader
|
||||
**************************************************************************/
|
||||
|
||||
void Packer::checkPatch(void *l, void *p, int size)
|
||||
void Packer::checkPatch(void *b, int blen, int boff, int size)
|
||||
{
|
||||
if (l == NULL && p == NULL && size == 0)
|
||||
if (b == NULL && blen == 0 && boff == 0 && size == 0)
|
||||
{
|
||||
// reset
|
||||
last_patch = NULL;
|
||||
last_patch_offset = 0;
|
||||
return;
|
||||
}
|
||||
if (l == NULL || p == NULL || p < l || size <= 0)
|
||||
if (b == NULL || blen <= 0 || boff < 0 || size <= 0)
|
||||
throwBadLoader();
|
||||
ptrdiff_t offset = (upx_bytep) p - (upx_bytep) l;
|
||||
//printf("checkPatch: %p %5ld %d\n", l, offset, size);
|
||||
if (l == last_patch)
|
||||
if (boff + size < 0 || boff + size > blen)
|
||||
throwBadLoader();
|
||||
//printf("checkPatch: %p %5d %5d %d\n", b, blen, boff, size);
|
||||
if (b == last_patch)
|
||||
{
|
||||
if (offset + size > last_patch_offset)
|
||||
if (boff + size > last_patch_offset)
|
||||
throwInternalError("invalid patch order");
|
||||
}
|
||||
else
|
||||
last_patch = l;
|
||||
last_patch_offset = offset;
|
||||
last_patch = b;
|
||||
last_patch_offset = boff;
|
||||
}
|
||||
|
||||
|
||||
unsigned Packer::patch_be16(void *l, int llen, unsigned old, unsigned new_)
|
||||
int Packer::patch_be16(void *b, int blen, unsigned old, unsigned new_)
|
||||
{
|
||||
void *p = find_be16(l,llen,old);
|
||||
checkPatch(l,p,2);
|
||||
int boff = find_be16(b,blen,old);
|
||||
checkPatch(b, blen, boff, 2);
|
||||
|
||||
unsigned char *p = (unsigned char *)b + boff;
|
||||
set_be16(p,new_);
|
||||
return (unsigned) last_patch_offset;
|
||||
|
||||
return boff;
|
||||
}
|
||||
|
||||
|
||||
unsigned Packer::patch_be16(void *l, int llen, const void * old, unsigned new_)
|
||||
int Packer::patch_be16(void *b, int blen, const void *old, unsigned new_)
|
||||
{
|
||||
void *p = find(l,llen,old,2);
|
||||
checkPatch(l,p,2);
|
||||
int boff = find(b,blen,old,2);
|
||||
checkPatch(b, blen, boff, 2);
|
||||
|
||||
unsigned char *p = (unsigned char *)b + boff;
|
||||
set_be16(p,new_);
|
||||
return (unsigned) last_patch_offset;
|
||||
|
||||
return boff;
|
||||
}
|
||||
|
||||
|
||||
unsigned Packer::patch_be32(void *l, int llen, unsigned old, unsigned new_)
|
||||
int Packer::patch_be32(void *b, int blen, unsigned old, unsigned new_)
|
||||
{
|
||||
void *p = find_be32(l,llen,old);
|
||||
checkPatch(l,p,4);
|
||||
int boff = find_be32(b,blen,old);
|
||||
checkPatch(b, blen, boff, 4);
|
||||
|
||||
unsigned char *p = (unsigned char *)b + boff;
|
||||
set_be32(p,new_);
|
||||
return (unsigned) last_patch_offset;
|
||||
|
||||
return boff;
|
||||
}
|
||||
|
||||
|
||||
unsigned Packer::patch_be32(void *l, int llen, const void * old, unsigned new_)
|
||||
int Packer::patch_be32(void *b, int blen, const void *old, unsigned new_)
|
||||
{
|
||||
void *p = find(l,llen,old,4);
|
||||
checkPatch(l,p,4);
|
||||
int boff = find(b,blen,old,4);
|
||||
checkPatch(b, blen, boff, 4);
|
||||
|
||||
unsigned char *p = (unsigned char *)b + boff;
|
||||
set_be32(p,new_);
|
||||
return (unsigned) last_patch_offset;
|
||||
|
||||
return boff;
|
||||
}
|
||||
|
||||
|
||||
unsigned Packer::patch_le16(void *l, int llen, unsigned old, unsigned new_)
|
||||
int Packer::patch_le16(void *b, int blen, unsigned old, unsigned new_)
|
||||
{
|
||||
void *p = find_le16(l,llen,old);
|
||||
checkPatch(l,p,2);
|
||||
int boff = find_le16(b,blen,old);
|
||||
checkPatch(b, blen, boff, 2);
|
||||
|
||||
unsigned char *p = (unsigned char *)b + boff;
|
||||
set_le16(p,new_);
|
||||
return (unsigned) last_patch_offset;
|
||||
|
||||
return boff;
|
||||
}
|
||||
|
||||
|
||||
unsigned Packer::patch_le16(void *l, int llen, const void * old, unsigned new_)
|
||||
int Packer::patch_le16(void *b, int blen, const void *old, unsigned new_)
|
||||
{
|
||||
void *p = find(l,llen,old,2);
|
||||
checkPatch(l,p,2);
|
||||
int boff = find(b,blen,old,2);
|
||||
checkPatch(b, blen, boff, 2);
|
||||
|
||||
unsigned char *p = (unsigned char *)b + boff;
|
||||
set_le16(p,new_);
|
||||
return (unsigned) last_patch_offset;
|
||||
|
||||
return boff;
|
||||
}
|
||||
|
||||
|
||||
unsigned Packer::patch_le32(void *l, int llen, unsigned old, unsigned new_)
|
||||
int Packer::patch_le32(void *b, int blen, unsigned old, unsigned new_)
|
||||
{
|
||||
void *p = find_le32(l,llen,old);
|
||||
checkPatch(l,p,4);
|
||||
int boff = find_le32(b,blen,old);
|
||||
checkPatch(b, blen, boff, 2);
|
||||
|
||||
unsigned char *p = (unsigned char *)b + boff;
|
||||
set_le32(p,new_);
|
||||
return (unsigned) last_patch_offset;
|
||||
|
||||
return boff;
|
||||
}
|
||||
|
||||
|
||||
unsigned Packer::patch_le32(void *l, int llen, const void * old, unsigned new_)
|
||||
int Packer::patch_le32(void *b, int blen, const void *old, unsigned new_)
|
||||
{
|
||||
void *p = find(l,llen,old,4);
|
||||
checkPatch(l,p,4);
|
||||
int boff = find(b,blen,old,4);
|
||||
checkPatch(b, blen, boff, 2);
|
||||
|
||||
unsigned char *p = (unsigned char *)b + boff;
|
||||
set_le32(p,new_);
|
||||
return (unsigned) last_patch_offset;
|
||||
|
||||
return boff;
|
||||
}
|
||||
|
||||
|
||||
// patch version into stub/ident_n.ash
|
||||
unsigned Packer::patchVersion(void *l, int llen)
|
||||
int Packer::patchVersion(void *b, int blen)
|
||||
{
|
||||
upx_byte *p = find(l,llen,"$Id: UPX UPXV ",14);
|
||||
checkPatch(l,p,14);
|
||||
unsigned char buf[4+1];
|
||||
memset(buf, ' ', 4);
|
||||
size_t len = UPX_MIN(strlen(UPX_VERSION_STRING), 4);
|
||||
memcpy(buf, UPX_VERSION_STRING, len);
|
||||
memcpy(p + 9, buf, 4);
|
||||
return (unsigned) last_patch_offset;
|
||||
int boff = find(b,blen,"$Id: UPX UPXV ",14);
|
||||
checkPatch(b, blen, boff, 14);
|
||||
|
||||
unsigned char *p = (unsigned char *)b + boff + 9;
|
||||
memset(p, ' ', 4);
|
||||
memcpy(p, UPX_VERSION_STRING, UPX_MIN(strlen(UPX_VERSION_STRING), 4));
|
||||
|
||||
return boff;
|
||||
}
|
||||
|
||||
|
||||
|
|
23
src/packer.h
23
src/packer.h
|
@ -207,16 +207,16 @@ protected:
|
|||
virtual unsigned getRandomId() const;
|
||||
|
||||
// patch util
|
||||
unsigned patch_be16(void *l, int llen, unsigned old, unsigned new_);
|
||||
unsigned patch_be16(void *l, int llen, const void * old, unsigned new_);
|
||||
unsigned patch_be32(void *l, int llen, unsigned old, unsigned new_);
|
||||
unsigned patch_be32(void *l, int llen, const void * old, unsigned new_);
|
||||
unsigned patch_le16(void *l, int llen, unsigned old, unsigned new_);
|
||||
unsigned patch_le16(void *l, int llen, const void * old, unsigned new_);
|
||||
unsigned patch_le32(void *l, int llen, unsigned old, unsigned new_);
|
||||
unsigned patch_le32(void *l, int llen, const void * old, unsigned new_);
|
||||
unsigned patchVersion(void *l, int llen);
|
||||
void checkPatch(void *l, void *p, int size);
|
||||
int patch_be16(void *b, int blen, unsigned old, unsigned new_);
|
||||
int patch_be16(void *b, int blen, const void * old, unsigned new_);
|
||||
int patch_be32(void *b, int blen, unsigned old, unsigned new_);
|
||||
int patch_be32(void *b, int blen, const void * old, unsigned new_);
|
||||
int patch_le16(void *b, int blen, unsigned old, unsigned new_);
|
||||
int patch_le16(void *b, int blen, const void * old, unsigned new_);
|
||||
int patch_le32(void *b, int blen, unsigned old, unsigned new_);
|
||||
int patch_le32(void *b, int blen, const void * old, unsigned new_);
|
||||
int patchVersion(void *b, int blen);
|
||||
void checkPatch(void *b, int blen, int boff, int size);
|
||||
|
||||
protected:
|
||||
// relocation util
|
||||
|
@ -240,13 +240,14 @@ protected:
|
|||
int ui_pass;
|
||||
int ui_total_passes;
|
||||
|
||||
private:
|
||||
// linker
|
||||
Linker *linker;
|
||||
|
||||
private:
|
||||
// private to checkPatch()
|
||||
void *last_patch;
|
||||
ptrdiff_t last_patch_offset;
|
||||
int last_patch_offset;
|
||||
|
||||
private:
|
||||
// disable copy and assignment
|
||||
|
|
|
@ -101,9 +101,10 @@ void PackHeader::putPackHeader(upx_bytep buf, unsigned len)
|
|||
#if defined(UNUPX)
|
||||
throwBadLoader();
|
||||
#else
|
||||
upx_bytep l = find_le32(buf,len,magic);
|
||||
if (l == 0)
|
||||
int offset = find_le32(buf,len,magic);
|
||||
if (offset < 0)
|
||||
throwBadLoader();
|
||||
upx_bytep l = buf + offset;
|
||||
|
||||
l[4] = (unsigned char) version;
|
||||
l[5] = (unsigned char) format;
|
||||
|
@ -163,14 +164,16 @@ void PackHeader::putPackHeader(upx_bytep buf, unsigned len)
|
|||
|
||||
bool PackHeader::fillPackHeader(upx_bytep buf, unsigned len)
|
||||
{
|
||||
upx_bytep l = find_le32(buf,len,magic);
|
||||
if (l == 0)
|
||||
int offset = find_le32(buf,len,magic);
|
||||
if (offset < 0)
|
||||
return false;
|
||||
buf_offset = l - buf;
|
||||
const int hlen = len - buf_offset;
|
||||
const int hlen = len - offset;
|
||||
if (hlen < 8)
|
||||
return false;
|
||||
|
||||
upx_bytep l = buf + offset;
|
||||
buf_offset = offset;
|
||||
|
||||
version = l[4];
|
||||
format = l[5];
|
||||
method = l[6];
|
||||
|
|
47
src/util.cpp
47
src/util.cpp
|
@ -31,7 +31,7 @@
|
|||
|
||||
|
||||
/*************************************************************************
|
||||
//
|
||||
// qsort() util
|
||||
**************************************************************************/
|
||||
|
||||
int be16_compare(const void *e1, const void *e2)
|
||||
|
@ -64,24 +64,27 @@ int le32_compare(const void *e1, const void *e2)
|
|||
|
||||
|
||||
/*************************************************************************
|
||||
//
|
||||
// find util
|
||||
**************************************************************************/
|
||||
|
||||
upx_bytep find(const void *b, int blen, const void *what, int wlen)
|
||||
int find(const void *b, int blen, const void *what, int wlen)
|
||||
{
|
||||
if (b == NULL || what == NULL || wlen <= 0)
|
||||
return -1;
|
||||
|
||||
int i;
|
||||
const upx_bytep base = (const upx_bytep) b;
|
||||
unsigned char firstc = * (const upx_bytep) what;
|
||||
const unsigned char *base = (const unsigned char *) b;
|
||||
unsigned char firstc = * (const unsigned char *) what;
|
||||
|
||||
for (i = 0; i <= blen - wlen; i++, base++)
|
||||
if (*base == firstc && memcmp(base,what,wlen) == 0)
|
||||
return const_cast<upx_bytep>(base);
|
||||
return i;
|
||||
|
||||
return NULL;
|
||||
return -1;
|
||||
}
|
||||
|
||||
|
||||
upx_bytep find_be16(const void *b, int blen, unsigned what)
|
||||
int find_be16(const void *b, int blen, unsigned what)
|
||||
{
|
||||
unsigned char w[2];
|
||||
set_be16(w,what);
|
||||
|
@ -89,7 +92,7 @@ upx_bytep find_be16(const void *b, int blen, unsigned what)
|
|||
}
|
||||
|
||||
|
||||
upx_bytep find_be32(const void *b, int blen, unsigned what)
|
||||
int find_be32(const void *b, int blen, unsigned what)
|
||||
{
|
||||
unsigned char w[4];
|
||||
set_be32(w,what);
|
||||
|
@ -97,7 +100,7 @@ upx_bytep find_be32(const void *b, int blen, unsigned what)
|
|||
}
|
||||
|
||||
|
||||
upx_bytep find_le16(const void *b, int blen, unsigned what)
|
||||
int find_le16(const void *b, int blen, unsigned what)
|
||||
{
|
||||
unsigned char w[2];
|
||||
set_le16(w,what);
|
||||
|
@ -105,7 +108,7 @@ upx_bytep find_le16(const void *b, int blen, unsigned what)
|
|||
}
|
||||
|
||||
|
||||
upx_bytep find_le32(const void *b, int blen, unsigned what)
|
||||
int find_le32(const void *b, int blen, unsigned what)
|
||||
{
|
||||
unsigned char w[4];
|
||||
set_le32(w,what);
|
||||
|
@ -330,7 +333,7 @@ bool file_exists(const char *name)
|
|||
struct stat st;
|
||||
|
||||
/* return true if we can open it */
|
||||
fd = open(name,O_RDONLY);
|
||||
fd = open(name, O_RDONLY);
|
||||
if (fd >= 0)
|
||||
{
|
||||
(void) close(fd);
|
||||
|
@ -338,15 +341,19 @@ bool file_exists(const char *name)
|
|||
}
|
||||
|
||||
/* return true if we can stat it */
|
||||
memset(&st, 0, sizeof(st));
|
||||
#if defined(HAVE_LSTAT)
|
||||
r = lstat(name,&st);
|
||||
#else
|
||||
r = stat(name,&st);
|
||||
#endif
|
||||
//memset(&st, 0, sizeof(st));
|
||||
r = stat(name, &st);
|
||||
if (r != -1)
|
||||
return true;
|
||||
|
||||
/* return true if we can lstat it */
|
||||
#if defined(HAVE_LSTAT)
|
||||
//memset(&st, 0, sizeof(st));
|
||||
r = lstat(name, &st);
|
||||
if (r != -1)
|
||||
return true;
|
||||
#endif
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
|
@ -375,6 +382,8 @@ bool maketempname(char *ofilename, const char *ifilename,
|
|||
if (!file_exists(ofilename))
|
||||
return true;
|
||||
}
|
||||
|
||||
ofilename[0] = 0;
|
||||
return false;
|
||||
}
|
||||
|
||||
|
@ -408,6 +417,8 @@ bool makebakname(char *ofilename, const char *ifilename, bool force)
|
|||
if (!file_exists(ofilename))
|
||||
return true;
|
||||
}
|
||||
|
||||
ofilename[0] = 0;
|
||||
return false;
|
||||
}
|
||||
|
||||
|
|
10
src/util.h
10
src/util.h
|
@ -53,11 +53,11 @@ unsigned get_ratio(unsigned long packedsize, unsigned long size,
|
|||
char *center_string(const char *name, size_t s);
|
||||
|
||||
|
||||
unsigned char *find(const void *b, int blen, const void *what, int wlen);
|
||||
unsigned char *find_be16(const void *b, int blen, unsigned what);
|
||||
unsigned char *find_be32(const void *b, int blen, unsigned what);
|
||||
unsigned char *find_le16(const void *b, int blen, unsigned what);
|
||||
unsigned char *find_le32(const void *b, int blen, unsigned what);
|
||||
int find(const void *b, int blen, const void *what, int wlen);
|
||||
int find_be16(const void *b, int blen, unsigned what);
|
||||
int find_be32(const void *b, int blen, unsigned what);
|
||||
int find_le16(const void *b, int blen, unsigned what);
|
||||
int find_le32(const void *b, int blen, unsigned what);
|
||||
|
||||
|
||||
inline ptrdiff_t ptr_diff(const void *p1, const void *p2)
|
||||
|
|
Loading…
Reference in New Issue
Block a user