Blame libebl/eblopenbackend.c

Packit 032894
/* Generate ELF backend handle.
Packit 032894
   Copyright (C) 2000-2017 Red Hat, Inc.
Packit 032894
   This file is part of elfutils.
Packit 032894
Packit 032894
   This file is free software; you can redistribute it and/or modify
Packit 032894
   it under the terms of either
Packit 032894
Packit 032894
     * the GNU Lesser General Public License as published by the Free
Packit 032894
       Software Foundation; either version 3 of the License, or (at
Packit 032894
       your option) any later version
Packit 032894
Packit 032894
   or
Packit 032894
Packit 032894
     * the GNU General Public License as published by the Free
Packit 032894
       Software Foundation; either version 2 of the License, or (at
Packit 032894
       your option) any later version
Packit 032894
Packit 032894
   or both in parallel, as here.
Packit 032894
Packit 032894
   elfutils is distributed in the hope that it will be useful, but
Packit 032894
   WITHOUT ANY WARRANTY; without even the implied warranty of
Packit 032894
   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
Packit 032894
   General Public License for more details.
Packit 032894
Packit 032894
   You should have received copies of the GNU General Public License and
Packit 032894
   the GNU Lesser General Public License along with this program.  If
Packit 032894
   not, see <http://www.gnu.org/licenses/>.  */
Packit 032894
Packit 032894
#ifdef HAVE_CONFIG_H
Packit 032894
# include <config.h>
Packit 032894
#endif
Packit 032894
Packit 032894
#include <assert.h>
Packit 032894
#include <dlfcn.h>
Packit 032894
#include <libelfP.h>
Packit 032894
#include <dwarf.h>
Packit 032894
#include <stdlib.h>
Packit 032894
#include <string.h>
Packit 032894
#include <stdio.h>
Packit 032894
Packit 032894
#include <system.h>
Packit 032894
#include <libeblP.h>
Packit 032894
Packit Service 35cfd5
Ebl *i386_init (Elf *, GElf_Half, Ebl *);
Packit Service 35cfd5
Ebl *sh_init (Elf *, GElf_Half, Ebl *);
Packit Service 35cfd5
Ebl *x86_64_init (Elf *, GElf_Half, Ebl *);
Packit Service 35cfd5
Ebl *ia64_init (Elf *, GElf_Half, Ebl *);
Packit Service 35cfd5
Ebl *alpha_init (Elf *, GElf_Half, Ebl *);
Packit Service 35cfd5
Ebl *arm_init (Elf *, GElf_Half, Ebl *);
Packit Service 35cfd5
Ebl *aarch64_init (Elf *, GElf_Half, Ebl *);
Packit Service 35cfd5
Ebl *sparc_init (Elf *, GElf_Half, Ebl *);
Packit Service 35cfd5
Ebl *ppc_init (Elf *, GElf_Half, Ebl *);
Packit Service 35cfd5
Ebl *ppc64_init (Elf *, GElf_Half, Ebl *);
Packit Service 35cfd5
Ebl *s390_init (Elf *, GElf_Half, Ebl *);
Packit Service 35cfd5
Ebl *tilegx_init (Elf *, GElf_Half, Ebl *);
Packit Service 35cfd5
Ebl *m68k_init (Elf *, GElf_Half, Ebl *);
Packit Service 35cfd5
Ebl *bpf_init (Elf *, GElf_Half, Ebl *);
Packit Service 35cfd5
Ebl *riscv_init (Elf *, GElf_Half, Ebl *);
Packit Service 35cfd5
Ebl *csky_init (Elf *, GElf_Half, Ebl *);
Packit 032894
Packit 032894
/* This table should contain the complete list of architectures as far
Packit 032894
   as the ELF specification is concerned.  */
Packit 032894
/* XXX When things are stable replace the string pointers with char
Packit 032894
   arrays to avoid relocations.  */
