Skip to content

Commit b4626a7

Browse files
Remove the size limit for memory read and write
Eliminate the maximum size restriction for uc_mem_read and uc_mem_write. This change is required to support applications, such as LLVM CFI, that map or unmap memory blocks with sizes equal to or greater than INT_MAX.
1 parent 7b8c63d commit b4626a7

File tree

4 files changed

+46
-54
lines changed

4 files changed

+46
-54
lines changed

include/uc_priv.h

+2-2
Original file line numberDiff line numberDiff line change
@@ -80,10 +80,10 @@ typedef struct {
8080
typedef void (*reg_reset_t)(struct uc_struct *uc);
8181

8282
typedef bool (*uc_write_mem_t)(AddressSpace *as, hwaddr addr,
83-
const uint8_t *buf, int len);
83+
const uint8_t *buf, hwaddr len);
8484

8585
typedef bool (*uc_read_mem_t)(AddressSpace *as, hwaddr addr, uint8_t *buf,
86-
int len);
86+
hwaddr len);
8787

8888
typedef void (*uc_args_void_t)(void *);
8989

include/unicorn/unicorn.h

+7-7
Original file line numberDiff line numberDiff line change
@@ -794,7 +794,7 @@ uc_err uc_reg_read_batch(uc_engine *uc, int *regs, void **vals, int count);
794794
*/
795795
UNICORN_EXPORT
796796
uc_err uc_mem_write(uc_engine *uc, uint64_t address, const void *bytes,
797-
size_t size);
797+
uint64_t size);
798798

799799
/*
800800
Read a range of bytes in memory.
@@ -810,7 +810,7 @@ uc_err uc_mem_write(uc_engine *uc, uint64_t address, const void *bytes,
810810
for detailed error).
811811
*/
812812
UNICORN_EXPORT
813-
uc_err uc_mem_read(uc_engine *uc, uint64_t address, void *bytes, size_t size);
813+
uc_err uc_mem_read(uc_engine *uc, uint64_t address, void *bytes, uint64_t size);
814814

815815
/*
816816
Emulate machine code in a specific duration of time.
@@ -917,7 +917,7 @@ typedef enum uc_prot {
917917
for detailed error).
918918
*/
919919
UNICORN_EXPORT
920-
uc_err uc_mem_map(uc_engine *uc, uint64_t address, size_t size, uint32_t perms);
920+
uc_err uc_mem_map(uc_engine *uc, uint64_t address, uint64_t size, uint32_t perms);
921921

