Contiki 2.6
|
00001 /* 00002 * Copyright (c) 2005, Swedish Institute of Computer Science 00003 * Copyright (c) 2007, Simon Berg 00004 * All rights reserved. 00005 * 00006 * Redistribution and use in source and binary forms, with or without 00007 * modification, are permitted provided that the following conditions 00008 * are met: 00009 * 1. Redistributions of source code must retain the above copyright 00010 * notice, this list of conditions and the following disclaimer. 00011 * 2. Redistributions in binary form must reproduce the above copyright 00012 * notice, this list of conditions and the following disclaimer in the 00013 * documentation and/or other materials provided with the distribution. 00014 * 3. Neither the name of the Institute nor the names of its contributors 00015 * may be used to endorse or promote products derived from this software 00016 * without specific prior written permission. 00017 * 00018 * THIS SOFTWARE IS PROVIDED BY THE INSTITUTE AND CONTRIBUTORS ``AS IS'' AND 00019 * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE 00020 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE 00021 * ARE DISCLAIMED. IN NO EVENT SHALL THE INSTITUTE OR CONTRIBUTORS BE LIABLE 00022 * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL 00023 * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS 00024 * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) 00025 * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT 00026 * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY 00027 * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF 00028 * SUCH DAMAGE. 00029 * 00030 * This file is part of the Contiki operating system. 00031 * 00032 * @(#)$Id: elfloader-otf.c,v 1.1 2009/07/11 14:18:50 ksb Exp $ 00033 */ 00034 00035 #include "contiki.h" 00036 00037 #include "loader/elfloader-otf.h" 00038 #include "loader/elfloader-arch-otf.h" 00039 00040 #include "cfs/cfs.h" 00041 #include "loader/symtab.h" 00042 00043 #include <stddef.h> 00044 #include <string.h> 00045 #include <stdio.h> 00046 00047 #if 0 00048 #include <stdio.h> 00049 #define PRINTF(...) printf(__VA_ARGS__) 00050 #else 00051 #define PRINTF(...) do {} while (0) 00052 #endif 00053 00054 #define EI_NIDENT 16 00055 00056 00057 struct elf32_ehdr { 00058 unsigned char e_ident[EI_NIDENT]; /* ident bytes */ 00059 elf32_half e_type; /* file type */ 00060 elf32_half e_machine; /* target machine */ 00061 elf32_word e_version; /* file version */ 00062 elf32_addr e_entry; /* start address */ 00063 elf32_off e_phoff; /* phdr file offset */ 00064 elf32_off e_shoff; /* shdr file offset */ 00065 elf32_word e_flags; /* file flags */ 00066 elf32_half e_ehsize; /* sizeof ehdr */ 00067 elf32_half e_phentsize; /* sizeof phdr */ 00068 elf32_half e_phnum; /* number phdrs */ 00069 elf32_half e_shentsize; /* sizeof shdr */ 00070 elf32_half e_shnum; /* number shdrs */ 00071 elf32_half e_shstrndx; /* shdr string index */ 00072 }; 00073 00074 /* Values for e_type. */ 00075 #define ET_NONE 0 /* Unknown type. */ 00076 #define ET_REL 1 /* Relocatable. */ 00077 #define ET_EXEC 2 /* Executable. */ 00078 #define ET_DYN 3 /* Shared object. */ 00079 #define ET_CORE 4 /* Core file. */ 00080 00081 struct elf32_shdr { 00082 elf32_word sh_name; /* section name */ 00083 elf32_word sh_type; /* SHT_... */ 00084 elf32_word sh_flags; /* SHF_... */ 00085 elf32_addr sh_addr; /* virtual address */ 00086 elf32_off sh_offset; /* file offset */ 00087 elf32_word sh_size; /* section size */ 00088 elf32_word sh_link; /* misc info */ 00089 elf32_word sh_info; /* misc info */ 00090 elf32_word sh_addralign; /* memory alignment */ 00091 elf32_word sh_entsize; /* entry size if table */ 00092 }; 00093 00094 /* sh_type */ 00095 #define SHT_NULL 0 /* inactive */ 00096 #define SHT_PROGBITS 1 /* program defined information */ 00097 #define SHT_SYMTAB 2 /* symbol table section */ 00098 #define SHT_STRTAB 3 /* string table section */ 00099 #define SHT_RELA 4 /* relocation section with addends*/ 00100 #define SHT_HASH 5 /* symbol hash table section */ 00101 #define SHT_DYNAMIC 6 /* dynamic section */ 00102 #define SHT_NOTE 7 /* note section */ 00103 #define SHT_NOBITS 8 /* no space section */ 00104 #define SHT_REL 9 /* relation section without addends */ 00105 #define SHT_SHLIB 10 /* reserved - purpose unknown */ 00106 #define SHT_DYNSYM 11 /* dynamic symbol table section */ 00107 #define SHT_LOPROC 0x70000000 /* reserved range for processor */ 00108 #define SHT_HIPROC 0x7fffffff /* specific section header types */ 00109 #define SHT_LOUSER 0x80000000 /* reserved range for application */ 00110 #define SHT_HIUSER 0xffffffff /* specific indexes */ 00111 00112 struct elf32_rel { 00113 elf32_addr r_offset; /* Location to be relocated. */ 00114 elf32_word r_info; /* Relocation type and symbol index. */ 00115 }; 00116 00117 struct elf32_sym { 00118 elf32_word st_name; /* String table index of name. */ 00119 elf32_addr st_value; /* Symbol value. */ 00120 elf32_word st_size; /* Size of associated object. */ 00121 unsigned char st_info; /* Type and binding information. */ 00122 unsigned char st_other; /* Reserved (not used). */ 00123 elf32_half st_shndx; /* Section index of symbol. */ 00124 }; 00125 00126 #define ELF32_R_SYM(info) ((info) >> 8) 00127 #define ELF32_R_TYPE(info) ((unsigned char)(info)) 00128 00129 struct relevant_section { 00130 unsigned char number; 00131 unsigned int offset; 00132 char *address; 00133 }; 00134 00135 char elfloader_unknown[30]; /* Name that caused link error. */ 00136 00137 struct process **elfloader_autostart_processes; 00138 00139 static struct relevant_section bss, data, rodata, text; 00140 00141 const static unsigned char elf_magic_header[] = 00142 {0x7f, 0x45, 0x4c, 0x46, /* 0x7f, 'E', 'L', 'F' */ 00143 0x01, /* Only 32-bit objects. */ 00144 0x01, /* Only LSB data. */ 00145 0x01, /* Only ELF version 1. */ 00146 }; 00147 00148 /* Copy data from the elf file to a segment */ 00149 static int 00150 copy_segment_data(int input_fd, unsigned int offset, 00151 struct elfloader_output *output, unsigned int len) 00152 { 00153 char buffer[16]; 00154 int res; 00155 if (cfs_seek(input_fd, offset, CFS_SEEK_SET) != offset) return ELFLOADER_INPUT_ERROR; 00156 while(len > sizeof(buffer)) { 00157 res = cfs_read(input_fd, buffer, sizeof(buffer)); 00158 if (res != sizeof(buffer)) return ELFLOADER_INPUT_ERROR; 00159 res = elfloader_output_write_segment(output, buffer, sizeof(buffer)); 00160 if (res != sizeof(buffer)) return ELFLOADER_OUTPUT_ERROR; 00161 len -= sizeof(buffer); 00162 } 00163 res = cfs_read(input_fd, buffer, len); 00164 if (res != len) return ELFLOADER_INPUT_ERROR; 00165 res = elfloader_output_write_segment(output, buffer, len); 00166 if (res != len) return ELFLOADER_OUTPUT_ERROR; 00167 return ELFLOADER_OK; 00168 } 00169 00170 static int 00171 seek_read(int fd, unsigned int offset, char *buf, int len) 00172 { 00173 if (cfs_seek(fd, offset, CFS_SEEK_SET) != offset) return -1; 00174 return cfs_read(fd, buf, len); 00175 } 00176 00177 static void * 00178 find_local_symbol(int input_fd, const char *symbol, 00179 unsigned int symtab, unsigned short symtabsize, 00180 unsigned int strtab) 00181 { 00182 struct elf32_sym s; 00183 unsigned int a; 00184 char name[30]; 00185 struct relevant_section *sect; 00186 int ret; 00187 00188 for(a = symtab; a < symtab + symtabsize; a += sizeof(s)) { 00189 ret = seek_read(input_fd, a, (char *)&s, sizeof(s)); 00190 if (ret < 0) return NULL; 00191 00192 if(s.st_name != 0) { 00193 ret = seek_read(input_fd, strtab + s.st_name, name, sizeof(name)); 00194 if (ret < 0) return NULL; 00195 00196 if(strcmp(name, symbol) == 0) { 00197 if(s.st_shndx == bss.number) { 00198 sect = &bss; 00199 } else if(s.st_shndx == data.number) { 00200 sect = &data; 00201 } else if(s.st_shndx == text.number) { 00202 sect = &text; 00203 } else { 00204 return NULL; 00205 } 00206 return &(sect->address[s.st_value]); 00207 } 00208 } 00209 } 00210 return NULL; 00211 } 00212 /*---------------------------------------------------------------------------*/ 00213 static int 00214 relocate_section(int input_fd, 00215 struct elfloader_output *output, 00216 unsigned int section, unsigned short size, 00217 unsigned int sectionaddr, 00218 char *sectionbase, 00219 unsigned int strs, 00220 unsigned int strtab, 00221 unsigned int symtab, unsigned short symtabsize, 00222 unsigned char using_relas) 00223 { 00224 /* sectionbase added; runtime start address of current section */ 00225 struct elf32_rela rela; /* Now used both for rel and rela data! */ 00226 int rel_size = 0; 00227 struct elf32_sym s; 00228 unsigned int a; 00229 char name[30]; 00230 char *addr; 00231 struct relevant_section *sect; 00232 int ret; 00233 00234 /* determine correct relocation entry sizes */ 00235 if(using_relas) { 00236 rel_size = sizeof(struct elf32_rela); 00237 } else { 00238 rel_size = sizeof(struct elf32_rel); 00239 } 00240 00241 for(a = section; a < section + size; a += rel_size) { 00242 ret = seek_read(input_fd, a, (char *)&rela, rel_size); 00243 if (ret < 0) return ELFLOADER_INPUT_ERROR; 00244 ret = seek_read(input_fd, 00245 (symtab + 00246 sizeof(struct elf32_sym) * ELF32_R_SYM(rela.r_info)), 00247 (char *)&s, sizeof(s)); 00248 if (ret < 0) return ELFLOADER_INPUT_ERROR; 00249 if(s.st_name != 0) { 00250 ret = seek_read(input_fd, strtab + s.st_name, name, sizeof(name)); 00251 if (ret < 0) return ELFLOADER_INPUT_ERROR; 00252 PRINTF("name: %s\n", name); 00253 addr = (char *)symtab_lookup(name); 00254 /* ADDED */ 00255 if(addr == NULL) { 00256 PRINTF("name not found in global: %s\n", name); 00257 addr = find_local_symbol(input_fd, name, symtab, symtabsize, strtab); 00258 PRINTF("found address %p\n", addr); 00259 } 00260 if(addr == NULL) { 00261 if(s.st_shndx == bss.number) { 00262 sect = &bss; 00263 } else if(s.st_shndx == data.number) { 00264 sect = &data; 00265 } else if(s.st_shndx == rodata.number) { 00266 sect = &rodata; 00267 } else if(s.st_shndx == text.number) { 00268 sect = &text; 00269 } else { 00270 PRINTF("elfloader unknown name: '%30s'\n", name); 00271 memcpy(elfloader_unknown, name, sizeof(elfloader_unknown)); 00272 elfloader_unknown[sizeof(elfloader_unknown) - 1] = 0; 00273 return ELFLOADER_SYMBOL_NOT_FOUND; 00274 } 00275 addr = sect->address; 00276 } 00277 } else { 00278 if(s.st_shndx == bss.number) { 00279 sect = &bss; 00280 } else if(s.st_shndx == data.number) { 00281 sect = &data; 00282 } else if(s.st_shndx == rodata.number) { 00283 sect = &rodata; 00284 } else if(s.st_shndx == text.number) { 00285 sect = &text; 00286 } else { 00287 return ELFLOADER_SEGMENT_NOT_FOUND; 00288 } 00289 00290 addr = sect->address; 00291 } 00292 00293 #if 0 /* We don't know how big the relocation is or even if we need to read it. 00294 Let the architecture dependant code decide */ 00295 if (!using_relas) { 00296 /* copy addend to rela structure */ 00297 ret = seek_read(fd, sectionaddr + rela.r_offset, &rela.r_addend, 4); 00298 if (ret < 0) return ELFLOADER_INPUT_ERROR; 00299 } 00300 #endif 00301 { 00302 /* Copy data up to the next relocation */ 00303 unsigned int offset = elfloader_output_segment_offset(output); 00304 if (rela.r_offset < offset) { 00305 PRINTF("elfloader relocation out of offset order\n"); 00306 00307 } 00308 if (rela.r_offset > offset) { 00309 ret = copy_segment_data(input_fd, offset+sectionaddr, output, 00310 rela.r_offset - offset); 00311 if (ret != ELFLOADER_OK) return ret; 00312 } 00313 } 00314 ret = elfloader_arch_relocate(input_fd, output, sectionaddr, sectionbase, 00315 &rela, addr); 00316 if (ret != ELFLOADER_OK) return ret; 00317 } 00318 return ELFLOADER_OK; 00319 } 00320 /*---------------------------------------------------------------------------*/ 00321 static void * 00322 find_program_processes(int input_fd, 00323 unsigned int symtab, unsigned short size, 00324 unsigned int strtab) 00325 { 00326 struct elf32_sym s; 00327 unsigned int a; 00328 char name[30]; 00329 00330 for(a = symtab; a < symtab + size; a += sizeof(s)) { 00331 seek_read(input_fd, a, (char *)&s, sizeof(s)); 00332 00333 if(s.st_name != 0) { 00334 seek_read(input_fd, strtab + s.st_name, name, sizeof(name)); 00335 if(strcmp(name, "autostart_processes") == 0) { 00336 return &data.address[s.st_value]; 00337 } 00338 } 00339 } 00340 return NULL; 00341 /* return find_local_symbol(fd, "autostart_processes", symtab, size, strtab); */ 00342 } 00343 /*---------------------------------------------------------------------------*/ 00344 void 00345 elfloader_init(void) 00346 { 00347 elfloader_autostart_processes = NULL; 00348 } 00349 /*---------------------------------------------------------------------------*/ 00350 #if 0 00351 static void 00352 print_chars(unsigned char *ptr, int num) 00353 { 00354 int i; 00355 for(i = 0; i < num; ++i) { 00356 PRINTF("%d", ptr[i]); 00357 if(i == num - 1) { 00358 PRINTF("\n"); 00359 } else { 00360 PRINTF(", "); 00361 } 00362 } 00363 } 00364 #endif /* 0 */ 00365 00366 static int 00367 copy_segment(int input_fd, 00368 struct elfloader_output *output, 00369 unsigned int section, unsigned short size, 00370 unsigned int sectionaddr, 00371 char *sectionbase, 00372 unsigned int strs, 00373 unsigned int strtab, 00374 unsigned int symtab, unsigned short symtabsize, 00375 unsigned char using_relas, 00376 unsigned int seg_size, unsigned int seg_type) 00377 { 00378 unsigned int offset; 00379 int ret; 00380 ret = elfloader_output_start_segment(output, seg_type,sectionbase, seg_size); 00381 if (ret != ELFLOADER_OK) return ret; 00382 ret = relocate_section(input_fd, output, 00383 section, size, 00384 sectionaddr, 00385 sectionbase, 00386 strs, 00387 strtab, 00388 symtab, symtabsize, using_relas); 00389 if (ret != ELFLOADER_OK) return ret; 00390 offset = elfloader_output_segment_offset(output); 00391 ret = copy_segment_data(input_fd, offset+sectionaddr, output,seg_size - offset); 00392 if (ret != ELFLOADER_OK) return ret; 00393 return elfloader_output_end_segment(output); 00394 } 00395 00396 /*---------------------------------------------------------------------------*/ 00397 int 00398 elfloader_load(int input_fd, struct elfloader_output *output) 00399 { 00400 struct elf32_ehdr ehdr; 00401 struct elf32_shdr shdr; 00402 struct elf32_shdr strtable; 00403 unsigned int strs; 00404 unsigned int shdrptr; 00405 unsigned int nameptr; 00406 char name[12]; 00407 00408 int i; 00409 unsigned short shdrnum, shdrsize; 00410 00411 unsigned char using_relas = -1; 00412 unsigned short textoff = 0, textsize, textrelaoff = 0, textrelasize; 00413 unsigned short dataoff = 0, datasize, datarelaoff = 0, datarelasize; 00414 unsigned short rodataoff = 0, rodatasize, rodatarelaoff = 0, rodatarelasize; 00415 unsigned short symtaboff = 0, symtabsize; 00416 unsigned short strtaboff = 0, strtabsize; 00417 unsigned short bsssize = 0; 00418 00419 struct process **process; 00420 int ret; 00421 00422 elfloader_unknown[0] = 0; 00423 00424 /* The ELF header is located at the start of the buffer. */ 00425 ret = seek_read(input_fd, 0, (char *)&ehdr, sizeof(ehdr)); 00426 if (ret != sizeof(ehdr)) return ELFLOADER_INPUT_ERROR; 00427 00428 /* print_chars(ehdr.e_ident, sizeof(elf_magic_header)); 00429 print_chars(elf_magic_header, sizeof(elf_magic_header));*/ 00430 /* Make sure that we have a correct and compatible ELF header. */ 00431 if(memcmp(ehdr.e_ident, elf_magic_header, sizeof(elf_magic_header)) != 0) { 00432 PRINTF("ELF header problems\n"); 00433 return ELFLOADER_BAD_ELF_HEADER; 00434 } 00435 00436 /* Grab the section header. */ 00437 shdrptr = ehdr.e_shoff; 00438 ret = seek_read(input_fd, shdrptr, (char *)&shdr, sizeof(shdr)); 00439 if (ret != sizeof(shdr)) return ELFLOADER_INPUT_ERROR; 00440 00441 /* Get the size and number of entries of the section header. */ 00442 shdrsize = ehdr.e_shentsize; 00443 shdrnum = ehdr.e_shnum; 00444 00445 /* The string table section: holds the names of the sections. */ 00446 ret = seek_read(input_fd, ehdr.e_shoff + shdrsize * ehdr.e_shstrndx, 00447 (char *)&strtable, sizeof(strtable)); 00448 if (ret != sizeof(strtable)) return ELFLOADER_INPUT_ERROR; 00449 00450 /* Get a pointer to the actual table of strings. This table holds 00451 the names of the sections, not the names of other symbols in the 00452 file (these are in the sybtam section). */ 00453 strs = strtable.sh_offset; 00454 00455 /* Go through all sections and pick out the relevant ones. The 00456 ".text" segment holds the actual code from the ELF file, the 00457 ".data" segment contains initialized data, the ".rodata" segment 00458 contains read-only data, the ".bss" segment holds the size of the 00459 unitialized data segment. The ".rel[a].text" and ".rel[a].data" 00460 segments contains relocation information for the contents of the 00461 ".text" and ".data" segments, respectively. The ".symtab" segment 00462 contains the symbol table for this file. The ".strtab" segment 00463 points to the actual string names used by the symbol table. 00464 00465 In addition to grabbing pointers to the relevant sections, we 00466 also save the section number for resolving addresses in the 00467 relocator code. 00468 */ 00469 00470 00471 /* Initialize the segment sizes to zero so that we can check if 00472 their sections was found in the file or not. */ 00473 textsize = textrelasize = datasize = datarelasize = 00474 rodatasize = rodatarelasize = symtabsize = strtabsize = 0; 00475 00476 bss.number = data.number = rodata.number = text.number = -1; 00477 00478 shdrptr = ehdr.e_shoff; 00479 for(i = 0; i < shdrnum; ++i) { 00480 00481 ret = seek_read(input_fd, shdrptr, (char *)&shdr, sizeof(shdr)); 00482 if (ret != sizeof(shdr)) return ELFLOADER_INPUT_ERROR; 00483 00484 /* The name of the section is contained in the strings table. */ 00485 nameptr = strs + shdr.sh_name; 00486 ret = seek_read(input_fd, nameptr, name, sizeof(name)); 00487 if (ret != sizeof(name)) return ELFLOADER_INPUT_ERROR; 00488 00489 /* Match the name of the section with a predefined set of names 00490 (.text, .data, .bss, .rela.text, .rela.data, .symtab, and 00491 .strtab). */ 00492 /* added support for .rodata, .rel.text and .rel.data). */ 00493 00494 if(strncmp(name, ".text", 5) == 0) { 00495 textoff = shdr.sh_offset; 00496 textsize = shdr.sh_size; 00497 text.number = i; 00498 text.offset = textoff; 00499 } else if(strncmp(name, ".rel.text", 9) == 0) { 00500 using_relas = 0; 00501 textrelaoff = shdr.sh_offset; 00502 textrelasize = shdr.sh_size; 00503 } else if(strncmp(name, ".rela.text", 10) == 0) { 00504 using_relas = 1; 00505 textrelaoff = shdr.sh_offset; 00506 textrelasize = shdr.sh_size; 00507 } else if(strncmp(name, ".data", 5) == 0) { 00508 dataoff = shdr.sh_offset; 00509 datasize = shdr.sh_size; 00510 data.number = i; 00511 data.offset = dataoff; 00512 } else if(strncmp(name, ".rodata", 7) == 0) { 00513 /* read-only data handled the same way as regular text section */ 00514 rodataoff = shdr.sh_offset; 00515 rodatasize = shdr.sh_size; 00516 rodata.number = i; 00517 rodata.offset = rodataoff; 00518 } else if(strncmp(name, ".rel.rodata", 11) == 0) { 00519 /* using elf32_rel instead of rela */ 00520 using_relas = 0; 00521 rodatarelaoff = shdr.sh_offset; 00522 rodatarelasize = shdr.sh_size; 00523 } else if(strncmp(name, ".rela.rodata", 12) == 0) { 00524 using_relas = 1; 00525 rodatarelaoff = shdr.sh_offset; 00526 rodatarelasize = shdr.sh_size; 00527 } else if(strncmp(name, ".rel.data", 9) == 0) { 00528 /* using elf32_rel instead of rela */ 00529 using_relas = 0; 00530 datarelaoff = shdr.sh_offset; 00531 datarelasize = shdr.sh_size; 00532 } else if(strncmp(name, ".rela.data", 10) == 0) { 00533 using_relas = 1; 00534 datarelaoff = shdr.sh_offset; 00535 datarelasize = shdr.sh_size; 00536 } else if(strncmp(name, ".symtab", 7) == 0) { 00537 symtaboff = shdr.sh_offset; 00538 symtabsize = shdr.sh_size; 00539 } else if(strncmp(name, ".strtab", 7) == 0) { 00540 strtaboff = shdr.sh_offset; 00541 strtabsize = shdr.sh_size; 00542 } else if(strncmp(name, ".bss", 4) == 0) { 00543 bsssize = shdr.sh_size; 00544 bss.number = i; 00545 bss.offset = 0; 00546 } 00547 00548 /* Move on to the next section header. */ 00549 shdrptr += shdrsize; 00550 } 00551 00552 if(symtabsize == 0) { 00553 return ELFLOADER_NO_SYMTAB; 00554 } 00555 if(strtabsize == 0) { 00556 return ELFLOADER_NO_STRTAB; 00557 } 00558 if(textsize == 0) { 00559 return ELFLOADER_NO_TEXT; 00560 } 00561 00562 00563 if (bsssize) { 00564 bss.address = (char *) 00565 elfloader_output_alloc_segment(output, ELFLOADER_SEG_BSS, bsssize); 00566 if (!bss.address) return ELFLOADER_OUTPUT_ERROR; 00567 } 00568 if (datasize) { 00569 data.address = (char *) 00570 elfloader_output_alloc_segment(output,ELFLOADER_SEG_DATA,datasize); 00571 if (!data.address) return ELFLOADER_OUTPUT_ERROR; 00572 } 00573 if (textsize) { 00574 text.address = (char *) 00575 elfloader_output_alloc_segment(output,ELFLOADER_SEG_TEXT,textsize); 00576 if (!text.address) return ELFLOADER_OUTPUT_ERROR; 00577 } 00578 if (rodatasize) { 00579 rodata.address = (char *) 00580 elfloader_output_alloc_segment(output,ELFLOADER_SEG_RODATA,rodatasize); 00581 if (!rodata.address) return ELFLOADER_OUTPUT_ERROR; 00582 } 00583 00584 /* printf("bss base address: bss.address = 0x%08x\n", bss.address); 00585 printf("data base address: data.address = 0x%08x\n", data.address); 00586 printf("text base address: text.address = 0x%08x\n", text.address); 00587 printf("rodata base address: rodata.address = 0x%08x\n", rodata.address); */ 00588 00589 00590 /* If we have text segment relocations, we process them. */ 00591 PRINTF("elfloader: relocate text\n"); 00592 if(textrelasize > 0) { 00593 ret = copy_segment(input_fd, output, 00594 textrelaoff, textrelasize, 00595 textoff, 00596 text.address, 00597 strs, 00598 strtaboff, 00599 symtaboff, symtabsize, using_relas, 00600 textsize, ELFLOADER_SEG_TEXT); 00601 if(ret != ELFLOADER_OK) { 00602 return ret; 00603 } 00604 } 00605 00606 /* If we have any rodata segment relocations, we process them too. */ 00607 PRINTF("elfloader: relocate rodata\n"); 00608 if(rodatarelasize > 0) { 00609 ret = copy_segment(input_fd, output, 00610 rodatarelaoff, rodatarelasize, 00611 rodataoff, 00612 rodata.address, 00613 strs, 00614 strtaboff, 00615 symtaboff, symtabsize, using_relas, 00616 rodatasize, ELFLOADER_SEG_RODATA); 00617 if(ret != ELFLOADER_OK) { 00618 PRINTF("elfloader: data failed\n"); 00619 return ret; 00620 } 00621 } 00622 00623 /* If we have any data segment relocations, we process them too. */ 00624 PRINTF("elfloader: relocate data\n"); 00625 if(datarelasize > 0) { 00626 ret = copy_segment(input_fd, output, 00627 datarelaoff, datarelasize, 00628 dataoff, 00629 data.address, 00630 strs, 00631 strtaboff, 00632 symtaboff, symtabsize, using_relas, 00633 datasize, ELFLOADER_SEG_DATA); 00634 if(ret != ELFLOADER_OK) { 00635 PRINTF("elfloader: data failed\n"); 00636 return ret; 00637 } 00638 ret = elfloader_output_end_segment(output); 00639 if (ret != ELFLOADER_OK) return ret; 00640 } 00641 00642 /* Write text and rodata segment into flash and data segment into RAM. */ 00643 /* elfloader_arch_write_rom(fd, textoff, textsize, text.address); */ 00644 /* elfloader_arch_write_rom(fd, rodataoff, rodatasize, rodata.address); */ 00645 00646 /* memset(bss.address, 0, bsssize); */ 00647 /* seek_read(fd, dataoff, data.address, datasize); */ 00648 00649 { 00650 /* Write zeros to bss segment */ 00651 unsigned int len = bsssize; 00652 static const char zeros[16] = {0}; 00653 ret = elfloader_output_start_segment(output, ELFLOADER_SEG_BSS, 00654 bss.address,bsssize); 00655 if (ret != ELFLOADER_OK) return ret; 00656 while(len > sizeof(zeros)) { 00657 ret = elfloader_output_write_segment(output, zeros, sizeof(zeros)); 00658 if (ret != sizeof(zeros)) return ELFLOADER_OUTPUT_ERROR; 00659 len -= sizeof(zeros); 00660 } 00661 ret = elfloader_output_write_segment(output, zeros, len); 00662 if (ret != len) return ELFLOADER_OUTPUT_ERROR; 00663 } 00664 00665 PRINTF("elfloader: autostart search\n"); 00666 process = find_local_symbol(input_fd, "autostart_processes", symtaboff, symtabsize, strtaboff); 00667 if(process != NULL) { 00668 PRINTF("elfloader: autostart found\n"); 00669 elfloader_autostart_processes = process; 00670 return ELFLOADER_OK; 00671 } else { 00672 PRINTF("elfloader: no autostart\n"); 00673 process = find_program_processes(input_fd, symtaboff, symtabsize, strtaboff); 00674 if(process != NULL) { 00675 PRINTF("elfloader: FOUND PRG\n"); 00676 } 00677 return ELFLOADER_NO_STARTPOINT; 00678 } 00679 } 00680 /*---------------------------------------------------------------------------*/