Home | History | Annotate | Line # | Download | only in bfd
      1 /* 32-bit ELF for the WebAssembly target
      2    Copyright (C) 2017-2024 Free Software Foundation, Inc.
      3 
      4    This file is part of BFD, the Binary File Descriptor library.
      5 
      6    This program is free software; you can redistribute it and/or modify
      7    it under the terms of the GNU General Public License as published by
      8    the Free Software Foundation; either version 3 of the License, or
      9    (at your option) any later version.
     10 
     11    This program 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
     14    GNU General Public License for more details.
     15 
     16    You should have received a copy of the GNU General Public License
     17    along with this program; if not, write to the Free Software
     18    Foundation, Inc., 51 Franklin Street - Fifth Floor,
     19    Boston, MA 02110-1301, USA.  */
     20 
     21 #include "sysdep.h"
     22 #include "bfd.h"
     23 #include "libbfd.h"
     24 #include "elf-bfd.h"
     25 #include "libiberty.h"
     26 #include "elf/wasm32.h"
     27 
     28 static reloc_howto_type elf32_wasm32_howto_table[] =
     29 {
     30   HOWTO (R_WASM32_NONE,		/* type */
     31 	 0,			/* rightshift */
     32 	 0,			/* size */
     33 	 0,			/* bitsize */
     34 	 false,			/* pc_relative */
     35 	 0,			/* bitpos */
     36 	 complain_overflow_dont,/* complain_on_overflow */
     37 	 bfd_elf_generic_reloc,	/* special_function */
     38 	 "R_WASM32_NONE",	/* name */
     39 	 false,			/* partial_inplace */
     40 	 0,			/* src_mask */
     41 	 0,			/* dst_mask */
     42 	 false),		/* pcrel_offset */
     43 
     44   /* 32 bit absolute */
     45   HOWTO (R_WASM32_32,		/* type */
     46 	 0,			/* rightshift */
     47 	 4,			/* size */
     48 	 32,			/* bitsize */
     49 	 false,			/* pc_relative */
     50 	 0,			/* bitpos */
     51 	 complain_overflow_bitfield,/* complain_on_overflow */
     52 	 bfd_elf_generic_reloc,	/* special_function */
     53 	 "R_WASM32_32",	/* name */
     54 	 false,			/* partial_inplace */
     55 	 0xffffffff,		/* src_mask */
     56 	 0xffffffff,		/* dst_mask */
     57 	 false),		/* pcrel_offset */
     58 };
     59 
     60 /* Look up the relocation CODE.  */
     61 
     62 static reloc_howto_type *
     63 elf32_wasm32_reloc_type_lookup (bfd *abfd ATTRIBUTE_UNUSED,
     64 				bfd_reloc_code_real_type code)
     65 {
     66   switch (code)
     67     {
     68     case BFD_RELOC_NONE:
     69       return &elf32_wasm32_howto_table[R_WASM32_NONE];
     70     case BFD_RELOC_32:
     71       return &elf32_wasm32_howto_table[R_WASM32_32];
     72     default:
     73       break;
     74     }
     75 
     76   return NULL;
     77 }
     78 
     79 /* Look up the relocation R_NAME.  */
     80 
     81 static reloc_howto_type *
     82 elf32_wasm32_reloc_name_lookup (bfd *abfd ATTRIBUTE_UNUSED,
     83 				const char *r_name)
     84 {
     85   unsigned int i;
     86 
     87   for (i = 0; i < ARRAY_SIZE (elf32_wasm32_howto_table); i++)
     88     if (elf32_wasm32_howto_table[i].name != NULL
     89 	&& strcasecmp (elf32_wasm32_howto_table[i].name, r_name) == 0)
     90       return &elf32_wasm32_howto_table[i];
     91 
     92   return NULL;
     93 }
     94 
     95 /* Look up the relocation R_TYPE.  */
     96 
     97 static reloc_howto_type *
     98 elf32_wasm32_rtype_to_howto (bfd *abfd, unsigned r_type)
     99 {
    100   unsigned int i = r_type;
    101 
    102   if (i >= ARRAY_SIZE (elf32_wasm32_howto_table))
    103     {
    104       /* xgettext:c-format */
    105       _bfd_error_handler (_("%pB: unsupported relocation type %#x"),
    106 			  abfd, r_type);
    107       bfd_set_error (bfd_error_bad_value);
    108       return NULL;
    109     }
    110 
    111   if (elf32_wasm32_howto_table[i].type != r_type)
    112     return NULL;
    113 
    114   return elf32_wasm32_howto_table + i;
    115 }
    116 
    117 /* Translate the ELF-internal relocation RELA into CACHE_PTR.  */
    118 
    119 static bool
    120 elf32_wasm32_info_to_howto_rela (bfd *abfd,
    121 				arelent *cache_ptr,
    122 				Elf_Internal_Rela *dst)
    123 {
    124   unsigned int r_type = ELF32_R_TYPE (dst->r_info);
    125 
    126   cache_ptr->howto = elf32_wasm32_rtype_to_howto (abfd, r_type);
    127   return cache_ptr->howto != NULL;
    128 }
    129 
    130 #define ELF_ARCH		bfd_arch_wasm32
    131 #define ELF_TARGET_ID		EM_WEBASSEMBLY
    132 #define ELF_MACHINE_CODE	EM_WEBASSEMBLY
    133 /* FIXME we don't have paged executables, see:
    134    https://github.com/pipcet/binutils-gdb/issues/4  */
    135 #define ELF_MAXPAGESIZE		4096
    136 
    137 #define TARGET_LITTLE_SYM	wasm32_elf32_vec
    138 #define TARGET_LITTLE_NAME	"elf32-wasm32"
    139 
    140 #define elf_backend_can_gc_sections	1
    141 #define elf_backend_rela_normal		1
    142 /* For testing. */
    143 #define elf_backend_want_dynrelro	1
    144 
    145 #define elf_info_to_howto		elf32_wasm32_info_to_howto_rela
    146 #define elf_info_to_howto_rel		NULL
    147 
    148 #define bfd_elf32_bfd_reloc_type_lookup elf32_wasm32_reloc_type_lookup
    149 #define bfd_elf32_bfd_reloc_name_lookup elf32_wasm32_reloc_name_lookup
    150 
    151 #define ELF_DYNAMIC_INTERPRETER	 "/sbin/elf-dynamic-interpreter.so"
    152 
    153 #define elf_backend_want_got_plt	1
    154 #define elf_backend_plt_readonly	1
    155 #define elf_backend_got_header_size	0
    156 
    157 #include "elf32-target.h"
    158