// SPDX-License-Identifier: GPL-2.0
/* This is included from relocs_32/64.c */

#define ElfW(type)		_ElfW(ELF_BITS, type)
#define _ElfW(bits, type)	__ElfW(bits, type)
#define __ElfW(bits, type)	Elf##bits##_##type

#define Elf_Addr		ElfW(Addr)
#define Elf_Ehdr		ElfW(Ehdr)
#define Elf_Phdr		ElfW(Phdr)
#define Elf_Shdr		ElfW(Shdr)
#define Elf_Sym			ElfW(Sym)

static Elf_Ehdr			ehdr;
static unsigned long		shnum;
static unsigned int		shstrndx;
static unsigned int		shsymtabndx;
static unsigned int		shxsymtabndx;

static int sym_index(Elf_Sym *sym);

struct relocs {
				uint32_t	*offset;
				unsigned long	count;
				unsigned long	size;
};

static struct relocs		relocs16;
static struct relocs		relocs32;

#if ELF_BITS == 64
static struct relocs		relocs32neg;
static struct relocs		relocs64;
# define FMT PRIu64
#else
# define FMT PRIu32
#endif

struct section {
				Elf_Shdr       shdr;
				struct section *link;
				Elf_Sym        *symtab;
				Elf32_Word     *xsymtab;
				Elf_Rel        *reltab;
				char           *strtab;
};
static struct section		*secs;

static const char * const	sym_regex_kernel[S_NSYMTYPES] = {
/*
 * Following symbols have been audited. There values are constant and do
 * not change if bzImage is loaded at a different physical address than
 * the address for which it has been compiled. Don't warn user about
 * absolute relocations present w.r.t these symbols.
 */
	[S_ABS] =
	"^(xen_irq_disable_direct_reloc$|"
	"xen_save_fl_direct_reloc$|"
	"xen_elfnote_.+_offset$|"
	"VDSO|"
	"__kcfi_typeid_|"
	"__crc_)",

/*
 * These symbols are known to be relative, even if the linker marks them
 * as absolute (typically defined outside any section in the linker script.)
 */
	[S_REL] =
	"^(__init_(begin|end)|"
	"__x86_cpu_dev_(start|end)|"
	"__alt_instructions(_end)?|"
	"(__iommu_table|__apicdrivers|__smp_locks)(_end)?|"
	"__(start|end)_pci_.*|"
#if CONFIG_FW_LOADER
	"__(start|end)_builtin_fw|"
#endif
	"__(start|stop)___ksymtab(_gpl)?|"
	"__(start|stop)___kcrctab(_gpl)?|"
	"__(start|stop)___param|"
	"__(start|stop)___modver|"
	"__(start|stop)___bug_table|"
	"__tracedata_(start|end)|"
	"__(start|stop)_notes|"
	"__end_rodata|"
	"__end_rodata_aligned|"
	"__initramfs_start|"
	"(jiffies|jiffies_64)|"
#if ELF_BITS == 64
	"__per_cpu_load|"
	"init_per_cpu__.*|"
	"__end_rodata_hpage_align|"
#endif
	"__vvar_page|"
	"_end)$"
};


static const char * const sym_regex_realmode[S_NSYMTYPES] = {
/*
 * These symbols are known to be relative, even if the linker marks them
 * as absolute (typically defined outside any section in the linker script.)
 */
	[S_REL] =
	"^pa_",

/*
 * These are 16-bit segment symbols when compiling 16-bit code.
 */
	[S_SEG] =
	"^real_mode_seg$",

/*
 * These are offsets belonging to segments, as opposed to linear addresses,
 * when compiling 16-bit code.
 */
	[S_LIN] =
	"^pa_",
};

static const char * const	*sym_regex;

static regex_t			sym_regex_c[S_NSYMTYPES];

static int is_reloc(enum symtype type, const char *sym_name)
{
	return sym_regex[type] && !regexec(&sym_regex_c[type], sym_name, 0, NULL, 0);
}

static void regex_init(int use_real_mode)
{
        char errbuf[128];
        int err;
	int i;

	if (use_real_mode)
		sym_regex = sym_regex_realmode;
	else
		sym_regex = sym_regex_kernel;

	for (i = 0; i < S_NSYMTYPES; i++) {
		if (!sym_regex[i])
			continue;

		err = regcomp(&sym_regex_c[i], sym_regex[i], REG_EXTENDED|REG_NOSUB);

		if (err) {
			regerror(err, &sym_regex_c[i], errbuf, sizeof(errbuf));
			die("%s", errbuf);
		}
        }
}

static const char *sym_type(unsigned type)
{
	static const char *type_name[] = {
#define SYM_TYPE(X) [X] = #X
		SYM_TYPE(STT_NOTYPE),
		SYM_TYPE(STT_OBJECT),
		SYM_TYPE(STT_FUNC),
		SYM_TYPE(STT_SECTION),
		SYM_TYPE(STT_FILE),
		SYM_TYPE(STT_COMMON),
		SYM_TYPE(STT_TLS),
#undef SYM_TYPE
	};
	const char *name = "unknown sym type name";

	if (type < ARRAY_SIZE(type_name))
		name = type_name[type];

	return name;
}

