]> git.ipfire.org Git - pakfire.git/commitdiff
stripper: Identify source files
authorMichael Tremer <michael.tremer@ipfire.org>
Tue, 22 Oct 2024 09:23:34 +0000 (09:23 +0000)
committerMichael Tremer <michael.tremer@ipfire.org>
Tue, 22 Oct 2024 15:10:56 +0000 (15:10 +0000)
Signed-off-by: Michael Tremer <michael.tremer@ipfire.org>
src/libpakfire/include/pakfire/stripper.h
src/libpakfire/stripper.c

index 84d9dff0a2eedb497f587cfd94a6e1c12858ee2c..dd30ced67fc45b7d831fea5b5cb27234d0f425e8 100644 (file)
@@ -23,6 +23,9 @@
 
 #ifdef PAKFIRE_PRIVATE
 
+#define BUILD_SRC_DIR "/build/source"
+#define DEBUG_SRC_DIR "/usr/src/debug"
+
 struct pakfire_stripper;
 
 int pakfire_stripper_create(struct pakfire_stripper** stripper,
index b8e9c84a5b1c74b6ed6d18e0e14f663240b6f07c..cc73f51936afd1c807fab008c125d8e9564d7f87 100644 (file)
 #include <errno.h>
 #include <stdlib.h>
 
+// libdw
+#include <elfutils/libdw.h>
+
 #include <pakfire/filelist.h>
 #include <pakfire/pakfire.h>
+#include <pakfire/path.h>
 #include <pakfire/string.h>
 #include <pakfire/stripper.h>
 
@@ -147,6 +151,106 @@ ERROR:
        return r;
 }
 
+static int pakfire_stripper_copy_source_file(
+               struct pakfire_stripper* stripper, const char* filename) {
+       printf("FILENAME = %s\n", filename);
+
+       return 0;
+}
+
+static int pakfire_stripper_copy_sources(
+               struct pakfire* pakfire, struct pakfire_file* file, void* data) {
+       struct pakfire_stripper* stripper = data;
+       const char* filename = NULL;
+       char basename[PATH_MAX];
+       Dwarf* dwarf = NULL;
+       Dwarf_Files* files = NULL;
+       Dwarf_Die* die = NULL;
+       Dwarf_Off offset = 0;
+       Dwarf_Off next_offset;
+       size_t cu_header_length;
+       Dwarf_Die die_mem;
+       size_t count;
+       FILE* f = NULL;
+       int r;
+
+       // Open the file
+       f = pakfire_file_open(file);
+       if (!f) {
+               r = -errno;
+               goto ERROR;
+       }
+
+       // Read DWARF information
+       dwarf = dwarf_begin(fileno(f), DWARF_C_READ);
+       if (!dwarf) {
+               CTX_ERROR(stripper->ctx, "Could not initialize DWARF context: %s\n",
+                               dwarf_errmsg(-1));
+               r = -errno;
+               goto ERROR;
+       }
+
+       for (;;) {
+               // Fetch the next compilation unit
+               r = dwarf_nextcu(dwarf, offset, &next_offset, &cu_header_length, NULL, NULL, NULL);
+               if (r < 0)
+                       goto ERROR;
+
+               // Fetch the Debug Information Entry
+               die = dwarf_offdie(dwarf, offset + cu_header_length, &die_mem);
+               if (!die)
+                       break;
+
+               // Fetch the source files
+               r = dwarf_getsrcfiles(die, &files, &count);
+               if (r < 0) {
+                       CTX_ERROR(stripper->ctx, "Could not fetch the source files: %s\n",
+                                       dwarf_errmsg(-1));
+                       r = -errno;
+                       goto ERROR;
+               }
+
+               // Iterate over all files...
+               for (unsigned int i = 0; i < count; i++) {
+                       // Fetch the filename
+                       filename = dwarf_filesrc(files, i, NULL, NULL);
+
+                       // If the source file is not in the right path, we ignore it
+                       if (!pakfire_string_startswith(filename, BUILD_SRC_DIR))
+                               continue;
+
+                       // Determine the basename
+                       r = pakfire_path_basename(basename, filename);
+                       if (r < 0)
+                               goto ERROR;
+
+                       // Ignore things like <artificial> or <built-in>
+                       if (pakfire_string_startswith(basename, "<") && pakfire_string_endswith(basename, ">"))
+                               continue;
+
+                       CTX_DEBUG(stripper->ctx, "Found source file: %s\n", filename);
+
+                       // Copy the file
+                       r = pakfire_stripper_copy_source_file(stripper, filename);
+                       if (r < 0) {
+                               CTX_ERROR(stripper->ctx, "Could not copy source file %s: %s\n",
+                                       filename, strerror(-r));
+                               goto ERROR;
+                       }
+               }
+
+               offset = next_offset;
+       }
+
+ERROR:
+       if (f)
+               fclose(f);
+       if (dwarf)
+               dwarf_end(dwarf);
+
+       return r;
+}
+
 int pakfire_stripper_run(struct pakfire_stripper* stripper) {
        int r;
 
@@ -159,7 +263,10 @@ int pakfire_stripper_run(struct pakfire_stripper* stripper) {
        if (pakfire_filelist_is_empty(stripper->filelist))
                return 0;
 
-       // XXX TODO
+       // Copy sources
+       r = pakfire_filelist_walk(stripper->filelist, pakfire_stripper_copy_sources, stripper, 0);
+       if (r < 0)
+               return r;
 
        return 0;
 }