-
-// Find the "clean" entry point from a "dirty" entry point
-// by skipping past the call to verify_code
-static void *get_clean_addr(void *addr)
-{
- signed int *ptr = addr;
- #ifndef HAVE_ARMV7
- ptr+=4;
- #else
- ptr+=6;
- #endif
- if((*ptr&0xFF000000)!=0xeb000000) ptr++;
- assert((*ptr&0xFF000000)==0xeb000000); // bl instruction
- ptr++;
- if((*ptr&0xFF000000)==0xea000000) {
- return (char *)ptr+((*ptr<<8)>>6)+8; // follow jump
- }
- return ptr;
-}
-
-static int verify_dirty(const u_int *ptr)
-{
- #ifndef HAVE_ARMV7
- u_int offset;
- // get from literal pool
- assert((*ptr&0xFFFF0000)==0xe59f0000);
- offset=*ptr&0xfff;
- u_int source=*(u_int*)((void *)ptr+offset+8);
- ptr++;
- assert((*ptr&0xFFFF0000)==0xe59f0000);
- offset=*ptr&0xfff;
- u_int copy=*(u_int*)((void *)ptr+offset+8);
- ptr++;
- assert((*ptr&0xFFFF0000)==0xe59f0000);
- offset=*ptr&0xfff;
- u_int len=*(u_int*)((void *)ptr+offset+8);
- ptr++;
- ptr++;
- #else
- // ARMv7 movw/movt
- assert((*ptr&0xFFF00000)==0xe3000000);
- u_int source=(ptr[0]&0xFFF)+((ptr[0]>>4)&0xF000)+((ptr[2]<<16)&0xFFF0000)+((ptr[2]<<12)&0xF0000000);
- u_int copy=(ptr[1]&0xFFF)+((ptr[1]>>4)&0xF000)+((ptr[3]<<16)&0xFFF0000)+((ptr[3]<<12)&0xF0000000);
- u_int len=(ptr[4]&0xFFF)+((ptr[4]>>4)&0xF000);
- ptr+=6;
- #endif
- if((*ptr&0xFF000000)!=0xeb000000) ptr++;
- assert((*ptr&0xFF000000)==0xeb000000); // bl instruction
- //printf("verify_dirty: %x %x %x\n",source,copy,len);
- return !memcmp((void *)source,(void *)copy,len);
-}
-
-// This doesn't necessarily find all clean entry points, just
-// guarantees that it's not dirty
-static int isclean(void *addr)
-{
- #ifndef HAVE_ARMV7
- u_int *ptr=((u_int *)addr)+4;
- #else
- u_int *ptr=((u_int *)addr)+6;
- #endif
- if((*ptr&0xFF000000)!=0xeb000000) ptr++;
- if((*ptr&0xFF000000)!=0xeb000000) return 1; // bl instruction
- if((int)ptr+((*ptr<<8)>>6)+8==(int)verify_code) return 0;
- if((int)ptr+((*ptr<<8)>>6)+8==(int)verify_code_ds) return 0;
- return 1;
-}
-
-// get source that block at addr was compiled from (host pointers)
-static void get_bounds(void *addr, u_char **start, u_char **end)
-{
- u_int *ptr = addr;
- #ifndef HAVE_ARMV7
- u_int offset;
- // get from literal pool
- assert((*ptr&0xFFFF0000)==0xe59f0000);
- offset=*ptr&0xfff;
- u_int source=*(u_int*)((void *)ptr+offset+8);
- ptr++;
- //assert((*ptr&0xFFFF0000)==0xe59f0000);
- //offset=*ptr&0xfff;
- //u_int copy=*(u_int*)((void *)ptr+offset+8);
- ptr++;
- assert((*ptr&0xFFFF0000)==0xe59f0000);
- offset=*ptr&0xfff;
- u_int len=*(u_int*)((void *)ptr+offset+8);
- ptr++;
- ptr++;
- #else
- // ARMv7 movw/movt
- assert((*ptr&0xFFF00000)==0xe3000000);
- u_int source=(ptr[0]&0xFFF)+((ptr[0]>>4)&0xF000)+((ptr[2]<<16)&0xFFF0000)+((ptr[2]<<12)&0xF0000000);
- //u_int copy=(ptr[1]&0xFFF)+((ptr[1]>>4)&0xF000)+((ptr[3]<<16)&0xFFF0000)+((ptr[3]<<12)&0xF0000000);
- u_int len=(ptr[4]&0xFFF)+((ptr[4]>>4)&0xF000);
- ptr+=6;
- #endif
- if((*ptr&0xFF000000)!=0xeb000000) ptr++;
- assert((*ptr&0xFF000000)==0xeb000000); // bl instruction
- *start=(u_char *)source;
- *end=(u_char *)source+len;
-}