On Tue, 25 Feb 2025 08:23:27 -0800 (PST), Palmer Dabbelt wrote:
> On Fri, 14 Feb 2025 05:04:20 PST (-0800), ji...@linux.alibaba.com wrote:
> > According to the definition in gcc/config/riscv/t-linux, after obtaining
> > the reused multilib_dir result using TARGET_COMPUTE_MULTILIB, we should
> > set multilib_os_dir to its parent directory.
> >
> > For example, when building GCC with the options "--enable-multilib
> > --with-arch=rv64gc --with-abi=lp64d" and using GCC to compile RV32GC
> > programs, the current multilib_dir is set to "lib32/ilp32d", and
> > multilib_os_dir is also "lib32/ilp32d". This results in an inability to
> > locate the path "lib/lib32/ilp32d" during the linking process(as it does
> > not exist); the actual path should be "lib/../lib32/ilp32d".
> >
> > Library Search Order Before Applying This Patch (Incorrect):
> >
> > 1. lib/gcc/riscv64-unknown-linux-gnu/15.0.1/lib32/ilp32d/
> > 2. lib/gcc/riscv64-unknown-linux-gnu/15.0.1/
> > 3. 
> > lib/gcc/riscv64-unknown-linux-gnu/15.0.1/../../../../riscv64-unknown-linux-gnu/lib/
> > 4. sysroot/lib32/ilp32d/
> > 5. sysroot/usr/lib32/ilp32d/
> > 6. sysroot/lib/
> >
> > Library Search Order After Applying This Patch:
> >
> > 1. lib/gcc/riscv64-unknown-linux-gnu/15.0.1/lib32/ilp32d/
> > 2. 
> > lib/gcc/riscv64-unknown-linux-gnu/15.0.1/../../../../riscv64-unknown-linux-gnu/lib/../lib32/ilp32d/
> > 3. sysroot/lib/../lib32/ilp32d/
> > 4. lib/gcc/riscv64-unknown-linux-gnu/15.0.1/
> > 5. 
> > lib/gcc/riscv64-unknown-linux-gnu/15.0.1/../../../../riscv64-unknown-linux-gnu/lib/
> > 6. sysroot/lib32/ilp32d/
> > 7. sysroot/usr/lib32/ilp32d/
> > 8. sysroot/lib/
> >
> > Clearly, two valid paths (2 and 3) have been added, which is the correct 
> > behavior.
> 
> We were talking about this in the patchwork meeting this morning, and 
> nobody could figure out why these paths are the desired behavior here.  

First, it is important to note that we need the TARGET_COMPUTE_MULTILIB hook to 
replace the old MULTILIB_REUSE
rule. Kito has already provided a reasonable explanation for this when 
introducing the new hook.

Second, we need to ensure that the library search paths during compilation are 
consistent, regardless of
whether the TARGET_COMPUTE_MULTILIB hook is used. Currently, this is clearly 
not the case.

In summary, the purpose of this patch is solely to mitigate the negative 
effects introduced by the
TARGET_COMPUTE_MULTILIB hook. I have not added any new paths :)

> Unless I'm reading something wrong, this just adds two new paths:
> 
>     
> lib/gcc/riscv64-unknown-linux-gnu/15.0.1/../../../../riscv64-unknown-linux-gnu/lib/../lib32/ilp32d/
>     sysroot/lib/../lib32/ilp32d/
> 
> For the first one, if I remove all the ".." that resolves to 
> "riscv64-unknown-linux-gnu/lib32/ilp32d/".  That looks odd to me, as I'd 
> expect that to be a sysroot-based path.

For clarity, I have renumbered the library search paths before and after the 
patch, according to the
order in which they are searched:

Library Search Order Before Applying This Patch (Incorrect):

a1. lib/gcc/riscv64-unknown-linux-gnu/15.0.1/lib32/ilp32d/
a2. lib/gcc/riscv64-unknown-linux-gnu/15.0.1/
a3. 
lib/gcc/riscv64-unknown-linux-gnu/15.0.1/../../../../riscv64-unknown-linux-gnu/lib/
a4. sysroot/lib32/ilp32d/
a5. sysroot/usr/lib32/ilp32d/
a6. sysroot/lib/

Library Search Order After Applying This Patch:

b1. lib/gcc/riscv64-unknown-linux-gnu/15.0.1/lib32/ilp32d/
b2. 
lib/gcc/riscv64-unknown-linux-gnu/15.0.1/../../../../riscv64-unknown-linux-gnu/lib/../lib32/ilp32d/
b3. sysroot/lib/../lib32/ilp32d/
b4. lib/gcc/riscv64-unknown-linux-gnu/15.0.1/
b5. 
lib/gcc/riscv64-unknown-linux-gnu/15.0.1/../../../../riscv64-unknown-linux-gnu/lib/
b6. sysroot/lib32/ilp32d/
b7. sysroot/usr/lib32/ilp32d/
b8. sysroot/lib/

