110d565efSmrg /* Provide the runtime infrastructure for the transactional memory lib.
2*ec02198aSmrg    Copyright (C) 2011-2020 Free Software Foundation, Inc.
310d565efSmrg    Contributed by Iain Sandoe <iains@gcc.gnu.org>
410d565efSmrg 
510d565efSmrg    This file is part of GCC.
610d565efSmrg 
710d565efSmrg GCC is free software; you can redistribute it and/or modify it under
810d565efSmrg the terms of the GNU General Public License as published by the Free
910d565efSmrg Software Foundation; either version 3, or (at your option) any later
1010d565efSmrg version.
1110d565efSmrg 
1210d565efSmrg GCC is distributed in the hope that it will be useful, but WITHOUT ANY
1310d565efSmrg WARRANTY; without even the implied warranty of MERCHANTABILITY or
1410d565efSmrg FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
1510d565efSmrg for more details.
1610d565efSmrg 
1710d565efSmrg Under Section 7 of GPL version 3, you are granted additional
1810d565efSmrg permissions described in the GCC Runtime Library Exception, version
1910d565efSmrg 3.1, as published by the Free Software Foundation.
2010d565efSmrg 
2110d565efSmrg You should have received a copy of the GNU General Public License and
2210d565efSmrg a copy of the GCC Runtime Library Exception along with this program;
2310d565efSmrg see the files COPYING3 and COPYING.RUNTIME respectively.  If not, see
2410d565efSmrg <http://www.gnu.org/licenses/>.  */
2510d565efSmrg 
2610d565efSmrg #include "tsystem.h"
2710d565efSmrg #include <stddef.h>
2810d565efSmrg #include <dlfcn.h>
2910d565efSmrg #include <mach-o/dyld.h>
3010d565efSmrg #include <mach-o/getsect.h>
3110d565efSmrg 
3210d565efSmrg #ifdef __LP64__
3310d565efSmrg #define GET_DATA_TMCT(mh,size) \
3410d565efSmrg   getsectdatafromheader_64 ((struct mach_header_64*) mh, \
3510d565efSmrg 			    "__DATA", "__tm_clone_table", (uint64_t *)size)
3610d565efSmrg #else
3710d565efSmrg #define GET_DATA_TMCT(mh,size) \
3810d565efSmrg   getsectdatafromheader (mh, "__DATA", "__tm_clone_table", (uint32_t *)size)
3910d565efSmrg #endif
4010d565efSmrg 
4110d565efSmrg #define WEAK __attribute__((weak))
4210d565efSmrg 
4310d565efSmrg extern void _ITM_registerTMCloneTable (void *, size_t) WEAK;
4410d565efSmrg extern void _ITM_deregisterTMCloneTable (void *) WEAK;
4510d565efSmrg 
4610d565efSmrg #if defined(START) || defined(END)
getTMCloneTable(const void * f,size_t * tmct_siz)4710d565efSmrg static inline void *getTMCloneTable (const void *f, size_t *tmct_siz)
4810d565efSmrg {
4910d565efSmrg   char *tmct_fixed, *tmct = NULL;
5010d565efSmrg   unsigned int i, img_count;
5110d565efSmrg   struct mach_header *mh;
5210d565efSmrg   Dl_info info;
5310d565efSmrg 
5410d565efSmrg   if (! dladdr (f, &info) || info.dli_fbase == NULL)
5510d565efSmrg     abort ();
5610d565efSmrg 
5710d565efSmrg   mh = (struct mach_header *) info.dli_fbase;
5810d565efSmrg   tmct_fixed = GET_DATA_TMCT (mh, tmct_siz);
5910d565efSmrg   *tmct_siz /= (sizeof (size_t) * 2);
6010d565efSmrg   /* No tm_clone_table or no clones. */
6110d565efSmrg   if (tmct_fixed == NULL || *tmct_siz == 0)
6210d565efSmrg     return NULL;
6310d565efSmrg 
6410d565efSmrg   img_count = _dyld_image_count();
6510d565efSmrg   for (i = 0; i < img_count && tmct == NULL; i++)
6610d565efSmrg     {
6710d565efSmrg       if (mh == _dyld_get_image_header(i))
6810d565efSmrg 	tmct = tmct_fixed + (unsigned long)_dyld_get_image_vmaddr_slide(i);
6910d565efSmrg     }
7010d565efSmrg 
7110d565efSmrg   return tmct;
7210d565efSmrg }
7310d565efSmrg #endif
7410d565efSmrg 
7510d565efSmrg #ifdef START
7610d565efSmrg 
7710d565efSmrg void __doTMRegistrations (void) __attribute__ ((constructor));
7810d565efSmrg 
__doTMRegistrations(void)7910d565efSmrg void __doTMRegistrations (void)
8010d565efSmrg {
8110d565efSmrg   size_t tmct_siz;
8210d565efSmrg   void *tmct;
8310d565efSmrg 
8410d565efSmrg   tmct = getTMCloneTable ((const void *)&__doTMRegistrations, &tmct_siz);
8510d565efSmrg   if (_ITM_registerTMCloneTable != NULL && tmct != NULL)
8610d565efSmrg     _ITM_registerTMCloneTable (tmct, (size_t)tmct_siz);
8710d565efSmrg }
8810d565efSmrg 
8910d565efSmrg #endif
9010d565efSmrg 
9110d565efSmrg #ifdef END
9210d565efSmrg 
9310d565efSmrg void __doTMdeRegistrations (void) __attribute__ ((destructor));
9410d565efSmrg 
__doTMdeRegistrations(void)9510d565efSmrg void __doTMdeRegistrations (void)
9610d565efSmrg {
9710d565efSmrg   size_t tmct_siz;
9810d565efSmrg   void *tmct;
9910d565efSmrg 
10010d565efSmrg   tmct = getTMCloneTable ((const void *)&__doTMdeRegistrations, &tmct_siz);
10110d565efSmrg   if (_ITM_deregisterTMCloneTable != NULL && tmct != NULL)
10210d565efSmrg     _ITM_deregisterTMCloneTable (tmct);
10310d565efSmrg }
10410d565efSmrg 
10510d565efSmrg #endif
106