예제 #1
0
파일: SystemInfo.cpp 프로젝트: MrMC/mrmc
int CSysInfo::GetKernelBitness(void)
{
  static int kernelBitness = -1;
  if (kernelBitness == -1)
  {
#if defined(TARGET_DARWIN_IOS)
    // Note: OS X return x86 CPU type without CPU_ARCH_ABI64 flag
    const NXArchInfo* archInfo = NXGetLocalArchInfo();
    if (archInfo)
      kernelBitness = ((archInfo->cputype & CPU_ARCH_ABI64) != 0) ? 64 : 32;
#elif defined(TARGET_POSIX)
    struct utsname un;
    if (uname(&un) == 0)
    {
      std::string machine(un.machine);
      if (machine == "x86_64" || machine == "amd64" || machine == "arm64" || machine == "aarch64" || machine == "ppc64" ||
          machine == "ia64" || machine == "mips64")
        kernelBitness = 64;
      else
        kernelBitness = 32;
    }
#endif
    if (kernelBitness == -1)
      kernelBitness = 0; // can't detect
  }

  return kernelBitness;
}
예제 #2
0
unsigned short getCpuHash()            
{         
	const NXArchInfo* info = NXGetLocalArchInfo();    
	unsigned short val = 0;            
	val += (unsigned short)info->cputype;               
	val += (unsigned short)info->cpusubtype;            
	return val;             
}
예제 #3
0
/**
 * \fn cpu_type_t moa_working_arch(void)
 * \brief Returns the arch of the computer.
 *
 * \return Constant associated to the arch of the computer.
 */
