This is the mail archive of the elfutils-devel@sourceware.org mailing list for the elfutils project.


Index Nav: [Date Index] [Subject Index] [Author Index] [Thread Index]
Message Nav: [Date Prev] [Date Next] [Thread Prev] [Thread Next]
Other format: [Raw text]

[PATCH] elfclassify: Add --library classification.


> Maybe you are looking for another goal/classification?  For example I
> added --program which does classify those special files as programs
> (even though --shared also says they are shared libraries). Maybe you
> are looking for a different classification similar/dual to that. Say
> --library?

This patch implements this and updates the --help text to better explain
the differenes between --loadable, --shared/--executable and
--program/--library.

Does this look reasonable?

Cheers,

Mark
---
 src/elfclassify.c | 59 +++++++++++++++++++++++++++++++++++++++--------
 1 file changed, 50 insertions(+), 9 deletions(-)

diff --git a/src/elfclassify.c b/src/elfclassify.c
index 1df0789d..ebd42c1d 100644
--- a/src/elfclassify.c
+++ b/src/elfclassify.c
@@ -583,6 +583,30 @@ is_program (void)
   return false;
 }
 
+/* Like is_shared but the library could also be an executable.  */
+static bool
+is_library  (void)
+{
+  /* Only ET_DYN can be shared libraries.  */
+  if (elf_type != ET_DYN)
+    return false;
+
+  if (!is_loadable ())
+    return false;
+
+  /* Without a PT_DYNAMIC segment the library cannot be loaded.  */
+  if (!has_dynamic)
+    return false;
+
+  /* This really is a (PIE) executable.  See is_shared.  */
+  if (has_pie_flag || has_dt_debug)
+    return false;
+
+  /* It could still (also) be a (PIE) executable, but most likely you
+     can dlopen it just fine.  */
+  return true;
+}
+
 /* Returns true if the file is a linux kernel module (is ET_REL and
    has the two magic sections .modinfo and .gnu.linkonce.this_module).  */
 static bool
@@ -606,6 +630,7 @@ enum classify_check
   classify_executable,
   classify_program,
   classify_shared,
+  classify_library,
   classify_linux_kernel_module,
   classify_debug_only,
   classify_loadable,
@@ -733,6 +758,7 @@ process_current_path (int *status)
 	 [classify_executable] = is_executable (),
 	 [classify_program] = is_program (),
 	 [classify_shared] = is_shared (),
+	 [classify_library] = is_library (),
 	 [classify_linux_kernel_module] = is_linux_kernel_module (),
 	 [classify_debug_only] = is_debug_only (),
 	 [classify_loadable] = is_loadable (),
@@ -756,6 +782,8 @@ process_current_path (int *status)
             fprintf (stderr, "debug: %s: program\n", current_path);
           if (checks[classify_shared])
             fprintf (stderr, "debug: %s: shared\n", current_path);
+          if (checks[classify_library])
+            fprintf (stderr, "debug: %s: library\n", current_path);
 	  if (checks[classify_linux_kernel_module])
 	    fprintf (stderr, "debug: %s: linux kernel module\n", current_path);
 	  if (checks[classify_debug_only])
@@ -853,7 +881,7 @@ main (int argc, char **argv)
         N_("File looks like an ELF object or archive/static library (default)")
 	, 1 },
       { "elf-file", classify_check_offset + classify_elf_file, NULL, 0,
-        N_("File is an regular ELF object (not an archive/static library")
+        N_("File is an regular ELF object (not an archive/static library)")
 	, 1 },
       { "elf-archive", classify_check_offset + classify_elf_archive, NULL, 0,
         N_("File is an ELF archive or static library")
@@ -865,13 +893,17 @@ main (int argc, char **argv)
         N_("File is an ELF file with symbol table or .debug_* sections \
 and can be stripped further"), 1 },
       { "executable", classify_check_offset + classify_executable, NULL, 0,
-        N_("File is an ELF program executable \
-(and not also a shared library)"), 1 },
+        N_("File is (primarily) an ELF program executable \
+(not primarily a DSO)"), 1 },
       { "program", classify_check_offset + classify_program, NULL, 0,
         N_("File is an ELF program executable \
-(might also be a shared library)"), 1 },
+(might also be a DSO)"), 1 },
       { "shared", classify_check_offset + classify_shared, NULL, 0,
-        N_("File is an ELF shared object (DSO)"), 1 },
+        N_("File is (primarily) an ELF shared object (DSO) \
+(not primarily an executable)"), 1 },
+      { "library", classify_check_offset + classify_library, NULL, 0,
+        N_("File is an ELF shared object (DSO) \
+(might also be an executable)"), 1 },
       { "linux-kernel-module", (classify_check_offset
 				+ classify_linux_kernel_module), NULL, 0,
         N_("File is a linux kernel module"), 1 },
@@ -898,6 +930,8 @@ and can be stripped further"), 1 },
         NULL, OPTION_HIDDEN, NULL, 1 },
       { "not-shared", classify_check_not_offset + classify_shared,
         NULL, OPTION_HIDDEN, NULL, 1 },
+      { "not-library", classify_check_not_offset + classify_library,
+        NULL, OPTION_HIDDEN, NULL, 1 },
       { "not-linux-kernel-module", (classify_check_not_offset
 				    + classify_linux_kernel_module),
         NULL, OPTION_HIDDEN, NULL, 1 },
@@ -956,10 +990,17 @@ particular file.  Classification options can be negated using a \
 Since modern ELF does not clearly distinguish between programs and \
 dynamic shared objects, you should normally use either --executable or \
 --shared to identify the primary purpose of a file.  \
-Only one of the --shared and --executable checks can pass for a file.  \
-If you want to know whether an ELF object might be both a program and a \
-shared library at the same time use --program --shared.  \
---executable is effectively the same as --program --not-shared.\
+Only one of the --shared and --executable checks can pass for a file.\
+\n\n\
+If you want to know whether an ELF object might a program or a \
+shared library (but could be both), then use --program or --library. \
+Some ELF files will classify as both a program and a library.\
+\n\n\
+If you just want to know whether an ELF file is loadable (as program \
+or library) use --loadable.  Note that files that only contain \
+(separate) debug information (--debug-only) are never --loadable (even \
+though they might contain program headers).  Linux kernel modules are \
+also not --loadable (in the normal sense).\
 \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 \
-- 
2.18.1


Index Nav: [Date Index] [Subject Index] [Author Index] [Thread Index]
Message Nav: [Date Prev] [Date Next] [Thread Prev] [Thread Next]