/* BFD back-end for WebAssembly modules.
   Copyright (C) 2017-2020 Free Software Foundation, Inc.

   Based on srec.c, mmo.c, and binary.c

   This file is part of BFD, the Binary File Descriptor library.

   This program is free software; you can redistribute it and/or modify
   it under the terms of the GNU General Public License as published by
   the Free Software Foundation; either version 3 of the License, or
   (at your option) any later version.

   This program is distributed in the hope that it will be useful,
   but WITHOUT ANY WARRANTY; without even the implied warranty of
   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
   GNU General Public License for more details.

   You should have received a copy of the GNU General Public License
   along with this program; if not, write to the Free Software
   Foundation, Inc., 51 Franklin Street - Fifth Floor, Boston,
   MA 02110-1301, USA.  */

/* The WebAssembly module format is a simple object file format
   including up to 11 numbered sections, plus any number of named
   "custom" sections. It is described at:
   https://github.com/WebAssembly/design/blob/master/BinaryEncoding.md. */

#include "sysdep.h"
#include "alloca-conf.h"
#include "bfd.h"
#include <limits.h>
#include "libiberty.h"
#include "libbfd.h"
#include "wasm-module.h"

typedef struct
{
  asymbol *      symbols;
  bfd_size_type  symcount;
} tdata_type;

static const char * const wasm_numbered_sections[] =
{
  NULL, /* Custom section, different layout.  */
  WASM_SECTION ( 1, "type"),
  WASM_SECTION ( 2, "import"),
  WASM_SECTION ( 3, "function"),
  WASM_SECTION ( 4, "table"),
  WASM_SECTION ( 5, "memory"),
  WASM_SECTION ( 6, "global"),
  WASM_SECTION ( 7, "export"),
  WASM_SECTION ( 8, "start"),
  WASM_SECTION ( 9, "element"),
  WASM_SECTION (10, "code"),
  WASM_SECTION (11, "data"),
};

#define WASM_NUMBERED_SECTIONS ARRAY_SIZE (wasm_numbered_sections)

/* Resolve SECTION_CODE to a section name if there is one, NULL
   otherwise.  */

static const char *
wasm_section_code_to_name (bfd_byte section_code)
{
  if (section_code < WASM_NUMBERED_SECTIONS)
    return wasm_numbered_sections[section_code];

  return NULL;
}

/* Translate section name NAME to a section code, or 0 if it's a
   custom name.  */

static unsigned int
wasm_section_name_to_code (const char *name)
{
  unsigned i;

  for (i = 1; i < WASM_NUMBERED_SECTIONS; i++)
    if (strcmp (name, wasm_numbered_sections[i]) == 0)
      return i;

  return 0;
}

/* WebAssembly LEB128 integers are sufficiently like DWARF LEB128
   integers that we use _bfd_safe_read_leb128, but there are two
   points of difference:

   - WebAssembly requires a 32-bit value to be encoded in at most 5
     bytes, etc.
   - _bfd_safe_read_leb128 accepts incomplete LEB128 encodings at the
     end of the buffer, while these are invalid in WebAssembly.

   Those differences mean that we will accept some files that are
   invalid WebAssembly.  */

/* Read an LEB128-encoded integer from ABFD's I/O stream, reading one
   byte at a time.  Set ERROR_RETURN if no complete integer could be
   read, LENGTH_RETURN to the number of bytes read (including bytes in
   incomplete numbers).  SIGN means interpret the number as SLEB128. */

static bfd_vma
wasm_read_leb128 (bfd *		  abfd,
		  bfd_boolean *	  error_return,
		  unsigned int *  length_return,
		  bfd_boolean	  sign)
{
  bfd_vma result = 0;
  unsigned int num_read = 0;
  unsigned int shift = 0;
  unsigned char byte = 0;
  int status = 1;

  while (bfd_bread (&byte, 1, abfd) == 1)
    {
      num_read++;

      if (shift < sizeof (result) * 8)
	{
	  result |= ((bfd_vma) (byte & 0x7f)) << shift;
	  if ((result >> shift) != (byte & 0x7f))
	    /* Overflow.  */
	    status |= 2;
	  shift += 7;
	}
      else if ((byte & 0x7f) != 0)
	status |= 2;

      if ((byte & 0x80) == 0)
	{
	  status &= ~1;
	  if (sign && (shift < 8 * sizeof (result)) && (byte & 0x40))
	    result |= -((bfd_vma) 1 << shift);
	  break;
	}
    }

  if (length_return != NULL)
    *length_return = num_read;
  if (error_return != NULL)
    *error_return = status != 0;

  return result;
}