static const char *sym_bind(unsigned bind)
{
	static const char *bind_name[] = {
#define SYM_BIND(X) [X] = #X
		SYM_BIND(STB_LOCAL),
		SYM_BIND(STB_GLOBAL),
		SYM_BIND(STB_WEAK),
#undef SYM_BIND
	};
	const char *name = "unknown sym bind name";

	if (bind < ARRAY_SIZE(bind_name))
		name = bind_name[bind];

	return name;
}

static const char *sym_visibility(unsigned visibility)
{
	static const char *visibility_name[] = {
#define SYM_VISIBILITY(X) [X] = #X
		SYM_VISIBILITY(STV_DEFAULT),
		SYM_VISIBILITY(STV_INTERNAL),
		SYM_VISIBILITY(STV_HIDDEN),
		SYM_VISIBILITY(STV_PROTECTED),
#undef SYM_VISIBILITY
	};
	const char *name = "unknown sym visibility name";

	if (visibility < ARRAY_SIZE(visibility_name))
		name = visibility_name[visibility];

	return name;
}

static const char *rel_type(unsigned type)
{
	static const char *type_name[] = {
#define REL_TYPE(X) [X] = #X
#if ELF_BITS == 64
		REL_TYPE(R_X86_64_NONE),
		REL_TYPE(R_X86_64_64),
		REL_TYPE(R_X86_64_PC64),
		REL_TYPE(R_X86_64_PC32),
		REL_TYPE(R_X86_64_GOT32),
		REL_TYPE(R_X86_64_PLT32),
		REL_TYPE(R_X86_64_COPY),
		REL_TYPE(R_X86_64_GLOB_DAT),
		REL_TYPE(R_X86_64_JUMP_SLOT),
		REL_TYPE(R_X86_64_RELATIVE),
		REL_TYPE(R_X86_64_GOTPCREL),
		REL_TYPE(R_X86_64_32),
		REL_TYPE(R_X86_64_32S),
		REL_TYPE(R_X86_64_16),
		REL_TYPE(R_X86_64_PC16),
		REL_TYPE(R_X86_64_8),
		REL_TYPE(R_X86_64_PC8),
#else
		REL_TYPE(R_386_NONE),
		REL_TYPE(R_386_32),
		REL_TYPE(R_386_PC32),
		REL_TYPE(R_386_GOT32),
		REL_TYPE(R_386_PLT32),
		REL_TYPE(R_386_COPY),
		REL_TYPE(R_386_GLOB_DAT),
		REL_TYPE(R_386_JMP_SLOT),
		REL_TYPE(R_386_RELATIVE),
		REL_TYPE(R_386_GOTOFF),
		REL_TYPE(R_386_GOTPC),
		REL_TYPE(R_386_8),
		REL_TYPE(R_386_PC8),
		REL_TYPE(R_386_16),
		REL_TYPE(R_386_PC16),
#endif
#undef REL_TYPE
	};
	const char *name = "unknown type rel type name";

	if (type < ARRAY_SIZE(type_name) && type_name[type])
		name = type_name[type];

	return name;
}

static const char *sec_name(unsigned shndx)
{
	const char *sec_strtab;
	const char *name;
	sec_strtab = secs[shstrndx].strtab;
	name = "<noname>";

	if (shndx < shnum)
		name = sec_strtab + secs[shndx].shdr.sh_name;
	else if (shndx == SHN_ABS)
		name = "ABSOLUTE";
	else if (shndx == SHN_COMMON)
		name = "COMMON";

	return name;
}

static const char *sym_name(const char *sym_strtab, Elf_Sym *sym)
{
	const char *name;
	name = "<noname>";

	if (sym->st_name)
		name = sym_strtab + sym->st_name;
	else
		name = sec_name(sym_index(sym));

	return name;
}

static Elf_Sym *sym_lookup(const char *symname)
{
	int i;

	for (i = 0; i < shnum; i++) {
		struct section *sec = &secs[i];
		long nsyms;
		char *strtab;
		Elf_Sym *symtab;
		Elf_Sym *sym;

		if (sec->shdr.sh_type != SHT_SYMTAB)
			continue;

		nsyms = sec->shdr.sh_size/sizeof(Elf_Sym);
		symtab = sec->symtab;
		strtab = sec->link->strtab;

		for (sym = symtab; --nsyms >= 0; sym++) {
			if (!sym->st_name)
				continue;
			if (strcmp(symname, strtab + sym->st_name) == 0)
				return sym;
		}
	}
	return 0;
}

