/* Load module for 'compile' command.

   Copyright (C) 2014-2025 Free Software Foundation, Inc.

   This file is part of GDB.

   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, see <http://www.gnu.org/licenses/>.  */

#include "compile-object-load.h"
#include "compile-internal.h"
#include "command.h"
#include "objfiles.h"
#include "gdbcore.h"
#include "readline/tilde.h"
#include "bfdlink.h"
#include "cli/cli-cmds.h"
#include "regcache.h"
#include "inferior.h"
#include "gdbthread.h"
#include "compile.h"
#include "block.h"
#include "arch-utils.h"
#include <algorithm>

/* Add inferior mmap memory range ADDR..ADDR+SIZE (exclusive) to the
   list.  */

void
munmap_list::add (CORE_ADDR addr, CORE_ADDR size)
{
  struct munmap_item item = { addr, size };
  items.push_back (item);
}

/* Destroy an munmap_list.  */

munmap_list::~munmap_list ()
{
  for (auto &item : items)
    {
      try
	{
	  gdbarch_infcall_munmap (current_inferior ()->arch (),
				  item.addr, item.size);
	}
      catch (const gdb_exception_error &ex)
	{
	  /* There's not much the user can do, so just ignore
	     this.  */
	}
    }
}

/* A data structure that is used to lay out sections of our objfile in
   inferior memory.  */

struct setup_sections_data
{
  explicit setup_sections_data (bfd *abfd)
    : m_bfd (abfd),
      m_last_section_first (abfd->sections)
  {
  }

  /* Place all ABFD sections next to each other obeying all
     constraints.  */
  void setup_one_section (asection *sect);

  /* List of inferior mmap ranges where setup_sections should add its
     next range.  */
  struct munmap_list munmap_list;

private:

  /* The BFD.  */
  bfd *m_bfd;

  /* Size of all recent sections with matching LAST_PROT.  */
  CORE_ADDR m_last_size = 0;

  /* First section matching LAST_PROT.  */
  asection *m_last_section_first;

  /* Memory protection like the prot parameter of gdbarch_infcall_mmap. */
  unsigned m_last_prot = -1;

  /* Maximum of alignments of all sections matching LAST_PROT.
     This value is always at least 1.  This value is always a power of 2.  */
  CORE_ADDR m_last_max_alignment = -1;

};

/* See setup_sections_data.  */

void
setup_sections_data::setup_one_section (asection *sect)
{
  CORE_ADDR alignment;
  unsigned prot;

  if (sect != NULL)
    {
      /* It is required by later bfd_get_relocated_section_contents.  */
      if (sect->output_section == NULL)
	sect->output_section = sect;

      if ((bfd_section_flags (sect) & SEC_ALLOC) == 0)
	return;

      /* Make the memory always readable.  */
      prot = GDB_MMAP_PROT_READ;
      if ((bfd_section_flags (sect) & SEC_READONLY) == 0)
	prot |= GDB_MMAP_PROT_WRITE;
      if ((bfd_section_flags (sect) & SEC_CODE) != 0)
	prot |= GDB_MMAP_PROT_EXEC;

      if (compile_debug)
	gdb_printf (gdb_stdlog,
		    "module \"%s\" section \"%s\" size %s prot %u\n",
		    bfd_get_filename (m_bfd),
		    bfd_section_name (sect),
		    paddress (current_inferior ()->arch (),
			      bfd_section_size (sect)),
		    prot);
    }
  else
    prot = -1;

  if (sect == NULL
      || (m_last_prot != prot && bfd_section_size (sect) != 0))
    {
      CORE_ADDR addr;
      asection *sect_iter;

      if (m_last_size != 0)
	{
	  addr = gdbarch_infcall_mmap (current_inferior ()->arch (),
				       m_last_size, m_last_prot);
	  munmap_list.add (addr, m_last_size);
	  if (compile_debug)
	    gdb_printf (gdb_stdlog,
			"allocated %s bytes at %s prot %u\n",
			paddress (current_inferior ()->arch (), m_last_size),
			paddress (current_inferior ()->arch (), addr),
			m_last_prot);
	}
      else
	addr = 0;

      if ((addr & (m_last_max_alignment - 1)) != 0)
	error (_("Inferior compiled module address %s "
		 "is not aligned to BFD required %s."),
	       paddress (current_inferior ()->arch (), addr),
	       paddress (current_inferior ()->arch (), m_last_max_alignment));

      for (sect_iter = m_last_section_first; sect_iter != sect;
	   sect_iter = sect_iter->next)
	if ((bfd_section_flags (sect_iter) & SEC_ALLOC) != 0)
	  bfd_set_section_vma (sect_iter, addr + bfd_section_vma (sect_iter));

      m_last_size = 0;
      m_last_section_first = sect;
      m_last_prot = prot;
      m_last_max_alignment = 1;
    }

  if (sect == NULL)
    return;

  alignment = ((CORE_ADDR) 1) << bfd_section_alignment (sect);
  m_last_max_alignment = std::max (m_last_max_alignment, alignment);

  m_last_size = (m_last_size + alignment - 1) & -alignment;

  bfd_set_section_vma (sect, m_last_size);

  m_last_size += bfd_section_size (sect);
  m_last_size = (m_last_size + alignment - 1) & -alignment;
}