/* Encode an integer V as LEB128 and write it to ABFD, return TRUE on
   success.  */

static bfd_boolean
wasm_write_uleb128 (bfd *abfd, bfd_vma v)
{
  do
    {
      bfd_byte c = v & 0x7f;
      v >>= 7;

      if (v)
	c |= 0x80;

      if (bfd_bwrite (&c, 1, abfd) != 1)
	return FALSE;
    }
  while (v);

  return TRUE;
}

/* Read the LEB128 integer at P, saving it to X; at end of buffer,
   jump to error_return.  */
#define READ_LEB128(x, p, end)						\
  do									\
    {									\
      unsigned int length_read;						\
      (x) = _bfd_safe_read_leb128 (abfd, (p), &length_read,		\
				   FALSE, (end));			\
      (p) += length_read;						\
      if (length_read == 0)						\
	goto error_return;						\
    }									\
  while (0)

/* Verify the magic number at the beginning of a WebAssembly module
   ABFD, setting ERRORPTR if there's a mismatch.  */

static bfd_boolean
wasm_read_magic (bfd *abfd, bfd_boolean *errorptr)
{
  bfd_byte magic_const[SIZEOF_WASM_MAGIC] = WASM_MAGIC;
  bfd_byte magic[SIZEOF_WASM_MAGIC];

  if (bfd_bread (magic, sizeof (magic), abfd) == sizeof (magic)
      && memcmp (magic, magic_const, sizeof (magic)) == 0)
    return TRUE;

  *errorptr = TRUE;
  return FALSE;
}

/* Read the version number from ABFD, returning TRUE if it's a supported
   version. Set ERRORPTR otherwise.  */

static bfd_boolean
wasm_read_version (bfd *abfd, bfd_boolean *errorptr)
{
  bfd_byte vers_const[SIZEOF_WASM_VERSION] = WASM_VERSION;
  bfd_byte vers[SIZEOF_WASM_VERSION];

  if (bfd_bread (vers, sizeof (vers), abfd) == sizeof (vers)
      /* Don't attempt to parse newer versions, which are likely to
	 require code changes.  */
      && memcmp (vers, vers_const, sizeof (vers)) == 0)
    return TRUE;

  *errorptr = TRUE;
  return FALSE;
}

/* Read the WebAssembly header (magic number plus version number) from
   ABFD, setting ERRORPTR to TRUE if there is a mismatch.  */

static bfd_boolean
wasm_read_header (bfd *abfd, bfd_boolean *errorptr)
{
  if (! wasm_read_magic (abfd, errorptr))
    return FALSE;

  if (! wasm_read_version (abfd, errorptr))
    return FALSE;

  return TRUE;
}

/* Scan the "function" subsection of the "name" section ASECT in the
   wasm module ABFD. Create symbols. Return TRUE on success.  */

