示例#1
0
/* Return the image index of the given pointer, or -1 if not found. */
int osx_find_image( const void *p )
{
	unsigned long image_count = _dyld_image_count();

	for( unsigned i = 0; i < image_count; i++ )
	{
		const struct mach_header *header = _dyld_get_image_header(i);
		if( header == NULL )
			continue;

		/* The load commands directly follow the mach_header. */
		const struct load_command *cmd = (struct load_command *) &header[1];

		for( unsigned j = 0; j < header->ncmds; j++ )
		{
			/* We only care about mapped segments. */
			if( cmd->cmd != LC_SEGMENT )
			{
				cmd = next_load_command(cmd);
				continue;
			}

			const segment_command *scmd = (const segment_command *) cmd;

			const unsigned long bottom = scmd->vmaddr + _dyld_get_image_vmaddr_slide( i );
			const unsigned long top = scmd->vmaddr + scmd->vmsize + _dyld_get_image_vmaddr_slide( i );
			if ( (unsigned long) p >= bottom && (unsigned long) p < top )
				return i;

			cmd = next_load_command(cmd);
		}
	}

	return -1;
}
示例#2
0
	static const struct mach_header *FindOwnerOfPC(unsigned int pc)
	{
		unsigned int			count,index,offset,cmdex;
		struct segment_command	*seg;
		struct load_command		*cmd;
		const struct mach_header*header;
		
		count = _dyld_image_count();
		for (index = 0;index < count;index += 1)
		{
			header = _dyld_get_image_header(index);
			offset = _dyld_get_image_vmaddr_slide(index);
			cmd = (struct load_command*)((char*)header + sizeof(struct mach_header));
			for (cmdex = 0;cmdex < header->ncmds;cmdex += 1,cmd = (struct load_command*)((char*)cmd + cmd->cmdsize))
			{
				switch(cmd->cmd)
				{
					case LC_SEGMENT:
						seg = (struct segment_command*)cmd;
						if ((pc >= (seg->vmaddr + offset)) && (pc < (seg->vmaddr + offset + seg->vmsize)))
							return header;
						break;
				}
			}
		}
		
		return NULL;
	}
示例#3
0
static gboolean
find_image_address_and_slide (const gchar * image_name,
                              gpointer * address,
                              gpointer * slide)
{
  gboolean name_is_absolute;
  guint count, idx;

  name_is_absolute = index (image_name, '/') != NULL;

  count = _dyld_image_count ();

  for (idx = 0; idx != count; idx++)
  {
    const gchar * name, * s;

    name = _dyld_get_image_name (idx);
    if (!name_is_absolute && (s = strrchr (name, '/')) != NULL)
      name = s + 1;

    if (strcmp (name, image_name) == 0)
    {
      *address = (gpointer) _dyld_get_image_header (idx);
      *slide = (gpointer) _dyld_get_image_vmaddr_slide (idx);
      return TRUE;
    }
  }

  return FALSE;
}
示例#4
0
static inline void *getTMCloneTable (const void *f, size_t *tmct_siz)
{
  char *tmct_fixed, *tmct = NULL;
  unsigned int i, img_count; 
  struct mach_header *mh;
  Dl_info info;
  
  if (! dladdr (f, &info) || info.dli_fbase == NULL)
    abort ();
  
  mh = (struct mach_header *) info.dli_fbase;
  tmct_fixed = GET_DATA_TMCT (mh, tmct_siz);
  *tmct_siz /= (sizeof (size_t) * 2);
  /* No tm_clone_table or no clones. */
  if (tmct_fixed == NULL || *tmct_siz == 0)
    return NULL; 

  img_count = _dyld_image_count();
  for (i = 0; i < img_count && tmct == NULL; i++)
    {
      if (mh == _dyld_get_image_header(i))
	tmct = tmct_fixed + (unsigned long)_dyld_get_image_vmaddr_slide(i); 
    }

  return tmct;
}
示例#5
0
bool interpose() {
    const struct mach_header_native *mach_hdr;
    uint32_t i;
    for(i = 0; (mach_hdr = (void *) _dyld_get_image_header(i)); i++) {
        find_lazy(mach_hdr->ncmds, (void *) (mach_hdr + 1), _dyld_get_image_vmaddr_slide(i));
    }
    return true;
}
示例#6
0
static inline void *get_real_address(void *addr) {
    if (!addr)
        return NULL;

    // We need to slide the section address to get a valid pointer
    // because ASLR will shift the image by a random offset
    return addr + _dyld_get_image_vmaddr_slide(BASE_IMAGE_INDEX);
}
示例#7
0
文件: mach.c 项目: dseev/memprof
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;
    }
  }
}
示例#8
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;
}
示例#9
0
init_(void)
{
	struct import_t table[] = {
		{ 0, "_dlsym" },
		{ 0, NULL }
	};
	int rv = find_stubs((void *)_dyld_get_image_header(0), table);
	intptr_t slide = _dyld_get_image_vmaddr_slide(0);
	if (rv == 1 && table[0].a) {
		my_printf("hooked %lx %s\n", table[0].a, table[0].s);
		*(void **)(table[0].a + slide) = (void *)my_dlsym;
	}
}
示例#10
0
/*
 * find the memory address where the target was loaded to
 * this is due to full ASLR in Lion
 * we also use it for Snow Leopard to avoid opening the binary and parse the mach-o header
 */
