[PATCH] elfclassify: Add --library classification.
Mark Wielaard
mark@klomp.org
Thu Jul 25 22:39:00 GMT 2019
> 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
More information about the Elfutils-devel
mailing list