static bfd_boolean
wasm_scan_name_function_section (bfd *abfd, sec_ptr asect)
{
  bfd_byte *p;
  bfd_byte *end;
  bfd_vma payload_size;
  bfd_vma symcount = 0;
  tdata_type *tdata = abfd->tdata.any;
  asymbol *symbols = NULL;
  sec_ptr space_function_index;
  size_t amt;

  p = asect->contents;
  end = asect->contents + asect->size;

  if (!p)
    return FALSE;

  while (p < end)
    {
      bfd_byte subsection_code = *p++;
      if (subsection_code == WASM_FUNCTION_SUBSECTION)
	break;

      /* subsection_code is documented to be a varuint7, meaning that
	 it has to be a single byte in the 0 - 127 range.  If it isn't,
	 the spec must have changed underneath us, so give up.  */
      if (subsection_code & 0x80)
	return FALSE;

      READ_LEB128 (payload_size, p, end);

      if (payload_size > (size_t) (end - p))
	return FALSE;

      p += payload_size;
    }

  if (p >= end)
    return FALSE;

  READ_LEB128 (payload_size, p, end);

  if (payload_size > (size_t) (end - p))
    return FALSE;

  end = p + payload_size;

  READ_LEB128 (symcount, p, end);

  /* Sanity check: each symbol has at least two bytes.  */
  if (symcount > payload_size / 2)
    return FALSE;

  tdata->symcount = symcount;

  space_function_index
    = bfd_make_section_with_flags (abfd, WASM_SECTION_FUNCTION_INDEX,
				   SEC_READONLY | SEC_CODE);

  if (!space_function_index)
    space_function_index
      = bfd_get_section_by_name (abfd, WASM_SECTION_FUNCTION_INDEX);

  if (!space_function_index)
    return FALSE;

  if (_bfd_mul_overflow (tdata->symcount, sizeof (asymbol), &amt))
    {
      bfd_set_error (bfd_error_file_too_big);
      return FALSE;
    }
  symbols = bfd_alloc (abfd, amt);
  if (!symbols)
    return FALSE;

  for (symcount = 0; p < end && symcount < tdata->symcount; symcount++)
    {
      bfd_vma idx;
      bfd_vma len;
      char *name;
      asymbol *sym;

      READ_LEB128 (idx, p, end);
      READ_LEB128 (len, p, end);

      if (len > (size_t) (end - p))
	goto error_return;

      name = bfd_alloc (abfd, len + 1);
      if (!name)
	goto error_return;

      memcpy (name, p, len);
      name[len] = 0;
      p += len;

      sym = &symbols[symcount];
      sym->the_bfd = abfd;
      sym->name = name;
      sym->value = idx;
      sym->flags = BSF_GLOBAL | BSF_FUNCTION;
      sym->section = space_function_index;
      sym->udata.p = NULL;
    }

  if (symcount < tdata->symcount)
    goto error_return;

  tdata->symbols = symbols;
  abfd->symcount = symcount;

  return TRUE;

 error_return:
  bfd_release (abfd, symbols);
  return FALSE;
}

/* Read a byte from ABFD and return it, or EOF for EOF or error.
   Set ERRORPTR on non-EOF error.  */

static int
wasm_read_byte (bfd *abfd, bfd_boolean *errorptr)
{
  bfd_byte byte;

  if (bfd_bread (&byte, (bfd_size_type) 1, abfd) != 1)
    {
      if (bfd_get_error () != bfd_error_file_truncated)
	*errorptr = TRUE;
      return EOF;
    }

  return byte;
}

/* Scan the wasm module ABFD, creating sections and symbols.
   Return TRUE on success.  */

static bfd_boolean
wasm_scan (bfd *abfd)
{
  bfd_boolean error = FALSE;
  /* Fake VMAs for now. Choose 0x80000000 as base to avoid clashes
     with actual data addresses.  */
  bfd_vma vma = 0x80000000;
  int section_code;
  unsigned int bytes_read;
  asection *bfdsec;

  if (bfd_seek (abfd, (file_ptr) 0, SEEK_SET) != 0)
    goto error_return;

  if (!wasm_read_header (abfd, &error))
    goto error_return;

  while ((section_code = wasm_read_byte (abfd, &error)) != EOF)
    {
      if (section_code != 0)
	{
	  const char *sname = wasm_section_code_to_name (section_code);

	  if (!sname)
	    goto error_return;

	  bfdsec = bfd_make_section_anyway_with_flags (abfd, sname,
						       SEC_HAS_CONTENTS);
	  if (bfdsec == NULL)
	    goto error_return;

	  bfdsec->size = wasm_read_leb128 (abfd, &error, &bytes_read, FALSE);
	  if (error)
	    goto error_return;
	}
      else
	{
	  bfd_vma payload_len;
	  bfd_vma namelen;
	  char *name;
	  char *prefix = WASM_SECTION_PREFIX;
	  size_t prefixlen = strlen (prefix);
	  ufile_ptr filesize;

	  payload_len = wasm_read_leb128 (abfd, &error, &bytes_read, FALSE);
	  if (error)
	    goto error_return;
	  namelen = wasm_read_leb128 (abfd, &error, &bytes_read, FALSE);
	  if (error || bytes_read > payload_len
	      || namelen > payload_len - bytes_read)
	    goto error_return;
	  payload_len -= namelen + bytes_read;
	  filesize = bfd_get_file_size (abfd);
	  if (filesize != 0 && namelen > filesize)
	    {
	      bfd_set_error (bfd_error_file_truncated);
	      return FALSE;
	    }
	  name = bfd_alloc (abfd, namelen + prefixlen + 1);
	  if (!name)
	    goto error_return;
	  memcpy (name, prefix, prefixlen);
	  if (bfd_bread (name + prefixlen, namelen, abfd) != namelen)
	    goto error_return;
	  name[prefixlen + namelen] = 0;

	  bfdsec = bfd_make_section_anyway_with_flags (abfd, name,
						       SEC_HAS_CONTENTS);
	  if (bfdsec == NULL)
	    goto error_return;

	  bfdsec->size = payload_len;
	}

      bfdsec->vma = vma;
      bfdsec->lma = vma;
      bfdsec->alignment_power = 0;
      bfdsec->filepos = bfd_tell (abfd);
      if (bfdsec->size != 0)
	{
	  bfdsec->contents = _bfd_alloc_and_read (abfd, bfdsec->size,
						  bfdsec->size);
	  if (!bfdsec->contents)
	    goto error_return;
	}

      vma += bfdsec->size;
    }

  /* Make sure we're at actual EOF.  There's no indication in the
     WebAssembly format of how long the file is supposed to be.  */
  if (error)
    goto error_return;

  return TRUE;

 error_return:
  return FALSE;
}

