CHDK_DE Vorschauversion  Trunk Rev. 5663
 Alle Datenstrukturen Dateien Funktionen Variablen Typdefinitionen Aufzählungen Aufzählungswerte Makrodefinitionen
elfflt.h-Dateireferenz
#include <unistd.h>
#include "elf.h"
#include "flt.h"
+ Include-Abhängigkeitsdiagramm für elfflt.h:
+ Dieser Graph zeigt, welche Datei direkt oder indirekt diese Datei enthält:

gehe zum Quellcode dieser Datei

Datenstrukturen

struct  relevant_section
 
struct  import_record_t
 

Makrodefinitionen

#define USE_INT32_FOR_PTRS
 
#define ELFFLT_OK   0
 
#define ELFFLT_BAD_ELF_HEADER   1
 
#define ELFFLT_NO_SYMTAB   2
 
#define ELFFLT_NO_STRTAB   3
 
#define ELFFLT_NO_TEXT   4
 
#define ELFFLT_SYMBOL_NOT_FOUND   5
 
#define ELFFLT_SEGMENT_NOT_FOUND   6
 
#define ELFFLT_NO_MODULEINFO   7
 
#define ELFFLT_UNHANDLED_RELOC   8
 
#define ELFFLT_OUTOF_RANGE   9
 
#define ELFFLT_INPUT_ERROR   10
 
#define ELFFLT_OUTPUT_ERROR   11
 
#define ELFFLT_UNSAFE_SYMBOL   12
 

Typdefinitionen

typedef uint32_t reloc_record_t
 

Funktionen

int elfloader_load (char *fltfile)
 Load and relocate an ELF file. Mehr ...
 
int apply_realloc (struct relevant_section *base_sect, struct elf32_rela *rela, struct relevant_section *tgt_sect, struct elf32_sym *sym, int symidx)
 
int apply_import (struct relevant_section *base_sect, struct elf32_rela *rela, int importidx, struct elf32_sym *sym)
 

Variablen

struct relevant_section bss
data rodata 
text
 
char * flat_buf
 
flat_hdrflat
 
uint32_t flat_reloc_count
 
reloc_record_tflat_reloc
 
reloc_record_tflat_reloc_cur
 
uint32_t flat_import_count
 
import_record_tflat_import_buf
 
import_record_tflat_import_cur
 
unsigned int strtaboff
 
unsigned int symtaboff
 

Makro-Dokumentation

#define ELFFLT_BAD_ELF_HEADER   1

Definiert in Zeile 10 der Datei elfflt.h.

#define ELFFLT_INPUT_ERROR   10

Definiert in Zeile 19 der Datei elfflt.h.

#define ELFFLT_NO_MODULEINFO   7

Definiert in Zeile 16 der Datei elfflt.h.

#define ELFFLT_NO_STRTAB   3

Definiert in Zeile 12 der Datei elfflt.h.

#define ELFFLT_NO_SYMTAB   2

Definiert in Zeile 11 der Datei elfflt.h.

#define ELFFLT_NO_TEXT   4

Definiert in Zeile 13 der Datei elfflt.h.

#define ELFFLT_OK   0

Definiert in Zeile 9 der Datei elfflt.h.

#define ELFFLT_OUTOF_RANGE   9

Definiert in Zeile 18 der Datei elfflt.h.

#define ELFFLT_OUTPUT_ERROR   11

Definiert in Zeile 20 der Datei elfflt.h.

#define ELFFLT_SEGMENT_NOT_FOUND   6

Definiert in Zeile 15 der Datei elfflt.h.

#define ELFFLT_SYMBOL_NOT_FOUND   5

Definiert in Zeile 14 der Datei elfflt.h.

#define ELFFLT_UNHANDLED_RELOC   8

Definiert in Zeile 17 der Datei elfflt.h.

#define ELFFLT_UNSAFE_SYMBOL   12

Definiert in Zeile 21 der Datei elfflt.h.

#define USE_INT32_FOR_PTRS

Definiert in Zeile 6 der Datei elfflt.h.

Dokumentation der benutzerdefinierten Typen

Definiert in Zeile 48 der Datei elfflt.h.

Dokumentation der Funktionen

int apply_import ( struct relevant_section base_sect,
struct elf32_rela rela,
int  importidx,
struct elf32_sym sym 
)

