#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>
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;
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;
}