Packit 032894
static const struct
Packit 032894
{
Packit 032894
  ebl_bhinit_t init;
Packit 032894
  const char *emulation;
Packit 032894
  const char *prefix;
Packit 032894
  int prefix_len;
Packit 032894
  int em;
Packit 032894
  int class;
Packit 032894
  int data;
Packit 032894
} machines[] =
Packit 032894
{
Packit 032894
  { i386_init, "elf_i386", "i386", 4, EM_386, ELFCLASS32, ELFDATA2LSB },
Packit 032894
  { ia64_init, "elf_ia64", "ia64", 4, EM_IA_64, ELFCLASS64, ELFDATA2LSB },
Packit 032894
  { alpha_init, "elf_alpha", "alpha", 5, EM_ALPHA, ELFCLASS64, ELFDATA2LSB },
Packit 032894
  { x86_64_init, "elf_x86_64", "x86_64", 6, EM_X86_64, ELFCLASS64, ELFDATA2LSB },
Packit 032894
  { ppc_init, "elf_ppc", "ppc", 3, EM_PPC, ELFCLASS32, ELFDATA2MSB },
Packit 032894
  { ppc64_init, "elf_ppc64", "ppc64", 5, EM_PPC64, ELFCLASS64, ELFDATA2MSB },
Packit 032894
  { tilegx_init, "elf_tilegx", "tilegx", 6, EM_TILEGX, ELFCLASS64, ELFDATA2LSB },
Packit 032894
  // XXX class and machine fields need to be filled in for all archs.
Packit 032894
  { sh_init, "elf_sh", "sh", 2, EM_SH, 0, 0 },
Packit 032894
  { arm_init, "ebl_arm", "arm", 3, EM_ARM, 0, 0 },
Packit 032894
  { sparc_init, "elf_sparcv9", "sparc", 5, EM_SPARCV9, 0, 0 },
Packit 032894
  { sparc_init, "elf_sparc", "sparc", 5, EM_SPARC, 0, 0 },
Packit 032894
  { sparc_init, "elf_sparcv8plus", "sparc", 5, EM_SPARC32PLUS, 0, 0 },
Packit 032894
  { s390_init, "ebl_s390", "s390", 4, EM_S390, 0, 0 },
Packit 032894
Packit 032894
  { NULL, "elf_m32", "m32", 3, EM_M32, 0, 0 },
Packit 032894
  { m68k_init, "elf_m68k", "m68k", 4, EM_68K, ELFCLASS32, ELFDATA2MSB },
Packit 032894
  { NULL, "elf_m88k", "m88k", 4, EM_88K, 0, 0 },
Packit 032894
  { NULL, "elf_i860", "i860", 4, EM_860, 0, 0 },
Packit 032894
  { NULL, "ebl_s370", "s370", 4, EM_S370, 0, 0 },
Packit 032894
  { NULL, "elf_parisc", "parisc", 6, EM_PARISC, 0, 0 },
Packit 032894
  { NULL, "elf_vpp500", "vpp500", 5, EM_VPP500, 0, 0 },
Packit 032894
  { sparc_init, "elf_v8plus", "v8plus", 6, EM_SPARC32PLUS, 0, 0 },
Packit 032894
  { NULL, "elf_i960", "i960", 4, EM_960, 0, 0 },
Packit 032894
  { NULL, "ebl_v800", "v800", 4, EM_V800, 0, 0 },
Packit 032894
  { NULL, "ebl_fr20", "fr20", 4, EM_FR20, 0, 0 },
Packit 032894
  { NULL, "ebl_rh32", "rh32", 4, EM_RH32, 0, 0 },
Packit 032894
  { NULL, "ebl_rce", "rce", 3, EM_RCE, 0, 0 },
Packit 032894
  { NULL, "elf_tricore", "tricore", 7, EM_TRICORE, 0, 0 },
Packit 032894
  { NULL, "elf_arc", "arc", 3, EM_ARC, 0, 0 },
Packit 032894
  { NULL, "elf_h8_300", "h8_300", 6, EM_H8_300, 0, 0 },
Packit 032894
  { NULL, "elf_h8_300h", "h8_300h", 6, EM_H8_300H, 0, 0 },
Packit 032894
  { NULL, "elf_h8s", "h8s", 6, EM_H8S, 0, 0 },
Packit 032894
  { NULL, "elf_h8_500", "h8_500", 6, EM_H8_500, 0, 0 },
Packit 032894
  { NULL, "elf_coldfire", "coldfire", 8, EM_COLDFIRE, 0, 0 },
Packit 032894
  { m68k_init, "elf_68hc12", "68hc12", 6, EM_68HC12, 0, 0 },
Packit 032894
  { NULL, "elf_mma", "mma", 3, EM_MMA, 0, 0 },
Packit 032894
  { NULL, "elf_pcp", "pcp", 3, EM_PCP, 0, 0 },
Packit 032894
  { NULL, "elf_ncpu", "ncpu", 4, EM_NCPU, 0, 0 },
Packit 032894
  { NULL, "elf_ndr1", "ndr1", 4, EM_NDR1, 0, 0 },
Packit 032894
  { NULL, "elf_starcore", "starcore", 8, EM_STARCORE, 0, 0 },
Packit 032894
  { NULL, "elf_me16", "em16", 4, EM_ME16, 0, 0 },
Packit 032894
  { NULL, "elf_st100", "st100", 5, EM_ST100, 0, 0 },
Packit 032894
  { NULL, "elf_tinyj", "tinyj", 5, EM_TINYJ, 0, 0 },
Packit 032894
  { NULL, "elf_pdsp", "pdsp", 4, EM_PDSP, 0, 0 },
Packit 032894
  { NULL, "elf_fx66", "fx66", 4, EM_FX66, 0, 0 },
Packit 032894
  { NULL, "elf_st9plus", "st9plus", 7, EM_ST9PLUS, 0, 0 },
Packit 032894
  { NULL, "elf_st7", "st7", 3, EM_ST7, 0, 0 },
Packit 032894
  { m68k_init, "elf_68hc16", "68hc16", 6, EM_68HC16, 0, 0 },
Packit 032894
  { m68k_init, "elf_68hc11", "68hc11", 6, EM_68HC11, 0, 0 },
Packit 032894
  { m68k_init, "elf_68hc08", "68hc08", 6, EM_68HC08, 0, 0 },
Packit 032894
  { m68k_init, "elf_68hc05", "68hc05", 6, EM_68HC05, 0, 0 },
Packit 032894
  { NULL, "elf_svx", "svx", 3, EM_SVX, 0, 0 },
Packit 032894
  { NULL, "elf_st19", "st19", 4, EM_ST19, 0, 0 },
Packit 032894
  { NULL, "elf_vax", "vax", 3, EM_VAX, 0, 0 },
Packit 032894
  { NULL, "elf_cris", "cris", 4, EM_CRIS, 0, 0 },
Packit 032894
  { NULL, "elf_javelin", "javelin", 7, EM_JAVELIN, 0, 0 },
Packit 032894
  { NULL, "elf_firepath", "firepath", 8, EM_FIREPATH, 0, 0 },
Packit 032894
  { NULL, "elf_zsp", "zsp", 3, EM_ZSP, 0, 0 },
Packit 032894
  { NULL, "elf_mmix", "mmix", 4, EM_MMIX, 0, 0 },
Packit 032894
  { NULL, "elf_huany", "huany", 5, EM_HUANY, 0, 0 },
Packit 032894
  { NULL, "elf_prism", "prism", 5, EM_PRISM, 0, 0 },
Packit 032894
  { NULL, "elf_avr", "avr", 3, EM_AVR, 0, 0 },
Packit 032894
  { NULL, "elf_fr30", "fr30", 4, EM_FR30, 0, 0 },
Packit 032894
  { NULL, "elf_dv10", "dv10", 4, EM_D10V, 0, 0 },
Packit 032894
  { NULL, "elf_dv30", "dv30", 4, EM_D30V, 0, 0 },
Packit 032894
  { NULL, "elf_v850", "v850", 4, EM_V850, 0, 0 },
Packit 032894
  { NULL, "elf_m32r", "m32r", 4, EM_M32R, 0, 0 },
Packit 032894
  { NULL, "elf_mn10300", "mn10300", 7, EM_MN10300, 0, 0 },
Packit 032894
  { NULL, "elf_mn10200", "mn10200", 7, EM_MN10200, 0, 0 },
Packit 032894
  { NULL, "elf_pj", "pj", 2, EM_PJ, 0, 0 },
Packit 032894
  { NULL, "elf_openrisc", "openrisc", 8, EM_OPENRISC, 0, 0 },
Packit 032894
  { NULL, "elf_arc_a5", "arc_a5", 6, EM_ARC_A5, 0, 0 },
Packit 032894
  { NULL, "elf_xtensa", "xtensa", 6, EM_XTENSA, 0, 0 },
Packit 032894
  { aarch64_init, "elf_aarch64", "aarch64", 7, EM_AARCH64, ELFCLASS64, 0 },
Packit 032894
  { bpf_init, "elf_bpf", "bpf", 3, EM_BPF, 0, 0 },
Packit 032894
  { riscv_init, "elf_riscv", "riscv", 5, EM_RISCV, ELFCLASS64, ELFDATA2LSB },
Packit 032894
  { riscv_init, "elf_riscv", "riscv", 5, EM_RISCV, ELFCLASS32, ELFDATA2LSB },
Packit 032894
  { csky_init, "elf_csky", "csky", 4, EM_CSKY, ELFCLASS32, ELFDATA2LSB },
Packit 032894
};
Packit 032894
#define nmachines (sizeof (machines) / sizeof (machines[0]))
Packit 032894
Packit 032894
/* No machine prefix should be larger than this.  */
Packit 032894
#define MAX_PREFIX_LEN 16
Packit 032894
Packit 032894
/* Default callbacks.  Mostly they just return the error value.  */
Packit 032894
static const char *default_reloc_type_name (int ignore, char *buf, size_t len);
Packit 032894
static bool default_reloc_type_check (int ignore);
Packit 032894
static bool default_reloc_valid_use (Elf *elf, int ignore);
Packit 032894
static Elf_Type default_reloc_simple_type (Ebl *ebl, int ignore, int *addsub);
Packit 032894
static bool default_gotpc_reloc_check (Elf *elf, int ignore);
Packit 032894
static const char *default_segment_type_name (int ignore, char *buf,
Packit 032894
					      size_t len);
