//--------------------------------------------------------------------- Elf_Scn* getELFSectionByName(Elf* elf, char* secName) { Elf32_Ehdr* ehdr; Elf_Scn *scn; Elf32_Shdr *shdr; // Get the ELF Header ehdr = elf32_getehdr(elf); if (NULL == ehdr){ fprintf(stderr, "getELFSectionByName: Error reading ELF header\n"); return NULL; } scn = NULL; while ((scn = elf_nextscn(elf, scn)) != NULL){ if ((shdr = elf32_getshdr(scn)) != NULL){ char* CurrSecName = NULL; CurrSecName = elf_strptr(elf, ehdr->e_shstrndx, shdr->sh_name); if (strcmp(CurrSecName, secName) == 0) return scn; } } return NULL; }
Elf_Scn * get_scnbyname(Elf *elf, char *name, int *num) { Elf32_Ehdr * ehdr; Elf_Scn * scn; Elf32_Shdr * shdr; Elf_Data * data; int cnt, tmp; if (!num) num = &tmp; *num = 0; if ((ehdr = elf32_getehdr(elf))==NULL) return NULL; if (((scn = elf_getscn(elf, ehdr->e_shstrndx)) == NULL) || ((data = elf_getdata(scn, NULL)) == NULL)) return NULL; for (cnt = 1, scn = NULL; (scn = elf_nextscn(elf, scn)); cnt++) { if ((shdr = elf32_getshdr(scn)) == NULL) return NULL; if (! strcmp(name, (char *)data->d_buf + shdr->sh_name)) { *num = cnt; return scn; } } return NULL; }
Elf32_Ehdr *xelf32_getehdr(Elf *e) { Elf32_Ehdr *ehdr = elf32_getehdr(e); if (ehdr == NULL) { eprintf("elf_getehdr() failed: %s", elf_errmsg(-1)); exit(EXIT_FAILURE); } return ehdr; }
static Elf64_Half get_type(Elf* elf) { Elf64_Ehdr* ehdr64 = elf64_getehdr(elf); if (ehdr64) return ehdr64->e_type; Elf32_Ehdr* ehdr32 = elf32_getehdr(elf); if (ehdr32) return ehdr32->e_type; xbt_die("Could not get ELF heeader"); }
int32_t __tgt_rtl_is_valid_binary(__tgt_device_image *image) { // If we don't have a valid ELF ID we can just fail. #if TARGET_ELF_ID < 1 return 0; #else // Is the library version incompatible with the header file? if (elf_version(EV_CURRENT) == EV_NONE) { DP("Incompatible ELF library!\n"); return 0; } char *img_begin = (char *)image->ImageStart; char *img_end = (char *)image->ImageEnd; size_t img_size = img_end - img_begin; // Obtain elf handler Elf *e = elf_memory(img_begin, img_size); if (!e) { DP("Unable to get ELF handle: %s!\n", elf_errmsg(-1)); return 0; } // Check if ELF is the right kind if (elf_kind(e) != ELF_K_ELF) { DP("Unexpected ELF type!\n"); return 0; } Elf64_Ehdr *eh64 = elf64_getehdr(e); Elf32_Ehdr *eh32 = elf32_getehdr(e); if (!eh64 && !eh32) { DP("Unable to get machine ID from ELF file!\n"); elf_end(e); return 0; } uint16_t MachineID; if (eh64 && !eh32) MachineID = eh64->e_machine; else if (eh32 && !eh64) MachineID = eh32->e_machine; else { DP("Ambiguous ELF header!\n"); elf_end(e); return 0; } elf_end(e); return MachineID == TARGET_ELF_ID; #endif }
static Elf32_Half download_machine( const char *filename ) { Elf *elf; Elf32_Ehdr *ehdr; int fd; Elf32_Half machine = 0; if ((fd = open(filename, O_RDONLY | O_BINARY)) != -1) { if (elf_version(EV_CURRENT) != EV_NONE) { elf = elf_begin(fd, ELF_C_READ, NULL); if (elf) { ehdr = elf32_getehdr( elf ); if (ehdr ) { machine = ehdr->e_machine; } else { fprintf( stderr, "Failed to get ELF header: %s\n", elf_errmsg(-1) ); } elf_end(elf); } else { fprintf( stderr, "download_machine: elf_begin - %s\n", elf_errmsg(-1) ); } } else { fprintf(stderr, "Elf library is out of date\n" ); } if (close( fd ) != 0) perror("Error closing executable"); } else { perror("Error opening executable" ); } return machine; }
int main(int argc, char *argv[]) { if (argc < 2) { fprintf(stderr, "%s input\n", argv[0]); return 1; } const char* elfinput = argv[1]; if (elf_version(EV_CURRENT) == EV_NONE) { fprintf(stderr, "Elf library out of date\n"); return 1; } int fd = open(elfinput, O_RDONLY); if (fd < 0) { perror(elfinput); return 1; } Elf* elf = elf_begin(fd, ELF_C_READ, NULL); Elf32_Ehdr* ehdr = elf32_getehdr(elf); Elf_Scn* section = NULL; while ((section = elf_nextscn(elf, section)) != NULL) { Elf32_Shdr* shdr; if ((shdr = elf32_getshdr(section)) != NULL) { const char* name = elf_strptr(elf, ehdr->e_shstrndx, shdr->sh_name); if (strcmp(name, ".directive")) continue; Elf_Data* data = NULL; if ((data = elf_rawdata(section, data)) == NULL || data->d_size == 0 || data->d_buf == 0) continue; fwrite(data->d_buf, 1, data->d_size, stdout); fprintf(stdout, "\n"); elf_end(elf); close(fd); return 0; } } fprintf(stderr, "No .directive section found!\n"); elf_end(elf); close(fd); return 1; }
//--------------------------------------------------------------------- char* getELFSectionName(Elf* elf, int ndx) { Elf32_Ehdr* ehdr; Elf_Scn *scn; Elf32_Shdr *shdr; if ((ehdr = elf32_getehdr(elf)) == NULL){ fprintf(stderr, "Error reading ELF header\n"); return NULL; } if ((scn = elf_getscn(elf, ndx)) == NULL){ fprintf(stderr, "Error reading ELF section table.\n"); return NULL; } if ((shdr = elf32_getshdr(scn)) == NULL){ fprintf(stderr, "Error reading ELF section header.\n"); return NULL; }; return elf_strptr(elf, ehdr->e_shstrndx, shdr->sh_name); }
int write_ehdr(elf_data_t *elf, char **err) { off_t off; size_t n, ehdr_size; void *ehdr_buf; if(!gelf_update_ehdr(elf->e, &elf->ehdr)) { (*err) = "failed to update executable header"; return -1; } if(elf->bits == 32) { ehdr_buf = elf32_getehdr(elf->e); ehdr_size = sizeof(Elf32_Ehdr); } else { ehdr_buf = elf64_getehdr(elf->e); ehdr_size = sizeof(Elf64_Ehdr); } if(!ehdr_buf) { (*err) = "failed to get executable header"; return -1; } off = lseek(elf->fd, 0, SEEK_SET); if(off < 0) { (*err) = "lseek failed"; return -1; } n = write(elf->fd, ehdr_buf, ehdr_size); if(n != ehdr_size) { (*err) = "write failed"; return -1; } return 0; }
/* Given an Elf ptr, set up dbg with pointers to all the Dwarf data sections. Return NULL on error. This function is also responsible for determining whether the given object contains Dwarf information or not. The test currently used is that it contains either a .debug_info or a .debug_frame section. If not, it returns DW_DLV_NO_ENTRY causing dwarf_init() also to return DW_DLV_NO_ENTRY. Earlier, we had thought of using only the presence/absence of .debug_info to test, but we added .debug_frame since there could be stripped objects that have only a .debug_frame section for exception processing. DW_DLV_NO_ENTRY or DW_DLV_OK or DW_DLV_ERROR */ static int _dwarf_setup(Dwarf_Debug dbg, dwarf_elf_handle elf, Dwarf_Error * error) { #ifdef __SGI_FAST_LIBELF Elf64_Ehdr ehdr; Elf64_Shdr shdr; enum elf_sgi_error_type sres; unsigned char const* ehdr_ident; #else Elf32_Ehdr *ehdr32; #ifdef HAVE_ELF64_GETEHDR Elf64_Ehdr *ehdr64; #endif Elf32_Shdr *shdr32; #ifdef HAVE_ELF64_GETSHDR Elf64_Shdr *shdr64; #endif Elf_Scn *scn; char *ehdr_ident; #endif /* !defined(__SGI_FAST_LIBELF) */ Dwarf_Half machine; char *scn_name; int is_64bit; int foundDwarf; Dwarf_Unsigned section_size; Dwarf_Unsigned section_count; Dwarf_Half section_index; foundDwarf = FALSE; dbg->de_elf = elf; dbg->de_assume_string_in_bounds = _dwarf_assume_string_bad; #ifdef __SGI_FAST_LIBELF sres = elf_sgi_ehdr(elf, &ehdr); if (sres != ELF_SGI_ERROR_OK) { DWARF_DBG_ERROR(dbg, _dwarf_error_code_from_elf_sgi_error_code(sres), DW_DLV_ERROR); } ehdr_ident = ehdr.e_ident; section_count = ehdr.e_shnum; machine = ehdr.e_machine; #else if ((ehdr_ident = elf_getident(elf, NULL)) == NULL) { DWARF_DBG_ERROR(dbg, DW_DLE_ELF_GETIDENT_ERROR, DW_DLV_ERROR); } #endif is_64bit = (ehdr_ident[EI_CLASS] == ELFCLASS64); dbg->de_same_endian = 1; dbg->de_copy_word = memcpy; #ifdef WORDS_BIGENDIAN dbg->de_big_endian_object = 1; if (ehdr_ident[EI_DATA] == ELFDATA2LSB) { dbg->de_same_endian = 0; dbg->de_big_endian_object = 0; dbg->de_copy_word = _dwarf_memcpy_swap_bytes; } #else /* little endian */ dbg->de_big_endian_object = 0; if (ehdr_ident[EI_DATA] == ELFDATA2MSB) { dbg->de_same_endian = 0; dbg->de_big_endian_object = 1; dbg->de_copy_word = _dwarf_memcpy_swap_bytes; } #endif /* !WORDS_BIGENDIAN */ /* The following de_length_size is Not Too Significant. Only used one calculation, and an appoximate one at that. */ dbg->de_length_size = is_64bit ? 8 : 4; dbg->de_pointer_size = is_64bit ? 8 : 4; #ifdef __SGI_FAST_LIBELF /* We've already loaded the ELF header, so there's nothing to do here */ #else #ifdef HAVE_ELF64_GETEHDR if (is_64bit) { ehdr64 = elf64_getehdr(elf); if (ehdr64 == NULL) { DWARF_DBG_ERROR(dbg, DW_DLE_ELF_GETEHDR_ERROR, DW_DLV_ERROR); } section_count = ehdr64->e_shnum; machine = ehdr64->e_machine; } else #endif { ehdr32 = elf32_getehdr(elf); if (ehdr32 == NULL) { DWARF_DBG_ERROR(dbg, DW_DLE_ELF_GETEHDR_ERROR, DW_DLV_ERROR); } section_count = ehdr32->e_shnum; machine = ehdr32->e_machine; } #endif /* !defined(__SGI_FAST_LIBELF) */ if (is_64bit && machine != EM_MIPS) { /* MIPS/IRIX makes pointer size and length size 8 for -64. Other platforms make length 4 always. */ /* 4 here supports 32bit-offset dwarf2, as emitted by cygnus tools, and the dwarfv2.1 64bit extension setting. */ dbg->de_length_size = 4; } /* We start at index 1 to skip the initial empty section. */ for (section_index = 1; section_index < section_count; ++section_index) { #ifdef __SGI_FAST_LIBELF sres = elf_sgi_shdr(elf, section_index, &shdr); if (sres != ELF_SGI_ERROR_OK) { DWARF_DBG_ERROR(dbg, _dwarf_error_code_from_elf_sgi_error_code(sres), DW_DLV_ERROR); } section_size = shdr.sh_size; sres = elf_sgi_string(elf, ehdr.e_shstrndx, shdr.sh_name, (char const** )&scn_name); if (sres != ELF_SGI_ERROR_OK) { DWARF_DBG_ERROR(dbg, _dwarf_error_code_from_elf_sgi_error_code(sres), DW_DLV_ERROR); } #else /* !defined(__SGI_FAST_LIBELF) */ scn = elf_getscn(elf, section_index); if (scn == NULL) { DWARF_DBG_ERROR(dbg, DW_DLE_MDE, DW_DLV_ERROR); } #ifdef HAVE_ELF64_GETSHDR if (is_64bit) { shdr64 = elf64_getshdr(scn); if (shdr64 == NULL) { DWARF_DBG_ERROR(dbg, DW_DLE_ELF_GETSHDR_ERROR, DW_DLV_ERROR); } section_size = shdr64->sh_size; if ((scn_name = elf_strptr(elf, ehdr64->e_shstrndx, shdr64->sh_name)) == NULL) { DWARF_DBG_ERROR(dbg, DW_DLE_ELF_STRPTR_ERROR, DW_DLV_ERROR); } } else #endif /* HAVE_ELF64_GETSHDR */ { if ((shdr32 = elf32_getshdr(scn)) == NULL) { DWARF_DBG_ERROR(dbg, DW_DLE_ELF_GETSHDR_ERROR, 0); } section_size = shdr32->sh_size; if ((scn_name = elf_strptr(elf, ehdr32->e_shstrndx, shdr32->sh_name)) == NULL) { DWARF_DBG_ERROR(dbg, DW_DLE_ELF_STRPTR_ERROR, DW_DLV_ERROR); } } #endif /* !defined(__SGI_FAST_LIBELF) */ if (strncmp(scn_name, ".debug_", 7) && strcmp(scn_name, ".eh_frame") ) continue; else if (strcmp(scn_name, ".debug_info") == 0) { if (dbg->de_debug_info != NULL) { DWARF_DBG_ERROR(dbg, DW_DLE_DEBUG_INFO_DUPLICATE, DW_DLV_ERROR); } if (section_size == 0) { /* Know no reason to allow empty debug_info section */ DWARF_DBG_ERROR(dbg, DW_DLE_DEBUG_INFO_NULL, DW_DLV_ERROR); } foundDwarf = TRUE; dbg->de_debug_info_index = section_index; dbg->de_debug_info_size = section_size; } else if (strcmp(scn_name, ".debug_abbrev") == 0) { if (dbg->de_debug_abbrev != NULL) { DWARF_DBG_ERROR(dbg, DW_DLE_DEBUG_ABBREV_DUPLICATE, DW_DLV_ERROR); } if (section_size == 0) { /* Know no reason to allow empty debug_abbrev section */ DWARF_DBG_ERROR(dbg, DW_DLE_DEBUG_ABBREV_NULL, DW_DLV_ERROR); } dbg->de_debug_abbrev_index = section_index; dbg->de_debug_abbrev_size = section_size; } else if (strcmp(scn_name, ".debug_aranges") == 0) { if (dbg->de_debug_aranges_index != 0) { DWARF_DBG_ERROR(dbg, DW_DLE_DEBUG_ARANGES_DUPLICATE, DW_DLV_ERROR); } if (section_size == 0) { /* a zero size section is just empty. Ok, no error */ continue; } dbg->de_debug_aranges_index = section_index; dbg->de_debug_aranges_size = section_size; } else if (strcmp(scn_name, ".debug_line") == 0) { if (dbg->de_debug_line_index != 0) { DWARF_DBG_ERROR(dbg, DW_DLE_DEBUG_LINE_DUPLICATE, DW_DLV_ERROR); } if (section_size == 0) { /* a zero size section is just empty. Ok, no error */ continue; } dbg->de_debug_line_index = section_index; dbg->de_debug_line_size = section_size; } else if (strcmp(scn_name, ".debug_frame") == 0) { if (dbg->de_debug_frame_index != 0) { DWARF_DBG_ERROR(dbg, DW_DLE_DEBUG_FRAME_DUPLICATE, DW_DLV_ERROR); } if (section_size == 0) { /* a zero size section is just empty. Ok, no error */ continue; } dbg->de_debug_frame_index = section_index; dbg->de_debug_frame_size = section_size; foundDwarf = TRUE; } else if (strcmp(scn_name, ".eh_frame") == 0) { /* gnu egcs-1.1.2 data */ if (dbg->de_debug_frame_eh_gnu_index != 0) { DWARF_DBG_ERROR(dbg, DW_DLE_DEBUG_FRAME_DUPLICATE, DW_DLV_ERROR); } if (section_size == 0) { /* a zero size section is just empty. Ok, no error */ continue; } dbg->de_debug_frame_eh_gnu_index = section_index; dbg->de_debug_frame_size_eh_gnu = section_size; foundDwarf = TRUE; } else if (strcmp(scn_name, ".debug_loc") == 0) { if (dbg->de_debug_loc_index != 0) { DWARF_DBG_ERROR(dbg, DW_DLE_DEBUG_LOC_DUPLICATE, DW_DLV_ERROR); } if (section_size == 0) { /* a zero size section is just empty. Ok, no error */ continue; } dbg->de_debug_loc_index = section_index; dbg->de_debug_loc_size = section_size; } else if (strcmp(scn_name, ".debug_pubnames") == 0) { if (dbg->de_debug_pubnames_index != 0) { DWARF_DBG_ERROR(dbg, DW_DLE_DEBUG_PUBNAMES_DUPLICATE, DW_DLV_ERROR); } if (section_size == 0) { /* a zero size section is just empty. Ok, no error */ continue; } dbg->de_debug_pubnames_index = section_index; dbg->de_debug_pubnames_size = section_size; } else if (strcmp(scn_name, ".debug_str") == 0) { if (dbg->de_debug_str_index != 0) { DWARF_DBG_ERROR(dbg, DW_DLE_DEBUG_STR_DUPLICATE, DW_DLV_ERROR); } if (section_size == 0) { /* a zero size section is just empty. Ok, no error */ continue; } dbg->de_debug_str_index = section_index; dbg->de_debug_str_size = section_size; } else if (strcmp(scn_name, ".debug_funcnames") == 0) { if (dbg->de_debug_funcnames_index != 0) { DWARF_DBG_ERROR(dbg, DW_DLE_DEBUG_FUNCNAMES_DUPLICATE, DW_DLV_ERROR); } if (section_size == 0) { /* a zero size section is just empty. Ok, no error */ continue; } dbg->de_debug_funcnames_index = section_index; dbg->de_debug_funcnames_size = section_size; } else if (strcmp(scn_name, ".debug_typenames") == 0) { if (dbg->de_debug_typenames_index != 0) { DWARF_DBG_ERROR(dbg, DW_DLE_DEBUG_TYPENAMES_DUPLICATE, DW_DLV_ERROR); } if (section_size == 0) { /* a zero size section is just empty. Ok, no error */ continue; } dbg->de_debug_typenames_index = section_index; dbg->de_debug_typenames_size = section_size; } else if (strcmp(scn_name, ".debug_varnames") == 0) { if (dbg->de_debug_varnames_index != 0) { DWARF_DBG_ERROR(dbg, DW_DLE_DEBUG_VARNAMES_DUPLICATE, DW_DLV_ERROR); } if (section_size == 0) { /* a zero size section is just empty. Ok, no error */ continue; } dbg->de_debug_varnames_index = section_index; dbg->de_debug_varnames_size = section_size; } else if (strcmp(scn_name, ".debug_weaknames") == 0) { if (dbg->de_debug_weaknames_index != 0) { DWARF_DBG_ERROR(dbg, DW_DLE_DEBUG_WEAKNAMES_DUPLICATE, DW_DLV_ERROR); } if (section_size == 0) { /* a zero size section is just empty. Ok, no error */ continue; } dbg->de_debug_weaknames_index = section_index; dbg->de_debug_weaknames_size = section_size; } else if (strcmp(scn_name, ".debug_macinfo") == 0) { if (dbg->de_debug_macinfo_index != 0) { DWARF_DBG_ERROR(dbg, DW_DLE_DEBUG_MACINFO_DUPLICATE, DW_DLV_ERROR); } if (section_size == 0) { /* a zero size section is just empty. Ok, no error */ continue; } dbg->de_debug_macinfo_index = section_index; dbg->de_debug_macinfo_size = section_size; } } if (foundDwarf) { return DW_DLV_OK; } return (DW_DLV_NO_ENTRY); }
bool saveSharedLibrary::readNewLib(){ Elf32_Shdr *newsh, *shdr; Elf_Scn *scn, *newScn; Elf32_Ehdr *ehdr; Elf32_Phdr *oldPhdr; Elf_Data *strdata, *newdata, *olddata; if ((ehdr = elf32_getehdr(newElf)) == NULL){ fprintf(stderr," FAILED obtaining ehdr readNewLib\n"); return false; } if((scn = elf_getscn(newElf, ehdr->e_shstrndx)) != NULL){ if((strdata = elf_getdata(scn, NULL)) == NULL){ fprintf(stderr," Failed obtaining .shstrtab data buffer \n"); return false; } }else{ fprintf(stderr," FAILED obtaining .shstrtab scn\n"); } unsigned int newScnName =0; scn = NULL; Elf_Data shstrtabData; #if defined(i386_unknown_linux2_0) \ || defined(x86_64_unknown_linux2_4) /* save the PHDR from the library */ oldPhdr = elf32_getphdr(newElf); Elf32_Phdr phdrBuffer[ehdr->e_phnum]; /* copy it over to a buffer because, on linux, we will close newElf and reopen it. This closing of newElf should dealloc the data pointed to by oldPhdr */ memcpy(phdrBuffer, oldPhdr, ehdr->e_phnum * ehdr->e_phentsize); #endif for (int cnt = 1; (scn = elf_nextscn(newElf, scn)); cnt++) { //copy sections from newElf to newElf. shdr = elf32_getshdr(scn); olddata = elf_getdata(scn,NULL); if(!strcmp( (char *)strdata->d_buf + shdr->sh_name, ".text")){ textAddr = shdr->sh_addr; textData = olddata; textSize = shdr->sh_size; } if(!strcmp( (char*) strdata->d_buf + shdr->sh_name, ".shstrtab")){ const char *secname =".dyninst_mutated\0"; shstrtabData.d_size = olddata->d_size+strlen(secname)+1; newShstrtabData_d_buf = new char[shstrtabData.d_size]; shstrtabData.d_buf = newShstrtabData_d_buf; memcpy( shstrtabData.d_buf, olddata->d_buf, olddata->d_size); memcpy(&(((char*) shstrtabData.d_buf)[olddata->d_size]), secname, strlen(secname)+1); newScnName = olddata->d_size; olddata->d_buf = shstrtabData.d_buf; olddata->d_size = shstrtabData.d_size; shdr->sh_size +=strlen(secname)+1; /* if the section header table is past this section in the ELF file, calculate the new offset*/ if(ehdr ->e_shoff > shdr->sh_offset){ ehdr->e_shoff += strlen(secname)+1; } elf_flagscn(scn,ELF_C_SET,ELF_F_DIRTY); } } ehdr-> e_shnum++; newScn = elf_newscn(newElf); newsh = elf32_getshdr(newScn); newsh->sh_name = newScnName; newsh->sh_type = SHT_NOBITS; // SHT_NOTE; newsh->sh_flags=0; newsh->sh_addr = 0x0; newsh->sh_offset = shdr->sh_offset; newsh->sh_size=0; newsh->sh_link=0; newsh->sh_info=0; newsh->sh_addralign = 0x1; //Values 0 and 1 mean the section has no alignment constraints. newsh->sh_entsize = 0; newdata = elf_newdata(newScn); newdata->d_size =0; newdata->d_buf=0; elf_update(newElf, ELF_C_NULL); /* elfutils on linux does not write data back to an ELF file you have opened correctly. Specifically, if you add a section the section's section header has space allocated for it in the file but no data is written to it. lovely, eh? to combat this, we reopen the file we just closed, and find the empty section header and fill it with data. */ #if defined(i386_unknown_linux2_0) \ || defined(x86_64_unknown_linux2_4) elf_update(newElf, ELF_C_WRITE); elf_end(newElf); P_close(newfd); if((newfd = (open(newpathname, O_RDWR)))==-1){ fprintf(stderr,"%s[%d]: cannot open new SO : %s\n",FILE__, __LINE__, newpathname); perror(" FAIL "); return false;; } if((newElf = elf_begin(newfd, ELF_C_RDWR, NULL)) ==NULL){ fprintf(stderr,"cannot open ELF %s \n", newpathname); return false;; } if ((ehdr = elf32_getehdr(newElf)) == NULL){ fprintf(stderr," FAILED obtaining ehdr readNewLib\n"); return false; } if((scn = elf_getscn(newElf, ehdr->e_shstrndx)) != NULL){ if((strdata = elf_getdata(scn, NULL)) == NULL){ fprintf(stderr," Failed obtaining .shstrtab data buffer \n"); return false; } }else{ fprintf(stderr," FAILED obtaining .shstrtab scn\n"); } scn = NULL; bool foundText=false; for (int cnt = 1; (scn = elf_nextscn(newElf, scn)); cnt++) { //copy sections from newElf to newElf. shdr = elf32_getshdr(scn); olddata = elf_getdata(scn,NULL); if(!foundText && !strcmp( (char *)strdata->d_buf + shdr->sh_name, ".text")){ textAddr = shdr->sh_addr; textData = olddata; textSize = shdr->sh_size; elf_flagscn(scn,ELF_C_SET,ELF_F_DIRTY); foundText = true; } } /**UPDATE THE LAST SHDR **/ memset(shdr,'\0', sizeof(Elf32_Shdr)); shdr->sh_name = newScnName; shdr->sh_addr = 0x0; shdr->sh_type = 7; /* update the PHDR, well just make sure it is reset to what was in the original library */ Elf32_Phdr *newPhdr = elf32_getphdr(newElf); memcpy(newPhdr,phdrBuffer, ehdr->e_phnum * ehdr->e_phentsize); /* be extra sure, set the DIRTY flag */ elf_flagphdr(newElf, ELF_C_SET,ELF_F_DIRTY); elf_flagscn(scn,ELF_C_SET,ELF_F_DIRTY); elf_update(newElf, ELF_C_NULL); #endif return true; }
/** * @brief Parse a .elf file into the section cache * * Parse a .elf file and extract the text (code) and data segments, creating * code and data segments in the cache. * * @param filename The pathanme of the .elf file * @param start_address Pointer to the TFTF start_address field. This will * be set to the .elf file entrypoint (e_entry) if not already set * by the "--start" parameter. * @param start_symbol Name of the symbol to use for the TFTF start_address * field, or NULL indicating not to use one. * * @returns True if successful, false otherwise. */ bool load_elf(const char * filename, uint32_t * start_address, const char *start_symbol) { bool success = false; int fd = -1; Elf *elf = NULL; Elf_Scn *scn = NULL; size_t shstrndx; int sections_created = 0; GElf_Addr start_symbol_addr; Elf32_Ehdr * ehdr = NULL; if (!filename) { goto cleanup; } if (elf_version(EV_CURRENT) == EV_NONE) { fprintf(stderr, "ELF library initialization failed: %s\n", elf_errmsg(-1)); goto cleanup; } if ((fd = open(filename, O_RDONLY, 0)) < 0) { fprintf(stderr, "ERROR: Can't open '%s' (err %d)\n", filename, errno); goto cleanup; } if ((elf = elf_begin(fd, ELF_C_READ, NULL)) == NULL) { fprintf(stderr, "elf_begin() failed: %s\n", elf_errmsg(-1)); goto cleanup; } if (elf_kind(elf) != ELF_K_ELF) { fprintf(stderr, "%s is not an ELF object\n", filename); goto cleanup; } if (elf_getshdrstrndx(elf, &shstrndx) != 0) { fprintf(stderr, "elf_getshdrstrndx() failed: %s\n", elf_errmsg(-1)); goto cleanup; } /** * Extract the .text and .data segments and add them to the section cache */ scn = elf_getscn_byname(elf, ".text"); if (scn != NULL) { success = elf_add_section_cache_entry(scn, TFTF_SECTION_RAW_CODE); if (success) { /* Extract entrypoint (e_entry) */ ehdr = elf32_getehdr(elf); if (ehdr != NULL) { if (start_address && *start_address == 0) { *start_address = (uint32_t)ehdr->e_entry; } } else { fprintf(stderr, "ERROR: elf32_getehdr failed\n"); } sections_created++; } } scn = elf_getscn_byname(elf, ".data"); if (scn != NULL) { success = elf_add_section_cache_entry(scn, TFTF_SECTION_RAW_DATA); if (success) { sections_created++; } } if (start_symbol && start_address) { if (*start_address == ehdr->e_entry) { start_symbol_addr = elf_getsymaddr_byname(elf, start_symbol); if (start_symbol_addr) { *start_address = start_symbol_addr; } } else { fprintf(stderr, "ERROR: explicit start address (0x%.8x) and \ explicit start symbol (%s) both supplied\n", *start_address, start_symbol); success = false; } } if (sections_created >= 1) { success = true; } else { fprintf(stderr, "ERROR: no code or data segments in '%s'\n", filename); success = false; } cleanup: if (elf != NULL) { elf_end(elf); } if (fd != -1) { close(fd); } return success; }
void leaky::readSymbols(const char *fileName) { int fd = ::open(fileName, O_RDONLY); if (fd < 0) { fprintf(stderr, "%s: unable to open \"%s\"\n", applicationName, fileName); exit(-1); } elf_version(EV_CURRENT); Elf *elf = elf_begin(fd, ELF_C_READ, 0); if (!elf) { fprintf(stderr, "%s: \"%s\": has no symbol table\n", applicationName, fileName); exit(-1); } long alloced = 10000; Symbol* syms = (Symbol*) malloc(sizeof(Symbol) * 10000); Symbol* sp = syms; Symbol* last = syms + alloced; // Get each of the relevant sections and add them to the list of // symbols. Elf32_Ehdr *ehdr = elf32_getehdr(elf); if (!ehdr) { fprintf(stderr, "%s: elf library lossage\n", applicationName); exit(-1); } #if 0 Elf32_Half ndx = ehdr->e_shstrndx; #endif Elf_Scn *scn = 0; int strtabndx = -1; for (int i = 1; (scn = elf_nextscn(elf, scn)) != 0; i++) { Elf32_Shdr *shdr = elf32_getshdr(scn); #if 0 char *name = elf_strptr(elf, ndx, (size_t) shdr->sh_name); printf("Section %s (%d 0x%x)\n", name ? name : "(null)", shdr->sh_type, shdr->sh_type); #endif if (shdr->sh_type == SHT_STRTAB) { /* We assume here that string tables preceed symbol tables... */ strtabndx = i; continue; } #if 0 if (shdr->sh_type == SHT_DYNAMIC) { /* Dynamic */ Elf_Data *data = elf_getdata(scn, 0); if (!data || !data->d_size) { printf("No data..."); continue; } Elf32_Dyn *dyn = (Elf32_Dyn*) data->d_buf; Elf32_Dyn *lastdyn = (Elf32_Dyn*) ((char*) data->d_buf + data->d_size); for (; dyn < lastdyn; dyn++) { printf("tag=%d value=0x%x\n", dyn->d_tag, dyn->d_un.d_val); } } else #endif if ((shdr->sh_type == SHT_SYMTAB) || (shdr->sh_type == SHT_DYNSYM)) { /* Symbol table */ Elf_Data *data = elf_getdata(scn, 0); if (!data || !data->d_size) { printf("No data..."); continue; } /* In theory we now have the symbols... */ Elf32_Sym *esym = (Elf32_Sym*) data->d_buf; Elf32_Sym *lastsym = (Elf32_Sym*) ((char*) data->d_buf + data->d_size); for (; esym < lastsym; esym++) { #if 0 char *nm = elf_strptr(elf, strtabndx, (size_t)esym->st_name); printf("%20s 0x%08x %02x %02x\n", nm, esym->st_value, ELF32_ST_BIND(esym->st_info), ELF32_ST_TYPE(esym->st_info)); #endif if ((esym->st_value == 0) || (ELF32_ST_BIND(esym->st_info) == STB_WEAK) || (ELF32_ST_BIND(esym->st_info) == STB_NUM) || (ELF32_ST_TYPE(esym->st_info) != STT_FUNC)) { continue; } #if 1 char *nm = elf_strptr(elf, strtabndx, (size_t)esym->st_name); #endif sp->name = nm ? strdup(nm) : "(no name)"; sp->address = esym->st_value; sp++; if (sp >= last) { long n = alloced + 10000; syms = (Symbol*) realloc(syms, (size_t) (sizeof(Symbol) * n)); last = syms + n; sp = syms + alloced; alloced = n; } } } } int interesting = sp - syms; if (!quiet) { printf("Total of %d symbols\n", interesting); } usefulSymbols = interesting; externalSymbols = syms; }
unsigned int *NWMouse_findcookie(char *filename) { Elf *elf_ptr; int fd; Elf32_Ehdr *ehdr; Elf_Scn *section; Elf32_Shdr *section_header; Elf32_Shdr *code_header; unsigned char *buffer, *entry; unsigned char *buffer_ptr; unsigned char *cookie_address; struct stat statbuf; static unsigned int calls[7]; /* Return things in this array */ unsigned int *ptr_calls; int instruction_size; struct instr instruction; int i, j; unsigned int *table_ptr; int done; /* Dynamic Linking, we only use this stuff if we need it */ void *dlhandle; dlhandle = dlopen("nwmouse/libdis/libdisasm.so", RTLD_NOW); if( !dlhandle ) { fprintf(stderr, "ERROR: NWMouse: (cookie) dlopen of libdisasm.so failed: %s\n", dlerror()); abort(); } NWMouse_disassemble_init_ptr = (int (*)())dlsym(dlhandle, "disassemble_init"); if( NWMouse_disassemble_init_ptr == NULL ) { fprintf(stderr, "ERROR: NWMouse: (cookie) dlsym(disassemble_init) failed: %s\n", dlerror()); abort(); } NWMouse_disassemble_address_ptr = (int (*)())dlsym(dlhandle, "disassemble_address"); if( NWMouse_disassemble_address_ptr == NULL ) { fprintf(stderr, "ERROR: NWMouse: (cookie) dlsym(disassemble_address) failed: %s\n", dlerror()); abort(); } NWMouse_disassemble_cleanup_ptr = (int (*)())dlsym(dlhandle, "disassemble_cleanup"); if( NWMouse_disassemble_cleanup_ptr == NULL ) { fprintf(stderr, "ERROR: NWMouse: (cookie) dlsym(disassemble_cleanup) failed: %s\n", dlerror()); abort(); } NWMouse_disassemble_init_ptr(0, INTEL_SYNTAX); /* Initialize the elves. */ if (elf_version(EV_CURRENT) == EV_NONE) { fprintf(stderr, "ERROR: NWMouse: (cookie) libelf version mismatch.\n"); abort(); } /* open library */ fd = open(filename, O_RDONLY); if( fd < 0 ) { fprintf(stderr, "ERROR: NWMouse: (cookie) Unable to open shared library: %s (%d)\n", filename, errno); abort(); } if( fstat(fd, &statbuf) < 0 ) { fprintf(stderr, "ERROR: NWMouse: (cookie) Unable to stat shared library: %s (%d) Howd that happen?\n", filename, errno); abort(); } buffer = mmap(0, statbuf.st_size, PROT_READ, MAP_SHARED, fd, 0); if( buffer == NULL ) { fprintf(stderr, "ERROR: NWMouse: (cookie) Unable to mmap executable: %s (%d)\n", filename, errno); abort(); } elf_ptr = elf_begin(fd, ELF_C_READ, (Elf *)0); if( elf_ptr == NULL) { fprintf(stderr, "ERROR: NWMouse: (cookie) elf_begin failed: %s.\n", elf_errmsg(elf_errno())); abort(); } /* Get the Header */ if ( (ehdr = elf32_getehdr(elf_ptr)) == NULL) { fprintf(stderr, "ERROR: NWMouse: (cookie) Unable to get Elf header: %s\n", elf_errmsg(elf_errno()) ); abort(); } section = 0; code_header = NULL; while( (section = elf_nextscn( elf_ptr, section )) ) { section_header = elf32_getshdr(section); if( ehdr->e_entry >= section_header->sh_addr && ehdr->e_entry < (section_header->sh_addr + section_header->sh_size)) { code_header = section_header; break; } } if( code_header == NULL ) { fprintf(stderr, "ERROR: NWMouse: (cookie) Unable to locate appropriate code section.\n"); abort(); } /* Found start of program */ entry = (unsigned char *)ehdr->e_entry - (code_header->sh_addr - code_header->sh_offset); fprintf(stderr, "NOTICE: NWMouse: (cookie) Entry point determined: %p\n", entry); buffer_ptr = (unsigned char *) (int)entry + (int)buffer; calls[0] = (NWMouse_search(buffer_ptr, (unsigned char *)ehdr->e_entry, code_header->sh_size, NWMouse_cookie0, 0, -1, 1))[0]; fprintf(stderr, "NOTICE: NWMouse: (cookie) Cookie0 location: 0x%08x\n", (unsigned int)calls[0] + (unsigned int)code_header->sh_addr); ptr_calls = NWMouse_search(buffer_ptr, (unsigned char *)ehdr->e_entry, code_header->sh_size, NWMouse_cookie1, 0, 1, 1); calls[1] = ptr_calls[0]; calls[2] = ptr_calls[1]; instruction_size = NWMouse_disassemble_address_ptr((char *)buffer_ptr + calls[2], &instruction ); if( ! instruction_size ) { fprintf(stderr, "ERROR: NWMouse: (cookie) Curious: Invalid instruction disassembled: %08x\n", calls[2]); fprintf(stderr, "ERROR: NWMouse: (cookie) This really shouldn't happen.\n"); fprintf(stderr, "ERROR: NWMouse: (cookie) Please contact David Holland ([email protected])\n"); abort(); } if( strcmp(instruction.mnemonic, "mov") || strtol( instruction.src, (char **)NULL, 16) < code_header->sh_addr ) { fprintf(stderr, "ERROR: NWMouse: (cookie) Unexpected opcode found: %s %s\n", instruction.mnemonic, instruction.src); fprintf(stderr, "ERROR: NWMouse: (cookie) Please contact David Holland ([email protected])\n"); abort(); } calls[2] = strtol( instruction.src, (char **)NULL, 16); fprintf(stderr, "NOTICE: NWMouse: (cookie) Cookie1 location: 0x%08x\n", (unsigned int)calls[1] + (unsigned int)code_header->sh_addr); fprintf(stderr, "NOTICE: NWMouse: (cookie) Cookie2 location: 0x%08x\n", (unsigned int)calls[2]); calls[3] = (NWMouse_search(buffer_ptr, (unsigned char *)ehdr->e_entry, code_header->sh_size, NWMouse_cookie2, 0, 1, 1))[0]; fprintf(stderr, "NOTICE: NWMouse: (cookie) Cookie3 location: 0x%08x\n", (unsigned int)calls[3] + (unsigned int)code_header->sh_addr); calls[4] = (NWMouse_search(buffer_ptr, (unsigned char *)ehdr->e_entry, code_header->sh_size, NWMouse_cookie3, 0, 1, 1))[0]; fprintf(stderr, "NOTICE: NWMouse: (cookie) Cookie4 location: 0x%08x\n", (unsigned int)calls[4] + (unsigned int)code_header->sh_addr); calls[5] = (NWMouse_search(buffer_ptr, (unsigned char *)ehdr->e_entry, code_header->sh_size, NWMouse_cookie4, 0, 1, 1))[1]; fprintf(stderr, "NOTICE: NWMouse: (cookie) Cookie5 location: 0x%08x\n", (unsigned int)calls[5] + (unsigned int)code_header->sh_addr); /* Calls "loaded". Correct into virtual addresses */ calls[0] = calls[0] + code_header->sh_addr; /* Function outside of end of table */ calls[1] = calls[1] + code_header->sh_addr; /* Constructor */ // calls[2] = calls[2] + code_header->sh_addr; - Do not add to this one - Already corrected. /* Table Start */ calls[3] = calls[3] + code_header->sh_addr; /* Render */ calls[4] = calls[4] + code_header->sh_addr; /* Texture */ calls[5] = calls[5] + code_header->sh_addr; /* Constructed object */ /* Find the Orientation function, ugh... */ fprintf(stderr, "NOTICE: NWMouse: (cookie) Searching for proper Orientation function, this may take a while...\n"); /* Partially cloned from nwmouse.c */ table_ptr = (void *)calls[2]; i = 1; done = 0; while( table_ptr[i] != 0x0 && table_ptr[i] != calls[0] && !done ) { calls[6] = (NWMouse_search(buffer_ptr, /* Secondary in memory copy */ (unsigned char *)ehdr->e_entry, /* Kinda useless, unless _NOTDEF_ defd */ table_ptr[i] - code_header->sh_addr + NWMouse_cookie5_size, /* routine length. - hardcoded - blah */ NWMouse_cookie5, /* Search cookie */ table_ptr[i] - code_header->sh_addr, /* start position */ 1, /* First occurance */ 0 /* Abort if not found? */ ))[0]; if( calls[6] != 0 ) { j = 0; while( j < NWMouse_cookie5_size ) { memset(&instruction, 0, sizeof(struct code)); instruction_size = NWMouse_disassemble_address_ptr((char *)buffer_ptr + calls[6] + j, &instruction ); if( !instruction_size ) { fprintf(stderr, "ERROR: NWMouse: (cookie) Huh...: Invalid instruction disassembled: %08x\n", calls[2]); fprintf(stderr, "ERROR: NWMouse: (cookie) This really shouldn't happen.\n"); fprintf(stderr, "ERROR: NWMouse: (cookie) Please contact David Holland ([email protected])\n"); abort(); } if( !strcmp(instruction.mnemonic, "mov") && strtol( instruction.src, (char **)NULL, 16) == 0x4 && !strcmp(instruction.dest, "ecx") ) { done = 1; j = NWMouse_cookie5_size; } j += instruction_size; } } i++; } fprintf(stderr, "NOTICE: NWMouse: (cookie) Cookie6 location: 0x%08x\n", (unsigned int)calls[6] + (unsigned int)code_header->sh_addr); calls[6] = calls[6] + code_header->sh_addr; /* Set Orientation */ elf_end(elf_ptr); munmap(buffer, statbuf.st_size ); close(fd); dlclose(dlhandle); return(calls); }
u_long symval(char *lib, char *name) { int fd; int i, nsym; u_long addr = 0; Elf32_Shdr *shdr; Elf *elf; Elf_Scn *scn = (Elf_Scn *)0; Elf32_Ehdr *ehdr; Elf_Data *dp; Elf32_Sym *symbol; char *np; fd = open(lib, O_RDONLY); if (fd < 0) { perror("open"); exit(1); } /* Initializations, see elf(3E) */ (void) elf_version(EV_CURRENT); elf = elf_begin(fd, ELF_C_READ, 0); if (elf == (Elf *)0) elferr(); ehdr = elf32_getehdr(elf); if (ehdr == (Elf32_Ehdr*)0) elferr(); /* * Loop through sections looking for the dynamic symbol table. */ while ((scn = elf_nextscn(elf, scn))) { shdr = elf32_getshdr(scn); if (shdr == (Elf32_Shdr *)0) elferr(); if (shdr->sh_type == SHT_DYNSYM) break; } if (scn == (Elf_Scn *)0) { fprintf(stderr, "%s: dynamic symbol table not found\n", prog); exit(1); } dp = elf_getdata(scn, (Elf_Data *)0); if (dp == (Elf_Data *)0) elferr(); if (dp->d_size == 0) { fprintf(stderr, "%s: .dynamic symbol table empty\n", prog); exit(1); } symbol = (Elf32_Sym *)dp->d_buf; nsym = dp->d_size / sizeof (*symbol); for (i = 0; i < nsym; i++) { np = elf_strptr(elf, shdr->sh_link, (size_t) symbol[i].st_name); if (np && !strcmp(np, name)) break; } if (i < nsym) addr = symbol[i].st_value; (void) elf_end(elf); (void) close(fd); return (addr); }
// read symbol table from elf_file struct symtab *build_symtab(const char *elf_file) { int fd; Elf *elf; Elf32_Ehdr *ehdr; char *names; struct symtab *symtab = NULL; if ((fd = open(elf_file, O_RDONLY)) < 0) { perror("open"); return NULL; } elf = elf_begin(fd, ELF_C_READ, NULL); if (elf == NULL || elf_kind(elf) != ELF_K_ELF) { // not an elf close(fd); return NULL; } // read ELF header if ((ehdr = elf32_getehdr(elf)) != NULL) { Elf_Scn *scn; struct elf_section *scn_cache, *scn_cache_ptr; int cnt; // read section headers into scn_cache scn_cache = (struct elf_section *) malloc(ehdr->e_shnum * sizeof(struct elf_section)); scn_cache_ptr = scn_cache; scn_cache_ptr++; for (scn = NULL; scn = elf_nextscn(elf, scn); scn_cache_ptr++) { scn_cache_ptr->c_shdr = elf32_getshdr(scn); scn_cache_ptr->c_data = elf_getdata(scn, NULL); } for (cnt = 1; cnt < ehdr->e_shnum; cnt++) { Elf32_Shdr *shdr = scn_cache[cnt].c_shdr; if (shdr->sh_type == SHT_SYMTAB) { Elf32_Sym *syms; int j, n, rslt; size_t size; // FIXME: there could be multiple data buffers associated with the // same ELF section. Here we can handle only one buffer. See man page // for elf_getdata on Solaris. guarantee(symtab == NULL, "multiple symtab"); symtab = (struct symtab *)calloc(1, sizeof(struct symtab)); // the symbol table syms = (Elf32_Sym *)scn_cache[cnt].c_data->d_buf; // number of symbols n = shdr->sh_size / shdr->sh_entsize; // create hash table, we use hcreate_r, hsearch_r and hdestroy_r to // manipulate the hash table. symtab->hash_table = calloc(1, sizeof(struct hsearch_data)); rslt = hcreate_r(n, symtab->hash_table); guarantee(rslt, "unexpected failure: hcreate_r"); // shdr->sh_link points to the section that contains the actual strings // for symbol names. the st_name field in Elf32_Sym is just the // string table index. we make a copy of the string table so the // strings will not be destroyed by elf_end. size = scn_cache[shdr->sh_link].c_data->d_size; symtab->strs = (char *)malloc(size); memcpy(symtab->strs, scn_cache[shdr->sh_link].c_data->d_buf, size); // allocate memory for storing symbol offset and size; symtab->symbols = (struct elf_symbol *)malloc(n * sizeof(struct elf_symbol)); // copy symbols info our symtab and enter them info the hash table for (j = 0; j < n; j++, syms++) { ENTRY item, *ret; char *sym_name = symtab->strs + syms->st_name; symtab->symbols[j].name = sym_name; symtab->symbols[j].offset = syms->st_value; symtab->symbols[j].size = syms->st_size; // skip empty strings if (*sym_name == '\0') continue; item.key = sym_name; item.data = (void *)&(symtab->symbols[j]); hsearch_r(item, ENTER, &ret, symtab->hash_table); } } } free(scn_cache); } elf_end(elf); close(fd); return symtab; }
/* Extract ROM code+data from an ELF file and convert it into a C array */ int main(int argc,char *argv[]) { unsigned char buffer[8]; m_uint32_t vaddr,start; Elf32_Ehdr *ehdr; Elf32_Phdr *phdr; Elf *img_elf; size_t len,clen; int i,j,fd; FILE *bfd,*fd_out; if (argc != 4) { fprintf(stderr,"Usage: %s <input_file> <output_file> <addr>\n",argv[0]); exit(EXIT_FAILURE); } start = strtoul(argv[3],NULL,0); if ((fd = open(argv[1],O_RDONLY)) == -1) return(-1); if (elf_version(EV_CURRENT) == EV_NONE) { fprintf(stderr,"load_elf_image: library out of date\n"); return(-1); } if (!(img_elf = elf_begin(fd,ELF_C_READ,NULL))) { fprintf(stderr,"load_elf_image: elf_begin: %s\n", elf_errmsg(elf_errno())); return(-1); } if (!(phdr = elf32_getphdr(img_elf))) { fprintf(stderr,"load_elf_image: elf32_getphdr: %s\n", elf_errmsg(elf_errno())); return(-1); } if (!(fd_out = fopen(argv[2],"w"))) { fprintf(stderr,"Unable to create file \"%s\"\n",argv[2]); exit(EXIT_FAILURE); } ehdr = elf32_getehdr(img_elf); phdr = elf32_getphdr(img_elf); printf("Extracting ROM from ELF file '%s'...\n",argv[1]); bfd = fdopen(fd,"r"); if (!bfd) { perror("load_elf_image: fdopen"); return(-1); } for(i=0;i<ehdr->e_phnum;i++,phdr++) { fseek(bfd,phdr->p_offset,SEEK_SET); vaddr = (m_uint64_t)phdr->p_vaddr; len = phdr->p_filesz; if (vaddr != start) continue; while(len > 0) { clen = fread(buffer,1,sizeof(buffer),bfd); if (clen == 0) break; fprintf(fd_out," "); for(j=0;j<clen;j++) fprintf(fd_out,"0x%2.2x, ",buffer[j]); fprintf(fd_out,"\n"); len -= clen; } } fclose(fd_out); return(0); }
int main (int argc, char *argv[]) { Elf *elf; int result = 0; int fd; char fname[] = "newfile-XXXXXX"; fd = mkstemp (fname); if (fd == -1) { printf ("cannot create temporary file: %m\n"); exit (1); } /* Remove the file when we exit. */ unlink (fname); elf_version (EV_CURRENT); elf = elf_begin (fd, ELF_C_WRITE, NULL); if (elf == NULL) { printf ("elf_begin: %s\n", elf_errmsg (-1)); result = 1; } else { if (elf32_newehdr (elf) == NULL) { printf ("elf32_newehdr: %s\n", elf_errmsg (-1)); result = 1; } else { Elf32_Ehdr *ehdr = elf32_getehdr (elf); if (ehdr == NULL) { printf ("elf32_getehdr: %s\n", elf_errmsg (-1)); result = 1; } else { int i; if (argc > 1) /* Use argc as a debugging flag. */ print_ehdr (ehdr); /* Some tests. */ for (i = 0; i < EI_NIDENT; ++i) if (ehdr->e_ident[i] != 0) { printf ("ehdr->e_ident[%d] != 0\n", i); result = 1; break; } #define VALUE_TEST(name, val) \ if (ehdr->name != val) \ { \ printf ("ehdr->%s != %d\n", #name, val); \ result = 1; \ } #define ZERO_TEST(name) VALUE_TEST (name, 0) ZERO_TEST (e_type); ZERO_TEST (e_machine); ZERO_TEST (e_version); ZERO_TEST (e_entry); ZERO_TEST (e_phoff); ZERO_TEST (e_shoff); ZERO_TEST (e_flags); ZERO_TEST (e_ehsize); ZERO_TEST (e_phentsize); ZERO_TEST (e_phnum); ZERO_TEST (e_shentsize); ZERO_TEST (e_shnum); ZERO_TEST (e_shstrndx); if (elf32_newphdr (elf, 10) == NULL) { printf ("elf32_newphdr: %s\n", elf_errmsg (-1)); result = 1; } else { if (argc > 1) print_ehdr (ehdr); ehdr = elf32_getehdr (elf); if (ehdr == NULL) { printf ("elf32_getehdr (#2): %s\n", elf_errmsg (-1)); result = 1; } else { ZERO_TEST (e_type); ZERO_TEST (e_machine); ZERO_TEST (e_version); ZERO_TEST (e_entry); ZERO_TEST (e_phoff); ZERO_TEST (e_shoff); ZERO_TEST (e_flags); ZERO_TEST (e_ehsize); VALUE_TEST (e_phentsize, (int) sizeof (Elf32_Phdr)); VALUE_TEST (e_phnum, 10); ZERO_TEST (e_shentsize); ZERO_TEST (e_shnum); ZERO_TEST (e_shstrndx); } } } } (void) elf_end (elf); } return result; }
int xlate_named_init_elf(Elf * elf, const char *section_name, xlate_table_con * ret_tab_ptr) { int retstatus = XLATE_TB_STATUS_NO_ERROR; xlate_table_con newtab = 0; Elf_Scn *scn = 0; int is64bit = 0; char *ident; size_t identsize; Elf_Scn *xlscn = 0; Elf64_Shdr *shdr64 = 0; Elf32_Shdr *shdr32 = 0; Elf32_Ehdr *ehdr32 = 0; Elf64_Ehdr *ehdr64 = 0; Elf_Data *xlatedata = 0; int stringindex = 0; char * sec_name; if(elf_kind(elf) != ELF_K_ELF) { return XLATE_TB_STATUS_NOT_ELF; } ident = elf_getident(elf,&identsize); if(ident == 0 || identsize < EI_NIDENT) { return XLATE_TB_STATUS_ELF_IDENT_BAD; } if(ident[EI_CLASS] == ELFCLASS64) { is64bit = 1; } if(is64bit) { ehdr64 = elf64_getehdr(elf); if(ehdr64 == 0 ) { return XLATE_TB_STATUS_ELF_EHDR_BAD; } stringindex = ehdr64->e_shstrndx; } else { ehdr32 = elf32_getehdr(elf); if(ehdr32 == 0 ) { return XLATE_TB_STATUS_ELF_EHDR_BAD; } stringindex = ehdr32->e_shstrndx; } for(scn = elf_nextscn(elf,scn); scn != 0 && xlscn == 0 ; scn = elf_nextscn(elf,scn)) { if(is64bit) { shdr64 = elf64_getshdr(scn); if(shdr64 == 0) { return XLATE_TB_STATUS_ELF_SHDR_BAD; } sec_name = elf_strptr(elf,stringindex,shdr64->sh_name); if(sec_name == 0) { return XLATE_TB_STATUS_ELF_STRPTR_BAD; } if(shdr64->sh_type != SHT_MIPS_XLATE && shdr64->sh_type != SHT_MIPS_XLATE_DEBUG && shdr64->sh_type != SHT_MIPS_XLATE_OLD ) { continue; } if(!streq(section_name,sec_name)) { continue; } xlscn = scn; break; } else { shdr32 = elf32_getshdr(scn); if(shdr32 == 0) { return XLATE_TB_STATUS_ELF_SHDR_BAD; } sec_name = elf_strptr(elf,stringindex,shdr32->sh_name); if(sec_name == 0) { return XLATE_TB_STATUS_ELF_STRPTR_BAD; } if(shdr32->sh_type != SHT_MIPS_XLATE && shdr32->sh_type != SHT_MIPS_XLATE_DEBUG && shdr32->sh_type != SHT_MIPS_XLATE_OLD ) { continue; } if(!streq(section_name,sec_name)) { continue; } xlscn = scn; break; } } if(xlscn == 0) { return XLATE_TB_STATUS_NO_XLATE; } xlatedata = elf_getdata(xlscn,NULL); if(xlatedata == NULL || xlatedata->d_size == 0) { return XLATE_TB_STATUS_NO_XLATE_DATA; } newtab = (xlate_table_con)malloc(sizeof(struct xlate_table_con_s)); if(newtab == NULL) { return XLATE_TB_STATUS_ALLOC_FAIL; } bzero(newtab,sizeof(struct xlate_table_con_s)); newtab->xc_elf = elf; newtab->xc_section_data = xlatedata->d_buf; newtab->xc_data_size = xlatedata->d_size; if(newtab->xc_data_size != xlatedata->d_size) { /* we have a gigantic section and are compiled only 32 bit. ** we simply cannot handle and I don't think the ** mmap would have worked anyway so we cannot really ** get here. */ free(newtab); return XLATE_TB_STATUS_SECTION_TOO_BIG; } retstatus = _xlate_fill_in_table_data(newtab,is64bit); if(retstatus != XLATE_TB_STATUS_NO_ERROR) { free(newtab); return retstatus; } newtab->xc_valid_table = VALID_TABLE_MAGIC; *ret_tab_ptr = newtab; return retstatus; }
static OBJECT_FILE *object_open( const char *file_name ) { OBJECT_FILE *file; Elf_Scn *section; Elf_Data *symtab; Elf32_Shdr *shdr; int compare; // search for the file in the list of already open objects for (file = objects ; file ; file = file->next_object) { compare = strcmp( file_name, file->name ); if ( compare == 0 ) // if we found it { return file; } else if ( compare < 0 ) // if we didn't find it { break; } } // try to add a new file to the list of open objects file = (OBJECT_FILE *)malloc( sizeof(OBJECT_FILE) ); assert(file); if ( file ) { memset( file, 0, sizeof(*file) ); if ((file->fd = open(file_name, O_RDONLY | O_BINARY)) != -1) { file->elf = elf_begin(file->fd, ELF_C_READ, NULL); if (file->elf) { file->ehdr = elf32_getehdr(file->elf); if (file->ehdr) { if ( file->ehdr->e_machine == out_file_machine ) { Elf_Data *string_data; OBJECT_FILE **scan; int compare; exec_getsection( file->elf, file->ehdr->e_shstrndx, NULL, &string_data ); file->strings = (char *)string_data->d_buf; file->name = strdup( file_name ); section = NULL; while ((section = elf_nextscn(file->elf, section)) != 0) { shdr = elf32_getshdr(section); elfcheck( shdr != NULL ); if (shdr->sh_type == SHT_SYMTAB) { symtab = exec_getdata(section); file->symbols = symtab->d_buf; file->symbol_count = symtab->d_size / sizeof(Elf32_Sym); file->first_global = shdr->sh_info; file->string_index = shdr->sh_link; if ( file->symbol_count > max_symbols ) { max_symbols = file->symbol_count; } break; } } // ordered insert into the file list assert( file->name ); for ( scan = &objects ; *scan ; scan = &(*scan)->next_object ) { compare = strcmp(file_name, (*scan)->name ); // if this file already exists we should have found // it instead of creating it assert( compare != 0 ); if (compare < 0) { break; } } file->next_object = *scan; *scan = file; return file; } else { yyerror( "Input file machine type doesn't match architecture" ); } } else { yyerror( "File %s is not a valid ELF file: %s", file_name, elf_errmsg(-1) ); } elf_end(file->elf); } else { yyerror( "Elf_begin on %s failed: %s", file_name, elf_errmsg(-1) ); } close( file->fd ); } else { yyerror( "File %s not found", file_name ); } free( file ); file = NULL; } return file; }
Func_DWARF *SET_fill_func_dwarf(char *name, uint32_t *func_addr, int len, uint32_t off) { int fd; Elf_Cmd cmd; Elf *arf; /* Used for an archive */ Elf *elf; int ret; if (elf_version(EV_CURRENT) == EV_NONE) { fprintf(stderr, "SET dwarf: libelf.a is out of date\n"); return NULL; } fd = open(name, O_RDONLY); if (fd == -1) { fprintf(stderr, "SET dwarf: Cannot open %s\n", name); return NULL; } /* Function DWARF table */ func_dwarf = (Func_DWARF *) malloc(sizeof(Func_DWARF) * len); if (func_dwarf == NULL) { fprintf(stderr, "SET dwarf: No memory space to allocate DWARF table!\n"); close(fd); return NULL; } memset(func_dwarf, 0, sizeof(Func_DWARF) * len); local_func_addr = func_addr; local_func_len = len; local_offset = off; cmd = ELF_C_READ; arf = elf_begin(fd, cmd, NULL); while ((elf = elf_begin(fd, cmd, arf)) != NULL) { Elf32_Ehdr *eh32; eh32 = elf32_getehdr(elf); if (eh32 == NULL) { fprintf(stderr, "SET dwarf: %s is not a 32-bit ELF file\n", name); goto fail; } else { ret = process_one_file(elf); if (ret != 0) goto fail; } cmd = elf_next(elf); elf_end(elf); } elf_end(arf); close(fd); return func_dwarf; fail: elf_end(elf); elf_end(arf); free(func_dwarf); close(fd); return NULL; }
u_long plt_offset(char *lib, char *func) { int fd; Elf *elf; Elf_Scn *scn = (Elf_Scn *)0; Elf_Data *dp; Elf32_Ehdr *ehdr; Elf32_Rela *relocp = (Elf32_Rela *)0; Elf32_Word pltsz = 0; Elf32_Shdr *shdr; Elf_Scn *symtab; Elf32_Sym *symbols; char *np; u_long offset = 0; u_long plt; fd = open(lib, O_RDONLY); if (fd < 0) { perror("open"); exit(1); } /* Initializations, see elf(3E) */ (void) elf_version(EV_CURRENT); elf = elf_begin(fd, ELF_C_READ, 0); if (elf == (Elf *)0) elferr(); ehdr = elf32_getehdr(elf); if (ehdr == (Elf32_Ehdr *)0) elferr(); /* * Loop through sections looking for the relocation entries * associated with the procedure linkage table. */ while ((scn = elf_nextscn(elf, scn))) { shdr = elf32_getshdr(scn); if (shdr == (Elf32_Shdr *)0) elferr(); if (shdr->sh_type == SHT_RELA) { np = elf_strptr(elf, ehdr->e_shstrndx, (size_t) shdr->sh_name); if (np && !strcmp(np, ".rela.plt")) break; } } if (scn == (Elf_Scn *)0) { fprintf(stderr, "%s: .rela.plt section not found\n", prog); exit(1); } dp = elf_getdata(scn, (Elf_Data *)0); if (dp == (Elf_Data *)0) elferr(); if (dp->d_size == 0) { fprintf(stderr, "%s: .rela.plt section empty\n", prog); exit(1); } /* * The .rela.plt section contains an array of relocation entries, * the first 4 are not used. */ relocp = (Elf32_Rela *)dp->d_buf; pltsz = dp->d_size / sizeof (*relocp); relocp += 4; pltsz -= 4; /* * Find the symbol table associated with this section. */ symtab = elf_getscn(elf, shdr->sh_link); if (symtab == (Elf_Scn *)0) elferr(); shdr = elf32_getshdr(symtab); if (shdr == (Elf32_Shdr *)0) elferr(); dp = elf_getdata(symtab, (Elf_Data *)0); if (dp == (Elf_Data *)0) elferr(); if (dp->d_size == 0) { fprintf(stderr, "%s: dynamic symbol table empty\n", prog); exit(1); } symbols = (Elf32_Sym *)dp->d_buf; /* * Loop through the relocation list, looking for the desired * symbol. */ while (pltsz-- > 0) { Elf32_Word ndx = ELF32_R_SYM(relocp->r_info); np = elf_strptr(elf, shdr->sh_link, (size_t) symbols[ndx].st_name); if (np && !strcmp(np, func)) break; relocp++; } if (relocp) { plt = symval(lib, PLT_SYMBOL); offset = relocp->r_offset - plt; } (void) elf_end(elf); (void) close(fd); return (offset); }
static void print_relocinfo_32 (Dwarf_Debug dbg, Elf *elf) { Elf_Scn *scn = NULL; Elf_Data *data; Elf32_Ehdr *ehdr32; Elf32_Shdr *shdr32; char *scn_name; int i; if ((ehdr32 = elf32_getehdr(elf)) == NULL) { print_error(dbg, "DW_ELF_GETEHDR_ERROR",DW_DLV_OK, err); } while ((scn = elf_nextscn(elf, scn)) != NULL) { if ((shdr32 = elf32_getshdr(scn)) == NULL) { print_error(dbg, "DW_ELF_GETSHDR_ERROR",DW_DLV_OK, err); } if ((scn_name = elf_strptr(elf,ehdr32->e_shstrndx, shdr32->sh_name) ) == NULL) { print_error(dbg, "DW_ELF_STRPTR_ERROR",DW_DLV_OK, err); } if (shdr32->sh_type == SHT_SYMTAB) { size_t sym_size = 0; size_t count = 0; if ((sym = (Elf32_Sym *) get_scndata(scn, &sym_size)) == NULL) { print_error(dbg, "no symbol table data",DW_DLV_OK, err); } sym = (Elf32_Sym *) get_scndata(scn, &sym_size); count = sym_size / sizeof (Elf32_Sym); sym ++; if ((sym_data = readsyms(sym, count, elf, shdr32->sh_link)) == NULL) { print_error(dbg, "problem reading symbol table data",DW_DLV_OK, err); } } else if (strncmp(scn_name, ".rel.debug_", 11)) continue; else if (strcmp(scn_name, ".rel.debug_info") == 0) { SECT_DATA_SET(DW_SECTION_REL_DEBUG_INFO) } else if (strcmp(scn_name, ".rel.debug_line") == 0) { SECT_DATA_SET(DW_SECTION_REL_DEBUG_LINE) } else if (strcmp(scn_name, ".rel.debug_pubname") == 0) { SECT_DATA_SET(DW_SECTION_REL_DEBUG_PUBNAME) } else if (strcmp(scn_name, ".rel.debug_aranges") == 0) { SECT_DATA_SET(DW_SECTION_REL_DEBUG_ARANGES) } else if (strcmp(scn_name, ".rel.debug_abbrev") == 0) { SECT_DATA_SET(DW_SECTION_REL_DEBUG_ABBREV) } else if (strcmp(scn_name, ".rel.debug_frame") == 0) { SECT_DATA_SET(DW_SECTION_REL_DEBUG_FRAME) } } /* while */ for (i = 0; i < DW_SECTION_REL_DEBUG_NUM; i ++) { if (sect_data[i].buf != NULL && sect_data[i].size > 0) { print_reloc_information_32(i, sect_data[i].buf, sect_data[i].size); } } }
void *NWMovies_lookup_symbol(char *filename, char *function) { Elf *elf_ptr; int fd; Elf32_Ehdr *ehdr; Elf_Scn *section; Elf32_Shdr *section_header; Elf32_Sym *symtab_start, *symtab_current; int symtab_count, i; char *strtab; int strtab_type; char *symstrtab; void *return_val; /* Initialize the elves. */ if (elf_version(EV_CURRENT) == EV_NONE) { fprintf(stderr, "ERROR: NWMovies: libelf version mismatch.\n"); abort(); } /* open shared library */ fd = open(filename, O_RDONLY); if( fd < 0 ) { fprintf(stderr, "ERROR: NWMovies: Unable to open shared library: %s (%d)\n", filename, errno); abort(); } elf_ptr = elf_begin(fd, ELF_C_READ, (Elf *)0); if( elf_ptr == NULL) { fprintf(stderr, "ERROR: NWMovies: elf_begin failed: %s.\n", elf_errmsg(elf_errno())); abort(); } /* Get the Header */ if ( (ehdr = elf32_getehdr(elf_ptr)) == NULL) { fprintf(stderr, "ERROR: NWMovies: Unable to get Elf header: %s\n", elf_errmsg(elf_errno()) ); abort(); } /* Find the section string table */ section = elf_getscn(elf_ptr, ehdr->e_shstrndx); symstrtab = elf_getdata(section, NULL)->d_buf; section = 0; symtab_start = NULL; strtab = NULL; strtab_type = -1; while( (section = elf_nextscn( elf_ptr, section )) ) { section_header = elf32_getshdr(section); /* DYNSYM is better than nothing */ if( symtab_start == NULL && section_header->sh_type == SHT_DYNSYM ) { symtab_start = elf_getdata(section, NULL)->d_buf; symtab_count = section_header->sh_size / section_header->sh_entsize; strtab_type = 0; } /* However, we prefer SYMTAB */ if( section_header->sh_type == SHT_SYMTAB ) { symtab_start = elf_getdata(section, NULL)->d_buf; symtab_count = section_header->sh_size / section_header->sh_entsize; strtab_type = 1; } } if( strtab_type == -1 ) { fprintf(stderr, "ERROR: NWMovies: didn't find any symbol tables. Positively won't work.\n"); fprintf(stderr, "ERROR: NWMovies: Try a different %s library\n", filename); abort(); } section = 0; while((section = elf_nextscn(elf_ptr, section))) { section_header = elf32_getshdr(section); if( section_header->sh_type == SHT_STRTAB ) { if( strtab_type == 0 && strcmp(section_header->sh_name + symstrtab, ".dynstr") == 0 ) { strtab = elf_getdata(section, NULL)->d_buf; break; } if( strtab_type == 1 && strcmp(section_header->sh_name + symstrtab, ".strtab") == 0 ) { strtab = elf_getdata(section, NULL)->d_buf; break; } } } symtab_current = symtab_start; for(i=0; i<symtab_count; i++) { // fprintf(stderr, "DEBUG: INDEX: %d: %d\n", i, symtab_current->st_name); if( symtab_current->st_name != 0 ) { // fprintf(stderr, "DEBUG: Testing: %s\n", symtab_current->st_name + strtab); if( ! strcmp(symtab_current->st_name+strtab,function) ) { break; } } symtab_current++; } if( i >= symtab_count ) { elf_end(elf_ptr); close(fd); return(NULL); } else { return_val = (void *)symtab_current->st_value; elf_end(elf_ptr); close(fd); return(return_val); } }
static int _elf_nlist(Elf *elf, struct nlist *nl) { Elf_Scn *symtab = NULL; Elf_Scn *strtab = NULL; Elf_Data *symdata; Elf_Data *strdata; Elf32_Ehdr *ehdr; Elf32_Shdr *shdr; Elf_Scn *scn; Elf32_Sym *symbols; const char *strings; unsigned nsymbols; unsigned nstrings; unsigned i; const char *name; struct hash *table; unsigned nhash; unsigned long hash; unsigned long j; long val; if (!(ehdr = elf32_getehdr(elf))) { return -1; } scn = NULL; elf_errno(); while ((scn = elf_nextscn(elf, scn))) { if (!(shdr = elf32_getshdr(scn))) { return -1; } if (shdr->sh_type != SHT_SYMTAB && shdr->sh_type != SHT_DYNSYM) { continue; } symtab = scn; strtab = elf_getscn(elf, shdr->sh_link); if (shdr->sh_type == SHT_SYMTAB) { break; } } if (elf_errno()) { return -1; } symdata = elf_getdata(symtab, NULL); strdata = elf_getdata(strtab, NULL); if (!symdata || !strdata) { return -1; } symbols = (Elf32_Sym*)symdata->d_buf; strings = (const char*)strdata->d_buf; nsymbols = symdata->d_size / sizeof(Elf32_Sym); nstrings = strdata->d_size; if (!symbols || !strings || !nsymbols || !nstrings) { return -1; } /* * build a simple hash table */ nhash = 3 * nsymbols - 4; if (!(table = (struct hash*)malloc(nhash * sizeof(*table)))) { return -1; } for (i = 0; i < nhash; i++) { table[i].name = NULL; table[i].sym = NULL; } for (i = 1; i < nsymbols; i++) { if (symbols[i].st_name < 0 || symbols[i].st_name >= nstrings) { free(table); return -1; } if (symbols[i].st_name == 0) { continue; } name = strings + symbols[i].st_name; hash = elf_hash(name); for (j = hash; table[j %= nhash].name; j += 3) { if (table[j].hash != hash) { continue; } if (table[j].name == name || !strcmp(table[j].name, name)) { break; } } table[j].hash = hash; table[j].name = name; table[j].sym = &symbols[i]; } /* * symbol lookup */ for (i = 0; (name = nl[i].n_name) && *name ; i++) { val = nl[i].n_value; if (!strcmp("__UNKNOWN__", name)) { for (j=0; j < nhash; j++) if ((table[j].sym != NULL) && (table[j].sym->st_value == val)) { break; } if (j != nhash) { if ((nl[i].n_name = malloc(strlen(table[j].name)+1)) == NULL) return -1; strcpy(nl[i].n_name,table[j].name); nl[i].n_scnum = table[j].sym->st_shndx; } else { nl[i].n_name = NULL; nl[i].n_scnum = 0; } } else { hash = elf_hash(name); for (j = hash; table[j %= nhash].name; j += 3) { if ( (table[j].hash == hash) && (!strcmp(table[j].name, name)) ) { break; } } if (table[j].name) { nl[i].n_value = table[j].sym->st_value; nl[i].n_scnum = table[j].sym->st_shndx; } else { nl[i].n_value = 0; nl[i].n_scnum = 0; } } /* * this needs more work */ nl[i].n_type = 0; nl[i].n_sclass = 0; nl[i].n_numaux = 0; } free(table); return 0; }
int xlate_init_elf(Elf * elf, int open_debug_table, xlate_table_con * ret_tab_ptr) { int res; Elf32_Word wanttype; Elf_Scn *scn = 0; int is64bit = 0; char *ident; size_t identsize; Elf64_Shdr *shdr64 = 0; Elf32_Shdr *shdr32 = 0; Elf32_Ehdr *ehdr32 = 0; Elf64_Ehdr *ehdr64 = 0; int stringindex = 0; char * sec_name; if(elf_kind(elf) != ELF_K_ELF) { return XLATE_TB_STATUS_NOT_ELF; } ident = elf_getident(elf,&identsize); if(open_debug_table == XLATE_OPEN_STD_TABLE) { /* we take the first SHT_MIPS_XLATE*/ wanttype = SHT_MIPS_XLATE; } else if(open_debug_table == XLATE_OPEN_DEBUG_TABLE) { /* we take the first SHT_MIPS_XLATE_DEBUG */ wanttype = SHT_MIPS_XLATE_DEBUG; } else { return XLATE_TB_STATUS_NO_XLATE; } res = XLATE_TB_STATUS_NO_XLATE; if(ident == 0 || identsize < EI_NIDENT) { return XLATE_TB_STATUS_ELF_IDENT_BAD; } if(ident[EI_CLASS] == ELFCLASS64) { is64bit = 1; } if(is64bit) { ehdr64 = elf64_getehdr(elf); if(ehdr64 == 0 ) { return XLATE_TB_STATUS_ELF_EHDR_BAD; } stringindex = ehdr64->e_shstrndx; } else { ehdr32 = elf32_getehdr(elf); if(ehdr32 == 0 ) { return XLATE_TB_STATUS_ELF_EHDR_BAD; } stringindex = ehdr32->e_shstrndx; } for(scn = elf_nextscn(elf,scn); scn != 0 ; scn = elf_nextscn(elf,scn)) { if(is64bit) { shdr64 = elf64_getshdr(scn); if(shdr64 == 0) { return XLATE_TB_STATUS_ELF_SHDR_BAD; } sec_name = elf_strptr(elf,stringindex,shdr64->sh_name); if(sec_name == 0) { return XLATE_TB_STATUS_ELF_STRPTR_BAD; } if(shdr64->sh_type != wanttype) { continue; } res = xlate_named_init_elf(elf, sec_name,ret_tab_ptr); return res; } else { shdr32 = elf32_getshdr(scn); if(shdr32 == 0) { return XLATE_TB_STATUS_ELF_SHDR_BAD; } sec_name = elf_strptr(elf,stringindex,shdr32->sh_name); if(sec_name == 0) { return XLATE_TB_STATUS_ELF_STRPTR_BAD; } if(shdr32->sh_type != wanttype) { continue; } res = xlate_named_init_elf(elf, sec_name,ret_tab_ptr); return res; } } return res; }
//////////////////////////////////////////////////////////////////////////////// /// adds a target shared library to the target execution image EXTERN void __tgt_register_lib(__tgt_bin_desc *desc){ //Is the library version incompatible with the header file? if (elf_version(EV_CURRENT) == EV_NONE){ DP("Incompatible ELF library!\n"); return; } // Can't read the host entries?? if (!desc) { DP("Invalid descr!\n"); return; } if (!desc->EntriesBegin){ DP("Invalid Host entries!\n"); return; } DP("Registering entries starting at %016lx...\n", (Elf64_Addr)desc->EntriesBegin->addr); HostEntriesBeginToTransTableTy::iterator TransTableIt = HostEntriesBeginToTransTable.find(desc->EntriesBegin); if (TransTableIt != HostEntriesBeginToTransTable.end()){ DP("Already registered!\n"); return; } // Initialize translation table for this TranslationTable &TransTable = HostEntriesBeginToTransTable[desc->EntriesBegin]; TransTable.HostTable.EntriesBegin = desc->EntriesBegin; TransTable.HostTable.EntriesEnd = desc->EntriesEnd; // Scan all the device images for(int32_t i=0; i<desc->NumDevices; ++i){ __tgt_device_image &img = desc->DeviceImages[i]; char *img_begin = (char*)img.ImageStart; char *img_end = (char*)img.ImageEnd; size_t img_size = img_end - img_begin; //Obtain elf handler Elf *e = elf_memory(img_begin, img_size); if (!e){ DP("Unable to get ELF handle: %s!\n", elf_errmsg(-1)); continue; } //Check if ELF is the right kind if (elf_kind(e) != ELF_K_ELF){ DP("Unexpected ELF type!\n"); continue; } Elf64_Ehdr *eh64 = elf64_getehdr(e); Elf32_Ehdr *eh32 = elf32_getehdr(e); uint16_t MachineID; if (eh64 && !eh32) MachineID = eh64->e_machine; else if (eh32 && !eh64) MachineID = eh32->e_machine; else{ DP("Ambiguous ELF header!\n"); continue; } DTypeToRTLMapTy::iterator RTLHandler = DTypeToRTLMap.find(MachineID); // We already have an handler for this device's RTL? // If so insert the Image <-> RTL Map entry and continue if (RTLHandler != DTypeToRTLMap.end()){ // We were unable to find a runtime for this device before... if (RTLHandler->second == 0) continue; RegisterImageIntoTranslationTable(TransTable, *RTLHandler->second, &img); continue; } // Locate the library name and create an handler void *dynlib_handle = 0; DP("Looking for RTL libraries: with machine id %d\n", MachineID); for(int32_t j=0; j<targets_info.Number_of_Entries; ++j){ if (targets_info.Entries[j].Machine_Elf_ID == MachineID){ DP("Found library %s!\n", targets_info.Entries[j].Machine_RTL_Lib); dynlib_handle = dlopen(targets_info.Entries[j].Machine_RTL_Lib, RTLD_NOW); if (!dynlib_handle) DP("Error opening library for target %d: %s!\n", MachineID, dlerror()); break; } else DP("Machine ID %d != %d!\n", targets_info.Entries[j].Machine_Elf_ID, MachineID); } RTLInfoTy *&RTL = DTypeToRTLMap[MachineID]; RTL = 0; if (!dynlib_handle){ DP("No valid library for target %d, %s!\n", MachineID, dlerror()); continue; } // Create the handler and try to retrieve the functions RTLInfoTy R; R.LibraryHandler = dynlib_handle; if (!(R.device_type = (RTLInfoTy::device_type_ty*) dlsym(dynlib_handle, "__tgt_rtl_device_type"))) continue; if (!(R.number_of_devices = (RTLInfoTy::number_of_devices_ty*)dlsym(dynlib_handle, "__tgt_rtl_number_of_devices"))) continue; if (!(R.init_device = (RTLInfoTy::init_device_ty*) dlsym(dynlib_handle, "__tgt_rtl_init_device"))) continue; if (!(R.load_binary = (RTLInfoTy::load_binary_ty*) dlsym(dynlib_handle, "__tgt_rtl_load_binary"))) continue; if (!(R.data_alloc = (RTLInfoTy::data_alloc_ty*) dlsym(dynlib_handle, "__tgt_rtl_data_alloc"))) continue; if (!(R.data_submit = (RTLInfoTy::data_submit_ty*) dlsym(dynlib_handle, "__tgt_rtl_data_submit"))) continue; if (!(R.data_retrieve = (RTLInfoTy::data_retrieve_ty*) dlsym(dynlib_handle, "__tgt_rtl_data_retrieve"))) continue; if (!(R.data_delete = (RTLInfoTy::data_delete_ty*) dlsym(dynlib_handle, "__tgt_rtl_data_delete"))) continue; if (!(R.run_region = (RTLInfoTy::run_region_ty*) dlsym(dynlib_handle, "__tgt_rtl_run_target_region"))) continue; if (!(R.run_team_region = (RTLInfoTy::run_team_region_ty*) dlsym(dynlib_handle, "__tgt_rtl_run_target_team_region"))) continue; // No devices are supported by this RTL? if (!(R.NumberOfDevices = R.number_of_devices())) { DP("No device support this RTL\n"); continue; } R.Idx = (RTLs.empty()) ? 0 : RTLs.back().Idx + RTLs.back().NumberOfDevices; DP("Registered RTL supporting %d devices at index %d!\n", R.NumberOfDevices, R.Idx); // The RTL is valid! RTLs.push_back(R); RTL = &RTLs.back(); // Add devices DeviceTy device(RTL); size_t start = Devices.size(); Devices.resize(start + RTL->NumberOfDevices, device); for (int32_t device_id = 0; device_id < RTL->NumberOfDevices; device_id++) { // global device ID Devices[start + device_id].DeviceID = start + device_id; // RTL local device ID Devices[start + device_id].RTLDeviceID = device_id; // Save pointer to device in RTL in case we want to unregister the RTL RTL->Devices.push_back(&Devices[start + device_id]); } DP("Registering image %016lx with RTL!\n", (Elf64_Addr)img_begin); RegisterImageIntoTranslationTable(TransTable, *RTL, &img); } DP("Done register entries!\n"); }
int ar_diff(int fd1, int fd2, char *sections, int verbose) { int i=0, retval = ED_SUCCESS; Elf *arf[2]; Elf *elf[2]; Elf_Cmd cmd[2]; if ((arf[0] = elf_begin(fd1,ELF_C_READ,NULL))==NULL) { if (verbose) fprintf(stderr, "elfdiff: Error reading AR information from first input file.\n"); return ED_ELFFAIL; } if ((arf[1] = elf_begin(fd2,ELF_C_READ,NULL))==NULL) { if (verbose) fprintf(stderr, "elfdiff: Error reading AR information from second input file.\n"); elf_end(elf[0]); return ED_ELFFAIL; } if (arf[0]->e_numsyms != arf[1]->e_numsyms) { retval = ED_HDRFAIL; } else { //////////////////////////////////////////////////////// //FIXME: this section should correlate the items by name //////////////////////////////////////////////////////// cmd[0] = cmd[1] = ELF_C_READ; while (((elf[0] = elf_begin(fd1, cmd[0], arf[0])) != 0) && !retval) { if (elf32_getehdr(elf[0]) != 0) { while ((elf[1] = elf_begin(fd2, cmd[1], arf[1])) != 0) { if (elf32_getehdr(elf[1]) != 0) { if (strcmp(elf[0]->e_arhdrp->ar_name, elf[1]->e_arhdrp->ar_name) != 0) { if (verbose>1) fprintf(stderr, "elfdiff: Internal object order does not match. ('%s' != '%s')\n", elf[0]->e_arhdrp->ar_name, elf[1]->e_arhdrp->ar_name); retval = ED_HDRFAIL; } else { retval = ohdr_diff(elf, verbose); if (!retval && sections) retval=shdr_diff(elf, sections, verbose); if (retval) { if (verbose>1) fprintf(stderr, "elfdiff: Internal object '%s' - FAIL\n", elf[0]->e_arhdrp->ar_name); } else { if (verbose>1) fprintf(stdout, "elfdiff: Internal object '%s'- PASS\n", elf[0]->e_arhdrp->ar_name); } } cmd[1]=elf_next(elf[1]); elf_end(elf[1]); break; } cmd[1]=elf_next(elf[1]); elf_end(elf[1]); } } cmd[0]=elf_next(elf[0]); elf_end(elf[0]); } } for (i=0;i<2;i++) { elf_end(arf[i]); } if (verbose) { if (retval) { fprintf(stderr, "elfdiff: Files do not match\n"); } else { printf("elfdiff: Files match.\n"); } } return retval; }
//-------------------------------------------------------------------------------- static int convElfToMiniFile(char* elffilename, char* melffilename) { int fdelf, fdmelf, modhdrsymndx; Elf* elf; Elf32_Ehdr *ehdr; Elf_Scn *relatextscn, *textscn, *symtabscn, *strtabscn; Melf_Scn *m_relatextscn, *m_textscn, *m_symtabscn; Melf* melf; symbol_map_t* symmap; Melf_Data *relatextdata, *symtabdata, *textdata; symbol_map_t symmap_storage; printf("ELF File: %s\n", elffilename); printf("Mini-ELF File: %s\n", melffilename); symmap = &symmap_storage; // Open ELF file for reading if ((fdelf = open(elffilename, O_RDONLY)) < 0){ fprintf(stderr, "%s: ", elffilename); perror("convElfToMini -> fopen: "); exit(EXIT_FAILURE); } // Open Mini-ELF file for writing if ((fdmelf = open(melffilename, (O_RDWR | O_CREAT | O_EXCL), (S_IRWXU | S_IRWXG | S_IRWXO))) < 0){ fprintf(stderr, "%s: ", melffilename); perror("convElfToMini -> fopen: "); exit(EXIT_FAILURE); } // Check version of ELF Library if (elf_version(EV_CURRENT) == EV_NONE){ fprintf(stderr, "Library version is out of date.\n"); exit(EXIT_FAILURE); } // Get the ELF descriptor elf = elf_begin(fdelf, ELF_C_READ, NULL); if (NULL == elf){ fprintf(stderr, "elf_begin: Error getting elf descriptor\n"); exit(EXIT_FAILURE); } // Ensure that it is an ELF format file if (elf_kind(elf) != ELF_K_ELF){ fprintf(stderr, "This program can only read ELF format files.\n"); exit(EXIT_FAILURE); } // Get the ELF Header ehdr = elf32_getehdr(elf); if (NULL == ehdr){ fprintf(stderr, "Error reading ELF header\n"); exit(EXIT_FAILURE); } // Verify if the ELF is AVR specific if (ehdr->e_machine != EM_AVR && ehdr->e_machine != EM_MSP430){ fprintf(stderr, "This ELF binary is not supported.\n"); exit(EXIT_FAILURE); } e_machine = ehdr->e_machine; // Create a new Mini-ELF (MELF) descriptor if ((melf = melf_new(fdmelf)) == NULL){ fprintf(stderr, "Error creating a new MELF descriptor\n"); exit(EXIT_FAILURE); } // Get the pointer to .symtab section if ((symtabscn = getELFSectionByName(elf, ".symtab")) == NULL){ fprintf(stderr, "Error getting .symtab section.\n"); exit(EXIT_FAILURE); } // Get the pointer to .rela.text section /* if ((relatextscn = getELFSectionByName(elf, ".rela.text")) == NULL){ fprintf(stderr, "Error getting .rela.text section.\n"); exit(EXIT_FAILURE); } */ relatextscn = getELFSectionByName(elf, ".rela.text"); // Get the pointer to .text section if ((textscn = getELFSectionByName(elf, ".text")) == NULL){ fprintf(stderr, "Error getting .text section.\n"); exit(EXIT_FAILURE); } if ((strtabscn = getELFSectionByName(elf, ".strtab")) == NULL ) { fprintf(stderr, "Error getting .strtab section. \n"); exit(EXIT_FAILURE); } // DEBUG info. to verify we have the correct sections DEBUG("Section Number (.text): %d\n", (int)elf_ndxscn(textscn)); if( relatextscn != NULL ) { DEBUG("Section Number (.rela.text): %d\n", (int)elf_ndxscn(relatextscn)); } DEBUG("Section Number (.symtab): %d\n", (int)elf_ndxscn(symtabscn)); // Initialize Symbol Map if (initSymbolMap(symmap, symtabscn) < 0){ fprintf(stderr, "Error initializing symbol map.\n"); exit(EXIT_FAILURE); } // // Set string table to symbol map // addStrTabToSymbolMap( symmap, strtabscn ); addTxtScnToSymbolMap( symmap, textscn ); // Convert Relocation Table // Simon: convert relocation before text section // because some symbols will be patched in .text section if( relatextscn != NULL ) { if ((relatextdata = convRelaScn(relatextscn, symmap)) == NULL){ fprintf(stderr, "Error converting Rela table.\n"); exit(EXIT_FAILURE); } } // Convert Text Section if ((textdata = convProgbitsScn(textscn)) == NULL){ fprintf(stderr, "Error converting text section.\n"); exit(EXIT_FAILURE); } // Add mod_header symbol if ((modhdrsymndx = getELFSymbolTableNdx(elf, "mod_header")) == -1){ fprintf(stderr, "Could not locate symbol: mod_header. Not a valid SOS module\n"); exit(EXIT_FAILURE); } addMelfSymbol(symmap, modhdrsymndx); melf_setModHdrSymNdx(melf, symmap->etommap[modhdrsymndx]); // Convert Symbol Table if ((symtabdata = convSymScn(symmap)) == NULL){ fprintf(stderr, "Error convering symbol table.\n"); exit(EXIT_FAILURE); } // Create a new MELF Symbol table section if ((m_symtabscn = melf_new_scn(melf)) == NULL){ fprintf(stderr, "Error creating symbol table MELF section.\n"); exit(EXIT_FAILURE); } convElfHdr(m_symtabscn, symtabscn); melf_add_data_to_scn(m_symtabscn, symtabdata); // Create a new MELF Relocation table section if( relatextscn != NULL ) { if ((m_relatextscn = melf_new_scn(melf)) == NULL){ fprintf(stderr, "Error creating relocation table MELF section.\n"); exit(EXIT_FAILURE); } convElfHdr(m_relatextscn, relatextscn); melf_add_data_to_scn(m_relatextscn, relatextdata); } // Create a new MELF Symbol table section if ((m_textscn = melf_new_scn(melf)) == NULL){ fprintf(stderr, "Error creating .text MELF section.\n"); exit(EXIT_FAILURE); } convElfHdr(m_textscn, textscn); melf_add_data_to_scn(m_textscn, textdata); // Sort the MELF Sections (Enable single pass writing on the nodes) melf_sortScn(melf); // Set the section offsets melf_setScnOffsets(melf); // Write the MELF File melf_write(melf); #ifdef DBGMODE prettyPrintMELF(melf); #endif // Close ELF Descriptor elf_end(elf); // Close ELF File close(fdelf); // Close MELF File close(fdmelf); return 0; }
int main( int argc, char **argv ) { int fd; Elf_Scn *section; int scndx; Elf32_Shdr *sheader; Elf32_Ehdr *eheader; int strings; int len; int what_to_do; Elf *elf; char *filep; if( argc != 3 ) { fprintf(stderr, "%s: <what> <filename>\n", argv[0]); return(1); } if (strcmp("vindex",argv[1]) == 0) what_to_do = 1; else if (strcmp("type",argv[1]) == 0) what_to_do = 2; else if (strcmp("vtable",argv[1]) == 0) what_to_do = 3; else { fprintf(stderr, "%s: unknown command> %s\n", argv[0], argv[1] ); return(1); } sprintf(program,"%s<%s>",argv[0],argv[1]); elf_version(EV_CURRENT); fd = open(argv[2], OPEN_FLAGS); if( fd < 0 ) { fprintf(stderr, "%s: open of file %s failed\n", argv[0], argv[2] ); return(1); } len = lseek(fd, 0, SEEK_END); #if MAPFILE /* printf("Mapping file %s [len %d]\n", argv[1], len); */ filep = (char *) mmap(NULL, len, PROT_READ | PROT_WRITE, MAP_SHARED,fd,0); if (filep == (char *)-1) { perror("mmap"); return(1); } #else filep = (char*)malloc(len); lseek(fd,0,SEEK_SET); if (len != read(fd,filep,len)) { perror("mmap"); return(1); } #endif elf = elf_begin(fd, ELF_C_READ, (Elf *)NULL); if ((eheader = elf32_getehdr(elf)) == NULL) { fprintf(stderr, "%s: get header failed\n", argv[0] ); return(1); } strings = eheader->e_shstrndx; section = NULL; scndx = 0; while ((section = elf_nextscn(elf, section)) != NULL) { char *name = 0; ++scndx; if ((sheader = elf32_getshdr(section)) != NULL) name = elf_strptr(elf, strings, sheader->sh_name); if( name != NULL ) { // printf("SECTION[%d]: <%s>\n",(int)section,name); if( strcmp( name, THE_DATA_SECTION ) == 0 ) { pdata = (char *) (filep + sheader->sh_offset); data_index = scndx; } else if( strcmp( name, SMALL_DATA_SECTION ) == 0 ) { psdata = (char *) (filep + sheader->sh_offset); sdata_index = scndx; } else if( strcmp( name, ELF_SYMTAB ) == 0 ) { psyms = (Elf32_Sym *) (filep + sheader->sh_offset); nsyms = sheader->sh_size / sizeof(Elf32_Sym); } else if( strcmp( name, ELF_STRTAB ) == 0 ) { pstr = (char *) (filep + sheader->sh_offset); } } } if( pdata == NULL && psdata == NULL ) { fprintf(stderr, "%s: no data segment found\n", argv[0] ); return(1); } if( psyms == NULL ) { fprintf(stderr, "%s: no symbol table found\n", argv[0] ); return(1); } if( pstr == NULL ) { fprintf(stderr, "%s: no string table found\n", argv[0] ); return(1); } switch (what_to_do) { case 1: extract_virtual_index(); break; case 2: extract_type_values(); break; case 3: extract_virtual_table_size_indirect(); break; } elf_end(elf); return(0); }