// SPDX-License-Identifier: GPL-2.0
#include <fcntl.h>
#include <stdio.h>
#include <errno.h>
#include <stdlib.h>
#include <string.h>
#include <unistd.h>
#include <inttypes.h>

#include "compress.h"
#include "dso.h"
#include "libbfd.h"
#include "map.h"
#include "maps.h"
#include "symbol.h"
#include "symsrc.h"
#include "machine.h"
#include "vdso.h"
#include "debug.h"
#include "util/copyfile.h"
#include <linux/ctype.h>
#include <linux/kernel.h>
#include <linux/zalloc.h>
#include <linux/string.h>
#include <symbol/kallsyms.h>
#include <internal/lib.h>

#ifndef EM_AARCH64
#define EM_AARCH64	183  /* ARM 64 bit */
#endif

#ifndef EM_LOONGARCH
#define EM_LOONGARCH	258
#endif

#ifndef ELF32_ST_VISIBILITY
#define ELF32_ST_VISIBILITY(o)	((o) & 0x03)
#endif

/* For ELF64 the definitions are the same.  */
#ifndef ELF64_ST_VISIBILITY
#define ELF64_ST_VISIBILITY(o)	ELF32_ST_VISIBILITY (o)
#endif

/* How to extract information held in the st_other field.  */
#ifndef GELF_ST_VISIBILITY
#define GELF_ST_VISIBILITY(val)	ELF64_ST_VISIBILITY (val)
#endif

typedef Elf64_Nhdr GElf_Nhdr;


#ifndef HAVE_ELF_GETPHDRNUM_SUPPORT
static int elf_getphdrnum(Elf *elf, size_t *dst)
{
	GElf_Ehdr gehdr;
	GElf_Ehdr *ehdr;

	ehdr = gelf_getehdr(elf, &gehdr);
	if (!ehdr)
		return -1;

	*dst = ehdr->e_phnum;

	return 0;
}
#endif

#ifndef HAVE_ELF_GETSHDRSTRNDX_SUPPORT
static int elf_getshdrstrndx(Elf *elf __maybe_unused, size_t *dst __maybe_unused)
{
	pr_err("%s: update your libelf to > 0.140, this one lacks elf_getshdrstrndx().\n", __func__);
	return -1;
}
#endif

#ifndef NT_GNU_BUILD_ID
#define NT_GNU_BUILD_ID 3
#endif

/**
 * elf_symtab__for_each_symbol - iterate thru all the symbols
 *
 * @syms: struct elf_symtab instance to iterate
 * @idx: uint32_t idx
 * @sym: GElf_Sym iterator
 */
#define elf_symtab__for_each_symbol(syms, nr_syms, idx, sym) \
	for (idx = 0, gelf_getsym(syms, idx, &sym);\
	     idx < nr_syms; \
	     idx++, gelf_getsym(syms, idx, &sym))

static inline uint8_t elf_sym__type(const GElf_Sym *sym)
{
	return GELF_ST_TYPE(sym->st_info);
}

static inline uint8_t elf_sym__visibility(const GElf_Sym *sym)
{
	return GELF_ST_VISIBILITY(sym->st_other);
}

#ifndef STT_GNU_IFUNC
#define STT_GNU_IFUNC 10
#endif

static inline int elf_sym__is_function(const GElf_Sym *sym)
{
	return (elf_sym__type(sym) == STT_FUNC ||
		elf_sym__type(sym) == STT_GNU_IFUNC) &&
	       sym->st_name != 0 &&
	       sym->st_shndx != SHN_UNDEF;
}

static inline bool elf_sym__is_object(const GElf_Sym *sym)
{
	return elf_sym__type(sym) == STT_OBJECT &&
		sym->st_name != 0 &&
		sym->st_shndx != SHN_UNDEF;
}

static inline int elf_sym__is_label(const GElf_Sym *sym)
{
	return elf_sym__type(sym) == STT_NOTYPE &&
		sym->st_name != 0 &&
		sym->st_shndx != SHN_UNDEF &&
		sym->st_shndx != SHN_ABS &&
		elf_sym__visibility(sym) != STV_HIDDEN &&
		elf_sym__visibility(sym) != STV_INTERNAL;
}

static bool elf_sym__filter(GElf_Sym *sym)
{
	return elf_sym__is_function(sym) || elf_sym__is_object(sym);
}

static inline const char *elf_sym__name(const GElf_Sym *sym,
					const Elf_Data *symstrs)
{
	return symstrs->d_buf + sym->st_name;
}

static inline const char *elf_sec__name(const GElf_Shdr *shdr,
					const Elf_Data *secstrs)
{
	return secstrs->d_buf + shdr->sh_name;
}

static inline int elf_sec__is_text(const GElf_Shdr *shdr,
					const Elf_Data *secstrs)
{
	return strstr(elf_sec__name(shdr, secstrs), "text") != NULL;
}

static inline bool elf_sec__is_data(const GElf_Shdr *shdr,
				    const Elf_Data *secstrs)
{
	return strstr(elf_sec__name(shdr, secstrs), "data") != NULL;
}

static bool elf_sec__filter(GElf_Shdr *shdr, Elf_Data *secstrs)
{
	return elf_sec__is_text(shdr, secstrs) ||
	       elf_sec__is_data(shdr, secstrs);
}

static size_t elf_addr_to_index(Elf *elf, GElf_Addr addr)
{
	Elf_Scn *sec = NULL;
	GElf_Shdr shdr;
	size_t cnt = 1;

	while ((sec = elf_nextscn(elf, sec)) != NULL) {
		gelf_getshdr(sec, &shdr);

		if ((addr >= shdr.sh_addr) &&
		    (addr < (shdr.sh_addr + shdr.sh_size)))
			return cnt;

		++cnt;
	}

	return -1;
}

Elf_Scn *elf_section_by_name(Elf *elf, GElf_Ehdr *ep,
			     GElf_Shdr *shp, const char *name, size_t *idx)
{
	Elf_Scn *sec = NULL;
	size_t cnt = 1;

	/* ELF is corrupted/truncated, avoid calling elf_strptr. */
	if (!elf_rawdata(elf_getscn(elf, ep->e_shstrndx), NULL))
		return NULL;

	while ((sec = elf_nextscn(elf, sec)) != NULL) {
		char *str;

		gelf_getshdr(sec, shp);
		str = elf_strptr(elf, ep->e_shstrndx, shp->sh_name);
		if (str && !strcmp(name, str)) {
			if (idx)
				*idx = cnt;
			return sec;
		}
		++cnt;
	}

	return NULL;
}

bool filename__has_section(const char *filename, const char *sec)
{
	int fd;
	Elf *elf;
	GElf_Ehdr ehdr;
	GElf_Shdr shdr;
	bool found = false;

	fd = open(filename, O_RDONLY);
	if (fd < 0)
		return false;

	elf = elf_begin(fd, PERF_ELF_C_READ_MMAP, NULL);
	if (elf == NULL)
		goto out;

	if (gelf_getehdr(elf, &ehdr) == NULL)
		goto elf_out;

	found = !!elf_section_by_name(elf, &ehdr, &shdr, sec, NULL);

elf_out:
	elf_end(elf);
out:
	close(fd);
	return found;
}

static int elf_read_program_header(Elf *elf, u64 vaddr, GElf_Phdr *phdr)
{
	size_t i, phdrnum;
	u64 sz;

	if (elf_getphdrnum(elf, &phdrnum))
		return -1;

	for (i = 0; i < phdrnum; i++) {
		if (gelf_getphdr(elf, i, phdr) == NULL)
			return -1;

		if (phdr->p_type != PT_LOAD)
			continue;

		sz = max(phdr->p_memsz, phdr->p_filesz);
		if (!sz)
			continue;

		if (vaddr >= phdr->p_vaddr && (vaddr < phdr->p_vaddr + sz))
			return 0;
	}

	/* Not found any valid program header */
	return -1;
}

struct rel_info {
	u32		nr_entries;
	u32		*sorted;
	bool		is_rela;
	Elf_Data	*reldata;
	GElf_Rela	rela;
	GElf_Rel	rel;
};

static u32 get_rel_symidx(struct rel_info *ri, u32 idx)
{
	idx = ri->sorted ? ri->sorted[idx] : idx;
	if (ri->is_rela) {
		gelf_getrela(ri->reldata, idx, &ri->rela);
		return GELF_R_SYM(ri->rela.r_info);
	}
	gelf_getrel(ri->reldata, idx, &ri->rel);
	return GELF_R_SYM(ri->rel.r_info);
}

static u64 get_rel_offset(struct rel_info *ri, u32 x)
{
	if (ri->is_rela) {
		GElf_Rela rela;

		gelf_getrela(ri->reldata, x, &rela);
		return rela.r_offset;
	} else {
		GElf_Rel rel;

		gelf_getrel(ri->reldata, x, &rel);
		return rel.r_offset;
	}
}

static int rel_cmp(const void *a, const void *b, void *r)
{
	struct rel_info *ri = r;
	u64 a_offset = get_rel_offset(ri, *(const u32 *)a);
	u64 b_offset = get_rel_offset(ri, *(const u32 *)b);

	return a_offset < b_offset ? -1 : (a_offset > b_offset ? 1 : 0);
}

static int sort_rel(struct rel_info *ri)
{
	size_t sz = sizeof(ri->sorted[0]);
	u32 i;

	ri->sorted = calloc(ri->nr_entries, sz);
	if (!ri->sorted)
		return -1;
	for (i = 0; i < ri->nr_entries; i++)
		ri->sorted[i] = i;
	qsort_r(ri->sorted, ri->nr_entries, sz, rel_cmp, ri);
	return 0;
}

/*
 * For x86_64, the GNU linker is putting IFUNC information in the relocation
 * addend.
 */
static bool addend_may_be_ifunc(GElf_Ehdr *ehdr, struct rel_info *ri)
{
	return ehdr->e_machine == EM_X86_64 && ri->is_rela &&
	       GELF_R_TYPE(ri->rela.r_info) == R_X86_64_IRELATIVE;
}

static bool get_ifunc_name(Elf *elf, struct dso *dso, GElf_Ehdr *ehdr,
			   struct rel_info *ri, char *buf, size_t buf_sz)
{
	u64 addr = ri->rela.r_addend;
	struct symbol *sym;
	GElf_Phdr phdr;

	if (!addend_may_be_ifunc(ehdr, ri))
		return false;

	if (elf_read_program_header(elf, addr, &phdr))
		return false;

	addr -= phdr.p_vaddr - phdr.p_offset;

	sym = dso__find_symbol_nocache(dso, addr);

	/* Expecting the address to be an IFUNC or IFUNC alias */
	if (!sym || sym->start != addr || (sym->type != STT_GNU_IFUNC && !sym->ifunc_alias))
		return false;

	snprintf(buf, buf_sz, "%s@plt", sym->name);

	return true;
}

static void exit_rel(struct rel_info *ri)
{
	zfree(&ri->sorted);
}