/* Helper for link_callbacks callbacks vector.  */

static void
link_callbacks_multiple_definition (struct bfd_link_info *link_info,
				    struct bfd_link_hash_entry *h, bfd *nbfd,
				    asection *nsec, bfd_vma nval)
{
  bfd *abfd = link_info->input_bfds;

  if (link_info->allow_multiple_definition)
    return;
  warning (_("Compiled module \"%s\": multiple symbol definitions: %s"),
	   bfd_get_filename (abfd), h->root.string);
}

/* Helper for link_callbacks callbacks vector.  */

static void
link_callbacks_warning (struct bfd_link_info *link_info, const char *xwarning,
			const char *symbol, bfd *abfd, asection *section,
			bfd_vma address)
{
  warning (_("Compiled module \"%s\" section \"%s\": warning: %s"),
	   bfd_get_filename (abfd), bfd_section_name (section),
	   xwarning);
}

/* Helper for link_callbacks callbacks vector.  */

static void
link_callbacks_undefined_symbol (struct bfd_link_info *link_info,
				 const char *name, bfd *abfd, asection *section,
				 bfd_vma address, bfd_boolean is_fatal)
{
  warning (_("Cannot resolve relocation to \"%s\" "
	     "from compiled module \"%s\" section \"%s\"."),
	   name, bfd_get_filename (abfd), bfd_section_name (section));
}

/* Helper for link_callbacks callbacks vector.  */

static void
link_callbacks_reloc_overflow (struct bfd_link_info *link_info,
			       struct bfd_link_hash_entry *entry,
			       const char *name, const char *reloc_name,
			       bfd_vma addend, bfd *abfd, asection *section,
			       bfd_vma address)
{
}

/* Helper for link_callbacks callbacks vector.  */

static void
link_callbacks_reloc_dangerous (struct bfd_link_info *link_info,
				const char *message, bfd *abfd,
				asection *section, bfd_vma address)
{
  warning (_("Compiled module \"%s\" section \"%s\": dangerous "
	     "relocation: %s\n"),
	   bfd_get_filename (abfd), bfd_section_name (section),
	   message);
}

/* Helper for link_callbacks callbacks vector.  */

static void
link_callbacks_unattached_reloc (struct bfd_link_info *link_info,
				 const char *name, bfd *abfd, asection *section,
				 bfd_vma address)
{
  warning (_("Compiled module \"%s\" section \"%s\": unattached "
	     "relocation: %s\n"),
	   bfd_get_filename (abfd), bfd_section_name (section),
	   name);
}

