示例#1
0
文件: xattr.c 项目: pcwizz/crossxattr
ssize_t setAttr( const char* path, const char *attrname, const void* data, size_t nbytes ) {
    ssize_t ret = extattr_set_file( path, EXTATTR_NAMESPACE_USER, attrname, data, nbytes );

    checkReturnValue( "setAttr", ret );

    return ret;
}
示例#2
0
文件: xattr.c 项目: pcwizz/crossxattr
ssize_t deleteAttr( const char* path, const char* attrname ) {
    ssize_t ret = extattr_delete_file( path, EXTATTR_NAMESPACE_USER, attrname );

    checkReturnValue( "deleteAttr", ret );

    return ret;
}
示例#3
0
文件: xattr.c 项目: pcwizz/crossxattr
ssize_t listAttrs( const char* path, void* data, size_t nbytes ) {
    ssize_t listxattrRet = listxattr( path, (char*) data, nbytes );

    checkReturnValue( "listAttrs", listxattrRet);

    ssize_t numEntries = numCharInStr( '.', data, listxattrRet );

    // remove non-user namespace list items and remove the namespace name
    // specifier
    
    // first allocate a list of pointers to each string. Worst case every
    // attribute which is found is in the USER namespace so we need a
    // dynamically array which is this long
    char** usefulBits = (char**) malloc( sizeof(char*) * numEntries );
    if ( usefulBits == NULL )
        errExit( "usefulBits malloc in listAttrs" );

    // fill usefulBits with NULL for now
    for ( ssize_t i = 0; i < numEntries; i++ )
        usefulBits[i] = NULL;

    // now put in the relevant pointers
    size_t numEntriesRemaining = numEntries;
    usefulBits[0] = seekToInterestingPart( (char*) data, &numEntriesRemaining );
    for ( ssize_t i = 1; i < numEntries; i++ ) { // don't do this too many times
        // returns NULL if we have run out
        usefulBits[i] = seekToInterestingPart( usefulBits[i-1] + strlen(usefulBits[i-1]) + 6, &numEntriesRemaining );
    }

    // work out how many entries we have
    ssize_t numInterestingEntries = 0;
    for ( ssize_t i = 0; i < numEntries; i++ ) {
        if ( usefulBits[i] == NULL ) {
            // this is all of them
            break;
        } else {
            numInterestingEntries++;
        }
    }

    // now we overwrite data with the newly edited list. This will definitely
    // fit because we have removed things from what was previously in data
    // for the same reason we can be sure that we won't be overwriting ourself

    // these for loops could all be combined however this form is better for readability
    char* currPos = (char*) data;
    for ( ssize_t i = 0; i < numInterestingEntries; i++ ) {
        size_t size = strlen( usefulBits[i] );
        strcpy( currPos, usefulBits[i] );
        currPos += ( size + 2 );
    }
    free( usefulBits );
    return numInterestingEntries;
}
示例#4
0
文件: xattr.c 项目: pcwizz/crossxattr
ssize_t deleteAttr( const char* path, const char* attrname ) {
    char* name = addNamespacePrefix( attrname );
    ssize_t ret = removexattr( path, name );

    free( name );
    name = NULL;

    checkReturnValue( "deleteAttr", ret );

    return ret;
}
示例#5
0
文件: xattr.c 项目: pcwizz/crossxattr
ssize_t getAttr( const char* path, const char* attrname, void* data, size_t nbytes ) {
    char* name = addNamespacePrefix( attrname );
    ssize_t ret = getxattr( path, name, data, nbytes );

    free( name );
    name = NULL;

    checkReturnValue( "getAttr", ret );

    return ret;
}
示例#6
0
文件: xattr.c 项目: pcwizz/crossxattr
ssize_t setAttr( const char* path, const char *attrname, const void* data, size_t nbytes ) {
    char* name = addNamespacePrefix( attrname );
    // flags = 0 means it will be created if it does not exist or replaced if
    // it does
    ssize_t ret = setxattr( path, name, data, nbytes, 0 );

    free( name );
    name = NULL;

    checkReturnValue( "setAttr", ret );

    return ret;
}
示例#7
0
文件: xattr.c 项目: pcwizz/crossxattr
ssize_t listAttrs( const char* path, void* data, size_t nbytes ) {
    /* 
	 extattr_list_file() returns a list of attributes present in the requested namespace.
	 Each list entry consists of a single byte containing the length of the attribute name.
	 The attribute name is not terminated by ASCII 0 (nul).
	*/
    ssize_t ret = extattr_list_file( path, EXTATTR_NAMESPACE_USER, data, nbytes );

    checkReturnValue( "listAttrs", ret );

	// Do the string manipulation
	char* bitstring = data;// Cast the void pointer to a string
	int len = (int) bitstring[0];// Bootstrap the first pointer
	for ( int i = 1; i < nbytes; i++ ) {
		if ( i == len ) {
			// Set the position of the next pointer
			len = (int) bitstring[i];
			bitstring[i] = '\0';
		}
		bitstring[i-1] = bitstring[i];
	}
    return ret;
}
示例#8
0
文件: JIT.cpp 项目: hoangt/tool_axe
/// Try and compile a fragment starting at the specified address. Returns
/// true if successful setting \a nextAddress to the first instruction after
/// the fragment. If unsuccessful returns false and sets \a nextAddress to the
/// address after the current function. \a endOfBlock is set to true if the
/// next address is in a new basic block.
bool JITImpl::
compileOneFragment(Core &core, JITCoreInfo &coreInfo, uint32_t startPc,
                   bool &endOfBlock, uint32_t &pcAfterFragment)
{
  assert(initialized);
  resetPerFunctionState();

  std::map<uint32_t,JITFunctionInfo*>::iterator infoIt =
    coreInfo.functionMap.find(startPc);
  JITFunctionInfo *info =
    (infoIt == coreInfo.functionMap.end()) ? 0 : infoIt->second;
  if (info && !info->isStub) {
    endOfBlock = true;
    return false;
  }

  std::vector<InstructionOpcode> opcode;
  std::vector<Operands> operands;
  if (!getFragmentToCompile(core, startPc, opcode, operands,
                            endOfBlock, pcAfterFragment)) {
    return false;
  }
  std::queue<std::pair<uint32_t,MemoryCheck*> > checks;
  placeMemoryChecks(opcode, operands, checks);

  LLVMValueRef f;
  if (info) {
    f = info->value;
    info->func = 0;
    info->isStub = false;
    deleteFunctionBody(f);
  } else {
    info = new JITFunctionInfo(startPc);
    coreInfo.functionMap.insert(std::make_pair(startPc, info));
    // Create function to contain the code we are about to add.
    info->value = f = LLVMAddFunction(module, "", jitFunctionType);
    LLVMSetFunctionCallConv(f, LLVMFastCallConv);
  }
  threadParam = LLVMGetParam(f, 0);
  LLVMValueRef ramBase = LLVMConstInt(LLVMInt32Type(), core.ram_base, false);
  ramSizeLog2Param = LLVMConstInt(LLVMInt32Type(), core.ramSizeLog2, false);
  LLVMBasicBlockRef entryBB = LLVMAppendBasicBlock(f, "entry");
  LLVMPositionBuilderAtEnd(builder, entryBB);
  uint32_t pc = startPc;
  bool needsReturn = true;
  for (unsigned i = 0, e = opcode.size(); i != e; ++i) {
    InstructionOpcode opc = opcode[i];
    const Operands &ops = operands[i];
    InstructionProperties *properties = &instructionProperties[opc];
    uint32_t nextPc = pc + properties->size / 2;
    emitMemoryChecks(i, checks);

    // Lookup function to call.
    LLVMValueRef callee = LLVMGetNamedFunction(module, properties->function);
    assert(callee && "Function for instruction not found in module");
    LLVMTypeRef calleeType = LLVMGetElementType(LLVMTypeOf(callee));
    const unsigned fixedArgs = 4;
    const unsigned maxOperands = 6;
    unsigned numArgs = properties->getNumExplicitOperands() + fixedArgs;
    assert(LLVMCountParamTypes(calleeType) == numArgs);
    LLVMTypeRef paramTypes[fixedArgs + maxOperands];
    assert(numArgs <= (fixedArgs + maxOperands));
    LLVMGetParamTypes(calleeType, paramTypes);
    // Build call.
    LLVMValueRef args[fixedArgs + maxOperands];
    args[0] = threadParam;
    args[1] = LLVMConstInt(paramTypes[1], nextPc, false);
    args[2] = ramBase;
    args[3] = ramSizeLog2Param;
    for (unsigned i = fixedArgs; i < numArgs; i++) {
      uint32_t value =
      properties->getNumExplicitOperands() <= 3 ? ops.ops[i - fixedArgs] :
      ops.lops[i - fixedArgs];
      args[i] = LLVMConstInt(paramTypes[i], value, false);
    }
    LLVMValueRef call = emitCallToBeInlined(callee, args, numArgs);
    checkReturnValue(call, *properties);
    if (properties->mayBranch() && properties->function &&
        emitJumpToNextFragment(opc, ops, coreInfo, nextPc, info)) {
      needsReturn = false;
    }
    pc = nextPc;
  }
  assert(checks.empty() && "Not all checks emitted");
  if (needsReturn) {
    LLVMValueRef args[] = {
      threadParam
    };
    emitCallToBeInlined(functions.jitUpdateExecutionFrequency, args, 1);
    // Build return.
    LLVMBuildRet(builder,
                 LLVMConstInt(LLVMGetReturnType(jitFunctionType),
                              JIT_RETURN_CONTINUE, 0));
  }
  // Add incoming phi values.
  if (earlyReturnBB) {
    LLVMAddIncoming(earlyReturnPhi, &earlyReturnIncomingValues[0],
                    &earlyReturnIncomingBlocks[0],
                    earlyReturnIncomingValues.size());
  }
  if (DEBUG_JIT) {
    LLVMDumpValue(f);
    LLVMVerifyFunction(f, LLVMAbortProcessAction);
  }
  // Optimize.
  for (std::vector<LLVMValueRef>::iterator it = calls.begin(), e = calls.end();
       it != e; ++it) {
    LLVMExtraInlineFunction(*it);
  }
  LLVMRunFunctionPassManager(FPM, f);
  if (DEBUG_JIT) {
    LLVMDumpValue(f);
  }
  // Compile.
  JITInstructionFunction_t compiledFunction =
    reinterpret_cast<JITInstructionFunction_t>(
      LLVMRecompileAndRelinkFunction(executionEngine, f));
  info->isStub = false;
  info->func = compiledFunction;
  core.setOpcode(startPc, getFunctionThunk(*info), (pc - startPc) * 2);
  return true;
}