Beispiel #1
0
uint32_t ksbt_imageIndexContainingAddress(const uintptr_t address)
{
    const uint32_t imageCount = _dyld_image_count();
    const struct mach_header* header = 0;

    for(uint32_t iImg = 0; iImg < imageCount; iImg++)
    {
        header = _dyld_get_image_header(iImg);
        if(header != NULL)
        {
            // Look for a segment command with this address within its range.
            uintptr_t addressWSlide = address - (uintptr_t)_dyld_get_image_vmaddr_slide(iImg);
            uintptr_t cmdPtr = ksmach_firstCmdAfterHeader(header);
            if(cmdPtr == 0)
            {
                continue;
            }
            for(uint32_t iCmd = 0; iCmd < header->ncmds; iCmd++)
            {
                const struct load_command* loadCmd = (struct load_command*)cmdPtr;
                if(loadCmd->cmd == LC_SEGMENT)
                {
                    const struct segment_command* segCmd = (struct segment_command*)cmdPtr;
                    if(addressWSlide >= segCmd->vmaddr &&
                            addressWSlide < segCmd->vmaddr + segCmd->vmsize)
                    {
                        return iImg;
                    }
                }
                else if(loadCmd->cmd == LC_SEGMENT_64)
                {
                    const struct segment_command_64* segCmd = (struct segment_command_64*)cmdPtr;
                    if(addressWSlide >= segCmd->vmaddr &&
                            addressWSlide < segCmd->vmaddr + segCmd->vmsize)
                    {
                        return iImg;
                    }
                }
                cmdPtr += loadCmd->cmdsize;
            }
        }
    }
    return UINT_MAX;
}
static CFStringRef _CFBundleDYLDCopyLoadedImagePathForPointer(void *p) {
    CFStringRef result = NULL;
#if USE_DYLD_PRIV
    const char *name = dyld_image_path_containing_address(p);
    if (name) result = CFStringCreateWithFileSystemRepresentation(kCFAllocatorSystemDefault, name);
#else /* USE_DYLD_PRIV */
    if (!result) {
        uint32_t i, j, n = _dyld_image_count();
        Boolean foundIt = false;
        const char *name;
#if TARGET_RT_64_BIT
#define MACH_HEADER_TYPE struct mach_header_64
#define MACH_SEGMENT_CMD_TYPE struct segment_command_64
#define MACH_SEGMENT_FLAVOR LC_SEGMENT_64
#else
#define MACH_HEADER_TYPE struct mach_header
#define MACH_SEGMENT_CMD_TYPE struct segment_command
#define MACH_SEGMENT_FLAVOR LC_SEGMENT
#endif
        for (i = 0; !foundIt && i < n; i++) {
            const MACH_HEADER_TYPE *mh = (const MACH_HEADER_TYPE *)_dyld_get_image_header(i);
            uintptr_t addr = (uintptr_t)p - _dyld_get_image_vmaddr_slide(i);
            if (mh) {
                struct load_command *lc = (struct load_command *)((char *)mh + sizeof(MACH_HEADER_TYPE));
                for (j = 0; !foundIt && j < mh->ncmds; j++, lc = (struct load_command *)((char *)lc + lc->cmdsize)) {
                    if (MACH_SEGMENT_FLAVOR == lc->cmd && ((MACH_SEGMENT_CMD_TYPE *)lc)->vmaddr <= addr && addr < ((MACH_SEGMENT_CMD_TYPE *)lc)->vmaddr + ((MACH_SEGMENT_CMD_TYPE *)lc)->vmsize) {
                        foundIt = true;
                        name = _dyld_get_image_name(i);
                        if (name) result = CFStringCreateWithFileSystemRepresentation(kCFAllocatorSystemDefault, name);
                    }
                }
            }
        }
#undef MACH_HEADER_TYPE
#undef MACH_SEGMENT_CMD_TYPE
#undef MACH_SEGMENT_FLAVOR
    }
#endif /* USE_DYLD_PRIV */
#if LOG_BUNDLE_LOAD
    printf("dyld image path for pointer %p is %p\n", p, result);
#endif /* LOG_BUNDLE_LOAD */
    return result;
}
Beispiel #3
0
/*
 * This routine returns the a pointer to the data for the named section in the
 * named segment if it exist in the named Framework.  Also it returns the size
 * of the section data indirectly through the pointer size.  Otherwise it
 * returns zero for the pointer and the size.  The last component of the path
 * of the Framework is passed as FrameworkName.
 */
