x32: Set GLRO(dl_platform) to "x86_64" by default [BZ #22363]

Message ID 20171029211541.GA6435@gmail.com
State New, archived
Headers

Commit Message

H.J. Lu Oct. 29, 2017, 9:15 p.m. UTC
  Set dl_platform to "x86_64" for x32 by default since kernel may set it
to "i686".  This fixed:

FAIL: elf/tst-platform-1

on x32.  Tested on x86-64 and x32.

Any comments?

H.J.
---
	[BZ #22363]
	* sysdeps/x86/cpu-features.c (init_cpu_features): Set
	GLRO(dl_platform) to "x86_64" by default for x32.
---
 sysdeps/x86/cpu-features.c | 5 +++++
 1 file changed, 5 insertions(+)
  

Comments

Andreas Schwab Oct. 30, 2017, 7:05 a.m. UTC | #1
On Okt 29 2017, "H.J. Lu" <hjl.tools@gmail.com> wrote:

> Set dl_platform to "x86_64" for x32 by default since kernel may set it
> to "i686".

Why does it do that?  Isn't that a kernel bug?

Andreas.
  
Florian Weimer Oct. 30, 2017, 9:47 a.m. UTC | #2
On 10/30/2017 08:05 AM, Andreas Schwab wrote:
> On Okt 29 2017, "H.J. Lu" <hjl.tools@gmail.com> wrote:
> 
>> Set dl_platform to "x86_64" for x32 by default since kernel may set it
>> to "i686".
> 
> Why does it do that?  Isn't that a kernel bug?

The whole thing is a bit iffy.  Why does the kernel set AT_PLATFORM to 
i686 when running on a x86_64 machine?  x86_64 would make more sense 
because it allows the loader to select libraries which were compiled 
with -march=x86-64.  I think AT_PLATFORM should be about CPU 
capabilities, not the initial CPU mode after process creation.  The 
latter requires separate search paths anyway.

Thanks,
Florian
  
H.J. Lu Oct. 30, 2017, 12:36 p.m. UTC | #3
On Mon, Oct 30, 2017 at 12:05 AM, Andreas Schwab <schwab@linux-m68k.org> wrote:
> On Okt 29 2017, "H.J. Lu" <hjl.tools@gmail.com> wrote:
>
>> Set dl_platform to "x86_64" for x32 by default since kernel may set it
>> to "i686".
>
> Why does it do that?  Isn't that a kernel bug?
>

There is

include/asm/elf.h:#define COMPAT_ELF_PLATFORM         ("i686")

It is much simpler to fix it in glibc.
  
H.J. Lu Oct. 30, 2017, 12:39 p.m. UTC | #4
On Mon, Oct 30, 2017 at 2:47 AM, Florian Weimer <fweimer@redhat.com> wrote:
> On 10/30/2017 08:05 AM, Andreas Schwab wrote:
>>
>> On Okt 29 2017, "H.J. Lu" <hjl.tools@gmail.com> wrote:
>>
>>> Set dl_platform to "x86_64" for x32 by default since kernel may set it
>>> to "i686".
>>
>>
>> Why does it do that?  Isn't that a kernel bug?
>
>
> The whole thing is a bit iffy.  Why does the kernel set AT_PLATFORM to i686
> when running on a x86_64 machine?  x86_64 would make more sense because it

Before x32 has 32-bit address space, it uses

include/asm/elf.h:#define COMPAT_ELF_PLATFORM         ("i686")

It is correct for i386 program, but incorrect for x32 program.

> allows the loader to select libraries which were compiled with
> -march=x86-64.  I think AT_PLATFORM should be about CPU capabilities, not
> the initial CPU mode after process creation.  The latter requires separate
> search paths anyway.
>

The whole AT_PLATFORM was useful before we implemented early CPUID
check in glibc.
  
Andreas Schwab Oct. 30, 2017, 4:28 p.m. UTC | #5
On Okt 30 2017, "H.J. Lu" <hjl.tools@gmail.com> wrote:

> On Mon, Oct 30, 2017 at 12:05 AM, Andreas Schwab <schwab@linux-m68k.org> wrote:
>> On Okt 29 2017, "H.J. Lu" <hjl.tools@gmail.com> wrote:
>>
>>> Set dl_platform to "x86_64" for x32 by default since kernel may set it
>>> to "i686".
>>
>> Why does it do that?  Isn't that a kernel bug?
>>
>
> There is
>
> include/asm/elf.h:#define COMPAT_ELF_PLATFORM         ("i686")
>
> It is much simpler to fix it in glibc.

Take a look how this is solved for aarch64 ILP32.

Andreas.
  
H.J. Lu Oct. 30, 2017, 6:15 p.m. UTC | #6
On Mon, Oct 30, 2017 at 9:28 AM, Andreas Schwab <schwab@linux-m68k.org> wrote:
> On Okt 30 2017, "H.J. Lu" <hjl.tools@gmail.com> wrote:
>
>> On Mon, Oct 30, 2017 at 12:05 AM, Andreas Schwab <schwab@linux-m68k.org> wrote:
>>> On Okt 29 2017, "H.J. Lu" <hjl.tools@gmail.com> wrote:
>>>
>>>> Set dl_platform to "x86_64" for x32 by default since kernel may set it
>>>> to "i686".
>>>
>>> Why does it do that?  Isn't that a kernel bug?
>>>
>>
>> There is
>>
>> include/asm/elf.h:#define COMPAT_ELF_PLATFORM         ("i686")
>>
>> It is much simpler to fix it in glibc.
>
> Take a look how this is solved for aarch64 ILP32.
>

I saw

#define ELF_PLATFORM ("aarch64_be")
#define ELF_PLATFORM ("aarch64")
#define COMPAT_ELF_PLATFORM ("v8b")
#define COMPAT_ELF_PLATFORM ("v8l")

on staging/ilp32-4.13 branch.

I assume v8l/v8b will be used as AT_PLATFORM for both ILP32 and
arm32 programs.    I don't see how this approach can work for i686
and x32.
  
Florian Weimer Oct. 30, 2017, 6:31 p.m. UTC | #7
On 10/30/2017 07:15 PM, H.J. Lu wrote:
> I saw
> 
> #define ELF_PLATFORM ("aarch64_be")
> #define ELF_PLATFORM ("aarch64")
> #define COMPAT_ELF_PLATFORM ("v8b")
> #define COMPAT_ELF_PLATFORM ("v8l")
> 
> on staging/ilp32-4.13 branch.
> 
> I assume v8l/v8b will be used as AT_PLATFORM for both ILP32 and
> arm32 programs.    I don't see how this approach can work for i686
> and x32.

The bug is that with an x86-64 kernel, we didn't set AT_PLATFORM to 
x86_64 by default for all executables because that's a reasonable way to 
identify the microarchitecture (in particular, that there is SSE2 
support, and you can switch to long mode if you think it's beneficial 
for what you are doing).

Thanks,
Florian
  
Andreas Schwab Oct. 30, 2017, 6:36 p.m. UTC | #8
On Okt 30 2017, "H.J. Lu" <hjl.tools@gmail.com> wrote:

> I assume v8l/v8b will be used as AT_PLATFORM for both ILP32 and
> arm32 programs.

$ LD_SHOW_AUXV=1 /usr/bin/true
AT_SYSINFO_EHDR: 0xf7e0e000
AT_HWCAP:        8ff
AT_PAGESZ:       4096
AT_CLKTCK:       100
AT_PHDR:         0x9ea034
AT_PHENT:        32
AT_PHNUM:        9
AT_BASE:         0xf7dd0000
AT_FLAGS:        0x0
AT_ENTRY:        0x9eb460
AT_UID:          0
AT_EUID:         0
AT_GID:          0
AT_EGID:         0
AT_SECURE:       0
AT_RANDOM:       0xffcfa0a2
AT_HWCAP2:       0x0
AT_EXECFN:       /usr/bin/true
AT_PLATFORM:     aarch64:ilp32

Andreas.
  
H.J. Lu Oct. 30, 2017, 7:12 p.m. UTC | #9
On Mon, Oct 30, 2017 at 11:36 AM, Andreas Schwab <schwab@linux-m68k.org> wrote:
> On Okt 30 2017, "H.J. Lu" <hjl.tools@gmail.com> wrote:
>
>> I assume v8l/v8b will be used as AT_PLATFORM for both ILP32 and
>> arm32 programs.
>
> $ LD_SHOW_AUXV=1 /usr/bin/true
> AT_SYSINFO_EHDR: 0xf7e0e000
> AT_HWCAP:        8ff
> AT_PAGESZ:       4096
> AT_CLKTCK:       100
> AT_PHDR:         0x9ea034
> AT_PHENT:        32
> AT_PHNUM:        9
> AT_BASE:         0xf7dd0000
> AT_FLAGS:        0x0
> AT_ENTRY:        0x9eb460
> AT_UID:          0
> AT_EUID:         0
> AT_GID:          0
> AT_EGID:         0
> AT_SECURE:       0
> AT_RANDOM:       0xffcfa0a2
> AT_HWCAP2:       0x0
> AT_EXECFN:       /usr/bin/true
> AT_PLATFORM:     aarch64:ilp32
>
> Andreas.
>

arm64 uses

arch/arm64/kernel/binfmt_ilp32.c:#undef ELF_PLATFORM
arch/arm64/kernel/binfmt_ilp32.c:#define ELF_PLATFORM    ("aarch64_be:ilp32")
arch/arm64/kernel/binfmt_ilp32.c:#define ELF_PLATFORM    ("aarch64:ilp32")

Let me ask x86 kernel people.
  

Patch

diff --git a/sysdeps/x86/cpu-features.c b/sysdeps/x86/cpu-features.c
index 87aaa8683c..0ca29365ef 100644
--- a/sysdeps/x86/cpu-features.c
+++ b/sysdeps/x86/cpu-features.c
@@ -430,6 +430,11 @@  no_cpuid:
 
       if (platform != NULL)
 	GLRO(dl_platform) = platform;
+# ifdef __ILP32__
+      /* Set dl_platform to "x86_64" since kernel may set it to "i686".  */
+      else
+	GLRO(dl_platform) = "x86_64";
+# endif
     }
 #else
   GLRO(dl_hwcap) = 0;