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