elfloader-otf.c
来自「伟大的Contiki工程, 短小精悍 的操作系统, 学习编程不可不看」· C语言 代码 · 共 681 行 · 第 1/2 页
C
681 行
}/*---------------------------------------------------------------------------*/voidelfloader_init(void){ elfloader_autostart_processes = NULL;}/*---------------------------------------------------------------------------*/#if 0static voidprint_chars(unsigned char *ptr, int num){ int i; for(i = 0; i < num; ++i) { PRINTF("%d", ptr[i]); if(i == num - 1) { PRINTF("\n"); } else { PRINTF(", "); } }}#endif /* 0 */static intcopy_segment(int input_fd, struct elfloader_output *output, unsigned int section, unsigned short size, unsigned int sectionaddr, char *sectionbase, unsigned int strs, unsigned int strtab, unsigned int symtab, unsigned short symtabsize, unsigned char using_relas, unsigned int seg_size, unsigned int seg_type){ unsigned int offset; int ret; ret = elfloader_output_start_segment(output, seg_type,sectionbase, seg_size); if (ret != ELFLOADER_OK) return ret; ret = relocate_section(input_fd, output, section, size, sectionaddr, sectionbase, strs, strtab, symtab, symtabsize, using_relas); if (ret != ELFLOADER_OK) return ret; offset = elfloader_output_segment_offset(output); ret = copy_segment_data(input_fd, offset+sectionaddr, output,seg_size - offset); if (ret != ELFLOADER_OK) return ret; return elfloader_output_end_segment(output);}/*---------------------------------------------------------------------------*/intelfloader_load(int input_fd, struct elfloader_output *output){ struct elf32_ehdr ehdr; struct elf32_shdr shdr; struct elf32_shdr strtable; unsigned int strs; unsigned int shdrptr; unsigned int nameptr; char name[12]; int i; unsigned short shdrnum, shdrsize; unsigned char using_relas = -1; unsigned short textoff = 0, textsize, textrelaoff = 0, textrelasize; unsigned short dataoff = 0, datasize, datarelaoff = 0, datarelasize; unsigned short rodataoff = 0, rodatasize, rodatarelaoff = 0, rodatarelasize; unsigned short symtaboff = 0, symtabsize; unsigned short strtaboff = 0, strtabsize; unsigned short bsssize = 0; struct process **process; int ret; elfloader_unknown[0] = 0; /* The ELF header is located at the start of the buffer. */ ret = seek_read(input_fd, 0, (char *)&ehdr, sizeof(ehdr)); if (ret != sizeof(ehdr)) return ELFLOADER_INPUT_ERROR; /* print_chars(ehdr.e_ident, sizeof(elf_magic_header)); print_chars(elf_magic_header, sizeof(elf_magic_header));*/ /* Make sure that we have a correct and compatible ELF header. */ if(memcmp(ehdr.e_ident, elf_magic_header, sizeof(elf_magic_header)) != 0) { PRINTF("ELF header problems\n"); return ELFLOADER_BAD_ELF_HEADER; } /* Grab the section header. */ shdrptr = ehdr.e_shoff; ret = seek_read(input_fd, shdrptr, (char *)&shdr, sizeof(shdr)); if (ret != sizeof(shdr)) return ELFLOADER_INPUT_ERROR; /* Get the size and number of entries of the section header. */ shdrsize = ehdr.e_shentsize; shdrnum = ehdr.e_shnum; /* The string table section: holds the names of the sections. */ ret = seek_read(input_fd, ehdr.e_shoff + shdrsize * ehdr.e_shstrndx, (char *)&strtable, sizeof(strtable)); if (ret != sizeof(strtable)) return ELFLOADER_INPUT_ERROR; /* Get a pointer to the actual table of strings. This table holds the names of the sections, not the names of other symbols in the file (these are in the sybtam section). */ strs = strtable.sh_offset; /* Go through all sections and pick out the relevant ones. The ".text" segment holds the actual code from the ELF file, the ".data" segment contains initialized data, the ".rodata" segment contains read-only data, the ".bss" segment holds the size of the unitialized data segment. The ".rel[a].text" and ".rel[a].data" segments contains relocation information for the contents of the ".text" and ".data" segments, respectively. The ".symtab" segment contains the symbol table for this file. The ".strtab" segment points to the actual string names used by the symbol table. In addition to grabbing pointers to the relevant sections, we also save the section number for resolving addresses in the relocator code. */ /* Initialize the segment sizes to zero so that we can check if their sections was found in the file or not. */ textsize = textrelasize = datasize = datarelasize = rodatasize = rodatarelasize = symtabsize = strtabsize = 0; bss.number = data.number = rodata.number = text.number = -1; shdrptr = ehdr.e_shoff; for(i = 0; i < shdrnum; ++i) { ret = seek_read(input_fd, shdrptr, (char *)&shdr, sizeof(shdr)); if (ret != sizeof(shdr)) return ELFLOADER_INPUT_ERROR; /* The name of the section is contained in the strings table. */ nameptr = strs + shdr.sh_name; ret = seek_read(input_fd, nameptr, name, sizeof(name)); if (ret != sizeof(name)) return ELFLOADER_INPUT_ERROR; /* Match the name of the section with a predefined set of names (.text, .data, .bss, .rela.text, .rela.data, .symtab, and .strtab). */ /* added support for .rodata, .rel.text and .rel.data). */ if(strncmp(name, ".text", 5) == 0) { textoff = shdr.sh_offset; textsize = shdr.sh_size; text.number = i; text.offset = textoff; } else if(strncmp(name, ".rel.text", 9) == 0) { using_relas = 0; textrelaoff = shdr.sh_offset; textrelasize = shdr.sh_size; } else if(strncmp(name, ".rela.text", 10) == 0) { using_relas = 1; textrelaoff = shdr.sh_offset; textrelasize = shdr.sh_size; } else if(strncmp(name, ".data", 5) == 0) { dataoff = shdr.sh_offset; datasize = shdr.sh_size; data.number = i; data.offset = dataoff; } else if(strncmp(name, ".rodata", 7) == 0) { /* read-only data handled the same way as regular text section */ rodataoff = shdr.sh_offset; rodatasize = shdr.sh_size; rodata.number = i; rodata.offset = rodataoff; } else if(strncmp(name, ".rel.rodata", 11) == 0) { /* using elf32_rel instead of rela */ using_relas = 0; rodatarelaoff = shdr.sh_offset; rodatarelasize = shdr.sh_size; } else if(strncmp(name, ".rela.rodata", 12) == 0) { using_relas = 1; rodatarelaoff = shdr.sh_offset; rodatarelasize = shdr.sh_size; } else if(strncmp(name, ".rel.data", 9) == 0) { /* using elf32_rel instead of rela */ using_relas = 0; datarelaoff = shdr.sh_offset; datarelasize = shdr.sh_size; } else if(strncmp(name, ".rela.data", 10) == 0) { using_relas = 1; datarelaoff = shdr.sh_offset; datarelasize = shdr.sh_size; } else if(strncmp(name, ".symtab", 7) == 0) { symtaboff = shdr.sh_offset; symtabsize = shdr.sh_size; } else if(strncmp(name, ".strtab", 7) == 0) { strtaboff = shdr.sh_offset; strtabsize = shdr.sh_size; } else if(strncmp(name, ".bss", 4) == 0) { bsssize = shdr.sh_size; bss.number = i; bss.offset = 0; } /* Move on to the next section header. */ shdrptr += shdrsize; } if(symtabsize == 0) { return ELFLOADER_NO_SYMTAB; } if(strtabsize == 0) { return ELFLOADER_NO_STRTAB; } if(textsize == 0) { return ELFLOADER_NO_TEXT; } if (bsssize) { bss.address = (char *) elfloader_output_alloc_segment(output, ELFLOADER_SEG_BSS, bsssize); if (!bss.address) return ELFLOADER_OUTPUT_ERROR; } if (datasize) { data.address = (char *) elfloader_output_alloc_segment(output,ELFLOADER_SEG_DATA,datasize); if (!data.address) return ELFLOADER_OUTPUT_ERROR; } if (textsize) { text.address = (char *) elfloader_output_alloc_segment(output,ELFLOADER_SEG_TEXT,textsize); if (!text.address) return ELFLOADER_OUTPUT_ERROR; } if (rodatasize) { rodata.address = (char *) elfloader_output_alloc_segment(output,ELFLOADER_SEG_RODATA,rodatasize); if (!rodata.address) return ELFLOADER_OUTPUT_ERROR; }/* printf("bss base address: bss.address = 0x%08x\n", bss.address); printf("data base address: data.address = 0x%08x\n", data.address); printf("text base address: text.address = 0x%08x\n", text.address); printf("rodata base address: rodata.address = 0x%08x\n", rodata.address); */ /* If we have text segment relocations, we process them. */ PRINTF("elfloader: relocate text\n"); if(textrelasize > 0) { ret = copy_segment(input_fd, output, textrelaoff, textrelasize, textoff, text.address, strs, strtaboff, symtaboff, symtabsize, using_relas, textsize, ELFLOADER_SEG_TEXT); if(ret != ELFLOADER_OK) { return ret; } } /* If we have any rodata segment relocations, we process them too. */ PRINTF("elfloader: relocate rodata\n"); if(rodatarelasize > 0) { ret = copy_segment(input_fd, output, rodatarelaoff, rodatarelasize, rodataoff, rodata.address, strs, strtaboff, symtaboff, symtabsize, using_relas, rodatasize, ELFLOADER_SEG_RODATA); if(ret != ELFLOADER_OK) { PRINTF("elfloader: data failed\n"); return ret; } } /* If we have any data segment relocations, we process them too. */ PRINTF("elfloader: relocate data\n"); if(datarelasize > 0) { ret = copy_segment(input_fd, output, datarelaoff, datarelasize, dataoff, data.address, strs, strtaboff, symtaboff, symtabsize, using_relas, datasize, ELFLOADER_SEG_DATA); if(ret != ELFLOADER_OK) { PRINTF("elfloader: data failed\n"); return ret; } ret = elfloader_output_end_segment(output); if (ret != ELFLOADER_OK) return ret; } /* Write text and rodata segment into flash and data segment into RAM. *//* elfloader_arch_write_rom(fd, textoff, textsize, text.address); *//* elfloader_arch_write_rom(fd, rodataoff, rodatasize, rodata.address); */ /* memset(bss.address, 0, bsssize); *//* seek_read(fd, dataoff, data.address, datasize); */ { /* Write zeros to bss segment */ unsigned int len = bsssize; static const char zeros[16] = {0}; ret = elfloader_output_start_segment(output, ELFLOADER_SEG_BSS, bss.address,bsssize); if (ret != ELFLOADER_OK) return ret; while(len > sizeof(zeros)) { ret = elfloader_output_write_segment(output, zeros, sizeof(zeros)); if (ret != sizeof(zeros)) return ELFLOADER_OUTPUT_ERROR; len -= sizeof(zeros); } ret = elfloader_output_write_segment(output, zeros, len); if (ret != len) return ELFLOADER_OUTPUT_ERROR; } PRINTF("elfloader: autostart search\n"); process = find_local_symbol(input_fd, "autostart_processes", symtaboff, symtabsize, strtaboff); if(process != NULL) { PRINTF("elfloader: autostart found\n"); elfloader_autostart_processes = process; return ELFLOADER_OK; } else { PRINTF("elfloader: no autostart\n"); process = find_program_processes(input_fd, symtaboff, symtabsize, strtaboff); if(process != NULL) { PRINTF("elfloader: FOUND PRG\n"); } return ELFLOADER_NO_STARTPOINT; }}/*---------------------------------------------------------------------------*/
⌨️ 快捷键说明
复制代码Ctrl + C
搜索代码Ctrl + F
全屏模式F11
增大字号Ctrl + =
减小字号Ctrl + -
显示快捷键?