relocs.c 24.9 KB
Newer Older
1
/* This is included from relocs_32/64.c */
2

3 4 5 6
#define ElfW(type)		_ElfW(ELF_BITS, type)
#define _ElfW(bits, type)	__ElfW(bits, type)
#define __ElfW(bits, type)	Elf##bits##_##type

7
#define Elf_Addr		ElfW(Addr)
8 9 10 11 12 13
#define Elf_Ehdr		ElfW(Ehdr)
#define Elf_Phdr		ElfW(Phdr)
#define Elf_Shdr		ElfW(Shdr)
#define Elf_Sym			ElfW(Sym)

static Elf_Ehdr ehdr;
14 15 16 17 18 19 20 21 22

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

static struct relocs relocs16;
static struct relocs relocs32;
23
static struct relocs relocs64;
24

25
struct section {
26
	Elf_Shdr       shdr;
27
	struct section *link;
28 29
	Elf_Sym        *symtab;
	Elf_Rel        *reltab;
30 31 32 33
	char           *strtab;
};
static struct section *secs;

34
static const char * const sym_regex_kernel[S_NSYMTYPES] = {
35 36 37 38 39 40
/*
 * 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.
 */
41
	[S_ABS] =
42 43 44
	"^(xen_irq_disable_direct_reloc$|"
	"xen_save_fl_direct_reloc$|"
	"VDSO|"
45
	"__crc_)",
46

47 48 49 50
/*
 * These symbols are known to be relative, even if the linker marks them
 * as absolute (typically defined outside any section in the linker script.)
 */
51
	[S_REL] =
52 53 54 55
	"^(__init_(begin|end)|"
	"__x86_cpu_dev_(start|end)|"
	"(__parainstructions|__alt_instructions)(|_end)|"
	"(__iommu_table|__apicdrivers|__smp_locks)(|_end)|"
56 57 58 59 60 61 62 63 64 65 66
	"__(start|end)_pci_.*|"
	"__(start|end)_builtin_fw|"
	"__(start|stop)___ksymtab(|_gpl|_unused|_unused_gpl|_gpl_future)|"
	"__(start|stop)___kcrctab(|_gpl|_unused|_unused_gpl|_gpl_future)|"
	"__(start|stop)___param|"
	"__(start|stop)___modver|"
	"__(start|stop)___bug_table|"
	"__tracedata_(start|end)|"
	"__(start|stop)_notes|"
	"__end_rodata|"
	"__initramfs_start|"
67
	"(jiffies|jiffies_64)|"
68
#if ELF_BITS == 64
69 70 71
	"__per_cpu_load|"
	"init_per_cpu__.*|"
	"__end_rodata_hpage_align|"
72
	"__vvar_page|"
73
#endif
74
	"_end)$"
75 76 77 78
};


