/* Freescale XGATE-specific support for 32-bit ELF
   Copyright (C) 2012-2018 Free Software Foundation, Inc.

   Contributed by Sean Keys (skeys@ipdatasys.com)
   (Heavily copied from the HC11 port by Stephane Carrez (stcarrez@nerim.fr))

   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.  */

#ifndef _ELF32_XGATE_H
#define _ELF32_XGATE_H

#include "elf-bfd.h"
#include "bfdlink.h"
#include "elf/xgate.h"

/* Set and control ELF flags in ELF header.  */
extern bfd_boolean _bfd_xgate_elf_set_private_flags (bfd*,flagword);
extern bfd_boolean _bfd_xgate_elf_print_private_bfd_data (bfd*, void*);

struct elf32_xgate_stub_hash_entry
{
  /* Base hash table entry structure.  */
  struct bfd_hash_entry root;

  /* The stub section.  */
  asection *stub_sec;

  /* Offset within stub_sec of the beginning of this stub.  */
  bfd_vma stub_offset;

  /* Given the symbol's value and its section we can determine its final
     value when building the stubs (so the stub knows where to jump.  */
  bfd_vma target_value;
  asection *target_section;
};

struct xgate_page_info
{
  bfd_vma bank_virtual;
  bfd_vma bank_physical;
  bfd_vma bank_physical_end;
  bfd_vma bank_mask;
  bfd_vma bank_size;
  int bank_shift;
  int bank_param_initialized;
  bfd_vma trampoline_addr;
};

struct xgate_elf_link_hash_table
{
  struct elf_link_hash_table root;
  struct xgate_page_info pinfo;

  /* The stub hash table.  */
  struct bfd_hash_table* stub_hash_table;

  /* Linker stub bfd.  */
  bfd *stub_bfd;

  asection* stub_section;
  asection* tramp_section;

  /* Linker call-backs.  */
  asection * (*add_stub_section) (const char *, asection *);

  /* Assorted information used by elf32_hppa_size_stubs.  */
  unsigned int bfd_count;
  int	       top_index;
  asection **  input_list;

  /* Small local sym cache.  */
  struct sym_cache sym_cache;

  bfd_boolean (*size_one_stub) (struct bfd_hash_entry*, void*);
  bfd_boolean (*build_one_stub) (struct bfd_hash_entry*, void*);
};

/* Get the XGate ELF linker hash table from a link_info structure.  */

#define xgate_elf_hash_table(p) \
  ((struct xgate_elf_link_hash_table *) ((p)->hash))

/* Create a XGATE ELF linker hash table.  */

extern struct xgate_elf_link_hash_table* xgate_elf_hash_table_create
  (bfd *);

extern void xgate_elf_get_bank_parameters (struct bfd_link_info *);

/* Return 1 if the address is in banked memory.
   This can be applied to a virtual address and to a physical address.  */
extern int xgate_addr_is_banked (struct xgate_page_info *, bfd_vma);

/* Return the physical address seen by the processor, taking
   into account banked memory.  */
extern bfd_vma xgate_phys_addr (struct xgate_page_info *, bfd_vma);

/* Return the page number corresponding to an address in banked memory.  */
extern bfd_vma xgate_phys_page (struct xgate_page_info *, bfd_vma);

bfd_reloc_status_type xgate_elf_ignore_reloc
  (bfd *, arelent *, asymbol *, void *, asection *, bfd *, char **);
bfd_reloc_status_type xgate_elf_special_reloc
  (bfd *, arelent *, asymbol *, void *, asection *, bfd *, char **);

bfd_boolean elf32_xgate_check_relocs
  (bfd *, struct bfd_link_info *, asection *, const Elf_Internal_Rela *);
bfd_boolean elf32_xgate_relocate_section
  (bfd *, struct bfd_link_info *, bfd *, asection *, bfd_byte *,
   Elf_Internal_Rela *, Elf_Internal_Sym *, asection **);

bfd_boolean elf32_xgate_add_symbol_hook
  (bfd *, struct bfd_link_info *, Elf_Internal_Sym *, const char **,
   flagword *, asection **, bfd_vma *);

/* Tweak the OSABI field of the elf header.  */
extern void elf32_xgate_post_process_headers (bfd *, struct bfd_link_info *);

int elf32_xgate_setup_section_lists (bfd *, struct bfd_link_info *);

bfd_boolean elf32_xgate_size_stubs
  (bfd *, bfd *, struct bfd_link_info *,
   asection * (*) (const char *, asection *));

bfd_boolean elf32_xgate_build_stubs (bfd * abfd, struct bfd_link_info *);

#endif /* _ELF32_XGATE_H */
