From: Rich Felker Date: Mon, 18 May 2015 20:51:54 +0000 (-0400) Subject: reprocess libc/ldso RELA relocations in stage 3 of dynamic linking X-Git-Tag: v1.1.10~24 X-Git-Url: https://git.librecmc.org/?a=commitdiff_plain;h=c093e2e8201524db0d638920e76bcb6b1d925f3a;p=oweals%2Fmusl.git reprocess libc/ldso RELA relocations in stage 3 of dynamic linking this fixes a regression on powerpc that was introduced in commit f3ddd173806fd5c60b3f034528ca24542aecc5b9. global data accesses on powerpc seem to be using a translation-unit-local GOT filled via R_PPC_ADDR32 relocations rather than R_PPC_GLOB_DAT. being a non-GOT relocation type, these were not reprocessed after adding the main application and its libraries to the chain, causing libc code not to see copy relocations in the main program, and therefore to use the pre-copy-relocation addresses for global data objects (like environ). the motivation for the dynamic linker only reprocessing GOT/PLT relocation types in stage 3 is that these types always have a zero addend, making them safe to process again even if the storage for the addend has been clobbered. other relocation types which can be used for address constants in initialized data objects may have non-zero addends which will be clobbered during the first pass of relocation processing if they're stored inline (REL form) rather than out-of-line (RELA form). powerpc generally uses only RELA, so this patch is sufficient to fix the regression in practice, but is not fully general, and would not suffice if an alternate toolchain generated REL for powerpc. --- diff --git a/src/ldso/dynlink.c b/src/ldso/dynlink.c index 7c92ef6c..93595a0f 100644 --- a/src/ldso/dynlink.c +++ b/src/ldso/dynlink.c @@ -281,7 +281,7 @@ static void do_relocs(struct dso *dso, size_t *rel, size_t rel_size, size_t stri } int gotplt = (type == REL_GOT || type == REL_PLT); - if (dso->rel_update_got && !gotplt) continue; + if (dso->rel_update_got && !gotplt && stride==2) continue; addend = stride>2 ? rel[2] : gotplt || type==REL_COPY ? 0