> 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