/* Pedantic checking of ELF files compliance with gABI/psABI spec.
   Copyright (C) 2001, 2002, 2003, 2004 Red Hat, Inc.
   Written by Ulrich Drepper <drepper@redhat.com>, 2001.

   This program is Open Source software; you can redistribute it and/or
   modify it under the terms of the Open Software License version 1.0 as
   published by the Open Source Initiative.

   You should have received a copy of the Open Software License along
   with this program; if not, you may obtain a copy of the Open Software
   License version 1.0 from http://www.opensource.org/licenses/osl.php or
   by writing the Open Source Initiative c/o Lawrence Rosen, Esq.,
   3001 King Ranch Road, Ukiah, CA 95482.   */

#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 <libebl.h>
#include <libintl.h>
#include <locale.h>
#include <stdbool.h>
#include <stdlib.h>
#include <string.h>
#include <unistd.h>
#include <sys/param.h>

#include <elf-knowledge.h>
#include <system.h>


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


#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.") },
  { "quiet", 'q', NULL, 0, N_("Do not print anything if successful") },
  { "gnu-ld", ARGP_gnuld, NULL, 0,
    N_("Binary has been created with GNU ld and is therefore known to be \
broken in certain ways") },
  { NULL, 0, NULL, 0, NULL }
};

/* 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);

/* Function to print some extra text in the help message.  */
static char *more_help (int key, const char *text, void *input);

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


/* 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);

/* Report an error.  */
#define ERROR(str, args...) \
  do {									      \
    printf (str, ##args);						      \
    ++error_count;							      \
  } while (0)
static 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 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;


int
main (int argc, char *argv[])
{
  int remaining;
  bool only_one;

  /* Set locale.  */
  setlocale (LC_ALL, "");

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

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

  /* If no ELF file is given punt.  */
  if (remaining >= argc)
    {
      argp_help (&argp, stdout, ARGP_HELP_SEE | ARGP_HELP_EXIT_ERR,
		 program_invocation_short_name);
      exit (1);
    }

  /* 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.  */
  only_one = remaining + 1 == argc;
  do
    {
      int fd;
      Elf *elf;

      /* Open the file.  */
      fd = open (argv[remaining], O_RDONLY);
      if (fd == -1)
	{
	  error (0, errno, gettext ("cannot open input file"));
	  continue;
	}

      /* Create an `Elf' descriptor.  */
      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, struct argp_state *state)
{
  switch (key)
    {
    case ARGP_strict:
      be_strict = true;
      break;

    case 'q':
      be_quiet = true;
      break;

    case ARGP_gnuld:
      gnuld = true;
      break;

    default:
      return ARGP_ERR_UNKNOWN;
    }
  return 0;
}


static char *
more_help (int key, const char *text, void *input)
{
  char *buf;

  switch (key)
    {
    case ARGP_KEY_HELP_EXTRA:
      /* We print some extra information.  */
      if (asprintf (&buf, gettext ("Please report bugs to %s.\n"),
		    PACKAGE_BUGREPORT) < 0)
	buf = NULL;
      return buf;

    default:
      break;
    }
  return (char *) text;
}


/* Print the version information.  */
static void
print_version (FILE *stream, struct argp_state *state)
{
  fprintf (stream, "elflint (%s) %s\n", PACKAGE_NAME, 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\
"), "2004");
  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"));
      break;
    }
}


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

  shdr = gelf_getshdr (elf_getscn (ebl->elf, idx), &shdr_mem);

  return elf_strptr (ebl->elf, shstrndx, shdr->sh_name);
}


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
  };
#define nvalid_e_machine \
  (sizeof (valid_e_machine) / sizeof (valid_e_machine[0]))


