-
Notifications
You must be signed in to change notification settings - Fork 31
/
Copy pathenv.c
152 lines (120 loc) · 2.58 KB
/
env.c
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
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
#include "config.h"
#include "types.h"
#include "memory.h"
#include <stdarg.h>
#ifdef __KERNEL__
#include <linux/kernel.h>
#include <linux/module.h>
#include <linux/uaccess.h>
#include <linux/slab.h>
#ifdef USE_KALLSYMS
#include <linux/kallsyms.h>
#endif
MODULE_LICENSE("GPL");
#else
#include <stdio.h>
#include <malloc.h>
#include <string.h>
/* for dlsym() */
#define __USE_GNU
#include <dlfcn.h>
#endif
#include "env.h"
#include "memory.h"
/* allocate memory */
void *memory_alloc(word size)
{
#ifdef __KERNEL__
/* we don't know in which context we run the we want the allocation to be atomic */
return kmalloc(size, GFP_ATOMIC);
#else
return malloc(size);
#endif
}
/* free memory */
void memory_free(void *mem)
{
#ifdef __KERNEL__
kfree(mem);
#else
free(mem);
#endif
}
/* copy data from inside memory to inside memory */
void *memory_copy(void *dst, const void *src, word len)
{
return memcpy(dst, src, len);
}
/* copy data from outside memory to inside memory */
int memory_copy_from_outside(void *dst, const void *src, word len)
{
#ifdef __KERNEL__
return safe_memory_copy(dst, src, len, ADDR_INSIDE, ADDR_OUTSIDE, 0, 0);
#else
memcpy(dst, src, len);
return 0;
#endif
}
/* copy data from inside memory to outside memory */
int memory_copy_to_outside(void *dst, const void *src, word len)
{
#ifdef __KERNEL__
return safe_memory_copy(dst, src, len, ADDR_OUTSIDE, ADDR_INSIDE, 0, 0);
#else
memcpy(dst, src, len);
return 0;
#endif
}
/* set the value of an inside memory */
void *memory_set(void *str, int ch, word num)
{
return memset(str, ch, num);
}
/* compare two strings */
int string_compare(const char *s1, const char *s2)
{
return strcmp(s1, s2);
}
/* copy a string to a buffer */
char *string_copy(char *s1, const char *s2)
{
return strcpy(s1, s2);
}
/* get a string's length */
int string_len(const char *s)
{
return strlen(s);
}
/* find an external function by its name */
void *find_external_function(const byte *name)
{
const struct kernel_symbol *sym;
#ifdef __KERNEL__
#ifdef USE_KALLSYMS
unsigned long ret = kallsyms_lookup_name(name);
if (ret != 0) {
return (void *)ret;
}
#endif
preempt_disable();
sym = find_symbol(name, NULL, NULL, 1, 0);
preempt_enable();
if (sym != NULL) {
#ifdef CONFIG_HAVE_ARCH_PREL32_RELOCATIONS
return (void *)offset_to_ptr(&sym->value_offset);
#else
return (void *)(sym->value);
#endif
}
return NULL;
#else
return dlsym(RTLD_NEXT, (const char *)name);
#endif
}
#ifndef __KERNEL__
/* the user mode version is just for testing, AND IS NOT THREAD SAFE */
inline int atomic_dec_and_test(atomic_t *atom)
{
return (--(*atom)) == 0;
}
#endif