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