ltrace-elf.c revision b1492dfaca6882fa0798b549e0557c7dec6b7e9c
1#include "config.h"
2
3#include <assert.h>
4#include <endian.h>
5#include <errno.h>
6#include <fcntl.h>
7#include <gelf.h>
8#include <inttypes.h>
9#include <search.h>
10#include <stdint.h>
11#include <stdio.h>
12#include <stdlib.h>
13#include <string.h>
14#include <unistd.h>
15
16#include "common.h"
17#include "proc.h"
18#include "library.h"
19#include "filter.h"
20
21#ifdef PLT_REINITALISATION_BP
22extern char *PLTs_initialized_by_here;
23#endif
24
25#ifndef ARCH_HAVE_LTELF_DATA
26int
27arch_elf_init(struct ltelf *lte, struct library *lib)
28{
29	return 0;
30}
31
32void
33arch_elf_destroy(struct ltelf *lte)
34{
35}
36#endif
37
38int
39default_elf_add_plt_entry(struct Process *proc, struct ltelf *lte,
40			  const char *a_name, GElf_Rela *rela, size_t ndx,
41			  struct library_symbol **ret)
42{
43	char *name = strdup(a_name);
44	if (name == NULL) {
45	fail:
46		free(name);
47		return -1;
48	}
49
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	/* XXX The double cast should be removed when
57	 * target_address_t becomes integral type.  */
58	target_address_t taddr = (target_address_t)
59		(uintptr_t)(addr + lte->bias);
60
61	if (library_symbol_init(libsym, taddr, name, 1, LS_TOPLT_EXEC) < 0) {
62		free(libsym);
63		goto fail;
64	}
65
66	*ret = libsym;
67	return 0;
68}
69
70#ifndef ARCH_HAVE_ADD_PLT_ENTRY
71enum plt_status
72arch_elf_add_plt_entry(struct Process *proc, struct ltelf *lte,
73		       const char *a_name, GElf_Rela *rela, size_t ndx,
74		       struct library_symbol **ret)
75{
76	return plt_default;
77}
78#endif
79
80Elf_Data *
81elf_loaddata(Elf_Scn *scn, GElf_Shdr *shdr)
82{
83	Elf_Data *data = elf_getdata(scn, NULL);
84	if (data == NULL || elf_getdata(scn, data) != NULL
85	    || data->d_off || data->d_size != shdr->sh_size)
86		return NULL;
87	return data;
88}
89
90static int
91elf_get_section_if(struct ltelf *lte, Elf_Scn **tgt_sec, GElf_Shdr *tgt_shdr,
92		   int (*predicate)(Elf_Scn *, GElf_Shdr *, void *data),
93		   void *data)
94{
95	int i;
96	for (i = 1; i < lte->ehdr.e_shnum; ++i) {
97		Elf_Scn *scn;
98		GElf_Shdr shdr;
99
100		scn = elf_getscn(lte->elf, i);
101		if (scn == NULL || gelf_getshdr(scn, &shdr) == NULL) {
102			debug(1, "Couldn't read section or header.");
103			return -1;
104		}
105		if (predicate(scn, &shdr, data)) {
106			*tgt_sec = scn;
107			*tgt_shdr = shdr;
108			return 0;
109		}
110	}
111	return -1;
112
113}
114
115static int
116inside_p(Elf_Scn *scn, GElf_Shdr *shdr, void *data)
117{
118	GElf_Addr addr = *(GElf_Addr *)data;
119	return addr >= shdr->sh_addr
120		&& addr < shdr->sh_addr + shdr->sh_size;
121}
122
123int
124elf_get_section_covering(struct ltelf *lte, GElf_Addr addr,
125			 Elf_Scn **tgt_sec, GElf_Shdr *tgt_shdr)
126{
127	return elf_get_section_if(lte, tgt_sec, tgt_shdr,
128				  &inside_p, &addr);
129}
130
131static int
132type_p(Elf_Scn *scn, GElf_Shdr *shdr, void *data)
133{
134	GElf_Word type = *(GElf_Word *)data;
135	return shdr->sh_type == type;
136}
137
138int
139elf_get_section_type(struct ltelf *lte, GElf_Word type,
140		     Elf_Scn **tgt_sec, GElf_Shdr *tgt_shdr)
141{
142	return elf_get_section_if(lte, tgt_sec, tgt_shdr,
143				  &type_p, &type);
144}
145
146struct section_named_data {
147	struct ltelf *lte;
148	const char *name;
149};
150
151static int
152name_p(Elf_Scn *scn, GElf_Shdr *shdr, void *d)
153{
154	struct section_named_data *data = d;
155	const char *name = elf_strptr(data->lte->elf,
156				      data->lte->ehdr.e_shstrndx,
157				      shdr->sh_name);
158	return strcmp(name, data->name) == 0;
159}
160
161int
162elf_get_section_named(struct ltelf *lte, const char *name,
163		     Elf_Scn **tgt_sec, GElf_Shdr *tgt_shdr)
164{
165	struct section_named_data data = {
166		.lte = lte,
167		.name = name,
168	};
169	return elf_get_section_if(lte, tgt_sec, tgt_shdr,
170				  &name_p, &data);
171}
172
173static int
174need_data(Elf_Data *data, GElf_Xword offset, GElf_Xword size)
175{
176	assert(data != NULL);
177	if (data->d_size < size || offset > data->d_size - size) {
178		debug(1, "Not enough data to read %zd-byte value"
179		      " at offset %zd.", size, offset);
180		return -1;
181	}
182	return 0;
183}
184
185#define DEF_READER(NAME, SIZE)						\
186	int								\
187	NAME(Elf_Data *data, GElf_Xword offset, uint##SIZE##_t *retp)	\
188	{								\
189		if (!need_data(data, offset, SIZE / 8) < 0)		\
190			return -1;					\
191									\
192		if (data->d_buf == NULL) /* NODATA section */ {		\
193			*retp = 0;					\
194			return 0;					\
195		}							\
196									\
197		union {							\
198			uint##SIZE##_t dst;				\
199			char buf[0];					\
200		} u;							\
201		memcpy(u.buf, data->d_buf + offset, sizeof(u.dst));	\
202		*retp = u.dst;						\
203		return 0;						\
204	}
205
206DEF_READER(elf_read_u16, 16)
207DEF_READER(elf_read_u32, 32)
208DEF_READER(elf_read_u64, 64)
209
210#undef DEF_READER
211
212int
213open_elf(struct ltelf *lte, const char *filename)
214{
215	lte->fd = open(filename, O_RDONLY);
216	if (lte->fd == -1)
217		return 1;
218
219	elf_version(EV_CURRENT);
220
221#ifdef HAVE_ELF_C_READ_MMAP
222	lte->elf = elf_begin(lte->fd, ELF_C_READ_MMAP, NULL);
223#else
224	lte->elf = elf_begin(lte->fd, ELF_C_READ, NULL);
225#endif
226
227	if (lte->elf == NULL || elf_kind(lte->elf) != ELF_K_ELF) {
228		fprintf(stderr, "\"%s\" is not an ELF file\n", filename);
229		exit(EXIT_FAILURE);
230	}
231
232	if (gelf_getehdr(lte->elf, &lte->ehdr) == NULL) {
233		fprintf(stderr, "can't read ELF header of \"%s\": %s\n",
234			filename, elf_errmsg(-1));
235		exit(EXIT_FAILURE);
236	}
237
238	if (lte->ehdr.e_type != ET_EXEC && lte->ehdr.e_type != ET_DYN) {
239		fprintf(stderr, "\"%s\" is neither an ELF executable"
240			" nor a shared library\n", filename);
241		exit(EXIT_FAILURE);
242	}
243
244	if ((lte->ehdr.e_ident[EI_CLASS] != LT_ELFCLASS
245	     || lte->ehdr.e_machine != LT_ELF_MACHINE)
246#ifdef LT_ELF_MACHINE2
247	    && (lte->ehdr.e_ident[EI_CLASS] != LT_ELFCLASS2
248		|| lte->ehdr.e_machine != LT_ELF_MACHINE2)
249#endif
250#ifdef LT_ELF_MACHINE3
251	    && (lte->ehdr.e_ident[EI_CLASS] != LT_ELFCLASS3
252		|| lte->ehdr.e_machine != LT_ELF_MACHINE3)
253#endif
254		) {
255		fprintf(stderr,
256			"\"%s\" is ELF from incompatible architecture\n",
257			filename);
258		exit(EXIT_FAILURE);
259	}
260
261	return 0;
262}
263
264static void
265read_symbol_table(struct ltelf *lte, const char *filename,
266		  Elf_Scn *scn, GElf_Shdr *shdr, const char *name,
267		  Elf_Data **datap, size_t *countp, const char **strsp)
268{
269	*datap = elf_getdata(scn, NULL);
270	*countp = shdr->sh_size / shdr->sh_entsize;
271	if ((*datap == NULL || elf_getdata(scn, *datap) != NULL)
272	    && options.static_filter != NULL) {
273		fprintf(stderr, "Couldn't get data of section"
274			" %s from \"%s\": %s\n",
275			name, filename, elf_errmsg(-1));
276		exit(EXIT_FAILURE);
277	}
278
279	scn = elf_getscn(lte->elf, shdr->sh_link);
280	GElf_Shdr shdr2;
281	if (scn == NULL || gelf_getshdr(scn, &shdr2) == NULL) {
282		fprintf(stderr, "Couldn't get header of section"
283			" #%d from \"%s\": %s\n",
284			shdr2.sh_link, filename, elf_errmsg(-1));
285		exit(EXIT_FAILURE);
286	}
287
288	Elf_Data *data = elf_getdata(scn, NULL);
289	if (data == NULL || elf_getdata(scn, data) != NULL
290	    || shdr2.sh_size != data->d_size || data->d_off) {
291		fprintf(stderr, "Couldn't get data of section"
292			" #%d from \"%s\": %s\n",
293			shdr2.sh_link, filename, elf_errmsg(-1));
294		exit(EXIT_FAILURE);
295	}
296
297	*strsp = data->d_buf;
298}
299
300static int
301do_init_elf(struct ltelf *lte, const char *filename, GElf_Addr bias)
302{
303	int i;
304	GElf_Addr relplt_addr = 0;
305	GElf_Addr soname_offset = 0;
306
307	debug(DEBUG_FUNCTION, "do_init_elf(filename=%s)", filename);
308	debug(1, "Reading ELF from %s...", filename);
309
310	if (open_elf(lte, filename) < 0)
311		return -1;
312
313	/* Find out the base address.  */
314	{
315		GElf_Phdr phdr;
316		for (i = 0; gelf_getphdr (lte->elf, i, &phdr) != NULL; ++i) {
317			if (phdr.p_type == PT_LOAD) {
318				lte->base_addr = phdr.p_vaddr + bias;
319				break;
320			}
321		}
322	}
323
324	if (lte->base_addr == 0) {
325		fprintf(stderr, "Couldn't determine base address of %s\n",
326			filename);
327		return -1;
328	}
329
330	lte->bias = bias;
331	lte->entry_addr = lte->ehdr.e_entry + lte->bias;
332
333	for (i = 1; i < lte->ehdr.e_shnum; ++i) {
334		Elf_Scn *scn;
335		GElf_Shdr shdr;
336		const char *name;
337
338		scn = elf_getscn(lte->elf, i);
339		if (scn == NULL || gelf_getshdr(scn, &shdr) == NULL) {
340			fprintf(stderr,	"Couldn't get section #%d from"
341				" \"%s\": %s\n", i, filename, elf_errmsg(-1));
342			exit(EXIT_FAILURE);
343		}
344
345		name = elf_strptr(lte->elf, lte->ehdr.e_shstrndx, shdr.sh_name);
346		if (name == NULL) {
347			fprintf(stderr,	"Couldn't get name of section #%d from"
348				" \"%s\": %s\n", i, filename, elf_errmsg(-1));
349			exit(EXIT_FAILURE);
350		}
351
352		if (shdr.sh_type == SHT_SYMTAB) {
353			read_symbol_table(lte, filename,
354					  scn, &shdr, name, &lte->symtab,
355					  &lte->symtab_count, &lte->strtab);
356
357		} else if (shdr.sh_type == SHT_DYNSYM) {
358			read_symbol_table(lte, filename,
359					  scn, &shdr, name, &lte->dynsym,
360					  &lte->dynsym_count, &lte->dynstr);
361
362		} else if (shdr.sh_type == SHT_DYNAMIC) {
363			Elf_Data *data;
364			size_t j;
365
366			lte->dyn_addr = shdr.sh_addr;
367			lte->dyn_sz = shdr.sh_size;
368
369			data = elf_getdata(scn, NULL);
370			if (data == NULL || elf_getdata(scn, data) != NULL) {
371				fprintf(stderr, "Couldn't get .dynamic data"
372					" from \"%s\": %s\n",
373					filename, strerror(errno));
374				exit(EXIT_FAILURE);
375			}
376
377			for (j = 0; j < shdr.sh_size / shdr.sh_entsize; ++j) {
378				GElf_Dyn dyn;
379
380				if (gelf_getdyn(data, j, &dyn) == NULL) {
381					fprintf(stderr, "Couldn't get .dynamic"
382						" data from \"%s\": %s\n",
383						filename, strerror(errno));
384					exit(EXIT_FAILURE);
385				}
386				if (dyn.d_tag == DT_JMPREL)
387					relplt_addr = dyn.d_un.d_ptr;
388				else if (dyn.d_tag == DT_PLTRELSZ)
389					lte->relplt_size = dyn.d_un.d_val;
390				else if (dyn.d_tag == DT_SONAME)
391					soname_offset = dyn.d_un.d_val;
392			}
393		} else if (shdr.sh_type == SHT_PROGBITS
394			   || shdr.sh_type == SHT_NOBITS) {
395			if (strcmp(name, ".plt") == 0) {
396				lte->plt_addr = shdr.sh_addr;
397				lte->plt_size = shdr.sh_size;
398				lte->plt_data = elf_loaddata(scn, &shdr);
399				if (lte->plt_data == NULL)
400					fprintf(stderr,
401						"Can't load .plt data\n");
402				lte->plt_flags = shdr.sh_flags;
403			}
404#ifdef ARCH_SUPPORTS_OPD
405			else if (strcmp(name, ".opd") == 0) {
406				lte->opd_addr = (GElf_Addr *) (long) shdr.sh_addr;
407				lte->opd_size = shdr.sh_size;
408				lte->opd = elf_rawdata(scn, NULL);
409			}
410#endif
411		}
412	}
413
414	if (lte->dynsym == NULL || lte->dynstr == NULL) {
415		fprintf(stderr, "Couldn't find .dynsym or .dynstr in \"%s\"\n",
416			filename);
417		exit(EXIT_FAILURE);
418	}
419
420	if (!relplt_addr || !lte->plt_addr) {
421		debug(1, "%s has no PLT relocations", filename);
422		lte->relplt = NULL;
423		lte->relplt_count = 0;
424	} else if (lte->relplt_size == 0) {
425		debug(1, "%s has unknown PLT size", filename);
426		lte->relplt = NULL;
427		lte->relplt_count = 0;
428	} else {
429
430		for (i = 1; i < lte->ehdr.e_shnum; ++i) {
431			Elf_Scn *scn;
432			GElf_Shdr shdr;
433
434			scn = elf_getscn(lte->elf, i);
435			if (scn == NULL || gelf_getshdr(scn, &shdr) == NULL) {
436				fprintf(stderr, "Couldn't get section header"
437					" from \"%s\": %s\n",
438					filename, elf_errmsg(-1));
439				exit(EXIT_FAILURE);
440			}
441			if (shdr.sh_addr == relplt_addr
442			    && shdr.sh_size == lte->relplt_size) {
443				lte->relplt = elf_getdata(scn, NULL);
444				lte->relplt_count =
445				    shdr.sh_size / shdr.sh_entsize;
446				if (lte->relplt == NULL
447				    || elf_getdata(scn, lte->relplt) != NULL) {
448					fprintf(stderr, "Couldn't get .rel*.plt"
449						" data from \"%s\": %s\n",
450						filename, elf_errmsg(-1));
451					exit(EXIT_FAILURE);
452				}
453				break;
454			}
455		}
456
457		if (i == lte->ehdr.e_shnum) {
458			fprintf(stderr,
459				"Couldn't find .rel*.plt section in \"%s\"\n",
460				filename);
461			exit(EXIT_FAILURE);
462		}
463
464		debug(1, "%s %zd PLT relocations", filename, lte->relplt_count);
465	}
466
467	if (soname_offset != 0)
468		lte->soname = lte->dynstr + soname_offset;
469
470	return 0;
471}
472
473/* XXX temporarily non-static */
474void
475do_close_elf(struct ltelf *lte) {
476	debug(DEBUG_FUNCTION, "do_close_elf()");
477	arch_elf_destroy(lte);
478	elf_end(lte->elf);
479	close(lte->fd);
480}
481
482static int
483populate_plt(struct Process *proc, const char *filename,
484	     struct ltelf *lte, struct library *lib)
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		void *ret;
492
493		if (lte->relplt->d_type == ELF_T_REL) {
494			ret = gelf_getrel(lte->relplt, i, &rel);
495			rela.r_offset = rel.r_offset;
496			rela.r_info = rel.r_info;
497			rela.r_addend = 0;
498		} else {
499			ret = gelf_getrela(lte->relplt, i, &rela);
500		}
501
502		if (ret == NULL
503		    || ELF64_R_SYM(rela.r_info) >= lte->dynsym_count
504		    || gelf_getsym(lte->dynsym, ELF64_R_SYM(rela.r_info),
505				   &sym) == NULL) {
506			fprintf(stderr,
507				"Couldn't get relocation from \"%s\": %s\n",
508				filename, elf_errmsg(-1));
509			exit(EXIT_FAILURE);
510		}
511
512		char const *name = lte->dynstr + sym.st_name;
513
514		if (!filter_matches_symbol(options.plt_filter, name, lib))
515			continue;
516
517		struct library_symbol *libsym = NULL;
518		switch (arch_elf_add_plt_entry(proc, lte, name,
519					       &rela, i, &libsym)) {
520		case plt_default:
521			if (default_elf_add_plt_entry(proc, lte, name,
522						      &rela, i, &libsym) < 0)
523			/* fall-through */
524		case plt_fail:
525				return -1;
526			/* fall-through */
527		case plt_ok:
528			if (libsym != NULL)
529				library_add_symbol(lib, libsym);
530		}
531	}
532	return 0;
533}
534
535/* When -x rules result in request to trace several aliases, we only
536 * want to add such symbol once.  The only way that those symbols
537 * differ in is their name, e.g. in glibc you have __GI___libc_free,
538 * __cfree, __free, __libc_free, cfree and free all defined on the
539 * same address.  So instead we keep this unique symbol struct for
540 * each address, and replace name in libsym with a shorter variant if
541 * we find it.  */
542struct unique_symbol {
543	target_address_t addr;
544	struct library_symbol *libsym;
545};
546
547static int
548unique_symbol_cmp(const void *key, const void *val)
549{
550	const struct unique_symbol *sym_key = key;
551	const struct unique_symbol *sym_val = val;
552	return sym_key->addr != sym_val->addr;
553}
554
555static int
556populate_this_symtab(struct Process *proc, const char *filename,
557		     struct ltelf *lte, struct library *lib,
558		     Elf_Data *symtab, const char *strtab, size_t size)
559{
560	/* Using sorted array would be arguably better, but this
561	 * should be well enough for the number of symbols that we
562	 * typically deal with.  */
563	size_t num_symbols = 0;
564	struct unique_symbol *symbols = malloc(sizeof(*symbols) * size);
565	if (symbols == NULL) {
566		fprintf(stderr, "couldn't insert symbols for -x: %s\n",
567			strerror(errno));
568		return -1;
569	}
570
571	GElf_Word secflags[lte->ehdr.e_shnum];
572	size_t i;
573	for (i = 1; i < lte->ehdr.e_shnum; ++i) {
574		Elf_Scn *scn = elf_getscn(lte->elf, i);
575		if (scn == NULL)
576			continue;
577		GElf_Shdr shdr;
578		if (gelf_getshdr(scn, &shdr) == NULL)
579			continue;
580		secflags[i] = shdr.sh_flags;
581	}
582
583	size_t lib_len = strlen(lib->soname);
584	for (i = 0; i < size; ++i) {
585		GElf_Sym sym;
586		if (gelf_getsym(symtab, i, &sym) == NULL) {
587		fail:
588			fprintf(stderr,
589				"couldn't get symbol #%zd from %s: %s\n",
590				i, filename, elf_errmsg(-1));
591			continue;
592		}
593
594		/* XXX support IFUNC as well.  */
595		if (GELF_ST_TYPE(sym.st_info) != STT_FUNC
596		    || sym.st_value == 0)
597			continue;
598
599		const char *orig_name = strtab + sym.st_name;
600		const char *version = strchr(orig_name, '@');
601		size_t len = version != NULL ? (assert(version > orig_name),
602						(size_t)(version - orig_name))
603			: strlen(orig_name);
604		char name[len + 1];
605		memcpy(name, orig_name, len);
606		name[len] = 0;
607
608		if (!filter_matches_symbol(options.static_filter, name, lib))
609			continue;
610
611		target_address_t addr = (target_address_t)
612			(uintptr_t)(sym.st_value + lte->bias);
613		target_address_t naddr;
614
615		/* On arches that support OPD, the value of typical
616		 * function symbol will be a pointer to .opd, but some
617		 * will point directly to .text.  We don't want to
618		 * translate those.  */
619		if (secflags[sym.st_shndx] & SHF_EXECINSTR) {
620			naddr = addr;
621		} else if (arch_translate_address(lte, addr, &naddr) < 0) {
622			fprintf(stderr,
623				"couldn't translate address of %s@%s: %s\n",
624				name, lib->soname, strerror(errno));
625			continue;
626		}
627
628		char *full_name;
629		if (lib->type != LT_LIBTYPE_MAIN) {
630			full_name = malloc(strlen(name) + 1 + lib_len + 1);
631			if (full_name == NULL)
632				goto fail;
633			sprintf(full_name, "%s@%s", name, lib->soname);
634		} else {
635			full_name = strdup(name);
636			if (full_name == NULL)
637				goto fail;
638		}
639
640		/* Look whether we already have a symbol for this
641		 * address.  If not, add this one.  */
642		struct unique_symbol key = { naddr, NULL };
643		struct unique_symbol *unique
644			= lsearch(&key, symbols, &num_symbols,
645				  sizeof(*symbols), &unique_symbol_cmp);
646
647		if (unique->libsym == NULL) {
648			struct library_symbol *libsym = malloc(sizeof(*libsym));
649			if (libsym == NULL
650			    || library_symbol_init(libsym, naddr, full_name,
651						   1, LS_TOPLT_NONE) < 0) {
652				--num_symbols;
653				goto fail;
654			}
655			unique->libsym = libsym;
656			unique->addr = naddr;
657
658		} else if (strlen(full_name) < strlen(unique->libsym->name)) {
659			library_symbol_set_name(unique->libsym, full_name, 1);
660
661		} else {
662			free(full_name);
663		}
664	}
665
666	for (i = 0; i < num_symbols; ++i) {
667		assert(symbols[i].libsym != NULL);
668		library_add_symbol(lib, symbols[i].libsym);
669	}
670
671	free(symbols);
672
673	return 0;
674}
675
676static int
677populate_symtab(struct Process *proc, const char *filename,
678		struct ltelf *lte, struct library *lib)
679{
680	if (lte->symtab != NULL && lte->strtab != NULL)
681		return populate_this_symtab(proc, filename, lte, lib,
682					    lte->symtab, lte->strtab,
683					    lte->symtab_count);
684	else
685		return populate_this_symtab(proc, filename, lte, lib,
686					    lte->dynsym, lte->dynstr,
687					    lte->dynsym_count);
688}
689
690int
691ltelf_read_library(struct library *lib, struct Process *proc,
692		   const char *filename, GElf_Addr bias)
693{
694	struct ltelf lte = {};
695	if (do_init_elf(&lte, filename, bias) < 0)
696		return -1;
697	if (arch_elf_init(&lte, lib) < 0) {
698		fprintf(stderr, "Backend initialization failed.\n");
699		return -1;
700	}
701
702	proc->e_machine = lte.ehdr.e_machine;
703
704	int status = 0;
705	if (lib == NULL)
706		goto fail;
707
708	/* Note that we set soname and pathname as soon as they are
709	 * allocated, so in case of further errors, this get released
710	 * when LIB is release, which should happen in the caller when
711	 * we return error.  */
712
713	if (lib->pathname == NULL) {
714		char *pathname = strdup(filename);
715		if (pathname == NULL)
716			goto fail;
717		library_set_pathname(lib, pathname, 1);
718	}
719
720	if (lte.soname != NULL) {
721		char *soname = strdup(lte.soname);
722		if (soname == NULL)
723			goto fail;
724		library_set_soname(lib, soname, 1);
725	} else {
726		const char *soname = rindex(lib->pathname, '/') + 1;
727		if (soname == NULL)
728			soname = lib->pathname;
729		library_set_soname(lib, soname, 0);
730	}
731
732	/* XXX The double cast should be removed when
733	 * target_address_t becomes integral type.  */
734	target_address_t entry = (target_address_t)(uintptr_t)lte.entry_addr;
735	if (arch_translate_address(&lte, entry, &entry) < 0)
736		goto fail;
737
738	/* XXX The double cast should be removed when
739	 * target_address_t becomes integral type.  */
740	lib->base = (target_address_t)(uintptr_t)lte.base_addr;
741	lib->entry = entry;
742	/* XXX The double cast should be removed when
743	 * target_address_t becomes integral type.  */
744	lib->dyn_addr = (target_address_t)(uintptr_t)lte.dyn_addr;
745
746	if (filter_matches_library(options.plt_filter, lib)
747	    && populate_plt(proc, filename, &lte, lib) < 0)
748		goto fail;
749
750	if (filter_matches_library(options.static_filter, lib)
751	    && populate_symtab(proc, filename, &lte, lib) < 0)
752		goto fail;
753
754done:
755	do_close_elf(&lte);
756	return status;
757
758fail:
759	status = -1;
760	goto done;
761}
762
763struct library *
764ltelf_read_main_binary(struct Process *proc, const char *path)
765{
766	struct library *lib = malloc(sizeof(*lib));
767	if (lib == NULL)
768		return NULL;
769	library_init(lib, LT_LIBTYPE_MAIN);
770	library_set_pathname(lib, path, 0);
771
772	/* There is a race between running the process and reading its
773	 * binary for internal consumption.  So open the binary from
774	 * the /proc filesystem.  XXX Note that there is similar race
775	 * for libraries, but there we don't have a nice answer like
776	 * that.  Presumably we could read the DSOs from the process
777	 * memory image, but that's not currently done.  */
778	char *fname = pid2name(proc->pid);
779	if (ltelf_read_library(lib, proc, fname, 0) < 0) {
780		library_destroy(lib);
781		free(lib);
782		return NULL;
783	}
784
785	return lib;
786}
787