static bool get_plt_sizes(struct dso *dso, GElf_Ehdr *ehdr, GElf_Shdr *shdr_plt,
			  u64 *plt_header_size, u64 *plt_entry_size)
{
	switch (ehdr->e_machine) {
	case EM_ARM:
		*plt_header_size = 20;
		*plt_entry_size = 12;
		return true;
	case EM_AARCH64:
	case EM_LOONGARCH:
	case EM_RISCV:
		*plt_header_size = 32;
		*plt_entry_size = 16;
		return true;
	case EM_SPARC:
		*plt_header_size = 48;
		*plt_entry_size = 12;
		return true;
	case EM_SPARCV9:
		*plt_header_size = 128;
		*plt_entry_size = 32;
		return true;
	case EM_386:
	case EM_X86_64:
		*plt_entry_size = shdr_plt->sh_entsize;
		/* Size is 8 or 16, if not, assume alignment indicates size */
		if (*plt_entry_size != 8 && *plt_entry_size != 16)
			*plt_entry_size = shdr_plt->sh_addralign == 8 ? 8 : 16;
		*plt_header_size = *plt_entry_size;
		break;
	default: /* FIXME: s390/alpha/mips/parisc/poperpc/sh/xtensa need to be checked */
		*plt_header_size = shdr_plt->sh_entsize;
		*plt_entry_size = shdr_plt->sh_entsize;
		break;
	}
	if (*plt_entry_size)
		return true;
	pr_debug("Missing PLT entry size for %s\n", dso__long_name(dso));
	return false;
}

static bool machine_is_x86(GElf_Half e_machine)
{
	return e_machine == EM_386 || e_machine == EM_X86_64;
}

struct rela_dyn {
	GElf_Addr	offset;
	u32		sym_idx;
};

struct rela_dyn_info {
	struct dso	*dso;
	Elf_Data	*plt_got_data;
	u32		nr_entries;
	struct rela_dyn	*sorted;
	Elf_Data	*dynsym_data;
	Elf_Data	*dynstr_data;
	Elf_Data	*rela_dyn_data;
};

static void exit_rela_dyn(struct rela_dyn_info *di)
{
	zfree(&di->sorted);
}

static int cmp_offset(const void *a, const void *b)
{
	const struct rela_dyn *va = a;
	const struct rela_dyn *vb = b;

	return va->offset < vb->offset ? -1 : (va->offset > vb->offset ? 1 : 0);
}

static int sort_rela_dyn(struct rela_dyn_info *di)
{
	u32 i, n;

	di->sorted = calloc(di->nr_entries, sizeof(di->sorted[0]));
	if (!di->sorted)
		return -1;

	/* Get data for sorting: the offset and symbol index */
	for (i = 0, n = 0; i < di->nr_entries; i++) {
		GElf_Rela rela;
		u32 sym_idx;

		gelf_getrela(di->rela_dyn_data, i, &rela);
		sym_idx = GELF_R_SYM(rela.r_info);
		if (sym_idx) {
			di->sorted[n].sym_idx = sym_idx;
			di->sorted[n].offset = rela.r_offset;
			n += 1;
		}
	}

	/* Sort by offset */
	di->nr_entries = n;
	qsort(di->sorted, n, sizeof(di->sorted[0]), cmp_offset);

	return 0;
}

static void get_rela_dyn_info(Elf *elf, GElf_Ehdr *ehdr, struct rela_dyn_info *di, Elf_Scn *scn)
{
	GElf_Shdr rela_dyn_shdr;
	GElf_Shdr shdr;

	di->plt_got_data = elf_getdata(scn, NULL);

	scn = elf_section_by_name(elf, ehdr, &rela_dyn_shdr, ".rela.dyn", NULL);
	if (!scn || !rela_dyn_shdr.sh_link || !rela_dyn_shdr.sh_entsize)
		return;

	di->nr_entries = rela_dyn_shdr.sh_size / rela_dyn_shdr.sh_entsize;
	di->rela_dyn_data = elf_getdata(scn, NULL);

	scn = elf_getscn(elf, rela_dyn_shdr.sh_link);
	if (!scn || !gelf_getshdr(scn, &shdr) || !shdr.sh_link)
		return;

	di->dynsym_data = elf_getdata(scn, NULL);
	di->dynstr_data = elf_getdata(elf_getscn(elf, shdr.sh_link), NULL);

	if (!di->plt_got_data || !di->dynstr_data || !di->dynsym_data || !di->rela_dyn_data)
		return;

	/* Sort into offset order */
	sort_rela_dyn(di);
}

/* Get instruction displacement from a plt entry for x86_64 */
static u32 get_x86_64_plt_disp(const u8 *p)
{
	u8 endbr64[] = {0xf3, 0x0f, 0x1e, 0xfa};
	int n = 0;

	/* Skip endbr64 */
	if (!memcmp(p, endbr64, sizeof(endbr64)))
		n += sizeof(endbr64);
	/* Skip bnd prefix */
	if (p[n] == 0xf2)
		n += 1;
	/* jmp with 4-byte displacement */
	if (p[n] == 0xff && p[n + 1] == 0x25) {
		u32 disp;

		n += 2;
		/* Also add offset from start of entry to end of instruction */
		memcpy(&disp, p + n, sizeof(disp));
		return n + 4 + le32toh(disp);
	}
	return 0;
}

static bool get_plt_got_name(GElf_Shdr *shdr, size_t i,
			     struct rela_dyn_info *di,
			     char *buf, size_t buf_sz)
{
	struct rela_dyn vi, *vr;
	const char *sym_name;
	char *demangled;
	GElf_Sym sym;
	bool result;
	u32 disp;

	if (!di->sorted)
		return false;

	disp = get_x86_64_plt_disp(di->plt_got_data->d_buf + i);
	if (!disp)
		return false;

	/* Compute target offset of the .plt.got entry */
	vi.offset = shdr->sh_offset + di->plt_got_data->d_off + i + disp;

	/* Find that offset in .rela.dyn (sorted by offset) */
	vr = bsearch(&vi, di->sorted, di->nr_entries, sizeof(di->sorted[0]), cmp_offset);
	if (!vr)
		return false;

	/* Get the associated symbol */
	gelf_getsym(di->dynsym_data, vr->sym_idx, &sym);
	sym_name = elf_sym__name(&sym, di->dynstr_data);
	demangled = dso__demangle_sym(di->dso, /*kmodule=*/0, sym_name);
	if (demangled != NULL)
		sym_name = demangled;

	snprintf(buf, buf_sz, "%s@plt", sym_name);

	result = *sym_name;

	free(demangled);

	return result;
}

static int dso__synthesize_plt_got_symbols(struct dso *dso, Elf *elf,
					   GElf_Ehdr *ehdr,
					   char *buf, size_t buf_sz)
{
	struct rela_dyn_info di = { .dso = dso };
	struct symbol *sym;
	GElf_Shdr shdr;
	Elf_Scn *scn;
	int err = -1;
	size_t i;

	scn = elf_section_by_name(elf, ehdr, &shdr, ".plt.got", NULL);
	if (!scn || !shdr.sh_entsize)
		return 0;

	if (ehdr->e_machine == EM_X86_64)
		get_rela_dyn_info(elf, ehdr, &di, scn);

	for (i = 0; i < shdr.sh_size; i += shdr.sh_entsize) {
		if (!get_plt_got_name(&shdr, i, &di, buf, buf_sz))
			snprintf(buf, buf_sz, "offset_%#" PRIx64 "@plt", (u64)shdr.sh_offset + i);
		sym = symbol__new(shdr.sh_offset + i, shdr.sh_entsize, STB_GLOBAL, STT_FUNC, buf);
		if (!sym)
			goto out;
		symbols__insert(dso__symbols(dso), sym);
	}
	err = 0;
out:
	exit_rela_dyn(&di);
	return err;
}

/*
 * We need to check if we have a .dynsym, so that we can handle the
 * .plt, synthesizing its symbols, that aren't on the symtabs (be it
 * .dynsym or .symtab).
 * And always look at the original dso, not at debuginfo packages, that
 * have the PLT data stripped out (shdr_rel_plt.sh_type == SHT_NOBITS).
 */
int dso__synthesize_plt_symbols(struct dso *dso, struct symsrc *ss)
{
	uint32_t idx;
	GElf_Sym sym;
	u64 plt_offset, plt_header_size, plt_entry_size;
	GElf_Shdr shdr_plt, plt_sec_shdr;
	struct symbol *f, *plt_sym;
	GElf_Shdr shdr_rel_plt, shdr_dynsym;
	Elf_Data *syms, *symstrs;
	Elf_Scn *scn_plt_rel, *scn_symstrs, *scn_dynsym;
	GElf_Ehdr ehdr;
	char sympltname[1024];
	Elf *elf;
	int nr = 0, err = -1;
	struct rel_info ri = { .is_rela = false };
	bool lazy_plt;

	elf = ss->elf;
	ehdr = ss->ehdr;

	if (!elf_section_by_name(elf, &ehdr, &shdr_plt, ".plt", NULL))
		return 0;

	/*
	 * A symbol from a previous section (e.g. .init) can have been expanded
	 * by symbols__fixup_end() to overlap .plt. Truncate it before adding
	 * a symbol for .plt header.
	 */
	f = dso__find_symbol_nocache(dso, shdr_plt.sh_offset);
	if (f && f->start < shdr_plt.sh_offset && f->end > shdr_plt.sh_offset)
		f->end = shdr_plt.sh_offset;

	if (!get_plt_sizes(dso, &ehdr, &shdr_plt, &plt_header_size, &plt_entry_size))
		return 0;

	/* Add a symbol for .plt header */
	plt_sym = symbol__new(shdr_plt.sh_offset, plt_header_size, STB_GLOBAL, STT_FUNC, ".plt");
	if (!plt_sym)
		goto out_elf_end;
	symbols__insert(dso__symbols(dso), plt_sym);

	/* Only x86 has .plt.got */
	if (machine_is_x86(ehdr.e_machine) &&
	    dso__synthesize_plt_got_symbols(dso, elf, &ehdr, sympltname, sizeof(sympltname)))
		goto out_elf_end;

	/* Only x86 has .plt.sec */
	if (machine_is_x86(ehdr.e_machine) &&
	    elf_section_by_name(elf, &ehdr, &plt_sec_shdr, ".plt.sec", NULL)) {
		if (!get_plt_sizes(dso, &ehdr, &plt_sec_shdr, &plt_header_size, &plt_entry_size))
			return 0;
		/* Extend .plt symbol to entire .plt */
		plt_sym->end = plt_sym->start + shdr_plt.sh_size;
		/* Use .plt.sec offset */
		plt_offset = plt_sec_shdr.sh_offset;
		lazy_plt = false;
	} else {
		plt_offset = shdr_plt.sh_offset;
		lazy_plt = true;
	}

	scn_plt_rel = elf_section_by_name(elf, &ehdr, &shdr_rel_plt,
					  ".rela.plt", NULL);
	if (scn_plt_rel == NULL) {
		scn_plt_rel = elf_section_by_name(elf, &ehdr, &shdr_rel_plt,
						  ".rel.plt", NULL);
		if (scn_plt_rel == NULL)
			return 0;
	}

	if (shdr_rel_plt.sh_type != SHT_RELA &&
	    shdr_rel_plt.sh_type != SHT_REL)
		return 0;

	if (!shdr_rel_plt.sh_link)
		return 0;

	if (shdr_rel_plt.sh_link == ss->dynsym_idx) {
		scn_dynsym = ss->dynsym;
		shdr_dynsym = ss->dynshdr;
	} else if (shdr_rel_plt.sh_link == ss->symtab_idx) {
		/*
		 * A static executable can have a .plt due to IFUNCs, in which
		 * case .symtab is used not .dynsym.
		 */
		scn_dynsym = ss->symtab;
		shdr_dynsym = ss->symshdr;
	} else {
		goto out_elf_end;
	}

	if (!scn_dynsym)
		return 0;

	/*
	 * Fetch the relocation section to find the idxes to the GOT
	 * and the symbols in the .dynsym they refer to.
	 */
	ri.reldata = elf_getdata(scn_plt_rel, NULL);
	if (!ri.reldata)
		goto out_elf_end;

	syms = elf_getdata(scn_dynsym, NULL);
	if (syms == NULL)
		goto out_elf_end;

	scn_symstrs = elf_getscn(elf, shdr_dynsym.sh_link);
	if (scn_symstrs == NULL)
		goto out_elf_end;

	symstrs = elf_getdata(scn_symstrs, NULL);
	if (symstrs == NULL)
		goto out_elf_end;

	if (symstrs->d_size == 0)
		goto out_elf_end;

	ri.nr_entries = shdr_rel_plt.sh_size / shdr_rel_plt.sh_entsize;

	ri.is_rela = shdr_rel_plt.sh_type == SHT_RELA;

	if (lazy_plt) {
		/*
		 * Assume a .plt with the same number of entries as the number
		 * of relocation entries is not lazy and does not have a header.
		 */
		if (ri.nr_entries * plt_entry_size == shdr_plt.sh_size)
			dso__delete_symbol(dso, plt_sym);
		else
			plt_offset += plt_header_size;
	}

	/*
	 * x86 doesn't insert IFUNC relocations in .plt order, so sort to get
	 * back in order.
	 */
	if (machine_is_x86(ehdr.e_machine) && sort_rel(&ri))
		goto out_elf_end;

	for (idx = 0; idx < ri.nr_entries; idx++) {
		const char *elf_name = NULL;
		char *demangled = NULL;

		gelf_getsym(syms, get_rel_symidx(&ri, idx), &sym);

		elf_name = elf_sym__name(&sym, symstrs);
		demangled = dso__demangle_sym(dso, /*kmodule=*/0, elf_name);
		if (demangled)
			elf_name = demangled;
		if (*elf_name)
			snprintf(sympltname, sizeof(sympltname), "%s@plt", elf_name);
		else if (!get_ifunc_name(elf, dso, &ehdr, &ri, sympltname, sizeof(sympltname)))
			snprintf(sympltname, sizeof(sympltname),
				 "offset_%#" PRIx64 "@plt", plt_offset);
		free(demangled);

		f = symbol__new(plt_offset, plt_entry_size, STB_GLOBAL, STT_FUNC, sympltname);
		if (!f)
			goto out_elf_end;

		plt_offset += plt_entry_size;
		symbols__insert(dso__symbols(dso), f);
		++nr;
	}

	err = 0;
out_elf_end:
	exit_rel(&ri);
	if (err == 0)
		return nr;
	pr_debug("%s: problems reading %s PLT info.\n",
		 __func__, dso__long_name(dso));
	return 0;
}

