/* Pedantic checking of ELF files compliance with gABI/psABI spec.
   Copyright (C) 2001-2014 Red Hat, Inc.
   This file is part of elfutils.
   Written by Ulrich Drepper <drepper@redhat.com>, 2001.

   This file 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.

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

#ifdef HAVE_CONFIG_H
# include <config.h>
#endif

#include <argp.h>
#include <assert.h>
#include <byteswap.h>
#include <endian.h>
#include <error.h>
#include <fcntl.h>
#include <gelf.h>
#include <inttypes.h>
#include <libintl.h>
#include <locale.h>
#include <stdbool.h>
#include <stdlib.h>
#include <string.h>
#include <unistd.h>
#include <sys/stat.h>
#include <sys/param.h>

#include <elf-knowledge.h>
#include <system.h>
#include "../libelf/libelfP.h"
#include "../libelf/common.h"
#include "../libebl/libeblP.h"
#include "../libdw/libdwP.h"
#include "../libdwfl/libdwflP.h"
#include "../libdw/memory-access.h"


/* Name and version of program.  */
static void print_version (FILE *stream, struct argp_state *state);
ARGP_PROGRAM_VERSION_HOOK_DEF = print_version;

/* Bug report address.  */
ARGP_PROGRAM_BUG_ADDRESS_DEF = PACKAGE_BUGREPORT;

#define ARGP_strict	300
#define ARGP_gnuld	301

/* Definitions of arguments for argp functions.  */
static const struct argp_option options[] =
{
  { "strict", ARGP_strict, NULL, 0,
    N_("Be extremely strict, flag level 2 features."), 0 },
  { "quiet", 'q', NULL, 0, N_("Do not print anything if successful"), 0 },
  { "debuginfo", 'd', NULL, 0, N_("Binary is a separate debuginfo file"), 0 },
  { "gnu-ld", ARGP_gnuld, NULL, 0,
    N_("Binary has been created with GNU ld and is therefore known to be \
broken in certain ways"), 0 },
  { NULL, 0, NULL, 0, NULL, 0 }
};

/* Short description of program.  */
static const char doc[] = N_("\
Pedantic checking of ELF files compliance with gABI/psABI spec.");

/* Strings for arguments in help texts.  */
static const char args_doc[] = N_("FILE...");

/* Prototype for option handler.  */
static error_t parse_opt (int key, char *arg, struct argp_state *state);

/* Data structure to communicate with argp functions.  */
static struct argp argp =
{
  options, parse_opt, args_doc, doc, NULL, NULL, NULL
};


/* Declarations of local functions.  */
static void process_file (int fd, Elf *elf, const char *prefix,
			  const char *suffix, const char *fname, size_t size,
			  bool only_one);
static void process_elf_file (Elf *elf, const char *prefix, const char *suffix,
			      const char *fname, size_t size, bool only_one);
static void check_note_section (Ebl *ebl, GElf_Ehdr *ehdr,
				GElf_Shdr *shdr, int idx);


