1 /* Make sure dlopen/dlclose are not marked as leaf functions. 2 3 Copyright (C) 2013-2022 Free Software Foundation, Inc. 4 This file is part of the GNU C Library. 5 6 The GNU C Library is free software; you can redistribute it and/or 7 modify it under the terms of the GNU Lesser General Public 8 License as published by the Free Software Foundation; either 9 version 2.1 of the License, or (at your option) any later version. 10 11 The GNU C Library is distributed in the hope that it will be useful, 12 but WITHOUT ANY WARRANTY; without even the implied warranty of 13 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU 14 Lesser General Public License for more details. 15 16 You should have received a copy of the GNU Lesser General Public 17 License along with the GNU C Library; if not, see 18 <https://www.gnu.org/licenses/>. */ 19 20 /* The bug-dl-leaf.c file will call our lib_main directly. We do this to 21 keep things simple -- no need to use --export-dynamic with the linker 22 or build the main ELF as a PIE. 23 24 The lib_main func will modify some of its state while dlopening and 25 dlclosing the bug-dl-leaf-lib-cb.so library. The constructors and 26 destructors in that library will call back into this library to also 27 muck with state (the check_val_xxx funcs). 28 29 If dlclose/dlopen are marked as "leaf" functions, then with newer 30 versions of gcc, the state modification won't work correctly. */ 31 32 #include <assert.h> 33 #include <dlfcn.h> 34 35 static int val = 1; 36 static int called = 0; 37 check_val_init(void)38void check_val_init (void) 39 { 40 called = 1; 41 assert (val == 2); 42 } 43 check_val_fini(void)44void check_val_fini (void) 45 { 46 called = 2; 47 assert (val == 4); 48 } 49 lib_main(void)50int lib_main (void) 51 { 52 int ret __attribute__ ((unused)); 53 void *hdl; 54 55 /* Make sure the constructor sees the updated val. */ 56 val = 2; 57 hdl = dlopen ("bug-dl-leaf-lib-cb.so", RTLD_GLOBAL | RTLD_LAZY); 58 val = 3; 59 assert (hdl); 60 assert (called == 1); 61 62 /* Make sure the destructor sees the updated val. */ 63 val = 4; 64 ret = dlclose (hdl); 65 val = 5; 66 assert (ret == 0); 67 assert (called == 2); 68 69 return !val; 70 } 71