<commit_before>/*
 * Copyright (c) 2007 The Hewlett-Packard Development Company
 * All rights reserved.
 *
 * Redistribution and use of this software in source and binary forms,
 * with or without modification, are permitted provided that the
 * following conditions are met:
 *
 * The software must be used only for Non-Commercial Use which means any
 * use which is NOT directed to receiving any direct monetary
 * compensation for, or commercial advantage from such use.  Illustrative
 * examples of non-commercial use are academic research, personal study,
 * teaching, education and corporate research & development.
 * Illustrative examples of commercial use are distributing products for
 * commercial advantage and providing services using the software for
 * commercial advantage.
 *
 * If you wish to use this software or functionality therein that may be
 * covered by patents for commercial use, please contact:
 *     Director of Intellectual Property Licensing
 *     Office of Strategy and Technology
 *     Hewlett-Packard Company
 *     1501 Page Mill Road
 *     Palo Alto, California  94304
 *
 * Redistributions of source code must retain the above copyright notice,
 * this list of conditions and the following disclaimer.  Redistributions
 * in binary form must reproduce the above copyright notice, this list of
 * conditions and the following disclaimer in the documentation and/or
 * other materials provided with the distribution.  Neither the name of
 * the COPYRIGHT HOLDER(s), HEWLETT-PACKARD COMPANY, nor the names of its
 * contributors may be used to endorse or promote products derived from
 * this software without specific prior written permission.  No right of
 * sublicense is granted herewith.  Derivatives of the software and
 * output created using the software may be prepared, but only for
 * Non-Commercial Uses.  Derivatives of the software may be shared with
 * others provided: (i) the others agree to abide by the list of
 * conditions herein which includes the Non-Commercial Use restrictions;
 * and (ii) such Derivatives of the software include the above copyright
 * notice to acknowledge the contribution from this software where
 * applicable, this list of conditions and the disclaimer below.
 *
 * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
 * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
 * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
 * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
 * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
 * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
 * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
 * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
 * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
 * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
 * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
 *
 * Authors: Gabe Black
 */

#include "arch/x86/insts/microldstop.hh"
#include <string>

namespace X86ISA
{
    std::string LdStOp::generateDisassembly(Addr pc,
            const SymbolTable *symtab) const
    {
        std::stringstream response;

        printMnemonic(response, instMnem, mnemonic);
        printDestReg(response, 0, dataSize);
        response << ", ";
        printSegment(response, segment);
        ccprintf(response, ":[%d*", scale);
        printSrcReg(response, 0, addressSize);
        response << " + ";
        printSrcReg(response, 1, addressSize);
        ccprintf(response, " + %#x]", disp);
        return response.str();
    }
}
<commit_msg>X86: Hide the irrelevant portions of the address components for load and store microops.<commit_after>/*
 * Copyright (c) 2007 The Hewlett-Packard Development Company
 * All rights reserved.
 *
 * Redistribution and use of this software in source and binary forms,
 * with or without modification, are permitted provided that the
 * following conditions are met:
 *
 * The software must be used only for Non-Commercial Use which means any
 * use which is NOT directed to receiving any direct monetary
 * compensation for, or commercial advantage from such use.  Illustrative
 * examples of non-commercial use are academic research, personal study,
 * teaching, education and corporate research & development.
 * Illustrative examples of commercial use are distributing products for
 * commercial advantage and providing services using the software for
 * commercial advantage.
 *
 * If you wish to use this software or functionality therein that may be
 * covered by patents for commercial use, please contact:
 *     Director of Intellectual Property Licensing
 *     Office of Strategy and Technology
 *     Hewlett-Packard Company
 *     1501 Page Mill Road
 *     Palo Alto, California  94304
 *
 * Redistributions of source code must retain the above copyright notice,
 * this list of conditions and the following disclaimer.  Redistributions
 * in binary form must reproduce the above copyright notice, this list of
 * conditions and the following disclaimer in the documentation and/or
 * other materials provided with the distribution.  Neither the name of
 * the COPYRIGHT HOLDER(s), HEWLETT-PACKARD COMPANY, nor the names of its
 * contributors may be used to endorse or promote products derived from
 * this software without specific prior written permission.  No right of
 * sublicense is granted herewith.  Derivatives of the software and
 * output created using the software may be prepared, but only for
 * Non-Commercial Uses.  Derivatives of the software may be shared with
 * others provided: (i) the others agree to abide by the list of
 * conditions herein which includes the Non-Commercial Use restrictions;
 * and (ii) such Derivatives of the software include the above copyright
 * notice to acknowledge the contribution from this software where
 * applicable, this list of conditions and the disclaimer below.
 *
 * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
 * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
 * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
 * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
 * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
 * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
 * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
 * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
 * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
 * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
 * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
 *
 * Authors: Gabe Black
 */

#include "arch/x86/insts/microldstop.hh"
#include <string>

namespace X86ISA
{
    std::string LdStOp::generateDisassembly(Addr pc,
            const SymbolTable *symtab) const
    {
        std::stringstream response;
        bool someAddr = false;

        printMnemonic(response, instMnem, mnemonic);
        if(flags[IsLoad])
            printDestReg(response, 0, dataSize);
        else
            printSrcReg(response, 2, dataSize);
        response << ", ";
        printSegment(response, segment);
        response << ":[";
        if(scale != 0 && _srcRegIdx[0] != ZeroReg)
        {
            if(scale != 1)
                ccprintf(response, "%d*", scale);
            printSrcReg(response, 0, addressSize);
            someAddr = true;
        }
        if(_srcRegIdx[1] != ZeroReg)
        {
            if(someAddr)
                response << " + ";
            printSrcReg(response, 1, addressSize);
            someAddr = true;
        }
        if(disp != 0)
        {
            if(someAddr)
                response << " + ";
            ccprintf(response, "%#x", disp);
            someAddr = true;
        }
        if(!someAddr)
            response << "0";
        response << "]";
        return response.str();
    }
}
<|endoftext|>


<commit_before>
#include <list>
#include <map>
#include <python2.7/Python.h>
#include <set>

#include "AnalysisProcessor.h"
#include "pin.H"

#define CB_BEFORE 0
#define CB_AFTER  1

extern AnalysisProcessor ap;

/* NameSapce for all Python Bindings variables */
namespace PyTritonOptions {

  /* Debug configurations */
  bool dumpStats = false;
  bool dumpTrace = false;

  /* Execution configurations */
  char *startAnalysisFromSymbol = NULL;
  std::set<uint64_t> startAnalysisFromAddr;
  std::set<uint64_t> stopAnalysisFromAddr;

  /* Callback configurations */
  PyObject *callbackBefore = NULL; // Before the instruction processing
  PyObject *callbackAfter  = NULL; // After the instruction processing

  /* Taint configurations */
  std::map<uint64_t, std::list<uint64_t>> taintRegFromAddr;   // <addr, [reg1, reg2]>
  std::map<uint64_t, std::list<uint64_t>> untaintRegFromAddr; // <addr, [reg1, reg2]>
  std::map<uint64_t, std::list<uint64_t>> taintMemFromAddr;   // <addr, [mem1, mem2]>
  std::map<uint64_t, std::list<uint64_t>> untaintMemFromAddr; // <addr, [mem1, mem2]>
};

static char Triton_addCallback_doc[] = "Add a callback for each instruction instrumented";
static PyObject *Triton_addCallback(PyObject *self, PyObject *args)
{
  PyObject *function;
  PyObject *flag;

  /* Extract arguments */
  PyArg_ParseTuple(args, "O|O", &function, &flag);

  if (!PyCallable_Check(function)){
    PyErr_Format(PyExc_TypeError, "addCallback(): expected a function callback as first argument");
    PyErr_Print();
    exit(-1);
  }

  /* Check if the second arg is CB_BEFORE or CB_AFTER */
  if (!PyLong_Check(flag) && !PyInt_Check(flag)) {
    PyErr_Format(PyExc_TypeError, "addCallback(): expected an integer as second argument");
    PyErr_Print();
    exit(-1);
  }

  if (PyLong_AsLong(flag) == CB_BEFORE)
    PyTritonOptions::callbackBefore = function;
  else if ((PyLong_AsLong(flag) == CB_AFTER))
    PyTritonOptions::callbackAfter = function;
  else {
    PyErr_Format(PyExc_TypeError, "addCallback(): expected CB_BEFORE or CB_AFTER as second argument");
    PyErr_Print();
    exit(-1);
  }

  return Py_None;
}

static char Triton_dumpTrace_doc[] = "Dump the trace at the end of the execution";
static PyObject *Triton_dumpTrace(PyObject *self, PyObject *flag)
{
  if (!PyBool_Check(flag)){
    PyErr_Format(PyExc_TypeError, "dumpTrace(): expected a boolean");
    PyErr_Print();
    exit(-1);
  }
  PyTritonOptions::dumpTrace = (flag == Py_True);
  return Py_None;
}

static char Triton_dumpStats_doc[] = "Dump statistics at the end of the execution";
static PyObject *Triton_dumpStats(PyObject *self, PyObject *flag)
{
  if (!PyBool_Check(flag)){
    PyErr_Format(PyExc_TypeError, "dumpStats(): expected a boolean");
    PyErr_Print();
    exit(-1);
  }
  PyTritonOptions::dumpStats = (flag == Py_True);
  return Py_None;
}

static char Triton_isMemTainted_doc[] = "Check if the memory is tainted";
static PyObject *Triton_isMemTainted(PyObject *self, PyObject *mem)
{
  if (!PyLong_Check(mem) && !PyInt_Check(mem)){
    PyErr_Format(PyExc_TypeError, "isMemTainted(): expected an address (integer) as argument");
    PyErr_Print();
    exit(-1);
  }
  if (ap.isMemTainted(PyInt_AsLong(mem)) == true)
    return Py_True;
  return Py_False;
}

static char Triton_isRegTainted_doc[] = "Check if the register is tainted";
static PyObject *Triton_isRegTainted(PyObject *self, PyObject *reg)
{
  if (!PyLong_Check(reg) && !PyInt_Check(reg)){
    PyErr_Format(PyExc_TypeError, "isRegTainted(): expected a reg (integer) as argument");
    PyErr_Print();
    exit(-1);
  }
  if (ap.isRegTainted(PyInt_AsLong(reg)) == true)
    return Py_True;
  return Py_False;
}

static char Triton_opcodeToString_doc[] = "Returns a string with the opcode of the instruction";
static PyObject *Triton_opcodeToString(PyObject *self, PyObject *opcode)
{
  if (!PyLong_Check(opcode) && !PyInt_Check(opcode)){
    PyErr_Format(PyExc_TypeError, "opcodeToString(): expected an opcode (integer) as argument");
    PyErr_Print();
    exit(-1);
  }
  return Py_BuildValue("s", OPCODE_StringShort(PyInt_AsLong(opcode)).c_str());
}

static char Triton_runProgram_doc[] = "Start the Pin instrumentation";
static PyObject *Triton_runProgram(PyObject *self, PyObject *noarg)
{
  // Never returns - Rock 'n roll baby \o/
  PIN_StartProgram();
  return Py_None;
}

static char Triton_startAnalysisFromSymbol_doc[] = "Start the symbolic execution from a specific name point";
static PyObject *Triton_startAnalysisFromSymbol(PyObject *self, PyObject *name)
{

  if (!PyString_Check(name)){
    PyErr_Format(PyExc_TypeError, "startAnalysisFromSymbol(): expected a string as argument");
    PyErr_Print();
    exit(-1);
  }
  PyTritonOptions::startAnalysisFromSymbol = PyString_AsString(name);
  return Py_None;
}