void *
getsectdatafromFramework(
    const char *FrameworkName,
    const char *segname,
    const char *sectname,
    unsigned long *size)
{
    uint32_t i, n;
    uintptr_t vmaddr_slide;
#ifndef __LP64__
    struct mach_header *mh;
    const struct section *s;
#else /* defined(__LP64__) */
    struct mach_header_64 *mh;
    const struct section_64 *s;
#endif /* defined(__LP64__) */
    char *name, *p;

    n = _dyld_image_count();
    for(i = 0; i < n ; i++) {
        name = _dyld_get_image_name(i);
        p = strrchr(name, '/');
        if(p != NULL && p[1] != '\0')
            name = p + 1;
        if(strcmp(name, FrameworkName) != 0)
            continue;
        mh = _dyld_get_image_header(i);
        vmaddr_slide = _dyld_get_image_vmaddr_slide(i);
#ifndef __LP64__
        s = getsectbynamefromheader(mh, segname, sectname);
#else /* defined(__LP64__) */
        s = getsectbynamefromheader_64(mh, segname, sectname);
#endif /* defined(__LP64__) */
        if(s == NULL) {
            *size = 0;
            return(NULL);
        }
        *size = s->size;
        return((void *)(s->addr + vmaddr_slide));
    }
    *size = 0;
    return(NULL);
}
Beispiel #4
0
DLSyms* dlSymsInit(const char* libPath) 
{
	DLSyms* pSyms = NULL;
	uint32_t iImage, nImages;
	for (iImage = 0, nImages = _dyld_image_count(); iImage < nImages; iImage++)
	{
		const char* name = _dyld_get_image_name(iImage);
		if (name && !strcmp(name, libPath))
		{
			const struct MACH_HEADER_TYPE* pHeader = _dyld_get_image_header(iImage);
			const char* pBase = ((const char*)pHeader);
			if (pHeader->filetype != MH_DYLIB)
				return NULL;
			if (pHeader->flags & MH_SPLIT_SEGS)
				return NULL;

			if (pHeader)
			{
				uint32_t iCmd, nCmds = pHeader->ncmds;
				const struct load_command* cmd = (const struct load_command*)(pBase + sizeof(struct MACH_HEADER_TYPE));
				
				for (iCmd = 0; iCmd < nCmds; iCmd++) 
				{
					if (cmd->cmd == LC_SYMTAB) 
					{
						const struct symtab_command* scmd = (const struct symtab_command*)cmd;
					
						pSyms = (DLSyms*)( dcAllocMem(sizeof(DLSyms)) );
						pSyms->symbolCount = scmd->nsyms;
						pSyms->pStringTable = pBase + scmd->stroff;
						pSyms->pSymbolTable = (struct NLIST_TYPE*)(pBase + scmd->symoff);
						
						return pSyms;
					}
					cmd = (const struct load_command*)(((char*)cmd) + cmd->cmdsize);
				}
			}
			break;
		}
	}
	return NULL;
}
Beispiel #5
0
void
bin_update_image(int entry, void *trampee_addr)
{
  int i, j, k;
  int header_count = _dyld_image_count();

  // Go through all the mach objects that are loaded into this process
  for (i=0; i < header_count; i++) {
    const struct mach_header *current_hdr = _dyld_get_image_header(i);

    // Modify any callsites residing inside the text segment
    set_text_segment(current_hdr, "__text");
    text_segment += _dyld_get_image_vmaddr_slide(i);
    update_callqs(entry, trampee_addr);

    int lc_count = current_hdr->ncmds;

    // this as a char* because we need to step it forward by an arbitrary number of bytes
    const char *lc = ((const char*) current_hdr) + sizeof(struct mach_header_64);

    // Check all the load commands in the object to see if they are segment commands
    for (j = 0; j < lc_count; j++) {
      if (((struct load_command*)lc)->cmd == LC_SEGMENT_64) {
        const struct segment_command_64 *seg = (const struct segment_command_64 *) lc;
        const struct section_64 * sect = (const struct section_64*)(lc + sizeof(struct segment_command_64));
        int section_count = (seg->cmdsize - sizeof(struct segment_command_64)) / sizeof(struct section_64);

        // Search the segment for a section containing dyld stub functions
        for (k=0; k < section_count; k++) {
          if (strncmp(sect->sectname, "__symbol_stub", 13) == 0) {
            set_text_segment((struct mach_header*)current_hdr, sect->sectname);
            text_segment += _dyld_get_image_vmaddr_slide(i);
            update_dyld_stubs(entry, trampee_addr);
          }
          sect++;
        }
      }
      lc += ((struct load_command*)lc)->cmdsize;
    }
  }
}
void InitMachOLibrary ()
{
    const mach_header* header = &_mh_bundle_header;
    if (header == 0)
        return;

    const char* imagename = 0;
    /* determine the image name, TODO: ther have to be a better way */
    int cnt = _dyld_image_count();
    for (int idx1 = 1; idx1 < cnt; idx1++)
    {
        if (_dyld_get_image_header(idx1) == header)
        {
            imagename = _dyld_get_image_name(idx1);
            break;
        }
    }
    if (imagename == 0)
        return;
    /* get the bundle of a header, TODO: ther have to be a better way */
    VSTGUI_BUNDLEREF = _CFXBundleCreateFromImageName (NULL, imagename);
}
Beispiel #7
0
/* There should probably be an apple dyld api for this. */
static const mach_header *
lt__nsmodule_get_header (NSModule module)
{
  int i = _dyld_image_count();
  const char *modname = NSNameOfModule (module);
  const mach_header *mh = 0;

  if (!modname)
    return NULL;

  while (i > 0)
    {
      --i;
      if (strneq (_dyld_get_image_name (i), modname))
	{
	  mh = _dyld_get_image_header (i);
	  break;
	}
    }

  return mh;
}
Beispiel #8
0
void loadAirtunesd() {
//    char *lib_path = aitrtunesdPath();
//    void *lib = dlopen(lib_path, RTLD_LAZY);
//
//    if (!lib) {
//        printf("%s\n", dlerror());
//    }
    
    int airtunesd_index = retrieveAirtunesdIndex();
    printf("airtunesd index %i\n", airtunesd_index);
    
    const struct mach_header *airtunesd_header = _dyld_get_image_header(airtunesd_index);
    printf("%p\n", airtunesd_header);
    
    int init_offset = 0x435B4 - 0x1000;
    init = (initFunction)((int)airtunesd_header + init_offset);
    
    int challenge_offset = 0xEB00C - 0x1000;
    challenge = (challengeFunction)((int)airtunesd_header + challenge_offset);
    
    int decrypt_offset = 0xEB964 - 0x1000;
    decrypt = (decryptFunction)((int)airtunesd_header + decrypt_offset);
}
Beispiel #9
0
static const struct mach_header *my_find_image(const char *name)
{
	const struct mach_header *mh = 0;
	const char *id = NULL;
	int i = _dyld_image_count();
	int j;
	mh = (struct mach_header *)
		dyld_NSAddImage(name, NSADDIMAGE_OPTION_RETURN_ONLY_IF_LOADED |
						NSADDIMAGE_OPTION_RETURN_ON_ERROR);
	if (!mh)
	{
		for (j = 0; j < i; j++)
		{
			id = _dyld_get_image_name(j);
			if (!strcmp(id, name))
			{
				mh = _dyld_get_image_header(j);
				break;
			}
		}
	}
	return mh;
}
ZZSTATUS ZzActivateSolidifyTrampoline(ZzHookFunctionEntry *entry, zaddr target_fileoff) {
    struct mach_header_64 *header = (struct mach_header_64 *)_dyld_get_image_header(0);
    struct segment_command_64 *text_seg_cmd = zz_macho_get_segment_64_via_name(header, "__TEXT");
    struct segment_command_64 *data_seg_cmd = zz_macho_get_segment_64_via_name(header, "HookZzData");
    zaddr aslr_slide = (zaddr)header - text_seg_cmd->vmaddr;
    ZzInterceptorBackendNoJB *nojb_backend = (ZzInterceptorBackendNoJB *)(aslr_slide + data_seg_cmd->vmaddr);
    nojb_backend->enter_thunk = (void *)enter_thunk_template;
    nojb_backend->leave_thunk = (void *)leave_thunk_template;

    ZzHookFunctionEntryNoJB *nojb_entry =
        (ZzHookFunctionEntryNoJB *)(data_seg_cmd->vmaddr + sizeof(ZzHookFunctionEntryNoJB) + aslr_slide);
    unsigned long i;
    for (i = 0; i < nojb_backend->num_of_entry; i++) {
        nojb_entry = &nojb_entry[i];
        if ((zaddr)nojb_entry->target_fileoff == target_fileoff) {
            nojb_entry->entry_address = entry;
            entry->on_enter_trampoline = (zpointer)(nojb_entry->on_enter_trampoline + aslr_slide);
            entry->on_invoke_trampoline = nojb_entry->on_invoke_trampoline + aslr_slide;
            entry->on_leave_trampoline = nojb_entry->on_leave_trampoline + aslr_slide;
        }
    }
    return ZZ_SUCCESS;
}
Beispiel #11
0
static uintptr_t libSystemSlide()
{
	Dl_info info;
	if ( dladdr(&malloc, &info) == 0 ) {
		FAIL("all_image_infos-cache-slide: dladdr(&malloc, xx) failed");
		exit(0);
	}
	
	const struct mach_header* mallocMh = (struct mach_header*)info.dli_fbase;
	if ( (mallocMh->flags & 0x80000000) == 0 ) {
		FAIL("all_image_infos-cache-slide: image containing _malloc not in shared cache");
		exit(0);
	}
	
	int count = _dyld_image_count();
	for(int i=0; i < count; ++i) {
		if ( mallocMh == _dyld_get_image_header(i) ) {
			return _dyld_get_image_vmaddr_slide(i);
		}
	}

	FAIL("all_image_infos-cache-slide: slide of image containing _malloc not found");
	exit(0);
}
Beispiel #12
0
// SegmentAlignment.swift import SpriteKit and calls Test().
void Test(void)
{
    for (int i = 0; i < _dyld_image_count(); i++) {
        const char *name = _dyld_get_image_name(i);
        if (strstr(name, "libswift") == 0) continue;

        unsigned long size;
        const struct mach_header *mhdr = _dyld_get_image_header(i);
        uint8_t *textAddress =
            getsegmentdata((HeaderType *)mhdr, "__TEXT", &size);
        uint8_t *dataAddress =
            getsegmentdata((HeaderType *)mhdr, "__DATA", &size);

        printf("%s %p %p\n", name, textAddress, dataAddress);
        assert((uintptr_t)textAddress % 0x4000 == 0);
        assert((uintptr_t)dataAddress % 0x4000 == 0);
    }

    printf("Flawless victory\n");
    // CHECK-DAG: libswiftSpriteKit.dylib
    // CHECK-DAG: libswiftUIKit.dylib
    // CHECK-DAG: libswiftCore.dylib
    // CHECK: Flawless victory
}
Beispiel #13
0
bool ksdl_dladdr(const uintptr_t address, Dl_info* const info)
{
    info->dli_fname = NULL;
    info->dli_fbase = NULL;
    info->dli_sname = NULL;
    info->dli_saddr = NULL;

    const uint32_t idx = ksdl_imageIndexContainingAddress(address);
    if(idx == UINT_MAX)
    {
        return false;
    }
    const struct mach_header* header = _dyld_get_image_header(idx);
    const uintptr_t imageVMAddrSlide = (uintptr_t)_dyld_get_image_vmaddr_slide(idx);
    const uintptr_t addressWithSlide = address - imageVMAddrSlide;
    const uintptr_t segmentBase = ksdl_segmentBaseOfImageIndex(idx) + imageVMAddrSlide;
    if(segmentBase == 0)
    {
        return false;
    }

    info->dli_fname = _dyld_get_image_name(idx);
    info->dli_fbase = (void*)header;

    // Find symbol tables and get whichever symbol is closest to the address.
    const STRUCT_NLIST* bestMatch = NULL;
    uintptr_t bestDistance = ULONG_MAX;
    uintptr_t cmdPtr = ksdl_firstCmdAfterHeader(header);
    if(cmdPtr == 0)
    {
        return false;
    }
    for(uint32_t iCmd = 0; iCmd < header->ncmds; iCmd++)
    {
        const struct load_command* loadCmd = (struct load_command*)cmdPtr;
        if(loadCmd->cmd == LC_SYMTAB)
        {
            const struct symtab_command* symtabCmd = (struct symtab_command*)cmdPtr;
            const STRUCT_NLIST* symbolTable = (STRUCT_NLIST*)(segmentBase + symtabCmd->symoff);
            const uintptr_t stringTable = segmentBase + symtabCmd->stroff;

            for(uint32_t iSym = 0; iSym < symtabCmd->nsyms; iSym++)
            {
                // If n_value is 0, the symbol refers to an external object.
                if(symbolTable[iSym].n_value != 0)
                {
                    uintptr_t symbolBase = symbolTable[iSym].n_value;
                    uintptr_t currentDistance = addressWithSlide - symbolBase;
                    if((addressWithSlide >= symbolBase) &&
                       (currentDistance <= bestDistance))
                    {
                        bestMatch = symbolTable + iSym;
                        bestDistance = currentDistance;
                    }
                }
            }
            if(bestMatch != NULL)
            {
                info->dli_saddr = (void*)(bestMatch->n_value + imageVMAddrSlide);
                info->dli_sname = (char*)((intptr_t)stringTable + (intptr_t)bestMatch->n_un.n_strx);
                if(*info->dli_sname == '_')
                {
                    info->dli_sname++;
                }
                // This happens if all symbols have been stripped.
                if(info->dli_saddr == info->dli_fbase && bestMatch->n_type == 3)
                {
                    info->dli_sname = NULL;
                }
                break;
            }
        }
        cmdPtr += loadCmd->cmdsize;
    }
    
    return true;
}
Beispiel #14
0
int dladdr(void * p, Dl_info * info)
{
    unsigned long i;
    unsigned long j;
    unsigned long count = _dyld_image_count();
    struct mach_header *mh=0;
    struct load_command *lc=0;
    unsigned long addr = 0;
    int found = 0;
    if (!info) return 0;
    info->dli_fname = 0;
    info->dli_fbase = 0;
    info->dli_sname = 0;
    info->dli_saddr = 0;    
/* Some of this was swiped from code posted by Douglas Davidson <ddavidso AT apple DOT com>
to darwin-development AT lists DOT apple DOT com and slightly modified
*/    
    for (i = 0; i < count; i++) 
    {
    addr = (unsigned long)p - _dyld_get_image_vmaddr_slide(i);
    mh = _dyld_get_image_header(i);    
    if (mh) 
    {
        lc = (struct load_command *)((char *)mh + sizeof(struct mach_header));
        for (j = 0; j < mh->ncmds; j++, lc = (struct load_command *)((char *)lc + lc->cmdsize)) 
        {
         if (LC_SEGMENT == lc->cmd && 
         addr >= ((struct segment_command *)lc)->vmaddr && 
         addr < ((struct segment_command *)lc)->vmaddr + ((struct segment_command *)lc)->vmsize) 
         {      
            info->dli_fname = _dyld_get_image_name(i);
            info->dli_fbase = (void*)mh;
            found = 1;
            break;
         }      
         }
         if (found) break;
     }
     }
     if (!found) return 0;
/*      Okay, we seem to have found a place for the address, so now, we have to search the symbol table
    for the nearest symbol with an address less than or equal to the passed in address */
    lc = (struct load_command *)((char *)mh + sizeof(struct mach_header));
    for (j = 0; j < mh->ncmds; j++, lc = (struct load_command *)((char *)lc + lc->cmdsize)) 
    {
        if ( LC_SYMTAB == lc->cmd )
        {
            struct nlist * symtable = (struct nlist *)(((struct symtab_command *)lc)->symoff + (void*)mh);
            unsigned long numsyms = ((struct symtab_command *)lc)->nsyms;
            struct nlist * nearest = NULL;
            unsigned long diff = 0xffffffff;
            unsigned long strtable = (unsigned long)(((struct symtab_command *)lc)->stroff + (void*)mh);
            for (i = 0; i < numsyms; i++)
            {
                /* Ignore the following kinds of Symbols */
                if ((!symtable->n_value)                     /* Undefined */
                    || (symtable->n_type >= N_PEXT)         /* Debug symbol */
                    || (!(symtable->n_type & N_EXT))         /* Local Symbol */
                    )
                {
                    symtable++;
                    continue;
                }
                /*
                printf("info for symbol : %ld\n",i);
                printf("n_type: 0x%x\n",symtable->n_type);
                printf("n_sect: 0x%x\n",symtable->n_sect);    
                printf("n_desc: 0x%x\n",symtable->n_desc);
                printf("n_value: 0x%x\n",symtable->n_value);    
                printf("Name: %s\n",(char*)(strtable + symtable->n_un.n_strx ));
                */
                if (( addr >= symtable->n_value) && (diff >= (symtable->n_value - addr)))
                {
                    diff = symtable->n_value - addr;
                    nearest = symtable;
                    /*
                    printf("Nearest is 0x%x\n",nearest);
                    printf("Value: 0x%x\n",nearest->n_value);
                    */
                }
                symtable++;
            }
            if (nearest)
            {
                info->dli_saddr = nearest->n_value + (p - addr);
                info->dli_sname = (char*)(strtable + nearest->n_un.n_strx );
            }                        
        }
    }
    return 1;
}
primitiveExecutableModulesAndOffsets(void) {
    const struct mach_header *h;
    sqInt i;
    const char *name;
    char *nameObjData;
    sqInt nimages;
    sqInt present;
    sqInt resultObj;
    const struct section *s;
    unsigned long size;
    sqInt slide;
    unsigned long start;
    sqInt valueObj;

	present = _dyld_present();
	if (!(present)) {
		return interpreterProxy->primitiveFail();
	}
	nimages = _dyld_image_count();
	resultObj = interpreterProxy->instantiateClassindexableSize(interpreterProxy->classArray(), nimages * 4);
	if (resultObj == 0) {
		return interpreterProxy->primitiveFail();
	}
	interpreterProxy->pushRemappableOop(resultObj);
	for (i = 0; i <= (nimages - 1); i += 1) {

		/* impossible start & size */

		start = size = -1;
		name = _dyld_get_image_name(i);
		slide = _dyld_get_image_vmaddr_slide(i);
		h = _dyld_get_image_header(i);
		if (h != null) {
			s = getsectbynamefromheader(h,SEG_TEXT,SECT_TEXT);
			if (s != null) {
				start = s->addr;
				size = s->size;
			}
		}
		valueObj = interpreterProxy->instantiateClassindexableSize(interpreterProxy->classString(), strlen(name));
		if (interpreterProxy->failed()) {
			interpreterProxy->pop(1);
			return interpreterProxy->primitiveFail();
		}
		interpreterProxy->storePointerofObjectwithValue(i * 4, interpreterProxy->topRemappableOop(), valueObj);
		nameObjData = interpreterProxy->arrayValueOf(valueObj);
		memcpy(nameObjData, name, strlen(name));
		valueObj = interpreterProxy->signed32BitIntegerFor(slide);
		if (interpreterProxy->failed()) {
			interpreterProxy->pop(1);
			return interpreterProxy->primitiveFail();
		}
		interpreterProxy->storePointerofObjectwithValue((i * 4) + 1, interpreterProxy->topRemappableOop(), valueObj);
		valueObj = interpreterProxy->positive32BitIntegerFor(start);
		if (interpreterProxy->failed()) {
			interpreterProxy->pop(1);
			return interpreterProxy->primitiveFail();
		}
		interpreterProxy->storePointerofObjectwithValue((i * 4) + 2, interpreterProxy->topRemappableOop(), valueObj);
		valueObj = interpreterProxy->positive32BitIntegerFor(size);
		if (interpreterProxy->failed()) {
			interpreterProxy->pop(1);
			return interpreterProxy->primitiveFail();
		}
		interpreterProxy->storePointerofObjectwithValue((i * 4) + 3, interpreterProxy->topRemappableOop(), valueObj);
	}
	resultObj = interpreterProxy->popRemappableOop();
	return interpreterProxy->popthenPush(1, resultObj);
}
void initialize_library(const char *uGensPluginPath)
{
	gCmdLib     = new HashTable<SC_LibCmd, Malloc>(&gMalloc, 64, true);
	gUnitDefLib = new HashTable<UnitDef, Malloc>(&gMalloc, 512, true);
	gBufGenLib  = new HashTable<BufGen, Malloc>(&gMalloc, 512, true);
	gPlugInCmds = new HashTable<PlugInCmd, Malloc>(&gMalloc, 64, true);

	initMiscCommands();

#ifdef STATIC_PLUGINS
	IO_Load(&gInterfaceTable);
	Osc_Load(&gInterfaceTable);
	Delay_Load(&gInterfaceTable);
	BinaryOp_Load(&gInterfaceTable);
	Filter_Load(&gInterfaceTable);
	Gendyn_Load(&gInterfaceTable);
	LF_Load(&gInterfaceTable);
	Noise_Load(&gInterfaceTable);
	MulAdd_Load(&gInterfaceTable);
	Grain_Load(&gInterfaceTable);
	Pan_Load(&gInterfaceTable);
	Reverb_Load(&gInterfaceTable);
	Trigger_Load(&gInterfaceTable);
	UnaryOp_Load(&gInterfaceTable);
	DiskIO_Load(&gInterfaceTable);
	PhysicalModeling_Load(&gInterfaceTable);
	Test_Load(&gInterfaceTable);
	Demand_Load(&gInterfaceTable);
	DynNoise_Load(&gInterfaceTable);
#if defined(SC_IPHONE) && !TARGET_IPHONE_SIMULATOR
	iPhone_Load(&gInterfaceTable);
#endif
	return;
#endif

	// If uGensPluginPath is supplied, it is exclusive.
	bool loadUGensExtDirs = true;
	if(uGensPluginPath){
		loadUGensExtDirs = false;
		SC_StringParser sp(uGensPluginPath, SC_STRPARSE_PATHDELIMITER);
		while (!sp.AtEnd()) {
			PlugIn_LoadDir(const_cast<char *>(sp.NextToken()), true);
		}
	}

	if(loadUGensExtDirs) {
#ifdef SC_PLUGIN_DIR
		// load globally installed plugins
		if (sc_DirectoryExists(SC_PLUGIN_DIR)) {
			PlugIn_LoadDir(SC_PLUGIN_DIR, true);
		}
#endif

		// load default plugin directory
		char pluginDir[MAXPATHLEN];
		sc_GetResourceDirectory(pluginDir, MAXPATHLEN);
		sc_AppendToPath(pluginDir, SC_PLUGIN_DIR_NAME);

		if (sc_DirectoryExists(pluginDir)) {
			PlugIn_LoadDir(pluginDir, true);
		}
	}

	// get extension directories
	char extensionDir[MAXPATHLEN];
	if (!sc_IsStandAlone() && loadUGensExtDirs) {
		// load system extension plugins
		sc_GetSystemExtensionDirectory(extensionDir, MAXPATHLEN);
		PlugIn_LoadDir(extensionDir, false);

		// load user extension plugins
		sc_GetUserExtensionDirectory(extensionDir, MAXPATHLEN);
		PlugIn_LoadDir(extensionDir, false);

		// load user plugin directories
		SC_StringParser sp(getenv("SC_PLUGIN_PATH"), SC_STRPARSE_PATHDELIMITER);
		while (!sp.AtEnd()) {
			PlugIn_LoadDir(const_cast<char *>(sp.NextToken()), true);
		}
	}
#ifdef SC_DARWIN
	/* on darwin plugins are lazily loaded (dlopen uses mmap internally), which can produce audible
		glitches when UGens have to be paged-in. to work around this we preload all the plugins by
		iterating through their memory space. */

	unsigned long images = _dyld_image_count();
	for(unsigned long i = 0; i < images; i++) {
		const mach_header	*hdr = _dyld_get_image_header(i);
		unsigned long slide = _dyld_get_image_vmaddr_slide(i);
		const char *name = _dyld_get_image_name(i);
		uint32_t	size;
		char *sect;

		if(!strcmp(name + (strlen(name) - 4), ".scx")) {
			read_section(hdr, slide, "__TEXT", "__text");
			read_section(hdr, slide, "__TEXT", "__const");
			read_section(hdr, slide, "__TEXT", "__cstring");
			read_section(hdr, slide, "__TEXT", "__picsymbol_stub");
			read_section(hdr, slide, "__TEXT", "__symbol_stub");
			read_section(hdr, slide, "__TEXT", "__const");
			read_section(hdr, slide, "__TEXT", "__literal4");
			read_section(hdr, slide, "__TEXT", "__literal8");

			read_section(hdr, slide, "__DATA", "__data");
			read_section(hdr, slide, "__DATA", "__la_symbol_ptr");
			read_section(hdr, slide, "__DATA", "__nl_symbol_ptr");
			read_section(hdr, slide, "__DATA", "__dyld");
			read_section(hdr, slide, "__DATA", "__const");
			read_section(hdr, slide, "__DATA", "__mod_init_func");
			read_section(hdr, slide, "__DATA", "__bss");
			read_section(hdr, slide, "__DATA", "__common");

			read_section(hdr, slide, "__IMPORT", "__jump_table");
			read_section(hdr, slide, "__IMPORT", "__pointers");
		}
	}
#endif
}
Beispiel #17
0
bool Instance_LocateModule(const char * name, char * fileName)
{
#if defined(__WIN32__)
   HMODULE hModule = null;
   if(name && name[0])
   {
      uint16 _wmoduleName[MAX_LOCATION];
      UTF8toUTF16Buffer(name, _wmoduleName, MAX_LOCATION);
      hModule = GetModuleHandle(_wmoduleName);
      if(!hModule)
      {
         wcscat(_wmoduleName, L".exe");
         hModule = GetModuleHandle(_wmoduleName);
      }
      if(hModule)
      {
         uint16 _wfileName[MAX_LOCATION];
         GetModuleFileNameW(hModule, _wfileName, MAX_LOCATION);
         UTF16toUTF8Buffer(_wfileName, fileName, MAX_LOCATION);
         return true;
      }
   }
   else
   {
      uint16 _wfileName[MAX_LOCATION];
      GetModuleFileNameW(null, _wfileName, MAX_LOCATION);
      UTF16toUTF8Buffer(_wfileName, fileName, MAX_LOCATION);
      return true;
   }
#elif defined(__APPLE__)
   if(name && name[0])
   {
      int imageCount = _dyld_image_count();
      int c;
      int nameLen = strlen(name);
      for(c = 0; c<imageCount; c++)
      {
         struct mach_header * header = _dyld_get_image_header(c);
         char * path = _dyld_get_image_name(c);
         int pathLen = strlen(path);
         char * subStr = RSearchString(path, name, pathLen, false, false);
         if(subStr)
         {
            if(( *(subStr-1) == '/' || !strncmp(subStr - 4, "/lib", 4)) &&
               (!subStr[nameLen] || !strncmp(subStr + nameLen, ".dylib", 6)))
            {
               strcpy(fileName, path);
               return true;
            }
         }
      }
   }
   else
   {
      int size = MAX_LOCATION;
      _NSGetExecutablePath(fileName, &size);
      return true;
   }
#elif defined(__unix__)
   //File f = FileOpen("/proc/self/maps", read);
   FILE * f = null;
   char exeName[MAX_FILENAME];
   exeName[0] = 0;
#if defined(__linux__)
   f = fopen("/proc/self/status", "r");
#else
   f = fopen("/proc/curproc/status", "r");
#endif
   if(f)
   {
      char line[1025];
      while(fgets(line, sizeof(line), f))
      {
         char * name = strstr(line, "Name:\t");
         if(name)
         {
            int nameLen;
            name += 6;
            nameLen = strlen(name);
            name[--nameLen] = 0;
            strcpy(exeName, name);
            break;
         }
      }
      fclose(f);
  }
#if defined(__linux__)
   f = fopen("/proc/self/maps", "r");
#else
   f = fopen("/proc/curproc/map", "r");
#endif
   if(f)
   {
      char line[1025];
      //while(f.GetLine(line, sizeof(line)))
      while(fgets(line, sizeof(line), f))
      {
         char * path = strstr(line, "/");
         if(path)
         {
            int pathLen = strlen(path);
            path[--pathLen] = 0;
            if(name && name[0])
            {
               int nameLen = strlen(name);
               char * subStr;
               subStr = RSearchString(path, name, pathLen, false, false);
               if(subStr)
               {
                  if(( *(subStr-1) == '/' || !strncmp(subStr - 4, "/lib", 4)) &&
                     (!subStr[nameLen] || !strncmp(subStr + nameLen, ".so", 3)))
                  {
                     char * space = strchr(path, ' ');
                     if(space) *space = 0;
                     strcpy(fileName, path);
                     fclose(f);
                     return true;
                  }
               }
            }
            else
            {
               char name[MAX_FILENAME];
               GetLastDirectory(path, name);
               if(!exeName[0] || !strcmp(name, exeName))
               {
                  char * space = strchr(path, ' ');
                  if(space) *space = 0;
                  strcpy(fileName, path);
                  fclose(f);
                  return true;
               }
            }
         }
      }
      fclose(f);
   }
#if !defined(ECERE_NOFILE) && !defined(__linux__) && !defined(__EMSCRIPTEN__)
   if(name && name[0])
   {
      // Couldn't locate libraries with /proc/curmap/map, attempt with ldd
      FILE * in = null, * out = null;
      _DualPipe * p;
      char command[MAX_LOCATION];
      snprintf(command, sizeof(command), "ldd /proc/%d/file", (int)getpid());
      p  = _DualPipeOpen(1, command, null, &in, &out);
      if(p)
      {
         bool result = false;
         char line[1025];
         int nameLen = strlen(name);
         while(DualPipe_GetLine(in, line, sizeof(line)))
         {
            char * path = strstr(line, "/");
            if(path)
            {
               int pathLen = strlen(path);
               char * subStr;
               path[--pathLen] = 0;
               subStr = RSearchString(path, name, pathLen, false, false);
               if(subStr)
               {
                  if(( *(subStr-1) == '/' || !strncmp(subStr - 4, "/lib", 4)) &&
                     (!subStr[nameLen] || !strncmp(subStr + nameLen, ".so", 3)))
                  {
                     char * space = strchr(path, ' ');
                     if(space) *space = 0;
                     strcpy(fileName, path);
                     result = true;
                  }
               }
            }
         }
         DualPipe_Wait(p);
         fclose(in);
         DualPipe_Destructor(p);
         return result;
      }
   }
#endif
   if(!name || !name[0])
   {
#if defined(__FreeBSD__)
      {
         int mib[4] = { CTL_KERN, KERN_PROC, KERN_PROC_PATHNAME, -1 };
         size_t cb = MAX_LOCATION;
         fileName[0] = 0;
         sysctl(mib, 4, fileName, &cb, null, 0);
         if(fileName[0])
            return true;
      }
#endif
#if !defined(__linux__)
      {
         char * env;
         if(!access("/proc/curproc/file", F_OK))
         {
            strcpy(fileName, "/proc/curproc/file");
            return true;
         }
         if((env = getenv("_")))
         {
            strcpy(fileName, env);
            return true;
         }
      }
#endif
      strcpy(fileName, exeLocation);
      return true;
   }
#endif
   return false;
}
static CFBundleRef _CFBundleGetMainBundleAlreadyLocked(void) {
    if (!_initedMainBundle) {
        const char *processPath;
        CFStringRef str = NULL;
        CFURLRef executableURL = NULL, bundleURL = NULL;
        _initedMainBundle = true;
        processPath = _CFProcessPath();
        if (processPath) {
            str = CFStringCreateWithFileSystemRepresentation(kCFAllocatorSystemDefault, processPath);
            if (!executableURL) executableURL = CFURLCreateWithFileSystemPath(kCFAllocatorSystemDefault, str, PLATFORM_PATH_STYLE, false);
        }
        if (executableURL) bundleURL = _CFBundleCopyBundleURLForExecutableURL(executableURL);
        if (bundleURL) {
            // make sure that main bundle has executable path
            //??? what if we are not the main executable in the bundle?
            // NB doFinalProcessing must be false here, see below
            _mainBundle = _CFBundleCreateMain(kCFAllocatorSystemDefault, bundleURL);
            if (_mainBundle) {
                // make sure that the main bundle is listed as loaded, and mark it as executable
                _mainBundle->_isLoaded = true;
#if defined(BINARY_SUPPORT_DYLD)
                if (_mainBundle->_binaryType == __CFBundleUnknownBinary) {
                    if (!executableURL) {
                        _mainBundle->_binaryType = __CFBundleNoBinary;
                    } else {
                        _mainBundle->_binaryType = _CFBundleGrokBinaryType(executableURL);
                        if (_mainBundle->_binaryType != __CFBundleCFMBinary && _mainBundle->_binaryType != __CFBundleUnreadableBinary) _mainBundle->_resourceData._executableLacksResourceFork = true;
                    }
                }
#endif /* BINARY_SUPPORT_DYLD */
                // get cookie for already-loaded main bundle
#if defined(BINARY_SUPPORT_DLFCN)
                if (!_mainBundle->_handleCookie) {
                    _mainBundle->_handleCookie = dlopen(NULL, RTLD_NOLOAD | RTLD_FIRST);
#if LOG_BUNDLE_LOAD
                    printf("main bundle %p getting handle %p\n", _mainBundle, _mainBundle->_handleCookie);
#endif /* LOG_BUNDLE_LOAD */
                }
#elif defined(BINARY_SUPPORT_DYLD)
                if (_mainBundle->_binaryType == __CFBundleDYLDExecutableBinary && !_mainBundle->_imageCookie) {
                    _mainBundle->_imageCookie = (void *)_dyld_get_image_header(0);
#if LOG_BUNDLE_LOAD
                    printf("main bundle %p getting image %p\n", _mainBundle, _mainBundle->_imageCookie);
#endif /* LOG_BUNDLE_LOAD */
                }
#endif /* BINARY_SUPPORT_DLFCN */
                _CFBundleInitializeMainBundleInfoDictionaryAlreadyLocked(str);
                // Perform delayed final processing steps.
                // This must be done after _isLoaded has been set, for security reasons (3624341).
                // It is safe to unlock and re-lock here because we don't really do anything under the lock after we are done. It is just re-locked to satisfy the 'already locked' contract.
                _CFMutexUnlock(&_mainBundleLock);
                _CFBundleInitPlugIn(_mainBundle);
                _CFMutexLock(&_mainBundleLock);
            }
        }
        if (bundleURL) CFRelease(bundleURL);
        if (str) CFRelease(str);
        if (executableURL) CFRelease(executableURL);
        
    }
    return _mainBundle;
}
Beispiel #19
0
int
darwin_dladdr(void *p, Dl_info *info)
{
  unsigned long i;
  unsigned long j;
  uint32_t count = _dyld_image_count();
  struct mach_header *mh = 0;
  struct load_command *lc = 0;
  unsigned long addr = 0;
  unsigned long table_off = (unsigned long)0;
  int found = 0;

  if (!info)
    return 0;
  info->dli_fname = 0;
  info->dli_fbase = 0;
  info->dli_sname = 0;
  info->dli_saddr = 0;
  /* Some of this was swiped from code posted by Douglas Davidson
   * <ddavidso AT apple DOT com> to darwin-development AT lists DOT
   * apple DOT com and slightly modified
   */
  for (i = 0; i < count; i++) {
    addr = (unsigned long)p - _dyld_get_image_vmaddr_slide(i);
    mh = (struct mach_header *)_dyld_get_image_header(i);
    if (mh) {
      lc = (struct load_command *)((char *)mh + sizeof(struct mach_header));
      for (j = 0; j < mh->ncmds; j++, lc = (struct load_command *)((char *)lc + lc->cmdsize)) {
	if (LC_SEGMENT == lc->cmd &&
	    addr >= ((struct segment_command *)lc)->vmaddr &&
	    addr <
	    ((struct segment_command *)lc)->vmaddr + ((struct segment_command *)lc)->vmsize) {
	  info->dli_fname = _dyld_get_image_name(i);
	  info->dli_fbase = (void *)mh;
	  found = 1;
	  break;
	}
      }
      if (found) {
	    break;
      }
    }
  }
  if (!found) {
    return 0;
  }
  lc = (struct load_command *)((char *)mh + sizeof(struct mach_header));
  for (j = 0; 
       j < mh->ncmds; 
       j++, lc = (struct load_command *)((char *)lc + lc->cmdsize)) {
    if (LC_SEGMENT == lc->cmd) {
      if (!strcmp(((struct segment_command *)lc)->segname, "__LINKEDIT"))
	break;
    }
  }
  table_off =
    ((unsigned long)((struct segment_command *)lc)->vmaddr) -
    ((unsigned long)((struct segment_command *)lc)->fileoff) + _dyld_get_image_vmaddr_slide(i);
  
  lc = (struct load_command *)((char *)mh + sizeof(struct mach_header));
  for (j = 0; 
       j < mh->ncmds; 
       j++, lc = (struct load_command *)((char *)lc + lc->cmdsize)) {
    if (LC_SYMTAB == lc->cmd) {
      struct nlist *symtable = (struct nlist *)(((struct symtab_command *)lc)->symoff + table_off);
      unsigned long numsyms = ((struct symtab_command *)lc)->nsyms;
      struct nlist *nearest = NULL;
      unsigned long diff = 0xffffffff;
      unsigned long strtable = (unsigned long)(((struct symtab_command *)lc)->stroff + table_off);
      for (i = 0; i < numsyms; i++) {
	/* fprintf(dbgout,"%s : 0x%08x, 0x%x\n",(char *)(strtable + symtable->n_un.n_strx) ,symtable->n_value, symtable->n_type); */
	/* Ignore the following kinds of Symbols */
	if ((!symtable->n_value)	/* Undefined */
	    || (symtable->n_type & N_STAB)	/* Debug symbol */
	    || ((symtable->n_type & N_TYPE) != N_SECT)	/* Absolute, indirect, ... */
	    ) {
	  symtable++;
	  continue;
	}
	if ((addr >= symtable->n_value) && 
	    (diff >= addr - (symtable->n_value ))) {
	  diff = addr- (unsigned long)symtable->n_value;
	  nearest = symtable;
	}
	symtable++;
      }
      if (nearest) {
	info->dli_saddr = nearest->n_value + ((void *)p - addr);
	info->dli_sname = (char *)(strtable + nearest->n_un.n_strx);
      }
    }
  }
  return 1;
}
CF_PRIVATE CFArrayRef _CFBundleDYLDCopyLoadedImagePathsForHint(CFStringRef hint) {
    uint32_t i, numImages = _dyld_image_count();
    CFMutableArrayRef result = CFArrayCreateMutable(kCFAllocatorSystemDefault, 0, &kCFTypeArrayCallBacks);
    CFRange range = CFRangeMake(0, CFStringGetLength(hint)), altRange = CFRangeMake(0, 0), testRange = CFRangeMake(0, 0);
    const char *processPath = _CFProcessPath();
    const void *mhp = (const void *)_NSGetMachExecuteHeader();
    
    if (range.length > 14) {
        // handle some common variations on framework bundle identifiers
        if (CFStringFindWithOptions(hint, CFSTR(".framework"), range, kCFCompareAnchored|kCFCompareBackwards|kCFCompareCaseInsensitive, &testRange) && testRange.location > 0 && testRange.length > 0) {
            // identifier has .framework appended
            altRange.length = testRange.location;
        } else if (CFStringFindWithOptions(hint, CFSTR("framework"), range, kCFCompareAnchored|kCFCompareBackwards|kCFCompareCaseInsensitive, &testRange) && testRange.location > 0 && testRange.length > 0) {
            // identifier has Framework appended
            altRange.length = testRange.location;
        } else if (CFStringFindWithOptions(hint, CFSTR("fw"), range, kCFCompareAnchored|kCFCompareBackwards|kCFCompareCaseInsensitive, &testRange) && testRange.location > 0 && testRange.length > 0) {
            // identifier has FW appended
            altRange.length = testRange.location;
        }
    }
    for (i = 0; i < numImages; i++) {
        const char *curName = _dyld_get_image_name(i), *lastComponent = NULL;
        if (curName && (!processPath || 0 != strcmp(curName, processPath)) && mhp != (void *)_dyld_get_image_header(i)) lastComponent = strrchr(curName, '/');
        if (lastComponent) {
            CFStringRef str = CFStringCreateWithFileSystemRepresentation(kCFAllocatorSystemDefault, lastComponent + 1);
            if (str) {
                if (CFStringFindWithOptions(hint, str, range, kCFCompareAnchored|kCFCompareBackwards|kCFCompareCaseInsensitive, NULL) || (altRange.length > 0 && CFStringFindWithOptions(hint, str, altRange, kCFCompareAnchored|kCFCompareBackwards|kCFCompareCaseInsensitive, NULL))) {
                    CFStringRef curStr = CFStringCreateWithFileSystemRepresentation(kCFAllocatorSystemDefault, curName);
                    if (curStr) {
                        CFArrayAppendValue(result, curStr);
                        CFRelease(curStr);
                    }
                }
                CFRelease(str);
            }
        }
    }
    return result;
}
Beispiel #21
0
MODULE_SCOPE void *
TkMacOSXGetNamedDebugSymbol(
    const char* module,
    const char* symbol)
{
    void* addr = TkMacOSXGetNamedSymbol(module, symbol);
#ifndef __LP64__
    if (!addr) {
	const struct mach_header *mh = NULL;
	uint32_t i, n = _dyld_image_count();
	size_t module_len = 0;

	if (module && *module) {
	    module_len = strlen(module);
	}
	for (i = 0; i < n; i++) {
	    if (module && *module) {
		/* Find image with given module name */
		char *name;
		const char *path = _dyld_get_image_name(i);

		if (!path) {
		    continue;
		}
		name = strrchr(path, '/') + 1;
		if (strncmp(name, module, module_len) != 0) {
		    continue;
		}
	    }
	    mh = _dyld_get_image_header(i);
	    if (mh) {
		struct load_command *lc;
		struct symtab_command *st = NULL;
		struct segment_command *sg = NULL;
		uint32_t j, m, nsect = 0, txtsectx = 0;

		lc = (struct load_command*)((const char*) mh +
			sizeof(struct mach_header));
		m = mh->ncmds;
		for (j = 0; j < m; j++) {
		    /* Find symbol table and index of __text section */
		    if (lc->cmd == LC_SEGMENT) {
			/* Find last segment before symbol table */
			sg = (struct segment_command*) lc;
			if (!txtsectx) {
			    /* Count total sections until (__TEXT, __text) */
			    uint32_t k, ns = sg->nsects;

			    if (strcmp(sg->segname, SEG_TEXT) == 0) {
				struct section *s = (struct section *)(
					(char *)sg +
					sizeof(struct segment_command));

				for(k = 0; k < ns; k++) {
				    if (strcmp(s->sectname, SECT_TEXT) == 0) {
					txtsectx = nsect+k+1;
					break;
				    }
				    s++;
				}
			    }
			    nsect += ns;
			}
		    } else if (!st && lc->cmd == LC_SYMTAB) {
			st = (struct symtab_command*) lc;
			break;
		    }
		    lc = (struct load_command *)((char *) lc + lc->cmdsize);
		}
		if (st && sg && txtsectx) {
		    intptr_t base, slide = _dyld_get_image_vmaddr_slide(i);
		    char *strings;
		    struct nlist *sym;
		    uint32_t strsize = st->strsize;
		    int32_t strx;

		    /* Offset file positions by difference to actual position
		       in memory of last segment before symbol table: */
		    base = (intptr_t) sg->vmaddr + slide - sg->fileoff;
		    strings = (char*)(base + st->stroff);
		    sym = (struct nlist*)(base + st->symoff);
		    m = st->nsyms;
		    for (j = 0; j < m; j++) {
			/* Find symbol with given name in __text section */
			strx = sym->n_un.n_strx;
			if ((sym->n_type & N_TYPE) == N_SECT &&
				sym->n_sect == txtsectx &&
				strx > 0 && (uint32_t) strx < strsize &&
				strcmp(strings + strx, symbol) == 0) {
			    addr = (char*) sym->n_value + slide;
			    break;
			}
			sym++;
		    }
		}
	    }
	    if (module && *module) {
		/* If given a module name, only search corresponding image */
		break;
	    }
	}
    }
#endif /* __LP64__ */
    return addr;
}
CF_PRIVATE CFArrayRef _CFBundleDYLDCopyLoadedImagePathsIfChanged(void) {
    // This returns an array of the paths of all the dyld images in the process.  These paths may not be absolute, they may point at things that are not bundles, they may be staticly linked bundles or dynamically loaded bundles, they may be NULL.
    uint32_t i, numImages = _dyld_image_count();
    CFMutableArrayRef result = NULL;
    static uint32_t _cachedDYLDImageCount = -1;

    if (numImages != _cachedDYLDImageCount) {
        const char *curName;
        char *cleanedCurName = NULL;
        CFStringRef curStr;
        const char *processPath = _CFProcessPath();
        const void *mhp = (const void *)_NSGetMachExecuteHeader();

        result = CFArrayCreateMutable(kCFAllocatorSystemDefault, 0, &kCFTypeArrayCallBacks);

        for (i = 0; i < numImages; i++) {
            curName = _dyld_get_image_name(i);
            if (curName && i == 0) cleanedCurName = _cleanedPathForPath(curName);
            if (curName && (!processPath || 0 != strcmp(curName, processPath)) && (!processPath || !cleanedCurName || 0 != strcmp(cleanedCurName, processPath)) && mhp != (void *)_dyld_get_image_header(i)) {
                curStr = CFStringCreateWithFileSystemRepresentation(kCFAllocatorSystemDefault, curName);
                if (curStr) {
                    CFArrayAppendValue(result, curStr);
                    CFRelease(curStr);
                }
            }
            if (cleanedCurName) {
                free(cleanedCurName);
                cleanedCurName = NULL;
            }
        }
        _cachedDYLDImageCount = numImages;
    }
    return result;
}
Beispiel #23
0
cc_libhandle
cc_dl_open(const char * filename)
{
  cc_libhandle h = new struct cc_libhandle_struct;
  h->nativehnd = NULL;
  h->libname = NULL_STR;

#ifdef HAVE_DL_LIB

#ifdef HAVE_DYLD_RUNTIME_BINDING
  /* Mac OS X: Search for library shipped with bundled Inventor framework
     or directly in application bundle. */

  if (h->nativehnd == NULL) {
    cc_string * path = cc_find_file(filename);
    if (cc_string_length(path) > 0) {
      if (cc_dl_debugging()) {
        cc_debugerror_postinfo("cc_dl_open", "opening: %s", 
                               cc_string_get_text(path));
      }
      h->nativehnd = dlopen(cc_string_get_text(path), 
                            RTLD_LAZY);      
    }
    cc_string_destruct(path);
  }
#endif /* HAVE_DYLD_RUNTIME_BINDING */

  if (h->nativehnd == NULL) {
    /* try loading path-less */
    h->nativehnd = dlopen(filename, RTLD_LAZY);
  }

  /*
    If dlopen() fails for any reason than not being able to find the
    dynamic link-library given by "filename" on disk, we should really
    detect it and report an error, whether we're running in debug mode
    or release mode.

    The libdl interface doesn't provide any means to do that, though,
    so we'll just /assume/ that a NULL return means the library
    couldn't be found.

    But if a special debugging environment variable is found, we'll
    spit out the error message, which could prove useful for remote
    debugging:
  */

  if (cc_dl_debugging() && (h->nativehnd == NULL)) {
    const char * e = dlerror();
    if (e) {
      cc_debugerror_post("cc_dl_open", "dlopen(\"%s\") failed with: '%s'", 
                         filename, e);
    }
  }

#elif defined (HAVE_DYLD_RUNTIME_BINDING) 

  if (filename == NULL) {

    /* 
       Simulate the behaviour of dlopen(NULL) by returning a handle to
       the first image loaded by the dynamic linker, which is the
       current process. See dyld(3).

       Note that this handle is not necessary for the dyld cc_dl_sym()
       implementation, but it makes it possible to use cc_dl_open() in
       the "classic" dlopen() style (where a NULL return value would
       indicate failure).
    */ 
    h->nativehnd = _dyld_get_image_header(0);

  } else {

    /* 
       Note that we must use NSAddImage, since we want to load a
       shared library, instead of NSCreateObjectFileImageFromFile()
       and NSLinkModule(), which work only with loadable
       modules/bundles. See NSModule(3), NSObjectFileImage(3) and
       http://fink.sourceforge.net/doc/porting/shared.php for details.
    */
    cc_string * path = cc_find_file(filename);
    if (cc_string_length(path) > 0) {
      if (cc_dl_debugging()) {
        cc_debugerror_postinfo("cc_dlopen", "opening: %s", 
                               cc_string_get_text(path));
      }

      h->nativehnd = (void *) NSAddImage(cc_string_get_text(path), 
                                         NSADDIMAGE_OPTION_RETURN_ON_ERROR);

      if (cc_dl_debugging() && !h->nativehnd) {
        NSLinkEditErrors c;
        int e;
        const char * file;
        const char * errstr;
        NSLinkEditError(&c, &e, &file, &errstr);
        cc_debugerror_post("cc_dlopen", "%s", errstr);
      }
      cc_string_destruct(path);
    } 
  }

#elif defined (HAVE_WINDLL_RUNTIME_BINDING)

  /* We don't want to call LoadLibrary(NULL) because this causes a
     crash on some Windows platforms (Crashes on Windows2000 has been
     reported). 20021101 thammer.
  */
  if (filename != NULL) {

    /* Don't use GetModuleHandle(): LoadLibrary() will *not* load a
       new image if the module is already loaded, it will only inc the
       reference count.

       Also, GetModuleHandle() doesn't inc the reference count, so it
       is dangerous in the sense that the module could be free'd from
       somewhere else between us opening it, and until it is used for
       resolving symbols.
    */
    h->nativehnd = LoadLibrary(filename);

    if (cc_dl_debugging() && (h->nativehnd == NULL)) {
      cc_string funcstr;
      cc_string_construct(&funcstr);
      cc_string_sprintf(&funcstr, "LoadLibrary(\"%s\")", filename ? filename : "(null)");
      cc_win32_print_error("cc_dl_open", cc_string_get_text(&funcstr), GetLastError());
      cc_string_clean(&funcstr);
    }
  }
  else {
    h->nativehnd = GetModuleHandle(NULL);
    if (cc_dl_debugging() && (h->nativehnd == NULL)) {
      cc_win32_print_error("cc_dl_open", "GetModuleHandle(NULL)", GetLastError());
    }
  }

#elif defined (HAVE_DLD_LIB)

  /* FIXME: there is a good reason to try to use shn_load() *first*,
     then dlopen() on HP-UX: according to a discussion on the libtool
     mailinglist, dlopen() for HP-UX was buggy in an official release,
     needing a patch to function properly. This would take some
     changes to the configure checks (we cut off further checking if
     libdl is found), and any code that depends on _either_
     HAVE_DL_LIB _or_ HAVE_DLD_LIB being defined, but not both at the
     same time.  20010626 mortene. */

  /* This define not available on older versions. */
#ifndef DYNAMIC_PATH
#define DYNAMIC_PATH 0
#endif /* DYNAMIC_PATH */

  /* Handle attempt to look at running executable image and already
     loaded dynamic libraries. */

  if (filename == NULL) {
    shl_t exehnd = (shl_t)0;
    void * dummy;
    int ret = shl_findsym(&exehnd, "main", TYPE_UNDEFINED, &dummy);
    if (ret != -1) {
      h->nativehnd = exehnd;
    }
    else {
      const char * e = strerror(errno);
      cc_debugerror_post("cc_dl_open",
                         "shl_findsym(&NULL, \"main\", ...) failed with: '%s'",
                         e);
    }
  }
  else {
    h->nativehnd = shl_load(filename, BIND_IMMEDIATE|BIND_NONFATAL|DYNAMIC_PATH, 0L);

    /*
      If a special debugging environment variable is found, we'll spit
      out the error message, which could prove useful for remote
      debugging.

      Note that if shl_load() fails for any reason than not being able
      to find the dynamic link-library given by "filename" on disk, we
      detect it and report an error, whether we're running in debug
      mode or release mode. ENOENT means "the specified library does
      not exist" -- all other errors should be warned about no matter
      what.
    */

    if ((h->nativehnd == NULL) && (cc_dl_debugging() || (errno != ENOENT))) {
      const char * e = strerror(errno);
      cc_debugerror_post("cc_dl_open", "shl_load(\"%s\") failed with: '%s'",
                         filename ? filename : "(null)", e);
    }
  }

#endif

  if (h->nativehnd == NULL) {
    delete h;
    h = NULL;
  }
  else {
    h->libname = filename ? filename : NULL_STR;

    if (cc_dl_debugging()) {
#ifdef HAVE_WINDLL_RUNTIME_BINDING
      char libpath[512];
      DWORD retval = GetModuleFileName((HINSTANCE) h->nativehnd, libpath, sizeof(libpath));
      assert(retval > 0 && "GetModuleFileName() failed");
      libpath[sizeof(libpath) - 1] = 0;
      cc_debugerror_postinfo("cc_dl_open", "Opened library '%s'", libpath);
#elif defined (HAVE_DL_LIB) || defined (HAVE_DLD_LIB)
      cc_debugerror_postinfo("cc_dl_open", "Opening library '%s'", h->libname.getString());
#endif
    }
  }

  if (cc_dl_debugging() && h) {
    cc_debugerror_postinfo("cc_dl_open",
                           "\"%s\" success => cc_libhandle==%p, nativehnd==%p", 
                           h->libname.getString(), h, h->nativehnd);
  }

  return h;
}
Beispiel #24
0
EXPORT
DWORD GetImageCount()
{
    uint32_t imagecount;
    int i;
    imagecount = _dyld_image_count();
    for (i=0; i < imagecount; i++)
    {
        printf("Image name: %s %x %x\n", _dyld_get_image_name(i), (uint32_t)_dyld_get_image_vmaddr_slide(i), (uint32_t)_dyld_get_image_header(i));
    }
    return imagecount;
}
plcrash_error_t unwind_current_state (plcrash_async_thread_state_t *state, void *context) {
    plframe_cursor_t cursor;
    plcrash_async_image_list_t image_list;
    plframe_cursor_frame_reader_t **readers = global_harness_state.test_case->frame_readers_dwarf;
    size_t reader_count = 0;
    plframe_error_t err;

    /* Determine the number of frame readers */
    if (readers != NULL) {
        for (reader_count = 0; readers[reader_count] != NULL; reader_count++) {
            
        }
    }

    /* Initialize the image list */
    plcrash_nasync_image_list_init(&image_list, mach_task_self());
    for (uint32_t i = 0; i < _dyld_image_count(); i++)
        plcrash_nasync_image_list_append(&image_list, _dyld_get_image_header(i), _dyld_get_image_name(i));

    /* Initialie our cursor */
    plframe_cursor_init(&cursor, mach_task_self(), state, &image_list);

    /* Walk the frames until we hit the test function */
    for (uint32_t i = 0; i < global_harness_state.test_case->intermediate_frames; i++) {
        if ((err = plframe_cursor_next(&cursor)) != PLFRAME_ESUCCESS) {
            PLCF_DEBUG("Step failed: %d", err);
            return PLCRASH_EINVAL;
        }
    }

    /* Now in test function; Unwind using the specified readers */
    if (readers != NULL) {
        /* Issue the read */
        err = plframe_cursor_next_with_readers(&cursor, global_harness_state.test_case->frame_readers_dwarf, reader_count);
    } else {
        /* Use default readers */
        err = plframe_cursor_next(&cursor);
    }
    
    if (err != PLFRAME_ESUCCESS) {
        PLCF_DEBUG("Step within test function failed: %d", err);
        return PLFRAME_EINVAL;
    }

    /* Now in unwind_tester; verify that we unwound to the correct IP */
    plcrash_greg_t ip;
    if (plframe_cursor_get_reg(&cursor, PLCRASH_REG_IP, &ip) != PLFRAME_ESUCCESS) {
        PLCF_DEBUG("Could not fetch IP from register state");
        __builtin_trap();
    }
    if (ip != (plcrash_greg_t) unwind_tester_target_ip) {
        PLCF_DEBUG("Incorrect IP. ip=%" PRIx64 " target_ip=%" PRIx64, (uint64_t) ip, (uint64_t) unwind_tester_target_ip);
        __builtin_trap();
    }

    /*
     * For tests using DWARF or compact unwinding, verify that non-volatile registers have been restored.
     * This replaces the use of thread state restoration in the original libunwind tests; rather
     * than letting the unwind_tester() perform these register value tests,
     * we just do so ourselves
     */
    if (!global_harness_state.test_case->restores_callee_registers)
        return PLCRASH_ESUCCESS;

    VERIFY_NV_REG(&cursor, PLCRASH_REG_SP, (plcrash_greg_t)global_harness_state.test_case->expected_sp);
#ifdef __x86_64__
    VERIFY_NV_REG(&cursor, PLCRASH_X86_64_RBX, 0x1234567887654321);
    VERIFY_NV_REG(&cursor, PLCRASH_X86_64_R12, 0x02468ACEECA86420);
    VERIFY_NV_REG(&cursor, PLCRASH_X86_64_R13, 0x13579BDFFDB97531);
    VERIFY_NV_REG(&cursor, PLCRASH_X86_64_R14, 0x1122334455667788);
    VERIFY_NV_REG(&cursor, PLCRASH_X86_64_R15, 0x0022446688AACCEE);
#elif (__i386__)
    VERIFY_NV_REG(&cursor, PLCRASH_X86_EBX, 0x12344321);
    VERIFY_NV_REG(&cursor, PLCRASH_X86_ESI, 0x56788765);
    VERIFY_NV_REG(&cursor, PLCRASH_X86_EDI, 0xABCDDCBA);
#elif (__arm64__)
    VERIFY_NV_REG(&cursor, PLCRASH_ARM64_X19, 0x1234567887654321);
    VERIFY_NV_REG(&cursor, PLCRASH_ARM64_X20, 0x02468ACEECA86420);
    VERIFY_NV_REG(&cursor, PLCRASH_ARM64_X21, 0x13579BDFFDB97531);
    VERIFY_NV_REG(&cursor, PLCRASH_ARM64_X22, 0x1122334455667788);
    VERIFY_NV_REG(&cursor, PLCRASH_ARM64_X23, 0x0022446688AACCEE);
    VERIFY_NV_REG(&cursor, PLCRASH_ARM64_X24, 0x0033557799BBDDFF);
    VERIFY_NV_REG(&cursor, PLCRASH_ARM64_X25, 0x00446688AACCEE00);
    VERIFY_NV_REG(&cursor, PLCRASH_ARM64_X26, 0x006688AACCEEFF11);
    VERIFY_NV_REG(&cursor, PLCRASH_ARM64_X27, 0x0088AACCEEFF1133);
    VERIFY_NV_REG(&cursor, PLCRASH_ARM64_X28, 0xCAFEDEADF00DBEEF);
#endif
    return PLCRASH_ESUCCESS;
}
Beispiel #26
0
bool Instance_LocateModule(char * name, char * fileName)
{
#if defined(__WIN32__)
   HMODULE hModule = null;
   if(name && name[0])
   {
      uint16 _wmoduleName[MAX_LOCATION];
      UTF8toUTF16Buffer(name, _wmoduleName, MAX_LOCATION);
      hModule = GetModuleHandle(_wmoduleName);
      if(!hModule)
      {
         wcscat(_wmoduleName, L".exe");
         hModule = GetModuleHandle(_wmoduleName);
      }
      if(hModule)
      {
         uint16 _wfileName[MAX_LOCATION];
         GetModuleFileNameW(hModule, _wfileName, MAX_LOCATION);
         UTF16toUTF8Buffer(_wfileName, (byte *)fileName, MAX_LOCATION);
         return true;
      }
   }
   else
   {
      uint16 _wfileName[MAX_LOCATION];
      GetModuleFileNameW(null, _wfileName, MAX_LOCATION);
      UTF16toUTF8Buffer(_wfileName, (byte *)fileName, MAX_LOCATION);
      return true;
   }
#elif defined(__APPLE__)
   if(name && name[0])
   {
      int imageCount = _dyld_image_count();
      int c;
      int nameLen = strlen(name);
      for(c = 0; c<imageCount; c++)
      {
         struct mach_header * header = _dyld_get_image_header(c);
         char * path = _dyld_get_image_name(c);
         int pathLen = strlen(path);
         char * subStr = RSearchString(path, name, pathLen, false, false);
         if(subStr)
         {
            if(( *(subStr-1) == '/' || !strncmp(subStr - 4, "/lib", 4)) &&
               (!subStr[nameLen] || !strncmp(subStr + nameLen, ".dylib", 6)))
            {
               strcpy(fileName, path);
               return true;
            }
         }
      }
   }
   else
   {
      int size = MAX_LOCATION;
      _NSGetExecutablePath(fileName, &size);
      return true;
   }
#elif defined(__unix__)
   //File f = FileOpen("/proc/self/maps", read);
   FILE * f;
   char exeName[MAX_FILENAME];
   exeName[0] = 0;
#if defined(__linux__)
   f = fopen("/proc/self/status", "r");
#else
   f = fopen("/proc/curproc/status", "r");
#endif
   if(f)
   {
      char line[1025];
      while(fgets(line, sizeof(line), f))
      {
         char * name = strstr(line, "Name:\t");
         if(name)
         {
            int nameLen;
            name += 6;
            nameLen = strlen(name);
            name[--nameLen] = 0;
            strcpy(exeName, name);
            break;
         }
      }
      fclose(f);
  }
#if defined(__linux__)
   f = fopen("/proc/self/maps", "r");
#else
   f = fopen("/proc/curproc/map", "r");
#endif
   if(f)
   {
      char line[1025];
      //while(f.GetLine(line, sizeof(line)))
      while(fgets(line, sizeof(line), f))
      {
         char * path = strstr(line, "/");
         if(path)
         {
            int pathLen = strlen(path);
            path[--pathLen] = 0;
            if(name && name[0])
            {
               int nameLen = strlen(name);
               char * subStr;
               subStr = RSearchString(path, name, pathLen, false, false);
               if(subStr)
               {
                  if(( *(subStr-1) == '/' || !strncmp(subStr - 4, "/lib", 4)) &&
                     (!subStr[nameLen] || !strncmp(subStr + nameLen, ".so", 3)))
                  {
                     char * space = strchr(path, ' ');
                     if(space) *space = 0;
                     strcpy(fileName, path);
                     fclose(f);
                     return true;
                  }
               }
            }
            else
            {
               char name[MAX_FILENAME];
               GetLastDirectory(path, name);
               if(!exeName[0] || !strcmp(name, exeName))
               {
                  char * space = strchr(path, ' ');
                  if(space) *space = 0;
                  strcpy(fileName, path);
                  fclose(f);
                  return true;
               }
            }
         }
      }
      fclose(f);
   }
   if(!name || !name[0])
   {
      strcpy(fileName, exeLocation);
      return true;
   }
#endif
   return false;
}
Beispiel #27
0
bool ksdl_getBinaryImage(int index, KSBinaryImage* buffer)
{
    const struct mach_header* header = _dyld_get_image_header((unsigned)index);
    if(header == NULL)
    {
        return false;
    }
    
    uintptr_t cmdPtr = firstCmdAfterHeader(header);
    if(cmdPtr == 0)
    {
        return false;
    }
    
    // Look for the TEXT segment to get the image size.
    // Also look for a UUID command.
    uint64_t imageSize = 0;
    uint64_t imageVmAddr = 0;
    uint8_t* uuid = NULL;
    
    for(uint32_t iCmd = 0; iCmd < header->ncmds; iCmd++)
    {
        struct load_command* loadCmd = (struct load_command*)cmdPtr;
        switch(loadCmd->cmd)
        {
            case LC_SEGMENT:
            {
                struct segment_command* segCmd = (struct segment_command*)cmdPtr;
                if(strcmp(segCmd->segname, SEG_TEXT) == 0)
                {
                    imageSize = segCmd->vmsize;
                    imageVmAddr = segCmd->vmaddr;
                }
                break;
            }
            case LC_SEGMENT_64:
            {
                struct segment_command_64* segCmd = (struct segment_command_64*)cmdPtr;
                if(strcmp(segCmd->segname, SEG_TEXT) == 0)
                {
                    imageSize = segCmd->vmsize;
                    imageVmAddr = segCmd->vmaddr;
                }
                break;
            }
            case LC_UUID:
            {
                struct uuid_command* uuidCmd = (struct uuid_command*)cmdPtr;
                uuid = uuidCmd->uuid;
                break;
            }
        }
        cmdPtr += loadCmd->cmdsize;
    }

    buffer->address = (uintptr_t)header;
    buffer->vmAddress = imageVmAddr;
    buffer->size = imageSize;
    buffer->name = _dyld_get_image_name((unsigned)index);
    buffer->uuid = uuid;
    buffer->cpuType = header->cputype;
    buffer->cpuSubType = header->cpusubtype;
    
    return true;
}
primitiveExecutableModulesAndOffsets(void)
{
    const struct mach_header *h;
    const struct mach_header_64 *h64;
    sqInt i;
    const char *name;
    char *nameObjData;
    sqInt nimages;
    sqInt resultObj;
    const struct section *s;
    const struct section_64 *s64;
    usqIntptr_t size;
    usqIntptr_t slide;
    usqIntptr_t start;
    sqInt valueObj;

	
#  if MAC_OS_X_VERSION_MIN_REQUIRED <= MAC_OS_X_VERSION_10_4

	/* _dyld_present was deprecated in 10.5 */
	if (!(_dyld_present())) {
		return primitiveFail();
	}

#  endif /* MAC_OS_X_VERSION_MIN_REQUIRED <= MAC_OS_X_VERSION_10_4 */

	nimages = _dyld_image_count();
	resultObj = instantiateClassindexableSize(classArray(), nimages * 4);
	if (resultObj == 0) {
		return primitiveFail();
	}
	pushRemappableOop(resultObj);
	for (i = 0; i < nimages; i += 1) {

		/* impossible start & size */
		start = (size = -1);
		name = _dyld_get_image_name(i);
		slide = _dyld_get_image_vmaddr_slide(i);
		
#    if __x86_64__
		h64 = (const struct mach_header_64 *)_dyld_get_image_header(i);
		if (!(h64 == null)) {
			s64 = getsectbynamefromheader_64(h64,SEG_TEXT,SECT_TEXT);
			if (!(s64 == null)) {
				start = s64->addr;
				size = s64->size;
			}
		}

#    else /* __x86_64__ */
		h = _dyld_get_image_header(i);
		if (!(h == null)) {
			s = getsectbynamefromheader(h,SEG_TEXT,SECT_TEXT);
			if (!(s == null)) {
				start = s->addr;
				size = s->size;
			}
		}

#    endif /* __x86_64__ */

		valueObj = instantiateClassindexableSize(classString(), strlen(name));
		if (failed()) {
			popRemappableOop();
			return primitiveFail();
		}
		storePointerofObjectwithValue(i * 4, topRemappableOop(), valueObj);
		nameObjData = arrayValueOf(valueObj);
		memcpy(nameObjData, name, strlen(name));
		valueObj = (BytesPerWord == 8
			? signed64BitIntegerFor(slide)
			: signed32BitIntegerFor(slide));
		if (failed()) {
			popRemappableOop();
			return primitiveFail();
		}
		storePointerofObjectwithValue((i * 4) + 1, topRemappableOop(), valueObj);
		/* begin positiveMachineIntegerFor: */
		valueObj = (BytesPerWord == 8
			? positive64BitIntegerFor(start)
			: positive32BitIntegerFor(start));
		if (failed()) {
			popRemappableOop();
			return primitiveFail();
		}
		storePointerofObjectwithValue((i * 4) + 2, topRemappableOop(), valueObj);
		/* begin positiveMachineIntegerFor: */
		valueObj = (BytesPerWord == 8
			? positive64BitIntegerFor(size)
			: positive32BitIntegerFor(size));
		if (failed()) {
			popRemappableOop();
			return primitiveFail();
		}
		storePointerofObjectwithValue((i * 4) + 3, topRemappableOop(), valueObj);
	}
	resultObj = popRemappableOop();
	return popthenPush(1, resultObj);
}
void BacktraceNames::FromAddr( const void *p )
{
	Address = (intptr_t) p;

	/* Find the image with the given pointer. */
	int index = osx_find_image( p );
	if( index == -1 )
		return;

	File = _dyld_get_image_name( index );

	/* Find the link-edit pointer. */
	const char *link_edit = osx_find_link_edit( _dyld_get_image_header(index) );
	if( link_edit == NULL )
		return;
	link_edit += _dyld_get_image_vmaddr_slide( index );

	unsigned long addr = (unsigned long)p - _dyld_get_image_vmaddr_slide(index);
	const struct mach_header *header = _dyld_get_image_header( index );
	const struct load_command *cmd = (struct load_command *) &header[1];
	unsigned long diff = 0xffffffff;

        const char *dli_sname = NULL;
        void *dli_saddr = NULL;

	for( unsigned long i = 0; i < header->ncmds; i++, cmd = next_load_command(cmd) )
	{
		if( cmd->cmd != LC_SYMTAB )
			continue;

		const symtab_command *scmd = (const symtab_command *) cmd;
		struct nlist *symtable = (struct nlist *)( link_edit + scmd->symoff );
		for( unsigned long  j = 0; j < scmd->nsyms; j++ )
		{
			if( !symtable[j].n_value )
				continue; /* Undefined */
			if( symtable[j].n_type >= N_PEXT )
				continue; /* Debug symbol */

			if( addr >= symtable[j].n_value && diff >= (addr - symtable[j].n_value) )
			{
				diff = addr - (unsigned long)symtable[j].n_value;
				dli_saddr = symtable[j].n_value + ((char *)p - addr);
				dli_sname = (const char *)( link_edit + scmd->stroff + symtable[j].n_un.n_strx );
			}
		}
	}

	if( diff == 0xffffffff )
		return;

	Symbol = dli_sname;
	Offset = (char*)(p)-(char*)dli_saddr;

	/*
	 * __start   -> _start
	 * __ZN7RageLog5TraceEPKcz -> _ZN7RageLog5TraceEPKcz (so demangling will work)
	 */
	if( Symbol.Left(1) == "_" )
		Symbol = Symbol.substr(1);
	/* After stripping off the leading _
	 * _GLOBAL__I__ZN5ModelC2Ev -> _ZN5ModelC2Ev
	 * _GLOBAL__D__Z12ForceToAsciiR7CStdStrIcE -> _Z12ForceToAsciiR7CStdStrIcE
	 */
	if( Symbol.Left(9) == "_GLOBAL__" )
		Symbol = Symbol.substr(11);
	
}
Beispiel #30
0
static ssize_t MSMachONameList_(const void *stuff, struct MSSymbolData *list, size_t nreq) {
    // XXX: ok, this is just pathetic; API fail much?
    size_t slide(0);
    for (uint32_t image(0), images(_dyld_image_count()); image != images; ++image)
        if (_dyld_get_image_header(image) == stuff) {
            slide = _dyld_get_image_vmaddr_slide(image);
            goto fat;
        }

    return -1;

fat:
    const uint8_t *base(reinterpret_cast<const uint8_t *>(stuff));
    const struct exec *buf(reinterpret_cast<const struct exec *>(base));

    if (OSSwapBigToHostInt32(buf->a_magic) == FAT_MAGIC) {
        struct host_basic_info hbi;
        {
            host_t host(mach_host_self());
            mach_msg_type_number_t count(HOST_BASIC_INFO_COUNT);
            if (host_info(host, HOST_BASIC_INFO, reinterpret_cast<host_info_t>(&hbi), &count) != KERN_SUCCESS)
                return -1;
            mach_port_deallocate(mach_task_self(), host);
        }

        const struct fat_header *fh(reinterpret_cast<const struct fat_header *>(base));
        uint32_t nfat_arch(OSSwapBigToHostInt32(fh->nfat_arch));
        const struct fat_arch *fat_archs(reinterpret_cast<const struct fat_arch *>(fh + 1));

        for (uint32_t i(0); i != nfat_arch; ++i)
            if (static_cast<cpu_type_t>(OSSwapBigToHostInt32(fat_archs[i].cputype)) == hbi.cpu_type) {
                buf = reinterpret_cast<const struct exec *>(base + OSSwapBigToHostInt32(fat_archs[i].offset));
                goto thin;
            }

        return -1;
    }

thin:
    const nlist_xx *symbols;
    const char *strings;
    size_t n;

    // XXX: this check looks really scary when it fails
    if (buf->a_magic == MH_MAGIC_XX) {
        const mach_header_xx *mh(reinterpret_cast<const mach_header_xx *>(base));
        const struct load_command *load_commands(reinterpret_cast<const struct load_command *>(mh + 1));

        const struct symtab_command *stp(NULL);
        const struct load_command *lcp;

        /* forlc (command, mh, LC_SYMTAB, struct symtab_command) {
            stp = command;
            goto found;
        } */

        lcp = load_commands;
        for (uint32_t i(0); i != mh->ncmds; ++i) {
            if (
                lcp->cmdsize % sizeof(long) != 0 || lcp->cmdsize <= 0 ||
                reinterpret_cast<const uint8_t *>(lcp) + lcp->cmdsize > reinterpret_cast<const uint8_t *>(load_commands) + mh->sizeofcmds
            )
                return -1;

            if (lcp->cmd == LC_SYMTAB) {
                if (lcp->cmdsize != sizeof(struct symtab_command))
                    return -1;
                stp = reinterpret_cast<const struct symtab_command *>(lcp);
                goto found;
            }

            lcp = reinterpret_cast<const struct load_command *>(reinterpret_cast<const uint8_t *>(lcp) + lcp->cmdsize);
        }

        return -1;

found:
        n = stp->nsyms;

        symbols = NULL;
        strings = NULL;

        /* forlc (command, mh, LC_SEGMENT_XX, segment_command_xx) {
            stp = command;
            goto found;
        } */

        lcp = load_commands;
        for (uint32_t i(0); i != mh->ncmds; ++i) {
            if (
                lcp->cmdsize % sizeof(long) != 0 || lcp->cmdsize <= 0 ||
                reinterpret_cast<const uint8_t *>(lcp) + lcp->cmdsize > reinterpret_cast<const uint8_t *>(load_commands) + mh->sizeofcmds
            )
                return -1;

            if (lcp->cmd == LC_SEGMENT_XX) {
                if (lcp->cmdsize < sizeof(segment_command_xx))
                    return -1;
                const segment_command_xx *segment(reinterpret_cast<const segment_command_xx *>(lcp));
                if (stp->symoff >= segment->fileoff && stp->symoff < segment->fileoff + segment->filesize)
                    symbols = reinterpret_cast<const nlist_xx *>(stp->symoff - segment->fileoff + segment->vmaddr + slide);
                if (stp->stroff >= segment->fileoff && stp->stroff < segment->fileoff + segment->filesize)
                    strings = reinterpret_cast<const char *>(stp->stroff - segment->fileoff + segment->vmaddr + slide);
            }

            lcp = reinterpret_cast<const struct load_command *>(reinterpret_cast<const uint8_t *>(lcp) + lcp->cmdsize);
        }

        if (symbols == NULL || strings == NULL)
            return -1;
        // XXX: detect a.out somehow?
    } else if (false) {
        /* XXX: is this right anymore?!? */
        symbols = reinterpret_cast<const nlist_xx *>(base + N_SYMOFF(*buf));
        strings = reinterpret_cast<const char *>(reinterpret_cast<const uint8_t *>(symbols) + buf->a_syms);
        n = buf->a_syms / sizeof(nlist_xx);
    } else return -1;

    size_t result(nreq);

    for (size_t m(0); m != n; ++m) {
        const nlist_xx *q(&symbols[m]);
        if (q->n_un.n_strx == 0 || (q->n_type & N_STAB) != 0)
            continue;

        const char *nambuf(strings + q->n_un.n_strx);
        //fprintf(stderr, " == %s\n", nambuf);

        for (size_t item(0); item != nreq; ++item) {
            struct MSSymbolData *p(list + item);
            if (p->name_ == NULL || strcmp(p->name_, nambuf) != 0)
                continue;

            p->name_ = NULL;

            p->value_ = q->n_value;
            if (p->value_ != 0)
                p->value_ += slide;

            p->type_ = q->n_type;
            p->desc_ = q->n_desc;
            p->sect_ = q->n_sect;

            if (--result == 0)
                return 0;
            break;
        }
    }

    return result;
}