VirtualBox

Changeset 100231 in vbox for trunk


Ignore:
Timestamp:
Jun 20, 2023 11:10:27 PM (18 months ago)
Author:
vboxsync
Message:

VMM/IEM: Recompiler fixes. Gets thru the bios now. bugref:10369

Location:
trunk/src/VBox/VMM
Files:
5 edited

Legend:

Unmodified
Added
Removed
  • trunk/src/VBox/VMM/VMMAll/IEMAllInstructionsOneByte.cpp.h

    r100222 r100231  
    67356735 * Common 'mov r8, imm8' helper.
    67366736 */
    6737 FNIEMOP_DEF_1(iemOpCommonMov_r8_Ib, uint8_t, iReg)
     6737FNIEMOP_DEF_1(iemOpCommonMov_r8_Ib, uint8_t, iFixedReg)
    67386738{
    67396739    uint8_t u8Imm; IEM_OPCODE_GET_NEXT_U8(&u8Imm);
     
    67426742    IEM_MC_BEGIN(0, 1);
    67436743    IEM_MC_LOCAL_CONST(uint8_t, u8Value,/*=*/ u8Imm);
    6744     IEM_MC_STORE_GREG_U8(iReg, u8Value);
     6744    IEM_MC_STORE_GREG_U8(iFixedReg, u8Value);
    67456745    IEM_MC_ADVANCE_RIP_AND_FINISH();
    67466746    IEM_MC_END();
     
    68316831 * Common 'mov regX,immX' helper.
    68326832 */
    6833 FNIEMOP_DEF_1(iemOpCommonMov_Rv_Iv, uint8_t, iReg)
     6833FNIEMOP_DEF_1(iemOpCommonMov_Rv_Iv, uint8_t, iFixedReg)
    68346834{
    68356835    switch (pVCpu->iem.s.enmEffOpSize)
     
    68426842            IEM_MC_BEGIN(0, 1);
    68436843            IEM_MC_LOCAL_CONST(uint16_t, u16Value,/*=*/ u16Imm);
    6844             IEM_MC_STORE_GREG_U16(iReg, u16Value);
     6844            IEM_MC_STORE_GREG_U16(iFixedReg, u16Value);
    68456845            IEM_MC_ADVANCE_RIP_AND_FINISH();
    68466846            IEM_MC_END();
     
    68556855            IEM_MC_BEGIN(0, 1);
    68566856            IEM_MC_LOCAL_CONST(uint32_t, u32Value,/*=*/ u32Imm);
    6857             IEM_MC_STORE_GREG_U32(iReg, u32Value);
     6857            IEM_MC_STORE_GREG_U32(iFixedReg, u32Value);
    68586858            IEM_MC_ADVANCE_RIP_AND_FINISH();
    68596859            IEM_MC_END();
     
    68676867            IEM_MC_BEGIN(0, 1);
    68686868            IEM_MC_LOCAL_CONST(uint64_t, u64Value,/*=*/ u64Imm);
    6869             IEM_MC_STORE_GREG_U64(iReg, u64Value);
     6869            IEM_MC_STORE_GREG_U64(iFixedReg, u64Value);
    68706870            IEM_MC_ADVANCE_RIP_AND_FINISH();
    68716871            IEM_MC_END();
     
    1113911139{
    1114011140    uint8_t bRm; IEM_OPCODE_GET_NEXT_U8(&bRm);
     11141    pVCpu->iem.s.uFpuOpcode = RT_MAKE_U16(bRm, 0xdf & 0x7);
    1114111142    if (IEM_IS_MODRM_REG_MODE(bRm))
    1114211143    {
  • trunk/src/VBox/VMM/VMMAll/IEMAllThreadedFunctions.cpp

    r100149 r100231  
    335335static RTGCPTR iemOpHlpCalcRmEffAddrThreadedAddr16(PVMCPUCC pVCpu, uint8_t bRm, uint16_t u16Disp) RT_NOEXCEPT
    336336{
    337     Log5(("iemOpHlpCalcRmEffAddrThreadedAddr16: bRm=%#x\n", bRm));
     337    Log5(("iemOpHlpCalcRmEffAddrThreadedAddr16: bRm=%#x u16Disp=%#x\n", bRm, u16Disp));
    338338    Assert(!IEM_IS_64BIT_CODE(pVCpu));
    339339
     
    390390static RTGCPTR iemOpHlpCalcRmEffAddrThreadedAddr32(PVMCPUCC pVCpu, uint8_t bRm, uint8_t bSib, uint32_t u32Disp) RT_NOEXCEPT
    391391{
    392     Log5(("iemOpHlpCalcRmEffAddrThreadedAddr32: bRm=%#x\n", bRm));
     392    Log5(("iemOpHlpCalcRmEffAddrThreadedAddr32: bRm=%#x bSib=%#x u32Disp=%#x\n", bRm, bSib, u32Disp));
    393393
    394394    /* Handle the disp32 form with no registers first. */
  • trunk/src/VBox/VMM/VMMAll/IEMAllThreadedPython.py

    r100223 r100231  
    254254        self.oParent.raiseProblem(sMessage);
    255255
     256    def warning(self, sMessage):
     257        """ Emits a warning. """
     258        self.oParent.warning(sMessage);
     259
    256260    def analyzeReferenceToType(self, sRef):
    257261        """
     
    283287            if sRef.startswith('i64'):
    284288                return 'int64_t';
    285             if sRef in ('iReg', 'iGReg', 'iSegReg', 'iSrcReg', 'iDstReg', 'iCrReg'):
     289            if sRef in ('iReg', 'iFixedReg', 'iGReg', 'iSegReg', 'iSrcReg', 'iDstReg', 'iCrReg'):
    286290                return 'uint8_t';
    287291        elif ch0 == 'p':
     
    372376
    373377        sRegRef = oStmt.asParams[idxReg];
    374         sOrgExpr = '((%s) < 4 || (pVCpu->iem.s.fPrefixes & IEM_OP_PRF_REX) ? (%s) : (%s) | 16)' % (sRegRef, sRegRef, sRegRef);
    375 
    376         if sRegRef.find('IEM_GET_MODRM_RM') > 0:    sStdRef = 'bRmRm8Ex';
    377         elif sRegRef.find('IEM_GET_MODRM_REG') > 0: sStdRef = 'bRmReg8Ex';
    378         else:                                       sStdRef = 'bOther8Ex';
    379 
     378        if sRegRef.startswith('IEM_GET_MODRM_RM') >= 0:
     379            sOrgExpr = 'IEM_GET_MODRM_RM_EX8(pVCpu, %s)' % (sRegRef,);
     380        elif sRegRef.startswith('IEM_GET_MODRM_REG') >= 0:
     381            sOrgExpr = 'IEM_GET_MODRM_REG_EX8(pVCpu, %s)' % (sRegRef,);
     382        else:
     383            sOrgExpr = '((%s) < 4 || (pVCpu->iem.s.fPrefixes & IEM_OP_PRF_REX) ? (%s) : (%s) + 12)' % (sRegRef, sRegRef, sRegRef);
     384
     385        if sRegRef.find('IEM_GET_MODRM_RM') >= 0:    sStdRef = 'bRmRm8Ex';
     386        elif sRegRef.find('IEM_GET_MODRM_REG') >= 0: sStdRef = 'bRmReg8Ex';
     387        elif sRegRef == 'X86_GREG_xAX':              sStdRef = 'bGregXAx8Ex';
     388        elif sRegRef == 'X86_GREG_xCX':              sStdRef = 'bGregXCx8Ex';
     389        elif sRegRef == 'X86_GREG_xSP':              sStdRef = 'bGregXSp8Ex';
     390        elif sRegRef == 'iFixedReg':                 sStdRef = 'bFixedReg8Ex';
     391        else:
     392            self.warning('analyze8BitGRegStmt: sRegRef=%s -> bOther8Ex; %s %s; sOrgExpr=%s'
     393                         % (sRegRef, oStmt.sName, oStmt.asParams, sOrgExpr,));
     394            sStdRef = 'bOther8Ex';
     395
     396        #print('analyze8BitGRegStmt: %s %s; sRegRef=%s\n -> idxReg=%s sOrgExpr=%s sStdRef=%s'
     397        #      % (oStmt.sName, oStmt.asParams, sRegRef, idxReg, sOrgExpr, sStdRef));
    380398        return (idxReg, sOrgExpr, sStdRef);
    381399
     
    463481                # ... and IEM_MC_*_GREG_U8 into *_THREADED w/ reworked index taking REX into account
    464482                elif oNewStmt.sName.startswith('IEM_MC_') and oNewStmt.sName.find('_GREG_U8') > 0:
    465                     (idxReg, _, sStdRef) = self.analyze8BitGRegStmt(oNewStmt);
     483                    (idxReg, _, sStdRef) = self.analyze8BitGRegStmt(oStmt); # Don't use oNewStmt as it has been modified!
    466484                    oNewStmt.asParams[idxReg] = self.dParamRefs[sStdRef][0].sNewName;
    467485                    oNewStmt.sName += '_THREADED';
     
    480498        return (aoThreadedStmts, iParamRef);
    481499
     500
    482501    def analyzeCodeOperation(self, aoStmts):
    483502        """
     
    488507        """
    489508        for oStmt in aoStmts:
     509            # Pick up hints from CIMPL calls and deferals.
    490510            if oStmt.sName.startswith('IEM_MC_CALL_CIMPL_') or oStmt.sName.startswith('IEM_MC_DEFER_TO_CIMPL_'):
    491511                sFlagsSansComments = iai.McBlock.stripComments(oStmt.asParams[0]);
     
    497517                        else:
    498518                            self.raiseProblem('Unknown CIMPL flag value: %s' % (sFlag,));
     519
     520            # Set IEM_IMPL_C_F_BRANCH if we see any branching MCs.
     521            if (   oStmt.sName.startswith('IEM_MC_SET_RIP')
     522                or oStmt.sName.startswith('IEM_MC_REL_JMP')):
     523                self.dsCImplFlags['IEM_CIMPL_F_BRANCH'] = True;
    499524
    500525            # Process branches of conditionals recursively.
     
    646671            if oStmt.sName.startswith('IEM_MC_') and oStmt.sName.find('_GREG_U8') > 0:
    647672                (idxReg, sOrgRef, sStdRef) = self.analyze8BitGRegStmt(oStmt);
    648                 self.aoParamRefs.append(ThreadedParamRef(sOrgRef, 'uint4_t', oStmt, idxReg, sStdRef = sStdRef));
     673                self.aoParamRefs.append(ThreadedParamRef(sOrgRef, 'uint16_t', oStmt, idxReg, sStdRef = sStdRef));
    649674                aiSkipParams[idxReg] = True; # Skip the parameter below.
    650675
     
    887912        raise Exception('%s:%s: error: %s' % (self.oMcBlock.sSrcFile, self.oMcBlock.iBeginLine, sMessage, ));
    888913
     914    def warning(self, sMessage):
     915        """ Emits a warning. """
     916        print('%s:%s: warning: %s' % (self.oMcBlock.sSrcFile, self.oMcBlock.iBeginLine, sMessage, ));
     917
    889918    def analyzeFindVariablesAndCallArgs(self, aoStmts):
    890919        """ Scans the statements for MC variables and call arguments. """
     
    10321061        #print('McBlock at %s:%s' % (os.path.split(self.oMcBlock.sSrcFile)[1], self.oMcBlock.iBeginLine,));
    10331062        aoDecoderStmts = [];
     1063
     1064        # Take a very simple approach to problematic instructions for now.
     1065        if cDepth == 0:
     1066            dsCImplFlags = {};
     1067            for oVar in self.aoVariations:
     1068                dsCImplFlags.update(oVar.dsCImplFlags);
     1069            if (   'IEM_CIMPL_F_BRANCH' in dsCImplFlags
     1070                or 'IEM_CIMPL_F_MODE'   in dsCImplFlags
     1071                or 'IEM_CIMPL_F_REP'    in dsCImplFlags):
     1072                aoDecoderStmts.append(iai.McCppGeneric('pVCpu->iem.s.fEndTb = true;'));
     1073
    10341074        for oStmt in aoStmts:
    10351075            # Copy the statement. Make a deep copy to make sure we've got our own
     
    12351275            '',
    12361276            'extern const PFNIEMTHREADEDFUNC g_apfnIemThreadedFunctions[kIemThreadedFunc_End];',
     1277            '#if defined(IN_RING3) || defined(LOG_ENABLED)',
     1278            'extern const char * const       g_apszIemThreadedFunctions[kIemThreadedFunc_End];',
     1279            '#endif',
    12371280        ];
    12381281
     
    12851328                               + '\n'
    12861329                               + '/**\n'
    1287                                + ' * %s at line %s offset %s in %s%s\n'
    1288                                   % (oMcBlock.sFunction, oMcBlock.iBeginLine, oMcBlock.offBeginLine,
     1330                               + ' * #%u: %s at line %s offset %s in %s%s\n'
     1331                                  % (oVariation.iEnumValue, oMcBlock.sFunction, oMcBlock.iBeginLine, oMcBlock.offBeginLine,
    12891332                                     os.path.split(oMcBlock.sSrcFile)[1],
    12901333                                     ' (macro expansion)' if oMcBlock.iBeginLine == oMcBlock.iEndLine else '')
     
    13731416        oOut.write('};\n');
    13741417
     1418        #
     1419        # Emit the function name table.
     1420        #
     1421        oOut.write(  '\n'
     1422                   + '\n'
     1423                   + '#if defined(IN_RING3) || defined(LOG_ENABLED)\n'
     1424                   + '/**\n'
     1425                   + ' * Function table.\n'
     1426                   + ' */\n'
     1427                   + 'const char * const g_apszIemThreadedFunctions[kIemThreadedFunc_End] =\n'
     1428                   + '{\n'
     1429                   + '    "Invalid",\n'
     1430                   + '\n'
     1431                   + '    /*\n'
     1432                   + '     * Predefined.\n'
     1433                   + '     */'
     1434                   + '    "BltIn_CheckMode",\n'
     1435                   );
     1436        iThreadedFunction = 1;
     1437        for sVariation in ThreadedFunctionVariation.kasVariationsEmitOrder:
     1438            oOut.write(  '\n'
     1439                       + '    /*\n'
     1440                       + '     * Variation: ' + ThreadedFunctionVariation.kdVariationNames[sVariation] + '\n'
     1441                       + '     */\n');
     1442            for oThreadedFunction in self.aoThreadedFuncs:
     1443                oVariation = oThreadedFunction.dVariations.get(sVariation, None);
     1444                if oVariation:
     1445                    iThreadedFunction += 1;
     1446                    assert oVariation.iEnumValue == iThreadedFunction;
     1447                    sName = oVariation.getFunctionName();
     1448                    if sName.startswith('iemThreadedFunc_'):
     1449                        sName = sName[len('iemThreadedFunc_'):];
     1450                    oOut.write('    /*%4u*/ "%s",\n' % (iThreadedFunction, sName,));
     1451        oOut.write(  '};\n'
     1452                   + '#endif /* IN_RING3 || LOG_ENABLED */\n');
     1453
    13751454        return True;
    13761455
     
    14411520                        assert (   sModified.startswith('IEM_MC_BEGIN')
    14421521                                or (sModified.find('IEM_MC_DEFER_TO_CIMPL_') > 0 and sModified.strip().startswith('{\n'))
     1522                                or sModified.startswith('pVCpu->iem.s.fEndTb = true')
    14431523                                ), 'sModified="%s"' % (sModified,);
    14441524                        oOut.write(sModified);
  • trunk/src/VBox/VMM/VMMAll/IEMAllThreadedRecompiler.cpp

    r100222 r100231  
    22/** @file
    33 * IEM - Instruction Decoding and Threaded Recompilation.
     4 *
     5 * Logging group IEM_RE_THREADED assignments:
     6 *      - Level 1  (Log)  : Errors, exceptions, interrupts and such major events. [same as IEM]
     7 *      - Flow  (LogFlow) :
     8 *      - Level 2  (Log2) :
     9 *      - Level 3  (Log3) : More detailed enter/exit IEM state info. [same as IEM]
     10 *      - Level 4  (Log4) : Decoding mnemonics w/ EIP. [same as IEM]
     11 *      - Level 5  (Log5) : Decoding details. [same as IEM]
     12 *      - Level 6  (Log6) :
     13 *      - Level 7  (Log7) :
     14 *      - Level 8  (Log8) : TB compilation.
     15 *      - Level 9  (Log9) : TB exec.
     16 *      - Level 10 (Log10): TB block lookup.
     17 *      - Level 11 (Log11): TB block lookup.
     18 *      - Level 12 (Log12): TB insertion.
    419 */
    520
     
    295310}
    296311
    297 /** @todo deal with IEM_MC_DEFER_TO_CIMPL_1, IEM_MC_DEFER_TO_CIMPL_2 and
    298  *        IEM_MC_DEFER_TO_CIMPL_3 as well. */
    299312
    300313/*
     
    435448 */
    436449
     450#ifdef LOG_ENABLED
     451/**
     452 * Logs the current instruction.
     453 * @param   pVCpu       The cross context virtual CPU structure of the calling EMT.
     454 * @param   pszFunction The IEM function doing the execution.
     455 */
     456static void iemThreadedLogCurInstr(PVMCPUCC pVCpu, const char *pszFunction) RT_NOEXCEPT
     457{
     458# ifdef IN_RING3
     459    if (LogIs2Enabled())
     460    {
     461        char     szInstr[256];
     462        uint32_t cbInstr = 0;
     463        DBGFR3DisasInstrEx(pVCpu->pVMR3->pUVM, pVCpu->idCpu, 0, 0,
     464                           DBGF_DISAS_FLAGS_CURRENT_GUEST | DBGF_DISAS_FLAGS_DEFAULT_MODE,
     465                           szInstr, sizeof(szInstr), &cbInstr);
     466
     467        PCX86FXSTATE pFpuCtx = &pVCpu->cpum.GstCtx.XState.x87;
     468        Log2(("**** %s fExec=%x pTb=%p\n"
     469              " eax=%08x ebx=%08x ecx=%08x edx=%08x esi=%08x edi=%08x\n"
     470              " eip=%08x esp=%08x ebp=%08x iopl=%d tr=%04x\n"
     471              " cs=%04x ss=%04x ds=%04x es=%04x fs=%04x gs=%04x efl=%08x\n"
     472              " fsw=%04x fcw=%04x ftw=%02x mxcsr=%04x/%04x\n"
     473              " %s\n"
     474              , pszFunction, pVCpu->iem.s.fExec, pVCpu->iem.s.pCurTbR3,
     475              pVCpu->cpum.GstCtx.eax, pVCpu->cpum.GstCtx.ebx, pVCpu->cpum.GstCtx.ecx, pVCpu->cpum.GstCtx.edx, pVCpu->cpum.GstCtx.esi, pVCpu->cpum.GstCtx.edi,
     476              pVCpu->cpum.GstCtx.eip, pVCpu->cpum.GstCtx.esp, pVCpu->cpum.GstCtx.ebp, pVCpu->cpum.GstCtx.eflags.Bits.u2IOPL, pVCpu->cpum.GstCtx.tr.Sel,
     477              pVCpu->cpum.GstCtx.cs.Sel, pVCpu->cpum.GstCtx.ss.Sel, pVCpu->cpum.GstCtx.ds.Sel, pVCpu->cpum.GstCtx.es.Sel,
     478              pVCpu->cpum.GstCtx.fs.Sel, pVCpu->cpum.GstCtx.gs.Sel, pVCpu->cpum.GstCtx.eflags.u,
     479              pFpuCtx->FSW, pFpuCtx->FCW, pFpuCtx->FTW, pFpuCtx->MXCSR, pFpuCtx->MXCSR_MASK,
     480              szInstr));
     481
     482        if (LogIs3Enabled())
     483            DBGFR3InfoEx(pVCpu->pVMR3->pUVM, pVCpu->idCpu, "cpumguest", "verbose", NULL);
     484    }
     485    else
     486# endif
     487        LogFlow(("%s: cs:rip=%04x:%08RX64 ss:rsp=%04x:%08RX64 EFL=%06x\n", pszFunction, pVCpu->cpum.GstCtx.cs.Sel,
     488                 pVCpu->cpum.GstCtx.rip, pVCpu->cpum.GstCtx.ss.Sel, pVCpu->cpum.GstCtx.rsp, pVCpu->cpum.GstCtx.eflags.u));
     489}
     490#endif /* LOG_ENABLED */
     491
     492
    437493static VBOXSTRICTRC iemThreadedCompileLongJumped(PVMCC pVM, PVMCPUCC pVCpu, VBOXSTRICTRC rcStrict)
    438494{
     
    635691    {
    636692        /* Process the next instruction. */
     693#ifdef LOG_ENABLED
     694        iemThreadedLogCurInstr(pVCpu, "CC");
     695        uint16_t const uCsLog  = pVCpu->cpum.GstCtx.cs.Sel;
     696        uint64_t const uRipLog = pVCpu->cpum.GstCtx.rip;
     697#endif
    637698        uint8_t b; IEM_OPCODE_GET_FIRST_U8(&b);
    638699        uint16_t const cCallsPrev = pTb->Thrd.cCalls;
     
    645706        }
    646707        else if (pTb->Thrd.cCalls > 0)
     708        {
     709            Log8(("%04x:%08RX64: End TB - %u calls, rc=%d\n", uCsLog, uRipLog, pTb->Thrd.cCalls, VBOXSTRICTRC_VAL(rcStrict)));
    647710            break;
     711        }
    648712        else
    649713        {
     714            Log8(("%04x:%08RX64: End TB - 0 calls, rc=%d\n", uCsLog, uRipLog, VBOXSTRICTRC_VAL(rcStrict)));
    650715            pVCpu->iem.s.pCurTbR3 = NULL;
    651716            iemThreadedTbFree(pVM, pVCpu, pTb);
     
    657722            iemThreadedCompileInitDecoder(pVCpu, true /*fReInit*/);
    658723        else
     724        {
     725            Log8(("%04x:%08RX64: End TB - %u calls - full\n", uCsLog, uRipLog, pTb->Thrd.cCalls));
    659726            break;
     727        }
    660728        iemThreadedCompileReInitOpcodeFetching(pVCpu);
    661729    }
     
    695763    while (cCallsLeft-- > 0)
    696764    {
     765#ifdef LOG_ENABLED
     766        iemThreadedLogCurInstr(pVCpu, "EX");
     767        Log9(("%04x:%08RX64: #%d - %d %s\n", pVCpu->cpum.GstCtx.cs.Sel, pVCpu->cpum.GstCtx.rip,
     768              pTb->Thrd.cCalls - cCallsLeft - 1, pCallEntry->enmFunction, g_apszIemThreadedFunctions[pCallEntry->enmFunction]));
     769#endif
    697770        VBOXSTRICTRC const rcStrict = g_apfnIemThreadedFunctions[pCallEntry->enmFunction](pVCpu,
    698771                                                                                          pCallEntry->auParams[0],
  • trunk/src/VBox/VMM/include/IEMInternal.h

    r100222 r100231  
    38353835 */
    38363836#define IEM_GET_MODRM_RM_8(a_bRm)           ( ((a_bRm) & X86_MODRM_RM_MASK) )
     3837
     3838/**
     3839 * Gets the register (reg) part of a ModR/M encoding as an extended 8-bit
     3840 * register index, with REX.R added in.
     3841 *
     3842 * For use during decoding.
     3843 *
     3844 * @see iemGRegRefU8Ex, iemGRegFetchU8Ex, iemGRegStoreU8Ex
     3845 */
     3846#define IEM_GET_MODRM_REG_EX8(a_pVCpu, a_bRm) \
     3847    (   (pVCpu->iem.s.fPrefixes & IEM_OP_PRF_REX) \
     3848     || !((a_bRm) & (4 << X86_MODRM_REG_SHIFT)) /* IEM_GET_MODRM_REG(pVCpu, a_bRm) < 4 */ \
     3849     ? IEM_GET_MODRM_REG(pVCpu, a_bRm) : (((a_bRm) >> X86_MODRM_REG_SHIFT) & 3) | 16)
     3850/**
     3851 * Gets the r/m part of a ModR/M encoding as an extended 8-bit register index,
     3852 * with REX.B added in.
     3853 *
     3854 * For use during decoding.
     3855 *
     3856 * @see iemGRegRefU8Ex, iemGRegFetchU8Ex, iemGRegStoreU8Ex
     3857 */
     3858#define IEM_GET_MODRM_RM_EX8(a_pVCpu, a_bRm) \
     3859    (   (pVCpu->iem.s.fPrefixes & IEM_OP_PRF_REX) \
     3860     || !((a_bRm) & 4) /* IEM_GET_MODRM_RM(pVCpu, a_bRm) < 4 */ \
     3861     ? IEM_GET_MODRM_RM(pVCpu, a_bRm) : ((a_bRm) & 3) | 16)
    38373862
    38383863/**
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