Packit 032894
static const char *default_section_type_name (int ignore, char *buf,
Packit 032894
					      size_t len);
Packit 032894
static const char *default_section_name (int ignore, int ignore2, char *buf,
Packit 032894
					 size_t len);
Packit 032894
static const char *default_machine_flag_name (Elf64_Word *ignore);
Packit 032894
static bool default_machine_flag_check (Elf64_Word flags);
Packit 032894
static bool default_machine_section_flag_check (GElf_Xword flags);
Packit 032894
static const char *default_symbol_type_name (int ignore, char *buf,
Packit 032894
					     size_t len);
Packit 032894
static const char *default_symbol_binding_name (int ignore, char *buf,
Packit 032894
						size_t len);
Packit 032894
static const char *default_dynamic_tag_name (int64_t ignore, char *buf,
Packit 032894
					     size_t len);
Packit 032894
static bool default_dynamic_tag_check (int64_t ignore);
Packit 032894
static const char *default_osabi_name (int ignore, char *buf, size_t len);
Packit 032894
static void default_destr (struct ebl *ignore);
Packit 032894
static const char *default_core_note_type_name (uint32_t, char *buf,
Packit 032894
						size_t len);
Packit 032894
static const char *default_object_note_type_name (const char *name, uint32_t,
Packit 032894
						  char *buf, size_t len);
