243 return; |
249 return; |
244 } |
250 } |
245 Add(aChild); |
251 Add(aChild); |
246 } |
252 } |
247 |
253 |
248 TRomNode* TRomNode::NewSubDir(TText *aName) |
254 TRomNode* TRomNode::NewSubDir(const char *aName) { |
249 { |
255 if (iEntry) { |
250 if (iEntry) |
|
251 { |
|
252 Print(EError, "Adding subdirectory to a file!!!\n"); |
256 Print(EError, "Adding subdirectory to a file!!!\n"); |
253 return 0; |
257 return 0; |
254 } |
258 } |
255 |
259 |
256 TRomNode* node = new TRomNode(aName ); |
260 TRomNode* node = new TRomNode(aName); |
257 if (node==0) |
261 if (node==0){ |
258 { |
|
259 Print(EError, "TRomNode::NewNode: Out of memory\n"); |
262 Print(EError, "TRomNode::NewNode: Out of memory\n"); |
260 return 0; |
263 return 0; |
261 } |
264 } |
262 node->iParent = this; |
265 node->iParent = this; |
263 Add(node); |
266 Add(node); |
264 return node; |
267 return node; |
265 } |
268 } |
266 |
269 |
267 void TRomNode::Add(TRomNode* aChild) |
270 void TRomNode::Add(TRomNode* aChild) { |
268 { |
271 if (iChild){ // this node is a non-empty directory |
269 if (iChild) // this node is a non-empty directory |
272 |
270 { |
|
271 TRomNode* dir = iChild; // find where to link in the new node |
273 TRomNode* dir = iChild; // find where to link in the new node |
272 while (dir->iSibling) |
274 while (dir->iSibling) |
273 dir = dir->iSibling; |
275 dir = dir->iSibling; |
274 dir->iSibling = aChild; |
276 dir->iSibling = aChild; |
275 } |
277 } |
276 else |
278 else |
277 iChild = aChild; // else just set it up as the child of the dir |
279 iChild = aChild; // else just set it up as the child of the dir |
278 aChild->iSibling = 0; |
280 aChild->iSibling = 0; |
279 aChild->iParent = this; |
281 aChild->iParent = this; |
280 } |
282 } |
281 |
|
282 TInt TRomNode::SetAttExtra(TText *anAttWord, TRomBuilderEntry* aFile, enum EKeyword aKeyword) |
|
283 // |
283 // |
284 // Set the file extra attribute byte from the letters passed |
284 // Set the file extra attribute byte from the letters passed |
285 // Note: The iAttExtra bits are inverted. '0' represent enabled |
285 // Note: The iAttExtra bits are inverted. '0' represent enabled |
286 // |
286 // |
287 { |
287 TInt TRomNode::SetAttExtra(char *anAttWord, TRomBuilderEntry* aFile, enum EKeyword aKeyword){ |
288 iAttExtra=0xFF; |
288 iAttExtra=0xFF; |
289 if (anAttWord==0 || anAttWord[0]=='\0') |
289 if (anAttWord==0 || anAttWord[0]=='\0') |
290 return Print(EError, "Missing argument for keyword 'exattrib'.\n"); |
290 return Print(EError, "Missing argument for keyword 'exattrib'.\n"); |
291 for (TText *letter=anAttWord;*letter!=0;letter++) |
291 for (char *letter=anAttWord;*letter!=0;letter++) |
292 { |
292 { |
293 switch (*letter) |
293 switch (*letter) |
294 { |
294 { |
295 case 'u': |
295 case 'u': |
296 iAttExtra |= (KEntryAttUnique >> 23); // '1' represents disabled in iAttExtra |
296 iAttExtra |= (KEntryAttUnique >> 23); // '1' represents disabled in iAttExtra |
738 aFileCount++; |
740 aFileCount++; |
739 current=current->iSibling; |
741 current=current->iSibling; |
740 } |
742 } |
741 } |
743 } |
742 |
744 |
743 void TRomNode::Destroy() |
|
744 // |
745 // |
745 // Follow the TRomNode tree, destroying it |
746 // Follow the TRomNode tree, destroying it |
746 // |
747 // |
747 { |
748 void TRomNode::Destroy() { |
748 |
|
749 TRomNode *current = this; // root has no siblings |
749 TRomNode *current = this; // root has no siblings |
750 while (current) |
750 while (current) |
751 { |
751 { |
752 if (current->iChild) |
752 if (current->iChild) |
753 current->iChild->Destroy(); |
753 current->iChild->Destroy(); |
754 TRomNode* prev=current; |
754 TRomNode* prev=current; |
755 current=current->iSibling; |
755 current=current->iSibling; |
756 delete prev; |
756 delete prev; |
757 prev = 0; |
757 prev = 0; |
758 } |
758 } |
759 } |
759 } |
760 |
760 |
761 |
761 |
762 |
762 |
763 |
763 |
764 TInt TRomNode::NameCpy(char* aDest, TUint8& aUnicodeLength ) |
|
765 // |
|
766 // Safely copy a file name in the rom entry |
|
767 // Returns the number of bytes used. Write the length in unicode characters |
|
768 // into aUnicodeLength. |
|
769 // |
|
770 { |
|
771 |
|
772 if ((aDest==NULL) || (iName==NULL)) |
|
773 return 0; |
|
774 const unsigned char* pSourceByte = (const unsigned char*)iName; |
|
775 unsigned char* pTargetByte=(unsigned char*)aDest; |
|
776 for (;;) |
|
777 { |
|
778 const TUint sourceByte=*pSourceByte; |
|
779 if (sourceByte==0) |
|
780 { |
|
781 break; |
|
782 } |
|
783 if ((sourceByte&0x80)==0) |
|
784 { |
|
785 *pTargetByte=(unsigned char)sourceByte; |
|
786 ++pTargetByte; |
|
787 *pTargetByte=0; |
|
788 ++pTargetByte; |
|
789 ++pSourceByte; |
|
790 } |
|
791 else if ((sourceByte&0xe0)==0xc0) |
|
792 { |
|
793 ++pSourceByte; |
|
794 const TUint secondSourceByte=*pSourceByte; |
|
795 if ((secondSourceByte&0xc0)!=0x80) |
|
796 { |
|
797 Print(EError, "Bad UTF-8 '%s'", iName); |
|
798 exit(671); |
|
799 } |
|
800 *pTargetByte=(unsigned char)((secondSourceByte&0x3f)|((sourceByte&0x03)<<6)); |
|
801 ++pTargetByte; |
|
802 *pTargetByte=(unsigned char)((sourceByte>>2)&0x07); |
|
803 ++pTargetByte; |
|
804 ++pSourceByte; |
|
805 } |
|
806 else if ((sourceByte&0xf0)==0xe0) |
|
807 { |
|
808 ++pSourceByte; |
|
809 const TUint secondSourceByte=*pSourceByte; |
|
810 if ((secondSourceByte&0xc0)!=0x80) |
|
811 { |
|
812 Print(EError, "Bad UTF-8 '%s'", iName); |
|
813 exit(672); |
|
814 } |
|
815 ++pSourceByte; |
|
816 const TUint thirdSourceByte=*pSourceByte; |
|
817 if ((thirdSourceByte&0xc0)!=0x80) |
|
818 { |
|
819 Print(EError, "Bad UTF-8 '%s'", iName); |
|
820 exit(673); |
|
821 } |
|
822 *pTargetByte=(unsigned char)((thirdSourceByte&0x3f)|((secondSourceByte&0x03)<<6)); |
|
823 ++pTargetByte; |
|
824 *pTargetByte=(unsigned char)(((secondSourceByte>>2)&0x0f)|((sourceByte&0x0f)<<4)); |
|
825 ++pTargetByte; |
|
826 ++pSourceByte; |
|
827 } |
|
828 else |
|
829 { |
|
830 Print(EError, "Bad UTF-8 '%s'", iName); |
|
831 exit(674); |
|
832 } |
|
833 } |
|
834 const TInt numberOfBytesInTarget=(pTargetByte-(unsigned char*)aDest); // this number excludes the trailing null-terminator |
|
835 if (numberOfBytesInTarget%2!=0) |
|
836 { |
|
837 Print(EError, "Internal error"); |
|
838 exit(675); |
|
839 } |
|
840 aUnicodeLength = (TUint8)(numberOfBytesInTarget/2); // returns the length of aDest (in UTF-16 characters for Unicode, not bytes) |
|
841 return numberOfBytesInTarget; |
|
842 } |
|
843 |
|
844 |
|
845 TInt TRomNode::NameLengthUnicode() const |
|
846 // |
|
847 // Find the unicode lenght of the name |
|
848 // |
|
849 { |
|
850 |
|
851 if (iName==NULL) |
|
852 return 0; |
|
853 |
|
854 const unsigned char* pSourceByte = (const unsigned char*)iName; |
|
855 TInt len = 0; |
|
856 for (;;) |
|
857 { |
|
858 const TUint sourceByte=*pSourceByte; |
|
859 if (sourceByte==0) |
|
860 { |
|
861 break; |
|
862 } |
|
863 if ((sourceByte&0x80)==0) |
|
864 { |
|
865 len += 2; |
|
866 ++pSourceByte; |
|
867 } |
|
868 else if ((sourceByte&0xe0)==0xc0) |
|
869 { |
|
870 ++pSourceByte; |
|
871 const TUint secondSourceByte=*pSourceByte; |
|
872 if ((secondSourceByte&0xc0)!=0x80) |
|
873 { |
|
874 Print(EError, "Bad UTF-8 '%s'", iName); |
|
875 exit(671); |
|
876 } |
|
877 len += 2; |
|
878 ++pSourceByte; |
|
879 } |
|
880 else if ((sourceByte&0xf0)==0xe0) |
|
881 { |
|
882 ++pSourceByte; |
|
883 const TUint secondSourceByte=*pSourceByte; |
|
884 if ((secondSourceByte&0xc0)!=0x80) |
|
885 { |
|
886 Print(EError, "Bad UTF-8 '%s'", iName); |
|
887 exit(672); |
|
888 } |
|
889 ++pSourceByte; |
|
890 const TUint thirdSourceByte=*pSourceByte; |
|
891 if ((thirdSourceByte&0xc0)!=0x80) |
|
892 { |
|
893 Print(EError, "Bad UTF-8 '%s'", iName); |
|
894 exit(673); |
|
895 } |
|
896 len += 2; |
|
897 ++pSourceByte; |
|
898 } |
|
899 else |
|
900 { |
|
901 Print(EError, "Bad UTF-8 '%s'", iName); |
|
902 exit(674); |
|
903 } |
|
904 } |
|
905 return len; |
|
906 } |
|
907 |
|
908 |
|
909 void TRomNode::AddNodeForSameFile(TRomNode* aPreviousNode, TRomBuilderEntry* aFile) |
764 void TRomNode::AddNodeForSameFile(TRomNode* aPreviousNode, TRomBuilderEntry* aFile) |
910 { |
765 { |
911 // sanity checking |
766 // sanity checking |
912 if (iNextNodeForSameFile != 0 || iEntry != aFile || (aPreviousNode && aPreviousNode->iEntry != iEntry)) |
767 if (iNextNodeForSameFile != 0 || iEntry != aFile || (aPreviousNode && aPreviousNode->iEntry != iEntry)) |
913 { |
768 { |
924 //************************************** |
779 //************************************** |
925 // TRomBuilderEntry |
780 // TRomBuilderEntry |
926 //************************************** |
781 //************************************** |
927 |
782 |
928 |
783 |
929 |
|
930 TRomBuilderEntry::TRomBuilderEntry(const char *aFileName,TText *aName) |
|
931 // |
784 // |
932 // Constructor |
785 // Constructor |
933 // |
786 // |
934 :iFirstDllDataEntry(0), iName(0),iFileName(0),iNext(0), iNextInArea(0), |
787 TRomBuilderEntry::TRomBuilderEntry(const char *aFileName,const char *aName): |
|
788 iFirstDllDataEntry(0), iName(0),iFileName(0),iNext(0), iNextInArea(0), |
935 iExecutable(EFalse), iFileOffset(EFalse), iCompressEnabled(0), |
789 iExecutable(EFalse), iFileOffset(EFalse), iCompressEnabled(0), |
936 iHidden(0), iRomNode(0), iRealFileSize(0) |
790 iHidden(0), iRomNode(0), iRealFileSize(0) |
937 { |
791 { |
938 if (aFileName) |
792 if (aFileName) |
939 iFileName = NormaliseFileName(aFileName); |
793 iFileName = NormaliseFileName(aFileName); |
940 if (aName) |
794 if (aName) |
941 iName = (TText*)NormaliseFileName((const char*)aName); |
795 iName = NormaliseFileName(aName); |
942 memset(iUids,0 ,sizeof(TCheckedUid)); |
796 memset(iUids,0 ,sizeof(TCheckedUid)); |
943 } |
797 } |
|
798 // |
|
799 // Destructor |
|
800 // |
|
801 TRomBuilderEntry::~TRomBuilderEntry() { |
|
802 if(iFileName) { |
|
803 delete []iFileName; |
|
804 iFileName = 0; |
|
805 } |
944 |
806 |
945 TRomBuilderEntry::~TRomBuilderEntry() |
807 if(iName) { |
946 // |
808 delete []iName; |
947 // Destructor |
809 iName = 0 ; |
948 // |
810 } |
949 { |
811 } |
950 if(iFileName) |
|
951 { |
|
952 free(iFileName); |
|
953 } |
|
954 iFileName = 0; |
|
955 if(iName) |
|
956 { |
|
957 free(iName); |
|
958 } |
|
959 } |
|
960 |
812 |
961 void TRomBuilderEntry::SetRomNode(TRomNode* aNode) |
813 void TRomBuilderEntry::SetRomNode(TRomNode* aNode) |
962 { |
814 { |
963 aNode->AddNodeForSameFile(iRomNode, this); |
815 aNode->AddNodeForSameFile(iRomNode, this); |
964 iRomNode = aNode; |
816 iRomNode = aNode; |
965 } |
817 } |
966 |
818 |
967 |
819 // |
968 TInt isNumber(TText *aString) |
820 // Place the file in ROFS. Since we don't support compression yet all |
969 { |
821 // we have to do is read the file into memory |
970 if (aString==NULL) |
822 // compress it, if it isn't already compressed. |
971 return 0; |
823 // |
972 if (strlen((char *)aString)==0) |
824 // Returns the number of bytes used, or -ve error code |
973 return 0; |
825 TInt TRomBuilderEntry::PlaceFile( TUint8* &aDest,TUint aMaxSize, CBytePair *aBPE ){ |
974 return isdigit(aString[0]); |
826 |
975 } |
827 |
976 |
|
977 TInt getNumber(TText *aStr) |
|
978 { |
|
979 TUint a; |
|
980 #ifdef __TOOLS2__ |
|
981 istringstream val((char *)aStr); |
|
982 #else |
|
983 istrstream val((char *)aStr,strlen((char *)aStr)); |
|
984 #endif |
|
985 |
|
986 #if defined(__MSVCDOTNET__) || defined(__TOOLS2__) |
|
987 val >> setbase(0); |
|
988 #endif //__MSVCDOTNET__ |
|
989 |
|
990 val >> a; |
|
991 return a; |
|
992 } |
|
993 |
|
994 |
|
995 TInt TRomBuilderEntry::PlaceFile( TUint8* &aDest,TUint aMaxSize, CBytePair *aBPE ) |
|
996 // |
|
997 // Place the file in ROM. Since we don't support compression yet all |
|
998 // we have to do is read the file into memory |
|
999 // compress it, if it isn't already compressed. |
|
1000 // |
|
1001 // Returns the number of bytes used, or -ve error code |
|
1002 { |
|
1003 TUint compression = 0; |
828 TUint compression = 0; |
1004 TBool executable = iExecutable; |
829 TBool executable = iExecutable; |
1005 Print(ELog,"Reading file %s to image\n", iFileName ); |
830 Print(ELog,"Reading file %s to image\n", iFileName ); |
1006 TUint32 size=HFile::GetLength((TText*)iFileName); |
831 TUint32 size = HFile::GetLength(iFileName); |
1007 if (size==0) |
832 if (size==0) |
1008 Print(EWarning, "File %s does not exist or is 0 bytes in length.\n",iFileName); |
833 Print(EWarning, "File %s does not exist or is 0 bytes in length.\n",iFileName); |
1009 if (aDest == NULL) { |
834 if (aDest == NULL) { |
1010 aMaxSize = size*2; |
835 aMaxSize = size << 1; |
1011 aMaxSize = (aMaxSize>0) ? aMaxSize : 2; |
836 aMaxSize = (aMaxSize>0) ? aMaxSize : 2; |
1012 aDest = new TUint8[aMaxSize]; |
837 aDest = new TUint8[aMaxSize]; |
1013 } |
838 } |
1014 |
839 |
1015 if (executable) |
840 if (executable) |
1016 { |
841 { |
1017 // indicate if the image will overflow without compression |
842 // indicate if the image will overflow without compression |
1018 TBool overflow; |
843 TBool overflow; |
1019 if(size>aMaxSize) |
844 if(size>aMaxSize) |
1020 overflow = ETrue; |
845 overflow = ETrue; |
1021 else |
846 else |
1022 overflow = EFalse; |
847 overflow = EFalse; |
1023 |
848 |
1024 // try to compress this executable |
849 // try to compress this executable |
1025 E32ImageFile f(aBPE); |
850 E32ImageFile f(aBPE); |
1026 TInt r = f.Open(iFileName); |
851 TInt r = f.Open(iFileName); |
1027 // is it really a valid E32ImageFile? |
852 // is it really a valid E32ImageFile? |
1028 if (r != KErrNone) |
853 if (r != KErrNone) |
1029 { |
854 { |
1030 Print(EWarning, "File '%s' is not a valid executable. Placing file as data.\n", iFileName); |
855 Print(EWarning, "File '%s' is not a valid executable. Placing file as data.\n", iFileName); |
1031 executable = EFalse; |
856 executable = EFalse; |
1032 } |
857 } |
1033 else |
858 else |
1034 { |
859 { |
1035 |
860 |
1036 if(iRomNode->iOverride & KOverrideDllData) |
861 if(iRomNode->iOverride & KOverrideDllData) |
1037 { |
862 { |
1038 DllDataEntry *aDllEntry = iRomNode->iEntry->GetFirstDllDataEntry(); |
863 DllDataEntry *aDllEntry = iRomNode->iEntry->GetFirstDllDataEntry(); |
1039 TLinAddr* aExportTbl; |
864 TLinAddr* aExportTbl; |
1041 TUint aDataAddr; |
866 TUint aDataAddr; |
1042 char *aCodeSeg, *aDataSeg; |
867 char *aCodeSeg, *aDataSeg; |
1043 |
868 |
1044 aExportTbl = (TLinAddr*)((char*)f.iData + f.iOrigHdr->iExportDirOffset); |
869 aExportTbl = (TLinAddr*)((char*)f.iData + f.iOrigHdr->iExportDirOffset); |
1045 |
870 |
1046 // const data symbol may belong in the Code section. If the address lies within the Code or data section limits, |
871 // const data symbol may belong in the Code section. If the address lies within the Code or data section limits, |
1047 // get the corresponding location and update it.While considering the Data section limits |
872 // get the corresponding location and update it.While considering the Data section limits |
1048 // don't include the Bss section, as it doesn't exist as yet in the image. |
873 // don't include the Bss section, as it doesn't exist as yet in the image. |
1049 while( aDllEntry ){ |
874 while( aDllEntry ){ |
1050 if(aDllEntry->iOrdinal != (TUint32)-1){ |
875 if(aDllEntry->iOrdinal != (TUint32)-1){ |
1051 if(aDllEntry->iOrdinal < 1 || aDllEntry->iOrdinal > (TUint)f.iOrigHdr->iExportDirCount){ |
876 if(aDllEntry->iOrdinal < 1 || aDllEntry->iOrdinal > (TUint)f.iOrigHdr->iExportDirCount){ |
1052 Print(EWarning, "Invalid ordinal %d specified for DLL %s\n", aDllEntry->iOrdinal, iRomNode->iName); |
877 Print(EWarning, "Invalid ordinal %d specified for DLL %s\n", aDllEntry->iOrdinal, iRomNode->iName); |
1053 aDllEntry = aDllEntry->NextDllDataEntry(); |
878 aDllEntry = aDllEntry->NextDllDataEntry(); |
1054 continue; |
879 continue; |
1055 } |
880 } |
1056 |
881 |
1057 // Get the address of the data field via the export table. |
882 // Get the address of the data field via the export table. |
1058 aDataAddr = (TInt32)(aExportTbl[aDllEntry->iOrdinal - 1] + aDllEntry->iOffset); |
883 aDataAddr = (TInt32)(aExportTbl[aDllEntry->iOrdinal - 1] + aDllEntry->iOffset); |
1059 if( aDataAddr >= f.iOrigHdr->iCodeBase && aDataAddr <= (f.iOrigHdr->iCodeBase + f.iOrigHdr->iCodeSize)){ |
884 if( aDataAddr >= f.iOrigHdr->iCodeBase && aDataAddr <= (f.iOrigHdr->iCodeBase + f.iOrigHdr->iCodeSize)){ |
1060 aCodeSeg = (char*)(f.iData + f.iOrigHdr->iCodeOffset); |
885 aCodeSeg = (char*)(f.iData + f.iOrigHdr->iCodeOffset); |
1061 aLocation = (void*)(aCodeSeg + aDataAddr - f.iOrigHdr->iCodeBase ); |
886 aLocation = (void*)(aCodeSeg + aDataAddr - f.iOrigHdr->iCodeBase ); |
1062 memcpy(aLocation, &aDllEntry->iNewValue, aDllEntry->iSize); |
887 memcpy(aLocation, &aDllEntry->iNewValue, aDllEntry->iSize); |
1063 } |
888 } |
1064 else if(aDataAddr >= f.iOrigHdr->iDataBase && aDataAddr <= (f.iOrigHdr->iDataBase + f.iOrigHdr->iDataSize)){ |
889 else if(aDataAddr >= f.iOrigHdr->iDataBase && aDataAddr <= (f.iOrigHdr->iDataBase + f.iOrigHdr->iDataSize)){ |
1065 aDataSeg = (char*)(f.iData + f.iOrigHdr->iDataOffset); |
890 aDataSeg = (char*)(f.iData + f.iOrigHdr->iDataOffset); |
1066 aLocation = (void*)(aDataSeg + aDataAddr - f.iOrigHdr->iDataBase ); |
891 aLocation = (void*)(aDataSeg + aDataAddr - f.iOrigHdr->iDataBase ); |
1067 memcpy(aLocation, &aDllEntry->iNewValue, aDllEntry->iSize); |
892 memcpy(aLocation, &aDllEntry->iNewValue, aDllEntry->iSize); |
1068 } |
893 } |
1069 else |
894 else |
1070 { |
895 { |
1071 Print(EWarning, "Patchdata failed as address pointed by ordinal %d of DLL %s doesn't lie within Code or Data section limits\n", aDllEntry->iOrdinal, iRomNode->iName); |
896 Print(EWarning, "Patchdata failed as address pointed by ordinal %d of DLL %s doesn't lie within Code or Data section limits\n", aDllEntry->iOrdinal, iRomNode->iName); |
1072 } |
897 } |
1073 } |
898 } |
1074 else if(aDllEntry->iDataAddress != (TLinAddr)-1){ |
899 else if(aDllEntry->iDataAddress != (TLinAddr)-1){ |
1075 aDataAddr = aDllEntry->iDataAddress + aDllEntry->iOffset; |
900 aDataAddr = aDllEntry->iDataAddress + aDllEntry->iOffset; |
1076 if( aDataAddr >= f.iOrigHdr->iCodeBase && aDataAddr <= (f.iOrigHdr->iCodeBase + f.iOrigHdr->iCodeSize)){ |
901 if( aDataAddr >= f.iOrigHdr->iCodeBase && aDataAddr <= (f.iOrigHdr->iCodeBase + f.iOrigHdr->iCodeSize)){ |
1077 aCodeSeg = (char*)(f.iData + f.iOrigHdr->iCodeOffset); |
902 aCodeSeg = (char*)(f.iData + f.iOrigHdr->iCodeOffset); |
1078 aLocation = (void*)(aCodeSeg + aDataAddr - f.iOrigHdr->iCodeBase ); |
903 aLocation = (void*)(aCodeSeg + aDataAddr - f.iOrigHdr->iCodeBase ); |
1079 memcpy(aLocation, &aDllEntry->iNewValue, aDllEntry->iSize); |
904 memcpy(aLocation, &aDllEntry->iNewValue, aDllEntry->iSize); |
1080 } |
905 } |
1081 else if(aDataAddr >= f.iOrigHdr->iDataBase && aDataAddr <= (f.iOrigHdr->iDataBase + f.iOrigHdr->iDataSize)){ |
906 else if(aDataAddr >= f.iOrigHdr->iDataBase && aDataAddr <= (f.iOrigHdr->iDataBase + f.iOrigHdr->iDataSize)){ |
1082 aDataSeg = (char*)(f.iData + f.iOrigHdr->iDataOffset); |
907 aDataSeg = (char*)(f.iData + f.iOrigHdr->iDataOffset); |
1083 aLocation = (void*)(aDataSeg + aDataAddr - f.iOrigHdr->iDataBase ); |
908 aLocation = (void*)(aDataSeg + aDataAddr - f.iOrigHdr->iDataBase ); |
1084 memcpy(aLocation, &aDllEntry->iNewValue, aDllEntry->iSize); |
909 memcpy(aLocation, &aDllEntry->iNewValue, aDllEntry->iSize); |
1085 } |
910 } |
1086 else |
911 else |
1087 { |
912 { |
1088 Print(EWarning, "Patchdata failed as address 0x%x of DLL %s doesn't lie within Code or Data section limits\n", aDllEntry->iOrdinal, iRomNode->iName); |
913 Print(EWarning, "Patchdata failed as address 0x%x of DLL %s doesn't lie within Code or Data section limits\n", aDllEntry->iOrdinal, iRomNode->iName); |
1089 } |
914 } |
1090 } |
915 } |
1091 aDllEntry = aDllEntry->NextDllDataEntry(); |
916 aDllEntry = aDllEntry->NextDllDataEntry(); |
1092 } |
917 } |
1093 } |
918 } |
1094 |
919 |
1095 compression = f.iHdr->CompressionType(); |
920 compression = f.iHdr->CompressionType(); |
1096 Print(ELog,"Original file:'%s' is compressed by method:%08x\n", iFileName, compression); |
921 Print(ELog,"Original file:'%s' is compressed by method:%08x\n", iFileName, compression); |
1097 |
922 |
1189 break; |
1014 break; |
1190 case EKernelConfigPagingPolicyDefaultPaged: |
1015 case EKernelConfigPagingPolicyDefaultPaged: |
1191 if(!(h->iFlags&(KImageDataUnpaged|KImageDataPaged))) |
1016 if(!(h->iFlags&(KImageDataUnpaged|KImageDataPaged))) |
1192 h->iFlags |= KImageDataPaged; |
1017 h->iFlags |= KImageDataPaged; |
1193 break; |
1018 break; |
1194 } |
1019 } |
1195 f.UpdateHeaderCrc(); |
1020 f.UpdateHeaderCrc(); |
1196 |
1021 |
1197 // make sure paged code has correct compression type... |
1022 // make sure paged code has correct compression type... |
1198 if(h->iFlags&KImageCodePaged) |
1023 if(h->iFlags&KImageCodePaged) |
1199 { |
1024 { |
1200 if(newFileComp!=0) |
1025 if(newFileComp!=0) |
1201 newFileComp = KUidCompressionBytePair; |
1026 newFileComp = KUidCompressionBytePair; |
1202 } |
1027 } |
1203 } |
1028 } |
1204 |
1029 |
1205 if ( oldFileComp != newFileComp ) |
1030 if ( oldFileComp != newFileComp ) |
1206 { |
1031 { |
1207 |
1032 |
1208 if( newFileComp == 0) |
1033 if( newFileComp == 0) |
1209 { |
1034 { |
1210 Print(ELog,"Decompressing executable '%s'\n", iFileName); |
1035 Print(ELog,"Decompressing executable '%s'\n", iFileName); |
1211 f.iHdr->iCompressionType = 0; |
1036 f.iHdr->iCompressionType = 0; |
1212 } |
1037 } |
1213 else |
1038 else |
1214 { |
1039 { |
1215 Print(ELog,"Compressing executable '%s' with method:%08x\n", iFileName, newFileComp); |
1040 Print(ELog,"Compressing executable '%s' with method:%08x\n", iFileName, newFileComp); |
1216 f.iHdr->iCompressionType = newFileComp; |
1041 f.iHdr->iCompressionType = newFileComp; |
1217 } |
1042 } |
1218 f.UpdateHeaderCrc(); |
1043 f.UpdateHeaderCrc(); |
1219 if (overflow) |
1044 if (overflow) |
1220 { |
1045 { |
|
1046 // need to check if the compressed file will fit in the image |
|
1047 //TODO the checking will slow down the build process, should do it later along with the writing on aDest. |
|
1048 TUint32 compressedSize; |
1221 char * buffer = new char [size]; |
1049 char * buffer = new char [size]; |
1222 // need to check if the compressed file will fit in the image |
1050 #if defined(__LINUX__) |
1223 #if defined(__LINUX__) |
1051 ostrstream os((char*)aDest, aMaxSize, (ios_base::openmode)(ios_base::out+ios_base::binary)); |
1224 ostrstream os((char*)aDest, aMaxSize, (ios::openmode)(ios::out+ios::binary)); |
1052 #elif defined(__TOOLS2__) && defined (_STLP_THREADS) |
1225 #elif defined(__TOOLS2__) && defined (_STLP_THREADS) |
1053 ostrstream os((char*)buffer, size,(ios_base::out+ios_base::binary)); |
1226 ostrstream os((char*)buffer, size,(ios::out+ios::binary)); |
1054 #elif defined( __TOOLS2__) |
1227 #elif defined( __TOOLS2__) |
1055 ostrstream os((char*)buffer, size,(ios_base::out+ios_base::binary)); |
1228 ostrstream os((char*)buffer, size,(ios::out+ios::binary)); |
1056 #else |
1229 #else |
1057 ostrstream os( (char*)buffer, size, (ios_base::out+ios_base::binary)); |
1230 ostrstream os( (char*)buffer, size, (ios::out+ios::binary)); |
1058 #endif |
1231 #endif |
|
1232 os << f; |
1059 os << f; |
1233 TUint compressedSize = os.pcount(); |
1060 compressedSize = os.pcount(); |
|
1061 delete[] buffer; |
1234 if (compressedSize <= aMaxSize) |
1062 if (compressedSize <= aMaxSize) |
1235 overflow = EFalse; |
1063 overflow = EFalse; |
1236 delete[] buffer; |
1064 } |
1237 } |
1065 } |
1238 } |
|
1239 if (overflow) |
1066 if (overflow) |
1240 { |
1067 { |
1241 Print(EError, "Can't fit '%s' in image\n", iFileName); |
1068 Print(EError, "Can't fit '%s' in image\n", iFileName); |
1242 Print(EError, "Overflowed by approximately 0x%x bytes.\n", size - aMaxSize); |
1069 Print(EError, "Overflowed by approximately 0x%x bytes.\n", size - aMaxSize); |
1243 exit(667); |
1070 exit(667); |
1244 } |
1071 } |
1245 #if defined(__TOOLS2__) && defined (_STLP_THREADS) |
1072 |
1246 ostrstream os((char*)aDest, aMaxSize,(ios::out+ios::binary)); |
1073 //try to use cached version where possible. |
1247 #elif __TOOLS2__ |
1074 if(gCache && !gDriveImage && !(iRomNode->iAlias) && (iRomNode->iEntry->iExecutable) && !(iRomNode->iOverride & KOverrideDllData)) |
1248 ostrstream os((char*)aDest, aMaxSize, (std::_Ios_Openmode)(ios::out+ios::binary)); |
1075 { |
1249 #else |
1076 //retrive cached version. |
1250 ostrstream os((char*)aDest, aMaxSize, (ios::out+ios::binary)); |
1077 size_t len = strlen(iFileName) + 1; |
1251 #endif |
1078 char* temp = (char*)_alloca(len); |
|
1079 memcpy(temp,iFileName,len); |
|
1080 CacheEntry* entryref = CacheManager::GetInstance()->GetE32ImageFileRepresentation(temp , compression); |
|
1081 if(entryref) |
|
1082 { |
|
1083 size = entryref->GetCachedFileBufferLen(); |
|
1084 memcpy(aDest, entryref->GetCachedFileBuffer(), size); |
|
1085 memcpy(aDest,f.iHdr,sizeof(E32ImageHeaderV)); |
|
1086 compression = atoi(entryref->GetCachedFileCompressionID()); |
|
1087 memcpy(&iUids[0], aDest, sizeof(iUids)); |
|
1088 if (compression) |
|
1089 Print(ELog,"Compressed executable File '%s' size: %08x, mode:%08x\n", iFileName, size, compression); |
|
1090 else if (iExecutable) |
|
1091 Print(ELog,"Executable File '%s' size: %08x\n", iFileName, size); |
|
1092 else |
|
1093 Print(ELog,"File '%s' size: %08x\n", iFileName, size); |
|
1094 iRealFileSize = size; // required later when directory is written |
|
1095 |
|
1096 return size; |
|
1097 } |
|
1098 } |
|
1099 |
|
1100 #if defined(__TOOLS2__) && defined (_STLP_THREADS) |
|
1101 ostrstream os((char*)aDest, aMaxSize,(ios_base::out+ios_base::binary)); |
|
1102 #elif __TOOLS2__ |
|
1103 ostrstream os((char*)aDest, aMaxSize, (_Ios_Openmode)(ios_base::out+ios_base::binary)); |
|
1104 #else |
|
1105 ostrstream os((char*)aDest, aMaxSize, (ios_base::out+ios_base::binary)); |
|
1106 #endif |
1252 os << f; |
1107 os << f; |
1253 size = os.pcount(); |
1108 size = os.pcount(); |
|
1109 |
|
1110 //save the decompressed/recompressed executable into the cache if it's enabled. |
|
1111 if(gCache && !gDriveImage && !(iRomNode->iAlias) && (iRomNode->iEntry->iExecutable) && !(iRomNode->iOverride & KOverrideDllData)) |
|
1112 { |
|
1113 CacheEntry* newentryref = new (nothrow) CacheEntry(); |
|
1114 if(newentryref) |
|
1115 { |
|
1116 boost::filesystem::path originalfilepath(iFileName); |
|
1117 time_t originalcreationtime = last_write_time(originalfilepath); |
|
1118 newentryref->SetOriginalFileCreateTime(&originalcreationtime); |
|
1119 newentryref->SetOriginalFileCompression(f.iHdr->CompressionType()); |
|
1120 size_t len = strlen(iFileName) + 1; |
|
1121 char* originalfilename = (char*)_alloca(len); |
|
1122 memcpy(originalfilename,iFileName,len); |
|
1123 CacheManager::GetInstance()->NormalizeFilename(originalfilename); |
|
1124 newentryref->SetOriginalFilename(originalfilename); |
|
1125 newentryref->SetCachedFileCompression(compression); |
|
1126 string cachedfilename(".rofs."); |
|
1127 cachedfilename += newentryref->GetCachedFileCompressionID(); |
|
1128 cachedfilename += "."; |
|
1129 cachedfilename += iFileName; |
|
1130 size_t slashpos; |
|
1131 while(((slashpos=cachedfilename.find("/"))!=string::npos) || ((slashpos=cachedfilename.find("\\"))!=string::npos)) |
|
1132 cachedfilename.replace(slashpos, 1, 1, '.'); |
|
1133 cachedfilename.insert(0, "/"); |
|
1134 cachedfilename.insert(0, CacheManager::GetInstance()->GetCacheRoot()); |
|
1135 newentryref->SetCachedFilename(cachedfilename.c_str()); |
|
1136 newentryref->SetCachedFileBuffer((char*)aDest, size); |
|
1137 try |
|
1138 { |
|
1139 size_t len = strlen(iFileName) + 1; |
|
1140 char* temp = (char*)_alloca(len); |
|
1141 memcpy(temp,iFileName,len); |
|
1142 CacheManager::GetInstance()->Invalidate(temp, newentryref); |
|
1143 } |
|
1144 catch (CacheException ce) |
|
1145 { |
|
1146 Print(EWarning, "Cache brings up an exception (%s) when processes %s\r\n", ce.GetErrorMessage(), iFileName); |
|
1147 } |
|
1148 } |
|
1149 } |
|
1150 |
1254 compression = f.iHdr->CompressionType(); |
1151 compression = f.iHdr->CompressionType(); |
1255 memcpy(&iUids[0], aDest, sizeof(iUids)); |
1152 memcpy(&iUids[0], aDest, sizeof(iUids)); |
1256 } |
1153 } |
1257 } |
1154 } |
1258 if (!executable) |
1155 if (!executable) |
1259 { |
1156 { |
1260 if ( size > aMaxSize ) |
1157 if ( size > aMaxSize ) |
1261 { |
1158 { |
1262 Print(EError, "Can't fit '%s' in image\n", iFileName); |
1159 Print(EError, "Can't fit '%s' in image\n", iFileName); |
1263 Print(EError, "Overflowed by approximately 0x%x bytes.\n", size - aMaxSize); |
1160 Print(EError, "Overflowed by approximately 0x%x bytes.\n", size - aMaxSize); |
1264 exit(667); |
1161 exit(667); |
1265 } |
1162 } |
1266 size = HFile::Read((TText*)iFileName, (TAny *)aDest); |
1163 size = HFile::Read(iFileName, (TAny *)aDest); |
1267 TUint32 Uidslen = (size > sizeof(iUids)) ? sizeof(iUids) : size; |
1164 TUint32 Uidslen = (size > sizeof(iUids)) ? sizeof(iUids) : size; |
1268 memcpy(&iUids[0], aDest, Uidslen); |
1165 memcpy(&iUids[0], aDest, Uidslen); |
1269 } |
1166 } |
1270 |
1167 |
1271 if (compression) |
1168 if (compression) |
1272 Print(ELog,"Compressed executable File '%s' size: %08x, mode:%08x\n", iFileName, size, compression); |
1169 Print(ELog,"Compressed executable File '%s' size: %08x, mode:%08x\n", iFileName, size, compression); |
1273 else if (iExecutable) |
1170 else if (iExecutable) |
1274 Print(ELog,"Executable File '%s' size: %08x\n", iFileName, size); |
1171 Print(ELog,"Executable File '%s' size: %08x\n", iFileName, size); |
1275 else |
1172 else |
1276 Print(ELog,"File '%s' size: %08x\n", iFileName, size); |
1173 Print(ELog,"File '%s' size: %08x\n", iFileName, size); |
|
1174 iCompressEnabled = compression; |
1277 iRealFileSize = size; // required later when directory is written |
1175 iRealFileSize = size; // required later when directory is written |
1278 |
1176 |
1279 return size; |
1177 return size; |
1280 } |
1178 } |
1281 |
1179 |
1282 |
1180 |
1283 TRomNode* TRomNode::CopyDirectory(TRomNode*& aLastExecutable) |
1181 TRomNode* TRomNode::CopyDirectory(TRomNode*& aLastExecutable) |
1284 { |
1182 { |
1285 |
1183 |