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