cachepc-linux

Fork of AMDESE/linux with modifications for CachePC side-channel attack
git clone https://git.sinitax.com/sinitax/cachepc-linux
Log | Files | Refs | README | LICENSE | sfeed.txt

relocs.c (28997B)


      1// SPDX-License-Identifier: GPL-2.0
      2/* This is included from relocs_32/64.c */
      3
      4#define ElfW(type)		_ElfW(ELF_BITS, type)
      5#define _ElfW(bits, type)	__ElfW(bits, type)
      6#define __ElfW(bits, type)	Elf##bits##_##type
      7
      8#define Elf_Addr		ElfW(Addr)
      9#define Elf_Ehdr		ElfW(Ehdr)
     10#define Elf_Phdr		ElfW(Phdr)
     11#define Elf_Shdr		ElfW(Shdr)
     12#define Elf_Sym			ElfW(Sym)
     13
     14static Elf_Ehdr		ehdr;
     15static unsigned long	shnum;
     16static unsigned int	shstrndx;
     17static unsigned int	shsymtabndx;
     18static unsigned int	shxsymtabndx;
     19
     20static int sym_index(Elf_Sym *sym);
     21
     22struct relocs {
     23	uint32_t	*offset;
     24	unsigned long	count;
     25	unsigned long	size;
     26};
     27
     28static struct relocs relocs16;
     29static struct relocs relocs32;
     30#if ELF_BITS == 64
     31static struct relocs relocs32neg;
     32static struct relocs relocs64;
     33#define FMT PRIu64
     34#else
     35#define FMT PRIu32
     36#endif
     37
     38struct section {
     39	Elf_Shdr       shdr;
     40	struct section *link;
     41	Elf_Sym        *symtab;
     42	Elf32_Word     *xsymtab;
     43	Elf_Rel        *reltab;
     44	char           *strtab;
     45};
     46static struct section *secs;
     47
     48static const char * const sym_regex_kernel[S_NSYMTYPES] = {
     49/*
     50 * Following symbols have been audited. There values are constant and do
     51 * not change if bzImage is loaded at a different physical address than
     52 * the address for which it has been compiled. Don't warn user about
     53 * absolute relocations present w.r.t these symbols.
     54 */
     55	[S_ABS] =
     56	"^(xen_irq_disable_direct_reloc$|"
     57	"xen_save_fl_direct_reloc$|"
     58	"VDSO|"
     59	"__crc_)",
     60
     61/*
     62 * These symbols are known to be relative, even if the linker marks them
     63 * as absolute (typically defined outside any section in the linker script.)
     64 */
     65	[S_REL] =
     66	"^(__init_(begin|end)|"
     67	"__x86_cpu_dev_(start|end)|"
     68	"(__parainstructions|__alt_instructions)(_end)?|"
     69	"(__iommu_table|__apicdrivers|__smp_locks)(_end)?|"
     70	"__(start|end)_pci_.*|"
     71#if CONFIG_FW_LOADER
     72	"__(start|end)_builtin_fw|"
     73#endif
     74	"__(start|stop)___ksymtab(_gpl)?|"
     75	"__(start|stop)___kcrctab(_gpl)?|"
     76	"__(start|stop)___param|"
     77	"__(start|stop)___modver|"
     78	"__(start|stop)___bug_table|"
     79	"__tracedata_(start|end)|"
     80	"__(start|stop)_notes|"
     81	"__end_rodata|"
     82	"__end_rodata_aligned|"
     83	"__initramfs_start|"
     84	"(jiffies|jiffies_64)|"
     85#if ELF_BITS == 64
     86	"__per_cpu_load|"
     87	"init_per_cpu__.*|"
     88	"__end_rodata_hpage_align|"
     89#endif
     90	"__vvar_page|"
     91	"_end)$"
     92};
     93
     94
     95static const char * const sym_regex_realmode[S_NSYMTYPES] = {
     96/*
     97 * These symbols are known to be relative, even if the linker marks them
     98 * as absolute (typically defined outside any section in the linker script.)
     99 */
    100	[S_REL] =
    101	"^pa_",
    102
    103/*
    104 * These are 16-bit segment symbols when compiling 16-bit code.
    105 */
    106	[S_SEG] =
    107	"^real_mode_seg$",
    108
    109/*
    110 * These are offsets belonging to segments, as opposed to linear addresses,
    111 * when compiling 16-bit code.
    112 */
    113	[S_LIN] =
    114	"^pa_",
    115};
    116
    117static const char * const *sym_regex;
    118
    119static regex_t sym_regex_c[S_NSYMTYPES];
    120static int is_reloc(enum symtype type, const char *sym_name)
    121{
    122	return sym_regex[type] &&
    123		!regexec(&sym_regex_c[type], sym_name, 0, NULL, 0);
    124}
    125
    126static void regex_init(int use_real_mode)
    127{
    128        char errbuf[128];
    129        int err;
    130	int i;
    131
    132	if (use_real_mode)
    133		sym_regex = sym_regex_realmode;
    134	else
    135		sym_regex = sym_regex_kernel;
    136
    137	for (i = 0; i < S_NSYMTYPES; i++) {
    138		if (!sym_regex[i])
    139			continue;
    140
    141		err = regcomp(&sym_regex_c[i], sym_regex[i],
    142			      REG_EXTENDED|REG_NOSUB);
    143
    144		if (err) {
    145			regerror(err, &sym_regex_c[i], errbuf, sizeof(errbuf));
    146			die("%s", errbuf);
    147		}
    148        }
    149}
    150
    151static const char *sym_type(unsigned type)
    152{
    153	static const char *type_name[] = {
    154#define SYM_TYPE(X) [X] = #X
    155		SYM_TYPE(STT_NOTYPE),
    156		SYM_TYPE(STT_OBJECT),
    157		SYM_TYPE(STT_FUNC),
    158		SYM_TYPE(STT_SECTION),
    159		SYM_TYPE(STT_FILE),
    160		SYM_TYPE(STT_COMMON),
    161		SYM_TYPE(STT_TLS),
    162#undef SYM_TYPE
    163	};
    164	const char *name = "unknown sym type name";
    165	if (type < ARRAY_SIZE(type_name)) {
    166		name = type_name[type];
    167	}
    168	return name;
    169}
    170
    171static const char *sym_bind(unsigned bind)
    172{
    173	static const char *bind_name[] = {
    174#define SYM_BIND(X) [X] = #X
    175		SYM_BIND(STB_LOCAL),
    176		SYM_BIND(STB_GLOBAL),
    177		SYM_BIND(STB_WEAK),
    178#undef SYM_BIND
    179	};
    180	const char *name = "unknown sym bind name";
    181	if (bind < ARRAY_SIZE(bind_name)) {
    182		name = bind_name[bind];
    183	}
    184	return name;
    185}
    186
    187static const char *sym_visibility(unsigned visibility)
    188{
    189	static const char *visibility_name[] = {
    190#define SYM_VISIBILITY(X) [X] = #X
    191		SYM_VISIBILITY(STV_DEFAULT),
    192		SYM_VISIBILITY(STV_INTERNAL),
    193		SYM_VISIBILITY(STV_HIDDEN),
    194		SYM_VISIBILITY(STV_PROTECTED),
    195#undef SYM_VISIBILITY
    196	};
    197	const char *name = "unknown sym visibility name";
    198	if (visibility < ARRAY_SIZE(visibility_name)) {
    199		name = visibility_name[visibility];
    200	}
    201	return name;
    202}
    203
    204static const char *rel_type(unsigned type)
    205{
    206	static const char *type_name[] = {
    207#define REL_TYPE(X) [X] = #X
    208#if ELF_BITS == 64
    209		REL_TYPE(R_X86_64_NONE),
    210		REL_TYPE(R_X86_64_64),
    211		REL_TYPE(R_X86_64_PC64),
    212		REL_TYPE(R_X86_64_PC32),
    213		REL_TYPE(R_X86_64_GOT32),
    214		REL_TYPE(R_X86_64_PLT32),
    215		REL_TYPE(R_X86_64_COPY),
    216		REL_TYPE(R_X86_64_GLOB_DAT),
    217		REL_TYPE(R_X86_64_JUMP_SLOT),
    218		REL_TYPE(R_X86_64_RELATIVE),
    219		REL_TYPE(R_X86_64_GOTPCREL),
    220		REL_TYPE(R_X86_64_32),
    221		REL_TYPE(R_X86_64_32S),
    222		REL_TYPE(R_X86_64_16),
    223		REL_TYPE(R_X86_64_PC16),
    224		REL_TYPE(R_X86_64_8),
    225		REL_TYPE(R_X86_64_PC8),
    226#else
    227		REL_TYPE(R_386_NONE),
    228		REL_TYPE(R_386_32),
    229		REL_TYPE(R_386_PC32),
    230		REL_TYPE(R_386_GOT32),
    231		REL_TYPE(R_386_PLT32),
    232		REL_TYPE(R_386_COPY),
    233		REL_TYPE(R_386_GLOB_DAT),
    234		REL_TYPE(R_386_JMP_SLOT),
    235		REL_TYPE(R_386_RELATIVE),
    236		REL_TYPE(R_386_GOTOFF),
    237		REL_TYPE(R_386_GOTPC),
    238		REL_TYPE(R_386_8),
    239		REL_TYPE(R_386_PC8),
    240		REL_TYPE(R_386_16),
    241		REL_TYPE(R_386_PC16),
    242#endif
    243#undef REL_TYPE
    244	};
    245	const char *name = "unknown type rel type name";
    246	if (type < ARRAY_SIZE(type_name) && type_name[type]) {
    247		name = type_name[type];
    248	}
    249	return name;
    250}
    251
    252static const char *sec_name(unsigned shndx)
    253{
    254	const char *sec_strtab;
    255	const char *name;
    256	sec_strtab = secs[shstrndx].strtab;
    257	name = "<noname>";
    258	if (shndx < shnum) {
    259		name = sec_strtab + secs[shndx].shdr.sh_name;
    260	}
    261	else if (shndx == SHN_ABS) {
    262		name = "ABSOLUTE";
    263	}
    264	else if (shndx == SHN_COMMON) {
    265		name = "COMMON";
    266	}
    267	return name;
    268}
    269
    270static const char *sym_name(const char *sym_strtab, Elf_Sym *sym)
    271{
    272	const char *name;
    273	name = "<noname>";
    274	if (sym->st_name) {
    275		name = sym_strtab + sym->st_name;
    276	}
    277	else {
    278		name = sec_name(sym_index(sym));
    279	}
    280	return name;
    281}
    282
    283static Elf_Sym *sym_lookup(const char *symname)
    284{
    285	int i;
    286	for (i = 0; i < shnum; i++) {
    287		struct section *sec = &secs[i];
    288		long nsyms;
    289		char *strtab;
    290		Elf_Sym *symtab;
    291		Elf_Sym *sym;
    292
    293		if (sec->shdr.sh_type != SHT_SYMTAB)
    294			continue;
    295
    296		nsyms = sec->shdr.sh_size/sizeof(Elf_Sym);
    297		symtab = sec->symtab;
    298		strtab = sec->link->strtab;
    299
    300		for (sym = symtab; --nsyms >= 0; sym++) {
    301			if (!sym->st_name)
    302				continue;
    303			if (strcmp(symname, strtab + sym->st_name) == 0)
    304				return sym;
    305		}
    306	}
    307	return 0;
    308}
    309
    310#if BYTE_ORDER == LITTLE_ENDIAN
    311#define le16_to_cpu(val) (val)
    312#define le32_to_cpu(val) (val)
    313#define le64_to_cpu(val) (val)
    314#endif
    315#if BYTE_ORDER == BIG_ENDIAN
    316#define le16_to_cpu(val) bswap_16(val)
    317#define le32_to_cpu(val) bswap_32(val)
    318#define le64_to_cpu(val) bswap_64(val)
    319#endif
    320
    321static uint16_t elf16_to_cpu(uint16_t val)
    322{
    323	return le16_to_cpu(val);
    324}
    325
    326static uint32_t elf32_to_cpu(uint32_t val)
    327{
    328	return le32_to_cpu(val);
    329}
    330
    331#define elf_half_to_cpu(x)	elf16_to_cpu(x)
    332#define elf_word_to_cpu(x)	elf32_to_cpu(x)
    333
    334#if ELF_BITS == 64
    335static uint64_t elf64_to_cpu(uint64_t val)
    336{
    337        return le64_to_cpu(val);
    338}
    339#define elf_addr_to_cpu(x)	elf64_to_cpu(x)
    340#define elf_off_to_cpu(x)	elf64_to_cpu(x)
    341#define elf_xword_to_cpu(x)	elf64_to_cpu(x)
    342#else
    343#define elf_addr_to_cpu(x)	elf32_to_cpu(x)
    344#define elf_off_to_cpu(x)	elf32_to_cpu(x)
    345#define elf_xword_to_cpu(x)	elf32_to_cpu(x)
    346#endif
    347
    348static int sym_index(Elf_Sym *sym)
    349{
    350	Elf_Sym *symtab = secs[shsymtabndx].symtab;
    351	Elf32_Word *xsymtab = secs[shxsymtabndx].xsymtab;
    352	unsigned long offset;
    353	int index;
    354
    355	if (sym->st_shndx != SHN_XINDEX)
    356		return sym->st_shndx;
    357
    358	/* calculate offset of sym from head of table. */
    359	offset = (unsigned long)sym - (unsigned long)symtab;
    360	index = offset / sizeof(*sym);
    361
    362	return elf32_to_cpu(xsymtab[index]);
    363}
    364
    365static void read_ehdr(FILE *fp)
    366{
    367	if (fread(&ehdr, sizeof(ehdr), 1, fp) != 1) {
    368		die("Cannot read ELF header: %s\n",
    369			strerror(errno));
    370	}
    371	if (memcmp(ehdr.e_ident, ELFMAG, SELFMAG) != 0) {
    372		die("No ELF magic\n");
    373	}
    374	if (ehdr.e_ident[EI_CLASS] != ELF_CLASS) {
    375		die("Not a %d bit executable\n", ELF_BITS);
    376	}
    377	if (ehdr.e_ident[EI_DATA] != ELFDATA2LSB) {
    378		die("Not a LSB ELF executable\n");
    379	}
    380	if (ehdr.e_ident[EI_VERSION] != EV_CURRENT) {
    381		die("Unknown ELF version\n");
    382	}
    383	/* Convert the fields to native endian */
    384	ehdr.e_type      = elf_half_to_cpu(ehdr.e_type);
    385	ehdr.e_machine   = elf_half_to_cpu(ehdr.e_machine);
    386	ehdr.e_version   = elf_word_to_cpu(ehdr.e_version);
    387	ehdr.e_entry     = elf_addr_to_cpu(ehdr.e_entry);
    388	ehdr.e_phoff     = elf_off_to_cpu(ehdr.e_phoff);
    389	ehdr.e_shoff     = elf_off_to_cpu(ehdr.e_shoff);
    390	ehdr.e_flags     = elf_word_to_cpu(ehdr.e_flags);
    391	ehdr.e_ehsize    = elf_half_to_cpu(ehdr.e_ehsize);
    392	ehdr.e_phentsize = elf_half_to_cpu(ehdr.e_phentsize);
    393	ehdr.e_phnum     = elf_half_to_cpu(ehdr.e_phnum);
    394	ehdr.e_shentsize = elf_half_to_cpu(ehdr.e_shentsize);
    395	ehdr.e_shnum     = elf_half_to_cpu(ehdr.e_shnum);
    396	ehdr.e_shstrndx  = elf_half_to_cpu(ehdr.e_shstrndx);
    397
    398	shnum = ehdr.e_shnum;
    399	shstrndx = ehdr.e_shstrndx;
    400
    401	if ((ehdr.e_type != ET_EXEC) && (ehdr.e_type != ET_DYN))
    402		die("Unsupported ELF header type\n");
    403	if (ehdr.e_machine != ELF_MACHINE)
    404		die("Not for %s\n", ELF_MACHINE_NAME);
    405	if (ehdr.e_version != EV_CURRENT)
    406		die("Unknown ELF version\n");
    407	if (ehdr.e_ehsize != sizeof(Elf_Ehdr))
    408		die("Bad Elf header size\n");
    409	if (ehdr.e_phentsize != sizeof(Elf_Phdr))
    410		die("Bad program header entry\n");
    411	if (ehdr.e_shentsize != sizeof(Elf_Shdr))
    412		die("Bad section header entry\n");
    413
    414
    415	if (shnum == SHN_UNDEF || shstrndx == SHN_XINDEX) {
    416		Elf_Shdr shdr;
    417
    418		if (fseek(fp, ehdr.e_shoff, SEEK_SET) < 0)
    419			die("Seek to %" FMT " failed: %s\n", ehdr.e_shoff, strerror(errno));
    420
    421		if (fread(&shdr, sizeof(shdr), 1, fp) != 1)
    422			die("Cannot read initial ELF section header: %s\n", strerror(errno));
    423
    424		if (shnum == SHN_UNDEF)
    425			shnum = elf_xword_to_cpu(shdr.sh_size);
    426
    427		if (shstrndx == SHN_XINDEX)
    428			shstrndx = elf_word_to_cpu(shdr.sh_link);
    429	}
    430
    431	if (shstrndx >= shnum)
    432		die("String table index out of bounds\n");
    433}
    434
    435static void read_shdrs(FILE *fp)
    436{
    437	int i;
    438	Elf_Shdr shdr;
    439
    440	secs = calloc(shnum, sizeof(struct section));
    441	if (!secs) {
    442		die("Unable to allocate %ld section headers\n",
    443		    shnum);
    444	}
    445	if (fseek(fp, ehdr.e_shoff, SEEK_SET) < 0) {
    446		die("Seek to %" FMT " failed: %s\n",
    447		    ehdr.e_shoff, strerror(errno));
    448	}
    449	for (i = 0; i < shnum; i++) {
    450		struct section *sec = &secs[i];
    451		if (fread(&shdr, sizeof(shdr), 1, fp) != 1)
    452			die("Cannot read ELF section headers %d/%ld: %s\n",
    453			    i, shnum, strerror(errno));
    454		sec->shdr.sh_name      = elf_word_to_cpu(shdr.sh_name);
    455		sec->shdr.sh_type      = elf_word_to_cpu(shdr.sh_type);
    456		sec->shdr.sh_flags     = elf_xword_to_cpu(shdr.sh_flags);
    457		sec->shdr.sh_addr      = elf_addr_to_cpu(shdr.sh_addr);
    458		sec->shdr.sh_offset    = elf_off_to_cpu(shdr.sh_offset);
    459		sec->shdr.sh_size      = elf_xword_to_cpu(shdr.sh_size);
    460		sec->shdr.sh_link      = elf_word_to_cpu(shdr.sh_link);
    461		sec->shdr.sh_info      = elf_word_to_cpu(shdr.sh_info);
    462		sec->shdr.sh_addralign = elf_xword_to_cpu(shdr.sh_addralign);
    463		sec->shdr.sh_entsize   = elf_xword_to_cpu(shdr.sh_entsize);
    464		if (sec->shdr.sh_link < shnum)
    465			sec->link = &secs[sec->shdr.sh_link];
    466	}
    467
    468}
    469
    470static void read_strtabs(FILE *fp)
    471{
    472	int i;
    473	for (i = 0; i < shnum; i++) {
    474		struct section *sec = &secs[i];
    475		if (sec->shdr.sh_type != SHT_STRTAB) {
    476			continue;
    477		}
    478		sec->strtab = malloc(sec->shdr.sh_size);
    479		if (!sec->strtab) {
    480			die("malloc of %" FMT " bytes for strtab failed\n",
    481			    sec->shdr.sh_size);
    482		}
    483		if (fseek(fp, sec->shdr.sh_offset, SEEK_SET) < 0) {
    484			die("Seek to %" FMT " failed: %s\n",
    485			    sec->shdr.sh_offset, strerror(errno));
    486		}
    487		if (fread(sec->strtab, 1, sec->shdr.sh_size, fp)
    488		    != sec->shdr.sh_size) {
    489			die("Cannot read symbol table: %s\n",
    490				strerror(errno));
    491		}
    492	}
    493}
    494
    495static void read_symtabs(FILE *fp)
    496{
    497	int i,j;
    498
    499	for (i = 0; i < shnum; i++) {
    500		struct section *sec = &secs[i];
    501		int num_syms;
    502
    503		switch (sec->shdr.sh_type) {
    504		case SHT_SYMTAB_SHNDX:
    505			sec->xsymtab = malloc(sec->shdr.sh_size);
    506			if (!sec->xsymtab) {
    507				die("malloc of %" FMT " bytes for xsymtab failed\n",
    508				    sec->shdr.sh_size);
    509			}
    510			if (fseek(fp, sec->shdr.sh_offset, SEEK_SET) < 0) {
    511				die("Seek to %" FMT " failed: %s\n",
    512				    sec->shdr.sh_offset, strerror(errno));
    513			}
    514			if (fread(sec->xsymtab, 1, sec->shdr.sh_size, fp)
    515			    != sec->shdr.sh_size) {
    516				die("Cannot read extended symbol table: %s\n",
    517				    strerror(errno));
    518			}
    519			shxsymtabndx = i;
    520			continue;
    521
    522		case SHT_SYMTAB:
    523			num_syms = sec->shdr.sh_size / sizeof(Elf_Sym);
    524
    525			sec->symtab = malloc(sec->shdr.sh_size);
    526			if (!sec->symtab) {
    527				die("malloc of %" FMT " bytes for symtab failed\n",
    528				    sec->shdr.sh_size);
    529			}
    530			if (fseek(fp, sec->shdr.sh_offset, SEEK_SET) < 0) {
    531				die("Seek to %" FMT " failed: %s\n",
    532				    sec->shdr.sh_offset, strerror(errno));
    533			}
    534			if (fread(sec->symtab, 1, sec->shdr.sh_size, fp)
    535			    != sec->shdr.sh_size) {
    536				die("Cannot read symbol table: %s\n",
    537				    strerror(errno));
    538			}
    539			for (j = 0; j < num_syms; j++) {
    540				Elf_Sym *sym = &sec->symtab[j];
    541
    542				sym->st_name  = elf_word_to_cpu(sym->st_name);
    543				sym->st_value = elf_addr_to_cpu(sym->st_value);
    544				sym->st_size  = elf_xword_to_cpu(sym->st_size);
    545				sym->st_shndx = elf_half_to_cpu(sym->st_shndx);
    546			}
    547			shsymtabndx = i;
    548			continue;
    549
    550		default:
    551			continue;
    552		}
    553	}
    554}
    555
    556
    557static void read_relocs(FILE *fp)
    558{
    559	int i,j;
    560	for (i = 0; i < shnum; i++) {
    561		struct section *sec = &secs[i];
    562		if (sec->shdr.sh_type != SHT_REL_TYPE) {
    563			continue;
    564		}
    565		sec->reltab = malloc(sec->shdr.sh_size);
    566		if (!sec->reltab) {
    567			die("malloc of %" FMT " bytes for relocs failed\n",
    568			    sec->shdr.sh_size);
    569		}
    570		if (fseek(fp, sec->shdr.sh_offset, SEEK_SET) < 0) {
    571			die("Seek to %" FMT " failed: %s\n",
    572			    sec->shdr.sh_offset, strerror(errno));
    573		}
    574		if (fread(sec->reltab, 1, sec->shdr.sh_size, fp)
    575		    != sec->shdr.sh_size) {
    576			die("Cannot read symbol table: %s\n",
    577				strerror(errno));
    578		}
    579		for (j = 0; j < sec->shdr.sh_size/sizeof(Elf_Rel); j++) {
    580			Elf_Rel *rel = &sec->reltab[j];
    581			rel->r_offset = elf_addr_to_cpu(rel->r_offset);
    582			rel->r_info   = elf_xword_to_cpu(rel->r_info);
    583#if (SHT_REL_TYPE == SHT_RELA)
    584			rel->r_addend = elf_xword_to_cpu(rel->r_addend);
    585#endif
    586		}
    587	}
    588}
    589
    590
    591static void print_absolute_symbols(void)
    592{
    593	int i;
    594	const char *format;
    595
    596	if (ELF_BITS == 64)
    597		format = "%5d %016"PRIx64" %5"PRId64" %10s %10s %12s %s\n";
    598	else
    599		format = "%5d %08"PRIx32"  %5"PRId32" %10s %10s %12s %s\n";
    600
    601	printf("Absolute symbols\n");
    602	printf(" Num:    Value Size  Type       Bind        Visibility  Name\n");
    603	for (i = 0; i < shnum; i++) {
    604		struct section *sec = &secs[i];
    605		char *sym_strtab;
    606		int j;
    607
    608		if (sec->shdr.sh_type != SHT_SYMTAB) {
    609			continue;
    610		}
    611		sym_strtab = sec->link->strtab;
    612		for (j = 0; j < sec->shdr.sh_size/sizeof(Elf_Sym); j++) {
    613			Elf_Sym *sym;
    614			const char *name;
    615			sym = &sec->symtab[j];
    616			name = sym_name(sym_strtab, sym);
    617			if (sym->st_shndx != SHN_ABS) {
    618				continue;
    619			}
    620			printf(format,
    621				j, sym->st_value, sym->st_size,
    622				sym_type(ELF_ST_TYPE(sym->st_info)),
    623				sym_bind(ELF_ST_BIND(sym->st_info)),
    624				sym_visibility(ELF_ST_VISIBILITY(sym->st_other)),
    625				name);
    626		}
    627	}
    628	printf("\n");
    629}
    630
    631static void print_absolute_relocs(void)
    632{
    633	int i, printed = 0;
    634	const char *format;
    635
    636	if (ELF_BITS == 64)
    637		format = "%016"PRIx64" %016"PRIx64" %10s %016"PRIx64"  %s\n";
    638	else
    639		format = "%08"PRIx32" %08"PRIx32" %10s %08"PRIx32"  %s\n";
    640
    641	for (i = 0; i < shnum; i++) {
    642		struct section *sec = &secs[i];
    643		struct section *sec_applies, *sec_symtab;
    644		char *sym_strtab;
    645		Elf_Sym *sh_symtab;
    646		int j;
    647		if (sec->shdr.sh_type != SHT_REL_TYPE) {
    648			continue;
    649		}
    650		sec_symtab  = sec->link;
    651		sec_applies = &secs[sec->shdr.sh_info];
    652		if (!(sec_applies->shdr.sh_flags & SHF_ALLOC)) {
    653			continue;
    654		}
    655		sh_symtab  = sec_symtab->symtab;
    656		sym_strtab = sec_symtab->link->strtab;
    657		for (j = 0; j < sec->shdr.sh_size/sizeof(Elf_Rel); j++) {
    658			Elf_Rel *rel;
    659			Elf_Sym *sym;
    660			const char *name;
    661			rel = &sec->reltab[j];
    662			sym = &sh_symtab[ELF_R_SYM(rel->r_info)];
    663			name = sym_name(sym_strtab, sym);
    664			if (sym->st_shndx != SHN_ABS) {
    665				continue;
    666			}
    667
    668			/* Absolute symbols are not relocated if bzImage is
    669			 * loaded at a non-compiled address. Display a warning
    670			 * to user at compile time about the absolute
    671			 * relocations present.
    672			 *
    673			 * User need to audit the code to make sure
    674			 * some symbols which should have been section
    675			 * relative have not become absolute because of some
    676			 * linker optimization or wrong programming usage.
    677			 *
    678			 * Before warning check if this absolute symbol
    679			 * relocation is harmless.
    680			 */
    681			if (is_reloc(S_ABS, name) || is_reloc(S_REL, name))
    682				continue;
    683
    684			if (!printed) {
    685				printf("WARNING: Absolute relocations"
    686					" present\n");
    687				printf("Offset     Info     Type     Sym.Value "
    688					"Sym.Name\n");
    689				printed = 1;
    690			}
    691
    692			printf(format,
    693				rel->r_offset,
    694				rel->r_info,
    695				rel_type(ELF_R_TYPE(rel->r_info)),
    696				sym->st_value,
    697				name);
    698		}
    699	}
    700
    701	if (printed)
    702		printf("\n");
    703}
    704
    705static void add_reloc(struct relocs *r, uint32_t offset)
    706{
    707	if (r->count == r->size) {
    708		unsigned long newsize = r->size + 50000;
    709		void *mem = realloc(r->offset, newsize * sizeof(r->offset[0]));
    710
    711		if (!mem)
    712			die("realloc of %ld entries for relocs failed\n",
    713                                newsize);
    714		r->offset = mem;
    715		r->size = newsize;
    716	}
    717	r->offset[r->count++] = offset;
    718}
    719
    720static void walk_relocs(int (*process)(struct section *sec, Elf_Rel *rel,
    721			Elf_Sym *sym, const char *symname))
    722{
    723	int i;
    724	/* Walk through the relocations */
    725	for (i = 0; i < shnum; i++) {
    726		char *sym_strtab;
    727		Elf_Sym *sh_symtab;
    728		struct section *sec_applies, *sec_symtab;
    729		int j;
    730		struct section *sec = &secs[i];
    731
    732		if (sec->shdr.sh_type != SHT_REL_TYPE) {
    733			continue;
    734		}
    735		sec_symtab  = sec->link;
    736		sec_applies = &secs[sec->shdr.sh_info];
    737		if (!(sec_applies->shdr.sh_flags & SHF_ALLOC)) {
    738			continue;
    739		}
    740		sh_symtab = sec_symtab->symtab;
    741		sym_strtab = sec_symtab->link->strtab;
    742		for (j = 0; j < sec->shdr.sh_size/sizeof(Elf_Rel); j++) {
    743			Elf_Rel *rel = &sec->reltab[j];
    744			Elf_Sym *sym = &sh_symtab[ELF_R_SYM(rel->r_info)];
    745			const char *symname = sym_name(sym_strtab, sym);
    746
    747			process(sec, rel, sym, symname);
    748		}
    749	}
    750}
    751
    752/*
    753 * The .data..percpu section is a special case for x86_64 SMP kernels.
    754 * It is used to initialize the actual per_cpu areas and to provide
    755 * definitions for the per_cpu variables that correspond to their offsets
    756 * within the percpu area. Since the values of all of the symbols need
    757 * to be offsets from the start of the per_cpu area the virtual address
    758 * (sh_addr) of .data..percpu is 0 in SMP kernels.
    759 *
    760 * This means that:
    761 *
    762 *	Relocations that reference symbols in the per_cpu area do not
    763 *	need further relocation (since the value is an offset relative
    764 *	to the start of the per_cpu area that does not change).
    765 *
    766 *	Relocations that apply to the per_cpu area need to have their
    767 *	offset adjusted by by the value of __per_cpu_load to make them
    768 *	point to the correct place in the loaded image (because the
    769 *	virtual address of .data..percpu is 0).
    770 *
    771 * For non SMP kernels .data..percpu is linked as part of the normal
    772 * kernel data and does not require special treatment.
    773 *
    774 */
    775static int per_cpu_shndx	= -1;
    776static Elf_Addr per_cpu_load_addr;
    777
    778static void percpu_init(void)
    779{
    780	int i;
    781	for (i = 0; i < shnum; i++) {
    782		ElfW(Sym) *sym;
    783		if (strcmp(sec_name(i), ".data..percpu"))
    784			continue;
    785
    786		if (secs[i].shdr.sh_addr != 0)	/* non SMP kernel */
    787			return;
    788
    789		sym = sym_lookup("__per_cpu_load");
    790		if (!sym)
    791			die("can't find __per_cpu_load\n");
    792
    793		per_cpu_shndx = i;
    794		per_cpu_load_addr = sym->st_value;
    795		return;
    796	}
    797}
    798
    799#if ELF_BITS == 64
    800
    801/*
    802 * Check to see if a symbol lies in the .data..percpu section.
    803 *
    804 * The linker incorrectly associates some symbols with the
    805 * .data..percpu section so we also need to check the symbol
    806 * name to make sure that we classify the symbol correctly.
    807 *
    808 * The GNU linker incorrectly associates:
    809 *	__init_begin
    810 *	__per_cpu_load
    811 *
    812 * The "gold" linker incorrectly associates:
    813 *	init_per_cpu__fixed_percpu_data
    814 *	init_per_cpu__gdt_page
    815 */
    816static int is_percpu_sym(ElfW(Sym) *sym, const char *symname)
    817{
    818	int shndx = sym_index(sym);
    819
    820	return (shndx == per_cpu_shndx) &&
    821		strcmp(symname, "__init_begin") &&
    822		strcmp(symname, "__per_cpu_load") &&
    823		strncmp(symname, "init_per_cpu_", 13);
    824}
    825
    826
    827static int do_reloc64(struct section *sec, Elf_Rel *rel, ElfW(Sym) *sym,
    828		      const char *symname)
    829{
    830	unsigned r_type = ELF64_R_TYPE(rel->r_info);
    831	ElfW(Addr) offset = rel->r_offset;
    832	int shn_abs = (sym->st_shndx == SHN_ABS) && !is_reloc(S_REL, symname);
    833
    834	if (sym->st_shndx == SHN_UNDEF)
    835		return 0;
    836
    837	/*
    838	 * Adjust the offset if this reloc applies to the percpu section.
    839	 */
    840	if (sec->shdr.sh_info == per_cpu_shndx)
    841		offset += per_cpu_load_addr;
    842
    843	switch (r_type) {
    844	case R_X86_64_NONE:
    845		/* NONE can be ignored. */
    846		break;
    847
    848	case R_X86_64_PC32:
    849	case R_X86_64_PLT32:
    850		/*
    851		 * PC relative relocations don't need to be adjusted unless
    852		 * referencing a percpu symbol.
    853		 *
    854		 * NB: R_X86_64_PLT32 can be treated as R_X86_64_PC32.
    855		 */
    856		if (is_percpu_sym(sym, symname))
    857			add_reloc(&relocs32neg, offset);
    858		break;
    859
    860	case R_X86_64_PC64:
    861		/*
    862		 * Only used by jump labels
    863		 */
    864		if (is_percpu_sym(sym, symname))
    865			die("Invalid R_X86_64_PC64 relocation against per-CPU symbol %s\n",
    866			    symname);
    867		break;
    868
    869	case R_X86_64_32:
    870	case R_X86_64_32S:
    871	case R_X86_64_64:
    872		/*
    873		 * References to the percpu area don't need to be adjusted.
    874		 */
    875		if (is_percpu_sym(sym, symname))
    876			break;
    877
    878		if (shn_abs) {
    879			/*
    880			 * Whitelisted absolute symbols do not require
    881			 * relocation.
    882			 */
    883			if (is_reloc(S_ABS, symname))
    884				break;
    885
    886			die("Invalid absolute %s relocation: %s\n",
    887			    rel_type(r_type), symname);
    888			break;
    889		}
    890
    891		/*
    892		 * Relocation offsets for 64 bit kernels are output
    893		 * as 32 bits and sign extended back to 64 bits when
    894		 * the relocations are processed.
    895		 * Make sure that the offset will fit.
    896		 */
    897		if ((int32_t)offset != (int64_t)offset)
    898			die("Relocation offset doesn't fit in 32 bits\n");
    899
    900		if (r_type == R_X86_64_64)
    901			add_reloc(&relocs64, offset);
    902		else
    903			add_reloc(&relocs32, offset);
    904		break;
    905
    906	default:
    907		die("Unsupported relocation type: %s (%d)\n",
    908		    rel_type(r_type), r_type);
    909		break;
    910	}
    911
    912	return 0;
    913}
    914
    915#else
    916
    917static int do_reloc32(struct section *sec, Elf_Rel *rel, Elf_Sym *sym,
    918		      const char *symname)
    919{
    920	unsigned r_type = ELF32_R_TYPE(rel->r_info);
    921	int shn_abs = (sym->st_shndx == SHN_ABS) && !is_reloc(S_REL, symname);
    922
    923	switch (r_type) {
    924	case R_386_NONE:
    925	case R_386_PC32:
    926	case R_386_PC16:
    927	case R_386_PC8:
    928	case R_386_PLT32:
    929		/*
    930		 * NONE can be ignored and PC relative relocations don't need
    931		 * to be adjusted. Because sym must be defined, R_386_PLT32 can
    932		 * be treated the same way as R_386_PC32.
    933		 */
    934		break;
    935
    936	case R_386_32:
    937		if (shn_abs) {
    938			/*
    939			 * Whitelisted absolute symbols do not require
    940			 * relocation.
    941			 */
    942			if (is_reloc(S_ABS, symname))
    943				break;
    944
    945			die("Invalid absolute %s relocation: %s\n",
    946			    rel_type(r_type), symname);
    947			break;
    948		}
    949
    950		add_reloc(&relocs32, rel->r_offset);
    951		break;
    952
    953	default:
    954		die("Unsupported relocation type: %s (%d)\n",
    955		    rel_type(r_type), r_type);
    956		break;
    957	}
    958
    959	return 0;
    960}
    961
    962static int do_reloc_real(struct section *sec, Elf_Rel *rel, Elf_Sym *sym,
    963			 const char *symname)
    964{
    965	unsigned r_type = ELF32_R_TYPE(rel->r_info);
    966	int shn_abs = (sym->st_shndx == SHN_ABS) && !is_reloc(S_REL, symname);
    967
    968	switch (r_type) {
    969	case R_386_NONE:
    970	case R_386_PC32:
    971	case R_386_PC16:
    972	case R_386_PC8:
    973	case R_386_PLT32:
    974		/*
    975		 * NONE can be ignored and PC relative relocations don't need
    976		 * to be adjusted. Because sym must be defined, R_386_PLT32 can
    977		 * be treated the same way as R_386_PC32.
    978		 */
    979		break;
    980
    981	case R_386_16:
    982		if (shn_abs) {
    983			/*
    984			 * Whitelisted absolute symbols do not require
    985			 * relocation.
    986			 */
    987			if (is_reloc(S_ABS, symname))
    988				break;
    989
    990			if (is_reloc(S_SEG, symname)) {
    991				add_reloc(&relocs16, rel->r_offset);
    992				break;
    993			}
    994		} else {
    995			if (!is_reloc(S_LIN, symname))
    996				break;
    997		}
    998		die("Invalid %s %s relocation: %s\n",
    999		    shn_abs ? "absolute" : "relative",
   1000		    rel_type(r_type), symname);
   1001		break;
   1002
   1003	case R_386_32:
   1004		if (shn_abs) {
   1005			/*
   1006			 * Whitelisted absolute symbols do not require
   1007			 * relocation.
   1008			 */
   1009			if (is_reloc(S_ABS, symname))
   1010				break;
   1011
   1012			if (is_reloc(S_REL, symname)) {
   1013				add_reloc(&relocs32, rel->r_offset);
   1014				break;
   1015			}
   1016		} else {
   1017			if (is_reloc(S_LIN, symname))
   1018				add_reloc(&relocs32, rel->r_offset);
   1019			break;
   1020		}
   1021		die("Invalid %s %s relocation: %s\n",
   1022		    shn_abs ? "absolute" : "relative",
   1023		    rel_type(r_type), symname);
   1024		break;
   1025
   1026	default:
   1027		die("Unsupported relocation type: %s (%d)\n",
   1028		    rel_type(r_type), r_type);
   1029		break;
   1030	}
   1031
   1032	return 0;
   1033}
   1034
   1035#endif
   1036
   1037static int cmp_relocs(const void *va, const void *vb)
   1038{
   1039	const uint32_t *a, *b;
   1040	a = va; b = vb;
   1041	return (*a == *b)? 0 : (*a > *b)? 1 : -1;
   1042}
   1043
   1044static void sort_relocs(struct relocs *r)
   1045{
   1046	qsort(r->offset, r->count, sizeof(r->offset[0]), cmp_relocs);
   1047}
   1048
   1049static int write32(uint32_t v, FILE *f)
   1050{
   1051	unsigned char buf[4];
   1052
   1053	put_unaligned_le32(v, buf);
   1054	return fwrite(buf, 1, 4, f) == 4 ? 0 : -1;
   1055}
   1056
   1057static int write32_as_text(uint32_t v, FILE *f)
   1058{
   1059	return fprintf(f, "\t.long 0x%08"PRIx32"\n", v) > 0 ? 0 : -1;
   1060}
   1061
   1062static void emit_relocs(int as_text, int use_real_mode)
   1063{
   1064	int i;
   1065	int (*write_reloc)(uint32_t, FILE *) = write32;
   1066	int (*do_reloc)(struct section *sec, Elf_Rel *rel, Elf_Sym *sym,
   1067			const char *symname);
   1068
   1069#if ELF_BITS == 64
   1070	if (!use_real_mode)
   1071		do_reloc = do_reloc64;
   1072	else
   1073		die("--realmode not valid for a 64-bit ELF file");
   1074#else
   1075	if (!use_real_mode)
   1076		do_reloc = do_reloc32;
   1077	else
   1078		do_reloc = do_reloc_real;
   1079#endif
   1080
   1081	/* Collect up the relocations */
   1082	walk_relocs(do_reloc);
   1083
   1084	if (relocs16.count && !use_real_mode)
   1085		die("Segment relocations found but --realmode not specified\n");
   1086
   1087	/* Order the relocations for more efficient processing */
   1088	sort_relocs(&relocs32);
   1089#if ELF_BITS == 64
   1090	sort_relocs(&relocs32neg);
   1091	sort_relocs(&relocs64);
   1092#else
   1093	sort_relocs(&relocs16);
   1094#endif
   1095
   1096	/* Print the relocations */
   1097	if (as_text) {
   1098		/* Print the relocations in a form suitable that
   1099		 * gas will like.
   1100		 */
   1101		printf(".section \".data.reloc\",\"a\"\n");
   1102		printf(".balign 4\n");
   1103		write_reloc = write32_as_text;
   1104	}
   1105
   1106	if (use_real_mode) {
   1107		write_reloc(relocs16.count, stdout);
   1108		for (i = 0; i < relocs16.count; i++)
   1109			write_reloc(relocs16.offset[i], stdout);
   1110
   1111		write_reloc(relocs32.count, stdout);
   1112		for (i = 0; i < relocs32.count; i++)
   1113			write_reloc(relocs32.offset[i], stdout);
   1114	} else {
   1115#if ELF_BITS == 64
   1116		/* Print a stop */
   1117		write_reloc(0, stdout);
   1118
   1119		/* Now print each relocation */
   1120		for (i = 0; i < relocs64.count; i++)
   1121			write_reloc(relocs64.offset[i], stdout);
   1122
   1123		/* Print a stop */
   1124		write_reloc(0, stdout);
   1125
   1126		/* Now print each inverse 32-bit relocation */
   1127		for (i = 0; i < relocs32neg.count; i++)
   1128			write_reloc(relocs32neg.offset[i], stdout);
   1129#endif
   1130
   1131		/* Print a stop */
   1132		write_reloc(0, stdout);
   1133
   1134		/* Now print each relocation */
   1135		for (i = 0; i < relocs32.count; i++)
   1136			write_reloc(relocs32.offset[i], stdout);
   1137	}
   1138}
   1139
   1140/*
   1141 * As an aid to debugging problems with different linkers
   1142 * print summary information about the relocs.
   1143 * Since different linkers tend to emit the sections in
   1144 * different orders we use the section names in the output.
   1145 */
   1146static int do_reloc_info(struct section *sec, Elf_Rel *rel, ElfW(Sym) *sym,
   1147				const char *symname)
   1148{
   1149	printf("%s\t%s\t%s\t%s\n",
   1150		sec_name(sec->shdr.sh_info),
   1151		rel_type(ELF_R_TYPE(rel->r_info)),
   1152		symname,
   1153		sec_name(sym_index(sym)));
   1154	return 0;
   1155}
   1156
   1157static void print_reloc_info(void)
   1158{
   1159	printf("reloc section\treloc type\tsymbol\tsymbol section\n");
   1160	walk_relocs(do_reloc_info);
   1161}
   1162
   1163#if ELF_BITS == 64
   1164# define process process_64
   1165#else
   1166# define process process_32
   1167#endif
   1168
   1169void process(FILE *fp, int use_real_mode, int as_text,
   1170	     int show_absolute_syms, int show_absolute_relocs,
   1171	     int show_reloc_info)
   1172{
   1173	regex_init(use_real_mode);
   1174	read_ehdr(fp);
   1175	read_shdrs(fp);
   1176	read_strtabs(fp);
   1177	read_symtabs(fp);
   1178	read_relocs(fp);
   1179	if (ELF_BITS == 64)
   1180		percpu_init();
   1181	if (show_absolute_syms) {
   1182		print_absolute_symbols();
   1183		return;
   1184	}
   1185	if (show_absolute_relocs) {
   1186		print_absolute_relocs();
   1187		return;
   1188	}
   1189	if (show_reloc_info) {
   1190		print_reloc_info();
   1191		return;
   1192	}
   1193	emit_relocs(as_text, use_real_mode);
   1194}