static const char * const sym_regex_realmode[S_NSYMTYPES] = {
79 80 81 82 83 84 85
/*
 * 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_",

86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103
/*
 * 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)
104
{
105 106
	return sym_regex[type] &&
		!regexec(&sym_regex_c[type], sym_name, 0, NULL, 0);
107
}
108

109
static void regex_init(int use_real_mode)
110 111 112
{
        char errbuf[128];
        int err;
113
	int i;
114

115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130
	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);
		}
131
        }
132 133
}

134 135 136 137 138 139 140 141 142 143 144 145 146 147
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";
148
	if (type < ARRAY_SIZE(type_name)) {
149 150 151 152 153 154 155 156 157 158 159 160 161 162 163
		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";
164
	if (bind < ARRAY_SIZE(bind_name)) {
165 166 167 168 169 170 171 172 173 174 175 176 177 178 179 180
		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";
181
	if (visibility < ARRAY_SIZE(visibility_name)) {
182 183 184 185 186 187 188 189 190
		name = visibility_name[visibility];
	}
	return name;
}

static const char *rel_type(unsigned type)
{
	static const char *type_name[] = {
#define REL_TYPE(X) [X] = #X
191
#if ELF_BITS == 64
192 193 194 195 196 197 198 199 200 201 202 203 204 205 206 207 208
		REL_TYPE(R_X86_64_NONE),
		REL_TYPE(R_X86_64_64),
		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
209 210 211 212 213 214 215 216 217 218 219
		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),
220 221 222 223
		REL_TYPE(R_386_8),
		REL_TYPE(R_386_PC8),
		REL_TYPE(R_386_16),
		REL_TYPE(R_386_PC16),
224
#endif
225 226 227
#undef REL_TYPE
	};
	const char *name = "unknown type rel type name";
228
	if (type < ARRAY_SIZE(type_name) && type_name[type]) {
229 230 231 232 233 234 235 236 237
		name = type_name[type];
	}
	return name;
}

static const char *sec_name(unsigned shndx)
{
	const char *sec_strtab;
	const char *name;
238
	sec_strtab = secs[ehdr.e_shstrndx].strtab;
239 240
	name = "<noname>";
	if (shndx < ehdr.e_shnum) {
241
		name = sec_strtab + secs[shndx].shdr.sh_name;
242 243 244 245 246 247 248 249 250 251
	}
	else if (shndx == SHN_ABS) {
		name = "ABSOLUTE";
	}
	else if (shndx == SHN_COMMON) {
		name = "COMMON";
	}
	return name;
}

252
static const char *sym_name(const char *sym_strtab, Elf_Sym *sym)
253 254 255 256 257 258 259
{
	const char *name;
	name = "<noname>";
	if (sym->st_name) {
		name = sym_strtab + sym->st_name;
	}
	else {
260
		name = sec_name(sym->st_shndx);
261 262 263 264
	}
	return name;
}

265 266 267 268 269 270 271 272 273
static Elf_Sym *sym_lookup(const char *symname)
{
	int i;
	for (i = 0; i < ehdr.e_shnum; i++) {
		struct section *sec = &secs[i];
		long nsyms;
		char *strtab;
		Elf_Sym *symtab;
		Elf_Sym *sym;
274

275 276 277 278 279 280 281 282 283 284 285 286 287 288 289 290
		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;
}
291

292
#if BYTE_ORDER == LITTLE_ENDIAN
293 294
#define le16_to_cpu(val) (val)
#define le32_to_cpu(val) (val)
295
#define le64_to_cpu(val) (val)
296
#endif
297
#if BYTE_ORDER == BIG_ENDIAN
298 299
#define le16_to_cpu(val) bswap_16(val)
#define le32_to_cpu(val) bswap_32(val)
300
#define le64_to_cpu(val) bswap_64(val)
301 302 303 304 305 306 307 308 309 310 311 312
#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);
}

313 314
#define elf_half_to_cpu(x)	elf16_to_cpu(x)
#define elf_word_to_cpu(x)	elf32_to_cpu(x)
315

316
#if ELF_BITS == 64
317 318 319 320 321 322 323 324
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
325 326 327
#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)
328
#endif
329

330 331 332 333 334 335
static void read_ehdr(FILE *fp)
{
	if (fread(&ehdr, sizeof(ehdr), 1, fp) != 1) {
		die("Cannot read ELF header: %s\n",
			strerror(errno));
	}
336
	if (memcmp(ehdr.e_ident, ELFMAG, SELFMAG) != 0) {
337 338
		die("No ELF magic\n");
	}
339 340
	if (ehdr.e_ident[EI_CLASS] != ELF_CLASS) {
		die("Not a %d bit executable\n", ELF_BITS);
341 342 343 344 345 346 347 348
	}
	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 */
349 350 351 352 353 354 355 356 357 358 359 360 361
	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);
362 363 364 365

	if ((ehdr.e_type != ET_EXEC) && (ehdr.e_type != ET_DYN)) {
		die("Unsupported ELF header type\n");
	}
366 367
	if (ehdr.e_machine != ELF_MACHINE) {
		die("Not for %s\n", ELF_MACHINE_NAME);
368 369 370 371
	}
	if (ehdr.e_version != EV_CURRENT) {
		die("Unknown ELF version\n");
	}
372
	if (ehdr.e_ehsize != sizeof(Elf_Ehdr)) {
373 374
		die("Bad Elf header size\n");
	}
375
	if (ehdr.e_phentsize != sizeof(Elf_Phdr)) {
376 377
		die("Bad program header entry\n");
	}
378
	if (ehdr.e_shentsize != sizeof(Elf_Shdr)) {
379 380 381 382 383 384 385 386 387 388
		die("Bad section header entry\n");
	}
	if (ehdr.e_shstrndx >= ehdr.e_shnum) {
		die("String table index out of bounds\n");
	}
}