Packit 032894
static int default_core_note (const GElf_Nhdr *nhdr, const char *name,
Packit 032894
			      GElf_Word *regs_offset, size_t *nregloc,
Packit 032894
			      const Ebl_Register_Location **reglocs,
Packit 032894
			      size_t *nitems, const Ebl_Core_Item **);
Packit 032894
static int default_auxv_info (GElf_Xword a_type,
Packit 032894
			      const char **name, const char **format);
Packit 032894
static bool default_object_note (const char *name, uint32_t type,
Packit 032894
				 uint32_t descsz, const char *desc);
Packit 032894
static bool default_debugscn_p (const char *name);
Packit 032894
static bool default_copy_reloc_p (int reloc);
Packit 032894
static bool default_none_reloc_p (int reloc);
Packit 032894
static bool default_relative_reloc_p (int reloc);
Packit 032894
static bool default_check_special_symbol (Elf *elf,
Packit 032894
					  const GElf_Sym *sym,
Packit 032894
					  const char *name,
Packit 032894
					  const GElf_Shdr *destshdr);
Packit 032894
static bool default_data_marker_symbol (const GElf_Sym *sym, const char *sname);
Packit 032894
static bool default_check_st_other_bits (unsigned char st_other);
Packit 032894
static bool default_check_special_section (Ebl *, int,
Packit 032894
					   const GElf_Shdr *, const char *);
Packit 032894
static bool default_bss_plt_p (Elf *elf);
Packit 032894
static int default_return_value_location (Dwarf_Die *functypedie,
Packit 032894
					  const Dwarf_Op **locops);
Packit 032894
static ssize_t default_register_info (Ebl *ebl,
Packit 032894
				      int regno, char *name, size_t namelen,
Packit 032894
				      const char **prefix,
Packit 032894
				      const char **setname,
Packit 032894
				      int *bits, int *type);
Packit 032894
static int default_syscall_abi (Ebl *ebl, int *sp, int *pc,
Packit 032894
				int *callno, int args[6]);
Packit 032894
static bool default_check_object_attribute (Ebl *ebl, const char *vendor,
Packit 032894
					    int tag, uint64_t value,
Packit 032894
					    const char **tag_name,
Packit 032894
					    const char **value_name);
