Move ksplice_reloc generation into objmanip.
[ksplice.git] / objcommon.h
blob7bfe5e747771a5e09b58d32a9a80fcf3f9c36e65
1 #include <bfd.h>
2 #include <stddef.h>
3 #include <stdio.h>
4 #include <stdlib.h>
5 #include <string.h>
7 #define DIE do { fprintf(stderr, "ksplice: died at %s:%d\n", __FILE__, __LINE__); abort(); } while(0)
8 #define assert(x) do { if(!(x)) DIE; } while(0)
9 #define align(x, n) ((((x)+(n)-1)/(n))*(n))
11 #define container_of(ptr, type, member) ({ \
12 const typeof( ((type *)0)->member ) *__mptr = (ptr); \
13 (type *)( (char *)__mptr - offsetof(type,member) );})
15 #define DECLARE_VEC_TYPE(elt_t, vectype) \
16 struct vectype { \
17 elt_t *data; \
18 size_t size; \
19 size_t mem_size; \
22 /* void vec_init(struct vectype *vec); */
23 #define vec_init(vec) *(vec) = (typeof(*(vec))) { NULL, 0, 0 }
25 /* void vec_move(struct vectype *dstvec, struct vectype *srcvec); */
26 #define vec_move(dstvec, srcvec) do { \
27 typeof(srcvec) _srcvec = (srcvec); \
28 *(dstvec) = *(_srcvec); \
29 vec_init(_srcvec); \
30 } while (0)
32 /* void vec_free(struct vectype *vec); */
33 #define vec_free(vec) do { \
34 typeof(vec) _vec1 = (vec); \
35 free(_vec1->data); \
36 vec_init(_vec1); \
37 } while (0)
39 void vec_do_reserve(void **data, size_t *mem_size, size_t newsize);
41 /* void vec_reserve(struct vectype *vec, size_t new_mem_size); */
42 #define vec_reserve(vec, new_mem_size) do { \
43 typeof(vec) _vec2 = (vec); \
44 vec_do_reserve((void **)&_vec2->data, &_vec2->mem_size, \
45 (new_mem_size)); \
46 } while (0)
48 /* void vec_resize(struct vectype *vec, size_t new_size); */
49 #define vec_resize(vec, new_size) do { \
50 typeof(vec) _vec3 = (vec); \
51 _vec3->size = (new_size); \
52 vec_reserve(_vec3, _vec3->size * sizeof(*_vec3->data)); \
53 } while (0)
55 /* elt_t *vec_grow(struct vectype *vec, size_t n); */
56 #define vec_grow(vec, n) ({ \
57 typeof(vec) _vec4 = (vec); \
58 size_t _n = (n); \
59 vec_resize(_vec4, _vec4->size + _n); \
60 _vec4->data + (_vec4->size - _n); \
63 DECLARE_VEC_TYPE(void, void_vec);
64 DECLARE_VEC_TYPE(arelent *, arelentp_vec);
65 DECLARE_VEC_TYPE(asymbol *, asymbolp_vec);
67 #define DECLARE_HASH_TYPE(elt_t, hashtype, \
68 hashtype_init, hashtype_free, \
69 hashtype_lookup) \
70 struct hashtype { \
71 struct bfd_hash_table root; \
72 }; \
74 void hashtype_init(struct hashtype *table); \
75 void hashtype_free(struct hashtype *table); \
76 typeof(elt_t) *hashtype_lookup(struct hashtype *table, \
77 const char *string, \
78 bfd_boolean create)
80 #ifndef BFD_HASH_TABLE_HAS_ENTSIZE
81 #define bfd_hash_table_init(table, newfunc, entry) \
82 bfd_hash_table_init(table, newfunc)
83 #endif
85 #define DEFINE_HASH_TYPE(elt_t, hashtype, \
86 hashtype_init, hashtype_free, \
87 hashtype_lookup, \
88 elt_construct) \
89 DECLARE_HASH_TYPE(elt_t, hashtype, hashtype_init, \
90 hashtype_free, hashtype_lookup); \
92 struct hashtype##_entry { \
93 struct bfd_hash_entry root; \
94 typeof(elt_t) val; \
95 }; \
97 static struct bfd_hash_entry *hashtype##_newfunc( \
98 struct bfd_hash_entry *entry, \
99 struct bfd_hash_table *table, \
100 const char *string) \
102 if (entry == NULL) { \
103 entry = bfd_hash_allocate(table, \
104 sizeof(struct hashtype##_entry)); \
105 if (entry == NULL) \
106 return entry; \
108 entry = bfd_hash_newfunc(entry, table, string); \
109 typeof(elt_t) *v = \
110 &container_of(entry, struct hashtype##_entry, \
111 root)->val; \
112 elt_construct(v); \
113 return entry; \
114 }; \
116 void hashtype_init(struct hashtype *table) \
118 bfd_hash_table_init(&table->root, hashtype##_newfunc, \
119 sizeof(struct hashtype##_entry)); \
122 void hashtype_free(struct hashtype *table) \
124 bfd_hash_table_free(&table->root); \
127 typeof(elt_t) *hashtype_lookup(struct hashtype *table, \
128 const char *string, \
129 bfd_boolean create) \
131 struct bfd_hash_entry *e = \
132 bfd_hash_lookup(&table->root, string, create, \
133 TRUE); \
134 if (create) \
135 assert(e != NULL); \
136 else if (e == NULL) \
137 return NULL; \
138 return &container_of(e, struct hashtype##_entry, \
139 root)->val; \
142 struct eat_trailing_semicolon
144 #ifndef bfd_get_section_size
145 #define bfd_get_section_size(x) ((x)->_cooked_size)
146 #endif
148 struct supersect {
149 bfd *parent;
150 char *name;
151 struct void_vec contents;
152 int alignment;
153 struct arelentp_vec relocs;
154 struct supersect *next;
155 asymbol *symbol;
158 void get_syms(bfd *abfd, struct asymbolp_vec *syms);
159 struct supersect *fetch_supersect(bfd *abfd, asection *sect,
160 struct asymbolp_vec *syms);
161 extern struct supersect *new_supersects;
162 struct supersect *new_supersect(char *name);
164 #define sect_grow(ss, n, type) \
165 ((type *)sect_do_grow(ss, n, sizeof(type), __alignof__(type)))
166 void *sect_do_grow(struct supersect *ss, size_t n, size_t size, int alignment);
168 #define starts_with(str, prefix) \
169 (strncmp(str, prefix, strlen(prefix)) == 0)
170 #define ends_with(str, suffix) \
171 (strlen(str) >= strlen(suffix) && \
172 strcmp(&str[strlen(str) - strlen(suffix)], suffix) == 0)
174 int label_offset(const char *sym_name);
175 const char *only_label(const char *sym_name);
176 const char *dup_wolabel(const char *sym_name);