/* Number of sections.  */
static unsigned int shnum;


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.  */
  if (ehdr->e_ident[EI_OSABI] != ELFOSABI_NONE)
    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;

	  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;

	  shdr = gelf_getshdr (elf_getscn (ebl->elf, 0), &shdr_mem);
	  if (shdr != NULL)
	    {
	      /* The error will be reported later.  */
	      if (shdr->sh_link >= shnum)
		ERROR (gettext ("invalid section header index\n"));
	      else
		shstrndx = shdr->sh_link;
	    }
	}
      else if (shstrndx >= shnum)
	ERROR (gettext ("invalid section header index\n"));
    }

  /* 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 + ehdr->e_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 + ehdr->e_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 + ehdr->e_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, GElf_Ehdr *ehdr, 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;
	  GElf_Shdr shdr_mem;
	  GElf_Shdr *shdr;
	  Elf_Data *data;
	  Elf32_Word *grpdata;
	  size_t inner;

	  scn = elf_getscn (ebl->elf, cnt);
	  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;

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

	  grpdata = (Elf32_Word *) data->d_buf;
	  for (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, ehdr, idx));
      else
	ERROR (gettext ("\
section [%2d] '%s': section group [%2zu] '%s' does not preceed group member\n"),
	       idx, section_name (ebl, ehdr, idx),
	       cnt, section_name (ebl, ehdr, cnt));
    }
}


static void
check_symtab (Ebl *ebl, GElf_Ehdr *ehdr, int idx)
{
  bool no_xndx_warned = false;
  int no_pt_tls = 0;

  Elf_Scn *scn = elf_getscn (ebl->elf, idx);
  GElf_Shdr shdr_mem;
  GElf_Shdr *shdr = gelf_getshdr (scn, &shdr_mem);
  GElf_Shdr strshdr_mem;
  GElf_Shdr *strshdr = gelf_getshdr (elf_getscn (ebl->elf, shdr->sh_link),
				     &strshdr_mem);
  if (shdr == NULL || strshdr == NULL)
    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, ehdr, idx));
      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, ehdr, shdr->sh_link),
	   idx, section_name (ebl, ehdr, idx));

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

	if (xndxshdr == NULL || xndxdata == NULL)
	  continue;

	if (xndxshdr->sh_type == SHT_SYMTAB_SHNDX
	    && xndxshdr->sh_link == (GElf_Word) idx)
	  break;
      }
  if (cnt == shnum)
    {
      xndxshdr = NULL;
      xndxdata = NULL;
    }

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

  /* 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, ehdr, 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, ehdr, idx), "st_name");
      if (sym->st_value != 0)
	ERROR (gettext ("section [%2d] '%s': '%s' in zeroth entry not zero\n"),
	       idx, section_name (ebl, ehdr, idx), "st_value");
      if (sym->st_size != 0)
	ERROR (gettext ("section [%2d] '%s': '%s' in zeroth entry not zero\n"),
	       idx, section_name (ebl, ehdr, idx), "st_size");
      if (sym->st_info != 0)
	ERROR (gettext ("section [%2d] '%s': '%s' in zeroth entry not zero\n"),
	       idx, section_name (ebl, ehdr, idx), "st_info");
      if (sym->st_other != 0)
	ERROR (gettext ("section [%2d] '%s': '%s' in zeroth entry not zero\n"),
	       idx, section_name (ebl, ehdr, idx), "st_other");
      if (sym->st_shndx != 0)
	ERROR (gettext ("section [%2d] '%s': '%s' in zeroth entry not zero\n"),
	       idx, section_name (ebl, ehdr, idx), "st_shndx");
      if (xndxdata != NULL && xndx != 0)
	ERROR (gettext ("\
section [%2d] '%s': XINDEX for zeroth entry not zero\n"),
	       xndxscnidx, section_name (ebl, ehdr, xndxscnidx));
    }

  for (cnt = 1; cnt < shdr->sh_size / shdr->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, ehdr, idx), cnt, elf_errmsg (-1));
	  continue;
	}

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

      if (sym->st_shndx == SHN_XINDEX)
	{
	  if (xndxdata == NULL)
	    {
	      ERROR (gettext ("\
section [%2d] '%s': symbol %zu: too large section index but no extended section index section\n"),
		     idx, section_name (ebl, ehdr, 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, ehdr, 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, ehdr, idx), cnt);
      else
	xndx = sym->st_shndx;

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

      if (GELF_ST_BIND (sym->st_info) >= STB_NUM)
	ERROR (gettext ("\
section [%2d] '%s': symbol %zu: unknown symbol binding\n"),
	       idx, section_name (ebl, ehdr, 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, ehdr, idx), cnt);
	  if (cnt < shdr->sh_info)
	    ERROR (gettext ("\
section [%2d] '%s': symbol %zu: local COMMON symbols are nonsense\n"),
		   idx, section_name (ebl, ehdr, 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, ehdr, 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)
	    {
	      if (GELF_ST_TYPE (sym->st_info) != STT_TLS)
		{
		  if ((sym->st_value - destshdr->sh_addr) > destshdr->sh_size)
		    ERROR (gettext ("\
section [%2d] '%s': symbol %zu: st_value out of bounds\n"),
			   idx, section_name (ebl, ehdr, idx), cnt);
		  else if ((sym->st_value - destshdr->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, ehdr, idx), cnt,
			   (int) xndx, section_name (ebl, ehdr, 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, ehdr, idx), cnt,
			   (int) xndx, section_name (ebl, ehdr, xndx));

		  if (ehdr->e_type == ET_REL)
		    {
		      /* For object files the symbol value must fall
                         into the section.  */
		      if (sym->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, ehdr, idx), cnt,
			       (int) xndx, section_name (ebl, ehdr, xndx));
		      else if (sym->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, ehdr, idx), cnt,
			       (int) xndx, section_name (ebl, ehdr, xndx));
		    }
		  else
		    {
		      GElf_Phdr phdr_mem;
		      GElf_Phdr *phdr = NULL;
		      int pcnt;

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

		      if (pcnt == ehdr->e_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, ehdr, idx), cnt);
			}
		      else
			{
			  if (sym->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, ehdr, idx), cnt,
				   (int) xndx, section_name (ebl, ehdr, xndx));
			  else if (sym->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, ehdr, idx), cnt,
				   (int) xndx, section_name (ebl, ehdr, xndx));
			  else if (sym->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, ehdr, idx), cnt,
				   (int) xndx, section_name (ebl, ehdr, 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, ehdr, 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, ehdr, 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, ehdr, idx), cnt);

      if (name != NULL)
	{
	  if (strcmp (name, "_GLOBAL_OFFSET_TABLE_") == 0)
	    {
	      /* Check that address and size match the global offset
		 table.  We have to locate the GOT by searching for a
		 section named ".got".  */
	      Elf_Scn *gscn = NULL;

	      while ((gscn = elf_nextscn (ebl->elf, gscn)) != NULL)
		{
		  GElf_Shdr gshdr_mem;
		  GElf_Shdr *gshdr = gelf_getshdr (gscn, &gshdr_mem);
		  assert (gshdr != NULL);

		  const char *sname = elf_strptr (ebl->elf, ehdr->e_shstrndx,
						  gshdr->sh_name);
		  if (sname != NULL && strcmp (sname, ".got") == 0)
		    {
		      /* Found it.  */
		      if (sym->st_value != gshdr->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 .got section address %#" PRIx64 "\n"),
			       idx, section_name (ebl, ehdr, idx),
			       (uint64_t) sym->st_value,
			       (uint64_t) gshdr->sh_addr);

		      if (sym->st_size != gshdr->sh_size)
			ERROR (gettext ("\
section [%2d] '%s': _GLOBAL_OFFSET_TABLE_ symbol size %" PRIu64 " does not match .got section size %" PRIu64 "\n"),
			       idx, section_name (ebl, ehdr, idx),
			       (uint64_t) sym->st_size,
			       (uint64_t) gshdr->sh_size);

		      break;
		    }
		}

	      if (gscn == NULL)
		ERROR (gettext ("\
section [%2d] '%s': _GLOBAL_OFFSET_TABLE_ symbol present, but no .got section\n"),
		       idx, section_name (ebl, ehdr, 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.  */
	      int pcnt;

	      for (pcnt = 0; pcnt < ehdr->e_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, ehdr, idx),
			       (uint64_t) sym->st_value,
			       (uint64_t) phdr->p_vaddr);

		      if (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, ehdr, idx),
			       (uint64_t) sym->st_size,
			       (uint64_t) phdr->p_memsz);

		      break;
		    }
		}
	    }
	}
    }
}


