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

📄 relocs.c

📁 linux内核源码
💻 C
📖 第 1 页 / 共 2 页
字号:
		if (fread(symtab[i], 1, shdr[i].sh_size, fp) != shdr[i].sh_size) {			die("Cannot read symbol table: %s\n",				strerror(errno));		}		for(j = 0; j < shdr[i].sh_size/sizeof(symtab[i][0]); j++) {			symtab[i][j].st_name  = elf32_to_cpu(symtab[i][j].st_name);			symtab[i][j].st_value = elf32_to_cpu(symtab[i][j].st_value);			symtab[i][j].st_size  = elf32_to_cpu(symtab[i][j].st_size);			symtab[i][j].st_shndx = elf16_to_cpu(symtab[i][j].st_shndx);		}	}}static void read_relocs(FILE *fp){	int i,j;	for(i = 0; i < ehdr.e_shnum; i++) {		if (shdr[i].sh_type != SHT_REL) {			continue;		}		reltab[i] = malloc(shdr[i].sh_size);		if (!reltab[i]) {			die("malloc of %d bytes for relocs 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(reltab[i], 1, shdr[i].sh_size, fp) != shdr[i].sh_size) {			die("Cannot read symbol table: %s\n",				strerror(errno));		}		for(j = 0; j < shdr[i].sh_size/sizeof(reltab[0][0]); j++) {			reltab[i][j].r_offset = elf32_to_cpu(reltab[i][j].r_offset);			reltab[i][j].r_info   = elf32_to_cpu(reltab[i][j].r_info);		}	}}static void print_absolute_symbols(void){	int i;	printf("Absolute symbols\n");	printf(" Num:    Value Size  Type       Bind        Visibility  Name\n");	for(i = 0; i < ehdr.e_shnum; i++) {		char *sym_strtab;		Elf32_Sym *sh_symtab;		int j;		if (shdr[i].sh_type != SHT_SYMTAB) {			continue;		}		sh_symtab = symtab[i];		sym_strtab = strtab[shdr[i].sh_link];		for(j = 0; j < shdr[i].sh_size/sizeof(symtab[0][0]); j++) {			Elf32_Sym *sym;			const char *name;			sym = &symtab[i][j];			name = sym_name(sym_strtab, sym);			if (sym->st_shndx != SHN_ABS) {				continue;			}			printf("%5d %08x %5d %10s %10s %12s %s\n",				j, sym->st_value, sym->st_size,				sym_type(ELF32_ST_TYPE(sym->st_info)),				sym_bind(ELF32_ST_BIND(sym->st_info)),				sym_visibility(ELF32_ST_VISIBILITY(sym->st_other)),				name);		}	}	printf("\n");}static void print_absolute_relocs(void){	int i, printed = 0;	for(i = 0; i < ehdr.e_shnum; i++) {		char *sym_strtab;		Elf32_Sym *sh_symtab;		unsigned sec_applies, sec_symtab;		int j;		if (shdr[i].sh_type != SHT_REL) {			continue;		}		sec_symtab  = shdr[i].sh_link;		sec_applies = shdr[i].sh_info;		if (!(shdr[sec_applies].sh_flags & SHF_ALLOC)) {			continue;		}		sh_symtab = symtab[sec_symtab];		sym_strtab = strtab[shdr[sec_symtab].sh_link];		for(j = 0; j < shdr[i].sh_size/sizeof(reltab[0][0]); j++) {			Elf32_Rel *rel;			Elf32_Sym *sym;			const char *name;			rel = &reltab[i][j];			sym = &sh_symtab[ELF32_R_SYM(rel->r_info)];			name = sym_name(sym_strtab, sym);			if (sym->st_shndx != SHN_ABS) {				continue;			}			/* 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.			 */			if (is_safe_abs_reloc(name))				continue;			if (!printed) {				printf("WARNING: Absolute relocations"					" present\n");				printf("Offset     Info     Type     Sym.Value "					"Sym.Name\n");				printed = 1;			}			printf("%08x %08x %10s %08x  %s\n",				rel->r_offset,				rel->r_info,				rel_type(ELF32_R_TYPE(rel->r_info)),				sym->st_value,				name);		}	}	if (printed)		printf("\n");}static void walk_relocs(void (*visit)(Elf32_Rel *rel, Elf32_Sym *sym)){	int i;	/* Walk through the relocations */	for(i = 0; i < ehdr.e_shnum; i++) {		char *sym_strtab;		Elf32_Sym *sh_symtab;		unsigned sec_applies, sec_symtab;		int j;		if (shdr[i].sh_type != SHT_REL) {			continue;		}		sec_symtab  = shdr[i].sh_link;		sec_applies = shdr[i].sh_info;		if (!(shdr[sec_applies].sh_flags & SHF_ALLOC)) {			continue;		}		sh_symtab = symtab[sec_symtab];		sym_strtab = strtab[shdr[sec_symtab].sh_link];		for(j = 0; j < shdr[i].sh_size/sizeof(reltab[0][0]); j++) {			Elf32_Rel *rel;			Elf32_Sym *sym;			unsigned r_type;			rel = &reltab[i][j];			sym = &sh_symtab[ELF32_R_SYM(rel->r_info)];			r_type = ELF32_R_TYPE(rel->r_info);			/* Don't visit relocations to absolute symbols */			if (sym->st_shndx == SHN_ABS) {				continue;			}			if (r_type == R_386_PC32) {				/* PC relative relocations don't need to be adjusted */			}			else if (r_type == R_386_32) {				/* Visit relocations that need to be adjusted */				visit(rel, sym);			}			else {				die("Unsupported relocation type: %d\n", r_type);			}		}	}}static void count_reloc(Elf32_Rel *rel, Elf32_Sym *sym){	reloc_count += 1;}static void collect_reloc(Elf32_Rel *rel, Elf32_Sym *sym){	/* Remember the address that needs to be adjusted. */	relocs[reloc_idx++] = rel->r_offset;}static int cmp_relocs(const void *va, const void *vb){	const unsigned long *a, *b;	a = va; b = vb;	return (*a == *b)? 0 : (*a > *b)? 1 : -1;}static void emit_relocs(int as_text){	int i;	/* Count how many relocations I have and allocate space for them. */	reloc_count = 0;	walk_relocs(count_reloc);	relocs = malloc(reloc_count * sizeof(relocs[0]));	if (!relocs) {		die("malloc of %d entries for relocs failed\n",			reloc_count);	}	/* Collect up the relocations */	reloc_idx = 0;	walk_relocs(collect_reloc);	/* Order the relocations for more efficient processing */	qsort(relocs, reloc_count, sizeof(relocs[0]), cmp_relocs);	/* 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");		for(i = 0; i < reloc_count; i++) {			printf("\t .long 0x%08lx\n", relocs[i]);		}		printf("\n");	}	else {		unsigned char buf[4];		buf[0] = buf[1] = buf[2] = buf[3] = 0;		/* Print a stop */		printf("%c%c%c%c", buf[0], buf[1], buf[2], buf[3]);		/* Now print each relocation */		for(i = 0; i < reloc_count; i++) {			buf[0] = (relocs[i] >>  0) & 0xff;			buf[1] = (relocs[i] >>  8) & 0xff;			buf[2] = (relocs[i] >> 16) & 0xff;			buf[3] = (relocs[i] >> 24) & 0xff;			printf("%c%c%c%c", buf[0], buf[1], buf[2], buf[3]);		}	}}static void usage(void){	die("relocs [--abs-syms |--abs-relocs | --text] vmlinux\n");}int main(int argc, char **argv){	int show_absolute_syms, show_absolute_relocs;	int as_text;	const char *fname;	FILE *fp;	int i;	show_absolute_syms = 0;	show_absolute_relocs = 0;	as_text = 0;	fname = NULL;	for(i = 1; i < argc; i++) {		char *arg = argv[i];		if (*arg == '-') {			if (strcmp(argv[1], "--abs-syms") == 0) {				show_absolute_syms = 1;				continue;			}			if (strcmp(argv[1], "--abs-relocs") == 0) {				show_absolute_relocs = 1;				continue;			}			else if (strcmp(argv[1], "--text") == 0) {				as_text = 1;				continue;			}		}		else if (!fname) {			fname = arg;			continue;		}		usage();	}	if (!fname) {		usage();	}	fp = fopen(fname, "r");	if (!fp) {		die("Cannot open %s: %s\n",			fname, strerror(errno));	}	read_ehdr(fp);	read_shdrs(fp);	read_strtabs(fp);	read_symtabs(fp);	read_relocs(fp);	if (show_absolute_syms) {		print_absolute_symbols();		return 0;	}	if (show_absolute_relocs) {		print_absolute_relocs();		return 0;	}	emit_relocs(as_text);	return 0;}

⌨️ 快捷键说明

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