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