/*
 * Align offset to 4 bytes as needed for note name and descriptor data.
 */
#define NOTE_ALIGN(n) (((n) + 3) & -4U)

static int elf_read_build_id(Elf *elf, void *bf, size_t size)
{
	int err = -1;
	GElf_Ehdr ehdr;
	GElf_Shdr shdr;
	Elf_Data *data;
	Elf_Scn *sec;
	Elf_Kind ek;
	void *ptr;

	if (size < BUILD_ID_SIZE)
		goto out;

	ek = elf_kind(elf);
	if (ek != ELF_K_ELF)
		goto out;

	if (gelf_getehdr(elf, &ehdr) == NULL) {
		pr_err("%s: cannot get elf header.\n", __func__);
		goto out;
	}

	/*
	 * Check following sections for notes:
	 *   '.note.gnu.build-id'
	 *   '.notes'
	 *   '.note' (VDSO specific)
	 */
	do {
		sec = elf_section_by_name(elf, &ehdr, &shdr,
					  ".note.gnu.build-id", NULL);
		if (sec)
			break;

		sec = elf_section_by_name(elf, &ehdr, &shdr,
					  ".notes", NULL);
		if (sec)
			break;

		sec = elf_section_by_name(elf, &ehdr, &shdr,
					  ".note", NULL);
		if (sec)
			break;

		return err;

	} while (0);

	data = elf_getdata(sec, NULL);
	if (data == NULL)
		goto out;

	ptr = data->d_buf;
	while (ptr < (data->d_buf + data->d_size)) {
		GElf_Nhdr *nhdr = ptr;
		size_t namesz = NOTE_ALIGN(nhdr->n_namesz),
		       descsz = NOTE_ALIGN(nhdr->n_descsz);
		const char *name;

		ptr += sizeof(*nhdr);
		name = ptr;
		ptr += namesz;
		if (nhdr->n_type == NT_GNU_BUILD_ID &&
		    nhdr->n_namesz == sizeof("GNU")) {
			if (memcmp(name, "GNU", sizeof("GNU")) == 0) {
				size_t sz = min(size, descsz);
				memcpy(bf, ptr, sz);
				memset(bf + sz, 0, size - sz);
				err = sz;
				break;
			}
		}
		ptr += descsz;
	}

out:
	return err;
}

static int read_build_id(const char *filename, struct build_id *bid)
{
	size_t size = sizeof(bid->data);
	int fd, err;
	Elf *elf;

	err = libbfd__read_build_id(filename, bid);
	if (err >= 0)
		goto out;

	if (size < BUILD_ID_SIZE)
		goto out;

	fd = open(filename, O_RDONLY);
	if (fd < 0)
		goto out;

	elf = elf_begin(fd, PERF_ELF_C_READ_MMAP, NULL);
	if (elf == NULL) {
		pr_debug2("%s: cannot read %s ELF file.\n", __func__, filename);
		goto out_close;
	}

	err = elf_read_build_id(elf, bid->data, size);
	if (err > 0)
		bid->size = err;

	elf_end(elf);
out_close:
	close(fd);
out:
	return err;
}

int filename__read_build_id(const char *filename, struct build_id *bid)
{
	struct kmod_path m = { .name = NULL, };
	char path[PATH_MAX];
	int err;

	if (!filename)
		return -EFAULT;

	errno = 0;
	if (!is_regular_file(filename))
		return errno == 0 ? -EWOULDBLOCK : -errno;

	err = kmod_path__parse(&m, filename);
	if (err)
		return -1;

	if (m.comp) {
		int error = 0, fd;

		fd = filename__decompress(filename, path, sizeof(path), m.comp, &error);
		if (fd < 0) {
			pr_debug("Failed to decompress (error %d) %s\n",
				 error, filename);
			return -1;
		}
		close(fd);
		filename = path;
	}

	err = read_build_id(filename, bid);

	if (m.comp)
		unlink(filename);
	return err;
}

int sysfs__read_build_id(const char *filename, struct build_id *bid)
{
	size_t size = sizeof(bid->data);
	int fd, err = -1;

	fd = open(filename, O_RDONLY);
	if (fd < 0)
		goto out;

	while (1) {
		char bf[BUFSIZ];
		GElf_Nhdr nhdr;
		size_t namesz, descsz;

		if (read(fd, &nhdr, sizeof(nhdr)) != sizeof(nhdr))
			break;

		namesz = NOTE_ALIGN(nhdr.n_namesz);
		descsz = NOTE_ALIGN(nhdr.n_descsz);
		if (nhdr.n_type == NT_GNU_BUILD_ID &&
		    nhdr.n_namesz == sizeof("GNU")) {
			if (read(fd, bf, namesz) != (ssize_t)namesz)
				break;
			if (memcmp(bf, "GNU", sizeof("GNU")) == 0) {
				size_t sz = min(descsz, size);
				if (read(fd, bid->data, sz) == (ssize_t)sz) {
					memset(bid->data + sz, 0, size - sz);
					bid->size = sz;
					err = 0;
					break;
				}
			} else if (read(fd, bf, descsz) != (ssize_t)descsz)
				break;
		} else {
			int n = namesz + descsz;

			if (n > (int)sizeof(bf)) {
				n = sizeof(bf);
				pr_debug("%s: truncating reading of build id in sysfs file %s: n_namesz=%u, n_descsz=%u.\n",
					 __func__, filename, nhdr.n_namesz, nhdr.n_descsz);
			}
			if (read(fd, bf, n) != n)
				break;
		}
	}
	close(fd);
out:
	return err;
}

int filename__read_debuglink(const char *filename, char *debuglink,
			     size_t size)
{
	int fd, err = -1;
	Elf *elf;
	GElf_Ehdr ehdr;
	GElf_Shdr shdr;
	Elf_Data *data;
	Elf_Scn *sec;
	Elf_Kind ek;

	err = libbfd_filename__read_debuglink(filename, debuglink, size);
	if (err >= 0)
		goto out;

	fd = open(filename, O_RDONLY);
	if (fd < 0)
		goto out;

	elf = elf_begin(fd, PERF_ELF_C_READ_MMAP, NULL);
	if (elf == NULL) {
		pr_debug2("%s: cannot read %s ELF file.\n", __func__, filename);
		goto out_close;
	}

	ek = elf_kind(elf);
	if (ek != ELF_K_ELF)
		goto out_elf_end;

	if (gelf_getehdr(elf, &ehdr) == NULL) {
		pr_err("%s: cannot get elf header.\n", __func__);
		goto out_elf_end;
	}

	sec = elf_section_by_name(elf, &ehdr, &shdr,
				  ".gnu_debuglink", NULL);
	if (sec == NULL)
		goto out_elf_end;

	data = elf_getdata(sec, NULL);
	if (data == NULL)
		goto out_elf_end;

	/* the start of this section is a zero-terminated string */
	strncpy(debuglink, data->d_buf, size);

	err = 0;

out_elf_end:
	elf_end(elf);
out_close:
	close(fd);
out:
	return err;
}

bool symsrc__possibly_runtime(struct symsrc *ss)
{
	return ss->dynsym || ss->opdsec;
}

bool symsrc__has_symtab(struct symsrc *ss)
{
	return ss->symtab != NULL;
}

void symsrc__destroy(struct symsrc *ss)
{
	zfree(&ss->name);
	elf_end(ss->elf);
	close(ss->fd);
}

static bool elf__needs_adjust_symbols(const GElf_Ehdr *ehdr)
{
	/*
	 * Usually vmlinux is an ELF file with type ET_EXEC for most
	 * architectures; except Arm64 kernel is linked with option
	 * '-share', so need to check type ET_DYN.
	 */
	return ehdr->e_type == ET_EXEC || ehdr->e_type == ET_REL ||
	       ehdr->e_type == ET_DYN;
}

