prelink breaks fdpic support in a bunch of places

Mike Frysinger vapier at gentoo.org
Sun Nov 27 08:11:53 UTC 2011


there seems to be a bunch of changes that the associated changelog does not
seem to cover.  so i don't know if they were changed on purpose, by accident,
etc...

> commit a33796043bdef5345bc00a528c942f91a87af8e9
> ldso: Add runtime prelink support
>
> _dl_load_elf_shared_library(int secure,...)
> ...
> -	DL_LOADADDR_TYPE lib_loadaddr;
> +	DL_LOADADDR_TYPE lib_loadaddr = 0;

why is this necessary ?  nothing else in this func changed.  you can't assign
directly to a variable of type DL_LOADADDR_TYPE.

> int _dl_fixup(struct dyn_elf *rpnt, struct r_scope_elem *scope, int now_flag)
> ...
> -	elf_machine_relative(tpnt->loadaddr, reloc_addr, relative_count);
> +	if (tpnt->loadaddr
> +#ifdef __LDSO_PRELINK_SUPPORT__
> +		|| (!tpnt->dynamic_info[DT_GNU_PRELINKED_IDX])
> +#endif
> +		)
> +		elf_machine_relative(tpnt->loadaddr, reloc_addr, relative_count);

why is tpn->loadaddr now being checked ?

> DL_START(unsigned long args)
> ...
> -	elf_machine_relative(load_addr, rel_addr, relative_count);
> +	if (load_addr
> +#ifdef __LDSO_PRELINK_SUPPORT__
> +		|| !tpnt->dynamic_info[DT_GNU_PRELINKED_IDX]
> +#endif
> +		)
> +		elf_machine_relative(load_addr, rel_addr, relative_count);

why is load_addr now being checked ?

> commit 94cc6edb78a12655c0602a246fa1cbdc8c6d0ad9
> ldso: Rework global scope handling and symbol lookup mechanism
>
> DL_START(unsigned long args)
> ...
> -	DL_BOOT_COMPUTE_DYN(dpnt, got, load_addr);
> +	DL_BOOT_COMPUTE_DYN(dpnt, got, (DL_LOADADDR_TYPE)header);

why was that cast added and changed from load_addr to header ?

> commit 637e2b2440f69e22932edd71bd2f0b1210dc32ea
> ldso: Add implementation of ld.so standalone execution
>
> DL_START(unsigned long args)
> ...
> -	_dl_elf_main = (int (*)(int, char **, char **)) 
> -		auxvt[AT_ENTRY].a_un.a_val;
> -	_dl_get_ready_to_run(tpnt, load_addr, auxvt, envp, argv
> -		DL_GET_READY_TO_RUN_EXTRA_ARGS);
> +	_dl_elf_main = (int (*)(int, char **, char **))
> +		_dl_get_ready_to_run(tpnt, (DL_LOADADDR_TYPE) header, auxvt, envp,
> +                        argv, DL_GET_READY_TO_RUN_EXTRA_ARGS);

why was load_addr changed to header and the cast added ?

> commit b9766aa08c90b6718d5497d6a6cf9e6f737e5141
> ldso: Fix loadaddr and mappaddr when prelink support is enabled.
> 
> add_ldso(struct elf_resolve *tpnt,...)
> ...
> +	tpnt->mapaddr = load_addr;

mapaddr is of type ElfW(Addr) but load_addr is of type DL_LOADADDR_TYPE.  you
cannot assign one to the other.

> _dl_load_elf_shared_library(int secure, ...)
> ...
>		tryaddr = (piclib == 2 ? 0
>			: (char *) (ppnt->p_vaddr & PAGE_ALIGN)
> -				+ (piclib ? libaddr : 0));
> +				+ (piclib ? libaddr : lib_loadaddr));

you can't read the value of lib_loadaddr directly, so this change is broken.
there were more in the original patch, but it seems a change since (by Bernd?)
fixed the others.

> -   /* For a non-PIC library, the addresses are all absolute */
> -   if (piclib) {
> +   /*
> +    * The dynamic_addr must be take into acount lib_loadaddr value, to note
> +    * it is zero when the SO has been mapped to the elf's physical addr
> +    */
> +   if (lib_loadaddr) {
>		dynamic_addr = (unsigned long) DL_RELOC_ADDR(lib_loadaddr, dynamic_addr);
>     }

we have piclib because you can't read lib_loadaddr directly (it's of type
DL_LOADADDR_TYPE), so this is broken

> -	tpnt->ppnt = (ElfW(Phdr) *) DL_RELOC_ADDR(tpnt->loadaddr, epnt->e_phoff);
> +	tpnt->ppnt = (ElfW(Phdr) *) DL_RELOC_ADDR(tpnt->mapaddr, epnt->e_phoff);

we needed this to be the loadaddr, not the mapaddr ... they aren't the same
type, so they aren't directly interchangeable
-mike
-mike
-------------- next part --------------
A non-text attachment was scrubbed...
Name: signature.asc
Type: application/pgp-signature
Size: 836 bytes
Desc: This is a digitally signed message part.
URL: <http://lists.busybox.net/pipermail/uclibc/attachments/20111127/0e0caab0/attachment.asc>


More information about the uClibc mailing list