/* Put a numbered section ASECT of ABFD into the table of numbered
   sections pointed to by FSARG.  */

static void
wasm_register_section (bfd *abfd ATTRIBUTE_UNUSED,
		       asection *asect,
		       void *fsarg)
{
  sec_ptr *numbered_sections = fsarg;
  int idx = wasm_section_name_to_code (asect->name);

  if (idx == 0)
    return;

  numbered_sections[idx] = asect;
}

struct compute_section_arg
{
  bfd_vma pos;
  bfd_boolean failed;
};

/* Compute the file position of ABFD's section ASECT.  FSARG is a
   pointer to the current file position.

   We allow section names of the form .wasm.id to encode the numbered
   section with ID id, if it exists; otherwise, a custom section with
   ID "id" is produced.  Arbitrary section names are for sections that
   are assumed already to contain a section header; those are appended
   to the WebAssembly module verbatim.  */

static void
wasm_compute_custom_section_file_position (bfd *abfd,
					   sec_ptr asect,
					   void *fsarg)
{
  struct compute_section_arg *fs = fsarg;
  int idx;

  if (fs->failed)
    return;

  idx = wasm_section_name_to_code (asect->name);

  if (idx != 0)
    return;

  if (CONST_STRNEQ (asect->name, WASM_SECTION_PREFIX))
    {
      const char *name = asect->name + strlen (WASM_SECTION_PREFIX);
      bfd_size_type payload_len = asect->size;
      bfd_size_type name_len = strlen (name);
      bfd_size_type nl = name_len;

      payload_len += name_len;

      do
	{
	  payload_len++;
	  nl >>= 7;
	}
      while (nl);

      bfd_seek (abfd, fs->pos, SEEK_SET);
      if (! wasm_write_uleb128 (abfd, 0)
	  || ! wasm_write_uleb128 (abfd, payload_len)
	  || ! wasm_write_uleb128 (abfd, name_len)
	  || bfd_bwrite (name, name_len, abfd) != name_len)
	goto error_return;
      fs->pos = asect->filepos = bfd_tell (abfd);
    }
  else
    {
      asect->filepos = fs->pos;
    }


  fs->pos += asect->size;
  return;

 error_return:
  fs->failed = TRUE;
}

/* Compute the file positions for the sections of ABFD.  Currently,
   this writes all numbered sections first, in order, then all custom
   sections, in section order.

   The spec says that the numbered sections must appear in order of
   their ids, but custom sections can appear in any position and any
   order, and more than once. FIXME: support that.  */

