📄 dyngen.c.svn-base
字号:
void elf_swap_rel(ELF_RELOC *rel){ swabls(&rel->r_offset); swabls(&rel->r_info);#ifdef ELF_USES_RELOCA swablss(&rel->r_addend);#endif}struct elf_shdr *find_elf_section(struct elf_shdr *shdr, int shnum, const char *shstr, const char *name){ int i; const char *shname; struct elf_shdr *sec; for(i = 0; i < shnum; i++) { sec = &shdr[i]; if (!sec->sh_name) continue; shname = shstr + sec->sh_name; if (!strcmp(shname, name)) return sec; } return NULL;}int find_reloc(int sh_index){ struct elf_shdr *sec; int i; for(i = 0; i < ehdr.e_shnum; i++) { sec = &shdr[i]; if (sec->sh_type == SHT_RELOC && sec->sh_info == sh_index) return i; } return 0;}static host_ulong get_rel_offset(EXE_RELOC *rel){ return rel->r_offset;}static char *get_rel_sym_name(EXE_RELOC *rel){ return strtab + symtab[ELFW(R_SYM)(rel->r_info)].st_name;}static char *get_sym_name(EXE_SYM *sym){ return strtab + sym->st_name;}/* load an elf object file */int load_object(const char *filename){ int fd; struct elf_shdr *sec, *symtab_sec, *strtab_sec, *text_sec; int i, j; ElfW(Sym) *sym; char *shstr; ELF_RELOC *rel; fd = open(filename, O_RDONLY); if (fd < 0) error("can't open file '%s'", filename); /* Read ELF header. */ if (read(fd, &ehdr, sizeof (ehdr)) != sizeof (ehdr)) error("unable to read file header"); /* Check ELF identification. */ if (ehdr.e_ident[EI_MAG0] != ELFMAG0 || ehdr.e_ident[EI_MAG1] != ELFMAG1 || ehdr.e_ident[EI_MAG2] != ELFMAG2 || ehdr.e_ident[EI_MAG3] != ELFMAG3 || ehdr.e_ident[EI_VERSION] != EV_CURRENT) { error("bad ELF header"); } do_swap = elf_must_swap(&ehdr); if (do_swap) elf_swap_ehdr(&ehdr); if (ehdr.e_ident[EI_CLASS] != ELF_CLASS) error("Unsupported ELF class"); if (ehdr.e_type != ET_REL) error("ELF object file expected"); if (ehdr.e_version != EV_CURRENT) error("Invalid ELF version"); if (!elf_check_arch(ehdr.e_machine)) error("Unsupported CPU (e_machine=%d)", ehdr.e_machine); /* read section headers */ shdr = load_data(fd, ehdr.e_shoff, ehdr.e_shnum * sizeof(struct elf_shdr)); if (do_swap) { for(i = 0; i < ehdr.e_shnum; i++) { elf_swap_shdr(&shdr[i]); } } /* read all section data */ sdata = malloc(sizeof(void *) * ehdr.e_shnum); memset(sdata, 0, sizeof(void *) * ehdr.e_shnum); for(i = 0;i < ehdr.e_shnum; i++) { sec = &shdr[i]; if (sec->sh_type != SHT_NOBITS) sdata[i] = load_data(fd, sec->sh_offset, sec->sh_size); } sec = &shdr[ehdr.e_shstrndx]; shstr = (char *)sdata[ehdr.e_shstrndx]; /* swap relocations */ for(i = 0; i < ehdr.e_shnum; i++) { sec = &shdr[i]; if (sec->sh_type == SHT_RELOC) { nb_relocs = sec->sh_size / sec->sh_entsize; if (do_swap) { for(j = 0, rel = (ELF_RELOC *)sdata[i]; j < nb_relocs; j++, rel++) elf_swap_rel(rel); } } } /* text section */ text_sec = find_elf_section(shdr, ehdr.e_shnum, shstr, ".text"); if (!text_sec) error("could not find .text section"); text_shndx = text_sec - shdr; text = sdata[text_shndx]; /* find text relocations, if any */ relocs = NULL; nb_relocs = 0; i = find_reloc(text_shndx); if (i != 0) { relocs = (ELF_RELOC *)sdata[i]; nb_relocs = shdr[i].sh_size / shdr[i].sh_entsize; } symtab_sec = find_elf_section(shdr, ehdr.e_shnum, shstr, ".symtab"); if (!symtab_sec) error("could not find .symtab section"); strtab_sec = &shdr[symtab_sec->sh_link]; symtab = (ElfW(Sym) *)sdata[symtab_sec - shdr]; strtab = (char *)sdata[symtab_sec->sh_link]; nb_syms = symtab_sec->sh_size / sizeof(ElfW(Sym)); if (do_swap) { for(i = 0, sym = symtab; i < nb_syms; i++, sym++) { swab32s(&sym->st_name); swabls(&sym->st_value); swabls(&sym->st_size); swab16s(&sym->st_shndx); } } close(fd); return 0;}#endif /* CONFIG_FORMAT_ELF */#ifdef CONFIG_FORMAT_COFF/* COFF file info */struct external_scnhdr *shdr;uint8_t **sdata;struct external_filehdr fhdr;struct external_syment *coff_symtab;char *strtab;int coff_text_shndx, coff_data_shndx;int data_shndx;#define STRTAB_SIZE 4#define DIR32 0x06#define DISP32 0x14#define T_FUNCTION 0x20#define C_EXTERNAL 2void sym_ent_name(struct external_syment *ext_sym, EXE_SYM *sym){ char *q; int c, i, len; if (ext_sym->e.e.e_zeroes != 0) { q = sym->st_name; for(i = 0; i < 8; i++) { c = ext_sym->e.e_name[i]; if (c == '\0') break; *q++ = c; } *q = '\0'; } else { pstrcpy(sym->st_name, sizeof(sym->st_name), strtab + ext_sym->e.e.e_offset); } /* now convert the name to a C name (suppress the leading '_') */ if (sym->st_name[0] == '_') { len = strlen(sym->st_name); memmove(sym->st_name, sym->st_name + 1, len - 1); sym->st_name[len - 1] = '\0'; }}char *name_for_dotdata(struct coff_rel *rel){ int i; struct coff_sym *sym; uint32_t text_data; text_data = *(uint32_t *)(text + rel->r_offset); for (i = 0, sym = symtab; i < nb_syms; i++, sym++) { if (sym->st_syment->e_scnum == data_shndx && text_data >= sym->st_value && text_data < sym->st_value + sym->st_size) { return sym->st_name; } } return NULL;}static char *get_sym_name(EXE_SYM *sym){ return sym->st_name;}static char *get_rel_sym_name(EXE_RELOC *rel){ char *name; name = get_sym_name(symtab + *(uint32_t *)(rel->r_reloc->r_symndx)); if (!strcmp(name, ".data")) name = name_for_dotdata(rel); if (name[0] == '.') return NULL; return name;}static host_ulong get_rel_offset(EXE_RELOC *rel){ return rel->r_offset;}struct external_scnhdr *find_coff_section(struct external_scnhdr *shdr, int shnum, const char *name){ int i; const char *shname; struct external_scnhdr *sec; for(i = 0; i < shnum; i++) { sec = &shdr[i]; if (!sec->s_name) continue; shname = sec->s_name; if (!strcmp(shname, name)) return sec; } return NULL;}/* load a coff object file */int load_object(const char *filename){ int fd; struct external_scnhdr *sec, *text_sec, *data_sec; int i; struct external_syment *ext_sym; struct external_reloc *coff_relocs; struct external_reloc *ext_rel; uint32_t *n_strtab; EXE_SYM *sym; EXE_RELOC *rel; const char *p; int aux_size, j; fd = open(filename, O_RDONLY#ifdef _WIN32 | O_BINARY#endif ); if (fd < 0) error("can't open file '%s'", filename); /* Read COFF header. */ if (read(fd, &fhdr, sizeof (fhdr)) != sizeof (fhdr)) error("unable to read file header"); /* Check COFF identification. */ if (fhdr.f_magic != I386MAGIC) { error("bad COFF header"); } do_swap = 0; /* read section headers */ shdr = load_data(fd, sizeof(struct external_filehdr) + fhdr.f_opthdr, fhdr.f_nscns * sizeof(struct external_scnhdr)); /* read all section data */ sdata = malloc(sizeof(void *) * fhdr.f_nscns); memset(sdata, 0, sizeof(void *) * fhdr.f_nscns); for(i = 0;i < fhdr.f_nscns; i++) { sec = &shdr[i]; if (!strstart(sec->s_name, ".bss", &p)) sdata[i] = load_data(fd, sec->s_scnptr, sec->s_size); } /* text section */ text_sec = find_coff_section(shdr, fhdr.f_nscns, ".text"); if (!text_sec) error("could not find .text section"); coff_text_shndx = text_sec - shdr; text = sdata[coff_text_shndx]; /* data section */ data_sec = find_coff_section(shdr, fhdr.f_nscns, ".data"); if (!data_sec) error("could not find .data section"); coff_data_shndx = data_sec - shdr; coff_symtab = load_data(fd, fhdr.f_symptr, fhdr.f_nsyms*SYMESZ); for (i = 0, ext_sym = coff_symtab; i < nb_syms; i++, ext_sym++) { for(i=0;i<8;i++) printf(" %02x", ((uint8_t *)ext_sym->e.e_name)[i]); printf("\n"); } n_strtab = load_data(fd, (fhdr.f_symptr + fhdr.f_nsyms*SYMESZ), STRTAB_SIZE); strtab = load_data(fd, (fhdr.f_symptr + fhdr.f_nsyms*SYMESZ), *n_strtab); nb_syms = fhdr.f_nsyms; for (i = 0, ext_sym = coff_symtab; i < nb_syms; i++, ext_sym++) { if (strstart(ext_sym->e.e_name, ".text", NULL)) text_shndx = ext_sym->e_scnum; if (strstart(ext_sym->e.e_name, ".data", NULL)) data_shndx = ext_sym->e_scnum; } /* set coff symbol */ symtab = malloc(sizeof(struct coff_sym) * nb_syms); for (i = 0, ext_sym = coff_symtab, sym = symtab; i < nb_syms; i++, ext_sym++, sym++) { memset(sym, 0, sizeof(*sym)); sym->st_syment = ext_sym; sym_ent_name(ext_sym, sym); sym->st_value = ext_sym->e_value; aux_size = *(int8_t *)ext_sym->e_numaux; if (ext_sym->e_scnum == text_shndx && ext_sym->e_type == T_FUNCTION) { for (j = aux_size + 1; j < nb_syms - i; j++) { if ((ext_sym + j)->e_scnum == text_shndx && (ext_sym + j)->e_type == T_FUNCTION ){ sym->st_size = (ext_sym + j)->e_value - ext_sym->e_value; break; } else if (j == nb_syms - i - 1) { sec = &shdr[coff_text_shndx]; sym->st_size = sec->s_size - ext_sym->e_value; break; } } } else if (ext_sym->e_scnum == data_shndx && *(uint8_t *)ext_sym->e_sclass == C_EXTERNAL) { for (j = aux_size + 1; j < nb_syms - i; j++) { if ((ext_sym + j)->e_scnum == data_shndx) { sym->st_size = (ext_sym + j)->e_value - ext_sym->e_value; break; } else if (j == nb_syms - i - 1) { sec = &shdr[coff_data_shndx]; sym->st_size = sec->s_size - ext_sym->e_value; break; } } } else { sym->st_size = 0; } sym->st_type = ext_sym->e_type; sym->st_shndx = ext_sym->e_scnum; } /* find text relocations, if any */ sec = &shdr[coff_text_shndx]; coff_relocs = load_data(fd, sec->s_relptr, sec->s_nreloc*RELSZ); nb_relocs = sec->s_nreloc; /* set coff relocation */ relocs = malloc(sizeof(struct coff_rel) * nb_relocs); for (i = 0, ext_rel = coff_relocs, rel = relocs; i < nb_relocs; i++, ext_rel++, rel++) { memset(rel, 0, sizeof(*rel)); rel->r_reloc = ext_rel; rel->r_offset = *(uint32_t *)ext_rel->r_vaddr; rel->r_type = *(uint16_t *)ext_rel->r_type; } return 0;}#endif /* CONFIG_FORMAT_COFF */#ifdef CONFIG_FORMAT_MACH/* File Header */struct mach_header mach_hdr;/* commands */struct segment_command *segment = 0;struct dysymtab_command *dysymtabcmd = 0;
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -