1/* Provide the runtime infrastructure for the transactional memory lib. 2 Copyright (C) 2011-2015 Free Software Foundation, Inc. 3 Contributed by Iain Sandoe <iains@gcc.gnu.org> 4 5 This file is part of GCC. 6 7GCC is free software; you can redistribute it and/or modify it under 8the terms of the GNU General Public License as published by the Free 9Software Foundation; either version 3, or (at your option) any later 10version. 11 12GCC is distributed in the hope that it will be useful, but WITHOUT ANY 13WARRANTY; without even the implied warranty of MERCHANTABILITY or 14FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License 15for more details. 16 17Under Section 7 of GPL version 3, you are granted additional 18permissions described in the GCC Runtime Library Exception, version 193.1, as published by the Free Software Foundation. 20 21You should have received a copy of the GNU General Public License and 22a copy of the GCC Runtime Library Exception along with this program; 23see the files COPYING3 and COPYING.RUNTIME respectively. If not, see 24<http://www.gnu.org/licenses/>. */ 25 26#include "tsystem.h" 27#include <stddef.h> 28#include <dlfcn.h> 29#include <mach-o/dyld.h> 30#include <mach-o/getsect.h> 31 32#ifdef __LP64__ 33#define GET_DATA_TMCT(mh,size) \ 34 getsectdatafromheader_64 ((struct mach_header_64*) mh, \ 35 "__DATA", "__tm_clone_table", (uint64_t *)size) 36#else 37#define GET_DATA_TMCT(mh,size) \ 38 getsectdatafromheader (mh, "__DATA", "__tm_clone_table", (uint32_t *)size) 39#endif 40 41#define WEAK __attribute__((weak)) 42 43extern void _ITM_registerTMCloneTable (void *, size_t) WEAK; 44extern void _ITM_deregisterTMCloneTable (void *) WEAK; 45 46#if defined(START) || defined(END) 47static inline void *getTMCloneTable (const void *f, size_t *tmct_siz) 48{ 49 char *tmct_fixed, *tmct = NULL; 50 unsigned int i, img_count; 51 struct mach_header *mh; 52 Dl_info info; 53 54 if (! dladdr (f, &info) || info.dli_fbase == NULL) 55 abort (); 56 57 mh = (struct mach_header *) info.dli_fbase; 58 tmct_fixed = GET_DATA_TMCT (mh, tmct_siz); 59 *tmct_siz /= (sizeof (size_t) * 2); 60 /* No tm_clone_table or no clones. */ 61 if (tmct_fixed == NULL || *tmct_siz == 0) 62 return NULL; 63 64 img_count = _dyld_image_count(); 65 for (i = 0; i < img_count && tmct == NULL; i++) 66 { 67 if (mh == _dyld_get_image_header(i)) 68 tmct = tmct_fixed + (unsigned long)_dyld_get_image_vmaddr_slide(i); 69 } 70 71 return tmct; 72} 73#endif 74 75#ifdef START 76 77void __doTMRegistrations (void) __attribute__ ((constructor)); 78 79void __doTMRegistrations (void) 80{ 81 size_t tmct_siz; 82 void *tmct; 83 84 tmct = getTMCloneTable ((const void *)&__doTMRegistrations, &tmct_siz); 85 if (_ITM_registerTMCloneTable != NULL && tmct != NULL) 86 _ITM_registerTMCloneTable (tmct, (size_t)tmct_siz); 87} 88 89#endif 90 91#ifdef END 92 93void __doTMdeRegistrations (void) __attribute__ ((destructor)); 94 95void __doTMdeRegistrations (void) 96{ 97 size_t tmct_siz; 98 void *tmct; 99 100 tmct = getTMCloneTable ((const void *)&__doTMdeRegistrations, &tmct_siz); 101 if (_ITM_deregisterTMCloneTable != NULL && tmct != NULL) 102 _ITM_deregisterTMCloneTable (tmct); 103} 104 105#endif 106