Skip to content

Commit 089e39a

Browse files
refactor(profiling): call libc directly and eliminate static mut ORIG function pointers
1 parent 0f40b54 commit 089e39a

3 files changed

Lines changed: 13 additions & 71 deletions

File tree

profiling/src/io/got_elf64.rs

Lines changed: 1 addition & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -165,20 +165,13 @@ unsafe fn override_got_entry(
165165
}
166166

167167
trace!(
168-
"Overriding GOT entry for {} at offset {:?} (abs: {:p}) pointing to {:p} (orig function at {:p})",
168+
"Overriding GOT entry for {} at offset {:?} (abs: {:p}) pointing to {:p}",
169169
overwrite.symbol_name,
170170
(*rel).r_offset,
171171
got_entry,
172172
*got_entry,
173-
*overwrite.orig_func
174173
);
175174

176-
// This works for musl based linux distros, but not for libc once
177-
*overwrite.orig_func = libc::dlsym(libc::RTLD_NEXT, name_ptr) as *mut ();
178-
if (*overwrite.orig_func).is_null() {
179-
// libc linux fallback
180-
*overwrite.orig_func = *got_entry;
181-
}
182175
*got_entry = overwrite.new_func;
183176

184177
if is_relro {

profiling/src/io/got_macho.rs

Lines changed: 1 addition & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -514,18 +514,12 @@ unsafe fn rebind_symbols_in_section(
514514
}
515515

516516
trace!(
517-
"Overriding symbol pointer for {} at {:p} pointing to {:p} (orig function at {:p})",
517+
"Overriding symbol pointer for {} at {:p} pointing to {:p}",
518518
overwrite.symbol_name,
519519
slot,
520520
*slot,
521-
*overwrite.orig_func,
522521
);
523522

524-
// Save the original function pointer from the slot before we overwrite it.
525-
// This is written on every matching image (last writer wins), but that's fine:
526-
// by first RINIT all lazy bindings for common libc functions are resolved, so
527-
// every image's slot points to the same canonical address in libSystem.
528-
*overwrite.orig_func = *slot as *mut ();
529523
*slot = overwrite.new_func as *mut c_void;
530524
hooked = true;
531525

profiling/src/io/mod.rs

Lines changed: 11 additions & 56 deletions
Original file line numberDiff line numberDiff line change
@@ -12,7 +12,6 @@ use rustc_hash::FxHashMap;
1212
use std::cell::RefCell;
1313
use std::mem::MaybeUninit;
1414
use std::os::unix::io::RawFd;
15-
use std::ptr;
1615
use std::sync::atomic::{AtomicU64, Ordering};
1716
use std::sync::{Mutex, OnceLock};
1817
use std::time::Instant;
@@ -56,12 +55,8 @@ impl Drop for ErrnoBackup {
5655
pub struct GotSymbolOverwrite {
5756
pub symbol_name: &'static str,
5857
pub new_func: *mut (),
59-
pub orig_func: *mut *mut (),
6058
}
6159

62-
static mut ORIG_POLL: unsafe extern "C" fn(*mut libc::pollfd, libc::nfds_t, c_int) -> i32 =
63-
libc::poll;
64-
6560
fn eval_poll_events(ret: i32, fds: &[libc::pollfd]) -> (bool, bool) {
6661
let mut has_read = false;
6762
let mut has_write = false;
@@ -102,7 +97,7 @@ unsafe extern "C" fn observed_poll(
10297
timeout: c_int,
10398
) -> i32 {
10499
let start = Instant::now();
105-
let ret = ORIG_POLL(fds, nfds, timeout);
100+
let ret = libc::poll(fds, nfds, timeout);
106101
let _errno_backup = ErrnoBackup::new();
107102
let duration = start.elapsed();
108103

@@ -128,16 +123,14 @@ unsafe extern "C" fn observed_poll(
128123
ret
129124
}
130125

131-
static mut ORIG_RECV: unsafe extern "C" fn(c_int, *mut c_void, usize, c_int) -> isize = libc::recv;
132-
133126
unsafe extern "C" fn observed_recv(
134127
socket: c_int,
135128
buf: *mut c_void,
136129
length: usize,
137130
flags: c_int,
138131
) -> isize {
139132
let start = Instant::now();
140-
let len = ORIG_RECV(socket, buf, length, flags);
133+
let len = libc::recv(socket, buf, length, flags);
141134
let _errno_backup = ErrnoBackup::new();
142135
let duration = start.elapsed();
143136

@@ -156,16 +149,13 @@ unsafe extern "C" fn observed_recv(
156149
len
157150
}
158151

159-
static mut ORIG_RECVMSG: unsafe extern "C" fn(c_int, *mut libc::msghdr, c_int) -> isize =
160-
libc::recvmsg;
161-
162152
unsafe extern "C" fn observed_recvmsg(
163153
socket: c_int,
164154
msg: *mut libc::msghdr,
165155
flags: c_int,
166156
) -> isize {
167157
let start = Instant::now();
168-
let len = ORIG_RECVMSG(socket, msg, flags);
158+
let len = libc::recvmsg(socket, msg, flags);
169159
let _errno_backup = ErrnoBackup::new();
170160
let duration = start.elapsed();
171161

@@ -184,15 +174,6 @@ unsafe extern "C" fn observed_recvmsg(
184174
len
185175
}
186176

187-
static mut ORIG_RECVFROM: unsafe extern "C" fn(
188-
c_int,
189-
*mut c_void,
190-
usize,
191-
c_int,
192-
*mut libc::sockaddr,
193-
*mut libc::socklen_t,
194-
) -> isize = libc::recvfrom;
195-
196177
unsafe extern "C" fn observed_recvfrom(
197178
socket: c_int,
198179
buf: *mut c_void,
@@ -202,7 +183,7 @@ unsafe extern "C" fn observed_recvfrom(
202183
address_len: *mut libc::socklen_t,
203184
) -> isize {
204185
let start = Instant::now();
205-
let len = ORIG_RECVFROM(socket, buf, length, flags, address, address_len);
186+
let len = libc::recvfrom(socket, buf, length, flags, address, address_len);
206187
let _errno_backup = ErrnoBackup::new();
207188
let duration = start.elapsed();
208189

@@ -221,16 +202,14 @@ unsafe extern "C" fn observed_recvfrom(
221202
len
222203
}
223204

224-
static mut ORIG_SEND: unsafe extern "C" fn(c_int, *const c_void, usize, c_int) -> isize =
225-
libc::send;
226205
unsafe extern "C" fn observed_send(
227206
socket: c_int,
228207
buf: *const c_void,
229208
length: usize,
230209
flags: c_int,
231210
) -> isize {
232211
let start = Instant::now();
233-
let len = ORIG_SEND(socket, buf, length, flags);
212+
let len = libc::send(socket, buf, length, flags);
234213
let _errno_backup = ErrnoBackup::new();
235214
let duration = start.elapsed();
236215

@@ -249,15 +228,13 @@ unsafe extern "C" fn observed_send(
249228
len
250229
}
251230

252-
static mut ORIG_SENDMSG: unsafe extern "C" fn(c_int, *const libc::msghdr, c_int) -> isize =
253-
libc::sendmsg;
254231
unsafe extern "C" fn observed_sendmsg(
255232
socket: c_int,
256233
msg: *const libc::msghdr,
257234
flags: c_int,
258235
) -> isize {
259236
let start = Instant::now();
260-
let len = ORIG_SENDMSG(socket, msg, flags);
237+
let len = libc::sendmsg(socket, msg, flags);
261238
let _errno_backup = ErrnoBackup::new();
262239
let duration = start.elapsed();
263240

@@ -276,20 +253,14 @@ unsafe extern "C" fn observed_sendmsg(
276253
len
277254
}
278255

279-
static mut ORIG_FWRITE: unsafe extern "C" fn(
280-
*const c_void,
281-
usize,
282-
usize,
283-
*mut libc::FILE,
284-
) -> usize = libc::fwrite;
285256
unsafe extern "C" fn observed_fwrite(
286257
ptr: *const c_void,
287258
size: usize,
288259
nobj: usize,
289260
stream: *mut libc::FILE,
290261
) -> usize {
291262
let start = Instant::now();
292-
let len = ORIG_FWRITE(ptr, size, nobj, stream);
263+
let len = libc::fwrite(ptr, size, nobj, stream);
293264
let _errno_backup = ErrnoBackup::new();
294265
let duration = start.elapsed();
295266

@@ -307,10 +278,9 @@ unsafe extern "C" fn observed_fwrite(
307278
len
308279
}
309280

310-
static mut ORIG_WRITE: unsafe extern "C" fn(c_int, *const c_void, usize) -> isize = libc::write;
311281
unsafe extern "C" fn observed_write(fd: c_int, buf: *const c_void, count: usize) -> isize {
312282
let start = Instant::now();
313-
let len = ORIG_WRITE(fd, buf, count);
283+
let len = libc::write(fd, buf, count);
314284
let _errno_backup = ErrnoBackup::new();
315285
let duration = start.elapsed();
316286

@@ -347,8 +317,6 @@ unsafe extern "C" fn observed_write(fd: c_int, buf: *const c_void, count: usize)
347317
len
348318
}
349319

350-
static mut ORIG_FREAD: unsafe extern "C" fn(*mut c_void, usize, usize, *mut libc::FILE) -> usize =
351-
libc::fread;
352320
// So far there seems to be only one situation where a file is read using `fread()` instead of
353321
// `read()` in PHP and that is when compiling a PHP file, triggered by it being the start file or a
354322
// userland call to `include()`/`require()` functions.
@@ -359,7 +327,7 @@ unsafe extern "C" fn observed_fread(
359327
stream: *mut libc::FILE,
360328
) -> usize {
361329
let start = Instant::now();
362-
let len = ORIG_FREAD(ptr, size, nobj, stream);
330+
let len = libc::fread(ptr, size, nobj, stream);
363331
let _errno_backup = ErrnoBackup::new();
364332
let duration = start.elapsed();
365333

@@ -377,10 +345,9 @@ unsafe extern "C" fn observed_fread(
377345
len
378346
}
379347

380-
static mut ORIG_READ: unsafe extern "C" fn(c_int, *mut c_void, usize) -> isize = libc::read;
381348
unsafe extern "C" fn observed_read(fd: c_int, buf: *mut c_void, count: usize) -> isize {
382349
let start = Instant::now();
383-
let len = ORIG_READ(fd, buf, count);
350+
let len = libc::read(fd, buf, count);
384351
let _errno_backup = ErrnoBackup::new();
385352
let duration = start.elapsed();
386353

@@ -415,10 +382,9 @@ unsafe extern "C" fn observed_read(fd: c_int, buf: *mut c_void, count: usize) ->
415382
len
416383
}
417384

418-
static mut ORIG_CLOSE: unsafe extern "C" fn(i32) -> i32 = libc::close;
419385
/// The sole purpose of this function is to remove the `fd` from the `FD_CACHE`
420386
unsafe extern "C" fn observed_close(fd: i32) -> i32 {
421-
let ret = ORIG_CLOSE(fd);
387+
let ret = libc::close(fd);
422388
let _errno_backup = ErrnoBackup::new();
423389
let cache = FD_CACHE.get_or_init(|| Mutex::new(FxHashMap::default()));
424390
let mut cache = cache.lock().unwrap();
@@ -668,57 +634,46 @@ pub fn io_prof_first_rinit() {
668634
GotSymbolOverwrite {
669635
symbol_name: "recv",
670636
new_func: observed_recv as *mut (),
671-
orig_func: ptr::addr_of_mut!(ORIG_RECV) as *mut _ as *mut *mut (),
672637
},
673638
GotSymbolOverwrite {
674639
symbol_name: "recvmsg",
675640
new_func: observed_recvmsg as *mut (),
676-
orig_func: ptr::addr_of_mut!(ORIG_RECVMSG) as *mut _ as *mut *mut (),
677641
},
678642
GotSymbolOverwrite {
679643
symbol_name: "recvfrom",
680644
new_func: observed_recvfrom as *mut (),
681-
orig_func: ptr::addr_of_mut!(ORIG_RECVFROM) as *mut _ as *mut *mut (),
682645
},
683646
GotSymbolOverwrite {
684647
symbol_name: "send",
685648
new_func: observed_send as *mut (),
686-
orig_func: ptr::addr_of_mut!(ORIG_SEND) as *mut _ as *mut *mut (),
687649
},
688650
GotSymbolOverwrite {
689651
symbol_name: "sendmsg",
690652
new_func: observed_sendmsg as *mut (),
691-
orig_func: ptr::addr_of_mut!(ORIG_SENDMSG) as *mut _ as *mut *mut (),
692653
},
693654
GotSymbolOverwrite {
694655
symbol_name: "write",
695656
new_func: observed_write as *mut (),
696-
orig_func: ptr::addr_of_mut!(ORIG_WRITE) as *mut _ as *mut *mut (),
697657
},
698658
GotSymbolOverwrite {
699659
symbol_name: "read",
700660
new_func: observed_read as *mut (),
701-
orig_func: ptr::addr_of_mut!(ORIG_READ) as *mut _ as *mut *mut (),
702661
},
703662
GotSymbolOverwrite {
704663
symbol_name: "fwrite",
705664
new_func: observed_fwrite as *mut (),
706-
orig_func: ptr::addr_of_mut!(ORIG_FWRITE) as *mut _ as *mut *mut (),
707665
},
708666
GotSymbolOverwrite {
709667
symbol_name: "fread",
710668
new_func: observed_fread as *mut (),
711-
orig_func: ptr::addr_of_mut!(ORIG_FREAD) as *mut _ as *mut *mut (),
712669
},
713670
GotSymbolOverwrite {
714671
symbol_name: "close",
715672
new_func: observed_close as *mut (),
716-
orig_func: ptr::addr_of_mut!(ORIG_CLOSE) as *mut _ as *mut *mut (),
717673
},
718674
GotSymbolOverwrite {
719675
symbol_name: "poll",
720676
new_func: observed_poll as *mut (),
721-
orig_func: ptr::addr_of_mut!(ORIG_POLL) as *mut _ as *mut *mut (),
722677
},
723678
];
724679
#[cfg(target_os = "linux")]

0 commit comments

Comments
 (0)