VirtualBox

Changeset 87282 in vbox


Ignore:
Timestamp:
Jan 15, 2021 8:38:06 PM (4 years ago)
Author:
vboxsync
Message:

VBoxDef2LazyLoad.cpp: Untested arm64 code generator. bugref:9898

File:
1 edited

Legend:

Unmodified
Added
Removed
  • trunk/src/bldprogs/VBoxDef2LazyLoad.cpp

    r82968 r87282  
    2727#include <stdlib.h>
    2828#include <iprt/types.h>
     29#include <iprt/ldr.h> /* For RTLDRARCH. */
    2930
    3031
     
    4647
    4748
    48 
    4949/*********************************************************************************************************************************
    5050*   Global Variables                                                                                                             *
     
    5959static bool         g_fWithExplictLoadFunction = false;
    6060static bool         g_fSystemLibrary = false;
     61#if   defined(RT_ARCH_AMD64)
     62static RTLDRARCH    g_enmTarget = RTLDRARCH_AMD64;
     63#elif defined(RT_ARCH_X86)
     64static RTLDRARCH    g_enmTarget = RTLDRARCH_X86;
     65#elif defined(RT_ARCH_ARM64)
     66static RTLDRARCH    g_enmTarget = RTLDRARCH_ARM64;
     67#else
     68# error "Port me!"
     69#endif
    6170/** @} */
    6271
     
    321330
    322331/**
    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.
    324334 *
    325335 * @returns RTEXITCODE_SUCCESS or RTEXITCODE_FAILURE, in the latter case full
     
    328338 *                               when closing).
    329339 */
    330 static RTEXITCODE generateOutputInner(FILE *pOutput)
     340static RTEXITCODE generateOutputInnerX86AndAMD64(FILE *pOutput)
    331341{
    332342    fprintf(pOutput, ";;\n");
     
    983993
    984994/**
     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 */
     1003static 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/**
    9851451 * Generates the assembly source code, writing it to g_pszOutput.
    9861452 *
     
    9941460    if (pOutput)
    9951461    {
    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        }
    9971475        if (fclose(pOutput))
    9981476        {
Note: See TracChangeset for help on using the changeset viewer.

© 2024 Oracle Support Privacy / Do Not Sell My Info Terms of Use Trademark Policy Automated Access Etiquette