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); |
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: |
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(); |
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); |
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 |
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 |