mirror of
https://github.com/radareorg/radare2.git
synced 2024-10-10 12:24:20 +00:00
850045c329
Fixed ragg2 -e segfault Fix use of ragg2 -p Fix memleaks and null derefs in rio and rsocket Fix some build warnings Fix the segfaults found in the ELF parser Dwarf parsing is only done if bin.dwarf is true
214 lines
5.2 KiB
C
214 lines
5.2 KiB
C
/* radare - LGPL - Copyright 2009-2012 - pancake */
|
|
|
|
#include "r_types.h"
|
|
#include "r_util.h"
|
|
|
|
#if 0
|
|
/* TODO: the basic object lifecycle must be simplified */
|
|
struct r_class_t {
|
|
// new/free are implicit
|
|
.init = &r_buf_init,
|
|
.fini = &r_buf_fini,
|
|
} r_buf_class;
|
|
|
|
#define r_buf_init(x) r_buf_class->init
|
|
#endif
|
|
|
|
R_API RBuffer *r_buf_new() {
|
|
RBuffer *b = R_NEW (RBuffer);
|
|
if (b) {
|
|
b->buf = NULL;
|
|
b->length = 0;
|
|
b->cur = 0;
|
|
b->base = 0LL;
|
|
b->mmap = NULL;
|
|
}
|
|
return b;
|
|
}
|
|
|
|
R_API RBuffer *r_buf_mmap (const char *file, int rw) {
|
|
RBuffer *b = r_buf_new ();
|
|
if (!b) return NULL;
|
|
b->mmap = r_file_mmap (file, rw);
|
|
if (b->mmap && b->mmap->len>0) {
|
|
b->buf = b->mmap->buf;
|
|
b->length = b->mmap->len;
|
|
} else {
|
|
r_buf_free (b);
|
|
return NULL; /* we just freed b, don't return it */
|
|
}
|
|
return b;
|
|
}
|
|
|
|
R_API int r_buf_set_bits(RBuffer *b, int bitoff, int bitsize, ut64 value) {
|
|
// TODO: implement r_buf_set_bits
|
|
// TODO: get the implementation from reg/value.c ?
|
|
return R_FALSE;
|
|
}
|
|
|
|
R_API int r_buf_set_bytes(RBuffer *b, const ut8 *buf, int length) {
|
|
if (b->buf)
|
|
free (b->buf);
|
|
if (length<0)
|
|
return R_FALSE;
|
|
if (!(b->buf = malloc (length+1)))
|
|
return R_FALSE;
|
|
memcpy (b->buf, buf, length);
|
|
b->length = length;
|
|
return R_TRUE;
|
|
}
|
|
|
|
R_API int r_buf_prepend_bytes(RBuffer *b, const ut8 *buf, int length) {
|
|
if (!(b->buf = realloc (b->buf, b->length+length)))
|
|
return R_FALSE;
|
|
memmove (b->buf+length, b->buf, b->length);
|
|
memcpy (b->buf, buf, length);
|
|
b->length += length;
|
|
return R_TRUE;
|
|
}
|
|
|
|
// TODO: R_API void r_buf_insert_bytes() // with shift
|
|
// TODO: R_API void r_buf_write_bytes() // overwrite
|
|
|
|
R_API char *r_buf_to_string(RBuffer *b) {
|
|
char *s;
|
|
if (!b) return strdup ("");
|
|
s = malloc (b->length+1);
|
|
memcpy (s, b->buf, b->length);
|
|
s[b->length] = 0;
|
|
return s;
|
|
}
|
|
|
|
R_API int r_buf_append_bytes(RBuffer *b, const ut8 *buf, int length) {
|
|
if (!(b->buf = realloc (b->buf, b->length+length)))
|
|
return R_FALSE;
|
|
memcpy (b->buf+b->length, buf, length);
|
|
b->length += length;
|
|
return R_TRUE;
|
|
}
|
|
|
|
R_API int r_buf_append_nbytes(RBuffer *b, int length) {
|
|
if (!(b->buf = realloc (b->buf, b->length+length)))
|
|
return R_FALSE;
|
|
memset (b->buf+b->length, 0, length);
|
|
b->length += length;
|
|
return R_TRUE;
|
|
}
|
|
|
|
R_API int r_buf_append_ut16(RBuffer *b, ut16 n) {
|
|
if (!(b->buf = realloc (b->buf, b->length+sizeof (n))))
|
|
return R_FALSE;
|
|
memcpy (b->buf+b->length, &n, sizeof (n));
|
|
b->length += sizeof (n);
|
|
return R_TRUE;
|
|
}
|
|
|
|
R_API int r_buf_append_ut32(RBuffer *b, ut32 n) {
|
|
if (!(b->buf = realloc (b->buf, b->length+sizeof (n))))
|
|
return R_FALSE;
|
|
memcpy (b->buf+b->length, &n, sizeof (n));
|
|
b->length += sizeof (n);
|
|
return R_TRUE;
|
|
}
|
|
|
|
R_API int r_buf_append_ut64(RBuffer *b, ut64 n) {
|
|
if (!(b->buf = realloc (b->buf, b->length+sizeof (n))))
|
|
return R_FALSE;
|
|
memcpy (b->buf+b->length, &n, sizeof (n));
|
|
b->length += sizeof (n);
|
|
return R_TRUE;
|
|
}
|
|
|
|
R_API int r_buf_append_buf(RBuffer *b, RBuffer *a) {
|
|
if (!(b->buf = realloc (b->buf, b->length+a->length)))
|
|
return R_FALSE;
|
|
memcpy (b->buf+b->length, a->buf, a->length);
|
|
b->length += a->length;
|
|
return R_TRUE;
|
|
}
|
|
|
|
static int r_buf_cpy(RBuffer *b, ut64 addr, ut8 *dst, const ut8 *src, int len, int write) {
|
|
int end;
|
|
addr = (addr==R_BUF_CUR)? b->cur: addr-b->base;
|
|
if (len<1 || dst == NULL || addr > b->length)
|
|
return -1;
|
|
end = (int)(addr+len);
|
|
if (end > b->length)
|
|
len -= end-b->length;
|
|
if (write)
|
|
dst += addr;
|
|
else src += addr;
|
|
memcpy (dst, src, len);
|
|
b->cur = addr + len;
|
|
return len;
|
|
}
|
|
|
|
static int r_buf_fcpy_at (RBuffer *b, ut64 addr, ut8 *buf, const char *fmt, int n, int write) {
|
|
int i, j, k, len, tsize, endian, m = 1;
|
|
|
|
if (addr == R_BUF_CUR)
|
|
addr = b->cur;
|
|
else addr -= b->base;
|
|
if (addr < 0 || addr > b->length)
|
|
return -1;
|
|
for (i = len = 0; i < n; i++)
|
|
for (j = 0; fmt[j]; j++) {
|
|
if (len > b->length)
|
|
return -1;
|
|
switch (fmt[j]) {
|
|
case '0'...'9':
|
|
if (m == 1)
|
|
m = r_num_get(NULL, &fmt[j]);
|
|
continue;
|
|
case 's': tsize = 2; endian = 1; break;
|
|
case 'S': tsize = 2; endian = 0; break;
|
|
case 'i': tsize = 4; endian = 1; break;
|
|
case 'I': tsize = 4; endian = 0; break;
|
|
case 'l': tsize = 8; endian = 1; break;
|
|
case 'L': tsize = 8; endian = 0; break;
|
|
case 'c': tsize = 1; endian = 1; break;
|
|
default: return -1;
|
|
}
|
|
for (k = 0; k < m; k++) {
|
|
if (write) r_mem_copyendian((ut8*)&buf[addr+len+k*tsize],
|
|
(ut8*)&b->buf[len+k*tsize], tsize, endian);
|
|
else r_mem_copyendian((ut8*)&buf[len+k*tsize],
|
|
(ut8*)&b->buf[addr+len+k*tsize], tsize, endian);
|
|
}
|
|
len += m*tsize; m = 1;
|
|
}
|
|
b->cur = addr + len;
|
|
return len;
|
|
}
|
|
|
|
R_API int r_buf_read_at(RBuffer *b, ut64 addr, ut8 *buf, int len) {
|
|
return r_buf_cpy (b, addr, buf, b->buf, len, R_FALSE);
|
|
}
|
|
|
|
R_API int r_buf_fread_at (RBuffer *b, ut64 addr, ut8 *buf, const char *fmt, int n) {
|
|
return r_buf_fcpy_at (b, addr, buf, fmt, n, R_FALSE);
|
|
}
|
|
|
|
R_API int r_buf_write_at(RBuffer *b, ut64 addr, const ut8 *buf, int len) {
|
|
return r_buf_cpy (b, addr, b->buf, buf, len, R_TRUE);
|
|
}
|
|
|
|
R_API int r_buf_fwrite_at (RBuffer *b, ut64 addr, ut8 *buf, const char *fmt, int n) {
|
|
return r_buf_fcpy_at (b, addr, buf, fmt, n, R_TRUE);
|
|
}
|
|
|
|
R_API void r_buf_deinit(RBuffer *b) {
|
|
if (b->mmap) {
|
|
r_file_mmap_free (b->mmap);
|
|
b->mmap = NULL;
|
|
} else {
|
|
free (b->buf);
|
|
}
|
|
}
|
|
|
|
R_API void r_buf_free(struct r_buf_t *b) {
|
|
if (!b) return;
|
|
r_buf_deinit (b);
|
|
free (b);
|
|
}
|