Skip to content

Commit 2611835

Browse files
authored
[unsafe] Allow taking the address of malloc, free, realloc, calloc, strdup (#136)
1 parent 863c56b commit 2611835

11 files changed

Lines changed: 223 additions & 99 deletions

File tree

libcc2rs/src/alloc.rs

Lines changed: 37 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,37 @@
1+
// Copyright (c) 2022-present INESC-ID.
2+
// Distributed under the MIT license that can be found in the LICENSE file.
3+
4+
/// # Safety
5+
///
6+
/// Same contract as C's `malloc`.
7+
pub unsafe fn malloc_unsafe(a0: u64) -> *mut libc::c_void {
8+
unsafe { libc::malloc(a0 as libc::size_t) }
9+
}
10+
11+
/// # Safety
12+
///
13+
/// Same contract as C's `free`.
14+
pub unsafe fn free_unsafe(a0: *mut libc::c_void) {
15+
unsafe { libc::free(a0) }
16+
}
17+
18+
/// # Safety
19+
///
20+
/// Same contract as C's `realloc`.
21+
pub unsafe fn realloc_unsafe(a0: *mut libc::c_void, a1: u64) -> *mut libc::c_void {
22+
unsafe { libc::realloc(a0, a1 as libc::size_t) }
23+
}
24+
25+
/// # Safety
26+
///
27+
/// Same contract as C's `calloc`.
28+
pub unsafe fn calloc_unsafe(a0: u64, a1: u64) -> *mut libc::c_void {
29+
unsafe { libc::calloc(a0 as libc::size_t, a1 as libc::size_t) }
30+
}
31+
32+
/// # Safety
33+
///
34+
/// Same contract as C's `strdup`.
35+
pub unsafe fn strdup_unsafe(a0: *const u8) -> *mut u8 {
36+
unsafe { libc::strdup(a0 as *const libc::c_char) as *mut u8 }
37+
}

libcc2rs/src/lib.rs

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -22,6 +22,9 @@ pub use rules::*;
2222
mod io;
2323
pub use io::*;
2424

25+
mod alloc;
26+
pub use alloc::*;
27+
2528
mod iterators;
2629
pub use iterators::*;
2730

rules/cstdlib/ir_unsafe.json

Lines changed: 8 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -9,7 +9,7 @@
99
"f2": {
1010
"body": [
1111
{
12-
"text": "libc::free("
12+
"text": "libcc2rs::free_unsafe("
1313
},
1414
{
1515
"placeholder": {
@@ -31,7 +31,7 @@
3131
"f3": {
3232
"body": [
3333
{
34-
"text": "libc::malloc("
34+
"text": "libcc2rs::malloc_unsafe("
3535
},
3636
{
3737
"placeholder": {
@@ -40,7 +40,7 @@
4040
}
4141
},
4242
{
43-
"text": " as ::libc::size_t)"
43+
"text": ")"
4444
}
4545
],
4646
"params": {
@@ -56,7 +56,7 @@
5656
"f4": {
5757
"body": [
5858
{
59-
"text": "libc::realloc("
59+
"text": "libcc2rs::realloc_unsafe("
6060
},
6161
{
6262
"placeholder": {
@@ -74,7 +74,7 @@
7474
}
7575
},
7676
{
77-
"text": " as ::libc::size_t)"
77+
"text": ")"
7878
}
7979
],
8080
"params": {
@@ -94,7 +94,7 @@
9494
"f5": {
9595
"body": [
9696
{
97-
"text": "libc::calloc("
97+
"text": "libcc2rs::calloc_unsafe("
9898
},
9999
{
100100
"placeholder": {
@@ -103,7 +103,7 @@
103103
}
104104
},
105105
{
106-
"text": " as ::libc::size_t, "
106+
"text": ", "
107107
},
108108
{
109109
"placeholder": {
@@ -112,7 +112,7 @@
112112
}
113113
},
114114
{
115-
"text": " as ::libc::size_t)"
115+
"text": ")"
116116
}
117117
],
118118
"params": {

rules/cstdlib/tgt_unsafe.rs

Lines changed: 4 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -6,19 +6,19 @@ unsafe fn f1() {
66
}
77

88
unsafe fn f2(a0: *mut ::libc::c_void) {
9-
libc::free(a0)
9+
libcc2rs::free_unsafe(a0)
1010
}
1111

1212
unsafe fn f3(a0: u64) -> *mut ::libc::c_void {
13-
libc::malloc(a0 as ::libc::size_t)
13+
libcc2rs::malloc_unsafe(a0)
1414
}
1515

1616
unsafe fn f4(a0: *mut ::libc::c_void, a1: u64) -> *mut ::libc::c_void {
17-
libc::realloc(a0, a1 as ::libc::size_t)
17+
libcc2rs::realloc_unsafe(a0, a1)
1818
}
1919

2020
unsafe fn f5(a0: u64, a1: u64) -> *mut ::libc::c_void {
21-
libc::calloc(a0 as ::libc::size_t, a1 as ::libc::size_t)
21+
libcc2rs::calloc_unsafe(a0, a1)
2222
}
2323

2424
unsafe fn f6(a0: *const u8) -> *mut u8 {

rules/cstring/ir_unsafe.json

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -283,7 +283,7 @@
283283
"f15": {
284284
"body": [
285285
{
286-
"text": "libc::strdup("
286+
"text": "libcc2rs::strdup_unsafe("
287287
},
288288
{
289289
"placeholder": {
@@ -292,7 +292,7 @@
292292
}
293293
},
294294
{
295-
"text": " as *const i8) as *mut u8"
295+
"text": ")"
296296
}
297297
],
298298
"params": {

rules/cstring/tgt_unsafe.rs

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -77,7 +77,7 @@ unsafe fn f14(a0: *mut u8, a1: i32) -> *mut u8 {
7777
}
7878

7979
unsafe fn f15(a0: *const u8) -> *mut u8 {
80-
libc::strdup(a0 as *const i8) as *mut u8
80+
libcc2rs::strdup_unsafe(a0)
8181
}
8282

8383
unsafe fn f16(a0: *const u8, a1: *const u8) -> u64 {

tests/unit/malloc_realloc_free.c

Lines changed: 40 additions & 28 deletions
Original file line numberDiff line numberDiff line change
@@ -2,37 +2,49 @@
22
#include <assert.h>
33
#include <stdlib.h>
44

5-
int main() {
6-
int *p = (int *)malloc(sizeof(int));
7-
*p = 42;
8-
assert(*p == 42);
9-
free(p);
5+
#define ALLOC_TESTS(MALLOC, FREE, REALLOC, CALLOC) \
6+
do { \
7+
int *p = (int *)MALLOC(sizeof(int)); \
8+
*p = 42; \
9+
assert(*p == 42); \
10+
FREE(p); \
11+
\
12+
int *arr = (int *)MALLOC(4 * sizeof(int)); \
13+
for (int i = 0; i < 4; i++) { \
14+
arr[i] = i * 10; \
15+
} \
16+
assert(arr[0] == 0); \
17+
assert(arr[3] == 30); \
18+
FREE(arr); \
19+
\
20+
int *grow = (int *)MALLOC(2 * sizeof(int)); \
21+
grow[0] = 1; \
22+
grow[1] = 2; \
23+
grow = (int *)REALLOC(grow, 4 * sizeof(int)); \
24+
grow[2] = 3; \
25+
grow[3] = 4; \
26+
assert(grow[0] == 1); \
27+
assert(grow[1] == 2); \
28+
assert(grow[2] == 3); \
29+
assert(grow[3] == 4); \
30+
FREE(grow); \
31+
\
32+
int *zeros = (int *)CALLOC(4, sizeof(int)); \
33+
for (int i = 0; i < 4; i++) { \
34+
assert(zeros[i] == 0); \
35+
} \
36+
FREE(zeros); \
37+
} while (0)
1038

11-
int *arr = (int *)malloc(4 * sizeof(int));
12-
for (int i = 0; i < 4; i++) {
13-
arr[i] = i * 10;
14-
}
15-
assert(arr[0] == 0);
16-
assert(arr[3] == 30);
17-
free(arr);
39+
int main() {
40+
ALLOC_TESTS(malloc, free, realloc, calloc);
1841

19-
int *grow = (int *)malloc(2 * sizeof(int));
20-
grow[0] = 1;
21-
grow[1] = 2;
22-
grow = (int *)realloc(grow, 4 * sizeof(int));
23-
grow[2] = 3;
24-
grow[3] = 4;
25-
assert(grow[0] == 1);
26-
assert(grow[1] == 2);
27-
assert(grow[2] == 3);
28-
assert(grow[3] == 4);
29-
free(grow);
42+
void *(*pmalloc)(size_t) = malloc;
43+
void (*pfree)(void *) = free;
44+
void *(*prealloc)(void *, size_t) = realloc;
45+
void *(*pcalloc)(size_t, size_t) = calloc;
3046

31-
int *zeros = (int *)calloc(4, sizeof(int));
32-
for (int i = 0; i < 4; i++) {
33-
assert(zeros[i] == 0);
34-
}
35-
free(zeros);
47+
ALLOC_TESTS(pmalloc, pfree, prealloc, pcalloc);
3648

3749
return 0;
3850
}

tests/unit/out/unsafe/cstring.rs

Lines changed: 6 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -267,30 +267,30 @@ pub unsafe fn test_strrchr_9() {
267267
);
268268
}
269269
pub unsafe fn test_strdup_10() {
270-
let mut d: *mut u8 = libc::strdup(b"hello\0".as_ptr() as *const i8) as *mut u8;
270+
let mut d: *mut u8 = libcc2rs::strdup_unsafe(b"hello\0".as_ptr());
271271
assert!(!((d).is_null()));
272272
assert!(
273273
((libc::strcmp(
274274
(d).cast_const() as *const i8,
275275
b"hello\0".as_ptr() as *const i8
276276
)) == (0))
277277
);
278-
libc::free((d as *mut u8 as *mut ::libc::c_void));
278+
libcc2rs::free_unsafe((d as *mut u8 as *mut ::libc::c_void));
279279
let mut p: *const u8 = b"world\0".as_ptr();
280280
let mut buf: [u8; 4] = [('a' as u8), ('b' as u8), ('c' as u8), ('\0' as u8)];
281-
let mut d2: *mut u8 = libc::strdup(p as *const i8) as *mut u8;
281+
let mut d2: *mut u8 = libcc2rs::strdup_unsafe(p);
282282
assert!(!((d2).is_null()));
283283
assert!(((libc::strcmp((d2).cast_const() as *const i8, p as *const i8)) == (0)));
284-
libc::free((d2 as *mut u8 as *mut ::libc::c_void));
285-
let mut d3: *mut u8 = libc::strdup((buf.as_mut_ptr()).cast_const() as *const i8) as *mut u8;
284+
libcc2rs::free_unsafe((d2 as *mut u8 as *mut ::libc::c_void));
285+
let mut d3: *mut u8 = libcc2rs::strdup_unsafe((buf.as_mut_ptr()).cast_const());
286286
assert!(!((d3).is_null()));
287287
assert!(
288288
((libc::strcmp(
289289
(d3).cast_const() as *const i8,
290290
(buf.as_mut_ptr()).cast_const() as *const i8
291291
)) == (0))
292292
);
293-
libc::free((d3 as *mut u8 as *mut ::libc::c_void));
293+
libcc2rs::free_unsafe((d3 as *mut u8 as *mut ::libc::c_void));
294294
}
295295
pub unsafe fn test_strcspn_11() {
296296
assert!(

tests/unit/out/unsafe/errno.rs

Lines changed: 2 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -17,11 +17,10 @@ pub unsafe fn test_errno_0() {
1717
}
1818
pub unsafe fn test_errno_preserved_across_strdup_1() {
1919
(*libcc2rs::cpp2rust_errno()) = 99;
20-
let mut d: *mut u8 =
21-
libc::strdup((b"hello\0".as_ptr().cast_mut()).cast_const() as *const i8) as *mut u8;
20+
let mut d: *mut u8 = libcc2rs::strdup_unsafe((b"hello\0".as_ptr().cast_mut()).cast_const());
2221
assert!((((!((d).is_null())) as i32) != 0));
2322
assert!(((((*libcc2rs::cpp2rust_errno()) == (99)) as i32) != 0));
24-
libc::free((d as *mut u8 as *mut ::libc::c_void));
23+
libcc2rs::free_unsafe((d as *mut u8 as *mut ::libc::c_void));
2524
(*libcc2rs::cpp2rust_errno()) = 0;
2625
}
2726
pub unsafe fn test_errno_from_fseek_2() {

0 commit comments

Comments
 (0)