summaryrefslogtreecommitdiff
path: root/libmisc/intercept.c
blob: fcf2490e967ec79bd473ef268282d1b78b4833cf (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
/* libmisc/intercept.c - Interceptable ("weak") functions
 *
 * Copyright (C) 2024-2025  Luke T. Shumaker <lukeshu@lukeshu.com>
 * SPDX-License-Identifier: AGPL-3.0-or-later
 */

#include <stdint.h> /* for uintptr_t */
#include <stdio.h>  /* for fputc(), stderr */
#include <stdlib.h> /* for abort(), aligned_alloc(), realloc(), free(), random() */
#include <string.h> /* for memcpy() */

#include <libmisc/macro.h>

#include <libmisc/_intercept.h>

[[gnu::weak]]
void __lm_putchar(unsigned char c) {
	(void)fputc(c, stderr);
}

[[gnu::weak]]
void __lm_abort(void) {
	abort();
}

[[gnu::weak]]
void *__lm_heap_aligned_realloc(void *ptr, size_t align, size_t size) {
	if (!size)
		size = 1;
	size = LM_ROUND_UP(size, align);
	if (!ptr) {
		void *ret = aligned_alloc(align, size);
		memset(ret, 0, size);
		return ret;
	}
	ptr = realloc(ptr, size);
	if ((uintptr_t)ptr % align) {
		void *new = aligned_alloc(align, size);
		memcpy(new, ptr, size);
		free(ptr);
		ptr = new;
	}
	return ptr;
}

[[gnu::weak]]
void __lm_heap_free(void *ptr) {
	free(ptr);
}

[[gnu::weak]]
void __lm_heap_take(void *) {}

[[gnu::weak]]
uint32_t __lm_rand_uint31(void) {
	return (uint32_t)random();
}

[[gnu::weak]]
uint32_t __lm_rand_uint32(void) {
	return __lm_rand_uint31() << 31 | __lm_rand_uint31();
}

[[gnu::weak]]
uint64_t __lm_rand_uint62(void) {
	return (((uint64_t)__lm_rand_uint31()) << 31) | __lm_rand_uint31();
}

[[gnu::weak]]
uint64_t __lm_rand_uint64(void) {
	return (((uint64_t)__lm_rand_uint31()) << 62) | (((uint64_t)__lm_rand_uint31()) << 31) | __lm_rand_uint31();
}

[[gnu::weak]]
uint64_t __lm_rand_uint63(void) {
	return __lm_rand_uint64() & UINT64_C(0x7fffffffffffffff);
}