/* ---------------------------------------------------------------- */
void Dbtup::execSTORED_PROCREQ(Signal* signal) 
{
  OperationrecPtr regOperPtr;
  TablerecPtr regTabPtr;
  jamEntry();
  regOperPtr.i = signal->theData[0];
  c_operation_pool.getPtr(regOperPtr);
  regTabPtr.i = signal->theData[1];
  ptrCheckGuard(regTabPtr, cnoOfTablerec, tablerec);

  Uint32 requestInfo = signal->theData[3];
  TransState trans_state= get_trans_state(regOperPtr.p);
  ndbrequire(trans_state == TRANS_IDLE ||
             ((trans_state == TRANS_ERROR_WAIT_STORED_PROCREQ) &&
             (requestInfo == ZSTORED_PROCEDURE_DELETE)));
  ndbrequire(regTabPtr.p->tableStatus == DEFINED);
  switch (requestInfo) {
  case ZSCAN_PROCEDURE:
    jam();
    scanProcedure(signal,
                  regOperPtr.p,
                  signal->theData[4]);
    break;
  case ZCOPY_PROCEDURE:
    jam();
    copyProcedure(signal, regTabPtr, regOperPtr.p);
    break;
  case ZSTORED_PROCEDURE_DELETE:
    jam();
    deleteScanProcedure(signal, regOperPtr.p);
    break;
  default:
    ndbrequire(false);
  }//switch
}//Dbtup::execSTORED_PROCREQ()
void Dbtup::copyProcedure(Signal* signal,
                          TablerecPtr regTabPtr,
                          Operationrec* regOperPtr) 
{
  Uint32 TnoOfAttributes = regTabPtr.p->m_no_of_attributes;
  scanProcedure(signal,
                regOperPtr,
                TnoOfAttributes);

  Uint32 length = 0;
  for (Uint32 Ti = 0; Ti < TnoOfAttributes; Ti++) {
    AttributeHeader::init(&signal->theData[length + 1], Ti, 0);
    length++;
    if (length == 24) {
      jam();
      ndbrequire(storedProcedureAttrInfo(signal, regOperPtr, 
					 signal->theData+1, length, true));
      length = 0;
    }//if
  }//for
  if (length != 0) {
    jam();
    ndbrequire(storedProcedureAttrInfo(signal, regOperPtr, 
				       signal->theData+1, length, true));
  }//if
  ndbrequire(regOperPtr->currentAttrinbufLen == 0);
}//Dbtup::copyProcedure()
Пример #3
0
void Dbtup::copyProcedure(Signal* signal,
                          TablerecPtr regTabPtr,
                          Operationrec* regOperPtr) 
{
  /* We create a stored procedure for the fragment copy scan
   * This is done by trimming a 'read all columns in order'
   * program to the correct length for this table and
   * using that to create the procedure
   * This assumes that there is only one fragment copy going
   * on at any time, which is verified by checking 
   * cCopyLastSeg == RNIL before starting each copy
   *
   * If the table has extra per-row metainformation that
   * needs copied then we add that to the copy procedure
   * as well.
   */
  prepareCopyProcedure(regTabPtr.p->m_no_of_attributes,
                       regTabPtr.p->m_bits);

  SectionHandle handle(this);
  handle.m_cnt=1;
  handle.m_ptr[0].i= cCopyProcedure;
  getSections(handle.m_cnt, handle.m_ptr);

  scanProcedure(signal,
                regOperPtr,
                &handle,
                true); // isCopy
}//Dbtup::copyProcedure()
Пример #4
0
/* ---------------------------------------------------------------- */
void Dbtup::execSTORED_PROCREQ(Signal* signal) 
{
  OperationrecPtr regOperPtr;
  TablerecPtr regTabPtr;
  jamEntry();
  regOperPtr.i = signal->theData[0];
  c_operation_pool.getPtr(regOperPtr);
  regTabPtr.i = signal->theData[1];
  ptrCheckGuard(regTabPtr, cnoOfTablerec, tablerec);

  Uint32 requestInfo = signal->theData[3];
  TransState trans_state= get_trans_state(regOperPtr.p);
  ndbrequire(trans_state == TRANS_IDLE ||
             ((trans_state == TRANS_ERROR_WAIT_STORED_PROCREQ) &&
             (requestInfo == ZSTORED_PROCEDURE_DELETE)));
  ndbrequire(regTabPtr.p->tableStatus == DEFINED);
  /*
   * Also store count of procs called from non-API scans.
   * It can be done here since seize/release always succeeds.
   * The count is only used under -DERROR_INSERT via DUMP.
   */
  BlockReference apiBlockref = signal->theData[5];
  switch (requestInfo) {
  case ZSCAN_PROCEDURE:
  {
    jam();
#if defined VM_TRACE || defined ERROR_INSERT
    storedProcCountNonAPI(apiBlockref, +1);
#endif
    SectionHandle handle(this, signal);
    ndbrequire(handle.m_cnt == 1);

    scanProcedure(signal,
                  regOperPtr.p,
                  &handle,
                  false); // Not copy
    break;
  }
  case ZCOPY_PROCEDURE:
    jam();
#if defined VM_TRACE || defined ERROR_INSERT
    storedProcCountNonAPI(apiBlockref, +1);
#endif
    copyProcedure(signal, regTabPtr, regOperPtr.p);
    break;
  case ZSTORED_PROCEDURE_DELETE:
    jam();
#if defined VM_TRACE || defined ERROR_INSERT
    storedProcCountNonAPI(apiBlockref, -1);
#endif
    deleteScanProcedure(signal, regOperPtr.p);
    break;
  default:
    ndbrequire(false);
  }//switch
}//Dbtup::execSTORED_PROCREQ()
Пример #5
0
/**
 * Recursively generate code regions by statically analyzing machine code.
 */