static Elf *read_gnu_debugdata(struct dso *dso, Elf *elf, const char *name, int *fd_ret)
{
	Elf *elf_embedded;
	GElf_Ehdr ehdr;
	GElf_Shdr shdr;
	Elf_Scn *scn;
	Elf_Data *scn_data;
	FILE *wrapped;
	size_t shndx;
	char temp_filename[] = "/tmp/perf.gnu_debugdata.elf.XXXXXX";
	int ret, temp_fd;

	if (gelf_getehdr(elf, &ehdr) == NULL) {
		pr_debug("%s: cannot read %s ELF file.\n", __func__, name);
		*dso__load_errno(dso) = DSO_LOAD_ERRNO__INVALID_ELF;
		return NULL;
	}

	scn = elf_section_by_name(elf, &ehdr, &shdr, ".gnu_debugdata", &shndx);
	if (!scn) {
		*dso__load_errno(dso) = -ENOENT;
		return NULL;
	}

	if (shdr.sh_type == SHT_NOBITS) {
		pr_debug("%s: .gnu_debugdata of ELF file %s has no data.\n", __func__, name);
		*dso__load_errno(dso) = DSO_LOAD_ERRNO__INVALID_ELF;
		return NULL;
	}

	scn_data = elf_rawdata(scn, NULL);
	if (!scn_data) {
		pr_debug("%s: error reading .gnu_debugdata of %s: %s\n", __func__,
			 name, elf_errmsg(-1));
		*dso__load_errno(dso) = DSO_LOAD_ERRNO__INVALID_ELF;
		return NULL;
	}

	wrapped = fmemopen(scn_data->d_buf, scn_data->d_size, "r");
	if (!wrapped) {
		pr_debug("%s: fmemopen: %m\n", __func__);
		*dso__load_errno(dso) = -errno;
		return NULL;
	}

	temp_fd = mkstemp(temp_filename);
	if (temp_fd < 0) {
		pr_debug("%s: mkstemp: %m\n", __func__);
		*dso__load_errno(dso) = -errno;
		fclose(wrapped);
		return NULL;
	}
	unlink(temp_filename);

	ret = lzma_decompress_stream_to_file(wrapped, temp_fd);
	fclose(wrapped);
	if (ret < 0) {
		*dso__load_errno(dso) = -errno;
		close(temp_fd);
		return NULL;
	}

	elf_embedded = elf_begin(temp_fd, PERF_ELF_C_READ_MMAP, NULL);
	if (!elf_embedded) {
		pr_debug("%s: error reading .gnu_debugdata of %s: %s\n", __func__,
			 name, elf_errmsg(-1));
		*dso__load_errno(dso) = DSO_LOAD_ERRNO__INVALID_ELF;
		close(temp_fd);
		return NULL;
	}
	pr_debug("%s: using .gnu_debugdata of %s\n", __func__, name);
	*fd_ret = temp_fd;
	return elf_embedded;
}

int symsrc__init(struct symsrc *ss, struct dso *dso, const char *name,
		 enum dso_binary_type type)
{
	GElf_Ehdr ehdr;
	Elf *elf;
	int fd;

	if (dso__needs_decompress(dso)) {
		fd = dso__decompress_kmodule_fd(dso, name);
		if (fd < 0)
			return -1;

		type = dso__symtab_type(dso);
	} else {
		fd = open(name, O_RDONLY);
		if (fd < 0) {
			*dso__load_errno(dso) = errno;
			return -1;
		}
	}

	elf = elf_begin(fd, PERF_ELF_C_READ_MMAP, NULL);
	if (elf == NULL) {
		pr_debug("%s: cannot read %s ELF file.\n", __func__, name);
		*dso__load_errno(dso) = DSO_LOAD_ERRNO__INVALID_ELF;
		goto out_close;
	}

	if (type == DSO_BINARY_TYPE__GNU_DEBUGDATA) {
		int new_fd;
		Elf *embedded = read_gnu_debugdata(dso, elf, name, &new_fd);

		if (!embedded)
			goto out_elf_end;

		elf_end(elf);
		close(fd);
		fd = new_fd;
		elf = embedded;
	}

	if (gelf_getehdr(elf, &ehdr) == NULL) {
		*dso__load_errno(dso) = DSO_LOAD_ERRNO__INVALID_ELF;
		pr_debug("%s: cannot get elf header.\n", __func__);
		goto out_elf_end;
	}

	if (dso__swap_init(dso, ehdr.e_ident[EI_DATA])) {
		*dso__load_errno(dso) = DSO_LOAD_ERRNO__INTERNAL_ERROR;
		goto out_elf_end;
	}

	/* Always reject images with a mismatched build-id: */
	if (dso__has_build_id(dso) && !symbol_conf.ignore_vmlinux_buildid) {
		u8 build_id[BUILD_ID_SIZE];
		struct build_id bid;
		int size;

		size = elf_read_build_id(elf, build_id, BUILD_ID_SIZE);
		if (size <= 0) {
			*dso__load_errno(dso) = DSO_LOAD_ERRNO__CANNOT_READ_BUILDID;
			goto out_elf_end;
		}

		build_id__init(&bid, build_id, size);
		if (!dso__build_id_equal(dso, &bid)) {
			pr_debug("%s: build id mismatch for %s.\n", __func__, name);
			*dso__load_errno(dso) = DSO_LOAD_ERRNO__MISMATCHING_BUILDID;
			goto out_elf_end;
		}
	}

	ss->is_64_bit = (gelf_getclass(elf) == ELFCLASS64);

	ss->symtab_idx = 0;
	ss->symtab = elf_section_by_name(elf, &ehdr, &ss->symshdr, ".symtab",
			&ss->symtab_idx);
	if (ss->symshdr.sh_type != SHT_SYMTAB)
		ss->symtab = NULL;

	ss->dynsym_idx = 0;
	ss->dynsym = elf_section_by_name(elf, &ehdr, &ss->dynshdr, ".dynsym",
			&ss->dynsym_idx);
	if (ss->dynshdr.sh_type != SHT_DYNSYM)
		ss->dynsym = NULL;

	ss->opdidx = 0;
	ss->opdsec = elf_section_by_name(elf, &ehdr, &ss->opdshdr, ".opd",
			&ss->opdidx);
	if (ss->opdshdr.sh_type != SHT_PROGBITS)
		ss->opdsec = NULL;

	if (dso__kernel(dso) == DSO_SPACE__USER)
		ss->adjust_symbols = true;
	else
		ss->adjust_symbols = elf__needs_adjust_symbols(&ehdr);

	ss->name   = strdup(name);
	if (!ss->name) {
		*dso__load_errno(dso) = errno;
		goto out_elf_end;
	}

	ss->elf    = elf;
	ss->fd     = fd;
	ss->ehdr   = ehdr;
	ss->type   = type;

	return 0;

out_elf_end:
	elf_end(elf);
out_close:
	close(fd);
	return -1;
}

static bool is_exe_text(int flags)
{
	return (flags & (SHF_ALLOC | SHF_EXECINSTR)) == (SHF_ALLOC | SHF_EXECINSTR);
}

/*
 * Some executable module sections like .noinstr.text might be laid out with
 * .text so they can use the same mapping (memory address to file offset).
 * Check if that is the case. Refer to kernel layout_sections(). Return the
 * maximum offset.
 */
static u64 max_text_section(Elf *elf, GElf_Ehdr *ehdr)
{
	Elf_Scn *sec = NULL;
	GElf_Shdr shdr;
	u64 offs = 0;

	/* Doesn't work for some arch */
	if (ehdr->e_machine == EM_PARISC ||
	    ehdr->e_machine == EM_ALPHA)
		return 0;

	/* ELF is corrupted/truncated, avoid calling elf_strptr. */
	if (!elf_rawdata(elf_getscn(elf, ehdr->e_shstrndx), NULL))
		return 0;

	while ((sec = elf_nextscn(elf, sec)) != NULL) {
		char *sec_name;

		if (!gelf_getshdr(sec, &shdr))
			break;

		if (!is_exe_text(shdr.sh_flags))
			continue;

		/* .init and .exit sections are not placed with .text */
		sec_name = elf_strptr(elf, ehdr->e_shstrndx, shdr.sh_name);
		if (!sec_name ||
		    strstarts(sec_name, ".init") ||
		    strstarts(sec_name, ".exit"))
			break;

		/* Must be next to previous, assumes .text is first */
		if (offs && PERF_ALIGN(offs, shdr.sh_addralign ?: 1) != shdr.sh_offset)
			break;

		offs = shdr.sh_offset + shdr.sh_size;
	}

	return offs;
}

/**
 * ref_reloc_sym_not_found - has kernel relocation symbol been found.
 * @kmap: kernel maps and relocation reference symbol
 *
 * This function returns %true if we are dealing with the kernel maps and the
 * relocation reference symbol has not yet been found.  Otherwise %false is
 * returned.
 */
static bool ref_reloc_sym_not_found(struct kmap *kmap)
{
	return kmap && kmap->ref_reloc_sym && kmap->ref_reloc_sym->name &&
	       !kmap->ref_reloc_sym->unrelocated_addr;
}

/**
 * ref_reloc - kernel relocation offset.
 * @kmap: kernel maps and relocation reference symbol
 *
 * This function returns the offset of kernel addresses as determined by using
 * the relocation reference symbol i.e. if the kernel has not been relocated
 * then the return value is zero.
 */
static u64 ref_reloc(struct kmap *kmap)
{
	if (kmap && kmap->ref_reloc_sym &&
	    kmap->ref_reloc_sym->unrelocated_addr)
		return kmap->ref_reloc_sym->addr -
		       kmap->ref_reloc_sym->unrelocated_addr;
	return 0;
}

void __weak arch__sym_update(struct symbol *s __maybe_unused,
		GElf_Sym *sym __maybe_unused) { }

static int dso__process_kernel_symbol(struct dso *dso, struct map *map,
				      GElf_Sym *sym, GElf_Shdr *shdr,
				      struct maps *kmaps, struct kmap *kmap,
				      struct dso **curr_dsop,
				      const char *section_name,
				      bool adjust_kernel_syms, bool kmodule, bool *remap_kernel,
				      u64 max_text_sh_offset)
{
	struct dso *curr_dso = *curr_dsop;
	struct map *curr_map;
	char dso_name[PATH_MAX];

	/* Adjust symbol to map to file offset */
	if (adjust_kernel_syms) {
		if (dso__rel(dso))
			sym->st_value += shdr->sh_offset;
		else
			sym->st_value -= shdr->sh_addr - shdr->sh_offset;
	}

	if (strcmp(section_name, (dso__short_name(curr_dso) + dso__short_name_len(dso))) == 0)
		return 0;

	if (strcmp(section_name, ".text") == 0) {
		/*
		 * The initial kernel mapping is based on
		 * kallsyms and identity maps.  Overwrite it to
		 * map to the kernel dso.
		 */
		if (*remap_kernel && dso__kernel(dso) && !kmodule) {
			*remap_kernel = false;
			map__set_start(map, shdr->sh_addr + ref_reloc(kmap));
			map__set_end(map, map__start(map) + shdr->sh_size);
			map__set_pgoff(map, shdr->sh_offset);
			map__set_mapping_type(map, MAPPING_TYPE__DSO);
			/* Ensure maps are correctly ordered */
			if (kmaps) {
				int err;
				struct map *tmp = map__get(map);

				maps__remove(kmaps, map);
				err = maps__insert(kmaps, map);
				map__put(tmp);
				if (err)
					return err;
			}
		}

		/*
		 * The initial module mapping is based on
		 * /proc/modules mapped to offset zero.
		 * Overwrite it to map to the module dso.
		 */
		if (*remap_kernel && kmodule) {
			*remap_kernel = false;
			map__set_pgoff(map, shdr->sh_offset);
		}

		dso__put(*curr_dsop);
		*curr_dsop = dso__get(dso);
		return 0;
	}

	if (!kmap)
		return 0;

	/*
	 * perf does not record module section addresses except for .text, but
	 * some sections can use the same mapping as .text.
	 */
	if (kmodule && adjust_kernel_syms && is_exe_text(shdr->sh_flags) &&
	    shdr->sh_offset <= max_text_sh_offset) {
		dso__put(*curr_dsop);
		*curr_dsop = dso__get(dso);
		return 0;
	}

	snprintf(dso_name, sizeof(dso_name), "%s%s", dso__short_name(dso), section_name);

	curr_map = maps__find_by_name(kmaps, dso_name);
	if (curr_map == NULL) {
		u64 start = sym->st_value;

		if (kmodule)
			start += map__start(map) + shdr->sh_offset;

		curr_dso = dso__new(dso_name);
		if (curr_dso == NULL)
			return -1;
		dso__set_kernel(curr_dso, dso__kernel(dso));
		RC_CHK_ACCESS(curr_dso)->long_name = dso__long_name(dso);
		RC_CHK_ACCESS(curr_dso)->long_name_len = dso__long_name_len(dso);
		dso__set_binary_type(curr_dso, dso__binary_type(dso));
		dso__set_adjust_symbols(curr_dso, dso__adjust_symbols(dso));
		curr_map = map__new2(start, curr_dso);
		if (curr_map == NULL) {
			dso__put(curr_dso);
			return -1;
		}
		if (dso__kernel(curr_dso))
			map__kmap(curr_map)->kmaps = kmaps;

		if (adjust_kernel_syms) {
			map__set_start(curr_map, shdr->sh_addr + ref_reloc(kmap));
			map__set_end(curr_map, map__start(curr_map) + shdr->sh_size);
			map__set_pgoff(curr_map, shdr->sh_offset);
		} else {
			map__set_mapping_type(curr_map, MAPPING_TYPE__IDENTITY);
		}
		dso__set_symtab_type(curr_dso, dso__symtab_type(dso));
		if (maps__insert(kmaps, curr_map)) {
			dso__put(curr_dso);
			map__put(curr_map);
			return -1;
		}
		dsos__add(&maps__machine(kmaps)->dsos, curr_dso);
		dso__set_loaded(curr_dso);
		dso__put(*curr_dsop);
		*curr_dsop = curr_dso;
	} else {
		dso__put(*curr_dsop);
		*curr_dsop = dso__get(map__dso(curr_map));
	}
	map__put(curr_map);

	return 0;
}

