OpenCore  1.0.4
OpenCore Bootloader
Loading...
Searching...
No Matches
CxxSymbols.c
Go to the documentation of this file.
1
15#include <Uefi.h>
16
18
19#include <Library/BaseLib.h>
20#include <Library/BaseMemoryLib.h>
21#include <Library/BaseOverflowLib.h>
22#include <Library/DebugLib.h>
23#include <Library/OcMachoLib.h>
24#include <Library/OcStringLib.h>
25
26#define CXX_PREFIX "__Z"
27#define VTABLE_PREFIX CXX_PREFIX "TV"
28#define OSOBJ_PREFIX CXX_PREFIX "N"
29#define RESERVED_TOKEN "_RESERVED"
30#define METACLASS_TOKEN "10gMetaClassE"
31#define SMCP_TOKEN "10superClassE"
32#define METACLASS_VTABLE_PREFIX VTABLE_PREFIX "N"
33#define METACLASS_VTABLE_SUFFIX "9MetaClassE"
34#define CXX_PURE_VIRTUAL "___cxa_pure_virtual"
35#define FINAL_CLASS_TOKEN "14__OSFinalClassEv"
36
37#define VTABLE_ENTRY_SIZE_64 8U
38#define VTABLE_HEADER_LEN_64 2U
39#define VTABLE_HEADER_SIZE_64 (VTABLE_HEADER_LEN_64 * VTABLE_ENTRY_SIZE_64)
40
41BOOLEAN
43 IN CONST CHAR8 *Name
44 )
45{
46 ASSERT (Name != NULL);
47 return (AsciiStrCmp (Name, CXX_PURE_VIRTUAL) == 0);
48}
49
50BOOLEAN
52 IN CONST CHAR8 *Name
53 )
54{
55 ASSERT (Name != NULL);
56 return (AsciiStrStr (Name, RESERVED_TOKEN) != NULL);
57}
58
59BOOLEAN
61 IN OUT OC_MACHO_CONTEXT *Context,
62 IN CONST CHAR8 *SymbolName
63 )
64{
65 CONST CHAR8 *Suffix;
66
67 ASSERT (Context != NULL);
68 ASSERT (SymbolName != NULL);
69 //
70 // Verify the symbol has...
71 // 1) The C++ prefix.
72 // 2) The SMCP suffix.
73 // 3) At least one character between the prefix and the suffix.
74 //
75 Suffix = AsciiStrStr (SymbolName, SMCP_TOKEN);
76
77 if ( (Suffix == NULL)
78 || (AsciiStrnCmp (SymbolName, OSOBJ_PREFIX, L_STR_LEN (OSOBJ_PREFIX)) != 0)
79 || ((UINTN)(Suffix - SymbolName) <= L_STR_LEN (OSOBJ_PREFIX)))
80 {
81 return FALSE;
82 }
83
84 return TRUE;
85}
86
87BOOLEAN
89 IN OUT OC_MACHO_CONTEXT *Context,
90 IN CONST CHAR8 *SymbolName
91 )
92{
93 CONST CHAR8 *Suffix;
94
95 ASSERT (Context != NULL);
96 ASSERT (SymbolName != NULL);
97 //
98 // Verify the symbol has...
99 // 1) The C++ prefix.
100 // 2) The MetaClass suffix.
101 // 3) At least one character between the prefix and the suffix.
102 //
103 Suffix = AsciiStrStr (SymbolName, METACLASS_TOKEN);
104
105 if ( (Suffix == NULL)
106 || (AsciiStrnCmp (SymbolName, OSOBJ_PREFIX, L_STR_LEN (OSOBJ_PREFIX)) != 0)
107 || ((UINTN)(Suffix - SymbolName) <= L_STR_LEN (OSOBJ_PREFIX)))
108 {
109 return FALSE;
110 }
111
112 return TRUE;
113}
114
115BOOLEAN
117 IN OUT OC_MACHO_CONTEXT *Context,
118 IN CONST CHAR8 *SmcpName,
119 IN UINTN ClassNameSize,
120 OUT CHAR8 *ClassName
121 )
122{
123 UINTN PrefixSize;
124 UINTN SuffixSize;
125 UINTN OutputSize;
126
127 ASSERT (Context != NULL);
128 ASSERT (SmcpName != NULL);
129 ASSERT (ClassNameSize > 0);
130 ASSERT (ClassName != NULL);
131
132 ASSERT (Context->StringTable != NULL);
133
134 ASSERT (MachoSymbolNameIsSmcp (Context, SmcpName));
135
136 PrefixSize = L_STR_LEN (OSOBJ_PREFIX);
137 SuffixSize = L_STR_LEN (SMCP_TOKEN);
138
139 OutputSize = (AsciiStrLen (SmcpName) - PrefixSize - SuffixSize);
140
141 if ((OutputSize + 1) > ClassNameSize) {
142 return FALSE;
143 }
144
145 CopyMem (ClassName, &SmcpName[PrefixSize], OutputSize);
146 ClassName[OutputSize] = '\0';
147
148 return TRUE;
149}
150
151CONST CHAR8 *
153 IN CONST CHAR8 *VtableName
154 )
155{
156 ASSERT (VtableName != NULL);
157 ASSERT (MachoSymbolNameIsVtable (VtableName));
158 //
159 // As there is no suffix, just return a pointer from within VtableName.
160 //
161 return &VtableName[L_STR_LEN (VTABLE_PREFIX)];
162}
163
164BOOLEAN
166 IN CONST CHAR8 *ClassName,
167 IN UINTN FunctionPrefixSize,
168 OUT CHAR8 *FunctionPrefix
169 )
170{
171 UINTN Index;
172 UINTN BodySize;
173 BOOLEAN Result;
174 UINTN TotalSize;
175
176 ASSERT (ClassName != NULL);
177 ASSERT (FunctionPrefixSize > 0);
178 ASSERT (FunctionPrefix != NULL);
179
180 BodySize = AsciiStrSize (ClassName);
181 Result = BaseOverflowAddUN (L_STR_LEN (OSOBJ_PREFIX), BodySize, &TotalSize);
182 if (Result || (FunctionPrefixSize < TotalSize)) {
183 return FALSE;
184 }
185
186 Index = 0;
187 CopyMem (
188 &FunctionPrefix[Index],
191 );
192
193 Index += L_STR_LEN (OSOBJ_PREFIX);
194 CopyMem (
195 &FunctionPrefix[Index],
196 ClassName,
197 BodySize
198 );
199
200 return TRUE;
201}
202
203BOOLEAN
205 IN OUT OC_MACHO_CONTEXT *Context,
206 IN CONST CHAR8 *MetaClassName,
207 IN UINTN ClassNameSize,
208 OUT CHAR8 *ClassName
209 )
210{
211 UINTN PrefixSize;
212 UINTN SuffixSize;
213 UINTN ClassNameLength;
214
215 ASSERT (Context != NULL);
216 ASSERT (MetaClassName != NULL);
217 ASSERT (ClassNameSize > 0);
218 ASSERT (ClassName != NULL);
219
220 ASSERT (Context->StringTable != NULL);
221
222 ASSERT (MachoSymbolNameIsMetaclassPointer (Context, MetaClassName));
223
224 PrefixSize = L_STR_LEN (OSOBJ_PREFIX);
225 SuffixSize = L_STR_LEN (METACLASS_TOKEN);
226
227 ClassNameLength = (AsciiStrLen (MetaClassName) - PrefixSize - SuffixSize);
228 if ((ClassNameLength + 1) > ClassNameSize) {
229 return FALSE;
230 }
231
232 CopyMem (ClassName, &MetaClassName[PrefixSize], ClassNameLength);
233 ClassName[ClassNameLength] = '\0';
234
235 return TRUE;
236}
237
238BOOLEAN
240 IN CONST CHAR8 *ClassName,
241 IN UINTN VtableNameSize,
242 OUT CHAR8 *VtableName
243 )
244{
245 UINTN Index;
246 UINTN BodySize;
247 BOOLEAN Result;
248 UINTN TotalSize;
249
250 ASSERT (ClassName != NULL);
251 ASSERT (VtableNameSize > 0);
252 ASSERT (VtableName != NULL);
253
254 BodySize = AsciiStrSize (ClassName);
255
256 Result = BaseOverflowAddUN (
258 BodySize,
259 &TotalSize
260 );
261 if (Result || (VtableNameSize < TotalSize)) {
262 return FALSE;
263 }
264
265 Index = 0;
266 CopyMem (
267 &VtableName[Index],
270 );
271
272 Index += L_STR_LEN (VTABLE_PREFIX);
273 CopyMem (&VtableName[Index], ClassName, BodySize);
274
275 return TRUE;
276}
277
278BOOLEAN
280 IN CONST CHAR8 *ClassName,
281 IN UINTN VtableNameSize,
282 OUT CHAR8 *VtableName
283 )
284{
285 UINTN BodyLength;
286 BOOLEAN Result;
287 UINTN TotalSize;
288 UINTN Index;
289
290 ASSERT (ClassName != NULL);
291 ASSERT (VtableNameSize > 0);
292 ASSERT (VtableName != NULL);
293
294 BodyLength = AsciiStrLen (ClassName);
295
296 Result = BaseOverflowTriAddUN (
298 BodyLength,
300 &TotalSize
301 );
302 if (Result || (VtableNameSize < TotalSize)) {
303 return FALSE;
304 }
305
306 Index = 0;
307 CopyMem (
308 &VtableName[Index],
311 );
312
314 CopyMem (&VtableName[Index], ClassName, BodyLength);
315
316 Index += BodyLength;
317 CopyMem (
318 &VtableName[Index],
321 );
322
323 return TRUE;
324}
325
326BOOLEAN
328 IN CONST CHAR8 *ClassName,
329 IN UINTN FinalSymbolNameSize,
330 OUT CHAR8 *FinalSymbolName
331 )
332{
333 UINTN BodyLength;
334 BOOLEAN Result;
335 UINTN TotalSize;
336 UINTN Index;
337
338 ASSERT (ClassName != NULL);
339 ASSERT (FinalSymbolNameSize > 0);
340 ASSERT (FinalSymbolName != NULL);
341
342 BodyLength = AsciiStrLen (ClassName);
343
344 Result = BaseOverflowTriAddUN (
346 BodyLength,
348 &TotalSize
349 );
350 if (Result || (FinalSymbolNameSize < TotalSize)) {
351 return FALSE;
352 }
353
354 Index = 0;
355 CopyMem (
356 &FinalSymbolName[Index],
359 );
360
361 Index += L_STR_LEN (OSOBJ_PREFIX);
362 CopyMem (
363 &FinalSymbolName[Index],
364 ClassName,
365 BodyLength
366 );
367
368 Index += BodyLength;
369 CopyMem (
370 &FinalSymbolName[Index],
373 );
374
375 return TRUE;
376}
377
378BOOLEAN
380 IN CONST CHAR8 *SymbolName
381 )
382{
383 ASSERT (SymbolName != NULL);
384 //
385 // Implicitely checks for METACLASS_VTABLE_PREFIX.
386 //
387 return AsciiStrnCmp (SymbolName, VTABLE_PREFIX, L_STR_LEN (VTABLE_PREFIX)) == 0;
388}
389
390BOOLEAN
392 IN CONST CHAR8 *Name
393 )
394{
395 ASSERT (Name != NULL);
396 return AsciiStrnCmp (Name, CXX_PREFIX, L_STR_LEN (CXX_PREFIX)) == 0;
397}
398
401 IN OUT OC_MACHO_CONTEXT *Context,
402 IN CONST MACH_NLIST_ANY *Smcp
403 )
404{
405 ASSERT (Context != NULL);
406
407 return Context->Is32Bit ?
408 (MACH_NLIST_ANY *)MachoGetMetaclassSymbolFromSmcpSymbol32 (Context, &Smcp->Symbol32) :
409 (MACH_NLIST_ANY *)MachoGetMetaclassSymbolFromSmcpSymbol64 (Context, &Smcp->Symbol64);
410}
411
412BOOLEAN
414 IN OUT OC_MACHO_CONTEXT *Context,
415 IN CONST CHAR8 *SmcpName,
416 OUT CONST MACH_NLIST_ANY **Vtable,
417 OUT CONST MACH_NLIST_ANY **MetaVtable
418 )
419{
420 ASSERT (Context != NULL);
421
422 return Context->Is32Bit ?
423 MachoGetVtableSymbolsFromSmcp32 (Context, SmcpName, (CONST MACH_NLIST **)Vtable, (CONST MACH_NLIST **)MetaVtable) :
424 MachoGetVtableSymbolsFromSmcp64 (Context, SmcpName, (CONST MACH_NLIST_64 **)Vtable, (CONST MACH_NLIST_64 **)MetaVtable);
425}
#define RESERVED_TOKEN
Definition CxxSymbols.c:29
BOOLEAN MachoSymbolNameIsCxx(IN CONST CHAR8 *Name)
Definition CxxSymbols.c:391
#define CXX_PREFIX
Definition CxxSymbols.c:26
BOOLEAN MachoSymbolNameIsPadslot(IN CONST CHAR8 *Name)
Definition CxxSymbols.c:51
BOOLEAN MachoGetClassNameFromMetaClassPointer(IN OUT OC_MACHO_CONTEXT *Context, IN CONST CHAR8 *MetaClassName, IN UINTN ClassNameSize, OUT CHAR8 *ClassName)
Definition CxxSymbols.c:204
#define OSOBJ_PREFIX
Definition CxxSymbols.c:28
BOOLEAN MachoGetClassNameFromSuperMetaClassPointer(IN OUT OC_MACHO_CONTEXT *Context, IN CONST CHAR8 *SmcpName, IN UINTN ClassNameSize, OUT CHAR8 *ClassName)
Definition CxxSymbols.c:116
#define SMCP_TOKEN
Definition CxxSymbols.c:31
#define FINAL_CLASS_TOKEN
Definition CxxSymbols.c:35
CONST CHAR8 * MachoGetClassNameFromVtableName(IN CONST CHAR8 *VtableName)
Definition CxxSymbols.c:152
BOOLEAN MachoGetVtableSymbolsFromSmcp(IN OUT OC_MACHO_CONTEXT *Context, IN CONST CHAR8 *SmcpName, OUT CONST MACH_NLIST_ANY **Vtable, OUT CONST MACH_NLIST_ANY **MetaVtable)
Definition CxxSymbols.c:413
BOOLEAN MachoGetFunctionPrefixFromClassName(IN CONST CHAR8 *ClassName, IN UINTN FunctionPrefixSize, OUT CHAR8 *FunctionPrefix)
Definition CxxSymbols.c:165
#define METACLASS_VTABLE_PREFIX
Definition CxxSymbols.c:32
BOOLEAN MachoGetFinalSymbolNameFromClassName(IN CONST CHAR8 *ClassName, IN UINTN FinalSymbolNameSize, OUT CHAR8 *FinalSymbolName)
Definition CxxSymbols.c:327
MACH_NLIST_ANY * MachoGetMetaclassSymbolFromSmcpSymbol(IN OUT OC_MACHO_CONTEXT *Context, IN CONST MACH_NLIST_ANY *Smcp)
Definition CxxSymbols.c:400
BOOLEAN MachoSymbolNameIsMetaclassPointer(IN OUT OC_MACHO_CONTEXT *Context, IN CONST CHAR8 *SymbolName)
Definition CxxSymbols.c:88
#define VTABLE_PREFIX
Definition CxxSymbols.c:27
#define METACLASS_TOKEN
Definition CxxSymbols.c:30
BOOLEAN MachoSymbolNameIsVtable(IN CONST CHAR8 *SymbolName)
Definition CxxSymbols.c:379
BOOLEAN MachoGetVtableNameFromClassName(IN CONST CHAR8 *ClassName, IN UINTN VtableNameSize, OUT CHAR8 *VtableName)
Definition CxxSymbols.c:239
BOOLEAN MachoSymbolNameIsSmcp(IN OUT OC_MACHO_CONTEXT *Context, IN CONST CHAR8 *SymbolName)
Definition CxxSymbols.c:60
BOOLEAN MachoSymbolNameIsPureVirtual(IN CONST CHAR8 *Name)
Definition CxxSymbols.c:42
#define CXX_PURE_VIRTUAL
Definition CxxSymbols.c:34
BOOLEAN MachoGetMetaVtableNameFromClassName(IN CONST CHAR8 *ClassName, IN UINTN VtableNameSize, OUT CHAR8 *VtableName)
Definition CxxSymbols.c:279
#define METACLASS_VTABLE_SUFFIX
Definition CxxSymbols.c:33
MACH_NLIST_64 * MachoGetMetaclassSymbolFromSmcpSymbol64(IN OUT OC_MACHO_CONTEXT *Context, IN CONST MACH_NLIST_64 *Smcp)
BOOLEAN MachoGetVtableSymbolsFromSmcp32(IN OUT OC_MACHO_CONTEXT *Context, IN CONST CHAR8 *SmcpName, OUT CONST MACH_NLIST **Vtable, OUT CONST MACH_NLIST **MetaVtable)
MACH_NLIST * MachoGetMetaclassSymbolFromSmcpSymbol32(IN OUT OC_MACHO_CONTEXT *Context, IN CONST MACH_NLIST *Smcp)
BOOLEAN MachoGetVtableSymbolsFromSmcp64(IN OUT OC_MACHO_CONTEXT *Context, IN CONST CHAR8 *SmcpName, OUT CONST MACH_NLIST_64 **Vtable, OUT CONST MACH_NLIST_64 **MetaVtable)
#define L_STR_LEN(String)
Definition OcStringLib.h:26
#define L_STR_SIZE(String)
Definition OcStringLib.h:35
VOID *EFIAPI CopyMem(OUT VOID *DestinationBuffer, IN CONST VOID *SourceBuffer, IN UINTN Length)
#define ASSERT(x)
Definition coder.h:55