Don't mess around with EPOCROOT until actually entering raptor so we know what the original was
Put the original epocroot back on the front of the whatcomp output. This allows what output to be
either relative or absolute depending on what your epocroot is.
/*
* 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;
}