1 /* Configuration definitions. 2 Copyright (C) 2008, 2009 Red Hat, Inc. 3 This file is part of elfutils. 4 5 This file is free software; you can redistribute it and/or modify 6 it under the terms of either 7 8 * the GNU Lesser General Public License as published by the Free 9 Software Foundation; either version 3 of the License, or (at 10 your option) any later version 11 12 or 13 14 * the GNU General Public License as published by the Free 15 Software Foundation; either version 2 of the License, or (at 16 your option) any later version 17 18 or both in parallel, as here. 19 20 elfutils is distributed in the hope that it will be useful, but 21 WITHOUT ANY WARRANTY; without even the implied warranty of 22 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU 23 General Public License for more details. 24 25 You should have received copies of the GNU General Public License and 26 the GNU Lesser General Public License along with this program. If 27 not, see <http://www.gnu.org/licenses/>. */ 28 29 #ifndef EU_CONFIG_H 30 #define EU_CONFIG_H 1 31 32 #ifdef USE_LOCKS 33 # include <pthread.h> 34 # include <assert.h> 35 # define rwlock_define(class,name) class pthread_rwlock_t name 36 # define once_define(class,name) class pthread_once_t name = PTHREAD_ONCE_INIT 37 # define RWLOCK_CALL(call) \ 38 ({ int _err = pthread_rwlock_ ## call; assert_perror (_err); }) 39 # define ONCE_CALL(call) \ 40 ({ int _err = pthread_ ## call; assert_perror (_err); }) 41 # define rwlock_init(lock) RWLOCK_CALL (init (&lock, NULL)) 42 # define rwlock_fini(lock) RWLOCK_CALL (destroy (&lock)) 43 # define rwlock_rdlock(lock) RWLOCK_CALL (rdlock (&lock)) 44 # define rwlock_wrlock(lock) RWLOCK_CALL (wrlock (&lock)) 45 # define rwlock_unlock(lock) RWLOCK_CALL (unlock (&lock)) 46 # define once(once_control, init_routine) \ 47 ONCE_CALL (once (&once_control, init_routine)) 48 #else 49 /* Eventually we will allow multi-threaded applications to use the 50 libraries. Therefore we will add the necessary locking although 51 the macros used expand to nothing for now. */ 52 # define rwlock_define(class,name) class int name 53 # define rwlock_init(lock) ((void) (lock)) 54 # define rwlock_fini(lock) ((void) (lock)) 55 # define rwlock_rdlock(lock) ((void) (lock)) 56 # define rwlock_wrlock(lock) ((void) (lock)) 57 # define rwlock_unlock(lock) ((void) (lock)) 58 # define once_define(class,name) 59 # define once(once_control, init_routine) init_routine() 60 #endif /* USE_LOCKS */ 61 62 #include <libintl.h> 63 /* gettext helper macros. */ 64 #define N_(Str) Str 65 #define _(Str) dgettext ("elfutils", Str) 66 67 /* Compiler-specific definitions. */ 68 #define strong_alias(name, aliasname) \ 69 extern __typeof (name) aliasname __attribute__ ((alias (#name))); 70 71 #ifdef __i386__ 72 # define internal_function __attribute__ ((regparm (3), stdcall)) 73 #else 74 # define internal_function /* nothing */ 75 #endif 76 77 #define internal_strong_alias(name, aliasname) \ 78 extern __typeof (name) aliasname __attribute__ ((alias (#name))) internal_function; 79 80 #ifdef HAVE_VISIBILITY 81 #define attribute_hidden \ 82 __attribute__ ((visibility ("hidden"))) 83 #else 84 #define attribute_hidden /* empty */ 85 #endif 86 87 #ifdef HAVE_GCC_STRUCT 88 #define attribute_packed \ 89 __attribute__ ((packed, gcc_struct)) 90 #else 91 #define attribute_packed \ 92 __attribute__ ((packed)) 93 #endif 94 95 /* Define ALLOW_UNALIGNED if the architecture allows operations on 96 unaligned memory locations. */ 97 #define SANITIZE_UNDEFINED 1 98 #if (defined __i386__ || defined __x86_64__) && ! CHECK_UNDEFINED 99 # define ALLOW_UNALIGNED 1 100 #else 101 # define ALLOW_UNALIGNED 0 102 #endif 103 104 #if DEBUGPRED 105 # ifdef __x86_64__ 106 asm (".section predict_data, \"aw\"; .previous\n" 107 ".section predict_line, \"a\"; .previous\n" 108 ".section predict_file, \"a\"; .previous"); 109 # ifndef PIC 110 # define debugpred__(e, E) \ 111 ({ long int _e = !!(e); \ 112 asm volatile (".pushsection predict_data; ..predictcnt%=: .quad 0; .quad 0\n" \ 113 ".section predict_line; .quad %c1\n" \ 114 ".section predict_file; .quad %c2; .popsection\n" \ 115 "addq $1,..predictcnt%=(,%0,8)" \ 116 : : "r" (_e == E), "i" (__LINE__), "i" (__FILE__)); \ 117 __builtin_expect (_e, E); \ 118 }) 119 # endif 120 # elif defined __i386__ 121 asm (".section predict_data, \"aw\"; .previous\n" 122 ".section predict_line, \"a\"; .previous\n" 123 ".section predict_file, \"a\"; .previous"); 124 # ifndef PIC 125 # define debugpred__(e, E) \ 126 ({ long int _e = !!(e); \ 127 asm volatile (".pushsection predict_data; ..predictcnt%=: .long 0; .long 0\n" \ 128 ".section predict_line; .long %c1\n" \ 129 ".section predict_file; .long %c2; .popsection\n" \ 130 "incl ..predictcnt%=(,%0,8)" \ 131 : : "r" (_e == E), "i" (__LINE__), "i" (__FILE__)); \ 132 __builtin_expect (_e, E); \ 133 }) 134 # endif 135 # endif 136 # ifdef debugpred__ 137 # define unlikely(e) debugpred__ (e,0) 138 # define likely(e) debugpred__ (e,1) 139 # endif 140 #endif 141 #ifndef likely 142 # define unlikely(expr) __builtin_expect (!!(expr), 0) 143 # define likely(expr) __builtin_expect (!!(expr), 1) 144 #endif 145 146 #define obstack_calloc(ob, size) \ 147 ({ size_t _s = (size); memset (obstack_alloc (ob, _s), '\0', _s); }) 148 #define obstack_strdup(ob, str) \ 149 ({ const char *_s = (str); obstack_copy0 (ob, _s, strlen (_s)); }) 150 #define obstack_strndup(ob, str, n) \ 151 ({ const char *_s = (str); obstack_copy0 (ob, _s, strnlen (_s, n)); }) 152 153 #if __STDC_VERSION__ >= 199901L 154 # define flexarr_size /* empty */ 155 #else 156 # define flexarr_size 0 157 #endif 158 159 /* Calling conventions. */ 160 #ifdef __i386__ 161 # define CALLING_CONVENTION regparm (3), stdcall 162 # define AND_CALLING_CONVENTION , regparm (3), stdcall 163 #else 164 # define CALLING_CONVENTION 165 # define AND_CALLING_CONVENTION 166 #endif 167 168 /* Avoid PLT entries. */ 169 #ifdef PIC 170 # define INTUSE(name) _INTUSE(name) 171 # define _INTUSE(name) __##name##_internal 172 # define INTDEF(name) _INTDEF(name) 173 # define _INTDEF(name) \ 174 extern __typeof__ (name) __##name##_internal __attribute__ ((alias (#name))); 175 # define INTDECL(name) _INTDECL(name) 176 # define _INTDECL(name) \ 177 extern __typeof__ (name) __##name##_internal attribute_hidden; 178 #else 179 # define INTUSE(name) name 180 # define INTDEF(name) /* empty */ 181 # define INTDECL(name) /* empty */ 182 #endif 183 184 /* This macro is used by the tests conditionalize for standalone building. */ 185 #define ELFUTILS_HEADER(name) <lib##name.h> 186 187 /* Don't reorder with global asm blocks or optimize away. (Doesn't reliably 188 keep it in the same LTO partition, though; -flto-partition=none may be 189 still needed for some gcc versions < 10.) */ 190 #ifdef __has_attribute 191 # if __has_attribute(no_reorder) 192 # define used_in_asm __attribute__ ((externally_visible, no_reorder)) 193 # endif 194 #endif 195 #ifndef used_in_asm 196 # define used_in_asm /* empty */ 197 #endif 198 199 #ifdef SYMBOL_VERSIONING 200 # define NEW_INTDEF(name) __typeof (name) INTUSE(name) \ 201 __attribute__ ((alias ("_new." #name))) attribute_hidden; 202 # ifdef __has_attribute 203 # if __has_attribute(symver) 204 # define NEW_VERSION(name, version) \ 205 __typeof (name) name __asm__ ("_new." #name) \ 206 __attribute__ ((symver (#name "@@" #version))); 207 # define OLD_VERSION(name, version) _OLD_VERSION1(name, __COUNTER__, version) 208 # define _OLD_VERSION1(name, num, version) _OLD_VERSION2(name, num, version) 209 # define _OLD_VERSION2(name, num, version) \ 210 __typeof (name) _compat_old##num##_##name \ 211 __asm__ ("_compat." #version "." #name) \ 212 __attribute__ ((alias ("_new." #name), symver (#name "@" #version))); 213 # define COMPAT_VERSION_NEWPROTO(name, version, prefix) \ 214 __typeof (_compat_##prefix##_##name) _compat_##prefix##_##name \ 215 __asm__ ("_compat." #version "." #name) \ 216 __attribute__ ((symver (#name "@" #version))); 217 # define COMPAT_VERSION(name, version, prefix) \ 218 asm (".symver _compat." #version "." #name "," #name "@" #version); \ 219 __typeof (name) _compat_##prefix##_##name \ 220 __asm__ ("_compat." #version "." #name) \ 221 __attribute__ ((symver (#name "@" #version))); 222 # endif 223 # endif 224 # ifndef NEW_VERSION 225 # define OLD_VERSION(name, version) \ 226 asm (".globl _compat." #version "." #name "\n\t" \ 227 "_compat." #version "." #name " = _new." #name "\n\t" \ 228 ".symver _compat." #version "." #name "," #name "@" #version); 229 # define NEW_VERSION(name, version) \ 230 __typeof (name) name __asm__ ("_new." #name) used_in_asm; \ 231 asm (".symver _new." #name ", " #name "@@" #version); 232 # define COMPAT_VERSION_NEWPROTO(name, version, prefix) \ 233 __typeof (_compat_##prefix##_##name) _compat_##prefix##_##name \ 234 __asm__ ("_compat." #version "." #name) used_in_asm; \ 235 asm (".symver _compat." #version "." #name ", " #name "@" #version); 236 # define COMPAT_VERSION(name, version, prefix) \ 237 __typeof (name) _compat_##prefix##_##name \ 238 __asm__ ("_compat." #version "." #name) used_in_asm; \ 239 asm (".symver _compat." #version "." #name ", " #name "@" #version); 240 # endif 241 #else 242 # define NEW_INTDEF(name) INTDEF(name) 243 # define OLD_VERSION(name, version) /* Nothing for static linking. */ 244 # define NEW_VERSION(name, version) /* Nothing for static linking. */ 245 # define COMPAT_VERSION_NEWPROTO(name, version, prefix) \ 246 error "should use #ifdef SYMBOL_VERSIONING" 247 # define COMPAT_VERSION(name, version, prefix) \ 248 error "should use #ifdef SYMBOL_VERSIONING" 249 #endif 250 251 #ifndef FALLTHROUGH 252 # ifdef HAVE_FALLTHROUGH 253 # define FALLTHROUGH __attribute__ ((fallthrough)) 254 # else 255 # define FALLTHROUGH ((void) 0) 256 # endif 257 #endif 258 259 #endif /* eu-config.h */ 260