Record TLS modules and layout static TLS memory

Bug: http://b/78026329
Test: bionic unit tests
Change-Id: Ibf1bf5ec864c7830e4cd1cb882842b644e6182ae
diff --git a/linker/linker_soinfo.h b/linker/linker_soinfo.h
index 44bff28..87e385d 100644
--- a/linker/linker_soinfo.h
+++ b/linker/linker_soinfo.h
@@ -30,8 +30,10 @@
 
 #include <link.h>
 
+#include <memory>
 #include <string>
 
+#include "private/bionic_elf_tls.h"
 #include "linker_namespaces.h"
 
 #define FLAG_LINKED           0x00000001
@@ -61,7 +63,7 @@
                                          // unset.
 #define FLAG_NEW_SOINFO       0x40000000 // new soinfo format
 
-#define SOINFO_VERSION 4
+#define SOINFO_VERSION 5
 
 typedef void (*linker_dtor_function_t)();
 typedef void (*linker_ctor_function_t)(int, char**, char**);
@@ -100,6 +102,17 @@
 // TODO(dimitry): remove reference from soinfo member functions to this class.
 class VersionTracker;
 
+// The first ELF TLS module has ID 1. Zero is reserved for the first word of
+// the DTV, a generation count, and unresolved weak symbols also use module
+// ID 0.
+static constexpr size_t kUninitializedModuleId = 0;
+
+struct soinfo_tls {
+  TlsSegment segment;
+  size_t module_id = kUninitializedModuleId;
+  TlsModule* module = nullptr;
+};
+
 #if defined(__work_around_b_24465209__)
 #define SOINFO_NAME_LEN 128
 #endif
@@ -284,6 +297,8 @@
   void add_secondary_namespace(android_namespace_t* secondary_ns);
   android_namespace_list_t& get_secondary_namespaces();
 
+  soinfo_tls* get_tls() const;
+
   void set_mapped_by_caller(bool reserved_map);
   bool is_mapped_by_caller() const;
 
@@ -366,6 +381,9 @@
   // version >= 4
   ElfW(Relr)* relr_;
   size_t relr_count_;
+
+  // version >= 5
+  std::unique_ptr<soinfo_tls> tls_;
 };
 
 // This function is used by dlvsym() to calculate hash of sym_ver