From 1c23d5929a2f52986b2452fe0e9d34b12b39b313 Mon Sep 17 00:00:00 2001 From: Mark Wielaard Date: Wed, 27 Aug 2025 14:57:44 +0200 Subject: [PATCH] elfclassify: Add --has-debug-sections classification option There is --unstripped but that is whether the ELF file can be stripped (further) by removing any .[z]debug_* sections or symbol table (.symtab section). The --has-debug-sections option only checks whether there are .[z]debug sections present. * src/elfclassify.c (is_has_debug_sections): New function. (enum classify_check): Add classify_has_debug_sections. (check_checks): Add and print (if verbose) classify_has_debug_sections value. (main): Add ar-member to options. Update argp.doc to explain different debug options (--unstripped, --has-debug-section and --debug-only). * tests/run-elfclassify.sh: Add various --has-debug-sections tests. Signed-off-by: Mark Wielaard --- src/elfclassify.c | 25 +++++++++++++++++++++++++ tests/run-elfclassify.sh | 25 +++++++++++++++++++++++++ 2 files changed, 50 insertions(+) diff --git a/src/elfclassify.c b/src/elfclassify.c index 311530d7..fd84f90d 100644 --- a/src/elfclassify.c +++ b/src/elfclassify.c @@ -472,6 +472,16 @@ is_unstripped (void) && (has_symtab || has_debug_sections); } +/* Return true if the file is an ELF file which has .debug_* sections + (note that a symtab is not considered a debug section). */ +static bool +is_has_debug_sections (void) +{ + return elf_kind (elf) != ELF_K_NONE + && (elf_type == ET_REL || elf_type == ET_EXEC || elf_type == ET_DYN) + && has_debug_sections; +} + /* Return true if the file contains only debuginfo, but no loadable program bits. Then it is most likely a separate .debug file, a dwz multi-file or a .dwo file. Note that it can still be loadable, @@ -625,6 +635,7 @@ enum classify_check classify_elf_archive, classify_core, classify_unstripped, + classify_has_debug_sections, classify_executable, classify_program, classify_shared, @@ -753,6 +764,7 @@ check_checks () [classify_elf_archive] = is_elf_archive (), [classify_core] = is_core (), [classify_unstripped] = is_unstripped (), + [classify_has_debug_sections] = is_has_debug_sections (), [classify_executable] = is_executable (), [classify_program] = is_program (), [classify_shared] = is_shared (), @@ -774,6 +786,8 @@ check_checks () fprintf (stderr, "debug: %s: core\n", current_path); if (checks[classify_unstripped]) fprintf (stderr, "debug: %s: unstripped\n", current_path); + if (checks[classify_has_debug_sections]) + fprintf (stderr, "debug: %s: has_debug_sections\n", current_path); if (checks[classify_executable]) fprintf (stderr, "debug: %s: executable\n", current_path); if (checks[classify_program]) @@ -991,6 +1005,8 @@ main (int argc, char **argv) { "unstripped", classify_check_offset + classify_unstripped, NULL, 0, N_("File is an ELF file with symbol table or .debug_* sections \ and can be stripped further"), 1 }, + { "has-debug-sections", classify_check_offset + classify_has_debug_sections, NULL, 0, + N_("File is an ELF file with .debug_* sections"), 1 }, { "executable", classify_check_offset + classify_executable, NULL, 0, N_("File is (primarily) an ELF program executable \ (not primarily a DSO)"), 1 }, @@ -1023,6 +1039,8 @@ and can be stripped further"), 1 }, NULL, OPTION_HIDDEN, NULL, 1 }, { "not-unstripped", classify_check_not_offset + classify_unstripped, NULL, OPTION_HIDDEN, NULL, 1 }, + { "not-has-debug-sections", classify_check_not_offset + classify_has_debug_sections, + NULL, OPTION_HIDDEN, NULL, 1 }, { "not-executable", classify_check_not_offset + classify_executable, NULL, OPTION_HIDDEN, NULL, 1 }, { "not-program", classify_check_not_offset + classify_program, @@ -1105,6 +1123,13 @@ or library) use --loadable. Note that files that only contain \ though they might contain program headers). Linux kernel modules are \ also not --loadable (in the normal sense).\ \n\n\ +Detecting whether an ELF file can be stripped, because it has .[z]debug_* \ +sections and/or a symbol table (.symtab) is done with --unstripped. \ +To detect whether an ELF file just has .[z]debug_* sections use \ +--has-debug-section. Use --debug-only to detect ELF files that contain \ +only debuginfo (possibly just a .symtab), but no loadable program bits \ +(like separate .debug files, dwz multi-files or .dwo files).\ +\n\n\ Without any of the --print options, the program exits with status 0 \ if the requested checks pass for all input files, with 1 if a check \ fails for any file, and 2 if there is an environmental issue (such \ diff --git a/tests/run-elfclassify.sh b/tests/run-elfclassify.sh index a9b4ad76..7835fc97 100755 --- a/tests/run-elfclassify.sh +++ b/tests/run-elfclassify.sh @@ -254,6 +254,12 @@ testrun_compare ${abs_top_builddir}/src/elfclassify --unstripped --print $kmod_f $(echo $kmod_files | sed -e "s/ /\n/g") EOF +echo "kmods are have debug sections" +testrun ${abs_top_builddir}/src/elfclassify --has-debug-sections $kmod_files +testrun_compare ${abs_top_builddir}/src/elfclassify --has-debug-sections --print $kmod_files <