#if BYTE_ORDER == LITTLE_ENDIAN
# define le16_to_cpu(val)	(val)
# define le32_to_cpu(val)	(val)
# define le64_to_cpu(val)	(val)
#endif

#if BYTE_ORDER == BIG_ENDIAN
# define le16_to_cpu(val)	bswap_16(val)
# define le32_to_cpu(val)	bswap_32(val)
# define le64_to_cpu(val)	bswap_64(val)
#endif

static uint16_t elf16_to_cpu(uint16_t val)
{
	return le16_to_cpu(val);
}

static uint32_t elf32_to_cpu(uint32_t val)
{
	return le32_to_cpu(val);
}

#define elf_half_to_cpu(x)	elf16_to_cpu(x)
#define elf_word_to_cpu(x)	elf32_to_cpu(x)

#if ELF_BITS == 64
static uint64_t elf64_to_cpu(uint64_t val)
{
        return le64_to_cpu(val);
}
# define elf_addr_to_cpu(x)	elf64_to_cpu(x)
# define elf_off_to_cpu(x)	elf64_to_cpu(x)
# define elf_xword_to_cpu(x)	elf64_to_cpu(x)
#else
# define elf_addr_to_cpu(x)	elf32_to_cpu(x)
# define elf_off_to_cpu(x)	elf32_to_cpu(x)
# define elf_xword_to_cpu(x)	elf32_to_cpu(x)
#endif

static int sym_index(Elf_Sym *sym)
{
	Elf_Sym *symtab = secs[shsymtabndx].symtab;
	Elf32_Word *xsymtab = secs[shxsymtabndx].xsymtab;
	unsigned long offset;
	int index;

	if (sym->st_shndx != SHN_XINDEX)
		return sym->st_shndx;

	/* calculate offset of sym from head of table. */
	offset = (unsigned long)sym - (unsigned long)symtab;
	index = offset / sizeof(*sym);

	return elf32_to_cpu(xsymtab[index]);
}

static void read_ehdr(FILE *fp)
{
	if (fread(&ehdr, sizeof(ehdr), 1, fp) != 1)
		die("Cannot read ELF header: %s\n", strerror(errno));
	if (memcmp(ehdr.e_ident, ELFMAG, SELFMAG) != 0)
		die("No ELF magic\n");
	if (ehdr.e_ident[EI_CLASS] != ELF_CLASS)
		die("Not a %d bit executable\n", ELF_BITS);
	if (ehdr.e_ident[EI_DATA] != ELFDATA2LSB)
		die("Not a LSB ELF executable\n");
	if (ehdr.e_ident[EI_VERSION] != EV_CURRENT)
		die("Unknown ELF version\n");

	/* Convert the fields to native endian */
	ehdr.e_type      = elf_half_to_cpu(ehdr.e_type);
	ehdr.e_machine   = elf_half_to_cpu(ehdr.e_machine);
	ehdr.e_version   = elf_word_to_cpu(ehdr.e_version);
	ehdr.e_entry     = elf_addr_to_cpu(ehdr.e_entry);
	ehdr.e_phoff     = elf_off_to_cpu(ehdr.e_phoff);
	ehdr.e_shoff     = elf_off_to_cpu(ehdr.e_shoff);
	ehdr.e_flags     = elf_word_to_cpu(ehdr.e_flags);
	ehdr.e_ehsize    = elf_half_to_cpu(ehdr.e_ehsize);
	ehdr.e_phentsize = elf_half_to_cpu(ehdr.e_phentsize);
	ehdr.e_phnum     = elf_half_to_cpu(ehdr.e_phnum);
	ehdr.e_shentsize = elf_half_to_cpu(ehdr.e_shentsize);
	ehdr.e_shnum     = elf_half_to_cpu(ehdr.e_shnum);
	ehdr.e_shstrndx  = elf_half_to_cpu(ehdr.e_shstrndx);

	shnum = ehdr.e_shnum;
	shstrndx = ehdr.e_shstrndx;

	if ((ehdr.e_type != ET_EXEC) && (ehdr.e_type != ET_DYN))
		die("Unsupported ELF header type\n");
	if (ehdr.e_machine != ELF_MACHINE)
		die("Not for %s\n", ELF_MACHINE_NAME);
	if (ehdr.e_version != EV_CURRENT)
		die("Unknown ELF version\n");
	if (ehdr.e_ehsize != sizeof(Elf_Ehdr))
		die("Bad ELF header size\n");
	if (ehdr.e_phentsize != sizeof(Elf_Phdr))
		die("Bad program header entry\n");
	if (ehdr.e_shentsize != sizeof(Elf_Shdr))
		die("Bad section header entry\n");


	if (shnum == SHN_UNDEF || shstrndx == SHN_XINDEX) {
		Elf_Shdr shdr;

		if (fseek(fp, ehdr.e_shoff, SEEK_SET) < 0)
			die("Seek to %" FMT " failed: %s\n", ehdr.e_shoff, strerror(errno));

		if (fread(&shdr, sizeof(shdr), 1, fp) != 1)
			die("Cannot read initial ELF section header: %s\n", strerror(errno));

		if (shnum == SHN_UNDEF)
			shnum = elf_xword_to_cpu(shdr.sh_size);

		if (shstrndx == SHN_XINDEX)
			shstrndx = elf_word_to_cpu(shdr.sh_link);
	}

	if (shstrndx >= shnum)
		die("String table index out of bounds\n");
}

