--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/bintools/elftools/genstubs/genstubs.cpp Mon May 10 19:54:49 2010 +0100
@@ -0,0 +1,439 @@
+/*
+* Copyright (c) 2007-2009 Nokia Corporation and/or its subsidiary(-ies).
+* All rights reserved.
+* This component and the accompanying materials are made available
+* under the terms of the License "Eclipse Public License v1.0"
+* which accompanies this distribution, and is available
+* at the URL "http://www.eclipse.org/legal/epl-v10.html".
+*
+* Initial Contributors:
+* Nokia Corporation - initial contribution.
+*
+* Contributors:
+*
+* Description:
+*
+*/
+
+
+#include <stdio.h>
+#include <string.h>
+#include <stdlib.h>
+
+#include <elfdefs.h>
+
+#define MAXPATHNAMELENGTH 2000
+#define MAXSYMBOLLENGTH 2000
+
+#define writef(f, d, n, s) if ( 1 != fwrite(d, n, 1, f)) { croak(s); }
+
+void croak(char * s)
+{
+ printf("GENSTUB ERROR: %s\n", s);
+ exit(EXIT_FAILURE);
+}
+
+long codeSectionData [] =
+{
+ 0xe51ff004, // LDR pc,0x4
+ 0x00000000 // the pointer to the imported code
+};
+
+
+#define COMMENTSTRING "\tAndy's magic stub generator vsn 0.2\n"
+char commentSectionData[] = // "\tAndy's magic stub generator vsn 0.2\n"
+{
+ '\t','A','n','d','y','\'','s',' ','m','a','g','i','c',' ',
+ 's','t','u','b',' ','g','e','n','e','r','a','t','o','r',' ',
+ 'v','s','n',' ','0','.','2','\n'
+};
+
+char directiveSectionData[] = // "#<SYMEDIT>\nIMPORT "
+{
+ '#','<','S','Y','M','E','D','I','T','>','\n',
+ 'I','M','P','O','R','T',' '
+};
+
+char strtabSectionData [] =
+{
+ 0,'$','a',0, // $a
+ '$','d',0, // $d
+ 'S','t','u','b','C','o','d','e',0, // StubCode
+ '.','d','i','r','e','c','t','i','v','e',0, // .directive
+ 't','h','e','I','m','p','o','r','t','e','d','S','y','m','b','o','l',0 // theImportSymbol
+};
+
+Elf32_Sym symtabSectionData[] =
+{
+ // undefined symbol
+ {
+ 0, // st_name
+ 0, // st_value
+ 0, // st_size
+ 0, // st_info
+ 0, // st_other
+ 0 // stshndx
+ },
+ // $a
+ {
+ 1, // st_name
+ 0, // st_value
+ 0, // st_size
+ ELF32_ST_INFO(STB_LOCAL,STT_FUNC), // st_info
+ 0, // st_other
+ 1 // stshndx
+ },
+ // $d
+ {
+ 4, // st_name
+ 4, // st_value
+ 0, // st_size
+ ELF32_ST_INFO(STB_LOCAL,STT_OBJECT), // st_info
+ 0, // st_other
+ 1 // stshndx
+ },
+ // StubCode
+ {
+ 7, // st_name
+ 0, // st_value
+ sizeof(codeSectionData), // st_size
+ ELF32_ST_INFO(STB_LOCAL,STT_SECTION), // st_info
+ 0, // st_other
+ 1 // stshndx
+ },
+ // .directive
+#define DIRECTIVESYMNDX 4
+ {
+ 16,// st_name
+ 0, // st_value
+ 0, // st_size - to be filled on
+ ELF32_ST_INFO(STB_LOCAL,STT_SECTION), // st_info
+ 0, // st_other
+ 3 // stshndx
+ },
+ // theImportedSymbol
+ {
+ 27, // st_name
+ 4, // st_value
+ 0, // st_size
+ ELF32_ST_INFO(STB_LOCAL,STT_FUNC), // st_info
+ 0, // st_other
+ 1 // stshndx
+ },
+
+ // the exported symbol
+#define EXPORTEDSYMBOLSTRNDX 45
+ {
+ EXPORTEDSYMBOLSTRNDX, // st_name
+ 0, // st_value
+ 0, // st_size
+ ELF32_ST_INFO(STB_GLOBAL,STT_FUNC), // st_info
+ 0, // st_other
+ 1 // stshndx
+ },
+ // the imported symbol
+#define IMPORTEDSYMBOLSYMNDX 7
+ {
+ 0, // st_name - needs to be filled in = EXPORTEDSYMBOLSTRNDX + strlen(exportedSymbol) + 1
+ 0, // st_value
+ 0, // st_size
+ ELF32_ST_INFO(STB_GLOBAL,STT_NOTYPE), // st_info
+ 0, // st_other
+ SHN_UNDEF // stshndx
+ }
+};
+
+Elf32_Rel relocSectionData [] =
+{
+ {
+ 0x00000004, // r_offset
+ ELF32_R_INFO(IMPORTEDSYMBOLSYMNDX, R_ARM_ABS32)
+ }
+};
+
+char shstrtabSectionData []=
+{
+ 0,'S','t','u','b','C','o','d','e',0, // StubCode
+ '.','r','e','l','S','t','u','b','C','o','d','e',0, // .relStubCode
+ '.','d','i','r','e','c','t','i','v','e',0, // .directive
+ '.','s','y','m','t','a','b',0, // .symtab
+ '.','s','t','r','t','a','b',0, // .strtab
+ '.','c','o','m','m','e','n','t',0, // .comment
+ '.','s','h','s','t','r','t','a','b',0 // .shstrtab
+};
+
+Elf32_Shdr SectionHeaderTable[] =
+{
+ // dummy section
+ {
+ 0, // sh_name - to be filled
+ SHT_NULL, // sh_type
+ 0, // sh_flags
+ 0, // sh_addr
+ 0, // sh_offset - file offset of this section - to be filled in
+ 0, // sh_size - to be filled in
+ 0, // sh_link
+ 0, // sh_info
+ 0, // sh_addralign
+ 0 // sh_entsize
+ },
+
+ // StubCode section
+#define CODEINDEX 1
+#define CODEOFFSET (sizeof(Elf32_Ehdr) + (8 * sizeof(Elf32_Shdr)))
+#define CODESIZE (sizeof(codeSectionData))
+ {
+ 1, // sh_name
+ SHT_PROGBITS, // sh_type
+ SHF_ALLOC + SHF_EXECINSTR, // sh_flags
+ 0, // sh_addr
+ CODEOFFSET, // sh_offset
+ CODESIZE, // sh_size
+ SHN_UNDEF, // sh_link
+ 0, // sh_info
+ 4, // sh_addralign
+ 0 // sh_entsize
+ },
+
+ // relocation data
+#define RELOCINDEX 2
+#define RELOCOFFSET (CODEOFFSET + CODESIZE)
+#define RELOCSIZE (sizeof(relocSectionData))
+ {
+ 10, // sh_name - to be filled
+ SHT_REL, // sh_type
+ 0, // sh_flags
+ 0, // sh_addr
+ RELOCOFFSET, // sh_offset - file offset of this section - to be filled in
+ RELOCSIZE, // sh_size - there's only one of them
+ 3, // sh_link - index of the symbol table we use
+ 1, // sh_info - refers to section 1
+ 0, // sh_addralign
+ sizeof(Elf32_Rel) // sh_entsize
+ },
+
+ // .symtab
+#define SYMTABINDEX 3
+#define SYMTABOFFSET (RELOCOFFSET + RELOCSIZE)
+#define SYMTABSIZE sizeof(symtabSectionData)
+{
+ 34, // sh_name
+ SHT_SYMTAB, // sh_type
+ 0, // sh_flags
+ 0, // sh_addr
+ SYMTABOFFSET, // sh_offset
+ SYMTABSIZE, // sh_size
+ 7, // sh_link - .strtab - the string table section
+ 6, // sh_info - last local symbol
+ 0, // sh_addralign
+ sizeof(Elf32_Sym)// sh_entsize
+ },
+
+ // .comment
+#define COMMENTINDEX 4
+#define COMMENTOFFSET (SYMTABOFFSET + SYMTABSIZE)
+#define COMMENTSIZE (sizeof(commentSectionData))
+{
+ 50, // sh_name
+ SHT_PROGBITS, // sh_type
+ 0, // sh_flags
+ 0, // sh_addr
+ COMMENTOFFSET, // sh_offset
+ COMMENTSIZE, // sh_size - to be filled in
+ SHN_UNDEF, // sh_link
+ 0, // sh_info
+ 0, // sh_addralign
+ 0 // sh_entsize
+ },
+
+
+ // .shstrtab
+#define SHSTRTABINDEX 5
+#define SHSTRTABOFFSET (COMMENTOFFSET + COMMENTSIZE)
+#define SHSTRTABSIZE sizeof(shstrtabSectionData)
+ {
+ 59, // sh_name
+ SHT_STRTAB, // sh_type
+ 0, // sh_flags
+ 0, // sh_addr
+ SHSTRTABOFFSET,// sh_offset
+ SHSTRTABSIZE, // sh_size - to be filled in
+ SHN_UNDEF, // sh_link
+ 0, // sh_info
+ 0, // sh_addralign
+ 0 // sh_entsize
+ },
+
+ // .directive section
+#define DIRECTIVEINDEX 6
+#define DIRECTIVEOFFSET SHSTRTABOFFSET + SHSTRTABSIZE
+ {
+ 23, // sh_name
+ SHT_PROGBITS, // sh_type
+ 0, // sh_flags
+ 0, // sh_addr
+ DIRECTIVEOFFSET,// sh_offset
+ 0, // sh_size - to be filled in
+ SHN_UNDEF, // sh_link
+ 0, // sh_info
+ 1, // sh_addralign
+ 0 // sh_entsize
+ },
+
+ // .strtab
+#define STRTABINDEX 7
+ {
+ 42, // sh_name
+ SHT_STRTAB, // sh_type
+ 0, // sh_flags
+ 0, // sh_addr
+ 0, // sh_offset - to be filled in
+ 0, // sh_size - to be filled in
+ SHN_UNDEF, // sh_link
+ 0, // sh_info
+ 0, // sh_addralign
+ 0 // sh_entsize
+ }
+};
+
+#define ELFOBJECTFILEVERSION 1
+#define EF_NONE 0x02000000
+
+Elf32_Ehdr headerTemplate =
+{
+ {0x7f, 'E', 'L', 'F',
+ ELFCLASS32, ELFDATA2LSB, ELFOBJECTFILEVERSION, 0,
+ 0, 0, 0, 0,
+ 0, 0, 0, 0}, // e_ident
+ ET_REL, // e_type
+ EM_ARM, // e_machine
+ EV_CURRENT, // e_version
+ 0x00000000, // e_entry
+ 0, // e_phoff
+ sizeof(Elf32_Ehdr), // e_shoff
+ EF_ARM_EABI_VERSION,// e_flags
+ sizeof(Elf32_Ehdr), // e_ehsize
+ sizeof(Elf32_Phdr), // e_phentsize
+ 0, // e_phnum
+ sizeof(Elf32_Shdr), // e_shentsize
+#define SHNUM (sizeof(SectionHeaderTable)/sizeof(Elf32_Shdr))
+ SHNUM, // e_shnum
+ SHSTRTABINDEX // e_shstrndx
+};
+
+void WriteElfHeader(FILE * file);
+void WriteSectionHeaderTable(FILE * file);
+void WriteCodeSection(FILE * file);
+void WriteRelocationSection(FILE * file);
+void WriteCommentSection(FILE * file);
+void WriteSymtabSection(FILE * file);
+void WriteShStrtabSection(FILE * file);
+void WriteDirectiveSection(FILE * file, char * import);
+void WriteStrtabSection(FILE * file, char * eexport, char * import);
+
+void WriteStubFileX(FILE * file, char * eexport, char * import)
+{
+ int directiveSize = sizeof(directiveSectionData) + strlen(import) + 1; // terminated by a newline
+ int strtabSize = sizeof(strtabSectionData) + strlen(eexport) + strlen(import) + 2; // strings are null terminated
+
+ SectionHeaderTable[DIRECTIVEINDEX].sh_size = directiveSize;
+ SectionHeaderTable[STRTABINDEX].sh_offset = DIRECTIVEOFFSET+ directiveSize;
+ SectionHeaderTable[STRTABINDEX].sh_size = strtabSize;
+
+ symtabSectionData[IMPORTEDSYMBOLSYMNDX].st_name = EXPORTEDSYMBOLSTRNDX + strlen(eexport) + 1;
+
+ WriteElfHeader(file);
+ WriteSectionHeaderTable(file);
+ WriteCodeSection(file);
+ WriteRelocationSection(file);
+ WriteSymtabSection(file);
+ WriteCommentSection(file);
+ WriteShStrtabSection(file);
+ WriteDirectiveSection(file, import);
+ WriteStrtabSection(file, eexport, import);
+}
+
+void WriteElfHeader(FILE * file)
+{
+ writef(file, &headerTemplate, sizeof(headerTemplate), "ELF header");
+}
+
+void WriteSectionHeaderTable(FILE * file)
+{
+ writef(file, &SectionHeaderTable, sizeof(SectionHeaderTable), "Section header table");
+}
+
+void CheckFileOffset(FILE * f, int i, char *s)
+{
+ int o = SectionHeaderTable[i].sh_offset;
+ if (ftell(f)!= o) { croak(s); }
+}
+
+#define WriteSection(f, i, d, e1, e2) { CheckFileOffset(f, i, e1); writef(f, d, sizeof(d), e2); }
+
+void WriteCodeSection(FILE * file)
+{
+ WriteSection(file, CODEINDEX, codeSectionData,"StubCode section offset incorrect", "StubCode section");
+}
+
+void WriteRelocationSection(FILE * file)
+{
+ WriteSection(file, RELOCINDEX, relocSectionData,".relStubCode section offset incorrect", ".relStubCode section");
+}
+
+void WriteCommentSection(FILE * file)
+{
+ WriteSection(file, COMMENTINDEX, commentSectionData,".comment section offset incorrect", ".comment section");
+}
+
+void WriteSymtabSection(FILE * file)
+{
+ WriteSection(file, SYMTABINDEX, symtabSectionData,".symtab section offset incorrect", ".symtab section");
+}
+
+void WriteShStrtabSection(FILE * file)
+{
+ WriteSection(file, SHSTRTABINDEX, shstrtabSectionData,".shstrtab section offset incorrect", ".shstrtab section");
+}
+
+void WriteDirectiveSection(FILE * file, char * import)
+{
+ WriteSection(file, DIRECTIVEINDEX, directiveSectionData,
+ ".directive section offset incorrect", ".directive section");
+ fprintf(file, "%s\n", import);
+}
+
+void WriteStrtabSection(FILE * file, char * eexport, char * import)
+{
+ char n = 0;
+ WriteSection(file, STRTABINDEX, strtabSectionData,".strtab section offset incorrect", ".strtab section");
+ fprintf(file, eexport);
+ fwrite(&n, sizeof(n), 1, file);
+ fprintf(file, import);
+ fwrite(&n, sizeof(n), 1, file);
+}
+
+
+
+void WriteStubFile(char * file, char * eexport, char * import)
+{
+ FILE * f = fopen(file, "wb");
+ if (!f) croak("can't open output file");
+
+ WriteStubFileX(f, eexport, import);
+
+ fclose(f);
+}
+
+
+int main (void)
+{
+
+ char file[MAXPATHNAMELENGTH], eexport[MAXSYMBOLLENGTH], import[MAXSYMBOLLENGTH];
+
+ while (!feof(stdin) && !ferror(stdin)) {
+ fscanf(stdin, "%s %s %s\n", file, eexport, import);
+ WriteStubFile(file, eexport, import);
+ }
+ return EXIT_SUCCESS;
+}