aboutsummaryrefslogtreecommitdiff
path: root/src
diff options
context:
space:
mode:
authorJoseph Hunkeler <jhunkeler@gmail.com>2020-02-07 00:54:06 -0500
committerJoseph Hunkeler <jhunkeler@gmail.com>2020-02-07 00:54:06 -0500
commit88df453f8c5ea045f9c3734c1c74b33ac7b27a79 (patch)
tree174c494f397140a9eeb3327f7e4004fca97cb3bb /src
parent268f1a9c925d44e5e3e2a0c4f804d4108e1dab90 (diff)
downloadspmc-88df453f8c5ea045f9c3734c1c74b33ac7b27a79.tar.gz
Initial commit of shlib interface
Diffstat (limited to 'src')
-rw-r--r--src/shlib.c72
1 files changed, 72 insertions, 0 deletions
diff --git a/src/shlib.c b/src/shlib.c
new file mode 100644
index 0000000..b9cb3d7
--- /dev/null
+++ b/src/shlib.c
@@ -0,0 +1,72 @@
+#include "spm.h"
+#include "shlib.h"
+
+char *shlib_deps_objdump(const char *_filename) {
+ // do not expose this function
+ char *filename = NULL;
+ char *result = NULL;
+ Process *proc = NULL;
+ char cmd[PATH_MAX];
+ memset(cmd, '\0', sizeof(cmd));
+
+ if ((filename = strdup(_filename)) == NULL) {
+ fprintf(SYSERROR);
+ return NULL;
+ }
+
+ strchrdel(filename, "&;|");
+ snprintf(cmd, sizeof(cmd), "%s %s '%s'", "objdump", "-p", filename);
+ shell(&proc, SHELL_OUTPUT, cmd);
+
+ if (proc->returncode != 0) {
+ free(filename);
+ shell_free(proc);
+ return NULL;
+ }
+ result = strdup(proc->output);
+
+ free(filename);
+ shell_free(proc);
+ return result;
+}
+
+StrList *shlib_deps(const char *filename) {
+ char **data = NULL;
+ char *output = NULL;
+ StrList *result = NULL;
+
+ // Get output from objdump
+ // TODO: use preprocessor or another function to select the correct shlib_deps_*() in the future
+ if ((output = shlib_deps_objdump(filename)) == NULL) {
+ return NULL;
+ }
+
+ // Initialize list array
+ if ((result = strlist_init()) == NULL) {
+ free(output);
+ return NULL;
+ }
+
+ // Split output into individual lines
+ if ((data = split(output, "\n")) == NULL) {
+ free(output);
+ strlist_free(result);
+ return NULL;
+ }
+
+ // Parse output:
+ // Collapse whitespace and extract the NEEDED libraries (second field)
+ // AFAIK when "NEEDED" is present, a string containing the library name is guaranteed to be there
+ for (size_t i = 0; data[i] != NULL; i++) {
+ data[i] = normalize_space(data[i]);
+ if (startswith(data[i], "NEEDED") == 0) {
+ char **field = split(data[i], " ");
+ strlist_append(result, field[1]);
+ split_free(field);
+ }
+ }
+
+ free(output);
+ split_free(data);
+ return result;
+}