static void read_shdrs(FILE *fp)
{
	int i;
	Elf_Shdr shdr;

	secs = calloc(shnum, sizeof(struct section));
	if (!secs)
		die("Unable to allocate %ld section headers\n", shnum);

	if (fseek(fp, ehdr.e_shoff, SEEK_SET) < 0)
		die("Seek to %" FMT " failed: %s\n", ehdr.e_shoff, strerror(errno));

	for (i = 0; i < shnum; i++) {
		struct section *sec = &secs[i];

		if (fread(&shdr, sizeof(shdr), 1, fp) != 1)
			die("Cannot read ELF section headers %d/%ld: %s\n", i, shnum, strerror(errno));

		sec->shdr.sh_name      = elf_word_to_cpu(shdr.sh_name);
		sec->shdr.sh_type      = elf_word_to_cpu(shdr.sh_type);
		sec->shdr.sh_flags     = elf_xword_to_cpu(shdr.sh_flags);
		sec->shdr.sh_addr      = elf_addr_to_cpu(shdr.sh_addr);
		sec->shdr.sh_offset    = elf_off_to_cpu(shdr.sh_offset);
		sec->shdr.sh_size      = elf_xword_to_cpu(shdr.sh_size);
		sec->shdr.sh_link      = elf_word_to_cpu(shdr.sh_link);
		sec->shdr.sh_info      = elf_word_to_cpu(shdr.sh_info);
		sec->shdr.sh_addralign = elf_xword_to_cpu(shdr.sh_addralign);
		sec->shdr.sh_entsize   = elf_xword_to_cpu(shdr.sh_entsize);
		if (sec->shdr.sh_link < shnum)
			sec->link = &secs[sec->shdr.sh_link];
	}

}

static void read_strtabs(FILE *fp)
{
	int i;

	for (i = 0; i < shnum; i++) {
		struct section *sec = &secs[i];

		if (sec->shdr.sh_type != SHT_STRTAB)
			continue;

		sec->strtab = malloc(sec->shdr.sh_size);
		if (!sec->strtab)
			die("malloc of %" FMT " bytes for strtab failed\n", sec->shdr.sh_size);

		if (fseek(fp, sec->shdr.sh_offset, SEEK_SET) < 0)
			die("Seek to %" FMT " failed: %s\n", sec->shdr.sh_offset, strerror(errno));

		if (fread(sec->strtab, 1, sec->shdr.sh_size, fp) != sec->shdr.sh_size)
			die("Cannot read symbol table: %s\n", strerror(errno));
	}
}

static void read_symtabs(FILE *fp)
{
	int i, j;

	for (i = 0; i < shnum; i++) {
		struct section *sec = &secs[i];
		int num_syms;

		switch (sec->shdr.sh_type) {
		case SHT_SYMTAB_SHNDX:
			sec->xsymtab = malloc(sec->shdr.sh_size);
			if (!sec->xsymtab)
				die("malloc of %" FMT " bytes for xsymtab failed\n", sec->shdr.sh_size);

			if (fseek(fp, sec->shdr.sh_offset, SEEK_SET) < 0)
				die("Seek to %" FMT " failed: %s\n", sec->shdr.sh_offset, strerror(errno));

			if (fread(sec->xsymtab, 1, sec->shdr.sh_size, fp) != sec->shdr.sh_size)
				die("Cannot read extended symbol table: %s\n", strerror(errno));

			shxsymtabndx = i;
			continue;

		case SHT_SYMTAB:
			num_syms = sec->shdr.sh_size / sizeof(Elf_Sym);

			sec->symtab = malloc(sec->shdr.sh_size);
			if (!sec->symtab)
				die("malloc of %" FMT " bytes for symtab failed\n", sec->shdr.sh_size);

			if (fseek(fp, sec->shdr.sh_offset, SEEK_SET) < 0)
				die("Seek to %" FMT " failed: %s\n", sec->shdr.sh_offset, strerror(errno));

			if (fread(sec->symtab, 1, sec->shdr.sh_size, fp) != sec->shdr.sh_size)
				die("Cannot read symbol table: %s\n", strerror(errno));

			for (j = 0; j < num_syms; j++) {
				Elf_Sym *sym = &sec->symtab[j];

				sym->st_name  = elf_word_to_cpu(sym->st_name);
				sym->st_value = elf_addr_to_cpu(sym->st_value);
				sym->st_size  = elf_xword_to_cpu(sym->st_size);
				sym->st_shndx = elf_half_to_cpu(sym->st_shndx);
			}
			shsymtabndx = i;
			continue;

		default:
			continue;
		}
	}
}


