1 /* Xtensa configuration settings loader. 2 Copyright (C) 2022-2025 Free Software Foundation, Inc. 3 4 This file is part of BFD, the Binary File Descriptor library. 5 6 GCC is free software; you can redistribute it and/or modify it under 7 the terms of the GNU General Public License as published by the Free 8 Software Foundation; either version 3, or (at your option) any later 9 version. 10 11 GCC is distributed in the hope that it will be useful, but WITHOUT ANY 12 WARRANTY; without even the implied warranty of MERCHANTABILITY or 13 FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License 14 for more details. 15 16 You should have received a copy of the GNU General Public License 17 along with GCC; see the file COPYING3. If not see 18 <http://www.gnu.org/licenses/>. */ 19 20 #include "sysdep.h" 21 #include "bfd.h" 22 #include "libbfd.h" 23 24 #define XTENSA_CONFIG_DEFINITION 25 #include "xtensa-config.h" 26 #include "xtensa-dynconfig.h" 27 28 #if defined (HAVE_DLFCN_H) 29 #include <dlfcn.h> 30 #elif defined (HAVE_WINDOWS_H) 31 #include <windows.h> 32 #endif 33 34 #if !defined (HAVE_DLFCN_H) && defined (HAVE_WINDOWS_H) 35 36 #define RTLD_LAZY 0 /* Dummy value. */ 37 38 static void * 39 dlopen (const char *file, int mode ATTRIBUTE_UNUSED) 40 { 41 return LoadLibrary (file); 42 } 43 44 static void * 45 dlsym (void *handle, const char *name) 46 { 47 return (void *) GetProcAddress ((HMODULE) handle, name); 48 } 49 50 static int ATTRIBUTE_UNUSED 51 dlclose (void *handle) 52 { 53 FreeLibrary ((HMODULE) handle); 54 return 0; 55 } 56 57 static const char * 58 dlerror (void) 59 { 60 return _("Unable to load DLL."); 61 } 62 63 #endif /* !defined (HAVE_DLFCN_H) && defined (HAVE_WINDOWS_H) */ 64 65 #define CONFIG_ENV_NAME "XTENSA_GNU_CONFIG" 66 67 const void *xtensa_load_config (const char *name ATTRIBUTE_UNUSED, 68 const void *no_plugin_def, 69 const void *no_name_def ATTRIBUTE_UNUSED) 70 { 71 static int init; 72 #if BFD_SUPPORTS_PLUGINS 73 static void *handle; 74 void *p; 75 76 if (!init) 77 { 78 const char *path = getenv (CONFIG_ENV_NAME); 79 80 init = 1; 81 if (!path) 82 return no_plugin_def; 83 handle = dlopen (path, RTLD_LAZY); 84 if (!handle) 85 { 86 _bfd_error_handler (_("%s is defined but could not be loaded: %s"), 87 CONFIG_ENV_NAME, dlerror ()); 88 abort (); 89 } 90 } 91 else if (!handle) 92 { 93 return no_plugin_def; 94 } 95 96 p = dlsym (handle, name); 97 if (!p) 98 { 99 if (no_name_def) 100 return no_name_def; 101 102 _bfd_error_handler (_("%s is loaded but symbol \"%s\" is not found: %s"), 103 CONFIG_ENV_NAME, name, dlerror ()); 104 abort (); 105 } 106 return p; 107 #else 108 if (!init) 109 { 110 const char *path = getenv (CONFIG_ENV_NAME); 111 112 init = 1; 113 if (path) 114 { 115 _bfd_error_handler (_("%s is defined but plugin support is disabled"), 116 CONFIG_ENV_NAME); 117 abort (); 118 } 119 } 120 return no_plugin_def; 121 #endif 122 } 123 124 XTENSA_CONFIG_INSTANCE_LIST; 125 126 const struct xtensa_config_v1 *xtensa_get_config_v1 (void) 127 { 128 static const struct xtensa_config_v1 *config; 129 130 if (!config) 131 config = (const struct xtensa_config_v1 *) xtensa_load_config ("xtensa_config_v1", 132 &xtensa_config_v1, 133 NULL); 134 return config; 135 } 136 137 const struct xtensa_config_v2 *xtensa_get_config_v2 (void) 138 { 139 static const struct xtensa_config_v2 *config; 140 static const struct xtensa_config_v2 def; 141 142 if (!config) 143 config = (const struct xtensa_config_v2 *) xtensa_load_config ("xtensa_config_v2", 144 &xtensa_config_v2, 145 &def); 146 return config; 147 } 148