/* Report an error.  */
#define ERROR(str, args...) \
  do {									      \
    printf (str, ##args);						      \
    ++error_count;							      \
  } while (0)
static unsigned int error_count;

/* True if we should perform very strict testing.  */
static bool be_strict;

/* True if no message is to be printed if the run is succesful.  */
static bool be_quiet;

/* True if binary is from strip -f, not a normal ELF file.  */
static bool is_debuginfo;

/* True if binary is assumed to be generated with GNU ld.  */
static bool gnuld;

/* Index of section header string table.  */
static uint32_t shstrndx;

/* Array to count references in section groups.  */
static int *scnref;

/* Numbers of sections and program headers.  */
static unsigned int shnum;
static unsigned int phnum;


int
main (int argc, char *argv[])
{
  /* Set locale.  */
  setlocale (LC_ALL, "");

  /* Initialize the message catalog.  */
  textdomain (PACKAGE_TARNAME);

  /* Parse and process arguments.  */
  int remaining;
  argp_parse (&argp, argc, argv, 0, &remaining, NULL);

  /* Before we start tell the ELF library which version we are using.  */
  elf_version (EV_CURRENT);

  /* Now process all the files given at the command line.  */
  bool only_one = remaining + 1 == argc;
  do
    {
      /* Open the file.  */
      int fd = open (argv[remaining], O_RDONLY);
      if (fd == -1)
	{
	  error (0, errno, gettext ("cannot open input file"));
	  continue;
	}

      /* Create an `Elf' descriptor.  */
      Elf *elf = elf_begin (fd, ELF_C_READ_MMAP, NULL);
      if (elf == NULL)
	ERROR (gettext ("cannot generate Elf descriptor: %s\n"),
	       elf_errmsg (-1));
      else
	{
	  unsigned int prev_error_count = error_count;
	  struct stat64 st;

	  if (fstat64 (fd, &st) != 0)
	    {
	      printf ("cannot stat '%s': %m\n", argv[remaining]);
	      close (fd);
	      continue;
	    }

	  process_file (fd, elf, NULL, NULL, argv[remaining], st.st_size,
			only_one);

	  /* Now we can close the descriptor.  */
	  if (elf_end (elf) != 0)
	    ERROR (gettext ("error while closing Elf descriptor: %s\n"),
		   elf_errmsg (-1));

	  if (prev_error_count == error_count && !be_quiet)
	    puts (gettext ("No errors"));
	}

      close (fd);
    }
  while (++remaining < argc);

  return error_count != 0;
}


/* Handle program arguments.  */
static error_t
parse_opt (int key, char *arg __attribute__ ((unused)),
	   struct argp_state *state __attribute__ ((unused)))
{
  switch (key)
    {
    case ARGP_strict:
      be_strict = true;
      break;

    case 'q':
      be_quiet = true;
      break;

    case 'd':
      is_debuginfo = true;

    case ARGP_gnuld:
      gnuld = true;
      break;

    case ARGP_KEY_NO_ARGS:
      fputs (gettext ("Missing file name.\n"), stderr);
      argp_help (&argp, stderr, ARGP_HELP_SEE, program_invocation_short_name);
      exit (EXIT_FAILURE);

    default:
      return ARGP_ERR_UNKNOWN;
    }
  return 0;
}


/* Print the version information.  */
static void
print_version (FILE *stream, struct argp_state *state __attribute__ ((unused)))
{
  fprintf (stream, "elflint (%s) %s\n", PACKAGE_NAME, PACKAGE_VERSION);
  fprintf (stream, gettext ("\
Copyright (C) %s Red Hat, Inc.\n\
This is free software; see the source for copying conditions.  There is NO\n\
warranty; not even for MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.\n\
"), "2012");
  fprintf (stream, gettext ("Written by %s.\n"), "Ulrich Drepper");
}


/* Process one file.  */
static void
process_file (int fd, Elf *elf, const char *prefix, const char *suffix,
	      const char *fname, size_t size, bool only_one)
{
  /* We can handle two types of files: ELF files and archives.  */
  Elf_Kind kind = elf_kind (elf);

  switch (kind)
    {
    case ELF_K_ELF:
      /* Yes!  It's an ELF file.  */
      process_elf_file (elf, prefix, suffix, fname, size, only_one);
      break;

    case ELF_K_AR:
      {
	Elf *subelf;
	Elf_Cmd cmd = ELF_C_READ_MMAP;
	size_t prefix_len = prefix == NULL ? 0 : strlen (prefix);
	size_t fname_len = strlen (fname) + 1;
	char new_prefix[prefix_len + 1 + fname_len];
	char new_suffix[(suffix == NULL ? 0 : strlen (suffix)) + 2];
	char *cp = new_prefix;

	/* Create the full name of the file.  */
	if (prefix != NULL)
	  {
	    cp = mempcpy (cp, prefix, prefix_len);
	    *cp++ = '(';
	    strcpy (stpcpy (new_suffix, suffix), ")");
	  }
	else
	  new_suffix[0] = '\0';
	memcpy (cp, fname, fname_len);

	/* It's an archive.  We process each file in it.  */
	while ((subelf = elf_begin (fd, cmd, elf)) != NULL)
	  {
	    kind = elf_kind (subelf);

	    /* Call this function recursively.  */
	    if (kind == ELF_K_ELF || kind == ELF_K_AR)
	      {
		Elf_Arhdr *arhdr = elf_getarhdr (subelf);
		assert (arhdr != NULL);

		process_file (fd, subelf, new_prefix, new_suffix,
			      arhdr->ar_name, arhdr->ar_size, false);
	      }

	    /* Get next archive element.  */
	    cmd = elf_next (subelf);
	    if (elf_end (subelf) != 0)
	      ERROR (gettext (" error while freeing sub-ELF descriptor: %s\n"),
		     elf_errmsg (-1));
	  }
      }
      break;

    default:
      /* We cannot do anything.  */
      ERROR (gettext ("\
Not an ELF file - it has the wrong magic bytes at the start\n"));
      break;
    }
}


static const char *
section_name (Ebl *ebl, int idx)
{
  GElf_Shdr shdr_mem;
  GElf_Shdr *shdr;
  const char *ret;

  if ((unsigned int) idx > shnum)
    return "<invalid>";

  shdr = gelf_getshdr (elf_getscn (ebl->elf, idx), &shdr_mem);
  if (shdr == NULL)
    return "<invalid>";

  ret = elf_strptr (ebl->elf, shstrndx, shdr->sh_name);
  if (ret == NULL)
    return "<invalid>";
  return ret;
}


static const int valid_e_machine[] =
  {
    EM_M32, EM_SPARC, EM_386, EM_68K, EM_88K, EM_860, EM_MIPS, EM_S370,
    EM_MIPS_RS3_LE, EM_PARISC, EM_VPP500, EM_SPARC32PLUS, EM_960, EM_PPC,
    EM_PPC64, EM_S390, EM_V800, EM_FR20, EM_RH32, EM_RCE, EM_ARM,
    EM_FAKE_ALPHA, EM_SH, EM_SPARCV9, EM_TRICORE, EM_ARC, EM_H8_300,
    EM_H8_300H, EM_H8S, EM_H8_500, EM_IA_64, EM_MIPS_X, EM_COLDFIRE,
    EM_68HC12, EM_MMA, EM_PCP, EM_NCPU, EM_NDR1, EM_STARCORE, EM_ME16,
    EM_ST100, EM_TINYJ, EM_X86_64, EM_PDSP, EM_FX66, EM_ST9PLUS, EM_ST7,
    EM_68HC16, EM_68HC11, EM_68HC08, EM_68HC05, EM_SVX, EM_ST19, EM_VAX,
    EM_CRIS, EM_JAVELIN, EM_FIREPATH, EM_ZSP, EM_MMIX, EM_HUANY, EM_PRISM,
    EM_AVR, EM_FR30, EM_D10V, EM_D30V, EM_V850, EM_M32R, EM_MN10300,
    EM_MN10200, EM_PJ, EM_OPENRISC, EM_ARC_A5, EM_XTENSA, EM_ALPHA,
    EM_TILEGX, EM_TILEPRO, EM_AARCH64
  };
#define nvalid_e_machine \
  (sizeof (valid_e_machine) / sizeof (valid_e_machine[0]))


static void
check_elf_header (Ebl *ebl, GElf_Ehdr *ehdr, size_t size)
{
  char buf[512];
  size_t cnt;

  /* Check e_ident field.  */
  if (ehdr->e_ident[EI_MAG0] != ELFMAG0)
    ERROR ("e_ident[%d] != '%c'\n", EI_MAG0, ELFMAG0);
  if (ehdr->e_ident[EI_MAG1] != ELFMAG1)
    ERROR ("e_ident[%d] != '%c'\n", EI_MAG1, ELFMAG1);
  if (ehdr->e_ident[EI_MAG2] != ELFMAG2)
    ERROR ("e_ident[%d] != '%c'\n", EI_MAG2, ELFMAG2);
  if (ehdr->e_ident[EI_MAG3] != ELFMAG3)
    ERROR ("e_ident[%d] != '%c'\n", EI_MAG3, ELFMAG3);

  if (ehdr->e_ident[EI_CLASS] != ELFCLASS32
      && ehdr->e_ident[EI_CLASS] != ELFCLASS64)
    ERROR (gettext ("e_ident[%d] == %d is no known class\n"),
	   EI_CLASS, ehdr->e_ident[EI_CLASS]);

  if (ehdr->e_ident[EI_DATA] != ELFDATA2LSB
      && ehdr->e_ident[EI_DATA] != ELFDATA2MSB)
    ERROR (gettext ("e_ident[%d] == %d is no known data encoding\n"),
	   EI_DATA, ehdr->e_ident[EI_DATA]);

  if (ehdr->e_ident[EI_VERSION] != EV_CURRENT)
    ERROR (gettext ("unknown ELF header version number e_ident[%d] == %d\n"),
	   EI_VERSION, ehdr->e_ident[EI_VERSION]);

  /* We currently don't handle any OS ABIs other than Linux.  */
  if (ehdr->e_ident[EI_OSABI] != ELFOSABI_NONE
      && ehdr->e_ident[EI_OSABI] != ELFOSABI_LINUX)
    ERROR (gettext ("unsupported OS ABI e_ident[%d] == '%s'\n"),
	   EI_OSABI,
	   ebl_osabi_name (ebl, ehdr->e_ident[EI_OSABI], buf, sizeof (buf)));

  /* No ABI versions other than zero supported either.  */
  if (ehdr->e_ident[EI_ABIVERSION] != 0)
    ERROR (gettext ("unsupport ABI version e_ident[%d] == %d\n"),
	   EI_ABIVERSION, ehdr->e_ident[EI_ABIVERSION]);

  for (cnt = EI_PAD; cnt < EI_NIDENT; ++cnt)
    if (ehdr->e_ident[cnt] != 0)
      ERROR (gettext ("e_ident[%zu] is not zero\n"), cnt);

  /* Check the e_type field.  */
  if (ehdr->e_type != ET_REL && ehdr->e_type != ET_EXEC
      && ehdr->e_type != ET_DYN && ehdr->e_type != ET_CORE)
    ERROR (gettext ("unknown object file type %d\n"), ehdr->e_type);

  /* Check the e_machine field.  */
  for (cnt = 0; cnt < nvalid_e_machine; ++cnt)
    if (valid_e_machine[cnt] == ehdr->e_machine)
      break;
  if (cnt == nvalid_e_machine)
    ERROR (gettext ("unknown machine type %d\n"), ehdr->e_machine);

  /* Check the e_version field.  */
  if (ehdr->e_version != EV_CURRENT)
    ERROR (gettext ("unknown object file version\n"));

  /* Check the e_phoff and e_phnum fields.  */
  if (ehdr->e_phoff == 0)
    {
      if (ehdr->e_phnum != 0)
	ERROR (gettext ("invalid program header offset\n"));
      else if (ehdr->e_type == ET_EXEC || ehdr->e_type == ET_DYN)
	ERROR (gettext ("\
executables and DSOs cannot have zero program header offset\n"));
    }
  else if (ehdr->e_phnum == 0)
    ERROR (gettext ("invalid number of program header entries\n"));

  /* Check the e_shoff field.  */
  shnum = ehdr->e_shnum;
  shstrndx = ehdr->e_shstrndx;
  if (ehdr->e_shoff == 0)
    {
      if (ehdr->e_shnum != 0)
	ERROR (gettext ("invalid section header table offset\n"));
      else if (ehdr->e_type != ET_EXEC && ehdr->e_type != ET_DYN
	       && ehdr->e_type != ET_CORE)
	ERROR (gettext ("section header table must be present\n"));
    }
  else
    {
      if (ehdr->e_shnum == 0)
	{
	  /* Get the header of the zeroth section.  The sh_size field
	     might contain the section number.  */
	  GElf_Shdr shdr_mem;
	  GElf_Shdr *shdr = gelf_getshdr (elf_getscn (ebl->elf, 0), &shdr_mem);
	  if (shdr != NULL)
	    {
	      /* The error will be reported later.  */
	      if (shdr->sh_size == 0)
		ERROR (gettext ("\
invalid number of section header table entries\n"));
	      else
		shnum = shdr->sh_size;
	    }
	}

      if (ehdr->e_shstrndx == SHN_XINDEX)
	{
	  /* Get the header of the zeroth section.  The sh_size field
	     might contain the section number.  */
	  GElf_Shdr shdr_mem;
	  GElf_Shdr *shdr = gelf_getshdr (elf_getscn (ebl->elf, 0), &shdr_mem);
	  if (shdr != NULL && shdr->sh_link < shnum)
	    shstrndx = shdr->sh_link;
	}
      else if (shstrndx >= shnum)
	ERROR (gettext ("invalid section header index\n"));
    }

  phnum = ehdr->e_phnum;
  if (ehdr->e_phnum == PN_XNUM)
    {
      /* Get the header of the zeroth section.  The sh_info field
	 might contain the phnum count.  */
      GElf_Shdr shdr_mem;
      GElf_Shdr *shdr = gelf_getshdr (elf_getscn (ebl->elf, 0), &shdr_mem);
      if (shdr != NULL)
	{
	  /* The error will be reported later.  */
	  if (shdr->sh_info < PN_XNUM)
	    ERROR (gettext ("\
invalid number of program header table entries\n"));
	  else
	    phnum = shdr->sh_info;
	}
    }

  /* Check the e_flags field.  */
  if (!ebl_machine_flag_check (ebl, ehdr->e_flags))
    ERROR (gettext ("invalid machine flags: %s\n"),
	   ebl_machine_flag_name (ebl, ehdr->e_flags, buf, sizeof (buf)));

  /* Check e_ehsize, e_phentsize, and e_shentsize fields.  */
  if (gelf_getclass (ebl->elf) == ELFCLASS32)
    {
      if (ehdr->e_ehsize != 0 && ehdr->e_ehsize != sizeof (Elf32_Ehdr))
	ERROR (gettext ("invalid ELF header size: %hd\n"), ehdr->e_ehsize);

      if (ehdr->e_phentsize != 0 && ehdr->e_phentsize != sizeof (Elf32_Phdr))
	ERROR (gettext ("invalid program header size: %hd\n"),
	       ehdr->e_phentsize);
      else if (ehdr->e_phoff + phnum * ehdr->e_phentsize > size)
	ERROR (gettext ("invalid program header position or size\n"));

      if (ehdr->e_shentsize != 0 && ehdr->e_shentsize != sizeof (Elf32_Shdr))
	ERROR (gettext ("invalid section header size: %hd\n"),
	       ehdr->e_shentsize);
      else if (ehdr->e_shoff + shnum * ehdr->e_shentsize > size)
	ERROR (gettext ("invalid section header position or size\n"));
    }
  else if (gelf_getclass (ebl->elf) == ELFCLASS64)
    {
      if (ehdr->e_ehsize != 0 && ehdr->e_ehsize != sizeof (Elf64_Ehdr))
	ERROR (gettext ("invalid ELF header size: %hd\n"), ehdr->e_ehsize);

      if (ehdr->e_phentsize != 0 && ehdr->e_phentsize != sizeof (Elf64_Phdr))
	ERROR (gettext ("invalid program header size: %hd\n"),
	       ehdr->e_phentsize);
      else if (ehdr->e_phoff + phnum * ehdr->e_phentsize > size)
	ERROR (gettext ("invalid program header position or size\n"));

      if (ehdr->e_shentsize != 0 && ehdr->e_shentsize != sizeof (Elf64_Shdr))
	ERROR (gettext ("invalid section header size: %hd\n"),
	       ehdr->e_shentsize);
      else if (ehdr->e_shoff + ehdr->e_shnum * ehdr->e_shentsize > size)
	ERROR (gettext ("invalid section header position or size\n"));
    }
}


/* Check that there is a section group section with index < IDX which
   contains section IDX and that there is exactly one.  */
static void
check_scn_group (Ebl *ebl, int idx)
{
  if (scnref[idx] == 0)
    {
      /* No reference so far.  Search following sections, maybe the
	 order is wrong.  */
      size_t cnt;

      for (cnt = idx + 1; cnt < shnum; ++cnt)
	{
	  Elf_Scn *scn = elf_getscn (ebl->elf, cnt);
	  GElf_Shdr shdr_mem;
	  GElf_Shdr *shdr = gelf_getshdr (scn, &shdr_mem);
	  if (shdr == NULL)
	    /* We cannot get the section header so we cannot check it.
	       The error to get the section header will be shown
	       somewhere else.  */
	    continue;

	  if (shdr->sh_type != SHT_GROUP)
	    continue;

	  Elf_Data *data = elf_getdata (scn, NULL);
	  if (data == NULL || data->d_size < sizeof (Elf32_Word))
	    /* Cannot check the section.  */
	    continue;

	  Elf32_Word *grpdata = (Elf32_Word *) data->d_buf;
	  for (size_t inner = 1; inner < data->d_size / sizeof (Elf32_Word);
	       ++inner)
	    if (grpdata[inner] == (Elf32_Word) idx)
	      goto out;
	}

    out:
      if (cnt == shnum)
	ERROR (gettext ("\
section [%2d] '%s': section with SHF_GROUP flag set not part of a section group\n"),
	       idx, section_name (ebl, idx));
      else
	ERROR (gettext ("\
section [%2d] '%s': section group [%2zu] '%s' does not precede group member\n"),
	       idx, section_name (ebl, idx),
	       cnt, section_name (ebl, cnt));
    }
}


static void
check_symtab (Ebl *ebl, GElf_Ehdr *ehdr, GElf_Shdr *shdr, int idx)
{
  bool no_xndx_warned = false;
  int no_pt_tls = 0;
  Elf_Data *data = elf_getdata (elf_getscn (ebl->elf, idx), NULL);
  if (data == NULL)
    {
      ERROR (gettext ("section [%2d] '%s': cannot get section data\n"),
	     idx, section_name (ebl, idx));
      return;
    }

  GElf_Shdr strshdr_mem;
  GElf_Shdr *strshdr = gelf_getshdr (elf_getscn (ebl->elf, shdr->sh_link),
				     &strshdr_mem);
  if (strshdr == NULL)
    return;

  if (strshdr->sh_type != SHT_STRTAB)
    {
      ERROR (gettext ("section [%2d] '%s': referenced as string table for section [%2d] '%s' but type is not SHT_STRTAB\n"),
	     shdr->sh_link, section_name (ebl, shdr->sh_link),
	     idx, section_name (ebl, idx));
      strshdr = NULL;
    }

  /* Search for an extended section index table section.  */
  Elf_Data *xndxdata = NULL;
  Elf32_Word xndxscnidx = 0;
  bool found_xndx = false;
  for (size_t cnt = 1; cnt < shnum; ++cnt)
    if (cnt != (size_t) idx)
      {
	Elf_Scn *xndxscn = elf_getscn (ebl->elf, cnt);
	GElf_Shdr xndxshdr_mem;
	GElf_Shdr *xndxshdr = gelf_getshdr (xndxscn, &xndxshdr_mem);
	if (xndxshdr == NULL)
	  continue;

	if (xndxshdr->sh_type == SHT_SYMTAB_SHNDX
	    && xndxshdr->sh_link == (GElf_Word) idx)
	  {
	    if (found_xndx)
	      ERROR (gettext ("\
section [%2d] '%s': symbol table cannot have more than one extended index section\n"),
		     idx, section_name (ebl, idx));

	    xndxdata = elf_getdata (xndxscn, NULL);
	    xndxscnidx = elf_ndxscn (xndxscn);
	    found_xndx = true;
	  }
      }

  size_t sh_entsize = gelf_fsize (ebl->elf, ELF_T_SYM, 1, EV_CURRENT);
  if (shdr->sh_entsize != sh_entsize)
    ERROR (gettext ("\
section [%2u] '%s': entry size is does not match ElfXX_Sym\n"),
	   idx, section_name (ebl, idx));

  /* Test the zeroth entry.  */
  GElf_Sym sym_mem;
  Elf32_Word xndx;
  GElf_Sym *sym = gelf_getsymshndx (data, xndxdata, 0, &sym_mem, &xndx);
  if (sym == NULL)
      ERROR (gettext ("section [%2d] '%s': cannot get symbol %d: %s\n"),
	     idx, section_name (ebl, idx), 0, elf_errmsg (-1));
  else
    {
      if (sym->st_name != 0)
	ERROR (gettext ("section [%2d] '%s': '%s' in zeroth entry not zero\n"),
	       idx, section_name (ebl, idx), "st_name");
      if (sym->st_value != 0)
	ERROR (gettext ("section [%2d] '%s': '%s' in zeroth entry not zero\n"),
	       idx, section_name (ebl, idx), "st_value");
      if (sym->st_size != 0)
	ERROR (gettext ("section [%2d] '%s': '%s' in zeroth entry not zero\n"),
	       idx, section_name (ebl, idx), "st_size");
      if (sym->st_info != 0)
	ERROR (gettext ("section [%2d] '%s': '%s' in zeroth entry not zero\n"),
	       idx, section_name (ebl, idx), "st_info");
      if (sym->st_other != 0)
	ERROR (gettext ("section [%2d] '%s': '%s' in zeroth entry not zero\n"),
	       idx, section_name (ebl, idx), "st_other");
      if (sym->st_shndx != 0)
	ERROR (gettext ("section [%2d] '%s': '%s' in zeroth entry not zero\n"),
	       idx, section_name (ebl, idx), "st_shndx");
      if (xndxdata != NULL && xndx != 0)
	ERROR (gettext ("\
section [%2d] '%s': XINDEX for zeroth entry not zero\n"),
	       xndxscnidx, section_name (ebl, xndxscnidx));
    }

  for (size_t cnt = 1; cnt < shdr->sh_size / sh_entsize; ++cnt)
    {
      sym = gelf_getsymshndx (data, xndxdata, cnt, &sym_mem, &xndx);
      if (sym == NULL)
	{
	  ERROR (gettext ("section [%2d] '%s': cannot get symbol %zu: %s\n"),
		 idx, section_name (ebl, idx), cnt, elf_errmsg (-1));
	  continue;
	}

      const char *name = NULL;
      if (strshdr == NULL)
	name = "";
      else if (sym->st_name >= strshdr->sh_size)
	ERROR (gettext ("\
section [%2d] '%s': symbol %zu: invalid name value\n"),
	       idx, section_name (ebl, idx), cnt);
      else
	{
	  name = elf_strptr (ebl->elf, shdr->sh_link, sym->st_name);
	  assert (name != NULL
		  || strshdr->sh_type != SHT_STRTAB);
	}

      if (sym->st_shndx == SHN_XINDEX)
	{
	  if (xndxdata == NULL)
	    {
	      if (!no_xndx_warned)
		ERROR (gettext ("\
section [%2d] '%s': symbol %zu: too large section index but no extended section index section\n"),
		       idx, section_name (ebl, idx), cnt);
	      no_xndx_warned = true;
	    }
	  else if (xndx < SHN_LORESERVE)
	    ERROR (gettext ("\
section [%2d] '%s': symbol %zu: XINDEX used for index which would fit in st_shndx (%" PRIu32 ")\n"),
		   xndxscnidx, section_name (ebl, xndxscnidx), cnt,
		   xndx);
	}
      else if ((sym->st_shndx >= SHN_LORESERVE
		// && sym->st_shndx <= SHN_HIRESERVE    always true
		&& sym->st_shndx != SHN_ABS
		&& sym->st_shndx != SHN_COMMON)
	       || (sym->st_shndx >= shnum
		   && (sym->st_shndx < SHN_LORESERVE
		       /* || sym->st_shndx > SHN_HIRESERVE  always false */)))
	ERROR (gettext ("\
section [%2d] '%s': symbol %zu: invalid section index\n"),
	       idx, section_name (ebl, idx), cnt);
      else
	xndx = sym->st_shndx;

      if (GELF_ST_TYPE (sym->st_info) >= STT_NUM
	  && !ebl_symbol_type_name (ebl, GELF_ST_TYPE (sym->st_info), NULL, 0))
	ERROR (gettext ("section [%2d] '%s': symbol %zu: unknown type\n"),
	       idx, section_name (ebl, idx), cnt);

      if (GELF_ST_BIND (sym->st_info) >= STB_NUM
	  && !ebl_symbol_binding_name (ebl, GELF_ST_BIND (sym->st_info), NULL,
				       0))
	ERROR (gettext ("\
section [%2d] '%s': symbol %zu: unknown symbol binding\n"),
	       idx, section_name (ebl, idx), cnt);
      if (GELF_ST_BIND (sym->st_info) == STB_GNU_UNIQUE
	  && GELF_ST_TYPE (sym->st_info) != STT_OBJECT)
	ERROR (gettext ("\
section [%2d] '%s': symbol %zu: unique symbol not of object type\n"),
	       idx, section_name (ebl, idx), cnt);

      if (xndx == SHN_COMMON)
	{
	  /* Common symbols can only appear in relocatable files.  */
	  if (ehdr->e_type != ET_REL)
	    ERROR (gettext ("\
section [%2d] '%s': symbol %zu: COMMON only allowed in relocatable files\n"),
		   idx, section_name (ebl, idx), cnt);
	  if (cnt < shdr->sh_info)
	    ERROR (gettext ("\
section [%2d] '%s': symbol %zu: local COMMON symbols are nonsense\n"),
		   idx, section_name (ebl, idx), cnt);
	  if (GELF_R_TYPE (sym->st_info) == STT_FUNC)
	    ERROR (gettext ("\
section [%2d] '%s': symbol %zu: function in COMMON section is nonsense\n"),
		   idx, section_name (ebl, idx), cnt);
	}
      else if (xndx > 0 && xndx < shnum)
	{
	  GElf_Shdr destshdr_mem;
	  GElf_Shdr *destshdr;

	  destshdr = gelf_getshdr (elf_getscn (ebl->elf, xndx), &destshdr_mem);
	  if (destshdr != NULL)
	    {
	      GElf_Addr sh_addr = (ehdr->e_type == ET_REL ? 0
				   : destshdr->sh_addr);
	      GElf_Addr st_value;
	      if (GELF_ST_TYPE (sym->st_info) == STT_FUNC
		  || (GELF_ST_TYPE (sym->st_info) == STT_GNU_IFUNC))
		st_value = sym->st_value & ebl_func_addr_mask (ebl);
	      else
		st_value = sym->st_value;
	      if (GELF_ST_TYPE (sym->st_info) != STT_TLS)
		{
		  if (! ebl_check_special_symbol (ebl, ehdr, sym, name,
						  destshdr))
		    {
		      if (st_value - sh_addr > destshdr->sh_size)
			{
			  /* GNU ld has severe bugs.  When it decides to remove
			     empty sections it leaves symbols referencing them
			     behind.  These are symbols in .symtab or .dynsym
			     and for the named symbols have zero size.  See
			     sourceware PR13621.  */
			  if (!gnuld
			      || (strcmp (section_name (ebl, idx), ".symtab")
			          && strcmp (section_name (ebl, idx),
					     ".dynsym"))
			      || sym->st_size != 0
			      || (strcmp (name, "__preinit_array_start") != 0
				  && strcmp (name, "__preinit_array_end") != 0
				  && strcmp (name, "__init_array_start") != 0
				  && strcmp (name, "__init_array_end") != 0
				  && strcmp (name, "__fini_array_start") != 0
				  && strcmp (name, "__fini_array_end") != 0
				  && strcmp (name, "__bss_start") != 0
				  && strcmp (name, "__bss_start__") != 0
				  && strcmp (name, "__TMC_END__") != 0
				  && strcmp (name, ".TOC.") != 0))
			    ERROR (gettext ("\
section [%2d] '%s': symbol %zu: st_value out of bounds\n"),
				   idx, section_name (ebl, idx), cnt);
			}
		      else if ((st_value - sh_addr
				+ sym->st_size) > destshdr->sh_size)
			ERROR (gettext ("\
section [%2d] '%s': symbol %zu does not fit completely in referenced section [%2d] '%s'\n"),
			       idx, section_name (ebl, idx), cnt,
			       (int) xndx, section_name (ebl, xndx));
		    }
		}
	      else
		{
		  if ((destshdr->sh_flags & SHF_TLS) == 0)
		    ERROR (gettext ("\
section [%2d] '%s': symbol %zu: referenced section [%2d] '%s' does not have SHF_TLS flag set\n"),
			   idx, section_name (ebl, idx), cnt,
			   (int) xndx, section_name (ebl, xndx));

		  if (ehdr->e_type == ET_REL)
		    {
		      /* For object files the symbol value must fall
			 into the section.  */
		      if (st_value > destshdr->sh_size)
			ERROR (gettext ("\
section [%2d] '%s': symbol %zu: st_value out of bounds of referenced section [%2d] '%s'\n"),
			       idx, section_name (ebl, idx), cnt,
			       (int) xndx, section_name (ebl, xndx));
		      else if (st_value + sym->st_size
			       > destshdr->sh_size)
			ERROR (gettext ("\
section [%2d] '%s': symbol %zu does not fit completely in referenced section [%2d] '%s'\n"),
			       idx, section_name (ebl, idx), cnt,
			       (int) xndx, section_name (ebl, xndx));
		    }
		  else
		    {
		      GElf_Phdr phdr_mem;
		      GElf_Phdr *phdr = NULL;
		      unsigned int pcnt;

		      for (pcnt = 0; pcnt < phnum; ++pcnt)
			{
			  phdr = gelf_getphdr (ebl->elf, pcnt, &phdr_mem);
			  if (phdr != NULL && phdr->p_type == PT_TLS)
			    break;
			}

		      if (pcnt == phnum)
			{
			  if (no_pt_tls++ == 0)
			    ERROR (gettext ("\
section [%2d] '%s': symbol %zu: TLS symbol but no TLS program header entry\n"),
				   idx, section_name (ebl, idx), cnt);
			}
		      else
			{
			  if (st_value
			      < destshdr->sh_offset - phdr->p_offset)
			    ERROR (gettext ("\
section [%2d] '%s': symbol %zu: st_value short of referenced section [%2d] '%s'\n"),
				   idx, section_name (ebl, idx), cnt,
				   (int) xndx, section_name (ebl, xndx));
			  else if (st_value
				   > (destshdr->sh_offset - phdr->p_offset
				      + destshdr->sh_size))
			    ERROR (gettext ("\
section [%2d] '%s': symbol %zu: st_value out of bounds of referenced section [%2d] '%s'\n"),
				   idx, section_name (ebl, idx), cnt,
				   (int) xndx, section_name (ebl, xndx));
			  else if (st_value + sym->st_size
				   > (destshdr->sh_offset - phdr->p_offset
				      + destshdr->sh_size))
			    ERROR (gettext ("\
section [%2d] '%s': symbol %zu does not fit completely in referenced section [%2d] '%s'\n"),
				   idx, section_name (ebl, idx), cnt,
				   (int) xndx, section_name (ebl, xndx));
			}
		    }
		}
	    }
	}

      if (GELF_ST_BIND (sym->st_info) == STB_LOCAL)
	{
	  if (cnt >= shdr->sh_info)
	    ERROR (gettext ("\
section [%2d] '%s': symbol %zu: local symbol outside range described in sh_info\n"),
		   idx, section_name (ebl, idx), cnt);
	}
      else
	{
	  if (cnt < shdr->sh_info)
	    ERROR (gettext ("\
section [%2d] '%s': symbol %zu: non-local symbol outside range described in sh_info\n"),
		   idx, section_name (ebl, idx), cnt);
	}

      if (GELF_ST_TYPE (sym->st_info) == STT_SECTION
	  && GELF_ST_BIND (sym->st_info) != STB_LOCAL)
	ERROR (gettext ("\
section [%2d] '%s': symbol %zu: non-local section symbol\n"),
	       idx, section_name (ebl, idx), cnt);

      if (name != NULL)
	{
	  if (strcmp (name, "_GLOBAL_OFFSET_TABLE_") == 0)
	    {
	      /* Check that address and size match the global offset table.  */

	      GElf_Shdr destshdr_mem;
	      GElf_Shdr *destshdr = gelf_getshdr (elf_getscn (ebl->elf, xndx),
						  &destshdr_mem);

	      if (destshdr == NULL && xndx == SHN_ABS)
		{
		  /* In a DSO, we have to find the GOT section by name.  */
		  Elf_Scn *gotscn = NULL;
		  Elf_Scn *gscn = NULL;
		  while ((gscn = elf_nextscn (ebl->elf, gscn)) != NULL)
		    {
		      destshdr = gelf_getshdr (gscn, &destshdr_mem);
		      assert (destshdr != NULL);
		      const char *sname = elf_strptr (ebl->elf,
						      ehdr->e_shstrndx,
						      destshdr->sh_name);
		      if (sname != NULL)
			{
			  if (strcmp (sname, ".got.plt") == 0)
			    break;
			  if (strcmp (sname, ".got") == 0)
			    /* Do not stop looking.
			       There might be a .got.plt section.  */
			    gotscn = gscn;
			}

		      destshdr = NULL;
		    }

		  if (destshdr == NULL && gotscn != NULL)
		    destshdr = gelf_getshdr (gotscn, &destshdr_mem);
		}

	      const char *sname = ((destshdr == NULL || xndx == SHN_UNDEF)
				   ? NULL
				   : elf_strptr (ebl->elf, ehdr->e_shstrndx,
						 destshdr->sh_name));
	      if (sname == NULL)
		{
		  if (xndx != SHN_UNDEF || ehdr->e_type != ET_REL)
		    ERROR (gettext ("\
section [%2d] '%s': _GLOBAL_OFFSET_TABLE_ symbol refers to \
bad section [%2d]\n"),
			   idx, section_name (ebl, idx), xndx);
		}
	      else if (strcmp (sname, ".got.plt") != 0
		       && strcmp (sname, ".got") != 0)
		ERROR (gettext ("\
section [%2d] '%s': _GLOBAL_OFFSET_TABLE_ symbol refers to \
section [%2d] '%s'\n"),
		       idx, section_name (ebl, idx), xndx, sname);

	      if (destshdr != NULL)
		{
		  /* Found it.  */
		  if (!ebl_check_special_symbol (ebl, ehdr, sym, name,
						 destshdr))
		    {
		      if (ehdr->e_type != ET_REL
			  && sym->st_value != destshdr->sh_addr)
			/* This test is more strict than the psABIs which
			   usually allow the symbol to be in the middle of
			   the .got section, allowing negative offsets.  */
			ERROR (gettext ("\
section [%2d] '%s': _GLOBAL_OFFSET_TABLE_ symbol value %#" PRIx64 " does not match %s section address %#" PRIx64 "\n"),
			       idx, section_name (ebl, idx),
			       (uint64_t) sym->st_value,
			       sname, (uint64_t) destshdr->sh_addr);

		      if (!gnuld && sym->st_size != destshdr->sh_size)
			ERROR (gettext ("\
section [%2d] '%s': _GLOBAL_OFFSET_TABLE_ symbol size %" PRIu64 " does not match %s section size %" PRIu64 "\n"),
			       idx, section_name (ebl, idx),
			       (uint64_t) sym->st_size,
			       sname, (uint64_t) destshdr->sh_size);
		    }
		}
	      else
		ERROR (gettext ("\
section [%2d] '%s': _GLOBAL_OFFSET_TABLE_ symbol present, but no .got section\n"),
		       idx, section_name (ebl, idx));
	    }
	  else if (strcmp (name, "_DYNAMIC") == 0)
	    /* Check that address and size match the dynamic section.
	       We locate the dynamic section via the program header
	       entry.  */
	    for (unsigned int pcnt = 0; pcnt < phnum; ++pcnt)
	      {
		GElf_Phdr phdr_mem;
		GElf_Phdr *phdr = gelf_getphdr (ebl->elf, pcnt, &phdr_mem);

		if (phdr != NULL && phdr->p_type == PT_DYNAMIC)
		  {
		    if (sym->st_value != phdr->p_vaddr)
		      ERROR (gettext ("\
section [%2d] '%s': _DYNAMIC_ symbol value %#" PRIx64 " does not match dynamic segment address %#" PRIx64 "\n"),
			     idx, section_name (ebl, idx),
			     (uint64_t) sym->st_value,
			     (uint64_t) phdr->p_vaddr);

		    if (!gnuld && sym->st_size != phdr->p_memsz)
		      ERROR (gettext ("\
section [%2d] '%s': _DYNAMIC symbol size %" PRIu64 " does not match dynamic segment size %" PRIu64 "\n"),
			     idx, section_name (ebl, idx),
			     (uint64_t) sym->st_size,
			     (uint64_t) phdr->p_memsz);

		    break;
		  }
	    }
	}

      if (GELF_ST_VISIBILITY (sym->st_other) != STV_DEFAULT
	  && shdr->sh_type == SHT_DYNSYM)
	ERROR (gettext ("\
section [%2d] '%s': symbol %zu: symbol in dynamic symbol table with non-default visibility\n"),
	       idx, section_name (ebl, idx), cnt);
      if (! ebl_check_st_other_bits (ebl, sym->st_other))
	ERROR (gettext ("\
section [%2d] '%s': symbol %zu: unknown bit set in st_other\n"),
	       idx, section_name (ebl, idx), cnt);

    }
}


static bool
is_rel_dyn (Ebl *ebl, const GElf_Ehdr *ehdr, int idx, const GElf_Shdr *shdr,
	    bool is_rela)
{
  /* If this is no executable or DSO it cannot be a .rel.dyn section.  */
  if (ehdr->e_type != ET_EXEC && ehdr->e_type != ET_DYN)
    return false;

  /* Check the section name.  Unfortunately necessary.  */
  if (strcmp (section_name (ebl, idx), is_rela ? ".rela.dyn" : ".rel.dyn"))
    return false;

  /* When a .rel.dyn section is used a DT_RELCOUNT dynamic section
     entry can be present as well.  */
  Elf_Scn *scn = NULL;
  while ((scn = elf_nextscn (ebl->elf, scn)) != NULL)
    {
      GElf_Shdr rcshdr_mem;
      const GElf_Shdr *rcshdr = gelf_getshdr (scn, &rcshdr_mem);

      if (rcshdr == NULL)
	break;

      if (rcshdr->sh_type == SHT_DYNAMIC && rcshdr->sh_entsize)
	{
	  /* Found the dynamic section.  Look through it.  */
	  Elf_Data *d = elf_getdata (scn, NULL);
	  size_t cnt;

	  for (cnt = 1; cnt < rcshdr->sh_size / rcshdr->sh_entsize; ++cnt)
	    {
	      GElf_Dyn dyn_mem;
	      GElf_Dyn *dyn = gelf_getdyn (d, cnt, &dyn_mem);

	      if (dyn == NULL)
		break;

	      if (dyn->d_tag == DT_RELCOUNT)
		{
		  /* Found it.  Does the type match.  */
		  if (is_rela)
		    ERROR (gettext ("\
section [%2d] '%s': DT_RELCOUNT used for this RELA section\n"),
			   idx, section_name (ebl, idx));
		  else
		    {
		      /* Does the number specified number of relative
			 relocations exceed the total number of
			 relocations?  */
		      if (shdr->sh_entsize != 0
			  && dyn->d_un.d_val > (shdr->sh_size
						/ shdr->sh_entsize))
			ERROR (gettext ("\
section [%2d] '%s': DT_RELCOUNT value %d too high for this section\n"),
			       idx, section_name (ebl, idx),
			       (int) dyn->d_un.d_val);

		      /* Make sure the specified number of relocations are
			 relative.  */
		      Elf_Data *reldata = elf_getdata (elf_getscn (ebl->elf,
								   idx), NULL);
		      if (reldata != NULL)
			for (size_t inner = 0;
			     inner < shdr->sh_size / shdr->sh_entsize;
			     ++inner)
			  {
			    GElf_Rel rel_mem;
			    GElf_Rel *rel = gelf_getrel (reldata, inner,
							 &rel_mem);
			    if (rel == NULL)
			      /* The problem will be reported elsewhere.  */
			      break;

			    if (ebl_relative_reloc_p (ebl,
						      GELF_R_TYPE (rel->r_info)))
			      {
				if (inner >= dyn->d_un.d_val)
				  ERROR (gettext ("\
section [%2d] '%s': relative relocations after index %d as specified by DT_RELCOUNT\n"),
					 idx, section_name (ebl, idx),
					 (int) dyn->d_un.d_val);
			      }
			    else if (inner < dyn->d_un.d_val)
			      ERROR (gettext ("\
section [%2d] '%s': non-relative relocation at index %zu; DT_RELCOUNT specified %d relative relocations\n"),
				     idx, section_name (ebl, idx),
				     inner, (int) dyn->d_un.d_val);
			  }
		    }
		}

	      if (dyn->d_tag == DT_RELACOUNT)
		{
		  /* Found it.  Does the type match.  */
		  if (!is_rela)
		    ERROR (gettext ("\
section [%2d] '%s': DT_RELACOUNT used for this REL section\n"),
			   idx, section_name (ebl, idx));
		  else
		    {
		      /* Does the number specified number of relative
			 relocations exceed the total number of
			 relocations?  */
		      if (dyn->d_un.d_val > shdr->sh_size / shdr->sh_entsize)
			ERROR (gettext ("\
section [%2d] '%s': DT_RELCOUNT value %d too high for this section\n"),
			       idx, section_name (ebl, idx),
			       (int) dyn->d_un.d_val);

		      /* Make sure the specified number of relocations are
			 relative.  */
		      Elf_Data *reldata = elf_getdata (elf_getscn (ebl->elf,
								   idx), NULL);
		      if (reldata != NULL)
			for (size_t inner = 0;
			     inner < shdr->sh_size / shdr->sh_entsize;
			     ++inner)
			  {
			    GElf_Rela rela_mem;
			    GElf_Rela *rela = gelf_getrela (reldata, inner,
							    &rela_mem);
			    if (rela == NULL)
			      /* The problem will be reported elsewhere.  */
			      break;

			    if (ebl_relative_reloc_p (ebl,
						      GELF_R_TYPE (rela->r_info)))
			      {
				if (inner >= dyn->d_un.d_val)
				  ERROR (gettext ("\
section [%2d] '%s': relative relocations after index %d as specified by DT_RELCOUNT\n"),
					 idx, section_name (ebl, idx),
					 (int) dyn->d_un.d_val);
			      }
			    else if (inner < dyn->d_un.d_val)
			      ERROR (gettext ("\
section [%2d] '%s': non-relative relocation at index %zu; DT_RELCOUNT specified %d relative relocations\n"),
				     idx, section_name (ebl, idx),
				     inner, (int) dyn->d_un.d_val);
			  }
		    }
		}
	    }

	  break;
	}
    }

  return true;
}


struct loaded_segment
{
  GElf_Addr from;
  GElf_Addr to;
  bool read_only;
  struct loaded_segment *next;
};


/* Check whether binary has text relocation flag set.  */
static bool textrel;

/* Keep track of whether text relocation flag is needed.  */
static bool needed_textrel;


static bool
check_reloc_shdr (Ebl *ebl, const GElf_Ehdr *ehdr, const GElf_Shdr *shdr,
		  int idx, int reltype, GElf_Shdr **destshdrp,
		  GElf_Shdr *destshdr_memp, struct loaded_segment **loadedp)
{
  bool reldyn = false;

  /* Check whether the link to the section we relocate is reasonable.  */
  if (shdr->sh_info >= shnum)
    ERROR (gettext ("section [%2d] '%s': invalid destination section index\n"),
	   idx, section_name (ebl, idx));
  else if (shdr->sh_info != 0)
    {
      *destshdrp = gelf_getshdr (elf_getscn (ebl->elf, shdr->sh_info),
				 destshdr_memp);
      if (*destshdrp != NULL)
	{
	  if(! ebl_check_reloc_target_type (ebl, (*destshdrp)->sh_type))
	    {
	      reldyn = is_rel_dyn (ebl, ehdr, idx, shdr, true);
	      if (!reldyn)
		ERROR (gettext ("\
section [%2d] '%s': invalid destination section type\n"),
		       idx, section_name (ebl, idx));
	      else
		{
		  /* There is no standard, but we require that .rel{,a}.dyn
		     sections have a sh_info value of zero.  */
		  if (shdr->sh_info != 0)
		    ERROR (gettext ("\
section [%2d] '%s': sh_info should be zero\n"),
			   idx, section_name (ebl, idx));
		}
	    }

	  if (((*destshdrp)->sh_flags & (SHF_MERGE | SHF_STRINGS)) != 0)
	    ERROR (gettext ("\
section [%2d] '%s': no relocations for merge-able sections possible\n"),
		   idx, section_name (ebl, idx));
	}
    }

  size_t sh_entsize = gelf_fsize (ebl->elf, reltype, 1, EV_CURRENT);
  if (shdr->sh_entsize != sh_entsize)
    ERROR (gettext (reltype == ELF_T_RELA ? "\
section [%2d] '%s': section entry size does not match ElfXX_Rela\n" : "\
section [%2d] '%s': section entry size does not match ElfXX_Rel\n"),
	   idx, section_name (ebl, idx));

  /* In preparation of checking whether relocations are text
     relocations or not we need to determine whether the file is
     flagged to have text relocation and we need to determine a) what
     the loaded segments are and b) which are read-only.  This will
     also allow us to determine whether the same reloc section is
     modifying loaded and not loaded segments.  */
  for (unsigned int i = 0; i < phnum; ++i)
    {
      GElf_Phdr phdr_mem;
      GElf_Phdr *phdr = gelf_getphdr (ebl->elf, i, &phdr_mem);
      if (phdr == NULL)
	continue;

      if (phdr->p_type == PT_LOAD)
	{
	  struct loaded_segment *newp = xmalloc (sizeof (*newp));
	  newp->from = phdr->p_vaddr;
	  newp->to = phdr->p_vaddr + phdr->p_memsz;
	  newp->read_only = (phdr->p_flags & PF_W) == 0;
	  newp->next = *loadedp;
	  *loadedp = newp;
	}
      else if (phdr->p_type == PT_DYNAMIC)
	{
	  Elf_Scn *dynscn = gelf_offscn (ebl->elf, phdr->p_offset);
	  GElf_Shdr dynshdr_mem;
	  GElf_Shdr *dynshdr = gelf_getshdr (dynscn, &dynshdr_mem);
	  Elf_Data *dyndata = elf_getdata (dynscn, NULL);
	  if (dynshdr != NULL && dynshdr->sh_type == SHT_DYNAMIC
	      && dyndata != NULL)
	    for (size_t j = 0; j < dynshdr->sh_size / dynshdr->sh_entsize; ++j)
	      {
		GElf_Dyn dyn_mem;
		GElf_Dyn *dyn = gelf_getdyn (dyndata, j, &dyn_mem);
		if (dyn != NULL
		    && (dyn->d_tag == DT_TEXTREL
			|| (dyn->d_tag == DT_FLAGS
			    && (dyn->d_un.d_val & DF_TEXTREL) != 0)))
		  {
		    textrel = true;
		    break;
		  }
	      }
	}
    }

  /* A quick test which can be easily done here (although it is a bit
     out of place): the text relocation flag makes only sense if there
     is a segment which is not writable.  */
  if (textrel)
    {
      struct loaded_segment *seg = *loadedp;
      while (seg != NULL && !seg->read_only)
	seg = seg->next;
      if (seg == NULL)
	ERROR (gettext ("\
text relocation flag set but there is no read-only segment\n"));
    }

  return reldyn;
}


enum load_state
  {
    state_undecided,
    state_loaded,
    state_unloaded,
    state_error
  };


static void
check_one_reloc (Ebl *ebl, GElf_Ehdr *ehdr, GElf_Shdr *relshdr, int idx,
		 size_t cnt, const GElf_Shdr *symshdr, Elf_Data *symdata,
		 GElf_Addr r_offset, GElf_Xword r_info,
		 const GElf_Shdr *destshdr, bool reldyn,
		 struct loaded_segment *loaded, enum load_state *statep)
{
  bool known_broken = gnuld;

  if (!ebl_reloc_type_check (ebl, GELF_R_TYPE (r_info)))
    ERROR (gettext ("section [%2d] '%s': relocation %zu: invalid type\n"),
	   idx, section_name (ebl, idx), cnt);
  else if (((ehdr->e_type != ET_EXEC && ehdr->e_type != ET_DYN)
	    /* The executable/DSO can contain relocation sections with
	       all the relocations the linker has applied.  Those sections
	       are marked non-loaded, though.  */
	    || (relshdr->sh_flags & SHF_ALLOC) != 0)
	   && !ebl_reloc_valid_use (ebl, GELF_R_TYPE (r_info)))
    ERROR (gettext ("\
section [%2d] '%s': relocation %zu: relocation type invalid for the file type\n"),
	   idx, section_name (ebl, idx), cnt);

  if (symshdr != NULL
      && ((GELF_R_SYM (r_info) + 1)
	  * gelf_fsize (ebl->elf, ELF_T_SYM, 1, EV_CURRENT)
	  > symshdr->sh_size))
    ERROR (gettext ("\
section [%2d] '%s': relocation %zu: invalid symbol index\n"),
	   idx, section_name (ebl, idx), cnt);

  /* No more tests if this is a no-op relocation.  */
  if (ebl_none_reloc_p (ebl, GELF_R_TYPE (r_info)))
    return;

  if (ebl_gotpc_reloc_check (ebl, GELF_R_TYPE (r_info)))
    {
      const char *name;
      char buf[64];
      GElf_Sym sym_mem;
      GElf_Sym *sym = gelf_getsym (symdata, GELF_R_SYM (r_info), &sym_mem);
      if (sym != NULL
	  /* Get the name for the symbol.  */
	  && (name = elf_strptr (ebl->elf, symshdr->sh_link, sym->st_name))
	  && strcmp (name, "_GLOBAL_OFFSET_TABLE_") !=0 )
	ERROR (gettext ("\
section [%2d] '%s': relocation %zu: only symbol '_GLOBAL_OFFSET_TABLE_' can be used with %s\n"),
	       idx, section_name (ebl, idx), cnt,
	       ebl_reloc_type_name (ebl, GELF_R_SYM (r_info),
				    buf, sizeof (buf)));
    }

  if (reldyn)
    {
      // XXX TODO Check .rel.dyn section addresses.
    }
  else if (!known_broken)
    {
      if (destshdr != NULL
	  && GELF_R_TYPE (r_info) != 0
	  && (r_offset - (ehdr->e_type == ET_REL ? 0
			  : destshdr->sh_addr)) >= destshdr->sh_size)
	ERROR (gettext ("\
section [%2d] '%s': relocation %zu: offset out of bounds\n"),
	       idx, section_name (ebl, idx), cnt);
    }

  GElf_Sym sym_mem;
  GElf_Sym *sym = gelf_getsym (symdata, GELF_R_SYM (r_info), &sym_mem);

  if (ebl_copy_reloc_p (ebl, GELF_R_TYPE (r_info))
      /* Make sure the referenced symbol is an object or unspecified.  */
      && sym != NULL
      && GELF_ST_TYPE (sym->st_info) != STT_NOTYPE
      && GELF_ST_TYPE (sym->st_info) != STT_OBJECT)
    {
      char buf[64];
      ERROR (gettext ("section [%2d] '%s': relocation %zu: copy relocation against symbol of type %s\n"),
	     idx, section_name (ebl, idx), cnt,
	     ebl_symbol_type_name (ebl, GELF_ST_TYPE (sym->st_info),
				   buf, sizeof (buf)));
    }

  if ((ehdr->e_type != ET_EXEC && ehdr->e_type != ET_DYN)
      || (relshdr->sh_flags & SHF_ALLOC) != 0)
    {
      bool in_loaded_seg = false;
      while (loaded != NULL)
	{
	  if (r_offset < loaded->to
	      && r_offset + (sym == NULL ? 0 : sym->st_size) >= loaded->from)
	    {
	      /* The symbol is in this segment.  */
	      if  (loaded->read_only)
		{
		  if (textrel)
		    needed_textrel = true;
		  else
		    ERROR (gettext ("section [%2d] '%s': relocation %zu: read-only section modified but text relocation flag not set\n"),
			   idx, section_name (ebl, idx), cnt);
		}

	      in_loaded_seg = true;
	    }

	  loaded = loaded->next;
	}

      if (*statep == state_undecided)
	*statep = in_loaded_seg ? state_loaded : state_unloaded;
      else if ((*statep == state_unloaded && in_loaded_seg)
	       || (*statep == state_loaded && !in_loaded_seg))
	{
	  ERROR (gettext ("\
section [%2d] '%s': relocations are against loaded and unloaded data\n"),
		 idx, section_name (ebl, idx));
	  *statep = state_error;
	}
    }
}


static void
check_rela (Ebl *ebl, GElf_Ehdr *ehdr, GElf_Shdr *shdr, int idx)
{
  Elf_Data *data = elf_getdata (elf_getscn (ebl->elf, idx), NULL);
  if (data == NULL)
    {
      ERROR (gettext ("section [%2d] '%s': cannot get section data\n"),
	     idx, section_name (ebl, idx));
      return;
    }

  /* Check the fields of the section header.  */
  GElf_Shdr destshdr_mem;
  GElf_Shdr *destshdr = NULL;
  struct loaded_segment *loaded = NULL;
  bool reldyn = check_reloc_shdr (ebl, ehdr, shdr, idx, ELF_T_RELA, &destshdr,
				  &destshdr_mem, &loaded);

  Elf_Scn *symscn = elf_getscn (ebl->elf, shdr->sh_link);
  GElf_Shdr symshdr_mem;
  GElf_Shdr *symshdr = gelf_getshdr (symscn, &symshdr_mem);
  Elf_Data *symdata = elf_getdata (symscn, NULL);
  enum load_state state = state_undecided;

  size_t sh_entsize = gelf_fsize (ebl->elf, ELF_T_RELA, 1, EV_CURRENT);
  for (size_t cnt = 0; cnt < shdr->sh_size / sh_entsize; ++cnt)
    {
      GElf_Rela rela_mem;
      GElf_Rela *rela = gelf_getrela (data, cnt, &rela_mem);
      if (rela == NULL)
	{
	  ERROR (gettext ("\
section [%2d] '%s': cannot get relocation %zu: %s\n"),
		 idx, section_name (ebl, idx), cnt, elf_errmsg (-1));
	  continue;
	}

      check_one_reloc (ebl, ehdr, shdr, idx, cnt, symshdr, symdata,
		       rela->r_offset, rela->r_info, destshdr, reldyn, loaded,
		       &state);
    }

  while (loaded != NULL)
    {
      struct loaded_segment *old = loaded;
      loaded = loaded->next;
      free (old);
    }
}


static void
check_rel (Ebl *ebl, GElf_Ehdr *ehdr, GElf_Shdr *shdr, int idx)
{
  Elf_Data *data = elf_getdata (elf_getscn (ebl->elf, idx), NULL);
  if (data == NULL)
    {
      ERROR (gettext ("section [%2d] '%s': cannot get section data\n"),
	     idx, section_name (ebl, idx));
      return;
    }

  /* Check the fields of the section header.  */
  GElf_Shdr destshdr_mem;
  GElf_Shdr *destshdr = NULL;
  struct loaded_segment *loaded = NULL;
  bool reldyn = check_reloc_shdr (ebl, ehdr, shdr, idx, ELF_T_REL, &destshdr,
				  &destshdr_mem, &loaded);

  Elf_Scn *symscn = elf_getscn (ebl->elf, shdr->sh_link);
  GElf_Shdr symshdr_mem;
  GElf_Shdr *symshdr = gelf_getshdr (symscn, &symshdr_mem);
  Elf_Data *symdata = elf_getdata (symscn, NULL);
  enum load_state state = state_undecided;

  size_t sh_entsize = gelf_fsize (ebl->elf, ELF_T_REL, 1, EV_CURRENT);
  for (size_t cnt = 0; cnt < shdr->sh_size / sh_entsize; ++cnt)
    {
      GElf_Rel rel_mem;
      GElf_Rel *rel = gelf_getrel (data, cnt, &rel_mem);
      if (rel == NULL)
	{
	  ERROR (gettext ("\
section [%2d] '%s': cannot get relocation %zu: %s\n"),
		 idx, section_name (ebl, idx), cnt, elf_errmsg (-1));
	  continue;
	}

      check_one_reloc (ebl, ehdr, shdr, idx, cnt, symshdr, symdata,
		       rel->r_offset, rel->r_info, destshdr, reldyn, loaded,
		       &state);
    }

  while (loaded != NULL)
    {
      struct loaded_segment *old = loaded;
      loaded = loaded->next;
      free (old);
    }
}


/* Number of dynamic sections.  */
static int ndynamic;


static void
check_dynamic (Ebl *ebl, GElf_Ehdr *ehdr, GElf_Shdr *shdr, int idx)
{
  Elf_Data *data;
  GElf_Shdr strshdr_mem;
  GElf_Shdr *strshdr;
  size_t cnt;
  static const bool dependencies[DT_NUM][DT_NUM] =
    {
      [DT_NEEDED] = { [DT_STRTAB] = true },
      [DT_PLTRELSZ] = { [DT_JMPREL] = true },
      [DT_HASH] = { [DT_SYMTAB] = true },
      [DT_STRTAB] = { [DT_STRSZ] = true },
      [DT_SYMTAB] = { [DT_STRTAB] = true, [DT_SYMENT] = true },
      [DT_RELA] = { [DT_RELASZ] = true, [DT_RELAENT] = true },
      [DT_RELASZ] = { [DT_RELA] = true },
      [DT_RELAENT] = { [DT_RELA] = true },
      [DT_STRSZ] = { [DT_STRTAB] = true },
      [DT_SYMENT] = { [DT_SYMTAB] = true },
      [DT_SONAME] = { [DT_STRTAB] = true },
      [DT_RPATH] = { [DT_STRTAB] = true },
      [DT_REL] = { [DT_RELSZ] = true, [DT_RELENT] = true },
      [DT_RELSZ] = { [DT_REL] = true },
      [DT_RELENT] = { [DT_REL] = true },
      [DT_JMPREL] = { [DT_PLTRELSZ] = true, [DT_PLTREL] = true },
      [DT_RUNPATH] = { [DT_STRTAB] = true },
      [DT_PLTREL] = { [DT_JMPREL] = true },
    };
  bool has_dt[DT_NUM];
  bool has_val_dt[DT_VALNUM];
  bool has_addr_dt[DT_ADDRNUM];
  static const bool level2[DT_NUM] =
    {
      [DT_RPATH] = true,
      [DT_SYMBOLIC] = true,
      [DT_TEXTREL] = true,
      [DT_BIND_NOW] = true
    };
  static const bool mandatory[DT_NUM] =
    {
      [DT_NULL] = true,
      [DT_STRTAB] = true,
      [DT_SYMTAB] = true,
      [DT_STRSZ] = true,
      [DT_SYMENT] = true
    };

  memset (has_dt, '\0', sizeof (has_dt));
  memset (has_val_dt, '\0', sizeof (has_val_dt));
  memset (has_addr_dt, '\0', sizeof (has_addr_dt));

  if (++ndynamic == 2)
    ERROR (gettext ("more than one dynamic section present\n"));

  data = elf_getdata (elf_getscn (ebl->elf, idx), NULL);
  if (data == NULL)
    {
      ERROR (gettext ("section [%2d] '%s': cannot get section data\n"),
	     idx, section_name (ebl, idx));
      return;
    }

  strshdr = gelf_getshdr (elf_getscn (ebl->elf, shdr->sh_link), &strshdr_mem);
  if (strshdr != NULL && strshdr->sh_type != SHT_STRTAB)
    ERROR (gettext ("\
section [%2d] '%s': referenced as string table for section [%2d] '%s' but type is not SHT_STRTAB\n"),
	   shdr->sh_link, section_name (ebl, shdr->sh_link),
	   idx, section_name (ebl, idx));

  size_t sh_entsize = gelf_fsize (ebl->elf, ELF_T_DYN, 1, EV_CURRENT);
  if (shdr->sh_entsize != sh_entsize)
    ERROR (gettext ("\
section [%2d] '%s': section entry size does not match ElfXX_Dyn\n"),
	   idx, section_name (ebl, idx));

  if (shdr->sh_info != 0)
    ERROR (gettext ("section [%2d] '%s': sh_info not zero\n"),
	   idx, section_name (ebl, idx));

  bool non_null_warned = false;
  for (cnt = 0; cnt < shdr->sh_size / sh_entsize; ++cnt)
    {
      GElf_Dyn dyn_mem;
      GElf_Dyn *dyn = gelf_getdyn (data, cnt, &dyn_mem);
      if (dyn == NULL)
	{
	  ERROR (gettext ("\
section [%2d] '%s': cannot get dynamic section entry %zu: %s\n"),
		 idx, section_name (ebl, idx), cnt, elf_errmsg (-1));
	  continue;
	}

      if (has_dt[DT_NULL] && dyn->d_tag != DT_NULL && ! non_null_warned)
	{
	  ERROR (gettext ("\
section [%2d] '%s': non-DT_NULL entries follow DT_NULL entry\n"),
		 idx, section_name (ebl, idx));
	  non_null_warned = true;
	}

      if (!ebl_dynamic_tag_check (ebl, dyn->d_tag))
	ERROR (gettext ("section [%2d] '%s': entry %zu: unknown tag\n"),
	       idx, section_name (ebl, idx), cnt);

      if (dyn->d_tag >= 0 && dyn->d_tag < DT_NUM)
	{
	  if (has_dt[dyn->d_tag]
	      && dyn->d_tag != DT_NEEDED
	      && dyn->d_tag != DT_NULL
	      && dyn->d_tag != DT_POSFLAG_1)
	    {
	      char buf[50];
	      ERROR (gettext ("\
section [%2d] '%s': entry %zu: more than one entry with tag %s\n"),
		     idx, section_name (ebl, idx), cnt,
		     ebl_dynamic_tag_name (ebl, dyn->d_tag,
					   buf, sizeof (buf)));
	    }

	  if (be_strict && level2[dyn->d_tag])
	    {
	      char buf[50];
	      ERROR (gettext ("\
section [%2d] '%s': entry %zu: level 2 tag %s used\n"),
		     idx, section_name (ebl, idx), cnt,
		     ebl_dynamic_tag_name (ebl, dyn->d_tag,
					   buf, sizeof (buf)));
	    }

	  has_dt[dyn->d_tag] = true;
	}
      else if (dyn->d_tag <= DT_VALRNGHI
	       && DT_VALTAGIDX (dyn->d_tag) < DT_VALNUM)
	has_val_dt[DT_VALTAGIDX (dyn->d_tag)] = true;
      else if (dyn->d_tag <= DT_ADDRRNGHI
	       && DT_ADDRTAGIDX (dyn->d_tag) < DT_ADDRNUM)
	has_addr_dt[DT_ADDRTAGIDX (dyn->d_tag)] = true;

      if (dyn->d_tag == DT_PLTREL && dyn->d_un.d_val != DT_REL
	  && dyn->d_un.d_val != DT_RELA)
	ERROR (gettext ("\
section [%2d] '%s': entry %zu: DT_PLTREL value must be DT_REL or DT_RELA\n"),
	       idx, section_name (ebl, idx), cnt);

      /* Check that addresses for entries are in loaded segments.  */
      switch (dyn->d_tag)
	{
	  size_t n;
	case DT_STRTAB:
	  /* We require the referenced section is the same as the one
	     specified in sh_link.  */
	  if (strshdr->sh_addr != dyn->d_un.d_val)
	    {
	      ERROR (gettext ("\
section [%2d] '%s': entry %zu: pointer does not match address of section [%2d] '%s' referenced by sh_link\n"),
		     idx, section_name (ebl, idx), cnt,
		     shdr->sh_link, section_name (ebl, shdr->sh_link));
	      break;
	    }
	  goto check_addr;

	default:
	  if (dyn->d_tag < DT_ADDRRNGLO || dyn->d_tag > DT_ADDRRNGHI)
	    /* Value is no pointer.  */
	    break;
	  /* FALLTHROUGH */

	case DT_AUXILIARY:
	case DT_FILTER:
	case DT_FINI:
	case DT_FINI_ARRAY:
	case DT_HASH:
	case DT_INIT:
	case DT_INIT_ARRAY:
	case DT_JMPREL:
	case DT_PLTGOT:
	case DT_REL:
	case DT_RELA:
	case DT_SYMBOLIC:
	case DT_SYMTAB:
	case DT_VERDEF:
	case DT_VERNEED:
	case DT_VERSYM:
	check_addr:
	  for (n = 0; n < phnum; ++n)
	    {
	      GElf_Phdr phdr_mem;
	      GElf_Phdr *phdr = gelf_getphdr (ebl->elf, n, &phdr_mem);
	      if (phdr != NULL && phdr->p_type == PT_LOAD
		  && phdr->p_vaddr <= dyn->d_un.d_ptr
		  && phdr->p_vaddr + phdr->p_memsz > dyn->d_un.d_ptr)
		break;
	    }
	  if (unlikely (n >= phnum))
	    {
	      char buf[50];
	      ERROR (gettext ("\
section [%2d] '%s': entry %zu: %s value must point into loaded segment\n"),
		     idx, section_name (ebl, idx), cnt,
		     ebl_dynamic_tag_name (ebl, dyn->d_tag, buf,
					   sizeof (buf)));
	    }
	  break;

	case DT_NEEDED:
	case DT_RPATH:
	case DT_RUNPATH:
	case DT_SONAME:
	  if (dyn->d_un.d_ptr >= strshdr->sh_size)
	    {
	      char buf[50];
	      ERROR (gettext ("\
section [%2d] '%s': entry %zu: %s value must be valid offset in section [%2d] '%s'\n"),
		     idx, section_name (ebl, idx), cnt,
		     ebl_dynamic_tag_name (ebl, dyn->d_tag, buf,
					   sizeof (buf)),
		     shdr->sh_link, section_name (ebl, shdr->sh_link));
	    }
	  break;
	}
    }

  for (cnt = 1; cnt < DT_NUM; ++cnt)
    if (has_dt[cnt])
      {
	for (int inner = 0; inner < DT_NUM; ++inner)
	  if (dependencies[cnt][inner] && ! has_dt[inner])
	    {
	      char buf1[50];
	      char buf2[50];

	      ERROR (gettext ("\
section [%2d] '%s': contains %s entry but not %s\n"),
		     idx, section_name (ebl, idx),
		     ebl_dynamic_tag_name (ebl, cnt, buf1, sizeof (buf1)),
		     ebl_dynamic_tag_name (ebl, inner, buf2, sizeof (buf2)));
	    }
      }
    else
      {
	if (mandatory[cnt])
	  {
	    char buf[50];
	    ERROR (gettext ("\
section [%2d] '%s': mandatory tag %s not present\n"),
		   idx, section_name (ebl, idx),
		   ebl_dynamic_tag_name (ebl, cnt, buf, sizeof (buf)));
	  }
      }

  /* Make sure we have an hash table.  */
  if (!has_dt[DT_HASH] && !has_addr_dt[DT_ADDRTAGIDX (DT_GNU_HASH)])
    ERROR (gettext ("\
section [%2d] '%s': no hash section present\n"),
	   idx, section_name (ebl, idx));

  /* The GNU-style hash table also needs a symbol table.  */
  if (!has_dt[DT_HASH] && has_addr_dt[DT_ADDRTAGIDX (DT_GNU_HASH)]
      && !has_dt[DT_SYMTAB])
    ERROR (gettext ("\
section [%2d] '%s': contains %s entry but not %s\n"),
	   idx, section_name (ebl, idx),
	   "DT_GNU_HASH", "DT_SYMTAB");

  /* Check the rel/rela tags.  At least one group must be available.  */
  if ((has_dt[DT_RELA] || has_dt[DT_RELASZ] || has_dt[DT_RELAENT])
      && (!has_dt[DT_RELA] || !has_dt[DT_RELASZ] || !has_dt[DT_RELAENT]))
    ERROR (gettext ("\
section [%2d] '%s': not all of %s, %s, and %s are present\n"),
	   idx, section_name (ebl, idx),
	   "DT_RELA", "DT_RELASZ", "DT_RELAENT");

  if ((has_dt[DT_REL] || has_dt[DT_RELSZ] || has_dt[DT_RELENT])
      && (!has_dt[DT_REL] || !has_dt[DT_RELSZ] || !has_dt[DT_RELENT]))
    ERROR (gettext ("\
section [%2d] '%s': not all of %s, %s, and %s are present\n"),
	   idx, section_name (ebl, idx),
	   "DT_REL", "DT_RELSZ", "DT_RELENT");

  /* Check that all prelink sections are present if any of them is.  */
  if (has_val_dt[DT_VALTAGIDX (DT_GNU_PRELINKED)]
      || has_val_dt[DT_VALTAGIDX (DT_CHECKSUM)])
    {
      if (!has_val_dt[DT_VALTAGIDX (DT_GNU_PRELINKED)])
	ERROR (gettext ("\
section [%2d] '%s': %s tag missing in DSO marked during prelinking\n"),
	       idx, section_name (ebl, idx), "DT_GNU_PRELINKED");
      if (!has_val_dt[DT_VALTAGIDX (DT_CHECKSUM)])
	ERROR (gettext ("\
section [%2d] '%s': %s tag missing in DSO marked during prelinking\n"),
	       idx, section_name (ebl, idx), "DT_CHECKSUM");

      /* Only DSOs can be marked like this.  */
      if (ehdr->e_type != ET_DYN)
	ERROR (gettext ("\
section [%2d] '%s': non-DSO file marked as dependency during prelink\n"),
	       idx, section_name (ebl, idx));
    }

  if (has_val_dt[DT_VALTAGIDX (DT_GNU_CONFLICTSZ)]
      || has_val_dt[DT_VALTAGIDX (DT_GNU_LIBLISTSZ)]
      || has_addr_dt[DT_ADDRTAGIDX (DT_GNU_CONFLICT)]
      || has_addr_dt[DT_ADDRTAGIDX (DT_GNU_LIBLIST)])
    {
      if (!has_val_dt[DT_VALTAGIDX (DT_GNU_CONFLICTSZ)])
	ERROR (gettext ("\
section [%2d] '%s': %s tag missing in prelinked executable\n"),
	       idx, section_name (ebl, idx), "DT_GNU_CONFLICTSZ");
      if (!has_val_dt[DT_VALTAGIDX (DT_GNU_LIBLISTSZ)])
	ERROR (gettext ("\
section [%2d] '%s': %s tag missing in prelinked executable\n"),
	       idx, section_name (ebl, idx), "DT_GNU_LIBLISTSZ");
      if (!has_addr_dt[DT_ADDRTAGIDX (DT_GNU_CONFLICT)])
	ERROR (gettext ("\
section [%2d] '%s': %s tag missing in prelinked executable\n"),
	       idx, section_name (ebl, idx), "DT_GNU_CONFLICT");
      if (!has_addr_dt[DT_ADDRTAGIDX (DT_GNU_LIBLIST)])
	ERROR (gettext ("\
section [%2d] '%s': %s tag missing in prelinked executable\n"),
	       idx, section_name (ebl, idx), "DT_GNU_LIBLIST");
    }
}


static void
check_symtab_shndx (Ebl *ebl, GElf_Ehdr *ehdr, GElf_Shdr *shdr, int idx)
{
  if (ehdr->e_type != ET_REL)
    {
      ERROR (gettext ("\
section [%2d] '%s': only relocatable files can have extended section index\n"),
	     idx, section_name (ebl, idx));
      return;
    }

  Elf_Scn *symscn = elf_getscn (ebl->elf, shdr->sh_link);
  GElf_Shdr symshdr_mem;
  GElf_Shdr *symshdr = gelf_getshdr (symscn, &symshdr_mem);
  if (symshdr != NULL && symshdr->sh_type != SHT_SYMTAB)
    ERROR (gettext ("\
section [%2d] '%s': extended section index section not for symbol table\n"),
	   idx, section_name (ebl, idx));
  Elf_Data *symdata = elf_getdata (symscn, NULL);
  if (symdata == NULL)
    ERROR (gettext ("cannot get data for symbol section\n"));

  if (shdr->sh_entsize != sizeof (Elf32_Word))
    ERROR (gettext ("\
section [%2d] '%s': entry size does not match Elf32_Word\n"),
	   idx, section_name (ebl, idx));

  if (symshdr != NULL
      && shdr->sh_entsize
      && symshdr->sh_entsize
      && (shdr->sh_size / shdr->sh_entsize
	  < symshdr->sh_size / symshdr->sh_entsize))
    ERROR (gettext ("\
section [%2d] '%s': extended index table too small for symbol table\n"),
	   idx, section_name (ebl, idx));

  if (shdr->sh_info != 0)
    ERROR (gettext ("section [%2d] '%s': sh_info not zero\n"),
	   idx, section_name (ebl, idx));

  for (size_t cnt = idx + 1; cnt < shnum; ++cnt)
    {
      GElf_Shdr rshdr_mem;
      GElf_Shdr *rshdr = gelf_getshdr (elf_getscn (ebl->elf, cnt), &rshdr_mem);
      if (rshdr != NULL && rshdr->sh_type == SHT_SYMTAB_SHNDX
	  && rshdr->sh_link == shdr->sh_link)
	{
	  ERROR (gettext ("\
section [%2d] '%s': extended section index in section [%2zu] '%s' refers to same symbol table\n"),
		 idx, section_name (ebl, idx),
		 cnt, section_name (ebl, cnt));
	  break;
	}
    }

  Elf_Data *data = elf_getdata (elf_getscn (ebl->elf, idx), NULL);
  if (data == NULL)
    {
      ERROR (gettext ("section [%2d] '%s': cannot get section data\n"),
	     idx, section_name (ebl, idx));
      return;
    }

  if (*((Elf32_Word *) data->d_buf) != 0)
    ERROR (gettext ("symbol 0 should have zero extended section index\n"));

  for (size_t cnt = 1; cnt < data->d_size / sizeof (Elf32_Word); ++cnt)
    {
      Elf32_Word xndx = ((Elf32_Word *) data->d_buf)[cnt];

      if (xndx != 0)
	{
	  GElf_Sym sym_data;
	  GElf_Sym *sym = gelf_getsym (symdata, cnt, &sym_data);
	  if (sym == NULL)
	    {
	      ERROR (gettext ("cannot get data for symbol %zu\n"), cnt);
	      continue;
	    }

	  if (sym->st_shndx != SHN_XINDEX)
	    ERROR (gettext ("\
extended section index is %" PRIu32 " but symbol index is not XINDEX\n"),
		   (uint32_t) xndx);
	}
    }
}


static void
check_sysv_hash (Ebl *ebl, GElf_Shdr *shdr, Elf_Data *data, int idx,
		 GElf_Shdr *symshdr)
{
  Elf32_Word nbucket = ((Elf32_Word *) data->d_buf)[0];
  Elf32_Word nchain = ((Elf32_Word *) data->d_buf)[1];

  if (shdr->sh_size < (2 + nbucket + nchain) * shdr->sh_entsize)
    ERROR (gettext ("\
section [%2d] '%s': hash table section is too small (is %ld, expected %ld)\n"),
	   idx, section_name (ebl, idx), (long int) shdr->sh_size,
	   (long int) ((2 + nbucket + nchain) * shdr->sh_entsize));

  size_t maxidx = nchain;

  if (symshdr != NULL && symshdr->sh_entsize != 0)
    {
      size_t symsize = symshdr->sh_size / symshdr->sh_entsize;

      if (nchain > symshdr->sh_size / symshdr->sh_entsize)
	ERROR (gettext ("section [%2d] '%s': chain array too large\n"),
	       idx, section_name (ebl, idx));

      maxidx = symsize;
    }

  Elf32_Word *buf = (Elf32_Word *) data->d_buf;
  Elf32_Word *end = (Elf32_Word *) ((char *) data->d_buf + shdr->sh_size);
  size_t cnt;
  for (cnt = 2; cnt < 2 + nbucket; ++cnt)
    {
      if (buf + cnt >= end)
	break;
      else if (buf[cnt] >= maxidx)
      ERROR (gettext ("\
section [%2d] '%s': hash bucket reference %zu out of bounds\n"),
	     idx, section_name (ebl, idx), cnt - 2);
    }

  for (; cnt < 2 + nbucket + nchain; ++cnt)
    {
      if (buf + cnt >= end)
	break;
      else if (buf[cnt] >= maxidx)
      ERROR (gettext ("\
section [%2d] '%s': hash chain reference %zu out of bounds\n"),
	     idx, section_name (ebl, idx), cnt - 2 - nbucket);
    }
}


static void
check_sysv_hash64 (Ebl *ebl, GElf_Shdr *shdr, Elf_Data *data, int idx,
		 GElf_Shdr *symshdr)
{
  Elf64_Xword nbucket = ((Elf64_Xword *) data->d_buf)[0];
  Elf64_Xword nchain = ((Elf64_Xword *) data->d_buf)[1];

  if (shdr->sh_size < (2 + nbucket + nchain) * shdr->sh_entsize)
    ERROR (gettext ("\
section [%2d] '%s': hash table section is too small (is %ld, expected %ld)\n"),
	   idx, section_name (ebl, idx), (long int) shdr->sh_size,
	   (long int) ((2 + nbucket + nchain) * shdr->sh_entsize));

  size_t maxidx = nchain;

  if (symshdr != NULL)
    {
      size_t symsize = symshdr->sh_size / symshdr->sh_entsize;

      if (nchain > symshdr->sh_size / symshdr->sh_entsize)
	ERROR (gettext ("section [%2d] '%s': chain array too large\n"),
	       idx, section_name (ebl, idx));

      maxidx = symsize;
    }

  Elf64_Xword *buf = (Elf64_Xword *) data->d_buf;
  Elf64_Xword *end = (Elf64_Xword *) ((char *) data->d_buf + shdr->sh_size);
  size_t cnt;
  for (cnt = 2; cnt < 2 + nbucket; ++cnt)
    {
      if (buf + cnt >= end)
	break;
      else if (buf[cnt] >= maxidx)
      ERROR (gettext ("\
section [%2d] '%s': hash bucket reference %zu out of bounds\n"),
	     idx, section_name (ebl, idx), cnt - 2);
    }

  for (; cnt < 2 + nbucket + nchain; ++cnt)
    {
      if (buf + cnt >= end)
	break;
      else if (buf[cnt] >= maxidx)
      ERROR (gettext ("\
section [%2d] '%s': hash chain reference %" PRIu64 " out of bounds\n"),
	       idx, section_name (ebl, idx), (uint64_t) cnt - 2 - nbucket);
    }
}


static void
check_gnu_hash (Ebl *ebl, GElf_Shdr *shdr, Elf_Data *data, int idx,
		GElf_Shdr *symshdr)
{
  Elf32_Word nbuckets = ((Elf32_Word *) data->d_buf)[0];
  Elf32_Word symbias = ((Elf32_Word *) data->d_buf)[1];
  Elf32_Word bitmask_words = ((Elf32_Word *) data->d_buf)[2];

  if (!powerof2 (bitmask_words))
    ERROR (gettext ("\
section [%2d] '%s': bitmask size not power of 2: %u\n"),
	   idx, section_name (ebl, idx), bitmask_words);

  size_t bitmask_idxmask = bitmask_words - 1;
  if (gelf_getclass (ebl->elf) == ELFCLASS64)
    bitmask_words *= 2;
  Elf32_Word shift = ((Elf32_Word *) data->d_buf)[3];

  if (shdr->sh_size < (4 + bitmask_words + nbuckets) * sizeof (Elf32_Word))
    {
      ERROR (gettext ("\
section [%2d] '%s': hash table section is too small (is %ld, expected at least %ld)\n"),
	     idx, section_name (ebl, idx), (long int) shdr->sh_size,
	     (long int) ((4 + bitmask_words + nbuckets) * sizeof (Elf32_Word)));
      return;
    }

  if (shift > 31)
    ERROR (gettext ("\
section [%2d] '%s': 2nd hash function shift too big: %u\n"),
	   idx, section_name (ebl, idx), shift);

  size_t maxidx = shdr->sh_size / sizeof (Elf32_Word) - (4 + bitmask_words
							 + nbuckets);

  if (symshdr != NULL)
    maxidx = MIN (maxidx, symshdr->sh_size / symshdr->sh_entsize);

  /* We need the symbol section data.  */
  Elf_Data *symdata = elf_getdata (elf_getscn (ebl->elf, shdr->sh_link), NULL);

  union
  {
    Elf32_Word *p32;
    Elf64_Xword *p64;
  } bitmask = { .p32 = &((Elf32_Word *) data->d_buf)[4] },
      collected = { .p32 = xcalloc (bitmask_words, sizeof (Elf32_Word)) };

  size_t classbits = gelf_getclass (ebl->elf) == ELFCLASS32 ? 32 : 64;

  size_t cnt;
  for (cnt = 4 + bitmask_words; cnt < 4 + bitmask_words + nbuckets; ++cnt)
    {
      Elf32_Word symidx = ((Elf32_Word *) data->d_buf)[cnt];

      if (symidx == 0)
	continue;

      if (symidx < symbias)
	{
	  ERROR (gettext ("\
section [%2d] '%s': hash chain for bucket %zu lower than symbol index bias\n"),
		 idx, section_name (ebl, idx), cnt - (4 + bitmask_words));
	  continue;
	}

      while (symidx - symbias < maxidx)
	{
	  Elf32_Word chainhash = ((Elf32_Word *) data->d_buf)[4
							      + bitmask_words
							      + nbuckets
							      + symidx
							      - symbias];

	  if (symdata != NULL)
	    {
	      /* Check that the referenced symbol is not undefined.  */
	      GElf_Sym sym_mem;
	      GElf_Sym *sym = gelf_getsym (symdata, symidx, &sym_mem);
	      if (sym != NULL && sym->st_shndx == SHN_UNDEF
		  && GELF_ST_TYPE (sym->st_info) != STT_FUNC)
		ERROR (gettext ("\
section [%2d] '%s': symbol %u referenced in chain for bucket %zu is undefined\n"),
		       idx, section_name (ebl, idx), symidx,
		       cnt - (4 + bitmask_words));

	      const char *symname = elf_strptr (ebl->elf, symshdr->sh_link,
						sym->st_name);
	      if (symname != NULL)
		{
		  Elf32_Word hval = elf_gnu_hash (symname);
		  if ((hval & ~1u) != (chainhash & ~1u))
		    ERROR (gettext ("\
section [%2d] '%s': hash value for symbol %u in chain for bucket %zu wrong\n"),
			   idx, section_name (ebl, idx), symidx,
			   cnt - (4 + bitmask_words));

		  /* Set the bits in the bitmask.  */
		  size_t maskidx = (hval / classbits) & bitmask_idxmask;
		  if (classbits == 32)
		    {
		      collected.p32[maskidx]
			|= UINT32_C (1) << (hval & (classbits - 1));
		      collected.p32[maskidx]
			|= UINT32_C (1) << ((hval >> shift) & (classbits - 1));
		    }
		  else
		    {
		      collected.p64[maskidx]
			|= UINT64_C (1) << (hval & (classbits - 1));
		      collected.p64[maskidx]
			|= UINT64_C (1) << ((hval >> shift) & (classbits - 1));
		    }
		}
	    }

	  if ((chainhash & 1) != 0)
	    break;

	  ++symidx;
	}

      if (symidx - symbias >= maxidx)
	ERROR (gettext ("\
section [%2d] '%s': hash chain for bucket %zu out of bounds\n"),
	       idx, section_name (ebl, idx), cnt - (4 + bitmask_words));
      else if (symshdr != NULL
	       && symidx > symshdr->sh_size / symshdr->sh_entsize)
	ERROR (gettext ("\
section [%2d] '%s': symbol reference in chain for bucket %zu out of bounds\n"),
	       idx, section_name (ebl, idx), cnt - (4 + bitmask_words));
    }

  if (memcmp (collected.p32, bitmask.p32, bitmask_words * sizeof (Elf32_Word)))
    ERROR (gettext ("\
section [%2d] '%s': bitmask does not match names in the hash table\n"),
	   idx, section_name (ebl, idx));

  free (collected.p32);
}


static void
check_hash (int tag, Ebl *ebl, GElf_Ehdr *ehdr, GElf_Shdr *shdr, int idx)
{
  if (ehdr->e_type == ET_REL)
    {
      ERROR (gettext ("\
section [%2d] '%s': relocatable files cannot have hash tables\n"),
	     idx, section_name (ebl, idx));
      return;
    }

  Elf_Data *data = elf_getdata (elf_getscn (ebl->elf, idx), NULL);
  if (data == NULL)
    {
      ERROR (gettext ("section [%2d] '%s': cannot get section data\n"),
	     idx, section_name (ebl, idx));
      return;
    }

  GElf_Shdr symshdr_mem;
  GElf_Shdr *symshdr = gelf_getshdr (elf_getscn (ebl->elf, shdr->sh_link),
				     &symshdr_mem);
  if (symshdr != NULL && symshdr->sh_type != SHT_DYNSYM)
    ERROR (gettext ("\
section [%2d] '%s': hash table not for dynamic symbol table\n"),
	   idx, section_name (ebl, idx));

  if (shdr->sh_entsize != (tag == SHT_GNU_HASH
			   ? (gelf_getclass (ebl->elf) == ELFCLASS32
			      ? sizeof (Elf32_Word) : 0)
			   : (size_t) ebl_sysvhash_entrysize (ebl)))
    ERROR (gettext ("\
section [%2d] '%s': hash table entry size incorrect\n"),
	   idx, section_name (ebl, idx));

  if ((shdr->sh_flags & SHF_ALLOC) == 0)
    ERROR (gettext ("section [%2d] '%s': not marked to be allocated\n"),
	   idx, section_name (ebl, idx));

  if (shdr->sh_size < (tag == SHT_GNU_HASH ? 4 : 2) * (shdr->sh_entsize ?: 4))
    {
      ERROR (gettext ("\
section [%2d] '%s': hash table has not even room for initial administrative entries\n"),
	     idx, section_name (ebl, idx));
      return;
    }

  switch (tag)
    {
    case SHT_HASH:
      if (ebl_sysvhash_entrysize (ebl) == sizeof (Elf64_Xword))
	check_sysv_hash64 (ebl, shdr, data, idx, symshdr);
      else
	check_sysv_hash (ebl, shdr, data, idx, symshdr);
      break;

    case SHT_GNU_HASH:
      check_gnu_hash (ebl, shdr, data, idx, symshdr);
      break;

    default:
      assert (! "should not happen");
    }
}


/* Compare content of both hash tables, it must be identical.  */
static void
compare_hash_gnu_hash (Ebl *ebl, GElf_Ehdr *ehdr, size_t hash_idx,
		       size_t gnu_hash_idx)
{
  Elf_Scn *hash_scn = elf_getscn (ebl->elf, hash_idx);
  Elf_Data *hash_data = elf_getdata (hash_scn, NULL);
  GElf_Shdr hash_shdr_mem;
  GElf_Shdr *hash_shdr = gelf_getshdr (hash_scn, &hash_shdr_mem);
  Elf_Scn *gnu_hash_scn = elf_getscn (ebl->elf, gnu_hash_idx);
  Elf_Data *gnu_hash_data = elf_getdata (gnu_hash_scn, NULL);
  GElf_Shdr gnu_hash_shdr_mem;
  GElf_Shdr *gnu_hash_shdr = gelf_getshdr (gnu_hash_scn, &gnu_hash_shdr_mem);

  if (hash_shdr == NULL || gnu_hash_shdr == NULL
      || hash_data == NULL || gnu_hash_data == NULL)
    /* None of these pointers should be NULL since we used the
       sections already.  We are careful nonetheless.  */
    return;

  /* The link must point to the same symbol table.  */
  if (hash_shdr->sh_link != gnu_hash_shdr->sh_link)
    {
      ERROR (gettext ("\
sh_link in hash sections [%2zu] '%s' and [%2zu] '%s' not identical\n"),
	     hash_idx, elf_strptr (ebl->elf, shstrndx, hash_shdr->sh_name),
	     gnu_hash_idx,
	     elf_strptr (ebl->elf, shstrndx, gnu_hash_shdr->sh_name));
      return;
    }

  Elf_Scn *sym_scn = elf_getscn (ebl->elf, hash_shdr->sh_link);
  Elf_Data *sym_data = elf_getdata (sym_scn, NULL);
  GElf_Shdr sym_shdr_mem;
  GElf_Shdr *sym_shdr = gelf_getshdr (sym_scn, &sym_shdr_mem);

  if (sym_data == NULL || sym_shdr == NULL)
    return;

  int nentries = sym_shdr->sh_size / sym_shdr->sh_entsize;
  char *used = alloca (nentries);
  memset (used, '\0', nentries);

  /* First go over the GNU_HASH table and mark the entries as used.  */
  const Elf32_Word *gnu_hasharr = (Elf32_Word *) gnu_hash_data->d_buf;
  Elf32_Word gnu_nbucket = gnu_hasharr[0];
  const int bitmap_factor = ehdr->e_ident[EI_CLASS] == ELFCLASS32 ? 1 : 2;
  const Elf32_Word *gnu_bucket = (gnu_hasharr
				  + (4 + gnu_hasharr[2] * bitmap_factor));
  const Elf32_Word *gnu_chain = gnu_bucket + gnu_hasharr[0] - gnu_hasharr[1];

  for (Elf32_Word cnt = 0; cnt < gnu_nbucket; ++cnt)
    {
      Elf32_Word symidx = gnu_bucket[cnt];
      if (symidx != STN_UNDEF)
	do
	  used[symidx] |= 1;
	while ((gnu_chain[symidx++] & 1u) == 0);
    }

  /* Now go over the old hash table and check that we cover the same
     entries.  */
  if (hash_shdr->sh_entsize == sizeof (Elf32_Word))
    {
      const Elf32_Word *hasharr = (Elf32_Word *) hash_data->d_buf;
      Elf32_Word nbucket = hasharr[0];
      const Elf32_Word *bucket = &hasharr[2];
      const Elf32_Word *chain = &hasharr[2 + nbucket];

      for (Elf32_Word cnt = 0; cnt < nbucket; ++cnt)
	{
	  Elf32_Word symidx = bucket[cnt];
	  while (symidx != STN_UNDEF)
	    {
	      used[symidx] |= 2;
	      symidx = chain[symidx];
	    }
	}
    }
  else
    {
      const Elf64_Xword *hasharr = (Elf64_Xword *) hash_data->d_buf;
      Elf64_Xword nbucket = hasharr[0];
      const Elf64_Xword *bucket = &hasharr[2];
      const Elf64_Xword *chain = &hasharr[2 + nbucket];

      for (Elf64_Xword cnt = 0; cnt < nbucket; ++cnt)
	{
	  Elf64_Xword symidx = bucket[cnt];
	  while (symidx != STN_UNDEF)
	    {
	      used[symidx] |= 2;
	      symidx = chain[symidx];
	    }
	}
    }

  /* Now see which entries are not set in one or both hash tables
     (unless the symbol is undefined in which case it can be omitted
     in the new table format).  */
  if ((used[0] & 1) != 0)
    ERROR (gettext ("section [%2zu] '%s': reference to symbol index 0\n"),
	   gnu_hash_idx,
	   elf_strptr (ebl->elf, shstrndx, gnu_hash_shdr->sh_name));
  if ((used[0] & 2) != 0)
    ERROR (gettext ("section [%2zu] '%s': reference to symbol index 0\n"),
	   hash_idx, elf_strptr (ebl->elf, shstrndx, hash_shdr->sh_name));

  for (int cnt = 1; cnt < nentries; ++cnt)
    if (used[cnt] != 0 && used[cnt] != 3)
      {
	if (used[cnt] == 1)
	  ERROR (gettext ("\
symbol %d referenced in new hash table in [%2zu] '%s' but not in old hash table in [%2zu] '%s'\n"),
		 cnt, gnu_hash_idx,
		 elf_strptr (ebl->elf, shstrndx, gnu_hash_shdr->sh_name),
		 hash_idx,
		 elf_strptr (ebl->elf, shstrndx, hash_shdr->sh_name));
	else
	  {
	    GElf_Sym sym_mem;
	    GElf_Sym *sym = gelf_getsym (sym_data, cnt, &sym_mem);

	    if (sym != NULL && sym->st_shndx != STN_UNDEF)
	      ERROR (gettext ("\
symbol %d referenced in old hash table in [%2zu] '%s' but not in new hash table in [%2zu] '%s'\n"),
		     cnt, hash_idx,
		     elf_strptr (ebl->elf, shstrndx, hash_shdr->sh_name),
		     gnu_hash_idx,
		     elf_strptr (ebl->elf, shstrndx, gnu_hash_shdr->sh_name));
	  }
      }
}


static void
check_null (Ebl *ebl, GElf_Shdr *shdr, int idx)
{
#define TEST(name, extra) \
  if (extra && shdr->sh_##name != 0)					      \
    ERROR (gettext ("section [%2d] '%s': nonzero sh_%s for NULL section\n"),  \
	   idx, section_name (ebl, idx), #name)

  TEST (name, 1);
  TEST (flags, 1);
  TEST (addr, 1);
  TEST (offset, 1);
  TEST (size, idx != 0);
  TEST (link, idx != 0);
  TEST (info, 1);
  TEST (addralign, 1);
  TEST (entsize, 1);
}


static void
check_group (Ebl *ebl, GElf_Ehdr *ehdr, GElf_Shdr *shdr, int idx)
{
  if (ehdr->e_type != ET_REL)
    {
      ERROR (gettext ("\
section [%2d] '%s': section groups only allowed in relocatable object files\n"),
	     idx, section_name (ebl, idx));
      return;
    }

  /* Check that sh_link is an index of a symbol table.  */
  Elf_Scn *symscn = elf_getscn (ebl->elf, shdr->sh_link);
  GElf_Shdr symshdr_mem;
  GElf_Shdr *symshdr = gelf_getshdr (symscn, &symshdr_mem);
  if (symshdr == NULL)
    ERROR (gettext ("section [%2d] '%s': cannot get symbol table: %s\n"),
	   idx, section_name (ebl, idx), elf_errmsg (-1));
  else
    {
      if (symshdr->sh_type != SHT_SYMTAB)
	ERROR (gettext ("\
section [%2d] '%s': section reference in sh_link is no symbol table\n"),
	       idx, section_name (ebl, idx));

      if (shdr->sh_info >= symshdr->sh_size / gelf_fsize (ebl->elf, ELF_T_SYM,
							  1, EV_CURRENT))
	ERROR (gettext ("\
section [%2d] '%s': invalid symbol index in sh_info\n"),
	       idx, section_name (ebl, idx));

      if (shdr->sh_flags != 0)
	ERROR (gettext ("section [%2d] '%s': sh_flags not zero\n"),
	       idx, section_name (ebl, idx));

      GElf_Sym sym_data;
      GElf_Sym *sym = gelf_getsym (elf_getdata (symscn, NULL), shdr->sh_info,
				   &sym_data);
      if (sym == NULL)
	ERROR (gettext ("\
section [%2d] '%s': cannot get symbol for signature\n"),
	       idx, section_name (ebl, idx));
      else if (strcmp (elf_strptr (ebl->elf, symshdr->sh_link, sym->st_name),
		       "") == 0)
	ERROR (gettext ("\
section [%2d] '%s': signature symbol cannot be empty string\n"),
	       idx, section_name (ebl, idx));

      if (be_strict
	  && shdr->sh_entsize != elf32_fsize (ELF_T_WORD, 1, EV_CURRENT))
	ERROR (gettext ("section [%2d] '%s': sh_flags not set correctly\n"),
	       idx, section_name (ebl, idx));
    }

  Elf_Data *data = elf_getdata (elf_getscn (ebl->elf, idx), NULL);
  if (data == NULL)
    ERROR (gettext ("section [%2d] '%s': cannot get data: %s\n"),
	   idx, section_name (ebl, idx), elf_errmsg (-1));
  else
    {
      size_t elsize = elf32_fsize (ELF_T_WORD, 1, EV_CURRENT);
      size_t cnt;
      Elf32_Word val;

      if (data->d_size % elsize != 0)
	ERROR (gettext ("\
section [%2d] '%s': section size not multiple of sizeof(Elf32_Word)\n"),
	       idx, section_name (ebl, idx));

      if (data->d_size < elsize)
	ERROR (gettext ("\
section [%2d] '%s': section group without flags word\n"),
	       idx, section_name (ebl, idx));
      else if (be_strict)
	{
	  if (data->d_size < 2 * elsize)
	    ERROR (gettext ("\
section [%2d] '%s': section group without member\n"),
		   idx, section_name (ebl, idx));
	  else if (data->d_size < 3 * elsize)
	    ERROR (gettext ("\
section [%2d] '%s': section group with only one member\n"),
		   idx, section_name (ebl, idx));
	}

#if ALLOW_UNALIGNED
      val = *((Elf32_Word *) data->d_buf);
#else
      memcpy (&val, data->d_buf, elsize);
#endif
      if ((val & ~GRP_COMDAT) != 0)
	ERROR (gettext ("section [%2d] '%s': unknown section group flags\n"),
	       idx, section_name (ebl, idx));

      for (cnt = elsize; cnt < data->d_size; cnt += elsize)
	{
#if ALLOW_UNALIGNED
	  val = *((Elf32_Word *) ((char *) data->d_buf + cnt));
#else
	  memcpy (&val, (char *) data->d_buf + cnt, elsize);
#endif

	  if (val > shnum)
	    ERROR (gettext ("\
section [%2d] '%s': section index %Zu out of range\n"),
		   idx, section_name (ebl, idx), cnt / elsize);
	  else
	    {
	      GElf_Shdr refshdr_mem;
	      GElf_Shdr *refshdr = gelf_getshdr (elf_getscn (ebl->elf, val),
						 &refshdr_mem);
	      if (refshdr == NULL)
		ERROR (gettext ("\
section [%2d] '%s': cannot get section header for element %zu: %s\n"),
		       idx, section_name (ebl, idx), cnt / elsize,
		       elf_errmsg (-1));
	      else
		{
		  if (refshdr->sh_type == SHT_GROUP)
		    ERROR (gettext ("\
section [%2d] '%s': section group contains another group [%2d] '%s'\n"),
			   idx, section_name (ebl, idx),
			   val, section_name (ebl, val));

		  if ((refshdr->sh_flags & SHF_GROUP) == 0)
		    ERROR (gettext ("\
section [%2d] '%s': element %Zu references section [%2d] '%s' without SHF_GROUP flag set\n"),
			   idx, section_name (ebl, idx), cnt / elsize,
			   val, section_name (ebl, val));
		}

	      if (++scnref[val] == 2)
		ERROR (gettext ("\
section [%2d] '%s' is contained in more than one section group\n"),
		       val, section_name (ebl, val));
	    }
	}
    }
}


static const char *
section_flags_string (GElf_Word flags, char *buf, size_t len)
{
  if (flags == 0)
    return "none";

  static const struct
  {
    GElf_Word flag;
    const char *name;
  } known_flags[] =
    {
#define NEWFLAG(name) { SHF_##name, #name }
      NEWFLAG (WRITE),
      NEWFLAG (ALLOC),
      NEWFLAG (EXECINSTR),
      NEWFLAG (MERGE),
      NEWFLAG (STRINGS),
      NEWFLAG (INFO_LINK),
      NEWFLAG (LINK_ORDER),
      NEWFLAG (OS_NONCONFORMING),
      NEWFLAG (GROUP),
      NEWFLAG (TLS)
    };
#undef NEWFLAG
  const size_t nknown_flags = sizeof (known_flags) / sizeof (known_flags[0]);

  char *cp = buf;

  for (size_t cnt = 0; cnt < nknown_flags; ++cnt)
    if (flags & known_flags[cnt].flag)
      {
	if (cp != buf && len > 1)
	  {
	    *cp++ = '|';
	    --len;
	  }

	size_t ncopy = MIN (len - 1, strlen (known_flags[cnt].name));
	cp = mempcpy (cp, known_flags[cnt].name, ncopy);
	len -= ncopy;

	flags ^= known_flags[cnt].flag;
      }

  if (flags != 0 || cp == buf)
    snprintf (cp, len - 1, "%" PRIx64, (uint64_t) flags);

  *cp = '\0';

  return buf;
}


static int
has_copy_reloc (Ebl *ebl, unsigned int symscnndx, unsigned int symndx)
{
  /* First find the relocation section for the symbol table.  */
  Elf_Scn *scn = NULL;
  GElf_Shdr shdr_mem;
  GElf_Shdr *shdr = NULL;
  while ((scn = elf_nextscn (ebl->elf, scn)) != NULL)
    {
      shdr = gelf_getshdr (scn, &shdr_mem);
      if (shdr != NULL
	  && (shdr->sh_type == SHT_REL || shdr->sh_type == SHT_RELA)
	  && shdr->sh_link == symscnndx)
	/* Found the section.  */
	break;
    }

  if (scn == NULL)
    return 0;

  Elf_Data *data = elf_getdata (scn, NULL);
  if (data == NULL)
    return 0;

  if (shdr->sh_type == SHT_REL)
    for (int i = 0; (size_t) i < shdr->sh_size / shdr->sh_entsize; ++i)
      {
	GElf_Rel rel_mem;
	GElf_Rel *rel = gelf_getrel (data, i, &rel_mem);
	if (rel == NULL)
	  continue;

	if (GELF_R_SYM (rel->r_info) == symndx
	    && ebl_copy_reloc_p (ebl, GELF_R_TYPE (rel->r_info)))
	  return 1;
      }
  else
    for (int i = 0; (size_t) i < shdr->sh_size / shdr->sh_entsize; ++i)
      {
	GElf_Rela rela_mem;
	GElf_Rela *rela = gelf_getrela (data, i, &rela_mem);
	if (rela == NULL)
	  continue;

	if (GELF_R_SYM (rela->r_info) == symndx
	    && ebl_copy_reloc_p (ebl, GELF_R_TYPE (rela->r_info)))
	  return 1;
      }

  return 0;
}


static int
in_nobits_scn (Ebl *ebl, unsigned int shndx)
{
  GElf_Shdr shdr_mem;
  GElf_Shdr *shdr = gelf_getshdr (elf_getscn (ebl->elf, shndx), &shdr_mem);
  return shdr != NULL && shdr->sh_type == SHT_NOBITS;
}


static struct version_namelist
{
  const char *objname;
  const char *name;
  GElf_Versym ndx;
  enum { ver_def, ver_need } type;
  struct version_namelist *next;
} *version_namelist;


static int
add_version (const char *objname, const char *name, GElf_Versym ndx, int type)
{
  /* Check that there are no duplications.  */
  struct version_namelist *nlp = version_namelist;
  while (nlp != NULL)
    {
      if (((nlp->objname == NULL && objname == NULL)
	   || (nlp->objname != NULL && objname != NULL
	       && strcmp (nlp->objname, objname) == 0))
	  && strcmp (nlp->name, name) == 0)
	return nlp->type == ver_def ? 1 : -1;
      nlp = nlp->next;
    }

  nlp = xmalloc (sizeof (*nlp));
  nlp->objname = objname;
  nlp->name = name;
  nlp->ndx = ndx;
  nlp->type = type;
  nlp->next = version_namelist;
  version_namelist = nlp;

  return 0;
}


static void
check_versym (Ebl *ebl, int idx)
{
  Elf_Scn *scn = elf_getscn (ebl->elf, idx);
  GElf_Shdr shdr_mem;
  GElf_Shdr *shdr = gelf_getshdr (scn, &shdr_mem);
  if (shdr == NULL)
    /* The error has already been reported.  */
    return;

  Elf_Data *data = elf_getdata (scn, NULL);
  if (data == NULL)
    {
      ERROR (gettext ("section [%2d] '%s': cannot get section data\n"),
	     idx, section_name (ebl, idx));
      return;
    }

  Elf_Scn *symscn = elf_getscn (ebl->elf, shdr->sh_link);
  GElf_Shdr symshdr_mem;
  GElf_Shdr *symshdr = gelf_getshdr (symscn, &symshdr_mem);
  if (symshdr == NULL)
    /* The error has already been reported.  */
    return;

  if (symshdr->sh_type != SHT_DYNSYM)
    {
      ERROR (gettext ("\
section [%2d] '%s' refers in sh_link to section [%2d] '%s' which is no dynamic symbol table\n"),
	     idx, section_name (ebl, idx),
	     shdr->sh_link, section_name (ebl, shdr->sh_link));
      return;
    }

  /* The number of elements in the version symbol table must be the
     same as the number of symbols.  */
  if (shdr->sh_entsize && symshdr->sh_entsize
      && (shdr->sh_size / shdr->sh_entsize
	  != symshdr->sh_size / symshdr->sh_entsize))
    ERROR (gettext ("\
section [%2d] '%s' has different number of entries than symbol table [%2d] '%s'\n"),
	   idx, section_name (ebl, idx),
	   shdr->sh_link, section_name (ebl, shdr->sh_link));

  Elf_Data *symdata = elf_getdata (symscn, NULL);
  if (symdata == NULL)
    /* The error has already been reported.  */
    return;

  for (int cnt = 1; (size_t) cnt < shdr->sh_size / shdr->sh_entsize; ++cnt)
    {
      GElf_Versym versym_mem;
      GElf_Versym *versym = gelf_getversym (data, cnt, &versym_mem);
      if (versym == NULL)
	{
	  ERROR (gettext ("\
section [%2d] '%s': symbol %d: cannot read version data\n"),
		 idx, section_name (ebl, idx), cnt);
	  break;
	}

      GElf_Sym sym_mem;
      GElf_Sym *sym = gelf_getsym (symdata, cnt, &sym_mem);
      if (sym == NULL)
	/* Already reported elsewhere.  */
	continue;

      if (*versym == VER_NDX_GLOBAL)
	{
	  /* Global symbol.  Make sure it is not defined as local.  */
	  if (GELF_ST_BIND (sym->st_info) == STB_LOCAL)
	    ERROR (gettext ("\
section [%2d] '%s': symbol %d: local symbol with global scope\n"),
		   idx, section_name (ebl, idx), cnt);
	}
      else if (*versym != VER_NDX_LOCAL)
	{
	  /* Versioned symbol.  Make sure it is not defined as local.  */
	  if (!gnuld && GELF_ST_BIND (sym->st_info) == STB_LOCAL)
	    ERROR (gettext ("\
section [%2d] '%s': symbol %d: local symbol with version\n"),
		   idx, section_name (ebl, idx), cnt);

	  /* Look through the list of defined versions and locate the
	     index we need for this symbol.  */
	  struct version_namelist *runp = version_namelist;
	  while (runp != NULL)
	    if (runp->ndx == (*versym & (GElf_Versym) 0x7fff))
	      break;
	    else
	      runp = runp->next;

	  if (runp == NULL)
	    ERROR (gettext ("\
section [%2d] '%s': symbol %d: invalid version index %d\n"),
		   idx, section_name (ebl, idx), cnt, (int) *versym);
	  else if (sym->st_shndx == SHN_UNDEF
		   && runp->type == ver_def)
	    ERROR (gettext ("\
section [%2d] '%s': symbol %d: version index %d is for defined version\n"),
		   idx, section_name (ebl, idx), cnt, (int) *versym);
	  else if (sym->st_shndx != SHN_UNDEF
		   && runp->type == ver_need)
	    {
	      /* Unless this symbol has a copy relocation associated
		 this must not happen.  */
	      if (!has_copy_reloc (ebl, shdr->sh_link, cnt)
		  && !in_nobits_scn (ebl, sym->st_shndx))
		ERROR (gettext ("\
section [%2d] '%s': symbol %d: version index %d is for requested version\n"),
		       idx, section_name (ebl, idx), cnt, (int) *versym);
	    }
	}
    }
}


static int
unknown_dependency_p (Elf *elf, const char *fname)
{
  GElf_Phdr phdr_mem;
  GElf_Phdr *phdr = NULL;

  unsigned int i;
  for (i = 0; i < phnum; ++i)
    if ((phdr = gelf_getphdr (elf, i, &phdr_mem)) != NULL
	&& phdr->p_type == PT_DYNAMIC)
      break;

  if (i == phnum)
    return 1;
  assert (phdr != NULL);
  Elf_Scn *scn = gelf_offscn (elf, phdr->p_offset);
  GElf_Shdr shdr_mem;
  GElf_Shdr *shdr = gelf_getshdr (scn, &shdr_mem);
  Elf_Data *data = elf_getdata (scn, NULL);
  if (shdr != NULL && shdr->sh_type == SHT_DYNAMIC && data != NULL)
    for (size_t j = 0; j < shdr->sh_size / shdr->sh_entsize; ++j)
      {
	GElf_Dyn dyn_mem;
	GElf_Dyn *dyn = gelf_getdyn (data, j, &dyn_mem);
	if (dyn != NULL && dyn->d_tag == DT_NEEDED)
	  {
	    const char *str = elf_strptr (elf, shdr->sh_link, dyn->d_un.d_val);
	    if (str != NULL && strcmp (str, fname) == 0)
	      /* Found it.  */
	      return 0;
	  }
      }

  return 1;
}


static unsigned int nverneed;

static void
check_verneed (Ebl *ebl, GElf_Shdr *shdr, int idx)
{
  if (++nverneed == 2)
    ERROR (gettext ("more than one version reference section present\n"));

  GElf_Shdr strshdr_mem;
  GElf_Shdr *strshdr = gelf_getshdr (elf_getscn (ebl->elf, shdr->sh_link),
				     &strshdr_mem);
  if (strshdr == NULL)
    return;
  if (strshdr->sh_type != SHT_STRTAB)
    ERROR (gettext ("\
section [%2d] '%s': sh_link does not link to string table\n"),
	   idx, section_name (ebl, idx));

  Elf_Data *data = elf_getdata (elf_getscn (ebl->elf, idx), NULL);
  if (data == NULL)
    {
      ERROR (gettext ("section [%2d] '%s': cannot get section data\n"),
	     idx, section_name (ebl, idx));
      return;
    }
  unsigned int offset = 0;
  for (int cnt = shdr->sh_info; --cnt >= 0; )
    {
      /* Get the data at the next offset.  */
      GElf_Verneed needmem;
      GElf_Verneed *need = gelf_getverneed (data, offset, &needmem);
      if (need == NULL)
	break;

      unsigned int auxoffset = offset + need->vn_aux;

      if (need->vn_version != EV_CURRENT)
	ERROR (gettext ("\
section [%2d] '%s': entry %d has wrong version %d\n"),
	       idx, section_name (ebl, idx), cnt, (int) need->vn_version);

      if (need->vn_cnt > 0 && need->vn_aux < gelf_fsize (ebl->elf, ELF_T_VNEED,
							 1, EV_CURRENT))
	ERROR (gettext ("\
section [%2d] '%s': entry %d has wrong offset of auxiliary data\n"),
	       idx, section_name (ebl, idx), cnt);

      const char *libname = elf_strptr (ebl->elf, shdr->sh_link,
					need->vn_file);
      if (libname == NULL)
	{
	  ERROR (gettext ("\
section [%2d] '%s': entry %d has invalid file reference\n"),
		 idx, section_name (ebl, idx), cnt);
	  goto next_need;
	}

      /* Check that there is a DT_NEEDED entry for the referenced library.  */
      if (unknown_dependency_p (ebl->elf, libname))
	ERROR (gettext ("\
section [%2d] '%s': entry %d references unknown dependency\n"),
	       idx, section_name (ebl, idx), cnt);

      for (int cnt2 = need->vn_cnt; --cnt2 >= 0; )
	{
	  GElf_Vernaux auxmem;
	  GElf_Vernaux *aux = gelf_getvernaux (data, auxoffset, &auxmem);
	  if (aux == NULL)
	    break;

	  if ((aux->vna_flags & ~VER_FLG_WEAK) != 0)
	    ERROR (gettext ("\
section [%2d] '%s': auxiliary entry %d of entry %d has unknown flag\n"),
		   idx, section_name (ebl, idx), need->vn_cnt - cnt2, cnt);

	  const char *verstr = elf_strptr (ebl->elf, shdr->sh_link,
					   aux->vna_name);
	  if (verstr == NULL)
	    ERROR (gettext ("\
section [%2d] '%s': auxiliary entry %d of entry %d has invalid name reference\n"),
		   idx, section_name (ebl, idx), need->vn_cnt - cnt2, cnt);
	  else
	    {
	      GElf_Word hashval = elf_hash (verstr);
	      if (hashval != aux->vna_hash)
		ERROR (gettext ("\
section [%2d] '%s': auxiliary entry %d of entry %d has wrong hash value: %#x, expected %#x\n"),
		       idx, section_name (ebl, idx), need->vn_cnt - cnt2,
		       cnt, (int) hashval, (int) aux->vna_hash);

	      int res = add_version (libname, verstr, aux->vna_other,
				     ver_need);
	      if (unlikely (res !=0))
		{
		  assert (res > 0);
		  ERROR (gettext ("\
section [%2d] '%s': auxiliary entry %d of entry %d has duplicate version name '%s'\n"),
			 idx, section_name (ebl, idx), need->vn_cnt - cnt2,
			 cnt, verstr);
		}
	    }

	  if ((aux->vna_next != 0 || cnt2 > 0)
	      && aux->vna_next < gelf_fsize (ebl->elf, ELF_T_VNAUX, 1,
					     EV_CURRENT))
	    {
	      ERROR (gettext ("\
section [%2d] '%s': auxiliary entry %d of entry %d has wrong next field\n"),
		     idx, section_name (ebl, idx), need->vn_cnt - cnt2, cnt);
	      break;
	    }

	  auxoffset += MAX (aux->vna_next,
			    gelf_fsize (ebl->elf, ELF_T_VNAUX, 1, EV_CURRENT));
	}

      /* Find the next offset.  */
    next_need:
      offset += need->vn_next;

      if ((need->vn_next != 0 || cnt > 0)
	  && offset < auxoffset)
	ERROR (gettext ("\
section [%2d] '%s': entry %d has invalid offset to next entry\n"),
	       idx, section_name (ebl, idx), cnt);
    }
}


static unsigned int nverdef;

static void
check_verdef (Ebl *ebl, GElf_Shdr *shdr, int idx)
{
  if (++nverdef == 2)
    ERROR (gettext ("more than one version definition section present\n"));

  GElf_Shdr strshdr_mem;
  GElf_Shdr *strshdr = gelf_getshdr (elf_getscn (ebl->elf, shdr->sh_link),
				     &strshdr_mem);
  if (strshdr == NULL)
    return;
  if (strshdr->sh_type != SHT_STRTAB)
    ERROR (gettext ("\
section [%2d] '%s': sh_link does not link to string table\n"),
	   idx, section_name (ebl, idx));

  Elf_Data *data = elf_getdata (elf_getscn (ebl->elf, idx), NULL);
  if (data == NULL)
    {
    no_data:
      ERROR (gettext ("section [%2d] '%s': cannot get section data\n"),
	     idx, section_name (ebl, idx));
      return;
    }

  /* Iterate over all version definition entries.  We check that there
     is a BASE entry and that each index is unique.  To do the later
     we collection the information in a list which is later
     examined.  */
  struct namelist
  {
    const char *name;
    struct namelist *next;
  } *namelist = NULL;
  struct namelist *refnamelist = NULL;

  bool has_base = false;
  unsigned int offset = 0;
  for (int cnt = shdr->sh_info; --cnt >= 0; )
    {
      /* Get the data at the next offset.  */
      GElf_Verdef defmem;
      GElf_Verdef *def = gelf_getverdef (data, offset, &defmem);
      if (def == NULL)
	goto no_data;

      if ((def->vd_flags & VER_FLG_BASE) != 0)
	{
	  if (has_base)
	    ERROR (gettext ("\
section [%2d] '%s': more than one BASE definition\n"),
		   idx, section_name (ebl, idx));
	  if (def->vd_ndx != VER_NDX_GLOBAL)
	    ERROR (gettext ("\
section [%2d] '%s': BASE definition must have index VER_NDX_GLOBAL\n"),
		   idx, section_name (ebl, idx));
	  has_base = true;
	}
      if ((def->vd_flags & ~(VER_FLG_BASE|VER_FLG_WEAK)) != 0)
	ERROR (gettext ("\
section [%2d] '%s': entry %d has unknown flag\n"),
	       idx, section_name (ebl, idx), cnt);

      if (def->vd_version != EV_CURRENT)
	ERROR (gettext ("\
section [%2d] '%s': entry %d has wrong version %d\n"),
	       idx, section_name (ebl, idx), cnt, (int) def->vd_version);

      if (def->vd_cnt > 0 && def->vd_aux < gelf_fsize (ebl->elf, ELF_T_VDEF,
						       1, EV_CURRENT))
	ERROR (gettext ("\
section [%2d] '%s': entry %d has wrong offset of auxiliary data\n"),
	       idx, section_name (ebl, idx), cnt);

      unsigned int auxoffset = offset + def->vd_aux;
      GElf_Verdaux auxmem;
      GElf_Verdaux *aux = gelf_getverdaux (data, auxoffset, &auxmem);
      if (aux == NULL)
	goto no_data;

      const char *name = elf_strptr (ebl->elf, shdr->sh_link, aux->vda_name);
      if (name == NULL)
	{
	  ERROR (gettext ("\
section [%2d] '%s': entry %d has invalid name reference\n"),
		 idx, section_name (ebl, idx), cnt);
	  goto next_def;
	}
      GElf_Word hashval = elf_hash (name);
      if (def->vd_hash != hashval)
	ERROR (gettext ("\
section [%2d] '%s': entry %d has wrong hash value: %#x, expected %#x\n"),
	       idx, section_name (ebl, idx), cnt, (int) hashval,
	       (int) def->vd_hash);

      int res = add_version (NULL, name, def->vd_ndx, ver_def);
      if (unlikely (res !=0))
	{
	  assert (res > 0);
	  ERROR (gettext ("\
section [%2d] '%s': entry %d has duplicate version name '%s'\n"),
		 idx, section_name (ebl, idx), cnt, name);
	}

      struct namelist *newname = alloca (sizeof (*newname));
      newname->name = name;
      newname->next = namelist;
      namelist = newname;

      auxoffset += aux->vda_next;
      for (int cnt2 = 1; cnt2 < def->vd_cnt; ++cnt2)
	{
	  aux = gelf_getverdaux (data, auxoffset, &auxmem);
	  if (aux == NULL)
	    goto no_data;

	  name = elf_strptr (ebl->elf, shdr->sh_link, aux->vda_name);
	  if (name == NULL)
	    ERROR (gettext ("\
section [%2d] '%s': entry %d has invalid name reference in auxiliary data\n"),
		   idx, section_name (ebl, idx), cnt);
	  else
	    {
	      newname = alloca (sizeof (*newname));
	      newname->name = name;
	      newname->next = refnamelist;
	      refnamelist = newname;
	    }

	  if ((aux->vda_next != 0 || cnt2 + 1 < def->vd_cnt)
	      && aux->vda_next < gelf_fsize (ebl->elf, ELF_T_VDAUX, 1,
					     EV_CURRENT))
	    {
	      ERROR (gettext ("\
section [%2d] '%s': entry %d has wrong next field in auxiliary data\n"),
		     idx, section_name (ebl, idx), cnt);
	      break;
	    }

	  auxoffset += MAX (aux->vda_next,
			    gelf_fsize (ebl->elf, ELF_T_VDAUX, 1, EV_CURRENT));
	}

      /* Find the next offset.  */
    next_def:
      offset += def->vd_next;

      if ((def->vd_next != 0 || cnt > 0)
	  && offset < auxoffset)
	ERROR (gettext ("\
section [%2d] '%s': entry %d has invalid offset to next entry\n"),
	       idx, section_name (ebl, idx), cnt);
    }

  if (!has_base)
    ERROR (gettext ("section [%2d] '%s': no BASE definition\n"),
	   idx, section_name (ebl, idx));

  /* Check whether the referenced names are available.  */
  while (namelist != NULL)
    {
      struct version_namelist *runp = version_namelist;
      while (runp != NULL)
	{
	  if (runp->type == ver_def
	      && strcmp (runp->name, namelist->name) == 0)
	    break;
	  runp = runp->next;
	}

      if (runp == NULL)
	ERROR (gettext ("\
section [%2d] '%s': unknown parent version '%s'\n"),
	       idx, section_name (ebl, idx), namelist->name);

      namelist = namelist->next;
    }
}

static void
check_attributes (Ebl *ebl, GElf_Ehdr *ehdr, GElf_Shdr *shdr, int idx)
{
  if (shdr->sh_size == 0)
    {
      ERROR (gettext ("section [%2d] '%s': empty object attributes section\n"),
	     idx, section_name (ebl, idx));
      return;
    }

  Elf_Data *data = elf_rawdata (elf_getscn (ebl->elf, idx), NULL);
  if (data == NULL || data->d_size == 0)
    {
      ERROR (gettext ("section [%2d] '%s': cannot get section data\n"),
	     idx, section_name (ebl, idx));
      return;
    }

  inline size_t pos (const unsigned char *p)
  {
    return p - (const unsigned char *) data->d_buf;
  }

  const unsigned char *p = data->d_buf;
  if (*p++ != 'A')
    {
      ERROR (gettext ("section [%2d] '%s': unrecognized attribute format\n"),
	     idx, section_name (ebl, idx));
      return;
    }

  inline size_t left (void)
  {
    return (const unsigned char *) data->d_buf + data->d_size - p;
  }

  while (left () >= 4)
    {
      uint32_t len;
      memcpy (&len, p, sizeof len);

      if (len == 0)
	ERROR (gettext ("\
section [%2d] '%s': offset %zu: zero length field in attribute section\n"),
	       idx, section_name (ebl, idx), pos (p));

      if (MY_ELFDATA != ehdr->e_ident[EI_DATA])
	CONVERT (len);

      if (len > left ())
	{
	  ERROR (gettext ("\
section [%2d] '%s': offset %zu: invalid length in attribute section\n"),
		 idx, section_name (ebl, idx), pos (p));
	  break;
	}

      const unsigned char *name = p + sizeof len;
      p += len;

      unsigned const char *q = memchr (name, '\0', len);
      if (q == NULL)
	{
	  ERROR (gettext ("\
section [%2d] '%s': offset %zu: unterminated vendor name string\n"),
		 idx, section_name (ebl, idx), pos (p));
	  continue;
	}
      ++q;

      if (q - name == sizeof "gnu" && !memcmp (name, "gnu", sizeof "gnu"))
	while (q < p)
	  {
	    unsigned const char *chunk = q;

	    unsigned int subsection_tag;
	    get_uleb128 (subsection_tag, q, p);

	    if (q >= p)
	      {
		ERROR (gettext ("\
section [%2d] '%s': offset %zu: endless ULEB128 in attribute subsection tag\n"),
		       idx, section_name (ebl, idx), pos (chunk));
		break;
	      }

	    uint32_t subsection_len;
	    if (p - q < (ptrdiff_t) sizeof subsection_len)
	      {
		ERROR (gettext ("\
section [%2d] '%s': offset %zu: truncated attribute section\n"),
		       idx, section_name (ebl, idx), pos (q));
		break;
	      }

	    memcpy (&subsection_len, q, sizeof subsection_len);
	    if (subsection_len == 0)
	      {
		ERROR (gettext ("\
section [%2d] '%s': offset %zu: zero length field in attribute subsection\n"),
		       idx, section_name (ebl, idx), pos (q));

		q += sizeof subsection_len;
		continue;
	      }

	    if (MY_ELFDATA != ehdr->e_ident[EI_DATA])
	      CONVERT (subsection_len);

	    if (p - chunk < (ptrdiff_t) subsection_len)
	      {
		ERROR (gettext ("\
section [%2d] '%s': offset %zu: invalid length in attribute subsection\n"),
		       idx, section_name (ebl, idx), pos (q));
		break;
	      }

	    const unsigned char *subsection_end = chunk + subsection_len;
	    chunk = q;
	    q = subsection_end;

	    if (subsection_tag != 1) /* Tag_File */
	      ERROR (gettext ("\
section [%2d] '%s': offset %zu: attribute subsection has unexpected tag %u\n"),
		     idx, section_name (ebl, idx), pos (chunk), subsection_tag);
	    else
	      {
		chunk += sizeof subsection_len;
		while (chunk < q)
		  {
		    unsigned int tag;
		    get_uleb128 (tag, chunk, q);

		    uint64_t value = 0;
		    const unsigned char *r = chunk;
		    if (tag == 32 || (tag & 1) == 0)
		      {
			get_uleb128 (value, r, q);
			if (r > q)
			  {
			    ERROR (gettext ("\
section [%2d] '%s': offset %zu: endless ULEB128 in attribute tag\n"),
				   idx, section_name (ebl, idx), pos (chunk));
			    break;
			  }
		      }
		    if (tag == 32 || (tag & 1) != 0)
		      {
			r = memchr (r, '\0', q - r);
			if (r == NULL)
			  {
			    ERROR (gettext ("\
section [%2d] '%s': offset %zu: unterminated string in attribute\n"),
				   idx, section_name (ebl, idx), pos (chunk));
			    break;
			  }
			++r;
		      }

		    const char *tag_name = NULL;
		    const char *value_name = NULL;
		    if (!ebl_check_object_attribute (ebl, (const char *) name,
						     tag, value,
						     &tag_name, &value_name))
		      ERROR (gettext ("\
section [%2d] '%s': offset %zu: unrecognized attribute tag %u\n"),
			     idx, section_name (ebl, idx), pos (chunk), tag);
		    else if ((tag & 1) == 0 && value_name == NULL)
		      ERROR (gettext ("\
section [%2d] '%s': offset %zu: unrecognized %s attribute value %" PRIu64 "\n"),
			     idx, section_name (ebl, idx), pos (chunk),
			     tag_name, value);

		    chunk = r;
		  }
	      }
	  }
      else
	ERROR (gettext ("\
section [%2d] '%s': offset %zu: vendor '%s' unknown\n"),
	       idx, section_name (ebl, idx), pos (p), name);
    }

  if (left () != 0)
    ERROR (gettext ("\
section [%2d] '%s': offset %zu: extra bytes after last attribute section\n"),
	   idx, section_name (ebl, idx), pos (p));
}

static bool has_loadable_segment;
static bool has_interp_segment;

static const struct
{
  const char *name;
  size_t namelen;
  GElf_Word type;
  enum { unused, exact, atleast, exact_or_gnuld } attrflag;
  GElf_Word attr;
  GElf_Word attr2;
} special_sections[] =
  {
    /* See figure 4-14 in the gABI.  */
    { ".bss", 5, SHT_NOBITS, exact, SHF_ALLOC | SHF_WRITE, 0 },
    { ".comment", 8, SHT_PROGBITS, atleast, 0, SHF_MERGE | SHF_STRINGS },
    { ".data", 6, SHT_PROGBITS, exact, SHF_ALLOC | SHF_WRITE, 0 },
    { ".data1", 7, SHT_PROGBITS, exact, SHF_ALLOC | SHF_WRITE, 0 },
    { ".debug_str", 11, SHT_PROGBITS, exact_or_gnuld, SHF_MERGE | SHF_STRINGS, 0 },
    { ".debug", 6, SHT_PROGBITS, exact, 0, 0 },
    { ".dynamic", 9, SHT_DYNAMIC, atleast, SHF_ALLOC, SHF_WRITE },
    { ".dynstr", 8, SHT_STRTAB, exact, SHF_ALLOC, 0 },
    { ".dynsym", 8, SHT_DYNSYM, exact, SHF_ALLOC, 0 },
    { ".fini", 6, SHT_PROGBITS, exact, SHF_ALLOC | SHF_EXECINSTR, 0 },
    { ".fini_array", 12, SHT_FINI_ARRAY, exact, SHF_ALLOC | SHF_WRITE, 0 },
    { ".got", 5, SHT_PROGBITS, unused, 0, 0 }, // XXX more info?
    { ".hash", 6, SHT_HASH, exact, SHF_ALLOC, 0 },
    { ".init", 6, SHT_PROGBITS, exact, SHF_ALLOC | SHF_EXECINSTR, 0 },
    { ".init_array", 12, SHT_INIT_ARRAY, exact, SHF_ALLOC | SHF_WRITE, 0 },
    { ".interp", 8, SHT_PROGBITS, atleast, 0, SHF_ALLOC }, // XXX more tests?
    { ".line", 6, SHT_PROGBITS, exact, 0, 0 },
    { ".note", 6, SHT_NOTE, atleast, 0, SHF_ALLOC },
    { ".plt", 5, SHT_PROGBITS, unused, 0, 0 }, // XXX more tests
    { ".preinit_array", 15, SHT_PREINIT_ARRAY, exact, SHF_ALLOC | SHF_WRITE, 0 },
    { ".rela", 5, SHT_RELA, atleast, 0, SHF_ALLOC | SHF_INFO_LINK }, // XXX more tests
    { ".rel", 4, SHT_REL, atleast, 0, SHF_ALLOC | SHF_INFO_LINK }, // XXX more tests
    { ".rodata", 8, SHT_PROGBITS, atleast, SHF_ALLOC, SHF_MERGE | SHF_STRINGS },
    { ".rodata1", 9, SHT_PROGBITS, atleast, SHF_ALLOC, SHF_MERGE | SHF_STRINGS },
    { ".shstrtab", 10, SHT_STRTAB, exact, 0, 0 },
    { ".strtab", 8, SHT_STRTAB, atleast, 0, SHF_ALLOC }, // XXX more tests
    { ".symtab", 8, SHT_SYMTAB, atleast, 0, SHF_ALLOC }, // XXX more tests
    { ".symtab_shndx", 14, SHT_SYMTAB_SHNDX, atleast, 0, SHF_ALLOC }, // XXX more tests
    { ".tbss", 6, SHT_NOBITS, exact, SHF_ALLOC | SHF_WRITE | SHF_TLS, 0 },
    { ".tdata", 7, SHT_PROGBITS, exact, SHF_ALLOC | SHF_WRITE | SHF_TLS, 0 },
    { ".tdata1", 8, SHT_PROGBITS, exact, SHF_ALLOC | SHF_WRITE | SHF_TLS, 0 },
    { ".text", 6, SHT_PROGBITS, exact, SHF_ALLOC | SHF_EXECINSTR, 0 },

    /* The following are GNU extensions.  */
    { ".gnu.version", 13, SHT_GNU_versym, exact, SHF_ALLOC, 0 },
    { ".gnu.version_d", 15, SHT_GNU_verdef, exact, SHF_ALLOC, 0 },
    { ".gnu.version_r", 15, SHT_GNU_verneed, exact, SHF_ALLOC, 0 },
    { ".gnu.attributes", 16, SHT_GNU_ATTRIBUTES, exact, 0, 0 },
  };
#define nspecial_sections \
  (sizeof (special_sections) / sizeof (special_sections[0]))

#define IS_KNOWN_SPECIAL(idx, string, prefix)			      \
  (special_sections[idx].namelen == sizeof string - (prefix ? 1 : 0)  \
   && !memcmp (special_sections[idx].name, string, \
	       sizeof string - (prefix ? 1 : 0)))


/* Indeces of some sections we need later.  */
static size_t eh_frame_hdr_scnndx;
static size_t eh_frame_scnndx;
static size_t gcc_except_table_scnndx;


static void
check_sections (Ebl *ebl, GElf_Ehdr *ehdr)
{
  if (ehdr->e_shoff == 0)
    /* No section header.  */
    return;

  /* Allocate array to count references in section groups.  */
  scnref = (int *) xcalloc (shnum, sizeof (int));

  /* Check the zeroth section first.  It must not have any contents
     and the section header must contain nonzero value at most in the
     sh_size and sh_link fields.  */
  GElf_Shdr shdr_mem;
  GElf_Shdr *shdr = gelf_getshdr (elf_getscn (ebl->elf, 0), &shdr_mem);
  if (shdr == NULL)
    ERROR (gettext ("cannot get section header of zeroth section\n"));
  else
    {
      if (shdr->sh_name != 0)
	ERROR (gettext ("zeroth section has nonzero name\n"));
      if (shdr->sh_type != 0)
	ERROR (gettext ("zeroth section has nonzero type\n"));
      if (shdr->sh_flags != 0)
	ERROR (gettext ("zeroth section has nonzero flags\n"));
      if (shdr->sh_addr != 0)
	ERROR (gettext ("zeroth section has nonzero address\n"));
      if (shdr->sh_offset != 0)
	ERROR (gettext ("zeroth section has nonzero offset\n"));
      if (shdr->sh_addralign != 0)
	ERROR (gettext ("zeroth section has nonzero align value\n"));
      if (shdr->sh_entsize != 0)
	ERROR (gettext ("zeroth section has nonzero entry size value\n"));

      if (shdr->sh_size != 0 && ehdr->e_shnum != 0)
	ERROR (gettext ("\
zeroth section has nonzero size value while ELF header has nonzero shnum value\n"));

      if (shdr->sh_link != 0 && ehdr->e_shstrndx != SHN_XINDEX)
	ERROR (gettext ("\
zeroth section has nonzero link value while ELF header does not signal overflow in shstrndx\n"));

      if (shdr->sh_info != 0 && ehdr->e_phnum != PN_XNUM)
	ERROR (gettext ("\
zeroth section has nonzero link value while ELF header does not signal overflow in phnum\n"));
    }

  int *segment_flags = xcalloc (phnum, sizeof segment_flags[0]);

  bool dot_interp_section = false;

  size_t hash_idx = 0;
  size_t gnu_hash_idx = 0;

  size_t versym_scnndx = 0;
  for (size_t cnt = 1; cnt < shnum; ++cnt)
    {
      shdr = gelf_getshdr (elf_getscn (ebl->elf, cnt), &shdr_mem);
      if (shdr == NULL)
	{
	  ERROR (gettext ("\
cannot get section header for section [%2zu] '%s': %s\n"),
		 cnt, section_name (ebl, cnt), elf_errmsg (-1));
	  continue;
	}

      const char *scnname = elf_strptr (ebl->elf, shstrndx, shdr->sh_name);

      if (scnname == NULL)
	ERROR (gettext ("section [%2zu]: invalid name\n"), cnt);
      else
	{
	  /* Check whether it is one of the special sections defined in
	     the gABI.  */
	  size_t s;
	  for (s = 0; s < nspecial_sections; ++s)
	    if (strncmp (scnname, special_sections[s].name,
			 special_sections[s].namelen) == 0)
	      {
		char stbuf1[100];
		char stbuf2[100];
		char stbuf3[100];

		GElf_Word good_type = special_sections[s].type;
		if (IS_KNOWN_SPECIAL (s, ".plt", false)
		    && ebl_bss_plt_p (ebl))
		  good_type = SHT_NOBITS;

		/* In a debuginfo file, any normal section can be SHT_NOBITS.
		   This is only invalid for DWARF sections and .shstrtab.  */
		if (shdr->sh_type != good_type
		    && (shdr->sh_type != SHT_NOBITS
			|| !is_debuginfo
			|| IS_KNOWN_SPECIAL (s, ".debug_str", false)
			|| IS_KNOWN_SPECIAL (s, ".debug", true)
			|| IS_KNOWN_SPECIAL (s, ".shstrtab", false)))
		  ERROR (gettext ("\
section [%2d] '%s' has wrong type: expected %s, is %s\n"),
			 (int) cnt, scnname,
			 ebl_section_type_name (ebl, special_sections[s].type,
						stbuf1, sizeof (stbuf1)),
			 ebl_section_type_name (ebl, shdr->sh_type,
						stbuf2, sizeof (stbuf2)));

		if (special_sections[s].attrflag == exact
		    || special_sections[s].attrflag == exact_or_gnuld)
		  {
		    /* Except for the link order and group bit all the
		       other bits should match exactly.  */
		    if ((shdr->sh_flags & ~(SHF_LINK_ORDER | SHF_GROUP))
			!= special_sections[s].attr
			&& (special_sections[s].attrflag == exact || !gnuld))
		      ERROR (gettext ("\
section [%2zu] '%s' has wrong flags: expected %s, is %s\n"),
			     cnt, scnname,
			     section_flags_string (special_sections[s].attr,
						   stbuf1, sizeof (stbuf1)),
			     section_flags_string (shdr->sh_flags
						   & ~SHF_LINK_ORDER,
						   stbuf2, sizeof (stbuf2)));
		  }
		else if (special_sections[s].attrflag == atleast)
		  {
		    if ((shdr->sh_flags & special_sections[s].attr)
			!= special_sections[s].attr
			|| ((shdr->sh_flags & ~(SHF_LINK_ORDER | SHF_GROUP
						| special_sections[s].attr
						| special_sections[s].attr2))
			    != 0))
		      ERROR (gettext ("\
section [%2zu] '%s' has wrong flags: expected %s and possibly %s, is %s\n"),
			     cnt, scnname,
			     section_flags_string (special_sections[s].attr,
						   stbuf1, sizeof (stbuf1)),
			     section_flags_string (special_sections[s].attr2,
						   stbuf2, sizeof (stbuf2)),
			     section_flags_string (shdr->sh_flags
						   & ~(SHF_LINK_ORDER
						       | SHF_GROUP),
						   stbuf3, sizeof (stbuf3)));
		  }

		if (strcmp (scnname, ".interp") == 0)
		  {
		    dot_interp_section = true;

		    if (ehdr->e_type == ET_REL)
		      ERROR (gettext ("\
section [%2zu] '%s' present in object file\n"),
			     cnt, scnname);

		    if ((shdr->sh_flags & SHF_ALLOC) != 0
			&& !has_loadable_segment)
		      ERROR (gettext ("\
section [%2zu] '%s' has SHF_ALLOC flag set but there is no loadable segment\n"),
			     cnt, scnname);
		    else if ((shdr->sh_flags & SHF_ALLOC) == 0
			     && has_loadable_segment)
		      ERROR (gettext ("\
section [%2zu] '%s' has SHF_ALLOC flag not set but there are loadable segments\n"),
			     cnt, scnname);
		  }
		else
		  {
		    if (strcmp (scnname, ".symtab_shndx") == 0
			&& ehdr->e_type != ET_REL)
		      ERROR (gettext ("\
section [%2zu] '%s' is extension section index table in non-object file\n"),
			     cnt, scnname);

		    /* These sections must have the SHF_ALLOC flag set iff
		       a loadable segment is available.

		       .relxxx
		       .strtab
		       .symtab
		       .symtab_shndx

		       Check that if there is a reference from the
		       loaded section these sections also have the
		       ALLOC flag set.  */
#if 0
		    // XXX TODO
		    if ((shdr->sh_flags & SHF_ALLOC) != 0
			&& !has_loadable_segment)
		      ERROR (gettext ("\
section [%2zu] '%s' has SHF_ALLOC flag set but there is no loadable segment\n"),
			     cnt, scnname);
		    else if ((shdr->sh_flags & SHF_ALLOC) == 0
			     && has_loadable_segment)
		      ERROR (gettext ("\
section [%2zu] '%s' has SHF_ALLOC flag not set but there are loadable segments\n"),
			     cnt, scnname);
#endif
		  }

		break;
	      }

	  /* Remember a few special sections for later.  */
	  if (strcmp (scnname, ".eh_frame_hdr") == 0)
	    eh_frame_hdr_scnndx = cnt;
	  else if (strcmp (scnname, ".eh_frame") == 0)
	    eh_frame_scnndx = cnt;
	  else if (strcmp (scnname, ".gcc_except_table") == 0)
	    gcc_except_table_scnndx = cnt;
	}

      if (shdr->sh_entsize != 0 && shdr->sh_size % shdr->sh_entsize)
	ERROR (gettext ("\
section [%2zu] '%s': size not multiple of entry size\n"),
	       cnt, section_name (ebl, cnt));

      if (elf_strptr (ebl->elf, shstrndx, shdr->sh_name) == NULL)
	ERROR (gettext ("cannot get section header\n"));

      if (shdr->sh_type >= SHT_NUM
	  && shdr->sh_type != SHT_GNU_ATTRIBUTES
	  && shdr->sh_type != SHT_GNU_LIBLIST
	  && shdr->sh_type != SHT_CHECKSUM
	  && shdr->sh_type != SHT_GNU_verdef
	  && shdr->sh_type != SHT_GNU_verneed
	  && shdr->sh_type != SHT_GNU_versym
	  && ebl_section_type_name (ebl, shdr->sh_type, NULL, 0) == NULL)
	ERROR (gettext ("section [%2zu] '%s' has unsupported type %d\n"),
	       cnt, section_name (ebl, cnt),
	       (int) shdr->sh_type);

#define ALL_SH_FLAGS (SHF_WRITE | SHF_ALLOC | SHF_EXECINSTR | SHF_MERGE \
		      | SHF_STRINGS | SHF_INFO_LINK | SHF_LINK_ORDER \
		      | SHF_OS_NONCONFORMING | SHF_GROUP | SHF_TLS)
      if (shdr->sh_flags & ~(GElf_Xword) ALL_SH_FLAGS)
	{
	  GElf_Xword sh_flags = shdr->sh_flags & ~(GElf_Xword) ALL_SH_FLAGS;
	  if (sh_flags & SHF_MASKPROC)
	    {
	      if (!ebl_machine_section_flag_check (ebl,
						   sh_flags & SHF_MASKPROC))
		ERROR (gettext ("section [%2zu] '%s'"
				" contains invalid processor-specific flag(s)"
				" %#" PRIx64 "\n"),
		       cnt, section_name (ebl, cnt), sh_flags & SHF_MASKPROC);
	      sh_flags &= ~(GElf_Xword) SHF_MASKPROC;
	    }
	  if (sh_flags != 0)
	    ERROR (gettext ("section [%2zu] '%s' contains unknown flag(s)"
			    " %#" PRIx64 "\n"),
		   cnt, section_name (ebl, cnt), sh_flags);
	}
      if (shdr->sh_flags & SHF_TLS)
	{
	  // XXX Correct?
	  if (shdr->sh_addr != 0 && !gnuld)
	    ERROR (gettext ("\
section [%2zu] '%s': thread-local data sections address not zero\n"),
		   cnt, section_name (ebl, cnt));

	  // XXX TODO more tests!?
	}

      if (shdr->sh_link >= shnum)
	ERROR (gettext ("\
section [%2zu] '%s': invalid section reference in link value\n"),
	       cnt, section_name (ebl, cnt));

      if (SH_INFO_LINK_P (shdr) && shdr->sh_info >= shnum)
	ERROR (gettext ("\
section [%2zu] '%s': invalid section reference in info value\n"),
	       cnt, section_name (ebl, cnt));

      if ((shdr->sh_flags & SHF_MERGE) == 0
	  && (shdr->sh_flags & SHF_STRINGS) != 0
	  && be_strict)
	ERROR (gettext ("\
section [%2zu] '%s': strings flag set without merge flag\n"),
	       cnt, section_name (ebl, cnt));

      if ((shdr->sh_flags & SHF_MERGE) != 0 && shdr->sh_entsize == 0)
	ERROR (gettext ("\
section [%2zu] '%s': merge flag set but entry size is zero\n"),
	       cnt, section_name (ebl, cnt));

      if (shdr->sh_flags & SHF_GROUP)
	check_scn_group (ebl, cnt);

      if (shdr->sh_flags & SHF_EXECINSTR)
	{
	  switch (shdr->sh_type)
	    {
	    case SHT_PROGBITS:
	      break;

	    case SHT_NOBITS:
	      if (is_debuginfo)
		break;
	    default:
	      ERROR (gettext ("\
section [%2zu] '%s' has unexpected type %d for an executable section\n"),
		     cnt, section_name (ebl, cnt), shdr->sh_type);
	      break;
	    }

	  if ((shdr->sh_flags & SHF_WRITE)
	      && !ebl_check_special_section (ebl, cnt, shdr,
					     section_name (ebl, cnt)))
	    ERROR (gettext ("\
section [%2zu] '%s' is both executable and writable\n"),
		   cnt, section_name (ebl, cnt));
	}

      if (ehdr->e_type != ET_REL && (shdr->sh_flags & SHF_ALLOC) != 0)
	{
	  /* Make sure the section is contained in a loaded segment
	     and that the initialization part matches NOBITS sections.  */
	  unsigned int pcnt;
	  GElf_Phdr phdr_mem;
	  GElf_Phdr *phdr;

	  for (pcnt = 0; pcnt < phnum; ++pcnt)
	    if ((phdr = gelf_getphdr (ebl->elf, pcnt, &phdr_mem)) != NULL
		&& ((phdr->p_type == PT_LOAD
		     && (shdr->sh_flags & SHF_TLS) == 0)
		    || (phdr->p_type == PT_TLS
			&& (shdr->sh_flags & SHF_TLS) != 0))
		&& phdr->p_offset <= shdr->sh_offset
		&& ((shdr->sh_offset - phdr->p_offset <= phdr->p_filesz
		     && (shdr->sh_offset - phdr->p_offset < phdr->p_filesz
			 || shdr->sh_size == 0))
		    || (shdr->sh_offset - phdr->p_offset < phdr->p_memsz
			&& shdr->sh_type == SHT_NOBITS)))
	      {
		/* Found the segment.  */
		if (phdr->p_offset + phdr->p_memsz
		    < shdr->sh_offset + shdr->sh_size)
		  ERROR (gettext ("\
section [%2zu] '%s' not fully contained in segment of program header entry %d\n"),
			 cnt, section_name (ebl, cnt), pcnt);

		if (shdr->sh_type == SHT_NOBITS)
		  {
		    if (shdr->sh_offset < phdr->p_offset + phdr->p_filesz
			&& !is_debuginfo)
		      ERROR (gettext ("\
section [%2zu] '%s' has type NOBITS but is read from the file in segment of program header entry %d\n"),
			 cnt, section_name (ebl, cnt), pcnt);
		  }
		else
		  {
		    const GElf_Off end = phdr->p_offset + phdr->p_filesz;
		    if (shdr->sh_offset > end ||
			(shdr->sh_offset == end && shdr->sh_size != 0))
		      ERROR (gettext ("\
section [%2zu] '%s' has not type NOBITS but is not read from the file in segment of program header entry %d\n"),
			 cnt, section_name (ebl, cnt), pcnt);
		  }

		if (shdr->sh_type != SHT_NOBITS)
		  {
		    if ((shdr->sh_flags & SHF_EXECINSTR) != 0)
		      {
			segment_flags[pcnt] |= PF_X;
			if ((phdr->p_flags & PF_X) == 0)
			  ERROR (gettext ("\
section [%2zu] '%s' is executable in nonexecutable segment %d\n"),
				 cnt, section_name (ebl, cnt), pcnt);
		      }

		    if ((shdr->sh_flags & SHF_WRITE) != 0)
		      {
			segment_flags[pcnt] |= PF_W;
			if (0	/* XXX vdso images have this */
			    && (phdr->p_flags & PF_W) == 0)
			  ERROR (gettext ("\
section [%2zu] '%s' is writable in unwritable segment %d\n"),
				 cnt, section_name (ebl, cnt), pcnt);
		      }
		  }

		break;
	      }

	  if (pcnt == phnum)
	    ERROR (gettext ("\
section [%2zu] '%s': alloc flag set but section not in any loaded segment\n"),
		   cnt, section_name (ebl, cnt));
	}

      if (cnt == shstrndx && shdr->sh_type != SHT_STRTAB)
	ERROR (gettext ("\
section [%2zu] '%s': ELF header says this is the section header string table but type is not SHT_TYPE\n"),
	       cnt, section_name (ebl, cnt));

      switch (shdr->sh_type)
	{
	case SHT_DYNSYM:
	  if (ehdr->e_type == ET_REL)
	    ERROR (gettext ("\
section [%2zu] '%s': relocatable files cannot have dynamic symbol tables\n"),
		   cnt, section_name (ebl, cnt));
	  /* FALLTHROUGH */
	case SHT_SYMTAB:
	  check_symtab (ebl, ehdr, shdr, cnt);
	  break;

	case SHT_RELA:
	  check_rela (ebl, ehdr, shdr, cnt);
	  break;

	case SHT_REL:
	  check_rel (ebl, ehdr, shdr, cnt);
	  break;

	case SHT_DYNAMIC:
	  check_dynamic (ebl, ehdr, shdr, cnt);
	  break;

	case SHT_SYMTAB_SHNDX:
	  check_symtab_shndx (ebl, ehdr, shdr, cnt);
	  break;

	case SHT_HASH:
	  check_hash (shdr->sh_type, ebl, ehdr, shdr, cnt);
	  hash_idx = cnt;
	  break;

	case SHT_GNU_HASH:
	  check_hash (shdr->sh_type, ebl, ehdr, shdr, cnt);
	  gnu_hash_idx = cnt;
	  break;

	case SHT_NULL:
	  check_null (ebl, shdr, cnt);
	  break;

	case SHT_GROUP:
	  check_group (ebl, ehdr, shdr, cnt);
	  break;

	case SHT_NOTE:
	  check_note_section (ebl, ehdr, shdr, cnt);
	  break;

	case SHT_GNU_versym:
	  /* We cannot process this section now since we have no guarantee
	     that the verneed and verdef sections have already been read.
	     Just remember the section index.  */
	  if (versym_scnndx != 0)
	    ERROR (gettext ("more than one version symbol table present\n"));
	  versym_scnndx = cnt;
	  break;

	case SHT_GNU_verneed:
	  check_verneed (ebl, shdr, cnt);
	  break;

	case SHT_GNU_verdef:
	  check_verdef (ebl, shdr, cnt);
	  break;

	case SHT_GNU_ATTRIBUTES:
	  check_attributes (ebl, ehdr, shdr, cnt);
	  break;

	default:
	  /* Nothing.  */
	  break;
	}
    }

  if (has_interp_segment && !dot_interp_section)
    ERROR (gettext ("INTERP program header entry but no .interp section\n"));

  if (!is_debuginfo)
    for (unsigned int pcnt = 0; pcnt < phnum; ++pcnt)
      {
	GElf_Phdr phdr_mem;
	GElf_Phdr *phdr = gelf_getphdr (ebl->elf, pcnt, &phdr_mem);
	if (phdr != NULL && (phdr->p_type == PT_LOAD || phdr->p_type == PT_TLS))
	  {
	    if ((phdr->p_flags & PF_X) != 0
		&& (segment_flags[pcnt] & PF_X) == 0)
	      ERROR (gettext ("\
loadable segment [%u] is executable but contains no executable sections\n"),
		     pcnt);

	    if ((phdr->p_flags & PF_W) != 0
		&& (segment_flags[pcnt] & PF_W) == 0)
	      ERROR (gettext ("\
loadable segment [%u] is writable but contains no writable sections\n"),
		     pcnt);
	  }
      }

  free (segment_flags);

  if (version_namelist != NULL)
    {
      if (versym_scnndx == 0)
    ERROR (gettext ("\
no .gnu.versym section present but .gnu.versym_d or .gnu.versym_r section exist\n"));
      else
	check_versym (ebl, versym_scnndx);

      /* Check for duplicate index numbers.  */
      do
	{
	  struct version_namelist *runp = version_namelist->next;
	  while (runp != NULL)
	    {
	      if (version_namelist->ndx == runp->ndx)
		{
		  ERROR (gettext ("duplicate version index %d\n"),
			 (int) version_namelist->ndx);
		  break;
		}
	      runp = runp->next;
	    }

	  struct version_namelist *old = version_namelist;
	  version_namelist = version_namelist->next;
	  free (old);
	}
      while (version_namelist != NULL);
    }
  else if (versym_scnndx != 0)
    ERROR (gettext ("\
.gnu.versym section present without .gnu.versym_d or .gnu.versym_r\n"));

  if (hash_idx != 0 && gnu_hash_idx != 0)
    compare_hash_gnu_hash (ebl, ehdr, hash_idx, gnu_hash_idx);

  free (scnref);
}


static GElf_Off
check_note_data (Ebl *ebl, const GElf_Ehdr *ehdr,
		 Elf_Data *data, int shndx, int phndx, GElf_Off start)
{
  size_t offset = 0;
  size_t last_offset = 0;
  GElf_Nhdr nhdr;
  size_t name_offset;
  size_t desc_offset;
  while (offset < data->d_size
	 && (offset = gelf_getnote (data, offset,
				    &nhdr, &name_offset, &desc_offset)) > 0)
    {
      last_offset = offset;

      /* Make sure it is one of the note types we know about.  */
      if (ehdr->e_type == ET_CORE)
	switch (nhdr.n_type)
	  {
	  case NT_PRSTATUS:
	  case NT_FPREGSET:
	  case NT_PRPSINFO:
	  case NT_TASKSTRUCT:		/* NT_PRXREG on Solaris.  */
	  case NT_PLATFORM:
	  case NT_AUXV:
	  case NT_GWINDOWS:
	  case NT_ASRS:
	  case NT_PSTATUS:
	  case NT_PSINFO:
	  case NT_PRCRED:
	  case NT_UTSNAME:
	  case NT_LWPSTATUS:
	  case NT_LWPSINFO:
	  case NT_PRFPXREG:
	    /* Known type.  */
	    break;

	  default:
	    if (shndx == 0)
	      ERROR (gettext ("\
phdr[%d]: unknown core file note type %" PRIu32 " at offset %" PRIu64 "\n"),
		     phndx, (uint32_t) nhdr.n_type, start + offset);
	    else
	      ERROR (gettext ("\
section [%2d] '%s': unknown core file note type %" PRIu32
			      " at offset %Zu\n"),
		     shndx, section_name (ebl, shndx),
		     (uint32_t) nhdr.n_type, offset);
	  }
      else
	switch (nhdr.n_type)
	  {
	  case NT_GNU_ABI_TAG:
	  case NT_GNU_HWCAP:
	  case NT_GNU_BUILD_ID:
	  case NT_GNU_GOLD_VERSION:
	    break;

	  case 0:
	    /* Linux vDSOs use a type 0 note for the kernel version word.  */
	    if (nhdr.n_namesz == sizeof "Linux"
		&& !memcmp (data->d_buf + name_offset, "Linux", sizeof "Linux"))
	      break;

	  default:
	    if (shndx == 0)
	      ERROR (gettext ("\
phdr[%d]: unknown object file note type %" PRIu32 " at offset %Zu\n"),
		     phndx, (uint32_t) nhdr.n_type, offset);
	    else
	      ERROR (gettext ("\
section [%2d] '%s': unknown object file note type %" PRIu32
			      " at offset %Zu\n"),
		     shndx, section_name (ebl, shndx),
		     (uint32_t) nhdr.n_type, offset);
	  }
    }

  return last_offset;
}


static void
check_note (Ebl *ebl, GElf_Ehdr *ehdr, GElf_Phdr *phdr, int cnt)
{
  if (ehdr->e_type != ET_CORE && ehdr->e_type != ET_REL
      && ehdr->e_type != ET_EXEC && ehdr->e_type != ET_DYN)
    ERROR (gettext ("\
phdr[%d]: no note entries defined for the type of file\n"),
	   cnt);

  if (is_debuginfo)
    /* The p_offset values in a separate debug file are bogus.  */
    return;

  if (phdr->p_filesz == 0)
    return;

  GElf_Off notes_size = 0;
  Elf_Data *data = elf_getdata_rawchunk (ebl->elf,
					 phdr->p_offset, phdr->p_filesz,
					 ELF_T_NHDR);
  if (data != NULL)
    notes_size = check_note_data (ebl, ehdr, data, 0, cnt, phdr->p_offset);

  if (notes_size == 0)
    ERROR (gettext ("phdr[%d]: cannot get content of note section: %s\n"),
	   cnt, elf_errmsg (-1));
  else if (notes_size != phdr->p_filesz)
    ERROR (gettext ("phdr[%d]: extra %" PRIu64 " bytes after last note\n"),
	   cnt, phdr->p_filesz - notes_size);
}


static void
check_note_section (Ebl *ebl, GElf_Ehdr *ehdr, GElf_Shdr *shdr, int idx)
{
  if (shdr->sh_size == 0)
    return;

  Elf_Data *data = elf_getdata (elf_getscn (ebl->elf, idx), NULL);
  if (data == NULL)
    {
      ERROR (gettext ("section [%2d] '%s': cannot get section data\n"),
	     idx, section_name (ebl, idx));
      return;
    }

  if (ehdr->e_type != ET_CORE && ehdr->e_type != ET_REL
      && ehdr->e_type != ET_EXEC && ehdr->e_type != ET_DYN)
    ERROR (gettext ("\
section [%2d] '%s': no note entries defined for the type of file\n"),
	     idx, section_name (ebl, idx));

  GElf_Off notes_size = check_note_data (ebl, ehdr, data, idx, 0, 0);

  if (notes_size == 0)
    ERROR (gettext ("section [%2d] '%s': cannot get content of note section\n"),
	   idx, section_name (ebl, idx));
  else if (notes_size != shdr->sh_size)
    ERROR (gettext ("section [%2d] '%s': extra %" PRIu64
		    " bytes after last note\n"),
	   idx, section_name (ebl, idx), shdr->sh_size - notes_size);
}


/* Index of the PT_GNU_EH_FRAME program eader entry.  */
static int pt_gnu_eh_frame_pndx;


static void
check_program_header (Ebl *ebl, GElf_Ehdr *ehdr)
{
  if (ehdr->e_phoff == 0)
    return;

  if (ehdr->e_type != ET_EXEC && ehdr->e_type != ET_DYN
      && ehdr->e_type != ET_CORE)
    ERROR (gettext ("\
only executables, shared objects, and core files can have program headers\n"));

  int num_pt_interp = 0;
  int num_pt_tls = 0;
  int num_pt_relro = 0;

  for (unsigned int cnt = 0; cnt < phnum; ++cnt)
    {
      GElf_Phdr phdr_mem;
      GElf_Phdr *phdr;

      phdr = gelf_getphdr (ebl->elf, cnt, &phdr_mem);
      if (phdr == NULL)
	{
	  ERROR (gettext ("cannot get program header entry %d: %s\n"),
		 cnt, elf_errmsg (-1));
	  continue;
	}

      if (phdr->p_type >= PT_NUM && phdr->p_type != PT_GNU_EH_FRAME
	  && phdr->p_type != PT_GNU_STACK && phdr->p_type != PT_GNU_RELRO
	  /* Check for a known machine-specific type.  */
	  && ebl_segment_type_name (ebl, phdr->p_type, NULL, 0) == NULL)
	ERROR (gettext ("\
program header entry %d: unknown program header entry type %#" PRIx64 "\n"),
	       cnt, (uint64_t) phdr->p_type);

      if (phdr->p_type == PT_LOAD)
	has_loadable_segment = true;
      else if (phdr->p_type == PT_INTERP)
	{
	  if (++num_pt_interp != 1)
	    {
	      if (num_pt_interp == 2)
		ERROR (gettext ("\
more than one INTERP entry in program header\n"));
	    }
	  has_interp_segment = true;
	}
      else if (phdr->p_type == PT_TLS)
	{
	  if (++num_pt_tls == 2)
	    ERROR (gettext ("more than one TLS entry in program header\n"));
	}
      else if (phdr->p_type == PT_NOTE)
	check_note (ebl, ehdr, phdr, cnt);
      else if (phdr->p_type == PT_DYNAMIC)
	{
	  if (ehdr->e_type == ET_EXEC && ! has_interp_segment)
	    ERROR (gettext ("\
static executable cannot have dynamic sections\n"));
	  else
	    {
	      /* Check that the .dynamic section, if it exists, has
		 the same address.  */
	      Elf_Scn *scn = NULL;
	      while ((scn = elf_nextscn (ebl->elf, scn)) != NULL)
		{
		  GElf_Shdr shdr_mem;
		  GElf_Shdr *shdr = gelf_getshdr (scn, &shdr_mem);
		  if (shdr != NULL && shdr->sh_type == SHT_DYNAMIC)
		    {
		      if (phdr->p_offset != shdr->sh_offset)
			ERROR (gettext ("\
dynamic section reference in program header has wrong offset\n"));
		      if (phdr->p_memsz != shdr->sh_size)
			ERROR (gettext ("\
dynamic section size mismatch in program and section header\n"));
		      break;
		    }
		}
	    }
	}
      else if (phdr->p_type == PT_GNU_RELRO)
	{
	  if (++num_pt_relro == 2)
	    ERROR (gettext ("\
more than one GNU_RELRO entry in program header\n"));
	  else
	    {
	      /* Check that the region is in a writable segment.  */
	      unsigned int inner;
	      for (inner = 0; inner < phnum; ++inner)
		{
		  GElf_Phdr phdr2_mem;
		  GElf_Phdr *phdr2;

		  phdr2 = gelf_getphdr (ebl->elf, inner, &phdr2_mem);
		  if (phdr2 == NULL)
		    continue;

		  if (phdr2->p_type == PT_LOAD
		      && phdr->p_vaddr >= phdr2->p_vaddr
		      && (phdr->p_vaddr + phdr->p_memsz
			  <= phdr2->p_vaddr + phdr2->p_memsz))
		    {
		      if ((phdr2->p_flags & PF_W) == 0)
			ERROR (gettext ("\
loadable segment GNU_RELRO applies to is not writable\n"));
		      if ((phdr2->p_flags & ~PF_W) != (phdr->p_flags & ~PF_W))
			ERROR (gettext ("\
loadable segment [%u] flags do not match GNU_RELRO [%u] flags\n"),
			       cnt, inner);
		      break;
		    }
		}

	      if (inner >= phnum)
		ERROR (gettext ("\
%s segment not contained in a loaded segment\n"), "GNU_RELRO");
	    }
	}
      else if (phdr->p_type == PT_PHDR)
	{
	  /* Check that the region is in a writable segment.  */
	  unsigned int inner;
	  for (inner = 0; inner < phnum; ++inner)
	    {
	      GElf_Phdr phdr2_mem;
	      GElf_Phdr *phdr2;

	      phdr2 = gelf_getphdr (ebl->elf, inner, &phdr2_mem);
	      if (phdr2 != NULL
		  && phdr2->p_type == PT_LOAD
		  && phdr->p_vaddr >= phdr2->p_vaddr
		  && (phdr->p_vaddr + phdr->p_memsz
		      <= phdr2->p_vaddr + phdr2->p_memsz))
		break;
	    }

	  if (inner >= phnum)
	    ERROR (gettext ("\
%s segment not contained in a loaded segment\n"), "PHDR");

	  /* Check that offset in segment corresponds to offset in ELF
	     header.  */
	  if (phdr->p_offset != ehdr->e_phoff)
	    ERROR (gettext ("\
program header offset in ELF header and PHDR entry do not match"));
	}
      else if (phdr->p_type == PT_GNU_EH_FRAME)
	{
	  /* If there is an .eh_frame_hdr section it must be
	     referenced by this program header entry.  */
	  Elf_Scn *scn = NULL;
	  GElf_Shdr shdr_mem;
	  GElf_Shdr *shdr = NULL;
	  bool any = false;
	  while ((scn = elf_nextscn (ebl->elf, scn)) != NULL)
	    {
	      any = true;
	      shdr = gelf_getshdr (scn, &shdr_mem);
	      if (shdr != NULL
		  && shdr->sh_type == (is_debuginfo
				       ? SHT_NOBITS : SHT_PROGBITS)
		  && ! strcmp (".eh_frame_hdr",
			       elf_strptr (ebl->elf, shstrndx, shdr->sh_name)))
		{
		  if (! is_debuginfo)
		    {
		      if (phdr->p_offset != shdr->sh_offset)
			ERROR (gettext ("\
call frame search table reference in program header has wrong offset\n"));
		      if (phdr->p_memsz != shdr->sh_size)
			ERROR (gettext ("\
call frame search table size mismatch in program and section header\n"));
		    }
		  break;
		}
	    }

	  if (scn == NULL)
	    {
	      /* If there is no section header table we don't
		 complain.  But if there is one there should be an
		 entry for .eh_frame_hdr.  */
	      if (any)
		ERROR (gettext ("\
PT_GNU_EH_FRAME present but no .eh_frame_hdr section\n"));
	    }
	  else
	    {
	      /* The section must be allocated and not be writable and
		 executable.  */
	      if ((phdr->p_flags & PF_R) == 0)
		ERROR (gettext ("\
call frame search table must be allocated\n"));
	      else if (shdr != NULL && (shdr->sh_flags & SHF_ALLOC) == 0)
		ERROR (gettext ("\
section [%2zu] '%s' must be allocated\n"), elf_ndxscn (scn), ".eh_frame_hdr");

	      if ((phdr->p_flags & PF_W) != 0)
		ERROR (gettext ("\
call frame search table must not be writable\n"));
	      else if (shdr != NULL && (shdr->sh_flags & SHF_WRITE) != 0)
		ERROR (gettext ("\
section [%2zu] '%s' must not be writable\n"),
		       elf_ndxscn (scn), ".eh_frame_hdr");

	      if ((phdr->p_flags & PF_X) != 0)
		ERROR (gettext ("\
call frame search table must not be executable\n"));
	      else if (shdr != NULL && (shdr->sh_flags & SHF_EXECINSTR) != 0)
		ERROR (gettext ("\
section [%2zu] '%s' must not be executable\n"),
		       elf_ndxscn (scn), ".eh_frame_hdr");
	    }

	  /* Remember which entry this is.  */
	  pt_gnu_eh_frame_pndx = cnt;
	}

      if (phdr->p_filesz > phdr->p_memsz
	  && (phdr->p_memsz != 0 || phdr->p_type != PT_NOTE))
	ERROR (gettext ("\
program header entry %d: file size greater than memory size\n"),
	       cnt);

      if (phdr->p_align > 1)
	{
	  if (!powerof2 (phdr->p_align))
	    ERROR (gettext ("\
program header entry %d: alignment not a power of 2\n"), cnt);
	  else if ((phdr->p_vaddr - phdr->p_offset) % phdr->p_align != 0)
	    ERROR (gettext ("\
program header entry %d: file offset and virtual address not module of alignment\n"), cnt);
	}
    }
}


static void
check_exception_data (Ebl *ebl __attribute__ ((unused)),
		      GElf_Ehdr *ehdr __attribute__ ((unused)))
{
  if ((ehdr->e_type == ET_EXEC || ehdr->e_type == ET_DYN)
      && pt_gnu_eh_frame_pndx == 0 && eh_frame_hdr_scnndx != 0)
    ERROR (gettext ("executable/DSO with .eh_frame_hdr section does not have "
		    "a PT_GNU_EH_FRAME program header entry"));
}


/* Process one file.  */
static void
process_elf_file (Elf *elf, const char *prefix, const char *suffix,
		  const char *fname, size_t size, bool only_one)
{
  /* Reset variables.  */
  ndynamic = 0;
  nverneed = 0;
  nverdef = 0;
  textrel = false;
  needed_textrel = false;
  has_loadable_segment = false;
  has_interp_segment = false;

  GElf_Ehdr ehdr_mem;
  GElf_Ehdr *ehdr = gelf_getehdr (elf, &ehdr_mem);
  Ebl *ebl;

  /* Print the file name.  */
  if (!only_one)
    {
      if (prefix != NULL)
	printf ("\n%s(%s)%s:\n", prefix, fname, suffix);
      else
	printf ("\n%s:\n", fname);
    }

  if (ehdr == NULL)
    {
      ERROR (gettext ("cannot read ELF header: %s\n"), elf_errmsg (-1));
      return;
    }

  ebl = ebl_openbackend (elf);
  /* If there is no appropriate backend library we cannot test
     architecture and OS specific features.  Any encountered extension
     is an error.  */

  /* Go straight by the gABI, check all the parts in turn.  */
  check_elf_header (ebl, ehdr, size);

  /* Check the program header.  */
  check_program_header (ebl, ehdr);

  /* Next the section headers.  It is OK if there are no section
     headers at all.  */
  check_sections (ebl, ehdr);

  /* Check the exception handling data, if it exists.  */
  if (pt_gnu_eh_frame_pndx != 0 || eh_frame_hdr_scnndx != 0
      || eh_frame_scnndx != 0 || gcc_except_table_scnndx != 0)
    check_exception_data (ebl, ehdr);

  /* Report if no relocation section needed the text relocation flag.  */
  if (textrel && !needed_textrel)
    ERROR (gettext ("text relocation flag set but not needed\n"));

  /* Free the resources.  */
  ebl_closebackend (ebl);
}


#include "debugpred.h"
