[GCCE] We need a way for the HAL config extension to parameterise the HAL config file (.hcf) that will be used, depending upon
the toolchain we are building with. E.g. if we are building BeagleBoard with RVCT we can configure hardware floating point
because we have ARM's vfp math libraries; if we are building it with GCC, we lack this library support.
// Copyright (c) 1996-2009 Nokia Corporation and/or its subsidiary(-ies).
// All rights reserved.
// This component and the accompanying materials are made available
// under the terms of "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 <stdlib.h>
#include <string.h>
#include <e32std.h>
#include <e32std_private.h>
#include "h_utl.h"
#include "pe_file.h"
TInt E32ImageFile_PE::CopyImportAddrTable(char *aPtr, PEFile &aPeFile)
//
// Copy the import address table entries
//
{
TUint *ptr=(TUint *)aPtr;
char *importsection=aPeFile.iSectionData[KImportSection];
TUint *src=(TUint *)importsection;
while (*src)
{
TUint vaoffset=src[4];
if (!gLittleEndian) ByteSwap(vaoffset);
TUint offset=vaoffset-aPeFile.iSectionHeader[KImportSection]->VirtualAddress; // find the offset into the section of import addr table
vaoffset=src[3];
if (!gLittleEndian) ByteSwap(vaoffset);
TUint exportername=vaoffset-aPeFile.iSectionHeader[KImportSection]->VirtualAddress;
TUint *p=(TUint *)(importsection+offset);
while (*p)
{
if ((*p&0x80000000)==0)
{
Print(EError, "%s exporting symbol by name\n", importsection+exportername);
return KErrGeneral;
}
*ptr++=(*p++)&0x7fffffff; // mask out the high bit (- indicates export by ordinal)
}
src+=5;
}
*ptr++=0;
return KErrNone;
}
extern char* gX86imp;
extern int gX86num_imports;
extern int gX86num_imp_dlls;
extern int gX86imp_size;
int* gX86imp_relocs=NULL;
TInt CrunchImportSection(TAny* aSection, TInt aNumImpDlls, TInt aNumImports)
{
// Remove lists of ordinals from import section
TInt* d = (TInt*)aSection;
TInt orig_size = *d;
TInt offset_correction = aNumImports*sizeof(TUint);
*d -= offset_correction; // reduce total section size
TInt *dd = d+1;
TInt *ss = d+1;
TInt i;
for (i=0; i<aNumImpDlls; ++i)
{
*dd++ = *ss++ - offset_correction; // copy name offset and reduce it appropriately
TInt nimp = *ss++; // number of imports from this DLL
*dd++ = nimp; // copy it
ss += nimp; // skip the ordinals in the original list
}
TInt used_size = (ss - d) * sizeof(TInt);
memcpy(dd, ss, orig_size - used_size); // copy name strings
return *d; // return new total section size
}
char *E32ImageFile_PE::CreateImportSection(const PEFile &aPeFile, TInt &aSize)
//
// Create a new format import section
//
{
int total_imports = 0;
if (gX86imp)
{
TUint *rdata=(TUint*)aPeFile.iSectionData[KConstSection];
TInt bytecount=gX86imp_size;
char* section=new char[bytecount];
memcpy(section,gX86imp,bytecount);
int i;
int j=0;
int* s=(int*)section;
s++;
gX86imp_relocs=new int[gX86num_imports+gX86num_imp_dlls];
for (i=0; i<gX86num_imp_dlls; ++i)
{
++s;
int n=*s++;
total_imports += n;
while (n--)
{
int rdata_int_offset=*s>>2;
*s=rdata[rdata_int_offset]&0x7fffffffu; // rdata offset to ordinal
gX86imp_relocs[rdata_int_offset]=j<<2;
++j;
++s;
}
}
*(TInt*)section = bytecount;
aSize = CrunchImportSection(section, gX86num_imp_dlls, total_imports);
return section;
}
PIMAGE_SECTION_HEADER aHeader=aPeFile.iSectionHeader[KImportSection];
TUint *aSrc=(TUint *)aPeFile.iSectionData[KImportSection];
TInt nimportdlls=aPeFile.NumberOfImportDlls();
if (nimportdlls==0)
{
aSize=0;
return NULL;
}
E32ImportBlock *block=new E32ImportBlock [nimportdlls];
char **name=new char* [nimportdlls];
TUint **import=new TUint* [nimportdlls];
TInt bytecount=sizeof(E32ImportSection)+sizeof(E32ImportBlock)*nimportdlls;
TUint *src=aSrc;
TInt i;
for (i=0; i<nimportdlls; i++)
{
TUint vaoffset=src[4];
if (!gLittleEndian) ByteSwap(vaoffset);
TUint offset=vaoffset-aHeader->VirtualAddress; // find the offset into the section of import addr table
TUint *p=aSrc+offset/4;
block[i].iNumberOfImports=0;
while (*p++)
block[i].iNumberOfImports++;
total_imports += block[i].iNumberOfImports;
import[i]=new TUint [block[i].iNumberOfImports];
TInt j;
p=aSrc+offset/4;
for (j=0; j<block[i].iNumberOfImports; j++)
{
import[i][j]=(*p++)&0x7fffffffu;
bytecount+=4;
}
// name
vaoffset=src[3];
if (!gLittleEndian) ByteSwap(vaoffset);
offset=vaoffset-aHeader->VirtualAddress;
name[i]=((char *)aSrc)+offset;
bytecount+=strlen(name[i])+1;
src+=5;
}
bytecount=ALIGN4(bytecount);
char *section=new char [bytecount];
char *s=section+sizeof(E32ImportSection);
for (i=0; i<nimportdlls; i++)
{
memcpy(s, (char *)&block[i], sizeof(E32ImportBlock));
s+=sizeof(E32ImportBlock);
memcpy(s, (char *)import[i], block[i].iNumberOfImports*4);
s+=block[i].iNumberOfImports*4;
}
char *t=section+sizeof(E32ImportSection);
for (i=0; i<nimportdlls; i++)
{
((E32ImportBlock *)t)->iOffsetOfDllName=s-section;
strcpy(s, name[i]);
s+=strlen(name[i])+1;
t += ((E32ImportBlock *)t)->iNumberOfImports * sizeof(TUint) + sizeof(E32ImportBlock);
}
while ((s-section)<bytecount)
*s++=0;
// free mem
for (i=0; i<nimportdlls; i++)
delete import[i];
delete block;
delete import;
delete name;
*(TInt*)section = bytecount;
aSize = CrunchImportSection(section, nimportdlls, total_imports);
return section;
}
TUint E32ImageFile_PE::FixImportThunk(PEFile &aPeFile, TUint va)
//
// Fix an access to the import address table
//
{
TUint *imports=(TUint *)aPeFile.iSectionData[KImportSection];
TUint n=0;
TUint importoffset=imports[4];
if (!gLittleEndian) ByteSwap(importoffset);
TUint iat=importoffset-aPeFile.iSectionHeader[KImportSection]->VirtualAddress;
while (iat<va)
{
if (*((TUint *)(aPeFile.iSectionData[KImportSection]+iat))==0)
{
imports+=5;
importoffset=imports[4];
if (!gLittleEndian) ByteSwap(importoffset);
iat=importoffset-aPeFile.iSectionHeader[KImportSection]->VirtualAddress;
}
else
{
n++;
iat+=4;
}
}
// Flag errors brought about by a corrupt input binary
if (iat>va)
{
Print(EError, "%s is corrupt - problem processing import address table.\n", this->iFileName);
return (TUint)KErrGeneral;
}
return iHdr->iTextSize+n*sizeof(TUint);
}