static char Triton_startAnalysisFromAddr_doc[] = "Start the symbolic execution from a specific address";
static PyObject *Triton_startAnalysisFromAddr(PyObject *self, PyObject *addr)
{

  if (!PyLong_Check(addr) && !PyInt_Check(addr)){
    PyErr_Format(PyExc_TypeError, "startAnalysisFromAddr(): expected an address as argument");
    PyErr_Print();
    exit(-1);
  }
  PyTritonOptions::startAnalysisFromAddr.insert(PyLong_AsLong(addr));
  return Py_None;
}

static char Triton_stopAnalysisFromAddr_doc[] = "Stop the symbolic execution from a specific address";
static PyObject *Triton_stopAnalysisFromAddr(PyObject *self, PyObject *addr)
{

  if (!PyLong_Check(addr) && !PyInt_Check(addr)){
    PyErr_Format(PyExc_TypeError, "stopAnalysisFromAddr(): expected an address");
    PyErr_Print();
    exit(-1);
  }
  PyTritonOptions::stopAnalysisFromAddr.insert(PyLong_AsLong(addr));
  return Py_None;
}

static char Triton_taintRegFromAddr_doc[] = "Taint specific registers from an address";
static PyObject *Triton_taintRegFromAddr(PyObject *self, PyObject *args)
{
  PyObject *addr;
  PyObject *regs;
  std::list<uint64_t> regsList;

  /* Extract arguments */
  PyArg_ParseTuple(args, "O|O", &addr, &regs);

  /* Check if the first arg (addr) is a integer */
  if (!PyLong_Check(addr) && !PyInt_Check(addr)) {
    PyErr_Format(PyExc_TypeError, "taintRegFromAddr(): expected an address as first argument");
    PyErr_Print();
    exit(-1);
  }

  /* Check if the second arg (regs) is a list */
  if (!PyList_Check(regs)) {
    PyErr_Format(PyExc_TypeError, "taintRegFromAddr(): expected a list as second argument");
    PyErr_Print();
    exit(-1);
  }

  /* Check if the regs list contains only integer item and craft a std::list */
  for (Py_ssize_t i = 0; i < PyList_Size(regs); i++){
    PyObject *item = PyList_GetItem(regs, i);
    if (!PyLong_Check(item) && !PyInt_Check(item)){
      PyErr_Format(PyExc_TypeError, "taintRegFromAddr(): The second argument must be a list of integer");
      PyErr_Print();
      exit(-1);
    }
    regsList.push_back(PyLong_AsLong(item));
  }

  /* Update taint configuration */
  PyTritonOptions::taintRegFromAddr.insert(std::pair<uint64_t, std::list<uint64_t>>(PyLong_AsLong(addr), regsList));
  return Py_None;
}

static char Triton_untaintRegFromAddr_doc[] = "Untaint specific registers from an address";
static PyObject *Triton_untaintRegFromAddr(PyObject *self, PyObject *args)
{
  PyObject *addr;
  PyObject *regs;
  std::list<uint64_t> regsList;

  /* Extract arguments */
  PyArg_ParseTuple(args, "O|O", &addr, &regs);

  /* Check if the first arg (addr) is a integer */
  if (!PyLong_Check(addr) && !PyInt_Check(addr)) {
    PyErr_Format(PyExc_TypeError, "untaintRegFromAddr(): expected an address as first argument");
    PyErr_Print();
    exit(-1);
  }

  /* Check if the second arg (regs) is a list */
  if (!PyList_Check(regs)) {
    PyErr_Format(PyExc_TypeError, "untaintRegFromAddr(): expected a list as second argument");
    PyErr_Print();
    exit(-1);
  }

  /* Check if the regs list contains only integer item and craft a std::list */
  for (Py_ssize_t i = 0; i < PyList_Size(regs); i++){
    PyObject *item = PyList_GetItem(regs, i);
    if (!PyLong_Check(item) && !PyInt_Check(item)){
      PyErr_Format(PyExc_TypeError, "untaintRegFromAddr(): The second argument must be a list of integer");
      PyErr_Print();
      exit(-1);
    }
    regsList.push_back(PyLong_AsLong(item));
  }

  /* Update taint configuration */
  PyTritonOptions::untaintRegFromAddr.insert(std::pair<uint64_t, std::list<uint64_t>>(PyLong_AsLong(addr), regsList));

  return Py_None;
}

PyMethodDef pythonCallbacks[] = {
  {"addCallback",             Triton_addCallback,             METH_VARARGS, Triton_addCallback_doc},
  {"dumpStats",               Triton_dumpStats,               METH_O,       Triton_dumpStats_doc},
  {"dumpTrace",               Triton_dumpTrace,               METH_O,       Triton_dumpTrace_doc},
  {"isMemTainted",            Triton_isMemTainted,            METH_O,       Triton_isMemTainted_doc},
  {"isRegTainted",            Triton_isRegTainted,            METH_O,       Triton_isRegTainted_doc},
  {"opcodeToString",          Triton_opcodeToString,          METH_O,       Triton_opcodeToString_doc},
  {"runProgram",              Triton_runProgram,              METH_NOARGS,  Triton_runProgram_doc},
  {"startAnalysisFromAddr",   Triton_startAnalysisFromAddr,   METH_O,       Triton_startAnalysisFromAddr_doc},
  {"startAnalysisFromSymbol", Triton_startAnalysisFromSymbol, METH_O,       Triton_startAnalysisFromSymbol_doc},
  {"stopAnalysisFromAddr",    Triton_stopAnalysisFromAddr,    METH_O,       Triton_stopAnalysisFromAddr_doc},
  {"taintRegFromAddr",        Triton_taintRegFromAddr,        METH_VARARGS, Triton_taintRegFromAddr_doc},
  {"untaintRegFromAddr",      Triton_untaintRegFromAddr,      METH_VARARGS, Triton_untaintRegFromAddr_doc},
  {NULL,                      NULL,                           0,            NULL}
};

<commit_msg>Export taintReg() and untaintReg() into Python bindings<commit_after>
#include <list>
#include <map>
#include <python2.7/Python.h>
#include <set>

#include "AnalysisProcessor.h"
#include "pin.H"

#define CB_BEFORE 0
#define CB_AFTER  1

extern AnalysisProcessor ap;

/* NameSapce for all Python Bindings variables */
namespace PyTritonOptions {

  /* Debug configurations */
  bool dumpStats = false;
  bool dumpTrace = false;

  /* Execution configurations */
  char *startAnalysisFromSymbol = NULL;
  std::set<uint64_t> startAnalysisFromAddr;
  std::set<uint64_t> stopAnalysisFromAddr;

  /* Callback configurations */
  PyObject *callbackBefore = NULL; // Before the instruction processing
  PyObject *callbackAfter  = NULL; // After the instruction processing

  /* Taint configurations */
  std::map<uint64_t, std::list<uint64_t>> taintRegFromAddr;   // <addr, [reg1, reg2]>
  std::map<uint64_t, std::list<uint64_t>> untaintRegFromAddr; // <addr, [reg1, reg2]>
  std::map<uint64_t, std::list<uint64_t>> taintMemFromAddr;   // <addr, [mem1, mem2]>
  std::map<uint64_t, std::list<uint64_t>> untaintMemFromAddr; // <addr, [mem1, mem2]>
};

static char Triton_addCallback_doc[] = "Add a callback for each instruction instrumented";
static PyObject *Triton_addCallback(PyObject *self, PyObject *args)
{
  PyObject *function;
  PyObject *flag;

  /* Extract arguments */
  PyArg_ParseTuple(args, "O|O", &function, &flag);

  if (!PyCallable_Check(function)){
    PyErr_Format(PyExc_TypeError, "addCallback(): expected a function callback as first argument");
    PyErr_Print();
    exit(-1);
  }

  /* Check if the second arg is CB_BEFORE or CB_AFTER */
  if (!PyLong_Check(flag) && !PyInt_Check(flag)) {
    PyErr_Format(PyExc_TypeError, "addCallback(): expected an integer as second argument");
    PyErr_Print();
    exit(-1);
  }

  if (PyLong_AsLong(flag) == CB_BEFORE)
    PyTritonOptions::callbackBefore = function;
  else if ((PyLong_AsLong(flag) == CB_AFTER))
    PyTritonOptions::callbackAfter = function;
  else {
    PyErr_Format(PyExc_TypeError, "addCallback(): expected CB_BEFORE or CB_AFTER as second argument");
    PyErr_Print();
    exit(-1);
  }

  return Py_None;
}

static char Triton_dumpTrace_doc[] = "Dump the trace at the end of the execution";
static PyObject *Triton_dumpTrace(PyObject *self, PyObject *flag)
{
  if (!PyBool_Check(flag)){
    PyErr_Format(PyExc_TypeError, "dumpTrace(): expected a boolean");
    PyErr_Print();
    exit(-1);
  }
  PyTritonOptions::dumpTrace = (flag == Py_True);
  return Py_None;
}

static char Triton_dumpStats_doc[] = "Dump statistics at the end of the execution";
static PyObject *Triton_dumpStats(PyObject *self, PyObject *flag)
{
  if (!PyBool_Check(flag)){
    PyErr_Format(PyExc_TypeError, "dumpStats(): expected a boolean");
    PyErr_Print();
    exit(-1);
  }
  PyTritonOptions::dumpStats = (flag == Py_True);
  return Py_None;
}

static char Triton_isMemTainted_doc[] = "Check if the memory is tainted";
static PyObject *Triton_isMemTainted(PyObject *self, PyObject *mem)
{
  if (!PyLong_Check(mem) && !PyInt_Check(mem)){
    PyErr_Format(PyExc_TypeError, "isMemTainted(): expected an address (integer) as argument");
    PyErr_Print();
    exit(-1);
  }
  if (ap.isMemTainted(PyInt_AsLong(mem)) == true)
    return Py_True;
  return Py_False;
}

static char Triton_isRegTainted_doc[] = "Check if the register is tainted";
static PyObject *Triton_isRegTainted(PyObject *self, PyObject *reg)
{
  if (!PyLong_Check(reg) && !PyInt_Check(reg)){
    PyErr_Format(PyExc_TypeError, "isRegTainted(): expected a reg id (integer) as argument");
    PyErr_Print();
    exit(-1);
  }
  if (ap.isRegTainted(PyInt_AsLong(reg)) == true)
    return Py_True;
  return Py_False;
}

static char Triton_opcodeToString_doc[] = "Returns a string with the opcode of the instruction";
static PyObject *Triton_opcodeToString(PyObject *self, PyObject *opcode)
{
  if (!PyLong_Check(opcode) && !PyInt_Check(opcode)){
    PyErr_Format(PyExc_TypeError, "opcodeToString(): expected an opcode (integer) as argument");
    PyErr_Print();
    exit(-1);
  }
  return Py_BuildValue("s", OPCODE_StringShort(PyInt_AsLong(opcode)).c_str());
}

static char Triton_runProgram_doc[] = "Start the Pin instrumentation";
static PyObject *Triton_runProgram(PyObject *self, PyObject *noarg)
{
  // Never returns - Rock 'n roll baby \o/
  PIN_StartProgram();
  return Py_None;
}

