[PATCH 2/4] ld: Refactor input_statement_is_archive_path() to not touch its argument

Calvin Owens calvin@wbinvd.org
Sat May 2 09:58:45 GMT 2026


On Saturday 05/02 at 17:36 +0930, Alan Modra wrote:
> On Fri, Apr 24, 2026 at 07:19:45PM -0700, Calvin Owens wrote:
> > +	  char *tmp = stat_strdup (file_spec);
> > +
> > +	  tmp[sep - file_spec] = 0;
> > +	  match = name_match (tmp, aname) == 0;
> > +	  stat_free (tmp);
> 
> Let's not make an unnecessary copy.  I'm going to apply the following.
> ----
> 
> Assign strchr return to a const char* to match its arg in a couple of
> places.  archive_path now returns a const char*, and
> input_statement_is_archive_path now has a const char* sep arg.  If
> you follow where these args come from in ldgram.y it can be seen that
> they are in fact in writable memory, so it isn't necessary to copy
> file_spec to poke in a zero which is restored before the function
> returns.
> 
> Signed-off-by: Calvin Owens <calvin@wbinvd.org>

I've had a busy week, apologies I didn't get a chance to refresh this.

It's very generous of you to credit me, but not necessary :)

Cheers,
Calvin

> Signed-off-by: Alan Modra <amodra@gmail.com>
>
> diff --git a/ld/ldlang.c b/ld/ldlang.c
> index dec3d586671..48dd33a49bb 100644
> --- a/ld/ldlang.c
> +++ b/ld/ldlang.c
> @@ -337,10 +337,10 @@ stat_ldirname (const char *name)
>  /* If PATTERN is of the form archive:file, return a pointer to the
>     separator.  If not, return NULL.  */
>  
> -static char *
> +static const char *
>  archive_path (const char *pattern)
>  {
> -  char *p = NULL;
> +  const char *p = NULL;
>  
>    if (link_info.path_separator == 0)
>      return p;
> @@ -362,7 +362,7 @@ archive_path (const char *pattern)
>     return whether F matches FILE_SPEC.  */
>  
>  static bool
> -input_statement_is_archive_path (const char *file_spec, char *sep,
> +input_statement_is_archive_path (const char *file_spec, const char *sep,
>  				 lang_input_statement_type *f)
>  {
>    bool match = false;
> @@ -377,9 +377,10 @@ input_statement_is_archive_path (const char *file_spec, char *sep,
>        if (sep != file_spec)
>  	{
>  	  const char *aname = bfd_get_filename (f->the_bfd->my_archive);
> -	  *sep = 0;
> +	  /* SEP which points into FILE_SPEC is in writable memory.  */
> +	  *(char *) sep = 0;
>  	  match = name_match (file_spec, aname) == 0;
> -	  *sep = link_info.path_separator;
> +	  *(char *) sep = link_info.path_separator;
>  	}
>      }
>    return match;
> @@ -421,7 +422,7 @@ walk_wild_file_in_exclude_list (struct name_list *exclude_list,
>         list_tmp;
>         list_tmp = list_tmp->next)
>      {
> -      char *p = archive_path (list_tmp->name);
> +      const char *p = archive_path (list_tmp->name);
>  
>        if (p != NULL)
>  	{
> @@ -477,7 +478,7 @@ walk_wild_section_match (lang_wild_statement_type *ptr,
>  {
>    struct wildcard_list *sec;
>    const char *file_spec = ptr->filename;
> -  char *p;
> +  const char *p;
>  
>    /* Check if filenames match.  */
>    if (file_spec == NULL)
> @@ -10946,7 +10947,7 @@ cmdline_fopen_temp (const char *path, const char *target,
>  #ifdef HAVE_DOS_BASED_FILE_SYSTEM
>    {
>      /* We could have foo/bar\\baz, or foo\\bar, or d:bar.  */
> -    char *bslash = strrchr (path, '\\');
> +    const char *bslash = strrchr (path, '\\');
>  
>      if (slash == NULL || (bslash != NULL && bslash > slash))
>        slash = bslash;
> 
> -- 
> Alan Modra


More information about the Binutils mailing list