// 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 | O_CLOEXEC);
	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 ||
	    (symbol__type(sym) != STT_GNU_IFUNC && !symbol__ifunc_alias(sym)))
		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, descsz, remaining;
		const char *name;

		/* ensure the note header fits within the section */
		if (ptr + sizeof(*nhdr) > data->d_buf + data->d_size)
			break;

		namesz = NOTE_ALIGN(nhdr->n_namesz);
		descsz = NOTE_ALIGN(nhdr->n_descsz);

		/* validate individually to avoid size_t overflow on 32-bit */
		remaining = data->d_buf + data->d_size - ptr - sizeof(*nhdr);
		if (namesz > remaining || descsz > remaining - namesz) {
			pr_warning("%s: oversized note: n_namesz=%u, n_descsz=%u\n",
				   __func__, nhdr->n_namesz, nhdr->n_descsz);
			break;
		}

		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 | O_CLOEXEC);
	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);
		/* non-empty path means a temp file was created */
		if (path[0] != '\0')
			filename = path;
	}

	err = read_build_id(filename, bid);

	if (m.comp && filename == path)
		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 | O_CLOEXEC);
	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 {
				/* descsz from untrusted file — clamp to buffer */
				if (descsz > sizeof(bf))
					break;
				if (read(fd, bf, descsz) != (ssize_t)descsz)
					break;
			}
		} else {
			size_t n;

			/* int sum of namesz+descsz can overflow negative, bypassing size check */
			if (namesz > sizeof(bf) || descsz > sizeof(bf) - namesz) {
				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);
			} else {
				n = namesz + descsz;
			}
			/* no valid note has both namesz and descsz zero */
			if (n == 0)
				break;
			if (read(fd, bf, n) != (ssize_t)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 | O_CLOEXEC);
	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 */
	if (data->d_size > 0) {
		size_t len = min(size - 1, data->d_size);

		memcpy(debuglink, data->d_buf, len);
		debuglink[len] = '\0';
	} else {
		debuglink[0] = '\0';
	}

	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 = mkostemp(temp_filename, O_CLOEXEC);
	if (temp_fd < 0) {
		pr_debug("%s: mkostemp: %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 | O_CLOEXEC);
		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) { }

struct remap_kernel_ctx {
	u64 sh_addr;
	u64 sh_size;
	u64 sh_offset;
	struct kmap *kmap;
};

static int remap_kernel_cb(struct map *map, void *data)
{
	struct remap_kernel_ctx *ctx = data;

	map__set_start(map, ctx->sh_addr + ref_reloc(ctx->kmap));
	map__set_end(map, map__start(map) + ctx->sh_size);
	map__set_pgoff(map, ctx->sh_offset);
	map__set_mapping_type(map, MAPPING_TYPE__DSO);
	return 0;
}

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) {
			struct remap_kernel_ctx ctx = {
				.sh_addr = shdr->sh_addr,
				.sh_size = shdr->sh_size,
				.sh_offset = shdr->sh_offset,
				.kmap = kmap
			};

			*remap_kernel = false;
			maps__mutate_mapping(kmaps, map, remap_kernel_cb, &ctx);
		}

		/*
		 * 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;
		}

		/* Reject kernel mapping symbols for kernel DSOs only */
		if (dso__kernel(dso) && is_ignored_kernel_symbol(elf_name))
			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) {
			if (dynsym && ehdr.e_shnum &&
			    sym.st_shndx < SHN_LORESERVE &&
			    sym.st_shndx >= ehdr.e_shnum)
				continue;
			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);
		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 | O_CLOEXEC);
	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 = mkostemp(filename, O_CLOEXEC);
	else
		kcore->fd = open(filename, O_WRONLY | O_CREAT | O_EXCL | O_CLOEXEC, 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;

	/* Ignore livepatch symbols */
	if (is_livepatch_symbol(name))
		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 | O_CLOEXEC);
	if (from < 0)
		return -1;

	to = open(to_filename, O_RDONLY | O_CLOEXEC);
	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 | O_CLOEXEC);
	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);
}