int
find_image(struct header_info *hi)
{
    // get mach-o header of iTunes image (main binary is usually (always?) index 0)
    // XXX: this can be made error-proof by iterating all images and match iTunes
    const struct mach_header *mh = _dyld_get_image_header(0);
    intptr_t aslr_slide = _dyld_get_image_vmaddr_slide(0);
    DEBUG_MSG("Aslr slide is %p\n", (void*)aslr_slide);

    hi->mh = (const struct mach_header_64*)mh;
    hi->aslr_slide = aslr_slide;
    
    // compute iTunes image size
    uint64_t image_size = 0;
    if (mh->magic != MH_MAGIC_64)
    {
        return -1;
    }
    
    if (mh->ncmds == 0 || mh->sizeofcmds == 0)
    {
        ERROR_MSG("Invalid number of commands or size.");
    }
    
    struct load_command *load_cmd = NULL;
    char *load_cmd_addr = (char*)mh + sizeof(struct mach_header_64);
    
    for (uint32_t i = 0; i < mh->ncmds; i++)
    {
        load_cmd = (struct load_command*)load_cmd_addr;
        if (load_cmd->cmd == LC_SEGMENT_64)
        {
            struct segment_command_64 *seg_cmd = (struct segment_command_64*)load_cmd;
            image_size += seg_cmd->vmsize;
        }
        load_cmd_addr += load_cmd->cmdsize;
    }
    
    if (image_size != 0)
    {
        hi->image_size = image_size;
        return 0;
    }
    else
    {
        /* failure */
        return -1;
    }
}
示例#11
0
const void* ksdl_getSymbolAddrInImage(uint32_t imageIdx, const char* symbolName)
{
    const struct mach_header* header = _dyld_get_image_header(imageIdx);
    if(header == NULL)
    {
        return NULL;
    }
    const uintptr_t imageVMAddrSlide = (uintptr_t)_dyld_get_image_vmaddr_slide(imageIdx);
    const uintptr_t segmentBase = ksdl_segmentBaseOfImageIndex(imageIdx) + imageVMAddrSlide;
    if(segmentBase == 0)
    {
        return NULL;
    }
    uintptr_t cmdPtr = ksdl_firstCmdAfterHeader(header);
    if(cmdPtr == 0)
    {
        return NULL;
    }
    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)
                {
                    const char* sname = (char*)((intptr_t)stringTable + (intptr_t)symbolTable[iSym].n_un.n_strx);
                    if(*sname == '_')
                    {
                        sname++;
                    }
                    if(strcmp(sname, symbolName) == 0)
                    {
                        return (void*)(symbolTable[iSym].n_value + imageVMAddrSlide);
                    }
                }
            }
        }
        cmdPtr += loadCmd->cmdsize;
    }
    return NULL;
}
示例#12
0
int rebind_symbols(struct rebinding rebindings[], size_t rebindings_nel) {
  int retval = prepend_rebindings(&_rebindings_head, rebindings, rebindings_nel);
  if (retval < 0) {
    return retval;
  }
  // If this was the first call, register callback for image additions (which is also invoked for
  // existing images, otherwise, just run on existing images
  if (!_rebindings_head->next) {
    _dyld_register_func_for_add_image(_rebind_symbols_for_image);
  } else {
    uint32_t c = _dyld_image_count();
    for (uint32_t i = 0; i < c; i++) {
      _rebind_symbols_for_image(_dyld_get_image_header(i), _dyld_get_image_vmaddr_slide(i));
    }
  }
  return retval;
}
示例#13
0
uint32_t ksdl_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 = ksdl_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;
}
示例#14
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);
}
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;
}
示例#16
0
void SDMDaodanDumpLibraryInfo(char *dumpPath, struct SDMSTLibrary *libTable) {
	char *filePath = calloc(0x1, sizeof(char)*(strlen(dumpPath)+0x1+0xd));
	sprintf(filePath, "%sLibraries.txt",dumpPath);
	FILE *file = fopen(filePath, "w");
	if (file) {
		SDMDaodanWriteHeaderInDumpFile("Linked Libraries\n",file);
		for (uint32_t i = 0x0; i < libTable->dependencyCount; i++) {
			char *path = (char *)(libTable->dependency[i].loadCmd + libTable->dependency[i].dyl.dylib.name.offset);
			uintptr_t slide;
			if (libTable->couldLoad) {
				slide = _dyld_get_image_vmaddr_slide(SDMGetIndexForLibraryPath(path));
				char *slideAndPath = calloc(0x1, sizeof(char)*(strlen(path)+0x15));
				sprintf(slideAndPath, "\t0x%016lx %s\n",slide,path);
				FWRITE_STRING_TO_FILE(slideAndPath, file);
				free(slideAndPath);
			}
		}
		
		fclose(file);
	}
	free(filePath);
}
示例#17
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);
}
示例#18
0
void SDMDaodanDumpSymbolInfo(char *dumpPath, struct SDMSTLibrary *libTable) {
	char *filePath = calloc(0x1, sizeof(char)*(strlen(dumpPath)+0x1+0xb));
	sprintf(filePath, "%sSymbols.txt",dumpPath);
	FILE *file = fopen(filePath, "w");
	if (file) {
		SDMDaodanWriteHeaderInDumpFile("Symbol Table\n",file);
		for (uint32_t i = 0x0; i < libTable->symbolCount; i++) {
			char *symbolName = (char *)(libTable->table[i].name);
			char *nameAndOffset = calloc(0x1, sizeof(char)*(strlen(symbolName)+0x100));
			uintptr_t slide;
			if (libTable->couldLoad) {
				slide = _dyld_get_image_vmaddr_slide(libTable->libInfo->imageNumber);
			} else {
				slide = (uintptr_t)(libTable->libInfo->mhOffset);
			}
			sprintf(nameAndOffset, "\t0x%016lx %s\n",((libTable->table[i].offset)-slide),symbolName);
			FWRITE_STRING_TO_FILE(nameAndOffset, file);
			free(nameAndOffset);
		}
		
		fclose(file);
	}
	free(filePath);
}
示例#19
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;
}
示例#20
0
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);
	
}
示例#21
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;
    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 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
}
示例#24
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;
}
示例#25
0
文件: plbt.c 项目: darksage/lispbox
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;
}
示例#26
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;
}
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);
}