Contiki 3.x
elfloader-otf.c
1 /*
2  * Copyright (c) 2005, Swedish Institute of Computer Science
3  * Copyright (c) 2007, Simon Berg
4  * All rights reserved.
5  *
6  * Redistribution and use in source and binary forms, with or without
7  * modification, are permitted provided that the following conditions
8  * are met:
9  * 1. Redistributions of source code must retain the above copyright
10  * notice, this list of conditions and the following disclaimer.
11  * 2. Redistributions in binary form must reproduce the above copyright
12  * notice, this list of conditions and the following disclaimer in the
13  * documentation and/or other materials provided with the distribution.
14  * 3. Neither the name of the Institute nor the names of its contributors
15  * may be used to endorse or promote products derived from this software
16  * without specific prior written permission.
17  *
18  * THIS SOFTWARE IS PROVIDED BY THE INSTITUTE AND CONTRIBUTORS ``AS IS'' AND
19  * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
20  * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
21  * ARE DISCLAIMED. IN NO EVENT SHALL THE INSTITUTE OR CONTRIBUTORS BE LIABLE
22  * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
23  * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
24  * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
25  * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
26  * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
27  * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
28  * SUCH DAMAGE.
29  *
30  * This file is part of the Contiki operating system.
31  *
32  */
33 
34 #include "contiki.h"
35 
36 #include "loader/elfloader-otf.h"
38 
39 #include "cfs/cfs.h"
40 #include "loader/symtab.h"
41 
42 #include <stddef.h>
43 #include <string.h>
44 #include <stdio.h>
45 
46 #if 0
47 #include <stdio.h>
48 #define PRINTF(...) printf(__VA_ARGS__)
49 #else
50 #define PRINTF(...) do {} while (0)
51 #endif
52 
53 #define EI_NIDENT 16
54 
55 
56 struct elf32_ehdr {
57  unsigned char e_ident[EI_NIDENT]; /* ident bytes */
58  elf32_half e_type; /* file type */
59  elf32_half e_machine; /* target machine */
60  elf32_word e_version; /* file version */
61  elf32_addr e_entry; /* start address */
62  elf32_off e_phoff; /* phdr file offset */
63  elf32_off e_shoff; /* shdr file offset */
64  elf32_word e_flags; /* file flags */
65  elf32_half e_ehsize; /* sizeof ehdr */
66  elf32_half e_phentsize; /* sizeof phdr */
67  elf32_half e_phnum; /* number phdrs */
68  elf32_half e_shentsize; /* sizeof shdr */
69  elf32_half e_shnum; /* number shdrs */
70  elf32_half e_shstrndx; /* shdr string index */
71 };
72 
73 /* Values for e_type. */
74 #define ET_NONE 0 /* Unknown type. */
75 #define ET_REL 1 /* Relocatable. */
76 #define ET_EXEC 2 /* Executable. */
77 #define ET_DYN 3 /* Shared object. */
78 #define ET_CORE 4 /* Core file. */
79 
80 struct elf32_shdr {
81  elf32_word sh_name; /* section name */
82  elf32_word sh_type; /* SHT_... */
83  elf32_word sh_flags; /* SHF_... */
84  elf32_addr sh_addr; /* virtual address */
85  elf32_off sh_offset; /* file offset */
86  elf32_word sh_size; /* section size */
87  elf32_word sh_link; /* misc info */
88  elf32_word sh_info; /* misc info */
89  elf32_word sh_addralign; /* memory alignment */
90  elf32_word sh_entsize; /* entry size if table */
91 };
92 
93 /* sh_type */
94 #define SHT_NULL 0 /* inactive */
95 #define SHT_PROGBITS 1 /* program defined information */
96 #define SHT_SYMTAB 2 /* symbol table section */
97 #define SHT_STRTAB 3 /* string table section */
98 #define SHT_RELA 4 /* relocation section with addends*/
99 #define SHT_HASH 5 /* symbol hash table section */
100 #define SHT_DYNAMIC 6 /* dynamic section */
101 #define SHT_NOTE 7 /* note section */
102 #define SHT_NOBITS 8 /* no space section */
103 #define SHT_REL 9 /* relation section without addends */
104 #define SHT_SHLIB 10 /* reserved - purpose unknown */
105 #define SHT_DYNSYM 11 /* dynamic symbol table section */
106 #define SHT_LOPROC 0x70000000 /* reserved range for processor */
107 #define SHT_HIPROC 0x7fffffff /* specific section header types */
108 #define SHT_LOUSER 0x80000000 /* reserved range for application */
109 #define SHT_HIUSER 0xffffffff /* specific indexes */
110 
111 struct elf32_rel {
112  elf32_addr r_offset; /* Location to be relocated. */
113  elf32_word r_info; /* Relocation type and symbol index. */
114 };
115 
116 struct elf32_sym {
117  elf32_word st_name; /* String table index of name. */
118  elf32_addr st_value; /* Symbol value. */
119  elf32_word st_size; /* Size of associated object. */
120  unsigned char st_info; /* Type and binding information. */
121  unsigned char st_other; /* Reserved (not used). */
122  elf32_half st_shndx; /* Section index of symbol. */
123 };
124 
125 #define ELF32_R_SYM(info) ((info) >> 8)
126 #define ELF32_R_TYPE(info) ((unsigned char)(info))
127 
128 struct relevant_section {
129  unsigned char number;
130  unsigned int offset;
131  char *address;
132 };
133 
134 char elfloader_unknown[30]; /* Name that caused link error. */
135 
137 
138 static struct relevant_section bss, data, rodata, text;
139 
140 const static unsigned char elf_magic_header[] =
141  {0x7f, 0x45, 0x4c, 0x46, /* 0x7f, 'E', 'L', 'F' */
142  0x01, /* Only 32-bit objects. */
143  0x01, /* Only LSB data. */
144  0x01, /* Only ELF version 1. */
145  };
146 
147 /* Copy data from the elf file to a segment */
148 static int
149 copy_segment_data(int input_fd, unsigned int offset,
150  struct elfloader_output *output, unsigned int len)
151 {
152  char buffer[16];
153  int res;
154  if (cfs_seek(input_fd, offset, CFS_SEEK_SET) != offset) return ELFLOADER_INPUT_ERROR;
155  while(len > sizeof(buffer)) {
156  res = cfs_read(input_fd, buffer, sizeof(buffer));
157  if (res != sizeof(buffer)) return ELFLOADER_INPUT_ERROR;
158  res = elfloader_output_write_segment(output, buffer, sizeof(buffer));
159  if (res != sizeof(buffer)) return ELFLOADER_OUTPUT_ERROR;
160  len -= sizeof(buffer);
161  }
162  res = cfs_read(input_fd, buffer, len);
163  if (res != len) return ELFLOADER_INPUT_ERROR;
164  res = elfloader_output_write_segment(output, buffer, len);
165  if (res != len) return ELFLOADER_OUTPUT_ERROR;
166  return ELFLOADER_OK;
167 }
168 
169 static int
170 seek_read(int fd, unsigned int offset, char *buf, int len)
171 {
172  if (cfs_seek(fd, offset, CFS_SEEK_SET) != offset) return -1;
173  return cfs_read(fd, buf, len);
174 }
175 
176 static void *
177 find_local_symbol(int input_fd, const char *symbol,
178  unsigned int symtab, unsigned short symtabsize,
179  unsigned int strtab)
180 {
181  struct elf32_sym s;
182  unsigned int a;
183  char name[30];
184  struct relevant_section *sect;
185  int ret;
186 
187  for(a = symtab; a < symtab + symtabsize; a += sizeof(s)) {
188  ret = seek_read(input_fd, a, (char *)&s, sizeof(s));
189  if (ret < 0) return NULL;
190 
191  if(s.st_name != 0) {
192  ret = seek_read(input_fd, strtab + s.st_name, name, sizeof(name));
193  if (ret < 0) return NULL;
194 
195  if(strcmp(name, symbol) == 0) {
196  if(s.st_shndx == bss.number) {
197  sect = &bss;
198  } else if(s.st_shndx == data.number) {
199  sect = &data;
200  } else if(s.st_shndx == text.number) {
201  sect = &text;
202  } else {
203  return NULL;
204  }
205  return &(sect->address[s.st_value]);
206  }
207  }
208  }
209  return NULL;
210 }
211 /*---------------------------------------------------------------------------*/
212 static int
213 relocate_section(int input_fd,
214  struct elfloader_output *output,
215  unsigned int section, unsigned short size,
216  unsigned int sectionaddr,
217  char *sectionbase,
218  unsigned int strs,
219  unsigned int strtab,
220  unsigned int symtab, unsigned short symtabsize,
221  unsigned char using_relas)
222 {
223  /* sectionbase added; runtime start address of current section */
224  struct elf32_rela rela; /* Now used both for rel and rela data! */
225  int rel_size = 0;
226  struct elf32_sym s;
227  unsigned int a;
228  char name[30];
229  char *addr;
230  struct relevant_section *sect;
231  int ret;
232 
233  /* determine correct relocation entry sizes */
234  if(using_relas) {
235  rel_size = sizeof(struct elf32_rela);
236  } else {
237  rel_size = sizeof(struct elf32_rel);
238  }
239 
240  for(a = section; a < section + size; a += rel_size) {
241  ret = seek_read(input_fd, a, (char *)&rela, rel_size);
242  if (ret < 0) return ELFLOADER_INPUT_ERROR;
243  ret = seek_read(input_fd,
244  (symtab +
245  sizeof(struct elf32_sym) * ELF32_R_SYM(rela.r_info)),
246  (char *)&s, sizeof(s));
247  if (ret < 0) return ELFLOADER_INPUT_ERROR;
248  if(s.st_name != 0) {
249  ret = seek_read(input_fd, strtab + s.st_name, name, sizeof(name));
250  if (ret < 0) return ELFLOADER_INPUT_ERROR;
251  PRINTF("name: %s\n", name);
252  addr = (char *)symtab_lookup(name);
253  /* ADDED */
254  if(addr == NULL) {
255  PRINTF("name not found in global: %s\n", name);
256  addr = find_local_symbol(input_fd, name, symtab, symtabsize, strtab);
257  PRINTF("found address %p\n", addr);
258  }
259  if(addr == NULL) {
260  if(s.st_shndx == bss.number) {
261  sect = &bss;
262  } else if(s.st_shndx == data.number) {
263  sect = &data;
264  } else if(s.st_shndx == rodata.number) {
265  sect = &rodata;
266  } else if(s.st_shndx == text.number) {
267  sect = &text;
268  } else {
269  PRINTF("elfloader unknown name: '%30s'\n", name);
270  memcpy(elfloader_unknown, name, sizeof(elfloader_unknown));
271  elfloader_unknown[sizeof(elfloader_unknown) - 1] = 0;
273  }
274  addr = sect->address;
275  }
276  } else {
277  if(s.st_shndx == bss.number) {
278  sect = &bss;
279  } else if(s.st_shndx == data.number) {
280  sect = &data;
281  } else if(s.st_shndx == rodata.number) {
282  sect = &rodata;
283  } else if(s.st_shndx == text.number) {
284  sect = &text;
285  } else {
287  }
288 
289  addr = sect->address;
290  }
291 
292 #if 0 /* We don't know how big the relocation is or even if we need to read it.
293  Let the architecture dependant code decide */
294  if (!using_relas) {
295  /* copy addend to rela structure */
296  ret = seek_read(fd, sectionaddr + rela.r_offset, &rela.r_addend, 4);
297  if (ret < 0) return ELFLOADER_INPUT_ERROR;
298  }
299 #endif
300  {
301  /* Copy data up to the next relocation */
302  unsigned int offset = elfloader_output_segment_offset(output);
303  if (rela.r_offset < offset) {
304  PRINTF("elfloader relocation out of offset order\n");
305 
306  }
307  if (rela.r_offset > offset) {
308  ret = copy_segment_data(input_fd, offset+sectionaddr, output,
309  rela.r_offset - offset);
310  if (ret != ELFLOADER_OK) return ret;
311  }
312  }
313  ret = elfloader_arch_relocate(input_fd, output, sectionaddr, sectionbase,
314  &rela, addr);
315  if (ret != ELFLOADER_OK) return ret;
316  }
317  return ELFLOADER_OK;
318 }
319 /*---------------------------------------------------------------------------*/
320 static void *
321 find_program_processes(int input_fd,
322  unsigned int symtab, unsigned short size,
323  unsigned int strtab)
324 {
325  struct elf32_sym s;
326  unsigned int a;
327  char name[30];
328 
329  for(a = symtab; a < symtab + size; a += sizeof(s)) {
330  seek_read(input_fd, a, (char *)&s, sizeof(s));
331 
332  if(s.st_name != 0) {
333  seek_read(input_fd, strtab + s.st_name, name, sizeof(name));
334  if(strcmp(name, "autostart_processes") == 0) {
335  return &data.address[s.st_value];
336  }
337  }
338  }
339  return NULL;
340 /* return find_local_symbol(fd, "autostart_processes", symtab, size, strtab); */
341 }
342 /*---------------------------------------------------------------------------*/
343 void
345 {
347 }
348 /*---------------------------------------------------------------------------*/
349 #if 0
350 static void
351 print_chars(unsigned char *ptr, int num)
352 {
353  int i;
354  for(i = 0; i < num; ++i) {
355  PRINTF("%d", ptr[i]);
356  if(i == num - 1) {
357  PRINTF("\n");
358  } else {
359  PRINTF(", ");
360  }
361  }
362 }
363 #endif /* 0 */
364 
365 static int
366 copy_segment(int input_fd,
367  struct elfloader_output *output,
368  unsigned int section, unsigned short size,
369  unsigned int sectionaddr,
370  char *sectionbase,
371  unsigned int strs,
372  unsigned int strtab,
373  unsigned int symtab, unsigned short symtabsize,
374  unsigned char using_relas,
375  unsigned int seg_size, unsigned int seg_type)
376 {
377  unsigned int offset;
378  int ret;
379  ret = elfloader_output_start_segment(output, seg_type,sectionbase, seg_size);
380  if (ret != ELFLOADER_OK) return ret;
381  ret = relocate_section(input_fd, output,
382  section, size,
383  sectionaddr,
384  sectionbase,
385  strs,
386  strtab,
387  symtab, symtabsize, using_relas);
388  if (ret != ELFLOADER_OK) return ret;
389  offset = elfloader_output_segment_offset(output);
390  ret = copy_segment_data(input_fd, offset+sectionaddr, output,seg_size - offset);
391  if (ret != ELFLOADER_OK) return ret;
392  return elfloader_output_end_segment(output);
393 }
394 
395 /*---------------------------------------------------------------------------*/
396 int
397 elfloader_load(int input_fd, struct elfloader_output *output)
398 {
399  struct elf32_ehdr ehdr;
400  struct elf32_shdr shdr;
401  struct elf32_shdr strtable;
402  unsigned int strs;
403  unsigned int shdrptr;
404  unsigned int nameptr;
405  char name[12];
406 
407  int i;
408  unsigned short shdrnum, shdrsize;
409 
410  unsigned char using_relas = -1;
411  unsigned short textoff = 0, textsize, textrelaoff = 0, textrelasize;
412  unsigned short dataoff = 0, datasize, datarelaoff = 0, datarelasize;
413  unsigned short rodataoff = 0, rodatasize, rodatarelaoff = 0, rodatarelasize;
414  unsigned short symtaboff = 0, symtabsize;
415  unsigned short strtaboff = 0, strtabsize;
416  unsigned short bsssize = 0;
417 
418  struct process **process;
419  int ret;
420 
421  elfloader_unknown[0] = 0;
422 
423  /* The ELF header is located at the start of the buffer. */
424  ret = seek_read(input_fd, 0, (char *)&ehdr, sizeof(ehdr));
425  if (ret != sizeof(ehdr)) return ELFLOADER_INPUT_ERROR;
426 
427  /* print_chars(ehdr.e_ident, sizeof(elf_magic_header));
428  print_chars(elf_magic_header, sizeof(elf_magic_header));*/
429  /* Make sure that we have a correct and compatible ELF header. */
430  if(memcmp(ehdr.e_ident, elf_magic_header, sizeof(elf_magic_header)) != 0) {
431  PRINTF("ELF header problems\n");
433  }
434 
435  /* Grab the section header. */
436  shdrptr = ehdr.e_shoff;
437  ret = seek_read(input_fd, shdrptr, (char *)&shdr, sizeof(shdr));
438  if (ret != sizeof(shdr)) return ELFLOADER_INPUT_ERROR;
439 
440  /* Get the size and number of entries of the section header. */
441  shdrsize = ehdr.e_shentsize;
442  shdrnum = ehdr.e_shnum;
443 
444  /* The string table section: holds the names of the sections. */
445  ret = seek_read(input_fd, ehdr.e_shoff + shdrsize * ehdr.e_shstrndx,
446  (char *)&strtable, sizeof(strtable));
447  if (ret != sizeof(strtable)) return ELFLOADER_INPUT_ERROR;
448 
449  /* Get a pointer to the actual table of strings. This table holds
450  the names of the sections, not the names of other symbols in the
451  file (these are in the sybtam section). */
452  strs = strtable.sh_offset;
453 
454  /* Go through all sections and pick out the relevant ones. The
455  ".text" segment holds the actual code from the ELF file, the
456  ".data" segment contains initialized data, the ".rodata" segment
457  contains read-only data, the ".bss" segment holds the size of the
458  unitialized data segment. The ".rel[a].text" and ".rel[a].data"
459  segments contains relocation information for the contents of the
460  ".text" and ".data" segments, respectively. The ".symtab" segment
461  contains the symbol table for this file. The ".strtab" segment
462  points to the actual string names used by the symbol table.
463 
464  In addition to grabbing pointers to the relevant sections, we
465  also save the section number for resolving addresses in the
466  relocator code.
467  */
468 
469 
470  /* Initialize the segment sizes to zero so that we can check if
471  their sections was found in the file or not. */
472  textsize = textrelasize = datasize = datarelasize =
473  rodatasize = rodatarelasize = symtabsize = strtabsize = 0;
474 
475  bss.number = data.number = rodata.number = text.number = -1;
476 
477  shdrptr = ehdr.e_shoff;
478  for(i = 0; i < shdrnum; ++i) {
479 
480  ret = seek_read(input_fd, shdrptr, (char *)&shdr, sizeof(shdr));
481  if (ret != sizeof(shdr)) return ELFLOADER_INPUT_ERROR;
482 
483  /* The name of the section is contained in the strings table. */
484  nameptr = strs + shdr.sh_name;
485  ret = seek_read(input_fd, nameptr, name, sizeof(name));
486  if (ret != sizeof(name)) return ELFLOADER_INPUT_ERROR;
487 
488  /* Match the name of the section with a predefined set of names
489  (.text, .data, .bss, .rela.text, .rela.data, .symtab, and
490  .strtab). */
491  /* added support for .rodata, .rel.text and .rel.data). */
492 
493  if(strncmp(name, ".text", 5) == 0) {
494  textoff = shdr.sh_offset;
495  textsize = shdr.sh_size;
496  text.number = i;
497  text.offset = textoff;
498  } else if(strncmp(name, ".rel.text", 9) == 0) {
499  using_relas = 0;
500  textrelaoff = shdr.sh_offset;
501  textrelasize = shdr.sh_size;
502  } else if(strncmp(name, ".rela.text", 10) == 0) {
503  using_relas = 1;
504  textrelaoff = shdr.sh_offset;
505  textrelasize = shdr.sh_size;
506  } else if(strncmp(name, ".data", 5) == 0) {
507  dataoff = shdr.sh_offset;
508  datasize = shdr.sh_size;
509  data.number = i;
510  data.offset = dataoff;
511  } else if(strncmp(name, ".rodata", 7) == 0) {
512  /* read-only data handled the same way as regular text section */
513  rodataoff = shdr.sh_offset;
514  rodatasize = shdr.sh_size;
515  rodata.number = i;
516  rodata.offset = rodataoff;
517  } else if(strncmp(name, ".rel.rodata", 11) == 0) {
518  /* using elf32_rel instead of rela */
519  using_relas = 0;
520  rodatarelaoff = shdr.sh_offset;
521  rodatarelasize = shdr.sh_size;
522  } else if(strncmp(name, ".rela.rodata", 12) == 0) {
523  using_relas = 1;
524  rodatarelaoff = shdr.sh_offset;
525  rodatarelasize = shdr.sh_size;
526  } else if(strncmp(name, ".rel.data", 9) == 0) {
527  /* using elf32_rel instead of rela */
528  using_relas = 0;
529  datarelaoff = shdr.sh_offset;
530  datarelasize = shdr.sh_size;
531  } else if(strncmp(name, ".rela.data", 10) == 0) {
532  using_relas = 1;
533  datarelaoff = shdr.sh_offset;
534  datarelasize = shdr.sh_size;
535  } else if(strncmp(name, ".symtab", 7) == 0) {
536  symtaboff = shdr.sh_offset;
537  symtabsize = shdr.sh_size;
538  } else if(strncmp(name, ".strtab", 7) == 0) {
539  strtaboff = shdr.sh_offset;
540  strtabsize = shdr.sh_size;
541  } else if(strncmp(name, ".bss", 4) == 0) {
542  bsssize = shdr.sh_size;
543  bss.number = i;
544  bss.offset = 0;
545  }
546 
547  /* Move on to the next section header. */
548  shdrptr += shdrsize;
549  }
550 
551  if(symtabsize == 0) {
552  return ELFLOADER_NO_SYMTAB;
553  }
554  if(strtabsize == 0) {
555  return ELFLOADER_NO_STRTAB;
556  }
557  if(textsize == 0) {
558  return ELFLOADER_NO_TEXT;
559  }
560 
561 
562  if (bsssize) {
563  bss.address = (char *)
564  elfloader_output_alloc_segment(output, ELFLOADER_SEG_BSS, bsssize);
565  if (!bss.address) return ELFLOADER_OUTPUT_ERROR;
566  }
567  if (datasize) {
568  data.address = (char *)
569  elfloader_output_alloc_segment(output,ELFLOADER_SEG_DATA,datasize);
570  if (!data.address) return ELFLOADER_OUTPUT_ERROR;
571  }
572  if (textsize) {
573  text.address = (char *)
574  elfloader_output_alloc_segment(output,ELFLOADER_SEG_TEXT,textsize);
575  if (!text.address) return ELFLOADER_OUTPUT_ERROR;
576  }
577  if (rodatasize) {
578  rodata.address = (char *)
579  elfloader_output_alloc_segment(output,ELFLOADER_SEG_RODATA,rodatasize);
580  if (!rodata.address) return ELFLOADER_OUTPUT_ERROR;
581  }
582 
583 /* printf("bss base address: bss.address = 0x%08x\n", bss.address);
584  printf("data base address: data.address = 0x%08x\n", data.address);
585  printf("text base address: text.address = 0x%08x\n", text.address);
586  printf("rodata base address: rodata.address = 0x%08x\n", rodata.address); */
587 
588 
589  /* If we have text segment relocations, we process them. */
590  PRINTF("elfloader: relocate text\n");
591  if(textrelasize > 0) {
592  ret = copy_segment(input_fd, output,
593  textrelaoff, textrelasize,
594  textoff,
595  text.address,
596  strs,
597  strtaboff,
598  symtaboff, symtabsize, using_relas,
599  textsize, ELFLOADER_SEG_TEXT);
600  if(ret != ELFLOADER_OK) {
601  return ret;
602  }
603  }
604 
605  /* If we have any rodata segment relocations, we process them too. */
606  PRINTF("elfloader: relocate rodata\n");
607  if(rodatarelasize > 0) {
608  ret = copy_segment(input_fd, output,
609  rodatarelaoff, rodatarelasize,
610  rodataoff,
611  rodata.address,
612  strs,
613  strtaboff,
614  symtaboff, symtabsize, using_relas,
615  rodatasize, ELFLOADER_SEG_RODATA);
616  if(ret != ELFLOADER_OK) {
617  PRINTF("elfloader: data failed\n");
618  return ret;
619  }
620  }
621 
622  /* If we have any data segment relocations, we process them too. */
623  PRINTF("elfloader: relocate data\n");
624  if(datarelasize > 0) {
625  ret = copy_segment(input_fd, output,
626  datarelaoff, datarelasize,
627  dataoff,
628  data.address,
629  strs,
630  strtaboff,
631  symtaboff, symtabsize, using_relas,
632  datasize, ELFLOADER_SEG_DATA);
633  if(ret != ELFLOADER_OK) {
634  PRINTF("elfloader: data failed\n");
635  return ret;
636  }
637  ret = elfloader_output_end_segment(output);
638  if (ret != ELFLOADER_OK) return ret;
639  }
640 
641  /* Write text and rodata segment into flash and data segment into RAM. */
642 /* elfloader_arch_write_rom(fd, textoff, textsize, text.address); */
643 /* elfloader_arch_write_rom(fd, rodataoff, rodatasize, rodata.address); */
644 
645 /* memset(bss.address, 0, bsssize); */
646 /* seek_read(fd, dataoff, data.address, datasize); */
647 
648  {
649  /* Write zeros to bss segment */
650  unsigned int len = bsssize;
651  static const char zeros[16] = {0};
652  ret = elfloader_output_start_segment(output, ELFLOADER_SEG_BSS,
653  bss.address,bsssize);
654  if (ret != ELFLOADER_OK) return ret;
655  while(len > sizeof(zeros)) {
656  ret = elfloader_output_write_segment(output, zeros, sizeof(zeros));
657  if (ret != sizeof(zeros)) return ELFLOADER_OUTPUT_ERROR;
658  len -= sizeof(zeros);
659  }
660  ret = elfloader_output_write_segment(output, zeros, len);
661  if (ret != len) return ELFLOADER_OUTPUT_ERROR;
662  }
663 
664  PRINTF("elfloader: autostart search\n");
665  process = find_local_symbol(input_fd, "autostart_processes", symtaboff, symtabsize, strtaboff);
666  if(process != NULL) {
667  PRINTF("elfloader: autostart found\n");
669  return ELFLOADER_OK;
670  } else {
671  PRINTF("elfloader: no autostart\n");
672  process = find_program_processes(input_fd, symtaboff, symtabsize, strtaboff);
673  if(process != NULL) {
674  PRINTF("elfloader: FOUND PRG\n");
675  }
677  }
678 }
679 /*---------------------------------------------------------------------------*/
#define ELFLOADER_NO_TEXT
Return value from elfloader_load() indicating that the size of the .text segment was zero...
Definition: elfloader.h:103
#define ELFLOADER_SEGMENT_NOT_FOUND
Return value from elfloader_load() indicating that one of the required segments (.data, .bss, or .text) could not be found.
Definition: elfloader.h:116
void elfloader_arch_relocate(int fd, unsigned int sectionoffset, char *sectionaddr, struct elf32_rela *rela, char *addr)
Perform a relocation.
void elfloader_init(void)
elfloader initialization function.
Definition: elfloader.c:317
cfs_offset_t cfs_seek(int fd, cfs_offset_t offset, int whence)
Seek to a specified position in an open file.
Definition: cfs-coffee.c:1042
Header file for the architecture specific parts of the Contiki ELF loader.
int elfloader_load(int fd)
Load and relocate an ELF file.
Definition: elfloader.c:339
#define NULL
The null pointer.
#define ELFLOADER_NO_STRTAB
Return value from elfloader_load() indicating that no string table could be found in the ELF file...
Definition: elfloader.h:98
#define ELFLOADER_NO_SYMTAB
Return value from elfloader_load() indicating that no symbol table could be found in the ELF file...
Definition: elfloader.h:93
cle_scratch elfloader_unknown
If elfloader_load() could not find a specific symbol, it is copied into this array.
Definition: tcp_loader2.c:105
#define ELFLOADER_INPUT_ERROR
Return value from elfloader_load() indicating that reading from the ELF file failed in some way...
#define ELFLOADER_OUTPUT_ERROR
Return value from elfloader_load() indicating that writing to a segment failed.
Header file for the Contiki ELF loader.
struct process *const * elfloader_autostart_processes
A pointer to the processes loaded with elfloader_load().
Definition: elfloader.c:136
#define ELFLOADER_BAD_ELF_HEADER
Return value from elfloader_load() indicating that the ELF file had a bad header. ...
Definition: elfloader.h:88
#define ELFLOADER_SYMBOL_NOT_FOUND
Return value from elfloader_load() indicating that a symbol specific symbol could not be found...
Definition: elfloader.h:111
#define ELFLOADER_OK
Return value from elfloader_load() indicating that loading worked.
Definition: elfloader.h:83
#define ELFLOADER_NO_STARTPOINT
Return value from elfloader_load() indicating that no starting point could be found in the loaded mod...
Definition: elfloader.h:121
#define CFS_SEEK_SET
Specify that cfs_seek() should compute the offset from the beginning of the file. ...
Definition: cfs.h:127
elfloader output object
CFS header file.