In fact, when searching for library paths, we should first look at all paths 
related to lib32/ilp32d,
such as b1(lib32/ilp32d) -> b2(lib32/ilp32d) -> b3(lib32/ilp32d) -> ....

However, the current situation is a1(lib32/ilp32d) -> a2(lib64/lp64d) -> 
a3(lib64/lp64d) -> ....

Clearly, we are traversing the wrong paths before reaching the sysroot. In 
reality, I discovered this
issue because our downstream toolchain encountered an error during linking:
"error: adding symbols: file in wrong format."
This is due to rv32gc-ilp32d finding and attempting to link the incorrect 
library from the path
a3(lib64/lp64d).

Best regards,
Jin Ma

> For the second one, I get "sysroot/lib32/ilp32d/", which is already in 
> the list.
> 
> So I'm not quite sure what's going on here.
> 
> > gcc/ChangeLog:
> >
> >     * common/config/riscv/riscv-common.cc (riscv_compute_multilib_os):
> >     Implement TARGET_COMPUTE_MULTILIB_OS
> >     (TARGET_COMPUTE_MULTILIB_OS): Defined.
> >     * config/riscv/linux.h (RISCV_USE_CUSTOMISED_MULTI_LIB_OS): New.
> > ---
> >  gcc/common/config/riscv/riscv-common.cc | 32 +++++++++++++++++++++++++
> >  gcc/config/riscv/linux.h                |  1 +
> >  2 files changed, 33 insertions(+)
> >
> > diff --git a/gcc/common/config/riscv/riscv-common.cc 
> > b/gcc/common/config/riscv/riscv-common.cc
> > index 5038f0eb959..526d1fb9ca2 100644
> > --- a/gcc/common/config/riscv/riscv-common.cc
> > +++ b/gcc/common/config/riscv/riscv-common.cc
> > @@ -2426,9 +2426,41 @@ riscv_compute_multilib (
> >      }
> >  }
> >
> > +#ifndef RISCV_USE_CUSTOMISED_MULTI_LIB_OS
> > +#define RISCV_USE_CUSTOMISED_MULTI_LIB_OS 0
> > +#endif
> > +
> > +/* Implement TARGET_COMPUTE_MULTILIB_OS.  */
> > +static const char *
> > +riscv_compute_multilib_os (
> > +  const char *multilib_os_dir,
> > +  const char *multilib_dir)
> > +{
> > +  if (!RISCV_USE_CUSTOMISED_MULTI_LIB_OS)
> > +    return multilib_os_dir;
> > +
> > +  /* We don't need to do anything if we don't get multilib_dir.  */
> > +  if (multilib_dir == NULL)
> > +    return multilib_os_dir;
> > +
> > +  /* If multilib_dir is the default, multilib_os_dir should also be the
> > +     default.  */
> > +  if (strcmp (multilib_dir, ".") == 0 || multilib_os_dir != NULL)
> > +    return multilib_os_dir;
> > +
> > +  /* According to the definition in gcc/config/riscv/t-linux, We need to 
> > use the
> > +     multilib_dir's upper level directory instead of a simple copy.  In 
> > order
> > +     to maintain the original logic, we need to use the multilib_dir upper
> > +     level directory.  */
> > +  return concat ("../", multilib_dir , NULL);
> > +}
> > +
> >  #undef TARGET_COMPUTE_MULTILIB
> >  #define TARGET_COMPUTE_MULTILIB riscv_compute_multilib
> >
> > +#undef TARGET_COMPUTE_MULTILIB_OS
> > +#define TARGET_COMPUTE_MULTILIB_OS riscv_compute_multilib_os
> > +
> >  vec<const char *>
> >  riscv_get_valid_option_values (int option_code,
> >                            const char *prefix ATTRIBUTE_UNUSED)
> > diff --git a/gcc/config/riscv/linux.h b/gcc/config/riscv/linux.h
> > index 9060c940a44..4ac7477bdf4 100644
> > --- a/gcc/config/riscv/linux.h
> > +++ b/gcc/config/riscv/linux.h
> > @@ -68,3 +68,4 @@ along with GCC; see the file COPYING3.  If not see
> >     "/usr/lib/ "
> >
> >  #define RISCV_USE_CUSTOMISED_MULTI_LIB select_by_abi
> > +#define RISCV_USE_CUSTOMISED_MULTI_LIB_OS 1

Reply via email to