IOReturn IOFireWireSBP2LibORB::setCommandBuffersAsRanges( FWSBP2VirtualRange * ranges, 
										UInt32 withCount, UInt32 withDirection, 
										UInt32 offset, 
										UInt32 length )
{
	IOReturn status = kIOReturnSuccess;
	
	uint32_t len = 0;
	uint64_t params[6];
	
	FWLOG(( "IOFireWireSBP2LibORB : setCommandBuffersAsRanges\n" ));
//	printf( "IOFireWireSBP2LibORB : setCommandBuffersAsRanges\n" );

	//
	// create or grow range scratch
	//
	
	UInt32 range_length = withCount * sizeof(FWSBP2PrivateVirtualRange);
			
	if( fRangeScratchLength < range_length )
	{
		if( fRangeScratch != NULL )
		{
			// delete it
			vm_deallocate( mach_task_self(), (vm_address_t)fRangeScratch, fRangeScratchLength );
			fRangeScratch = NULL;
			fRangeScratchLength = 0;
		}
		
		// alloc a bigger one
		vm_allocate( mach_task_self(), (vm_address_t*)&fRangeScratch, range_length, true /*anywhere*/ );
		if( fRangeScratch != NULL )
		{
			fRangeScratchLength = range_length;
		}
	}

	//
	// fill range scratch
	//
	
	if( fRangeScratch != NULL )
	{
		for( UInt32 i = 0; i < withCount; i++ )
		{
			fRangeScratch[i].address = (uint64_t)ranges[i].address;
			fRangeScratch[i].length = ranges[i].length;

			ROSETTA_ONLY(
				fRangeScratch[i].address = OSSwapInt64( fRangeScratch[i].address );
				fRangeScratch[i].length = OSSwapInt64( fRangeScratch[i].length );
			);
		}
	}
Exemple #2
0
void 
swap_segment_command_64(
struct segment_command_64* sg,
enum NXByteOrder target_byte_sex)
{
	/* char segname[16] */
	sg->cmd = OSSwapInt32(sg->cmd);
	sg->cmdsize = OSSwapInt32(sg->cmdsize);
	sg->vmaddr = OSSwapInt64(sg->vmaddr);
	sg->vmsize = OSSwapInt64(sg->vmsize);
	sg->fileoff = OSSwapInt64(sg->fileoff);
	sg->filesize = OSSwapInt64(sg->filesize);
	sg->maxprot = OSSwapInt32(sg->maxprot);
	sg->initprot = OSSwapInt32(sg->initprot);
	sg->nsects = OSSwapInt32(sg->nsects);
	sg->flags = OSSwapInt32(sg->flags);
}
void
swap_x86_exception_state64(
x86_exception_state64_t *exc,
enum NXByteOrder target_byte_sex)
{
	exc->trapno = OSSwapInt32(exc->trapno);
	exc->err = OSSwapInt32(exc->err);
    	exc->faultvaddr = OSSwapInt64(exc->faultvaddr);
}
void
swap_x86_debug_state64(
x86_debug_state64_t *debug,
enum NXByteOrder target_byte_sex)
{
	debug->dr0 = OSSwapInt64(debug->dr0);
	debug->dr1 = OSSwapInt64(debug->dr1);
	debug->dr2 = OSSwapInt64(debug->dr2);
	debug->dr3 = OSSwapInt64(debug->dr3);
	debug->dr4 = OSSwapInt64(debug->dr4);
	debug->dr5 = OSSwapInt64(debug->dr5);
	debug->dr6 = OSSwapInt64(debug->dr6);
	debug->dr7 = OSSwapInt64(debug->dr7);
}
Exemple #5
0
void dosect64(void *start, struct section_64 *sect, bool needsFlip, struct gcinfo *gcip) {
    if (debug) printf("section %s from segment %s\n", sect->sectname, sect->segname);
    if (strcmp(sect->segname, "__OBJC") && strcmp(sect->segname, "__DATA")) return;
    if (strcmp(sect->sectname, "__image_info") && strncmp(sect->sectname, "__objc_imageinfo", 16)) return;
    gcip->hasObjC = true;
    gcip->hasInfo = true;
    if (needsFlip) {
        sect->offset = OSSwapInt32(sect->offset);
        sect->size = OSSwapInt64(sect->size);
    }
    // these guys aren't inline - they point elsewhere
    gcip->flags = iiflags(start + sect->offset, sect->size, needsFlip);
}
Exemple #6
0
void
swap_section_64(
struct section_64 *s,
uint32_t nsects,
enum NXByteOrder target_byte_sex)
{
    uint32_t i;

	for(i = 0; i < nsects; i++){
	    /* sectname[16] */
	    /* segname[16] */
	    s[i].addr = OSSwapInt64(s[i].addr);
	    s[i].size = OSSwapInt64(s[i].size);
	    s[i].offset = OSSwapInt32(s[i].offset);
	    s[i].align = OSSwapInt32(s[i].align);
	    s[i].reloff = OSSwapInt32(s[i].reloff);
	    s[i].nreloc = OSSwapInt32(s[i].nreloc);
	    s[i].flags = OSSwapInt32(s[i].flags);
	    s[i].reserved1 = OSSwapInt32(s[i].reserved1);
	    s[i].reserved2 = OSSwapInt32(s[i].reserved2);
	    s[i].reserved3 = OSSwapInt32(s[i].reserved3);
	}
}
Exemple #7
0
void
swap_routines_command_64(
struct routines_command_64 *r_cmd,
enum NXByteOrder target_byte_sex)
{
	r_cmd->cmd = OSSwapInt32(r_cmd->cmd);
	r_cmd->cmdsize = OSSwapInt32(r_cmd->cmdsize);
	r_cmd->init_address = OSSwapInt64(r_cmd->init_address);
	r_cmd->init_module = OSSwapInt64(r_cmd->init_module);
	r_cmd->reserved1 = OSSwapInt64(r_cmd->reserved1);
	r_cmd->reserved2 = OSSwapInt64(r_cmd->reserved2);
	r_cmd->reserved3 = OSSwapInt64(r_cmd->reserved3);
	r_cmd->reserved4 = OSSwapInt64(r_cmd->reserved4);
	r_cmd->reserved5 = OSSwapInt64(r_cmd->reserved5);
	r_cmd->reserved6 = OSSwapInt64(r_cmd->reserved6);
}
Exemple #8
0
void
swap_nlist_64(
struct nlist_64 *symbols,
uint32_t nsymbols,
enum NXByteOrder target_byte_sex)
{
    uint32_t i;

	for(i = 0; i < nsymbols; i++){
	    symbols[i].n_un.n_strx = OSSwapInt32(symbols[i].n_un.n_strx);
	    /* n_type */
	    /* n_sect */
	    symbols[i].n_desc = OSSwapInt16(symbols[i].n_desc);
	    symbols[i].n_value = OSSwapInt64(symbols[i].n_value);
	}
}
Exemple #9
0
void doseg64(void *start, struct segment_command_64 *seg, bool needsFlip, struct gcinfo *gcip) {
    if (debug) printf("segment name: %s\n", seg->segname);
    if (seg->segname[0] && strcmp("__OBJC", seg->segname) && strcmp("__DATA", seg->segname)) return;
    gcip->hasObjC = true;
    // lets do sections
    if (needsFlip) {
        seg->fileoff = OSSwapInt64(seg->fileoff);
        seg->nsects = OSSwapInt32(seg->nsects);
    }
    int nsects;
    struct section_64 *sect = (struct section_64 *)(seg + 1);
    for (int nsects = 0; nsects < seg->nsects; ++nsects) {
        // sections directly follow
        
        dosect64(start, sect + nsects, needsFlip, gcip);
    }
}
Exemple #10
0
void
swap_dylib_module_64(
struct dylib_module_64 *mods,
uint32_t nmods,
enum NXByteOrder target_byte_sex)
{
    uint32_t i;

	for(i = 0; i < nmods; i++){
	    mods[i].module_name = OSSwapInt32(mods[i].module_name);
	    mods[i].iextdefsym  = OSSwapInt32(mods[i].iextdefsym);
	    mods[i].nextdefsym  = OSSwapInt32(mods[i].nextdefsym);
	    mods[i].irefsym     = OSSwapInt32(mods[i].irefsym);
	    mods[i].nrefsym     = OSSwapInt32(mods[i].nrefsym);
	    mods[i].ilocalsym   = OSSwapInt32(mods[i].ilocalsym);
	    mods[i].nlocalsym   = OSSwapInt32(mods[i].nlocalsym);
	    mods[i].iextrel     = OSSwapInt32(mods[i].iextrel);
	    mods[i].nextrel     = OSSwapInt32(mods[i].nextrel);
	    mods[i].iinit_iterm = OSSwapInt32(mods[i].iinit_iterm);
	    mods[i].ninit_nterm = OSSwapInt32(mods[i].ninit_nterm);
	    mods[i].objc_module_info_size = OSSwapInt32(mods[i].objc_module_info_size);
	    mods[i].objc_module_info_addr = OSSwapInt64(mods[i].objc_module_info_addr);
	}
}
Exemple #11
0
void
swap_i860_thread_state_regs(
struct i860_thread_state_regs *cpu,
enum NXByteOrder target_byte_sex)
{
    int i;

	for(i = 0; i < 31; i++)
	    cpu->ireg[i] = OSSwapInt32(cpu->ireg[i]);
	for(i = 0; i < 30; i++)
	    cpu->freg[i] = OSSwapInt32(cpu->freg[i]);
	cpu->psr = OSSwapInt32(cpu->psr);
	cpu->epsr = OSSwapInt32(cpu->epsr);
	cpu->db = OSSwapInt32(cpu->db);
	cpu->pc = OSSwapInt32(cpu->pc);
	cpu->_padding_ = OSSwapInt32(cpu->_padding_);
	cpu->Mres3 = OSSwapInt64(cpu->Mres3);
	cpu->Ares3 = OSSwapInt64(cpu->Ares3);
	cpu->Mres2 = OSSwapInt64(cpu->Mres2);
	cpu->Ares2 = OSSwapInt64(cpu->Ares2);
	cpu->Mres1 = OSSwapInt64(cpu->Mres1);
	cpu->Ares1 = OSSwapInt64(cpu->Ares1);
	cpu->Ires1 = OSSwapInt64(cpu->Ires1);
	cpu->Lres3m = OSSwapInt64(cpu->Lres3m);
	cpu->Lres2m = OSSwapInt64(cpu->Lres2m);
	cpu->Lres1m = OSSwapInt64(cpu->Lres1m);
	cpu->KR = OSSwapInt64(cpu->KR);
	cpu->KI = OSSwapInt64(cpu->KI);
	cpu->T = OSSwapInt64(cpu->T);
	cpu->Fsr3 = OSSwapInt32(cpu->Fsr3);
	cpu->Fsr2 = OSSwapInt32(cpu->Fsr2);
	cpu->Fsr1 = OSSwapInt32(cpu->Fsr1);
	cpu->Mergelo32 = OSSwapInt32(cpu->Mergelo32);
	cpu->Mergehi32 = OSSwapInt32(cpu->Mergehi32);
}
IOReturn SamplePCIUserClientClassName::method2( SampleStructForMethod2 * structIn,
        SampleResultsForMethod2 * structOut,
        IOByteCount inputSize, IOByteCount * outputSize )

{
    IOReturn err;
    IOMemoryDescriptor * memDesc = 0;
    UInt32 param1 = structIn->parameter1;

    uint64_t clientAddr = structIn->data_pointer;
    uint64_t size = structIn->data_length;

    // Rosetta
    if (fCrossEndian) {
        param1 = OSSwapInt32(param1);
    }

    IOLog("SamplePCIUserClient::method2(" UInt32_x_FORMAT ")\n", param1);
    IOLog( "fClientShared->string == \"%s\"\n", fClientShared->string );

    structOut->results1 = 0x87654321;
    // Rosetta
    if (fCrossEndian) {
        structOut->results1 = OSSwapInt64(structOut->results1);
        clientAddr = OSSwapInt64(clientAddr);
        size = OSSwapInt64(size);
    }

    do
    {

#if defined(__ppc__) && (MAC_OS_X_VERSION_MIN_REQUIRED <= MAC_OS_X_VERSION_10_4)
        // construct a memory descriptor for the out of line client memory
        // old 32 bit API - this will fail and log a backtrace if the task is 64 bit
        IOLog("The Pre-Leopard way to construct a memory descriptor\n");
        memDesc = IOMemoryDescriptor::withAddress( (vm_address_t) clientAddr, (IOByteCount) size, kIODirectionNone, fTask );
        if (memDesc == NULL) {
            IOLog("IOMemoryDescriptor::withAddress failed\n");
            err = kIOReturnVMError;
            continue;
        }
#else
        // 64 bit API - works on all tasks, whether 64 bit or 32 bit
        IOLog("The Leopard and later way to construct a memory descriptor\n");
        memDesc = IOMemoryDescriptor::withAddressRange( clientAddr, size, kIODirectionNone, fTask );
        if (memDesc == NULL) {
            IOLog("IOMemoryDescriptor::withAddresswithAddressRange failed\n");
            err = kIOReturnVMError;
            continue;
        }
#endif
        // Wire it and make sure we can write it
        err = memDesc->prepare( kIODirectionOutIn );
        if (kIOReturnSuccess != err) {
            IOLog("IOMemoryDescriptor::prepare failed(0x%08x)\n", err);
            continue;
        }

        // Generate a DMA list for the client memory
        err = fDriver->generateDMAAddresses(memDesc);

        // Other methods to access client memory:

        // readBytes/writeBytes allow programmed I/O to/from an offset in the buffer
        char pioBuffer[ 200 ];
        memDesc->readBytes(32, &pioBuffer, sizeof(pioBuffer));
        IOLog("readBytes: \"%s\"\n", pioBuffer);

        // map() will create a mapping in the kernel address space.
        IOMemoryMap* memMap = memDesc->map();
        if (memMap) {
            char* address = (char *) memMap->getVirtualAddress();
            IOLog("kernel mapped: \"%s\"\n", address + 32);
            memMap->release();
        } else {
            IOLog("memDesc map(kernel) failed\n");
        }

        // this map() will create a mapping in the users (the client of this IOUserClient) address space.
#if MAC_OS_X_VERSION_MIN_REQUIRED <= MAC_OS_X_VERSION_10_4
        memMap = memDesc->map(fTask, 0, kIOMapAnywhere);
#else
        memMap = memDesc->createMappingInTask(fTask, 0, kIOMapAnywhere);
#endif
        if (memMap) {
#if MAC_OS_X_VERSION_MIN_REQUIRED <= MAC_OS_X_VERSION_10_4
            IOLog("The pre-Leopard way to construct a memory descriptor\n");
            // old 32 bit API - this will truncate and log a backtrace if the task is 64 bit
            IOVirtualAddress address32 = memMap->getVirtualAddress();
            IOLog("user32 mapped: " VirtAddr_FORMAT "\n", address32);
#else
            IOLog("The Leopard and later way to construct a memory descriptor\n");
            // new 64 bit API - same for 32 bit and 64 bit client tasks
            mach_vm_address_t address64 = memMap->getAddress();
            IOLog("user64 mapped: 0x%016llx\n", address64);
            memMap->release();
#endif
        } else {
            IOLog("memDesc map(user) failed\n");
        }

        // Done with the I/O now.
        memDesc->complete( kIODirectionOutIn );

    } while ( false );

    if (memDesc)
        memDesc->release();

    return err;
}
    mach_error_t
mach_override_ptr(
	void *originalFunctionAddress,
    const void *overrideFunctionAddress,
    void **originalFunctionReentryIsland )
{
	assert( originalFunctionAddress );
	assert( overrideFunctionAddress );
	
	long	*originalFunctionPtr = (long*) originalFunctionAddress;
	mach_error_t	err = err_none;
	
#if defined(__ppc__) || defined(__POWERPC__)
	//	Ensure first instruction isn't 'mfctr'.
	#define	kMFCTRMask			0xfc1fffff
	#define	kMFCTRInstruction	0x7c0903a6
	
	long	originalInstruction = *originalFunctionPtr;
	if( !err && ((originalInstruction & kMFCTRMask) == kMFCTRInstruction) )
		err = err_cannot_override;
#elif defined(__i386__) || defined(__x86_64__)
	int eatenCount = 0;
	char originalInstructions[kOriginalInstructionsSize];
	uint64_t jumpRelativeInstruction = 0; // JMP

	Boolean overridePossible = eatKnownInstructions ((unsigned char *)originalFunctionPtr, 
										&jumpRelativeInstruction, &eatenCount, originalInstructions);
	if (eatenCount > kOriginalInstructionsSize) {
		//printf ("Too many instructions eaten\n");
		overridePossible = false;
	}
	if (!overridePossible) err = err_cannot_override;
	if (err) printf("err = %x %d\n", err, __LINE__);
#endif
	
	//	Make the original function implementation writable.
	if( !err ) {
		err = vm_protect( mach_task_self(),
				(vm_address_t) originalFunctionPtr,
				sizeof(long), false, (VM_PROT_ALL | VM_PROT_COPY) );
		if( err )
			err = vm_protect( mach_task_self(),
					(vm_address_t) originalFunctionPtr, sizeof(long), false,
					(VM_PROT_DEFAULT | VM_PROT_COPY) );
	}
	if (err) printf("err = %x %d\n", err, __LINE__);
	
	//	Allocate and target the escape island to the overriding function.
	BranchIsland	*escapeIsland = NULL;
	if( !err )	
		err = allocateBranchIsland( &escapeIsland, kAllocateHigh, originalFunctionAddress );
		if (err) printf("err = %x %d\n", err, __LINE__);

	
#if defined(__ppc__) || defined(__POWERPC__)
	if( !err )
		err = setBranchIslandTarget( escapeIsland, overrideFunctionAddress, 0 );
	
	//	Build the branch absolute instruction to the escape island.
	long	branchAbsoluteInstruction = 0; // Set to 0 just to silence warning.
	if( !err ) {
		long escapeIslandAddress = ((long) escapeIsland) & 0x3FFFFFF;
		branchAbsoluteInstruction = 0x48000002 | escapeIslandAddress;
	}
#elif defined(__i386__) || defined(__x86_64__)
        if (err) printf("err = %x %d\n", err, __LINE__);

	if( !err )
		err = setBranchIslandTarget_i386( escapeIsland, overrideFunctionAddress, 0 );
 
	if (err) printf("err = %x %d\n", err, __LINE__);
	// Build the jump relative instruction to the escape island
#endif


#if defined(__i386__) || defined(__x86_64__)
	if (!err) {
		uint32_t addressOffset = ((void*)escapeIsland - (void*)originalFunctionPtr - 5);
		addressOffset = OSSwapInt32(addressOffset);
		
		jumpRelativeInstruction |= 0xE900000000000000LL; 
		jumpRelativeInstruction |= ((uint64_t)addressOffset & 0xffffffff) << 24;
		jumpRelativeInstruction = OSSwapInt64(jumpRelativeInstruction);		
	}
#endif
	
	//	Optionally allocate & return the reentry island.
	BranchIsland	*reentryIsland = NULL;
	if( !err && originalFunctionReentryIsland ) {
		err = allocateBranchIsland( &reentryIsland, kAllocateNormal, NULL);
		if( !err )
			*originalFunctionReentryIsland = reentryIsland;
	}
	
#if defined(__ppc__) || defined(__POWERPC__)	
	//	Atomically:
	//	o If the reentry island was allocated:
	//		o Insert the original instruction into the reentry island.
	//		o Target the reentry island at the 2nd instruction of the
	//		  original function.
	//	o Replace the original instruction with the branch absolute.
	if( !err ) {
		int escapeIslandEngaged = false;
		do {
			if( reentryIsland )
				err = setBranchIslandTarget( reentryIsland,
						(void*) (originalFunctionPtr+1), originalInstruction );
			if( !err ) {
				escapeIslandEngaged = CompareAndSwap( originalInstruction,
										branchAbsoluteInstruction,
										(UInt32*)originalFunctionPtr );
				if( !escapeIslandEngaged ) {
					//	Someone replaced the instruction out from under us,
					//	re-read the instruction, make sure it's still not
					//	'mfctr' and try again.
					originalInstruction = *originalFunctionPtr;
					if( (originalInstruction & kMFCTRMask) == kMFCTRInstruction)
						err = err_cannot_override;
				}
			}
		} while( !err && !escapeIslandEngaged );
	}
#elif defined(__i386__) || defined(__x86_64__)
	// Atomically:
	//	o If the reentry island was allocated:
	//		o Insert the original instructions into the reentry island.
	//		o Target the reentry island at the first non-replaced 
	//        instruction of the original function.
	//	o Replace the original first instructions with the jump relative.
	//
	// Note that on i386, we do not support someone else changing the code under our feet
	if ( !err ) {
		if( reentryIsland )
			err = setBranchIslandTarget_i386( reentryIsland,
										 (void*) ((char *)originalFunctionPtr+eatenCount), originalInstructions );
		if ( !err )
			atomic_mov64((uint64_t *)originalFunctionPtr, jumpRelativeInstruction);
	}
#endif
	
	//	Clean up on error.
	if( err ) {
		if( reentryIsland )
			freeBranchIsland( reentryIsland );
		if( escapeIsland )
			freeBranchIsland( escapeIsland );
	}

#if defined(__x86_64__)
        err = makeIslandExecutable(escapeIsland);
        err = makeIslandExecutable(reentryIsland);
#endif
	
	return err;
}
uint64_t AJ_ByteSwap64(uint64_t x)
{
    return OSSwapInt64(x);
}
Exemple #15
0
void
swap_x86_thread_state64(
x86_thread_state64_t *cpu,
enum NXByteOrder target_byte_sex)
{
	cpu->rax = OSSwapInt64(cpu->rax);
	cpu->rbx = OSSwapInt64(cpu->rbx);
	cpu->rcx = OSSwapInt64(cpu->rcx);
	cpu->rdx = OSSwapInt64(cpu->rdx);
	cpu->rdi = OSSwapInt64(cpu->rdi);
	cpu->rsi = OSSwapInt64(cpu->rsi);
	cpu->rbp = OSSwapInt64(cpu->rbp);
	cpu->rsp = OSSwapInt64(cpu->rsp);
	cpu->rflags = OSSwapInt64(cpu->rflags);
	cpu->rip = OSSwapInt64(cpu->rip);
	cpu->r8 = OSSwapInt64(cpu->r8);
	cpu->r9 = OSSwapInt64(cpu->r9);
	cpu->r10 = OSSwapInt64(cpu->r10);
	cpu->r11 = OSSwapInt64(cpu->r11);
	cpu->r12 = OSSwapInt64(cpu->r12);
	cpu->r13 = OSSwapInt64(cpu->r13);
	cpu->r14 = OSSwapInt64(cpu->r14);
	cpu->r15 = OSSwapInt64(cpu->r15);
	cpu->cs = OSSwapInt64(cpu->cs);
	cpu->fs = OSSwapInt64(cpu->fs);
	cpu->gs = OSSwapInt64(cpu->gs);
}
    mach_error_t
__asan_mach_override_ptr_custom(
	void *originalFunctionAddress,
    const void *overrideFunctionAddress,
    void **originalFunctionReentryIsland,
		island_malloc *alloc,
		island_free *dealloc)
{
	assert( originalFunctionAddress );
	assert( overrideFunctionAddress );
	
	// this addresses overriding such functions as AudioOutputUnitStart()
	// test with modified DefaultOutputUnit project
#if defined(__x86_64__)
    for(;;){
        if(*(uint16_t*)originalFunctionAddress==0x25FF)    // jmp qword near [rip+0x????????]
            originalFunctionAddress=*(void**)((char*)originalFunctionAddress+6+*(int32_t *)((uint16_t*)originalFunctionAddress+1));
        else break;
    }
#elif defined(__i386__)
    for(;;){
        if(*(uint16_t*)originalFunctionAddress==0x25FF)    // jmp *0x????????
            originalFunctionAddress=**(void***)((uint16_t*)originalFunctionAddress+1);
        else break;
    }
#endif
#ifdef DEBUG_DISASM
  {
    fprintf(stderr, "Replacing function at %p\n", originalFunctionAddress);
    fprintf(stderr, "First 16 bytes of the function: ");
    unsigned char *orig = (unsigned char *)originalFunctionAddress;
    int i;
    for (i = 0; i < 16; i++) {
       fprintf(stderr, "%x ", (unsigned int) orig[i]);
    }
    fprintf(stderr, "\n");
    fprintf(stderr, 
            "To disassemble, save the following function as disas.c"
            " and run:\n  gcc -c disas.c && gobjdump -d disas.o\n"
            "The first 16 bytes of the original function will start"
            " after four nop instructions.\n");
    fprintf(stderr, "\nvoid foo() {\n  asm volatile(\"nop;nop;nop;nop;\");\n");
    int j = 0;
    for (j = 0; j < 2; j++) {
      fprintf(stderr, "  asm volatile(\".byte ");
      for (i = 8 * j; i < 8 * (j+1) - 1; i++) {
        fprintf(stderr, "0x%x, ", (unsigned int) orig[i]);
      }
      fprintf(stderr, "0x%x;\");\n", (unsigned int) orig[8 * (j+1) - 1]);
    }
    fprintf(stderr, "}\n\n");
  }
#endif

	long	*originalFunctionPtr = (long*) originalFunctionAddress;
	mach_error_t	err = err_none;
	
#if defined(__ppc__) || defined(__POWERPC__)
	//	Ensure first instruction isn't 'mfctr'.
	#define	kMFCTRMask			0xfc1fffff
	#define	kMFCTRInstruction	0x7c0903a6
	
	long	originalInstruction = *originalFunctionPtr;
	if( !err && ((originalInstruction & kMFCTRMask) == kMFCTRInstruction) )
		err = err_cannot_override;
#elif defined(__i386__) || defined(__x86_64__)
	int eatenCount = 0;
	int originalInstructionCount = 0;
	char originalInstructions[kOriginalInstructionsSize];
	uint8_t originalInstructionSizes[kOriginalInstructionsSize];
	uint64_t jumpRelativeInstruction = 0; // JMP

	Boolean overridePossible = eatKnownInstructions ((unsigned char *)originalFunctionPtr, 
										&jumpRelativeInstruction, &eatenCount, 
										originalInstructions, &originalInstructionCount, 
										originalInstructionSizes );
#ifdef DEBUG_DISASM
  if (!overridePossible) fprintf(stderr, "overridePossible = false @%d\n", __LINE__);
#endif
	if (eatenCount > kOriginalInstructionsSize) {
#ifdef DEBUG_DISASM
		fprintf(stderr, "Too many instructions eaten\n");
#endif    
		overridePossible = false;
	}
	if (!overridePossible) err = err_cannot_override;
	if (err) fprintf(stderr, "err = %x %s:%d\n", err, __FILE__, __LINE__);
#endif
	
	//	Make the original function implementation writable.
	if( !err ) {
		err = vm_protect( mach_task_self(),
				(vm_address_t) originalFunctionPtr, 8, false,
				(VM_PROT_ALL | VM_PROT_COPY) );
		if( err )
			err = vm_protect( mach_task_self(),
					(vm_address_t) originalFunctionPtr, 8, false,
					(VM_PROT_DEFAULT | VM_PROT_COPY) );
	}
	if (err) fprintf(stderr, "err = %x %s:%d\n", err, __FILE__, __LINE__);
	
	//	Allocate and target the escape island to the overriding function.
	BranchIsland	*escapeIsland = NULL;
	if( !err )
		err = alloc( (void**)&escapeIsland, sizeof(BranchIsland), originalFunctionAddress );
	if ( err ) fprintf(stderr, "err = %x %s:%d\n", err, __FILE__, __LINE__);
	
#if defined(__ppc__) || defined(__POWERPC__)
	if( !err )
		err = setBranchIslandTarget( escapeIsland, overrideFunctionAddress, 0 );
	
	//	Build the branch absolute instruction to the escape island.
	long	branchAbsoluteInstruction = 0; // Set to 0 just to silence warning.
	if( !err ) {
		long escapeIslandAddress = ((long) escapeIsland) & 0x3FFFFFF;
		branchAbsoluteInstruction = 0x48000002 | escapeIslandAddress;
	}
#elif defined(__i386__) || defined(__x86_64__)
        if (err) fprintf(stderr, "err = %x %s:%d\n", err, __FILE__, __LINE__);

	if( !err )
		err = setBranchIslandTarget_i386( escapeIsland, overrideFunctionAddress, 0 );
 
	if (err) fprintf(stderr, "err = %x %s:%d\n", err, __FILE__, __LINE__);
	// Build the jump relative instruction to the escape island
#endif


#if defined(__i386__) || defined(__x86_64__)
	if (!err) {
		uint32_t addressOffset = ((char*)escapeIsland - (char*)originalFunctionPtr - 5);
		addressOffset = OSSwapInt32(addressOffset);
		
		jumpRelativeInstruction |= 0xE900000000000000LL; 
		jumpRelativeInstruction |= ((uint64_t)addressOffset & 0xffffffff) << 24;
		jumpRelativeInstruction = OSSwapInt64(jumpRelativeInstruction);		
	}
#endif
	
	//	Optionally allocate & return the reentry island. This may contain relocated
	//  jmp instructions and so has all the same addressing reachability requirements
	//  the escape island has to the original function, except the escape island is
	//  technically our original function.
	BranchIsland	*reentryIsland = NULL;
	if( !err && originalFunctionReentryIsland ) {
		err = alloc( (void**)&reentryIsland, sizeof(BranchIsland), escapeIsland);
		if( !err )
			*originalFunctionReentryIsland = reentryIsland;
	}
	
#if defined(__ppc__) || defined(__POWERPC__)	
	//	Atomically:
	//	o If the reentry island was allocated:
	//		o Insert the original instruction into the reentry island.
	//		o Target the reentry island at the 2nd instruction of the
	//		  original function.
	//	o Replace the original instruction with the branch absolute.
	if( !err ) {
		int escapeIslandEngaged = false;
		do {
			if( reentryIsland )
				err = setBranchIslandTarget( reentryIsland,
						(void*) (originalFunctionPtr+1), originalInstruction );
			if( !err ) {
				escapeIslandEngaged = CompareAndSwap( originalInstruction,
										branchAbsoluteInstruction,
										(UInt32*)originalFunctionPtr );
				if( !escapeIslandEngaged ) {
					//	Someone replaced the instruction out from under us,
					//	re-read the instruction, make sure it's still not
					//	'mfctr' and try again.
					originalInstruction = *originalFunctionPtr;
					if( (originalInstruction & kMFCTRMask) == kMFCTRInstruction)
						err = err_cannot_override;
				}
			}
		} while( !err && !escapeIslandEngaged );
	}
#elif defined(__i386__) || defined(__x86_64__)
	// Atomically:
	//	o If the reentry island was allocated:
	//		o Insert the original instructions into the reentry island.
	//		o Target the reentry island at the first non-replaced 
	//        instruction of the original function.
	//	o Replace the original first instructions with the jump relative.
	//
	// Note that on i386, we do not support someone else changing the code under our feet
	if ( !err ) {
		fixupInstructions(originalFunctionPtr, reentryIsland, originalInstructions,
					originalInstructionCount, originalInstructionSizes );
	
		if( reentryIsland )
			err = setBranchIslandTarget_i386( reentryIsland,
										 (void*) ((char *)originalFunctionPtr+eatenCount), originalInstructions );
		// try making islands executable before planting the jmp
#if defined(__x86_64__) || defined(__i386__)
        if( !err )
            err = makeIslandExecutable(escapeIsland);
        if( !err && reentryIsland )
            err = makeIslandExecutable(reentryIsland);
#endif
		if ( !err )
			atomic_mov64((uint64_t *)originalFunctionPtr, jumpRelativeInstruction);
	}
#endif
	
	//	Clean up on error.
	if( err ) {
		if( reentryIsland )
			dealloc( reentryIsland );
		if( escapeIsland )
			dealloc( escapeIsland );
	}

#ifdef DEBUG_DISASM
  {
    fprintf(stderr, "First 16 bytes of the function after slicing: ");
    unsigned char *orig = (unsigned char *)originalFunctionAddress;
    int i;
    for (i = 0; i < 16; i++) {
       fprintf(stderr, "%x ", (unsigned int) orig[i]);
    }
    fprintf(stderr, "\n");
  }
#endif
	return err;
}
IOReturn
AppleUHCIIsochTransferDescriptor::UpdateFrameList(AbsoluteTime timeStamp)
{
    UInt32						statFlags;
    IOUSBIsocFrame 				*pFrames;    
    IOUSBLowLatencyIsocFrame 	*pLLFrames;    
    IOReturn					frStatus = kIOReturnSuccess;
    UInt16						frActualCount = 0;
    UInt16						frReqCount;
    
    statFlags = USBToHostLong(GetSharedLogical()->ctrlStatus);
	frActualCount = UHCI_TD_GET_ACTLEN(statFlags);
    // warning - this method can run at primary interrupt time, which can cause a panic if it logs too much
    // USBLog(7, "AppleUHCIIsochTransferDescriptor[%p]::UpdateFrameList statFlags (%x)", this, statFlags);
    pFrames = _pFrames;
	if (!pFrames)							// this will be the case for the dummy TD
		return kIOReturnSuccess;
	
    pLLFrames = (IOUSBLowLatencyIsocFrame*)_pFrames;
    if (_lowLatency)
    {
		frReqCount = pLLFrames[_frameIndex].frReqCount;
    }
    else
    {
		frReqCount = pFrames[_frameIndex].frReqCount;
    }
	
    if (statFlags & kUHCI_TD_ACTIVE)
    {
		frStatus = kIOUSBNotSent2Err;
    }
    else if (statFlags & kUHCI_TD_CRCTO)
    {
		frStatus = kIOReturnNotResponding;
    }
    else if (statFlags & kUHCI_TD_DBUF)									// data buffer (PCI error)
    {
		if (_pEndpoint->direction == kUSBOut)
			frStatus = kIOUSBBufferUnderrunErr;
		else
			frStatus = kIOUSBBufferOverrunErr;
    }
    else if (statFlags & kUHCI_TD_BABBLE)
    {
		if (_pEndpoint->direction == kUSBOut)
			frStatus = kIOReturnNotResponding;							// babble on OUT. this should never happen
		else
			frStatus = kIOReturnOverrun;
    }
    else if (statFlags & kUHCI_TD_STALLED)								// if STALL happens on Isoch, it is most likely covered by one of the other bits above
    {
		frStatus = kIOUSBWrongPIDErr;
    }
    else
    {
		if (frActualCount != frReqCount)
		{
			if (_pEndpoint->direction == kUSBOut)
			{
				// warning - this method can run at primary interrupt time, which can cause a panic if it logs too much
				// USBLog(7, "AppleUHCIIsochTransferDescriptor[%p]::UpdateFrameList - (OUT) reqCount (%d) actCount (%d)", this, frReqCount, frActualCount);
				frStatus = kIOUSBBufferUnderrunErr;						// this better have generated a DBUF or other error
			}
			else if (_pEndpoint->direction == kUSBIn)
			{
				// warning - this method can run at primary interrupt time, which can cause a panic if it logs too much
				// USBLog(7, "AppleUHCIIsochTransferDescriptor[%p]::UpdateFrameList - (IN) reqCount (%d) actCount (%d)", this, frReqCount, frActualCount);
				frStatus = kIOReturnUnderrun;							// benign error
			}
		}
    }

    if (alignBuffer && alignBuffer->userBuffer && alignBuffer->vaddr && (_pEndpoint->direction == kUSBIn))
	{
		// i can't log in here because this is called at interrupt time
		// i know that this is OK for Low Latency because the buffer will be allocated in low memory and wont' be bounced
		alignBuffer->userBuffer->writeBytes(alignBuffer->userOffset, (void*)alignBuffer->vaddr, frActualCount);
		alignBuffer->actCount = frActualCount;
	}
	
	
	if (_lowLatency)
    {
		if ( _requestFromRosettaClient )
		{
			pLLFrames[_frameIndex].frActCount = OSSwapInt16(frActualCount);
			pLLFrames[_frameIndex].frReqCount = OSSwapInt16(pLLFrames[_frameIndex].frReqCount);
			AbsoluteTime_to_scalar(&pLLFrames[_frameIndex].frTimeStamp) 
			= OSSwapInt64(AbsoluteTime_to_scalar(&timeStamp));
			pLLFrames[_frameIndex].frStatus = OSSwapInt32(frStatus);
		}
		else
		{
			pLLFrames[_frameIndex].frActCount = frActualCount;
			pLLFrames[_frameIndex].frTimeStamp = timeStamp;
			pLLFrames[_frameIndex].frStatus = frStatus;

#ifdef __LP64__
			USBTrace( kUSBTUHCIInterrupts, kTPUHCIUpdateFrameList , (uintptr_t)((_pEndpoint->direction << 24) | ( _pEndpoint->functionAddress << 8) | _pEndpoint->endpointNumber), (uintptr_t)&pLLFrames[_frameIndex], (uintptr_t)frActualCount, (uintptr_t)timeStamp );
#else
			USBTrace( kUSBTUHCIInterrupts, kTPUHCIUpdateFrameList , (uintptr_t)((_pEndpoint->direction << 24) | ( _pEndpoint->functionAddress << 8) | _pEndpoint->endpointNumber), (uintptr_t)&pLLFrames[_frameIndex], (uintptr_t)(timeStamp.hi), (uintptr_t)timeStamp.lo );
#endif
		}
    }
    else
    {
		if ( _requestFromRosettaClient )
		{
			pFrames[_frameIndex].frActCount = OSSwapInt16(frActualCount);
			pFrames[_frameIndex].frReqCount = OSSwapInt16(pFrames[_frameIndex].frReqCount);
			pFrames[_frameIndex].frStatus = OSSwapInt32(frStatus);
		}
		else
		{
			pFrames[_frameIndex].frActCount = frActualCount;
			pFrames[_frameIndex].frStatus = frStatus;
		}
    }
	
    if (frStatus != kIOReturnSuccess)
    {
		if (frStatus != kIOReturnUnderrun)
		{
			_pEndpoint->accumulatedStatus = frStatus;
		}
		else if (_pEndpoint->accumulatedStatus == kIOReturnSuccess)
		{
			_pEndpoint->accumulatedStatus = kIOReturnUnderrun;
		}
    }
    return frStatus;
}
Exemple #18
0
    mach_error_t
mach_override_ptr(
	void *originalFunctionAddress,
    const void *overrideFunctionAddress,
    void **originalFunctionReentryIsland )
{
	assert( originalFunctionAddress );
	assert( overrideFunctionAddress );
	
	// this addresses overriding such functions as AudioOutputUnitStart()
	// test with modified DefaultOutputUnit project
#if defined(__x86_64__)
    for(;;){
        if(*(uint16_t*)originalFunctionAddress==0x25FF)    // jmp qword near [rip+0x????????]
            originalFunctionAddress=*(void**)((char*)originalFunctionAddress+6+*(int32_t *)((uint16_t*)originalFunctionAddress+1));
        else break;
    }
#elif defined(__i386__)
    for(;;){
        if(*(uint16_t*)originalFunctionAddress==0x25FF)    // jmp *0x????????
            originalFunctionAddress=**(void***)((uint16_t*)originalFunctionAddress+1);
        else break;
    }
#endif

	long	*originalFunctionPtr = (long*) originalFunctionAddress;
	mach_error_t	err = err_none;
	
#if defined(__ppc__) || defined(__POWERPC__)
	//	Ensure first instruction isn't 'mfctr'.
	#define	kMFCTRMask			0xfc1fffff
	#define	kMFCTRInstruction	0x7c0903a6
	
	long	originalInstruction = *originalFunctionPtr;
	if( !err && ((originalInstruction & kMFCTRMask) == kMFCTRInstruction) )
		err = err_cannot_override;
#elif defined(__i386__) || defined(__x86_64__)
	int eatenCount = 0;
	int originalInstructionCount = 0;
	char originalInstructions[kOriginalInstructionsSize];
	uint8_t originalInstructionSizes[kOriginalInstructionsSize];
	uint64_t jumpRelativeInstruction = 0; // JMP

	Boolean overridePossible = eatKnownInstructions ((unsigned char *)originalFunctionPtr, 
										&jumpRelativeInstruction, &eatenCount, 
										originalInstructions, &originalInstructionCount, 
										originalInstructionSizes );
	if (eatenCount + kMaxFixupSizeIncrease > kOriginalInstructionsSize) {
		//printf ("Too many instructions eaten\n");
		overridePossible = false;
	}
	if (!overridePossible) err = err_cannot_override;
	if (err) fprintf(stderr, "err = %x %s:%d\n", err, __FILE__, __LINE__);
#endif
	
	//	Make the original function implementation writable.
	if( !err ) {
		err = vm_protect( mach_task_self(),
				(vm_address_t) originalFunctionPtr, 8, false,
				(VM_PROT_ALL | VM_PROT_COPY) );
		if( err )
			err = vm_protect( mach_task_self(),
					(vm_address_t) originalFunctionPtr, 8, false,
					(VM_PROT_DEFAULT | VM_PROT_COPY) );
	}
	if (err) fprintf(stderr, "err = %x %s:%d\n", err, __FILE__, __LINE__);
	
	//	Allocate and target the escape island to the overriding function.
	BranchIsland	*escapeIsland = NULL;
	if( !err )	
		err = allocateBranchIsland( &escapeIsland, originalFunctionAddress );
		if (err) fprintf(stderr, "err = %x %s:%d\n", err, __FILE__, __LINE__);

	
#if defined(__ppc__) || defined(__POWERPC__)
	if( !err )
		err = setBranchIslandTarget( escapeIsland, overrideFunctionAddress, 0 );
	
	//	Build the branch absolute instruction to the escape island.
	long	branchAbsoluteInstruction = 0; // Set to 0 just to silence warning.
	if( !err ) {
		long escapeIslandAddress = ((long) escapeIsland) & 0x3FFFFFF;
		branchAbsoluteInstruction = 0x48000002 | escapeIslandAddress;
	}
#elif defined(__i386__) || defined(__x86_64__)
        if (err) fprintf(stderr, "err = %x %s:%d\n", err, __FILE__, __LINE__);

	if( !err )
		err = setBranchIslandTarget_i386( escapeIsland, overrideFunctionAddress, 0 );
 
	if (err) fprintf(stderr, "err = %x %s:%d\n", err, __FILE__, __LINE__);
	// Build the jump relative instruction to the escape island
#endif


#if defined(__i386__) || defined(__x86_64__)
	if (!err) {
		uint32_t addressOffset = ((char*)escapeIsland - (char*)originalFunctionPtr - 5);
		addressOffset = OSSwapInt32(addressOffset);
		
		jumpRelativeInstruction |= 0xE900000000000000LL; 
		jumpRelativeInstruction |= ((uint64_t)addressOffset & 0xffffffff) << 24;
		jumpRelativeInstruction = OSSwapInt64(jumpRelativeInstruction);		
	}
#endif
	
	//	Optionally allocate & return the reentry island. This may contain relocated
	//  jmp instructions and so has all the same addressing reachability requirements
	//  the escape island has to the original function, except the escape island is
	//  technically our original function.
	BranchIsland	*reentryIsland = NULL;
	if( !err && originalFunctionReentryIsland ) {
		err = allocateBranchIsland( &reentryIsland, escapeIsland);
		if( !err )
			*originalFunctionReentryIsland = reentryIsland;
	}
	
#if defined(__ppc__) || defined(__POWERPC__)	
	//	Atomically:
	//	o If the reentry island was allocated:
	//		o Insert the original instruction into the reentry island.
	//		o Target the reentry island at the 2nd instruction of the
	//		  original function.
	//	o Replace the original instruction with the branch absolute.
	if( !err ) {
		int escapeIslandEngaged = false;
		do {
			if( reentryIsland )
				err = setBranchIslandTarget( reentryIsland,
						(void*) (originalFunctionPtr+1), originalInstruction );
			if( !err ) {
				escapeIslandEngaged = CompareAndSwap( originalInstruction,
										branchAbsoluteInstruction,
										(UInt32*)originalFunctionPtr );
				if( !escapeIslandEngaged ) {
					//	Someone replaced the instruction out from under us,
					//	re-read the instruction, make sure it's still not
					//	'mfctr' and try again.
					originalInstruction = *originalFunctionPtr;
					if( (originalInstruction & kMFCTRMask) == kMFCTRInstruction)
						err = err_cannot_override;
				}
			}
		} while( !err && !escapeIslandEngaged );
	}
#elif defined(__i386__) || defined(__x86_64__)
	// Atomically:
	//	o If the reentry island was allocated:
	//		o Insert the original instructions into the reentry island.
	//		o Target the reentry island at the first non-replaced 
	//        instruction of the original function.
	//	o Replace the original first instructions with the jump relative.
	//
	// Note that on i386, we do not support someone else changing the code under our feet
	if ( !err ) {
		uint32_t offset = (uintptr_t)originalFunctionPtr - (uintptr_t)reentryIsland;
		fixupInstructions(offset, originalInstructions,
					originalInstructionCount, originalInstructionSizes );
	
		if( reentryIsland )
			err = setBranchIslandTarget_i386( reentryIsland,
										 (void*) ((char *)originalFunctionPtr+eatenCount), originalInstructions );
		// try making islands executable before planting the jmp
#if defined(__x86_64__) || defined(__i386__)
        if( !err )
            err = makeIslandExecutable(escapeIsland);
        if( !err && reentryIsland )
            err = makeIslandExecutable(reentryIsland);
#endif
		if ( !err )
			atomic_mov64((uint64_t *)originalFunctionPtr, jumpRelativeInstruction);
	}
#endif
	
	//	Clean up on error.
	if( err ) {
		if( reentryIsland )
			freeBranchIsland( reentryIsland );
		if( escapeIsland )
			freeBranchIsland( escapeIsland );
	}

	return err;
}
Exemple #19
0
size_t
decompress_lzvn(void * _dest,
                size_t _dest_size,
                void * _src,
                size_t _src_size)
{
    size_t   rax = 0;
    
    const uint64_t rdi = (const uint64_t)_dest;
    uint64_t rsi       = _dest_size;
    uint64_t rcx       = _src_size;
    uint64_t rdx       = (uint64_t)_src;
    
    uint64_t r8  = 0;
    uint64_t r9  = 0;
    uint64_t r10 = 0;
    uint64_t r11 = 0;
    uint64_t r12 = 0;
    
    uint64_t addr           = 0;
    unsigned char byte_data = 0;
    
    short jmp = 0;
    
    // lea    Llzvn_tableref(%rip),%rbx
    //
    //    this will load the address of the tableref label into the %rbx
    //    register. in our code, this is the 'Llzvn_tableref' array
    //
    //  for clearness, it will be used directly.
    
    rax = 0;    // xor    %rax,%rax
    r12 = 0;    // xor    %r12,%r12
    
    // sub    $0x8,%rsi
    // jb     Llzvn_exit
    jmp = rsi < 0x8 ? 1 : 0;
    rsi -= 0x8;
    if (jmp) {
        return 0;
    }
    
    // lea    -0x8(%rdx,%rcx,1),%rcx
    // cmp    %rcx,%rdx
	// ja     Llzvn_exit
    rcx = rdx + rcx - 0x8;
    if (rdx > rcx) {
        return 0;
    }
    
    LABEL_JUMP;
    
    
    
Llzvn_table0:
    r9 >>= 0x6;           // shr    $0x6,%r9
    rdx = rdx + r9 + 0x1; // lea    0x1(%rdx,%r9,1),%rdx
    
    // cmp    %rcx,%rdx
    // ja     Llzvn_exit
    if (rdx > rcx) {
        return 0;
    }
    
    r10 = 0x38;     // mov    $0x38,%r10
    r10 &= r8;      // and    %r8,%r10
    r8 >>= 0x8;     // shr    $0x8,%r8
    r10 >>= 0x3;    // shr    $0x3,%r10
    r10 += 0x3;     // add    $0x3,%r10
    goto Llzvn_l10; // jmp    Llzvn_l10
    
Llzvn_table1:
    r9 >>= 0x6;            // shr    $0x6,%r9
    rdx = rdx + r9 + 0x2;  // lea    0x2(%rdx,%r9,1),%rdx
    
    // cmp    %rcx,%rdx
	// ja     Llzvn_exit
    if (rdx > rcx) {
        return 0;
    }
    
    r12 = r8;                // mov    %r8,%r12
    r12 = OSSwapInt64(r12);  // bswap  %r12
    r10 = r12;               // mov    %r12,%r10
    r12 <<= 0x5;             // shl    $0x5,%r12
    r12 >>= 0x35;            // shr    $0x35,%r12
    r10 <<= 0x2;             // shl    $0x2,%r10
    r10 >>= 0x3d;            // shr    $0x3d,%r10
    r10 += 0x3;              // add    $0x3,%r10
    r8  >>= 0x10;            // shr    $0x10,%r8
    goto Llzvn_l10;
    
    
Llzvn_table3:
    r9 >>= 0x6;           // shr    $0x6,%r9
    rdx = rdx + r9 + 0x3; // lea    0x3(%rdx,%r9,1),%rdx
    
    // cmp    %rcx,%rdx
    // ja     Llzvn_exit
    if (rdx > rcx) {
        return 0;
    }
    
    r10 = 0x38;     // mov    $0x38,%r10
    r12 = 0xFFFF;   // mov    $0xffff,%r12
    r10 &= r8;      // and    %r8,%r10
    r8 >>= 0x8;     // shr    $0x8,%r8
    r10 >>= 0x3;    // shr    $0x3,%r10
    r12 &= r8;      // and    %r8,%r12
    r8 >>= 0x10;    // shr    $0x10,%r8
    r10 += 0x3;     // add    $0x3,%r10
    goto Llzvn_l10; // jmp    Llzvn_l10
    
    
Llzvn_table4:
    // add    $0x1,%rdx
    // cmp    %rcx,%rdx
    // ja     Llzvn_exit
    rdx += 1;
    if (rdx > rcx) {
        return 0;
    }
    
    LABEL_JUMP;
    
    
Llzvn_table6:
    r9 >>= 0x3;           // shr    $0x3,%r9
    r9 &= 0x3;            // and    $0x3,%r9
    rdx = rdx + r9 + 0x3; // lea    0x3(%rdx,%r9,1),%rdx
    
    // cmp    %rcx,%rdx
    // ja     Llzvn_exit
    if (rdx > rcx) {
        return 0;
    }
    
    r10 = r8;       // mov    %r8,%r10
    r10 &= 0x307;   // and    $0x307,%r10
    r8 >>= 0xa;     // shr    $0xa,%r8
    
    // movzbq %r10b,%r12
    r12 = r10 & 0xFF;
    
    r10 >>= 0x8;    // shr    $0x8,%r10
    r12 <<= 0x2;    // shl    $0x2,%r12
    r10 |= r12;     // or     %r12,%r10
    r12 = 0x3FFF;   // mov    $0x3fff,%r12
    r10 += 0x3;     // add    $0x3,%r10
    r12 &= r8;      // and    %r8,%r12
    r8 >>= 0xE;     // shr    $0xe,%r8
    goto Llzvn_l10; // jmp    Llzvn_l10
    
    
Llzvn_table7:
    r8 >>= 0x8;           // shr    $0x8,%r8
    r8 &= 0xFF;           // and    $0xff,%r8
    r8 += 0x10;           // add    $0x10,%r8
    rdx = rdx + r8 + 0x2; // lea    0x2(%rdx,%r8,1),%rdx
    goto Llzvn_l0;
    
    
Llzvn_table8:
    r8 &= 0xF;            // and    $0xf,%r8
    rdx = rdx + r8 + 0x1; // lea    0x1(%rdx,%r8,1),%rdx
    goto Llzvn_l0;        // jmp    Llzvn_l0
    
    
Llzvn_table9:
    rdx += 0x2; // add    $0x2,%rdx
    
    // cmp    %rcx,%rdx
    // ja     Llzvn_exit
    if (rdx > rcx) {
        return 0;
    }
    
    r10 = r8;    // mov    %r8,%r10
    r10 >>= 0x8; // shr    $0x8,%r10
    r10 &= 0xFF; // and    $0xff,%r10
    r10 += 0x10; // add    $0x10,%r10
    goto Llzvn_l11;
    
    
Llzvn_table10:
    rdx += 1; // add    $0x1,%rdx
    
    //cmp    %rcx,%rdx
   	//ja     Llzvn_exit
    if (rdx > rcx) {
        return 0;
    }
    
    r10 = r8;       // mov    %r8,%r10
    r10 &= 0xF;     // and    $0xf,%r10
    goto Llzvn_l11; // jmp    Llzvn_l11
    
    
    
    
Llzvn_l10:
    r11 = rax + r9;   // lea    (%rax,%r9,1),%r11
    r11 += r10;       // add    %r10,%r11
    
    // cmp    %rsi,%r11
	// jae    Llzvn_l8
    if (r11 >= rsi) {
        goto Llzvn_l8;
    }
    
    // mov    %r8,(%rdi,%rax,1)
    addr = rdi + rax;
    *((uint64_t *)addr) = r8;
    
    rax += r9;  // add    %r9,%rax
    r8 = rax;   // mov    %rax,%r8
    
    // sub    %r12,%r8
	// jb     Llzvn_exit
    jmp = r8 < r12 ? 1 : 0;
    r8 -= r12;
    if (jmp) {
        return 0;
    }
    
    // cmp    $0x8,%r12
	// jb     Llzvn_l4
    if (r12 < 0x8) {
        goto Llzvn_l4;
    }
    
    
Llzvn_l5:
    do
    {
        // mov    (%rdi,%r8,1),%r9
        addr = rdi + r8;
        r9 = *((uint64_t *)addr);
        
        r8 += 0x8;      // add    $0x8,%r8
        
        // mov    %r9,(%rdi,%rax,1)
        addr = rdi + rax;
        *((uint64_t *)addr) = r9;
        
        rax += 0x8;     // add    $0x8,%rax
        
        // sub    $0x8,%r10
        // ja     Llzvn_l5
        jmp = r10 > 0x8 ? 1 : 0;
        r10 -= 0x8;
    }
    while (jmp);
    
    rax += r10;     // add    %r10,%rax
    
    LABEL_JUMP;
    
    
Llzvn_l8:
    // test   %r9,%r9
	// je     Llzvn_l7
    if (r9 != 0)
    {
        r11 = rsi + 0x8; // lea    0x8(%rsi),%r11
        
        do
        {
            // mov    %r8b,(%rdi,%rax,1)
            addr = rdi + rax;
            byte_data = (unsigned char)(r8 & 0xFF);
            *((unsigned char *)addr) = byte_data;
            
            rax += 0x1; // add    $0x1,%rax
            
            // cmp    %rax,%r11
            // je     Llzvn_exit2
            if (rax == r11) {
                return rax;
            }
            
            r8 >>= 0x8; // shr    $0x8,%r8
            
            // sub    $0x1,%r9
            // jne    Llzvn_l6
            jmp = r9 != 0x1 ? 1 : 0;
            r9 -= 1;
        }
        while (jmp);
    }