ltrace-elf.c revision 1be2291ffdf3a20b0a1702f5705f82617fb91ef6
1#include "config.h"
2
3#include <endian.h>
4#include <errno.h>
5#include <error.h>
6#include <fcntl.h>
7#include <gelf.h>
8#include <inttypes.h>
9#include <stdint.h>
10#include <stdlib.h>
11#include <string.h>
12#include <unistd.h>
13#include <assert.h>
14
15#include "common.h"
16#include "proc.h"
17#include "library.h"
18
19#ifdef PLT_REINITALISATION_BP
20extern char *PLTs_initialized_by_here;
21#endif
22
23#ifndef DT_PPC_GOT
24# define DT_PPC_GOT		(DT_LOPROC + 0)
25#endif
26
27
28#ifndef ARCH_HAVE_LTELF_DATA
29int
30arch_elf_init(struct ltelf *lte)
31{
32	return 0;
33}
34#endif
35
36int
37default_elf_add_plt_entry(struct Process *proc, struct ltelf *lte,
38			  const char *a_name, GElf_Rela *rela, size_t ndx,
39			  struct library_symbol **ret)
40{
41	char *name = strdup(a_name);
42	if (name == NULL) {
43	fail:
44		free(name);
45		return -1;
46	}
47
48	enum toplt pltt = PLTS_ARE_EXECUTABLE(lte)
49		?  LS_TOPLT_EXEC : LS_TOPLT_POINT;
50	GElf_Addr addr = arch_plt_sym_val(lte, ndx, rela);
51
52	struct library_symbol *libsym = malloc(sizeof(*libsym));
53	if (libsym == NULL)
54		goto fail;
55
56	target_address_t taddr = (target_address_t)(addr + lte->bias);
57
58	/* The logic behind this conditional translation is as
59	 * follows.  PLT entries do not typically need custom TOC
60	 * pointer, and therefore aren't redirected via OPD.  POINT
61	 * PLT, on the other hand, most likely contains addresses of
62	 * target functions, not PLT entries themselves, and would
63	 * need the OPD redirection.  */
64	if (pltt == LS_TOPLT_POINT
65	    && arch_translate_address(proc, taddr, &taddr) < 0) {
66		free(libsym);
67		goto fail;
68	}
69
70	library_symbol_init(libsym, taddr, name, 1, pltt);
71	*ret = libsym;
72	return 0;
73}
74
75#ifndef ARCH_HAVE_ADD_PLT_ENTRY
76enum plt_status
77arch_elf_add_plt_entry(struct Process *proc, struct ltelf *lte,
78		       const char *a_name, GElf_Rela *rela, size_t ndx,
79		       struct library_symbol **ret)
80{
81	return plt_default;
82}
83#endif
84
85Elf_Data *
86elf_loaddata(Elf_Scn *scn, GElf_Shdr *shdr)
87{
88	Elf_Data *data = elf_getdata(scn, NULL);
89	if (data == NULL || elf_getdata(scn, data) != NULL
90	    || data->d_off || data->d_size != shdr->sh_size)
91		return NULL;
92	return data;
93}
94
95static int
96elf_get_section_if(struct ltelf *lte, Elf_Scn **tgt_sec, GElf_Shdr *tgt_shdr,
97		   int (*predicate)(Elf_Scn *, GElf_Shdr *, void *data),
98		   void *data)
99{
100	int i;
101	for (i = 1; i < lte->ehdr.e_shnum; ++i) {
102		Elf_Scn *scn;
103		GElf_Shdr shdr;
104
105		scn = elf_getscn(lte->elf, i);
106		if (scn == NULL || gelf_getshdr(scn, &shdr) == NULL) {
107			debug(1, "Couldn't read section or header.");
108			return -1;
109		}
110		if (predicate(scn, &shdr, data)) {
111			*tgt_sec = scn;
112			*tgt_shdr = shdr;
113			return 0;
114		}
115	}
116	return -1;
117
118}
119
120static int
121inside_p(Elf_Scn *scn, GElf_Shdr *shdr, void *data)
122{
123	GElf_Addr addr = *(GElf_Addr *)data;
124	return addr >= shdr->sh_addr
125		&& addr < shdr->sh_addr + shdr->sh_size;
126}
127
128int
129elf_get_section_covering(struct ltelf *lte, GElf_Addr addr,
130			 Elf_Scn **tgt_sec, GElf_Shdr *tgt_shdr)
131{
132	return elf_get_section_if(lte, tgt_sec, tgt_shdr,
133				  &inside_p, &addr);
134}
135
136static int
137type_p(Elf_Scn *scn, GElf_Shdr *shdr, void *data)
138{
139	GElf_Word type = *(GElf_Word *)data;
140	return shdr->sh_type == type;
141}
142
143int
144elf_get_section_type(struct ltelf *lte, GElf_Word type,
145		     Elf_Scn **tgt_sec, GElf_Shdr *tgt_shdr)
146{
147	return elf_get_section_if(lte, tgt_sec, tgt_shdr,
148				  &type_p, &type);
149}
150
151static int
152need_data(Elf_Data *data, size_t offset, size_t size)
153{
154	assert(data != NULL);
155	if (data->d_size < size || offset > data->d_size - size) {
156		debug(1, "Not enough data to read %zd-byte value"
157		      " at offset %zd.", size, offset);
158		return -1;
159	}
160	return 0;
161}
162
163#define DEF_READER(NAME, SIZE)						\
164	int								\
165	NAME(Elf_Data *data, size_t offset, uint##SIZE##_t *retp)	\
166	{								\
167		if (!need_data(data, offset, SIZE / 8) < 0)		\
168			return -1;					\
169									\
170		union {							\
171			uint##SIZE##_t dst;				\
172			char buf[0];					\
173		} u;							\
174		memcpy(u.buf, data->d_buf + offset, sizeof(u.dst));	\
175		*retp = u.dst;						\
176		return 0;						\
177	}
178
179DEF_READER(elf_read_u16, 16)
180DEF_READER(elf_read_u32, 32)
181DEF_READER(elf_read_u64, 64)
182
183#undef DEF_READER
184
185int
186open_elf(struct ltelf *lte, const char *filename)
187{
188	lte->fd = open(filename, O_RDONLY);
189	if (lte->fd == -1)
190		return 1;
191
192	elf_version(EV_CURRENT);
193
194#ifdef HAVE_ELF_C_READ_MMAP
195	lte->elf = elf_begin(lte->fd, ELF_C_READ_MMAP, NULL);
196#else
197	lte->elf = elf_begin(lte->fd, ELF_C_READ, NULL);
198#endif
199
200	if (lte->elf == NULL || elf_kind(lte->elf) != ELF_K_ELF)
201		error(EXIT_FAILURE, 0, "Can't open ELF file \"%s\"", filename);
202
203	if (gelf_getehdr(lte->elf, &lte->ehdr) == NULL)
204		error(EXIT_FAILURE, 0, "Can't read ELF header of \"%s\"",
205		      filename);
206
207	if (lte->ehdr.e_type != ET_EXEC && lte->ehdr.e_type != ET_DYN)
208		error(EXIT_FAILURE, 0,
209		      "\"%s\" is not an ELF executable nor shared library",
210		      filename);
211
212	if ((lte->ehdr.e_ident[EI_CLASS] != LT_ELFCLASS
213	     || lte->ehdr.e_machine != LT_ELF_MACHINE)
214#ifdef LT_ELF_MACHINE2
215	    && (lte->ehdr.e_ident[EI_CLASS] != LT_ELFCLASS2
216		|| lte->ehdr.e_machine != LT_ELF_MACHINE2)
217#endif
218#ifdef LT_ELF_MACHINE3
219	    && (lte->ehdr.e_ident[EI_CLASS] != LT_ELFCLASS3
220		|| lte->ehdr.e_machine != LT_ELF_MACHINE3)
221#endif
222	    )
223		error(EXIT_FAILURE, 0,
224		      "\"%s\" is ELF from incompatible architecture", filename);
225
226	return 0;
227}
228
229static int
230do_init_elf(struct ltelf *lte, const char *filename, GElf_Addr bias)
231{
232	int i;
233	GElf_Addr relplt_addr = 0;
234	GElf_Addr soname_offset = 0;
235
236	debug(DEBUG_FUNCTION, "do_init_elf(filename=%s)", filename);
237	debug(1, "Reading ELF from %s...", filename);
238
239	if (open_elf(lte, filename) < 0)
240		return -1;
241
242	/* Find out the base address.  */
243	{
244		GElf_Phdr phdr;
245		for (i = 0; gelf_getphdr (lte->elf, i, &phdr) != NULL; ++i) {
246			if (phdr.p_type == PT_LOAD) {
247				lte->base_addr = phdr.p_vaddr - bias;
248				fprintf(stderr,
249					" + vaddr=%#lx, bias=%#lx, base=%#lx\n",
250					phdr.p_vaddr, bias, lte->base_addr);
251				break;
252			}
253		}
254	}
255
256	if (lte->base_addr == 0) {
257		fprintf(stderr, "Couldn't determine base address of %s\n",
258			filename);
259		return -1;
260	}
261
262	lte->bias = bias;
263	lte->entry_addr = lte->ehdr.e_entry + lte->bias;
264
265	for (i = 1; i < lte->ehdr.e_shnum; ++i) {
266		Elf_Scn *scn;
267		GElf_Shdr shdr;
268		const char *name;
269
270		scn = elf_getscn(lte->elf, i);
271		if (scn == NULL || gelf_getshdr(scn, &shdr) == NULL)
272			error(EXIT_FAILURE, 0,
273			      "Couldn't get section header from \"%s\"",
274			      filename);
275
276		name = elf_strptr(lte->elf, lte->ehdr.e_shstrndx, shdr.sh_name);
277		if (name == NULL)
278			error(EXIT_FAILURE, 0,
279			      "Couldn't get section header from \"%s\"",
280			      filename);
281
282		if (shdr.sh_type == SHT_SYMTAB) {
283			Elf_Data *data;
284
285			lte->symtab = elf_getdata(scn, NULL);
286			lte->symtab_count = shdr.sh_size / shdr.sh_entsize;
287			if ((lte->symtab == NULL
288			     || elf_getdata(scn, lte->symtab) != NULL)
289			    && opt_x != NULL)
290				error(EXIT_FAILURE, 0,
291				      "Couldn't get .symtab data from \"%s\"",
292				      filename);
293
294			scn = elf_getscn(lte->elf, shdr.sh_link);
295			if (scn == NULL || gelf_getshdr(scn, &shdr) == NULL)
296				error(EXIT_FAILURE, 0,
297				      "Couldn't get section header from \"%s\"",
298				      filename);
299
300			data = elf_getdata(scn, NULL);
301			if (data == NULL || elf_getdata(scn, data) != NULL
302			    || shdr.sh_size != data->d_size || data->d_off)
303				error(EXIT_FAILURE, 0,
304				      "Couldn't get .strtab data from \"%s\"",
305				      filename);
306
307			lte->strtab = data->d_buf;
308		} else if (shdr.sh_type == SHT_DYNSYM) {
309			Elf_Data *data;
310
311			lte->dynsym = elf_getdata(scn, NULL);
312			lte->dynsym_count = shdr.sh_size / shdr.sh_entsize;
313			if (lte->dynsym == NULL
314			    || elf_getdata(scn, lte->dynsym) != NULL)
315				error(EXIT_FAILURE, 0,
316				      "Couldn't get .dynsym data from \"%s\"",
317				      filename);
318
319			scn = elf_getscn(lte->elf, shdr.sh_link);
320			if (scn == NULL || gelf_getshdr(scn, &shdr) == NULL)
321				error(EXIT_FAILURE, 0,
322				      "Couldn't get section header from \"%s\"",
323				      filename);
324
325			data = elf_getdata(scn, NULL);
326			if (data == NULL || elf_getdata(scn, data) != NULL
327			    || shdr.sh_size != data->d_size || data->d_off)
328				error(EXIT_FAILURE, 0,
329				      "Couldn't get .dynstr data from \"%s\"",
330				      filename);
331
332			lte->dynstr = data->d_buf;
333		} else if (shdr.sh_type == SHT_DYNAMIC) {
334			Elf_Data *data;
335			size_t j;
336
337			lte->dyn_addr = shdr.sh_addr;
338			fprintf(stderr, "dyn_addr = %#lx\n", lte->dyn_addr);
339			extern void *dyn_addr;
340			dyn_addr = (void *)lte->dyn_addr;
341			lte->dyn_sz = shdr.sh_size;
342
343			data = elf_getdata(scn, NULL);
344			if (data == NULL || elf_getdata(scn, data) != NULL)
345				error(EXIT_FAILURE, 0,
346				      "Couldn't get .dynamic data from \"%s\"",
347				      filename);
348
349			for (j = 0; j < shdr.sh_size / shdr.sh_entsize; ++j) {
350				GElf_Dyn dyn;
351
352				if (gelf_getdyn(data, j, &dyn) == NULL)
353					error(EXIT_FAILURE, 0,
354					      "Couldn't get .dynamic data from \"%s\"",
355					      filename);
356				if (dyn.d_tag == DT_JMPREL)
357					relplt_addr = dyn.d_un.d_ptr;
358				else if (dyn.d_tag == DT_PLTRELSZ)
359					lte->relplt_size = dyn.d_un.d_val;
360				else if (dyn.d_tag == DT_SONAME)
361					soname_offset = dyn.d_un.d_val;
362			}
363		} else if (shdr.sh_type == SHT_PROGBITS
364			   || shdr.sh_type == SHT_NOBITS) {
365			if (strcmp(name, ".plt") == 0) {
366				lte->plt_addr = shdr.sh_addr;
367				lte->plt_size = shdr.sh_size;
368				lte->plt_data = elf_loaddata(scn, &shdr);
369				if (lte->plt_data == NULL)
370					fprintf(stderr,
371						"Can't load .plt data\n");
372				if (shdr.sh_flags & SHF_EXECINSTR)
373					lte->lte_flags |= LTE_PLT_EXECUTABLE;
374			}
375#ifdef ARCH_SUPPORTS_OPD
376			else if (strcmp(name, ".opd") == 0) {
377				lte->opd_addr = (GElf_Addr *) (long) shdr.sh_addr;
378				lte->opd_size = shdr.sh_size;
379				lte->opd = elf_rawdata(scn, NULL);
380			}
381#endif
382		}
383	}
384
385	if (lte->dynsym == NULL || lte->dynstr == NULL)
386		error(EXIT_FAILURE, 0,
387		      "Couldn't find .dynsym or .dynstr in \"%s\"", filename);
388
389	if (!relplt_addr || !lte->plt_addr) {
390		debug(1, "%s has no PLT relocations", filename);
391		lte->relplt = NULL;
392		lte->relplt_count = 0;
393	} else if (lte->relplt_size == 0) {
394		debug(1, "%s has unknown PLT size", filename);
395		lte->relplt = NULL;
396		lte->relplt_count = 0;
397	} else {
398
399		for (i = 1; i < lte->ehdr.e_shnum; ++i) {
400			Elf_Scn *scn;
401			GElf_Shdr shdr;
402
403			scn = elf_getscn(lte->elf, i);
404			if (scn == NULL || gelf_getshdr(scn, &shdr) == NULL)
405				error(EXIT_FAILURE, 0,
406				      "Couldn't get section header from \"%s\"",
407				      filename);
408			if (shdr.sh_addr == relplt_addr
409			    && shdr.sh_size == lte->relplt_size) {
410				lte->relplt = elf_getdata(scn, NULL);
411				lte->relplt_count =
412				    shdr.sh_size / shdr.sh_entsize;
413				if (lte->relplt == NULL
414				    || elf_getdata(scn, lte->relplt) != NULL)
415					error(EXIT_FAILURE, 0,
416					      "Couldn't get .rel*.plt data from \"%s\"",
417					      filename);
418				break;
419			}
420		}
421
422		if (i == lte->ehdr.e_shnum)
423			error(EXIT_FAILURE, 0,
424			      "Couldn't find .rel*.plt section in \"%s\"",
425			      filename);
426
427		debug(1, "%s %zd PLT relocations", filename, lte->relplt_count);
428	}
429
430	if (soname_offset != 0)
431		lte->soname = lte->dynstr + soname_offset;
432
433	if (arch_elf_init(lte) < 0) {
434		fprintf(stderr, "Backend initialization failed.\n");
435		return -1;
436	}
437
438	return 0;
439}
440
441/* XXX temporarily non-static */
442void
443do_close_elf(struct ltelf *lte) {
444	debug(DEBUG_FUNCTION, "do_close_elf()");
445	arch_elf_destroy(lte);
446	elf_end(lte->elf);
447	close(lte->fd);
448}
449
450struct library *
451ltelf_read_library(struct Process *proc, const char *filename, GElf_Addr bias)
452{
453	 // XXX we leak LTE contents
454	struct ltelf lte = {};
455	if (do_init_elf(&lte, filename, bias) < 0)
456		return NULL;
457	proc->e_machine = lte.ehdr.e_machine;
458
459	struct library *lib = malloc(sizeof(*lib));
460	char *soname = NULL;
461	if (lib == NULL) {
462	fail:
463		free(soname);
464		library_destroy(lib);
465		free(lib);
466		lib = NULL;
467		goto done;
468	}
469
470	if (lte.soname != NULL) {
471		soname = strdup(lte.soname);
472		if (soname == NULL)
473			goto fail;
474	}
475
476	target_address_t entry = (target_address_t)lte.entry_addr;
477	if (arch_translate_address(proc, entry + lte.bias, &entry) < 0)
478		goto fail;
479
480	library_init(lib, soname, soname != NULL);
481	lib->base = (target_address_t)lte.base_addr;
482	lib->entry = entry;
483
484	size_t i;
485	for (i = 0; i < lte.relplt_count; ++i) {
486		GElf_Rel rel;
487		GElf_Rela rela;
488		GElf_Sym sym;
489		void *ret;
490
491		if (lte.relplt->d_type == ELF_T_REL) {
492			ret = gelf_getrel(lte.relplt, i, &rel);
493			rela.r_offset = rel.r_offset;
494			rela.r_info = rel.r_info;
495			rela.r_addend = 0;
496		} else {
497			ret = gelf_getrela(lte.relplt, i, &rela);
498		}
499
500		if (ret == NULL
501		    || ELF64_R_SYM(rela.r_info) >= lte.dynsym_count
502		    || gelf_getsym(lte.dynsym, ELF64_R_SYM(rela.r_info),
503				   &sym) == NULL)
504			error(EXIT_FAILURE, 0,
505			      "Couldn't get relocation from \"%s\"",
506			      filename);
507
508		char const *name = lte.dynstr + sym.st_name;
509		struct library_symbol *libsym;
510		switch (arch_elf_add_plt_entry(proc, &lte, name,
511					       &rela, i, &libsym)) {
512		case plt_default:
513			if (default_elf_add_plt_entry(proc, &lte, name,
514						      &rela, i, &libsym) < 0)
515		case plt_fail:
516				goto fail;
517		case plt_ok:
518			if (libsym != NULL)
519				library_add_symbol(lib, libsym);
520		}
521	}
522
523done:
524	do_close_elf(&lte);
525	return lib;
526}
527
528struct library *
529ltelf_read_main_binary(struct Process *proc, const char *path)
530{
531	fprintf(stderr, "ltelf_read_main_binary %d %s\n", proc->pid, path);
532	char *fname = pid2name(proc->pid);
533	struct library *lib = ltelf_read_library(proc, fname, 0);
534	if (lib != NULL)
535		library_set_name(lib, path, 0);
536	return lib;
537}
538