bool
MDBCode::scanProcedure(uintptr_t address) {
    if (getRegion(address)) {
        log.traceLn("a region already exists");
        // A region already exists for this address.
        return true;
    }

    log.traceLn("scanning address %llx", address);
    
    size_t bufferSize = 1024 * 8;
    char buffer[bufferSize];
    
    if (debugger->read(buffer, address, sizeof(buffer)) != (int) sizeof(buffer)) {
        log.traceLn("Cannot read procedure memory.");
    }
    
    MBList<uintptr_t> callTargets;
    
    ud_t insn;
    ud_init(&insn); 
    ud_set_input_buffer(&insn, (uint8_t*)buffer, bufferSize);
    ud_set_mode(&insn, 32);
    ud_set_syntax(&insn, UD_SYN_INTEL);
    
    size_t remainingBytes = bufferSize;
    while (remainingBytes > 0) {
        int offset = insn.pc;
        size_t insnSize = ud_disassemble(&insn);
        remainingBytes -= insnSize;
        if (insnSize == 0) {
            error("cannot disassemble");
            break;
        }
        log.traceLn("decoded: 0x%-8llx 0x%-8llx %s",
            address + offset,
            offset,
            ud_insn_asm(&insn));
        switch (insn.mnemonic) {
            case UD_Icall: {
                uintptr_t target = 0;
                if (insn.operand[0].type == UD_OP_JIMM) {
                    if (insn.operand[0].size == 32) {
                        target = address + insn.pc + insn.operand[0].lval.sdword;
                    }
                }
                if (target) {
                    if (callTargets.contains(target) == false) {
                        log.traceLn("discovered new call target 0x%llx", target);
                        callTargets.append(target);
                    }
                }
                break;
            }
            case UD_Iret: {
                MDBCodeRegion *region = new MDBCodeRegion(this, address, findSymbolByNameOrAddress(NULL, address), insn.pc);
                regions.append(region);
                remainingBytes = 0;
                break;
            }
            default:
                break;
        }
    }
    
    for (uint32_t i = 0; i < callTargets.length(); i++) {
        scanProcedure(callTargets[i]);
    }
    
    return true;
}