imgtools/romtools/rombuild/r_build.cpp
changeset 590 360bd6b35136
parent 0 044383f39525
child 626 ac03b93ca9c4
equal deleted inserted replaced
588:c7c26511138f 590:360bd6b35136
    28 #include <f32file.h>
    28 #include <f32file.h>
    29 #include "h_utl.h"
    29 #include "h_utl.h"
    30 
    30 
    31 #define USE_IAT_FOR_IMPORTS (iOverrideFlags&KOverrideKeepIAT || (iHdr->iCpuIdentifier & 0x1000))
    31 #define USE_IAT_FOR_IMPORTS (iOverrideFlags&KOverrideKeepIAT || (iHdr->iCpuIdentifier & 0x1000))
    32 
    32 
    33 #if defined(__MSVCDOTNET__) || defined(__TOOLS2__)
    33 #include <iomanip> 
    34 #include <iomanip>
       
    35 #else //!__MSVCDOTNET__
       
    36 #include <iomanip.h>
       
    37 #endif
       
    38 
       
    39 #if defined(__MSVCDOTNET__) || defined(__TOOLS2__)
       
    40 #include <iomanip>
       
    41 #else //!__MSVCDOTNET__
       
    42 #include <iomanip.h>
       
    43 #endif
       
    44 
       
    45 #include "r_obey.h"
    34 #include "r_obey.h"
    46 #include "r_global.h"
    35 #include "r_global.h"
    47 #include "r_dir.h"
    36 #include "r_dir.h"
    48 
    37 
    49 TInt NumRootDirs;
    38 TInt NumRootDirs;
    50 
    39 
    51 inline TLinAddr ActualToRomAddress(TAny* anAddr)
    40 inline TLinAddr ActualToRomAddress(TAny* anAddr) { 
    52 	{ return TLinAddr(anAddr)-TheRomMem+TheRomLinearAddress; }
    41 	return TLinAddr(anAddr)-TheRomMem+TheRomLinearAddress; 
    53 
    42 }
    54 TBool THardwareVariant::MutuallyExclusive(THardwareVariant a) const
    43 
    55 	{
    44 TBool THardwareVariant::MutuallyExclusive(THardwareVariant a) const {
    56 	if (Layer()<=3 || a.Layer()<=3)
    45 	if (Layer()<=3 || a.Layer()<=3)
    57 		return EFalse;
    46 		return EFalse;
    58 	if (Parent()==3 && a.Parent()==3)
    47 	if (Parent()==3 && a.Parent()==3)
    59 		return(Layer()!=a.Layer());
    48 		return(Layer()!=a.Layer());
    60 	if (Parent()==3 && a.Parent()!=Layer())
    49 	if (Parent()==3 && a.Parent()!=Layer())
    62 	if (a.Parent()==3 && Parent()!=a.Layer())
    51 	if (a.Parent()==3 && Parent()!=a.Layer())
    63 		return ETrue;
    52 		return ETrue;
    64 	if (Layer()!=a.Layer())
    53 	if (Layer()!=a.Layer())
    65 		return ETrue;
    54 		return ETrue;
    66 	return((VMask()&a.VMask())==0);
    55 	return((VMask()&a.VMask())==0);
    67 	}
    56 }
    68 
    57 
    69 TBool THardwareVariant::IsVariant() const
    58 TBool THardwareVariant::IsVariant() const {
    70 	{
       
    71 	if (Layer()<=3 || Parent()==3)
    59 	if (Layer()<=3 || Parent()==3)
    72 		return EFalse;
    60 		return EFalse;
    73 	TUint v=VMask();
    61 	TUint v=VMask();
    74 	TInt i;
    62 	TInt i;
    75 	for (i=0; i<16; i++)
    63 	for (i=0; i<16; i++) {
    76 		{
       
    77 		if (v==TUint(1<<i))
    64 		if (v==TUint(1<<i))
    78 			return ETrue;
    65 			return ETrue;
    79 		}
    66 	}
    80 	return EFalse;
    67 	return EFalse;
    81 	}
    68 }
    82 
    69 
    83 TInt THardwareVariant::Compare(THardwareVariant a) const
    70 TInt THardwareVariant::Compare(THardwareVariant a) const {
    84 	{
       
    85 	TUint l1=Layer();
    71 	TUint l1=Layer();
    86 	TUint p1=Parent();
    72 	TUint p1=Parent();
    87 	TUint v1=VMask();
    73 	TUint v1=VMask();
    88 	TUint l2=a.Layer();
    74 	TUint l2=a.Layer();
    89 	TUint p2=a.Parent();
    75 	TUint p2=a.Parent();
    90 	TUint v2=a.VMask();
    76 	TUint v2=a.VMask();
    91 
    77 
    92 	if (l1<=3)
    78 	if (l1<=3) {
    93 		{
    79 		if (l2<=3) {
    94 		if (l2<=3)
       
    95 			{
       
    96 			return EEqual;
    80 			return EEqual;
    97 			}
    81 		}
    98 		return EGreater;
    82 		return EGreater;
    99 		}
    83 	}
   100 	if (l2<=3)
    84 	if (l2<=3)
   101 		return ELess;
    85 		return ELess;
   102 	if (p1==3)
    86 	if (p1==3) {
   103 		{
    87 		if (p2==3) {
   104 		if (p2==3)
       
   105 			{
       
   106 			if (l1==l2)
    88 			if (l1==l2)
   107 				return EEqual;
    89 				return EEqual;
   108 			return EUnordered;
    90 			return EUnordered;
   109 			}
    91 		}
   110 		if (p2==l1)
    92 		if (p2==l1)
   111 			return EGreater;
    93 			return EGreater;
   112 		return EUnordered;
    94 		return EUnordered;
   113 		}
    95 	}
   114 	if (p2==3)
    96 	if (p2==3) {
   115 		{
       
   116 		if (p1==l2)
    97 		if (p1==l2)
   117 			return ELess;
    98 			return ELess;
   118 		return EUnordered;
    99 		return EUnordered;
   119 		}
   100 	}
   120 	if (l1!=l2)
   101 	if (l1!=l2)
   121 		return EUnordered;
   102 		return EUnordered;
   122 	if ((v1&v2)==v1)
   103 	if ((v1&v2)==v1)
   123 		return ELess;
   104 		return ELess;
   124 	if ((v1&v2)==v2)
   105 	if ((v1&v2)==v2)
   125 		return EGreater;
   106 		return EGreater;
   126 	return EUnordered;
   107 	return EUnordered;
   127 	}
   108 }
   128 //
   109 //
   129 TInt TRomNode::Count=0;
   110 TInt TRomNode::Count=0;
   130 TRomNode::TRomNode(const TText* aName, TRomBuilderEntry* aEntry)
   111 
   131 //
   112 //
   132 // Constructor from TRomBuilderEntry, i.e. for new file or directory
   113 // Constructor from TRomBuilderEntry, i.e. for new file or directory
   133 //
   114 //
   134 	{
   115 TRomNode::TRomNode(const char* aName, TRomBuilderEntry* aEntry) {
   135 	memset(this, 0, sizeof(TRomNode));
   116 	memset(this, 0, sizeof(TRomNode));
   136 	iAtt = (TUint8)KEntryAttReadOnly;
   117 	iAtt = (TUint8)KEntryAttReadOnly;
   137 	iName = (TText*)NormaliseFileName((const char*)aName);
   118 	iName = NormaliseFileName(aName);
   138 	iIdentifier=TRomNode::Count++;
   119 	iIdentifier=TRomNode::Count++;
   139 	iRomFile = new TRomFile;
   120 	iRomFile = new TRomFile;
   140 	if (aEntry)
   121 
   141 		{
   122 	if (aEntry) {
   142 		iRomFile->iRbEntry = aEntry;
   123 		iRomFile->iRbEntry = aEntry;
   143 		aEntry->SetRomNode(this);
   124 		aEntry->SetRomNode(this);
   144 		iBareName = strdup(aEntry->iBareName);
   125 		size_t len = strlen(aEntry->iBareName) + 1;
       
   126 		iBareName = new char[len];
       
   127 		memcpy(iBareName,aEntry->iBareName,len);
   145 		iRomFile->iHwvd = aEntry->iHardwareVariant;
   128 		iRomFile->iHwvd = aEntry->iHardwareVariant;
   146 		}
   129 	}
   147 	else
   130 	else {
   148 		{
       
   149 		iRomFile->iDir = ETrue;
   131 		iRomFile->iDir = ETrue;
   150 		iAtt |= (TUint8)KEntryAttDir;
   132 		iAtt |= (TUint8)KEntryAttDir;
   151 		iBareName = strdup((const char*)iName);
   133 		size_t len = strlen(iName) + 1;
       
   134 		iBareName = new char[len];
       
   135 		memcpy(iBareName,iName,len);
   152 		iRomFile->iHwvd = KVariantIndependent;
   136 		iRomFile->iHwvd = KVariantIndependent;
   153 		}
   137 	}
   154 	TRACE(TROMNODE,Print(ELog, "TRomNode %d name %s bare %s att %02x romfile %08x\n", iIdentifier,
   138 	TRACE(TROMNODE,Print(ELog, "TRomNode %d name %s bare %s att %02x romfile %08x\n", iIdentifier,
   155 			iName, iBareName, iAtt, iRomFile));
   139 		iName, iBareName, iAtt, iRomFile));
   156 	}
   140 }
   157 
   141 
   158 TRomNode::TRomNode(const TText* aName, TRomNode* aNode)
       
   159 //
   142 //
   160 // Constructor from TRomNode, i.e. for aliased file
   143 // Constructor from TRomNode, i.e. for aliased file
   161 //
   144 //	
   162 	{
   145 TRomNode::TRomNode(const char* aName, TRomNode* aNode){
   163 	memset(this, 0, sizeof(TRomNode));
   146 	memset(this, 0, sizeof(TRomNode));
   164 	iAtt = aNode->iAtt;
   147 	iAtt = aNode->iAtt;
   165 	iIdentifier=TRomNode::Count++;
   148 	iIdentifier=TRomNode::Count++;
   166 	iName = (TText*)NormaliseFileName((const char*)aName);
   149 	iName = NormaliseFileName(aName);
   167 	iHidden = aNode->iHidden;
   150 	iHidden = aNode->iHidden;
   168 	iRomFile = aNode->iRomFile;
   151 	iRomFile = aNode->iRomFile;
   169 	if (iRomFile)
   152 	if (iRomFile) {
   170 		{
       
   171 		iRomFile->Open();
   153 		iRomFile->Open();
   172 		}
   154 	}
   173 	TRACE(TROMNODE,Print(ELog, "TRomNode %d DUP name %s romfile %08x\n", iIdentifier, iName, iRomFile));
   155 	TRACE(TROMNODE,Print(ELog, "TRomNode %d DUP name %s romfile %08x\n", iIdentifier, iName, iRomFile));
   174 	}
   156 }
   175 
       
   176 TRomNode::TRomNode(const TRomNode& aNode)
       
   177 //
   157 //
   178 // Copy constructor - only used in deep copy function
   158 // Copy constructor - only used in deep copy function
   179 //
   159 //
   180 	{
   160 TRomNode::TRomNode(const TRomNode& aNode) {
   181 	memset(this, 0, sizeof(TRomNode));
   161 	memset(this, 0, sizeof(TRomNode));
   182 	iAtt = aNode.iAtt;
   162 	iAtt = aNode.iAtt;
   183 	iIdentifier=TRomNode::Count++;
   163 	iIdentifier=TRomNode::Count++;
   184 	iName = (TText*)strdup((const char*)aNode.iName);
   164 	size_t len = strlen(aNode.iName) + 1;
   185 	iBareName = strdup(aNode.iBareName);
   165 	iName = new char[len];
       
   166 	memcpy(iName,aNode.iName,len);
       
   167 	len = strlen(aNode.iBareName) + 1;
       
   168 	iBareName = new char[len];
       
   169 	memcpy(iBareName,aNode.iBareName,len);
   186 	iHidden = aNode.iHidden;
   170 	iHidden = aNode.iHidden;
   187 	iRomFile = aNode.iRomFile;
   171 	iRomFile = aNode.iRomFile;
   188 	if (iRomFile)
   172 	if (iRomFile) {
   189 		{
       
   190 		iRomFile->Open();
   173 		iRomFile->Open();
   191 		}
   174 	}
   192 	TRACE(TROMNODE,Print(ELog, "TRomNode %d COPY name %s bare %s att %02x romfile %08x\n", iIdentifier,
   175 	TRACE(TROMNODE,Print(ELog, "TRomNode %d COPY name %s bare %s att %02x romfile %08x\n", iIdentifier,
   193 			iName, iBareName, iAtt, iRomFile));
   176 		iName, iBareName, iAtt, iRomFile));
   194 	}
   177 }
   195 
   178 
   196 TRomNode::~TRomNode()
   179 TRomNode::~TRomNode() {
   197 	{
   180 	if(iName) {
   198 	free(iName);
   181 		delete []iName;
   199 	free(iBareName);
   182 		iName = 0 ;
       
   183 	}
       
   184 	if(iBareName){
       
   185 		delete []iBareName;
       
   186 		iBareName = 0 ;
       
   187 	}
   200 	if (iRomFile)
   188 	if (iRomFile)
   201 		iRomFile->Close();
   189 		iRomFile->Close();
   202 	}
   190 }
   203 
       
   204 TRomNode* TRomNode::FindInDirectory(const TText* aName)
       
   205 //
   191 //
   206 // Check if the TRomNode for aName exists in aDir, and if so, return it.
   192 // Check if the TRomNode for aName exists in aDir, and if so, return it.
   207 //
   193 //
   208 	{
   194 TRomNode* TRomNode::FindInDirectory(const char* aName) {
   209 
   195 
   210 	TRomNode *entry=iChild; // first subdirectory or file
   196 	TRomNode *entry=iChild; // first subdirectory or file
   211 	while (entry)
   197 	while (entry){
   212 		{
   198 		if (!entry->iHidden && (stricmp(aName, entry->iName))==0) 
   213 		if (!entry->iHidden && (stricmp((const char *)aName, (const char *)entry->iName))==0) 
       
   214 			return entry;
   199 			return entry;
   215 		else
   200 		else
   216 			entry=entry->iSibling;
   201 			entry=entry->iSibling;
   217 		}
   202 	}
   218 	return 0;
   203 	return 0;
   219 	}
   204 }
   220 
       
   221 TRomNode* TRomNode::FindInDirectory(const TText* aName, THardwareVariant aVariant, TBool aPatchDataFlag)
       
   222 //
   205 //
   223 // Check for a file with same name and a compatible hardware variant
   206 // Check for a file with same name and a compatible hardware variant
   224 //
   207 //
   225 	{
   208 TRomNode* TRomNode::FindInDirectory(const char* aName, THardwareVariant aVariant, TBool aPatchDataFlag) {
   226 
       
   227 	TRomNode *entry=iChild; // first subdirectory or file
   209 	TRomNode *entry=iChild; // first subdirectory or file
   228 	while (entry)
   210 	while (entry) {
   229 		{
   211 		if (((!entry->iHidden)||aPatchDataFlag) && entry->iRomFile && 
   230 		if (((!entry->iHidden)||aPatchDataFlag) && entry->iRomFile && (stricmp((const char *)aName, (const char *)entry->iName))==0) 
   212 			(stricmp(aName, entry->iName))==0) 	{
   231 			{
   213 				if (!aVariant.MutuallyExclusive(entry->HardwareVariant()))
   232 			if (!aVariant.MutuallyExclusive(entry->HardwareVariant()))
   214 					return entry;
   233 				return entry;
   215 		}
   234 			}
       
   235 		entry=entry->iSibling;
   216 		entry=entry->iSibling;
   236 		}
   217 	}
   237 	return 0;
   218 	return 0;
   238 	}
   219 }
   239 
   220 
   240 void TRomNode::AddFile(TRomNode* aChild)
   221 void TRomNode::AddFile(TRomNode* aChild) {
   241 	{
   222 	if (!(iAtt & KEntryAttDir)) {
   242 	if (!(iAtt & KEntryAttDir))
       
   243 		{
       
   244 		Print(EError, "Adding subdirectory to a file!!!\n");
   223 		Print(EError, "Adding subdirectory to a file!!!\n");
   245 		return;
   224 		return;
   246 		}
   225 	}
   247 	Add(aChild);
   226 	Add(aChild);
   248 	}
   227 }
   249 
   228 
   250 TRomNode* TRomNode::NewSubDir(const TText* aName)
   229 TRomNode* TRomNode::NewSubDir(const char* aName) {
   251 	{
   230 	if (!(iAtt & KEntryAttDir)) {
   252 	if (!(iAtt & KEntryAttDir))
       
   253 		{
       
   254 		Print(EError, "Adding subdirectory to a file!!!\n");
   231 		Print(EError, "Adding subdirectory to a file!!!\n");
   255 		return 0;
   232 		return 0;
   256 		}
   233 	}
   257 
   234 
   258 	TRomNode* node = new TRomNode(aName);
   235 	TRomNode* node = new TRomNode(aName);
   259 	if (node==0)
   236 	if (node==0) {
   260 		{
       
   261 		Print(EError, "TRomNode::NewNode: Out of memory\n");
   237 		Print(EError, "TRomNode::NewNode: Out of memory\n");
   262 		return 0;
   238 		return 0;
   263 		}
   239 	}
   264 	Add(node);
   240 	Add(node);
   265 	return node;
   241 	return node;
   266 	}
   242 }
   267 
   243 
   268 void TRomNode::Add(TRomNode* aChild)
   244 void TRomNode::Add(TRomNode* aChild) {
   269 	{
   245 	if (iChild) {// this node is a non-empty directory 
   270 	if (iChild) // this node is a non-empty directory
       
   271 		{
       
   272 		TRomNode* dir = iChild; // find where to link in the new node
   246 		TRomNode* dir = iChild; // find where to link in the new node
   273 		while (dir->iSibling)
   247 		while (dir->iSibling) 
   274 			dir = dir->iSibling;
   248 			dir = dir->iSibling;
   275 		dir->iSibling = aChild;
   249 		dir->iSibling = aChild;
   276 		}
   250 	}
   277 	else
   251 	else
   278 		iChild = aChild; // else just set it up as the child of the dir
   252 		iChild = aChild; // else just set it up as the child of the dir
   279 	aChild->iSibling = 0;
   253 	aChild->iSibling = 0;
   280 	aChild->iParent = this;
   254 	aChild->iParent = this;
   281 	}
   255 }
   282 
   256 
   283 void TRomNode::Remove(TRomNode* aChild)
   257 void TRomNode::Remove(TRomNode* aChild) {
   284 	{
   258 	if (iChild==0) {
   285 	if (iChild==0)
       
   286 		{
       
   287 		Print(EError, "Removing file from a file!!!\n");
   259 		Print(EError, "Removing file from a file!!!\n");
   288 		return;
   260 		return;
   289 		}
   261 	}
   290 	if (iChild==aChild) // first child in this directory
   262 	if (iChild==aChild) { // first child in this directory 
   291 		{
       
   292 		iChild = aChild->iSibling;
   263 		iChild = aChild->iSibling;
   293 		aChild->iSibling = 0;
   264 		aChild->iSibling = 0;
   294 		aChild->iParent = 0;
   265 		aChild->iParent = 0;
   295 		return;
   266 		return;
   296 		}
   267 	}
   297 	TRomNode* prev = iChild;
   268 	TRomNode* prev = iChild;
   298 	while (prev->iSibling && prev->iSibling != aChild)
   269 	while (prev->iSibling && prev->iSibling != aChild)
   299 		prev = prev->iSibling;
   270 		prev = prev->iSibling;
   300 	if (prev==0)
   271 	if (prev==0) {
   301 		{
       
   302 		Print(EError, "Attempting to remove file not in this directory!!!\n");
   272 		Print(EError, "Attempting to remove file not in this directory!!!\n");
   303 		return;
   273 		return;
   304 		}
   274 	}
   305 	prev->iSibling = aChild->iSibling;
   275 	prev->iSibling = aChild->iSibling;
   306 	aChild->iSibling = 0;
   276 	aChild->iSibling = 0;
   307 	aChild->iParent = 0;
   277 	aChild->iParent = 0;
   308 	}
   278 }
   309 
   279 
   310 void TRomNode::CountDirectory(TInt& aFileCount, TInt& aDirCount)
   280 void TRomNode::CountDirectory(TInt& aFileCount, TInt& aDirCount) {
   311 	{
       
   312 	TRomNode *current=iChild;
   281 	TRomNode *current=iChild;
   313 	while(current)
   282 	while(current) {
   314 		{
       
   315 		if (current->iChild)
   283 		if (current->iChild)
   316 			aDirCount++;
   284 			aDirCount++;
   317 		else if (!current->iHidden)
   285 		else if (!current->iHidden)
   318 			aFileCount++;
   286 			aFileCount++;
   319 		current=current->iSibling;
   287 		current=current->iSibling;
   320 		}
   288 	}
   321 	}
   289 }
   322 
   290 
   323 /**
   291 /**
   324  * Walk the contents of the directory, accumulating the
   292 * Walk the contents of the directory, accumulating the
   325  * files as FileEntry objects in the specified RomFileStructure
   293 * files as FileEntry objects in the specified RomFileStructure
   326  * and recursively handling the sub-directories
   294 * and recursively handling the sub-directories
   327  *
   295 *
   328  * TRomNode::ProcessDirectory is a pair with
   296 * TRomNode::ProcessDirectory is a pair with
   329  * RomFileStructure::ProcessDirectory
   297 * RomFileStructure::ProcessDirectory
   330  */
   298 */
   331 int TRomNode::ProcessDirectory(RomFileStructure* aRFS)
   299 int TRomNode::ProcessDirectory(RomFileStructure* aRFS) {
   332 	{
       
   333 	TInt r=KErrNone;
   300 	TInt r=KErrNone;
   334 	TRomNode *current=iChild;
   301 	TRomNode *current=iChild;
   335 	while(current)
   302 	while(current) {
   336 		{
   303 		if (current->iAtt & (TUint8)KEntryAttDir) {
   337 		if (current->iAtt & (TUint8)KEntryAttDir)
       
   338 			{
       
   339 			r=aRFS->ProcessDirectory(current);
   304 			r=aRFS->ProcessDirectory(current);
   340 			if (r!=KErrNone)
   305 			if (r!=KErrNone)
   341 				return r;
   306 				return r;
   342 			}
   307 		}
   343 		else if (!current->iHidden)
   308 		else if (!current->iHidden) {
   344 			{
       
   345 			FileEntry *pE=FileEntry::New(current);
   309 			FileEntry *pE=FileEntry::New(current);
   346 			if (!pE)
   310 			if (!pE)
   347 				return KErrNoMemory;
   311 				return KErrNoMemory;
   348 			r=aRFS->Add(*pE);
   312 			r=aRFS->Add(*pE);
   349 			if (r==KErrOverflow)
   313 			if (r==KErrOverflow)
   350 				return r;
   314 				return r;
   351 			}
   315 		}
   352 		current=current->iSibling;
   316 		current=current->iSibling;
   353 		}
   317 	}
   354 	return r;
   318 	return r;
   355 	}
   319 }
   356 
   320 
   357 void TRomNode::AddExecutableFile(TRomNode*& aLast, TRomNode* aNode)
   321 void TRomNode::AddExecutableFile(TRomNode*& aLast, TRomNode* aNode) {
   358 	{
       
   359 	aLast->iNextExecutable = aNode;
   322 	aLast->iNextExecutable = aNode;
   360 	aLast = aNode;
   323 	aLast = aNode;
   361 	aNode->iAtt |= KEntryAttXIP;
   324 	aNode->iAtt |= KEntryAttXIP;
   362 	}
   325 }
   363 
   326 
   364 char* TRomNode::BareName() const
   327 const char* TRomNode::BareName() const {
   365 	{
   328 	return iBareName  ;
   366 	return iBareName;
   329 }
   367 	}
   330 
   368 
   331 TUint32 TRomNode::Uid3() const {
   369 TUint32 TRomNode::Uid3() const
       
   370 	{
       
   371 	return iRomFile->Uid3();
   332 	return iRomFile->Uid3();
   372 	}
   333 }
   373 
   334 
   374 TUint32 TRomNode::ModuleVersion() const
   335 TUint32 TRomNode::ModuleVersion() const {
   375 	{
       
   376 	return iRomFile->ModuleVersion();
   336 	return iRomFile->ModuleVersion();
   377 	}
   337 }
   378 
   338 
   379 THardwareVariant TRomNode::HardwareVariant() const
   339 THardwareVariant TRomNode::HardwareVariant() const {
   380 	{
       
   381 	return iRomFile->HardwareVariant();
   340 	return iRomFile->HardwareVariant();
   382 	}
   341 }
   383 
   342 
   384 TUint32 TRomNode::ABI() const
   343 TUint32 TRomNode::ABI() const {
   385 	{
       
   386 	return iRomFile->ABI();
   344 	return iRomFile->ABI();
   387 	}
   345 }
   388 
   346 
   389 TUint32 TRomFile::Uid3() const
   347 TUint32 TRomFile::Uid3() const {
   390 	{
       
   391 	assert(!iDir);
   348 	assert(!iDir);
   392 	if (iRbEntry)
   349 	if (iRbEntry) {
   393 	{
       
   394 		if(iRbEntry->iHdr)
   350 		if(iRbEntry->iHdr)
   395 			return iRbEntry->iHdr->iUid3;
   351 			return iRbEntry->iHdr->iUid3;
   396 	}
   352 	}
   397 	return RomImgHdr()->iUid3;
   353 	return RomImgHdr()->iUid3;
   398 	}
   354 }
   399 
   355 
   400 TUint32 TRomFile::ModuleVersion() const
   356 TUint32 TRomFile::ModuleVersion() const {
   401 	{
       
   402 	assert(!iDir);
   357 	assert(!iDir);
   403 	if (iRbEntry)
   358 	if (iRbEntry) {
   404 	{
       
   405 		if(iRbEntry->iHdr)
   359 		if(iRbEntry->iHdr)
   406 			return iRbEntry->iHdr->ModuleVersion();
   360 			return iRbEntry->iHdr->ModuleVersion();
   407 	}
   361 	}
   408 	return RomImgHdr()->iModuleVersion;
   362 	return RomImgHdr()->iModuleVersion;
   409 	}
   363 }
   410 
   364 
   411 THardwareVariant TRomFile::HardwareVariant() const
   365 THardwareVariant TRomFile::HardwareVariant() const {
   412 	{
       
   413 	return iHwvd;
   366 	return iHwvd;
   414 	}
   367 }
   415 
   368 
   416 TUint32 TRomFile::ABI() const
   369 TUint32 TRomFile::ABI() const {
   417 	{
       
   418 	assert(!iDir);
   370 	assert(!iDir);
   419 	if (iRbEntry)
   371 	if (iRbEntry) {
   420 	{
       
   421 		if(iRbEntry->iHdr)
   372 		if(iRbEntry->iHdr)
   422 			return iRbEntry->iHdr->ABI();
   373 			return iRbEntry->iHdr->ABI();
   423 	}
   374 	}
   424 	return RomImgHdr()->iFlags & KRomImageABIMask;
   375 	return RomImgHdr()->iFlags & KRomImageABIMask;
   425 	}
   376 }
   426 
   377 
   427 TInt TRomFile::ExportDirCount() const
   378 TInt TRomFile::ExportDirCount() const {
   428 	{
       
   429 	assert(!iDir);
   379 	assert(!iDir);
   430 	if (iRbEntry)
   380 	if (iRbEntry) {
   431 	{
       
   432 		if(iRbEntry->iHdr)
   381 		if(iRbEntry->iHdr)
   433 			return iRbEntry->iHdr->iExportDirCount;
   382 			return iRbEntry->iHdr->iExportDirCount;
   434 	}
   383 	}
   435 	return RomImgHdr()->iExportDirCount;
   384 	return RomImgHdr()->iExportDirCount;
   436 	}
   385 }
   437 
   386 
   438 TUint32 TRomFile::RomImageFlags() const
   387 TUint32 TRomFile::RomImageFlags() const {
   439 	{
       
   440 	assert(!iDir);
   388 	assert(!iDir);
   441 	if (iRbEntry)
   389 	if (iRbEntry) {
   442 		{
   390 		if(iRbEntry->iHdr) {
   443 		if(iRbEntry->iHdr)
   391 			const TUint KRomFlagMask = KImageDll | KImageNoCallEntryPoint | KImageFixedAddressExe | KImageNmdExpData;
   444 		{
   392 			TUint romflags = iRbEntry->iHdr->iFlags & KRomFlagMask;
   445 		const TUint KRomFlagMask = KImageDll | KImageNoCallEntryPoint | KImageFixedAddressExe | KImageNmdExpData;
   393 			return iRbEntry->iRomImageFlags | romflags;
   446 		TUint romflags = iRbEntry->iHdr->iFlags & KRomFlagMask;
   394 		}
   447 		return iRbEntry->iRomImageFlags | romflags;
   395 	}
   448 		}
       
   449 		}
       
   450 	return RomImgHdr()->iFlags;
   396 	return RomImgHdr()->iFlags;
   451 	}
   397 }
   452 
   398 
   453 TLinAddr TRomFile::DataBssLinearBase() const
   399 TLinAddr TRomFile::DataBssLinearBase() const {
   454 	{
       
   455 	assert(!iDir);
   400 	assert(!iDir);
   456 	if (iRbEntry)
   401 	if (iRbEntry)
   457 		return iRbEntry->iDataBssLinearBase;
   402 		return iRbEntry->iDataBssLinearBase;
   458 	return RomImgHdr()->iDataBssLinearBase;
   403 	return RomImgHdr()->iDataBssLinearBase;
   459 	}
   404 }
   460 
   405 
   461 const SSecurityInfo& TRomFile::SecurityInfo() const
   406 const SSecurityInfo& TRomFile::SecurityInfo() const {
   462 	{
       
   463 	assert(!iDir);
   407 	assert(!iDir);
   464 	if (iRbEntry)
   408 	if (iRbEntry)
   465 		return iRbEntry->iS;
   409 		return iRbEntry->iS;
   466 	return RomImgHdr()->iS;
   410 	return RomImgHdr()->iS;
   467 	}
   411 }
   468 
   412 
   469 TInt TRomNode::FullNameLength(TBool aIgnoreHiddenAttrib) const
   413 TInt TRomNode::FullNameLength(TBool aIgnoreHiddenAttrib) const {
   470 	{
       
   471 	TInt l = 0;
   414 	TInt l = 0;
   472 	// aIgnoreHiddenAttrib is used to find the complete file name length as
   415 	// aIgnoreHiddenAttrib is used to find the complete file name length as
   473 	// in ROM of a hidden file.
   416 	// in ROM of a hidden file.
   474 	if (iParent && ( !iHidden || aIgnoreHiddenAttrib))
   417 	if (iParent && ( !iHidden || aIgnoreHiddenAttrib))
   475 		l = iParent->FullNameLength() + 1;
   418 		l = iParent->FullNameLength() + 1;
   476 	l += strlen((const char*)iName);
   419 	l += strlen((const char*)iName);
   477 	return l;
   420 	return l;
   478 	}
   421 }
   479 
   422 
   480 TInt TRomNode::GetFullName(char* aBuf, TBool aIgnoreHiddenAttrib) const
   423 TInt TRomNode::GetFullName(char* aBuf, TBool aIgnoreHiddenAttrib) const {
   481 	{
       
   482 	TInt l = 0;
   424 	TInt l = 0;
   483 	TInt nl = strlen((const char*)iName);
   425 	TInt nl = strlen(iName);
   484 	// aIgnoreHiddenAttrib is used to find the complete file name as in ROM of a hidden file.
   426 	// aIgnoreHiddenAttrib is used to find the complete file name as in ROM of a hidden file.
   485 	if (iParent && ( !iHidden || aIgnoreHiddenAttrib))
   427 	if (iParent && ( !iHidden || aIgnoreHiddenAttrib))
   486 		l = iParent->GetFullName(aBuf);
   428 		l = iParent->GetFullName(aBuf);
   487 	char* b = aBuf + l;
   429 	char* b = aBuf + l;
   488 	if (l)
   430 	if (l){
   489 		*b++ = '\\', ++l;
   431 		*b++ = SLASH_CHAR; 
       
   432 		++l;
       
   433 	}
   490 	memcpy(b, iName, nl);
   434 	memcpy(b, iName, nl);
   491 	b += nl;
   435 	b += nl;
   492 	*b = 0;
   436 	*b = 0;
   493 	l += nl;
   437 	l += nl;
   494 	return l;
   438 	return l;
   495 	}
   439 }
   496 
   440 
   497 TInt CompareCapabilities(const SCapabilitySet& aSubCaps, const SCapabilitySet& aSuperCaps, const char* aSubName, const char* aSuperName)
       
   498 //
   441 //
   499 //	Check that a aSubCaps are a subset of aSuperCaps
   442 //	Check that a aSubCaps are a subset of aSuperCaps
   500 //
   443 //
   501 	{
   444 TInt CompareCapabilities(const SCapabilitySet& aSubCaps, const SCapabilitySet& aSuperCaps, const char* aSubName, const char* aSuperName) {
   502 	if ((!gPlatSecEnforcement)&&(!gPlatSecDiagnostics))
   445 	if ((!gPlatSecEnforcement)&&(!gPlatSecDiagnostics))
   503 		return KErrNone;
   446 		return KErrNone;
   504 	TInt i;
   447 	TInt i;
   505 	TUint32 c = 0;
   448 	TUint32 c = 0;
   506 	for (i=0; i<SCapabilitySet::ENCapW; ++i)
   449 	for (i=0; i<SCapabilitySet::ENCapW; ++i)
   507 		c |= (aSubCaps[i] &~ aSuperCaps[i]);
   450 		c |= (aSubCaps[i] &~ aSuperCaps[i]);
   508 	TInt r = c ? KErrPermissionDenied : KErrNone;
   451 	TInt r = c ? KErrPermissionDenied : KErrNone;
   509 	if (r && aSubName && aSuperName)
   452 	if (r && aSubName && aSuperName) {
   510 		{
       
   511 		TPrintType printType;
   453 		TPrintType printType;
   512 		if(gPlatSecEnforcement)
   454 		if(gPlatSecEnforcement)
   513 			printType = EError;
   455 			printType = EError;
   514 		else
   456 		else {
   515 			{
       
   516 			printType = EWarning;
   457 			printType = EWarning;
   517 			r = KErrNone;
   458 			r = KErrNone;
   518 			}
   459 		}
   519 		char* buf = (char*)malloc(2);
   460 		char* buf = (char*)malloc(2);
   520 		if(!buf)
   461 		if(!buf)
   521 			return KErrNoMemory;
   462 			return KErrNoMemory;
   522 		TInt len = 0;
   463 		TInt len = 0;
   523 		for(i=0; i<ECapability_Limit; i++)
   464 		for(i=0; i<ECapability_Limit; i++) {
   524 			{
   465 			if( (aSubCaps[i>>5] &~ aSuperCaps[i>>5]) & (1<<(i&31)) ) {
   525 			if( (aSubCaps[i>>5] &~ aSuperCaps[i>>5]) & (1<<(i&31)) )
       
   526 				{
       
   527 				// append capability name to buf
   466 				// append capability name to buf
   528 				const char* name = CapabilityNames[i];
   467 				const char* name = CapabilityNames[i];
   529 				if(!name)
   468 				if(!name)
   530 					continue;
   469 					continue;
   531 				if(len)
   470 				if(len) {
   532 					{
       
   533 					buf[len++] = ' ';
   471 					buf[len++] = ' ';
   534 					}
   472 				}
   535 				int nameLen=strlen(name);
   473 				int nameLen=strlen(name);
   536 				buf = (char*)realloc(buf,len+nameLen+2);
   474 				buf = (char*)realloc(buf,len+nameLen+2);
   537 				if(!buf)
   475 				if(!buf)
   538 					return KErrNoMemory;
   476 					return KErrNoMemory;
   539 				memcpy(buf+len,CapabilityNames[i],nameLen);
   477 				memcpy(buf+len,CapabilityNames[i],nameLen);
   540 				len += nameLen;
   478 				len += nameLen;
   541 				}
       
   542 			}
   479 			}
       
   480 		}
   543 		buf[len]=0;
   481 		buf[len]=0;
   544 		Print(printType, "*PlatSec* %s - Capability check failed. Can't load %s because it links to %s which has the following capabilities missing: %s\n",gPlatSecEnforcement?"ERROR":"WARNING",aSubName, aSuperName, buf);
   482 		Print(printType, "*PlatSec* %s - Capability check failed. Can't load %s because it links to %s which has the following capabilities missing: %s\n",gPlatSecEnforcement?"ERROR":"WARNING",aSubName, aSuperName, buf);
   545 		free(buf);
   483 		free(buf);
   546 		}
   484 	}
   547 	return r;
   485 	return r;
   548 	}
   486 }
   549 
   487 
   550 TDllFindInfo::TDllFindInfo(const char* aImportName, const TRomBuilderEntry* aEntry)
   488 TDllFindInfo::TDllFindInfo(const char* aImportName, const TRomBuilderEntry* aEntry) {
   551 	{
       
   552 	TUint32 flags;
   489 	TUint32 flags;
   553 	iBareName = SplitFileName(aImportName, iUid3, iModuleVersion, flags);
   490 	iBareName = SplitFileName(aImportName, iUid3, iModuleVersion, flags);
   554 	assert(iBareName != 0);
   491 	assert(iBareName != 0);
   555 	iHwVariant = aEntry->iHardwareVariant.ReturnVariant(); 
   492 	iHwVariant = aEntry->iHardwareVariant.ReturnVariant(); 
   556 	}
   493 }
   557 
   494 
   558 TDllFindInfo::~TDllFindInfo()
   495 TDllFindInfo::~TDllFindInfo() {
   559 	{
   496 	delete []iBareName;
   560 	free((void*)iBareName);
   497 }
   561 	}
       
   562 
   498 
   563 // Generate name as follows:
   499 // Generate name as follows:
   564 // PC filename (UID3:xxxxxxxx HWVD:xxxxxxxx VER:M.m)
   500 // PC filename (UID3:xxxxxxxx HWVD:xxxxxxxx VER:M.m)
   565 TModuleName::TModuleName(const TRomBuilderEntry* a)
   501 TModuleName::TModuleName(const TRomBuilderEntry* a) {
   566 	{
       
   567 	TInt l = strlen(a->iFileName) + strlen(" (UID3:xxxxxxxx HWVD:xxxxxxxx VER:MMMMM.mmmmm)");
   502 	TInt l = strlen(a->iFileName) + strlen(" (UID3:xxxxxxxx HWVD:xxxxxxxx VER:MMMMM.mmmmm)");
   568 	iName = (char*)malloc(l + 1);
   503 	iName = new char[l + 1];
   569 	assert(iName != 0);
   504 	assert(iName != 0);
   570 	sprintf(iName, "%s (UID3:%08lx HWVD:%08lx VER:%ld.%ld)", a->iFileName, a->iHdr->iUid3,
   505 	sprintf(iName, "%s (UID3:%08lx HWVD:%08lx VER:%ld.%ld)", a->iFileName, a->iHdr->iUid3,
   571 		a->iHardwareVariant.ReturnVariant(), a->iHdr->ModuleVersion()>>16, a->iHdr->ModuleVersion()&0x0000ffffu);
   506 		a->iHardwareVariant.ReturnVariant(), a->iHdr->ModuleVersion()>>16, a->iHdr->ModuleVersion()&0x0000ffffu);
   572 	}
   507 }
   573 
   508 
   574 // Generate name as follows:
   509 // Generate name as follows:
   575 // Bare name (UID3:xxxxxxxx HWVD:xxxxxxxx VER:M.m)
   510 // Bare name (UID3:xxxxxxxx HWVD:xxxxxxxx VER:M.m)
   576 TModuleName::TModuleName(const TDllFindInfo& a)
   511 TModuleName::TModuleName(const TDllFindInfo& a) {
   577 	{
       
   578 	TInt l = strlen(a.iBareName) + strlen(" (UID3:xxxxxxxx HWVD:xxxxxxxx VER:MMMMM.mmmmm)");
   512 	TInt l = strlen(a.iBareName) + strlen(" (UID3:xxxxxxxx HWVD:xxxxxxxx VER:MMMMM.mmmmm)");
   579 	iName = (char*)malloc(l + 1);
   513 	iName = new char [l + 1];
   580 	assert(iName != 0);
   514 	assert(iName != 0);
   581 	sprintf(iName, "%s (UID3:%08lx HWVD:%08lx VER:%ld.%ld)", a.iBareName, a.iUid3,
   515 	sprintf(iName, "%s (UID3:%08lx HWVD:%08lx VER:%ld.%ld)", a.iBareName, a.iUid3,
   582 		a.iHwVariant, a.iModuleVersion>>16, a.iModuleVersion&0x0000ffffu);
   516 		a.iHwVariant, a.iModuleVersion>>16, a.iModuleVersion&0x0000ffffu);
   583 	}
   517 }
   584 
   518 
   585 // Generate name as follows:
   519 // Generate name as follows:
   586 // Name (UID3:xxxxxxxx HWVD:xxxxxxxx VER:M.m)
   520 // Name (UID3:xxxxxxxx HWVD:xxxxxxxx VER:M.m)
   587 TModuleName::TModuleName(const TRomNode& a)
   521 TModuleName::TModuleName(const TRomNode& a) {
   588 	{
       
   589 	TBool xip = (a.iAtt & KEntryAttXIP);
   522 	TBool xip = (a.iAtt & KEntryAttXIP);
   590 	TUint32 uid3 = xip ? a.Uid3() : 0;
   523 	TUint32 uid3 = xip ? a.Uid3() : 0;
   591 	TUint32 hwvd = (TUint)a.HardwareVariant();
   524 	TUint32 hwvd = (TUint)a.HardwareVariant();
   592 	TUint32 ver = xip ? a.ModuleVersion() : 0;
   525 	TUint32 ver = xip ? a.ModuleVersion() : 0;
   593 	TInt l = a.FullNameLength() + strlen(" (UID3:xxxxxxxx HWVD:xxxxxxxx VER:MMMMM.mmmmm)");
   526 	TInt l = a.FullNameLength() + strlen(" (UID3:xxxxxxxx HWVD:xxxxxxxx VER:MMMMM.mmmmm)");
   594 	iName = (char*)malloc(l + 1);
   527 	iName = new char[l + 1];
   595 	assert(iName != 0);
   528 	assert(iName != 0);
   596 	char* b = iName + a.GetFullName(iName);
   529 	char* b = iName + a.GetFullName(iName);
   597 	sprintf(b, " (UID3:%08lx HWVD:%08lx VER:%ld.%ld)", uid3, hwvd, ver>>16, ver&0x0000ffffu);
   530 	sprintf(b, " (UID3:%08lx HWVD:%08lx VER:%ld.%ld)", uid3, hwvd, ver>>16, ver&0x0000ffffu);
   598 	}
   531 }
   599 
   532 
   600 TModuleName::TModuleName(const TRomFile& a, const TRomNode* aRootDir)
   533 TModuleName::TModuleName(const TRomFile& a, const TRomNode* aRootDir) {
   601 	{
       
   602 	iName = 0;
   534 	iName = 0;
   603 	if (a.iRbEntry)
   535 	if (a.iRbEntry) {
   604 		{
       
   605 		new (this) TModuleName(a.iRbEntry);
   536 		new (this) TModuleName(a.iRbEntry);
   606 		return;
   537 		return;
   607 		}
   538 	}
   608 	TRomNode* x = aRootDir->iNextExecutable;
   539 	TRomNode* x = aRootDir->iNextExecutable;
   609 	for(; x; x=x->iNextExecutable)
   540 	for(; x; x=x->iNextExecutable) {
   610 		{
   541 		if (x->iRomFile == &a) {
   611 		if (x->iRomFile == &a)
       
   612 			{
       
   613 			new (this) TModuleName(*x);
   542 			new (this) TModuleName(*x);
   614 			return;
   543 			return;
   615 			}
   544 		}
   616 		}
   545 	}
   617 	}
   546 }
   618 
   547 
   619 TModuleName::~TModuleName()
   548 TModuleName::~TModuleName() {
   620 	{
   549 	if(iName)
   621 	free(iName);
   550 		delete []iName;
   622 	}
   551 }
   623 
   552 
   624 
   553 
   625 /**
   554 /**
   626  * TRomNode::FindImageFileByName is always called on the root TRomNode, so
   555 * TRomNode::FindImageFileByName is always called on the root TRomNode, so
   627  * it doesn't consider the current TRomNode, just the linked items in the
   556 * it doesn't consider the current TRomNode, just the linked items in the
   628  * iNextExecutable list.
   557 * iNextExecutable list.
   629  */
   558 */
   630 TRomNode* TRomNode::FindImageFileByName(const TDllFindInfo& aInfo, TBool aPrintDiag, TBool& aFallBack)
   559 TRomNode* TRomNode::FindImageFileByName(const TDllFindInfo& aInfo, TBool aPrintDiag, TBool& aFallBack) {
   631 	{
       
   632 	TUint r_major = aInfo.iModuleVersion >> 16;
   560 	TUint r_major = aInfo.iModuleVersion >> 16;
   633 	TUint r_minor = aInfo.iModuleVersion & 0x0000ffffu;
   561 	TUint r_minor = aInfo.iModuleVersion & 0x0000ffffu;
   634 	TRomNode* fallback = NULL;
   562 	TRomNode* fallback = NULL;
   635 	aFallBack = EFalse;
   563 	aFallBack = EFalse;
   636 	for (TRomNode* x=iNextExecutable; x!=0; x=x->iNextExecutable)
   564 	for (TRomNode* x=iNextExecutable; x!=0; x=x->iNextExecutable) {
   637 		{
       
   638 		if (stricmp(x->BareName(), aInfo.iBareName))
   565 		if (stricmp(x->BareName(), aInfo.iBareName))
   639 			continue;	// name doesn't match
   566 			continue;	// name doesn't match
   640 		if (aPrintDiag)
   567 		if (aPrintDiag)
   641 			Print(ELog, "Candidate: %s ", (const char*)TModuleName(*x) );
   568 			Print(ELog, "Candidate: %s ", (const char*)TModuleName(*x) );
   642 		if ( !(THardwareVariant(aInfo.iHwVariant) <= x->HardwareVariant()) )
   569 		if ( !(THardwareVariant(aInfo.iHwVariant) <= x->HardwareVariant()) ) {
   643 			{
       
   644 			if (aPrintDiag)
   570 			if (aPrintDiag)
   645 				Print(ELog, "HWVD mismatch - requested %08x\n", aInfo.iHwVariant);
   571 				Print(ELog, "HWVD mismatch - requested %08x\n", aInfo.iHwVariant);
   646 			continue;
   572 			continue;
   647 			}
   573 		}
   648 		if (aInfo.iUid3 && (aInfo.iUid3 != x->Uid3()))
   574 		if (aInfo.iUid3 && (aInfo.iUid3 != x->Uid3())) {
   649 			{
       
   650 			if (aPrintDiag)
   575 			if (aPrintDiag)
   651 				Print(ELog, "UID3 mismatch - requested %08x\n", aInfo.iUid3);
   576 				Print(ELog, "UID3 mismatch - requested %08x\n", aInfo.iUid3);
   652 			continue;
   577 			continue;
   653 			}
   578 		}
   654 		TUint x_major = x->ModuleVersion() >> 16;
   579 		TUint x_major = x->ModuleVersion() >> 16;
   655 		TUint x_minor = x->ModuleVersion() & 0x0000ffffu;
   580 		TUint x_minor = x->ModuleVersion() & 0x0000ffffu;
   656 		if ( x->ModuleVersion() == 0x00010000 && aInfo.iModuleVersion == 0 )
   581 		if ( x->ModuleVersion() == 0x00010000 && aInfo.iModuleVersion == 0 ) {
   657 			{
       
   658 			// allow requested version 0.0 to link to 1.0 with a warning
   582 			// allow requested version 0.0 to link to 1.0 with a warning
   659 			fallback = x;
   583 			fallback = x;
   660 			}
   584 		}
   661 		if ( x_major != r_major )
   585 		if ( x_major != r_major ) {
   662 			{
       
   663 			if (aPrintDiag)
   586 			if (aPrintDiag)
   664 				Print(ELog, "Major version mismatch - requested %d\n", r_major);
   587 				Print(ELog, "Major version mismatch - requested %d\n", r_major);
   665 			continue;
   588 			continue;
   666 			}
   589 		}
   667 		if ( x_minor < r_minor )
   590 		if ( x_minor < r_minor ) {
   668 			{
       
   669 			if (aPrintDiag)
   591 			if (aPrintDiag)
   670 				Print(ELog, "??? Minor version mismatch - requested %d\n", r_minor);
   592 				Print(ELog, "??? Minor version mismatch - requested %d\n", r_minor);
   671 			continue;
   593 			continue;
   672 			}
   594 		}
   673 		if (aPrintDiag)
   595 		if (aPrintDiag)
   674 			Print(ELog, "OK\n");
   596 			Print(ELog, "OK\n");
   675 		return x;
   597 		return x;
   676 		}
   598 	}
   677 	if (fallback)
   599 	if (fallback) {
   678 		{
       
   679 		aFallBack = ETrue;
   600 		aFallBack = ETrue;
   680 		return fallback;
   601 		return fallback;
   681 		}
   602 	}
   682 	return 0;
   603 	return 0;
   683 	}
   604 }
   684 
   605 
   685 TInt TRomNode::CheckForVersionConflicts(const TRomBuilderEntry* a)
   606 TInt TRomNode::CheckForVersionConflicts(const TRomBuilderEntry* a) {
   686 	{
       
   687 	TUint r_major = a->iHdr->ModuleVersion() >> 16;
   607 	TUint r_major = a->iHdr->ModuleVersion() >> 16;
   688 	TUint r_minor = a->iHdr->ModuleVersion() & 0x0000ffffu;
   608 	TUint r_minor = a->iHdr->ModuleVersion() & 0x0000ffffu;
   689 	TInt errors = 0;
   609 	TInt errors = 0;
   690 	for (TRomNode* x=iNextExecutable; x!=0; x=x->iNextExecutable)
   610 	for (TRomNode* x=iNextExecutable; x!=0; x=x->iNextExecutable) {
   691 		{
       
   692 		if (x->iRomFile->iRbEntry == a)
   611 		if (x->iRomFile->iRbEntry == a)
   693 			continue;	// don't compare a with itself
   612 			continue;	// don't compare a with itself
   694 		if (stricmp(x->BareName(), a->iBareName))
   613 		if (stricmp(x->BareName(), a->iBareName))
   695 			continue;	// name doesn't match
   614 			continue;	// name doesn't match
   696 		if ( a->iHardwareVariant.MutuallyExclusive(x->HardwareVariant()) )
   615 		if ( a->iHardwareVariant.MutuallyExclusive(x->HardwareVariant()) )
   697 			continue;	// HWVDs are mutually exclusive
   616 			continue;	// HWVDs are mutually exclusive
   698 		if ( a->iHdr->iUid3 && x->Uid3() && (a->iHdr->iUid3 != x->Uid3()) )
   617 		if ( a->iHdr->iUid3 && x->Uid3() && (a->iHdr->iUid3 != x->Uid3()) )
   699 			continue;	// UID3's don't match
   618 			continue;	// UID3's don't match
   700 		TUint x_major = x->ModuleVersion() >> 16;
   619 		TUint x_major = x->ModuleVersion() >> 16;
   701 		TUint x_minor = x->ModuleVersion() & 0x0000ffffu;
   620 		TUint x_minor = x->ModuleVersion() & 0x0000ffffu;
   702 		if (x_major == r_major && x_minor != r_minor)	// allow two copies of same file
   621 		if (x_major == r_major && x_minor != r_minor)  {	// allow two copies of same file
   703 			{
       
   704 			Print(EError, "Version Conflict %s with %s\n", (const char*)TModuleName(a), (const char*)TModuleName(*x) );
   622 			Print(EError, "Version Conflict %s with %s\n", (const char*)TModuleName(a), (const char*)TModuleName(*x) );
   705 			++errors;
   623 			++errors;
   706 			}
   624 		}
   707 		}
   625 	}
   708 	return errors;
   626 	return errors;
   709 	}
   627 }
   710 
   628 
   711 TInt E32Rom::WriteHeadersToRom(char *anAddr)
       
   712 //
   629 //
   713 // Follow the TRomBuilderEntry tree, writing TRomEntry headers to the rom.
   630 // Follow the TRomBuilderEntry tree, writing TRomEntry headers to the rom.
   714 //
   631 //
   715 	{
   632 TInt E32Rom::WriteHeadersToRom(char *anAddr) {
   716 	TRACE(TTIMING,Print(EAlways,"0\n"));
   633 	TRACE(TTIMING,Print(EAlways,"0\n"));
   717 	TRACE(TDIR,Print(EAlways,"WriteHeadersToRom()\n"));
   634 	TRACE(TDIR,Print(EAlways,"WriteHeadersToRom()\n"));
   718 	char* start=anAddr;
   635 	char* start=anAddr;
   719 	TRomRootDirectoryList* dirPointers=(TRomRootDirectoryList*)anAddr;
   636 	TRomRootDirectoryList* dirPointers=(TRomRootDirectoryList*)anAddr;
   720 	anAddr+=NumberOfVariants*sizeof(TRootDirInfo)+sizeof(TInt);
   637 	anAddr+=NumberOfVariants*sizeof(TRootDirInfo)+sizeof(TInt);
   730 		Print(EError,"Error processing directory tree NR=%d NV=%d\n",c,NumberOfVariants);
   647 		Print(EError,"Error processing directory tree NR=%d NV=%d\n",c,NumberOfVariants);
   731 	dirPointers->iNumRootDirs=c;
   648 	dirPointers->iNumRootDirs=c;
   732 	TInt i;
   649 	TInt i;
   733 	TRACE(TDIR,Print(EAlways,"Count=%d\n",c));
   650 	TRACE(TDIR,Print(EAlways,"Count=%d\n",c));
   734 	TRACE(TDIR,pS->DebugPrint());
   651 	TRACE(TDIR,pS->DebugPrint());
   735 	for(i=0; i<c; i++)
   652 	for(i=0; i<c; i++) {
   736 		{
       
   737 		DirEntry* pD=(DirEntry*)&(*pS)[i];
   653 		DirEntry* pD=(DirEntry*)&(*pS)[i];
   738 		TRomDir* pR=pD->CreateRomEntries(anAddr);
   654 		TRomDir* pR=pD->CreateRomEntries(anAddr);
   739 		dirPointers->iRootDir[i].iHardwareVariant=TUint(pD->Variants().Lookup());
   655 		dirPointers->iRootDir[i].iHardwareVariant=TUint(pD->Variants().Lookup());
   740 		dirPointers->iRootDir[i].iAddressLin=ActualToRomAddress(pR);
   656 		dirPointers->iRootDir[i].iAddressLin=ActualToRomAddress(pR);
   741 		}
   657 	}
   742 	TRACE(TDIR,Print(EAlways,"Beginning final cleanup\n"));
   658 	TRACE(TDIR,Print(EAlways,"Beginning final cleanup\n"));
   743 	delete pS;
   659 	delete pS;
   744 	TRACE(TTIMING,Print(EAlways,"1\n"));
   660 	TRACE(TTIMING,Print(EAlways,"1\n"));
   745 	return anAddr-start;
   661 	return anAddr-start;
   746 	}
   662 }
   747 
   663 
   748  void TRomNode::Destroy()
       
   749 //
   664 //
   750 // Follow the TRomNode tree, destroying it
   665 // Follow the TRomNode tree, destroying it
   751 //
   666 //
   752 	{
   667 void TRomNode::Destroy() {
   753 
   668 
   754  	TRomNode *current = this; // root has no siblings
   669 	TRomNode *current = this; // root has no siblings
   755 	while (current)
   670 	while (current) {
   756 		{
       
   757 		if (current->iChild)
   671 		if (current->iChild)
   758 			current->iChild->Destroy();
   672 			current->iChild->Destroy();
   759 		TRomNode* prev=current;
   673 		TRomNode* prev=current;
   760 		current=current->iSibling;
   674 		current=current->iSibling;
   761 		delete prev;
   675 		delete prev;
   762 		}
   676 	}
   763  	}
   677 }
   764 
   678 
   765 
       
   766 TInt TRomNode::SetAtt(TText *anAttWord)
       
   767 //
   679 //
   768 // Set the file attribute byte from the letters passed
   680 // Set the file attribute byte from the letters passed
   769 //
   681 //
   770 	{
   682 TInt TRomNode::SetAtt(const char* anAttWord) {
   771 	iAtt=0;
   683 	iAtt=0;
   772 	if (anAttWord==0 || anAttWord[0]=='\0')
   684 	if (anAttWord==0 || anAttWord[0]=='\0')
   773 		return Print(EError, "Missing argument for keyword 'attrib'.\n");
   685 		return Print(EError, "Missing argument for keyword 'attrib'.\n");
   774 	for (TText *letter=anAttWord;*letter!=0;letter++)
   686 	for (const char* letter = anAttWord; *letter != 0; letter ++) {
   775 		{
   687 		switch (*letter) {
   776 		switch (*letter)
       
   777 			{
       
   778 		case 'R':
   688 		case 'R':
   779 		case 'w':
   689 		case 'w':
   780 			iAtt |= KEntryAttReadOnly;
   690 			iAtt |= KEntryAttReadOnly;
   781 			break;
   691 			break;
   782 		case 'r':
   692 		case 'r':
   796 			iAtt &= ~KEntryAttSystem;
   706 			iAtt &= ~KEntryAttSystem;
   797 			break;
   707 			break;
   798 		default:
   708 		default:
   799 			return Print(EError, "Unrecognised attrib - '%c'.\n", *letter);
   709 			return Print(EError, "Unrecognised attrib - '%c'.\n", *letter);
   800 			break;
   710 			break;
   801 			}
   711 		}
   802 		}
   712 	}
   803 	return KErrNone;
   713 	return KErrNone;
   804 	}
   714 }
   805 
       
   806 TRomBuilderEntry::TRomBuilderEntry(const char *aFileName,TText *aName)
       
   807 //
   715 //
   808 // Constructor
   716 // Constructor
   809 //
   717 //
   810 	:
   718 TRomBuilderEntry::TRomBuilderEntry(const char *aFileName,const char* aName) :
   811 	E32ImageFile(),
   719 E32ImageFile(),
   812 	iName(0),
   720 iName(0),
   813 	iResource(EFalse), iNonXIP(EFalse), iPreferred(EFalse), iCompression(0), iPatched(EFalse),iArea(0),
   721 iResource(EFalse), iNonXIP(EFalse), iPreferred(EFalse), iCompression(0), iPatched(EFalse),iArea(0),
   814 	iOverrideFlags(0),iCodeAlignment(0),iDataAlignment(0),iUid1(0), iUid2(0), iUid3(0),iBareName(0), 
   722 iOverrideFlags(0),iCodeAlignment(0),iDataAlignment(0),iUid1(0), iUid2(0), iUid3(0),iBareName(0), 
   815 	iHardwareVariant(KVariantIndependent),iDataBssOffset(0xffffffff), 
   723 iHardwareVariant(KVariantIndependent),iDataBssOffset(0xffffffff), 
   816 	iStackReserve(0),iIATRefs(0), iNext(0), iNextInArea(0), 
   724 iStackReserve(0),iIATRefs(0), iNext(0), iNextInArea(0), 
   817 	iRomImageFlags(0),iProcessName(0), iRomNode(NULL)
   725 iRomImageFlags(0),iProcessName(0), iRomNode(NULL) {
   818 	{
   726 	if (aFileName){
   819 	if (aFileName)
   727 		if(iFileName)
   820    		iFileName = NormaliseFileName((const char*)aFileName);
   728 			delete []iFileName;
       
   729 		iFileName = NormaliseFileName(aFileName);	 
       
   730 	}
   821 	if (aName)
   731 	if (aName)
   822 		iName = (TText*)NormaliseFileName((const char*)aName);
   732 		iName = NormaliseFileName(aName);
   823 	}
   733 }
   824 
       
   825 TRomBuilderEntry::~TRomBuilderEntry()
       
   826 //
   734 //
   827 // Destructor
   735 // Destructor
   828 //
   736 //
   829 	{
   737 TRomBuilderEntry::~TRomBuilderEntry() {
   830 
   738 	 
   831 	free(iFileName);
   739 	if(iName){
   832 	iFileName = 0;
   740 		delete []iName; 
   833 	free(iName);
   741 		iName = 0 ;
   834 	iName = 0;
   742 	}
   835 	delete[] iProcessName;
   743 	if(iProcessName){	
   836 	free(iBareName);
   744 		delete []iProcessName;
   837 	iBareName = 0;
   745 		iProcessName = 0 ;
   838 	delete[] iIATRefs;
   746 	}
   839 	}
   747 	if(iBareName) {
   840 
   748 		delete []iBareName;
   841 TInt isNumber(TText *aString)
   749 		iBareName = 0 ;
   842 	{
   750 	}
   843 	if (aString==NULL)
   751 
   844 		return 0;
   752 	if(iIATRefs){
   845 	if (strlen((char *)aString)==0)
   753 		char* tmp = reinterpret_cast<char*>(iIATRefs);
   846 		return 0;
   754 		delete []tmp;
   847 	return isdigit(aString[0]);
   755 		iIATRefs = 0 ;
   848 	}
   756 	}
   849 
   757 }
   850 TInt getNumber(TText *aStr)
   758 
   851 	{
   759 TInt TRomBuilderEntry::SetCodeAlignment(const char* aStr) {
   852 	TUint a;
   760 	if (!IsValidNumber(aStr))
   853 	#ifdef __TOOLS2__
   761 		return Print(EError, "Number required as argument for keyword 'code-align'.\n"); 
   854 	istringstream val((char *)aStr);
   762 	TInt err = Val(iCodeAlignment,aStr);	 
   855 	#else
   763 	return err;
   856 	istrstream val((char *)aStr,strlen((char *)aStr));
   764 }
   857 	#endif
   765 
   858 
   766 TInt TRomBuilderEntry::SetDataAlignment(const char* aStr) {
   859 #if defined(__MSVCDOTNET__) || defined(__TOOLS2__)
   767 	if (!IsValidNumber(aStr))
   860 	val >> setbase(0);
   768 		return Print(EError, "Number required as argument for keyword 'data-align'.\n"); 
   861 #endif //__MSVCDOTNET__
   769 	TInt align = 0;
   862 
   770 	Val(align,aStr);
   863 	val >> a;
   771 	if (align < 0 || (align & 0x0F) != 0) 
   864 	return a;
       
   865 	}
       
   866 
       
   867 TInt TRomBuilderEntry::SetCodeAlignment(TText* aStr)
       
   868 	{
       
   869     if (!aStr || (aStr && isNumber(aStr)==0))
       
   870 		return Print(EError, "Number required as argument for keyword 'code-align'.\n");
       
   871     iCodeAlignment=getNumber(aStr);
       
   872     return KErrNone;
       
   873 	}
       
   874 
       
   875 TInt TRomBuilderEntry::SetDataAlignment(TText* aStr)
       
   876 	{
       
   877     if (!isNumber(aStr))
       
   878 		return Print(EError, "Number required as argument for keyword 'data-align'.\n");
       
   879     TInt align=getNumber(aStr);
       
   880 	if (align<0 || (align&0x0F) != 0)
       
   881 		return Print(EError, "Positive multiple of 16 required for 'data-align'.\n");
   772 		return Print(EError, "Positive multiple of 16 required for 'data-align'.\n");
   882 	iDataAlignment=align;
   773 	iDataAlignment = align;
   883     return KErrNone;
   774 	return KErrNone;
   884 	}
   775 }
   885 
   776 
   886 TInt TRomBuilderEntry::SetRelocationAddress(TText *aStr)
   777 TInt TRomBuilderEntry::SetRelocationAddress(const char* aStr) {
   887 	{
   778 	if (aStr && !IsValidNumber(aStr))
   888 	if (aStr && isNumber(aStr)==0)
       
   889 		return Print(EError, "Number required as argument for keyword 'reloc'.\n");
   779 		return Print(EError, "Number required as argument for keyword 'reloc'.\n");
   890 	iOverrideFlags |= KOverrideAddress;
   780 	iOverrideFlags |= KOverrideAddress;
   891 	iRelocationAddress=aStr ? getNumber(aStr) : 0xFFFFFFFF;
   781 	iRelocationAddress =  0xFFFFFFFF; 
       
   782 	if(aStr){
       
   783 		Val(iRelocationAddress,aStr);
       
   784 	}
   892 	return KErrNone;
   785 	return KErrNone;
   893 	}
   786 }
   894 
   787 
   895 TInt TRomBuilderEntry::SetStackReserve(TText *aStr)
   788 TInt TRomBuilderEntry::SetStackReserve(const char* aStr) {
   896 	{
   789 	if (!IsValidNumber(aStr))
   897 	if (isNumber(aStr)==0)
   790 		return Print(EError, "Number required as argument for keyword 'stackreserve'.\n");	
   898 		return Print(EError, "Number required as argument for keyword 'stackreserve'.\n");
   791 	TInt err = Val(iStackReserve,aStr);
   899 	iOverrideFlags |= KOverrideStackReserve;
   792 	if(err == KErrNone)
   900 	iStackReserve=getNumber(aStr);
   793 		iOverrideFlags |= KOverrideStackReserve;
       
   794 	return err;
       
   795 }
       
   796 
       
   797 TInt TRomBuilderEntry::SetStackSize(const char* aStr) {
       
   798 	if (!IsValidNumber(aStr))
       
   799 		return Print(EError, "Number required as argument for keyword 'stack'.\n");	
       
   800 	TInt err = Val(iStackSize,aStr);
       
   801 	if(err == KErrNone)
       
   802 		iOverrideFlags |= KOverrideStack;
       
   803 	return err;
       
   804 }
       
   805 
       
   806 TInt TRomBuilderEntry::SetHeapSizeMin(const char* aStr) {
       
   807 	if (!IsValidNumber(aStr))
       
   808 		return Print(EError, "Number required as argument for keyword 'heapmin'.\n");	
       
   809 	TInt err = Val(iHeapSizeMin,aStr); 
       
   810 	if(err == KErrNone)
       
   811 		iOverrideFlags |= KOverrideHeapMin;
   901 	return KErrNone;
   812 	return KErrNone;
   902 	}
   813 }
   903 
   814 
   904 TInt TRomBuilderEntry::SetStackSize(TText *aStr)
   815 TInt TRomBuilderEntry::SetHeapSizeMax(const char* aStr) {
   905 	{
   816 	if (!IsValidNumber(aStr))
   906 	if (isNumber(aStr)==0)
       
   907 		return Print(EError, "Number required as argument for keyword 'stack'.\n");
       
   908 	iOverrideFlags |= KOverrideStack;
       
   909 	iStackSize=getNumber(aStr);
       
   910 	return KErrNone;
       
   911 	}
       
   912 
       
   913 TInt TRomBuilderEntry::SetHeapSizeMin(TText *aStr)
       
   914 	{
       
   915 	if (isNumber(aStr)==0)
       
   916 		return Print(EError, "Number required as argument for keyword 'heapmin'.\n");
       
   917 	iOverrideFlags |= KOverrideHeapMin;
       
   918 	iHeapSizeMin=getNumber(aStr);
       
   919 	return KErrNone;
       
   920 	}
       
   921 
       
   922 TInt TRomBuilderEntry::SetHeapSizeMax(TText *aStr)
       
   923 	{
       
   924 	if (isNumber(aStr)==0)
       
   925 		return Print(EError, "Number required as argument for keyword 'heapmax'.\n");
   817 		return Print(EError, "Number required as argument for keyword 'heapmax'.\n");
   926 	iOverrideFlags |= KOverrideHeapMax;
   818 	TInt err = Val(iHeapSizeMax,aStr); 
   927 	iHeapSizeMax=getNumber(aStr);
   819 	if(err == KErrNone)
   928 	return KErrNone;
   820 		iOverrideFlags |= KOverrideHeapMax;
   929 	}
   821 	return err;
   930 
   822 }
   931 TInt TRomBuilderEntry::SetCapability(TText *aStr)
   823 
   932 	{
   824 TInt TRomBuilderEntry::SetCapability(const char* aStr) {
   933 	iOverrideFlags |= KOverrideCapability;
   825 	iOverrideFlags |= KOverrideCapability;
   934 	if (isNumber(aStr))
   826 	if (IsValidNumber(aStr)) {
   935 		{
       
   936 		Print(EDiagnostic,"Old style numeric CAPABILTY specification ignored.\n");
   827 		Print(EDiagnostic,"Old style numeric CAPABILTY specification ignored.\n");
   937 		return KErrNone;
   828 		return KErrNone;
   938 		}
   829 	}
   939 	return ParseCapabilitiesArg(iS.iCaps, (char*)aStr);
   830 	return ParseCapabilitiesArg(iS.iCaps, aStr);
   940 	}
   831 }
   941 
   832 
   942 TInt TRomBuilderEntry::SetPriority(TText *aStr)
   833 TInt TRomBuilderEntry::SetPriority(const char* aStr) {
   943 	{
   834 	if (IsValidNumber(aStr)){
   944 	if (isNumber(aStr))
   835 		TUint32 temp = 0 ;
   945 		iPriority=(TProcessPriority)getNumber(aStr);
   836 		Val(temp,aStr);
   946 	else
   837 		iPriority=(TProcessPriority)temp;
   947 		{
   838 	}
   948 		char *str=(char *)aStr;
   839 	else {		 
   949 		if (stricmp(str, "low")==0)
   840 		if (stricmp(aStr, "low")==0)
   950 			iPriority=EPriorityLow;
   841 			iPriority=EPriorityLow;
   951 		else if (strnicmp(str, "background", 4)==0)
   842 		else if (strnicmp(aStr, "background", 4)==0)
   952 			iPriority=EPriorityBackground;
   843 			iPriority=EPriorityBackground;
   953 		else if (strnicmp(str, "foreground", 4)==0)
   844 		else if (strnicmp(aStr, "foreground", 4)==0)
   954 			iPriority=EPriorityForeground;
   845 			iPriority=EPriorityForeground;
   955 		else if (stricmp(str, "high")==0)
   846 		else if (stricmp(aStr, "high")==0)
   956 			iPriority=EPriorityHigh;
   847 			iPriority=EPriorityHigh;
   957 		else if (strnicmp(str, "windowserver",3)==0)
   848 		else if (strnicmp(aStr, "windowserver",3)==0)
   958 			iPriority=EPriorityWindowServer;
   849 			iPriority=EPriorityWindowServer;
   959 		else if (strnicmp(str, "fileserver",4)==0)
   850 		else if (strnicmp(aStr, "fileserver",4)==0)
   960 			iPriority=EPriorityFileServer;
   851 			iPriority=EPriorityFileServer;
   961 		else if (strnicmp(str, "realtimeserver",4)==0)
   852 		else if (strnicmp(aStr, "realtimeserver",4)==0)
   962 			iPriority=EPriorityRealTimeServer;
   853 			iPriority=EPriorityRealTimeServer;
   963 		else if (strnicmp(str, "supervisor",3)==0)
   854 		else if (strnicmp(aStr, "supervisor",3)==0)
   964 			iPriority=EPrioritySupervisor;
   855 			iPriority=EPrioritySupervisor;
   965 		else
   856 		else
   966 			return Print(EError, "Unrecognised priority keyword.\n");
   857 			return Print(EError, "Unrecognised priority keyword.\n");
   967 		}
   858 	}
   968 	if (iPriority<EPriorityLow || iPriority>EPrioritySupervisor)
   859 	if (iPriority<EPriorityLow || iPriority>EPrioritySupervisor)
   969 		return Print(EError, "Priority out of range.\n");
   860 		return Print(EError, "Priority out of range.\n");
   970 	iOverrideFlags |= KOverridePriority;
   861 	iOverrideFlags |= KOverridePriority;
   971 	return KErrNone;
   862 	return KErrNone;
   972 	}
   863 }
   973 
   864 
   974 TInt TRomBuilderEntry::SetUid1(TText *aStr)
   865 TInt TRomBuilderEntry::SetUid1(const char* aStr) {
   975 	{
   866 	if (!IsValidNumber(aStr))
   976 	if (isNumber(aStr)==0)
       
   977 		return Print(EError, "Number required as argument for keyword 'uid1'.\n");
   867 		return Print(EError, "Number required as argument for keyword 'uid1'.\n");
   978 	iOverrideFlags |= KOverrideUid1;
   868 	iOverrideFlags |= KOverrideUid1;
   979 	iUid1=getNumber(aStr);
   869 	Val(iUid1,aStr);
   980 	return KErrNone;
   870 	return KErrNone;
   981 	}
   871 }
   982 TInt TRomBuilderEntry::SetUid2(TText *aStr)
   872 TInt TRomBuilderEntry::SetUid2(const char* aStr) {
   983 	{
   873 	if (!IsValidNumber(aStr))
   984 	if (isNumber(aStr)==0)
       
   985 		return Print(EError, "Number required as argument for keyword 'uid2'.\n");
   874 		return Print(EError, "Number required as argument for keyword 'uid2'.\n");
   986 	iOverrideFlags |= KOverrideUid2;
   875 	iOverrideFlags |= KOverrideUid2;
   987 	iUid2=getNumber(aStr);
   876 	Val(iUid2,aStr);
   988 	return KErrNone;
   877 	return KErrNone;
   989 	}
   878 }
   990 TInt TRomBuilderEntry::SetUid3(TText *aStr)
   879 TInt TRomBuilderEntry::SetUid3(const char* aStr) {
   991 	{
   880 	if (!IsValidNumber(aStr))
   992 	if (isNumber(aStr)==0)
       
   993 		return Print(EError, "Number required as argument for keyword 'uid3'.\n");
   881 		return Print(EError, "Number required as argument for keyword 'uid3'.\n");
   994 	iOverrideFlags |= KOverrideUid3;
   882 	iOverrideFlags |= KOverrideUid3;
   995 	iUid3=getNumber(aStr);
   883 	Val(iUid3,aStr);
   996 	return KErrNone;
   884 	return KErrNone;
   997 	}
   885 }
   998 TInt TRomBuilderEntry::SetCallEntryPoint(TBool aState)
   886 TInt TRomBuilderEntry::SetCallEntryPoint(TBool aState) {
   999 	{
       
  1000 	if (aState)
   887 	if (aState)
  1001 		iOverrideFlags|=KOverrideCallEntryPoint;
   888 		iOverrideFlags|=KOverrideCallEntryPoint;
  1002 	else
   889 	else
  1003 		iOverrideFlags|=KOverrideNoCallEntryPoint;
   890 		iOverrideFlags|=KOverrideNoCallEntryPoint;
  1004 	return KErrNone;
   891 	return KErrNone;
  1005 	}
   892 }
  1006 
   893 
  1007 TInt TRomBuilderEntry::SetAttachProcess(TText *aStr)
   894 TInt TRomBuilderEntry::SetAttachProcess(const char* aStr) {
  1008 	{
   895 
  1009 	const char* s=(const char*)aStr;
       
  1010 	TInt nd=0;
   896 	TInt nd=0;
  1011 	if (*s=='\\')
   897 	if (*aStr==SLASH_CHAR) {
  1012 		{
   898 		++aStr;
  1013 		++s;
       
  1014 		++nd;
   899 		++nd;
  1015 		}
   900 	}
  1016 	TInt l=strlen(s);
   901 	size_t l = strlen(aStr);
  1017 	if (l==0)
   902 	if (l == 0)
  1018 		return KErrGeneral;
   903 		return KErrGeneral;
  1019 	const char* ss=s;
   904 	const char* ss=aStr;
  1020 	while(*ss!=0 && *ss!='.') ++ss;
   905 	while(*ss != 0 && *ss!='.') ++ss;
  1021 	int ext=*ss;	// 0 if no extension
   906 	int ext = *ss;	// 0 if no extension
  1022 	iProcessName=new TText[l+2+(ext?0:4)];
   907 	iProcessName=new char[l+2+(ext?0:4)];
  1023 	char* d=(char *)iProcessName;
   908 	char* d=(char *)iProcessName;
  1024 	strcpy(d+1, s);
   909 	strcpy(d+1, aStr);
  1025 	if (!ext)
   910 	if (!ext) {
  1026 		{
       
  1027 		char* t=d+1+l;
   911 		char* t=d+1+l;
  1028 		*t++='.';
   912 		*t++='.';
  1029 		*t++='e';
   913 		*t++='e';
  1030 		*t++='x';
   914 		*t++='x';
  1031 		*t++='e';
   915 		*t++='e';
  1032 		*t++=0;
   916 		*t++=0;
  1033 		}
   917 	}
  1034 	char* dd=d;
   918 	char* dd=d;
  1035 	int ind=nd;
   919 	int ind=nd;
  1036 	while(*dd)
   920 	while(*dd) {
  1037 		{
   921 		while(*dd && *dd!=SLASH_CHAR) ++dd;
  1038 		while(*dd && *dd!='\\') ++dd;
   922 		if (*dd==SLASH_CHAR) {
  1039 		if (*dd=='\\')
       
  1040 			{
       
  1041 			*dd++=0;	// change \ to NUL
   923 			*dd++=0;	// change \ to NUL
  1042 			++nd;		// count path elements
   924 			++nd;		// count path elements
  1043 			}
   925 		}
  1044 		}
   926 	}
  1045 	if (!ind && nd)
   927 	if (!ind && nd)
  1046 		++nd;			// add initial \ if not present
   928 		++nd;			// add initial \ if not present
  1047 	*d=(char)nd;
   929 	*d=(char)nd;
  1048 	return 0;
   930 	return 0;
  1049 	}
   931 }
  1050 
   932 
  1051 TInt TRomBuilderEntry::OpenImageFile()
   933 TInt TRomBuilderEntry::OpenImageFile()
  1052 	{
   934 	{
       
   935 	TInt err = Open(iFileName);
       
   936 	return err;
       
   937 	}
       
   938 TInt TRomBuilderEntry::GetImageFileInfo(TInt aResult)
       
   939 {
       
   940 	TInt err = aResult;
  1053 	Print(ELog,"Loading E32Image file %s \n", iFileName);
   941 	Print(ELog,"Loading E32Image file %s \n", iFileName);
  1054 	TInt err = Open(iFileName);
   942 	if (err != KErrNone) {
  1055 	if (err != KErrNone)
       
  1056 		{
       
  1057 		Print(EError,"File %s is not a valid E32Image file (error %d)\n", iFileName, err);
   943 		Print(EError,"File %s is not a valid E32Image file (error %d)\n", iFileName, err);
  1058 		return err;
   944 		return err;
  1059 		}
   945 	}
  1060 	TUint hdrfmt = iHdr->HeaderFormat();
   946 	TUint hdrfmt = iHdr->HeaderFormat();
  1061 	if (hdrfmt != KImageHdrFmt_V)
   947 	if (hdrfmt != KImageHdrFmt_V) {
  1062 		{
       
  1063 		Print(EError,"%s: Can't load old format binary\n", iFileName);
   948 		Print(EError,"%s: Can't load old format binary\n", iFileName);
  1064 		return KErrNotSupported;
   949 		return KErrNotSupported;
  1065 		}
   950 	}
  1066 	E32ImageHeaderV* h = iHdr;
   951 	E32ImageHeaderV* h = iHdr;
  1067 	
   952 
  1068 	// Overide any settings in the image file with those in the obey file
   953 	// Overide any settings in the image file with those in the obey file
  1069 	if (iOverrideFlags & (KOverrideUid1|KOverrideUid2|KOverrideUid3))
   954 	if (iOverrideFlags & (KOverrideUid1|KOverrideUid2|KOverrideUid3)) {
  1070 		{
       
  1071 		TUint uid1 = h->iUid1;
   955 		TUint uid1 = h->iUid1;
  1072 		TUint uid2 = h->iUid2;
   956 		TUint uid2 = h->iUid2;
  1073 		TUint uid3 = h->iUid3;
   957 		TUint uid3 = h->iUid3;
  1074 		if (iOverrideFlags & KOverrideUid1)
   958 		if (iOverrideFlags & KOverrideUid1)
  1075 			uid1 = iUid1;
   959 			uid1 = iUid1;
  1076 		if (iOverrideFlags & KOverrideUid2)
   960 		if (iOverrideFlags & KOverrideUid2)
  1077 			uid2 = iUid2;
   961 			uid2 = iUid2;
  1078 		if (iOverrideFlags & KOverrideUid3)
   962 		if (iOverrideFlags & KOverrideUid3)
  1079 			uid3 = iUid3;
   963 			uid3 = iUid3;
  1080 		SetUids(TUid::Uid(uid1), TUid::Uid(uid2), TUid::Uid(uid3));
   964 		SetUids(TUid::Uid(uid1), TUid::Uid(uid2), TUid::Uid(uid3));
  1081 		}
   965 	}
  1082 	if (iOverrideFlags & KOverrideStack)
   966 	if (iOverrideFlags & KOverrideStack)
  1083 		h->iStackSize = iStackSize;
   967 		h->iStackSize = iStackSize;
  1084 	if (iOverrideFlags & KOverrideHeapMax)
   968 	if (iOverrideFlags & KOverrideHeapMax)
  1085 		h->iHeapSizeMax = iHeapSizeMax;
   969 		h->iHeapSizeMax = iHeapSizeMax;
  1086 	if (iOverrideFlags & KOverrideHeapMin)
   970 	if (iOverrideFlags & KOverrideHeapMin)
  1087 		h->iHeapSizeMin = iHeapSizeMin;
   971 		h->iHeapSizeMin = iHeapSizeMin;
  1088 	if (iOverrideFlags & KOverridePriority)
   972 	if (iOverrideFlags & KOverridePriority)
  1089 		h->iProcessPriority = (TUint16)iPriority;
   973 		h->iProcessPriority = (TUint16)iPriority;
  1090 	if (iOverrideFlags & KOverrideCapability)
   974 	if (iOverrideFlags & KOverrideCapability)
  1091 		h->iS.iCaps = iS.iCaps;
   975 		h->iS.iCaps = iS.iCaps;
  1092 	for (TInt i=0; i<SCapabilitySet::ENCapW; ++i)
   976 	for (TInt i=0; i<SCapabilitySet::ENCapW; ++i) {
  1093 		{
       
  1094 		h->iS.iCaps[i] |= gPlatSecDisabledCaps[i];
   977 		h->iS.iCaps[i] |= gPlatSecDisabledCaps[i];
  1095 		h->iS.iCaps[i] &= gPlatSecAllCaps[i];
   978 		h->iS.iCaps[i] &= gPlatSecAllCaps[i];
  1096 		}
   979 	}
  1097 
   980 
  1098 	if (iOverrideFlags & KOverrideCodePaged)
   981 	if (iOverrideFlags & KOverrideCodePaged) {
  1099 		{
       
  1100 		h->iFlags &= ~KImageCodeUnpaged;
   982 		h->iFlags &= ~KImageCodeUnpaged;
  1101 		h->iFlags |= KImageCodePaged;
   983 		h->iFlags |= KImageCodePaged;
  1102 		}
   984 	}
  1103 	if (iOverrideFlags & KOverrideCodeUnpaged)
   985 	if (iOverrideFlags & KOverrideCodeUnpaged) {
  1104 		{
       
  1105 		h->iFlags |= KImageCodeUnpaged;
   986 		h->iFlags |= KImageCodeUnpaged;
  1106 		h->iFlags &= ~KImageCodePaged;
   987 		h->iFlags &= ~KImageCodePaged;
  1107 		}
   988 	}
  1108 
   989 
  1109 	if ((TInt)h->iUid1 == KExecutableImageUidValue)
   990 	if ((TInt)h->iUid1 == KExecutableImageUidValue) {
  1110 		{
   991 		if (iOverrideFlags & KOverrideDataPaged) {
  1111 		if (iOverrideFlags & KOverrideDataPaged)
       
  1112 			{
       
  1113 			h->iFlags &= ~KImageDataUnpaged;
   992 			h->iFlags &= ~KImageDataUnpaged;
  1114 			h->iFlags |= KImageDataPaged;
   993 			h->iFlags |= KImageDataPaged;
  1115 			}
   994 		}
  1116 		if (iOverrideFlags & KOverrideDataUnpaged)
   995 		if (iOverrideFlags & KOverrideDataUnpaged) {
  1117 			{
       
  1118 			h->iFlags |= KImageDataUnpaged;
   996 			h->iFlags |= KImageDataUnpaged;
  1119 			h->iFlags &= ~KImageDataPaged;
   997 			h->iFlags &= ~KImageDataPaged;
  1120 			}
   998 		}
  1121 		}
   999 	}
  1122 
  1000 
  1123 	switch(gCodePagingOverride)
  1001 	switch(gCodePagingOverride) {
  1124 		{
       
  1125 	case EKernelConfigPagingPolicyNoPaging:
  1002 	case EKernelConfigPagingPolicyNoPaging:
  1126 		h->iFlags |= KImageCodeUnpaged;
  1003 		h->iFlags |= KImageCodeUnpaged;
  1127 		h->iFlags &= ~KImageCodePaged;
  1004 		h->iFlags &= ~KImageCodePaged;
  1128 		break;
  1005 		break;
  1129 	case EKernelConfigPagingPolicyAlwaysPage:
  1006 	case EKernelConfigPagingPolicyAlwaysPage:
  1136 		break;
  1013 		break;
  1137 	case EKernelConfigPagingPolicyDefaultPaged:
  1014 	case EKernelConfigPagingPolicyDefaultPaged:
  1138 		if(!(h->iFlags&(KImageCodeUnpaged|KImageCodePaged)))
  1015 		if(!(h->iFlags&(KImageCodeUnpaged|KImageCodePaged)))
  1139 			h->iFlags |= KImageCodePaged;
  1016 			h->iFlags |= KImageCodePaged;
  1140 		break;
  1017 		break;
  1141 		}
  1018 	}
  1142 	switch(gDataPagingOverride)
  1019 	switch(gDataPagingOverride) {
  1143 		{
       
  1144 	case EKernelConfigPagingPolicyNoPaging:
  1020 	case EKernelConfigPagingPolicyNoPaging:
  1145 		h->iFlags |= KImageDataUnpaged;
  1021 		h->iFlags |= KImageDataUnpaged;
  1146 		h->iFlags &= ~KImageDataPaged;
  1022 		h->iFlags &= ~KImageDataPaged;
  1147 		break;
  1023 		break;
  1148 	case EKernelConfigPagingPolicyAlwaysPage:
  1024 	case EKernelConfigPagingPolicyAlwaysPage:
  1155 		break;
  1031 		break;
  1156 	case EKernelConfigPagingPolicyDefaultPaged:
  1032 	case EKernelConfigPagingPolicyDefaultPaged:
  1157 		if(!(h->iFlags&(KImageDataUnpaged|KImageDataPaged)))
  1033 		if(!(h->iFlags&(KImageDataUnpaged|KImageDataPaged)))
  1158 			h->iFlags |= KImageDataPaged;
  1034 			h->iFlags |= KImageDataPaged;
  1159 		break;
  1035 		break;
  1160 		}
  1036 	}
  1161 	
  1037 
  1162 	h->iCompressionType=KUidCompressionDeflate; // XIP images are always uncompressed
  1038 	h->iCompressionType=KUidCompressionDeflate; // XIP images are always uncompressed
  1163 	
  1039 
  1164 	Print(ELog,"\t\tcompression format:0x%08x \n", h->iCompressionType);
  1040 	Print(ELog,"\t\tcompression format:0x%08x \n", h->iCompressionType);
  1165 	if (gLogLevel & LOG_LEVEL_COMPRESSION_INFO)
  1041 	if (gLogLevel & LOG_LEVEL_COMPRESSION_INFO)
  1166 		Print(ELog,"\t\tgCompress:%d, gCompressionMethod: 0x%08x \n", gEnableCompress , gCompressionMethod);
  1042 		Print(ELog,"\t\tgCompress:%d, gCompressionMethod: 0x%08x \n", gEnableCompress , gCompressionMethod);
  1167 
  1043 
  1168 
  1044 
  1178 	iCodeSection.iSize    = h->iTextSize;
  1054 	iCodeSection.iSize    = h->iTextSize;
  1179 	iCodeSection.iFilePtr = iData + iOrigHdr->iCodeOffset;
  1055 	iCodeSection.iFilePtr = iData + iOrigHdr->iCodeOffset;
  1180 
  1056 
  1181 	TUint impfmt = h->ImportFormat();
  1057 	TUint impfmt = h->ImportFormat();
  1182 
  1058 
  1183 	if (impfmt==KImageImpFmt_PE || impfmt==KImageImpFmt_PE2)
  1059 	if (impfmt==KImageImpFmt_PE || impfmt==KImageImpFmt_PE2) {
  1184 		{
       
  1185 		TInt nimports = NumberOfImports();
  1060 		TInt nimports = NumberOfImports();
  1186 		if (nimports)
  1061 		if (nimports) {
  1187 			{
  1062 			iImportAddressTableSection.iSize    = (nimports+1)* sizeof(TLinAddr*);
  1188 			iImportAddressTableSection.iSize    = (nimports+1)*4;
       
  1189 			iImportAddressTableSection.iFilePtr = iData + iOrigHdr->iCodeOffset + iOrigHdr->iTextSize;
  1063 			iImportAddressTableSection.iFilePtr = iData + iOrigHdr->iCodeOffset + iOrigHdr->iTextSize;
  1190 			iIATRefs = new TLinAddr*[nimports+1];
  1064 			iIATRefs = reinterpret_cast<TLinAddr **>(new char[iImportAddressTableSection.iSize ]);
  1191 			memcpy(iIATRefs, iImportAddressTableSection.iFilePtr, (nimports+1)*sizeof(TLinAddr*));
  1065 			memcpy(iIATRefs, iImportAddressTableSection.iFilePtr, iImportAddressTableSection.iSize);
  1192 			}
  1066 		}
  1193 
  1067 
  1194 		if (h->iExportDirCount)
  1068 		if (h->iExportDirCount) {
  1195 			{
       
  1196 			iExportDirSection.iSize    = h->iExportDirCount*4;
  1069 			iExportDirSection.iSize    = h->iExportDirCount*4;
  1197 			iExportDirSection.iFilePtr = iData + iOrigHdr->iExportDirOffset;
  1070 			iExportDirSection.iFilePtr = iData + iOrigHdr->iExportDirOffset;
  1198 			}
  1071 		}
  1199 
  1072 
  1200 		// assertion - there's no rdata between IAT and Export Directory
  1073 		// assertion - there's no rdata between IAT and Export Directory
  1201 		TInt rdatasize = h->iCodeSize;		// overall "readonly" size
  1074 		TInt rdatasize = h->iCodeSize;		// overall "readonly" size
  1202 		rdatasize -= iCodeSection.iSize;				// text
  1075 		rdatasize -= iCodeSection.iSize;				// text
  1203 		rdatasize -= iImportAddressTableSection.iSize;	// IAT plus trailing 0
  1076 		rdatasize -= iImportAddressTableSection.iSize;	// IAT plus trailing 0
  1204 		rdatasize -= iExportDirSection.iSize;			// export data
  1077 		rdatasize -= iExportDirSection.iSize;			// export data
  1205 
  1078 
  1206 		if (rdatasize != 0)
  1079 		if (rdatasize != 0) {
  1207 			{
       
  1208 			Print(EWarning, "Unexpected code in %s: %d bytes unexplained\n", iFileName, rdatasize);
  1080 			Print(EWarning, "Unexpected code in %s: %d bytes unexplained\n", iFileName, rdatasize);
  1209 			// expand the code to cover text+IAT+rdata
  1081 			// expand the code to cover text+IAT+rdata
  1210 			iCodeSection.iSize = h->iCodeSize - iExportDirSection.iSize;
  1082 			iCodeSection.iSize = h->iCodeSize - iExportDirSection.iSize;
  1211 			}
  1083 		}
  1212 		else
  1084 		else {
  1213 			{
       
  1214 			if (USE_IAT_FOR_IMPORTS)
  1085 			if (USE_IAT_FOR_IMPORTS)
  1215 				iCodeSection.iSize += iImportAddressTableSection.iSize;	// include IAT
  1086 				iCodeSection.iSize += iImportAddressTableSection.iSize;	// include IAT
  1216 			}
  1087 		}
  1217 		}
  1088 	}
  1218 	else
  1089 	else {
  1219 		{
       
  1220 		// ELF-derived images have no IAT and the export directory is included in the code section
  1090 		// ELF-derived images have no IAT and the export directory is included in the code section
  1221 		iImportAddressTableSection.iSize    = 0;
  1091 		iImportAddressTableSection.iSize    = 0;
  1222 		iImportAddressTableSection.iFilePtr = NULL;
  1092 		iImportAddressTableSection.iFilePtr = NULL;
  1223 		iExportDirSection.iSize    = 0;
  1093 		iExportDirSection.iSize    = 0;
  1224 		iExportDirSection.iFilePtr = NULL;
  1094 		iExportDirSection.iFilePtr = NULL;
  1225 		}
  1095 	}
  1226 
  1096 
  1227 	if (h->iDataSize)
  1097 	if (h->iDataSize) {
  1228 		{
       
  1229 		iDataSection.iSize    = h->iDataSize;
  1098 		iDataSection.iSize    = h->iDataSize;
  1230 		iDataSection.iFilePtr = iData + iOrigHdr->iDataOffset;
  1099 		iDataSection.iFilePtr = iData + iOrigHdr->iDataOffset;
  1231 		}
  1100 	}
  1232 
  1101 
  1233 	iRomNode->iRomFile->iTotalDataBss = h->iDataSize + h->iBssSize;
  1102 	iRomNode->iRomFile->iTotalDataBss = h->iDataSize + h->iBssSize;
  1234 	iS = h->iS;
  1103 	iS = h->iS;
  1235 	if (iVersionPresentInName && iVersionInName != h->ModuleVersion())
  1104 	if (iVersionPresentInName && iVersionInName != h->ModuleVersion()) {
  1236 		{
       
  1237 		Print(EError,"%s: Version in name (%d.%d) does not match version in header (%d.%d)\n", iFileName,
  1105 		Print(EError,"%s: Version in name (%d.%d) does not match version in header (%d.%d)\n", iFileName,
  1238 			iVersionInName>>16, iVersionInName&0x0000ffffu, h->ModuleVersion()>>16, h->ModuleVersion()&0x0000ffffu);
  1106 			iVersionInName>>16, iVersionInName&0x0000ffffu, h->ModuleVersion()>>16, h->ModuleVersion()&0x0000ffffu);
  1239 		return KErrGeneral;
  1107 		return KErrGeneral;
  1240 		}
  1108 	}
  1241 	return KErrNone;
  1109 	return KErrNone;
  1242 	}
  1110 }
  1243 
  1111 
  1244 TInt TRomNode::NameCpy(char* aDest)
       
  1245 //
       
  1246 // Safely copy a file name in the rom entry
       
  1247 //
       
  1248 	{
       
  1249 
       
  1250 	if ((aDest==NULL) || (iName==NULL))
       
  1251 		return 0;
       
  1252 	if (Unicode)
       
  1253 		{
       
  1254 		const unsigned char* pSourceByte=iName;
       
  1255 		unsigned char* pTargetByte=(unsigned char*)aDest;
       
  1256 		for (;;)
       
  1257 			{
       
  1258 			const TUint sourceByte=*pSourceByte;
       
  1259 			if (sourceByte==0)
       
  1260 				{
       
  1261 				*pTargetByte=0;
       
  1262 				*(pTargetByte+1)=0;
       
  1263 				break;
       
  1264 				}
       
  1265 			if ((sourceByte&0x80)==0)
       
  1266 				{
       
  1267 				*pTargetByte=(unsigned char)sourceByte;
       
  1268 				++pTargetByte;
       
  1269 				*pTargetByte=0;
       
  1270 				++pTargetByte;
       
  1271 				++pSourceByte;
       
  1272 				}
       
  1273 			else if ((sourceByte&0xe0)==0xc0)
       
  1274 				{
       
  1275 				++pSourceByte;
       
  1276 				const TUint secondSourceByte=*pSourceByte;
       
  1277 				if ((secondSourceByte&0xc0)!=0x80)
       
  1278 					{
       
  1279 					Print(EError, "Bad UTF-8 '%s'", iName);
       
  1280 					exit(671);
       
  1281 					}
       
  1282 				*pTargetByte=(unsigned char)((secondSourceByte&0x3f)|((sourceByte&0x03)<<6));
       
  1283 				++pTargetByte;
       
  1284 				*pTargetByte=(unsigned char)((sourceByte>>2)&0x07);
       
  1285 				++pTargetByte;
       
  1286 				++pSourceByte;
       
  1287 				}
       
  1288 			else if ((sourceByte&0xf0)==0xe0)
       
  1289 				{
       
  1290 				++pSourceByte;
       
  1291 				const TUint secondSourceByte=*pSourceByte;
       
  1292 				if ((secondSourceByte&0xc0)!=0x80)
       
  1293 					{
       
  1294 					Print(EError, "Bad UTF-8 '%s'", iName);
       
  1295 					exit(672);
       
  1296 					}
       
  1297 				++pSourceByte;
       
  1298 				const TUint thirdSourceByte=*pSourceByte;
       
  1299 				if ((thirdSourceByte&0xc0)!=0x80)
       
  1300 					{
       
  1301 					Print(EError, "Bad UTF-8 '%s'", iName);
       
  1302 					exit(673);
       
  1303 					}
       
  1304 				*pTargetByte=(unsigned char)((thirdSourceByte&0x3f)|((secondSourceByte&0x03)<<6));
       
  1305 				++pTargetByte;
       
  1306 				*pTargetByte=(unsigned char)(((secondSourceByte>>2)&0x0f)|((sourceByte&0x0f)<<4));
       
  1307 				++pTargetByte;
       
  1308 				++pSourceByte;
       
  1309 				}
       
  1310 			else
       
  1311 				{
       
  1312 				Print(EError, "Bad UTF-8 '%s'", iName);
       
  1313 				exit(674);
       
  1314 				}
       
  1315 			}
       
  1316 		const TInt numberOfBytesInTarget=(pTargetByte-(unsigned char*)aDest); // this number excludes the trailing null-terminator
       
  1317 		if (numberOfBytesInTarget%2!=0)
       
  1318 			{
       
  1319 			Print(EError, "Internal error");
       
  1320 			exit(675);
       
  1321 			}
       
  1322 		return numberOfBytesInTarget/2; // returns the length of aDest (in UTF-16 characters for Unicode, not bytes)
       
  1323 		}
       
  1324 	strcpy(aDest,(const char*)iName);
       
  1325 	return strlen((const char*)iName);
       
  1326 	}
       
  1327 
       
  1328 TInt TRomBuilderEntry::SizeInRom()
       
  1329 //
  1112 //
  1330 // Approximate the required size of the file when rommed
  1113 // Approximate the required size of the file when rommed
  1331 //
  1114 //
  1332 	{
  1115 TInt TRomBuilderEntry::SizeInRom() {
  1333 
       
  1334 	TInt size1, size2;
  1116 	TInt size1, size2;
  1335 	SizeInSections(size1,size2);
  1117 	SizeInSections(size1,size2);
  1336 	return size1+size2;
  1118 	return size1+size2;
  1337 	}
  1119 }
  1338 
  1120 //
  1339 void TRomBuilderEntry::LoadToRom()
  1121 //
  1340 //
  1122 //
  1341 //
  1123 void TRomBuilderEntry::LoadToRom() {
  1342 //
       
  1343 	{
       
  1344 	// Copy fixed stuff into iRomImageHeader
  1124 	// Copy fixed stuff into iRomImageHeader
  1345 	E32ImageHeaderV* h = iHdr;
  1125 	E32ImageHeaderV* h = iHdr;
  1346 	const TUint KRomFlagMask = KImageDll | KImageNoCallEntryPoint | KImageFixedAddressExe | KImageNmdExpData | KImageDataPagingMask;
  1126 	const TUint KRomFlagMask = KImageDll | KImageNoCallEntryPoint | KImageFixedAddressExe | KImageNmdExpData | KImageDataPagingMask;
  1347 	TUint romflags = h->iFlags & KRomFlagMask;
  1127 	TUint romflags = h->iFlags & KRomFlagMask;
  1348 	TUint abi = h->ABI();
  1128 	TUint abi = h->ABI();
  1368 	iRomImageHeader->iHeapSizeMax       = h->iHeapSizeMax;
  1148 	iRomImageHeader->iHeapSizeMax       = h->iHeapSizeMax;
  1369 	iRomImageHeader->iStackSize         = h->iStackSize;
  1149 	iRomImageHeader->iStackSize         = h->iStackSize;
  1370 	iRomImageHeader->iDllRefTable       = (TDllRefTable*)(iDllRefTableRange.iImageAddr);
  1150 	iRomImageHeader->iDllRefTable       = (TDllRefTable*)(iDllRefTableRange.iImageAddr);
  1371 	iRomImageHeader->iExportDirCount    = h->iExportDirCount;
  1151 	iRomImageHeader->iExportDirCount    = h->iExportDirCount;
  1372 	iRomImageHeader->iExportDir         = (impfmt==KImageImpFmt_ELF) ?
  1152 	iRomImageHeader->iExportDir         = (impfmt==KImageImpFmt_ELF) ?
  1373 											iCodeSection.iRunAddr + (h->iExportDirOffset - h->iCodeOffset)
  1153 		iCodeSection.iRunAddr + (h->iExportDirOffset - h->iCodeOffset)
  1374 											: iExportDirSection.iRunAddr;
  1154 		: iExportDirSection.iRunAddr;
  1375 	iRomImageHeader->iS					= h->iS;
  1155 	iRomImageHeader->iS					= h->iS;
  1376 	iRomImageHeader->iToolsVersion		= h->iToolsVersion;
  1156 	iRomImageHeader->iToolsVersion		= h->iToolsVersion;
  1377 	iRomImageHeader->iModuleVersion		= h->ModuleVersion();
  1157 	iRomImageHeader->iModuleVersion		= h->ModuleVersion();
  1378 	iRomImageHeader->iFlags             = romflags | iRomImageFlags;
  1158 	iRomImageHeader->iFlags             = romflags | iRomImageFlags;
  1379 	iRomImageHeader->iPriority          = h->ProcessPriority();
  1159 	iRomImageHeader->iPriority          = h->ProcessPriority();
  1383 	iRomImageHeader->iExceptionDescriptor = 0;
  1163 	iRomImageHeader->iExceptionDescriptor = 0;
  1384 	TUint32 xd = h->iExceptionDescriptor;
  1164 	TUint32 xd = h->iExceptionDescriptor;
  1385 	if ((xd & 1) && (xd != 0xffffffffu))
  1165 	if ((xd & 1) && (xd != 0xffffffffu))
  1386 		iRomImageHeader->iExceptionDescriptor = (xd & ~1) + iRomImageHeader->iCodeAddress;
  1166 		iRomImageHeader->iExceptionDescriptor = (xd & ~1) + iRomImageHeader->iCodeAddress;
  1387 
  1167 
  1388 	if (iPreferred)
  1168 	if (iPreferred) {
  1389 		{
       
  1390 		iRomImageHeader->iModuleVersion	&= ~0xffffu;
  1169 		iRomImageHeader->iModuleVersion	&= ~0xffffu;
  1391 		iRomImageHeader->iModuleVersion	|= 0x8000u;
  1170 		iRomImageHeader->iModuleVersion	|= 0x8000u;
  1392 		}
  1171 	}
  1393 
  1172 
  1394 	// Relocate the file to reflect the new addresses
  1173 	// Relocate the file to reflect the new addresses
  1395 	Relocate();
  1174 	Relocate();
  1396 
  1175 
  1397 	// Copy the sections
  1176 	// Copy the sections
  1398 	iCodeSection.Load();
  1177 	iCodeSection.Load();
  1399 	iExportDirSection.Load();
  1178 	iExportDirSection.Load();
  1400 	iDataSection.Load();
  1179 	iDataSection.Load();
  1401 	}
  1180 }
  1402 
       
  1403 void TRomBuilderEntry::Relocate()
       
  1404 //
  1181 //
  1405 // Relocates the iData to new Code and Data addresses
  1182 // Relocates the iData to new Code and Data addresses
  1406 //	
  1183 //
  1407 	{
  1184 void TRomBuilderEntry::Relocate() {
  1408 	TUint codeDelta=iRomImageHeader->iCodeAddress       - iHdr->iCodeBase;
  1185 	TUint codeDelta=iRomImageHeader->iCodeAddress       - iHdr->iCodeBase;
  1409 	TUint dataDelta=iRomImageHeader->iDataBssLinearBase - iHdr->iDataBase;
  1186 	TUint dataDelta=iRomImageHeader->iDataBssLinearBase - iHdr->iDataBase;
  1410 
  1187 
  1411 	// code section (text, IAT, export directory)
  1188 	// code section (text, IAT, export directory)
  1412 
  1189 
  1413 	if (iOrigHdr->iCodeRelocOffset)
  1190 	if (iOrigHdr->iCodeRelocOffset)
  1414 		RelocateSection(iData + iOrigHdr->iCodeOffset, iData + iOrigHdr->iCodeRelocOffset,
  1191 		RelocateSection(iData + iOrigHdr->iCodeOffset, iData + iOrigHdr->iCodeRelocOffset,
  1415 			codeDelta, dataDelta, (char*)iCodeSection.iImagePtr, iIATRefs);
  1192 		codeDelta, dataDelta, (char*)iCodeSection.iImagePtr, iIATRefs);
  1416 
  1193 
  1417 	// data section 
  1194 	// data section 
  1418 
  1195 
  1419 	if (iOrigHdr->iDataRelocOffset)
  1196 	if (iOrigHdr->iDataRelocOffset)
  1420 		RelocateSection(iData + iOrigHdr->iDataOffset, iData + iOrigHdr->iDataRelocOffset, 
  1197 		RelocateSection(iData + iOrigHdr->iDataOffset, iData + iOrigHdr->iDataRelocOffset, 
  1421 			codeDelta, dataDelta, (char*)iDataSection.iImagePtr, iIATRefs);
  1198 		codeDelta, dataDelta, (char*)iDataSection.iImagePtr, iIATRefs);
  1422 
  1199 
  1423 	// export directory (only for PE-derived files)
  1200 	// export directory (only for PE-derived files)
  1424 	if (iExportDirSection.iSize)
  1201 	if (iExportDirSection.iSize) {
  1425 		{
       
  1426 		TLinAddr* ptr=(TLinAddr*)(iData + iOrigHdr->iExportDirOffset);
  1202 		TLinAddr* ptr=(TLinAddr*)(iData + iOrigHdr->iExportDirOffset);
  1427 
  1203 
  1428 		TLinAddr textStart = iHdr->iCodeBase;
  1204 		TLinAddr textStart = iHdr->iCodeBase;
  1429 		TLinAddr textFinish = textStart + iHdr->iTextSize;
  1205 		TLinAddr textFinish = textStart + iHdr->iTextSize;
  1430 		TLinAddr dataStart = textStart + iHdr->iCodeSize;
  1206 		TLinAddr dataStart = textStart + iHdr->iCodeSize;
  1431 		TLinAddr dataFinish = dataStart + iHdr->iDataSize + iHdr->iBssSize;
  1207 		TLinAddr dataFinish = dataStart + iHdr->iDataSize + iHdr->iBssSize;
  1432 	 
  1208 
  1433 		TInt i;
  1209 		TInt i;
  1434 		for (i=0; i<iHdr->iExportDirCount; i++, ptr++)
  1210 		for (i=0; i<iHdr->iExportDirCount; i++, ptr++) {
  1435 			{
       
  1436 			TLinAddr data=*ptr+textStart;
  1211 			TLinAddr data=*ptr+textStart;
  1437 			if ((data>=textStart) && (data<textFinish))
  1212 			if ((data>=textStart) && (data<textFinish))
  1438 				*ptr=data+codeDelta; // export something from the text/rdata section
  1213 				*ptr=data+codeDelta; // export something from the text/rdata section
  1439 			else if ((data>=dataStart) && (data<dataFinish))
  1214 			else if ((data>=dataStart) && (data<dataFinish))
  1440 				*ptr=data+dataDelta; // export some data or bss item
  1215 				*ptr=data+dataDelta; // export some data or bss item
  1441 			else
  1216 			else {
  1442 				{
       
  1443 				Print(EWarning, "Export directory in %s: item %d -> %08x, which is not text or data!\n", iFileName, i, data);
  1217 				Print(EWarning, "Export directory in %s: item %d -> %08x, which is not text or data!\n", iFileName, i, data);
  1444 				*ptr=0x13;	// unlucky for some
  1218 				*ptr=0x13;	// unlucky for some
  1445 				}
       
  1446 			}
  1219 			}
  1447 		}
  1220 		}
       
  1221 	}
  1448 
  1222 
  1449 	// Replace absent exports with 0
  1223 	// Replace absent exports with 0
  1450 	TLinAddr* ptr = (TLinAddr*)(iData + iOrigHdr->iExportDirOffset);
  1224 	TLinAddr* ptr = (TLinAddr*)(iData + iOrigHdr->iExportDirOffset);
  1451 	TInt i;
  1225 	TInt i;
  1452 	for (i=0; i<iHdr->iExportDirCount; i++, ptr++)
  1226 	for (i=0; i<iHdr->iExportDirCount; i++, ptr++) {
  1453 		{
       
  1454 		if ( !( iExportBitMap[i>>3] & (1u << (i&7)) ) )
  1227 		if ( !( iExportBitMap[i>>3] & (1u << (i&7)) ) )
  1455 			*ptr = 0;
  1228 			*ptr = 0;
  1456 		}
  1229 	}
  1457 
  1230 
  1458 	// Update E32ImageHeader, in case we want to do this process again later
  1231 	// Update E32ImageHeader, in case we want to do this process again later
  1459 
  1232 
  1460 	iHdr->iCodeBase += codeDelta;
  1233 	iHdr->iCodeBase += codeDelta;
  1461 	iHdr->iDataBase += dataDelta;
  1234 	iHdr->iDataBase += dataDelta;
  1462 	}
  1235 }
  1463 
  1236 
  1464 
  1237 
  1465 
       
  1466 
       
  1467 TInt TRomBuilderEntry::FixupImports(E32Rom& aRom)
       
  1468 //
  1238 //
  1469 // Modify the import stubs to point directly into the export directory of the corresponding DLLs
  1239 // Modify the import stubs to point directly into the export directory of the corresponding DLLs
  1470 // using the back pointers captured by detecting relocations referring to the Import Address Table
  1240 // using the back pointers captured by detecting relocations referring to the Import Address Table
  1471 // The old-style Import Address Table behaviour can be retained by specifying the "keepIAT" attribute.
  1241 // The old-style Import Address Table behaviour can be retained by specifying the "keepIAT" attribute.
  1472 //
  1242 //
  1473 	{
  1243 
       
  1244 TInt TRomBuilderEntry::FixupImports(E32Rom& aRom) {
  1474 	if (iHdr->iImportOffset == 0)
  1245 	if (iHdr->iImportOffset == 0)
  1475 		return KErrNone;	// nothing to do
  1246 		return KErrNone;	// nothing to do
  1476 
  1247 
  1477 	
  1248 
  1478 
  1249 
  1479 	TUint impfmt = iHdr->ImportFormat();
  1250 	TUint impfmt = iHdr->ImportFormat();
  1480 	TUint my_abi = iHdr->ABI();
  1251 	TUint my_abi = iHdr->ABI();
  1481 	TRACE(TIMPORT,Print(ELog,"%40s[%08x] flags %08x\n",iFileName,(TUint)iHardwareVariant,iHdr->iFlags));
  1252 	TRACE(TIMPORT,Print(ELog,"%40s[%08x] flags %08x\n",iFileName,(TUint)iHardwareVariant,iHdr->iFlags));
  1482 	const E32ImportSection* importsection = (const E32ImportSection*)(iData + iOrigHdr->iImportOffset);
  1253 	const E32ImportSection* importsection = (const E32ImportSection*)(iData + iOrigHdr->iImportOffset);
  1483 	TLinAddr **iatRef=iIATRefs;
  1254 	TLinAddr **iatRef=iIATRefs;
  1484 	TAddressRange iatRange = iCodeSection;
  1255 	TAddressRange iatRange = iCodeSection;
  1485 	iatRange.Move(iHdr->iTextSize);
  1256 	iatRange.Move(iHdr->iTextSize);
  1486 	if (USE_IAT_FOR_IMPORTS)
  1257 	if (USE_IAT_FOR_IMPORTS) {
  1487 		{
       
  1488 		if (impfmt == KImageImpFmt_ELF)
  1258 		if (impfmt == KImageImpFmt_ELF)
  1489 			return Print(EError, "Can't retain IAT for %s since it never existed\n", iFileName);
  1259 			return Print(EError, "Can't retain IAT for %s since it never existed\n", iFileName);
  1490 		if (iRomSectionNumber==0 && aRom.iObey->iSectionPosition!=-1)
  1260 		if (iRomSectionNumber==0 && aRom.iObey->iSectionPosition!=-1)
  1491 			return Print(EError, "Can't retain IAT for %s in first section - not yet implemented\n", iFileName);
  1261 			return Print(EError, "Can't retain IAT for %s in first section - not yet implemented\n", iFileName);
  1492 		Print(ELog, "%s has IAT at %08x\n", iFileName, iatRange.iRunAddr);
  1262 		Print(ELog, "%s has IAT at %08x\n", iFileName, iatRange.iRunAddr);
  1493 		}
  1263 	}
  1494 	const E32ImportBlock* b = (const E32ImportBlock*)(importsection + 1);
  1264 	const E32ImportBlock* b = (const E32ImportBlock*)(importsection + 1);
  1495 	TInt i = iHdr->iDllRefTableCount;
  1265 	TInt i = iHdr->iDllRefTableCount;
  1496 	TInt numberOfImports=0;
  1266 	TInt numberOfImports=0;
  1497 	TUint *impOrdinalP = (TUint*)iImportAddressTableSection.iFilePtr;	// points to original IAT in file
  1267 	TUint *impOrdinalP = (TUint*)iImportAddressTableSection.iFilePtr;	// points to original IAT in file
  1498 	while (i-->0)
  1268 	while (i-->0) {
  1499 		{
       
  1500 		char* dllname = (char*)importsection + b->iOffsetOfDllName;
  1269 		char* dllname = (char*)importsection + b->iOffsetOfDllName;
  1501 		TDllFindInfo find_info(dllname, this);
  1270 		TDllFindInfo find_info(dllname, this);
  1502 		TBool fallback;
  1271 		TBool fallback;
  1503 		TRomNode* romnode = aRom.FindImageFileByName(find_info, EFalse, fallback);
  1272 		TRomNode* romnode = aRom.FindImageFileByName(find_info, EFalse, fallback);
  1504 		if (!romnode)
  1273 		if (!romnode) {
  1505 			{
       
  1506 			Print(EError, "Can't fixup imports for\n\t%s\nbecause\n\t%s\nis not in rom.\n",
  1274 			Print(EError, "Can't fixup imports for\n\t%s\nbecause\n\t%s\nis not in rom.\n",
  1507 						 (const char*)TModuleName(this), (const char*)TModuleName(find_info));
  1275 				(const char*)TModuleName(this), (const char*)TModuleName(find_info));
  1508 			aRom.FindImageFileByName(find_info, ETrue, fallback);
  1276 			aRom.FindImageFileByName(find_info, ETrue, fallback);
  1509 			return KErrGeneral;
  1277 			return KErrGeneral;
  1510 			}
  1278 		}
  1511 		TRomFile* dll=romnode->iRomFile;
  1279 		TRomFile* dll=romnode->iRomFile;
  1512 		TRACE(TIMPORT,Print(ELog,"%s importing from %s\n", (const char*)TModuleName(this), (const char*)TModuleName(find_info)));
  1280 		TRACE(TIMPORT,Print(ELog,"%s importing from %s\n", (const char*)TModuleName(this), (const char*)TModuleName(find_info)));
  1513 		if (romnode->ABI() != my_abi)
  1281 		if (romnode->ABI() != my_abi) {
  1514 			{
       
  1515 			Print(EWarning, "File %s links to %s with different ABI\n", (const char*)TModuleName(this), (const char*)TModuleName(find_info));
  1282 			Print(EWarning, "File %s links to %s with different ABI\n", (const char*)TModuleName(this), (const char*)TModuleName(find_info));
  1516 			}
  1283 		}
  1517 		TInt j;
  1284 		TInt j;
  1518 		numberOfImports += b->iNumberOfImports;
  1285 		numberOfImports += b->iNumberOfImports;
  1519 		if (impfmt==KImageImpFmt_ELF)
  1286 		if (impfmt==KImageImpFmt_ELF)
  1520 			impOrdinalP = (TUint*)(b->Imports());	// for ELF must look in import block
  1287 			impOrdinalP = (TUint*)(b->Imports());	// for ELF must look in import block
  1521 		char* codeBase = (char*)iCodeSection.iImagePtr;
  1288 		char* codeBase = (char*)iCodeSection.iImagePtr;
  1522 		for (j=0; j<b->iNumberOfImports; j++)
  1289 		for (j=0; j<b->iNumberOfImports; j++) {
  1523 			{
       
  1524 			TLinAddr exportAddr = 0xdeadbeef;
  1290 			TLinAddr exportAddr = 0xdeadbeef;
  1525 			TLinAddr exporter = 0xdeadbeef;
  1291 			TLinAddr exporter = 0xdeadbeef;
  1526 			TUint impOrdinal = *impOrdinalP;
  1292 			TUint impOrdinal = *impOrdinalP;
  1527 			TUint impOffset = 0;
  1293 			TUint impOffset = 0;
  1528 			if (impfmt==KImageImpFmt_ELF)
  1294 			if (impfmt==KImageImpFmt_ELF) {
  1529 				{
       
  1530 				TUint impd = *(TUint*)(codeBase + impOrdinal);
  1295 				TUint impd = *(TUint*)(codeBase + impOrdinal);
  1531 				impOrdinal = impd & 0xffff;
  1296 				impOrdinal = impd & 0xffff;
  1532 				impOffset = impd >> 16;
  1297 				impOffset = impd >> 16;
  1533 				}
  1298 			}
  1534 			TRACE(TIMPORT,Print(ELog,"Ordinal %d\n", impOrdinal));
  1299 			TRACE(TIMPORT,Print(ELog,"Ordinal %d\n", impOrdinal));
  1535 			TInt ret=dll->AddressFromOrdinal(exporter, exportAddr, impOrdinal);
  1300 			TInt ret=dll->AddressFromOrdinal(exporter, exportAddr, impOrdinal);
  1536 			TRACE(TIMPORT,Print(ELog,"export %08x exporter %08x\n",exportAddr,exporter));
  1301 			TRACE(TIMPORT,Print(ELog,"export %08x exporter %08x\n",exportAddr,exporter));
  1537 			if (ret!=KErrNone)
  1302 			if (ret!=KErrNone) {
  1538 				{
       
  1539 				Print(EError, "%s wants ordinal %d from %s which only exports %d functions\n",
  1303 				Print(EError, "%s wants ordinal %d from %s which only exports %d functions\n",
  1540 					iFileName, impOrdinal, 	(const char*)TModuleName(find_info), dll->ExportDirCount());
  1304 					iFileName, impOrdinal, 	(const char*)TModuleName(find_info), dll->ExportDirCount());
  1541 				exporter=0x13;	// unlucky for some...
  1305 				exporter=0x13;	// unlucky for some...
  1542 				exportAddr=0x13;
  1306 				exportAddr=0x13;
  1543 				}
  1307 			}
  1544 			else if (exportAddr == 0 && impOrdinal != 0)
  1308 			else if (exportAddr == 0 && impOrdinal != 0) {
  1545 				{
       
  1546 				Print(EError, "%s wants ordinal %d from %s which is absent\n",
  1309 				Print(EError, "%s wants ordinal %d from %s which is absent\n",
  1547 					iFileName, impOrdinal, 	(const char*)TModuleName(find_info));
  1310 					iFileName, impOrdinal, 	(const char*)TModuleName(find_info));
  1548 				exporter=0x13;	// unlucky for some...
  1311 				exporter=0x13;	// unlucky for some...
  1549 				exportAddr=0x13;
  1312 				exportAddr=0x13;
  1550 				}
  1313 			}
  1551 			if (USE_IAT_FOR_IMPORTS)
  1314 			if (USE_IAT_FOR_IMPORTS) {
  1552 				{
       
  1553 				// must be PE-derived
  1315 				// must be PE-derived
  1554 				*iatRef=(unsigned long*)exportAddr; //iatRange.iRunAddr;					// point into IAT ...
  1316 				*iatRef=(unsigned long*)exportAddr; //iatRange.iRunAddr;					// point into IAT ...
  1555 				*(TLinAddr*)(iatRange.iImagePtr)=exportAddr;	// ... which has a copy of the export
  1317 				*(TLinAddr*)(iatRange.iImagePtr)=exportAddr;	// ... which has a copy of the export
  1556 				iatRange.Move(sizeof(TLinAddr));
  1318 				iatRange.Move(sizeof(TLinAddr));
  1557 				iatRef++;
  1319 				iatRef++;
  1558 				}
  1320 			}
  1559 			else if (impfmt==KImageImpFmt_PE || impfmt==KImageImpFmt_PE2)
  1321 			else if (impfmt==KImageImpFmt_PE || impfmt==KImageImpFmt_PE2) {
  1560 				{
       
  1561 				**iatRef=exporter;	// point directly into export directory
  1322 				**iatRef=exporter;	// point directly into export directory
  1562 				iatRef++;
  1323 				iatRef++;
  1563 				}
  1324 			}
  1564 			else
  1325 			else {
  1565 				{
       
  1566 				// ELF-derived
  1326 				// ELF-derived
  1567 				*(TUint*)(codeBase + *impOrdinalP) = exportAddr + impOffset;
  1327 				*(TUint*)(codeBase + *impOrdinalP) = exportAddr + impOffset;
  1568 				}
  1328 			}
  1569 			impOrdinalP++;
  1329 			impOrdinalP++;
  1570 			}
  1330 		}
  1571 		b = b->NextBlock(impfmt);
  1331 		b = b->NextBlock(impfmt);
  1572 		}
  1332 	}
  1573 	iImportCount=numberOfImports;
  1333 	iImportCount=numberOfImports;
  1574 	return KErrNone;
  1334 	return KErrNone;
  1575 	}
  1335 }
  1576 
  1336 
  1577 const char* KF32ProcessName="efile.exe";
  1337 const char* KF32ProcessName="efile.exe";
  1578 const char* KWservProcessName="ewsrv.exe";
  1338 const char* KWservProcessName="ewsrv.exe";
  1579 const char* KFbservProcessName="fbserv.exe";
  1339 const char* KFbservProcessName="fbserv.exe";
  1580 const char* KMdaSvrProcessName="mediaserverstub.exe";
  1340 const char* KMdaSvrProcessName="mediaserverstub.exe";
  1581 const char* KC32ProcessName="c32exe.exe";
  1341 const char* KC32ProcessName="c32exe.exe";
  1582 
  1342 
  1583 const char* TRomBuilderEntry::GetDefaultAttachProcess()
       
  1584 //
  1343 //
  1585 // Work out the attach process from the file extension
  1344 // Work out the attach process from the file extension
  1586 //
  1345 //
  1587 // Only need to handle DLLs which run in F32, WSERV, FBSERV, MEDIASVR, C32
  1346 // Only need to handle DLLs which run in F32, WSERV, FBSERV, MEDIASVR, C32
  1588 // F32:		FSY FXT
  1347 // F32:		FSY FXT
  1589 // WSERV:	ANI
  1348 // WSERV:	ANI
  1590 // FBSERV:
  1349 // FBSERV:
  1591 // MDASVR:	MDA
  1350 // MDASVR:	MDA
  1592 // C32:		CSY, PRT, TSY, AGT, AGX
  1351 // C32:		CSY, PRT, TSY, AGT, AGX
  1593 //
  1352 //
  1594 	{
  1353 const char* TRomBuilderEntry::GetDefaultAttachProcess() {
  1595 	const char* s=(const char*)iName;
  1354 	const char* s=(const char*)iName;
  1596 	TInt l=strlen(s);
  1355 	TInt l=strlen(s);
  1597 	if (l<4 || s[l-4]!='.')
  1356 	if (l<4 || s[l-4]!='.')
  1598 		return NULL;
  1357 		return NULL;
  1599 	s+=(l-3);
  1358 	s+=(l-3);
  1614 	if (stricmp(s,"agt")==0)
  1373 	if (stricmp(s,"agt")==0)
  1615 		return KC32ProcessName;
  1374 		return KC32ProcessName;
  1616 	if (stricmp(s,"agx")==0)
  1375 	if (stricmp(s,"agx")==0)
  1617 		return KC32ProcessName;
  1376 		return KC32ProcessName;
  1618 	return NULL;
  1377 	return NULL;
  1619 	}
  1378 }
  1620 
  1379 
  1621 TInt TRomBuilderEntry::FindAttachProcess(E32Rom& aRom)
  1380 TInt TRomBuilderEntry::FindAttachProcess(E32Rom& aRom) {
  1622 	{
       
  1623 	if (iRomImageFlags & (KRomImageFlagVariant|KRomImageFlagExtension|KRomImageFlagDevice))
  1381 	if (iRomImageFlags & (KRomImageFlagVariant|KRomImageFlagExtension|KRomImageFlagDevice))
  1624 		return KErrNone;
  1382 		return KErrNone;
  1625 	const char* attp_name=(const char*)iProcessName;
  1383 	const char* attp_name=(const char*)iProcessName;
  1626 	int nd=0;
  1384 	int nd=0;
  1627 	if (attp_name)
  1385 	if (attp_name)
  1631 	if (!attp_name)
  1389 	if (!attp_name)
  1632 		return KErrNone;
  1390 		return KErrNone;
  1633 	TInt i;
  1391 	TInt i;
  1634 	TUint my_abi = iHdr->ABI();
  1392 	TUint my_abi = iHdr->ABI();
  1635 	TUint abi = 0;
  1393 	TUint abi = 0;
  1636 	if (nd)
  1394 	if (nd) {
  1637 		{
       
  1638 		// path search
  1395 		// path search
  1639 		TRomNode* rn=aRom.iObey->iRootDirectory;
  1396 		TRomNode* rn=aRom.iObey->iRootDirectory;
  1640 		for (; nd; --nd)
  1397 		for (; nd; --nd) {
  1641 			{
  1398 			rn=rn->FindInDirectory(attp_name);
  1642 			rn=rn->FindInDirectory((TText*)attp_name);
  1399 			if (!rn) {
  1643 			if (!rn)
       
  1644 				{
       
  1645 				Print(EError, "Invalid attach process name element %s\n", attp_name);
  1400 				Print(EError, "Invalid attach process name element %s\n", attp_name);
  1646 				return KErrGeneral;
  1401 				return KErrGeneral;
  1647 				}
  1402 			}
  1648 			attp_name+=(strlen(attp_name)+1);
  1403 			attp_name+=(strlen(attp_name)+1);
  1649 			}
  1404 		}
  1650 		iRomNode->iRomFile->iAttachProcess=rn->iRomFile;
  1405 		iRomNode->iRomFile->iAttachProcess=rn->iRomFile;
  1651 		abi = iRomNode->iRomFile->iAttachProcess->ABI();
  1406 		abi = iRomNode->iRomFile->iAttachProcess->ABI();
  1652 		}
  1407 	}
  1653 	else
  1408 	else {
  1654 		{
       
  1655 		// filename only search
  1409 		// filename only search
  1656 		for (i=0; i<aRom.iObey->iNumberOfPeFiles; i++)
  1410 		for (i=0; i<aRom.iObey->iNumberOfPeFiles; i++) {
  1657 			{
       
  1658 			TRomBuilderEntry* e=aRom.iPeFiles[i];
  1411 			TRomBuilderEntry* e=aRom.iPeFiles[i];
  1659 			abi = e->iHdr->ABI();
  1412 			abi = e->iHdr->ABI();
  1660 			if (stricmp((const char*)e->iName, attp_name)==0)
  1413 			if (stricmp((const char*)e->iName, attp_name)==0) {
  1661 				{
  1414 				if (iRomNode->iRomFile->iAttachProcess) {
  1662 				if (iRomNode->iRomFile->iAttachProcess)
       
  1663 					{
       
  1664 					Print(EError, "Ambiguous attach process name %s\n", attp_name);
  1415 					Print(EError, "Ambiguous attach process name %s\n", attp_name);
  1665 					return KErrGeneral;
  1416 					return KErrGeneral;
  1666 					}
  1417 				}
  1667 				iRomNode->iRomFile->iAttachProcess=e->iRomNode->iRomFile;
  1418 				iRomNode->iRomFile->iAttachProcess=e->iRomNode->iRomFile;
  1668 				}
       
  1669 			}
  1419 			}
  1670 		}
  1420 		}
  1671 	if (abi != my_abi)
  1421 	}
  1672 		{
  1422 	if (abi != my_abi) {
  1673 		Print(EWarning, "File %s: Attach process has different ABI\n", (const char*)TModuleName(this));
  1423 		Print(EWarning, "File %s: Attach process has different ABI\n", (const char*)TModuleName(this));
  1674 		}
  1424 	}
  1675 	return KErrNone;
  1425 	return KErrNone;
  1676 	}
  1426 }
  1677 
       
  1678 TInt TRomBuilderEntry::BuildDependenceGraph(E32Rom& aRom)
       
  1679 //
  1427 //
  1680 // Fill in the iDeps
  1428 // Fill in the iDeps
  1681 //
  1429 //
  1682 	{
  1430 TInt TRomBuilderEntry::BuildDependenceGraph(E32Rom& aRom) {
  1683 	TBool is_kernel = ((iRomImageFlags & KRomImageFlagsKernelMask) != 0);
  1431 	TBool is_kernel = ((iRomImageFlags & KRomImageFlagsKernelMask) != 0);
  1684 	TRomNode* rn = iRomNode;
  1432 	TRomNode* rn = iRomNode;
  1685 	TRomFile* rf = rn->iRomFile;
  1433 	TRomFile* rf = rn->iRomFile;
  1686 	TUint my_abi = iHdr->ABI();
  1434 	TUint my_abi = iHdr->ABI();
  1687 	TUint impfmt = iHdr->ImportFormat();
  1435 	TUint impfmt = iHdr->ImportFormat();
  1688 	rf->iNumDeps = iHdr->iDllRefTableCount;
  1436 	rf->iNumDeps = iHdr->iDllRefTableCount;
  1689 	if (IsDll() && aRom.iObey->iMemModel!=E_MM_Flexible && aRom.iObey->iMemModel!=E_MM_Multiple && (iHdr->iDataSize!=0 || iHdr->iBssSize!=0))
  1437 	if (IsDll() && aRom.iObey->iMemModel!=E_MM_Flexible && aRom.iObey->iMemModel!=E_MM_Multiple && (iHdr->iDataSize!=0 || iHdr->iBssSize!=0)) {
  1690 		{
       
  1691 		TInt r=FindAttachProcess(aRom);
  1438 		TInt r=FindAttachProcess(aRom);
  1692 		if (r!=KErrNone)
  1439 		if (r!=KErrNone)
  1693 			return r;
  1440 			return r;
  1694 		if (aRom.iObey->iMemModel==E_MM_Moving)
  1441 		if (aRom.iObey->iMemModel==E_MM_Moving) {
  1695 			{
       
  1696 			if (rf->iAttachProcess && !(rf->iAttachProcess->RomImageFlags() & KRomImageFlagFixedAddressExe))
  1442 			if (rf->iAttachProcess && !(rf->iAttachProcess->RomImageFlags() & KRomImageFlagFixedAddressExe))
  1697 				rf->iAttachProcess=NULL;	// ignore attach process if not fixed
  1443 				rf->iAttachProcess=NULL;	// ignore attach process if not fixed
  1698 			}
  1444 		}
  1699 		}
  1445 	}
  1700 	TRomFile* attp=rf->iAttachProcess;
  1446 	TRomFile* attp=rf->iAttachProcess;
  1701 	if (attp)
  1447 	if (attp)
  1702 		++rf->iNumDeps;		// extra implicit dependence on process
  1448 		++rf->iNumDeps;		// extra implicit dependence on process
  1703 	if (rf->iNumDeps)
  1449 	if (rf->iNumDeps) {
  1704 		{
       
  1705 		rf->iDeps=new TRomFile* [rf->iNumDeps];
  1450 		rf->iDeps=new TRomFile* [rf->iNumDeps];
  1706 		memset(rf->iDeps, 0, rf->iNumDeps*sizeof(TRomFile*));
  1451 		memset(rf->iDeps, 0, rf->iNumDeps*sizeof(TRomFile*));
  1707 		}
  1452 	}
  1708 
  1453 
  1709 	TInt err = KErrNone;
  1454 	TInt err = KErrNone;
  1710 	const E32ImportSection* importSection = (const E32ImportSection*)(iData + iOrigHdr->iImportOffset);
  1455 	const E32ImportSection* importSection = (const E32ImportSection*)(iData + iOrigHdr->iImportOffset);
  1711 	const E32ImportBlock* block = (const E32ImportBlock*)(importSection + 1);
  1456 	const E32ImportBlock* block = (const E32ImportBlock*)(importSection + 1);
  1712 	TInt i;
  1457 	TInt i;
  1713 	for (i=0; i<iHdr->iDllRefTableCount; i++, block = block->NextBlock(impfmt), TRACE(TIMPORT,Print(ELog,"DllRef/dll done\n")) )
  1458 	for (i=0; i<iHdr->iDllRefTableCount; i++, block = block->NextBlock(impfmt), TRACE(TIMPORT,Print(ELog,"DllRef/dll done\n")) ) {
  1714 		{
       
  1715 		char* dllname = (char*)importSection + block->iOffsetOfDllName;
  1459 		char* dllname = (char*)importSection + block->iOffsetOfDllName;
  1716 		TDllFindInfo find_info(dllname, this);
  1460 		TDllFindInfo find_info(dllname, this);
  1717 		TBool fallback;
  1461 		TBool fallback;
  1718 		TRomNode* romnode = aRom.FindImageFileByName(find_info, EFalse, fallback);
  1462 		TRomNode* romnode = aRom.FindImageFileByName(find_info, EFalse, fallback);
  1719 		if (!romnode)
  1463 		if (!romnode) {
  1720 			{
       
  1721 			Print(EError, "Can't build dependence graph for\n\t%s\nbecause\n\t%s\nis not in rom.\n",
  1464 			Print(EError, "Can't build dependence graph for\n\t%s\nbecause\n\t%s\nis not in rom.\n",
  1722 						 (const char*)TModuleName(this), (const char*)TModuleName(find_info));
  1465 				(const char*)TModuleName(this), (const char*)TModuleName(find_info));
  1723 			aRom.FindImageFileByName(find_info, ETrue, fallback);
  1466 			aRom.FindImageFileByName(find_info, ETrue, fallback);
  1724 			err = KErrNotFound;
  1467 			err = KErrNotFound;
  1725 			continue;
  1468 			continue;
  1726 			}
  1469 		}
  1727 		if (fallback)
  1470 		if (fallback) {
  1728 			{
       
  1729 			Print(EWarning, "File %s links to %s\n\twhich is not in ROM. Version 1.0 of latter used instead.\n",
  1471 			Print(EWarning, "File %s links to %s\n\twhich is not in ROM. Version 1.0 of latter used instead.\n",
  1730 					 (const char*)TModuleName(this), (const char*)TModuleName(find_info));
  1472 				(const char*)TModuleName(this), (const char*)TModuleName(find_info));
  1731 			}
  1473 		}
  1732 		TRACE(TIMPORT,Print(ELog,"%s links to %s\n", (const char*)TModuleName(this), (const char*)TModuleName(find_info)));
  1474 		TRACE(TIMPORT,Print(ELog,"%s links to %s\n", (const char*)TModuleName(this), (const char*)TModuleName(find_info)));
  1733 		TRACE(TIMPORT,Print(ELog,"Resolves to %s\n", (const char*)TModuleName(*romnode)));
  1475 		TRACE(TIMPORT,Print(ELog,"Resolves to %s\n", (const char*)TModuleName(*romnode)));
  1734 		TBool dep_is_kernel = ((romnode->iRomFile->RomImageFlags() & KRomImageFlagsKernelMask) != 0);
  1476 		TBool dep_is_kernel = ((romnode->iRomFile->RomImageFlags() & KRomImageFlagsKernelMask) != 0);
  1735 		if (dep_is_kernel != is_kernel)
  1477 		if (dep_is_kernel != is_kernel) {
  1736 			{
  1478 			if (is_kernel) {
  1737 			if (is_kernel)
       
  1738 				{
       
  1739 				Print(EError, "Kernel side executable\n\t%s\nlinks to user side executable\n\t%s\n",
  1479 				Print(EError, "Kernel side executable\n\t%s\nlinks to user side executable\n\t%s\n",
  1740 									 (const char*)TModuleName(this), (const char*)TModuleName(find_info));
  1480 					(const char*)TModuleName(this), (const char*)TModuleName(find_info));
  1741 				}
  1481 			}
  1742 			else
  1482 			else {
  1743 				{
       
  1744 				Print(EError, "User side executable\n\t%s\nlinks to kernel side executable\n\t%s\n",
  1483 				Print(EError, "User side executable\n\t%s\nlinks to kernel side executable\n\t%s\n",
  1745 									 (const char*)TModuleName(this), (const char*)TModuleName(find_info));
  1484 					(const char*)TModuleName(this), (const char*)TModuleName(find_info));
  1746 				}
  1485 			}
  1747 			err = KErrGeneral;
  1486 			err = KErrGeneral;
  1748 			continue;
  1487 			continue;
  1749 			}
  1488 		}
  1750 		// prevent the situiation which importer is primary, variant or extension, exporter is device
  1489 		// prevent the situiation which importer is primary, variant or extension, exporter is device
  1751 		if (is_kernel && !Device() && romnode->iRomFile->iRbEntry->Device())	
  1490 		if (is_kernel && !Device() && romnode->iRomFile->iRbEntry->Device())	 {
  1752 			{
       
  1753 			Print(EWarning, "Kernel/variant/extension\n\t%s\nlinks to non-extension LDD/PDD\n\t%s\n",
  1491 			Print(EWarning, "Kernel/variant/extension\n\t%s\nlinks to non-extension LDD/PDD\n\t%s\n",
  1754 							(const char*)TModuleName(this), (const char*)TModuleName(find_info));
  1492 				(const char*)TModuleName(this), (const char*)TModuleName(find_info));
  1755 			}
  1493 		}
  1756 		if (romnode->ABI() != my_abi)
  1494 		if (romnode->ABI() != my_abi) {
  1757 			{
       
  1758 			Print(EWarning, "File %s links to %s with different ABI\n", (const char*)TModuleName(this), (const char*)TModuleName(find_info));
  1495 			Print(EWarning, "File %s links to %s with different ABI\n", (const char*)TModuleName(this), (const char*)TModuleName(find_info));
  1759 			}
  1496 		}
  1760 
  1497 
  1761 		rf->iDeps[i]=romnode->iRomFile;
  1498 		rf->iDeps[i]=romnode->iRomFile;
  1762 		const SSecurityInfo& s1 = iHdr->iS;
  1499 		const SSecurityInfo& s1 = iHdr->iS;
  1763 		const SSecurityInfo& s2 = romnode->iRomFile->SecurityInfo();
  1500 		const SSecurityInfo& s2 = romnode->iRomFile->SecurityInfo();
  1764 		TInt r = CompareCapabilities(s1.iCaps, s2.iCaps, iFileName, dllname);
  1501 		TInt r = CompareCapabilities(s1.iCaps, s2.iCaps, iFileName, dllname);
  1765 		if (r != KErrNone)
  1502 		if (r != KErrNone)
  1766 			err = r;
  1503 			err = r;
  1767 		if (romnode->iRomFile==attp)
  1504 		if (romnode->iRomFile==attp)
  1768 			attp=NULL;
  1505 			attp=NULL;
  1769 		}
  1506 	}
  1770 
  1507 
  1771 	if (attp)
  1508 	if (attp)
  1772 		rf->iDeps[rf->iNumDeps-1]=attp;
  1509 		rf->iDeps[rf->iNumDeps-1]=attp;
  1773 	TRACE(TIMPORT,Print(ELog,"BuildDep done all\n"));
  1510 	TRACE(TIMPORT,Print(ELog,"BuildDep done all\n"));
  1774 	return err;
  1511 	return err;
  1775 	}
  1512 }
  1776 
       
  1777 TInt TRomBuilderEntry::ResolveDllRefTable(E32Rom& aRom)
       
  1778 //
  1513 //
  1779 // Fill in the DLLRefTable
  1514 // Fill in the DLLRefTable
  1780 //
  1515 //
  1781 	{
  1516 TInt TRomBuilderEntry::ResolveDllRefTable(E32Rom& aRom) {
  1782 	TRomNode* rn = iRomNode;
  1517 	TRomNode* rn = iRomNode;
  1783 	TRomFile* rf = rn->iRomFile;
  1518 	TRomFile* rf = rn->iRomFile;
  1784 	(void)aRom;
  1519 	(void)aRom;
  1785 	if (rf->iNumPDeps==0)
  1520 	if (rf->iNumPDeps==0)
  1786 		return KErrNone;	// nothing to do
  1521 		return KErrNone;	// nothing to do
  1792 	dllRefTable->iFlags=flags;
  1527 	dllRefTable->iFlags=flags;
  1793 	dllRefTable->iNumberOfEntries=(TUint16)rf->iNumPDeps;
  1528 	dllRefTable->iNumberOfEntries=(TUint16)rf->iNumPDeps;
  1794 
  1529 
  1795 	TInt err = KErrNone;
  1530 	TInt err = KErrNone;
  1796 	TInt i;
  1531 	TInt i;
  1797 	for (i=0; i<rf->iNumPDeps; i++)
  1532 	for (i=0; i<rf->iNumPDeps; i++) {
  1798 		{
       
  1799 		dllRefTable->iEntry[i]=(TRomImageHeader*)rf->iPDeps[i]->iAddresses.iRunAddr;
  1533 		dllRefTable->iEntry[i]=(TRomImageHeader*)rf->iPDeps[i]->iAddresses.iRunAddr;
  1800 		}
  1534 	}
  1801 	TRACE(TIMPORT,Print(ELog,"DllRef done all\n"));
  1535 	TRACE(TIMPORT,Print(ELog,"DllRef done all\n"));
  1802 	return err;
  1536 	return err;
  1803 	}
  1537 }
  1804 
  1538 
  1805 void TRomBuilderEntry::DisplaySize(TPrintType aWhere)
  1539 void TRomBuilderEntry::DisplaySize(TPrintType aWhere) {
  1806 	{
       
  1807 	if(gLogLevel > DEFAULT_LOG_LEVEL){
  1540 	if(gLogLevel > DEFAULT_LOG_LEVEL){
  1808 
  1541 
  1809 		if(gLogLevel & LOG_LEVEL_FILE_DETAILS)
  1542 		if(gLogLevel & LOG_LEVEL_FILE_DETAILS) {
  1810 		{
       
  1811 			// More detailed information about file name in .
  1543 			// More detailed information about file name in .
  1812 			TBool aIgnoreHiddenAttrib = ETrue;
  1544 			TBool aIgnoreHiddenAttrib = ETrue;
  1813 			TInt aLen = iRomNode->FullNameLength(aIgnoreHiddenAttrib);
  1545 			TInt aLen = iRomNode->FullNameLength(aIgnoreHiddenAttrib);
  1814 			char * aBuf = new char[aLen+1];
  1546 			char * aBuf = new char[aLen+1];
  1815 			iRomNode->GetFullName(aBuf, aIgnoreHiddenAttrib);
  1547 			iRomNode->GetFullName(aBuf, aIgnoreHiddenAttrib);
  1824 		if (iPatched|iRomNode->iHidden)
  1556 		if (iPatched|iRomNode->iHidden)
  1825 			Print(aWhere, "%s\t%d\t%s\n", iFileName, SizeInRom(), iPatched?"patched":"hidden");
  1557 			Print(aWhere, "%s\t%d\t%s\n", iFileName, SizeInRom(), iPatched?"patched":"hidden");
  1826 		else
  1558 		else
  1827 			Print(aWhere, "%s\t%d\n", iFileName, SizeInRom());
  1559 			Print(aWhere, "%s\t%d\n", iFileName, SizeInRom());
  1828 	}
  1560 	}
  1829 	}
  1561 }
  1830 
  1562 
  1831 /**
  1563 /**
  1832  * TRomFile iRomEntry is a linked list through the various
  1564 * TRomFile iRomEntry is a linked list through the various
  1833  * distinct TRomEntry objects which may exist for the associated file
  1565 * distinct TRomEntry objects which may exist for the associated file
  1834  * due to variant processing / aliasing
  1566 * due to variant processing / aliasing
  1835  */
  1567 */
  1836 
  1568 
  1837 void TRomFile::SetRomEntry(TRomEntry* aEntry)
  1569 void TRomFile::SetRomEntry(TRomEntry* aEntry) {
  1838 	{
       
  1839 	// Need to add to the tail of the list, for backwards compatibility
  1570 	// Need to add to the tail of the list, for backwards compatibility
  1840 	// Adding to the front of the list changes the iPrimary and iSecondary
  1571 	// Adding to the front of the list changes the iPrimary and iSecondary
  1841 	// values in the TRomHeader when multiple variants are present
  1572 	// values in the TRomHeader when multiple variants are present
  1842 
  1573 
  1843 	if (iFinal)
  1574 	if (iFinal)
  1844 		return;			// address already established so no fixup required
  1575 		return;			// address already established so no fixup required
  1845 	if (iRomEntry==0)
  1576 	if (iRomEntry==0) {
  1846 		{
       
  1847 		iRomEntry = aEntry;
  1577 		iRomEntry = aEntry;
  1848 		return;
  1578 		return;
  1849 		}
  1579 	}
  1850 	TRomEntry* entry = iRomEntry;
  1580 	TRomEntry* entry = iRomEntry;
  1851 	while (entry->iAddressLin != 0)
  1581 	while (entry->iAddressLin != 0)
  1852 		entry = (TRomEntry*)entry->iAddressLin;
  1582 		entry = (TRomEntry*)entry->iAddressLin;
  1853 	entry->iAddressLin = (TLinAddr)aEntry;
  1583 	entry->iAddressLin = (TLinAddr)aEntry;
  1854 	}
  1584 }
  1855 
  1585 
  1856 void TRomBuilderEntry::FixupRomEntries(TInt aSize)
  1586 void TRomBuilderEntry::FixupRomEntries(TInt aSize) {
  1857 	{
       
  1858 	if (iPatched)
  1587 	if (iPatched)
  1859 		return;		// patched files don't appear in the ROM file system
  1588 		return;		// patched files don't appear in the ROM file system
  1860 
  1589 
  1861 	iRomNode->Finalise(aSize);
  1590 	iRomNode->Finalise(aSize);
  1862 	}
  1591 }
  1863 
  1592 
  1864 /**
  1593 /**
  1865  * TRomNode::Finalise updates the associated TRomEntry objects with the final size and
  1594 * TRomNode::Finalise updates the associated TRomEntry objects with the final size and
  1866  * linear address information supplied by the TRomBuilderEntry. It also stores the
  1595 * linear address information supplied by the TRomBuilderEntry. It also stores the
  1867  * summary information for resolving static linkages to this executable (if appropriate)
  1596 * summary information for resolving static linkages to this executable (if appropriate)
  1868  * and adjusts the TRomNodes so that they are identical to the ones which would be 
  1597 * and adjusts the TRomNodes so that they are identical to the ones which would be 
  1869  * obtained by walking the directory structure in an existing ROM.
  1598 * obtained by walking the directory structure in an existing ROM.
  1870  */
  1599 */
  1871 void TRomNode::Finalise(TInt aSize)
  1600 void TRomNode::Finalise(TInt aSize) {
  1872 	{
       
  1873 	TRACE(TIMPORT,Print(ELog,"TRomNode %s Finalise %08x %d\n", (const char*)TModuleName(*this), iRomFile->iFinal));
  1601 	TRACE(TIMPORT,Print(ELog,"TRomNode %s Finalise %08x %d\n", (const char*)TModuleName(*this), iRomFile->iFinal));
  1874 	iRomFile->Finalise(aSize);
  1602 	iRomFile->Finalise(aSize);
  1875 	}
  1603 }
  1876 
  1604 
  1877 /**
  1605 /**
  1878  * TRomFile::Finalise updates the associated TRomEntry objects with the final size and
  1606 * TRomFile::Finalise updates the associated TRomEntry objects with the final size and
  1879  * linear address information supplied by the TRomBuilderEntry. It also stores the
  1607 * linear address information supplied by the TRomBuilderEntry. It also stores the
  1880  * summary information for resolving static linkages to this executable (if appropriate)
  1608 * summary information for resolving static linkages to this executable (if appropriate)
  1881  * and adjusts the TRomFiles so that they are identical to the ones which would be 
  1609 * and adjusts the TRomFiles so that they are identical to the ones which would be 
  1882  * obtained by walking the directory structure in an existing ROM.
  1610 * obtained by walking the directory structure in an existing ROM.
  1883  */
  1611 */
  1884 void TRomFile::Finalise(TInt aSize)
  1612 void TRomFile::Finalise(TInt aSize) {
  1885 	{
       
  1886 	if (iFinal)
  1613 	if (iFinal)
  1887 		return;
  1614 		return;
  1888 	TLinAddr ra = iRbEntry->iHeaderRange.iImageAddr;
  1615 	TLinAddr ra = iRbEntry->iHeaderRange.iImageAddr;
  1889 	TRomEntry* entry = iRomEntry;
  1616 	TRomEntry* entry = iRomEntry;
  1890 	while (entry)
  1617 	while (entry) {
  1891 		{
       
  1892 		TRomEntry* next = (TRomEntry*)entry->iAddressLin;
  1618 		TRomEntry* next = (TRomEntry*)entry->iAddressLin;
  1893 		entry->iSize = aSize;
  1619 		entry->iSize = aSize;
  1894 		entry->iAddressLin = ra;
  1620 		entry->iAddressLin = ra;
  1895 		entry = next;
  1621 		entry = next;
  1896 		}
  1622 	}
  1897 	iAddresses = iRbEntry->iHeaderRange;
  1623 	iAddresses = iRbEntry->iHeaderRange;
  1898 	iAddresses.iSize = aSize;
  1624 	iAddresses.iSize = aSize;
  1899 	if ((!iRbEntry->iResource) && (!iRbEntry->HCRDataFile()))
  1625 	if ((!iRbEntry->iResource) && (!iRbEntry->HCRDataFile())) {
  1900 		{
       
  1901 		iExportDir = iAddresses;
  1626 		iExportDir = iAddresses;
  1902 		iExportDir.iSize = iRbEntry->iHdr->iExportDirCount * sizeof(TLinAddr);
  1627 		iExportDir.iSize = iRbEntry->iHdr->iExportDirCount * sizeof(TLinAddr);
  1903 		iExportDir.Move(RomImgHdr()->iExportDir - iAddresses.iRunAddr);
  1628 		iExportDir.Move(RomImgHdr()->iExportDir - iAddresses.iRunAddr);
  1904 		}
  1629 	}
  1905 	iRbEntry = 0;
  1630 	iRbEntry = 0;
  1906 	iFinal = ETrue;
  1631 	iFinal = ETrue;
  1907 	}
  1632 }
  1908 
  1633 
  1909 void TRomBuilderEntry::SetRomNode(TRomNode* aNode)
  1634 void TRomBuilderEntry::SetRomNode(TRomNode* aNode) {
  1910 	{
       
  1911 	iRomNode = aNode;
  1635 	iRomNode = aNode;
  1912 	}
  1636 }
  1913 
  1637 
  1914 
  1638 
  1915 void TImageSection::Load() const
  1639 void TImageSection::Load() const
  1916 	{ 
  1640 { 
  1917 	if (iSize && iImagePtr && iFilePtr) 
  1641 	if (iSize && iImagePtr && iFilePtr) 
  1918 		memcpy(iImagePtr,iFilePtr,iSize); 
  1642 		memcpy(iImagePtr,iFilePtr,iSize); 
  1919 	}
  1643 }
  1920 
  1644 
  1921 /**
  1645 /**
  1922  * TDllExportInfo is the information about a DLL which is necessary to
  1646 * TDllExportInfo is the information about a DLL which is necessary to
  1923  * resolve a static link to that DLL. It all comes from the TRomImageHeader,
  1647 * resolve a static link to that DLL. It all comes from the TRomImageHeader,
  1924  * as it would with a static linkage resolved at runtime.
  1648 * as it would with a static linkage resolved at runtime.
  1925  */
  1649 */
  1926 TRomFile::TRomFile()
  1650 TRomFile::TRomFile() {
  1927 	{
       
  1928 	memset(this, 0, sizeof(TRomFile));
  1651 	memset(this, 0, sizeof(TRomFile));
  1929 	iRefCount = 1;
  1652 	iRefCount = 1;
  1930 	iHwvd = KVariantIndependent;
  1653 	iHwvd = KVariantIndependent;
  1931 	iDataBssOffsetInExe = -1;
  1654 	iDataBssOffsetInExe = -1;
  1932 	}
  1655 }
  1933 
  1656 
  1934 TRomFile::~TRomFile()
  1657 TRomFile::~TRomFile() {
  1935 	{
  1658 	if(iDeps) delete[] iDeps;
  1936 	delete[] iDeps;
  1659 	if(iPDeps) delete[] iPDeps;
  1937 	delete[] iPDeps;
  1660 }
  1938 	}
       
  1939 
       
  1940 TInt TRomFile::AddressFromOrdinal(TLinAddr& aEDataAddr, TLinAddr& aExport, TUint aOrdinal)
       
  1941 //
  1661 //
  1942 // Get the export address of symbol aOrdinal
  1662 // Get the export address of symbol aOrdinal
  1943 //
  1663 //
  1944 	{
  1664 
  1945 	if(aOrdinal == 0)
  1665 TInt TRomFile::AddressFromOrdinal(TLinAddr& aEDataAddr, TLinAddr& aExport, TUint aOrdinal) {
  1946 	{
  1666 	if(aOrdinal == 0) {
  1947 		aEDataAddr = iExportDir.iRunAddr -1 ;
  1667 		aEDataAddr = iExportDir.iRunAddr -1 ;
  1948 		aExport = *(TLinAddr*)((TLinAddr*)iExportDir.iImagePtr - 1);
  1668 		aExport = *(TLinAddr*)((TLinAddr*)iExportDir.iImagePtr - 1);
  1949 		if((TInt)aExport == ExportDirCount()) {
  1669 		if((TInt)aExport == ExportDirCount()) {
  1950 			aEDataAddr = 0;
  1670 			aEDataAddr = 0;
  1951 			aExport = 0;
  1671 			aExport = 0;
  1952 		}
  1672 		}
  1953 		return KErrNone;
  1673 		return KErrNone;
  1954 	}
  1674 	}
  1955 	
  1675 
  1956 	TUint index = aOrdinal - KOrdinalBase;
  1676 	TUint index = aOrdinal - KOrdinalBase;
  1957 	if (index >= (TUint)ExportDirCount())
  1677 	if (index >= (TUint)ExportDirCount())
  1958 		return KErrNotFound;
  1678 		return KErrNotFound;
  1959 	aEDataAddr = iExportDir.iRunAddr + index * sizeof(TLinAddr);
  1679 	aEDataAddr = iExportDir.iRunAddr + index * sizeof(TLinAddr);
  1960 	aExport = ((TLinAddr*)iExportDir.iImagePtr)[index];
  1680 	aExport = ((TLinAddr*)iExportDir.iImagePtr)[index];
  1961 	return KErrNone;
  1681 	return KErrNone;
  1962 	}
  1682 }
  1963 
  1683 
  1964 
  1684 
  1965 bool TRomFile::ComputeSmpSafe(const TRomBuilderEntry* aRbEntry)
  1685 bool TRomFile::ComputeSmpSafe(const TRomBuilderEntry* aRbEntry) {
  1966 	{
       
  1967 	// A component is SMP safe if:
  1686 	// A component is SMP safe if:
  1968 	//
  1687 	//
  1969 	// 1. It's E32 image file is marked as SMP safe (MMP keyword SMPSAFE).
  1688 	// 1. It's E32 image file is marked as SMP safe (MMP keyword SMPSAFE).
  1970 	// 2. All components it links to are SMP safe.
  1689 	// 2. All components it links to are SMP safe.
  1971 	//
  1690 	//
  1972 	// This implies a recursive dependency structure.
  1691 	// This implies a recursive dependency structure.
  1973 
  1692 
  1974 	if (iSmpInfo.isInit)
  1693 	if (iSmpInfo.isInit) {
  1975 		{
       
  1976 		// We have already visited this node.
  1694 		// We have already visited this node.
  1977 		return iSmpInfo.isSafe;
  1695 		return iSmpInfo.isSafe;
  1978 		}
  1696 	}
  1979 
  1697 
  1980 	// Mark this node as "active," meaning that we are currently evaluating it. We
  1698 	// Mark this node as "active," meaning that we are currently evaluating it. We
  1981 	// use this to detect cycles in the dependency graph.
  1699 	// use this to detect cycles in the dependency graph.
  1982 	iSmpInfo.isActive = 1;
  1700 	iSmpInfo.isActive = 1;
  1983 
  1701 
  1984 	iSmpInfo.isSafe = 1;
  1702 	iSmpInfo.isSafe = 1;
  1985 
  1703 
  1986 	// Have we found any cycle in the graph?
  1704 	// Have we found any cycle in the graph?
  1987 	bool is_cycle = 0;
  1705 	bool is_cycle = 0;
  1988 
  1706 
  1989 	if ( aRbEntry->iOrigHdr->iFlags & KImageSMPSafe )
  1707 	if ( aRbEntry->iOrigHdr->iFlags & KImageSMPSafe ) {
  1990 		{
       
  1991 		// OK, the E32 file for this node is marked as SMPSAFE. Now we need to check
  1708 		// OK, the E32 file for this node is marked as SMPSAFE. Now we need to check
  1992 		// that all nodes we depend on are SMP safe.
  1709 		// that all nodes we depend on are SMP safe.
  1993 
  1710 
  1994 		for (int i = 0; i < iNumDeps; i++)
  1711 		for (int i = 0; i < iNumDeps; i++) {
  1995 			{
       
  1996 			TRomFile* e = iDeps[i];
  1712 			TRomFile* e = iDeps[i];
  1997 
  1713 
  1998 			assert(this != e);
  1714 			assert(this != e);
  1999 
  1715 
  2000 			if (e->iSmpInfo.isActive)
  1716 			if (e->iSmpInfo.isActive) {
  2001 				{
       
  2002 				is_cycle = 1;
  1717 				is_cycle = 1;
       
  1718 			}
       
  1719 			else if ( ! e->ComputeSmpSafe(e->iRbEntry) ) {
       
  1720 				if (gLogLevel & LOG_LEVEL_SMP_INFO) {
       
  1721 					Print(ELog,"SMP-unsafe: %s: links to unsafe component %s.\n",
       
  1722 						aRbEntry->iBareName , e->iRbEntry->iBareName);
  2003 				}
  1723 				}
  2004 			else if ( ! e->ComputeSmpSafe(e->iRbEntry) )
       
  2005 				{
       
  2006 				if (gLogLevel & LOG_LEVEL_SMP_INFO)
       
  2007 					{
       
  2008 					Print(ELog,"SMP-unsafe: %s: links to unsafe component %s.\n",
       
  2009 							aRbEntry->iBareName , e->iRbEntry->iBareName);
       
  2010 					}
       
  2011 
  1724 
  2012 				iSmpInfo.isSafe = 0;
  1725 				iSmpInfo.isSafe = 0;
  2013 				break;
  1726 				break;
  2014 				}
       
  2015 			}
  1727 			}
  2016 		}
  1728 		}
  2017 	else
  1729 	}
  2018 		{
  1730 	else {
  2019 		if (gLogLevel & LOG_LEVEL_SMP_INFO)
  1731 		if (gLogLevel & LOG_LEVEL_SMP_INFO) {
  2020 			{
       
  2021 			Print(ELog,"SMP-unsafe: %s: MMP keyword SMPSAFE not used.\n", aRbEntry->iBareName);
  1732 			Print(ELog,"SMP-unsafe: %s: MMP keyword SMPSAFE not used.\n", aRbEntry->iBareName);
  2022 			}
  1733 		}
  2023 
  1734 
  2024 		iSmpInfo.isSafe = 0;
  1735 		iSmpInfo.isSafe = 0;
  2025 		}
  1736 	}
  2026 
  1737 
  2027 	iSmpInfo.isActive = 0;
  1738 	iSmpInfo.isActive = 0;
  2028 
  1739 
  2029 	if (!iSmpInfo.isSafe || !is_cycle)
  1740 	if (!iSmpInfo.isSafe || !is_cycle) {
  2030 		{
       
  2031 		iSmpInfo.isInit = 1;
  1741 		iSmpInfo.isInit = 1;
  2032 		}
  1742 	}
  2033 
  1743 
  2034 	return iSmpInfo.isSafe;
  1744 	return iSmpInfo.isSafe;
  2035 	}
  1745 }
  2036 
  1746 
  2037 /**
  1747 /**
  2038  * TRomNode::CopyDirectory performs a deep copy of the TRomNode structure
  1748 * TRomNode::CopyDirectory performs a deep copy of the TRomNode structure
  2039  */
  1749 */
  2040 TRomNode* TRomNode::CopyDirectory(TRomNode*& aLastExecutable, TRomNode* aParent)
  1750 TRomNode* TRomNode::CopyDirectory(TRomNode*& aLastExecutable, TRomNode* aParent) {
  2041 	{
  1751 	if (iHidden && iChild==0) {
  2042 	if (iHidden && iChild==0)
       
  2043 		{
       
  2044 		// Hidden file - do not copy (as it wouldn't be visible in the ROM filestructure)
  1752 		// Hidden file - do not copy (as it wouldn't be visible in the ROM filestructure)
  2045 		if (iSibling)
  1753 		if (iSibling)
  2046 			return iSibling->CopyDirectory(aLastExecutable, aParent);
  1754 			return iSibling->CopyDirectory(aLastExecutable, aParent);
  2047 		else
  1755 		else
  2048 			return 0;
  1756 			return 0;
  2049 		}
  1757 	}
  2050 
  1758 
  2051 	TRomNode* copy = new TRomNode(*this);
  1759 	TRomNode* copy = new TRomNode(*this);
  2052 	copy->iParent = aParent;
  1760 	copy->iParent = aParent;
  2053 	if(aLastExecutable==0)
  1761 	if(aLastExecutable==0)
  2054 		aLastExecutable = copy;		// this must be the root of the structure
  1762 		aLastExecutable = copy;		// this must be the root of the structure
  2060 		copy->iSibling = iSibling->CopyDirectory(aLastExecutable, aParent);
  1768 		copy->iSibling = iSibling->CopyDirectory(aLastExecutable, aParent);
  2061 
  1769 
  2062 	if (copy->iAtt & KEntryAttXIP)
  1770 	if (copy->iAtt & KEntryAttXIP)
  2063 		AddExecutableFile(aLastExecutable,copy);
  1771 		AddExecutableFile(aLastExecutable,copy);
  2064 	return copy;
  1772 	return copy;
  2065 	}
  1773 }
  2066 
  1774 
  2067 TInt TRomNode::Alias(TRomNode* aNode, TRomNode*& aLastExecutable)
  1775 TInt TRomNode::Alias(TRomNode* aNode, TRomNode*& aLastExecutable) {
  2068 	{
       
  2069 	if (aNode->iAtt & KEntryAttXIP)
  1776 	if (aNode->iAtt & KEntryAttXIP)
  2070 		AddExecutableFile(aLastExecutable,this);
  1777 		AddExecutableFile(aLastExecutable,this);
  2071 	return SetBareName();
  1778 	return SetBareName();
  2072 	}
  1779 }
  2073 
  1780 
  2074 TInt TRomNode::Rename(TRomNode *aOldParent, TRomNode* aNewParent, TText* aNewName)
  1781 TInt TRomNode::Rename(TRomNode *aOldParent, TRomNode* aNewParent, const char* aNewName) {
  2075 	{
       
  2076 	aOldParent->Remove(this);
  1782 	aOldParent->Remove(this);
  2077 	aNewParent->Add(this);
  1783 	aNewParent->Add(this);
  2078 	free(iName);
  1784 	if(iName)
  2079 	iName = (TText*)NormaliseFileName((const char*)aNewName);
  1785 		delete []iName;
       
  1786 	iName = NormaliseFileName(aNewName);
  2080 	return SetBareName();
  1787 	return SetBareName();
  2081 	}
  1788 }
  2082 
  1789 
  2083 TInt TRomNode::SetBareName()
  1790 TInt TRomNode::SetBareName() {
  2084 	{
  1791 	if(iBareName) {
  2085 	free(iBareName);
  1792 		delete []iBareName;
       
  1793 		iBareName = 0 ;
       
  1794 	}
  2086 	TUint32 uid;
  1795 	TUint32 uid;
  2087 	TUint32 vin;
  1796 	TUint32 vin;
  2088 	TUint32 flg;
  1797 	TUint32 flg;
  2089 	iBareName = SplitFileName((const char*)iName, uid, vin, flg);
  1798 	iBareName = SplitFileName(iName, uid, vin, flg);
  2090 	if (uid || (flg & EUidPresent))
  1799 	if (uid || (flg & EUidPresent))
  2091 		return KErrBadName;
  1800 		return KErrBadName;
  2092 	if (strchr(iBareName, '{') || strchr(iBareName, '}'))
  1801 	if (strchr(iBareName, '{') || strchr(iBareName, '}'))
  2093 		return KErrBadName;
  1802 		return KErrBadName;
  2094 	if ((iAtt & KEntryAttXIP) && (flg & EVerPresent))
  1803 	if ((iAtt & KEntryAttXIP) && (flg & EVerPresent)) {
  2095 		{
       
  2096 		TUint32 ver = iRomFile->ModuleVersion();
  1804 		TUint32 ver = iRomFile->ModuleVersion();
  2097 		if (ver != vin)
  1805 		if (ver != vin)
  2098 			return KErrArgument;
  1806 			return KErrArgument;
  2099 		}
  1807 	}
  2100 	return KErrNone;
  1808 	return KErrNone;
  2101 	}
  1809 }