1#ifndef _INTERNAL_RELOC_H
2#define _INTERNAL_RELOC_H
3
4#include <features.h>
5#include <elf.h>
6#include <stdint.h>
7#include <stddef.h>
8#include <stdarg.h>
9#include <link.h>
10#include <sys/types.h>
11#include <stdlib.h>
12#include "libc.h"
13#include "../../ldso/namespace.h"
14
15#if UINTPTR_MAX == 0xffffffff
16typedef Elf32_Ehdr Ehdr;
17typedef Elf32_Phdr Phdr;
18typedef Elf32_Shdr Shdr;
19typedef Elf32_Sym Sym;
20typedef Elf32_Verdaux Verdaux;
21typedef Elf32_Verdef Verdef;
22typedef Elf32_Vernaux Vernaux;
23typedef Elf32_Verneed Verneed;
24#define R_TYPE(x) ((x)&255)
25#define R_SYM(x) ((x)>>8)
26#define R_INFO ELF32_R_INFO
27#else
28typedef Elf64_Ehdr Ehdr;
29typedef Elf64_Phdr Phdr;
30typedef Elf64_Shdr Shdr;
31typedef Elf64_Sym Sym;
32typedef Elf64_Verdaux Verdaux;
33typedef Elf64_Verdef Verdef;
34typedef Elf64_Vernaux Vernaux;
35typedef Elf64_Verneed Verneed;
36#define R_TYPE(x) ((x)&0x7fffffff)
37#define R_SYM(x) ((x)>>32)
38#define R_INFO ELF64_R_INFO
39#endif
40
41/* These enum constants provide unmatchable default values for
42 * any relocation type the arch does not use. */
43enum {
44	REL_NONE = 0,
45	REL_SYMBOLIC = -100,
46	REL_USYMBOLIC,
47	REL_GOT,
48	REL_PLT,
49	REL_RELATIVE,
50	REL_OFFSET,
51	REL_OFFSET32,
52	REL_COPY,
53	REL_SYM_OR_REL,
54	REL_DTPMOD,
55	REL_DTPOFF,
56	REL_TPOFF,
57	REL_TPOFF_NEG,
58	REL_TLSDESC,
59	REL_FUNCDESC,
60	REL_FUNCDESC_VAL,
61};
62
63struct td_index {
64	size_t args[2];
65	struct td_index *next;
66};
67
68struct verinfo {
69	const char *s;
70	const char *v;
71	bool use_vna_hash;
72	uint32_t vna_hash;
73};
74
75struct sym_info_pair {
76	uint_fast32_t sym_h;
77	uint32_t sym_l;
78};
79
80struct dso {
81#if DL_FDPIC
82	struct fdpic_loadmap *loadmap;
83#else
84	unsigned char *base;
85#endif
86	char *name;
87	size_t *dynv;
88	struct dso *next, *prev;
89	/* add namespace */
90	ns_t *namespace;
91	int cache_sym_index;
92	struct dso *cache_dso;
93	Sym *cache_sym;
94	Phdr *phdr;
95	int phnum;
96	size_t phentsize;
97	Sym *syms;
98	Elf_Symndx *hashtab;
99	uint32_t *ghashtab;
100	int16_t *versym;
101	Verdef *verdef;
102	Verneed *verneed;
103	char *strings;
104	struct dso *syms_next, *lazy_next;
105	size_t *lazy, lazy_cnt;
106	unsigned char *map;
107	size_t map_len;
108	dev_t dev;
109	ino_t ino;
110	uint64_t file_offset;
111	pthread_t ctor_visitor;
112	char *rpath_orig, *rpath;
113	struct tls_module tls;
114	size_t tls_id;
115	size_t relro_start, relro_end;
116	uintptr_t *new_dtv;
117	unsigned char *new_tls;
118	struct td_index *td_index;
119	struct dso *fini_next;
120	char *shortname;
121#if DL_FDPIC
122	unsigned char *base;
123#else
124	struct fdpic_loadmap *loadmap;
125#endif
126	struct funcdesc {
127		void *addr;
128		size_t *got;
129	} *funcdescs;
130	size_t *got;
131	struct dso **deps, *needed_by;
132	uint16_t ndeps_direct;
133	uint16_t next_dep;
134	uint16_t parents_count;
135	uint16_t parents_capacity;
136	struct dso **parents;
137	struct dso **reloc_can_search_dso_list;
138	uint16_t reloc_can_search_dso_count;
139	uint16_t reloc_can_search_dso_capacity;
140	/* mark the dso status */
141	uint32_t flags;
142	uint32_t nr_dlopen;
143	bool is_global;
144	bool is_reloc_head_so_dep;
145	char relocated;
146	char constructed;
147	char kernel_mapped;
148	char mark;
149	char bfs_built;
150	char runtime_loaded;
151	char by_dlopen;
152	bool is_mapped_to_shadow;
153	struct dso_debug_info *debug_info;
154	char buf[];
155};
156
157struct dso_debug_info {
158#if DL_FDPIC
159	struct fdpic_loadmap *loadmap;
160#else
161	unsigned char *base;
162#endif
163	char *name;
164	size_t *dynv;
165	struct dso_debug_info *next, *prev;
166};
167
168struct symdef {
169	Sym *sym;
170	struct dso *dso;
171};
172
173struct fdpic_loadseg {
174	uintptr_t addr, p_vaddr, p_memsz;
175};
176
177struct fdpic_loadmap {
178	unsigned short version, nsegs;
179	struct fdpic_loadseg segs[];
180};
181
182struct fdpic_dummy_loadmap {
183	unsigned short version, nsegs;
184	struct fdpic_loadseg segs[1];
185};
186
187#include "reloc.h"
188
189#ifndef FDPIC_CONSTDISP_FLAG
190#define FDPIC_CONSTDISP_FLAG 0
191#endif
192
193#ifndef DL_FDPIC
194#define DL_FDPIC 0
195#endif
196
197#ifndef DL_NOMMU_SUPPORT
198#define DL_NOMMU_SUPPORT 0
199#endif
200
201#if !DL_FDPIC
202#define IS_RELATIVE(x,s) ( \
203	(R_TYPE(x) == REL_RELATIVE) || \
204	(R_TYPE(x) == REL_SYM_OR_REL && !R_SYM(x)) )
205#else
206#define IS_RELATIVE(x,s) ( ( \
207	(R_TYPE(x) == REL_FUNCDESC_VAL) || \
208	(R_TYPE(x) == REL_SYMBOLIC) ) \
209	&& (((s)[R_SYM(x)].st_info & 0xf) == STT_SECTION) )
210#endif
211
212#ifndef NEED_MIPS_GOT_RELOCS
213#define NEED_MIPS_GOT_RELOCS 0
214#endif
215
216#ifndef DT_DEBUG_INDIRECT
217#define DT_DEBUG_INDIRECT 0
218#endif
219
220#define AUX_CNT 32
221#define DYN_CNT 37
222
223#define DT_ANDROID_REL (DT_LOOS + 2)
224#define DT_ANDROID_RELSZ (DT_LOOS + 3)
225
226#define DT_ANDROID_RELA (DT_LOOS + 4)
227#define DT_ANDROID_RELASZ (DT_LOOS + 5)
228
229#define ANDROID_REL_SIGN_SIZE 4
230
231#define RELOCATION_GROUPED_BY_INFO_FLAG 1
232#define RELOCATION_GROUPED_BY_OFFSET_DELTA_FLAG 2
233#define RELOCATION_GROUPED_BY_ADDEND_FLAG 4
234#define RELOCATION_GROUP_HAS_ADDEND_FLAG 8
235
236typedef void (*stage2_func)(unsigned char *, size_t *);
237
238#if DL_FDPIC
239void *laddr(const struct dso *p, size_t v);
240#endif
241
242#ifdef UNIT_TEST_STATIC
243    #define UT_STATIC
244#else
245    #define UT_STATIC static
246#endif
247
248void *addr2dso(size_t a);
249UT_STATIC size_t count_syms(struct dso *p);
250struct sym_info_pair gnu_hash(const char *s0);
251struct symdef find_sym_impl(
252	struct dso *dso, struct verinfo *verinfo, struct sym_info_pair s_info_p, int need_def, ns_t *ns);
253
254hidden void *__dlsym(void *restrict, const char *restrict, void *restrict);
255hidden void *__dlvsym(void *restrict, const char *restrict, const char *restrict, void *restrict);
256hidden int __dlclose(void *p);
257
258hidden void __dl_seterr(const char *, ...);
259hidden int __dl_invalid_handle(void *);
260hidden void __dl_vseterr(const char *, va_list);
261
262hidden ptrdiff_t __tlsdesc_static(), __tlsdesc_dynamic();
263
264hidden extern int __malloc_replaced;
265hidden extern int __aligned_alloc_replaced;
266hidden void __malloc_donate(char *, char *);
267hidden int __malloc_allzerop(void *);
268
269#endif
270