Skip to content

Commit b250190

Browse files
committed
add AFL++ IJON functionality
1 parent dd35346 commit b250190

File tree

1 file changed

+190
-1
lines changed

1 file changed

+190
-1
lines changed

afl/src/lib.rs

Lines changed: 190 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -9,7 +9,7 @@ use std::env;
99
use std::io::{self, Read};
1010
use std::panic;
1111

12-
// those functions are provided by the afl-llvm-rt static library
12+
// those functions are provided by the afl-compiler-rt static library
1313
unsafe extern "C" {
1414
fn __afl_persistent_loop(counter: usize) -> isize;
1515
fn __afl_manual_init();
@@ -18,6 +18,195 @@ unsafe extern "C" {
1818
static __afl_fuzz_ptr: *const u8;
1919
}
2020

21+
// AFL++ IJON functions in afl-compiler-rt
22+
unsafe extern "C" {
23+
pub fn ijon_max(addr: u32, val: u64);
24+
pub fn ijon_min(addr: u32, val: u64);
25+
pub fn ijon_set(addr: u32, val: u32);
26+
pub fn ijon_inc(addr: u32, val: u32);
27+
pub fn ijon_xor_state(val: u32);
28+
pub fn ijon_reset_state();
29+
pub fn ijon_simple_hash(x: u64) -> u64;
30+
pub fn ijon_hashint(old: u32, val: u32) -> u32;
31+
pub fn ijon_hashstr(old: u32, val: *const u8) -> u32;
32+
pub fn ijon_hashmen(old: u32, val: *const u8, len: usize) -> u32;
33+
pub fn ijon_hashstack_backtrace() -> u32;
34+
pub fn ijon_hashstack() -> u32;
35+
pub fn ijon_strdist(a: *const u8, b: *const u8) -> u32;
36+
pub fn ijon_memdist(a: *const u8, b: *const u8, len: usize) -> u32;
37+
pub fn ijon_max_variadic(addr: u32, ...);
38+
pub fn ijon_min_variadic(addr: u32, ...);
39+
}
40+
41+
#[macro_export]
42+
macro_rules! ijon_inc {
43+
($x:expr) => {{
44+
use std::sync::atomic::{AtomicU32, Ordering};
45+
static LOC_CACHE: AtomicU32 = AtomicU32::new(0);
46+
let mut loc = LOC_CACHE.load(Ordering::Relaxed);
47+
if loc == 0 {
48+
let new_val = ijon_hashstr(line!(), file!());
49+
LOC_CACHE.store(new_val, Ordering::Relaxed);
50+
loc = new_val;
51+
}
52+
ijon_inc(loc, $x);
53+
}};
54+
}
55+
56+
#[macro_export]
57+
macro_rules! ijon_max {
58+
($($x:expr),+ $(,)?) => {{
59+
use std::sync::atomic::{AtomicU32, Ordering};
60+
static LOC_CACHE: AtomicU32 = AtomicU32::new(0);
61+
let mut loc = LOC_CACHE.load(Ordering::Relaxed);
62+
if loc == 0 {
63+
let new_val = ijon_hashstr(line!(), file!());
64+
LOC_CACHE.store(new_val, Ordering::Relaxed);
65+
loc = new_val;
66+
}
67+
ijon_max_variadic(loc, $($x),+, 0u64);
68+
}};
69+
}
70+
71+
#[macro_export]
72+
macro_rules! ijon_min {
73+
($($x:expr),+ $(,)?) => {{
74+
use std::sync::atomic::{AtomicU32, Ordering};
75+
static LOC_CACHE: AtomicU32 = AtomicU32::new(0);
76+
let mut loc = LOC_CACHE.load(Ordering::Relaxed);
77+
if loc == 0 {
78+
let new_val = ijon_hashstr(line!(), file!());
79+
LOC_CACHE.store(new_val, Ordering::Relaxed);
80+
loc = new_val;
81+
}
82+
ijon_min_variadic(loc, $($x),+, 0u64);
83+
}};
84+
}
85+
86+
#[macro_export]
87+
macro_rules! ijon_set {
88+
($x:expr) => {{
89+
use std::sync::atomic::{AtomicU32, Ordering};
90+
static LOC_CACHE: AtomicU32 = AtomicU32::new(0);
91+
let mut loc = LOC_CACHE.load(Ordering::Relaxed);
92+
if loc == 0 {
93+
let new_val = ijon_hashstr(line!(), file!());
94+
LOC_CACHE.store(new_val, Ordering::Relaxed);
95+
loc = new_val;
96+
}
97+
ijon_set(loc, $x);
98+
}};
99+
}
100+
101+
#[macro_export]
102+
macro_rules! ijon_state {
103+
($n:expr) => {
104+
ijon_xor_state($n)
105+
};
106+
}
107+
108+
#[macro_export]
109+
macro_rules! ijon_ctx {
110+
($x:expr) => {{
111+
let hash = ijon_hashstr(line!(), file!());
112+
ijon_xor_state(hash);
113+
let temp = $x;
114+
ijon_xor_state(hash);
115+
temp
116+
}};
117+
}
118+
119+
#[macro_export]
120+
macro_rules! ijon_max_at {
121+
($addr:expr, $x:expr) => {
122+
ijon_max($addr, $x)
123+
};
124+
}
125+
126+
#[macro_export]
127+
macro_rules! ijon_min_at {
128+
($addr:expr, $x:expr) => {
129+
ijon_min($addr, $x)
130+
};
131+
}
132+
133+
#[macro_export]
134+
macro_rules! _ijon_abs_dist {
135+
($x:expr, $y:expr) => {
136+
if $x < $y { $y - $x } else { $x - $y }
137+
};
138+
}
139+
140+
#[macro_export]
141+
macro_rules! ijon_bits {
142+
($x:expr) => {
143+
ijon_set(ijon_hashint(
144+
ijon_hashstack(),
145+
if $x == 0 {
146+
0
147+
} else {
148+
$x.leading_zeros() as u32
149+
},
150+
))
151+
};
152+
}
153+
154+
#[macro_export]
155+
macro_rules! ijon_strdist {
156+
($x:expr, $y:expr) => {
157+
ijon_set(ijon_hashint(ijon_hashstack(), ijon_strdist($x, $y)))
158+
};
159+
}
160+
161+
#[macro_export]
162+
macro_rules! ijon_dist {
163+
($x:expr, $y:expr) => {
164+
ijon_set(ijon_hashint(
165+
ijon_hashstack(),
166+
$crate::_ijon_abs_dist!($x, $y),
167+
))
168+
};
169+
}
170+
171+
#[macro_export]
172+
macro_rules! ijon_cmp {
173+
($x:expr, $y:expr) => {
174+
ijon_inc(ijon_hashint(ijon_hashstack(), ($x ^ $y).count_ones()))
175+
};
176+
}
177+
178+
#[macro_export]
179+
macro_rules! ijon_stack_max {
180+
($x:expr) => {{
181+
use std::sync::atomic::{AtomicU32, Ordering};
182+
static LOC: AtomicU32 = AtomicU32::new(0);
183+
let mut loc = LOC.load(Ordering::Relaxed);
184+
if loc == 0 {
185+
let new_val = ijon_hashstr(line!(), file!());
186+
LOC.store(new_val, Ordering::Relaxed);
187+
loc = new_val;
188+
}
189+
ijon_max(ijon_hashint(loc, ijon_hashstack()), $x);
190+
}};
191+
}
192+
193+
#[macro_export]
194+
macro_rules! ijon_stack_min {
195+
($x:expr) => {{
196+
use std::sync::atomic::{AtomicU32, Ordering};
197+
static LOC: AtomicU32 = AtomicU32::new(0);
198+
let mut loc = LOC.load(Ordering::Relaxed);
199+
if loc == 0 {
200+
let new_val = ijon_hashstr(line!(), file!());
201+
LOC.store(new_val, Ordering::Relaxed);
202+
loc = new_val;
203+
}
204+
ijon_min(ijon_hashint(loc, ijon_hashstack()), $x);
205+
}};
206+
}
207+
208+
// end if AFL++ IJON functions
209+
21210
#[allow(non_upper_case_globals)]
22211
#[doc(hidden)]
23212
#[unsafe(no_mangle)]

0 commit comments

Comments
 (0)