| Ulrich Drepper | b08d5a8 | 2005-07-26 05:00:05 +0000 | [diff] [blame^] | 1 | /* Generate ELF backend handle. | 
 | 2 |    Copyright (C) 2000, 2001, 2002, 2003, 2004, 2005 Red Hat, Inc. | 
 | 3 |  | 
 | 4 |    This program is Open Source software; you can redistribute it and/or | 
 | 5 |    modify it under the terms of the Open Software License version 1.0 as | 
 | 6 |    published by the Open Source Initiative. | 
 | 7 |  | 
 | 8 |    You should have received a copy of the Open Software License along | 
 | 9 |    with this program; if not, you may obtain a copy of the Open Software | 
 | 10 |    License version 1.0 from http://www.opensource.org/licenses/osl.php or | 
 | 11 |    by writing the Open Source Initiative c/o Lawrence Rosen, Esq., | 
 | 12 |    3001 King Ranch Road, Ukiah, CA 95482.   */ | 
 | 13 |  | 
 | 14 | #ifdef HAVE_CONFIG_H | 
 | 15 | # include <config.h> | 
 | 16 | #endif | 
 | 17 |  | 
 | 18 | #include <assert.h> | 
 | 19 | #include <dlfcn.h> | 
 | 20 | #include <error.h> | 
 | 21 | #include <gelf.h> | 
 | 22 | #include <stdlib.h> | 
 | 23 | #include <string.h> | 
 | 24 |  | 
 | 25 | #include <libeblP.h> | 
 | 26 |  | 
 | 27 |  | 
 | 28 | /* This table should contain the complete list of architectures as far | 
 | 29 |    as the ELF specification is concerned.  */ | 
 | 30 | /* XXX When things are stable replace the string pointers with char | 
 | 31 |    arrays to avoid relocations.  */ | 
 | 32 | static const struct | 
 | 33 | { | 
 | 34 |   const char *dsoname; | 
 | 35 |   const char *emulation; | 
 | 36 |   const char *prefix; | 
 | 37 |   int prefix_len; | 
 | 38 |   int em; | 
 | 39 | } machines[] = | 
 | 40 | { | 
 | 41 |   { "i386", "elf_i386", "i386", 4, EM_386 }, | 
 | 42 |   { "ia64", "elf_ia64", "ia64", 4, EM_IA_64 }, | 
 | 43 |   { "alpha", "elf_alpha", "alpha", 5, EM_ALPHA }, | 
 | 44 |   { "x86_64", "elf_x86_64", "x86_64", 6, EM_X86_64 }, | 
 | 45 |   { "sh", "elf_sh", "sh", 2, EM_SH }, | 
 | 46 |   { "arm", "ebl_arm", "arm", 3, EM_ARM }, | 
 | 47 |   { "sparc", "elf_sparcv9", "sparc", 5, EM_SPARCV9 }, | 
 | 48 |   { "sparc", "elf_sparc", "sparc", 5, EM_SPARC }, | 
 | 49 |   { "sparc", "elf_sparcv8plus", "sparc", 5, EM_SPARC32PLUS }, | 
 | 50 |  | 
 | 51 |   { "m32", "elf_m32", "m32", 3, EM_M32 }, | 
 | 52 |   { "m68k", "elf_m68k", "m68k", 4, EM_68K }, | 
 | 53 |   { "m88k", "elf_m88k", "m88k", 4, EM_88K }, | 
 | 54 |   { "i860", "elf_i860", "i860", 4, EM_860 }, | 
 | 55 |   { "mips", "elf_mips", "mips", 4, EM_MIPS }, | 
 | 56 |   { "s370", "ebl_s370", "s370", 4, EM_S370 }, | 
 | 57 |   { "mips", "elf_mipsel", "mips", 4, EM_MIPS_RS3_LE }, | 
 | 58 |   { "parisc", "elf_parisc", "parisc", 6, EM_PARISC }, | 
 | 59 |   { "vpp500", "elf_vpp500", "vpp500", 5, EM_VPP500 }, | 
 | 60 |   { "sparc", "elf_v8plus", "v8plus", 6, EM_SPARC32PLUS }, | 
 | 61 |   { "i960", "elf_i960", "i960", 4, EM_960 }, | 
 | 62 |   { "ppc", "elf_ppc", "ppc", 3, EM_PPC }, | 
 | 63 |   { "ppc64", "elf_ppc64", "ppc64", 5, EM_PPC64 }, | 
 | 64 |   { "s390", "ebl_s390", "s390", 4, EM_S390 }, | 
 | 65 |   { "v800", "ebl_v800", "v800", 4, EM_V800 }, | 
 | 66 |   { "fr20", "ebl_fr20", "fr20", 4, EM_FR20 }, | 
 | 67 |   { "rh32", "ebl_rh32", "rh32", 4, EM_RH32 }, | 
 | 68 |   { "rce", "ebl_rce", "rce", 3, EM_RCE }, | 
 | 69 |   { "tricore", "elf_tricore", "tricore", 7, EM_TRICORE }, | 
 | 70 |   { "arc", "elf_arc", "arc", 3, EM_ARC }, | 
 | 71 |   { "h8", "elf_h8_300", "h8_300", 6, EM_H8_300 }, | 
 | 72 |   { "h8", "elf_h8_300h", "h8_300h", 6, EM_H8_300H }, | 
 | 73 |   { "h8", "elf_h8s", "h8s", 6, EM_H8S }, | 
 | 74 |   { "h8", "elf_h8_500", "h8_500", 6, EM_H8_500 }, | 
 | 75 |   { "mips_x", "elf_mips_x", "mips_x", 6, EM_MIPS_X }, | 
 | 76 |   { "coldfire", "elf_coldfire", "coldfire", 8, EM_COLDFIRE }, | 
 | 77 |   { "m68k", "elf_68hc12", "68hc12", 6, EM_68HC12 }, | 
 | 78 |   { "mma", "elf_mma", "mma", 3, EM_MMA }, | 
 | 79 |   { "pcp", "elf_pcp", "pcp", 3, EM_PCP }, | 
 | 80 |   { "ncpu", "elf_ncpu", "ncpu", 4, EM_NCPU }, | 
 | 81 |   { "ndr1", "elf_ndr1", "ndr1", 4, EM_NDR1 }, | 
 | 82 |   { "starcore", "elf_starcore", "starcore", 8, EM_STARCORE }, | 
 | 83 |   { "me16", "elf_me16", "em16", 4, EM_ME16 }, | 
 | 84 |   { "st100", "elf_st100", "st100", 5, EM_ST100 }, | 
 | 85 |   { "tinyj", "elf_tinyj", "tinyj", 5, EM_TINYJ }, | 
 | 86 |   { "pdsp", "elf_pdsp", "pdsp", 4, EM_PDSP }, | 
 | 87 |   { "fx66", "elf_fx66", "fx66", 4, EM_FX66 }, | 
 | 88 |   { "st9plus", "elf_st9plus", "st9plus", 7, EM_ST9PLUS }, | 
 | 89 |   { "st7", "elf_st7", "st7", 3, EM_ST7 }, | 
 | 90 |   { "m68k", "elf_68hc16", "68hc16", 6, EM_68HC16 }, | 
 | 91 |   { "m68k", "elf_68hc11", "68hc11", 6, EM_68HC11 }, | 
 | 92 |   { "m68k", "elf_68hc08", "68hc08", 6, EM_68HC08 }, | 
 | 93 |   { "m68k", "elf_68hc05", "68hc05", 6, EM_68HC05 }, | 
 | 94 |   { "svx", "elf_svx", "svx", 3, EM_SVX }, | 
 | 95 |   { "st19", "elf_st19", "st19", 4, EM_ST19 }, | 
 | 96 |   { "vax", "elf_vax", "vax", 3, EM_VAX }, | 
 | 97 |   { "cris", "elf_cris", "cris", 4, EM_CRIS }, | 
 | 98 |   { "javelin", "elf_javelin", "javelin", 7, EM_JAVELIN }, | 
 | 99 |   { "firepath", "elf_firepath", "firepath", 8, EM_FIREPATH }, | 
 | 100 |   { "zsp", "elf_zsp", "zsp", 3, EM_ZSP}, | 
 | 101 |   { "mmix", "elf_mmix", "mmix", 4, EM_MMIX }, | 
 | 102 |   { "hunay", "elf_huany", "huany", 5, EM_HUANY }, | 
 | 103 |   { "prism", "elf_prism", "prism", 5, EM_PRISM }, | 
 | 104 |   { "avr", "elf_avr", "avr", 3, EM_AVR }, | 
 | 105 |   { "fr30", "elf_fr30", "fr30", 4, EM_FR30 }, | 
 | 106 |   { "dv10", "elf_dv10", "dv10", 4, EM_D10V }, | 
 | 107 |   { "dv30", "elf_dv30", "dv30", 4, EM_D30V }, | 
 | 108 |   { "v850", "elf_v850", "v850", 4, EM_V850 }, | 
 | 109 |   { "m32r", "elf_m32r", "m32r", 4, EM_M32R }, | 
 | 110 |   { "mn10300", "elf_mn10300", "mn10300", 7, EM_MN10300 }, | 
 | 111 |   { "mn10200", "elf_mn10200", "mn10200", 7, EM_MN10200 }, | 
 | 112 |   { "pj", "elf_pj", "pj", 2, EM_PJ }, | 
 | 113 |   { "openrisc", "elf_openrisc", "openrisc", 8, EM_OPENRISC }, | 
 | 114 |   { "arc", "elf_arc_a5", "arc_a5", 6, EM_ARC_A5 }, | 
 | 115 |   { "xtensa", "elf_xtensa", "xtensa", 6, EM_XTENSA }, | 
 | 116 | }; | 
 | 117 | #define nmachines (sizeof (machines) / sizeof (machines[0])) | 
 | 118 |  | 
 | 119 |  | 
 | 120 | /* Default callbacks.  Mostly they just return the error value.  */ | 
 | 121 | static const char *default_object_type_name (int ignore, char *buf, | 
 | 122 | 					     size_t len); | 
 | 123 | static const char *default_reloc_type_name (int ignore, char *buf, size_t len); | 
 | 124 | static bool default_reloc_type_check (int ignore); | 
 | 125 | static bool default_reloc_valid_use (Elf *elf, int ignore); | 
 | 126 | static Elf_Type default_reloc_simple_type (Elf *elf, int ignore); | 
 | 127 | static bool default_gotpc_reloc_check (Elf *elf, int ignore); | 
 | 128 | static const char *default_segment_type_name (int ignore, char *buf, | 
 | 129 | 					      size_t len); | 
 | 130 | static const char *default_section_type_name (int ignore, char *buf, | 
 | 131 | 					      size_t len); | 
 | 132 | static const char *default_section_name (int ignore, int ignore2, char *buf, | 
 | 133 | 					 size_t len); | 
 | 134 | static const char *default_machine_flag_name (Elf64_Word *ignore); | 
 | 135 | static bool default_machine_flag_check (Elf64_Word flags); | 
 | 136 | static const char *default_symbol_type_name (int ignore, char *buf, | 
 | 137 | 					     size_t len); | 
 | 138 | static const char *default_symbol_binding_name (int ignore, char *buf, | 
 | 139 | 						size_t len); | 
 | 140 | static const char *default_dynamic_tag_name (int64_t ignore, char *buf, | 
 | 141 | 					     size_t len); | 
 | 142 | static bool default_dynamic_tag_check (int64_t ignore); | 
 | 143 | static GElf_Word default_sh_flags_combine (GElf_Word flags1, GElf_Word flags2); | 
 | 144 | static const char *default_osabi_name (int ignore, char *buf, size_t len); | 
 | 145 | static void default_destr (struct ebl *ignore); | 
 | 146 | static const char *default_core_note_type_name (uint32_t, char *buf, | 
 | 147 | 						size_t len); | 
 | 148 | static const char *default_object_note_type_name (uint32_t, char *buf, | 
 | 149 | 						  size_t len); | 
 | 150 | static bool default_core_note (const char *name, uint32_t type, | 
 | 151 | 			       uint32_t descsz, const char *desc); | 
 | 152 | static bool default_object_note (const char *name, uint32_t type, | 
 | 153 | 				 uint32_t descsz, const char *desc); | 
 | 154 | static bool default_debugscn_p (const char *name); | 
 | 155 | static bool default_copy_reloc_p (int reloc); | 
 | 156 |  | 
 | 157 |  | 
 | 158 | static void | 
 | 159 | fill_defaults (Ebl *result) | 
 | 160 | { | 
 | 161 |   result->object_type_name = default_object_type_name; | 
 | 162 |   result->reloc_type_name = default_reloc_type_name; | 
 | 163 |   result->reloc_type_check = default_reloc_type_check; | 
 | 164 |   result->reloc_valid_use = default_reloc_valid_use; | 
 | 165 |   result->reloc_simple_type = default_reloc_simple_type; | 
 | 166 |   result->gotpc_reloc_check = default_gotpc_reloc_check; | 
 | 167 |   result->segment_type_name = default_segment_type_name; | 
 | 168 |   result->section_type_name = default_section_type_name; | 
 | 169 |   result->section_name = default_section_name; | 
 | 170 |   result->machine_flag_name = default_machine_flag_name; | 
 | 171 |   result->machine_flag_check = default_machine_flag_check; | 
 | 172 |   result->symbol_type_name = default_symbol_type_name; | 
 | 173 |   result->symbol_binding_name = default_symbol_binding_name; | 
 | 174 |   result->dynamic_tag_name = default_dynamic_tag_name; | 
 | 175 |   result->dynamic_tag_check = default_dynamic_tag_check; | 
 | 176 |   result->sh_flags_combine = default_sh_flags_combine; | 
 | 177 |   result->osabi_name = default_osabi_name; | 
 | 178 |   result->core_note_type_name = default_core_note_type_name; | 
 | 179 |   result->object_note_type_name = default_object_note_type_name; | 
 | 180 |   result->core_note = default_core_note; | 
 | 181 |   result->object_note = default_object_note; | 
 | 182 |   result->debugscn_p = default_debugscn_p; | 
 | 183 |   result->copy_reloc_p = default_copy_reloc_p; | 
 | 184 |   result->destr = default_destr; | 
 | 185 | } | 
 | 186 |  | 
 | 187 |  | 
 | 188 | /* Find an appropriate backend for the file associated with ELF.  */ | 
 | 189 | static Ebl * | 
 | 190 | openbackend (elf, emulation, machine) | 
 | 191 |      Elf *elf; | 
 | 192 |      const char *emulation; | 
 | 193 |      GElf_Half machine; | 
 | 194 | { | 
 | 195 |   Ebl *result; | 
 | 196 |   size_t cnt; | 
 | 197 |  | 
 | 198 |   /* First allocate the data structure for the result.  We do this | 
 | 199 |      here since this assures that the structure is always large | 
 | 200 |      enough.  */ | 
 | 201 |   result = (Ebl *) calloc (1, sizeof (Ebl)); | 
 | 202 |   if (result == NULL) | 
 | 203 |     { | 
 | 204 |       // XXX uncomment | 
 | 205 |       // __libebl_seterror (ELF_E_NOMEM); | 
 | 206 |       return NULL; | 
 | 207 |     } | 
 | 208 |  | 
 | 209 |   /* Fill in the default callbacks.  The initializer for the machine | 
 | 210 |      specific module can overwrite the values.  */ | 
 | 211 |   fill_defaults (result); | 
 | 212 |  | 
 | 213 |   /* XXX Currently all we do is to look at 'e_machine' value in the | 
 | 214 |      ELF header.  With an internal mapping table from EM_* value to | 
 | 215 |      DSO name we try to load the appropriate module to handle this | 
 | 216 |      binary type. | 
 | 217 |  | 
 | 218 |      Multiple modules for the same machine type are possible and they | 
 | 219 |      will be tried in sequence.  The lookup process will only stop | 
 | 220 |      when a module which can handle the machine type is found or all | 
 | 221 |      available matching modules are tried.  */ | 
 | 222 |   for (cnt = 0; cnt < nmachines; ++cnt) | 
 | 223 |     if ((emulation != NULL && strcmp (emulation, machines[cnt].emulation) == 0) | 
 | 224 | 	|| (emulation == NULL && machines[cnt].em == machine)) | 
 | 225 |       { | 
 | 226 | 	/* Well, we know the emulation name now.  */ | 
 | 227 | 	result->emulation = machines[cnt].emulation; | 
 | 228 |  | 
 | 229 | #ifndef LIBEBL_SUBDIR | 
 | 230 | # define LIBEBL_SUBDIR PACKAGE | 
 | 231 | #endif | 
 | 232 | #define ORIGINDIR "$ORIGIN/../$LIB/" LIBEBL_SUBDIR "/" | 
 | 233 |  | 
 | 234 | 	/* Give it a try.  At least the machine type matches.  First | 
 | 235 |            try to load the module.  */ | 
 | 236 | 	char dsoname[100]; | 
 | 237 | 	strcpy (stpcpy (stpcpy (dsoname, ORIGINDIR "libebl_"), | 
 | 238 | 			machines[cnt].dsoname), | 
 | 239 | 		".so"); | 
 | 240 |  | 
 | 241 | 	void *h = dlopen (dsoname, RTLD_LAZY); | 
 | 242 | 	if (h == NULL) | 
 | 243 | 	  { | 
 | 244 | 	    strcpy (stpcpy (stpcpy (dsoname, "libebl_"), | 
 | 245 | 			    machines[cnt].dsoname), | 
 | 246 | 		    ".so"); | 
 | 247 | 	    h = dlopen (dsoname, RTLD_LAZY); | 
 | 248 | 	  } | 
 | 249 |  | 
 | 250 | 	  /* Try without an explicit path.  */ | 
 | 251 | 	if (h != NULL) | 
 | 252 | 	  { | 
 | 253 | 	    /* We managed to load the object.  Now see whether the | 
 | 254 | 	       initialization function likes our file.  */ | 
 | 255 | 	    static const char version[] = MODVERSION; | 
 | 256 | 	    const char *modversion; | 
 | 257 | 	    ebl_bhinit_t initp; | 
 | 258 | 	    char symname[machines[cnt].prefix_len + sizeof "_init"]; | 
 | 259 |  | 
 | 260 | 	    strcpy (mempcpy (symname, machines[cnt].prefix, | 
 | 261 | 			     machines[cnt].prefix_len), "_init"); | 
 | 262 |  | 
 | 263 | 	    initp = (ebl_bhinit_t) dlsym (h, symname); | 
 | 264 | 	    if (initp != NULL | 
 | 265 | 		&& (modversion = initp (elf, machine, result, sizeof (Ebl))) | 
 | 266 | 		&& strcmp (version, modversion) == 0) | 
 | 267 | 	      { | 
 | 268 | 		/* We found a module to handle our file.  */ | 
 | 269 | 		result->dlhandle = h; | 
 | 270 | 		result->elf = elf; | 
 | 271 |  | 
 | 272 | 		/* A few entries are mandatory.  */ | 
 | 273 | 		assert (result->name != NULL); | 
 | 274 | 		assert (result->destr != NULL); | 
 | 275 |  | 
 | 276 | 		return result; | 
 | 277 | 	      } | 
 | 278 |  | 
 | 279 | 	    /* Not the module we need.  */ | 
 | 280 | 	    (void) dlclose (h); | 
 | 281 | 	  } | 
 | 282 |  | 
 | 283 | 	/* We cannot find a DSO but the emulation/machine ID matches. | 
 | 284 | 	   Return that information.  */ | 
 | 285 | 	result->dlhandle = NULL; | 
 | 286 | 	result->elf = elf; | 
 | 287 | 	result->name = machines[cnt].prefix; | 
 | 288 | 	fill_defaults (result); | 
 | 289 |  | 
 | 290 | 	return result; | 
 | 291 |       } | 
 | 292 |  | 
 | 293 |   /* Nothing matched.  We use only the default callbacks.   */ | 
 | 294 |   result->dlhandle = NULL; | 
 | 295 |   result->elf = elf; | 
 | 296 |   result->emulation = "<unknown>"; | 
 | 297 |   result->name = "<unknown>"; | 
 | 298 |   fill_defaults (result); | 
 | 299 |  | 
 | 300 |   return result; | 
 | 301 | } | 
 | 302 |  | 
 | 303 |  | 
 | 304 | /* Find an appropriate backend for the file associated with ELF.  */ | 
 | 305 | Ebl * | 
 | 306 | ebl_openbackend (elf) | 
 | 307 |      Elf *elf; | 
 | 308 | { | 
 | 309 |   GElf_Ehdr ehdr_mem; | 
 | 310 |   GElf_Ehdr *ehdr; | 
 | 311 |  | 
 | 312 |   /* Get the ELF header of the object.  */ | 
 | 313 |   ehdr = gelf_getehdr (elf, &ehdr_mem); | 
 | 314 |   if (ehdr == NULL) | 
 | 315 |     { | 
 | 316 |       // XXX uncomment | 
 | 317 |       // __libebl_seterror (elf_errno ()); | 
 | 318 |       return NULL; | 
 | 319 |     } | 
 | 320 |  | 
 | 321 |   return openbackend (elf, NULL, ehdr->e_machine); | 
 | 322 | } | 
 | 323 |  | 
 | 324 |  | 
 | 325 | /* Find backend without underlying ELF file.  */ | 
 | 326 | Ebl * | 
 | 327 | ebl_openbackend_machine (machine) | 
 | 328 |      GElf_Half machine; | 
 | 329 | { | 
 | 330 |   return openbackend (NULL, NULL, machine); | 
 | 331 | } | 
 | 332 |  | 
 | 333 |  | 
 | 334 | /* Find backend with given emulation name.  */ | 
 | 335 | Ebl * | 
 | 336 | ebl_openbackend_emulation (const char *emulation) | 
 | 337 | { | 
 | 338 |   return openbackend (NULL, emulation, EM_NONE); | 
 | 339 | } | 
 | 340 |  | 
 | 341 |  | 
 | 342 | /* Default callbacks.  Mostly they just return the error value.  */ | 
 | 343 | static const char * | 
 | 344 | default_object_type_name (int ignore __attribute__ ((unused)), | 
 | 345 | 			  char *buf __attribute__ ((unused)), | 
 | 346 | 			  size_t len __attribute__ ((unused))) | 
 | 347 | { | 
 | 348 |   return NULL; | 
 | 349 | } | 
 | 350 |  | 
 | 351 | static const char * | 
 | 352 | default_reloc_type_name (int ignore __attribute__ ((unused)), | 
 | 353 | 			 char *buf __attribute__ ((unused)), | 
 | 354 | 			 size_t len __attribute__ ((unused))) | 
 | 355 | { | 
 | 356 |   return NULL; | 
 | 357 | } | 
 | 358 |  | 
 | 359 | static bool | 
 | 360 | default_reloc_type_check (int ignore __attribute__ ((unused))) | 
 | 361 | { | 
 | 362 |   return false; | 
 | 363 | } | 
 | 364 |  | 
 | 365 | static bool | 
 | 366 | default_reloc_valid_use (Elf *elf __attribute__ ((unused)), | 
 | 367 | 			 int ignore __attribute__ ((unused))) | 
 | 368 | { | 
 | 369 |   return false; | 
 | 370 | } | 
 | 371 |  | 
 | 372 | static Elf_Type | 
 | 373 | default_reloc_simple_type (Elf *elf __attribute__ ((unused)), | 
 | 374 | 			   int ignore __attribute__ ((unused))) | 
 | 375 | { | 
 | 376 |   return ELF_T_NUM; | 
 | 377 | } | 
 | 378 |  | 
 | 379 | static bool | 
 | 380 | default_gotpc_reloc_check (Elf *elf __attribute__ ((unused)), | 
 | 381 | 			   int ignore __attribute__ ((unused))) | 
 | 382 | { | 
 | 383 |   return false; | 
 | 384 | } | 
 | 385 |  | 
 | 386 | static const char * | 
 | 387 | default_segment_type_name (int ignore __attribute__ ((unused)), | 
 | 388 | 			   char *buf __attribute__ ((unused)), | 
 | 389 | 			   size_t len __attribute__ ((unused))) | 
 | 390 | { | 
 | 391 |   return NULL; | 
 | 392 | } | 
 | 393 |  | 
 | 394 | static const char * | 
 | 395 | default_section_type_name (int ignore __attribute__ ((unused)), | 
 | 396 | 			   char *buf __attribute__ ((unused)), | 
 | 397 | 			   size_t len __attribute__ ((unused))) | 
 | 398 | { | 
 | 399 |   return NULL; | 
 | 400 | } | 
 | 401 |  | 
 | 402 | static const char * | 
 | 403 | default_section_name (int ignore __attribute__ ((unused)), | 
 | 404 | 		      int ignore2 __attribute__ ((unused)), | 
 | 405 | 		      char *buf __attribute__ ((unused)), | 
 | 406 | 		      size_t len __attribute__ ((unused))) | 
 | 407 | { | 
 | 408 |   return NULL; | 
 | 409 | } | 
 | 410 |  | 
 | 411 | static const char * | 
 | 412 | default_machine_flag_name (Elf64_Word *ignore __attribute__ ((unused))) | 
 | 413 | { | 
 | 414 |   return NULL; | 
 | 415 | } | 
 | 416 |  | 
 | 417 | static bool | 
 | 418 | default_machine_flag_check (Elf64_Word flags __attribute__ ((unused))) | 
 | 419 | { | 
 | 420 |   return flags == 0; | 
 | 421 | } | 
 | 422 |  | 
 | 423 | static const char * | 
 | 424 | default_symbol_type_name (int ignore __attribute__ ((unused)), | 
 | 425 | 			  char *buf __attribute__ ((unused)), | 
 | 426 | 			  size_t len __attribute__ ((unused))) | 
 | 427 | { | 
 | 428 |   return NULL; | 
 | 429 | } | 
 | 430 |  | 
 | 431 | static const char * | 
 | 432 | default_symbol_binding_name (int ignore __attribute__ ((unused)), | 
 | 433 | 			     char *buf __attribute__ ((unused)), | 
 | 434 | 			     size_t len __attribute__ ((unused))) | 
 | 435 | { | 
 | 436 |   return NULL; | 
 | 437 | } | 
 | 438 |  | 
 | 439 | static const char * | 
 | 440 | default_dynamic_tag_name (int64_t ignore __attribute__ ((unused)), | 
 | 441 | 			  char *buf __attribute__ ((unused)), | 
 | 442 | 			  size_t len __attribute__ ((unused))) | 
 | 443 | { | 
 | 444 |   return NULL; | 
 | 445 | } | 
 | 446 |  | 
 | 447 | static bool | 
 | 448 | default_dynamic_tag_check (int64_t ignore __attribute__ ((unused))) | 
 | 449 | { | 
 | 450 |   return false; | 
 | 451 | } | 
 | 452 |  | 
 | 453 | static GElf_Word | 
 | 454 | default_sh_flags_combine (GElf_Word flags1, GElf_Word flags2) | 
 | 455 | { | 
 | 456 |   return SH_FLAGS_COMBINE (flags1, flags2); | 
 | 457 | } | 
 | 458 |  | 
 | 459 | static void | 
 | 460 | default_destr (struct ebl *ignore __attribute__ ((unused))) | 
 | 461 | { | 
 | 462 | } | 
 | 463 |  | 
 | 464 | static const char * | 
 | 465 | default_osabi_name (int ignore __attribute__ ((unused)), | 
 | 466 | 		    char *buf __attribute__ ((unused)), | 
 | 467 | 		    size_t len __attribute__ ((unused))) | 
 | 468 | { | 
 | 469 |   return NULL; | 
 | 470 | } | 
 | 471 |  | 
 | 472 | static const char * | 
 | 473 | default_core_note_type_name (uint32_t ignore __attribute__ ((unused)), | 
 | 474 | 			     char *buf __attribute__ ((unused)), | 
 | 475 | 			     size_t len __attribute__ ((unused))) | 
 | 476 | { | 
 | 477 |   return NULL; | 
 | 478 | } | 
 | 479 |  | 
 | 480 | static const char * | 
 | 481 | default_object_note_type_name (uint32_t ignore __attribute__ ((unused)), | 
 | 482 | 			       char *buf __attribute__ ((unused)), | 
 | 483 | 			       size_t len __attribute__ ((unused))) | 
 | 484 | { | 
 | 485 |   return NULL; | 
 | 486 | } | 
 | 487 |  | 
 | 488 | static bool | 
 | 489 | default_core_note (const char *name __attribute__ ((unused)), | 
 | 490 | 		   uint32_t type __attribute__ ((unused)), | 
 | 491 | 		   uint32_t descsz __attribute__ ((unused)), | 
 | 492 | 		   const char *desc __attribute__ ((unused))) | 
 | 493 | { | 
 | 494 |   return NULL; | 
 | 495 | } | 
 | 496 |  | 
 | 497 | static bool | 
 | 498 | default_object_note (const char *name __attribute__ ((unused)), | 
 | 499 | 		     uint32_t type __attribute__ ((unused)), | 
 | 500 | 		     uint32_t descsz __attribute__ ((unused)), | 
 | 501 | 		     const char *desc __attribute__ ((unused))) | 
 | 502 | { | 
 | 503 |   return NULL; | 
 | 504 | } | 
 | 505 |  | 
 | 506 | static bool | 
 | 507 | default_debugscn_p (const char *name) | 
 | 508 | { | 
 | 509 |   /* We know by default only about the DWARF debug sections which have | 
 | 510 |      fixed names.  */ | 
 | 511 |   static const char *dwarf_scn_names[] = | 
 | 512 |     { | 
 | 513 |       /* DWARF 1 */ | 
 | 514 |       ".debug", | 
 | 515 |       ".line", | 
 | 516 |       /* GNU DWARF 1 extensions */ | 
 | 517 |       ".debug_srcinfo", | 
 | 518 |       ".debug_sfnames", | 
 | 519 |       /* DWARF 1.1 and DWARF 2 */ | 
 | 520 |       ".debug_aranges", | 
 | 521 |       ".debug_pubnames", | 
 | 522 |       /* DWARF 2 */ | 
 | 523 |       ".debug_info", | 
 | 524 |       ".debug_abbrev", | 
 | 525 |       ".debug_line", | 
 | 526 |       ".debug_frame", | 
 | 527 |       ".debug_str", | 
 | 528 |       ".debug_loc", | 
 | 529 |       ".debug_macinfo", | 
 | 530 |       /* DWARF 3 */ | 
 | 531 |       ".debug_ranges", | 
 | 532 |       /* SGI/MIPS DWARF 2 extensions */ | 
 | 533 |       ".debug_weaknames", | 
 | 534 |       ".debug_funcnames", | 
 | 535 |       ".debug_typenames", | 
 | 536 |       ".debug_varnames" | 
 | 537 |     }; | 
 | 538 |   const size_t ndwarf_scn_names = (sizeof (dwarf_scn_names) | 
 | 539 | 				   / sizeof (dwarf_scn_names[0])); | 
 | 540 |   for (size_t cnt = 0; cnt < ndwarf_scn_names; ++cnt) | 
 | 541 |     if (strcmp (name, dwarf_scn_names[cnt]) == 0) | 
 | 542 |       return true; | 
 | 543 |  | 
 | 544 |   return false; | 
 | 545 | } | 
 | 546 |  | 
 | 547 | static bool | 
 | 548 | default_copy_reloc_p (int reloc __attribute__ ((unused))) | 
 | 549 | { | 
 | 550 |   return false; | 
 | 551 | } |