Changeset 87282 in vbox
- Timestamp:
- Jan 15, 2021 8:38:06 PM (4 years ago)
- File:
-
- 1 edited
-
trunk/src/bldprogs/VBoxDef2LazyLoad.cpp (modified) (7 diffs)
Legend:
- Unmodified
- Added
- Removed
-
trunk/src/bldprogs/VBoxDef2LazyLoad.cpp
r82968 r87282 27 27 #include <stdlib.h> 28 28 #include <iprt/types.h> 29 #include <iprt/ldr.h> /* For RTLDRARCH. */ 29 30 30 31 … … 46 47 47 48 48 49 49 /********************************************************************************************************************************* 50 50 * Global Variables * … … 59 59 static bool g_fWithExplictLoadFunction = false; 60 60 static bool g_fSystemLibrary = false; 61 #if defined(RT_ARCH_AMD64) 62 static RTLDRARCH g_enmTarget = RTLDRARCH_AMD64; 63 #elif defined(RT_ARCH_X86) 64 static RTLDRARCH g_enmTarget = RTLDRARCH_X86; 65 #elif defined(RT_ARCH_ARM64) 66 static RTLDRARCH g_enmTarget = RTLDRARCH_ARM64; 67 #else 68 # error "Port me!" 69 #endif 61 70 /** @} */ 62 71 … … 321 330 322 331 /** 323 * Generates the assembly source code, writing it to @a pOutput. 332 * Generates the assembly source code for AMD64 and x86, writing it 333 * to @a pOutput. 324 334 * 325 335 * @returns RTEXITCODE_SUCCESS or RTEXITCODE_FAILURE, in the latter case full … … 328 338 * when closing). 329 339 */ 330 static RTEXITCODE generateOutputInner (FILE *pOutput)340 static RTEXITCODE generateOutputInnerX86AndAMD64(FILE *pOutput) 331 341 { 332 342 fprintf(pOutput, ";;\n"); … … 983 993 984 994 /** 995 * Generates the assembly source code for ARM64, writing it 996 * to @a pOutput. 997 * 998 * @returns RTEXITCODE_SUCCESS or RTEXITCODE_FAILURE, in the latter case full 999 * details has been displayed. 1000 * @param pOutput The output stream (caller checks it for errors 1001 * when closing). 1002 */ 1003 static RTEXITCODE generateOutputInnerArm64(FILE *pOutput) 1004 { 1005 // bool fMachO = true; 1006 // bool fDarwin = true; 1007 const char *pszNmPfx = "_"; 1008 1009 fprintf(pOutput, ";;\n"); 1010 for (unsigned i = 0; i < g_cInputs; i++) 1011 fprintf(pOutput, ";; Autogenerated from '%s'.\n", g_apszInputs[i]); 1012 1013 fprintf(pOutput, 1014 ";; DO NOT EDIT!\n" 1015 ";;\n" 1016 "\n" 1017 "\n" 1018 /*"%%include \"iprt/asmdefs.mac\"\n"*/ 1019 "\n" 1020 "\n"); 1021 1022 /* 1023 * Put the thunks first for alignment and other reasons. It's the hot part of the code. 1024 */ 1025 fprintf(pOutput, 1026 ";\n" 1027 "; Thunks.\n" 1028 ";\n" 1029 ".section __TEXT,__text,regular,pure_instructions\n" 1030 ".p2align 2\n"); 1031 for (PMYEXPORT pExp = g_pExpHead; pExp; pExp = pExp->pNext) 1032 fprintf(pOutput, 1033 ".globl %s%s\n" 1034 "%s%s:\n" 1035 " ldr x9, =g_pfn%s\n" 1036 " blr x9\n", 1037 pszNmPfx, pExp->szName, pszNmPfx, pExp->szName, pExp->szName); 1038 fprintf(pOutput, 1039 "\n" 1040 "\n"); 1041 1042 /* 1043 * Import pointers 1044 */ 1045 fprintf(pOutput, 1046 ";\n" 1047 "; Import pointers. Initialized to point a lazy loading stubs.\n" 1048 ";\n" 1049 ".section __DATA,__data\n" 1050 ".p2align 2\n" 1051 "g_apfnImports:\n"); 1052 for (PMYEXPORT pExp = g_pExpHead; pExp; pExp = pExp->pNext) 1053 fprintf(pOutput, 1054 ".globl __imp_%s\n" 1055 "__imp_%s:\n" 1056 ".globl %sg_pfn%s\n" 1057 "%sg_pfn%s:\n" 1058 " .quad ___LazyLoad___%s\n" 1059 "\n", 1060 pExp->szName, pExp->szName, 1061 pszNmPfx, pExp->szName, pszNmPfx, pExp->szName, 1062 pExp->pszExportedNm); 1063 fprintf(pOutput, 1064 " .quad 0 ; Terminator entry for traversal.\n" 1065 "\n" 1066 "\n"); 1067 1068 /* 1069 * Now for the less important stuff, starting with the names. 1070 * 1071 * We keep the names separate so we can traverse them in parallel to 1072 * g_apfnImports in the load-everything routine further down. 1073 */ 1074 fprintf(pOutput, 1075 ";\n" 1076 "; Imported names.\n" 1077 ";\n" 1078 ".section __TEXT,__cstring,cstring_literals\n" 1079 "g_szLibrary:\n" 1080 " .asciz \"%s\"\n" 1081 "\n" 1082 "g_szzNames:\n", 1083 g_pszLibrary); 1084 for (PMYEXPORT pExp = g_pExpHead; pExp; pExp = pExp->pNext) 1085 if (!pExp->fNoName) 1086 fprintf(pOutput, " g_sz%s:\n .asciz \"%s\"\n", pExp->pszExportedNm, pExp->pszExportedNm); 1087 else 1088 fprintf(pOutput, " g_sz%s:\n .asciz \"#%u\"\n", pExp->pszExportedNm, pExp->uOrdinal); 1089 fprintf(pOutput, 1090 "g_EndOfNames: .byte 0\n" 1091 "\n" 1092 "g_szFailLoadFmt: .asciz \"Lazy loader failed to load \\\"%%s\\\": %%Rrc\\n\"\n" 1093 "g_szFailResolveFmt: .asciz \"Lazy loader failed to resolve symbol \\\"%%s\\\" in \\\"%%s\\\": %%Rrc\\n\"\n" 1094 "\n" 1095 "\n"); 1096 1097 /* 1098 * The per import lazy load code. 1099 */ 1100 fprintf(pOutput, 1101 ";\n" 1102 "; Lazy load+resolve stubs.\n" 1103 ";\n" 1104 ".section __TEXT,__text,regular,pure_instructions\n" 1105 ".p2align 2\n"); 1106 for (PMYEXPORT pExp = g_pExpHead; pExp; pExp = pExp->pNext) 1107 { 1108 if (!pExp->fNoName) 1109 fprintf(pOutput, 1110 "___LazyLoad___%s:\n" 1111 " ldr x9, =g_sz%s\n" 1112 " ldr x10, =g_pfn%s\n" 1113 " bl LazyLoadResolver\n" 1114 , pExp->pszExportedNm, pExp->pszExportedNm, pExp->pszExportedNm); 1115 else 1116 fprintf(pOutput, 1117 "___LazyLoad___%s:\n" 1118 " movk w9, #%u\n" 1119 " ldr x10, =g_pfn%s\n" 1120 " bl LazyLoadResolver\n" 1121 , pExp->pszExportedNm, pExp->uOrdinal, pExp->pszExportedNm); 1122 fprintf(pOutput, " b %s%s\n", pszNmPfx, pExp->szName); 1123 fprintf(pOutput, "\n"); 1124 } 1125 fprintf(pOutput, 1126 "\n" 1127 "\n" 1128 "\n"); 1129 1130 /* 1131 * The code that does the loading and resolving. 1132 */ 1133 fprintf(pOutput, 1134 ";\n" 1135 "; The module handle.\n" 1136 ";\n" 1137 ".section __DATA,__data\n" 1138 "g_hMod:\n" 1139 " .quad 0\n" 1140 "\n" 1141 "\n" 1142 "\n"); 1143 1144 /* 1145 * Common lazy loader and resolved. 1146 */ 1147 fprintf(pOutput, 1148 ";\n" 1149 "; The resolver code.\n" 1150 ";\n" 1151 ".section __TEXT,__text,regular,pure_instructions\n" 1152 ".p2align 2\n" 1153 "LazyLoadResolver:\n" 1154 " .cfi_startproc\n" 1155 " ; Create frame.\n" 1156 " sub sp, sp, #(16 + 192)\n" 1157 " stp x29, x30, [sp, #192]\n" 1158 " add x29, sp, #192\n" 1159 " .cfi_def_cfa x29, 16\n" 1160 " .cfi_offset x30, -8\n" 1161 " .cfi_offset x29, -16\n" 1162 " ; Save all argument registers and a handful of preserved ones.\n" 1163 " stp x0, x1, [sp, #(192 - 16)]\n" 1164 " .cfi_offset x0, -32\n" 1165 " .cfi_offset x1, -24\n" 1166 " stp x2, x3, [sp, #(192 - 32)]\n" 1167 " .cfi_offset x3, -40\n" 1168 " .cfi_offset x2, -48\n" 1169 " stp x4, x5, [sp, #(192 - 48)]\n" 1170 " .cfi_offset x6, -56\n" 1171 " .cfi_offset x5, -64\n" 1172 " stp x6, x7, [sp, #(192 - 64)]\n" 1173 " .cfi_offset x7, -72\n" 1174 " .cfi_offset x6, -80\n" 1175 " stp x16, x17, [sp, #(192 - 80)]\n" 1176 " .cfi_offset x17, -88\n" 1177 " .cfi_offset x16, -96\n" 1178 " stp x18, x19, [sp, #(192 - 96)]\n" 1179 " .cfi_offset x19, -104\n" 1180 " .cfi_offset x18, -112\n" 1181 " stp x20, x21, [sp, #(192 - 112)]\n" 1182 " .cfi_offset x21, -120\n" 1183 " .cfi_offset x20, -128\n" 1184 " stp x22, x23, [sp, #(192 - 128)]\n" 1185 " .cfi_offset x23, -136\n" 1186 " .cfi_offset x22, -144\n" 1187 " str x8, [sp, #(192 - 144)]\n" 1188 "\n" 1189 " ; Shift the symbol name to x19 and g_pfnXXXX pointer to x20 as these are preserved registers\n" 1190 " ; (in case we need to call LazyLoadModule/RTLdrLoad)\n" 1191 " mov x19, x9\n" 1192 " mov x20, x10\n" 1193 "\n" 1194 " ; Get the module handle and call RTLdrGetSymbol(RTLDRMOD hLdrMod, const char *pszSymbol, void **ppvValue)\n" 1195 " ldr x0, =g_hMod\n" 1196 " ldr x0, [x0]\n" 1197 " cmp x0, #0\n" 1198 " b.eq LazyLoading\n" 1199 " mov x1, x19\n" 1200 " mov x2, x20\n" 1201 " bl %sRTLdrGetSymbol\n" 1202 "\n" 1203 " cmp w0, #0\n" 1204 " b.eq Lreturn\n" 1205 "\n" 1206 "Lbadsym: ; Call sRTAssertMsg2Weak. Variadic (...) arguments are passed on the stack it seems.\n" 1207 " mov x3, x0\n" 1208 " ldr x2, =g_szLibrary\n" 1209 " mov x1, x19\n" 1210 " ldr x0, =g_szFailLoadFmt\n" 1211 " stp x1, x2, [sp]\n" 1212 " str x3, [sp, #16]\n" 1213 " bl %sRTAssertMsg2Weak\n" 1214 "Lbadsymloop:\n" 1215 " brk #0x1\n" 1216 " b Lbadsymloop\n" 1217 1218 "Lreturn:\n" 1219 " ; Restore saved register\n" 1220 " ldr x8, [sp, #(192 - 144)]\n" 1221 " .cfi_restore x8\n" 1222 " ldp x22, x23, [sp, #(192 - 128)]\n" 1223 " .cfi_restore x23\n" 1224 " .cfi_restore x22\n" 1225 " ldp x20, x21, [sp, #(192 - 112)]\n" 1226 " .cfi_restore x21\n" 1227 " .cfi_restore x20\n" 1228 " ldp x18, x19, [sp, #(192 - 96)]\n" 1229 " .cfi_restore x19\n" 1230 " .cfi_restore x18\n" 1231 " ldp x16, x17, [sp, #(192 - 80)]\n" 1232 " .cfi_restore x17\n" 1233 " .cfi_restore x18\n" 1234 " ldp x6, x7, [sp, #(192 - 64)]\n" 1235 " .cfi_restore x7\n" 1236 " .cfi_restore x6\n" 1237 " ldp x4, x5, [sp, #(192 - 48)]\n" 1238 " .cfi_restore x5\n" 1239 " .cfi_restore x4\n" 1240 " ldp x2, x3, [sp, #(192 - 32)]\n" 1241 " .cfi_restore x3\n" 1242 " .cfi_restore x2\n" 1243 " ldp x0, x1, [sp, #(192 - 16)]\n" 1244 " .cfi_restore x1\n" 1245 " .cfi_restore x0\n" 1246 "\n" 1247 " ldp x29, x30, [sp, #192]\n" 1248 " .cfi_restore x29\n" 1249 " .cfi_restore x30\n" 1250 " add sp, sp, #(16 + 192)\n" 1251 " ret\n" 1252 " .cfi_endproc\n" 1253 "\n" 1254 "\n" 1255 , pszNmPfx, pszNmPfx); 1256 1257 fprintf(pOutput, 1258 ";\n" 1259 "; Loads the module.\n" 1260 "; ASSUMES called from LazyLoadResolver where all relevant registers are already saved.\n" 1261 ";\n" 1262 "LazyLoading:\n" 1263 " .cfi_startproc\n" 1264 " ; Create frame.\n" 1265 " sub sp, sp, #(16 + 48)\n" 1266 " stp x29, x30, [sp, #48]\n" 1267 " add x29, sp, #48\n" 1268 " .cfi_def_cfa x29, 16\n" 1269 " .cfi_offset x30, -8\n" 1270 " .cfi_offset x29, -16\n" 1271 "\n"); 1272 1273 if (!g_fSystemLibrary) 1274 fprintf(pOutput, 1275 " ; Call SUPR3HardenedLdrLoadAppPriv(const char *pszFilename, PRTLDRMOD phLdrMod, uint32_t fFlags, PRTERRINFO pErrInfo);\n" 1276 " mov x3, #0\n" 1277 " mov x2, #0\n" 1278 " ldr x1, =g_hMod\n" 1279 " ldr x0, =g_szLibrary\n" 1280 " bl %sSUPR3HardenedLdrLoadAppPriv\n" 1281 , pszNmPfx); 1282 else 1283 fprintf(pOutput, 1284 " ; Call RTLdrLoadSystem(const char *pszFilename, bool fNoUnload, PRTLDRMOD phLdrMod);\n" 1285 " ldr x2, =g_hMod\n" 1286 " mov x1, #1\n" 1287 " ldr x0, =g_szLibrary\n" 1288 " bl %sRTLdrLoadSystem\n" 1289 , pszNmPfx); 1290 1291 fprintf(pOutput, 1292 " cmp w0, #0\n" 1293 " b.eq Lload_return\n" 1294 "\n" 1295 "Lbadload: ; Call sRTAssertMsg2Weak. Variadic (...) arguments are passed on the stack it seems.\n" 1296 " mov x2, x0\n" 1297 " ldr x1, =g_szLibrary\n" 1298 " ldr x0, =g_szFailResolveFmt\n" 1299 " stp x1, x2, [sp]\n" 1300 " bl %sRTAssertMsg2Weak\n" 1301 "Lbadloadloop:\n" 1302 " brk #0x1\n" 1303 " b Lbadloadloop\n" 1304 "Lload_return:\n" 1305 " ldr x0, =g_hMod\n" 1306 " ldr x0, [x0]\n" 1307 " ldp x29, x30, [sp, #48]\n" 1308 " .cfi_restore x29\n" 1309 " .cfi_restore x30\n" 1310 " add sp, sp, #(16 + 48)\n" 1311 " ret\n" 1312 " .cfi_endproc\n" 1313 "\n" 1314 "\n" 1315 , pszNmPfx); 1316 1317 /* 1318 * C callable method for explicitly loading the library and optionally 1319 * resolving all the imports. 1320 */ 1321 if (g_fWithExplictLoadFunction) 1322 { 1323 if (g_fSystemLibrary) /* Lazy bird. */ 1324 { 1325 fprintf(stderr, "error: cannot use --system with --explicit-load-function, sorry\n"); 1326 return RTEXITCODE_FAILURE; 1327 } 1328 1329 int cchLibBaseName = (int)(strchr(g_pszLibrary, '.') ? strchr(g_pszLibrary, '.') - g_pszLibrary : strlen(g_pszLibrary)); 1330 fprintf(pOutput, 1331 ";;\n" 1332 "; ExplicitlyLoad%.*s(bool fResolveAllImports, pErrInfo);\n" 1333 ";\n" 1334 ".section __TEXT,__text,regular,pure_instructions\n" 1335 ".p2align 2\n" 1336 ".globl ExplicitlyLoad%.*s\n" 1337 "ExplicitlyLoad%.*s:\n" 1338 " .cfi_startproc\n" 1339 " ; Create frame.\n" 1340 " sub sp, sp, #(16 + #96)\n" 1341 " stp x29, x30, [sp, #96]\n" 1342 " add x29, sp, #96\n" 1343 " .cfi_def_cfa x29, 16\n" 1344 " .cfi_offset x30, -8\n" 1345 " .cfi_offset x29, -16\n" 1346 "\n" 1347 " stp x20, x21, [sp, #(96 - 16)]\n" 1348 " .cfi_offset x21, -24\n" 1349 " .cfi_offset x20, -32\n" 1350 " stp x22, x23, [sp, #(96 - 32)]\n" 1351 " .cfi_offset x23, -40\n" 1352 " .cfi_offset x22, -48\n" 1353 1354 " ; Save the input parameters.\n" 1355 " mov x20, x0\n" 1356 " mov x21, x1\n" 1357 "\n" 1358 " ;\n" 1359 " ; Is the module already loaded?\n" 1360 " ;\n" 1361 " ldr x0, =g_hMod\n" 1362 " ldr x0, [x0]\n" 1363 " cmp x0, #0\n" 1364 " b.ne Lexplicit_loaded_module\n" 1365 "\n" 1366 , 1367 cchLibBaseName, g_pszLibrary, 1368 cchLibBaseName, g_pszLibrary, 1369 cchLibBaseName, g_pszLibrary); 1370 fprintf(pOutput, 1371 "Lexplicit_load_module:\n" 1372 " ; Call SUPR3HardenedLdrLoadAppPriv(const char *pszFilename, PRTLDRMOD phLdrMod, uint32_t fFlags, PRTERRINFO pErrInfo);\n" 1373 " mov x3, #0\n" 1374 " mov x2, #0\n" 1375 " ldr x1, =g_hMod\n" 1376 " ldr x0, =g_szLibrary\n" 1377 " bl %sSUPR3HardenedLdrLoadAppPriv\n" 1378 " cmp x0, #0\n" 1379 " b.ne Lexplicit_load_return\n" 1380 "\n" 1381 , pszNmPfx); 1382 1383 fprintf(pOutput, 1384 " ;\n" 1385 " ; Resolve the imports too if requested to do so.\n" 1386 " ;\n" 1387 "Lexplicit_loaded_module:\n" 1388 " cmp w20, #0\n" 1389 " b.eq Lexplicit_load_return\n" 1390 "\n" 1391 " ldr x22, =g_szzNames\n" 1392 " ldr x23, =g_apfnImports\n" 1393 "Lexplicit_load_next_import:\n" 1394 " ldr x0, [x23]\n" 1395 " cmp x0, #0\n" 1396 " b.eq Lexplicit_load_return\n" 1397 "\n" 1398 " ; Get the module handle and call RTLdrGetSymbol(RTLDRMOD hLdrMod, const char *pszSymbol, void **ppvValue)\n" 1399 " ldr x0, =g_hMod\n" 1400 " ldr x0, [x0]\n" 1401 " mov x1, x22\n" 1402 " mov x2, x23\n" 1403 " bl %sRTLdrGetSymbol\n" 1404 " cmp x0, #0\n" 1405 " b.ne Lexplicit_load_symbol_error\n" 1406 "\n" 1407 " ; Advance.\n" 1408 " add x23, x23, #8\n" 1409 "Lexplict_load_advance_string:\n" 1410 " ldrb w0, [x22]\n" 1411 " add x22, x22, #1\n" 1412 " cmp w0, #0\n" 1413 " b.ne Lexplict_load_advance_string\n" 1414 " b Lexplicit_load_next_import\n" 1415 "\n" 1416 " ;\n" 1417 " ; Error loading a symbol. Call RTErrInfoSet(PRTERRINFO pErrInfo, int rc, const char *pszMsg) on pErrInfo (preserves x0).\n" 1418 " ;\n" 1419 "Lexplicit_load_symbol_error:\n" 1420 " mov x2, x22\n" 1421 " mov x1, x0\n" 1422 " mov x0, x21\n" 1423 " bl %sRTErrInfoSet\n" 1424 " b Lexplicit_load_return" 1425 " " 1426 "\n" 1427 "Lexplicit_load_return:\n" 1428 " ldp x22, x23, [sp, #(96 - 32)]\n" 1429 " .cfi_restore x23\n" 1430 " .cfi_restore x22\n" 1431 " ldp x20, x21, [sp, #(96 - 16)]\n" 1432 " .cfi_restore x21\n" 1433 " .cfi_restore x20\n" 1434 "\n" 1435 " ldp x29, x30, [sp, #96]\n" 1436 " .cfi_restore x29\n" 1437 " .cfi_restore x30\n" 1438 " add sp, sp, #(16 + 96)\n" 1439 " ret\n" 1440 " .cfi_endproc\n" 1441 "\n" 1442 "\n" 1443 , pszNmPfx, pszNmPfx); 1444 } 1445 1446 return RTEXITCODE_SUCCESS; 1447 } 1448 1449 1450 /** 985 1451 * Generates the assembly source code, writing it to g_pszOutput. 986 1452 * … … 994 1460 if (pOutput) 995 1461 { 996 rcExit = generateOutputInner(pOutput); 1462 switch (g_enmTarget) 1463 { 1464 case RTLDRARCH_AMD64: 1465 case RTLDRARCH_X86_32: 1466 rcExit = generateOutputInnerX86AndAMD64(pOutput); 1467 break; 1468 case RTLDRARCH_ARM64: 1469 rcExit = generateOutputInnerArm64(pOutput); 1470 break; 1471 default: 1472 rcExit = RTEXITCODE_FAILURE; 1473 break; 1474 } 997 1475 if (fclose(pOutput)) 998 1476 {
Note:
See TracChangeset
for help on using the changeset viewer.