static char Triton_startAnalysisFromSymbol_doc[] = "Start the symbolic execution from a specific name point";
static PyObject *Triton_startAnalysisFromSymbol(PyObject *self, PyObject *name)
{

  if (!PyString_Check(name)){
    PyErr_Format(PyExc_TypeError, "startAnalysisFromSymbol(): expected a string as argument");
    PyErr_Print();
    exit(-1);
  }
  PyTritonOptions::startAnalysisFromSymbol = PyString_AsString(name);
  return Py_None;
}

static char Triton_startAnalysisFromAddr_doc[] = "Start the symbolic execution from a specific address";
static PyObject *Triton_startAnalysisFromAddr(PyObject *self, PyObject *addr)
{

  if (!PyLong_Check(addr) && !PyInt_Check(addr)){
    PyErr_Format(PyExc_TypeError, "startAnalysisFromAddr(): expected an address as argument");
    PyErr_Print();
    exit(-1);
  }
  PyTritonOptions::startAnalysisFromAddr.insert(PyLong_AsLong(addr));
  return Py_None;
}

static char Triton_stopAnalysisFromAddr_doc[] = "Stop the symbolic execution from a specific address";
static PyObject *Triton_stopAnalysisFromAddr(PyObject *self, PyObject *addr)
{

  if (!PyLong_Check(addr) && !PyInt_Check(addr)){
    PyErr_Format(PyExc_TypeError, "stopAnalysisFromAddr(): expected an address");
    PyErr_Print();
    exit(-1);
  }
  PyTritonOptions::stopAnalysisFromAddr.insert(PyLong_AsLong(addr));
  return Py_None;
}

static char Triton_taintReg_doc[] = "Taint a register";
static PyObject *Triton_taintReg(PyObject *self, PyObject *reg)
{
  if (!PyLong_Check(reg) && !PyInt_Check(reg)){
    PyErr_Format(PyExc_TypeError, "taintReg(): expected a reg id (integer) as argument");
    PyErr_Print();
    exit(-1);
  }
  ap.taintReg(PyInt_AsLong(reg));
  return Py_None;
}

static char Triton_taintRegFromAddr_doc[] = "Taint specific registers from an address";
static PyObject *Triton_taintRegFromAddr(PyObject *self, PyObject *args)
{
  PyObject *addr;
  PyObject *regs;
  std::list<uint64_t> regsList;

  /* Extract arguments */
  PyArg_ParseTuple(args, "O|O", &addr, &regs);

  /* Check if the first arg (addr) is a integer */
  if (!PyLong_Check(addr) && !PyInt_Check(addr)) {
    PyErr_Format(PyExc_TypeError, "taintRegFromAddr(): expected an address as first argument");
    PyErr_Print();
    exit(-1);
  }

  /* Check if the second arg (regs) is a list */
  if (!PyList_Check(regs)) {
    PyErr_Format(PyExc_TypeError, "taintRegFromAddr(): expected a list as second argument");
    PyErr_Print();
    exit(-1);
  }

  /* Check if the regs list contains only integer item and craft a std::list */
  for (Py_ssize_t i = 0; i < PyList_Size(regs); i++){
    PyObject *item = PyList_GetItem(regs, i);
    if (!PyLong_Check(item) && !PyInt_Check(item)){
      PyErr_Format(PyExc_TypeError, "taintRegFromAddr(): The second argument must be a list of reg id (integer)");
      PyErr_Print();
      exit(-1);
    }
    regsList.push_back(PyLong_AsLong(item));
  }

  /* Update taint configuration */
  PyTritonOptions::taintRegFromAddr.insert(std::pair<uint64_t, std::list<uint64_t>>(PyLong_AsLong(addr), regsList));
  return Py_None;
}

static char Triton_untaintReg_doc[] = "Untaint a register";
static PyObject *Triton_untaintReg(PyObject *self, PyObject *reg)
{
  if (!PyLong_Check(reg) && !PyInt_Check(reg)){
    PyErr_Format(PyExc_TypeError, "untaintReg(): expected a reg id (integer) as argument");
    PyErr_Print();
    exit(-1);
  }
  ap.untaintReg(PyInt_AsLong(reg));
  return Py_None;
}

static char Triton_untaintRegFromAddr_doc[] = "Untaint specific registers from an address";
static PyObject *Triton_untaintRegFromAddr(PyObject *self, PyObject *args)
{
  PyObject *addr;
  PyObject *regs;
  std::list<uint64_t> regsList;

  /* Extract arguments */
  PyArg_ParseTuple(args, "O|O", &addr, &regs);

  /* Check if the first arg (addr) is a integer */
  if (!PyLong_Check(addr) && !PyInt_Check(addr)) {
    PyErr_Format(PyExc_TypeError, "untaintRegFromAddr(): expected an address as first argument");
    PyErr_Print();
    exit(-1);
  }

  /* Check if the second arg (regs) is a list */
  if (!PyList_Check(regs)) {
    PyErr_Format(PyExc_TypeError, "untaintRegFromAddr(): expected a list as second argument");
    PyErr_Print();
    exit(-1);
  }

  /* Check if the regs list contains only integer item and craft a std::list */
  for (Py_ssize_t i = 0; i < PyList_Size(regs); i++){
    PyObject *item = PyList_GetItem(regs, i);
    if (!PyLong_Check(item) && !PyInt_Check(item)){
      PyErr_Format(PyExc_TypeError, "untaintRegFromAddr(): The second argument must be a list of reg id (integer)");
      PyErr_Print();
      exit(-1);
    }
    regsList.push_back(PyLong_AsLong(item));
  }

  /* Update taint configuration */
  PyTritonOptions::untaintRegFromAddr.insert(std::pair<uint64_t, std::list<uint64_t>>(PyLong_AsLong(addr), regsList));

  return Py_None;
}

PyMethodDef pythonCallbacks[] = {
  {"addCallback",             Triton_addCallback,             METH_VARARGS, Triton_addCallback_doc},
  {"dumpStats",               Triton_dumpStats,               METH_O,       Triton_dumpStats_doc},
  {"dumpTrace",               Triton_dumpTrace,               METH_O,       Triton_dumpTrace_doc},
  {"isMemTainted",            Triton_isMemTainted,            METH_O,       Triton_isMemTainted_doc},
  {"isRegTainted",            Triton_isRegTainted,            METH_O,       Triton_isRegTainted_doc},
  {"opcodeToString",          Triton_opcodeToString,          METH_O,       Triton_opcodeToString_doc},
  {"runProgram",              Triton_runProgram,              METH_NOARGS,  Triton_runProgram_doc},
  {"startAnalysisFromAddr",   Triton_startAnalysisFromAddr,   METH_O,       Triton_startAnalysisFromAddr_doc},
  {"startAnalysisFromSymbol", Triton_startAnalysisFromSymbol, METH_O,       Triton_startAnalysisFromSymbol_doc},
  {"stopAnalysisFromAddr",    Triton_stopAnalysisFromAddr,    METH_O,       Triton_stopAnalysisFromAddr_doc},
  {"taintReg",                Triton_taintReg,                METH_O,       Triton_taintReg_doc},
  {"taintRegFromAddr",        Triton_taintRegFromAddr,        METH_VARARGS, Triton_taintRegFromAddr_doc},
  {"untaintReg",              Triton_untaintReg,              METH_O,       Triton_untaintReg_doc},
  {"untaintRegFromAddr",      Triton_untaintRegFromAddr,      METH_VARARGS, Triton_untaintRegFromAddr_doc},
  {NULL,                      NULL,                           0,            NULL}
};

<|endoftext|>


<commit_before>// Copyright (c) 2021 by Apex.AI Inc. All rights reserved.
//
// Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License.
// You may obtain a copy of the License at
//
//     http://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing, software
// distributed under the License is distributed on an "AS IS" BASIS,
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
// See the License for the specific language governing permissions and
// limitations under the License.
//
// SPDX-License-Identifier: Apache-2.0
#ifndef IOX_HOOFS_MAC_PLATFORM_PLATFORM_SETTINGS_HPP
#define IOX_HOOFS_MAC_PLATFORM_PLATFORM_SETTINGS_HPP

#include <cstdint>
#include <sys/shm.h>

namespace iox
{
namespace posix
{
class UnixDomainSocket;
}

namespace platform
{
constexpr uint64_t IOX_MAX_FILENAME_LENGTH = 255U;
constexpr uint64_t IOX_MAX_PATH_LENGTH = 1023U;
constexpr bool IOX_SHM_WRITE_ZEROS_ON_CREATION = true;
constexpr uint64_t IOX_MAX_SHM_NAME_LENGTH = SHM_NAME_MAX;
constexpr const char IOX_PATH_SEPARATORS[] = "/";
constexpr uint64_t IOX_UDS_SOCKET_MAX_MESSAGE_SIZE = 2048;
constexpr const char IOX_UDS_SOCKET_PATH_PREFIX[] = "/tmp/";
constexpr const char IOX_LOCK_FILE_PATH_PREFIX[] = "/tmp/";
using IoxIpcChannelType = iox::posix::UnixDomainSocket;
} // namespace platform
} // namespace iox

#endif // IOX_HOOFS_MAC_PLATFORM_PLATFORM_SETTINGS_HPP
<commit_msg>iox-#33 Use MAX_SHM_NAME_LENGTH value from windows in mac<commit_after>// Copyright (c) 2021 by Apex.AI Inc. All rights reserved.
//
// Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License.
// You may obtain a copy of the License at
//
//     http://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing, software
// distributed under the License is distributed on an "AS IS" BASIS,
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
// See the License for the specific language governing permissions and
// limitations under the License.
//
// SPDX-License-Identifier: Apache-2.0
#ifndef IOX_HOOFS_MAC_PLATFORM_PLATFORM_SETTINGS_HPP
#define IOX_HOOFS_MAC_PLATFORM_PLATFORM_SETTINGS_HPP

#include <cstdint>

namespace iox
{
namespace posix
{
class UnixDomainSocket;
}

namespace platform
{
constexpr uint64_t IOX_MAX_FILENAME_LENGTH = 255U;
constexpr uint64_t IOX_MAX_PATH_LENGTH = 1023U;
constexpr bool IOX_SHM_WRITE_ZEROS_ON_CREATION = true;
// it should be SHM_NAME_MAX but it is unknown in which header this define
// is defined
constexpr uint64_t IOX_MAX_SHM_NAME_LENGTH = 255U;
constexpr const char IOX_PATH_SEPARATORS[] = "/";
constexpr uint64_t IOX_UDS_SOCKET_MAX_MESSAGE_SIZE = 2048;
constexpr const char IOX_UDS_SOCKET_PATH_PREFIX[] = "/tmp/";
constexpr const char IOX_LOCK_FILE_PATH_PREFIX[] = "/tmp/";
using IoxIpcChannelType = iox::posix::UnixDomainSocket;
} // namespace platform
} // namespace iox

#endif // IOX_HOOFS_MAC_PLATFORM_PLATFORM_SETTINGS_HPP
<|endoftext|>


<commit_before>/*
 * Copyright (C) 2003-2006 Funambol
 *
 * This program is free software; you can redistribute it and/or modify
 * it under the terms of the GNU General Public License as published by
 * the Free Software Foundation; either version 2 of the License, or
 * (at your option) any later version.
 *
 * This program is distributed in the hope that it will be useful,
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
 * GNU General Public License for more details.
 *
 * You should have received a copy of the GNU General Public License
 * along with this program; if not, write to the Free Software
 * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
 */