Definiert in Zeile 214 der Datei elf-arm.c.

219 {
220  unsigned int type = ELF32_R_TYPE(rela->r_info);
221  uint32_t locoffset = base_sect->flat_offset + rela->r_offset;
222  char* loc = (char*)(flat_buf + locoffset );
223 
224  char symbuf[30];
225  char* symname=""; // to printf: name of symbol
226  int ret = b_seek_read(strtaboff + sym->st_name, symbuf, sizeof(symbuf));
227  if (ret > 0) { symname=symbuf; symbuf[sizeof(symbuf)-1]=0; }
228 
229  switch(type) {
230  case R_ARM_ABS32:
231  {
232  flat_import_cur->offs = locoffset;
233  flat_import_cur->importidx = importidx;
234 
235  if ( FLAG_DUMP_RELOC )
236  printf( "R_ARM_ABS32: %p(%s+0x%x=%x): import_value=%d (sym:%s)+0x%x %d\n",
237  base_sect->base_addr+rela->r_offset, base_sect->name, rela->r_offset, locoffset,
238  importidx, symname, *(uint32_t*)loc, flat_import_count
239  );
240  flat_import_cur++;
242  }
243  break;
244 
245  default:
246  // Use only ABS32 because we can't be sure that module will be loaded not too far from core to PC24/THM_CALL
247  PRINTERR(stderr, "Only R_ARM_ABS32 relocations could be processed as imported symbol (%s). Please compile with -mlong-call or use manual import\n",symname);
248  return ELFFLT_UNHANDLED_RELOC;
249  }
250  return ELFFLT_OK;
251 }
int apply_realloc ( struct relevant_section base_sect,
struct elf32_rela rela,
struct relevant_section tgt_sect,
struct elf32_sym sym,
int  symidx 
)

Definiert in Zeile 18 der Datei elf-arm.c.

