Subject: Re: MIPS shared linker running at virtual address 0!
To: Simon Burge <simonb@wasabisystems.com>
From: Matthias Drochner <M.Drochner@fz-juelich.de>
List: tech-kern
Date: 07/29/2005 20:42:49
simonb@wasabisystems.com said:
> I'll ignore comments along the lines of "eww, that's ugly"

eew, that's ugly:-)
It seems that I'm the last person who touched this stuff
(2 years ago), so I should feel responsible.

> +	 * Evil hack:  Only MIPS should be non-relocatable, and the
> [...]
> +	if (*last == ELF_LINK_ADDR && (ph->p_vaddr & 0xffff0000) == 0)

In principle, that patch is not too bad. Just that if this
applies to MIPS only, I'd also put an "#ifdef __mips__" or
so around. In particular, the p_vaddr check is mips specific.
And here I have a little concern: The patch just tests the first
program header, no matter whether PT_LOAD or not. If I look at
a -current ld.elf_so:

$ objdump -p /usr/libexec/ld.elf_so
/usr/libexec/ld.elf_so:     file format elf32-tradlittlemips
Program Header:
0x70000000 off    0x000000d4 vaddr 0x000000d4 paddr 0x000000d4 align 2**2
         filesz 0x00000018 memsz 0x00000018 flags r--
    LOAD off    0x00000000 vaddr 0x00000000 paddr 0x00000000 align 2**16
         filesz 0x0000d918 memsz 0x0000d918 flags r-x
    LOAD off    0x0000d920 vaddr 0x0004d920 paddr 0x0004d920 align 2**16
         filesz 0x00000c28 memsz 0x00001610 flags rw-
 DYNAMIC off    0x000000ec vaddr 0x000000ec paddr 0x000000ec align 2**2
         filesz 0x00002107 memsz 0x00002107 flags rwx
    NOTE off    0x0000d900 vaddr 0x0000d900 paddr 0x0000d900 align 2**2
         filesz 0x00000018 memsz 0x00000018 flags r--

There is a non-PT_LOAD section at the beginning.

It might be cleaner to do the address check after the phdrs are
walked through, a couple of lines later. Of course the "if" at
the beginning would have to be something like

	if (*last == ELFDEFNNAME(NO_ADDR)
#ifdef ELF_INTERP_NON_RELOCATABLE
		|| *last == ELF_LINK_ADDR
#endif
	) {
		[scan phdrs]
#ifdef ELF_INTERP_NON_RELOCATABLE
		if (*last == ELF_LINK_ADDR && trunc_page(base_ph->p_vaddr) == 0)
			addr = *last;
		else
#endif
			[allocate as before]
	}


best regards
Matthias