static bool
is_rel_dyn (Ebl *ebl, GElf_Ehdr *ehdr, int idx, GElf_Shdr *shdr, bool 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, ehdr, idx), 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);
      assert (rcshdr != NULL);

      if (rcshdr->sh_type == SHT_DYNAMIC)
	{
	  /* Found the dynamic section.  Look through it.  */
	  Elf_Data *d = elf_getdata (scn, NULL);
	  int 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);
	      assert (dyn != NULL);

	      if (dyn->d_tag == DT_RELCOUNT)
		{
		  /* Found it.  One last check: 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, ehdr, idx),
			   (int) dyn->d_un.d_val);
		}
	    }

	  break;
	}
    }

  return true;
}


static void
check_rela (Ebl *ebl, GElf_Ehdr *ehdr, int idx)
{
  Elf_Scn *scn;
  GElf_Shdr shdr_mem;
  GElf_Shdr *shdr;
  Elf_Data *data;
  GElf_Shdr destshdr_mem;
  GElf_Shdr *destshdr = NULL;
  size_t cnt;
  bool reldyn = false;
  bool known_broken = gnuld;

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

  /* 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, ehdr, idx));
  else
    {
      destshdr = gelf_getshdr (elf_getscn (ebl->elf, shdr->sh_info),
			       &destshdr_mem);
      if (destshdr != NULL)
	{
	  if(destshdr->sh_type != SHT_PROGBITS
	     && destshdr->sh_type != SHT_NOBITS)
	    {
	      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, ehdr, idx));
	      else
		{
		  /* There is no standard, but we require that .rela.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, ehdr, idx));
		}
	    }

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

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

  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);

  for (cnt = 0; cnt < shdr->sh_size / shdr->sh_entsize; ++cnt)
    {
      GElf_Rela rela_mem;
      GElf_Rela *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, ehdr, idx), cnt, elf_errmsg (-1));
	  continue;
	}

      if (!ebl_reloc_type_check (ebl, GELF_R_TYPE (rela->r_info)))
	ERROR (gettext ("section [%2d] '%s': relocation %zu: invalid type\n"),
	       idx, section_name (ebl, ehdr, idx), cnt);
      else if (!ebl_reloc_valid_use (ebl, GELF_R_TYPE (rela->r_info)))
	ERROR (gettext ("\
section [%2d] '%s': relocation %zu: relocation type invalid for the file type\n"),
	       idx, section_name (ebl, ehdr, idx), cnt);

      if (symshdr != NULL
	  && ((GELF_R_SYM (rela->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, ehdr, idx), cnt);

      if (ebl_gotpc_reloc_check (ebl, GELF_R_TYPE (rela->r_info)))
	{
	  const char *name;
	  char buf[64];
	  GElf_Sym sym_mem;
	  GElf_Sym *sym = gelf_getsym (symdata, GELF_R_SYM (rela->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, ehdr, idx), cnt,
		   ebl_reloc_type_name (ebl, GELF_R_SYM (rela->r_info),
					buf, sizeof (buf)));
	}

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


static void
check_rel (Ebl *ebl, GElf_Ehdr *ehdr, int idx)
{
  Elf_Scn *scn;
  GElf_Shdr shdr_mem;
  GElf_Shdr *shdr;
  Elf_Data *data;
  GElf_Shdr destshdr_mem;
  GElf_Shdr *destshdr = NULL;
  size_t cnt;
  bool reldyn = false;
  bool known_broken = gnuld;

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

  /* 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, ehdr, idx));
  else
    {
      destshdr = gelf_getshdr (elf_getscn (ebl->elf, shdr->sh_info),
			       &destshdr_mem);
      if (destshdr != NULL)
	{
	  if (destshdr->sh_type != SHT_PROGBITS
	      && destshdr->sh_type != SHT_NOBITS)
	    {
	      reldyn = is_rel_dyn (ebl, ehdr, idx, shdr, false);
	      if (!reldyn)
		ERROR (gettext ("\
section [%2d] '%s': invalid destination section type\n"),
		       idx, section_name (ebl, ehdr, idx));
	      else
		{
		  /* There is no standard, but we require that .rela.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, ehdr, idx));
		}
	    }

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

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

  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);

  for (cnt = 0; cnt < shdr->sh_size / shdr->sh_entsize; ++cnt)
    {
      GElf_Rel rel_mem;
      GElf_Rel *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, ehdr, idx), cnt, elf_errmsg (-1));
	  continue;
	}

      if (!ebl_reloc_type_check (ebl, GELF_R_TYPE (rel->r_info)))
	ERROR (gettext ("section [%2d] '%s': relocation %zu: invalid type\n"),
	       idx, section_name (ebl, ehdr, idx), cnt);
      else if (!ebl_reloc_valid_use (ebl, GELF_R_TYPE (rel->r_info)))
	ERROR (gettext ("\
section [%2d] '%s': relocation %zu: relocation type invalid for the file type\n"),
	       idx, section_name (ebl, ehdr, idx), cnt);

      if (symshdr != NULL
	  && ((GELF_R_SYM (rel->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, ehdr, idx), cnt);

      if (ebl_gotpc_reloc_check (ebl, GELF_R_TYPE (rel->r_info)))
	{
	  const char *name;
	  char buf[64];
	  GElf_Sym sym_mem;
	  GElf_Sym *sym = gelf_getsym (symdata, GELF_R_SYM (rel->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, ehdr, idx), cnt,
		   ebl_reloc_type_name (ebl, GELF_R_SYM (rel->r_info),
					buf, sizeof (buf)));
	}

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


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


static void
check_dynamic (Ebl *ebl, GElf_Ehdr *ehdr, int idx)
{
  Elf_Scn *scn;
  GElf_Shdr shdr_mem;
  GElf_Shdr *shdr;
  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_HASH] = 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 },
      [DT_PLTRELSZ] = { [DT_JMPREL] = true }
    };
  bool has_dt[DT_NUM];
  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_HASH] = true,
      [DT_STRTAB] = true,
      [DT_SYMTAB] = true,
      [DT_STRSZ] = true,
      [DT_SYMENT] = true
    };
  GElf_Addr reladdr = 0;
  GElf_Word relsz = 0;
  GElf_Addr pltreladdr = 0;
  GElf_Word pltrelsz = 0;

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

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

  scn = elf_getscn (ebl->elf, idx);
  shdr = gelf_getshdr (scn, &shdr_mem);
  if (shdr == NULL)
    return;
  data = elf_getdata (scn, NULL);
  if (data == NULL)
    {
      ERROR (gettext ("section [%2d] '%s': cannot get section data\n"),
	     idx, section_name (ebl, ehdr, 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, ehdr, shdr->sh_link),
	   idx, section_name (ebl, ehdr, idx));

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

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

  bool non_null_warned = false;
  for (cnt = 0; cnt < shdr->sh_size / shdr->sh_entsize; ++cnt)
    {
      GElf_Dyn dyn_mem;
      GElf_Dyn *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, ehdr, 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, ehdr, 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, ehdr, idx), cnt);

      if (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, ehdr, 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, ehdr, idx), cnt,
		     ebl_dynamic_tag_name (ebl, dyn->d_tag,
					   buf, sizeof (buf)));
	    }

	  has_dt[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, ehdr, idx), cnt);

      if (dyn->d_tag == DT_REL)
	reladdr = dyn->d_un.d_ptr;
      if (dyn->d_tag == DT_RELSZ)
	relsz = dyn->d_un.d_val;
      if (dyn->d_tag == DT_JMPREL)
	pltreladdr = dyn->d_un.d_ptr;
      if (dyn->d_tag == DT_PLTRELSZ)
	pltrelsz = dyn->d_un.d_val;
    }

  for (cnt = 1; cnt < DT_NUM; ++cnt)
    if (has_dt[cnt])
      {
	int inner;

	for (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, ehdr, 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, ehdr, idx),
		   ebl_dynamic_tag_name (ebl, cnt, buf, sizeof (buf)));
	  }
      }

  /* 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, ehdr, 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, ehdr, idx),
	   "DT_REL", "DT_RELSZ", "DT_RELENT");
}


static void
check_symtab_shndx (Ebl *ebl, GElf_Ehdr *ehdr, int idx)
{
  Elf_Scn *scn;
  GElf_Shdr shdr_mem;
  GElf_Shdr *shdr;
  GElf_Shdr symshdr_mem;
  GElf_Shdr *symshdr;
  Elf_Scn *symscn;
  size_t cnt;
  Elf_Data *data;
  Elf_Data *symdata;

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

  symscn = elf_getscn (ebl->elf, shdr->sh_link);
  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, ehdr, idx));
  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, ehdr, idx));

  if (symshdr != NULL
      && (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, ehdr, idx));

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

  for (cnt = idx + 1; cnt < shnum; ++cnt)
    {
      GElf_Shdr rshdr_mem;
      GElf_Shdr *rshdr;

      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, ehdr, idx),
		 cnt, section_name (ebl, ehdr, cnt));
	  break;
	}
    }

  data = elf_getdata (scn, NULL);

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

  for (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_hash (Ebl *ebl, GElf_Ehdr *ehdr, int idx)
{
  Elf_Scn *scn;
  GElf_Shdr shdr_mem;
  GElf_Shdr *shdr;
  Elf_Data *data;
  Elf32_Word nbucket;
  Elf32_Word nchain;
  GElf_Shdr symshdr_mem;
  GElf_Shdr *symshdr;

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

  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, ehdr, idx));

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

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

  if (shdr->sh_size < 2 * shdr->sh_entsize)
    {
      ERROR (gettext ("\
section [%2d] '%s': hash table has not even room for nbucket and nchain\n"),
	     idx, section_name (ebl, ehdr, idx));
      return;
    }

  nbucket = ((Elf32_Word *) data->d_buf)[0];
  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, ehdr, idx), (long int) shdr->sh_size,
	   (long int) ((2 + nbucket + nchain) * shdr->sh_entsize));

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

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

      for (cnt = 2; cnt < 2 + nbucket; ++cnt)
	if (((Elf32_Word *) data->d_buf)[cnt] >= symsize)
	  ERROR (gettext ("\
section [%2d] '%s': hash bucket reference %zu out of bounds\n"),
		 idx, section_name (ebl, ehdr, idx), cnt - 2);

      for (; cnt < 2 + nbucket + nchain; ++cnt)
	if (((Elf32_Word *) data->d_buf)[cnt] >= symsize)
	  ERROR (gettext ("\
section [%2d] '%s': hash chain reference %zu out of bounds\n"),
		 idx, section_name (ebl, ehdr, idx), cnt - 2 - nbucket);
    }
}


static void
check_null (Ebl *ebl, GElf_Ehdr *ehdr, 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, ehdr, 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, ehdr, idx));
      return;
    }

  /* Check that sh_link is an index of a symbol table.  */
  GElf_Shdr symshdr_mem;
  GElf_Shdr *symshdr = gelf_getshdr (elf_getscn (ebl->elf, shdr->sh_link),
				     &symshdr_mem);
  if (symshdr == NULL)
    ERROR (gettext ("section [%2d] '%s': cannot get symbol table: %s\n"),
	   idx, section_name (ebl, ehdr, 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, ehdr, 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, ehdr, idx));

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

      if (data->d_size < elsize)
	ERROR (gettext ("\
section [%2d] '%s': section group without flags word\n"),
	       idx, section_name (ebl, ehdr, 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, ehdr, idx));
	  else if (data->d_size < 3 * elsize)
	    ERROR (gettext ("\
section [%2d] '%s': section group with only one member\n"),
		   idx, section_name (ebl, ehdr, 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, ehdr, 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, ehdr, idx), cnt / elsize);
	  else
	    {
	      GElf_Shdr refshdr_mem;
	      GElf_Shdr *refshdr;

	      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, ehdr, 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, ehdr, idx),
			   val, section_name (ebl, ehdr, 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, ehdr, idx), cnt / elsize,
			   val, section_name (ebl, ehdr, val));
		}

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


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 } 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, exact, 0, 0 },
    { ".data", 6, SHT_PROGBITS, exact, SHF_ALLOC | SHF_WRITE, 0 },
    { ".data1", 7, SHT_PROGBITS, exact, SHF_ALLOC | SHF_WRITE, 0 },
    { ".debug", 7, 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, exact, 0, 0 },
    { ".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 }, // XXX more tests
    { ".rel", 4, SHT_REL, atleast, 0, SHF_ALLOC }, // XXX more tests
    { ".rodata", 8, SHT_PROGBITS, exact, SHF_ALLOC, 0 },
    { ".rodata1", 9, SHT_PROGBITS, exact, SHF_ALLOC, 0 },
    { ".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 }
  };
#define nspecial_sections \
  (sizeof (special_sections) / sizeof (special_sections[0]))


static const char *
section_flags_string (GElf_Word flags, char *buf, size_t len)
{
  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;
  size_t cnt;

  for (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 void
check_versym (Ebl *ebl, GElf_Ehdr *ehdr, GElf_Shdr *shdr, int idx)
{
  /* The number of elements in the version symbol table must be the
     same as the number of symbols.  */
  GElf_Shdr symshdr_mem;
  GElf_Shdr *symshdr = gelf_getshdr (elf_getscn (ebl->elf, shdr->sh_link),
				     &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, ehdr, idx),
	     shdr->sh_link, section_name (ebl, ehdr, shdr->sh_link));
      return;
    }

  if (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, ehdr, idx),
	   shdr->sh_link, section_name (ebl, ehdr, shdr->sh_link));

  // XXX TODO A lot more tests
  // check value of the fields.  local symbols must have zero entries.
  // nonlocal symbols refer to valid version.  Check that version index
  // in bound.
}


