aboutsummaryrefslogtreecommitdiff
path: root/lib/shlib.c
diff options
context:
space:
mode:
authorJoseph Hunkeler <jhunkeler@gmail.com>2020-03-18 22:25:27 -0400
committerJoseph Hunkeler <jhunkeler@gmail.com>2020-03-18 22:25:27 -0400
commitccaeb7092b5ad40b1b3833c987ba3ec4d47f0bb8 (patch)
treeae167772a9a2343aa77bf8944b56abe853f6a2ec /lib/shlib.c
parent3731bb4679ee8716d4f579d5744c36a2d1b4a257 (diff)
downloadspmc-ccaeb7092b5ad40b1b3833c987ba3ec4d47f0bb8.tar.gz
Refactor project: build/install libspm[_static.a].so to make unit testing possible
Diffstat (limited to 'lib/shlib.c')
-rw-r--r--lib/shlib.c72
1 files changed, 72 insertions, 0 deletions
diff --git a/lib/shlib.c b/lib/shlib.c
new file mode 100644
index 0000000..a8222af
--- /dev/null
+++ b/lib/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, SHELL_INVALID);
+ snprintf(cmd, sizeof(cmd), "%s %s '%s'", SPM_SHLIB_EXEC, "-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")) {
+ char **field = split(data[i], " ");
+ strlist_append(result, field[1]);
+ split_free(field);
+ }
+ }
+
+ free(output);
+ split_free(data);
+ return result;
+}