/* Helper for link_callbacks callbacks vector.  */

static void link_callbacks_einfo (const char *fmt, ...)
  ATTRIBUTE_PRINTF (1, 2);

static void
link_callbacks_einfo (const char *fmt, ...)
{
  va_list ap;

  va_start (ap, fmt);
  std::string str = string_vprintf (fmt, ap);
  va_end (ap);

  warning (_("Compile module: warning: %s"), str.c_str ());
}

/* Helper for bfd_get_relocated_section_contents.
   Only these symbols are set by bfd_simple_get_relocated_section_contents
   but bfd/ seems to use even the NULL ones without checking them first.  */

static const struct bfd_link_callbacks link_callbacks =
{
  NULL, /* add_archive_element */
  link_callbacks_multiple_definition, /* multiple_definition */
  NULL, /* multiple_common */
  NULL, /* add_to_set */
  NULL, /* constructor */
  link_callbacks_warning, /* warning */
  link_callbacks_undefined_symbol, /* undefined_symbol */
  link_callbacks_reloc_overflow, /* reloc_overflow */
  link_callbacks_reloc_dangerous, /* reloc_dangerous */
  link_callbacks_unattached_reloc, /* unattached_reloc */
  NULL, /* notice */
  NULL, /* fatal */
  link_callbacks_einfo, /* einfo */
  NULL, /* info */
  NULL, /* minfo */
  NULL, /* override_segment_assignment */
};

struct link_hash_table_cleanup_data
{
  explicit link_hash_table_cleanup_data (bfd *abfd_)
    : abfd (abfd_),
      link_next (abfd->link.next)
  {
  }

  ~link_hash_table_cleanup_data ()
  {
    if (abfd->is_linker_output)
      (*abfd->link.hash->hash_table_free) (abfd);
    abfd->link.next = link_next;
  }

  DISABLE_COPY_AND_ASSIGN (link_hash_table_cleanup_data);

private:

  bfd *abfd;
  bfd *link_next;
};

/* Relocate and store into inferior memory each section SECT of ABFD.  */

static void
copy_sections (bfd *abfd, asection *sect, void *data)
{
  asymbol **symbol_table = (asymbol **) data;
  bfd_byte *sect_data_got;
  struct bfd_link_info link_info;
  struct bfd_link_order link_order;
  CORE_ADDR inferior_addr;

  if ((bfd_section_flags (sect) & (SEC_ALLOC | SEC_LOAD))
      != (SEC_ALLOC | SEC_LOAD))
    return;

  if (bfd_section_size (sect) == 0)
    return;

  /* Mostly a copy of bfd_simple_get_relocated_section_contents which GDB
     cannot use as it does not report relocations to undefined symbols.  */
  memset (&link_info, 0, sizeof (link_info));
  link_info.output_bfd = abfd;
  link_info.input_bfds = abfd;
  link_info.input_bfds_tail = &abfd->link.next;

  struct link_hash_table_cleanup_data cleanup_data (abfd);

  abfd->link.next = NULL;
  link_info.hash = bfd_link_hash_table_create (abfd);

  link_info.callbacks = &link_callbacks;

  memset (&link_order, 0, sizeof (link_order));
  link_order.next = NULL;
  link_order.type = bfd_indirect_link_order;
  link_order.offset = 0;
  link_order.size = bfd_section_size (sect);
  link_order.u.indirect.section = sect;

  gdb::unique_xmalloc_ptr<gdb_byte> sect_data
    ((bfd_byte *) xmalloc (bfd_section_size (sect)));

  sect_data_got = bfd_get_relocated_section_contents (abfd, &link_info,
						      &link_order,
						      sect_data.get (),
						      FALSE, symbol_table);

  if (sect_data_got == NULL)
    error (_("Cannot map compiled module \"%s\" section \"%s\": %s"),
	   bfd_get_filename (abfd), bfd_section_name (sect),
	   bfd_errmsg (bfd_get_error ()));
  gdb_assert (sect_data_got == sect_data.get ());

  inferior_addr = bfd_section_vma (sect);
  if (0 != target_write_memory (inferior_addr, sect_data.get (),
				bfd_section_size (sect)))
    error (_("Cannot write compiled module \"%s\" section \"%s\" "
	     "to inferior memory range %s-%s."),
	   bfd_get_filename (abfd), bfd_section_name (sect),
	   paddress (current_inferior ()->arch (), inferior_addr),
	   paddress (current_inferior ()->arch (),
		     inferior_addr + bfd_section_size (sect)));
}

