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