root/tools/elf2flt/myio.c

/* [<][>][^][v][top][bottom][index][help] */

DEFINITIONS

This source file includes following definitions.
  1. b_file_preload
  2. b_read
  3. b_seek
  4. b_seek_read
  5. b_get_buf
  6. load_import
  7. find_import_symbol
  8. get_import_symbol
  9. load_stoplist
  10. stoplist_check
  11. raise_error

   1 /*
   2  * Service library of elf2flt 
   3  *
   4  *      (c)2011 Sergey Taranenko aka tsvstar
   5  *
   6  */
   7 #include <stdio.h>
   8 #include <stdlib.h>
   9 #include <unistd.h>
  10 #include <fcntl.h>
  11 #include <string.h>
  12 
  13 #include "myio.h"
  14 
  15 static char* filebuf=0;
  16 static int   filesize=0; 
  17 static int   filecuridx=0;
  18 
  19 /*---------------------------------------------------------------------------*/
  20 int b_file_preload(char* filename)
  21 {
  22     int fd;
  23 
  24     filesize=0;
  25     filecuridx=0;
  26     
  27     fd=open(filename, O_RDONLY|O_BINARY);
  28     if ( fd <=0 ) return 0;
  29     filesize = lseek(fd,0,SEEK_END);
  30     if ( FLAG_VERBOSE )
  31         printf("File size=%d\n",filesize);
  32     filebuf=malloc(filesize);    
  33     if (!filebuf) return 0;
  34 
  35     int now=0, loaded =0; 
  36     if (lseek(fd, 0, SEEK_SET) != 0) return 0;
  37     do
  38     {
  39         now = read(fd, filebuf+loaded, filesize-loaded);
  40         loaded+=now;
  41     } while (loaded<filesize && now);
  42          
  43     if ( loaded == filesize )
  44         return loaded;
  45     return -loaded;
  46 }
  47 
  48 /*---------------------------------------------------------------------------*/
  49 int b_read (void* buf, int count)
  50 {
  51     if ( (filecuridx+count)> filesize)
  52         count = filesize - filecuridx;
  53     memcpy(buf, filebuf+filecuridx, count);
  54     filecuridx+=count;
  55     return count;
  56 }
  57 
  58 /*---------------------------------------------------------------------------*/
  59 int b_seek(long offset)
  60 {
  61     filecuridx = offset;
  62     if ( offset < 0 )
  63      { filecuridx = 0;}
  64     else if ( offset > filesize)
  65      { filecuridx = filesize;}
  66     return filecuridx;
  67 }
  68 
  69 /*---------------------------------------------------------------------------*/
  70 int b_seek_read(long offset, char *buf, int len)
  71 {
  72   if (b_seek(offset) != offset) return -1;
  73   return b_read(buf, len);
  74 }
  75 
  76 char* b_get_buf()
  77 {
  78   return filebuf;
  79 }
  80 
  81 
  82 #define MAX_SYM 2048
  83 
  84 static char* import_buf=0;
  85 static char* import_syms[MAX_SYM];          // Symbol names in input file
  86 static unsigned int import_hash[MAX_SYM];   // Symbol hash values in input file
  87 static int import_counts=0;                 // # of symbols found
  88 static int importfilesize=0;
  89 
  90 int load_import(char* importfile)
  91 {
  92         int fd;
  93         static char buf[10];
  94 
  95         import_counts=0;
  96         import_buf=buf;
  97         if ( !importfile )
  98           return 0;
  99 
 100         fd=open(importfile, O_RDONLY|O_BINARY, 0777);
 101 
 102     if ( fd <=0 ) {
 103                 PRINTERR(stderr,"No import file '%s' found\n",importfile);
 104                 return 0;
 105         }
 106     importfilesize = lseek(fd,0,SEEK_END);
 107         if ( FLAG_VERBOSE )
 108         printf("Import file '%s' size=%d\n",importfile, importfilesize);
 109 
 110     import_buf=malloc(importfilesize+1);    
 111     if (!import_buf) return 0;
 112 
 113     int now=0, loaded =0; 
 114         if (lseek(fd, 0, SEEK_SET) != 0) return 0;
 115         do
 116         { 
 117       now = read(fd, import_buf+loaded, importfilesize-loaded);
 118       loaded+=now;
 119     } while (loaded<importfilesize && now);
 120 
 121         import_buf[loaded]=0;
 122         close(fd);
 123        
 124     if ( loaded != importfilesize )
 125       return -loaded;
 126 
 127     // Input file contains symbol hash value (in hex), a space and then the symbol name
 128         // Parse the input file and build the symbol / hash table
 129         char* p=import_buf;
 130     char* s=p;
 131         for (;*p;p++) {
 132                 if (*p==13) {
 133                         PRINTERR(stderr,"Import file should have unix EOL format\n");
 134                         import_counts=0;
 135                         break;
 136                 }
 137 
 138                 if (*p==10) {
 139                         *p=0;
 140             unsigned int h;
 141             sscanf(s,"%x ",&h);
 142             import_syms[import_counts] = s+9;
 143             import_hash[import_counts] = h;
 144                         import_counts++;
 145             s = p + 1;
 146                         continue;
 147                 }
 148                 
 149                 //if (!((*p>='A' && *p<='Z') || 
 150                 //        (*p>='a' && *p<='z') || 
 151                 //        (*p>='0' && *p<='9') || 
 152                 //        *p=='_' ))
 153                 //{
 154                 //      PRINTERR(stderr,"Found '%c' sym. Import file should contain only symbol names. No spaces or other sym allowed\n",*p);
 155                 //      break;
 156                 //}
 157         }
 158         if ( FLAG_VERBOSE )
 159                 printf("Import file has %d entries\n",import_counts);
 160         return loaded;
 161 }
 162 
 163 // Return: 0=not_found, otherwise return has value of symbol name
 164 int find_import_symbol(char* sym)
 165 {
 166   static const char prefix[] = "__imported_";
 167   static int prefixsize = sizeof(prefix);
 168 
 169         if (import_counts<=0)
 170                 return 0;
 171 
 172         if (strlen(sym)==0)
 173                 return 0;
 174 
 175         if ( !strncmp( sym, prefix, prefixsize ) )
 176          { sym+=prefixsize; }
 177 
 178         int idx=0;
 179 
 180         for(;idx<import_counts;idx++) {
 181           if (strcmp(sym,import_syms[idx]) == 0)
 182                 return (import_hash[idx]);
 183         }
 184         return 0;
 185 }
 186 
 187 // Return symbol name by its hash value
 188 char* get_import_symbol( unsigned symidx )
 189 {
 190         unsigned idx=0;
 191 
 192         for(;idx<symidx;idx++) {
 193       if (import_hash[idx] == symidx)
 194           return import_syms[idx];
 195         }
 196 
 197         return "";
 198 }
 199 
 200 
 201 //==========================================
 202 
 203 struct StopListRecord {
 204         char* symbol;
 205         char* warning;
 206         void* next;     
 207 };
 208 
 209 
 210 char *stoplist_buf=0;
 211 struct StopListRecord* stoplisthead=0;
 212 
 213 
 214 int load_stoplist(char* stopfile)
 215 {
 216         if ( !stopfile )
 217           return 0;
 218 
 219         int fd=open(stopfile, O_RDONLY|O_BINARY, 0777);
 220 
 221     if ( fd <=0 ) {
 222                 PRINTERR(stderr,"No stoplist file '%s' found\n",stopfile);
 223                 return 0;
 224         }
 225     int stoplistfilesize = lseek(fd,0,SEEK_END);
 226         if ( FLAG_VERBOSE )
 227         printf("Stoplist file '%s' size=%d\n",stopfile, stoplistfilesize);
 228 
 229     stoplist_buf=malloc(stoplistfilesize+1);    
 230     if (!stoplist_buf) return 0;
 231 
 232     int now=0, loaded =0; 
 233         if (lseek(fd, 0, SEEK_SET) != 0) return 0;
 234         do
 235         { 
 236       now = read(fd, stoplist_buf+loaded, stoplistfilesize-loaded);
 237       loaded+=now;
 238     } while (loaded<stoplistfilesize && now);
 239 
 240         stoplist_buf[loaded]=0;
 241         close(fd);
 242        
 243     if ( loaded != stoplistfilesize )
 244       return -loaded;
 245 
 246     // Parse
 247     struct StopListRecord record;
 248         char* sym=0, *finsym=0;
 249     char* cur=stoplist_buf;
 250 
 251     for ( ; cur<(stoplist_buf+stoplistfilesize); ) {
 252                 for(;*cur==' '; cur++); // skip spaces
 253 
 254                 sym=cur;
 255                 for(;*cur && *cur!=9 && *cur!=' ' && *cur!=0x0a; cur++);
 256                 if ( cur==sym ) {
 257                         for(;*cur && *cur!=10; cur++);
 258                         if ( *cur==10) {cur++;}
 259                         continue;
 260                 }
 261 
 262                 record.symbol = sym;    
 263                 record.warning = "Error: unsafe symbol used. Please check stoplist";
 264                 finsym=cur;
 265                 for(;*cur && *cur!=9 && *cur!=0x0a; cur++);     // find \t
 266 
 267                 if ( *cur==0 ) break;
 268                 if ( *cur==9 ) {
 269                         cur++;
 270                         record.warning=cur;
 271                 }
 272                 
 273                 for(;*cur && *cur!=10; cur++);          // find eol
 274                 if ( *cur==0x0a && cur>stoplist_buf && *(cur-1)==0x0d)
 275                         *(cur-1)=0;
 276 
 277                 if (cur==record.warning)
 278                         record.warning = "Error: unsafe symbol used. Please check stoplist";
 279 
 280                 record.next=stoplisthead;
 281                 stoplisthead = malloc (sizeof(struct StopListRecord));
 282                 memcpy( stoplisthead, &record, sizeof(struct StopListRecord));
 283 
 284                 if ( *cur!=0 ) { *cur=0; cur++;}
 285                 *finsym = 0;
 286 
 287                 if ( FLAG_VERBOSE )
 288                         printf("Stop record: %s => %s\n",record.symbol, record.warning);
 289         }
 290 
 291         return loaded;
 292 }
 293 
 294 //return: 1 - found in stoplist, 0 - not found
 295 int stoplist_check(char *sym)
 296 {
 297         struct StopListRecord *cur;
 298   
 299         for ( cur = stoplisthead; cur; cur = cur->next ) {
 300                 if ( !cur->symbol )
 301                         continue;
 302                 if ( !strcmp( sym, cur->symbol) ) {
 303                         PRINTERR(stderr,"%s\n",cur->warning);
 304                         cur->symbol = 0;  // mark that this symbol is already warned
 305                         return 1;
 306                 }
 307         }
 308         return 0;
 309 }
 310 
 311 
 312 //==========================================
 313 void raise_error()
 314 {
 315   static int flag =0;
 316 
 317   if (!flag)
 318         fprintf(stderr, "In file %s:\n", filename_elf);
 319   flag=1;
 320 }

/* [<][>][^][v][top][bottom][index][help] */