root/tools/makeexport.c

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

DEFINITIONS

This source file includes following definitions.
  1. add_hash
  2. cmp_hash
  3. sort_hash
  4. hash
  5. process_file
  6. main
  7. load_from_file
  8. cut_export_token
  9. find_last_token

   1 #include <stdio.h>
   2 #include <stdlib.h>
   3 #include <unistd.h>
   4 #include <math.h>
   5 
   6 #include <string.h>
   7 #include <fcntl.h>
   8 #include <sys/stat.h>
   9 
  10 char* load_from_file(const char* filename);
  11 void cut_export_token( char* sym );
  12 char* find_last_token(char* sym );
  13 
  14 #define MAX_SYM 2048
  15 
  16 typedef struct
  17 {
  18     unsigned int hash;
  19     char symbol[257];
  20     int count;
  21 } hash_val;
  22 
  23 hash_val hash_vals[MAX_SYM];
  24 int hash_idx = 0;
  25 
  26 void add_hash(unsigned int val, char *sym)
  27 {
  28     int i;
  29     for (i=0; i<hash_idx; i++)
  30     {
  31         if (hash_vals[i].hash == val)
  32         {
  33             hash_vals[i].count++;
  34             fprintf(stderr,"Hash collision for 0x%08x (%s and %s)\n",val, sym, hash_vals[i].symbol);
  35             exit(-3);
  36         }
  37     }
  38 
  39     hash_vals[hash_idx].hash = val;
  40     hash_vals[hash_idx].count = 1;
  41     strcpy(hash_vals[hash_idx].symbol,sym);
  42     hash_idx++;
  43 }
  44 
  45 int cmp_hash(const void *a, const void *b)
  46 {
  47     hash_val *ha = (hash_val*)a;
  48     hash_val *hb = (hash_val*)b;
  49     if (ha->hash < hb->hash) return -1;
  50     else if (ha->hash > hb->hash) return 1;
  51     else return 0;
  52 }
  53 
  54 void sort_hash()
  55 {
  56     qsort(hash_vals,hash_idx,sizeof(hash_val),cmp_hash);
  57 }
  58 
  59 unsigned int hash(unsigned char *str)
  60 {
  61     unsigned int hash = 5381;
  62     int c;
  63 
  64     // djb2 hash algorithm (Dan Bernstein - http://cr.yp.to/djb.html)
  65     while ((c = *str++) != 0)
  66         hash = ((hash << 5) + hash) ^ c; /* hash * 33 xor c */
  67 
  68     return hash;
  69 }
  70 
  71 int process_file(const char *name, FILE *out_txt)
  72 {
  73     char *cursym;
  74 
  75     char *cur = load_from_file(name);
  76 
  77     if (cur == 0)
  78     {
  79         printf("makeexport: file not found '%s'\n", name);
  80         return 0;
  81     }
  82 
  83     // Main cycle
  84     for(;*cur; )
  85     {
  86         for(; *cur==9 || *cur==' '; cur++)
  87             ;
  88         if (*cur=='(') {
  89             for(cur++; *cur && *cur!=')'; cur++);
  90             for(; *cur==9 || *cur==' ' || *cur==')'; cur++);
  91         }
  92 
  93         int is_address = 0;
  94         if (*cur=='&')
  95         {
  96             is_address = 1;
  97             for(cur++; *cur==9 || *cur==' '; cur++);
  98         }
  99 
 100         cursym=cur;
 101         for(; (*cur>='A' && *cur<='Z') ||
 102               (*cur>='a' && *cur<='z') ||
 103               (*cur>='0' && *cur<='9') ||
 104               *cur=='_';
 105             cur++);
 106 
 107         if (cursym!=cur) {
 108             char symbol[256], full_symbol[257];
 109             int size=cur-cursym;
 110 
 111             if ( size>255) {size=255;}
 112             memcpy(symbol,cursym,size);
 113             symbol[size]=0;
 114             full_symbol[0] = 0;
 115             if (is_address) strcpy(full_symbol,"&");
 116             strcat(full_symbol,symbol);
 117             cut_export_token(symbol);
 118 
 119             unsigned int hash_val = hash((unsigned char*)symbol);
 120             add_hash(hash_val,full_symbol);
 121             fprintf(out_txt,"%08x %s\n",hash_val,symbol);
 122             for(; size>=0; size--)
 123             {
 124                 if ( symbol[size]>='a' && symbol[size]<='z')
 125                     symbol[size]-=0x20;
 126             }
 127         }
 128 
 129         for(; *cur && *cur!=10; cur++);
 130         for(; *cur==10; cur++);
 131     }
 132 
 133     return 1;
 134 }
 135 
 136 ////////////////////////////////////////////////////////////////////////////////////////////////
 137 //
 138 // @tsv - Utility to convert export list to different required format
 139 //
 140 // USAGE:   makeexport module_exportlist.h exportlist.inc module_hashlist.c module_exportlist.c module_exportlist$(ABI).inc
 141 //
 142 ///////////////////////////////////////////////////////////////////////////////////////////////
 143 int main( int argc, char **argv )
 144 {
 145         if ( argc < 5 )
 146         {
 147                 printf("#error Not enough arguments for export list maker.\n");
 148                 exit(-1);
 149         }
 150 
 151         FILE* out_h = fopen(argv[1],"wb");
 152         FILE* out_txt = fopen(argv[2],"wb");
 153     FILE* out_hash = fopen(argv[3],"wb");
 154 
 155         if (!out_h)
 156         {
 157                 printf("#error Error creation exportlist.h.\n");
 158                 exit(-1);
 159         }
 160         if (!out_txt)
 161         {
 162                 printf("#error Error creation exportlist.txt.\n");
 163                 exit(-1);
 164         }
 165 
 166         fprintf(out_h,"//Auto generated file. Do not edit the contents of this file.\n");
 167         fprintf(out_h,"//Update the modules/module_exportlist.c file\n\n");
 168         fprintf(out_h,"#ifndef MODULE_EXPORTLIST_H\n");
 169         fprintf(out_h,"#define MODULE_EXPORTLIST_H\n\n");
 170 
 171         // Separate CHDK build num
 172         char* build = BUILD_NUMBER;
 173         char* e;
 174     int build_num=0;
 175         int mult=10000;
 176     for ( ; *build; build++) {
 177                 if ( *build<'0' || *build>'9') continue;
 178         build_num += mult*strtol(build, &e, 0/*autodetect base oct-dec-hex*/);
 179                 if ( mult==1 ) break;
 180                 build=e;
 181                 mult/=100;
 182         }
 183         if ( *build )
 184                 fprintf(out_h,"#define CHDK_BUILD_NUM %d\n\n",build_num);
 185 
 186         if (!process_file(argv[4], out_txt)) exit(-1);  // CHDK exports
 187     if (!process_file(argv[5], out_txt)) exit(-1);  // GCC library exports
 188 
 189     int n;
 190     sort_hash();
 191     fprintf(out_hash,"// This is an automatically generated file. DO NOT EDIT!\n");
 192     fprintf(out_hash, "\n#include \"module_hash.h\"\n\n");
 193     fprintf(out_hash, "// Address references so that symbol table will compile and link.\n// Don't need correct signatures here, just the name for linking.\n");
 194     for (n=0; n<hash_idx; n++)
 195     {
 196         if (hash_vals[n].symbol[0] == '&')  // variable
 197         {
 198             fprintf(out_hash,"extern int %s;\n",hash_vals[n].symbol+1);
 199         }
 200         else                                // function
 201         {
 202             fprintf(out_hash,"extern void %s(void);\n",hash_vals[n].symbol);
 203         }
 204     }
 205     fprintf(out_hash, "\n// Symbol hash table for resolving exported symbol references\nsym_hash symbol_hash_table[] =\n{\n");
 206     for (n=0; n<hash_idx; n++)
 207     {
 208         fprintf(out_hash,"{ 0x%08x, %s },\n",hash_vals[n].hash,hash_vals[n].symbol);
 209     }
 210     fprintf(out_hash, "};\n");
 211 
 212         if (hash_idx>=1)
 213                 fprintf(out_h,"#define EXPORTLIST_COUNT %d\n\n",hash_idx);
 214         else {
 215                 fprintf(out_h,"#error Malformed export list. Only %d valid records\n\n",hash_idx);
 216                 exit(-2);
 217         }
 218         fprintf(out_h,"#endif\n");
 219 
 220         fclose(out_h);
 221         fclose(out_txt);
 222     fclose(out_hash);
 223 
 224     return 0;
 225 }
 226 
 227 //-------------------------------------------------------------------
 228 
 229 char* load_from_file(const char *filename) 
 230 {
 231     int f, size;
 232     static struct stat st;
 233     char *buf = 0;
 234 
 235     f = open(filename, O_RDONLY, 0777);
 236     if (f>=0) {
 237         size = (stat((char*)filename, &st)==0)?st.st_size:0;
 238         if (size) {
 239             buf = (char*)malloc(size+1);
 240             if (buf) {
 241                 size = read(f, buf, size);
 242                 buf[size]=0;
 243             }
 244         }
 245         close(f);
 246     }
 247     return buf;
 248 }
 249 
 250 void cut_export_token( char* sym )
 251 {
 252         const char* token="_EXPORTEDSYM_";
 253         int sizetoken = strlen(token);
 254         char* src, *fin;
 255 
 256         fin=sym+strlen(sym)-sizetoken;
 257         for(;sym<=fin;sym++) {
 258                 if (!memcmp(sym,token,sizetoken)) {
 259                         for (src=sym+strlen(token); *src; src++,sym++)
 260                                 *sym=*src;
 261                         *sym=0;
 262                         return;
 263                 }
 264         }
 265 }
 266 
 267 char* find_last_token(char* sym )
 268 {
 269         char* token=sym;
 270 
 271         for (;*sym;sym++)
 272         {
 273                 if ( *sym==' ' && sym[1]>' ')
 274                  token=sym+1;
 275         }
 276         return token;
 277 }

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