Packit 032894
static bool default_check_reloc_target_type (Ebl *ebl, Elf64_Word sh_type);
Packit 032894
static int default_abi_cfi (Ebl *ebl, Dwarf_CIE *abi_info);
Packit 032894
Packit 032894
Packit 032894
static void
Packit 032894
fill_defaults (Ebl *result)
Packit 032894
{
Packit 032894
  result->reloc_type_name = default_reloc_type_name;
Packit 032894
  result->reloc_type_check = default_reloc_type_check;
Packit 032894
  result->reloc_valid_use = default_reloc_valid_use;
Packit 032894
  result->reloc_simple_type = default_reloc_simple_type;
Packit 032894
  result->gotpc_reloc_check = default_gotpc_reloc_check;
Packit 032894
  result->segment_type_name = default_segment_type_name;
Packit 032894
  result->section_type_name = default_section_type_name;
Packit 032894
  result->section_name = default_section_name;
Packit 032894
  result->machine_flag_name = default_machine_flag_name;
Packit 032894
  result->machine_flag_check = default_machine_flag_check;
Packit 032894
  result->machine_section_flag_check = default_machine_section_flag_check;
Packit 032894
  result->check_special_section = default_check_special_section;
Packit 032894
  result->symbol_type_name = default_symbol_type_name;
Packit 032894
  result->symbol_binding_name = default_symbol_binding_name;
Packit 032894
  result->dynamic_tag_name = default_dynamic_tag_name;
Packit 032894
  result->dynamic_tag_check = default_dynamic_tag_check;
Packit 032894
  result->osabi_name = default_osabi_name;
Packit 032894
  result->core_note_type_name = default_core_note_type_name;
Packit 032894
  result->object_note_type_name = default_object_note_type_name;
Packit 032894
  result->core_note = default_core_note;
Packit 032894
  result->auxv_info = default_auxv_info;
Packit 032894
  result->object_note = default_object_note;
Packit 032894
  result->debugscn_p = default_debugscn_p;
Packit 032894
  result->copy_reloc_p = default_copy_reloc_p;
Packit 032894
  result->none_reloc_p = default_none_reloc_p;
Packit 032894
  result->relative_reloc_p = default_relative_reloc_p;
Packit 032894
  result->check_special_symbol = default_check_special_symbol;
Packit 032894
  result->data_marker_symbol = default_data_marker_symbol;
Packit 032894
  result->check_st_other_bits = default_check_st_other_bits;
Packit 032894
  result->bss_plt_p = default_bss_plt_p;
Packit 032894
  result->return_value_location = default_return_value_location;
Packit 032894
  result->register_info = default_register_info;
Packit 032894
  result->syscall_abi = default_syscall_abi;
Packit 032894
  result->check_object_attribute = default_check_object_attribute;
Packit 032894
  result->check_reloc_target_type = default_check_reloc_target_type;
Packit 032894
  result->disasm = NULL;
Packit 032894
  result->abi_cfi = default_abi_cfi;
Packit 032894
  result->destr = default_destr;
Packit 032894
  result->sysvhash_entrysize = sizeof (Elf32_Word);
Packit 032894
}
Packit 032894
Packit 032894
/* Find an appropriate backend for the file associated with ELF.  */
Packit 032894
static Ebl *
Packit 032894
openbackend (Elf *elf, const char *emulation, GElf_Half machine)
Packit 032894
{
Packit 032894
  Ebl *result;
Packit 032894
  size_t cnt;
Packit 032894
Packit 032894
  /* First allocate the data structure for the result.  We do this
Packit 032894
     here since this assures that the structure is always large
Packit 032894
     enough.  */
Packit 032894
  result = (Ebl *) calloc (1, sizeof (Ebl));
Packit 032894
  if (result == NULL)
Packit 032894
    {
Packit 032894
      // XXX uncomment
Packit 032894
      // __libebl_seterror (ELF_E_NOMEM);
Packit 032894
      return NULL;
Packit 032894
    }
Packit 032894
Packit 032894
  /* Fill in the default callbacks.  The initializer for the machine
Packit 032894
     specific module can overwrite the values.  */
Packit 032894
  fill_defaults (result);
Packit 032894
Packit 032894
  /* XXX Currently all we do is to look at 'e_machine' value in the
Packit 032894
     ELF header.  With an internal mapping table from EM_* value to
Packit 032894
     DSO name we try to load the appropriate module to handle this
Packit 032894
     binary type.
Packit 032894
Packit 032894
     Multiple modules for the same machine type are possible and they
Packit 032894
     will be tried in sequence.  The lookup process will only stop
Packit 032894
     when a module which can handle the machine type is found or all
Packit 032894
     available matching modules are tried.  */
Packit 032894
  for (cnt = 0; cnt < nmachines; ++cnt)
Packit 032894
    if ((emulation != NULL && strcmp (emulation, machines[cnt].emulation) == 0)
Packit 032894
	|| (emulation == NULL && machines[cnt].em == machine))
Packit 032894
      {
Packit 032894
	/* Well, we know the emulation name now.  */
Packit 032894
	result->emulation = machines[cnt].emulation;
Packit 032894
Packit 032894
	/* We access some data structures directly.  Make sure the 32 and
Packit 032894
	   64 bit variants are laid out the same.  */
Packit 032894
	assert (offsetof (Elf32_Ehdr, e_machine)
Packit 032894
		== offsetof (Elf64_Ehdr, e_machine));
Packit 032894
	assert (sizeof (((Elf32_Ehdr *) 0)->e_machine)
Packit 032894
		== sizeof (((Elf64_Ehdr *) 0)->e_machine));
Packit 032894
	assert (offsetof (Elf, state.elf32.ehdr)
Packit 032894
		== offsetof (Elf, state.elf64.ehdr));
Packit 032894
Packit 032894
	/* Prefer taking the information from the ELF file.  */
Packit 032894
	if (elf == NULL)
Packit 032894
	  {
Packit 032894
	    result->machine = machines[cnt].em;
Packit 032894
	    result->class = machines[cnt].class;
Packit 032894
	    result->data = machines[cnt].data;
Packit 032894
	  }
Packit 032894
	else
Packit 032894
	  {
Packit 032894
	    result->machine = elf->state.elf32.ehdr->e_machine;
Packit 032894
	    result->class = elf->state.elf32.ehdr->e_ident[EI_CLASS];
Packit 032894
	    result->data = elf->state.elf32.ehdr->e_ident[EI_DATA];
Packit 032894
	  }
Packit 032894
Packit 032894
        if (machines[cnt].init &&
Packit Service 35cfd5
            machines[cnt].init (elf, machine, result))
Packit 032894
          {
Packit 032894
            result->elf = elf;
Packit 032894
            /* A few entries are mandatory.  */
Packit 032894
            assert (result->destr != NULL);
Packit 032894
            return result;
Packit 032894
          }
Packit 032894
Packit 032894
	/* We don't have a backend but the emulation/machine ID matches.
Packit 032894
	   Return that information.  */
Packit 032894
	result->elf = elf;
Packit 032894
	fill_defaults (result);
Packit 032894
Packit 032894
	return result;
Packit 032894
      }
Packit 032894
Packit 032894
  /* Nothing matched.  We use only the default callbacks.   */
Packit 032894
  result->elf = elf;
Packit 032894
  result->emulation = "<unknown>";
Packit 032894
  fill_defaults (result);
Packit 032894
Packit 032894
  return result;
Packit 032894
}
Packit 032894
Packit 032894
Packit 032894
/* Find an appropriate backend for the file associated with ELF.  */
Packit 032894
Ebl *
Packit 032894
ebl_openbackend (Elf *elf)
Packit 032894
{
Packit 032894
  GElf_Ehdr ehdr_mem;
Packit 032894
  GElf_Ehdr *ehdr;
Packit 032894
Packit 032894
  /* Get the ELF header of the object.  */
Packit 032894
  ehdr = gelf_getehdr (elf, &ehdr_mem);
Packit 032894
  if (ehdr == NULL)
Packit 032894
    {
Packit 032894
      // XXX uncomment
Packit 032894
      // __libebl_seterror (elf_errno ());
Packit 032894
      return NULL;
Packit 032894
    }
Packit 032894
Packit 032894
  return openbackend (elf, NULL, ehdr->e_machine);
Packit 032894
}
Packit 032894
Packit 032894
Packit 032894
/* Find backend without underlying ELF file.  */
Packit 032894
Ebl *
Packit 032894
ebl_openbackend_machine (GElf_Half machine)
Packit 032894
{
Packit 032894
  return openbackend (NULL, NULL, machine);
Packit 032894
}
Packit 032894
Packit 032894
Packit 032894
/* Find backend with given emulation name.  */
Packit 032894
Ebl *
Packit 032894
ebl_openbackend_emulation (const char *emulation)
Packit 032894
{
Packit 032894
  return openbackend (NULL, emulation, EM_NONE);
Packit 032894
}
Packit 032894
Packit 032894
Packit 032894
/* Default callbacks.  Mostly they just return the error value.  */
Packit 032894
static const char *
Packit 032894
default_reloc_type_name (int ignore __attribute__ ((unused)),
Packit 032894
			 char *buf __attribute__ ((unused)),
Packit 032894
			 size_t len __attribute__ ((unused)))