static void read_shdrs(FILE *fp)
{
	int i;
389
	Elf_Shdr shdr;
390 391 392 393 394

	secs = calloc(ehdr.e_shnum, sizeof(struct section));
	if (!secs) {
		die("Unable to allocate %d section headers\n",
		    ehdr.e_shnum);
395 396 397 398 399
	}
	if (fseek(fp, ehdr.e_shoff, SEEK_SET) < 0) {
		die("Seek to %d failed: %s\n",
			ehdr.e_shoff, strerror(errno));
	}
400 401 402 403 404
	for (i = 0; i < ehdr.e_shnum; i++) {
		struct section *sec = &secs[i];
		if (fread(&shdr, sizeof shdr, 1, fp) != 1)
			die("Cannot read ELF section headers %d/%d: %s\n",
			    i, ehdr.e_shnum, strerror(errno));
405 406 407 408 409 410 411 412 413 414
		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);
415 416
		if (sec->shdr.sh_link < ehdr.e_shnum)
			sec->link = &secs[sec->shdr.sh_link];
417 418 419 420 421 422 423
	}

}

static void read_strtabs(FILE *fp)
{
	int i;
424 425 426
	for (i = 0; i < ehdr.e_shnum; i++) {
		struct section *sec = &secs[i];
		if (sec->shdr.sh_type != SHT_STRTAB) {
427 428
			continue;
		}
429 430
		sec->strtab = malloc(sec->shdr.sh_size);
		if (!sec->strtab) {
431
			die("malloc of %d bytes for strtab failed\n",
432
				sec->shdr.sh_size);
433
		}
434
		if (fseek(fp, sec->shdr.sh_offset, SEEK_SET) < 0) {
435
			die("Seek to %d failed: %s\n",
436
				sec->shdr.sh_offset, strerror(errno));
437
		}
438 439
		if (fread(sec->strtab, 1, sec->shdr.sh_size, fp)
		    != sec->shdr.sh_size) {
440 441 442 443 444 445 446 447 448
			die("Cannot read symbol table: %s\n",
				strerror(errno));
		}
	}
}

static void read_symtabs(FILE *fp)
{
	int i,j;
449 450 451
	for (i = 0; i < ehdr.e_shnum; i++) {
		struct section *sec = &secs[i];
		if (sec->shdr.sh_type != SHT_SYMTAB) {
452 453
			continue;
		}
454 455
		sec->symtab = malloc(sec->shdr.sh_size);
		if (!sec->symtab) {
456
			die("malloc of %d bytes for symtab failed\n",
457
				sec->shdr.sh_size);
458
		}
459
		if (fseek(fp, sec->shdr.sh_offset, SEEK_SET) < 0) {
460
			die("Seek to %d failed: %s\n",
461
				sec->shdr.sh_offset, strerror(errno));
462
		}
463 464
		if (fread(sec->symtab, 1, sec->shdr.sh_size, fp)
		    != sec->shdr.sh_size) {
465 466 467
			die("Cannot read symbol table: %s\n",
				strerror(errno));
		}
468 469 470 471 472 473
		for (j = 0; j < sec->shdr.sh_size/sizeof(Elf_Sym); 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);
474 475 476 477 478 479 480 481
		}
	}
}


static void read_relocs(FILE *fp)
{
	int i,j;
482 483
	for (i = 0; i < ehdr.e_shnum; i++) {
		struct section *sec = &secs[i];
484
		if (sec->shdr.sh_type != SHT_REL_TYPE) {
485 486
			continue;
		}
487 488
		sec->reltab = malloc(sec->shdr.sh_size);
		if (!sec->reltab) {
489
			die("malloc of %d bytes for relocs failed\n",
490
				sec->shdr.sh_size);
491
		}
492
		if (fseek(fp, sec->shdr.sh_offset, SEEK_SET) < 0) {
493
			die("Seek to %d failed: %s\n",
494
				sec->shdr.sh_offset, strerror(errno));
495
		}
496 497
		if (fread(sec->reltab, 1, sec->shdr.sh_size, fp)
		    != sec->shdr.sh_size) {
498 499 500
			die("Cannot read symbol table: %s\n",
				strerror(errno));
		}
501 502 503 504
		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);
505 506 507
#if (SHT_REL_TYPE == SHT_RELA)
			rel->r_addend = elf_xword_to_cpu(rel->r_addend);
#endif
508 509 510 511 512 513 514 515
		}
	}
}


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

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

523 524
	printf("Absolute symbols\n");
	printf(" Num:    Value Size  Type       Bind        Visibility  Name\n");
525 526
	for (i = 0; i < ehdr.e_shnum; i++) {
		struct section *sec = &secs[i];
527 528
		char *sym_strtab;
		int j;
529 530

		if (sec->shdr.sh_type != SHT_SYMTAB) {
531 532
			continue;
		}
533
		sym_strtab = sec->link->strtab;
534 535
		for (j = 0; j < sec->shdr.sh_size/sizeof(Elf_Sym); j++) {
			Elf_Sym *sym;
536
			const char *name;
537
			sym = &sec->symtab[j];
538 539 540 541
			name = sym_name(sym_strtab, sym);
			if (sym->st_shndx != SHN_ABS) {
				continue;
			}
542
			printf(format,
543
				j, sym->st_value, sym->st_size,
544 545 546
				sym_type(ELF_ST_TYPE(sym->st_info)),
				sym_bind(ELF_ST_BIND(sym->st_info)),
				sym_visibility(ELF_ST_VISIBILITY(sym->st_other)),
547 548 549 550 551 552 553 554
				name);
		}
	}
	printf("\n");
}

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

