| Message ID | 20250602110006.3257934-1-gilles.bardoux@sagemcom.com |
|---|---|
| State | Changes Requested |
| Headers | show |
| Series | [1/1] Makefile: strip even non-writable files | expand |
Hi Gilles, On 02/06/2025 13:00, Gilles Bardoux via buildroot wrote: > Currently, files without write permission are not stripped. Good idea to fix that! > Since calling a find exec script for all the elf files would be > slower than doing it only for the files without write permission, With -exec yes, but if you use the original -print0 | xargs -0 then the helper script just gets called once (or a few times) with many arguments. In the script you can do for file; do ...; done which is almost as efficient as find -exec. It _is_ indeed a bit more efficient to call the bare strip with many arguments rather than re-starting it all the time, but I doubt that you can measure a significant difference. It's a small executable with few shared libs so launching it is not so expensive. > the STRIP_FIND_CMD has been split into two finds: > - one for the files with write permission for the current user, > without an exec script > - one for the files witout write permission for the current user > calling the exec script > The find exec script (non-writable-file-cmd-wrapper) has been made > as generic as possible. It does a chmod u+w before the command (here > a strip) and restores the original file permissions afterwards. > The find command for special files (libpthread and ld-*.so) was not > split, because it concerns only a few files. So the find exec script > is called in all cases for these files. This is starting to sound super complicated... I think it would be better to move all the logic to distinguish between the cases where it needs to be made writable and the cases where it needs to use the special debug strip into the helper script. In fact, even the find command itself could move in there - though that is less of a factor I think, because you'd need to export quite a few variables to that script. > Signed-off-by: Gilles Bardoux <gilles.bardoux@sagemcom.com> > --- > Makefile | 20 ++++++++-- > support/scripts/non-writable-file-cmd-wrapper | 37 +++++++++++++++++++ > 2 files changed, 53 insertions(+), 4 deletions(-) > create mode 100755 support/scripts/non-writable-file-cmd-wrapper > > diff --git a/Makefile b/Makefile > index f90b834ed2..cf2b517938 100644 > --- a/Makefile > +++ b/Makefile > @@ -637,17 +637,28 @@ STRIP_FIND_COMMON_CMD = \ > # applications and libraries. Normally kernel modules are already excluded > # by the executable permission check, so the explicit exclusion is only > # done for kernel modules with incorrect permissions. > -STRIP_FIND_CMD = \ > +STRIP_FIND_WRITABLE_CMD = \ > $(STRIP_FIND_COMMON_CMD) \ > -type f \( -perm /111 -o -name '*.so*' \) \ > -not \( $(call findfileclauses,libpthread*.so* ld-*.so* *.ko) \) \ > + -writable \ > -print0 > > +# Stripping for non writables files > +STRIP_FIND_NOT_WRITABLE_CMD = \ > + WRAPPED_CMD="$(STRIPCMD)" \ > + $(STRIP_FIND_COMMON_CMD) \ > + -type f \( -perm /111 -o -name '*.so*' \) \ > + -not \( $(call findfileclauses,libpthread*.so* ld-*.so* *.ko) \) \ > + -not -writable \ > + -exec $(TOPDIR)/support/scripts/non-writable-file-cmd-wrapper {} \; > + > # Special stripping (only debugging symbols) for libpthread and ld-*.so. > STRIP_FIND_SPECIAL_LIBS_CMD = \ > + WRAPPED_CMD="$(STRIPCMD) $(STRIP_STRIP_DEBUG)" \ > $(STRIP_FIND_COMMON_CMD) \ > \( -name 'ld-*.so*' -o -name 'libpthread*.so*' \) \ > - -print0 > + -exec $(TOPDIR)/support/scripts/non-writable-file-cmd-wrapper {} \; > > # Generate locale data. > ifeq ($(BR2_TOOLCHAIN_USES_GLIBC),y) > @@ -756,8 +767,9 @@ endif > ifneq ($(BR2_ENABLE_DEBUG):$(BR2_STRIP_strip),y:) > rm -rf $(TARGET_DIR)/lib/debug $(TARGET_DIR)/usr/lib/debug > endif > - $(STRIP_FIND_CMD) | xargs -0 $(STRIPCMD) 2>/dev/null || true > - $(STRIP_FIND_SPECIAL_LIBS_CMD) | xargs -0 -r $(STRIPCMD) $(STRIP_STRIP_DEBUG) 2>/dev/null || true > + $(STRIP_FIND_WRITABLE_CMD) | xargs -0 $(STRIPCMD) 2>/dev/null || true > + $(STRIP_FIND_NOT_WRITABLE_CMD) 2>/dev/null || true > + $(STRIP_FIND_SPECIAL_LIBS_CMD) 2>/dev/null || true So here we would have: find $(TARGET_DIR) \ $(if $(call qstrip,$(BR2_STRIP_EXCLUDE_DIRS)), \ \( $(call finddirclauses,$(TARGET_DIR),$(call qstrip,$(BR2_STRIP_EXCLUDE_DIRS))) \) \ -prune -o \ ) \ $(if $(call qstrip,$(BR2_STRIP_EXCLUDE_FILES)), \ -not \( $(call findfileclauses,$(call qstrip,$(BR2_STRIP_EXCLUDE_FILES))) \) ) \ -type f \( -perm /111 -o -name '*.so*' \) \ -print0 \ | STRIPCMD="$(STRIPCMD)" STRIP_STRIP_DEBUG="$(STRIP_STRIP_DEBUG)" \ xargs -0 support/scripts/strip-helper Note that the different STRIP_FIND variables can all be removed. Note that no || true is needed because the strip-helper doesn't return errors. > > test -f $(TARGET_DIR)/etc/ld.so.conf && \ > { echo "ERROR: we shouldn't have a /etc/ld.so.conf file"; exit 1; } || true > diff --git a/support/scripts/non-writable-file-cmd-wrapper b/support/scripts/non-writable-file-cmd-wrapper > new file mode 100755 > index 0000000000..efbbeb6e7c > --- /dev/null > +++ b/support/scripts/non-writable-file-cmd-wrapper > @@ -0,0 +1,37 @@ > +#!/usr/bin/env bash > + > +usage() { > + cat <<EOF >&2 > +Usage: ${0} FILE > + > +Description: > + > + This script runs WRAPPED_CMD with the file given in argument, adding the write permission temporarily during this action. > + > +Arguments: > + > + FILE file path to give to the command > + > +Environment: > + > + WRAPPED_CMD core command to run in between the chmods > + > +Returns: 0 > + > +EOF > +} This usage() function isn't called. In the support scripts we typically put the usage in comments because they're anyway only supposed to be called from the Makefile. > + > +helper() { We typically call it main(). > + local file="${1}" > + > + # make files writable if necessary > + changed="$(chmod -c u+w "${file}")" > + > + # action on the file > + ${WRAPPED_CMD} "${file}" > + > + # restore the original permission > + test "${changed}" != "" && chmod u-w "${file}" I think we normally use test -z "${changed}" to test for empty string. Regards, Arnout > +} > +helper "${@}" > +exit 0
diff --git a/Makefile b/Makefile index f90b834ed2..cf2b517938 100644 --- a/Makefile +++ b/Makefile @@ -637,17 +637,28 @@ STRIP_FIND_COMMON_CMD = \ # applications and libraries. Normally kernel modules are already excluded # by the executable permission check, so the explicit exclusion is only # done for kernel modules with incorrect permissions. -STRIP_FIND_CMD = \ +STRIP_FIND_WRITABLE_CMD = \ $(STRIP_FIND_COMMON_CMD) \ -type f \( -perm /111 -o -name '*.so*' \) \ -not \( $(call findfileclauses,libpthread*.so* ld-*.so* *.ko) \) \ + -writable \ -print0 +# Stripping for non writables files +STRIP_FIND_NOT_WRITABLE_CMD = \ + WRAPPED_CMD="$(STRIPCMD)" \ + $(STRIP_FIND_COMMON_CMD) \ + -type f \( -perm /111 -o -name '*.so*' \) \ + -not \( $(call findfileclauses,libpthread*.so* ld-*.so* *.ko) \) \ + -not -writable \ + -exec $(TOPDIR)/support/scripts/non-writable-file-cmd-wrapper {} \; + # Special stripping (only debugging symbols) for libpthread and ld-*.so. STRIP_FIND_SPECIAL_LIBS_CMD = \ + WRAPPED_CMD="$(STRIPCMD) $(STRIP_STRIP_DEBUG)" \ $(STRIP_FIND_COMMON_CMD) \ \( -name 'ld-*.so*' -o -name 'libpthread*.so*' \) \ - -print0 + -exec $(TOPDIR)/support/scripts/non-writable-file-cmd-wrapper {} \; # Generate locale data. ifeq ($(BR2_TOOLCHAIN_USES_GLIBC),y) @@ -756,8 +767,9 @@ endif ifneq ($(BR2_ENABLE_DEBUG):$(BR2_STRIP_strip),y:) rm -rf $(TARGET_DIR)/lib/debug $(TARGET_DIR)/usr/lib/debug endif - $(STRIP_FIND_CMD) | xargs -0 $(STRIPCMD) 2>/dev/null || true - $(STRIP_FIND_SPECIAL_LIBS_CMD) | xargs -0 -r $(STRIPCMD) $(STRIP_STRIP_DEBUG) 2>/dev/null || true + $(STRIP_FIND_WRITABLE_CMD) | xargs -0 $(STRIPCMD) 2>/dev/null || true + $(STRIP_FIND_NOT_WRITABLE_CMD) 2>/dev/null || true + $(STRIP_FIND_SPECIAL_LIBS_CMD) 2>/dev/null || true test -f $(TARGET_DIR)/etc/ld.so.conf && \ { echo "ERROR: we shouldn't have a /etc/ld.so.conf file"; exit 1; } || true diff --git a/support/scripts/non-writable-file-cmd-wrapper b/support/scripts/non-writable-file-cmd-wrapper new file mode 100755 index 0000000000..efbbeb6e7c --- /dev/null +++ b/support/scripts/non-writable-file-cmd-wrapper @@ -0,0 +1,37 @@ +#!/usr/bin/env bash + +usage() { + cat <<EOF >&2 +Usage: ${0} FILE + +Description: + + This script runs WRAPPED_CMD with the file given in argument, adding the write permission temporarily during this action. + +Arguments: + + FILE file path to give to the command + +Environment: + + WRAPPED_CMD core command to run in between the chmods + +Returns: 0 + +EOF +} + +helper() { + local file="${1}" + + # make files writable if necessary + changed="$(chmod -c u+w "${file}")" + + # action on the file + ${WRAPPED_CMD} "${file}" + + # restore the original permission + test "${changed}" != "" && chmod u-w "${file}" +} +helper "${@}" +exit 0
Currently, files without write permission are not stripped. Since calling a find exec script for all the elf files would be slower than doing it only for the files without write permission, the STRIP_FIND_CMD has been split into two finds: - one for the files with write permission for the current user, without an exec script - one for the files witout write permission for the current user calling the exec script The find exec script (non-writable-file-cmd-wrapper) has been made as generic as possible. It does a chmod u+w before the command (here a strip) and restores the original file permissions afterwards. The find command for special files (libpthread and ld-*.so) was not split, because it concerns only a few files. So the find exec script is called in all cases for these files. Signed-off-by: Gilles Bardoux <gilles.bardoux@sagemcom.com> --- Makefile | 20 ++++++++-- support/scripts/non-writable-file-cmd-wrapper | 37 +++++++++++++++++++ 2 files changed, 53 insertions(+), 4 deletions(-) create mode 100755 support/scripts/non-writable-file-cmd-wrapper