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 <m...@klomp.org>
---
 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 311530d74dd8..fd84f90dda9f 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 a9b4ad764c02..7835fc973b27 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 <<EOF
+$(echo $kmod_files | sed -e "s/ /\n/g")
+EOF
+
 echo "kmods are not debug-only"
 testrun ${abs_top_builddir}/src/elfclassify --not-debug-only $kmod_files
 testrun_compare ${abs_top_builddir}/src/elfclassify --not-debug-only --print 
$kmod_files <<EOF
@@ -299,6 +305,12 @@ testrun_compare ${abs_top_builddir}/src/elfclassify 
--unstripped --print $debug_
 $(echo $debug_files | sed -e "s/ /\n/g")
 EOF
 
+echo "debug-only files have debug sections"
+testrun ${abs_top_builddir}/src/elfclassify --has-debug-sections $debug_files
+testrun_compare ${abs_top_builddir}/src/elfclassify --has-debug-sections 
--print $debug_files <<EOF
+$(echo $debug_files | sed -e "s/ /\n/g")
+EOF
+
 echo "debug-only files are not programs"
 testrun ${abs_top_builddir}/src/elfclassify --not-program $debug_files
 testrun_compare ${abs_top_builddir}/src/elfclassify --not-program --print 
$debug_files <<EOF
@@ -352,3 +364,16 @@ echo "any-ar-member not-executable"
 testrun_compare ${abs_top_builddir}/src/elfclassify --any-ar-member 
--not-executable --print testarchive64.a test-ar-duplicates.a <<EOF
 testarchive64.a
 EOF
+
+echo "any-ar-member has-debug-sections"
+# Neither has members with actual debug sections.  They both do have
+# members that have symtab so are unstripped (see above).
+testrun_compare ${abs_top_builddir}/src/elfclassify --any-ar-member 
--has-debug-sections --print testarchive64.a test-ar-duplicates.a <<EOF
+EOF
+
+echo "any-ar-member not-has-debug-sections"
+# Noth match (opposite of above)
+testrun_compare ${abs_top_builddir}/src/elfclassify --any-ar-member 
--not-has-debug-sections --print testarchive64.a test-ar-duplicates.a <<EOF
+testarchive64.a
+test-ar-duplicates.a
+EOF
-- 
2.50.1

Reply via email to