558
	if (ELF_BITS == 64)
559 560 561
		format = "%016"PRIx64" %016"PRIx64" %10s %016"PRIx64"  %s\n";
	else
		format = "%08"PRIx32" %08"PRIx32" %10s %08"PRIx32"  %s\n";
562

563 564 565
	for (i = 0; i < ehdr.e_shnum; i++) {
		struct section *sec = &secs[i];
		struct section *sec_applies, *sec_symtab;
566
		char *sym_strtab;
567
		Elf_Sym *sh_symtab;
568
		int j;
569
		if (sec->shdr.sh_type != SHT_REL_TYPE) {
570 571
			continue;
		}
572 573 574
		sec_symtab  = sec->link;
		sec_applies = &secs[sec->shdr.sh_info];
		if (!(sec_applies->shdr.sh_flags & SHF_ALLOC)) {
575 576
			continue;
		}
577 578
		sh_symtab  = sec_symtab->symtab;
		sym_strtab = sec_symtab->link->strtab;
579 580 581
		for (j = 0; j < sec->shdr.sh_size/sizeof(Elf_Rel); j++) {
			Elf_Rel *rel;
			Elf_Sym *sym;
582
			const char *name;
583
			rel = &sec->reltab[j];
584
			sym = &sh_symtab[ELF_R_SYM(rel->r_info)];
585 586 587 588
			name = sym_name(sym_strtab, sym);
			if (sym->st_shndx != SHN_ABS) {
				continue;
			}
589 590 591 592 593 594 595 596 597 598 599 600 601 602

			/* 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.
			 */
603
			if (is_reloc(S_ABS, name) || is_reloc(S_REL, name))
604 605 606 607 608 609 610 611 612 613
				continue;

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

614
			printf(format,
615 616
				rel->r_offset,
				rel->r_info,
617
				rel_type(ELF_R_TYPE(rel->r_info)),
618 619 620 621
				sym->st_value,
				name);
		}
	}
622 623 624

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

627 628 629 630 631 632 633 634 635 636 637 638 639 640 641 642 643
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))
644 645 646
{
	int i;
	/* Walk through the relocations */
647
	for (i = 0; i < ehdr.e_shnum; i++) {
648
		char *sym_strtab;
649
		Elf_Sym *sh_symtab;
650
		struct section *sec_applies, *sec_symtab;
651
		int j;
652 653
		struct section *sec = &secs[i];

654
		if (sec->shdr.sh_type != SHT_REL_TYPE) {
655 656
			continue;
		}
657 658 659
		sec_symtab  = sec->link;
		sec_applies = &secs[sec->shdr.sh_info];
		if (!(sec_applies->shdr.sh_flags & SHF_ALLOC)) {
660 661
			continue;
		}
662
		sh_symtab = sec_symtab->symtab;
663
		sym_strtab = sec_symtab->link->strtab;
664
		for (j = 0; j < sec->shdr.sh_size/sizeof(Elf_Rel); j++) {
665 666 667
			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);
668

669 670 671 672 673
			process(sec, rel, sym, symname);
		}
	}
}

674 675 676 677 678 679 680 681 682 683 684 685 686 687 688 689 690 691 692 693 694 695 696 697 698 699 700 701 702 703 704 705 706 707 708 709 710 711 712 713 714 715 716 717 718 719 720
/*
 * 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;
Elf_Addr per_cpu_load_addr;

static void percpu_init(void)
{
	int i;
	for (i = 0; i < ehdr.e_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;
	}
}

721 722
#if ELF_BITS == 64

723 724
/*
 * Check to see if a symbol lies in the .data..percpu section.
725 726 727 728 729 730 731 732 733 734 735
 *
 * 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
 *
 * The "gold" linker incorrectly associates:
 *	init_per_cpu__irq_stack_union
 *	init_per_cpu__gdt_page
736 737 738 739
 */
static int is_percpu_sym(ElfW(Sym) *sym, const char *symname)
{
	return (sym->st_shndx == per_cpu_shndx) &&
740 741
		strcmp(symname, "__init_begin") &&
		strncmp(symname, "init_per_cpu_", 13);
742 743
}

