⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 relocs.c

📁 linux 内核源代码
💻 C
📖 第 1 页 / 共 2 页
字号:
#include <stdio.h>#include <stdarg.h>#include <stdlib.h>#include <stdint.h>#include <string.h>#include <errno.h>#include <unistd.h>#include <elf.h>#include <byteswap.h>#define USE_BSD#include <endian.h>#define MAX_SHDRS 100#define ARRAY_SIZE(x) (sizeof(x) / sizeof((x)[0]))static Elf32_Ehdr ehdr;static Elf32_Shdr shdr[MAX_SHDRS];static Elf32_Sym  *symtab[MAX_SHDRS];static Elf32_Rel  *reltab[MAX_SHDRS];static char *strtab[MAX_SHDRS];static unsigned long reloc_count, reloc_idx;static unsigned long *relocs;/* * 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. */static const char* safe_abs_relocs[] = {		"__kernel_vsyscall",		"__kernel_rt_sigreturn",		"__kernel_sigreturn",		"SYSENTER_RETURN",		"VDSO_NOTE_MASK",		"xen_irq_disable_direct_reloc",		"xen_save_fl_direct_reloc",};static int is_safe_abs_reloc(const char* sym_name){	int i;	for(i = 0; i < ARRAY_SIZE(safe_abs_relocs); i++) {		if (!strcmp(sym_name, safe_abs_relocs[i]))			/* Match found */			return 1;	}	if (strncmp(sym_name, "__crc_", 6) == 0)		return 1;	return 0;}static void die(char *fmt, ...){	va_list ap;	va_start(ap, fmt);	vfprintf(stderr, fmt, ap);	va_end(ap);	exit(1);}static const char *sym_type(unsigned type){	static const char *type_name[] = {#define SYM_TYPE(X) [X] = #X		SYM_TYPE(STT_NOTYPE),		SYM_TYPE(STT_OBJECT),		SYM_TYPE(STT_FUNC),		SYM_TYPE(STT_SECTION),		SYM_TYPE(STT_FILE),		SYM_TYPE(STT_COMMON),		SYM_TYPE(STT_TLS),#undef SYM_TYPE	};	const char *name = "unknown sym type name";	if (type < ARRAY_SIZE(type_name)) {		name = type_name[type];	}	return name;}static const char *sym_bind(unsigned bind){	static const char *bind_name[] = {#define SYM_BIND(X) [X] = #X		SYM_BIND(STB_LOCAL),		SYM_BIND(STB_GLOBAL),		SYM_BIND(STB_WEAK),#undef SYM_BIND	};	const char *name = "unknown sym bind name";	if (bind < ARRAY_SIZE(bind_name)) {		name = bind_name[bind];	}	return name;}static const char *sym_visibility(unsigned visibility){	static const char *visibility_name[] = {#define SYM_VISIBILITY(X) [X] = #X		SYM_VISIBILITY(STV_DEFAULT),		SYM_VISIBILITY(STV_INTERNAL),		SYM_VISIBILITY(STV_HIDDEN),		SYM_VISIBILITY(STV_PROTECTED),#undef SYM_VISIBILITY	};	const char *name = "unknown sym visibility name";	if (visibility < ARRAY_SIZE(visibility_name)) {		name = visibility_name[visibility];	}	return name;}static const char *rel_type(unsigned type){	static const char *type_name[] = {#define REL_TYPE(X) [X] = #X		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),#undef REL_TYPE	};	const char *name = "unknown type rel type name";	if (type < ARRAY_SIZE(type_name)) {		name = type_name[type];	}	return name;}static const char *sec_name(unsigned shndx){	const char *sec_strtab;	const char *name;	sec_strtab = strtab[ehdr.e_shstrndx];	name = "<noname>";	if (shndx < ehdr.e_shnum) {		name = sec_strtab + shdr[shndx].sh_name;	}	else if (shndx == SHN_ABS) {		name = "ABSOLUTE";	}	else if (shndx == SHN_COMMON) {		name = "COMMON";	}	return name;}static const char *sym_name(const char *sym_strtab, Elf32_Sym *sym){	const char *name;	name = "<noname>";	if (sym->st_name) {		name = sym_strtab + sym->st_name;	}	else {		name = sec_name(shdr[sym->st_shndx].sh_name);	}	return name;}#if BYTE_ORDER == LITTLE_ENDIAN#define le16_to_cpu(val) (val)#define le32_to_cpu(val) (val)#endif#if BYTE_ORDER == BIG_ENDIAN#define le16_to_cpu(val) bswap_16(val)#define le32_to_cpu(val) bswap_32(val)#endifstatic 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);}static void read_ehdr(FILE *fp){	if (fread(&ehdr, sizeof(ehdr), 1, fp) != 1) {		die("Cannot read ELF header: %s\n",			strerror(errno));	}	if (memcmp(ehdr.e_ident, ELFMAG, 4) != 0) {		die("No ELF magic\n");	}	if (ehdr.e_ident[EI_CLASS] != ELFCLASS32) {		die("Not a 32 bit executable\n");	}	if (ehdr.e_ident[EI_DATA] != ELFDATA2LSB) {		die("Not a LSB ELF executable\n");	}	if (ehdr.e_ident[EI_VERSION] != EV_CURRENT) {		die("Unknown ELF version\n");	}	/* Convert the fields to native endian */	ehdr.e_type      = elf16_to_cpu(ehdr.e_type);	ehdr.e_machine   = elf16_to_cpu(ehdr.e_machine);	ehdr.e_version   = elf32_to_cpu(ehdr.e_version);	ehdr.e_entry     = elf32_to_cpu(ehdr.e_entry);	ehdr.e_phoff     = elf32_to_cpu(ehdr.e_phoff);	ehdr.e_shoff     = elf32_to_cpu(ehdr.e_shoff);	ehdr.e_flags     = elf32_to_cpu(ehdr.e_flags);	ehdr.e_ehsize    = elf16_to_cpu(ehdr.e_ehsize);	ehdr.e_phentsize = elf16_to_cpu(ehdr.e_phentsize);	ehdr.e_phnum     = elf16_to_cpu(ehdr.e_phnum);	ehdr.e_shentsize = elf16_to_cpu(ehdr.e_shentsize);	ehdr.e_shnum     = elf16_to_cpu(ehdr.e_shnum);	ehdr.e_shstrndx  = elf16_to_cpu(ehdr.e_shstrndx);	if ((ehdr.e_type != ET_EXEC) && (ehdr.e_type != ET_DYN)) {		die("Unsupported ELF header type\n");	}	if (ehdr.e_machine != EM_386) {		die("Not for x86\n");	}	if (ehdr.e_version != EV_CURRENT) {		die("Unknown ELF version\n");	}	if (ehdr.e_ehsize != sizeof(Elf32_Ehdr)) {		die("Bad Elf header size\n");	}	if (ehdr.e_phentsize != sizeof(Elf32_Phdr)) {		die("Bad program header entry\n");	}	if (ehdr.e_shentsize != sizeof(Elf32_Shdr)) {		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;	if (ehdr.e_shnum > MAX_SHDRS) {		die("%d section headers supported: %d\n",			ehdr.e_shnum, MAX_SHDRS);	}	if (fseek(fp, ehdr.e_shoff, SEEK_SET) < 0) {		die("Seek to %d failed: %s\n",			ehdr.e_shoff, strerror(errno));	}	if (fread(&shdr, sizeof(shdr[0]), ehdr.e_shnum, fp) != ehdr.e_shnum) {		die("Cannot read ELF section headers: %s\n",			strerror(errno));	}	for(i = 0; i < ehdr.e_shnum; i++) {		shdr[i].sh_name      = elf32_to_cpu(shdr[i].sh_name);		shdr[i].sh_type      = elf32_to_cpu(shdr[i].sh_type);		shdr[i].sh_flags     = elf32_to_cpu(shdr[i].sh_flags);		shdr[i].sh_addr      = elf32_to_cpu(shdr[i].sh_addr);		shdr[i].sh_offset    = elf32_to_cpu(shdr[i].sh_offset);		shdr[i].sh_size      = elf32_to_cpu(shdr[i].sh_size);		shdr[i].sh_link      = elf32_to_cpu(shdr[i].sh_link);		shdr[i].sh_info      = elf32_to_cpu(shdr[i].sh_info);		shdr[i].sh_addralign = elf32_to_cpu(shdr[i].sh_addralign);		shdr[i].sh_entsize   = elf32_to_cpu(shdr[i].sh_entsize);	}}static void read_strtabs(FILE *fp){	int i;	for(i = 0; i < ehdr.e_shnum; i++) {		if (shdr[i].sh_type != SHT_STRTAB) {			continue;		}		strtab[i] = malloc(shdr[i].sh_size);		if (!strtab[i]) {			die("malloc of %d bytes for strtab failed\n",				shdr[i].sh_size);		}		if (fseek(fp, shdr[i].sh_offset, SEEK_SET) < 0) {			die("Seek to %d failed: %s\n",				shdr[i].sh_offset, strerror(errno));		}		if (fread(strtab[i], 1, shdr[i].sh_size, fp) != shdr[i].sh_size) {			die("Cannot read symbol table: %s\n",				strerror(errno));		}	}}static void read_symtabs(FILE *fp){	int i,j;	for(i = 0; i < ehdr.e_shnum; i++) {		if (shdr[i].sh_type != SHT_SYMTAB) {			continue;		}		symtab[i] = malloc(shdr[i].sh_size);		if (!symtab[i]) {			die("malloc of %d bytes for symtab failed\n",				shdr[i].sh_size);		}		if (fseek(fp, shdr[i].sh_offset, SEEK_SET) < 0) {			die("Seek to %d failed: %s\n",				shdr[i].sh_offset, strerror(errno));		}

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -