/* BFD back-end for WebAssembly modules.
   Copyright (C) 2017-2019 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;
  bfd_boolean success = FALSE;

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

      result |= ((bfd_vma) (byte & 0x7f)) << shift;

      shift += 7;
      if ((byte & 0x80) == 0)
	{
	  success = TRUE;
	  break;
	}
    }

  if (length_return != NULL)
    *length_return = num_read;
  if (error_return != NULL)
    *error_return = ! success;

  if (sign && (shift < 8 * sizeof (result)) && (byte & 0x40))
    result |= -((bfd_vma) 1 << shift);

  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;

  if (! asect)
    return FALSE;

  if (strcmp (asect->name, WASM_NAME_SECTION) != 0)
    return FALSE;

  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 (p > p + payload_size)
	return FALSE;

      p += payload_size;
    }

  if (p >= end)
    return FALSE;

  READ_LEB128 (payload_size, p, end);

  if (p > p + payload_size)
    return FALSE;

  if (p + payload_size > end)
    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;

  symbols = bfd_zalloc (abfd, tdata->symcount * sizeof (asymbol));
  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 (p + len < p || p + len > end)
	goto error_return;

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

      memcpy (name, p, len);
      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:
  while (symcount)
    bfd_release (abfd, (void *)symbols[--symcount].name);
  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;
  char *name = NULL;
  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;

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

	  bfdsec->vma = vma;
	  bfdsec->lma = vma;
	  bfdsec->size = wasm_read_leb128 (abfd, &error, &bytes_read, FALSE);
	  if (error)
	    goto error_return;
	  bfdsec->filepos = bfd_tell (abfd);
	  bfdsec->alignment_power = 0;
	}
      else
	{
	  bfd_vma payload_len;
	  file_ptr section_start;
	  bfd_vma namelen;
	  char *prefix = WASM_SECTION_PREFIX;
	  char *p;
	  int ret;

	  payload_len = wasm_read_leb128 (abfd, &error, &bytes_read, FALSE);
	  if (error)
	    goto error_return;
	  section_start = bfd_tell (abfd);
	  namelen = wasm_read_leb128 (abfd, &error, &bytes_read, FALSE);
	  if (error || namelen > payload_len)
	    goto error_return;
	  name = bfd_zmalloc (namelen + strlen (prefix) + 1);
	  if (! name)
	    goto error_return;
	  p = name;
	  ret = sprintf (p, "%s", prefix);
	  if (ret < 0 || (bfd_vma) ret != strlen (prefix))
	    goto error_return;
	  p += ret;
	  if (bfd_bread (p, namelen, abfd) != namelen)
	    goto error_return;

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

	  bfdsec->vma = vma;
	  bfdsec->lma = vma;
	  bfdsec->filepos = bfd_tell (abfd);
	  bfdsec->size = section_start + payload_len - bfdsec->filepos;
	  bfdsec->alignment_power = 0;
	}

      if (bfdsec->size != 0)
	{
	  bfdsec->contents = bfd_zalloc (abfd, bfdsec->size);
	  if (! bfdsec->contents)
	    goto error_return;

	  if (bfd_bread (bfdsec->contents, bfdsec->size, abfd) != bfdsec->size)
	    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:
  if (name)
    free (name);

  for (bfdsec = abfd->sections; bfdsec; bfdsec = bfdsec->next)
    free ((void *) bfdsec->name);

  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)
{
  bfd_size_type 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 const bfd_target *
wasm_object_p (bfd *abfd)
{
  bfd_boolean error;

  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) || ! wasm_scan (abfd))
    return NULL;

  if (! bfd_default_set_arch_mach (abfd, bfd_arch_wasm32, 0))
    return NULL;

  if (wasm_scan_name_function_section (abfd, bfd_get_section_by_name (abfd, WASM_NAME_SECTION)))
    abfd->flags |= HAS_SYMS;

  return abfd->xvec;
}

/* 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,
};