#include "base/memTracker.h"

MemTracker::MemTracker(bool useMemTracking) {
    tracking = useMemTracking;
}

MemTracker::~MemTracker() {}

// Add alloc informations to the list.
void MemTracker::addTrack(DWORD addr,  DWORD asize,  const char *fname, DWORD lnum) {

	AllocInfo info;
	strncpy(info.file, fname, MAX_LENGHT_FILE-1);
	info.address = addr;
	info.line	 = lnum;
	info.size	 = asize;

    allocList.add(info);
}

// Remove alloc informations from the list by the given address.
void MemTracker::removeTrack(DWORD addr) {

	int size = allocList.size();
    if (!size)
		return;

    if ( addr == ((AllocInfo*)allocList.front())->address ) {
        allocList.remove(0);
        return;
    }
    else {
        int i;
	    for (i=1; i<size; i++) {
            if ( addr == ((AllocInfo*)allocList.next())->address ) {
                allocList.remove(i);
			    break;
            }
	    }
    }
}

// To print final results of memory allocations.
void MemTracker::dumpUnfreed() {

    DWORD totalSize = 0;
	AllocInfo *info;
	int i;

    disableMemTracker();

    int size = allocList.size();
	LOG.debug("-------------------- MEMORY LEAKS: ------------------------");
    LOG.debug("-----------------------------------------------------------");
    LOG.debug("%d leaks found!", size);

    info = (AllocInfo*)allocList.front();
    LOG.debug("addr: %lx - size:%3ld, file: %s:%d", info->address, info->size, info->file, info->line);
    for(i=1; i<size; i++) {
		info = (AllocInfo*)allocList.next();
		LOG.debug("addr: %lx - size:%3ld, file: %s:%d", info->address, info->size, info->file, info->line);
		totalSize += info->size;
	}

	LOG.debug("Total Unfreed: %d bytes", totalSize);
    LOG.debug("-----------------------------------------------------------\n");

    allocList.clear();
}

//
// Functions to enable/disable tracking of memory leaks.
// Note: need to disable trackers when calling add/removeTracker
//       to avoid loops into new/delete operators!
//
void MemTracker::enableMemTracker() {
    tracking = TRUE;
}
void MemTracker::disableMemTracker() {
    tracking = FALSE;
}

// Are we tracking memory leaks?
bool MemTracker::isMemTracking() {
    return tracking;
}

// -------------------------------------------------

// not used
ArrayElement* AllocInfo::clone() {
    AllocInfo* ret = new AllocInfo();
    ret->address = address;
    ret->size = size;
    ret->line = line;
    strncpy(ret->file, file, MAX_LENGHT_FILE-1);
    return ret;
}

<commit_msg>correction to MemTracker<commit_after>/*
 * Copyright (C) 2003-2006 Funambol
 *
 * This program is free software; you can redistribute it and/or modify
 * it under the terms of the GNU General Public License as published by
 * the Free Software Foundation; either version 2 of the License, or
 * (at your option) any later version.
 *
 * This program is distributed in the hope that it will be useful,
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
 * GNU General Public License for more details.
 *
 * You should have received a copy of the GNU General Public License
 * along with this program; if not, write to the Free Software
 * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
 */

#include "base/memTracker.h"

MemTracker::MemTracker(bool useMemTracking) {
    tracking = useMemTracking;
}

MemTracker::~MemTracker() {}

// Add alloc informations to the list.
void MemTracker::addTrack(DWORD addr,  DWORD asize,  const char *fname, DWORD lnum) {

	AllocInfo info;
	strncpy(info.file, fname, MAX_LENGHT_FILE-1);
	info.address = addr;
	info.line	 = lnum;
	info.size	 = asize;

    allocList.add(info);
}

// Remove alloc informations from the list by the given address.
void MemTracker::removeTrack(DWORD addr) {

	int size = allocList.size();
    if (!size)
		return;

    if ( addr == ((AllocInfo*)allocList.front())->address ) {
        allocList.remove(0);
        return;
    }
    else {
        int i;
	    for (i=1; i<size; i++) {
            if ( addr == ((AllocInfo*)allocList.next())->address ) {
                allocList.remove(i);
			    break;
            }
	    }
    }
}

// To print final results of memory allocations.
void MemTracker::dumpUnfreed() {

    DWORD totalSize = 0;
	AllocInfo *info;
	int i;

    disableMemTracker();

    int size = allocList.size();
	LOG.debug("-------------------- MEMORY LEAKS: ------------------------");
    LOG.debug("-----------------------------------------------------------");
    LOG.debug("%d leaks found!", size);

    info = (AllocInfo*)allocList.front();
    LOG.debug("addr: %lx - size:%3ld, file: %s:%d", info->address, info->size, info->file, info->line);
	totalSize += info->size;
    for(i=1; i<size; i++) {
		info = (AllocInfo*)allocList.next();
		LOG.debug("addr: %lx - size:%3ld, file: %s:%d", info->address, info->size, info->file, info->line);
		totalSize += info->size;
	}

	LOG.debug("Total Unfreed: %d bytes", totalSize);
    LOG.debug("-----------------------------------------------------------\n");

    allocList.clear();
}

//
// Functions to enable/disable tracking of memory leaks.
// Note: need to disable trackers when calling add/removeTracker
//       to avoid loops into new/delete operators!
//
void MemTracker::enableMemTracker() {
    tracking = TRUE;
}
void MemTracker::disableMemTracker() {
    tracking = FALSE;
}

// Are we tracking memory leaks?
bool MemTracker::isMemTracking() {
    return tracking;
}

// -------------------------------------------------

// not used
ArrayElement* AllocInfo::clone() {
    AllocInfo* ret = new AllocInfo();
    ret->address = address;
    ret->size = size;
    ret->line = line;
    strncpy(ret->file, file, MAX_LENGHT_FILE-1);
    return ret;
}

<|endoftext|>


<commit_before>/*
 * This file is part of the µOS++ distribution.
 *   (https://github.com/micro-os-plus)
 * Copyright (c) 2016 Liviu Ionescu.
 *
 * µOS++ is free software: you can redistribute it and/or modify
 * it under the terms of the GNU Lesser General Public License as
 * published by the Free Software Foundation, version 3.
 *
 * µOS++ is distributed in the hope that it will be useful, but
 * WITHOUT ANY WARRANTY; without even the implied warranty of
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
 * Lesser General Public License for more details.
 *
 * You should have received a copy of the GNU Lesser General Public License
 * along with this program. If not, see <http://www.gnu.org/licenses/>.
 */

#include <cmsis-plus/rtos/os.h>
#include <cmsis-plus/diag/trace.h>

#include <cmsis-plus/rtos/port/os-decls.h>
#include <cmsis-plus/rtos/port/os-inlines.h>

// ----------------------------------------------------------------------------

#include <cassert>
#include <cerrno>
#include <cstdlib>

// ----------------------------------------------------------------------------

namespace os
{
  namespace rtos
  {
    static Systick_clock::rep __systick_now;
    static Realtime_clock::rep __rtc_now;

  } /* namespace rtos */
} /* namespace os */

// ----------------------------------------------------------------------------

void
os_systick_handler (void)
{
  using namespace os::rtos;

  // Prevent scheduler actions before starting it.
  if (scheduler::started ())
    {
      os_impl_systick_handler ();
    }
  __systick_now++;

#if !defined(OS_INCLUDE_REALTIME_CLOCK_DRIVER)
  static uint32_t ticks = Systick_clock::frequency_hz;

  if (--ticks == 0)
    {
      ticks = Systick_clock::frequency_hz;

      os_rtc_handler ();
    }
#endif
}

void
os_rtc_handler (void)
{
  using namespace os::rtos;

  // Prevent scheduler actions before starting it.
  if (scheduler::started ())
    {
      os_impl_rtc_handler ();
    }
  ++__rtc_now;
}

void __attribute__((weak))
os_impl_systick_handler (void)
{
  // TODO
}

void __attribute__((weak))
os_impl_rtc_handler (void)
{
  // TODO
}

// ----------------------------------------------------------------------------

namespace os
{
  namespace rtos
  {

#pragma GCC diagnostic push
// TODO: remove it when fully implemented
//#pragma GCC diagnostic ignored "-Wunused-parameter"

// ======================================================================

    /**
     * @details
     *
     * @note Can be invoked from Interrupt Service Routines.
     */
    Systick_clock::rep
    Systick_clock::now (void)
    {
      Critical_section_irq cs; // ---- Critical section -----

      // Prevent inconsistent values using the critical section.
      return __systick_now;
    }

    /**
     * @details
     * Return the very accurate current time, using the internal
     * SysTick cycle counter, which, at 100 MHz and 1000 ticks/sec
     * allows a 10 ns resolution.
     *
     * The function adjust for border conditions, when the SysTick
     * counter is reloaded during the call.
     *
     * @note Can be invoked from Interrupt Service Routines.
     */
    Systick_clock::rep
    Systick_clock::now (current_t* details)
    {
      assert(details != nullptr);

      // The core frequency can be returned right away, since
      // is not expected to change during this call.
      details->core_frequency_hz = SystemCoreClock;

      // The timer reload value, it is the divisor - 1.
      uint32_t load = SysTick->LOAD;
      // Can also be returned right away.
      details->divisor = load + 1;

      // The ticks and cycles must be read atomically, use a critical
      // section and adjust for border condition, when the event
      // came exactly after entering the critical section.
      uint64_t ticks;
      uint32_t val;
        {
          Critical_section_irq cs; // ----- Critical section -----

          // Sample ticks counter inside critical section.
          ticks = __systick_now;

          // Initial sample of the decrementing counter.
          // Might happen before the event, will be used as such.
          val = SysTick->VAL;

          // Check overflow. If the exception is pending, it means the
          // ticks counter was not yet updated, but the counter was reloaded.
          if (SysTick->CTRL & SCB_ICSR_PENDSTSET_Msk)
            {
              // Sample the decrementing counter again to validate the
              // initial sample.
              uint32_t val_update = SysTick->VAL;
              if (val_update > val)
                {
                  // The second sample is more accurate.
                  val = val_update;
                }
              ticks++; // Adjust to next tick.
            }
        }
      details->cycles = load - val;
      details->ticks = ticks;

      return ticks;
    }

    /**
     * @details
     * Put the current thread to sleep, until the next n-th
     * SysTick occurs. Depending when the call is issued, the
     * first tick counted may be very short.
     *
     * @warning Cannot be invoked from Interrupt Service Routines.
     */
    result_t
    Systick_clock::sleep_for (Systick_clock::sleep_rep ticks)
    {
      os_assert_err(!scheduler::in_handler_mode (), EPERM);

      trace::printf ("Systick_clock::sleep_for(%d_ticks)\n", ticks);

#if defined(OS_INCLUDE_PORT_RTOS_SYSTICK_CLOCK_SLEEP_FOR)
      return port::Systick_clock::sleep_for (ticks);
#else
      // TODO
      return result::ok;
#endif
    }

    /**
     * @details
     *
     * @note Can be invoked from Interrupt Service Routines.
     */
    Realtime_clock::rep
    Realtime_clock::now (void)
    {
      return __rtc_now;
    }

