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