static int
dso__load_sym_internal(struct dso *dso, struct map *map, struct symsrc *syms_ss,
		       struct symsrc *runtime_ss, int kmodule, int dynsym)
{
	struct kmap *kmap = dso__kernel(dso) ? map__kmap(map) : NULL;
	struct maps *kmaps = kmap ? map__kmaps(map) : NULL;
	struct dso *curr_dso = NULL;
	Elf_Data *symstrs, *secstrs, *secstrs_run, *secstrs_sym;
	uint32_t nr_syms;
	uint32_t idx;
	GElf_Ehdr ehdr;
	GElf_Shdr shdr;
	GElf_Shdr tshdr;
	Elf_Data *syms, *opddata = NULL;
	GElf_Sym sym;
	Elf_Scn *sec, *sec_strndx;
	Elf *elf;
	int nr = 0;
	bool remap_kernel = false, adjust_kernel_syms = false;
	u64 max_text_sh_offset = 0;

	if (kmap && !kmaps)
		return -1;

	elf = syms_ss->elf;
	ehdr = syms_ss->ehdr;
	if (dynsym) {
		sec  = syms_ss->dynsym;
		shdr = syms_ss->dynshdr;
	} else {
		sec =  syms_ss->symtab;
		shdr = syms_ss->symshdr;
	}

	if (elf_section_by_name(runtime_ss->elf, &runtime_ss->ehdr, &tshdr,
				".text", NULL)) {
		dso__set_text_offset(dso, tshdr.sh_addr - tshdr.sh_offset);
		dso__set_text_end(dso, tshdr.sh_offset + tshdr.sh_size);
	}

	if (runtime_ss->opdsec)
		opddata = elf_rawdata(runtime_ss->opdsec, NULL);

	syms = elf_getdata(sec, NULL);
	if (syms == NULL)
		goto out_elf_end;

	sec = elf_getscn(elf, shdr.sh_link);
	if (sec == NULL)
		goto out_elf_end;

	symstrs = elf_getdata(sec, NULL);
	if (symstrs == NULL)
		goto out_elf_end;

	sec_strndx = elf_getscn(runtime_ss->elf, runtime_ss->ehdr.e_shstrndx);
	if (sec_strndx == NULL)
		goto out_elf_end;

	secstrs_run = elf_getdata(sec_strndx, NULL);
	if (secstrs_run == NULL)
		goto out_elf_end;

	sec_strndx = elf_getscn(elf, ehdr.e_shstrndx);
	if (sec_strndx == NULL)
		goto out_elf_end;

	secstrs_sym = elf_getdata(sec_strndx, NULL);
	if (secstrs_sym == NULL)
		goto out_elf_end;

	nr_syms = shdr.sh_size / shdr.sh_entsize;

	memset(&sym, 0, sizeof(sym));

	/*
	 * The kernel relocation symbol is needed in advance in order to adjust
	 * kernel maps correctly.
	 */
	if (ref_reloc_sym_not_found(kmap)) {
		elf_symtab__for_each_symbol(syms, nr_syms, idx, sym) {
			const char *elf_name = elf_sym__name(&sym, symstrs);

			if (strcmp(elf_name, kmap->ref_reloc_sym->name))
				continue;
			kmap->ref_reloc_sym->unrelocated_addr = sym.st_value;
			map__set_reloc(map, kmap->ref_reloc_sym->addr - kmap->ref_reloc_sym->unrelocated_addr);
			break;
		}
	}

	/*
	 * Handle any relocation of vdso necessary because older kernels
	 * attempted to prelink vdso to its virtual address.
	 */
	if (dso__is_vdso(dso))
		map__set_reloc(map, map__start(map) - dso__text_offset(dso));

	dso__set_adjust_symbols(dso, runtime_ss->adjust_symbols || ref_reloc(kmap));
	/*
	 * Initial kernel and module mappings do not map to the dso.
	 * Flag the fixups.
	 */
	if (dso__kernel(dso)) {
		remap_kernel = true;
		adjust_kernel_syms = dso__adjust_symbols(dso);
	}

	if (kmodule && adjust_kernel_syms)
		max_text_sh_offset = max_text_section(runtime_ss->elf, &runtime_ss->ehdr);

	curr_dso = dso__get(dso);
	elf_symtab__for_each_symbol(syms, nr_syms, idx, sym) {
		struct symbol *f;
		const char *elf_name = elf_sym__name(&sym, symstrs);
		char *demangled = NULL;
		int is_label = elf_sym__is_label(&sym);
		const char *section_name;
		bool used_opd = false;

		if (!is_label && !elf_sym__filter(&sym))
			continue;

		/* Reject ARM ELF "mapping symbols": these aren't unique and
		 * don't identify functions, so will confuse the profile
		 * output: */
		if (ehdr.e_machine == EM_ARM || ehdr.e_machine == EM_AARCH64) {
			if (elf_name[0] == '$' && strchr("adtx", elf_name[1])
			    && (elf_name[2] == '\0' || elf_name[2] == '.'))
				continue;
		}

		/* Reject RISCV ELF "mapping symbols" */
		if (ehdr.e_machine == EM_RISCV) {
			if (elf_name[0] == '$' && strchr("dx", elf_name[1]))
				continue;
		}

		if (runtime_ss->opdsec && sym.st_shndx == runtime_ss->opdidx) {
			u32 offset = sym.st_value - syms_ss->opdshdr.sh_addr;
			u64 *opd = opddata->d_buf + offset;
			sym.st_value = DSO__SWAP(dso, u64, *opd);
			sym.st_shndx = elf_addr_to_index(runtime_ss->elf,
					sym.st_value);
			used_opd = true;
		}

		/*
		 * When loading symbols in a data mapping, ABS symbols (which
		 * has a value of SHN_ABS in its st_shndx) failed at
		 * elf_getscn().  And it marks the loading as a failure so
		 * already loaded symbols cannot be fixed up.
		 *
		 * I'm not sure what should be done. Just ignore them for now.
		 * - Namhyung Kim
		 */
		if (sym.st_shndx == SHN_ABS)
			continue;

		sec = elf_getscn(syms_ss->elf, sym.st_shndx);
		if (!sec)
			goto out_elf_end;

		gelf_getshdr(sec, &shdr);

		/*
		 * If the attribute bit SHF_ALLOC is not set, the section
		 * doesn't occupy memory during process execution.
		 * E.g. ".gnu.warning.*" section is used by linker to generate
		 * warnings when calling deprecated functions, the symbols in
		 * the section aren't loaded to memory during process execution,
		 * so skip them.
		 */
		if (!(shdr.sh_flags & SHF_ALLOC))
			continue;

		secstrs = secstrs_sym;

		/*
		 * We have to fallback to runtime when syms' section header has
		 * NOBITS set. NOBITS results in file offset (sh_offset) not
		 * being incremented. So sh_offset used below has different
		 * values for syms (invalid) and runtime (valid).
		 */
		if (shdr.sh_type == SHT_NOBITS) {
			sec = elf_getscn(runtime_ss->elf, sym.st_shndx);
			if (!sec)
				goto out_elf_end;

			gelf_getshdr(sec, &shdr);
			secstrs = secstrs_run;
		}

		if (is_label && !elf_sec__filter(&shdr, secstrs))
			continue;

		section_name = elf_sec__name(&shdr, secstrs);

		/* On ARM, symbols for thumb functions have 1 added to
		 * the symbol address as a flag - remove it */
		if ((ehdr.e_machine == EM_ARM) &&
		    (GELF_ST_TYPE(sym.st_info) == STT_FUNC) &&
		    (sym.st_value & 1))
			--sym.st_value;

		if (dso__kernel(dso)) {
			if (dso__process_kernel_symbol(dso, map, &sym, &shdr,
						       kmaps, kmap, &curr_dso,
						       section_name,
						       adjust_kernel_syms,
						       kmodule,
						       &remap_kernel,
						       max_text_sh_offset))
				goto out_elf_end;
		} else if ((used_opd && runtime_ss->adjust_symbols) ||
			   (!used_opd && syms_ss->adjust_symbols)) {
			GElf_Phdr phdr;

			if (elf_read_program_header(runtime_ss->elf,
						    (u64)sym.st_value, &phdr)) {
				pr_debug4("%s: failed to find program header for "
					   "symbol: %s st_value: %#" PRIx64 "\n",
					   __func__, elf_name, (u64)sym.st_value);
				pr_debug4("%s: adjusting symbol: st_value: %#" PRIx64 " "
					"sh_addr: %#" PRIx64 " sh_offset: %#" PRIx64 "\n",
					__func__, (u64)sym.st_value, (u64)shdr.sh_addr,
					(u64)shdr.sh_offset);
				/*
				 * Fail to find program header, let's rollback
				 * to use shdr.sh_addr and shdr.sh_offset to
				 * calibrate symbol's file address, though this
				 * is not necessary for normal C ELF file, we
				 * still need to handle java JIT symbols in this
				 * case.
				 */
				sym.st_value -= shdr.sh_addr - shdr.sh_offset;
			} else {
				pr_debug4("%s: adjusting symbol: st_value: %#" PRIx64 " "
					"p_vaddr: %#" PRIx64 " p_offset: %#" PRIx64 "\n",
					__func__, (u64)sym.st_value, (u64)phdr.p_vaddr,
					(u64)phdr.p_offset);
				sym.st_value -= phdr.p_vaddr - phdr.p_offset;
			}
		}

		demangled = dso__demangle_sym(dso, kmodule, elf_name);
		if (demangled != NULL)
			elf_name = demangled;

		f = symbol__new(sym.st_value, sym.st_size,
				GELF_ST_BIND(sym.st_info),
				GELF_ST_TYPE(sym.st_info), elf_name);
		free(demangled);
		if (!f)
			goto out_elf_end;

		arch__sym_update(f, &sym);

		__symbols__insert(dso__symbols(curr_dso), f, dso__kernel(dso));
		nr++;
	}
	dso__put(curr_dso);