static void read_relocs(FILE *fp)
{
	int i, j;

	for (i = 0; i < shnum; i++) {
		struct section *sec = &secs[i];

		if (sec->shdr.sh_type != SHT_REL_TYPE)
			continue;

		sec->reltab = malloc(sec->shdr.sh_size);
		if (!sec->reltab)
			die("malloc of %" FMT " bytes for relocs failed\n", sec->shdr.sh_size);

		if (fseek(fp, sec->shdr.sh_offset, SEEK_SET) < 0)
			die("Seek to %" FMT " failed: %s\n", sec->shdr.sh_offset, strerror(errno));

		if (fread(sec->reltab, 1, sec->shdr.sh_size, fp) != sec->shdr.sh_size)
			die("Cannot read symbol table: %s\n", strerror(errno));

		for (j = 0; j < sec->shdr.sh_size/sizeof(Elf_Rel); j++) {
			Elf_Rel *rel = &sec->reltab[j];

			rel->r_offset = elf_addr_to_cpu(rel->r_offset);
			rel->r_info   = elf_xword_to_cpu(rel->r_info);
#if (SHT_REL_TYPE == SHT_RELA)
			rel->r_addend = elf_xword_to_cpu(rel->r_addend);
#endif
		}
	}
}


static void print_absolute_symbols(void)
{
	int i;
	const char *format;

	if (ELF_BITS == 64)
		format = "%5d %016"PRIx64" %5"PRId64" %10s %10s %12s %s\n";
	else
		format = "%5d %08"PRIx32"  %5"PRId32" %10s %10s %12s %s\n";

	printf("Absolute symbols\n");
	printf(" Num:    Value Size  Type       Bind        Visibility  Name\n");

	for (i = 0; i < shnum; i++) {
		struct section *sec = &secs[i];
		char *sym_strtab;
		int j;

		if (sec->shdr.sh_type != SHT_SYMTAB)
			continue;

		sym_strtab = sec->link->strtab;

		for (j = 0; j < sec->shdr.sh_size/sizeof(Elf_Sym); j++) {
			Elf_Sym *sym;
			const char *name;

			sym = &sec->symtab[j];
			name = sym_name(sym_strtab, sym);

			if (sym->st_shndx != SHN_ABS)
				continue;

			printf(format,
				j, sym->st_value, sym->st_size,
				sym_type(ELF_ST_TYPE(sym->st_info)),
				sym_bind(ELF_ST_BIND(sym->st_info)),
				sym_visibility(ELF_ST_VISIBILITY(sym->st_other)),
				name);
		}
	}
	printf("\n");
}

static void print_absolute_relocs(void)
{
	int i, printed = 0;
	const char *format;

	if (ELF_BITS == 64)
		format = "%016"PRIx64" %016"PRIx64" %10s %016"PRIx64"  %s\n";
	else
		format = "%08"PRIx32" %08"PRIx32" %10s %08"PRIx32"  %s\n";

	for (i = 0; i < shnum; i++) {
		struct section *sec = &secs[i];
		struct section *sec_applies, *sec_symtab;
		char *sym_strtab;
		Elf_Sym *sh_symtab;
		int j;

		if (sec->shdr.sh_type != SHT_REL_TYPE)
			continue;

		sec_symtab  = sec->link;
		sec_applies = &secs[sec->shdr.sh_info];
		if (!(sec_applies->shdr.sh_flags & SHF_ALLOC))
			continue;

		/*
		 * Do not perform relocations in .notes section; any
		 * values there are meant for pre-boot consumption (e.g.
		 * startup_xen).
		 */
		if (sec_applies->shdr.sh_type == SHT_NOTE)
			continue;

		sh_symtab  = sec_symtab->symtab;
		sym_strtab = sec_symtab->link->strtab;

		for (j = 0; j < sec->shdr.sh_size/sizeof(Elf_Rel); j++) {
			Elf_Rel *rel;
			Elf_Sym *sym;
			const char *name;

			rel = &sec->reltab[j];
			sym = &sh_symtab[ELF_R_SYM(rel->r_info)];
			name = sym_name(sym_strtab, sym);

			if (sym->st_shndx != SHN_ABS)
				continue;

			/* Absolute symbols are not relocated if bzImage is
			 * loaded at a non-compiled address. Display a warning
			 * to user at compile time about the absolute
			 * relocations present.
			 *
			 * User need to audit the code to make sure
			 * some symbols which should have been section
			 * relative have not become absolute because of some
			 * linker optimization or wrong programming usage.
			 *
			 * Before warning check if this absolute symbol
			 * relocation is harmless.
			 */
			if (is_reloc(S_ABS, name) || is_reloc(S_REL, name))
				continue;

			if (!printed) {
				printf("WARNING: Absolute relocations present\n");
				printf("Offset     Info     Type     Sym.Value Sym.Name\n");
				printed = 1;
			}

			printf(format,
				rel->r_offset,
				rel->r_info,
				rel_type(ELF_R_TYPE(rel->r_info)),
				sym->st_value,
				name);
		}
	}

	if (printed)
		printf("\n");
}