Packit 032894
{
Packit 032894
  return NULL;
Packit 032894
}
Packit 032894
Packit 032894
static bool
Packit 032894
default_reloc_type_check (int ignore __attribute__ ((unused)))
Packit 032894
{
Packit 032894
  return false;
Packit 032894
}
Packit 032894
Packit 032894
static bool
Packit 032894
default_reloc_valid_use (Elf *elf __attribute__ ((unused)),
Packit 032894
			 int ignore __attribute__ ((unused)))
Packit 032894
{
Packit 032894
  return false;
Packit 032894
}
Packit 032894
Packit 032894
static Elf_Type
Packit 032894
default_reloc_simple_type (Ebl *eh __attribute__ ((unused)),
Packit 032894
			   int ignore __attribute__ ((unused)),
Packit 032894
			   int *addsub __attribute__ ((unused)))
Packit 032894
{
Packit 032894
  return ELF_T_NUM;
Packit 032894
}
Packit 032894
Packit 032894
static bool
Packit 032894
default_gotpc_reloc_check (Elf *elf __attribute__ ((unused)),
Packit 032894
			   int ignore __attribute__ ((unused)))
Packit 032894
{
Packit 032894
  return false;
Packit 032894
}
Packit 032894
Packit 032894
static const char *
Packit 032894
default_segment_type_name (int ignore __attribute__ ((unused)),
Packit 032894
			   char *buf __attribute__ ((unused)),
Packit 032894
			   size_t len __attribute__ ((unused)))
Packit 032894
{
Packit 032894
  return NULL;
Packit 032894
}
Packit 032894
Packit 032894
static const char *
Packit 032894
default_section_type_name (int ignore __attribute__ ((unused)),
Packit 032894
			   char *buf __attribute__ ((unused)),
Packit 032894
			   size_t len __attribute__ ((unused)))
Packit 032894
{
Packit 032894
  return NULL;
Packit 032894
}
Packit 032894
Packit 032894
static const char *
Packit 032894
default_section_name (int ignore __attribute__ ((unused)),
Packit 032894
		      int ignore2 __attribute__ ((unused)),
Packit 032894
		      char *buf __attribute__ ((unused)),
Packit 032894
		      size_t len __attribute__ ((unused)))
Packit 032894
{
Packit 032894
  return NULL;
Packit 032894
}
Packit 032894
Packit 032894
static const char *
Packit 032894
default_machine_flag_name (Elf64_Word *ignore __attribute__ ((unused)))
Packit 032894
{
Packit 032894
  return NULL;
Packit 032894
}
Packit 032894
Packit 032894
static bool
Packit 032894
default_machine_flag_check (Elf64_Word flags __attribute__ ((unused)))
Packit 032894
{
Packit 032894
  return flags == 0;
Packit 032894
}
Packit 032894
Packit 032894
static bool
Packit 032894
default_machine_section_flag_check (GElf_Xword flags)
Packit 032894
{
Packit 032894
  return flags == 0;
Packit 032894
}
Packit 032894
Packit 032894
static bool
Packit 032894
default_check_special_section (Ebl *ebl __attribute__ ((unused)),
Packit 032894
			       int ndx __attribute__ ((unused)),
Packit 032894
			       const GElf_Shdr *shdr __attribute__ ((unused)),
Packit 032894
			       const char *sname __attribute__ ((unused)))
Packit 032894
{
Packit 032894
  return false;
Packit 032894
}
Packit 032894
Packit 032894
static const char *
Packit 032894
default_symbol_type_name (int ignore __attribute__ ((unused)),
Packit 032894
			  char *buf __attribute__ ((unused)),
Packit 032894
			  size_t len __attribute__ ((unused)))
Packit 032894
{
Packit 032894
  return NULL;
Packit 032894
}
Packit 032894
Packit 032894
static const char *
Packit 032894
default_symbol_binding_name (int ignore __attribute__ ((unused)),
Packit 032894
			     char *buf __attribute__ ((unused)),
Packit 032894
			     size_t len __attribute__ ((unused)))
Packit 032894
{
Packit 032894
  return NULL;
Packit 032894
}
Packit 032894
Packit 032894
static const char *
Packit 032894
default_dynamic_tag_name (int64_t ignore __attribute__ ((unused)),
Packit 032894
			  char *buf __attribute__ ((unused)),
Packit 032894
			  size_t len __attribute__ ((unused)))
