Prev: Wanadoo
Next: AddOn GWK140
From: Tony Houghton on
In <87mzngipqa.fsf(a)amaterasu.srvr.nix>,
Nix <nix-razor-pit(a)esperi.org.uk> wrote:

> On 15 Aug 2005, Tony Houghton said:
>> In <87ek8vtfan.fsf(a)amaterasu.srvr.nix>,
>> Nix <nix-razor-pit(a)esperi.org.uk> wrote:
>>> I'd be surprised if there wasn't a personality-setting tool to do this
>>> (Linux/SPARC has the sparc32 and sparc64 tools for that purpose:
>>> internally, they call personality()).
>>
>> Debian has /emul/ia32-linux/bin/uname but I haven't investigated how
>> you're supposed to use it. I suppose one could just make
>> /emul/ia32-linux/bin/ the first thing in PATH. There aren't any other
>> files in the directory.
>
> That's just a 32-bit copy of the uname binary, I expect. Not useful for
> this.

You're right, it does report x86_64.

>> And there's a wrapper called linux32. But apt-cache show includes the
>> comment, "On systems without support for the PER_LINUX_32 execution
>> domain, this program has no effect." Whatever the PER_LINUX_32 execution
>> domain is.
>
> 32-bit Linux userspace, of course.

Ie a 32-bit loader/linker etc? Or just a CPU that supports 32-bit (as
well)? The linux32 deb doesn't depend on ia32-libs FWIW. Or does the
x86_64 libc6 include 32-bit support? The Debian AMD HOWTO says you have
to symlink the 32-bit linker from ia32-libs into /lib though.

> See include/linux/personality.h.

It contains enums for PER_LINUX_32BIT and PER_LINUX32 etc, but not
PER_LINUX_32.

> There's probably a `linux64' as well.

There is a linux64 wrapper in the linux32 package.

> Now try `linux32 uname -a', and be enlightened.

I realise what linux32 does, but I couldn't tell quite what that comment
is trying to get across.

--
The address in the Reply-To is genuine and should not be edited.
See <http://www.realh.co.uk/contact.html> for more reliable contact addresses.
From: Nix on
On 17 Aug 2005, Tony Houghton uttered the following:
> In <87mzngipqa.fsf(a)amaterasu.srvr.nix>,
> Nix <nix-razor-pit(a)esperi.org.uk> wrote:
>
>> On 15 Aug 2005, Tony Houghton said:
>>> Debian has /emul/ia32-linux/bin/uname but I haven't investigated how
>>> you're supposed to use it. I suppose one could just make
>>> /emul/ia32-linux/bin/ the first thing in PATH. There aren't any other
>>> files in the directory.
>>
>> That's just a 32-bit copy of the uname binary, I expect. Not useful for
>> this.
>
> You're right, it does report x86_64.

More to the point, file(1) probably says that it's a 32-bit program.

>>> And there's a wrapper called linux32. But apt-cache show includes the
>>> comment, "On systems without support for the PER_LINUX_32 execution
>>> domain, this program has no effect." Whatever the PER_LINUX_32 execution
>>> domain is.
>>
>> 32-bit Linux userspace, of course.
>
> Ie a 32-bit loader/linker etc? Or just a CPU that supports 32-bit (as
> well)?

It is the personality in which a 32-bit process runs. The Linux kernel,
ld.so, and the GNU binutils keep 32-bit and 64-bit stuff separate, just
as if they were targetted at different architectures which could just
happen to be run on the same physical CPU at the same time. (Hence the
GNU toolchain's term for this sort of stuff, `biarch support'.)

