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