diff mbox series

[v3,09/29] loongarch: Add <bits/pagesize.h>

Message ID bac0d3dd136a994bdf014dd1243e86a9095cce1c.1727624528.git.fweimer@redhat.com
State New
Headers show
Series Teach glibc about possible page sizes and handle gaps in ld.so | expand

Commit Message

Florian Weimer Sept. 29, 2024, 4:12 p.m. UTC
According to arch/loongarch/Kconfig in the kernel sources, LoongArch
supports 4 KiB, 16 KiB, and 64 KiB page sizes.

Note: The entire series runs into a GCC compilation problem on
LoongArch, which appears to be a GCC bug:

  Section type conflict on loongarch with .data.rel.ro section attribute
  https://gcc.gnu.org/bugzilla/show_bug.cgi?id=116887

---
 sysdeps/loongarch/bits/pagesize.h | 2 ++
 1 file changed, 2 insertions(+)
 create mode 100644 sysdeps/loongarch/bits/pagesize.h

Comments

Xi Ruoyao Sept. 29, 2024, 5:35 p.m. UTC | #1
On Sun, 2024-09-29 at 18:12 +0200, Florian Weimer wrote:
> According to arch/loongarch/Kconfig in the kernel sources, LoongArch
> supports 4 KiB, 16 KiB, and 64 KiB page sizes.

As reported
at https://github.com/loongson-community/discussions/issues/47, 64KiB
configuration currently does not work at all because ld sets an
insufficient alignment in the program header:

  LOAD           0x0000000000000000 0x0000000000000000 0x0000000000000000
                 0x0000000000000850 0x0000000000000850  R E    0x4000
  LOAD           0x0000000000003df8 0x0000000000007df8 0x0000000000007df8
                 0x0000000000000230 0x0000000000000238  RW     0x4000

So to me we should either raise the alignment to 0x10000, or remove the
64 KiB page support to simplify the code everywhere.

How do you think?

> Note: The entire series runs into a GCC compilation problem on
> LoongArch, which appears to be a GCC bug:
> 
>   Section type conflict on loongarch with .data.rel.ro section attribute
>   https://gcc.gnu.org/bugzilla/show_bug.cgi?id=116887

I'm taking a look.  But still we should try to work around it on the
Glibc side.  Otherwise even if we fix it for GCC we'd still need to
raise the required GCC version to the leading edge, and doing so is bad
for users and distro maintainers.

> ---
>  sysdeps/loongarch/bits/pagesize.h | 2 ++
>  1 file changed, 2 insertions(+)
>  create mode 100644 sysdeps/loongarch/bits/pagesize.h
> 
> diff --git a/sysdeps/loongarch/bits/pagesize.h
> b/sysdeps/loongarch/bits/pagesize.h
> new file mode 100644
> index 0000000000..cd688d3fb0
> --- /dev/null
> +++ b/sysdeps/loongarch/bits/pagesize.h
> @@ -0,0 +1,2 @@
> +#define __GLIBC_PAGE_SHIFT_MIN 12
> +#define __GLIBC_PAGE_SHIFT_MAX 16
Florian Weimer Sept. 29, 2024, 6:45 p.m. UTC | #2
* Xi Ruoyao:

> On Sun, 2024-09-29 at 18:12 +0200, Florian Weimer wrote:
>> According to arch/loongarch/Kconfig in the kernel sources, LoongArch
>> supports 4 KiB, 16 KiB, and 64 KiB page sizes.
>
> As reported
> at https://github.com/loongson-community/discussions/issues/47, 64KiB
> configuration currently does not work at all because ld sets an
> insufficient alignment in the program header:
>
>   LOAD           0x0000000000000000 0x0000000000000000 0x0000000000000000
>                  0x0000000000000850 0x0000000000000850  R E    0x4000
>   LOAD           0x0000000000003df8 0x0000000000007df8 0x0000000000007df8
>                  0x0000000000000230 0x0000000000000238  RW     0x4000
>
> So to me we should either raise the alignment to 0x10000, or remove the
> 64 KiB page support to simplify the code everywhere.

I think it's more important that the lower 16 bits of the file offset
and the virtual address are the same.  The alignment should actuallt be
4 KiB, otherwise the glibc loader will do extra work on 4 KiB machines
because it cannot know if the alignment really has to be 16 KiB
(or 64 KiB), or if it's just a toolchain default.

> How do you think?

On the glibc side, there is only a simplification if there's just one
page size to support.  It doesn't make a difference if there are two,
three, or more.

