18 |
18 |
19 |
19 |
20 #include <string.h> |
20 #include <string.h> |
21 #include <stdlib.h> |
21 #include <stdlib.h> |
22 #include <e32std.h> |
22 #include <e32std.h> |
23 #include <elfdefs.h> |
23 #include "elfdefs.h" |
24 #include "elfdll.h" |
24 #include "elfdll.h" |
25 #include "elffile.h" |
25 #include "elffile.h" |
26 #include <h_utl.h> |
26 #include "h_utl.h" |
27 #include <e32ldr.h> |
27 #include <e32ldr.h> |
28 |
28 |
29 ELFFile::ELFDllData::ELFDllData(ELFFile * f) |
29 ELFFile::ELFDllData::ELFDllData(ELFFile * f) : |
30 : |
30 iElfFile(f), iDynStrTab(0), iDynStrTabSize(0), iDynSymTab(0), |
31 iElfFile(f), |
31 iSymSize(0), iRela(0), iRelaSz(0), iRelaEnt(0), |
32 |
32 iRel(0), iRelSz(0), iRelEnt(0), |
33 iDynStrTab(0), |
33 iHashTable(0), iNamedExportSymbolHead(0), iNamedExportCount(0), |
34 iDynStrTabSize(0), |
34 iSymStringTableSize(0),iStringNameOffset(0), |
35 iDynSymTab(0), |
35 iDepRecords(0), iDepRecordsTail(0),iNeededDllNames(0),iNeededDllNamesTail(0), |
36 |
36 iOrdZeroRec(0), iNamedLookupEnabled(0), |
37 iSymSize(0), |
37 iDllHead(0), iDllTail(0), |
38 iRela(0), |
38 iNumberOfImports(0), iNumberOfExports(0), iNumberOfImportDlls(0), |
39 iRelaSz(0), |
39 iStringTableSize(0), iNumberOfRelocs(0), iNumberOfCodeRelocs(0), |
40 iRelaEnt(0), |
40 iNumberOfDataRelocs(0) |
41 |
41 |
42 iRel(0), |
|
43 iRelSz(0), |
|
44 iRelEnt(0), |
|
45 |
|
46 iHashTable(0), |
|
47 |
|
48 iNamedExportSymbolHead(0), |
|
49 iNamedExportCount(0), |
|
50 |
|
51 iSymStringTableSize(0), |
|
52 iStringNameOffset(0), |
|
53 |
|
54 iDepRecords(0), |
|
55 iDepRecordsTail(0), |
|
56 |
|
57 iNeededDllNames(0), |
|
58 iNeededDllNamesTail(0), |
|
59 |
|
60 iOrdZeroRec(0), |
|
61 |
|
62 iNamedLookupEnabled(0), |
|
63 |
|
64 iDllHead(0), |
|
65 iDllTail(0), |
|
66 |
|
67 iNumberOfImports(0), |
|
68 iNumberOfExports(0), |
|
69 iNumberOfImportDlls(0), |
|
70 |
|
71 iStringTableSize(0), |
|
72 |
|
73 iNumberOfRelocs(0), |
|
74 iNumberOfCodeRelocs(0), |
|
75 iNumberOfDataRelocs(0) |
|
76 { |
42 { |
77 } |
43 } |
78 |
44 |
79 ELFFile::ELFDllData::~ELFDllData() |
45 ELFFile::ELFDllData::~ELFDllData() |
80 { |
46 { |
132 errors++; |
98 errors++; |
133 } |
99 } |
134 } |
100 } |
135 // Set up export info |
101 // Set up export info |
136 if (InitExportInfo()) |
102 if (InitExportInfo()) |
137 { |
103 { |
138 TText * sym = (TText *)"_E32Startup"; |
|
139 // If _E32Startup is defined then this is not a DLL |
104 // If _E32Startup is defined then this is not a DLL |
140 iImageIsDll = !iElfFile->SymbolPresent(sym); |
105 iImageIsDll = !iElfFile->SymbolPresent("_E32Startup"); |
141 } |
106 } |
142 if (errors > 0) return EFalse; |
107 if (errors > 0) return EFalse; |
143 return ETrue; |
108 return ETrue; |
144 } |
109 } |
145 |
110 |
258 h &= ~g; |
223 h &= ~g; |
259 } |
224 } |
260 return h; |
225 return h; |
261 } |
226 } |
262 |
227 |
263 Elf32_Word ELFFile::ELFDllData::FindSymbolIndex(TText * s) |
228 Elf32_Word ELFFile::ELFDllData::FindSymbolIndex(const char* s) |
264 { |
229 { |
265 TUint h = elf_hash(s); |
230 TUint h = elf_hash((const unsigned char*)s); |
266 TUint nb = iHashTable[0].nBuckets; |
231 TUint nb = iHashTable[0].nBuckets; |
267 TUint probe = h%nb; |
232 TUint probe = h%nb; |
268 Elf32_Sword * bucket = ELFADDR(Elf32_Sword, iHashTable, sizeof(Elf32_HashTable)); |
233 Elf32_Sword * bucket = ELFADDR(Elf32_Sword, iHashTable, sizeof(Elf32_HashTable)); |
269 Elf32_Sword * chain = ELFADDR(Elf32_Sword, bucket, nb * sizeof(Elf32_Sword)); |
234 Elf32_Sword * chain = ELFADDR(Elf32_Sword, bucket, nb * sizeof(Elf32_Sword)); |
270 Elf32_Sword idx = bucket[probe]; |
235 Elf32_Sword idx = bucket[probe]; |
271 |
236 |
272 do |
237 do |
273 { |
238 { |
274 if (!strcmp(ELFADDR(char, iDynStrTab, iDynSymTab[idx].st_name), (char *)s)) return idx; |
239 if (!strcmp(ELFADDR(char, iDynStrTab, iDynSymTab[idx].st_name), s)) return idx; |
275 idx = chain[idx]; |
240 idx = chain[idx]; |
276 } while (idx > 0); |
241 } while (idx > 0); |
277 if (idx == 0) idx = -1; |
242 if (idx == 0) idx = -1; |
278 return idx; |
243 return idx; |
279 } |
244 } |
280 |
245 |
281 TBool ELFFile::ELFDllData::InitExportInfo() |
246 TBool ELFFile::ELFDllData::InitExportInfo() |
282 { |
247 { |
283 memset(&iSymInfoHdr, 0, sizeof(iSymInfoHdr)); |
248 memset(&iSymInfoHdr, 0, sizeof(iSymInfoHdr)); |
284 TText * exp = (TText *)EXPORTTABLENAME; |
249 if ((iExportTableSymIdx = FindSymbolIndex(EXPORTTABLENAME)) != (Elf32_Word)-1) |
285 if ( int(iExportTableSymIdx = FindSymbolIndex(exp)) != -1 ) |
250 { |
286 { |
251 iExportTableSizeSymIdx = FindSymbolIndex(EXPORTTABLESIZENAME); |
287 TText * exps = (TText *)EXPORTTABLESIZENAME; |
|
288 iExportTableSizeSymIdx = FindSymbolIndex(exps); |
|
289 //TUint offset = iDynSymTab[iExportTableSizeSymIdx].st_value - (TUint)code; |
252 //TUint offset = iDynSymTab[iExportTableSizeSymIdx].st_value - (TUint)code; |
290 Elf32_Word * pNumberOfExports = iElfFile->CodePtrFromAddr(iDynSymTab[iExportTableSizeSymIdx].st_value); |
253 Elf32_Word * pNumberOfExports = iElfFile->CodePtrFromAddr(iDynSymTab[iExportTableSizeSymIdx].st_value); |
291 iNumberOfExports = * pNumberOfExports; |
254 iNumberOfExports = * pNumberOfExports; |
292 iImageIsDll = ETrue; |
255 iImageIsDll = ETrue; |
293 return ETrue; |
256 return ETrue; |
378 |
341 |
379 // sanity check: segment should be the code segment |
342 // sanity check: segment should be the code segment |
380 if (!iElfFile->CodeSegmentP(segment)) |
343 if (!iElfFile->CodeSegmentP(segment)) |
381 { |
344 { |
382 Print(EPeError, "Import relocation does not refer to code segment.\n"); |
345 Print(EPeError, "Import relocation does not refer to code segment.\n"); |
|
346 Print(EPeError, "Dll: %s\n", sym->iDll); |
|
347 Print(EPeError, "Ordinal: %d\n", sym->iOrd); |
|
348 Print(EPeError, "DLL name: %s\n", dll->iName); |
383 aSize = 0; |
349 aSize = 0; |
384 return 0; |
350 return 0; |
385 } |
351 } |
386 |
352 |
387 // This field is misnamed because it is actually given as a virtual address in |
353 // This field is misnamed because it is actually given as a virtual address in |
394 // We store there reloc offset in the top 16 bits of the 'reloc info'. |
360 // We store there reloc offset in the top 16 bits of the 'reloc info'. |
395 // NB the ELF reloc values should only ever be multiples of 4. So we could optimize here, |
361 // NB the ELF reloc values should only ever be multiples of 4. So we could optimize here, |
396 // but we won't. |
362 // but we won't. |
397 TUint relocVal = *relocAddr; |
363 TUint relocVal = *relocAddr; |
398 TUint importOrdinal = sym->iOrd; |
364 TUint importOrdinal = sym->iOrd; |
399 if (relocVal > 0xFFFF) |
365 if (relocVal > 0xFFFF) { |
400 Print(EPeError, "ELF relocation exceeds E32Image limit of 64K.\n"); |
366 Print(EPeError, "ELF relocation exceeds E32Image limit of 64K.\n"); |
401 if (importOrdinal > 0xFFFF) |
367 Print(EPeError, "Dll: %s\n", sym->iDll); |
|
368 Print(EPeError, "Ordinal: %d\n", sym->iOrd); |
|
369 Print(EPeError, "DLL name: %s\n", dll->iName); |
|
370 } |
|
371 if (importOrdinal > 0xFFFF) { |
402 Print(EPeError, "Import ordinal exceeds E32Image limit of 64K.\n"); |
372 Print(EPeError, "Import ordinal exceeds E32Image limit of 64K.\n"); |
403 |
373 Print(EPeError, "Dll: %s\n", sym->iDll); |
|
374 Print(EPeError, "Ordinal: %d\n", sym->iOrd); |
|
375 Print(EPeError, "DLL name: %s\n", dll->iName); |
|
376 } |
404 *rp = segOffset; |
377 *rp = segOffset; |
405 |
378 |
406 // eek !! surgery on the code segment.... |
379 // eek !! surgery on the code segment.... |
407 *relocAddr = (relocVal<<16) | importOrdinal; |
380 *relocAddr = (relocVal<<16) | importOrdinal; |
408 } |
381 } |
529 |
503 |
530 TBool ELFFile::ELFDllData::SetupSymbolValues() |
504 TBool ELFFile::ELFDllData::SetupSymbolValues() |
531 { |
505 { |
532 NamedExportSymbol *aSym, *aPrevSym; |
506 NamedExportSymbol *aSym, *aPrevSym; |
533 |
507 |
534 if( int(iExportTableSymIdx) == -1 || int(iExportTableSizeSymIdx) == -1) |
508 if( iExportTableSymIdx == (Elf32_Word)-1 || iExportTableSizeSymIdx == (Elf32_Word)-1) |
535 return FALSE; |
509 return FALSE; |
536 |
510 |
537 // Fetch the 'export table' symbol from the dynamic symbol table. |
511 // Fetch the 'export table' symbol from the dynamic symbol table. |
538 Elf32_Sym *aElfExpTbl = &iDynSymTab[iExportTableSymIdx]; |
512 Elf32_Sym *aElfExpTbl = &iDynSymTab[iExportTableSymIdx]; |
539 |
513 |