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