Use spans in the primary floodfill.
[ksplice.git] / objcommon.h
blob0c4bd4a40fda0cc5e472c2948e4628cd6b808faa
1 #include <bfd.h>
2 #include <limits.h>
3 #include <stdbool.h>
4 #include <stddef.h>
5 #include <stdio.h>
6 #include <stdlib.h>
7 #include <string.h>
9 #define BITS_PER_LONG LONG_BIT
11 #define DIE do { fprintf(stderr, "ksplice: died at %s:%d\n", __FILE__, __LINE__); abort(); } while(0)
12 #define assert(x) do { if(!(x)) DIE; } while(0)
13 #define align(x, n) ((((x)+(n)-1)/(n))*(n))
15 #define container_of(ptr, type, member) ({ \
16 const typeof( ((type *)0)->member ) *__mptr = (ptr); \
17 (type *)( (char *)__mptr - offsetof(type,member) );})
19 #define DECLARE_VEC_TYPE(elt_t, vectype) \
20 struct vectype { \
21 elt_t *data; \
22 size_t size; \
23 size_t mem_size; \
26 /* void vec_init(struct vectype *vec); */
27 #define vec_init(vec) *(vec) = (typeof(*(vec))) { NULL, 0, 0 }
29 /* void vec_move(struct vectype *dstvec, struct vectype *srcvec); */
30 #define vec_move(dstvec, srcvec) do { \
31 typeof(srcvec) _srcvec = (srcvec); \
32 *(dstvec) = *(_srcvec); \
33 vec_init(_srcvec); \
34 } while (0)
36 /* void vec_free(struct vectype *vec); */
37 #define vec_free(vec) do { \
38 typeof(vec) _vec1 = (vec); \
39 free(_vec1->data); \
40 vec_init(_vec1); \
41 } while (0)
43 void vec_do_reserve(void **data, size_t *mem_size, size_t newsize);
45 /* void vec_reserve(struct vectype *vec, size_t new_mem_size); */
46 #define vec_reserve(vec, new_mem_size) do { \
47 typeof(vec) _vec2 = (vec); \
48 vec_do_reserve((void **)&_vec2->data, &_vec2->mem_size, \
49 (new_mem_size)); \
50 } while (0)
52 /* void vec_resize(struct vectype *vec, size_t new_size); */
53 #define vec_resize(vec, new_size) do { \
54 typeof(vec) _vec3 = (vec); \
55 _vec3->size = (new_size); \
56 vec_reserve(_vec3, _vec3->size * sizeof(*_vec3->data)); \
57 } while (0)
59 /* elt_t *vec_grow(struct vectype *vec, size_t n); */
60 #define vec_grow(vec, n) ({ \
61 typeof(vec) _vec4 = (vec); \
62 size_t _n = (n); \
63 vec_resize(_vec4, _vec4->size + _n); \
64 _vec4->data + (_vec4->size - _n); \
67 DECLARE_VEC_TYPE(void, void_vec);
68 DECLARE_VEC_TYPE(arelent *, arelentp_vec);
69 DECLARE_VEC_TYPE(asymbol *, asymbolp_vec);
70 DECLARE_VEC_TYPE(asymbol **, asymbolpp_vec);
72 #define DECLARE_HASH_TYPE(elt_t, hashtype, \
73 hashtype_init, hashtype_free, \
74 hashtype_lookup) \
75 struct hashtype { \
76 struct bfd_hash_table root; \
77 }; \
79 void hashtype_init(struct hashtype *table); \
80 void hashtype_free(struct hashtype *table); \
81 typeof(elt_t) *hashtype_lookup(struct hashtype *table, \
82 const char *string, \
83 bfd_boolean create)
85 #ifndef BFD_HASH_TABLE_HAS_ENTSIZE
86 #define bfd_hash_table_init(table, newfunc, entry) \
87 bfd_hash_table_init(table, newfunc)
88 #endif
90 #define IMPLEMENT_HASH_TYPE(elt_t, hashtype, \
91 hashtype_init, hashtype_free, \
92 hashtype_lookup, \
93 elt_construct) \
95 struct hashtype##_entry { \
96 struct bfd_hash_entry root; \
97 typeof(elt_t) val; \
98 }; \
100 static struct bfd_hash_entry *hashtype##_newfunc( \
101 struct bfd_hash_entry *entry, \
102 struct bfd_hash_table *table, \
103 const char *string) \
105 if (entry == NULL) { \
106 entry = bfd_hash_allocate(table, \
107 sizeof(struct hashtype##_entry)); \
108 if (entry == NULL) \
109 return entry; \
111 entry = bfd_hash_newfunc(entry, table, string); \
112 typeof(elt_t) *v = \
113 &container_of(entry, struct hashtype##_entry, \
114 root)->val; \
115 elt_construct(v); \
116 return entry; \
117 }; \
119 void hashtype_init(struct hashtype *table) \
121 bfd_hash_table_init(&table->root, hashtype##_newfunc, \
122 sizeof(struct hashtype##_entry)); \
125 void hashtype_free(struct hashtype *table) \
127 bfd_hash_table_free(&table->root); \
130 typeof(elt_t) *hashtype_lookup(struct hashtype *table, \
131 const char *string, \
132 bfd_boolean create) \
134 struct bfd_hash_entry *e = \
135 bfd_hash_lookup(&table->root, string, create, \
136 TRUE); \
137 if (create) \
138 assert(e != NULL); \
139 else if (e == NULL) \
140 return NULL; \
141 return &container_of(e, struct hashtype##_entry, \
142 root)->val; \
145 struct eat_trailing_semicolon
147 #define DEFINE_HASH_TYPE(elt_t, hashtype, \
148 hashtype_init, hashtype_free, \
149 hashtype_lookup, \
150 elt_construct) \
151 DECLARE_HASH_TYPE(elt_t, hashtype, hashtype_init, \
152 hashtype_free, hashtype_lookup); \
153 IMPLEMENT_HASH_TYPE(elt_t, hashtype, hashtype_init, \
154 hashtype_free, hashtype_lookup, \
155 elt_construct);
158 #ifndef bfd_get_section_size
159 #define bfd_get_section_size(x) ((x)->_cooked_size)
160 #endif
162 DECLARE_HASH_TYPE(arelent *, arelentp_hash, arelentp_hash_init,
163 arelentp_hash_free, arelentp_hash_lookup);
164 DECLARE_HASH_TYPE(asymbol **, asymbolpp_hash, asymbolpp_hash_init,
165 asymbolpp_hash_free, asymbolpp_hash_lookup);
166 DECLARE_HASH_TYPE(const char *, string_hash, string_hash_init,
167 string_hash_free, string_hash_lookup);
169 struct label_map {
170 asymbol *csym;
171 const char *orig_label;
172 const char *label;
173 int count;
175 DECLARE_VEC_TYPE(struct label_map, label_map_vec);
176 DECLARE_HASH_TYPE(struct label_map *, label_mapp_hash, label_mapp_hash_init,
177 label_mapp_hash_free, label_mapp_hash_lookup);
179 struct span {
180 struct supersect *ss;
181 asymbol *symbol;
182 const char *orig_label;
183 const char *label;
184 bfd_vma start;
185 bfd_vma size;
186 bool keep;
187 bool new;
188 bool patch;
189 struct span *match;
190 bfd_size_type shift;
192 DECLARE_VEC_TYPE(struct span, span_vec);
194 struct superbfd {
195 bfd *abfd;
196 struct asymbolp_vec syms;
197 struct supersect *new_supersects;
198 struct label_map_vec maps;
199 struct label_mapp_hash maps_hash;
200 struct asymbolpp_vec new_syms;
201 struct asymbolpp_hash csyms;
202 struct string_hash callers;
205 enum supersect_type {
206 SS_TYPE_TEXT, SS_TYPE_DATA, SS_TYPE_RODATA, SS_TYPE_STRING,
207 SS_TYPE_SPECIAL, SS_TYPE_IGNORED, SS_TYPE_KSPLICE, SS_TYPE_EXPORT,
208 SS_TYPE_UNKNOWN
211 struct supersect {
212 struct superbfd *parent;
213 const char *name;
214 flagword flags;
215 struct void_vec contents;
216 int alignment;
217 struct arelentp_vec relocs;
218 struct arelentp_vec new_relocs;
219 struct supersect *next;
220 struct asymbolp_vec syms;
221 struct span_vec spans;
222 struct arelentp_hash reloc_hash;
223 asymbol *symbol;
224 bool keep;
225 enum supersect_type type;
228 struct kernel_symbol {
229 unsigned long value;
230 char *name;
233 struct superbfd *fetch_superbfd(bfd *abfd);
234 struct supersect *fetch_supersect(struct superbfd *sbfd, asection *sect);
235 struct supersect *new_supersect(struct superbfd *sbfd, const char *name);
236 void supersect_move(struct supersect *dest_ss, struct supersect *src_ss);
238 #define sect_grow(ss, n, type) \
239 ((type *)sect_do_grow(ss, n, sizeof(type), __alignof__(type)))
240 void *sect_do_grow(struct supersect *ss, size_t n, size_t size, int alignment);
242 #define sect_copy(dest_ss, dest, src_ss, src, n) \
243 sect_do_copy(dest_ss, dest, src_ss, src, (n) * sizeof(*(src)))
244 void sect_do_copy(struct supersect *dest_ss, void *dest,
245 struct supersect *src_ss, const void *src, size_t n);
247 #define starts_with(str, prefix) \
248 (strncmp(str, prefix, strlen(prefix)) == 0)
249 #define ends_with(str, suffix) \
250 (strlen(str) >= strlen(suffix) && \
251 strcmp(&str[strlen(str) - strlen(suffix)], suffix) == 0)
253 bfd_vma addr_offset(struct supersect *ss, const void *addr);
254 bfd_vma get_reloc_offset(struct supersect *ss, arelent *reloc, bool adjust_pc);
255 bfd_vma read_reloc(struct supersect *ss, const void *addr, size_t size,
256 asymbol **symp);
257 const void *read_pointer(struct supersect *ss, void *const *addr,
258 struct supersect **ssp);
259 const char *read_string(struct supersect *ss, const char *const *addr);
260 char *str_pointer(struct supersect *ss, void *const *addr);
262 #define read_num(ss, addr) ((typeof(*(addr))) \
263 read_reloc(ss, addr, sizeof(*(addr)), NULL))