10 #define BITS_PER_LONG LONG_BIT
11 #define _PASTE(x, y) x##y
12 #define PASTE(x, y) _PASTE(x, y)
14 #define DIE do { fprintf(stderr, "ksplice: died at %s:%d\n", __FILE__, __LINE__); abort(); } while(0)
15 #define assert(x) do { if(!(x)) DIE; } while(0)
16 #define align(x, n) ((((x)+(n)-1)/(n))*(n))
18 #define container_of(ptr, type, member) ({ \
19 const typeof( ((type *)0)->member ) *__mptr = (ptr); \
20 (type *)( (char *)__mptr - offsetof(type,member) );})
22 #define DECLARE_VEC_TYPE(elt_t, vectype) \
29 /* void vec_init(struct vectype *vec); */
30 #define vec_init(vec) *(vec) = (typeof(*(vec))) { NULL, 0, 0 }
32 /* void vec_move(struct vectype *dstvec, struct vectype *srcvec); */
33 #define vec_move(dstvec, srcvec) do { \
34 typeof(srcvec) _srcvec = (srcvec); \
35 *(dstvec) = *(_srcvec); \
39 /* void vec_free(struct vectype *vec); */
40 #define vec_free(vec) do { \
41 typeof(vec) _vec1 = (vec); \
46 void vec_do_reserve(void **data
, size_t *mem_size
, size_t newsize
);
48 /* void vec_reserve(struct vectype *vec, size_t new_mem_size); */
49 #define vec_reserve(vec, new_mem_size) do { \
50 typeof(vec) _vec2 = (vec); \
51 vec_do_reserve((void **)&_vec2->data, &_vec2->mem_size, \
55 /* void vec_resize(struct vectype *vec, size_t new_size); */
56 #define vec_resize(vec, new_size) do { \
57 typeof(vec) _vec3 = (vec); \
58 _vec3->size = (new_size); \
59 vec_reserve(_vec3, _vec3->size * sizeof(*_vec3->data)); \
62 /* elt_t *vec_grow(struct vectype *vec, size_t n); */
63 #define vec_grow(vec, n) ({ \
64 typeof(vec) _vec4 = (vec); \
66 vec_resize(_vec4, _vec4->size + _n); \
67 _vec4->data + (_vec4->size - _n); \
70 DECLARE_VEC_TYPE(void, void_vec
);
71 DECLARE_VEC_TYPE(arelent
*, arelentp_vec
);
72 DECLARE_VEC_TYPE(asymbol
*, asymbolp_vec
);
73 DECLARE_VEC_TYPE(asymbol
**, asymbolpp_vec
);
75 #define DECLARE_HASH_TYPE(elt_t, hashtype, \
76 hashtype_init, hashtype_free, \
79 struct bfd_hash_table root; \
82 void hashtype_init(struct hashtype *table); \
83 void hashtype_free(struct hashtype *table); \
84 typeof(elt_t) *hashtype_lookup(struct hashtype *table, \
88 #ifndef BFD_HASH_TABLE_HAS_ENTSIZE
89 #define bfd_hash_table_init(table, newfunc, entry) \
90 bfd_hash_table_init(table, newfunc)
93 #define IMPLEMENT_HASH_TYPE(elt_t, hashtype, \
94 hashtype_init, hashtype_free, \
98 struct hashtype##_entry { \
99 struct bfd_hash_entry root; \
103 static struct bfd_hash_entry *hashtype##_newfunc( \
104 struct bfd_hash_entry *entry, \
105 struct bfd_hash_table *table, \
106 const char *string) \
108 if (entry == NULL) { \
109 entry = bfd_hash_allocate(table, \
110 sizeof(struct hashtype##_entry)); \
114 entry = bfd_hash_newfunc(entry, table, string); \
116 &container_of(entry, struct hashtype##_entry, \
122 void hashtype_init(struct hashtype *table) \
124 bfd_hash_table_init(&table->root, hashtype##_newfunc, \
125 sizeof(struct hashtype##_entry)); \
128 void hashtype_free(struct hashtype *table) \
130 bfd_hash_table_free(&table->root); \
133 typeof(elt_t) *hashtype_lookup(struct hashtype *table, \
134 const char *string, \
135 bfd_boolean create) \
137 struct bfd_hash_entry *e = \
138 bfd_hash_lookup(&table->root, string, create, \
142 else if (e == NULL) \
144 return &container_of(e, struct hashtype##_entry, \
148 struct eat_trailing_semicolon
150 #define DEFINE_HASH_TYPE(elt_t, hashtype, \
151 hashtype_init, hashtype_free, \
154 DECLARE_HASH_TYPE(elt_t, hashtype, hashtype_init, \
155 hashtype_free, hashtype_lookup); \
156 IMPLEMENT_HASH_TYPE(elt_t, hashtype, hashtype_init, \
157 hashtype_free, hashtype_lookup, \
161 #ifndef bfd_get_section_size
162 #define bfd_get_section_size(x) ((x)->_cooked_size)
165 DECLARE_HASH_TYPE(arelent
*, arelentp_hash
, arelentp_hash_init
,
166 arelentp_hash_free
, arelentp_hash_lookup
);
167 DECLARE_HASH_TYPE(asymbol
**, asymbolpp_hash
, asymbolpp_hash_init
,
168 asymbolpp_hash_free
, asymbolpp_hash_lookup
);
169 DECLARE_HASH_TYPE(const char *, string_hash
, string_hash_init
,
170 string_hash_free
, string_hash_lookup
);
174 const char *orig_label
;
178 DECLARE_VEC_TYPE(struct label_map
, label_map_vec
);
179 DECLARE_HASH_TYPE(struct label_map
*, label_mapp_hash
, label_mapp_hash_init
,
180 label_mapp_hash_free
, label_mapp_hash_lookup
);
188 DECLARE_VEC_TYPE(struct entry_point
, entry_point_vec
);
191 struct supersect
*ss
;
193 const char *orig_label
;
197 bfd_vma contents_size
;
205 struct entry_point_vec entry_points
;
206 struct entry_point_vec pre_entry_points
;
209 DECLARE_VEC_TYPE(struct span
, span_vec
);
213 struct asymbolp_vec syms
;
214 struct supersect
*new_supersects
;
215 struct label_map_vec maps
;
216 struct label_mapp_hash maps_hash
;
217 struct asymbolpp_vec new_syms
;
218 struct asymbolpp_hash csyms
;
219 struct string_hash callers
;
222 enum supersect_type
{
223 SS_TYPE_TEXT
, SS_TYPE_DATA
, SS_TYPE_RODATA
, SS_TYPE_STRING
,
224 SS_TYPE_SPECIAL
, SS_TYPE_IGNORED
, SS_TYPE_KSPLICE
, SS_TYPE_EXPORT
,
225 SS_TYPE_EXIT
, SS_TYPE_KSPLICE_CALL
, SS_TYPE_KSPLICE_EXTRACT
,
226 SS_TYPE_BUGTABLE
, SS_TYPE_UNKNOWN
230 struct superbfd
*parent
;
233 struct void_vec contents
;
235 unsigned int entsize
;
236 struct arelentp_vec relocs
;
237 struct arelentp_vec new_relocs
;
238 struct supersect
*next
;
239 struct asymbolp_vec syms
;
240 struct span_vec spans
;
241 struct arelentp_hash reloc_hash
;
244 enum supersect_type type
;
245 enum supersect_type orig_type
;
248 struct superbfd
*fetch_superbfd(bfd
*abfd
);
249 struct supersect
*fetch_supersect(struct superbfd
*sbfd
, asection
*sect
);
250 struct supersect
*new_supersect(struct superbfd
*sbfd
, const char *name
);
251 void supersect_move(struct supersect
*dest_ss
, struct supersect
*src_ss
);
253 #define sect_grow(ss, n, type) \
254 ((type *)sect_do_grow(ss, n, sizeof(type), __alignof__(type)))
255 void *sect_do_grow(struct supersect
*ss
, size_t n
, size_t size
, int alignment
);
257 #define sect_copy(dest_ss, dest, src_ss, src, n) \
258 sect_do_copy(dest_ss, dest, src_ss, src, (n) * sizeof(*(src)))
259 void sect_do_copy(struct supersect
*dest_ss
, void *dest
,
260 struct supersect
*src_ss
, const void *src
, size_t n
);
262 #define strstarts(str, prefix) \
263 (strncmp(str, prefix, strlen(prefix)) == 0)
264 #define ends_with(str, suffix) \
265 (strlen(str) >= strlen(suffix) && \
266 strcmp(&str[strlen(str) - strlen(suffix)], suffix) == 0)
268 bfd_vma
addr_offset(struct supersect
*ss
, const void *addr
);
269 bfd_vma
reloc_offset(struct supersect
*ss
, arelent
*reloc
);
270 arelent
*find_reloc(struct supersect
*ss
, const void *addr
);
271 bfd_vma
read_reloc(struct supersect
*ss
, const void *addr
, size_t size
,
273 const void *read_pointer(struct supersect
*ss
, void *const *addr
,
274 struct supersect
**ssp
);
275 const char *read_string(struct supersect
*ss
, const char *const *addr
);
277 #define read_num(ss, addr) ((typeof(*(addr))) \
278 read_reloc(ss, addr, sizeof(*(addr)), NULL))
280 static inline char *vstrprintf(const char *fmt
, va_list ap
)
283 assert(vasprintf(&str
, fmt
, ap
) >= 0);
287 static inline char * __attribute__((format (printf
, 1, 2)))
288 strprintf(const char *fmt
, ...)
292 char *str
= vstrprintf(fmt
, ap
);