    /**
     * @details
     * Put the current thread to sleep, until the next n-th
     * RTC second occurs. Depending when the call is issued, the
     * first second counted may be very short.
     *
     * @warning Cannot be invoked from Interrupt Service Routines.
     */
    result_t
    Realtime_clock::sleep_for (Realtime_clock::sleep_rep secs)
    {
      os_assert_err(!scheduler::in_handler_mode (), EPERM);

      trace::printf ("Realtime_clock::sleep_for(%ds)\n", secs);

      // TODO
      __rtc_now += secs;
      return result::ok;
    }

#pragma GCC diagnostic pop

  } /* namespace rtos */
} /* namespace os */
<commit_msg>os-clocks: add RTC:initialize()<commit_after>/*
 * This file is part of the µOS++ distribution.
 *   (https://github.com/micro-os-plus)
 * Copyright (c) 2016 Liviu Ionescu.
 *
 * µOS++ is free software: you can redistribute it and/or modify
 * it under the terms of the GNU Lesser General Public License as
 * published by the Free Software Foundation, version 3.
 *
 * µOS++ is distributed in the hope that it will be useful, but
 * WITHOUT ANY WARRANTY; without even the implied warranty of
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
 * Lesser General Public License for more details.
 *
 * You should have received a copy of the GNU Lesser General Public License
 * along with this program. If not, see <http://www.gnu.org/licenses/>.
 */

#include <cmsis-plus/rtos/os.h>
#include <cmsis-plus/diag/trace.h>

#include <cmsis-plus/rtos/port/os-decls.h>
#include <cmsis-plus/rtos/port/os-inlines.h>

// ----------------------------------------------------------------------------

#include <cassert>
#include <cerrno>
#include <cstdlib>

// ----------------------------------------------------------------------------

namespace os
{
  namespace rtos
  {
    static Systick_clock::rep __systick_now;
    static Realtime_clock::rep __rtc_now;

  } /* namespace rtos */
} /* namespace os */

// ----------------------------------------------------------------------------

void
os_systick_handler (void)
{
  using namespace os::rtos;

  // Prevent scheduler actions before starting it.
  if (scheduler::started ())
    {
      os_impl_systick_handler ();
    }
  __systick_now++;

#if !defined(OS_INCLUDE_REALTIME_CLOCK_DRIVER)
  static uint32_t ticks = Systick_clock::frequency_hz;

  if (--ticks == 0)
    {
      ticks = Systick_clock::frequency_hz;

      os_rtc_handler ();
    }
#endif
}

void
os_rtc_handler (void)
{
  using namespace os::rtos;

  // Prevent scheduler actions before starting it.
  if (scheduler::started ())
    {
      os_impl_rtc_handler ();
    }
  ++__rtc_now;
}

void __attribute__((weak))
os_impl_systick_handler (void)
{
  // TODO
}

void __attribute__((weak))
os_impl_rtc_handler (void)
{
  // TODO
}

// ----------------------------------------------------------------------------

namespace os
{
  namespace rtos
  {

#pragma GCC diagnostic push
// TODO: remove it when fully implemented
//#pragma GCC diagnostic ignored "-Wunused-parameter"

// ======================================================================

    /**
     * @details
     *
     * @note Can be invoked from Interrupt Service Routines.
     */
    Systick_clock::rep
    Systick_clock::now (void)
    {
      Critical_section_irq cs; // ---- Critical section -----

      // Prevent inconsistent values using the critical section.
      return __systick_now;
    }

    /**
     * @details
     * Return the very accurate current time, using the internal
     * SysTick cycle counter, which, at 100 MHz and 1000 ticks/sec
     * allows a 10 ns resolution.
     *
     * The function adjust for border conditions, when the SysTick
     * counter is reloaded during the call.
     *
     * @note Can be invoked from Interrupt Service Routines.
     */
    Systick_clock::rep
    Systick_clock::now (current_t* details)
    {
      assert(details != nullptr);

      // The core frequency can be returned right away, since
      // is not expected to change during this call.
      details->core_frequency_hz = SystemCoreClock;

      // The timer reload value, it is the divisor - 1.
      uint32_t load = SysTick->LOAD;
      // Can also be returned right away.
      details->divisor = load + 1;

      // The ticks and cycles must be read atomically, use a critical
      // section and adjust for border condition, when the event
      // came exactly after entering the critical section.
      uint64_t ticks;
      uint32_t val;
        {
          Critical_section_irq cs; // ----- Critical section -----

          // Sample ticks counter inside critical section.
          ticks = __systick_now;

          // Initial sample of the decrementing counter.
          // Might happen before the event, will be used as such.
          val = SysTick->VAL;

          // Check overflow. If the exception is pending, it means the
          // ticks counter was not yet updated, but the counter was reloaded.
          if (SysTick->CTRL & SCB_ICSR_PENDSTSET_Msk)
            {
              // Sample the decrementing counter again to validate the
              // initial sample.
              uint32_t val_update = SysTick->VAL;
              if (val_update > val)
                {
                  // The second sample is more accurate.
                  val = val_update;
                }
              ticks++; // Adjust to next tick.
            }
        }
      details->cycles = load - val;
      details->ticks = ticks;

      return ticks;
    }

    /**
     * @details
     * Put the current thread to sleep, until the next n-th
     * SysTick occurs. Depending when the call is issued, the
     * first tick counted may be very short.
     *
     * @warning Cannot be invoked from Interrupt Service Routines.
     */
    result_t
    Systick_clock::sleep_for (Systick_clock::sleep_rep ticks)
    {
      os_assert_err(!scheduler::in_handler_mode (), EPERM);

      trace::printf ("Systick_clock::sleep_for(%d_ticks)\n", ticks);

#if defined(OS_INCLUDE_PORT_RTOS_SYSTICK_CLOCK_SLEEP_FOR)
      return port::Systick_clock::sleep_for (ticks);
#else
      // TODO
      return result::ok;
#endif
    }

    /**
     * @details
     * Must be called only once, during inits.
     *
     * @warning Cannot be invoked from Interrupt Service Routines.
     */
    result_t
    Realtime_clock::initialize (void)
    {
      os_assert_err(!scheduler::in_handler_mode (), EPERM);

      // TODO: Use the RTC driver to initialise the seconds to epoch.

      return result::ok;
    }

    /**
     * @details
     *
     * @note Can be invoked from Interrupt Service Routines.
     */
    Realtime_clock::rep
    Realtime_clock::now (void)
    {
      return __rtc_now;
    }

    /**
     * @details
     * Put the current thread to sleep, until the next n-th
     * RTC second occurs. Depending when the call is issued, the
     * first second counted may be very short.
     *
     * @warning Cannot be invoked from Interrupt Service Routines.
     */
    result_t
    Realtime_clock::sleep_for (Realtime_clock::sleep_rep secs)
    {
      os_assert_err(!scheduler::in_handler_mode (), EPERM);

      trace::printf ("Realtime_clock::sleep_for(%ds)\n", secs);

      // TODO
      __rtc_now += secs;
      return result::ok;
    }

#pragma GCC diagnostic pop

  } /* namespace rtos */
} /* namespace os */
<|endoftext|>


<commit_before>#include <stdio.h>
#include <Halide.h>

using namespace Halide;

int main(int argc, char **argv) {
    Var x, y;

    Func pred("pred");
    pred(x, y) = x < y;

    Func selector("selector");
    selector(x, y) = select(pred(x, y), 1, 0);

    // Load a vector of 8 bools
    pred.compute_root();
    selector.compute_root().vectorize(x, 8);

    RDom range(0, 100, 0, 100);
    int32_t result = evaluate<int32_t>(lambda(sum(selector(range.x, range.y))));

    assert(result == 4950);

    printf("Success!\n");
    return 0;
}
<commit_msg>Had this under two names. Delete the less descriptive one.<commit_after><|endoftext|>


<commit_before>/*
 *  Copyright (c) 2014, Oculus VR, Inc.
 *  All rights reserved.
 *
 *  This source code is licensed under the BSD-style license found in the
 *  LICENSE file in the root directory of this source tree. An additional grant
 *  of patent rights can be found in the PATENTS file in the same directory.
 *
 */

// ----------------------------------------------------------------------
// RakNet version 1.0
// Filename Ping.cpp
// Very basic chat engine example
// ----------------------------------------------------------------------
#include "MessageIdentifiers.h"

#include "RakPeerInterface.h"
#include "RakPeerInterface.h"
#include "RakNetTypes.h"
#include "GetTime.h"
#include "BitStream.h"
#include <assert.h>
#include <cstdio>
#include <cstring>
#include <stdlib.h>
#include "Gets.h"

#ifdef WIN32
#include "Kbhit.h"
#else
#include "Kbhit.h"
#endif

int main(void)
{
	// Pointers to the interfaces of our server and client.
	// Note we can easily have both in the same program
	RakNet::RakPeerInterface *client=RakNet::RakPeerInterface::GetInstance();
	RakNet::RakPeerInterface *server=RakNet::RakPeerInterface::GetInstance();

	int i = server->GetNumberOfAddresses();

	// Holds packets
	RakNet::Packet* p;

	// Record the first client that connects to us so we can pass it to the ping function
	RakNet::SystemAddress clientID=RakNet::UNASSIGNED_SYSTEM_ADDRESS;
	bool packetFromServer;
	char portstring[30];

	printf("This is a sample of how to send offline pings and get offline ping\n");
	printf("responses.\n");
	printf("Difficulty: Beginner\n\n");

	// A server
	puts("Enter the server port to listen on");
	Gets(portstring,sizeof(portstring));
	if (portstring[0]==0)
		strcpy(portstring,"60000");

	// Enumeration data
	puts("Enter offline ping response data (for return by a LAN discovery for example)");
	puts("Hit enter for none.");
	char enumData[512];
	Gets(enumData,sizeof(enumData));
	if (enumData[0])
		server->SetOfflinePingResponse(enumData, (const unsigned int) strlen(enumData)+1);

	puts("Starting server.");

	// The server has to be started to respond to pings.
	RakNet::SocketDescriptor socketDescriptor(atoi(portstring),0);
	bool b = server->Startup(2, &socketDescriptor, 1)==RakNet::RAKNET_STARTED;
	server->SetMaximumIncomingConnections(2);
	if (b)
		puts("Server started, waiting for connections.");
	else
	{
		puts("Server failed to start.  Terminating.");
		exit(1);
	}

	socketDescriptor.port=0;
	client->Startup(1,&socketDescriptor, 1);

	puts("'q' to quit, any other key to send a ping from the client.");
	char buff[256];

	// Loop for input
	while (1)
	{
		if (kbhit())
		{
			// Holds user data
			char ip[64], serverPort[30], clientPort[30];

			if (Gets(buff,sizeof(buff))&&(buff[0]=='q'))
				break;
			else
			{

				// Get our input
				puts("Enter the client port to listen on, or 0");
				Gets(clientPort,sizeof(clientPort));
				if (clientPort[0]==0)
					strcpy(clientPort, "0");
				puts("Enter IP to ping");
				Gets(ip, sizeof(ip));
				if (ip[0]==0)
					strcpy(ip, "127.0.0.1");
				puts("Enter the port to ping");
				Gets(serverPort,sizeof(serverPort));
				if (serverPort[0]==0)
					strcpy(serverPort, "60000");

				client->Ping(ip, atoi(serverPort), false);

				puts("Pinging");
			}
		}

		// Get a packet from either the server or the client
		p = server->Receive();

		if (p==0)
		{
			packetFromServer=false;
			p = client->Receive();
		}
		else
			packetFromServer=true;

		if (p==0)
			continue;

		// Check if this is a network message packet
		switch (p->data[0])
		{
			case ID_UNCONNECTED_PONG:
				{
					unsigned int dataLength;
					RakNet::TimeMS time;
					RakNet::BitStream bsIn(p->data,p->length,false);
					bsIn.IgnoreBytes(1);
					bsIn.Read(time);
					dataLength = p->length - sizeof(unsigned char) - sizeof(RakNet::TimeMS);
					printf("ID_UNCONNECTED_PONG from SystemAddress %s.\n", p->systemAddress.ToString(true));
					printf("Time is %i\n",time);
					printf("Ping is %i\n", (unsigned int)(RakNet::GetTimeMS()-time));
					printf("Data is %i bytes long.\n", dataLength);
					if (dataLength > 0)
						printf("Data is %s\n", p->data+sizeof(unsigned char)+sizeof(RakNet::TimeMS));

					// In this sample since the client is not running a game we can save CPU cycles by
					// Stopping the network threads after receiving the pong.
					client->Shutdown(100);
				}
				break;
			case ID_UNCONNECTED_PING:
				break;
			case ID_UNCONNECTED_PING_OPEN_CONNECTIONS:
				break;
		}

		// We're done with the packet
		if (packetFromServer)
			server->DeallocatePacket(p);
		else
			client->DeallocatePacket(p);
	}

	// We're done with the network
	RakNet::RakPeerInterface::DestroyInstance(server);
	RakNet::RakPeerInterface::DestroyInstance(client);

	return 0;
}
<commit_msg>Update ping.<commit_after>/*
 *  Copyright (c) 2014, Oculus VR, Inc.
 *  All rights reserved.
 *
 *  This source code is licensed under the BSD-style license found in the
 *  LICENSE file in the root directory of this source tree. An additional grant
 *  of patent rights can be found in the PATENTS file in the same directory.
 *
 */

