├── ioalloccount.tproj ├── ioalloccount.8 └── ioalloccount.c ├── ioclasscount.tproj ├── ioclasscount.8 └── ioclasscount.c ├── ioreg.tproj ├── ioreg.8 └── ioreg.c ├── IOKitTools.xcodeproj └── project.pbxproj └── APPLE_LICENSE /ioalloccount.tproj/ioalloccount.8: -------------------------------------------------------------------------------- 1 | .\" 2 | .\" Copyright (c) 2000-2008 Apple Computer, Inc. All rights reserved. 3 | .\" 4 | .\" $Id: ioalloccount.8,v 1.4 2004/10/22 23:39:09 dreece Exp $ 5 | .\" 6 | .Dd November 06, 2008 7 | .Dt IOALLOCCOUNT 8 8 | .Os Darwin 9 | .Sh NAME 10 | .Nm ioalloccount 11 | .Nd Summarize IOKit memory usage. 12 | .Sh SYNOPSIS 13 | .Nm 14 | .Sh DESCRIPTION 15 | .Nm 16 | displays some accounting of memory allocated by IOKit allocators, 17 | including object instances, in the kernel. 18 | .Pp 19 | This information is useful for tracking leaks. 20 | Instance counts can also found in the root of the IORegistry 21 | in the 22 | .Dq IOKitDiagnostics 23 | property. 24 | .Sh EXAMPLES 25 | .Bl -tag -width findx 26 | .It Li "ioalloccount" 27 | Instance allocation = 0x0022c718 = 2225 K 28 | Container allocation = 0x00141bad = 1286 K 29 | IOMalloc allocation = 0x00638221 = 6368 K 30 | Pageable allocation = 0x00f4f000 = 15676 K 31 | .El 32 | .Sh SEE ALSO 33 | .Xr ioclasscount 8 , 34 | .Xr ioreg 8 35 | -------------------------------------------------------------------------------- /ioclasscount.tproj/ioclasscount.8: -------------------------------------------------------------------------------- 1 | .\" 2 | .\" Copyright (c) 2000-2008 Apple Computer, Inc. All rights reserved. 3 | .\" 4 | .\" $Id: ioclasscount.8,v 1.4 2003/11/06 19:16:54 sdouglas Exp $ 5 | .\" 6 | .Dd November 06, 2008 7 | .Dt IOCLASSCOUNT 8 8 | .Os Darwin 9 | .Sh NAME 10 | .Nm ioclasscount 11 | .Sh SYNOPSIS 12 | .Nm 13 | .Op classname 14 | .Op ... 15 | .Sh DESCRIPTION 16 | .Nm 17 | displays the instance counts of OSObject-based C++ classes in the kernel, 18 | incremented by the number of 19 | .Em direct 20 | subclasses that have an instance count of at least 1. 21 | For example, if IONetworkController is not directly instantiated, 22 | but its direct subclass IOEthernetController has any instances, 23 | then IONetworkController's instance count will be at least 1; 24 | if another direct subclass such as IOFWController has any instances, 25 | then IONetworkController's instance count will be at least 2; and so on. 26 | (This modification of instance counts prevents unloading of 27 | kexts defining superclasses that have no instances, 28 | but whose subclasses in other kexts have instances.) 29 | .Pp 30 | If classes are specified, 31 | instance counts are printed as a comma-separated list 32 | in the order specified. 33 | If no classes are specified, 34 | instance counts for all classes are printed, 35 | one per line of output and sorted by name. 36 | .Pp 37 | This information is useful for tracking leaks. 38 | Instance counts can also found in the root of the IORegistry 39 | in the 40 | .Dq IOKitDiagnostics 41 | property. 42 | .Sh EXAMPLES 43 | Display instance counts for IOPCIDevice and AppleTestPCI: 44 | .Bl -tag -width findx 45 | .It Li "/usr/sbin/ioclasscount IOPCIDevice AppleTestPCI" 46 | IOPCIDevice = 2, AppleTestPCI = 1 47 | .El 48 | .Sh SEE ALSO 49 | .Xr ioalloccount 8 , 50 | .Xr ioreg 8 51 | -------------------------------------------------------------------------------- /ioreg.tproj/ioreg.8: -------------------------------------------------------------------------------- 1 | .\" 2 | .\" Copyright (c) 2000-2011 Apple Computer, Inc. All rights reserved. 3 | .\" 4 | .\" This file contains Original Code and/or Modifications of Original Code 5 | .\" as defined in and that are subject to the Apple Public Source License 6 | .\" Version 2.0 (the 'License'). You may not use this file except in 7 | .\" compliance with the License. Please obtain a copy of the License at 8 | .\" http://www.opensource.apple.com/apsl/ and read it before using this 9 | .\" file. 10 | .\" 11 | .\" The Original Code and all software distributed under the License are 12 | .\" distributed on an 'AS IS' basis, WITHOUT WARRANTY OF ANY KIND, EITHER 13 | .\" EXPRESS OR IMPLIED, AND APPLE HEREBY DISCLAIMS ALL SUCH WARRANTIES, 14 | .\" INCLUDING WITHOUT LIMITATION, ANY WARRANTIES OF MERCHANTABILITY, 15 | .\" FITNESS FOR A PARTICULAR PURPOSE, QUIET ENJOYMENT OR NON-INFRINGEMENT. 16 | .\" Please see the License for the specific language governing rights and 17 | .\" limitations under the License. 18 | .\" 19 | .Dd September 26, 2011 20 | .Dt IOREG 8 21 | .Os Darwin 22 | .Sh NAME 23 | .Nm ioreg 24 | .Nd show I/O Kit registry 25 | .Sh SYNOPSIS 26 | .Nm 27 | .Op Fl abfilrtx 28 | .Op Fl c Ar class 29 | .Op Fl d Ar depth 30 | .Op Fl k Ar key 31 | .Op Fl n Ar name 32 | .Op Fl p Ar plane 33 | .Op Fl w Ar width 34 | .Sh DESCRIPTION 35 | .Nm 36 | displays the I/O Kit registry. It shows the heirarchical registry structure 37 | as an inverted tree. The provider-client relationships among those objects 38 | is shown as follows: 39 | .Pp 40 | +-o provider 41 | | 42 | +-o client 43 | .Pp 44 | By default, object properties are not shown. The use of the 45 | .Fl c , 46 | .Fl k , 47 | .Fl l , 48 | or 49 | .Fl n 50 | options cause 51 | .Nm 52 | to show properties for objects that match the specified criteria. 53 | .Pp 54 | By supplying the 55 | .Fl r 56 | option, the user may specify the object which will 57 | appear at the root of the tree with the 58 | .Fl c , 59 | .Fl k , 60 | or 61 | .Fl n 62 | options. If root matches more 63 | than one object, multiple trees will be displayed. 64 | .Pp 65 | The options are as follows: 66 | .Pp 67 | .Bl -tag -width flag 68 | .It Fl a 69 | Archive the output in XML. 70 | .It Fl b 71 | Show the object name in bold. 72 | .It Fl c 73 | Show the object properties only if the object is an instance of, or derives from, the specified 74 | C++ 75 | .Ar class 76 | (e.g. IOService). 77 | .It Fl d 78 | Limit tree traversal to the specified 79 | .Ar depth . 80 | The depth limit is 81 | applied with respect to each subtree root individually. Therefore, 82 | supplying a depth of 1 will cause 83 | .Nm 84 | to display only (sub)tree 85 | root nodes; children will not be shown. 86 | .It Fl f 87 | Enable smart formatting. 88 | .Nm 89 | knows how to format certain properties 90 | so that the output is more readable and meaningful, decoding 91 | data fields where appropriate. Currently supported are `reg', 92 | `assigned-addresses', `slot-names', `ranges', `interrupt-map', 93 | `interrupt-parent`, and `interrupts'. 94 | .It Fl i 95 | Show the object inheritance. 96 | .It Fl k 97 | Show the object properties only if the object has the specified 98 | .Ar key . 99 | Substrings do not match; the specified key must be a full 100 | property name. 101 | .It Fl l 102 | Show properties for all displayed objects. 103 | .It Fl n 104 | Show the object properties only if the object has the specified 105 | .Ar name . 106 | The object location, if any, is considered part of the name, thus 107 | pci@f0000000 and pci@f4000000 are distinct names. 108 | .It Fl p 109 | Traverse the registry over the specified 110 | .Ar plane . 111 | The default plane value is ``IOService''. The other planes, such as ``IODeviceTree'', can be found under the ``IORegistryPlanes'' property of the root object (ioreg -d 1 -k IORegistryPlanes). 112 | .It Fl r 113 | Show subtrees rooted by objects that match the specified criteria. If none of 114 | .Fl c , 115 | .Fl k , 116 | or 117 | .Fl n 118 | are supplied, 119 | .Fl r 120 | has no effect. 121 | .It Fl t 122 | Show tree location of each subtree. This option causes 123 | .Nm 124 | to display all nodes between the I/O Kit Root and the root of the 125 | displayed subtree, i.e. the subtree's parent, grandparent, etc. 126 | .It Fl w 127 | Clip the output to the specified line 128 | .Ar width . 129 | The default width value is the current screen size. A value of 0 specifies an unlimited line width. 130 | .It Fl x 131 | Show data and numbers as hexadecimal. 132 | .El 133 | -------------------------------------------------------------------------------- /ioalloccount.tproj/ioalloccount.c: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright (c) 2009 Apple Inc. All rights reserved. 3 | * 4 | * @APPLE_LICENSE_HEADER_START@ 5 | * 6 | * This file contains Original Code and/or Modifications of Original Code 7 | * as defined in and that are subject to the Apple Public Source License 8 | * Version 2.0 (the 'License'). You may not use this file except in 9 | * compliance with the License. Please obtain a copy of the License at 10 | * http://www.opensource.apple.com/apsl/ and read it before using this 11 | * file. 12 | * 13 | * The Original Code and all software distributed under the License are 14 | * distributed on an 'AS IS' basis, WITHOUT WARRANTY OF ANY KIND, EITHER 15 | * EXPRESS OR IMPLIED, AND APPLE HEREBY DISCLAIMS ALL SUCH WARRANTIES, 16 | * INCLUDING WITHOUT LIMITATION, ANY WARRANTIES OF MERCHANTABILITY, 17 | * FITNESS FOR A PARTICULAR PURPOSE, QUIET ENJOYMENT OR NON-INFRINGEMENT. 18 | * Please see the License for the specific language governing rights and 19 | * limitations under the License. 20 | * 21 | * @APPLE_LICENSE_HEADER_END@ 22 | */ 23 | /* 24 | cc alloccount.c -o alloccount -Wall -framework IOKit 25 | */ 26 | 27 | #include 28 | #include 29 | #include 30 | #include 31 | #include 32 | 33 | /********************************************************************* 34 | *********************************************************************/ 35 | static Boolean printNumber( 36 | CFDictionaryRef dict, 37 | CFStringRef name, 38 | char ** nameCString) 39 | { 40 | int result = FALSE; 41 | CFIndex nameLength = 0; 42 | static char * nameBuffer = NULL; // free if nameCString is NULL 43 | CFNumberRef num = NULL; // do not release 44 | SInt32 num32 = 0; 45 | Boolean gotName = FALSE; 46 | Boolean gotNum = FALSE; 47 | 48 | /* Note that errors displaying the name and value are not considered 49 | * fatal and do not affect the exit status of the program. 50 | */ 51 | num = (CFNumberRef)CFDictionaryGetValue(dict, name); 52 | if (num) { 53 | nameLength = CFStringGetMaximumSizeForEncoding(CFStringGetLength(name), 54 | kCFStringEncodingUTF8); 55 | if (!nameCString || !*nameCString) { 56 | nameBuffer = (char *)malloc((1 + nameLength) * sizeof(char)); 57 | } else if ((1 + nameLength) > malloc_size(nameBuffer)) { 58 | nameBuffer = (char *)realloc(*nameCString, 59 | (1 + nameLength) * sizeof(char)); 60 | } 61 | if (nameBuffer) { 62 | gotName = CFStringGetCString(name, nameBuffer, 1 + nameLength, 63 | kCFStringEncodingUTF8); 64 | } else { 65 | fprintf(stderr, "Memory allocation failure.\n"); 66 | goto finish; 67 | } 68 | printf("%22s = ", gotName ? nameBuffer : "??"); 69 | 70 | if (CFNumberGetTypeID() == CFGetTypeID(num)) { 71 | gotNum = CFNumberGetValue(num, kCFNumberSInt32Type, &num32); 72 | } 73 | if (gotNum) { 74 | printf("0x%08lx = %4lu K\n", 75 | (unsigned long)num32, 76 | (unsigned long)(num32 / 1024)); 77 | } else { 78 | printf("?? (error reading/converting value)\n"); 79 | } 80 | } 81 | 82 | result = TRUE; 83 | 84 | finish: 85 | if (nameCString) { 86 | *nameCString = nameBuffer; 87 | } else { 88 | if (nameBuffer) free(nameBuffer); 89 | } 90 | return result; 91 | } 92 | 93 | /********************************************************************* 94 | *********************************************************************/ 95 | int main(int argc, char ** argv) 96 | { 97 | int result = EX_OSERR; 98 | io_registry_entry_t root = IO_OBJECT_NULL; // must IOObjectRelease() 99 | CFDictionaryRef rootProps = NULL; // must release 100 | CFDictionaryRef allocInfo = NULL; // do not release 101 | kern_return_t status = KERN_FAILURE; 102 | char * nameCString = NULL; // must free 103 | 104 | // Obtain the registry root entry. 105 | 106 | root = IORegistryGetRootEntry(kIOMasterPortDefault); 107 | if (!root) { 108 | fprintf(stderr, "Error: Can't get registry root.\n"); 109 | goto finish; 110 | } 111 | 112 | status = IORegistryEntryCreateCFProperties(root, 113 | (CFMutableDictionaryRef *)&rootProps, 114 | kCFAllocatorDefault, kNilOptions ); 115 | if (KERN_SUCCESS != status) { 116 | fprintf(stderr, "Error: Can't read registry root properties.\n"); 117 | goto finish; 118 | } 119 | if (CFDictionaryGetTypeID() != CFGetTypeID(rootProps)) { 120 | fprintf(stderr, "Error: Registry root properties not a dictionary.\n"); 121 | goto finish; 122 | } 123 | 124 | allocInfo = (CFDictionaryRef)CFDictionaryGetValue(rootProps, 125 | CFSTR(kIOKitDiagnosticsKey)); 126 | if (!allocInfo) { 127 | fprintf(stderr, "Error: Allocation information missing.\n"); 128 | goto finish; 129 | } 130 | if (CFDictionaryGetTypeID() != CFGetTypeID(allocInfo)) { 131 | fprintf(stderr, "Error: Allocation information not a dictionary.\n"); 132 | goto finish; 133 | } 134 | 135 | if (!(printNumber(allocInfo, CFSTR("Instance allocation"), &nameCString) && 136 | printNumber(allocInfo, CFSTR("Container allocation"), &nameCString) && 137 | printNumber(allocInfo, CFSTR("IOMalloc allocation"), &nameCString) && 138 | printNumber(allocInfo, CFSTR("Pageable allocation"), &nameCString) )) { 139 | 140 | goto finish; 141 | } 142 | 143 | result = EX_OK; 144 | 145 | finish: 146 | if (nameCString) free(nameCString); 147 | if (rootProps) CFRelease(rootProps); 148 | if (root != IO_OBJECT_NULL) IOObjectRelease(root); 149 | 150 | return result; 151 | } 152 | 153 | -------------------------------------------------------------------------------- /ioclasscount.tproj/ioclasscount.c: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright (c) 2009 Apple Inc. All rights reserved. 3 | * 4 | * @APPLE_LICENSE_HEADER_START@ 5 | * 6 | * This file contains Original Code and/or Modifications of Original Code 7 | * as defined in and that are subject to the Apple Public Source License 8 | * Version 2.0 (the 'License'). You may not use this file except in 9 | * compliance with the License. Please obtain a copy of the License at 10 | * http://www.opensource.apple.com/apsl/ and read it before using this 11 | * file. 12 | * 13 | * The Original Code and all software distributed under the License are 14 | * distributed on an 'AS IS' basis, WITHOUT WARRANTY OF ANY KIND, EITHER 15 | * EXPRESS OR IMPLIED, AND APPLE HEREBY DISCLAIMS ALL SUCH WARRANTIES, 16 | * INCLUDING WITHOUT LIMITATION, ANY WARRANTIES OF MERCHANTABILITY, 17 | * FITNESS FOR A PARTICULAR PURPOSE, QUIET ENJOYMENT OR NON-INFRINGEMENT. 18 | * Please see the License for the specific language governing rights and 19 | * limitations under the License. 20 | * 21 | * @APPLE_LICENSE_HEADER_END@ 22 | */ 23 | /* 24 | cc ioclasscount.c -o /tmp/ioclasscount -Wall -framework IOKit -framework CoreFoundation 25 | */ 26 | 27 | #include 28 | #include 29 | #include 30 | #include 31 | #include 32 | 33 | /********************************************************************* 34 | *********************************************************************/ 35 | static int compareClassNames(const void * left, const void * right) 36 | { 37 | switch (CFStringCompare(*((CFStringRef *)left), *((CFStringRef *)right), 38 | (CFStringCompareFlags)kCFCompareCaseInsensitive)) { 39 | case kCFCompareLessThan: 40 | return -1; 41 | break; 42 | case kCFCompareEqualTo: 43 | return 0; 44 | break; 45 | case kCFCompareGreaterThan: 46 | return 1; 47 | break; 48 | default: 49 | fprintf(stderr, "fatal error\n"); 50 | exit(EX_OSERR); 51 | return 0; 52 | break; 53 | } 54 | } 55 | 56 | /********************************************************************* 57 | *********************************************************************/ 58 | static Boolean printInstanceCount( 59 | CFDictionaryRef dict, 60 | CFStringRef name, 61 | char ** nameCString, 62 | Boolean addNewlineFlag) 63 | { 64 | int result = FALSE; 65 | CFIndex nameLength = 0; 66 | static char * nameBuffer = NULL; // free if nameCString is NULL 67 | CFNumberRef num = NULL; // do not release 68 | SInt32 num32 = 0; 69 | Boolean gotName = FALSE; 70 | Boolean gotNum = FALSE; 71 | 72 | nameLength = CFStringGetMaximumSizeForEncoding(CFStringGetLength(name), 73 | kCFStringEncodingUTF8); 74 | if (!nameCString || !*nameCString) { 75 | nameBuffer = (char *)malloc((1 + nameLength) * sizeof(char)); 76 | } else if ((1 + nameLength) > malloc_size(nameBuffer)) { 77 | nameBuffer = (char *)realloc(*nameCString, 78 | (1 + nameLength) * sizeof(char)); 79 | } 80 | if (nameBuffer) { 81 | gotName = CFStringGetCString(name, nameBuffer, 1 + nameLength, 82 | kCFStringEncodingUTF8); 83 | } else { 84 | fprintf(stderr, "Memory allocation failure.\n"); 85 | goto finish; 86 | } 87 | 88 | /* Note that errors displaying the name and value are not considered 89 | * fatal and do not affect the exit status of the program. 90 | */ 91 | printf("%s = ", gotName ? nameBuffer : "??"); 92 | 93 | num = (CFNumberRef)CFDictionaryGetValue(dict, name); 94 | if (num) { 95 | 96 | if (CFNumberGetTypeID() == CFGetTypeID(num)) { 97 | gotNum = CFNumberGetValue(num, kCFNumberSInt32Type, &num32); 98 | } 99 | if (gotNum) { 100 | printf("%lu", (unsigned long)num32); 101 | } else { 102 | printf("?? (error reading/converting value)"); 103 | } 104 | } else { 105 | printf(""); 106 | } 107 | 108 | if (addNewlineFlag) { 109 | printf("\n"); 110 | } else { 111 | printf(", "); 112 | } 113 | 114 | result = TRUE; 115 | 116 | finish: 117 | if (nameCString) { 118 | *nameCString = nameBuffer; 119 | } else { 120 | if (nameBuffer) free(nameBuffer); 121 | } 122 | return result; 123 | } 124 | 125 | /********************************************************************* 126 | *********************************************************************/ 127 | int main(int argc, char ** argv) 128 | { 129 | int result = EX_OSERR; 130 | kern_return_t status = KERN_FAILURE; 131 | io_registry_entry_t root = IO_OBJECT_NULL; // must IOObjectRelease() 132 | CFMutableDictionaryRef rootProps = NULL; // must release 133 | CFDictionaryRef diagnostics = NULL; // do not release 134 | CFDictionaryRef classes = NULL; // do not release 135 | CFStringRef * classNames = NULL; // must free 136 | CFStringRef className = NULL; // must release 137 | char * nameCString = NULL; // must free 138 | 139 | // Obtain the registry root entry. 140 | 141 | root = IORegistryGetRootEntry(kIOMasterPortDefault); 142 | if (!root) { 143 | fprintf(stderr, "Error: Can't get registry root.\n"); 144 | goto finish; 145 | } 146 | 147 | status = IORegistryEntryCreateCFProperties(root, 148 | &rootProps, kCFAllocatorDefault, kNilOptions); 149 | if (KERN_SUCCESS != status) { 150 | fprintf(stderr, "Error: Can't read registry root properties.\n"); 151 | goto finish; 152 | } 153 | if (CFDictionaryGetTypeID() != CFGetTypeID(rootProps)) { 154 | fprintf(stderr, "Error: Registry root properties not a dictionary.\n"); 155 | goto finish; 156 | } 157 | 158 | diagnostics = (CFDictionaryRef)CFDictionaryGetValue(rootProps, 159 | CFSTR(kIOKitDiagnosticsKey)); 160 | if (!diagnostics) { 161 | fprintf(stderr, "Error: Allocation information missing.\n"); 162 | goto finish; 163 | } 164 | if (CFDictionaryGetTypeID() != CFGetTypeID(diagnostics)) { 165 | fprintf(stderr, "Error: Allocation information not a dictionary.\n"); 166 | goto finish; 167 | } 168 | 169 | classes = (CFDictionaryRef)CFDictionaryGetValue(diagnostics, CFSTR("Classes")); 170 | if (!classes) { 171 | fprintf(stderr, "Error: Class information missing.\n"); 172 | goto finish; 173 | } 174 | if (CFDictionaryGetTypeID() != CFGetTypeID(classes)) { 175 | fprintf(stderr, "Error: Class information not a dictionary.\n"); 176 | goto finish; 177 | } 178 | 179 | if (argc < 2) { 180 | CFIndex index, count; 181 | 182 | count = CFDictionaryGetCount(classes); 183 | classNames = (CFStringRef *)calloc(count, sizeof(CFStringRef)); 184 | if (!classNames) { 185 | fprintf(stderr, "Memory allocation failure.\n"); 186 | goto finish; 187 | } 188 | CFDictionaryGetKeysAndValues(classes, (const void **)classNames, NULL); 189 | qsort(classNames, count, sizeof(CFStringRef), &compareClassNames); 190 | 191 | for (index = 0; index < count; index++) { 192 | printInstanceCount(classes, classNames[index], &nameCString, 193 | /* addNewline? */ TRUE); 194 | } 195 | 196 | } else { 197 | uint32_t index = 0; 198 | for (index = 1; index < argc; index++ ) { 199 | 200 | if (className) CFRelease(className); 201 | className = NULL; 202 | 203 | className = CFStringCreateWithCString(kCFAllocatorDefault, 204 | argv[index], kCFStringEncodingUTF8); 205 | if (!className) { 206 | fprintf(stderr, "Error: Can't create CFString for '%s'.\n", 207 | argv[index]); 208 | goto finish; 209 | } 210 | printInstanceCount(classes, className, &nameCString, 211 | /* addNewline? */ (index + 1 == argc)); 212 | } 213 | } 214 | 215 | result = EX_OK; 216 | finish: 217 | if (rootProps) CFRelease(rootProps); 218 | if (root != IO_OBJECT_NULL) IOObjectRelease(root); 219 | if (classNames) free(classNames); 220 | if (className) CFRelease(className); 221 | if (nameCString) free(nameCString); 222 | 223 | return result; 224 | } 225 | 226 | -------------------------------------------------------------------------------- /IOKitTools.xcodeproj/project.pbxproj: -------------------------------------------------------------------------------- 1 | // !$*UTF8*$! 2 | { 3 | archiveVersion = 1; 4 | classes = { 5 | }; 6 | objectVersion = 42; 7 | objects = { 8 | 9 | /* Begin PBXAggregateTarget section */ 10 | 2D7D901F08F4AEF7003CF2E8 /* IOKitTools */ = { 11 | isa = PBXAggregateTarget; 12 | buildConfigurationList = 2D7D902708F4AF47003CF2E8 /* Build configuration list for PBXAggregateTarget "IOKitTools" */; 13 | buildPhases = ( 14 | 2D7D902208F4AF1E003CF2E8 /* CopyFiles */, 15 | ); 16 | dependencies = ( 17 | 2D7D903308F4AFE9003CF2E8 /* PBXTargetDependency */, 18 | 2D7D916508F4B0CB003CF2E8 /* PBXTargetDependency */, 19 | 2D7D916708F4B0CD003CF2E8 /* PBXTargetDependency */, 20 | ); 21 | name = IOKitTools; 22 | productName = IOKitTools; 23 | }; 24 | /* End PBXAggregateTarget section */ 25 | 26 | /* Begin PBXBuildFile section */ 27 | 2D7D902408F4AF3C003CF2E8 /* ioalloccount.8 in CopyFiles */ = {isa = PBXBuildFile; fileRef = 97CF609805585D4100A48F3A /* ioalloccount.8 */; }; 28 | 2D7D902508F4AF3C003CF2E8 /* ioclasscount.8 in CopyFiles */ = {isa = PBXBuildFile; fileRef = 97CF608505585D4100A48F3A /* ioclasscount.8 */; }; 29 | 2D7D902608F4AF3C003CF2E8 /* ioreg.8 in CopyFiles */ = {isa = PBXBuildFile; fileRef = 97CF603805585D4100A48F3A /* ioreg.8 */; }; 30 | 2D7D903408F4AFF9003CF2E8 /* ioreg.c in Sources */ = {isa = PBXBuildFile; fileRef = 97CF603205585D4100A48F3A /* ioreg.c */; }; 31 | 2D7D903508F4B001003CF2E8 /* CoreFoundation.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 97CF60A305585D4100A48F3A /* CoreFoundation.framework */; }; 32 | 2D7D903608F4B001003CF2E8 /* IOKit.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 97CF609C05585D4100A48F3A /* IOKit.framework */; }; 33 | 2D7D903708F4B001003CF2E8 /* libncurses.dylib in Frameworks */ = {isa = PBXBuildFile; fileRef = 97CF60D005585DC900A48F3A /* libncurses.dylib */; }; 34 | 2D7D915508F4B063003CF2E8 /* ioclasscount.c in Sources */ = {isa = PBXBuildFile; fileRef = 97CF607F05585D4100A48F3A /* ioclasscount.c */; }; 35 | 2D7D915608F4B076003CF2E8 /* CoreFoundation.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 97CF60A305585D4100A48F3A /* CoreFoundation.framework */; }; 36 | 2D7D915708F4B076003CF2E8 /* IOKit.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 97CF609C05585D4100A48F3A /* IOKit.framework */; }; 37 | 2D7D915C08F4B07A003CF2E8 /* CoreFoundation.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 97CF60A305585D4100A48F3A /* CoreFoundation.framework */; }; 38 | 2D7D915D08F4B07A003CF2E8 /* IOKit.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 97CF609C05585D4100A48F3A /* IOKit.framework */; }; 39 | 2D7D916308F4B0C2003CF2E8 /* ioalloccount.c in Sources */ = {isa = PBXBuildFile; fileRef = 97CF609205585D4100A48F3A /* ioalloccount.c */; }; 40 | /* End PBXBuildFile section */ 41 | 42 | /* Begin PBXContainerItemProxy section */ 43 | 2D7D903208F4AFE9003CF2E8 /* PBXContainerItemProxy */ = { 44 | isa = PBXContainerItemProxy; 45 | containerPortal = 97CF60AF05585D4200A48F3A /* Project object */; 46 | proxyType = 1; 47 | remoteGlobalIDString = 2D7D902C08F4AFC7003CF2E8; 48 | remoteInfo = ioreg; 49 | }; 50 | 2D7D916408F4B0CB003CF2E8 /* PBXContainerItemProxy */ = { 51 | isa = PBXContainerItemProxy; 52 | containerPortal = 97CF60AF05585D4200A48F3A /* Project object */; 53 | proxyType = 1; 54 | remoteGlobalIDString = 2D7D914F08F4B017003CF2E8; 55 | remoteInfo = ioclasscount; 56 | }; 57 | 2D7D916608F4B0CD003CF2E8 /* PBXContainerItemProxy */ = { 58 | isa = PBXContainerItemProxy; 59 | containerPortal = 97CF60AF05585D4200A48F3A /* Project object */; 60 | proxyType = 1; 61 | remoteGlobalIDString = 2D7D915808F4B07A003CF2E8; 62 | remoteInfo = ioalloccount; 63 | }; 64 | /* End PBXContainerItemProxy section */ 65 | 66 | /* Begin PBXCopyFilesBuildPhase section */ 67 | 2D7D902208F4AF1E003CF2E8 /* CopyFiles */ = { 68 | isa = PBXCopyFilesBuildPhase; 69 | buildActionMask = 8; 70 | dstPath = /usr/share/man/man8; 71 | dstSubfolderSpec = 0; 72 | files = ( 73 | 2D7D902408F4AF3C003CF2E8 /* ioalloccount.8 in CopyFiles */, 74 | 2D7D902508F4AF3C003CF2E8 /* ioclasscount.8 in CopyFiles */, 75 | 2D7D902608F4AF3C003CF2E8 /* ioreg.8 in CopyFiles */, 76 | ); 77 | runOnlyForDeploymentPostprocessing = 1; 78 | }; 79 | /* End PBXCopyFilesBuildPhase section */ 80 | 81 | /* Begin PBXFileReference section */ 82 | 056F26F20AFBD911006CB74E /* libMallocDebug.a */ = {isa = PBXFileReference; lastKnownFileType = archive.ar; name = libMallocDebug.a; path = /usr/lib/libMallocDebug.a; sourceTree = ""; }; 83 | 2D7D902D08F4AFC7003CF2E8 /* ioreg */ = {isa = PBXFileReference; explicitFileType = "compiled.mach-o.executable"; includeInIndex = 0; path = ioreg; sourceTree = BUILT_PRODUCTS_DIR; }; 84 | 2D7D915008F4B017003CF2E8 /* ioclasscount */ = {isa = PBXFileReference; explicitFileType = "compiled.mach-o.executable"; includeInIndex = 0; path = ioclasscount; sourceTree = BUILT_PRODUCTS_DIR; }; 85 | 2D7D916108F4B07A003CF2E8 /* ioalloccount */ = {isa = PBXFileReference; explicitFileType = "compiled.mach-o.executable"; includeInIndex = 0; path = ioalloccount; sourceTree = BUILT_PRODUCTS_DIR; }; 86 | 97CF603205585D4100A48F3A /* ioreg.c */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.c.c; path = ioreg.c; sourceTree = ""; }; 87 | 97CF603805585D4100A48F3A /* ioreg.8 */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = text; path = ioreg.8; sourceTree = ""; }; 88 | 97CF607F05585D4100A48F3A /* ioclasscount.c */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.c.c; path = ioclasscount.c; sourceTree = ""; }; 89 | 97CF608505585D4100A48F3A /* ioclasscount.8 */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = text; path = ioclasscount.8; sourceTree = ""; }; 90 | 97CF609205585D4100A48F3A /* ioalloccount.c */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.c.c; path = ioalloccount.c; sourceTree = ""; }; 91 | 97CF609805585D4100A48F3A /* ioalloccount.8 */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = text; path = ioalloccount.8; sourceTree = ""; }; 92 | 97CF609C05585D4100A48F3A /* IOKit.framework */ = {isa = PBXFileReference; lastKnownFileType = wrapper.framework; name = IOKit.framework; path = /System/Library/Frameworks/IOKit.framework; sourceTree = ""; }; 93 | 97CF60A305585D4100A48F3A /* CoreFoundation.framework */ = {isa = PBXFileReference; lastKnownFileType = wrapper.framework; name = CoreFoundation.framework; path = /System/Library/Frameworks/CoreFoundation.framework; sourceTree = ""; }; 94 | 97CF60A805585D4100A48F3A /* System.framework */ = {isa = PBXFileReference; lastKnownFileType = wrapper.framework; name = System.framework; path = /System/Library/Frameworks/System.framework; sourceTree = ""; }; 95 | 97CF60D005585DC900A48F3A /* libncurses.dylib */ = {isa = PBXFileReference; lastKnownFileType = "compiled.mach-o.dylib"; name = libncurses.dylib; path = /usr/lib/libncurses.dylib; sourceTree = ""; }; 96 | /* End PBXFileReference section */ 97 | 98 | /* Begin PBXFrameworksBuildPhase section */ 99 | 2D7D902B08F4AFC7003CF2E8 /* Frameworks */ = { 100 | isa = PBXFrameworksBuildPhase; 101 | buildActionMask = 2147483647; 102 | files = ( 103 | 2D7D903508F4B001003CF2E8 /* CoreFoundation.framework in Frameworks */, 104 | 2D7D903608F4B001003CF2E8 /* IOKit.framework in Frameworks */, 105 | 2D7D903708F4B001003CF2E8 /* libncurses.dylib in Frameworks */, 106 | ); 107 | runOnlyForDeploymentPostprocessing = 0; 108 | }; 109 | 2D7D914E08F4B017003CF2E8 /* Frameworks */ = { 110 | isa = PBXFrameworksBuildPhase; 111 | buildActionMask = 2147483647; 112 | files = ( 113 | 2D7D915608F4B076003CF2E8 /* CoreFoundation.framework in Frameworks */, 114 | 2D7D915708F4B076003CF2E8 /* IOKit.framework in Frameworks */, 115 | ); 116 | runOnlyForDeploymentPostprocessing = 0; 117 | }; 118 | 2D7D915B08F4B07A003CF2E8 /* Frameworks */ = { 119 | isa = PBXFrameworksBuildPhase; 120 | buildActionMask = 2147483647; 121 | files = ( 122 | 2D7D915C08F4B07A003CF2E8 /* CoreFoundation.framework in Frameworks */, 123 | 2D7D915D08F4B07A003CF2E8 /* IOKit.framework in Frameworks */, 124 | ); 125 | runOnlyForDeploymentPostprocessing = 0; 126 | }; 127 | /* End PBXFrameworksBuildPhase section */ 128 | 129 | /* Begin PBXGroup section */ 130 | 97CF601A05585D4100A48F3A /* IOKitTools */ = { 131 | isa = PBXGroup; 132 | children = ( 133 | 97CF602405585D4100A48F3A /* ioreg */, 134 | 97CF607305585D4100A48F3A /* ioclasscount */, 135 | 97CF608605585D4100A48F3A /* ioalloccount */, 136 | 97CF609905585D4100A48F3A /* External Frameworks and Libraries */, 137 | 97CF602B05585D4100A48F3A /* Products */, 138 | ); 139 | name = IOKitTools; 140 | sourceTree = ""; 141 | }; 142 | 97CF602405585D4100A48F3A /* ioreg */ = { 143 | isa = PBXGroup; 144 | children = ( 145 | 97CF603205585D4100A48F3A /* ioreg.c */, 146 | 97CF603805585D4100A48F3A /* ioreg.8 */, 147 | ); 148 | name = ioreg; 149 | path = ioreg.tproj; 150 | sourceTree = ""; 151 | }; 152 | 97CF602B05585D4100A48F3A /* Products */ = { 153 | isa = PBXGroup; 154 | children = ( 155 | 2D7D902D08F4AFC7003CF2E8 /* ioreg */, 156 | 2D7D915008F4B017003CF2E8 /* ioclasscount */, 157 | 2D7D916108F4B07A003CF2E8 /* ioalloccount */, 158 | ); 159 | name = Products; 160 | sourceTree = ""; 161 | }; 162 | 97CF607305585D4100A48F3A /* ioclasscount */ = { 163 | isa = PBXGroup; 164 | children = ( 165 | 97CF607F05585D4100A48F3A /* ioclasscount.c */, 166 | 97CF608505585D4100A48F3A /* ioclasscount.8 */, 167 | ); 168 | name = ioclasscount; 169 | path = ioclasscount.tproj; 170 | sourceTree = ""; 171 | }; 172 | 97CF608605585D4100A48F3A /* ioalloccount */ = { 173 | isa = PBXGroup; 174 | children = ( 175 | 97CF609205585D4100A48F3A /* ioalloccount.c */, 176 | 97CF609805585D4100A48F3A /* ioalloccount.8 */, 177 | ); 178 | name = ioalloccount; 179 | path = ioalloccount.tproj; 180 | sourceTree = ""; 181 | }; 182 | 97CF609905585D4100A48F3A /* External Frameworks and Libraries */ = { 183 | isa = PBXGroup; 184 | children = ( 185 | 056F26F20AFBD911006CB74E /* libMallocDebug.a */, 186 | 97CF60D005585DC900A48F3A /* libncurses.dylib */, 187 | 97CF609C05585D4100A48F3A /* IOKit.framework */, 188 | 97CF60A305585D4100A48F3A /* CoreFoundation.framework */, 189 | 97CF60A805585D4100A48F3A /* System.framework */, 190 | ); 191 | name = "External Frameworks and Libraries"; 192 | sourceTree = ""; 193 | }; 194 | /* End PBXGroup section */ 195 | 196 | /* Begin PBXNativeTarget section */ 197 | 2D7D902C08F4AFC7003CF2E8 /* ioreg */ = { 198 | isa = PBXNativeTarget; 199 | buildConfigurationList = 2D7D902F08F4AFE5003CF2E8 /* Build configuration list for PBXNativeTarget "ioreg" */; 200 | buildPhases = ( 201 | 2D7D902A08F4AFC7003CF2E8 /* Sources */, 202 | 2D7D902B08F4AFC7003CF2E8 /* Frameworks */, 203 | ); 204 | buildRules = ( 205 | ); 206 | dependencies = ( 207 | ); 208 | name = ioreg; 209 | productName = ioreg; 210 | productReference = 2D7D902D08F4AFC7003CF2E8 /* ioreg */; 211 | productType = "com.apple.product-type.tool"; 212 | }; 213 | 2D7D914F08F4B017003CF2E8 /* ioclasscount */ = { 214 | isa = PBXNativeTarget; 215 | buildConfigurationList = 2D7D915208F4B04A003CF2E8 /* Build configuration list for PBXNativeTarget "ioclasscount" */; 216 | buildPhases = ( 217 | 2D7D914D08F4B017003CF2E8 /* Sources */, 218 | 2D7D914E08F4B017003CF2E8 /* Frameworks */, 219 | ); 220 | buildRules = ( 221 | ); 222 | dependencies = ( 223 | ); 224 | name = ioclasscount; 225 | productName = ioclasscount; 226 | productReference = 2D7D915008F4B017003CF2E8 /* ioclasscount */; 227 | productType = "com.apple.product-type.tool"; 228 | }; 229 | 2D7D915808F4B07A003CF2E8 /* ioalloccount */ = { 230 | isa = PBXNativeTarget; 231 | buildConfigurationList = 2D7D915E08F4B07A003CF2E8 /* Build configuration list for PBXNativeTarget "ioalloccount" */; 232 | buildPhases = ( 233 | 2D7D915908F4B07A003CF2E8 /* Sources */, 234 | 2D7D915B08F4B07A003CF2E8 /* Frameworks */, 235 | ); 236 | buildRules = ( 237 | ); 238 | dependencies = ( 239 | ); 240 | name = ioalloccount; 241 | productName = ioclasscount; 242 | productReference = 2D7D916108F4B07A003CF2E8 /* ioalloccount */; 243 | productType = "com.apple.product-type.tool"; 244 | }; 245 | /* End PBXNativeTarget section */ 246 | 247 | /* Begin PBXProject section */ 248 | 97CF60AF05585D4200A48F3A /* Project object */ = { 249 | isa = PBXProject; 250 | buildConfigurationList = 2D7D900708F4AE49003CF2E8 /* Build configuration list for PBXProject "IOKitTools" */; 251 | compatibilityVersion = "Xcode 2.4"; 252 | hasScannedForEncodings = 1; 253 | mainGroup = 97CF601A05585D4100A48F3A /* IOKitTools */; 254 | productRefGroup = 97CF602B05585D4100A48F3A /* Products */; 255 | projectDirPath = ""; 256 | projectRoot = ""; 257 | targets = ( 258 | 2D7D901F08F4AEF7003CF2E8 /* IOKitTools */, 259 | 2D7D902C08F4AFC7003CF2E8 /* ioreg */, 260 | 2D7D914F08F4B017003CF2E8 /* ioclasscount */, 261 | 2D7D915808F4B07A003CF2E8 /* ioalloccount */, 262 | ); 263 | }; 264 | /* End PBXProject section */ 265 | 266 | /* Begin PBXSourcesBuildPhase section */ 267 | 2D7D902A08F4AFC7003CF2E8 /* Sources */ = { 268 | isa = PBXSourcesBuildPhase; 269 | buildActionMask = 2147483647; 270 | files = ( 271 | 2D7D903408F4AFF9003CF2E8 /* ioreg.c in Sources */, 272 | ); 273 | runOnlyForDeploymentPostprocessing = 0; 274 | }; 275 | 2D7D914D08F4B017003CF2E8 /* Sources */ = { 276 | isa = PBXSourcesBuildPhase; 277 | buildActionMask = 2147483647; 278 | files = ( 279 | 2D7D915508F4B063003CF2E8 /* ioclasscount.c in Sources */, 280 | ); 281 | runOnlyForDeploymentPostprocessing = 0; 282 | }; 283 | 2D7D915908F4B07A003CF2E8 /* Sources */ = { 284 | isa = PBXSourcesBuildPhase; 285 | buildActionMask = 2147483647; 286 | files = ( 287 | 2D7D916308F4B0C2003CF2E8 /* ioalloccount.c in Sources */, 288 | ); 289 | runOnlyForDeploymentPostprocessing = 0; 290 | }; 291 | /* End PBXSourcesBuildPhase section */ 292 | 293 | /* Begin PBXTargetDependency section */ 294 | 2D7D903308F4AFE9003CF2E8 /* PBXTargetDependency */ = { 295 | isa = PBXTargetDependency; 296 | target = 2D7D902C08F4AFC7003CF2E8 /* ioreg */; 297 | targetProxy = 2D7D903208F4AFE9003CF2E8 /* PBXContainerItemProxy */; 298 | }; 299 | 2D7D916508F4B0CB003CF2E8 /* PBXTargetDependency */ = { 300 | isa = PBXTargetDependency; 301 | target = 2D7D914F08F4B017003CF2E8 /* ioclasscount */; 302 | targetProxy = 2D7D916408F4B0CB003CF2E8 /* PBXContainerItemProxy */; 303 | }; 304 | 2D7D916708F4B0CD003CF2E8 /* PBXTargetDependency */ = { 305 | isa = PBXTargetDependency; 306 | target = 2D7D915808F4B07A003CF2E8 /* ioalloccount */; 307 | targetProxy = 2D7D916608F4B0CD003CF2E8 /* PBXContainerItemProxy */; 308 | }; 309 | /* End PBXTargetDependency section */ 310 | 311 | /* Begin XCBuildConfiguration section */ 312 | 2D7D900808F4AE49003CF2E8 /* Development */ = { 313 | isa = XCBuildConfiguration; 314 | buildSettings = { 315 | GCC_OPTIMIZATION_LEVEL = 0; 316 | GCC_TREAT_WARNINGS_AS_ERRORS = YES; 317 | INSTALL_GROUP = wheel; 318 | INSTALL_OWNER = root; 319 | INSTALL_PATH = /usr/sbin; 320 | WARNING_CFLAGS = ( 321 | "-Wshorten-64-to-32", 322 | "-Wall", 323 | ); 324 | }; 325 | name = Development; 326 | }; 327 | 2D7D900908F4AE49003CF2E8 /* Deployment */ = { 328 | isa = XCBuildConfiguration; 329 | buildSettings = { 330 | GCC_TREAT_WARNINGS_AS_ERRORS = YES; 331 | INSTALL_GROUP = wheel; 332 | INSTALL_OWNER = root; 333 | INSTALL_PATH = /usr/sbin; 334 | WARNING_CFLAGS = ( 335 | "-Wshorten-64-to-32", 336 | "-Wall", 337 | ); 338 | }; 339 | name = Deployment; 340 | }; 341 | 2D7D902808F4AF47003CF2E8 /* Development */ = { 342 | isa = XCBuildConfiguration; 343 | buildSettings = { 344 | PRODUCT_NAME = IOKitTools; 345 | }; 346 | name = Development; 347 | }; 348 | 2D7D902908F4AF47003CF2E8 /* Deployment */ = { 349 | isa = XCBuildConfiguration; 350 | buildSettings = { 351 | PRODUCT_NAME = IOKitTools; 352 | }; 353 | name = Deployment; 354 | }; 355 | 2D7D903008F4AFE5003CF2E8 /* Development */ = { 356 | isa = XCBuildConfiguration; 357 | buildSettings = { 358 | COPY_PHASE_STRIP = NO; 359 | PRODUCT_NAME = ioreg; 360 | SKIP_INSTALL = NO; 361 | }; 362 | name = Development; 363 | }; 364 | 2D7D903108F4AFE5003CF2E8 /* Deployment */ = { 365 | isa = XCBuildConfiguration; 366 | buildSettings = { 367 | PRODUCT_NAME = ioreg; 368 | SKIP_INSTALL = NO; 369 | }; 370 | name = Deployment; 371 | }; 372 | 2D7D915308F4B04A003CF2E8 /* Development */ = { 373 | isa = XCBuildConfiguration; 374 | buildSettings = { 375 | COPY_PHASE_STRIP = NO; 376 | PRODUCT_NAME = ioclasscount; 377 | SKIP_INSTALL = NO; 378 | }; 379 | name = Development; 380 | }; 381 | 2D7D915408F4B04A003CF2E8 /* Deployment */ = { 382 | isa = XCBuildConfiguration; 383 | buildSettings = { 384 | PRODUCT_NAME = ioclasscount; 385 | SKIP_INSTALL = NO; 386 | }; 387 | name = Deployment; 388 | }; 389 | 2D7D915F08F4B07A003CF2E8 /* Development */ = { 390 | isa = XCBuildConfiguration; 391 | buildSettings = { 392 | COPY_PHASE_STRIP = NO; 393 | PRODUCT_NAME = ioalloccount; 394 | SKIP_INSTALL = NO; 395 | }; 396 | name = Development; 397 | }; 398 | 2D7D916008F4B07A003CF2E8 /* Deployment */ = { 399 | isa = XCBuildConfiguration; 400 | buildSettings = { 401 | PRODUCT_NAME = ioalloccount; 402 | SKIP_INSTALL = NO; 403 | }; 404 | name = Deployment; 405 | }; 406 | /* End XCBuildConfiguration section */ 407 | 408 | /* Begin XCConfigurationList section */ 409 | 2D7D900708F4AE49003CF2E8 /* Build configuration list for PBXProject "IOKitTools" */ = { 410 | isa = XCConfigurationList; 411 | buildConfigurations = ( 412 | 2D7D900808F4AE49003CF2E8 /* Development */, 413 | 2D7D900908F4AE49003CF2E8 /* Deployment */, 414 | ); 415 | defaultConfigurationIsVisible = 0; 416 | defaultConfigurationName = Deployment; 417 | }; 418 | 2D7D902708F4AF47003CF2E8 /* Build configuration list for PBXAggregateTarget "IOKitTools" */ = { 419 | isa = XCConfigurationList; 420 | buildConfigurations = ( 421 | 2D7D902808F4AF47003CF2E8 /* Development */, 422 | 2D7D902908F4AF47003CF2E8 /* Deployment */, 423 | ); 424 | defaultConfigurationIsVisible = 0; 425 | defaultConfigurationName = Deployment; 426 | }; 427 | 2D7D902F08F4AFE5003CF2E8 /* Build configuration list for PBXNativeTarget "ioreg" */ = { 428 | isa = XCConfigurationList; 429 | buildConfigurations = ( 430 | 2D7D903008F4AFE5003CF2E8 /* Development */, 431 | 2D7D903108F4AFE5003CF2E8 /* Deployment */, 432 | ); 433 | defaultConfigurationIsVisible = 0; 434 | defaultConfigurationName = Deployment; 435 | }; 436 | 2D7D915208F4B04A003CF2E8 /* Build configuration list for PBXNativeTarget "ioclasscount" */ = { 437 | isa = XCConfigurationList; 438 | buildConfigurations = ( 439 | 2D7D915308F4B04A003CF2E8 /* Development */, 440 | 2D7D915408F4B04A003CF2E8 /* Deployment */, 441 | ); 442 | defaultConfigurationIsVisible = 0; 443 | defaultConfigurationName = Deployment; 444 | }; 445 | 2D7D915E08F4B07A003CF2E8 /* Build configuration list for PBXNativeTarget "ioalloccount" */ = { 446 | isa = XCConfigurationList; 447 | buildConfigurations = ( 448 | 2D7D915F08F4B07A003CF2E8 /* Development */, 449 | 2D7D916008F4B07A003CF2E8 /* Deployment */, 450 | ); 451 | defaultConfigurationIsVisible = 0; 452 | defaultConfigurationName = Deployment; 453 | }; 454 | /* End XCConfigurationList section */ 455 | }; 456 | rootObject = 97CF60AF05585D4200A48F3A /* Project object */; 457 | } 458 | -------------------------------------------------------------------------------- /APPLE_LICENSE: -------------------------------------------------------------------------------- 1 | APPLE PUBLIC SOURCE LICENSE 2 | Version 2.0 - August 6, 2003 3 | 4 | Please read this License carefully before downloading this software. By 5 | downloading or using this software, you are agreeing to be bound by the terms 6 | of this License. If you do not or cannot agree to the terms of this License, 7 | please do not download or use the software. 8 | 9 | Apple Note: In January 2007, Apple changed its corporate name from "Apple 10 | Computer, Inc." to "Apple Inc." This change has been reflected below and 11 | copyright years updated, but no other changes have been made to the APSL 2.0. 12 | 13 | 1. General; Definitions. This License applies to any program or other 14 | work which Apple Inc. ("Apple") makes publicly available and which contains a 15 | notice placed by Apple identifying such program or work as "Original Code" and 16 | stating that it is subject to the terms of this Apple Public Source License 17 | version 2.0 ("License"). As used in this License: 18 | 19 | 1.1 "Applicable Patent Rights" mean: (a) in the case where Apple is the 20 | grantor of rights, (i) claims of patents that are now or hereafter acquired, 21 | owned by or assigned to Apple and (ii) that cover subject matter contained in 22 | the Original Code, but only to the extent necessary to use, reproduce and/or 23 | distribute the Original Code without infringement; and (b) in the case where 24 | You are the grantor of rights, (i) claims of patents that are now or hereafter 25 | acquired, owned by or assigned to You and (ii) that cover subject matter in 26 | Your Modifications, taken alone or in combination with Original Code. 27 | 28 | 1.2 "Contributor" means any person or entity that creates or contributes to 29 | the creation of Modifications. 30 | 31 | 1.3 "Covered Code" means the Original Code, Modifications, the combination 32 | of Original Code and any Modifications, and/or any respective portions thereof. 33 | 34 | 1.4 "Externally Deploy" means: (a) to sublicense, distribute or otherwise 35 | make Covered Code available, directly or indirectly, to anyone other than You; 36 | and/or (b) to use Covered Code, alone or as part of a Larger Work, in any way 37 | to provide a service, including but not limited to delivery of content, through 38 | electronic communication with a client other than You. 39 | 40 | 1.5 "Larger Work" means a work which combines Covered Code or portions 41 | thereof with code not governed by the terms of this License. 42 | 43 | 1.6 "Modifications" mean any addition to, deletion from, and/or change to, 44 | the substance and/or structure of the Original Code, any previous 45 | Modifications, the combination of Original Code and any previous Modifications, 46 | and/or any respective portions thereof. When code is released as a series of 47 | files, a Modification is: (a) any addition to or deletion from the contents of 48 | a file containing Covered Code; and/or (b) any new file or other representation 49 | of computer program statements that contains any part of Covered Code. 50 | 51 | 1.7 "Original Code" means (a) the Source Code of a program or other work as 52 | originally made available by Apple under this License, including the Source 53 | Code of any updates or upgrades to such programs or works made available by 54 | Apple under this License, and that has been expressly identified by Apple as 55 | such in the header file(s) of such work; and (b) the object code compiled from 56 | such Source Code and originally made available by Apple under this License 57 | 58 | 1.8 "Source Code" means the human readable form of a program or other work 59 | that is suitable for making modifications to it, including all modules it 60 | contains, plus any associated interface definition files, scripts used to 61 | control compilation and installation of an executable (object code). 62 | 63 | 1.9 "You" or "Your" means an individual or a legal entity exercising rights 64 | under this License. For legal entities, "You" or "Your" includes any entity 65 | which controls, is controlled by, or is under common control with, You, where 66 | "control" means (a) the power, direct or indirect, to cause the direction or 67 | management of such entity, whether by contract or otherwise, or (b) ownership 68 | of fifty percent (50%) or more of the outstanding shares or beneficial 69 | ownership of such entity. 70 | 71 | 2. Permitted Uses; Conditions & Restrictions. Subject to the terms and 72 | conditions of this License, Apple hereby grants You, effective on the date You 73 | accept this License and download the Original Code, a world-wide, royalty-free, 74 | non-exclusive license, to the extent of Apple's Applicable Patent Rights and 75 | copyrights covering the Original Code, to do the following: 76 | 77 | 2.1 Unmodified Code. You may use, reproduce, display, perform, internally 78 | distribute within Your organization, and Externally Deploy verbatim, unmodified 79 | copies of the Original Code, for commercial or non-commercial purposes, 80 | provided that in each instance: 81 | 82 | (a) You must retain and reproduce in all copies of Original Code the 83 | copyright and other proprietary notices and disclaimers of Apple as they appear 84 | in the Original Code, and keep intact all notices in the Original Code that 85 | refer to this License; and 86 | 87 | (b) You must include a copy of this License with every copy of Source Code 88 | of Covered Code and documentation You distribute or Externally Deploy, and You 89 | may not offer or impose any terms on such Source Code that alter or restrict 90 | this License or the recipients' rights hereunder, except as permitted under 91 | Section 6. 92 | 93 | 2.2 Modified Code. You may modify Covered Code and use, reproduce, 94 | display, perform, internally distribute within Your organization, and 95 | Externally Deploy Your Modifications and Covered Code, for commercial or 96 | non-commercial purposes, provided that in each instance You also meet all of 97 | these conditions: 98 | 99 | (a) You must satisfy all the conditions of Section 2.1 with respect to the 100 | Source Code of the Covered Code; 101 | 102 | (b) You must duplicate, to the extent it does not already exist, the notice 103 | in Exhibit A in each file of the Source Code of all Your Modifications, and 104 | cause the modified files to carry prominent notices stating that You changed 105 | the files and the date of any change; and 106 | 107 | (c) If You Externally Deploy Your Modifications, You must make Source Code 108 | of all Your Externally Deployed Modifications either available to those to whom 109 | You have Externally Deployed Your Modifications, or publicly available. Source 110 | Code of Your Externally Deployed Modifications must be released under the terms 111 | set forth in this License, including the license grants set forth in Section 3 112 | below, for as long as you Externally Deploy the Covered Code or twelve (12) 113 | months from the date of initial External Deployment, whichever is longer. You 114 | should preferably distribute the Source Code of Your Externally Deployed 115 | Modifications electronically (e.g. download from a web site). 116 | 117 | 2.3 Distribution of Executable Versions. In addition, if You Externally 118 | Deploy Covered Code (Original Code and/or Modifications) in object code, 119 | executable form only, You must include a prominent notice, in the code itself 120 | as well as in related documentation, stating that Source Code of the Covered 121 | Code is available under the terms of this License with information on how and 122 | where to obtain such Source Code. 123 | 124 | 2.4 Third Party Rights. You expressly acknowledge and agree that although 125 | Apple and each Contributor grants the licenses to their respective portions of 126 | the Covered Code set forth herein, no assurances are provided by Apple or any 127 | Contributor that the Covered Code does not infringe the patent or other 128 | intellectual property rights of any other entity. Apple and each Contributor 129 | disclaim any liability to You for claims brought by any other entity based on 130 | infringement of intellectual property rights or otherwise. As a condition to 131 | exercising the rights and licenses granted hereunder, You hereby assume sole 132 | responsibility to secure any other intellectual property rights needed, if any. 133 | For example, if a third party patent license is required to allow You to 134 | distribute the Covered Code, it is Your responsibility to acquire that license 135 | before distributing the Covered Code. 136 | 137 | 3. Your Grants. In consideration of, and as a condition to, the licenses 138 | granted to You under this License, You hereby grant to any person or entity 139 | receiving or distributing Covered Code under this License a non-exclusive, 140 | royalty-free, perpetual, irrevocable license, under Your Applicable Patent 141 | Rights and other intellectual property rights (other than patent) owned or 142 | controlled by You, to use, reproduce, display, perform, modify, sublicense, 143 | distribute and Externally Deploy Your Modifications of the same scope and 144 | extent as Apple's licenses under Sections 2.1 and 2.2 above. 145 | 146 | 4. Larger Works. You may create a Larger Work by combining Covered Code 147 | with other code not governed by the terms of this License and distribute the 148 | Larger Work as a single product. In each such instance, You must make sure the 149 | requirements of this License are fulfilled for the Covered Code or any portion 150 | thereof. 151 | 152 | 5. Limitations on Patent License. Except as expressly stated in Section 153 | 2, no other patent rights, express or implied, are granted by Apple herein. 154 | Modifications and/or Larger Works may require additional patent licenses from 155 | Apple which Apple may grant in its sole discretion. 156 | 157 | 6. Additional Terms. You may choose to offer, and to charge a fee for, 158 | warranty, support, indemnity or liability obligations and/or other rights 159 | consistent with the scope of the license granted herein ("Additional Terms") to 160 | one or more recipients of Covered Code. However, You may do so only on Your own 161 | behalf and as Your sole responsibility, and not on behalf of Apple or any 162 | Contributor. You must obtain the recipient's agreement that any such Additional 163 | Terms are offered by You alone, and You hereby agree to indemnify, defend and 164 | hold Apple and every Contributor harmless for any liability incurred by or 165 | claims asserted against Apple or such Contributor by reason of any such 166 | Additional Terms. 167 | 168 | 7. Versions of the License. Apple may publish revised and/or new versions 169 | of this License from time to time. Each version will be given a distinguishing 170 | version number. Once Original Code has been published under a particular 171 | version of this License, You may continue to use it under the terms of that 172 | version. You may also choose to use such Original Code under the terms of any 173 | subsequent version of this License published by Apple. No one other than Apple 174 | has the right to modify the terms applicable to Covered Code created under this 175 | License. 176 | 177 | 8. NO WARRANTY OR SUPPORT. The Covered Code may contain in whole or in 178 | part pre-release, untested, or not fully tested works. The Covered Code may 179 | contain errors that could cause failures or loss of data, and may be incomplete 180 | or contain inaccuracies. You expressly acknowledge and agree that use of the 181 | Covered Code, or any portion thereof, is at Your sole and entire risk. THE 182 | COVERED CODE IS PROVIDED "AS IS" AND WITHOUT WARRANTY, UPGRADES OR SUPPORT OF 183 | ANY KIND AND APPLE AND APPLE'S LICENSOR(S) (COLLECTIVELY REFERRED TO AS "APPLE" 184 | FOR THE PURPOSES OF SECTIONS 8 AND 9) AND ALL CONTRIBUTORS EXPRESSLY DISCLAIM 185 | ALL WARRANTIES AND/OR CONDITIONS, EXPRESS OR IMPLIED, INCLUDING, BUT NOT 186 | LIMITED TO, THE IMPLIED WARRANTIES AND/OR CONDITIONS OF MERCHANTABILITY, OF 187 | SATISFACTORY QUALITY, OF FITNESS FOR A PARTICULAR PURPOSE, OF ACCURACY, OF 188 | QUIET ENJOYMENT, AND NONINFRINGEMENT OF THIRD PARTY RIGHTS. APPLE AND EACH 189 | CONTRIBUTOR DOES NOT WARRANT AGAINST INTERFERENCE WITH YOUR ENJOYMENT OF THE 190 | COVERED CODE, THAT THE FUNCTIONS CONTAINED IN THE COVERED CODE WILL MEET YOUR 191 | REQUIREMENTS, THAT THE OPERATION OF THE COVERED CODE WILL BE UNINTERRUPTED OR 192 | ERROR-FREE, OR THAT DEFECTS IN THE COVERED CODE WILL BE CORRECTED. NO ORAL OR 193 | WRITTEN INFORMATION OR ADVICE GIVEN BY APPLE, AN APPLE AUTHORIZED 194 | REPRESENTATIVE OR ANY CONTRIBUTOR SHALL CREATE A WARRANTY. You acknowledge 195 | that the Covered Code is not intended for use in the operation of nuclear 196 | facilities, aircraft navigation, communication systems, or air traffic control 197 | machines in which case the failure of the Covered Code could lead to death, 198 | personal injury, or severe physical or environmental damage. 199 | 200 | 9. LIMITATION OF LIABILITY. TO THE EXTENT NOT PROHIBITED BY LAW, IN NO 201 | EVENT SHALL APPLE OR ANY CONTRIBUTOR BE LIABLE FOR ANY INCIDENTAL, SPECIAL, 202 | INDIRECT OR CONSEQUENTIAL DAMAGES ARISING OUT OF OR RELATING TO THIS LICENSE OR 203 | YOUR USE OR INABILITY TO USE THE COVERED CODE, OR ANY PORTION THEREOF, WHETHER 204 | UNDER A THEORY OF CONTRACT, WARRANTY, TORT (INCLUDING NEGLIGENCE), PRODUCTS 205 | LIABILITY OR OTHERWISE, EVEN IF APPLE OR SUCH CONTRIBUTOR HAS BEEN ADVISED OF 206 | THE POSSIBILITY OF SUCH DAMAGES AND NOTWITHSTANDING THE FAILURE OF ESSENTIAL 207 | PURPOSE OF ANY REMEDY. SOME JURISDICTIONS DO NOT ALLOW THE LIMITATION OF 208 | LIABILITY OF INCIDENTAL OR CONSEQUENTIAL DAMAGES, SO THIS LIMITATION MAY NOT 209 | APPLY TO YOU. In no event shall Apple's total liability to You for all damages 210 | (other than as may be required by applicable law) under this License exceed the 211 | amount of fifty dollars ($50.00). 212 | 213 | 10. Trademarks. This License does not grant any rights to use the 214 | trademarks or trade names "Apple", "Mac", "Mac OS", "QuickTime", "QuickTime 215 | Streaming Server" or any other trademarks, service marks, logos or trade names 216 | belonging to Apple (collectively "Apple Marks") or to any trademark, service 217 | mark, logo or trade name belonging to any Contributor. You agree not to use 218 | any Apple Marks in or as part of the name of products derived from the Original 219 | Code or to endorse or promote products derived from the Original Code other 220 | than as expressly permitted by and in strict compliance at all times with 221 | Apple's third party trademark usage guidelines which are posted at 222 | http://www.apple.com/legal/guidelinesfor3rdparties.html. 223 | 224 | 11. Ownership. Subject to the licenses granted under this License, each 225 | Contributor retains all rights, title and interest in and to any Modifications 226 | made by such Contributor. Apple retains all rights, title and interest in and 227 | to the Original Code and any Modifications made by or on behalf of Apple 228 | ("Apple Modifications"), and such Apple Modifications will not be automatically 229 | subject to this License. Apple may, at its sole discretion, choose to license 230 | such Apple Modifications under this License, or on different terms from those 231 | contained in this License or may choose not to license them at all. 232 | 233 | 12. Termination. 234 | 235 | 12.1 Termination. This License and the rights granted hereunder will 236 | terminate: 237 | 238 | (a) automatically without notice from Apple if You fail to comply with any 239 | term(s) of this License and fail to cure such breach within 30 days of becoming 240 | aware of such breach; 241 | (b) immediately in the event of the circumstances described in Section 242 | 13.5(b); or 243 | (c) automatically without notice from Apple if You, at any time during the 244 | term of this License, commence an action for patent infringement against Apple; 245 | provided that Apple did not first commence an action for patent infringement 246 | against You in that instance. 247 | 248 | 12.2 Effect of Termination. Upon termination, You agree to immediately stop 249 | any further use, reproduction, modification, sublicensing and distribution of 250 | the Covered Code. All sublicenses to the Covered Code which have been properly 251 | granted prior to termination shall survive any termination of this License. 252 | Provisions which, by their nature, should remain in effect beyond the 253 | termination of this License shall survive, including but not limited to 254 | Sections 3, 5, 8, 9, 10, 11, 12.2 and 13. No party will be liable to any other 255 | for compensation, indemnity or damages of any sort solely as a result of 256 | terminating this License in accordance with its terms, and termination of this 257 | License will be without prejudice to any other right or remedy of any party. 258 | 259 | 13. Miscellaneous. 260 | 261 | 13.1 Government End Users. The Covered Code is a "commercial item" as 262 | defined in FAR 2.101. Government software and technical data rights in the 263 | Covered Code include only those rights customarily provided to the public as 264 | defined in this License. This customary commercial license in technical data 265 | and software is provided in accordance with FAR 12.211 (Technical Data) and 266 | 12.212 (Computer Software) and, for Department of Defense purchases, DFAR 267 | 252.227-7015 (Technical Data -- Commercial Items) and 227.7202-3 (Rights in 268 | Commercial Computer Software or Computer Software Documentation). Accordingly, 269 | all U.S. Government End Users acquire Covered Code with only those rights set 270 | forth herein. 271 | 272 | 13.2 Relationship of Parties. This License will not be construed as 273 | creating an agency, partnership, joint venture or any other form of legal 274 | association between or among You, Apple or any Contributor, and You will not 275 | represent to the contrary, whether expressly, by implication, appearance or 276 | otherwise. 277 | 278 | 13.3 Independent Development. Nothing in this License will impair Apple's 279 | right to acquire, license, develop, have others develop for it, market and/or 280 | distribute technology or products that perform the same or similar functions 281 | as, or otherwise compete with, Modifications, Larger Works, technology or 282 | products that You may develop, produce, market or distribute. 283 | 284 | 13.4 Waiver; Construction. Failure by Apple or any Contributor to enforce 285 | any provision of this License will not be deemed a waiver of future enforcement 286 | of that or any other provision. Any law or regulation which provides that the 287 | language of a contract shall be construed against the drafter will not apply to 288 | this License. 289 | 290 | 13.5 Severability. (a) If for any reason a court of competent jurisdiction 291 | finds any provision of this License, or portion thereof, to be unenforceable, 292 | that provision of the License will be enforced to the maximum extent 293 | permissible so as to effect the economic benefits and intent of the parties, 294 | and the remainder of this License will continue in full force and effect. (b) 295 | Notwithstanding the foregoing, if applicable law prohibits or restricts You 296 | from fully and/or specifically complying with Sections 2 and/or 3 or prevents 297 | the enforceability of either of those Sections, this License will immediately 298 | terminate and You must immediately discontinue any use of the Covered Code and 299 | destroy all copies of it that are in your possession or control. 300 | 301 | 13.6 Dispute Resolution. Any litigation or other dispute resolution between 302 | You and Apple relating to this License shall take place in the Northern 303 | District of California, and You and Apple hereby consent to the personal 304 | jurisdiction of, and venue in, the state and federal courts within that 305 | District with respect to this License. The application of the United Nations 306 | Convention on Contracts for the International Sale of Goods is expressly 307 | excluded. 308 | 309 | 13.7 Entire Agreement; Governing Law. This License constitutes the entire 310 | agreement between the parties with respect to the subject matter hereof. This 311 | License shall be governed by the laws of the United States and the State of 312 | California, except that body of California law concerning conflicts of law. 313 | 314 | Where You are located in the province of Quebec, Canada, the following clause 315 | applies: The parties hereby confirm that they have requested that this License 316 | and all related documents be drafted in English. Les parties ont exigé que le 317 | présent contrat et tous les documents connexes soient rédigés en anglais. 318 | 319 | EXHIBIT A. 320 | 321 | "Portions Copyright (c) 1999-2007 Apple Inc. All Rights Reserved. 322 | 323 | This file contains Original Code and/or Modifications of Original Code as 324 | defined in and that are subject to the Apple Public Source License Version 2.0 325 | (the 'License'). You may not use this file except in compliance with the 326 | License. Please obtain a copy of the License at 327 | http://www.opensource.apple.com/apsl/ and read it before using this file. 328 | 329 | The Original Code and all software distributed under the License are 330 | distributed on an 'AS IS' basis, WITHOUT WARRANTY OF ANY KIND, EITHER EXPRESS 331 | OR IMPLIED, AND APPLE HEREBY DISCLAIMS ALL SUCH WARRANTIES, INCLUDING WITHOUT 332 | LIMITATION, ANY WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR 333 | PURPOSE, QUIET ENJOYMENT OR NON-INFRINGEMENT. Please see the License for the 334 | specific language governing rights and limitations under the License." 335 | 336 | -------------------------------------------------------------------------------- /ioreg.tproj/ioreg.c: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright (c) 2000-2011 Apple Computer, Inc. All rights reserved. 3 | * 4 | * @APPLE_LICENSE_HEADER_START@ 5 | * 6 | * This file contains Original Code and/or Modifications of Original Code 7 | * as defined in and that are subject to the Apple Public Source License 8 | * Version 2.0 (the 'License'). You may not use this file except in 9 | * compliance with the License. Please obtain a copy of the License at 10 | * http://www.opensource.apple.com/apsl/ and read it before using this 11 | * file. 12 | * 13 | * The Original Code and all software distributed under the License are 14 | * distributed on an 'AS IS' basis, WITHOUT WARRANTY OF ANY KIND, EITHER 15 | * EXPRESS OR IMPLIED, AND APPLE HEREBY DISCLAIMS ALL SUCH WARRANTIES, 16 | * INCLUDING WITHOUT LIMITATION, ANY WARRANTIES OF MERCHANTABILITY, 17 | * FITNESS FOR A PARTICULAR PURPOSE, QUIET ENJOYMENT OR NON-INFRINGEMENT. 18 | * Please see the License for the specific language governing rights and 19 | * limitations under the License. 20 | * 21 | * @APPLE_LICENSE_HEADER_END@ 22 | */ 23 | 24 | #include // (CFDictionary, ...) 25 | #include // (IOCFSerialize, ...) 26 | #include // (IOMasterPort, ...) 27 | #include // (IOServiceGetState, ...) 28 | #include // (TIOCGWINSZ, ...) 29 | #include // (tputs, ...) 30 | #include // (getopt, ...) 31 | 32 | // - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - 33 | 34 | #define assertion(e, message) ((void) (__builtin_expect(!(e), 0) ? fprintf(stderr, "ioreg: error: %s.\n", message), exit(1) : 0)) 35 | 36 | // - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - 37 | 38 | struct options 39 | { 40 | UInt32 archive:1; // (-a option) 41 | UInt32 bold:1; // (-b option) 42 | UInt32 format:1; // (-f option) 43 | UInt32 hex:1; // (-x option) 44 | UInt32 inheritance:1; // (-i option) 45 | UInt32 list:1; // (-l option) 46 | UInt32 root:1; // (-r option) 47 | UInt32 tree:1; // (-t option) 48 | 49 | char * class; // (-c option) 50 | UInt32 depth; // (-d option) 51 | char * key; // (-k option) 52 | char * name; // (-n option) 53 | char * plane; // (-p option) 54 | UInt32 width; // (-w option) 55 | }; 56 | 57 | struct context 58 | { 59 | io_registry_entry_t service; 60 | UInt32 serviceDepth; 61 | UInt64 stackOfBits; 62 | struct options options; 63 | }; 64 | 65 | // - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - 66 | 67 | static void boldinit(); 68 | static void boldon(); 69 | static void boldoff(); 70 | static void printinit(int width); 71 | static void print(const char * format, ...); 72 | static void println(const char * format, ...); 73 | 74 | static void cfshowinit(Boolean hex); 75 | static void cfshow(CFTypeRef object); 76 | static void cfarrayshow(CFArrayRef object); 77 | static void cfbooleanshow(CFBooleanRef object); 78 | static void cfdatashow(CFDataRef object); 79 | static void cfdictionaryshow(CFDictionaryRef object); 80 | static void cfnumbershow(CFNumberRef object); 81 | static void cfsetshow(CFSetRef object); 82 | static void cfstringshow(CFStringRef object); 83 | 84 | static CFStringRef createInheritanceStringForIORegistryClassName(CFStringRef name); 85 | 86 | static void printProp(CFStringRef key, CFTypeRef value, struct context * context); 87 | static void printPhysAddr(CFTypeRef value, struct context * context); 88 | static void printSlotNames(CFTypeRef value, struct context * context); 89 | static void printPCIRanges(CFTypeRef value, struct context * context); 90 | static void printInterruptMap(CFTypeRef value, struct context * context); 91 | static void printInterrupts(CFTypeRef value, struct context * context); 92 | static void printInterruptParent( CFTypeRef value, struct context * context ); 93 | static void printData(CFTypeRef value, struct context * context); 94 | 95 | // - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - 96 | 97 | static CFMutableDictionaryRef archive( io_registry_entry_t service, 98 | struct options options ) CF_RETURNS_RETAINED; 99 | 100 | static CFMutableDictionaryRef archive_scan( io_registry_entry_t service, 101 | UInt32 serviceDepth, 102 | struct options options ) CF_RETURNS_RETAINED; 103 | 104 | static CFMutableArrayRef archive_search( io_registry_entry_t service, 105 | UInt32 serviceHasMatchedDepth, 106 | UInt32 serviceDepth, 107 | io_registry_entry_t stackOfObjects[], 108 | struct options options ) CF_RETURNS_RETAINED; 109 | 110 | static Boolean compare( io_registry_entry_t service, 111 | struct options options ); 112 | 113 | static void indent( Boolean isNode, 114 | UInt32 serviceDepth, 115 | UInt64 stackOfBits ); 116 | 117 | static void scan( io_registry_entry_t service, 118 | Boolean serviceHasMoreSiblings, 119 | UInt32 serviceDepth, 120 | UInt64 stackOfBits, 121 | struct options options ); 122 | 123 | static void search( io_registry_entry_t service, 124 | UInt32 serviceHasMatchedDepth, 125 | UInt32 serviceDepth, 126 | io_registry_entry_t stackOfObjects[], 127 | struct options options ); 128 | 129 | static void show( io_registry_entry_t service, 130 | UInt32 serviceDepth, 131 | UInt64 stackOfBits, 132 | struct options options ); 133 | 134 | static void showitem( const void * key, 135 | const void * value, 136 | void * parameter ); 137 | 138 | static void usage(); 139 | 140 | // - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - 141 | 142 | int main(int argc, char ** argv) 143 | { 144 | int argument = 0; 145 | CFWriteStreamRef file = 0; // (needs release) 146 | CFTypeRef object = 0; // (needs release) 147 | struct options options; 148 | CFURLRef path = 0; // (needs release) 149 | io_registry_entry_t service = 0; // (needs release) 150 | io_registry_entry_t stackOfObjects[64]; 151 | Boolean success = FALSE; 152 | struct winsize winsize; 153 | 154 | // Initialize our minimal state. 155 | 156 | options.archive = FALSE; 157 | options.bold = FALSE; 158 | options.format = FALSE; 159 | options.hex = FALSE; 160 | options.inheritance = FALSE; 161 | options.list = FALSE; 162 | options.root = FALSE; 163 | options.tree = FALSE; 164 | 165 | options.class = 0; 166 | options.depth = 0; 167 | options.key = 0; 168 | options.name = 0; 169 | options.plane = kIOServicePlane; 170 | options.root = 0; 171 | options.width = 0; 172 | 173 | // Obtain the screen width. 174 | 175 | if (isatty(fileno(stdout))) 176 | { 177 | if (ioctl(fileno(stdout), TIOCGWINSZ, &winsize) == 0) 178 | { 179 | options.width = winsize.ws_col; 180 | } 181 | } 182 | 183 | // Obtain the command-line arguments. 184 | 185 | while ( (argument = getopt(argc, argv, ":abc:d:fik:ln:p:rsStw:x")) != -1 ) 186 | { 187 | switch (argument) 188 | { 189 | case 'a': 190 | options.archive = TRUE; 191 | break; 192 | case 'b': 193 | options.bold = TRUE; 194 | break; 195 | case 'c': 196 | options.class = optarg; 197 | break; 198 | case 'd': 199 | options.depth = atoi(optarg); 200 | break; 201 | case 'f': 202 | options.format = TRUE; 203 | break; 204 | case 'i': 205 | options.inheritance = TRUE; 206 | break; 207 | case 'k': 208 | options.key = optarg; 209 | break; 210 | case 'l': 211 | options.list = TRUE; 212 | break; 213 | case 'n': 214 | options.name = optarg; 215 | break; 216 | case 'p': 217 | options.plane = optarg; 218 | break; 219 | case 'r': 220 | options.root = TRUE; 221 | break; 222 | case 's': 223 | break; 224 | case 'S': 225 | break; 226 | case 't': 227 | options.tree = TRUE; 228 | break; 229 | case 'w': 230 | options.width = atoi(optarg); 231 | break; 232 | case 'x': 233 | options.hex = TRUE; 234 | break; 235 | default: 236 | usage(); 237 | break; 238 | } 239 | } 240 | 241 | // Initialize text output functions. 242 | 243 | cfshowinit(options.hex); 244 | 245 | printinit(options.width); 246 | 247 | if (options.bold) boldinit(); 248 | 249 | // Obtain the I/O Kit root service. 250 | 251 | service = IORegistryGetRootEntry(kIOMasterPortDefault); 252 | assertion(service, "can't obtain I/O Kit's root service"); 253 | 254 | // Traverse over all the I/O Kit services. 255 | 256 | if (options.archive) 257 | { 258 | if (options.root) 259 | { 260 | object = archive_search( /* service */ service, 261 | /* serviceHasMatchedDepth */ 0, 262 | /* serviceDepth */ 0, 263 | /* stackOfObjects */ stackOfObjects, 264 | /* options */ options ); 265 | } 266 | else 267 | { 268 | object = archive_scan( /* service */ service, 269 | /* serviceDepth */ 0, 270 | /* options */ options ); 271 | } 272 | 273 | if (object) 274 | { 275 | path = CFURLCreateWithFileSystemPath( /* allocator */ kCFAllocatorDefault, 276 | /* filePath */ CFSTR("/dev/stdout"), 277 | /* pathStyle */ kCFURLPOSIXPathStyle, 278 | /* isDirectory */ FALSE ); 279 | assertion(path != NULL, "can't create path"); 280 | 281 | file = CFWriteStreamCreateWithFile(kCFAllocatorDefault, path); 282 | assertion(file != NULL, "can't create file"); 283 | 284 | success = CFWriteStreamOpen(file); 285 | assertion(success, "can't open file"); 286 | 287 | CFPropertyListWrite( /* propertyList */ object, 288 | /* stream */ file, 289 | /* format */ kCFPropertyListXMLFormat_v1_0, 290 | /* options */ 0, 291 | /* error */ NULL ); 292 | 293 | CFWriteStreamClose(file); 294 | 295 | CFRelease(file); 296 | CFRelease(path); 297 | CFRelease(object); 298 | } 299 | } 300 | else 301 | { 302 | if (options.root) 303 | { 304 | search( /* service */ service, 305 | /* serviceHasMatchedDepth */ 0, 306 | /* serviceDepth */ 0, 307 | /* stackOfObjects */ stackOfObjects, 308 | /* options */ options ); 309 | } 310 | else 311 | { 312 | scan( /* service */ service, 313 | /* serviceHasMoreSiblings */ FALSE, 314 | /* serviceDepth */ 0, 315 | /* stackOfBits */ 0, 316 | /* options */ options ); 317 | } 318 | } 319 | 320 | // Release resources. 321 | 322 | IOObjectRelease(service); 323 | 324 | // Quit. 325 | 326 | exit(0); 327 | } 328 | 329 | // - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - 330 | 331 | static CFMutableDictionaryRef archive( io_registry_entry_t service, 332 | struct options options ) 333 | { 334 | io_name_t class; // (don't release) 335 | uint32_t count = 0; 336 | CFMutableDictionaryRef dictionary = 0; // (needs release) 337 | uint64_t identifier = 0; 338 | io_name_t location; // (don't release) 339 | io_name_t name; // (don't release) 340 | CFTypeRef object = 0; // (needs release) 341 | uint64_t state = 0; 342 | kern_return_t status = KERN_SUCCESS; 343 | uint64_t time = 0; 344 | 345 | // Determine whether the service is a match. 346 | 347 | if (options.list || compare(service, options)) 348 | { 349 | // Obtain the service's properties. 350 | 351 | status = IORegistryEntryCreateCFProperties( service, 352 | &dictionary, 353 | kCFAllocatorDefault, 354 | kNilOptions ); 355 | assertion(status == KERN_SUCCESS, "can't obtain properties"); 356 | } 357 | else 358 | { 359 | dictionary = CFDictionaryCreateMutable( kCFAllocatorDefault, 360 | 0, 361 | &kCFTypeDictionaryKeyCallBacks, 362 | &kCFTypeDictionaryValueCallBacks ); 363 | assertion(dictionary != NULL, "can't create dictionary"); 364 | } 365 | 366 | // Obtain the name of the service. 367 | 368 | status = IORegistryEntryGetNameInPlane(service, options.plane, name); 369 | assertion(status == KERN_SUCCESS, "can't obtain name"); 370 | 371 | object = CFStringCreateWithCString(kCFAllocatorDefault, name, kCFStringEncodingUTF8); 372 | assertion(object != NULL, "can't create name"); 373 | 374 | CFDictionarySetValue(dictionary, CFSTR("IORegistryEntryName"), object); 375 | CFRelease(object); 376 | 377 | // Obtain the location of the service. 378 | 379 | status = IORegistryEntryGetLocationInPlane(service, options.plane, location); 380 | if (status == KERN_SUCCESS) 381 | { 382 | object = CFStringCreateWithCString(kCFAllocatorDefault, location, kCFStringEncodingUTF8); 383 | assertion(object != NULL, "can't create location"); 384 | 385 | CFDictionarySetValue(dictionary, CFSTR("IORegistryEntryLocation"), object); 386 | CFRelease(object); 387 | } 388 | 389 | // Obtain the ID of the service. 390 | 391 | status = IORegistryEntryGetRegistryEntryID(service, &identifier); 392 | assertion(status == KERN_SUCCESS, "can't obtain identifier"); 393 | 394 | object = CFNumberCreate(kCFAllocatorDefault, kCFNumberSInt64Type, &identifier); 395 | assertion(object != NULL, "can't create identifier"); 396 | 397 | CFDictionarySetValue(dictionary, CFSTR("IORegistryEntryID"), object); 398 | CFRelease(object); 399 | 400 | // Obtain the class of the service. 401 | 402 | status = IOObjectGetClass(service, class); 403 | assertion(status == KERN_SUCCESS, "can't obtain class"); 404 | 405 | object = CFStringCreateWithCString(kCFAllocatorDefault, name, kCFStringEncodingUTF8); 406 | assertion(object != NULL, "can't create class"); 407 | 408 | CFDictionarySetValue(dictionary, CFSTR("IOObjectClass"), object); 409 | CFRelease(object); 410 | 411 | // Obtain the retain count of the service. 412 | 413 | count = IOObjectGetKernelRetainCount(service); 414 | 415 | object = CFNumberCreate(kCFAllocatorDefault, kCFNumberSInt32Type, &count); 416 | assertion(object != NULL, "can't create retain count"); 417 | 418 | CFDictionarySetValue(dictionary, CFSTR("IOObjectRetainCount"), object); 419 | CFRelease(object); 420 | 421 | // Obtain the busy state of the service (for IOService objects). 422 | 423 | if (IOObjectConformsTo(service, "IOService")) 424 | { 425 | status = IOServiceGetBusyStateAndTime(service, &state, &count, &time); 426 | assertion(status == KERN_SUCCESS, "can't obtain state"); 427 | 428 | object = CFNumberCreate(kCFAllocatorDefault, kCFNumberSInt64Type, &state); 429 | assertion(object != NULL, "can't create state"); 430 | 431 | CFDictionarySetValue(dictionary, CFSTR("IOServiceState"), object); 432 | CFRelease(object); 433 | 434 | object = CFNumberCreate(kCFAllocatorDefault, kCFNumberSInt32Type, &count); 435 | assertion(object != NULL, "can't create busy state"); 436 | 437 | CFDictionarySetValue(dictionary, CFSTR("IOServiceBusyState"), object); 438 | CFRelease(object); 439 | 440 | object = CFNumberCreate(kCFAllocatorDefault, kCFNumberSInt64Type, &time); 441 | assertion(object != NULL, "can't create busy time"); 442 | 443 | CFDictionarySetValue(dictionary, CFSTR("IOServiceBusyTime"), object); 444 | CFRelease(object); 445 | } 446 | 447 | return dictionary; 448 | } 449 | 450 | // - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - 451 | 452 | static CFMutableDictionaryRef archive_scan( io_registry_entry_t service, 453 | UInt32 serviceDepth, 454 | struct options options ) 455 | { 456 | CFMutableArrayRef array = 0; // (needs release) 457 | io_registry_entry_t child = 0; // (needs release) 458 | io_registry_entry_t childUpNext = 0; // (don't release) 459 | io_iterator_t children = 0; // (needs release) 460 | CFMutableDictionaryRef dictionary = 0; // (needs release) 461 | CFTypeRef object = 0; // (needs release) 462 | kern_return_t status = KERN_SUCCESS; 463 | 464 | // Obtain the service's children. 465 | 466 | status = IORegistryEntryGetChildIterator(service, options.plane, &children); 467 | assertion(status == KERN_SUCCESS, "can't obtain children"); 468 | 469 | childUpNext = IOIteratorNext(children); 470 | 471 | // Obtain the relevant service information. 472 | 473 | dictionary = archive(service, options); 474 | 475 | // Traverse over the children of this service. 476 | 477 | if (options.depth == 0 || options.depth > serviceDepth + 1) 478 | { 479 | if (childUpNext) 480 | { 481 | array = CFArrayCreateMutable(kCFAllocatorDefault, 0, &kCFTypeArrayCallBacks); 482 | assertion(array != NULL, "can't create array"); 483 | 484 | while (childUpNext) 485 | { 486 | child = childUpNext; 487 | childUpNext = IOIteratorNext(children); 488 | 489 | object = archive_scan( /* service */ child, 490 | /* serviceDepth */ serviceDepth + 1, 491 | /* options */ options ); 492 | assertion(object != NULL, "can't obtain child"); 493 | 494 | CFArrayAppendValue(array, object); 495 | CFRelease(object); 496 | 497 | IOObjectRelease(child); 498 | } 499 | 500 | CFDictionarySetValue(dictionary, CFSTR("IORegistryEntryChildren"), array); 501 | CFRelease(array); 502 | } 503 | } 504 | 505 | IOObjectRelease(children); 506 | 507 | return dictionary; 508 | } 509 | 510 | // - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - 511 | 512 | static CFMutableArrayRef archive_search( io_registry_entry_t service, 513 | UInt32 serviceHasMatchedDepth, 514 | UInt32 serviceDepth, 515 | io_registry_entry_t stackOfObjects[], 516 | struct options options ) 517 | { 518 | CFMutableArrayRef array = 0; // (needs release) 519 | CFMutableArrayRef array2 = 0; // (needs release) 520 | io_registry_entry_t child = 0; // (needs release) 521 | io_registry_entry_t childUpNext = 0; // (don't release) 522 | io_iterator_t children = 0; // (needs release) 523 | CFMutableDictionaryRef dictionary = 0; // (needs release) 524 | CFMutableDictionaryRef dictionary2 = 0; // (needs release) 525 | UInt32 index = 0; 526 | kern_return_t status = KERN_SUCCESS; 527 | 528 | // Determine whether the service is a match. 529 | 530 | if (serviceHasMatchedDepth < serviceDepth + 1 && compare(service, options)) 531 | { 532 | if (options.depth) 533 | { 534 | serviceHasMatchedDepth = serviceDepth + options.depth; 535 | } 536 | else 537 | { 538 | serviceHasMatchedDepth = UINT32_MAX; 539 | } 540 | 541 | if (options.tree) 542 | { 543 | if (options.depth) options.depth += serviceDepth; 544 | 545 | dictionary = archive_scan( /* service */ service, 546 | /* serviceDepth */ serviceDepth, 547 | /* options */ options ); 548 | 549 | if (options.depth) options.depth -= serviceDepth; 550 | 551 | for (index = serviceDepth; index > 0; index--) 552 | { 553 | dictionary2 = archive(stackOfObjects[index - 1], options); 554 | assertion(dictionary2 != NULL, "can't obtain parent"); 555 | 556 | CFDictionarySetValue(dictionary2, CFSTR("IORegistryEntryChildren"), dictionary); 557 | CFRelease(dictionary); 558 | 559 | dictionary = dictionary2; 560 | } 561 | } 562 | else 563 | { 564 | dictionary = archive_scan( /* service */ service, 565 | /* serviceDepth */ 0, 566 | /* options */ options ); 567 | } 568 | 569 | array = CFArrayCreateMutable(kCFAllocatorDefault, 0, &kCFTypeArrayCallBacks); 570 | assertion(array != NULL, "can't create array"); 571 | 572 | CFArrayAppendValue(array, dictionary); 573 | CFRelease(dictionary); 574 | } 575 | 576 | // Save service into stackOfObjects for this depth. 577 | 578 | stackOfObjects[serviceDepth] = service; 579 | 580 | // Obtain the service's children. 581 | 582 | status = IORegistryEntryGetChildIterator(service, options.plane, &children); 583 | assertion(status == KERN_SUCCESS, "can't obtain children"); 584 | 585 | childUpNext = IOIteratorNext(children); 586 | 587 | // Traverse over the children of this service. 588 | 589 | while (childUpNext) 590 | { 591 | child = childUpNext; 592 | childUpNext = IOIteratorNext(children); 593 | 594 | array2 = archive_search( /* service */ child, 595 | /* serviceHasMatchedDepth */ serviceHasMatchedDepth, 596 | /* serviceDepth */ serviceDepth + 1, 597 | /* stackOfObjects */ stackOfObjects, 598 | /* options */ options ); 599 | if (array2) 600 | { 601 | if (array) 602 | { 603 | CFArrayAppendArray(array, array2, CFRangeMake(0, CFArrayGetCount(array2))); 604 | CFRelease(array2); 605 | } 606 | else 607 | { 608 | array = array2; 609 | } 610 | } 611 | 612 | IOObjectRelease(child); 613 | } 614 | 615 | IOObjectRelease(children); 616 | 617 | return array; 618 | } 619 | 620 | // - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - 621 | 622 | static Boolean compare( io_registry_entry_t service, 623 | struct options options ) 624 | { 625 | CFStringRef key = 0; // (needs release) 626 | io_name_t location; // (don't release) 627 | Boolean match = FALSE; 628 | io_name_t name; // (don't release) 629 | kern_return_t status = KERN_SUCCESS; 630 | CFTypeRef value = 0; // (needs release) 631 | 632 | // Determine whether the class of the service is a match. 633 | 634 | if (options.class) 635 | { 636 | if (IOObjectConformsTo(service, options.class) == FALSE) 637 | { 638 | return FALSE; 639 | } 640 | 641 | match = TRUE; 642 | } 643 | 644 | // Determine whether the key of the service is a match. 645 | 646 | if (options.key) 647 | { 648 | key = CFStringCreateWithCString( kCFAllocatorDefault, 649 | options.key, 650 | kCFStringEncodingUTF8 ); 651 | assertion(key != NULL, "can't create key"); 652 | 653 | value = IORegistryEntryCreateCFProperty( service, 654 | key, 655 | kCFAllocatorDefault, 656 | kNilOptions ); 657 | 658 | CFRelease(key); 659 | 660 | if (value == NULL) 661 | { 662 | return FALSE; 663 | } 664 | 665 | CFRelease(value); 666 | 667 | match = TRUE; 668 | } 669 | 670 | // Determine whether the name of the service is a match. 671 | 672 | if (options.name) 673 | { 674 | // Obtain the name of the service. 675 | 676 | status = IORegistryEntryGetNameInPlane(service, options.plane, name); 677 | assertion(status == KERN_SUCCESS, "can't obtain name"); 678 | 679 | if (strchr(options.name, '@')) 680 | { 681 | strlcat(name, "@", sizeof(name)); 682 | 683 | // Obtain the location of the service. 684 | 685 | status = IORegistryEntryGetLocationInPlane(service, options.plane, location); 686 | if (status == KERN_SUCCESS) strlcat(name, location, sizeof(name)); 687 | } 688 | 689 | if (strcmp(options.name, name)) 690 | { 691 | return FALSE; 692 | } 693 | 694 | match = TRUE; 695 | } 696 | 697 | return match; 698 | } 699 | 700 | // - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - 701 | 702 | static void scan( io_registry_entry_t service, 703 | Boolean serviceHasMoreSiblings, 704 | UInt32 serviceDepth, 705 | UInt64 stackOfBits, 706 | struct options options ) 707 | { 708 | io_registry_entry_t child = 0; // (needs release) 709 | io_registry_entry_t childUpNext = 0; // (don't release) 710 | io_iterator_t children = 0; // (needs release) 711 | kern_return_t status = KERN_SUCCESS; 712 | 713 | // Obtain the service's children. 714 | 715 | status = IORegistryEntryGetChildIterator(service, options.plane, &children); 716 | assertion(status == KERN_SUCCESS, "can't obtain children"); 717 | 718 | childUpNext = IOIteratorNext(children); 719 | 720 | // Save has-more-siblings state into stackOfBits for this depth. 721 | 722 | if (serviceHasMoreSiblings) 723 | stackOfBits |= (1 << serviceDepth); 724 | else 725 | stackOfBits &= ~(1 << serviceDepth); 726 | 727 | // Save has-children state into stackOfBits for this depth. 728 | 729 | if (options.depth == 0 || options.depth > serviceDepth + 1) 730 | { 731 | if (childUpNext) 732 | stackOfBits |= (2 << serviceDepth); 733 | else 734 | stackOfBits &= ~(2 << serviceDepth); 735 | } 736 | 737 | // Print out the relevant service information. 738 | 739 | show(service, serviceDepth, stackOfBits, options); 740 | 741 | // Traverse over the children of this service. 742 | 743 | if (options.depth == 0 || options.depth > serviceDepth + 1) 744 | { 745 | while (childUpNext) 746 | { 747 | child = childUpNext; 748 | childUpNext = IOIteratorNext(children); 749 | 750 | scan( /* service */ child, 751 | /* serviceHasMoreSiblings */ (childUpNext) ? TRUE : FALSE, 752 | /* serviceDepth */ serviceDepth + 1, 753 | /* stackOfBits */ stackOfBits, 754 | /* options */ options ); 755 | 756 | IOObjectRelease(child); 757 | } 758 | } 759 | 760 | IOObjectRelease(children); 761 | } 762 | 763 | // - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - 764 | 765 | static void search( io_registry_entry_t service, 766 | UInt32 serviceHasMatchedDepth, 767 | UInt32 serviceDepth, 768 | io_registry_entry_t stackOfObjects[], 769 | struct options options ) 770 | { 771 | io_registry_entry_t child = 0; // (needs release) 772 | io_registry_entry_t childUpNext = 0; // (don't release) 773 | io_iterator_t children = 0; // (needs release) 774 | UInt32 index = 0; 775 | kern_return_t status = KERN_SUCCESS; 776 | 777 | // Determine whether the service is a match. 778 | 779 | if (serviceHasMatchedDepth < serviceDepth + 1 && compare(service, options)) 780 | { 781 | if (options.depth) 782 | { 783 | serviceHasMatchedDepth = serviceDepth + options.depth; 784 | } 785 | else 786 | { 787 | serviceHasMatchedDepth = UINT32_MAX; 788 | } 789 | 790 | if (options.tree) 791 | { 792 | for (index = 0; index < serviceDepth; index++) 793 | { 794 | show(stackOfObjects[index], index, (2 << index), options); 795 | } 796 | 797 | if (options.depth) options.depth += serviceDepth; 798 | 799 | scan( /* service */ service, 800 | /* serviceHasMoreSiblings */ FALSE, 801 | /* serviceDepth */ serviceDepth, 802 | /* stackOfBits */ 0, 803 | /* options */ options ); 804 | 805 | if (options.depth) options.depth -= serviceDepth; 806 | } 807 | else 808 | { 809 | scan( /* service */ service, 810 | /* serviceHasMoreSiblings */ FALSE, 811 | /* serviceDepth */ 0, 812 | /* stackOfBits */ 0, 813 | /* options */ options ); 814 | } 815 | 816 | println(""); 817 | } 818 | 819 | // Save service into stackOfObjects for this depth. 820 | 821 | stackOfObjects[serviceDepth] = service; 822 | 823 | // Obtain the service's children. 824 | 825 | status = IORegistryEntryGetChildIterator(service, options.plane, &children); 826 | assertion(status == KERN_SUCCESS, "can't obtain children"); 827 | 828 | childUpNext = IOIteratorNext(children); 829 | 830 | // Traverse over the children of this service. 831 | 832 | while (childUpNext) 833 | { 834 | child = childUpNext; 835 | childUpNext = IOIteratorNext(children); 836 | 837 | search( /* service */ child, 838 | /* serviceHasMatchedDepth */ serviceHasMatchedDepth, 839 | /* serviceDepth */ serviceDepth + 1, 840 | /* stackOfObjects */ stackOfObjects, 841 | /* options */ options ); 842 | 843 | IOObjectRelease(child); 844 | } 845 | 846 | IOObjectRelease(children); 847 | } 848 | 849 | // - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - 850 | 851 | static void show( io_registry_entry_t service, 852 | UInt32 serviceDepth, 853 | UInt64 stackOfBits, 854 | struct options options ) 855 | { 856 | io_name_t class; // (don't release) 857 | struct context context = { service, serviceDepth, stackOfBits, options }; 858 | uint32_t integer = 0; 859 | uint64_t state = 0; 860 | uint64_t accumulated_busy_time; 861 | io_name_t location; // (don't release) 862 | io_name_t name; // (don't release) 863 | CFMutableDictionaryRef properties = 0; // (needs release) 864 | kern_return_t status = KERN_SUCCESS; 865 | 866 | // Print out the name of the service. 867 | 868 | status = IORegistryEntryGetNameInPlane(service, options.plane, name); 869 | assertion(status == KERN_SUCCESS, "can't obtain name"); 870 | 871 | indent(TRUE, serviceDepth, stackOfBits); 872 | 873 | if (options.bold) boldon(); 874 | 875 | print("%s", name); 876 | 877 | if (options.bold) boldoff(); 878 | 879 | // Print out the location of the service. 880 | 881 | status = IORegistryEntryGetLocationInPlane(service, options.plane, location); 882 | if (status == KERN_SUCCESS) print("@%s", location); 883 | 884 | // Print out the class of the service. 885 | 886 | print(" "); 953 | 954 | // Determine whether the service is a match. 955 | 956 | if (options.list || compare(service, options)) 957 | { 958 | indent(FALSE, serviceDepth, stackOfBits); 959 | println("{"); 960 | 961 | // Obtain the service's properties. 962 | 963 | status = IORegistryEntryCreateCFProperties( service, 964 | &properties, 965 | kCFAllocatorDefault, 966 | kNilOptions ); 967 | assertion(status == KERN_SUCCESS, "can't obtain properties"); 968 | 969 | // Print out the service's properties. 970 | 971 | CFDictionaryApplyFunction(properties, showitem, &context); 972 | 973 | indent(FALSE, serviceDepth, stackOfBits); 974 | println("}"); 975 | indent(FALSE, serviceDepth, stackOfBits); 976 | println(""); 977 | 978 | // Release resources. 979 | 980 | CFRelease(properties); 981 | } 982 | } 983 | 984 | // - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - 985 | 986 | static void showitem(const void * key, const void * value, void * parameter) 987 | { 988 | struct context * context = parameter; // (don't release) 989 | 990 | // Print out one of the service's properties. 991 | 992 | indent(FALSE, context->serviceDepth, context->stackOfBits); 993 | print(" "); 994 | cfshow(key); 995 | print(" = "); 996 | 997 | if (context->options.format) 998 | { 999 | printProp(key, value, context); 1000 | } 1001 | else 1002 | { 1003 | cfshow(value); 1004 | println(""); 1005 | } 1006 | } 1007 | 1008 | // - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - 1009 | 1010 | static void indent(Boolean isNode, UInt32 serviceDepth, UInt64 stackOfBits) 1011 | { 1012 | // stackOfBits representation, given current zero-based depth is n: 1013 | // bit n+1 = does depth n have children? 1=yes, 0=no 1014 | // bit [n, .. i .., 0] = does depth i have more siblings? 1=yes, 0=no 1015 | 1016 | UInt32 index; 1017 | 1018 | if (isNode) 1019 | { 1020 | for (index = 0; index < serviceDepth; index++) 1021 | print( (stackOfBits & (1 << index)) ? "| " : " " ); 1022 | 1023 | print("+-o "); 1024 | } 1025 | else // if (!isNode) 1026 | { 1027 | for (index = 0; index <= serviceDepth + 1; index++) 1028 | print( (stackOfBits & (1 << index)) ? "| " : " " ); 1029 | } 1030 | } 1031 | 1032 | // - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - 1033 | 1034 | void usage() 1035 | { 1036 | fprintf( stderr, 1037 | "usage: ioreg [-abfilrtx] [-c class] [-d depth] [-k key] [-n name] [-p plane] [-w width]\n" 1038 | "where options are:\n" 1039 | "\t-a archive output\n" 1040 | "\t-b show object name in bold\n" 1041 | "\t-c list properties of objects with the given class\n" 1042 | "\t-d limit tree to the given depth\n" 1043 | "\t-f enable smart formatting\n" 1044 | "\t-i show object inheritance\n" 1045 | "\t-k list properties of objects with the given key\n" 1046 | "\t-l list properties of all objects\n" 1047 | "\t-n list properties of objects with the given name\n" 1048 | "\t-p traverse registry over the given plane (IOService is default)\n" 1049 | "\t-r show subtrees rooted by the given criteria\n" 1050 | "\t-t show location of each substree\n" 1051 | "\t-w clip output to the given line width (0 is unlimited)\n" 1052 | "\t-x show data and numbers as hexadecimal\n" 1053 | ); 1054 | exit(1); 1055 | } 1056 | 1057 | // - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - 1058 | 1059 | static char * termcapstr_boldon = 0; 1060 | static char * termcapstr_boldoff = 0; 1061 | 1062 | static int termcapstr_outc(int c) 1063 | { 1064 | return putchar(c); 1065 | } 1066 | 1067 | static void boldinit() 1068 | { 1069 | char * term; 1070 | static char termcapbuf[64]; 1071 | char * termcapbufptr = termcapbuf; 1072 | 1073 | term = getenv("TERM"); 1074 | 1075 | if (term) 1076 | { 1077 | if (tgetent(NULL, term) > 0) 1078 | { 1079 | termcapstr_boldon = tgetstr("md", &termcapbufptr); 1080 | termcapstr_boldoff = tgetstr("me", &termcapbufptr); 1081 | 1082 | assertion(termcapbufptr - termcapbuf <= sizeof(termcapbuf), "can't obtain terminfo"); 1083 | } 1084 | } 1085 | 1086 | if (termcapstr_boldon == 0) termcapstr_boldon = ""; 1087 | if (termcapstr_boldoff == 0) termcapstr_boldoff = ""; 1088 | } 1089 | 1090 | static void boldon() 1091 | { 1092 | tputs(termcapstr_boldon, 1, termcapstr_outc); 1093 | } 1094 | 1095 | static void boldoff() 1096 | { 1097 | tputs(termcapstr_boldoff, 1, termcapstr_outc); 1098 | } 1099 | 1100 | // - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - 1101 | 1102 | static char * printbuf = 0; 1103 | static int printbufclip = FALSE; 1104 | static int printbufleft = 0; 1105 | static int printbufsize = 0; 1106 | 1107 | static void printinit(int width) 1108 | { 1109 | if (width) 1110 | { 1111 | printbuf = malloc(width); 1112 | printbufleft = width; 1113 | printbufsize = width; 1114 | 1115 | assertion(printbuf != NULL, "can't allocate buffer"); 1116 | } 1117 | } 1118 | 1119 | static void printva(const char * format, va_list arguments) 1120 | { 1121 | if (printbufsize) 1122 | { 1123 | char * c; 1124 | int count = vsnprintf(printbuf, printbufleft, format, arguments); 1125 | 1126 | while ( (c = strchr(printbuf, '\n')) ) *c = ' '; // (strip newlines) 1127 | 1128 | printf("%s", printbuf); 1129 | 1130 | if (count >= printbufleft) 1131 | { 1132 | count = printbufleft - 1; 1133 | printbufclip = TRUE; 1134 | } 1135 | 1136 | printbufleft -= count; // (printbufleft never hits zero, stops at one) 1137 | } 1138 | else 1139 | { 1140 | vprintf(format, arguments); 1141 | } 1142 | } 1143 | 1144 | static void print(const char * format, ...) 1145 | { 1146 | va_list arguments; 1147 | va_start(arguments, format); 1148 | printva(format, arguments); 1149 | va_end(arguments); 1150 | } 1151 | 1152 | static void println(const char * format, ...) 1153 | { 1154 | va_list arguments; 1155 | va_start(arguments, format); 1156 | printva(format, arguments); 1157 | va_end(arguments); 1158 | 1159 | if (printbufclip) printf("$"); 1160 | 1161 | printf("\n"); 1162 | 1163 | printbufclip = FALSE; 1164 | printbufleft = printbufsize; 1165 | } 1166 | 1167 | // - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - 1168 | 1169 | static Boolean cfshowhex; 1170 | 1171 | static void cfshowinit(Boolean hex) 1172 | { 1173 | cfshowhex = hex; 1174 | } 1175 | 1176 | static void cfshow(CFTypeRef object) 1177 | { 1178 | CFTypeID type = CFGetTypeID(object); 1179 | 1180 | if ( type == CFArrayGetTypeID() ) cfarrayshow(object); 1181 | else if ( type == CFBooleanGetTypeID() ) cfbooleanshow(object); 1182 | else if ( type == CFDataGetTypeID() ) cfdatashow(object); 1183 | else if ( type == CFDictionaryGetTypeID() ) cfdictionaryshow(object); 1184 | else if ( type == CFNumberGetTypeID() ) cfnumbershow(object); 1185 | else if ( type == CFSetGetTypeID() ) cfsetshow(object); 1186 | else if ( type == CFStringGetTypeID() ) cfstringshow(object); 1187 | else print(""); 1188 | } 1189 | 1190 | static void cfarrayshowapplier(const void * value, void * parameter) 1191 | { 1192 | Boolean * first = (Boolean *) parameter; 1193 | 1194 | if (*first) 1195 | *first = FALSE; 1196 | else 1197 | print(","); 1198 | 1199 | cfshow(value); 1200 | } 1201 | 1202 | static void cfarrayshow(CFArrayRef object) 1203 | { 1204 | Boolean first = TRUE; 1205 | CFRange range = { 0, CFArrayGetCount(object) }; 1206 | 1207 | print("("); 1208 | CFArrayApplyFunction(object, range, cfarrayshowapplier, &first); 1209 | print(")"); 1210 | } 1211 | 1212 | static void cfbooleanshow(CFBooleanRef object) 1213 | { 1214 | print(CFBooleanGetValue(object) ? "Yes" : "No"); 1215 | } 1216 | 1217 | static void cfdatashow(CFDataRef object) 1218 | { 1219 | UInt32 asciiNormalCount = 0; 1220 | UInt32 asciiSymbolCount = 0; 1221 | const UInt8 * bytes; 1222 | CFIndex index; 1223 | CFIndex length; 1224 | 1225 | print("<"); 1226 | length = CFDataGetLength(object); 1227 | bytes = CFDataGetBytePtr(object); 1228 | 1229 | // 1230 | // This algorithm detects ascii strings, or a set of ascii strings, inside a 1231 | // stream of bytes. The string, or last string if in a set, needn't be null 1232 | // terminated. High-order symbol characters are accepted, unless they occur 1233 | // too often (80% of characters must be normal). Zero padding at the end of 1234 | // the string(s) is valid. If the data stream is only one byte, it is never 1235 | // considered to be a string. 1236 | // 1237 | 1238 | for (index = 0; index < length; index++) // (scan for ascii string/strings) 1239 | { 1240 | if (bytes[index] == 0) // (detected null in place of a new string, 1241 | { // ensure remainder of the string is null) 1242 | break; // (either end of data or a non-null byte in stream) 1243 | } 1244 | else // (scan along this potential ascii string) 1245 | { 1246 | for (; index < length; index++) 1247 | { 1248 | if (isprint(bytes[index])) 1249 | asciiNormalCount++; 1250 | else if (bytes[index] >= 128 && bytes[index] <= 254) 1251 | asciiSymbolCount++; 1252 | else 1253 | break; 1254 | } 1255 | 1256 | if (index < length && bytes[index] == 0) // (end of string) 1257 | continue; 1258 | else // (either end of data or an unprintable character) 1259 | break; 1260 | } 1261 | } 1262 | 1263 | if ((asciiNormalCount >> 2) < asciiSymbolCount) // (is 80% normal ascii?) 1264 | index = 0; 1265 | else if (length == 1) // (is just one byte?) 1266 | index = 0; 1267 | else if (cfshowhex) 1268 | index = 0; 1269 | 1270 | if (index >= length && asciiNormalCount) // (is a string or set of strings?) 1271 | { 1272 | Boolean quoted = FALSE; 1273 | 1274 | for (index = 0; index < length; index++) 1275 | { 1276 | if (bytes[index]) 1277 | { 1278 | if (quoted == FALSE) 1279 | { 1280 | quoted = TRUE; 1281 | if (index) 1282 | print(",\""); 1283 | else 1284 | print("\""); 1285 | } 1286 | print("%c", bytes[index]); 1287 | } 1288 | else 1289 | { 1290 | if (quoted == TRUE) 1291 | { 1292 | quoted = FALSE; 1293 | print("\""); 1294 | } 1295 | else 1296 | break; 1297 | } 1298 | } 1299 | if (quoted == TRUE) 1300 | print("\""); 1301 | } 1302 | else // (is not a string or set of strings) 1303 | { 1304 | for (index = 0; index < length; index++) print("%02x", bytes[index]); 1305 | } 1306 | 1307 | print(">"); 1308 | } 1309 | 1310 | static void cfdictionaryshowapplier( const void * key, 1311 | const void * value, 1312 | void * parameter ) 1313 | { 1314 | Boolean * first = (Boolean *) parameter; 1315 | 1316 | if (*first) 1317 | *first = FALSE; 1318 | else 1319 | print(","); 1320 | 1321 | cfshow(key); 1322 | print("="); 1323 | cfshow(value); 1324 | } 1325 | 1326 | static void cfdictionaryshow(CFDictionaryRef object) 1327 | { 1328 | Boolean first = TRUE; 1329 | 1330 | print("{"); 1331 | CFDictionaryApplyFunction(object, cfdictionaryshowapplier, &first); 1332 | print("}"); 1333 | } 1334 | 1335 | static void cfnumbershow(CFNumberRef object) 1336 | { 1337 | long long number; 1338 | 1339 | if (CFNumberGetValue(object, kCFNumberLongLongType, &number)) 1340 | { 1341 | if (cfshowhex) 1342 | print("0x%qx", (unsigned long long)number); 1343 | else 1344 | print("%qu", (unsigned long long)number); 1345 | } 1346 | } 1347 | 1348 | static void cfsetshowapplier(const void * value, void * parameter) 1349 | { 1350 | Boolean * first = (Boolean *) parameter; 1351 | 1352 | if (*first) 1353 | *first = FALSE; 1354 | else 1355 | print(","); 1356 | 1357 | cfshow(value); 1358 | } 1359 | 1360 | static void cfsetshow(CFSetRef object) 1361 | { 1362 | Boolean first = TRUE; 1363 | print("["); 1364 | CFSetApplyFunction(object, cfsetshowapplier, &first); 1365 | print("]"); 1366 | } 1367 | 1368 | static void cfstringshow(CFStringRef object) 1369 | { 1370 | const char * c = CFStringGetCStringPtr(object, kCFStringEncodingMacRoman); 1371 | 1372 | if (c) 1373 | print("\"%s\"", c); 1374 | else 1375 | { 1376 | CFIndex bufferSize = CFStringGetLength(object) + 1; 1377 | char * buffer = malloc(bufferSize); 1378 | 1379 | if (buffer) 1380 | { 1381 | if ( CFStringGetCString( 1382 | /* string */ object, 1383 | /* buffer */ buffer, 1384 | /* bufferSize */ bufferSize, 1385 | /* encoding */ kCFStringEncodingMacRoman ) ) 1386 | print("\"%s\"", buffer); 1387 | 1388 | free(buffer); 1389 | } 1390 | } 1391 | } 1392 | 1393 | // - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - 1394 | 1395 | static CFStringRef createInheritanceStringForIORegistryClassName(CFStringRef name) 1396 | { 1397 | CFStringRef curClassCFStr; 1398 | CFStringRef oldClassCFStr; 1399 | CFMutableStringRef outCFStr; 1400 | 1401 | outCFStr = CFStringCreateMutable (NULL, 512); 1402 | CFStringInsert (outCFStr, 0, name); 1403 | 1404 | curClassCFStr = CFStringCreateCopy (NULL, name); 1405 | 1406 | for (;;) 1407 | { 1408 | oldClassCFStr = curClassCFStr; 1409 | curClassCFStr = IOObjectCopySuperclassForClass (curClassCFStr); 1410 | CFRelease (oldClassCFStr); 1411 | 1412 | if (FALSE == CFEqual (curClassCFStr, CFSTR ("OSObject"))) 1413 | { 1414 | CFStringInsert (outCFStr, 0, CFSTR (":")); 1415 | CFStringInsert (outCFStr, 0, curClassCFStr); 1416 | } 1417 | else 1418 | { 1419 | break; 1420 | } 1421 | } 1422 | 1423 | if (curClassCFStr) CFRelease(curClassCFStr); 1424 | 1425 | // Return the CFMutableStringRef as a CFStringRef because it is derived and compatible: 1426 | return (CFStringRef) outCFStr; 1427 | } 1428 | 1429 | // - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - 1430 | 1431 | static void printProp(CFStringRef key, CFTypeRef value, struct context * context) 1432 | { 1433 | kern_return_t status = KERN_SUCCESS; 1434 | Boolean valueShown = FALSE; // Flag is set when property is printed 1435 | io_registry_entry_t thisObj; 1436 | 1437 | thisObj = context->service; 1438 | 1439 | // Match "reg" property for PCI devices. 1440 | if (CFStringCompare(key, CFSTR("reg"), 0 ) == 0) 1441 | { 1442 | io_registry_entry_t parentObj; // (needs release) 1443 | io_name_t parentName; 1444 | 1445 | // If the parent entry in the IODeviceTree plane is "pci", 1446 | // then we've found what we're looking for. 1447 | 1448 | status = IORegistryEntryGetParentEntry( thisObj, 1449 | kIODeviceTreePlane, 1450 | &parentObj ); 1451 | if (status == KERN_SUCCESS) 1452 | { 1453 | status = IORegistryEntryGetNameInPlane( parentObj, 1454 | kIODeviceTreePlane, 1455 | parentName ); 1456 | assertion(status == KERN_SUCCESS, "could not get name of parent"); 1457 | 1458 | IOObjectRelease(parentObj); 1459 | 1460 | if (strncmp(parentName, "pci", 3) == 0) 1461 | { 1462 | printPhysAddr(value, context); 1463 | valueShown = TRUE; 1464 | } 1465 | } 1466 | } 1467 | 1468 | // Match "assigned-addresses" property. 1469 | else if (CFStringCompare(key, CFSTR("assigned-addresses"), 0) == 0) 1470 | { 1471 | printPhysAddr(value, context); 1472 | valueShown = TRUE; 1473 | } 1474 | 1475 | // Match "slot-names" property. 1476 | else if (CFStringCompare(key, CFSTR("slot-names"), 0) == 0) 1477 | { 1478 | printSlotNames(value, context); 1479 | valueShown = TRUE; 1480 | } 1481 | 1482 | // Match "ranges" property. 1483 | else if (CFStringCompare(key, CFSTR("ranges"), 0) == 0) 1484 | { 1485 | printPCIRanges(value, context); 1486 | valueShown = TRUE; 1487 | } 1488 | 1489 | // Match "interrupt-map" property. 1490 | else if (CFStringCompare(key, CFSTR("interrupt-map"), 0) == 0) 1491 | { 1492 | printInterruptMap(value, context); 1493 | valueShown = TRUE; 1494 | } 1495 | 1496 | // Match "interrupts" property. 1497 | else if ( CFStringCompare( key, CFSTR("interrupts"), 0) == 0 ) 1498 | { 1499 | printInterrupts( value, context ); 1500 | valueShown = TRUE; 1501 | } 1502 | 1503 | // Match "interrupt-parent" property. 1504 | else if ( CFStringCompare( key, CFSTR("interrupt-parent"), 0) == 0 ) 1505 | { 1506 | printInterruptParent( value, context ); 1507 | valueShown = TRUE; 1508 | } 1509 | 1510 | // Print the value if it doesn't have a formatter. 1511 | if (valueShown == FALSE) 1512 | { 1513 | if (CFGetTypeID(value) == CFDataGetTypeID()) 1514 | { 1515 | printData(value, context); 1516 | } 1517 | else 1518 | { 1519 | cfshow(value); 1520 | println(""); 1521 | } 1522 | } 1523 | } 1524 | 1525 | /* The following data structures, masks and shift values are used to decode 1526 | * physical address properties as defined by IEEE 1275-1994. The format is 1527 | * used in 'reg' and 'assigned-address' properties. 1528 | * 1529 | * The format of the physHi word is as follows: 1530 | * 1531 | * npt000ss bbbbbbbb dddddfff rrrrrrrr 1532 | * 1533 | * n 1 = Relocatable, 0 = Absolute (1 bit) 1534 | * p 1 = Prefetchable (1 bit) 1535 | * t 1 = Alias (1 bit) 1536 | * ss Space code (Config, I/O, Mem, 64-bit Mem) (2 bits) 1537 | * bbbbbbbb Bus number (8 bits) 1538 | * ddddd Device number (5 bits) 1539 | * fff Function number (3 bits) 1540 | * rrrrrrrr Register number (8 bits) 1541 | */ 1542 | 1543 | struct physAddrProperty { 1544 | UInt32 physHi; 1545 | UInt32 physMid; 1546 | UInt32 physLo; 1547 | UInt32 sizeHi; 1548 | UInt32 sizeLo; 1549 | }; 1550 | 1551 | #define kPhysAbsoluteMask 0x80000000 1552 | #define kPhysPrefetchMask 0x40000000 1553 | #define kPhysAliasMask 0x20000000 1554 | #define kPhysSpaceMask 0x03000000 1555 | #define kPhysSpaceShift 24 1556 | #define kPhysBusMask 0x00FF0000 1557 | #define kPhysBusShift 16 1558 | #define kPhysDeviceMask 0x0000F800 1559 | #define kPhysDeviceShift 11 1560 | #define kPhysFunctionMask 0x00000700 1561 | #define kPhysFunctionShift 8 1562 | #define kPhysRegisterMask 0x000000FF 1563 | #define kPhysRegisterShift 0 1564 | 1565 | static SInt32 1566 | getRecursivePropValue( io_registry_entry_t thisRegEntry, CFStringRef propertyNameToLookFor ) 1567 | { 1568 | SInt32 returnValue; 1569 | CFTypeRef ptr; 1570 | 1571 | ptr = IORegistryEntrySearchCFProperty(thisRegEntry, 1572 | kIODeviceTreePlane, 1573 | propertyNameToLookFor, 1574 | kCFAllocatorDefault, 1575 | kIORegistryIterateParents | kIORegistryIterateRecursively); 1576 | assertion( ptr != NULL, "unable to get properties" ); 1577 | 1578 | returnValue = *(SInt32 *)CFDataGetBytePtr( (CFDataRef) ptr ); 1579 | 1580 | CFRelease( ptr ); 1581 | return( returnValue ); 1582 | } 1583 | 1584 | static void printPhysAddr(CFTypeRef value, struct context * context) 1585 | { 1586 | CFIndex length; // stores total byte count in this prop. 1587 | struct physAddrProperty *physAddr; // points to current physAddr property 1588 | UInt64 numPhysAddr, // how many physAddr's to decode? 1589 | count; // loop counter variable 1590 | UInt32 tmpCell; // temp storage for a single word 1591 | 1592 | UInt32 busNumber, // temp storage for decoded values 1593 | deviceNumber, 1594 | functionNumber, 1595 | registerNumber; 1596 | const char *addressType, 1597 | *isPrefetch, 1598 | *isAlias, 1599 | *isAbsolute; 1600 | 1601 | // Ensure that the object passed in is in fact a CFData object. 1602 | 1603 | assertion(CFGetTypeID(value) == CFDataGetTypeID(), "invalid phys addr"); 1604 | 1605 | // Make sure there is actually data in the object. 1606 | length = CFDataGetLength((CFDataRef)value); 1607 | 1608 | if (length == 0) 1609 | { 1610 | println("<>"); 1611 | return; 1612 | } 1613 | 1614 | numPhysAddr = length / sizeof(struct physAddrProperty); 1615 | physAddr = (struct physAddrProperty *)CFDataGetBytePtr((CFDataRef)value); 1616 | 1617 | println(""); 1618 | 1619 | for (count = 0; count < numPhysAddr; count++) 1620 | { 1621 | tmpCell = physAddr[count].physHi; // copy physHi word to a temp var 1622 | 1623 | // Decode the fields in the physHi word. 1624 | 1625 | busNumber = (tmpCell & kPhysBusMask) >> kPhysBusShift; 1626 | deviceNumber = (tmpCell & kPhysDeviceMask) >> kPhysDeviceShift; 1627 | functionNumber = (tmpCell & kPhysFunctionMask) >> kPhysFunctionShift; 1628 | registerNumber = (tmpCell & kPhysRegisterMask) >> kPhysRegisterShift; 1629 | isAbsolute = ((tmpCell & kPhysAbsoluteMask) != 0) ? "abs" : "rel"; 1630 | isPrefetch = ((tmpCell & kPhysPrefetchMask) != 0) ? ", prefetch" : ""; 1631 | isAlias = ((tmpCell & kPhysAliasMask) != 0) ? ", alias" : ""; 1632 | switch ((tmpCell & kPhysSpaceMask) >> kPhysSpaceShift) 1633 | { 1634 | case 0: addressType = "Config"; break; 1635 | case 1: addressType = "I/O"; break; 1636 | case 2: addressType = "Mem"; break; 1637 | case 3: addressType = "64-bit"; break; 1638 | default: addressType = "?"; break; 1639 | } 1640 | 1641 | // Format and print the information for this entry. 1642 | 1643 | indent(FALSE, context->serviceDepth, context->stackOfBits); 1644 | println(" %02lu: phys.hi: %08lx phys.mid: %08lx phys.lo: %08lx", 1645 | (unsigned long)count, 1646 | (unsigned long)physAddr[count].physHi, 1647 | (unsigned long)physAddr[count].physMid, 1648 | (unsigned long)physAddr[count].physLo ); 1649 | 1650 | indent(FALSE, context->serviceDepth, context->stackOfBits); 1651 | println(" size.hi: %08lx size.lo: %08lx", 1652 | (unsigned long)physAddr[count].sizeHi, 1653 | (unsigned long)physAddr[count].sizeLo ); 1654 | 1655 | indent(FALSE, context->serviceDepth, context->stackOfBits); 1656 | println(" bus: %lu dev: %lu func: %lu reg: %lu", 1657 | (unsigned long)busNumber, 1658 | (unsigned long)deviceNumber, 1659 | (unsigned long)functionNumber, 1660 | (unsigned long)registerNumber ); 1661 | 1662 | indent(FALSE, context->serviceDepth, context->stackOfBits); 1663 | println(" type: %s flags: %s%s%s", 1664 | addressType, 1665 | isAbsolute, 1666 | isPrefetch, 1667 | isAlias ); 1668 | } 1669 | } 1670 | 1671 | static void printSlotNames(CFTypeRef value, struct context * context) 1672 | { 1673 | CFIndex length; 1674 | char * bytePtr; 1675 | UInt32 count; 1676 | UInt32 * avail_slots; 1677 | 1678 | // Ensure that the object passed in is in fact a CFData object. 1679 | 1680 | assertion(CFGetTypeID(value) == CFDataGetTypeID(), "invalid phys addr"); 1681 | 1682 | // Make sure there is actually data in the object. 1683 | 1684 | length = CFDataGetLength((CFDataRef)value); 1685 | 1686 | if (length == 0) 1687 | { 1688 | println("<>"); 1689 | return; 1690 | } 1691 | 1692 | avail_slots = (UInt32 *)CFDataGetBytePtr((CFDataRef)value); 1693 | bytePtr = (char *)avail_slots + sizeof(UInt32); 1694 | 1695 | // Ignore entries that have no named slots. 1696 | 1697 | if (*avail_slots == 0) 1698 | { 1699 | println("<>"); 1700 | return; 1701 | } 1702 | 1703 | println(""); 1704 | 1705 | // Cycle through all 32 bit positions and print slot names. 1706 | 1707 | for (count = 0; count < 32; count++) 1708 | { 1709 | if ((*avail_slots & (1 << count)) != 0) 1710 | { 1711 | indent(FALSE, context->serviceDepth, context->stackOfBits); 1712 | println(" %02lu: %s", (unsigned long)count, bytePtr); 1713 | bytePtr += strlen(bytePtr) + 1; // advance to next string 1714 | } 1715 | } 1716 | } 1717 | 1718 | static void printPCIRanges(CFTypeRef value, struct context * context) 1719 | { 1720 | kern_return_t status = KERN_SUCCESS; 1721 | CFIndex length; 1722 | UInt32 *quadletPtr; 1723 | SInt32 parentACells, childACells, childSCells, elemSize; 1724 | io_registry_entry_t parentObj; // must be released 1725 | UInt64 i,j,nRanges; 1726 | SInt32 counts[3]; 1727 | const char *titles[] = {"-child--", "-parent-", "-size---"}; 1728 | 1729 | // Ensure that the object passed in is in fact a CFData object. 1730 | assertion(CFGetTypeID(value) == CFDataGetTypeID(), "invalid ranges"); 1731 | 1732 | // Make sure there is actually data in the object. 1733 | length = CFDataGetLength((CFDataRef)value); 1734 | 1735 | if (length == 0) 1736 | { 1737 | println("<>"); 1738 | return; 1739 | } 1740 | 1741 | quadletPtr = (UInt32 *)CFDataGetBytePtr((CFDataRef)value); 1742 | 1743 | // Get #address-cells of device-tree parent 1744 | status = IORegistryEntryGetParentEntry( context->service, kIODeviceTreePlane, &parentObj ); 1745 | assertion(status == KERN_SUCCESS, "unable to get device tree parent"); 1746 | 1747 | parentACells = getRecursivePropValue( parentObj, CFSTR( "#address-cells" ) ); 1748 | 1749 | IOObjectRelease( parentObj ); 1750 | 1751 | // Get #address-cells and #size-cells for owner 1752 | childACells = getRecursivePropValue( context->service, CFSTR( "#address-cells" ) ); 1753 | childSCells = getRecursivePropValue( context->service, CFSTR( "#size-cells" ) ); 1754 | 1755 | // ranges property is a list of [[child addr][parent addr][size]] 1756 | elemSize = childACells + parentACells + childSCells; 1757 | 1758 | // print a title line 1759 | println(""); 1760 | indent(FALSE, context->serviceDepth, context->stackOfBits); 1761 | print(" "); 1762 | 1763 | // set up array of cell counts (only used to print title) 1764 | counts[0] = childACells; 1765 | counts[1] = parentACells; 1766 | counts[2] = childSCells; 1767 | 1768 | for (j = 0; j < 3; j++) 1769 | { 1770 | print("%s", titles[j]); // titles is init'ed at start of func. 1771 | if (counts[j] > 1) 1772 | { 1773 | print("-"); 1774 | for( i = 2; i <= counts[j]; i++) 1775 | { 1776 | if(i == counts[j]) 1777 | print("-------- "); 1778 | else 1779 | print("---------"); 1780 | } 1781 | } 1782 | else 1783 | print(" "); 1784 | } 1785 | println(""); 1786 | 1787 | nRanges = length/(elemSize * sizeof(UInt32)); 1788 | 1789 | for(j = 0; j < nRanges; j++) 1790 | { 1791 | indent(FALSE, context->serviceDepth, context->stackOfBits); 1792 | print(" "); 1793 | for(i = 0; i < elemSize; i++) print("%08lx ", (unsigned long)*quadletPtr++); 1794 | println(""); 1795 | } 1796 | } 1797 | 1798 | // constructs a path string for a node in the device tree 1799 | static void makepath(io_registry_entry_t target, io_string_t path) 1800 | { 1801 | kern_return_t status = KERN_SUCCESS; 1802 | 1803 | status = IORegistryEntryGetPath(target, kIODeviceTreePlane, path); 1804 | assertion(status == KERN_SUCCESS, "unable to get path"); 1805 | 1806 | strlcpy(path, strchr(path, ':') + 1, sizeof(io_string_t)); 1807 | } 1808 | 1809 | static Boolean lookupPHandle(UInt32 phandle, io_registry_entry_t * device) 1810 | { 1811 | CFDictionaryRef props; 1812 | Boolean ret = FALSE; // pre-set to failure 1813 | CFStringRef key = CFSTR(kIOPropertyMatchKey); 1814 | CFDictionaryRef value; 1815 | CFStringRef phandleKey = CFSTR("AAPL,phandle"); 1816 | CFDataRef data; 1817 | 1818 | data = CFDataCreate(NULL, (void *)&phandle, sizeof(UInt32)); 1819 | 1820 | props = CFDictionaryCreate( NULL, 1821 | (void *)&phandleKey, 1822 | (void *)&data, 1823 | 1, 1824 | &kCFCopyStringDictionaryKeyCallBacks, 1825 | &kCFTypeDictionaryValueCallBacks ); 1826 | 1827 | value = CFDictionaryCreate( NULL, 1828 | (void *)&key, 1829 | (void *)&props, 1830 | 1, 1831 | &kCFCopyStringDictionaryKeyCallBacks, 1832 | &kCFTypeDictionaryValueCallBacks ); 1833 | 1834 | /* This call consumes 'value', so do not release it. 1835 | */ 1836 | *device = IOServiceGetMatchingService(kIOMasterPortDefault, value); 1837 | 1838 | if (*device) 1839 | ret = TRUE; 1840 | 1841 | CFRelease(props); 1842 | CFRelease(data); 1843 | 1844 | return(ret); 1845 | } 1846 | 1847 | static void printInterruptMap(CFTypeRef value, struct context * context) 1848 | { 1849 | io_registry_entry_t intParent; 1850 | io_string_t path; 1851 | SInt32 childCells, parentCells; 1852 | UInt32 *position, *end; 1853 | CFIndex length, count, index; 1854 | 1855 | // Get #address-cells and #interrupt-cells for owner 1856 | childCells = getRecursivePropValue( context->service, CFSTR("#address-cells" ) ) 1857 | + getRecursivePropValue( context->service, CFSTR("#interrupt-cells" ) ); 1858 | 1859 | // Walk through each table entry. 1860 | position = (UInt32 *)CFDataGetBytePtr((CFDataRef)value); 1861 | length = CFDataGetLength((CFDataRef)value)/sizeof(UInt32); 1862 | end = position + length; 1863 | count = 0; 1864 | 1865 | println(""); 1866 | 1867 | while (position < end) 1868 | { 1869 | indent(FALSE, context->serviceDepth, context->stackOfBits); 1870 | print(" %02ld: ", (unsigned long)count); 1871 | 1872 | // Display the child's unit interrupt specifier. 1873 | print(" child: "); 1874 | for (index = 0; index < childCells; index++) { 1875 | print("%08lx ", (unsigned long)*position++); 1876 | } 1877 | println(""); 1878 | 1879 | // Lookup the phandle and retreive needed info. 1880 | assertion( lookupPHandle(*position, &intParent), "error looking up phandle" ); 1881 | 1882 | parentCells = getRecursivePropValue( intParent, CFSTR( "#address-cells" ) ) 1883 | + getRecursivePropValue( intParent, CFSTR( "#interrupt-cells" ) ); 1884 | 1885 | *path = '\0'; 1886 | makepath(intParent, path); 1887 | 1888 | IOObjectRelease(intParent); 1889 | 1890 | // Display the phandle, corresponding device path, and 1891 | // the parent interrupt specifier. 1892 | indent(FALSE, context->serviceDepth, context->stackOfBits); 1893 | println(" phandle: %08lx (%s)", (unsigned long)*position++, path); 1894 | 1895 | indent(FALSE, context->serviceDepth, context->stackOfBits); 1896 | print(" parent: "); 1897 | for (index = 0; index < parentCells; index++) { 1898 | print("%08lx ", (unsigned long)*position++); 1899 | } 1900 | println(""); 1901 | 1902 | count++; 1903 | } 1904 | } 1905 | 1906 | static void printInterrupts(CFTypeRef value, struct context * context) 1907 | { 1908 | UInt32 *position, *end; 1909 | CFIndex length, count, index; 1910 | 1911 | // Walk through each table entry. 1912 | position = (UInt32 *)CFDataGetBytePtr((CFDataRef)value); 1913 | length = CFDataGetLength((CFDataRef)value) / sizeof(UInt32); 1914 | end = position + length; 1915 | count = 0; 1916 | index = 0; 1917 | 1918 | println(""); 1919 | 1920 | while (position < end) 1921 | { 1922 | indent(FALSE, context->serviceDepth, context->stackOfBits); 1923 | print(" %02ld: ", (unsigned long)index); 1924 | 1925 | if ( count < (length-1) ) 1926 | { 1927 | print("specifier: %08lx (vector: %02lx) sense: %08lx (", 1928 | (unsigned long)*position, 1929 | (unsigned long)((*position) & 0x000000FF), 1930 | (unsigned long)*(position+1) ); 1931 | position ++; 1932 | count ++; 1933 | if ( (*position & 0x00000002 ) ) // HyperTransport 1934 | { 1935 | print( "HyperTransport vector: %04lx, ", 1936 | (unsigned long)((*position >> 16) & 0x0000FFFF)); 1937 | } 1938 | 1939 | println( "%s)", (*position & 1)? "level" : "edge" ); 1940 | } 1941 | else 1942 | { 1943 | println("parent interrupt-map entry: %08lx", 1944 | (unsigned long)*position ); 1945 | } 1946 | 1947 | position ++; 1948 | count ++; 1949 | index ++; 1950 | } 1951 | } 1952 | 1953 | static void printInterruptParent( CFTypeRef value, struct context * context ) 1954 | { 1955 | io_registry_entry_t parentRegEntry; 1956 | io_string_t path; 1957 | UInt32 * pHandleValue = (UInt32 *) CFDataGetBytePtr( (CFDataRef) value ); 1958 | 1959 | if ( lookupPHandle( *pHandleValue, &parentRegEntry ) ) 1960 | { 1961 | *path = '\0'; 1962 | makepath( parentRegEntry, path ); 1963 | 1964 | print( "<%08lx>", (unsigned long)*pHandleValue ); 1965 | if ( *path != '\0' ) 1966 | print( " (%s)", path ); 1967 | println( "" ); 1968 | 1969 | IOObjectRelease( parentRegEntry ); 1970 | } 1971 | } 1972 | 1973 | static char ToAscii(UInt32 nibble) 1974 | { 1975 | nibble &= 0x0F; 1976 | 1977 | if (nibble <= 9) 1978 | return((char)nibble + '0'); 1979 | else 1980 | return((char)nibble - 10 + 'A'); 1981 | } 1982 | 1983 | static void printData(CFTypeRef value, struct context * context) 1984 | { 1985 | UInt32 asciiNormalCount = 0; 1986 | UInt32 asciiSymbolCount = 0; 1987 | const UInt8 * bytes; 1988 | CFIndex index; 1989 | CFIndex length; 1990 | 1991 | length = CFDataGetLength(value); 1992 | bytes = CFDataGetBytePtr(value); 1993 | 1994 | // 1995 | // This algorithm detects ascii strings, or a set of ascii strings, inside a 1996 | // stream of bytes. The string, or last string if in a set, needn't be null 1997 | // terminated. High-order symbol characters are accepted, unless they occur 1998 | // too often (80% of characters must be normal). Zero padding at the end of 1999 | // the string(s) is valid. If the data stream is only one byte, it is never 2000 | // considered to be a string. 2001 | // 2002 | 2003 | for (index = 0; index < length; index++) // (scan for ascii string/strings) 2004 | { 2005 | if (bytes[index] == 0) // (detected null in place of a new string, 2006 | { // ensure remainder of the string is null) 2007 | for (; index < length && bytes[index] == 0; index++) { } 2008 | 2009 | break; // (either end of data or a non-null byte in stream) 2010 | } 2011 | else // (scan along this potential ascii string) 2012 | { 2013 | for (; index < length; index++) 2014 | { 2015 | if (isprint(bytes[index])) 2016 | asciiNormalCount++; 2017 | else if (bytes[index] >= 128 && bytes[index] <= 254) 2018 | asciiSymbolCount++; 2019 | else 2020 | break; 2021 | } 2022 | 2023 | if (index < length && bytes[index] == 0) // (end of string) 2024 | continue; 2025 | else // (either end of data or an unprintable character) 2026 | break; 2027 | } 2028 | } 2029 | 2030 | if ((asciiNormalCount >> 2) < asciiSymbolCount) // (is 80% normal ascii?) 2031 | index = 0; 2032 | else if (length == 1) // (is just one byte?) 2033 | index = 0; 2034 | else if (cfshowhex) 2035 | index = 0; 2036 | 2037 | if (index >= length && asciiNormalCount) // (is a string or set of strings?) 2038 | { 2039 | Boolean quoted = FALSE; 2040 | 2041 | print("<"); 2042 | 2043 | for (index = 0; index < length; index++) 2044 | { 2045 | if (bytes[index]) 2046 | { 2047 | if (quoted == FALSE) 2048 | { 2049 | quoted = TRUE; 2050 | if (index) 2051 | print(",\""); 2052 | else 2053 | print("\""); 2054 | } 2055 | print("%c", bytes[index]); 2056 | } 2057 | else 2058 | { 2059 | if (quoted == TRUE) 2060 | { 2061 | quoted = FALSE; 2062 | print("\""); 2063 | } 2064 | else 2065 | break; 2066 | } 2067 | } 2068 | if (quoted == TRUE) 2069 | print("\""); 2070 | 2071 | print(">"); 2072 | } 2073 | 2074 | else if (length > 8) // (is not a string or set of strings) 2075 | { 2076 | SInt8 work[ 256 ]; 2077 | SInt8* p; 2078 | UInt32 i; 2079 | UInt32 offset; 2080 | CFIndex totalBytes; 2081 | CFIndex nBytesToDraw; 2082 | UInt32 bytesPerLine; 2083 | UInt8 c; 2084 | 2085 | totalBytes = length; // assume length is greater than zero 2086 | 2087 | // Calculate number of bytes per line to print, use as much screen 2088 | // as possible. The numbers used are derived by counting the number 2089 | // of characters that are always printed (data address offset, white 2090 | // space, etc ~= 20), indentation from the tree structure (2*depth) 2091 | // and 4 characters printed per byte (two hex digits, one space, and 2092 | // one ascii char). 2093 | 2094 | bytesPerLine = (context->options.width - 20 - (2*context->serviceDepth))/4; 2095 | 2096 | // Make sure we don't overflow the work buffer (256 bytes) 2097 | bytesPerLine = bytesPerLine > 32 ? 32 : bytesPerLine; 2098 | 2099 | for ( offset = 0; offset < totalBytes; offset += bytesPerLine ) 2100 | { 2101 | UInt32 offsetCopy; 2102 | UInt16 text; 2103 | 2104 | println(""); 2105 | 2106 | if ( ( offset + bytesPerLine ) <= totalBytes ) 2107 | nBytesToDraw = bytesPerLine; 2108 | else 2109 | nBytesToDraw = totalBytes - offset; 2110 | 2111 | offsetCopy = offset; 2112 | 2113 | // Convert offset to ASCII. 2114 | work[ 8 ] = ':'; 2115 | p = &work[ 7 ]; 2116 | 2117 | while ( offsetCopy != 0 ) 2118 | { 2119 | *p-- = ToAscii( offsetCopy & 0x0F ); 2120 | offsetCopy >>= 4; 2121 | } 2122 | 2123 | // Insert leading zeros. 2124 | while ( p >= work ) 2125 | *p-- = '0'; 2126 | 2127 | // Add kBytesPerLine bytes of data. 2128 | p = &work[ 9 ]; 2129 | for ( i = 0; i < nBytesToDraw; i++ ) 2130 | { 2131 | c = bytes[ offset + i ]; 2132 | *p++ = ' '; 2133 | *p++ = ToAscii( ( c & 0xF0 ) >> 4 ); 2134 | *p++ = ToAscii( c & 0x0F ); 2135 | } 2136 | 2137 | // Add padding spaces. 2138 | for ( ; i < bytesPerLine; i++ ) 2139 | { 2140 | text = ( ( ' ' << 8 ) | ' ' ); 2141 | *( UInt16 * ) p = text; 2142 | p[ 2 ] = ' '; 2143 | p += 3; 2144 | } 2145 | 2146 | *p++ = ' '; 2147 | 2148 | // Insert ASCII representation of data. 2149 | for ( i = 0; i < nBytesToDraw; i++ ) 2150 | { 2151 | c = bytes[ offset + i ]; 2152 | if ( ( c < ' ' ) || ( c > '~' ) ) 2153 | c = '.'; 2154 | 2155 | *p++ = c; 2156 | } 2157 | 2158 | *p = 0; 2159 | 2160 | // Print this line. 2161 | indent(FALSE, context->serviceDepth, context->stackOfBits); 2162 | print(" %s", work); 2163 | 2164 | } // for 2165 | 2166 | } // else if (length > 32) 2167 | else 2168 | { 2169 | print("<"); 2170 | for (index = 0; index < length; index++) print("%02x", bytes[index]); 2171 | print(">"); 2172 | } 2173 | 2174 | println(""); 2175 | } 2176 | --------------------------------------------------------------------------------