elflint.c revision 607e05466d3fef5e3ad90aa200d3bba1950cf982
1b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper/* Pedantic checking of ELF files compliance with gABI/psABI spec.
271c1534c9c7a0652fb6c5f9295baa08f32b0b166Jakub Jelinek   Copyright (C) 2001, 2002, 2003, 2004, 2005 Red Hat, Inc.
3de2ed97f33139af5c7a0811e4ec66fc896a13cf2Mark Wielaard   Written by Ulrich Drepper <drepper@redhat.com>, 2001.
4b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper
5b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper   This program is Open Source software; you can redistribute it and/or
6de2ed97f33139af5c7a0811e4ec66fc896a13cf2Mark Wielaard   modify it under the terms of the Open Software License version 1.0 as
7de2ed97f33139af5c7a0811e4ec66fc896a13cf2Mark Wielaard   published by the Open Source Initiative.
8de2ed97f33139af5c7a0811e4ec66fc896a13cf2Mark Wielaard
9de2ed97f33139af5c7a0811e4ec66fc896a13cf2Mark Wielaard   You should have received a copy of the Open Software License along
10b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper   with this program; if not, you may obtain a copy of the Open Software
11de2ed97f33139af5c7a0811e4ec66fc896a13cf2Mark Wielaard   License version 1.0 from http://www.opensource.org/licenses/osl.php or
12361df7da6dfecd817b27e62b91752ac316d7cdd4Ulrich Drepper   by writing the Open Source Initiative c/o Lawrence Rosen, Esq.,
13de2ed97f33139af5c7a0811e4ec66fc896a13cf2Mark Wielaard   3001 King Ranch Road, Ukiah, CA 95482.   */
14de2ed97f33139af5c7a0811e4ec66fc896a13cf2Mark Wielaard
15de2ed97f33139af5c7a0811e4ec66fc896a13cf2Mark Wielaard#ifdef HAVE_CONFIG_H
16de2ed97f33139af5c7a0811e4ec66fc896a13cf2Mark Wielaard# include <config.h>
17de2ed97f33139af5c7a0811e4ec66fc896a13cf2Mark Wielaard#endif
18b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper
19b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper#include <argp.h>
20b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper#include <assert.h>
21b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper#include <byteswap.h>
22b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper#include <endian.h>
23b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper#include <error.h>
24b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper#include <fcntl.h>
25b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper#include <gelf.h>
26b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper#include <inttypes.h>
27b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper#include <libintl.h>
28b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper#include <locale.h>
29b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper#include <stdbool.h>
30b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper#include <stdlib.h>
31b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper#include <string.h>
32b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper#include <unistd.h>
33b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper#include <sys/param.h>
34b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper
35b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper#include <elf-knowledge.h>
36b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper#include <system.h>
37b337b1fd5f3b3410fe522a690ccee70bce8519eeRoland McGrath#include "../libebl/libeblP.h"
38b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper
39b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper
40b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper/* Name and version of program.  */
41b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepperstatic void print_version (FILE *stream, struct argp_state *state);
42059c83e5db89955913a39fe6705acca571c32c3fRoland McGrathvoid (*argp_program_version_hook) (FILE *, struct argp_state *) = print_version;
43059c83e5db89955913a39fe6705acca571c32c3fRoland McGrath
44b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper/* Bug report address.  */
45059c83e5db89955913a39fe6705acca571c32c3fRoland McGrathconst char *argp_program_bug_address = PACKAGE_BUGREPORT;
46059c83e5db89955913a39fe6705acca571c32c3fRoland McGrath
47059c83e5db89955913a39fe6705acca571c32c3fRoland McGrath#define ARGP_strict	300
48b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper#define ARGP_gnuld	301
49b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper
50b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper/* Definitions of arguments for argp functions.  */
51b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepperstatic const struct argp_option options[] =
52fdc93e12a77866cafd1aae4463d89cef2c01d9b1Ulrich Drepper{
53b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper
54b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper  { "strict", ARGP_strict, NULL, 0,
55fdc93e12a77866cafd1aae4463d89cef2c01d9b1Ulrich Drepper    N_("Be extremely strict, flag level 2 features."), 0 },
56b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper  { "quiet", 'q', NULL, 0, N_("Do not print anything if successful"), 0 },
57b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper  { "debuginfo", 'd', NULL, 0, N_("Binary is a separate debuginfo file"), 0 },
58b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper  { "gnu-ld", ARGP_gnuld, NULL, 0,
59b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper    N_("Binary has been created with GNU ld and is therefore known to be \
60b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepperbroken in certain ways"), 0 },
61b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper  { NULL, 0, NULL, 0, NULL, 0 }
62b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper};
63b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper
64b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper/* Short description of program.  */
65b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepperstatic const char doc[] = N_("\
66b08d5a8fb42f4586d756068065186b5af7e48daUlrich DrepperPedantic checking of ELF files compliance with gABI/psABI spec.");
67b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper
68b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper/* Strings for arguments in help texts.  */
69b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepperstatic const char args_doc[] = N_("FILE...");
70b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper
71b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper/* Prototype for option handler.  */
72b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepperstatic error_t parse_opt (int key, char *arg, struct argp_state *state);
73b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper
74b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper/* Data structure to communicate with argp functions.  */
75b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepperstatic struct argp argp =
76b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper{
77b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper  options, parse_opt, args_doc, doc, NULL, NULL, NULL
78b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper};
79b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper
80b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper
81b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper/* Declarations of local functions.  */
82b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepperstatic void process_file (int fd, Elf *elf, const char *prefix,
83b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper			  const char *suffix, const char *fname, size_t size,
84b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper			  bool only_one);
85b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepperstatic void process_elf_file (Elf *elf, const char *prefix, const char *suffix,
86b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper			      const char *fname, size_t size, bool only_one);
87b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper
88b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper/* Report an error.  */
89b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper#define ERROR(str, args...) \
90b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper  do {									      \
91b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper    printf (str, ##args);						      \
92b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper    ++error_count;							      \
93b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper  } while (0)
94b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepperstatic unsigned int error_count;
95b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper
9659ea7f33f781e6e3f8c9d81d457e5d99eee8f1ceRoland McGrath/* True if we should perform very strict testing.  */
9759ea7f33f781e6e3f8c9d81d457e5d99eee8f1ceRoland McGrathstatic bool be_strict;
9859ea7f33f781e6e3f8c9d81d457e5d99eee8f1ceRoland McGrath
99b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper/* True if no message is to be printed if the run is succesful.  */
100b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepperstatic bool be_quiet;
101b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper
102b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper/* True if binary is from strip -f, not a normal ELF file.  */
103b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepperstatic bool is_debuginfo;
104b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper
105b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper/* True if binary is assumed to be generated with GNU ld.  */
106b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepperstatic bool gnuld;
107b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper
108b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper/* Index of section header string table.  */
109b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepperstatic uint32_t shstrndx;
110b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper
111b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper/* Array to count references in section groups.  */
112b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepperstatic int *scnref;
113b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper
114b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper
115b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepperint
116b08d5a8fb42f4586d756068065186b5af7e48daUlrich Dreppermain (int argc, char *argv[])
117b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper{
118b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper  /* Set locale.  */
119b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper  setlocale (LC_ALL, "");
120b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper
121b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper  /* Initialize the message catalog.  */
122b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper  textdomain (PACKAGE);
123b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper
124b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper  /* Parse and process arguments.  */
125b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper  int remaining;
12671c1534c9c7a0652fb6c5f9295baa08f32b0b166Jakub Jelinek  argp_parse (&argp, argc, argv, 0, &remaining, NULL);
12771c1534c9c7a0652fb6c5f9295baa08f32b0b166Jakub Jelinek
12871c1534c9c7a0652fb6c5f9295baa08f32b0b166Jakub Jelinek  /* Before we start tell the ELF library which version we are using.  */
12971c1534c9c7a0652fb6c5f9295baa08f32b0b166Jakub Jelinek  elf_version (EV_CURRENT);
130b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper
131b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper  /* Now process all the files given at the command line.  */
132b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper  bool only_one = remaining + 1 == argc;
133b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper  do
134b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper    {
135b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper      /* Open the file.  */
136b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper      int fd = open (argv[remaining], O_RDONLY);
137b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper      if (fd == -1)
138b0243863149acde9e42b25688c7c2959830e69a9Ulrich Drepper	{
139b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper	  error (0, errno, gettext ("cannot open input file"));
140b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper	  continue;
141b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper	}
142b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper
143b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper      /* Create an `Elf' descriptor.  */
144b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper      Elf *elf = elf_begin (fd, ELF_C_READ_MMAP, NULL);
145b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper      if (elf == NULL)
146b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper	ERROR (gettext ("cannot generate Elf descriptor: %s\n"),
147b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper	       elf_errmsg (-1));
148b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper      else
149b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper	{
150b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper	  unsigned int prev_error_count = error_count;
151b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper	  struct stat64 st;
152b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper
153b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper	  if (fstat64 (fd, &st) != 0)
154b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper	    {
155b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper	      printf ("cannot stat '%s': %m\n", argv[remaining]);
156b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper	      close (fd);
157b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper	      continue;
158b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper	    }
159b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper
160b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper	  process_file (fd, elf, NULL, NULL, argv[remaining], st.st_size,
161b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper			only_one);
162b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper
163b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper	  /* Now we can close the descriptor.  */
164b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper	  if (elf_end (elf) != 0)
165b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper	    ERROR (gettext ("error while closing Elf descriptor: %s\n"),
166b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper		   elf_errmsg (-1));
167b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper
168b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper	  if (prev_error_count == error_count && !be_quiet)
169b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper	    puts (gettext ("No errors"));
170b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper	}
171b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper
172b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper      close (fd);
173b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper    }
174b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper  while (++remaining < argc);
175b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper
176b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper  return error_count != 0;
177b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper}
178b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper
179b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper
180b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper/* Handle program arguments.  */
181b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepperstatic error_t
182b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepperparse_opt (int key, char *arg __attribute__ ((unused)),
183b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper	   struct argp_state *state __attribute__ ((unused)))
184b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper{
185b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper  switch (key)
186b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper    {
187b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper    case ARGP_strict:
188b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper      be_strict = true;
189b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper      break;
190b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper
191b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper    case 'q':
192b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper      be_quiet = true;
193b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper      break;
194b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper
195b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper    case 'd':
196b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper      is_debuginfo = true;
197b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper
198b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper    case ARGP_gnuld:
199b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper      gnuld = true;
200b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper      break;
201b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper
202b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper    case ARGP_KEY_NO_ARGS:
203b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper      fputs (gettext ("Missing file name.\n"), stderr);
204b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper      argp_help (&argp, stderr, ARGP_HELP_SEE | ARGP_HELP_EXIT_ERR,
205b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper		 program_invocation_short_name);
206b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper      exit (1);
207b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper
208b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper    default:
209b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper      return ARGP_ERR_UNKNOWN;
210b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper    }
211b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper  return 0;
212b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper}
213b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper
214b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper
215b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper/* Print the version information.  */
216b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepperstatic void
217b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepperprint_version (FILE *stream, struct argp_state *state __attribute__ ((unused)))
218b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper{
219b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper  fprintf (stream, "elflint (%s) %s\n", PACKAGE_NAME, VERSION);
2205ee720c60a298352b52513d03ede85814ab63ad5Ulrich Drepper  fprintf (stream, gettext ("\
2215ee720c60a298352b52513d03ede85814ab63ad5Ulrich DrepperCopyright (C) %s Red Hat, Inc.\n\
222b08d5a8fb42f4586d756068065186b5af7e48daUlrich DrepperThis is free software; see the source for copying conditions.  There is NO\n\
223b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepperwarranty; not even for MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.\n\
224b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper"), "2005");
225b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper  fprintf (stream, gettext ("Written by %s.\n"), "Ulrich Drepper");
226b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper}
227b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper
228b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper
229b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper/* Process one file.  */
230b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepperstatic void
231b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepperprocess_file (int fd, Elf *elf, const char *prefix, const char *suffix,
232b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper	      const char *fname, size_t size, bool only_one)
233b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper{
234b0243863149acde9e42b25688c7c2959830e69a9Ulrich Drepper  /* We can handle two types of files: ELF files and archives.  */
235b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper  Elf_Kind kind = elf_kind (elf);
236b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper
237b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper  switch (kind)
238b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper    {
2393a64a3087f53ab860c7de04da0e53dabef459520Ulrich Drepper    case ELF_K_ELF:
240b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper      /* Yes!  It's an ELF file.  */
241b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper      process_elf_file (elf, prefix, suffix, fname, size, only_one);
242b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper      break;
243b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper
244b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper    case ELF_K_AR:
245b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper      {
246b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper	Elf *subelf;
247b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper	Elf_Cmd cmd = ELF_C_READ_MMAP;
248b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper	size_t prefix_len = prefix == NULL ? 0 : strlen (prefix);
249b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper	size_t fname_len = strlen (fname) + 1;
250b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper	char new_prefix[prefix_len + 1 + fname_len];
251b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper	char new_suffix[(suffix == NULL ? 0 : strlen (suffix)) + 2];
252b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper	char *cp = new_prefix;
253b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper
254b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper	/* Create the full name of the file.  */
255b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper	if (prefix != NULL)
256b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper	  {
257b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper	    cp = mempcpy (cp, prefix, prefix_len);
258b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper	    *cp++ = '(';
259b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper	    strcpy (stpcpy (new_suffix, suffix), ")");
260b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper	  }
261b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper	else
262b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper	  new_suffix[0] = '\0';
263b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper	memcpy (cp, fname, fname_len);
264b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper
265b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper	/* It's an archive.  We process each file in it.  */
266b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper	while ((subelf = elf_begin (fd, cmd, elf)) != NULL)
267b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper	  {
268b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper	    kind = elf_kind (subelf);
269b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper
270b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper	    /* Call this function recursively.  */
271b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper	    if (kind == ELF_K_ELF || kind == ELF_K_AR)
272b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper	      {
273b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper		Elf_Arhdr *arhdr = elf_getarhdr (subelf);
274b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper		assert (arhdr != NULL);
275b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper
276b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper		process_file (fd, subelf, new_prefix, new_suffix,
277b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper			      arhdr->ar_name, arhdr->ar_size, false);
278b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper	      }
279b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper
280b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper	    /* Get next archive element.  */
281b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper	    cmd = elf_next (subelf);
282b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper	    if (elf_end (subelf) != 0)
283b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper	      ERROR (gettext (" error while freeing sub-ELF descriptor: %s\n"),
284b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper		     elf_errmsg (-1));
285b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper	  }
286b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper      }
287b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper      break;
288b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper
289b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper    default:
290b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper      /* We cannot do anything.  */
291b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper      ERROR (gettext ("\
292b08d5a8fb42f4586d756068065186b5af7e48daUlrich DrepperNot an ELF file - it has the wrong magic bytes at the start\n"));
293b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper      break;
294b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper    }
295b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper}
296b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper
297b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper
298b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepperstatic const char *
299b08d5a8fb42f4586d756068065186b5af7e48daUlrich Dreppersection_name (Ebl *ebl, int idx)
300b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper{
301b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper  GElf_Shdr shdr_mem;
302b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper  GElf_Shdr *shdr;
303b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper
304b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper  shdr = gelf_getshdr (elf_getscn (ebl->elf, idx), &shdr_mem);
305b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper
306b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper  return elf_strptr (ebl->elf, shstrndx, shdr->sh_name);
30741de488a0ad6679e816dbab960351e5f62ab8eadUlrich Drepper}
308b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper
309b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper
310b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepperstatic const int valid_e_machine[] =
311b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper  {
312b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper    EM_M32, EM_SPARC, EM_386, EM_68K, EM_88K, EM_860, EM_MIPS, EM_S370,
313b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper    EM_MIPS_RS3_LE, EM_PARISC, EM_VPP500, EM_SPARC32PLUS, EM_960, EM_PPC,
314b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper    EM_PPC64, EM_S390, EM_V800, EM_FR20, EM_RH32, EM_RCE, EM_ARM,
315b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper    EM_FAKE_ALPHA, EM_SH, EM_SPARCV9, EM_TRICORE, EM_ARC, EM_H8_300,
316b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper    EM_H8_300H, EM_H8S, EM_H8_500, EM_IA_64, EM_MIPS_X, EM_COLDFIRE,
317b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper    EM_68HC12, EM_MMA, EM_PCP, EM_NCPU, EM_NDR1, EM_STARCORE, EM_ME16,
31871c1534c9c7a0652fb6c5f9295baa08f32b0b166Jakub Jelinek    EM_ST100, EM_TINYJ, EM_X86_64, EM_PDSP, EM_FX66, EM_ST9PLUS, EM_ST7,
31971c1534c9c7a0652fb6c5f9295baa08f32b0b166Jakub Jelinek    EM_68HC16, EM_68HC11, EM_68HC08, EM_68HC05, EM_SVX, EM_ST19, EM_VAX,
32071c1534c9c7a0652fb6c5f9295baa08f32b0b166Jakub Jelinek    EM_CRIS, EM_JAVELIN, EM_FIREPATH, EM_ZSP, EM_MMIX, EM_HUANY, EM_PRISM,
32171c1534c9c7a0652fb6c5f9295baa08f32b0b166Jakub Jelinek    EM_AVR, EM_FR30, EM_D10V, EM_D30V, EM_V850, EM_M32R, EM_MN10300,
322b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper    EM_MN10200, EM_PJ, EM_OPENRISC, EM_ARC_A5, EM_XTENSA
323b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper  };
32471c1534c9c7a0652fb6c5f9295baa08f32b0b166Jakub Jelinek#define nvalid_e_machine \
32571c1534c9c7a0652fb6c5f9295baa08f32b0b166Jakub Jelinek  (sizeof (valid_e_machine) / sizeof (valid_e_machine[0]))
326b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper
32771c1534c9c7a0652fb6c5f9295baa08f32b0b166Jakub Jelinek
32871c1534c9c7a0652fb6c5f9295baa08f32b0b166Jakub Jelinek/* Number of sections.  */
32971c1534c9c7a0652fb6c5f9295baa08f32b0b166Jakub Jelinekstatic unsigned int shnum;
33071c1534c9c7a0652fb6c5f9295baa08f32b0b166Jakub Jelinek
331b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper
332b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepperstatic void
333b08d5a8fb42f4586d756068065186b5af7e48daUlrich Dreppercheck_elf_header (Ebl *ebl, GElf_Ehdr *ehdr, size_t size)
334b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper{
335b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper  char buf[512];
336b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper  size_t cnt;
337b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper
338b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper  /* Check e_ident field.  */
339b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper  if (ehdr->e_ident[EI_MAG0] != ELFMAG0)
340b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper    ERROR ("e_ident[%d] != '%c'\n", EI_MAG0, ELFMAG0);
341b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper  if (ehdr->e_ident[EI_MAG1] != ELFMAG1)
342b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper    ERROR ("e_ident[%d] != '%c'\n", EI_MAG1, ELFMAG1);
343b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper  if (ehdr->e_ident[EI_MAG2] != ELFMAG2)
344b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper    ERROR ("e_ident[%d] != '%c'\n", EI_MAG2, ELFMAG2);
345b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper  if (ehdr->e_ident[EI_MAG3] != ELFMAG3)
346257dcf47ed0cf57bcd2ad225cc7aaa6a8dfeb2abJeff Kenton    ERROR ("e_ident[%d] != '%c'\n", EI_MAG3, ELFMAG3);
34798c8a7395b4e5e7bed233397148b15c1f8c66490Petr Machata
348b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper  if (ehdr->e_ident[EI_CLASS] != ELFCLASS32
349b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper      && ehdr->e_ident[EI_CLASS] != ELFCLASS64)
350b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper    ERROR (gettext ("e_ident[%d] == %d is no known class\n"),
351b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper	   EI_CLASS, ehdr->e_ident[EI_CLASS]);
352b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper
353b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper  if (ehdr->e_ident[EI_DATA] != ELFDATA2LSB
354b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper      && ehdr->e_ident[EI_DATA] != ELFDATA2MSB)
355b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper    ERROR (gettext ("e_ident[%d] == %d is no known data encoding\n"),
356b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper	   EI_DATA, ehdr->e_ident[EI_DATA]);
357b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper
358b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper  if (ehdr->e_ident[EI_VERSION] != EV_CURRENT)
359b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper    ERROR (gettext ("unknown ELF header version number e_ident[%d] == %d\n"),
360b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper	   EI_VERSION, ehdr->e_ident[EI_VERSION]);
361b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper
362b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper  /* We currently don't handle any OS ABIs.  */
363b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper  if (ehdr->e_ident[EI_OSABI] != ELFOSABI_NONE)
364b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper    ERROR (gettext ("unsupported OS ABI e_ident[%d] == '%s'\n"),
365b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper	   EI_OSABI,
366b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper	   ebl_osabi_name (ebl, ehdr->e_ident[EI_OSABI], buf, sizeof (buf)));
367b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper
368b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper  /* No ABI versions other than zero supported either.  */
369b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper  if (ehdr->e_ident[EI_ABIVERSION] != 0)
370b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper    ERROR (gettext ("unsupport ABI version e_ident[%d] == %d\n"),
371b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper	   EI_ABIVERSION, ehdr->e_ident[EI_ABIVERSION]);
372b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper
373b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper  for (cnt = EI_PAD; cnt < EI_NIDENT; ++cnt)
374b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper    if (ehdr->e_ident[cnt] != 0)
375b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper      ERROR (gettext ("e_ident[%zu] is not zero\n"), cnt);
376b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper
377b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper  /* Check the e_type field.  */
378b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper  if (ehdr->e_type != ET_REL && ehdr->e_type != ET_EXEC
379b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper      && ehdr->e_type != ET_DYN && ehdr->e_type != ET_CORE)
380b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper    ERROR (gettext ("unknown object file type %d\n"), ehdr->e_type);
381b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper
382b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper  /* Check the e_machine field.  */
38396d950e3e28d89469b62b46d5a014ad1260e6a1aUlrich Drepper  for (cnt = 0; cnt < nvalid_e_machine; ++cnt)
38496d950e3e28d89469b62b46d5a014ad1260e6a1aUlrich Drepper    if (valid_e_machine[cnt] == ehdr->e_machine)
38596d950e3e28d89469b62b46d5a014ad1260e6a1aUlrich Drepper      break;
386e3f9b7db6c7361579ec5cc5eb5e414f7e93baeb6Ulrich Drepper  if (cnt == nvalid_e_machine)
387b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper    ERROR (gettext ("unknown machine type %d\n"), ehdr->e_machine);
388b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper
389b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper  /* Check the e_version field.  */
390b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper  if (ehdr->e_version != EV_CURRENT)
391b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper    ERROR (gettext ("unknown object file version\n"));
392b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper
393b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper  /* Check the e_phoff and e_phnum fields.  */
394b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper  if (ehdr->e_phoff == 0)
395b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper    {
396b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper      if (ehdr->e_phnum != 0)
397b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper	ERROR (gettext ("invalid program header offset\n"));
398b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper      else if (ehdr->e_type == ET_EXEC || ehdr->e_type == ET_DYN)
399b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper	ERROR (gettext ("\
400b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepperexecutables and DSOs cannot have zero program header offset\n"));
401b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper    }
402b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper  else if (ehdr->e_phnum == 0)
403b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper    ERROR (gettext ("invalid number of program header entries\n"));
404b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper
405b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper  /* Check the e_shoff field.  */
406b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper  shnum = ehdr->e_shnum;
407b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper  shstrndx = ehdr->e_shstrndx;
408b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper  if (ehdr->e_shoff == 0)
409b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper    {
410b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper      if (ehdr->e_shnum != 0)
411b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper	ERROR (gettext ("invalid section header table offset\n"));
412b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper      else if (ehdr->e_type != ET_EXEC && ehdr->e_type != ET_DYN
413b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper	       && ehdr->e_type != ET_CORE)
414b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper	ERROR (gettext ("section header table must be present\n"));
415b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper    }
416b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper  else
417b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper    {
418b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper      if (ehdr->e_shnum == 0)
419b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper	{
420b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper	  /* Get the header of the zeroth section.  The sh_size field
421b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper	     might contain the section number.  */
422b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper	  GElf_Shdr shdr_mem;
423b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper	  GElf_Shdr *shdr = gelf_getshdr (elf_getscn (ebl->elf, 0), &shdr_mem);
424b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper	  if (shdr != NULL)
425b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper	    {
426b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper	      /* The error will be reported later.  */
427b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper	      if (shdr->sh_size == 0)
428b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper		ERROR (gettext ("\
429b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepperinvalid number of section header table entries\n"));
430b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper	      else
431b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper		shnum = shdr->sh_size;
432b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper	    }
433b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper	}
434b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper
435b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper      if (ehdr->e_shstrndx == SHN_XINDEX)
436b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper	{
437b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper	  /* Get the header of the zeroth section.  The sh_size field
438b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper	     might contain the section number.  */
439b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper	  GElf_Shdr shdr_mem;
440b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper	  GElf_Shdr *shdr = gelf_getshdr (elf_getscn (ebl->elf, 0), &shdr_mem);
441b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper	  if (shdr != NULL && shdr->sh_link < shnum)
442b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper	    shstrndx = shdr->sh_link;
443b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper	}
444b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper      else if (shstrndx >= shnum)
445acb8983909a3f031041ee5d7cbe09fbeb3c31b9aUlrich Drepper	ERROR (gettext ("invalid section header index\n"));
446b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper    }
447b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper
448b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper  /* Check the e_flags field.  */
449b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper  if (!ebl_machine_flag_check (ebl, ehdr->e_flags))
450b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper    ERROR (gettext ("invalid machine flags: %s\n"),
451b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper	   ebl_machine_flag_name (ebl, ehdr->e_flags, buf, sizeof (buf)));
452b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper
453b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper  /* Check e_ehsize, e_phentsize, and e_shentsize fields.  */
454b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper  if (gelf_getclass (ebl->elf) == ELFCLASS32)
455b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper    {
456b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper      if (ehdr->e_ehsize != 0 && ehdr->e_ehsize != sizeof (Elf32_Ehdr))
457b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper	ERROR (gettext ("invalid ELF header size: %hd\n"), ehdr->e_ehsize);
458b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper
459b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper      if (ehdr->e_phentsize != 0 && ehdr->e_phentsize != sizeof (Elf32_Phdr))
460b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper	ERROR (gettext ("invalid program header size: %hd\n"),
461b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper	       ehdr->e_phentsize);
462acb8983909a3f031041ee5d7cbe09fbeb3c31b9aUlrich Drepper      else if (ehdr->e_phoff + ehdr->e_phnum * ehdr->e_phentsize > size)
463acb8983909a3f031041ee5d7cbe09fbeb3c31b9aUlrich Drepper	ERROR (gettext ("invalid program header position or size\n"));
464acb8983909a3f031041ee5d7cbe09fbeb3c31b9aUlrich Drepper
465b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper      if (ehdr->e_shentsize != 0 && ehdr->e_shentsize != sizeof (Elf32_Shdr))
466b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper	ERROR (gettext ("invalid section header size: %hd\n"),
467b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper	       ehdr->e_shentsize);
468b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper      else if (ehdr->e_shoff + ehdr->e_shnum * ehdr->e_shentsize > size)
469b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper	ERROR (gettext ("invalid section header position or size\n"));
470bd733cae5159e3a3c4c05f7685559fa3ae8b58c6Roland McGrath    }
471bd733cae5159e3a3c4c05f7685559fa3ae8b58c6Roland McGrath  else if (gelf_getclass (ebl->elf) == ELFCLASS64)
472bd733cae5159e3a3c4c05f7685559fa3ae8b58c6Roland McGrath    {
473bd733cae5159e3a3c4c05f7685559fa3ae8b58c6Roland McGrath      if (ehdr->e_ehsize != 0 && ehdr->e_ehsize != sizeof (Elf64_Ehdr))
474bd733cae5159e3a3c4c05f7685559fa3ae8b58c6Roland McGrath	ERROR (gettext ("invalid ELF header size: %hd\n"), ehdr->e_ehsize);
475bd733cae5159e3a3c4c05f7685559fa3ae8b58c6Roland McGrath
476bd733cae5159e3a3c4c05f7685559fa3ae8b58c6Roland McGrath      if (ehdr->e_phentsize != 0 && ehdr->e_phentsize != sizeof (Elf64_Phdr))
477bd733cae5159e3a3c4c05f7685559fa3ae8b58c6Roland McGrath	ERROR (gettext ("invalid program header size: %hd\n"),
478bd733cae5159e3a3c4c05f7685559fa3ae8b58c6Roland McGrath	       ehdr->e_phentsize);
479bd733cae5159e3a3c4c05f7685559fa3ae8b58c6Roland McGrath      else if (ehdr->e_phoff + ehdr->e_phnum * ehdr->e_phentsize > size)
480bd733cae5159e3a3c4c05f7685559fa3ae8b58c6Roland McGrath	ERROR (gettext ("invalid program header position or size\n"));
481bd733cae5159e3a3c4c05f7685559fa3ae8b58c6Roland McGrath
482bd733cae5159e3a3c4c05f7685559fa3ae8b58c6Roland McGrath      if (ehdr->e_shentsize != 0 && ehdr->e_shentsize != sizeof (Elf64_Shdr))
483bd733cae5159e3a3c4c05f7685559fa3ae8b58c6Roland McGrath	ERROR (gettext ("invalid section header size: %hd\n"),
484bd733cae5159e3a3c4c05f7685559fa3ae8b58c6Roland McGrath	       ehdr->e_shentsize);
485bd733cae5159e3a3c4c05f7685559fa3ae8b58c6Roland McGrath      else if (ehdr->e_shoff + ehdr->e_shnum * ehdr->e_shentsize > size)
486bd733cae5159e3a3c4c05f7685559fa3ae8b58c6Roland McGrath	ERROR (gettext ("invalid section header position or size\n"));
487bd733cae5159e3a3c4c05f7685559fa3ae8b58c6Roland McGrath    }
488b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper}
489b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper
490b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper
491b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper/* Check that there is a section group section with index < IDX which
492b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper   contains section IDX and that there is exactly one.  */
493b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepperstatic void
494b08d5a8fb42f4586d756068065186b5af7e48daUlrich Dreppercheck_scn_group (Ebl *ebl, int idx)
495b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper{
496b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper  if (scnref[idx] == 0)
497b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper    {
498b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper      /* No reference so far.  Search following sections, maybe the
499b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper	 order is wrong.  */
500b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper      size_t cnt;
501b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper
502bd733cae5159e3a3c4c05f7685559fa3ae8b58c6Roland McGrath      for (cnt = idx + 1; cnt < shnum; ++cnt)
503b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper	{
504b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper	  Elf_Scn *scn = elf_getscn (ebl->elf, cnt);
505b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper	  GElf_Shdr shdr_mem;
506b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper	  GElf_Shdr *shdr = gelf_getshdr (scn, &shdr_mem);
507b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper	  if (shdr == NULL)
508bd733cae5159e3a3c4c05f7685559fa3ae8b58c6Roland McGrath	    /* We cannot get the section header so we cannot check it.
509b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper	       The error to get the section header will be shown
510b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper	       somewhere else.  */
511b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper	    continue;
512b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper
513b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper	  if (shdr->sh_type != SHT_GROUP)
514b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper	    continue;
515b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper
516b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper	  Elf_Data *data = elf_getdata (scn, NULL);
517b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper	  if (data == NULL || data->d_size < sizeof (Elf32_Word))
518b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper	    /* Cannot check the section.  */
519bd733cae5159e3a3c4c05f7685559fa3ae8b58c6Roland McGrath	    continue;
520b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper
521b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper	  Elf32_Word *grpdata = (Elf32_Word *) data->d_buf;
522b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper	  for (size_t inner = 1; inner < data->d_size / sizeof (Elf32_Word);
523b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper	       ++inner)
524b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper	    if (grpdata[inner] == (Elf32_Word) idx)
525b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper	      goto out;
526b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper	}
527b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper
528b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper    out:
529b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper      if (cnt == shnum)
530b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper	ERROR (gettext ("\
531b08d5a8fb42f4586d756068065186b5af7e48daUlrich Dreppersection [%2d] '%s': section with SHF_GROUP flag set not part of a section group\n"),
532b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper	       idx, section_name (ebl, idx));
533b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper      else
534b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper	ERROR (gettext ("\
535b08d5a8fb42f4586d756068065186b5af7e48daUlrich Dreppersection [%2d] '%s': section group [%2zu] '%s' does not preceed group member\n"),
536b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper	       idx, section_name (ebl, idx),
537b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper	       cnt, section_name (ebl, cnt));
538b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper    }
539b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper}
540b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper
541b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper
542b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepperstatic void
543b08d5a8fb42f4586d756068065186b5af7e48daUlrich Dreppercheck_symtab (Ebl *ebl, GElf_Ehdr *ehdr, GElf_Shdr *shdr, int idx)
544acb8983909a3f031041ee5d7cbe09fbeb3c31b9aUlrich Drepper{
545b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper  bool no_xndx_warned = false;
546acb8983909a3f031041ee5d7cbe09fbeb3c31b9aUlrich Drepper  int no_pt_tls = 0;
547b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper  Elf_Data *data = elf_getdata (elf_getscn (ebl->elf, idx), NULL);
548b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper  if (data == NULL)
549b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper    {
550b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper      ERROR (gettext ("section [%2d] '%s': cannot get section data\n"),
551b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper	     idx, section_name (ebl, idx));
552b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper      return;
553b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper    }
554b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper
555b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper  GElf_Shdr strshdr_mem;
556acb8983909a3f031041ee5d7cbe09fbeb3c31b9aUlrich Drepper  GElf_Shdr *strshdr = gelf_getshdr (elf_getscn (ebl->elf, shdr->sh_link),
5570a545e678f2c0605ba050b4f72080572ac7c8470Mark Wielaard				     &strshdr_mem);
5580a545e678f2c0605ba050b4f72080572ac7c8470Mark Wielaard  if (strshdr == NULL)
559b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper    return;
560b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper
561b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper  if (strshdr->sh_type != SHT_STRTAB)
562acb8983909a3f031041ee5d7cbe09fbeb3c31b9aUlrich Drepper    ERROR (gettext ("section [%2d] '%s': referenced as string table for section [%2d] '%s' but type is not SHT_STRTAB\n"),
563acb8983909a3f031041ee5d7cbe09fbeb3c31b9aUlrich Drepper	   shdr->sh_link, section_name (ebl, shdr->sh_link),
564acb8983909a3f031041ee5d7cbe09fbeb3c31b9aUlrich Drepper	   idx, section_name (ebl, idx));
565b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper
566b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper  /* Search for an extended section index table section.  */
567b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper  size_t cnt;
568b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper  Elf_Data *xndxdata = NULL;
569b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper  Elf32_Word xndxscnidx = 0;
570b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper  bool found_xndx = false;
571b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper  for (cnt = 1; cnt < shnum; ++cnt)
572b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper    if (cnt != (size_t) idx)
573b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper      {
574b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper	Elf_Scn *xndxscn = elf_getscn (ebl->elf, cnt);
575b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper	GElf_Shdr xndxshdr_mem;
5763b495d8e963eead963a37b5be5b063c96bb58c63Roland McGrath	GElf_Shdr *xndxshdr = gelf_getshdr (xndxscn, &xndxshdr_mem);
577b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper	if (xndxshdr == NULL)
578b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper	  continue;
579b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper
580b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper	if (xndxshdr->sh_type == SHT_SYMTAB_SHNDX
581b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper	    && xndxshdr->sh_link == (GElf_Word) idx)
582b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper	  {
583b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper	    if (found_xndx)
584dbace2389b6f89cd4f8f2713aac50a16b16964a2Ulrich Drepper	      ERROR (gettext ("\
585b08d5a8fb42f4586d756068065186b5af7e48daUlrich Dreppersection [%2d] '%s': symbol table cannot have more than one extended index section\n"),
586b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper		     idx, section_name (ebl, idx));
587b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper
588dbace2389b6f89cd4f8f2713aac50a16b16964a2Ulrich Drepper	    xndxdata = elf_getdata (xndxscn, NULL);
589b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper	    xndxscnidx = elf_ndxscn (xndxscn);
590b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper	    found_xndx = true;
591b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper	  }
592b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper      }
593b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper
594b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper  if (shdr->sh_entsize != gelf_fsize (ebl->elf, ELF_T_SYM, 1, EV_CURRENT))
595b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper    ERROR (gettext ("\
596dbace2389b6f89cd4f8f2713aac50a16b16964a2Ulrich Dreppersection [%2zu] '%s': entry size is does not match ElfXX_Sym\n"),
597dbace2389b6f89cd4f8f2713aac50a16b16964a2Ulrich Drepper	   cnt, section_name (ebl, cnt));
598dbace2389b6f89cd4f8f2713aac50a16b16964a2Ulrich Drepper
599dbace2389b6f89cd4f8f2713aac50a16b16964a2Ulrich Drepper  /* Test the zeroth entry.  */
600dbace2389b6f89cd4f8f2713aac50a16b16964a2Ulrich Drepper  GElf_Sym sym_mem;
601dbace2389b6f89cd4f8f2713aac50a16b16964a2Ulrich Drepper  Elf32_Word xndx;
602b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper  GElf_Sym *sym = gelf_getsymshndx (data, xndxdata, 0, &sym_mem, &xndx);
603521c47d2a216fc64098c024fc5ed53532b485f32Roland McGrath  if (sym == NULL)
604521c47d2a216fc64098c024fc5ed53532b485f32Roland McGrath      ERROR (gettext ("section [%2d] '%s': cannot get symbol %d: %s\n"),
605521c47d2a216fc64098c024fc5ed53532b485f32Roland McGrath	     idx, section_name (ebl, idx), 0, elf_errmsg (-1));
606521c47d2a216fc64098c024fc5ed53532b485f32Roland McGrath  else
607521c47d2a216fc64098c024fc5ed53532b485f32Roland McGrath    {
608521c47d2a216fc64098c024fc5ed53532b485f32Roland McGrath      if (sym->st_name != 0)
609b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper	ERROR (gettext ("section [%2d] '%s': '%s' in zeroth entry not zero\n"),
610b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper	       idx, section_name (ebl, idx), "st_name");
611b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper      if (sym->st_value != 0)
612b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper	ERROR (gettext ("section [%2d] '%s': '%s' in zeroth entry not zero\n"),
613acb8983909a3f031041ee5d7cbe09fbeb3c31b9aUlrich Drepper	       idx, section_name (ebl, idx), "st_value");
6143cbdd387c752999255aea91600b5cfdefbeac7d0Ulrich Drepper      if (sym->st_size != 0)
615b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper	ERROR (gettext ("section [%2d] '%s': '%s' in zeroth entry not zero\n"),
616b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper	       idx, section_name (ebl, idx), "st_size");
617b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper      if (sym->st_info != 0)
618acb8983909a3f031041ee5d7cbe09fbeb3c31b9aUlrich Drepper	ERROR (gettext ("section [%2d] '%s': '%s' in zeroth entry not zero\n"),
619acb8983909a3f031041ee5d7cbe09fbeb3c31b9aUlrich Drepper	       idx, section_name (ebl, idx), "st_info");
620acb8983909a3f031041ee5d7cbe09fbeb3c31b9aUlrich Drepper      if (sym->st_other != 0)
621b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper	ERROR (gettext ("section [%2d] '%s': '%s' in zeroth entry not zero\n"),
622b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper	       idx, section_name (ebl, idx), "st_other");
623b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper      if (sym->st_shndx != 0)
624b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper	ERROR (gettext ("section [%2d] '%s': '%s' in zeroth entry not zero\n"),
625acb8983909a3f031041ee5d7cbe09fbeb3c31b9aUlrich Drepper	       idx, section_name (ebl, idx), "st_shndx");
626acb8983909a3f031041ee5d7cbe09fbeb3c31b9aUlrich Drepper      if (xndxdata != NULL && xndx != 0)
627acb8983909a3f031041ee5d7cbe09fbeb3c31b9aUlrich Drepper	ERROR (gettext ("\
628acb8983909a3f031041ee5d7cbe09fbeb3c31b9aUlrich Dreppersection [%2d] '%s': XINDEX for zeroth entry not zero\n"),
629acb8983909a3f031041ee5d7cbe09fbeb3c31b9aUlrich Drepper	       xndxscnidx, section_name (ebl, xndxscnidx));
630acb8983909a3f031041ee5d7cbe09fbeb3c31b9aUlrich Drepper    }
631acb8983909a3f031041ee5d7cbe09fbeb3c31b9aUlrich Drepper
632acb8983909a3f031041ee5d7cbe09fbeb3c31b9aUlrich Drepper  for (cnt = 1; cnt < shdr->sh_size / shdr->sh_entsize; ++cnt)
633acb8983909a3f031041ee5d7cbe09fbeb3c31b9aUlrich Drepper    {
634acb8983909a3f031041ee5d7cbe09fbeb3c31b9aUlrich Drepper      sym = gelf_getsymshndx (data, xndxdata, cnt, &sym_mem, &xndx);
635b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper      if (sym == NULL)
636b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper	{
63771c1534c9c7a0652fb6c5f9295baa08f32b0b166Jakub Jelinek	  ERROR (gettext ("section [%2d] '%s': cannot get symbol %zu: %s\n"),
63871c1534c9c7a0652fb6c5f9295baa08f32b0b166Jakub Jelinek		 idx, section_name (ebl, idx), cnt, elf_errmsg (-1));
639b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper	  continue;
6403cbdd387c752999255aea91600b5cfdefbeac7d0Ulrich Drepper	}
6413cbdd387c752999255aea91600b5cfdefbeac7d0Ulrich Drepper
642b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper      const char *name = NULL;
643b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper      if (sym->st_name >= strshdr->sh_size)
644b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper	ERROR (gettext ("\
645b08d5a8fb42f4586d756068065186b5af7e48daUlrich Dreppersection [%2d] '%s': symbol %zu: invalid name value\n"),
646b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper	       idx, section_name (ebl, idx), cnt);
647b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper      else
648b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper	{
649b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper	  name = elf_strptr (ebl->elf, shdr->sh_link, sym->st_name);
650b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper	  assert (name != NULL);
651b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper	}
652b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper
653b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper      if (sym->st_shndx == SHN_XINDEX)
654b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper	{
655b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper	  if (xndxdata == NULL)
656b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper	    {
657b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper	      ERROR (gettext ("\
658b08d5a8fb42f4586d756068065186b5af7e48daUlrich Dreppersection [%2d] '%s': symbol %zu: too large section index but no extended section index section\n"),
659b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper		     idx, section_name (ebl, idx), cnt);
660b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper	      no_xndx_warned = true;
661b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper	    }
662b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper	  else if (xndx < SHN_LORESERVE)
663b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper	    ERROR (gettext ("\
664b08d5a8fb42f4586d756068065186b5af7e48daUlrich Dreppersection [%2d] '%s': symbol %zu: XINDEX used for index which would fit in st_shndx (%" PRIu32 ")\n"),
665b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper		   xndxscnidx, section_name (ebl, xndxscnidx), cnt,
666b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper		   xndx);
667b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper	}
668b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper      else if ((sym->st_shndx >= SHN_LORESERVE
669b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper		// && sym->st_shndx <= SHN_HIRESERVE    always true
670b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper		&& sym->st_shndx != SHN_ABS
671b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper		&& sym->st_shndx != SHN_COMMON)
672b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper	       || (sym->st_shndx >= shnum
673b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper		   && (sym->st_shndx < SHN_LORESERVE
674b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper		       /* || sym->st_shndx > SHN_HIRESERVE  always false */)))
675b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper	ERROR (gettext ("\
67671c1534c9c7a0652fb6c5f9295baa08f32b0b166Jakub Jelineksection [%2d] '%s': symbol %zu: invalid section index\n"),
677b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper	       idx, section_name (ebl, idx), cnt);
678b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper      else
679b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper	xndx = sym->st_shndx;
680b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper
681b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper      if (GELF_ST_TYPE (sym->st_info) >= STT_NUM
682b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper	  && !ebl_symbol_type_name (ebl, GELF_ST_TYPE (sym->st_info), NULL, 0))
683b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper	ERROR (gettext ("section [%2d] '%s': symbol %zu: unknown type\n"),
684b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper	       idx, section_name (ebl, idx), cnt);
685b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper
686b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper      if (GELF_ST_BIND (sym->st_info) >= STB_NUM)
687521c47d2a216fc64098c024fc5ed53532b485f32Roland McGrath	ERROR (gettext ("\
688521c47d2a216fc64098c024fc5ed53532b485f32Roland McGrathsection [%2d] '%s': symbol %zu: unknown symbol binding\n"),
689521c47d2a216fc64098c024fc5ed53532b485f32Roland McGrath	       idx, section_name (ebl, idx), cnt);
690b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper
691b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper      if (xndx == SHN_COMMON)
692b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper	{
693b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper	  /* Common symbols can only appear in relocatable files.  */
694b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper	  if (ehdr->e_type != ET_REL)
695b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper	    ERROR (gettext ("\
6960a545e678f2c0605ba050b4f72080572ac7c8470Mark Wielaardsection [%2d] '%s': symbol %zu: COMMON only allowed in relocatable files\n"),
6970a545e678f2c0605ba050b4f72080572ac7c8470Mark Wielaard		   idx, section_name (ebl, idx), cnt);
698b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper	  if (cnt < shdr->sh_info)
699b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper	    ERROR (gettext ("\
700b08d5a8fb42f4586d756068065186b5af7e48daUlrich Dreppersection [%2d] '%s': symbol %zu: local COMMON symbols are nonsense\n"),
701b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper		   idx, section_name (ebl, idx), cnt);
702b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper	  if (GELF_R_TYPE (sym->st_info) == STT_FUNC)
703b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper	    ERROR (gettext ("\
704fd992543185126eb0280c1ee0883e073020499b4Roland McGrathsection [%2d] '%s': symbol %zu: function in COMMON section is nonsense\n"),
705fd992543185126eb0280c1ee0883e073020499b4Roland McGrath		   idx, section_name (ebl, idx), cnt);
706b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper	}
707fd992543185126eb0280c1ee0883e073020499b4Roland McGrath      else if (xndx > 0 && xndx < shnum)
708b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper	{
709b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper	  GElf_Shdr destshdr_mem;
710b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper	  GElf_Shdr *destshdr;
711b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper
712b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper	  destshdr = gelf_getshdr (elf_getscn (ebl->elf, xndx), &destshdr_mem);
713b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper	  if (destshdr != NULL)
714b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper	    {
715b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper	      if (GELF_ST_TYPE (sym->st_info) != STT_TLS)
716b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper		{
717b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper		  if (! ebl_check_special_symbol (ebl, ehdr, sym, name,
718b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper						  destshdr))
719b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper		    {
720b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper		      if ((sym->st_value - destshdr->sh_addr)
721b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper			  > destshdr->sh_size)
722b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper			ERROR (gettext ("\
723b08d5a8fb42f4586d756068065186b5af7e48daUlrich Dreppersection [%2d] '%s': symbol %zu: st_value out of bounds\n"),
724b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper			       idx, section_name (ebl, idx), cnt);
725b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper		      else if ((sym->st_value - destshdr->sh_addr
726b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper				+ sym->st_size) > destshdr->sh_size)
727b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper			ERROR (gettext ("\
728b08d5a8fb42f4586d756068065186b5af7e48daUlrich Dreppersection [%2d] '%s': symbol %zu does not fit completely in referenced section [%2d] '%s'\n"),
72918e13427fa32a5464f1678be31512c0e0fec59c7Roland McGrath			       idx, section_name (ebl, idx), cnt,
73018e13427fa32a5464f1678be31512c0e0fec59c7Roland McGrath			       (int) xndx, section_name (ebl, xndx));
731b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper		    }
732b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper		}
733b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper	      else
73496d950e3e28d89469b62b46d5a014ad1260e6a1aUlrich Drepper		{
73596d950e3e28d89469b62b46d5a014ad1260e6a1aUlrich Drepper		  if ((destshdr->sh_flags & SHF_TLS) == 0)
73696d950e3e28d89469b62b46d5a014ad1260e6a1aUlrich Drepper		    ERROR (gettext ("\
737b08d5a8fb42f4586d756068065186b5af7e48daUlrich Dreppersection [%2d] '%s': symbol %zu: referenced section [%2d] '%s' does not have SHF_TLS flag set\n"),
738b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper			   idx, section_name (ebl, idx), cnt,
739b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper			   (int) xndx, section_name (ebl, xndx));
74096d950e3e28d89469b62b46d5a014ad1260e6a1aUlrich Drepper
74196d950e3e28d89469b62b46d5a014ad1260e6a1aUlrich Drepper		  if (ehdr->e_type == ET_REL)
74296d950e3e28d89469b62b46d5a014ad1260e6a1aUlrich Drepper		    {
74396d950e3e28d89469b62b46d5a014ad1260e6a1aUlrich Drepper		      /* For object files the symbol value must fall
74496d950e3e28d89469b62b46d5a014ad1260e6a1aUlrich Drepper                         into the section.  */
745b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper		      if (sym->st_value > destshdr->sh_size)
746b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper			ERROR (gettext ("\
747b08d5a8fb42f4586d756068065186b5af7e48daUlrich Dreppersection [%2d] '%s': symbol %zu: st_value out of bounds of referenced section [%2d] '%s'\n"),
748b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper			       idx, section_name (ebl, idx), cnt,
749b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper			       (int) xndx, section_name (ebl, xndx));
750b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper		      else if (sym->st_value + sym->st_size
751b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper			       > destshdr->sh_size)
752b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper			ERROR (gettext ("\
753b08d5a8fb42f4586d756068065186b5af7e48daUlrich Dreppersection [%2d] '%s': symbol %zu does not fit completely in referenced section [%2d] '%s'\n"),
754b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper			       idx, section_name (ebl, idx), cnt,
755b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper			       (int) xndx, section_name (ebl, xndx));
756b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper		    }
757b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper		  else
758b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper		    {
759b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper		      GElf_Phdr phdr_mem;
760b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper		      GElf_Phdr *phdr = NULL;
761b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper		      int pcnt;
762b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper
763b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper		      for (pcnt = 0; pcnt < ehdr->e_phnum; ++pcnt)
764b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper			{
765b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper			  phdr = gelf_getphdr (ebl->elf, pcnt, &phdr_mem);
766b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper			  if (phdr != NULL && phdr->p_type == PT_TLS)
767b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper			    break;
768b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper			}
769b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper
770b597dfad924980dede10d7c19d87900b6172e599Ulrich Drepper		      if (pcnt == ehdr->e_phnum)
771b597dfad924980dede10d7c19d87900b6172e599Ulrich Drepper			{
772c1c1c06e30f0b3b4ae66fcfec6318a93b8f31569Mark Wielaard			  if (no_pt_tls++ == 0)
773c1c1c06e30f0b3b4ae66fcfec6318a93b8f31569Mark Wielaard			    ERROR (gettext ("\
774c1c1c06e30f0b3b4ae66fcfec6318a93b8f31569Mark Wielaardsection [%2d] '%s': symbol %zu: TLS symbol but no TLS program header entry\n"),
775c1c1c06e30f0b3b4ae66fcfec6318a93b8f31569Mark Wielaard				   idx, section_name (ebl, idx), cnt);
776c1c1c06e30f0b3b4ae66fcfec6318a93b8f31569Mark Wielaard			}
777c1c1c06e30f0b3b4ae66fcfec6318a93b8f31569Mark Wielaard		      else
778b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper			{
779b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper			  if (sym->st_value
780c5c33a6a2ce5ea400ac5d06b3c2f15808f68b803Ulrich Drepper			      < destshdr->sh_offset - phdr->p_offset)
781c5c33a6a2ce5ea400ac5d06b3c2f15808f68b803Ulrich Drepper			    ERROR (gettext ("\
782c5c33a6a2ce5ea400ac5d06b3c2f15808f68b803Ulrich Dreppersection [%2d] '%s': symbol %zu: st_value short of referenced section [%2d] '%s'\n"),
783c1c1c06e30f0b3b4ae66fcfec6318a93b8f31569Mark Wielaard				   idx, section_name (ebl, idx), cnt,
784ce0bdb6ee5f977af9e565f2871ba2b1b37d162a5Ulrich Drepper				   (int) xndx, section_name (ebl, xndx));
785ce0bdb6ee5f977af9e565f2871ba2b1b37d162a5Ulrich Drepper			  else if (sym->st_value
786ce0bdb6ee5f977af9e565f2871ba2b1b37d162a5Ulrich Drepper				   > (destshdr->sh_offset - phdr->p_offset
7873bdc16ce98295463c071192eab2ec611a8edc508Mark Wielaard				      + destshdr->sh_size))
7883bdc16ce98295463c071192eab2ec611a8edc508Mark Wielaard			    ERROR (gettext ("\
7893bdc16ce98295463c071192eab2ec611a8edc508Mark Wielaardsection [%2d] '%s': symbol %zu: st_value out of bounds of referenced section [%2d] '%s'\n"),
790ce0bdb6ee5f977af9e565f2871ba2b1b37d162a5Ulrich Drepper				   idx, section_name (ebl, idx), cnt,
7913bdc16ce98295463c071192eab2ec611a8edc508Mark Wielaard				   (int) xndx, section_name (ebl, xndx));
7923bdc16ce98295463c071192eab2ec611a8edc508Mark Wielaard			  else if (sym->st_value + sym->st_size
7933bdc16ce98295463c071192eab2ec611a8edc508Mark Wielaard				   > (destshdr->sh_offset - phdr->p_offset
7943bdc16ce98295463c071192eab2ec611a8edc508Mark Wielaard				      + destshdr->sh_size))
795ce0bdb6ee5f977af9e565f2871ba2b1b37d162a5Ulrich Drepper			    ERROR (gettext ("\
796ce0bdb6ee5f977af9e565f2871ba2b1b37d162a5Ulrich Dreppersection [%2d] '%s': symbol %zu does not fit completely in referenced section [%2d] '%s'\n"),
797ce0bdb6ee5f977af9e565f2871ba2b1b37d162a5Ulrich Drepper				   idx, section_name (ebl, idx), cnt,
798ce0bdb6ee5f977af9e565f2871ba2b1b37d162a5Ulrich Drepper				   (int) xndx, section_name (ebl, xndx));
799ce0bdb6ee5f977af9e565f2871ba2b1b37d162a5Ulrich Drepper			}
8003bdc16ce98295463c071192eab2ec611a8edc508Mark Wielaard		    }
8013bdc16ce98295463c071192eab2ec611a8edc508Mark Wielaard		}
802b94cceae503b56fb360cd597f154fa2b33552887Mark Wielaard	    }
803a95c4ad24cf83b2b0273fee73162bf476cebec8fMark Wielaard	}
804a95c4ad24cf83b2b0273fee73162bf476cebec8fMark Wielaard
805ce0bdb6ee5f977af9e565f2871ba2b1b37d162a5Ulrich Drepper      if (GELF_ST_BIND (sym->st_info) == STB_LOCAL)
806b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper	{
807ce0bdb6ee5f977af9e565f2871ba2b1b37d162a5Ulrich Drepper	  if (cnt >= shdr->sh_info)
808ce0bdb6ee5f977af9e565f2871ba2b1b37d162a5Ulrich Drepper	    ERROR (gettext ("\
809c1c1c06e30f0b3b4ae66fcfec6318a93b8f31569Mark Wielaardsection [%2d] '%s': symbol %zu: local symbol outside range described in sh_info\n"),
810c5c33a6a2ce5ea400ac5d06b3c2f15808f68b803Ulrich Drepper		   idx, section_name (ebl, idx), cnt);
811c5c33a6a2ce5ea400ac5d06b3c2f15808f68b803Ulrich Drepper	}
812b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper      else
813c5c33a6a2ce5ea400ac5d06b3c2f15808f68b803Ulrich Drepper	{
814c5c33a6a2ce5ea400ac5d06b3c2f15808f68b803Ulrich Drepper	  if (cnt < shdr->sh_info)
815c5c33a6a2ce5ea400ac5d06b3c2f15808f68b803Ulrich Drepper	    ERROR (gettext ("\
816b08d5a8fb42f4586d756068065186b5af7e48daUlrich Dreppersection [%2d] '%s': symbol %zu: non-local symbol outside range described in sh_info\n"),
817b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper		   idx, section_name (ebl, idx), cnt);
818b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper	}
819b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper
820b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper      if (GELF_ST_TYPE (sym->st_info) == STT_SECTION
821b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper	  && GELF_ST_BIND (sym->st_info) != STB_LOCAL)
822b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper	ERROR (gettext ("\
823b08d5a8fb42f4586d756068065186b5af7e48daUlrich Dreppersection [%2d] '%s': symbol %zu: non-local section symbol\n"),
824b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper	       idx, section_name (ebl, idx), cnt);
825b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper
826b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper      if (name != NULL)
827b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper	{
828c49d00afc4bda21181cd4237e67930f3f5228adfMark Wielaard	  if (strcmp (name, "_GLOBAL_OFFSET_TABLE_") == 0)
829c1c1c06e30f0b3b4ae66fcfec6318a93b8f31569Mark Wielaard	    {
830b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper	      /* Check that address and size match the global offset table.  */
831b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper
832b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper	      GElf_Shdr destshdr_mem;
833b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper	      GElf_Shdr *destshdr = gelf_getshdr (elf_getscn (ebl->elf, xndx),
834c1c1c06e30f0b3b4ae66fcfec6318a93b8f31569Mark Wielaard						  &destshdr_mem);
835b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper
836b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper	      if (destshdr == NULL && xndx == SHN_ABS)
837b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper		{
838b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper		  /* In a DSO, we have to find the GOT section by name.  */
839b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper		  Elf_Scn *gotscn = NULL;
840b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper		  Elf_Scn *gscn = NULL;
841b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper		  while ((gscn = elf_nextscn (ebl->elf, gscn)) != NULL)
842b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper		    {
843b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper		      destshdr = gelf_getshdr (gscn, &destshdr_mem);
844b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper		      assert (destshdr != NULL);
845bd733cae5159e3a3c4c05f7685559fa3ae8b58c6Roland McGrath		      const char *sname = elf_strptr (ebl->elf,
846b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper						      ehdr->e_shstrndx,
847bd733cae5159e3a3c4c05f7685559fa3ae8b58c6Roland McGrath						      destshdr->sh_name);
848b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper		      if (sname != NULL)
849b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper			{
850b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper			  if (strcmp (sname, ".got.plt") == 0)
851b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper			    break;
852b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper			  if (strcmp (sname, ".got") == 0)
853b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper			    /* Do not stop looking.
854bd733cae5159e3a3c4c05f7685559fa3ae8b58c6Roland McGrath			       There might be a .got.plt section.  */
855b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper			    gotscn = gscn;
856b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper			}
857b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper
858b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper		      destshdr = NULL;
859b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper		    }
860b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper
86177be59bca4057b22af70b0b2d0197f9505577381Mark Wielaard		  if (destshdr == NULL && gotscn != NULL)
86277be59bca4057b22af70b0b2d0197f9505577381Mark Wielaard		    destshdr = gelf_getshdr (gotscn, &destshdr_mem);
86377be59bca4057b22af70b0b2d0197f9505577381Mark Wielaard		}
86477be59bca4057b22af70b0b2d0197f9505577381Mark Wielaard
86577be59bca4057b22af70b0b2d0197f9505577381Mark Wielaard	      const char *sname = (destshdr == NULL ? NULL
86677be59bca4057b22af70b0b2d0197f9505577381Mark Wielaard				   : elf_strptr (ebl->elf, ehdr->e_shstrndx,
867b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper						 destshdr->sh_name));
868b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper	      if (sname == NULL)
869c1c1c06e30f0b3b4ae66fcfec6318a93b8f31569Mark Wielaard		ERROR (gettext ("\
870b08d5a8fb42f4586d756068065186b5af7e48daUlrich Dreppersection [%2d] '%s': _GLOBAL_OFFSET_TABLE_ symbol refers to bad section\n"),
871b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper		       idx, section_name (ebl, idx));
872b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper	      else if (strcmp (sname, ".got.plt") != 0
873b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper		       && strcmp (sname, ".got") != 0)
874b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper		ERROR (gettext ("\
875c1c1c06e30f0b3b4ae66fcfec6318a93b8f31569Mark Wielaardsection [%2d] '%s': _GLOBAL_OFFSET_TABLE_ symbol refers to '%s' section\n"),
876b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper		       idx, section_name (ebl, idx), sname);
877b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper
878b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper	      if (destshdr != NULL)
879b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper		{
880b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper		  /* Found it.  */
881b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper		  if (!ebl_check_special_symbol (ebl, ehdr, sym, name,
882c1c1c06e30f0b3b4ae66fcfec6318a93b8f31569Mark Wielaard						 destshdr))
883b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper		    {
884b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper		      if (sym->st_value != destshdr->sh_addr)
885b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper			/* This test is more strict than the psABIs which
886b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper			   usually allow the symbol to be in the middle of
887b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper			   the .got section, allowing negative offsets.  */
888b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper			ERROR (gettext ("\
889b08d5a8fb42f4586d756068065186b5af7e48daUlrich Dreppersection [%2d] '%s': _GLOBAL_OFFSET_TABLE_ symbol value %#" PRIx64 " does not match %s section address %#" PRIx64 "\n"),
890b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper			       idx, section_name (ebl, idx),
891b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper			       (uint64_t) sym->st_value,
892b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper			       sname, (uint64_t) destshdr->sh_addr);
893b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper
894b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper		      if (!gnuld && sym->st_size != destshdr->sh_size)
895b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper			ERROR (gettext ("\
896b08d5a8fb42f4586d756068065186b5af7e48daUlrich Dreppersection [%2d] '%s': _GLOBAL_OFFSET_TABLE_ symbol size %" PRIu64 " does not match %s section size %" PRIu64 "\n"),
897b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper			       idx, section_name (ebl, idx),
898b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper			       (uint64_t) sym->st_size,
899b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper			       sname, (uint64_t) destshdr->sh_size);
900b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper		    }
901b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper		}
902b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper	      else
903b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper		ERROR (gettext ("\
904b08d5a8fb42f4586d756068065186b5af7e48daUlrich Dreppersection [%2d] '%s': _GLOBAL_OFFSET_TABLE_ symbol present, but no .got section\n"),
905b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper		       idx, section_name (ebl, idx));
906b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper	    }
907b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper	  else if (strcmp (name, "_DYNAMIC") == 0)
908b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper	    /* Check that address and size match the dynamic section.
909b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper	       We locate the dynamic section via the program header
910b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper	       entry.  */
911b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper	    for (int pcnt = 0; pcnt < ehdr->e_phnum; ++pcnt)
912b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper	      {
913b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper		GElf_Phdr phdr_mem;
914b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper		GElf_Phdr *phdr = gelf_getphdr (ebl->elf, pcnt, &phdr_mem);
915b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper
916b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper		if (phdr != NULL && phdr->p_type == PT_DYNAMIC)
917b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper		  {
918b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper		    if (sym->st_value != phdr->p_vaddr)
919b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper		      ERROR (gettext ("\
920653d3763e986da9f1c8a92ff9103d85c534754cdRoland McGrathsection [%2d] '%s': _DYNAMIC_ symbol value %#" PRIx64 " does not match dynamic segment address %#" PRIx64 "\n"),
921653d3763e986da9f1c8a92ff9103d85c534754cdRoland McGrath			     idx, section_name (ebl, idx),
922653d3763e986da9f1c8a92ff9103d85c534754cdRoland McGrath			     (uint64_t) sym->st_value,
923653d3763e986da9f1c8a92ff9103d85c534754cdRoland McGrath			     (uint64_t) phdr->p_vaddr);
924653d3763e986da9f1c8a92ff9103d85c534754cdRoland McGrath
925653d3763e986da9f1c8a92ff9103d85c534754cdRoland McGrath		    if (!gnuld && sym->st_size != phdr->p_memsz)
926653d3763e986da9f1c8a92ff9103d85c534754cdRoland McGrath		      ERROR (gettext ("\
927b08d5a8fb42f4586d756068065186b5af7e48daUlrich Dreppersection [%2d] '%s': _DYNAMIC symbol size %" PRIu64 " does not match dynamic segment size %" PRIu64 "\n"),
928653d3763e986da9f1c8a92ff9103d85c534754cdRoland McGrath			     idx, section_name (ebl, idx),
929653d3763e986da9f1c8a92ff9103d85c534754cdRoland McGrath			     (uint64_t) sym->st_size,
930c5c33a6a2ce5ea400ac5d06b3c2f15808f68b803Ulrich Drepper			     (uint64_t) phdr->p_memsz);
931653d3763e986da9f1c8a92ff9103d85c534754cdRoland McGrath
932b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper		    break;
933653d3763e986da9f1c8a92ff9103d85c534754cdRoland McGrath		  }
934653d3763e986da9f1c8a92ff9103d85c534754cdRoland McGrath	    }
935653d3763e986da9f1c8a92ff9103d85c534754cdRoland McGrath	}
936653d3763e986da9f1c8a92ff9103d85c534754cdRoland McGrath    }
937653d3763e986da9f1c8a92ff9103d85c534754cdRoland McGrath}
938653d3763e986da9f1c8a92ff9103d85c534754cdRoland McGrath
939b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper
940c5c33a6a2ce5ea400ac5d06b3c2f15808f68b803Ulrich Drepperstatic bool
941653d3763e986da9f1c8a92ff9103d85c534754cdRoland McGrathis_rel_dyn (Ebl *ebl, const GElf_Ehdr *ehdr, int idx, const GElf_Shdr *shdr,
942c5c33a6a2ce5ea400ac5d06b3c2f15808f68b803Ulrich Drepper	    bool rela)
943653d3763e986da9f1c8a92ff9103d85c534754cdRoland McGrath{
944653d3763e986da9f1c8a92ff9103d85c534754cdRoland McGrath  /* If this is no executable or DSO it cannot be a .rel.dyn section.  */
945653d3763e986da9f1c8a92ff9103d85c534754cdRoland McGrath  if (ehdr->e_type != ET_EXEC && ehdr->e_type != ET_DYN)
946b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper    return false;
947653d3763e986da9f1c8a92ff9103d85c534754cdRoland McGrath
948653d3763e986da9f1c8a92ff9103d85c534754cdRoland McGrath  /* Check the section name.  Unfortunately necessary.  */
949b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper  if (strcmp (section_name (ebl, idx), rela ? ".rela.dyn" : ".rel.dyn"))
950653d3763e986da9f1c8a92ff9103d85c534754cdRoland McGrath    return false;
951653d3763e986da9f1c8a92ff9103d85c534754cdRoland McGrath
952653d3763e986da9f1c8a92ff9103d85c534754cdRoland McGrath  /* When a .rel.dyn section is used a DT_RELCOUNT dynamic section
953b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper     entry can be present as well.  */
954b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper  Elf_Scn *scn = NULL;
955b597dfad924980dede10d7c19d87900b6172e599Ulrich Drepper  while ((scn = elf_nextscn (ebl->elf, scn)) != NULL)
956b597dfad924980dede10d7c19d87900b6172e599Ulrich Drepper    {
957653d3763e986da9f1c8a92ff9103d85c534754cdRoland McGrath      GElf_Shdr rcshdr_mem;
958653d3763e986da9f1c8a92ff9103d85c534754cdRoland McGrath      const GElf_Shdr *rcshdr = gelf_getshdr (scn, &rcshdr_mem);
959653d3763e986da9f1c8a92ff9103d85c534754cdRoland McGrath      assert (rcshdr != NULL);
960b597dfad924980dede10d7c19d87900b6172e599Ulrich Drepper
961b597dfad924980dede10d7c19d87900b6172e599Ulrich Drepper      if (rcshdr->sh_type == SHT_DYNAMIC)
962b597dfad924980dede10d7c19d87900b6172e599Ulrich Drepper	{
963b597dfad924980dede10d7c19d87900b6172e599Ulrich Drepper	  /* Found the dynamic section.  Look through it.  */
964b597dfad924980dede10d7c19d87900b6172e599Ulrich Drepper	  Elf_Data *d = elf_getdata (scn, NULL);
965b597dfad924980dede10d7c19d87900b6172e599Ulrich Drepper	  size_t cnt;
966b597dfad924980dede10d7c19d87900b6172e599Ulrich Drepper
967653d3763e986da9f1c8a92ff9103d85c534754cdRoland McGrath	  for (cnt = 1; cnt < rcshdr->sh_size / rcshdr->sh_entsize; ++cnt)
968653d3763e986da9f1c8a92ff9103d85c534754cdRoland McGrath	    {
969653d3763e986da9f1c8a92ff9103d85c534754cdRoland McGrath	      GElf_Dyn dyn_mem;
970b597dfad924980dede10d7c19d87900b6172e599Ulrich Drepper	      GElf_Dyn *dyn = gelf_getdyn (d, cnt, &dyn_mem);
971b597dfad924980dede10d7c19d87900b6172e599Ulrich Drepper	      assert (dyn != NULL);
972b597dfad924980dede10d7c19d87900b6172e599Ulrich Drepper
973653d3763e986da9f1c8a92ff9103d85c534754cdRoland McGrath	      if (dyn->d_tag == DT_RELCOUNT)
974653d3763e986da9f1c8a92ff9103d85c534754cdRoland McGrath		{
975b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper		  /* Found it.  One last check: does the number
976b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper		     specified number of relative relocations exceed
977c5c33a6a2ce5ea400ac5d06b3c2f15808f68b803Ulrich Drepper		     the total number of relocations?  */
978c5c33a6a2ce5ea400ac5d06b3c2f15808f68b803Ulrich Drepper		  if (dyn->d_un.d_val > shdr->sh_size / shdr->sh_entsize)
979c5c33a6a2ce5ea400ac5d06b3c2f15808f68b803Ulrich Drepper		    ERROR (gettext ("\
980b597dfad924980dede10d7c19d87900b6172e599Ulrich Dreppersection [%2d] '%s': DT_RELCOUNT value %d too high for this section\n"),
981b597dfad924980dede10d7c19d87900b6172e599Ulrich Drepper			   idx, section_name (ebl, idx),
982c5c33a6a2ce5ea400ac5d06b3c2f15808f68b803Ulrich Drepper			   (int) dyn->d_un.d_val);
983c5c33a6a2ce5ea400ac5d06b3c2f15808f68b803Ulrich Drepper		}
984c5c33a6a2ce5ea400ac5d06b3c2f15808f68b803Ulrich Drepper	    }
985c5c33a6a2ce5ea400ac5d06b3c2f15808f68b803Ulrich Drepper
986653d3763e986da9f1c8a92ff9103d85c534754cdRoland McGrath	  break;
987c5c33a6a2ce5ea400ac5d06b3c2f15808f68b803Ulrich Drepper	}
988c5c33a6a2ce5ea400ac5d06b3c2f15808f68b803Ulrich Drepper    }
989c5c33a6a2ce5ea400ac5d06b3c2f15808f68b803Ulrich Drepper
990b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper  return true;
991c5c33a6a2ce5ea400ac5d06b3c2f15808f68b803Ulrich Drepper}
992c5c33a6a2ce5ea400ac5d06b3c2f15808f68b803Ulrich Drepper
993653d3763e986da9f1c8a92ff9103d85c534754cdRoland McGrath
994c5c33a6a2ce5ea400ac5d06b3c2f15808f68b803Ulrich Drepperstruct loaded_segment
995c5c33a6a2ce5ea400ac5d06b3c2f15808f68b803Ulrich Drepper{
996c5c33a6a2ce5ea400ac5d06b3c2f15808f68b803Ulrich Drepper  GElf_Addr from;
997c5c33a6a2ce5ea400ac5d06b3c2f15808f68b803Ulrich Drepper  GElf_Addr to;
998b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper  bool read_only;
999b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper  struct loaded_segment *next;
1000b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper};
1001b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper
1002b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper
1003b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper/* Check whether binary has text relocation flag set.  */
1004b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepperstatic bool textrel;
100541de488a0ad6679e816dbab960351e5f62ab8eadUlrich Drepper
100641de488a0ad6679e816dbab960351e5f62ab8eadUlrich Drepper/* Keep track of whether text relocation flag is needed.  */
100741de488a0ad6679e816dbab960351e5f62ab8eadUlrich Drepperstatic bool needed_textrel;
1008bd733cae5159e3a3c4c05f7685559fa3ae8b58c6Roland McGrath
100941de488a0ad6679e816dbab960351e5f62ab8eadUlrich Drepper
101041de488a0ad6679e816dbab960351e5f62ab8eadUlrich Drepperstatic bool
101141de488a0ad6679e816dbab960351e5f62ab8eadUlrich Dreppercheck_reloc_shdr (Ebl *ebl, const GElf_Ehdr *ehdr, const GElf_Shdr *shdr,
1012b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper		  int idx, int reltype, GElf_Shdr **destshdrp,
101341de488a0ad6679e816dbab960351e5f62ab8eadUlrich Drepper		  GElf_Shdr *destshdr_memp, struct loaded_segment **loadedp)
101441de488a0ad6679e816dbab960351e5f62ab8eadUlrich Drepper{
101541de488a0ad6679e816dbab960351e5f62ab8eadUlrich Drepper  bool reldyn = false;
101641de488a0ad6679e816dbab960351e5f62ab8eadUlrich Drepper
1017b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper  /* Check whether the link to the section we relocate is reasonable.  */
101841de488a0ad6679e816dbab960351e5f62ab8eadUlrich Drepper  if (shdr->sh_info >= shnum)
101941de488a0ad6679e816dbab960351e5f62ab8eadUlrich Drepper    ERROR (gettext ("section [%2d] '%s': invalid destination section index\n"),
102041de488a0ad6679e816dbab960351e5f62ab8eadUlrich Drepper	   idx, section_name (ebl, idx));
1021b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper  else if (shdr->sh_info != 0)
102241de488a0ad6679e816dbab960351e5f62ab8eadUlrich Drepper    {
102341de488a0ad6679e816dbab960351e5f62ab8eadUlrich Drepper      *destshdrp = gelf_getshdr (elf_getscn (ebl->elf, shdr->sh_info),
1024b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper				 destshdr_memp);
102541de488a0ad6679e816dbab960351e5f62ab8eadUlrich Drepper      if (*destshdrp != NULL)
102641de488a0ad6679e816dbab960351e5f62ab8eadUlrich Drepper	{
102741de488a0ad6679e816dbab960351e5f62ab8eadUlrich Drepper	  if((*destshdrp)->sh_type != SHT_PROGBITS
1028b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper	     && (*destshdrp)->sh_type != SHT_NOBITS)
102941de488a0ad6679e816dbab960351e5f62ab8eadUlrich Drepper	    {
103041de488a0ad6679e816dbab960351e5f62ab8eadUlrich Drepper	      reldyn = is_rel_dyn (ebl, ehdr, idx, shdr, true);
1031b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper	      if (!reldyn)
1032b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper		ERROR (gettext ("\
1033c803fbe6c3fa15d08dee1c99948ec66326db1e9eUlrich Dreppersection [%2d] '%s': invalid destination section type\n"),
1034c803fbe6c3fa15d08dee1c99948ec66326db1e9eUlrich Drepper		       idx, section_name (ebl, idx));
1035c803fbe6c3fa15d08dee1c99948ec66326db1e9eUlrich Drepper	      else
1036c803fbe6c3fa15d08dee1c99948ec66326db1e9eUlrich Drepper		{
1037c803fbe6c3fa15d08dee1c99948ec66326db1e9eUlrich Drepper		  /* There is no standard, but we require that .rel{,a}.dyn
1038c803fbe6c3fa15d08dee1c99948ec66326db1e9eUlrich Drepper		     sections have a sh_info value of zero.  */
1039a062b6bcadd1565d360acf640f9d4c159b2270eaMark Wielaard		  if (shdr->sh_info != 0)
1040c803fbe6c3fa15d08dee1c99948ec66326db1e9eUlrich Drepper		    ERROR (gettext ("\
1041c803fbe6c3fa15d08dee1c99948ec66326db1e9eUlrich Dreppersection [%2d] '%s': sh_info should be zero\n"),
1042c803fbe6c3fa15d08dee1c99948ec66326db1e9eUlrich Drepper			   idx, section_name (ebl, idx));
1043c803fbe6c3fa15d08dee1c99948ec66326db1e9eUlrich Drepper		}
1044b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper	    }
1045b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper
1046b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper	  if (((*destshdrp)->sh_flags & (SHF_MERGE | SHF_STRINGS)) != 0)
1047b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper	    ERROR (gettext ("\
1048b08d5a8fb42f4586d756068065186b5af7e48daUlrich Dreppersection [%2d] '%s': no relocations for merge-able sections possible\n"),
1049c911c9efe553d9af2d4fb0d420d8b614983e16acUlrich Drepper		   idx, section_name (ebl, idx));
105028ed895fdc303b2a793506bb1fcdd35d5fd14e70Ulrich Drepper	}
1051b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper    }
1052b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper
1053b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper  if (shdr->sh_entsize != gelf_fsize (ebl->elf, reltype, 1, EV_CURRENT))
1054b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper    ERROR (gettext (reltype == ELF_T_RELA ? "\
1055b08d5a8fb42f4586d756068065186b5af7e48daUlrich Dreppersection [%2d] '%s': section entry size does not match ElfXX_Rela\n" : "\
1056b08d5a8fb42f4586d756068065186b5af7e48daUlrich Dreppersection [%2d] '%s': section entry size does not match ElfXX_Rel\n"),
105728ed895fdc303b2a793506bb1fcdd35d5fd14e70Ulrich Drepper	   idx, section_name (ebl, idx));
1058b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper
1059b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper  /* In preparation of checking whether relocations are text
1060b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper     relocations or not we need to determine whether the file is
1061b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper     flagged to have text relocation and we need to determine a) what
1062b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper     the loaded segments are and b) which are read-only.  This will
1063b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper     also allow us to determine whether the same reloc section is
1064b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper     modifying loaded and not loaded segments.  */
1065b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper  for (int i = 0; i < ehdr->e_phnum; ++i)
1066b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper    {
1067b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper      GElf_Phdr phdr_mem;
106871c1534c9c7a0652fb6c5f9295baa08f32b0b166Jakub Jelinek      GElf_Phdr *phdr = gelf_getphdr (ebl->elf, i, &phdr_mem);
106971c1534c9c7a0652fb6c5f9295baa08f32b0b166Jakub Jelinek      if (phdr == NULL)
107071c1534c9c7a0652fb6c5f9295baa08f32b0b166Jakub Jelinek	continue;
10710a545e678f2c0605ba050b4f72080572ac7c8470Mark Wielaard
1072b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper      if (phdr->p_type == PT_LOAD)
1073b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper	{
1074b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper	  struct loaded_segment *newp = xmalloc (sizeof (*newp));
1075b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper	  newp->from = phdr->p_vaddr;
1076b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper	  newp->to = phdr->p_vaddr + phdr->p_memsz;
10770a545e678f2c0605ba050b4f72080572ac7c8470Mark Wielaard	  newp->read_only = (phdr->p_flags & PF_W) == 0;
10780a545e678f2c0605ba050b4f72080572ac7c8470Mark Wielaard	  newp->next = *loadedp;
10790a545e678f2c0605ba050b4f72080572ac7c8470Mark Wielaard	  *loadedp = newp;
10800a545e678f2c0605ba050b4f72080572ac7c8470Mark Wielaard	}
10810a545e678f2c0605ba050b4f72080572ac7c8470Mark Wielaard      else if (phdr->p_type == PT_DYNAMIC)
1082b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper	{
1083b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper	  Elf_Scn *dynscn = gelf_offscn (ebl->elf, phdr->p_offset);
1084b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper	  GElf_Shdr dynshdr_mem;
1085b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper	  GElf_Shdr *dynshdr = gelf_getshdr (dynscn, &dynshdr_mem);
108671c1534c9c7a0652fb6c5f9295baa08f32b0b166Jakub Jelinek	  Elf_Data *dyndata = elf_getdata (dynscn, NULL);
108771c1534c9c7a0652fb6c5f9295baa08f32b0b166Jakub Jelinek	  if (dynshdr != NULL && dynshdr->sh_type == SHT_DYNAMIC
108871c1534c9c7a0652fb6c5f9295baa08f32b0b166Jakub Jelinek	      && dyndata != NULL)
1089b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper	    for (size_t j = 0; j < dynshdr->sh_size / dynshdr->sh_entsize; ++j)
1090b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper	      {
1091b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper		GElf_Dyn dyn_mem;
109228ed895fdc303b2a793506bb1fcdd35d5fd14e70Ulrich Drepper		GElf_Dyn *dyn = gelf_getdyn (dyndata, j, &dyn_mem);
109328ed895fdc303b2a793506bb1fcdd35d5fd14e70Ulrich Drepper		if (dyn != NULL
1094b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper		    && (dyn->d_tag == DT_TEXTREL
109528ed895fdc303b2a793506bb1fcdd35d5fd14e70Ulrich Drepper			|| (dyn->d_tag == DT_FLAGS
109628ed895fdc303b2a793506bb1fcdd35d5fd14e70Ulrich Drepper			    && (dyn->d_un.d_val & DF_TEXTREL) != 0)))
109728ed895fdc303b2a793506bb1fcdd35d5fd14e70Ulrich Drepper		  {
109828ed895fdc303b2a793506bb1fcdd35d5fd14e70Ulrich Drepper		    textrel = true;
109928ed895fdc303b2a793506bb1fcdd35d5fd14e70Ulrich Drepper		    break;
110028ed895fdc303b2a793506bb1fcdd35d5fd14e70Ulrich Drepper		  }
110128ed895fdc303b2a793506bb1fcdd35d5fd14e70Ulrich Drepper	      }
110271c1534c9c7a0652fb6c5f9295baa08f32b0b166Jakub Jelinek	}
110371c1534c9c7a0652fb6c5f9295baa08f32b0b166Jakub Jelinek    }
110471c1534c9c7a0652fb6c5f9295baa08f32b0b166Jakub Jelinek
110528ed895fdc303b2a793506bb1fcdd35d5fd14e70Ulrich Drepper  /* A quick test which can be easily done here (although it is a bit
1106b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper     out of place): the text relocation flag makes only sense if there
110728ed895fdc303b2a793506bb1fcdd35d5fd14e70Ulrich Drepper     is a segment which is not writable.  */
110828ed895fdc303b2a793506bb1fcdd35d5fd14e70Ulrich Drepper  if (textrel)
110928ed895fdc303b2a793506bb1fcdd35d5fd14e70Ulrich Drepper    {
111028ed895fdc303b2a793506bb1fcdd35d5fd14e70Ulrich Drepper      struct loaded_segment *seg = *loadedp;
111128ed895fdc303b2a793506bb1fcdd35d5fd14e70Ulrich Drepper      while (seg != NULL && !seg->read_only)
111228ed895fdc303b2a793506bb1fcdd35d5fd14e70Ulrich Drepper	seg = seg->next;
111328ed895fdc303b2a793506bb1fcdd35d5fd14e70Ulrich Drepper      if (seg == NULL)
11140a545e678f2c0605ba050b4f72080572ac7c8470Mark Wielaard	ERROR (gettext ("\
111528ed895fdc303b2a793506bb1fcdd35d5fd14e70Ulrich Dreppertext relocation flag set but there is no read-only segment\n"));
111628ed895fdc303b2a793506bb1fcdd35d5fd14e70Ulrich Drepper    }
111728ed895fdc303b2a793506bb1fcdd35d5fd14e70Ulrich Drepper
111828ed895fdc303b2a793506bb1fcdd35d5fd14e70Ulrich Drepper  return reldyn;
111928ed895fdc303b2a793506bb1fcdd35d5fd14e70Ulrich Drepper}
112028ed895fdc303b2a793506bb1fcdd35d5fd14e70Ulrich Drepper
112128ed895fdc303b2a793506bb1fcdd35d5fd14e70Ulrich Drepper
112228ed895fdc303b2a793506bb1fcdd35d5fd14e70Ulrich Drepperenum load_state
112328ed895fdc303b2a793506bb1fcdd35d5fd14e70Ulrich Drepper  {
112428ed895fdc303b2a793506bb1fcdd35d5fd14e70Ulrich Drepper    state_undecided,
112528ed895fdc303b2a793506bb1fcdd35d5fd14e70Ulrich Drepper    state_loaded,
112628ed895fdc303b2a793506bb1fcdd35d5fd14e70Ulrich Drepper    state_unloaded,
112728ed895fdc303b2a793506bb1fcdd35d5fd14e70Ulrich Drepper    state_error
112828ed895fdc303b2a793506bb1fcdd35d5fd14e70Ulrich Drepper  };
112928ed895fdc303b2a793506bb1fcdd35d5fd14e70Ulrich Drepper
113028ed895fdc303b2a793506bb1fcdd35d5fd14e70Ulrich Drepper
113128ed895fdc303b2a793506bb1fcdd35d5fd14e70Ulrich Drepperstatic void
113228ed895fdc303b2a793506bb1fcdd35d5fd14e70Ulrich Dreppercheck_one_reloc (Ebl *ebl, GElf_Ehdr *ehdr, GElf_Shdr *relshdr, int idx,
113328ed895fdc303b2a793506bb1fcdd35d5fd14e70Ulrich Drepper		 size_t cnt, const GElf_Shdr *symshdr, Elf_Data *symdata,
113428ed895fdc303b2a793506bb1fcdd35d5fd14e70Ulrich Drepper		 GElf_Addr r_offset, GElf_Xword r_info,
113528ed895fdc303b2a793506bb1fcdd35d5fd14e70Ulrich Drepper		 const GElf_Shdr *destshdr, bool reldyn,
113628ed895fdc303b2a793506bb1fcdd35d5fd14e70Ulrich Drepper		 struct loaded_segment *loaded, enum load_state *statep)
113728ed895fdc303b2a793506bb1fcdd35d5fd14e70Ulrich Drepper{
113828ed895fdc303b2a793506bb1fcdd35d5fd14e70Ulrich Drepper  bool known_broken = gnuld;
113928ed895fdc303b2a793506bb1fcdd35d5fd14e70Ulrich Drepper
114028ed895fdc303b2a793506bb1fcdd35d5fd14e70Ulrich Drepper  if (!ebl_reloc_type_check (ebl, GELF_R_TYPE (r_info)))
114128ed895fdc303b2a793506bb1fcdd35d5fd14e70Ulrich Drepper    ERROR (gettext ("section [%2d] '%s': relocation %zu: invalid type\n"),
114228ed895fdc303b2a793506bb1fcdd35d5fd14e70Ulrich Drepper	   idx, section_name (ebl, idx), cnt);
114328ed895fdc303b2a793506bb1fcdd35d5fd14e70Ulrich Drepper  else if (((ehdr->e_type != ET_EXEC && ehdr->e_type != ET_DYN)
114428ed895fdc303b2a793506bb1fcdd35d5fd14e70Ulrich Drepper	    /* The executable/DSO can contain relocation sections with
114528ed895fdc303b2a793506bb1fcdd35d5fd14e70Ulrich Drepper	       all the relocations the linker has applied.  Those sections
114628ed895fdc303b2a793506bb1fcdd35d5fd14e70Ulrich Drepper	       are marked non-loaded, though.  */
114728ed895fdc303b2a793506bb1fcdd35d5fd14e70Ulrich Drepper	    || (relshdr->sh_flags & SHF_ALLOC) != 0)
114828ed895fdc303b2a793506bb1fcdd35d5fd14e70Ulrich Drepper	   && !ebl_reloc_valid_use (ebl, GELF_R_TYPE (r_info)))
114928ed895fdc303b2a793506bb1fcdd35d5fd14e70Ulrich Drepper    ERROR (gettext ("\
115028ed895fdc303b2a793506bb1fcdd35d5fd14e70Ulrich Dreppersection [%2d] '%s': relocation %zu: relocation type invalid for the file type\n"),
115128ed895fdc303b2a793506bb1fcdd35d5fd14e70Ulrich Drepper	   idx, section_name (ebl, idx), cnt);
115228ed895fdc303b2a793506bb1fcdd35d5fd14e70Ulrich Drepper
115328ed895fdc303b2a793506bb1fcdd35d5fd14e70Ulrich Drepper  if (symshdr != NULL
115428ed895fdc303b2a793506bb1fcdd35d5fd14e70Ulrich Drepper      && ((GELF_R_SYM (r_info) + 1)
115528ed895fdc303b2a793506bb1fcdd35d5fd14e70Ulrich Drepper	  * gelf_fsize (ebl->elf, ELF_T_SYM, 1, EV_CURRENT)
11560a545e678f2c0605ba050b4f72080572ac7c8470Mark Wielaard	  > symshdr->sh_size))
11570a545e678f2c0605ba050b4f72080572ac7c8470Mark Wielaard    ERROR (gettext ("\
115828ed895fdc303b2a793506bb1fcdd35d5fd14e70Ulrich Dreppersection [%2d] '%s': relocation %zu: invalid symbol index\n"),
115928ed895fdc303b2a793506bb1fcdd35d5fd14e70Ulrich Drepper	   idx, section_name (ebl, idx), cnt);
116028ed895fdc303b2a793506bb1fcdd35d5fd14e70Ulrich Drepper
116128ed895fdc303b2a793506bb1fcdd35d5fd14e70Ulrich Drepper  if (ebl_gotpc_reloc_check (ebl, GELF_R_TYPE (r_info)))
116228ed895fdc303b2a793506bb1fcdd35d5fd14e70Ulrich Drepper    {
116328ed895fdc303b2a793506bb1fcdd35d5fd14e70Ulrich Drepper      const char *name;
116428ed895fdc303b2a793506bb1fcdd35d5fd14e70Ulrich Drepper      char buf[64];
116528ed895fdc303b2a793506bb1fcdd35d5fd14e70Ulrich Drepper      GElf_Sym sym_mem;
116628ed895fdc303b2a793506bb1fcdd35d5fd14e70Ulrich Drepper      GElf_Sym *sym = gelf_getsym (symdata, GELF_R_SYM (r_info), &sym_mem);
11670a545e678f2c0605ba050b4f72080572ac7c8470Mark Wielaard      if (sym != NULL
116828ed895fdc303b2a793506bb1fcdd35d5fd14e70Ulrich Drepper	  /* Get the name for the symbol.  */
116928ed895fdc303b2a793506bb1fcdd35d5fd14e70Ulrich Drepper	  && (name = elf_strptr (ebl->elf, symshdr->sh_link, sym->st_name))
117028ed895fdc303b2a793506bb1fcdd35d5fd14e70Ulrich Drepper	  && strcmp (name, "_GLOBAL_OFFSET_TABLE_") !=0 )
117128ed895fdc303b2a793506bb1fcdd35d5fd14e70Ulrich Drepper	ERROR (gettext ("\
117228ed895fdc303b2a793506bb1fcdd35d5fd14e70Ulrich Dreppersection [%2d] '%s': relocation %zu: only symbol '_GLOBAL_OFFSET_TABLE_' can be used with %s\n"),
117328ed895fdc303b2a793506bb1fcdd35d5fd14e70Ulrich Drepper	       idx, section_name (ebl, idx), cnt,
117428ed895fdc303b2a793506bb1fcdd35d5fd14e70Ulrich Drepper	       ebl_reloc_type_name (ebl, GELF_R_SYM (r_info),
117528ed895fdc303b2a793506bb1fcdd35d5fd14e70Ulrich Drepper				    buf, sizeof (buf)));
117628ed895fdc303b2a793506bb1fcdd35d5fd14e70Ulrich Drepper    }
117728ed895fdc303b2a793506bb1fcdd35d5fd14e70Ulrich Drepper
117828ed895fdc303b2a793506bb1fcdd35d5fd14e70Ulrich Drepper  if (reldyn)
117928ed895fdc303b2a793506bb1fcdd35d5fd14e70Ulrich Drepper    {
118028ed895fdc303b2a793506bb1fcdd35d5fd14e70Ulrich Drepper      // XXX TODO Check .rel.dyn section addresses.
118128ed895fdc303b2a793506bb1fcdd35d5fd14e70Ulrich Drepper    }
118228ed895fdc303b2a793506bb1fcdd35d5fd14e70Ulrich Drepper  else if (!known_broken)
118328ed895fdc303b2a793506bb1fcdd35d5fd14e70Ulrich Drepper    {
118428ed895fdc303b2a793506bb1fcdd35d5fd14e70Ulrich Drepper      if (destshdr != NULL
118528ed895fdc303b2a793506bb1fcdd35d5fd14e70Ulrich Drepper	  && GELF_R_TYPE (r_info) != 0
118628ed895fdc303b2a793506bb1fcdd35d5fd14e70Ulrich Drepper	  && (r_offset - destshdr->sh_addr) >= destshdr->sh_size)
118728ed895fdc303b2a793506bb1fcdd35d5fd14e70Ulrich Drepper	ERROR (gettext ("\
118828ed895fdc303b2a793506bb1fcdd35d5fd14e70Ulrich Dreppersection [%2d] '%s': relocation %zu: offset out of bounds\n"),
118928ed895fdc303b2a793506bb1fcdd35d5fd14e70Ulrich Drepper	       idx, section_name (ebl, idx), cnt);
119028ed895fdc303b2a793506bb1fcdd35d5fd14e70Ulrich Drepper    }
119128ed895fdc303b2a793506bb1fcdd35d5fd14e70Ulrich Drepper
119228ed895fdc303b2a793506bb1fcdd35d5fd14e70Ulrich Drepper  GElf_Sym sym_mem;
119328ed895fdc303b2a793506bb1fcdd35d5fd14e70Ulrich Drepper  GElf_Sym *sym = gelf_getsym (symdata, GELF_R_SYM (r_info), &sym_mem);
119428ed895fdc303b2a793506bb1fcdd35d5fd14e70Ulrich Drepper
1195b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper  if (ebl_copy_reloc_p (ebl, GELF_R_TYPE (r_info))
1196b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper      /* Make sure the referenced symbol is an object or unspecified.  */
1197b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper      && sym != NULL
1198b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper      && GELF_ST_TYPE (sym->st_info) != STT_NOTYPE
1199b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper      && GELF_ST_TYPE (sym->st_info) != STT_OBJECT)
1200b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper    {
1201b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper      char buf[64];
1202b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper      ERROR (gettext ("section [%2d] '%s': relocation %zu: copy relocation against symbol of type %s\n"),
1203b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper	     idx, section_name (ebl, idx), cnt,
1204b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper	     ebl_symbol_type_name (ebl, GELF_ST_TYPE (sym->st_info),
1205b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper				   buf, sizeof (buf)));
120641de488a0ad6679e816dbab960351e5f62ab8eadUlrich Drepper    }
120741de488a0ad6679e816dbab960351e5f62ab8eadUlrich Drepper
120841de488a0ad6679e816dbab960351e5f62ab8eadUlrich Drepper  bool in_loaded_seg = false;
120941de488a0ad6679e816dbab960351e5f62ab8eadUlrich Drepper  while (loaded != NULL)
121041de488a0ad6679e816dbab960351e5f62ab8eadUlrich Drepper    {
121141de488a0ad6679e816dbab960351e5f62ab8eadUlrich Drepper      if (r_offset < loaded->to
121241de488a0ad6679e816dbab960351e5f62ab8eadUlrich Drepper	  && r_offset + (sym == NULL ? 0 : sym->st_size) >= loaded->from)
121341de488a0ad6679e816dbab960351e5f62ab8eadUlrich Drepper	{
121441de488a0ad6679e816dbab960351e5f62ab8eadUlrich Drepper	  /* The symbol is in this segment.  */
121541de488a0ad6679e816dbab960351e5f62ab8eadUlrich Drepper	  if  (loaded->read_only)
121641de488a0ad6679e816dbab960351e5f62ab8eadUlrich Drepper	    {
121741de488a0ad6679e816dbab960351e5f62ab8eadUlrich Drepper	      if (textrel)
121841de488a0ad6679e816dbab960351e5f62ab8eadUlrich Drepper		needed_textrel = true;
121941de488a0ad6679e816dbab960351e5f62ab8eadUlrich Drepper	      else
122041de488a0ad6679e816dbab960351e5f62ab8eadUlrich Drepper		ERROR (gettext ("section [%2d] '%s': relocation %zu: read-only section modified but text relocation flag not set\n"),
122141de488a0ad6679e816dbab960351e5f62ab8eadUlrich Drepper		       idx, section_name (ebl, idx), cnt);
1222c911c9efe553d9af2d4fb0d420d8b614983e16acUlrich Drepper	    }
1223c911c9efe553d9af2d4fb0d420d8b614983e16acUlrich Drepper
1224c911c9efe553d9af2d4fb0d420d8b614983e16acUlrich Drepper	  in_loaded_seg = true;
122541de488a0ad6679e816dbab960351e5f62ab8eadUlrich Drepper	}
1226b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper
1227b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper      loaded = loaded->next;
1228b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper    }
1229b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper
1230b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper  if (*statep == state_undecided)
1231b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper    *statep = in_loaded_seg ? state_loaded : state_unloaded;
1232b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper  else if ((*statep == state_unloaded && in_loaded_seg)
1233c911c9efe553d9af2d4fb0d420d8b614983e16acUlrich Drepper	   || (*statep == state_loaded && !in_loaded_seg))
1234b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper    {
1235c911c9efe553d9af2d4fb0d420d8b614983e16acUlrich Drepper      ERROR (gettext ("\
1236c911c9efe553d9af2d4fb0d420d8b614983e16acUlrich Dreppersection [%2d] '%s': relocations are against loaded and unloaded data\n"),
1237c911c9efe553d9af2d4fb0d420d8b614983e16acUlrich Drepper	     idx, section_name (ebl, idx));
1238b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper      *statep = state_error;
1239028d0ab0cc1cb5f96ee48feef966b7d8d56c6a8eMark Wielaard    }
1240b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper}
1241b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper
1242b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper
1243b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepperstatic void
1244b08d5a8fb42f4586d756068065186b5af7e48daUlrich Dreppercheck_rela (Ebl *ebl, GElf_Ehdr *ehdr, GElf_Shdr *shdr, int idx)
1245b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper{
1246b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper  Elf_Data *data = elf_getdata (elf_getscn (ebl->elf, idx), NULL);
1247b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper  if (data == NULL)
1248c911c9efe553d9af2d4fb0d420d8b614983e16acUlrich Drepper    {
1249b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper      ERROR (gettext ("section [%2d] '%s': cannot get section data\n"),
1250b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper	     idx, section_name (ebl, idx));
1251b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper      return;
1252b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper    }
1253b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper
1254b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper  /* Check the fields of the section header.  */
1255b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper  GElf_Shdr destshdr_mem;
1256b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper  GElf_Shdr *destshdr = NULL;
1257c911c9efe553d9af2d4fb0d420d8b614983e16acUlrich Drepper  struct loaded_segment *loaded = NULL;
1258b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper  bool reldyn = check_reloc_shdr (ebl, ehdr, shdr, idx, ELF_T_RELA, &destshdr,
1259b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper				  &destshdr_mem, &loaded);
1260b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper
1261b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper  Elf_Scn *symscn = elf_getscn (ebl->elf, shdr->sh_link);
1262b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper  GElf_Shdr symshdr_mem;
1263b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper  GElf_Shdr *symshdr = gelf_getshdr (symscn, &symshdr_mem);
126471c1534c9c7a0652fb6c5f9295baa08f32b0b166Jakub Jelinek  Elf_Data *symdata = elf_getdata (symscn, NULL);
126571c1534c9c7a0652fb6c5f9295baa08f32b0b166Jakub Jelinek  enum load_state state = state_undecided;
1266c911c9efe553d9af2d4fb0d420d8b614983e16acUlrich Drepper
1267c911c9efe553d9af2d4fb0d420d8b614983e16acUlrich Drepper  for (size_t cnt = 0; cnt < shdr->sh_size / shdr->sh_entsize; ++cnt)
1268c911c9efe553d9af2d4fb0d420d8b614983e16acUlrich Drepper    {
1269b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper      GElf_Rela rela_mem;
1270b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper      GElf_Rela *rela = gelf_getrela (data, cnt, &rela_mem);
127141de488a0ad6679e816dbab960351e5f62ab8eadUlrich Drepper      if (rela == NULL)
127241de488a0ad6679e816dbab960351e5f62ab8eadUlrich Drepper	{
127341de488a0ad6679e816dbab960351e5f62ab8eadUlrich Drepper	  ERROR (gettext ("\
127441de488a0ad6679e816dbab960351e5f62ab8eadUlrich Dreppersection [%2d] '%s': cannot get relocation %zu: %s\n"),
127541de488a0ad6679e816dbab960351e5f62ab8eadUlrich Drepper		 idx, section_name (ebl, idx), cnt, elf_errmsg (-1));
127641de488a0ad6679e816dbab960351e5f62ab8eadUlrich Drepper	  continue;
1277bd733cae5159e3a3c4c05f7685559fa3ae8b58c6Roland McGrath	}
127841de488a0ad6679e816dbab960351e5f62ab8eadUlrich Drepper
127941de488a0ad6679e816dbab960351e5f62ab8eadUlrich Drepper      check_one_reloc (ebl, ehdr, shdr, idx, cnt, symshdr, symdata,
128041de488a0ad6679e816dbab960351e5f62ab8eadUlrich Drepper		       rela->r_offset, rela->r_info, destshdr, reldyn, loaded,
128141de488a0ad6679e816dbab960351e5f62ab8eadUlrich Drepper		       &state);
128241de488a0ad6679e816dbab960351e5f62ab8eadUlrich Drepper    }
128341de488a0ad6679e816dbab960351e5f62ab8eadUlrich Drepper
128441de488a0ad6679e816dbab960351e5f62ab8eadUlrich Drepper  while (loaded != NULL)
128541de488a0ad6679e816dbab960351e5f62ab8eadUlrich Drepper    {
128641de488a0ad6679e816dbab960351e5f62ab8eadUlrich Drepper      struct loaded_segment *old = loaded;
128741de488a0ad6679e816dbab960351e5f62ab8eadUlrich Drepper      loaded = loaded->next;
128841de488a0ad6679e816dbab960351e5f62ab8eadUlrich Drepper      free (old);
128941de488a0ad6679e816dbab960351e5f62ab8eadUlrich Drepper    }
129041de488a0ad6679e816dbab960351e5f62ab8eadUlrich Drepper}
129141de488a0ad6679e816dbab960351e5f62ab8eadUlrich Drepper
129241de488a0ad6679e816dbab960351e5f62ab8eadUlrich Drepper
129341de488a0ad6679e816dbab960351e5f62ab8eadUlrich Drepperstatic void
129441de488a0ad6679e816dbab960351e5f62ab8eadUlrich Dreppercheck_rel (Ebl *ebl, GElf_Ehdr *ehdr, GElf_Shdr *shdr, int idx)
129541de488a0ad6679e816dbab960351e5f62ab8eadUlrich Drepper{
129641de488a0ad6679e816dbab960351e5f62ab8eadUlrich Drepper  Elf_Data *data = elf_getdata (elf_getscn (ebl->elf, idx), NULL);
129741de488a0ad6679e816dbab960351e5f62ab8eadUlrich Drepper  if (data == NULL)
129841de488a0ad6679e816dbab960351e5f62ab8eadUlrich Drepper    {
129941de488a0ad6679e816dbab960351e5f62ab8eadUlrich Drepper      ERROR (gettext ("section [%2d] '%s': cannot get section data\n"),
13000a545e678f2c0605ba050b4f72080572ac7c8470Mark Wielaard	     idx, section_name (ebl, idx));
130141de488a0ad6679e816dbab960351e5f62ab8eadUlrich Drepper      return;
130241de488a0ad6679e816dbab960351e5f62ab8eadUlrich Drepper    }
130341de488a0ad6679e816dbab960351e5f62ab8eadUlrich Drepper
130441de488a0ad6679e816dbab960351e5f62ab8eadUlrich Drepper  /* Check the fields of the section header.  */
130541de488a0ad6679e816dbab960351e5f62ab8eadUlrich Drepper  GElf_Shdr destshdr_mem;
130641de488a0ad6679e816dbab960351e5f62ab8eadUlrich Drepper  GElf_Shdr *destshdr = NULL;
130741de488a0ad6679e816dbab960351e5f62ab8eadUlrich Drepper  struct loaded_segment *loaded = NULL;
130841de488a0ad6679e816dbab960351e5f62ab8eadUlrich Drepper  bool reldyn = check_reloc_shdr (ebl, ehdr, shdr, idx, ELF_T_REL, &destshdr,
130941de488a0ad6679e816dbab960351e5f62ab8eadUlrich Drepper				  &destshdr_mem, &loaded);
131041de488a0ad6679e816dbab960351e5f62ab8eadUlrich Drepper
131141de488a0ad6679e816dbab960351e5f62ab8eadUlrich Drepper  Elf_Scn *symscn = elf_getscn (ebl->elf, shdr->sh_link);
131241de488a0ad6679e816dbab960351e5f62ab8eadUlrich Drepper  GElf_Shdr symshdr_mem;
131341de488a0ad6679e816dbab960351e5f62ab8eadUlrich Drepper  GElf_Shdr *symshdr = gelf_getshdr (symscn, &symshdr_mem);
131441de488a0ad6679e816dbab960351e5f62ab8eadUlrich Drepper  Elf_Data *symdata = elf_getdata (symscn, NULL);
131541de488a0ad6679e816dbab960351e5f62ab8eadUlrich Drepper  enum load_state state = state_undecided;
131641de488a0ad6679e816dbab960351e5f62ab8eadUlrich Drepper
131741de488a0ad6679e816dbab960351e5f62ab8eadUlrich Drepper  for (size_t cnt = 0; cnt < shdr->sh_size / shdr->sh_entsize; ++cnt)
131841de488a0ad6679e816dbab960351e5f62ab8eadUlrich Drepper    {
131941de488a0ad6679e816dbab960351e5f62ab8eadUlrich Drepper      GElf_Rel rel_mem;
132041de488a0ad6679e816dbab960351e5f62ab8eadUlrich Drepper      GElf_Rel *rel = gelf_getrel (data, cnt, &rel_mem);
132141de488a0ad6679e816dbab960351e5f62ab8eadUlrich Drepper      if (rel == NULL)
132241de488a0ad6679e816dbab960351e5f62ab8eadUlrich Drepper	{
132341de488a0ad6679e816dbab960351e5f62ab8eadUlrich Drepper	  ERROR (gettext ("\
132441de488a0ad6679e816dbab960351e5f62ab8eadUlrich Dreppersection [%2d] '%s': cannot get relocation %zu: %s\n"),
132541de488a0ad6679e816dbab960351e5f62ab8eadUlrich Drepper		 idx, section_name (ebl, idx), cnt, elf_errmsg (-1));
132641de488a0ad6679e816dbab960351e5f62ab8eadUlrich Drepper	  continue;
132741de488a0ad6679e816dbab960351e5f62ab8eadUlrich Drepper	}
132841de488a0ad6679e816dbab960351e5f62ab8eadUlrich Drepper
132941de488a0ad6679e816dbab960351e5f62ab8eadUlrich Drepper      check_one_reloc (ebl, ehdr, shdr, idx, cnt, symshdr, symdata,
1330c911c9efe553d9af2d4fb0d420d8b614983e16acUlrich Drepper		       rel->r_offset, rel->r_info, destshdr, reldyn, loaded,
1331c911c9efe553d9af2d4fb0d420d8b614983e16acUlrich Drepper		       &state);
1332b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper    }
1333b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper
133441de488a0ad6679e816dbab960351e5f62ab8eadUlrich Drepper  while (loaded != NULL)
133541de488a0ad6679e816dbab960351e5f62ab8eadUlrich Drepper    {
133641de488a0ad6679e816dbab960351e5f62ab8eadUlrich Drepper      struct loaded_segment *old = loaded;
133741de488a0ad6679e816dbab960351e5f62ab8eadUlrich Drepper      loaded = loaded->next;
133841de488a0ad6679e816dbab960351e5f62ab8eadUlrich Drepper      free (old);
133941de488a0ad6679e816dbab960351e5f62ab8eadUlrich Drepper    }
134041de488a0ad6679e816dbab960351e5f62ab8eadUlrich Drepper}
134141de488a0ad6679e816dbab960351e5f62ab8eadUlrich Drepper
134241de488a0ad6679e816dbab960351e5f62ab8eadUlrich Drepper
1343c911c9efe553d9af2d4fb0d420d8b614983e16acUlrich Drepper/* Number of dynamic sections.  */
1344607e05466d3fef5e3ad90aa200d3bba1950cf982Ulrich Drepperstatic int ndynamic;
1345607e05466d3fef5e3ad90aa200d3bba1950cf982Ulrich Drepper
1346607e05466d3fef5e3ad90aa200d3bba1950cf982Ulrich Drepper
134741de488a0ad6679e816dbab960351e5f62ab8eadUlrich Drepperstatic void
134841de488a0ad6679e816dbab960351e5f62ab8eadUlrich Dreppercheck_dynamic (Ebl *ebl, GElf_Ehdr *ehdr, GElf_Shdr *shdr, int idx)
1349c911c9efe553d9af2d4fb0d420d8b614983e16acUlrich Drepper{
1350c911c9efe553d9af2d4fb0d420d8b614983e16acUlrich Drepper  Elf_Data *data;
1351b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper  GElf_Shdr strshdr_mem;
1352c911c9efe553d9af2d4fb0d420d8b614983e16acUlrich Drepper  GElf_Shdr *strshdr;
1353c911c9efe553d9af2d4fb0d420d8b614983e16acUlrich Drepper  size_t cnt;
1354c911c9efe553d9af2d4fb0d420d8b614983e16acUlrich Drepper  static const bool dependencies[DT_NUM][DT_NUM] =
1355607e05466d3fef5e3ad90aa200d3bba1950cf982Ulrich Drepper    {
1356607e05466d3fef5e3ad90aa200d3bba1950cf982Ulrich Drepper      [DT_NEEDED] = { [DT_STRTAB] = true },
1357607e05466d3fef5e3ad90aa200d3bba1950cf982Ulrich Drepper      [DT_PLTRELSZ] = { [DT_JMPREL] = true },
1358607e05466d3fef5e3ad90aa200d3bba1950cf982Ulrich Drepper      [DT_HASH] = { [DT_SYMTAB] = true },
1359607e05466d3fef5e3ad90aa200d3bba1950cf982Ulrich Drepper      [DT_STRTAB] = { [DT_STRSZ] = true },
1360607e05466d3fef5e3ad90aa200d3bba1950cf982Ulrich Drepper      [DT_SYMTAB] = { [DT_STRTAB] = true, [DT_HASH] = true,
1361c911c9efe553d9af2d4fb0d420d8b614983e16acUlrich Drepper		      [DT_SYMENT] = true },
1362b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper      [DT_RELA] = { [DT_RELASZ] = true, [DT_RELAENT] = true },
1363c911c9efe553d9af2d4fb0d420d8b614983e16acUlrich Drepper      [DT_RELASZ] = { [DT_RELA] = true },
1364b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper      [DT_RELAENT] = { [DT_RELA] = true },
1365c911c9efe553d9af2d4fb0d420d8b614983e16acUlrich Drepper      [DT_STRSZ] = { [DT_STRTAB] = true },
1366c911c9efe553d9af2d4fb0d420d8b614983e16acUlrich Drepper      [DT_SYMENT] = { [DT_SYMTAB] = true },
1367c911c9efe553d9af2d4fb0d420d8b614983e16acUlrich Drepper      [DT_SONAME] = { [DT_STRTAB] = true },
1368c911c9efe553d9af2d4fb0d420d8b614983e16acUlrich Drepper      [DT_RPATH] = { [DT_STRTAB] = true },
1369c911c9efe553d9af2d4fb0d420d8b614983e16acUlrich Drepper      [DT_REL] = { [DT_RELSZ] = true, [DT_RELENT] = true },
1370b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper      [DT_RELSZ] = { [DT_REL] = true },
1371c911c9efe553d9af2d4fb0d420d8b614983e16acUlrich Drepper      [DT_RELENT] = { [DT_REL] = true },
1372b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper      [DT_JMPREL] = { [DT_PLTRELSZ] = true, [DT_PLTREL] = true },
13736ca4600fb59d1e1ae3dfb872b184ac91f10c473fUlrich Drepper      [DT_RUNPATH] = { [DT_STRTAB] = true },
13746ca4600fb59d1e1ae3dfb872b184ac91f10c473fUlrich Drepper      [DT_PLTREL] = { [DT_JMPREL] = true },
13756ca4600fb59d1e1ae3dfb872b184ac91f10c473fUlrich Drepper      [DT_PLTRELSZ] = { [DT_JMPREL] = true }
13766ca4600fb59d1e1ae3dfb872b184ac91f10c473fUlrich Drepper    };
1377c911c9efe553d9af2d4fb0d420d8b614983e16acUlrich Drepper  bool has_dt[DT_NUM];
1378c911c9efe553d9af2d4fb0d420d8b614983e16acUlrich Drepper  static const bool level2[DT_NUM] =
1379c911c9efe553d9af2d4fb0d420d8b614983e16acUlrich Drepper    {
1380c911c9efe553d9af2d4fb0d420d8b614983e16acUlrich Drepper      [DT_RPATH] = true,
1381c911c9efe553d9af2d4fb0d420d8b614983e16acUlrich Drepper      [DT_SYMBOLIC] = true,
1382c911c9efe553d9af2d4fb0d420d8b614983e16acUlrich Drepper      [DT_TEXTREL] = true,
1383c911c9efe553d9af2d4fb0d420d8b614983e16acUlrich Drepper      [DT_BIND_NOW] = true
1384c911c9efe553d9af2d4fb0d420d8b614983e16acUlrich Drepper    };
1385c911c9efe553d9af2d4fb0d420d8b614983e16acUlrich Drepper  static const bool mandatory[DT_NUM] =
1386c911c9efe553d9af2d4fb0d420d8b614983e16acUlrich Drepper    {
1387c911c9efe553d9af2d4fb0d420d8b614983e16acUlrich Drepper      [DT_NULL] = true,
1388b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper      [DT_HASH] = true,
1389c911c9efe553d9af2d4fb0d420d8b614983e16acUlrich Drepper      [DT_STRTAB] = true,
1390c911c9efe553d9af2d4fb0d420d8b614983e16acUlrich Drepper      [DT_SYMTAB] = true,
1391c911c9efe553d9af2d4fb0d420d8b614983e16acUlrich Drepper      [DT_STRSZ] = true,
1392c911c9efe553d9af2d4fb0d420d8b614983e16acUlrich Drepper      [DT_SYMENT] = true
1393b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper    };
1394c911c9efe553d9af2d4fb0d420d8b614983e16acUlrich Drepper  GElf_Addr reladdr = 0;
1395c911c9efe553d9af2d4fb0d420d8b614983e16acUlrich Drepper  GElf_Word relsz = 0;
1396c911c9efe553d9af2d4fb0d420d8b614983e16acUlrich Drepper  GElf_Addr pltreladdr = 0;
1397c911c9efe553d9af2d4fb0d420d8b614983e16acUlrich Drepper  GElf_Word pltrelsz = 0;
1398c911c9efe553d9af2d4fb0d420d8b614983e16acUlrich Drepper
1399c911c9efe553d9af2d4fb0d420d8b614983e16acUlrich Drepper  memset (has_dt, '\0', sizeof (has_dt));
1400c911c9efe553d9af2d4fb0d420d8b614983e16acUlrich Drepper
1401c911c9efe553d9af2d4fb0d420d8b614983e16acUlrich Drepper  if (++ndynamic == 2)
1402b597dfad924980dede10d7c19d87900b6172e599Ulrich Drepper    ERROR (gettext ("more than one dynamic section present\n"));
1403b597dfad924980dede10d7c19d87900b6172e599Ulrich Drepper
1404c911c9efe553d9af2d4fb0d420d8b614983e16acUlrich Drepper  data = elf_getdata (elf_getscn (ebl->elf, idx), NULL);
1405b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper  if (data == NULL)
1406b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper    {
1407c911c9efe553d9af2d4fb0d420d8b614983e16acUlrich Drepper      ERROR (gettext ("section [%2d] '%s': cannot get section data\n"),
1408b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper	     idx, section_name (ebl, idx));
140941de488a0ad6679e816dbab960351e5f62ab8eadUlrich Drepper      return;
141041de488a0ad6679e816dbab960351e5f62ab8eadUlrich Drepper    }
141141de488a0ad6679e816dbab960351e5f62ab8eadUlrich Drepper
141241de488a0ad6679e816dbab960351e5f62ab8eadUlrich Drepper  strshdr = gelf_getshdr (elf_getscn (ebl->elf, shdr->sh_link), &strshdr_mem);
1413c911c9efe553d9af2d4fb0d420d8b614983e16acUlrich Drepper  if (strshdr != NULL && strshdr->sh_type != SHT_STRTAB)
141441de488a0ad6679e816dbab960351e5f62ab8eadUlrich Drepper    ERROR (gettext ("\
141541de488a0ad6679e816dbab960351e5f62ab8eadUlrich Dreppersection [%2d] '%s': referenced as string table for section [%2d] '%s' but type is not SHT_STRTAB\n"),
141641de488a0ad6679e816dbab960351e5f62ab8eadUlrich Drepper	   shdr->sh_link, section_name (ebl, shdr->sh_link),
141741de488a0ad6679e816dbab960351e5f62ab8eadUlrich Drepper	   idx, section_name (ebl, idx));
141841de488a0ad6679e816dbab960351e5f62ab8eadUlrich Drepper
141941de488a0ad6679e816dbab960351e5f62ab8eadUlrich Drepper  if (shdr->sh_entsize != gelf_fsize (ebl->elf, ELF_T_DYN, 1, EV_CURRENT))
142041de488a0ad6679e816dbab960351e5f62ab8eadUlrich Drepper    ERROR (gettext ("\
142141de488a0ad6679e816dbab960351e5f62ab8eadUlrich Dreppersection [%2d] '%s': section entry size does not match ElfXX_Dyn\n"),
142241de488a0ad6679e816dbab960351e5f62ab8eadUlrich Drepper	   idx, section_name (ebl, idx));
142341de488a0ad6679e816dbab960351e5f62ab8eadUlrich Drepper
142441de488a0ad6679e816dbab960351e5f62ab8eadUlrich Drepper  if (shdr->sh_info != 0)
1425038129b11ac71a13ccaf9029122be86d6c532990Ulrich Drepper    ERROR (gettext ("section [%2d] '%s': sh_info not zero\n"),
1426038129b11ac71a13ccaf9029122be86d6c532990Ulrich Drepper	   idx, section_name (ebl, idx));
142741de488a0ad6679e816dbab960351e5f62ab8eadUlrich Drepper
1428038129b11ac71a13ccaf9029122be86d6c532990Ulrich Drepper  bool non_null_warned = false;
1429038129b11ac71a13ccaf9029122be86d6c532990Ulrich Drepper  for (cnt = 0; cnt < shdr->sh_size / shdr->sh_entsize; ++cnt)
1430b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper    {
1431038129b11ac71a13ccaf9029122be86d6c532990Ulrich Drepper      GElf_Dyn dyn_mem;
1432038129b11ac71a13ccaf9029122be86d6c532990Ulrich Drepper      GElf_Dyn *dyn = gelf_getdyn (data, cnt, &dyn_mem);
143341de488a0ad6679e816dbab960351e5f62ab8eadUlrich Drepper      if (dyn == NULL)
1434038129b11ac71a13ccaf9029122be86d6c532990Ulrich Drepper	{
1435038129b11ac71a13ccaf9029122be86d6c532990Ulrich Drepper	  ERROR (gettext ("\
1436038129b11ac71a13ccaf9029122be86d6c532990Ulrich Dreppersection [%2d] '%s': cannot get dynamic section entry %zu: %s\n"),
1437038129b11ac71a13ccaf9029122be86d6c532990Ulrich Drepper		 idx, section_name (ebl, idx), cnt, elf_errmsg (-1));
1438038129b11ac71a13ccaf9029122be86d6c532990Ulrich Drepper	  continue;
1439038129b11ac71a13ccaf9029122be86d6c532990Ulrich Drepper	}
1440038129b11ac71a13ccaf9029122be86d6c532990Ulrich Drepper
1441038129b11ac71a13ccaf9029122be86d6c532990Ulrich Drepper      if (has_dt[DT_NULL] && dyn->d_tag != DT_NULL && ! non_null_warned)
1442038129b11ac71a13ccaf9029122be86d6c532990Ulrich Drepper	{
1443038129b11ac71a13ccaf9029122be86d6c532990Ulrich Drepper	  ERROR (gettext ("\
1444038129b11ac71a13ccaf9029122be86d6c532990Ulrich Dreppersection [%2d] '%s': non-DT_NULL entries follow DT_NULL entry\n"),
144541de488a0ad6679e816dbab960351e5f62ab8eadUlrich Drepper		 idx, section_name (ebl, idx));
144641de488a0ad6679e816dbab960351e5f62ab8eadUlrich Drepper	  non_null_warned = true;
1447038129b11ac71a13ccaf9029122be86d6c532990Ulrich Drepper	}
1448b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper
144941de488a0ad6679e816dbab960351e5f62ab8eadUlrich Drepper      if (!ebl_dynamic_tag_check (ebl, dyn->d_tag))
1450038129b11ac71a13ccaf9029122be86d6c532990Ulrich Drepper	ERROR (gettext ("section [%2d] '%s': entry %zu: unknown tag\n"),
1451038129b11ac71a13ccaf9029122be86d6c532990Ulrich Drepper	       idx, section_name (ebl, idx), cnt);
1452038129b11ac71a13ccaf9029122be86d6c532990Ulrich Drepper
1453038129b11ac71a13ccaf9029122be86d6c532990Ulrich Drepper      if (dyn->d_tag >= 0 && dyn->d_tag < DT_NUM)
1454038129b11ac71a13ccaf9029122be86d6c532990Ulrich Drepper	{
1455038129b11ac71a13ccaf9029122be86d6c532990Ulrich Drepper	  if (has_dt[dyn->d_tag]
145641de488a0ad6679e816dbab960351e5f62ab8eadUlrich Drepper	      && dyn->d_tag != DT_NEEDED
1457038129b11ac71a13ccaf9029122be86d6c532990Ulrich Drepper	      && dyn->d_tag != DT_NULL
1458038129b11ac71a13ccaf9029122be86d6c532990Ulrich Drepper	      && dyn->d_tag != DT_POSFLAG_1)
1459038129b11ac71a13ccaf9029122be86d6c532990Ulrich Drepper	    {
1460b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper	      char buf[50];
1461b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper	      ERROR (gettext ("\
1462b08d5a8fb42f4586d756068065186b5af7e48daUlrich Dreppersection [%2d] '%s': entry %zu: more than one entry with tag %s\n"),
1463b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper		     idx, section_name (ebl, idx), cnt,
1464b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper		     ebl_dynamic_tag_name (ebl, dyn->d_tag,
1465c911c9efe553d9af2d4fb0d420d8b614983e16acUlrich Drepper					   buf, sizeof (buf)));
1466b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper	    }
1467c911c9efe553d9af2d4fb0d420d8b614983e16acUlrich Drepper
1468b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper	  if (be_strict && level2[dyn->d_tag])
1469b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper	    {
1470b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper	      char buf[50];
1471b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper	      ERROR (gettext ("\
1472b08d5a8fb42f4586d756068065186b5af7e48daUlrich Dreppersection [%2d] '%s': entry %zu: level 2 tag %s used\n"),
1473b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper		     idx, section_name (ebl, idx), cnt,
1474b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper		     ebl_dynamic_tag_name (ebl, dyn->d_tag,
1475c911c9efe553d9af2d4fb0d420d8b614983e16acUlrich Drepper					   buf, sizeof (buf)));
1476c911c9efe553d9af2d4fb0d420d8b614983e16acUlrich Drepper	    }
1477c911c9efe553d9af2d4fb0d420d8b614983e16acUlrich Drepper
147841de488a0ad6679e816dbab960351e5f62ab8eadUlrich Drepper	  has_dt[dyn->d_tag] = true;
1479c911c9efe553d9af2d4fb0d420d8b614983e16acUlrich Drepper	}
148041de488a0ad6679e816dbab960351e5f62ab8eadUlrich Drepper
1481c911c9efe553d9af2d4fb0d420d8b614983e16acUlrich Drepper      if (dyn->d_tag == DT_PLTREL && dyn->d_un.d_val != DT_REL
1482c911c9efe553d9af2d4fb0d420d8b614983e16acUlrich Drepper	  && dyn->d_un.d_val != DT_RELA)
1483c911c9efe553d9af2d4fb0d420d8b614983e16acUlrich Drepper	ERROR (gettext ("\
1484c911c9efe553d9af2d4fb0d420d8b614983e16acUlrich Dreppersection [%2d] '%s': entry %zu: DT_PLTREL value must be DT_REL or DT_RELA\n"),
1485c911c9efe553d9af2d4fb0d420d8b614983e16acUlrich Drepper	       idx, section_name (ebl, idx), cnt);
148641de488a0ad6679e816dbab960351e5f62ab8eadUlrich Drepper
1487c911c9efe553d9af2d4fb0d420d8b614983e16acUlrich Drepper      if (dyn->d_tag == DT_REL)
148871c1534c9c7a0652fb6c5f9295baa08f32b0b166Jakub Jelinek	reladdr = dyn->d_un.d_ptr;
148971c1534c9c7a0652fb6c5f9295baa08f32b0b166Jakub Jelinek      if (dyn->d_tag == DT_RELSZ)
1490b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper	relsz = dyn->d_un.d_val;
1491c911c9efe553d9af2d4fb0d420d8b614983e16acUlrich Drepper      if (dyn->d_tag == DT_JMPREL)
1492c911c9efe553d9af2d4fb0d420d8b614983e16acUlrich Drepper	pltreladdr = dyn->d_un.d_ptr;
1493c911c9efe553d9af2d4fb0d420d8b614983e16acUlrich Drepper      if (dyn->d_tag == DT_PLTRELSZ)
1494b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper	pltrelsz = dyn->d_un.d_val;
1495c911c9efe553d9af2d4fb0d420d8b614983e16acUlrich Drepper
1496c911c9efe553d9af2d4fb0d420d8b614983e16acUlrich Drepper      /* Check that addresses for entries are in loaded segments.  */
1497c911c9efe553d9af2d4fb0d420d8b614983e16acUlrich Drepper      switch (dyn->d_tag)
1498c911c9efe553d9af2d4fb0d420d8b614983e16acUlrich Drepper	{
1499b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper	  size_t n;
1500c911c9efe553d9af2d4fb0d420d8b614983e16acUlrich Drepper	default:
1501607e05466d3fef5e3ad90aa200d3bba1950cf982Ulrich Drepper	  if (dyn->d_tag < DT_ADDRRNGLO || dyn->d_tag > DT_ADDRRNGHI)
1502607e05466d3fef5e3ad90aa200d3bba1950cf982Ulrich Drepper	    /* Value is no pointer.  */
1503607e05466d3fef5e3ad90aa200d3bba1950cf982Ulrich Drepper	    break;
150441de488a0ad6679e816dbab960351e5f62ab8eadUlrich Drepper	  /* FALLTHROUGH */
150541de488a0ad6679e816dbab960351e5f62ab8eadUlrich Drepper
150641de488a0ad6679e816dbab960351e5f62ab8eadUlrich Drepper	case DT_PLTGOT:
150741de488a0ad6679e816dbab960351e5f62ab8eadUlrich Drepper	case DT_HASH:
150841de488a0ad6679e816dbab960351e5f62ab8eadUlrich Drepper	case DT_STRTAB:
150941de488a0ad6679e816dbab960351e5f62ab8eadUlrich Drepper	case DT_SYMTAB:
151041de488a0ad6679e816dbab960351e5f62ab8eadUlrich Drepper	case DT_RELA:
1511b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper	case DT_INIT:
1512c911c9efe553d9af2d4fb0d420d8b614983e16acUlrich Drepper	case DT_FINI:
1513b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper	case DT_SONAME:
1514c911c9efe553d9af2d4fb0d420d8b614983e16acUlrich Drepper	case DT_RPATH:
1515c911c9efe553d9af2d4fb0d420d8b614983e16acUlrich Drepper	case DT_SYMBOLIC:
1516c911c9efe553d9af2d4fb0d420d8b614983e16acUlrich Drepper	case DT_REL:
1517c911c9efe553d9af2d4fb0d420d8b614983e16acUlrich Drepper	case DT_JMPREL:
1518c911c9efe553d9af2d4fb0d420d8b614983e16acUlrich Drepper	case DT_INIT_ARRAY:
1519c911c9efe553d9af2d4fb0d420d8b614983e16acUlrich Drepper	case DT_FINI_ARRAY:
1520c911c9efe553d9af2d4fb0d420d8b614983e16acUlrich Drepper	case DT_RUNPATH:
1521c911c9efe553d9af2d4fb0d420d8b614983e16acUlrich Drepper	case DT_VERSYM:
1522c911c9efe553d9af2d4fb0d420d8b614983e16acUlrich Drepper	case DT_VERDEF:
1523c911c9efe553d9af2d4fb0d420d8b614983e16acUlrich Drepper	case DT_VERNEED:
1524c911c9efe553d9af2d4fb0d420d8b614983e16acUlrich Drepper	case DT_AUXILIARY:
1525c911c9efe553d9af2d4fb0d420d8b614983e16acUlrich Drepper	case DT_FILTER:
1526c911c9efe553d9af2d4fb0d420d8b614983e16acUlrich Drepper	  for (n = 0; n < ehdr->e_phnum; ++n)
1527c911c9efe553d9af2d4fb0d420d8b614983e16acUlrich Drepper	    {
1528c911c9efe553d9af2d4fb0d420d8b614983e16acUlrich Drepper	      GElf_Phdr phdr_mem;
152941de488a0ad6679e816dbab960351e5f62ab8eadUlrich Drepper	      GElf_Phdr *phdr = gelf_getphdr (ebl->elf, n, &phdr_mem);
1530c911c9efe553d9af2d4fb0d420d8b614983e16acUlrich Drepper	      if (phdr != NULL && phdr->p_type == PT_LOAD
153141de488a0ad6679e816dbab960351e5f62ab8eadUlrich Drepper		  && phdr->p_vaddr <= dyn->d_un.d_ptr
1532b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper		  && phdr->p_vaddr + phdr->p_memsz > dyn->d_un.d_ptr)
1533b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper		break;
1534b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper	    }
1535b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper	  if (unlikely (n >= ehdr->e_phnum))
1536b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper	    {
153741de488a0ad6679e816dbab960351e5f62ab8eadUlrich Drepper	      char buf[50];
1538b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper	      ERROR (gettext ("\
153971c1534c9c7a0652fb6c5f9295baa08f32b0b166Jakub Jelineksection [%2d] '%s': entry %zu: %s value must point into loaded segment\n"),
154071c1534c9c7a0652fb6c5f9295baa08f32b0b166Jakub Jelinek		     idx, section_name (ebl, idx), cnt,
1541b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper		     ebl_dynamic_tag_name (ebl, dyn->d_tag, buf,
1542b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper					   sizeof (buf)));
1543c911c9efe553d9af2d4fb0d420d8b614983e16acUlrich Drepper	    }
1544b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper	}
1545b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper    }
1546b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper
1547b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper  for (cnt = 1; cnt < DT_NUM; ++cnt)
1548b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper    if (has_dt[cnt])
1549b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper      {
1550b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper	for (int inner = 0; inner < DT_NUM; ++inner)
1551b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper	  if (dependencies[cnt][inner] && ! has_dt[inner])
1552607e05466d3fef5e3ad90aa200d3bba1950cf982Ulrich Drepper	    {
1553607e05466d3fef5e3ad90aa200d3bba1950cf982Ulrich Drepper	      char buf1[50];
1554607e05466d3fef5e3ad90aa200d3bba1950cf982Ulrich Drepper	      char buf2[50];
155541de488a0ad6679e816dbab960351e5f62ab8eadUlrich Drepper
155641de488a0ad6679e816dbab960351e5f62ab8eadUlrich Drepper	      ERROR (gettext ("\
155741de488a0ad6679e816dbab960351e5f62ab8eadUlrich Dreppersection [%2d] '%s': contains %s entry but not %s\n"),
155841de488a0ad6679e816dbab960351e5f62ab8eadUlrich Drepper		     idx, section_name (ebl, idx),
155941de488a0ad6679e816dbab960351e5f62ab8eadUlrich Drepper		     ebl_dynamic_tag_name (ebl, cnt, buf1, sizeof (buf1)),
156041de488a0ad6679e816dbab960351e5f62ab8eadUlrich Drepper		     ebl_dynamic_tag_name (ebl, inner, buf2, sizeof (buf2)));
156141de488a0ad6679e816dbab960351e5f62ab8eadUlrich Drepper	    }
1562b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper      }
1563b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper    else
1564b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper      {
1565b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper	if (mandatory[cnt])
1566b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper	  {
1567b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper	    char buf[50];
1568b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper	    ERROR (gettext ("\
1569b08d5a8fb42f4586d756068065186b5af7e48daUlrich Dreppersection [%2d] '%s': mandatory tag %s not present\n"),
1570b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper		   idx, section_name (ebl, idx),
1571607e05466d3fef5e3ad90aa200d3bba1950cf982Ulrich Drepper		   ebl_dynamic_tag_name (ebl, cnt, buf, sizeof (buf)));
1572b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper	  }
1573b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper      }
1574b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper
1575b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper  /* Check the rel/rela tags.  At least one group must be available.  */
1576b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper  if ((has_dt[DT_RELA] || has_dt[DT_RELASZ] || has_dt[DT_RELAENT])
1577b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper      && (!has_dt[DT_RELA] || !has_dt[DT_RELASZ] || !has_dt[DT_RELAENT]))
1578b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper    ERROR (gettext ("\
1579b08d5a8fb42f4586d756068065186b5af7e48daUlrich Dreppersection [%2d] '%s': not all of %s, %s, and %s are present\n"),
1580b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper	   idx, section_name (ebl, idx),
1581b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper	   "DT_RELA", "DT_RELASZ", "DT_RELAENT");
1582b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper
1583231c590fbe9d6f3a8e22796ded9c6a378628eb09Ulrich Drepper  if ((has_dt[DT_REL] || has_dt[DT_RELSZ] || has_dt[DT_RELENT])
1584b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper      && (!has_dt[DT_REL] || !has_dt[DT_RELSZ] || !has_dt[DT_RELENT]))
1585b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper    ERROR (gettext ("\
1586b08d5a8fb42f4586d756068065186b5af7e48daUlrich Dreppersection [%2d] '%s': not all of %s, %s, and %s are present\n"),
1587b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper	   idx, section_name (ebl, idx),
1588b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper	   "DT_REL", "DT_RELSZ", "DT_RELENT");
1589b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper}
1590b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper
1591b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper
1592b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepperstatic void
1593b08d5a8fb42f4586d756068065186b5af7e48daUlrich Dreppercheck_symtab_shndx (Ebl *ebl, GElf_Ehdr *ehdr, GElf_Shdr *shdr, int idx)
1594b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper{
1595b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper  if (ehdr->e_type != ET_REL)
1596b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper    {
1597b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper      ERROR (gettext ("\
1598b08d5a8fb42f4586d756068065186b5af7e48daUlrich Dreppersection [%2d] '%s': only relocatable files can have extended section index\n"),
1599231c590fbe9d6f3a8e22796ded9c6a378628eb09Ulrich Drepper	     idx, section_name (ebl, idx));
1600231c590fbe9d6f3a8e22796ded9c6a378628eb09Ulrich Drepper      return;
1601b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper    }
1602b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper
1603b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper  Elf_Scn *symscn = elf_getscn (ebl->elf, shdr->sh_link);
1604b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper  GElf_Shdr symshdr_mem;
1605b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper  GElf_Shdr *symshdr = gelf_getshdr (symscn, &symshdr_mem);
1606b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper  if (symshdr != NULL && symshdr->sh_type != SHT_SYMTAB)
1607b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper    ERROR (gettext ("\
1608b08d5a8fb42f4586d756068065186b5af7e48daUlrich Dreppersection [%2d] '%s': extended section index section not for symbol table\n"),
1609b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper	   idx, section_name (ebl, idx));
1610b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper  Elf_Data *symdata = elf_getdata (symscn, NULL);
1611b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper  if (symdata == NULL)
1612b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper    ERROR (gettext ("cannot get data for symbol section\n"));
1613b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper
1614b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper  if (shdr->sh_entsize != sizeof (Elf32_Word))
1615b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper    ERROR (gettext ("\
1616b08d5a8fb42f4586d756068065186b5af7e48daUlrich Dreppersection [%2d] '%s': entry size does not match Elf32_Word\n"),
1617b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper	   idx, section_name (ebl, idx));
1618231c590fbe9d6f3a8e22796ded9c6a378628eb09Ulrich Drepper
1619231c590fbe9d6f3a8e22796ded9c6a378628eb09Ulrich Drepper  if (symshdr != NULL
1620b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper      && (shdr->sh_size / shdr->sh_entsize
1621b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper	  < symshdr->sh_size / symshdr->sh_entsize))
1622b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper    ERROR (gettext ("\
1623b08d5a8fb42f4586d756068065186b5af7e48daUlrich Dreppersection [%2d] '%s': extended index table too small for symbol table\n"),
162441de488a0ad6679e816dbab960351e5f62ab8eadUlrich Drepper	   idx, section_name (ebl, idx));
1625b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper
1626b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper  if (shdr->sh_info != 0)
1627b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper    ERROR (gettext ("section [%2d] '%s': sh_info not zero\n"),
1628b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper	   idx, section_name (ebl, idx));
1629b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper
1630b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper  for (size_t cnt = idx + 1; cnt < shnum; ++cnt)
1631b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper    {
1632b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper      GElf_Shdr rshdr_mem;
1633b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper      GElf_Shdr *rshdr = gelf_getshdr (elf_getscn (ebl->elf, cnt), &rshdr_mem);
1634b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper      if (rshdr != NULL && rshdr->sh_type == SHT_SYMTAB_SHNDX
1635b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper	  && rshdr->sh_link == shdr->sh_link)
1636b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper	{
1637b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper	  ERROR (gettext ("\
16380a545e678f2c0605ba050b4f72080572ac7c8470Mark Wielaardsection [%2d] '%s': extended section index in section [%2zu] '%s' refers to same symbol table\n"),
16390a545e678f2c0605ba050b4f72080572ac7c8470Mark Wielaard		 idx, section_name (ebl, idx),
16400a545e678f2c0605ba050b4f72080572ac7c8470Mark Wielaard		 cnt, section_name (ebl, cnt));
16410a545e678f2c0605ba050b4f72080572ac7c8470Mark Wielaard	  break;
16420a545e678f2c0605ba050b4f72080572ac7c8470Mark Wielaard	}
16430a545e678f2c0605ba050b4f72080572ac7c8470Mark Wielaard    }
16440a545e678f2c0605ba050b4f72080572ac7c8470Mark Wielaard
1645b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper  Elf_Data *data = elf_getdata (elf_getscn (ebl->elf, idx), NULL);
164671c1534c9c7a0652fb6c5f9295baa08f32b0b166Jakub Jelinek
164771c1534c9c7a0652fb6c5f9295baa08f32b0b166Jakub Jelinek  if (*((Elf32_Word *) data->d_buf) != 0)
1648b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper    ERROR (gettext ("symbol 0 should have zero extended section index\n"));
1649b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper
1650b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper  for (size_t cnt = 1; cnt < data->d_size / sizeof (Elf32_Word); ++cnt)
1651b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper    {
1652b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper      Elf32_Word xndx = ((Elf32_Word *) data->d_buf)[cnt];
1653b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper
1654b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper      if (xndx != 0)
1655b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper	{
1656b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper	  GElf_Sym sym_data;
165771c1534c9c7a0652fb6c5f9295baa08f32b0b166Jakub Jelinek	  GElf_Sym *sym = gelf_getsym (symdata, cnt, &sym_data);
1658b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper	  if (sym == NULL)
1659b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper	    {
1660acb8983909a3f031041ee5d7cbe09fbeb3c31b9aUlrich Drepper	      ERROR (gettext ("cannot get data for symbol %zu\n"), cnt);
1661b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper	      continue;
1662b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper	    }
1663b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper
1664b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper	  if (sym->st_shndx != SHN_XINDEX)
1665b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper	    ERROR (gettext ("\
1666b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepperextended section index is %" PRIu32 " but symbol index is not XINDEX\n"),
1667b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper		   (uint32_t) xndx);
1668b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper	}
1669b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper    }
1670b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper}
1671b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper
1672b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper
1673b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepperstatic void
1674b08d5a8fb42f4586d756068065186b5af7e48daUlrich Dreppercheck_hash (Ebl *ebl, GElf_Ehdr *ehdr, GElf_Shdr *shdr, int idx)
1675b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper{
1676b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper  if (ehdr->e_type == ET_REL)
1677b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper    {
1678b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper      ERROR (gettext ("\
1679b08d5a8fb42f4586d756068065186b5af7e48daUlrich Dreppersection [%2d] '%s': relocatable files cannot have hash tables\n"),
1680b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper	     idx, section_name (ebl, idx));
1681b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper      return;
1682b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper    }
1683b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper
1684b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper  Elf_Data *data = elf_getdata (elf_getscn (ebl->elf, idx), NULL);
1685b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper  if (data == NULL)
1686b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper    {
1687b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper      ERROR (gettext ("section [%2d] '%s': cannot get section data\n"),
1688b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper	     idx, section_name (ebl, idx));
1689b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper      return;
1690b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper    }
1691b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper
1692b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper  GElf_Shdr symshdr_mem;
1693b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper  GElf_Shdr *symshdr = gelf_getshdr (elf_getscn (ebl->elf, shdr->sh_link),
1694b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper				     &symshdr_mem);
1695b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper  if (symshdr != NULL && symshdr->sh_type != SHT_DYNSYM)
1696b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper    ERROR (gettext ("\
1697b08d5a8fb42f4586d756068065186b5af7e48daUlrich Dreppersection [%2d] '%s': hash table not for dynamic symbol table\n"),
1698b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper	   idx, section_name (ebl, idx));
1699b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper
1700b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper  if (shdr->sh_entsize != sizeof (Elf32_Word))
1701b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper    ERROR (gettext ("\
1702b08d5a8fb42f4586d756068065186b5af7e48daUlrich Dreppersection [%2d] '%s': entry size does not match Elf32_Word\n"),
1703b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper	   idx, section_name (ebl, idx));
1704b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper
1705b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper  if ((shdr->sh_flags & SHF_ALLOC) == 0)
1706b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper    ERROR (gettext ("section [%2d] '%s': not marked to be allocated\n"),
1707b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper	   idx, section_name (ebl, idx));
17080a545e678f2c0605ba050b4f72080572ac7c8470Mark Wielaard
1709231c590fbe9d6f3a8e22796ded9c6a378628eb09Ulrich Drepper  if (shdr->sh_size < 2 * shdr->sh_entsize)
1710231c590fbe9d6f3a8e22796ded9c6a378628eb09Ulrich Drepper    {
17110a545e678f2c0605ba050b4f72080572ac7c8470Mark Wielaard      ERROR (gettext ("\
1712231c590fbe9d6f3a8e22796ded9c6a378628eb09Ulrich Dreppersection [%2d] '%s': hash table has not even room for nbucket and nchain\n"),
1713231c590fbe9d6f3a8e22796ded9c6a378628eb09Ulrich Drepper	     idx, section_name (ebl, idx));
1714b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper      return;
1715b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper    }
1716b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper
1717b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper  Elf32_Word nbucket = ((Elf32_Word *) data->d_buf)[0];
1718b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper  Elf32_Word nchain = ((Elf32_Word *) data->d_buf)[1];
1719b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper
1720b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper  if (shdr->sh_size < (2 + nbucket + nchain) * shdr->sh_entsize)
1721607e05466d3fef5e3ad90aa200d3bba1950cf982Ulrich Drepper    ERROR (gettext ("\
1722607e05466d3fef5e3ad90aa200d3bba1950cf982Ulrich Dreppersection [%2d] '%s': hash table section is too small (is %ld, expected %ld)\n"),
1723607e05466d3fef5e3ad90aa200d3bba1950cf982Ulrich Drepper	   idx, section_name (ebl, idx), (long int) shdr->sh_size,
1724607e05466d3fef5e3ad90aa200d3bba1950cf982Ulrich Drepper	   (long int) ((2 + nbucket + nchain) * shdr->sh_entsize));
1725cbb51e5253e05d98af8bdaf2217fed00b2e489b9Ulrich Drepper
1726cbb51e5253e05d98af8bdaf2217fed00b2e489b9Ulrich Drepper  if (symshdr != NULL)
1727cbb51e5253e05d98af8bdaf2217fed00b2e489b9Ulrich Drepper    {
1728cbb51e5253e05d98af8bdaf2217fed00b2e489b9Ulrich Drepper      size_t symsize = symshdr->sh_size / symshdr->sh_entsize;
1729cbb51e5253e05d98af8bdaf2217fed00b2e489b9Ulrich Drepper      size_t cnt;
1730cbb51e5253e05d98af8bdaf2217fed00b2e489b9Ulrich Drepper
1731cbb51e5253e05d98af8bdaf2217fed00b2e489b9Ulrich Drepper      if (nchain < symshdr->sh_size / symshdr->sh_entsize)
1732cbb51e5253e05d98af8bdaf2217fed00b2e489b9Ulrich Drepper	ERROR (gettext ("section [%2d] '%s': chain array not large enough\n"),
1733cbb51e5253e05d98af8bdaf2217fed00b2e489b9Ulrich Drepper	       idx, section_name (ebl, idx));
1734cbb51e5253e05d98af8bdaf2217fed00b2e489b9Ulrich Drepper
1735cbb51e5253e05d98af8bdaf2217fed00b2e489b9Ulrich Drepper      for (cnt = 2; cnt < 2 + nbucket; ++cnt)
1736cbb51e5253e05d98af8bdaf2217fed00b2e489b9Ulrich Drepper	if (((Elf32_Word *) data->d_buf)[cnt] >= symsize)
1737cbb51e5253e05d98af8bdaf2217fed00b2e489b9Ulrich Drepper	  ERROR (gettext ("\
1738607e05466d3fef5e3ad90aa200d3bba1950cf982Ulrich Dreppersection [%2d] '%s': hash bucket reference %zu out of bounds\n"),
1739607e05466d3fef5e3ad90aa200d3bba1950cf982Ulrich Drepper		 idx, section_name (ebl, idx), cnt - 2);
1740607e05466d3fef5e3ad90aa200d3bba1950cf982Ulrich Drepper
1741607e05466d3fef5e3ad90aa200d3bba1950cf982Ulrich Drepper      for (; cnt < 2 + nbucket + nchain; ++cnt)
1742607e05466d3fef5e3ad90aa200d3bba1950cf982Ulrich Drepper	if (((Elf32_Word *) data->d_buf)[cnt] >= symsize)
1743607e05466d3fef5e3ad90aa200d3bba1950cf982Ulrich Drepper	  ERROR (gettext ("\
1744cbb51e5253e05d98af8bdaf2217fed00b2e489b9Ulrich Dreppersection [%2d] '%s': hash chain reference %zu out of bounds\n"),
1745cbb51e5253e05d98af8bdaf2217fed00b2e489b9Ulrich Drepper		 idx, section_name (ebl, idx), cnt - 2 - nbucket);
1746cbb51e5253e05d98af8bdaf2217fed00b2e489b9Ulrich Drepper    }
1747cbb51e5253e05d98af8bdaf2217fed00b2e489b9Ulrich Drepper}
1748607e05466d3fef5e3ad90aa200d3bba1950cf982Ulrich Drepper
1749607e05466d3fef5e3ad90aa200d3bba1950cf982Ulrich Drepper
1750607e05466d3fef5e3ad90aa200d3bba1950cf982Ulrich Drepperstatic void
1751cbb51e5253e05d98af8bdaf2217fed00b2e489b9Ulrich Dreppercheck_null (Ebl *ebl, GElf_Shdr *shdr, int idx)
1752cbb51e5253e05d98af8bdaf2217fed00b2e489b9Ulrich Drepper{
1753cbb51e5253e05d98af8bdaf2217fed00b2e489b9Ulrich Drepper#define TEST(name, extra) \
1754cbb51e5253e05d98af8bdaf2217fed00b2e489b9Ulrich Drepper  if (extra && shdr->sh_##name != 0)					      \
1755cbb51e5253e05d98af8bdaf2217fed00b2e489b9Ulrich Drepper    ERROR (gettext ("section [%2d] '%s': nonzero sh_%s for NULL section\n"),  \
1756cbb51e5253e05d98af8bdaf2217fed00b2e489b9Ulrich Drepper	   idx, section_name (ebl, idx), #name)
1757607e05466d3fef5e3ad90aa200d3bba1950cf982Ulrich Drepper
1758607e05466d3fef5e3ad90aa200d3bba1950cf982Ulrich Drepper  TEST (name, 1);
1759cbb51e5253e05d98af8bdaf2217fed00b2e489b9Ulrich Drepper  TEST (flags, 1);
1760cbb51e5253e05d98af8bdaf2217fed00b2e489b9Ulrich Drepper  TEST (addr, 1);
1761bd733cae5159e3a3c4c05f7685559fa3ae8b58c6Roland McGrath  TEST (offset, 1);
1762607e05466d3fef5e3ad90aa200d3bba1950cf982Ulrich Drepper  TEST (size, idx != 0);
1763607e05466d3fef5e3ad90aa200d3bba1950cf982Ulrich Drepper  TEST (link, idx != 0);
1764607e05466d3fef5e3ad90aa200d3bba1950cf982Ulrich Drepper  TEST (info, 1);
1765607e05466d3fef5e3ad90aa200d3bba1950cf982Ulrich Drepper  TEST (addralign, 1);
1766607e05466d3fef5e3ad90aa200d3bba1950cf982Ulrich Drepper  TEST (entsize, 1);
1767607e05466d3fef5e3ad90aa200d3bba1950cf982Ulrich Drepper}
1768607e05466d3fef5e3ad90aa200d3bba1950cf982Ulrich Drepper
1769607e05466d3fef5e3ad90aa200d3bba1950cf982Ulrich Drepper
1770bd733cae5159e3a3c4c05f7685559fa3ae8b58c6Roland McGrathstatic void
1771607e05466d3fef5e3ad90aa200d3bba1950cf982Ulrich Dreppercheck_group (Ebl *ebl, GElf_Ehdr *ehdr, GElf_Shdr *shdr, int idx)
1772607e05466d3fef5e3ad90aa200d3bba1950cf982Ulrich Drepper{
1773607e05466d3fef5e3ad90aa200d3bba1950cf982Ulrich Drepper  if (ehdr->e_type != ET_REL)
1774607e05466d3fef5e3ad90aa200d3bba1950cf982Ulrich Drepper    {
1775607e05466d3fef5e3ad90aa200d3bba1950cf982Ulrich Drepper      ERROR (gettext ("\
1776607e05466d3fef5e3ad90aa200d3bba1950cf982Ulrich Dreppersection [%2d] '%s': section groups only allowed in relocatable object files\n"),
1777607e05466d3fef5e3ad90aa200d3bba1950cf982Ulrich Drepper	     idx, section_name (ebl, idx));
1778607e05466d3fef5e3ad90aa200d3bba1950cf982Ulrich Drepper      return;
1779cbb51e5253e05d98af8bdaf2217fed00b2e489b9Ulrich Drepper    }
1780cbb51e5253e05d98af8bdaf2217fed00b2e489b9Ulrich Drepper
1781cbb51e5253e05d98af8bdaf2217fed00b2e489b9Ulrich Drepper  /* Check that sh_link is an index of a symbol table.  */
1782cbb51e5253e05d98af8bdaf2217fed00b2e489b9Ulrich Drepper  GElf_Shdr symshdr_mem;
1783cbb51e5253e05d98af8bdaf2217fed00b2e489b9Ulrich Drepper  GElf_Shdr *symshdr = gelf_getshdr (elf_getscn (ebl->elf, shdr->sh_link),
1784cbb51e5253e05d98af8bdaf2217fed00b2e489b9Ulrich Drepper				     &symshdr_mem);
1785cbb51e5253e05d98af8bdaf2217fed00b2e489b9Ulrich Drepper  if (symshdr == NULL)
1786cbb51e5253e05d98af8bdaf2217fed00b2e489b9Ulrich Drepper    ERROR (gettext ("section [%2d] '%s': cannot get symbol table: %s\n"),
1787cbb51e5253e05d98af8bdaf2217fed00b2e489b9Ulrich Drepper	   idx, section_name (ebl, idx), elf_errmsg (-1));
1788cbb51e5253e05d98af8bdaf2217fed00b2e489b9Ulrich Drepper  else
1789cbb51e5253e05d98af8bdaf2217fed00b2e489b9Ulrich Drepper    {
1790cbb51e5253e05d98af8bdaf2217fed00b2e489b9Ulrich Drepper      if (symshdr->sh_type != SHT_SYMTAB)
1791cbb51e5253e05d98af8bdaf2217fed00b2e489b9Ulrich Drepper	ERROR (gettext ("\
1792cbb51e5253e05d98af8bdaf2217fed00b2e489b9Ulrich Dreppersection [%2d] '%s': section reference in sh_link is no symbol table\n"),
1793cbb51e5253e05d98af8bdaf2217fed00b2e489b9Ulrich Drepper	       idx, section_name (ebl, idx));
1794cbb51e5253e05d98af8bdaf2217fed00b2e489b9Ulrich Drepper
1795cbb51e5253e05d98af8bdaf2217fed00b2e489b9Ulrich Drepper      if (shdr->sh_info >= symshdr->sh_size / gelf_fsize (ebl->elf, ELF_T_SYM,
1796607e05466d3fef5e3ad90aa200d3bba1950cf982Ulrich Drepper							  1, EV_CURRENT))
1797b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper	ERROR (gettext ("\
1798b08d5a8fb42f4586d756068065186b5af7e48daUlrich Dreppersection [%2d] '%s': invalid symbol index in sh_info\n"),
1799b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper	       idx, section_name (ebl, idx));
1800b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper
1801b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper      if (shdr->sh_flags != 0)
1802acb8983909a3f031041ee5d7cbe09fbeb3c31b9aUlrich Drepper	ERROR (gettext ("section [%2d] '%s': sh_flags not zero\n"),
1803b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper	       idx, section_name (ebl, idx));
1804b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper
1805b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper      if (be_strict
1806b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper	  && shdr->sh_entsize != elf32_fsize (ELF_T_WORD, 1, EV_CURRENT))
1807b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper	ERROR (gettext ("section [%2d] '%s': sh_flags not set correctly\n"),
1808b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper	       idx, section_name (ebl, idx));
1809b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper    }
1810b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper
1811b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper  Elf_Data *data = elf_getdata (elf_getscn (ebl->elf, idx), NULL);
1812b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper  if (data == NULL)
1813b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper    ERROR (gettext ("section [%2d] '%s': cannot get data: %s\n"),
1814b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper	   idx, section_name (ebl, idx), elf_errmsg (-1));
1815b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper  else
1816b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper    {
1817b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper      size_t elsize = elf32_fsize (ELF_T_WORD, 1, EV_CURRENT);
1818b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper      size_t cnt;
1819b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper      Elf32_Word val;
1820b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper
1821b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper      if (data->d_size % elsize != 0)
1822b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper	ERROR (gettext ("\
1823b08d5a8fb42f4586d756068065186b5af7e48daUlrich Dreppersection [%2d] '%s': section size not multiple of sizeof(Elf32_Word)\n"),
1824b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper	       idx, section_name (ebl, idx));
1825b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper
1826b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper      if (data->d_size < elsize)
1827231c590fbe9d6f3a8e22796ded9c6a378628eb09Ulrich Drepper	ERROR (gettext ("\
1828231c590fbe9d6f3a8e22796ded9c6a378628eb09Ulrich Dreppersection [%2d] '%s': section group without flags word\n"),
1829231c590fbe9d6f3a8e22796ded9c6a378628eb09Ulrich Drepper	       idx, section_name (ebl, idx));
1830231c590fbe9d6f3a8e22796ded9c6a378628eb09Ulrich Drepper      else if (be_strict)
1831231c590fbe9d6f3a8e22796ded9c6a378628eb09Ulrich Drepper	{
1832231c590fbe9d6f3a8e22796ded9c6a378628eb09Ulrich Drepper	  if (data->d_size < 2 * elsize)
1833231c590fbe9d6f3a8e22796ded9c6a378628eb09Ulrich Drepper	    ERROR (gettext ("\
1834231c590fbe9d6f3a8e22796ded9c6a378628eb09Ulrich Dreppersection [%2d] '%s': section group without member\n"),
1835231c590fbe9d6f3a8e22796ded9c6a378628eb09Ulrich Drepper		   idx, section_name (ebl, idx));
1836231c590fbe9d6f3a8e22796ded9c6a378628eb09Ulrich Drepper	  else if (data->d_size < 3 * elsize)
1837231c590fbe9d6f3a8e22796ded9c6a378628eb09Ulrich Drepper	    ERROR (gettext ("\
1838231c590fbe9d6f3a8e22796ded9c6a378628eb09Ulrich Dreppersection [%2d] '%s': section group with only one member\n"),
1839231c590fbe9d6f3a8e22796ded9c6a378628eb09Ulrich Drepper		   idx, section_name (ebl, idx));
1840231c590fbe9d6f3a8e22796ded9c6a378628eb09Ulrich Drepper	}
1841b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper
1842b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper#if ALLOW_UNALIGNED
1843b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper      val = *((Elf32_Word *) data->d_buf);
1844b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper#else
1845b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper      memcpy (&val, data->d_buf, elsize);
1846b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper#endif
1847b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper      if ((val & ~GRP_COMDAT) != 0)
1848b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper	ERROR (gettext ("section [%2d] '%s': unknown section group flags\n"),
1849b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper	       idx, section_name (ebl, idx));
1850b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper
1851b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper      for (cnt = elsize; cnt < data->d_size; cnt += elsize)
1852b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper	{
1853b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper#if ALLOW_UNALIGNED
1854b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper	  val = *((Elf32_Word *) ((char *) data->d_buf + cnt));
1855231c590fbe9d6f3a8e22796ded9c6a378628eb09Ulrich Drepper#else
1856231c590fbe9d6f3a8e22796ded9c6a378628eb09Ulrich Drepper	  memcpy (&val, (char *) data->d_buf + cnt, elsize);
1857231c590fbe9d6f3a8e22796ded9c6a378628eb09Ulrich Drepper#endif
1858231c590fbe9d6f3a8e22796ded9c6a378628eb09Ulrich Drepper
1859231c590fbe9d6f3a8e22796ded9c6a378628eb09Ulrich Drepper	  if (val > shnum)
1860231c590fbe9d6f3a8e22796ded9c6a378628eb09Ulrich Drepper	    ERROR (gettext ("\
1861231c590fbe9d6f3a8e22796ded9c6a378628eb09Ulrich Dreppersection [%2d] '%s': section index %Zu out of range\n"),
1862231c590fbe9d6f3a8e22796ded9c6a378628eb09Ulrich Drepper		   idx, section_name (ebl, idx), cnt / elsize);
1863231c590fbe9d6f3a8e22796ded9c6a378628eb09Ulrich Drepper	  else
1864231c590fbe9d6f3a8e22796ded9c6a378628eb09Ulrich Drepper	    {
1865231c590fbe9d6f3a8e22796ded9c6a378628eb09Ulrich Drepper	      GElf_Shdr refshdr_mem;
1866231c590fbe9d6f3a8e22796ded9c6a378628eb09Ulrich Drepper	      GElf_Shdr *refshdr = gelf_getshdr (elf_getscn (ebl->elf, val),
1867231c590fbe9d6f3a8e22796ded9c6a378628eb09Ulrich Drepper						 &refshdr_mem);
1868231c590fbe9d6f3a8e22796ded9c6a378628eb09Ulrich Drepper	      if (refshdr == NULL)
1869231c590fbe9d6f3a8e22796ded9c6a378628eb09Ulrich Drepper		ERROR (gettext ("\
1870231c590fbe9d6f3a8e22796ded9c6a378628eb09Ulrich Dreppersection [%2d] '%s': cannot get section header for element %zu: %s\n"),
1871231c590fbe9d6f3a8e22796ded9c6a378628eb09Ulrich Drepper		       idx, section_name (ebl, idx), cnt / elsize,
1872231c590fbe9d6f3a8e22796ded9c6a378628eb09Ulrich Drepper		       elf_errmsg (-1));
1873231c590fbe9d6f3a8e22796ded9c6a378628eb09Ulrich Drepper	      else
1874231c590fbe9d6f3a8e22796ded9c6a378628eb09Ulrich Drepper		{
1875231c590fbe9d6f3a8e22796ded9c6a378628eb09Ulrich Drepper		  if (refshdr->sh_type == SHT_GROUP)
1876231c590fbe9d6f3a8e22796ded9c6a378628eb09Ulrich Drepper		    ERROR (gettext ("\
1877231c590fbe9d6f3a8e22796ded9c6a378628eb09Ulrich Dreppersection [%2d] '%s': section group contains another group [%2d] '%s'\n"),
1878231c590fbe9d6f3a8e22796ded9c6a378628eb09Ulrich Drepper			   idx, section_name (ebl, idx),
1879231c590fbe9d6f3a8e22796ded9c6a378628eb09Ulrich Drepper			   val, section_name (ebl, val));
1880231c590fbe9d6f3a8e22796ded9c6a378628eb09Ulrich Drepper
1881231c590fbe9d6f3a8e22796ded9c6a378628eb09Ulrich Drepper		  if ((refshdr->sh_flags & SHF_GROUP) == 0)
1882231c590fbe9d6f3a8e22796ded9c6a378628eb09Ulrich Drepper		    ERROR (gettext ("\
1883231c590fbe9d6f3a8e22796ded9c6a378628eb09Ulrich Dreppersection [%2d] '%s': element %Zu references section [%2d] '%s' without SHF_GROUP flag set\n"),
1884231c590fbe9d6f3a8e22796ded9c6a378628eb09Ulrich Drepper			   idx, section_name (ebl, idx), cnt / elsize,
1885231c590fbe9d6f3a8e22796ded9c6a378628eb09Ulrich Drepper			   val, section_name (ebl, val));
1886231c590fbe9d6f3a8e22796ded9c6a378628eb09Ulrich Drepper		}
1887231c590fbe9d6f3a8e22796ded9c6a378628eb09Ulrich Drepper
1888231c590fbe9d6f3a8e22796ded9c6a378628eb09Ulrich Drepper	      if (++scnref[val] == 2)
1889231c590fbe9d6f3a8e22796ded9c6a378628eb09Ulrich Drepper		ERROR (gettext ("\
1890231c590fbe9d6f3a8e22796ded9c6a378628eb09Ulrich Dreppersection [%2d] '%s' is contained in more than one section group\n"),
1891231c590fbe9d6f3a8e22796ded9c6a378628eb09Ulrich Drepper		       val, section_name (ebl, val));
1892231c590fbe9d6f3a8e22796ded9c6a378628eb09Ulrich Drepper	    }
1893231c590fbe9d6f3a8e22796ded9c6a378628eb09Ulrich Drepper	}
1894231c590fbe9d6f3a8e22796ded9c6a378628eb09Ulrich Drepper    }
1895231c590fbe9d6f3a8e22796ded9c6a378628eb09Ulrich Drepper}
1896231c590fbe9d6f3a8e22796ded9c6a378628eb09Ulrich Drepper
1897231c590fbe9d6f3a8e22796ded9c6a378628eb09Ulrich Drepper
1898b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepperstatic const char *
1899b08d5a8fb42f4586d756068065186b5af7e48daUlrich Dreppersection_flags_string (GElf_Word flags, char *buf, size_t len)
1900b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper{
1901b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper  static const struct
1902acb8983909a3f031041ee5d7cbe09fbeb3c31b9aUlrich Drepper  {
1903b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper    GElf_Word flag;
1904acb8983909a3f031041ee5d7cbe09fbeb3c31b9aUlrich Drepper    const char *name;
1905acb8983909a3f031041ee5d7cbe09fbeb3c31b9aUlrich Drepper  } known_flags[] =
1906acb8983909a3f031041ee5d7cbe09fbeb3c31b9aUlrich Drepper    {
1907acb8983909a3f031041ee5d7cbe09fbeb3c31b9aUlrich Drepper#define NEWFLAG(name) { SHF_##name, #name }
1908acb8983909a3f031041ee5d7cbe09fbeb3c31b9aUlrich Drepper      NEWFLAG (WRITE),
1909acb8983909a3f031041ee5d7cbe09fbeb3c31b9aUlrich Drepper      NEWFLAG (ALLOC),
1910acb8983909a3f031041ee5d7cbe09fbeb3c31b9aUlrich Drepper      NEWFLAG (EXECINSTR),
1911b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper      NEWFLAG (MERGE),
1912acb8983909a3f031041ee5d7cbe09fbeb3c31b9aUlrich Drepper      NEWFLAG (STRINGS),
1913acb8983909a3f031041ee5d7cbe09fbeb3c31b9aUlrich Drepper      NEWFLAG (INFO_LINK),
1914acb8983909a3f031041ee5d7cbe09fbeb3c31b9aUlrich Drepper      NEWFLAG (LINK_ORDER),
1915b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper      NEWFLAG (OS_NONCONFORMING),
1916b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper      NEWFLAG (GROUP),
1917b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper      NEWFLAG (TLS)
1918b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper    };
19190a545e678f2c0605ba050b4f72080572ac7c8470Mark Wielaard#undef NEWFLAG
19200a545e678f2c0605ba050b4f72080572ac7c8470Mark Wielaard  const size_t nknown_flags = sizeof (known_flags) / sizeof (known_flags[0]);
19210a545e678f2c0605ba050b4f72080572ac7c8470Mark Wielaard
19220a545e678f2c0605ba050b4f72080572ac7c8470Mark Wielaard  char *cp = buf;
1923acb8983909a3f031041ee5d7cbe09fbeb3c31b9aUlrich Drepper
1924b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper  for (size_t cnt = 0; cnt < nknown_flags; ++cnt)
1925b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper    if (flags & known_flags[cnt].flag)
1926b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper      {
1927b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper	if (cp != buf && len > 1)
1928b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper	  {
1929b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper	    *cp++ = '|';
1930b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper	    --len;
1931b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper	  }
1932b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper
19330a545e678f2c0605ba050b4f72080572ac7c8470Mark Wielaard	size_t ncopy = MIN (len - 1, strlen (known_flags[cnt].name));
19340a545e678f2c0605ba050b4f72080572ac7c8470Mark Wielaard	cp = mempcpy (cp, known_flags[cnt].name, ncopy);
1935b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper	len -= ncopy;
1936b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper
1937b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper	flags ^= known_flags[cnt].flag;
1938b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper      }
1939b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper
1940b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper  if (flags != 0 || cp == buf)
1941b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper    snprintf (cp, len - 1, "%" PRIx64, (uint64_t) flags);
1942b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper
1943b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper  *cp = '\0';
1944b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper
1945acb8983909a3f031041ee5d7cbe09fbeb3c31b9aUlrich Drepper  return buf;
1946b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper}
1947b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper
1948acb8983909a3f031041ee5d7cbe09fbeb3c31b9aUlrich Drepper
1949b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepperstatic int
1950b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepperhas_copy_reloc (Ebl *ebl, unsigned int symscnndx, unsigned int symndx)
1951b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper{
1952b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper  /* First find the relocation section for the symbol table.  */
1953b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper  Elf_Scn *scn = NULL;
1954b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper  GElf_Shdr shdr_mem;
1955b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper  GElf_Shdr *shdr = NULL;
1956b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper  while ((scn = elf_nextscn (ebl->elf, scn)) != NULL)
1957b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper    {
1958b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper      shdr = gelf_getshdr (scn, &shdr_mem);
1959b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper      if (shdr != NULL
1960acb8983909a3f031041ee5d7cbe09fbeb3c31b9aUlrich Drepper	  && (shdr->sh_type == SHT_REL || shdr->sh_type == SHT_RELA)
19610a545e678f2c0605ba050b4f72080572ac7c8470Mark Wielaard	  && shdr->sh_link == symscnndx)
196271c1534c9c7a0652fb6c5f9295baa08f32b0b166Jakub Jelinek	/* Found the section.  */
196371c1534c9c7a0652fb6c5f9295baa08f32b0b166Jakub Jelinek	break;
196471c1534c9c7a0652fb6c5f9295baa08f32b0b166Jakub Jelinek    }
196571c1534c9c7a0652fb6c5f9295baa08f32b0b166Jakub Jelinek
196671c1534c9c7a0652fb6c5f9295baa08f32b0b166Jakub Jelinek  if (scn == NULL)
1967b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper    return 0;
1968b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper
1969b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper  Elf_Data *data = elf_getdata (scn, NULL);
1970b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper  if (data == NULL)
1971acb8983909a3f031041ee5d7cbe09fbeb3c31b9aUlrich Drepper    return 0;
1972b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper
1973b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper  if (shdr->sh_type == SHT_REL)
1974b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper    for (int i = 0; (size_t) i < shdr->sh_size / shdr->sh_entsize; ++i)
1975b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper      {
1976b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper	GElf_Rel rel_mem;
1977b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper	GElf_Rel *rel = gelf_getrel (data, i, &rel_mem);
1978b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper	if (rel == NULL)
1979b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper	  continue;
1980b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper
1981b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper	if (GELF_R_SYM (rel->r_info) == symndx
1982b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper	    && ebl_copy_reloc_p (ebl, GELF_R_TYPE (rel->r_info)))
1983b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper	  return 1;
1984b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper      }
1985b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper  else
1986b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper    for (int i = 0; (size_t) i < shdr->sh_size / shdr->sh_entsize; ++i)
1987b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper      {
1988b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper	GElf_Rela rela_mem;
1989b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper	GElf_Rela *rela = gelf_getrela (data, i, &rela_mem);
1990b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper	if (rela == NULL)
1991b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper	  continue;
1992b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper
1993b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper	if (GELF_R_SYM (rela->r_info) == symndx
1994b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper	    && ebl_copy_reloc_p (ebl, GELF_R_TYPE (rela->r_info)))
199528ed895fdc303b2a793506bb1fcdd35d5fd14e70Ulrich Drepper	  return 1;
199628ed895fdc303b2a793506bb1fcdd35d5fd14e70Ulrich Drepper      }
199728ed895fdc303b2a793506bb1fcdd35d5fd14e70Ulrich Drepper
199828ed895fdc303b2a793506bb1fcdd35d5fd14e70Ulrich Drepper  return 0;
199928ed895fdc303b2a793506bb1fcdd35d5fd14e70Ulrich Drepper}
200028ed895fdc303b2a793506bb1fcdd35d5fd14e70Ulrich Drepper
200128ed895fdc303b2a793506bb1fcdd35d5fd14e70Ulrich Drepper
200228ed895fdc303b2a793506bb1fcdd35d5fd14e70Ulrich Drepperstatic int
200328ed895fdc303b2a793506bb1fcdd35d5fd14e70Ulrich Drepperin_nobits_scn (Ebl *ebl, unsigned int shndx)
200428ed895fdc303b2a793506bb1fcdd35d5fd14e70Ulrich Drepper{
200528ed895fdc303b2a793506bb1fcdd35d5fd14e70Ulrich Drepper  GElf_Shdr shdr_mem;
200628ed895fdc303b2a793506bb1fcdd35d5fd14e70Ulrich Drepper  GElf_Shdr *shdr = gelf_getshdr (elf_getscn (ebl->elf, shndx), &shdr_mem);
200728ed895fdc303b2a793506bb1fcdd35d5fd14e70Ulrich Drepper  return shdr != NULL && shdr->sh_type == SHT_NOBITS;
200828ed895fdc303b2a793506bb1fcdd35d5fd14e70Ulrich Drepper}
200971c1534c9c7a0652fb6c5f9295baa08f32b0b166Jakub Jelinek
201028ed895fdc303b2a793506bb1fcdd35d5fd14e70Ulrich Drepper
201128ed895fdc303b2a793506bb1fcdd35d5fd14e70Ulrich Drepperstatic struct version_namelist
201228ed895fdc303b2a793506bb1fcdd35d5fd14e70Ulrich Drepper{
201328ed895fdc303b2a793506bb1fcdd35d5fd14e70Ulrich Drepper  const char *objname;
201428ed895fdc303b2a793506bb1fcdd35d5fd14e70Ulrich Drepper  const char *name;
201528ed895fdc303b2a793506bb1fcdd35d5fd14e70Ulrich Drepper  GElf_Word ndx;
201628ed895fdc303b2a793506bb1fcdd35d5fd14e70Ulrich Drepper  enum { ver_def, ver_need } type;
201728ed895fdc303b2a793506bb1fcdd35d5fd14e70Ulrich Drepper  struct version_namelist *next;
201828ed895fdc303b2a793506bb1fcdd35d5fd14e70Ulrich Drepper} *version_namelist;
201928ed895fdc303b2a793506bb1fcdd35d5fd14e70Ulrich Drepper
202071c1534c9c7a0652fb6c5f9295baa08f32b0b166Jakub Jelinek
202171c1534c9c7a0652fb6c5f9295baa08f32b0b166Jakub Jelinekstatic int
202228ed895fdc303b2a793506bb1fcdd35d5fd14e70Ulrich Drepperadd_version (const char *objname, const char *name, GElf_Word ndx, int type)
202328ed895fdc303b2a793506bb1fcdd35d5fd14e70Ulrich Drepper{
202471c1534c9c7a0652fb6c5f9295baa08f32b0b166Jakub Jelinek  /* Check that there are no duplications.  */
202571c1534c9c7a0652fb6c5f9295baa08f32b0b166Jakub Jelinek  struct version_namelist *nlp = version_namelist;
202671c1534c9c7a0652fb6c5f9295baa08f32b0b166Jakub Jelinek  while (nlp != NULL)
202771c1534c9c7a0652fb6c5f9295baa08f32b0b166Jakub Jelinek    {
202828ed895fdc303b2a793506bb1fcdd35d5fd14e70Ulrich Drepper      if (((nlp->objname == NULL && objname == NULL)
202928ed895fdc303b2a793506bb1fcdd35d5fd14e70Ulrich Drepper	   || (nlp->objname != NULL && objname != NULL
203028ed895fdc303b2a793506bb1fcdd35d5fd14e70Ulrich Drepper	       && strcmp (nlp->objname, objname) == 0))
203171c1534c9c7a0652fb6c5f9295baa08f32b0b166Jakub Jelinek	  && strcmp (nlp->name, name) == 0)
203228ed895fdc303b2a793506bb1fcdd35d5fd14e70Ulrich Drepper	return nlp->type == ver_def ? 1 : -1;
203328ed895fdc303b2a793506bb1fcdd35d5fd14e70Ulrich Drepper      nlp = nlp->next;
203471c1534c9c7a0652fb6c5f9295baa08f32b0b166Jakub Jelinek    }
203571c1534c9c7a0652fb6c5f9295baa08f32b0b166Jakub Jelinek
203671c1534c9c7a0652fb6c5f9295baa08f32b0b166Jakub Jelinek  nlp = xmalloc (sizeof (*nlp));
203771c1534c9c7a0652fb6c5f9295baa08f32b0b166Jakub Jelinek  nlp->objname = objname;
203828ed895fdc303b2a793506bb1fcdd35d5fd14e70Ulrich Drepper  nlp->name = name;
203928ed895fdc303b2a793506bb1fcdd35d5fd14e70Ulrich Drepper  nlp->ndx = ndx;
204028ed895fdc303b2a793506bb1fcdd35d5fd14e70Ulrich Drepper  nlp->type = type;
204171c1534c9c7a0652fb6c5f9295baa08f32b0b166Jakub Jelinek  nlp->next = version_namelist;
204228ed895fdc303b2a793506bb1fcdd35d5fd14e70Ulrich Drepper  version_namelist = nlp;
204328ed895fdc303b2a793506bb1fcdd35d5fd14e70Ulrich Drepper
204428ed895fdc303b2a793506bb1fcdd35d5fd14e70Ulrich Drepper  return 0;
204528ed895fdc303b2a793506bb1fcdd35d5fd14e70Ulrich Drepper}
204628ed895fdc303b2a793506bb1fcdd35d5fd14e70Ulrich Drepper
204728ed895fdc303b2a793506bb1fcdd35d5fd14e70Ulrich Drepper
204828ed895fdc303b2a793506bb1fcdd35d5fd14e70Ulrich Drepperstatic void
204928ed895fdc303b2a793506bb1fcdd35d5fd14e70Ulrich Dreppercheck_versym (Ebl *ebl, int idx)
205028ed895fdc303b2a793506bb1fcdd35d5fd14e70Ulrich Drepper{
205128ed895fdc303b2a793506bb1fcdd35d5fd14e70Ulrich Drepper  Elf_Scn *scn = elf_getscn (ebl->elf, idx);
205228ed895fdc303b2a793506bb1fcdd35d5fd14e70Ulrich Drepper  GElf_Shdr shdr_mem;
205328ed895fdc303b2a793506bb1fcdd35d5fd14e70Ulrich Drepper  GElf_Shdr *shdr = gelf_getshdr (scn, &shdr_mem);
205428ed895fdc303b2a793506bb1fcdd35d5fd14e70Ulrich Drepper  if (shdr == NULL)
205528ed895fdc303b2a793506bb1fcdd35d5fd14e70Ulrich Drepper    /* The error has already been reported.  */
205628ed895fdc303b2a793506bb1fcdd35d5fd14e70Ulrich Drepper    return;
205728ed895fdc303b2a793506bb1fcdd35d5fd14e70Ulrich Drepper
205828ed895fdc303b2a793506bb1fcdd35d5fd14e70Ulrich Drepper  Elf_Data *data = elf_getdata (scn, NULL);
205928ed895fdc303b2a793506bb1fcdd35d5fd14e70Ulrich Drepper  if (data == NULL)
20600a545e678f2c0605ba050b4f72080572ac7c8470Mark Wielaard    {
206128ed895fdc303b2a793506bb1fcdd35d5fd14e70Ulrich Drepper      ERROR (gettext ("section [%2d] '%s': cannot get section data\n"),
206228ed895fdc303b2a793506bb1fcdd35d5fd14e70Ulrich Drepper	     idx, section_name (ebl, idx));
206328ed895fdc303b2a793506bb1fcdd35d5fd14e70Ulrich Drepper      return;
206428ed895fdc303b2a793506bb1fcdd35d5fd14e70Ulrich Drepper    }
206528ed895fdc303b2a793506bb1fcdd35d5fd14e70Ulrich Drepper
206628ed895fdc303b2a793506bb1fcdd35d5fd14e70Ulrich Drepper  Elf_Scn *symscn = elf_getscn (ebl->elf, shdr->sh_link);
206728ed895fdc303b2a793506bb1fcdd35d5fd14e70Ulrich Drepper  GElf_Shdr symshdr_mem;
206828ed895fdc303b2a793506bb1fcdd35d5fd14e70Ulrich Drepper  GElf_Shdr *symshdr = gelf_getshdr (symscn, &symshdr_mem);
206928ed895fdc303b2a793506bb1fcdd35d5fd14e70Ulrich Drepper  if (symshdr == NULL)
207028ed895fdc303b2a793506bb1fcdd35d5fd14e70Ulrich Drepper    /* The error has already been reported.  */
207171c1534c9c7a0652fb6c5f9295baa08f32b0b166Jakub Jelinek    return;
207271c1534c9c7a0652fb6c5f9295baa08f32b0b166Jakub Jelinek
207328ed895fdc303b2a793506bb1fcdd35d5fd14e70Ulrich Drepper  if (symshdr->sh_type != SHT_DYNSYM)
207428ed895fdc303b2a793506bb1fcdd35d5fd14e70Ulrich Drepper    {
207571c1534c9c7a0652fb6c5f9295baa08f32b0b166Jakub Jelinek      ERROR (gettext ("\
207671c1534c9c7a0652fb6c5f9295baa08f32b0b166Jakub Jelineksection [%2d] '%s' refers in sh_link to section [%2d] '%s' which is no dynamic symbol table\n"),
207771c1534c9c7a0652fb6c5f9295baa08f32b0b166Jakub Jelinek	     idx, section_name (ebl, idx),
207871c1534c9c7a0652fb6c5f9295baa08f32b0b166Jakub Jelinek	     shdr->sh_link, section_name (ebl, shdr->sh_link));
207928ed895fdc303b2a793506bb1fcdd35d5fd14e70Ulrich Drepper      return;
208028ed895fdc303b2a793506bb1fcdd35d5fd14e70Ulrich Drepper    }
208128ed895fdc303b2a793506bb1fcdd35d5fd14e70Ulrich Drepper
208271c1534c9c7a0652fb6c5f9295baa08f32b0b166Jakub Jelinek  /* The number of elements in the version symbol table must be the
208328ed895fdc303b2a793506bb1fcdd35d5fd14e70Ulrich Drepper     same as the number of symbols.  */
208428ed895fdc303b2a793506bb1fcdd35d5fd14e70Ulrich Drepper  if (shdr->sh_size / shdr->sh_entsize
208571c1534c9c7a0652fb6c5f9295baa08f32b0b166Jakub Jelinek      != symshdr->sh_size / symshdr->sh_entsize)
208671c1534c9c7a0652fb6c5f9295baa08f32b0b166Jakub Jelinek    ERROR (gettext ("\
208771c1534c9c7a0652fb6c5f9295baa08f32b0b166Jakub Jelineksection [%2d] '%s' has different number of entries than symbol table [%2d] '%s'\n"),
208871c1534c9c7a0652fb6c5f9295baa08f32b0b166Jakub Jelinek	   idx, section_name (ebl, idx),
208928ed895fdc303b2a793506bb1fcdd35d5fd14e70Ulrich Drepper	   shdr->sh_link, section_name (ebl, shdr->sh_link));
2090dcf6160602985e6eb70c96c6546ed9614a414d98Ulrich Drepper
209171c1534c9c7a0652fb6c5f9295baa08f32b0b166Jakub Jelinek  Elf_Data *symdata = elf_getdata (symscn, NULL);
209271c1534c9c7a0652fb6c5f9295baa08f32b0b166Jakub Jelinek  if (symdata == NULL)
209328ed895fdc303b2a793506bb1fcdd35d5fd14e70Ulrich Drepper    /* The error has already been reported.  */
209428ed895fdc303b2a793506bb1fcdd35d5fd14e70Ulrich Drepper    return;
209528ed895fdc303b2a793506bb1fcdd35d5fd14e70Ulrich Drepper
209628ed895fdc303b2a793506bb1fcdd35d5fd14e70Ulrich Drepper  for (int cnt = 1; (size_t) cnt < shdr->sh_size / shdr->sh_entsize; ++cnt)
209728ed895fdc303b2a793506bb1fcdd35d5fd14e70Ulrich Drepper    {
209828ed895fdc303b2a793506bb1fcdd35d5fd14e70Ulrich Drepper      GElf_Versym versym_mem;
209928ed895fdc303b2a793506bb1fcdd35d5fd14e70Ulrich Drepper      GElf_Versym *versym = gelf_getversym (data, cnt, &versym_mem);
2100281bb49c71665f306b23107cbf821636f59211e0Mark Wielaard      if (versym == NULL)
2101281bb49c71665f306b23107cbf821636f59211e0Mark Wielaard	{
2102281bb49c71665f306b23107cbf821636f59211e0Mark Wielaard	  ERROR (gettext ("\
2103281bb49c71665f306b23107cbf821636f59211e0Mark Wielaardsection [%2d] '%s': symbol %d: cannot read version data\n"),
2104281bb49c71665f306b23107cbf821636f59211e0Mark Wielaard		 idx, section_name (ebl, idx), cnt);
2105281bb49c71665f306b23107cbf821636f59211e0Mark Wielaard	  break;
2106281bb49c71665f306b23107cbf821636f59211e0Mark Wielaard	}
2107281bb49c71665f306b23107cbf821636f59211e0Mark Wielaard
210828ed895fdc303b2a793506bb1fcdd35d5fd14e70Ulrich Drepper      GElf_Sym sym_mem;
210928ed895fdc303b2a793506bb1fcdd35d5fd14e70Ulrich Drepper      GElf_Sym *sym = gelf_getsym (symdata, cnt, &sym_mem);
21108ae5814209558f51c93b583c9ae6fdd482f0cbb2Ulrich Drepper      if (sym == NULL)
211128ed895fdc303b2a793506bb1fcdd35d5fd14e70Ulrich Drepper	/* Already reported elsewhere.  */
2112281bb49c71665f306b23107cbf821636f59211e0Mark Wielaard	continue;
2113281bb49c71665f306b23107cbf821636f59211e0Mark Wielaard
2114281bb49c71665f306b23107cbf821636f59211e0Mark Wielaard      if (*versym == VER_NDX_GLOBAL)
2115281bb49c71665f306b23107cbf821636f59211e0Mark Wielaard	{
2116281bb49c71665f306b23107cbf821636f59211e0Mark Wielaard	  /* Global symbol.  Make sure it is not defined as local.  */
2117281bb49c71665f306b23107cbf821636f59211e0Mark Wielaard	  if (GELF_ST_BIND (sym->st_info) == STB_LOCAL)
2118281bb49c71665f306b23107cbf821636f59211e0Mark Wielaard	    ERROR (gettext ("\
21198ae5814209558f51c93b583c9ae6fdd482f0cbb2Ulrich Dreppersection [%2d] '%s': symbol %d: local symbol with global scope\n"),
21208ae5814209558f51c93b583c9ae6fdd482f0cbb2Ulrich Drepper		   idx, section_name (ebl, idx), cnt);
21218ae5814209558f51c93b583c9ae6fdd482f0cbb2Ulrich Drepper	}
21228ae5814209558f51c93b583c9ae6fdd482f0cbb2Ulrich Drepper      else if (*versym != VER_NDX_LOCAL)
21238ae5814209558f51c93b583c9ae6fdd482f0cbb2Ulrich Drepper	{
21248ae5814209558f51c93b583c9ae6fdd482f0cbb2Ulrich Drepper	  /* Versioned symbol.  Make sure it is not defined as local.  */
2125281bb49c71665f306b23107cbf821636f59211e0Mark Wielaard	  if (!gnuld && GELF_ST_BIND (sym->st_info) == STB_LOCAL)
2126281bb49c71665f306b23107cbf821636f59211e0Mark Wielaard	    ERROR (gettext ("\
2127281bb49c71665f306b23107cbf821636f59211e0Mark Wielaardsection [%2d] '%s': symbol %d: local symbol with version\n"),
2128281bb49c71665f306b23107cbf821636f59211e0Mark Wielaard		   idx, section_name (ebl, idx), cnt);
212928ed895fdc303b2a793506bb1fcdd35d5fd14e70Ulrich Drepper
213028ed895fdc303b2a793506bb1fcdd35d5fd14e70Ulrich Drepper	  /* Look through the list of defined versions and locate the
213171c1534c9c7a0652fb6c5f9295baa08f32b0b166Jakub Jelinek	     index we need for this symbol.  */
213228ed895fdc303b2a793506bb1fcdd35d5fd14e70Ulrich Drepper	  struct version_namelist *runp = version_namelist;
2133281bb49c71665f306b23107cbf821636f59211e0Mark Wielaard	  while (runp != NULL)
213428ed895fdc303b2a793506bb1fcdd35d5fd14e70Ulrich Drepper	    if (runp->ndx == *versym)
213528ed895fdc303b2a793506bb1fcdd35d5fd14e70Ulrich Drepper	      break;
213628ed895fdc303b2a793506bb1fcdd35d5fd14e70Ulrich Drepper	    else
21378ae5814209558f51c93b583c9ae6fdd482f0cbb2Ulrich Drepper	      runp = runp->next;
213816e2ac344788f2bb08ae9dc0a20948f554ca560cMark Wielaard
213916e2ac344788f2bb08ae9dc0a20948f554ca560cMark Wielaard	  if (runp == NULL)
21408ae5814209558f51c93b583c9ae6fdd482f0cbb2Ulrich Drepper	    ERROR (gettext ("\
214116e2ac344788f2bb08ae9dc0a20948f554ca560cMark Wielaardsection [%2d] '%s': symbol %d: invalid version index %d\n"),
214216e2ac344788f2bb08ae9dc0a20948f554ca560cMark Wielaard		   idx, section_name (ebl, idx), cnt, (int) *versym);
214316e2ac344788f2bb08ae9dc0a20948f554ca560cMark Wielaard	  else if (sym->st_shndx == SHN_UNDEF
21448ae5814209558f51c93b583c9ae6fdd482f0cbb2Ulrich Drepper		   && runp->type == ver_def)
21458ae5814209558f51c93b583c9ae6fdd482f0cbb2Ulrich Drepper	    ERROR (gettext ("\
21468ae5814209558f51c93b583c9ae6fdd482f0cbb2Ulrich Dreppersection [%2d] '%s': symbol %d: version index %d is for defined version\n"),
214728ed895fdc303b2a793506bb1fcdd35d5fd14e70Ulrich Drepper		   idx, section_name (ebl, idx), cnt, (int) *versym);
21480a545e678f2c0605ba050b4f72080572ac7c8470Mark Wielaard	  else if (sym->st_shndx != SHN_UNDEF
214928ed895fdc303b2a793506bb1fcdd35d5fd14e70Ulrich Drepper		   && runp->type == ver_need)
215028ed895fdc303b2a793506bb1fcdd35d5fd14e70Ulrich Drepper	    {
215128ed895fdc303b2a793506bb1fcdd35d5fd14e70Ulrich Drepper	      /* Unless this symbol has a copy relocation associated
215228ed895fdc303b2a793506bb1fcdd35d5fd14e70Ulrich Drepper		 this must not happen.  */
215328ed895fdc303b2a793506bb1fcdd35d5fd14e70Ulrich Drepper	      if (!has_copy_reloc (ebl, shdr->sh_link, cnt)
21548ae5814209558f51c93b583c9ae6fdd482f0cbb2Ulrich Drepper		  && !in_nobits_scn (ebl, sym->st_shndx))
21558ae5814209558f51c93b583c9ae6fdd482f0cbb2Ulrich Drepper		ERROR (gettext ("\
21568ae5814209558f51c93b583c9ae6fdd482f0cbb2Ulrich Dreppersection [%2d] '%s': symbol %d: version index %d is for requested version\n"),
21578ae5814209558f51c93b583c9ae6fdd482f0cbb2Ulrich Drepper		       idx, section_name (ebl, idx), cnt, (int) *versym);
21588ae5814209558f51c93b583c9ae6fdd482f0cbb2Ulrich Drepper	    }
21598ae5814209558f51c93b583c9ae6fdd482f0cbb2Ulrich Drepper	}
21608ae5814209558f51c93b583c9ae6fdd482f0cbb2Ulrich Drepper    }
21618ae5814209558f51c93b583c9ae6fdd482f0cbb2Ulrich Drepper}
21628ae5814209558f51c93b583c9ae6fdd482f0cbb2Ulrich Drepper
216328ed895fdc303b2a793506bb1fcdd35d5fd14e70Ulrich Drepper
21648ae5814209558f51c93b583c9ae6fdd482f0cbb2Ulrich Drepperstatic int
216528ed895fdc303b2a793506bb1fcdd35d5fd14e70Ulrich Drepperunknown_dependency_p (Elf *elf, GElf_Ehdr *ehdr, const char *fname)
21668ae5814209558f51c93b583c9ae6fdd482f0cbb2Ulrich Drepper{
216728ed895fdc303b2a793506bb1fcdd35d5fd14e70Ulrich Drepper  GElf_Phdr phdr_mem;
216828ed895fdc303b2a793506bb1fcdd35d5fd14e70Ulrich Drepper  GElf_Phdr *phdr = NULL;
21698ae5814209558f51c93b583c9ae6fdd482f0cbb2Ulrich Drepper
217028ed895fdc303b2a793506bb1fcdd35d5fd14e70Ulrich Drepper  int i;
217128ed895fdc303b2a793506bb1fcdd35d5fd14e70Ulrich Drepper  for (i = 0; i < ehdr->e_phnum; ++i)
217228ed895fdc303b2a793506bb1fcdd35d5fd14e70Ulrich Drepper    if ((phdr = gelf_getphdr (elf, i, &phdr_mem)) != NULL
217328ed895fdc303b2a793506bb1fcdd35d5fd14e70Ulrich Drepper	&& phdr->p_type == PT_DYNAMIC)
217428ed895fdc303b2a793506bb1fcdd35d5fd14e70Ulrich Drepper      break;
21758ae5814209558f51c93b583c9ae6fdd482f0cbb2Ulrich Drepper
217628ed895fdc303b2a793506bb1fcdd35d5fd14e70Ulrich Drepper  if (i == ehdr->e_phnum)
217728ed895fdc303b2a793506bb1fcdd35d5fd14e70Ulrich Drepper    return 1;
217828ed895fdc303b2a793506bb1fcdd35d5fd14e70Ulrich Drepper  assert (phdr != NULL);
217928ed895fdc303b2a793506bb1fcdd35d5fd14e70Ulrich Drepper  Elf_Scn *scn = gelf_offscn (elf, phdr->p_offset);
218028ed895fdc303b2a793506bb1fcdd35d5fd14e70Ulrich Drepper  GElf_Shdr shdr_mem;
21818ae5814209558f51c93b583c9ae6fdd482f0cbb2Ulrich Drepper  GElf_Shdr *shdr = gelf_getshdr (scn, &shdr_mem);
21828ae5814209558f51c93b583c9ae6fdd482f0cbb2Ulrich Drepper  Elf_Data *data = elf_getdata (scn, NULL);
21838ae5814209558f51c93b583c9ae6fdd482f0cbb2Ulrich Drepper  if (shdr != NULL && shdr->sh_type == SHT_DYNAMIC && data != NULL)
218428ed895fdc303b2a793506bb1fcdd35d5fd14e70Ulrich Drepper    for (size_t j = 0; j < shdr->sh_size / shdr->sh_entsize; ++j)
218528ed895fdc303b2a793506bb1fcdd35d5fd14e70Ulrich Drepper      {
218628ed895fdc303b2a793506bb1fcdd35d5fd14e70Ulrich Drepper	GElf_Dyn dyn_mem;
218728ed895fdc303b2a793506bb1fcdd35d5fd14e70Ulrich Drepper	GElf_Dyn *dyn = gelf_getdyn (data, j, &dyn_mem);
218828ed895fdc303b2a793506bb1fcdd35d5fd14e70Ulrich Drepper	if (dyn != NULL && dyn->d_tag == DT_NEEDED)
218928ed895fdc303b2a793506bb1fcdd35d5fd14e70Ulrich Drepper	  {
219028ed895fdc303b2a793506bb1fcdd35d5fd14e70Ulrich Drepper	    const char *str = elf_strptr (elf, shdr->sh_link, dyn->d_un.d_val);
219128ed895fdc303b2a793506bb1fcdd35d5fd14e70Ulrich Drepper	    if (str != NULL && strcmp (str, fname) == 0)
2192231c590fbe9d6f3a8e22796ded9c6a378628eb09Ulrich Drepper	      /* Found it.  */
2193231c590fbe9d6f3a8e22796ded9c6a378628eb09Ulrich Drepper	      return 0;
219428ed895fdc303b2a793506bb1fcdd35d5fd14e70Ulrich Drepper	  }
219528ed895fdc303b2a793506bb1fcdd35d5fd14e70Ulrich Drepper      }
21965530ec5bbb95d2041ba9ece15ba10fe2b1d86eabUlrich Drepper
21975530ec5bbb95d2041ba9ece15ba10fe2b1d86eabUlrich Drepper  return 1;
219828ed895fdc303b2a793506bb1fcdd35d5fd14e70Ulrich Drepper}
21990a545e678f2c0605ba050b4f72080572ac7c8470Mark Wielaard
22000a545e678f2c0605ba050b4f72080572ac7c8470Mark Wielaard
22010a545e678f2c0605ba050b4f72080572ac7c8470Mark Wielaardstatic unsigned int nverneed;
22020a545e678f2c0605ba050b4f72080572ac7c8470Mark Wielaard
220328ed895fdc303b2a793506bb1fcdd35d5fd14e70Ulrich Drepperstatic void
220428ed895fdc303b2a793506bb1fcdd35d5fd14e70Ulrich Dreppercheck_verneed (Ebl *ebl, GElf_Ehdr *ehdr, GElf_Shdr *shdr, int idx)
220528ed895fdc303b2a793506bb1fcdd35d5fd14e70Ulrich Drepper{
220628ed895fdc303b2a793506bb1fcdd35d5fd14e70Ulrich Drepper  if (++nverneed == 2)
220728ed895fdc303b2a793506bb1fcdd35d5fd14e70Ulrich Drepper    ERROR (gettext ("more than one version reference section present\n"));
220828ed895fdc303b2a793506bb1fcdd35d5fd14e70Ulrich Drepper
22095530ec5bbb95d2041ba9ece15ba10fe2b1d86eabUlrich Drepper  GElf_Shdr strshdr_mem;
22105530ec5bbb95d2041ba9ece15ba10fe2b1d86eabUlrich Drepper  GElf_Shdr *strshdr = gelf_getshdr (elf_getscn (ebl->elf, shdr->sh_link),
22118ae5814209558f51c93b583c9ae6fdd482f0cbb2Ulrich Drepper				     &strshdr_mem);
22128ae5814209558f51c93b583c9ae6fdd482f0cbb2Ulrich Drepper  if (strshdr == NULL)
22138ae5814209558f51c93b583c9ae6fdd482f0cbb2Ulrich Drepper    return;
22140a545e678f2c0605ba050b4f72080572ac7c8470Mark Wielaard  if (strshdr->sh_type != SHT_STRTAB)
22150a545e678f2c0605ba050b4f72080572ac7c8470Mark Wielaard    ERROR (gettext ("\
22160a545e678f2c0605ba050b4f72080572ac7c8470Mark Wielaardsection [%2d] '%s': sh_link does not link to string table\n"),
22170a545e678f2c0605ba050b4f72080572ac7c8470Mark Wielaard	   idx, section_name (ebl, idx));
22180a545e678f2c0605ba050b4f72080572ac7c8470Mark Wielaard
22190a545e678f2c0605ba050b4f72080572ac7c8470Mark Wielaard  Elf_Data *data = elf_getdata (elf_getscn (ebl->elf, idx), NULL);
22200a545e678f2c0605ba050b4f72080572ac7c8470Mark Wielaard  if (data == NULL)
22210a545e678f2c0605ba050b4f72080572ac7c8470Mark Wielaard    {
22228ae5814209558f51c93b583c9ae6fdd482f0cbb2Ulrich Drepper      ERROR (gettext ("section [%2d] '%s': cannot get section data\n"),
22238ae5814209558f51c93b583c9ae6fdd482f0cbb2Ulrich Drepper	     idx, section_name (ebl, idx));
22248ae5814209558f51c93b583c9ae6fdd482f0cbb2Ulrich Drepper      return;
22258ae5814209558f51c93b583c9ae6fdd482f0cbb2Ulrich Drepper    }
22268ae5814209558f51c93b583c9ae6fdd482f0cbb2Ulrich Drepper  unsigned int offset = 0;
22278ae5814209558f51c93b583c9ae6fdd482f0cbb2Ulrich Drepper  for (int cnt = shdr->sh_info; --cnt >= 0; )
22288ae5814209558f51c93b583c9ae6fdd482f0cbb2Ulrich Drepper    {
22298ae5814209558f51c93b583c9ae6fdd482f0cbb2Ulrich Drepper      /* Get the data at the next offset.  */
22308ae5814209558f51c93b583c9ae6fdd482f0cbb2Ulrich Drepper      GElf_Verneed needmem;
22318ae5814209558f51c93b583c9ae6fdd482f0cbb2Ulrich Drepper      GElf_Verneed *need = gelf_getverneed (data, offset, &needmem);
22328ae5814209558f51c93b583c9ae6fdd482f0cbb2Ulrich Drepper      if (need == NULL)
22338ae5814209558f51c93b583c9ae6fdd482f0cbb2Ulrich Drepper	break;
22348ae5814209558f51c93b583c9ae6fdd482f0cbb2Ulrich Drepper
22358ae5814209558f51c93b583c9ae6fdd482f0cbb2Ulrich Drepper      unsigned int auxoffset = offset + need->vn_aux;
223628ed895fdc303b2a793506bb1fcdd35d5fd14e70Ulrich Drepper
223728ed895fdc303b2a793506bb1fcdd35d5fd14e70Ulrich Drepper      if (need->vn_version != EV_CURRENT)
223828ed895fdc303b2a793506bb1fcdd35d5fd14e70Ulrich Drepper	ERROR (gettext ("\
223928ed895fdc303b2a793506bb1fcdd35d5fd14e70Ulrich Dreppersection [%2d] '%s': entry %d has wrong version %d\n"),
224028ed895fdc303b2a793506bb1fcdd35d5fd14e70Ulrich Drepper	       idx, section_name (ebl, idx), cnt, (int) need->vn_version);
224128ed895fdc303b2a793506bb1fcdd35d5fd14e70Ulrich Drepper
224228ed895fdc303b2a793506bb1fcdd35d5fd14e70Ulrich Drepper      if (need->vn_cnt > 0 && need->vn_aux < gelf_fsize (ebl->elf, ELF_T_VNEED,
224328ed895fdc303b2a793506bb1fcdd35d5fd14e70Ulrich Drepper							 1, EV_CURRENT))
224428ed895fdc303b2a793506bb1fcdd35d5fd14e70Ulrich Drepper	ERROR (gettext ("\
224528ed895fdc303b2a793506bb1fcdd35d5fd14e70Ulrich Dreppersection [%2d] '%s': entry %d has wrong offset of auxiliary data\n"),
224628ed895fdc303b2a793506bb1fcdd35d5fd14e70Ulrich Drepper	       idx, section_name (ebl, idx), cnt);
224728ed895fdc303b2a793506bb1fcdd35d5fd14e70Ulrich Drepper
22485530ec5bbb95d2041ba9ece15ba10fe2b1d86eabUlrich Drepper      const char *libname = elf_strptr (ebl->elf, shdr->sh_link,
22490a545e678f2c0605ba050b4f72080572ac7c8470Mark Wielaard					need->vn_file);
225028ed895fdc303b2a793506bb1fcdd35d5fd14e70Ulrich Drepper      if (libname == NULL)
225128ed895fdc303b2a793506bb1fcdd35d5fd14e70Ulrich Drepper	{
225228ed895fdc303b2a793506bb1fcdd35d5fd14e70Ulrich Drepper	  ERROR (gettext ("\
22535530ec5bbb95d2041ba9ece15ba10fe2b1d86eabUlrich Dreppersection [%2d] '%s': entry %d has invalid file reference\n"),
225428ed895fdc303b2a793506bb1fcdd35d5fd14e70Ulrich Drepper		 idx, section_name (ebl, idx), cnt);
22558ae5814209558f51c93b583c9ae6fdd482f0cbb2Ulrich Drepper	  goto next_need;
22568ae5814209558f51c93b583c9ae6fdd482f0cbb2Ulrich Drepper	}
22578ae5814209558f51c93b583c9ae6fdd482f0cbb2Ulrich Drepper
22588ae5814209558f51c93b583c9ae6fdd482f0cbb2Ulrich Drepper      /* Check that there is a DT_NEEDED entry for the referenced library.  */
22598ae5814209558f51c93b583c9ae6fdd482f0cbb2Ulrich Drepper      if (unknown_dependency_p (ebl->elf, ehdr, libname))
22608ae5814209558f51c93b583c9ae6fdd482f0cbb2Ulrich Drepper	ERROR (gettext ("\
22618ae5814209558f51c93b583c9ae6fdd482f0cbb2Ulrich Dreppersection [%2d] '%s': entry %d references unknown dependency\n"),
226228ed895fdc303b2a793506bb1fcdd35d5fd14e70Ulrich Drepper	       idx, section_name (ebl, idx), cnt);
226328ed895fdc303b2a793506bb1fcdd35d5fd14e70Ulrich Drepper
226428ed895fdc303b2a793506bb1fcdd35d5fd14e70Ulrich Drepper      for (int cnt2 = need->vn_cnt; --cnt2 >= 0; )
226528ed895fdc303b2a793506bb1fcdd35d5fd14e70Ulrich Drepper	{
226628ed895fdc303b2a793506bb1fcdd35d5fd14e70Ulrich Drepper	  GElf_Vernaux auxmem;
2267b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper	  GElf_Vernaux *aux = gelf_getvernaux (data, auxoffset, &auxmem);
2268acb8983909a3f031041ee5d7cbe09fbeb3c31b9aUlrich Drepper	  if (aux == NULL)
2269acb8983909a3f031041ee5d7cbe09fbeb3c31b9aUlrich Drepper	    break;
2270acb8983909a3f031041ee5d7cbe09fbeb3c31b9aUlrich Drepper
2271acb8983909a3f031041ee5d7cbe09fbeb3c31b9aUlrich Drepper	  if ((aux->vna_flags & ~VER_FLG_WEAK) != 0)
2272acb8983909a3f031041ee5d7cbe09fbeb3c31b9aUlrich Drepper	    ERROR (gettext ("\
2273acb8983909a3f031041ee5d7cbe09fbeb3c31b9aUlrich Dreppersection [%2d] '%s': auxiliary entry %d of entry %d has unknown flag\n"),
2274acb8983909a3f031041ee5d7cbe09fbeb3c31b9aUlrich Drepper		   idx, section_name (ebl, idx), need->vn_cnt - cnt2, cnt);
2275b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper
2276acb8983909a3f031041ee5d7cbe09fbeb3c31b9aUlrich Drepper	  const char *verstr = elf_strptr (ebl->elf, shdr->sh_link,
22770a545e678f2c0605ba050b4f72080572ac7c8470Mark Wielaard					   aux->vna_name);
2278b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper	  if (verstr == NULL)
2279b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper	    ERROR (gettext ("\
2280b08d5a8fb42f4586d756068065186b5af7e48daUlrich Dreppersection [%2d] '%s': auxiliary entry %d of entry %d has invalid name reference\n"),
2281b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper		   idx, section_name (ebl, idx), need->vn_cnt - cnt2, cnt);
2282b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper	  else
2283b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper	    {
2284acb8983909a3f031041ee5d7cbe09fbeb3c31b9aUlrich Drepper	      GElf_Word hashval = elf_hash (verstr);
2285acb8983909a3f031041ee5d7cbe09fbeb3c31b9aUlrich Drepper	      if (hashval != aux->vna_hash)
2286acb8983909a3f031041ee5d7cbe09fbeb3c31b9aUlrich Drepper		ERROR (gettext ("\
2287b08d5a8fb42f4586d756068065186b5af7e48daUlrich Dreppersection [%2d] '%s': auxiliary entry %d of entry %d has wrong hash value: %#x, expected %#x\n"),
2288b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper		       idx, section_name (ebl, idx), need->vn_cnt - cnt2,
2289b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper		       cnt, (int) hashval, (int) aux->vna_hash);
2290b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper
22910a545e678f2c0605ba050b4f72080572ac7c8470Mark Wielaard	      int res = add_version (libname, verstr, aux->vna_other,
22920a545e678f2c0605ba050b4f72080572ac7c8470Mark Wielaard				     ver_need);
22930a545e678f2c0605ba050b4f72080572ac7c8470Mark Wielaard	      if (unlikely (res !=0))
22940a545e678f2c0605ba050b4f72080572ac7c8470Mark Wielaard		{
2295b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper		  assert (res > 0);
229628ed895fdc303b2a793506bb1fcdd35d5fd14e70Ulrich Drepper		  ERROR (gettext ("\
22978ae5814209558f51c93b583c9ae6fdd482f0cbb2Ulrich Dreppersection [%2d] '%s': auxiliary entry %d of entry %d has duplicate version name '%s'\n"),
22988ae5814209558f51c93b583c9ae6fdd482f0cbb2Ulrich Drepper			 idx, section_name (ebl, idx), need->vn_cnt - cnt2,
229928ed895fdc303b2a793506bb1fcdd35d5fd14e70Ulrich Drepper			 cnt, verstr);
2300b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper		}
230128ed895fdc303b2a793506bb1fcdd35d5fd14e70Ulrich Drepper	    }
2302b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper
2303b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper	  if ((aux->vna_next != 0 || cnt2 > 0)
2304b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper	      && aux->vna_next < gelf_fsize (ebl->elf, ELF_T_VNAUX, 1,
2305b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper					     EV_CURRENT))
2306b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper	    {
2307b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper	      ERROR (gettext ("\
23088ae5814209558f51c93b583c9ae6fdd482f0cbb2Ulrich Dreppersection [%2d] '%s': auxiliary entry %d of entry %d has wrong next field\n"),
2309b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper		     idx, section_name (ebl, idx), need->vn_cnt - cnt2, cnt);
2310b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper	      break;
23118ae5814209558f51c93b583c9ae6fdd482f0cbb2Ulrich Drepper	    }
2312b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper
2313b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper	  auxoffset += MAX (aux->vna_next,
2314b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper			    gelf_fsize (ebl->elf, ELF_T_VNAUX, 1, EV_CURRENT));
2315b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper	}
231628ed895fdc303b2a793506bb1fcdd35d5fd14e70Ulrich Drepper
2317b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper      /* Find the next offset.  */
231828ed895fdc303b2a793506bb1fcdd35d5fd14e70Ulrich Drepper    next_need:
231928ed895fdc303b2a793506bb1fcdd35d5fd14e70Ulrich Drepper      offset += need->vn_next;
232028ed895fdc303b2a793506bb1fcdd35d5fd14e70Ulrich Drepper
232128ed895fdc303b2a793506bb1fcdd35d5fd14e70Ulrich Drepper      if ((need->vn_next != 0 || cnt > 0)
232228ed895fdc303b2a793506bb1fcdd35d5fd14e70Ulrich Drepper	  && offset < auxoffset)
232328ed895fdc303b2a793506bb1fcdd35d5fd14e70Ulrich Drepper	ERROR (gettext ("\
2324b08d5a8fb42f4586d756068065186b5af7e48daUlrich Dreppersection [%2d] '%s': entry %d has invalid offset to next entry\n"),
232528ed895fdc303b2a793506bb1fcdd35d5fd14e70Ulrich Drepper	       idx, section_name (ebl, idx), cnt);
232628ed895fdc303b2a793506bb1fcdd35d5fd14e70Ulrich Drepper    }
232728ed895fdc303b2a793506bb1fcdd35d5fd14e70Ulrich Drepper}
2328ee4b927bae351b21787355e00a3d28371bf78e8fUlrich Drepper
232928ed895fdc303b2a793506bb1fcdd35d5fd14e70Ulrich Drepper
23308ae5814209558f51c93b583c9ae6fdd482f0cbb2Ulrich Drepperstatic unsigned int nverdef;
2331b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper
2332b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepperstatic void
2333b08d5a8fb42f4586d756068065186b5af7e48daUlrich Dreppercheck_verdef (Ebl *ebl, GElf_Shdr *shdr, int idx)
2334b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper{
23357c0e79ffc201e4828a050b35f2c9d96e3001cb48Ulrich Drepper  if (++nverdef == 2)
23367c0e79ffc201e4828a050b35f2c9d96e3001cb48Ulrich Drepper    ERROR (gettext ("more than one version definition section present\n"));
23377c0e79ffc201e4828a050b35f2c9d96e3001cb48Ulrich Drepper
23387c0e79ffc201e4828a050b35f2c9d96e3001cb48Ulrich Drepper  GElf_Shdr strshdr_mem;
23397c0e79ffc201e4828a050b35f2c9d96e3001cb48Ulrich Drepper  GElf_Shdr *strshdr = gelf_getshdr (elf_getscn (ebl->elf, shdr->sh_link),
23407c0e79ffc201e4828a050b35f2c9d96e3001cb48Ulrich Drepper				     &strshdr_mem);
23417c0e79ffc201e4828a050b35f2c9d96e3001cb48Ulrich Drepper  if (strshdr == NULL)
23427c0e79ffc201e4828a050b35f2c9d96e3001cb48Ulrich Drepper    return;
23437c0e79ffc201e4828a050b35f2c9d96e3001cb48Ulrich Drepper  if (strshdr->sh_type != SHT_STRTAB)
23447c0e79ffc201e4828a050b35f2c9d96e3001cb48Ulrich Drepper    ERROR (gettext ("\
23457c0e79ffc201e4828a050b35f2c9d96e3001cb48Ulrich Dreppersection [%2d] '%s': sh_link does not link to string table\n"),
23467c0e79ffc201e4828a050b35f2c9d96e3001cb48Ulrich Drepper	   idx, section_name (ebl, idx));
23477c0e79ffc201e4828a050b35f2c9d96e3001cb48Ulrich Drepper
23487c0e79ffc201e4828a050b35f2c9d96e3001cb48Ulrich Drepper  Elf_Data *data = elf_getdata (elf_getscn (ebl->elf, idx), NULL);
23497c0e79ffc201e4828a050b35f2c9d96e3001cb48Ulrich Drepper  if (data == NULL)
23500a545e678f2c0605ba050b4f72080572ac7c8470Mark Wielaard    {
23510a545e678f2c0605ba050b4f72080572ac7c8470Mark Wielaard    no_data:
23527c0e79ffc201e4828a050b35f2c9d96e3001cb48Ulrich Drepper      ERROR (gettext ("section [%2d] '%s': cannot get section data\n"),
23537c0e79ffc201e4828a050b35f2c9d96e3001cb48Ulrich Drepper	     idx, section_name (ebl, idx));
23547c0e79ffc201e4828a050b35f2c9d96e3001cb48Ulrich Drepper      return;
23557c0e79ffc201e4828a050b35f2c9d96e3001cb48Ulrich Drepper    }
23567c0e79ffc201e4828a050b35f2c9d96e3001cb48Ulrich Drepper
23577c0e79ffc201e4828a050b35f2c9d96e3001cb48Ulrich Drepper  /* Iterate over all version definition entries.  We check that there
23587c0e79ffc201e4828a050b35f2c9d96e3001cb48Ulrich Drepper     is a BASE entry and that each index is unique.  To do the later
23597c0e79ffc201e4828a050b35f2c9d96e3001cb48Ulrich Drepper     we collection the information in a list which is later
23607c0e79ffc201e4828a050b35f2c9d96e3001cb48Ulrich Drepper     examined.  */
23617c0e79ffc201e4828a050b35f2c9d96e3001cb48Ulrich Drepper  struct namelist
23627c0e79ffc201e4828a050b35f2c9d96e3001cb48Ulrich Drepper  {
23637c0e79ffc201e4828a050b35f2c9d96e3001cb48Ulrich Drepper    const char *name;
23647c0e79ffc201e4828a050b35f2c9d96e3001cb48Ulrich Drepper    struct namelist *next;
23657c0e79ffc201e4828a050b35f2c9d96e3001cb48Ulrich Drepper  } *namelist = NULL;
23667c0e79ffc201e4828a050b35f2c9d96e3001cb48Ulrich Drepper  struct namelist *refnamelist = NULL;
23677c0e79ffc201e4828a050b35f2c9d96e3001cb48Ulrich Drepper
23687c0e79ffc201e4828a050b35f2c9d96e3001cb48Ulrich Drepper  bool has_base = false;
23697c0e79ffc201e4828a050b35f2c9d96e3001cb48Ulrich Drepper  unsigned int offset = 0;
23707c0e79ffc201e4828a050b35f2c9d96e3001cb48Ulrich Drepper  for (int cnt = shdr->sh_info; --cnt >= 0; )
23717c0e79ffc201e4828a050b35f2c9d96e3001cb48Ulrich Drepper    {
23720a545e678f2c0605ba050b4f72080572ac7c8470Mark Wielaard      /* Get the data at the next offset.  */
23730a545e678f2c0605ba050b4f72080572ac7c8470Mark Wielaard      GElf_Verdef defmem;
23747c0e79ffc201e4828a050b35f2c9d96e3001cb48Ulrich Drepper      GElf_Verdef *def = gelf_getverdef (data, offset, &defmem);
23757c0e79ffc201e4828a050b35f2c9d96e3001cb48Ulrich Drepper      if (def == NULL)
23760a545e678f2c0605ba050b4f72080572ac7c8470Mark Wielaard	goto no_data;
23770a545e678f2c0605ba050b4f72080572ac7c8470Mark Wielaard
23780a545e678f2c0605ba050b4f72080572ac7c8470Mark Wielaard      if ((def->vd_flags & VER_FLG_BASE) != 0)
23790a545e678f2c0605ba050b4f72080572ac7c8470Mark Wielaard	{
23800a545e678f2c0605ba050b4f72080572ac7c8470Mark Wielaard	  if (has_base)
23810a545e678f2c0605ba050b4f72080572ac7c8470Mark Wielaard	    ERROR (gettext ("\
23820a545e678f2c0605ba050b4f72080572ac7c8470Mark Wielaardsection [%2d] '%s': more than one BASE definition\n"),
23830a545e678f2c0605ba050b4f72080572ac7c8470Mark Wielaard		   idx, section_name (ebl, idx));
23840a545e678f2c0605ba050b4f72080572ac7c8470Mark Wielaard	  if (def->vd_ndx != VER_NDX_GLOBAL)
23850a545e678f2c0605ba050b4f72080572ac7c8470Mark Wielaard	    ERROR (gettext ("\
23860a545e678f2c0605ba050b4f72080572ac7c8470Mark Wielaardsection [%2d] '%s': BASE definition must have index VER_NDX_GLOBAL\n"),
23870a545e678f2c0605ba050b4f72080572ac7c8470Mark Wielaard		   idx, section_name (ebl, idx));
23880a545e678f2c0605ba050b4f72080572ac7c8470Mark Wielaard	  has_base = true;
23890a545e678f2c0605ba050b4f72080572ac7c8470Mark Wielaard	}
23907c0e79ffc201e4828a050b35f2c9d96e3001cb48Ulrich Drepper      if ((def->vd_flags & ~(VER_FLG_BASE|VER_FLG_WEAK)) != 0)
23917c0e79ffc201e4828a050b35f2c9d96e3001cb48Ulrich Drepper	ERROR (gettext ("\
23927c0e79ffc201e4828a050b35f2c9d96e3001cb48Ulrich Dreppersection [%2d] '%s': entry %d has unknown flag\n"),
23937c0e79ffc201e4828a050b35f2c9d96e3001cb48Ulrich Drepper	       idx, section_name (ebl, idx), cnt);
23947c0e79ffc201e4828a050b35f2c9d96e3001cb48Ulrich Drepper
23957c0e79ffc201e4828a050b35f2c9d96e3001cb48Ulrich Drepper      if (def->vd_version != EV_CURRENT)
23960a545e678f2c0605ba050b4f72080572ac7c8470Mark Wielaard	ERROR (gettext ("\
23977c0e79ffc201e4828a050b35f2c9d96e3001cb48Ulrich Dreppersection [%2d] '%s': entry %d has wrong version %d\n"),
23987c0e79ffc201e4828a050b35f2c9d96e3001cb48Ulrich Drepper	       idx, section_name (ebl, idx), cnt, (int) def->vd_version);
23997c0e79ffc201e4828a050b35f2c9d96e3001cb48Ulrich Drepper
24000a545e678f2c0605ba050b4f72080572ac7c8470Mark Wielaard      if (def->vd_cnt > 0 && def->vd_aux < gelf_fsize (ebl->elf, ELF_T_VDEF,
24010a545e678f2c0605ba050b4f72080572ac7c8470Mark Wielaard						       1, EV_CURRENT))
24020a545e678f2c0605ba050b4f72080572ac7c8470Mark Wielaard	ERROR (gettext ("\
24030a545e678f2c0605ba050b4f72080572ac7c8470Mark Wielaardsection [%2d] '%s': entry %d has wrong offset of auxiliary data\n"),
24040a545e678f2c0605ba050b4f72080572ac7c8470Mark Wielaard	       idx, section_name (ebl, idx), cnt);
24050a545e678f2c0605ba050b4f72080572ac7c8470Mark Wielaard
24060a545e678f2c0605ba050b4f72080572ac7c8470Mark Wielaard      unsigned int auxoffset = offset + def->vd_aux;
24070a545e678f2c0605ba050b4f72080572ac7c8470Mark Wielaard      GElf_Verdaux auxmem;
24080a545e678f2c0605ba050b4f72080572ac7c8470Mark Wielaard      GElf_Verdaux *aux = gelf_getverdaux (data, auxoffset, &auxmem);
24090a545e678f2c0605ba050b4f72080572ac7c8470Mark Wielaard      if (aux == NULL)
24100a545e678f2c0605ba050b4f72080572ac7c8470Mark Wielaard	goto no_data;
24110a545e678f2c0605ba050b4f72080572ac7c8470Mark Wielaard
24120a545e678f2c0605ba050b4f72080572ac7c8470Mark Wielaard      const char *name = elf_strptr (ebl->elf, shdr->sh_link, aux->vda_name);
24130a545e678f2c0605ba050b4f72080572ac7c8470Mark Wielaard      if (name == NULL)
24140a545e678f2c0605ba050b4f72080572ac7c8470Mark Wielaard	{
24150a545e678f2c0605ba050b4f72080572ac7c8470Mark Wielaard	  ERROR (gettext ("\
24160a545e678f2c0605ba050b4f72080572ac7c8470Mark Wielaardsection [%2d] '%s': entry %d has invalid name reference\n"),
24170a545e678f2c0605ba050b4f72080572ac7c8470Mark Wielaard		 idx, section_name (ebl, idx), cnt);
24180a545e678f2c0605ba050b4f72080572ac7c8470Mark Wielaard	  goto next_def;
24190a545e678f2c0605ba050b4f72080572ac7c8470Mark Wielaard	}
24207c0e79ffc201e4828a050b35f2c9d96e3001cb48Ulrich Drepper      GElf_Word hashval = elf_hash (name);
24217c0e79ffc201e4828a050b35f2c9d96e3001cb48Ulrich Drepper      if (def->vd_hash != hashval)
24227c0e79ffc201e4828a050b35f2c9d96e3001cb48Ulrich Drepper	ERROR (gettext ("\
2423ae9aa3e4b2853d58598a6928eb1dbaacf6488496Mark Wielaardsection [%2d] '%s': entry %d has wrong hash value: %#x, expected %#x\n"),
2424ae9aa3e4b2853d58598a6928eb1dbaacf6488496Mark Wielaard	       idx, section_name (ebl, idx), cnt, (int) hashval,
2425ae9aa3e4b2853d58598a6928eb1dbaacf6488496Mark Wielaard	       (int) def->vd_hash);
2426ae9aa3e4b2853d58598a6928eb1dbaacf6488496Mark Wielaard
2427ae9aa3e4b2853d58598a6928eb1dbaacf6488496Mark Wielaard      int res = add_version (NULL, name, def->vd_ndx, ver_def);
2428ae9aa3e4b2853d58598a6928eb1dbaacf6488496Mark Wielaard      if (unlikely (res !=0))
2429ae9aa3e4b2853d58598a6928eb1dbaacf6488496Mark Wielaard	{
2430ae9aa3e4b2853d58598a6928eb1dbaacf6488496Mark Wielaard	  assert (res > 0);
2431ae9aa3e4b2853d58598a6928eb1dbaacf6488496Mark Wielaard	  ERROR (gettext ("\
2432ae9aa3e4b2853d58598a6928eb1dbaacf6488496Mark Wielaardsection [%2d] '%s': entry %d has duplicate version name '%s'\n"),
2433ae9aa3e4b2853d58598a6928eb1dbaacf6488496Mark Wielaard		 idx, section_name (ebl, idx), cnt, name);
2434ae9aa3e4b2853d58598a6928eb1dbaacf6488496Mark Wielaard	}
2435ae9aa3e4b2853d58598a6928eb1dbaacf6488496Mark Wielaard
2436ae9aa3e4b2853d58598a6928eb1dbaacf6488496Mark Wielaard      struct namelist *newname = alloca (sizeof (*newname));
2437ae9aa3e4b2853d58598a6928eb1dbaacf6488496Mark Wielaard      newname->name = name;
2438ae9aa3e4b2853d58598a6928eb1dbaacf6488496Mark Wielaard      newname->next = namelist;
24397c0e79ffc201e4828a050b35f2c9d96e3001cb48Ulrich Drepper      namelist = newname;
24407c0e79ffc201e4828a050b35f2c9d96e3001cb48Ulrich Drepper
24417c0e79ffc201e4828a050b35f2c9d96e3001cb48Ulrich Drepper      auxoffset += aux->vda_next;
24427c0e79ffc201e4828a050b35f2c9d96e3001cb48Ulrich Drepper      for (int cnt2 = 1; cnt2 < def->vd_cnt; ++cnt2)
24437c0e79ffc201e4828a050b35f2c9d96e3001cb48Ulrich Drepper	{
24447c0e79ffc201e4828a050b35f2c9d96e3001cb48Ulrich Drepper	  aux = gelf_getverdaux (data, auxoffset, &auxmem);
24457c0e79ffc201e4828a050b35f2c9d96e3001cb48Ulrich Drepper	  if (aux == NULL)
24460a545e678f2c0605ba050b4f72080572ac7c8470Mark Wielaard	    goto no_data;
24470a545e678f2c0605ba050b4f72080572ac7c8470Mark Wielaard
24480a545e678f2c0605ba050b4f72080572ac7c8470Mark Wielaard	  name = elf_strptr (ebl->elf, shdr->sh_link, aux->vda_name);
24490a545e678f2c0605ba050b4f72080572ac7c8470Mark Wielaard	  if (name == NULL)
24500a545e678f2c0605ba050b4f72080572ac7c8470Mark Wielaard	    ERROR (gettext ("\
24510a545e678f2c0605ba050b4f72080572ac7c8470Mark Wielaardsection [%2d] '%s': entry %d has invalid name reference in auxiliary data\n"),
24520a545e678f2c0605ba050b4f72080572ac7c8470Mark Wielaard		   idx, section_name (ebl, idx), cnt);
24530a545e678f2c0605ba050b4f72080572ac7c8470Mark Wielaard	  else
24547c0e79ffc201e4828a050b35f2c9d96e3001cb48Ulrich Drepper	    {
24550a545e678f2c0605ba050b4f72080572ac7c8470Mark Wielaard	      newname = alloca (sizeof (*newname));
24560a545e678f2c0605ba050b4f72080572ac7c8470Mark Wielaard	      newname->name = name;
24570a545e678f2c0605ba050b4f72080572ac7c8470Mark Wielaard	      newname->next = refnamelist;
24580a545e678f2c0605ba050b4f72080572ac7c8470Mark Wielaard	      refnamelist = newname;
24590a545e678f2c0605ba050b4f72080572ac7c8470Mark Wielaard	    }
24600a545e678f2c0605ba050b4f72080572ac7c8470Mark Wielaard
24610a545e678f2c0605ba050b4f72080572ac7c8470Mark Wielaard	  if ((aux->vda_next != 0 || cnt2 + 1 < def->vd_cnt)
24620a545e678f2c0605ba050b4f72080572ac7c8470Mark Wielaard	      && aux->vda_next < gelf_fsize (ebl->elf, ELF_T_VDAUX, 1,
24630a545e678f2c0605ba050b4f72080572ac7c8470Mark Wielaard					     EV_CURRENT))
24640a545e678f2c0605ba050b4f72080572ac7c8470Mark Wielaard	    {
24657c0e79ffc201e4828a050b35f2c9d96e3001cb48Ulrich Drepper	      ERROR (gettext ("\
24667c0e79ffc201e4828a050b35f2c9d96e3001cb48Ulrich Dreppersection [%2d] '%s': entry %d has wrong next field in auxiliary data\n"),
24677c0e79ffc201e4828a050b35f2c9d96e3001cb48Ulrich Drepper		     idx, section_name (ebl, idx), cnt);
24687c0e79ffc201e4828a050b35f2c9d96e3001cb48Ulrich Drepper	      break;
24697c0e79ffc201e4828a050b35f2c9d96e3001cb48Ulrich Drepper	    }
24707c0e79ffc201e4828a050b35f2c9d96e3001cb48Ulrich Drepper
24710a545e678f2c0605ba050b4f72080572ac7c8470Mark Wielaard	  auxoffset += MAX (aux->vda_next,
24727c0e79ffc201e4828a050b35f2c9d96e3001cb48Ulrich Drepper			    gelf_fsize (ebl->elf, ELF_T_VDAUX, 1, EV_CURRENT));
24737c0e79ffc201e4828a050b35f2c9d96e3001cb48Ulrich Drepper	}
24747c0e79ffc201e4828a050b35f2c9d96e3001cb48Ulrich Drepper
24757c0e79ffc201e4828a050b35f2c9d96e3001cb48Ulrich Drepper      /* Find the next offset.  */
24767c0e79ffc201e4828a050b35f2c9d96e3001cb48Ulrich Drepper    next_def:
24777c0e79ffc201e4828a050b35f2c9d96e3001cb48Ulrich Drepper      offset += def->vd_next;
24780a545e678f2c0605ba050b4f72080572ac7c8470Mark Wielaard
24797c0e79ffc201e4828a050b35f2c9d96e3001cb48Ulrich Drepper      if ((def->vd_next != 0 || cnt > 0)
24807c0e79ffc201e4828a050b35f2c9d96e3001cb48Ulrich Drepper	  && offset < auxoffset)
24810a545e678f2c0605ba050b4f72080572ac7c8470Mark Wielaard	ERROR (gettext ("\
24820a545e678f2c0605ba050b4f72080572ac7c8470Mark Wielaardsection [%2d] '%s': entry %d has invalid offset to next entry\n"),
24830a545e678f2c0605ba050b4f72080572ac7c8470Mark Wielaard	       idx, section_name (ebl, idx), cnt);
24840a545e678f2c0605ba050b4f72080572ac7c8470Mark Wielaard    }
24850a545e678f2c0605ba050b4f72080572ac7c8470Mark Wielaard
24860a545e678f2c0605ba050b4f72080572ac7c8470Mark Wielaard  if (!has_base)
24870a545e678f2c0605ba050b4f72080572ac7c8470Mark Wielaard    ERROR (gettext ("section [%2d] '%s': no BASE definition\n"),
24880a545e678f2c0605ba050b4f72080572ac7c8470Mark Wielaard	   idx, section_name (ebl, idx));
24897c0e79ffc201e4828a050b35f2c9d96e3001cb48Ulrich Drepper
24900a545e678f2c0605ba050b4f72080572ac7c8470Mark Wielaard  /* Check whether the referenced names are available.  */
24910a545e678f2c0605ba050b4f72080572ac7c8470Mark Wielaard  while (namelist != NULL)
24920a545e678f2c0605ba050b4f72080572ac7c8470Mark Wielaard    {
24930a545e678f2c0605ba050b4f72080572ac7c8470Mark Wielaard      struct version_namelist *runp = version_namelist;
24940a545e678f2c0605ba050b4f72080572ac7c8470Mark Wielaard      while (runp != NULL)
24950a545e678f2c0605ba050b4f72080572ac7c8470Mark Wielaard	{
24960a545e678f2c0605ba050b4f72080572ac7c8470Mark Wielaard	  if (runp->type == ver_def
24970a545e678f2c0605ba050b4f72080572ac7c8470Mark Wielaard	      && strcmp (runp->name, namelist->name) == 0)
24980a545e678f2c0605ba050b4f72080572ac7c8470Mark Wielaard	    break;
24990a545e678f2c0605ba050b4f72080572ac7c8470Mark Wielaard	  runp = runp->next;
25000a545e678f2c0605ba050b4f72080572ac7c8470Mark Wielaard	}
25010a545e678f2c0605ba050b4f72080572ac7c8470Mark Wielaard
25027c0e79ffc201e4828a050b35f2c9d96e3001cb48Ulrich Drepper      if (runp == NULL)
25037c0e79ffc201e4828a050b35f2c9d96e3001cb48Ulrich Drepper	ERROR (gettext ("\
25047c0e79ffc201e4828a050b35f2c9d96e3001cb48Ulrich Dreppersection [%2d] '%s': unknown parent version '%s'\n"),
25057c0e79ffc201e4828a050b35f2c9d96e3001cb48Ulrich Drepper	       idx, section_name (ebl, idx), namelist->name);
25067c0e79ffc201e4828a050b35f2c9d96e3001cb48Ulrich Drepper
25077c0e79ffc201e4828a050b35f2c9d96e3001cb48Ulrich Drepper      namelist = namelist->next;
25080a545e678f2c0605ba050b4f72080572ac7c8470Mark Wielaard    }
25097c0e79ffc201e4828a050b35f2c9d96e3001cb48Ulrich Drepper}
25107c0e79ffc201e4828a050b35f2c9d96e3001cb48Ulrich Drepper
25117c0e79ffc201e4828a050b35f2c9d96e3001cb48Ulrich Drepper
25127c0e79ffc201e4828a050b35f2c9d96e3001cb48Ulrich Drepperstatic bool has_loadable_segment;
25137c0e79ffc201e4828a050b35f2c9d96e3001cb48Ulrich Drepperstatic bool has_interp_segment;
25147c0e79ffc201e4828a050b35f2c9d96e3001cb48Ulrich Drepper
25150a545e678f2c0605ba050b4f72080572ac7c8470Mark Wielaardstatic const struct
25160a545e678f2c0605ba050b4f72080572ac7c8470Mark Wielaard{
25170a545e678f2c0605ba050b4f72080572ac7c8470Mark Wielaard  const char *name;
25180a545e678f2c0605ba050b4f72080572ac7c8470Mark Wielaard  size_t namelen;
25190a545e678f2c0605ba050b4f72080572ac7c8470Mark Wielaard  GElf_Word type;
25200a545e678f2c0605ba050b4f72080572ac7c8470Mark Wielaard  enum { unused, exact, atleast } attrflag;
25210a545e678f2c0605ba050b4f72080572ac7c8470Mark Wielaard  GElf_Word attr;
25227c0e79ffc201e4828a050b35f2c9d96e3001cb48Ulrich Drepper  GElf_Word attr2;
25237c0e79ffc201e4828a050b35f2c9d96e3001cb48Ulrich Drepper} special_sections[] =
25247c0e79ffc201e4828a050b35f2c9d96e3001cb48Ulrich Drepper  {
25257c0e79ffc201e4828a050b35f2c9d96e3001cb48Ulrich Drepper    /* See figure 4-14 in the gABI.  */
25267c0e79ffc201e4828a050b35f2c9d96e3001cb48Ulrich Drepper    { ".bss", 5, SHT_NOBITS, exact, SHF_ALLOC | SHF_WRITE, 0 },
25277c0e79ffc201e4828a050b35f2c9d96e3001cb48Ulrich Drepper    { ".comment", 8, SHT_PROGBITS, exact, 0, 0 },
25287c0e79ffc201e4828a050b35f2c9d96e3001cb48Ulrich Drepper    { ".data", 6, SHT_PROGBITS, exact, SHF_ALLOC | SHF_WRITE, 0 },
25297c0e79ffc201e4828a050b35f2c9d96e3001cb48Ulrich Drepper    { ".data1", 7, SHT_PROGBITS, exact, SHF_ALLOC | SHF_WRITE, 0 },
25307c0e79ffc201e4828a050b35f2c9d96e3001cb48Ulrich Drepper    { ".debug", 7, SHT_PROGBITS, exact, 0, 0 },
25317c0e79ffc201e4828a050b35f2c9d96e3001cb48Ulrich Drepper    { ".dynamic", 9, SHT_DYNAMIC, atleast, SHF_ALLOC, SHF_WRITE },
25327c0e79ffc201e4828a050b35f2c9d96e3001cb48Ulrich Drepper    { ".dynstr", 8, SHT_STRTAB, exact, SHF_ALLOC, 0 },
25337c0e79ffc201e4828a050b35f2c9d96e3001cb48Ulrich Drepper    { ".dynsym", 8, SHT_DYNSYM, exact, SHF_ALLOC, 0 },
25340a545e678f2c0605ba050b4f72080572ac7c8470Mark Wielaard    { ".fini", 6, SHT_PROGBITS, exact, SHF_ALLOC | SHF_EXECINSTR, 0 },
25357c0e79ffc201e4828a050b35f2c9d96e3001cb48Ulrich Drepper    { ".fini_array", 12, SHT_FINI_ARRAY, exact, SHF_ALLOC | SHF_WRITE, 0 },
25367c0e79ffc201e4828a050b35f2c9d96e3001cb48Ulrich Drepper    { ".got", 5, SHT_PROGBITS, unused, 0, 0 }, // XXX more info?
25377c0e79ffc201e4828a050b35f2c9d96e3001cb48Ulrich Drepper    { ".hash", 6, SHT_HASH, exact, SHF_ALLOC, 0 },
25387c0e79ffc201e4828a050b35f2c9d96e3001cb48Ulrich Drepper    { ".init", 6, SHT_PROGBITS, exact, SHF_ALLOC | SHF_EXECINSTR, 0 },
25397c0e79ffc201e4828a050b35f2c9d96e3001cb48Ulrich Drepper    { ".init_array", 12, SHT_INIT_ARRAY, exact, SHF_ALLOC | SHF_WRITE, 0 },
25407c0e79ffc201e4828a050b35f2c9d96e3001cb48Ulrich Drepper    { ".interp", 8, SHT_PROGBITS, atleast, 0, SHF_ALLOC }, // XXX more tests?
25417c0e79ffc201e4828a050b35f2c9d96e3001cb48Ulrich Drepper    { ".line", 6, SHT_PROGBITS, exact, 0, 0 },
25427c0e79ffc201e4828a050b35f2c9d96e3001cb48Ulrich Drepper    { ".note", 6, SHT_NOTE, exact, 0, 0 },
25437c0e79ffc201e4828a050b35f2c9d96e3001cb48Ulrich Drepper    { ".plt", 5, SHT_PROGBITS, unused, 0, 0 }, // XXX more tests
25447c0e79ffc201e4828a050b35f2c9d96e3001cb48Ulrich Drepper    { ".preinit_array", 15, SHT_PREINIT_ARRAY, exact, SHF_ALLOC | SHF_WRITE, 0 },
25457c0e79ffc201e4828a050b35f2c9d96e3001cb48Ulrich Drepper    { ".rela", 5, SHT_RELA, atleast, 0, SHF_ALLOC }, // XXX more tests
25467c0e79ffc201e4828a050b35f2c9d96e3001cb48Ulrich Drepper    { ".rel", 4, SHT_REL, atleast, 0, SHF_ALLOC }, // XXX more tests
25477c0e79ffc201e4828a050b35f2c9d96e3001cb48Ulrich Drepper    { ".rodata", 8, SHT_PROGBITS, atleast, SHF_ALLOC, SHF_MERGE | SHF_STRINGS },
25487c0e79ffc201e4828a050b35f2c9d96e3001cb48Ulrich Drepper    { ".rodata1", 9, SHT_PROGBITS, atleast, SHF_ALLOC, SHF_MERGE | SHF_STRINGS },
25497c0e79ffc201e4828a050b35f2c9d96e3001cb48Ulrich Drepper    { ".shstrtab", 10, SHT_STRTAB, exact, 0, 0 },
25507c0e79ffc201e4828a050b35f2c9d96e3001cb48Ulrich Drepper    { ".strtab", 8, SHT_STRTAB, atleast, 0, SHF_ALLOC }, // XXX more tests
25517c0e79ffc201e4828a050b35f2c9d96e3001cb48Ulrich Drepper    { ".symtab", 8, SHT_SYMTAB, atleast, 0, SHF_ALLOC }, // XXX more tests
25527c0e79ffc201e4828a050b35f2c9d96e3001cb48Ulrich Drepper    { ".symtab_shndx", 14, SHT_SYMTAB_SHNDX, atleast, 0, SHF_ALLOC }, // XXX more tests
25537c0e79ffc201e4828a050b35f2c9d96e3001cb48Ulrich Drepper    { ".tbss", 6, SHT_NOBITS, exact, SHF_ALLOC | SHF_WRITE | SHF_TLS, 0 },
25547c0e79ffc201e4828a050b35f2c9d96e3001cb48Ulrich Drepper    { ".tdata", 7, SHT_PROGBITS, exact, SHF_ALLOC | SHF_WRITE | SHF_TLS, 0 },
25557c0e79ffc201e4828a050b35f2c9d96e3001cb48Ulrich Drepper    { ".tdata1", 8, SHT_PROGBITS, exact, SHF_ALLOC | SHF_WRITE | SHF_TLS, 0 },
25567c0e79ffc201e4828a050b35f2c9d96e3001cb48Ulrich Drepper    { ".text", 6, SHT_PROGBITS, exact, SHF_ALLOC | SHF_EXECINSTR, 0 },
25577c0e79ffc201e4828a050b35f2c9d96e3001cb48Ulrich Drepper
25587c0e79ffc201e4828a050b35f2c9d96e3001cb48Ulrich Drepper    /* The following are GNU extensions.  */
25597c0e79ffc201e4828a050b35f2c9d96e3001cb48Ulrich Drepper    { ".gnu.version", 13, SHT_GNU_versym, exact, SHF_ALLOC, 0 },
25607c0e79ffc201e4828a050b35f2c9d96e3001cb48Ulrich Drepper    { ".gnu.version_d", 15, SHT_GNU_verdef, exact, SHF_ALLOC, 0 },
2561b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper    { ".gnu.version_r", 15, SHT_GNU_verneed, exact, SHF_ALLOC, 0 }
2562b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper  };
2563b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper#define nspecial_sections \
2564b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper  (sizeof (special_sections) / sizeof (special_sections[0]))
2565b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper
2566b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper
2567b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepperstatic void
2568b08d5a8fb42f4586d756068065186b5af7e48daUlrich Dreppercheck_sections (Ebl *ebl, GElf_Ehdr *ehdr)
2569b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper{
2570b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper  if (ehdr->e_shoff == 0)
2571b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper    /* No section header.  */
2572b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper    return;
2573b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper
2574b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper  /* Allocate array to count references in section groups.  */
2575b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper  scnref = (int *) xcalloc (shnum, sizeof (int));
2576b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper
2577b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper  /* Check the zeroth section first.  It must not have any contents
2578b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper     and the section header must contain nonzero value at most in the
2579b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper     sh_size and sh_link fields.  */
2580b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper  GElf_Shdr shdr_mem;
2581b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper  GElf_Shdr *shdr = gelf_getshdr (elf_getscn (ebl->elf, 0), &shdr_mem);
2582b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper  if (shdr == NULL)
2583b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper    ERROR (gettext ("cannot get section header of zeroth section\n"));
2584b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper  else
2585b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper    {
2586b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper      if (shdr->sh_name != 0)
2587b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper	ERROR (gettext ("zeroth section has nonzero name\n"));
2588b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper      if (shdr->sh_type != 0)
2589b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper	ERROR (gettext ("zeroth section has nonzero type\n"));
2590b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper      if (shdr->sh_flags != 0)
2591b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper	ERROR (gettext ("zeroth section has nonzero flags\n"));
2592b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper      if (shdr->sh_addr != 0)
25930e864dd86871c809668c557985ca19344dfff787Ulrich Drepper	ERROR (gettext ("zeroth section has nonzero address\n"));
2594b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper      if (shdr->sh_offset != 0)
25950e864dd86871c809668c557985ca19344dfff787Ulrich Drepper	ERROR (gettext ("zeroth section has nonzero offset\n"));
2596b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper      if (shdr->sh_info != 0)
2597b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper	ERROR (gettext ("zeroth section has nonzero info field\n"));
2598b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper      if (shdr->sh_addralign != 0)
2599b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper	ERROR (gettext ("zeroth section has nonzero align value\n"));
2600b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper      if (shdr->sh_entsize != 0)
2601b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper	ERROR (gettext ("zeroth section has nonzero entry size value\n"));
2602b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper
2603b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper      if (shdr->sh_size != 0 && ehdr->e_shnum != 0)
2604b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper	ERROR (gettext ("\
2605b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepperzeroth section has nonzero size value while ELF header has nonzero shnum value\n"));
2606b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper
2607b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper      if (shdr->sh_link != 0 && ehdr->e_shstrndx != SHN_XINDEX)
2608b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper	ERROR (gettext ("\
2609b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepperzeroth section has nonzero link value while ELF header does not signal overflow in shstrndx\n"));
2610b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper    }
2611b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper
2612b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper  bool dot_interp_section = false;
2613b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper
2614b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper  size_t versym_scnndx = 0;
2615b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper  for (size_t cnt = 1; cnt < shnum; ++cnt)
26160e864dd86871c809668c557985ca19344dfff787Ulrich Drepper    {
26170e864dd86871c809668c557985ca19344dfff787Ulrich Drepper      shdr = gelf_getshdr (elf_getscn (ebl->elf, cnt), &shdr_mem);
26180e864dd86871c809668c557985ca19344dfff787Ulrich Drepper      if (shdr == NULL)
26190e864dd86871c809668c557985ca19344dfff787Ulrich Drepper	{
26200e864dd86871c809668c557985ca19344dfff787Ulrich Drepper	  ERROR (gettext ("\
26210e864dd86871c809668c557985ca19344dfff787Ulrich Dreppercannot get section header for section [%2zu] '%s': %s\n"),
26220e864dd86871c809668c557985ca19344dfff787Ulrich Drepper		 cnt, section_name (ebl, cnt), elf_errmsg (-1));
26230a545e678f2c0605ba050b4f72080572ac7c8470Mark Wielaard	  continue;
26240a545e678f2c0605ba050b4f72080572ac7c8470Mark Wielaard	}
26250a545e678f2c0605ba050b4f72080572ac7c8470Mark Wielaard
26260a545e678f2c0605ba050b4f72080572ac7c8470Mark Wielaard      const char *scnname = elf_strptr (ebl->elf, shstrndx, shdr->sh_name);
26270e864dd86871c809668c557985ca19344dfff787Ulrich Drepper
26280e864dd86871c809668c557985ca19344dfff787Ulrich Drepper      if (scnname == NULL)
26290e864dd86871c809668c557985ca19344dfff787Ulrich Drepper	ERROR (gettext ("section [%2zu]: invalid name\n"), cnt);
26303b495d8e963eead963a37b5be5b063c96bb58c63Roland McGrath      else
26310e864dd86871c809668c557985ca19344dfff787Ulrich Drepper	{
26320e864dd86871c809668c557985ca19344dfff787Ulrich Drepper	  /* Check whether it is one of the special sections defined in
2633b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper	     the gABI.  */
2634b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper	  size_t s;
2635b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper	  for (s = 0; s < nspecial_sections; ++s)
2636b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper	    if (strncmp (scnname, special_sections[s].name,
2637b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper			 special_sections[s].namelen) == 0)
2638b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper	      {
2639b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper		char stbuf1[100];
26400a545e678f2c0605ba050b4f72080572ac7c8470Mark Wielaard		char stbuf2[100];
2641b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper		char stbuf3[100];
2642b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper
2643b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper		GElf_Word good_type = special_sections[s].type;
2644b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper		if (special_sections[s].namelen == sizeof ".plt" &&
2645b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper		    !memcmp (special_sections[s].name, ".plt", sizeof ".plt")
2646b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper		    && ebl_bss_plt_p (ebl, ehdr))
2647b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper		  good_type = SHT_NOBITS;
2648b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper
2649b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper		if (shdr->sh_type != good_type
2650b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper		    && !(is_debuginfo && shdr->sh_type == SHT_NOBITS))
2651b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper		  ERROR (gettext ("\
2652b08d5a8fb42f4586d756068065186b5af7e48daUlrich Dreppersection [%2d] '%s' has wrong type: expected %s, is %s\n"),
2653b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper			 (int) cnt, scnname,
2654b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper			 ebl_section_type_name (ebl, special_sections[s].type,
2655b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper						stbuf1, sizeof (stbuf1)),
2656b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper			 ebl_section_type_name (ebl, shdr->sh_type,
2657b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper						stbuf2, sizeof (stbuf2)));
2658b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper
2659b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper		if (special_sections[s].attrflag == exact)
2660b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper		  {
2661b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper		    /* Except for the link order and group bit all the
2662b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper		       other bits should match exactly.  */
2663b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper		    if ((shdr->sh_flags & ~(SHF_LINK_ORDER | SHF_GROUP))
2664b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper			!= special_sections[s].attr)
2665b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper		      ERROR (gettext ("\
2666b08d5a8fb42f4586d756068065186b5af7e48daUlrich Dreppersection [%2zu] '%s' has wrong flags: expected %s, is %s\n"),
2667b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper			     cnt, scnname,
2668b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper			     section_flags_string (special_sections[s].attr,
2669b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper						   stbuf1, sizeof (stbuf1)),
2670b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper			     section_flags_string (shdr->sh_flags
2671b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper						   & ~SHF_LINK_ORDER,
2672b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper						   stbuf2, sizeof (stbuf2)));
2673b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper		  }
2674b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper		else if (special_sections[s].attrflag == atleast)
2675b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper		  {
2676b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper		    if ((shdr->sh_flags & special_sections[s].attr)
2677b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper			!= special_sections[s].attr
2678b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper			|| ((shdr->sh_flags & ~(SHF_LINK_ORDER | SHF_GROUP
2679b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper						| special_sections[s].attr
2680b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper						| special_sections[s].attr2))
2681b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper			    != 0))
2682b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper		      ERROR (gettext ("\
2683b08d5a8fb42f4586d756068065186b5af7e48daUlrich Dreppersection [%2zu] '%s' has wrong flags: expected %s and possibly %s, is %s\n"),
2684b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper			     cnt, scnname,
2685b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper			     section_flags_string (special_sections[s].attr,
2686b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper						   stbuf1, sizeof (stbuf1)),
2687b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper			     section_flags_string (special_sections[s].attr2,
2688b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper						   stbuf2, sizeof (stbuf2)),
26892ec957327cdfae6cee592a52958a9c937ea4b13cChih-Hung Hsieh			     section_flags_string (shdr->sh_flags
2690b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper						   & ~(SHF_LINK_ORDER
2691b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper						       | SHF_GROUP),
2692b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper						   stbuf3, sizeof (stbuf3)));
2693b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper		  }
2694acb8983909a3f031041ee5d7cbe09fbeb3c31b9aUlrich Drepper
2695acb8983909a3f031041ee5d7cbe09fbeb3c31b9aUlrich Drepper		if (strcmp (scnname, ".interp") == 0)
2696b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper		  {
2697b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper		    dot_interp_section = true;
2698b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper
2699b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper		    if (ehdr->e_type == ET_REL)
2700b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper		      ERROR (gettext ("\
2701b08d5a8fb42f4586d756068065186b5af7e48daUlrich Dreppersection [%2zu] '%s' present in object file\n"),
2702b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper			     cnt, scnname);
2703b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper
2704b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper		    if ((shdr->sh_flags & SHF_ALLOC) != 0
2705b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper			&& !has_loadable_segment)
2706b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper		      ERROR (gettext ("\
2707b08d5a8fb42f4586d756068065186b5af7e48daUlrich Dreppersection [%2zu] '%s' has SHF_ALLOC flag set but there is no loadable segment\n"),
2708b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper			     cnt, scnname);
2709b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper		    else if ((shdr->sh_flags & SHF_ALLOC) == 0
2710b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper			     && has_loadable_segment)
27112ec957327cdfae6cee592a52958a9c937ea4b13cChih-Hung Hsieh		      ERROR (gettext ("\
2712b08d5a8fb42f4586d756068065186b5af7e48daUlrich Dreppersection [%2zu] '%s' has SHF_ALLOC flag not set but there are loadable segments\n"),
2713b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper			     cnt, scnname);
2714b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper		  }
2715b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper		else
27160a545e678f2c0605ba050b4f72080572ac7c8470Mark Wielaard		  {
2717b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper		    if (strcmp (scnname, ".symtab_shndx") == 0
2718b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper			&& ehdr->e_type != ET_REL)
2719b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper		      ERROR (gettext ("\
2720b08d5a8fb42f4586d756068065186b5af7e48daUlrich Dreppersection [%2zu] '%s' is extension section index table in non-object file\n"),
2721b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper			     cnt, scnname);
2722b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper
2723b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper		    /* These sections must have the SHF_ALLOC flag set iff
2724b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper		       a loadable segment is available.
2725b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper
2726b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper		       .relxxx
2727b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper		       .strtab
2728b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper		       .symtab
2729099dd52727f2ce1a2c73cde82af8cd5e06368aecRoland McGrath		       .symtab_shndx
2730099dd52727f2ce1a2c73cde82af8cd5e06368aecRoland McGrath
2731099dd52727f2ce1a2c73cde82af8cd5e06368aecRoland McGrath		       Check that if there is a reference from the
2732b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper		       loaded section these sections also have the
2733b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper		       ALLOC flag set.  */
2734b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper#if 0
2735b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper		    // XXX TODO
2736b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper		    if ((shdr->sh_flags & SHF_ALLOC) != 0
2737b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper			&& !has_loadable_segment)
2738b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper		      ERROR (gettext ("\
2739b08d5a8fb42f4586d756068065186b5af7e48daUlrich Dreppersection [%2zu] '%s' has SHF_ALLOC flag set but there is no loadable segment\n"),
2740b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper			     cnt, scnname);
2741b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper		    else if ((shdr->sh_flags & SHF_ALLOC) == 0
2742b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper			     && has_loadable_segment)
2743b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper		      ERROR (gettext ("\
2744b08d5a8fb42f4586d756068065186b5af7e48daUlrich Dreppersection [%2zu] '%s' has SHF_ALLOC flag not set but there are loadable segments\n"),
2745b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper			     cnt, scnname);
2746b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper#endif
2747b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper		  }
2748b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper
2749b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper		break;
2750b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper	      }
2751b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper	}
2752b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper
2753b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper      if (shdr->sh_entsize != 0 && shdr->sh_size % shdr->sh_entsize)
2754b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper	ERROR (gettext ("\
2755acb8983909a3f031041ee5d7cbe09fbeb3c31b9aUlrich Dreppersection [%2zu] '%s': size not multiple of entry size\n"),
2756b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper	       cnt, section_name (ebl, cnt));
2757b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper
2758b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper      if (elf_strptr (ebl->elf, shstrndx, shdr->sh_name) == NULL)
2759b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper	ERROR (gettext ("cannot get section header\n"));
2760b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper
2761b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper      if (shdr->sh_type >= SHT_NUM
2762b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper	  && shdr->sh_type != SHT_GNU_LIBLIST
2763b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper	  && shdr->sh_type != SHT_CHECKSUM
2764b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper	  && shdr->sh_type != SHT_GNU_verdef
2765b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper	  && shdr->sh_type != SHT_GNU_verneed
2766b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper	  && shdr->sh_type != SHT_GNU_versym
2767b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper	  && ebl_section_type_name (ebl, shdr->sh_type, NULL, 0) == NULL)
2768b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper	ERROR (gettext ("section [%2zu] '%s' has unsupported type %d\n"),
2769b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper	       cnt, section_name (ebl, cnt),
2770b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper	       (int) shdr->sh_type);
2771b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper
2772b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper#define ALL_SH_FLAGS (SHF_WRITE | SHF_ALLOC | SHF_EXECINSTR | SHF_MERGE \
2773b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper		      | SHF_STRINGS | SHF_INFO_LINK | SHF_LINK_ORDER \
2774b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper		      | SHF_OS_NONCONFORMING | SHF_GROUP | SHF_TLS)
2775b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper      if (shdr->sh_flags & ~ALL_SH_FLAGS)
2776b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper	ERROR (gettext ("section [%2zu] '%s' contains unknown flag(s)"
2777b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper			" %#" PRIx64 "\n"),
2778b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper	       cnt, section_name (ebl, cnt),
2779b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper	       (uint64_t) shdr->sh_flags & ~(uint64_t) ALL_SH_FLAGS);
2780dbace2389b6f89cd4f8f2713aac50a16b16964a2Ulrich Drepper      else if (shdr->sh_flags & SHF_TLS)
2781dbace2389b6f89cd4f8f2713aac50a16b16964a2Ulrich Drepper	{
2782dbace2389b6f89cd4f8f2713aac50a16b16964a2Ulrich Drepper	  // XXX Correct?
2783dbace2389b6f89cd4f8f2713aac50a16b16964a2Ulrich Drepper	  if (shdr->sh_addr != 0 && !gnuld)
2784dbace2389b6f89cd4f8f2713aac50a16b16964a2Ulrich Drepper	    ERROR (gettext ("\
2785dbace2389b6f89cd4f8f2713aac50a16b16964a2Ulrich Dreppersection [%2zu] '%s': thread-local data sections address not zero\n"),
2786dbace2389b6f89cd4f8f2713aac50a16b16964a2Ulrich Drepper		   cnt, section_name (ebl, cnt));
2787dbace2389b6f89cd4f8f2713aac50a16b16964a2Ulrich Drepper
2788dbace2389b6f89cd4f8f2713aac50a16b16964a2Ulrich Drepper	  // XXX TODO more tests!?
2789dbace2389b6f89cd4f8f2713aac50a16b16964a2Ulrich Drepper	}
2790dbace2389b6f89cd4f8f2713aac50a16b16964a2Ulrich Drepper
2791dbace2389b6f89cd4f8f2713aac50a16b16964a2Ulrich Drepper      if (shdr->sh_link >= shnum)
2792dbace2389b6f89cd4f8f2713aac50a16b16964a2Ulrich Drepper	ERROR (gettext ("\
2793dbace2389b6f89cd4f8f2713aac50a16b16964a2Ulrich Dreppersection [%2zu] '%s': invalid section reference in link value\n"),
2794dbace2389b6f89cd4f8f2713aac50a16b16964a2Ulrich Drepper	       cnt, section_name (ebl, cnt));
2795dbace2389b6f89cd4f8f2713aac50a16b16964a2Ulrich Drepper
2796dbace2389b6f89cd4f8f2713aac50a16b16964a2Ulrich Drepper      if (SH_INFO_LINK_P (shdr) && shdr->sh_info >= shnum)
2797dbace2389b6f89cd4f8f2713aac50a16b16964a2Ulrich Drepper	ERROR (gettext ("\
2798dbace2389b6f89cd4f8f2713aac50a16b16964a2Ulrich Dreppersection [%2zu] '%s': invalid section reference in info value\n"),
2799dbace2389b6f89cd4f8f2713aac50a16b16964a2Ulrich Drepper	       cnt, section_name (ebl, cnt));
2800dbace2389b6f89cd4f8f2713aac50a16b16964a2Ulrich Drepper
28010a545e678f2c0605ba050b4f72080572ac7c8470Mark Wielaard      if ((shdr->sh_flags & SHF_MERGE) == 0
2802dbace2389b6f89cd4f8f2713aac50a16b16964a2Ulrich Drepper	  && (shdr->sh_flags & SHF_STRINGS) != 0
2803dbace2389b6f89cd4f8f2713aac50a16b16964a2Ulrich Drepper	  && be_strict)
2804dbace2389b6f89cd4f8f2713aac50a16b16964a2Ulrich Drepper	ERROR (gettext ("\
2805dbace2389b6f89cd4f8f2713aac50a16b16964a2Ulrich Dreppersection [%2zu] '%s': strings flag set without merge flag\n"),
2806dbace2389b6f89cd4f8f2713aac50a16b16964a2Ulrich Drepper	       cnt, section_name (ebl, cnt));
2807dbace2389b6f89cd4f8f2713aac50a16b16964a2Ulrich Drepper
2808dbace2389b6f89cd4f8f2713aac50a16b16964a2Ulrich Drepper      if ((shdr->sh_flags & SHF_MERGE) != 0 && shdr->sh_entsize == 0)
2809dbace2389b6f89cd4f8f2713aac50a16b16964a2Ulrich Drepper	ERROR (gettext ("\
2810dbace2389b6f89cd4f8f2713aac50a16b16964a2Ulrich Dreppersection [%2zu] '%s': merge flag set but entry size is zero\n"),
2811dbace2389b6f89cd4f8f2713aac50a16b16964a2Ulrich Drepper	       cnt, section_name (ebl, cnt));
2812dbace2389b6f89cd4f8f2713aac50a16b16964a2Ulrich Drepper
2813dbace2389b6f89cd4f8f2713aac50a16b16964a2Ulrich Drepper      if (shdr->sh_flags & SHF_GROUP)
2814dbace2389b6f89cd4f8f2713aac50a16b16964a2Ulrich Drepper	check_scn_group (ebl, cnt);
2815dbace2389b6f89cd4f8f2713aac50a16b16964a2Ulrich Drepper
2816dbace2389b6f89cd4f8f2713aac50a16b16964a2Ulrich Drepper      if (ehdr->e_type != ET_REL && (shdr->sh_flags & SHF_ALLOC) != 0)
2817dbace2389b6f89cd4f8f2713aac50a16b16964a2Ulrich Drepper	{
2818dbace2389b6f89cd4f8f2713aac50a16b16964a2Ulrich Drepper	  /* Make sure the section is contained in a loaded segment
2819dbace2389b6f89cd4f8f2713aac50a16b16964a2Ulrich Drepper	     and that the initialization part matches NOBITS sections.  */
2820dbace2389b6f89cd4f8f2713aac50a16b16964a2Ulrich Drepper	  int pcnt;
2821dbace2389b6f89cd4f8f2713aac50a16b16964a2Ulrich Drepper	  GElf_Phdr phdr_mem;
2822dbace2389b6f89cd4f8f2713aac50a16b16964a2Ulrich Drepper	  GElf_Phdr *phdr;
2823dbace2389b6f89cd4f8f2713aac50a16b16964a2Ulrich Drepper
2824dbace2389b6f89cd4f8f2713aac50a16b16964a2Ulrich Drepper	  for (pcnt = 0; pcnt < ehdr->e_phnum; ++pcnt)
2825dbace2389b6f89cd4f8f2713aac50a16b16964a2Ulrich Drepper	    if ((phdr = gelf_getphdr (ebl->elf, pcnt, &phdr_mem)) != NULL
2826dbace2389b6f89cd4f8f2713aac50a16b16964a2Ulrich Drepper		&& ((phdr->p_type == PT_LOAD
2827dbace2389b6f89cd4f8f2713aac50a16b16964a2Ulrich Drepper		     && (shdr->sh_flags & SHF_TLS) == 0)
2828dbace2389b6f89cd4f8f2713aac50a16b16964a2Ulrich Drepper		    || (phdr->p_type == PT_TLS
2829dbace2389b6f89cd4f8f2713aac50a16b16964a2Ulrich Drepper			&& (shdr->sh_flags & SHF_TLS) != 0))
2830dbace2389b6f89cd4f8f2713aac50a16b16964a2Ulrich Drepper		&& phdr->p_offset <= shdr->sh_offset
2831dbace2389b6f89cd4f8f2713aac50a16b16964a2Ulrich Drepper		&& phdr->p_offset + phdr->p_memsz > shdr->sh_offset)
2832dbace2389b6f89cd4f8f2713aac50a16b16964a2Ulrich Drepper	      {
2833637963b564240fe6db4908b28238b75aa0758a06Ulrich Drepper		/* Found the segment.  */
2834637963b564240fe6db4908b28238b75aa0758a06Ulrich Drepper		if (phdr->p_offset + phdr->p_memsz
2835637963b564240fe6db4908b28238b75aa0758a06Ulrich Drepper		    < shdr->sh_offset + shdr->sh_size)
2836637963b564240fe6db4908b28238b75aa0758a06Ulrich Drepper		  ERROR (gettext ("\
2837637963b564240fe6db4908b28238b75aa0758a06Ulrich Dreppersection [%2zu] '%s' not fully contained in segment of program header entry %d\n"),
2838637963b564240fe6db4908b28238b75aa0758a06Ulrich Drepper			 cnt, section_name (ebl, cnt), pcnt);
2839637963b564240fe6db4908b28238b75aa0758a06Ulrich Drepper
2840637963b564240fe6db4908b28238b75aa0758a06Ulrich Drepper		if (shdr->sh_type == SHT_NOBITS)
2841637963b564240fe6db4908b28238b75aa0758a06Ulrich Drepper		  {
2842dbace2389b6f89cd4f8f2713aac50a16b16964a2Ulrich Drepper		    if (shdr->sh_offset < phdr->p_offset + phdr->p_filesz
2843dbace2389b6f89cd4f8f2713aac50a16b16964a2Ulrich Drepper			&& !is_debuginfo)
2844dbace2389b6f89cd4f8f2713aac50a16b16964a2Ulrich Drepper		      ERROR (gettext ("\
2845dbace2389b6f89cd4f8f2713aac50a16b16964a2Ulrich Dreppersection [%2zu] '%s' has type NOBITS but is read from the file in segment of program header entry %d\n"),
2846858b189f82ecc32ca7042e74ccb022f794a9f83bRoland McGrath			 cnt, section_name (ebl, cnt), pcnt);
2847dbace2389b6f89cd4f8f2713aac50a16b16964a2Ulrich Drepper		  }
2848dbace2389b6f89cd4f8f2713aac50a16b16964a2Ulrich Drepper		else
2849dbace2389b6f89cd4f8f2713aac50a16b16964a2Ulrich Drepper		  {
2850dbace2389b6f89cd4f8f2713aac50a16b16964a2Ulrich Drepper		    const GElf_Off end = phdr->p_offset + phdr->p_filesz;
2851dbace2389b6f89cd4f8f2713aac50a16b16964a2Ulrich Drepper		    if (shdr->sh_offset > end ||
2852dbace2389b6f89cd4f8f2713aac50a16b16964a2Ulrich Drepper			(shdr->sh_offset == end && shdr->sh_size != 0))
2853858b189f82ecc32ca7042e74ccb022f794a9f83bRoland McGrath		      ERROR (gettext ("\
2854dbace2389b6f89cd4f8f2713aac50a16b16964a2Ulrich Dreppersection [%2zu] '%s' has not type NOBITS but is not read from the file in segment of program header entry %d\n"),
2855dbace2389b6f89cd4f8f2713aac50a16b16964a2Ulrich Drepper			 cnt, section_name (ebl, cnt), pcnt);
2856dbace2389b6f89cd4f8f2713aac50a16b16964a2Ulrich Drepper		  }
2857dbace2389b6f89cd4f8f2713aac50a16b16964a2Ulrich Drepper
2858dbace2389b6f89cd4f8f2713aac50a16b16964a2Ulrich Drepper		break;
2859dbace2389b6f89cd4f8f2713aac50a16b16964a2Ulrich Drepper	      }
2860dbace2389b6f89cd4f8f2713aac50a16b16964a2Ulrich Drepper
2861dbace2389b6f89cd4f8f2713aac50a16b16964a2Ulrich Drepper	  if (pcnt == ehdr->e_phnum)
2862dbace2389b6f89cd4f8f2713aac50a16b16964a2Ulrich Drepper	    ERROR (gettext ("\
2863dbace2389b6f89cd4f8f2713aac50a16b16964a2Ulrich Dreppersection [%2zu] '%s': alloc flag set but section not in any loaded segment\n"),
2864dbace2389b6f89cd4f8f2713aac50a16b16964a2Ulrich Drepper		   cnt, section_name (ebl, cnt));
2865dbace2389b6f89cd4f8f2713aac50a16b16964a2Ulrich Drepper	}
2866dbace2389b6f89cd4f8f2713aac50a16b16964a2Ulrich Drepper
2867dbace2389b6f89cd4f8f2713aac50a16b16964a2Ulrich Drepper      if (cnt == shstrndx && shdr->sh_type != SHT_STRTAB)
2868dbace2389b6f89cd4f8f2713aac50a16b16964a2Ulrich Drepper	ERROR (gettext ("\
2869dbace2389b6f89cd4f8f2713aac50a16b16964a2Ulrich Dreppersection [%2zu] '%s': ELF header says this is the section header string table but type is not SHT_TYPE\n"),
2870dbace2389b6f89cd4f8f2713aac50a16b16964a2Ulrich Drepper	       cnt, section_name (ebl, cnt));
2871dbace2389b6f89cd4f8f2713aac50a16b16964a2Ulrich Drepper
2872dbace2389b6f89cd4f8f2713aac50a16b16964a2Ulrich Drepper      switch (shdr->sh_type)
2873dbace2389b6f89cd4f8f2713aac50a16b16964a2Ulrich Drepper	{
2874dbace2389b6f89cd4f8f2713aac50a16b16964a2Ulrich Drepper	case SHT_DYNSYM:
2875dbace2389b6f89cd4f8f2713aac50a16b16964a2Ulrich Drepper	  if (ehdr->e_type == ET_REL)
2876dbace2389b6f89cd4f8f2713aac50a16b16964a2Ulrich Drepper	    ERROR (gettext ("\
2877dbace2389b6f89cd4f8f2713aac50a16b16964a2Ulrich Dreppersection [%2zu] '%s': relocatable files cannot have dynamic symbol tables\n"),
2878dbace2389b6f89cd4f8f2713aac50a16b16964a2Ulrich Drepper		   cnt, section_name (ebl, cnt));
2879b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper	  /* FALLTHROUGH */
2880dbace2389b6f89cd4f8f2713aac50a16b16964a2Ulrich Drepper	case SHT_SYMTAB:
2881b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper	  check_symtab (ebl, ehdr, shdr, cnt);
2882dbace2389b6f89cd4f8f2713aac50a16b16964a2Ulrich Drepper	  break;
2883dbace2389b6f89cd4f8f2713aac50a16b16964a2Ulrich Drepper
2884dbace2389b6f89cd4f8f2713aac50a16b16964a2Ulrich Drepper	case SHT_RELA:
2885dbace2389b6f89cd4f8f2713aac50a16b16964a2Ulrich Drepper	  check_rela (ebl, ehdr, shdr, cnt);
2886dbace2389b6f89cd4f8f2713aac50a16b16964a2Ulrich Drepper	  break;
2887dbace2389b6f89cd4f8f2713aac50a16b16964a2Ulrich Drepper
2888dbace2389b6f89cd4f8f2713aac50a16b16964a2Ulrich Drepper	case SHT_REL:
2889dbace2389b6f89cd4f8f2713aac50a16b16964a2Ulrich Drepper	  check_rel (ebl, ehdr, shdr, cnt);
2890dbace2389b6f89cd4f8f2713aac50a16b16964a2Ulrich Drepper	  break;
2891dbace2389b6f89cd4f8f2713aac50a16b16964a2Ulrich Drepper
2892dbace2389b6f89cd4f8f2713aac50a16b16964a2Ulrich Drepper	case SHT_DYNAMIC:
2893dbace2389b6f89cd4f8f2713aac50a16b16964a2Ulrich Drepper	  check_dynamic (ebl, ehdr, shdr, cnt);
2894dbace2389b6f89cd4f8f2713aac50a16b16964a2Ulrich Drepper	  break;
2895dbace2389b6f89cd4f8f2713aac50a16b16964a2Ulrich Drepper
2896dbace2389b6f89cd4f8f2713aac50a16b16964a2Ulrich Drepper	case SHT_SYMTAB_SHNDX:
2897dbace2389b6f89cd4f8f2713aac50a16b16964a2Ulrich Drepper	  check_symtab_shndx (ebl, ehdr, shdr, cnt);
2898b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper	  break;
2899dbace2389b6f89cd4f8f2713aac50a16b16964a2Ulrich Drepper
2900b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper	case SHT_HASH:
2901b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper	  check_hash (ebl, ehdr, shdr, cnt);
2902b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper	  break;
2903b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper
2904b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper	case SHT_NULL:
2905b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper	  check_null (ebl, shdr, cnt);
2906b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper	  break;
2907b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper
2908b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper	case SHT_GROUP:
2909b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper	  check_group (ebl, ehdr, shdr, cnt);
2910b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper	  break;
2911b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper
2912b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper	case SHT_GNU_versym:
2913dbace2389b6f89cd4f8f2713aac50a16b16964a2Ulrich Drepper	  /* We cannot process this section now since we have no guarantee
2914dbace2389b6f89cd4f8f2713aac50a16b16964a2Ulrich Drepper	     that the verneed and verdef sections have already been read.
29150a545e678f2c0605ba050b4f72080572ac7c8470Mark Wielaard	     Just remember the section index.  */
291671c1534c9c7a0652fb6c5f9295baa08f32b0b166Jakub Jelinek	  if (versym_scnndx != 0)
291771c1534c9c7a0652fb6c5f9295baa08f32b0b166Jakub Jelinek	    ERROR (gettext ("more than one version symbol table present\n"));
2918b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper	  versym_scnndx = cnt;
2919b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper	  break;
2920b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper
2921b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper	case SHT_GNU_verneed:
2922b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper	  check_verneed (ebl, ehdr, shdr, cnt);
2923dbace2389b6f89cd4f8f2713aac50a16b16964a2Ulrich Drepper	  break;
29240a545e678f2c0605ba050b4f72080572ac7c8470Mark Wielaard
2925dbace2389b6f89cd4f8f2713aac50a16b16964a2Ulrich Drepper	case SHT_GNU_verdef:
2926dbace2389b6f89cd4f8f2713aac50a16b16964a2Ulrich Drepper	  check_verdef (ebl, shdr, cnt);
2927dbace2389b6f89cd4f8f2713aac50a16b16964a2Ulrich Drepper	  break;
2928dbace2389b6f89cd4f8f2713aac50a16b16964a2Ulrich Drepper
2929dbace2389b6f89cd4f8f2713aac50a16b16964a2Ulrich Drepper	default:
2930dbace2389b6f89cd4f8f2713aac50a16b16964a2Ulrich Drepper	  /* Nothing.  */
2931dbace2389b6f89cd4f8f2713aac50a16b16964a2Ulrich Drepper	  break;
2932dbace2389b6f89cd4f8f2713aac50a16b16964a2Ulrich Drepper	}
2933dbace2389b6f89cd4f8f2713aac50a16b16964a2Ulrich Drepper    }
2934dbace2389b6f89cd4f8f2713aac50a16b16964a2Ulrich Drepper
2935dbace2389b6f89cd4f8f2713aac50a16b16964a2Ulrich Drepper  if (has_interp_segment && !dot_interp_section)
2936dbace2389b6f89cd4f8f2713aac50a16b16964a2Ulrich Drepper    ERROR (gettext ("INTERP program header entry but no .interp section\n"));
2937dbace2389b6f89cd4f8f2713aac50a16b16964a2Ulrich Drepper
2938dbace2389b6f89cd4f8f2713aac50a16b16964a2Ulrich Drepper  if (version_namelist != NULL)
2939dbace2389b6f89cd4f8f2713aac50a16b16964a2Ulrich Drepper    {
2940dbace2389b6f89cd4f8f2713aac50a16b16964a2Ulrich Drepper      if (versym_scnndx == 0)
2941dbace2389b6f89cd4f8f2713aac50a16b16964a2Ulrich Drepper    ERROR (gettext ("\
2942dbace2389b6f89cd4f8f2713aac50a16b16964a2Ulrich Drepperno .gnu.versym section present but .gnu.versym_d or .gnu.versym_r section exist\n"));
2943dbace2389b6f89cd4f8f2713aac50a16b16964a2Ulrich Drepper      else
2944dbace2389b6f89cd4f8f2713aac50a16b16964a2Ulrich Drepper	check_versym (ebl, versym_scnndx);
2945dbace2389b6f89cd4f8f2713aac50a16b16964a2Ulrich Drepper
294661655e08ba36430de47381cefdf10d0c26aa8480Ulrich Drepper      /* Check for duplicate index numbers.  */
2947dbace2389b6f89cd4f8f2713aac50a16b16964a2Ulrich Drepper      do
2948dbace2389b6f89cd4f8f2713aac50a16b16964a2Ulrich Drepper	{
2949dbace2389b6f89cd4f8f2713aac50a16b16964a2Ulrich Drepper	  struct version_namelist *runp = version_namelist->next;
2950dbace2389b6f89cd4f8f2713aac50a16b16964a2Ulrich Drepper	  while (runp != NULL)
2951dbace2389b6f89cd4f8f2713aac50a16b16964a2Ulrich Drepper	    {
2952dbace2389b6f89cd4f8f2713aac50a16b16964a2Ulrich Drepper	      if (version_namelist->ndx == runp->ndx)
2953dbace2389b6f89cd4f8f2713aac50a16b16964a2Ulrich Drepper		{
295461655e08ba36430de47381cefdf10d0c26aa8480Ulrich Drepper		  ERROR (gettext ("duplicate version index %d\n"),
2955dbace2389b6f89cd4f8f2713aac50a16b16964a2Ulrich Drepper			 (int) version_namelist->ndx);
2956c5a06cd2a5f48351b273872ed3e4a2d63d29e459Ulrich Drepper		  break;
2957c5a06cd2a5f48351b273872ed3e4a2d63d29e459Ulrich Drepper		}
2958c5a06cd2a5f48351b273872ed3e4a2d63d29e459Ulrich Drepper	      runp = runp->next;
2959c5a06cd2a5f48351b273872ed3e4a2d63d29e459Ulrich Drepper	    }
2960c5a06cd2a5f48351b273872ed3e4a2d63d29e459Ulrich Drepper
2961c5a06cd2a5f48351b273872ed3e4a2d63d29e459Ulrich Drepper	  struct version_namelist *old = version_namelist;
2962dbace2389b6f89cd4f8f2713aac50a16b16964a2Ulrich Drepper	  version_namelist = version_namelist->next;
2963dbace2389b6f89cd4f8f2713aac50a16b16964a2Ulrich Drepper	  free (old);
2964dbace2389b6f89cd4f8f2713aac50a16b16964a2Ulrich Drepper	}
2965dbace2389b6f89cd4f8f2713aac50a16b16964a2Ulrich Drepper      while (version_namelist != NULL);
2966858b189f82ecc32ca7042e74ccb022f794a9f83bRoland McGrath    }
2967dbace2389b6f89cd4f8f2713aac50a16b16964a2Ulrich Drepper  else if (versym_scnndx != 0)
2968dbace2389b6f89cd4f8f2713aac50a16b16964a2Ulrich Drepper    ERROR (gettext ("\
2969dbace2389b6f89cd4f8f2713aac50a16b16964a2Ulrich Drepper.gnu.versym section present without .gnu.versym_d or .gnu.versym_r\n"));
2970dbace2389b6f89cd4f8f2713aac50a16b16964a2Ulrich Drepper
2971dbace2389b6f89cd4f8f2713aac50a16b16964a2Ulrich Drepper  free (scnref);
2972dbace2389b6f89cd4f8f2713aac50a16b16964a2Ulrich Drepper}
2973dbace2389b6f89cd4f8f2713aac50a16b16964a2Ulrich Drepper
2974dbace2389b6f89cd4f8f2713aac50a16b16964a2Ulrich Drepper
2975dbace2389b6f89cd4f8f2713aac50a16b16964a2Ulrich Drepperstatic void
2976dbace2389b6f89cd4f8f2713aac50a16b16964a2Ulrich Dreppercheck_note (Ebl *ebl, GElf_Ehdr *ehdr, GElf_Phdr *phdr, int cnt)
2977dbace2389b6f89cd4f8f2713aac50a16b16964a2Ulrich Drepper{
2978dbace2389b6f89cd4f8f2713aac50a16b16964a2Ulrich Drepper  if (ehdr->e_type != ET_CORE && ehdr->e_type != ET_REL
2979dbace2389b6f89cd4f8f2713aac50a16b16964a2Ulrich Drepper      && ehdr->e_type != ET_EXEC && ehdr->e_type != ET_DYN)
2980dbace2389b6f89cd4f8f2713aac50a16b16964a2Ulrich Drepper    ERROR (gettext ("\
2981dbace2389b6f89cd4f8f2713aac50a16b16964a2Ulrich Drepperphdr[%d]: no note entries defined for the type of file\n"),
2982dbace2389b6f89cd4f8f2713aac50a16b16964a2Ulrich Drepper	   cnt);
2983dbace2389b6f89cd4f8f2713aac50a16b16964a2Ulrich Drepper
2984dbace2389b6f89cd4f8f2713aac50a16b16964a2Ulrich Drepper  if (is_debuginfo)
2985637963b564240fe6db4908b28238b75aa0758a06Ulrich Drepper    /* The p_offset values in a separate debug file are bogus.  */
2986637963b564240fe6db4908b28238b75aa0758a06Ulrich Drepper    return;
2987dbace2389b6f89cd4f8f2713aac50a16b16964a2Ulrich Drepper
2988dbace2389b6f89cd4f8f2713aac50a16b16964a2Ulrich Drepper  char *notemem = gelf_rawchunk (ebl->elf, phdr->p_offset, phdr->p_filesz);
2989dbace2389b6f89cd4f8f2713aac50a16b16964a2Ulrich Drepper
2990dbace2389b6f89cd4f8f2713aac50a16b16964a2Ulrich Drepper  /* ELF64 files often use note section entries in the 32-bit format.
2991dbace2389b6f89cd4f8f2713aac50a16b16964a2Ulrich Drepper     The p_align field is set to 8 in case the 64-bit format is used.
2992dbace2389b6f89cd4f8f2713aac50a16b16964a2Ulrich Drepper     In case the p_align value is 0 or 4 the 32-bit format is
2993dbace2389b6f89cd4f8f2713aac50a16b16964a2Ulrich Drepper     used.  */
2994dbace2389b6f89cd4f8f2713aac50a16b16964a2Ulrich Drepper  GElf_Xword align = phdr->p_align == 0 || phdr->p_align == 4 ? 4 : 8;
2995dbace2389b6f89cd4f8f2713aac50a16b16964a2Ulrich Drepper#define ALIGNED_LEN(len) (((len) + align - 1) & ~(align - 1))
2996dbace2389b6f89cd4f8f2713aac50a16b16964a2Ulrich Drepper
2997bd733cae5159e3a3c4c05f7685559fa3ae8b58c6Roland McGrath  GElf_Xword idx = 0;
2998dbace2389b6f89cd4f8f2713aac50a16b16964a2Ulrich Drepper  while (idx < phdr->p_filesz)
2999dbace2389b6f89cd4f8f2713aac50a16b16964a2Ulrich Drepper    {
3000dbace2389b6f89cd4f8f2713aac50a16b16964a2Ulrich Drepper      uint64_t namesz;
3001dbace2389b6f89cd4f8f2713aac50a16b16964a2Ulrich Drepper      uint64_t descsz;
3002bd733cae5159e3a3c4c05f7685559fa3ae8b58c6Roland McGrath      uint64_t type;
3003bd733cae5159e3a3c4c05f7685559fa3ae8b58c6Roland McGrath      uint32_t namesz32;
3004dbace2389b6f89cd4f8f2713aac50a16b16964a2Ulrich Drepper      uint32_t descsz32;
3005dbace2389b6f89cd4f8f2713aac50a16b16964a2Ulrich Drepper
3006dbace2389b6f89cd4f8f2713aac50a16b16964a2Ulrich Drepper      if (align == 4)
3007dbace2389b6f89cd4f8f2713aac50a16b16964a2Ulrich Drepper	{
3008bd733cae5159e3a3c4c05f7685559fa3ae8b58c6Roland McGrath	  uint32_t *ptr = (uint32_t *) (notemem + idx);
3009dbace2389b6f89cd4f8f2713aac50a16b16964a2Ulrich Drepper
3010dbace2389b6f89cd4f8f2713aac50a16b16964a2Ulrich Drepper	  if ((__BYTE_ORDER == __LITTLE_ENDIAN
3011dbace2389b6f89cd4f8f2713aac50a16b16964a2Ulrich Drepper	       && ehdr->e_ident[EI_DATA] == ELFDATA2MSB)
3012dbace2389b6f89cd4f8f2713aac50a16b16964a2Ulrich Drepper	      || (__BYTE_ORDER == __BIG_ENDIAN
3013dbace2389b6f89cd4f8f2713aac50a16b16964a2Ulrich Drepper		  && ehdr->e_ident[EI_DATA] == ELFDATA2LSB))
3014dbace2389b6f89cd4f8f2713aac50a16b16964a2Ulrich Drepper	    {
30150a545e678f2c0605ba050b4f72080572ac7c8470Mark Wielaard	      namesz32 = namesz = bswap_32 (*ptr);
30160a545e678f2c0605ba050b4f72080572ac7c8470Mark Wielaard	      ++ptr;
3017dbace2389b6f89cd4f8f2713aac50a16b16964a2Ulrich Drepper	      descsz32 = descsz = bswap_32 (*ptr);
3018dbace2389b6f89cd4f8f2713aac50a16b16964a2Ulrich Drepper	      ++ptr;
3019dbace2389b6f89cd4f8f2713aac50a16b16964a2Ulrich Drepper	      type = bswap_32 (*ptr);
3020dbace2389b6f89cd4f8f2713aac50a16b16964a2Ulrich Drepper	    }
3021dbace2389b6f89cd4f8f2713aac50a16b16964a2Ulrich Drepper	  else
3022dbace2389b6f89cd4f8f2713aac50a16b16964a2Ulrich Drepper	    {
3023dbace2389b6f89cd4f8f2713aac50a16b16964a2Ulrich Drepper	      namesz32 = namesz = *ptr++;
3024dbace2389b6f89cd4f8f2713aac50a16b16964a2Ulrich Drepper	      descsz32 = descsz = *ptr++;
3025dbace2389b6f89cd4f8f2713aac50a16b16964a2Ulrich Drepper	      type = *ptr;
3026dbace2389b6f89cd4f8f2713aac50a16b16964a2Ulrich Drepper	    }
3027dbace2389b6f89cd4f8f2713aac50a16b16964a2Ulrich Drepper	}
3028dbace2389b6f89cd4f8f2713aac50a16b16964a2Ulrich Drepper      else
3029dbace2389b6f89cd4f8f2713aac50a16b16964a2Ulrich Drepper	{
3030dbace2389b6f89cd4f8f2713aac50a16b16964a2Ulrich Drepper	  uint64_t *ptr = (uint64_t *) (notemem + idx);
3031b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper	  uint32_t *ptr32 = (uint32_t *) (notemem + idx);
3032b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper
3033b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper	  if ((__BYTE_ORDER == __LITTLE_ENDIAN
3034acb8983909a3f031041ee5d7cbe09fbeb3c31b9aUlrich Drepper	       && ehdr->e_ident[EI_DATA] == ELFDATA2MSB)
3035acb8983909a3f031041ee5d7cbe09fbeb3c31b9aUlrich Drepper	      || (__BYTE_ORDER == __BIG_ENDIAN
3036b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper		  && ehdr->e_ident[EI_DATA] == ELFDATA2LSB))
3037bd733cae5159e3a3c4c05f7685559fa3ae8b58c6Roland McGrath	    {
3038b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper	      namesz = bswap_64 (*ptr);
3039acb8983909a3f031041ee5d7cbe09fbeb3c31b9aUlrich Drepper	      ++ptr;
3040acb8983909a3f031041ee5d7cbe09fbeb3c31b9aUlrich Drepper	      descsz = bswap_64 (*ptr);
3041acb8983909a3f031041ee5d7cbe09fbeb3c31b9aUlrich Drepper	      ++ptr;
3042acb8983909a3f031041ee5d7cbe09fbeb3c31b9aUlrich Drepper	      type = bswap_64 (*ptr);
3043acb8983909a3f031041ee5d7cbe09fbeb3c31b9aUlrich Drepper
3044acb8983909a3f031041ee5d7cbe09fbeb3c31b9aUlrich Drepper	      namesz32 = bswap_32 (*ptr32);
3045acb8983909a3f031041ee5d7cbe09fbeb3c31b9aUlrich Drepper	      ++ptr32;
3046acb8983909a3f031041ee5d7cbe09fbeb3c31b9aUlrich Drepper	      descsz32 = bswap_32 (*ptr32);
3047acb8983909a3f031041ee5d7cbe09fbeb3c31b9aUlrich Drepper	    }
3048acb8983909a3f031041ee5d7cbe09fbeb3c31b9aUlrich Drepper	  else
3049acb8983909a3f031041ee5d7cbe09fbeb3c31b9aUlrich Drepper	    {
3050acb8983909a3f031041ee5d7cbe09fbeb3c31b9aUlrich Drepper	      namesz = *ptr++;
3051dbace2389b6f89cd4f8f2713aac50a16b16964a2Ulrich Drepper	      descsz = *ptr++;
3052dbace2389b6f89cd4f8f2713aac50a16b16964a2Ulrich Drepper	      type = *ptr;
3053dbace2389b6f89cd4f8f2713aac50a16b16964a2Ulrich Drepper
3054dbace2389b6f89cd4f8f2713aac50a16b16964a2Ulrich Drepper	      namesz32 = *ptr32++;
3055dbace2389b6f89cd4f8f2713aac50a16b16964a2Ulrich Drepper	      descsz32 = *ptr32;
3056dbace2389b6f89cd4f8f2713aac50a16b16964a2Ulrich Drepper	    }
3057dbace2389b6f89cd4f8f2713aac50a16b16964a2Ulrich Drepper	}
3058dbace2389b6f89cd4f8f2713aac50a16b16964a2Ulrich Drepper
3059dbace2389b6f89cd4f8f2713aac50a16b16964a2Ulrich Drepper      if (idx + 3 * align > phdr->p_filesz
30609d0926538635fe9a2bda0684623516aaf4407ecbMark Wielaard	  || (idx + 3 * align + ALIGNED_LEN (namesz) + ALIGNED_LEN (descsz)
3061dbace2389b6f89cd4f8f2713aac50a16b16964a2Ulrich Drepper	      > phdr->p_filesz))
30629d0926538635fe9a2bda0684623516aaf4407ecbMark Wielaard	{
30639d0926538635fe9a2bda0684623516aaf4407ecbMark Wielaard	  if (ehdr->e_ident[EI_CLASS] == ELFCLASS64
3064dbace2389b6f89cd4f8f2713aac50a16b16964a2Ulrich Drepper	      && idx + 3 * 4 <= phdr->p_filesz
3065dbace2389b6f89cd4f8f2713aac50a16b16964a2Ulrich Drepper	      && (idx + 3 * 4 + ALIGNED_LEN (namesz32) + ALIGNED_LEN (descsz32)
3066dbace2389b6f89cd4f8f2713aac50a16b16964a2Ulrich Drepper		  <= phdr->p_filesz))
3067dbace2389b6f89cd4f8f2713aac50a16b16964a2Ulrich Drepper	    ERROR (gettext ("\
3068dbace2389b6f89cd4f8f2713aac50a16b16964a2Ulrich Drepperphdr[%d]: note entries probably in form of a 32-bit ELF file\n"), cnt);
3069dbace2389b6f89cd4f8f2713aac50a16b16964a2Ulrich Drepper	  else
3070dbace2389b6f89cd4f8f2713aac50a16b16964a2Ulrich Drepper	    ERROR (gettext ("phdr[%d]: extra %zu bytes after last note\n"),
3071dbace2389b6f89cd4f8f2713aac50a16b16964a2Ulrich Drepper		   cnt, (size_t) (phdr->p_filesz - idx));
3072dbace2389b6f89cd4f8f2713aac50a16b16964a2Ulrich Drepper	  break;
3073dbace2389b6f89cd4f8f2713aac50a16b16964a2Ulrich Drepper	}
3074dbace2389b6f89cd4f8f2713aac50a16b16964a2Ulrich Drepper
3075dbace2389b6f89cd4f8f2713aac50a16b16964a2Ulrich Drepper      /* Make sure it is one of the note types we know about.  */
3076dbace2389b6f89cd4f8f2713aac50a16b16964a2Ulrich Drepper      if (ehdr->e_type == ET_CORE)
3077dbace2389b6f89cd4f8f2713aac50a16b16964a2Ulrich Drepper	{
3078dbace2389b6f89cd4f8f2713aac50a16b16964a2Ulrich Drepper	  switch (type)
30790a545e678f2c0605ba050b4f72080572ac7c8470Mark Wielaard	    {
30800a545e678f2c0605ba050b4f72080572ac7c8470Mark Wielaard	    case NT_PRSTATUS:
3081dbace2389b6f89cd4f8f2713aac50a16b16964a2Ulrich Drepper	    case NT_FPREGSET:
30820a545e678f2c0605ba050b4f72080572ac7c8470Mark Wielaard	    case NT_PRPSINFO:
30830a545e678f2c0605ba050b4f72080572ac7c8470Mark Wielaard	    case NT_TASKSTRUCT:		/* NT_PRXREG on Solaris.  */
30840a545e678f2c0605ba050b4f72080572ac7c8470Mark Wielaard	    case NT_PLATFORM:
3085dbace2389b6f89cd4f8f2713aac50a16b16964a2Ulrich Drepper	    case NT_AUXV:
3086dbace2389b6f89cd4f8f2713aac50a16b16964a2Ulrich Drepper	    case NT_GWINDOWS:
3087dbace2389b6f89cd4f8f2713aac50a16b16964a2Ulrich Drepper	    case NT_ASRS:
3088dbace2389b6f89cd4f8f2713aac50a16b16964a2Ulrich Drepper	    case NT_PSTATUS:
3089dbace2389b6f89cd4f8f2713aac50a16b16964a2Ulrich Drepper	    case NT_PSINFO:
3090dbace2389b6f89cd4f8f2713aac50a16b16964a2Ulrich Drepper	    case NT_PRCRED:
3091dbace2389b6f89cd4f8f2713aac50a16b16964a2Ulrich Drepper	    case NT_UTSNAME:
3092dbace2389b6f89cd4f8f2713aac50a16b16964a2Ulrich Drepper	    case NT_LWPSTATUS:
3093dbace2389b6f89cd4f8f2713aac50a16b16964a2Ulrich Drepper	    case NT_LWPSINFO:
3094dbace2389b6f89cd4f8f2713aac50a16b16964a2Ulrich Drepper	    case NT_PRFPXREG:
3095dbace2389b6f89cd4f8f2713aac50a16b16964a2Ulrich Drepper	      /* Known type.  */
3096dbace2389b6f89cd4f8f2713aac50a16b16964a2Ulrich Drepper	      break;
3097bd733cae5159e3a3c4c05f7685559fa3ae8b58c6Roland McGrath
3098dbace2389b6f89cd4f8f2713aac50a16b16964a2Ulrich Drepper	    default:
3099dbace2389b6f89cd4f8f2713aac50a16b16964a2Ulrich Drepper	      ERROR (gettext ("\
3100dbace2389b6f89cd4f8f2713aac50a16b16964a2Ulrich Drepperphdr[%d]: unknown core file note type %" PRIu64 " at offset %" PRIu64 "\n"),
3101dbace2389b6f89cd4f8f2713aac50a16b16964a2Ulrich Drepper		     cnt, type, idx);
3102dbace2389b6f89cd4f8f2713aac50a16b16964a2Ulrich Drepper	    }
3103dbace2389b6f89cd4f8f2713aac50a16b16964a2Ulrich Drepper	}
3104dbace2389b6f89cd4f8f2713aac50a16b16964a2Ulrich Drepper      else
3105dbace2389b6f89cd4f8f2713aac50a16b16964a2Ulrich Drepper	{
3106dbace2389b6f89cd4f8f2713aac50a16b16964a2Ulrich Drepper	  if (type != NT_VERSION)
3107dbace2389b6f89cd4f8f2713aac50a16b16964a2Ulrich Drepper	    ERROR (gettext ("\
3108dbace2389b6f89cd4f8f2713aac50a16b16964a2Ulrich Drepperphdr[%d]: unknown object file note type %" PRIu64 " at offset %" PRIu64 "\n"),
3109dbace2389b6f89cd4f8f2713aac50a16b16964a2Ulrich Drepper		   cnt, type, idx);
3110dbace2389b6f89cd4f8f2713aac50a16b16964a2Ulrich Drepper	}
3111dbace2389b6f89cd4f8f2713aac50a16b16964a2Ulrich Drepper
3112dbace2389b6f89cd4f8f2713aac50a16b16964a2Ulrich Drepper      /* Move to the next entry.  */
3113dbace2389b6f89cd4f8f2713aac50a16b16964a2Ulrich Drepper      idx += 3 * align + ALIGNED_LEN (namesz) + ALIGNED_LEN (descsz);
3114dbace2389b6f89cd4f8f2713aac50a16b16964a2Ulrich Drepper
3115dbace2389b6f89cd4f8f2713aac50a16b16964a2Ulrich Drepper    }
3116dbace2389b6f89cd4f8f2713aac50a16b16964a2Ulrich Drepper
31170a545e678f2c0605ba050b4f72080572ac7c8470Mark Wielaard  gelf_freechunk (ebl->elf, notemem);
31180a545e678f2c0605ba050b4f72080572ac7c8470Mark Wielaard}
3119dbace2389b6f89cd4f8f2713aac50a16b16964a2Ulrich Drepper
31200a545e678f2c0605ba050b4f72080572ac7c8470Mark Wielaard
31210a545e678f2c0605ba050b4f72080572ac7c8470Mark Wielaardstatic void
31220a545e678f2c0605ba050b4f72080572ac7c8470Mark Wielaardcheck_program_header (Ebl *ebl, GElf_Ehdr *ehdr)
3123dbace2389b6f89cd4f8f2713aac50a16b16964a2Ulrich Drepper{
3124dbace2389b6f89cd4f8f2713aac50a16b16964a2Ulrich Drepper  if (ehdr->e_phoff == 0)
3125dbace2389b6f89cd4f8f2713aac50a16b16964a2Ulrich Drepper    return;
3126dbace2389b6f89cd4f8f2713aac50a16b16964a2Ulrich Drepper
3127dbace2389b6f89cd4f8f2713aac50a16b16964a2Ulrich Drepper  if (ehdr->e_type != ET_EXEC && ehdr->e_type != ET_DYN
3128dbace2389b6f89cd4f8f2713aac50a16b16964a2Ulrich Drepper      && ehdr->e_type != ET_CORE)
3129dbace2389b6f89cd4f8f2713aac50a16b16964a2Ulrich Drepper    ERROR (gettext ("\
3130dbace2389b6f89cd4f8f2713aac50a16b16964a2Ulrich Drepperonly executables, shared objects, and core files can have program headers\n"));
3131dbace2389b6f89cd4f8f2713aac50a16b16964a2Ulrich Drepper
3132dbace2389b6f89cd4f8f2713aac50a16b16964a2Ulrich Drepper  int num_pt_interp = 0;
3133dbace2389b6f89cd4f8f2713aac50a16b16964a2Ulrich Drepper  int num_pt_tls = 0;
3134dbace2389b6f89cd4f8f2713aac50a16b16964a2Ulrich Drepper  int num_pt_relro = 0;
3135dbace2389b6f89cd4f8f2713aac50a16b16964a2Ulrich Drepper
3136dbace2389b6f89cd4f8f2713aac50a16b16964a2Ulrich Drepper  for (int cnt = 0; cnt < ehdr->e_phnum; ++cnt)
3137dbace2389b6f89cd4f8f2713aac50a16b16964a2Ulrich Drepper    {
3138dbace2389b6f89cd4f8f2713aac50a16b16964a2Ulrich Drepper      GElf_Phdr phdr_mem;
3139dbace2389b6f89cd4f8f2713aac50a16b16964a2Ulrich Drepper      GElf_Phdr *phdr;
3140dbace2389b6f89cd4f8f2713aac50a16b16964a2Ulrich Drepper
3141dbace2389b6f89cd4f8f2713aac50a16b16964a2Ulrich Drepper      phdr = gelf_getphdr (ebl->elf, cnt, &phdr_mem);
3142dbace2389b6f89cd4f8f2713aac50a16b16964a2Ulrich Drepper      if (phdr == NULL)
3143dbace2389b6f89cd4f8f2713aac50a16b16964a2Ulrich Drepper	{
3144dbace2389b6f89cd4f8f2713aac50a16b16964a2Ulrich Drepper	  ERROR (gettext ("cannot get program header entry %d: %s\n"),
3145dbace2389b6f89cd4f8f2713aac50a16b16964a2Ulrich Drepper		 cnt, elf_errmsg (-1));
3146dbace2389b6f89cd4f8f2713aac50a16b16964a2Ulrich Drepper	  continue;
3147dbace2389b6f89cd4f8f2713aac50a16b16964a2Ulrich Drepper	}
3148dbace2389b6f89cd4f8f2713aac50a16b16964a2Ulrich Drepper
3149dbace2389b6f89cd4f8f2713aac50a16b16964a2Ulrich Drepper      if (phdr->p_type >= PT_NUM && phdr->p_type != PT_GNU_EH_FRAME
3150dbace2389b6f89cd4f8f2713aac50a16b16964a2Ulrich Drepper	  && phdr->p_type != PT_GNU_STACK && phdr->p_type != PT_GNU_RELRO
3151dbace2389b6f89cd4f8f2713aac50a16b16964a2Ulrich Drepper	  /* Check for a known machine-specific type.  */
3152dbace2389b6f89cd4f8f2713aac50a16b16964a2Ulrich Drepper	  && ebl_segment_type_name (ebl, phdr->p_type, NULL, 0) == NULL)
3153dbace2389b6f89cd4f8f2713aac50a16b16964a2Ulrich Drepper	ERROR (gettext ("\
3154dbace2389b6f89cd4f8f2713aac50a16b16964a2Ulrich Drepperprogram header entry %d: unknown program header entry type %#" PRIx64 "\n"),
3155dbace2389b6f89cd4f8f2713aac50a16b16964a2Ulrich Drepper	       cnt, (uint64_t) phdr->p_type);
3156dbace2389b6f89cd4f8f2713aac50a16b16964a2Ulrich Drepper
3157dbace2389b6f89cd4f8f2713aac50a16b16964a2Ulrich Drepper      if (phdr->p_type == PT_LOAD)
3158dbace2389b6f89cd4f8f2713aac50a16b16964a2Ulrich Drepper	has_loadable_segment = true;
3159dbace2389b6f89cd4f8f2713aac50a16b16964a2Ulrich Drepper      else if (phdr->p_type == PT_INTERP)
3160dbace2389b6f89cd4f8f2713aac50a16b16964a2Ulrich Drepper	{
3161dbace2389b6f89cd4f8f2713aac50a16b16964a2Ulrich Drepper	  if (++num_pt_interp != 1)
3162dbace2389b6f89cd4f8f2713aac50a16b16964a2Ulrich Drepper	    {
31630a545e678f2c0605ba050b4f72080572ac7c8470Mark Wielaard	      if (num_pt_interp == 2)
31640a545e678f2c0605ba050b4f72080572ac7c8470Mark Wielaard		ERROR (gettext ("\
3165dbace2389b6f89cd4f8f2713aac50a16b16964a2Ulrich Dreppermore than one INTERP entry in program header\n"));
31660a545e678f2c0605ba050b4f72080572ac7c8470Mark Wielaard	    }
31670a545e678f2c0605ba050b4f72080572ac7c8470Mark Wielaard	  has_interp_segment = true;
31680a545e678f2c0605ba050b4f72080572ac7c8470Mark Wielaard	}
31690a545e678f2c0605ba050b4f72080572ac7c8470Mark Wielaard      else if (phdr->p_type == PT_TLS)
31700a545e678f2c0605ba050b4f72080572ac7c8470Mark Wielaard	{
31710a545e678f2c0605ba050b4f72080572ac7c8470Mark Wielaard	  if (++num_pt_tls == 2)
31720a545e678f2c0605ba050b4f72080572ac7c8470Mark Wielaard	    ERROR (gettext ("more than one TLS entry in program header\n"));
31730a545e678f2c0605ba050b4f72080572ac7c8470Mark Wielaard	}
31740a545e678f2c0605ba050b4f72080572ac7c8470Mark Wielaard      else if (phdr->p_type == PT_NOTE)
31750a545e678f2c0605ba050b4f72080572ac7c8470Mark Wielaard	check_note (ebl, ehdr, phdr, cnt);
31760a545e678f2c0605ba050b4f72080572ac7c8470Mark Wielaard      else if (phdr->p_type == PT_DYNAMIC)
3177dbace2389b6f89cd4f8f2713aac50a16b16964a2Ulrich Drepper	{
3178acb8983909a3f031041ee5d7cbe09fbeb3c31b9aUlrich Drepper	  if (ehdr->e_type == ET_EXEC && ! has_interp_segment)
3179b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper	    ERROR (gettext ("\
3180acb8983909a3f031041ee5d7cbe09fbeb3c31b9aUlrich Drepperstatic executable cannot have dynamic sections\n"));
3181acb8983909a3f031041ee5d7cbe09fbeb3c31b9aUlrich Drepper	  else
3182acb8983909a3f031041ee5d7cbe09fbeb3c31b9aUlrich Drepper	    {
3183acb8983909a3f031041ee5d7cbe09fbeb3c31b9aUlrich Drepper	      /* Check that the .dynamic section, if it exists, has
3184acb8983909a3f031041ee5d7cbe09fbeb3c31b9aUlrich Drepper		 the same address.  */
3185acb8983909a3f031041ee5d7cbe09fbeb3c31b9aUlrich Drepper	      Elf_Scn *scn = NULL;
3186acb8983909a3f031041ee5d7cbe09fbeb3c31b9aUlrich Drepper	      while ((scn = elf_nextscn (ebl->elf, scn)) != NULL)
3187acb8983909a3f031041ee5d7cbe09fbeb3c31b9aUlrich Drepper		{
3188acb8983909a3f031041ee5d7cbe09fbeb3c31b9aUlrich Drepper		  GElf_Shdr shdr_mem;
3189acb8983909a3f031041ee5d7cbe09fbeb3c31b9aUlrich Drepper		  GElf_Shdr *shdr = gelf_getshdr (scn, &shdr_mem);
3190acb8983909a3f031041ee5d7cbe09fbeb3c31b9aUlrich Drepper		  if (shdr != NULL && shdr->sh_type == SHT_DYNAMIC)
3191acb8983909a3f031041ee5d7cbe09fbeb3c31b9aUlrich Drepper		    {
3192acb8983909a3f031041ee5d7cbe09fbeb3c31b9aUlrich Drepper		      if (phdr->p_offset != shdr->sh_offset)
3193acb8983909a3f031041ee5d7cbe09fbeb3c31b9aUlrich Drepper			ERROR (gettext ("\
3194acb8983909a3f031041ee5d7cbe09fbeb3c31b9aUlrich Drepperdynamic section reference in program header has wrong offset\n"));
3195acb8983909a3f031041ee5d7cbe09fbeb3c31b9aUlrich Drepper		      if (phdr->p_memsz != shdr->sh_size)
3196acb8983909a3f031041ee5d7cbe09fbeb3c31b9aUlrich Drepper			ERROR (gettext ("\
3197acb8983909a3f031041ee5d7cbe09fbeb3c31b9aUlrich Drepperdynamic section size mismatch in program and section header\n"));
3198dbace2389b6f89cd4f8f2713aac50a16b16964a2Ulrich Drepper		      break;
3199dbace2389b6f89cd4f8f2713aac50a16b16964a2Ulrich Drepper		    }
3200dbace2389b6f89cd4f8f2713aac50a16b16964a2Ulrich Drepper		}
3201dbace2389b6f89cd4f8f2713aac50a16b16964a2Ulrich Drepper	    }
3202dbace2389b6f89cd4f8f2713aac50a16b16964a2Ulrich Drepper	}
3203dbace2389b6f89cd4f8f2713aac50a16b16964a2Ulrich Drepper      else if (phdr->p_type == PT_GNU_RELRO)
3204dbace2389b6f89cd4f8f2713aac50a16b16964a2Ulrich Drepper	{
3205dbace2389b6f89cd4f8f2713aac50a16b16964a2Ulrich Drepper	  if (++num_pt_relro == 2)
3206dbace2389b6f89cd4f8f2713aac50a16b16964a2Ulrich Drepper	    ERROR (gettext ("\
3207dbace2389b6f89cd4f8f2713aac50a16b16964a2Ulrich Dreppermore than one GNU_RELRO entry in program header\n"));
3208dbace2389b6f89cd4f8f2713aac50a16b16964a2Ulrich Drepper	  else
3209dbace2389b6f89cd4f8f2713aac50a16b16964a2Ulrich Drepper	    {
3210dbace2389b6f89cd4f8f2713aac50a16b16964a2Ulrich Drepper	      /* Check that the region is in a writable segment.  */
3211dbace2389b6f89cd4f8f2713aac50a16b16964a2Ulrich Drepper	      int inner;
3212dbace2389b6f89cd4f8f2713aac50a16b16964a2Ulrich Drepper	      for (inner = 0; inner < ehdr->e_phnum; ++inner)
3213dbace2389b6f89cd4f8f2713aac50a16b16964a2Ulrich Drepper		{
3214dbace2389b6f89cd4f8f2713aac50a16b16964a2Ulrich Drepper		  GElf_Phdr phdr2_mem;
3215dbace2389b6f89cd4f8f2713aac50a16b16964a2Ulrich Drepper		  GElf_Phdr *phdr2;
3216dbace2389b6f89cd4f8f2713aac50a16b16964a2Ulrich Drepper
3217dbace2389b6f89cd4f8f2713aac50a16b16964a2Ulrich Drepper		  phdr2 = gelf_getphdr (ebl->elf, inner, &phdr2_mem);
3218dbace2389b6f89cd4f8f2713aac50a16b16964a2Ulrich Drepper		  if (phdr2 == NULL)
3219dbace2389b6f89cd4f8f2713aac50a16b16964a2Ulrich Drepper		    continue;
3220dbace2389b6f89cd4f8f2713aac50a16b16964a2Ulrich Drepper
32219d0926538635fe9a2bda0684623516aaf4407ecbMark Wielaard		  if (phdr2->p_type == PT_LOAD
3222dbace2389b6f89cd4f8f2713aac50a16b16964a2Ulrich Drepper		      && phdr->p_vaddr >= phdr2->p_vaddr
32239d0926538635fe9a2bda0684623516aaf4407ecbMark Wielaard		      && (phdr->p_vaddr + phdr->p_memsz
32249d0926538635fe9a2bda0684623516aaf4407ecbMark Wielaard			  <= phdr2->p_vaddr + phdr2->p_memsz))
3225dbace2389b6f89cd4f8f2713aac50a16b16964a2Ulrich Drepper		    {
3226dbace2389b6f89cd4f8f2713aac50a16b16964a2Ulrich Drepper		      if ((phdr2->p_flags & PF_W) == 0)
3227dbace2389b6f89cd4f8f2713aac50a16b16964a2Ulrich Drepper			ERROR (gettext ("\
3228dbace2389b6f89cd4f8f2713aac50a16b16964a2Ulrich Drepperloadable segment GNU_RELRO applies to is not writable\n"));
3229dbace2389b6f89cd4f8f2713aac50a16b16964a2Ulrich Drepper		      if ((phdr2->p_flags & PF_X) != 0)
3230dbace2389b6f89cd4f8f2713aac50a16b16964a2Ulrich Drepper			ERROR (gettext ("\
3231dbace2389b6f89cd4f8f2713aac50a16b16964a2Ulrich Drepperloadable segment GNU_RELRO applies to is executable\n"));
3232dbace2389b6f89cd4f8f2713aac50a16b16964a2Ulrich Drepper		      break;
3233dbace2389b6f89cd4f8f2713aac50a16b16964a2Ulrich Drepper		    }
3234dbace2389b6f89cd4f8f2713aac50a16b16964a2Ulrich Drepper		}
3235dbace2389b6f89cd4f8f2713aac50a16b16964a2Ulrich Drepper
3236dbace2389b6f89cd4f8f2713aac50a16b16964a2Ulrich Drepper	      if (inner >= ehdr->e_phnum)
3237dbace2389b6f89cd4f8f2713aac50a16b16964a2Ulrich Drepper		ERROR (gettext ("\
3238dbace2389b6f89cd4f8f2713aac50a16b16964a2Ulrich Drepper%s segment not contained in a loaded segment\n"), "GNU_RELRO");
3239dbace2389b6f89cd4f8f2713aac50a16b16964a2Ulrich Drepper	    }
3240dbace2389b6f89cd4f8f2713aac50a16b16964a2Ulrich Drepper	}
3241dbace2389b6f89cd4f8f2713aac50a16b16964a2Ulrich Drepper      else if (phdr->p_type == PT_PHDR)
3242dbace2389b6f89cd4f8f2713aac50a16b16964a2Ulrich Drepper	{
3243dbace2389b6f89cd4f8f2713aac50a16b16964a2Ulrich Drepper	  /* Check that the region is in a writable segment.  */
3244dbace2389b6f89cd4f8f2713aac50a16b16964a2Ulrich Drepper	  int inner;
3245dbace2389b6f89cd4f8f2713aac50a16b16964a2Ulrich Drepper	  for (inner = 0; inner < ehdr->e_phnum; ++inner)
3246dbace2389b6f89cd4f8f2713aac50a16b16964a2Ulrich Drepper	    {
3247dbace2389b6f89cd4f8f2713aac50a16b16964a2Ulrich Drepper	      GElf_Phdr phdr2_mem;
3248dbace2389b6f89cd4f8f2713aac50a16b16964a2Ulrich Drepper	      GElf_Phdr *phdr2;
3249dbace2389b6f89cd4f8f2713aac50a16b16964a2Ulrich Drepper
3250dbace2389b6f89cd4f8f2713aac50a16b16964a2Ulrich Drepper	      phdr2 = gelf_getphdr (ebl->elf, inner, &phdr2_mem);
3251dbace2389b6f89cd4f8f2713aac50a16b16964a2Ulrich Drepper	      if (phdr2 != NULL
3252dbace2389b6f89cd4f8f2713aac50a16b16964a2Ulrich Drepper		  && phdr2->p_type == PT_LOAD
3253dbace2389b6f89cd4f8f2713aac50a16b16964a2Ulrich Drepper		  && phdr->p_vaddr >= phdr2->p_vaddr
3254dbace2389b6f89cd4f8f2713aac50a16b16964a2Ulrich Drepper		  && (phdr->p_vaddr + phdr->p_memsz
32550a545e678f2c0605ba050b4f72080572ac7c8470Mark Wielaard		      <= phdr2->p_vaddr + phdr2->p_memsz))
32560a545e678f2c0605ba050b4f72080572ac7c8470Mark Wielaard		break;
3257dbace2389b6f89cd4f8f2713aac50a16b16964a2Ulrich Drepper	    }
32580a545e678f2c0605ba050b4f72080572ac7c8470Mark Wielaard
32590a545e678f2c0605ba050b4f72080572ac7c8470Mark Wielaard	  if (inner >= ehdr->e_phnum)
32600a545e678f2c0605ba050b4f72080572ac7c8470Mark Wielaard	    ERROR (gettext ("\
3261dbace2389b6f89cd4f8f2713aac50a16b16964a2Ulrich Drepper%s segment not contained in a loaded segment\n"), "PHDR");
3262dbace2389b6f89cd4f8f2713aac50a16b16964a2Ulrich Drepper
3263dbace2389b6f89cd4f8f2713aac50a16b16964a2Ulrich Drepper	  /* Check that offset in segment corresponds to offset in ELF
3264dbace2389b6f89cd4f8f2713aac50a16b16964a2Ulrich Drepper	     header.  */
3265dbace2389b6f89cd4f8f2713aac50a16b16964a2Ulrich Drepper	  if (phdr->p_offset != ehdr->e_phoff)
3266dbace2389b6f89cd4f8f2713aac50a16b16964a2Ulrich Drepper	    ERROR (gettext ("\
3267dbace2389b6f89cd4f8f2713aac50a16b16964a2Ulrich Drepperprogram header offset in ELF header and PHDR entry do not match"));
3268dbace2389b6f89cd4f8f2713aac50a16b16964a2Ulrich Drepper	}
3269dbace2389b6f89cd4f8f2713aac50a16b16964a2Ulrich Drepper
3270dbace2389b6f89cd4f8f2713aac50a16b16964a2Ulrich Drepper      if (phdr->p_filesz > phdr->p_memsz)
3271dbace2389b6f89cd4f8f2713aac50a16b16964a2Ulrich Drepper	ERROR (gettext ("\
3272dbace2389b6f89cd4f8f2713aac50a16b16964a2Ulrich Drepperprogram header entry %d: file size greater than memory size\n"),
3273dbace2389b6f89cd4f8f2713aac50a16b16964a2Ulrich Drepper	       cnt);
3274dbace2389b6f89cd4f8f2713aac50a16b16964a2Ulrich Drepper
3275dbace2389b6f89cd4f8f2713aac50a16b16964a2Ulrich Drepper      if (phdr->p_align > 1)
3276dbace2389b6f89cd4f8f2713aac50a16b16964a2Ulrich Drepper	{
3277dbace2389b6f89cd4f8f2713aac50a16b16964a2Ulrich Drepper	  if (!powerof2 (phdr->p_align))
3278dbace2389b6f89cd4f8f2713aac50a16b16964a2Ulrich Drepper	    ERROR (gettext ("\
3279dbace2389b6f89cd4f8f2713aac50a16b16964a2Ulrich Drepperprogram header entry %d: alignment not a power of 2\n"), cnt);
3280dbace2389b6f89cd4f8f2713aac50a16b16964a2Ulrich Drepper	  else if ((phdr->p_vaddr - phdr->p_offset) % phdr->p_align != 0)
3281dbace2389b6f89cd4f8f2713aac50a16b16964a2Ulrich Drepper	    ERROR (gettext ("\
3282dbace2389b6f89cd4f8f2713aac50a16b16964a2Ulrich Drepperprogram header entry %d: file offset and virtual address not module of alignment\n"), cnt);
3283dbace2389b6f89cd4f8f2713aac50a16b16964a2Ulrich Drepper	}
3284dbace2389b6f89cd4f8f2713aac50a16b16964a2Ulrich Drepper    }
3285dbace2389b6f89cd4f8f2713aac50a16b16964a2Ulrich Drepper}
3286dbace2389b6f89cd4f8f2713aac50a16b16964a2Ulrich Drepper
3287dbace2389b6f89cd4f8f2713aac50a16b16964a2Ulrich Drepper
3288dbace2389b6f89cd4f8f2713aac50a16b16964a2Ulrich Drepper/* Process one file.  */
3289dbace2389b6f89cd4f8f2713aac50a16b16964a2Ulrich Drepperstatic void
3290dbace2389b6f89cd4f8f2713aac50a16b16964a2Ulrich Drepperprocess_elf_file (Elf *elf, const char *prefix, const char *suffix,
3291dbace2389b6f89cd4f8f2713aac50a16b16964a2Ulrich Drepper		  const char *fname, size_t size, bool only_one)
32926247d634c33be4c9ee4bfc650bb8f06f5add41e5Ulrich Drepper{
3293dbace2389b6f89cd4f8f2713aac50a16b16964a2Ulrich Drepper  /* Reset variables.  */
3294dbace2389b6f89cd4f8f2713aac50a16b16964a2Ulrich Drepper  ndynamic = 0;
3295dbace2389b6f89cd4f8f2713aac50a16b16964a2Ulrich Drepper  nverneed = 0;
3296dbace2389b6f89cd4f8f2713aac50a16b16964a2Ulrich Drepper  nverdef = 0;
3297dbace2389b6f89cd4f8f2713aac50a16b16964a2Ulrich Drepper  textrel = false;
3298dbace2389b6f89cd4f8f2713aac50a16b16964a2Ulrich Drepper  needed_textrel = false;
3299dbace2389b6f89cd4f8f2713aac50a16b16964a2Ulrich Drepper  has_loadable_segment = false;
3300dbace2389b6f89cd4f8f2713aac50a16b16964a2Ulrich Drepper  has_interp_segment = false;
3301dbace2389b6f89cd4f8f2713aac50a16b16964a2Ulrich Drepper
3302dbace2389b6f89cd4f8f2713aac50a16b16964a2Ulrich Drepper  GElf_Ehdr ehdr_mem;
3303c2e3135df6741db94a9ec98f1eb57b02277a00b8Ulrich Drepper  GElf_Ehdr *ehdr = gelf_getehdr (elf, &ehdr_mem);
3304c2e3135df6741db94a9ec98f1eb57b02277a00b8Ulrich Drepper  Ebl *ebl;
33050a545e678f2c0605ba050b4f72080572ac7c8470Mark Wielaard
33060a545e678f2c0605ba050b4f72080572ac7c8470Mark Wielaard  /* Print the file name.  */
3307c2e3135df6741db94a9ec98f1eb57b02277a00b8Ulrich Drepper  if (!only_one)
33080a545e678f2c0605ba050b4f72080572ac7c8470Mark Wielaard    {
33090a545e678f2c0605ba050b4f72080572ac7c8470Mark Wielaard      if (prefix != NULL)
33100a545e678f2c0605ba050b4f72080572ac7c8470Mark Wielaard	printf ("\n%s(%s)%s:\n", prefix, fname, suffix);
3311c2e3135df6741db94a9ec98f1eb57b02277a00b8Ulrich Drepper      else
3312c2e3135df6741db94a9ec98f1eb57b02277a00b8Ulrich Drepper	printf ("\n%s:\n", fname);
3313c2e3135df6741db94a9ec98f1eb57b02277a00b8Ulrich Drepper    }
3314c2e3135df6741db94a9ec98f1eb57b02277a00b8Ulrich Drepper
3315c2e3135df6741db94a9ec98f1eb57b02277a00b8Ulrich Drepper  if (ehdr == NULL)
3316c2e3135df6741db94a9ec98f1eb57b02277a00b8Ulrich Drepper    {
3317c2e3135df6741db94a9ec98f1eb57b02277a00b8Ulrich Drepper      ERROR (gettext ("cannot read ELF header: %s\n"), elf_errmsg (-1));
3318dbace2389b6f89cd4f8f2713aac50a16b16964a2Ulrich Drepper      return;
3319dbace2389b6f89cd4f8f2713aac50a16b16964a2Ulrich Drepper    }
3320dbace2389b6f89cd4f8f2713aac50a16b16964a2Ulrich Drepper
3321dbace2389b6f89cd4f8f2713aac50a16b16964a2Ulrich Drepper  ebl = ebl_openbackend (elf);
3322dbace2389b6f89cd4f8f2713aac50a16b16964a2Ulrich Drepper  /* If there is no appropriate backend library we cannot test
3323dbace2389b6f89cd4f8f2713aac50a16b16964a2Ulrich Drepper     architecture and OS specific features.  Any encountered extension
3324dbace2389b6f89cd4f8f2713aac50a16b16964a2Ulrich Drepper     is an error.  */
3325dbace2389b6f89cd4f8f2713aac50a16b16964a2Ulrich Drepper
3326dbace2389b6f89cd4f8f2713aac50a16b16964a2Ulrich Drepper  /* Go straight by the gABI, check all the parts in turn.  */
3327dbace2389b6f89cd4f8f2713aac50a16b16964a2Ulrich Drepper  check_elf_header (ebl, ehdr, size);
3328dbace2389b6f89cd4f8f2713aac50a16b16964a2Ulrich Drepper
3329dbace2389b6f89cd4f8f2713aac50a16b16964a2Ulrich Drepper  /* Check the program header.  */
3330dbace2389b6f89cd4f8f2713aac50a16b16964a2Ulrich Drepper  check_program_header (ebl, ehdr);
3331dbace2389b6f89cd4f8f2713aac50a16b16964a2Ulrich Drepper
3332dbace2389b6f89cd4f8f2713aac50a16b16964a2Ulrich Drepper  /* Next the section headers.  It is OK if there are no section
3333dbace2389b6f89cd4f8f2713aac50a16b16964a2Ulrich Drepper     headers at all.  */
3334dbace2389b6f89cd4f8f2713aac50a16b16964a2Ulrich Drepper  check_sections (ebl, ehdr);
3335dbace2389b6f89cd4f8f2713aac50a16b16964a2Ulrich Drepper
3336dbace2389b6f89cd4f8f2713aac50a16b16964a2Ulrich Drepper  /* Report if no relocation section needed the text relocation flag.  */
3337dbace2389b6f89cd4f8f2713aac50a16b16964a2Ulrich Drepper  if (textrel && !needed_textrel)
3338dbace2389b6f89cd4f8f2713aac50a16b16964a2Ulrich Drepper    ERROR (gettext ("text relocation flag set but not needed\n"));
33390a545e678f2c0605ba050b4f72080572ac7c8470Mark Wielaard
33400a545e678f2c0605ba050b4f72080572ac7c8470Mark Wielaard  /* Free the resources.  */
3341dbace2389b6f89cd4f8f2713aac50a16b16964a2Ulrich Drepper  ebl_closebackend (ebl);
33420a545e678f2c0605ba050b4f72080572ac7c8470Mark Wielaard}
33430a545e678f2c0605ba050b4f72080572ac7c8470Mark Wielaard