	/*
	 * For misannotated, zeroed, ASM function sizes.
	 */
	if (nr > 0) {
		symbols__fixup_end(dso__symbols(dso), false);
		symbols__fixup_duplicate(dso__symbols(dso));
		if (kmap) {
			/*
			 * We need to fixup this here too because we create new
			 * maps here, for things like vsyscall sections.
			 */
			maps__fixup_end(kmaps);
		}
	}
	return nr;
out_elf_end:
	dso__put(curr_dso);
	return -1;
}

int dso__load_sym(struct dso *dso, struct map *map, struct symsrc *syms_ss,
		  struct symsrc *runtime_ss, int kmodule)
{
	int nr = 0;
	int err = -1;

	dso__set_symtab_type(dso, syms_ss->type);
	dso__set_is_64_bit(dso, syms_ss->is_64_bit);
	dso__set_rel(dso, syms_ss->ehdr.e_type == ET_REL);

	/*
	 * Modules may already have symbols from kallsyms, but those symbols
	 * have the wrong values for the dso maps, so remove them.
	 */
	if (kmodule && syms_ss->symtab)
		symbols__delete(dso__symbols(dso));

	if (!syms_ss->symtab) {
		/*
		 * If the vmlinux is stripped, fail so we will fall back
		 * to using kallsyms. The vmlinux runtime symbols aren't
		 * of much use.
		 */
		if (dso__kernel(dso))
			return err;
	} else  {
		err = dso__load_sym_internal(dso, map, syms_ss, runtime_ss,
					     kmodule, 0);
		if (err < 0)
			return err;
		nr = err;
	}

	if (syms_ss->dynsym) {
		err = dso__load_sym_internal(dso, map, syms_ss, runtime_ss,
					     kmodule, 1);
		if (err < 0)
			return err;
		nr += err;
	}

	/*
	 * The .gnu_debugdata is a special situation: it contains a symbol
	 * table, but the runtime file may also contain dynsym entries which are
	 * not present there. We need to load both.
	 */
	if (syms_ss->type == DSO_BINARY_TYPE__GNU_DEBUGDATA && runtime_ss->dynsym) {
		err = dso__load_sym_internal(dso, map, runtime_ss, runtime_ss,
					     kmodule, 1);
		if (err < 0)
			return err;
		nr += err;
	}

	return nr;
}

static int elf_read_maps(Elf *elf, bool exe, mapfn_t mapfn, void *data)
{
	GElf_Phdr phdr;
	size_t i, phdrnum;
	int err;
	u64 sz;

	if (elf_getphdrnum(elf, &phdrnum))
		return -1;

	for (i = 0; i < phdrnum; i++) {
		if (gelf_getphdr(elf, i, &phdr) == NULL)
			return -1;
		if (phdr.p_type != PT_LOAD)
			continue;
		if (exe) {
			if (!(phdr.p_flags & PF_X))
				continue;
		} else {
			if (!(phdr.p_flags & PF_R))
				continue;
		}
		sz = min(phdr.p_memsz, phdr.p_filesz);
		if (!sz)
			continue;
		err = mapfn(phdr.p_vaddr, sz, phdr.p_offset, data);
		if (err)
			return err;
	}
	return 0;
}

int file__read_maps(int fd, bool exe, mapfn_t mapfn, void *data,
		    bool *is_64_bit)
{
	int err;
	Elf *elf;

	elf = elf_begin(fd, PERF_ELF_C_READ_MMAP, NULL);
	if (elf == NULL)
		return -1;

	if (is_64_bit)
		*is_64_bit = (gelf_getclass(elf) == ELFCLASS64);

	err = elf_read_maps(elf, exe, mapfn, data);

	elf_end(elf);
	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;
	size_t n;
	int err = -1;
	char *buf = malloc(page_size);

	if (buf == NULL)
		return -1;

	if (lseek(to, to_offs, SEEK_SET) != to_offs)
		goto out;

	if (lseek(from, from_offs, SEEK_SET) != from_offs)
		goto out;

	while (len) {
		n = page_size;
		if (len < n)
			n = len;
		/* Use read because mmap won't work on proc files */
		r = read(from, buf, n);
		if (r < 0)
			goto out;
		if (!r)
			break;
		n = r;
		r = write(to, buf, n);
		if (r < 0)
			goto out;
		if ((size_t)r != n)
			goto out;
		len -= n;
	}

	err = 0;
out:
	free(buf);
	return err;
}

struct kcore {
	int fd;
	int elfclass;
	Elf *elf;
	GElf_Ehdr ehdr;
};

static int kcore__open(struct kcore *kcore, const char *filename)
{
	GElf_Ehdr *ehdr;

	kcore->fd = open(filename, O_RDONLY);
	if (kcore->fd == -1)
		return -1;

	kcore->elf = elf_begin(kcore->fd, ELF_C_READ, NULL);
	if (!kcore->elf)
		goto out_close;

	kcore->elfclass = gelf_getclass(kcore->elf);
	if (kcore->elfclass == ELFCLASSNONE)
		goto out_end;

	ehdr = gelf_getehdr(kcore->elf, &kcore->ehdr);
	if (!ehdr)
		goto out_end;

	return 0;

out_end:
	elf_end(kcore->elf);
out_close:
	close(kcore->fd);
	return -1;
}

static int kcore__init(struct kcore *kcore, char *filename, int elfclass,
		       bool temp)
{
	kcore->elfclass = elfclass;

	if (temp)
		kcore->fd = mkstemp(filename);
	else
		kcore->fd = open(filename, O_WRONLY | O_CREAT | O_EXCL, 0400);
	if (kcore->fd == -1)
		return -1;

	kcore->elf = elf_begin(kcore->fd, ELF_C_WRITE, NULL);
	if (!kcore->elf)
		goto out_close;

	if (!gelf_newehdr(kcore->elf, elfclass))
		goto out_end;

	memset(&kcore->ehdr, 0, sizeof(GElf_Ehdr));

	return 0;

out_end:
	elf_end(kcore->elf);
out_close:
	close(kcore->fd);
	unlink(filename);
	return -1;
}

static void kcore__close(struct kcore *kcore)
{
	elf_end(kcore->elf);
	close(kcore->fd);
}

static int kcore__copy_hdr(struct kcore *from, struct kcore *to, size_t count)
{
	GElf_Ehdr *ehdr = &to->ehdr;
	GElf_Ehdr *kehdr = &from->ehdr;

	memcpy(ehdr->e_ident, kehdr->e_ident, EI_NIDENT);
	ehdr->e_type      = kehdr->e_type;
	ehdr->e_machine   = kehdr->e_machine;
	ehdr->e_version   = kehdr->e_version;
	ehdr->e_entry     = 0;
	ehdr->e_shoff     = 0;
	ehdr->e_flags     = kehdr->e_flags;
	ehdr->e_phnum     = count;
	ehdr->e_shentsize = 0;
	ehdr->e_shnum     = 0;
	ehdr->e_shstrndx  = 0;

	if (from->elfclass == ELFCLASS32) {
		ehdr->e_phoff     = sizeof(Elf32_Ehdr);
		ehdr->e_ehsize    = sizeof(Elf32_Ehdr);
		ehdr->e_phentsize = sizeof(Elf32_Phdr);
	} else {
		ehdr->e_phoff     = sizeof(Elf64_Ehdr);
		ehdr->e_ehsize    = sizeof(Elf64_Ehdr);
		ehdr->e_phentsize = sizeof(Elf64_Phdr);
	}

	if (!gelf_update_ehdr(to->elf, ehdr))
		return -1;

	if (!gelf_newphdr(to->elf, count))
		return -1;

	return 0;
}

static int kcore__add_phdr(struct kcore *kcore, int idx, off_t offset,
			   u64 addr, u64 len)
{
	GElf_Phdr phdr = {
		.p_type		= PT_LOAD,
		.p_flags	= PF_R | PF_W | PF_X,
		.p_offset	= offset,
		.p_vaddr	= addr,
		.p_paddr	= 0,
		.p_filesz	= len,
		.p_memsz	= len,
		.p_align	= page_size,
	};

	if (!gelf_update_phdr(kcore->elf, idx, &phdr))
		return -1;

	return 0;
}

static off_t kcore__write(struct kcore *kcore)
{
	return elf_update(kcore->elf, ELF_C_WRITE);
}

struct phdr_data {
	off_t offset;
	off_t rel;
	u64 addr;
	u64 len;
	struct list_head node;
	struct phdr_data *remaps;
};

struct sym_data {
	u64 addr;
	struct list_head node;
};

struct kcore_copy_info {
	u64 stext;
	u64 etext;
	u64 first_symbol;
	u64 last_symbol;
	u64 first_module;
	u64 first_module_symbol;
	u64 last_module_symbol;
	size_t phnum;
	struct list_head phdrs;
	struct list_head syms;
};

#define kcore_copy__for_each_phdr(k, p) \
	list_for_each_entry((p), &(k)->phdrs, node)

static struct phdr_data *phdr_data__new(u64 addr, u64 len, off_t offset)
{
	struct phdr_data *p = zalloc(sizeof(*p));

	if (p) {
		p->addr   = addr;
		p->len    = len;
		p->offset = offset;
	}

	return p;
}

static struct phdr_data *kcore_copy_info__addnew(struct kcore_copy_info *kci,
						 u64 addr, u64 len,
						 off_t offset)
{
	struct phdr_data *p = phdr_data__new(addr, len, offset);

	if (p)
		list_add_tail(&p->node, &kci->phdrs);

	return p;
}

static void kcore_copy__free_phdrs(struct kcore_copy_info *kci)
{
	struct phdr_data *p, *tmp;

	list_for_each_entry_safe(p, tmp, &kci->phdrs, node) {
		list_del_init(&p->node);
		free(p);
	}
}

static struct sym_data *kcore_copy__new_sym(struct kcore_copy_info *kci,
					    u64 addr)
{
	struct sym_data *s = zalloc(sizeof(*s));

	if (s) {
		s->addr = addr;
		list_add_tail(&s->node, &kci->syms);
	}

	return s;
}

static void kcore_copy__free_syms(struct kcore_copy_info *kci)
{
	struct sym_data *s, *tmp;

	list_for_each_entry_safe(s, tmp, &kci->syms, node) {
		list_del_init(&s->node);
		free(s);
	}
}