24 {
25  unsigned int type = ELF32_R_TYPE(rela->r_info);
26  uint32_t locoffset = base_sect->flat_offset + rela->r_offset;
27  char* loc = (char*)(flat_buf + locoffset );
28  uint32_t tgt_fulloffset = tgt_sect->flat_offset + sym->st_value; // full offset in flat target symbol
29 
30  int relindex = tgt_sect->number; // to printf: num of tgt segment
31  char symbuf[30];
32  char* symname=""; // to printf: name of symbol
33  char* reloc_name="";
34  int ret = b_seek_read(strtaboff + sym->st_name, symbuf, sizeof(symbuf));
35  if (ret > 0) { symname=symbuf; symbuf[sizeof(symbuf)-1]=0; }
36 
37 
39  uint32_t upper, lower, sign, j1, j2;
40  char* patch_name=""; // detected build-in function
41 
42 
43  if (rela->r_offset > base_sect->size - sizeof(uint32_t)) {
44  PRINTERR(stderr, "section %u(%s) reloc %u sym '%s': out of bounds relocation, offset %d size %u\n",
45  relindex, base_sect->name, i, symname,
46  rela->r_offset, base_sect->size);
47  return ELFFLT_OUTOF_RANGE;
48  }
49 
50  switch(type) {
51  case R_ARM_ABS32:
52  {
53  uint32_t addend = *(uint32_t*)loc;
54  *(uint32_t*)loc += tgt_fulloffset;
55 
56  if ( FLAG_DUMP_RELOC )
57  printf( "R_ARM_ABS32: %p(%s+0x%x=%x): ptr=%x [%s+0x%x+0x%x] sym:%s\n",
58  base_sect->base_addr+rela->r_offset, base_sect->name, rela->r_offset, locoffset,
59  tgt_sect->base_addr + addend + sym->st_value,
60  tgt_sect->name, sym->st_value, addend, symname
61  );
62 
63  if ( FLAG_VERBOSE)
64  printf("=== flt%p(reloc+%x: %x): [%x]=0x%x\n",flat_reloc_cur, (char*)flat_reloc_cur-(char*)flat_reloc, (char*)flat_reloc_cur-flat_buf, locoffset, *(uint32_t*)loc);
65  *flat_reloc_cur = locoffset;
68  }
69  break;
70 
71  case R_ARM_THM_CALL:
72  case R_ARM_THM_JUMP24: //needed on arm-none-eabi
73  upper = *(uint16_t *)loc;
74  lower = *(uint16_t *)(loc + 2);
75 
76  /*
77  * 25 bit signed address range (Thumb-2 BL and B.W
78  * instructions):
79  * S:I1:I2:imm10:imm11:0
80  * where:
81  * S = upper[10] = offset[24]
82  * I1 = ~(J1 ^ S) = offset[23]
83  * I2 = ~(J2 ^ S) = offset[22]
84  * imm10 = upper[9:0] = offset[21:12]
85  * imm11 = lower[10:0] = offset[11:1]
86  * J1 = lower[13]
87  * J2 = lower[11]
88  */
89  sign = (upper >> 10) & 1;
90  j1 = (lower >> 13) & 1;
91  j2 = (lower >> 11) & 1;
92  offset = (sign << 24) | ((~(j1 ^ sign) & 1) << 23) |
93  ((~(j2 ^ sign) & 1) << 22) |
94  ((upper & 0x03ff) << 12) |
95  ((lower & 0x07ff) << 1);
96  if (offset & 0x01000000)
97  offset -= 0x02000000;
98  offset += tgt_fulloffset - locoffset;
99 
100  /*
101  * For function symbols, only Thumb addresses are
102  * allowed (no interworking).
103  *
104  * For non-function symbols, the destination
105  * has no specific ARM/Thumb disposition, so
106  * the branch is resolved under the assumption
107  * that interworking is not required.
108  */
109  if ((ELF32_ST_TYPE(sym->st_info) == STT_FUNC &&
110  !(offset & 1)) ||
111  offset <= (int32_t)0xff000000 ||
112  offset >= (int32_t)0x01000000) {
113  PRINTERR(stderr, "section %u reloc %u sym '%s': relocation %u out of range (%#lx -> %#x)\n",
114  relindex, i, symname,
115  ELF32_R_TYPE(rela->r_info), locoffset,
116  sym->st_value);
117  return ELFFLT_OUTOF_RANGE;
118  }
119 
120  if ( FLAG_DUMP_RELOC )
121  printf( "R_ARM_THM_CALL: %p(%s+0x%x=%x): %04x %04x ptr=%x [loc%-d] sym:%s\n",
122  base_sect->base_addr+rela->r_offset, base_sect->name, rela->r_offset, locoffset,
123  upper, lower,
124  tgt_sect->base_addr+rela->r_offset+offset, offset,
125  symname);
126 
127  sign = (offset >> 24) & 1;
128  j1 = sign ^ (~(offset >> 23) & 1);
129  j2 = sign ^ (~(offset >> 22) & 1);
130  *(uint16_t *)loc = (uint16_t)((upper & 0xf800) | (sign << 10) |
131  ((offset >> 12) & 0x03ff));
132  *(uint16_t *)(loc + 2) = (uint16_t)((lower & 0xd000) |
133  (j1 << 13) | (j2 << 11) |
134  ((offset >> 1) & 0x07ff));
135  break;
136 
137  case R_ARM_PC24:
138  case R_ARM_JUMP24:
139  case R_ARM_CALL:
140  // R_ARM_PC24 is generated by Win arm-gcc. And in some buildin funcs change
141  // this pointer to different function. This part is emulate this behaviour.
142 
143  patch_name=0;
144  if ( strcmp(symname,"__div0") == 0 )
145  {
146  if ( locoffset == offs_divsi3_skip_div0_test )
147  patch_name=".divsi3_skip_div0_test";
148  else if ( locoffset == offs__aeabi_uidiv )
149  patch_name="__aeabi_uidiv";
150 
151  if ( !patch_name ) {
152  PRINTERR( stderr, "%s is requested from unusual place .text+0x%x\n", reloc_name,locoffset-text.flat_offset);
153  return ELFFLT_UNHANDLED_RELOC;
154  }
155 
156  // this is redirection to the new func
157  tgt_fulloffset = (text.flat_offset + offs_div0_from_arm);
158  // Falls through to next case - no break ***
159  }
160 
161  case R_ARM_PLT32:
162  // R_ARM_PLT32 is generated by linux arm-gcc and it doesn't change binary when instance into fixed adress
163 
164 // case R_ARM_CALL: // not needed
165 // case R_ARM_JUMP24: // not needed
166 
167  reloc_name = (type==R_ARM_PC24)?"R_ARM_PC24":"R_ARM_PLT32";
168 
169  offset = (*(uint32_t *)loc & 0x00ffffff) << 2;
170  if (offset & 0x02000000)
171  offset -= 0x04000000;
172 
173  offset += tgt_fulloffset - locoffset;
174 
175 /* it is possible to have offset close to upper border
176  if (offset & 3 ||
177  offset <= (int32_t)0xfe000000 ||
178  offset >= (int32_t)0x02000000) {
179  PRINTERR(stderr, "section %u reloc %u sym '%s': relocation %u out of range (%#lx -> %#x)\n",
180  relindex, i, symname,
181  ELF32_R_TYPE(rela->r_info), locoffset,
182  tgt_fulloffset);
183  return ELFFLT_OUTOF_RANGE;
184  }
185 */
186 
187  offset >>= 2;
188 
189  if ( FLAG_DUMP_RELOC )
190  {
191  printf( "%s: %p(%s+0x%x=%x): %08x ptr=%x [loc%-d] sym:%s\n", reloc_name,
192  base_sect->base_addr+rela->r_offset, base_sect->name, rela->r_offset, locoffset,
193  *(uint32_t *)loc,
194  base_sect->base_addr+rela->r_offset+offset*4, offset*4,
195  symname);
196  if ((type==R_ARM_PC24) && patch_name)
197  printf( "...Patched 0x%x(__div0)->0x%x (__div0_from_arm) for %s\n", sym->st_value, offs_div0_from_arm, patch_name);
198  }
199 
200  *(uint32_t *)loc &= 0xff000000;
201  *(uint32_t *)loc |= offset & 0x00ffffff;
202  break;
203  default:
204  PRINTERR(stderr, "Unknown relocation type %d\n",type);
205  return ELFFLT_UNHANDLED_RELOC;
206  }
207 
208  return ELFFLT_OK;
209 }
int elfloader_load ( char *  fltfile)