/* Fetch the type of COMPILE_I_EXPR_PTR_TYPE and COMPILE_I_EXPR_VAL
   symbols in OBJFILE so we can calculate how much memory to allocate
   for the out parameter.  This avoids needing a malloc in the generated
   code.  Throw an error if anything fails.
   GDB first tries to compile the code with COMPILE_I_PRINT_ADDRESS_SCOPE.
   If it finds user tries to print an array type this function returns
   NULL.  Caller will then regenerate the code with
   COMPILE_I_PRINT_VALUE_SCOPE, recompiles it again and finally runs it.
   This is because __auto_type array-to-pointer type conversion of
   COMPILE_I_EXPR_VAL which gets detected by COMPILE_I_EXPR_PTR_TYPE
   preserving the array type.  */

static struct type *
get_out_value_type (struct symbol *func_sym, struct objfile *objfile,
		    enum compile_i_scope_types scope)
{
  struct symbol *gdb_ptr_type_sym;
  /* Initialize it just to avoid a GCC false warning.  */
  struct symbol *gdb_val_sym = NULL;
  struct type *gdb_ptr_type, *gdb_type_from_ptr, *gdb_type, *retval;
  /* Initialize it just to avoid a GCC false warning.  */
  const struct block *block = NULL;
  const struct blockvector *bv;
  int nblocks = 0;
  int block_loop = 0;

  lookup_name_info func_matcher (GCC_FE_WRAPPER_FUNCTION,
				 symbol_name_match_type::SEARCH_NAME);
  lookup_name_info i_val_matcher (COMPILE_I_EXPR_VAL,
				  symbol_name_match_type::SEARCH_NAME);
  lookup_name_info i_ptr_matcher (COMPILE_I_EXPR_PTR_TYPE,
				  symbol_name_match_type::SEARCH_NAME);

  bv = func_sym->symtab ()->compunit ()->blockvector ();
  nblocks = bv->num_blocks ();

  gdb_ptr_type_sym = NULL;
  for (block_loop = 0; block_loop < nblocks; block_loop++)
    {
      struct symbol *function = NULL;
      const struct block *function_block;

      block = bv->block (block_loop);
      if (block->function () != NULL)
	continue;
      gdb_val_sym = block_lookup_symbol (block, i_val_matcher, SEARCH_VFT);
      if (gdb_val_sym == NULL)
	continue;

      function_block = block;
      while (function_block != bv->static_block ()
	     && function_block != bv->global_block ())
	{
	  function_block = function_block->superblock ();
	  function = function_block->function ();
	  if (function != NULL)
	    break;
	}
      if (function != NULL
	  && function_block->superblock () == bv->static_block ()
	  && symbol_matches_search_name (function, func_matcher))
	break;
    }
  if (block_loop == nblocks)
    error (_("No \"%s\" symbol found"), COMPILE_I_EXPR_VAL);

  gdb_type = gdb_val_sym->type ();
  gdb_type = check_typedef (gdb_type);