744

745 746 747 748 749 750 751 752 753 754 755 756 757 758 759 760 761 762 763 764 765 766 767 768 769 770 771 772 773 774 775 776 777 778 779 780 781 782 783 784 785 786 787 788 789 790 791 792 793 794 795 796 797 798 799 800 801 802 803 804 805 806 807 808 809 810 811 812 813 814 815
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:
	case R_X86_64_PC32:
		/*
		 * NONE can be ignored and PC relative relocations don't
		 * need to be adjusted.
		 */
		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;
}

816
#else
817 818 819

static int do_reloc32(struct section *sec, Elf_Rel *rel, Elf_Sym *sym,
		      const char *symname)
820 821 822 823 824 825 826 827 828 829 830 831 832 833 834 835 836 837 838 839 840 841
{
	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:
		/*
		 * NONE can be ignored and PC relative relocations don't
		 * need to be adjusted.
		 */
		break;

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

844 845 846 847 848 849 850 851 852 853 854 855 856 857 858 859 860 861 862 863 864 865 866 867 868 869 870 871 872 873 874 875 876 877 878 879 880 881 882 883 884
			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:
		/*
		 * NONE can be ignored and PC relative relocations don't
		 * need to be adjusted.
		 */
		break;

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

887 888 889 890 891 892
			if (is_reloc(S_SEG, symname)) {
				add_reloc(&relocs16, rel->r_offset);
				break;
			}
		} else {
			if (!is_reloc(S_LIN, symname))
893
				break;
894 895 896 897 898 899 900 901 902 903 904 905 906 907 908 909 910
		}
		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);
911
				break;
912
			}
913 914 915 916
		} else {
			if (is_reloc(S_LIN, symname))
				add_reloc(&relocs32, rel->r_offset);
			break;
917
		}
918 919 920 921
		die("Invalid %s %s relocation: %s\n",
		    shn_abs ? "absolute" : "relative",
		    rel_type(r_type), symname);
		break;
922

923 924 925 926 927
	default:
		die("Unsupported relocation type: %s (%d)\n",
		    rel_type(r_type), r_type);
		break;
	}
928

929
	return 0;
930 931
}

932 933
#endif

934 935
static int cmp_relocs(const void *va, const void *vb)
{
936
	const uint32_t *a, *b;
937 938 939 940
	a = va; b = vb;
	return (*a == *b)? 0 : (*a > *b)? 1 : -1;
}

941 942 943 944 945 946
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)
947 948 949 950 951 952 953
{
	unsigned char buf[4];

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

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

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

966 967
#if ELF_BITS == 64
	if (!use_real_mode)
968
		do_reloc = do_reloc64;
969 970 971 972
	else
		die("--realmode not valid for a 64-bit ELF file");
#else
	if (!use_real_mode)
973 974 975
		do_reloc = do_reloc32;
	else
		do_reloc = do_reloc_real;
976
#endif
977

978
	/* Collect up the relocations */
979
	walk_relocs(do_reloc);
980

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

	/* Order the relocations for more efficient processing */
985 986
	sort_relocs(&relocs16);
	sort_relocs(&relocs32);
987
	sort_relocs(&relocs64);
988 989 990 991 992 993 994 995

	/* 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");
996
		write_reloc = write32_as_text;
997
	}
998

999 1000 1001 1002 1003 1004 1005 1006 1007
	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 {
1008
		if (ELF_BITS == 64) {
1009 1010 1011 1012 1013 1014 1015 1016
			/* Print a stop */
			write_reloc(0, stdout);

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

1017 1018 1019 1020 1021 1022
		/* Print a stop */
		write_reloc(0, stdout);

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

1026 1027 1028 1029 1030
#if ELF_BITS == 64
# define process process_64
#else
# define process process_32
#endif
1031

1032 1033
void process(FILE *fp, int use_real_mode, int as_text,
	     int show_absolute_syms, int show_absolute_relocs)
1034
{
1035
	regex_init(use_real_mode);
1036 1037 1038 1039 1040
	read_ehdr(fp);
	read_shdrs(fp);
	read_strtabs(fp);
	read_symtabs(fp);
	read_relocs(fp);
1041
	if (ELF_BITS == 64)
1042
		percpu_init();
1043
	if (show_absolute_syms) {
1044
		print_absolute_symbols();
1045
		return;
1046 1047
	}
	if (show_absolute_relocs) {
1048
		print_absolute_relocs();
1049
		return;
1050
	}
1051
	emit_relocs(as_text, use_real_mode);
1052
}