static int kcore_copy__process_kallsyms(void *arg, const char *name, char type,
					u64 start)
{
	struct kcore_copy_info *kci = arg;

	if (!kallsyms__is_function(type))
		return 0;

	if (strchr(name, '[')) {
		if (!kci->first_module_symbol || start < kci->first_module_symbol)
			kci->first_module_symbol = start;
		if (start > kci->last_module_symbol)
			kci->last_module_symbol = start;
		return 0;
	}

	if (!kci->first_symbol || start < kci->first_symbol)
		kci->first_symbol = start;

	if (!kci->last_symbol || start > kci->last_symbol)
		kci->last_symbol = start;

	if (!strcmp(name, "_stext")) {
		kci->stext = start;
		return 0;
	}

	if (!strcmp(name, "_etext")) {
		kci->etext = start;
		return 0;
	}

	if (is_entry_trampoline(name) && !kcore_copy__new_sym(kci, start))
		return -1;

	return 0;
}

static int kcore_copy__parse_kallsyms(struct kcore_copy_info *kci,
				      const char *dir)
{
	char kallsyms_filename[PATH_MAX];

	scnprintf(kallsyms_filename, PATH_MAX, "%s/kallsyms", dir);

	if (symbol__restricted_filename(kallsyms_filename, "/proc/kallsyms"))
		return -1;

	if (kallsyms__parse(kallsyms_filename, kci,
			    kcore_copy__process_kallsyms) < 0)
		return -1;

	return 0;
}

static int kcore_copy__process_modules(void *arg,
				       const char *name __maybe_unused,
				       u64 start, u64 size __maybe_unused)
{
	struct kcore_copy_info *kci = arg;

	if (!kci->first_module || start < kci->first_module)
		kci->first_module = start;

	return 0;
}

static int kcore_copy__parse_modules(struct kcore_copy_info *kci,
				     const char *dir)
{
	char modules_filename[PATH_MAX];

	scnprintf(modules_filename, PATH_MAX, "%s/modules", dir);

	if (symbol__restricted_filename(modules_filename, "/proc/modules"))
		return -1;

	if (modules__parse(modules_filename, kci,
			   kcore_copy__process_modules) < 0)
		return -1;

	return 0;
}

static int kcore_copy__map(struct kcore_copy_info *kci, u64 start, u64 end,
			   u64 pgoff, u64 s, u64 e)
{
	u64 len, offset;

	if (s < start || s >= end)
		return 0;

	offset = (s - start) + pgoff;
	len = e < end ? e - s : end - s;

	return kcore_copy_info__addnew(kci, s, len, offset) ? 0 : -1;
}

static int kcore_copy__read_map(u64 start, u64 len, u64 pgoff, void *data)
{
	struct kcore_copy_info *kci = data;
	u64 end = start + len;
	struct sym_data *sdat;

	if (kcore_copy__map(kci, start, end, pgoff, kci->stext, kci->etext))
		return -1;

	if (kcore_copy__map(kci, start, end, pgoff, kci->first_module,
			    kci->last_module_symbol))
		return -1;

	list_for_each_entry(sdat, &kci->syms, node) {
		u64 s = round_down(sdat->addr, page_size);

		if (kcore_copy__map(kci, start, end, pgoff, s, s + len))
			return -1;
	}

	return 0;
}

static int kcore_copy__read_maps(struct kcore_copy_info *kci, Elf *elf)
{
	if (elf_read_maps(elf, true, kcore_copy__read_map, kci) < 0)
		return -1;

	return 0;
}

static void kcore_copy__find_remaps(struct kcore_copy_info *kci)
{
	struct phdr_data *p, *k = NULL;
	u64 kend;

	if (!kci->stext)
		return;

	/* Find phdr that corresponds to the kernel map (contains stext) */
	kcore_copy__for_each_phdr(kci, p) {
		u64 pend = p->addr + p->len - 1;

		if (p->addr <= kci->stext && pend >= kci->stext) {
			k = p;
			break;
		}
	}

	if (!k)
		return;

	kend = k->offset + k->len;

	/* Find phdrs that remap the kernel */
	kcore_copy__for_each_phdr(kci, p) {
		u64 pend = p->offset + p->len;

		if (p == k)
			continue;

		if (p->offset >= k->offset && pend <= kend)
			p->remaps = k;
	}
}

static void kcore_copy__layout(struct kcore_copy_info *kci)
{
	struct phdr_data *p;
	off_t rel = 0;

	kcore_copy__find_remaps(kci);

	kcore_copy__for_each_phdr(kci, p) {
		if (!p->remaps) {
			p->rel = rel;
			rel += p->len;
		}
		kci->phnum += 1;
	}

	kcore_copy__for_each_phdr(kci, p) {
		struct phdr_data *k = p->remaps;

		if (k)
			p->rel = p->offset - k->offset + k->rel;
	}
}

static int kcore_copy__calc_maps(struct kcore_copy_info *kci, const char *dir,
				 Elf *elf)
{
	if (kcore_copy__parse_kallsyms(kci, dir))
		return -1;

	if (kcore_copy__parse_modules(kci, dir))
		return -1;

	if (kci->stext)
		kci->stext = round_down(kci->stext, page_size);
	else
		kci->stext = round_down(kci->first_symbol, page_size);

	if (kci->etext) {
		kci->etext = round_up(kci->etext, page_size);
	} else if (kci->last_symbol) {
		kci->etext = round_up(kci->last_symbol, page_size);
		kci->etext += page_size;
	}

	if (kci->first_module_symbol &&
	    (!kci->first_module || kci->first_module_symbol < kci->first_module))
		kci->first_module = kci->first_module_symbol;

	kci->first_module = round_down(kci->first_module, page_size);

	if (kci->last_module_symbol) {
		kci->last_module_symbol = round_up(kci->last_module_symbol,
						   page_size);
		kci->last_module_symbol += page_size;
	}

	if (!kci->stext || !kci->etext)
		return -1;

	if (kci->first_module && !kci->last_module_symbol)
		return -1;

	if (kcore_copy__read_maps(kci, elf))
		return -1;

	kcore_copy__layout(kci);

	return 0;
}

static int kcore_copy__copy_file(const char *from_dir, const char *to_dir,
				 const char *name)
{
	char from_filename[PATH_MAX];
	char to_filename[PATH_MAX];

	scnprintf(from_filename, PATH_MAX, "%s/%s", from_dir, name);
	scnprintf(to_filename, PATH_MAX, "%s/%s", to_dir, name);

	return copyfile_mode(from_filename, to_filename, 0400);
}

static int kcore_copy__unlink(const char *dir, const char *name)
{
	char filename[PATH_MAX];

	scnprintf(filename, PATH_MAX, "%s/%s", dir, name);

	return unlink(filename);
}

static int kcore_copy__compare_fds(int from, int to)
{
	char *buf_from;
	char *buf_to;
	ssize_t ret;
	size_t len;
	int err = -1;

	buf_from = malloc(page_size);
	buf_to = malloc(page_size);
	if (!buf_from || !buf_to)
		goto out;

	while (1) {
		/* Use read because mmap won't work on proc files */
		ret = read(from, buf_from, page_size);
		if (ret < 0)
			goto out;

		if (!ret)
			break;

		len = ret;

		if (readn(to, buf_to, len) != (int)len)
			goto out;

		if (memcmp(buf_from, buf_to, len))
			goto out;
	}

	err = 0;
out:
	free(buf_to);
	free(buf_from);
	return err;
}

static int kcore_copy__compare_files(const char *from_filename,
				     const char *to_filename)
{
	int from, to, err = -1;

	from = open(from_filename, O_RDONLY);
	if (from < 0)
		return -1;

	to = open(to_filename, O_RDONLY);
	if (to < 0)
		goto out_close_from;

	err = kcore_copy__compare_fds(from, to);

	close(to);
out_close_from:
	close(from);
	return err;
}

static int kcore_copy__compare_file(const char *from_dir, const char *to_dir,
				    const char *name)
{
	char from_filename[PATH_MAX];
	char to_filename[PATH_MAX];

	scnprintf(from_filename, PATH_MAX, "%s/%s", from_dir, name);
	scnprintf(to_filename, PATH_MAX, "%s/%s", to_dir, name);

	return kcore_copy__compare_files(from_filename, to_filename);
}

/**
 * kcore_copy - copy kallsyms, modules and kcore from one directory to another.
 * @from_dir: from directory
 * @to_dir: to directory
 *
 * This function copies kallsyms, modules and kcore files from one directory to
 * another.  kallsyms and modules are copied entirely.  Only code segments are
 * copied from kcore.  It is assumed that two segments suffice: one for the
 * kernel proper and one for all the modules.  The code segments are determined
 * from kallsyms and modules files.  The kernel map starts at _stext or the
 * lowest function symbol, and ends at _etext or the highest function symbol.
 * The module map starts at the lowest module address and ends at the highest
 * module symbol.  Start addresses are rounded down to the nearest page.  End
 * addresses are rounded up to the nearest page.  An extra page is added to the
 * highest kernel symbol and highest module symbol to, hopefully, encompass that
 * symbol too.  Because it contains only code sections, the resulting kcore is
 * unusual.  One significant peculiarity is that the mapping (start -> pgoff)
 * is not the same for the kernel map and the modules map.  That happens because
 * the data is copied adjacently whereas the original kcore has gaps.  Finally,
 * kallsyms file is compared with its copy to check that modules have not been
 * loaded or unloaded while the copies were taking place.
 *
 * Return: %0 on success, %-1 on failure.
 */
int kcore_copy(const char *from_dir, const char *to_dir)
{
	struct kcore kcore;
	struct kcore extract;
	int idx = 0, err = -1;
	off_t offset, sz;
	struct kcore_copy_info kci = { .stext = 0, };
	char kcore_filename[PATH_MAX];
	char extract_filename[PATH_MAX];
	struct phdr_data *p;

	INIT_LIST_HEAD(&kci.phdrs);
	INIT_LIST_HEAD(&kci.syms);

	if (kcore_copy__copy_file(from_dir, to_dir, "kallsyms"))
		return -1;

	if (kcore_copy__copy_file(from_dir, to_dir, "modules"))
		goto out_unlink_kallsyms;

	scnprintf(kcore_filename, PATH_MAX, "%s/kcore", from_dir);
	scnprintf(extract_filename, PATH_MAX, "%s/kcore", to_dir);

	if (kcore__open(&kcore, kcore_filename))
		goto out_unlink_modules;

	if (kcore_copy__calc_maps(&kci, from_dir, kcore.elf))
		goto out_kcore_close;

	if (kcore__init(&extract, extract_filename, kcore.elfclass, false))
		goto out_kcore_close;

	if (kcore__copy_hdr(&kcore, &extract, kci.phnum))
		goto out_extract_close;

	offset = gelf_fsize(extract.elf, ELF_T_EHDR, 1, EV_CURRENT) +
		 gelf_fsize(extract.elf, ELF_T_PHDR, kci.phnum, EV_CURRENT);
	offset = round_up(offset, page_size);

	kcore_copy__for_each_phdr(&kci, p) {
		off_t offs = p->rel + offset;

		if (kcore__add_phdr(&extract, idx++, offs, p->addr, p->len))
			goto out_extract_close;
	}

	sz = kcore__write(&extract);
	if (sz < 0 || sz > offset)
		goto out_extract_close;

	kcore_copy__for_each_phdr(&kci, p) {
		off_t offs = p->rel + offset;

		if (p->remaps)
			continue;
		if (copy_bytes(kcore.fd, p->offset, extract.fd, offs, p->len))
			goto out_extract_close;
	}

	if (kcore_copy__compare_file(from_dir, to_dir, "kallsyms"))
		goto out_extract_close;

	err = 0;

out_extract_close:
	kcore__close(&extract);
	if (err)
		unlink(extract_filename);
out_kcore_close:
	kcore__close(&kcore);
out_unlink_modules:
	if (err)
		kcore_copy__unlink(to_dir, "modules");
out_unlink_kallsyms:
	if (err)
		kcore_copy__unlink(to_dir, "kallsyms");

	kcore_copy__free_phdrs(&kci);
	kcore_copy__free_syms(&kci);

	return err;
}

