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