diff --git a/linker/linker.cpp b/linker/linker.cpp index 2be58ed7a..51ec29760 100644 --- a/linker/linker.cpp +++ b/linker/linker.cpp @@ -3198,6 +3198,17 @@ bool soinfo::relocate(const VersionTracker& version_tracker, ElfRelIteratorT&& r *reinterpret_cast(reloc) = ifunc_addr; } break; + case R_GENERIC_COPY: + // Copy relocations allow read-only data or code in a non-PIE executable to access a + // variable from a DSO. The executable reserves extra space in its .bss section, and the + // linker copies the variable into the extra space. The executable then exports its copy + // to interpose the copy in the DSO. + // + // Bionic only supports PIE executables, so copy relocations aren't supported. The ARM and + // AArch64 ABI documents only allow them for ET_EXEC (non-PIE) objects. See IHI0056B and + // IHI0044F. + DL_ERR("%s COPY relocations are not supported", get_realpath()); + return false; case R_GENERIC_TLS_TPREL: count_relocation(kRelocRelative); MARK(rel->r_offset); @@ -3292,20 +3303,7 @@ bool soinfo::relocate(const VersionTracker& version_tracker, ElfRelIteratorT&& r break; #endif // defined(__aarch64__) -#if defined(__aarch64__) - case R_AARCH64_COPY: - /* - * ET_EXEC is not supported so this should not happen. - * - * http://infocenter.arm.com/help/topic/com.arm.doc.ihi0056b/IHI0056B_aaelf64.pdf - * - * Section 4.6.11 "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", get_realpath()); - return false; -#elif defined(__x86_64__) +#if defined(__x86_64__) case R_X86_64_32: count_relocation(kRelocAbsolute); MARK(rel->r_offset); @@ -3329,18 +3327,6 @@ bool soinfo::relocate(const VersionTracker& version_tracker, ElfRelIteratorT&& r reloc, sym_addr, rel->r_offset, sym_name); *reinterpret_cast(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.6.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", get_realpath()); - return false; #elif defined(__i386__) case R_386_PC32: count_relocation(kRelocRelative); diff --git a/linker/linker_relocs.h b/linker/linker_relocs.h index 5424445f1..93d899e0f 100644 --- a/linker/linker_relocs.h +++ b/linker/linker_relocs.h @@ -40,6 +40,7 @@ #define R_GENERIC_GLOB_DAT R_AARCH64_GLOB_DAT #define R_GENERIC_RELATIVE R_AARCH64_RELATIVE #define R_GENERIC_IRELATIVE R_AARCH64_IRELATIVE +#define R_GENERIC_COPY R_AARCH64_COPY #define R_GENERIC_TLS_DTPMOD R_AARCH64_TLS_DTPMOD #define R_GENERIC_TLS_DTPREL R_AARCH64_TLS_DTPREL #define R_GENERIC_TLS_TPREL R_AARCH64_TLS_TPREL @@ -53,6 +54,7 @@ #define R_GENERIC_GLOB_DAT R_ARM_GLOB_DAT #define R_GENERIC_RELATIVE R_ARM_RELATIVE #define R_GENERIC_IRELATIVE R_ARM_IRELATIVE +#define R_GENERIC_COPY R_ARM_COPY #define R_GENERIC_TLS_DTPMOD R_ARM_TLS_DTPMOD32 #define R_GENERIC_TLS_DTPREL R_ARM_TLS_DTPOFF32 #define R_GENERIC_TLS_TPREL R_ARM_TLS_TPOFF32 @@ -65,6 +67,7 @@ #define R_GENERIC_GLOB_DAT R_386_GLOB_DAT #define R_GENERIC_RELATIVE R_386_RELATIVE #define R_GENERIC_IRELATIVE R_386_IRELATIVE +#define R_GENERIC_COPY R_386_COPY #define R_GENERIC_TLS_DTPMOD R_386_TLS_DTPMOD32 #define R_GENERIC_TLS_DTPREL R_386_TLS_DTPOFF32 #define R_GENERIC_TLS_TPREL R_386_TLS_TPOFF @@ -77,6 +80,7 @@ #define R_GENERIC_GLOB_DAT R_X86_64_GLOB_DAT #define R_GENERIC_RELATIVE R_X86_64_RELATIVE #define R_GENERIC_IRELATIVE R_X86_64_IRELATIVE +#define R_GENERIC_COPY R_X86_64_COPY #define R_GENERIC_TLS_DTPMOD R_X86_64_DTPMOD64 #define R_GENERIC_TLS_DTPREL R_X86_64_DTPOFF64 #define R_GENERIC_TLS_TPREL R_X86_64_TPOFF64