static void add_reloc(struct relocs *r, uint32_t offset)
{
	if (r->count == r->size) {
		unsigned long newsize = r->size + 50000;
		void *mem = realloc(r->offset, newsize * sizeof(r->offset[0]));

		if (!mem)
			die("realloc of %ld entries for relocs failed\n", newsize);

		r->offset = mem;
		r->size = newsize;
	}
	r->offset[r->count++] = offset;
}

static void walk_relocs(int (*process)(struct section *sec, Elf_Rel *rel,
			Elf_Sym *sym, const char *symname))
{
	int i;

	/* Walk through the relocations */
	for (i = 0; i < shnum; i++) {
		char *sym_strtab;
		Elf_Sym *sh_symtab;
		struct section *sec_applies, *sec_symtab;
		int j;
		struct section *sec = &secs[i];

		if (sec->shdr.sh_type != SHT_REL_TYPE)
			continue;

		sec_symtab  = sec->link;
		sec_applies = &secs[sec->shdr.sh_info];
		if (!(sec_applies->shdr.sh_flags & SHF_ALLOC))
			continue;

		/*
		 * Do not perform relocations in .notes sections; any
		 * values there are meant for pre-boot consumption (e.g.
		 * startup_xen).
		 */
		if (sec_applies->shdr.sh_type == SHT_NOTE)
			continue;

		sh_symtab = sec_symtab->symtab;
		sym_strtab = sec_symtab->link->strtab;

		for (j = 0; j < sec->shdr.sh_size/sizeof(Elf_Rel); j++) {
			Elf_Rel *rel = &sec->reltab[j];
			Elf_Sym *sym = &sh_symtab[ELF_R_SYM(rel->r_info)];
			const char *symname = sym_name(sym_strtab, sym);

			process(sec, rel, sym, symname);
		}
	}
}

/*
 * The .data..percpu section is a special case for x86_64 SMP kernels.
 * It is used to initialize the actual per_cpu areas and to provide
 * definitions for the per_cpu variables that correspond to their offsets
 * within the percpu area. Since the values of all of the symbols need
 * to be offsets from the start of the per_cpu area the virtual address
 * (sh_addr) of .data..percpu is 0 in SMP kernels.
 *
 * This means that:
 *
 *	Relocations that reference symbols in the per_cpu area do not
 *	need further relocation (since the value is an offset relative
 *	to the start of the per_cpu area that does not change).
 *
 *	Relocations that apply to the per_cpu area need to have their
 *	offset adjusted by by the value of __per_cpu_load to make them
 *	point to the correct place in the loaded image (because the
 *	virtual address of .data..percpu is 0).
 *
 * For non SMP kernels .data..percpu is linked as part of the normal
 * kernel data and does not require special treatment.
 *
 */
static int per_cpu_shndx = -1;
static Elf_Addr per_cpu_load_addr;

static void percpu_init(void)
{
	int i;

	for (i = 0; i < shnum; i++) {
		ElfW(Sym) *sym;

		if (strcmp(sec_name(i), ".data..percpu"))
			continue;

		if (secs[i].shdr.sh_addr != 0)	/* non SMP kernel */
			return;

		sym = sym_lookup("__per_cpu_load");
		if (!sym)
			die("can't find __per_cpu_load\n");

		per_cpu_shndx = i;
		per_cpu_load_addr = sym->st_value;

		return;
	}
}

#if ELF_BITS == 64

/*
 * Check to see if a symbol lies in the .data..percpu section.
 *
 * The linker incorrectly associates some symbols with the
 * .data..percpu section so we also need to check the symbol
 * name to make sure that we classify the symbol correctly.
 *
 * The GNU linker incorrectly associates:
 *	__init_begin
 *	__per_cpu_load
 *
 * The "gold" linker incorrectly associates:
 *	init_per_cpu__fixed_percpu_data
 *	init_per_cpu__gdt_page
 */
static int is_percpu_sym(ElfW(Sym) *sym, const char *symname)
{
	int shndx = sym_index(sym);

	return (shndx == per_cpu_shndx) &&
		strcmp(symname, "__init_begin") &&
		strcmp(symname, "__per_cpu_load") &&
		strncmp(symname, "init_per_cpu_", 13);
}