// ----------------------------------------------------------------------
// RakNet version 1.0
// Filename Ping.cpp
// Very basic chat engine example
// ----------------------------------------------------------------------
#include "MessageIdentifiers.h"

#include "RakPeerInterface.h"
#include "RakPeerInterface.h"
#include "RakNetTypes.h"
#include "GetTime.h"
#include "BitStream.h"
#include <assert.h>
#include <cstdio>
#include <cstring>
#include <stdlib.h>
#include "Gets.h"

#ifdef WIN32
#include "Kbhit.h"
#else
#include "Kbhit.h"
#endif

int main(void)
{
	// Pointers to the interfaces of our server and client.
	// Note we can easily have both in the same program
	RakNet::RakPeerInterface *client=RakNet::RakPeerInterface::GetInstance();
	RakNet::RakPeerInterface *server=RakNet::RakPeerInterface::GetInstance();

	int i = server->GetNumberOfAddresses();

	// Holds packets
	RakNet::Packet* p;

	// Record the first client that connects to us so we can pass it to the ping function
	RakNet::SystemAddress clientID=RakNet::UNASSIGNED_SYSTEM_ADDRESS;
	bool packetFromServer;
	char portstring[30];

	printf("This is a sample of how to send offline pings and get offline ping\n");
	printf("responses.\n");
	printf("Difficulty: Beginner\n\n");

	// A server
	puts("Enter the server port to listen on");
	Gets(portstring,sizeof(portstring));
	if (portstring[0]==0)
		strcpy(portstring,"60000");

	// Enumeration data
	puts("Enter offline ping response data (for return by a LAN discovery for example)");
	puts("Hit enter for none.");
	char enumData[512];
	Gets(enumData,sizeof(enumData));
	if (enumData[0])
		server->SetOfflinePingResponse(enumData, (const unsigned int) strlen(enumData)+1);

	puts("Starting server.");

	// The server has to be started to respond to pings.
	RakNet::SocketDescriptor socketDescriptor(atoi(portstring),0);
	bool b = server->Startup(2, &socketDescriptor, 1)==RakNet::StartupResult::RAKNET_STARTED;
	server->SetMaximumIncomingConnections(2);
	if (b)
		puts("Server started, waiting for connections.");
	else
	{
		puts("Server failed to start.  Terminating.");
		exit(1);
	}

	socketDescriptor.port=0;
	client->Startup(1,&socketDescriptor, 1);

	puts("'q' to quit, any other key to send a ping from the client.");
	char buff[256];

	// Loop for input
	while (1)
	{
		if (kbhit())
		{
			// Holds user data
			char ip[64], serverPort[30], clientPort[30];

			if (Gets(buff,sizeof(buff))&&(buff[0]=='q'))
				break;
			else
			{

				// Get our input
				puts("Enter the client port to listen on, or 0");
				Gets(clientPort,sizeof(clientPort));
				if (clientPort[0]==0)
					strcpy(clientPort, "0");
				puts("Enter IP to ping");
				Gets(ip, sizeof(ip));
				if (ip[0]==0)
					strcpy(ip, "127.0.0.1");
				puts("Enter the port to ping");
				Gets(serverPort,sizeof(serverPort));
				if (serverPort[0]==0)
					strcpy(serverPort, "60000");

				client->Ping(ip, atoi(serverPort), false);

				puts("Pinging");
			}
		}

		// Get a packet from either the server or the client
		p = server->Receive();

		if (p==0)
		{
			packetFromServer=false;
			p = client->Receive();
		}
		else
			packetFromServer=true;

		if (p==0)
			continue;

		// Check if this is a network message packet
		switch (p->data[0])
		{
			case ID_UNCONNECTED_PONG:
				{
					unsigned int dataLength;
					RakNet::TimeMS time;
					RakNet::BitStream bsIn(p->data,p->length,false);
					bsIn.IgnoreBytes(1);
					bsIn.Read(time);
					dataLength = p->length - sizeof(unsigned char) - sizeof(RakNet::TimeMS);
					printf("ID_UNCONNECTED_PONG from SystemAddress %s.\n", p->systemAddress.ToString(true));
					printf("Time is %i\n",time);
					printf("Ping is %i\n", (unsigned int)(RakNet::GetTimeMS()-time));
					printf("Data is %i bytes long.\n", dataLength);
					if (dataLength > 0)
						printf("Data is %s\n", p->data+sizeof(unsigned char)+sizeof(RakNet::TimeMS));

					// In this sample since the client is not running a game we can save CPU cycles by
					// Stopping the network threads after receiving the pong.
					client->Shutdown(100);
				}
				break;
			case ID_UNCONNECTED_PING:
				break;
			case ID_UNCONNECTED_PING_OPEN_CONNECTIONS:
				break;
		}

		// We're done with the packet
		if (packetFromServer)
			server->DeallocatePacket(p);
		else
			client->DeallocatePacket(p);
	}

	// We're done with the network
	RakNet::RakPeerInterface::DestroyInstance(server);
	RakNet::RakPeerInterface::DestroyInstance(client);

	return 0;
}
<|endoftext|>


<commit_before>/**
 *  Copyright (c) 2009, Asmodehn's Corp.
 *  All rights reserved.
 *
 *  Redistribution and use in source and binary forms, with or without
 *  modification, are permitted provided that the following conditions are met:
 *
 *      * Redistributions of source code must retain the above copyright notice,
 * 	    this list of conditions and the following disclaimer.
 *      * Redistributions in binary form must reproduce the above copyright
 * 		notice, this list of conditions and the following disclaimer in the
 * 	    documentation and/or other materials provided with the distribution.
 *      * Neither the name of the Asmodehn's Corp. nor the names of its
 * 	    contributors may be used to endorse or promote products derived
 * 	    from this software without specific prior written permission.
 *
 *  THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
 *  AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO,
 *  THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
 *  PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS
 *  BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
 *  CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
 *  SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
 *  INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
 *  CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
 *  ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF
 *  THE POSSIBILITY OF SUCH DAMAGE.
 *
 */

#include "header.hh"

int main ( int argc, char* argv[] )
{
	return displayXX("test");
}
<commit_msg>changed header include command<commit_after>/**
 *  Copyright (c) 2009, Asmodehn's Corp.
 *  All rights reserved.
 *
 *  Redistribution and use in source and binary forms, with or without
 *  modification, are permitted provided that the following conditions are met:
 *
 *      * Redistributions of source code must retain the above copyright notice,
 * 	    this list of conditions and the following disclaimer.
 *      * Redistributions in binary form must reproduce the above copyright
 * 		notice, this list of conditions and the following disclaimer in the
 * 	    documentation and/or other materials provided with the distribution.
 *      * Neither the name of the Asmodehn's Corp. nor the names of its
 * 	    contributors may be used to endorse or promote products derived
 * 	    from this software without specific prior written permission.
 *
 *  THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
 *  AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO,
 *  THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
 *  PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS
 *  BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
 *  CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
 *  SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
 *  INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
 *  CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
 *  ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF
 *  THE POSSIBILITY OF SUCH DAMAGE.
 *
 */

#include "ProjectA/header.hh"

int main ( int argc, char* argv[] )
{
	return A_display("test A");
}
<|endoftext|>


<commit_before>#include "vm/test/test.hpp"

/* Project */
#include "vm.hpp"
#include "message.hpp"
#include "builtin/array.hpp"
#include "builtin/module.hpp"
#include "builtin/fixnum.hpp"
#include "builtin/string.hpp"
#include "builtin/symbol.hpp"

/* Testee */
#include "builtin/nativemethod.hpp"

#include "subtend/ruby.h"

/* Re-reset */
#undef  Qfalse
#undef  Qtrue
#undef  Qnil
#undef  Qundef

#define Qfalse RBX_Qfalse
#define Qtrue  RBX_Qtrue
#define Qnil   RBX_Qnil
#define Qundef RBX_Qundef

#define Sfalse ((VALUE)6L)
#define Strue  ((VALUE)10L)
#define Snil   ((VALUE)14L)
#define Sundef ((VALUE)18L)

/* From vm/objectmemory.hpp */
#undef  ALLOC_N
#define ALLOC_N(type, size) ((type*)calloc(size, sizeof(type)))

static NativeMethodContext* hidden_context = NULL;
static Array* hidden_ruby_array = NULL;
static Object* hidden_receiver = NULL;
static int hidden_argc = 0;
static Handle* hidden_c_array = NULL;

using namespace rubinius;

