From e1083622d34c0f58e060e337aa55773611198ffa Mon Sep 17 00:00:00 2001 From: Michael Tremer Date: Wed, 25 Dec 2024 13:02:58 +0000 Subject: [PATCH] Revert "stripper: Throw this away" This reverts commit 76774bf62a622da82ca589519331371c71b87bf1. Signed-off-by: Michael Tremer --- Makefile.am | 2 + src/libpakfire/build.c | 27 ++ src/libpakfire/include/pakfire/stripper.h | 40 +++ src/libpakfire/stripper.c | 285 ++++++++++++++++++++++ 4 files changed, 354 insertions(+) create mode 100644 src/libpakfire/include/pakfire/stripper.h create mode 100644 src/libpakfire/stripper.c diff --git a/Makefile.am b/Makefile.am index 8b03d9ad1..706b3c819 100644 --- a/Makefile.am +++ b/Makefile.am @@ -233,6 +233,7 @@ libpakfire_la_SOURCES = \ src/libpakfire/snapshot.c \ src/libpakfire/solution.c \ src/libpakfire/string.c \ + src/libpakfire/stripper.c \ src/libpakfire/transaction.c \ src/libpakfire/util.c \ src/libpakfire/xfer.c @@ -289,6 +290,7 @@ pkginclude_HEADERS += \ src/libpakfire/include/pakfire/snapshot.h \ src/libpakfire/include/pakfire/solution.h \ src/libpakfire/include/pakfire/string.h \ + src/libpakfire/include/pakfire/stripper.h \ src/libpakfire/include/pakfire/syscalls.h \ src/libpakfire/include/pakfire/transaction.h \ src/libpakfire/include/pakfire/util.h \ diff --git a/src/libpakfire/build.c b/src/libpakfire/build.c index 08fa21604..f53e35ed5 100644 --- a/src/libpakfire/build.c +++ b/src/libpakfire/build.c @@ -49,6 +49,7 @@ #include #include #include +#include #include #include @@ -1287,6 +1288,27 @@ static int pakfire_build_run_post_build_scripts(struct pakfire_build* build) { return 0; } +static int pakfire_build_strip(struct pakfire_build* build) { + struct pakfire_stripper* stripper = NULL; + int r; + + // Create a new stripper + r = pakfire_stripper_create(&stripper, build->pakfire, build->buildroot); + if (r < 0) + goto ERROR; + + // Strip! + r = pakfire_stripper_run(stripper); + if (r < 0) + goto ERROR; + +ERROR: + if (stripper) + pakfire_stripper_unref(stripper); + + return r; +} + static void pakfire_build_free(struct pakfire_build* build) { if (build->packages) pakfire_packagelist_unref(build->packages); @@ -1811,6 +1833,11 @@ static int pakfire_build_perform(struct pakfire_build* build, if (r) goto ERROR; + // Run the stripper + r = pakfire_build_strip(build); + if (r < 0) + goto ERROR; + // Done! return 0; diff --git a/src/libpakfire/include/pakfire/stripper.h b/src/libpakfire/include/pakfire/stripper.h new file mode 100644 index 000000000..dd30ced67 --- /dev/null +++ b/src/libpakfire/include/pakfire/stripper.h @@ -0,0 +1,40 @@ +/*############################################################################# +# # +# Pakfire - The IPFire package management system # +# Copyright (C) 2024 Pakfire development team # +# # +# This program is free software: you can redistribute it and/or modify # +# it under the terms of the GNU General Public License as published by # +# the Free Software Foundation, either version 3 of the License, or # +# (at your option) any later version. # +# # +# This program is distributed in the hope that it will be useful, # +# but WITHOUT ANY WARRANTY; without even the implied warranty of # +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the # +# GNU General Public License for more details. # +# # +# You should have received a copy of the GNU General Public License # +# along with this program. If not, see . # +# # +#############################################################################*/ + +#ifndef PAKFIRE_STRIPPER_H +#define PAKFIRE_STRIPPER_H + +#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, + struct pakfire* pakfire, const char* path); + +struct pakfire_stripper* pakfire_stripper_ref(struct pakfire_stripper* stripper); +struct pakfire_stripper* pakfire_stripper_unref(struct pakfire_stripper* stripper); + +int pakfire_stripper_run(struct pakfire_stripper* stripper); + +#endif /* PAKFIRE_PRIVATE */ +#endif /* PAKFIRE_STRIPPER_H */ diff --git a/src/libpakfire/stripper.c b/src/libpakfire/stripper.c new file mode 100644 index 000000000..f3dedf975 --- /dev/null +++ b/src/libpakfire/stripper.c @@ -0,0 +1,285 @@ +/*############################################################################# +# # +# Pakfire - The IPFire package management system # +# Copyright (C) 2023 Pakfire development team # +# # +# This program is free software: you can redistribute it and/or modify # +# it under the terms of the GNU General Public License as published by # +# the Free Software Foundation, either version 3 of the License, or # +# (at your option) any later version. # +# # +# This program is distributed in the hope that it will be useful, # +# but WITHOUT ANY WARRANTY; without even the implied warranty of # +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the # +# GNU General Public License for more details. # +# # +# You should have received a copy of the GNU General Public License # +# along with this program. If not, see . # +# # +#############################################################################*/ + +#include +#include + +// libdw +#include + +#include +#include +#include +#include +#include + +struct pakfire_stripper { + struct pakfire_ctx* ctx; + int nrefs; + + // Pakfire + struct pakfire* pakfire; + + // Path + char path[PATH_MAX]; + + // Filelist + struct pakfire_filelist* filelist; +}; + +int pakfire_stripper_create(struct pakfire_stripper** stripper, + struct pakfire* pakfire, const char* path) { + struct pakfire_stripper* s = NULL; + int r; + + // Allocate a new object + s = calloc(1, sizeof(*s)); + if (!s) + return -errno; + + // Store a reference to the context + s->ctx = pakfire_ctx(pakfire); + + // Store a reference to Pakfire + s->pakfire = pakfire_ref(pakfire); + + // Initialize the reference counter + s->nrefs = 1; + + // Store the path + r = pakfire_string_set(s->path, path); + if (r < 0) + goto ERROR; + + // Create a filelist + r = pakfire_filelist_create(&s->filelist, s->pakfire); + if (r < 0) + goto ERROR; + + // Return the pointer + *stripper = pakfire_stripper_ref(s); + +ERROR: + if (s) + pakfire_stripper_unref(s); + + return r; +} + +static void pakfire_stripper_free(struct pakfire_stripper* stripper) { + if (stripper->filelist) + pakfire_filelist_unref(stripper->filelist); + if (stripper->pakfire) + pakfire_unref(stripper->pakfire); + if (stripper->ctx) + pakfire_ctx_unref(stripper->ctx); + free(stripper); +} + +struct pakfire_stripper* pakfire_stripper_ref(struct pakfire_stripper* stripper) { + ++stripper->nrefs; + + return stripper; +} + +struct pakfire_stripper* pakfire_stripper_unref(struct pakfire_stripper* stripper) { + if (--stripper->nrefs > 0) + return stripper; + + pakfire_stripper_free(stripper); + return NULL; +} + +static int pakfire_stripper_find_elf( + struct pakfire_ctx* ctx, struct pakfire_file* file, void* data) { + struct pakfire_stripper* stripper = data; + int r; + + // Add ELF files to the filelist + if (pakfire_file_matches_class(file, PAKFIRE_FILE_ELF)) { + r = pakfire_filelist_add(stripper->filelist, file); + if (r < 0) + return r; + } + + return 0; +} + +/* + Scan all files in path and identify ELF files +*/ +static int pakfire_stripper_scan(struct pakfire_stripper* stripper) { + struct pakfire_filelist* filelist = NULL; + int r; + + // Create a new filelist + r = pakfire_filelist_create(&filelist, stripper->pakfire); + if (r < 0) + goto ERROR; + + // Scan path for all files + r = pakfire_filelist_scan(filelist, stripper->path, NULL, NULL, 0); + if (r < 0) + goto ERROR; + + // Walk through all files to find ELF files + r = pakfire_filelist_walk(filelist, pakfire_stripper_find_elf, stripper, 0); + if (r < 0) + goto ERROR; + +ERROR: + if (filelist) + pakfire_filelist_unref(filelist); + + return r; +} + +static int pakfire_stripper_copy_source_file( + struct pakfire_stripper* stripper, const char* filename) { + printf("FILENAME = %s\n", filename); + + return 0; +} + +/* + libdw does not seem to export the error codes in their header files, + although there is a function to retrieve them... +*/ +#ifndef DWARF_E_NO_DWARF +#define DWARF_E_NO_DWARF 6 +#endif + +static int pakfire_stripper_copy_sources( + struct pakfire_ctx* ctx, 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) { + switch (dwarf_errno()) { + // If we don't have any DWARF information there is nothing to do + case DWARF_E_NO_DWARF: + r = 0; + goto ERROR; + + default: + ERROR(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) { + ERROR(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 or + if (pakfire_string_startswith(basename, "<") && pakfire_string_endswith(basename, ">")) + continue; + + DEBUG(ctx, "Found source file: %s\n", filename); + + // Copy the file + r = pakfire_stripper_copy_source_file(stripper, filename); + if (r < 0) { + ERROR(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; + + // Scan for all ELF files in path + r = pakfire_stripper_scan(stripper); + if (r < 0) + return r; + + // If the filelist is empty, there is nothing to do + if (pakfire_filelist_is_empty(stripper->filelist)) + return 0; + + // Copy sources + r = pakfire_filelist_walk(stripper->filelist, pakfire_stripper_copy_sources, stripper, 0); + if (r < 0) + return r; + + return 0; +} -- 2.47.3