static int do_reloc64(struct section *sec, Elf_Rel *rel, ElfW(Sym) *sym,
		      const char *symname)
{
	unsigned r_type = ELF64_R_TYPE(rel->r_info);
	ElfW(Addr) offset = rel->r_offset;
	int shn_abs = (sym->st_shndx == SHN_ABS) && !is_reloc(S_REL, symname);

	if (sym->st_shndx == SHN_UNDEF)
		return 0;

	/*
	 * Adjust the offset if this reloc applies to the percpu section.
	 */
	if (sec->shdr.sh_info == per_cpu_shndx)
		offset += per_cpu_load_addr;

	switch (r_type) {
	case R_X86_64_NONE:
		/* NONE can be ignored. */
		break;

	case R_X86_64_PC32:
	case R_X86_64_PLT32:
		/*
		 * PC relative relocations don't need to be adjusted unless
		 * referencing a percpu symbol.
		 *
		 * NB: R_X86_64_PLT32 can be treated as R_X86_64_PC32.
		 */
		if (is_percpu_sym(sym, symname))
			add_reloc(&relocs32neg, offset);
		break;

	case R_X86_64_PC64:
		/*
		 * Only used by jump labels
		 */
		if (is_percpu_sym(sym, symname))
			die("Invalid R_X86_64_PC64 relocation against per-CPU symbol %s\n", symname);
		break;

	case R_X86_64_32:
	case R_X86_64_32S:
	case R_X86_64_64:
		/*
		 * References to the percpu area don't need to be adjusted.
		 */
		if (is_percpu_sym(sym, symname))
			break;

		if (shn_abs) {
			/*
			 * Whitelisted absolute symbols do not require
			 * relocation.
			 */
			if (is_reloc(S_ABS, symname))
				break;

			die("Invalid absolute %s relocation: %s\n", rel_type(r_type), symname);
			break;
		}

		/*
		 * Relocation offsets for 64 bit kernels are output
		 * as 32 bits and sign extended back to 64 bits when
		 * the relocations are processed.
		 * Make sure that the offset will fit.
		 */
		if ((int32_t)offset != (int64_t)offset)
			die("Relocation offset doesn't fit in 32 bits\n");

		if (r_type == R_X86_64_64)
			add_reloc(&relocs64, offset);
		else
			add_reloc(&relocs32, offset);
		break;

	default:
		die("Unsupported relocation type: %s (%d)\n", rel_type(r_type), r_type);
		break;
	}

	return 0;
}

#else

static int do_reloc32(struct section *sec, Elf_Rel *rel, Elf_Sym *sym,
		      const char *symname)
{
	unsigned r_type = ELF32_R_TYPE(rel->r_info);
	int shn_abs = (sym->st_shndx == SHN_ABS) && !is_reloc(S_REL, symname);

	switch (r_type) {
	case R_386_NONE:
	case R_386_PC32:
	case R_386_PC16:
	case R_386_PC8:
	case R_386_PLT32:
		/*
		 * NONE can be ignored and PC relative relocations don't need
		 * to be adjusted. Because sym must be defined, R_386_PLT32 can
		 * be treated the same way as R_386_PC32.
		 */
		break;

	case R_386_32:
		if (shn_abs) {
			/*
			 * Whitelisted absolute symbols do not require
			 * relocation.
			 */
			if (is_reloc(S_ABS, symname))
				break;

			die("Invalid absolute %s relocation: %s\n", rel_type(r_type), symname);
			break;
		}

		add_reloc(&relocs32, rel->r_offset);
		break;

	default:
		die("Unsupported relocation type: %s (%d)\n", rel_type(r_type), r_type);
		break;
	}

	return 0;
}

static int do_reloc_real(struct section *sec, Elf_Rel *rel, Elf_Sym *sym, const char *symname)
{
	unsigned r_type = ELF32_R_TYPE(rel->r_info);
	int shn_abs = (sym->st_shndx == SHN_ABS) && !is_reloc(S_REL, symname);

	switch (r_type) {
	case R_386_NONE:
	case R_386_PC32:
	case R_386_PC16:
	case R_386_PC8:
	case R_386_PLT32:
		/*
		 * NONE can be ignored and PC relative relocations don't need
		 * to be adjusted. Because sym must be defined, R_386_PLT32 can
		 * be treated the same way as R_386_PC32.
		 */
		break;

	case R_386_16:
		if (shn_abs) {
			/*
			 * Whitelisted absolute symbols do not require
			 * relocation.
			 */
			if (is_reloc(S_ABS, symname))
				break;

			if (is_reloc(S_SEG, symname)) {
				add_reloc(&relocs16, rel->r_offset);
				break;
			}
		} else {
			if (!is_reloc(S_LIN, symname))
				break;
		}
		die("Invalid %s %s relocation: %s\n", shn_abs ? "absolute" : "relative", rel_type(r_type), symname);
		break;

	case R_386_32:
		if (shn_abs) {
			/*
			 * Whitelisted absolute symbols do not require
			 * relocation.
			 */
			if (is_reloc(S_ABS, symname))
				break;

			if (is_reloc(S_REL, symname)) {
				add_reloc(&relocs32, rel->r_offset);
				break;
			}
		} else {
			if (is_reloc(S_LIN, symname))
				add_reloc(&relocs32, rel->r_offset);
			break;
		}
		die("Invalid %s %s relocation: %s\n", shn_abs ? "absolute" : "relative", rel_type(r_type), symname);
		break;

	default:
		die("Unsupported relocation type: %s (%d)\n", rel_type(r_type), r_type);
		break;
	}

	return 0;
}