Packit 032894
{
Packit 032894
  return NULL;
Packit 032894
}
Packit 032894
Packit 032894
static bool
Packit 032894
default_dynamic_tag_check (int64_t ignore __attribute__ ((unused)))
Packit 032894
{
Packit 032894
  return false;
Packit 032894
}
Packit 032894
Packit 032894
static void
Packit 032894
default_destr (struct ebl *ignore __attribute__ ((unused)))
Packit 032894
{
Packit 032894
}
Packit 032894
Packit 032894
static const char *
Packit 032894
default_osabi_name (int ignore __attribute__ ((unused)),
Packit 032894
		    char *buf __attribute__ ((unused)),
Packit 032894
		    size_t len __attribute__ ((unused)))
Packit 032894
{
Packit 032894
  return NULL;
Packit 032894
}
Packit 032894
Packit 032894
static const char *
Packit 032894
default_core_note_type_name (uint32_t ignore __attribute__ ((unused)),
Packit 032894
			     char *buf __attribute__ ((unused)),
Packit 032894
			     size_t len __attribute__ ((unused)))
Packit 032894
{
Packit 032894
  return NULL;
Packit 032894
}
Packit 032894
Packit 032894
static int
Packit 032894
default_auxv_info (GElf_Xword a_type __attribute__ ((unused)),
Packit 032894
		   const char **name __attribute__ ((unused)),
Packit 032894
		   const char **format __attribute__ ((unused)))
Packit 032894
{
Packit 032894
  return 0;
Packit 032894
}
Packit 032894
Packit 032894
static int
Packit 032894
default_core_note (const GElf_Nhdr *nhdr __attribute__ ((unused)),
Packit 032894
		   const char *name __attribute__ ((unused)),
Packit 032894
		   GElf_Word *ro __attribute__ ((unused)),
Packit 032894
		   size_t *nregloc  __attribute__ ((unused)),
Packit 032894
		   const Ebl_Register_Location **reglocs
Packit 032894
		   __attribute__ ((unused)),
Packit 032894
		   size_t *nitems __attribute__ ((unused)),
Packit 032894
		   const Ebl_Core_Item **items __attribute__ ((unused)))
Packit 032894
{
Packit 032894
  return 0;
Packit 032894
}
Packit 032894
Packit 032894
static const char *
Packit 032894
default_object_note_type_name (const char *name __attribute__ ((unused)),
Packit 032894
			       uint32_t ignore __attribute__ ((unused)),
Packit 032894
			       char *buf __attribute__ ((unused)),
Packit 032894
			       size_t len __attribute__ ((unused)))
Packit 032894
{
Packit 032894
  return NULL;
Packit 032894
}
Packit 032894
Packit 032894
static bool
Packit 032894
default_object_note (const char *name __attribute__ ((unused)),
Packit 032894
		     uint32_t type __attribute__ ((unused)),
Packit 032894
		     uint32_t descsz __attribute__ ((unused)),
Packit 032894
		     const char *desc __attribute__ ((unused)))
Packit 032894
{
Packit 032894
  return NULL;
Packit 032894
}
Packit 032894
Packit 032894
static bool
Packit 032894
default_debugscn_p (const char *name)
Packit 032894
{
Packit 032894
  /* We know by default only about the DWARF debug sections which have
Packit 032894
     fixed names.  */
Packit 032894
  static const char *dwarf_scn_names[] =
Packit 032894
    {
Packit 032894
      /* DWARF 1 */
Packit 032894
      ".debug",
Packit 032894
      ".line",
Packit 032894
      /* GNU DWARF 1 extensions */
Packit 032894
      ".debug_srcinfo",
Packit 032894
      ".debug_sfnames",
Packit 032894
      /* DWARF 1.1 and DWARF 2 */
Packit 032894
      ".debug_aranges",
Packit 032894
      ".debug_pubnames",
Packit 032894
      /* DWARF 2 */
Packit 032894
      ".debug_info",
Packit 032894
      ".debug_abbrev",
Packit 032894
      ".debug_line",
Packit 032894
      ".debug_frame",
Packit 032894
      ".debug_str",
Packit 032894
      ".debug_loc",
Packit 032894
      ".debug_macinfo",
Packit 032894
      /* DWARF 3 */
Packit 032894
      ".debug_ranges",
Packit 032894
      ".debug_pubtypes",
Packit 032894
      /* DWARF 4 */
Packit 032894
      ".debug_types",
Packit 032894
      /* GDB DWARF 4 extension */
Packit 032894
      ".gdb_index",
Packit 032894
      /* GNU/DWARF 5 extension/proposal */
Packit 032894
      ".debug_macro",
Packit 032894
      /* DWARF 5 */
Packit 032894
      ".debug_addr",
Packit 032894
      ".debug_line_str",
Packit 032894
      ".debug_loclists",
Packit 032894
      ".debug_names",
Packit 032894
      ".debug_rnglists",
Packit 032894
      ".debug_str_offsets",
Packit 032894
      /* SGI/MIPS DWARF 2 extensions */
Packit 032894
      ".debug_weaknames",
Packit 032894
      ".debug_funcnames",
Packit 032894
      ".debug_typenames",
Packit 032894
      ".debug_varnames"
Packit 032894
    };
Packit 032894
  const size_t ndwarf_scn_names = (sizeof (dwarf_scn_names)
Packit 032894
				   / sizeof (dwarf_scn_names[0]));
Packit 032894
  for (size_t cnt = 0; cnt < ndwarf_scn_names; ++cnt)
Packit 032894
    if (strcmp (name, dwarf_scn_names[cnt]) == 0
Packit 032894
	|| (strncmp (name, ".zdebug", strlen (".zdebug")) == 0
Packit Service 35cfd5
	    && strcmp (&name[2], &dwarf_scn_names[cnt][1]) == 0)
Packit Service 35cfd5
	|| (strncmp (name, ".gnu.debuglto_", strlen (".gnu.debuglto_")) == 0
Packit Service 35cfd5
	    && strcmp (&name[14], dwarf_scn_names[cnt]) == 0))
Packit 032894
      return true;
Packit 032894
Packit 032894
  return false;
Packit 032894
}
Packit 032894
Packit 032894
static bool
Packit 032894
default_copy_reloc_p (int reloc __attribute__ ((unused)))
Packit 032894
{
Packit 032894
  return false;
Packit 032894
}
Packit 032894
strong_alias (default_copy_reloc_p, default_none_reloc_p)
Packit 032894
strong_alias (default_copy_reloc_p, default_relative_reloc_p)
Packit 032894
Packit 032894
static bool
Packit 032894
default_check_special_symbol (Elf *elf __attribute__ ((unused)),
Packit 032894
			      const GElf_Sym *sym __attribute__ ((unused)),
Packit 032894
			      const char *name __attribute__ ((unused)),
Packit 032894
			      const GElf_Shdr *destshdr __attribute__ ((unused)))
