-
Notifications
You must be signed in to change notification settings - Fork 2
/
Copy pathcommon.h
161 lines (135 loc) · 3.46 KB
/
common.h
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
153
154
155
156
157
158
159
160
161
#ifndef _COMMON_H_
#define _COMMON_H_
#include <error.h>
extern char *childobj;
#define ERROR(format, ...) \
error(1, 0, "ERROR: %s: %s: %d: " format, childobj, __FUNCTION__, __LINE__, ##__VA_ARGS__)
#define DIFF_FATAL(format, ...) \
({ \
fprintf(stderr, "ERROR: %s: " format "\n", childobj, ##__VA_ARGS__); \
error(2, 0, "unreconcilable difference"); \
})
#define log_debug(format, ...) log(DEBUG, format, ##__VA_ARGS__)
#define log_normal(format, ...) log(NORMAL, "%s: " format, childobj, ##__VA_ARGS__)
#define log(level, format, ...) \
({ \
if (loglevel <= (level)) \
printf(format, ##__VA_ARGS__); \
})
#define ALLOC_LINK(_new, _list) \
{ \
(_new) = malloc(sizeof(*(_new))); \
if (!(_new)) \
ERROR("malloc"); \
memset((_new), 0, sizeof(*(_new))); \
INIT_LIST_HEAD(&(_new)->list); \
list_add_tail(&(_new)->list, (_list)); \
}
enum loglevel {
DEBUG,
NORMAL
};
extern enum loglevel loglevel;
/*******************
* Data structures
* ****************/
struct section;
struct symbol;
struct rela;
enum status {
NEW,
CHANGED,
SAME
};
struct section {
struct list_head list;
struct section *twin;
GElf_Shdr sh;
Elf_Data *data;
char *name;
int index;
enum status status;
int include;
int ignore;
int grouped;
union {
struct { /* if (is_rela_section()) */
struct section *base;
struct list_head relas;
};
struct { /* else */
struct section *rela;
struct symbol *secsym, *sym;
};
};
};
struct symbol {
struct list_head list;
struct symbol *twin;
struct section *sec;
GElf_Sym sym;
char *name;
int index;
unsigned char bind, type;
enum status status;
union {
int include; /* used in the patched elf */
int strip; /* used in the output elf */
};
};
struct rela {
struct list_head list;
GElf_Rela rela;
struct symbol *sym;
unsigned int type;
int addend;
int offset;
char *string;
};
struct string {
struct list_head list;
char *name;
};
struct kpatch_elf {
Elf *elf;
struct list_head sections;
struct list_head symbols;
struct list_head strings;
int fd;
};
#define PATCH_INSN_SIZE 5
struct livepatch_patch_func {
char *name;
unsigned long new_addr;
unsigned long old_addr;
uint32_t new_size;
uint32_t old_size;
uint8_t version;
unsigned char pad[31];
};
struct special_section {
char *name;
int (*group_size)(struct kpatch_elf *kelf, int offset);
};
struct kpatch_elf *kpatch_elf_open(const char *name);
void kpatch_elf_free(struct kpatch_elf *kelf);
void kpatch_elf_teardown(struct kpatch_elf *kelf);
void kpatch_write_output_elf(struct kpatch_elf *kelf,
Elf *elf, char *outfile);
void kpatch_dump_kelf(struct kpatch_elf *kelf);
void kpatch_create_symtab(struct kpatch_elf *kelf);
void kpatch_create_strtab(struct kpatch_elf *kelf);
void kpatch_create_shstrtab(struct kpatch_elf *kelf);
void kpatch_rebuild_rela_section_data(struct section *sec);
struct section *find_section_by_index(struct list_head *list, unsigned int index);
struct section *find_section_by_name(struct list_head *list, const char *name);
struct symbol *find_symbol_by_index(struct list_head *list, size_t index);
struct symbol *find_symbol_by_name(struct list_head *list, const char *name);
int is_text_section(struct section *sec);
int is_debug_section(struct section *sec);
int is_rela_section(struct section *sec);
int is_local_sym(struct symbol *sym);
void rela_insn(struct section *sec, struct rela *rela, struct insn *insn);
int offset_of_string(struct list_head *list, char *name);
char *status_str(enum status status);
#endif /* _COMMON_H_ */