  gdb_ptr_type_sym = block_lookup_symbol (block, i_ptr_matcher, SEARCH_VFT);
  if (gdb_ptr_type_sym == NULL)
    error (_("No \"%s\" symbol found"), COMPILE_I_EXPR_PTR_TYPE);
  gdb_ptr_type = gdb_ptr_type_sym->type ();
  gdb_ptr_type = check_typedef (gdb_ptr_type);
  if (gdb_ptr_type->code () != TYPE_CODE_PTR)
    error (_("Type of \"%s\" is not a pointer"), COMPILE_I_EXPR_PTR_TYPE);
  gdb_type_from_ptr = check_typedef (gdb_ptr_type->target_type ());

  if (types_deeply_equal (gdb_type, gdb_type_from_ptr))
    {
      if (scope != COMPILE_I_PRINT_ADDRESS_SCOPE)
	error (_("Expected address scope in compiled module \"%s\"."),
	       objfile_name (objfile));
      return gdb_type;
    }

  if (gdb_type->code () != TYPE_CODE_PTR)
    error (_("Invalid type code %d of symbol \"%s\" "
	     "in compiled module \"%s\"."),
	   gdb_type_from_ptr->code (), COMPILE_I_EXPR_VAL,
	   objfile_name (objfile));
  
  retval = gdb_type_from_ptr;
  switch (gdb_type_from_ptr->code ())
    {
    case TYPE_CODE_ARRAY:
      gdb_type_from_ptr = gdb_type_from_ptr->target_type ();
      break;
    case TYPE_CODE_FUNC:
      break;
    default:
      error (_("Invalid type code %d of symbol \"%s\" "
	       "in compiled module \"%s\"."),
	     gdb_type_from_ptr->code (), COMPILE_I_EXPR_PTR_TYPE,
	     objfile_name (objfile));
    }
  if (!types_deeply_equal (gdb_type_from_ptr,
			   gdb_type->target_type ()))
    error (_("Referenced types do not match for symbols \"%s\" and \"%s\" "
	     "in compiled module \"%s\"."),
	   COMPILE_I_EXPR_PTR_TYPE, COMPILE_I_EXPR_VAL,
	   objfile_name (objfile));
  if (scope == COMPILE_I_PRINT_ADDRESS_SCOPE)
    return NULL;
  return retval;
}

/* Fetch the type of first parameter of FUNC_SYM.
   Return NULL if FUNC_SYM has no parameters.  Throw an error otherwise.  */

static struct type *
get_regs_type (struct symbol *func_sym, struct objfile *objfile)
{
  struct type *func_type = func_sym->type ();
  struct type *regsp_type, *regs_type;

  /* No register parameter present.  */
  if (func_type->num_fields () == 0)
    return NULL;

  regsp_type = check_typedef (func_type->field (0).type ());
  if (regsp_type->code () != TYPE_CODE_PTR)
    error (_("Invalid type code %d of first parameter of function \"%s\" "
	     "in compiled module \"%s\"."),
	   regsp_type->code (), GCC_FE_WRAPPER_FUNCTION,
	   objfile_name (objfile));

  regs_type = check_typedef (regsp_type->target_type ());
  if (regs_type->code () != TYPE_CODE_STRUCT)
    error (_("Invalid type code %d of dereferenced first parameter "
	     "of function \"%s\" in compiled module \"%s\"."),
	   regs_type->code (), GCC_FE_WRAPPER_FUNCTION,
	   objfile_name (objfile));

  return regs_type;
}

/* Store all inferior registers required by REGS_TYPE to inferior memory
   starting at inferior address REGS_BASE.  */