Packit 032894
{
Packit 032894
  return false;
Packit 032894
}
Packit 032894
Packit 032894
static bool
Packit 032894
default_data_marker_symbol (const GElf_Sym *sym __attribute__ ((unused)),
Packit 032894
			    const char *sname __attribute__ ((unused)))
Packit 032894
{
Packit 032894
  return false;
Packit 032894
}
Packit 032894
Packit 032894
static bool
Packit 032894
default_check_st_other_bits (unsigned char st_other __attribute__ ((unused)))
Packit 032894
{
Packit 032894
  return false;
Packit 032894
}
Packit 032894
Packit 032894
Packit 032894
static bool
Packit 032894
default_bss_plt_p (Elf *elf __attribute__ ((unused)))
Packit 032894
{
Packit 032894
  return false;
Packit 032894
}
Packit 032894
Packit 032894
static int
Packit 032894
default_return_value_location (Dwarf_Die *functypedie __attribute__ ((unused)),
Packit 032894
			       const Dwarf_Op **locops __attribute__ ((unused)))
Packit 032894
{
Packit 032894
  return -2;
Packit 032894
}
Packit 032894
Packit 032894
static ssize_t
Packit 032894
default_register_info (Ebl *ebl __attribute__ ((unused)),
Packit 032894
		       int regno, char *name, size_t namelen,
Packit 032894
		       const char **prefix,
Packit 032894
		       const char **setname,
Packit 032894
		       int *bits, int *type)
Packit 032894
{
Packit 032894
  if (name == NULL)
Packit 032894
    return 0;
Packit 032894
Packit 032894
  *setname = "???";
Packit 032894
  *prefix = "";
Packit 032894
  *bits = -1;
Packit 032894
  *type = DW_ATE_void;
Packit 032894
  return snprintf (name, namelen, "reg%d", regno);
Packit 032894
}
Packit 032894
Packit 032894
static int
Packit 032894
default_syscall_abi (Ebl *ebl __attribute__ ((unused)),
Packit 032894
		     int *sp, int *pc, int *callno, int args[6])
Packit 032894
{
Packit 032894
  *sp = *pc = *callno = -1;
Packit 032894
  args[0] = -1;
Packit 032894
  args[1] = -1;
Packit 032894
  args[2] = -1;
Packit 032894
  args[3] = -1;
Packit 032894
  args[4] = -1;
Packit 032894
  args[5] = -1;
Packit 032894
  return -1;
Packit 032894
}
Packit 032894
Packit 032894
static bool
Packit 032894
default_check_object_attribute (Ebl *ebl __attribute__ ((unused)),
Packit 032894
				const char *vendor  __attribute__ ((unused)),
Packit 032894
				int tag __attribute__ ((unused)),
Packit 032894
				uint64_t value __attribute__ ((unused)),
Packit 032894
				const char **tag_name, const char **value_name)
Packit 032894
{
Packit 032894
  *tag_name = NULL;
Packit 032894
  *value_name = NULL;
Packit 032894
  return false;
Packit 032894
}
Packit 032894
Packit 032894
static bool
Packit 032894
default_check_reloc_target_type (Ebl *ebl __attribute__ ((unused)),
Packit 032894
				 Elf64_Word sh_type __attribute__ ((unused)))
Packit 032894
{
Packit 032894
  return false;
Packit 032894
}
Packit 032894
Packit 032894
static int
Packit 032894
default_abi_cfi (Ebl *ebl __attribute__ ((unused)),
Packit 032894
		 Dwarf_CIE *abi_info __attribute__ ((unused)))
Packit 032894
{
Packit 032894
  return -1;
Packit 032894
}