diff options
Diffstat (limited to 'tools/perf/util/symbol-elf.c')
| -rw-r--r-- | tools/perf/util/symbol-elf.c | 41 | 
1 files changed, 39 insertions, 2 deletions
diff --git a/tools/perf/util/symbol-elf.c b/tools/perf/util/symbol-elf.c index 6864661a79dd..d75349979e65 100644 --- a/tools/perf/util/symbol-elf.c +++ b/tools/perf/util/symbol-elf.c @@ -49,7 +49,8 @@ static inline uint8_t elf_sym__type(const GElf_Sym *sym)  static inline int elf_sym__is_function(const GElf_Sym *sym)  { -	return elf_sym__type(sym) == STT_FUNC && +	return (elf_sym__type(sym) == STT_FUNC || +		elf_sym__type(sym) == STT_GNU_IFUNC) &&  	       sym->st_name != 0 &&  	       sym->st_shndx != SHN_UNDEF;  } @@ -598,6 +599,8 @@ int symsrc__init(struct symsrc *ss, struct dso *dso, const char *name,  			goto out_elf_end;  	} +	ss->is_64_bit = (gelf_getclass(elf) == ELFCLASS64); +  	ss->symtab = elf_section_by_name(elf, &ehdr, &ss->symshdr, ".symtab",  			NULL);  	if (ss->symshdr.sh_type != SHT_SYMTAB) @@ -619,7 +622,7 @@ int symsrc__init(struct symsrc *ss, struct dso *dso, const char *name,  		GElf_Shdr shdr;  		ss->adjust_symbols = (ehdr.e_type == ET_EXEC ||  				ehdr.e_type == ET_REL || -				is_vdso_map(dso->short_name) || +				dso__is_vdso(dso) ||  				elf_section_by_name(elf, &ehdr, &shdr,  						     ".gnu.prelink_undo",  						     NULL) != NULL); @@ -698,6 +701,7 @@ int dso__load_sym(struct dso *dso, struct map *map,  	bool remap_kernel = false, adjust_kernel_syms = false;  	dso->symtab_type = syms_ss->type; +	dso->is_64_bit = syms_ss->is_64_bit;  	dso->rel = syms_ss->ehdr.e_type == ET_REL;  	/* @@ -1024,6 +1028,39 @@ int file__read_maps(int fd, bool exe, mapfn_t mapfn, void *data,  	return err;  } +enum dso_type dso__type_fd(int fd) +{ +	enum dso_type dso_type = DSO__TYPE_UNKNOWN; +	GElf_Ehdr ehdr; +	Elf_Kind ek; +	Elf *elf; + +	elf = elf_begin(fd, PERF_ELF_C_READ_MMAP, NULL); +	if (elf == NULL) +		goto out; + +	ek = elf_kind(elf); +	if (ek != ELF_K_ELF) +		goto out_end; + +	if (gelf_getclass(elf) == ELFCLASS64) { +		dso_type = DSO__TYPE_64BIT; +		goto out_end; +	} + +	if (gelf_getehdr(elf, &ehdr) == NULL) +		goto out_end; + +	if (ehdr.e_machine == EM_X86_64) +		dso_type = DSO__TYPE_X32BIT; +	else +		dso_type = DSO__TYPE_32BIT; +out_end: +	elf_end(elf); +out: +	return dso_type; +} +  static int copy_bytes(int from, off_t from_offs, int to, off_t to_offs, u64 len)  {  	ssize_t r;  |