static void
check_sections (Ebl *ebl, GElf_Ehdr *ehdr)
{
  GElf_Shdr shdr_mem;
  GElf_Shdr *shdr;
  size_t cnt;
  bool dot_interp_section = false;

  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.  */
  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_info != 0)
	ERROR (gettext ("zeroth section has nonzero info field\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"));
    }

  for (cnt = 1; cnt < shnum; ++cnt)
    {
      Elf_Scn *scn;

      scn = elf_getscn (ebl->elf, cnt);
      shdr = gelf_getshdr (scn, &shdr_mem);
      if (shdr == NULL)
	{
	  ERROR (gettext ("\
cannot get section header for section [%2zu] '%s': %s\n"),
		 cnt, section_name (ebl, ehdr, 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];

		if (shdr->sh_type != special_sections[s].type)
		  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)
		  {
		    /* 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)
		      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;
	      }
	}

      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, ehdr, 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_LIBLIST
	  && shdr->sh_type != SHT_CHECKSUM
	  && shdr->sh_type != SHT_GNU_verdef
	  && shdr->sh_type != SHT_GNU_verneed
	  && shdr->sh_type != SHT_GNU_versym)
	ERROR (gettext ("unsupported section type %d\n"), (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 & ~ALL_SH_FLAGS)
	ERROR (gettext ("section [%2zu] '%s' contain unknown flag(s) %d\n"),
	       cnt, section_name (ebl, ehdr, cnt),
	       (int) shdr->sh_flags & ~ALL_SH_FLAGS);
      else 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, ehdr, 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, ehdr, 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, ehdr, 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, ehdr, 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, ehdr, cnt));

      if (shdr->sh_flags & SHF_GROUP)
	check_scn_group (ebl, ehdr, 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.  */
	  int pcnt;
	  GElf_Phdr phdr_mem;
	  GElf_Phdr *phdr;

	  for (pcnt = 0; pcnt < ehdr->e_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
		&& phdr->p_offset + phdr->p_memsz > shdr->sh_offset)
	      {
		/* 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, ehdr, cnt), pcnt);

		if (shdr->sh_type == SHT_NOBITS)
		  {
		    if (shdr->sh_offset < phdr->p_offset + phdr->p_filesz)
		      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, ehdr, cnt), pcnt);
		  }
		else
		  {
		    if (shdr->sh_offset >= phdr->p_offset + phdr->p_filesz)
		      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, ehdr, cnt), pcnt);
		  }

		break;
	      }

	  if (pcnt == ehdr->e_phnum)
	    ERROR (gettext ("\
section [%2zu] '%s': alloc flag set but section not in any loaded segment\n"),
		   cnt, section_name (ebl, ehdr, 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, ehdr, cnt));

      switch (shdr->sh_type)
	{
	case SHT_SYMTAB:
	case SHT_DYNSYM:
	  check_symtab (ebl, ehdr, cnt);
	  break;

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

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

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

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

	case SHT_HASH:
	  check_hash (ebl, ehdr, cnt);
	  break;

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

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

	case SHT_GNU_versym:
	  check_versym (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"));

  free (scnref);
}


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);

  char *notemem = gelf_rawchunk (ebl->elf, phdr->p_offset, phdr->p_filesz);

  /* ELF64 files often use note section entries in the 32-bit format.
     The p_align field is set to 8 in case the 64-bit format is used.
     In case the p_align value is 0 or 4 the 32-bit format is
     used.  */
  GElf_Xword align = phdr->p_align == 0 || phdr->p_align == 4 ? 4 : 8;
#define ALIGNED_LEN(len) (((len) + align - 1) & ~(align - 1))

  GElf_Xword idx = 0;
  while (idx < phdr->p_filesz)
    {
      uint64_t namesz;
      uint64_t descsz;
      uint64_t type;
      uint32_t namesz32;
      uint32_t descsz32;

      if (align == 4)
	{
	  uint32_t *ptr = (uint32_t *) (notemem + idx);

	  if ((__BYTE_ORDER == __LITTLE_ENDIAN
	       && ehdr->e_ident[EI_DATA] == ELFDATA2MSB)
	      || (__BYTE_ORDER == __BIG_ENDIAN
		  && ehdr->e_ident[EI_DATA] == ELFDATA2LSB))
	    {
	      namesz32 = namesz = bswap_32 (*ptr);
	      ++ptr;
	      descsz32 = descsz = bswap_32 (*ptr);
	      ++ptr;
	      type = bswap_32 (*ptr);
	    }
	  else
	    {
	      namesz32 = namesz = *ptr++;
	      descsz32 = descsz = *ptr++;
	      type = *ptr;
	    }
	}
      else
	{
	  uint64_t *ptr = (uint64_t *) (notemem + idx);
	  uint32_t *ptr32 = (uint32_t *) (notemem + idx);

	  if ((__BYTE_ORDER == __LITTLE_ENDIAN
	       && ehdr->e_ident[EI_DATA] == ELFDATA2MSB)
	      || (__BYTE_ORDER == __BIG_ENDIAN
		  && ehdr->e_ident[EI_DATA] == ELFDATA2LSB))
	    {
	      namesz = bswap_64 (*ptr);
	      ++ptr;
	      descsz = bswap_64 (*ptr);
	      ++ptr;
	      type = bswap_64 (*ptr);

	      namesz32 = bswap_32 (*ptr32);
	      ++ptr32;
	      descsz32 = bswap_32 (*ptr32);
	    }
	  else
	    {
	      namesz = *ptr++;
	      descsz = *ptr++;
	      type = *ptr;

	      namesz32 = *ptr32++;
	      descsz32 = *ptr32;
	    }
	}

      if (idx + 3 * align > phdr->p_filesz
	  || (idx + 3 * align + ALIGNED_LEN (namesz) + ALIGNED_LEN (descsz)
	      > phdr->p_filesz))
	{
	  if (ehdr->e_ident[EI_CLASS] == ELFCLASS64
	      && idx + 3 * 4 <= phdr->p_filesz
	      && (idx + 3 * 4 + ALIGNED_LEN (namesz32) + ALIGNED_LEN (descsz32)
		  <= phdr->p_filesz))
	    ERROR (gettext ("\
phdr[%d]: note entries probably in form of a 32-bit ELF file\n"), cnt);
	  else
	    ERROR (gettext ("phdr[%d]: extra %zu bytes after last note\n"),
		   cnt, (size_t) (phdr->p_filesz - idx));
	  break;
	}

      /* Make sure it is one of the note types we know about.  */
      if (ehdr->e_type == ET_CORE)
	{
	  switch (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:
	      ERROR (gettext ("\
phdr[%d]: unknown core file note type %" PRIu64 " at offset %" PRIu64 "\n"),
		     cnt, type, idx);
	    }
	}
      else
	{
	  if (type != NT_VERSION)
	    ERROR (gettext ("\
phdr[%d]: unknown object file note type %" PRIu64 " at offset %" PRIu64 "\n"),
		   cnt, type, idx);
	}

      /* Move to the next entry.  */
      idx += 3 * align + ALIGNED_LEN (namesz) + ALIGNED_LEN (descsz);

    }

  gelf_freechunk (ebl->elf, notemem);
}


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 (int cnt = 0; cnt < ehdr->e_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)
	ERROR (gettext ("\
program header entry %d: unknown program header entry type\n"),
	       cnt);

      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
	       && ehdr->e_type == ET_EXEC && ! has_interp_segment)
	ERROR (gettext ("static executable cannot have dynamic sections\n"));
      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.  */
	      int inner;
	      for (inner = 0; inner < ehdr->e_phnum; ++inner)
		{
		  GElf_Phdr phdr2_mem;
		  GElf_Phdr *phdr2;

		  phdr2 = gelf_getphdr (ebl->elf, cnt, &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_X) != 0)
			ERROR (gettext ("\
loadable segment GNU_RELRO applies to is executable\n"));
		      break;
		    }
		}

	      if (inner >= ehdr->e_phnum)
		ERROR (gettext ("\
GNU_RELRO segment not contained in a loaded segment\n"));
	    }
	}

      if (phdr->p_filesz > phdr->p_memsz)
	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);
	}
    }
}


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

  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);

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