TInt PEFile::Normalise() // // Remove the MSVC anomalies // { // MSVC puts export data in with .rdata if (iExportDataDir && iSectionHeader[KExportSection]==NULL) { if (!PEFile::VirtualAddressInSection(iExportDataDir+iLinkedBase, iSectionHeader[KConstSection])) return Print(EError, "Can't find exports in this PE file.\n"); else { iSectionHeader[KExportSection]=new IMAGE_SECTION_HEADER; iSectionHeader[KExportSection]->VirtualAddress=iExportDataDir; iSectionHeader[KExportSection]->Misc.VirtualSize=iExportDirSize; iSectionHeader[KExportSection]->SizeOfRawData=iExportDirSize; iSectionData[KExportSection]=new char [iExportDirSize]; if (iSectionData[KExportSection]==NULL) return Print(EError, "Out of memory.\n"); memcpy(iSectionData[KExportSection], iSectionData[KConstSection]+iExportDataDir-iSectionHeader[KConstSection]->VirtualAddress, iExportDirSize); // adjust .rdata so it does not include .edata iSectionHeader[KConstSection]->Misc.VirtualSize-=iExportDirSize; iSectionHeader[KConstSection]->SizeOfRawData-=iExportDirSize; char *c=new char [iSectionHeader[KConstSection]->SizeOfRawData]; if (c==NULL) return Print(EError, "Out of memory.\n"); memcpy(c, iSectionData[KConstSection], iSectionHeader[KConstSection]->SizeOfRawData); delete iSectionData[KConstSection]; iSectionData[KConstSection]=c; } } // Stupid compilers generate .idata sections even when there are no imports if (iSectionHeader[KImportSection]) { if (NumberOfImports()==0) { delete iSectionHeader[KImportSection]; delete iSectionData[KImportSection]; iSectionHeader[KImportSection]=NULL; iSectionData[KImportSection]=NULL; } } return KErrNone; }
void E32ImageFile::RelocateSection(char* aPtr, char* aRelocs, TUint aCodeDelta, TUint aDataDelta, char* aImagePtr, TLinAddr** aIATRefs, TBool keepIAT) // // Relocates the section data at aPtr // { TUint codeStart=iHdr->iCodeBase; TUint codeFinish=codeStart+iHdr->iCodeSize; TUint iatStart = aIATRefs ? codeStart+iHdr->iTextSize : 0; TUint iatFinish = aIATRefs ? iatStart+NumberOfImports()*sizeof(TUint) : 0; char* relocs=aRelocs; TUint page=0; TInt size=0; TInt i=((E32RelocSection *)relocs)->iNumberOfRelocs; relocs+=sizeof(E32RelocSection); while (i>0) { if (size>0) { TUint offset=*(TUint16 *)relocs; relocs+=2; if (offset!=0) { // its a reloc TUint va=page+(offset&0x0fff); TUint relocType=offset&0xf000; TUint *dataptr=(TUint *)(aPtr+va); assert((char *)dataptr < aRelocs); TUint data=*dataptr; if (relocType == KTextRelocType) *dataptr=data+aCodeDelta; // points to text/rdata section else if (relocType == KDataRelocType) *dataptr=data+aDataDelta; else { if (relocType != KInferredRelocType) Print(EError,"Unrecognized relocation type %x\n",relocType); if (data>=iatStart && data<iatFinish) { TUint iatNum = (data-iatStart)/sizeof(TLinAddr); // If "keepIAT" is used then the importing instruction must import through the IAT entry, // but otherwise we change the IAT entry to point to the bit of code doing the importing // and do the real fix-up later on in TRomBuilderEntry::FixupImports. // NB: We always want to do this for X86 or data exports dont work. if (keepIAT || (iHdr->iCpuIdentifier & 0x1000) /*denotes X86*/) *dataptr=data+aCodeDelta; else { if ((TUint)aIATRefs[iatNum]>65535) Print(EWarning, "Multiple relocations for IAT entry %d (0x%x, 0x%x)\n", iatNum, aIATRefs[iatNum], dataptr); else aIATRefs[iatNum] = (TLinAddr*)(aImagePtr+va); // ROM image address of importing pointer } } else if (data>=codeStart && data<codeFinish) *dataptr=data+aCodeDelta; // points to text/rdata section else *dataptr=data+aDataDelta; // points to data section } --i; } size-=2; } else { // next page of relocs page=*(TUint *)relocs; relocs+=4; size=*(TUint *)relocs; relocs+=4; size-=8; } } }