int kcore_extract__create(struct kcore_extract *kce)
{
	struct kcore kcore;
	struct kcore extract;
	size_t count = 1;
	int idx = 0, err = -1;
	off_t offset = page_size, sz;

	if (kcore__open(&kcore, kce->kcore_filename))
		return -1;

	strcpy(kce->extract_filename, PERF_KCORE_EXTRACT);
	if (kcore__init(&extract, kce->extract_filename, kcore.elfclass, true))
		goto out_kcore_close;

	if (kcore__copy_hdr(&kcore, &extract, count))
		goto out_extract_close;

	if (kcore__add_phdr(&extract, idx, offset, kce->addr, kce->len))
		goto out_extract_close;

	sz = kcore__write(&extract);
	if (sz < 0 || sz > offset)
		goto out_extract_close;

	if (copy_bytes(kcore.fd, kce->offs, extract.fd, offset, kce->len))
		goto out_extract_close;

	err = 0;

out_extract_close:
	kcore__close(&extract);
	if (err)
		unlink(kce->extract_filename);
out_kcore_close:
	kcore__close(&kcore);

	return err;
}

void kcore_extract__delete(struct kcore_extract *kce)
{
	unlink(kce->extract_filename);
}

#ifdef HAVE_GELF_GETNOTE_SUPPORT

static void sdt_adjust_loc(struct sdt_note *tmp, GElf_Addr base_off)
{
	if (!base_off)
		return;

	if (tmp->bit32)
		tmp->addr.a32[SDT_NOTE_IDX_LOC] =
			tmp->addr.a32[SDT_NOTE_IDX_LOC] + base_off -
			tmp->addr.a32[SDT_NOTE_IDX_BASE];
	else
		tmp->addr.a64[SDT_NOTE_IDX_LOC] =
			tmp->addr.a64[SDT_NOTE_IDX_LOC] + base_off -
			tmp->addr.a64[SDT_NOTE_IDX_BASE];
}

static void sdt_adjust_refctr(struct sdt_note *tmp, GElf_Addr base_addr,
			      GElf_Addr base_off)
{
	if (!base_off)
		return;

	if (tmp->bit32 && tmp->addr.a32[SDT_NOTE_IDX_REFCTR])
		tmp->addr.a32[SDT_NOTE_IDX_REFCTR] -= (base_addr - base_off);
	else if (tmp->addr.a64[SDT_NOTE_IDX_REFCTR])
		tmp->addr.a64[SDT_NOTE_IDX_REFCTR] -= (base_addr - base_off);
}

/**
 * populate_sdt_note : Parse raw data and identify SDT note
 * @elf: elf of the opened file
 * @data: raw data of a section with description offset applied
 * @len: note description size
 * @type: type of the note
 * @sdt_notes: List to add the SDT note
 *
 * Responsible for parsing the @data in section .note.stapsdt in @elf and
 * if its an SDT note, it appends to @sdt_notes list.
 */
static int populate_sdt_note(Elf **elf, const char *data, size_t len,
			     struct list_head *sdt_notes)
{
	const char *provider, *name, *args;
	struct sdt_note *tmp = NULL;
	GElf_Ehdr ehdr;
	GElf_Shdr shdr;
	int ret = -EINVAL;

	union {
		Elf64_Addr a64[NR_ADDR];
		Elf32_Addr a32[NR_ADDR];
	} buf;

	Elf_Data dst = {
		.d_buf = &buf, .d_type = ELF_T_ADDR, .d_version = EV_CURRENT,
		.d_size = gelf_fsize((*elf), ELF_T_ADDR, NR_ADDR, EV_CURRENT),
		.d_off = 0, .d_align = 0
	};
	Elf_Data src = {
		.d_buf = (void *) data, .d_type = ELF_T_ADDR,
		.d_version = EV_CURRENT, .d_size = dst.d_size, .d_off = 0,
		.d_align = 0
	};

	tmp = (struct sdt_note *)calloc(1, sizeof(struct sdt_note));
	if (!tmp) {
		ret = -ENOMEM;
		goto out_err;
	}

	INIT_LIST_HEAD(&tmp->note_list);

	if (len < dst.d_size + 3)
		goto out_free_note;

	/* Translation from file representation to memory representation */
	if (gelf_xlatetom(*elf, &dst, &src,
			  elf_getident(*elf, NULL)[EI_DATA]) == NULL) {
		pr_err("gelf_xlatetom : %s\n", elf_errmsg(-1));
		goto out_free_note;
	}

	/* Populate the fields of sdt_note */
	provider = data + dst.d_size;

	name = (const char *)memchr(provider, '\0', data + len - provider);
	if (name++ == NULL)
		goto out_free_note;

	tmp->provider = strdup(provider);
	if (!tmp->provider) {
		ret = -ENOMEM;
		goto out_free_note;
	}
	tmp->name = strdup(name);
	if (!tmp->name) {
		ret = -ENOMEM;
		goto out_free_prov;
	}

	args = memchr(name, '\0', data + len - name);

	/*
	 * There is no argument if:
	 * - We reached the end of the note;
	 * - There is not enough room to hold a potential string;
	 * - The argument string is empty or just contains ':'.
	 */
	if (args == NULL || data + len - args < 2 ||
		args[1] == ':' || args[1] == '\0')
		tmp->args = NULL;
	else {
		tmp->args = strdup(++args);
		if (!tmp->args) {
			ret = -ENOMEM;
			goto out_free_name;
		}
	}

	if (gelf_getclass(*elf) == ELFCLASS32) {
		memcpy(&tmp->addr, &buf, 3 * sizeof(Elf32_Addr));
		tmp->bit32 = true;
	} else {
		memcpy(&tmp->addr, &buf, 3 * sizeof(Elf64_Addr));
		tmp->bit32 = false;
	}

	if (!gelf_getehdr(*elf, &ehdr)) {
		pr_debug("%s : cannot get elf header.\n", __func__);
		ret = -EBADF;
		goto out_free_args;
	}

	/* Adjust the prelink effect :
	 * Find out the .stapsdt.base section.
	 * This scn will help us to handle prelinking (if present).
	 * Compare the retrieved file offset of the base section with the
	 * base address in the description of the SDT note. If its different,
	 * then accordingly, adjust the note location.
	 */
	if (elf_section_by_name(*elf, &ehdr, &shdr, SDT_BASE_SCN, NULL))
		sdt_adjust_loc(tmp, shdr.sh_offset);

	/* Adjust reference counter offset */
	if (elf_section_by_name(*elf, &ehdr, &shdr, SDT_PROBES_SCN, NULL))
		sdt_adjust_refctr(tmp, shdr.sh_addr, shdr.sh_offset);

	list_add_tail(&tmp->note_list, sdt_notes);
	return 0;

out_free_args:
	zfree(&tmp->args);
out_free_name:
	zfree(&tmp->name);
out_free_prov:
	zfree(&tmp->provider);
out_free_note:
	free(tmp);
out_err:
	return ret;
}

/**
 * construct_sdt_notes_list : constructs a list of SDT notes
 * @elf : elf to look into
 * @sdt_notes : empty list_head
 *
 * Scans the sections in 'elf' for the section
 * .note.stapsdt. It, then calls populate_sdt_note to find
 * out the SDT events and populates the 'sdt_notes'.
 */
static int construct_sdt_notes_list(Elf *elf, struct list_head *sdt_notes)
{
	GElf_Ehdr ehdr;
	Elf_Scn *scn = NULL;
	Elf_Data *data;
	GElf_Shdr shdr;
	size_t shstrndx, next;
	GElf_Nhdr nhdr;
	size_t name_off, desc_off, offset;
	int ret = 0;

	if (gelf_getehdr(elf, &ehdr) == NULL) {
		ret = -EBADF;
		goto out_ret;
	}
	if (elf_getshdrstrndx(elf, &shstrndx) != 0) {
		ret = -EBADF;
		goto out_ret;
	}

	/* Look for the required section */
	scn = elf_section_by_name(elf, &ehdr, &shdr, SDT_NOTE_SCN, NULL);
	if (!scn) {
		ret = -ENOENT;
		goto out_ret;
	}

	if ((shdr.sh_type != SHT_NOTE) || (shdr.sh_flags & SHF_ALLOC)) {
		ret = -ENOENT;
		goto out_ret;
	}

	data = elf_getdata(scn, NULL);

	/* Get the SDT notes */
	for (offset = 0; (next = gelf_getnote(data, offset, &nhdr, &name_off,
					      &desc_off)) > 0; offset = next) {
		if (nhdr.n_namesz == sizeof(SDT_NOTE_NAME) &&
		    !memcmp(data->d_buf + name_off, SDT_NOTE_NAME,
			    sizeof(SDT_NOTE_NAME))) {
			/* Check the type of the note */
			if (nhdr.n_type != SDT_NOTE_TYPE)
				goto out_ret;

			ret = populate_sdt_note(&elf, ((data->d_buf) + desc_off),
						nhdr.n_descsz, sdt_notes);
			if (ret < 0)
				goto out_ret;
		}
	}
	if (list_empty(sdt_notes))
		ret = -ENOENT;

out_ret:
	return ret;
}

/**
 * get_sdt_note_list : Wrapper to construct a list of sdt notes
 * @head : empty list_head
 * @target : file to find SDT notes from
 *
 * This opens the file, initializes
 * the ELF and then calls construct_sdt_notes_list.
 */
int get_sdt_note_list(struct list_head *head, const char *target)
{
	Elf *elf;
	int fd, ret;

	fd = open(target, O_RDONLY);
	if (fd < 0)
		return -EBADF;

	elf = elf_begin(fd, PERF_ELF_C_READ_MMAP, NULL);
	if (!elf) {
		ret = -EBADF;
		goto out_close;
	}
	ret = construct_sdt_notes_list(elf, head);
	elf_end(elf);
out_close:
	close(fd);
	return ret;
}

/**
 * cleanup_sdt_note_list : free the sdt notes' list
 * @sdt_notes: sdt notes' list
 *
 * Free up the SDT notes in @sdt_notes.
 * Returns the number of SDT notes free'd.
 */
int cleanup_sdt_note_list(struct list_head *sdt_notes)
{
	struct sdt_note *tmp, *pos;
	int nr_free = 0;

	list_for_each_entry_safe(pos, tmp, sdt_notes, note_list) {
		list_del_init(&pos->note_list);
		zfree(&pos->args);
		zfree(&pos->name);
		zfree(&pos->provider);
		free(pos);
		nr_free++;
	}
	return nr_free;
}

/**
 * sdt_notes__get_count: Counts the number of sdt events
 * @start: list_head to sdt_notes list
 *
 * Returns the number of SDT notes in a list
 */
int sdt_notes__get_count(struct list_head *start)
{
	struct sdt_note *sdt_ptr;
	int count = 0;

	list_for_each_entry(sdt_ptr, start, note_list)
		count++;
	return count;
}
#endif

void symbol__elf_init(void)
{
	elf_version(EV_CURRENT);
}