Load and relocate an ELF file.

Definiert in Zeile 378 der Datei elfflt.c.

379 {
380  struct elf32_ehdr ehdr;
381  struct elf32_shdr shdr;
382  struct elf32_shdr strtable;
383  unsigned int strs;
384  unsigned int shdrptr;
385  unsigned int nameptr;
386  char name[12];
387 
388  uint32_t i;
389  unsigned short shdrnum, shdrsize;
390 
391  int ret;
392 
393  /* Ensure that we have a correct and compatible ELF header. */
394  ret = b_seek_read( 0, (char *)&ehdr, sizeof(ehdr));
395  if (ret != sizeof(ehdr)) return ELFFLT_INPUT_ERROR;
396 
397  if(memcmp(ehdr.e_ident, elf_magic_header, sizeof(elf_magic_header)) != 0) {
398  PRINTERR(stderr, "ELF header problems\n");
399  return ELFFLT_BAD_ELF_HEADER;
400  }
401 
402  if ( FLAG_VERBOSE )
403  printf ("Grab section header\n");
404 
405  // Grab the section header.
406  shdrptr = ehdr.e_shoff;
407  ret = b_seek_read( shdrptr, (char *)&shdr, sizeof(shdr));
408  if (ret != sizeof(shdr)) return ELFFLT_INPUT_ERROR;
409 
410  shdrsize = ehdr.e_shentsize;
411  shdrnum = ehdr.e_shnum;
412 
413  if ( FLAG_VERBOSE )
414  printf ("Grab string table section\n");
415 
416  // Grab the string table section for the names of the sections.
417  ret = b_seek_read( ehdr.e_shoff + shdrsize * ehdr.e_shstrndx,
418  (char *)&strtable, sizeof(strtable));
419  if (ret != sizeof(strtable)) return ELFFLT_INPUT_ERROR;
420  strs = strtable.sh_offset;
421 
422  /* Parse segments headers to releavant_section entries.
423  .text = actual code from the ELF file
424  .data = initialized data
425  .rodata = contains read-only data
426  .bss = segment holds the size of the unitialized data segment
427  .rel.text, .rel.data = relocation information for the contents
428  of the ".text" and ".data" segments, respectively.
429  .symtab = symbol table for this file
430  .strtab = points to the actual string names used by the symbol table.
431  */
432 
433 
434  // Zero size is indicator of unitialized (not found) section
435  text.size = text.relasize = data.size = data.relasize =
436  rodata.size = rodata.relasize = symtabsize = strtabsize = 0;
437 
438  bss.number = data.number = rodata.number = text.number = -1;
439 
440  shdrptr = ehdr.e_shoff;
441  for(i = 0; i < shdrnum; ++i) {
442 
443  ret = b_seek_read( shdrptr, (char *)&shdr, sizeof(shdr));
444  DEBUGPRINTF("==shdrptr=0x%x, sizeof=%d; size=0x%x\n",shdrptr,sizeof(shdr),shdrsize );
445  if (ret != sizeof(shdr)) { PRINTERR(stderr, "input error at %s:%d :loaded%d",__FILE__,__LINE__,ret);return ELFFLT_INPUT_ERROR;}
446 
447  /* The name of the section is contained in the strings table. */
448  nameptr = strs + shdr.sh_name;
449  DEBUGPRINTF("==nameptr=%x(%x+%x), size=%d\n",nameptr,strs,shdr.sh_name,sizeof(name) );
450  ret = b_seek_read( nameptr, name, sizeof(name));
451  if (ret != sizeof(name)) {PRINTERR(stderr, "input error at %s:%d",__FILE__,__LINE__); return ELFFLT_INPUT_ERROR;}
452 
453  DEBUGPRINTF("==shdrptr=0x%x, sizeof=%d; size=0x%x\n",shdrptr,sizeof(shdr),shdrsize );
454  if ( FLAG_DUMP_SECTIONS )
455  printf ("Section #%d: %-15s [section header 0x%x, offset=0x%x, size %d, vma=0x%x]\n",i,name,shdrptr,
456  shdr.sh_offset,shdr.sh_size, shdr.sh_addr);
457 
458  if(strncmp(name, ".text", 5) == 0) {
459  text.number = i;
460  text.offset = shdr.sh_offset;
461  text.size = shdr.sh_size;
462  text.base_addr = shdr.sh_addr;
463  } else if(strncmp(name, ".rel.text", 9) == 0) {
464  text.relaoff = shdr.sh_offset;
465  text.relasize = shdr.sh_size;
466  } else if(strncmp(name, ".data", 5) == 0) {
467  data.number = i;
468  data.offset = shdr.sh_offset;
469  data.size = shdr.sh_size;
470  data.base_addr = shdr.sh_addr;
471  } else if(strncmp(name, ".rodata", 7) == 0) {
472  rodata.number = i;
473  rodata.offset = shdr.sh_offset;
474  rodata.size = shdr.sh_size;
475  rodata.base_addr = shdr.sh_addr;
476  } else if(strncmp(name, ".rel.rodata", 11) == 0) {
477  rodata.relaoff = shdr.sh_offset;
478  rodata.relasize = shdr.sh_size;
479  } else if(strncmp(name, ".rel.data", 9) == 0) {
480  data.relaoff = shdr.sh_offset;
481  data.relasize = shdr.sh_size;
482  } else if(strncmp(name, ".rela.", 6) == 0) {
483  PRINTERR(stderr,"RELA relocs are not supported.");
484  return ELFFLT_INPUT_ERROR;
485  } else if(strncmp(name, ".symtab", 7) == 0) {
486  symtaboff = shdr.sh_offset;
487  symtabsize = shdr.sh_size;
488  } else if(strncmp(name, ".strtab", 7) == 0) {
489  strtaboff = shdr.sh_offset;
490  strtabsize = shdr.sh_size;
491  } else if(strncmp(name, ".bss", 4) == 0) {
492  bss.size = shdr.sh_size;
493  bss.number = i;
494  bss.offset = 0;
495  }
496 
497  shdrptr += shdrsize;
498  }
499 
500  if(symtabsize == 0) {
501  PRINTERR(stderr,"No symbol table found.");
502  return ELFFLT_NO_SYMTAB;
503  }
504  if(strtabsize == 0) {
505  PRINTERR(stderr,"No strings table found.");
506  return ELFFLT_NO_STRTAB;
507  }
508  if(text.size == 0) {
509  PRINTERR(stderr, "No .text segment found.");
510  return ELFFLT_NO_TEXT;
511  }
512 
513  if ( (text.relasize + rodata.relasize+ data.relasize) <=0 ) {
514  PRINTERR(stderr,"Found no reloc sections. Please link with -r -d options.\n");
515  return ELFFLT_UNHANDLED_RELOC;
516  }
517 
518  if (bss.size) {
519  bss.address = (char *)malloc(bss.size);
520  if (!bss.address) return ELFFLT_OUTPUT_ERROR;
521  }
522  if (data.size) {
523  data.address = (char *)malloc(data.size);
524  if (!data.address) return ELFFLT_OUTPUT_ERROR;
525  }
526  if (text.size) {
527  text.address = (char *)malloc(text.size);
528  if (!text.address) return ELFFLT_OUTPUT_ERROR;
529  }
530  if (rodata.size) {
531  rodata.address = (char *)malloc(rodata.size);
532  if (!rodata.address) return ELFFLT_OUTPUT_ERROR;
533  }
534 
535  rodata.name=".rodata";
536  bss.name=".bss";
537  text.name=".text";
538  data.name=".data";
539 
540  b_seek_read(text.offset, text.address, text.size);
541  b_seek_read(data.offset, data.address, data.size);
542  b_seek_read(rodata.offset, rodata.address, rodata.size);
543 
544  if ( FLAG_DUMP_SOURCE ) {
545  dump_section( text.name, (unsigned char *)text.address, text.size );
546  dump_section( data.name, (unsigned char *)data.address, data.size );
547  dump_section( rodata.name, (unsigned char *)rodata.address, rodata.size );
548  }
549 
550  if ( FLAG_DUMP_SYMBOLS ) {
551  dump_symtable();
552  }
553 
555  printf("\n\n");
556 
557  if ( FLAG_VERBOSE )
558  printf ("Prepare flat\n");
559 
560  int div0hack_size = sizeof(div0_arm);
561 
562  int flatmainsize = sizeof(flat_hdr)+text.size+div0hack_size+data.size+rodata.size;
563  int flatrelocsize = text.relasize+rodata.relasize+data.relasize;
564 
565 
566  // Take to account aligning to int32 each section
567  flatmainsize += align4(text.size) + align4(data.size) + align4(rodata.size);
568 
569  flat_buf=malloc( flatmainsize+flatrelocsize );
570  if ( !flat_buf) { PRINTERR(stderr, "fail to malloc flat buf\n"); return ELFFLT_OUTPUT_ERROR;}
571  memset(flat_buf, 0, flatmainsize+flatrelocsize);
572 
573  //import is subset of full reloc list, so same count is enough
574  // but apply multiplier to take into account difference between sizeofs
575  flat_import_buf=malloc( flatrelocsize* sizeof(import_record_t)/sizeof(reloc_record_t) );
576  if ( !flat_import_buf) { PRINTERR(stderr, "fail to malloc flat import buf\n"); return ELFFLT_OUTPUT_ERROR;}
577  memset(flat_import_buf, 0, flatrelocsize);
578 
579  // Fill flat with sections aligned to int32
580 
581  flat = (flat_hdr*) flat_buf;
582 
583  if ( FLAG_VERBOSE )
584  printf(">>elf2flt: load segments\n");
585  int offset=sizeof(flat_hdr);
586  text.flat_offset = offset;
587  memcpy( flat_buf+offset, text.address, text.size );
588  DEBUGPRINTF("load .txt to %x (%x->%x)\n",offset,text.size,text.size+align4(text.size));
589  offset+=text.size+div0hack_size+align4(text.size);
590 
591  rodata.flat_offset = offset;
592  DEBUGPRINTF("load .rodata to %x (%x->%x)\n",offset,rodata.size,rodata.size+align4(rodata.size));
593  memcpy( flat_buf+offset, rodata.address, rodata.size );
594  offset+=rodata.size+align4(rodata.size);
595 
596  data.flat_offset = offset;
597  DEBUGPRINTF("load .data to %x (%x->%x)\n",offset,data.size,data.size+align4(data.size));
598  memcpy( flat_buf+offset, data.address, data.size );
599  offset+=data.size+align4(data.size);
600 
601  bss.flat_offset = offset;
602  DEBUGPRINTF(".bss to %x (%x)\n",offset,bss.size);
603  DEBUGPRINTF("result=%x\n", flatmainsize);
604 
605  // Initialize flat headers
607  flat->rev = FLAT_VERSION;
608  flat->entry = text.flat_offset;
609  flat->data_start = rodata.flat_offset;
610  //flat->bss_start = bss.flat_offset;
611  flat->bss_size = bss.size;
612  flat->reloc_start = flatmainsize;
613  flat_reloc_count = 0;
614 
615  flat->import_start = 0;
616  flat_import_count = 0;
617 
618  flat_reloc = (reloc_record_t*)(flat_buf+flatmainsize);
620 
622 
623  // _div0_arm hack
624  add_div0_arm();
625 
626  flag_unsafe_sym = 0;
627 
628  // Do relocations
629  ret = relocate_section( &text);
630  if(ret != ELFFLT_OK)
631  return ret;
632  ret = relocate_section( &rodata);
633  if(ret != ELFFLT_OK)
634  return ret;
635  ret = relocate_section( &data);
636  if(ret != ELFFLT_OK)
637  return ret;
638 
639  if ( flag_unsafe_sym )
640  return ELFFLT_UNSAFE_SYMBOL;
641 
643 
644  // Init offsets to the entry symbols
645 
646  if ( FLAG_VERBOSE )
647  printf(">>elf2flt: lookup entry symbols\n");
648 
649  flat->_module_info_offset = find_symbol_inflat("_module_info", &data );
650  if ( flat->_module_info_offset <=0 ) {
651  PRINTERR(stderr, "No or invalid section of _module_info. This symbol should be initialized as ModuleInfo structure.\n");
652  return ELFFLT_NO_MODULEINFO;
653  }
654 
656  if ( _module_info->magicnum != MODULEINFO_V1_MAGICNUM )
657  {
658  PRINTERR(stderr, "Wrong _module_info->magicnum value. Please check correct filling of this structure\n");
659  return ELFFLT_NO_MODULEINFO;
660  }
661  if ( _module_info->sizeof_struct != sizeof(ModuleInfo) )
662  {
663  PRINTERR(stderr, "Wrong _module_info->sizeof_struct value. Please check correct filling of this structure\n");
664  return ELFFLT_NO_MODULEINFO;
665  }
666 
667  // Group import relocations
668  // Input = array of offset/index pairs - one for each address to be relocated to a core CHDK symbol
669  // Output = list of entries of the form:
670  // Index, Offset1 | (N<<24), Offset2, ..., OffsetN
671  // where each offset is a reference to the same core CHDK symbol
672  uint32_t *new_import_buf = malloc(flat_import_count*3*sizeof(uint32_t));
673  uint32_t new_import_cnt = 0;
674  int process = 1;
675  while (process)
676  {
677  process = 0;
678  for (i=0; i<flat_import_count; i++)
679  {
680  if (flat_import_buf[i].offs != 0)
681  {
682  process = 1;
683  int cnt = 0;
685  new_import_buf[new_import_cnt++] = idx;
686  int pcnt = new_import_cnt;
687  uint32_t j;
688  for (j=0; j<flat_import_count; j++)
689  {
690  if (flat_import_buf[j].importidx == idx)
691  {
692  new_import_buf[new_import_cnt++] = flat_import_buf[j].offs;
693  flat_import_buf[j].offs = 0;
694  cnt++;
695  }
696  }
697  new_import_buf[pcnt] = (cnt << 24) | new_import_buf[pcnt];
698  }
699  }
700  }
701 
702  flat->import_size = new_import_cnt*sizeof(uint32_t);
703 
704  if ( FLAG_DUMP_FLT_HEADERS ) {
705  printf("\nFLT Headers:\n");
706  printf("->entry 0x%x (size %d)\n", flat->entry, flat->data_start - flat->entry );
707  printf("->data_start 0x%x (size %d)\n", flat->data_start, flat->reloc_start - flat->data_start );
708  printf("->bss_start 0x%x (size %d)\n", flat->reloc_start, flat->bss_size );
709  printf("->reloc_start 0x%x (size %d)\n", flat->reloc_start, flat_reloc_count*sizeof(reloc_record_t) );
710  printf("->import_start 0x%x (size %d %d)\n", flat->import_start, flat->import_size, flat_import_count*sizeof(import_record_t) );
711  printf("\n");
712 
713  printf("\nModule info:\n");
714  printf("->Module Name: %s\n", get_flat_string(_module_info->moduleName) );
715  printf("->Module Ver: %d.%d\n", _module_info->module_version.major, _module_info->module_version.minor );
716 
717  char* branches_str[] = {"any branch","CHDK", "CHDK_DE", "CHDK_SDM", "PRIVATEBUILD"};
718  int branch = (_module_info->chdk_required_branch>REQUIRE_CHDK_PRIVATEBUILD) ?
720  printf("->Require: %s-build%d. ", branches_str[branch], _module_info->chdk_required_ver );
721  if ( _module_info->chdk_required_platfid == 0 )
722  printf("Any platform.\n");
723  else
724  printf(" Platform #%d only.\n", _module_info->chdk_required_platfid );
725  //printf("->Description: %s\n", get_flat_string(_module_info->description) );
726  print_offs("->lib = ", _module_info->lib,"\n");
727  //print_offs("->_module_loader() = ", _module_info->loader,"\n");
728  //print_offs("->_module_unloader() = ", _module_info->unloader,"\n");
729  //print_offs("->_module_can_unload()= ", _module_info->can_unload,"\n");
730  //print_offs("->_module_exit_alt() = ", _module_info->exit_alt,"\n");
731  }
732 
733  if ( FLAG_DUMP_FLAT ) {
734  dump_section( "FLT_header", (unsigned char*)flat_buf, sizeof(flat_hdr) );
735  dump_section( "FLT_text", (unsigned char*)flat_buf+flat->entry, flat->data_start-flat->entry );
736  dump_section( "FLT_data", (unsigned char*)flat_buf+flat->data_start, flat->reloc_start-flat->data_start);
737  //dump_section( "FLT_bss", (unsigned char*)flat_buf+flat->reloc_start, flat->bss_size );
738 
739  printf("\nDump relocations 0x%x (size=%d):\n",flat->reloc_start,flat_reloc_count*sizeof(reloc_record_t));
740  for( i = 0; i< flat_reloc_count; i++)
741  {
742  print_offs("Offs: ",*(uint32_t*)(flat_buf+flat->reloc_start+i*sizeof(reloc_record_t)), "\n");
743  }
744 
745  printf("\nDump imports 0x%x (size=%d):\n",flat->import_start,new_import_cnt*sizeof(uint32_t));
746  for (i = 0; i< new_import_cnt;)
747  {
748  uint32_t idx = new_import_buf[i++];
749  int cnt = new_import_buf[i] >> 24;
750  int j;
751  for (j=0; j<cnt; j++)
752  {
753  uint32_t offs = new_import_buf[i++] & 0x00FFFFFF;
754  print_offs((j==0)?"Offs: ":" ",offs,"");
755  int addend = *(uint32_t*)(flat_buf+offs);
756  printf(" = sym_%08x[%s]+0x%x\n",idx,get_import_symbol(idx),addend);
757  }
758  }
759  }
760 
762 
763  printf("\n\nOutput file %s (size=%d bytes)\n",fltfile,filesize);
764 
765  int output_fd = open(fltfile,O_WRONLY|O_CREAT|O_TRUNC|O_BINARY,0777);
766  i = write(output_fd, flat_buf, flat->import_start);
767  i = write(output_fd, new_import_buf, new_import_cnt*sizeof(uint32_t));
768  close(output_fd);
769  free(new_import_buf);
770 
771  return ELFFLT_OK;
772 }

Variablen-Dokumentation

flat_hdr* flat

Definiert in Zeile 42 der Datei elfflt.c.

char* flat_buf

Definiert in Zeile 41 der Datei elfflt.c.

import_record_t* flat_import_buf

Definiert in Zeile 49 der Datei elfflt.c.

uint32_t flat_import_count

Definiert in Zeile 48 der Datei elfflt.c.

import_record_t* flat_import_cur

Definiert in Zeile 50 der Datei elfflt.c.

reloc_record_t* flat_reloc

Definiert in Zeile 45 der Datei elfflt.c.

uint32_t flat_reloc_count

Definiert in Zeile 44 der Datei elfflt.c.

reloc_record_t* flat_reloc_cur

Definiert in Zeile 46 der Datei elfflt.c.

unsigned int strtaboff

Definiert in Zeile 38 der Datei elfflt.c.

unsigned int symtaboff

Definiert in Zeile 37 der Datei elfflt.c.

struct relevant_section bss data rodata text

Definiert in Zeile 29 der Datei gui_mbox.c.