Merge "Disable Android relocation packing in linker." into main
diff --git a/linker/Android.bp b/linker/Android.bp
index f87a92e..e1a5a91 100644
--- a/linker/Android.bp
+++ b/linker/Android.bp
@@ -334,6 +334,13 @@
"-Wl,-Bsymbolic",
"-Wl,--exclude-libs,ALL",
"-Wl,-soname,ld-android.so",
+ // When the linker applies its own IRELATIVE relocations, it will only read DT_REL[A] and
+ // DT_JMPREL, not DT_ANDROID_REL[A], which can also theoretically contain IRELATIVE
+ // relocations. lld has been taught to not store them there as a bug workaround (see
+ // https://llvm.org/pr86751) but the workaround could be removed at some point in the
+ // future. So we explicitly prevent it from doing so by disabling DT_ANDROID_REL[A] when
+ // linking the linker (DT_RELR cannot encode IRELATIVE relocations).
+ "-Wl,--pack-dyn-relocs=relr",
],
// we are going to link libc++_static manually because
diff --git a/linker/linker_main.cpp b/linker/linker_main.cpp
index c9dcfa3..c0a68af 100644
--- a/linker/linker_main.cpp
+++ b/linker/linker_main.cpp
@@ -647,6 +647,9 @@
auto *dyn = reinterpret_cast<ElfW(Dyn)*>(ehdr + phdr[i].p_vaddr);
ElfW(Addr) pltrel = 0, pltrelsz = 0, rel = 0, relsz = 0;
for (size_t j = 0, size = phdr[i].p_filesz / sizeof(ElfW(Dyn)); j != size; ++j) {
+ // We can't handle IRELATIVE relocations in DT_ANDROID_REL[A].
+ // We disabled DT_ANDROID_REL[A] at build time; verify that it was actually disabled.
+ CHECK(dyn[j].d_tag != DT_ANDROID_REL && dyn[j].d_tag != DT_ANDROID_RELA);
if (dyn[j].d_tag == DT_JMPREL) {
pltrel = dyn[j].d_un.d_ptr;
} else if (dyn[j].d_tag == DT_PLTRELSZ) {