⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 mk_processtool.cxx

📁 C++ 编写的EROS RTOS
💻 CXX
字号:
/* * Copyright (C) 1998, 1999, 2001, Jonathan S. Shapiro. * * This file is part of the EROS Operating System. * * 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, * 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, 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */#include <kerninc/kernel.hxx>#include <kerninc/Key.hxx>#include <kerninc/Invocation.hxx>#include <kerninc/Node.hxx>#include <kerninc/Thread.hxx>#include <eros/Key.h>#include <eros/Invoke.h>#include <eros/StdKeyType.h>#include <eros/ProcessToolKey.h>#include <eros/KeyBitsKey.h>/* CompareBrand(inv, pDomKey, pBrand) returns TRUE if the passed keys * were of the right type and it was feasible to compare their * brands. Otherwise, it returns FALSE. * * Iff CompareBrand returns TRUE, then it also updates inv.exit_w1 and * inv.exit_w2 to hold the capability type (start or resume) and the * key info field, respectively. */static boolCompareBrand(Invocation& inv, Key* pDomKey, Key* pBrand){  /* It was some sort of identify operation -- see if we can satisfy   * it.  Must not do this operation on prepared key, since the link   * pointers mess things up rather badly.  Since we know that these   * are argument keys, the deprepare will not damage any state in the   * client key registers.   *    * The brand slot never needs to be prepared anyway.   */  /* WE NEED TO MAKE A TEMPORARY COPY OF THESE KEYS in case one of   * them proves to be the output key.   */  assert (pDomKey->IsPrepared());  pBrand->Prepare();  Node *domNode = (Node *) pDomKey->GetObjectPtr();  Key& otherBrand = (*domNode)[ProcBrand];  otherBrand.Prepare();  COMMIT_POINT();    /* Expensive comparison, primarily because we do not want to   * unprepare the keys (unpreparing them would bump allocation counts   * unnecessarily).   */  if ( pBrand->GetType() != otherBrand.GetType()        /* Do not compare flags field -- that is purely internal. */       || pBrand->keyData != otherBrand.keyData )    return false;  /* If they *did* prepare, and they are object keys, then the object   * pointers will be the same.   */  if ( pBrand->IsObjectKey() ) {    if (pBrand->ok.pObj != otherBrand.ok.pObj)      return false;  }  else {    if ( pBrand->keyData != pBrand->keyData	 || pBrand->nk.value[0] != otherBrand.nk.value[0]	 || pBrand->nk.value[1] != otherBrand.nk.value[1]	 || pBrand->nk.value[2] != otherBrand.nk.value[2] )      return false;  }      inv.exit.w1 = pDomKey->GetType();  inv.exit.w2 = pDomKey->keyData;    /* Temporary keys of this form MUST NOT BE BUILT until after the   * commit point!!!   */  {    /* Unchain, but do not unprepare -- the objects do not have on-disk     * keys.      */    Process *pContext = 0;    if (pDomKey->IsGateKey())      pContext = pDomKey->gk.pContext;    inv.SetExitKey(0, *pDomKey);    if (inv.exit.pKey[0]) {      assert (inv.exit.pKey[0]->IsPrepared());      inv.exit.pKey[0]->InitType(KT_Node);      inv.exit.pKey[0]->SetPrepared();      /* We have really just copied the input key and smashed it for a       * node key.  We now have a prepared node key, UNLESS the input key       * was actually a gate key, in which event we have a prepared node       * key on the wrong keyring.  Fix up the keyring in that case:       */        if (pContext) {	inv.exit.pKey[0]->NH_Unchain();	ObjectHeader *pObj = pContext->procRoot;	assert (pObj);	/* Link as next key after object */	inv.exit.pKey[0]->ok.pObj = pObj;  	inv.exit.pKey[0]->ok.next = pObj->kr.next;	inv.exit.pKey[0]->ok.prev = (KeyRing *) pObj;  	pObj->kr.next = (KeyRing*) inv.exit.pKey[0];	inv.exit.pKey[0]->ok.next->prev = (KeyRing*) inv.exit.pKey[0];      }    }  }  return true;}voidProcessToolKey(Invocation& inv){#if 0  Key& arg0Key = inv.entry.key[0]; /* user-provided key arg 0 */  Key& arg1Key = inv.entry.key[1]; /* user-provided brand key */  Key& domKey = arg0Key;	/* key to domain */#endif    /* Until proven otherwise: */  inv.exit.code = RC_RequestError;  /* All of these operations return a single key, which is void until   * proven otherwise:   */  switch (inv.entry.code) {  case OC_ProcTool_MkProcKey:    {      COMMIT_POINT();      if (inv.entry.key[0]->IsType(KT_Node) == false) {#if 0        dprintf(true, "domtool: entry key is not node key\n");#endif	return;      }      if ( inv.entry.key[0]->IsReadOnly() ) {#if 0        printf("domtool: entry key is read only\n");#endif	return;      }      if ( inv.entry.key[0]->IsNoCall() ) {#if 0        printf("domtool: entry key is no-call\n");#endif	return;      }      assert ( inv.entry.key[0]->IsHazard() == false );      inv.exit.code = RC_OK;      inv.SetExitKey(0, *inv.entry.key[0]);      if (inv.exit.pKey[0]) {	inv.exit.pKey[0]->SetType(KT_Process);	inv.exit.pKey[0]->keyData = 0;      }      return;    }  case OC_ProcTool_IdentGateKey:    {      inv.entry.key[0]->Prepare();            if (inv.entry.key[0]->IsType(KT_Start) == false &&	  inv.entry.key[0]->IsType(KT_Resume) == false) {	COMMIT_POINT();	return;      }      bool isResume = inv.entry.key[0]->IsType(KT_Resume);            inv.exit.code = RC_OK;      if ( CompareBrand(inv, inv.entry.key[0], inv.entry.key[1]) == false )	return;			/* brands do not match */            /* Must be either start or resume, by virtue of test above. */      inv.exit.w1 = (inv.exit.w1 == KT_Start) ? 1 : 2;      if ( isResume )	inv.exit.w2 = inv.entry.key[0]->keyData;      return;    }  case OC_ProcTool_IdentProcessKey:    {      inv.entry.key[0]->Prepare();            if (inv.entry.key[0]->IsType(KT_Process) == false) {	COMMIT_POINT();	return;      }      inv.exit.code = RC_OK;      if ( CompareBrand(inv, inv.entry.key[0], inv.entry.key[1]) ) {	inv.exit.w1 = 1;	inv.exit.w2 = 0;      }            return;    }  case OC_ProcTool_IdentSegGateKey:    {#ifdef KT_Wrapper      if (inv.entry.key[0]->IsType(KT_Wrapper) == false) {	COMMIT_POINT();	return;      }#else      if (inv.entry.key[0]->IsType(KT_Segment) == false &&	  inv.entry.key[0]->IsType(KT_Node) == false) {	COMMIT_POINT();	return;      }      if (inv.entry.key[0]->IsRedSegmentKey() == false) {	COMMIT_POINT();	return;      }#endif      if ( inv.entry.key[0]->IsNoCall() ) {	COMMIT_POINT();	return;      }      inv.entry.key[0]->Prepare();      Node *theNode = (Node *) inv.entry.key[0]->GetObjectPtr();#ifdef KT_Wrapper      Key& fmtKey = (*theNode)[WrapperFormat];      /* If no keeper key: */      if ((fmtKey.nk.value[0] & WRAPPER_KEEPER) == 0) {	COMMIT_POINT();	return;      }      uint32_t slot = WrapperKeeper;#else      Key& fmtKey = (*theNode)[RedSegFormat];      if ( fmtKey.IsValidFormatKey() == false ) {#if 0	extern void db_eros_print_key(Key&);	db_eros_print_key(fmtKey);	dprintf(true, "Bad format key!\n");#endif	COMMIT_POINT();	return;      }      /* If no keeper key: */      uint32_t slot = REDSEG_GET_KPR_SLOT(fmtKey.nk);      if ( slot == EROS_NODE_SLOT_MASK ||	   (*theNode)[slot].IsGateKey() == false) {	COMMIT_POINT();	return;      }#endif      Key& domKey = (*theNode)[slot];      domKey.Prepare();            if (domKey.IsType(KT_Start) == false &&	  domKey.IsType(KT_Resume) == false) {	COMMIT_POINT();	return;      }      bool isResume = domKey.IsType(KT_Resume);            inv.exit.code = RC_OK;            if ( CompareBrand(inv, &domKey, inv.entry.key[1]) == false )	return;      /* Must be either start or resume, by virtue of test above. */      inv.exit.w1 = (inv.exit.w1 == KT_Start) ? 1 : 2;      if ( isResume )	inv.exit.w2 = inv.entry.key[0]->keyData;      return;    }  case OC_ProcTool_CompareProcessOrigins:    {      if ((inv.entry.key[0]->IsGateKey() == false) &&	  (inv.entry.key[0]->IsType(KT_Process) == false)) {	COMMIT_POINT();	return;      }      if ((inv.entry.key[1]->IsGateKey() == false) &&	  (inv.entry.key[1]->IsType(KT_Process) == false)) {	COMMIT_POINT();	return;      }            inv.entry.key[0]->Prepare();      inv.entry.key[1]->Prepare();      Node *domain0 = (Node *) inv.entry.key[0]->GetObjectPtr();      Node *domain1 = (Node *) inv.entry.key[1]->GetObjectPtr();      (*domain0)[ProcBrand].Prepare();      (*domain1)[ProcBrand].Prepare();      COMMIT_POINT();      Key& brand0 = (*domain0)[ProcBrand];      Key& brand1 = (*domain1)[ProcBrand];      inv.exit.code = RC_OK;            /* The following works ONLY because neither the domain brand key nor       * a key coming from a key register can be hazarded.       */      if (memcmp( &brand0, &brand1, sizeof(Key)) == 0)	inv.exit.w1 = 1;      else	inv.exit.w1 = 0;      return;    }  case OC_KeyType:    COMMIT_POINT();    inv.exit.code = RC_OK;    inv.exit.w1 = inv.keyType;    return;  default:    COMMIT_POINT();    inv.exit.code = RC_UnknownRequest;    return;  }  return;}

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -