relocs.c 24.8 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
#if ELF_BITS == 64
46 47
	"__vvar_page|"
#endif
48
	"__crc_)",
49

50 51 52 53
/*
 * These symbols are known to be relative, even if the linker marks them
 * as absolute (typically defined outside any section in the linker script.)
 */
54
	[S_REL] =
55 56 57 58
	"^(__init_(begin|end)|"
	"__x86_cpu_dev_(start|end)|"
	"(__parainstructions|__alt_instructions)(|_end)|"
	"(__iommu_table|__apicdrivers|__smp_locks)(|_end)|"
59 60 61 62 63 64 65 66 67 68 69
	"__(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|"
70
	"(jiffies|jiffies_64)|"
71
#if ELF_BITS == 64
72 73 74 75
	"__per_cpu_load|"
	"init_per_cpu__.*|"
	"__end_rodata_hpage_align|"
#endif
76
	"_end)$"
77 78 79 80
};


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

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

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

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

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

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

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

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

267 268 269 270 271 272 273 274 275
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;
276

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

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

315 316
#define elf_half_to_cpu(x)	elf16_to_cpu(x)
#define elf_word_to_cpu(x)	elf32_to_cpu(x)
317

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

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

	if ((ehdr.e_type != ET_EXEC) && (ehdr.e_type != ET_DYN)) {
		die("Unsupported ELF header type\n");
	}
368 369
	if (ehdr.e_machine != ELF_MACHINE) {
		die("Not for %s\n", ELF_MACHINE_NAME);
370 371 372 373
	}
	if (ehdr.e_version != EV_CURRENT) {
		die("Unknown ELF version\n");
	}
374
	if (ehdr.e_ehsize != sizeof(Elf_Ehdr)) {
375 376
		die("Bad Elf header size\n");
	}
377
	if (ehdr.e_phentsize != sizeof(Elf_Phdr)) {
378 379
		die("Bad program header entry\n");
	}
380
	if (ehdr.e_shentsize != sizeof(Elf_Shdr)) {
381 382 383 384 385 386 387 388 389 390
		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;
391
	Elf_Shdr shdr;
392 393 394 395 396

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

}

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

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


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


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

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

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

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

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

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

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

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

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

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

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

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

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

671 672 673 674 675
			process(sec, rel, sym, symname);
		}
	}
}

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

723 724
#if ELF_BITS == 64

725 726 727 728 729 730 731 732 733 734 735 736 737
/*
 * Check to see if a symbol lies in the .data..percpu section.
 * For some as yet not understood reason the "__init_begin"
 * symbol which immediately preceeds the .data..percpu section
 * also shows up as it it were part of it so we do an explict
 * check for that symbol name and ignore it.
 */
static int is_percpu_sym(ElfW(Sym) *sym, const char *symname)
{
	return (sym->st_shndx == per_cpu_shndx) &&
		strcmp(symname, "__init_begin");
}

738

739 740 741 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
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;
}

810
#else
811 812 813

static int do_reloc32(struct section *sec, Elf_Rel *rel, Elf_Sym *sym,
		      const char *symname)
814 815 816 817 818 819 820 821 822 823 824 825 826 827 828 829 830 831 832 833 834 835
{
	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))
836
				break;
837

838 839 840 841 842 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
			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))
879 880
				break;

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

917 918 919 920 921
	default:
		die("Unsupported relocation type: %s (%d)\n",
		    rel_type(r_type), r_type);
		break;
	}
922

923
	return 0;
924 925
}

926 927
#endif

928 929
static int cmp_relocs(const void *va, const void *vb)
{
930
	const uint32_t *a, *b;
931 932 933 934
	a = va; b = vb;
	return (*a == *b)? 0 : (*a > *b)? 1 : -1;
}

935 936 937 938 939 940
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)
941 942 943 944 945 946 947
{
	unsigned char buf[4];

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

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

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

960 961
#if ELF_BITS == 64
	if (!use_real_mode)
962
		do_reloc = do_reloc64;
963 964 965 966
	else
		die("--realmode not valid for a 64-bit ELF file");
#else
	if (!use_real_mode)
967 968 969
		do_reloc = do_reloc32;
	else
		do_reloc = do_reloc_real;
970
#endif
971

972
	/* Collect up the relocations */
973
	walk_relocs(do_reloc);
974

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

	/* Order the relocations for more efficient processing */
979 980
	sort_relocs(&relocs16);
	sort_relocs(&relocs32);
981
	sort_relocs(&relocs64);
982 983 984 985 986 987 988 989

	/* 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");
990
		write_reloc = write32_as_text;
991
	}
992

993 994 995 996 997 998 999 1000 1001
	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 {
1002
		if (ELF_BITS == 64) {
1003 1004 1005 1006 1007 1008 1009 1010
			/* Print a stop */
			write_reloc(0, stdout);

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

1011 1012 1013 1014 1015 1016
		/* Print a stop */
		write_reloc(0, stdout);

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

1020 1021 1022 1023 1024
#if ELF_BITS == 64
# define process process_64
#else
# define process process_32
#endif
1025

1026 1027
void process(FILE *fp, int use_real_mode, int as_text,
	     int show_absolute_syms, int show_absolute_relocs)
1028
{
1029
	regex_init(use_real_mode);
1030 1031 1032 1033 1034
	read_ehdr(fp);
	read_shdrs(fp);
	read_strtabs(fp);
	read_symtabs(fp);
	read_relocs(fp);
1035
	if (ELF_BITS == 64)
1036
		percpu_init();
1037
	if (show_absolute_syms) {
1038
		print_absolute_symbols();
1039
		return;
1040 1041
	}
	if (show_absolute_relocs) {
1042
		print_absolute_relocs();
1043
		return;
1044
	}
1045
	emit_relocs(as_text, use_real_mode);
1046
}