static bfd_boolean
wasm_compute_section_file_positions (bfd *abfd)
{
  bfd_byte magic[SIZEOF_WASM_MAGIC] = WASM_MAGIC;
  bfd_byte vers[SIZEOF_WASM_VERSION] = WASM_VERSION;
  sec_ptr numbered_sections[WASM_NUMBERED_SECTIONS];
  struct compute_section_arg fs;
  unsigned int i;

  bfd_seek (abfd, (bfd_vma) 0, SEEK_SET);

  if (bfd_bwrite (magic, sizeof (magic), abfd) != (sizeof magic)
      || bfd_bwrite (vers, sizeof (vers), abfd) != sizeof (vers))
    return FALSE;

  for (i = 0; i < WASM_NUMBERED_SECTIONS; i++)
    numbered_sections[i] = NULL;

  bfd_map_over_sections (abfd, wasm_register_section, numbered_sections);

  fs.pos = bfd_tell (abfd);
  for (i = 0; i < WASM_NUMBERED_SECTIONS; i++)
    {
      sec_ptr sec = numbered_sections[i];
      bfd_size_type size;

      if (! sec)
	continue;
      size = sec->size;
      if (bfd_seek (abfd, fs.pos, SEEK_SET) != 0)
	return FALSE;
      if (! wasm_write_uleb128 (abfd, i)
	  || ! wasm_write_uleb128 (abfd, size))
	return FALSE;
      fs.pos = sec->filepos = bfd_tell (abfd);
      fs.pos += size;
    }

  fs.failed = FALSE;

  bfd_map_over_sections (abfd, wasm_compute_custom_section_file_position, &fs);

  if (fs.failed)
    return FALSE;

  abfd->output_has_begun = TRUE;

  return TRUE;
}

static bfd_boolean
wasm_set_section_contents (bfd *abfd,
			   sec_ptr section,
			   const void *location,
			   file_ptr offset,
			   bfd_size_type count)
{
  if (count == 0)
    return TRUE;

  if (! abfd->output_has_begun
      && ! wasm_compute_section_file_positions (abfd))
    return FALSE;

  if (bfd_seek (abfd, section->filepos + offset, SEEK_SET) != 0
      || bfd_bwrite (location, count, abfd) != count)
    return FALSE;

  return TRUE;
}

static bfd_boolean
wasm_write_object_contents (bfd* abfd)
{
  bfd_byte magic[] = WASM_MAGIC;
  bfd_byte vers[] = WASM_VERSION;

  if (bfd_seek (abfd, 0, SEEK_SET) != 0)
    return FALSE;

  if (bfd_bwrite (magic, sizeof (magic), abfd) != sizeof (magic)
      || bfd_bwrite (vers, sizeof (vers), abfd) != sizeof (vers))
    return FALSE;

  return TRUE;
}

static bfd_boolean
wasm_mkobject (bfd *abfd)
{
  tdata_type *tdata = (tdata_type *) bfd_alloc (abfd, sizeof (tdata_type));

  if (! tdata)
    return FALSE;

  tdata->symbols = NULL;
  tdata->symcount = 0;

  abfd->tdata.any = tdata;

  return TRUE;
}

static long
wasm_get_symtab_upper_bound (bfd *abfd)
{
  tdata_type *tdata = abfd->tdata.any;

  return (tdata->symcount + 1) * (sizeof (asymbol *));
}

static long
wasm_canonicalize_symtab (bfd *abfd, asymbol **alocation)
{
  tdata_type *tdata = abfd->tdata.any;
  size_t i;

  for (i = 0; i < tdata->symcount; i++)
    alocation[i] = &tdata->symbols[i];
  alocation[i] = NULL;

  return tdata->symcount;
}

static asymbol *
wasm_make_empty_symbol (bfd *abfd)
{
  size_t amt = sizeof (asymbol);
  asymbol *new_symbol = (asymbol *) bfd_zalloc (abfd, amt);

  if (! new_symbol)
    return NULL;
  new_symbol->the_bfd = abfd;
  return new_symbol;
}

static void
wasm_print_symbol (bfd *abfd,
		   void * filep,
		   asymbol *symbol,
		   bfd_print_symbol_type how)
{
  FILE *file = (FILE *) filep;

  switch (how)
    {
    case bfd_print_symbol_name:
      fprintf (file, "%s", symbol->name);
      break;

    default:
      bfd_print_symbol_vandf (abfd, filep, symbol);
      fprintf (file, " %-5s %s", symbol->section->name, symbol->name);
    }
}

static void
wasm_get_symbol_info (bfd *abfd ATTRIBUTE_UNUSED,
		      asymbol *symbol,
		      symbol_info *ret)
{
  bfd_symbol_info (symbol, ret);
}

/* Check whether ABFD is a WebAssembly module; if so, scan it.  */