#endif

static int cmp_relocs(const void *va, const void *vb)
{
	const uint32_t *a, *b;

	a = va;
	b = vb;

	return (*a == *b)? 0 : (*a > *b)? 1 : -1;
}

static void sort_relocs(struct relocs *r)
{
	qsort(r->offset, r->count, sizeof(r->offset[0]), cmp_relocs);
}

static int write32(uint32_t v, FILE *f)
{
	unsigned char buf[4];

	put_unaligned_le32(v, buf);

	return fwrite(buf, 1, 4, f) == 4 ? 0 : -1;
}

static int write32_as_text(uint32_t v, FILE *f)
{
	return fprintf(f, "\t.long 0x%08"PRIx32"\n", v) > 0 ? 0 : -1;
}

static void emit_relocs(int as_text, int use_real_mode)
{
	int i;
	int (*write_reloc)(uint32_t, FILE *) = write32;
	int (*do_reloc)(struct section *sec, Elf_Rel *rel, Elf_Sym *sym, const char *symname);

#if ELF_BITS == 64
	if (!use_real_mode)
		do_reloc = do_reloc64;
	else
		die("--realmode not valid for a 64-bit ELF file");
#else
	if (!use_real_mode)
		do_reloc = do_reloc32;
	else
		do_reloc = do_reloc_real;
#endif

	/* Collect up the relocations */
	walk_relocs(do_reloc);

	if (relocs16.count && !use_real_mode)
		die("Segment relocations found but --realmode not specified\n");

	/* Order the relocations for more efficient processing */
	sort_relocs(&relocs32);
#if ELF_BITS == 64
	sort_relocs(&relocs32neg);
	sort_relocs(&relocs64);
#else
	sort_relocs(&relocs16);
#endif

	/* Print the relocations */
	if (as_text) {
		/* Print the relocations in a form suitable that
		 * gas will like.
		 */
		printf(".section \".data.reloc\",\"a\"\n");
		printf(".balign 4\n");
		write_reloc = write32_as_text;
	}

	if (use_real_mode) {
		write_reloc(relocs16.count, stdout);
		for (i = 0; i < relocs16.count; i++)
			write_reloc(relocs16.offset[i], stdout);

		write_reloc(relocs32.count, stdout);
		for (i = 0; i < relocs32.count; i++)
			write_reloc(relocs32.offset[i], stdout);
	} else {
#if ELF_BITS == 64
		/* Print a stop */
		write_reloc(0, stdout);

		/* Now print each relocation */
		for (i = 0; i < relocs64.count; i++)
			write_reloc(relocs64.offset[i], stdout);

		/* Print a stop */
		write_reloc(0, stdout);

		/* Now print each inverse 32-bit relocation */
		for (i = 0; i < relocs32neg.count; i++)
			write_reloc(relocs32neg.offset[i], stdout);
#endif

		/* Print a stop */
		write_reloc(0, stdout);

		/* Now print each relocation */
		for (i = 0; i < relocs32.count; i++)
			write_reloc(relocs32.offset[i], stdout);
	}
}

/*
 * As an aid to debugging problems with different linkers
 * print summary information about the relocs.
 * Since different linkers tend to emit the sections in
 * different orders we use the section names in the output.
 */
static int do_reloc_info(struct section *sec, Elf_Rel *rel, ElfW(Sym) *sym,
				const char *symname)
{
	printf("%s\t%s\t%s\t%s\n",
		sec_name(sec->shdr.sh_info),
		rel_type(ELF_R_TYPE(rel->r_info)),
		symname,
		sec_name(sym_index(sym)));

	return 0;
}

static void print_reloc_info(void)
{
	printf("reloc section\treloc type\tsymbol\tsymbol section\n");
	walk_relocs(do_reloc_info);
}

#if ELF_BITS == 64
# define process process_64
#else
# define process process_32
#endif

void process(FILE *fp, int use_real_mode, int as_text,
	     int show_absolute_syms, int show_absolute_relocs,
	     int show_reloc_info)
{
	regex_init(use_real_mode);
	read_ehdr(fp);
	read_shdrs(fp);
	read_strtabs(fp);
	read_symtabs(fp);
	read_relocs(fp);

	if (ELF_BITS == 64)
		percpu_init();

	if (show_absolute_syms) {
		print_absolute_symbols();
		return;
	}

	if (show_absolute_relocs) {
		print_absolute_relocs();
		return;
	}

	if (show_reloc_info) {
		print_reloc_info();
		return;
	}

	emit_relocs(as_text, use_real_mode);
}
