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; }
unsigned short getCpuHash() { const NXArchInfo* info = NXGetLocalArchInfo(); unsigned short val = 0; val += (unsigned short)info->cputype; val += (unsigned short)info->cpusubtype; return val; }
/** * \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; }
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; }
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; }
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); }
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; }
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; }
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; }
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; }
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; }
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); }
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); }
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); }
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; }
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); }
const char* ksmach_currentCPUArch(void) { const NXArchInfo* archInfo = NXGetLocalArchInfo(); return archInfo == NULL ? NULL : archInfo->name; }
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; }