extern "C" {

  Handle minus_three_arity(Handle ruby_array)
  {
    hidden_context = NativeMethodContext::current();
    hidden_ruby_array = as<Array>(hidden_context->object_from(ruby_array));

    Object* first = hidden_ruby_array->get(hidden_context->state(), 0);

    return hidden_context->handle_for(first);
  }

  Handle minus_two_arity(Handle receiver, Handle ruby_array)
  {
    hidden_context = NativeMethodContext::current();
    hidden_receiver = hidden_context->object_from(receiver);
    hidden_ruby_array = as<Array>(hidden_context->object_from(ruby_array));

    Object* first = hidden_ruby_array->get(hidden_context->state(), 0);

    return hidden_context->handle_for(first);
  }

  Handle minus_one_arity(int argc, Handle* args, Handle receiver)
  {
    hidden_context = NativeMethodContext::current();
    hidden_argc = argc;
    hidden_c_array = args;
    hidden_receiver = hidden_context->object_from(receiver);

    return args[0];
  }

  Handle one_arg(Handle receiver, Handle arg1)
  {
    hidden_context = NativeMethodContext::current();
    hidden_receiver = hidden_context->object_from(receiver);

    return hidden_context->handle_for(Fixnum::from(1));
  }

  Handle two_arg(Handle receiver, Handle arg1, Handle arg2)
  {
    hidden_context = NativeMethodContext::current();
    hidden_receiver = hidden_context->object_from(receiver);

    return hidden_context->handle_for(Fixnum::from(2));
  }

  Handle three_arg(Handle receiver, Handle arg1, Handle arg2, Handle arg3)
  {
    hidden_context = NativeMethodContext::current();
    hidden_receiver = hidden_context->object_from(receiver);

    return hidden_context->handle_for(Fixnum::from(3));
  }

  Handle four_arg(Handle receiver, Handle arg1, Handle arg2, Handle arg3, Handle arg4)
  {
    hidden_context = NativeMethodContext::current();
    hidden_receiver = hidden_context->object_from(receiver);

    return hidden_context->handle_for(Fixnum::from(4));
  }

  Handle five_arg(Handle receiver, Handle arg1, Handle arg2, Handle arg3, Handle arg4, Handle arg5)
  {
    hidden_context = NativeMethodContext::current();
    hidden_receiver = hidden_context->object_from(receiver);

    return hidden_context->handle_for(Fixnum::from(5));
  }

  Handle funcaller2(Handle receiver, Handle array, Handle obj)
  {
    hidden_context = NativeMethodContext::current();
    Symbol* method = hidden_context->state()->symbol("blah");

    Handle args[1];

    args[0] = obj;

    /* Handle ret = */ rb_funcall2(array, reinterpret_cast<ID>(method), 1, args);

    return obj;
  }

}

class TestSubtend : public CxxTest::TestSuite
{
  public:

  VM* my_state;
  Task* my_task;
  Message* my_message;
  Module* my_module;

  void setUp() {
    my_state = new VM(65536 * 1000);
    my_task = Task::create(my_state);
    my_message = new Message(my_state);
    my_module = Module::create(my_state);

    my_message->set_caller(my_task->active());
  }

  void tearDown() {
    hidden_context = NULL;
    hidden_ruby_array = NULL;
    hidden_argc = 0;
    hidden_c_array = NULL;

    delete my_message;
    delete my_state;
  }

  /* Tests */

  void test_ruby_to_c_call_with_args_as_ruby_array()
  {
    Array* args = Array::create(my_state, 10);
    Array* control = Array::create(my_state, 10);

    for (std::size_t i = 0; i < 10; ++i) {
      Object* obj = my_state->new_object<Object>(my_state->globals.object.get());

      args->set(my_state, i, obj);
      control->set(my_state, i, obj);
    }

    my_message->set_arguments(my_state, args);
    my_message->name = my_state->symbol("__subtend_fake_test_method__");

    NativeMethod* method = NativeMethod::create(my_state,
                                                String::create(my_state, __FILE__),
                                                my_module,
                                                my_message->name,
                                                &minus_three_arity,
                                                Fixnum::from(ARGS_IN_RUBY_ARRAY));

    my_message->method = method;
    bool ret = method->execute(my_state, my_task, *my_message);

    TS_ASSERT_EQUALS(ret, true);

    TS_ASSERT_DIFFERS(hidden_context, static_cast<NativeMethodContext*>(NULL));

    TS_ASSERT_EQUALS(hidden_ruby_array, args);

    for (std::size_t i = 0; i < 10; ++i) {
      TS_ASSERT_EQUALS(hidden_ruby_array->get(my_state, i), control->get(my_state, i));
    }

    TS_ASSERT_EQUALS(hidden_context->return_value(), hidden_ruby_array->get(my_state, 0));
  }

  void test_ruby_to_c_call_with_receiver_and_args_as_ruby_array()
  {
    Array* args = Array::create(my_state, 10);
    Array* control = Array::create(my_state, 10);

    for (std::size_t i = 0; i < 10; ++i) {
      Object* obj = my_state->new_object<Object>(my_state->globals.object.get());

      args->set(my_state, i, obj);
      control->set(my_state, i, obj);
    }

    Object* receiver = my_state->new_object<Object>(my_state->globals.object.get());

    my_message->recv = receiver;
    my_message->set_arguments(my_state, args);
    my_message->name = my_state->symbol("__subtend_fake_test_method__");

    NativeMethod* method = NativeMethod::create(my_state,
                                                String::create(my_state, __FILE__),
                                                my_module,
                                                my_message->name,
                                                &minus_two_arity,
                                                Fixnum::from(RECEIVER_PLUS_ARGS_IN_RUBY_ARRAY));

    my_message->method = method;
    bool ret = method->execute(my_state, my_task, *my_message);

    TS_ASSERT_EQUALS(ret, true);

    TS_ASSERT_DIFFERS(hidden_context, static_cast<NativeMethodContext*>(NULL));

    TS_ASSERT_EQUALS(hidden_receiver, receiver);
    TS_ASSERT_EQUALS(hidden_ruby_array, args);

    for (std::size_t i = 0; i < 10; ++i) {
      TS_ASSERT_EQUALS(hidden_ruby_array->get(my_state, i), control->get(my_state, i));
    }

    TS_ASSERT_EQUALS(hidden_context->return_value(), hidden_ruby_array->get(my_state, 0));
  }

  void test_ruby_to_c_call_with_arg_count_args_in_c_array_plus_receiver()
  {
    Array* args = Array::create(my_state, 10);
    Array* control = Array::create(my_state, 10);

    for (std::size_t i = 0; i < 10; ++i) {
      Object* obj = my_state->new_object<Object>(my_state->globals.object.get());

      args->set(my_state, i, obj);
      control->set(my_state, i, obj);
    }

    Object* receiver = my_state->new_object<Object>(my_state->globals.object.get());

    my_message->recv = receiver;
    my_message->set_arguments(my_state, args);
    my_message->name = my_state->symbol("__subtend_fake_test_method__");

    NativeMethod* method = NativeMethod::create(my_state,
                                                String::create(my_state, __FILE__),
                                                my_module,
                                                my_message->name,
                                                &minus_one_arity,
                                                Fixnum::from(ARG_COUNT_ARGS_IN_C_ARRAY_PLUS_RECEIVER));

    my_message->method = method;
    bool ret = method->execute(my_state, my_task, *my_message);

    TS_ASSERT_EQUALS(ret, true);

    TS_ASSERT_DIFFERS(hidden_context, static_cast<NativeMethodContext*>(NULL));

    TS_ASSERT_EQUALS(hidden_receiver, receiver);
    TS_ASSERT_EQUALS(hidden_argc, 10);

    for (std::size_t i = 0; i < 10; ++i) {
      TS_ASSERT_EQUALS(hidden_context->object_from(hidden_c_array[i]), control->get(my_state, i));
    }

    TS_ASSERT_EQUALS(hidden_context->return_value(), control->get(my_state, 0));
  }

  /* TODO: Should check object identities too? */
  void test_ruby_to_c_call_with_recv_plus_one()
  {
    int arg_count = 1;

    Array* args = Array::create(my_state, arg_count);
    Array* control = Array::create(my_state, arg_count);

    for (int i = 0; i < arg_count; ++i) {
      Object* obj = my_state->new_object<Object>(my_state->globals.object.get());

      args->set(my_state, i, obj);
      control->set(my_state, i, obj);
    }

    Object* receiver = my_state->new_object<Object>(my_state->globals.object.get());

    my_message->recv = receiver;
    my_message->set_arguments(my_state, args);
    my_message->name = my_state->symbol("__subtend_fake_test_method__");

    NativeMethod* method = NativeMethod::create(my_state,
                                                String::create(my_state, __FILE__),
                                                my_module,
                                                my_message->name,
                                                &one_arg,
                                                Fixnum::from(arg_count));

    my_message->method = method;
    method->execute(my_state, my_task, *my_message);

    TS_ASSERT_EQUALS(hidden_receiver, receiver);
    TS_ASSERT_EQUALS(as<Fixnum>(hidden_context->return_value())->to_int(), arg_count);
  }

  void test_ruby_to_c_call_clears_caller_stack()
  {
    Task* task = Task::create(my_state, 2);
    task->push(Fixnum::from(4));

    MethodContext* top = task->active();

    TS_ASSERT_EQUALS(top->calculate_sp(), 0);

    Object* receiver = my_state->new_object<Object>(my_state->globals.object.get());

    my_message->recv = receiver;
    my_message->use_from_task(task, 1);
    my_message->name = my_state->symbol("__subtend_fake_test_method__");
    my_message->stack = 1;

    NativeMethod* method = NativeMethod::create(my_state,
                                                String::create(my_state, __FILE__),
                                                my_module,
                                                my_message->name,
                                                &one_arg,
                                                Fixnum::from(1));

    my_message->method = method;
    method->execute(my_state, task, *my_message);

    TS_ASSERT_EQUALS(task->active(), top);
    TS_ASSERT_EQUALS(top->calculate_sp(), 0);
    TS_ASSERT_EQUALS(hidden_receiver, receiver);
    TS_ASSERT_EQUALS(as<Fixnum>(hidden_context->return_value())->to_int(), 1);
    TS_ASSERT_EQUALS(as<Fixnum>(top->pop())->to_int(), 1);
  }

  void test_ruby_to_c_call_with_recv_plus_two()
  {
    int arg_count = 2;

    Array* args = Array::create(my_state, arg_count);
    Array* control = Array::create(my_state, arg_count);

    for (int i = 0; i < arg_count; ++i) {
      Object* obj = my_state->new_object<Object>(my_state->globals.object.get());

      args->set(my_state, i, obj);
      control->set(my_state, i, obj);
    }

    Object* receiver = my_state->new_object<Object>(my_state->globals.object.get());

    my_message->recv = receiver;
    my_message->set_arguments(my_state, args);
    my_message->name = my_state->symbol("__subtend_fake_test_method__");

    NativeMethod* method = NativeMethod::create(my_state,
                                                String::create(my_state, __FILE__),
                                                my_module,
                                                my_message->name,
                                                &two_arg,
                                                Fixnum::from(arg_count));

    my_message->method = method;
    method->execute(my_state, my_task, *my_message);

    TS_ASSERT_EQUALS(hidden_receiver, receiver);
    TS_ASSERT_EQUALS(as<Fixnum>(hidden_context->return_value())->to_int(), arg_count);
  }

  void test_ruby_to_c_call_with_recv_plus_three()
  {
    int arg_count = 3;

    Array* args = Array::create(my_state, arg_count);
    Array* control = Array::create(my_state, arg_count);

    for (int i = 0; i < arg_count; ++i) {
      Object* obj = my_state->new_object<Object>(my_state->globals.object.get());

      args->set(my_state, i, obj);
      control->set(my_state, i, obj);
    }

    Object* receiver = my_state->new_object<Object>(my_state->globals.object.get());

    my_message->recv = receiver;
    my_message->set_arguments(my_state, args);
    my_message->name = my_state->symbol("__subtend_fake_test_method__");

    NativeMethod* method = NativeMethod::create(my_state,
                                                String::create(my_state, __FILE__),
                                                my_module,
                                                my_message->name,
                                                &three_arg,
                                                Fixnum::from(arg_count));

    my_message->method = method;
    method->execute(my_state, my_task, *my_message);

    TS_ASSERT_EQUALS(hidden_receiver, receiver);
    TS_ASSERT_EQUALS(as<Fixnum>(hidden_context->return_value())->to_int(), arg_count);
  }