static void
store_regs (struct type *regs_type, CORE_ADDR regs_base)
{
  gdbarch *gdbarch = current_inferior ()->arch ();
  int fieldno;

  for (fieldno = 0; fieldno < regs_type->num_fields (); fieldno++)
    {
      const char *reg_name = regs_type->field (fieldno).name ();
      ULONGEST reg_bitpos = regs_type->field (fieldno).loc_bitpos ();
      ULONGEST reg_bitsize = regs_type->field (fieldno).bitsize ();
      ULONGEST reg_offset;
      struct type *reg_type
	= check_typedef (regs_type->field (fieldno).type ());
      ULONGEST reg_size = reg_type->length ();
      int regnum;
      struct value *regval;
      CORE_ADDR inferior_addr;

      if (strcmp (reg_name, COMPILE_I_SIMPLE_REGISTER_DUMMY) == 0)
	continue;

      if ((reg_bitpos % 8) != 0 || reg_bitsize != 0)
	error (_("Invalid register \"%s\" position %s bits or size %s bits"),
	       reg_name, pulongest (reg_bitpos), pulongest (reg_bitsize));
      reg_offset = reg_bitpos / 8;

      if (reg_type->code () != TYPE_CODE_INT
	  && reg_type->code () != TYPE_CODE_PTR)
	error (_("Invalid register \"%s\" type code %d"), reg_name,
	       reg_type->code ());

      regnum = compile_register_name_demangle (gdbarch, reg_name);

      regval = value_from_register (reg_type, regnum, get_current_frame ());
      if (regval->optimized_out ())
	error (_("Register \"%s\" is optimized out."), reg_name);
      if (!regval->entirely_available ())
	error (_("Register \"%s\" is not available."), reg_name);

      inferior_addr = regs_base + reg_offset;
      if (0 != target_write_memory (inferior_addr,
				    regval->contents ().data (),
				    reg_size))
	error (_("Cannot write register \"%s\" to inferior memory at %s."),
	       reg_name, paddress (gdbarch, inferior_addr));
    }
}

/* Load the object file specified in FILE_NAMES into inferior memory.
   Throw an error otherwise.  Caller must fully dispose the return
   value by calling compile_object_run.  Returns NULL only for
   COMPILE_I_PRINT_ADDRESS_SCOPE when COMPILE_I_PRINT_VALUE_SCOPE
   should have been used instead.  */

compile_module_up
compile_object_load (const compile_file_names &file_names,
		     enum compile_i_scope_types scope, void *scope_data)
{
  CORE_ADDR regs_addr, out_value_addr = 0;
  struct symbol *func_sym;
  struct type *func_type;
  long missing_symbols;
  struct type *regs_type, *out_value_type = NULL;
  char **matching;
  struct objfile *objfile;
  int expect_parameters;
  struct type *expect_return_type;

  gdb::unique_xmalloc_ptr<char> filename
    (tilde_expand (file_names.object_file ()));

  gdb_bfd_ref_ptr abfd (gdb_bfd_open (filename.get (), gnutarget));
  if (abfd == NULL)
    error (_("\"%s\": could not open as compiled module: %s"),
	  filename.get (), bfd_errmsg (bfd_get_error ()));

  if (!bfd_check_format_matches (abfd.get (), bfd_object, &matching))
    error (_("\"%s\": not in loadable format: %s"),
	   filename.get (),
	   gdb_bfd_errmsg (bfd_get_error (), matching).c_str ());

  if ((bfd_get_file_flags (abfd.get ()) & (EXEC_P | DYNAMIC)) != 0)
    error (_("\"%s\": not in object format."), filename.get ());

  struct setup_sections_data setup_sections_data (abfd.get ());
  for (asection *sect = abfd->sections; sect != nullptr; sect = sect->next)
    setup_sections_data.setup_one_section (sect);
  setup_sections_data.setup_one_section (nullptr);

  /* SYMFILE_VERBOSE is not passed even if FROM_TTY, user is not interested in
     "Reading symbols from ..." message for automatically generated file.  */
  scoped_objfile_unlinker objfile_holder (symbol_file_add_from_bfd
					    (abfd, filename.get (),
					     0, NULL, 0, NULL));
  objfile = objfile_holder.get ();

