Mercurial > pub > dyncall > dyncall
annotate dynload/dynload_syms_pe.c @ 665:ef356272a1c7 default tip
- introduced Makefile var APP_SUFFIX to handle cases where compilers implicitly add an extension to executables (e.g. llvm/mingw64 adds .exe even of not specified via -o)
author | Tassilo Philipp |
---|---|
date | Thu, 20 Jun 2024 17:10:12 +0200 |
parents | 2d9f1cb06352 |
children |
rev | line source |
---|---|
0 | 1 /* |
2 | |
3 Package: dyncall | |
4 Library: dynload | |
5 File: dynload/dynload_syms_pe.c | |
281 | 6 Description: |
0 | 7 License: |
8 | |
281 | 9 Copyright (c) 2007-2018 Daniel Adler <dadler@uni-goettingen.de>, |
0 | 10 Tassilo Philipp <tphilipp@potion-studios.com> |
11 Olivier Chafik <olivier.chafik@gmail.com> | |
12 | |
13 Permission to use, copy, modify, and distribute this software for any | |
14 purpose with or without fee is hereby granted, provided that the above | |
15 copyright notice and this permission notice appear in all copies. | |
16 | |
17 THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES | |
18 WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF | |
19 MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR | |
20 ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES | |
21 WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN | |
22 ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF | |
23 OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. | |
24 | |
25 */ | |
26 | |
27 | |
28 | |
29 #include "dynload.h" | |
30 #include "dynload_alloc.h" | |
31 | |
32 #include <windows.h> | |
33 | |
34 struct DLSyms_ | |
35 { | |
36 DLLib* pLib; | |
37 const char* pBase; | |
38 const DWORD* pNames; | |
39 const DWORD* pFuncs; | |
40 const unsigned short* pOrds; | |
41 size_t count; | |
42 }; | |
43 | |
44 | |
45 DLSyms* dlSymsInit(const char* libPath) | |
46 { | |
230 | 47 DLLib* pLib; |
48 DLSyms* pSyms; | |
49 IMAGE_DOS_HEADER* pDOSHeader; | |
50 IMAGE_NT_HEADERS* pNTHeader; | |
51 IMAGE_DATA_DIRECTORY* pExportsDataDir; | |
52 IMAGE_EXPORT_DIRECTORY* pExports; | |
53 const char* base; | |
0 | 54 |
230 | 55 pLib = dlLoadLibrary(libPath); |
56 if(!pLib) | |
57 return NULL; | |
58 | |
59 base = (const char*)pLib; | |
60 pDOSHeader = (IMAGE_DOS_HEADER*)base; | |
61 pNTHeader = (IMAGE_NT_HEADERS*)(base + pDOSHeader->e_lfanew); | |
398 | 62 |
63 /* optional header present and big enough? this header should exist as it's only optional for object files */ | |
425
2d9f1cb06352
- dynload: corrected comparison of size of optional PE header info to what is pointed to (ptr arithmetic was incorrect, only broke ReactOS builds and runtime, though)
Tassilo Philipp
parents:
398
diff
changeset
|
64 if(pNTHeader->FileHeader.SizeOfOptionalHeader < ((char*)&pNTHeader->OptionalHeader.DataDirectory - (char*)&pNTHeader->OptionalHeader)) |
398 | 65 return NULL; |
66 | |
67 /* export table available? */ | |
68 if(pNTHeader->OptionalHeader.NumberOfRvaAndSizes <= IMAGE_DIRECTORY_ENTRY_EXPORT) | |
69 return NULL; | |
70 | |
230 | 71 pExportsDataDir = &pNTHeader->OptionalHeader.DataDirectory[IMAGE_DIRECTORY_ENTRY_EXPORT]; |
398 | 72 if(!pExportsDataDir->VirtualAddress) |
73 return NULL; | |
74 | |
230 | 75 pExports = (IMAGE_EXPORT_DIRECTORY*)(base + pExportsDataDir->VirtualAddress); |
76 | |
77 pSyms = (DLSyms*)dlAllocMem(sizeof(DLSyms)); | |
0 | 78 pSyms->pBase = base; |
79 pSyms->pNames = (DWORD*)(base + pExports->AddressOfNames); | |
80 pSyms->pFuncs = (DWORD*)(base + pExports->AddressOfFunctions); | |
81 pSyms->pOrds = (unsigned short*)(base + pExports->AddressOfNameOrdinals); | |
82 pSyms->count = (size_t)pExports->NumberOfNames; | |
83 pSyms->pLib = pLib; | |
84 | |
85 return pSyms; | |
86 } | |
87 | |
88 | |
89 void dlSymsCleanup(DLSyms* pSyms) | |
90 { | |
91 if(pSyms) { | |
92 dlFreeLibrary(pSyms->pLib); | |
93 dlFreeMem(pSyms); | |
94 } | |
95 } | |
96 | |
97 | |
98 int dlSymsCount(DLSyms* pSyms) | |
99 { | |
398 | 100 return pSyms ? (int)pSyms->count : 0; |
0 | 101 } |
102 | |
103 | |
104 const char* dlSymsName(DLSyms* pSyms, int index) | |
105 { | |
398 | 106 if(!pSyms || index < 0 || index >= pSyms->count) |
107 return NULL; | |
230 | 108 return pSyms->pBase + pSyms->pNames[index]; |
0 | 109 } |
110 | |
111 | |
230 | 112 const char* dlSymsNameFromValue(DLSyms* pSyms, void* value) |
0 | 113 { |
114 int i, c=dlSymsCount(pSyms); | |
115 for(i=0; i<c; ++i) | |
116 { | |
230 | 117 if((void*)(pSyms->pBase + pSyms->pFuncs[pSyms->pOrds[i]]) == value) |
0 | 118 return dlSymsName(pSyms, i); |
119 } | |
120 | |
121 /* Not found. */ | |
122 return NULL; | |
123 } | |
230 | 124 |