1 | #!/usr/bin/env python
|
---|
2 | # -*- coding: utf-8 -*-
|
---|
3 | # $Id: icd_forwarders.py 106674 2024-10-24 21:31:30Z vboxsync $
|
---|
4 |
|
---|
5 | """
|
---|
6 | Generates forwards from a .def file.
|
---|
7 | """
|
---|
8 |
|
---|
9 | __copyright__ = \
|
---|
10 | """
|
---|
11 | Copyright (C) 2018-2024 Oracle and/or its affiliates.
|
---|
12 |
|
---|
13 | This file is part of VirtualBox base platform packages, as
|
---|
14 | available from https://www.virtualbox.org.
|
---|
15 |
|
---|
16 | This program is free software; you can redistribute it and/or
|
---|
17 | modify it under the terms of the GNU General Public License
|
---|
18 | as published by the Free Software Foundation, in version 3 of the
|
---|
19 | License.
|
---|
20 |
|
---|
21 | This program is distributed in the hope that it will be useful, but
|
---|
22 | WITHOUT ANY WARRANTY; without even the implied warranty of
|
---|
23 | MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
|
---|
24 | General Public License for more details.
|
---|
25 |
|
---|
26 | You should have received a copy of the GNU General Public License
|
---|
27 | along with this program; if not, see <https://www.gnu.org/licenses>.
|
---|
28 |
|
---|
29 | SPDX-License-Identifier: GPL-3.0-only
|
---|
30 | """
|
---|
31 | __version__ = "$Revision: 106674 $"
|
---|
32 |
|
---|
33 | # Standard python imports"""
|
---|
34 | import sys
|
---|
35 |
|
---|
36 |
|
---|
37 | def GenerateForwarders(asArgs):
|
---|
38 |
|
---|
39 | if len(asArgs) != 4:
|
---|
40 | raise Exception('Expected 3 arguments, not %u!' % (len(asArgs) - 1,));
|
---|
41 |
|
---|
42 | # Get list of functions.
|
---|
43 | asNames = []
|
---|
44 | asParamSizes = []
|
---|
45 | with open(asArgs[1], "r") as oInFile:
|
---|
46 | for line in oInFile.readlines():
|
---|
47 | line = line.strip()
|
---|
48 | if len(line) > 0 and line[0] != ';' and line != 'EXPORTS':
|
---|
49 | # Parse 'glAccum = glAccum@8'
|
---|
50 | words = line.split('=', 1)
|
---|
51 |
|
---|
52 | # Function name
|
---|
53 | asNames.append(words[0].strip())
|
---|
54 |
|
---|
55 | # Size of arguments in bytes
|
---|
56 | words = words[1].split('@')
|
---|
57 | asParamSizes.append(words[1].strip())
|
---|
58 |
|
---|
59 |
|
---|
60 | #
|
---|
61 | # Assembler forwarders
|
---|
62 | #
|
---|
63 | if asArgs[3] in ('x86', 'amd64',):
|
---|
64 | asLines = [
|
---|
65 | '; AUTOGENERATED - DO NOT EDIT!',
|
---|
66 | '%include "iprt/asmdefs.mac"',
|
---|
67 | '',
|
---|
68 | ';;;; Enable ICD_LAZY_LOAD to lazy load the ICD DLL - bird 2024-10-24: it should work again now',
|
---|
69 | '; %define ICD_LAZY_LOAD 1',
|
---|
70 | '',
|
---|
71 | '%ifdef ICD_LAZY_LOAD',
|
---|
72 | 'extern NAME(g_hmodICD)',
|
---|
73 | 'extern NAME(VBoxLoadICD)',
|
---|
74 | '',
|
---|
75 | 'BEGINPROC VBoxLoadICDWrapper',
|
---|
76 | ' ; Check if loaded',
|
---|
77 | ' mov xAX, [NAME(g_hmodICD) xWrtRIP]',
|
---|
78 | ' test xAX, xAX',
|
---|
79 | ' jz .needs_loading',
|
---|
80 | ' ret',
|
---|
81 | ' ; Save parameter registers',
|
---|
82 | '.needs_loading:',
|
---|
83 | ' %ifdef RT_ARCH_AMD64',
|
---|
84 | ' push rcx',
|
---|
85 | ' push rdx',
|
---|
86 | ' push r8',
|
---|
87 | ' push r9',
|
---|
88 | ' %ifdef ASM_CALL64_GCC',
|
---|
89 | ' push rsi',
|
---|
90 | ' push rdi',
|
---|
91 | ' sub rsp, 8h',
|
---|
92 | ' %else',
|
---|
93 | ' sub rsp, 28h',
|
---|
94 | ' %endif',
|
---|
95 | ' %endif',
|
---|
96 | ' ; Make the call',
|
---|
97 | ' call NAME(VBoxLoadICD)',
|
---|
98 | ' ; Restore parameter registers',
|
---|
99 | ' %ifdef RT_ARCH_AMD64',
|
---|
100 | ' %ifdef ASM_CALL64_GCC',
|
---|
101 | ' add rsp, 8h',
|
---|
102 | ' pop rdi',
|
---|
103 | ' pop rsi',
|
---|
104 | ' %else',
|
---|
105 | ' add rsp, 28h',
|
---|
106 | ' %endif',
|
---|
107 | ' pop r9',
|
---|
108 | ' pop r8',
|
---|
109 | ' pop rdx',
|
---|
110 | ' pop rcx',
|
---|
111 | ' %endif',
|
---|
112 | ' ret',
|
---|
113 | 'ENDPROC VBoxLoadICDWrapper',
|
---|
114 | '%endif ; ICD_LAZY_LOAD',
|
---|
115 | ];
|
---|
116 |
|
---|
117 | for iFn, sFnNm in enumerate(asNames):
|
---|
118 | cbRet = asParamSizes[iFn]
|
---|
119 | asLines.extend([
|
---|
120 | '',
|
---|
121 | 'BEGINPROC_EXPORTED %s' % sFnNm,
|
---|
122 | ' extern NAME(g_pfn_%s)' % sFnNm,
|
---|
123 | '; int3',
|
---|
124 | '%ifdef ICD_LAZY_LOAD',
|
---|
125 | ' call VBoxLoadICDWrapper',
|
---|
126 | '%endif',
|
---|
127 | ' mov xAX, [NAME(g_pfn_%s) xWrtRIP]' % sFnNm,
|
---|
128 | ' test xAX, xAX',
|
---|
129 | ' jz .return',
|
---|
130 | ' jmp xAX',
|
---|
131 | '.return:',
|
---|
132 | '%ifdef RT_ARCH_AMD64',
|
---|
133 | ' ret',
|
---|
134 | '%else ; X86',
|
---|
135 | ' ret %s' % cbRet,
|
---|
136 | '%endif',
|
---|
137 | 'ENDPROC %s' % sFnNm,
|
---|
138 | ]);
|
---|
139 |
|
---|
140 | elif asArgs[3] == 'arm64':
|
---|
141 | asLines = [
|
---|
142 | '/* AUTOGENERATED - DO NOT EDIT!*/',
|
---|
143 | '#include "iprt/asmdefs-arm.h"',
|
---|
144 | '',
|
---|
145 | '/** Enable ICD_LAZY_LOAD to lazy load the ICD DLL */',
|
---|
146 | '/* #define ICD_LAZY_LOAD 1*/',
|
---|
147 | '',
|
---|
148 | '#ifdef ICD_LAZY_LOAD',
|
---|
149 | ' .p2align 4',
|
---|
150 | 'BEGINPROC VBoxLoadICDWrapper',
|
---|
151 | ' ; Check if loaded',
|
---|
152 | ' adrp x8, PAGE(NAME(g_hmodICD))',
|
---|
153 | ' ldr x8, [x8, PAGEOFF(NAME(g_hmodICD))]',
|
---|
154 | ' cbz x8, Lneeds_loading',
|
---|
155 | ' ret',
|
---|
156 | 'Lneeds_loading:',
|
---|
157 | ' /* Save parameter registers */',
|
---|
158 | ' stp x0, x1, [sp, #-0x50]!',
|
---|
159 | ' stp x2, x3, [sp, #0x10]',
|
---|
160 | ' stp x4, x5, [sp, #0x20]',
|
---|
161 | ' stp x6, x7, [sp, #0x30]',
|
---|
162 | ' stp x29, x30, [sp, #0x40]',
|
---|
163 | ' /* Make the call */',
|
---|
164 | ' bl NAME(VBoxLoadICD)',
|
---|
165 | ' /* Restore parameter registers */',
|
---|
166 | ' ldp x0, x1, [sp, #0x00]',
|
---|
167 | ' ldp x2, x3, [sp, #x10]',
|
---|
168 | ' ldp x4, x5, [sp, #x20]',
|
---|
169 | ' ldp x6, x7, [sp, #x30]',
|
---|
170 | ' ldp x29, x30, [sp, #x40]',
|
---|
171 | ' add sp, sp #0x50',
|
---|
172 | ' ret',
|
---|
173 | 'ENDPROC VBoxLoadICDWrapper',
|
---|
174 | '#endif /* ICD_LAZY_LOAD */',
|
---|
175 | ];
|
---|
176 |
|
---|
177 | for sFnNm in asNames:
|
---|
178 | asLines.extend([
|
---|
179 | '',
|
---|
180 | ' .p2align 3',
|
---|
181 | 'BEGINPROC_EXPORTED %s' % (sFnNm,),
|
---|
182 | '; brk #0x8888',
|
---|
183 | '#ifdef ICD_LAZY_LOAD',
|
---|
184 | ' bl VBoxLoadICDWrapper',
|
---|
185 | '#endif',
|
---|
186 | ' adrp x8, PAGE(NAME(g_pfn_%s))' % (sFnNm,),
|
---|
187 | ' ldr x8, [x8, PAGEOFF(NAME(g_pfn_%s))]' % (sFnNm,),
|
---|
188 | ' cbz x8, Lreturn_%s' % (sFnNm,),
|
---|
189 | ' br x8',
|
---|
190 | 'Lreturn_%s:' % (sFnNm,),
|
---|
191 | ' ret',
|
---|
192 | 'ENDPROC %s' % (sFnNm,),
|
---|
193 | ]);
|
---|
194 |
|
---|
195 | else:
|
---|
196 | raise Exception('Unsupported target architecture: %s' % (asArgs[3],));
|
---|
197 |
|
---|
198 | #
|
---|
199 | # Write it out.
|
---|
200 | #
|
---|
201 | with open(asArgs[2], "w") as oOutFile:
|
---|
202 | oOutFile.write('\n'.join(asLines));
|
---|
203 |
|
---|
204 | return 0;
|
---|
205 |
|
---|
206 | if __name__ == '__main__':
|
---|
207 | sys.exit(GenerateForwarders(sys.argv));
|
---|
208 |
|
---|