Last active
February 11, 2025 14:42
-
-
Save akku1139/efe06d281f464a6e9017bfd023b92720 to your computer and use it in GitHub Desktop.
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
diff --git a/linker/linker.cpp b/linker/linker.cpp | |
index cf65705..ed5ebf2 100644 | |
--- a/linker/linker.cpp | |
+++ b/linker/linker.cpp | |
@@ -1117,17 +1117,52 @@ static int soinfo_relocate(soinfo* si, ElfW(Rela)* rela, unsigned count, soinfo* | |
break; | |
case R_AARCH64_COPY: | |
- /* | |
- * ET_EXEC is not supported so this should not happen. | |
- * | |
- * http://infocenter.arm.com/help/topic/com.arm.doc.ihi0044d/IHI0044D_aaelf.pdf | |
- * | |
- * Section 4.7.1.10 "Dynamic relocations" | |
- * R_AARCH64_COPY may only appear in executable objects where e_type is | |
- * set to ET_EXEC. | |
- */ | |
- DL_ERR("%s R_AARCH64_COPY relocations are not supported", si->name); | |
- return -1; | |
+ if ((si->flags & FLAG_EXE) == 0) { | |
+ /* | |
+ * http://infocenter.arm.com/help/topic/com.arm.doc.ihi0044d/IHI0044D_aaelf.pdf | |
+ * | |
+ * Section 4.7.1.10 "Dynamic relocations" | |
+ * R_AARCH64_COPY may only appear in executable objects where e_type is | |
+ * set to ET_EXEC. | |
+ * | |
+ * FLAG_EXE is set for both ET_DYN and ET_EXEC executables. | |
+ * We should explicitly disallow ET_DYN executables from having | |
+ * R_AARCH64_COPY relocations. | |
+ */ | |
+ DL_ERR("%s R_AARCH64_COPY relocations only supported for ET_EXEC", si->name); | |
+ return -1; | |
+ } | |
+ count_relocation(kRelocCopy); | |
+ MARK(rela->r_offset); | |
+ TRACE_TYPE(RELO, "RELO COPY %16llx <- %lld @ %16llx %s\n", | |
+ reloc, | |
+ s->st_size, | |
+ (sym_addr + rela->r_addend), | |
+ sym_name); | |
+ if (reloc == (sym_addr + rela->r_addend)) { | |
+ ElfW(Sym)* src = soinfo_do_lookup(NULL, sym_name, &lsi, needed); | |
+ | |
+ if (src == NULL) { | |
+ DL_ERR("%s R_AARCH64_COPY relocation source cannot be resolved", si->name); | |
+ return -1; | |
+ } | |
+ if (lsi->has_DT_SYMBOLIC) { | |
+ DL_ERR("%s invalid R_AARCH64_COPY relocation against DT_SYMBOLIC shared " | |
+ "library %s (built with -Bsymbolic?)", si->name, lsi->name); | |
+ return -1; | |
+ } | |
+ if (s->st_size < src->st_size) { | |
+ DL_ERR("%s R_AARCH64_COPY relocation size mismatch (%lld < %lld)", | |
+ si->name, s->st_size, src->st_size); | |
+ return -1; | |
+ } | |
+ memcpy(reinterpret_cast<void*>(reloc), | |
+ reinterpret_cast<void*>(src->st_value + lsi->load_bias), src->st_size); | |
+ } else { | |
+ DL_ERR("%s R_AARCH64_COPY relocation target cannot be resolved", si->name); | |
+ return -1; | |
+ } | |
+ break; | |
case R_AARCH64_TLS_TPREL64: | |
TRACE_TYPE(RELO, "RELO TLS_TPREL64 *** %16llx <- %16llx - %16llx\n", | |
reloc, (sym_addr + rela->r_addend), rela->r_offset); | |
@@ -1305,17 +1340,48 @@ static int soinfo_relocate(soinfo* si, ElfW(Rel)* rel, unsigned count, soinfo* n | |
*reinterpret_cast<ElfW(Addr)*>(reloc) += sym_addr - rel->r_offset; | |
break; | |
case R_ARM_COPY: | |
- /* | |
- * ET_EXEC is not supported so this should not happen. | |
- * | |
- * http://infocenter.arm.com/help/topic/com.arm.doc.ihi0044d/IHI0044D_aaelf.pdf | |
- * | |
- * Section 4.7.1.10 "Dynamic relocations" | |
- * R_ARM_COPY may only appear in executable objects where e_type is | |
- * set to ET_EXEC. | |
- */ | |
- DL_ERR("%s R_ARM_COPY relocations are not supported", si->name); | |
- return -1; | |
+ if ((si->flags & FLAG_EXE) == 0) { | |
+ /* | |
+ * http://infocenter.arm.com/help/topic/com.arm.doc.ihi0044d/IHI0044D_aaelf.pdf | |
+ * | |
+ * Section 4.7.1.10 "Dynamic relocations" | |
+ * R_ARM_COPY may only appear in executable objects where e_type is | |
+ * set to ET_EXEC. | |
+ * | |
+ * TODO: FLAG_EXE is set for both ET_DYN and ET_EXEC executables. | |
+ * We should explicitly disallow ET_DYN executables from having | |
+ * R_ARM_COPY relocations. | |
+ */ | |
+ DL_ERR("%s R_ARM_COPY relocations only supported for ET_EXEC", si->name); | |
+ return -1; | |
+ } | |
+ count_relocation(kRelocCopy); | |
+ MARK(rel->r_offset); | |
+ TRACE_TYPE(RELO, "RELO %08x <- %d @ %08x %s", reloc, s->st_size, sym_addr, sym_name); | |
+ if (reloc == sym_addr) { | |
+ ElfW(Sym)* src = soinfo_do_lookup(NULL, sym_name, &lsi, needed); | |
+ | |
+ if (src == NULL) { | |
+ DL_ERR("%s R_ARM_COPY relocation source cannot be resolved", si->name); | |
+ return -1; | |
+ } | |
+ if (lsi->has_DT_SYMBOLIC) { | |
+ DL_ERR("%s invalid R_ARM_COPY relocation against DT_SYMBOLIC shared " | |
+ "library %s (built with -Bsymbolic?)", si->name, lsi->name); | |
+ return -1; | |
+ } | |
+ if (s->st_size < src->st_size) { | |
+ DL_ERR("%s R_ARM_COPY relocation size mismatch (%d < %d)", | |
+ si->name, s->st_size, src->st_size); | |
+ return -1; | |
+ } | |
+ memcpy(reinterpret_cast<void*>(reloc), | |
+ reinterpret_cast<void*>(src->st_value + lsi->load_bias), src->st_size); | |
+ } else { | |
+ DL_ERR("%s R_ARM_COPY relocation target cannot be resolved", si->name); | |
+ return -1; | |
+ } | |
+ break; | |
#elif defined(__i386__) | |
case R_386_JMP_SLOT: | |
count_relocation(kRelocAbsolute); | |
@@ -2177,11 +2243,13 @@ static ElfW(Addr) __linker_init_post_relocation(KernelArgumentBlock& args, ElfW( | |
si->dynamic = NULL; | |
si->ref_count = 1; | |
+#if defined(__LP64__) | |
ElfW(Ehdr)* elf_hdr = reinterpret_cast<ElfW(Ehdr)*>(si->base); | |
if (elf_hdr->e_type != ET_DYN) { | |
__libc_format_fd(2, "error: only position independent executables (PIE) are supported.\n"); | |
exit(EXIT_FAILURE); | |
} | |
+#endif | |
// Use LD_LIBRARY_PATH and LD_PRELOAD (but only if we aren't setuid/setgid). | |
parse_LD_LIBRARY_PATH(ldpath_env); |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment