OcAppleKernelLib: Tune based on profiling data

This commit is contained in:
vit9696 2019-03-29 01:24:04 +03:00
parent afc7db0518
commit 8255f23ff0
10 changed files with 101 additions and 33 deletions

View File

@ -39,12 +39,14 @@ CONST PRELINKED_KEXT_SYMBOL *
InternalOcGetSymbolWorkerName (
IN PRELINKED_KEXT *Kext,
IN CONST CHAR8 *LookupValue,
IN UINT32 LookupValueLength,
IN OC_GET_SYMBOL_LEVEL SymbolLevel
)
{
PRELINKED_KEXT *Dependency;
CONST PRELINKED_KEXT_SYMBOL *Symbols;
CONST PRELINKED_KEXT_SYMBOL *SymbolsEnd;
CONST CHAR8 *LookedSymbol;
UINT32 Index;
UINT32 NumSymbols;
@ -63,8 +65,24 @@ InternalOcGetSymbolWorkerName (
SymbolsEnd = &Symbols[NumSymbols];
while (Symbols < SymbolsEnd) {
if (AsciiStrCmp (LookupValue, Symbols->Name) == 0) {
return Symbols;
//
// Symbol names often start and end similarly due to C++ mangling (e.g. __ZN).
// To optimise the lookup we compare their length check in the middle.
// Please do not change this without careful profiling.
//
if (Symbols->Length == LookupValueLength) {
LookedSymbol = Kext->StringTable + Symbols->Name;
if (LookedSymbol[LookupValueLength/2] == LookupValue[LookupValueLength/2]
&& LookedSymbol[LookupValueLength/2 + 1] == LookupValue[LookupValueLength/2 + 1]) {
for (Index = 0; Index < LookupValueLength; ++Index) {
if (LookedSymbol[Index] != LookupValue[Index]) {
break;
}
}
if (Index == LookupValueLength) {
return Symbols;
}
}
}
Symbols++;
}
@ -83,6 +101,7 @@ InternalOcGetSymbolWorkerName (
Symbols = InternalOcGetSymbolWorkerName (
Dependency,
LookupValue,
LookupValueLength,
OcGetSymbolOnlyCxx
);
if (Symbols != NULL) {
@ -165,7 +184,7 @@ CONST PRELINKED_KEXT_SYMBOL *
InternalOcGetSymbolName (
IN PRELINKED_CONTEXT *Context,
IN PRELINKED_KEXT *Kext,
IN UINT64 LookupValue,
IN CONST CHAR8 *LookupValue,
IN OC_GET_SYMBOL_LEVEL SymbolLevel
)
{
@ -173,11 +192,25 @@ InternalOcGetSymbolName (
PRELINKED_KEXT *Dependency;
UINT32 Index;
UINT32 LookupValueLength;
Symbol = NULL;
LookupValueLength = (UINT32) AsciiStrLen (LookupValue);
//
// Such symbols are illegit, but InternalOcGetSymbolWorkerName assumes Length > 0.
//
if (LookupValueLength == 0) {
return NULL;
}
if ((SymbolLevel == OcGetSymbolOnlyCxx) && (Kext->LinkedSymbolTable != NULL)) {
Symbol = InternalOcGetSymbolWorkerName (Kext, (CHAR8 *)(UINTN)LookupValue, SymbolLevel);
Symbol = InternalOcGetSymbolWorkerName (
Kext,
LookupValue,
LookupValueLength,
SymbolLevel
);
} else {
for (Index = 0; Index < ARRAY_SIZE (Kext->Dependencies); ++Index) {
Dependency = Kext->Dependencies[Index];
@ -187,7 +220,8 @@ InternalOcGetSymbolName (
Symbol = InternalOcGetSymbolWorkerName (
Dependency,
(CHAR8 *)(UINTN)LookupValue,
LookupValue,
LookupValueLength,
SymbolLevel
);
if (Symbol != NULL) {
@ -317,7 +351,7 @@ InternalSolveSymbolNonWeak64 (
ResolveSymbol = InternalOcGetSymbolName (
Context,
Kext,
(UINTN)Name,
Name,
OcGetSymbolFirstLevel
);
if (ResolveSymbol != NULL) {

View File

@ -34,7 +34,8 @@ typedef struct {
// Value is declared first as it has shown to improve comparison performance.
//
UINT64 Value; ///< value of this symbol (or stab offset)
CONST CHAR8 *Name; ///< name of this symbol
UINT32 Name; ///< name of this symbol
UINT32 Length;
} PRELINKED_KEXT_SYMBOL;
typedef struct {
@ -341,12 +342,11 @@ typedef enum {
OcGetSymbolOnlyCxx
} OC_GET_SYMBOL_LEVEL;
// TODO: Move?
CONST PRELINKED_KEXT_SYMBOL *
InternalOcGetSymbolName (
IN PRELINKED_CONTEXT *Context,
IN PRELINKED_KEXT *Kext,
IN UINT64 LookupValue,
IN CONST CHAR8 *LookupValue,
IN OC_GET_SYMBOL_LEVEL SymbolLevel
);

View File

@ -284,7 +284,7 @@ InternalScanBuildLinkedSymbolTable (
ResolvedSymbol = InternalOcGetSymbolName (
Context,
Kext,
(UINTN)Name,
Name,
OcGetSymbolFirstLevel
);
if (ResolvedSymbol == NULL) {
@ -297,12 +297,14 @@ InternalScanBuildLinkedSymbolTable (
}
if (!Result) {
WalkerBottom->Name = (Kext->StringTable + Symbol->UnifiedName.StringIndex);
WalkerBottom->Value = Symbol->Value;
WalkerBottom->Name = Symbol->UnifiedName.StringIndex;
WalkerBottom->Length = AsciiStrLen (Kext->StringTable + Symbol->UnifiedName.StringIndex);
++WalkerBottom;
} else {
WalkerTop->Name = (Kext->StringTable + Symbol->UnifiedName.StringIndex);
WalkerTop->Value = Symbol->Value;
WalkerTop->Value = Symbol->Value;
WalkerTop->Name = Symbol->UnifiedName.StringIndex;
WalkerTop->Length = AsciiStrLen (Kext->StringTable + Symbol->UnifiedName.StringIndex);
--WalkerTop;
++NumCxxSymbols;

View File

@ -135,7 +135,7 @@ InternalConstructVtablePrelinked64 (
if (Symbol != NULL) {
Vtable->Entries[Index].Address = Value;
Vtable->Entries[Index].Name = Symbol->Name;
Vtable->Entries[Index].Name = Kext->StringTable + Symbol->Name;
} else {
Vtable->Entries[Index].Address = 0;
Vtable->Entries[Index].Name = NULL;
@ -198,12 +198,12 @@ InternalPrepareCreateVtablesPrelinked64 (
++Index
) {
Symbol = &Kext->LinkedSymbolTable[Index];
if (MachoSymbolNameIsVtable64 (Symbol->Name)) {
if (MachoSymbolNameIsVtable64 (Kext->StringTable + Symbol->Name)) {
if ((Symbol->Value == 0) || (VtableIndex >= MaxSize)) {
return FALSE;
}
Vtables[VtableIndex].Name = Symbol->Name;
Vtables[VtableIndex].Name = Kext->StringTable + Symbol->Name;
Vtables[VtableIndex].Vtable.Value = Symbol->Value;
++VtableIndex;
}
@ -421,7 +421,7 @@ InternalInitializeVtableByEntriesAndRelocations64 (
OcGetSymbolOnlyCxx
);
if (OcSymbol != NULL) {
VtableEntries[Index].Name = OcSymbol->Name;
VtableEntries[Index].Name = Kext->StringTable + OcSymbol->Name;
VtableEntries[Index].Address = OcSymbol->Value;
continue;
}
@ -787,7 +787,7 @@ InternalPatchByVtables64 (
OcSymbolDummy = InternalOcGetSymbolName (
Context,
Kext,
(UINTN)FinalSymbolName,
FinalSymbolName,
OcGetSymbolAnyLevel
);
if (OcSymbolDummy != NULL) {

View File

@ -30,6 +30,18 @@ typedef INT32 int32_t;
#define compress_lzss CompressLZSS
#define decompress_lzss DecompressLZSS
#ifdef bzero
#undef bzero
#endif
#ifdef malloc
#undef malloc
#endif
#ifdef free
#undef free
#endif
#define bzero(Dst, Size) ZeroMem ((Dst), (Size))
#define malloc(Size) AllocatePool (Size)
#define free(Ptr) FreePool (Ptr)

View File

@ -31,6 +31,14 @@ typedef UINTN uintmax_t;
#define lzvn_decode_buffer DecompressLZVN
#ifdef memset
#undef memset
#endif
#ifdef memcpy
#undef memcpy
#endif
#define memset(Dst, Value, Size) SetMem ((Dst), (Size), (UINT8)(Value))
#define memcpy(Dst, Src, Size) CopyMem ((Dst), (Src), (Size))

View File

@ -238,9 +238,10 @@ XmlNodeChildPush (
}
//
// Allocate twice more room.
// Allocate three times more room.
// This balances performance and memory usage on large files like prelinked plist.
//
AllocCount *= 2;
AllocCount *= 3;
NewList = (XML_NODE_LIST *) AllocatePool (
sizeof (XML_NODE_LIST) + sizeof (NewList->NodeList[0]) * AllocCount

View File

@ -525,6 +525,17 @@ TestFileOpen (
return EFI_OUT_OF_RESOURCES;
}
#if 0
STATIC UINT32 DumpCounter;
CHAR16 DumpName[64];
UnicodeSPrint (DumpName, sizeof (DumpName), L"prel%u.bin", DumpCounter++);
Print (
L"Writing resulting kernel of %u bytes - %r\n",
KernelSize,
WriteFileData (NULL, DumpName, Kernel, KernelSize)
);
#endif
//
// Return our handle.
//

View File

@ -486,14 +486,14 @@ struct _LIST_ENTRY {
// Functions
//
#define AllocatePool(x) malloc(x)
#define AllocateZeroPool(x) calloc(1, x)
#define ReallocatePool(a,b,c) realloc(c,b)
#define FreePool(x) free(x)
#define CompareMem(a,b,c) memcmp((a),(b),(c))
#define CopyMem(a,b,c) memmove((a),(b),(c))
#define ZeroMem(a,b) memset(a, 0, b)
#define SetMem(Dst, Size, Value) memset(Dst, Value, Size)
#define AllocatePool(x) (malloc)(x)
#define AllocateZeroPool(x) (calloc)(1, x)
#define ReallocatePool(a,b,c) (realloc)(c,b)
#define FreePool(x) (free)(x)
#define CompareMem(a,b,c) (memcmp)((a),(b),(c))
#define CopyMem(a,b,c) (memmove)((a),(b),(c))
#define ZeroMem(a,b) (memset)(a, 0, b)
#define SetMem(Dst, Size, Value) (memset)(Dst, Value, Size)
#define AsciiSPrint snppprintf
#define AsciiStrCmp strcmp
#define AsciiStrLen strlen
@ -501,15 +501,15 @@ struct _LIST_ENTRY {
#define AsciiStrnCmp strncmp
#define AsciiStrSize(x) (strlen(x) + 1)
#define AsciiStrnCpyS(a, b, c, d) oc_strlcpy(a, c, b)
#define AsciiStrDecimalToUint64(a) strtoull(a, NULL, 10)
#define AsciiStrHexToUint64(a) strtoull(a, NULL, 16)
#define AsciiStrDecimalToUint64(a) (strtoull)(a, NULL, 10)
#define AsciiStrHexToUint64(a) (strtoull)(a, NULL, 16)
#define ASSERT(x) assert(x)
#define DebugCodeEnabled() true
#define DebugAssertEnabled() true
#define FreePages(a,b) do {} while (0)
#define UnicodeSPrint(...) assert(false)
#define CompareGuid(a, b) (memcmp((a), (b), sizeof (EFI_GUID)) == 0)
#define CopyGuid(a, b) memcpy((a), (b), sizeof (EFI_GUID))
#define CompareGuid(a, b) ((memcmp)((a), (b), sizeof (EFI_GUID)) == 0)
#define CopyGuid(a, b) (memcpy)((a), (b), sizeof (EFI_GUID))
EFI_STATUS EfiGetSystemConfigurationTable (EFI_GUID *TableGuid, OUT VOID **Table);

View File

@ -670,7 +670,7 @@ INT32 LLVMFuzzerTestOneInput(CONST UINT8 *Data, UINTN Size) {
}
int main(int argc, char *argv[]) {
for (size_t i = 0; i < 15; i++) {
for (size_t i = 0; i < 1; i++) {
wrap_main(argc, argv);
}
return 0;