  void test_ruby_to_c_call_with_recv_plus_four()
  {
    int arg_count = 4;

    Array* args = Array::create(my_state, arg_count);
    Array* control = Array::create(my_state, arg_count);

    for (int i = 0; i < arg_count; ++i) {
      Object* obj = my_state->new_object<Object>(my_state->globals.object.get());

      args->set(my_state, i, obj);
      control->set(my_state, i, obj);
    }

    Object* receiver = my_state->new_object<Object>(my_state->globals.object.get());

    my_message->recv = receiver;
    my_message->set_arguments(my_state, args);
    my_message->name = my_state->symbol("__subtend_fake_test_method__");

    NativeMethod* method = NativeMethod::create(my_state,
                                                String::create(my_state, __FILE__),
                                                my_module,
                                                my_message->name,
                                                &four_arg,
                                                Fixnum::from(arg_count));

    my_message->method = method;
    method->execute(my_state, my_task, *my_message);

    TS_ASSERT_EQUALS(hidden_receiver, receiver);
    TS_ASSERT_EQUALS(as<Fixnum>(hidden_context->return_value())->to_int(), arg_count);
  }

  void test_ruby_to_c_call_with_recv_plus_five()
  {
    int arg_count = 5;

    Array* args = Array::create(my_state, arg_count);
    Array* control = Array::create(my_state, arg_count);

    for (int i = 0; i < arg_count; ++i) {
      Object* obj = my_state->new_object<Object>(my_state->globals.object.get());

      args->set(my_state, i, obj);
      control->set(my_state, i, obj);
    }

    Object* receiver = my_state->new_object<Object>(my_state->globals.object.get());

    my_message->recv = receiver;
    my_message->set_arguments(my_state, args);
    my_message->name = my_state->symbol("__subtend_fake_test_method__");

    NativeMethod* method = NativeMethod::create(my_state,
                                                String::create(my_state, __FILE__),
                                                my_module,
                                                my_message->name,
                                                &five_arg,
                                                Fixnum::from(arg_count));

    my_message->method = method;
    method->execute(my_state, my_task, *my_message);

    TS_ASSERT_EQUALS(hidden_receiver, receiver);
    TS_ASSERT_EQUALS(as<Fixnum>(hidden_context->return_value())->to_int(), arg_count);
  }

  void test_rb_funcall()
  {
    /* No actual Ruby code involved.. */
    CompiledMethod* target = CompiledMethod::create(my_state);
    target->iseq(my_state, InstructionSequence::create(my_state, 1));
    target->iseq()->opcodes()->put(my_state, 0, Fixnum::from(InstructionSequence::insn_ret));
    target->total_args(my_state, Fixnum::from(1));
    target->required_args(my_state, target->total_args());
    target->stack_size(my_state, Fixnum::from(1));

    Symbol* name = my_state->symbol("blah");
    my_state->globals.true_class.get()->method_table()->store(my_state, name, target);

    target->formalize(my_state);

    Array* args = Array::create(my_state, 2);
    Object* obj = my_state->new_object<Object>(my_state->globals.object.get());

    args->set(my_state, 0, Qtrue);
    args->set(my_state, 1, obj);

    Object* receiver = my_state->new_object<Object>(my_state->globals.object.get());

    my_message->recv = receiver;
    my_message->set_arguments(my_state, args);
    my_message->name = my_state->symbol("__subtend_fake_funcall_test_method__");

    NativeMethod* method = NativeMethod::create(my_state,
                                                String::create(my_state, __FILE__),
                                                my_module,
                                                my_message->name,
                                                &funcaller2,
                                                Fixnum::from(2));

    my_message->method = method;
    /* This only loads the cm. */
    method->execute(my_state, my_task, *my_message);

    my_task->active()->vmm->run(my_task->active()->vmm, my_task, my_task->active());

    TS_ASSERT_EQUALS(obj, my_task->active()->top());

    /* TODO: Need some more reasonable tests here? */
  }

};
<commit_msg>Removed old subtend VM tests.<commit_after><|endoftext|>


<commit_before>/*
 *  RustEditor: Plugin to add Rust language support to QtCreator IDE.
 *  Copyright (C) 2015  Davide Ghilardi
 *
 *  This file is part of RustEditor.
 *
 *  RustEditor is free software: you can redistribute it and/or modify
 *  it under the terms of the GNU Lesser General Public License as published by
 *  the Free Software Foundation, either version 2.1 of the License, or
 *  (at your option) any later version.
 *
 *  RustEditor is distributed in the hope that it will be useful,
 *  but WITHOUT ANY WARRANTY; without even the implied warranty of
 *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
 *  GNU Lesser General Public License for more details.
 *
 *  You should have received a copy of the GNU Lesser General Public License
 *  along with RustEditor.  If not, see <http://www.gnu.org/licenses/>.
*/

#include "configuration.h"

#include <QSettings>
#include <QFileInfo>

#include <utils/environment.h>
#include <utils/fileutils.h>
#include <coreplugin/icore.h>

namespace {
    const QLatin1String SETTINGS_GROUP("RustEditorConfiguration");

    const QLatin1String RUST_SRC_ENV("RUST_SRC_PATH");
    const QLatin1String RUST_SRC_DEF("/usr/src/rust");

    const QLatin1String RACER_PATH_DEF("/usr/bin");
}

using namespace RustEditor::Internal;

Configuration *Configuration::cfg_instance = NULL;

Configuration::Configuration(QObject *parent):
    QObject(parent)
{
    load();
    cfg_instance = this;
}

Configuration *Configuration::getInstancePtr()
{
    Q_ASSERT(cfg_instance != NULL);
    return cfg_instance;
}

const Settings &Configuration::getSettingsPtr()
{
    return cfg_instance->rusteditorSettings;
}

void Configuration::setSettings(const Settings &newSettings)
{
    cfg_instance->rusteditorSettings = newSettings;
    cfg_instance->save();
}

void Configuration::load()
{
    bool saveSettings = false;

    QSettings *qtCreatorSettings = Core::ICore::settings();
    qtCreatorSettings->beginGroup(SETTINGS_GROUP);
    rusteditorSettings.load(*qtCreatorSettings);

    Utils::FileName rustSrcPath = cfgPathLookup(rusteditorSettings.rustSrcPath(), Utils::FileName::fromString(RUST_SRC_DEF), RUST_SRC_ENV, saveSettings);
    rusteditorSettings.setRustSrcPath(rustSrcPath);

    Utils::FileName racerPath = cfgPathLookup(rusteditorSettings.racerPath(), Utils::FileName::fromString(RACER_PATH_DEF), QLatin1String(""), saveSettings);
    rusteditorSettings.setRacerPath(racerPath);

    qtCreatorSettings->endGroup();

    if (saveSettings)
        save();
}

void Configuration::save()
{
    QSettings *settings = Core::ICore::settings();
    settings->beginGroup(SETTINGS_GROUP);
    rusteditorSettings.save(*settings);
    settings->endGroup();
}

Utils::FileName Configuration::cfgPathLookup(const Utils::FileName &cfg, const Utils::FileName &def, const QString &envKey, bool &save)
{
    Utils::FileName result;
    if (cfg.isEmpty()) {
        Utils::Environment env = Utils::Environment::systemEnvironment();
        if (!envKey.isEmpty()){
            Utils::FileName location = env.searchInPath(envKey);
            QFileInfo fi = location.toFileInfo();

            if (fi.exists() && fi.isDir()) result = location;
            else result = def;

        }else{

            result = def;
        }
    }else{
        result = cfg;
    }
    save = save || (result != cfg);
    return result;
}

<commit_msg>Modified default rust source dir<commit_after>/*
 *  RustEditor: Plugin to add Rust language support to QtCreator IDE.
 *  Copyright (C) 2015  Davide Ghilardi
 *
 *  This file is part of RustEditor.
 *
 *  RustEditor is free software: you can redistribute it and/or modify
 *  it under the terms of the GNU Lesser General Public License as published by
 *  the Free Software Foundation, either version 2.1 of the License, or
 *  (at your option) any later version.
 *
 *  RustEditor is distributed in the hope that it will be useful,
 *  but WITHOUT ANY WARRANTY; without even the implied warranty of
 *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
 *  GNU Lesser General Public License for more details.
 *
 *  You should have received a copy of the GNU Lesser General Public License
 *  along with RustEditor.  If not, see <http://www.gnu.org/licenses/>.
*/

#include "configuration.h"

#include <QSettings>
#include <QFileInfo>

#include <utils/environment.h>
#include <utils/fileutils.h>
#include <coreplugin/icore.h>

namespace {
    const QLatin1String SETTINGS_GROUP("RustEditorConfiguration");

    const QLatin1String RUST_SRC_ENV("RUST_SRC_PATH");
    const QLatin1String RUST_SRC_DEF("/usr/src/rust/src");

    const QLatin1String RACER_PATH_DEF("/usr/bin");
}

using namespace RustEditor::Internal;

Configuration *Configuration::cfg_instance = NULL;

Configuration::Configuration(QObject *parent):
    QObject(parent)
{
    load();
    cfg_instance = this;
}

Configuration *Configuration::getInstancePtr()
{
    Q_ASSERT(cfg_instance != NULL);
    return cfg_instance;
}

const Settings &Configuration::getSettingsPtr()
{
    return cfg_instance->rusteditorSettings;
}

void Configuration::setSettings(const Settings &newSettings)
{
    cfg_instance->rusteditorSettings = newSettings;
    cfg_instance->save();
}

void Configuration::load()
{
    bool saveSettings = false;

    QSettings *qtCreatorSettings = Core::ICore::settings();
    qtCreatorSettings->beginGroup(SETTINGS_GROUP);
    rusteditorSettings.load(*qtCreatorSettings);

    Utils::FileName rustSrcPath = cfgPathLookup(rusteditorSettings.rustSrcPath(), Utils::FileName::fromString(RUST_SRC_DEF), RUST_SRC_ENV, saveSettings);
    rusteditorSettings.setRustSrcPath(rustSrcPath);

    Utils::FileName racerPath = cfgPathLookup(rusteditorSettings.racerPath(), Utils::FileName::fromString(RACER_PATH_DEF), QLatin1String(""), saveSettings);
    rusteditorSettings.setRacerPath(racerPath);

    qtCreatorSettings->endGroup();

    if (saveSettings)
        save();
}

void Configuration::save()
{
    QSettings *settings = Core::ICore::settings();
    settings->beginGroup(SETTINGS_GROUP);
    rusteditorSettings.save(*settings);
    settings->endGroup();
}

Utils::FileName Configuration::cfgPathLookup(const Utils::FileName &cfg, const Utils::FileName &def, const QString &envKey, bool &save)
{
    Utils::FileName result;
    if (cfg.isEmpty()) {
        Utils::Environment env = Utils::Environment::systemEnvironment();
        if (!envKey.isEmpty()){
            Utils::FileName location = env.searchInPath(envKey);
            QFileInfo fi = location.toFileInfo();

            if (fi.exists() && fi.isDir()) result = location;
            else result = def;

        }else{

            result = def;
        }
    }else{
        result = cfg;
    }
    save = save || (result != cfg);
    return result;
}

<|endoftext|>