diff options
Diffstat (limited to 'src/elflint.c')
| -rw-r--r-- | src/elflint.c | 42 |
1 files changed, 38 insertions, 4 deletions
diff --git a/src/elflint.c b/src/elflint.c index 23b0f496..1c508c47 100644 --- a/src/elflint.c +++ b/src/elflint.c @@ -56,10 +56,10 @@ /* Name and version of program. */ static void print_version (FILE *stream, struct argp_state *state); -void (*argp_program_version_hook) (FILE *, struct argp_state *) = print_version; +ARGP_PROGRAM_VERSION_HOOK_DEF = print_version; /* Bug report address. */ -const char *argp_program_bug_address = PACKAGE_BUGREPORT; +ARGP_PROGRAM_BUG_ADDRESS_DEF = PACKAGE_BUGREPORT; #define ARGP_strict 300 #define ARGP_gnuld 301 @@ -67,7 +67,6 @@ const char *argp_program_bug_address = PACKAGE_BUGREPORT; /* Definitions of arguments for argp functions. */ static const struct argp_option options[] = { - { "strict", ARGP_strict, NULL, 0, N_("Be extremely strict, flag level 2 features."), 0 }, { "quiet", 'q', NULL, 0, N_("Do not print anything if successful"), 0 }, @@ -4132,7 +4131,7 @@ more than one GNU_RELRO entry in program header\n")); if ((phdr2->p_flags & PF_W) == 0) ERROR (gettext ("\ loadable segment GNU_RELRO applies to is not writable\n")); - if ((phdr2->p_flags &~ PF_W) != (phdr->p_flags &~ PF_W)) + if ((phdr2->p_flags & ~PF_W) != (phdr->p_flags & ~PF_W)) ERROR (gettext ("\ loadable segment [%u] flags do not match GNU_RELRO [%u] flags\n"), cnt, inner); @@ -4173,6 +4172,41 @@ loadable segment [%u] flags do not match GNU_RELRO [%u] flags\n"), ERROR (gettext ("\ program header offset in ELF header and PHDR entry do not match")); } + else if (phdr->p_type == PT_GNU_EH_FRAME) + { + /* If there is an .eh_frame_hdr section it must be + referenced by this program header entry. */ + Elf_Scn *scn = NULL; + while ((scn = elf_nextscn (ebl->elf, scn)) != NULL) + { + GElf_Shdr shdr_mem; + GElf_Shdr *shdr = gelf_getshdr (scn, &shdr_mem); + if (shdr != NULL && shdr->sh_type == SHT_PROGBITS + && ! strcmp (".eh_frame_hdr", + elf_strptr (ebl->elf, shstrndx, shdr->sh_name))) + { + if (phdr->p_offset != shdr->sh_offset) + ERROR (gettext ("\ +call frame search table reference in program header has wrong offset\n")); + if (phdr->p_memsz != shdr->sh_size) + ERROR (gettext ("\ +call frame search table size mismatch in program and section header\n")); + break; + } + } + + /* The section must be allocated and not be writable and + executable. */ + if ((phdr->p_flags & PF_R) == 0) + ERROR (gettext ("\ +call frame search table must be allocated\n")); + if ((phdr->p_flags & PF_W) != 0) + ERROR (gettext ("\ +call frame search table must not be writable\n")); + if ((phdr->p_flags & PF_X) != 0) + ERROR (gettext ("\ +call frame search table must not be executable\n")); + } if (phdr->p_filesz > phdr->p_memsz && (phdr->p_memsz != 0 || phdr->p_type != PT_NOTE)) |