static bfd_cleanup
wasm_object_p (bfd *abfd)
{
  bfd_boolean error;
  asection *s;

  if (bfd_seek (abfd, (file_ptr) 0, SEEK_SET) != 0)
    return NULL;

  if (!wasm_read_header (abfd, &error))
    {
      bfd_set_error (bfd_error_wrong_format);
      return NULL;
    }

  if (!wasm_mkobject (abfd))
    return NULL;

  if (!wasm_scan (abfd)
      || !bfd_default_set_arch_mach (abfd, bfd_arch_wasm32, 0))
    {
      bfd_release (abfd, abfd->tdata.any);
      abfd->tdata.any = NULL;
      return NULL;
    }

  s = bfd_get_section_by_name (abfd, WASM_NAME_SECTION);
  if (s != NULL && wasm_scan_name_function_section (abfd, s))
    abfd->flags |= HAS_SYMS;

  return _bfd_no_cleanup;
}

/* BFD_JUMP_TABLE_WRITE */
#define wasm_set_arch_mach		  _bfd_generic_set_arch_mach

/* BFD_JUMP_TABLE_SYMBOLS */
#define wasm_get_symbol_version_string	  _bfd_nosymbols_get_symbol_version_string
#define wasm_bfd_is_local_label_name	   bfd_generic_is_local_label_name
#define wasm_bfd_is_target_special_symbol _bfd_bool_bfd_asymbol_false
#define wasm_get_lineno			  _bfd_nosymbols_get_lineno
#define wasm_find_nearest_line		  _bfd_nosymbols_find_nearest_line
#define wasm_find_line			  _bfd_nosymbols_find_line
#define wasm_find_inliner_info		  _bfd_nosymbols_find_inliner_info
#define wasm_bfd_make_debug_symbol	  _bfd_nosymbols_bfd_make_debug_symbol
#define wasm_read_minisymbols		  _bfd_generic_read_minisymbols
#define wasm_minisymbol_to_symbol	  _bfd_generic_minisymbol_to_symbol

const bfd_target wasm_vec =
{
  "wasm",			/* Name.  */
  bfd_target_unknown_flavour,
  BFD_ENDIAN_LITTLE,
  BFD_ENDIAN_LITTLE,
  (HAS_SYMS | WP_TEXT),		/* Object flags.  */
  (SEC_CODE | SEC_DATA | SEC_HAS_CONTENTS), /* Section flags.  */
  0,				/* Leading underscore.  */
  ' ',				/* AR_pad_char.  */
  255,				/* AR_max_namelen.  */
  0,				/* Match priority.  */
  /* Routines to byte-swap various sized integers from the data sections.  */
  bfd_getl64, bfd_getl_signed_64, bfd_putl64,
  bfd_getl32, bfd_getl_signed_32, bfd_putl32,
  bfd_getl16, bfd_getl_signed_16, bfd_putl16,

  /* Routines to byte-swap various sized integers from the file headers.  */
  bfd_getl64, bfd_getl_signed_64, bfd_putl64,
  bfd_getl32, bfd_getl_signed_32, bfd_putl32,
  bfd_getl16, bfd_getl_signed_16, bfd_putl16,

  {
    _bfd_dummy_target,
    wasm_object_p,		/* bfd_check_format.  */
    _bfd_dummy_target,
    _bfd_dummy_target,
  },
  {
    _bfd_bool_bfd_false_error,
    wasm_mkobject,
    _bfd_generic_mkarchive,
    _bfd_bool_bfd_false_error,
  },
  {				/* bfd_write_contents.  */
    _bfd_bool_bfd_false_error,
    wasm_write_object_contents,
    _bfd_write_archive_contents,
    _bfd_bool_bfd_false_error,
  },

  BFD_JUMP_TABLE_GENERIC (_bfd_generic),
  BFD_JUMP_TABLE_COPY (_bfd_generic),
  BFD_JUMP_TABLE_CORE (_bfd_nocore),
  BFD_JUMP_TABLE_ARCHIVE (_bfd_noarchive),
  BFD_JUMP_TABLE_SYMBOLS (wasm),
  BFD_JUMP_TABLE_RELOCS (_bfd_norelocs),
  BFD_JUMP_TABLE_WRITE (wasm),
  BFD_JUMP_TABLE_LINK (_bfd_nolink),
  BFD_JUMP_TABLE_DYNAMIC (_bfd_nodynamic),

  NULL,

  NULL,
};