922922
/*
923923
Map existing host memory in for emulation.
@@ -942,7 +942,7 @@ uc_err uc_mem_map(uc_engine *uc, uint64_t address, size_t size, uint32_t perms);
942942
for detailed error).
943943
*/
944944
UNICORN_EXPORT
945-
uc_err uc_mem_map_ptr(uc_engine *uc, uint64_t address, size_t size,
945+
uc_err uc_mem_map_ptr(uc_engine *uc, uint64_t address, uint64_t size,
946946
uint32_t perms, void *ptr);
947947

948948
/*
@@ -965,7 +965,7 @@ uc_err uc_mem_map_ptr(uc_engine *uc, uint64_t address, size_t size,
965965
for detailed error).
966966
*/
967967
UNICORN_EXPORT
968-
uc_err uc_mmio_map(uc_engine *uc, uint64_t address, size_t size,
968+
uc_err uc_mmio_map(uc_engine *uc, uint64_t address, uint64_t size,
969969
uc_cb_mmio_read_t read_cb, void *user_data_read,
970970
uc_cb_mmio_write_t write_cb, void *user_data_write);
971971

@@ -985,7 +985,7 @@ uc_err uc_mmio_map(uc_engine *uc, uint64_t address, size_t size,
985985
for detailed error).
986986
*/
987987
UNICORN_EXPORT
988-
uc_err uc_mem_unmap(uc_engine *uc, uint64_t address, size_t size);
988+
uc_err uc_mem_unmap(uc_engine *uc, uint64_t address, uint64_t size);
989989

990990
/*
991991
Set memory permissions for emulation memory.
@@ -1006,7 +1006,7 @@ uc_err uc_mem_unmap(uc_engine *uc, uint64_t address, size_t size);
10061006
for detailed error).
10071007
*/
10081008
UNICORN_EXPORT
1009-
uc_err uc_mem_protect(uc_engine *uc, uint64_t address, size_t size,
1009+
uc_err uc_mem_protect(uc_engine *uc, uint64_t address, uint64_t size,
10101010
uint32_t perms);
10111011

10121012
/*

qemu/unicorn_common.h

+2-2
Original file line numberDiff line numberDiff line change
@@ -14,13 +14,13 @@ void tcg_exec_init(struct uc_struct *uc, unsigned long tb_size);
1414

1515
// return true on success, false on failure
1616
static inline bool cpu_physical_mem_read(AddressSpace *as, hwaddr addr,
17-
uint8_t *buf, int len)
17+
uint8_t *buf, hwaddr len)
1818
{
1919
return cpu_physical_memory_rw(as, addr, (void *)buf, len, 0);
2020
}
2121

2222
static inline bool cpu_physical_mem_write(AddressSpace *as, hwaddr addr,
23-
const uint8_t *buf, int len)
23+
const uint8_t *buf, hwaddr len)
2424
{
2525
return cpu_physical_memory_rw(as, addr, (void *)buf, len, 1);
2626
}

uc.c

+35-43
Original file line numberDiff line numberDiff line change
@@ -547,14 +547,14 @@ uc_err uc_reg_write(uc_engine *uc, int regid, const void *value)
547547

548548
// check if a memory area is mapped
549549
// this is complicated because an area can overlap adjacent blocks
550-
static bool check_mem_area(uc_engine *uc, uint64_t address, size_t size)
550+
static bool check_mem_area(uc_engine *uc, uint64_t address, uint64_t size)
551551
{
552-
size_t count = 0, len;
552+
uint64_t count = 0, len;
553553

554554
while (count < size) {
555555
MemoryRegion *mr = memory_mapping(uc, address);
556556
if (mr) {
557-
len = (size_t)MIN(size - count, mr->end - address);
557+
len = (uint64_t)MIN(size - count, mr->end - address);
558558
count += len;
559559
address += len;
560560
} else { // this address is not mapped in yet
@@ -566,17 +566,13 @@ static bool check_mem_area(uc_engine *uc, uint64_t address, size_t size)
566566
}
567567

568568
UNICORN_EXPORT
569-
uc_err uc_mem_read(uc_engine *uc, uint64_t address, void *_bytes, size_t size)
569+
uc_err uc_mem_read(uc_engine *uc, uint64_t address, void *_bytes, uint64_t size)
570570
{
571-
size_t count = 0, len;
571+
uint64_t count = 0, len;
572572
uint8_t *bytes = _bytes;
573573

574574
UC_INIT(uc);
575575

576-
// qemu cpu_physical_memory_rw() size is an int
577-
if (size > INT_MAX)
578-
return UC_ERR_ARG;
579-
580576
if (uc->mem_redirect) {
581577
address = uc->mem_redirect(address);
582578
}
@@ -589,7 +585,7 @@ uc_err uc_mem_read(uc_engine *uc, uint64_t address, void *_bytes, size_t size)
589585
while (count < size) {
590586
MemoryRegion *mr = memory_mapping(uc, address);
591587
if (mr) {
592-
len = (size_t)MIN(size - count, mr->end - address);
588+
len = (uint64_t)MIN(size - count, mr->end - address);
593589
if (uc->read_mem(&uc->address_space_memory, address, bytes, len) ==
594590
false) {
595591
break;
@@ -611,17 +607,13 @@ uc_err uc_mem_read(uc_engine *uc, uint64_t address, void *_bytes, size_t size)
611607

612608
UNICORN_EXPORT
613609
uc_err uc_mem_write(uc_engine *uc, uint64_t address, const void *_bytes,
614-
size_t size)
610+
uint64_t size)
615611
{
616-
size_t count = 0, len;
612+
uint64_t count = 0, len;
617613
const uint8_t *bytes = _bytes;
618614

619615
UC_INIT(uc);
620616

621-
// qemu cpu_physical_memory_rw() size is an int
622-
if (size > INT_MAX)
623-
return UC_ERR_ARG;
624-
625617
if (uc->mem_redirect) {
626618
address = uc->mem_redirect(address);
627619
}
@@ -641,7 +633,7 @@ uc_err uc_mem_write(uc_engine *uc, uint64_t address, const void *_bytes,
641633
uc->readonly_mem(mr, false);
642634
}
643635

644-
len = (size_t)MIN(size - count, mr->end - address);
636+
len = (uint64_t)MIN(size - count, mr->end - address);
645637
if (uc->write_mem(&uc->address_space_memory, address, bytes, len) ==
646638
false) {
647639
break;
@@ -956,7 +948,7 @@ static int bsearch_mapped_blocks(const uc_engine *uc, uint64_t address)
956948
}
957949

958950
// find if a memory range overlaps with existing mapped regions
959-
static bool memory_overlap(struct uc_struct *uc, uint64_t begin, size_t size)
951+
static bool memory_overlap(struct uc_struct *uc, uint64_t begin, uint64_t size)
960952
{
961953
unsigned int i;
962954
uint64_t end = begin + size - 1;
@@ -976,7 +968,7 @@ static bool memory_overlap(struct uc_struct *uc, uint64_t begin, size_t size)
976968
}
977969

978970
// common setup/error checking shared between uc_mem_map and uc_mem_map_ptr
979-
static uc_err mem_map(uc_engine *uc, uint64_t address, size_t size,
971+
static uc_err mem_map(uc_engine *uc, uint64_t address, uint64_t size,
980972
uint32_t perms, MemoryRegion *block)
981973
{
982974
MemoryRegion **regions;
@@ -1008,7 +1000,7 @@ static uc_err mem_map(uc_engine *uc, uint64_t address, size_t size,
10081000
return UC_ERR_OK;
10091001
}
10101002

1011-
static uc_err mem_map_check(uc_engine *uc, uint64_t address, size_t size,
1003+
static uc_err mem_map_check(uc_engine *uc, uint64_t address, uint64_t size,
10121004
uint32_t perms)
10131005
{
10141006
if (size == 0) {
@@ -1045,7 +1037,7 @@ static uc_err mem_map_check(uc_engine *uc, uint64_t address, size_t size,
10451037
}
10461038

10471039
UNICORN_EXPORT
1048-
uc_err uc_mem_map(uc_engine *uc, uint64_t address, size_t size, uint32_t perms)
1040+
uc_err uc_mem_map(uc_engine *uc, uint64_t address, uint64_t size, uint32_t perms)
10491041
{
10501042
uc_err res;
10511043

@@ -1065,7 +1057,7 @@ uc_err uc_mem_map(uc_engine *uc, uint64_t address, size_t size, uint32_t perms)
10651057
}
10661058

10671059
UNICORN_EXPORT
1068-
uc_err uc_mem_map_ptr(uc_engine *uc, uint64_t address, size_t size,
1060+
uc_err uc_mem_map_ptr(uc_engine *uc, uint64_t address, uint64_t size,
10691061
uint32_t perms, void *ptr)
10701062
{
10711063
uc_err res;
@@ -1090,7 +1082,7 @@ uc_err uc_mem_map_ptr(uc_engine *uc, uint64_t address, size_t size,
10901082
}
10911083

10921084
UNICORN_EXPORT
1093-
uc_err uc_mmio_map(uc_engine *uc, uint64_t address, size_t size,
1085+
uc_err uc_mmio_map(uc_engine *uc, uint64_t address, uint64_t size,
10941086
uc_cb_mmio_read_t read_cb, void *user_data_read,
10951087
uc_cb_mmio_write_t write_cb, void *user_data_write)
10961088
{
@@ -1117,10 +1109,10 @@ uc_err uc_mmio_map(uc_engine *uc, uint64_t address, size_t size,
11171109
// Generally used in prepartion for splitting a MemoryRegion.
11181110
static uint8_t *copy_region(struct uc_struct *uc, MemoryRegion *mr)
11191111
{
1120-
uint8_t *block = (uint8_t *)g_malloc0((size_t)int128_get64(mr->size));
1112+
uint8_t *block = (uint8_t *)g_malloc0((uint64_t)int128_get64(mr->size));
11211113
if (block != NULL) {
11221114
uc_err err =
1123-
uc_mem_read(uc, mr->addr, block, (size_t)int128_get64(mr->size));
1115+
uc_mem_read(uc, mr->addr, block, (uint64_t)int128_get64(mr->size));
11241116
if (err != UC_ERR_OK) {
11251117
free(block);
11261118
block = NULL;
@@ -1136,10 +1128,10 @@ static uint8_t *copy_region(struct uc_struct *uc, MemoryRegion *mr)
11361128
Note this function may be called recursively.
11371129
*/
11381130
static bool split_mmio_region(struct uc_struct *uc, MemoryRegion *mr,
1139-
uint64_t address, size_t size, bool do_delete)
1131+
uint64_t address, uint64_t size, bool do_delete)
11401132
{
11411133
uint64_t begin, end, chunk_end;
1142-
size_t l_size, r_size, m_size;
1134+
uint64_t l_size, r_size, m_size;
11431135
mmio_cbs backup;
11441136

11451137
chunk_end = address + size;
@@ -1166,7 +1158,7 @@ static bool split_mmio_region(struct uc_struct *uc, MemoryRegion *mr,
11661158
*/
11671159

11681160
// unmap this region first, then do split it later
1169-
if (uc_mem_unmap(uc, mr->addr, (size_t)int128_get64(mr->size)) !=
1161+
if (uc_mem_unmap(uc, mr->addr, (uint64_t)int128_get64(mr->size)) !=
11701162
UC_ERR_OK) {
11711163
return false;
11721164
}
@@ -1180,9 +1172,9 @@ static bool split_mmio_region(struct uc_struct *uc, MemoryRegion *mr,
11801172
}
11811173

11821174
// compute sub region sizes
1183-
l_size = (size_t)(address - begin);
1184-
r_size = (size_t)(end - chunk_end);
1185-
m_size = (size_t)(chunk_end - address);
1175+
l_size = (uint64_t)(address - begin);
1176+
r_size = (uint64_t)(end - chunk_end);
1177+
m_size = (uint64_t)(chunk_end - address);
11861178

11871179
if (l_size > 0) {
11881180
if (uc_mmio_map(uc, begin, l_size, backup.read, backup.user_data_read,
@@ -1225,12 +1217,12 @@ static bool split_mmio_region(struct uc_struct *uc, MemoryRegion *mr,
12251217
// TODO: investigate whether qemu region manipulation functions already offered
12261218
// this capability
12271219
static bool split_region(struct uc_struct *uc, MemoryRegion *mr,
1228-
uint64_t address, size_t size, bool do_delete)
1220+
uint64_t address, uint64_t size, bool do_delete)
12291221
{
12301222
uint8_t *backup;
12311223
uint32_t perms;
12321224
uint64_t begin, end, chunk_end;
1233-
size_t l_size, m_size, r_size;
1225+
uint64_t l_size, m_size, r_size;
12341226
RAMBlock *block = NULL;
12351227
bool prealloc = false;
12361228

@@ -1287,7 +1279,7 @@ static bool split_region(struct uc_struct *uc, MemoryRegion *mr,
12871279
end = mr->end;
12881280

12891281
// unmap this region first, then do split it later
1290-
if (uc_mem_unmap(uc, mr->addr, (size_t)int128_get64(mr->size)) !=
1282+
if (uc_mem_unmap(uc, mr->addr, (uint64_t)int128_get64(mr->size)) !=
12911283
UC_ERR_OK) {
12921284
goto error;
12931285
}
@@ -1308,9 +1300,9 @@ static bool split_region(struct uc_struct *uc, MemoryRegion *mr,
13081300
}
13091301

13101302
// compute sub region sizes
1311-
l_size = (size_t)(address - begin);
1312-
r_size = (size_t)(end - chunk_end);
1313-
m_size = (size_t)(chunk_end - address);
1303+
l_size = (uint64_t)(address - begin);
1304+
r_size = (uint64_t)(end - chunk_end);
1305+
m_size = (uint64_t)(chunk_end - address);
13141306

13151307
// If there are error in any of the below operations, things are too far
13161308
// gone at that point to recover. Could try to remap orignal region, but
@@ -1378,13 +1370,13 @@ static bool split_region(struct uc_struct *uc, MemoryRegion *mr,
13781370
}
13791371

13801372
UNICORN_EXPORT
1381-
uc_err uc_mem_protect(struct uc_struct *uc, uint64_t address, size_t size,
1373+
uc_err uc_mem_protect(struct uc_struct *uc, uint64_t address, uint64_t size,
13821374
uint32_t perms)
13831375
{
13841376
MemoryRegion *mr;
13851377
uint64_t addr = address;
13861378
uint64_t pc;
1387-
size_t count, len;
1379+
uint64_t count, len;
13881380
bool remove_exec = false;
13891381

13901382
UC_INIT(uc);
@@ -1424,7 +1416,7 @@ uc_err uc_mem_protect(struct uc_struct *uc, uint64_t address, size_t size,
14241416
count = 0;
14251417
while (count < size) {
14261418
mr = memory_mapping(uc, addr);
1427-
len = (size_t)MIN(size - count, mr->end - addr);
1419+
len = (uint64_t)MIN(size - count, mr->end - addr);
14281420
if (mr->ram) {
14291421
if (!split_region(uc, mr, addr, len, false)) {
14301422
return UC_ERR_NOMEM;
@@ -1466,11 +1458,11 @@ uc_err uc_mem_protect(struct uc_struct *uc, uint64_t address, size_t size,
14661458
}
14671459

14681460
UNICORN_EXPORT
1469-
uc_err uc_mem_unmap(struct uc_struct *uc, uint64_t address, size_t size)
1461+
uc_err uc_mem_unmap(struct uc_struct *uc, uint64_t address, uint64_t size)
14701462
{
14711463
MemoryRegion *mr;
14721464
uint64_t addr;
1473-
size_t count, len;
1465+
uint64_t count, len;
14741466

14751467
UC_INIT(uc);
14761468

@@ -1504,7 +1496,7 @@ uc_err uc_mem_unmap(struct uc_struct *uc, uint64_t address, size_t size)
15041496
count = 0;
15051497
while (count < size) {
15061498
mr = memory_mapping(uc, addr);
1507-
len = (size_t)MIN(size - count, mr->end - addr);
1499+
len = (uint64_t)MIN(size - count, mr->end - addr);
15081500
if (!mr->ram) {
15091501
if (!split_mmio_region(uc, mr, addr, len, true)) {
15101502
return UC_ERR_NOMEM;

0 commit comments

Comments
 (0)