Skip to content
Snippets Groups Projects

Add inspect-library helper

Merged Ludovico de Nittis requested to merge wip/denittis/inspect-library into master
Compare and Show latest version
2 files
+ 36
31
Compare changes
  • Side-by-side
  • Inline
Files
2
+ 35
30
@@ -28,7 +28,8 @@
* JSON with the path and the dependencies of the requested library.
*/
#include <glib.h>
#include <stdio.h>
#include <string.h>
#include <dlfcn.h>
#include <link.h>
@@ -44,36 +45,36 @@ main (int argc,
const char *version;
const char *symbol;
void *handle = NULL;
/* 4096 should be the standard PATH_MAX */
char library_path[4096];
struct link_map *dep_map = NULL;
const int SYMBOL_START = 2;
if (argc < 2)
{
g_warning ("Expected one SONAME as argument.\n");
fprintf (stderr, "Expected one SONAME as argument.\n");
return 1;
}
soname = argv[1];
g_print ("{\n");
g_print (" \"%s\": {", soname);
handle = dlopen (soname, RTLD_LAZY);
printf ("{\n");
printf (" \"%s\": {", soname);
handle = dlopen (soname, RTLD_NOW);
if (handle == NULL)
{
g_warning ("Unable to find the library: %s\n", dlerror ());
fprintf (stderr, "Unable to find the library: %s\n", dlerror ());
clean_exit (handle);
return 1;
}
if (dlinfo (handle, RTLD_DI_ORIGIN, library_path) != 0)
/* Using RTLD_DI_LINKMAP insted of RTLD_DI_ORIGIN we don't need to worry
* about allocating a big enough array for the path. */
if (dlinfo (handle, RTLD_DI_LINKMAP, &dep_map) != 0 || dep_map == NULL)
{
g_warning ("Unable to obtain the path: %s\n", dlerror ());
fprintf (stderr, "Unable to obtain the path: %s\n", dlerror ());
clean_exit (handle);
return 1;
}
g_print ("\n \"path\": \"%s\",\n", library_path);
printf ("\n \"path\": \"%s\",\n", dep_map->l_name);
g_print (" \"missing_symbols\": [");
printf (" \"missing_symbols\": [");
for (int i = SYMBOL_START; i < argc; i++)
{
version = strsep(&argv[i], "@");
@@ -81,8 +82,8 @@ main (int argc,
if (symbol == NULL)
{
g_warning ("Probably the version@symbol pair is mispelled.");
g_print ("\n ]");
fprintf (stderr, "Probably the version@symbol pair is mispelled.");
printf ("\n ]");
clean_exit (handle);
return 1;
}
@@ -92,9 +93,9 @@ main (int argc,
if (dlsym (handle, symbol) == NULL)
{
if (i == SYMBOL_START)
g_print ("\n \"%s\"", symbol);
printf ("\n \"%s\"", symbol);
else
g_print (",\n \"%s\"", symbol);
printf (",\n \"%s\"", symbol);
}
}
else
@@ -102,35 +103,39 @@ main (int argc,
if (dlvsym (handle, symbol, version) == NULL)
{
if (i == SYMBOL_START)
g_print ("\n \"%s/%s\"", version, symbol);
printf ("\n \"%s/%s\"", version, symbol);
else
g_print (",\n \"%s/%s\"", version, symbol);
printf (",\n \"%s/%s\"", version, symbol);
}
}
}
g_print ("\n ]");
printf ("\n ]");
if (dlinfo (handle, RTLD_DI_LINKMAP, &dep_map) != 0)
{
g_warning ("Unable to obtain the dependencies list: %s\n", dlerror ());
clean_exit (handle);
return 1;
}
/* Some loaded libraries may be before our handle.
* To list them all we move the pointer at the beginning. */
while (dep_map != NULL && dep_map->l_prev != NULL)
dep_map = dep_map->l_prev;
printf (",\n \"dependencies\": [");
/* Some entries don't have a name. We move the pointer to the
* first element that has one. */
while (dep_map != NULL && strcmp (dep_map->l_name, "") == 0)
dep_map = dep_map->l_next;
g_print (",\n \"dependencies\": [");
if (dep_map != NULL)
{
g_print ("\n \"%s\"", dep_map->l_name);
printf ("\n \"%s\"", dep_map->l_name);
dep_map = dep_map->l_next;
}
for (; dep_map != NULL; dep_map = dep_map->l_next)
{
g_print (",\n \"%s\"", dep_map->l_name);
if (strcmp (dep_map->l_name, "") != 0)
printf (",\n \"%s\"", dep_map->l_name);
}
g_print ("\n ]\n }");
printf ("\n ]\n }");
clean_exit (handle);
return 0;
@@ -142,5 +147,5 @@ clean_exit (void *handle)
if (handle != NULL)
dlclose (handle);
g_print ("\n}\n");
printf ("\n}\n");
}
Loading