>> Note: The entire series runs into a GCC compilation problem on
>> LoongArch, which appears to be a GCC bug:
>> 
>>   Section type conflict on loongarch with .data.rel.ro section attribute
>>   https://gcc.gnu.org/bugzilla/show_bug.cgi?id=116887
>
> I'm taking a look.  But still we should try to work around it on the
> Glibc side.  Otherwise even if we fix it for GCC we'd still need to
> raise the required GCC version to the leading edge, and doing so is bad
> for users and distro maintainers.

We can do this:

diff --git a/sysdeps/unix/sysv/linux/loongarch/dl-find_object.c b/sysdeps/unix/sysv/linux/loongarch/dl-find_object.c
new file mode 100644
index 0000000000..63f055bd40
--- /dev/null
+++ b/sysdeps/unix/sysv/linux/loongarch/dl-find_object.c
@@ -0,0 +1,4 @@
+/* Work around GCC PR116887.  */
+#undef attribute_relro
+#define attribute_relro
+#include <elf/dl-find_object.c>

But maybe there is a better option.

Thanks,
Florian
Xi Ruoyao Sept. 29, 2024, 6:54 p.m. UTC | #3
On Sun, 2024-09-29 at 20:45 +0200, Florian Weimer wrote:
> * Xi Ruoyao:
> 
> > On Sun, 2024-09-29 at 18:12 +0200, Florian Weimer wrote:
> > > According to arch/loongarch/Kconfig in the kernel sources, LoongArch
> > > supports 4 KiB, 16 KiB, and 64 KiB page sizes.
> > 
> > As reported
> > at https://github.com/loongson-community/discussions/issues/47, 64KiB
> > configuration currently does not work at all because ld sets an
> > insufficient alignment in the program header:
> > 
> >   LOAD           0x0000000000000000 0x0000000000000000 0x0000000000000000
> >                  0x0000000000000850 0x0000000000000850  R E    0x4000
> >   LOAD           0x0000000000003df8 0x0000000000007df8 0x0000000000007df8
> >                  0x0000000000000230 0x0000000000000238  RW     0x4000
> > 
> > So to me we should either raise the alignment to 0x10000, or remove the
> > 64 KiB page support to simplify the code everywhere.

> I think it's more important that the lower 16 bits of the file offset
> and the virtual address are the same.  The alignment should actuallt be
> 4 KiB, otherwise the glibc loader will do extra work on 4 KiB machines
> because it cannot know if the alignment really has to be 16 KiB
> (or 64 KiB), or if it's just a toolchain default.

Hmm interesting.  AArch64 (where the kernel also supports 4, 16, 64 KiB
pages, and 4 KiB is the most common setting except Apple M1) ld produces
0x10000 here.

> > How do you think?
> 
> On the glibc side, there is only a simplification if there's just one
> page size to support.  It doesn't make a difference if there are two,
> three, or more.
> 
> > > Note: The entire series runs into a GCC compilation problem on
> > > LoongArch, which appears to be a GCC bug:
> > > 
> > >   Section type conflict on loongarch with .data.rel.ro section attribute
> > >   https://gcc.gnu.org/bugzilla/show_bug.cgi?id=116887
> > 
> > I'm taking a look.  But still we should try to work around it on the
> > Glibc side.  Otherwise even if we fix it for GCC we'd still need to
> > raise the required GCC version to the leading edge, and doing so is bad
> > for users and distro maintainers.
> 
> We can do this:
> 
> diff --git a/sysdeps/unix/sysv/linux/loongarch/dl-find_object.c b/sysdeps/unix/sysv/linux/loongarch/dl-find_object.c
> new file mode 100644
> index 0000000000..63f055bd40
> --- /dev/null
> +++ b/sysdeps/unix/sysv/linux/loongarch/dl-find_object.c
> @@ -0,0 +1,4 @@
> +/* Work around GCC PR116887.  */
> +#undef attribute_relro
> +#define attribute_relro
> +#include <elf/dl-find_object.c>
> 
> But maybe there is a better option.

I've posted a diff (it should just work while I don't really understand
why other ports don't need it) on the GCC PR, so I guess at least we'll
be able to wrap this with #if __GNUC_PREREQ.
diff mbox series

Patch

diff --git a/sysdeps/loongarch/bits/pagesize.h b/sysdeps/loongarch/bits/pagesize.h
new file mode 100644
index 0000000000..cd688d3fb0
--- /dev/null
+++ b/sysdeps/loongarch/bits/pagesize.h
@@ -0,0 +1,2 @@ 
+#define __GLIBC_PAGE_SHIFT_MIN 12
+#define __GLIBC_PAGE_SHIFT_MAX 16