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