File Index
Files and directories
Sign in
FILE

relocs.c

File preview with syntax highlighting.

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