···11+ GNU GENERAL PUBLIC LICENSE
22+ Version 2, June 1991
33+44+ Copyright (C) 1989, 1991 Free Software Foundation, Inc.
55+ 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
66+ Everyone is permitted to copy and distribute verbatim copies
77+ of this license document, but changing it is not allowed.
88+99+ Preamble
1010+1111+ The licenses for most software are designed to take away your
1212+freedom to share and change it. By contrast, the GNU General Public
1313+License is intended to guarantee your freedom to share and change free
1414+software--to make sure the software is free for all its users. This
1515+General Public License applies to most of the Free Software
1616+Foundation's software and to any other program whose authors commit to
1717+using it. (Some other Free Software Foundation software is covered by
1818+the GNU Library General Public License instead.) You can apply it to
1919+your programs, too.
2020+2121+ When we speak of free software, we are referring to freedom, not
2222+price. Our General Public Licenses are designed to make sure that you
2323+have the freedom to distribute copies of free software (and charge for
2424+this service if you wish), that you receive source code or can get it
2525+if you want it, that you can change the software or use pieces of it
2626+in new free programs; and that you know you can do these things.
2727+2828+ To protect your rights, we need to make restrictions that forbid
2929+anyone to deny you these rights or to ask you to surrender the rights.
3030+These restrictions translate to certain responsibilities for you if you
3131+distribute copies of the software, or if you modify it.
3232+3333+ For example, if you distribute copies of such a program, whether
3434+gratis or for a fee, you must give the recipients all the rights that
3535+you have. You must make sure that they, too, receive or can get the
3636+source code. And you must show them these terms so they know their
3737+rights.
3838+3939+ We protect your rights with two steps: (1) copyright the software, and
4040+(2) offer you this license which gives you legal permission to copy,
4141+distribute and/or modify the software.
4242+4343+ Also, for each author's protection and ours, we want to make certain
4444+that everyone understands that there is no warranty for this free
4545+software. If the software is modified by someone else and passed on, we
4646+want its recipients to know that what they have is not the original, so
4747+that any problems introduced by others will not reflect on the original
4848+authors' reputations.
4949+5050+ Finally, any free program is threatened constantly by software
5151+patents. We wish to avoid the danger that redistributors of a free
5252+program will individually obtain patent licenses, in effect making the
5353+program proprietary. To prevent this, we have made it clear that any
5454+patent must be licensed for everyone's free use or not licensed at all.
5555+5656+ The precise terms and conditions for copying, distribution and
5757+modification follow.
5858+5959+ GNU GENERAL PUBLIC LICENSE
6060+ TERMS AND CONDITIONS FOR COPYING, DISTRIBUTION AND MODIFICATION
6161+6262+ 0. This License applies to any program or other work which contains
6363+a notice placed by the copyright holder saying it may be distributed
6464+under the terms of this General Public License. The "Program", below,
6565+refers to any such program or work, and a "work based on the Program"
6666+means either the Program or any derivative work under copyright law:
6767+that is to say, a work containing the Program or a portion of it,
6868+either verbatim or with modifications and/or translated into another
6969+language. (Hereinafter, translation is included without limitation in
7070+the term "modification".) Each licensee is addressed as "you".
7171+7272+Activities other than copying, distribution and modification are not
7373+covered by this License; they are outside its scope. The act of
7474+running the Program is not restricted, and the output from the Program
7575+is covered only if its contents constitute a work based on the
7676+Program (independent of having been made by running the Program).
7777+Whether that is true depends on what the Program does.
7878+7979+ 1. You may copy and distribute verbatim copies of the Program's
8080+source code as you receive it, in any medium, provided that you
8181+conspicuously and appropriately publish on each copy an appropriate
8282+copyright notice and disclaimer of warranty; keep intact all the
8383+notices that refer to this License and to the absence of any warranty;
8484+and give any other recipients of the Program a copy of this License
8585+along with the Program.
8686+8787+You may charge a fee for the physical act of transferring a copy, and
8888+you may at your option offer warranty protection in exchange for a fee.
8989+9090+ 2. You may modify your copy or copies of the Program or any portion
9191+of it, thus forming a work based on the Program, and copy and
9292+distribute such modifications or work under the terms of Section 1
9393+above, provided that you also meet all of these conditions:
9494+9595+ a) You must cause the modified files to carry prominent notices
9696+ stating that you changed the files and the date of any change.
9797+9898+ b) You must cause any work that you distribute or publish, that in
9999+ whole or in part contains or is derived from the Program or any
100100+ part thereof, to be licensed as a whole at no charge to all third
101101+ parties under the terms of this License.
102102+103103+ c) If the modified program normally reads commands interactively
104104+ when run, you must cause it, when started running for such
105105+ interactive use in the most ordinary way, to print or display an
106106+ announcement including an appropriate copyright notice and a
107107+ notice that there is no warranty (or else, saying that you provide
108108+ a warranty) and that users may redistribute the program under
109109+ these conditions, and telling the user how to view a copy of this
110110+ License. (Exception: if the Program itself is interactive but
111111+ does not normally print such an announcement, your work based on
112112+ the Program is not required to print an announcement.)
113113+114114+These requirements apply to the modified work as a whole. If
115115+identifiable sections of that work are not derived from the Program,
116116+and can be reasonably considered independent and separate works in
117117+themselves, then this License, and its terms, do not apply to those
118118+sections when you distribute them as separate works. But when you
119119+distribute the same sections as part of a whole which is a work based
120120+on the Program, the distribution of the whole must be on the terms of
121121+this License, whose permissions for other licensees extend to the
122122+entire whole, and thus to each and every part regardless of who wrote it.
123123+124124+Thus, it is not the intent of this section to claim rights or contest
125125+your rights to work written entirely by you; rather, the intent is to
126126+exercise the right to control the distribution of derivative or
127127+collective works based on the Program.
128128+129129+In addition, mere aggregation of another work not based on the Program
130130+with the Program (or with a work based on the Program) on a volume of
131131+a storage or distribution medium does not bring the other work under
132132+the scope of this License.
133133+134134+ 3. You may copy and distribute the Program (or a work based on it,
135135+under Section 2) in object code or executable form under the terms of
136136+Sections 1 and 2 above provided that you also do one of the following:
137137+138138+ a) Accompany it with the complete corresponding machine-readable
139139+ source code, which must be distributed under the terms of Sections
140140+ 1 and 2 above on a medium customarily used for software interchange; or,
141141+142142+ b) Accompany it with a written offer, valid for at least three
143143+ years, to give any third party, for a charge no more than your
144144+ cost of physically performing source distribution, a complete
145145+ machine-readable copy of the corresponding source code, to be
146146+ distributed under the terms of Sections 1 and 2 above on a medium
147147+ customarily used for software interchange; or,
148148+149149+ c) Accompany it with the information you received as to the offer
150150+ to distribute corresponding source code. (This alternative is
151151+ allowed only for noncommercial distribution and only if you
152152+ received the program in object code or executable form with such
153153+ an offer, in accord with Subsection b above.)
154154+155155+The source code for a work means the preferred form of the work for
156156+making modifications to it. For an executable work, complete source
157157+code means all the source code for all modules it contains, plus any
158158+associated interface definition files, plus the scripts used to
159159+control compilation and installation of the executable. However, as a
160160+special exception, the source code distributed need not include
161161+anything that is normally distributed (in either source or binary
162162+form) with the major components (compiler, kernel, and so on) of the
163163+operating system on which the executable runs, unless that component
164164+itself accompanies the executable.
165165+166166+If distribution of executable or object code is made by offering
167167+access to copy from a designated place, then offering equivalent
168168+access to copy the source code from the same place counts as
169169+distribution of the source code, even though third parties are not
170170+compelled to copy the source along with the object code.
171171+172172+ 4. You may not copy, modify, sublicense, or distribute the Program
173173+except as expressly provided under this License. Any attempt
174174+otherwise to copy, modify, sublicense or distribute the Program is
175175+void, and will automatically terminate your rights under this License.
176176+However, parties who have received copies, or rights, from you under
177177+this License will not have their licenses terminated so long as such
178178+parties remain in full compliance.
179179+180180+ 5. You are not required to accept this License, since you have not
181181+signed it. However, nothing else grants you permission to modify or
182182+distribute the Program or its derivative works. These actions are
183183+prohibited by law if you do not accept this License. Therefore, by
184184+modifying or distributing the Program (or any work based on the
185185+Program), you indicate your acceptance of this License to do so, and
186186+all its terms and conditions for copying, distributing or modifying
187187+the Program or works based on it.
188188+189189+ 6. Each time you redistribute the Program (or any work based on the
190190+Program), the recipient automatically receives a license from the
191191+original licensor to copy, distribute or modify the Program subject to
192192+these terms and conditions. You may not impose any further
193193+restrictions on the recipients' exercise of the rights granted herein.
194194+You are not responsible for enforcing compliance by third parties to
195195+this License.
196196+197197+ 7. If, as a consequence of a court judgment or allegation of patent
198198+infringement or for any other reason (not limited to patent issues),
199199+conditions are imposed on you (whether by court order, agreement or
200200+otherwise) that contradict the conditions of this License, they do not
201201+excuse you from the conditions of this License. If you cannot
202202+distribute so as to satisfy simultaneously your obligations under this
203203+License and any other pertinent obligations, then as a consequence you
204204+may not distribute the Program at all. For example, if a patent
205205+license would not permit royalty-free redistribution of the Program by
206206+all those who receive copies directly or indirectly through you, then
207207+the only way you could satisfy both it and this License would be to
208208+refrain entirely from distribution of the Program.
209209+210210+If any portion of this section is held invalid or unenforceable under
211211+any particular circumstance, the balance of the section is intended to
212212+apply and the section as a whole is intended to apply in other
213213+circumstances.
214214+215215+It is not the purpose of this section to induce you to infringe any
216216+patents or other property right claims or to contest validity of any
217217+such claims; this section has the sole purpose of protecting the
218218+integrity of the free software distribution system, which is
219219+implemented by public license practices. Many people have made
220220+generous contributions to the wide range of software distributed
221221+through that system in reliance on consistent application of that
222222+system; it is up to the author/donor to decide if he or she is willing
223223+to distribute software through any other system and a licensee cannot
224224+impose that choice.
225225+226226+This section is intended to make thoroughly clear what is believed to
227227+be a consequence of the rest of this License.
228228+229229+ 8. If the distribution and/or use of the Program is restricted in
230230+certain countries either by patents or by copyrighted interfaces, the
231231+original copyright holder who places the Program under this License
232232+may add an explicit geographical distribution limitation excluding
233233+those countries, so that distribution is permitted only in or among
234234+countries not thus excluded. In such case, this License incorporates
235235+the limitation as if written in the body of this License.
236236+237237+ 9. The Free Software Foundation may publish revised and/or new versions
238238+of the General Public License from time to time. Such new versions will
239239+be similar in spirit to the present version, but may differ in detail to
240240+address new problems or concerns.
241241+242242+Each version is given a distinguishing version number. If the Program
243243+specifies a version number of this License which applies to it and "any
244244+later version", you have the option of following the terms and conditions
245245+either of that version or of any later version published by the Free
246246+Software Foundation. If the Program does not specify a version number of
247247+this License, you may choose any version ever published by the Free Software
248248+Foundation.
249249+250250+ 10. If you wish to incorporate parts of the Program into other free
251251+programs whose distribution conditions are different, write to the author
252252+to ask for permission. For software which is copyrighted by the Free
253253+Software Foundation, write to the Free Software Foundation; we sometimes
254254+make exceptions for this. Our decision will be guided by the two goals
255255+of preserving the free status of all derivatives of our free software and
256256+of promoting the sharing and reuse of software generally.
257257+258258+ NO WARRANTY
259259+260260+ 11. BECAUSE THE PROGRAM IS LICENSED FREE OF CHARGE, THERE IS NO WARRANTY
261261+FOR THE PROGRAM, TO THE EXTENT PERMITTED BY APPLICABLE LAW. EXCEPT WHEN
262262+OTHERWISE STATED IN WRITING THE COPYRIGHT HOLDERS AND/OR OTHER PARTIES
263263+PROVIDE THE PROGRAM "AS IS" WITHOUT WARRANTY OF ANY KIND, EITHER EXPRESSED
264264+OR IMPLIED, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
265265+MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE. THE ENTIRE RISK AS
266266+TO THE QUALITY AND PERFORMANCE OF THE PROGRAM IS WITH YOU. SHOULD THE
267267+PROGRAM PROVE DEFECTIVE, YOU ASSUME THE COST OF ALL NECESSARY SERVICING,
268268+REPAIR OR CORRECTION.
269269+270270+ 12. IN NO EVENT UNLESS REQUIRED BY APPLICABLE LAW OR AGREED TO IN WRITING
271271+WILL ANY COPYRIGHT HOLDER, OR ANY OTHER PARTY WHO MAY MODIFY AND/OR
272272+REDISTRIBUTE THE PROGRAM AS PERMITTED ABOVE, BE LIABLE TO YOU FOR DAMAGES,
273273+INCLUDING ANY GENERAL, SPECIAL, INCIDENTAL OR CONSEQUENTIAL DAMAGES ARISING
274274+OUT OF THE USE OR INABILITY TO USE THE PROGRAM (INCLUDING BUT NOT LIMITED
275275+TO LOSS OF DATA OR DATA BEING RENDERED INACCURATE OR LOSSES SUSTAINED BY
276276+YOU OR THIRD PARTIES OR A FAILURE OF THE PROGRAM TO OPERATE WITH ANY OTHER
277277+PROGRAMS), EVEN IF SUCH HOLDER OR OTHER PARTY HAS BEEN ADVISED OF THE
278278+POSSIBILITY OF SUCH DAMAGES.
279279+280280+ END OF TERMS AND CONDITIONS
281281+282282+ How to Apply These Terms to Your New Programs
283283+284284+ If you develop a new program, and you want it to be of the greatest
285285+possible use to the public, the best way to achieve this is to make it
286286+free software which everyone can redistribute and change under these terms.
287287+288288+ To do so, attach the following notices to the program. It is safest
289289+to attach them to the start of each source file to most effectively
290290+convey the exclusion of warranty; and each file should have at least
291291+the "copyright" line and a pointer to where the full notice is found.
292292+293293+ <one line to give the program's name and a brief idea of what it does.>
294294+ Copyright (C) <year> <name of author>
295295+296296+ This program is free software; you can redistribute it and/or modify
297297+ it under the terms of the GNU General Public License as published by
298298+ the Free Software Foundation; either version 2 of the License, or
299299+ (at your option) any later version.
300300+301301+ This program is distributed in the hope that it will be useful,
302302+ but WITHOUT ANY WARRANTY; without even the implied warranty of
303303+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
304304+ GNU General Public License for more details.
305305+306306+ You should have received a copy of the GNU General Public License
307307+ along with this program; if not, write to the Free Software
308308+ Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
309309+310310+311311+Also add information on how to contact you by electronic and paper mail.
312312+313313+If the program is interactive, make it output a short notice like this
314314+when it starts in an interactive mode:
315315+316316+ Gnomovision version 69, Copyright (C) year name of author
317317+ Gnomovision comes with ABSOLUTELY NO WARRANTY; for details type `show w'.
318318+ This is free software, and you are welcome to redistribute it
319319+ under certain conditions; type `show c' for details.
320320+321321+The hypothetical commands `show w' and `show c' should show the appropriate
322322+parts of the General Public License. Of course, the commands you use may
323323+be called something other than `show w' and `show c'; they could even be
324324+mouse-clicks or menu items--whatever suits your program.
325325+326326+You should also get your employer (if you work as a programmer) or your
327327+school, if any, to sign a "copyright disclaimer" for the program, if
328328+necessary. Here is a sample; alter the names:
329329+330330+ Yoyodyne, Inc., hereby disclaims all copyright interest in the program
331331+ `Gnomovision' (which makes passes at compilers) written by James Hacker.
332332+333333+ <signature of Ty Coon>, 1 April 1989
334334+ Ty Coon, President of Vice
335335+336336+This General Public License does not permit incorporating your program into
337337+proprietary programs. If your program is a subroutine library, you may
338338+consider it more useful to permit linking proprietary applications with the
339339+library. If this is what you want to do, use the GNU Library General
340340+Public License instead of this License.
+850
keymgr/keymgr.c
···11+/* Copyright (C) 1999-2005, 2012 Apple Inc.
22+ Copyright (C) 1997, 2001 Free Software Foundation, Inc.
33+44+This file is part of KeyMgr.
55+66+KeyMgr is free software; you can redistribute it and/or modify it under
77+the terms of the GNU General Public License as published by the Free
88+Software Foundation; either version 2, or (at your option) any later
99+version.
1010+1111+In addition to the permissions in the GNU General Public License,
1212+Apple Computer and the Free Software Foundation gives you unlimited
1313+permission to link the compiled version of this file into combinations
1414+with other programs, and to distribute those combinations without any
1515+restriction coming from the use of this file. (The General Public
1616+License restrictions do apply in other respects; for example, they
1717+cover modification of the file, and distribution when not linked into
1818+a combine executable.)
1919+2020+KeyMgr is distributed in the hope that it will be useful, but WITHOUT ANY
2121+WARRANTY; without even the implied warranty of MERCHANTABILITY or
2222+FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
2323+for more details.
2424+2525+You should have received a copy of the GNU General Public License
2626+along with KeyMgr; see the file COPYING. If not, write to the Free
2727+Software Foundation, 59 Temple Place - Suite 330, Boston, MA
2828+02111-1307, USA. */
2929+3030+/* The FSF-copyright part is the definition of 'struct
3131+ old_object'. It was taken from unwind-dw2-fde.h from GCC 3.1. */
3232+3333+/*
3434+ * keymgr - Create and maintain process-wide global data known to
3535+ * all threads across all dynamic libraries.
3636+ *
3737+ */
3838+3939+#include <mach-o/dyld.h>
4040+#include <dlfcn.h>
4141+#include <pthread.h>
4242+#include <errno.h>
4343+#include <stdlib.h>
4444+#include <libkern/OSAtomic.h>
4545+#include <stdint.h>
4646+4747+#if __has_include(<os/alloc_once_private.h>)
4848+#include <os/alloc_once_private.h>
4949+#if defined(OS_ALLOC_ONCE_KEY_LIBKEYMGR)
5050+#define _HAS_ALLOC_ONCE 1
5151+#endif
5252+#endif
5353+5454+#include "keymgr.h"
5555+5656+/* On x86 or later platforms, there's no need to support the TLS SPIs.
5757+ The only reason to support them on ppc64 is because the tools
5858+ shipped with Tiger included a libsupc++.a which used these
5959+ functions. (To do: investigate whether anyone ever actually used
6060+ that library for ppc64.) */
6161+#if defined(__ppc__) || defined(__ppc64__)
6262+#define WANT_TLS_SPIS 1
6363+#endif
6464+6565+/* On Mac OS X 10.6, unwinding is down by libunwind in libSystem.B.dylib
6666+ Normally, the object list is not used, but some applications that dynamically
6767+ generate code directly use keymgr to find the KEYMGR_GCC3_DW2_OBJ_LIST
6868+ list and insert frame information. The problem is those apps don't check
6969+ if KEYMGR_GCC3_DW2_OBJ_LIST is currently NULL. The fix is to statically
7070+ allocate the object list head struct and set KEYMGR_GCC3_DW2_OBJ_LIST to
7171+ point to it <rdar://problem/6599778>. */
7272+#if defined(__i386__)
7373+#define PR_6599778 1
7474+#endif
7575+7676+#ifndef ESUCCESS
7777+#define ESUCCESS 0
7878+#endif
7979+8080+/* Types of node, used for error checking. */
8181+typedef enum node_kinds {
8282+ NODE_PROCESSWIDE_PTR=1,
8383+#ifdef WANT_TLS_SPIS
8484+ NODE_THREAD_SPECIFIC_DATA
8585+#endif
8686+} TnodeKind;
8787+8888+/* These values are internal; the subflags of NM_ENHANCED_LOCKING are
8989+ defined in keymgr.h and are not internal. */
9090+enum {
9191+ NM_ENHANCED_LOCKING=3
9292+};
9393+9494+/* Base node kind for keymgr node list; also used to represent per
9595+ thread variables (NODE_THREAD_SPECIFIC_DATA). */
9696+9797+typedef struct Skey_data {
9898+ struct Skey_data * next;
9999+ unsigned int handle; /* Key id of variable. */
100100+ unsigned char node_kind; /* What kind of variable is this? */
101101+ unsigned char flags; /* Flags controlling behavior of variable. */
102102+ unsigned short refcount; /* If recursion has been enabled, reference
103103+ count. */
104104+ void *ptr; /* Data associated with variable. */
105105+ pthread_mutex_t thread_lock; /* Semaphore for this specific variable. */
106106+} Tkey_Data;
107107+108108+typedef struct Sinfo_Node {
109109+ unsigned int size; /* Size of this node. */
110110+ unsigned short major_version; /* API major version. */
111111+ unsigned short minor_version; /* API minor version. */
112112+} Tinfo_Node;
113113+114114+/* Static variables for initial __keymgr_global values. */
115115+116116+static const Tinfo_Node keymgr_info = {
117117+ sizeof (Tinfo_Node),
118118+ KEYMGR_API_REV_MAJOR,
119119+ KEYMGR_API_REV_MINOR
120120+};
121121+122122+/* __keymgr_global - contains pointers to keymgr data that needs to be
123123+ global and known across all dlls/plugins. */
124124+struct {
125125+ /* Formerly, a pthreads semaphore for accessing the keymgr global data.
126126+ Now unused. */
127127+ void *unused;
128128+129129+ /* Formerly the keymgr_globals pointer. Moved to os_alloc_once allocation. */
130130+ void *unused2;
131131+132132+ /* Pointer to keymgr information node. This is part of the semi-public
133133+ ABI of keymgr. */
134134+ const Tinfo_Node *keymgr_info;
135135+} const __attribute__((aligned (32))) __keymgr_global = {
136136+ NULL,
137137+ NULL,
138138+ &keymgr_info
139139+};
140140+141141+struct keymgr_globals_s {
142142+ /* Pointer to keymgr global list. This pointer was previously contained
143143+ in the second word of __keymgr_global static data. Moved here to avoid
144144+ diryting a __DATA page in each process.
145145+ Prior to that, contained in __eh_global_dataptr. */
146146+ Tkey_Data * volatile keymgr_globals;
147147+148148+#ifdef PR_6599778
149149+ /* Used to statically allocate the head of the object list.
150150+ The struct is 4 pointers long and must be initially zero filled. */
151151+ void *km_object_list_head[4];
152152+#endif
153153+};
154154+typedef struct keymgr_globals_s *keymgr_globals_t;
155155+156156+__attribute__((__pure__))
157157+static inline keymgr_globals_t
158158+_keymgr_globals(void) {
159159+#if _HAS_ALLOC_ONCE
160160+ return (keymgr_globals_t)os_alloc_once(OS_ALLOC_ONCE_KEY_LIBKEYMGR,
161161+ sizeof(struct keymgr_globals_s), NULL);
162162+#else
163163+ static struct keymgr_globals_s storage;
164164+ return &storage;
165165+#endif
166166+}
167167+168168+#if defined(__ppc__)
169169+/* Initialize keymgr. */
170170+171171+void _init_keymgr (void)
172172+{
173173+ /* This routine is now empty, but is part of keymgr's ABI on ppc and
174174+ so can't be completely removed. */
175175+}
176176+#endif
177177+178178+/* Find any Tkey_Data associated with KEY. If none exists, or KIND
179179+ does not match, return NULL. */
180180+181181+static Tkey_Data *
182182+get_key_element (unsigned int key, TnodeKind kind)
183183+{
184184+ Tkey_Data *keyArray;
185185+186186+ for (keyArray = _keymgr_globals()->keymgr_globals;
187187+ keyArray != NULL;
188188+ keyArray = keyArray->next)
189189+ if (keyArray->handle == key)
190190+ {
191191+ if (keyArray->node_kind == kind)
192192+ return keyArray;
193193+ else
194194+ return NULL;
195195+ }
196196+197197+ return NULL;
198198+}
199199+200200+/* Find any Tkey_Data associated with KEY. If none exists, create one
201201+ and add it to the list. Put it in *RESULT.
202202+203203+ On success, return 0, otherwise:
204204+ [EINVAL] The node existed but was not of type KIND.
205205+ [ENOMEM] Out of memory, couldn't create node.
206206+ [EAGAIN] The mutex associated with the new node couldn't be created.
207207+ This can only happen when KIND == NODE_PROCESSWIDE_PTR.
208208+209209+ The aims of this routine are:
210210+211211+ - After execution, there should be exactly one element in the list
212212+ with HANDLE set to KEY.
213213+ - The pointer to that element should be returned in *RESULT.
214214+215215+ In addition, we know that:
216216+217217+ - The list only has elements added, never removed, and they are
218218+ always added to the head of the list.
219219+*/
220220+221221+static int
222222+get_or_create_key_element (unsigned int key, TnodeKind kind,
223223+ Tkey_Data **result)
224224+{
225225+ Tkey_Data *searchEnd = NULL;
226226+ Tkey_Data *newEntry = NULL;
227227+228228+ for (;;)
229229+ {
230230+ Tkey_Data *keyArrayStart = _keymgr_globals()->keymgr_globals;
231231+ Tkey_Data *keyArray;
232232+233233+ /* At this point, we know that we have not searched the elements
234234+ between keyArrayStart and searchEnd, but we have previously searched
235235+ searchEnd (if not NULL) and all the elements after it. */
236236+237237+ for (keyArray = keyArrayStart;
238238+ keyArray != searchEnd;
239239+ keyArray = keyArray->next)
240240+ if (keyArray->handle == key)
241241+ {
242242+ /* Found an existing entry for KEY. Free any new entry we
243243+ created in a previous pass through the loop. */
244244+ if (newEntry)
245245+ {
246246+ if (kind == NODE_PROCESSWIDE_PTR)
247247+ /* This call should never fail. */
248248+ if (pthread_mutex_destroy (&newEntry->thread_lock)
249249+ != ESUCCESS)
250250+ abort ();
251251+ free (newEntry);
252252+ }
253253+254254+ if (keyArray->node_kind != kind)
255255+ return EINVAL;
256256+ *result = keyArray;
257257+ return ESUCCESS;
258258+ }
259259+260260+ /* At this point, we know that there is no entry after keyArrayStart
261261+ which matches KEY. We will try to add one. */
262262+263263+ if (! newEntry)
264264+ {
265265+ /* Create the new entry. */
266266+ newEntry = (Tkey_Data *) malloc (sizeof (Tkey_Data));
267267+ if (newEntry == NULL)
268268+ return ENOMEM;
269269+270270+ if (kind == NODE_PROCESSWIDE_PTR)
271271+ {
272272+ pthread_mutexattr_t attr;
273273+ int errnum;
274274+275275+ newEntry->refcount = 0;
276276+ newEntry->flags = 0;
277277+278278+ errnum = pthread_mutexattr_init (&attr);
279279+ if (errnum == ESUCCESS)
280280+ {
281281+ pthread_mutexattr_settype (&attr, PTHREAD_MUTEX_ERRORCHECK);
282282+ errnum = pthread_mutex_init (&newEntry->thread_lock, &attr);
283283+ pthread_mutexattr_destroy (&attr);
284284+ }
285285+ if (errnum != ESUCCESS)
286286+ {
287287+ free (newEntry);
288288+ return errnum;
289289+ }
290290+ }
291291+292292+ newEntry->handle = key;
293293+ newEntry->ptr = NULL;
294294+ newEntry->node_kind = kind;
295295+ }
296296+297297+ /* The compare-and-swap will succeed only if the list head is
298298+ keyArrayStart, and we are prepending newEntry onto the list,
299299+ so the next element after newEntry should be keyArrayStart. */
300300+301301+ newEntry->next = keyArrayStart;
302302+303303+ /* The barrier is necessary to ensure that newEntry->next is seen
304304+ to be set by any thread that sees newEntry in the list. */
305305+306306+ /* If the compare-and-swap succeeds, it means that the head of
307307+ the list did not change between the search above and the
308308+ store of newEntry. Therefore, since we searched all the
309309+ elements from the head at that time, we can be sure that the
310310+ entry we're adding is not in the list. */
311311+#ifdef __LP64__
312312+ if (OSAtomicCompareAndSwap64Barrier (
313313+ (int64_t) keyArrayStart,
314314+ (int64_t) newEntry,
315315+ (int64_t *) &_keymgr_globals()->keymgr_globals))
316316+#else
317317+ if (OSAtomicCompareAndSwap32Barrier (
318318+ (int32_t) keyArrayStart,
319319+ (int32_t) newEntry,
320320+ (int32_t *) &_keymgr_globals()->keymgr_globals))
321321+#endif
322322+ {
323323+ *result = newEntry;
324324+ return ESUCCESS;
325325+ }
326326+ /* Another thread changed the list. The entries between
327327+ keyArrayStart and searchEnd were searched above, so now we
328328+ can stop searching at keyArrayStart. We know we will make
329329+ progress in the next loop iteration because the new searchEnd
330330+ will not be equal to __keymgr_global.keymgr_globals and so we
331331+ will search at least one new element. Since the list can
332332+ have at most one element for each valid key, eventually there
333333+ will be no more elements to search and so we will stop reaching
334334+ this point and looping. */
335335+ searchEnd = keyArrayStart;
336336+ }
337337+}
338338+339339+#ifdef WANT_TLS_SPIS
340340+/* Return the data associated with KEY for the current thread.
341341+ Return NULL if there is no such data. */
342342+343343+void *
344344+_keymgr_get_per_thread_data (unsigned int key)
345345+{
346346+ Tkey_Data * keyArray;
347347+ void * key_data;
348348+349349+ keyArray = get_key_element (key, NODE_THREAD_SPECIFIC_DATA);
350350+351351+ /* If the element hasn't been set, the answer is always NULL. */
352352+ if (keyArray == NULL)
353353+ return NULL;
354354+355355+ /* On all platforms we run on, a pointer-sized load from an aligned
356356+ address is atomic. */
357357+ key_data = keyArray->ptr;
358358+359359+ /* key_data might be NULL if this entry is in the process of being
360360+ created. In that case, return NULL. */
361361+ if (key_data == NULL)
362362+ return NULL;
363363+364364+ return pthread_getspecific ((pthread_key_t) key_data);
365365+}
366366+367367+/* Set the data for KEY for this thread to be KEYDATA. Return 0 on success,
368368+ or:
369369+370370+ [ENOMEM] Out of memory.
371371+ [EINVAL] The KEY was previously used to store process-wide data.
372372+ [EAGAIN] The system lacked the necessary resources to create
373373+ another thread-specific data key, or the system- imposed
374374+ limit on the total number of keys per process
375375+ [PTHREAD_KEYS_MAX] would be exceeded. This error can't
376376+ happen after the first successful call to
377377+ _keymgr_set_per_thread_data from a particular thread with
378378+ a particular KEY.
379379+*/
380380+381381+int
382382+_keymgr_set_per_thread_data (unsigned int key, void *keydata)
383383+{
384384+ volatile Tkey_Data * keyArray;
385385+ pthread_key_t pthread_key;
386386+ void *ptr;
387387+ int errnum;
388388+389389+ errnum = get_or_create_key_element (key, NODE_THREAD_SPECIFIC_DATA,
390390+ (Tkey_Data **)&keyArray);
391391+ if (errnum != ESUCCESS)
392392+ return errnum;
393393+394394+ /* This routine doesn't lock *keyArray. Instead, it relies on the
395395+ fact that keyArray->ptr is either NULL or a valid pthread key value,
396396+ and it only changes once, from NULL to a valid value. */
397397+398398+ ptr = keyArray->ptr;
399399+ if (ptr == NULL)
400400+ {
401401+ void (*destructor)(void *);
402402+ bool neededInit;
403403+404404+ switch (key)
405405+ {
406406+ case KEYMGR_EH_CONTEXT_KEY:
407407+ case KEYMGR_EH_GLOBALS_KEY:
408408+ destructor = free;
409409+ break;
410410+ default:
411411+ destructor = NULL;
412412+ break;
413413+ }
414414+ if ((errnum = pthread_key_create (&pthread_key, destructor)) != 0)
415415+ return errnum;
416416+417417+#ifdef __LP64__
418418+ neededInit = OSAtomicCompareAndSwap64 ((int64_t) NULL,
419419+ (int64_t) pthread_key,
420420+ (int64_t *) &keyArray->ptr);
421421+#else
422422+ neededInit = OSAtomicCompareAndSwap32 ((int32_t) NULL,
423423+ (int32_t) pthread_key,
424424+ (int32_t *) &keyArray->ptr);
425425+#endif
426426+ if (!neededInit)
427427+ pthread_key_delete (pthread_key);
428428+ ptr = keyArray->ptr;
429429+ }
430430+ pthread_key = (pthread_key_t) ptr;
431431+432432+ return pthread_setspecific (pthread_key, keydata);
433433+}
434434+#endif /* WANT_TLS_SPIS */
435435+436436+437437+/*
438438+ * These routines provide management of a process wide, thread safe,
439439+ * persistent pointer. If a pointer is created by a bundle/plug-in
440440+ * and placed in here, it will persist for the life of the process,
441441+ * even after the bundle has been unloaded. This is especially useful
442442+ * for data shared across plugins and across repeated plugin loads and
443443+ * unloads.
444444+ */
445445+446446+/* Get the processwide data associated with KEY into *RESULT,
447447+ and lock a lock associated with KEY.
448448+449449+ On success, return 0, otherwise:
450450+451451+ [EINVAL] KEY was previously used to store thread-specific data.
452452+ [ENOMEM] Out of memory, couldn't create node.
453453+ [EAGAIN] The mutex associated with the new node couldn't be created.
454454+ [EDEADLK] A deadlock would occur if the thread blocked waiting
455455+ for the lock.
456456+*/
457457+458458+int
459459+_keymgr_get_and_lock_processwide_ptr_2 (unsigned int key, void ** result)
460460+{
461461+ Tkey_Data *keyArray;
462462+ int errnum;
463463+464464+ errnum = get_or_create_key_element (key, NODE_PROCESSWIDE_PTR, &keyArray);
465465+ if (errnum != ESUCCESS)
466466+ return errnum;
467467+468468+ if ((errnum = pthread_mutex_lock (&keyArray->thread_lock)) != ESUCCESS)
469469+ return errnum;
470470+471471+ keyArray->refcount++;
472472+ *result = keyArray->ptr;
473473+ return ESUCCESS;
474474+}
475475+476476+/* For backwards compatibility; like _keymgr_get_and_lock_processwide_ptr_2
477477+ but returns the pointer or NULL on error. */
478478+479479+void *
480480+_keymgr_get_and_lock_processwide_ptr (unsigned int key)
481481+{
482482+ void *result = NULL;
483483+ _keymgr_get_and_lock_processwide_ptr_2 (key, &result);
484484+ return result;
485485+}
486486+487487+/* Unlock the lock associated with NODE. Return 0 on success.
488488+ Returns EPERM if the lock is not locked by the current thread. */
489489+490490+static int
491491+unlock_node (Tkey_Data *node)
492492+{
493493+ int result;
494494+495495+ node->refcount--;
496496+ result = pthread_mutex_unlock (&node->thread_lock);
497497+ if (result != ESUCCESS)
498498+ node->refcount++;
499499+ return result;
500500+}
501501+502502+/* Set the processwide data associated with KEY to PTR, and unlock
503503+ the lock associated with KEY.
504504+505505+ On success, returns 0. On failure, returns:
506506+507507+ [EINVAL] KEY was previously used to store thread-specific data.
508508+ [ENOMEM] Out of memory, couldn't create node.
509509+ [EAGAIN] The mutex associated with the new node couldn't be created.
510510+ [EPERM] The lock was not locked by the current thread.
511511+*/
512512+513513+int
514514+_keymgr_set_and_unlock_processwide_ptr (unsigned int key, void *ptr)
515515+{
516516+ Tkey_Data *keyArray;
517517+ int result;
518518+519519+ result = get_or_create_key_element (key, NODE_PROCESSWIDE_PTR, &keyArray);
520520+ if (result != ESUCCESS)
521521+ return result;
522522+523523+ keyArray->ptr = ptr;
524524+ return unlock_node (keyArray);
525525+}
526526+527527+/* Unlock the lock associated with KEY.
528528+529529+ On success, returns 0. On failure, returns:
530530+531531+ [EINVAL] KEY was not previously used to store process-specific data.
532532+ [EPERM] The lock was not locked by the current thread.
533533+*/
534534+535535+int
536536+_keymgr_unlock_processwide_ptr (unsigned int key)
537537+{
538538+ Tkey_Data *keyArray;
539539+540540+ keyArray = get_key_element (key, NODE_PROCESSWIDE_PTR);
541541+ if (keyArray == NULL)
542542+ return EINVAL;
543543+544544+ return unlock_node (keyArray);
545545+}
546546+547547+/* Set the locking mode of KEY to MODE. This should not be done while
548548+ KEY is locked or another thread might be using KEY.
549549+550550+ On success, returns 0. On failure, returns:
551551+ [EINVAL] KEY was previously used to store thread-specific data.
552552+ [ENOMEM] Out of memory.
553553+ [EBUSY] The mutex associated with the node was locked.
554554+*/
555555+556556+int
557557+_keymgr_set_lockmode_processwide_ptr (unsigned int key, unsigned int mode)
558558+{
559559+ Tkey_Data *keyArray;
560560+ pthread_mutexattr_t attr;
561561+ int type;
562562+ int result;
563563+564564+ result = get_or_create_key_element (key, NODE_PROCESSWIDE_PTR, &keyArray);
565565+ if (result != ESUCCESS)
566566+ return result;
567567+568568+ if (mode == keyArray->flags)
569569+ return ESUCCESS;
570570+571571+ result = pthread_mutexattr_init (&attr);
572572+ if (result != ESUCCESS)
573573+ return result;
574574+575575+ if (mode == NM_ALLOW_RECURSION)
576576+ type = PTHREAD_MUTEX_RECURSIVE;
577577+ else
578578+ type = PTHREAD_MUTEX_ERRORCHECK;
579579+ pthread_mutexattr_settype (&attr, type);
580580+581581+ /* Delete the old mutex and create a new one. */
582582+ result = pthread_mutex_destroy (&keyArray->thread_lock);
583583+ /* Apple's implementation of pthread_mutex_init can't fail in this
584584+ situation. */
585585+ if (result == ESUCCESS)
586586+ result = pthread_mutex_init (&keyArray->thread_lock, &attr);
587587+588588+ pthread_mutexattr_destroy (&attr);
589589+590590+ if (result == ESUCCESS)
591591+ keyArray->flags = mode;
592592+ return result;
593593+}
594594+595595+/* Returns the locking mode of the lock associated with KEY, if any,
596596+ or 0 if there is no such lock. */
597597+598598+unsigned int
599599+_keymgr_get_lockmode_processwide_ptr (unsigned int key)
600600+{
601601+ Tkey_Data *keyArray;
602602+603603+ keyArray = get_key_element (key, NODE_PROCESSWIDE_PTR);
604604+ if (keyArray == NULL)
605605+ return 0;
606606+ return keyArray->flags;
607607+}
608608+609609+/* Return the number of locks on KEY. To call this routine safely,
610610+ you should be holding one of them, thus 0 is an error return. */
611611+612612+int
613613+_keymgr_get_lock_count_processwide_ptr (unsigned int key)
614614+{
615615+ Tkey_Data *keyArray;
616616+617617+ keyArray = get_key_element (key, NODE_PROCESSWIDE_PTR);
618618+ if (keyArray == NULL)
619619+ return 0;
620620+ return keyArray->refcount;
621621+}
622622+623623+/*********************************************/
624624+625625+#include <mach-o/getsect.h>
626626+627627+/* Beware, this is an API. */
628628+629629+struct __live_images {
630630+ unsigned long this_size; /* sizeof (__live_images) */
631631+ const struct mach_header *mh; /* the image info */
632632+ intptr_t vm_slide;
633633+ void (*destructor)(struct __live_images *); /* destructor for this */
634634+ struct __live_images *next;
635635+ unsigned long examined_p;
636636+ void *fde;
637637+ void *object_info;
638638+ unsigned long info[2]; /* GCC3 use */
639639+};
640640+641641+/* Bits in the examined_p field of struct live_images. */
642642+enum {
643643+ EXAMINED_IMAGE_MASK = 1, /* We've seen this one. */
644644+ ALLOCED_IMAGE_MASK = 2, /* The FDE entries were allocated by
645645+ malloc, and must be freed. This isn't
646646+ used by newer libgcc versions. */
647647+ IMAGE_IS_TEXT_MASK = 4, /* This image is in the TEXT segment. */
648648+ DESTRUCTOR_MAY_BE_CALLED_LIVE = 8 /* The destructor may be called on an
649649+ object that's part of the live
650650+ image list. */
651651+};
652652+653653+#ifdef __ppc__
654654+struct old_object
655655+{
656656+ void *pc_begin;
657657+ void *pc_end;
658658+ struct dwarf_fde *fde_begin;
659659+ struct dwarf_fde **fde_array;
660660+ size_t count;
661661+ struct old_object *next;
662662+ long section_size;
663663+};
664664+665665+static const char __DWARF2_UNWIND_SECTION_TYPE[] = "__TEXT";
666666+static const char __DWARF2_UNWIND_SECTION_NAME[] = "__dwarf2_unwind";
667667+#endif
668668+669669+#if !__x86_64__
670670+/* Called by dyld when an image is added to the executable.
671671+ If it has a dwarf2_unwind section, register it so the C++ runtime
672672+ can get at it. All of this is protected by dyld thread locks. */
673673+674674+static void dwarf2_unwind_dyld_add_image_hook (const struct mach_header *mh,
675675+ intptr_t vm_slide)
676676+{
677677+#ifdef __ppc__
678678+ uint32_t sz;
679679+ char *fde;
680680+681681+ /* See if the image has a __TEXT __dwarf2_unwind section. This
682682+ is for backwards compatibility with old GCCs. */
683683+684684+ fde = getsectdatafromheader (mh, __DWARF2_UNWIND_SECTION_TYPE,
685685+ __DWARF2_UNWIND_SECTION_NAME, &sz);
686686+687687+ if (fde != 0)
688688+ {
689689+ struct old_object *obp;
690690+691691+ obp = (struct old_object *) calloc (1, sizeof (struct old_object) + 8);
692692+ if (obp == NULL)
693693+ return;
694694+695695+ obp->section_size = sz;
696696+ obp->fde_begin = (struct dwarf_fde *) (fde + vm_slide);
697697+698698+ if (_keymgr_get_and_lock_processwide_ptr_2 (KEYMGR_ZOE_IMAGE_LIST,
699699+ (void **) &obp->next) == 0)
700700+ _keymgr_set_and_unlock_processwide_ptr (KEYMGR_ZOE_IMAGE_LIST, obp);
701701+ }
702702+#endif
703703+704704+ {
705705+ struct __live_images *l = (struct __live_images *) calloc (1, sizeof (*l));
706706+ if (l == NULL)
707707+ return;
708708+709709+ l->mh = mh;
710710+ l->vm_slide = vm_slide;
711711+ l->this_size = sizeof (*l);
712712+ if (_keymgr_get_and_lock_processwide_ptr_2 (KEYMGR_GCC3_LIVE_IMAGE_LIST,
713713+ (void **) &l->next) == 0)
714714+ _keymgr_set_and_unlock_processwide_ptr (KEYMGR_GCC3_LIVE_IMAGE_LIST, l);
715715+ }
716716+}
717717+718718+719719+720720+static void
721721+dwarf2_unwind_dyld_remove_image_hook (const struct mach_header *mh,
722722+ intptr_t vm_slide)
723723+{
724724+#ifdef __ppc__
725725+ uint32_t sz;
726726+ char *fde;
727727+728728+ /* See if the image has a __TEXT __dwarf2_unwind section. */
729729+730730+ fde = getsectdatafromheader (mh, __DWARF2_UNWIND_SECTION_TYPE,
731731+ __DWARF2_UNWIND_SECTION_NAME, &sz);
732732+ if (fde != 0)
733733+ {
734734+ struct old_object *objlist, **obp;
735735+736736+ if (_keymgr_get_and_lock_processwide_ptr_2 (KEYMGR_ZOE_IMAGE_LIST,
737737+ (void **) &objlist) != 0)
738738+ goto get_zoe_failed;
739739+740740+ for (obp = &objlist; *obp; obp = &(*obp)->next)
741741+ if ((char *)(*obp)->fde_begin == fde + vm_slide)
742742+ {
743743+ struct old_object *p = *obp;
744744+ *obp = p->next;
745745+ if (p->pc_begin)
746746+ free (p->fde_array);
747747+ free (p);
748748+ break;
749749+ }
750750+751751+ _keymgr_set_and_unlock_processwide_ptr (KEYMGR_ZOE_IMAGE_LIST, objlist);
752752+ get_zoe_failed:
753753+ ;
754754+ }
755755+#endif
756756+757757+ {
758758+ struct __live_images *top, **lip, *destroy = NULL;
759759+760760+ /* This is a bit of cache. _dyld_get_image_header_containing_address
761761+ can be expensive, but most of the time the destructors come from
762762+ one or two objects and are consecutive in the list. */
763763+ void (*prev_destructor)(struct __live_images *) = NULL;
764764+ int was_in_object = 0;
765765+766766+ /* Look for it in the list of live images and delete it.
767767+ Also, call any destructors in case they are in this image and about
768768+ to be unloaded. The test with DESTRUCTOR_MAY_BE_CALLED_LIVE is
769769+ because in GCC 3.1, the destructor would (uselessly) try to acquire
770770+ the LIVE_IMAGE_LIST lock, and it's not practical to call it in
771771+ that case (deadlock ensues, unless we release the lock, in which
772772+ case the concurrency issues become impossible). */
773773+774774+ if (_keymgr_get_and_lock_processwide_ptr_2 (KEYMGR_GCC3_LIVE_IMAGE_LIST,
775775+ (void **) &top) != 0)
776776+ goto get_live_image_failed;
777777+778778+ lip = ⊤
779779+780780+ while (*lip != NULL)
781781+ {
782782+ if ((*lip)->destructor
783783+ && ((*lip)->examined_p & DESTRUCTOR_MAY_BE_CALLED_LIVE))
784784+ {
785785+ if (! was_in_object && (*lip)->destructor != prev_destructor)
786786+ {
787787+ Dl_info info;
788788+ prev_destructor = (*lip)->destructor;
789789+ was_in_object = (dladdr (prev_destructor, &info) != 0
790790+ && info.dli_fbase == mh);
791791+ }
792792+ if ((*lip)->destructor == prev_destructor && was_in_object)
793793+ (*lip)->destructor (*lip);
794794+ }
795795+796796+ if ((*lip)->mh == mh && (*lip)->vm_slide == vm_slide)
797797+ {
798798+ destroy = *lip;
799799+ *lip = destroy->next; /* unlink DESTROY */
800800+801801+ if (destroy->this_size != sizeof (*destroy)) /* sanity check */
802802+ abort ();
803803+804804+ continue;
805805+ }
806806+ lip = &(*lip)->next;
807807+ }
808808+ _keymgr_set_and_unlock_processwide_ptr (KEYMGR_GCC3_LIVE_IMAGE_LIST, top);
809809+810810+ /* Now that we have unlinked this from the image list, toss it.
811811+ The destructor gets called here only to handle the GCC 3.1 case. */
812812+ if (destroy != NULL)
813813+ {
814814+ if (destroy->destructor != NULL)
815815+ (*destroy->destructor) (destroy);
816816+ free (destroy);
817817+ }
818818+ get_live_image_failed:
819819+ ;
820820+ }
821821+}
822822+#endif // !x86_64
823823+824824+void __keymgr_dwarf2_register_sections (void)
825825+{
826826+ /* This function needs to remain for binary compatibiliity */
827827+ /* with old programs which were linked with a crt1.o that */
828828+ /* explicitly called __keymgr_dwarf2_register_sections() */
829829+}
830830+831831+/* call by libSystem's initializer */
832832+void __keymgr_initializer (void)
833833+{
834834+#ifdef PR_6599778
835835+ _keymgr_get_and_lock_processwide_ptr(KEYMGR_GCC3_DW2_OBJ_LIST);
836836+ _keymgr_set_and_unlock_processwide_ptr(KEYMGR_GCC3_DW2_OBJ_LIST, &_keymgr_globals()->km_object_list_head);
837837+#endif
838838+839839+#if __x86_64__
840840+ /* On Mac OS X 10.6, libunwind in libSystem.dylib implements all unwinding functionality. */
841841+ /* libunwind does not use keymgr, so there is no need to maintain KEYMGR_GCC3_LIVE_IMAGE_LIST */
842842+ /* in sync with dyld's list of images. But there might be some i386 or ppc applications that */
843843+ /* carry around there own copy of the unwinder (from libgcc.a) and need KEYMGR_GCC3_LIVE_IMAGE_LIST. */
844844+#else
845845+ /* register with dyld so that we are notified about all loaded mach-o images */
846846+ _dyld_register_func_for_add_image (dwarf2_unwind_dyld_add_image_hook);
847847+ _dyld_register_func_for_remove_image (dwarf2_unwind_dyld_remove_image_hook);
848848+#endif /* __x86_64__ */
849849+}
850850+
+125
keymgr/keymgr.h
···11+/* Copyright (C) 1999, 2000, 2001, 2002, 2003 Apple Computer, Inc.
22+33+This file is part of KeyMgr.
44+55+KeyMgr is free software; you can redistribute it and/or modify it under
66+the terms of the GNU General Public License as published by the Free
77+Software Foundation; either version 2, or (at your option) any later
88+version.
99+1010+In addition to the permissions in the GNU General Public License,
1111+Apple Computer gives you unlimited permission to link the compiled
1212+version of this file into combinations with other programs, and to
1313+distribute those combinations without any restriction coming from the
1414+use of this file. (The General Public License restrictions do apply
1515+in other respects; for example, they cover modification of the file,
1616+and distribution when not linked into a combine executable.)
1717+1818+KeyMgr is distributed in the hope that it will be useful, but WITHOUT ANY
1919+WARRANTY; without even the implied warranty of MERCHANTABILITY or
2020+FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
2121+for more details.
2222+2323+You should have received a copy of the GNU General Public License
2424+along with KeyMgr; see the file COPYING. If not, write to the Free
2525+Software Foundation, 59 Temple Place - Suite 330, Boston, MA
2626+02111-1307, USA. */
2727+2828+#ifndef __KEYMGR_H
2929+#define __KEYMGR_H
3030+3131+#ifdef __cplusplus
3232+extern "C" {
3333+#endif
3434+3535+3636+3737+/*
3838+ * keymgr - Create and maintain process-wide global data known to
3939+ * all threads across all dynamic libraries.
4040+ *
4141+ */
4242+4343+enum {
4444+ NM_ALLOW_RECURSION = 1,
4545+ NM_RECURSION_ILLEGAL = 2
4646+};
4747+4848+extern void * _keymgr_get_per_thread_data (unsigned int key);
4949+extern int _keymgr_set_per_thread_data (unsigned int key, void *keydata);
5050+extern void *_keymgr_get_and_lock_processwide_ptr (unsigned int key);
5151+extern int _keymgr_get_and_lock_processwide_ptr_2 (unsigned int key, void **);
5252+extern int _keymgr_set_and_unlock_processwide_ptr (unsigned int key,
5353+ void *ptr);
5454+extern int _keymgr_unlock_processwide_ptr (unsigned int key);
5555+extern int _keymgr_set_lockmode_processwide_ptr (unsigned int key,
5656+ unsigned int mode);
5757+extern unsigned int _keymgr_get_lockmode_processwide_ptr (unsigned int key);
5858+extern int _keymgr_get_lock_count_processwide_ptr (unsigned int key);
5959+6060+/*
6161+ * Keys currently in use:
6262+ */
6363+6464+/* Head pointer of exception context node. */
6565+#define KEYMGR_EH_CONTEXT_KEY 1
6666+6767+/* New handler. */
6868+#define KEYMGR_NEW_HANDLER_KEY 2
6969+7070+/* Unexpected exception handler. */
7171+#define KEYMGR_UNEXPECTED_HANDLER_KEY 3
7272+7373+/* Terminate handler. */
7474+#define KEYMGR_TERMINATE_HANDLER_KEY 4
7575+7676+/* Runtime mode bits. */
7777+#define KEYMGR_MODE_BITS 5
7878+7979+/* Head pointer of the list of open streams. */
8080+#define KEYMGR_IO_LIST 6
8181+8282+/* libstdc++ for GCC 2.95 stdin. */
8383+#define KEYMGR_IO_STDIN 7
8484+8585+/* libstdc++ for GCC 2.95 stdout. */
8686+#define KEYMGR_IO_STDOUT 8
8787+8888+/* libstdc++ for GCC 2.95 stdout. */
8989+#define KEYMGR_IO_STDERR 9
9090+9191+/* Number of plugins/main program currently using streams in GCC 2.95. */
9292+#define KEYMGR_IO_REFCNT 10
9393+9494+/* Flags controlling the behavior of C++ I/O. */
9595+#define KEYMGR_IO_MODE_BITS 11
9696+9797+/* Head pointer for list of per image dwarf2 unwind sections. */
9898+#define KEYMGR_ZOE_IMAGE_LIST 12
9999+100100+/* C++ runtime EH global data. */
101101+#define KEYMGR_EH_GLOBALS_KEY 13
102102+103103+/* atexit() and __cxa_atexit routine list. */
104104+#define KEYMGR_ATEXIT_LIST 14
105105+106106+/* KeyMgr 3.x is the first one supporting GCC3 stuff natively. */
107107+#define KEYMGR_API_MAJOR_GCC3 3
108108+/* ... with these keys. */
109109+#define KEYMGR_GCC3_LIVE_IMAGE_LIST 301 /* loaded images */
110110+#define KEYMGR_GCC3_DW2_OBJ_LIST 302 /* Dwarf2 object list */
111111+112112+/*
113113+ * Other important data.
114114+ */
115115+116116+/* Major revision number of the keymgr API. */
117117+#define KEYMGR_API_REV_MAJOR 5
118118+/* Minor revision number of the keymgr API. */
119119+#define KEYMGR_API_REV_MINOR 0
120120+121121+#ifdef __cplusplus
122122+}
123123+#endif
124124+125125+#endif /* __KEYMGR_H */