LCOV - code coverage report
Current view: top level - src - elflint.c (source / functions) Hit Total Coverage
Test: elfutils-0.178 Lines: 658 2055 32.0 %
Date: 2019-11-26 23:55:16 Functions: 17 37 45.9 %
Legend: Lines: hit not hit

          Line data    Source code
       1             : /* Pedantic checking of ELF files compliance with gABI/psABI spec.
       2             :    Copyright (C) 2001-2015, 2017, 2018 Red Hat, Inc.
       3             :    This file is part of elfutils.
       4             :    Written by Ulrich Drepper <drepper@redhat.com>, 2001.
       5             : 
       6             :    This file is free software; you can redistribute it and/or modify
       7             :    it under the terms of the GNU General Public License as published by
       8             :    the Free Software Foundation; either version 3 of the License, or
       9             :    (at your option) any later version.
      10             : 
      11             :    elfutils is distributed in the hope that it will be useful, but
      12             :    WITHOUT ANY WARRANTY; without even the implied warranty of
      13             :    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
      14             :    GNU General Public License for more details.
      15             : 
      16             :    You should have received a copy of the GNU General Public License
      17             :    along with this program.  If not, see <http://www.gnu.org/licenses/>.  */
      18             : 
      19             : #ifdef HAVE_CONFIG_H
      20             : # include <config.h>
      21             : #endif
      22             : 
      23             : #include <argp.h>
      24             : #include <assert.h>
      25             : #include <byteswap.h>
      26             : #include <endian.h>
      27             : #include <fcntl.h>
      28             : #include <gelf.h>
      29             : #include <inttypes.h>
      30             : #include <libintl.h>
      31             : #include <locale.h>
      32             : #include <stdbool.h>
      33             : #include <stdlib.h>
      34             : #include <string.h>
      35             : #include <unistd.h>
      36             : #include <sys/stat.h>
      37             : 
      38             : #include <elf-knowledge.h>
      39             : #include <libeu.h>
      40             : #include <system.h>
      41             : #include <printversion.h>
      42             : #include "../libelf/libelfP.h"
      43             : #include "../libelf/common.h"
      44             : #include "../libebl/libeblP.h"
      45             : #include "../libdw/libdwP.h"
      46             : #include "../libdwfl/libdwflP.h"
      47             : #include "../libdw/memory-access.h"
      48             : 
      49             : 
      50             : /* Name and version of program.  */
      51             : ARGP_PROGRAM_VERSION_HOOK_DEF = print_version;
      52             : 
      53             : /* Bug report address.  */
      54             : ARGP_PROGRAM_BUG_ADDRESS_DEF = PACKAGE_BUGREPORT;
      55             : 
      56             : #define ARGP_strict     300
      57             : #define ARGP_gnuld      301
      58             : 
      59             : /* Definitions of arguments for argp functions.  */
      60             : static const struct argp_option options[] =
      61             : {
      62             :   { "strict", ARGP_strict, NULL, 0,
      63             :     N_("Be extremely strict, flag level 2 features."), 0 },
      64             :   { "quiet", 'q', NULL, 0, N_("Do not print anything if successful"), 0 },
      65             :   { "debuginfo", 'd', NULL, 0, N_("Binary is a separate debuginfo file"), 0 },
      66             :   { "gnu-ld", ARGP_gnuld, NULL, 0,
      67             :     N_("Binary has been created with GNU ld and is therefore known to be \
      68             : broken in certain ways"), 0 },
      69             :   { NULL, 0, NULL, 0, NULL, 0 }
      70             : };
      71             : 
      72             : /* Short description of program.  */
      73             : static const char doc[] = N_("\
      74             : Pedantic checking of ELF files compliance with gABI/psABI spec.");
      75             : 
      76             : /* Strings for arguments in help texts.  */
      77             : static const char args_doc[] = N_("FILE...");
      78             : 
      79             : /* Prototype for option handler.  */
      80             : static error_t parse_opt (int key, char *arg, struct argp_state *state);
      81             : 
      82             : /* Data structure to communicate with argp functions.  */
      83             : static struct argp argp =
      84             : {
      85             :   options, parse_opt, args_doc, doc, NULL, NULL, NULL
      86             : };
      87             : 
      88             : 
      89             : /* Declarations of local functions.  */
      90             : static void process_file (int fd, Elf *elf, const char *prefix,
      91             :                           const char *suffix, const char *fname, size_t size,
      92             :                           bool only_one);
      93             : static void process_elf_file (Elf *elf, const char *prefix, const char *suffix,
      94             :                               const char *fname, size_t size, bool only_one);
      95             : static void check_note_section (Ebl *ebl, GElf_Ehdr *ehdr,
      96             :                                 GElf_Shdr *shdr, int idx);
      97             : 
      98             : 
      99             : /* Report an error.  */
     100             : #define ERROR(str, args...) \
     101             :   do {                                                                        \
     102             :     printf (str, ##args);                                                     \
     103             :     ++error_count;                                                            \
     104             :   } while (0)
     105             : static unsigned int error_count;
     106             : 
     107             : /* True if we should perform very strict testing.  */
     108             : static bool be_strict;
     109             : 
     110             : /* True if no message is to be printed if the run is succesful.  */
     111             : static bool be_quiet;
     112             : 
     113             : /* True if binary is from strip -f, not a normal ELF file.  */
     114             : static bool is_debuginfo;
     115             : 
     116             : /* True if binary is assumed to be generated with GNU ld.  */
     117             : static bool gnuld;
     118             : 
     119             : /* Index of section header string table.  */
     120             : static uint32_t shstrndx;
     121             : 
     122             : /* Array to count references in section groups.  */
     123             : static int *scnref;
     124             : 
     125             : /* Numbers of sections and program headers.  */
     126             : static unsigned int shnum;
     127             : static unsigned int phnum;
     128             : 
     129             : 
     130             : int
     131         193 : main (int argc, char *argv[])
     132             : {
     133             :   /* Set locale.  */
     134         193 :   setlocale (LC_ALL, "");
     135             : 
     136             :   /* Initialize the message catalog.  */
     137         193 :   textdomain (PACKAGE_TARNAME);
     138             : 
     139             :   /* Parse and process arguments.  */
     140         193 :   int remaining;
     141         193 :   argp_parse (&argp, argc, argv, 0, &remaining, NULL);
     142             : 
     143             :   /* Before we start tell the ELF library which version we are using.  */
     144         193 :   elf_version (EV_CURRENT);
     145             : 
     146             :   /* Now process all the files given at the command line.  */
     147         193 :   bool only_one = remaining + 1 == argc;
     148         193 :   do
     149             :     {
     150             :       /* Open the file.  */
     151         193 :       int fd = open (argv[remaining], O_RDONLY);
     152         193 :       if (fd == -1)
     153             :         {
     154           0 :           error (0, errno, _("cannot open input file '%s'"), argv[remaining]);
     155           0 :           continue;
     156             :         }
     157             : 
     158             :       /* Create an `Elf' descriptor.  */
     159         193 :       Elf *elf = elf_begin (fd, ELF_C_READ_MMAP, NULL);
     160         193 :       if (elf == NULL)
     161           0 :         ERROR (_("cannot generate Elf descriptor for '%s': %s\n"),
     162             :                argv[remaining], elf_errmsg (-1));
     163             :       else
     164             :         {
     165         193 :           unsigned int prev_error_count = error_count;
     166         193 :           struct stat st;
     167             : 
     168         193 :           if (fstat (fd, &st) != 0)
     169             :             {
     170           0 :               printf ("cannot stat '%s': %m\n", argv[remaining]);
     171           0 :               close (fd);
     172           0 :               continue;
     173             :             }
     174             : 
     175         193 :           process_file (fd, elf, NULL, NULL, argv[remaining], st.st_size,
     176             :                         only_one);
     177             : 
     178             :           /* Now we can close the descriptor.  */
     179         193 :           if (elf_end (elf) != 0)
     180           0 :             ERROR (gettext ("error while closing Elf descriptor: %s\n"),
     181             :                    elf_errmsg (-1));
     182             : 
     183         193 :           if (prev_error_count == error_count && !be_quiet)
     184         138 :             puts (gettext ("No errors"));
     185             :         }
     186             : 
     187         193 :       close (fd);
     188             :     }
     189         193 :   while (++remaining < argc);
     190             : 
     191         193 :   return error_count != 0;
     192             : }
     193             : 
     194             : 
     195             : /* Handle program arguments.  */
     196             : static error_t
     197        1225 : parse_opt (int key, char *arg __attribute__ ((unused)),
     198             :            struct argp_state *state __attribute__ ((unused)))
     199             : {
     200        1225 :   switch (key)
     201             :     {
     202           0 :     case ARGP_strict:
     203           0 :       be_strict = true;
     204           0 :       break;
     205             : 
     206          54 :     case 'q':
     207          54 :       be_quiet = true;
     208          54 :       break;
     209             : 
     210          22 :     case 'd':
     211          22 :       is_debuginfo = true;
     212          22 :       break;
     213             : 
     214         184 :     case ARGP_gnuld:
     215         184 :       gnuld = true;
     216         184 :       break;
     217             : 
     218           0 :     case ARGP_KEY_NO_ARGS:
     219           0 :       fputs (gettext ("Missing file name.\n"), stderr);
     220           0 :       argp_help (&argp, stderr, ARGP_HELP_SEE, program_invocation_short_name);
     221           0 :       exit (EXIT_FAILURE);
     222             : 
     223             :     default:
     224             :       return ARGP_ERR_UNKNOWN;
     225             :     }
     226             :   return 0;
     227             : }
     228             : 
     229             : 
     230             : /* Process one file.  */
     231             : static void
     232         193 : process_file (int fd, Elf *elf, const char *prefix, const char *suffix,
     233             :               const char *fname, size_t size, bool only_one)
     234             : {
     235             :   /* We can handle two types of files: ELF files and archives.  */
     236         193 :   Elf_Kind kind = elf_kind (elf);
     237             : 
     238         193 :   switch (kind)
     239             :     {
     240         193 :     case ELF_K_ELF:
     241             :       /* Yes!  It's an ELF file.  */
     242         193 :       process_elf_file (elf, prefix, suffix, fname, size, only_one);
     243         193 :       break;
     244             : 
     245           0 :     case ELF_K_AR:
     246           0 :       {
     247           0 :         Elf *subelf;
     248           0 :         Elf_Cmd cmd = ELF_C_READ_MMAP;
     249           0 :         size_t prefix_len = prefix == NULL ? 0 : strlen (prefix);
     250           0 :         size_t fname_len = strlen (fname) + 1;
     251           0 :         char new_prefix[prefix_len + 1 + fname_len];
     252           0 :         char new_suffix[(suffix == NULL ? 0 : strlen (suffix)) + 2];
     253           0 :         char *cp = new_prefix;
     254             : 
     255             :         /* Create the full name of the file.  */
     256           0 :         if (prefix != NULL)
     257             :           {
     258           0 :             cp = mempcpy (cp, prefix, prefix_len);
     259           0 :             *cp++ = '(';
     260           0 :             strcpy (stpcpy (new_suffix, suffix), ")");
     261             :           }
     262             :         else
     263           0 :           new_suffix[0] = '\0';
     264           0 :         memcpy (cp, fname, fname_len);
     265             : 
     266             :         /* It's an archive.  We process each file in it.  */
     267           0 :         while ((subelf = elf_begin (fd, cmd, elf)) != NULL)
     268             :           {
     269           0 :             kind = elf_kind (subelf);
     270             : 
     271             :             /* Call this function recursively.  */
     272           0 :             if (kind == ELF_K_ELF || kind == ELF_K_AR)
     273             :               {
     274           0 :                 Elf_Arhdr *arhdr = elf_getarhdr (subelf);
     275           0 :                 assert (arhdr != NULL);
     276             : 
     277           0 :                 process_file (fd, subelf, new_prefix, new_suffix,
     278           0 :                               arhdr->ar_name, arhdr->ar_size, false);
     279             :               }
     280             : 
     281             :             /* Get next archive element.  */
     282           0 :             cmd = elf_next (subelf);
     283           0 :             if (elf_end (subelf) != 0)
     284           0 :               ERROR (gettext (" error while freeing sub-ELF descriptor: %s\n"),
     285             :                      elf_errmsg (-1));
     286             :           }
     287             :       }
     288           0 :       break;
     289             : 
     290           0 :     default:
     291             :       /* We cannot do anything.  */
     292           0 :       ERROR (gettext ("\
     293             : Not an ELF file - it has the wrong magic bytes at the start\n"));
     294           0 :       break;
     295             :     }
     296         193 : }
     297             : 
     298             : 
     299             : static const char *
     300           0 : section_name (Ebl *ebl, int idx)
     301             : {
     302           0 :   GElf_Shdr shdr_mem;
     303           0 :   GElf_Shdr *shdr;
     304           0 :   const char *ret;
     305             : 
     306           0 :   if ((unsigned int) idx > shnum)
     307           0 :     return "<invalid>";
     308             : 
     309           0 :   shdr = gelf_getshdr (elf_getscn (ebl->elf, idx), &shdr_mem);
     310           0 :   if (shdr == NULL)
     311           0 :     return "<invalid>";
     312             : 
     313           0 :   ret = elf_strptr (ebl->elf, shstrndx, shdr->sh_name);
     314           0 :   if (ret == NULL)
     315           0 :     return "<invalid>";
     316             :   return ret;
     317             : }
     318             : 
     319             : 
     320             : static const int valid_e_machine[] =
     321             :   {
     322             :     EM_M32, EM_SPARC, EM_386, EM_68K, EM_88K, EM_860, EM_MIPS, EM_S370,
     323             :     EM_MIPS_RS3_LE, EM_PARISC, EM_VPP500, EM_SPARC32PLUS, EM_960, EM_PPC,
     324             :     EM_PPC64, EM_S390, EM_V800, EM_FR20, EM_RH32, EM_RCE, EM_ARM,
     325             :     EM_FAKE_ALPHA, EM_SH, EM_SPARCV9, EM_TRICORE, EM_ARC, EM_H8_300,
     326             :     EM_H8_300H, EM_H8S, EM_H8_500, EM_IA_64, EM_MIPS_X, EM_COLDFIRE,
     327             :     EM_68HC12, EM_MMA, EM_PCP, EM_NCPU, EM_NDR1, EM_STARCORE, EM_ME16,
     328             :     EM_ST100, EM_TINYJ, EM_X86_64, EM_PDSP, EM_FX66, EM_ST9PLUS, EM_ST7,
     329             :     EM_68HC16, EM_68HC11, EM_68HC08, EM_68HC05, EM_SVX, EM_ST19, EM_VAX,
     330             :     EM_CRIS, EM_JAVELIN, EM_FIREPATH, EM_ZSP, EM_MMIX, EM_HUANY, EM_PRISM,
     331             :     EM_AVR, EM_FR30, EM_D10V, EM_D30V, EM_V850, EM_M32R, EM_MN10300,
     332             :     EM_MN10200, EM_PJ, EM_OPENRISC, EM_ARC_A5, EM_XTENSA, EM_ALPHA,
     333             :     EM_TILEGX, EM_TILEPRO, EM_AARCH64, EM_BPF, EM_RISCV, EM_CSKY
     334             :   };
     335             : #define nvalid_e_machine \
     336             :   (sizeof (valid_e_machine) / sizeof (valid_e_machine[0]))
     337             : 
     338             : 
     339             : static void
     340         193 : check_elf_header (Ebl *ebl, GElf_Ehdr *ehdr, size_t size)
     341             : {
     342         193 :   char buf[512];
     343         193 :   size_t cnt;
     344             : 
     345             :   /* Check e_ident field.  */
     346         193 :   if (ehdr->e_ident[EI_MAG0] != ELFMAG0)
     347           0 :     ERROR ("e_ident[%d] != '%c'\n", EI_MAG0, ELFMAG0);
     348         193 :   if (ehdr->e_ident[EI_MAG1] != ELFMAG1)
     349           0 :     ERROR ("e_ident[%d] != '%c'\n", EI_MAG1, ELFMAG1);
     350         193 :   if (ehdr->e_ident[EI_MAG2] != ELFMAG2)
     351           0 :     ERROR ("e_ident[%d] != '%c'\n", EI_MAG2, ELFMAG2);
     352         193 :   if (ehdr->e_ident[EI_MAG3] != ELFMAG3)
     353           0 :     ERROR ("e_ident[%d] != '%c'\n", EI_MAG3, ELFMAG3);
     354             : 
     355         386 :   if (ehdr->e_ident[EI_CLASS] != ELFCLASS32
     356         193 :       && ehdr->e_ident[EI_CLASS] != ELFCLASS64)
     357           0 :     ERROR (gettext ("e_ident[%d] == %d is no known class\n"),
     358             :            EI_CLASS, ehdr->e_ident[EI_CLASS]);
     359             : 
     360         386 :   if (ehdr->e_ident[EI_DATA] != ELFDATA2LSB
     361         193 :       && ehdr->e_ident[EI_DATA] != ELFDATA2MSB)
     362           0 :     ERROR (gettext ("e_ident[%d] == %d is no known data encoding\n"),
     363             :            EI_DATA, ehdr->e_ident[EI_DATA]);
     364             : 
     365         193 :   if (ehdr->e_ident[EI_VERSION] != EV_CURRENT)
     366           0 :     ERROR (gettext ("unknown ELF header version number e_ident[%d] == %d\n"),
     367             :            EI_VERSION, ehdr->e_ident[EI_VERSION]);
     368             : 
     369             :   /* We currently don't handle any OS ABIs other than Linux and the
     370             :      kFreeBSD variant of Debian.  */
     371         386 :   if (ehdr->e_ident[EI_OSABI] != ELFOSABI_NONE
     372         193 :       && ehdr->e_ident[EI_OSABI] != ELFOSABI_LINUX
     373           0 :       && ehdr->e_ident[EI_OSABI] != ELFOSABI_FREEBSD)
     374           0 :     ERROR (gettext ("unsupported OS ABI e_ident[%d] == '%s'\n"),
     375             :            EI_OSABI,
     376             :            ebl_osabi_name (ebl, ehdr->e_ident[EI_OSABI], buf, sizeof (buf)));
     377             : 
     378             :   /* No ABI versions other than zero are supported either.  */
     379         193 :   if (ehdr->e_ident[EI_ABIVERSION] != 0)
     380           0 :     ERROR (gettext ("unsupported ABI version e_ident[%d] == %d\n"),
     381             :            EI_ABIVERSION, ehdr->e_ident[EI_ABIVERSION]);
     382             : 
     383        1544 :   for (cnt = EI_PAD; cnt < EI_NIDENT; ++cnt)
     384        1351 :     if (ehdr->e_ident[cnt] != 0)
     385           0 :       ERROR (gettext ("e_ident[%zu] is not zero\n"), cnt);
     386             : 
     387             :   /* Check the e_type field.  */
     388         386 :   if (ehdr->e_type != ET_REL && ehdr->e_type != ET_EXEC
     389         193 :       && ehdr->e_type != ET_DYN && ehdr->e_type != ET_CORE)
     390           0 :     ERROR (gettext ("unknown object file type %d\n"), ehdr->e_type);
     391             : 
     392             :   /* Check the e_machine field.  */
     393        4845 :   for (cnt = 0; cnt < nvalid_e_machine; ++cnt)
     394        4845 :     if (valid_e_machine[cnt] == ehdr->e_machine)
     395             :       break;
     396         193 :   if (cnt == nvalid_e_machine)
     397           0 :     ERROR (gettext ("unknown machine type %d\n"), ehdr->e_machine);
     398             : 
     399             :   /* Check the e_version field.  */
     400         193 :   if (ehdr->e_version != EV_CURRENT)
     401           0 :     ERROR (gettext ("unknown object file version\n"));
     402             : 
     403             :   /* Check the e_phoff and e_phnum fields.  */
     404         193 :   if (ehdr->e_phoff == 0)
     405             :     {
     406          35 :       if (ehdr->e_phnum != 0)
     407           0 :         ERROR (gettext ("invalid program header offset\n"));
     408          35 :       else if (ehdr->e_type == ET_EXEC || ehdr->e_type == ET_DYN)
     409           0 :         ERROR (gettext ("\
     410             : executables and DSOs cannot have zero program header offset\n"));
     411             :     }
     412         158 :   else if (ehdr->e_phnum == 0)
     413           0 :     ERROR (gettext ("invalid number of program header entries\n"));
     414             : 
     415             :   /* Check the e_shoff field.  */
     416         193 :   shnum = ehdr->e_shnum;
     417         193 :   shstrndx = ehdr->e_shstrndx;
     418         193 :   if (ehdr->e_shoff == 0)
     419             :     {
     420           0 :       if (ehdr->e_shnum != 0)
     421           0 :         ERROR (gettext ("invalid section header table offset\n"));
     422           0 :       else if (ehdr->e_type != ET_EXEC && ehdr->e_type != ET_DYN
     423           0 :                && ehdr->e_type != ET_CORE)
     424           0 :         ERROR (gettext ("section header table must be present\n"));
     425             :     }
     426             :   else
     427             :     {
     428         193 :       if (ehdr->e_shnum == 0)
     429             :         {
     430             :           /* Get the header of the zeroth section.  The sh_size field
     431             :              might contain the section number.  */
     432           6 :           GElf_Shdr shdr_mem;
     433           6 :           GElf_Shdr *shdr = gelf_getshdr (elf_getscn (ebl->elf, 0), &shdr_mem);
     434           6 :           if (shdr != NULL)
     435             :             {
     436             :               /* The error will be reported later.  */
     437           6 :               if (shdr->sh_size == 0)
     438           0 :                 ERROR (gettext ("\
     439             : invalid number of section header table entries\n"));
     440             :               else
     441           6 :                 shnum = shdr->sh_size;
     442             :             }
     443             :         }
     444             : 
     445         193 :       if (ehdr->e_shstrndx == SHN_XINDEX)
     446             :         {
     447             :           /* Get the header of the zeroth section.  The sh_size field
     448             :              might contain the section number.  */
     449           6 :           GElf_Shdr shdr_mem;
     450           6 :           GElf_Shdr *shdr = gelf_getshdr (elf_getscn (ebl->elf, 0), &shdr_mem);
     451           6 :           if (shdr != NULL && shdr->sh_link < shnum)
     452           6 :             shstrndx = shdr->sh_link;
     453             :         }
     454         187 :       else if (shstrndx >= shnum)
     455           0 :         ERROR (gettext ("invalid section header index\n"));
     456             :     }
     457             : 
     458             :   /* Check the shdrs actually exist.  And uncompress them before
     459             :      further checking.  Indexes between sections reference the
     460             :      uncompressed data.  */
     461             :   unsigned int scnt;
     462             :   Elf_Scn *scn = NULL;
     463      399518 :   for (scnt = 1; scnt < shnum; ++scnt)
     464             :      {
     465      399325 :         scn = elf_nextscn (ebl->elf, scn);
     466      399325 :         if (scn == NULL)
     467             :           break;
     468             :         /* If the section wasn't compressed this does nothing, but
     469             :            returns an error.  We don't care.  */
     470      399325 :         elf_compress (scn, 0, 0);
     471             :      }
     472         193 :   if (scnt < shnum)
     473           0 :     ERROR (gettext ("Can only check %u headers, shnum was %u\n"), scnt, shnum);
     474         193 :   shnum = scnt;
     475             : 
     476         193 :   phnum = ehdr->e_phnum;
     477         193 :   if (ehdr->e_phnum == PN_XNUM)
     478             :     {
     479             :       /* Get the header of the zeroth section.  The sh_info field
     480             :          might contain the phnum count.  */
     481           0 :       GElf_Shdr shdr_mem;
     482           0 :       GElf_Shdr *shdr = gelf_getshdr (elf_getscn (ebl->elf, 0), &shdr_mem);
     483           0 :       if (shdr != NULL)
     484             :         {
     485             :           /* The error will be reported later.  */
     486           0 :           if (shdr->sh_info < PN_XNUM)
     487           0 :             ERROR (gettext ("\
     488             : invalid number of program header table entries\n"));
     489             :           else
     490           0 :             phnum = shdr->sh_info;
     491             :         }
     492             :     }
     493             : 
     494             :   /* Check the phdrs actually exist. */
     495             :   unsigned int pcnt;
     496        1118 :   for (pcnt = 0; pcnt < phnum; ++pcnt)
     497             :      {
     498         925 :         GElf_Phdr phdr_mem;
     499         925 :         GElf_Phdr *phdr = gelf_getphdr (ebl->elf, pcnt, &phdr_mem);
     500         925 :         if (phdr == NULL)
     501             :           break;
     502             :      }
     503         193 :   if (pcnt < phnum)
     504           0 :     ERROR (gettext ("Can only check %u headers, phnum was %u\n"), pcnt, phnum);
     505         193 :   phnum = pcnt;
     506             : 
     507             :   /* Check the e_flags field.  */
     508         193 :   if (!ebl_machine_flag_check (ebl, ehdr->e_flags))
     509           0 :     ERROR (gettext ("invalid machine flags: %s\n"),
     510             :            ebl_machine_flag_name (ebl, ehdr->e_flags, buf, sizeof (buf)));
     511             : 
     512             :   /* Check e_ehsize, e_phentsize, and e_shentsize fields.  */
     513         193 :   if (gelf_getclass (ebl->elf) == ELFCLASS32)
     514             :     {
     515          76 :       if (ehdr->e_ehsize != 0 && ehdr->e_ehsize != sizeof (Elf32_Ehdr))
     516           0 :         ERROR (gettext ("invalid ELF header size: %hd\n"), ehdr->e_ehsize);
     517             : 
     518          76 :       if (ehdr->e_phentsize != 0 && ehdr->e_phentsize != sizeof (Elf32_Phdr))
     519           0 :         ERROR (gettext ("invalid program header size: %hd\n"),
     520             :                ehdr->e_phentsize);
     521          76 :       else if (ehdr->e_phoff + phnum * ehdr->e_phentsize > size)
     522           0 :         ERROR (gettext ("invalid program header position or size\n"));
     523             : 
     524          76 :       if (ehdr->e_shentsize != 0 && ehdr->e_shentsize != sizeof (Elf32_Shdr))
     525           0 :         ERROR (gettext ("invalid section header size: %hd\n"),
     526             :                ehdr->e_shentsize);
     527          76 :       else if (ehdr->e_shoff + shnum * ehdr->e_shentsize > size)
     528           0 :         ERROR (gettext ("invalid section header position or size\n"));
     529             :     }
     530         117 :   else if (gelf_getclass (ebl->elf) == ELFCLASS64)
     531             :     {
     532         117 :       if (ehdr->e_ehsize != 0 && ehdr->e_ehsize != sizeof (Elf64_Ehdr))
     533           0 :         ERROR (gettext ("invalid ELF header size: %hd\n"), ehdr->e_ehsize);
     534             : 
     535         117 :       if (ehdr->e_phentsize != 0 && ehdr->e_phentsize != sizeof (Elf64_Phdr))
     536           0 :         ERROR (gettext ("invalid program header size: %hd\n"),
     537             :                ehdr->e_phentsize);
     538         117 :       else if (ehdr->e_phoff + phnum * ehdr->e_phentsize > size)
     539           0 :         ERROR (gettext ("invalid program header position or size\n"));
     540             : 
     541         117 :       if (ehdr->e_shentsize != 0 && ehdr->e_shentsize != sizeof (Elf64_Shdr))
     542           0 :         ERROR (gettext ("invalid section header size: %hd\n"),
     543             :                ehdr->e_shentsize);
     544         117 :       else if (ehdr->e_shoff + shnum * ehdr->e_shentsize > size)
     545           0 :         ERROR (gettext ("invalid section header position or size\n"));
     546             :     }
     547         193 : }
     548             : 
     549             : 
     550             : /* Check that there is a section group section with index < IDX which
     551             :    contains section IDX and that there is exactly one.  */
     552             : static void
     553       44008 : check_scn_group (Ebl *ebl, int idx)
     554             : {
     555       44008 :   if (scnref[idx] == 0)
     556             :     {
     557             :       /* No reference so far.  Search following sections, maybe the
     558             :          order is wrong.  */
     559           0 :       size_t cnt;
     560             : 
     561           0 :       for (cnt = idx + 1; cnt < shnum; ++cnt)
     562             :         {
     563           0 :           Elf_Scn *scn = elf_getscn (ebl->elf, cnt);
     564           0 :           GElf_Shdr shdr_mem;
     565           0 :           GElf_Shdr *shdr = gelf_getshdr (scn, &shdr_mem);
     566           0 :           if (shdr == NULL)
     567             :             /* We cannot get the section header so we cannot check it.
     568             :                The error to get the section header will be shown
     569             :                somewhere else.  */
     570           0 :             continue;
     571             : 
     572           0 :           if (shdr->sh_type != SHT_GROUP)
     573             :             continue;
     574             : 
     575           0 :           Elf_Data *data = elf_getdata (scn, NULL);
     576           0 :           if (data == NULL || data->d_buf == NULL
     577           0 :               || data->d_size < sizeof (Elf32_Word))
     578             :             /* Cannot check the section.  */
     579             :             continue;
     580             : 
     581             :           Elf32_Word *grpdata = (Elf32_Word *) data->d_buf;
     582           0 :           for (size_t inner = 1; inner < data->d_size / sizeof (Elf32_Word);
     583           0 :                ++inner)
     584           0 :             if (grpdata[inner] == (Elf32_Word) idx)
     585           0 :               goto out;
     586             :         }
     587             : 
     588           0 :     out:
     589           0 :       if (cnt == shnum)
     590           0 :         ERROR (gettext ("\
     591             : section [%2d] '%s': section with SHF_GROUP flag set not part of a section group\n"),
     592             :                idx, section_name (ebl, idx));
     593             :       else
     594           0 :         ERROR (gettext ("\
     595             : section [%2d] '%s': section group [%2zu] '%s' does not precede group member\n"),
     596             :                idx, section_name (ebl, idx),
     597             :                cnt, section_name (ebl, cnt));
     598             :     }
     599       44008 : }
     600             : 
     601             : 
     602             : static void
     603           0 : check_symtab (Ebl *ebl, GElf_Ehdr *ehdr, GElf_Shdr *shdr, int idx)
     604             : {
     605           0 :   bool no_xndx_warned = false;
     606           0 :   int no_pt_tls = 0;
     607           0 :   Elf_Data *data = elf_getdata (elf_getscn (ebl->elf, idx), NULL);
     608           0 :   if (data == NULL)
     609             :     {
     610           0 :       ERROR (gettext ("section [%2d] '%s': cannot get section data\n"),
     611             :              idx, section_name (ebl, idx));
     612           0 :       return;
     613             :     }
     614             : 
     615           0 :   GElf_Shdr strshdr_mem;
     616           0 :   GElf_Shdr *strshdr = gelf_getshdr (elf_getscn (ebl->elf, shdr->sh_link),
     617             :                                      &strshdr_mem);
     618           0 :   if (strshdr == NULL)
     619           0 :     return;
     620             : 
     621           0 :   if (strshdr->sh_type != SHT_STRTAB)
     622             :     {
     623           0 :       ERROR (gettext ("section [%2d] '%s': referenced as string table for section [%2d] '%s' but type is not SHT_STRTAB\n"),
     624             :              shdr->sh_link, section_name (ebl, shdr->sh_link),
     625             :              idx, section_name (ebl, idx));
     626           0 :       strshdr = NULL;
     627             :     }
     628             : 
     629             :   /* Search for an extended section index table section.  */
     630           0 :   Elf_Data *xndxdata = NULL;
     631           0 :   Elf32_Word xndxscnidx = 0;
     632           0 :   bool found_xndx = false;
     633           0 :   for (size_t cnt = 1; cnt < shnum; ++cnt)
     634           0 :     if (cnt != (size_t) idx)
     635             :       {
     636           0 :         Elf_Scn *xndxscn = elf_getscn (ebl->elf, cnt);
     637           0 :         GElf_Shdr xndxshdr_mem;
     638           0 :         GElf_Shdr *xndxshdr = gelf_getshdr (xndxscn, &xndxshdr_mem);
     639           0 :         if (xndxshdr == NULL)
     640           0 :           continue;
     641             : 
     642           0 :         if (xndxshdr->sh_type == SHT_SYMTAB_SHNDX
     643           0 :             && xndxshdr->sh_link == (GElf_Word) idx)
     644             :           {
     645           0 :             if (found_xndx)
     646           0 :               ERROR (gettext ("\
     647             : section [%2d] '%s': symbol table cannot have more than one extended index section\n"),
     648             :                      idx, section_name (ebl, idx));
     649             : 
     650           0 :             xndxdata = elf_getdata (xndxscn, NULL);
     651           0 :             xndxscnidx = elf_ndxscn (xndxscn);
     652           0 :             found_xndx = true;
     653             :           }
     654             :       }
     655             : 
     656           0 :   size_t sh_entsize = gelf_fsize (ebl->elf, ELF_T_SYM, 1, EV_CURRENT);
     657           0 :   if (shdr->sh_entsize != sh_entsize)
     658           0 :     ERROR (gettext ("\
     659             : section [%2u] '%s': entry size is does not match ElfXX_Sym\n"),
     660             :            idx, section_name (ebl, idx));
     661             : 
     662             :   /* Test the zeroth entry.  */
     663           0 :   GElf_Sym sym_mem;
     664           0 :   Elf32_Word xndx;
     665           0 :   GElf_Sym *sym = gelf_getsymshndx (data, xndxdata, 0, &sym_mem, &xndx);
     666           0 :   if (sym == NULL)
     667           0 :       ERROR (gettext ("section [%2d] '%s': cannot get symbol %d: %s\n"),
     668             :              idx, section_name (ebl, idx), 0, elf_errmsg (-1));
     669             :   else
     670             :     {
     671           0 :       if (sym->st_name != 0)
     672           0 :         ERROR (gettext ("section [%2d] '%s': '%s' in zeroth entry not zero\n"),
     673             :                idx, section_name (ebl, idx), "st_name");
     674           0 :       if (sym->st_value != 0)
     675           0 :         ERROR (gettext ("section [%2d] '%s': '%s' in zeroth entry not zero\n"),
     676             :                idx, section_name (ebl, idx), "st_value");
     677           0 :       if (sym->st_size != 0)
     678           0 :         ERROR (gettext ("section [%2d] '%s': '%s' in zeroth entry not zero\n"),
     679             :                idx, section_name (ebl, idx), "st_size");
     680           0 :       if (sym->st_info != 0)
     681           0 :         ERROR (gettext ("section [%2d] '%s': '%s' in zeroth entry not zero\n"),
     682             :                idx, section_name (ebl, idx), "st_info");
     683           0 :       if (sym->st_other != 0)
     684           0 :         ERROR (gettext ("section [%2d] '%s': '%s' in zeroth entry not zero\n"),
     685             :                idx, section_name (ebl, idx), "st_other");
     686           0 :       if (sym->st_shndx != 0)
     687           0 :         ERROR (gettext ("section [%2d] '%s': '%s' in zeroth entry not zero\n"),
     688             :                idx, section_name (ebl, idx), "st_shndx");
     689           0 :       if (xndxdata != NULL && xndx != 0)
     690           0 :         ERROR (gettext ("\
     691             : section [%2d] '%s': XINDEX for zeroth entry not zero\n"),
     692             :                xndxscnidx, section_name (ebl, xndxscnidx));
     693             :     }
     694             : 
     695           0 :   for (size_t cnt = 1; cnt < shdr->sh_size / sh_entsize; ++cnt)
     696             :     {
     697           0 :       sym = gelf_getsymshndx (data, xndxdata, cnt, &sym_mem, &xndx);
     698           0 :       if (sym == NULL)
     699             :         {
     700           0 :           ERROR (gettext ("section [%2d] '%s': cannot get symbol %zu: %s\n"),
     701             :                  idx, section_name (ebl, idx), cnt, elf_errmsg (-1));
     702           0 :           continue;
     703             :         }
     704             : 
     705           0 :       const char *name = NULL;
     706           0 :       if (strshdr == NULL)
     707             :         name = "";
     708           0 :       else if (sym->st_name >= strshdr->sh_size)
     709           0 :         ERROR (gettext ("\
     710             : section [%2d] '%s': symbol %zu: invalid name value\n"),
     711             :                idx, section_name (ebl, idx), cnt);
     712             :       else
     713             :         {
     714           0 :           name = elf_strptr (ebl->elf, shdr->sh_link, sym->st_name);
     715           0 :           if (name == NULL)
     716           0 :             name = "";
     717             :         }
     718             : 
     719           0 :       if (sym->st_shndx == SHN_XINDEX)
     720             :         {
     721           0 :           if (xndxdata == NULL)
     722             :             {
     723           0 :               if (!no_xndx_warned)
     724           0 :                 ERROR (gettext ("\
     725             : section [%2d] '%s': symbol %zu: too large section index but no extended section index section\n"),
     726             :                        idx, section_name (ebl, idx), cnt);
     727             :               no_xndx_warned = true;
     728             :             }
     729           0 :           else if (xndx < SHN_LORESERVE)
     730           0 :             ERROR (gettext ("\
     731             : section [%2d] '%s': symbol %zu: XINDEX used for index which would fit in st_shndx (%" PRIu32 ")\n"),
     732             :                    xndxscnidx, section_name (ebl, xndxscnidx), cnt,
     733             :                    xndx);
     734             :         }
     735           0 :       else if ((sym->st_shndx >= SHN_LORESERVE
     736             :                 // && sym->st_shndx <= SHN_HIRESERVE    always true
     737           0 :                 && sym->st_shndx != SHN_ABS
     738           0 :                 && sym->st_shndx != SHN_COMMON)
     739           0 :                || (sym->st_shndx >= shnum
     740           0 :                    && (sym->st_shndx < SHN_LORESERVE
     741             :                        /* || sym->st_shndx > SHN_HIRESERVE  always false */)))
     742           0 :         ERROR (gettext ("\
     743             : section [%2d] '%s': symbol %zu: invalid section index\n"),
     744             :                idx, section_name (ebl, idx), cnt);
     745             :       else
     746           0 :         xndx = sym->st_shndx;
     747             : 
     748           0 :       if (GELF_ST_TYPE (sym->st_info) >= STT_NUM
     749           0 :           && !ebl_symbol_type_name (ebl, GELF_ST_TYPE (sym->st_info), NULL, 0))
     750           0 :         ERROR (gettext ("section [%2d] '%s': symbol %zu: unknown type\n"),
     751             :                idx, section_name (ebl, idx), cnt);
     752             : 
     753           0 :       if (GELF_ST_BIND (sym->st_info) >= STB_NUM
     754           0 :           && !ebl_symbol_binding_name (ebl, GELF_ST_BIND (sym->st_info), NULL,
     755             :                                        0))
     756           0 :         ERROR (gettext ("\
     757             : section [%2d] '%s': symbol %zu: unknown symbol binding\n"),
     758             :                idx, section_name (ebl, idx), cnt);
     759           0 :       if (GELF_ST_BIND (sym->st_info) == STB_GNU_UNIQUE
     760           0 :           && GELF_ST_TYPE (sym->st_info) != STT_OBJECT)
     761           0 :         ERROR (gettext ("\
     762             : section [%2d] '%s': symbol %zu: unique symbol not of object type\n"),
     763             :                idx, section_name (ebl, idx), cnt);
     764             : 
     765           0 :       if (xndx == SHN_COMMON)
     766             :         {
     767             :           /* Common symbols can only appear in relocatable files.  */
     768           0 :           if (ehdr->e_type != ET_REL)
     769           0 :             ERROR (gettext ("\
     770             : section [%2d] '%s': symbol %zu: COMMON only allowed in relocatable files\n"),
     771             :                    idx, section_name (ebl, idx), cnt);
     772           0 :           if (cnt < shdr->sh_info)
     773           0 :             ERROR (gettext ("\
     774             : section [%2d] '%s': symbol %zu: local COMMON symbols are nonsense\n"),
     775             :                    idx, section_name (ebl, idx), cnt);
     776           0 :           if (GELF_R_TYPE (sym->st_info) == STT_FUNC)
     777           0 :             ERROR (gettext ("\
     778             : section [%2d] '%s': symbol %zu: function in COMMON section is nonsense\n"),
     779             :                    idx, section_name (ebl, idx), cnt);
     780             :         }
     781           0 :       else if (xndx > 0 && xndx < shnum)
     782             :         {
     783           0 :           GElf_Shdr destshdr_mem;
     784           0 :           GElf_Shdr *destshdr;
     785             : 
     786           0 :           destshdr = gelf_getshdr (elf_getscn (ebl->elf, xndx), &destshdr_mem);
     787           0 :           if (destshdr != NULL)
     788             :             {
     789           0 :               GElf_Addr sh_addr = (ehdr->e_type == ET_REL ? 0
     790           0 :                                    : destshdr->sh_addr);
     791           0 :               GElf_Addr st_value;
     792           0 :               if (GELF_ST_TYPE (sym->st_info) == STT_FUNC
     793           0 :                   || (GELF_ST_TYPE (sym->st_info) == STT_GNU_IFUNC))
     794           0 :                 st_value = sym->st_value & ebl_func_addr_mask (ebl);
     795             :               else
     796           0 :                 st_value = sym->st_value;
     797           0 :               if (GELF_ST_TYPE (sym->st_info) != STT_TLS)
     798             :                 {
     799           0 :                   if (! ebl_check_special_symbol (ebl, sym, name,
     800             :                                                   destshdr))
     801             :                     {
     802           0 :                       if (st_value - sh_addr > destshdr->sh_size)
     803             :                         {
     804             :                           /* GNU ld has severe bugs.  When it decides to remove
     805             :                              empty sections it leaves symbols referencing them
     806             :                              behind.  These are symbols in .symtab or .dynsym
     807             :                              and for the named symbols have zero size.  See
     808             :                              sourceware PR13621.  */
     809           0 :                           if (!gnuld
     810           0 :                               || (strcmp (section_name (ebl, idx), ".symtab")
     811           0 :                                   && strcmp (section_name (ebl, idx),
     812             :                                              ".dynsym"))
     813           0 :                               || sym->st_size != 0
     814           0 :                               || (strcmp (name, "__preinit_array_start") != 0
     815           0 :                                   && strcmp (name, "__preinit_array_end") != 0
     816           0 :                                   && strcmp (name, "__init_array_start") != 0
     817           0 :                                   && strcmp (name, "__init_array_end") != 0
     818           0 :                                   && strcmp (name, "__fini_array_start") != 0
     819           0 :                                   && strcmp (name, "__fini_array_end") != 0
     820           0 :                                   && strcmp (name, "__bss_start") != 0
     821           0 :                                   && strcmp (name, "__bss_start__") != 0
     822           0 :                                   && strcmp (name, "__TMC_END__") != 0
     823           0 :                                   && strcmp (name, ".TOC.") != 0
     824           0 :                                   && strcmp (name, "_edata") != 0
     825           0 :                                   && strcmp (name, "__edata") != 0
     826           0 :                                   && strcmp (name, "_end") != 0
     827           0 :                                   && strcmp (name, "__end") != 0))
     828           0 :                             ERROR (gettext ("\
     829             : section [%2d] '%s': symbol %zu: st_value out of bounds\n"),
     830             :                                    idx, section_name (ebl, idx), cnt);
     831             :                         }
     832           0 :                       else if ((st_value - sh_addr
     833           0 :                                 + sym->st_size) > destshdr->sh_size)
     834           0 :                         ERROR (gettext ("\
     835             : section [%2d] '%s': symbol %zu does not fit completely in referenced section [%2d] '%s'\n"),
     836             :                                idx, section_name (ebl, idx), cnt,
     837             :                                (int) xndx, section_name (ebl, xndx));
     838             :                     }
     839             :                 }
     840             :               else
     841             :                 {
     842           0 :                   if ((destshdr->sh_flags & SHF_TLS) == 0)
     843           0 :                     ERROR (gettext ("\
     844             : section [%2d] '%s': symbol %zu: referenced section [%2d] '%s' does not have SHF_TLS flag set\n"),
     845             :                            idx, section_name (ebl, idx), cnt,
     846             :                            (int) xndx, section_name (ebl, xndx));
     847             : 
     848           0 :                   if (ehdr->e_type == ET_REL)
     849             :                     {
     850             :                       /* For object files the symbol value must fall
     851             :                          into the section.  */
     852           0 :                       if (st_value > destshdr->sh_size)
     853           0 :                         ERROR (gettext ("\
     854             : section [%2d] '%s': symbol %zu: st_value out of bounds of referenced section [%2d] '%s'\n"),
     855             :                                idx, section_name (ebl, idx), cnt,
     856             :                                (int) xndx, section_name (ebl, xndx));
     857           0 :                       else if (st_value + sym->st_size
     858             :                                > destshdr->sh_size)
     859           0 :                         ERROR (gettext ("\
     860             : section [%2d] '%s': symbol %zu does not fit completely in referenced section [%2d] '%s'\n"),
     861             :                                idx, section_name (ebl, idx), cnt,
     862             :                                (int) xndx, section_name (ebl, xndx));
     863             :                     }
     864             :                   else
     865             :                     {
     866             :                       GElf_Phdr phdr_mem;
     867             :                       GElf_Phdr *phdr = NULL;
     868             :                       unsigned int pcnt;
     869             : 
     870           0 :                       for (pcnt = 0; pcnt < phnum; ++pcnt)
     871             :                         {
     872           0 :                           phdr = gelf_getphdr (ebl->elf, pcnt, &phdr_mem);
     873           0 :                           if (phdr != NULL && phdr->p_type == PT_TLS)
     874             :                             break;
     875             :                         }
     876             : 
     877           0 :                       if (pcnt == phnum)
     878             :                         {
     879           0 :                           if (no_pt_tls++ == 0)
     880           0 :                             ERROR (gettext ("\
     881             : section [%2d] '%s': symbol %zu: TLS symbol but no TLS program header entry\n"),
     882             :                                    idx, section_name (ebl, idx), cnt);
     883             :                         }
     884           0 :                       else if (phdr == NULL)
     885             :                         {
     886           0 :                             ERROR (gettext ("\
     887             : section [%2d] '%s': symbol %zu: TLS symbol but couldn't get TLS program header entry\n"),
     888             :                                    idx, section_name (ebl, idx), cnt);
     889             :                         }
     890           0 :                       else if (!is_debuginfo)
     891             :                         {
     892           0 :                           if (st_value
     893           0 :                               < destshdr->sh_offset - phdr->p_offset)
     894           0 :                             ERROR (gettext ("\
     895             : section [%2d] '%s': symbol %zu: st_value short of referenced section [%2d] '%s'\n"),
     896             :                                    idx, section_name (ebl, idx), cnt,
     897             :                                    (int) xndx, section_name (ebl, xndx));
     898           0 :                           else if (st_value
     899             :                                    > (destshdr->sh_offset - phdr->p_offset
     900           0 :                                       + destshdr->sh_size))
     901           0 :                             ERROR (gettext ("\
     902             : section [%2d] '%s': symbol %zu: st_value out of bounds of referenced section [%2d] '%s'\n"),
     903             :                                    idx, section_name (ebl, idx), cnt,
     904             :                                    (int) xndx, section_name (ebl, xndx));
     905           0 :                           else if (st_value + sym->st_size
     906             :                                    > (destshdr->sh_offset - phdr->p_offset
     907             :                                       + destshdr->sh_size))
     908           0 :                             ERROR (gettext ("\
     909             : section [%2d] '%s': symbol %zu does not fit completely in referenced section [%2d] '%s'\n"),
     910             :                                    idx, section_name (ebl, idx), cnt,
     911             :                                    (int) xndx, section_name (ebl, xndx));
     912             :                         }
     913             :                     }
     914             :                 }
     915             :             }
     916             :         }
     917             : 
     918           0 :       if (GELF_ST_BIND (sym->st_info) == STB_LOCAL)
     919             :         {
     920           0 :           if (cnt >= shdr->sh_info)
     921           0 :             ERROR (gettext ("\
     922             : section [%2d] '%s': symbol %zu: local symbol outside range described in sh_info\n"),
     923             :                    idx, section_name (ebl, idx), cnt);
     924             :         }
     925             :       else
     926             :         {
     927           0 :           if (cnt < shdr->sh_info)
     928           0 :             ERROR (gettext ("\
     929             : section [%2d] '%s': symbol %zu: non-local symbol outside range described in sh_info\n"),
     930             :                    idx, section_name (ebl, idx), cnt);
     931             :         }
     932             : 
     933           0 :       if (GELF_ST_TYPE (sym->st_info) == STT_SECTION
     934           0 :           && GELF_ST_BIND (sym->st_info) != STB_LOCAL)
     935           0 :         ERROR (gettext ("\
     936             : section [%2d] '%s': symbol %zu: non-local section symbol\n"),
     937             :                idx, section_name (ebl, idx), cnt);
     938             : 
     939           0 :       if (name != NULL)
     940             :         {
     941           0 :           if (strcmp (name, "_GLOBAL_OFFSET_TABLE_") == 0)
     942             :             {
     943             :               /* Check that address and size match the global offset table.  */
     944             : 
     945           0 :               GElf_Shdr destshdr_mem;
     946           0 :               GElf_Shdr *destshdr = gelf_getshdr (elf_getscn (ebl->elf, xndx),
     947             :                                                   &destshdr_mem);
     948             : 
     949           0 :               if (destshdr == NULL && xndx == SHN_ABS)
     950             :                 {
     951             :                   /* In a DSO, we have to find the GOT section by name.  */
     952             :                   Elf_Scn *gotscn = NULL;
     953             :                   Elf_Scn *gscn = NULL;
     954           0 :                   while ((gscn = elf_nextscn (ebl->elf, gscn)) != NULL)
     955             :                     {
     956           0 :                       destshdr = gelf_getshdr (gscn, &destshdr_mem);
     957           0 :                       assert (destshdr != NULL);
     958           0 :                       const char *sname = elf_strptr (ebl->elf,
     959             :                                                       shstrndx,
     960           0 :                                                       destshdr->sh_name);
     961           0 :                       if (sname != NULL)
     962             :                         {
     963           0 :                           if (strcmp (sname, ".got.plt") == 0)
     964             :                             break;
     965           0 :                           if (strcmp (sname, ".got") == 0)
     966             :                             /* Do not stop looking.
     967             :                                There might be a .got.plt section.  */
     968           0 :                             gotscn = gscn;
     969             :                         }
     970             : 
     971             :                       destshdr = NULL;
     972             :                     }
     973             : 
     974           0 :                   if (destshdr == NULL && gotscn != NULL)
     975           0 :                     destshdr = gelf_getshdr (gotscn, &destshdr_mem);
     976             :                 }
     977             : 
     978           0 :               const char *sname = ((destshdr == NULL || xndx == SHN_UNDEF)
     979             :                                    ? NULL
     980           0 :                                    : elf_strptr (ebl->elf, shstrndx,
     981           0 :                                                  destshdr->sh_name));
     982           0 :               if (sname == NULL)
     983             :                 {
     984           0 :                   if (xndx != SHN_UNDEF || ehdr->e_type != ET_REL)
     985           0 :                     ERROR (gettext ("\
     986             : section [%2d] '%s': _GLOBAL_OFFSET_TABLE_ symbol refers to \
     987             : bad section [%2d]\n"),
     988             :                            idx, section_name (ebl, idx), xndx);
     989             :                 }
     990           0 :               else if (strcmp (sname, ".got.plt") != 0
     991           0 :                        && strcmp (sname, ".got") != 0)
     992           0 :                 ERROR (gettext ("\
     993             : section [%2d] '%s': _GLOBAL_OFFSET_TABLE_ symbol refers to \
     994             : section [%2d] '%s'\n"),
     995             :                        idx, section_name (ebl, idx), xndx, sname);
     996             : 
     997           0 :               if (destshdr != NULL)
     998             :                 {
     999             :                   /* Found it.  */
    1000           0 :                   if (!ebl_check_special_symbol (ebl, sym, name,
    1001             :                                                  destshdr))
    1002             :                     {
    1003           0 :                       if (ehdr->e_type != ET_REL
    1004           0 :                           && sym->st_value != destshdr->sh_addr)
    1005             :                         /* This test is more strict than the psABIs which
    1006             :                            usually allow the symbol to be in the middle of
    1007             :                            the .got section, allowing negative offsets.  */
    1008           0 :                         ERROR (gettext ("\
    1009             : section [%2d] '%s': _GLOBAL_OFFSET_TABLE_ symbol value %#" PRIx64 " does not match %s section address %#" PRIx64 "\n"),
    1010             :                                idx, section_name (ebl, idx),
    1011             :                                (uint64_t) sym->st_value,
    1012             :                                sname, (uint64_t) destshdr->sh_addr);
    1013             : 
    1014           0 :                       if (!gnuld && sym->st_size != destshdr->sh_size)
    1015           0 :                         ERROR (gettext ("\
    1016             : section [%2d] '%s': _GLOBAL_OFFSET_TABLE_ symbol size %" PRIu64 " does not match %s section size %" PRIu64 "\n"),
    1017             :                                idx, section_name (ebl, idx),
    1018             :                                (uint64_t) sym->st_size,
    1019             :                                sname, (uint64_t) destshdr->sh_size);
    1020             :                     }
    1021             :                 }
    1022             :               else
    1023           0 :                 ERROR (gettext ("\
    1024             : section [%2d] '%s': _GLOBAL_OFFSET_TABLE_ symbol present, but no .got section\n"),
    1025             :                        idx, section_name (ebl, idx));
    1026             :             }
    1027           0 :           else if (strcmp (name, "_DYNAMIC") == 0)
    1028             :             /* Check that address and size match the dynamic section.
    1029             :                We locate the dynamic section via the program header
    1030             :                entry.  */
    1031           0 :             for (unsigned int pcnt = 0; pcnt < phnum; ++pcnt)
    1032             :               {
    1033           0 :                 GElf_Phdr phdr_mem;
    1034           0 :                 GElf_Phdr *phdr = gelf_getphdr (ebl->elf, pcnt, &phdr_mem);
    1035             : 
    1036           0 :                 if (phdr != NULL && phdr->p_type == PT_DYNAMIC)
    1037             :                   {
    1038           0 :                     if (sym->st_value != phdr->p_vaddr)
    1039           0 :                       ERROR (gettext ("\
    1040             : section [%2d] '%s': _DYNAMIC_ symbol value %#" PRIx64 " does not match dynamic segment address %#" PRIx64 "\n"),
    1041             :                              idx, section_name (ebl, idx),
    1042             :                              (uint64_t) sym->st_value,
    1043             :                              (uint64_t) phdr->p_vaddr);
    1044             : 
    1045           0 :                     if (!gnuld && sym->st_size != phdr->p_memsz)
    1046           0 :                       ERROR (gettext ("\
    1047             : section [%2d] '%s': _DYNAMIC symbol size %" PRIu64 " does not match dynamic segment size %" PRIu64 "\n"),
    1048             :                              idx, section_name (ebl, idx),
    1049             :                              (uint64_t) sym->st_size,
    1050             :                              (uint64_t) phdr->p_memsz);
    1051             : 
    1052           0 :                     break;
    1053             :                   }
    1054             :             }
    1055             :         }
    1056             : 
    1057           0 :       if (GELF_ST_VISIBILITY (sym->st_other) != STV_DEFAULT
    1058           0 :           && shdr->sh_type == SHT_DYNSYM)
    1059           0 :         ERROR (gettext ("\
    1060             : section [%2d] '%s': symbol %zu: symbol in dynamic symbol table with non-default visibility\n"),
    1061             :                idx, section_name (ebl, idx), cnt);
    1062           0 :       if (! ebl_check_st_other_bits (ebl, sym->st_other))
    1063           0 :         ERROR (gettext ("\
    1064             : section [%2d] '%s': symbol %zu: unknown bit set in st_other\n"),
    1065             :                idx, section_name (ebl, idx), cnt);
    1066             : 
    1067             :     }
    1068             : }
    1069             : 
    1070             : 
    1071             : static bool
    1072           0 : is_rel_dyn (Ebl *ebl, const GElf_Ehdr *ehdr, int idx, const GElf_Shdr *shdr,
    1073             :             bool is_rela)
    1074             : {
    1075             :   /* If this is no executable or DSO it cannot be a .rel.dyn section.  */
    1076           0 :   if (ehdr->e_type != ET_EXEC && ehdr->e_type != ET_DYN)
    1077             :     return false;
    1078             : 
    1079             :   /* Check the section name.  Unfortunately necessary.  */
    1080           0 :   if (strcmp (section_name (ebl, idx), is_rela ? ".rela.dyn" : ".rel.dyn"))
    1081             :     return false;
    1082             : 
    1083             :   /* When a .rel.dyn section is used a DT_RELCOUNT dynamic section
    1084             :      entry can be present as well.  */
    1085             :   Elf_Scn *scn = NULL;
    1086           0 :   while ((scn = elf_nextscn (ebl->elf, scn)) != NULL)
    1087             :     {
    1088           0 :       GElf_Shdr rcshdr_mem;
    1089           0 :       const GElf_Shdr *rcshdr = gelf_getshdr (scn, &rcshdr_mem);
    1090             : 
    1091           0 :       if (rcshdr == NULL)
    1092             :         break;
    1093             : 
    1094           0 :       if (rcshdr->sh_type == SHT_DYNAMIC && rcshdr->sh_entsize != 0)
    1095             :         {
    1096             :           /* Found the dynamic section.  Look through it.  */
    1097           0 :           Elf_Data *d = elf_getdata (scn, NULL);
    1098           0 :           size_t cnt;
    1099             : 
    1100           0 :           if (d == NULL)
    1101           0 :             ERROR (gettext ("\
    1102             : section [%2d] '%s': cannot get section data.\n"),
    1103             :                    idx, section_name (ebl, idx));
    1104             : 
    1105           0 :           for (cnt = 1; cnt < rcshdr->sh_size / rcshdr->sh_entsize; ++cnt)
    1106             :             {
    1107           0 :               GElf_Dyn dyn_mem;
    1108           0 :               GElf_Dyn *dyn = gelf_getdyn (d, cnt, &dyn_mem);
    1109             : 
    1110           0 :               if (dyn == NULL)
    1111             :                 break;
    1112             : 
    1113           0 :               if (dyn->d_tag == DT_RELCOUNT)
    1114             :                 {
    1115             :                   /* Found it.  Does the type match.  */
    1116           0 :                   if (is_rela)
    1117           0 :                     ERROR (gettext ("\
    1118             : section [%2d] '%s': DT_RELCOUNT used for this RELA section\n"),
    1119             :                            idx, section_name (ebl, idx));
    1120             :                   else
    1121             :                     {
    1122             :                       /* Does the number specified number of relative
    1123             :                          relocations exceed the total number of
    1124             :                          relocations?  */
    1125           0 :                       if (shdr->sh_entsize != 0
    1126           0 :                           && dyn->d_un.d_val > (shdr->sh_size
    1127           0 :                                                 / shdr->sh_entsize))
    1128           0 :                         ERROR (gettext ("\
    1129             : section [%2d] '%s': DT_RELCOUNT value %d too high for this section\n"),
    1130             :                                idx, section_name (ebl, idx),
    1131             :                                (int) dyn->d_un.d_val);
    1132             : 
    1133             :                       /* Make sure the specified number of relocations are
    1134             :                          relative.  */
    1135           0 :                       Elf_Data *reldata = elf_getdata (elf_getscn (ebl->elf,
    1136             :                                                                    idx), NULL);
    1137           0 :                       if (reldata != NULL && shdr->sh_entsize != 0)
    1138           0 :                         for (size_t inner = 0;
    1139           0 :                              inner < shdr->sh_size / shdr->sh_entsize;
    1140           0 :                              ++inner)
    1141             :                           {
    1142           0 :                             GElf_Rel rel_mem;
    1143           0 :                             GElf_Rel *rel = gelf_getrel (reldata, inner,
    1144             :                                                          &rel_mem);
    1145           0 :                             if (rel == NULL)
    1146             :                               /* The problem will be reported elsewhere.  */
    1147             :                               break;
    1148             : 
    1149           0 :                             if (ebl_relative_reloc_p (ebl,
    1150           0 :                                                       GELF_R_TYPE (rel->r_info)))
    1151             :                               {
    1152           0 :                                 if (inner >= dyn->d_un.d_val)
    1153           0 :                                   ERROR (gettext ("\
    1154             : section [%2d] '%s': relative relocations after index %d as specified by DT_RELCOUNT\n"),
    1155             :                                          idx, section_name (ebl, idx),
    1156             :                                          (int) dyn->d_un.d_val);
    1157             :                               }
    1158           0 :                             else if (inner < dyn->d_un.d_val)
    1159           0 :                               ERROR (gettext ("\
    1160             : section [%2d] '%s': non-relative relocation at index %zu; DT_RELCOUNT specified %d relative relocations\n"),
    1161             :                                      idx, section_name (ebl, idx),
    1162             :                                      inner, (int) dyn->d_un.d_val);
    1163             :                           }
    1164             :                     }
    1165             :                 }
    1166             : 
    1167           0 :               if (dyn->d_tag == DT_RELACOUNT)
    1168             :                 {
    1169             :                   /* Found it.  Does the type match.  */
    1170           0 :                   if (!is_rela)
    1171           0 :                     ERROR (gettext ("\
    1172             : section [%2d] '%s': DT_RELACOUNT used for this REL section\n"),
    1173             :                            idx, section_name (ebl, idx));
    1174             :                   else
    1175             :                     {
    1176             :                       /* Does the number specified number of relative
    1177             :                          relocations exceed the total number of
    1178             :                          relocations?  */
    1179           0 :                       if (shdr->sh_entsize != 0
    1180           0 :                           && dyn->d_un.d_val > shdr->sh_size / shdr->sh_entsize)
    1181           0 :                         ERROR (gettext ("\
    1182             : section [%2d] '%s': DT_RELCOUNT value %d too high for this section\n"),
    1183             :                                idx, section_name (ebl, idx),
    1184             :                                (int) dyn->d_un.d_val);
    1185             : 
    1186             :                       /* Make sure the specified number of relocations are
    1187             :                          relative.  */
    1188           0 :                       Elf_Data *reldata = elf_getdata (elf_getscn (ebl->elf,
    1189             :                                                                    idx), NULL);
    1190           0 :                       if (reldata != NULL && shdr->sh_entsize != 0)
    1191           0 :                         for (size_t inner = 0;
    1192           0 :                              inner < shdr->sh_size / shdr->sh_entsize;
    1193           0 :                              ++inner)
    1194             :                           {
    1195           0 :                             GElf_Rela rela_mem;
    1196           0 :                             GElf_Rela *rela = gelf_getrela (reldata, inner,
    1197             :                                                             &rela_mem);
    1198           0 :                             if (rela == NULL)
    1199             :                               /* The problem will be reported elsewhere.  */
    1200             :                               break;
    1201             : 
    1202           0 :                             if (ebl_relative_reloc_p (ebl,
    1203           0 :                                                       GELF_R_TYPE (rela->r_info)))
    1204             :                               {
    1205           0 :                                 if (inner >= dyn->d_un.d_val)
    1206           0 :                                   ERROR (gettext ("\
    1207             : section [%2d] '%s': relative relocations after index %d as specified by DT_RELCOUNT\n"),
    1208             :                                          idx, section_name (ebl, idx),
    1209             :                                          (int) dyn->d_un.d_val);
    1210             :                               }
    1211           0 :                             else if (inner < dyn->d_un.d_val)
    1212           0 :                               ERROR (gettext ("\
    1213             : section [%2d] '%s': non-relative relocation at index %zu; DT_RELCOUNT specified %d relative relocations\n"),
    1214             :                                      idx, section_name (ebl, idx),
    1215             :                                      inner, (int) dyn->d_un.d_val);
    1216             :                           }
    1217             :                     }
    1218             :                 }
    1219             :             }
    1220             : 
    1221             :           break;
    1222             :         }
    1223             :     }
    1224             : 
    1225             :   return true;
    1226             : }
    1227             : 
    1228             : 
    1229             : struct loaded_segment
    1230             : {
    1231             :   GElf_Addr from;
    1232             :   GElf_Addr to;
    1233             :   bool read_only;
    1234             :   struct loaded_segment *next;
    1235             : };
    1236             : 
    1237             : 
    1238             : /* Check whether binary has text relocation flag set.  */
    1239             : static bool textrel;
    1240             : 
    1241             : /* Keep track of whether text relocation flag is needed.  */
    1242             : static bool needed_textrel;
    1243             : 
    1244             : 
    1245             : static bool
    1246         413 : check_reloc_shdr (Ebl *ebl, const GElf_Ehdr *ehdr, const GElf_Shdr *shdr,
    1247             :                   int idx, int reltype, GElf_Shdr **destshdrp,
    1248             :                   GElf_Shdr *destshdr_memp, struct loaded_segment **loadedp)
    1249             : {
    1250         413 :   bool reldyn = false;
    1251             : 
    1252             :   /* Check whether the link to the section we relocate is reasonable.  */
    1253         413 :   if (shdr->sh_info >= shnum)
    1254           0 :     ERROR (gettext ("section [%2d] '%s': invalid destination section index\n"),
    1255             :            idx, section_name (ebl, idx));
    1256         413 :   else if (shdr->sh_info != 0)
    1257             :     {
    1258         343 :       *destshdrp = gelf_getshdr (elf_getscn (ebl->elf, shdr->sh_info),
    1259             :                                  destshdr_memp);
    1260         343 :       if (*destshdrp != NULL)
    1261             :         {
    1262         343 :           if(! ebl_check_reloc_target_type (ebl, (*destshdrp)->sh_type))
    1263             :             {
    1264           0 :               reldyn = is_rel_dyn (ebl, ehdr, idx, shdr, true);
    1265           0 :               if (!reldyn)
    1266           0 :                 ERROR (gettext ("\
    1267             : section [%2d] '%s': invalid destination section type\n"),
    1268             :                        idx, section_name (ebl, idx));
    1269             :               else
    1270             :                 {
    1271             :                   /* There is no standard, but we require that .rel{,a}.dyn
    1272             :                      sections have a sh_info value of zero.  */
    1273           0 :                   if (shdr->sh_info != 0)
    1274           0 :                     ERROR (gettext ("\
    1275             : section [%2d] '%s': sh_info should be zero\n"),
    1276             :                            idx, section_name (ebl, idx));
    1277             :                 }
    1278             :             }
    1279             : 
    1280         686 :           if ((((*destshdrp)->sh_flags & SHF_MERGE) != 0)
    1281         343 :               && ((*destshdrp)->sh_flags & SHF_STRINGS) != 0)
    1282           0 :             ERROR (gettext ("\
    1283             : section [%2d] '%s': no relocations for merge-able string sections possible\n"),
    1284             :                    idx, section_name (ebl, idx));
    1285             :         }
    1286             :     }
    1287             : 
    1288         413 :   size_t sh_entsize = gelf_fsize (ebl->elf, reltype, 1, EV_CURRENT);
    1289         413 :   if (shdr->sh_entsize != sh_entsize)
    1290           0 :     ERROR (gettext (reltype == ELF_T_RELA ? "\
    1291             : section [%2d] '%s': section entry size does not match ElfXX_Rela\n" : "\
    1292             : section [%2d] '%s': section entry size does not match ElfXX_Rel\n"),
    1293             :            idx, section_name (ebl, idx));
    1294             : 
    1295             :   /* In preparation of checking whether relocations are text
    1296             :      relocations or not we need to determine whether the file is
    1297             :      flagged to have text relocation and we need to determine a) what
    1298             :      the loaded segments are and b) which are read-only.  This will
    1299             :      also allow us to determine whether the same reloc section is
    1300             :      modifying loaded and not loaded segments.  */
    1301        1893 :   for (unsigned int i = 0; i < phnum; ++i)
    1302             :     {
    1303        1480 :       GElf_Phdr phdr_mem;
    1304        1480 :       GElf_Phdr *phdr = gelf_getphdr (ebl->elf, i, &phdr_mem);
    1305        1480 :       if (phdr == NULL)
    1306           0 :         continue;
    1307             : 
    1308        1480 :       if (phdr->p_type == PT_LOAD)
    1309             :         {
    1310         465 :           struct loaded_segment *newp = xmalloc (sizeof (*newp));
    1311         465 :           newp->from = phdr->p_vaddr;
    1312         465 :           newp->to = phdr->p_vaddr + phdr->p_memsz;
    1313         465 :           newp->read_only = (phdr->p_flags & PF_W) == 0;
    1314         465 :           newp->next = *loadedp;
    1315         465 :           *loadedp = newp;
    1316             :         }
    1317        1015 :       else if (phdr->p_type == PT_DYNAMIC)
    1318             :         {
    1319         177 :           Elf_Scn *dynscn = gelf_offscn (ebl->elf, phdr->p_offset);
    1320         177 :           GElf_Shdr dynshdr_mem;
    1321         177 :           GElf_Shdr *dynshdr = gelf_getshdr (dynscn, &dynshdr_mem);
    1322         177 :           Elf_Data *dyndata = elf_getdata (dynscn, NULL);
    1323         177 :           if (dynshdr != NULL && dynshdr->sh_type == SHT_DYNAMIC
    1324         177 :               && dyndata != NULL && dynshdr->sh_entsize != 0)
    1325        5164 :             for (size_t j = 0; j < dynshdr->sh_size / dynshdr->sh_entsize; ++j)
    1326             :               {
    1327        4987 :                 GElf_Dyn dyn_mem;
    1328        4987 :                 GElf_Dyn *dyn = gelf_getdyn (dyndata, j, &dyn_mem);
    1329        4987 :                 if (dyn != NULL
    1330        4987 :                     && (dyn->d_tag == DT_TEXTREL
    1331        4987 :                         || (dyn->d_tag == DT_FLAGS
    1332           0 :                             && (dyn->d_un.d_val & DF_TEXTREL) != 0)))
    1333             :                   {
    1334           0 :                     textrel = true;
    1335           0 :                     break;
    1336             :                   }
    1337             :               }
    1338             :         }
    1339             :     }
    1340             : 
    1341             :   /* A quick test which can be easily done here (although it is a bit
    1342             :      out of place): the text relocation flag makes only sense if there
    1343             :      is a segment which is not writable.  */
    1344         413 :   if (textrel)
    1345             :     {
    1346           0 :       struct loaded_segment *seg = *loadedp;
    1347           0 :       while (seg != NULL && !seg->read_only)
    1348           0 :         seg = seg->next;
    1349           0 :       if (seg == NULL)
    1350           0 :         ERROR (gettext ("\
    1351             : text relocation flag set but there is no read-only segment\n"));
    1352             :     }
    1353             : 
    1354         413 :   return reldyn;
    1355             : }
    1356             : 
    1357             : 
    1358             : enum load_state
    1359             :   {
    1360             :     state_undecided,
    1361             :     state_loaded,
    1362             :     state_unloaded,
    1363             :     state_error
    1364             :   };
    1365             : 
    1366             : 
    1367             : static void
    1368      159557 : check_one_reloc (Ebl *ebl, GElf_Ehdr *ehdr, GElf_Shdr *relshdr, int idx,
    1369             :                  size_t cnt, const GElf_Shdr *symshdr, Elf_Data *symdata,
    1370             :                  GElf_Addr r_offset, GElf_Xword r_info,
    1371             :                  const GElf_Shdr *destshdr, bool reldyn,
    1372             :                  struct loaded_segment *loaded, enum load_state *statep)
    1373             : {
    1374      159557 :   bool known_broken = gnuld;
    1375             : 
    1376      159557 :   if (!ebl_reloc_type_check (ebl, GELF_R_TYPE (r_info)))
    1377           0 :     ERROR (gettext ("section [%2d] '%s': relocation %zu: invalid type\n"),
    1378             :            idx, section_name (ebl, idx), cnt);
    1379      159557 :   else if (((ehdr->e_type != ET_EXEC && ehdr->e_type != ET_DYN)
    1380             :             /* The executable/DSO can contain relocation sections with
    1381             :                all the relocations the linker has applied.  Those sections
    1382             :                are marked non-loaded, though.  */
    1383       96567 :             || (relshdr->sh_flags & SHF_ALLOC) != 0)
    1384      159557 :            && !ebl_reloc_valid_use (ebl, GELF_R_TYPE (r_info)))
    1385           0 :     ERROR (gettext ("\
    1386             : section [%2d] '%s': relocation %zu: relocation type invalid for the file type\n"),
    1387             :            idx, section_name (ebl, idx), cnt);
    1388             : 
    1389      159557 :   if (symshdr != NULL
    1390      319114 :       && ((GELF_R_SYM (r_info) + 1)
    1391      159557 :           * gelf_fsize (ebl->elf, ELF_T_SYM, 1, EV_CURRENT)
    1392      159557 :           > symshdr->sh_size))
    1393           0 :     ERROR (gettext ("\
    1394             : section [%2d] '%s': relocation %zu: invalid symbol index\n"),
    1395             :            idx, section_name (ebl, idx), cnt);
    1396             : 
    1397             :   /* No more tests if this is a no-op relocation.  */
    1398      159557 :   if (ebl_none_reloc_p (ebl, GELF_R_TYPE (r_info)))
    1399           2 :     return;
    1400             : 
    1401      159555 :   if (ebl_gotpc_reloc_check (ebl, GELF_R_TYPE (r_info)))
    1402             :     {
    1403           0 :       const char *name;
    1404           0 :       char buf[64];
    1405           0 :       GElf_Sym sym_mem;
    1406           0 :       GElf_Sym *sym = gelf_getsym (symdata, GELF_R_SYM (r_info), &sym_mem);
    1407           0 :       if (sym != NULL
    1408             :           /* Get the name for the symbol.  */
    1409           0 :           && (name = elf_strptr (ebl->elf, symshdr->sh_link, sym->st_name))
    1410           0 :           && strcmp (name, "_GLOBAL_OFFSET_TABLE_") !=0 )
    1411           0 :         ERROR (gettext ("\
    1412             : section [%2d] '%s': relocation %zu: only symbol '_GLOBAL_OFFSET_TABLE_' can be used with %s\n"),
    1413             :                idx, section_name (ebl, idx), cnt,
    1414             :                ebl_reloc_type_name (ebl, GELF_R_SYM (r_info),
    1415             :                                     buf, sizeof (buf)));
    1416             :     }
    1417             : 
    1418      159555 :   if (reldyn)
    1419             :     {
    1420             :       // XXX TODO Check .rel.dyn section addresses.
    1421             :     }
    1422      159555 :   else if (!known_broken)
    1423             :     {
    1424         192 :       if (destshdr != NULL
    1425         186 :           && GELF_R_TYPE (r_info) != 0
    1426         558 :           && (r_offset - (ehdr->e_type == ET_REL ? 0
    1427         186 :                           : destshdr->sh_addr)) >= destshdr->sh_size)
    1428           0 :         ERROR (gettext ("\
    1429             : section [%2d] '%s': relocation %zu: offset out of bounds\n"),
    1430             :                idx, section_name (ebl, idx), cnt);
    1431             :     }
    1432             : 
    1433      159555 :   GElf_Sym sym_mem;
    1434      159555 :   GElf_Sym *sym = gelf_getsym (symdata, GELF_R_SYM (r_info), &sym_mem);
    1435             : 
    1436      159555 :   if (ebl_copy_reloc_p (ebl, GELF_R_TYPE (r_info))
    1437             :       /* Make sure the referenced symbol is an object or unspecified.  */
    1438          67 :       && sym != NULL
    1439          67 :       && GELF_ST_TYPE (sym->st_info) != STT_NOTYPE
    1440          67 :       && GELF_ST_TYPE (sym->st_info) != STT_OBJECT)
    1441             :     {
    1442           1 :       char buf[64];
    1443           1 :       ERROR (gettext ("section [%2d] '%s': relocation %zu: copy relocation against symbol of type %s\n"),
    1444             :              idx, section_name (ebl, idx), cnt,
    1445             :              ebl_symbol_type_name (ebl, GELF_ST_TYPE (sym->st_info),
    1446             :                                    buf, sizeof (buf)));
    1447             :     }
    1448             : 
    1449      159555 :   if ((ehdr->e_type != ET_EXEC && ehdr->e_type != ET_DYN)
    1450       96565 :       || (relshdr->sh_flags & SHF_ALLOC) != 0)
    1451             :     {
    1452             :       bool in_loaded_seg = false;
    1453      543797 :       while (loaded != NULL)
    1454             :         {
    1455      384242 :           if (r_offset < loaded->to
    1456       96565 :               && r_offset + (sym == NULL ? 0 : sym->st_size) >= loaded->from)
    1457             :             {
    1458             :               /* The symbol is in this segment.  */
    1459       96565 :               if  (loaded->read_only)
    1460             :                 {
    1461           0 :                   if (textrel)
    1462           0 :                     needed_textrel = true;
    1463             :                   else
    1464           0 :                     ERROR (gettext ("section [%2d] '%s': relocation %zu: read-only section modified but text relocation flag not set\n"),
    1465             :                            idx, section_name (ebl, idx), cnt);
    1466             :                 }
    1467             : 
    1468             :               in_loaded_seg = true;
    1469             :             }
    1470             : 
    1471      384242 :           loaded = loaded->next;
    1472             :         }
    1473             : 
    1474      159555 :       if (*statep == state_undecided)
    1475         648 :         *statep = in_loaded_seg ? state_loaded : state_unloaded;
    1476      159143 :       else if ((*statep == state_unloaded && in_loaded_seg)
    1477      159143 :                || (*statep == state_loaded && !in_loaded_seg))
    1478             :         {
    1479           0 :           ERROR (gettext ("\
    1480             : section [%2d] '%s': relocations are against loaded and unloaded data\n"),
    1481             :                  idx, section_name (ebl, idx));
    1482           0 :           *statep = state_error;
    1483             :         }
    1484             :     }
    1485             : }
    1486             : 
    1487             : 
    1488             : static void
    1489         360 : check_rela (Ebl *ebl, GElf_Ehdr *ehdr, GElf_Shdr *shdr, int idx)
    1490             : {
    1491         360 :   Elf_Data *data = elf_getdata (elf_getscn (ebl->elf, idx), NULL);
    1492         360 :   if (data == NULL)
    1493             :     {
    1494           0 :       ERROR (gettext ("section [%2d] '%s': cannot get section data\n"),
    1495             :              idx, section_name (ebl, idx));
    1496           0 :       return;
    1497             :     }
    1498             : 
    1499             :   /* Check the fields of the section header.  */
    1500         360 :   GElf_Shdr destshdr_mem;
    1501         360 :   GElf_Shdr *destshdr = NULL;
    1502         360 :   struct loaded_segment *loaded = NULL;
    1503         360 :   bool reldyn = check_reloc_shdr (ebl, ehdr, shdr, idx, ELF_T_RELA, &destshdr,
    1504             :                                   &destshdr_mem, &loaded);
    1505             : 
    1506         360 :   Elf_Scn *symscn = elf_getscn (ebl->elf, shdr->sh_link);
    1507         360 :   GElf_Shdr symshdr_mem;
    1508         360 :   GElf_Shdr *symshdr = gelf_getshdr (symscn, &symshdr_mem);
    1509         360 :   Elf_Data *symdata = elf_getdata (symscn, NULL);
    1510         360 :   enum load_state state = state_undecided;
    1511             : 
    1512         360 :   size_t sh_entsize = gelf_fsize (ebl->elf, ELF_T_RELA, 1, EV_CURRENT);
    1513      156261 :   for (size_t cnt = 0; cnt < shdr->sh_size / sh_entsize; ++cnt)
    1514             :     {
    1515      155901 :       GElf_Rela rela_mem;
    1516      155901 :       GElf_Rela *rela = gelf_getrela (data, cnt, &rela_mem);
    1517      155901 :       if (rela == NULL)
    1518             :         {
    1519           0 :           ERROR (gettext ("\
    1520             : section [%2d] '%s': cannot get relocation %zu: %s\n"),
    1521             :                  idx, section_name (ebl, idx), cnt, elf_errmsg (-1));
    1522           0 :           continue;
    1523             :         }
    1524             : 
    1525      155901 :       check_one_reloc (ebl, ehdr, shdr, idx, cnt, symshdr, symdata,
    1526             :                        rela->r_offset, rela->r_info, destshdr, reldyn, loaded,
    1527             :                        &state);
    1528             :     }
    1529             : 
    1530         753 :   while (loaded != NULL)
    1531             :     {
    1532         393 :       struct loaded_segment *old = loaded;
    1533         393 :       loaded = loaded->next;
    1534         393 :       free (old);
    1535             :     }
    1536             : }
    1537             : 
    1538             : 
    1539             : static void
    1540          53 : check_rel (Ebl *ebl, GElf_Ehdr *ehdr, GElf_Shdr *shdr, int idx)
    1541             : {
    1542          53 :   Elf_Data *data = elf_getdata (elf_getscn (ebl->elf, idx), NULL);
    1543          53 :   if (data == NULL)
    1544             :     {
    1545           0 :       ERROR (gettext ("section [%2d] '%s': cannot get section data\n"),
    1546             :              idx, section_name (ebl, idx));
    1547           0 :       return;
    1548             :     }
    1549             : 
    1550             :   /* Check the fields of the section header.  */
    1551          53 :   GElf_Shdr destshdr_mem;
    1552          53 :   GElf_Shdr *destshdr = NULL;
    1553          53 :   struct loaded_segment *loaded = NULL;
    1554          53 :   bool reldyn = check_reloc_shdr (ebl, ehdr, shdr, idx, ELF_T_REL, &destshdr,
    1555             :                                   &destshdr_mem, &loaded);
    1556             : 
    1557          53 :   Elf_Scn *symscn = elf_getscn (ebl->elf, shdr->sh_link);
    1558          53 :   GElf_Shdr symshdr_mem;
    1559          53 :   GElf_Shdr *symshdr = gelf_getshdr (symscn, &symshdr_mem);
    1560          53 :   Elf_Data *symdata = elf_getdata (symscn, NULL);
    1561          53 :   enum load_state state = state_undecided;
    1562             : 
    1563          53 :   size_t sh_entsize = gelf_fsize (ebl->elf, ELF_T_REL, 1, EV_CURRENT);
    1564        3709 :   for (size_t cnt = 0; cnt < shdr->sh_size / sh_entsize; ++cnt)
    1565             :     {
    1566        3656 :       GElf_Rel rel_mem;
    1567        3656 :       GElf_Rel *rel = gelf_getrel (data, cnt, &rel_mem);
    1568        3656 :       if (rel == NULL)
    1569             :         {
    1570           0 :           ERROR (gettext ("\
    1571             : section [%2d] '%s': cannot get relocation %zu: %s\n"),
    1572             :                  idx, section_name (ebl, idx), cnt, elf_errmsg (-1));
    1573           0 :           continue;
    1574             :         }
    1575             : 
    1576        3656 :       check_one_reloc (ebl, ehdr, shdr, idx, cnt, symshdr, symdata,
    1577             :                        rel->r_offset, rel->r_info, destshdr, reldyn, loaded,
    1578             :                        &state);
    1579             :     }
    1580             : 
    1581         125 :   while (loaded != NULL)
    1582             :     {
    1583          72 :       struct loaded_segment *old = loaded;
    1584          72 :       loaded = loaded->next;
    1585          72 :       free (old);
    1586             :     }
    1587             : }
    1588             : 
    1589             : 
    1590             : /* Number of dynamic sections.  */
    1591             : static int ndynamic;
    1592             : 
    1593             : 
    1594             : static void
    1595           0 : check_dynamic (Ebl *ebl, GElf_Ehdr *ehdr, GElf_Shdr *shdr, int idx)
    1596             : {
    1597           0 :   Elf_Data *data;
    1598           0 :   GElf_Shdr strshdr_mem;
    1599           0 :   GElf_Shdr *strshdr;
    1600           0 :   size_t cnt;
    1601           0 :   static const bool dependencies[DT_NUM][DT_NUM] =
    1602             :     {
    1603             :       [DT_NEEDED] = { [DT_STRTAB] = true },
    1604             :       [DT_PLTRELSZ] = { [DT_JMPREL] = true },
    1605             :       [DT_HASH] = { [DT_SYMTAB] = true },
    1606             :       [DT_STRTAB] = { [DT_STRSZ] = true },
    1607             :       [DT_SYMTAB] = { [DT_STRTAB] = true, [DT_SYMENT] = true },
    1608             :       [DT_RELA] = { [DT_RELASZ] = true, [DT_RELAENT] = true },
    1609             :       [DT_RELASZ] = { [DT_RELA] = true },
    1610             :       [DT_RELAENT] = { [DT_RELA] = true },
    1611             :       [DT_STRSZ] = { [DT_STRTAB] = true },
    1612             :       [DT_SYMENT] = { [DT_SYMTAB] = true },
    1613             :       [DT_SONAME] = { [DT_STRTAB] = true },
    1614             :       [DT_RPATH] = { [DT_STRTAB] = true },
    1615             :       [DT_REL] = { [DT_RELSZ] = true, [DT_RELENT] = true },
    1616             :       [DT_RELSZ] = { [DT_REL] = true },
    1617             :       [DT_RELENT] = { [DT_REL] = true },
    1618             :       [DT_JMPREL] = { [DT_PLTRELSZ] = true, [DT_PLTREL] = true },
    1619             :       [DT_RUNPATH] = { [DT_STRTAB] = true },
    1620             :       [DT_PLTREL] = { [DT_JMPREL] = true },
    1621             :     };
    1622           0 :   bool has_dt[DT_NUM];
    1623           0 :   bool has_val_dt[DT_VALNUM];
    1624           0 :   bool has_addr_dt[DT_ADDRNUM];
    1625           0 :   static const bool level2[DT_NUM] =
    1626             :     {
    1627             :       [DT_RPATH] = true,
    1628             :       [DT_SYMBOLIC] = true,
    1629             :       [DT_TEXTREL] = true,
    1630             :       [DT_BIND_NOW] = true
    1631             :     };
    1632           0 :   static const bool mandatory[DT_NUM] =
    1633             :     {
    1634             :       [DT_NULL] = true,
    1635             :       [DT_STRTAB] = true,
    1636             :       [DT_SYMTAB] = true,
    1637             :       [DT_STRSZ] = true,
    1638             :       [DT_SYMENT] = true
    1639             :     };
    1640             : 
    1641           0 :   memset (has_dt, '\0', sizeof (has_dt));
    1642           0 :   memset (has_val_dt, '\0', sizeof (has_val_dt));
    1643           0 :   memset (has_addr_dt, '\0', sizeof (has_addr_dt));
    1644             : 
    1645           0 :   if (++ndynamic == 2)
    1646           0 :     ERROR (gettext ("more than one dynamic section present\n"));
    1647             : 
    1648           0 :   data = elf_getdata (elf_getscn (ebl->elf, idx), NULL);
    1649           0 :   if (data == NULL)
    1650             :     {
    1651           0 :       ERROR (gettext ("section [%2d] '%s': cannot get section data\n"),
    1652             :              idx, section_name (ebl, idx));
    1653           0 :       return;
    1654             :     }
    1655             : 
    1656           0 :   strshdr = gelf_getshdr (elf_getscn (ebl->elf, shdr->sh_link), &strshdr_mem);
    1657           0 :   if (strshdr != NULL && strshdr->sh_type != SHT_STRTAB)
    1658           0 :     ERROR (gettext ("\
    1659             : section [%2d] '%s': referenced as string table for section [%2d] '%s' but type is not SHT_STRTAB\n"),
    1660             :            shdr->sh_link, section_name (ebl, shdr->sh_link),
    1661             :            idx, section_name (ebl, idx));
    1662           0 :   else if (strshdr == NULL)
    1663             :     {
    1664           0 :       ERROR (gettext ("\
    1665             : section [%2d]: referenced as string table for section [%2d] '%s' but section link value is invalid\n"),
    1666             :            shdr->sh_link, idx, section_name (ebl, idx));
    1667           0 :       return;
    1668             :     }
    1669             : 
    1670           0 :   size_t sh_entsize = gelf_fsize (ebl->elf, ELF_T_DYN, 1, EV_CURRENT);
    1671           0 :   if (shdr->sh_entsize != sh_entsize)
    1672           0 :     ERROR (gettext ("\
    1673             : section [%2d] '%s': section entry size does not match ElfXX_Dyn\n"),
    1674             :            idx, section_name (ebl, idx));
    1675             : 
    1676           0 :   if (shdr->sh_info != 0)
    1677           0 :     ERROR (gettext ("section [%2d] '%s': sh_info not zero\n"),
    1678             :            idx, section_name (ebl, idx));
    1679             : 
    1680             :   bool non_null_warned = false;
    1681           0 :   for (cnt = 0; cnt < shdr->sh_size / sh_entsize; ++cnt)
    1682             :     {
    1683           0 :       GElf_Dyn dyn_mem;
    1684           0 :       GElf_Dyn *dyn = gelf_getdyn (data, cnt, &dyn_mem);
    1685           0 :       if (dyn == NULL)
    1686             :         {
    1687           0 :           ERROR (gettext ("\
    1688             : section [%2d] '%s': cannot get dynamic section entry %zu: %s\n"),
    1689             :                  idx, section_name (ebl, idx), cnt, elf_errmsg (-1));
    1690           0 :           continue;
    1691             :         }
    1692             : 
    1693           0 :       if (has_dt[DT_NULL] && dyn->d_tag != DT_NULL && ! non_null_warned)
    1694             :         {
    1695           0 :           ERROR (gettext ("\
    1696             : section [%2d] '%s': non-DT_NULL entries follow DT_NULL entry\n"),
    1697             :                  idx, section_name (ebl, idx));
    1698           0 :           non_null_warned = true;
    1699             :         }
    1700             : 
    1701           0 :       if (!ebl_dynamic_tag_check (ebl, dyn->d_tag))
    1702           0 :         ERROR (gettext ("section [%2d] '%s': entry %zu: unknown tag\n"),
    1703             :                idx, section_name (ebl, idx), cnt);
    1704             : 
    1705           0 :       if (dyn->d_tag >= 0 && dyn->d_tag < DT_NUM)
    1706             :         {
    1707           0 :           if (has_dt[dyn->d_tag]
    1708           0 :               && dyn->d_tag != DT_NEEDED
    1709           0 :               && dyn->d_tag != DT_NULL
    1710             :               && dyn->d_tag != DT_POSFLAG_1)
    1711             :             {
    1712           0 :               char buf[50];
    1713           0 :               ERROR (gettext ("\
    1714             : section [%2d] '%s': entry %zu: more than one entry with tag %s\n"),
    1715             :                      idx, section_name (ebl, idx), cnt,
    1716             :                      ebl_dynamic_tag_name (ebl, dyn->d_tag,
    1717             :                                            buf, sizeof (buf)));
    1718             :             }
    1719             : 
    1720           0 :           if (be_strict && level2[dyn->d_tag])
    1721             :             {
    1722           0 :               char buf[50];
    1723           0 :               ERROR (gettext ("\
    1724             : section [%2d] '%s': entry %zu: level 2 tag %s used\n"),
    1725             :                      idx, section_name (ebl, idx), cnt,
    1726             :                      ebl_dynamic_tag_name (ebl, dyn->d_tag,
    1727             :                                            buf, sizeof (buf)));
    1728             :             }
    1729             : 
    1730           0 :           has_dt[dyn->d_tag] = true;
    1731             :         }
    1732           0 :       else if (dyn->d_tag >= 0 && dyn->d_tag <= DT_VALRNGHI
    1733           0 :                && DT_VALTAGIDX (dyn->d_tag) < DT_VALNUM)
    1734           0 :         has_val_dt[DT_VALTAGIDX (dyn->d_tag)] = true;
    1735           0 :       else if (dyn->d_tag >= 0 && dyn->d_tag <= DT_ADDRRNGHI
    1736           0 :                && DT_ADDRTAGIDX (dyn->d_tag) < DT_ADDRNUM)
    1737           0 :         has_addr_dt[DT_ADDRTAGIDX (dyn->d_tag)] = true;
    1738             : 
    1739           0 :       if (dyn->d_tag == DT_PLTREL && dyn->d_un.d_val != DT_REL
    1740           0 :           && dyn->d_un.d_val != DT_RELA)
    1741           0 :         ERROR (gettext ("\
    1742             : section [%2d] '%s': entry %zu: DT_PLTREL value must be DT_REL or DT_RELA\n"),
    1743             :                idx, section_name (ebl, idx), cnt);
    1744             : 
    1745             :       /* Check that addresses for entries are in loaded segments.  */
    1746           0 :       switch (dyn->d_tag)
    1747             :         {
    1748           0 :           size_t n;
    1749           0 :         case DT_STRTAB:
    1750             :           /* We require the referenced section is the same as the one
    1751             :              specified in sh_link.  */
    1752           0 :           if (strshdr->sh_addr != dyn->d_un.d_val)
    1753             :             {
    1754           0 :               ERROR (gettext ("\
    1755             : section [%2d] '%s': entry %zu: pointer does not match address of section [%2d] '%s' referenced by sh_link\n"),
    1756             :                      idx, section_name (ebl, idx), cnt,
    1757             :                      shdr->sh_link, section_name (ebl, shdr->sh_link));
    1758           0 :               break;
    1759             :             }
    1760           0 :           goto check_addr;
    1761             : 
    1762           0 :         default:
    1763           0 :           if (dyn->d_tag < DT_ADDRRNGLO || dyn->d_tag > DT_ADDRRNGHI)
    1764             :             /* Value is no pointer.  */
    1765             :             break;
    1766             :           FALLTHROUGH;
    1767             : 
    1768             :         case DT_AUXILIARY:
    1769             :         case DT_FILTER:
    1770             :         case DT_FINI:
    1771             :         case DT_FINI_ARRAY:
    1772             :         case DT_HASH:
    1773             :         case DT_INIT:
    1774             :         case DT_INIT_ARRAY:
    1775             :         case DT_JMPREL:
    1776             :         case DT_PLTGOT:
    1777             :         case DT_REL:
    1778             :         case DT_RELA:
    1779             :         case DT_SYMBOLIC:
    1780             :         case DT_SYMTAB:
    1781             :         case DT_VERDEF:
    1782             :         case DT_VERNEED:
    1783             :         case DT_VERSYM:
    1784           0 :         check_addr:
    1785           0 :           for (n = 0; n < phnum; ++n)
    1786           0 :             {
    1787           0 :               GElf_Phdr phdr_mem;
    1788           0 :               GElf_Phdr *phdr = gelf_getphdr (ebl->elf, n, &phdr_mem);
    1789           0 :               if (phdr != NULL && phdr->p_type == PT_LOAD
    1790           0 :                   && phdr->p_vaddr <= dyn->d_un.d_ptr
    1791           0 :                   && phdr->p_vaddr + phdr->p_memsz > dyn->d_un.d_ptr)
    1792             :                 break;
    1793             :             }
    1794           0 :           if (unlikely (n >= phnum))
    1795             :             {
    1796           0 :               char buf[50];
    1797           0 :               ERROR (gettext ("\
    1798             : section [%2d] '%s': entry %zu: %s value must point into loaded segment\n"),
    1799             :                      idx, section_name (ebl, idx), cnt,
    1800             :                      ebl_dynamic_tag_name (ebl, dyn->d_tag, buf,
    1801             :                                            sizeof (buf)));
    1802             :             }
    1803             :           break;
    1804             : 
    1805           0 :         case DT_NEEDED:
    1806             :         case DT_RPATH:
    1807             :         case DT_RUNPATH:
    1808             :         case DT_SONAME:
    1809           0 :           if (dyn->d_un.d_ptr >= strshdr->sh_size)
    1810             :             {
    1811           0 :               char buf[50];
    1812           0 :               ERROR (gettext ("\
    1813             : section [%2d] '%s': entry %zu: %s value must be valid offset in section [%2d] '%s'\n"),
    1814             :                      idx, section_name (ebl, idx), cnt,
    1815             :                      ebl_dynamic_tag_name (ebl, dyn->d_tag, buf,
    1816             :                                            sizeof (buf)),
    1817             :                      shdr->sh_link, section_name (ebl, shdr->sh_link));
    1818             :             }
    1819             :           break;
    1820             :         }
    1821           0 :     }
    1822             : 
    1823           0 :   for (cnt = 1; cnt < DT_NUM; ++cnt)
    1824           0 :     if (has_dt[cnt])
    1825             :       {
    1826           0 :         for (int inner = 0; inner < DT_NUM; ++inner)
    1827           0 :           if (dependencies[cnt][inner] && ! has_dt[inner])
    1828             :             {
    1829           0 :               char buf1[50];
    1830           0 :               char buf2[50];
    1831             : 
    1832           0 :               ERROR (gettext ("\
    1833             : section [%2d] '%s': contains %s entry but not %s\n"),
    1834             :                      idx, section_name (ebl, idx),
    1835             :                      ebl_dynamic_tag_name (ebl, cnt, buf1, sizeof (buf1)),
    1836             :                      ebl_dynamic_tag_name (ebl, inner, buf2, sizeof (buf2)));
    1837             :             }
    1838             :       }
    1839             :     else
    1840             :       {
    1841           0 :         if (mandatory[cnt])
    1842             :           {
    1843           0 :             char buf[50];
    1844           0 :             ERROR (gettext ("\
    1845             : section [%2d] '%s': mandatory tag %s not present\n"),
    1846             :                    idx, section_name (ebl, idx),
    1847             :                    ebl_dynamic_tag_name (ebl, cnt, buf, sizeof (buf)));
    1848             :           }
    1849             :       }
    1850             : 
    1851             :   /* Make sure we have an hash table.  */
    1852           0 :   if (!has_dt[DT_HASH] && !has_addr_dt[DT_ADDRTAGIDX (DT_GNU_HASH)])
    1853           0 :     ERROR (gettext ("\
    1854             : section [%2d] '%s': no hash section present\n"),
    1855             :            idx, section_name (ebl, idx));
    1856             : 
    1857             :   /* The GNU-style hash table also needs a symbol table.  */
    1858           0 :   if (!has_dt[DT_HASH] && has_addr_dt[DT_ADDRTAGIDX (DT_GNU_HASH)]
    1859           0 :       && !has_dt[DT_SYMTAB])
    1860           0 :     ERROR (gettext ("\
    1861             : section [%2d] '%s': contains %s entry but not %s\n"),
    1862             :            idx, section_name (ebl, idx),
    1863             :            "DT_GNU_HASH", "DT_SYMTAB");
    1864             : 
    1865             :   /* Check the rel/rela tags.  At least one group must be available.  */
    1866           0 :   if ((has_dt[DT_RELA] || has_dt[DT_RELASZ] || has_dt[DT_RELAENT])
    1867           0 :       && (!has_dt[DT_RELA] || !has_dt[DT_RELASZ] || !has_dt[DT_RELAENT]))
    1868           0 :     ERROR (gettext ("\
    1869             : section [%2d] '%s': not all of %s, %s, and %s are present\n"),
    1870             :            idx, section_name (ebl, idx),
    1871             :            "DT_RELA", "DT_RELASZ", "DT_RELAENT");
    1872             : 
    1873           0 :   if ((has_dt[DT_REL] || has_dt[DT_RELSZ] || has_dt[DT_RELENT])
    1874           0 :       && (!has_dt[DT_REL] || !has_dt[DT_RELSZ] || !has_dt[DT_RELENT]))
    1875           0 :     ERROR (gettext ("\
    1876             : section [%2d] '%s': not all of %s, %s, and %s are present\n"),
    1877             :            idx, section_name (ebl, idx),
    1878             :            "DT_REL", "DT_RELSZ", "DT_RELENT");
    1879             : 
    1880             :   /* Check that all prelink sections are present if any of them is.  */
    1881           0 :   if (has_val_dt[DT_VALTAGIDX (DT_GNU_PRELINKED)]
    1882           0 :       || has_val_dt[DT_VALTAGIDX (DT_CHECKSUM)])
    1883             :     {
    1884           0 :       if (!has_val_dt[DT_VALTAGIDX (DT_GNU_PRELINKED)])
    1885           0 :         ERROR (gettext ("\
    1886             : section [%2d] '%s': %s tag missing in DSO marked during prelinking\n"),
    1887             :                idx, section_name (ebl, idx), "DT_GNU_PRELINKED");
    1888           0 :       if (!has_val_dt[DT_VALTAGIDX (DT_CHECKSUM)])
    1889           0 :         ERROR (gettext ("\
    1890             : section [%2d] '%s': %s tag missing in DSO marked during prelinking\n"),
    1891             :                idx, section_name (ebl, idx), "DT_CHECKSUM");
    1892             : 
    1893             :       /* Only DSOs can be marked like this.  */
    1894           0 :       if (ehdr->e_type != ET_DYN)
    1895           0 :         ERROR (gettext ("\
    1896             : section [%2d] '%s': non-DSO file marked as dependency during prelink\n"),
    1897             :                idx, section_name (ebl, idx));
    1898             :     }
    1899             : 
    1900           0 :   if (has_val_dt[DT_VALTAGIDX (DT_GNU_CONFLICTSZ)]
    1901           0 :       || has_val_dt[DT_VALTAGIDX (DT_GNU_LIBLISTSZ)]
    1902           0 :       || has_addr_dt[DT_ADDRTAGIDX (DT_GNU_CONFLICT)]
    1903           0 :       || has_addr_dt[DT_ADDRTAGIDX (DT_GNU_LIBLIST)])
    1904             :     {
    1905           0 :       if (!has_val_dt[DT_VALTAGIDX (DT_GNU_CONFLICTSZ)])
    1906           0 :         ERROR (gettext ("\
    1907             : section [%2d] '%s': %s tag missing in prelinked executable\n"),
    1908             :                idx, section_name (ebl, idx), "DT_GNU_CONFLICTSZ");
    1909           0 :       if (!has_val_dt[DT_VALTAGIDX (DT_GNU_LIBLISTSZ)])
    1910           0 :         ERROR (gettext ("\
    1911             : section [%2d] '%s': %s tag missing in prelinked executable\n"),
    1912             :                idx, section_name (ebl, idx), "DT_GNU_LIBLISTSZ");
    1913           0 :       if (!has_addr_dt[DT_ADDRTAGIDX (DT_GNU_CONFLICT)])
    1914           0 :         ERROR (gettext ("\
    1915             : section [%2d] '%s': %s tag missing in prelinked executable\n"),
    1916             :                idx, section_name (ebl, idx), "DT_GNU_CONFLICT");
    1917           0 :       if (!has_addr_dt[DT_ADDRTAGIDX (DT_GNU_LIBLIST)])
    1918           0 :         ERROR (gettext ("\
    1919             : section [%2d] '%s': %s tag missing in prelinked executable\n"),
    1920             :                idx, section_name (ebl, idx), "DT_GNU_LIBLIST");
    1921             :     }
    1922             : }
    1923             : 
    1924             : 
    1925             : static void
    1926           0 : check_symtab_shndx (Ebl *ebl, GElf_Ehdr *ehdr, GElf_Shdr *shdr, int idx)
    1927             : {
    1928           0 :   if (ehdr->e_type != ET_REL)
    1929             :     {
    1930           0 :       ERROR (gettext ("\
    1931             : section [%2d] '%s': only relocatable files can have extended section index\n"),
    1932             :              idx, section_name (ebl, idx));
    1933           0 :       return;
    1934             :     }
    1935             : 
    1936           0 :   Elf_Scn *symscn = elf_getscn (ebl->elf, shdr->sh_link);
    1937           0 :   GElf_Shdr symshdr_mem;
    1938           0 :   GElf_Shdr *symshdr = gelf_getshdr (symscn, &symshdr_mem);
    1939           0 :   if (symshdr != NULL && symshdr->sh_type != SHT_SYMTAB)
    1940           0 :     ERROR (gettext ("\
    1941             : section [%2d] '%s': extended section index section not for symbol table\n"),
    1942             :            idx, section_name (ebl, idx));
    1943           0 :   else if (symshdr == NULL)
    1944           0 :     ERROR (gettext ("\
    1945             : section [%2d] '%s': sh_link extended section index [%2d] is invalid\n"),
    1946             :            idx, section_name (ebl, idx), shdr->sh_link);
    1947           0 :   Elf_Data *symdata = elf_getdata (symscn, NULL);
    1948           0 :   if (symdata == NULL)
    1949           0 :     ERROR (gettext ("cannot get data for symbol section\n"));
    1950             : 
    1951           0 :   if (shdr->sh_entsize != sizeof (Elf32_Word))
    1952           0 :     ERROR (gettext ("\
    1953             : section [%2d] '%s': entry size does not match Elf32_Word\n"),
    1954             :            idx, section_name (ebl, idx));
    1955             : 
    1956           0 :   if (symshdr != NULL
    1957           0 :       && shdr->sh_entsize != 0
    1958           0 :       && symshdr->sh_entsize != 0
    1959           0 :       && (shdr->sh_size / shdr->sh_entsize
    1960           0 :           < symshdr->sh_size / symshdr->sh_entsize))
    1961           0 :     ERROR (gettext ("\
    1962             : section [%2d] '%s': extended index table too small for symbol table\n"),
    1963             :            idx, section_name (ebl, idx));
    1964             : 
    1965           0 :   if (shdr->sh_info != 0)
    1966           0 :     ERROR (gettext ("section [%2d] '%s': sh_info not zero\n"),
    1967             :            idx, section_name (ebl, idx));
    1968             : 
    1969           0 :   for (size_t cnt = idx + 1; cnt < shnum; ++cnt)
    1970             :     {
    1971           0 :       GElf_Shdr rshdr_mem;
    1972           0 :       GElf_Shdr *rshdr = gelf_getshdr (elf_getscn (ebl->elf, cnt), &rshdr_mem);
    1973           0 :       if (rshdr != NULL && rshdr->sh_type == SHT_SYMTAB_SHNDX
    1974           0 :           && rshdr->sh_link == shdr->sh_link)
    1975             :         {
    1976           0 :           ERROR (gettext ("\
    1977             : section [%2d] '%s': extended section index in section [%2zu] '%s' refers to same symbol table\n"),
    1978             :                  idx, section_name (ebl, idx),
    1979             :                  cnt, section_name (ebl, cnt));
    1980           0 :           break;
    1981             :         }
    1982             :     }
    1983             : 
    1984           0 :   Elf_Data *data = elf_getdata (elf_getscn (ebl->elf, idx), NULL);
    1985           0 :   if (data == NULL || data->d_buf == NULL)
    1986             :     {
    1987           0 :       ERROR (gettext ("section [%2d] '%s': cannot get section data\n"),
    1988             :              idx, section_name (ebl, idx));
    1989           0 :       return;
    1990             :     }
    1991             : 
    1992           0 :   if (data->d_size < sizeof (Elf32_Word)
    1993           0 :       || *((Elf32_Word *) data->d_buf) != 0)
    1994           0 :     ERROR (gettext ("symbol 0 should have zero extended section index\n"));
    1995             : 
    1996           0 :   for (size_t cnt = 1; cnt < data->d_size / sizeof (Elf32_Word); ++cnt)
    1997             :     {
    1998           0 :       Elf32_Word xndx = ((Elf32_Word *) data->d_buf)[cnt];
    1999             : 
    2000           0 :       if (xndx != 0)
    2001             :         {
    2002           0 :           GElf_Sym sym_data;
    2003           0 :           GElf_Sym *sym = gelf_getsym (symdata, cnt, &sym_data);
    2004           0 :           if (sym == NULL)
    2005             :             {
    2006           0 :               ERROR (gettext ("cannot get data for symbol %zu\n"), cnt);
    2007           0 :               continue;
    2008             :             }
    2009             : 
    2010           0 :           if (sym->st_shndx != SHN_XINDEX)
    2011           0 :             ERROR (gettext ("\
    2012             : extended section index is %" PRIu32 " but symbol index is not XINDEX\n"),
    2013             :                    (uint32_t) xndx);
    2014             :         }
    2015             :     }
    2016             : }
    2017             : 
    2018             : 
    2019             : static void
    2020           0 : check_sysv_hash (Ebl *ebl, GElf_Shdr *shdr, Elf_Data *data, int idx,
    2021             :                  GElf_Shdr *symshdr)
    2022             : {
    2023           0 :   Elf32_Word nbucket = ((Elf32_Word *) data->d_buf)[0];
    2024           0 :   Elf32_Word nchain = ((Elf32_Word *) data->d_buf)[1];
    2025             : 
    2026           0 :   if (shdr->sh_size < (2ULL + nbucket + nchain) * sizeof (Elf32_Word))
    2027             :     {
    2028           0 :       ERROR (gettext ("\
    2029             : section [%2d] '%s': hash table section is too small (is %ld, expected %ld)\n"),
    2030             :              idx, section_name (ebl, idx), (long int) shdr->sh_size,
    2031             :              (long int) ((2 + nbucket + nchain) * sizeof (Elf32_Word)));
    2032           0 :       return;
    2033             :     }
    2034             : 
    2035           0 :   size_t maxidx = nchain;
    2036             : 
    2037           0 :   if (symshdr != NULL && symshdr->sh_entsize != 0)
    2038             :     {
    2039           0 :       size_t symsize = symshdr->sh_size / symshdr->sh_entsize;
    2040             : 
    2041           0 :       if (nchain > symshdr->sh_size / symshdr->sh_entsize)
    2042           0 :         ERROR (gettext ("section [%2d] '%s': chain array too large\n"),
    2043             :                idx, section_name (ebl, idx));
    2044             : 
    2045             :       maxidx = symsize;
    2046             :     }
    2047             : 
    2048           0 :   Elf32_Word *buf = (Elf32_Word *) data->d_buf;
    2049           0 :   Elf32_Word *end = (Elf32_Word *) ((char *) data->d_buf + shdr->sh_size);
    2050           0 :   size_t cnt;
    2051           0 :   for (cnt = 2; cnt < 2 + nbucket; ++cnt)
    2052             :     {
    2053           0 :       if (buf + cnt >= end)
    2054             :         break;
    2055           0 :       else if (buf[cnt] >= maxidx)
    2056           0 :       ERROR (gettext ("\
    2057             : section [%2d] '%s': hash bucket reference %zu out of bounds\n"),
    2058             :              idx, section_name (ebl, idx), cnt - 2);
    2059             :     }
    2060             : 
    2061           0 :   for (; cnt < 2 + nbucket + nchain; ++cnt)
    2062             :     {
    2063           0 :       if (buf + cnt >= end)
    2064             :         break;
    2065           0 :       else if (buf[cnt] >= maxidx)
    2066           0 :       ERROR (gettext ("\
    2067             : section [%2d] '%s': hash chain reference %zu out of bounds\n"),
    2068             :              idx, section_name (ebl, idx), cnt - 2 - nbucket);
    2069             :     }
    2070             : }
    2071             : 
    2072             : 
    2073             : static void
    2074           0 : check_sysv_hash64 (Ebl *ebl, GElf_Shdr *shdr, Elf_Data *data, int idx,
    2075             :                  GElf_Shdr *symshdr)
    2076             : {
    2077           0 :   Elf64_Xword nbucket = ((Elf64_Xword *) data->d_buf)[0];
    2078           0 :   Elf64_Xword nchain = ((Elf64_Xword *) data->d_buf)[1];
    2079             : 
    2080           0 :   uint64_t maxwords = shdr->sh_size / sizeof (Elf64_Xword);
    2081           0 :   if (maxwords < 2
    2082           0 :       || maxwords - 2 < nbucket
    2083           0 :       || maxwords - 2 - nbucket < nchain)
    2084             :     {
    2085           0 :       ERROR (gettext ("\
    2086             : section [%2d] '%s': hash table section is too small (is %ld, expected %ld)\n"),
    2087             :              idx, section_name (ebl, idx), (long int) shdr->sh_size,
    2088             :              (long int) ((2 + nbucket + nchain) * sizeof (Elf64_Xword)));
    2089           0 :       return;
    2090             :     }
    2091             : 
    2092           0 :   size_t maxidx = nchain;
    2093             : 
    2094           0 :   if (symshdr != NULL && symshdr->sh_entsize != 0)
    2095             :     {
    2096           0 :       size_t symsize = symshdr->sh_size / symshdr->sh_entsize;
    2097             : 
    2098           0 :       if (nchain > symshdr->sh_size / symshdr->sh_entsize)
    2099           0 :         ERROR (gettext ("section [%2d] '%s': chain array too large\n"),
    2100             :                idx, section_name (ebl, idx));
    2101             : 
    2102             :       maxidx = symsize;
    2103             :     }
    2104             : 
    2105           0 :   Elf64_Xword *buf = (Elf64_Xword *) data->d_buf;
    2106           0 :   Elf64_Xword *end = (Elf64_Xword *) ((char *) data->d_buf + shdr->sh_size);
    2107           0 :   size_t cnt;
    2108           0 :   for (cnt = 2; cnt < 2 + nbucket; ++cnt)
    2109             :     {
    2110           0 :       if (buf + cnt >= end)
    2111             :         break;
    2112           0 :       else if (buf[cnt] >= maxidx)
    2113           0 :       ERROR (gettext ("\
    2114             : section [%2d] '%s': hash bucket reference %zu out of bounds\n"),
    2115             :              idx, section_name (ebl, idx), cnt - 2);
    2116             :     }
    2117             : 
    2118           0 :   for (; cnt < 2 + nbucket + nchain; ++cnt)
    2119             :     {
    2120           0 :       if (buf + cnt >= end)
    2121             :         break;
    2122           0 :       else if (buf[cnt] >= maxidx)
    2123           0 :       ERROR (gettext ("\
    2124             : section [%2d] '%s': hash chain reference %" PRIu64 " out of bounds\n"),
    2125             :                idx, section_name (ebl, idx), (uint64_t) cnt - 2 - nbucket);
    2126             :     }
    2127             : }
    2128             : 
    2129             : 
    2130             : static void
    2131           0 : check_gnu_hash (Ebl *ebl, GElf_Shdr *shdr, Elf_Data *data, int idx,
    2132             :                 GElf_Shdr *symshdr)
    2133             : {
    2134           0 :   if (data->d_size < 4 * sizeof (Elf32_Word))
    2135             :     {
    2136           0 :       ERROR (gettext ("\
    2137             : section [%2d] '%s': not enough data\n"),
    2138             :              idx, section_name (ebl, idx));
    2139           0 :       return;
    2140             :     }
    2141             : 
    2142           0 :   Elf32_Word nbuckets = ((Elf32_Word *) data->d_buf)[0];
    2143           0 :   Elf32_Word symbias = ((Elf32_Word *) data->d_buf)[1];
    2144           0 :   Elf32_Word bitmask_words = ((Elf32_Word *) data->d_buf)[2];
    2145             : 
    2146           0 :   if (bitmask_words == 0 || !powerof2 (bitmask_words))
    2147             :     {
    2148           0 :       ERROR (gettext ("\
    2149             : section [%2d] '%s': bitmask size zero or not power of 2: %u\n"),
    2150             :              idx, section_name (ebl, idx), bitmask_words);
    2151           0 :       return;
    2152             :     }
    2153             : 
    2154           0 :   size_t bitmask_idxmask = bitmask_words - 1;
    2155           0 :   if (gelf_getclass (ebl->elf) == ELFCLASS64)
    2156           0 :     bitmask_words *= 2;
    2157           0 :   Elf32_Word shift = ((Elf32_Word *) data->d_buf)[3];
    2158             : 
    2159             :   /* Is there still room for the sym chain?
    2160             :      Use uint64_t calculation to prevent 32bit overlow.  */
    2161           0 :   uint64_t used_buf = (4ULL + bitmask_words + nbuckets) * sizeof (Elf32_Word);
    2162           0 :   if (used_buf > data->d_size)
    2163             :     {
    2164           0 :       ERROR (gettext ("\
    2165             : section [%2d] '%s': hash table section is too small (is %ld, expected at least %ld)\n"),
    2166             :              idx, section_name (ebl, idx), (long int) shdr->sh_size,
    2167             :              (long int) used_buf);
    2168           0 :       return;
    2169             :     }
    2170             : 
    2171           0 :   if (shift > 31)
    2172             :     {
    2173           0 :       ERROR (gettext ("\
    2174             : section [%2d] '%s': 2nd hash function shift too big: %u\n"),
    2175             :              idx, section_name (ebl, idx), shift);
    2176           0 :       return;
    2177             :     }
    2178             : 
    2179           0 :   size_t maxidx = shdr->sh_size / sizeof (Elf32_Word) - (4 + bitmask_words
    2180           0 :                                                          + nbuckets);
    2181             : 
    2182           0 :   if (symshdr != NULL && symshdr->sh_entsize != 0)
    2183           0 :     maxidx = MIN (maxidx, symshdr->sh_size / symshdr->sh_entsize);
    2184             : 
    2185             :   /* We need the symbol section data.  */
    2186           0 :   Elf_Data *symdata = elf_getdata (elf_getscn (ebl->elf, shdr->sh_link), NULL);
    2187             : 
    2188           0 :   union
    2189             :   {
    2190             :     Elf32_Word *p32;
    2191             :     Elf64_Xword *p64;
    2192           0 :   } bitmask = { .p32 = &((Elf32_Word *) data->d_buf)[4] },
    2193           0 :       collected = { .p32 = xcalloc (bitmask_words, sizeof (Elf32_Word)) };
    2194             : 
    2195           0 :   size_t classbits = gelf_getclass (ebl->elf) == ELFCLASS32 ? 32 : 64;
    2196             : 
    2197           0 :   size_t cnt;
    2198           0 :   for (cnt = 4 + bitmask_words; cnt < 4 + bitmask_words + nbuckets; ++cnt)
    2199             :     {
    2200           0 :       Elf32_Word symidx = ((Elf32_Word *) data->d_buf)[cnt];
    2201             : 
    2202           0 :       if (symidx == 0)
    2203           0 :         continue;
    2204             : 
    2205           0 :       if (symidx < symbias)
    2206             :         {
    2207           0 :           ERROR (gettext ("\
    2208             : section [%2d] '%s': hash chain for bucket %zu lower than symbol index bias\n"),
    2209             :                  idx, section_name (ebl, idx), cnt - (4 + bitmask_words));
    2210           0 :           continue;
    2211             :         }
    2212             : 
    2213           0 :       while (symidx - symbias < maxidx)
    2214             :         {
    2215           0 :           Elf32_Word chainhash = ((Elf32_Word *) data->d_buf)[4
    2216             :                                                               + bitmask_words
    2217             :                                                               + nbuckets
    2218           0 :                                                               + symidx
    2219           0 :                                                               - symbias];
    2220             : 
    2221           0 :           if (symdata != NULL)
    2222             :             {
    2223             :               /* Check that the referenced symbol is not undefined.  */
    2224           0 :               GElf_Sym sym_mem;
    2225           0 :               GElf_Sym *sym = gelf_getsym (symdata, symidx, &sym_mem);
    2226           0 :               if (sym != NULL && sym->st_shndx == SHN_UNDEF
    2227           0 :                   && GELF_ST_TYPE (sym->st_info) != STT_FUNC)
    2228           0 :                 ERROR (gettext ("\
    2229             : section [%2d] '%s': symbol %u referenced in chain for bucket %zu is undefined\n"),
    2230             :                        idx, section_name (ebl, idx), symidx,
    2231             :                        cnt - (4 + bitmask_words));
    2232             : 
    2233           0 :               const char *symname = (sym != NULL
    2234           0 :                                      ? elf_strptr (ebl->elf, symshdr->sh_link,
    2235           0 :                                                    sym->st_name)
    2236           0 :                                      : NULL);
    2237           0 :               if (symname != NULL)
    2238             :                 {
    2239           0 :                   Elf32_Word hval = elf_gnu_hash (symname);
    2240           0 :                   if ((hval & ~1u) != (chainhash & ~1u))
    2241           0 :                     ERROR (gettext ("\
    2242             : section [%2d] '%s': hash value for symbol %u in chain for bucket %zu wrong\n"),
    2243             :                            idx, section_name (ebl, idx), symidx,
    2244             :                            cnt - (4 + bitmask_words));
    2245             : 
    2246             :                   /* Set the bits in the bitmask.  */
    2247           0 :                   size_t maskidx = (hval / classbits) & bitmask_idxmask;
    2248           0 :                   if (maskidx >= bitmask_words)
    2249             :                     {
    2250           0 :                       ERROR (gettext ("\
    2251             : section [%2d] '%s': mask index for symbol %u in chain for bucket %zu wrong\n"),
    2252             :                              idx, section_name (ebl, idx), symidx,
    2253             :                              cnt - (4 + bitmask_words));
    2254           0 :                       return;
    2255             :                     }
    2256           0 :                   if (classbits == 32)
    2257             :                     {
    2258           0 :                       collected.p32[maskidx]
    2259           0 :                         |= UINT32_C (1) << (hval & (classbits - 1));
    2260           0 :                       collected.p32[maskidx]
    2261           0 :                         |= UINT32_C (1) << ((hval >> shift) & (classbits - 1));
    2262             :                     }
    2263             :                   else
    2264             :                     {
    2265           0 :                       collected.p64[maskidx]
    2266           0 :                         |= UINT64_C (1) << (hval & (classbits - 1));
    2267           0 :                       collected.p64[maskidx]
    2268           0 :                         |= UINT64_C (1) << ((hval >> shift) & (classbits - 1));
    2269             :                     }
    2270             :                 }
    2271             :             }
    2272             : 
    2273           0 :           if ((chainhash & 1) != 0)
    2274             :             break;
    2275             : 
    2276           0 :           ++symidx;
    2277             :         }
    2278             : 
    2279           0 :       if (symidx - symbias >= maxidx)
    2280           0 :         ERROR (gettext ("\
    2281             : section [%2d] '%s': hash chain for bucket %zu out of bounds\n"),
    2282             :                idx, section_name (ebl, idx), cnt - (4 + bitmask_words));
    2283           0 :       else if (symshdr != NULL && symshdr->sh_entsize != 0
    2284           0 :                && symidx > symshdr->sh_size / symshdr->sh_entsize)
    2285           0 :         ERROR (gettext ("\
    2286             : section [%2d] '%s': symbol reference in chain for bucket %zu out of bounds\n"),
    2287             :                idx, section_name (ebl, idx), cnt - (4 + bitmask_words));
    2288             :     }
    2289             : 
    2290           0 :   if (memcmp (collected.p32, bitmask.p32, bitmask_words * sizeof (Elf32_Word)))
    2291           0 :     ERROR (gettext ("\
    2292             : section [%2d] '%s': bitmask does not match names in the hash table\n"),
    2293             :            idx, section_name (ebl, idx));
    2294             : 
    2295           0 :   free (collected.p32);
    2296             : }
    2297             : 
    2298             : 
    2299             : static void
    2300           0 : check_hash (int tag, Ebl *ebl, GElf_Ehdr *ehdr, GElf_Shdr *shdr, int idx)
    2301             : {
    2302           0 :   if (ehdr->e_type == ET_REL)
    2303             :     {
    2304           0 :       ERROR (gettext ("\
    2305             : section [%2d] '%s': relocatable files cannot have hash tables\n"),
    2306             :              idx, section_name (ebl, idx));
    2307           0 :       return;
    2308             :     }
    2309             : 
    2310           0 :   Elf_Data *data = elf_getdata (elf_getscn (ebl->elf, idx), NULL);
    2311           0 :   if (data == NULL || data->d_buf == NULL)
    2312             :     {
    2313           0 :       ERROR (gettext ("section [%2d] '%s': cannot get section data\n"),
    2314             :              idx, section_name (ebl, idx));
    2315           0 :       return;
    2316             :     }
    2317             : 
    2318           0 :   GElf_Shdr symshdr_mem;
    2319           0 :   GElf_Shdr *symshdr = gelf_getshdr (elf_getscn (ebl->elf, shdr->sh_link),
    2320             :                                      &symshdr_mem);
    2321           0 :   if (symshdr != NULL && symshdr->sh_type != SHT_DYNSYM)
    2322           0 :     ERROR (gettext ("\
    2323             : section [%2d] '%s': hash table not for dynamic symbol table\n"),
    2324             :            idx, section_name (ebl, idx));
    2325           0 :   else if (symshdr == NULL)
    2326           0 :     ERROR (gettext ("\
    2327             : section [%2d] '%s': invalid sh_link symbol table section index [%2d]\n"),
    2328             :            idx, section_name (ebl, idx), shdr->sh_link);
    2329             : 
    2330           0 :   size_t expect_entsize = (tag == SHT_GNU_HASH
    2331           0 :                            ? (gelf_getclass (ebl->elf) == ELFCLASS32
    2332           0 :                               ? sizeof (Elf32_Word) : 0)
    2333           0 :                            : (size_t) ebl_sysvhash_entrysize (ebl));
    2334             : 
    2335           0 :   if (shdr->sh_entsize != expect_entsize)
    2336           0 :     ERROR (gettext ("\
    2337             : section [%2d] '%s': hash table entry size incorrect\n"),
    2338             :            idx, section_name (ebl, idx));
    2339             : 
    2340           0 :   if ((shdr->sh_flags & SHF_ALLOC) == 0)
    2341           0 :     ERROR (gettext ("section [%2d] '%s': not marked to be allocated\n"),
    2342             :            idx, section_name (ebl, idx));
    2343             : 
    2344           0 :   if (shdr->sh_size < (tag == SHT_GNU_HASH ? 4 : 2) * (expect_entsize ?: 4))
    2345             :     {
    2346           0 :       ERROR (gettext ("\
    2347             : section [%2d] '%s': hash table has not even room for initial administrative entries\n"),
    2348             :              idx, section_name (ebl, idx));
    2349           0 :       return;
    2350             :     }
    2351             : 
    2352           0 :   switch (tag)
    2353             :     {
    2354           0 :     case SHT_HASH:
    2355           0 :       if (ebl_sysvhash_entrysize (ebl) == sizeof (Elf64_Xword))
    2356           0 :         check_sysv_hash64 (ebl, shdr, data, idx, symshdr);
    2357             :       else
    2358           0 :         check_sysv_hash (ebl, shdr, data, idx, symshdr);
    2359             :       break;
    2360             : 
    2361           0 :     case SHT_GNU_HASH:
    2362           0 :       check_gnu_hash (ebl, shdr, data, idx, symshdr);
    2363           0 :       break;
    2364             : 
    2365             :     default:
    2366           0 :       assert (! "should not happen");
    2367             :     }
    2368             : }
    2369             : 
    2370             : 
    2371             : /* Compare content of both hash tables, it must be identical.  */
    2372             : static void
    2373           0 : compare_hash_gnu_hash (Ebl *ebl, GElf_Ehdr *ehdr, size_t hash_idx,
    2374             :                        size_t gnu_hash_idx)
    2375             : {
    2376           0 :   Elf_Scn *hash_scn = elf_getscn (ebl->elf, hash_idx);
    2377           0 :   Elf_Data *hash_data = elf_getdata (hash_scn, NULL);
    2378           0 :   GElf_Shdr hash_shdr_mem;
    2379           0 :   GElf_Shdr *hash_shdr = gelf_getshdr (hash_scn, &hash_shdr_mem);
    2380           0 :   Elf_Scn *gnu_hash_scn = elf_getscn (ebl->elf, gnu_hash_idx);
    2381           0 :   Elf_Data *gnu_hash_data = elf_getdata (gnu_hash_scn, NULL);
    2382           0 :   GElf_Shdr gnu_hash_shdr_mem;
    2383           0 :   GElf_Shdr *gnu_hash_shdr = gelf_getshdr (gnu_hash_scn, &gnu_hash_shdr_mem);
    2384             : 
    2385           0 :   if (hash_shdr == NULL || gnu_hash_shdr == NULL
    2386           0 :       || hash_data == NULL || hash_data->d_buf == NULL
    2387           0 :       || gnu_hash_data == NULL || gnu_hash_data->d_buf == NULL)
    2388             :     /* None of these pointers should be NULL since we used the
    2389             :        sections already.  We are careful nonetheless.  */
    2390           0 :     return;
    2391             : 
    2392             :   /* The link must point to the same symbol table.  */
    2393           0 :   if (hash_shdr->sh_link != gnu_hash_shdr->sh_link)
    2394             :     {
    2395           0 :       ERROR (gettext ("\
    2396             : sh_link in hash sections [%2zu] '%s' and [%2zu] '%s' not identical\n"),
    2397             :              hash_idx, elf_strptr (ebl->elf, shstrndx, hash_shdr->sh_name),
    2398             :              gnu_hash_idx,
    2399             :              elf_strptr (ebl->elf, shstrndx, gnu_hash_shdr->sh_name));
    2400           0 :       return;
    2401             :     }
    2402             : 
    2403           0 :   Elf_Scn *sym_scn = elf_getscn (ebl->elf, hash_shdr->sh_link);
    2404           0 :   Elf_Data *sym_data = elf_getdata (sym_scn, NULL);
    2405           0 :   GElf_Shdr sym_shdr_mem;
    2406           0 :   GElf_Shdr *sym_shdr = gelf_getshdr (sym_scn, &sym_shdr_mem);
    2407             : 
    2408           0 :   if (sym_data == NULL || sym_data->d_buf == NULL
    2409           0 :       || sym_shdr == NULL || sym_shdr->sh_entsize == 0)
    2410           0 :     return;
    2411             : 
    2412           0 :   const char *hash_name;
    2413           0 :   const char *gnu_hash_name;
    2414           0 :   hash_name  = elf_strptr (ebl->elf, shstrndx, hash_shdr->sh_name);
    2415           0 :   gnu_hash_name  = elf_strptr (ebl->elf, shstrndx, gnu_hash_shdr->sh_name);
    2416             : 
    2417           0 :   if (gnu_hash_data->d_size < 4 * sizeof (Elf32_Word))
    2418             :     {
    2419           0 :       ERROR (gettext ("\
    2420             : hash section [%2zu] '%s' does not contain enough data\n"),
    2421             :              gnu_hash_idx, gnu_hash_name);
    2422           0 :       return;
    2423             :     }
    2424             : 
    2425           0 :   uint32_t nentries = sym_shdr->sh_size / sym_shdr->sh_entsize;
    2426           0 :   char *used = alloca (nentries);
    2427           0 :   memset (used, '\0', nentries);
    2428             : 
    2429             :   /* First go over the GNU_HASH table and mark the entries as used.  */
    2430           0 :   const Elf32_Word *gnu_hasharr = (Elf32_Word *) gnu_hash_data->d_buf;
    2431           0 :   Elf32_Word gnu_nbucket = gnu_hasharr[0];
    2432           0 :   Elf32_Word gnu_symbias = gnu_hasharr[1];
    2433           0 :   const int bitmap_factor = ehdr->e_ident[EI_CLASS] == ELFCLASS32 ? 1 : 2;
    2434           0 :   const Elf32_Word *gnu_bucket = (gnu_hasharr
    2435           0 :                                   + (4 + gnu_hasharr[2] * bitmap_factor));
    2436           0 :   const Elf32_Word *gnu_chain = gnu_bucket + gnu_hasharr[0];
    2437             : 
    2438           0 :   if (gnu_hasharr[2] == 0)
    2439             :     {
    2440           0 :       ERROR (gettext ("\
    2441             : hash section [%2zu] '%s' has zero bit mask words\n"),
    2442             :              gnu_hash_idx, gnu_hash_name);
    2443           0 :       return;
    2444             :     }
    2445             : 
    2446           0 :   uint64_t used_buf = ((4ULL + gnu_hasharr[2] * bitmap_factor + gnu_nbucket)
    2447           0 :                        * sizeof (Elf32_Word));
    2448           0 :   uint32_t max_nsyms = (gnu_hash_data->d_size - used_buf) / sizeof (Elf32_Word);
    2449           0 :   if (used_buf > gnu_hash_data->d_size)
    2450             :     {
    2451           0 :       ERROR (gettext ("\
    2452             : hash section [%2zu] '%s' uses too much data\n"),
    2453             :              gnu_hash_idx, gnu_hash_name);
    2454           0 :       return;
    2455             :     }
    2456             : 
    2457           0 :   for (Elf32_Word cnt = 0; cnt < gnu_nbucket; ++cnt)
    2458             :     {
    2459           0 :       if (gnu_bucket[cnt] != STN_UNDEF)
    2460             :         {
    2461           0 :           Elf32_Word symidx = gnu_bucket[cnt] - gnu_symbias;
    2462           0 :           do
    2463             :             {
    2464           0 :               if (symidx >= max_nsyms || symidx + gnu_symbias >= nentries)
    2465             :                 {
    2466           0 :                   ERROR (gettext ("\
    2467             : hash section [%2zu] '%s' invalid symbol index %" PRIu32 " (max_nsyms: %" PRIu32 ", nentries: %" PRIu32 "\n"),
    2468             :                          gnu_hash_idx, gnu_hash_name, symidx, max_nsyms, nentries);
    2469           0 :                   return;
    2470             :                 }
    2471           0 :               used[symidx + gnu_symbias] |= 1;
    2472             :             }
    2473           0 :           while ((gnu_chain[symidx++] & 1u) == 0);
    2474             :         }
    2475             :     }
    2476             : 
    2477             :   /* Now go over the old hash table and check that we cover the same
    2478             :      entries.  */
    2479           0 :   if (hash_shdr->sh_entsize == sizeof (Elf32_Word))
    2480             :     {
    2481           0 :       const Elf32_Word *hasharr = (Elf32_Word *) hash_data->d_buf;
    2482           0 :       if (hash_data->d_size < 2 * sizeof (Elf32_Word))
    2483             :         {
    2484           0 :           ERROR (gettext ("\
    2485             : hash section [%2zu] '%s' does not contain enough data\n"),
    2486             :                  hash_idx, hash_name);
    2487           0 :           return;
    2488             :         }
    2489             : 
    2490           0 :       Elf32_Word nbucket = hasharr[0];
    2491           0 :       Elf32_Word nchain = hasharr[1];
    2492           0 :       uint64_t hash_used = (2ULL + nchain + nbucket) * sizeof (Elf32_Word);
    2493           0 :       if (hash_used > hash_data->d_size)
    2494             :         {
    2495           0 :           ERROR (gettext ("\
    2496             : hash section [%2zu] '%s' uses too much data\n"),
    2497             :                  hash_idx, hash_name);
    2498           0 :           return;
    2499             :         }
    2500             : 
    2501           0 :       const Elf32_Word *bucket = &hasharr[2];
    2502           0 :       const Elf32_Word *chain = &hasharr[2 + nbucket];
    2503             : 
    2504           0 :       for (Elf32_Word cnt = 0; cnt < nbucket; ++cnt)
    2505             :         {
    2506           0 :           Elf32_Word symidx = bucket[cnt];
    2507           0 :           while (symidx != STN_UNDEF && symidx < nentries && symidx < nchain)
    2508             :             {
    2509           0 :               used[symidx] |= 2;
    2510           0 :               symidx = chain[symidx];
    2511             :             }
    2512             :         }
    2513             :     }
    2514           0 :   else if (hash_shdr->sh_entsize == sizeof (Elf64_Xword))
    2515             :     {
    2516           0 :       const Elf64_Xword *hasharr = (Elf64_Xword *) hash_data->d_buf;
    2517           0 :       if (hash_data->d_size < 2 * sizeof (Elf32_Word))
    2518             :         {
    2519           0 :           ERROR (gettext ("\
    2520             : hash section [%2zu] '%s' does not contain enough data\n"),
    2521             :                  hash_idx, hash_name);
    2522           0 :           return;
    2523             :         }
    2524             : 
    2525           0 :       Elf64_Xword nbucket = hasharr[0];
    2526           0 :       Elf64_Xword nchain = hasharr[1];
    2527           0 :       uint64_t maxwords = hash_data->d_size / sizeof (Elf64_Xword);
    2528           0 :       if (maxwords < 2
    2529           0 :           || maxwords - 2 < nbucket
    2530           0 :           || maxwords - 2 - nbucket < nchain)
    2531             :         {
    2532           0 :           ERROR (gettext ("\
    2533             : hash section [%2zu] '%s' uses too much data\n"),
    2534             :                  hash_idx, hash_name);
    2535           0 :           return;
    2536             :         }
    2537             : 
    2538           0 :       const Elf64_Xword *bucket = &hasharr[2];
    2539           0 :       const Elf64_Xword *chain = &hasharr[2 + nbucket];
    2540             : 
    2541           0 :       for (Elf64_Xword cnt = 0; cnt < nbucket; ++cnt)
    2542             :         {
    2543           0 :           Elf64_Xword symidx = bucket[cnt];
    2544           0 :           while (symidx != STN_UNDEF && symidx < nentries && symidx < nchain)
    2545             :             {
    2546           0 :               used[symidx] |= 2;
    2547           0 :               symidx = chain[symidx];
    2548             :             }
    2549             :         }
    2550             :     }
    2551             :   else
    2552             :     {
    2553           0 :       ERROR (gettext ("\
    2554             : hash section [%2zu] '%s' invalid sh_entsize\n"),
    2555             :              hash_idx, hash_name);
    2556           0 :       return;
    2557             :     }
    2558             : 
    2559             :   /* Now see which entries are not set in one or both hash tables
    2560             :      (unless the symbol is undefined in which case it can be omitted
    2561             :      in the new table format).  */
    2562           0 :   if ((used[0] & 1) != 0)
    2563           0 :     ERROR (gettext ("section [%2zu] '%s': reference to symbol index 0\n"),
    2564             :            gnu_hash_idx,
    2565             :            elf_strptr (ebl->elf, shstrndx, gnu_hash_shdr->sh_name));
    2566           0 :   if ((used[0] & 2) != 0)
    2567           0 :     ERROR (gettext ("section [%2zu] '%s': reference to symbol index 0\n"),
    2568             :            hash_idx, elf_strptr (ebl->elf, shstrndx, hash_shdr->sh_name));
    2569             : 
    2570           0 :   for (uint32_t cnt = 1; cnt < nentries; ++cnt)
    2571           0 :     if (used[cnt] != 0 && used[cnt] != 3)
    2572             :       {
    2573           0 :         if (used[cnt] == 1)
    2574           0 :           ERROR (gettext ("\
    2575             : symbol %d referenced in new hash table in [%2zu] '%s' but not in old hash table in [%2zu] '%s'\n"),
    2576             :                  cnt, gnu_hash_idx,
    2577             :                  elf_strptr (ebl->elf, shstrndx, gnu_hash_shdr->sh_name),
    2578             :                  hash_idx,
    2579             :                  elf_strptr (ebl->elf, shstrndx, hash_shdr->sh_name));
    2580             :         else
    2581             :           {
    2582           0 :             GElf_Sym sym_mem;
    2583           0 :             GElf_Sym *sym = gelf_getsym (sym_data, cnt, &sym_mem);
    2584             : 
    2585           0 :             if (sym != NULL && sym->st_shndx != STN_UNDEF)
    2586           0 :               ERROR (gettext ("\
    2587             : symbol %d referenced in old hash table in [%2zu] '%s' but not in new hash table in [%2zu] '%s'\n"),
    2588             :                      cnt, hash_idx,
    2589             :                      elf_strptr (ebl->elf, shstrndx, hash_shdr->sh_name),
    2590             :                      gnu_hash_idx,
    2591             :                      elf_strptr (ebl->elf, shstrndx, gnu_hash_shdr->sh_name));
    2592             :           }
    2593             :       }
    2594             : }
    2595             : 
    2596             : 
    2597             : static void
    2598           0 : check_null (Ebl *ebl, GElf_Shdr *shdr, int idx)
    2599             : {
    2600             : #define TEST(name, extra) \
    2601             :   if (extra && shdr->sh_##name != 0)                                       \
    2602             :     ERROR (gettext ("section [%2d] '%s': nonzero sh_%s for NULL section\n"),  \
    2603             :            idx, section_name (ebl, idx), #name)
    2604             : 
    2605           0 :   TEST (name, 1);
    2606           0 :   TEST (flags, 1);
    2607           0 :   TEST (addr, 1);
    2608           0 :   TEST (offset, 1);
    2609           0 :   TEST (size, idx != 0);
    2610           0 :   TEST (link, idx != 0);
    2611           0 :   TEST (info, 1);
    2612           0 :   TEST (addralign, 1);
    2613           0 :   TEST (entsize, 1);
    2614           0 : }
    2615             : 
    2616             : 
    2617             : static void
    2618           0 : check_group (Ebl *ebl, GElf_Ehdr *ehdr, GElf_Shdr *shdr, int idx)
    2619             : {
    2620           0 :   if (ehdr->e_type != ET_REL)
    2621             :     {
    2622           0 :       ERROR (gettext ("\
    2623             : section [%2d] '%s': section groups only allowed in relocatable object files\n"),
    2624             :              idx, section_name (ebl, idx));
    2625           0 :       return;
    2626             :     }
    2627             : 
    2628             :   /* Check that sh_link is an index of a symbol table.  */
    2629           0 :   Elf_Scn *symscn = elf_getscn (ebl->elf, shdr->sh_link);
    2630           0 :   GElf_Shdr symshdr_mem;
    2631           0 :   GElf_Shdr *symshdr = gelf_getshdr (symscn, &symshdr_mem);
    2632           0 :   if (symshdr == NULL)
    2633           0 :     ERROR (gettext ("section [%2d] '%s': cannot get symbol table: %s\n"),
    2634             :            idx, section_name (ebl, idx), elf_errmsg (-1));
    2635             :   else
    2636             :     {
    2637           0 :       if (symshdr->sh_type != SHT_SYMTAB)
    2638           0 :         ERROR (gettext ("\
    2639             : section [%2d] '%s': section reference in sh_link is no symbol table\n"),
    2640             :                idx, section_name (ebl, idx));
    2641             : 
    2642           0 :       if (shdr->sh_info >= symshdr->sh_size / gelf_fsize (ebl->elf, ELF_T_SYM,
    2643             :                                                           1, EV_CURRENT))
    2644           0 :         ERROR (gettext ("\
    2645             : section [%2d] '%s': invalid symbol index in sh_info\n"),
    2646             :                idx, section_name (ebl, idx));
    2647             : 
    2648           0 :       if (shdr->sh_flags != 0)
    2649           0 :         ERROR (gettext ("section [%2d] '%s': sh_flags not zero\n"),
    2650             :                idx, section_name (ebl, idx));
    2651             : 
    2652           0 :       GElf_Sym sym_data;
    2653           0 :       GElf_Sym *sym = gelf_getsym (elf_getdata (symscn, NULL), shdr->sh_info,
    2654             :                                    &sym_data);
    2655           0 :       if (sym == NULL)
    2656           0 :         ERROR (gettext ("\
    2657             : section [%2d] '%s': cannot get symbol for signature\n"),
    2658             :                idx, section_name (ebl, idx));
    2659           0 :       else if (elf_strptr (ebl->elf, symshdr->sh_link, sym->st_name) == NULL)
    2660           0 :         ERROR (gettext ("\
    2661             : section [%2d] '%s': cannot get symbol name for signature\n"),
    2662             :                idx, section_name (ebl, idx));
    2663           0 :       else if (strcmp (elf_strptr (ebl->elf, symshdr->sh_link, sym->st_name),
    2664             :                        "") == 0)
    2665           0 :         ERROR (gettext ("\
    2666             : section [%2d] '%s': signature symbol cannot be empty string\n"),
    2667             :                idx, section_name (ebl, idx));
    2668             : 
    2669           0 :       if (be_strict
    2670           0 :           && shdr->sh_entsize != elf32_fsize (ELF_T_WORD, 1, EV_CURRENT))
    2671           0 :         ERROR (gettext ("section [%2d] '%s': sh_flags not set correctly\n"),
    2672             :                idx, section_name (ebl, idx));
    2673             :     }
    2674             : 
    2675           0 :   Elf_Data *data = elf_getdata (elf_getscn (ebl->elf, idx), NULL);
    2676           0 :   if (data == NULL || data->d_buf == NULL)
    2677           0 :     ERROR (gettext ("section [%2d] '%s': cannot get data: %s\n"),
    2678             :            idx, section_name (ebl, idx), elf_errmsg (-1));
    2679             :   else
    2680             :     {
    2681           0 :       size_t elsize = elf32_fsize (ELF_T_WORD, 1, EV_CURRENT);
    2682           0 :       size_t cnt;
    2683           0 :       Elf32_Word val;
    2684             : 
    2685           0 :       if (data->d_size % elsize != 0)
    2686           0 :         ERROR (gettext ("\
    2687             : section [%2d] '%s': section size not multiple of sizeof(Elf32_Word)\n"),
    2688             :                idx, section_name (ebl, idx));
    2689             : 
    2690           0 :       if (data->d_size < elsize)
    2691             :         {
    2692           0 :           ERROR (gettext ("\
    2693             : section [%2d] '%s': section group without flags word\n"),
    2694             :                idx, section_name (ebl, idx));
    2695           0 :           return;
    2696             :         }
    2697           0 :       else if (be_strict)
    2698             :         {
    2699           0 :           if (data->d_size < 2 * elsize)
    2700           0 :             ERROR (gettext ("\
    2701             : section [%2d] '%s': section group without member\n"),
    2702             :                    idx, section_name (ebl, idx));
    2703           0 :           else if (data->d_size < 3 * elsize)
    2704           0 :             ERROR (gettext ("\
    2705             : section [%2d] '%s': section group with only one member\n"),
    2706             :                    idx, section_name (ebl, idx));
    2707             :         }
    2708             : 
    2709             : #if ALLOW_UNALIGNED
    2710           0 :       val = *((Elf32_Word *) data->d_buf);
    2711             : #else
    2712             :       memcpy (&val, data->d_buf, elsize);
    2713             : #endif
    2714           0 :       if ((val & ~GRP_COMDAT) != 0)
    2715           0 :         ERROR (gettext ("section [%2d] '%s': unknown section group flags\n"),
    2716             :                idx, section_name (ebl, idx));
    2717             : 
    2718           0 :       for (cnt = elsize; cnt + elsize <= data->d_size; cnt += elsize)
    2719             :         {
    2720             : #if ALLOW_UNALIGNED
    2721           0 :           val = *((Elf32_Word *) ((char *) data->d_buf + cnt));
    2722             : #else
    2723             :           memcpy (&val, (char *) data->d_buf + cnt, elsize);
    2724             : #endif
    2725             : 
    2726           0 :           if (val > shnum)
    2727           0 :             ERROR (gettext ("\
    2728             : section [%2d] '%s': section index %zu out of range\n"),
    2729             :                    idx, section_name (ebl, idx), cnt / elsize);
    2730             :           else
    2731             :             {
    2732           0 :               GElf_Shdr refshdr_mem;
    2733           0 :               GElf_Shdr *refshdr = gelf_getshdr (elf_getscn (ebl->elf, val),
    2734             :                                                  &refshdr_mem);
    2735           0 :               if (refshdr == NULL)
    2736           0 :                 ERROR (gettext ("\
    2737             : section [%2d] '%s': cannot get section header for element %zu: %s\n"),
    2738             :                        idx, section_name (ebl, idx), cnt / elsize,
    2739             :                        elf_errmsg (-1));
    2740             :               else
    2741             :                 {
    2742           0 :                   if (refshdr->sh_type == SHT_GROUP)
    2743           0 :                     ERROR (gettext ("\
    2744             : section [%2d] '%s': section group contains another group [%2d] '%s'\n"),
    2745             :                            idx, section_name (ebl, idx),
    2746             :                            val, section_name (ebl, val));
    2747             : 
    2748           0 :                   if ((refshdr->sh_flags & SHF_GROUP) == 0)
    2749           0 :                     ERROR (gettext ("\
    2750             : section [%2d] '%s': element %zu references section [%2d] '%s' without SHF_GROUP flag set\n"),
    2751             :                            idx, section_name (ebl, idx), cnt / elsize,
    2752             :                            val, section_name (ebl, val));
    2753             :                 }
    2754             : 
    2755           0 :               if (val < shnum && ++scnref[val] == 2)
    2756           0 :                 ERROR (gettext ("\
    2757             : section [%2d] '%s' is contained in more than one section group\n"),
    2758             :                        val, section_name (ebl, val));
    2759             :             }
    2760             :         }
    2761             :     }
    2762             : }
    2763             : 
    2764             : 
    2765             : static const char *
    2766           0 : section_flags_string (GElf_Word flags, char *buf, size_t len)
    2767             : {
    2768           0 :   if (flags == 0)
    2769             :     return "none";
    2770             : 
    2771             :   static const struct
    2772             :   {
    2773             :     GElf_Word flag;
    2774             :     const char *name;
    2775             :   } known_flags[] =
    2776             :     {
    2777             : #define NEWFLAG(name) { SHF_##name, #name }
    2778             :       NEWFLAG (WRITE),
    2779             :       NEWFLAG (ALLOC),
    2780             :       NEWFLAG (EXECINSTR),
    2781             :       NEWFLAG (MERGE),
    2782             :       NEWFLAG (STRINGS),
    2783             :       NEWFLAG (INFO_LINK),
    2784             :       NEWFLAG (LINK_ORDER),
    2785             :       NEWFLAG (OS_NONCONFORMING),
    2786             :       NEWFLAG (GROUP),
    2787             :       NEWFLAG (TLS),
    2788             :       NEWFLAG (COMPRESSED)
    2789             :     };
    2790             : #undef NEWFLAG
    2791             :   const size_t nknown_flags = sizeof (known_flags) / sizeof (known_flags[0]);
    2792             : 
    2793             :   char *cp = buf;
    2794             : 
    2795           0 :   for (size_t cnt = 0; cnt < nknown_flags; ++cnt)
    2796           0 :     if (flags & known_flags[cnt].flag)
    2797             :       {
    2798           0 :         if (cp != buf && len > 1)
    2799             :           {
    2800           0 :             *cp++ = '|';
    2801           0 :             --len;
    2802             :           }
    2803             : 
    2804           0 :         size_t ncopy = MIN (len - 1, strlen (known_flags[cnt].name));
    2805           0 :         cp = mempcpy (cp, known_flags[cnt].name, ncopy);
    2806           0 :         len -= ncopy;
    2807             : 
    2808           0 :         flags ^= known_flags[cnt].flag;
    2809             :       }
    2810             : 
    2811           0 :   if (flags != 0 || cp == buf)
    2812           0 :     snprintf (cp, len - 1, "%" PRIx64, (uint64_t) flags);
    2813             : 
    2814           0 :   *cp = '\0';
    2815             : 
    2816           0 :   return buf;
    2817             : }
    2818             : 
    2819             : 
    2820             : static int
    2821          66 : has_copy_reloc (Ebl *ebl, unsigned int symscnndx, unsigned int symndx)
    2822             : {
    2823             :   /* First find the relocation section for the symbol table.  */
    2824          66 :   Elf_Scn *scn = NULL;
    2825          66 :   GElf_Shdr shdr_mem;
    2826          66 :   GElf_Shdr *shdr = NULL;
    2827         586 :   while ((scn = elf_nextscn (ebl->elf, scn)) != NULL)
    2828             :     {
    2829         586 :       shdr = gelf_getshdr (scn, &shdr_mem);
    2830         586 :       if (shdr != NULL
    2831         586 :           && (shdr->sh_type == SHT_REL || shdr->sh_type == SHT_RELA)
    2832          66 :           && shdr->sh_link == symscnndx)
    2833             :         /* Found the section.  */
    2834             :         break;
    2835             :     }
    2836             : 
    2837          66 :   if (scn == NULL)
    2838             :     return 0;
    2839             : 
    2840          66 :   Elf_Data *data = elf_getdata (scn, NULL);
    2841          66 :   if (data == NULL || shdr->sh_entsize == 0)
    2842             :     return 0;
    2843             : 
    2844          66 :   if (shdr->sh_type == SHT_REL)
    2845          36 :     for (int i = 0; (size_t) i < shdr->sh_size / shdr->sh_entsize; ++i)
    2846             :       {
    2847          36 :         GElf_Rel rel_mem;
    2848          36 :         GElf_Rel *rel = gelf_getrel (data, i, &rel_mem);
    2849          36 :         if (rel == NULL)
    2850           0 :           continue;
    2851             : 
    2852          36 :         if (GELF_R_SYM (rel->r_info) == symndx
    2853           8 :             && ebl_copy_reloc_p (ebl, GELF_R_TYPE (rel->r_info)))
    2854           8 :           return 1;
    2855             :       }
    2856             :   else
    2857      270158 :     for (int i = 0; (size_t) i < shdr->sh_size / shdr->sh_entsize; ++i)
    2858             :       {
    2859      270158 :         GElf_Rela rela_mem;
    2860      270158 :         GElf_Rela *rela = gelf_getrela (data, i, &rela_mem);
    2861      270158 :         if (rela == NULL)
    2862           0 :           continue;
    2863             : 
    2864      270158 :         if (GELF_R_SYM (rela->r_info) == symndx
    2865          74 :             && ebl_copy_reloc_p (ebl, GELF_R_TYPE (rela->r_info)))
    2866          58 :           return 1;
    2867             :       }
    2868             : 
    2869             :   return 0;
    2870             : }
    2871             : 
    2872             : 
    2873             : static int
    2874           0 : in_nobits_scn (Ebl *ebl, unsigned int shndx)
    2875             : {
    2876           0 :   GElf_Shdr shdr_mem;
    2877           0 :   GElf_Shdr *shdr = gelf_getshdr (elf_getscn (ebl->elf, shndx), &shdr_mem);
    2878           0 :   return shdr != NULL && shdr->sh_type == SHT_NOBITS;
    2879             : }
    2880             : 
    2881             : 
    2882             : static struct version_namelist
    2883             : {
    2884             :   const char *objname;
    2885             :   const char *name;
    2886             :   GElf_Versym ndx;
    2887             :   enum { ver_def, ver_need } type;
    2888             :   struct version_namelist *next;
    2889             : } *version_namelist;
    2890             : 
    2891             : 
    2892             : static int
    2893         403 : add_version (const char *objname, const char *name, GElf_Versym ndx, int type)
    2894             : {
    2895             :   /* Check that there are no duplications.  */
    2896         403 :   struct version_namelist *nlp = version_namelist;
    2897        1993 :   while (nlp != NULL)
    2898             :     {
    2899        1590 :       if (((nlp->objname == NULL && objname == NULL)
    2900        1405 :            || (nlp->objname != NULL && objname != NULL
    2901        1187 :                && strcmp (nlp->objname, objname) == 0))
    2902         526 :           && strcmp (nlp->name, name) == 0)
    2903           0 :         return nlp->type == ver_def ? 1 : -1;
    2904        1590 :       nlp = nlp->next;
    2905             :     }
    2906             : 
    2907         403 :   nlp = xmalloc (sizeof (*nlp));
    2908         403 :   nlp->objname = objname;
    2909         403 :   nlp->name = name;
    2910         403 :   nlp->ndx = ndx;
    2911         403 :   nlp->type = type;
    2912         403 :   nlp->next = version_namelist;
    2913         403 :   version_namelist = nlp;
    2914             : 
    2915         403 :   return 0;
    2916             : }
    2917             : 
    2918             : 
    2919             : static void
    2920          92 : check_versym (Ebl *ebl, int idx)
    2921             : {
    2922          92 :   Elf_Scn *scn = elf_getscn (ebl->elf, idx);
    2923          92 :   GElf_Shdr shdr_mem;
    2924          92 :   GElf_Shdr *shdr = gelf_getshdr (scn, &shdr_mem);
    2925          92 :   if (shdr == NULL)
    2926             :     /* The error has already been reported.  */
    2927           0 :     return;
    2928             : 
    2929          92 :   Elf_Data *data = elf_getdata (scn, NULL);
    2930          92 :   if (data == NULL)
    2931             :     {
    2932           0 :       ERROR (gettext ("section [%2d] '%s': cannot get section data\n"),
    2933             :              idx, section_name (ebl, idx));
    2934           0 :       return;
    2935             :     }
    2936             : 
    2937          92 :   Elf_Scn *symscn = elf_getscn (ebl->elf, shdr->sh_link);
    2938          92 :   GElf_Shdr symshdr_mem;
    2939          92 :   GElf_Shdr *symshdr = gelf_getshdr (symscn, &symshdr_mem);
    2940          92 :   if (symshdr == NULL)
    2941             :     /* The error has already been reported.  */
    2942             :     return;
    2943             : 
    2944          92 :   if (symshdr->sh_type != SHT_DYNSYM)
    2945             :     {
    2946           0 :       ERROR (gettext ("\
    2947             : section [%2d] '%s' refers in sh_link to section [%2d] '%s' which is no dynamic symbol table\n"),
    2948             :              idx, section_name (ebl, idx),
    2949             :              shdr->sh_link, section_name (ebl, shdr->sh_link));
    2950           0 :       return;
    2951             :     }
    2952             : 
    2953             :   /* The number of elements in the version symbol table must be the
    2954             :      same as the number of symbols.  */
    2955          92 :   if (shdr->sh_entsize != 0 && symshdr->sh_entsize != 0
    2956         184 :       && (shdr->sh_size / shdr->sh_entsize
    2957          92 :           != symshdr->sh_size / symshdr->sh_entsize))
    2958           0 :     ERROR (gettext ("\
    2959             : section [%2d] '%s' has different number of entries than symbol table [%2d] '%s'\n"),
    2960             :            idx, section_name (ebl, idx),
    2961             :            shdr->sh_link, section_name (ebl, shdr->sh_link));
    2962             : 
    2963          92 :   Elf_Data *symdata = elf_getdata (symscn, NULL);
    2964          92 :   if (symdata == NULL || shdr->sh_entsize == 0)
    2965             :     /* The error has already been reported.  */
    2966             :     return;
    2967             : 
    2968        4931 :   for (int cnt = 1; (size_t) cnt < shdr->sh_size / shdr->sh_entsize; ++cnt)
    2969             :     {
    2970        4839 :       GElf_Versym versym_mem;
    2971        4839 :       GElf_Versym *versym = gelf_getversym (data, cnt, &versym_mem);
    2972        4839 :       if (versym == NULL)
    2973             :         {
    2974           0 :           ERROR (gettext ("\
    2975             : section [%2d] '%s': symbol %d: cannot read version data\n"),
    2976             :                  idx, section_name (ebl, idx), cnt);
    2977           0 :           break;
    2978             :         }
    2979             : 
    2980        4839 :       GElf_Sym sym_mem;
    2981        4839 :       GElf_Sym *sym = gelf_getsym (symdata, cnt, &sym_mem);
    2982        4839 :       if (sym == NULL)
    2983             :         /* Already reported elsewhere.  */
    2984           0 :         continue;
    2985             : 
    2986        4839 :       if (*versym == VER_NDX_GLOBAL)
    2987             :         {
    2988             :           /* Global symbol.  Make sure it is not defined as local.  */
    2989         653 :           if (GELF_ST_BIND (sym->st_info) == STB_LOCAL)
    2990           0 :             ERROR (gettext ("\
    2991             : section [%2d] '%s': symbol %d: local symbol with global scope\n"),
    2992             :                    idx, section_name (ebl, idx), cnt);
    2993             :         }
    2994        4186 :       else if (*versym != VER_NDX_LOCAL)
    2995             :         {
    2996             :           /* Versioned symbol.  Make sure it is not defined as local.  */
    2997        3386 :           if (!gnuld && GELF_ST_BIND (sym->st_info) == STB_LOCAL)
    2998           0 :             ERROR (gettext ("\
    2999             : section [%2d] '%s': symbol %d: local symbol with version\n"),
    3000             :                    idx, section_name (ebl, idx), cnt);
    3001             : 
    3002             :           /* Look through the list of defined versions and locate the
    3003             :              index we need for this symbol.  */
    3004        3386 :           struct version_namelist *runp = version_namelist;
    3005       14120 :           while (runp != NULL)
    3006       14120 :             if (runp->ndx == (*versym & (GElf_Versym) 0x7fff))
    3007             :               break;
    3008             :             else
    3009       10734 :               runp = runp->next;
    3010             : 
    3011        3386 :           if (runp == NULL)
    3012           0 :             ERROR (gettext ("\
    3013             : section [%2d] '%s': symbol %d: invalid version index %d\n"),
    3014             :                    idx, section_name (ebl, idx), cnt, (int) *versym);
    3015        3386 :           else if (sym->st_shndx == SHN_UNDEF
    3016        2702 :                    && runp->type == ver_def)
    3017           0 :             ERROR (gettext ("\
    3018             : section [%2d] '%s': symbol %d: version index %d is for defined version\n"),
    3019             :                    idx, section_name (ebl, idx), cnt, (int) *versym);
    3020        3386 :           else if (sym->st_shndx != SHN_UNDEF
    3021         684 :                    && runp->type == ver_need)
    3022             :             {
    3023             :               /* Unless this symbol has a copy relocation associated
    3024             :                  this must not happen.  */
    3025          66 :               if (!has_copy_reloc (ebl, shdr->sh_link, cnt)
    3026           0 :                   && !in_nobits_scn (ebl, sym->st_shndx))
    3027           0 :                 ERROR (gettext ("\
    3028             : section [%2d] '%s': symbol %d: version index %d is for requested version\n"),
    3029             :                        idx, section_name (ebl, idx), cnt, (int) *versym);
    3030             :             }
    3031             :         }
    3032             :     }
    3033             : }
    3034             : 
    3035             : 
    3036             : static int
    3037         209 : unknown_dependency_p (Elf *elf, const char *fname)
    3038             : {
    3039         209 :   GElf_Phdr phdr_mem;
    3040         209 :   GElf_Phdr *phdr = NULL;
    3041             : 
    3042         209 :   unsigned int i;
    3043        1237 :   for (i = 0; i < phnum; ++i)
    3044        1237 :     if ((phdr = gelf_getphdr (elf, i, &phdr_mem)) != NULL
    3045        1237 :         && phdr->p_type == PT_DYNAMIC)
    3046             :       break;
    3047             : 
    3048         209 :   if (i == phnum)
    3049             :     return 1;
    3050         209 :   assert (phdr != NULL);
    3051         209 :   Elf_Scn *scn = gelf_offscn (elf, phdr->p_offset);
    3052         209 :   GElf_Shdr shdr_mem;
    3053         209 :   GElf_Shdr *shdr = gelf_getshdr (scn, &shdr_mem);
    3054         209 :   Elf_Data *data = elf_getdata (scn, NULL);
    3055         209 :   if (shdr != NULL && shdr->sh_type == SHT_DYNAMIC
    3056         209 :       && data != NULL && shdr->sh_entsize != 0)
    3057         697 :     for (size_t j = 0; j < shdr->sh_size / shdr->sh_entsize; ++j)
    3058             :       {
    3059         697 :         GElf_Dyn dyn_mem;
    3060         697 :         GElf_Dyn *dyn = gelf_getdyn (data, j, &dyn_mem);
    3061         697 :         if (dyn != NULL && dyn->d_tag == DT_NEEDED)
    3062             :           {
    3063         671 :             const char *str = elf_strptr (elf, shdr->sh_link, dyn->d_un.d_val);
    3064         671 :             if (str != NULL && strcmp (str, fname) == 0)
    3065             :               /* Found it.  */
    3066         209 :               return 0;
    3067             :           }
    3068             :       }
    3069             : 
    3070             :   return 1;
    3071             : }
    3072             : 
    3073             : 
    3074             : static unsigned int nverneed;
    3075             : 
    3076             : static void
    3077           0 : check_verneed (Ebl *ebl, GElf_Shdr *shdr, int idx)
    3078             : {
    3079           0 :   if (++nverneed == 2)
    3080           0 :     ERROR (gettext ("more than one version reference section present\n"));
    3081             : 
    3082           0 :   GElf_Shdr strshdr_mem;
    3083           0 :   GElf_Shdr *strshdr = gelf_getshdr (elf_getscn (ebl->elf, shdr->sh_link),
    3084             :                                      &strshdr_mem);
    3085           0 :   if (strshdr == NULL)
    3086           0 :     return;
    3087           0 :   if (strshdr->sh_type != SHT_STRTAB)
    3088           0 :     ERROR (gettext ("\
    3089             : section [%2d] '%s': sh_link does not link to string table\n"),
    3090             :            idx, section_name (ebl, idx));
    3091             : 
    3092           0 :   Elf_Data *data = elf_getdata (elf_getscn (ebl->elf, idx), NULL);
    3093           0 :   if (data == NULL)
    3094             :     {
    3095           0 :       ERROR (gettext ("section [%2d] '%s': cannot get section data\n"),
    3096             :              idx, section_name (ebl, idx));
    3097           0 :       return;
    3098             :     }
    3099           0 :   unsigned int offset = 0;
    3100           0 :   for (Elf64_Word cnt = shdr->sh_info; cnt > 0; )
    3101             :     {
    3102           0 :       cnt--;
    3103             : 
    3104             :       /* Get the data at the next offset.  */
    3105           0 :       GElf_Verneed needmem;
    3106           0 :       GElf_Verneed *need = gelf_getverneed (data, offset, &needmem);
    3107           0 :       if (need == NULL)
    3108             :         break;
    3109             : 
    3110           0 :       unsigned int auxoffset = offset + need->vn_aux;
    3111             : 
    3112           0 :       if (need->vn_version != EV_CURRENT)
    3113           0 :         ERROR (gettext ("\
    3114             : section [%2d] '%s': entry %d has wrong version %d\n"),
    3115             :                idx, section_name (ebl, idx), cnt, (int) need->vn_version);
    3116             : 
    3117           0 :       if (need->vn_cnt > 0 && need->vn_aux < gelf_fsize (ebl->elf, ELF_T_VNEED,
    3118             :                                                          1, EV_CURRENT))
    3119             :         {
    3120           0 :           ERROR (gettext ("\
    3121             : section [%2d] '%s': entry %d has wrong offset of auxiliary data\n"),
    3122             :                  idx, section_name (ebl, idx), cnt);
    3123           0 :           break;
    3124             :         }
    3125             : 
    3126           0 :       const char *libname = elf_strptr (ebl->elf, shdr->sh_link,
    3127           0 :                                         need->vn_file);
    3128           0 :       if (libname == NULL)
    3129             :         {
    3130           0 :           ERROR (gettext ("\
    3131             : section [%2d] '%s': entry %d has invalid file reference\n"),
    3132             :                  idx, section_name (ebl, idx), cnt);
    3133           0 :           goto next_need;
    3134             :         }
    3135             : 
    3136             :       /* Check that there is a DT_NEEDED entry for the referenced library.  */
    3137           0 :       if (unknown_dependency_p (ebl->elf, libname))
    3138           0 :         ERROR (gettext ("\
    3139             : section [%2d] '%s': entry %d references unknown dependency\n"),
    3140             :                idx, section_name (ebl, idx), cnt);
    3141             : 
    3142           0 :       for (int cnt2 = need->vn_cnt; --cnt2 >= 0; )
    3143             :         {
    3144           0 :           GElf_Vernaux auxmem;
    3145           0 :           GElf_Vernaux *aux = gelf_getvernaux (data, auxoffset, &auxmem);
    3146           0 :           if (aux == NULL)
    3147             :             break;
    3148             : 
    3149           0 :           if ((aux->vna_flags & ~VER_FLG_WEAK) != 0)
    3150           0 :             ERROR (gettext ("\
    3151             : section [%2d] '%s': auxiliary entry %d of entry %d has unknown flag\n"),
    3152             :                    idx, section_name (ebl, idx), need->vn_cnt - cnt2, cnt);
    3153             : 
    3154           0 :           const char *verstr = elf_strptr (ebl->elf, shdr->sh_link,
    3155           0 :                                            aux->vna_name);
    3156           0 :           if (verstr == NULL)
    3157             :             {
    3158           0 :               ERROR (gettext ("\
    3159             : section [%2d] '%s': auxiliary entry %d of entry %d has invalid name reference\n"),
    3160             :                      idx, section_name (ebl, idx), need->vn_cnt - cnt2, cnt);
    3161           0 :               break;
    3162             :             }
    3163             :           else
    3164             :             {
    3165           0 :               GElf_Word hashval = elf_hash (verstr);
    3166           0 :               if (hashval != aux->vna_hash)
    3167           0 :                 ERROR (gettext ("\
    3168             : section [%2d] '%s': auxiliary entry %d of entry %d has wrong hash value: %#x, expected %#x\n"),
    3169             :                        idx, section_name (ebl, idx), need->vn_cnt - cnt2,
    3170             :                        cnt, (int) hashval, (int) aux->vna_hash);
    3171             : 
    3172           0 :               int res = add_version (libname, verstr, aux->vna_other,
    3173             :                                      ver_need);
    3174           0 :               if (unlikely (res !=0))
    3175             :                 {
    3176           0 :                   ERROR (gettext ("\
    3177             : section [%2d] '%s': auxiliary entry %d of entry %d has duplicate version name '%s'\n"),
    3178             :                          idx, section_name (ebl, idx), need->vn_cnt - cnt2,
    3179             :                          cnt, verstr);
    3180             :                 }
    3181             :             }
    3182             : 
    3183           0 :           if ((aux->vna_next != 0 || cnt2 > 0)
    3184           0 :               && aux->vna_next < gelf_fsize (ebl->elf, ELF_T_VNAUX, 1,
    3185             :                                              EV_CURRENT))
    3186             :             {
    3187           0 :               ERROR (gettext ("\
    3188             : section [%2d] '%s': auxiliary entry %d of entry %d has wrong next field\n"),
    3189             :                      idx, section_name (ebl, idx), need->vn_cnt - cnt2, cnt);
    3190           0 :               break;
    3191             :             }
    3192             : 
    3193           0 :           auxoffset += MAX (aux->vna_next,
    3194             :                             gelf_fsize (ebl->elf, ELF_T_VNAUX, 1, EV_CURRENT));
    3195             :         }
    3196             : 
    3197             :       /* Find the next offset.  */
    3198           0 :     next_need:
    3199           0 :       offset += need->vn_next;
    3200             : 
    3201           0 :       if ((need->vn_next != 0 || cnt > 0)
    3202           0 :           && offset < auxoffset)
    3203             :         {
    3204           0 :           ERROR (gettext ("\
    3205             : section [%2d] '%s': entry %d has invalid offset to next entry\n"),
    3206             :                  idx, section_name (ebl, idx), cnt);
    3207           0 :           break;
    3208             :         }
    3209             : 
    3210           0 :       if (need->vn_next == 0 && cnt > 0)
    3211             :         {
    3212           0 :           ERROR (gettext ("\
    3213             : section [%2d] '%s': entry %d has zero offset to next entry, but sh_info says there are more entries\n"),
    3214             :                  idx, section_name (ebl, idx), cnt);
    3215           0 :           break;
    3216             :         }
    3217             :     }
    3218             : }
    3219             : 
    3220             : 
    3221             : static unsigned int nverdef;
    3222             : 
    3223             : static void
    3224           0 : check_verdef (Ebl *ebl, GElf_Shdr *shdr, int idx)
    3225             : {
    3226           0 :   if (++nverdef == 2)
    3227           0 :     ERROR (gettext ("more than one version definition section present\n"));
    3228             : 
    3229           0 :   GElf_Shdr strshdr_mem;
    3230           0 :   GElf_Shdr *strshdr = gelf_getshdr (elf_getscn (ebl->elf, shdr->sh_link),
    3231             :                                      &strshdr_mem);
    3232           0 :   if (strshdr == NULL)
    3233           0 :     return;
    3234           0 :   if (strshdr->sh_type != SHT_STRTAB)
    3235           0 :     ERROR (gettext ("\
    3236             : section [%2d] '%s': sh_link does not link to string table\n"),
    3237             :            idx, section_name (ebl, idx));
    3238             : 
    3239           0 :   Elf_Data *data = elf_getdata (elf_getscn (ebl->elf, idx), NULL);
    3240           0 :   if (data == NULL)
    3241             :     {
    3242           0 :     no_data:
    3243           0 :       ERROR (gettext ("section [%2d] '%s': cannot get section data\n"),
    3244             :              idx, section_name (ebl, idx));
    3245           0 :       return;
    3246             :     }
    3247             : 
    3248             :   /* Iterate over all version definition entries.  We check that there
    3249             :      is a BASE entry and that each index is unique.  To do the later
    3250             :      we collection the information in a list which is later
    3251             :      examined.  */
    3252           0 :   struct namelist
    3253             :   {
    3254             :     const char *name;
    3255             :     struct namelist *next;
    3256           0 :   } *namelist = NULL;
    3257           0 :   struct namelist *refnamelist = NULL;
    3258             : 
    3259           0 :   bool has_base = false;
    3260           0 :   unsigned int offset = 0;
    3261           0 :   for (Elf64_Word cnt = shdr->sh_info; cnt > 0; )
    3262             :     {
    3263           0 :       cnt--;
    3264             : 
    3265             :       /* Get the data at the next offset.  */
    3266           0 :       GElf_Verdef defmem;
    3267           0 :       GElf_Verdef *def = gelf_getverdef (data, offset, &defmem);
    3268           0 :       if (def == NULL)
    3269           0 :         goto no_data;
    3270             : 
    3271           0 :       if ((def->vd_flags & VER_FLG_BASE) != 0)
    3272             :         {
    3273           0 :           if (has_base)
    3274           0 :             ERROR (gettext ("\
    3275             : section [%2d] '%s': more than one BASE definition\n"),
    3276             :                    idx, section_name (ebl, idx));
    3277           0 :           if (def->vd_ndx != VER_NDX_GLOBAL)
    3278           0 :             ERROR (gettext ("\
    3279             : section [%2d] '%s': BASE definition must have index VER_NDX_GLOBAL\n"),
    3280             :                    idx, section_name (ebl, idx));
    3281             :           has_base = true;
    3282             :         }
    3283           0 :       if ((def->vd_flags & ~(VER_FLG_BASE|VER_FLG_WEAK)) != 0)
    3284           0 :         ERROR (gettext ("\
    3285             : section [%2d] '%s': entry %d has unknown flag\n"),
    3286             :                idx, section_name (ebl, idx), cnt);
    3287             : 
    3288           0 :       if (def->vd_version != EV_CURRENT)
    3289           0 :         ERROR (gettext ("\
    3290             : section [%2d] '%s': entry %d has wrong version %d\n"),
    3291             :                idx, section_name (ebl, idx), cnt, (int) def->vd_version);
    3292             : 
    3293           0 :       if (def->vd_cnt > 0 && def->vd_aux < gelf_fsize (ebl->elf, ELF_T_VDEF,
    3294             :                                                        1, EV_CURRENT))
    3295             :         {
    3296           0 :           ERROR (gettext ("\
    3297             : section [%2d] '%s': entry %d has wrong offset of auxiliary data\n"),
    3298             :                  idx, section_name (ebl, idx), cnt);
    3299           0 :           break;
    3300             :         }
    3301             : 
    3302           0 :       unsigned int auxoffset = offset + def->vd_aux;
    3303           0 :       GElf_Verdaux auxmem;
    3304           0 :       GElf_Verdaux *aux = gelf_getverdaux (data, auxoffset, &auxmem);
    3305           0 :       if (aux == NULL)
    3306           0 :         goto no_data;
    3307             : 
    3308           0 :       const char *name = elf_strptr (ebl->elf, shdr->sh_link, aux->vda_name);
    3309           0 :       if (name == NULL)
    3310             :         {
    3311           0 :           ERROR (gettext ("\
    3312             : section [%2d] '%s': entry %d has invalid name reference\n"),
    3313             :                  idx, section_name (ebl, idx), cnt);
    3314           0 :           goto next_def;
    3315             :         }
    3316           0 :       GElf_Word hashval = elf_hash (name);
    3317           0 :       if (def->vd_hash != hashval)
    3318           0 :         ERROR (gettext ("\
    3319             : section [%2d] '%s': entry %d has wrong hash value: %#x, expected %#x\n"),
    3320             :                idx, section_name (ebl, idx), cnt, (int) hashval,
    3321             :                (int) def->vd_hash);
    3322             : 
    3323           0 :       int res = add_version (NULL, name, def->vd_ndx, ver_def);
    3324           0 :       if (unlikely (res !=0))
    3325             :         {
    3326           0 :           ERROR (gettext ("\
    3327             : section [%2d] '%s': entry %d has duplicate version name '%s'\n"),
    3328             :                  idx, section_name (ebl, idx), cnt, name);
    3329             :         }
    3330             : 
    3331           0 :       struct namelist *newname = alloca (sizeof (*newname));
    3332           0 :       newname->name = name;
    3333           0 :       newname->next = namelist;
    3334           0 :       namelist = newname;
    3335             : 
    3336           0 :       auxoffset += aux->vda_next;
    3337           0 :       for (int cnt2 = 1; cnt2 < def->vd_cnt; ++cnt2)
    3338             :         {
    3339           0 :           aux = gelf_getverdaux (data, auxoffset, &auxmem);
    3340           0 :           if (aux == NULL)
    3341           0 :             goto no_data;
    3342             : 
    3343           0 :           name = elf_strptr (ebl->elf, shdr->sh_link, aux->vda_name);
    3344           0 :           if (name == NULL)
    3345             :             {
    3346           0 :               ERROR (gettext ("\
    3347             : section [%2d] '%s': entry %d has invalid name reference in auxiliary data\n"),
    3348             :                      idx, section_name (ebl, idx), cnt);
    3349           0 :               break;
    3350             :             }
    3351             :           else
    3352             :             {
    3353           0 :               newname = alloca (sizeof (*newname));
    3354           0 :               newname->name = name;
    3355           0 :               newname->next = refnamelist;
    3356           0 :               refnamelist = newname;
    3357             :             }
    3358             : 
    3359           0 :           if ((aux->vda_next != 0 || cnt2 + 1 < def->vd_cnt)
    3360           0 :               && aux->vda_next < gelf_fsize (ebl->elf, ELF_T_VDAUX, 1,
    3361             :                                              EV_CURRENT))
    3362             :             {
    3363           0 :               ERROR (gettext ("\
    3364             : section [%2d] '%s': entry %d has wrong next field in auxiliary data\n"),
    3365             :                      idx, section_name (ebl, idx), cnt);
    3366           0 :               break;
    3367             :             }
    3368             : 
    3369           0 :           auxoffset += MAX (aux->vda_next,
    3370             :                             gelf_fsize (ebl->elf, ELF_T_VDAUX, 1, EV_CURRENT));
    3371             :         }
    3372             : 
    3373             :       /* Find the next offset.  */
    3374           0 :     next_def:
    3375           0 :       offset += def->vd_next;
    3376             : 
    3377           0 :       if ((def->vd_next != 0 || cnt > 0)
    3378           0 :           && offset < auxoffset)
    3379             :         {
    3380           0 :           ERROR (gettext ("\
    3381             : section [%2d] '%s': entry %d has invalid offset to next entry\n"),
    3382             :                  idx, section_name (ebl, idx), cnt);
    3383           0 :           break;
    3384             :         }
    3385             : 
    3386           0 :       if (def->vd_next == 0 && cnt > 0)
    3387             :         {
    3388           0 :           ERROR (gettext ("\
    3389             : section [%2d] '%s': entry %d has zero offset to next entry, but sh_info says there are more entries\n"),
    3390             :                  idx, section_name (ebl, idx), cnt);
    3391           0 :           break;
    3392             :         }
    3393             :     }
    3394             : 
    3395           0 :   if (!has_base)
    3396           0 :     ERROR (gettext ("section [%2d] '%s': no BASE definition\n"),
    3397             :            idx, section_name (ebl, idx));
    3398             : 
    3399             :   /* Check whether the referenced names are available.  */
    3400           0 :   while (namelist != NULL)
    3401             :     {
    3402           0 :       struct version_namelist *runp = version_namelist;
    3403           0 :       while (runp != NULL)
    3404             :         {
    3405           0 :           if (runp->type == ver_def
    3406           0 :               && strcmp (runp->name, namelist->name) == 0)
    3407             :             break;
    3408           0 :           runp = runp->next;
    3409             :         }
    3410             : 
    3411           0 :       if (runp == NULL)
    3412           0 :         ERROR (gettext ("\
    3413             : section [%2d] '%s': unknown parent version '%s'\n"),
    3414             :                idx, section_name (ebl, idx), namelist->name);
    3415             : 
    3416           0 :       namelist = namelist->next;
    3417             :     }
    3418             : }
    3419             : 
    3420             : static void
    3421           0 : check_attributes (Ebl *ebl, GElf_Ehdr *ehdr, GElf_Shdr *shdr, int idx)
    3422             : {
    3423           0 :   if (shdr->sh_size == 0)
    3424             :     {
    3425           0 :       ERROR (gettext ("section [%2d] '%s': empty object attributes section\n"),
    3426             :              idx, section_name (ebl, idx));
    3427           0 :       return;
    3428             :     }
    3429             : 
    3430           0 :   Elf_Data *data = elf_rawdata (elf_getscn (ebl->elf, idx), NULL);
    3431           0 :   if (data == NULL || data->d_size == 0 || data->d_buf == NULL)
    3432             :     {
    3433           0 :       ERROR (gettext ("section [%2d] '%s': cannot get section data\n"),
    3434             :              idx, section_name (ebl, idx));
    3435           0 :       return;
    3436             :     }
    3437             : 
    3438           0 :   inline size_t pos (const unsigned char *p)
    3439             :   {
    3440           0 :     return p - (const unsigned char *) data->d_buf;
    3441             :   }
    3442             : 
    3443           0 :   const unsigned char *p = data->d_buf;
    3444           0 :   if (*p++ != 'A')
    3445             :     {
    3446           0 :       ERROR (gettext ("section [%2d] '%s': unrecognized attribute format\n"),
    3447             :              idx, section_name (ebl, idx));
    3448           0 :       return;
    3449             :     }
    3450             : 
    3451             :   inline size_t left (void)
    3452             :   {
    3453           0 :     return (const unsigned char *) data->d_buf + data->d_size - p;
    3454             :   }
    3455             : 
    3456           0 :   while (left () >= 4)
    3457             :     {
    3458           0 :       uint32_t len;
    3459           0 :       memcpy (&len, p, sizeof len);
    3460             : 
    3461           0 :       if (len == 0)
    3462           0 :         ERROR (gettext ("\
    3463             : section [%2d] '%s': offset %zu: zero length field in attribute section\n"),
    3464             :                idx, section_name (ebl, idx), pos (p));
    3465             : 
    3466           0 :       if (MY_ELFDATA != ehdr->e_ident[EI_DATA])
    3467           0 :         CONVERT (len);
    3468             : 
    3469           0 :       if (len > left ())
    3470             :         {
    3471           0 :           ERROR (gettext ("\
    3472             : section [%2d] '%s': offset %zu: invalid length in attribute section\n"),
    3473             :                  idx, section_name (ebl, idx), pos (p));
    3474           0 :           break;
    3475             :         }
    3476             : 
    3477           0 :       const unsigned char *name = p + sizeof len;
    3478           0 :       p += len;
    3479             : 
    3480           0 :       unsigned const char *q = memchr (name, '\0', len);
    3481           0 :       if (q == NULL)
    3482             :         {
    3483           0 :           ERROR (gettext ("\
    3484             : section [%2d] '%s': offset %zu: unterminated vendor name string\n"),
    3485             :                  idx, section_name (ebl, idx), pos (p));
    3486           0 :           break;
    3487             :         }
    3488           0 :       ++q;
    3489             : 
    3490           0 :       if (q - name == sizeof "gnu" && !memcmp (name, "gnu", sizeof "gnu"))
    3491           0 :         while (q < p)
    3492             :           {
    3493           0 :             unsigned const char *chunk = q;
    3494             : 
    3495           0 :             unsigned int subsection_tag;
    3496           0 :             get_uleb128 (subsection_tag, q, p);
    3497             : 
    3498           0 :             if (q >= p)
    3499             :               {
    3500           0 :                 ERROR (gettext ("\
    3501             : section [%2d] '%s': offset %zu: endless ULEB128 in attribute subsection tag\n"),
    3502             :                        idx, section_name (ebl, idx), pos (chunk));
    3503           0 :                 break;
    3504             :               }
    3505             : 
    3506           0 :             uint32_t subsection_len;
    3507           0 :             if (p - q < (ptrdiff_t) sizeof subsection_len)
    3508             :               {
    3509           0 :                 ERROR (gettext ("\
    3510             : section [%2d] '%s': offset %zu: truncated attribute section\n"),
    3511             :                        idx, section_name (ebl, idx), pos (q));
    3512           0 :                 break;
    3513             :               }
    3514             : 
    3515           0 :             memcpy (&subsection_len, q, sizeof subsection_len);
    3516           0 :             if (subsection_len == 0)
    3517             :               {
    3518           0 :                 ERROR (gettext ("\
    3519             : section [%2d] '%s': offset %zu: zero length field in attribute subsection\n"),
    3520             :                        idx, section_name (ebl, idx), pos (q));
    3521             : 
    3522           0 :                 q += sizeof subsection_len;
    3523           0 :                 continue;
    3524             :               }
    3525             : 
    3526           0 :             if (MY_ELFDATA != ehdr->e_ident[EI_DATA])
    3527           0 :               CONVERT (subsection_len);
    3528             : 
    3529             :             /* Don't overflow, ptrdiff_t might be 32bits, but signed.  */
    3530           0 :             if (p - chunk < (ptrdiff_t) subsection_len
    3531           0 :                 || subsection_len >= (uint32_t) PTRDIFF_MAX)
    3532             :               {
    3533           0 :                 ERROR (gettext ("\
    3534             : section [%2d] '%s': offset %zu: invalid length in attribute subsection\n"),
    3535             :                        idx, section_name (ebl, idx), pos (q));
    3536           0 :                 break;
    3537             :               }
    3538             : 
    3539           0 :             const unsigned char *subsection_end = chunk + subsection_len;
    3540           0 :             chunk = q;
    3541           0 :             q = subsection_end;
    3542             : 
    3543           0 :             if (subsection_tag != 1) /* Tag_File */
    3544           0 :               ERROR (gettext ("\
    3545             : section [%2d] '%s': offset %zu: attribute subsection has unexpected tag %u\n"),
    3546             :                      idx, section_name (ebl, idx), pos (chunk), subsection_tag);
    3547             :             else
    3548             :               {
    3549           0 :                 chunk += sizeof subsection_len;
    3550           0 :                 while (chunk < q)
    3551             :                   {
    3552           0 :                     unsigned int tag;
    3553           0 :                     get_uleb128 (tag, chunk, q);
    3554             : 
    3555           0 :                     uint64_t value = 0;
    3556           0 :                     const unsigned char *r = chunk;
    3557           0 :                     if (tag == 32 || (tag & 1) == 0)
    3558             :                       {
    3559           0 :                         get_uleb128 (value, r, q);
    3560           0 :                         if (r > q)
    3561             :                           {
    3562           0 :                             ERROR (gettext ("\
    3563             : section [%2d] '%s': offset %zu: endless ULEB128 in attribute tag\n"),
    3564             :                                    idx, section_name (ebl, idx), pos (chunk));
    3565           0 :                             break;
    3566             :                           }
    3567             :                       }
    3568           0 :                     if (tag == 32 || (tag & 1) != 0)
    3569             :                       {
    3570           0 :                         r = memchr (r, '\0', q - r);
    3571           0 :                         if (r == NULL)
    3572             :                           {
    3573           0 :                             ERROR (gettext ("\
    3574             : section [%2d] '%s': offset %zu: unterminated string in attribute\n"),
    3575             :                                    idx, section_name (ebl, idx), pos (chunk));
    3576           0 :                             break;
    3577             :                           }
    3578           0 :                         ++r;
    3579             :                       }
    3580             : 
    3581           0 :                     const char *tag_name = NULL;
    3582           0 :                     const char *value_name = NULL;
    3583           0 :                     if (!ebl_check_object_attribute (ebl, (const char *) name,
    3584             :                                                      tag, value,
    3585             :                                                      &tag_name, &value_name))
    3586           0 :                       ERROR (gettext ("\
    3587             : section [%2d] '%s': offset %zu: unrecognized attribute tag %u\n"),
    3588             :                              idx, section_name (ebl, idx), pos (chunk), tag);
    3589           0 :                     else if ((tag & 1) == 0 && value_name == NULL)
    3590           0 :                       ERROR (gettext ("\
    3591             : section [%2d] '%s': offset %zu: unrecognized %s attribute value %" PRIu64 "\n"),
    3592             :                              idx, section_name (ebl, idx), pos (chunk),
    3593             :                              tag_name, value);
    3594             : 
    3595           0 :                     chunk = r;
    3596             :                   }
    3597             :               }
    3598             :           }
    3599             :       else
    3600           0 :         ERROR (gettext ("\
    3601             : section [%2d] '%s': offset %zu: vendor '%s' unknown\n"),
    3602             :                idx, section_name (ebl, idx), pos (p), name);
    3603             :     }
    3604             : 
    3605           0 :   if (left () != 0)
    3606           0 :     ERROR (gettext ("\
    3607             : section [%2d] '%s': offset %zu: extra bytes after last attribute section\n"),
    3608             :            idx, section_name (ebl, idx), pos (p));
    3609             : }
    3610             : 
    3611             : static bool has_loadable_segment;
    3612             : static bool has_interp_segment;
    3613             : 
    3614             : static const struct
    3615             : {
    3616             :   const char *name;
    3617             :   size_t namelen;
    3618             :   GElf_Word type;
    3619             :   enum { unused, exact, atleast, exact_or_gnuld } attrflag;
    3620             :   GElf_Word attr;
    3621             :   GElf_Word attr2;
    3622             : } special_sections[] =
    3623             :   {
    3624             :     /* See figure 4-14 in the gABI.  */
    3625             :     { ".bss", 5, SHT_NOBITS, exact, SHF_ALLOC | SHF_WRITE, 0 },
    3626             :     { ".comment", 8, SHT_PROGBITS, atleast, 0, SHF_MERGE | SHF_STRINGS },
    3627             :     { ".data", 6, SHT_PROGBITS, exact, SHF_ALLOC | SHF_WRITE, 0 },
    3628             :     { ".data1", 7, SHT_PROGBITS, exact, SHF_ALLOC | SHF_WRITE, 0 },
    3629             :     { ".debug_str", 11, SHT_PROGBITS, exact_or_gnuld, SHF_MERGE | SHF_STRINGS, 0 },
    3630             :     { ".debug", 6, SHT_PROGBITS, exact, 0, 0 },
    3631             :     { ".dynamic", 9, SHT_DYNAMIC, atleast, SHF_ALLOC, SHF_WRITE },
    3632             :     { ".dynstr", 8, SHT_STRTAB, exact, SHF_ALLOC, 0 },
    3633             :     { ".dynsym", 8, SHT_DYNSYM, exact, SHF_ALLOC, 0 },
    3634             :     { ".fini", 6, SHT_PROGBITS, exact, SHF_ALLOC | SHF_EXECINSTR, 0 },
    3635             :     { ".fini_array", 12, SHT_FINI_ARRAY, exact, SHF_ALLOC | SHF_WRITE, 0 },
    3636             :     { ".got", 5, SHT_PROGBITS, unused, 0, 0 }, // XXX more info?
    3637             :     { ".hash", 6, SHT_HASH, exact, SHF_ALLOC, 0 },
    3638             :     { ".init", 6, SHT_PROGBITS, exact, SHF_ALLOC | SHF_EXECINSTR, 0 },
    3639             :     { ".init_array", 12, SHT_INIT_ARRAY, exact, SHF_ALLOC | SHF_WRITE, 0 },
    3640             :     { ".interp", 8, SHT_PROGBITS, atleast, 0, SHF_ALLOC }, // XXX more tests?
    3641             :     { ".line", 6, SHT_PROGBITS, exact, 0, 0 },
    3642             :     { ".note", 6, SHT_NOTE, atleast, 0, SHF_ALLOC },
    3643             :     { ".plt", 5, SHT_PROGBITS, unused, 0, 0 }, // XXX more tests
    3644             :     { ".preinit_array", 15, SHT_PREINIT_ARRAY, exact, SHF_ALLOC | SHF_WRITE, 0 },
    3645             :     { ".rela", 5, SHT_RELA, atleast, 0, SHF_ALLOC | SHF_INFO_LINK }, // XXX more tests
    3646             :     { ".rel", 4, SHT_REL, atleast, 0, SHF_ALLOC | SHF_INFO_LINK }, // XXX more tests
    3647             :     { ".rodata", 8, SHT_PROGBITS, atleast, SHF_ALLOC, SHF_MERGE | SHF_STRINGS },
    3648             :     { ".rodata1", 9, SHT_PROGBITS, atleast, SHF_ALLOC, SHF_MERGE | SHF_STRINGS },
    3649             :     { ".shstrtab", 10, SHT_STRTAB, exact, 0, 0 },
    3650             :     { ".strtab", 8, SHT_STRTAB, atleast, 0, SHF_ALLOC }, // XXX more tests
    3651             :     { ".symtab", 8, SHT_SYMTAB, atleast, 0, SHF_ALLOC }, // XXX more tests
    3652             :     { ".symtab_shndx", 14, SHT_SYMTAB_SHNDX, atleast, 0, SHF_ALLOC }, // XXX more tests
    3653             :     { ".tbss", 6, SHT_NOBITS, exact, SHF_ALLOC | SHF_WRITE | SHF_TLS, 0 },
    3654             :     { ".tdata", 7, SHT_PROGBITS, exact, SHF_ALLOC | SHF_WRITE | SHF_TLS, 0 },
    3655             :     { ".tdata1", 8, SHT_PROGBITS, exact, SHF_ALLOC | SHF_WRITE | SHF_TLS, 0 },
    3656             :     { ".text", 6, SHT_PROGBITS, exact, SHF_ALLOC | SHF_EXECINSTR, 0 },
    3657             : 
    3658             :     /* The following are GNU extensions.  */
    3659             :     { ".gnu.version", 13, SHT_GNU_versym, exact, SHF_ALLOC, 0 },
    3660             :     { ".gnu.version_d", 15, SHT_GNU_verdef, exact, SHF_ALLOC, 0 },
    3661             :     { ".gnu.version_r", 15, SHT_GNU_verneed, exact, SHF_ALLOC, 0 },
    3662             :     { ".gnu.attributes", 16, SHT_GNU_ATTRIBUTES, exact, 0, 0 },
    3663             :   };
    3664             : #define nspecial_sections \
    3665             :   (sizeof (special_sections) / sizeof (special_sections[0]))
    3666             : 
    3667             : #define IS_KNOWN_SPECIAL(idx, string, prefix)                         \
    3668             :   (special_sections[idx].namelen == sizeof string - (prefix ? 1 : 0)  \
    3669             :    && !memcmp (special_sections[idx].name, string, \
    3670             :                sizeof string - (prefix ? 1 : 0)))
    3671             : 
    3672             : 
    3673             : /* Indeces of some sections we need later.  */
    3674             : static size_t eh_frame_hdr_scnndx;
    3675             : static size_t eh_frame_scnndx;
    3676             : static size_t gcc_except_table_scnndx;
    3677             : 
    3678             : 
    3679             : static void
    3680         193 : check_sections (Ebl *ebl, GElf_Ehdr *ehdr)
    3681             : {
    3682         193 :   if (ehdr->e_shoff == 0)
    3683             :     /* No section header.  */
    3684           0 :     return;
    3685             : 
    3686             :   /* Allocate array to count references in section groups.  */
    3687         193 :   scnref = (int *) xcalloc (shnum, sizeof (int));
    3688             : 
    3689             :   /* Check the zeroth section first.  It must not have any contents
    3690             :      and the section header must contain nonzero value at most in the
    3691             :      sh_size and sh_link fields.  */
    3692         193 :   GElf_Shdr shdr_mem;
    3693         193 :   GElf_Shdr *shdr = gelf_getshdr (elf_getscn (ebl->elf, 0), &shdr_mem);
    3694         193 :   if (shdr == NULL)
    3695           0 :     ERROR (gettext ("cannot get section header of zeroth section\n"));
    3696             :   else
    3697             :     {
    3698         193 :       if (shdr->sh_name != 0)
    3699           0 :         ERROR (gettext ("zeroth section has nonzero name\n"));
    3700         193 :       if (shdr->sh_type != 0)
    3701           0 :         ERROR (gettext ("zeroth section has nonzero type\n"));
    3702         193 :       if (shdr->sh_flags != 0)
    3703           0 :         ERROR (gettext ("zeroth section has nonzero flags\n"));
    3704         193 :       if (shdr->sh_addr != 0)
    3705           0 :         ERROR (gettext ("zeroth section has nonzero address\n"));
    3706         193 :       if (shdr->sh_offset != 0)
    3707           0 :         ERROR (gettext ("zeroth section has nonzero offset\n"));
    3708         193 :       if (shdr->sh_addralign != 0)
    3709           0 :         ERROR (gettext ("zeroth section has nonzero align value\n"));
    3710         193 :       if (shdr->sh_entsize != 0)
    3711           0 :         ERROR (gettext ("zeroth section has nonzero entry size value\n"));
    3712             : 
    3713         193 :       if (shdr->sh_size != 0 && ehdr->e_shnum != 0)
    3714           0 :         ERROR (gettext ("\
    3715             : zeroth section has nonzero size value while ELF header has nonzero shnum value\n"));
    3716             : 
    3717         193 :       if (shdr->sh_link != 0 && ehdr->e_shstrndx != SHN_XINDEX)
    3718           0 :         ERROR (gettext ("\
    3719             : zeroth section has nonzero link value while ELF header does not signal overflow in shstrndx\n"));
    3720             : 
    3721         193 :       if (shdr->sh_info != 0 && ehdr->e_phnum != PN_XNUM)
    3722           0 :         ERROR (gettext ("\
    3723             : zeroth section has nonzero link value while ELF header does not signal overflow in phnum\n"));
    3724             :     }
    3725             : 
    3726         193 :   int *segment_flags = xcalloc (phnum, sizeof segment_flags[0]);
    3727             : 
    3728         193 :   bool dot_interp_section = false;
    3729             : 
    3730         193 :   size_t hash_idx = 0;
    3731         193 :   size_t gnu_hash_idx = 0;
    3732             : 
    3733         193 :   size_t versym_scnndx = 0;
    3734      399518 :   for (size_t cnt = 1; cnt < shnum; ++cnt)
    3735             :     {
    3736      399325 :       Elf_Scn *scn = elf_getscn (ebl->elf, cnt);
    3737      399325 :       shdr = gelf_getshdr (scn, &shdr_mem);
    3738      399325 :       if (shdr == NULL)
    3739             :         {
    3740           0 :           ERROR (gettext ("\
    3741             : cannot get section header for section [%2zu] '%s': %s\n"),
    3742             :                  cnt, section_name (ebl, cnt), elf_errmsg (-1));
    3743           0 :           continue;
    3744             :         }
    3745             : 
    3746      399325 :       const char *scnname = elf_strptr (ebl->elf, shstrndx, shdr->sh_name);
    3747             : 
    3748      399325 :       if (scnname == NULL)
    3749           0 :         ERROR (gettext ("section [%2zu]: invalid name\n"), cnt);
    3750             :       else
    3751             :         {
    3752             :           /* Check whether it is one of the special sections defined in
    3753             :              the gABI.  */
    3754             :           size_t s;
    3755    13950607 :           for (s = 0; s < nspecial_sections; ++s)
    3756    13576884 :             if (strncmp (scnname, special_sections[s].name,
    3757             :                          special_sections[s].namelen) == 0)
    3758             :               {
    3759       25602 :                 char stbuf1[100];
    3760       25602 :                 char stbuf2[100];
    3761       25602 :                 char stbuf3[100];
    3762             : 
    3763       25602 :                 GElf_Word good_type = special_sections[s].type;
    3764       25602 :                 if (IS_KNOWN_SPECIAL (s, ".plt", false)
    3765         106 :                     && ebl_bss_plt_p (ebl))
    3766           7 :                   good_type = SHT_NOBITS;
    3767             : 
    3768             :                 /* In a debuginfo file, any normal section can be SHT_NOBITS.
    3769             :                    This is only invalid for DWARF sections and .shstrtab.  */
    3770       25602 :                 if (shdr->sh_type != good_type
    3771         286 :                     && (shdr->sh_type != SHT_NOBITS
    3772         286 :                         || !is_debuginfo
    3773         286 :                         || IS_KNOWN_SPECIAL (s, ".debug_str", false)
    3774         286 :                         || IS_KNOWN_SPECIAL (s, ".debug", true)
    3775         286 :                         || IS_KNOWN_SPECIAL (s, ".shstrtab", false)))
    3776           0 :                   ERROR (gettext ("\
    3777             : section [%2d] '%s' has wrong type: expected %s, is %s\n"),
    3778             :                          (int) cnt, scnname,
    3779             :                          ebl_section_type_name (ebl, special_sections[s].type,
    3780             :                                                 stbuf1, sizeof (stbuf1)),
    3781             :                          ebl_section_type_name (ebl, shdr->sh_type,
    3782             :                                                 stbuf2, sizeof (stbuf2)));
    3783             : 
    3784       51204 :                 if (special_sections[s].attrflag == exact
    3785       25602 :                     || special_sections[s].attrflag == exact_or_gnuld)
    3786             :                   {
    3787             :                     /* Except for the link order, group bit and
    3788             :                        compression flag all the other bits should
    3789             :                        match exactly.  */
    3790       48274 :                     if ((shdr->sh_flags
    3791       24137 :                          & ~(SHF_LINK_ORDER | SHF_GROUP | SHF_COMPRESSED))
    3792       24137 :                         != special_sections[s].attr
    3793           0 :                         && (special_sections[s].attrflag == exact || !gnuld))
    3794           0 :                       ERROR (gettext ("\
    3795             : section [%2zu] '%s' has wrong flags: expected %s, is %s\n"),
    3796             :                              cnt, scnname,
    3797             :                              section_flags_string (special_sections[s].attr,
    3798             :                                                    stbuf1, sizeof (stbuf1)),
    3799             :                              section_flags_string (shdr->sh_flags
    3800             :                                                    & ~SHF_LINK_ORDER,
    3801             :                                                    stbuf2, sizeof (stbuf2)));
    3802             :                   }
    3803        1465 :                 else if (special_sections[s].attrflag == atleast)
    3804             :                   {
    3805        1251 :                     if ((shdr->sh_flags & special_sections[s].attr)
    3806             :                         != special_sections[s].attr
    3807        1251 :                         || ((shdr->sh_flags
    3808        1251 :                              & ~(SHF_LINK_ORDER | SHF_GROUP | SHF_COMPRESSED
    3809             :                                  | special_sections[s].attr
    3810        1251 :                                  | special_sections[s].attr2))
    3811             :                             != 0))
    3812           0 :                       ERROR (gettext ("\
    3813             : section [%2zu] '%s' has wrong flags: expected %s and possibly %s, is %s\n"),
    3814             :                              cnt, scnname,
    3815             :                              section_flags_string (special_sections[s].attr,
    3816             :                                                    stbuf1, sizeof (stbuf1)),
    3817             :                              section_flags_string (special_sections[s].attr2,
    3818             :                                                    stbuf2, sizeof (stbuf2)),
    3819             :                              section_flags_string (shdr->sh_flags
    3820             :                                                    & ~(SHF_LINK_ORDER
    3821             :                                                        | SHF_GROUP),
    3822             :                                                    stbuf3, sizeof (stbuf3)));
    3823             :                   }
    3824             : 
    3825       25602 :                 if (strcmp (scnname, ".interp") == 0)
    3826             :                   {
    3827          77 :                     dot_interp_section = true;
    3828             : 
    3829          77 :                     if (ehdr->e_type == ET_REL)
    3830           0 :                       ERROR (gettext ("\
    3831             : section [%2zu] '%s' present in object file\n"),
    3832             :                              cnt, scnname);
    3833             : 
    3834          77 :                     if ((shdr->sh_flags & SHF_ALLOC) != 0
    3835          77 :                         && !has_loadable_segment)
    3836           0 :                       ERROR (gettext ("\
    3837             : section [%2zu] '%s' has SHF_ALLOC flag set but there is no loadable segment\n"),
    3838             :                              cnt, scnname);
    3839          77 :                     else if ((shdr->sh_flags & SHF_ALLOC) == 0
    3840           0 :                              && has_loadable_segment)
    3841           0 :                       ERROR (gettext ("\
    3842             : section [%2zu] '%s' has SHF_ALLOC flag not set but there are loadable segments\n"),
    3843             :                              cnt, scnname);
    3844             :                   }
    3845             :                 else
    3846             :                   {
    3847       25525 :                     if (strcmp (scnname, ".symtab_shndx") == 0
    3848           2 :                         && ehdr->e_type != ET_REL)
    3849           0 :                       ERROR (gettext ("\
    3850             : section [%2zu] '%s' is extension section index table in non-object file\n"),
    3851             :                              cnt, scnname);
    3852             : 
    3853             :                     /* These sections must have the SHF_ALLOC flag set iff
    3854             :                        a loadable segment is available.
    3855             : 
    3856             :                        .relxxx
    3857             :                        .strtab
    3858             :                        .symtab
    3859             :                        .symtab_shndx
    3860             : 
    3861             :                        Check that if there is a reference from the
    3862             :                        loaded section these sections also have the
    3863             :                        ALLOC flag set.  */
    3864             : #if 0
    3865             :                     // XXX TODO
    3866             :                     if ((shdr->sh_flags & SHF_ALLOC) != 0
    3867             :                         && !has_loadable_segment)
    3868             :                       ERROR (gettext ("\
    3869             : section [%2zu] '%s' has SHF_ALLOC flag set but there is no loadable segment\n"),
    3870             :                              cnt, scnname);
    3871             :                     else if ((shdr->sh_flags & SHF_ALLOC) == 0
    3872             :                              && has_loadable_segment)
    3873             :                       ERROR (gettext ("\
    3874             : section [%2zu] '%s' has SHF_ALLOC flag not set but there are loadable segments\n"),
    3875             :                              cnt, scnname);
    3876             : #endif
    3877             :                   }
    3878             : 
    3879       25602 :                 break;
    3880             :               }
    3881             : 
    3882             :           /* Remember a few special sections for later.  */
    3883      399325 :           if (strcmp (scnname, ".eh_frame_hdr") == 0)
    3884          85 :             eh_frame_hdr_scnndx = cnt;
    3885      399240 :           else if (strcmp (scnname, ".eh_frame") == 0)
    3886         149 :             eh_frame_scnndx = cnt;
    3887      399091 :           else if (strcmp (scnname, ".gcc_except_table") == 0)
    3888          10 :             gcc_except_table_scnndx = cnt;
    3889             :         }
    3890             : 
    3891      399325 :       if (shdr->sh_entsize != 0 && shdr->sh_size % shdr->sh_entsize)
    3892           0 :         ERROR (gettext ("\
    3893             : section [%2zu] '%s': size not multiple of entry size\n"),
    3894             :                cnt, section_name (ebl, cnt));
    3895             : 
    3896      399325 :       if (elf_strptr (ebl->elf, shstrndx, shdr->sh_name) == NULL)
    3897           0 :         ERROR (gettext ("cannot get section header\n"));
    3898             : 
    3899      798650 :       if (shdr->sh_type >= SHT_NUM
    3900      399325 :           && shdr->sh_type != SHT_GNU_ATTRIBUTES
    3901         250 :           && shdr->sh_type != SHT_GNU_LIBLIST
    3902         250 :           && shdr->sh_type != SHT_CHECKSUM
    3903         250 :           && shdr->sh_type != SHT_GNU_verdef
    3904         240 :           && shdr->sh_type != SHT_GNU_verneed
    3905         149 :           && shdr->sh_type != SHT_GNU_versym
    3906          57 :           && ebl_section_type_name (ebl, shdr->sh_type, NULL, 0) == NULL)
    3907           0 :         ERROR (gettext ("section [%2zu] '%s' has unsupported type %d\n"),
    3908             :                cnt, section_name (ebl, cnt),
    3909             :                (int) shdr->sh_type);
    3910             : 
    3911             : #define ALL_SH_FLAGS (SHF_WRITE | SHF_ALLOC | SHF_EXECINSTR | SHF_MERGE \
    3912             :                       | SHF_STRINGS | SHF_INFO_LINK | SHF_LINK_ORDER \
    3913             :                       | SHF_OS_NONCONFORMING | SHF_GROUP | SHF_TLS \
    3914             :                       | SHF_COMPRESSED)
    3915      399325 :       if (shdr->sh_flags & ~(GElf_Xword) ALL_SH_FLAGS)
    3916             :         {
    3917           4 :           GElf_Xword sh_flags = shdr->sh_flags & ~(GElf_Xword) ALL_SH_FLAGS;
    3918           4 :           if (sh_flags & SHF_MASKPROC)
    3919             :             {
    3920           4 :               if (!ebl_machine_section_flag_check (ebl,
    3921             :                                                    sh_flags & SHF_MASKPROC))
    3922           0 :                 ERROR (gettext ("section [%2zu] '%s'"
    3923             :                                 " contains invalid processor-specific flag(s)"
    3924             :                                 " %#" PRIx64 "\n"),
    3925             :                        cnt, section_name (ebl, cnt), sh_flags & SHF_MASKPROC);
    3926           4 :               sh_flags &= ~(GElf_Xword) SHF_MASKPROC;
    3927             :             }
    3928           4 :           if (sh_flags != 0)
    3929           0 :             ERROR (gettext ("section [%2zu] '%s' contains unknown flag(s)"
    3930             :                             " %#" PRIx64 "\n"),
    3931             :                    cnt, section_name (ebl, cnt), sh_flags);
    3932             :         }
    3933      399325 :       if (shdr->sh_flags & SHF_TLS)
    3934             :         {
    3935             :           // XXX Correct?
    3936          42 :           if (shdr->sh_addr != 0 && !gnuld)
    3937           0 :             ERROR (gettext ("\
    3938             : section [%2zu] '%s': thread-local data sections address not zero\n"),
    3939             :                    cnt, section_name (ebl, cnt));
    3940             : 
    3941             :           // XXX TODO more tests!?
    3942             :         }
    3943             : 
    3944      399325 :       if (shdr->sh_flags & SHF_COMPRESSED)
    3945             :         {
    3946           0 :           if (shdr->sh_flags & SHF_ALLOC)
    3947           0 :             ERROR (gettext ("\
    3948             : section [%2zu] '%s': allocated section cannot be compressed\n"),
    3949             :                    cnt, section_name (ebl, cnt));
    3950             : 
    3951           0 :           if (shdr->sh_type == SHT_NOBITS)
    3952           0 :             ERROR (gettext ("\
    3953             : section [%2zu] '%s': nobits section cannot be compressed\n"),
    3954             :                    cnt, section_name (ebl, cnt));
    3955             : 
    3956           0 :           GElf_Chdr chdr;
    3957           0 :           if (gelf_getchdr (scn, &chdr) == NULL)
    3958           0 :             ERROR (gettext ("\
    3959             : section [%2zu] '%s': compressed section with no compression header: %s\n"),
    3960             :                    cnt, section_name (ebl, cnt), elf_errmsg (-1));
    3961             :         }
    3962             : 
    3963      399325 :       if (shdr->sh_link >= shnum)
    3964           0 :         ERROR (gettext ("\
    3965             : section [%2zu] '%s': invalid section reference in link value\n"),
    3966             :                cnt, section_name (ebl, cnt));
    3967             : 
    3968      399325 :       if (SH_INFO_LINK_P (shdr) && shdr->sh_info >= shnum)
    3969           0 :         ERROR (gettext ("\
    3970             : section [%2zu] '%s': invalid section reference in info value\n"),
    3971             :                cnt, section_name (ebl, cnt));
    3972             : 
    3973      798650 :       if ((shdr->sh_flags & SHF_MERGE) == 0
    3974      399325 :           && (shdr->sh_flags & SHF_STRINGS) != 0
    3975           0 :           && be_strict)
    3976           0 :         ERROR (gettext ("\
    3977             : section [%2zu] '%s': strings flag set without merge flag\n"),
    3978             :                cnt, section_name (ebl, cnt));
    3979             : 
    3980      399325 :       if ((shdr->sh_flags & SHF_MERGE) != 0 && shdr->sh_entsize == 0)
    3981           0 :         ERROR (gettext ("\
    3982             : section [%2zu] '%s': merge flag set but entry size is zero\n"),
    3983             :                cnt, section_name (ebl, cnt));
    3984             : 
    3985      399325 :       if (shdr->sh_flags & SHF_GROUP)
    3986       44008 :         check_scn_group (ebl, cnt);
    3987             : 
    3988      399325 :       if (shdr->sh_flags & SHF_EXECINSTR)
    3989             :         {
    3990         561 :           switch (shdr->sh_type)
    3991             :             {
    3992             :             case SHT_PROGBITS:
    3993             :               break;
    3994             : 
    3995          72 :             case SHT_NOBITS:
    3996          72 :               if (is_debuginfo)
    3997             :                 break;
    3998           0 :               FALLTHROUGH;
    3999             :             default:
    4000           0 :               ERROR (gettext ("\
    4001             : section [%2zu] '%s' has unexpected type %d for an executable section\n"),
    4002             :                      cnt, section_name (ebl, cnt), shdr->sh_type);
    4003           0 :               break;
    4004             :             }
    4005             : 
    4006         561 :           if (shdr->sh_flags & SHF_WRITE)
    4007             :             {
    4008           2 :               if (is_debuginfo && shdr->sh_type != SHT_NOBITS)
    4009           0 :                 ERROR (gettext ("\
    4010             : section [%2zu] '%s' must be of type NOBITS in debuginfo files\n"),
    4011             :                        cnt, section_name (ebl, cnt));
    4012             : 
    4013           2 :               if (!is_debuginfo
    4014           2 :                   && !ebl_check_special_section (ebl, cnt, shdr,
    4015             :                                                  section_name (ebl, cnt)))
    4016           0 :                 ERROR (gettext ("\
    4017             : section [%2zu] '%s' is both executable and writable\n"),
    4018             :                        cnt, section_name (ebl, cnt));
    4019             :             }
    4020             :         }
    4021             : 
    4022      399325 :       if (ehdr->e_type != ET_REL && (shdr->sh_flags & SHF_ALLOC) != 0
    4023        2651 :           && !is_debuginfo)
    4024             :         {
    4025             :           /* Make sure the section is contained in a loaded segment
    4026             :              and that the initialization part matches NOBITS sections.  */
    4027             :           unsigned int pcnt;
    4028             :           GElf_Phdr phdr_mem;
    4029             :           GElf_Phdr *phdr;
    4030             : 
    4031        7386 :           for (pcnt = 0; pcnt < phnum; ++pcnt)
    4032        7386 :             if ((phdr = gelf_getphdr (ebl->elf, pcnt, &phdr_mem)) != NULL
    4033        7386 :                 && ((phdr->p_type == PT_LOAD
    4034        3909 :                      && (shdr->sh_flags & SHF_TLS) == 0)
    4035        3639 :                     || (phdr->p_type == PT_TLS
    4036          41 :                         && (shdr->sh_flags & SHF_TLS) != 0))
    4037        3788 :                 && phdr->p_offset <= shdr->sh_offset
    4038        3788 :                 && ((shdr->sh_offset - phdr->p_offset <= phdr->p_filesz
    4039        2321 :                      && (shdr->sh_offset - phdr->p_offset < phdr->p_filesz
    4040         171 :                          || shdr->sh_size == 0))
    4041        1614 :                     || (shdr->sh_offset - phdr->p_offset < phdr->p_memsz
    4042         128 :                         && shdr->sh_type == SHT_NOBITS)))
    4043             :               {
    4044             :                 /* Found the segment.  */
    4045        4604 :                 if (phdr->p_offset + phdr->p_memsz
    4046        2302 :                     < shdr->sh_offset + shdr->sh_size)
    4047           0 :                   ERROR (gettext ("\
    4048             : section [%2zu] '%s' not fully contained in segment of program header entry %d\n"),
    4049             :                          cnt, section_name (ebl, cnt), pcnt);
    4050             : 
    4051        2302 :                 if (shdr->sh_type == SHT_NOBITS)
    4052             :                   {
    4053         128 :                     if (shdr->sh_offset < phdr->p_offset + phdr->p_filesz
    4054           0 :                         && !is_debuginfo)
    4055             :                       {
    4056           0 :                         if (!gnuld)
    4057           0 :                           ERROR (gettext ("\
    4058             : section [%2zu] '%s' has type NOBITS but is read from the file in segment of program header entry %d\n"),
    4059             :                                  cnt, section_name (ebl, cnt), pcnt);
    4060             :                         else
    4061             :                           {
    4062             :                             /* This is truly horrible. GNU ld might put a
    4063             :                                NOBITS section in the middle of a PT_LOAD
    4064             :                                segment, assuming the next gap in the file
    4065             :                                actually consists of zero bits...
    4066             :                                So it really is like a PROGBITS section
    4067             :                                where the data is all zeros.  Check those
    4068             :                                zero bytes are really there.  */
    4069           0 :                             bool bad;
    4070           0 :                             Elf_Data *databits;
    4071           0 :                             databits = elf_getdata_rawchunk (ebl->elf,
    4072             :                                                              shdr->sh_offset,
    4073             :                                                              shdr->sh_size,
    4074             :                                                              ELF_T_BYTE);
    4075           0 :                             bad = (databits == NULL
    4076           0 :                                    || databits->d_size != shdr->sh_size);
    4077           0 :                             for (size_t idx = 0;
    4078           0 :                                  idx < databits->d_size && ! bad;
    4079           0 :                                  idx++)
    4080           0 :                               bad = ((char *) databits->d_buf)[idx] != 0;
    4081             : 
    4082           0 :                             if (bad)
    4083           0 :                               ERROR (gettext ("\
    4084             : section [%2zu] '%s' has type NOBITS but is read from the file in segment of program header entry %d and file contents is non-zero\n"),
    4085             :                                      cnt, section_name (ebl, cnt), pcnt);
    4086             :                           }
    4087             :                       }
    4088             :                   }
    4089             :                 else
    4090             :                   {
    4091        2174 :                     const GElf_Off end = phdr->p_offset + phdr->p_filesz;
    4092        2174 :                     if (shdr->sh_offset > end ||
    4093          24 :                         (shdr->sh_offset == end && shdr->sh_size != 0))
    4094           0 :                       ERROR (gettext ("\
    4095             : section [%2zu] '%s' has not type NOBITS but is not read from the file in segment of program header entry %d\n"),
    4096             :                          cnt, section_name (ebl, cnt), pcnt);
    4097             :                   }
    4098             : 
    4099        2302 :                 if (shdr->sh_type != SHT_NOBITS)
    4100             :                   {
    4101        2174 :                     if ((shdr->sh_flags & SHF_EXECINSTR) != 0)
    4102             :                       {
    4103         428 :                         segment_flags[pcnt] |= PF_X;
    4104         428 :                         if ((phdr->p_flags & PF_X) == 0)
    4105           0 :                           ERROR (gettext ("\
    4106             : section [%2zu] '%s' is executable in nonexecutable segment %d\n"),
    4107             :                                  cnt, section_name (ebl, cnt), pcnt);
    4108             :                       }
    4109             : 
    4110        2174 :                     if ((shdr->sh_flags & SHF_WRITE) != 0)
    4111             :                       {
    4112         645 :                         segment_flags[pcnt] |= PF_W;
    4113         645 :                         if (0   /* XXX vdso images have this */
    4114             :                             && (phdr->p_flags & PF_W) == 0)
    4115             :                           ERROR (gettext ("\
    4116             : section [%2zu] '%s' is writable in unwritable segment %d\n"),
    4117             :                                  cnt, section_name (ebl, cnt), pcnt);
    4118             :                       }
    4119             :                   }
    4120             : 
    4121             :                 break;
    4122             :               }
    4123             : 
    4124        2302 :           if (pcnt == phnum)
    4125           0 :             ERROR (gettext ("\
    4126             : section [%2zu] '%s': alloc flag set but section not in any loaded segment\n"),
    4127             :                    cnt, section_name (ebl, cnt));
    4128             :         }
    4129             : 
    4130      399325 :       if (cnt == shstrndx && shdr->sh_type != SHT_STRTAB)
    4131           0 :         ERROR (gettext ("\
    4132             : section [%2zu] '%s': ELF header says this is the section header string table but type is not SHT_TYPE\n"),
    4133             :                cnt, section_name (ebl, cnt));
    4134             : 
    4135      399325 :       switch (shdr->sh_type)
    4136             :         {
    4137          92 :         case SHT_DYNSYM:
    4138          92 :           if (ehdr->e_type == ET_REL)
    4139           0 :             ERROR (gettext ("\
    4140             : section [%2zu] '%s': relocatable files cannot have dynamic symbol tables\n"),
    4141             :                    cnt, section_name (ebl, cnt));
    4142         254 :           FALLTHROUGH;
    4143             :         case SHT_SYMTAB:
    4144         254 :           check_symtab (ebl, ehdr, shdr, cnt);
    4145         254 :           break;
    4146             : 
    4147         360 :         case SHT_RELA:
    4148         360 :           check_rela (ebl, ehdr, shdr, cnt);
    4149         360 :           break;
    4150             : 
    4151          53 :         case SHT_REL:
    4152          53 :           check_rel (ebl, ehdr, shdr, cnt);
    4153          53 :           break;
    4154             : 
    4155          92 :         case SHT_DYNAMIC:
    4156          92 :           check_dynamic (ebl, ehdr, shdr, cnt);
    4157          92 :           break;
    4158             : 
    4159           2 :         case SHT_SYMTAB_SHNDX:
    4160           2 :           check_symtab_shndx (ebl, ehdr, shdr, cnt);
    4161           2 :           break;
    4162             : 
    4163          40 :         case SHT_HASH:
    4164          40 :           check_hash (shdr->sh_type, ebl, ehdr, shdr, cnt);
    4165          40 :           hash_idx = cnt;
    4166          40 :           break;
    4167             : 
    4168          56 :         case SHT_GNU_HASH:
    4169          56 :           check_hash (shdr->sh_type, ebl, ehdr, shdr, cnt);
    4170          56 :           gnu_hash_idx = cnt;
    4171          56 :           break;
    4172             : 
    4173           0 :         case SHT_NULL:
    4174           0 :           check_null (ebl, shdr, cnt);
    4175           0 :           break;
    4176             : 
    4177       22008 :         case SHT_GROUP:
    4178       22008 :           check_group (ebl, ehdr, shdr, cnt);
    4179       22008 :           break;
    4180             : 
    4181         169 :         case SHT_NOTE:
    4182         169 :           check_note_section (ebl, ehdr, shdr, cnt);
    4183         169 :           break;
    4184             : 
    4185          92 :         case SHT_GNU_versym:
    4186             :           /* We cannot process this section now since we have no guarantee
    4187             :              that the verneed and verdef sections have already been read.
    4188             :              Just remember the section index.  */
    4189          92 :           if (versym_scnndx != 0)
    4190           0 :             ERROR (gettext ("more than one version symbol table present\n"));
    4191             :           versym_scnndx = cnt;
    4192             :           break;
    4193             : 
    4194          91 :         case SHT_GNU_verneed:
    4195          91 :           check_verneed (ebl, shdr, cnt);
    4196          91 :           break;
    4197             : 
    4198          10 :         case SHT_GNU_verdef:
    4199          10 :           check_verdef (ebl, shdr, cnt);
    4200          10 :           break;
    4201             : 
    4202           1 :         case SHT_GNU_ATTRIBUTES:
    4203           1 :           check_attributes (ebl, ehdr, shdr, cnt);
    4204           1 :           break;
    4205             : 
    4206             :         default:
    4207             :           /* Nothing.  */
    4208             :           break;
    4209             :         }
    4210             :     }
    4211             : 
    4212         193 :   if (has_interp_segment && !dot_interp_section)
    4213           0 :     ERROR (gettext ("INTERP program header entry but no .interp section\n"));
    4214             : 
    4215         193 :   if (!is_debuginfo)
    4216         990 :     for (unsigned int pcnt = 0; pcnt < phnum; ++pcnt)
    4217             :       {
    4218         819 :         GElf_Phdr phdr_mem;
    4219         819 :         GElf_Phdr *phdr = gelf_getphdr (ebl->elf, pcnt, &phdr_mem);
    4220         819 :         if (phdr != NULL && (phdr->p_type == PT_LOAD || phdr->p_type == PT_TLS))
    4221             :           {
    4222         317 :             if ((phdr->p_flags & PF_X) != 0
    4223         142 :                 && (segment_flags[pcnt] & PF_X) == 0)
    4224           0 :               ERROR (gettext ("\
    4225             : loadable segment [%u] is executable but contains no executable sections\n"),
    4226             :                      pcnt);
    4227             : 
    4228         317 :             if ((phdr->p_flags & PF_W) != 0
    4229          91 :                 && (segment_flags[pcnt] & PF_W) == 0)
    4230           0 :               ERROR (gettext ("\
    4231             : loadable segment [%u] is writable but contains no writable sections\n"),
    4232             :                      pcnt);
    4233             :           }
    4234             :       }
    4235             : 
    4236         193 :   free (segment_flags);
    4237             : 
    4238         193 :   if (version_namelist != NULL)
    4239             :     {
    4240          92 :       if (versym_scnndx == 0)
    4241           0 :     ERROR (gettext ("\
    4242             : no .gnu.versym section present but .gnu.versym_d or .gnu.versym_r section exist\n"));
    4243             :       else
    4244          92 :         check_versym (ebl, versym_scnndx);
    4245             : 
    4246             :       /* Check for duplicate index numbers.  */
    4247         403 :       do
    4248             :         {
    4249         403 :           struct version_namelist *runp = version_namelist->next;
    4250        1993 :           while (runp != NULL)
    4251             :             {
    4252        1590 :               if (version_namelist->ndx == runp->ndx)
    4253             :                 {
    4254           0 :                   ERROR (gettext ("duplicate version index %d\n"),
    4255             :                          (int) version_namelist->ndx);
    4256           0 :                   break;
    4257             :                 }
    4258        1590 :               runp = runp->next;
    4259             :             }
    4260             : 
    4261         403 :           struct version_namelist *old = version_namelist;
    4262         403 :           version_namelist = version_namelist->next;
    4263         403 :           free (old);
    4264             :         }
    4265         403 :       while (version_namelist != NULL);
    4266             :     }
    4267         101 :   else if (versym_scnndx != 0)
    4268           0 :     ERROR (gettext ("\
    4269             : .gnu.versym section present without .gnu.versym_d or .gnu.versym_r\n"));
    4270             : 
    4271         193 :   if (hash_idx != 0 && gnu_hash_idx != 0)
    4272           4 :     compare_hash_gnu_hash (ebl, ehdr, hash_idx, gnu_hash_idx);
    4273             : 
    4274         193 :   free (scnref);
    4275             : }
    4276             : 
    4277             : 
    4278             : static GElf_Off
    4279           0 : check_note_data (Ebl *ebl, const GElf_Ehdr *ehdr,
    4280             :                  Elf_Data *data, int shndx, int phndx, GElf_Off start)
    4281             : {
    4282           0 :   size_t offset = 0;
    4283           0 :   size_t last_offset = 0;
    4284           0 :   GElf_Nhdr nhdr;
    4285           0 :   size_t name_offset;
    4286           0 :   size_t desc_offset;
    4287           0 :   while (offset < data->d_size
    4288           0 :          && (offset = gelf_getnote (data, offset,
    4289             :                                     &nhdr, &name_offset, &desc_offset)) > 0)
    4290             :     {
    4291           0 :       last_offset = offset;
    4292             : 
    4293             :       /* Make sure it is one of the note types we know about.  */
    4294           0 :       if (ehdr->e_type == ET_CORE)
    4295           0 :         switch (nhdr.n_type)
    4296             :           {
    4297             :           case NT_PRSTATUS:
    4298             :           case NT_FPREGSET:
    4299             :           case NT_PRPSINFO:
    4300             :           case NT_TASKSTRUCT:           /* NT_PRXREG on Solaris.  */
    4301             :           case NT_PLATFORM:
    4302             :           case NT_AUXV:
    4303             :           case NT_GWINDOWS:
    4304             :           case NT_ASRS:
    4305             :           case NT_PSTATUS:
    4306             :           case NT_PSINFO:
    4307             :           case NT_PRCRED:
    4308             :           case NT_UTSNAME:
    4309             :           case NT_LWPSTATUS:
    4310             :           case NT_LWPSINFO:
    4311             :           case NT_PRFPXREG:
    4312             :             /* Known type.  */
    4313             :             break;
    4314             : 
    4315           0 :           default:
    4316           0 :             if (shndx == 0)
    4317           0 :               ERROR (gettext ("\
    4318             : phdr[%d]: unknown core file note type %" PRIu32 " at offset %" PRIu64 "\n"),
    4319             :                      phndx, (uint32_t) nhdr.n_type, start + offset);
    4320             :             else
    4321           0 :               ERROR (gettext ("\
    4322             : section [%2d] '%s': unknown core file note type %" PRIu32
    4323             :                               " at offset %zu\n"),
    4324             :                      shndx, section_name (ebl, shndx),
    4325             :                      (uint32_t) nhdr.n_type, offset);
    4326             :           }
    4327             :       else
    4328           0 :         switch (nhdr.n_type)
    4329             :           {
    4330           0 :           case NT_GNU_ABI_TAG:
    4331             :           case NT_GNU_HWCAP:
    4332             :           case NT_GNU_BUILD_ID:
    4333             :           case NT_GNU_GOLD_VERSION:
    4334             :           case NT_GNU_PROPERTY_TYPE_0:
    4335           0 :             if (nhdr.n_namesz == sizeof ELF_NOTE_GNU
    4336           0 :                 && strcmp (data->d_buf + name_offset, ELF_NOTE_GNU) == 0)
    4337             :               break;
    4338             :             else
    4339             :               {
    4340             :                 /* NT_VERSION is 1, same as NT_GNU_ABI_TAG.  It has no
    4341             :                    descriptor and (ab)uses the name as version string.  */
    4342           0 :                 if (nhdr.n_descsz == 0 && nhdr.n_type == NT_VERSION)
    4343             :                   break;
    4344             :               }
    4345           0 :               goto unknown_note;
    4346             : 
    4347           0 :           case NT_GNU_BUILD_ATTRIBUTE_OPEN:
    4348             :           case NT_GNU_BUILD_ATTRIBUTE_FUNC:
    4349             :             /* GNU Build Attributes store most data in the owner
    4350             :                name, which must start with the
    4351             :                ELF_NOTE_GNU_BUILD_ATTRIBUTE_PREFIX "GA".  */
    4352           0 :             if (nhdr.n_namesz >= sizeof ELF_NOTE_GNU_BUILD_ATTRIBUTE_PREFIX
    4353           0 :                 && strncmp (data->d_buf + name_offset,
    4354             :                             ELF_NOTE_GNU_BUILD_ATTRIBUTE_PREFIX,
    4355             :                             strlen (ELF_NOTE_GNU_BUILD_ATTRIBUTE_PREFIX)) == 0)
    4356             :               break;
    4357             :             else
    4358           0 :               goto unknown_note;
    4359             : 
    4360             :           case 0:
    4361             :             /* Linux vDSOs use a type 0 note for the kernel version word.  */
    4362           0 :             if (nhdr.n_namesz == sizeof "Linux"
    4363           0 :                 && !memcmp (data->d_buf + name_offset, "Linux", sizeof "Linux"))
    4364             :               break;
    4365           0 :             FALLTHROUGH;
    4366             :           default:
    4367             :             {
    4368           0 :             unknown_note:
    4369           0 :             if (shndx == 0)
    4370           0 :               ERROR (gettext ("\
    4371             : phdr[%d]: unknown object file note type %" PRIu32 " with owner name '%s' at offset %zu\n"),
    4372             :                      phndx, (uint32_t) nhdr.n_type,
    4373             :                      (char *) data->d_buf + name_offset, offset);
    4374             :             else
    4375           0 :               ERROR (gettext ("\
    4376             : section [%2d] '%s': unknown object file note type %" PRIu32
    4377             :                               " with owner name '%s' at offset %zu\n"),
    4378             :                      shndx, section_name (ebl, shndx),
    4379             :                      (uint32_t) nhdr.n_type,
    4380             :                      (char *) data->d_buf + name_offset, offset);
    4381             :             }
    4382             :           }
    4383             :     }
    4384             : 
    4385           0 :   return last_offset;
    4386             : }
    4387             : 
    4388             : 
    4389             : static void
    4390          98 : check_note (Ebl *ebl, GElf_Ehdr *ehdr, GElf_Phdr *phdr, int cnt)
    4391             : {
    4392          98 :   if (ehdr->e_type != ET_CORE && ehdr->e_type != ET_REL
    4393          98 :       && ehdr->e_type != ET_EXEC && ehdr->e_type != ET_DYN)
    4394           0 :     ERROR (gettext ("\
    4395             : phdr[%d]: no note entries defined for the type of file\n"),
    4396             :            cnt);
    4397             : 
    4398          98 :   if (is_debuginfo)
    4399             :     /* The p_offset values in a separate debug file are bogus.  */
    4400             :     return;
    4401             : 
    4402          82 :   if (phdr->p_filesz == 0)
    4403             :     return;
    4404             : 
    4405          82 :   GElf_Off notes_size = 0;
    4406         328 :   Elf_Data *data = elf_getdata_rawchunk (ebl->elf,
    4407          82 :                                          phdr->p_offset, phdr->p_filesz,
    4408          82 :                                          (phdr->p_align == 8
    4409             :                                           ? ELF_T_NHDR8 : ELF_T_NHDR));
    4410          82 :   if (data != NULL && data->d_buf != NULL)
    4411          82 :     notes_size = check_note_data (ebl, ehdr, data, 0, cnt, phdr->p_offset);
    4412             : 
    4413          82 :   if (notes_size == 0)
    4414           0 :     ERROR (gettext ("phdr[%d]: cannot get content of note section: %s\n"),
    4415             :            cnt, elf_errmsg (-1));
    4416          82 :   else if (notes_size != phdr->p_filesz)
    4417           0 :     ERROR (gettext ("phdr[%d]: extra %" PRIu64 " bytes after last note\n"),
    4418             :            cnt, phdr->p_filesz - notes_size);
    4419             : }
    4420             : 
    4421             : 
    4422             : static void
    4423           0 : check_note_section (Ebl *ebl, GElf_Ehdr *ehdr, GElf_Shdr *shdr, int idx)
    4424             : {
    4425           0 :   if (shdr->sh_size == 0)
    4426           0 :     return;
    4427             : 
    4428           0 :   Elf_Data *data = elf_getdata (elf_getscn (ebl->elf, idx), NULL);
    4429           0 :   if (data == NULL || data->d_buf == NULL)
    4430             :     {
    4431           0 :       ERROR (gettext ("section [%2d] '%s': cannot get section data\n"),
    4432             :              idx, section_name (ebl, idx));
    4433           0 :       return;
    4434             :     }
    4435             : 
    4436           0 :   if (ehdr->e_type != ET_CORE && ehdr->e_type != ET_REL
    4437           0 :       && ehdr->e_type != ET_EXEC && ehdr->e_type != ET_DYN)
    4438           0 :     ERROR (gettext ("\
    4439             : section [%2d] '%s': no note entries defined for the type of file\n"),
    4440             :              idx, section_name (ebl, idx));
    4441             : 
    4442           0 :   GElf_Off notes_size = check_note_data (ebl, ehdr, data, idx, 0, 0);
    4443             : 
    4444           0 :   if (notes_size == 0)
    4445           0 :     ERROR (gettext ("section [%2d] '%s': cannot get content of note section\n"),
    4446             :            idx, section_name (ebl, idx));
    4447           0 :   else if (notes_size != shdr->sh_size)
    4448           0 :     ERROR (gettext ("section [%2d] '%s': extra %" PRIu64
    4449             :                     " bytes after last note\n"),
    4450             :            idx, section_name (ebl, idx), shdr->sh_size - notes_size);
    4451             : }
    4452             : 
    4453             : 
    4454             : /* Index of the PT_GNU_EH_FRAME program eader entry.  */
    4455             : static int pt_gnu_eh_frame_pndx;
    4456             : 
    4457             : 
    4458             : static void
    4459         193 : check_program_header (Ebl *ebl, GElf_Ehdr *ehdr)
    4460             : {
    4461         193 :   if (ehdr->e_phoff == 0)
    4462             :     return;
    4463             : 
    4464         316 :   if (ehdr->e_type != ET_EXEC && ehdr->e_type != ET_DYN
    4465         158 :       && ehdr->e_type != ET_CORE)
    4466           0 :     ERROR (gettext ("\
    4467             : only executables, shared objects, and core files can have program headers\n"));
    4468             : 
    4469             :   int num_pt_interp = 0;
    4470             :   int num_pt_tls = 0;
    4471             :   int num_pt_relro = 0;
    4472             : 
    4473        1083 :   for (unsigned int cnt = 0; cnt < phnum; ++cnt)
    4474             :     {
    4475         925 :       GElf_Phdr phdr_mem;
    4476         925 :       GElf_Phdr *phdr;
    4477             : 
    4478         925 :       phdr = gelf_getphdr (ebl->elf, cnt, &phdr_mem);
    4479         925 :       if (phdr == NULL)
    4480             :         {
    4481           0 :           ERROR (gettext ("cannot get program header entry %d: %s\n"),
    4482             :                  cnt, elf_errmsg (-1));
    4483           0 :           continue;
    4484             :         }
    4485             : 
    4486         925 :       if (phdr->p_type >= PT_NUM && phdr->p_type != PT_GNU_EH_FRAME
    4487         127 :           && phdr->p_type != PT_GNU_STACK && phdr->p_type != PT_GNU_RELRO
    4488             :           /* Check for a known machine-specific type.  */
    4489           1 :           && ebl_segment_type_name (ebl, phdr->p_type, NULL, 0) == NULL)
    4490           0 :         ERROR (gettext ("\
    4491             : program header entry %d: unknown program header entry type %#" PRIx64 "\n"),
    4492             :                cnt, (uint64_t) phdr->p_type);
    4493             : 
    4494         925 :       if (phdr->p_type == PT_LOAD)
    4495         322 :         has_loadable_segment = true;
    4496         603 :       else if (phdr->p_type == PT_INTERP)
    4497             :         {
    4498          77 :           if (++num_pt_interp != 1)
    4499             :             {
    4500           0 :               if (num_pt_interp == 2)
    4501           0 :                 ERROR (gettext ("\
    4502             : more than one INTERP entry in program header\n"));
    4503             :             }
    4504          77 :           has_interp_segment = true;
    4505             :         }
    4506         526 :       else if (phdr->p_type == PT_TLS)
    4507             :         {
    4508          30 :           if (++num_pt_tls == 2)
    4509           0 :             ERROR (gettext ("more than one TLS entry in program header\n"));
    4510             :         }
    4511         496 :       else if (phdr->p_type == PT_NOTE)
    4512          98 :         check_note (ebl, ehdr, phdr, cnt);
    4513         398 :       else if (phdr->p_type == PT_DYNAMIC)
    4514             :         {
    4515         108 :           if (ehdr->e_type == ET_EXEC && ! has_interp_segment)
    4516           0 :             ERROR (gettext ("\
    4517             : static executable cannot have dynamic sections\n"));
    4518             :           else
    4519             :             {
    4520             :               /* Check that the .dynamic section, if it exists, has
    4521             :                  the same address.  */
    4522             :               Elf_Scn *scn = NULL;
    4523      133481 :               while ((scn = elf_nextscn (ebl->elf, scn)) != NULL)
    4524             :                 {
    4525      133465 :                   GElf_Shdr shdr_mem;
    4526      133465 :                   GElf_Shdr *shdr = gelf_getshdr (scn, &shdr_mem);
    4527      133465 :                   if (shdr != NULL && shdr->sh_type == SHT_DYNAMIC)
    4528             :                     {
    4529          92 :                       if (phdr->p_offset != shdr->sh_offset)
    4530           0 :                         ERROR (gettext ("\
    4531             : dynamic section reference in program header has wrong offset\n"));
    4532          92 :                       if (phdr->p_memsz != shdr->sh_size)
    4533           0 :                         ERROR (gettext ("\
    4534             : dynamic section size mismatch in program and section header\n"));
    4535          92 :                       break;
    4536             :                     }
    4537             :                 }
    4538             :             }
    4539             :         }
    4540         290 :       else if (phdr->p_type == PT_GNU_RELRO)
    4541             :         {
    4542          45 :           if (++num_pt_relro == 2)
    4543           0 :             ERROR (gettext ("\
    4544             : more than one GNU_RELRO entry in program header\n"));
    4545             :           else
    4546             :             {
    4547             :               /* Check that the region is in a writable segment.  */
    4548             :               unsigned int inner;
    4549         222 :               for (inner = 0; inner < phnum; ++inner)
    4550             :                 {
    4551         222 :                   GElf_Phdr phdr2_mem;
    4552         222 :                   GElf_Phdr *phdr2;
    4553             : 
    4554         222 :                   phdr2 = gelf_getphdr (ebl->elf, inner, &phdr2_mem);
    4555         222 :                   if (phdr2 == NULL)
    4556           0 :                     continue;
    4557             : 
    4558         222 :                   if (phdr2->p_type == PT_LOAD
    4559         148 :                       && phdr->p_vaddr >= phdr2->p_vaddr
    4560         296 :                       && (phdr->p_vaddr + phdr->p_memsz
    4561         148 :                           <= phdr2->p_vaddr + phdr2->p_memsz))
    4562             :                     {
    4563          45 :                       if ((phdr2->p_flags & PF_W) == 0)
    4564           0 :                         ERROR (gettext ("\
    4565             : loadable segment GNU_RELRO applies to is not writable\n"));
    4566             :                       /* Unless fully covered, relro flags could be a
    4567             :                          subset of the phdrs2 flags.  For example the load
    4568             :                          segment could also have PF_X set.  */
    4569          45 :                       if (phdr->p_vaddr == phdr2->p_vaddr
    4570          90 :                           && (phdr->p_vaddr + phdr->p_memsz
    4571          45 :                               == phdr2->p_vaddr + phdr2->p_memsz))
    4572             :                         {
    4573           0 :                           if ((phdr2->p_flags & ~PF_W)
    4574           0 :                               != (phdr->p_flags & ~PF_W))
    4575           0 :                             ERROR (gettext ("\
    4576             : loadable segment [%u] flags do not match GNU_RELRO [%u] flags\n"),
    4577             :                                    cnt, inner);
    4578             :                         }
    4579             :                       else
    4580             :                         {
    4581          45 :                           if ((phdr->p_flags & ~phdr2->p_flags) != 0)
    4582           0 :                             ERROR (gettext ("\
    4583             : GNU_RELRO [%u] flags are not a subset of the loadable segment [%u] flags\n"),
    4584             :                                    inner, cnt);
    4585             :                         }
    4586          45 :                       break;
    4587             :                     }
    4588             :                 }
    4589             : 
    4590          45 :               if (inner >= phnum)
    4591           0 :                 ERROR (gettext ("\
    4592             : %s segment not contained in a loaded segment\n"), "GNU_RELRO");
    4593             :             }
    4594             :         }
    4595         245 :       else if (phdr->p_type == PT_PHDR)
    4596             :         {
    4597             :           /* Check that the region is in a writable segment.  */
    4598             :           unsigned int inner;
    4599         233 :           for (inner = 0; inner < phnum; ++inner)
    4600             :             {
    4601         233 :               GElf_Phdr phdr2_mem;
    4602         233 :               GElf_Phdr *phdr2;
    4603             : 
    4604         233 :               phdr2 = gelf_getphdr (ebl->elf, inner, &phdr2_mem);
    4605         233 :               if (phdr2 != NULL
    4606         233 :                   && phdr2->p_type == PT_LOAD
    4607          78 :                   && phdr->p_vaddr >= phdr2->p_vaddr
    4608         156 :                   && (phdr->p_vaddr + phdr->p_memsz
    4609          78 :                       <= phdr2->p_vaddr + phdr2->p_memsz))
    4610             :                 break;
    4611             :             }
    4612             : 
    4613          78 :           if (inner >= phnum)
    4614           0 :             ERROR (gettext ("\
    4615             : %s segment not contained in a loaded segment\n"), "PHDR");
    4616             : 
    4617             :           /* Check that offset in segment corresponds to offset in ELF
    4618             :              header.  */
    4619          78 :           if (phdr->p_offset != ehdr->e_phoff)
    4620           0 :             ERROR (gettext ("\
    4621             : program header offset in ELF header and PHDR entry do not match"));
    4622             :         }
    4623         167 :       else if (phdr->p_type == PT_GNU_EH_FRAME)
    4624             :         {
    4625             :           /* If there is an .eh_frame_hdr section it must be
    4626             :              referenced by this program header entry.  */
    4627             :           Elf_Scn *scn = NULL;
    4628             :           GElf_Shdr shdr_mem;
    4629             :           GElf_Shdr *shdr = NULL;
    4630             :           bool any = false;
    4631        1280 :           while ((scn = elf_nextscn (ebl->elf, scn)) != NULL)
    4632             :             {
    4633        1280 :               any = true;
    4634        1280 :               shdr = gelf_getshdr (scn, &shdr_mem);
    4635        1280 :               if (shdr != NULL
    4636        1280 :                   && ((is_debuginfo && shdr->sh_type == SHT_NOBITS)
    4637        1153 :                       || (! is_debuginfo
    4638        2284 :                           && (shdr->sh_type == SHT_PROGBITS
    4639        1142 :                               || shdr->sh_type == SHT_X86_64_UNWIND)))
    4640         634 :                   && elf_strptr (ebl->elf, shstrndx, shdr->sh_name) != NULL
    4641         634 :                   && ! strcmp (".eh_frame_hdr",
    4642         634 :                                elf_strptr (ebl->elf, shstrndx, shdr->sh_name)))
    4643             :                 {
    4644          85 :                   if (! is_debuginfo)
    4645             :                     {
    4646          75 :                       if (phdr->p_offset != shdr->sh_offset)
    4647           0 :                         ERROR (gettext ("\
    4648             : call frame search table reference in program header has wrong offset\n"));
    4649          75 :                       if (phdr->p_memsz != shdr->sh_size)
    4650           0 :                         ERROR (gettext ("\
    4651             : call frame search table size mismatch in program and section header\n"));
    4652             :                     }
    4653             :                   break;
    4654             :                 }
    4655             :             }
    4656             : 
    4657          85 :           if (scn == NULL)
    4658             :             {
    4659             :               /* If there is no section header table we don't
    4660             :                  complain.  But if there is one there should be an
    4661             :                  entry for .eh_frame_hdr.  */
    4662           0 :               if (any)
    4663           0 :                 ERROR (gettext ("\
    4664             : PT_GNU_EH_FRAME present but no .eh_frame_hdr section\n"));
    4665             :             }
    4666             :           else
    4667             :             {
    4668             :               /* The section must be allocated and not be writable and
    4669             :                  executable.  */
    4670          85 :               if ((phdr->p_flags & PF_R) == 0)
    4671           0 :                 ERROR (gettext ("\
    4672             : call frame search table must be allocated\n"));
    4673          85 :               else if (shdr != NULL && (shdr->sh_flags & SHF_ALLOC) == 0)
    4674           0 :                 ERROR (gettext ("\
    4675             : section [%2zu] '%s' must be allocated\n"), elf_ndxscn (scn), ".eh_frame_hdr");
    4676             : 
    4677          85 :               if ((phdr->p_flags & PF_W) != 0)
    4678           0 :                 ERROR (gettext ("\
    4679             : call frame search table must not be writable\n"));
    4680          85 :               else if (shdr != NULL && (shdr->sh_flags & SHF_WRITE) != 0)
    4681           0 :                 ERROR (gettext ("\
    4682             : section [%2zu] '%s' must not be writable\n"),
    4683             :                        elf_ndxscn (scn), ".eh_frame_hdr");
    4684             : 
    4685          85 :               if ((phdr->p_flags & PF_X) != 0)
    4686           0 :                 ERROR (gettext ("\
    4687             : call frame search table must not be executable\n"));
    4688          85 :               else if (shdr != NULL && (shdr->sh_flags & SHF_EXECINSTR) != 0)
    4689           0 :                 ERROR (gettext ("\
    4690             : section [%2zu] '%s' must not be executable\n"),
    4691             :                        elf_ndxscn (scn), ".eh_frame_hdr");
    4692             :             }
    4693             : 
    4694             :           /* Remember which entry this is.  */
    4695          85 :           pt_gnu_eh_frame_pndx = cnt;
    4696             :         }
    4697             : 
    4698         925 :       if (phdr->p_filesz > phdr->p_memsz
    4699           0 :           && (phdr->p_memsz != 0 || phdr->p_type != PT_NOTE))
    4700           0 :         ERROR (gettext ("\
    4701             : program header entry %d: file size greater than memory size\n"),
    4702             :                cnt);
    4703             : 
    4704         925 :       if (phdr->p_align > 1)
    4705             :         {
    4706         802 :           if (!powerof2 (phdr->p_align))
    4707           0 :             ERROR (gettext ("\
    4708             : program header entry %d: alignment not a power of 2\n"), cnt);
    4709         802 :           else if ((phdr->p_vaddr - phdr->p_offset) % phdr->p_align != 0)
    4710           0 :             ERROR (gettext ("\
    4711             : program header entry %d: file offset and virtual address not module of alignment\n"), cnt);
    4712             :         }
    4713             :     }
    4714             : }
    4715             : 
    4716             : 
    4717             : static void
    4718           0 : check_exception_data (Ebl *ebl __attribute__ ((unused)),
    4719             :                       GElf_Ehdr *ehdr __attribute__ ((unused)))
    4720             : {
    4721           0 :   if ((ehdr->e_type == ET_EXEC || ehdr->e_type == ET_DYN)
    4722           0 :       && pt_gnu_eh_frame_pndx == 0 && eh_frame_hdr_scnndx != 0)
    4723           0 :     ERROR (gettext ("executable/DSO with .eh_frame_hdr section does not have "
    4724             :                     "a PT_GNU_EH_FRAME program header entry"));
    4725           0 : }
    4726             : 
    4727             : 
    4728             : /* Process one file.  */
    4729             : static void
    4730         193 : process_elf_file (Elf *elf, const char *prefix, const char *suffix,
    4731             :                   const char *fname, size_t size, bool only_one)
    4732             : {
    4733             :   /* Reset variables.  */
    4734         193 :   ndynamic = 0;
    4735         193 :   nverneed = 0;
    4736         193 :   nverdef = 0;
    4737         193 :   textrel = false;
    4738         193 :   needed_textrel = false;
    4739         193 :   has_loadable_segment = false;
    4740         193 :   has_interp_segment = false;
    4741             : 
    4742         193 :   GElf_Ehdr ehdr_mem;
    4743         193 :   GElf_Ehdr *ehdr = gelf_getehdr (elf, &ehdr_mem);
    4744         193 :   Ebl *ebl;
    4745             : 
    4746             :   /* Print the file name.  */
    4747         193 :   if (!only_one)
    4748             :     {
    4749           0 :       if (prefix != NULL)
    4750           0 :         printf ("\n%s(%s)%s:\n", prefix, fname, suffix);
    4751             :       else
    4752           0 :         printf ("\n%s:\n", fname);
    4753             :     }
    4754             : 
    4755         193 :   if (ehdr == NULL)
    4756             :     {
    4757           0 :       ERROR (gettext ("cannot read ELF header: %s\n"), elf_errmsg (-1));
    4758           0 :       return;
    4759             :     }
    4760             : 
    4761         193 :   ebl = ebl_openbackend (elf);
    4762             :   /* If there is no appropriate backend library we cannot test
    4763             :      architecture and OS specific features.  Any encountered extension
    4764             :      is an error.  */
    4765             : 
    4766             :   /* Go straight by the gABI, check all the parts in turn.  */
    4767         193 :   check_elf_header (ebl, ehdr, size);
    4768             : 
    4769             :   /* Check the program header.  */
    4770         193 :   check_program_header (ebl, ehdr);
    4771             : 
    4772             :   /* Next the section headers.  It is OK if there are no section
    4773             :      headers at all.  */
    4774         193 :   check_sections (ebl, ehdr);
    4775             : 
    4776             :   /* Check the exception handling data, if it exists.  */
    4777         193 :   if (pt_gnu_eh_frame_pndx != 0 || eh_frame_hdr_scnndx != 0
    4778         108 :       || eh_frame_scnndx != 0 || gcc_except_table_scnndx != 0)
    4779         149 :     check_exception_data (ebl, ehdr);
    4780             : 
    4781             :   /* Report if no relocation section needed the text relocation flag.  */
    4782         193 :   if (textrel && !needed_textrel)
    4783           0 :     ERROR (gettext ("text relocation flag set but not needed\n"));
    4784             : 
    4785             :   /* Free the resources.  */
    4786         193 :   ebl_closebackend (ebl);
    4787             : }
    4788             : 
    4789             : 
    4790             : #include "debugpred.h"

Generated by: LCOV version 1.13