toolsandutils/e32tools/elftools/genstubs/genstubs.cpp
changeset 0 83f4b4db085c
child 1 d4b442d23379
equal deleted inserted replaced
-1:000000000000 0:83f4b4db085c
       
     1 // Copyright (c) 2007-2009 Nokia Corporation and/or its subsidiary(-ies).
       
     2 // All rights reserved.
       
     3 // This component and the accompanying materials are made available
       
     4 // under the terms of "Eclipse Public License v1.0"
       
     5 // which accompanies this distribution, and is available
       
     6 // at the URL "http://www.eclipse.org/legal/epl-v10.html".
       
     7 //
       
     8 // Initial Contributors:
       
     9 // Nokia Corporation - initial contribution.
       
    10 //
       
    11 // Contributors:
       
    12 //
       
    13 // Description:
       
    14 //
       
    15 
       
    16 #include <stdio.h>
       
    17 #include <string.h>
       
    18 #include <stdlib.h>
       
    19 
       
    20 #include <tools/elfdefs.h>
       
    21 
       
    22 #define MAXPATHNAMELENGTH 2000
       
    23 #define MAXSYMBOLLENGTH 2000
       
    24 
       
    25 #define writef(f, d, n, s) if ( 1 != fwrite(d, n, 1, f)) { croak(s); }
       
    26 
       
    27 void croak(char * s)
       
    28 {
       
    29   printf("GENSTUB ERROR: %s\n", s);
       
    30   exit(EXIT_FAILURE);
       
    31 }
       
    32 
       
    33 long codeSectionData [] = 
       
    34 {
       
    35   0xe51ff004,    // LDR      pc,0x4
       
    36   0x00000000     // the pointer to the imported code
       
    37 };
       
    38 
       
    39 
       
    40 #define COMMENTSTRING "\tAndy's magic stub generator vsn 0.2\n"
       
    41 char commentSectionData[] = // "\tAndy's magic stub generator vsn 0.2\n"
       
    42 { 
       
    43   '\t','A','n','d','y','\'','s',' ','m','a','g','i','c',' ',
       
    44   's','t','u','b',' ','g','e','n','e','r','a','t','o','r',' ',
       
    45   'v','s','n',' ','0','.','2','\n'
       
    46 };
       
    47 
       
    48 char directiveSectionData[] = // "#<SYMEDIT>\nIMPORT "
       
    49 {
       
    50   '#','<','S','Y','M','E','D','I','T','>','\n',
       
    51   'I','M','P','O','R','T',' '
       
    52 };
       
    53 
       
    54 char strtabSectionData [] =
       
    55 {
       
    56   0,'$','a',0,                                                          // $a
       
    57   '$','d',0,                                                            // $d
       
    58   'S','t','u','b','C','o','d','e',0,                                    // StubCode
       
    59   '.','d','i','r','e','c','t','i','v','e',0,                            // .directive
       
    60   't','h','e','I','m','p','o','r','t','e','d','S','y','m','b','o','l',0 // theImportSymbol
       
    61 };
       
    62 
       
    63 Elf32_Sym symtabSectionData[] =
       
    64 {
       
    65   // undefined symbol
       
    66   {
       
    67     0, // st_name
       
    68     0, // st_value
       
    69     0, // st_size
       
    70     0, // st_info
       
    71     0, // st_other
       
    72     0  // stshndx
       
    73   },
       
    74   // $a
       
    75   {
       
    76     1, // st_name
       
    77     0, // st_value
       
    78     0, // st_size
       
    79     ELF32_ST_INFO(STB_LOCAL,STT_FUNC), // st_info
       
    80     0, // st_other
       
    81     1  // stshndx
       
    82   },
       
    83   // $d
       
    84   {
       
    85     4, // st_name
       
    86     4, // st_value
       
    87     0, // st_size
       
    88     ELF32_ST_INFO(STB_LOCAL,STT_OBJECT), // st_info
       
    89     0, // st_other
       
    90     1  // stshndx
       
    91   },
       
    92   // StubCode
       
    93   {
       
    94     7, // st_name
       
    95     0, // st_value
       
    96     sizeof(codeSectionData), // st_size
       
    97     ELF32_ST_INFO(STB_LOCAL,STT_SECTION), // st_info
       
    98     0, // st_other
       
    99     1  // stshndx
       
   100   },
       
   101   // .directive
       
   102 #define DIRECTIVESYMNDX 4
       
   103   {
       
   104     16,// st_name
       
   105     0, // st_value
       
   106     0, // st_size - to be filled on
       
   107     ELF32_ST_INFO(STB_LOCAL,STT_SECTION), // st_info
       
   108     0, // st_other
       
   109     3  // stshndx
       
   110   },
       
   111   // theImportedSymbol
       
   112   {
       
   113     27, // st_name
       
   114     4, // st_value
       
   115     0, // st_size
       
   116     ELF32_ST_INFO(STB_LOCAL,STT_FUNC), // st_info
       
   117     0, // st_other
       
   118     1  // stshndx
       
   119   },
       
   120 
       
   121   // the exported symbol
       
   122 #define EXPORTEDSYMBOLSTRNDX 45
       
   123   {
       
   124     EXPORTEDSYMBOLSTRNDX, // st_name
       
   125     0, // st_value
       
   126     0, // st_size
       
   127     ELF32_ST_INFO(STB_GLOBAL,STT_FUNC), // st_info
       
   128     0, // st_other
       
   129     1  // stshndx
       
   130   },
       
   131   // the imported symbol
       
   132 #define IMPORTEDSYMBOLSYMNDX 7
       
   133   {
       
   134     0, // st_name - needs to be filled in = EXPORTEDSYMBOLSTRNDX + strlen(exportedSymbol) + 1
       
   135     0, // st_value
       
   136     0, // st_size
       
   137     ELF32_ST_INFO(STB_GLOBAL,STT_NOTYPE), // st_info
       
   138     0, // st_other
       
   139     SHN_UNDEF  // stshndx
       
   140   }
       
   141 };
       
   142 
       
   143 Elf32_Rel relocSectionData [] =
       
   144 {
       
   145   {
       
   146     0x00000004, // r_offset
       
   147     ELF32_R_INFO(IMPORTEDSYMBOLSYMNDX, R_ARM_ABS32)
       
   148   }
       
   149 };
       
   150 
       
   151 char shstrtabSectionData []= 
       
   152 {
       
   153   0,'S','t','u','b','C','o','d','e',0,                 // StubCode
       
   154   '.','r','e','l','S','t','u','b','C','o','d','e',0,   // .relStubCode
       
   155   '.','d','i','r','e','c','t','i','v','e',0,           // .directive
       
   156   '.','s','y','m','t','a','b',0,                       // .symtab
       
   157   '.','s','t','r','t','a','b',0,                       // .strtab
       
   158   '.','c','o','m','m','e','n','t',0,                  // .comment
       
   159   '.','s','h','s','t','r','t','a','b',0                // .shstrtab
       
   160 };
       
   161 
       
   162 Elf32_Shdr SectionHeaderTable[] = 
       
   163 {
       
   164   // dummy section
       
   165   {
       
   166     0,             // sh_name - to be filled
       
   167     SHT_NULL,      // sh_type
       
   168     0,             // sh_flags
       
   169     0,             // sh_addr
       
   170     0,             // sh_offset - file offset of this section - to be filled in
       
   171     0,             // sh_size - to be filled in
       
   172     0,             // sh_link
       
   173     0,             // sh_info
       
   174     0,             // sh_addralign
       
   175     0              // sh_entsize
       
   176   },
       
   177 
       
   178   // StubCode section
       
   179 #define CODEINDEX 1
       
   180 #define CODEOFFSET (sizeof(Elf32_Ehdr) + (8 * sizeof(Elf32_Shdr)))
       
   181 #define CODESIZE (sizeof(codeSectionData))
       
   182   {
       
   183     1,             // sh_name 
       
   184     SHT_PROGBITS,  // sh_type
       
   185     SHF_ALLOC + SHF_EXECINSTR, // sh_flags
       
   186     0,             // sh_addr
       
   187     CODEOFFSET,    // sh_offset 
       
   188     CODESIZE,      // sh_size
       
   189     SHN_UNDEF,     // sh_link
       
   190     0,             // sh_info
       
   191     4,             // sh_addralign
       
   192     0              // sh_entsize
       
   193   },
       
   194 
       
   195   // relocation data
       
   196 #define RELOCINDEX 2
       
   197 #define RELOCOFFSET (CODEOFFSET + CODESIZE)
       
   198 #define RELOCSIZE (sizeof(relocSectionData))
       
   199   {
       
   200     10,            // sh_name - to be filled
       
   201     SHT_REL,       // sh_type
       
   202     0,             // sh_flags
       
   203     0,             // sh_addr
       
   204     RELOCOFFSET,   // sh_offset - file offset of this section - to be filled in
       
   205     RELOCSIZE,     // sh_size - there's only one of them
       
   206     3,             // sh_link - index of the symbol table we use
       
   207     1,             // sh_info - refers to section 1
       
   208     0,             // sh_addralign
       
   209     sizeof(Elf32_Rel) // sh_entsize
       
   210   },
       
   211 
       
   212   // .symtab
       
   213 #define SYMTABINDEX 3
       
   214 #define SYMTABOFFSET (RELOCOFFSET + RELOCSIZE)
       
   215 #define SYMTABSIZE sizeof(symtabSectionData)
       
   216 {
       
   217     34,            // sh_name 
       
   218     SHT_SYMTAB,    // sh_type
       
   219     0,             // sh_flags
       
   220     0,             // sh_addr
       
   221     SYMTABOFFSET,  // sh_offset
       
   222     SYMTABSIZE, // sh_size
       
   223     7,             // sh_link - .strtab - the string table section
       
   224     6,             // sh_info - last local symbol
       
   225     0,             // sh_addralign
       
   226     sizeof(Elf32_Sym)// sh_entsize
       
   227   },
       
   228 
       
   229   // .comment
       
   230 #define COMMENTINDEX 4
       
   231 #define COMMENTOFFSET (SYMTABOFFSET + SYMTABSIZE)
       
   232 #define COMMENTSIZE (sizeof(commentSectionData))
       
   233 {
       
   234     50,            // sh_name 
       
   235     SHT_PROGBITS,  // sh_type
       
   236     0,             // sh_flags
       
   237     0,             // sh_addr
       
   238     COMMENTOFFSET, // sh_offset
       
   239     COMMENTSIZE,   // sh_size - to be filled in
       
   240     SHN_UNDEF,     // sh_link
       
   241     0,             // sh_info
       
   242     0,             // sh_addralign
       
   243     0              // sh_entsize
       
   244   },
       
   245 
       
   246 
       
   247   // .shstrtab
       
   248 #define SHSTRTABINDEX 5
       
   249 #define SHSTRTABOFFSET (COMMENTOFFSET + COMMENTSIZE)
       
   250 #define SHSTRTABSIZE sizeof(shstrtabSectionData)
       
   251   {
       
   252     59,            // sh_name 
       
   253     SHT_STRTAB,    // sh_type
       
   254     0,             // sh_flags
       
   255     0,             // sh_addr
       
   256     SHSTRTABOFFSET,// sh_offset
       
   257     SHSTRTABSIZE,  // sh_size - to be filled in
       
   258     SHN_UNDEF,     // sh_link
       
   259     0,             // sh_info
       
   260     0,             // sh_addralign
       
   261     0              // sh_entsize
       
   262       },
       
   263 
       
   264   // .directive section
       
   265 #define DIRECTIVEINDEX 6
       
   266 #define DIRECTIVEOFFSET SHSTRTABOFFSET + SHSTRTABSIZE
       
   267   {
       
   268     23,            // sh_name 
       
   269     SHT_PROGBITS,  // sh_type
       
   270     0,             // sh_flags
       
   271     0,             // sh_addr
       
   272     DIRECTIVEOFFSET,// sh_offset
       
   273     0,             // sh_size - to be filled in
       
   274     SHN_UNDEF,     // sh_link 
       
   275     0,             // sh_info 
       
   276     1,             // sh_addralign
       
   277     0              // sh_entsize
       
   278   },
       
   279 
       
   280   // .strtab
       
   281 #define STRTABINDEX 7
       
   282   {
       
   283     42,            // sh_name
       
   284     SHT_STRTAB,    // sh_type
       
   285     0,             // sh_flags
       
   286     0,             // sh_addr
       
   287     0,             // sh_offset - to be filled in
       
   288     0,             // sh_size - to be filled in
       
   289     SHN_UNDEF,     // sh_link
       
   290     0,             // sh_info
       
   291     0,             // sh_addralign
       
   292     0              // sh_entsize
       
   293   }
       
   294 };
       
   295 
       
   296 #define ELFOBJECTFILEVERSION 1
       
   297 #define EF_NONE 0x02000000
       
   298 
       
   299 Elf32_Ehdr headerTemplate = 
       
   300 {
       
   301   {0x7f, 'E', 'L', 'F', 
       
   302    ELFCLASS32, ELFDATA2LSB, ELFOBJECTFILEVERSION, 0,
       
   303    0, 0, 0, 0,
       
   304    0, 0, 0, 0},       // e_ident
       
   305   ET_REL,             // e_type
       
   306   EM_ARM,             // e_machine
       
   307   EV_CURRENT,         // e_version
       
   308   0x00000000,         // e_entry
       
   309   0,                  // e_phoff
       
   310   sizeof(Elf32_Ehdr), // e_shoff
       
   311   EF_ARM_EABI_VERSION,// e_flags
       
   312   sizeof(Elf32_Ehdr), // e_ehsize
       
   313   sizeof(Elf32_Phdr), // e_phentsize
       
   314   0,                  // e_phnum
       
   315   sizeof(Elf32_Shdr), // e_shentsize
       
   316 #define SHNUM (sizeof(SectionHeaderTable)/sizeof(Elf32_Shdr))
       
   317   SHNUM,              // e_shnum 
       
   318   SHSTRTABINDEX       // e_shstrndx
       
   319 };
       
   320 
       
   321 void WriteElfHeader(FILE * file);
       
   322 void WriteSectionHeaderTable(FILE * file);
       
   323 void WriteCodeSection(FILE * file);
       
   324 void WriteRelocationSection(FILE * file);
       
   325 void WriteCommentSection(FILE * file);
       
   326 void WriteSymtabSection(FILE * file);
       
   327 void WriteShStrtabSection(FILE * file);
       
   328 void WriteDirectiveSection(FILE * file, char * import);
       
   329 void WriteStrtabSection(FILE * file, char * eexport, char * import);
       
   330 
       
   331 void WriteStubFileX(FILE * file, char * eexport, char * import)
       
   332 {
       
   333   int directiveSize = sizeof(directiveSectionData) + strlen(import) + 1; // terminated by a newline
       
   334   int strtabSize = sizeof(strtabSectionData) + strlen(eexport) + strlen(import) + 2; // strings are null terminated
       
   335 
       
   336   SectionHeaderTable[DIRECTIVEINDEX].sh_size = directiveSize;
       
   337   SectionHeaderTable[STRTABINDEX].sh_offset = DIRECTIVEOFFSET+ directiveSize;
       
   338   SectionHeaderTable[STRTABINDEX].sh_size = strtabSize;
       
   339 
       
   340   symtabSectionData[IMPORTEDSYMBOLSYMNDX].st_name  = EXPORTEDSYMBOLSTRNDX + strlen(eexport) + 1;
       
   341 
       
   342   WriteElfHeader(file);
       
   343   WriteSectionHeaderTable(file);
       
   344   WriteCodeSection(file);
       
   345   WriteRelocationSection(file);
       
   346   WriteSymtabSection(file);
       
   347   WriteCommentSection(file);
       
   348   WriteShStrtabSection(file);
       
   349   WriteDirectiveSection(file, import);
       
   350   WriteStrtabSection(file, eexport, import);
       
   351 }
       
   352 
       
   353 void WriteElfHeader(FILE * file)
       
   354 {
       
   355   writef(file, &headerTemplate, sizeof(headerTemplate), "ELF header");
       
   356 }
       
   357 
       
   358 void WriteSectionHeaderTable(FILE * file)
       
   359 {
       
   360   writef(file, &SectionHeaderTable, sizeof(SectionHeaderTable), "Section header table");
       
   361 }
       
   362 
       
   363 void CheckFileOffset(FILE * f, int i, char *s)
       
   364 {
       
   365 	int o = SectionHeaderTable[i].sh_offset;
       
   366 	if (ftell(f)!= o) { croak(s); }
       
   367 }
       
   368 
       
   369 #define WriteSection(f, i, d, e1, e2) { CheckFileOffset(f, i, e1); writef(f, d, sizeof(d), e2); }
       
   370 
       
   371 void WriteCodeSection(FILE * file)
       
   372 {
       
   373   WriteSection(file, CODEINDEX, codeSectionData,"StubCode section offset incorrect", "StubCode section");
       
   374 }
       
   375 
       
   376 void WriteRelocationSection(FILE * file)
       
   377 {
       
   378   WriteSection(file, RELOCINDEX, relocSectionData,".relStubCode section offset incorrect", ".relStubCode section");
       
   379 }
       
   380 
       
   381 void WriteCommentSection(FILE * file)
       
   382 {
       
   383   WriteSection(file, COMMENTINDEX, commentSectionData,".comment section offset incorrect", ".comment section");
       
   384 }
       
   385 
       
   386 void WriteSymtabSection(FILE * file)
       
   387 {
       
   388   WriteSection(file, SYMTABINDEX, symtabSectionData,".symtab section offset incorrect", ".symtab section");
       
   389 }
       
   390 
       
   391 void WriteShStrtabSection(FILE * file)
       
   392 {
       
   393   WriteSection(file, SHSTRTABINDEX, shstrtabSectionData,".shstrtab section offset incorrect", ".shstrtab section");
       
   394 }
       
   395 
       
   396 void WriteDirectiveSection(FILE * file, char * import)
       
   397 {
       
   398   WriteSection(file, DIRECTIVEINDEX, directiveSectionData,
       
   399 	       ".directive section offset incorrect", ".directive section");
       
   400   fprintf(file, "%s\n", import);
       
   401 }
       
   402 
       
   403 void WriteStrtabSection(FILE * file, char * eexport, char * import)
       
   404 {
       
   405   char n = 0;
       
   406   WriteSection(file, STRTABINDEX, strtabSectionData,".strtab section offset incorrect", ".strtab section");
       
   407   fprintf(file, eexport);
       
   408   fwrite(&n, sizeof(n), 1, file);
       
   409   fprintf(file, import);
       
   410   fwrite(&n, sizeof(n), 1, file);
       
   411 }
       
   412 
       
   413 
       
   414 
       
   415 void WriteStubFile(char * file, char * eexport, char * import)
       
   416 {
       
   417   FILE * f = fopen(file, "wb");
       
   418   if (!f) croak("can't open output file");
       
   419   
       
   420   WriteStubFileX(f, eexport, import);
       
   421 
       
   422   fclose(f);
       
   423 }
       
   424 
       
   425 
       
   426 int  main (void)
       
   427 {
       
   428   
       
   429   char file[MAXPATHNAMELENGTH], eexport[MAXSYMBOLLENGTH], import[MAXSYMBOLLENGTH];
       
   430   
       
   431   while (!feof(stdin) && !ferror(stdin)) {
       
   432     fscanf(stdin, "%s %s %s\n", file, eexport, import);
       
   433     WriteStubFile(file, eexport, import);
       
   434   }
       
   435   return EXIT_SUCCESS;
       
   436 }