📄 relocs.c
字号:
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 + -