[PATCH v4 07/14] elf: Merge the three implementations of _dl_dst_substitute
Adhemerval Zanella Netto
adhemerval.zanella@linaro.org
Mon Mar 17 16:15:04 GMT 2025
On 02/02/25 18:13, Florian Weimer wrote:
> Use one implementation to perform the copying and the counting.
> Use l_origin of the main program as a fallback for objects
> that have not been dlopen'ed (such as ld.so itself, or the vDSO).
> These should not end up as dlopen callers normally, but they
> might one day if a dlopen variant with an explicit caller
> argument is supported for application use.
LGTM, thanks.
Reviewed-by: Adhemerval Zanella <adhemerval.zanella@linaro.org>
> else if (len != 0)
> @@ -329,16 +310,20 @@ _dl_dst_substitute (struct link_map *l, const char *input, char *result)
> /* We found a valid DST that we know about, but we could
> not find a replacement value for it, therefore we
> cannot use this path and discard it. */
> - *result = '\0';
> - return result;
> + alloc_buffer_mark_failed (result);
> + return 0;
> }
> else
> - /* No DST we recognize. */
> - *wp++ = '$';
> + {
> + /* No DST we recognize. */
> + ++length;
> + alloc_buffer_add_byte (result, '$');
This will incur in alloc_buffer_mark_failed for each bytes, which
is two word stores for each byte. Not the most optimized interface,
but I think it should be ok.
> + }
> }
> else
> {
> - *wp++ = *input++;
> + ++length;
> + alloc_buffer_add_byte (result, *input++);
> }
> }
> while (*input != '\0');
> @@ -353,15 +338,19 @@ _dl_dst_substitute (struct link_map *l, const char *input, char *result)
> this way because it may be manipulated in some ways with hard
> links. */
> if (__glibc_unlikely (check_for_trusted)
> - && !is_trusted_path_normalize (result, wp - result))
> + && !alloc_buffer_has_failed (result)
> + && !is_trusted_path_normalize (result_start,
> + alloc_buffer_next (result, char)
> + - result_start))
> {
> - *result = '\0';
> - return result;
> + alloc_buffer_mark_failed (result);
> + return 0;
> }
>
> - *wp = '\0';
> + ++length;
> + alloc_buffer_add_byte (result, 0);
>
> - return result;
> + return length;
> }
>
>
> @@ -373,30 +362,18 @@ _dl_dst_substitute (struct link_map *l, const char *input, char *result)
> static char *
> expand_dynamic_string_token (struct link_map *l, const char *input)
> {
> - /* We make two runs over the string. First we determine how large the
> - resulting string is and then we copy it over. Since this is no
> - frequently executed operation we are looking here not for performance
> - but rather for code size. */
> - size_t cnt;
> - size_t total;
> - char *result;
> -
> - /* Determine the number of DSTs. */
> - cnt = _dl_dst_count (input);
> -
> - /* If we do not have to replace anything simply copy the string. */
> - if (__glibc_likely (cnt == 0))
> - return __strdup (input);
> -
> - /* Determine the length of the substituted string. */
> - total = DL_DST_REQUIRED (l, input, strlen (input), cnt);
> -
> - /* Allocate the necessary memory. */
> - result = (char *) malloc (total + 1);
> + struct alloc_buffer buf = {};
> + size_t size = _dl_dst_substitute (l, input, &buf);
> + char *result = malloc (size);
> if (result == NULL)
> return NULL;
> -
> - return _dl_dst_substitute (l, input, result);
> + buf = alloc_buffer_create (result, size);
> + if (_dl_dst_substitute (l, input, &buf) == 0)
> + /* Mark the expanded string as to be ignored. */
> + *result = '\0';
> + else
> + assert (!alloc_buffer_has_failed (&buf));
> + return result;
> }
>
>
> diff --git a/elf/dl-open.c b/elf/dl-open.c
> index 60a1dce9de..4fb77e3ff7 100644
> --- a/elf/dl-open.c
> +++ b/elf/dl-open.c
> @@ -38,7 +38,6 @@
> #include <gnu/lib-names.h>
> #include <dl-find_object.h>
>
> -#include <dl-dst.h>
> #include <dl-prop.h>
>
>
> diff --git a/elf/dl-origin.c b/elf/dl-origin.c
> index 9f6b921b01..5d06f5bbe3 100644
> --- a/elf/dl-origin.c
> +++ b/elf/dl-origin.c
> @@ -21,9 +21,6 @@
> #include <sys/param.h>
> #include <ldsodefs.h>
>
> -#include <dl-dst.h>
> -
> -
> const char *
> _dl_get_origin (void)
> {
> diff --git a/sysdeps/generic/ldsodefs.h b/sysdeps/generic/ldsodefs.h
> index c0785cba04..e8418973ed 100644
> --- a/sysdeps/generic/ldsodefs.h
> +++ b/sysdeps/generic/ldsodefs.h
> @@ -1223,12 +1223,11 @@ extern struct link_map * _dl_get_dl_main_map (void) attribute_hidden;
> /* Find origin of the executable. */
> extern const char *_dl_get_origin (void) attribute_hidden;
>
> -/* Count DSTs. */
> -extern size_t _dl_dst_count (const char *name) attribute_hidden;
> -
> /* Substitute DST values. */
> -extern char *_dl_dst_substitute (struct link_map *l, const char *name,
> - char *result) attribute_hidden;
> +struct alloc_buffer;
> +size_t _dl_dst_substitute (struct link_map *l, const char *name,
> + struct alloc_buffer *result)
> + attribute_hidden __nonnull ((1, 2, 3));
>
> /* Open the shared object NAME, relocate it, and run its initializer if it
> hasn't already been run. MODE is as for `dlopen' (see <dlfcn.h>). If
> diff --git a/sysdeps/unix/sysv/linux/dl-origin.c b/sysdeps/unix/sysv/linux/dl-origin.c
> index decdd8ae9e..9c87ca3208 100644
> --- a/sysdeps/unix/sysv/linux/dl-origin.c
> +++ b/sysdeps/unix/sysv/linux/dl-origin.c
> @@ -17,7 +17,6 @@
> <https://www.gnu.org/licenses/>. */
>
> #include <assert.h>
> -#include <dl-dst.h>
> #include <fcntl.h>
> #include <ldsodefs.h>
> #include <sysdep.h>
More information about the Libc-alpha
mailing list