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