The personality is the kernel-level per-process tag which says which of
a set of mutually-incompatible ABIs/address spaces/whatever the current
process requires. The dynamic linker could consult it, but doesn't, in
favour of using multiple dynamic linkers --- since the dynamic linkers
would need different ABIs anyway, this is reasonable. (Oddly for a
per-process tag, it isn't visible anywhere under /proc/{pid}.)

Remember iBCS? That had a few personalities all of its own --- not
exactly widely-used ones anymore, I'd wager.

> The linux32 deb doesn't depend on ia32-libs FWIW. Or does the
> x86_64 libc6 include 32-bit support? The Debian AMD HOWTO says you have
> to symlink the 32-bit linker from ia32-libs into /lib though.

The x64-64 libc6 is *only* for 64-bit processes; the 32-bit one is
*only* for 32-bit processes. Even the dynamic linkers are separated;
the 64-bit GCC specs file contains a stanza roughly like this (this
one is for sparc64):

-m elf64_sparc -Y P,/usr/lib64 %{shared:-shared} %{!shared: %{!ibcs: %{!static: %{rdynamic:-export-dynamic} %{!dynamic-linker:-dynamic-linker /lib64/ld-linux.so.2}} %{static:-static}}}

Note that it's searching different directories for libraries and *wiring
a different path to the dynamic linker into the executable*. The paths
for 32-bit and 64-bit dynamic linkers are standardized (or nobody would
ever be able to exchange binaries), and that for the 32-bit dynamic
linker is /lib/ld-linux.so.2. Hence you *must* have that file present,
or your 32-bit stuff won't work. (If you've ever had to recover from a
screwed-up glibc install using statically-linked tools and watched all
your dynamically-linked stuff segfault down around your ears, you'll
have a visceral knowledge of this.)


Have some proof (done on UltraSPARC, again: I don't have access to any
x86-64 boxes at the moment):

A little program what prints its PID and kicks off a shell:

,----
| nix(a)amaterasu 27 /tmp% cat shell.c
| #include <stdio.h>
| #include <stdlib.h>
| #include <unistd.h>
|
| int main (void)
| {
| fprintf (stderr, "%lu\n", getpid());
| system ("/bin/bash");
| return 0;
| }
`----

(There's a reason why I'm using this test script: I only have about ten
64-bit programs on my system, and they're all monsters...)

Compile it: prove that it's 32-bit:

,----
| nix(a)amaterasu 28 /tmp% gcc -Wall -ansi -pedantic -O2 -m32 -o shell shell.c
| shell.c: In function `main':
| shell.c:7: warning: long unsigned int format, __pid_t arg (arg 3)
| nix(a)amaterasu 30 /tmp% file shell
| shell: ELF 32-bit MSB executable, SPARC32PLUS, V8+ Required, version 1 (SYSV), for GNU/Linux 2.4.29, dynamically linked (uses shared libs), not stripped
`----

Fire it up and have a look at its maps: they're all from /lib, and the
address space is recognizably a 32-bit one:

,----
| nix(a)amaterasu 31 /tmp% ./shell
| 2692
| nix(a)amaterasu 1 /tmp% cat /proc/2692/maps
| 00010000-00012000 r-xp 00000000 00:0c 12206 /tmp/shell
| 00020000-00022000 rwxp 00000000 00:0c 12206 /tmp/shell
| 70000000-7001c000 r-xp 00000000 08:01 12199 /lib/ld-2.3.5.so
| 7002a000-7002c000 r--p 0001a000 08:01 12199 /lib/ld-2.3.5.so
| 7002c000-7002e000 rwxp 0001c000 08:01 12199 /lib/ld-2.3.5.so
| 7004c000-70174000 r-xp 00000000 08:01 12211 /lib/libc-2.3.5.so
| 70174000-70184000 ---p 00128000 08:01 12211 /lib/libc-2.3.5.so
| 70184000-70186000 r--p 00128000 08:01 12211 /lib/libc-2.3.5.so
| 70186000-7018a000 rwxp 0012a000 08:01 12211 /lib/libc-2.3.5.so
| 7018a000-7018c000 rwxp 7018a000 00:00 0
| efeb4000-efede000 rw-p efeb4000 00:00 0 [stack]
| nix(a)amaterasu 2 /tmp% exit
| exit
`----

Now a 64-bit binary. (This is using the same compiler and linker as the
32-bit stuff, but only because GCC and the binutils contain explicit
support for merging SPARC32 and SPARC64 --- and x86 and x86-64 --- into
one program rather than having to use a cross-compiler for one of them.
That works, too.)

