this repo has no description
1
fork

Configure Feed

Select the types of activity you want to include in your feed.

keymgr build

+1345 -1
+1
CMakeLists.txt
··· 19 19 add_subdirectory(libm) 20 20 add_subdirectory(libmalloc) 21 21 add_subdirectory(libsystem) 22 + add_subdirectory(keymgr) 22 23
+28
keymgr/CMakeLists.txt
··· 1 + project(keymgr) 2 + 3 + cmake_minimum_required(VERSION 2.4.0) 4 + 5 + set(CMAKE_C_FLAGS "${CMAKE_C_FLAGS} -nostdinc") 6 + set(CMAKE_SHARED_LINKER_FLAGS "${CMAKE_SHARED_LINKER_FLAGS} -nostdlib") 7 + 8 + include_directories(${CMAKE_SOURCE_DIR}/libc/fbsdcompat) 9 + include_directories(${CMAKE_SOURCE_DIR}/kernel/libsyscall/wrappers) 10 + 11 + if(CMAKE_SIZEOF_VOID_P EQUAL 4 OR CMAKE_INSTALL_LIBDIR STREQUAL "lib32") 12 + set(BITS 32) 13 + add_definitions(-DTARGET_CPU_X86=1) 14 + else(CMAKE_SIZEOF_VOID_P EQUAL 4 OR CMAKE_INSTALL_LIBDIR STREQUAL "lib32") 15 + set(BITS 64) 16 + add_definitions(-DTARGET_CPU_X86_64=1) 17 + endif(CMAKE_SIZEOF_VOID_P EQUAL 4 OR CMAKE_INSTALL_LIBDIR STREQUAL "lib32") 18 + 19 + add_definitions(-DTARGET_OS_MAC=1) 20 + add_definitions(-DHAVE_STDINT_H=1) 21 + add_definitions(-D__APPLE__ -D__DYNAMIC__) 22 + 23 + set(keymgr_sources 24 + keymgr.c 25 + ) 26 + 27 + add_library(keymgr SHARED ${keymgr_sources}) 28 +
+340
keymgr/COPYING
··· 1 + GNU GENERAL PUBLIC LICENSE 2 + Version 2, June 1991 3 + 4 + Copyright (C) 1989, 1991 Free Software Foundation, Inc. 5 + 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA 6 + Everyone is permitted to copy and distribute verbatim copies 7 + of this license document, but changing it is not allowed. 8 + 9 + Preamble 10 + 11 + The licenses for most software are designed to take away your 12 + freedom to share and change it. By contrast, the GNU General Public 13 + License is intended to guarantee your freedom to share and change free 14 + software--to make sure the software is free for all its users. This 15 + General Public License applies to most of the Free Software 16 + Foundation's software and to any other program whose authors commit to 17 + using it. (Some other Free Software Foundation software is covered by 18 + the GNU Library General Public License instead.) You can apply it to 19 + your programs, too. 20 + 21 + When we speak of free software, we are referring to freedom, not 22 + price. Our General Public Licenses are designed to make sure that you 23 + have the freedom to distribute copies of free software (and charge for 24 + this service if you wish), that you receive source code or can get it 25 + if you want it, that you can change the software or use pieces of it 26 + in new free programs; and that you know you can do these things. 27 + 28 + To protect your rights, we need to make restrictions that forbid 29 + anyone to deny you these rights or to ask you to surrender the rights. 30 + These restrictions translate to certain responsibilities for you if you 31 + distribute copies of the software, or if you modify it. 32 + 33 + For example, if you distribute copies of such a program, whether 34 + gratis or for a fee, you must give the recipients all the rights that 35 + you have. You must make sure that they, too, receive or can get the 36 + source code. And you must show them these terms so they know their 37 + rights. 38 + 39 + We protect your rights with two steps: (1) copyright the software, and 40 + (2) offer you this license which gives you legal permission to copy, 41 + distribute and/or modify the software. 42 + 43 + Also, for each author's protection and ours, we want to make certain 44 + that everyone understands that there is no warranty for this free 45 + software. If the software is modified by someone else and passed on, we 46 + want its recipients to know that what they have is not the original, so 47 + that any problems introduced by others will not reflect on the original 48 + authors' reputations. 49 + 50 + Finally, any free program is threatened constantly by software 51 + patents. We wish to avoid the danger that redistributors of a free 52 + program will individually obtain patent licenses, in effect making the 53 + program proprietary. To prevent this, we have made it clear that any 54 + patent must be licensed for everyone's free use or not licensed at all. 55 + 56 + The precise terms and conditions for copying, distribution and 57 + modification follow. 58 + 59 + GNU GENERAL PUBLIC LICENSE 60 + TERMS AND CONDITIONS FOR COPYING, DISTRIBUTION AND MODIFICATION 61 + 62 + 0. This License applies to any program or other work which contains 63 + a notice placed by the copyright holder saying it may be distributed 64 + under the terms of this General Public License. The "Program", below, 65 + refers to any such program or work, and a "work based on the Program" 66 + means either the Program or any derivative work under copyright law: 67 + that is to say, a work containing the Program or a portion of it, 68 + either verbatim or with modifications and/or translated into another 69 + language. (Hereinafter, translation is included without limitation in 70 + the term "modification".) Each licensee is addressed as "you". 71 + 72 + Activities other than copying, distribution and modification are not 73 + covered by this License; they are outside its scope. The act of 74 + running the Program is not restricted, and the output from the Program 75 + is covered only if its contents constitute a work based on the 76 + Program (independent of having been made by running the Program). 77 + Whether that is true depends on what the Program does. 78 + 79 + 1. You may copy and distribute verbatim copies of the Program's 80 + source code as you receive it, in any medium, provided that you 81 + conspicuously and appropriately publish on each copy an appropriate 82 + copyright notice and disclaimer of warranty; keep intact all the 83 + notices that refer to this License and to the absence of any warranty; 84 + and give any other recipients of the Program a copy of this License 85 + along with the Program. 86 + 87 + You may charge a fee for the physical act of transferring a copy, and 88 + you may at your option offer warranty protection in exchange for a fee. 89 + 90 + 2. You may modify your copy or copies of the Program or any portion 91 + of it, thus forming a work based on the Program, and copy and 92 + distribute such modifications or work under the terms of Section 1 93 + above, provided that you also meet all of these conditions: 94 + 95 + a) You must cause the modified files to carry prominent notices 96 + stating that you changed the files and the date of any change. 97 + 98 + b) You must cause any work that you distribute or publish, that in 99 + whole or in part contains or is derived from the Program or any 100 + part thereof, to be licensed as a whole at no charge to all third 101 + parties under the terms of this License. 102 + 103 + c) If the modified program normally reads commands interactively 104 + when run, you must cause it, when started running for such 105 + interactive use in the most ordinary way, to print or display an 106 + announcement including an appropriate copyright notice and a 107 + notice that there is no warranty (or else, saying that you provide 108 + a warranty) and that users may redistribute the program under 109 + these conditions, and telling the user how to view a copy of this 110 + License. (Exception: if the Program itself is interactive but 111 + does not normally print such an announcement, your work based on 112 + the Program is not required to print an announcement.) 113 + 114 + These requirements apply to the modified work as a whole. If 115 + identifiable sections of that work are not derived from the Program, 116 + and can be reasonably considered independent and separate works in 117 + themselves, then this License, and its terms, do not apply to those 118 + sections when you distribute them as separate works. But when you 119 + distribute the same sections as part of a whole which is a work based 120 + on the Program, the distribution of the whole must be on the terms of 121 + this License, whose permissions for other licensees extend to the 122 + entire whole, and thus to each and every part regardless of who wrote it. 123 + 124 + Thus, it is not the intent of this section to claim rights or contest 125 + your rights to work written entirely by you; rather, the intent is to 126 + exercise the right to control the distribution of derivative or 127 + collective works based on the Program. 128 + 129 + In addition, mere aggregation of another work not based on the Program 130 + with the Program (or with a work based on the Program) on a volume of 131 + a storage or distribution medium does not bring the other work under 132 + the scope of this License. 133 + 134 + 3. You may copy and distribute the Program (or a work based on it, 135 + under Section 2) in object code or executable form under the terms of 136 + Sections 1 and 2 above provided that you also do one of the following: 137 + 138 + a) Accompany it with the complete corresponding machine-readable 139 + source code, which must be distributed under the terms of Sections 140 + 1 and 2 above on a medium customarily used for software interchange; or, 141 + 142 + b) Accompany it with a written offer, valid for at least three 143 + years, to give any third party, for a charge no more than your 144 + cost of physically performing source distribution, a complete 145 + machine-readable copy of the corresponding source code, to be 146 + distributed under the terms of Sections 1 and 2 above on a medium 147 + customarily used for software interchange; or, 148 + 149 + c) Accompany it with the information you received as to the offer 150 + to distribute corresponding source code. (This alternative is 151 + allowed only for noncommercial distribution and only if you 152 + received the program in object code or executable form with such 153 + an offer, in accord with Subsection b above.) 154 + 155 + The source code for a work means the preferred form of the work for 156 + making modifications to it. For an executable work, complete source 157 + code means all the source code for all modules it contains, plus any 158 + associated interface definition files, plus the scripts used to 159 + control compilation and installation of the executable. However, as a 160 + special exception, the source code distributed need not include 161 + anything that is normally distributed (in either source or binary 162 + form) with the major components (compiler, kernel, and so on) of the 163 + operating system on which the executable runs, unless that component 164 + itself accompanies the executable. 165 + 166 + If distribution of executable or object code is made by offering 167 + access to copy from a designated place, then offering equivalent 168 + access to copy the source code from the same place counts as 169 + distribution of the source code, even though third parties are not 170 + compelled to copy the source along with the object code. 171 + 172 + 4. You may not copy, modify, sublicense, or distribute the Program 173 + except as expressly provided under this License. Any attempt 174 + otherwise to copy, modify, sublicense or distribute the Program is 175 + void, and will automatically terminate your rights under this License. 176 + However, parties who have received copies, or rights, from you under 177 + this License will not have their licenses terminated so long as such 178 + parties remain in full compliance. 179 + 180 + 5. You are not required to accept this License, since you have not 181 + signed it. However, nothing else grants you permission to modify or 182 + distribute the Program or its derivative works. These actions are 183 + prohibited by law if you do not accept this License. Therefore, by 184 + modifying or distributing the Program (or any work based on the 185 + Program), you indicate your acceptance of this License to do so, and 186 + all its terms and conditions for copying, distributing or modifying 187 + the Program or works based on it. 188 + 189 + 6. Each time you redistribute the Program (or any work based on the 190 + Program), the recipient automatically receives a license from the 191 + original licensor to copy, distribute or modify the Program subject to 192 + these terms and conditions. You may not impose any further 193 + restrictions on the recipients' exercise of the rights granted herein. 194 + You are not responsible for enforcing compliance by third parties to 195 + this License. 196 + 197 + 7. If, as a consequence of a court judgment or allegation of patent 198 + infringement or for any other reason (not limited to patent issues), 199 + conditions are imposed on you (whether by court order, agreement or 200 + otherwise) that contradict the conditions of this License, they do not 201 + excuse you from the conditions of this License. If you cannot 202 + distribute so as to satisfy simultaneously your obligations under this 203 + License and any other pertinent obligations, then as a consequence you 204 + may not distribute the Program at all. For example, if a patent 205 + license would not permit royalty-free redistribution of the Program by 206 + all those who receive copies directly or indirectly through you, then 207 + the only way you could satisfy both it and this License would be to 208 + refrain entirely from distribution of the Program. 209 + 210 + If any portion of this section is held invalid or unenforceable under 211 + any particular circumstance, the balance of the section is intended to 212 + apply and the section as a whole is intended to apply in other 213 + circumstances. 214 + 215 + It is not the purpose of this section to induce you to infringe any 216 + patents or other property right claims or to contest validity of any 217 + such claims; this section has the sole purpose of protecting the 218 + integrity of the free software distribution system, which is 219 + implemented by public license practices. Many people have made 220 + generous contributions to the wide range of software distributed 221 + through that system in reliance on consistent application of that 222 + system; it is up to the author/donor to decide if he or she is willing 223 + to distribute software through any other system and a licensee cannot 224 + impose that choice. 225 + 226 + This section is intended to make thoroughly clear what is believed to 227 + be a consequence of the rest of this License. 228 + 229 + 8. If the distribution and/or use of the Program is restricted in 230 + certain countries either by patents or by copyrighted interfaces, the 231 + original copyright holder who places the Program under this License 232 + may add an explicit geographical distribution limitation excluding 233 + those countries, so that distribution is permitted only in or among 234 + countries not thus excluded. In such case, this License incorporates 235 + the limitation as if written in the body of this License. 236 + 237 + 9. The Free Software Foundation may publish revised and/or new versions 238 + of the General Public License from time to time. Such new versions will 239 + be similar in spirit to the present version, but may differ in detail to 240 + address new problems or concerns. 241 + 242 + Each version is given a distinguishing version number. If the Program 243 + specifies a version number of this License which applies to it and "any 244 + later version", you have the option of following the terms and conditions 245 + either of that version or of any later version published by the Free 246 + Software Foundation. If the Program does not specify a version number of 247 + this License, you may choose any version ever published by the Free Software 248 + Foundation. 249 + 250 + 10. If you wish to incorporate parts of the Program into other free 251 + programs whose distribution conditions are different, write to the author 252 + to ask for permission. For software which is copyrighted by the Free 253 + Software Foundation, write to the Free Software Foundation; we sometimes 254 + make exceptions for this. Our decision will be guided by the two goals 255 + of preserving the free status of all derivatives of our free software and 256 + of promoting the sharing and reuse of software generally. 257 + 258 + NO WARRANTY 259 + 260 + 11. BECAUSE THE PROGRAM IS LICENSED FREE OF CHARGE, THERE IS NO WARRANTY 261 + FOR THE PROGRAM, TO THE EXTENT PERMITTED BY APPLICABLE LAW. EXCEPT WHEN 262 + OTHERWISE STATED IN WRITING THE COPYRIGHT HOLDERS AND/OR OTHER PARTIES 263 + PROVIDE THE PROGRAM "AS IS" WITHOUT WARRANTY OF ANY KIND, EITHER EXPRESSED 264 + OR IMPLIED, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF 265 + MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE. THE ENTIRE RISK AS 266 + TO THE QUALITY AND PERFORMANCE OF THE PROGRAM IS WITH YOU. SHOULD THE 267 + PROGRAM PROVE DEFECTIVE, YOU ASSUME THE COST OF ALL NECESSARY SERVICING, 268 + REPAIR OR CORRECTION. 269 + 270 + 12. IN NO EVENT UNLESS REQUIRED BY APPLICABLE LAW OR AGREED TO IN WRITING 271 + WILL ANY COPYRIGHT HOLDER, OR ANY OTHER PARTY WHO MAY MODIFY AND/OR 272 + REDISTRIBUTE THE PROGRAM AS PERMITTED ABOVE, BE LIABLE TO YOU FOR DAMAGES, 273 + INCLUDING ANY GENERAL, SPECIAL, INCIDENTAL OR CONSEQUENTIAL DAMAGES ARISING 274 + OUT OF THE USE OR INABILITY TO USE THE PROGRAM (INCLUDING BUT NOT LIMITED 275 + TO LOSS OF DATA OR DATA BEING RENDERED INACCURATE OR LOSSES SUSTAINED BY 276 + YOU OR THIRD PARTIES OR A FAILURE OF THE PROGRAM TO OPERATE WITH ANY OTHER 277 + PROGRAMS), EVEN IF SUCH HOLDER OR OTHER PARTY HAS BEEN ADVISED OF THE 278 + POSSIBILITY OF SUCH DAMAGES. 279 + 280 + END OF TERMS AND CONDITIONS 281 + 282 + How to Apply These Terms to Your New Programs 283 + 284 + If you develop a new program, and you want it to be of the greatest 285 + possible use to the public, the best way to achieve this is to make it 286 + free software which everyone can redistribute and change under these terms. 287 + 288 + To do so, attach the following notices to the program. It is safest 289 + to attach them to the start of each source file to most effectively 290 + convey the exclusion of warranty; and each file should have at least 291 + the "copyright" line and a pointer to where the full notice is found. 292 + 293 + <one line to give the program's name and a brief idea of what it does.> 294 + Copyright (C) <year> <name of author> 295 + 296 + This program is free software; you can redistribute it and/or modify 297 + it under the terms of the GNU General Public License as published by 298 + the Free Software Foundation; either version 2 of the License, or 299 + (at your option) any later version. 300 + 301 + This program is distributed in the hope that it will be useful, 302 + but WITHOUT ANY WARRANTY; without even the implied warranty of 303 + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 304 + GNU General Public License for more details. 305 + 306 + You should have received a copy of the GNU General Public License 307 + along with this program; if not, write to the Free Software 308 + Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA 309 + 310 + 311 + Also add information on how to contact you by electronic and paper mail. 312 + 313 + If the program is interactive, make it output a short notice like this 314 + when it starts in an interactive mode: 315 + 316 + Gnomovision version 69, Copyright (C) year name of author 317 + Gnomovision comes with ABSOLUTELY NO WARRANTY; for details type `show w'. 318 + This is free software, and you are welcome to redistribute it 319 + under certain conditions; type `show c' for details. 320 + 321 + The hypothetical commands `show w' and `show c' should show the appropriate 322 + parts of the General Public License. Of course, the commands you use may 323 + be called something other than `show w' and `show c'; they could even be 324 + mouse-clicks or menu items--whatever suits your program. 325 + 326 + You should also get your employer (if you work as a programmer) or your 327 + school, if any, to sign a "copyright disclaimer" for the program, if 328 + necessary. Here is a sample; alter the names: 329 + 330 + Yoyodyne, Inc., hereby disclaims all copyright interest in the program 331 + `Gnomovision' (which makes passes at compilers) written by James Hacker. 332 + 333 + <signature of Ty Coon>, 1 April 1989 334 + Ty Coon, President of Vice 335 + 336 + This General Public License does not permit incorporating your program into 337 + proprietary programs. If your program is a subroutine library, you may 338 + consider it more useful to permit linking proprietary applications with the 339 + library. If this is what you want to do, use the GNU Library General 340 + Public License instead of this License.
+850
keymgr/keymgr.c
··· 1 + /* Copyright (C) 1999-2005, 2012 Apple Inc. 2 + Copyright (C) 1997, 2001 Free Software Foundation, Inc. 3 + 4 + This file is part of KeyMgr. 5 + 6 + KeyMgr is free software; you can redistribute it and/or modify it under 7 + the terms of the GNU General Public License as published by the Free 8 + Software Foundation; either version 2, or (at your option) any later 9 + version. 10 + 11 + In addition to the permissions in the GNU General Public License, 12 + Apple Computer and the Free Software Foundation gives you unlimited 13 + permission to link the compiled version of this file into combinations 14 + with other programs, and to distribute those combinations without any 15 + restriction coming from the use of this file. (The General Public 16 + License restrictions do apply in other respects; for example, they 17 + cover modification of the file, and distribution when not linked into 18 + a combine executable.) 19 + 20 + KeyMgr is distributed in the hope that it will be useful, but WITHOUT ANY 21 + WARRANTY; without even the implied warranty of MERCHANTABILITY or 22 + FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License 23 + for more details. 24 + 25 + You should have received a copy of the GNU General Public License 26 + along with KeyMgr; see the file COPYING. If not, write to the Free 27 + Software Foundation, 59 Temple Place - Suite 330, Boston, MA 28 + 02111-1307, USA. */ 29 + 30 + /* The FSF-copyright part is the definition of 'struct 31 + old_object'. It was taken from unwind-dw2-fde.h from GCC 3.1. */ 32 + 33 + /* 34 + * keymgr - Create and maintain process-wide global data known to 35 + * all threads across all dynamic libraries. 36 + * 37 + */ 38 + 39 + #include <mach-o/dyld.h> 40 + #include <dlfcn.h> 41 + #include <pthread.h> 42 + #include <errno.h> 43 + #include <stdlib.h> 44 + #include <libkern/OSAtomic.h> 45 + #include <stdint.h> 46 + 47 + #if __has_include(<os/alloc_once_private.h>) 48 + #include <os/alloc_once_private.h> 49 + #if defined(OS_ALLOC_ONCE_KEY_LIBKEYMGR) 50 + #define _HAS_ALLOC_ONCE 1 51 + #endif 52 + #endif 53 + 54 + #include "keymgr.h" 55 + 56 + /* On x86 or later platforms, there's no need to support the TLS SPIs. 57 + The only reason to support them on ppc64 is because the tools 58 + shipped with Tiger included a libsupc++.a which used these 59 + functions. (To do: investigate whether anyone ever actually used 60 + that library for ppc64.) */ 61 + #if defined(__ppc__) || defined(__ppc64__) 62 + #define WANT_TLS_SPIS 1 63 + #endif 64 + 65 + /* On Mac OS X 10.6, unwinding is down by libunwind in libSystem.B.dylib 66 + Normally, the object list is not used, but some applications that dynamically 67 + generate code directly use keymgr to find the KEYMGR_GCC3_DW2_OBJ_LIST 68 + list and insert frame information. The problem is those apps don't check 69 + if KEYMGR_GCC3_DW2_OBJ_LIST is currently NULL. The fix is to statically 70 + allocate the object list head struct and set KEYMGR_GCC3_DW2_OBJ_LIST to 71 + point to it <rdar://problem/6599778>. */ 72 + #if defined(__i386__) 73 + #define PR_6599778 1 74 + #endif 75 + 76 + #ifndef ESUCCESS 77 + #define ESUCCESS 0 78 + #endif 79 + 80 + /* Types of node, used for error checking. */ 81 + typedef enum node_kinds { 82 + NODE_PROCESSWIDE_PTR=1, 83 + #ifdef WANT_TLS_SPIS 84 + NODE_THREAD_SPECIFIC_DATA 85 + #endif 86 + } TnodeKind; 87 + 88 + /* These values are internal; the subflags of NM_ENHANCED_LOCKING are 89 + defined in keymgr.h and are not internal. */ 90 + enum { 91 + NM_ENHANCED_LOCKING=3 92 + }; 93 + 94 + /* Base node kind for keymgr node list; also used to represent per 95 + thread variables (NODE_THREAD_SPECIFIC_DATA). */ 96 + 97 + typedef struct Skey_data { 98 + struct Skey_data * next; 99 + unsigned int handle; /* Key id of variable. */ 100 + unsigned char node_kind; /* What kind of variable is this? */ 101 + unsigned char flags; /* Flags controlling behavior of variable. */ 102 + unsigned short refcount; /* If recursion has been enabled, reference 103 + count. */ 104 + void *ptr; /* Data associated with variable. */ 105 + pthread_mutex_t thread_lock; /* Semaphore for this specific variable. */ 106 + } Tkey_Data; 107 + 108 + typedef struct Sinfo_Node { 109 + unsigned int size; /* Size of this node. */ 110 + unsigned short major_version; /* API major version. */ 111 + unsigned short minor_version; /* API minor version. */ 112 + } Tinfo_Node; 113 + 114 + /* Static variables for initial __keymgr_global values. */ 115 + 116 + static const Tinfo_Node keymgr_info = { 117 + sizeof (Tinfo_Node), 118 + KEYMGR_API_REV_MAJOR, 119 + KEYMGR_API_REV_MINOR 120 + }; 121 + 122 + /* __keymgr_global - contains pointers to keymgr data that needs to be 123 + global and known across all dlls/plugins. */ 124 + struct { 125 + /* Formerly, a pthreads semaphore for accessing the keymgr global data. 126 + Now unused. */ 127 + void *unused; 128 + 129 + /* Formerly the keymgr_globals pointer. Moved to os_alloc_once allocation. */ 130 + void *unused2; 131 + 132 + /* Pointer to keymgr information node. This is part of the semi-public 133 + ABI of keymgr. */ 134 + const Tinfo_Node *keymgr_info; 135 + } const __attribute__((aligned (32))) __keymgr_global = { 136 + NULL, 137 + NULL, 138 + &keymgr_info 139 + }; 140 + 141 + struct keymgr_globals_s { 142 + /* Pointer to keymgr global list. This pointer was previously contained 143 + in the second word of __keymgr_global static data. Moved here to avoid 144 + diryting a __DATA page in each process. 145 + Prior to that, contained in __eh_global_dataptr. */ 146 + Tkey_Data * volatile keymgr_globals; 147 + 148 + #ifdef PR_6599778 149 + /* Used to statically allocate the head of the object list. 150 + The struct is 4 pointers long and must be initially zero filled. */ 151 + void *km_object_list_head[4]; 152 + #endif 153 + }; 154 + typedef struct keymgr_globals_s *keymgr_globals_t; 155 + 156 + __attribute__((__pure__)) 157 + static inline keymgr_globals_t 158 + _keymgr_globals(void) { 159 + #if _HAS_ALLOC_ONCE 160 + return (keymgr_globals_t)os_alloc_once(OS_ALLOC_ONCE_KEY_LIBKEYMGR, 161 + sizeof(struct keymgr_globals_s), NULL); 162 + #else 163 + static struct keymgr_globals_s storage; 164 + return &storage; 165 + #endif 166 + } 167 + 168 + #if defined(__ppc__) 169 + /* Initialize keymgr. */ 170 + 171 + void _init_keymgr (void) 172 + { 173 + /* This routine is now empty, but is part of keymgr's ABI on ppc and 174 + so can't be completely removed. */ 175 + } 176 + #endif 177 + 178 + /* Find any Tkey_Data associated with KEY. If none exists, or KIND 179 + does not match, return NULL. */ 180 + 181 + static Tkey_Data * 182 + get_key_element (unsigned int key, TnodeKind kind) 183 + { 184 + Tkey_Data *keyArray; 185 + 186 + for (keyArray = _keymgr_globals()->keymgr_globals; 187 + keyArray != NULL; 188 + keyArray = keyArray->next) 189 + if (keyArray->handle == key) 190 + { 191 + if (keyArray->node_kind == kind) 192 + return keyArray; 193 + else 194 + return NULL; 195 + } 196 + 197 + return NULL; 198 + } 199 + 200 + /* Find any Tkey_Data associated with KEY. If none exists, create one 201 + and add it to the list. Put it in *RESULT. 202 + 203 + On success, return 0, otherwise: 204 + [EINVAL] The node existed but was not of type KIND. 205 + [ENOMEM] Out of memory, couldn't create node. 206 + [EAGAIN] The mutex associated with the new node couldn't be created. 207 + This can only happen when KIND == NODE_PROCESSWIDE_PTR. 208 + 209 + The aims of this routine are: 210 + 211 + - After execution, there should be exactly one element in the list 212 + with HANDLE set to KEY. 213 + - The pointer to that element should be returned in *RESULT. 214 + 215 + In addition, we know that: 216 + 217 + - The list only has elements added, never removed, and they are 218 + always added to the head of the list. 219 + */ 220 + 221 + static int 222 + get_or_create_key_element (unsigned int key, TnodeKind kind, 223 + Tkey_Data **result) 224 + { 225 + Tkey_Data *searchEnd = NULL; 226 + Tkey_Data *newEntry = NULL; 227 + 228 + for (;;) 229 + { 230 + Tkey_Data *keyArrayStart = _keymgr_globals()->keymgr_globals; 231 + Tkey_Data *keyArray; 232 + 233 + /* At this point, we know that we have not searched the elements 234 + between keyArrayStart and searchEnd, but we have previously searched 235 + searchEnd (if not NULL) and all the elements after it. */ 236 + 237 + for (keyArray = keyArrayStart; 238 + keyArray != searchEnd; 239 + keyArray = keyArray->next) 240 + if (keyArray->handle == key) 241 + { 242 + /* Found an existing entry for KEY. Free any new entry we 243 + created in a previous pass through the loop. */ 244 + if (newEntry) 245 + { 246 + if (kind == NODE_PROCESSWIDE_PTR) 247 + /* This call should never fail. */ 248 + if (pthread_mutex_destroy (&newEntry->thread_lock) 249 + != ESUCCESS) 250 + abort (); 251 + free (newEntry); 252 + } 253 + 254 + if (keyArray->node_kind != kind) 255 + return EINVAL; 256 + *result = keyArray; 257 + return ESUCCESS; 258 + } 259 + 260 + /* At this point, we know that there is no entry after keyArrayStart 261 + which matches KEY. We will try to add one. */ 262 + 263 + if (! newEntry) 264 + { 265 + /* Create the new entry. */ 266 + newEntry = (Tkey_Data *) malloc (sizeof (Tkey_Data)); 267 + if (newEntry == NULL) 268 + return ENOMEM; 269 + 270 + if (kind == NODE_PROCESSWIDE_PTR) 271 + { 272 + pthread_mutexattr_t attr; 273 + int errnum; 274 + 275 + newEntry->refcount = 0; 276 + newEntry->flags = 0; 277 + 278 + errnum = pthread_mutexattr_init (&attr); 279 + if (errnum == ESUCCESS) 280 + { 281 + pthread_mutexattr_settype (&attr, PTHREAD_MUTEX_ERRORCHECK); 282 + errnum = pthread_mutex_init (&newEntry->thread_lock, &attr); 283 + pthread_mutexattr_destroy (&attr); 284 + } 285 + if (errnum != ESUCCESS) 286 + { 287 + free (newEntry); 288 + return errnum; 289 + } 290 + } 291 + 292 + newEntry->handle = key; 293 + newEntry->ptr = NULL; 294 + newEntry->node_kind = kind; 295 + } 296 + 297 + /* The compare-and-swap will succeed only if the list head is 298 + keyArrayStart, and we are prepending newEntry onto the list, 299 + so the next element after newEntry should be keyArrayStart. */ 300 + 301 + newEntry->next = keyArrayStart; 302 + 303 + /* The barrier is necessary to ensure that newEntry->next is seen 304 + to be set by any thread that sees newEntry in the list. */ 305 + 306 + /* If the compare-and-swap succeeds, it means that the head of 307 + the list did not change between the search above and the 308 + store of newEntry. Therefore, since we searched all the 309 + elements from the head at that time, we can be sure that the 310 + entry we're adding is not in the list. */ 311 + #ifdef __LP64__ 312 + if (OSAtomicCompareAndSwap64Barrier ( 313 + (int64_t) keyArrayStart, 314 + (int64_t) newEntry, 315 + (int64_t *) &_keymgr_globals()->keymgr_globals)) 316 + #else 317 + if (OSAtomicCompareAndSwap32Barrier ( 318 + (int32_t) keyArrayStart, 319 + (int32_t) newEntry, 320 + (int32_t *) &_keymgr_globals()->keymgr_globals)) 321 + #endif 322 + { 323 + *result = newEntry; 324 + return ESUCCESS; 325 + } 326 + /* Another thread changed the list. The entries between 327 + keyArrayStart and searchEnd were searched above, so now we 328 + can stop searching at keyArrayStart. We know we will make 329 + progress in the next loop iteration because the new searchEnd 330 + will not be equal to __keymgr_global.keymgr_globals and so we 331 + will search at least one new element. Since the list can 332 + have at most one element for each valid key, eventually there 333 + will be no more elements to search and so we will stop reaching 334 + this point and looping. */ 335 + searchEnd = keyArrayStart; 336 + } 337 + } 338 + 339 + #ifdef WANT_TLS_SPIS 340 + /* Return the data associated with KEY for the current thread. 341 + Return NULL if there is no such data. */ 342 + 343 + void * 344 + _keymgr_get_per_thread_data (unsigned int key) 345 + { 346 + Tkey_Data * keyArray; 347 + void * key_data; 348 + 349 + keyArray = get_key_element (key, NODE_THREAD_SPECIFIC_DATA); 350 + 351 + /* If the element hasn't been set, the answer is always NULL. */ 352 + if (keyArray == NULL) 353 + return NULL; 354 + 355 + /* On all platforms we run on, a pointer-sized load from an aligned 356 + address is atomic. */ 357 + key_data = keyArray->ptr; 358 + 359 + /* key_data might be NULL if this entry is in the process of being 360 + created. In that case, return NULL. */ 361 + if (key_data == NULL) 362 + return NULL; 363 + 364 + return pthread_getspecific ((pthread_key_t) key_data); 365 + } 366 + 367 + /* Set the data for KEY for this thread to be KEYDATA. Return 0 on success, 368 + or: 369 + 370 + [ENOMEM] Out of memory. 371 + [EINVAL] The KEY was previously used to store process-wide data. 372 + [EAGAIN] The system lacked the necessary resources to create 373 + another thread-specific data key, or the system- imposed 374 + limit on the total number of keys per process 375 + [PTHREAD_KEYS_MAX] would be exceeded. This error can't 376 + happen after the first successful call to 377 + _keymgr_set_per_thread_data from a particular thread with 378 + a particular KEY. 379 + */ 380 + 381 + int 382 + _keymgr_set_per_thread_data (unsigned int key, void *keydata) 383 + { 384 + volatile Tkey_Data * keyArray; 385 + pthread_key_t pthread_key; 386 + void *ptr; 387 + int errnum; 388 + 389 + errnum = get_or_create_key_element (key, NODE_THREAD_SPECIFIC_DATA, 390 + (Tkey_Data **)&keyArray); 391 + if (errnum != ESUCCESS) 392 + return errnum; 393 + 394 + /* This routine doesn't lock *keyArray. Instead, it relies on the 395 + fact that keyArray->ptr is either NULL or a valid pthread key value, 396 + and it only changes once, from NULL to a valid value. */ 397 + 398 + ptr = keyArray->ptr; 399 + if (ptr == NULL) 400 + { 401 + void (*destructor)(void *); 402 + bool neededInit; 403 + 404 + switch (key) 405 + { 406 + case KEYMGR_EH_CONTEXT_KEY: 407 + case KEYMGR_EH_GLOBALS_KEY: 408 + destructor = free; 409 + break; 410 + default: 411 + destructor = NULL; 412 + break; 413 + } 414 + if ((errnum = pthread_key_create (&pthread_key, destructor)) != 0) 415 + return errnum; 416 + 417 + #ifdef __LP64__ 418 + neededInit = OSAtomicCompareAndSwap64 ((int64_t) NULL, 419 + (int64_t) pthread_key, 420 + (int64_t *) &keyArray->ptr); 421 + #else 422 + neededInit = OSAtomicCompareAndSwap32 ((int32_t) NULL, 423 + (int32_t) pthread_key, 424 + (int32_t *) &keyArray->ptr); 425 + #endif 426 + if (!neededInit) 427 + pthread_key_delete (pthread_key); 428 + ptr = keyArray->ptr; 429 + } 430 + pthread_key = (pthread_key_t) ptr; 431 + 432 + return pthread_setspecific (pthread_key, keydata); 433 + } 434 + #endif /* WANT_TLS_SPIS */ 435 + 436 + 437 + /* 438 + * These routines provide management of a process wide, thread safe, 439 + * persistent pointer. If a pointer is created by a bundle/plug-in 440 + * and placed in here, it will persist for the life of the process, 441 + * even after the bundle has been unloaded. This is especially useful 442 + * for data shared across plugins and across repeated plugin loads and 443 + * unloads. 444 + */ 445 + 446 + /* Get the processwide data associated with KEY into *RESULT, 447 + and lock a lock associated with KEY. 448 + 449 + On success, return 0, otherwise: 450 + 451 + [EINVAL] KEY was previously used to store thread-specific data. 452 + [ENOMEM] Out of memory, couldn't create node. 453 + [EAGAIN] The mutex associated with the new node couldn't be created. 454 + [EDEADLK] A deadlock would occur if the thread blocked waiting 455 + for the lock. 456 + */ 457 + 458 + int 459 + _keymgr_get_and_lock_processwide_ptr_2 (unsigned int key, void ** result) 460 + { 461 + Tkey_Data *keyArray; 462 + int errnum; 463 + 464 + errnum = get_or_create_key_element (key, NODE_PROCESSWIDE_PTR, &keyArray); 465 + if (errnum != ESUCCESS) 466 + return errnum; 467 + 468 + if ((errnum = pthread_mutex_lock (&keyArray->thread_lock)) != ESUCCESS) 469 + return errnum; 470 + 471 + keyArray->refcount++; 472 + *result = keyArray->ptr; 473 + return ESUCCESS; 474 + } 475 + 476 + /* For backwards compatibility; like _keymgr_get_and_lock_processwide_ptr_2 477 + but returns the pointer or NULL on error. */ 478 + 479 + void * 480 + _keymgr_get_and_lock_processwide_ptr (unsigned int key) 481 + { 482 + void *result = NULL; 483 + _keymgr_get_and_lock_processwide_ptr_2 (key, &result); 484 + return result; 485 + } 486 + 487 + /* Unlock the lock associated with NODE. Return 0 on success. 488 + Returns EPERM if the lock is not locked by the current thread. */ 489 + 490 + static int 491 + unlock_node (Tkey_Data *node) 492 + { 493 + int result; 494 + 495 + node->refcount--; 496 + result = pthread_mutex_unlock (&node->thread_lock); 497 + if (result != ESUCCESS) 498 + node->refcount++; 499 + return result; 500 + } 501 + 502 + /* Set the processwide data associated with KEY to PTR, and unlock 503 + the lock associated with KEY. 504 + 505 + On success, returns 0. On failure, returns: 506 + 507 + [EINVAL] KEY was previously used to store thread-specific data. 508 + [ENOMEM] Out of memory, couldn't create node. 509 + [EAGAIN] The mutex associated with the new node couldn't be created. 510 + [EPERM] The lock was not locked by the current thread. 511 + */ 512 + 513 + int 514 + _keymgr_set_and_unlock_processwide_ptr (unsigned int key, void *ptr) 515 + { 516 + Tkey_Data *keyArray; 517 + int result; 518 + 519 + result = get_or_create_key_element (key, NODE_PROCESSWIDE_PTR, &keyArray); 520 + if (result != ESUCCESS) 521 + return result; 522 + 523 + keyArray->ptr = ptr; 524 + return unlock_node (keyArray); 525 + } 526 + 527 + /* Unlock the lock associated with KEY. 528 + 529 + On success, returns 0. On failure, returns: 530 + 531 + [EINVAL] KEY was not previously used to store process-specific data. 532 + [EPERM] The lock was not locked by the current thread. 533 + */ 534 + 535 + int 536 + _keymgr_unlock_processwide_ptr (unsigned int key) 537 + { 538 + Tkey_Data *keyArray; 539 + 540 + keyArray = get_key_element (key, NODE_PROCESSWIDE_PTR); 541 + if (keyArray == NULL) 542 + return EINVAL; 543 + 544 + return unlock_node (keyArray); 545 + } 546 + 547 + /* Set the locking mode of KEY to MODE. This should not be done while 548 + KEY is locked or another thread might be using KEY. 549 + 550 + On success, returns 0. On failure, returns: 551 + [EINVAL] KEY was previously used to store thread-specific data. 552 + [ENOMEM] Out of memory. 553 + [EBUSY] The mutex associated with the node was locked. 554 + */ 555 + 556 + int 557 + _keymgr_set_lockmode_processwide_ptr (unsigned int key, unsigned int mode) 558 + { 559 + Tkey_Data *keyArray; 560 + pthread_mutexattr_t attr; 561 + int type; 562 + int result; 563 + 564 + result = get_or_create_key_element (key, NODE_PROCESSWIDE_PTR, &keyArray); 565 + if (result != ESUCCESS) 566 + return result; 567 + 568 + if (mode == keyArray->flags) 569 + return ESUCCESS; 570 + 571 + result = pthread_mutexattr_init (&attr); 572 + if (result != ESUCCESS) 573 + return result; 574 + 575 + if (mode == NM_ALLOW_RECURSION) 576 + type = PTHREAD_MUTEX_RECURSIVE; 577 + else 578 + type = PTHREAD_MUTEX_ERRORCHECK; 579 + pthread_mutexattr_settype (&attr, type); 580 + 581 + /* Delete the old mutex and create a new one. */ 582 + result = pthread_mutex_destroy (&keyArray->thread_lock); 583 + /* Apple's implementation of pthread_mutex_init can't fail in this 584 + situation. */ 585 + if (result == ESUCCESS) 586 + result = pthread_mutex_init (&keyArray->thread_lock, &attr); 587 + 588 + pthread_mutexattr_destroy (&attr); 589 + 590 + if (result == ESUCCESS) 591 + keyArray->flags = mode; 592 + return result; 593 + } 594 + 595 + /* Returns the locking mode of the lock associated with KEY, if any, 596 + or 0 if there is no such lock. */ 597 + 598 + unsigned int 599 + _keymgr_get_lockmode_processwide_ptr (unsigned int key) 600 + { 601 + Tkey_Data *keyArray; 602 + 603 + keyArray = get_key_element (key, NODE_PROCESSWIDE_PTR); 604 + if (keyArray == NULL) 605 + return 0; 606 + return keyArray->flags; 607 + } 608 + 609 + /* Return the number of locks on KEY. To call this routine safely, 610 + you should be holding one of them, thus 0 is an error return. */ 611 + 612 + int 613 + _keymgr_get_lock_count_processwide_ptr (unsigned int key) 614 + { 615 + Tkey_Data *keyArray; 616 + 617 + keyArray = get_key_element (key, NODE_PROCESSWIDE_PTR); 618 + if (keyArray == NULL) 619 + return 0; 620 + return keyArray->refcount; 621 + } 622 + 623 + /*********************************************/ 624 + 625 + #include <mach-o/getsect.h> 626 + 627 + /* Beware, this is an API. */ 628 + 629 + struct __live_images { 630 + unsigned long this_size; /* sizeof (__live_images) */ 631 + const struct mach_header *mh; /* the image info */ 632 + intptr_t vm_slide; 633 + void (*destructor)(struct __live_images *); /* destructor for this */ 634 + struct __live_images *next; 635 + unsigned long examined_p; 636 + void *fde; 637 + void *object_info; 638 + unsigned long info[2]; /* GCC3 use */ 639 + }; 640 + 641 + /* Bits in the examined_p field of struct live_images. */ 642 + enum { 643 + EXAMINED_IMAGE_MASK = 1, /* We've seen this one. */ 644 + ALLOCED_IMAGE_MASK = 2, /* The FDE entries were allocated by 645 + malloc, and must be freed. This isn't 646 + used by newer libgcc versions. */ 647 + IMAGE_IS_TEXT_MASK = 4, /* This image is in the TEXT segment. */ 648 + DESTRUCTOR_MAY_BE_CALLED_LIVE = 8 /* The destructor may be called on an 649 + object that's part of the live 650 + image list. */ 651 + }; 652 + 653 + #ifdef __ppc__ 654 + struct old_object 655 + { 656 + void *pc_begin; 657 + void *pc_end; 658 + struct dwarf_fde *fde_begin; 659 + struct dwarf_fde **fde_array; 660 + size_t count; 661 + struct old_object *next; 662 + long section_size; 663 + }; 664 + 665 + static const char __DWARF2_UNWIND_SECTION_TYPE[] = "__TEXT"; 666 + static const char __DWARF2_UNWIND_SECTION_NAME[] = "__dwarf2_unwind"; 667 + #endif 668 + 669 + #if !__x86_64__ 670 + /* Called by dyld when an image is added to the executable. 671 + If it has a dwarf2_unwind section, register it so the C++ runtime 672 + can get at it. All of this is protected by dyld thread locks. */ 673 + 674 + static void dwarf2_unwind_dyld_add_image_hook (const struct mach_header *mh, 675 + intptr_t vm_slide) 676 + { 677 + #ifdef __ppc__ 678 + uint32_t sz; 679 + char *fde; 680 + 681 + /* See if the image has a __TEXT __dwarf2_unwind section. This 682 + is for backwards compatibility with old GCCs. */ 683 + 684 + fde = getsectdatafromheader (mh, __DWARF2_UNWIND_SECTION_TYPE, 685 + __DWARF2_UNWIND_SECTION_NAME, &sz); 686 + 687 + if (fde != 0) 688 + { 689 + struct old_object *obp; 690 + 691 + obp = (struct old_object *) calloc (1, sizeof (struct old_object) + 8); 692 + if (obp == NULL) 693 + return; 694 + 695 + obp->section_size = sz; 696 + obp->fde_begin = (struct dwarf_fde *) (fde + vm_slide); 697 + 698 + if (_keymgr_get_and_lock_processwide_ptr_2 (KEYMGR_ZOE_IMAGE_LIST, 699 + (void **) &obp->next) == 0) 700 + _keymgr_set_and_unlock_processwide_ptr (KEYMGR_ZOE_IMAGE_LIST, obp); 701 + } 702 + #endif 703 + 704 + { 705 + struct __live_images *l = (struct __live_images *) calloc (1, sizeof (*l)); 706 + if (l == NULL) 707 + return; 708 + 709 + l->mh = mh; 710 + l->vm_slide = vm_slide; 711 + l->this_size = sizeof (*l); 712 + if (_keymgr_get_and_lock_processwide_ptr_2 (KEYMGR_GCC3_LIVE_IMAGE_LIST, 713 + (void **) &l->next) == 0) 714 + _keymgr_set_and_unlock_processwide_ptr (KEYMGR_GCC3_LIVE_IMAGE_LIST, l); 715 + } 716 + } 717 + 718 + 719 + 720 + static void 721 + dwarf2_unwind_dyld_remove_image_hook (const struct mach_header *mh, 722 + intptr_t vm_slide) 723 + { 724 + #ifdef __ppc__ 725 + uint32_t sz; 726 + char *fde; 727 + 728 + /* See if the image has a __TEXT __dwarf2_unwind section. */ 729 + 730 + fde = getsectdatafromheader (mh, __DWARF2_UNWIND_SECTION_TYPE, 731 + __DWARF2_UNWIND_SECTION_NAME, &sz); 732 + if (fde != 0) 733 + { 734 + struct old_object *objlist, **obp; 735 + 736 + if (_keymgr_get_and_lock_processwide_ptr_2 (KEYMGR_ZOE_IMAGE_LIST, 737 + (void **) &objlist) != 0) 738 + goto get_zoe_failed; 739 + 740 + for (obp = &objlist; *obp; obp = &(*obp)->next) 741 + if ((char *)(*obp)->fde_begin == fde + vm_slide) 742 + { 743 + struct old_object *p = *obp; 744 + *obp = p->next; 745 + if (p->pc_begin) 746 + free (p->fde_array); 747 + free (p); 748 + break; 749 + } 750 + 751 + _keymgr_set_and_unlock_processwide_ptr (KEYMGR_ZOE_IMAGE_LIST, objlist); 752 + get_zoe_failed: 753 + ; 754 + } 755 + #endif 756 + 757 + { 758 + struct __live_images *top, **lip, *destroy = NULL; 759 + 760 + /* This is a bit of cache. _dyld_get_image_header_containing_address 761 + can be expensive, but most of the time the destructors come from 762 + one or two objects and are consecutive in the list. */ 763 + void (*prev_destructor)(struct __live_images *) = NULL; 764 + int was_in_object = 0; 765 + 766 + /* Look for it in the list of live images and delete it. 767 + Also, call any destructors in case they are in this image and about 768 + to be unloaded. The test with DESTRUCTOR_MAY_BE_CALLED_LIVE is 769 + because in GCC 3.1, the destructor would (uselessly) try to acquire 770 + the LIVE_IMAGE_LIST lock, and it's not practical to call it in 771 + that case (deadlock ensues, unless we release the lock, in which 772 + case the concurrency issues become impossible). */ 773 + 774 + if (_keymgr_get_and_lock_processwide_ptr_2 (KEYMGR_GCC3_LIVE_IMAGE_LIST, 775 + (void **) &top) != 0) 776 + goto get_live_image_failed; 777 + 778 + lip = &top; 779 + 780 + while (*lip != NULL) 781 + { 782 + if ((*lip)->destructor 783 + && ((*lip)->examined_p & DESTRUCTOR_MAY_BE_CALLED_LIVE)) 784 + { 785 + if (! was_in_object && (*lip)->destructor != prev_destructor) 786 + { 787 + Dl_info info; 788 + prev_destructor = (*lip)->destructor; 789 + was_in_object = (dladdr (prev_destructor, &info) != 0 790 + && info.dli_fbase == mh); 791 + } 792 + if ((*lip)->destructor == prev_destructor && was_in_object) 793 + (*lip)->destructor (*lip); 794 + } 795 + 796 + if ((*lip)->mh == mh && (*lip)->vm_slide == vm_slide) 797 + { 798 + destroy = *lip; 799 + *lip = destroy->next; /* unlink DESTROY */ 800 + 801 + if (destroy->this_size != sizeof (*destroy)) /* sanity check */ 802 + abort (); 803 + 804 + continue; 805 + } 806 + lip = &(*lip)->next; 807 + } 808 + _keymgr_set_and_unlock_processwide_ptr (KEYMGR_GCC3_LIVE_IMAGE_LIST, top); 809 + 810 + /* Now that we have unlinked this from the image list, toss it. 811 + The destructor gets called here only to handle the GCC 3.1 case. */ 812 + if (destroy != NULL) 813 + { 814 + if (destroy->destructor != NULL) 815 + (*destroy->destructor) (destroy); 816 + free (destroy); 817 + } 818 + get_live_image_failed: 819 + ; 820 + } 821 + } 822 + #endif // !x86_64 823 + 824 + void __keymgr_dwarf2_register_sections (void) 825 + { 826 + /* This function needs to remain for binary compatibiliity */ 827 + /* with old programs which were linked with a crt1.o that */ 828 + /* explicitly called __keymgr_dwarf2_register_sections() */ 829 + } 830 + 831 + /* call by libSystem's initializer */ 832 + void __keymgr_initializer (void) 833 + { 834 + #ifdef PR_6599778 835 + _keymgr_get_and_lock_processwide_ptr(KEYMGR_GCC3_DW2_OBJ_LIST); 836 + _keymgr_set_and_unlock_processwide_ptr(KEYMGR_GCC3_DW2_OBJ_LIST, &_keymgr_globals()->km_object_list_head); 837 + #endif 838 + 839 + #if __x86_64__ 840 + /* On Mac OS X 10.6, libunwind in libSystem.dylib implements all unwinding functionality. */ 841 + /* libunwind does not use keymgr, so there is no need to maintain KEYMGR_GCC3_LIVE_IMAGE_LIST */ 842 + /* in sync with dyld's list of images. But there might be some i386 or ppc applications that */ 843 + /* carry around there own copy of the unwinder (from libgcc.a) and need KEYMGR_GCC3_LIVE_IMAGE_LIST. */ 844 + #else 845 + /* register with dyld so that we are notified about all loaded mach-o images */ 846 + _dyld_register_func_for_add_image (dwarf2_unwind_dyld_add_image_hook); 847 + _dyld_register_func_for_remove_image (dwarf2_unwind_dyld_remove_image_hook); 848 + #endif /* __x86_64__ */ 849 + } 850 +
+125
keymgr/keymgr.h
··· 1 + /* Copyright (C) 1999, 2000, 2001, 2002, 2003 Apple Computer, Inc. 2 + 3 + This file is part of KeyMgr. 4 + 5 + KeyMgr is free software; you can redistribute it and/or modify it under 6 + the terms of the GNU General Public License as published by the Free 7 + Software Foundation; either version 2, or (at your option) any later 8 + version. 9 + 10 + In addition to the permissions in the GNU General Public License, 11 + Apple Computer gives you unlimited permission to link the compiled 12 + version of this file into combinations with other programs, and to 13 + distribute those combinations without any restriction coming from the 14 + use of this file. (The General Public License restrictions do apply 15 + in other respects; for example, they cover modification of the file, 16 + and distribution when not linked into a combine executable.) 17 + 18 + KeyMgr is distributed in the hope that it will be useful, but WITHOUT ANY 19 + WARRANTY; without even the implied warranty of MERCHANTABILITY or 20 + FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License 21 + for more details. 22 + 23 + You should have received a copy of the GNU General Public License 24 + along with KeyMgr; see the file COPYING. If not, write to the Free 25 + Software Foundation, 59 Temple Place - Suite 330, Boston, MA 26 + 02111-1307, USA. */ 27 + 28 + #ifndef __KEYMGR_H 29 + #define __KEYMGR_H 30 + 31 + #ifdef __cplusplus 32 + extern "C" { 33 + #endif 34 + 35 + 36 + 37 + /* 38 + * keymgr - Create and maintain process-wide global data known to 39 + * all threads across all dynamic libraries. 40 + * 41 + */ 42 + 43 + enum { 44 + NM_ALLOW_RECURSION = 1, 45 + NM_RECURSION_ILLEGAL = 2 46 + }; 47 + 48 + extern void * _keymgr_get_per_thread_data (unsigned int key); 49 + extern int _keymgr_set_per_thread_data (unsigned int key, void *keydata); 50 + extern void *_keymgr_get_and_lock_processwide_ptr (unsigned int key); 51 + extern int _keymgr_get_and_lock_processwide_ptr_2 (unsigned int key, void **); 52 + extern int _keymgr_set_and_unlock_processwide_ptr (unsigned int key, 53 + void *ptr); 54 + extern int _keymgr_unlock_processwide_ptr (unsigned int key); 55 + extern int _keymgr_set_lockmode_processwide_ptr (unsigned int key, 56 + unsigned int mode); 57 + extern unsigned int _keymgr_get_lockmode_processwide_ptr (unsigned int key); 58 + extern int _keymgr_get_lock_count_processwide_ptr (unsigned int key); 59 + 60 + /* 61 + * Keys currently in use: 62 + */ 63 + 64 + /* Head pointer of exception context node. */ 65 + #define KEYMGR_EH_CONTEXT_KEY 1 66 + 67 + /* New handler. */ 68 + #define KEYMGR_NEW_HANDLER_KEY 2 69 + 70 + /* Unexpected exception handler. */ 71 + #define KEYMGR_UNEXPECTED_HANDLER_KEY 3 72 + 73 + /* Terminate handler. */ 74 + #define KEYMGR_TERMINATE_HANDLER_KEY 4 75 + 76 + /* Runtime mode bits. */ 77 + #define KEYMGR_MODE_BITS 5 78 + 79 + /* Head pointer of the list of open streams. */ 80 + #define KEYMGR_IO_LIST 6 81 + 82 + /* libstdc++ for GCC 2.95 stdin. */ 83 + #define KEYMGR_IO_STDIN 7 84 + 85 + /* libstdc++ for GCC 2.95 stdout. */ 86 + #define KEYMGR_IO_STDOUT 8 87 + 88 + /* libstdc++ for GCC 2.95 stdout. */ 89 + #define KEYMGR_IO_STDERR 9 90 + 91 + /* Number of plugins/main program currently using streams in GCC 2.95. */ 92 + #define KEYMGR_IO_REFCNT 10 93 + 94 + /* Flags controlling the behavior of C++ I/O. */ 95 + #define KEYMGR_IO_MODE_BITS 11 96 + 97 + /* Head pointer for list of per image dwarf2 unwind sections. */ 98 + #define KEYMGR_ZOE_IMAGE_LIST 12 99 + 100 + /* C++ runtime EH global data. */ 101 + #define KEYMGR_EH_GLOBALS_KEY 13 102 + 103 + /* atexit() and __cxa_atexit routine list. */ 104 + #define KEYMGR_ATEXIT_LIST 14 105 + 106 + /* KeyMgr 3.x is the first one supporting GCC3 stuff natively. */ 107 + #define KEYMGR_API_MAJOR_GCC3 3 108 + /* ... with these keys. */ 109 + #define KEYMGR_GCC3_LIVE_IMAGE_LIST 301 /* loaded images */ 110 + #define KEYMGR_GCC3_DW2_OBJ_LIST 302 /* Dwarf2 object list */ 111 + 112 + /* 113 + * Other important data. 114 + */ 115 + 116 + /* Major revision number of the keymgr API. */ 117 + #define KEYMGR_API_REV_MAJOR 5 118 + /* Minor revision number of the keymgr API. */ 119 + #define KEYMGR_API_REV_MINOR 0 120 + 121 + #ifdef __cplusplus 122 + } 123 + #endif 124 + 125 + #endif /* __KEYMGR_H */
+1 -1
libsystem/CMakeLists.txt
··· 26 26 ) 27 27 28 28 add_library(system SHARED ${libsystem_sources}) 29 - target_link_libraries(system system_malloc system_c system_kernel) 29 + target_link_libraries(system system_malloc system_c system_kernel keymgr)