cpu_type_t
moa_working_arch(void)
{
	const NXArchInfo* arch_info = NXGetLocalArchInfo();
	if (NULL == arch_info)
		return CPU_TYPE_ANY;
	return arch_info->cputype;
}
static const char *
get_arch_name (const char *name)
{
  NXArchInfo * a_info;
  const NXArchInfo * all_info;
  cpu_type_t cputype;
  struct arch_config_guess_map *map;
  const char *aname;

  if (name) {
    /* Find config name based on arch name.  */
    aname = NULL;
    map = arch_config_map;
    while (map->arch_name) {
      if (!strcmp (map->arch_name, name))
	return name;
      else map++;
    }
    a_info = (NXArchInfo *) NXGetArchInfoFromName (name);
    /* radr://7148788  emit diagnostic for ARM architectures not explicitly
     * handled by the driver. */
    if (a_info && a_info->cputype == CPU_TYPE_ARM)
      a_info = NULL;
  } else {
    a_info = (NXArchInfo *) NXGetLocalArchInfo();
    if (a_info) {
      if (dash_m32_seen) {
        /* If -m32 is seen then do not change cpu type.  */
      } else if (dash_m64_seen) {
        /* If -m64 is seen then enable CPU_ARCH_ABI64.  */
	a_info->cputype |= CPU_ARCH_ABI64;
      } else if (sizeof (long) == 8)
	/* On x86, by default (name is NULL here) enable 64 bit code.  */
	a_info->cputype |= CPU_ARCH_ABI64;
    }
  }

  if (!a_info)
    fatal ("Invalid arch name : %s", name);

  all_info = NXGetAllArchInfos();

  if (!all_info)
    fatal ("Unable to get architecture information");

  /* Find first arch. that matches cputype.  */
  cputype = a_info->cputype;

  while (all_info->name)
    {
      if (all_info->cputype == cputype)
	break;
      else
	all_info++;
    }

  return all_info->name;
}
예제 #5
0
static wi_process_t * _wi_process_init_with_argv(wi_process_t *process, int argc, const char **argv) {
	wi_array_t			*array;
	wi_string_t			*string;
	struct utsname		name;
#if defined(HAVE_NXGETLOCALARCHINFO)
	const NXArchInfo	*archinfo;
	cpu_type_t			cputype;
	size_t				cputypesize;
#elif defined(HAVE_SYSINFO) && defined(SI_ARCHITECTURE)
	char				buffer[SYS_NMLN];
#endif

	
	array = wi_array_init_with_argv(wi_array_alloc(), argc, argv);
	
	string = wi_array_first_data(array);
	
	if(string) {
		process->path = wi_retain(string);
		process->name = wi_retain(wi_string_last_path_component(process->path));
	} else {
		process->path = wi_retain(WI_STR("unknown"));
		process->name = wi_retain(process->path);
	}
	
	if(wi_array_count(array) <= 1)
		process->arguments = wi_array_init(wi_array_alloc());
	else
		process->arguments = wi_retain(wi_array_subarray_with_range(array, wi_make_range(1, wi_array_count(array) - 1)));
	
	wi_release(array);
	
	uname(&name);
	
	process->os_name = wi_string_init_with_cstring(wi_string_alloc(), name.sysname);
	process->os_release = wi_string_init_with_cstring(wi_string_alloc(), name.release);

#if defined(HAVE_NXGETLOCALARCHINFO)
	cputypesize = sizeof(cputype);
	
	if(sysctlbyname("sysctl.proc_cputype", &cputype, &cputypesize, NULL, 0) < 0)
		cputype = NXGetLocalArchInfo()->cputype;
	
	archinfo = NXGetArchInfoFromCpuType(cputype, CPU_SUBTYPE_MULTIPLE);
	
	if(archinfo)
		process->arch = wi_string_init_with_cstring(wi_string_alloc(), archinfo->name);
#elif defined(HAVE_SYSINFO) && defined(SI_ARCHITECTURE)
	if(sysinfo(SI_ARCHITECTURE, buffer, sizeof(buffer)) >= 0)
		process->arch = wi_string_init_with_cstring(wi_string_alloc(), buffer);
#endif

	if(!process->arch)
		process->arch = wi_string_init_with_cstring(wi_string_alloc(), name.machine);

	return process;
}
예제 #6
0
QString OSInfo::getOSVersion() {
#if defined(Q_WS_WIN)
	OSVERSIONINFOEXW ovi;
	memset(&ovi, 0, sizeof(ovi));

	ovi.dwOSVersionInfoSize=sizeof(ovi);
	GetVersionEx(reinterpret_cast<OSVERSIONINFOW *>(&ovi));

	QString os;
	os.sprintf("%d.%d.%d.%d", ovi.dwMajorVersion, ovi.dwMinorVersion, ovi.dwBuildNumber, (ovi.wProductType == VER_NT_WORKSTATION) ? 1 : 0);
	return os;
#elif defined(Q_OS_MAC)
	SInt32 major, minor, bugfix;
	OSErr err = Gestalt(gestaltSystemVersionMajor, &major);
	if (err == noErr)
		err = Gestalt(gestaltSystemVersionMinor, &minor);
	if (err == noErr)
		err = Gestalt(gestaltSystemVersionBugFix, &bugfix);
	if (err != noErr)
		return QString::number(QSysInfo::MacintoshVersion, 16);

	const NXArchInfo *local = NXGetLocalArchInfo();
	const NXArchInfo *ai = local ? NXGetArchInfoFromCpuType(local->cputype, CPU_SUBTYPE_MULTIPLE) : NULL;
	const char *arch = ai ? ai->name : "unknown";

	QString os;
	os.sprintf("%i.%i.%i (%s)", major, minor, bugfix, arch);
	return os;
#else
#ifdef Q_OS_LINUX
	QProcess qp;
	QStringList args;
	args << QLatin1String("-s");
	args << QLatin1String("-d");
	qp.start(QLatin1String("lsb_release"), args);
	if (qp.waitForFinished(5000)) {
		QString os = QString::fromUtf8(qp.readAll()).simplified();
		if (os.startsWith(QLatin1Char('"')) && os.endsWith(QLatin1Char('"')))
			os = os.mid(1, os.length() - 2).trimmed();
		if (! os.isEmpty())
			return os;
	}
	qWarning("OSInfo: Failed to execute lsb_release");
	qp.terminate();
	if (! qp.waitForFinished(1000))
		qp.kill();
#endif
	struct utsname un;
	if (uname(&un) == 0) {
		QString os;
		os.sprintf("%s %s", un.sysname, un.release);
		return os;
	}
	return QString();
#endif
}
/*  Determines whether an executable's header matches the current architecture, ppc, and/or i386. 
*   Returns true if the header corresponds to a Mach-O, 64-bit Mach-O, or universal binary executable, false otherwise.
*   Returns by reference the result of matching against a given architecture (matches_current, matches_ppc, matches_i386).
*   Checks for a given architecture only if the corresponding return-by-reference argument is non-NULL. 
*/
static Boolean examine_header(uint8_t *bytes, ssize_t length, Boolean *matches_current, Boolean *matches_ppc, Boolean *matches_i386) {
    Boolean retval = false;
    uint32_t magic = 0, num_fat = 0, max_fat = 0;
    struct fat_arch one_fat = {0}, *fat = NULL;
    const NXArchInfo *current_arch, *ppc_arch, *i386_arch;
    
    // Look for any of the six magic numbers relevant to Mach-O executables, and swap the header if necessary.
    if (length >= sizeof(struct mach_header_64)) {
        magic = *((uint32_t *)bytes);
        max_fat = (length - sizeof(struct fat_header)) / sizeof(struct fat_arch);
        if (MH_MAGIC == magic || MH_CIGAM == magic) {
            struct mach_header *mh = (struct mach_header *)bytes;
            if (MH_CIGAM == magic) swap_header(bytes, length);
            one_fat.cputype = mh->cputype;
            one_fat.cpusubtype = mh->cpusubtype;
            fat = &one_fat;
            num_fat = 1;
        } else if (MH_MAGIC_64 == magic || MH_CIGAM_64 == magic) {
            struct mach_header_64 *mh = (struct mach_header_64 *)bytes;
            if (MH_CIGAM_64 == magic) swap_header(bytes, length);
            one_fat.cputype = mh->cputype;
            one_fat.cpusubtype = mh->cpusubtype;
            fat = &one_fat;
            num_fat = 1;
        } else if (FAT_MAGIC == magic || FAT_CIGAM == magic) {
            fat = (struct fat_arch *)(bytes + sizeof(struct fat_header));
            if (FAT_CIGAM == magic) swap_header(bytes, length);
            num_fat = ((struct fat_header *)bytes)->nfat_arch;
            if (num_fat > max_fat) num_fat = max_fat;
        }
    }
    
    // Set the return value depending on whether the header appears valid.
    retval = ((fat && num_fat > 0) ? true : false);
    
    // Check for a match against the current architecture specification, if requested.
    if (matches_current) {
        current_arch = NXGetLocalArchInfo();
        *matches_current = ((retval && current_arch && NXFindBestFatArch(current_arch->cputype, current_arch->cpusubtype, fat, num_fat)) ? true : false);
    }
    // Check for a match against the ppc architecture specification, if requested.
    if (matches_ppc) {
        ppc_arch = NXGetArchInfoFromName("ppc");
        *matches_ppc = ((retval && ppc_arch && NXFindBestFatArch(ppc_arch->cputype, ppc_arch->cpusubtype, fat, num_fat)) ? true : false);
    }
    // Check for a match against the i386 architecture specification, if requested.
    if (matches_i386) {
        i386_arch = NXGetArchInfoFromName("i386");
        *matches_i386 = ((retval && i386_arch && NXFindBestFatArch(i386_arch->cputype, i386_arch->cpusubtype, fat, num_fat)) ? true : false);
    }
    return retval;
}
예제 #8
0
void * fat_iterator_find_host_arch(
    fat_iterator iter,
    void ** arch_end_ptr)
{
    const NXArchInfo * archinfo;

    archinfo = NXGetLocalArchInfo();
    if (!archinfo) {
        return NULL;
    }
    return fat_iterator_find_arch(iter, archinfo->cputype,
                                  archinfo->cpusubtype, arch_end_ptr);
}
예제 #9
0
const std::string& CSysInfo::GetKernelCpuFamily(void)
{
  static std::string kernelCpuFamily;
  if (kernelCpuFamily.empty())
  {
#ifdef TARGET_WINDOWS
    SYSTEM_INFO si;
    GetNativeSystemInfo(&si);
    if (si.wProcessorArchitecture == PROCESSOR_ARCHITECTURE_INTEL ||
        si.wProcessorArchitecture == PROCESSOR_ARCHITECTURE_AMD64)
        kernelCpuFamily = "x86";
    else if (si.wProcessorArchitecture == PROCESSOR_ARCHITECTURE_ARM)
      kernelCpuFamily = "ARM";
#elif defined(TARGET_DARWIN)
    const NXArchInfo* archInfo = NXGetLocalArchInfo();
    if (archInfo)
    {
      const cpu_type_t cpuType = (archInfo->cputype & ~CPU_ARCH_ABI64); // get CPU family without 64-bit ABI flag
      if (cpuType == CPU_TYPE_I386)
        kernelCpuFamily = "x86";
      else if (cpuType == CPU_TYPE_ARM)
        kernelCpuFamily = "ARM";
      else if (cpuType == CPU_TYPE_POWERPC)
        kernelCpuFamily = "PowerPC";
#ifdef CPU_TYPE_MIPS
      else if (cpuType == CPU_TYPE_MIPS)
        kernelCpuFamily = "MIPS";
#endif // CPU_TYPE_MIPS
    }
#elif defined(TARGET_POSIX)
    struct utsname un;
    if (uname(&un) == 0)
    {
      std::string machine(un.machine);
      if (machine.compare(0, 3, "arm", 3) == 0 || machine.compare(0, 7, "aarch64", 7) == 0)
        kernelCpuFamily = "ARM";
      else if (machine.compare(0, 4, "mips", 4) == 0)
        kernelCpuFamily = "MIPS";
      else if (machine.compare(0, 4, "i686", 4) == 0 || machine == "i386" || machine == "amd64" ||  machine.compare(0, 3, "x86", 3) == 0)
        kernelCpuFamily = "x86";
      else if (machine.compare(0, 4, "s390", 4) == 0)
        kernelCpuFamily = "s390";
      else if (machine.compare(0, 3, "ppc", 3) == 0 || machine.compare(0, 5, "power", 5) == 0)
        kernelCpuFamily = "PowerPC";
    }
#endif
    if (kernelCpuFamily.empty())
      kernelCpuFamily = "unknown CPU family";
  }
  return kernelCpuFamily;
}
CF_PRIVATE SInt32 _CFBundleCurrentArchitecture(void) {
    SInt32 arch = 0;
#if defined(__ppc__)
    arch = kCFBundleExecutableArchitecturePPC;
#elif defined(__ppc64__)
    arch = kCFBundleExecutableArchitecturePPC64;
#elif defined(__i386__)
    arch = kCFBundleExecutableArchitectureI386;
#elif defined(__x86_64__)
    arch = kCFBundleExecutableArchitectureX86_64;
#elif defined(BINARY_SUPPORT_DYLD)
    const NXArchInfo *archInfo = NXGetLocalArchInfo();
    if (archInfo) arch = archInfo->cputype;
#endif
    return arch;
}
예제 #11
0
파일: driverdriver.c 프로젝트: aosm/gcc_42
static const char *
get_arch_name (const char *name)
{
  const NXArchInfo * a_info;
  const NXArchInfo * all_info;
  cpu_type_t cputype;
  struct arch_config_guess_map *map;
  const char *aname;

  if (name)
    {
      /* Find config name based on arch name.  */
      aname = NULL;
      map = arch_config_map;
      while (map->arch_name)
	{
	  if (!strcmp (map->arch_name, name))
	    return name;
	  else map++;
	}
      a_info = NXGetArchInfoFromName (name);
    }
  else
    a_info = NXGetLocalArchInfo ();

  if (!a_info)
    fatal ("Invalid arch name : %s", name);

  all_info = NXGetAllArchInfos();

  if (!all_info)
    fatal ("Unable to get architecture information");

  /* Find first arch. that matches cputype.  */
  cputype = a_info->cputype;

  while (all_info->name)
    {
      if (all_info->cputype == cputype)
	break;
      else
	all_info++;
    }

  return all_info->name;
}
예제 #12
0
static wi_process_t * _wi_process_init_with_argv(wi_process_t *process, int argc, const char **argv) {
	wi_array_t			*array;
	wi_string_t			*string;
	struct utsname		name;
#ifdef HAVE_MACH_O_ARCH_H
	const NXArchInfo	*arch_info;
#endif
	
	array = wi_array_init_with_argv(wi_array_alloc(), argc, argv);
	
	string = wi_array_first_data(array);
	
	if(string) {
		process->path = wi_retain(string);
		process->name = wi_retain(wi_string_last_path_component(process->path));
	} else {
		process->path = wi_retain(WI_STR("unknown"));
		process->name = wi_retain(process->path);
	}
	
	if(wi_array_count(array) <= 1)
		process->arguments = wi_array_init(wi_array_alloc());
	else
		process->arguments = wi_retain(wi_array_subarray_with_range(array, wi_make_range(1, wi_array_count(array) - 1)));
	
	wi_release(array);
	
	uname(&name);
	
	process->os_name = wi_string_init_with_cstring(wi_string_alloc(), name.sysname);
	process->os_release = wi_string_init_with_cstring(wi_string_alloc(), name.release);

#ifdef HAVE_MACH_O_ARCH_H
	arch_info = NXGetArchInfoFromCpuType(NXGetLocalArchInfo()->cputype, CPU_SUBTYPE_MULTIPLE);
	
	process->arch = wi_string_init_with_cstring(wi_string_alloc(), arch_info->name);
#else
	process->arch = wi_string_init_with_cstring(wi_string_alloc(), name.machine);
#endif

	return process;
}
예제 #13
0
int CSysInfo::GetKernelBitness(void)
{
  static int kernelBitness = -1;
  if (kernelBitness == -1)
  {
#ifdef TARGET_WINDOWS
    SYSTEM_INFO si;
    GetNativeSystemInfo(&si);
    if (si.wProcessorArchitecture == PROCESSOR_ARCHITECTURE_INTEL || si.wProcessorArchitecture == PROCESSOR_ARCHITECTURE_ARM)
      kernelBitness = 32;
    else if (si.wProcessorArchitecture == PROCESSOR_ARCHITECTURE_AMD64)
      kernelBitness = 64;
    else
    {
      BOOL isWow64 = FALSE;
      if (IsWow64Process(GetCurrentProcess(), &isWow64) && isWow64) // fallback
        kernelBitness = 64;
    }
#elif defined(TARGET_DARWIN_IOS)
    // Note: OS X return x86 CPU type without CPU_ARCH_ABI64 flag
    const NXArchInfo* archInfo = NXGetLocalArchInfo();
    if (archInfo)
      kernelBitness = ((archInfo->cputype & CPU_ARCH_ABI64) != 0) ? 64 : 32;
#elif defined(TARGET_POSIX)
    struct utsname un;
    if (uname(&un) == 0)
    {
      std::string machine(un.machine);
      if (machine == "x86_64" || machine == "amd64" || machine == "arm64" || machine == "aarch64" || machine == "ppc64" ||
          machine == "ia64" || machine == "mips64")
        kernelBitness = 64;
      else
        kernelBitness = 32;
    }
#endif
    if (kernelBitness == -1)
      kernelBitness = 0; // can't detect
  }

  return kernelBitness;
}
예제 #14
0
파일: SystemInfo.cpp 프로젝트: MrMC/mrmc
const std::string& CSysInfo::GetKernelCpuFamily(void)
{
  static std::string kernelCpuFamily;
  if (kernelCpuFamily.empty())
  {
#if defined(TARGET_DARWIN)
    const NXArchInfo* archInfo = NXGetLocalArchInfo();
    if (archInfo)
    {
      const cpu_type_t cpuType = (archInfo->cputype & ~CPU_ARCH_ABI64); // get CPU family without 64-bit ABI flag
      if (cpuType == CPU_TYPE_I386)
        kernelCpuFamily = "x86";
      else if (cpuType == CPU_TYPE_ARM)
        kernelCpuFamily = "ARM";
      else if (cpuType == CPU_TYPE_POWERPC)
        kernelCpuFamily = "PowerPC";
#ifdef CPU_TYPE_MIPS
      else if (cpuType == CPU_TYPE_MIPS)
        kernelCpuFamily = "MIPS";
#endif // CPU_TYPE_MIPS
    }
#elif defined(TARGET_POSIX)
    struct utsname un;
    if (uname(&un) == 0)
    {
      std::string machine(un.machine);
      if (machine.compare(0, 3, "arm", 3) == 0)
        kernelCpuFamily = "ARM";
      else if (machine.compare(0, 4, "mips", 4) == 0)
        kernelCpuFamily = "MIPS";
      else if (machine.compare(0, 4, "i686", 4) == 0 || machine == "i386" || machine == "amd64" ||  machine.compare(0, 3, "x86", 3) == 0)
        kernelCpuFamily = "x86";
      else if (machine.compare(0, 3, "ppc", 3) == 0 || machine.compare(0, 5, "power", 5) == 0)
        kernelCpuFamily = "PowerPC";
    }
#endif
    if (kernelCpuFamily.empty())
      kernelCpuFamily = "unknown CPU family";
  }
  return kernelCpuFamily;
}
예제 #15
0
파일: main.c 프로젝트: prophile/dim3
bool app_check_os_support(char *err_str)
{
#ifdef D3_OS_MAC
	
	NXArchInfo		*info;

		// system version

	Gestalt(gestaltSystemVersion,&os_vers_hex);
	
	os_vers_major=(((os_vers_hex&0xF000)>>12)*10)+((os_vers_hex&0x0F00)>>8);
	os_vers_minor_1=(os_vers_hex&0x00F0)>>4;
	os_vers_minor_2=os_vers_hex&0x000F;

	if (os_vers_hex<0x1039) {
		strcpy(err_str,"Unsupported System Version: You need at least MacOS X 10.3.9 to run dim3.");
		return(FALSE);
	}

		// arch type

	info=(NXArchInfo*)NXGetLocalArchInfo();
	strncpy(arch_type,info->name,name_str_len);
	arch_type[name_str_len-1]=0x0;
	arch_ppc_g3=(strcasecmp(info->name,"ppc750")==0);

#else
	os_vers_hex=0;
	os_vers_major=0;
	os_vers_minor_1=0;
	os_vers_minor_2=0;

	arch_ppc_g3=FALSE;
	strcpy(arch_type,"x86");
#endif

	return(TRUE);
}
예제 #16
0
int main(int argc, char * argv[])
{
    KXKextManagerError	err;
    int			fd;
    const char *	output_name = NULL;
    uint32_t		i, zero = 0, num_files = 0;
    uint32_t		filenum;
    uint32_t		strx, strtabsize, strtabpad;
    struct symbol *	import_symbols;
    struct symbol *	export_symbols;
    uint32_t		num_import_syms, num_export_syms, num_removed_syms;
    uint32_t		import_idx, export_idx;
    const NXArchInfo *	host_arch;
    const NXArchInfo *	target_arch;
    boolean_t		require_imports = true;
    boolean_t		diff = false;

    struct {
	struct mach_header    hdr;
	struct symtab_command symcmd;
    } load_cmds;

    struct file {
        vm_offset_t  mapped;
        vm_size_t    mapped_size;
	uint32_t     nsyms;
	boolean_t    import;
	const char * path;
    };
    struct file files[64];
    
    host_arch = NXGetLocalArchInfo();
    target_arch = host_arch;

    for( i = 1; i < argc; i += 2)
    {
	boolean_t import;

        if (!strcmp("-sect", argv[i]))
        {
	    require_imports = false;
	    i--;
	    continue;
        }
        if (!strcmp("-diff", argv[i]))
        {
	    require_imports = false;
	    diff = true;
	    i--;
	    continue;
        }

	if (i == (argc - 1))
	{
	    fprintf(stderr, "bad arguments: %s\n", argv[i]);
	    exit(1);
	}

        if (!strcmp("-arch", argv[i]))
        {
            target_arch = NXGetArchInfoFromName(argv[i + 1]);
	    if (!target_arch)
	    {
		fprintf(stderr, "unknown architecture name: %s\n", argv[i+1]);
		exit(1);
	    }
            continue;
        }
        if (!strcmp("-output", argv[i]))
        {
	    output_name = argv[i+1];
            continue;
        }

        if (!strcmp("-import", argv[i]))
	    import = true;
	else if (!strcmp("-export", argv[i]))
	    import = false;
	else
	{
	    fprintf(stderr, "unknown option: %s\n", argv[i]);
	    exit(1);
	}

        err = readFile(argv[i+1], &files[num_files].mapped, &files[num_files].mapped_size);
        if (kKXKextManagerErrorNone != err)
            exit(1);

        if (files[num_files].mapped && files[num_files].mapped_size)
	{
	    files[num_files].import = import;
	    files[num_files].path   = argv[i+1];
            num_files++;
	}
    }

    if (!output_name)
    {
	fprintf(stderr, "no output file\n");
	exit(1);
    }

    num_import_syms = 0;
    num_export_syms = 0;
    for (filenum = 0; filenum < num_files; filenum++)
    {
        files[filenum].nsyms = count_symbols((char *) files[filenum].mapped);
	if (files[filenum].import)
	    num_import_syms += files[filenum].nsyms;
	else
	    num_export_syms += files[filenum].nsyms;
    }
    if (!num_export_syms)
    {
	fprintf(stderr, "no export names\n");
	exit(1);
    }

    import_symbols = calloc(num_import_syms, sizeof(struct symbol));
    export_symbols = calloc(num_export_syms, sizeof(struct symbol));

    strtabsize = 4;
    import_idx = 0;
    export_idx = 0;

    for (filenum = 0; filenum < num_files; filenum++)
    {
	if (files[filenum].import)
	{
	    store_symbols((char *) files[filenum].mapped,
					import_symbols, import_idx, num_import_syms);
	    import_idx += files[filenum].nsyms;
	}
	else
	{
	    strtabsize += store_symbols((char *) files[filenum].mapped,
					export_symbols, export_idx, num_export_syms);
	    export_idx += files[filenum].nsyms;
	}
	if (!files[filenum].nsyms)
	{
	    fprintf(stderr, "warning: file %s contains no names\n", files[filenum].path);
	}
    }


    qsort(import_symbols, num_import_syms, sizeof(struct symbol), &qsort_cmp);
    qsort(export_symbols, num_export_syms, sizeof(struct symbol), &qsort_cmp);

    num_removed_syms = 0;
    if (num_import_syms)
    {
	for (export_idx = 0; export_idx < num_export_syms; export_idx++)
	{
	    boolean_t found = true;
	    if (!bsearch(export_symbols[export_idx].name, import_symbols, 
			    num_import_syms, sizeof(struct symbol), &bsearch_cmp))
	    {
		if (require_imports)
		    fprintf(stderr, "exported name not in import list: %s\n", 
				export_symbols[export_idx].name);
		found = false;
	    }
    
	    if (export_symbols[export_idx].indirect)
	    {
		if (!bsearch(export_symbols[export_idx].indirect, import_symbols, 
				num_import_syms, sizeof(struct symbol), &bsearch_cmp))
		{
		    if (require_imports)
			fprintf(stderr, "exported name not in import list: %s\n", 
				    export_symbols[export_idx].indirect);
		    found = false;
		}
	    }
	    if (found && !diff)
		continue;
	    if (!found && diff)
		continue;

	    num_removed_syms++;
	    strtabsize -= (export_symbols[export_idx].name_len + export_symbols[export_idx].indirect_len);
	    export_symbols[export_idx].name = 0;
	}
    }

    if (require_imports && num_removed_syms)
    {
	err = kKXKextManagerErrorUnspecified;
	goto finish;
    }

    fd = open(output_name, O_WRONLY|O_CREAT|O_TRUNC, 0755);
    if (-1 == fd)
    {
	perror("couldn't write output");
	err = kKXKextManagerErrorFileAccess;
	goto finish;
    }

    strtabpad = (strtabsize + 3) & ~3;

    load_cmds.hdr.magic		= MH_MAGIC;
    load_cmds.hdr.cputype	= target_arch->cputype;
    load_cmds.hdr.cpusubtype	= target_arch->cpusubtype;
    load_cmds.hdr.filetype	= MH_OBJECT;
    load_cmds.hdr.ncmds		= 1;
    load_cmds.hdr.sizeofcmds	= sizeof(load_cmds.symcmd);
    load_cmds.hdr.flags		= MH_INCRLINK;

    load_cmds.symcmd.cmd	= LC_SYMTAB;
    load_cmds.symcmd.cmdsize	= sizeof(load_cmds.symcmd);
    load_cmds.symcmd.symoff	= sizeof(load_cmds);
    load_cmds.symcmd.nsyms	= (num_export_syms - num_removed_syms);
    load_cmds.symcmd.stroff	= (num_export_syms - num_removed_syms) * sizeof(struct nlist) 
				+ load_cmds.symcmd.symoff;
    load_cmds.symcmd.strsize	= strtabpad;

    if (target_arch->byteorder != host_arch->byteorder)
    {
	swap_mach_header(&load_cmds.hdr, target_arch->byteorder);
	swap_symtab_command(&load_cmds.symcmd, target_arch->byteorder);
    }

    err = writeFile(fd, &load_cmds, sizeof(load_cmds));
    if (kKXKextManagerErrorNone != err)
	goto finish;

    strx = 4;
    for (export_idx = 0; export_idx < num_export_syms; export_idx++)
    {
	struct nlist nl;

	if (!export_symbols[export_idx].name)
	    continue;

	nl.n_sect  = 0;
	nl.n_desc  = 0;

	nl.n_un.n_strx = strx;
	strx += export_symbols[export_idx].name_len;

	if (export_symbols[export_idx].indirect)
	{
	    nl.n_type  = N_INDR | N_EXT;
	    nl.n_value = strx;
	    strx += export_symbols[export_idx].indirect_len;
	}
	else
	{
	    nl.n_type  = N_UNDF | N_EXT;
	    nl.n_value = 0;
	}

	if (target_arch->byteorder != host_arch->byteorder)
	    swap_nlist(&nl, 1, target_arch->byteorder);

	err = writeFile(fd, &nl, sizeof(nl));
	if (kKXKextManagerErrorNone != err)
	    goto finish;
    }

    strx = sizeof(uint32_t);
    err = writeFile(fd, &zero, strx);
    if (kKXKextManagerErrorNone != err)
	goto finish;

    for (export_idx = 0; export_idx < num_export_syms; export_idx++)
    {
	if (!export_symbols[export_idx].name)
	    continue;
	err = writeFile(fd, export_symbols[export_idx].name, 
		    export_symbols[export_idx].name_len + export_symbols[export_idx].indirect_len);
	if (kKXKextManagerErrorNone != err)
	    goto finish;
    }

    err = writeFile(fd, &zero, strtabpad - strtabsize);
    if (kKXKextManagerErrorNone != err)
	goto finish;
	
    close(fd);


finish:
    if (kKXKextManagerErrorNone != err)
    {
	if (output_name)
	    unlink(output_name);
        exit(1);
    }
    else
        exit(0);
    return(0);
}
예제 #17
0
int main(int argc, char * argv[])
{
    ToolError	err;
    int			i, fd;
    const char *	output_name = NULL;
    uint32_t		zero = 0, num_files = 0;
    uint32_t		filenum;
    uint32_t		strx, strtabsize, strtabpad;
    struct symbol *	import_symbols;
    struct symbol *	export_symbols;
    uint32_t		num_import_syms, num_export_syms;
    uint32_t		result_count, num_removed_syms;
    uint32_t		import_idx, export_idx;
    const NXArchInfo *	host_arch;
    const NXArchInfo *	target_arch;
    boolean_t		require_imports = true;
    boolean_t		diff = false;


    struct file {
        vm_offset_t  mapped;
        vm_size_t    mapped_size;
	uint32_t     nsyms;
	boolean_t    import;
	const char * path;
    };
    struct file files[64];
    
    host_arch = NXGetLocalArchInfo();
    target_arch = host_arch;

    for( i = 1; i < argc; i += 2)
    {
	boolean_t import;

        if (!strcmp("-sect", argv[i]))
        {
	    require_imports = false;
	    i--;
	    continue;
        }
        if (!strcmp("-diff", argv[i]))
        {
	    require_imports = false;
	    diff = true;
	    i--;
	    continue;
        }

	if (i == (argc - 1))
	{
	    fprintf(stderr, "bad arguments: %s\n", argv[i]);
	    exit(1);
	}

        if (!strcmp("-arch", argv[i]))
        {
            target_arch = DL_NXGetArchInfoFromName(argv[i + 1]);
	    if (!target_arch)
	    {
		fprintf(stderr, "unknown architecture name: %s\n", argv[i+1]);
		exit(1);
	    }
            continue;
        }
        if (!strcmp("-output", argv[i]))
        {
	    output_name = argv[i+1];
            continue;
        }

        if (!strcmp("-import", argv[i]))
	    import = true;
	else if (!strcmp("-export", argv[i]))
	    import = false;
	else
	{
	    fprintf(stderr, "unknown option: %s\n", argv[i]);
	    exit(1);
	}

        err = readFile(argv[i+1], &files[num_files].mapped, &files[num_files].mapped_size);
        if (kErrorNone != err)
            exit(1);

        if (files[num_files].mapped && files[num_files].mapped_size)
	{
	    files[num_files].import = import;
	    files[num_files].path   = argv[i+1];
            num_files++;
	}
    }

    if (!output_name)
    {
	fprintf(stderr, "no output file\n");
	exit(1);
    }

    num_import_syms = 0;
    num_export_syms = 0;
    for (filenum = 0; filenum < num_files; filenum++)
    {
        files[filenum].nsyms = count_symbols((char *) files[filenum].mapped, files[filenum].mapped_size);
	if (files[filenum].import)
	    num_import_syms += files[filenum].nsyms;
	else
	    num_export_syms += files[filenum].nsyms;
    }
    if (!num_export_syms)
    {
	fprintf(stderr, "no export names\n");
	exit(1);
    }

    import_symbols = calloc(num_import_syms, sizeof(struct symbol));
    export_symbols = calloc(num_export_syms, sizeof(struct symbol));

    import_idx = 0;
    export_idx = 0;

    for (filenum = 0; filenum < num_files; filenum++)
    {
	if (files[filenum].import)
	{
	    store_symbols((char *) files[filenum].mapped, files[filenum].mapped_size,
					import_symbols, import_idx, num_import_syms);
	    import_idx += files[filenum].nsyms;
	}
	else
	{
	    store_symbols((char *) files[filenum].mapped, files[filenum].mapped_size,
					export_symbols, export_idx, num_export_syms);
	    export_idx += files[filenum].nsyms;
	}
	if (false && !files[filenum].nsyms)
	{
	    fprintf(stderr, "warning: file %s contains no names\n", files[filenum].path);
	}
    }


    qsort(import_symbols, num_import_syms, sizeof(struct symbol), &qsort_cmp);
    qsort(export_symbols, num_export_syms, sizeof(struct symbol), &qsort_cmp);

    result_count = 0;
    num_removed_syms = 0;
    strtabsize = 4;
    if (num_import_syms)
    {
	for (export_idx = 0; export_idx < num_export_syms; export_idx++)
	{
	    struct symbol * result;
	    char * name;
	    size_t len;
	    boolean_t wild;

	    name = export_symbols[export_idx].indirect;
	    len  = export_symbols[export_idx].indirect_len;
	    if (!name)
	    {
		name = export_symbols[export_idx].name;
		len  = export_symbols[export_idx].name_len;
	    }
	    wild = ((len > 2) && ('*' == name[len-=2]));
	    if (wild)
	    {
		struct bsearch_key key;
		key.name = name;
		key.name_len = len;
		result = bsearch(&key, import_symbols, 
				    num_import_syms, sizeof(struct symbol), &bsearch_cmp_prefix);

		if (result)
		{
		    struct symbol * first;
		    struct symbol * last;

		    strtabsize += (result->name_len + result->indirect_len);

		    first = result;
		    while (--first >= &import_symbols[0])
		    {
			if (bsearch_cmp_prefix(&key, first))
			    break;
			strtabsize += (first->name_len + first->indirect_len);
		    }
		    first++;

		    last = result;
		    while (++last < (&import_symbols[0] + num_import_syms))
		    {
			if (bsearch_cmp_prefix(&key, last))
			    break;
			strtabsize += (last->name_len + last->indirect_len);
		    }
		    result_count += last - first;
		    result = first;
		    export_symbols[export_idx].list = first;
		    export_symbols[export_idx].list_count = last - first;
		    export_symbols[export_idx].flags |= kExported;
		}
	    }
	    else
		result = bsearch(name, import_symbols, 
				    num_import_syms, sizeof(struct symbol), &bsearch_cmp);

	    if (!result && require_imports)
	    {
		int status;
		char * demangled_result = 
			__cxa_demangle(export_symbols[export_idx].name + 1, NULL, NULL, &status);
		fprintf(stderr, "exported name not in import list: %s\n",
					demangled_result ? demangled_result : export_symbols[export_idx].name);
//		fprintf(stderr, "                                : %s\n", export_symbols[export_idx].name);
		if (demangled_result) {
			free(demangled_result);
		}
		num_removed_syms++;
	    }
	    if (diff)
	    {
		if (!result)
		    result = &export_symbols[export_idx];
		else
		    result = NULL;
	    }
	    if (result && !wild)
	    {
		export_symbols[export_idx].flags |= kExported;
		strtabsize += (export_symbols[export_idx].name_len + export_symbols[export_idx].indirect_len);
		result_count++;
		export_symbols[export_idx].list = &export_symbols[export_idx];
		export_symbols[export_idx].list_count = 1;
	    }
	}
    }
    strtabpad = (strtabsize + 3) & ~3;

    if (require_imports && num_removed_syms)
    {
	err = kError;
	goto finish;
    }

    fd = open(output_name, O_WRONLY|O_CREAT|O_TRUNC, 0755);
    if (-1 == fd)
    {
	perror("couldn't write output");
	err = kErrorFileAccess;
	goto finish;
    }

    struct symtab_command symcmd;
    struct uuid_command uuidcmd;

    symcmd.cmd		= LC_SYMTAB;
    symcmd.cmdsize	= sizeof(symcmd);
    symcmd.symoff	= sizeof(symcmd) + sizeof(uuidcmd);
    symcmd.nsyms	= result_count;
    symcmd.strsize	= strtabpad;

    uuidcmd.cmd         = LC_UUID;
    uuidcmd.cmdsize     = sizeof(uuidcmd);
    uuid_generate(uuidcmd.uuid);

    if (CPU_ARCH_ABI64 & target_arch->cputype)
    {
	struct mach_header_64 hdr;
	hdr.magic	= MH_MAGIC_64;
	hdr.cputype	= target_arch->cputype;
	hdr.cpusubtype	= target_arch->cpusubtype;
	hdr.filetype	= MH_KEXT_BUNDLE;
	hdr.ncmds	= 2;
	hdr.sizeofcmds	= sizeof(symcmd) + sizeof(uuidcmd);
	hdr.flags	= MH_INCRLINK;

	symcmd.symoff	+= sizeof(hdr);
	symcmd.stroff	= result_count * sizeof(struct nlist_64) 
				+ symcmd.symoff;

	if (target_arch->byteorder != host_arch->byteorder)
	    swap_mach_header_64(&hdr, target_arch->byteorder);
	err = writeFile(fd, &hdr, sizeof(hdr));
    }
    else
    {
	struct mach_header    hdr;
	hdr.magic	= MH_MAGIC;
	hdr.cputype	= target_arch->cputype;
	hdr.cpusubtype	= target_arch->cpusubtype;
	hdr.filetype	= (target_arch->cputype == CPU_TYPE_I386) ? MH_OBJECT : MH_KEXT_BUNDLE;
	hdr.ncmds	= 2;
	hdr.sizeofcmds	= sizeof(symcmd) + sizeof(uuidcmd);
	hdr.flags	= MH_INCRLINK;

	symcmd.symoff	+= sizeof(hdr);
	symcmd.stroff	= result_count * sizeof(struct nlist) 
				+ symcmd.symoff;

	if (target_arch->byteorder != host_arch->byteorder)
	    swap_mach_header(&hdr, target_arch->byteorder);
	err = writeFile(fd, &hdr, sizeof(hdr));
    }

    if (kErrorNone != err)
	goto finish;

    if (target_arch->byteorder != host_arch->byteorder) {
        swap_symtab_command(&symcmd, target_arch->byteorder);
        swap_uuid_command(&uuidcmd, target_arch->byteorder);
    }
    err = writeFile(fd, &symcmd, sizeof(symcmd));
    if (kErrorNone != err)
	goto finish;
    err = writeFile(fd, &uuidcmd, sizeof(uuidcmd));
    if (kErrorNone != err)
        goto finish;

    strx = 4;
    for (export_idx = 0; export_idx < num_export_syms; export_idx++)
    {
	if (!export_symbols[export_idx].name)
	    continue;
	if (!(kExported & export_symbols[export_idx].flags))
	    continue;

	if (export_idx
	  && export_symbols[export_idx - 1].name
	  && !strcmp(export_symbols[export_idx - 1].name, export_symbols[export_idx].name))
	{
	    fprintf(stderr, "duplicate export: %s\n", export_symbols[export_idx - 1].name);
	    err = kErrorDuplicate;
	    goto finish;
	}

	for (import_idx = 0; import_idx < export_symbols[export_idx].list_count; import_idx++)
	{

	    if (export_symbols[export_idx].list != &export_symbols[export_idx])
	    {
		printf("wild: %s, %s\n", export_symbols[export_idx].name, 
			export_symbols[export_idx].list[import_idx].name);
	    }
	    if (CPU_ARCH_ABI64 & target_arch->cputype)
	    {
		struct nlist_64 nl;

		nl.n_sect  = 0;
                nl.n_desc  = 0;
		nl.n_un.n_strx = strx;
		strx += export_symbols[export_idx].list[import_idx].name_len;
                
                if (export_symbols[export_idx].flags & kObsolete) {
                    nl.n_desc |= N_DESC_DISCARDED;
                }

		if (export_symbols[export_idx].list[import_idx].indirect)
		{
		    nl.n_type  = N_INDR | N_EXT;
		    nl.n_value = strx;
		    strx += export_symbols[export_idx].list[import_idx].indirect_len;
		}
		else
		{
		    nl.n_type  = N_UNDF | N_EXT;
		    nl.n_value = 0;
		}

		if (target_arch->byteorder != host_arch->byteorder)
		    swap_nlist_64(&nl, 1, target_arch->byteorder);

		err = writeFile(fd, &nl, sizeof(nl));
	    }
	    else
	    {
		struct nlist nl;

		nl.n_sect  = 0;
		nl.n_desc  = 0;
		nl.n_un.n_strx = strx;
		strx += export_symbols[export_idx].list[import_idx].name_len;
 
                if (export_symbols[export_idx].flags & kObsolete) {
                    nl.n_desc |= N_DESC_DISCARDED;
                }

		if (export_symbols[export_idx].list[import_idx].indirect)
		{
		    nl.n_type  = N_INDR | N_EXT;
		    nl.n_value = strx;
		    strx += export_symbols[export_idx].list[import_idx].indirect_len;
		}
		else
		{
		    nl.n_type  = N_UNDF | N_EXT;
		    nl.n_value = 0;
		}

		if (target_arch->byteorder != host_arch->byteorder)
		    swap_nlist(&nl, 1, target_arch->byteorder);

		err = writeFile(fd, &nl, sizeof(nl));
	    }
	}

	if (kErrorNone != err)
	    goto finish;
    }

    strx = sizeof(uint32_t);
    err = writeFile(fd, &zero, strx);
    if (kErrorNone != err)
	goto finish;

    for (export_idx = 0; export_idx < num_export_syms; export_idx++)
    {
	if (!export_symbols[export_idx].name)
	    continue;

	for (import_idx = 0; import_idx < export_symbols[export_idx].list_count; import_idx++)
	{
	    err = writeFile(fd, export_symbols[export_idx].list[import_idx].name, 
			export_symbols[export_idx].list[import_idx].name_len);
	    if (kErrorNone != err)
		goto finish;
	    if (export_symbols[export_idx].list[import_idx].indirect)
	    {
		err = writeFile(fd, export_symbols[export_idx].list[import_idx].indirect, 
			    export_symbols[export_idx].list[import_idx].indirect_len);
		if (kErrorNone != err)
		    goto finish;
	    }
	}
    }

    err = writeFile(fd, &zero, strtabpad - strtabsize);
    if (kErrorNone != err)
	goto finish;
	
    close(fd);


finish:
    for (filenum = 0; filenum < num_files; filenum++) {
        // unmap file
        if (files[filenum].mapped_size)
        {
            munmap((caddr_t)files[filenum].mapped, files[filenum].mapped_size);
            files[filenum].mapped     = 0;
            files[filenum].mapped_size = 0;
        }

    }

    if (kErrorNone != err)
    {
	if (output_name)
	    unlink(output_name);
        exit(1);
    }
    else
        exit(0);
    return(0);
}
예제 #18
0
파일: CPUInfo.cpp 프로젝트: Karlson2k/xbmc
CCPUInfo::CCPUInfo(void)
{
#ifdef TARGET_POSIX
  m_fProcStat = m_fProcTemperature = m_fCPUFreq = NULL;
  m_cpuInfoForFreq = false;
#elif defined(TARGET_WINDOWS)
  m_cpuQueryFreq = NULL;
  m_cpuQueryLoad = NULL;
#endif
  m_lastUsedPercentage = 0;
  m_cpuFeatures = 0;

#if defined(TARGET_DARWIN)
  size_t len = 4;
  std::string cpuVendor;
  
  // The number of cores.
  if (sysctlbyname("hw.activecpu", &m_cpuCount, &len, NULL, 0) == -1)
      m_cpuCount = 1;

  // The model.
#if defined(__ppc__) || defined (TARGET_DARWIN_IOS)
  const NXArchInfo *info = NXGetLocalArchInfo();
  if (info != NULL)
    m_cpuModel = info->description;
#else
  // NXGetLocalArchInfo is ugly for intel so keep using this method
  char buffer[512];
  len = 512;
  if (sysctlbyname("machdep.cpu.brand_string", &buffer, &len, NULL, 0) == 0)
    m_cpuModel = buffer;

  // The CPU vendor
  len = 512;
  if (sysctlbyname("machdep.cpu.vendor", &buffer, &len, NULL, 0) == 0)
    cpuVendor = buffer;
  
#endif
  // Go through each core.
  for (int i=0; i<m_cpuCount; i++)
  {
    CoreInfo core;
    core.m_id = i;
    core.m_strModel = m_cpuModel;
    core.m_strVendor = cpuVendor;
    m_cores[core.m_id] = core;
  }

#elif defined(TARGET_WINDOWS)
  HKEY hKeyCpuRoot;

  if (RegOpenKeyExW(HKEY_LOCAL_MACHINE, L"HARDWARE\\DESCRIPTION\\System\\CentralProcessor", 0, KEY_READ, &hKeyCpuRoot) == ERROR_SUCCESS)
  {
    DWORD num = 0;
    std::vector<CoreInfo> cpuCores;
    wchar_t subKeyName[200]; // more than enough
    DWORD subKeyNameLen = sizeof(subKeyName) / sizeof(wchar_t);
    while (RegEnumKeyExW(hKeyCpuRoot, num++, subKeyName, &subKeyNameLen, NULL, NULL, NULL, NULL) == ERROR_SUCCESS)
    {
      HKEY hCpuKey;
      if (RegOpenKeyExW(hKeyCpuRoot, subKeyName, 0, KEY_QUERY_VALUE, &hCpuKey) == ERROR_SUCCESS)
      {
        CoreInfo cpuCore;
        if (swscanf_s(subKeyName, L"%i", &cpuCore.m_id) != 1)
          cpuCore.m_id = num - 1;
        wchar_t buf[300]; // more than enough
        DWORD bufSize = sizeof(buf);
        DWORD valType;
        if (RegQueryValueExW(hCpuKey, L"ProcessorNameString", NULL, &valType, (LPBYTE)buf, &bufSize) == ERROR_SUCCESS &&
            valType == REG_SZ)
        {
          g_charsetConverter.wToUTF8(std::wstring(buf, bufSize / sizeof(wchar_t)), cpuCore.m_strModel);
          cpuCore.m_strModel = cpuCore.m_strModel.substr(0, cpuCore.m_strModel.find(char(0))); // remove extra null terminations
          StringUtils::RemoveDuplicatedSpacesAndTabs(cpuCore.m_strModel);
          StringUtils::Trim(cpuCore.m_strModel);
        }
        bufSize = sizeof(buf);
        if (RegQueryValueExW(hCpuKey, L"VendorIdentifier", NULL, &valType, (LPBYTE)buf, &bufSize) == ERROR_SUCCESS &&
            valType == REG_SZ)
        {
          g_charsetConverter.wToUTF8(std::wstring(buf, bufSize / sizeof(wchar_t)), cpuCore.m_strVendor);
          cpuCore.m_strVendor = cpuCore.m_strVendor.substr(0, cpuCore.m_strVendor.find(char(0))); // remove extra null terminations
        }
        DWORD mhzVal;
        bufSize = sizeof(mhzVal);
        if (RegQueryValueExW(hCpuKey, L"~MHz", NULL, &valType, (LPBYTE)&mhzVal, &bufSize) == ERROR_SUCCESS &&
            valType == REG_DWORD)
          cpuCore.m_fSpeed = double(mhzVal);

        RegCloseKey(hCpuKey);

        if (cpuCore.m_strModel.empty())
          cpuCore.m_strModel = "Unknown";
        cpuCores.push_back(cpuCore);
      }
      subKeyNameLen = sizeof(subKeyName) / sizeof(wchar_t); // restore length value
    }
    RegCloseKey(hKeyCpuRoot);
    std::sort(cpuCores.begin(), cpuCores.end()); // sort cores by id
    for (size_t i = 0; i < cpuCores.size(); i++)
      m_cores[i] = cpuCores[i]; // add in sorted order
  }

  if (!m_cores.empty())
    m_cpuModel = m_cores.begin()->second.m_strModel;
  else
    m_cpuModel = "Unknown";

  SYSTEM_INFO siSysInfo;
  GetNativeSystemInfo(&siSysInfo);
  m_cpuCount = siSysInfo.dwNumberOfProcessors;

  if (PdhOpenQueryW(NULL, 0, &m_cpuQueryFreq) == ERROR_SUCCESS)
  {
    if (PdhAddEnglishCounterW(m_cpuQueryFreq, L"\\Processor Information(0,0)\\Processor Frequency", 0, &m_cpuFreqCounter) != ERROR_SUCCESS)
      m_cpuFreqCounter = NULL;
  }
  else
    m_cpuQueryFreq = NULL;
  
  if (PdhOpenQueryW(NULL, 0, &m_cpuQueryLoad) == ERROR_SUCCESS)
  {
    for (size_t i = 0; i < m_cores.size(); i++)
    {
      if (PdhAddEnglishCounterW(m_cpuQueryLoad, StringUtils::Format(L"\\Processor(%d)\\%% Idle Time", int(i)).c_str(), 0, &m_cores[i].m_coreCounter) != ERROR_SUCCESS)
        m_cores[i].m_coreCounter = NULL;
    }
  }
  else
    m_cpuQueryLoad = NULL;
#elif defined(TARGET_FREEBSD)
  size_t len;
  int i;
  char cpumodel[512];

  len = sizeof(m_cpuCount);
  if (sysctlbyname("hw.ncpu", &m_cpuCount, &len, NULL, 0) != 0)
    m_cpuCount = 1;

  len = sizeof(cpumodel);
  if (sysctlbyname("hw.model", &cpumodel, &len, NULL, 0) != 0)
    (void)strncpy(cpumodel, "Unknown", 8);
  m_cpuModel = cpumodel;

  for (i = 0; i < m_cpuCount; i++)
  {
    CoreInfo core;
    core.m_id = i;
    core.m_strModel = m_cpuModel;
    m_cores[core.m_id] = core;
  }
#else
  m_fProcStat = fopen("/proc/stat", "r");
  m_fProcTemperature = fopen("/proc/acpi/thermal_zone/THM0/temperature", "r");
  if (m_fProcTemperature == NULL)
    m_fProcTemperature = fopen("/proc/acpi/thermal_zone/THRM/temperature", "r");
  if (m_fProcTemperature == NULL)
    m_fProcTemperature = fopen("/proc/acpi/thermal_zone/THR0/temperature", "r");
  if (m_fProcTemperature == NULL)
    m_fProcTemperature = fopen("/proc/acpi/thermal_zone/TZ0/temperature", "r");
  // read from the new location of the temperature data on new kernels, 2.6.39, 3.0 etc
  if (m_fProcTemperature == NULL)   
    m_fProcTemperature = fopen("/sys/class/hwmon/hwmon0/temp1_input", "r");
  if (m_fProcTemperature == NULL)   
    m_fProcTemperature = fopen("/sys/class/thermal/thermal_zone0/temp", "r");  // On Raspberry PIs

  m_fCPUFreq = fopen ("/sys/devices/system/cpu/cpu0/cpufreq/scaling_cur_freq", "r");
  if (!m_fCPUFreq)
  {
    m_cpuInfoForFreq = true;
    m_fCPUFreq = fopen("/proc/cpuinfo", "r");
  }
  else
    m_cpuInfoForFreq = false;


  FILE* fCPUInfo = fopen("/proc/cpuinfo", "r");
  m_cpuCount = 0;
  if (fCPUInfo)
  {
    char buffer[512];

    int nCurrId = 0;
    while (fgets(buffer, sizeof(buffer), fCPUInfo))
    {
      if (strncmp(buffer, "processor", strlen("processor"))==0)
      {
        char *needle = strstr(buffer, ":");
        if (needle)
        {
          CoreInfo core;
          core.m_id = atoi(needle+2);
          nCurrId = core.m_id;
          m_cores[core.m_id] = core;
        }
        m_cpuCount++;
      }
      else if (strncmp(buffer, "vendor_id", strlen("vendor_id"))==0)
      {
        char *needle = strstr(buffer, ":");
        if (needle && strlen(needle)>3)
        {
          needle+=2;
          m_cores[nCurrId].m_strVendor = needle;
          StringUtils::Trim(m_cores[nCurrId].m_strVendor);
        }
      }
      else if (strncmp(buffer, "Processor", strlen("Processor"))==0)
      {
        char *needle = strstr(buffer, ":");
        if (needle && strlen(needle)>3)
        {
          needle+=2;
          m_cpuModel = needle;
          m_cores[nCurrId].m_strModel = m_cpuModel;
          StringUtils::Trim(m_cores[nCurrId].m_strModel);
        }
      }
      else if (strncmp(buffer, "BogoMIPS", strlen("BogoMIPS"))==0)
      {
        char *needle = strstr(buffer, ":");
        if (needle && strlen(needle)>3)
        {
          needle+=2;
          m_cpuBogoMips = needle;
          m_cores[nCurrId].m_strBogoMips = m_cpuBogoMips;
          StringUtils::Trim(m_cores[nCurrId].m_strBogoMips);
        }
      }
      else if (strncmp(buffer, "Hardware", strlen("Hardware"))==0)
      {
        char *needle = strstr(buffer, ":");
        if (needle && strlen(needle)>3)
        {
          needle+=2;
          m_cpuHardware = needle;
          m_cores[nCurrId].m_strHardware = m_cpuHardware;
          StringUtils::Trim(m_cores[nCurrId].m_strHardware);
        }
      }
      else if (strncmp(buffer, "Revision", strlen("Revision"))==0)
      {
        char *needle = strstr(buffer, ":");
        if (needle && strlen(needle)>3)
        {
          needle+=2;
          m_cpuRevision = needle;
          m_cores[nCurrId].m_strRevision = m_cpuRevision;
          StringUtils::Trim(m_cores[nCurrId].m_strRevision);
        }
      }
      else if (strncmp(buffer, "Serial", strlen("Serial"))==0)
      {
        char *needle = strstr(buffer, ":");
        if (needle && strlen(needle)>3)
        {
          needle+=2;
          m_cpuSerial = needle;
          m_cores[nCurrId].m_strSerial = m_cpuSerial;
          StringUtils::Trim(m_cores[nCurrId].m_strSerial);
        }
      }
      else if (strncmp(buffer, "model name", strlen("model name"))==0)
      {
        char *needle = strstr(buffer, ":");
        if (needle && strlen(needle)>3)
        {
          needle+=2;
          m_cpuModel = needle;
          m_cores[nCurrId].m_strModel = m_cpuModel;
          StringUtils::Trim(m_cores[nCurrId].m_strModel);
        }
      }
      else if (strncmp(buffer, "flags", 5) == 0)
      {
        char* needle = strchr(buffer, ':');
        if (needle)
        {
          char* tok = NULL,
              * save;
          needle++;
          tok = strtok_r(needle, " ", &save);
          while (tok)
          {
            if (0 == strcmp(tok, "mmx"))
              m_cpuFeatures |= CPU_FEATURE_MMX;
            else if (0 == strcmp(tok, "mmxext"))
              m_cpuFeatures |= CPU_FEATURE_MMX2;
            else if (0 == strcmp(tok, "sse"))
              m_cpuFeatures |= CPU_FEATURE_SSE;
            else if (0 == strcmp(tok, "sse2"))
              m_cpuFeatures |= CPU_FEATURE_SSE2;
            else if (0 == strcmp(tok, "sse3"))
              m_cpuFeatures |= CPU_FEATURE_SSE3;
            else if (0 == strcmp(tok, "ssse3"))
              m_cpuFeatures |= CPU_FEATURE_SSSE3;
            else if (0 == strcmp(tok, "sse4_1"))
              m_cpuFeatures |= CPU_FEATURE_SSE4;
            else if (0 == strcmp(tok, "sse4_2"))
              m_cpuFeatures |= CPU_FEATURE_SSE42;
            else if (0 == strcmp(tok, "3dnow"))
              m_cpuFeatures |= CPU_FEATURE_3DNOW;
            else if (0 == strcmp(tok, "3dnowext"))
              m_cpuFeatures |= CPU_FEATURE_3DNOWEXT;
            tok = strtok_r(NULL, " ", &save);
          }
        }
      }
    }
    fclose(fCPUInfo);
  }
  else
  {
    m_cpuCount = 1;
    m_cpuModel = "Unknown";
  }

#endif
  StringUtils::Replace(m_cpuModel, '\r', ' ');
  StringUtils::Replace(m_cpuModel, '\n', ' ');
  StringUtils::RemoveDuplicatedSpacesAndTabs(m_cpuModel);
  StringUtils::Trim(m_cpuModel);

  /* Set some default for empty string variables */
  if (m_cpuBogoMips.empty())
    m_cpuBogoMips = "N/A";
  if (m_cpuHardware.empty())
    m_cpuHardware = "N/A";
  if (m_cpuRevision.empty())
    m_cpuRevision = "N/A";
  if (m_cpuSerial.empty())
    m_cpuSerial = "N/A";

  readProcStat(m_userTicks, m_niceTicks, m_systemTicks, m_idleTicks, m_ioTicks);
  m_nextUsedReadTime.Set(MINIMUM_TIME_BETWEEN_READS);

  ReadCPUFeatures();

  // Set MMX2 when SSE is present as SSE is a superset of MMX2 and Intel doesn't set the MMX2 cap
  if (m_cpuFeatures & CPU_FEATURE_SSE)
    m_cpuFeatures |= CPU_FEATURE_MMX2;

  if (HasNeon())
    m_cpuFeatures |= CPU_FEATURE_NEON;

}
예제 #19
0
void PrintBacktrace(void) {
    int                         err;
    QCrashReportRef             crRef = NULL;

    char                        nameBuf[256], pathToThisProcess[1024];
    const NXArchInfo            *localArch;
    char                        OSMinorVersion = '?';
    time_t                      t;
    char                        atosPipeBuf[1024], cppfiltPipeBuf[1024];
    char                        outBuf[1024], offsetBuf[32];
    char                        *sourceSymbol, *symbolEnd;
    char                        **symbols = NULL;
    void                        *callstack[CALL_STACK_SIZE];
    int                         frames, i;
    void                        *systemlib = NULL;
    FILE                        *atosPipe = NULL;
    FILE                        *cppfiltPipe = NULL;
    backtraceProc               myBacktraceProc = NULL;
    backtrace_symbolsProc       myBacktrace_symbolsProc = NULL;
    char                        saved_env[128], *env = NULL;
    bool                        atosExists = false, cppfiltExists = false;

#if 0
// To debug backtrace logic:
//  * Enable this block of code.
//  * Set a breakpoint at sleep(1) call, and wherever else you wish.
//  * Launch built development application from Finder.
//  * Get this application's pid from Activity Monitor.
//  * Attach Debugger to this application.
//  * Continue until you reach this breakpoint.
//  * Change wait variable to 0 (false).
// This is necessary because GDB intercepts signals even if you tell it 
// not to, so you must attach GDB after the signal handler is invoked.

    bool wait = true;
    
    while (wait) {
        fprintf(stderr, "waiting\n");
        sleep(1);
    }
#endif

    GetNameOfAndPathToThisProcess(nameBuf, sizeof(nameBuf), pathToThisProcess, sizeof(pathToThisProcess));
    
    if (nameBuf[0]) {
        fprintf(stderr, "\nCrashed executable name: %s\n", nameBuf);
    }
    
#ifdef BOINC_VERSION_STRING
    fprintf(stderr, "built using BOINC library version %s\n", BOINC_VERSION_STRING);
#endif

    localArch = NXGetLocalArchInfo();
    fprintf(stderr, "Machine type %s", localArch->description);
#ifdef __LP64__
    fprintf(stderr, " (64-bit executable)\n");
#else
    fprintf(stderr, " (32-bit executable)\n");
#endif

    PrintOSVersion(&OSMinorVersion);

    time(&t);
    fputs(asctime(localtime(&t)), stderr);
    fputc('\n', stderr);
    
    err = QCRCreateFromSelf(&crRef);

    if (OSMinorVersion == '5') {
#ifdef __ppc__
        fputs("BOINC backtrace under OS 10.5.x only shows exported (global) symbols\n", stderr);
        fputs("and may work poorly on a PowerPC Mac after a crash.  For a better\n", stderr);
        fputs("backtrace, run under OS 10.4.x.\n\n", stderr);
#else
        fputs("BOINC backtrace under OS 10.5.x only shows exported (global) symbols\n", stderr);
        fputs("and may not show the final location which caused a crash.  For a better\n", stderr);
        fputs("backtrace, either run under OS 10.4.x or run under OS 10.6.x or later.\n\n", stderr);
#endif
    }
    
    if (OSMinorVersion >= '5') {
        // Use new backtrace functions if available (only in OS 10.5 and later)
        systemlib = dlopen ("/usr/lib/libSystem.dylib", RTLD_NOW );
        if (systemlib) {
            myBacktraceProc = (backtraceProc)dlsym(systemlib, "backtrace");
         }
        if (! myBacktraceProc) {
            goto skipBackTrace;     // Should never happen
        }
        frames = myBacktraceProc(callstack, CALL_STACK_SIZE);
        myBacktrace_symbolsProc = (backtrace_symbolsProc)dlsym(systemlib, "backtrace_symbols");
        if (myBacktrace_symbolsProc) {
            symbols = myBacktrace_symbolsProc(callstack, frames);
        } else {
            goto skipBackTrace;     // Should never happen
        }
        
        atosExists = boinc_file_exists("/usr/bin/atos");
        cppfiltExists = boinc_file_exists("/usr/bin/atos");
        if (atosExists || cppfiltExists) {
            // The bidirectional popen only works if the NSUnbufferedIO environment 
            // variable is set, so we save and restore its current value.
            env = getenv("NSUnbufferedIO");
            if (env) {
                strlcpy(saved_env, env, sizeof(saved_env));
            }
            setenv("NSUnbufferedIO", "YES", 1);
        }
        
        if (atosExists) {
            // The backtrace_symbols() and backtrace_symbols() APIs are limited to 
            // external symbols only, so we also use the atos command-line utility  
            // which gives us debugging symbols when available.
            //
            // For some reason, using the -p option with the value from getpid() 
            // fails here but the -o option with a path does work.
#ifdef __x86_64__
            snprintf(atosPipeBuf, sizeof(atosPipeBuf), "/usr/bin/atos -o \"%s\" -arch x86_64", pathToThisProcess);
#elif defined (__i386__)
            snprintf(atosPipeBuf, sizeof(atosPipeBuf), "/usr/bin/atos -o \"%s\" -arch i386", pathToThisProcess);
#else
            snprintf(atosPipeBuf, sizeof(atosPipeBuf), "/usr/bin/atos -o \"%s\" -arch ppc", pathToThisProcess);
#endif

            atosPipe = popen(atosPipeBuf, "r+");
            if (atosPipe) {
                setbuf(atosPipe, 0);
            }
        }

        if (cppfiltExists) {
            cppfiltPipe = popen("/usr/bin/c++filt -s gnu-v3 -n", "r+");
            if (cppfiltPipe) {
                setbuf(cppfiltPipe, 0);
            }
        }
        
        for (i=0; i<frames; i++) {
            strlcpy(outBuf, symbols[i], sizeof(outBuf));
            if (cppfiltPipe) {
                sourceSymbol = strstr(outBuf, "0x");
                if (sourceSymbol) {
                    sourceSymbol = strchr(sourceSymbol, (int)'_');
                    if (sourceSymbol) {
                        strlcpy(cppfiltPipeBuf, sourceSymbol, sizeof(cppfiltPipeBuf)-1);
                        *sourceSymbol = '\0';
                        symbolEnd = strchr(cppfiltPipeBuf, (int)' ');
                        if (symbolEnd) {
                            strlcpy(offsetBuf, symbolEnd, sizeof(offsetBuf));
                            *symbolEnd = '\0';
                        }
                        fprintf(cppfiltPipe, "%s\n", cppfiltPipeBuf);
                        BT_PersistentFGets(cppfiltPipeBuf, sizeof(cppfiltPipeBuf), cppfiltPipe);
                        symbolEnd = strchr(cppfiltPipeBuf, (int)'\n');
                        if (symbolEnd) {
                            *symbolEnd = '\0';
                        }
                        strlcat(outBuf, cppfiltPipeBuf, sizeof(outBuf));
                        strlcat(outBuf, offsetBuf, sizeof(outBuf));
                    }
                }
            }
            
            if (atosPipe) {
                fprintf(atosPipe, "%#llx\n", (QTMAddr)callstack[i]);
                BT_PersistentFGets(atosPipeBuf, sizeof(atosPipeBuf), atosPipe);
                sourceSymbol = strstr(atosPipeBuf, "0x");
                if (!sourceSymbol) {        // If atos returned a symbol (not just a hex value)
                    sourceSymbol = strstr(outBuf, "0x");
                    if (sourceSymbol) sourceSymbol = strstr(sourceSymbol, " ");
                    if (sourceSymbol) *++sourceSymbol = '\0'; // Remove questionable symbol from backtrace_symbols()
                    strlcat(outBuf, " ", sizeof(outBuf));
                    strlcat(outBuf, atosPipeBuf, sizeof(outBuf));
                    symbolEnd = strchr(outBuf, (int)'\n');
                    if (symbolEnd) {
                        *symbolEnd = '\0';
                    }
                }
            }
            fprintf(stderr, "%s\n", outBuf);
        }

        if (atosPipe) {
            pclose(atosPipe);
        }
        
        if (cppfiltPipe) {
            pclose(cppfiltPipe);
        }

        if (atosExists || cppfiltExists) {
            if (env) {
                setenv("NSUnbufferedIO", saved_env, 1);
            } else {
                unsetenv("NSUnbufferedIO");
            }
        }
        
skipBackTrace:
        fprintf(stderr, "\n");
    } else {
    // Not OS 10.5.x
        QCRPrintBacktraces(crRef, stderr);
    }

    // make sure this much gets written to file in case future 
    // versions of OS break our crash dump code beyond this point.
    fflush(stderr);
    
    QCRPrintThreadState(crRef, stderr);
    QCRPrintImages(crRef, stderr);
}
예제 #20
0
const char* ksmach_currentCPUArch(void)
{
    const NXArchInfo* archInfo = NXGetLocalArchInfo();
    return archInfo == NULL ? NULL : archInfo->name;
}
예제 #21
0
MODULE_SCOPE int
TclpLoadMemory(
    Tcl_Interp *interp,		/* Used for error reporting. */
    void *buffer,		/* Buffer containing the desired code
				 * (allocated with TclpLoadMemoryGetBuffer). */
    int size,			/* Allocation size of buffer. */
    int codeSize,		/* Size of code data read into buffer or -1 if
				 * an error occurred and the buffer should
				 * just be freed. */
    Tcl_LoadHandle *loadHandle, /* Filled with token for dynamically loaded
				 * file which will be passed back to
				 * (*unloadProcPtr)() to unload the file. */
    Tcl_FSUnloadFileProc **unloadProcPtr)
				/* Filled with address of Tcl_FSUnloadFileProc
				 * function which should be used for this
				 * file. */
{
    Tcl_DyldLoadHandle *dyldLoadHandle;
    NSObjectFileImage dyldObjFileImage = NULL;
    Tcl_DyldModuleHandle *modulePtr;
    NSModule module;
    const char *objFileImageErrMsg = NULL;

    /*
     * Try to create an object file image that we can load from.
     */

    if (codeSize >= 0) {
	NSObjectFileImageReturnCode err = NSObjectFileImageSuccess;
	const struct fat_header *fh = buffer;
	uint32_t ms = 0;
#ifndef __LP64__
	const struct mach_header *mh = NULL;
	#define mh_size  sizeof(struct mach_header)
	#define mh_magic MH_MAGIC
	#define arch_abi 0
#else
	const struct mach_header_64 *mh = NULL;
	#define mh_size  sizeof(struct mach_header_64)
	#define mh_magic MH_MAGIC_64
	#define arch_abi CPU_ARCH_ABI64
#endif

	if ((size_t) codeSize >= sizeof(struct fat_header)
		&& fh->magic == OSSwapHostToBigInt32(FAT_MAGIC)) {
	    uint32_t fh_nfat_arch = OSSwapBigToHostInt32(fh->nfat_arch);

	    /*
	     * Fat binary, try to find mach_header for our architecture
	     */

	    TclLoadDbgMsg("Fat binary, %d archs", fh_nfat_arch);
	    if ((size_t) codeSize >= sizeof(struct fat_header) +
		    fh_nfat_arch * sizeof(struct fat_arch)) {
		void *fatarchs = (char*)buffer + sizeof(struct fat_header);
		const NXArchInfo *arch = NXGetLocalArchInfo();
		struct fat_arch *fa;

		if (fh->magic != FAT_MAGIC) {
		    swap_fat_arch(fatarchs, fh_nfat_arch, arch->byteorder);
		}
		fa = NXFindBestFatArch(arch->cputype | arch_abi,
			arch->cpusubtype, fatarchs, fh_nfat_arch);
		if (fa) {
		    TclLoadDbgMsg("NXFindBestFatArch() successful: "
			    "local cputype %d subtype %d, "
			    "fat cputype %d subtype %d",
			    arch->cputype | arch_abi, arch->cpusubtype,
			    fa->cputype, fa->cpusubtype);
		    mh = (void*)((char*)buffer + fa->offset);
		    ms = fa->size;
		} else {
		    TclLoadDbgMsg("NXFindBestFatArch() failed");
		    err = NSObjectFileImageInappropriateFile;
		}
		if (fh->magic != FAT_MAGIC) {
		    swap_fat_arch(fatarchs, fh_nfat_arch, arch->byteorder);
		}
	    } else {
		TclLoadDbgMsg("Fat binary header failure");
		err = NSObjectFileImageInappropriateFile;
	    }
	} else {
	    /*
	     * Thin binary
	     */

	    TclLoadDbgMsg("Thin binary");
	    mh = buffer;
	    ms = codeSize;
	}
	if (ms && !(ms >= mh_size && mh->magic == mh_magic &&
		 mh->filetype == MH_BUNDLE)) {
	    TclLoadDbgMsg("Inappropriate file: magic %x filetype %d",
		    mh->magic, mh->filetype);
	    err = NSObjectFileImageInappropriateFile;
	}
	if (err == NSObjectFileImageSuccess) {
	    err = NSCreateObjectFileImageFromMemory(buffer, codeSize,
		    &dyldObjFileImage);
	    if (err == NSObjectFileImageSuccess) {
		TclLoadDbgMsg("NSCreateObjectFileImageFromMemory() "
			"successful");
	    } else {
		objFileImageErrMsg = DyldOFIErrorMsg(err);
		TclLoadDbgMsg("NSCreateObjectFileImageFromMemory() failed: %s",
			objFileImageErrMsg);
	    }
	} else {
	    objFileImageErrMsg = DyldOFIErrorMsg(err);
	}
    }

    /*
     * If it went wrong (or we were asked to just deallocate), get rid of the
     * memory block and create an error message.
     */

    if (dyldObjFileImage == NULL) {
	vm_deallocate(mach_task_self(), (vm_address_t) buffer, size);
	if (objFileImageErrMsg != NULL) {
	    Tcl_AppendResult(interp, "NSCreateObjectFileImageFromMemory() "
		    "error: ", objFileImageErrMsg, NULL);
	}
	return TCL_ERROR;
    }

    /*
     * Extract the module we want from the image of the object file.
     */

    module = NSLinkModule(dyldObjFileImage, "[Memory Based Bundle]",
	    NSLINKMODULE_OPTION_BINDNOW | NSLINKMODULE_OPTION_RETURN_ON_ERROR);
    NSDestroyObjectFileImage(dyldObjFileImage);
    if (module) {
	TclLoadDbgMsg("NSLinkModule() successful");
    } else {
	NSLinkEditErrors editError;
	int errorNumber;
	const char *errorName, *errMsg;

	NSLinkEditError(&editError, &errorNumber, &errorName, &errMsg);
	TclLoadDbgMsg("NSLinkModule() failed: %s", errMsg);
	Tcl_AppendResult(interp, errMsg, NULL);
	return TCL_ERROR;
    }

    /*
     * Stash the module reference within the load handle we create and return.
     */

    modulePtr = (Tcl_DyldModuleHandle *) ckalloc(sizeof(Tcl_DyldModuleHandle));
    modulePtr->module = module;
    modulePtr->nextPtr = NULL;
    dyldLoadHandle = (Tcl_DyldLoadHandle *)
	    ckalloc(sizeof(Tcl_DyldLoadHandle));
#if TCL_DYLD_USE_DLFCN
    dyldLoadHandle->dlHandle = NULL;
#endif
    dyldLoadHandle->dyldLibHeader = NULL;
    dyldLoadHandle->modulePtr = modulePtr;
    *loadHandle = (Tcl_LoadHandle) dyldLoadHandle;
    *unloadProcPtr = &TclpUnloadFile;
    return TCL_OK;
}