  func_sym = lookup_global_symbol_from_objfile (objfile,
						GLOBAL_BLOCK,
						GCC_FE_WRAPPER_FUNCTION,
						SEARCH_VFT).symbol;
  if (func_sym == NULL)
    error (_("Cannot find function \"%s\" in compiled module \"%s\"."),
	   GCC_FE_WRAPPER_FUNCTION, objfile_name (objfile));
  func_type = func_sym->type ();
  if (func_type->code () != TYPE_CODE_FUNC)
    error (_("Invalid type code %d of function \"%s\" in compiled "
	     "module \"%s\"."),
	   func_type->code (), GCC_FE_WRAPPER_FUNCTION,
	   objfile_name (objfile));

  switch (scope)
    {
    case COMPILE_I_SIMPLE_SCOPE:
      expect_parameters = 1;
      expect_return_type
	= builtin_type (current_inferior ()->arch ())->builtin_void;
      break;
    case COMPILE_I_RAW_SCOPE:
      expect_parameters = 0;
      expect_return_type
	= builtin_type (current_inferior ()->arch ())->builtin_void;
      break;
    case COMPILE_I_PRINT_ADDRESS_SCOPE:
    case COMPILE_I_PRINT_VALUE_SCOPE:
      expect_parameters = 2;
      expect_return_type
	= builtin_type (current_inferior ()->arch ())->builtin_void;
      break;
    default:
      internal_error (_("invalid scope %d"), scope);
    }
  if (func_type->num_fields () != expect_parameters)
    error (_("Invalid %d parameters of function \"%s\" in compiled "
	     "module \"%s\"."),
	   func_type->num_fields (), GCC_FE_WRAPPER_FUNCTION,
	   objfile_name (objfile));
  if (!types_deeply_equal (expect_return_type, func_type->target_type ()))
    error (_("Invalid return type of function \"%s\" in compiled "
	     "module \"%s\"."),
	   GCC_FE_WRAPPER_FUNCTION, objfile_name (objfile));

  gdb::array_view<asymbol *> symbol_table
    = gdb_bfd_canonicalize_symtab (abfd.get ());

  missing_symbols = 0;
  for (asymbol *sym : symbol_table)
    {
      if (sym->flags != 0)
	continue;
      sym->flags = BSF_GLOBAL;
      sym->section = bfd_abs_section_ptr;
      if (strcmp (sym->name, "_GLOBAL_OFFSET_TABLE_") == 0)
	{
	  if (compile_debug)
	    gdb_printf (gdb_stdlog,
			"ELF symbol \"%s\" relocated to zero\n",
			sym->name);

	  /* It seems to be a GCC bug, with -mcmodel=large there should be no
	     need for _GLOBAL_OFFSET_TABLE_.  Together with -fPIE the data
	     remain PC-relative even with _GLOBAL_OFFSET_TABLE_ as zero.  */
	  sym->value = 0;
	  continue;
	}
      if (strcmp (sym->name, ".TOC.") == 0)
	{
	  /* Handle the .TOC. symbol as the linker would do.  Set the .TOC.
	     sections value to 0x8000 (see bfd/elf64-ppc.c TOC_BASE_OFF);
	     point the symbol section at the ".toc" section;
	     and pass the toc->vma value into bfd_set_gp_value().
	     If the .toc section is not found, use the first section
	     with the SEC_ALLOC flag set.  In the unlikely case that
	     we still do not have a section identified, fall back to using
	     the "*ABS*" section.  */
	  asection *toc_fallback = bfd_get_section_by_name(abfd.get(), ".toc");
	  if (toc_fallback == NULL)
	    {
	      for (asection *tsect = abfd->sections; tsect != nullptr;
		   tsect = tsect->next)
		 {
		    if (bfd_section_flags (tsect) & SEC_ALLOC)
		       {
			  toc_fallback = tsect;
			  break;
		       }
		 }
	    }

	  if (toc_fallback == NULL)
	    /*  If we've gotten here, we have not found a section usable
		as a backup for the .toc section.  In this case, use the
		absolute (*ABS*) section.  */
	     toc_fallback = bfd_abs_section_ptr;

	  sym->section = toc_fallback;
	  sym->value = 0x8000;
	  bfd_set_gp_value(abfd.get(), toc_fallback->vma);
	  if (compile_debug)
	    gdb_printf (gdb_stdlog,
			"Connecting ELF symbol \"%s\" to the .toc section (%s)\n",
			sym->name,
			paddress (current_inferior ()->arch (), sym->value));
	  continue;
	}

      bound_minimal_symbol bmsym
	= lookup_minimal_symbol (current_program_space, sym->name);
      switch (bmsym.minsym == NULL
	      ? mst_unknown : bmsym.minsym->type ())
	{
	case mst_text:
	case mst_bss:
	case mst_data:
	  sym->value = bmsym.value_address ();
	  if (compile_debug)
	    gdb_printf (gdb_stdlog,
			"ELF mst_text symbol \"%s\" relocated to %s\n",
			sym->name,
			paddress (current_inferior ()->arch (), sym->value));
	  break;
	case mst_text_gnu_ifunc:
	  sym->value = gnu_ifunc_resolve_addr (current_inferior ()->arch (),
					       bmsym.value_address ());
	  if (compile_debug)
	    gdb_printf (gdb_stdlog,
			"ELF mst_text_gnu_ifunc symbol \"%s\" "
			"relocated to %s\n",
			sym->name,
			paddress (current_inferior ()->arch (), sym->value));
	  break;
	default:
	  warning (_("Could not find symbol \"%s\" "
		     "for compiled module \"%s\"."),
		   sym->name, filename.get ());
	  missing_symbols++;
	}
    }
  if (missing_symbols)
    error (_("%ld symbols were missing, cannot continue."), missing_symbols);

