Merge changes Idb061b98,I93c17ca6 into main

* changes:
  ldd: skip relocation processing, TLS modules, CFI
  Guard against linker[64] having a PT_TLS segment
diff --git a/linker/linker.cpp b/linker/linker.cpp
index e54a524..81869b3 100644
--- a/linker/linker.cpp
+++ b/linker/linker.cpp
@@ -2866,11 +2866,12 @@
 
   TlsSegment tls_segment;
   if (__bionic_get_tls_segment(phdr, phnum, load_bias, &tls_segment)) {
+    // The loader does not (currently) support ELF TLS, so it shouldn't have
+    // a TLS segment.
+    CHECK(!relocating_linker && "TLS not supported in loader");
     if (!__bionic_check_tls_alignment(&tls_segment.alignment)) {
-      if (!relocating_linker) {
-        DL_ERR("TLS segment alignment in \"%s\" is not a power of 2: %zu",
-               get_realpath(), tls_segment.alignment);
-      }
+      DL_ERR("TLS segment alignment in \"%s\" is not a power of 2: %zu", get_realpath(),
+             tls_segment.alignment);
       return false;
     }
     tls_ = std::make_unique<soinfo_tls>();
diff --git a/linker/linker_main.cpp b/linker/linker_main.cpp
index 1860ccc..c9dcfa3 100644
--- a/linker/linker_main.cpp
+++ b/linker/linker_main.cpp
@@ -496,6 +496,12 @@
     }
     si->increment_ref_count();
   }
+
+  // Exit early for ldd. We don't want to run the code that was loaded, so skip
+  // the constructor calls. Skip CFI setup because it would call __cfi_init in
+  // libdl.so.
+  if (g_is_ldd) _exit(EXIT_SUCCESS);
+
 #if defined(__aarch64__)
   // This has to happen after the find_libraries, which will have collected any possible
   // libraries that request memtag_stack in the dynamic section.
@@ -829,8 +835,6 @@
 
   ElfW(Addr) start_address = linker_main(args, exe_to_load);
 
-  if (g_is_ldd) _exit(EXIT_SUCCESS);
-
   INFO("[ Jumping to _start (%p)... ]", reinterpret_cast<void*>(start_address));
 
   // Return the address that the calling assembly stub should jump to.
diff --git a/linker/linker_relocate.cpp b/linker/linker_relocate.cpp
index 5b58895..080570d 100644
--- a/linker/linker_relocate.cpp
+++ b/linker/linker_relocate.cpp
@@ -421,6 +421,7 @@
         } else {
           CHECK(found_in->get_tls() != nullptr); // We rejected a missing TLS segment above.
           module_id = found_in->get_tls()->module_id;
+          CHECK(module_id != kTlsUninitializedModuleId);
         }
         trace_reloc("RELO TLS_DTPMOD %16p <- %zu %s",
                     rel_target, module_id, sym_name);
@@ -588,6 +589,11 @@
 }
 
 bool soinfo::relocate(const SymbolLookupList& lookup_list) {
+  // For ldd, don't apply relocations because TLS segments are not registered.
+  // We don't care whether ldd diagnoses unresolved symbols.
+  if (g_is_ldd) {
+    return true;
+  }
 
   VersionTracker version_tracker;
 
diff --git a/linker/linker_soinfo.cpp b/linker/linker_soinfo.cpp
index 3e7506c..802c06a 100644
--- a/linker/linker_soinfo.cpp
+++ b/linker/linker_soinfo.cpp
@@ -503,15 +503,13 @@
 }
 
 void soinfo::call_pre_init_constructors() {
-  if (g_is_ldd) return;
-
   // DT_PREINIT_ARRAY functions are called before any other constructors for executables,
   // but ignored in a shared library.
   call_array("DT_PREINIT_ARRAY", preinit_array_, preinit_array_count_, false, get_realpath());
 }
 
 void soinfo::call_constructors() {
-  if (constructors_called || g_is_ldd) {
+  if (constructors_called) {
     return;
   }
 
diff --git a/linker/linker_tls.cpp b/linker/linker_tls.cpp
index 97892f4..e90b8cb 100644
--- a/linker/linker_tls.cpp
+++ b/linker/linker_tls.cpp
@@ -31,14 +31,15 @@
 #include <vector>
 
 #include "async_safe/CHECK.h"
+#include "linker_globals.h"
+#include "linker_main.h"
+#include "linker_soinfo.h"
 #include "private/ScopedRWLock.h"
 #include "private/ScopedSignalBlocker.h"
 #include "private/bionic_defs.h"
 #include "private/bionic_elf_tls.h"
 #include "private/bionic_globals.h"
 #include "private/linker_native_bridge.h"
-#include "linker_main.h"
-#include "linker_soinfo.h"
 
 static bool g_static_tls_finished;
 static std::vector<TlsModule> g_tls_modules;
@@ -109,7 +110,11 @@
 void linker_setup_exe_static_tls(const char* progname) {
   soinfo* somain = solist_get_somain();
   StaticTlsLayout& layout = __libc_shared_globals()->static_tls_layout;
-  if (somain->get_tls() == nullptr) {
+
+  // For ldd, don't add the executable's TLS segment to the static TLS layout.
+  // It is likely to trigger the underaligned TLS segment error on arm32/arm64
+  // when the ldd argument is actually a shared object.
+  if (somain->get_tls() == nullptr || g_is_ldd) {
     layout.reserve_exe_segment_and_tcb(nullptr, progname);
   } else {
     register_tls_module(somain, layout.reserve_exe_segment_and_tcb(&somain->get_tls()->segment, progname));
@@ -133,6 +138,11 @@
 }
 
 void register_soinfo_tls(soinfo* si) {
+  // ldd skips registration of the executable's TLS segment above to avoid the
+  // arm32/arm64 underalignment error. For consistency, also skip registration
+  // of TLS segments here, for shared objects.
+  if (g_is_ldd) return;
+
   soinfo_tls* si_tls = si->get_tls();
   if (si_tls == nullptr || si_tls->module_id != kTlsUninitializedModuleId) {
     return;