Elf32_Shdr * elf_find_section_named(char *name) { Elf32_Shdr *section; Elf32_Shdr *strtab_section; Elf32_Word sectionsize; int numsections; char *strtab; int i = 0; section = (Elf32_Shdr *)FILE_OFFSET(read_word(elf_header->e_shoff)); strtab_section = elf_find_section_num(read_half(elf_header->e_shstrndx)); strtab = (char *)FILE_OFFSET(read_word(strtab_section->sh_offset)); sectionsize = read_half(elf_header->e_shentsize); numsections = read_half(elf_header->e_shnum); for (i=0;i<numsections;i++) { if (strcmp(&strtab[read_word(section->sh_name)], name) == 0) { return section; } section = (Elf32_Shdr *)((char *)section + sectionsize); } return NULL; }
void * dynamic_find_tag(Elf32_Shdr *dynamic, Elf32_Sword d_tag) { int i; Elf32_Dyn *element; element = (Elf32_Dyn *)FILE_OFFSET(read_word(dynamic->sh_offset)); for (i=0; read_sword(element[i].d_tag) != DT_NULL; i++) { if (read_sword(element[i].d_tag) == d_tag) { return FILE_OFFSET(read_word(element[i].d_un.d_ptr)); } } return NULL; }
void find_segment_addr_min_max(Elf32_Word file_offset, Elf32_Addr *start, Elf32_Addr *end) { Elf32_Phdr *segment; Elf32_Word segmentsize; int numsegments; int i = 0; segment = (Elf32_Phdr *)FILE_OFFSET(read_word(elf_header->e_phoff)); segmentsize = read_half(elf_header->e_phentsize); numsegments = read_half(elf_header->e_phnum); for (i=0;i<numsegments;i++) { if ((file_offset >= read_word(segment->p_offset)) && (file_offset < read_word(segment->p_offset) + read_word(segment->p_filesz))) { *start = read_word(segment->p_vaddr); *end = read_word(segment->p_vaddr) + read_word(segment->p_memsz); return; } segment = (Elf32_Phdr *)((char *)segment + segmentsize); } fprintf(stderr, "Error: Couldn't find segment in find_segment_addr_min_max()\n"); }
Elf32_Word vma_to_offset(Elf32_Addr addr) { Elf32_Shdr *section; Elf32_Shdr *higher; Elf32_Word sectionsize; int numsections; int i = 0; section = (Elf32_Shdr *)FILE_OFFSET(read_word(elf_header->e_shoff)); sectionsize = read_half(elf_header->e_shentsize); numsections = read_half(elf_header->e_shnum); higher = NULL; for (i=0;i<numsections;i++) { if ( (addr >= read_word(section->sh_addr)) && (addr < read_word(section->sh_addr) + read_word(section->sh_size)) ) { return read_word(section->sh_offset) + (addr - read_word(section->sh_addr)); } section = (Elf32_Shdr *)((char *)section + sectionsize); } fprintf(stderr, "Warning, unable to convert address %d (0x%x) to file offset\n", addr, addr); return 0; }
Elf32_Shdr * elf_find_next_higher_section(Elf32_Word offset) { Elf32_Shdr *section; Elf32_Shdr *higher; Elf32_Word sectionsize; int numsections; int i = 0; section = (Elf32_Shdr *)FILE_OFFSET(read_word(elf_header->e_shoff)); sectionsize = read_half(elf_header->e_shentsize); numsections = read_half(elf_header->e_shnum); higher = NULL; for (i=0;i<numsections;i++) { if (read_word(section->sh_offset) >= offset) { if (higher == NULL) { higher = section; } else if (read_word(section->sh_offset) < read_word(higher->sh_offset)) { higher = section; } } section = (Elf32_Shdr *)((char *)section + sectionsize); } return higher; }
Elf32_Shdr * elf_find_section_num(int section_index) { Elf32_Shdr *section; Elf32_Word sectionsize; section = (Elf32_Shdr *)FILE_OFFSET(read_word(elf_header->e_shoff)); sectionsize = read_half(elf_header->e_shentsize); section = (Elf32_Shdr *)((char *)section + sectionsize*section_index); return section; }
Elf32_Shdr * elf_find_section(Elf32_Word sh_type) { Elf32_Shdr *section; Elf32_Word sectionsize; int numsections; int i = 0; section = (Elf32_Shdr *)FILE_OFFSET(read_word(elf_header->e_shoff)); sectionsize = read_half(elf_header->e_shentsize); numsections = read_half(elf_header->e_shnum); for (i=0;i<numsections;i++) { if (read_word(section->sh_type) == sh_type) { return section; } section = (Elf32_Shdr *)((char *)section + sectionsize); } return NULL; }
/* * Move the read/write file offset */ LOCAL INT lseek64(fs_env_t *env, INT fno, off64_t off, INT whence, off64_t *newoff, BOOL off64) { fs_file_t *file; fs_cond_t *con; INT sts; /* Get file & connection descriptor */ sts = fs_file_get(env, fno, &file, &con); if (sts != 0) goto exit0; /* Check file type & get file size */ sts = xfs_fstat64_us_impl(env, con, file); if (sts != 0) goto exit1; if (S_ISCHR(env->t_misc.t_stat64_u.st_mode) || S_ISFIFO(env->t_misc.t_stat64_u.st_mode) || S_ISSOCK(env->t_misc.t_stat64_u.st_mode)) { sts = EX_SPIPE; goto exit1; } /* Move offset depends on whence */ switch (whence) { case SEEK_SET: // off = off; break; case SEEK_CUR: off += FILE_OFFSET(file); break; case SEEK_END: off += env->t_misc.t_stat64_u.st_size; break; default: sts = EX_INVAL; goto exit1; } /* Check result offset */ if (off < 0 #if LSEEK_WITHIN_FILE_SIZE || off > env->t_misc.t_stat64_u.st_size #endif ) { sts = EX_INVAL; goto exit1; } /* Check over 32 bits */ if (off64 == FALSE) { if (off > ULONG_MAX) { sts = EX_OVERFLOW; goto exit1; } #if SIGNED_OFFSET if (off > LONG_MAX) { sts = EX_INVAL; goto exit1; } #endif } /* Set new offset */ FILE_OFFSET(file) = off; *newoff = off; exit1: /* Release file & connection descriptor */ (void)fs_file_release(env, file, con); if (sts == 0) return 0; exit0: env->t_errno = sts; return sts; }