,----
| nix(a)amaterasu 32 /tmp% gcc -Wall -ansi -pedantic -O2 -m64 -o shell shell.c
| shell.c: In function `main':
| shell.c:7: warning: long unsigned int format, different type arg (arg 3)
| nix(a)amaterasu 33 /tmp% file shell
| shell: ELF 64-bit MSB executable, SPARC V9, version 1 (SYSV), for GNU/Linux 2.6.11, dynamically linked (uses shared libs), not stripped
`----

Now we run it:

,----
| nix(a)amaterasu 34 /tmp% ./shell
| 2738
| nix(a)amaterasu 1 /tmp% cat /proc/2738/maps
| 00100000-00102000 r-xp 00000000 00:0c 12271 /tmp/shell
| 00200000-00202000 rwxp 00000000 00:0c 12271 /tmp/shell
| 7ffffbe0000-7ffffc0a000 rw-p 7ffffbe0000 00:00 0 [stack]
| fffff80000000000-fffff8000001c000 r-xp 00000000 08:01 14226 /lib64/ld-2.3.5.so
| fffff8000011c000-fffff8000011e000 r--p 0001c000 08:01 14226 /lib64/ld-2.3.5.so
| fffff8000011e000-fffff80000120000 rwxp 0001e000 08:01 14226 /lib64/ld-2.3.5.so
| fffff80000120000-fffff80000258000 r-xp 00000000 08:01 14233 /lib64/libc-2.3.5.so
| fffff80000258000-fffff80000356000 ---p 00138000 08:01 14233 /lib64/libc-2.3.5.so
| fffff80000356000-fffff8000035a000 r--p 00136000 08:01 14233 /lib64/libc-2.3.5.so
| fffff8000035a000-fffff80000362000 rwxp 0013a000 08:01 14233 /lib64/libc-2.3.5.so
| fffff80000362000-fffff80000366000 rwxp fffff80000362000 00:00 0
`----

Just look at those 64-bit addresses and different library paths! (Note
also that the stack has moved around, because Linux, on SPARC64 at
least, defaults to the `medlow' model, with 64-bit addresses, but
executable and stack always in the low 32 bits. You can set different
code models, but *they are all incompatible*, which means you'd need a
different libc and so on for each one. Generally, a whole system uses
only one model per `bitness', and most of the models are reserved for
specialist purposes (like the kernel).

On x86-64, it looks like the 64-bit default is to try to fit all code
and constant data in 31 bits (the `small' model), judging by
gcc/config/i386/i386.c:override_options(), and the absence of any
specific defaults in i386.h or linux64.h....

.... I should have just checked the GCC docs, where it says exactly that.
*slaps self*

>> See include/linux/personality.h.
>
> It contains enums for PER_LINUX_32BIT and PER_LINUX32 etc, but not
> PER_LINUX_32.

This is a typo in the Debian packaging:

amaterasu 44 /tmp/linux32-1.orig% grep -RF PER_LINUX *
debian/control: On systems without support for the PER_LINUX_32 execution domain, this
linux32.c:#define DFL_PER PER_LINUX32_3GB
linux32.c:#define DFL_PER PER_LINUX32
linux32.c:#define PER_LINUX32_3GB (0x0008 | ADDR_LIMIT_3GB)
linux32.c:#if DFL_PER == PER_LINUX32_3GB
linux32.c: if (!strcmp(av[0],"linux64")) pers= PER_LINUX;
linux32.c: pers = PER_LINUX32_3GB;
linux32.c: pers = PER_LINUX32;

>> Now try `linux32 uname -a', and be enlightened.
>
> I realise what linux32 does, but I couldn't tell quite what that comment
> is trying to get across.

It is... not a very good package description. The sort of thing of which
interminable flamewars on debian-devel are made...

--
`I work in computers so, of course, I'm an expert on everything.'
--- Simon Rumble
First  |  Prev  | 
Pages: 1 2 3
Prev: Wanadoo
Next: AddOn GWK140