  bfd_map_over_sections (abfd.get (), copy_sections, symbol_table.data ());

  regs_type = get_regs_type (func_sym, objfile);
  if (regs_type == NULL)
    regs_addr = 0;
  else
    {
      /* Use read-only non-executable memory protection.  */
      regs_addr = gdbarch_infcall_mmap (current_inferior ()->arch (),
					regs_type->length (),
					GDB_MMAP_PROT_READ);
      gdb_assert (regs_addr != 0);
      setup_sections_data.munmap_list.add (regs_addr, regs_type->length ());
      if (compile_debug)
	gdb_printf (gdb_stdlog,
		    "allocated %s bytes at %s for registers\n",
		    paddress (current_inferior ()->arch (),
			      regs_type->length ()),
		    paddress (current_inferior ()->arch (), regs_addr));
      store_regs (regs_type, regs_addr);
    }

  if (scope == COMPILE_I_PRINT_ADDRESS_SCOPE
      || scope == COMPILE_I_PRINT_VALUE_SCOPE)
    {
      out_value_type = get_out_value_type (func_sym, objfile, scope);
      if (out_value_type == NULL)
	return NULL;
      check_typedef (out_value_type);
      out_value_addr = gdbarch_infcall_mmap (current_inferior ()->arch (),
					     out_value_type->length (),
					     (GDB_MMAP_PROT_READ
					      | GDB_MMAP_PROT_WRITE));
      gdb_assert (out_value_addr != 0);
      setup_sections_data.munmap_list.add (out_value_addr,
					   out_value_type->length ());
      if (compile_debug)
	gdb_printf (gdb_stdlog,
		    "allocated %s bytes at %s for printed value\n",
		    paddress (current_inferior ()->arch (),
			      out_value_type->length ()),
		    paddress (current_inferior ()->arch (), out_value_addr));
    }

  compile_module_up retval (new struct compile_module);
  retval->objfile = objfile_holder.release ();
  retval->source_file = file_names.source_file ();
  retval->func_sym = func_sym;
  retval->regs_addr = regs_addr;
  retval->scope = scope;
  retval->scope_data = scope_data;
  retval->out_value_type = out_value_type;
  retval->out_value_addr = out_value_addr;
  retval->munmap_list = std::move (setup_sections_data.munmap_list);

  return retval;
}
