diff --git a/csu/libc-start.c b/csu/libc-start.c
index c3bb6d09bc..5ec6303c82 100644
--- a/csu/libc-start.c
+++ b/csu/libc-start.c
@@ -125,14 +125,14 @@ static void
 call_init (int argc, char **argv, char **env)
 {
   /* Obtain the main map of the executable.  */
-  struct link_map *l = GL(dl_ns)[LM_ID_BASE]._ns_loaded;
+  struct link_map_private *l = GL(dl_ns)[LM_ID_BASE]._ns_loaded;
 
   /* DT_PREINIT_ARRAY is not processed here.  It is already handled in
      _dl_init in elf/dl-init.c.  Also see the call_init function in
      the same file.  */
 
   if (ELF_INITFINI && l->l_info[DT_INIT] != NULL)
-    DL_CALL_DT_INIT(l, l->l_addr + l->l_info[DT_INIT]->d_un.d_ptr,
+    DL_CALL_DT_INIT(l, l->l_public.l_addr + l->l_info[DT_INIT]->d_un.d_ptr,
 		    argc, argv, env);
 
   ElfW(Dyn) *init_array = l->l_info[DT_INIT_ARRAY];
@@ -140,7 +140,8 @@ call_init (int argc, char **argv, char **env)
     {
       unsigned int jm
 	= l->l_info[DT_INIT_ARRAYSZ]->d_un.d_val / sizeof (ElfW(Addr));
-      ElfW(Addr) *addrs = (void *) (init_array->d_un.d_ptr + l->l_addr);
+      ElfW(Addr) *addrs = (void *) (init_array->d_un.d_ptr
+				    + l->l_public.l_addr);
       for (unsigned int j = 0; j < jm; ++j)
 	((dl_init_t) addrs[j]) (argc, argv, env);
     }
diff --git a/csu/libc-tls.c b/csu/libc-tls.c
index cdf6442c02..7a3238789d 100644
--- a/csu/libc-tls.c
+++ b/csu/libc-tls.c
@@ -114,7 +114,7 @@ __libc_setup_tls (void)
   size_t tcb_offset;
   const ElfW(Phdr) *phdr;
 
-  struct link_map *main_map = GL(dl_ns)[LM_ID_BASE]._ns_loaded;
+  struct link_map_private *main_map = GL(dl_ns)[LM_ID_BASE]._ns_loaded;
 
   __tls_pre_init_tp ();
 
@@ -125,7 +125,7 @@ __libc_setup_tls (void)
 	/* Remember the values we need.  */
 	memsz = phdr->p_memsz;
 	filesz = phdr->p_filesz;
-	initimage = (void *) phdr->p_vaddr + main_map->l_addr;
+	initimage = (void *) phdr->p_vaddr + main_map->l_public.l_addr;
 	align = phdr->p_align;
 	if (phdr->p_align > max_align)
 	  max_align = phdr->p_align;
diff --git a/debug/backtracesyms.c b/debug/backtracesyms.c
index 079d8d0d22..0633fc0f5a 100644
--- a/debug/backtracesyms.c
+++ b/debug/backtracesyms.c
@@ -44,7 +44,7 @@ __backtrace_symbols (void *const *array, int size)
   /* Fill in the information we can get from `dladdr'.  */
   for (cnt = 0; cnt < size; ++cnt)
     {
-      struct link_map *map;
+      struct link_map_private *map;
       status[cnt] = _dl_addr (array[cnt], &info[cnt], &map, NULL);
       if (status[cnt] && info[cnt].dli_fname && info[cnt].dli_fname[0] != '\0')
 	{
@@ -58,7 +58,7 @@ __backtrace_symbols (void *const *array, int size)
 	     address.  The use of these addresses is to calculate an
 	     address in the ELF file, so its prelinked bias is not
 	     something we want to subtract out.  */
-	  info[cnt].dli_fbase = (void *) map->l_addr;
+	  info[cnt].dli_fbase = (void *) map->l_public.l_addr;
 	}
       else
 	total += 5 + WORD_WIDTH;
diff --git a/debug/backtracesymsfd.c b/debug/backtracesymsfd.c
index e78b1c0832..6dab0b38b6 100644
--- a/debug/backtracesymsfd.c
+++ b/debug/backtracesymsfd.c
@@ -42,7 +42,7 @@ __backtrace_symbols_fd (void *const *array, int size, int fd)
       char buf[WORD_WIDTH];
       char buf2[WORD_WIDTH];
       Dl_info info;
-      struct link_map *map;
+      struct link_map_private *map;
       size_t last = 0;
 
       if (_dl_addr (array[cnt], &info, &map, NULL)
@@ -53,7 +53,7 @@ __backtrace_symbols_fd (void *const *array, int size, int fd)
 	  iov[0].iov_len = strlen (info.dli_fname);
 	  last = 1;
 
-	  if (info.dli_sname != NULL || map->l_addr != 0)
+	  if (info.dli_sname != NULL || map->l_public.l_addr != 0)
 	    {
 	      size_t diff;
 
@@ -74,7 +74,7 @@ __backtrace_symbols_fd (void *const *array, int size, int fd)
 		   address.  The use of these addresses is to calculate an
 		   address in the ELF file, so its prelinked bias is not
 		   something we want to subtract out.  */
-		info.dli_saddr = (void *) map->l_addr;
+		info.dli_saddr = (void *) map->l_public.l_addr;
 
 	      if (array[cnt] >= (void *) info.dli_saddr)
 		{
diff --git a/dlfcn/dladdr1.c b/dlfcn/dladdr1.c
index 9466ef1b6e..fe67f5c188 100644
--- a/dlfcn/dladdr1.c
+++ b/dlfcn/dladdr1.c
@@ -36,7 +36,12 @@ __dladdr1 (const void *address, Dl_info *info, void **extra, int flags)
     case RTLD_DL_SYMENT:
       return _dl_addr (address, info, NULL, (const ElfW(Sym) **) extra);
     case RTLD_DL_LINKMAP:
-      return _dl_addr (address, info, (struct link_map **) extra, NULL);
+      {
+	struct link_map_private *l;
+	int ret = _dl_addr (address, info, &l, NULL);
+	*(struct link_map **)extra = &l->l_public;
+	return ret;
+      }
     }
 }
 versioned_symbol (libc, __dladdr1, dladdr1, GLIBC_2_34);
diff --git a/dlfcn/dlinfo.c b/dlfcn/dlinfo.c
index 1b5dd90ae5..2ac4320b36 100644
--- a/dlfcn/dlinfo.c
+++ b/dlfcn/dlinfo.c
@@ -38,7 +38,7 @@ static void
 dlinfo_doit (void *argsblock)
 {
   struct dlinfo_args *const args = argsblock;
-  struct link_map *l = args->handle;
+  struct link_map_private *l = args->handle;
 
   switch (args->request)
     {
@@ -53,7 +53,7 @@ dlinfo_doit (void *argsblock)
       break;
 
     case RTLD_DI_LINKMAP:
-      *(struct link_map **) args->arg = l;
+      *(struct link_map **) args->arg = &l->l_public;
       break;
 
     case RTLD_DI_SERINFO:
diff --git a/dlfcn/tst-dlinfo-phdr.c b/dlfcn/tst-dlinfo-phdr.c
index 4448680f51..b8a5e8e5e3 100644
--- a/dlfcn/tst-dlinfo-phdr.c
+++ b/dlfcn/tst-dlinfo-phdr.c
@@ -59,13 +59,13 @@ do_test (void)
 {
   /* Avoid a copy relocation.  */
   struct r_debug *debug = xdlsym (RTLD_DEFAULT, "_r_debug");
-  struct link_map *l = (struct link_map *) debug->r_map;
+  struct link_map_private *l = l_private (debug->r_map);
   TEST_VERIFY_EXIT (l != NULL);
 
   do
     {
       printf ("info: checking link map %p (%p) for \"%s\"\n",
-              l, l->l_phdr, l->l_name);
+              l, l->l_phdr, l->l_public.l_name);
 
       /* Cause dlerror () to return an error message.  */
       dlsym (RTLD_DEFAULT, "does-not-exist");
@@ -87,7 +87,8 @@ do_test (void)
           if (phdr[i].p_type == PT_DYNAMIC)
             {
               dynamic_found = true;
-              TEST_COMPARE ((ElfW(Addr)) l->l_ld, l->l_addr + phdr[i].p_vaddr);
+              TEST_COMPARE ((ElfW(Addr)) l->l_public.l_ld,
+                            l->l_public.l_addr + phdr[i].p_vaddr);
             }
         TEST_VERIFY (dynamic_found);
       }
@@ -97,7 +98,7 @@ do_test (void)
       {
         struct dlip_callback_args args =
           {
-            .l =  l,
+            .l = &l->l_public,
             .phdr = phdr,
             .phnum = phnum,
             .found = false,
@@ -106,16 +107,16 @@ do_test (void)
         TEST_VERIFY (args.found);
       }
 
-      if (l->l_prev == NULL)
+      if (l->l_public.l_prev == NULL)
         {
           /* This is the executable, so the information is also
              available via getauxval.  */
-          TEST_COMPARE_STRING (l->l_name, "");
+          TEST_COMPARE_STRING (l->l_public.l_name, "");
           TEST_VERIFY (phdr == (const ElfW(Phdr) *) getauxval (AT_PHDR));
           TEST_COMPARE (phnum, getauxval (AT_PHNUM));
         }
 
-      l = l->l_next;
+      l = l_next (l);
     }
   while (l != NULL);
 
diff --git a/elf/circleload1.c b/elf/circleload1.c
index 990ff84a84..dcf04bc25a 100644
--- a/elf/circleload1.c
+++ b/elf/circleload1.c
@@ -5,12 +5,12 @@
 #include <stdlib.h>
 #include <string.h>
 
-#define MAPS ((struct link_map *) _r_debug.r_map)
+#define MAPS (l_private (_r_debug.r_map))
 
 static int
 check_loaded_objects (const char **loaded)
 {
-  struct link_map *lm;
+  struct link_map_private *lm;
   int n;
   int *found = NULL;
   int errors = 0;
@@ -26,16 +26,18 @@ check_loaded_objects (const char **loaded)
 
   printf("   Name\n");
   printf(" --------------------------------------------------------\n");
-  for (lm = MAPS; lm; lm = lm->l_next)
+  for (lm = MAPS; lm != NULL; lm = l_next (lm))
     {
-      if (lm->l_name && lm->l_name[0])
-	printf(" %s, count = %d\n", lm->l_name, (int) lm->l_direct_opencount);
-      if (lm->l_type == lt_loaded && lm->l_name)
+      if (lm->l_public.l_name && lm->l_public.l_name[0])
+	printf(" %s, count = %d\n", lm->l_public.l_name,
+	       (int) lm->l_direct_opencount);
+      if (lm->l_type == lt_loaded && lm->l_public.l_name)
 	{
 	  int match = 0;
 	  for (n = 0; loaded[n] != NULL; n++)
 	    {
-	      if (strcmp (basename (loaded[n]), basename (lm->l_name)) == 0)
+	      if (strcmp (basename (loaded[n]),
+			  basename (lm->l_public.l_name)) == 0)
 	        {
 		  found[n] = 1;
 		  match = 1;
@@ -46,7 +48,7 @@ check_loaded_objects (const char **loaded)
 	  if (match == 0)
 	    {
 	      ++errors;
-	      printf ("ERRORS: %s is not unloaded\n", lm->l_name);
+	      printf ("ERRORS: %s is not unloaded\n", lm->l_public.l_name);
 	    }
 	}
     }
diff --git a/elf/dl-addr-obj.c b/elf/dl-addr-obj.c
index 630710849f..78b8069235 100644
--- a/elf/dl-addr-obj.c
+++ b/elf/dl-addr-obj.c
@@ -61,10 +61,10 @@
 
 */
 int
-_dl_addr_inside_object (struct link_map *l, const ElfW(Addr) addr)
+_dl_addr_inside_object (struct link_map_private *l, const ElfW(Addr) addr)
 {
   int n = l->l_phnum;
-  const ElfW(Addr) reladdr = addr - l->l_addr;
+  const ElfW(Addr) reladdr = addr - l->l_public.l_addr;
 
   while (--n >= 0)
     if (l->l_phdr[n].p_type == PT_LOAD
diff --git a/elf/dl-addr.c b/elf/dl-addr.c
index 44f0103687..6fbc1d4d59 100644
--- a/elf/dl-addr.c
+++ b/elf/dl-addr.c
@@ -23,15 +23,16 @@
 
 static inline void
 __attribute ((always_inline))
-determine_info (const ElfW(Addr) addr, struct link_map *match, Dl_info *info,
-		struct link_map **mapp, const ElfW(Sym) **symbolp)
+determine_info (const ElfW(Addr) addr, struct link_map_private *match,
+		Dl_info *info, struct link_map_private **mapp,
+		const ElfW(Sym) **symbolp)
 {
   /* Now we know what object the address lies in.  */
-  info->dli_fname = match->l_name;
+  info->dli_fname = match->l_public.l_name;
   info->dli_fbase = (void *) match->l_map_start;
 
   /* If this is the main program the information is incomplete.  */
-  if (__builtin_expect (match->l_name[0], 'a') == '\0'
+  if (__builtin_expect (match->l_public.l_name[0], 'a') == '\0'
       && match->l_type == lt_executable)
     info->dli_fname = _dl_argv[0];
 
@@ -116,7 +117,7 @@ determine_info (const ElfW(Addr) addr, struct link_map *match, Dl_info *info,
 
 int
 _dl_addr (const void *address, Dl_info *info,
-	  struct link_map **mapp, const ElfW(Sym) **symbolp)
+	  struct link_map_private **mapp, const ElfW(Sym) **symbolp)
 {
   const ElfW(Addr) addr = DL_LOOKUP_ADDRESS (address);
   int result = 0;
@@ -124,7 +125,7 @@ _dl_addr (const void *address, Dl_info *info,
   /* Protect against concurrent loads and unloads.  */
   __rtld_lock_lock_recursive (GL(dl_load_lock));
 
-  struct link_map *l = _dl_find_dso_for_object (addr);
+  struct link_map_private *l = _dl_find_dso_for_object (addr);
 
   if (l)
     {
diff --git a/elf/dl-audit.c b/elf/dl-audit.c
index 81543f85fe..d7a55123ec 100644
--- a/elf/dl-audit.c
+++ b/elf/dl-audit.c
@@ -25,7 +25,7 @@
 #include <sys/param.h>
 
 void
-_dl_audit_activity_map (struct link_map *l, int action)
+_dl_audit_activity_map (struct link_map_private *l, int action)
 {
   struct audit_ifaces *afct = GLRO(dl_audit);
   for (unsigned int cnt = 0; cnt < GLRO(dl_naudit); ++cnt)
@@ -42,7 +42,7 @@ _dl_audit_activity_nsid (Lmid_t nsid, int action)
   /* If head is NULL, the namespace has become empty, and the audit interface
      does not give us a way to signal LA_ACT_CONSISTENT for it because the
      first loaded module is used to identify the namespace.  */
-  struct link_map *head = GL(dl_ns)[nsid]._ns_loaded;
+  struct link_map_private *head = GL(dl_ns)[nsid]._ns_loaded;
   if (__glibc_likely (GLRO(dl_naudit) == 0)
       || head == NULL || head->l_auditing)
     return;
@@ -51,7 +51,8 @@ _dl_audit_activity_nsid (Lmid_t nsid, int action)
 }
 
 const char *
-_dl_audit_objsearch (const char *name, struct link_map *l, unsigned int code)
+_dl_audit_objsearch (const char *name, struct link_map_private *l,
+		     unsigned int code)
 {
   if (l == NULL || l->l_auditing || code == 0)
     return name;
@@ -73,7 +74,7 @@ _dl_audit_objsearch (const char *name, struct link_map *l, unsigned int code)
 }
 
 void
-_dl_audit_objopen (struct link_map *l, Lmid_t nsid)
+_dl_audit_objopen (struct link_map_private *l, Lmid_t nsid)
 {
   if (__glibc_likely (GLRO(dl_naudit) == 0))
     return;
@@ -93,7 +94,7 @@ _dl_audit_objopen (struct link_map *l, Lmid_t nsid)
 }
 
 void
-_dl_audit_objclose (struct link_map *l)
+_dl_audit_objclose (struct link_map_private *l)
 {
   if (__glibc_likely (GLRO(dl_naudit) == 0)
       || GL(dl_ns)[l->l_ns]._ns_loaded->l_auditing)
@@ -114,7 +115,7 @@ _dl_audit_objclose (struct link_map *l)
 }
 
 void
-_dl_audit_preinit (struct link_map *l)
+_dl_audit_preinit (struct link_map_private *l)
 {
   if (__glibc_likely (GLRO(dl_naudit) == 0))
     return;
@@ -129,8 +130,8 @@ _dl_audit_preinit (struct link_map *l)
 }
 
 void
-_dl_audit_symbind_alt (struct link_map *l, const ElfW(Sym) *ref, void **value,
-		       lookup_t result)
+_dl_audit_symbind_alt (struct link_map_private *l, const ElfW(Sym) *ref,
+		       void **value, lookup_t result)
 {
   if ((l->l_audit_any_plt | result->l_audit_any_plt) == 0)
     return;
@@ -175,7 +176,8 @@ _dl_audit_symbind_alt (struct link_map *l, const ElfW(Sym) *ref, void **value,
 rtld_hidden_def (_dl_audit_symbind_alt)
 
 void
-_dl_audit_symbind (struct link_map *l, struct reloc_result *reloc_result,
+_dl_audit_symbind (struct link_map_private *l,
+		   struct reloc_result *reloc_result,
 		   const void *reloc, const ElfW(Sym) *defsym,
 		   DL_FIXUP_VALUE_TYPE *value, lookup_t result, bool lazy)
 {
@@ -263,7 +265,8 @@ _dl_audit_symbind (struct link_map *l, struct reloc_result *reloc_result,
 }
 
 void
-_dl_audit_pltenter (struct link_map *l, struct reloc_result *reloc_result,
+_dl_audit_pltenter (struct link_map_private *l,
+		    struct reloc_result *reloc_result,
 		    DL_FIXUP_VALUE_TYPE *value, void *regs, long int *framesize)
 {
   /* Don't do anything if no auditor wants to intercept this call.  */
@@ -339,7 +342,7 @@ _dl_audit_pltenter (struct link_map *l, struct reloc_result *reloc_result,
 
 void
 DL_ARCH_FIXUP_ATTRIBUTE
-_dl_audit_pltexit (struct link_map *l, ElfW(Word) reloc_arg,
+_dl_audit_pltexit (struct link_map_private *l, ElfW(Word) reloc_arg,
 		   const void *inregs, void *outregs)
 {
   const uintptr_t pltgot = (uintptr_t) D_PTR (l, l_info[DT_PLTGOT]);
diff --git a/elf/dl-call-libc-early-init.c b/elf/dl-call-libc-early-init.c
index 144a744212..c2df5b00c4 100644
--- a/elf/dl-call-libc-early-init.c
+++ b/elf/dl-call-libc-early-init.c
@@ -23,7 +23,7 @@
 #include <stddef.h>
 
 void
-_dl_call_libc_early_init (struct link_map *libc_map, _Bool initial)
+_dl_call_libc_early_init (struct link_map_private *libc_map, _Bool initial)
 {
   /* There is nothing to do if we did not actually load libc.so.  */
   if (libc_map == NULL)
diff --git a/elf/dl-call_fini.c b/elf/dl-call_fini.c
index 7376546ae0..a9d60e9803 100644
--- a/elf/dl-call_fini.c
+++ b/elf/dl-call_fini.c
@@ -22,11 +22,12 @@
 void
 _dl_call_fini (void *closure_map)
 {
-  struct link_map *map = closure_map;
+  struct link_map_private *map = closure_map;
 
   /* When debugging print a message first.  */
   if (__glibc_unlikely (GLRO(dl_debug_mask) & DL_DEBUG_IMPCALLS))
-    _dl_debug_printf ("\ncalling fini: %s [%lu]\n\n", map->l_name, map->l_ns);
+    _dl_debug_printf ("\ncalling fini: %s [%lu]\n\n",
+                      map->l_public.l_name, map->l_ns);
 
   /* Make sure nothing happens if we are called twice.  */
   map->l_init_called = 0;
@@ -34,7 +35,7 @@ _dl_call_fini (void *closure_map)
   ElfW(Dyn) *fini_array = map->l_info[DT_FINI_ARRAY];
   if (fini_array != NULL)
     {
-      ElfW(Addr) *array = (ElfW(Addr) *) (map->l_addr
+      ElfW(Addr) *array = (ElfW(Addr) *) (map->l_public.l_addr
                                           + fini_array->d_un.d_ptr);
       size_t sz = (map->l_info[DT_FINI_ARRAYSZ]->d_un.d_val
                    / sizeof (ElfW(Addr)));
@@ -46,5 +47,5 @@ _dl_call_fini (void *closure_map)
   /* Next try the old-style destructor.  */
   ElfW(Dyn) *fini = map->l_info[DT_FINI];
   if (fini != NULL)
-    DL_CALL_DT_FINI (map, ((void *) map->l_addr + fini->d_un.d_ptr));
+    DL_CALL_DT_FINI (map, ((void *) map->l_public.l_addr + fini->d_un.d_ptr));
 }
diff --git a/elf/dl-close.c b/elf/dl-close.c
index a97a1efa45..7222b21cf0 100644
--- a/elf/dl-close.c
+++ b/elf/dl-close.c
@@ -67,7 +67,7 @@ remove_slotinfo (size_t idx, struct dtv_slotinfo_list *listp, size_t disp,
     }
   else
     {
-      struct link_map *old_map = listp->slotinfo[idx - disp].map;
+      struct link_map_private *old_map = listp->slotinfo[idx - disp].map;
 
       /* The entry might still be in its unused state if we are closing an
 	 object that wasn't fully set up.  */
@@ -106,7 +106,7 @@ remove_slotinfo (size_t idx, struct dtv_slotinfo_list *listp, size_t disp,
 }
 
 void
-_dl_close_worker (struct link_map *map, bool force)
+_dl_close_worker (struct link_map_private *map, bool force)
 {
   /* One less direct use.  */
   --map->l_direct_opencount;
@@ -125,7 +125,7 @@ _dl_close_worker (struct link_map *map, bool force)
       /* There are still references to this object.  Do nothing more.  */
       if (__glibc_unlikely (GLRO(dl_debug_mask) & DL_DEBUG_FILES))
 	_dl_debug_printf ("\nclosing file=%s; direct_opencount=%u\n",
-			  map->l_name, map->l_direct_opencount);
+			  map->l_public.l_name, map->l_direct_opencount);
 
       return;
     }
@@ -138,12 +138,12 @@ _dl_close_worker (struct link_map *map, bool force)
 
   bool any_tls = false;
   const unsigned int nloaded = ns->_ns_nloaded;
-  struct link_map *maps[nloaded];
+  struct link_map_private *maps[nloaded];
 
   /* Run over the list and assign indexes to the link maps and enter
      them into the MAPS array.  */
   int idx = 0;
-  for (struct link_map *l = ns->_ns_loaded; l != NULL; l = l->l_next)
+  for (struct link_map_private *l = ns->_ns_loaded; l != NULL; l = l_next (l))
     {
       l->l_map_used = 0;
       l->l_map_done = 0;
@@ -167,7 +167,7 @@ _dl_close_worker (struct link_map *map, bool force)
   int done_index = -1;
   while (++done_index < nloaded)
     {
-      struct link_map *l = maps[done_index];
+      struct link_map_private *l = maps[done_index];
 
       if (l->l_map_done)
 	/* Already handled.  */
@@ -194,7 +194,7 @@ _dl_close_worker (struct link_map *map, bool force)
 	{
 	  /* We are always the zeroth entry, and since we don't include
 	     ourselves in the dependency analysis start at 1.  */
-	  struct link_map **lp = &l->l_initfini[1];
+	  struct link_map_private **lp = &l->l_initfini[1];
 	  while (*lp != NULL)
 	    {
 	      if ((*lp)->l_idx != IDX_STILL_USED)
@@ -220,7 +220,7 @@ _dl_close_worker (struct link_map *map, bool force)
       if (l->l_reldeps != NULL)
 	for (unsigned int j = 0; j < l->l_reldeps->act; ++j)
 	  {
-	    struct link_map *jmap = l->l_reldeps->list[j];
+	    struct link_map_private *jmap = l->l_reldeps->list[j];
 
 	    if (jmap->l_idx != IDX_STILL_USED)
 	      {
@@ -248,7 +248,7 @@ _dl_close_worker (struct link_map *map, bool force)
   unsigned int first_loaded = ~0;
   for (unsigned int i = 0; i < nloaded; ++i)
     {
-      struct link_map *imap = maps[i];
+      struct link_map_private *imap = maps[i];
 
       /* All elements must be in the same namespace.  */
       assert (imap->l_ns == nsid);
@@ -317,9 +317,9 @@ _dl_close_worker (struct link_map *map, bool force)
 	       l_searchlist address.  */
 	    if (imap->l_scope[cnt] != &imap->l_symbolic_searchlist)
 	      {
-		struct link_map *tmap = (struct link_map *)
+		struct link_map_private *tmap = (struct link_map_private *)
 		  ((char *) imap->l_scope[cnt]
-		   - offsetof (struct link_map, l_searchlist));
+		   - offsetof (struct link_map_private, l_searchlist));
 		assert (tmap->l_ns == nsid);
 		if (tmap->l_idx == IDX_STILL_USED)
 		  ++remain;
@@ -363,9 +363,11 @@ _dl_close_worker (struct link_map *map, bool force)
 		{
 		  if (imap->l_scope[cnt] != &imap->l_symbolic_searchlist)
 		    {
-		      struct link_map *tmap = (struct link_map *)
-			((char *) imap->l_scope[cnt]
-			 - offsetof (struct link_map, l_searchlist));
+		      struct link_map_private *tmap
+			= ((struct link_map_private *)
+			   ((char *) imap->l_scope[cnt]
+			    - offsetof (struct link_map_private,
+					l_searchlist)));
 		      if (tmap->l_idx != IDX_STILL_USED)
 			{
 			  /* Remove the scope.  Or replace with own map's
@@ -489,7 +491,7 @@ _dl_close_worker (struct link_map *map, bool force)
      it are gone.  */
   for (unsigned int i = first_loaded; i < nloaded; ++i)
     {
-      struct link_map *imap = maps[i];
+      struct link_map_private *imap = maps[i];
       if (!imap->l_map_used)
 	{
 	  assert (imap->l_type == lt_loaded);
@@ -635,12 +637,12 @@ _dl_close_worker (struct link_map *map, bool force)
 	     is tantamount to nsid >= DL_NNS).  That should be impossible
 	     in this configuration, so just assert about it instead.  */
 	  assert (nsid == LM_ID_BASE);
-	  assert (imap->l_prev != NULL);
+	  assert (imap->l_public.l_prev != NULL);
 #else
-	  if (imap->l_prev == NULL)
+	  if (imap->l_public.l_prev == NULL)
 	    {
 	      assert (nsid != LM_ID_BASE);
-	      ns->_ns_loaded = imap->l_next;
+	      ns->_ns_loaded = l_next (imap);
 
 	      /* Update the pointer to the head of the list
 		 we leave for debuggers to examine.  */
@@ -648,11 +650,11 @@ _dl_close_worker (struct link_map *map, bool force)
 	    }
 	  else
 #endif
-	    imap->l_prev->l_next = imap->l_next;
+	    imap->l_public.l_prev->l_next = imap->l_public.l_next;
 
 	  --ns->_ns_nloaded;
-	  if (imap->l_next != NULL)
-	    imap->l_next->l_prev = imap->l_prev;
+	  if (imap->l_public.l_next != NULL)
+	    imap->l_public.l_next->l_prev = imap->l_public.l_prev;
 
 	  /* Update the data used by _dl_find_object.  */
 	  _dl_find_object_dlclose (imap);
@@ -666,10 +668,10 @@ _dl_close_worker (struct link_map *map, bool force)
 	  /* Print debugging message.  */
 	  if (__glibc_unlikely (GLRO(dl_debug_mask) & DL_DEBUG_FILES))
 	    _dl_debug_printf ("\nfile=%s [%lu];  destroying link map\n",
-			      imap->l_name, imap->l_ns);
+			      imap->l_public.l_name, imap->l_ns);
 
 	  /* This name always is allocated.  */
-	  free (imap->l_name);
+	  free (imap->l_public.l_name);
 	  /* Remove the list with all the names of the shared object.  */
 
 	  struct libname_list *lnp = imap->l_libname;
@@ -756,7 +758,7 @@ _dl_close_worker (struct link_map *map, bool force)
 void
 _dl_close (void *_map)
 {
-  struct link_map *map = _map;
+  struct link_map_private *map = _map;
 
   /* We must take the lock to examine the contents of map and avoid
      concurrent dlopens.  */
@@ -787,7 +789,8 @@ _dl_close (void *_map)
   if (__builtin_expect (map->l_direct_opencount, 1) == 0)
     {
       __rtld_lock_unlock_recursive (GL(dl_load_lock));
-      _dl_signal_error (0, map->l_name, NULL, N_("shared object not open"));
+      _dl_signal_error (0, map->l_public.l_name, NULL,
+			N_("shared object not open"));
     }
 
   _dl_close_worker (map, false);
diff --git a/elf/dl-debug.c b/elf/dl-debug.c
index bd7b1cc8f7..6c097e6920 100644
--- a/elf/dl-debug.c
+++ b/elf/dl-debug.c
@@ -18,18 +18,6 @@
 
 #include <ldsodefs.h>
 
-
-/* These are the members in the public `struct link_map' type.
-   Sanity check that the internal type and the public type match.  */
-#define VERIFY_MEMBER(name) \
-  (offsetof (struct link_map_public, name) == offsetof (struct link_map, name))
-extern const int verify_link_map_members[(VERIFY_MEMBER (l_addr)
-					  && VERIFY_MEMBER (l_name)
-					  && VERIFY_MEMBER (l_ld)
-					  && VERIFY_MEMBER (l_next)
-					  && VERIFY_MEMBER (l_prev))
-					 ? 1 : -1];
-
 /* Update the `r_map' member and return the address of `struct r_debug'
    of the namespace NS. */
 
diff --git a/elf/dl-deps.c b/elf/dl-deps.c
index 110c8953bd..c730713167 100644
--- a/elf/dl-deps.c
+++ b/elf/dl-deps.c
@@ -45,14 +45,14 @@
 struct openaux_args
   {
     /* The arguments to openaux.  */
-    struct link_map *map;
+    struct link_map_private *map;
     int trace_mode;
     int open_mode;
     const char *strtab;
     const char *name;
 
     /* The return value of openaux.  */
-    struct link_map *aux;
+    struct link_map_private *aux;
   };
 
 static void
@@ -74,7 +74,7 @@ openaux (void *a)
 struct list
   {
     int done;			/* Nonzero if this map was processed.  */
-    struct link_map *map;	/* The data.  */
+    struct link_map_private *map; /* The data.  */
     struct list *next;		/* Elements for normal list.  */
   };
 
@@ -109,7 +109,7 @@ cannot load auxiliary `%s' because of empty dynamic string token "	\
   })									\
 
 static void
-preload (struct list *known, unsigned int *nlist, struct link_map *map)
+preload (struct list *known, unsigned int *nlist, struct link_map_private *map)
 {
   known[*nlist].done = 0;
   known[*nlist].map = map;
@@ -123,9 +123,9 @@ preload (struct list *known, unsigned int *nlist, struct link_map *map)
 }
 
 void
-_dl_map_object_deps (struct link_map *map,
-		     struct link_map **preloads, unsigned int npreloads,
-		     int trace_mode, int open_mode)
+_dl_map_object_deps (struct link_map_private *map,
+		     struct link_map_private **preloads,
+		     unsigned int npreloads, int trace_mode, int open_mode)
 {
   struct list *known = __alloca (sizeof *known * (1 + npreloads + 1));
   struct list *runp, *tail;
@@ -171,8 +171,8 @@ _dl_map_object_deps (struct link_map *map,
   name = NULL;
   for (runp = known; runp; )
     {
-      struct link_map *l = runp->map;
-      struct link_map **needed = NULL;
+      struct link_map_private *l = runp->map;
+      struct link_map_private **needed = NULL;
       unsigned int nneeded = 0;
 
       /* Unless otherwise stated, this object is handled.  */
@@ -185,8 +185,8 @@ _dl_map_object_deps (struct link_map *map,
 	{
 	  /* l->l_ldnum includes space for the terminating NULL.  */
 	  if (!scratch_buffer_set_array_size
-	      (&needed_space, l->l_ldnum, sizeof (struct link_map *)))
-	    _dl_signal_error (ENOMEM, map->l_name, NULL,
+	      (&needed_space, l->l_ldnum, sizeof (struct link_map_private *)))
+	    _dl_signal_error (ENOMEM, map->l_public.l_name, NULL,
 			      N_("cannot allocate dependency buffer"));
 	  needed = needed_space.data;
 	}
@@ -204,11 +204,11 @@ _dl_map_object_deps (struct link_map *map,
 	  args.open_mode = open_mode;
 	  orig = runp;
 
-	  for (d = l->l_ld; d->d_tag != DT_NULL; ++d)
+	  for (d = l->l_public.l_ld; d->d_tag != DT_NULL; ++d)
 	    if (__builtin_expect (d->d_tag, DT_NEEDED) == DT_NEEDED)
 	      {
 		/* Map in the needed object.  */
-		struct link_map *dep;
+		struct link_map_private *dep;
 
 		/* Recognize DSTs.  */
 		name = expand_dst (l, strtab + d->d_un.d_val, 0);
@@ -265,7 +265,7 @@ _dl_map_object_deps (struct link_map *map,
 		  _dl_debug_printf ("load auxiliary object=%s"
 				    " requested by file=%s\n",
 				    name,
-				    DSO_FILENAME (l->l_name));
+				    DSO_FILENAME (l->l_public.l_name));
 
 		/* We must be prepared that the addressed shared
 		   object is not available.  For filter objects the dependency
@@ -347,16 +347,19 @@ _dl_map_object_deps (struct link_map *map,
 			late->next = late->next->next;
 
 			/* We must move the object earlier in the chain.  */
-			if (args.aux->l_prev != NULL)
-			  args.aux->l_prev->l_next = args.aux->l_next;
-			if (args.aux->l_next != NULL)
-			  args.aux->l_next->l_prev = args.aux->l_prev;
-
-			args.aux->l_prev = newp->map->l_prev;
-			newp->map->l_prev = args.aux;
-			if (args.aux->l_prev != NULL)
-			  args.aux->l_prev->l_next = args.aux;
-			args.aux->l_next = newp->map;
+			if (args.aux->l_public.l_prev != NULL)
+			  args.aux->l_public.l_prev->l_next
+			    = args.aux->l_public.l_next;
+			if (args.aux->l_public.l_next != NULL)
+			  args.aux->l_public.l_next->l_prev
+			    = args.aux->l_public.l_prev;
+
+			args.aux->l_public.l_prev = newp->map->l_public.l_prev;
+			newp->map->l_public.l_prev = &args.aux->l_public;
+			if (args.aux->l_public.l_prev != NULL)
+			  args.aux->l_public.l_prev->l_next
+			    = &args.aux->l_public;
+			args.aux->l_public.l_next = &newp->map->l_public;
 		      }
 		    else
 		      {
@@ -378,16 +381,18 @@ _dl_map_object_deps (struct link_map *map,
 		    /* The only problem is that in the double linked
 		       list of all objects we don't have this new
 		       object at the correct place.  Correct this here.  */
-		    if (args.aux->l_prev)
-		      args.aux->l_prev->l_next = args.aux->l_next;
-		    if (args.aux->l_next)
-		      args.aux->l_next->l_prev = args.aux->l_prev;
-
-		    args.aux->l_prev = newp->map->l_prev;
-		    newp->map->l_prev = args.aux;
-		    if (args.aux->l_prev != NULL)
-		      args.aux->l_prev->l_next = args.aux;
-		    args.aux->l_next = newp->map;
+		    if (args.aux->l_public.l_prev)
+		      args.aux->l_public.l_prev->l_next
+			= args.aux->l_public.l_next;
+		    if (args.aux->l_public.l_next)
+		      args.aux->l_public.l_next->l_prev
+			= args.aux->l_public.l_prev;
+
+		    args.aux->l_public.l_prev = newp->map->l_public.l_prev;
+		    newp->map->l_public.l_prev = &args.aux->l_public;
+		    if (args.aux->l_public.l_prev != NULL)
+		      args.aux->l_public.l_prev->l_next = &args.aux->l_public;
+		    args.aux->l_public.l_next = &newp->map->l_public;
 		  }
 
 		/* Move the tail pointer if necessary.  */
@@ -404,12 +409,12 @@ _dl_map_object_deps (struct link_map *map,
 	{
 	  needed[nneeded++] = NULL;
 
-	  struct link_map **l_initfini = (struct link_map **)
+	  struct link_map_private **l_initfini = (struct link_map_private **)
 	    malloc ((2 * nneeded + 1) * sizeof needed[0]);
 	  if (l_initfini == NULL)
 	    {
 	      scratch_buffer_free (&needed_space);
-	      _dl_signal_error (ENOMEM, map->l_name, NULL,
+	      _dl_signal_error (ENOMEM, map->l_public.l_name, NULL,
 				N_("cannot allocate dependency list"));
 	    }
 	  l_initfini[0] = l;
@@ -434,7 +439,7 @@ _dl_map_object_deps (struct link_map *map,
   if (errno == 0 && errno_saved != 0)
     __set_errno (errno_saved);
 
-  struct link_map **old_l_initfini = NULL;
+  struct link_map_private **old_l_initfini = NULL;
   if (map->l_initfini != NULL && map->l_type == lt_loaded)
     {
       /* This object was previously loaded as a dependency and we have
@@ -445,11 +450,11 @@ _dl_map_object_deps (struct link_map *map,
 
   /* Store the search list we built in the object.  It will be used for
      searches in the scope of this object.  */
-  struct link_map **l_initfini =
-    (struct link_map **) malloc ((2 * nlist + 1)
-				 * sizeof (struct link_map *));
+  struct link_map_private **l_initfini =
+    (struct link_map_private **) malloc ((2 * nlist + 1)
+				 * sizeof (struct link_map_private *));
   if (l_initfini == NULL)
-    _dl_signal_error (ENOMEM, map->l_name, NULL,
+    _dl_signal_error (ENOMEM, map->l_public.l_name, NULL,
 		      N_("cannot allocate symbol search list"));
 
 
@@ -485,14 +490,14 @@ _dl_map_object_deps (struct link_map *map,
 
       /* Avoid removing relocation dependencies of the main binary.  */
       map->l_reserved = 0;
-      struct link_map **list = &map->l_reldeps->list[0];
+      struct link_map_private **list = &map->l_reldeps->list[0];
       for (i = 0; i < map->l_reldeps->act; ++i)
 	if (list[i]->l_reserved)
 	  {
 	    /* Need to allocate new array of relocation dependencies.  */
 	    l_reldeps = malloc (sizeof (*l_reldeps)
 				+ map->l_reldepsmax
-				  * sizeof (struct link_map *));
+				  * sizeof (struct link_map_private *));
 	    if (l_reldeps == NULL)
 	      /* Bad luck, keep the reldeps duplicated between
 		 map->l_reldeps->list and map->l_initfini lists.  */
@@ -501,7 +506,7 @@ _dl_map_object_deps (struct link_map *map,
 	      {
 		unsigned int j = i;
 		memcpy (&l_reldeps->list[0], &list[0],
-			i * sizeof (struct link_map *));
+			i * sizeof (struct link_map_private *));
 		for (i = i + 1; i < map->l_reldeps->act; ++i)
 		  if (!list[i]->l_reserved)
 		    l_reldeps->list[j++] = list[i];
@@ -531,7 +536,7 @@ _dl_map_object_deps (struct link_map *map,
     }
   else
     memcpy (l_initfini, map->l_searchlist.r_list,
-	    nlist * sizeof (struct link_map *));
+	    nlist * sizeof (struct link_map_private *));
 
   /* If libc.so.6 is the main map, it participates in the sort, so
      that the relocation order is correct regarding libc.so.6.  */
diff --git a/elf/dl-find_object.c b/elf/dl-find_object.c
index c1390ee10f..5042b0a8c1 100644
--- a/elf/dl-find_object.c
+++ b/elf/dl-find_object.c
@@ -37,8 +37,8 @@ _dl_find_object_slow (void *pc, struct dl_find_object *result)
 {
   ElfW(Addr) addr = (ElfW(Addr)) pc;
   for (Lmid_t ns = 0; ns < GL(dl_nns); ++ns)
-    for (struct link_map *l = GL(dl_ns)[ns]._ns_loaded; l != NULL;
-         l = l->l_next)
+    for (struct link_map_private *l = GL(dl_ns)[ns]._ns_loaded; l != NULL;
+         l = l_next (l))
       if (addr >= l->l_map_start && addr < l->l_map_end
           && (l->l_contiguous || _dl_addr_inside_object (l, addr)))
         {
@@ -168,7 +168,7 @@ _dlfo_mappings_segment_allocate_unpadded (size_t size)
   if (size < dlfo_mappings_initial_segment_size)
     size = dlfo_mappings_initial_segment_size;
   /* No overflow checks here because the size is a mapping count, and
-     struct link_map is larger than what we allocate here.  */
+     struct link_map_private is larger than what we allocate here.  */
   enum
     {
       element_size = sizeof ((struct dlfo_mappings_segment) {}.objects[0])
@@ -206,7 +206,7 @@ _dlfo_mappings_segment_allocate (size_t size,
   }
   enum { cache_line_size_estimate = 128 };
   /* No overflow checks here because the size is a mapping count, and
-     struct link_map is larger than what we allocate here.  */
+     struct link_map_private is larger than what we allocate here.  */
   enum
     {
       element_size = sizeof ((struct dlfo_mappings_segment) {}.objects[0])
@@ -472,7 +472,7 @@ rtld_hidden_def (_dl_find_object)
 static size_t
 _dlfo_process_initial (void)
 {
-  struct link_map *main_map = GL(dl_ns)[LM_ID_BASE]._ns_loaded;
+  struct link_map_private *main_map = GL(dl_ns)[LM_ID_BASE]._ns_loaded;
 
   size_t nodelete = 0;
   if (!main_map->l_contiguous)
@@ -492,7 +492,7 @@ _dlfo_process_initial (void)
                 /* Second pass only.  */
                 _dlfo_nodelete_mappings[nodelete] = dlfo;
                 _dlfo_nodelete_mappings[nodelete].map_start
-                  = ph->p_vaddr + main_map->l_addr;
+                  = ph->p_vaddr + main_map->l_public.l_addr;
                 _dlfo_nodelete_mappings[nodelete].map_end
                   = _dlfo_nodelete_mappings[nodelete].map_start + ph->p_memsz;
               }
@@ -502,8 +502,8 @@ _dlfo_process_initial (void)
 
   size_t loaded = 0;
   for (Lmid_t ns = 0; ns < GL(dl_nns); ++ns)
-    for (struct link_map *l = GL(dl_ns)[ns]._ns_loaded; l != NULL;
-         l = l->l_next)
+    for (struct link_map_private *l = GL(dl_ns)[ns]._ns_loaded; l != NULL;
+         l = l_next (l))
       /* Skip the main map processed above, and proxy maps.  */
       if (l != main_map && l == l->l_real)
         {
@@ -561,7 +561,7 @@ _dl_find_object_init (void)
 {
   /* Cover the main mapping.  */
   {
-    struct link_map *main_map = GL(dl_ns)[LM_ID_BASE]._ns_loaded;
+    struct link_map_private *main_map = GL(dl_ns)[LM_ID_BASE]._ns_loaded;
 
     if (main_map->l_contiguous)
       _dl_find_object_from_map (main_map, &_dlfo_main);
@@ -604,7 +604,7 @@ Fatal glibc error: cannot allocate memory for find-object data\n");
 }
 
 static void
-_dl_find_object_link_map_sort (struct link_map **loaded, size_t size)
+_dl_find_object_link_map_sort (struct link_map_private **loaded, size_t size)
 {
   /* Selection sort based on map_start.  */
   if (size < 2)
@@ -622,7 +622,7 @@ _dl_find_object_link_map_sort (struct link_map **loaded, size_t size)
           }
 
       /* Swap into place.  */
-      struct link_map *tmp = loaded[min_idx];
+      struct link_map_private *tmp = loaded[min_idx];
       loaded[min_idx] = loaded[i];
       loaded[i] = tmp;
     }
@@ -649,7 +649,7 @@ _dlfo_update_init_seg (struct dlfo_mappings_segment *seg,
    shared data need to use relaxed MO.  But plain loads can be used
    because the loader lock prevents concurrent stores.  */
 static bool
-_dl_find_object_update_1 (struct link_map **loaded, size_t count)
+_dl_find_object_update_1 (struct link_map_private **loaded, size_t count)
 {
   int active_idx = _dlfo_read_version_locked () & 1;
 
@@ -781,22 +781,22 @@ _dl_find_object_update_1 (struct link_map **loaded, size_t count)
 }
 
 bool
-_dl_find_object_update (struct link_map *new_map)
+_dl_find_object_update (struct link_map_private *new_map)
 {
   /* Copy the newly-loaded link maps into an array for sorting.  */
   size_t count = 0;
-  for (struct link_map *l = new_map; l != NULL; l = l->l_next)
+  for (struct link_map_private *l = new_map; l != NULL; l = l_next (l))
     /* Skip proxy maps and already-processed maps.  */
     count += l == l->l_real && !l->l_find_object_processed;
   if (count == 0)
     return true;
 
-  struct link_map **map_array = malloc (count * sizeof (*map_array));
+  struct link_map_private **map_array = malloc (count * sizeof (*map_array));
   if (map_array == NULL)
     return false;
   {
     size_t i = 0;
-    for (struct link_map *l = new_map; l != NULL; l = l->l_next)
+    for (struct link_map_private *l = new_map; l != NULL; l = l_next (l))
       if (l == l->l_real && !l->l_find_object_processed)
         map_array[i++] = l;
   }
@@ -808,7 +808,7 @@ _dl_find_object_update (struct link_map *new_map)
 }
 
 void
-_dl_find_object_dlclose (struct link_map *map)
+_dl_find_object_dlclose (struct link_map_private *map)
 {
   uint64_t start_version = _dlfo_read_version_locked ();
   uintptr_t map_start = map->l_map_start;
diff --git a/elf/dl-find_object.h b/elf/dl-find_object.h
index 87c9460619..edcc0a7755 100644
--- a/elf/dl-find_object.h
+++ b/elf/dl-find_object.h
@@ -28,14 +28,14 @@
 
 /* Internal version of struct dl_find_object.  Does not include the
    (yet unused) flags member.  We need to make a copy of data also in
-   struct link_map to support non-contiguous mappings, and to support
-   software transactional memory (the link map is not covered by
-   transactions).  */
+   struct link_map_private to support non-contiguous mappings, and to
+   support software transactional memory (the link map is not covered
+   by transactions).  */
 struct dl_find_object_internal
 {
   uintptr_t map_start;
   uintptr_t map_end;            /* Set to map_start by dlclose.  */
-  struct link_map *map;         /* Set to NULL by dlclose.  */
+  struct link_map_private *map;         /* Set to NULL by dlclose.  */
   void *eh_frame;
 #if DLFO_STRUCT_HAS_EH_DBASE
   void *eh_dbase;
@@ -76,7 +76,7 @@ _dl_find_object_to_external (struct dl_find_object_internal *internal,
   external->dlfo_flags = 0;
   external->dlfo_map_start = (void *) internal->map_start;
   external->dlfo_map_end = (void *) internal->map_end;
-  external->dlfo_link_map = internal->map;
+  external->dlfo_link_map = &internal->map->l_public;
   external->dlfo_eh_frame = internal->eh_frame;
 # if DLFO_STRUCT_HAS_EH_DBASE
   external->dlfo_eh_dbase = internal->eh_dbase;
@@ -89,7 +89,7 @@ _dl_find_object_to_external (struct dl_find_object_internal *internal,
 /* Extract the object location data from a link map and writes it to
    *RESULT using relaxed MO stores.  */
 static void __attribute__ ((unused))
-_dl_find_object_from_map (struct link_map *l,
+_dl_find_object_from_map (struct link_map_private *l,
                           struct dl_find_object_internal *result)
 {
   atomic_store_relaxed (&result->map_start, (uintptr_t) l->l_map_start);
@@ -105,7 +105,7 @@ _dl_find_object_from_map (struct link_map *l,
     if (ph->p_type == DLFO_EH_SEGMENT_TYPE)
       {
         atomic_store_relaxed (&result->eh_frame,
-                              (void *) (ph->p_vaddr + l->l_addr));
+                              (void *) (ph->p_vaddr + l->l_public.l_addr));
 #if DLFO_STRUCT_HAS_EH_COUNT
         atomic_store_relaxed (&result->eh_count, ph->p_memsz / 8);
 #endif
@@ -129,11 +129,11 @@ void _dl_find_object_init (void) attribute_hidden;
    the l_next list are added if l_object_processed is 0.  Needs to
    be protected by loader write lock.  Returns true on success, false
    on malloc failure.  */
-bool _dl_find_object_update (struct link_map *new_map) attribute_hidden;
+bool _dl_find_object_update (struct link_map_private *new_l) attribute_hidden;
 
 /* Called by dlclose to remove the link map from the DWARF EH frame
    data structures.  Needs to be protected by loader write lock.  */
-void _dl_find_object_dlclose (struct link_map *l) attribute_hidden;
+void _dl_find_object_dlclose (struct link_map_private *l) attribute_hidden;
 
 /* Called from __libc_freeres to deallocate malloc'ed memory.  */
 void _dl_find_object_freeres (void) attribute_hidden;
diff --git a/elf/dl-fini.c b/elf/dl-fini.c
index 9acb64f47c..2e10f1b0b6 100644
--- a/elf/dl-fini.c
+++ b/elf/dl-fini.c
@@ -65,12 +65,12 @@ _dl_fini (void)
 
 	  /* Now we can allocate an array to hold all the pointers and
 	     copy the pointers in.  */
-	  struct link_map *maps[nloaded];
+	  struct link_map_private *maps[nloaded];
 
 	  unsigned int i;
-	  struct link_map *l;
+	  struct link_map_private *l;
 	  assert (nloaded != 0 || GL(dl_ns)[ns]._ns_loaded == NULL);
-	  for (l = GL(dl_ns)[ns]._ns_loaded, i = 0; l != NULL; l = l->l_next)
+	  for (l = GL(dl_ns)[ns]._ns_loaded, i = 0; l != NULL; l = l_next (l))
 	    /* Do not handle ld.so in secondary namespaces.  */
 	    if (l == l->l_real)
 	      {
@@ -107,7 +107,7 @@ _dl_fini (void)
 	     the front.  */
 	  for (i = 0; i < nmaps; ++i)
 	    {
-	      struct link_map *l = maps[i];
+	      struct link_map_private *l = maps[i];
 
 	      if (l->l_init_called)
 		{
diff --git a/elf/dl-fptr.c b/elf/dl-fptr.c
index 536ad17089..afa626daf7 100644
--- a/elf/dl-fptr.c
+++ b/elf/dl-fptr.c
@@ -164,7 +164,7 @@ make_fdesc (ElfW(Addr) ip, ElfW(Addr) gp)
 
 
 static inline ElfW(Addr) * __attribute__ ((always_inline))
-make_fptr_table (struct link_map *map)
+make_fptr_table (struct link_map_private *map)
 {
   const ElfW(Sym) *symtab
     = (const void *) D_PTR (map, l_info[DT_SYMTAB]);
@@ -202,7 +202,7 @@ make_fptr_table (struct link_map *map)
 
 
 ElfW(Addr)
-_dl_make_fptr (struct link_map *map, const ElfW(Sym) *sym,
+_dl_make_fptr (struct link_map_private *map, const ElfW(Sym) *sym,
 	       ElfW(Addr) ip)
 {
   ElfW(Addr) *ftab = map->l_mach.fptr_table;
@@ -264,7 +264,7 @@ _dl_make_fptr (struct link_map *map, const ElfW(Sym) *sym,
 
 
 void
-_dl_unmap (struct link_map *map)
+_dl_unmap (struct link_map_private *map)
 {
   ElfW(Addr) *ftab = map->l_mach.fptr_table;
   struct fdesc *head = NULL, *tail = NULL;
diff --git a/elf/dl-init.c b/elf/dl-init.c
index ba4d2fdc85..b220ca9239 100644
--- a/elf/dl-init.c
+++ b/elf/dl-init.c
@@ -23,7 +23,7 @@
 
 
 static void
-call_init (struct link_map *l, int argc, char **argv, char **env)
+call_init (struct link_map_private *l, int argc, char **argv, char **env)
 {
   /* Do not run constructors for proxy objects.  */
   if (l != l->l_real)
@@ -43,21 +43,22 @@ call_init (struct link_map *l, int argc, char **argv, char **env)
   l->l_init_called = 1;
 
   /* Check for object which constructors we do not run here.  */
-  if (__builtin_expect (l->l_name[0], 'a') == '\0'
+  if (__builtin_expect (l->l_public.l_name[0], 'a') == '\0'
       && l->l_type == lt_executable)
     return;
 
   /* Print a debug message if wanted.  */
   if (__glibc_unlikely (GLRO(dl_debug_mask) & DL_DEBUG_IMPCALLS))
     _dl_debug_printf ("\ncalling init: %s\n\n",
-		      DSO_FILENAME (l->l_name));
+		      DSO_FILENAME (l->l_public.l_name));
 
   /* Now run the local constructors.  There are two forms of them:
      - the one named by DT_INIT
      - the others in the DT_INIT_ARRAY.
   */
   if (ELF_INITFINI && l->l_info[DT_INIT] != NULL)
-    DL_CALL_DT_INIT(l, l->l_addr + l->l_info[DT_INIT]->d_un.d_ptr, argc, argv, env);
+    DL_CALL_DT_INIT(l, l->l_public.l_addr + l->l_info[DT_INIT]->d_un.d_ptr,
+		    argc, argv, env);
 
   /* Next see whether there is an array with initialization functions.  */
   ElfW(Dyn) *init_array = l->l_info[DT_INIT_ARRAY];
@@ -69,7 +70,7 @@ call_init (struct link_map *l, int argc, char **argv, char **env)
 
       jm = l->l_info[DT_INIT_ARRAYSZ]->d_un.d_val / sizeof (ElfW(Addr));
 
-      addrs = (ElfW(Addr) *) (init_array->d_un.d_ptr + l->l_addr);
+      addrs = (ElfW(Addr) *) (init_array->d_un.d_ptr + l->l_public.l_addr);
       for (j = 0; j < jm; ++j)
 	((dl_init_t) addrs[j]) (argc, argv, env);
     }
@@ -77,7 +78,7 @@ call_init (struct link_map *l, int argc, char **argv, char **env)
 
 
 void
-_dl_init (struct link_map *main_map, int argc, char **argv, char **env)
+_dl_init (struct link_map_private *main_map, int argc, char **argv, char **env)
 {
   ElfW(Dyn) *preinit_array = main_map->l_info[DT_PREINIT_ARRAY];
   ElfW(Dyn) *preinit_array_size = main_map->l_info[DT_PREINIT_ARRAYSZ];
@@ -99,9 +100,10 @@ _dl_init (struct link_map *main_map, int argc, char **argv, char **env)
 
       if (__glibc_unlikely (GLRO(dl_debug_mask) & DL_DEBUG_IMPCALLS))
 	_dl_debug_printf ("\ncalling preinit: %s\n\n",
-			  DSO_FILENAME (main_map->l_name));
+			  DSO_FILENAME (main_map->l_public.l_name));
 
-      addrs = (ElfW(Addr) *) (preinit_array->d_un.d_ptr + main_map->l_addr);
+      addrs = (ElfW(Addr) *) (preinit_array->d_un.d_ptr
+			      + main_map->l_public.l_addr);
       for (cnt = 0; cnt < i; ++cnt)
 	((dl_init_t) addrs[cnt]) (argc, argv, env);
     }
diff --git a/elf/dl-iteratephdr.c b/elf/dl-iteratephdr.c
index 2acccc4f83..943f3a74a5 100644
--- a/elf/dl-iteratephdr.c
+++ b/elf/dl-iteratephdr.c
@@ -31,7 +31,7 @@ int
 __dl_iterate_phdr (int (*callback) (struct dl_phdr_info *info,
 				    size_t size, void *data), void *data)
 {
-  struct link_map *l;
+  struct link_map_private *l;
   struct dl_phdr_info info;
   int ret = 0;
 
@@ -46,7 +46,8 @@ __dl_iterate_phdr (int (*callback) (struct dl_phdr_info *info,
 #ifdef SHARED
   const void *caller = RETURN_ADDRESS (0);
   for (Lmid_t cnt = GL(dl_nns) - 1; cnt > 0; --cnt)
-    for (struct link_map *l = GL(dl_ns)[cnt]._ns_loaded; l; l = l->l_next)
+    for (struct link_map_private *l = GL(dl_ns)[cnt]._ns_loaded; l;
+	 l = l_next (l))
       {
 	/* We have to count the total number of loaded objects.  */
 	nloaded += GL(dl_ns)[cnt]._ns_nloaded;
@@ -59,10 +60,10 @@ __dl_iterate_phdr (int (*callback) (struct dl_phdr_info *info,
       }
 #endif
 
-  for (l = GL(dl_ns)[ns]._ns_loaded; l != NULL; l = l->l_next)
+  for (l = GL(dl_ns)[ns]._ns_loaded; l != NULL; l = l_next (l))
     {
-      info.dlpi_addr = l->l_real->l_addr;
-      info.dlpi_name = l->l_real->l_name;
+      info.dlpi_addr = l->l_real->l_public.l_addr;
+      info.dlpi_name = l->l_real->l_public.l_name;
       info.dlpi_phdr = l->l_real->l_phdr;
       info.dlpi_phnum = l->l_real->l_phnum;
       info.dlpi_adds = GL(dl_load_adds);
diff --git a/elf/dl-libc.c b/elf/dl-libc.c
index 1d0ebd4793..679d95c4ec 100644
--- a/elf/dl-libc.c
+++ b/elf/dl-libc.c
@@ -64,13 +64,13 @@ struct do_dlopen_args
   const void *caller_dlopen;
 
   /* Return from do_dlopen.  */
-  struct link_map *map;
+  struct link_map_private *map;
 };
 
 struct do_dlsym_args
 {
   /* Arguments to do_dlsym.  */
-  struct link_map *map;
+  struct link_map_private *map;
   const char *name;
 
   /* Return values of do_dlsym.  */
@@ -122,7 +122,7 @@ do_dlvsym (void *ptr)
 static void
 do_dlclose (void *ptr)
 {
-  GLRO(dl_close) ((struct link_map *) ptr);
+  GLRO(dl_close) ((struct link_map_private *) ptr);
 }
 
 #ifndef SHARED
@@ -164,7 +164,7 @@ __libc_dlopen_mode (const char *name, int mode)
 
 #ifndef SHARED
 void *
-__libc_dlsym_private (struct link_map *map, const char *name)
+__libc_dlsym_private (struct link_map_private *map, const char *name)
 {
   struct do_dlsym_args sargs;
   sargs.map = map;
diff --git a/elf/dl-libc_freeres.c b/elf/dl-libc_freeres.c
index d60c18d359..65fc70837a 100644
--- a/elf/dl-libc_freeres.c
+++ b/elf/dl-libc_freeres.c
@@ -49,7 +49,7 @@ free_slotinfo (struct dtv_slotinfo_list **elemp)
 void
 __rtld_libc_freeres (void)
 {
-  struct link_map *l;
+  struct link_map_private *l;
   struct r_search_path_elem *d;
 
   /* Remove all search directories.  */
@@ -63,7 +63,7 @@ __rtld_libc_freeres (void)
 
   for (Lmid_t ns = 0; ns < GL(dl_nns); ++ns)
     {
-      for (l = GL(dl_ns)[ns]._ns_loaded; l != NULL; l = l->l_next)
+      for (l = GL(dl_ns)[ns]._ns_loaded; l != NULL; l = l_next (l))
 	{
 	  struct libname_list *lnp = l->l_libname->next;
 
@@ -91,7 +91,8 @@ __rtld_libc_freeres (void)
 	{
 	  /* All object dynamically loaded by the program are unloaded.  Free
 	     the memory allocated for the global scope variable.  */
-	  struct link_map **old = GL(dl_ns)[ns]._ns_main_searchlist->r_list;
+	  struct link_map_private **old
+            = GL(dl_ns)[ns]._ns_main_searchlist->r_list;
 
 	  /* Put the old map in.  */
 	  GL(dl_ns)[ns]._ns_main_searchlist->r_list
diff --git a/elf/dl-load.c b/elf/dl-load.c
index 2faaa44eaf..5c9aaf2eec 100644
--- a/elf/dl-load.c
+++ b/elf/dl-load.c
@@ -244,7 +244,7 @@ is_dst (const char *input, const char *ref)
    DT_AUXILIARY, and DT_FILTER entries to have colons, but we treat
    those as literal colons here, not as path list delimiters.  */
 size_t
-_dl_dst_substitute (struct link_map *l, const char *input,
+_dl_dst_substitute (struct link_map_private *l, const char *input,
 		    struct alloc_buffer *result)
 {
   /* Copy character-by-character from input into the working pointer
@@ -294,7 +294,7 @@ _dl_dst_substitute (struct link_map *l, const char *input,
 		    {
 		      /* For loaded DSOs, the l_origin field is set in
 			 _dl_new_object.  */
-		      assert (l->l_name[0] == '\0');
+		      assert (l->l_public.l_name[0] == '\0');
 		      l->l_origin = _dl_get_origin ();
 		    }
 		  repl = l->l_origin;
@@ -370,7 +370,7 @@ _dl_dst_substitute (struct link_map *l, const char *input,
    case the path containing the DST is left out.  On error NULL
    is returned.  */
 static char *
-expand_dynamic_string_token (struct link_map *l, const char *input)
+expand_dynamic_string_token (struct link_map_private *l, const char *input)
 {
   struct alloc_buffer buf = {};
   size_t size = _dl_dst_substitute (l, input, &buf);
@@ -392,7 +392,7 @@ expand_dynamic_string_token (struct link_map *l, const char *input)
    be freed if the shared object already has this name.
    Returns false if the object already had this name.  */
 static void
-add_name_to_object (struct link_map *l, const char *name)
+add_name_to_object (struct link_map_private *l, const char *name)
 {
   struct libname_list *lnp, *lastp;
   struct libname_list *newname;
@@ -427,7 +427,7 @@ static size_t max_dirnamelen;
 
 static struct r_search_path_elem **
 fillin_rpath (char *rpath, struct r_search_path_elem **result, const char *sep,
-	      const char *what, const char *where, struct link_map *l)
+	      const char *what, const char *where, struct link_map_private *l)
 {
   char *cp;
   size_t nelems = 0;
@@ -537,10 +537,11 @@ fillin_rpath (char *rpath, struct r_search_path_elem **result, const char *sep,
 
 static bool
 decompose_rpath (struct r_search_path_struct *sps,
-		 const char *rpath, struct link_map *l, const char *what)
+		 const char *rpath, struct link_map_private *l,
+		 const char *what)
 {
   /* Make a copy we can work with.  */
-  const char *where = l->l_name;
+  const char *where = l->l_public.l_name;
   char *cp;
   struct r_search_path_elem **result;
   size_t nelems;
@@ -635,7 +636,7 @@ decompose_rpath (struct r_search_path_struct *sps,
 /* Make sure cached path information is stored in *SP
    and return true if there are any paths to search there.  */
 static bool
-cache_rpath (struct link_map *l,
+cache_rpath (struct link_map_private *l,
 	     struct r_search_path_struct *sp,
 	     int tag,
 	     const char *what)
@@ -669,7 +670,7 @@ _dl_init_paths (const char *llp, const char *source,
   const char *strp;
   struct r_search_path_elem *pelem, **aelem;
   size_t round_size;
-  struct link_map __attribute__ ((unused)) *l = NULL;
+  struct link_map_private __attribute__ ((unused)) *l = NULL;
   /* Initialize to please the compiler.  */
   const char *errstring = NULL;
 
@@ -825,9 +826,10 @@ _dl_init_paths (const char *llp, const char *source,
    the fd used for loading module L.  */
 
 void
-_dl_process_pt_gnu_property (struct link_map *l, int fd, const ElfW(Phdr) *ph)
+_dl_process_pt_gnu_property (struct link_map_private *l, int fd,
+			     const ElfW(Phdr) *ph)
 {
-  const ElfW(Nhdr) *note = (const void *) (ph->p_vaddr + l->l_addr);
+  const ElfW(Nhdr) *note = (const void *) (ph->p_vaddr + l->l_public.l_addr);
   const ElfW(Addr) size = ph->p_memsz;
   const ElfW(Addr) align = ph->p_align;
 
@@ -897,13 +899,13 @@ _dl_process_pt_gnu_property (struct link_map *l, int fd, const ElfW(Phdr) *ph)
 #ifndef EXTERNAL_MAP_FROM_FD
 static
 #endif
-struct link_map *
+struct link_map_private *
 _dl_map_object_from_fd (const char *name, const char *origname, int fd,
 			struct filebuf *fbp, char *realname,
-			struct link_map *loader, int l_type, int mode,
+			struct link_map_private *loader, int l_type, int mode,
 			void **stack_endp, Lmid_t nsid)
 {
-  struct link_map *l = NULL;
+  struct link_map_private *l = NULL;
   const ElfW(Ehdr) *header;
   const ElfW(Phdr) *phdr;
   const ElfW(Phdr) *ph;
@@ -947,7 +949,7 @@ _dl_map_object_from_fd (const char *name, const char *origname, int fd,
 	}
 
       /* Look again to see if the real name matched another already loaded.  */
-      for (l = GL(dl_ns)[nsid]._ns_loaded; l != NULL; l = l->l_next)
+      for (l = GL(dl_ns)[nsid]._ns_loaded; l != NULL; l = l_next (l))
 	if (!l->l_removed && _dl_file_id_match_p (&l->l_file_id, &id))
 	  {
 	    /* The object is already loaded.
@@ -980,8 +982,8 @@ _dl_map_object_from_fd (const char *name, const char *origname, int fd,
       l->l_real = &GL(dl_rtld_map);
 
       /* Copy l_addr and l_ld to avoid a GDB warning with dlmopen().  */
-      l->l_addr = l->l_real->l_addr;
-      l->l_ld = l->l_real->l_ld;
+      l->l_public.l_addr = l->l_real->l_public.l_addr;
+      l->l_public.l_ld = l->l_real->l_public.l_ld;
 
       /* No need to bump the refcount of the real object, ld.so will
 	 never be unloaded.  */
@@ -1055,9 +1057,9 @@ _dl_map_object_from_fd (const char *name, const char *origname, int fd,
     ElfW(Addr) p_align_max = 0;
 
     /* The struct is initialized to zero so this is not necessary:
-    l->l_ld = 0;
+    l->l_public.l_ld = 0;
     l->l_phdr = 0;
-    l->l_addr = 0; */
+    l->l_public.l_addr = 0; */
     for (ph = phdr; ph < &phdr[l->l_phnum]; ++ph)
       switch (ph->p_type)
 	{
@@ -1072,7 +1074,7 @@ _dl_map_object_from_fd (const char *name, const char *origname, int fd,
 	      /* Debuginfo only files from "objcopy --only-keep-debug"
 		 contain a PT_DYNAMIC segment with p_filesz == 0.  Skip
 		 such a segment to avoid a crash later.  */
-	      l->l_ld = (void *) ph->p_vaddr;
+	      l->l_public.l_ld = (void *) ph->p_vaddr;
 	      l->l_ldnum = ph->p_memsz / sizeof (ElfW(Dyn));
 	      l->l_ld_readonly = (ph->p_flags & PF_W) == 0;
 	    }
@@ -1159,7 +1161,8 @@ _dl_map_object_from_fd (const char *name, const char *origname, int fd,
 	      /* We are loading the executable itself when the dynamic
 		 linker was executed directly.  The setup will happen
 		 later.  */
-	      assert (l->l_prev == NULL || (mode & __RTLD_AUDIT) != 0);
+	      assert (l->l_public.l_prev == NULL
+		      || (mode & __RTLD_AUDIT) != 0);
 #else
 	      assert (false && "TLS not initialized in static application");
 #endif
@@ -1203,7 +1206,8 @@ _dl_map_object_from_fd (const char *name, const char *origname, int fd,
       }
 
     /* This check recognizes most separate debuginfo files.  */
-    if (__glibc_unlikely ((l->l_ld == 0 && type == ET_DYN) || empty_dynamic))
+    if (__glibc_unlikely ((l->l_public.l_ld == 0 && type == ET_DYN)
+			  || empty_dynamic))
       {
 	errstring = N_("object file has no dynamic section");
 	goto lose;
@@ -1226,8 +1230,9 @@ _dl_map_object_from_fd (const char *name, const char *origname, int fd,
       }
   }
 
-  if (l->l_ld != 0)
-    l->l_ld = (ElfW(Dyn) *) ((ElfW(Addr)) l->l_ld + l->l_addr);
+  if (l->l_public.l_ld != 0)
+    l->l_public.l_ld = (ElfW(Dyn) *) ((ElfW(Addr)) l->l_public.l_ld
+				      + l->l_public.l_addr);
 
   elf_get_dynamic_info (l, false, false);
 
@@ -1265,7 +1270,7 @@ _dl_map_object_from_fd (const char *name, const char *origname, int fd,
     }
   else
     /* Adjust the PT_PHDR value by the runtime load address.  */
-    l->l_phdr = (ElfW(Phdr) *) ((ElfW(Addr)) l->l_phdr + l->l_addr);
+    l->l_phdr = (ElfW(Phdr) *) ((ElfW(Addr)) l->l_phdr + l->l_public.l_addr);
 
   if (__glibc_unlikely ((stack_flags &~ GL(dl_stack_flags)) & PF_X))
     {
@@ -1279,8 +1284,8 @@ _dl_map_object_from_fd (const char *name, const char *origname, int fd,
 	  const uintptr_t p = (uintptr_t) &__stack_prot & -GLRO(dl_pagesize);
 	  const size_t s = (uintptr_t) (&__stack_prot + 1) - p;
 
-	  struct link_map *const m = &GL(dl_rtld_map);
-	  const uintptr_t relro_end = ((m->l_addr + m->l_relro_addr
+	  struct link_map_private *const m = &GL(dl_rtld_map);
+	  const uintptr_t relro_end = ((m->l_public.l_addr + m->l_relro_addr
 					+ m->l_relro_size)
 				       & -GLRO(dl_pagesize));
 	  if (__glibc_likely (p + s <= relro_end))
@@ -1320,7 +1325,7 @@ cannot enable executable stack as shared object requires");
 
   /* Adjust the address of the TLS initialization image.  */
   if (l->l_tls_initimage != NULL)
-    l->l_tls_initimage = (char *) l->l_tls_initimage + l->l_addr;
+    l->l_tls_initimage = (char *) l->l_tls_initimage + l->l_public.l_addr;
 
   /* Process program headers again after load segments are mapped in
      case processing requires accessing those segments.  Scan program
@@ -1353,16 +1358,16 @@ cannot enable executable stack as shared object requires");
   /* If this is ET_EXEC, we should have loaded it as lt_executable.  */
   assert (type != ET_EXEC || l->l_type == lt_executable);
 
-  l->l_entry += l->l_addr;
+  l->l_entry += l->l_public.l_addr;
 
   if (__glibc_unlikely (GLRO(dl_debug_mask) & DL_DEBUG_FILES))
     _dl_debug_printf ("\
   dynamic: 0x%0*lx  base: 0x%0*lx   size: 0x%0*zx\n\
     entry: 0x%0*lx  phdr: 0x%0*lx  phnum:   %*u\n\n",
 			   (int) sizeof (void *) * 2,
-			   (unsigned long int) l->l_ld,
+			   (unsigned long int) l->l_public.l_ld,
 			   (int) sizeof (void *) * 2,
-			   (unsigned long int) l->l_addr,
+			   (unsigned long int) l->l_public.l_addr,
 			   (int) sizeof (void *) * 2, maplength,
 			   (int) sizeof (void *) * 2,
 			   (unsigned long int) l->l_entry,
@@ -1531,7 +1536,7 @@ print_search_path (struct r_search_path_elem **list,
    In that case, FD is consumed for both successful and error returns.  */
 static int
 open_verify (const char *name, int fd,
-             struct filebuf *fbp, struct link_map *loader,
+             struct filebuf *fbp, struct link_map_private *loader,
 	     int whatcode, int mode, bool *found_other_class, bool free_name)
 {
   /* This is the expected ELF header.  */
@@ -1747,7 +1752,7 @@ open_verify (const char *name, int fd,
 static int
 open_path (const char *name, size_t namelen, int mode,
 	   struct r_search_path_struct *sps, char **realname,
-	   struct filebuf *fbp, struct link_map *loader, int whatcode,
+	   struct filebuf *fbp, struct link_map_private *loader, int whatcode,
 	   bool *found_other_class)
 {
   struct r_search_path_elem **dirs = sps->dirs;
@@ -1901,22 +1906,22 @@ open_path (const char *name, size_t namelen, int mode,
 
 /* Map in the shared object file NAME.  */
 
-struct link_map *
-_dl_map_object (struct link_map *loader, const char *name,
+struct link_map_private *
+_dl_map_object (struct link_map_private *loader, const char *name,
 		int type, int trace_mode, int mode, Lmid_t nsid)
 {
   int fd;
   const char *origname = NULL;
   char *realname;
   char *name_copy;
-  struct link_map *l;
+  struct link_map_private *l;
   struct filebuf fb;
 
   assert (nsid >= 0);
   assert (nsid < GL(dl_nns));
 
   /* Look for this name among those already loaded.  */
-  for (l = GL(dl_ns)[nsid]._ns_loaded; l; l = l->l_next)
+  for (l = GL(dl_ns)[nsid]._ns_loaded; l; l = l_next (l))
     {
       /* If the requested name matches the soname of a loaded object,
 	 use that object.  Elide this check for names that have not
@@ -1951,7 +1956,8 @@ _dl_map_object (struct link_map *loader, const char *name,
     _dl_debug_printf ((mode & __RTLD_CALLMAP) == 0
 		      ? "\nfile=%s [%lu];  needed by %s [%lu]\n"
 		      : "\nfile=%s [%lu];  dynamically loaded by %s [%lu]\n",
-		      name, nsid, DSO_FILENAME (loader->l_name), loader->l_ns);
+		      name, nsid, DSO_FILENAME (loader->l_public.l_name),
+		      loader->l_ns);
 
 #ifdef SHARED
   /* Give the auditing libraries a chance to change the name before we
@@ -1990,7 +1996,7 @@ _dl_map_object (struct link_map *loader, const char *name,
 	{
 	  /* This is the executable's map (if there is one).  Make sure that
 	     we do not look at it twice.  */
-	  struct link_map *main_map = GL(dl_ns)[LM_ID_BASE]._ns_loaded;
+	  struct link_map_private *main_map = GL(dl_ns)[LM_ID_BASE]._ns_loaded;
 	  bool did_main_map = false;
 
 	  /* First try the DT_RPATH of the dependent object that caused NAME
@@ -2239,7 +2245,8 @@ add_path (struct add_path_state *p, const struct r_search_path_struct *sps,
 }
 
 void
-_dl_rtld_di_serinfo (struct link_map *loader, Dl_serinfo *si, bool counting)
+_dl_rtld_di_serinfo (struct link_map_private *loader, Dl_serinfo *si,
+		     bool counting)
 {
   if (counting)
     {
@@ -2263,7 +2270,7 @@ _dl_rtld_di_serinfo (struct link_map *loader, Dl_serinfo *si, bool counting)
       /* First try the DT_RPATH of the dependent object that caused NAME
 	 to be loaded.  Then that object's dependent, and on up.  */
 
-      struct link_map *l = loader;
+      struct link_map_private *l = loader;
       do
 	{
 	  if (cache_rpath (l, &l->l_rpath_dirs, DT_RPATH, "RPATH"))
diff --git a/elf/dl-load.h b/elf/dl-load.h
index 1d5207694b..78d28627a6 100644
--- a/elf/dl-load.h
+++ b/elf/dl-load.h
@@ -85,7 +85,7 @@ struct loadcmd
    load command, some time after L->l_addr has been set correctly.  It is
    responsible for setting the l_phdr fields  */
 static __always_inline void
-_dl_postprocess_loadcmd (struct link_map *l, const ElfW(Ehdr) *header,
+_dl_postprocess_loadcmd (struct link_map_private *l, const ElfW(Ehdr) *header,
                          const struct loadcmd *c)
 {
   if (l->l_phdr == 0
@@ -110,13 +110,13 @@ _dl_postprocess_loadcmd (struct link_map *l, const ElfW(Ehdr) *header,
    The file <dl-map-segments.h> defines this function.  The canonical
    implementation in elf/dl-map-segments.h might be replaced by a sysdeps
    version.  */
-static const char *_dl_map_segments (struct link_map *l, int fd,
+static const char *_dl_map_segments (struct link_map_private *l, int fd,
                                      const ElfW(Ehdr) *header, int type,
                                      const struct loadcmd loadcmds[],
                                      size_t nloadcmds,
                                      const size_t maplength,
                                      bool has_holes,
-                                     struct link_map *loader);
+                                     struct link_map_private *loader);
 
 /* All the error message strings _dl_map_segments might return are
    listed here so that different implementations in different sysdeps
diff --git a/elf/dl-lookup-direct.c b/elf/dl-lookup-direct.c
index 2c13e92961..35502464c5 100644
--- a/elf/dl-lookup-direct.c
+++ b/elf/dl-lookup-direct.c
@@ -25,7 +25,8 @@
    variant here is simplified because it requires symbol
    versioning.  */
 static const ElfW(Sym) *
-check_match (const struct link_map *const map, const char *const undef_name,
+check_match (const struct link_map_private *const map,
+             const char *const undef_name,
              const char *version, uint32_t version_hash,
              const Elf_Symndx symidx)
 {
@@ -68,7 +69,7 @@ check_match (const struct link_map *const map, const char *const undef_name,
    variant here is simplified because it does not search object
    dependencies.  It is optimized for a successful lookup.  */
 const ElfW(Sym) *
-_dl_lookup_direct (struct link_map *map,
+_dl_lookup_direct (struct link_map_private *map,
                    const char *undef_name, uint32_t new_hash,
                    const char *version, uint32_t version_hash)
 {
diff --git a/elf/dl-lookup.c b/elf/dl-lookup.c
index f889473378..d3c705811c 100644
--- a/elf/dl-lookup.c
+++ b/elf/dl-lookup.c
@@ -38,7 +38,7 @@
 struct sym_val
   {
     const ElfW(Sym) *s;
-    struct link_map *m;
+    struct link_map_private *m;
   };
 
 
@@ -64,7 +64,7 @@ check_match (const char *const undef_name,
 	     const ElfW(Sym) *const sym,
 	     const Elf_Symndx symidx,
 	     const char *const strtab,
-	     const struct link_map *const map,
+	     const struct link_map_private *const map,
 	     const ElfW(Sym) **const versioned_sym,
 	     int *const num_versions)
 {
@@ -152,7 +152,7 @@ check_match (const char *const undef_name,
 static void
 enter_unique_sym (struct unique_sym *table, size_t size,
                   unsigned int hash, const char *name,
-                  const ElfW(Sym) *sym, const struct link_map *map)
+                  const ElfW(Sym) *sym, const struct link_map_private *map)
 {
   size_t idx = hash % size;
   size_t hash2 = 1 + hash % (size - 2);
@@ -172,7 +172,7 @@ enter_unique_sym (struct unique_sym *table, size_t size,
 /* Mark MAP as NODELETE according to the lookup mode in FLAGS.  During
    initial relocation, NODELETE state is pending only.  */
 static void
-mark_nodelete (struct link_map *map, int flags)
+mark_nodelete (struct link_map_private *map, int flags)
 {
   if (flags & DL_LOOKUP_FOR_RELOCATE)
     map->l_nodelete_pending = true;
@@ -183,7 +183,7 @@ mark_nodelete (struct link_map *map, int flags)
 /* Return true if MAP is marked as NODELETE according to the lookup
    mode in FLAGS> */
 static bool
-is_nodelete (struct link_map *map, int flags)
+is_nodelete (struct link_map_private *map, int flags)
 {
   /* Non-pending NODELETE always counts.  Pending NODELETE only counts
      during initial relocation processing.  */
@@ -196,9 +196,10 @@ is_nodelete (struct link_map *map, int flags)
    Return the matching symbol in RESULT.  */
 static void
 do_lookup_unique (const char *undef_name, unsigned int new_hash,
-		  struct link_map *map, struct sym_val *result,
+		  struct link_map_private *map, struct sym_val *result,
 		  int type_class, const ElfW(Sym) *sym, const char *strtab,
-		  const ElfW(Sym) *ref, const struct link_map *undef_map,
+		  const ElfW(Sym) *ref,
+		  const struct link_map_private *undef_map,
 		  int flags)
 {
   /* We have to determine whether we already found a symbol with this
@@ -232,7 +233,7 @@ do_lookup_unique (const char *undef_name, unsigned int new_hash,
 	      else
 		{
 		  result->s = entries[idx].sym;
-		  result->m = (struct link_map *) entries[idx].map;
+		  result->m = (struct link_map_private *) entries[idx].map;
 		}
 	      __rtld_lock_unlock_recursive (tab->lock);
 	      return;
@@ -309,7 +310,7 @@ do_lookup_unique (const char *undef_name, unsigned int new_hash,
 	  if (__glibc_unlikely (GLRO (dl_debug_mask) & DL_DEBUG_BINDINGS))
 	    _dl_debug_printf ("\
 marking %s [%lu] as NODELETE due to unique symbol\n",
-			      map->l_name, map->l_ns);
+			      map->l_public.l_name, map->l_ns);
 	  mark_nodelete (map, flags);
 	}
     }
@@ -318,7 +319,7 @@ marking %s [%lu] as NODELETE due to unique symbol\n",
   __rtld_lock_unlock_recursive (tab->lock);
 
   result->s = sym;
-  result->m = (struct link_map *) map;
+  result->m = (struct link_map_private *) map;
 }
 
 /* Inner part of the lookup functions.  We return a value > 0 if we
@@ -330,7 +331,8 @@ do_lookup_x (const char *undef_name, unsigned int new_hash,
 	     unsigned long int *old_hash, const ElfW(Sym) *ref,
 	     struct sym_val *result, struct r_scope_elem *scope, size_t i,
 	     const struct r_found_version *const version, int flags,
-	     struct link_map *skip, int type_class, struct link_map *undef_map)
+	     struct link_map_private *skip, int type_class,
+	     struct link_map_private *undef_map)
 {
   size_t n = scope->r_nlist;
   /* Make sure we read the value before proceeding.  Otherwise we
@@ -338,11 +340,11 @@ do_lookup_x (const char *undef_name, unsigned int new_hash,
      the value after a resize.  That is the only path in dl-open.c not
      protected by GSCOPE.  A read barrier here might be to expensive.  */
   __asm volatile ("" : "+r" (n), "+m" (scope->r_list));
-  struct link_map **list = scope->r_list;
+  struct link_map_private **list = scope->r_list;
 
   do
     {
-      const struct link_map *map = list[i]->l_real;
+      const struct link_map_private *map = list[i]->l_real;
 
       /* Here come the extra test needed for `_dl_lookup_symbol_skip'.  */
       if (map == skip)
@@ -376,7 +378,7 @@ do_lookup_x (const char *undef_name, unsigned int new_hash,
       /* Print some debugging info if wanted.  */
       if (__glibc_unlikely (GLRO(dl_debug_mask) & DL_DEBUG_SYMBOLS))
 	_dl_debug_printf ("symbol=%s;  lookup in file=%s [%lu]\n",
-			  undef_name, DSO_FILENAME (map->l_name),
+			  undef_name, DSO_FILENAME (map->l_public.l_name),
 			  map->l_ns);
 
       /* If the hash table is empty there is nothing to do here.  */
@@ -476,7 +478,7 @@ do_lookup_x (const char *undef_name, unsigned int new_hash,
 		  if (! result->s)
 		    {
 		      result->s = sym;
-		      result->m = (struct link_map *) map;
+		      result->m = (struct link_map_private *) map;
 		    }
 		  break;
 		}
@@ -484,11 +486,11 @@ do_lookup_x (const char *undef_name, unsigned int new_hash,
 	    case STB_GLOBAL:
 	      /* Global definition.  Just what we need.  */
 	      result->s = sym;
-	      result->m = (struct link_map *) map;
+	      result->m = (struct link_map_private *) map;
 	      return 1;
 
 	    case STB_GNU_UNIQUE:;
-	      do_lookup_unique (undef_name, new_hash, (struct link_map *) map,
+	      do_lookup_unique (undef_name, new_hash, (struct link_map_private *) map,
 				result, type_class, sym, strtab, ref,
 				undef_map, flags);
 	      return 1;
@@ -511,9 +513,10 @@ skip:
 
 /* Add extra dependency on MAP to UNDEF_MAP.  */
 static int
-add_dependency (struct link_map *undef_map, struct link_map *map, int flags)
+add_dependency (struct link_map_private *undef_map,
+		struct link_map_private *map, int flags)
 {
-  struct link_map *runp;
+  struct link_map_private *runp;
   unsigned int i;
   int result = 0;
 
@@ -539,7 +542,8 @@ add_dependency (struct link_map *undef_map, struct link_map *map, int flags)
 
   /* Determine whether UNDEF_MAP already has a reference to MAP.  First
      look in the normal dependencies.  */
-  struct link_map **l_initfini = atomic_forced_read (undef_map->l_initfini);
+  struct link_map_private **l_initfini
+    = atomic_forced_read (undef_map->l_initfini);
   if (l_initfini != NULL)
     {
       for (i = 0; l_initfini[i] != NULL; ++i)
@@ -552,7 +556,7 @@ add_dependency (struct link_map *undef_map, struct link_map *map, int flags)
   unsigned int l_reldepsact = 0;
   if (l_reldeps != NULL)
     {
-      struct link_map **list = &l_reldeps->list[0];
+      struct link_map_private **list = &l_reldeps->list[0];
       l_reldepsact = l_reldeps->act;
       for (i = 0; i < l_reldepsact; ++i)
 	if (list[i] == map)
@@ -595,7 +599,7 @@ add_dependency (struct link_map *undef_map, struct link_map *map, int flags)
 	{
 	  if (undef_map->l_reldeps != l_reldeps)
 	    {
-	      struct link_map **list = &undef_map->l_reldeps->list[0];
+	      struct link_map_private **list = &undef_map->l_reldeps->list[0];
 	      l_reldepsact = undef_map->l_reldeps->act;
 	      for (i = 0; i < l_reldepsact; ++i)
 		if (list[i] == map)
@@ -603,7 +607,7 @@ add_dependency (struct link_map *undef_map, struct link_map *map, int flags)
 	    }
 	  else if (undef_map->l_reldeps->act > l_reldepsact)
 	    {
-	      struct link_map **list
+	      struct link_map_private **list
 		= &undef_map->l_reldeps->list[0];
 	      i = l_reldepsact;
 	      l_reldepsact = undef_map->l_reldeps->act;
@@ -623,7 +627,7 @@ add_dependency (struct link_map *undef_map, struct link_map *map, int flags)
      definition.  */
   runp = GL(dl_ns)[undef_map->l_ns]._ns_loaded;
   while (runp != NULL && runp != map)
-    runp = runp->l_next;
+    runp = l_next (runp);
 
   if (runp != NULL)
     {
@@ -647,15 +651,15 @@ add_dependency (struct link_map *undef_map, struct link_map *map, int flags)
 	  if (__glibc_unlikely (GLRO (dl_debug_mask) & DL_DEBUG_BINDINGS)
 	      && !is_nodelete (map, flags))
 	    {
-	      if (undef_map->l_name[0] == '\0')
+	      if (undef_map->l_public.l_name[0] == '\0')
 		_dl_debug_printf ("\
 marking %s [%lu] as NODELETE due to reference from main program\n",
-				  map->l_name, map->l_ns);
+				  map->l_public.l_name, map->l_ns);
 	      else
 		_dl_debug_printf ("\
 marking %s [%lu] as NODELETE due to reference from %s [%lu]\n",
-				  map->l_name, map->l_ns,
-				  undef_map->l_name, undef_map->l_ns);
+				  map->l_public.l_name, map->l_ns,
+				  undef_map->l_public.l_name, undef_map->l_ns);
 	    }
 	  mark_nodelete (map, flags);
 	  goto out;
@@ -675,7 +679,8 @@ marking %s [%lu] as NODELETE due to reference from %s [%lu]\n",
 	  RTLD_PREPARE_FOREIGN_CALL;
 #endif
 
-	  newp = malloc (sizeof (*newp) + max * sizeof (struct link_map *));
+	  newp = malloc (sizeof (*newp)
+			 + max * sizeof (struct link_map_private *));
 	  if (newp == NULL)
 	    {
 	      /* If we didn't manage to allocate memory for the list this is
@@ -686,7 +691,7 @@ marking %s [%lu] as NODELETE due to reference from %s [%lu]\n",
 		  && !is_nodelete (map, flags))
 		_dl_debug_printf ("\
 marking %s [%lu] as NODELETE due to memory allocation failure\n",
-				  map->l_name, map->l_ns);
+				  map->l_public.l_name, map->l_ns);
 	      /* In case of non-lazy binding, we could actually report
 		 the memory allocation error, but for now, we use the
 		 conservative approximation as well.  */
@@ -697,7 +702,7 @@ marking %s [%lu] as NODELETE due to memory allocation failure\n",
 	    {
 	      if (l_reldepsact)
 		memcpy (&newp->list[0], &undef_map->l_reldeps->list[0],
-			l_reldepsact * sizeof (struct link_map *));
+			l_reldepsact * sizeof (struct link_map_private *));
 	      newp->list[l_reldepsact] = map;
 	      newp->act = l_reldepsact + 1;
 	      atomic_write_barrier ();
@@ -719,9 +724,9 @@ marking %s [%lu] as NODELETE due to memory allocation failure\n",
       if (__glibc_unlikely (GLRO(dl_debug_mask) & DL_DEBUG_FILES))
 	_dl_debug_printf ("\
 \nfile=%s [%lu];  needed by %s [%lu] (relocation dependency)\n\n",
-			  DSO_FILENAME (map->l_name),
+			  DSO_FILENAME (map->l_public.l_name),
 			  map->l_ns,
-			  DSO_FILENAME (undef_map->l_name),
+			  DSO_FILENAME (undef_map->l_public.l_name),
 			  undef_map->l_ns);
     }
   else
@@ -751,11 +756,11 @@ marking %s [%lu] as NODELETE due to memory allocation failure\n",
    or in any function which gets called.  If this would happen the audit
    code might create a thread which can throw off all the scope locking.  */
 lookup_t
-_dl_lookup_symbol_x (const char *undef_name, struct link_map *undef_map,
-		     const ElfW(Sym) **ref,
+_dl_lookup_symbol_x (const char *undef_name,
+		     struct link_map_private *undef_map, const ElfW(Sym) **ref,
 		     struct r_scope_elem *symbol_scope[],
-		     const struct r_found_version *version,
-		     int type_class, int flags, struct link_map *skip_map)
+		     const struct r_found_version *version, int type_class,
+		     int flags, struct link_map_private *skip_map)
 {
   const unsigned int new_hash = _dl_new_hash (undef_name);
   unsigned long int old_hash = 0xffffffff;
@@ -787,7 +792,8 @@ _dl_lookup_symbol_x (const char *undef_name, struct link_map *undef_map,
 	  && !(GLRO(dl_debug_mask) & DL_DEBUG_UNUSED))
 	{
 	  /* We could find no value for a strong reference.  */
-	  const char *reference_name = undef_map ? undef_map->l_name : "";
+	  const char *reference_name
+	    = undef_map ? undef_map->l_public.l_name : "";
 	  const char *versionstr = version ? ", version " : "";
 	  const char *versionname = (version && version->name
 				     ? version->name : "");
@@ -859,12 +865,12 @@ _dl_lookup_symbol_x (const char *undef_name, struct link_map *undef_map,
 
  if (__glibc_unlikely (GLRO(dl_debug_mask) & DL_DEBUG_BINDINGS))
    {
-      const char *reference_name = undef_map->l_name;
+      const char *reference_name = undef_map->l_public.l_name;
 
       _dl_debug_printf ("binding file %s [%lu] to %s [%lu]: %s symbol `%s'",
 			DSO_FILENAME (reference_name),
 			undef_map->l_ns,
-			DSO_FILENAME (current_value.m->l_name),
+			DSO_FILENAME (current_value.m->l_public.l_name),
 			current_value.m->l_ns,
 			protected ? "protected" : "normal", undef_name);
       if (version)
diff --git a/elf/dl-machine-reject-phdr.h b/elf/dl-machine-reject-phdr.h
index f9a8e31e4e..391dda0883 100644
--- a/elf/dl-machine-reject-phdr.h
+++ b/elf/dl-machine-reject-phdr.h
@@ -25,8 +25,8 @@
    host.  */
 static inline bool
 elf_machine_reject_phdr_p (const ElfW(Phdr) *phdr, unsigned int phnum,
-			   const char *buf, size_t len, struct link_map *map,
-			   int fd)
+			   const char *buf, size_t len,
+			   struct link_map_private *map, int fd)
 {
   return false;
 }
diff --git a/elf/dl-map-segments.h b/elf/dl-map-segments.h
index ac10182d58..4ae4ce0a0a 100644
--- a/elf/dl-map-segments.h
+++ b/elf/dl-map-segments.h
@@ -72,11 +72,11 @@ _dl_map_segment (const struct loadcmd *c, ElfW(Addr) mappref,
    other use of those parts of the address space).  */
 
 static __always_inline const char *
-_dl_map_segments (struct link_map *l, int fd,
+_dl_map_segments (struct link_map_private *l, int fd,
                   const ElfW(Ehdr) *header, int type,
                   const struct loadcmd loadcmds[], size_t nloadcmds,
                   const size_t maplength, bool has_holes,
-                  struct link_map *loader)
+                  struct link_map_private *loader)
 {
   const struct loadcmd *c = loadcmds;
 
@@ -103,7 +103,7 @@ _dl_map_segments (struct link_map *l, int fd,
         return DL_MAP_SEGMENTS_ERROR_MAP_SEGMENT;
 
       l->l_map_end = l->l_map_start + maplength;
-      l->l_addr = l->l_map_start - c->mapstart;
+      l->l_public.l_addr = l->l_map_start - c->mapstart;
 
       if (has_holes)
         {
@@ -116,7 +116,7 @@ _dl_map_segments (struct link_map *l, int fd,
 				c->mapend))
 	    return N_("ELF load command address/offset not page-aligned");
           if (__glibc_unlikely
-              (__mprotect ((caddr_t) (l->l_addr + c->mapend),
+              (__mprotect ((caddr_t) (l->l_public.l_addr + c->mapend),
                            loadcmds[nloadcmds - 1].mapstart - c->mapend,
                            PROT_NONE) < 0))
             return DL_MAP_SEGMENTS_ERROR_MPROTECT;
@@ -128,7 +128,7 @@ _dl_map_segments (struct link_map *l, int fd,
     }
 
   /* Remember which part of the address space this object uses.  */
-  l->l_map_start = c->mapstart + l->l_addr;
+  l->l_map_start = c->mapstart + l->l_public.l_addr;
   l->l_map_end = l->l_map_start + maplength;
   l->l_contiguous = !has_holes;
 
@@ -136,7 +136,7 @@ _dl_map_segments (struct link_map *l, int fd,
     {
       if (c->mapend > c->mapstart
           /* Map the segment contents from the file.  */
-          && (__mmap ((void *) (l->l_addr + c->mapstart),
+          && (__mmap ((void *) (l->l_public.l_addr + c->mapstart),
                       c->mapend - c->mapstart, c->prot,
                       MAP_FIXED|MAP_COPY|MAP_FILE,
                       fd, c->mapoff)
@@ -152,8 +152,8 @@ _dl_map_segments (struct link_map *l, int fd,
              after the data mapped from the file.   */
           ElfW(Addr) zero, zeroend, zeropage;
 
-          zero = l->l_addr + c->dataend;
-          zeroend = l->l_addr + c->allocend;
+          zero = l->l_public.l_addr + c->dataend;
+          zeroend = l->l_public.l_addr + c->allocend;
           zeropage = ((zero + GLRO(dl_pagesize) - 1)
                       & ~(GLRO(dl_pagesize) - 1));
 
diff --git a/elf/dl-minimal.c b/elf/dl-minimal.c
index 578bf84c20..31c2f7fbb0 100644
--- a/elf/dl-minimal.c
+++ b/elf/dl-minimal.c
@@ -56,7 +56,7 @@ __rtld_malloc_is_complete (void)
 
 /* Lookup NAME at VERSION in the scope of MATCH.  */
 static void *
-lookup_malloc_symbol (struct link_map *main_map, const char *name,
+lookup_malloc_symbol (struct link_map_private *main_map, const char *name,
 		      struct r_found_version *version)
 {
 
@@ -72,7 +72,7 @@ lookup_malloc_symbol (struct link_map *main_map, const char *name,
 }
 
 void
-__rtld_malloc_init_real (struct link_map *main_map)
+__rtld_malloc_init_real (struct link_map_private *main_map)
 {
   /* We cannot use relocations and initializers for this because the
      changes made by __rtld_malloc_init_stubs break REL-style
diff --git a/elf/dl-misc.c b/elf/dl-misc.c
index e998083284..37c8a4dee9 100644
--- a/elf/dl-misc.c
+++ b/elf/dl-misc.c
@@ -64,9 +64,9 @@ _dl_sysdep_read_whole_file (const char *file, size_t *sizep, int prot)
 
 /* Test whether given NAME matches any of the names of the given object.  */
 int
-_dl_name_match_p (const char *name, const struct link_map *map)
+_dl_name_match_p (const char *name, const struct link_map_private *map)
 {
-  if (strcmp (name, map->l_name) == 0)
+  if (strcmp (name, map->l_public.l_name) == 0)
     return 1;
 
   struct libname_list *runp = map->l_libname;
diff --git a/elf/dl-object.c b/elf/dl-object.c
index f1f2ec956c..3e06e22ab2 100644
--- a/elf/dl-object.c
+++ b/elf/dl-object.c
@@ -27,19 +27,19 @@
 
 /* Add the new link_map NEW to the end of the namespace list.  */
 void
-_dl_add_to_namespace_list (struct link_map *new, Lmid_t nsid)
+_dl_add_to_namespace_list (struct link_map_private *new, Lmid_t nsid)
 {
   /* We modify the list of loaded objects.  */
   __rtld_lock_lock_recursive (GL(dl_load_write_lock));
 
   if (GL(dl_ns)[nsid]._ns_loaded != NULL)
     {
-      struct link_map *l = GL(dl_ns)[nsid]._ns_loaded;
-      while (l->l_next != NULL)
-	l = l->l_next;
-      new->l_prev = l;
+      struct link_map_private *l = GL(dl_ns)[nsid]._ns_loaded;
+      while (l_next (l) != NULL)
+	l = l_next (l);
+      new->l_public.l_prev = &l->l_public;
       /* new->l_next = NULL;   Would be necessary but we use calloc.  */
-      l->l_next = new;
+      l->l_public.l_next = &new->l_public;
     }
   else
     GL(dl_ns)[nsid]._ns_loaded = new;
@@ -51,11 +51,11 @@ _dl_add_to_namespace_list (struct link_map *new, Lmid_t nsid)
 }
 
 
-/* Allocate a `struct link_map' for a new object being loaded,
+/* Allocate a `struct link_map_private' for a new object being loaded,
    and enter it into the _dl_loaded list.  */
-struct link_map *
+struct link_map_private *
 _dl_new_object (char *realname, const char *libname, int type,
-		struct link_map *loader, int mode, Lmid_t nsid)
+		struct link_map_private *loader, int mode, Lmid_t nsid)
 {
 #ifdef SHARED
   unsigned int naudit;
@@ -81,7 +81,7 @@ _dl_new_object (char *realname, const char *libname, int type,
 #endif
 
   size_t libname_len = strlen (libname) + 1;
-  struct link_map *new;
+  struct link_map_private *new;
   struct libname_list *newname;
 #ifdef SHARED
   size_t audit_space = naudit * sizeof (struct auditstate);
@@ -89,15 +89,15 @@ _dl_new_object (char *realname, const char *libname, int type,
 # define audit_space 0
 #endif
 
-  new = (struct link_map *) calloc (sizeof (*new) + audit_space
-				    + sizeof (struct link_map *)
-				    + sizeof (*newname) + libname_len, 1);
+  new = calloc (sizeof (*new) + audit_space
+		+ sizeof (struct link_map_private *)
+		+ sizeof (*newname) + libname_len, 1);
   if (new == NULL)
     return NULL;
 
   new->l_real = new;
-  new->l_symbolic_searchlist.r_list = (struct link_map **) ((char *) (new + 1)
-							    + audit_space);
+  new->l_symbolic_searchlist.r_list
+    = (struct link_map_private **) ((char *) (new + 1) + audit_space);
 
   new->l_libname = newname
     = (struct libname_list *) (new->l_symbolic_searchlist.r_list + 1);
@@ -120,9 +120,9 @@ _dl_new_object (char *realname, const char *libname, int type,
 #else
   if (*realname != '\0')
 #endif
-    new->l_name = realname;
+    new->l_public.l_name = realname;
   else
-    new->l_name = (char *) newname->name + libname_len - 1;
+    new->l_public.l_name = (char *) newname->name + libname_len - 1;
 
   new->l_type = type;
   /* If we set the bit now since we know it is never used we avoid
diff --git a/elf/dl-open.c b/elf/dl-open.c
index 9a16b01838..542889a6b8 100644
--- a/elf/dl-open.c
+++ b/elf/dl-open.c
@@ -50,7 +50,7 @@ struct dl_open_args
   int mode;
   /* This is the caller of the dlopen() function.  */
   const void *caller_dlopen;
-  struct link_map *map;
+  struct link_map_private *map;
   /* Namespace ID.  */
   Lmid_t nsid;
 
@@ -77,7 +77,7 @@ struct dl_open_args
 
 /* Called in case the global scope cannot be extended.  */
 static void __attribute__ ((noreturn))
-add_to_global_resize_failure (struct link_map *new)
+add_to_global_resize_failure (struct link_map_private *new)
 {
   _dl_signal_error (ENOMEM, new->l_libname->name, NULL,
 		    N_ ("cannot extend global scope"));
@@ -88,7 +88,7 @@ add_to_global_resize_failure (struct link_map *new)
    risk of memory allocation failure.  add_to_global_resize raises
    exceptions for memory allocation errors.  */
 static void
-add_to_global_resize (struct link_map *new)
+add_to_global_resize (struct link_map_private *new)
 {
   struct link_namespaces *ns = &GL (dl_ns)[new->l_ns];
 
@@ -145,16 +145,17 @@ add_to_global_resize (struct link_map *new)
   if (new_size > 0)
     {
       size_t allocation_size;
-      if (__builtin_mul_overflow (new_size, sizeof (struct link_map *),
+      if (__builtin_mul_overflow (new_size, sizeof (struct link_map_private *),
 				  &allocation_size))
 	add_to_global_resize_failure (new);
-      struct link_map **new_global = malloc (allocation_size);
+      struct link_map_private **new_global = malloc (allocation_size);
       if (new_global == NULL)
 	add_to_global_resize_failure (new);
 
       /* Copy over the old entries.  */
       memcpy (new_global, ns->_ns_main_searchlist->r_list,
-	      ns->_ns_main_searchlist->r_nlist * sizeof (struct link_map *));
+	      ns->_ns_main_searchlist->r_nlist
+	      * sizeof (struct link_map_private *));
 
       ns->_ns_global_scope_alloc = new_size;
       ns->_ns_main_searchlist->r_list = new_global;
@@ -169,7 +170,7 @@ add_to_global_resize (struct link_map *new)
 /* Actually add the new global objects to the global scope.  Must be
    called after add_to_global_resize.  This function cannot fail.  */
 static void
-add_to_global_update (struct link_map *new)
+add_to_global_update (struct link_map_private *new)
 {
   struct link_namespaces *ns = &GL (dl_ns)[new->l_ns];
 
@@ -177,7 +178,7 @@ add_to_global_update (struct link_map *new)
   unsigned int new_nlist = ns->_ns_main_searchlist->r_nlist;
   for (unsigned int cnt = 0; cnt < new->l_searchlist.r_nlist; ++cnt)
     {
-      struct link_map *map = new->l_searchlist.r_list[cnt];
+      struct link_map_private *map = new->l_searchlist.r_list[cnt];
 
       if (map->l_global == 0)
 	{
@@ -191,7 +192,7 @@ add_to_global_update (struct link_map *new)
 	  /* We modify the global scope.  Report this.  */
 	  if (__glibc_unlikely (GLRO(dl_debug_mask) & DL_DEBUG_SCOPES))
 	    _dl_debug_printf ("\nadd %s [%lu] to global scope\n",
-			      map->l_name, map->l_ns);
+			      map->l_public.l_name, map->l_ns);
 	}
     }
 
@@ -208,14 +209,14 @@ add_to_global_update (struct link_map *new)
 /* Search link maps in all namespaces for the DSO that contains the object at
    address ADDR.  Returns the pointer to the link map of the matching DSO, or
    NULL if a match is not found.  */
-struct link_map *
+struct link_map_private *
 _dl_find_dso_for_object (const ElfW(Addr) addr)
 {
-  struct link_map *l;
+  struct link_map_private *l;
 
   /* Find the highest-addressed object that ADDR is not below.  */
   for (Lmid_t ns = 0; ns < GL(dl_nns); ++ns)
-    for (l = GL(dl_ns)[ns]._ns_loaded; l != NULL; l = l->l_next)
+    for (l = GL(dl_ns)[ns]._ns_loaded; l != NULL; l = l_next (l))
       if (addr >= l->l_map_start && addr < l->l_map_end
 	  && (l->l_contiguous
 	      || _dl_addr_inside_object (l, (ElfW(Addr)) addr)))
@@ -229,7 +230,7 @@ rtld_hidden_def (_dl_find_dso_for_object);
 
 /* Return true if NEW is found in the scope for MAP.  */
 static size_t
-scope_has_map (struct link_map *map, struct link_map *new)
+scope_has_map (struct link_map_private *map, struct link_map_private *new)
 {
   size_t cnt;
   for (cnt = 0; map->l_scope[cnt] != NULL; ++cnt)
@@ -240,7 +241,7 @@ scope_has_map (struct link_map *map, struct link_map *new)
 
 /* Return the length of the scope for MAP.  */
 static size_t
-scope_size (struct link_map *map)
+scope_size (struct link_map_private *map)
 {
   size_t cnt;
   for (cnt = 0; map->l_scope[cnt] != NULL; )
@@ -252,13 +253,13 @@ scope_size (struct link_map *map)
    can be added later without further allocation of memory.  This
    function can raise an exceptions due to malloc failure.  */
 static void
-resize_scopes (struct link_map *new)
+resize_scopes (struct link_map_private *new)
 {
   /* If the file is not loaded now as a dependency, add the search
      list of the newly loaded object to the scope.  */
   for (unsigned int i = 0; i < new->l_searchlist.r_nlist; ++i)
     {
-      struct link_map *imap = new->l_searchlist.r_list[i];
+      struct link_map_private *imap = new->l_searchlist.r_list[i];
 
       /* If the initializer has been called already, the object has
 	 not been loaded here and now.  */
@@ -319,11 +320,11 @@ resize_scopes (struct link_map *new)
    This function cannot raise an exception because all required memory
    has been allocated by a previous call to resize_scopes.  */
 static void
-update_scopes (struct link_map *new)
+update_scopes (struct link_map_private *new)
 {
   for (unsigned int i = 0; i < new->l_searchlist.r_nlist; ++i)
     {
-      struct link_map *imap = new->l_searchlist.r_list[i];
+      struct link_map_private *imap = new->l_searchlist.r_list[i];
       int from_scope = 0;
 
       if (imap->l_init_called && imap->l_type == lt_loaded)
@@ -358,12 +359,12 @@ update_scopes (struct link_map *new)
    exception.  The return value is true if any of the new objects use
    TLS.  */
 static bool
-resize_tls_slotinfo (struct link_map *new)
+resize_tls_slotinfo (struct link_map_private *new)
 {
   bool any_tls = false;
   for (unsigned int i = 0; i < new->l_searchlist.r_nlist; ++i)
     {
-      struct link_map *imap = new->l_searchlist.r_list[i];
+      struct link_map_private *imap = new->l_searchlist.r_list[i];
 
       /* Only add TLS memory if this object is loaded now and
 	 therefore is not yet initialized.  */
@@ -380,12 +381,12 @@ resize_tls_slotinfo (struct link_map *new)
    function does not raise any exception.  It should only be called if
    resize_tls_slotinfo returned true.  */
 static void
-update_tls_slotinfo (struct link_map *new)
+update_tls_slotinfo (struct link_map_private *new)
 {
   unsigned int first_static_tls = new->l_searchlist.r_nlist;
   for (unsigned int i = 0; i < new->l_searchlist.r_nlist; ++i)
     {
-      struct link_map *imap = new->l_searchlist.r_list[i];
+      struct link_map_private *imap = new->l_searchlist.r_list[i];
 
       /* Only add TLS memory if this object is loaded now and
 	 therefore is not yet initialized.  */
@@ -411,7 +412,7 @@ TLS generation counter wrapped!  Please report this."));
      _dl_add_to_slotinfo are still pending.  */
   for (unsigned int i = first_static_tls; i < new->l_searchlist.r_nlist; ++i)
     {
-      struct link_map *imap = new->l_searchlist.r_list[i];
+      struct link_map_private *imap = new->l_searchlist.r_list[i];
 
       if (imap->l_need_tls_init
 	  && ! imap->l_init_called
@@ -443,18 +444,18 @@ TLS generation counter wrapped!  Please report this."));
    after dlopen failure is not possible, so that _dl_close can clean
    up objects if necessary.  */
 static void
-activate_nodelete (struct link_map *new)
+activate_nodelete (struct link_map_private *new)
 {
   /* It is necessary to traverse the entire namespace.  References to
      objects in the global scope and unique symbol bindings can force
      NODELETE status for objects outside the local scope.  */
-  for (struct link_map *l = GL (dl_ns)[new->l_ns]._ns_loaded; l != NULL;
-       l = l->l_next)
+  for (struct link_map_private *l = GL (dl_ns)[new->l_ns]._ns_loaded;
+       l != NULL; l = l_next (l))
     if (l->l_nodelete_pending)
       {
 	if (__glibc_unlikely (GLRO (dl_debug_mask) & DL_DEBUG_FILES))
 	  _dl_debug_printf ("activating NODELETE for %s [%lu]\n",
-			    l->l_name, l->l_ns);
+			    l->l_public.l_name, l->l_ns);
 
 	/* The flag can already be true at this point, e.g. a signal
 	   handler may have triggered lazy binding and set NODELETE
@@ -471,7 +472,7 @@ activate_nodelete (struct link_map *new)
    the debugger is notified of the start of relocation processing.  */
 static void
 _dl_open_relocate_one_object (struct dl_open_args *args, struct r_debug *r,
-			      struct link_map *l, int reloc_mode,
+			      struct link_map_private *l, int reloc_mode,
 			      bool *relocation_in_progress)
 {
   if (l->l_real->l_relocated)
@@ -492,7 +493,7 @@ _dl_open_relocate_one_object (struct dl_open_args *args, struct r_debug *r,
 	 this is necessary or not by observing the `_dl_profile_map'
 	 variable.  If it was NULL but is not NULL afterwards we must
 	 start the profiling.  */
-      struct link_map *old_profile_map = GL(dl_profile_map);
+      struct link_map_private *old_profile_map = GL(dl_profile_map);
 
       _dl_relocate_object (l, l->l_scope, reloc_mode | RTLD_LAZY, 1);
 
@@ -515,7 +516,7 @@ _dl_open_relocate_one_object (struct dl_open_args *args, struct r_debug *r,
    exception handling disabled.  */
 struct dl_init_args
 {
-  struct link_map *new;
+  struct link_map_private *new;
   int argc;
   char **argv;
   char **env;
@@ -534,7 +535,7 @@ dl_open_worker_begin (void *a)
   struct dl_open_args *args = a;
   const char *file = args->file;
   int mode = args->mode;
-  struct link_map *call_map = NULL;
+  struct link_map_private *call_map = NULL;
 
   /* Determine the caller's map if necessary.  This is needed in case
      we have a DST, when we don't know the namespace ID we have to put
@@ -550,7 +551,7 @@ dl_open_worker_begin (void *a)
 	 By default we assume this is the main application.  */
       call_map = GL(dl_ns)[LM_ID_BASE]._ns_loaded;
 
-      struct link_map *l = _dl_find_dso_for_object ((ElfW(Addr)) caller_dlopen);
+      struct link_map_private *l = _dl_find_dso_for_object ((ElfW(Addr)) caller_dlopen);
 
       if (l)
 	call_map = l;
@@ -573,7 +574,7 @@ dl_open_worker_begin (void *a)
   _dl_debug_initialize (0, args->nsid);
 
   /* Load the named object.  */
-  struct link_map *new;
+  struct link_map_private *new;
   args->map = new = _dl_map_object (call_map, file, lt_loaded, 0,
 				    mode | __RTLD_CALLMAP, args->nsid);
 
@@ -598,7 +599,8 @@ dl_open_worker_begin (void *a)
       /* Let the user know about the opencount.  */
       if (__glibc_unlikely (GLRO(dl_debug_mask) & DL_DEBUG_FILES))
 	_dl_debug_printf ("opening file=%s [%lu]; direct_opencount=%u\n\n",
-			  new->l_name, new->l_ns, new->l_direct_opencount);
+			  new->l_public.l_name, new->l_ns,
+			  new->l_direct_opencount);
 
       /* If the user requested the object to be in the global
 	 namespace but it is not so far, prepare to add it now.  This
@@ -613,7 +615,7 @@ dl_open_worker_begin (void *a)
 	  if (__glibc_unlikely (GLRO (dl_debug_mask) & DL_DEBUG_FILES)
 	      && !new->l_nodelete_active)
 	    _dl_debug_printf ("marking %s [%lu] as NODELETE\n",
-			      new->l_name, new->l_ns);
+			      new->l_public.l_name, new->l_ns);
 	  new->l_nodelete_active = true;
 	}
 
@@ -641,7 +643,7 @@ dl_open_worker_begin (void *a)
   for (unsigned int i = 0; i < new->l_searchlist.r_nlist; ++i)
     if (new->l_searchlist.r_list[i]->l_real->l_versions == NULL)
       {
-	struct link_map *map = new->l_searchlist.r_list[i]->l_real;
+	struct link_map_private *map = new->l_searchlist.r_list[i]->l_real;
 	_dl_check_map_versions (map, 0, 0);
 #ifndef SHARED
 	/* During static dlopen, check if ld.so has been loaded.
@@ -684,7 +686,7 @@ dl_open_worker_begin (void *a)
   unsigned int first = UINT_MAX;
   unsigned int last = 0;
   unsigned int j = 0;
-  struct link_map *l = new->l_initfini[0];
+  struct link_map_private *l = new->l_initfini[0];
   do
     {
       if (! l->l_real->l_relocated)
@@ -780,7 +782,7 @@ dl_open_worker_begin (void *a)
   if (!args->libc_already_loaded)
     {
       /* dlopen cannot be used to load an initial libc by design.  */
-      struct link_map *libc_map = GL(dl_ns)[args->nsid].libc_map;
+      struct link_map_private *libc_map = GL(dl_ns)[args->nsid].libc_map;
       _dl_call_libc_early_init (libc_map, false);
     }
 
@@ -812,7 +814,7 @@ dl_open_worker (void *a)
     return;
 
   int mode = args->mode;
-  struct link_map *new = args->map;
+  struct link_map_private *new = args->map;
 
   /* Run the initializer functions of new objects.  Temporarily
      disable the exception handler, so that lazy binding failures are
@@ -835,7 +837,8 @@ dl_open_worker (void *a)
   /* Let the user know about the opencount.  */
   if (__glibc_unlikely (GLRO(dl_debug_mask) & DL_DEBUG_FILES))
     _dl_debug_printf ("opening file=%s [%lu]; direct_opencount=%u\n\n",
-		      new->l_name, new->l_ns, new->l_direct_opencount);
+		      new->l_public.l_name, new->l_ns,
+		      new->l_direct_opencount);
 }
 
 void *
@@ -959,19 +962,20 @@ no more namespaces available for dlmopen()"));
 
 
 void
-_dl_show_scope (struct link_map *l, int from)
+_dl_show_scope (struct link_map_private *l, int from)
 {
   _dl_debug_printf ("object=%s [%lu]\n",
-		    DSO_FILENAME (l->l_name), l->l_ns);
+		    DSO_FILENAME (l->l_public.l_name), l->l_ns);
   if (l->l_scope != NULL)
     for (int scope_cnt = from; l->l_scope[scope_cnt] != NULL; ++scope_cnt)
       {
 	_dl_debug_printf (" scope %u:", scope_cnt);
 
 	for (unsigned int cnt = 0; cnt < l->l_scope[scope_cnt]->r_nlist; ++cnt)
-	  if (*l->l_scope[scope_cnt]->r_list[cnt]->l_name)
+	  if (*l->l_scope[scope_cnt]->r_list[cnt]->l_public.l_name)
 	    _dl_debug_printf_c (" %s",
-				l->l_scope[scope_cnt]->r_list[cnt]->l_name);
+				l->l_scope[scope_cnt]->r_list[cnt]
+				->l_public.l_name);
 	  else
 	    _dl_debug_printf_c (" %s", RTLD_PROGNAME);
 
diff --git a/elf/dl-profile.c b/elf/dl-profile.c
index 8be0065fbd..fdf540c957 100644
--- a/elf/dl-profile.c
+++ b/elf/dl-profile.c
@@ -220,9 +220,9 @@ _dl_start_profile (void)
   /* Now we can compute the size of the profiling data.  This is done
      with the same formulas as in `monstartup' (see gmon.c).  */
   running = 0;
-  lowpc = ROUNDDOWN (mapstart + GL(dl_profile_map)->l_addr,
+  lowpc = ROUNDDOWN (mapstart + GL(dl_profile_map)->l_public.l_addr,
 		     HISTFRACTION * sizeof (HISTCOUNTER));
-  highpc = ROUNDUP (mapend + GL(dl_profile_map)->l_addr,
+  highpc = ROUNDUP (mapend + GL(dl_profile_map)->l_public.l_addr,
 		    HISTFRACTION * sizeof (HISTCOUNTER));
   textsize = highpc - lowpc;
   kcountsize = textsize / HISTFRACTION;
diff --git a/elf/dl-reloc-static-pie.c b/elf/dl-reloc-static-pie.c
index a143ee5aad..ab94462f20 100644
--- a/elf/dl-reloc-static-pie.c
+++ b/elf/dl-reloc-static-pie.c
@@ -35,13 +35,14 @@
 void
 _dl_relocate_static_pie (void)
 {
-  struct link_map *main_map = _dl_get_dl_main_map ();
+  struct link_map_private *main_map = _dl_get_dl_main_map ();
 
   /* Figure out the run-time load address of static PIE.  */
-  main_map->l_addr = elf_machine_load_address ();
+  main_map->l_public.l_addr = elf_machine_load_address ();
 
   /* Read our own dynamic section and fill in the info array.  */
-  main_map->l_ld = ((void *) main_map->l_addr + elf_machine_dynamic ());
+  main_map->l_public.l_ld = ((void *) main_map->l_public.l_addr
+			     + elf_machine_dynamic ());
 
   const ElfW(Phdr) *ph, *phdr = GL(dl_phdr);
   size_t phnum = GL(dl_phnum);
diff --git a/elf/dl-reloc.c b/elf/dl-reloc.c
index 72c8586d29..cbe4fcee4c 100644
--- a/elf/dl-reloc.c
+++ b/elf/dl-reloc.c
@@ -49,7 +49,7 @@
    TLS runs out.  If OPTIONAL is false then the entire surplus TLS area is
    considered and the allocation only fails if that runs out.  */
 int
-_dl_try_allocate_static_tls (struct link_map *map, bool optional)
+_dl_try_allocate_static_tls (struct link_map_private *map, bool optional)
 {
   /* If we've already used the variable with dynamic access, or if the
      alignment requirements are too high, fail.  */
@@ -132,12 +132,12 @@ _dl_try_allocate_static_tls (struct link_map *map, bool optional)
    not be inlined as much as possible.  */
 void
 __attribute_noinline__
-_dl_allocate_static_tls (struct link_map *map)
+_dl_allocate_static_tls (struct link_map_private *map)
 {
   if (map->l_tls_offset == FORCED_DYNAMIC_TLS_OFFSET
       || _dl_try_allocate_static_tls (map, false))
     {
-      _dl_signal_error (0, map->l_name, NULL, N_("\
+      _dl_signal_error (0, map->l_public.l_name, NULL, N_("\
 cannot allocate memory in static TLS block"));
     }
 }
@@ -147,7 +147,7 @@ cannot allocate memory in static TLS block"));
    libpthread implementations should provide their own hook
    to handle all threads.  */
 void
-_dl_nothread_init_static_tls (struct link_map *map)
+_dl_nothread_init_static_tls (struct link_map_private *map)
 {
 #if TLS_TCB_AT_TP
   void *dest = (char *) THREAD_SELF - map->l_tls_offset;
@@ -202,7 +202,7 @@ resolve_map (lookup_t l, struct r_scope_elem *scope[], const ElfW(Sym) **ref,
 #include "dynamic-link.h"
 
 void
-_dl_relocate_object (struct link_map *l, struct r_scope_elem *scope[],
+_dl_relocate_object (struct link_map_private *l, struct r_scope_elem *scope[],
 		     int reloc_mode, int consider_profiling)
 {
   if (l->l_relocated)
@@ -254,7 +254,8 @@ _dl_relocate_object (struct link_map *l, struct r_scope_elem *scope[],
 
   if (__glibc_unlikely (GLRO(dl_debug_mask) & DL_DEBUG_RELOC))
     _dl_debug_printf ("\nrelocation processing: %s%s\n",
-		      DSO_FILENAME (l->l_name), lazy ? " (lazy)" : "");
+		      DSO_FILENAME (l->l_public.l_name), lazy
+		      ? " (lazy)" : "");
 
   /* DT_TEXTREL is now in level 2 and might phase out at some time.
      But we rewrite the DT_FLAGS entry to a DT_TEXTREL entry to make
@@ -273,7 +274,7 @@ _dl_relocate_object (struct link_map *l, struct r_scope_elem *scope[],
 	    newp->len = ALIGN_UP (ph->p_vaddr + ph->p_memsz, GLRO(dl_pagesize))
 			- ALIGN_DOWN (ph->p_vaddr, GLRO(dl_pagesize));
 	    newp->start = PTR_ALIGN_DOWN (ph->p_vaddr, GLRO(dl_pagesize))
-			  + (caddr_t) l->l_addr;
+			  + (caddr_t) l->l_public.l_addr;
 
 	    newp->prot = 0;
 	    if (ph->p_flags & PF_R)
@@ -287,7 +288,7 @@ _dl_relocate_object (struct link_map *l, struct r_scope_elem *scope[],
 	      {
 		errstring = N_("cannot make segment writable for relocation");
 	      call_error:
-		_dl_signal_error (errno, l->l_name, NULL, errstring);
+		_dl_signal_error (errno, l->l_public.l_name, NULL, errstring);
 	      }
 
 	    newp->next = textrels;
@@ -318,7 +319,7 @@ _dl_relocate_object (struct link_map *l, struct r_scope_elem *scope[],
 	  {
 	    errstring = N_("\
 %s: out of memory to store relocation results for %s\n");
-	    _dl_fatal_printf (errstring, RTLD_PROGNAME, l->l_name);
+	    _dl_fatal_printf (errstring, RTLD_PROGNAME, l->l_public.l_name);
 	  }
       }
 #endif
@@ -351,12 +352,12 @@ _dl_relocate_object (struct link_map *l, struct r_scope_elem *scope[],
 
 
 void
-_dl_protect_relro (struct link_map *l)
+_dl_protect_relro (struct link_map_private *l)
 {
-  ElfW(Addr) start = ALIGN_DOWN((l->l_addr
+  ElfW(Addr) start = ALIGN_DOWN((l->l_public.l_addr
 				 + l->l_relro_addr),
 				GLRO(dl_pagesize));
-  ElfW(Addr) end = ALIGN_DOWN((l->l_addr
+  ElfW(Addr) end = ALIGN_DOWN((l->l_public.l_addr
 			       + l->l_relro_addr
 			       + l->l_relro_size),
 			      GLRO(dl_pagesize));
@@ -365,13 +366,13 @@ _dl_protect_relro (struct link_map *l)
     {
       static const char errstring[] = N_("\
 cannot apply additional memory protection after relocation");
-      _dl_signal_error (errno, l->l_name, NULL, errstring);
+      _dl_signal_error (errno, l->l_public.l_name, NULL, errstring);
     }
 }
 
 void
 __attribute_noinline__
-_dl_reloc_bad_type (struct link_map *map, unsigned int type, int plt)
+_dl_reloc_bad_type (struct link_map_private *map, unsigned int type, int plt)
 {
 #define DIGIT(b)	_itoa_lower_digits[(b) & 0xf];
 
@@ -401,5 +402,5 @@ _dl_reloc_bad_type (struct link_map *map, unsigned int type, int plt)
   *cp++ = DIGIT (type);
   *cp = '\0';
 
-  _dl_signal_error (0, map->l_name, NULL, msgbuf);
+  _dl_signal_error (0, map->l_public.l_name, NULL, msgbuf);
 }
diff --git a/elf/dl-runtime.c b/elf/dl-runtime.c
index fe7deda32a..8214b862c2 100644
--- a/elf/dl-runtime.c
+++ b/elf/dl-runtime.c
@@ -42,7 +42,7 @@ _dl_fixup (
 # ifdef ELF_MACHINE_RUNTIME_FIXUP_ARGS
 	   ELF_MACHINE_RUNTIME_FIXUP_ARGS,
 # endif
-	   struct link_map *l, ElfW(Word) reloc_arg)
+	   struct link_map_private *l, ElfW(Word) reloc_arg)
 {
   const ElfW(Sym) *const symtab
     = (const void *) D_PTR (l, l_info[DT_SYMTAB]);
@@ -55,7 +55,7 @@ _dl_fixup (
 		      + reloc_offset (pltgot, reloc_arg));
   const ElfW(Sym) *sym = &symtab[ELFW(R_SYM) (reloc->r_info)];
   const ElfW(Sym) *refsym = sym;
-  void *const rel_addr = (void *)(l->l_addr + reloc->r_offset);
+  void *const rel_addr = (void *)(l->l_public.l_addr + reloc->r_offset);
   lookup_t result;
   DL_FIXUP_VALUE_TYPE value;
 
@@ -170,7 +170,7 @@ _dl_profile_fixup (
 # ifdef ELF_MACHINE_RUNTIME_FIXUP_ARGS
 		   ELF_MACHINE_RUNTIME_FIXUP_ARGS,
 # endif
-		   struct link_map *l, ElfW(Word) reloc_arg,
+		   struct link_map_private *l, ElfW(Word) reloc_arg,
 		   ElfW(Addr) retaddr, void *regs, long int *framesizep)
 {
   void (*mcount_fct) (ElfW(Addr), ElfW(Addr)) = _dl_mcount;
diff --git a/elf/dl-setup_hash.c b/elf/dl-setup_hash.c
index e3322dec4b..1b8481b07f 100644
--- a/elf/dl-setup_hash.c
+++ b/elf/dl-setup_hash.c
@@ -21,7 +21,7 @@
 #include <ldsodefs.h>
 
 void
-_dl_setup_hash (struct link_map *map)
+_dl_setup_hash (struct link_map_private *map)
 {
   Elf_Symndx *hash;
 
diff --git a/elf/dl-sort-maps.c b/elf/dl-sort-maps.c
index 5c846c7c6f..bcc49fa0e9 100644
--- a/elf/dl-sort-maps.c
+++ b/elf/dl-sort-maps.c
@@ -26,7 +26,7 @@
    Sort array MAPS according to dependencies of the contained objects.
    If FOR_FINI is true, this is called for finishing an object.  */
 static void
-_dl_sort_maps_original (struct link_map **maps, unsigned int nmaps,
+_dl_sort_maps_original (struct link_map_private **maps, unsigned int nmaps,
 			bool force_first, bool for_fini)
 {
   /* Allows caller to do the common optimization of skipping the first map,
@@ -45,7 +45,7 @@ _dl_sort_maps_original (struct link_map **maps, unsigned int nmaps,
     {
       /* Keep track of which object we looked at this round.  */
       ++seen[i];
-      struct link_map *thisp = maps[i];
+      struct link_map_private *thisp = maps[i];
 
       if (__glibc_unlikely (for_fini))
 	{
@@ -61,7 +61,7 @@ _dl_sort_maps_original (struct link_map **maps, unsigned int nmaps,
       unsigned int k = nmaps - 1;
       while (k > i)
 	{
-	  struct link_map **runp = maps[k]->l_initfini;
+	  struct link_map_private **runp = maps[k]->l_initfini;
 	  if (runp != NULL)
 	    /* Look through the dependencies of the object.  */
 	    while (*runp != NULL)
@@ -90,7 +90,7 @@ _dl_sort_maps_original (struct link_map **maps, unsigned int nmaps,
 	  if (__glibc_unlikely (for_fini && maps[k]->l_reldeps != NULL))
 	    {
 	      unsigned int m = maps[k]->l_reldeps->act;
-	      struct link_map **relmaps = &maps[k]->l_reldeps->list[0];
+	      struct link_map_private **relmaps = &maps[k]->l_reldeps->list[0];
 
 	      /* Look through the relocation dependencies of the object.  */
 	      while (m-- > 0)
@@ -98,7 +98,7 @@ _dl_sort_maps_original (struct link_map **maps, unsigned int nmaps,
 		  {
 		    /* If a cycle exists with a link time dependency,
 		       preserve the latter.  */
-		    struct link_map **runp = thisp->l_initfini;
+		    struct link_map_private **runp = thisp->l_initfini;
 		    if (runp != NULL)
 		      while (*runp != NULL)
 			if (__glibc_unlikely (*runp++ == maps[k]))
@@ -132,7 +132,7 @@ _dl_sort_maps_original (struct link_map **maps, unsigned int nmaps,
    decremented before storing the current map at each level.  */
 
 static void
-dfs_traversal (struct link_map ***rpo, struct link_map *map,
+dfs_traversal (struct link_map_private ***rpo, struct link_map_private *map,
 	       bool *do_reldeps)
 {
   /* _dl_map_object_deps ignores l_faked objects when calculating the
@@ -146,7 +146,7 @@ dfs_traversal (struct link_map ***rpo, struct link_map *map,
     {
       for (int i = 0; map->l_initfini[i] != NULL; i++)
 	{
-	  struct link_map *dep = map->l_initfini[i];
+	  struct link_map_private *dep = map->l_initfini[i];
 	  if (dep->l_visited == 0
 	      && dep->l_main_map == 0)
 	    dfs_traversal (rpo, dep, do_reldeps);
@@ -161,7 +161,7 @@ dfs_traversal (struct link_map ***rpo, struct link_map *map,
 
       for (int m = map->l_reldeps->act - 1; m >= 0; m--)
 	{
-	  struct link_map *dep = map->l_reldeps->list[m];
+	  struct link_map_private *dep = map->l_reldeps->list[m];
 	  if (dep->l_visited == 0
 	      && dep->l_main_map == 0)
 	    dfs_traversal (rpo, dep, do_reldeps);
@@ -176,10 +176,10 @@ dfs_traversal (struct link_map ***rpo, struct link_map *map,
    objects.  */
 
 static void
-_dl_sort_maps_dfs (struct link_map **maps, unsigned int nmaps,
+_dl_sort_maps_dfs (struct link_map_private **maps, unsigned int nmaps,
 		   bool force_first, bool for_fini)
 {
-  struct link_map *first_map = maps[0];
+  struct link_map_private *first_map = maps[0];
   for (int i = nmaps - 1; i >= 0; i--)
     maps[i]->l_visited = 0;
 
@@ -208,12 +208,12 @@ _dl_sort_maps_dfs (struct link_map **maps, unsigned int nmaps,
      to front makes things much more straightforward.  */
 
   /* Array to hold RPO sorting results, before we copy back to maps[].  */
-  struct link_map *rpo[nmaps];
+  struct link_map_private *rpo[nmaps];
 
   /* The 'head' position during each DFS iteration. Note that we start at
      one past the last element due to first-decrement-then-store (see the
      bottom of above dfs_traversal() routine).  */
-  struct link_map **rpo_head = &rpo[nmaps];
+  struct link_map_private **rpo_head = &rpo[nmaps];
 
   bool do_reldeps = false;
   bool *do_reldeps_ref = (for_fini ? &do_reldeps : NULL);
@@ -246,7 +246,7 @@ _dl_sort_maps_dfs (struct link_map **maps, unsigned int nmaps,
       for (int i = nmaps - 1; i >= 0; i--)
 	rpo[i]->l_visited = 0;
 
-      struct link_map **maps_head = &maps[nmaps];
+      struct link_map_private **maps_head = &maps[nmaps];
       for (int i = nmaps - 1; i >= 0; i--)
 	{
 	  dfs_traversal (&maps_head, rpo[i], NULL);
@@ -260,7 +260,7 @@ _dl_sort_maps_dfs (struct link_map **maps, unsigned int nmaps,
       assert (maps_head == maps);
     }
   else
-    memcpy (maps, rpo, sizeof (struct link_map *) * nmaps);
+    memcpy (maps, rpo, sizeof (struct link_map_private *) * nmaps);
 
   /* Skipping the first object at maps[0] is not valid in general,
      since traversing along object dependency-links may "find" that
@@ -293,7 +293,7 @@ _dl_sort_maps_init (void)
 }
 
 void
-_dl_sort_maps (struct link_map **maps, unsigned int nmaps,
+_dl_sort_maps (struct link_map_private **maps, unsigned int nmaps,
 	       bool force_first, bool for_fini)
 {
   /* It can be tempting to use a static function pointer to store and call
diff --git a/elf/dl-static-tls.h b/elf/dl-static-tls.h
index 5ffbad99f5..d40dd882f6 100644
--- a/elf/dl-static-tls.h
+++ b/elf/dl-static-tls.h
@@ -45,7 +45,7 @@
      && (__builtin_expect ((sym_map)->l_tls_offset != NO_TLS_OFFSET, 1)	\
 	 || _dl_try_allocate_static_tls (sym_map, true) == 0))
 
-int _dl_try_allocate_static_tls (struct link_map *map, bool optional)
+int _dl_try_allocate_static_tls (struct link_map_private *map, bool optional)
   attribute_hidden;
 
 #endif
diff --git a/elf/dl-support.c b/elf/dl-support.c
index 837fa1c836..3648dd4d05 100644
--- a/elf/dl-support.c
+++ b/elf/dl-support.c
@@ -65,7 +65,7 @@ int _dl_verbose;
 const char *_dl_inhibit_rpath;
 
 /* The map for the object we will profile.  */
-struct link_map *_dl_profile_map;
+struct link_map_private *_dl_profile_map;
 
 /* This is the address of the last stack address ever used.  */
 void *__libc_stack_end;
@@ -78,18 +78,21 @@ int _dl_bind_not;
 
 /* A dummy link map for the executable, used by dlopen to access the global
    scope.  We don't export any symbols ourselves, so this can be minimal.  */
-static struct link_map _dl_main_map =
+static struct link_map_private _dl_main_map =
   {
-    .l_name = (char *) "",
+    .l_public = { .l_name = (char *) "", },
     .l_real = &_dl_main_map,
     .l_ns = LM_ID_BASE,
     .l_libname = &(struct libname_list) { .name = "", .dont_free = 1 },
     .l_searchlist =
       {
-	.r_list = &(struct link_map *) { &_dl_main_map },
+	.r_list = &(struct link_map_private *) { &_dl_main_map },
 	.r_nlist = 1,
       },
-    .l_symbolic_searchlist = { .r_list = &(struct link_map *) { NULL } },
+    .l_symbolic_searchlist =
+      {
+	.r_list = &(struct link_map_private *) { NULL },
+      },
     .l_type = lt_executable,
     .l_scope_mem = { &_dl_main_map.l_searchlist },
     .l_scope_max = (sizeof (_dl_main_map.l_scope_mem)
@@ -119,7 +122,7 @@ unsigned long long _dl_load_adds = 1;
 /* Fake scope of the main application.  */
 struct r_scope_elem _dl_initial_searchlist =
   {
-    .r_list = &(struct link_map *) { &_dl_main_map },
+    .r_list = &(struct link_map_private *) { &_dl_main_map },
     .r_nlist = 1,
   };
 
@@ -148,7 +151,7 @@ struct r_search_path_elem *_dl_all_dirs;
 struct r_search_path_elem *_dl_init_all_dirs;
 
 /* The object to be initialized first.  */
-struct link_map *_dl_initfirst;
+struct link_map_private *_dl_initfirst;
 
 /* Descriptor to write debug messages to.  */
 int _dl_debug_fd = STDERR_FILENO;
@@ -180,7 +183,8 @@ int _dl_stack_cache_lock;
    when it was not, we do it by calling this function.
    It returns an errno code or zero on success.  */
 int (*_dl_make_stack_executable_hook) (void **) = _dl_make_stack_executable;
-void (*_dl_init_static_tls) (struct link_map *) = &_dl_nothread_init_static_tls;
+void (*_dl_init_static_tls) (struct link_map_private *)
+  = &_dl_nothread_init_static_tls;
 #endif
 struct dl_scope_free_list *_dl_scope_free_list;
 
@@ -193,7 +197,7 @@ uintptr_t _dl_sysinfo;
 /* Address of the ELF headers in the vsyscall page.  */
 const ElfW(Ehdr) *_dl_sysinfo_dso;
 
-struct link_map *_dl_sysinfo_map;
+struct link_map_private *_dl_sysinfo_map;
 
 # include "get-dynamic-info.h"
 #endif
@@ -348,7 +352,7 @@ DL_SYSINFO_IMPLEMENTATION
 /* Since relocation to hidden _dl_main_map causes relocation overflow on
    aarch64, a function is used to get the address of _dl_main_map.  */
 
-struct link_map *
+struct link_map_private *
 _dl_get_dl_main_map (void)
 {
   return &_dl_main_map;
@@ -358,7 +362,7 @@ _dl_get_dl_main_map (void)
 /* This is used by _dl_runtime_profile, not used on static code.  */
 void
 DL_ARCH_FIXUP_ATTRIBUTE
-_dl_audit_pltexit (struct link_map *l, ElfW(Word) reloc_arg,
+_dl_audit_pltexit (struct link_map_private *l, ElfW(Word) reloc_arg,
 		   const void *inregs, void *outregs)
 {
 }
diff --git a/elf/dl-sym-post.h b/elf/dl-sym-post.h
index 5623d63ac8..c118f81f79 100644
--- a/elf/dl-sym-post.h
+++ b/elf/dl-sym-post.h
@@ -18,10 +18,10 @@
 
 
 /* Return the link map containing the caller address.  */
-static struct link_map *
+static struct link_map_private *
 _dl_sym_find_caller_link_map (ElfW(Addr) caller)
 {
-  struct link_map *l = _dl_find_dso_for_object (caller);
+  struct link_map_private *l = _dl_find_dso_for_object (caller);
   if (l != NULL)
     return l;
   else
@@ -35,7 +35,7 @@ _dl_sym_find_caller_link_map (ElfW(Addr) caller)
    necessary.  If MATCH is NULL, CALLER is used to determine it.  */
 static void *
 _dl_sym_post (lookup_t result, const ElfW(Sym) *ref, void *value,
-              ElfW(Addr) caller, struct link_map *match)
+              ElfW(Addr) caller, struct link_map_private *match)
 {
   /* Resolve indirect function address.  */
   if (__glibc_unlikely (ELFW(ST_TYPE) (ref->st_info) == STT_GNU_IFUNC))
diff --git a/elf/dl-sym.c b/elf/dl-sym.c
index b1ed1f2006..5774ea594a 100644
--- a/elf/dl-sym.c
+++ b/elf/dl-sym.c
@@ -42,7 +42,7 @@
 /* Return the symbol address given the map of the module it is in and
    the symbol record.  This is used in dl-sym.c.  */
 static void *
-_dl_tls_symaddr (struct link_map *map, const ElfW(Sym) *ref)
+_dl_tls_symaddr (struct link_map_private *map, const ElfW(Sym) *ref)
 {
 # ifndef DONT_USE_TLS_INDEX
   tls_index tmp =
@@ -62,7 +62,7 @@ _dl_tls_symaddr (struct link_map *map, const ElfW(Sym) *ref)
 struct call_dl_lookup_args
 {
   /* Arguments to do_dlsym.  */
-  struct link_map *map;
+  struct link_map_private *map;
   const char *name;
   struct r_found_version *vers;
   int flags;
@@ -90,7 +90,7 @@ do_sym (void *handle, const char *name, void *who,
   ElfW(Addr) caller = (ElfW(Addr)) who;
 
   /* Link map of the caller if needed.  */
-  struct link_map *match = NULL;
+  struct link_map_private *match = NULL;
 
   if (handle == RTLD_DEFAULT)
     {
@@ -139,7 +139,7 @@ do_sym (void *handle, const char *name, void *who,
 RTLD_NEXT used in code not dynamically loaded"));
 	}
 
-      struct link_map *l = match;
+      struct link_map_private *l = match;
       while (l->l_loader != NULL)
 	l = l->l_loader;
 
@@ -149,7 +149,7 @@ RTLD_NEXT used in code not dynamically loaded"));
   else
     {
       /* Search the scope of the given object.  */
-      struct link_map *map = handle;
+      struct link_map_private *map = handle;
       result = GLRO(dl_lookup_symbol_x) (name, map, &ref, map->l_local_scope,
 					 vers, 0, flags, NULL);
     }
diff --git a/elf/dl-symaddr.c b/elf/dl-symaddr.c
index 5c4f94943b..6f37f26080 100644
--- a/elf/dl-symaddr.c
+++ b/elf/dl-symaddr.c
@@ -20,7 +20,7 @@
 #include <dl-fptr.h>
 
 void *
-_dl_symbol_address (struct link_map *map, const ElfW(Sym) *ref)
+_dl_symbol_address (struct link_map_private *map, const ElfW(Sym) *ref)
 {
   ElfW(Addr) value = SYMBOL_ADDRESS (map, ref, false);
 
diff --git a/elf/dl-tls.c b/elf/dl-tls.c
index 70446e71a8..68ed806c8e 100644
--- a/elf/dl-tls.c
+++ b/elf/dl-tls.c
@@ -121,7 +121,7 @@ oom (void)
 
 
 void
-_dl_assign_tls_modid (struct link_map *l)
+_dl_assign_tls_modid (struct link_map_private *l)
 {
   size_t result;
 
@@ -553,7 +553,7 @@ _dl_allocate_tls_init (void *result, bool init_tls)
 
       for (cnt = total == 0 ? 1 : 0; cnt < listp->len; ++cnt)
 	{
-	  struct link_map *map;
+	  struct link_map_private *map;
 	  void *dest;
 
 	  /* Check for the total number of used slots.  */
@@ -699,7 +699,7 @@ allocate_dtv_entry (size_t alignment, size_t size)
 }
 
 static struct dtv_pointer
-allocate_and_init (struct link_map *map)
+allocate_and_init (struct link_map_private *map)
 {
   struct dtv_pointer result = allocate_dtv_entry
     (map->l_tls_align, map->l_tls_blocksize);
@@ -715,10 +715,10 @@ allocate_and_init (struct link_map *map)
 }
 
 
-struct link_map *
+struct link_map_private *
 _dl_update_slotinfo (unsigned long int req_modid, size_t new_gen)
 {
-  struct link_map *the_map = NULL;
+  struct link_map_private *the_map = NULL;
   dtv_t *dtv = THREAD_DTV ();
 
   /* CONCURRENCY NOTES:
@@ -796,7 +796,7 @@ _dl_update_slotinfo (unsigned long int req_modid, size_t new_gen)
 	      /* Case (3) or (1).  */
 
 	      /* If there is no map this means the entry is empty.  */
-	      struct link_map *map
+	      struct link_map_private *map
 		= atomic_load_relaxed (&listp->slotinfo[cnt].map);
 	      /* Check whether the current dtv array is large enough.  */
 	      if (dtv[-1].counter < modid)
@@ -850,7 +850,7 @@ _dl_update_slotinfo (unsigned long int req_modid, size_t new_gen)
 
 static void *
 __attribute_noinline__
-tls_get_addr_tail (GET_ADDR_ARGS, dtv_t *dtv, struct link_map *the_map)
+tls_get_addr_tail (GET_ADDR_ARGS, dtv_t *dtv, struct link_map_private *the_map)
 {
   /* The allocation was deferred.  Do it now.  */
   if (the_map == NULL)
@@ -909,11 +909,11 @@ tls_get_addr_tail (GET_ADDR_ARGS, dtv_t *dtv, struct link_map *the_map)
 }
 
 
-static struct link_map *
+static struct link_map_private *
 __attribute_noinline__
 update_get_addr (GET_ADDR_ARGS, size_t gen)
 {
-  struct link_map *the_map = _dl_update_slotinfo (GET_ADDR_MODULE, gen);
+  struct link_map_private *the_map = _dl_update_slotinfo (GET_ADDR_MODULE, gen);
   dtv_t *dtv = THREAD_DTV ();
 
   void *p = dtv[GET_ADDR_MODULE].pointer.val;
@@ -968,7 +968,7 @@ __tls_get_addr (GET_ADDR_ARGS)
 /* Look up the module's TLS block as for __tls_get_addr,
    but never touch anything.  Return null if it's not allocated yet.  */
 void *
-_dl_tls_get_addr_soft (struct link_map *l)
+_dl_tls_get_addr_soft (struct link_map_private *l)
 {
   if (__glibc_unlikely (l->l_tls_modid == 0))
     /* This module has no TLS segment.  */
@@ -1013,7 +1013,7 @@ _dl_tls_get_addr_soft (struct link_map *l)
 
 
 void
-_dl_add_to_slotinfo (struct link_map *l, bool do_add)
+_dl_add_to_slotinfo (struct link_map_private *l, bool do_add)
 {
   /* Now that we know the object is loaded successfully add
      modules containing TLS data to the dtv info table.  We
@@ -1073,7 +1073,7 @@ cannot create TLS data structures"));
 
 #if PTHREAD_IN_LIBC
 static inline void __attribute__((always_inline))
-init_one_static_tls (struct pthread *curp, struct link_map *map)
+init_one_static_tls (struct pthread *curp, struct link_map_private *map)
 {
 # if TLS_TCB_AT_TP
   void *dest = (char *) curp - map->l_tls_offset;
@@ -1089,7 +1089,7 @@ init_one_static_tls (struct pthread *curp, struct link_map *map)
 }
 
 void
-_dl_init_static_tls (struct link_map *map)
+_dl_init_static_tls (struct link_map_private *map)
 {
   lll_lock (GL (dl_stack_cache_lock), LLL_PRIVATE);
 
diff --git a/elf/dl-unmap-segments.h b/elf/dl-unmap-segments.h
index 1ec507e887..f51b320777 100644
--- a/elf/dl-unmap-segments.h
+++ b/elf/dl-unmap-segments.h
@@ -27,7 +27,7 @@
    range in one fell swoop.  */
 
 static __always_inline void
-_dl_unmap_segments (struct link_map *l)
+_dl_unmap_segments (struct link_map_private *l)
 {
   __munmap ((void *) l->l_map_start, l->l_map_end - l->l_map_start);
 }
diff --git a/elf/dl-usage.c b/elf/dl-usage.c
index 04315451f2..dde0b2be53 100644
--- a/elf/dl-usage.c
+++ b/elf/dl-usage.c
@@ -90,7 +90,7 @@ print_search_path_for_help (struct dl_main_state *state)
   /* The print order should reflect the processing in
      _dl_map_object.  */
 
-  struct link_map *map = GL(dl_ns)[LM_ID_BASE]._ns_loaded;
+  struct link_map_private *map = GL(dl_ns)[LM_ID_BASE]._ns_loaded;
   if (map != NULL)
     print_search_path_for_help_1 (map->l_rpath_dirs.dirs);
 
diff --git a/elf/dl-version.c b/elf/dl-version.c
index b3b2160ac8..faad3fea16 100644
--- a/elf/dl-version.c
+++ b/elf/dl-version.c
@@ -26,20 +26,20 @@
 
 #include <assert.h>
 
-static inline struct link_map *
+static inline struct link_map_private *
 __attribute ((always_inline))
-find_needed (const char *name, struct link_map *map)
+find_needed (const char *name, struct link_map_private *map)
 {
-  struct link_map *tmap;
+  struct link_map_private *tmap;
 
   for (tmap = GL(dl_ns)[map->l_ns]._ns_loaded; tmap != NULL;
-       tmap = tmap->l_next)
+       tmap = l_next (tmap))
     if (_dl_name_match_p (name, tmap))
       return tmap;
 
   struct dl_exception exception;
   _dl_exception_create_format
-    (&exception, DSO_FILENAME (map->l_name),
+    (&exception, DSO_FILENAME (map->l_public.l_name),
      "missing soname %s in version dependency", name);
   _dl_signal_exception (0, &exception, NULL);
 }
@@ -47,7 +47,7 @@ find_needed (const char *name, struct link_map *map)
 
 static int
 match_symbol (const char *name, Lmid_t ns, ElfW(Word) hash, const char *string,
-	      struct link_map *map, int verbose, int weak)
+	      struct link_map_private *map, int verbose, int weak)
 {
   const char *strtab = (const void *) D_PTR (map, l_info[DT_STRTAB]);
   ElfW(Addr) def_offset;
@@ -60,7 +60,7 @@ match_symbol (const char *name, Lmid_t ns, ElfW(Word) hash, const char *string,
   if (__glibc_unlikely (GLRO(dl_debug_mask) & DL_DEBUG_VERSIONS))
     _dl_debug_printf ("\
 checking for version `%s' in file %s [%lu] required by file %s [%lu]\n",
-		      string, DSO_FILENAME (map->l_name),
+		      string, DSO_FILENAME (map->l_public.l_name),
 		      map->l_ns, name, ns);
 
   if (__glibc_unlikely (map->l_info[VERSYMIDX (DT_VERDEF)] == NULL))
@@ -72,7 +72,7 @@ checking for version `%s' in file %s [%lu] required by file %s [%lu]\n",
 	{
 	  /* XXX We cannot translate the messages.  */
 	  _dl_exception_create_format
-	    (&exception, DSO_FILENAME (map->l_name),
+	    (&exception, DSO_FILENAME (map->l_public.l_name),
 	     "no version information available (required by %s)", name);
 	  goto call_cerror;
 	}
@@ -82,7 +82,7 @@ checking for version `%s' in file %s [%lu] required by file %s [%lu]\n",
   def_offset = map->l_info[VERSYMIDX (DT_VERDEF)]->d_un.d_ptr;
   assert (def_offset != 0);
 
-  def = (ElfW(Verdef) *) ((char *) map->l_addr + def_offset);
+  def = (ElfW(Verdef) *) ((char *) map->l_public.l_addr + def_offset);
   while (1)
     {
       /* Currently the version number of the definition entry is 1.
@@ -93,7 +93,7 @@ checking for version `%s' in file %s [%lu] required by file %s [%lu]\n",
 	  buf[sizeof (buf) - 1] = '\0';
 	  /* XXX We cannot translate the message.  */
 	  _dl_exception_create_format
-	    (&exception, DSO_FILENAME (map->l_name),
+	    (&exception, DSO_FILENAME (map->l_public.l_name),
 	     "unsupported version %s of Verdef record",
 	     _itoa (def->vd_version, &buf[sizeof (buf) - 1], 10, 0));
 	  result = 1;
@@ -127,7 +127,7 @@ checking for version `%s' in file %s [%lu] required by file %s [%lu]\n",
 	{
 	  /* XXX We cannot translate the message.  */
 	  _dl_exception_create_format
-	    (&exception, DSO_FILENAME (map->l_name),
+	    (&exception, DSO_FILENAME (map->l_public.l_name),
 	     "weak version `%s' not found (required by %s)", string, name);
 	  goto call_cerror;
 	}
@@ -136,7 +136,7 @@ checking for version `%s' in file %s [%lu] required by file %s [%lu]\n",
 
   /* XXX We cannot translate the message.  */
   _dl_exception_create_format
-    (&exception, DSO_FILENAME (map->l_name),
+    (&exception, DSO_FILENAME (map->l_public.l_name),
      "version `%s' not found (required by %s)", string, name);
   result = 1;
  call_cerror:
@@ -147,7 +147,7 @@ checking for version `%s' in file %s [%lu] required by file %s [%lu]\n",
 
 
 int
-_dl_check_map_versions (struct link_map *map, int verbose, int trace_mode)
+_dl_check_map_versions (struct link_map_private *map, int verbose, int trace_mode)
 {
   int result = 0;
   const char *strtab;
@@ -173,7 +173,8 @@ _dl_check_map_versions (struct link_map *map, int verbose, int trace_mode)
   if (dyn != NULL)
     {
       /* This file requires special versions from its dependencies.  */
-      ElfW(Verneed) *ent = (ElfW(Verneed) *) (map->l_addr + dyn->d_un.d_ptr);
+      ElfW(Verneed) *ent = (ElfW(Verneed) *) (map->l_public.l_addr
+					      + dyn->d_un.d_ptr);
 
       /* Currently the version number of the needed entry is 1.
 	 Make sure all we see is this version.  */
@@ -183,7 +184,7 @@ _dl_check_map_versions (struct link_map *map, int verbose, int trace_mode)
 	  buf[sizeof (buf) - 1] = '\0';
 	  /* XXX We cannot translate the message.  */
 	  _dl_exception_create_format
-	    (&exception, DSO_FILENAME (map->l_name),
+	    (&exception, DSO_FILENAME (map->l_public.l_name),
 	     "unsupported version %s of Verneed record",
 	     _itoa (ent->vn_version, &buf[sizeof (buf) - 1], 10, 0));
 	call_error:
@@ -193,7 +194,7 @@ _dl_check_map_versions (struct link_map *map, int verbose, int trace_mode)
       while (1)
 	{
 	  ElfW(Vernaux) *aux;
-	  struct link_map *needed = find_needed (strtab + ent->vn_file, map);
+	  struct link_map_private *needed = find_needed (strtab + ent->vn_file, map);
 
 	  /* Make sure this is no stub we created because of a missing
 	     dependency.  */
@@ -207,7 +208,7 @@ _dl_check_map_versions (struct link_map *map, int verbose, int trace_mode)
 		{
 		  /* Match the symbol.  */
 		  const char *string = strtab + aux->vna_name;
-		  result |= match_symbol (DSO_FILENAME (map->l_name),
+		  result |= match_symbol (DSO_FILENAME (map->l_public.l_name),
 					  map->l_ns, aux->vna_hash,
 					  string, needed->l_real, verbose,
 					  aux->vna_flags & VER_FLG_WEAK);
@@ -249,7 +250,7 @@ _dl_check_map_versions (struct link_map *map, int verbose, int trace_mode)
   if (def != NULL)
     {
       ElfW(Verdef) *ent;
-      ent = (ElfW(Verdef) *) (map->l_addr + def->d_un.d_ptr);
+      ent = (ElfW(Verdef) *) (map->l_public.l_addr + def->d_un.d_ptr);
       while (1)
 	{
 	  if ((unsigned int) (ent->vd_ndx & 0x7fff) > ndx_high)
@@ -273,7 +274,7 @@ _dl_check_map_versions (struct link_map *map, int verbose, int trace_mode)
       if (__glibc_unlikely (map->l_versions == NULL))
 	{
 	  _dl_exception_create
-	    (&exception, DSO_FILENAME (map->l_name),
+	    (&exception, DSO_FILENAME (map->l_public.l_name),
 	     N_("cannot allocate version reference table"));
 	  errval = ENOMEM;
 	  goto call_error;
@@ -288,7 +289,7 @@ _dl_check_map_versions (struct link_map *map, int verbose, int trace_mode)
       if (dyn != NULL)
 	{
 	  ElfW(Verneed) *ent;
-	  ent = (ElfW(Verneed) *) (map->l_addr + dyn->d_un.d_ptr);
+	  ent = (ElfW(Verneed) *) (map->l_public.l_addr + dyn->d_un.d_ptr);
 	  while (1)
 	    {
 	      ElfW(Vernaux) *aux;
@@ -326,7 +327,7 @@ _dl_check_map_versions (struct link_map *map, int verbose, int trace_mode)
       if (def != NULL)
 	{
 	  ElfW(Verdef) *ent;
-	  ent = (ElfW(Verdef)  *) (map->l_addr + def->d_un.d_ptr);
+	  ent = (ElfW(Verdef)  *) (map->l_public.l_addr + def->d_un.d_ptr);
 	  while (1)
 	    {
 	      ElfW(Verdaux) *aux;
@@ -361,14 +362,14 @@ _dl_check_map_versions (struct link_map *map, int verbose, int trace_mode)
     {
       const char *strtab = (const void *) D_PTR (map, l_info[DT_STRTAB]);
       const ElfW(Dyn) *d;
-      for (d = map->l_ld; d->d_tag != DT_NULL; ++d)
+      for (d = map->l_public.l_ld; d->d_tag != DT_NULL; ++d)
 	if (d->d_tag == DT_NEEDED)
 	  {
 	    const char *name = strtab + d->d_un.d_val;
 	    if (strncmp (name, "libc.so.", 8) == 0)
 	      {
 		_dl_exception_create
-		  (&exception, DSO_FILENAME (map->l_name),
+		  (&exception, DSO_FILENAME (map->l_public.l_name),
 		   N_("DT_RELR without GLIBC_ABI_DT_RELR dependency"));
 		goto call_error;
 	      }
@@ -380,12 +381,13 @@ _dl_check_map_versions (struct link_map *map, int verbose, int trace_mode)
 
 
 int
-_dl_check_all_versions (struct link_map *map, int verbose, int trace_mode)
+_dl_check_all_versions (struct link_map_private *map, int verbose,
+			int trace_mode)
 {
-  struct link_map *l;
+  struct link_map_private *l;
   int result = 0;
 
-  for (l = map; l != NULL; l = l->l_next)
+  for (l = map; l != NULL; l = l_next (l))
     result |= (! l->l_faked
 	       && _dl_check_map_versions (l, verbose, trace_mode));
 
diff --git a/elf/do-rel.h b/elf/do-rel.h
index ea973b155a..8083cb4162 100644
--- a/elf/do-rel.h
+++ b/elf/do-rel.h
@@ -40,7 +40,7 @@
    than fully resolved now.  */
 
 static inline void __attribute__ ((always_inline))
-elf_dynamic_do_Rel (struct link_map *map, struct r_scope_elem *scope[],
+elf_dynamic_do_Rel (struct link_map_private *map, struct r_scope_elem *scope[],
 		    ElfW(Addr) reladdr, ElfW(Addr) relsize,
 		    __typeof (((ElfW(Dyn) *) 0)->d_un.d_val) nrelative,
 		    int lazy, int skip_ifunc)
@@ -48,7 +48,7 @@ elf_dynamic_do_Rel (struct link_map *map, struct r_scope_elem *scope[],
   const ElfW(Rel) *relative = (const void *) reladdr;
   const ElfW(Rel) *r = relative + nrelative;
   const ElfW(Rel) *end = (const void *) (reladdr + relsize);
-  ElfW(Addr) l_addr = map->l_addr;
+  ElfW(Addr) l_addr = map->l_public.l_addr;
   const ElfW(Sym) *const symtab
       = (const void *) D_PTR (map, l_info[DT_SYMTAB]);
 
@@ -150,7 +150,7 @@ elf_dynamic_do_Rel (struct link_map *map, struct r_scope_elem *scope[],
 	      if (ELFW(R_TYPE) (r->r_info) == ELF_MACHINE_JMP_SLOT
 		  && GLRO(dl_naudit) > 0)
 		{
-		  struct link_map *sym_map
+		  struct link_map_private *sym_map
 		    = RESOLVE_MAP (map, scope, &sym, rversion,
 				   ELF_MACHINE_JMP_SLOT);
 		  if (sym != NULL)
@@ -196,7 +196,7 @@ elf_dynamic_do_Rel (struct link_map *map, struct r_scope_elem *scope[],
 	      if (ELFW(R_TYPE) (r->r_info) == ELF_MACHINE_JMP_SLOT
 		  && GLRO(dl_naudit) > 0)
 		{
-		  struct link_map *sym_map
+		  struct link_map_private *sym_map
 		    = RESOLVE_MAP (map, scope, &sym,
 				   (struct r_found_version *) NULL,
 				   ELF_MACHINE_JMP_SLOT);
diff --git a/elf/dynamic-link.h b/elf/dynamic-link.h
index e7f755fc75..2f72240b6a 100644
--- a/elf/dynamic-link.h
+++ b/elf/dynamic-link.h
@@ -32,7 +32,7 @@
    unaligned cases.  */
 # if ! ELF_MACHINE_NO_REL
 static inline void __attribute__((always_inline))
-elf_machine_rel (struct link_map *map, struct r_scope_elem *scope[],
+elf_machine_rel (struct link_map_private *map, struct r_scope_elem *scope[],
 		 const ElfW(Rel) *reloc, const ElfW(Sym) *sym,
 		 const struct r_found_version *version,
 		 void *const reloc_addr, int skip_ifunc);
@@ -42,7 +42,7 @@ elf_machine_rel_relative (ElfW(Addr) l_addr, const ElfW(Rel) *reloc,
 # endif
 # if ! ELF_MACHINE_NO_RELA
 static inline void __attribute__((always_inline))
-elf_machine_rela (struct link_map *map, struct r_scope_elem *scope[],
+elf_machine_rela (struct link_map_private *map, struct r_scope_elem *scope[],
 		  const ElfW(Rela) *reloc, const ElfW(Sym) *sym,
 		  const struct r_found_version *version, void *const reloc_addr,
 		  int skip_ifunc);
@@ -52,12 +52,14 @@ elf_machine_rela_relative (ElfW(Addr) l_addr, const ElfW(Rela) *reloc,
 # endif
 # if ELF_MACHINE_NO_RELA || defined ELF_MACHINE_PLT_REL
 static inline void __attribute__((always_inline))
-elf_machine_lazy_rel (struct link_map *map, struct r_scope_elem *scope[],
+elf_machine_lazy_rel (struct link_map_private *map,
+		      struct r_scope_elem *scope[],
 		      ElfW(Addr) l_addr, const ElfW(Rel) *reloc,
 		      int skip_ifunc);
 # else
 static inline void __attribute__((always_inline))
-elf_machine_lazy_rel (struct link_map *map, struct r_scope_elem *scope[],
+elf_machine_lazy_rel (struct link_map_private *map,
+		      struct r_scope_elem *scope[],
 		      ElfW(Addr) l_addr, const ElfW(Rela) *reloc,
 		      int skip_ifunc);
 # endif
@@ -152,7 +154,7 @@ elf_machine_lazy_rel (struct link_map *map, struct r_scope_elem *scope[],
 
 # define ELF_DYNAMIC_DO_RELR(map)					      \
   do {									      \
-    ElfW(Addr) l_addr = (map)->l_addr, *where = 0;			      \
+    ElfW(Addr) l_addr = (map)->l_public.l_addr, *where = 0;		      \
     const ElfW(Relr) *r, *end;						      \
     if ((map)->l_info[DT_RELR] == NULL)					      \
       break;								      \
diff --git a/elf/get-dynamic-info.h b/elf/get-dynamic-info.h
index 1e458420c0..066395eab5 100644
--- a/elf/get-dynamic-info.h
+++ b/elf/get-dynamic-info.h
@@ -26,7 +26,7 @@
 #include <libc-diag.h>
 
 static inline void __attribute__ ((unused, always_inline))
-elf_get_dynamic_info (struct link_map *l, bool bootstrap,
+elf_get_dynamic_info (struct link_map_private *l, bool bootstrap,
 		      bool static_pie_bootstrap)
 {
 #if __ELF_NATIVE_CLASS == 32
@@ -36,13 +36,13 @@ elf_get_dynamic_info (struct link_map *l, bool bootstrap,
 #endif
 
 #ifndef STATIC_PIE_BOOTSTRAP
-  if (!bootstrap && l->l_ld == NULL)
+  if (!bootstrap && l->l_public.l_ld == NULL)
     return;
 #endif
 
   ElfW(Dyn) **info = l->l_info;
 
-  for (ElfW(Dyn) *dyn = l->l_ld; dyn->d_tag != DT_NULL; dyn++)
+  for (ElfW(Dyn) *dyn = l->l_public.l_ld; dyn->d_tag != DT_NULL; dyn++)
     {
       d_tag_utype i;
 
@@ -69,9 +69,9 @@ elf_get_dynamic_info (struct link_map *l, bool bootstrap,
     }
 
   /* Don't adjust .dynamic unnecessarily.  */
-  if (l->l_addr != 0 && dl_relocate_ld (l))
+  if (l->l_public.l_addr != 0 && dl_relocate_ld (l))
     {
-      ElfW(Addr) l_addr = l->l_addr;
+      ElfW(Addr) l_addr = l->l_public.l_addr;
 
 # define ADJUST_DYN_INFO(tag) \
       do								      \
diff --git a/elf/libc-early-init.h b/elf/libc-early-init.h
index e3e9dcd4f5..318630dc1d 100644
--- a/elf/libc-early-init.h
+++ b/elf/libc-early-init.h
@@ -19,12 +19,12 @@
 #ifndef _LIBC_EARLY_INIT_H
 #define _LIBC_EARLY_INIT_H
 
-struct link_map;
+struct link_map_private;
 
 /* If LIBC_MAP is not NULL, look up the __libc_early_init symbol in it
    and call this function, with INITIAL as the argument.  */
-void _dl_call_libc_early_init (struct link_map *libc_map, _Bool initial)
-  attribute_hidden;
+void _dl_call_libc_early_init (struct link_map_private *libc_map,
+                               _Bool initial) attribute_hidden;
 
 /* In the shared case, this function is defined in libc.so and invoked
    from ld.so (or on the fist static dlopen) after complete relocation
diff --git a/elf/loadtest.c b/elf/loadtest.c
index b5eab5e93c..ca7b634347 100644
--- a/elf/loadtest.c
+++ b/elf/loadtest.c
@@ -70,15 +70,16 @@ static const struct
 
 #include <include/link.h>
 
-#define MAPS ((struct link_map *) _r_debug.r_map)
+#define MAPS (l_private (_r_debug.r_map))
 
 #define OUT							\
   do								\
     {								\
-      for (map = MAPS; map != NULL; map = map->l_next)		\
+      for (map = MAPS; map != NULL; map = l_next (map))		\
 	if (map->l_type == lt_loaded)				\
 	  printf ("name = \"%s\", direct_opencount = %d\n",	\
-		  map->l_name, (int) map->l_direct_opencount);	\
+		  map->l_public.l_name,				\
+		  (int) map->l_direct_opencount);		\
       fflush (stdout);						\
     }								\
   while (0)
@@ -90,7 +91,7 @@ main (int argc, char *argv[])
   int debug = argc > 1 && argv[1][0] != '\0';
   int count = TEST_ROUNDS;
   int result = 0;
-  struct link_map *map;
+  struct link_map_private *map;
 
   mtrace ();
 
@@ -153,13 +154,15 @@ main (int argc, char *argv[])
 	    {
 	      /* In this case none of the objects above should be
 		 present.  */
-	      for (map = MAPS; map != NULL; map = map->l_next)
+	      for (map = MAPS; map != NULL; map = l_next (map))
 		if (map->l_type == lt_loaded
-		    && (strstr (map->l_name, testobjs[0].name) != NULL
-			|| strstr (map->l_name, testobjs[1].name) != NULL
-			|| strstr (map->l_name, testobjs[5].name) != NULL))
+		    && (strstr (map->l_public.l_name, testobjs[0].name) != NULL
+			|| strstr (map->l_public.l_name,
+				   testobjs[1].name) != NULL
+			|| strstr (map->l_public.l_name,
+				   testobjs[5].name) != NULL))
 		  {
-		    printf ("`%s' is still loaded\n", map->l_name);
+		    printf ("`%s' is still loaded\n", map->l_public.l_name);
 		    result = 1;
 		  }
 	    }
@@ -173,10 +176,9 @@ main (int argc, char *argv[])
   for (count = 0; count < (int) NOBJS; ++count)
     if (testobjs[count].handle != NULL)
       {
+	struct link_map_private *l = testobjs[count].handle;
 	printf ("\nclose: %s: l_initfini = %p, l_versions = %p\n",
-		testobjs[count].name,
-		((struct link_map *) testobjs[count].handle)->l_initfini,
-		((struct link_map *) testobjs[count].handle)->l_versions);
+		testobjs[count].name, l->l_initfini, l->l_versions);
 
 	if (dlclose (testobjs[count].handle) != 0)
 	  {
@@ -186,11 +188,11 @@ main (int argc, char *argv[])
       }
 
   /* Check whether all files are unloaded.  */
-  for (map = MAPS; map != NULL; map = map->l_next)
+  for (map = MAPS; map != NULL; map = l_next (map))
     if (map->l_type == lt_loaded)
       {
 	printf ("name = \"%s\", direct_opencount = %d\n",
-		map->l_name, (int) map->l_direct_opencount);
+		map->l_public.l_name, (int) map->l_direct_opencount);
 	result = 1;
       }
 
diff --git a/elf/neededtest.c b/elf/neededtest.c
index 3cea499314..1fce50b81a 100644
--- a/elf/neededtest.c
+++ b/elf/neededtest.c
@@ -5,12 +5,12 @@
 #include <stdlib.h>
 #include <string.h>
 
-#define MAPS ((struct link_map *) _r_debug.r_map)
+#define MAPS (l_private (_r_debug.r_map))
 
 static int
 check_loaded_objects (const char **loaded)
 {
-  struct link_map *lm;
+  struct link_map_private *lm;
   int n;
   int *found = NULL;
   int errors = 0;
@@ -26,16 +26,19 @@ check_loaded_objects (const char **loaded)
 
   printf("   Name\n");
   printf(" --------------------------------------------------------\n");
-  for (lm = MAPS; lm; lm = lm->l_next)
+  for (lm = MAPS; lm; lm = l_next (lm))
     {
-      if (lm->l_name && lm->l_name[0])
-	printf(" %s, count = %d\n", lm->l_name, (int) lm->l_direct_opencount);
-      if (lm->l_type == lt_loaded && lm->l_name)
+      if (lm->l_public.l_name && lm->l_public.l_name[0])
+	printf(" %s, count = %d\n",
+	       lm->l_public.l_name,
+	       (int) lm->l_direct_opencount);
+      if (lm->l_type == lt_loaded && lm->l_public.l_name)
 	{
 	  int match = 0;
 	  for (n = 0; loaded[n] != NULL; n++)
 	    {
-	      if (strcmp (basename (loaded[n]), basename (lm->l_name)) == 0)
+	      if (strcmp (basename (loaded[n]),
+			  basename (lm->l_public.l_name)) == 0)
 	        {
 		  found[n] = 1;
 		  match = 1;
@@ -46,7 +49,7 @@ check_loaded_objects (const char **loaded)
 	  if (match == 0)
 	    {
 	      ++errors;
-	      printf ("ERRORS: %s is not unloaded\n", lm->l_name);
+	      printf ("ERRORS: %s is not unloaded\n", lm->l_public.l_name);
 	    }
 	}
     }
diff --git a/elf/neededtest2.c b/elf/neededtest2.c
index 17c75f2ba3..00b5dd0cb1 100644
--- a/elf/neededtest2.c
+++ b/elf/neededtest2.c
@@ -5,12 +5,12 @@
 #include <stdlib.h>
 #include <string.h>
 
-#define MAPS ((struct link_map *) _r_debug.r_map)
+#define MAPS (l_private (_r_debug.r_map))
 
 static int
 check_loaded_objects (const char **loaded)
 {
-  struct link_map *lm;
+  struct link_map_private *lm;
   int n;
   int *found = NULL;
   int errors = 0;
@@ -26,16 +26,18 @@ check_loaded_objects (const char **loaded)
 
   printf("   Name\n");
   printf(" --------------------------------------------------------\n");
-  for (lm = MAPS; lm; lm = lm->l_next)
+  for (lm = MAPS; lm; lm = l_next (lm))
     {
-      if (lm->l_name && lm->l_name[0])
-	printf(" %s, count = %d\n", lm->l_name, (int) lm->l_direct_opencount);
-      if (lm->l_type == lt_loaded && lm->l_name)
+      if (lm->l_public.l_name && lm->l_public.l_name[0])
+	printf(" %s, count = %d\n",
+	       lm->l_public.l_name, (int) lm->l_direct_opencount);
+      if (lm->l_type == lt_loaded && lm->l_public.l_name)
 	{
 	  int match = 0;
 	  for (n = 0; loaded[n] != NULL; n++)
 	    {
-	      if (strcmp (basename (loaded[n]), basename (lm->l_name)) == 0)
+	      if (strcmp (basename (loaded[n]),
+			  basename (lm->l_public.l_name)) == 0)
 	        {
 		  found[n] = 1;
 		  match = 1;
@@ -46,7 +48,7 @@ check_loaded_objects (const char **loaded)
 	  if (match == 0)
 	    {
 	      ++errors;
-	      printf ("ERRORS: %s is not unloaded\n", lm->l_name);
+	      printf ("ERRORS: %s is not unloaded\n", lm->l_public.l_name);
 	    }
 	}
     }
diff --git a/elf/neededtest3.c b/elf/neededtest3.c
index 41970cf2c7..cb625649fa 100644
--- a/elf/neededtest3.c
+++ b/elf/neededtest3.c
@@ -5,12 +5,12 @@
 #include <stdlib.h>
 #include <string.h>
 
-#define MAPS ((struct link_map *) _r_debug.r_map)
+#define MAPS (l_private (_r_debug.r_map))
 
 static int
 check_loaded_objects (const char **loaded)
 {
-  struct link_map *lm;
+  struct link_map_private *lm;
   int n;
   int *found = NULL;
   int errors = 0;
@@ -26,16 +26,18 @@ check_loaded_objects (const char **loaded)
 
   printf("   Name\n");
   printf(" --------------------------------------------------------\n");
-  for (lm = MAPS; lm; lm = lm->l_next)
+  for (lm = MAPS; lm; lm = l_next (lm))
     {
-      if (lm->l_name && lm->l_name[0])
-	printf(" %s, count = %d\n", lm->l_name, (int) lm->l_direct_opencount);
-      if (lm->l_type == lt_loaded && lm->l_name)
+      if (lm->l_public.l_name && lm->l_public.l_name[0])
+	printf(" %s, count = %d\n",
+	       lm->l_public.l_name, (int) lm->l_direct_opencount);
+      if (lm->l_type == lt_loaded && lm->l_public.l_name)
 	{
 	  int match = 0;
 	  for (n = 0; loaded[n] != NULL; n++)
 	    {
-	      if (strcmp (basename (loaded[n]), basename (lm->l_name)) == 0)
+	      if (strcmp (basename (loaded[n]),
+			  basename (lm->l_public.l_name)) == 0)
 	        {
 		  found[n] = 1;
 		  match = 1;
@@ -46,7 +48,7 @@ check_loaded_objects (const char **loaded)
 	  if (match == 0)
 	    {
 	      ++errors;
-	      printf ("ERRORS: %s is not unloaded\n", lm->l_name);
+	      printf ("ERRORS: %s is not unloaded\n", lm->l_public.l_name);
 	    }
 	}
     }
diff --git a/elf/neededtest4.c b/elf/neededtest4.c
index 0ae0b7ff47..9f5d5fcbc3 100644
--- a/elf/neededtest4.c
+++ b/elf/neededtest4.c
@@ -5,12 +5,12 @@
 #include <stdlib.h>
 #include <string.h>
 
-#define MAPS ((struct link_map *) _r_debug.r_map)
+#define MAPS (l_private (_r_debug.r_map))
 
 static int
 check_loaded_objects (const char **loaded)
 {
-  struct link_map *lm;
+  struct link_map_private *lm;
   int n;
   int *found = NULL;
   int errors = 0;
@@ -26,16 +26,18 @@ check_loaded_objects (const char **loaded)
 
   printf("   Name\n");
   printf(" --------------------------------------------------------\n");
-  for (lm = MAPS; lm; lm = lm->l_next)
+  for (lm = MAPS; lm; lm = l_next (lm))
     {
-      if (lm->l_name && lm->l_name[0])
-	printf(" %s, count = %d\n", lm->l_name, (int) lm->l_direct_opencount);
-      if (lm->l_type == lt_loaded && lm->l_name)
+      if (lm->l_public.l_name && lm->l_public.l_name[0])
+	printf(" %s, count = %d\n",
+	       lm->l_public.l_name, (int) lm->l_direct_opencount);
+      if (lm->l_type == lt_loaded && lm->l_public.l_name)
 	{
 	  int match = 0;
 	  for (n = 0; loaded[n] != NULL; n++)
 	    {
-	      if (strcmp (basename (loaded[n]), basename (lm->l_name)) == 0)
+	      if (strcmp (basename (loaded[n]),
+			  basename (lm->l_public.l_name)) == 0)
 		{
 		  found[n] = 1;
 		  match = 1;
@@ -46,7 +48,7 @@ check_loaded_objects (const char **loaded)
 	  if (match == 0)
 	    {
 	      ++errors;
-	      printf ("ERRORS: %s is not unloaded\n", lm->l_name);
+	      printf ("ERRORS: %s is not unloaded\n", lm->l_public.l_name);
 	    }
 	}
     }
diff --git a/elf/rtld.c b/elf/rtld.c
index 05cbcee24a..92d8fa6fd4 100644
--- a/elf/rtld.c
+++ b/elf/rtld.c
@@ -139,7 +139,7 @@ static void audit_list_add_string (struct audit_list *, const char *);
    segment at TG (either DT_AUDIT and DT_DEPAUDIT).  Must be called
    before audit_list_next.  */
 static void audit_list_add_dynamic_tag (struct audit_list *,
-					struct link_map *,
+					struct link_map_private *,
 					unsigned int tag);
 
 /* Extract the next audit module from the audit list.  Only modules
@@ -218,8 +218,8 @@ audit_list_add_string (struct audit_list *list, const char *string)
 }
 
 static void
-audit_list_add_dynamic_tag (struct audit_list *list, struct link_map *main_map,
-			    unsigned int tag)
+audit_list_add_dynamic_tag (struct audit_list *list,
+			    struct link_map_private *main_map, unsigned int tag)
 {
   ElfW(Dyn) *info = main_map->l_info[ADDRIDX (tag)];
   const char *strtab = (const char *) D_PTR (main_map, l_info[DT_STRTAB]);
@@ -417,7 +417,7 @@ static ElfW(Addr) _dl_start_final (void *arg);
 #else
 struct dl_start_final_info
 {
-  struct link_map l;
+  struct link_map_private l;
   RTLD_TIMING_VAR (start_time);
 };
 static ElfW(Addr) _dl_start_final (void *arg,
@@ -466,8 +466,8 @@ _dl_start_final (void *arg, struct dl_start_final_info *info)
 
   /* Transfer data about ourselves to the permanent link_map structure.  */
 #ifndef DONT_USE_BOOTSTRAP_MAP
-  GL(dl_rtld_map).l_addr = info->l.l_addr;
-  GL(dl_rtld_map).l_ld = info->l.l_ld;
+  GL(dl_rtld_map).l_public.l_addr = info->l.l_public.l_addr;
+  GL(dl_rtld_map).l_public.l_ld = info->l.l_public.l_ld;
   GL(dl_rtld_map).l_ld_readonly = info->l.l_ld_readonly;
   memcpy (GL(dl_rtld_map).l_info, info->l.l_info,
 	  sizeof GL(dl_rtld_map).l_info);
@@ -541,10 +541,11 @@ _dl_start (void *arg)
 #endif
 
   /* Figure out the run-time load address of the dynamic linker itself.  */
-  bootstrap_map.l_addr = elf_machine_load_address ();
+  bootstrap_map.l_public.l_addr = elf_machine_load_address ();
 
   /* Read our own dynamic section and fill in the info array.  */
-  bootstrap_map.l_ld = (void *) bootstrap_map.l_addr + elf_machine_dynamic ();
+  bootstrap_map.l_public.l_ld
+    = (void *) bootstrap_map.l_public.l_addr + elf_machine_dynamic ();
   bootstrap_map.l_ld_readonly = DL_RO_DYN_SECTION;
   elf_get_dynamic_info (&bootstrap_map, true, false);
 
@@ -556,7 +557,7 @@ _dl_start (void *arg)
   ELF_MACHINE_BEFORE_RTLD_RELOC (&bootstrap_map, bootstrap_map.l_info);
 #endif
 
-  if (bootstrap_map.l_addr)
+  if (bootstrap_map.l_public.l_addr)
     {
       /* Relocate ourselves so we can do normal function calls and
 	 data access using the global offset table.  */
@@ -593,7 +594,7 @@ _dl_start (void *arg)
 /* Arguments to relocate_doit.  */
 struct relocate_args
 {
-  struct link_map *l;
+  struct link_map_private *l;
   int reloc_mode;
 };
 
@@ -601,22 +602,22 @@ struct map_args
 {
   /* Argument to map_doit.  */
   const char *str;
-  struct link_map *loader;
+  struct link_map_private *loader;
   int mode;
   /* Return value of map_doit.  */
-  struct link_map *map;
+  struct link_map_private *map;
 };
 
 struct dlmopen_args
 {
   const char *fname;
-  struct link_map *map;
+  struct link_map_private *map;
 };
 
 struct lookup_args
 {
   const char *name;
-  struct link_map *map;
+  struct link_map_private *map;
   void *result;
 };
 
@@ -679,7 +680,7 @@ version_check_doit (void *a)
 }
 
 
-static inline struct link_map *
+static inline struct link_map_private *
 find_needed (const char *name)
 {
   struct r_scope_elem *scope = &GL(dl_ns)[LM_ID_BASE]._ns_loaded->l_searchlist;
@@ -694,7 +695,7 @@ find_needed (const char *name)
 }
 
 static int
-match_version (const char *string, struct link_map *map)
+match_version (const char *string, struct link_map_private *map)
 {
   const char *strtab = (const void *) D_PTR (map, l_info[DT_STRTAB]);
   ElfW(Verdef) *def;
@@ -704,7 +705,7 @@ match_version (const char *string, struct link_map *map)
     /* The file has no symbol versioning.  */
     return 0;
 
-  def = (ElfW(Verdef) *) ((char *) map->l_addr
+  def = (ElfW(Verdef) *) ((char *) map->l_public.l_addr
 			  + map->l_info[VERDEFTAG]->d_un.d_ptr);
   while (1)
     {
@@ -759,8 +760,8 @@ init_tls (size_t naudit)
      but the base one can be filled at this time.  */
   assert (GL(dl_ns)[LM_ID_BASE + 1]._ns_loaded == NULL);
   int i = 0;
-  for (struct link_map *l = GL(dl_ns)[LM_ID_BASE]._ns_loaded; l != NULL;
-       l = l->l_next)
+  for (struct link_map_private *l = GL(dl_ns)[LM_ID_BASE]._ns_loaded;
+       l != NULL; l = l_next (l))
     if (l->l_tls_blocksize != 0)
       {
 	/* This is a module with TLS data.  Store the map reference.
@@ -799,7 +800,8 @@ cannot allocate TLS data structures for initial thread\n");
 }
 
 static unsigned int
-do_preload (const char *fname, struct link_map *main_map, const char *where)
+do_preload (const char *fname, struct link_map_private *main_map,
+	    const char *where)
 {
   const char *objname;
   const char *err_str = NULL;
@@ -863,8 +865,8 @@ security_init (void)
    ignored since it is insecure.)  Return the number of preloads
    performed.   Ditto for --preload command argument.  */
 unsigned int
-handle_preload_list (const char *preloadlist, struct link_map *main_map,
-		     const char *where)
+handle_preload_list (const char *preloadlist,
+		     struct link_map_private *main_map, const char *where)
 {
   unsigned int npreloads = 0;
   const char *p = preloadlist;
@@ -897,7 +899,7 @@ handle_preload_list (const char *preloadlist, struct link_map *main_map,
    appropriate interfaces, or it expects a more recent version library
    version than what the dynamic linker provides.  */
 static void
-unload_audit_module (struct link_map *map, int original_tls_idx)
+unload_audit_module (struct link_map_private *map, int original_tls_idx)
 {
 #ifndef NDEBUG
   Lmid_t ns = map->l_ns;
@@ -970,7 +972,7 @@ load_audit_module (const char *name, struct audit_ifaces **last_audit)
       if (GLRO(dl_debug_mask) & DL_DEBUG_FILES)
 	_dl_debug_printf ("\
 file=%s [%lu]; audit interface function la_version returned zero; ignored.\n",
-			  dlmargs.map->l_name, dlmargs.map->l_ns);
+			  dlmargs.map->l_public.l_name, dlmargs.map->l_ns);
       unload_audit_module (dlmargs.map, original_tls_idx);
       return;
     }
@@ -1044,7 +1046,8 @@ ERROR: audit interface '%s' requires version %d (maximum supported version %d);
 
 /* Load all audit modules.  */
 static void
-load_audit_modules (struct link_map *main_map, struct audit_list *audit_list)
+load_audit_modules (struct link_map_private *main_map,
+		    struct audit_list *audit_list)
 {
   struct audit_ifaces *last_audit = NULL;
 
@@ -1068,7 +1071,7 @@ load_audit_modules (struct link_map *main_map, struct audit_list *audit_list)
 /* Check if the executable is not actually dynamically linked, and
    invoke it directly in that case.  */
 static void
-rtld_chain_load (struct link_map *main_map, char *argv0)
+rtld_chain_load (struct link_map_private *main_map, char *argv0)
 {
   /* The dynamic loader run against itself.  */
   const char *rtld_soname
@@ -1107,7 +1110,7 @@ rtld_chain_load (struct link_map *main_map, char *argv0)
 /* Called to complete the initialization of the link map for the main
    executable.  Returns true if there is a PT_INTERP segment.  */
 static bool
-rtld_setup_main_map (struct link_map *main_map)
+rtld_setup_main_map (struct link_map_private *main_map)
 {
   /* This have already been filled in right after _dl_new_object, or
      as part of _dl_map_object.  */
@@ -1144,12 +1147,13 @@ rtld_setup_main_map (struct link_map *main_map)
       {
       case PT_PHDR:
 	/* Find out the load address.  */
-	main_map->l_addr = (ElfW(Addr)) phdr - ph->p_vaddr;
+	main_map->l_public.l_addr = (ElfW(Addr)) phdr - ph->p_vaddr;
 	break;
       case PT_DYNAMIC:
 	/* This tells us where to find the dynamic section,
 	   which tells us everything we need to do.  */
-	main_map->l_ld = (void *) main_map->l_addr + ph->p_vaddr;
+	main_map->l_public.l_ld
+	  = (void *) main_map->l_public.l_addr + ph->p_vaddr;
 	main_map->l_ld_readonly = (ph->p_flags & PF_W) == 0;
 	break;
       case PT_INTERP:
@@ -1159,7 +1163,7 @@ rtld_setup_main_map (struct link_map *main_map)
 	   dlopen call or DT_NEEDED entry, for something that wants to link
 	   against the dynamic linker as a shared library, will know that
 	   the shared object is already loaded.  */
-	_dl_rtld_libname.name = ((const char *) main_map->l_addr
+	_dl_rtld_libname.name = ((const char *) main_map->l_public.l_addr
 				 + ph->p_vaddr);
 	/* _dl_rtld_libname.next = NULL;	Already zero.  */
 	GL(dl_rtld_map).l_libname = &_dl_rtld_libname;
@@ -1172,7 +1176,7 @@ rtld_setup_main_map (struct link_map *main_map)
 	  ElfW(Addr) allocend;
 
 	  /* Remember where the main program starts in memory.  */
-	  mapstart = (main_map->l_addr
+	  mapstart = (main_map->l_public.l_addr
 		      + (ph->p_vaddr & ~(GLRO(dl_pagesize) - 1)));
 	  if (main_map->l_map_start > mapstart)
 	    main_map->l_map_start = mapstart;
@@ -1182,7 +1186,7 @@ rtld_setup_main_map (struct link_map *main_map)
 	    main_map->l_contiguous = 0;
 
 	  /* Also where it ends.  */
-	  allocend = main_map->l_addr + ph->p_vaddr + ph->p_memsz;
+	  allocend = main_map->l_public.l_addr + ph->p_vaddr + ph->p_memsz;
 	  if (main_map->l_map_end < allocend)
 	    main_map->l_map_end = allocend;
 
@@ -1241,14 +1245,14 @@ rtld_setup_main_map (struct link_map *main_map)
      the executable is actually an ET_DYN object.  */
   if (main_map->l_tls_initimage != NULL)
     main_map->l_tls_initimage
-      = (char *) main_map->l_tls_initimage + main_map->l_addr;
+      = (char *) main_map->l_tls_initimage + main_map->l_public.l_addr;
   if (! main_map->l_map_end)
     main_map->l_map_end = ~0;
-  if (! GL(dl_rtld_map).l_libname && GL(dl_rtld_map).l_name)
+  if (! GL(dl_rtld_map).l_libname && GL(dl_rtld_map).l_public.l_name)
     {
       /* We were invoked directly, so the program might not have a
 	 PT_INTERP.  */
-      _dl_rtld_libname.name = GL(dl_rtld_map).l_name;
+      _dl_rtld_libname.name = GL(dl_rtld_map).l_public.l_name;
       /* _dl_rtld_libname.next = NULL;	Already zero.  */
       GL(dl_rtld_map).l_libname =  &_dl_rtld_libname;
     }
@@ -1320,7 +1324,7 @@ dl_main (const ElfW(Phdr) *phdr,
 	 ElfW(Addr) *user_entry,
 	 ElfW(auxv_t) *auxv)
 {
-  struct link_map *main_map;
+  struct link_map_private *main_map;
   size_t file_size;
   char *file;
   unsigned int i;
@@ -1370,7 +1374,7 @@ dl_main (const ElfW(Phdr) *phdr,
       char **orig_argv = _dl_argv;
 
       /* Note the place where the dynamic linker actually came from.  */
-      GL(dl_rtld_map).l_name = rtld_progname;
+      GL(dl_rtld_map).l_public.l_name = rtld_progname;
 
       while (_dl_argc > 1)
 	if (! strcmp (_dl_argv[1], "--list"))
@@ -1572,7 +1576,7 @@ dl_main (const ElfW(Phdr) *phdr,
 	 the malloc() implementation used at this point is the dummy
 	 implementations which has no real free() function it does not
 	 makes sense to free the old string first.  */
-      main_map->l_name = (char *) "";
+      main_map->l_public.l_name = (char *) "";
       *user_entry = main_map->l_entry;
 
       /* Set bit indicating this is the main program map.  */
@@ -1687,13 +1691,13 @@ dl_main (const ElfW(Phdr) *phdr,
 	 executable using us as the program interpreter.  Exit with an
 	 error if we were not able to load the binary or no interpreter
 	 is specified (i.e., this is no dynamically linked binary.  */
-      if (main_map->l_ld == NULL)
+      if (main_map->l_public.l_ld == NULL)
 	_exit (1);
 
       _exit (has_interp ? 0 : 2);
     }
 
-  struct link_map **first_preload = &GL(dl_rtld_map).l_next;
+  struct link_map **first_preload = &GL(dl_rtld_map).l_public.l_next;
   /* Set up the data structures for the system-supplied DSO early,
      so they can influence _dl_init_paths.  */
   setup_vdso (main_map, &first_preload);
@@ -1706,20 +1710,20 @@ dl_main (const ElfW(Phdr) *phdr,
   call_init_paths (&state);
 
   /* Initialize _r_debug_extended.  */
-  struct r_debug *r = _dl_debug_initialize (GL(dl_rtld_map).l_addr,
+  struct r_debug *r = _dl_debug_initialize (GL(dl_rtld_map).l_public.l_addr,
 					    LM_ID_BASE);
   r->r_state = RT_CONSISTENT;
 
   /* Put the link_map for ourselves on the chain so it can be found by
      name.  Note that at this point the global chain of link maps contains
      exactly one element, which is pointed to by dl_loaded.  */
-  if (! GL(dl_rtld_map).l_name)
+  if (! GL(dl_rtld_map).l_public.l_name)
     /* If not invoked directly, the dynamic linker shared object file was
        found by the PT_INTERP name.  */
-    GL(dl_rtld_map).l_name = (char *) GL(dl_rtld_map).l_libname->name;
+    GL(dl_rtld_map).l_public.l_name = (char *) GL(dl_rtld_map).l_libname->name;
   GL(dl_rtld_map).l_type = lt_library;
-  main_map->l_next = &GL(dl_rtld_map);
-  GL(dl_rtld_map).l_prev = main_map;
+  main_map->l_public.l_next = &GL(dl_rtld_map).l_public;
+  GL(dl_rtld_map).l_public.l_prev = &main_map->l_public;
   ++GL(dl_ns)[LM_ID_BASE]._ns_nloaded;
   ++GL(dl_load_adds);
 
@@ -1808,7 +1812,7 @@ dl_main (const ElfW(Phdr) *phdr,
      variable and via the file /etc/ld.so.preload.  The latter can also
      be used when security is enabled.  */
   assert (*first_preload == NULL);
-  struct link_map **preloads = NULL;
+  struct link_map_private **preloads = NULL;
   unsigned int npreloads = 0;
 
   if (__glibc_unlikely (state.preloadlist != NULL))
@@ -1920,7 +1924,7 @@ dl_main (const ElfW(Phdr) *phdr,
       i = 0;
       do
 	{
-	  preloads[i++] = l;
+	  preloads[i++] = l_private (l);
 	  l = l->l_next;
 	} while (l);
       assert (i == npreloads);
@@ -1948,9 +1952,9 @@ dl_main (const ElfW(Phdr) *phdr,
     main_map->l_searchlist.r_list[--i]->l_global = 1;
 
   /* Remove _dl_rtld_map from the chain.  */
-  GL(dl_rtld_map).l_prev->l_next = GL(dl_rtld_map).l_next;
-  if (GL(dl_rtld_map).l_next != NULL)
-    GL(dl_rtld_map).l_next->l_prev = GL(dl_rtld_map).l_prev;
+  GL(dl_rtld_map).l_public.l_prev->l_next = GL(dl_rtld_map).l_public.l_next;
+  if (GL(dl_rtld_map).l_public.l_next != NULL)
+    GL(dl_rtld_map).l_public.l_next->l_prev = GL(dl_rtld_map).l_public.l_prev;
 
   for (i = 1; i < main_map->l_searchlist.r_nlist; ++i)
     if (main_map->l_searchlist.r_list[i] == &GL(dl_rtld_map))
@@ -1965,17 +1969,21 @@ dl_main (const ElfW(Phdr) *phdr,
 	 its symbol search order.  */
       rtld_multiple_ref = true;
 
-      GL(dl_rtld_map).l_prev = main_map->l_searchlist.r_list[i - 1];
+      GL(dl_rtld_map).l_public.l_prev
+	= &main_map->l_searchlist.r_list[i - 1]->l_public;
       if (__glibc_likely (state.mode == rtld_mode_normal))
 	{
-	  GL(dl_rtld_map).l_next = (i + 1 < main_map->l_searchlist.r_nlist
-				    ? main_map->l_searchlist.r_list[i + 1]
-				    : NULL);
+	  GL(dl_rtld_map).l_public.l_next
+	    = (i + 1 < main_map->l_searchlist.r_nlist
+	       ? &main_map->l_searchlist.r_list[i + 1]->l_public
+	       : NULL);
 #ifdef NEED_DL_SYSINFO_DSO
 	  if (GLRO(dl_sysinfo_map) != NULL
-	      && GL(dl_rtld_map).l_prev->l_next == GLRO(dl_sysinfo_map)
-	      && GL(dl_rtld_map).l_next != GLRO(dl_sysinfo_map))
-	    GL(dl_rtld_map).l_prev = GLRO(dl_sysinfo_map);
+	      && (GL(dl_rtld_map).l_public.l_prev->l_next
+		  == &GLRO(dl_sysinfo_map)->l_public)
+	      && (GL(dl_rtld_map).l_public.l_next
+		  != &GLRO(dl_sysinfo_map)->l_public))
+	    GL(dl_rtld_map).l_public.l_prev = &GLRO(dl_sysinfo_map)->l_public;
 #endif
 	}
       else
@@ -1984,14 +1992,17 @@ dl_main (const ElfW(Phdr) *phdr,
 	   In this case it doesn't matter much where we put the
 	   interpreter object, so we just initialize the list pointer so
 	   that the assertion below holds.  */
-	GL(dl_rtld_map).l_next = GL(dl_rtld_map).l_prev->l_next;
+	GL(dl_rtld_map).l_public.l_next
+	  = GL(dl_rtld_map).l_public.l_prev->l_next;
 
-      assert (GL(dl_rtld_map).l_prev->l_next == GL(dl_rtld_map).l_next);
-      GL(dl_rtld_map).l_prev->l_next = &GL(dl_rtld_map);
-      if (GL(dl_rtld_map).l_next != NULL)
+      assert (GL(dl_rtld_map).l_public.l_prev->l_next
+	      == GL(dl_rtld_map).l_public.l_next);
+      GL(dl_rtld_map).l_public.l_prev->l_next = &GL(dl_rtld_map).l_public;
+      if (GL(dl_rtld_map).l_public.l_next != NULL)
 	{
-	  assert (GL(dl_rtld_map).l_next->l_prev == GL(dl_rtld_map).l_prev);
-	  GL(dl_rtld_map).l_next->l_prev = &GL(dl_rtld_map);
+	  assert (GL(dl_rtld_map).l_public.l_next->l_prev
+		  == GL(dl_rtld_map).l_public.l_prev);
+	  GL(dl_rtld_map).l_public.l_next->l_prev = &GL(dl_rtld_map).l_public;
 	}
     }
 
@@ -2026,14 +2037,14 @@ dl_main (const ElfW(Phdr) *phdr,
 	 important that we do this before real relocation, because the
 	 functions we call below for output may no longer work properly
 	 after relocation.  */
-      struct link_map *l;
+      struct link_map_private *l;
 
       if (GLRO(dl_debug_mask) & DL_DEBUG_UNUSED)
 	{
 	  /* Look through the dependencies of the main executable
 	     and determine which of them is not actually
 	     required.  */
-	  struct link_map *l = main_map;
+	  struct link_map_private *l = main_map;
 
 	  /* Relocate the main executable.  */
 	  struct relocate_args args = { .l = l,
@@ -2044,18 +2055,18 @@ dl_main (const ElfW(Phdr) *phdr,
 
 	  /* This loop depends on the dependencies of the executable to
 	     correspond in number and order to the DT_NEEDED entries.  */
-	  ElfW(Dyn) *dyn = main_map->l_ld;
+	  ElfW(Dyn) *dyn = main_map->l_public.l_ld;
 	  bool first = true;
 	  while (dyn->d_tag != DT_NULL)
 	    {
 	      if (dyn->d_tag == DT_NEEDED)
 		{
-		  l = l->l_next;
+		  l = l_next (l);
 #ifdef NEED_DL_SYSINFO_DSO
 		  /* Skip the VDSO since it's not part of the list
 		     of objects we brought in via DT_NEEDED entries.  */
 		  if (l == GLRO(dl_sysinfo_map))
-		    l = l->l_next;
+		    l = l_next (l);
 #endif
 		  if (!l->l_used)
 		    {
@@ -2065,7 +2076,7 @@ dl_main (const ElfW(Phdr) *phdr,
 			  first = false;
 			}
 
-		      _dl_printf ("\t%s\n", l->l_name);
+		      _dl_printf ("\t%s\n", l->l_public.l_name);
 		    }
 		}
 
@@ -2078,12 +2089,12 @@ dl_main (const ElfW(Phdr) *phdr,
 	_dl_printf ("\tstatically linked\n");
       else
 	{
-	  for (l = state.mode_trace_program ? main_map : main_map->l_next;
-	       l; l = l->l_next) {
+	  for (l = state.mode_trace_program ? main_map : l_next (main_map);
+	       l; l = l_next (l)) {
 	    if (l->l_faked)
 	      /* The library was not found.  */
 	      _dl_printf ("\t%s => not found\n",  l->l_libname->name);
-	    else if (strcmp (l->l_libname->name, l->l_name) == 0)
+	    else if (strcmp (l->l_libname->name, l->l_public.l_name) == 0)
 	      /* Print vDSO like libraries without duplicate name.  Some
 		 consumers depend of this format.  */
 	      _dl_printf ("\t%s (0x%0*zx)\n", l->l_libname->name,
@@ -2092,7 +2103,7 @@ dl_main (const ElfW(Phdr) *phdr,
 	    else
 	      _dl_printf ("\t%s => %s (0x%0*zx)\n",
 			  DSO_FILENAME (l->l_libname->name),
-			  DSO_FILENAME (l->l_name),
+			  DSO_FILENAME (l->l_public.l_name),
 			  (int) sizeof l->l_map_start * 2,
 			  (size_t) l->l_map_start);
 	  }
@@ -2133,7 +2144,7 @@ dl_main (const ElfW(Phdr) *phdr,
 	      i = main_map->l_searchlist.r_nlist;
 	      while (i-- > 0)
 		{
-		  struct link_map *l = main_map->l_initfini[i];
+		  struct link_map_private *l = main_map->l_initfini[i];
 		  if (l != &GL(dl_rtld_map) && ! l->l_faked)
 		    {
 		      args.l = l;
@@ -2149,9 +2160,9 @@ dl_main (const ElfW(Phdr) *phdr,
 	      /* Print more information.  This means here, print information
 		 about the versions needed.  */
 	      int first = 1;
-	      struct link_map *map;
+	      struct link_map_private *map;
 
-	      for (map = main_map; map != NULL; map = map->l_next)
+	      for (map = main_map; map != NULL; map = l_next (map))
 		{
 		  const char *strtab;
 		  ElfW(Dyn) *dyn = map->l_info[VERNEEDTAG];
@@ -2161,7 +2172,8 @@ dl_main (const ElfW(Phdr) *phdr,
 		    continue;
 
 		  strtab = (const void *) D_PTR (map, l_info[DT_STRTAB]);
-		  ent = (ElfW(Verneed) *) (map->l_addr + dyn->d_un.d_ptr);
+		  ent = (ElfW(Verneed) *) (map->l_public.l_addr
+					   + dyn->d_un.d_ptr);
 
 		  if (first)
 		    {
@@ -2169,12 +2181,12 @@ dl_main (const ElfW(Phdr) *phdr,
 		      first = 0;
 		    }
 
-		  _dl_printf ("\t%s:\n", DSO_FILENAME (map->l_name));
+		  _dl_printf ("\t%s:\n", DSO_FILENAME (map->l_public.l_name));
 
 		  while (1)
 		    {
 		      ElfW(Vernaux) *aux;
-		      struct link_map *needed;
+		      struct link_map_private *needed;
 
 		      needed = find_needed (strtab + ent->vn_file);
 		      aux = (ElfW(Vernaux) *) ((char *) ent + ent->vn_aux);
@@ -2186,7 +2198,7 @@ dl_main (const ElfW(Phdr) *phdr,
 			  if (needed != NULL
 			      && match_version (strtab + aux->vna_name,
 						needed))
-			    fname = needed->l_name;
+			    fname = needed->l_public.l_name;
 
 			  _dl_printf ("\t\t%s (%s) %s=> %s\n",
 				      strtab + ent->vn_file,
@@ -2236,7 +2248,7 @@ dl_main (const ElfW(Phdr) *phdr,
     {
       _dl_debug_printf ("\nInitial object scopes\n");
 
-      for (struct link_map *l = main_map; l != NULL; l = l->l_next)
+      for (struct link_map_private *l = main_map; l != NULL; l = l_next (l))
 	_dl_show_scope (l, 0);
     }
 
@@ -2268,7 +2280,7 @@ dl_main (const ElfW(Phdr) *phdr,
     unsigned i = main_map->l_searchlist.r_nlist;
     while (i-- > 0)
       {
-	struct link_map *l = main_map->l_initfini[i];
+	struct link_map_private *l = main_map->l_initfini[i];
 
 	/* While we are at it, help the memory handling a bit.  We have to
 	   mark some data structures as allocated with the fake malloc()
@@ -2785,20 +2797,20 @@ print_statistics (const hp_timing_t *rtld_total_timep)
 
       for (unsigned int i = 0; i < scope->r_nlist; i++)
 	{
-	  struct link_map *l = scope->r_list [i];
+	  struct link_map_private *l = scope->r_list [i];
 
-	  if (l->l_addr != 0 && l->l_info[VERSYMIDX (DT_RELCOUNT)])
+	  if (l->l_public.l_addr != 0 && l->l_info[VERSYMIDX (DT_RELCOUNT)])
 	    num_relative_relocations
 	      += l->l_info[VERSYMIDX (DT_RELCOUNT)]->d_un.d_val;
 #ifndef ELF_MACHINE_REL_RELATIVE
 	  /* Relative relocations are processed on these architectures if
 	     library is loaded to different address than p_vaddr.  */
-	  if ((l->l_addr != 0)
+	  if ((l->l_public.l_addr != 0)
 	      && l->l_info[VERSYMIDX (DT_RELACOUNT)])
 #else
 	  /* On e.g. IA-64 or Alpha, relative relocations are processed
 	     only if library is loaded to different address than p_vaddr.  */
-	  if (l->l_addr != 0 && l->l_info[VERSYMIDX (DT_RELACOUNT)])
+	  if (l->l_public.l_addr != 0 && l->l_info[VERSYMIDX (DT_RELACOUNT)])
 #endif
 	    num_relative_relocations
 	      += l->l_info[VERSYMIDX (DT_RELACOUNT)]->d_un.d_val;
diff --git a/elf/rtld_static_init.c b/elf/rtld_static_init.c
index aec8cc056b..9ce92fa4fc 100644
--- a/elf/rtld_static_init.c
+++ b/elf/rtld_static_init.c
@@ -43,7 +43,7 @@ static const struct dlfcn_hook _dlfcn_hook =
   };
 
 void
-__rtld_static_init (struct link_map *map)
+__rtld_static_init (struct link_map_private *map)
 {
   const ElfW(Sym) *sym
     = _dl_lookup_direct (map, "_rtld_global_ro",
diff --git a/elf/setup-vdso.h b/elf/setup-vdso.h
index d92b12a7aa..5e9d2eb820 100644
--- a/elf/setup-vdso.h
+++ b/elf/setup-vdso.h
@@ -17,7 +17,7 @@
    <https://www.gnu.org/licenses/>.  */
 
 static inline void __attribute__ ((always_inline))
-setup_vdso (struct link_map *main_map __attribute__ ((unused)),
+setup_vdso (struct link_map_private *main_map __attribute__ ((unused)),
 	    struct link_map ***first_preload __attribute__ ((unused)))
 {
 #ifdef NEED_DL_SYSINFO_DSO
@@ -29,8 +29,8 @@ setup_vdso (struct link_map *main_map __attribute__ ((unused)),
      better be, since it's read-only and so we couldn't relocate it).
      We just want our data structures to describe it as if we had just
      mapped and relocated it normally.  */
-  struct link_map *l = _dl_new_object ((char *) "", "", lt_library, NULL,
-				       __RTLD_VDSO, LM_ID_BASE);
+  struct link_map_private *l = _dl_new_object ((char *) "", "", lt_library,
+					       NULL, __RTLD_VDSO, LM_ID_BASE);
   if (__glibc_likely (l != NULL))
     {
       l->l_phdr = ((const void *) GLRO(dl_sysinfo_dso)
@@ -41,14 +41,14 @@ setup_vdso (struct link_map *main_map __attribute__ ((unused)),
 	  const ElfW(Phdr) *const ph = &l->l_phdr[i];
 	  if (ph->p_type == PT_DYNAMIC)
 	    {
-	      l->l_ld = (void *) ph->p_vaddr;
+	      l->l_public.l_ld = (void *) ph->p_vaddr;
 	      l->l_ldnum = ph->p_memsz / sizeof (ElfW(Dyn));
 	      l->l_ld_readonly = (ph->p_flags & PF_W) == 0;
 	    }
 	  else if (ph->p_type == PT_LOAD)
 	    {
-	      if (! l->l_addr)
-		l->l_addr = ph->p_vaddr;
+	      if (! l->l_public.l_addr)
+		l->l_public.l_addr = ph->p_vaddr;
 	      if (ph->p_vaddr + ph->p_memsz >= l->l_map_end)
 		l->l_map_end = ph->p_vaddr + ph->p_memsz;
 	    }
@@ -57,9 +57,10 @@ setup_vdso (struct link_map *main_map __attribute__ ((unused)),
 	    assert (ph->p_type != PT_TLS);
 	}
       l->l_map_start = (ElfW(Addr)) GLRO(dl_sysinfo_dso);
-      l->l_addr = l->l_map_start - l->l_addr;
-      l->l_map_end += l->l_addr;
-      l->l_ld = (void *) ((ElfW(Addr)) l->l_ld + l->l_addr);
+      l->l_public.l_addr = l->l_map_start - l->l_public.l_addr;
+      l->l_map_end += l->l_public.l_addr;
+      l->l_public.l_ld = (void *) ((ElfW(Addr)) l->l_public.l_ld
+				   + l->l_public.l_addr);
       elf_get_dynamic_info (l, false, false);
       _dl_setup_hash (l);
       l->l_relocated = 1;
@@ -81,7 +82,7 @@ setup_vdso (struct link_map *main_map __attribute__ ((unused)),
 	  char *dsoname = ((char *) D_PTR (l, l_info[DT_STRTAB])
 			   + l->l_info[DT_SONAME]->d_un.d_val);
 	  l->l_libname->name = dsoname;
-	  l->l_name = dsoname;
+	  l->l_public.l_name = dsoname;
 	}
 
       /* Add the vDSO to the object list.  */
@@ -89,11 +90,11 @@ setup_vdso (struct link_map *main_map __attribute__ ((unused)),
 
 # if IS_IN (rtld)
       /* Rearrange the list so this DSO appears after rtld_map.  */
-      assert (l->l_next == NULL);
-      assert (l->l_prev == main_map);
-      GL(dl_rtld_map).l_next = l;
-      l->l_prev = &GL(dl_rtld_map);
-      *first_preload = &l->l_next;
+      assert (l->l_public.l_next == NULL);
+      assert (l->l_public.l_prev == &main_map->l_public);
+      GL(dl_rtld_map).l_public.l_next = &l->l_public;
+      l->l_public.l_prev = &GL(dl_rtld_map).l_public;
+      *first_preload = &l->l_public.l_next;
 # else
       GL(dl_nns) = 1;
 # endif
@@ -102,7 +103,7 @@ setup_vdso (struct link_map *main_map __attribute__ ((unused)),
       GLRO(dl_sysinfo_map) = l;
 # ifdef NEED_DL_SYSINFO
       if (GLRO(dl_sysinfo) == DL_SYSINFO_DEFAULT)
-	GLRO(dl_sysinfo) = GLRO(dl_sysinfo_dso)->e_entry + l->l_addr;
+	GLRO(dl_sysinfo) = GLRO(dl_sysinfo_dso)->e_entry + l->l_public.l_addr;
 # endif
     }
 #endif
diff --git a/elf/sotruss-lib.c b/elf/sotruss-lib.c
index 59aa6aa1b9..09232b1a4a 100644
--- a/elf/sotruss-lib.c
+++ b/elf/sotruss-lib.c
@@ -173,7 +173,8 @@ la_objopen (struct link_map *map, Lmid_t lmid, uintptr_t *cookie)
 
   int result = 0;
   const char *print_name = NULL;
-  for (struct libname_list *l = map->l_libname; l != NULL; l = l->next)
+  for (struct libname_list *l = l_private (map)->l_libname; l != NULL;
+       l = l->next)
     {
       if (print_name == NULL || (print_name[0] == '/' && l->name[0] != '/'))
 	print_name = l->name;
diff --git a/elf/sprof.c b/elf/sprof.c
index 3eaa4758d6..155da1bd03 100644
--- a/elf/sprof.c
+++ b/elf/sprof.c
@@ -169,7 +169,7 @@ struct shobj
 {
   const char *name;		/* User-provided name.  */
 
-  struct link_map *map;
+  struct link_map_private *map;
   const char *dynstrtab;	/* Dynamic string table of shared object.  */
   const char *soname;		/* Soname of shared object.  */
 
@@ -400,7 +400,7 @@ warranty; not even for MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.\n\
 static struct shobj *
 load_shobj (const char *name)
 {
-  struct link_map *map = NULL;
+  struct link_map_private *map = NULL;
   struct shobj *result;
   ElfW(Addr) mapstart = ~((ElfW(Addr)) 0);
   ElfW(Addr) mapend = 0;
@@ -422,11 +422,11 @@ load_shobj (const char *name)
       char *load_name = (char *) alloca (strlen (name) + 3);
       stpcpy (stpcpy (load_name, "./"), name);
 
-      map = (struct link_map *) dlopen (load_name, RTLD_LAZY | __RTLD_SPROF);
+      map = dlopen (load_name, RTLD_LAZY | __RTLD_SPROF);
     }
   if (map == NULL)
     {
-      map = (struct link_map *) dlopen (name, RTLD_LAZY | __RTLD_SPROF);
+      map = dlopen (name, RTLD_LAZY | __RTLD_SPROF);
       if (map == NULL)
 	{
 	  error (0, errno, _("failed to load shared object `%s'"), name);
@@ -460,15 +460,15 @@ load_shobj (const char *name)
 	  mapend = end;
       }
 
-  result->lowpc = ROUNDDOWN ((uintptr_t) (mapstart + map->l_addr),
+  result->lowpc = ROUNDDOWN ((uintptr_t) (mapstart + map->l_public.l_addr),
 			     HISTFRACTION * sizeof (HISTCOUNTER));
-  result->highpc = ROUNDUP ((uintptr_t) (mapend + map->l_addr),
+  result->highpc = ROUNDUP ((uintptr_t) (mapend + map->l_public.l_addr),
 			    HISTFRACTION * sizeof (HISTCOUNTER));
   if (do_test)
     printf ("load addr: %0#*" PRIxPTR "\n"
 	    "lower bound PC: %0#*" PRIxPTR "\n"
 	    "upper bound PC: %0#*" PRIxPTR "\n",
-	    __ELF_NATIVE_CLASS == 32 ? 10 : 18, map->l_addr,
+	    __ELF_NATIVE_CLASS == 32 ? 10 : 18, map->l_public.l_addr,
 	    __ELF_NATIVE_CLASS == 32 ? 10 : 18, result->lowpc,
 	    __ELF_NATIVE_CLASS == 32 ? 10 : 18, result->highpc);
 
@@ -547,11 +547,11 @@ load_shobj (const char *name)
     abort ();
 
   /* And we need the shared object file descriptor again.  */
-  fd = open (map->l_name, O_RDONLY);
+  fd = open (map->l_public.l_name, O_RDONLY);
   if (fd == -1)
     /* Dooh, this really shouldn't happen.  We know the file is available.  */
     error (EXIT_FAILURE, errno, _("Reopening shared object `%s' failed"),
-	   map->l_name);
+	   map->l_public.l_name);
 
   /* Map the section header.  */
   size_t size = ehdr->e_shnum * sizeof (ElfW(Shdr));
@@ -879,8 +879,8 @@ load_profdata (const char *name, struct shobj *shobj)
 	  != offsetof (struct gmon_hist_hdr, dimen_abbrev)))
     abort ();
 
-  hist_hdr.low_pc = (char *) shobj->lowpc - shobj->map->l_addr;
-  hist_hdr.high_pc = (char *) shobj->highpc - shobj->map->l_addr;
+  hist_hdr.low_pc = (char *) shobj->lowpc - shobj->map->l_public.l_addr;
+  hist_hdr.high_pc = (char *) shobj->highpc - shobj->map->l_public.l_addr;
   if (do_test)
     printf ("low_pc = %p\nhigh_pc = %p\n", hist_hdr.low_pc, hist_hdr.high_pc);
   hist_hdr.hist_size = shobj->kcountsize / sizeof (HISTCOUNTER);
diff --git a/elf/tlsdeschtab.h b/elf/tlsdeschtab.h
index da92834234..a5efddcdf7 100644
--- a/elf/tlsdeschtab.h
+++ b/elf/tlsdeschtab.h
@@ -44,7 +44,7 @@ eq_tlsdesc (void *p, void *q)
 }
 
 inline static size_t
-map_generation (struct link_map *map)
+map_generation (struct link_map_private *map)
 {
   size_t idx = map->l_tls_modid;
   struct dtv_slotinfo_list *listp = GL(dl_tls_dtv_slotinfo_list);
@@ -82,7 +82,7 @@ map_generation (struct link_map *map)
    when using dynamic TLS.  This requires allocation, returns NULL on
    allocation failure.  */
 void *
-_dl_make_tlsdesc_dynamic (struct link_map *map, size_t ti_offset)
+_dl_make_tlsdesc_dynamic (struct link_map_private *map, size_t ti_offset)
 {
   struct hashtab *ht;
   void **entry;
diff --git a/elf/tst-_dl_addr_inside_object.c b/elf/tst-_dl_addr_inside_object.c
index 363a1990dc..62809c03a4 100644
--- a/elf/tst-_dl_addr_inside_object.c
+++ b/elf/tst-_dl_addr_inside_object.c
@@ -22,18 +22,19 @@
 #include <elf.h>
 #include <libc-symbols.h>
 
-extern int _dl_addr_inside_object (struct link_map *l, const ElfW(Addr) addr);
+extern int _dl_addr_inside_object (struct link_map_private *l,
+				   const ElfW(Addr) addr);
 
 static int
 do_test (void)
 {
   int ret, err = 0;
   ElfW(Addr) addr;
-  struct link_map map;
+  struct link_map_private map;
   ElfW(Phdr) header;
   map.l_phdr = &header;
   map.l_phnum = 1;
-  map.l_addr = 0x0;
+  map.l_public.l_addr = 0x0;
   /* Segment spans 0x2000 -> 0x4000.  */
   header.p_vaddr = 0x2000;
   header.p_memsz = 0x2000;
@@ -191,12 +192,12 @@ do_test (void)
   /* Attempt to wrap addr into the segment.
      Pick a load address in the middle of the address space.
      Place the test address at 0x0 so it wraps to the middle again.  */
-  map.l_addr = 0x0 - 0x1;
-  map.l_addr = map.l_addr / 2;
+  map.l_public.l_addr = 0x0 - 0x1;
+  map.l_public.l_addr = map.l_public.l_addr / 2;
   addr = 0;
   /* Setup a segment covering 1/2 the address space.  */
   header.p_vaddr = 0x0;
-  header.p_memsz = 0x0 - 0x1 - map.l_addr;
+  header.p_memsz = 0x0 - 0x1 - map.l_public.l_addr;
   /* No matter where you place addr everything is shifted modulo l_addr
      and even with this underflow you're always 1 byte away from being
      in the range.  */
diff --git a/elf/tst-audit19a.c b/elf/tst-audit19a.c
index 2b96b3bb53..48f607c780 100644
--- a/elf/tst-audit19a.c
+++ b/elf/tst-audit19a.c
@@ -26,7 +26,7 @@ do_test (void)
 {
   void *h = xdlopen ("tst-auditmod19a.so", RTLD_NOW);
 
-  struct link_map *lmap;
+  struct link_map_private *lmap;
   TEST_VERIFY_EXIT (dlinfo (h, RTLD_DI_LINKMAP, &lmap) == 0);
 
   /* The internal array is only allocated if profiling is enabled.  */
diff --git a/elf/tst-dl_find_object-threads.c b/elf/tst-dl_find_object-threads.c
index 0cc5e8920f..d940c73053 100644
--- a/elf/tst-dl_find_object-threads.c
+++ b/elf/tst-dl_find_object-threads.c
@@ -30,7 +30,7 @@
 /* Computes the expected _dl_find_object result directly from the
    map.  */
 static void
-from_map (struct link_map *l, struct dl_find_object *expected)
+from_map (struct link_map_private *l, struct dl_find_object *expected)
 {
   struct dl_find_object_internal internal;
   _dl_find_object_from_map (l, &internal);
@@ -169,9 +169,9 @@ static void
 start_verify (int number, struct verify_data *data)
 {
   data->soname = soname (number);
-  struct link_map *l = xdlopen (data->soname, RTLD_NOW);
+  struct link_map_private *l = xdlopen (data->soname, RTLD_NOW);
   from_map (l, &data->dlfo);
-  TEST_VERIFY_EXIT (data->dlfo.dlfo_link_map == l);
+  TEST_VERIFY_EXIT (data->dlfo.dlfo_link_map == &l->l_public);
   char *sym = symbol (number);
   data->address = xdlsym (data->dlfo.dlfo_link_map, sym);
   free (sym);
diff --git a/elf/tst-dl_find_object.c b/elf/tst-dl_find_object.c
index eaaa2cf91f..ce72439cdd 100644
--- a/elf/tst-dl_find_object.c
+++ b/elf/tst-dl_find_object.c
@@ -32,7 +32,7 @@ static char main_program_data;
 /* Computes the expected _dl_find_object result directly from the
    map.  */
 static void
-from_map (struct link_map *l, struct dl_find_object *expected)
+from_map (struct link_map_private *l, struct dl_find_object *expected)
 {
   struct dl_find_object_internal internal;
   _dl_find_object_from_map (l, &internal);
@@ -71,7 +71,7 @@ check (void *address,
               __FILE__, line, address,
               actual.dlfo_flags, expected->dlfo_flags);
     }
-  if (expected->dlfo_link_map->l_contiguous)
+  if (l_private (expected->dlfo_link_map)->l_contiguous)
     {
       /* If the mappings are not contiguous, the actual and execpted
          mappings may differ, so this subtest will not work.  */
@@ -136,15 +136,16 @@ check_initial (void)
   char **tzname = xdlsym (NULL, "tzname");
 
   /* The main executable has an unnamed link map.  */
-  struct link_map *main_map = (struct link_map *) debug->r_map;
-  TEST_COMPARE_STRING (main_map->l_name, "");
+  struct link_map_private *main_map = l_private (debug->r_map);
+  TEST_COMPARE_STRING (main_map->l_public.l_name, "");
 
   /* The link map of the dynamic linker.  */
-  struct link_map *rtld_map = xdlopen (LD_SO, RTLD_LAZY | RTLD_NOLOAD);
+  struct link_map_private *rtld_map = xdlopen (LD_SO, RTLD_LAZY | RTLD_NOLOAD);
   TEST_VERIFY_EXIT (rtld_map != NULL);
 
   /* The link map of libc.so.  */
-  struct link_map *libc_map = xdlopen (LIBC_SO, RTLD_LAZY | RTLD_NOLOAD);
+  struct link_map_private *libc_map
+    = xdlopen (LIBC_SO, RTLD_LAZY | RTLD_NOLOAD);
   TEST_VERIFY_EXIT (libc_map != NULL);
 
   struct dl_find_object expected;
@@ -185,7 +186,8 @@ do_test (void)
   check_initial ();
 
   /* dlopen-based test.  First an object that can be dlclosed.  */
-  struct link_map *mod1 = xdlopen ("tst-dl_find_object-mod1.so", RTLD_NOW);
+  struct link_map_private *mod1
+    = xdlopen ("tst-dl_find_object-mod1.so", RTLD_NOW);
   void *mod1_data = xdlsym (mod1, "mod1_data");
   void *map_start = (void *) mod1->l_map_start;
   void *map_end = (void *) (mod1->l_map_end - 1);
@@ -205,7 +207,8 @@ do_test (void)
   check (map_end, NULL, __LINE__);
 
   /* Now try a NODELETE load.  */
-  struct link_map *mod2 = xdlopen ("tst-dl_find_object-mod2.so", RTLD_NOW);
+  struct link_map_private *mod2
+    = xdlopen ("tst-dl_find_object-mod2.so", RTLD_NOW);
   void *mod2_data = xdlsym (mod2, "mod2_data");
   map_start = (void *) mod2->l_map_start;
   map_end = (void *) (mod2->l_map_end - 1);
diff --git a/elf/tst-tls6.c b/elf/tst-tls6.c
index df81c1f6b4..2da9229482 100644
--- a/elf/tst-tls6.c
+++ b/elf/tst-tls6.c
@@ -13,7 +13,7 @@ do_test (void)
   int *foop;
   int *foop2;
   int (*fp) (int, int *);
-  void *h;
+  struct link_map_private *h;
   int i;
   int modid = -1;
 
@@ -30,11 +30,11 @@ do_test (void)
 	 We make sure that the module gets assigned the same ID every
 	 time.  The value of the first round is used.  */
       if (modid == -1)
-	modid = ((struct link_map *) h)->l_tls_modid;
-      else if (((struct link_map *) h)->l_tls_modid != modid)
+	modid = h->l_tls_modid;
+      else if (h->l_tls_modid != modid)
 	{
 	  printf ("round %d: modid now %zd, initially %d\n",
-		  i, ((struct link_map *) h)->l_tls_modid, modid);
+		  i, h->l_tls_modid, modid);
 	  result = 1;
 	}
 
diff --git a/elf/tst-tls7.c b/elf/tst-tls7.c
index fa46709600..6bac842218 100644
--- a/elf/tst-tls7.c
+++ b/elf/tst-tls7.c
@@ -11,7 +11,7 @@ do_test (void)
   static const char modname[] = "tst-tlsmod3.so";
   int result = 0;
   int (*fp) (void);
-  void *h;
+  struct link_map_private *h;
   int i;
   int modid = -1;
 
@@ -28,11 +28,11 @@ do_test (void)
 	 We make sure that the module gets assigned the same ID every
 	 time.  The value of the first round is used.  */
       if (modid == -1)
-	modid = ((struct link_map *) h)->l_tls_modid;
-      else if (((struct link_map *) h)->l_tls_modid != (size_t) modid)
+	modid = h->l_tls_modid;
+      else if (h->l_tls_modid != (size_t) modid)
 	{
 	  printf ("round %d: modid now %zu, initially %d\n",
-		  i, ((struct link_map *) h)->l_tls_modid, modid);
+		  i, h->l_tls_modid, modid);
 	  result = 1;
 	}
 
diff --git a/elf/tst-tls8.c b/elf/tst-tls8.c
index c779572617..81576b85c3 100644
--- a/elf/tst-tls8.c
+++ b/elf/tst-tls8.c
@@ -13,8 +13,8 @@ do_test (void)
   int result = 0;
   int (*fp1) (void);
   int (*fp2) (int, int *);
-  void *h1;
-  void *h2;
+  struct link_map_private *h1;
+  struct link_map_private *h2;
   int i;
   size_t modid1 = (size_t) -1;
   size_t modid2 = (size_t) -1;
@@ -33,11 +33,11 @@ do_test (void)
 	 We make sure that the module gets assigned the same ID every
 	 time.  The value of the first round is used.  */
       if (modid1 == (size_t) -1)
-	modid1 = ((struct link_map *) h1)->l_tls_modid;
-      else if (((struct link_map *) h1)->l_tls_modid != modid1)
+	modid1 = h1->l_tls_modid;
+      else if (h1->l_tls_modid != modid1)
 	{
 	  printf ("round %d: modid now %zd, initially %zd\n",
-		  i, ((struct link_map *) h1)->l_tls_modid, modid1);
+		  i, h1->l_tls_modid, modid1);
 	  result = 1;
 	}
 
@@ -63,11 +63,11 @@ do_test (void)
 	 We make sure that the module gets assigned the same ID every
 	 time.  The value of the first round is used.  */
       if (modid2 == (size_t) -1)
-	modid2 = ((struct link_map *) h1)->l_tls_modid;
-      else if (((struct link_map *) h1)->l_tls_modid != modid2)
+	modid2 = h1->l_tls_modid;
+      else if (h1->l_tls_modid != modid2)
 	{
 	  printf ("round %d: modid now %zd, initially %zd\n",
-		  i, ((struct link_map *) h1)->l_tls_modid, modid2);
+		  i, h1->l_tls_modid, modid2);
 	  result = 1;
 	}
 
@@ -103,10 +103,10 @@ do_test (void)
       /* Dirty test code here: we peek into a private data structure.
 	 We make sure that the module gets assigned the same ID every
 	 time.  The value of the first round is used.  */
-      if (((struct link_map *) h1)->l_tls_modid != modid1)
+      if (h1->l_tls_modid != modid1)
 	{
 	  printf ("round %d: modid now %zd, initially %zd\n",
-		  i, ((struct link_map *) h1)->l_tls_modid, modid1);
+		  i, h1->l_tls_modid, modid1);
 	  result = 1;
 	}
 
@@ -131,10 +131,10 @@ do_test (void)
       /* Dirty test code here: we peek into a private data structure.
 	 We make sure that the module gets assigned the same ID every
 	 time.  The value of the first round is used.  */
-      if (((struct link_map *) h1)->l_tls_modid != modid2)
+      if (h1->l_tls_modid != modid2)
 	{
 	  printf ("round %d: modid now %zd, initially %zd\n",
-		  i, ((struct link_map *) h1)->l_tls_modid, modid2);
+		  i, h1->l_tls_modid, modid2);
 	  result = 1;
 	}
 
diff --git a/elf/unload.c b/elf/unload.c
index 4566f226f8..ab27d9da4a 100644
--- a/elf/unload.c
+++ b/elf/unload.c
@@ -9,13 +9,14 @@
 #include <stdio.h>
 #include <stdlib.h>
 
-#define MAPS ((struct link_map *) _r_debug.r_map)
+#define MAPS (l_private (_r_debug.r_map))
 
 #define OUT \
-  for (map = MAPS; map != NULL; map = map->l_next)			      \
+  for (map = MAPS; map != NULL; map = l_next (map))			      \
     if (map->l_type == lt_loaded)					      \
       printf ("name = \"%s\", direct_opencount = %d\n",			      \
-	      map->l_name, (int) map->l_direct_opencount);		      \
+	      map->l_public.l_name,					      \
+	      (int) map->l_direct_opencount);				      \
   fflush (stdout)
 
 typedef struct
@@ -30,7 +31,7 @@ main (void)
    strct *testdat;
    int ret;
    int result = 0;
-   struct link_map *map;
+   struct link_map_private *map;
 
    mtrace ();
 
diff --git a/elf/unload2.c b/elf/unload2.c
index eef2bfd426..3d6b224610 100644
--- a/elf/unload2.c
+++ b/elf/unload2.c
@@ -6,20 +6,21 @@
 #include <stdio.h>
 #include <stdlib.h>
 
-#define MAPS ((struct link_map *) _r_debug.r_map)
+#define MAPS (l_private (_r_debug.r_map))
 
 #define OUT \
-  for (map = MAPS; map != NULL; map = map->l_next)			      \
+  for (map = MAPS; map != NULL; map = l_next (map))			      \
     if (map->l_type == lt_loaded)					      \
       printf ("name = \"%s\", direct_opencount = %d\n",			      \
-	      map->l_name, (int) map->l_direct_opencount);		      \
+	      map->l_public.l_name,					      \
+	      (int) map->l_direct_opencount);				      \
   fflush (stdout)
 
 int
 main (void)
 {
   void *h[3];
-  struct link_map *map;
+  struct link_map_private *map;
   void (*fp) (void);
 
   h[0] = dlopen ("unload2mod.so", RTLD_LAZY);
diff --git a/htl/pt-alloc.c b/htl/pt-alloc.c
index e205752649..c94a4dcad9 100644
--- a/htl/pt-alloc.c
+++ b/htl/pt-alloc.c
@@ -204,7 +204,7 @@ retry:
 
 void
 attribute_hidden
-__pthread_init_static_tls (struct link_map *map)
+__pthread_init_static_tls (struct link_map_private *map)
 {
   int i;
 
diff --git a/include/dlfcn.h b/include/dlfcn.h
index a44420fa37..af5d75509c 100644
--- a/include/dlfcn.h
+++ b/include/dlfcn.h
@@ -61,17 +61,17 @@ extern int   __libc_dlclose (void *__map)
 /* Locate shared object containing the given address.  */
 #ifdef ElfW
 extern int _dl_addr (const void *address, Dl_info *info,
-		     struct link_map **mapp, const ElfW(Sym) **symbolp)
+		     struct link_map_private **mapp, const ElfW(Sym) **symbolp)
   attribute_hidden;
 #endif
 
-struct link_map;
+struct link_map_private;
 
 /* Close an object previously opened by _dl_open.  */
 extern void _dl_close (void *map) attribute_hidden;
 /* Same as above, but without locking and safety checks for user
    provided map arguments.  */
-extern void _dl_close_worker (struct link_map *map, bool force)
+extern void _dl_close_worker (struct link_map_private *map, bool force)
     attribute_hidden;
 
 /* Look up NAME in shared object HANDLE (which may be RTLD_DEFAULT or
diff --git a/include/link.h b/include/link.h
index adb3886193..ae76a99c30 100644
--- a/include/link.h
+++ b/include/link.h
@@ -5,7 +5,7 @@
 
    The GNU C Library is free software; you can redistribute it and/or
    modify it under the terms of the GNU Lesser General Public
-   License as published by the Free Software Foundation; either
+    License as published by the Free Software Foundation; either
    version 2.1 of the License, or (at your option) any later version.
 
    The GNU C Library is distributed in the hope that it will be useful,
@@ -24,14 +24,6 @@
 # error this should be impossible
 #endif
 
-# ifndef _ISOMAC
-/* Get most of the contents from the public header, but we define a
-   different `struct link_map' type for private use.  The la_objopen
-   prototype uses the type, so we have to declare it separately.  */
-#  define link_map	link_map_public
-#  define la_objopen	la_objopen_wrongproto
-# endif
-
 #include <elf/link.h>
 
 # ifndef _ISOMAC
@@ -66,7 +58,7 @@ struct link_map;
 struct r_scope_elem
 {
   /* Array of maps for the scope.  */
-  struct link_map **r_list;
+  struct link_map_private **r_list;
   /* Number of entries in the scope.  */
   unsigned int r_nlist;
 };
@@ -92,16 +84,11 @@ extern struct r_search_path_struct __rtld_env_path_list attribute_hidden;
    This data structure might change in future, if necessary.  User-level
    programs must avoid defining objects of this type.  */
 
-struct link_map
+struct link_map_private
   {
     /* These first few members are part of the protocol with the debugger.
        This is the same format used in SVR4.  */
-
-    ElfW(Addr) l_addr;		/* Difference between the address in the ELF
-				   file and the addresses in memory.  */
-    char *l_name;		/* Absolute file name object was found in.  */
-    ElfW(Dyn) *l_ld;		/* Dynamic section of the shared object.  */
-    struct link_map *l_next, *l_prev; /* Chain of loaded objects.  */
+    struct link_map l_public;
 
     /* All following members are internal to the dynamic linker.
        They may change without notice.  */
@@ -109,7 +96,7 @@ struct link_map
     /* This is an element which is only ever different from a pointer to
        the very same copy of this type for ld.so when it is used in more
        than one namespace.  */
-    struct link_map *l_real;
+    struct link_map_private *l_real;
 
     /* Number of the namespace this link map belongs to.  */
     Lmid_t l_ns;
@@ -148,7 +135,7 @@ struct link_map
     struct r_scope_elem l_symbolic_searchlist;
 
     /* Dependent object that first caused this object to be loaded.  */
-    struct link_map *l_loader;
+    struct link_map_private *l_loader;
 
     /* Array with version names.  */
     struct r_found_version *l_versions;
@@ -234,7 +221,7 @@ struct link_map
     struct reloc_result
     {
       DL_FIXUP_VALUE_TYPE addr;
-      struct link_map *bound;
+      struct link_map_private *bound;
       unsigned int boundndx;
       uint32_t enterexit;
       unsigned int flags;
@@ -274,13 +261,13 @@ struct link_map
     struct r_search_path_struct l_runpath_dirs;
 
     /* List of object in order of the init and fini calls.  */
-    struct link_map **l_initfini;
+    struct link_map_private **l_initfini;
 
     /* List of the dependencies introduced through symbol binding.  */
     struct link_map_reldeps
       {
 	unsigned int act;
-	struct link_map *list[];
+	struct link_map_private *list[];
       } *l_reldeps;
     unsigned int l_reldepsmax;
 
@@ -301,7 +288,7 @@ struct link_map
     {
       const ElfW(Sym) *sym;
       int type_class;
-      struct link_map *value;
+      struct link_map_private *value;
       const ElfW(Sym) *ret;
     } l_lookup_cache;
 
@@ -347,6 +334,21 @@ struct link_map
     unsigned long long int l_serial;
   };
 
+/* Type-safe downcast from struct link_map to the internal structure.  */
+static inline struct link_map_private *
+l_private (struct link_map *l)
+{
+  return (struct link_map_private *) l;
+}
+
+/* Return a pointer to the private view of the next link map.  Can be
+   used to iterate through the list of link maps.  */
+static inline struct link_map_private *
+l_next (struct link_map_private *l)
+{
+  return l_private (l->l_public.l_next);
+}
+
 #include <dl-relocate-ld.h>
 
 /* Information used by audit modules.  For most link maps, this data
diff --git a/include/rtld-malloc.h b/include/rtld-malloc.h
index 02f89bca1c..318ec53055 100644
--- a/include/rtld-malloc.h
+++ b/include/rtld-malloc.h
@@ -73,8 +73,9 @@ _Bool __rtld_malloc_is_complete (void) attribute_hidden;
 /* Called shortly before the final self-relocation (when RELRO
    variables are still writable) to activate the real malloc
    implementation.  MAIN_MAP is the link map of the executable.  */
-struct link_map;
-void __rtld_malloc_init_real (struct link_map *main_map) attribute_hidden;
+struct link_map_private;
+void __rtld_malloc_init_real (struct link_map_private *main_map)
+  attribute_hidden;
 
 #else /* !IS_IN (rtld) */
 
diff --git a/libio/vtables.c b/libio/vtables.c
index 34f7e15f1c..d7f4f96d49 100644
--- a/libio/vtables.c
+++ b/libio/vtables.c
@@ -516,7 +516,7 @@ _IO_vtable_check (void)
      boundary.  */
   {
     Dl_info di;
-    struct link_map *l;
+    struct link_map_private *l;
     if (!rtld_active ()
         || (_dl_addr (_IO_vtable_check, &di, &l, NULL) != 0
             && l->l_ns != LM_ID_BASE))
diff --git a/nptl_db/db_info.c b/nptl_db/db_info.c
index adb83769cf..64e5d220ef 100644
--- a/nptl_db/db_info.c
+++ b/nptl_db/db_info.c
@@ -37,7 +37,7 @@ typedef struct
   union dtv dtv[UINT32_MAX / 2 / sizeof (union dtv)]; /* No constant bound.  */
 } dtv;
 
-typedef struct link_map link_map;
+typedef struct link_map_private link_map;
 typedef struct rtld_global rtld_global;
 typedef struct dtv_slotinfo_list dtv_slotinfo_list;
 typedef struct dtv_slotinfo dtv_slotinfo;
diff --git a/stdlib/cxa_thread_atexit_impl.c b/stdlib/cxa_thread_atexit_impl.c
index 9bd2ad2158..d35002af30 100644
--- a/stdlib/cxa_thread_atexit_impl.c
+++ b/stdlib/cxa_thread_atexit_impl.c
@@ -83,13 +83,13 @@ struct dtor_list
 {
   dtor_func func;
   void *obj;
-  struct link_map *map;
+  struct link_map_private *map;
   struct dtor_list *next;
 };
 
 static __thread struct dtor_list *tls_dtor_list;
 static __thread void *dso_symbol_cache;
-static __thread struct link_map *lm_cache;
+static __thread struct link_map_private *lm_cache;
 
 /* Register a destructor for TLS variables declared with the 'thread_local'
    keyword.  This function is only called from code generated by the C++
@@ -121,7 +121,7 @@ __cxa_thread_atexit_impl (dtor_func func, void *obj, void *dso_symbol)
     {
       ElfW(Addr) caller = (ElfW(Addr)) dso_symbol;
 
-      struct link_map *l = _dl_find_dso_for_object (caller);
+      struct link_map_private *l = _dl_find_dso_for_object (caller);
 
       /* If the address is not recognized the call comes from the main
 	 program (we hope).  */
diff --git a/stdlib/tst-tls-atexit.c b/stdlib/tst-tls-atexit.c
index efbaed1220..4ccd8c1dc8 100644
--- a/stdlib/tst-tls-atexit.c
+++ b/stdlib/tst-tls-atexit.c
@@ -55,13 +55,13 @@
 static bool
 is_loaded (void)
 {
-  struct link_map *lm = (struct link_map *) _r_debug.r_map;
+  struct link_map_private *lm = l_private (_r_debug.r_map);
 
-  for (; lm; lm = lm->l_next)
-    if (lm->l_type == lt_loaded && lm->l_name
-	&& strcmp (basename (DSO_NAME), basename (lm->l_name)) == 0)
+  for (; lm; lm = l_next (lm))
+    if (lm->l_type == lt_loaded && lm->l_public.l_name
+	&& strcmp (basename (DSO_NAME), basename (lm->l_public.l_name)) == 0)
       {
-	printf ("%s is still loaded\n", lm->l_name);
+	printf ("%s is still loaded\n", lm->l_public.l_name);
 	return true;
       }
   return false;
diff --git a/sysdeps/aarch64/dl-bti.c b/sysdeps/aarch64/dl-bti.c
index b740b1f86d..ed4ea55f4c 100644
--- a/sysdeps/aarch64/dl-bti.c
+++ b/sysdeps/aarch64/dl-bti.c
@@ -29,7 +29,7 @@
 /* Enable BTI protection for MAP.  */
 
 void
-_dl_bti_protect (struct link_map *map, int fd)
+_dl_bti_protect (struct link_map_private *map, int fd)
 {
   const size_t pagesz = GLRO(dl_pagesize);
   const ElfW(Phdr) *phdr;
@@ -40,7 +40,7 @@ _dl_bti_protect (struct link_map *map, int fd)
 	size_t vstart = ALIGN_DOWN (phdr->p_vaddr, pagesz);
 	size_t vend = ALIGN_UP (phdr->p_vaddr + phdr->p_filesz, pagesz);
 	off_t off = ALIGN_DOWN (phdr->p_offset, pagesz);
-	void *start = (void *) (vstart + map->l_addr);
+	void *start = (void *) (vstart + map->l_public.l_addr);
 	size_t len = vend - vstart;
 
 	unsigned prot = PROT_EXEC | PROT_BTI;
@@ -61,14 +61,14 @@ _dl_bti_protect (struct link_map *map, int fd)
 
 
 static void
-bti_failed (struct link_map *l, const char *program)
+bti_failed (struct link_map_private *l, const char *program)
 {
   if (program)
     _dl_fatal_printf ("%s: %s: failed to turn on BTI protection\n",
-		      program, l->l_name);
+		      program, l->l_public.l_name);
   else
     /* Note: the errno value is not available any more.  */
-    _dl_signal_error (0, l->l_name, "dlopen",
+    _dl_signal_error (0, l->l_public.l_name, "dlopen",
 		      N_("failed to turn on BTI protection"));
 }
 
@@ -76,7 +76,7 @@ bti_failed (struct link_map *l, const char *program)
 /* Enable BTI for L and its dependencies.  */
 
 void
-_dl_bti_check (struct link_map *l, const char *program)
+_dl_bti_check (struct link_map_private *l, const char *program)
 {
   if (!GLRO(dl_aarch64_cpu_features).bti)
     return;
@@ -87,7 +87,7 @@ _dl_bti_check (struct link_map *l, const char *program)
   unsigned int i = l->l_searchlist.r_nlist;
   while (i-- > 0)
     {
-      struct link_map *dep = l->l_initfini[i];
+      struct link_map_private *dep = l->l_initfini[i];
       if (dep->l_mach.bti_fail)
 	bti_failed (dep, program);
     }
diff --git a/sysdeps/aarch64/dl-lookupcfg.h b/sysdeps/aarch64/dl-lookupcfg.h
index d7fe73636b..22d98485e2 100644
--- a/sysdeps/aarch64/dl-lookupcfg.h
+++ b/sysdeps/aarch64/dl-lookupcfg.h
@@ -20,8 +20,8 @@
 
 #include_next <dl-lookupcfg.h>
 
-struct link_map;
+struct link_map_private;
 
-extern void _dl_unmap (struct link_map *map);
+extern void _dl_unmap (struct link_map_private *map);
 
 #define DL_UNMAP(map) _dl_unmap (map)
diff --git a/sysdeps/aarch64/dl-machine.h b/sysdeps/aarch64/dl-machine.h
index a56eb96a79..370bbfceba 100644
--- a/sysdeps/aarch64/dl-machine.h
+++ b/sysdeps/aarch64/dl-machine.h
@@ -61,7 +61,8 @@ elf_machine_dynamic (void)
    entries will jump to the on-demand fixup code in dl-runtime.c.  */
 
 static inline int __attribute__ ((unused))
-elf_machine_runtime_setup (struct link_map *l, struct r_scope_elem *scope[],
+elf_machine_runtime_setup (struct link_map_private *l,
+			   struct r_scope_elem *scope[],
 			   int lazy, int profile)
 {
   if (l->l_info[DT_JMPREL] && lazy)
@@ -72,7 +73,7 @@ elf_machine_runtime_setup (struct link_map *l, struct r_scope_elem *scope[],
       got = (ElfW(Addr) *) D_PTR (l, l_info[DT_PLTGOT]);
       if (got[1])
 	{
-	  l->l_mach.plt = got[1] + l->l_addr;
+	  l->l_mach.plt = got[1] + l->l_public.l_addr;
 	}
       got[1] = (ElfW(Addr)) l;
 
@@ -138,7 +139,7 @@ dl_platform_init (void)
 
 
 static inline ElfW(Addr)
-elf_machine_fixup_plt (struct link_map *map, lookup_t t,
+elf_machine_fixup_plt (struct link_map_private *map, lookup_t t,
 		       const ElfW(Sym) *refsym, const ElfW(Sym) *sym,
 		       const ElfW(Rela) *reloc,
 		       ElfW(Addr) *reloc_addr,
@@ -149,7 +150,7 @@ elf_machine_fixup_plt (struct link_map *map, lookup_t t,
 
 /* Return the final value of a plt relocation.  */
 static inline ElfW(Addr)
-elf_machine_plt_value (struct link_map *map,
+elf_machine_plt_value (struct link_map_private *map,
 		       const ElfW(Rela) *reloc,
 		       ElfW(Addr) value)
 {
@@ -166,7 +167,7 @@ elf_machine_plt_value (struct link_map *map,
 
 static inline void
 __attribute__ ((always_inline))
-elf_machine_rela (struct link_map *map, struct r_scope_elem *scope[],
+elf_machine_rela (struct link_map_private *map, struct r_scope_elem *scope[],
 		  const ElfW(Rela) *reloc, const ElfW(Sym) *sym,
 		  const struct r_found_version *version,
 		  void *const reloc_addr_arg, int skip_ifunc)
@@ -175,7 +176,7 @@ elf_machine_rela (struct link_map *map, struct r_scope_elem *scope[],
   const unsigned int r_type = ELFW (R_TYPE) (reloc->r_info);
 
   if (__builtin_expect (r_type == AARCH64_R(RELATIVE), 0))
-      *reloc_addr = map->l_addr + reloc->r_addend;
+      *reloc_addr = map->l_public.l_addr + reloc->r_addend;
   else if (__builtin_expect (r_type == R_AARCH64_NONE, 0))
       return;
   else
@@ -183,8 +184,8 @@ elf_machine_rela (struct link_map *map, struct r_scope_elem *scope[],
 # ifndef RTLD_BOOTSTRAP
       const ElfW(Sym) *const refsym = sym;
 # endif
-      struct link_map *sym_map = RESOLVE_MAP (map, scope, &sym, version,
-					      r_type);
+      struct link_map_private *sym_map
+	= RESOLVE_MAP (map, scope, &sym, version, r_type);
       ElfW(Addr) value = SYMBOL_ADDRESS (sym_map, sym, true);
 
       if (sym != NULL
@@ -279,7 +280,7 @@ elf_machine_rela (struct link_map *map, struct r_scope_elem *scope[],
 	  break;
 
 	case AARCH64_R(IRELATIVE):
-	  value = map->l_addr + reloc->r_addend;
+	  value = map->l_public.l_addr + reloc->r_addend;
 	  if (__glibc_likely (!skip_ifunc))
 	    value = elf_ifunc_invoke (value);
 	  *reloc_addr = value;
@@ -305,7 +306,8 @@ elf_machine_rela_relative (ElfW(Addr) l_addr,
 
 static inline void
 __attribute__ ((always_inline))
-elf_machine_lazy_rel (struct link_map *map, struct r_scope_elem *scope[],
+elf_machine_lazy_rel (struct link_map_private *map,
+		      struct r_scope_elem *scope[],
 		      ElfW(Addr) l_addr,
 		      const ElfW(Rela) *reloc,
 		      int skip_ifunc)
@@ -364,7 +366,7 @@ elf_machine_lazy_rel (struct link_map *map, struct r_scope_elem *scope[],
     }
   else if (__glibc_unlikely (r_type == AARCH64_R(IRELATIVE)))
     {
-      ElfW(Addr) value = map->l_addr + reloc->r_addend;
+      ElfW(Addr) value = map->l_public.l_addr + reloc->r_addend;
       if (__glibc_likely (!skip_ifunc))
 	value = elf_ifunc_invoke (value);
       *reloc_addr = value;
diff --git a/sysdeps/aarch64/dl-prop.h b/sysdeps/aarch64/dl-prop.h
index 8fc58791d5..fa5865a9e9 100644
--- a/sysdeps/aarch64/dl-prop.h
+++ b/sysdeps/aarch64/dl-prop.h
@@ -19,30 +19,30 @@
 #ifndef _DL_PROP_H
 #define _DL_PROP_H
 
-extern void _dl_bti_protect (struct link_map *, int) attribute_hidden;
+extern void _dl_bti_protect (struct link_map_private *, int) attribute_hidden;
 
-extern void _dl_bti_check (struct link_map *, const char *)
+extern void _dl_bti_check (struct link_map_private *, const char *)
     attribute_hidden;
 
 static inline void __attribute__ ((always_inline))
-_rtld_main_check (struct link_map *m, const char *program)
+_rtld_main_check (struct link_map_private *m, const char *program)
 {
   _dl_bti_check (m, program);
 }
 
 static inline void __attribute__ ((always_inline))
-_dl_open_check (struct link_map *m)
+_dl_open_check (struct link_map_private *m)
 {
   _dl_bti_check (m, NULL);
 }
 
 static inline void __attribute__ ((always_inline))
-_dl_process_pt_note (struct link_map *l, int fd, const ElfW(Phdr) *ph)
+_dl_process_pt_note (struct link_map_private *l, int fd, const ElfW(Phdr) *ph)
 {
 }
 
 static inline int
-_dl_process_gnu_property (struct link_map *l, int fd, uint32_t type,
+_dl_process_gnu_property (struct link_map_private *l, int fd, uint32_t type,
 			  uint32_t datasz, void *data)
 {
   if (!GLRO(dl_aarch64_cpu_features).bti)
diff --git a/sysdeps/aarch64/dl-tlsdesc.h b/sysdeps/aarch64/dl-tlsdesc.h
index 0138efcf49..d84890dc86 100644
--- a/sysdeps/aarch64/dl-tlsdesc.h
+++ b/sysdeps/aarch64/dl-tlsdesc.h
@@ -49,7 +49,7 @@ extern ptrdiff_t attribute_hidden
 _dl_tlsdesc_undefweak (struct tlsdesc *);
 
 # ifdef SHARED
-extern void *_dl_make_tlsdesc_dynamic (struct link_map *, size_t);
+extern void *_dl_make_tlsdesc_dynamic (struct link_map_private *, size_t);
 
 extern ptrdiff_t attribute_hidden
 _dl_tlsdesc_dynamic (struct tlsdesc *);
diff --git a/sysdeps/aarch64/tlsdesc.c b/sysdeps/aarch64/tlsdesc.c
index a357e7619f..109ee9dbc7 100644
--- a/sysdeps/aarch64/tlsdesc.c
+++ b/sysdeps/aarch64/tlsdesc.c
@@ -28,7 +28,7 @@
    if there is one.  */
 
 void
-_dl_unmap (struct link_map *map)
+_dl_unmap (struct link_map_private *map)
 {
   _dl_unmap_segments (map);
 
diff --git a/sysdeps/alpha/dl-machine.h b/sysdeps/alpha/dl-machine.h
index 7fe2afca93..746c7d8189 100644
--- a/sysdeps/alpha/dl-machine.h
+++ b/sysdeps/alpha/dl-machine.h
@@ -71,7 +71,8 @@ elf_machine_load_address (void)
    entries will jump to the on-demand fixup code in dl-runtime.c.  */
 
 static inline int
-elf_machine_runtime_setup (struct link_map *map, struct r_scope_elem *scope[],
+elf_machine_runtime_setup (struct link_map_private *map,
+			   struct r_scope_elem *scope[],
 			   int lazy, int profile)
 {
   extern char _dl_runtime_resolve_new[] attribute_hidden;
@@ -79,7 +80,7 @@ elf_machine_runtime_setup (struct link_map *map, struct r_scope_elem *scope[],
 
   struct pltgot {
     char *resolve;
-    struct link_map *link;
+    struct link_map_private *link;
   };
 
   struct pltgot *pg;
@@ -218,7 +219,7 @@ dl_platform_init (void)
 /* Fix up the instructions of a PLT entry to invoke the function
    rather than the dynamic linker.  */
 static inline Elf64_Addr
-elf_machine_fixup_plt (struct link_map *map, lookup_t t,
+elf_machine_fixup_plt (struct link_map_private *map, lookup_t t,
 		       const ElfW(Sym) *refsym, const ElfW(Sym) *sym,
 		       const Elf64_Rela *reloc,
 		       Elf64_Addr *got_addr, Elf64_Addr value)
@@ -304,7 +305,7 @@ elf_machine_fixup_plt (struct link_map *map, lookup_t t,
 
 /* Return the final value of a plt relocation.  */
 static inline Elf64_Addr
-elf_machine_plt_value (struct link_map *map, const Elf64_Rela *reloc,
+elf_machine_plt_value (struct link_map_private *map, const Elf64_Rela *reloc,
 		       Elf64_Addr value)
 {
   return value + reloc->r_addend;
@@ -322,7 +323,7 @@ elf_machine_plt_value (struct link_map *map, const Elf64_Rela *reloc,
    MAP is the object containing the reloc.  */
 static inline void
 __attribute__ ((always_inline))
-elf_machine_rela (struct link_map *map, struct r_scope_elem *scope[],
+elf_machine_rela (struct link_map_private *map, struct r_scope_elem *scope[],
 		  const Elf64_Rela *reloc,
 		  const Elf64_Sym *sym,
 		  const struct r_found_version *version,
@@ -344,7 +345,7 @@ elf_machine_rela (struct link_map *map, struct r_scope_elem *scope[],
 
 	/* Load value without causing unaligned trap. */
 	memcpy (&reloc_addr_val, reloc_addr_arg, 8);
-	reloc_addr_val += map->l_addr;
+	reloc_addr_val += map->l_public.l_addr;
 
 	/* Store value without causing unaligned trap. */
 	memcpy (reloc_addr_arg, &reloc_addr_val, 8);
@@ -355,8 +356,8 @@ elf_machine_rela (struct link_map *map, struct r_scope_elem *scope[],
       return;
   else
     {
-      struct link_map *sym_map = RESOLVE_MAP (map, scope, &sym, version,
-					      r_type);
+      struct link_map_private *sym_map
+	= RESOLVE_MAP (map, scope, &sym, version, r_type);
       Elf64_Addr sym_value;
       Elf64_Addr sym_raw_value;
 
@@ -438,7 +439,8 @@ elf_machine_rela_relative (Elf64_Addr l_addr, const Elf64_Rela *reloc,
 
 static inline void
 __attribute__ ((always_inline))
-elf_machine_lazy_rel (struct link_map *map, struct r_scope_elem *scope[],
+elf_machine_lazy_rel (struct link_map_private *map,
+		      struct r_scope_elem *scope[],
 		      Elf64_Addr l_addr, const Elf64_Rela *reloc,
 		      int skip_ifunc)
 {
diff --git a/sysdeps/arc/dl-machine.h b/sysdeps/arc/dl-machine.h
index 4dc652a449..c07ebe0838 100644
--- a/sysdeps/arc/dl-machine.h
+++ b/sysdeps/arc/dl-machine.h
@@ -124,7 +124,8 @@ elf_machine_load_address (void)
 
 static inline int
 __attribute__ ((always_inline))
-elf_machine_runtime_setup (struct link_map *l, struct r_scope_elem *scope[],
+elf_machine_runtime_setup (struct link_map_private *l,
+			   struct r_scope_elem *scope[],
 			   int lazy, int profile)
 {
   extern void _dl_runtime_resolve (void);
@@ -134,7 +135,7 @@ elf_machine_runtime_setup (struct link_map *l, struct r_scope_elem *scope[],
       /* On ARC DT_PLTGOT point to .plt whose 5th word (after the PLT header)
          contains the address of .got.  */
       ElfW(Addr) *plt_base = (ElfW(Addr) *) D_PTR (l, l_info[DT_PLTGOT]);
-      ElfW(Addr) *got = (ElfW(Addr) *) (plt_base[5] + l->l_addr);
+      ElfW(Addr) *got = (ElfW(Addr) *) (plt_base[5] + l->l_public.l_addr);
 
       got[1] = (ElfW(Addr)) l;	/* Identify this shared object.  */
 
@@ -195,7 +196,7 @@ __start:								\n\
 /* Fixup a PLT entry to bounce directly to the function at VALUE.  */
 
 static inline ElfW(Addr)
-elf_machine_fixup_plt (struct link_map *map, lookup_t t,
+elf_machine_fixup_plt (struct link_map_private *map, lookup_t t,
 		       const ElfW(Sym) *refsym, const ElfW(Sym) *sym,
 		       const ElfW(Rela) *reloc,
 		       ElfW(Addr) *reloc_addr, ElfW(Addr) value)
@@ -216,7 +217,7 @@ elf_machine_fixup_plt (struct link_map *map, lookup_t t,
 
 static inline void
 __attribute__ ((always_inline))
-elf_machine_rela (struct link_map *map, struct r_scope_elem *scope[],
+elf_machine_rela (struct link_map_private *map, struct r_scope_elem *scope[],
 		  const ElfW(Rela) *reloc, const ElfW(Sym) *sym,
 		  const struct r_found_version *version,
                   void *const reloc_addr_arg, int skip_ifunc)
@@ -226,14 +227,14 @@ elf_machine_rela (struct link_map *map, struct r_scope_elem *scope[],
   ElfW(Addr) *const reloc_addr = reloc_addr_arg;
 
   if (__glibc_unlikely (r_type == R_ARC_RELATIVE))
-    *reloc_addr += map->l_addr;
+    *reloc_addr += map->l_public.l_addr;
   else if (__glibc_unlikely (r_type == R_ARC_NONE))
     return;
   else
     {
       const ElfW(Sym) *const refsym = sym;
-      struct link_map *sym_map = RESOLVE_MAP (map, scope, &sym, version,
-					      r_type);
+      struct link_map_private *sym_map
+	= RESOLVE_MAP (map, scope, &sym, version, r_type);
       ElfW(Addr) value = SYMBOL_ADDRESS (sym_map, sym, true);
 
       switch (r_type)
@@ -314,7 +315,8 @@ elf_machine_rela_relative (ElfW(Addr) l_addr, const ElfW(Rela) *reloc,
 
 static inline void
 __attribute__ ((always_inline))
-elf_machine_lazy_rel (struct link_map *map, struct r_scope_elem *scope[],
+elf_machine_lazy_rel (struct link_map_private *map,
+		      struct r_scope_elem *scope[],
 		      ElfW(Addr) l_addr, const ElfW(Rela) *reloc,
 		      int skip_ifunc)
 {
diff --git a/sysdeps/arm/dl-lookupcfg.h b/sysdeps/arm/dl-lookupcfg.h
index d7fe73636b..22d98485e2 100644
--- a/sysdeps/arm/dl-lookupcfg.h
+++ b/sysdeps/arm/dl-lookupcfg.h
@@ -20,8 +20,8 @@
 
 #include_next <dl-lookupcfg.h>
 
-struct link_map;
+struct link_map_private;
 
-extern void _dl_unmap (struct link_map *map);
+extern void _dl_unmap (struct link_map_private *map);
 
 #define DL_UNMAP(map) _dl_unmap (map)
diff --git a/sysdeps/arm/dl-machine.h b/sysdeps/arm/dl-machine.h
index a68679e653..e5fd0cc4d2 100644
--- a/sysdeps/arm/dl-machine.h
+++ b/sysdeps/arm/dl-machine.h
@@ -60,7 +60,8 @@ elf_machine_dynamic (void)
    entries will jump to the on-demand fixup code in dl-runtime.c.  */
 
 static inline int __attribute__ ((unused))
-elf_machine_runtime_setup (struct link_map *l, struct r_scope_elem *scope[],
+elf_machine_runtime_setup (struct link_map_private *l,
+			   struct r_scope_elem *scope[],
 			   int lazy, int profile)
 {
   Elf32_Addr *got;
@@ -78,7 +79,7 @@ elf_machine_runtime_setup (struct link_map *l, struct r_scope_elem *scope[],
 	 we have to be able to undo the prelinking of .got.plt.
 	 The prelinker saved us here address of .plt.  */
       if (got[1])
-	l->l_mach.plt = got[1] + l->l_addr;
+	l->l_mach.plt = got[1] + l->l_public.l_addr;
       got[1] = (Elf32_Addr) l;	/* Identify this shared object.  */
 
       /* The got[2] entry contains the address of a function which gets
@@ -205,7 +206,7 @@ dl_platform_init (void)
 }
 
 static inline Elf32_Addr
-elf_machine_fixup_plt (struct link_map *map, lookup_t t,
+elf_machine_fixup_plt (struct link_map_private *map, lookup_t t,
 		       const ElfW(Sym) *refsym, const ElfW(Sym) *sym,
 		       const Elf32_Rel *reloc,
 		       Elf32_Addr *reloc_addr, Elf32_Addr value)
@@ -215,7 +216,7 @@ elf_machine_fixup_plt (struct link_map *map, lookup_t t,
 
 /* Return the final value of a plt relocation.  */
 static inline Elf32_Addr
-elf_machine_plt_value (struct link_map *map, const Elf32_Rel *reloc,
+elf_machine_plt_value (struct link_map_private *map, const Elf32_Rel *reloc,
 		       Elf32_Addr value)
 {
   return value;
@@ -241,7 +242,7 @@ static inline bool set_new_value (Elf32_Addr *new_value, Elf32_Addr v,
 
 /* Handle a PC24 reloc, including the out-of-range case.  */
 static void
-relocate_pc24 (struct link_map *map, Elf32_Addr value,
+relocate_pc24 (struct link_map_private *map, Elf32_Addr value,
                Elf32_Addr *const reloc_addr, Elf32_Sword addend)
 {
   Elf32_Addr new_value;
@@ -258,7 +259,7 @@ relocate_pc24 (struct link_map *map, Elf32_Addr value,
                                    PROT_READ | PROT_WRITE | PROT_EXEC,
                                    MAP_PRIVATE | MAP_ANON, -1, 0);
           if (new_page == MAP_FAILED)
-            _dl_signal_error (0, map->l_name, NULL,
+            _dl_signal_error (0, map->l_public.l_name, NULL,
                               "could not map page for fixup");
           fix_page = new_page;
           assert (fix_offset == 0);
@@ -277,7 +278,7 @@ relocate_pc24 (struct link_map *map, Elf32_Addr value,
 
       if (set_new_value (&new_value, (Elf32_Addr) fix_address, reloc_addr,
 			 addend))
-        _dl_signal_error (0, map->l_name, NULL,
+        _dl_signal_error (0, map->l_public.l_name, NULL,
                           "R_ARM_PC24 relocation out of range");
     }
 
@@ -289,7 +290,7 @@ relocate_pc24 (struct link_map *map, Elf32_Addr value,
 
 static inline void
 __attribute__ ((always_inline))
-elf_machine_rel (struct link_map *map, struct r_scope_elem *scope[],
+elf_machine_rel (struct link_map_private *map, struct r_scope_elem *scope[],
                  const Elf32_Rel *reloc, const Elf32_Sym *sym,
                  const struct r_found_version *version,
 		 void *const reloc_addr_arg, int skip_ifunc)
@@ -299,7 +300,7 @@ elf_machine_rel (struct link_map *map, struct r_scope_elem *scope[],
 
 #if !defined RTLD_BOOTSTRAP
   if (__builtin_expect (r_type == R_ARM_RELATIVE, 0))
-    *reloc_addr += map->l_addr;
+    *reloc_addr += map->l_public.l_addr;
 # ifndef RTLD_BOOTSTRAP
   else if (__builtin_expect (r_type == R_ARM_NONE, 0))
     return;
@@ -308,8 +309,8 @@ elf_machine_rel (struct link_map *map, struct r_scope_elem *scope[],
 #endif
     {
       const Elf32_Sym *const refsym = sym;
-      struct link_map *sym_map = RESOLVE_MAP (map, scope, &sym, version,
-					      r_type);
+      struct link_map_private *sym_map
+	= RESOLVE_MAP (map, scope, &sym, version, r_type);
       Elf32_Addr value = SYMBOL_ADDRESS (sym_map, sym, true);
 
       if (sym != NULL
@@ -439,7 +440,7 @@ elf_machine_rel (struct link_map *map, struct r_scope_elem *scope[],
 	    }
 	  break;
 	case R_ARM_IRELATIVE:
-	  value = map->l_addr + *reloc_addr;
+	  value = map->l_public.l_addr + *reloc_addr;
 	  if (__glibc_likely (!skip_ifunc))
 	    value = ((Elf32_Addr (*) (int)) value) (GLRO(dl_hwcap));
 	  *reloc_addr = value;
@@ -465,7 +466,8 @@ elf_machine_rel_relative (Elf32_Addr l_addr, const Elf32_Rel *reloc,
 
 static inline void
 __attribute__ ((always_inline))
-elf_machine_lazy_rel (struct link_map *map, struct r_scope_elem *scope[],
+elf_machine_lazy_rel (struct link_map_private *map,
+		      struct r_scope_elem *scope[],
 		      Elf32_Addr l_addr, const Elf32_Rel *reloc,
 		      int skip_ifunc)
 {
diff --git a/sysdeps/arm/dl-tlsdesc.h b/sysdeps/arm/dl-tlsdesc.h
index bb647ccc87..7fa5732267 100644
--- a/sysdeps/arm/dl-tlsdesc.h
+++ b/sysdeps/arm/dl-tlsdesc.h
@@ -51,7 +51,7 @@ extern ptrdiff_t attribute_hidden
   _dl_tlsdesc_undefweak(struct tlsdesc *);
 
 # ifdef SHARED
-extern void *_dl_make_tlsdesc_dynamic (struct link_map *map, size_t ti_offset);
+void *_dl_make_tlsdesc_dynamic (struct link_map_private *, size_t ti_offset);
 
 extern ptrdiff_t attribute_hidden
   _dl_tlsdesc_dynamic(struct tlsdesc *);
diff --git a/sysdeps/arm/tlsdesc.c b/sysdeps/arm/tlsdesc.c
index 54b35f0bac..550d3695ee 100644
--- a/sysdeps/arm/tlsdesc.c
+++ b/sysdeps/arm/tlsdesc.c
@@ -26,7 +26,7 @@
    if there is one.  */
 
 void
-_dl_unmap (struct link_map *map)
+_dl_unmap (struct link_map_private *map)
 {
   _dl_unmap_segments (map);
 
diff --git a/sysdeps/csky/dl-machine.h b/sysdeps/csky/dl-machine.h
index 07a4b678bf..8dcb9b11c8 100644
--- a/sysdeps/csky/dl-machine.h
+++ b/sysdeps/csky/dl-machine.h
@@ -60,7 +60,8 @@ elf_machine_load_address (void)
    entries will jump to the on-demand fixup code in dl-runtime.c.  */
 
 static inline int __attribute__ ((always_inline))
-elf_machine_runtime_setup (struct link_map *l, struct r_scope_elem *scope[],
+elf_machine_runtime_setup (struct link_map_private *l,
+			   struct r_scope_elem *scope[],
 			   int lazy, int profile)
 {
   Elf32_Addr *got;
@@ -76,7 +77,7 @@ elf_machine_runtime_setup (struct link_map *l, struct r_scope_elem *scope[],
       got = (Elf32_Addr *) D_PTR (l, l_info[DT_PLTGOT]);
 
       if (got[1])
-	l->l_mach.plt = got[1] + l->l_addr;
+	l->l_mach.plt = got[1] + l->l_public.l_addr;
       got[1] = (Elf32_Addr) l; /* Identify this shared object.  */
 
       /* The got[2] entry contains the address of a function which gets
@@ -170,7 +171,7 @@ dl_platform_init (void)
 }
 
 static inline Elf32_Addr
-elf_machine_fixup_plt (struct link_map *map, lookup_t t,
+elf_machine_fixup_plt (struct link_map_private *map, lookup_t t,
 		       const ElfW(Sym) *refsym, const ElfW(Sym) *sym,
 		       const Elf32_Rela *reloc,
 		       Elf32_Addr *reloc_addr, Elf32_Addr value)
@@ -181,7 +182,7 @@ elf_machine_fixup_plt (struct link_map *map, lookup_t t,
 /* Return the final value of a plt relocation.  On the csky the JMP_SLOT
    relocation ignores the addend.  */
 static inline Elf32_Addr
-elf_machine_plt_value (struct link_map *map, const Elf32_Rela *reloc,
+elf_machine_plt_value (struct link_map_private *map, const Elf32_Rela *reloc,
 		       Elf32_Addr value)
 {
   return value;
@@ -198,7 +199,7 @@ elf_machine_plt_value (struct link_map *map, const Elf32_Rela *reloc,
    MAP is the object containing the reloc.  */
 
 static inline void __attribute__ ((unused, always_inline))
-elf_machine_rela (struct link_map *map, struct r_scope_elem *scope[],
+elf_machine_rela (struct link_map_private *map, struct r_scope_elem *scope[],
 		  const Elf32_Rela *reloc, const Elf32_Sym *sym,
 		  const struct r_found_version *version,
 		  void *const reloc_addr_arg, int skip_ifunc)
@@ -209,12 +210,12 @@ elf_machine_rela (struct link_map *map, struct r_scope_elem *scope[],
   Elf32_Addr __attribute__ ((unused)) insn_opcode = 0x0;
 
   if (__builtin_expect (r_type == R_CKCORE_RELATIVE, 0))
-    *reloc_addr = map->l_addr + reloc->r_addend;
+    *reloc_addr = map->l_public.l_addr + reloc->r_addend;
   else
     {
       const Elf32_Sym *const refsym = sym;
-      struct link_map *sym_map = RESOLVE_MAP (map, scope, &sym, version,
-					      r_type);
+      struct link_map_private *sym_map
+	= RESOLVE_MAP (map, scope, &sym, version, r_type);
       ElfW(Addr) value = SYMBOL_ADDRESS (sym_map, sym, true);
       opcode16_addr = (unsigned short *)reloc_addr;
 
@@ -324,7 +325,8 @@ elf_machine_rela_relative (Elf32_Addr l_addr, const Elf32_Rela *reloc,
 }
 
 static inline void __attribute__ ((unused, always_inline))
-elf_machine_lazy_rel (struct link_map *map, struct r_scope_elem *scope[],
+elf_machine_lazy_rel (struct link_map_private *map,
+		      struct r_scope_elem *scope[],
 		      Elf32_Addr l_addr, const Elf32_Rela *reloc,
 		      int skip_ifunc)
 {
diff --git a/sysdeps/generic/dl-debug.h b/sysdeps/generic/dl-debug.h
index 7ad4a286cc..dbc4c317c9 100644
--- a/sysdeps/generic/dl-debug.h
+++ b/sysdeps/generic/dl-debug.h
@@ -24,7 +24,7 @@
 
 static inline void
 __attribute ((always_inline))
-elf_setup_debug_entry (struct link_map *l, struct r_debug *r)
+elf_setup_debug_entry (struct link_map_private *l, struct r_debug *r)
 {
   if (l->l_info[DT_DEBUG] != NULL)
     l->l_info[DT_DEBUG]->d_un.d_ptr = (ElfW(Addr)) r;
diff --git a/sysdeps/generic/dl-fptr.h b/sysdeps/generic/dl-fptr.h
index adf40348bc..59cc9aaf02 100644
--- a/sysdeps/generic/dl-fptr.h
+++ b/sysdeps/generic/dl-fptr.h
@@ -35,11 +35,11 @@ struct fdesc_table
     struct fdesc fdesc[0];
   };
 
-struct link_map;
+struct link_map_private;
 
 extern ElfW(Addr) _dl_boot_fptr_table [];
 
-extern ElfW(Addr) _dl_make_fptr (struct link_map *, const ElfW(Sym) *,
+extern ElfW(Addr) _dl_make_fptr (struct link_map_private *, const ElfW(Sym) *,
 				 ElfW(Addr));
 
 #endif /* !dl_fptr_h */
diff --git a/sysdeps/generic/dl-prop.h b/sysdeps/generic/dl-prop.h
index 654137ebce..13913da970 100644
--- a/sysdeps/generic/dl-prop.h
+++ b/sysdeps/generic/dl-prop.h
@@ -27,24 +27,24 @@
    "flag day" ABI transitions.  */
 
 static inline void __attribute__ ((always_inline))
-_rtld_main_check (struct link_map *m, const char *program)
+_rtld_main_check (struct link_map_private *m, const char *program)
 {
 }
 
 static inline void __attribute__ ((always_inline))
-_dl_open_check (struct link_map *m)
+_dl_open_check (struct link_map_private *m)
 {
 }
 
 static inline void __attribute__ ((always_inline))
-_dl_process_pt_note (struct link_map *l, int fd, const ElfW(Phdr) *ph)
+_dl_process_pt_note (struct link_map_private *l, int fd, const ElfW(Phdr) *ph)
 {
 }
 
 /* Called for each property in the NT_GNU_PROPERTY_TYPE_0 note of L,
    processing of the properties continues until this returns 0.  */
 static inline int __attribute__ ((always_inline))
-_dl_process_gnu_property (struct link_map *l, int fd, uint32_t type,
+_dl_process_gnu_property (struct link_map_private *l, int fd, uint32_t type,
 			  uint32_t datasz, void *data)
 {
   /* Continue until GNU_PROPERTY_1_NEEDED is found.  */
diff --git a/sysdeps/generic/dl-protected.h b/sysdeps/generic/dl-protected.h
index 36fb8ce7f3..4d2540bea8 100644
--- a/sysdeps/generic/dl-protected.h
+++ b/sysdeps/generic/dl-protected.h
@@ -21,9 +21,9 @@
 
 static inline void __attribute__ ((always_inline))
 _dl_check_protected_symbol (const char *undef_name,
-			    const struct link_map *undef_map,
+			    const struct link_map_private *undef_map,
 			    const ElfW(Sym) *ref,
-			    const struct link_map *map,
+			    const struct link_map_private *map,
 			    int type_class)
 {
   if (undef_map == NULL || undef_map->l_type != lt_executable)
@@ -35,7 +35,7 @@ _dl_check_protected_symbol (const char *undef_name,
        access.  */
     _dl_error_printf ("warning: copy relocation against non-copyable "
 		      "protected symbol `%s' in `%s'\n",
-		      undef_name, map->l_name);
+		      undef_name, map->l_public.l_name);
   else if ((type_class & ELF_RTYPE_CLASS_PLT) && ref->st_value != 0
 	   && ref->st_shndx == SHN_UNDEF)
     /* Disallow non-zero symbol values of undefined symbols in
@@ -45,13 +45,13 @@ _dl_check_protected_symbol (const char *undef_name,
     _dl_error_printf (
 	"warning: direct reference to "
 	"protected function `%s' in `%s' may break pointer equality\n",
-	undef_name, map->l_name);
+	undef_name, map->l_public.l_name);
   else
     return;
 
   if (map->l_1_needed & GNU_PROPERTY_1_NEEDED_INDIRECT_EXTERN_ACCESS)
     _dl_signal_error (
-	0, map->l_name, undef_name,
+	0, map->l_public.l_name, undef_name,
 	N_ ("error due to GNU_PROPERTY_1_NEEDED_INDIRECT_EXTERN_ACCESS"));
 }
 
diff --git a/sysdeps/generic/ldsodefs.h b/sysdeps/generic/ldsodefs.h
index 51ee7f2112..53cc428421 100644
--- a/sysdeps/generic/ldsodefs.h
+++ b/sysdeps/generic/ldsodefs.h
@@ -73,7 +73,7 @@ __BEGIN_DECLS
    relocated.  */
 
 static inline bool
-dl_relocate_ld (const struct link_map *l)
+dl_relocate_ld (const struct link_map_private *l)
 {
   /* Don't relocate dynamic section if it is readonly  */
   return !(l->l_ld_readonly || DL_RO_DYN_SECTION);
@@ -86,12 +86,13 @@ dl_relocate_ld (const struct link_map *l)
   most architectures the entry is already relocated - but for some not
   and we need to relocate at access time.  */
 #define D_PTR(map, i) \
-  ((map)->i->d_un.d_ptr + (dl_relocate_ld (map) ? 0 : (map)->l_addr))
+  ((map)->i->d_un.d_ptr + (dl_relocate_ld (map) ? 0 : (map)->l_public.l_addr))
 
 /* Result of the lookup functions and how to retrieve the base address.  */
-typedef struct link_map *lookup_t;
+typedef struct link_map_private *lookup_t;
 #define LOOKUP_VALUE(map) map
-#define LOOKUP_VALUE_ADDRESS(map, set) ((set) || (map) ? (map)->l_addr : 0)
+#define LOOKUP_VALUE_ADDRESS(map, set) \
+  ((set) || (map) ? (map)->l_public.l_addr : 0)
 
 /* Calculate the address of symbol REF using the base address from map MAP,
    if non-NULL.  Don't check for NULL map if MAP_SET is TRUE.  */
@@ -121,10 +122,10 @@ typedef void (*fini_t) (void);
 
 /* On some architectures dladdr can't use st_size of all symbols this way.  */
 #define DL_ADDR_SYM_MATCH(L, SYM, MATCHSYM, ADDR) \
-  ((ADDR) >= (L)->l_addr + (SYM)->st_value				\
+  ((ADDR) >= (L)->l_public.l_addr + (SYM)->st_value			\
    && ((((SYM)->st_shndx == SHN_UNDEF || (SYM)->st_size == 0)		\
-	&& (ADDR) == (L)->l_addr + (SYM)->st_value)			\
-       || (ADDR) < (L)->l_addr + (SYM)->st_value + (SYM)->st_size)	\
+	&& (ADDR) == (L)->l_public.l_addr + (SYM)->st_value)		\
+       || (ADDR) < (L)->l_public.l_addr + (SYM)->st_value + (SYM)->st_size) \
    && ((MATCHSYM) == NULL || (MATCHSYM)->st_value < (SYM)->st_value))
 
 /* According to the ELF gABI no STV_HIDDEN or STV_INTERNAL symbols are
@@ -238,7 +239,7 @@ struct audit_ifaces
 {
   void (*activity) (uintptr_t *, unsigned int);
   char *(*objsearch) (const char *, uintptr_t *, unsigned int);
-  unsigned int (*objopen) (struct link_map *, Lmid_t, uintptr_t *);
+  unsigned int (*objopen) (struct link_map_private *, Lmid_t, uintptr_t *);
   void (*preinit) (uintptr_t *);
   union
   {
@@ -266,7 +267,8 @@ struct audit_ifaces
 
 
 /* Test whether given NAME matches any of the names of the given object.  */
-extern int _dl_name_match_p (const char *__name, const struct link_map *__map)
+extern int _dl_name_match_p (const char *__name,
+			     const struct link_map_private *__map)
      attribute_hidden;
 
 /* Compute next higher prime number.  */
@@ -315,7 +317,7 @@ struct rtld_global
   EXTERN struct link_namespaces
   {
     /* A pointer to the map for the main map.  */
-    struct link_map *_ns_loaded;
+    struct link_map_private *_ns_loaded;
     /* Number of object in the _dl_loaded list.  */
     unsigned int _ns_nloaded;
     /* Direct pointer to the searchlist of the main object.  */
@@ -333,7 +335,7 @@ struct rtld_global
 
     /* Once libc.so has been loaded into the namespace, this points to
        its link map.  */
-    struct link_map *libc_map;
+    struct link_map_private *libc_map;
 
     /* Search table for unique objects.  */
     struct unique_sym_table
@@ -344,7 +346,7 @@ struct rtld_global
 	uint32_t hashval;
 	const char *name;
 	const ElfW(Sym) *sym;
-	const struct link_map *map;
+	const struct link_map_private *map;
       } *entries;
       size_t size;
       size_t n_elements;
@@ -380,10 +382,10 @@ struct rtld_global
   EXTERN unsigned long long _dl_load_adds;
 
   /* The object to be initialized first.  */
-  EXTERN struct link_map *_dl_initfirst;
+  EXTERN struct link_map_private *_dl_initfirst;
 
   /* Map of shared object to be profiled.  */
-  EXTERN struct link_map *_dl_profile_map;
+  EXTERN struct link_map_private *_dl_profile_map;
 
   /* Counters for the number of relocations performed.  */
   EXTERN unsigned long int _dl_num_relocations;
@@ -393,7 +395,7 @@ struct rtld_global
   EXTERN struct r_search_path_elem *_dl_all_dirs;
 
   /* Structure describing the dynamic linker itself.  */
-  EXTERN struct link_map _dl_rtld_map;
+  EXTERN struct link_map_private _dl_rtld_map;
 #ifdef SHARED
   /* Used to store the audit information for the link map of the
      dynamic loader.  */
@@ -435,7 +437,7 @@ struct rtld_global
     struct dtv_slotinfo
     {
       size_t gen;
-      struct link_map *map;
+      struct link_map_private *map;
     } slotinfo[];
   } *_dl_tls_dtv_slotinfo_list;
   /* Number of modules in the static TLS block.  */
@@ -460,7 +462,7 @@ struct rtld_global
   EXTERN size_t _dl_tls_generation;
 
 #if !PTHREAD_IN_LIBC
-  EXTERN void (*_dl_init_static_tls) (struct link_map *);
+  EXTERN void (*_dl_init_static_tls) (struct link_map_private *);
 #endif
 
   /* Scopes to free after next THREAD_GSCOPE_WAIT ().  */
@@ -634,7 +636,7 @@ struct rtld_global_ro
 
   /* At startup time we set up the normal DSO data structure for it,
      and this points to it.  */
-  EXTERN struct link_map *_dl_sysinfo_map;
+  EXTERN struct link_map_private *_dl_sysinfo_map;
 
 # define PROCINFO_DECL
 # ifndef PROCINFO_CLASS
@@ -657,10 +659,10 @@ struct rtld_global_ro
   void (*_dl_debug_printf) (const char *, ...)
        __attribute__ ((__format__ (__printf__, 1, 2)));
   void (*_dl_mcount) (ElfW(Addr) frompc, ElfW(Addr) selfpc);
-  lookup_t (*_dl_lookup_symbol_x) (const char *, struct link_map *,
+  lookup_t (*_dl_lookup_symbol_x) (const char *, struct link_map_private *,
 				   const ElfW(Sym) **, struct r_scope_elem *[],
 				   const struct r_found_version *, int, int,
-				   struct link_map *);
+				   struct link_map_private *);
   void *(*_dl_open) (const char *file, int mode, const void *caller_dlopen,
 		     Lmid_t nsid, int argc, char *argv[], char *env[]);
   void (*_dl_close) (void *map);
@@ -673,7 +675,7 @@ struct rtld_global_ro
   /* libdl in a secondary namespace must use free from the base
      namespace.  */
   void (*_dl_error_free) (void *);
-  void *(*_dl_tls_get_addr_soft) (struct link_map *);
+  void *(*_dl_tls_get_addr_soft) (struct link_map_private *);
 
   /* Called from __libc_shared to deallocate malloc'ed memory.  */
   void (*_dl_libc_freeres) (void);
@@ -914,23 +916,23 @@ rtld_hidden_proto (_dl_catch_exception)
 /* Open the shared object NAME and map in its segments.
    LOADER's DT_RPATH is used in searching for NAME.
    If the object is already opened, returns its existing map.  */
-extern struct link_map *_dl_map_object (struct link_map *loader,
-					const char *name,
-					int type, int trace_mode, int mode,
-					Lmid_t nsid) attribute_hidden;
+struct link_map_private *_dl_map_object (struct link_map_private * loader,
+					 const char *name,
+					 int type, int trace_mode, int mode,
+					 Lmid_t nsid) attribute_hidden;
 
 /* Call _dl_map_object on the dependencies of MAP, and set up
    MAP->l_searchlist.  PRELOADS points to a vector of NPRELOADS previously
    loaded objects that will be inserted into MAP->l_searchlist after MAP
    but before its dependencies.  */
-extern void _dl_map_object_deps (struct link_map *map,
-				 struct link_map **preloads,
+extern void _dl_map_object_deps (struct link_map_private *map,
+				 struct link_map_private **preloads,
 				 unsigned int npreloads, int trace_mode,
 				 int open_mode)
      attribute_hidden;
 
 /* Cache the locations of MAP's hash table.  */
-extern void _dl_setup_hash (struct link_map *map) attribute_hidden;
+extern void _dl_setup_hash (struct link_map_private *map) attribute_hidden;
 
 
 /* Collect the directories in the search path for LOADER's dependencies.
@@ -938,12 +940,12 @@ extern void _dl_setup_hash (struct link_map *map) attribute_hidden;
    SI->dls_cnt and SI->dls_size are set; if false, those must be as set
    by a previous call with COUNTING set, and SI must point to SI->dls_size
    bytes to be used in filling in the result.  */
-extern void _dl_rtld_di_serinfo (struct link_map *loader,
+extern void _dl_rtld_di_serinfo (struct link_map_private *loader,
 				 Dl_serinfo *si, bool counting);
 
 /* Process PT_GNU_PROPERTY program header PH in module L after
    PT_LOAD segments are mapped from file FD.  */
-void _dl_process_pt_gnu_property (struct link_map *l, int fd,
+void _dl_process_pt_gnu_property (struct link_map_private *l, int fd,
 				  const ElfW(Phdr) *ph);
 
 
@@ -972,12 +974,12 @@ enum
 
 /* Lookup versioned symbol.  */
 extern lookup_t _dl_lookup_symbol_x (const char *undef,
-				     struct link_map *undef_map,
+				     struct link_map_private *undef_map,
 				     const ElfW(Sym) **sym,
 				     struct r_scope_elem *symbol_scope[],
 				     const struct r_found_version *version,
 				     int type_class, int flags,
-				     struct link_map *skip_map)
+				     struct link_map_private *skip_map)
      attribute_hidden;
 
 
@@ -988,53 +990,54 @@ extern lookup_t _dl_lookup_symbol_x (const char *undef,
    the symbol table entry in MAP on success, or NULL on failure.  MAP
    must have symbol versioning information, or otherwise the result is
    undefined.  */
-const ElfW(Sym) *_dl_lookup_direct (struct link_map *map,
+const ElfW(Sym) *_dl_lookup_direct (struct link_map_private *map,
 				    const char *undef_name,
 				    uint32_t new_hash,
 				    const char *version,
 				    uint32_t version_hash) attribute_hidden;
 
 /* Add the new link_map NEW to the end of the namespace list.  */
-extern void _dl_add_to_namespace_list (struct link_map *new, Lmid_t nsid)
-     attribute_hidden;
-
-/* Allocate a `struct link_map' for a new object being loaded.  */
-extern struct link_map *_dl_new_object (char *realname, const char *libname,
-					int type, struct link_map *loader,
-					int mode, Lmid_t nsid)
+extern void _dl_add_to_namespace_list (struct link_map_private *new,
+				       Lmid_t nsid) attribute_hidden;
+
+/* Allocate a `struct link_map_private' for a new object being loaded.  */
+struct link_map_private *_dl_new_object (char *realname,
+					 const char *libname, int type,
+					 struct link_map_private *loader,
+					 int mode, Lmid_t nsid)
      attribute_hidden;
 
 /* Relocate the given object (if it hasn't already been).
    SCOPE is passed to _dl_lookup_symbol in symbol lookups.
    If RTLD_LAZY is set in RELOC-MODE, don't relocate its PLT.  */
-extern void _dl_relocate_object (struct link_map *map,
+extern void _dl_relocate_object (struct link_map_private *map,
 				 struct r_scope_elem *scope[],
 				 int reloc_mode, int consider_profiling)
      attribute_hidden;
 
 /* Protect PT_GNU_RELRO area.  */
-extern void _dl_protect_relro (struct link_map *map) attribute_hidden;
+extern void _dl_protect_relro (struct link_map_private *map) attribute_hidden;
 
 /* Call _dl_signal_error with a message about an unhandled reloc type.
    TYPE is the result of ELFW(R_TYPE) (r_info), i.e. an R_<CPU>_* value.
    PLT is nonzero if this was a PLT reloc; it just affects the message.  */
-extern void _dl_reloc_bad_type (struct link_map *map,
+extern void _dl_reloc_bad_type (struct link_map_private *map,
 				unsigned int type, int plt)
      attribute_hidden __attribute__ ((__noreturn__));
 
 /* Check the version dependencies of all objects available through
    MAP.  If VERBOSE print some more diagnostics.  */
-extern int _dl_check_all_versions (struct link_map *map, int verbose,
+extern int _dl_check_all_versions (struct link_map_private *map, int verbose,
 				   int trace_mode) attribute_hidden;
 
 /* Check the version dependencies for MAP.  If VERBOSE print some more
    diagnostics.  */
-extern int _dl_check_map_versions (struct link_map *map, int verbose,
+extern int _dl_check_map_versions (struct link_map_private *map, int verbose,
 				   int trace_mode) attribute_hidden;
 
 /* Initialize the object in SCOPE by calling the constructors with
    ARGC, ARGV, and ENV as the parameters.  */
-extern void _dl_init (struct link_map *main_map, int argc, char **argv,
+extern void _dl_init (struct link_map_private *main_map, int argc, char **argv,
 		      char **env) attribute_hidden;
 
 /* Call the finalizer functions of all shared objects whose
@@ -1042,14 +1045,14 @@ extern void _dl_init (struct link_map *main_map, int argc, char **argv,
 extern void _dl_fini (void) attribute_hidden;
 
 /* Invoke the DT_FINI_ARRAY and DT_FINI destructors for MAP, which
-   must be a struct link_map *.  Can be used as an argument to
+   must be a struct link_map_private *.  Can be used as an argument to
    _dl_catch_exception.  */
 void _dl_call_fini (void *map) attribute_hidden;
 
 /* Sort array MAPS according to dependencies of the contained objects.
    If FORCE_FIRST, MAPS[0] keeps its place even if the dependencies
    say otherwise.  */
-extern void _dl_sort_maps (struct link_map **maps, unsigned int nmaps,
+extern void _dl_sort_maps (struct link_map_private **maps, unsigned int nmaps,
 			   bool force_first, bool for_fini) attribute_hidden;
 
 /* The dynamic linker calls this function before and having changing
@@ -1146,7 +1149,7 @@ extern void _dl_sysdep_start_cleanup (void) attribute_hidden;
 
 
 /* Determine next available module ID and set the L l_tls_modid.  */
-extern void _dl_assign_tls_modid (struct link_map *l) attribute_hidden;
+extern void _dl_assign_tls_modid (struct link_map_private *l) attribute_hidden;
 
 /* Count the modules with TLS segments.  */
 extern size_t _dl_count_modids (void) attribute_hidden;
@@ -1178,7 +1181,7 @@ void __libc_setup_tls (void);
 extern void _dl_relocate_static_pie (void) attribute_hidden;
 
 /* Get a pointer to _dl_main_map.  */
-extern struct link_map * _dl_get_dl_main_map (void)
+extern struct link_map_private * _dl_get_dl_main_map (void)
   __attribute__ ((visibility ("hidden")));
 # else
 #  define _dl_relocate_static_pie()
@@ -1204,7 +1207,7 @@ rtld_hidden_proto (_dl_allocate_tls)
 /* Get size and alignment requirements of the static TLS block.  */
 extern void _dl_get_tls_static_info (size_t *sizep, size_t *alignp);
 
-extern void _dl_allocate_static_tls (struct link_map *map) attribute_hidden;
+void _dl_allocate_static_tls (struct link_map_private *map) attribute_hidden;
 
 /* These are internal entry points to the two halves of _dl_allocate_tls,
    only used within rtld.c itself at startup time.  */
@@ -1219,14 +1222,14 @@ extern bool __rtld_tls_init_tp_called attribute_hidden;
 extern void _dl_deallocate_tls (void *tcb, bool dealloc_tcb);
 rtld_hidden_proto (_dl_deallocate_tls)
 
-extern void _dl_nothread_init_static_tls (struct link_map *) attribute_hidden;
+void _dl_nothread_init_static_tls (struct link_map_private *) attribute_hidden;
 
 /* Find origin of the executable.  */
 extern const char *_dl_get_origin (void) attribute_hidden;
 
 /* Substitute DST values.  */
 struct alloc_buffer;
-size_t _dl_dst_substitute (struct link_map *l, const char *name,
+size_t _dl_dst_substitute (struct link_map_private *l, const char *name,
 			   struct alloc_buffer *result)
      attribute_hidden __nonnull ((1, 2, 3));
 
@@ -1249,27 +1252,26 @@ extern int _dl_scope_free (void *) attribute_hidden;
    for the link map L with !do_add, then this function will not raise
    an exception, otherwise it is possible that it encounters a memory
    allocation failure.  */
-extern void _dl_add_to_slotinfo (struct link_map *l, bool do_add)
+extern void _dl_add_to_slotinfo (struct link_map_private *l, bool do_add)
   attribute_hidden;
 
 /* Update slot information data for at least the generation of the
    module with the given index.  */
-extern struct link_map *_dl_update_slotinfo (unsigned long int req_modid,
-					     size_t gen)
-     attribute_hidden;
+struct link_map_private *_dl_update_slotinfo (unsigned long int req_modid,
+					      size_t gen) attribute_hidden;
 
 /* Look up the module's TLS block as for __tls_get_addr,
    but never touch anything.  Return null if it's not allocated yet.  */
-extern void *_dl_tls_get_addr_soft (struct link_map *l) attribute_hidden;
+void *_dl_tls_get_addr_soft (struct link_map_private *l) attribute_hidden;
 
-extern int _dl_addr_inside_object (struct link_map *l, const ElfW(Addr) addr)
+int _dl_addr_inside_object (struct link_map_private *l, const ElfW(Addr) addr)
      attribute_hidden;
 
 /* Show show of an object.  */
-extern void _dl_show_scope (struct link_map *new, int from)
+extern void _dl_show_scope (struct link_map_private *new, int from)
      attribute_hidden;
 
-extern struct link_map *_dl_find_dso_for_object (const ElfW(Addr) addr);
+struct link_map_private *_dl_find_dso_for_object (const ElfW(Addr) addr);
 rtld_hidden_proto (_dl_find_dso_for_object)
 
 /* Initialization which is normally done by the dynamic linker.  */
@@ -1283,10 +1285,10 @@ extern void _dl_aux_init (ElfW(auxv_t) *av)
 /* Initialize the static TLS space for the link map in all existing
    threads. */
 #if PTHREAD_IN_LIBC
-void _dl_init_static_tls (struct link_map *map) attribute_hidden;
+void _dl_init_static_tls (struct link_map_private *map) attribute_hidden;
 #endif
 static inline void
-dl_init_static_tls (struct link_map *map)
+dl_init_static_tls (struct link_map_private *map)
 {
 #if PTHREAD_IN_LIBC
   /* The stack list is available to ld.so, so the initialization can
@@ -1301,7 +1303,7 @@ dl_init_static_tls (struct link_map *map)
 /* Called before relocating ld.so during static dlopen.  This can be
    used to partly initialize the dormant ld.so copy in the static
    dlopen namespace.  */
-void __rtld_static_init (struct link_map *map) attribute_hidden;
+void __rtld_static_init (struct link_map_private *map) attribute_hidden;
 #endif
 
 /* Return true if the ld.so copy in this namespace is actually active
@@ -1319,7 +1321,7 @@ rtld_active (void)
 }
 
 static inline struct auditstate *
-link_map_audit_state (struct link_map *l, size_t index)
+link_map_audit_state (struct link_map_private *l, size_t index)
 {
   if (l == &GL (dl_rtld_map))
     /* The auditstate array is stored separately.  */
@@ -1335,13 +1337,13 @@ link_map_audit_state (struct link_map *l, size_t index)
 /* Call the la_objsearch from the audit modules from the link map L.  If
    ORIGNAME is non NULL, it is updated with the revious name prior calling
    la_objsearch.  */
-const char *_dl_audit_objsearch (const char *name, struct link_map *l,
+const char *_dl_audit_objsearch (const char *name, struct link_map_private *l,
 				 unsigned int code)
    attribute_hidden;
 
 /* Call the la_activity from the audit modules from the link map L and issues
    the ACTION argument.  */
-void _dl_audit_activity_map (struct link_map *l, int action)
+void _dl_audit_activity_map (struct link_map_private *l, int action)
   attribute_hidden;
 
 /* Call the la_activity from the audit modules from the link map from the
@@ -1351,33 +1353,35 @@ void _dl_audit_activity_nsid (Lmid_t nsid, int action)
 
 /* Call the la_objopen from the audit modules for the link_map L on the
    namespace identification NSID.  */
-void _dl_audit_objopen (struct link_map *l, Lmid_t nsid)
+void _dl_audit_objopen (struct link_map_private *l, Lmid_t nsid)
   attribute_hidden;
 
 /* Call the la_objclose from the audit modules for the link_map L.  */
-void _dl_audit_objclose (struct link_map *l)
+void _dl_audit_objclose (struct link_map_private *l)
   attribute_hidden;
 
 /* Call the la_preinit from the audit modules for the link_map L.  */
-void _dl_audit_preinit (struct link_map *l);
+void _dl_audit_preinit (struct link_map_private *l);
 
 /* Call the la_symbind{32,64} from the audit modules for the link_map L.  If
    RELOC_RESULT is NULL it assumes the symbol to be bind-now and will set
    the flags with LA_SYMB_NOPLTENTER | LA_SYMB_NOPLTEXIT prior calling
    la_symbind{32,64}.  */
-void _dl_audit_symbind (struct link_map *l, struct reloc_result *reloc_result,
+void _dl_audit_symbind (struct link_map_private *l,
+			struct reloc_result *reloc_result,
 			const void *reloc, const ElfW(Sym) *defsym,
 			DL_FIXUP_VALUE_TYPE *value, lookup_t result, bool lazy)
   attribute_hidden;
 /* Same as _dl_audit_symbind, but also sets LA_SYMB_DLSYM flag.  */
-void _dl_audit_symbind_alt (struct link_map *l, const ElfW(Sym) *ref,
+void _dl_audit_symbind_alt (struct link_map_private *l, const ElfW(Sym) *ref,
 			    void **value, lookup_t result);
 rtld_hidden_proto (_dl_audit_symbind_alt)
-void _dl_audit_pltenter (struct link_map *l, struct reloc_result *reloc_result,
+void _dl_audit_pltenter (struct link_map_private *l,
+			 struct reloc_result *reloc_result,
 			 DL_FIXUP_VALUE_TYPE *value, void *regs,
 			 long int *framesize)
   attribute_hidden;
-void DL_ARCH_FIXUP_ATTRIBUTE _dl_audit_pltexit (struct link_map *l,
+void DL_ARCH_FIXUP_ATTRIBUTE _dl_audit_pltexit (struct link_map_private *l,
 						ElfW(Word) reloc_arg,
 						const void *inregs,
 						void *outregs)
diff --git a/sysdeps/generic/rtld_static_init.h b/sysdeps/generic/rtld_static_init.h
index 92543cd798..a482112760 100644
--- a/sysdeps/generic/rtld_static_init.h
+++ b/sysdeps/generic/rtld_static_init.h
@@ -17,7 +17,8 @@
    <https://www.gnu.org/licenses/>.  */
 
 static inline void
-__rtld_static_init_arch (struct link_map *map, struct rtld_global_ro *dl)
+__rtld_static_init_arch (struct link_map_private *map,
+                         struct rtld_global_ro *dl)
 {
   /* The generic helper does not perform any additional
      initialization.  */
diff --git a/sysdeps/hppa/dl-fptr.c b/sysdeps/hppa/dl-fptr.c
index 1c0d51ca9b..9015c40fc9 100644
--- a/sysdeps/hppa/dl-fptr.c
+++ b/sysdeps/hppa/dl-fptr.c
@@ -181,7 +181,7 @@ make_fdesc (ElfW(Addr) ip, ElfW(Addr) gp)
 
 
 static inline ElfW(Addr) * __attribute__ ((always_inline))
-make_fptr_table (struct link_map *map)
+make_fptr_table (struct link_map_private *map)
 {
   const ElfW(Sym) *symtab = (const void *) D_PTR (map, l_info[DT_SYMTAB]);
   const char *strtab = (const void *) D_PTR (map, l_info[DT_STRTAB]);
@@ -224,7 +224,7 @@ make_fptr_table (struct link_map *map)
 
 
 ElfW(Addr)
-_dl_make_fptr (struct link_map *map, const ElfW(Sym) *sym,
+_dl_make_fptr (struct link_map_private *map, const ElfW(Sym) *sym,
 	       ElfW(Addr) ip)
 {
   ElfW(Addr) *ftab = map->l_mach.fptr_table;
@@ -286,7 +286,7 @@ _dl_make_fptr (struct link_map *map, const ElfW(Sym) *sym,
 
 
 void
-_dl_unmap (struct link_map *map)
+_dl_unmap (struct link_map_private *map)
 {
   ElfW(Addr) *ftab = map->l_mach.fptr_table;
   struct fdesc *head = NULL, *tail = NULL;
@@ -322,7 +322,7 @@ _dl_unmap (struct link_map *map)
   map->l_mach.fptr_table = NULL;
 }
 
-extern ElfW(Addr) _dl_fixup (struct link_map *, ElfW(Word)) attribute_hidden;
+ElfW(Addr) _dl_fixup (struct link_map_private *, ElfW(Word)) attribute_hidden;
 
 static inline Elf32_Addr
 elf_machine_resolve (void)
@@ -396,7 +396,7 @@ _dl_lookup_address (const void *address)
       && gptr[1] == 0xd6801c1e			/* depwi 0,31,2,r20 */
       && (ElfW(Addr)) gptr[2] == elf_machine_resolve ())
     {
-      struct link_map *l = (struct link_map *) gptr[5];
+      struct link_map_private *l = (struct link_map *) gptr[5];
 
       /* If gp has been resolved, we need to hunt for relocation offset.  */
       if (!(reloc_arg & PA_GP_RELOC))
diff --git a/sysdeps/hppa/dl-lookupcfg.h b/sysdeps/hppa/dl-lookupcfg.h
index 28daf3f89b..e64dea69b0 100644
--- a/sysdeps/hppa/dl-lookupcfg.h
+++ b/sysdeps/hppa/dl-lookupcfg.h
@@ -22,9 +22,9 @@
 #include <dl-fptr.h>
 
 /* Forward declaration.  */
-struct link_map;
+struct link_map_private;
 
-void *_dl_symbol_address (struct link_map *map, const ElfW(Sym) *ref);
+void *_dl_symbol_address (struct link_map_private *map, const ElfW(Sym) *ref);
 rtld_hidden_proto (_dl_symbol_address)
 
 #define DL_SYMBOL_ADDRESS(map, ref) _dl_symbol_address(map, ref)
@@ -34,7 +34,7 @@ rtld_hidden_proto (_dl_lookup_address)
 
 #define DL_LOOKUP_ADDRESS(addr) _dl_lookup_address ((const void *) addr)
 
-void attribute_hidden _dl_unmap (struct link_map *map);
+void attribute_hidden _dl_unmap (struct link_map_private *map);
 
 #define DL_UNMAP(map) _dl_unmap (map)
 
diff --git a/sysdeps/hppa/dl-machine.h b/sysdeps/hppa/dl-machine.h
index 993593de5d..60ef82c3e7 100644
--- a/sysdeps/hppa/dl-machine.h
+++ b/sysdeps/hppa/dl-machine.h
@@ -59,7 +59,7 @@
 
 /* Initialize the function descriptor table before relocations */
 static inline void
-__hppa_init_bootstrap_fdesc_table (struct link_map *map)
+__hppa_init_bootstrap_fdesc_table (struct link_map_private *map)
 {
   ElfW(Addr) *boot_table;
 
@@ -118,7 +118,7 @@ elf_machine_load_address (void)
 
 /* Fixup a PLT entry to bounce directly to the function at VALUE. */
 static inline struct fdesc __attribute__ ((always_inline))
-elf_machine_fixup_plt (struct link_map *map, lookup_t t,
+elf_machine_fixup_plt (struct link_map_private *map, lookup_t t,
 		       const ElfW(Sym) *refsym, const ElfW(Sym) *sym,
 		       const Elf32_Rela *reloc,
 		       Elf32_Addr *reloc_addr, struct fdesc value)
@@ -153,7 +153,7 @@ elf_machine_fixup_plt (struct link_map *map, lookup_t t,
 
 /* Return the final value of a plt relocation.  */
 static inline struct fdesc
-elf_machine_plt_value (struct link_map *map, const Elf32_Rela *reloc,
+elf_machine_plt_value (struct link_map_private *map, const Elf32_Rela *reloc,
 		       struct fdesc value)
 {
   /* We are rela only, return a function descriptor as a plt entry. */
@@ -164,7 +164,8 @@ elf_machine_plt_value (struct link_map *map, const Elf32_Rela *reloc,
    entries will jump to the on-demand fixup code in dl-runtime.c.  */
 
 static inline int
-elf_machine_runtime_setup (struct link_map *l, struct r_scope_elem *scope[],
+elf_machine_runtime_setup (struct link_map_private *l,
+			   struct r_scope_elem *scope[],
 			   int lazy, int profile)
 {
   Elf32_Addr *got = NULL;
@@ -190,7 +191,7 @@ elf_machine_runtime_setup (struct link_map *l, struct r_scope_elem *scope[],
     return lazy;
 
   /* All paths use these values */
-  l_addr = l->l_addr;
+  l_addr = l->l_public.l_addr;
   jmprel = D_PTR(l, l_info[DT_JMPREL]);
   end_jmprel = jmprel + l->l_info[DT_PLTRELSZ]->d_un.d_val;
 
@@ -350,8 +351,8 @@ elf_machine_runtime_setup (struct link_map *l, struct r_scope_elem *scope[],
 
 #define RTLD_START \
 /* Set up dp for any non-PIC lib constructors that may be called.  */	\
-static struct link_map * __attribute__((used))				\
-set_dp (struct link_map *map)						\
+static struct link_map_private * __attribute__((used))			\
+set_dp (struct link_map_private *map)					\
 {									\
   register Elf32_Addr dp asm ("%r27");					\
   dp = D_PTR (map, l_info[DT_PLTGOT]);					\
@@ -552,7 +553,7 @@ dl_platform_init (void)
    | (((as14) & 0x2000) >> 13))
 
 static void __attribute__((always_inline))
-elf_machine_rela (struct link_map *map, struct r_scope_elem *scope[],
+elf_machine_rela (struct link_map_private *map, struct r_scope_elem *scope[],
 		  const Elf32_Rela *reloc,
 		  const Elf32_Sym *sym,
 		  const struct r_found_version *version,
@@ -562,7 +563,7 @@ elf_machine_rela (struct link_map *map, struct r_scope_elem *scope[],
   Elf32_Addr *const reloc_addr = reloc_addr_arg;
   const Elf32_Sym *const refsym = sym;
   unsigned long const r_type = ELF32_R_TYPE (reloc->r_info);
-  struct link_map *sym_map;
+  struct link_map_private *sym_map;
   Elf32_Addr value;
 
   /* RESOLVE_MAP will return a null value for undefined syms, and
@@ -740,7 +741,7 @@ elf_machine_rela_relative (Elf32_Addr l_addr,
   unsigned long const r_type = ELF32_R_TYPE (reloc->r_info);
   Elf32_Addr *const reloc_addr = reloc_addr_arg;
   static char msgbuf[] = { "Unknown" };
-  struct link_map map;
+  struct link_map_private map;
   Elf32_Addr value;
 
   value = l_addr + reloc->r_addend;
@@ -777,7 +778,7 @@ elf_machine_rela_relative (Elf32_Addr l_addr,
       return;
 
     default: /* Bad reloc, map unknown (really it's the current map) */
-      map.l_name = msgbuf;
+      map.l_public.l_name = msgbuf;
       _dl_reloc_bad_type (&map, r_type, 0);
       return;
     }
@@ -786,7 +787,8 @@ elf_machine_rela_relative (Elf32_Addr l_addr,
 }
 
 static void __attribute__((always_inline))
-elf_machine_lazy_rel (struct link_map *map, struct r_scope_elem *scope[],
+elf_machine_lazy_rel (struct link_map_private *map,
+		      struct r_scope_elem *scope[],
 		      Elf32_Addr l_addr, const Elf32_Rela *reloc,
 		      int skip_ifunc)
 {
diff --git a/sysdeps/hppa/dl-runtime.c b/sysdeps/hppa/dl-runtime.c
index bebf640725..61095bdbcf 100644
--- a/sysdeps/hppa/dl-runtime.c
+++ b/sysdeps/hppa/dl-runtime.c
@@ -26,12 +26,12 @@
    _dl_fixup with the relocation offset.  */
 
 ElfW(Word) __attribute ((noinline)) DL_ARCH_FIXUP_ATTRIBUTE
-_dl_fix_reloc_arg (struct fdesc *fptr, struct link_map *l)
+_dl_fix_reloc_arg (struct fdesc *fptr, struct link_map_private *l)
 {
   Elf32_Addr l_addr, iplt, jmprel, end_jmprel, r_type;
   const Elf32_Rela *reloc;
 
-  l_addr = l->l_addr;
+  l_addr = l->l_public.l_addr;
   jmprel = D_PTR(l, l_info[DT_JMPREL]);
   end_jmprel = jmprel + l->l_info[DT_PLTRELSZ]->d_un.d_val;
 
diff --git a/sysdeps/hppa/dl-runtime.h b/sysdeps/hppa/dl-runtime.h
index 5dbe762fee..7a44279aa7 100644
--- a/sysdeps/hppa/dl-runtime.h
+++ b/sysdeps/hppa/dl-runtime.h
@@ -17,7 +17,7 @@
    Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA
    02111-1307 USA.  */
 
-ElfW(Word) _dl_fix_reloc_arg (struct fdesc *, struct link_map *);
+ElfW(Word) _dl_fix_reloc_arg (struct fdesc *, struct link_map_private *);
 rtld_hidden_proto (_dl_fix_reloc_arg)
 
 /* Clear PA_GP_RELOC bit in relocation offset.  */
diff --git a/sysdeps/hppa/dl-symaddr.c b/sysdeps/hppa/dl-symaddr.c
index 3b5a000dd8..bfc720ed92 100644
--- a/sysdeps/hppa/dl-symaddr.c
+++ b/sysdeps/hppa/dl-symaddr.c
@@ -20,7 +20,7 @@
 #include <dl-machine.h>
 
 void *
-_dl_symbol_address (struct link_map *map, const ElfW(Sym) *ref)
+_dl_symbol_address (struct link_map_private *map, const ElfW(Sym) *ref)
 {
   /* Find the "ip" from the "map" and symbol "ref" */
   Elf32_Addr value = SYMBOL_ADDRESS (map, ref, false);
diff --git a/sysdeps/htl/pthreadP.h b/sysdeps/htl/pthreadP.h
index 3f052f0e53..d178aa63c4 100644
--- a/sysdeps/htl/pthreadP.h
+++ b/sysdeps/htl/pthreadP.h
@@ -27,7 +27,7 @@
 /* Attribute to indicate thread creation was issued from C11 thrd_create.  */
 #define ATTR_C11_THREAD ((void*)(uintptr_t)-1)
 
-extern void __pthread_init_static_tls (struct link_map *) attribute_hidden;
+void __pthread_init_static_tls (struct link_map_private *) attribute_hidden;
 
 /* These represent the interface used by glibc itself.  */
 
diff --git a/sysdeps/i386/dl-machine.h b/sysdeps/i386/dl-machine.h
index 07469e99b0..b0bba3621f 100644
--- a/sysdeps/i386/dl-machine.h
+++ b/sysdeps/i386/dl-machine.h
@@ -57,7 +57,8 @@ elf_machine_dynamic (void)
    entries will jump to the on-demand fixup code in dl-runtime.c.  */
 
 static inline int __attribute__ ((unused, always_inline))
-elf_machine_runtime_setup (struct link_map *l, struct r_scope_elem *scope[],
+elf_machine_runtime_setup (struct link_map_private *l,
+			   struct r_scope_elem *scope[],
 			   int lazy, int profile)
 {
   Elf32_Addr *got;
@@ -81,7 +82,7 @@ elf_machine_runtime_setup (struct link_map *l, struct r_scope_elem *scope[],
 	 The prelinker saved us here address of .plt + 0x16.  */
       if (got[1])
 	{
-	  l->l_mach.plt = got[1] + l->l_addr;
+	  l->l_mach.plt = got[1] + l->l_public.l_addr;
 	  l->l_mach.gotplt = (Elf32_Addr) &got[3];
 	}
       got[1] = (Elf32_Addr) l;	/* Identify this shared object.  */
@@ -217,7 +218,7 @@ dl_platform_init (void)
 }
 
 static inline Elf32_Addr
-elf_machine_fixup_plt (struct link_map *map, lookup_t t,
+elf_machine_fixup_plt (struct link_map_private *map, lookup_t t,
 		       const ElfW(Sym) *refsym, const ElfW(Sym) *sym,
 		       const Elf32_Rel *reloc,
 		       Elf32_Addr *reloc_addr, Elf32_Addr value)
@@ -227,7 +228,7 @@ elf_machine_fixup_plt (struct link_map *map, lookup_t t,
 
 /* Return the final value of a plt relocation.  */
 static inline Elf32_Addr
-elf_machine_plt_value (struct link_map *map, const Elf32_Rel *reloc,
+elf_machine_plt_value (struct link_map_private *map, const Elf32_Rel *reloc,
 		       Elf32_Addr value)
 {
   return value;
@@ -247,7 +248,7 @@ elf_machine_plt_value (struct link_map *map, const Elf32_Rel *reloc,
 
 static inline void
 __attribute ((always_inline))
-elf_machine_rel (struct link_map *map, struct r_scope_elem *scope[],
+elf_machine_rel (struct link_map_private *map, struct r_scope_elem *scope[],
 		 const Elf32_Rel *reloc,
 		 const Elf32_Sym *sym, const struct r_found_version *version,
 		 void *const reloc_addr_arg, int skip_ifunc)
@@ -257,7 +258,7 @@ elf_machine_rel (struct link_map *map, struct r_scope_elem *scope[],
 
 # if !defined RTLD_BOOTSTRAP
   if (__glibc_unlikely (r_type == R_386_RELATIVE))
-    *reloc_addr += map->l_addr;
+    *reloc_addr += map->l_public.l_addr;
 #  ifndef RTLD_BOOTSTRAP
   else if (__glibc_unlikely (r_type == R_386_NONE))
     return;
@@ -268,8 +269,8 @@ elf_machine_rel (struct link_map *map, struct r_scope_elem *scope[],
 # ifndef RTLD_BOOTSTRAP
       const Elf32_Sym *const refsym = sym;
 # endif
-      struct link_map *sym_map = RESOLVE_MAP (map, scope, &sym, version,
-					      r_type);
+      struct link_map_private *sym_map
+	= RESOLVE_MAP (map, scope, &sym, version, r_type);
       Elf32_Addr value = SYMBOL_ADDRESS (sym_map, sym, true);
 
       if (sym != NULL
@@ -288,12 +289,12 @@ elf_machine_rel (struct link_map *map, struct r_scope_elem *scope[],
 %s: IFUNC symbol '%s' referenced in '%s' is defined in the executable \
 and creates an unsatisfiable circular dependency.\n",
 				  RTLD_PROGNAME, strtab + refsym->st_name,
-				  map->l_name);
+				  map->l_public.l_name);
 	      else
 		_dl_error_printf ("\
 %s: Relink `%s' with `%s' for IFUNC symbol `%s'\n",
-				  RTLD_PROGNAME, map->l_name,
-				  sym_map->l_name,
+				  RTLD_PROGNAME, map->l_public.l_name,
+				  sym_map->l_public.l_name,
 				  strtab + refsym->st_name);
 	    }
 # endif
@@ -426,7 +427,7 @@ and creates an unsatisfiable circular dependency.\n",
 		  MIN (sym->st_size, refsym->st_size));
 	  break;
 	case R_386_IRELATIVE:
-	  value = map->l_addr + *reloc_addr;
+	  value = map->l_public.l_addr + *reloc_addr;
 	  if (__glibc_likely (!skip_ifunc))
 	    value = ((Elf32_Addr (*) (void)) value) ();
 	  *reloc_addr = value;
@@ -463,7 +464,8 @@ elf_machine_rela_relative (Elf32_Addr l_addr, const Elf32_Rela *reloc,
 
 static inline void
 __attribute__ ((always_inline))
-elf_machine_lazy_rel (struct link_map *map, struct r_scope_elem *scope[],
+elf_machine_lazy_rel (struct link_map_private *map,
+		      struct r_scope_elem *scope[],
 		      Elf32_Addr l_addr, const Elf32_Rel *reloc,
 		      int skip_ifunc)
 {
@@ -510,7 +512,7 @@ elf_machine_lazy_rel (struct link_map *map, struct r_scope_elem *scope[],
     }
   else if (__glibc_unlikely (r_type == R_386_IRELATIVE))
     {
-      Elf32_Addr value = map->l_addr + *reloc_addr;
+      Elf32_Addr value = map->l_public.l_addr + *reloc_addr;
       if (__glibc_likely (!skip_ifunc))
 	value = ((Elf32_Addr (*) (void)) value) ();
       *reloc_addr = value;
diff --git a/sysdeps/i386/dl-tlsdesc.h b/sysdeps/i386/dl-tlsdesc.h
index 312905eb93..0851d833cb 100644
--- a/sysdeps/i386/dl-tlsdesc.h
+++ b/sysdeps/i386/dl-tlsdesc.h
@@ -46,7 +46,7 @@ extern ptrdiff_t attribute_hidden __attribute__ ((regparm (1)))
   _dl_tlsdesc_undefweak (struct tlsdesc *);
 
 # ifdef SHARED
-extern void *_dl_make_tlsdesc_dynamic (struct link_map *map,
+extern void *_dl_make_tlsdesc_dynamic (struct link_map_private *map,
 				       size_t ti_offset) attribute_hidden;
 
 extern ptrdiff_t attribute_hidden __attribute__ ((regparm (1)))
diff --git a/sysdeps/i386/tlsdesc.c b/sysdeps/i386/tlsdesc.c
index b5c6a06e13..b2dbd7634a 100644
--- a/sysdeps/i386/tlsdesc.c
+++ b/sysdeps/i386/tlsdesc.c
@@ -26,7 +26,7 @@
    if there is one.  */
 
 void
-_dl_unmap (struct link_map *map)
+_dl_unmap (struct link_map_private *map)
 {
   _dl_unmap_segments (map);
 
diff --git a/sysdeps/ia64/dl-lookupcfg.h b/sysdeps/ia64/dl-lookupcfg.h
index 64218fa7bb..e12da0e149 100644
--- a/sysdeps/ia64/dl-lookupcfg.h
+++ b/sysdeps/ia64/dl-lookupcfg.h
@@ -25,9 +25,9 @@
 #define DL_NO_COPY_RELOCS
 
 /* Forward declaration.  */
-struct link_map;
+struct link_map_private;
 
-extern void *_dl_symbol_address (struct link_map *map, const Elf64_Sym *ref);
+void *_dl_symbol_address (struct link_map_private *, const Elf64_Sym *ref);
 rtld_hidden_proto (_dl_symbol_address)
 
 #define DL_SYMBOL_ADDRESS(map, ref) _dl_symbol_address(map, ref)
@@ -36,7 +36,7 @@ extern Elf64_Addr _dl_lookup_address (const void *address);
 
 #define DL_LOOKUP_ADDRESS(addr) _dl_lookup_address (addr)
 
-extern void attribute_hidden _dl_unmap (struct link_map *map);
+extern void attribute_hidden _dl_unmap (struct link_map_private *map);
 
 #define DL_UNMAP(map) _dl_unmap (map)
 
diff --git a/sysdeps/ia64/dl-machine.h b/sysdeps/ia64/dl-machine.h
index 3ef6b0ef4b..e9c59dc65a 100644
--- a/sysdeps/ia64/dl-machine.h
+++ b/sysdeps/ia64/dl-machine.h
@@ -35,7 +35,7 @@
 #define DT_IA_64(x) (DT_IA_64_##x - DT_LOPROC + DT_NUM)
 
 static inline void __attribute__ ((always_inline))
-__ia64_init_bootstrap_fdesc_table (struct link_map *map)
+__ia64_init_bootstrap_fdesc_table (struct link_map_private *map)
 {
   Elf64_Addr *boot_table;
 
@@ -100,7 +100,8 @@ elf_machine_load_address (void)
    entries will jump to the on-demand fixup code in dl-runtime.c.  */
 
 static inline int __attribute__ ((unused, always_inline))
-elf_machine_runtime_setup (struct link_map *l, struct r_scope_elem *scope[],
+elf_machine_runtime_setup (struct link_map_private *l,
+			   struct r_scope_elem *scope[],
 			   int lazy, int profile)
 {
   extern void _dl_runtime_resolve (void);
@@ -112,11 +113,12 @@ elf_machine_runtime_setup (struct link_map *l, struct r_scope_elem *scope[],
       Elf64_Addr *reserve, doit;
 
       /*
-       * Careful with the typecast here or it will try to add l-l_addr
+       * Careful with the typecast here or it will try to add l_addr
        * pointer elements
        */
       reserve = ((Elf64_Addr *)
-		 (l->l_info[DT_IA_64 (PLT_RESERVE)]->d_un.d_ptr + l->l_addr));
+		 (l->l_info[DT_IA_64 (PLT_RESERVE)]->d_un.d_ptr
+		  + l->l_public.l_addr));
       /* Identify this shared object.  */
       reserve[0] = (Elf64_Addr) l;
 
@@ -293,7 +295,7 @@ elf_machine_runtime_setup (struct link_map *l, struct r_scope_elem *scope[],
 
 /* Fixup a PLT entry to bounce directly to the function at VALUE.  */
 static inline struct fdesc __attribute__ ((always_inline))
-elf_machine_fixup_plt (struct link_map *l, lookup_t t,
+elf_machine_fixup_plt (struct link_map_private *l, lookup_t t,
 		       const ElfW(Sym) *refsym, const ElfW(Sym) *sym,
 		       const Elf64_Rela *reloc,
 		       Elf64_Addr *reloc_addr, struct fdesc value)
@@ -310,7 +312,7 @@ elf_machine_fixup_plt (struct link_map *l, lookup_t t,
 
 /* Return the final value of a plt relocation.  */
 static inline struct fdesc
-elf_machine_plt_value (struct link_map *map, const Elf64_Rela *reloc,
+elf_machine_plt_value (struct link_map_private *map, const Elf64_Rela *reloc,
 		       struct fdesc value)
 {
   /* No need to handle rel vs rela since IA64 is rela only */
@@ -334,7 +336,7 @@ elf_machine_plt_value (struct link_map *map, const Elf64_Rela *reloc,
    resolved).  MAP is the object containing the reloc.  */
 static inline void
 __attribute ((always_inline))
-elf_machine_rela (struct link_map *map, struct r_scope_elem *scope[],
+elf_machine_rela (struct link_map_private *map, struct r_scope_elem *scope[],
 		  const Elf64_Rela *reloc,
 		  const Elf64_Sym *sym,
 		  const struct r_found_version *version,
@@ -353,7 +355,7 @@ elf_machine_rela (struct link_map *map, struct r_scope_elem *scope[],
 			0))
     {
       assert (ELF64_R_TYPE (reloc->r_info) == R_IA64_REL64LSB);
-      value = *reloc_addr + map->l_addr;
+      value = *reloc_addr + map->l_public.l_addr;
     }
   else
 #endif
@@ -361,8 +363,8 @@ elf_machine_rela (struct link_map *map, struct r_scope_elem *scope[],
       return;
   else
     {
-      struct link_map *sym_map = RESOLVE_MAP (map, scope, &sym, version,
-					      r_type);
+      struct link_map_private *sym_map
+	= RESOLVE_MAP (map, scope, &sym, version, r_type);
 
       /* RESOLVE_MAP() will return NULL if it fail to locate the symbol.  */
       if (sym_map != NULL)
@@ -390,14 +392,14 @@ elf_machine_rela (struct link_map *map, struct r_scope_elem *scope[],
 	       resolv function.  */
 	    value = sym_map->l_tls_modid;
 	  else if (R_IA64_TYPE (r_type) == R_IA64_TYPE (R_IA64_DTPREL64LSB))
-	    value -= sym_map->l_addr;
+	    value -= sym_map->l_public.l_addr;
 #endif
 	  else if (R_IA64_TYPE (r_type) == R_IA64_TYPE (R_IA64_TPREL64LSB))
 	    {
 #ifndef RTLD_BOOTSTRAP
 	      CHECK_STATIC_TLS (map, sym_map);
 #endif
-	      value += sym_map->l_tls_offset - sym_map->l_addr;
+	      value += sym_map->l_tls_offset - sym_map->l_public.l_addr;
 	    }
 	  else
 	    _dl_reloc_bad_type (map, r_type, 0);
@@ -439,7 +441,8 @@ elf_machine_rela_relative (Elf64_Addr l_addr, const Elf64_Rela *reloc,
 /* Perform a RELATIVE reloc on the .got entry that transfers to the .plt.  */
 static inline void
 __attribute ((always_inline))
-elf_machine_lazy_rel (struct link_map *map, struct r_scope_elem *scope[],
+elf_machine_lazy_rel (struct link_map_private *map,
+		      struct r_scope_elem *scope[],
 		      Elf64_Addr l_addr, const Elf64_Rela *reloc,
 		      int skip_ifunc)
 {
diff --git a/sysdeps/loongarch/dl-machine.h b/sysdeps/loongarch/dl-machine.h
index 0d17fd21e3..683d5f4e7e 100644
--- a/sysdeps/loongarch/dl-machine.h
+++ b/sysdeps/loongarch/dl-machine.h
@@ -93,7 +93,7 @@ static inline ElfW (Addr) elf_machine_dynamic (void)
 	or	$s0, $a0, $zero   \n\
 	# Load the original argument count.   \n\
 	ld.d	$a1, $sp, 0   \n\
-	# Call _dl_init (struct link_map *main_map, int argc, \
+	# Call _dl_init (struct link_map_private *main_map, int argc, \
 			 char **argv, char **env)    \n\
 	la	$a0, _rtld_local   \n\
 	ld.d	$a0, $a0, 0   \n\
@@ -124,7 +124,7 @@ static inline ElfW (Addr) elf_machine_dynamic (void)
 #define elf_machine_plt_value(map, reloc, value) (value)
 
 static inline ElfW (Addr)
-elf_machine_fixup_plt (struct link_map *map, lookup_t t,
+elf_machine_fixup_plt (struct link_map_private *map, lookup_t t,
 			 const ElfW (Sym) *refsym, const ElfW (Sym) *sym,
 			 const ElfW (Rela) *reloc, ElfW (Addr) *reloc_addr,
 			 ElfW (Addr) value)
@@ -141,7 +141,7 @@ elf_machine_fixup_plt (struct link_map *map, lookup_t t,
    MAP is the object containing the reloc.  */
 
 static inline void __attribute__ ((always_inline))
-elf_machine_rela (struct link_map *map, struct r_scope_elem *scope[],
+elf_machine_rela (struct link_map_private *map, struct r_scope_elem *scope[],
 		  const ElfW (Rela) *reloc,
 		  const ElfW (Sym) *sym,
 		  const struct r_found_version *version,
@@ -151,7 +151,8 @@ elf_machine_rela (struct link_map *map, struct r_scope_elem *scope[],
   const unsigned long int r_type = ELFW (R_TYPE) (r_info);
   ElfW (Addr) *addr_field = (ElfW (Addr) *) reloc_addr;
   const ElfW (Sym) *const __attribute__ ((unused)) refsym = sym;
-  struct link_map *sym_map = RESOLVE_MAP (map, scope, &sym, version, r_type);
+  struct link_map_private *sym_map
+    = RESOLVE_MAP (map, scope, &sym, version, r_type);
   ElfW (Addr) value = 0;
   if (sym_map != NULL)
     value = SYMBOL_ADDRESS (sym_map, sym, true) + reloc->r_addend;
@@ -211,11 +212,11 @@ elf_machine_rela (struct link_map *map, struct r_scope_elem *scope[],
       }
 
     case R_LARCH_RELATIVE:
-      *addr_field = map->l_addr + reloc->r_addend;
+      *addr_field = map->l_public.l_addr + reloc->r_addend;
       break;
 
     case R_LARCH_IRELATIVE:
-      value = map->l_addr + reloc->r_addend;
+      value = map->l_public.l_addr + reloc->r_addend;
       if (__glibc_likely (!skip_ifunc))
 	value = ((ElfW (Addr) (*) (void)) value) ();
       *addr_field = value;
@@ -237,7 +238,8 @@ elf_machine_rela_relative (ElfW (Addr) l_addr, const ElfW (Rela) *reloc,
 }
 
 static inline void __attribute__ ((always_inline))
-elf_machine_lazy_rel (struct link_map *map, struct r_scope_elem *scope[],
+elf_machine_lazy_rel (struct link_map_private *map,
+		      struct r_scope_elem *scope[],
 		      ElfW (Addr) l_addr,
 		      const ElfW (Rela) *reloc, int skip_ifunc)
 {
@@ -263,7 +265,8 @@ elf_machine_lazy_rel (struct link_map *map, struct r_scope_elem *scope[],
    will jump to the on-demand fixup code __dl_runtime_resolve.  */
 
 static inline int __attribute__ ((always_inline))
-elf_machine_runtime_setup (struct link_map *l, struct r_scope_elem *scope[],
+elf_machine_runtime_setup (struct link_map_private *l,
+			   struct r_scope_elem *scope[],
 			   int lazy, int profile)
 {
 #ifndef RTLD_BOOTSTRAP
diff --git a/sysdeps/m68k/dl-machine.h b/sysdeps/m68k/dl-machine.h
index 8d7e733e2a..6bba7315c3 100644
--- a/sysdeps/m68k/dl-machine.h
+++ b/sysdeps/m68k/dl-machine.h
@@ -70,7 +70,8 @@ elf_machine_load_address (void)
    entries will jump to the on-demand fixup code in dl-runtime.c.  */
 
 static inline int __attribute__ ((always_inline))
-elf_machine_runtime_setup (struct link_map *l, struct r_scope_elem *scope[],
+elf_machine_runtime_setup (struct link_map_private *l,
+			   struct r_scope_elem *scope[],
 			   int lazy, int profile)
 {
   Elf32_Addr *got;
@@ -146,7 +147,7 @@ _dl_start_user:\n\
 	move.l %d0, %a4\n\
 	| Load the adjusted argument count.\n\
 	move.l (%sp), %d1\n\
-	# Call _dl_init (struct link_map *main_map, int argc, char **argv, char **env)\n\
+	# Call _dl_init (struct link_map_private *main_map, int argc, char **argv, char **env)\n\
 	pea 8(%sp, %d1*4)\n\
 	pea 8(%sp)\n\
 	move.l %d1, -(%sp)\n\
@@ -179,7 +180,7 @@ _dl_start_user:\n\
 #define ELF_MACHINE_JMP_SLOT	R_68K_JMP_SLOT
 
 static inline Elf32_Addr
-elf_machine_fixup_plt (struct link_map *map, lookup_t t,
+elf_machine_fixup_plt (struct link_map_private *map, lookup_t t,
 		       const ElfW(Sym) *refsym, const ElfW(Sym) *sym,
 		       const Elf32_Rela *reloc,
 		       Elf32_Addr *reloc_addr, Elf32_Addr value)
@@ -190,7 +191,7 @@ elf_machine_fixup_plt (struct link_map *map, lookup_t t,
 /* Return the final value of a plt relocation.  On the m68k the JMP_SLOT
    relocation ignores the addend.  */
 static inline Elf32_Addr
-elf_machine_plt_value (struct link_map *map, const Elf32_Rela *reloc,
+elf_machine_plt_value (struct link_map_private *map, const Elf32_Rela *reloc,
 		       Elf32_Addr value)
 {
   return value;
@@ -208,7 +209,7 @@ elf_machine_plt_value (struct link_map *map, const Elf32_Rela *reloc,
    MAP is the object containing the reloc.  */
 
 static inline void __attribute__ ((unused, always_inline))
-elf_machine_rela (struct link_map *map, struct r_scope_elem *scope[],
+elf_machine_rela (struct link_map_private *map, struct r_scope_elem *scope[],
 		  const Elf32_Rela *reloc, const Elf32_Sym *sym,
 		  const struct r_found_version *version,
 		  void *const reloc_addr_arg, int skip_ifunc)
@@ -217,12 +218,12 @@ elf_machine_rela (struct link_map *map, struct r_scope_elem *scope[],
   const unsigned int r_type = ELF32_R_TYPE (reloc->r_info);
 
   if (__builtin_expect (r_type == R_68K_RELATIVE, 0))
-    *reloc_addr = map->l_addr + reloc->r_addend;
+    *reloc_addr = map->l_public.l_addr + reloc->r_addend;
   else
     {
       const Elf32_Sym *const refsym = sym;
-      struct link_map *sym_map = RESOLVE_MAP (map, scope, &sym, version,
-					      r_type);
+      struct link_map_private *sym_map
+	= RESOLVE_MAP (map, scope, &sym, version, r_type);
       Elf32_Addr value = SYMBOL_ADDRESS (sym_map, sym, true);
 
       switch (r_type)
@@ -306,7 +307,8 @@ elf_machine_rela_relative (Elf32_Addr l_addr, const Elf32_Rela *reloc,
 }
 
 static inline void __attribute__ ((unused, always_inline))
-elf_machine_lazy_rel (struct link_map *map, struct r_scope_elem *scope[],
+elf_machine_lazy_rel (struct link_map_private *map,
+		      struct r_scope_elem *scope[],
 		      Elf32_Addr l_addr, const Elf32_Rela *reloc,
 		      int skip_ifunc)
 {
diff --git a/sysdeps/microblaze/dl-machine.h b/sysdeps/microblaze/dl-machine.h
index da875b68c5..e8f9cebe2f 100644
--- a/sysdeps/microblaze/dl-machine.h
+++ b/sysdeps/microblaze/dl-machine.h
@@ -71,7 +71,8 @@ elf_machine_load_address (void)
    entries will jump to the on-demand fixup code in dl-runtime.c.  */
 
 static inline int __attribute__ ((always_inline))
-elf_machine_runtime_setup (struct link_map *l, struct r_scope_elem *scope[],
+elf_machine_runtime_setup (struct link_map_private *l,
+			   struct r_scope_elem *scope[],
 			   int lazy, int profile)
 {
   extern void _dl_runtime_resolve (Elf32_Word);
@@ -167,7 +168,7 @@ _dl_start_user:\n\
 #define ELF_MACHINE_JMP_SLOT	R_MICROBLAZE_JUMP_SLOT
 
 static inline Elf32_Addr
-elf_machine_fixup_plt (struct link_map *map, lookup_t t,
+elf_machine_fixup_plt (struct link_map_private *map, lookup_t t,
 		       const ElfW(Sym) *refsym, const ElfW(Sym) *sym,
 		       const Elf32_Rela *reloc,
 		       Elf32_Addr *reloc_addr, Elf32_Addr value)
@@ -177,7 +178,7 @@ elf_machine_fixup_plt (struct link_map *map, lookup_t t,
 
 /* Return the final value of a plt relocation. Ignore the addend.  */
 static inline Elf32_Addr
-elf_machine_plt_value (struct link_map *map, const Elf32_Rela *reloc,
+elf_machine_plt_value (struct link_map_private *map, const Elf32_Rela *reloc,
 		       Elf32_Addr value)
 {
   return value;
@@ -202,7 +203,7 @@ elf_machine_plt_value (struct link_map *map, const Elf32_Rela *reloc,
   } while (0)
 
 static inline void __attribute__ ((always_inline))
-elf_machine_rela (struct link_map *map, struct r_scope_elem *scope[],
+elf_machine_rela (struct link_map_private *map, struct r_scope_elem *scope[],
 		  const Elf32_Rela *reloc, const Elf32_Sym *sym,
 		  const struct r_found_version *version,
 		  void *const reloc_addr_arg, int skip_ifunc)
@@ -211,14 +212,14 @@ elf_machine_rela (struct link_map *map, struct r_scope_elem *scope[],
   const int r_type = ELF32_R_TYPE (reloc->r_info);
 
   if (__builtin_expect (r_type == R_MICROBLAZE_64_PCREL, 0))
-    PUT_REL_64 (reloc_addr, map->l_addr + reloc->r_addend);
+    PUT_REL_64 (reloc_addr, map->l_public.l_addr + reloc->r_addend);
   else if (r_type == R_MICROBLAZE_REL)
-    *reloc_addr = map->l_addr + reloc->r_addend;
+    *reloc_addr = map->l_public.l_addr + reloc->r_addend;
   else
     {
       const Elf32_Sym *const refsym = sym;
-      struct link_map *sym_map = RESOLVE_MAP (map, scope, &sym, version,
-					      r_type);
+      struct link_map_private *sym_map
+	= RESOLVE_MAP (map, scope, &sym, version, r_type);
       Elf32_Addr value = SYMBOL_ADDRESS (sym_map, sym, true);
 
       value += reloc->r_addend;
@@ -282,7 +283,8 @@ elf_machine_rela_relative (Elf32_Addr l_addr, const Elf32_Rela *reloc,
 }
 
 static inline void
-elf_machine_lazy_rel (struct link_map *map, struct r_scope_elem *scope[],
+elf_machine_lazy_rel (struct link_map_private *map,
+		      struct r_scope_elem *scope[],
 		      Elf32_Addr l_addr, const Elf32_Rela *reloc,
 		      int skip_ifunc)
 {
diff --git a/sysdeps/mips/dl-debug.h b/sysdeps/mips/dl-debug.h
index 584ae0da1c..3966b6a8db 100644
--- a/sysdeps/mips/dl-debug.h
+++ b/sysdeps/mips/dl-debug.h
@@ -25,7 +25,7 @@
 
 static inline void
 __attribute ((always_inline))
-elf_setup_debug_entry (struct link_map *l, struct r_debug *r)
+elf_setup_debug_entry (struct link_map_private *l, struct r_debug *r)
 {
   if (l->l_info[DT_MIPS (RLD_MAP_REL)] != NULL)
     {
diff --git a/sysdeps/mips/dl-machine-reject-phdr.h b/sysdeps/mips/dl-machine-reject-phdr.h
index b784697fc1..85cc2beeea 100644
--- a/sysdeps/mips/dl-machine-reject-phdr.h
+++ b/sysdeps/mips/dl-machine-reject-phdr.h
@@ -52,7 +52,7 @@ find_mips_abiflags (const ElfW(Phdr) *phdr, ElfW(Half) phnum)
 /* Cache the FP ABI value from the PT_MIPS_ABIFLAGS program header.  */
 
 static bool
-cached_fpabi_reject_phdr_p (struct link_map *l)
+cached_fpabi_reject_phdr_p (struct link_map_private *l)
 {
   if (l->l_mach.fpabi == 0)
     {
@@ -62,13 +62,15 @@ cached_fpabi_reject_phdr_p (struct link_map *l)
 	{
 	  Elf_MIPS_ABIFlags_v0 * mips_abiflags;
 	  if (ph->p_filesz < sizeof (Elf_MIPS_ABIFlags_v0))
-	    REJECT ("   %s: malformed PT_MIPS_ABIFLAGS found\n", l->l_name);
+	    REJECT ("   %s: malformed PT_MIPS_ABIFLAGS found\n",
+		    l->l_public.l_name);
 
-	  mips_abiflags = (Elf_MIPS_ABIFlags_v0 *) (l->l_addr + ph->p_vaddr);
+	  mips_abiflags
+	    = (Elf_MIPS_ABIFlags_v0 *) (l->l_public.l_addr + ph->p_vaddr);
 
 	  if (__glibc_unlikely (mips_abiflags->flags2 != 0))
-	    REJECT ("   %s: unknown MIPS.abiflags flags2: %u\n", l->l_name,
-		    mips_abiflags->flags2);
+	    REJECT ("   %s: unknown MIPS.abiflags flags2: %u\n",
+		    l->l_public.l_name, mips_abiflags->flags2);
 
 	  l->l_mach.fpabi = mips_abiflags->fp_abi;
 	  l->l_mach.odd_spreg = (mips_abiflags->flags1
@@ -153,11 +155,11 @@ static const struct abi_req none_req = { true, true, true, false, true };
 
 static bool __attribute_used__
 elf_machine_reject_phdr_p (const ElfW(Phdr) *phdr, unsigned int phnum,
-			   const char *buf, size_t len, struct link_map *map,
-			   int fd)
+			   const char *buf, size_t len,
+			   struct link_map_private *map, int fd)
 {
   const ElfW(Phdr) *ph = find_mips_abiflags (phdr, phnum);
-  struct link_map *l;
+  struct link_map_private *l;
   Lmid_t nsid;
   int in_abi = -1;
   struct abi_req in_req;
@@ -204,7 +206,7 @@ elf_machine_reject_phdr_p (const ElfW(Phdr) *phdr, unsigned int phnum,
   /* Check that the new requirement does not conflict with any currently
      loaded object.  */
   for (nsid = 0; nsid < DL_NNS; ++nsid)
-    for (l = GL(dl_ns)[nsid]._ns_loaded; l != NULL; l = l->l_next)
+    for (l = GL(dl_ns)[nsid]._ns_loaded; l != NULL; l = l_next (l))
       {
 	struct abi_req existing_req;
 
diff --git a/sysdeps/mips/dl-machine.h b/sysdeps/mips/dl-machine.h
index f1b3effec8..b7b1705f65 100644
--- a/sysdeps/mips/dl-machine.h
+++ b/sysdeps/mips/dl-machine.h
@@ -168,14 +168,14 @@ elf_machine_load_address (void)
    fiddles with global data.  */
 #define ELF_MACHINE_BEFORE_RTLD_RELOC(bootstrap_map, dynamic_info)	\
 do {									\
-  struct link_map *map = bootstrap_map;					\
+  struct link_map_private *map = bootstrap_map;				\
   ElfW(Sym) *sym;							\
   ElfW(Addr) *got;							\
   int i, n;								\
 									\
   got = (ElfW(Addr) *) D_PTR (map, l_info[DT_PLTGOT]);			\
 									\
-  if (__builtin_expect (map->l_addr == 0, 1))				\
+  if (__builtin_expect (map->l_public.l_addr == 0, 1))			\
     break;								\
 									\
   /* got[0] is reserved. got[1] is also reserved for the dynamic object	\
@@ -186,7 +186,7 @@ do {									\
 									\
   /* Add the run-time displacement to all local got entries. */		\
   while (i < n)								\
-    got[i++] += map->l_addr;						\
+    got[i++] += map->l_public.l_addr;					\
 									\
   /* Handle global got entries. */					\
   got += n;								\
@@ -201,11 +201,11 @@ do {									\
 	*got = SYMBOL_ADDRESS (map, sym, true);				\
       else if (ELFW(ST_TYPE) (sym->st_info) == STT_FUNC			\
 	       && *got != sym->st_value)				\
-	*got += map->l_addr;						\
+	*got += map->l_public.l_addr;					\
       else if (ELFW(ST_TYPE) (sym->st_info) == STT_SECTION)		\
 	{								\
 	  if (sym->st_other == 0)					\
-	    *got += map->l_addr;					\
+	    *got += map->l_public.l_addr;				\
 	}								\
       else								\
 	*got = SYMBOL_ADDRESS (map, sym, true);				\
@@ -278,7 +278,7 @@ do {									\
 	move $16, $28\n\
 	# Save the user entry point address in a saved register.\n\
 	move $17, $2\n\
-	# Call _dl_init (struct link_map *main_map, int argc, char **argv, char **env) \n\
+	# Call _dl_init (struct link_map_private *main_map, int argc, char **argv, char **env) \n\
 	" STRINGXP(PTR_L) " $4, _rtld_local\n\
 	" STRINGXP(PTR_L) /* or lw???  fixme */ " $5, 0($29)\n\
 	" STRINGXP(PTR_LA) " $6, " STRINGXP (PTRSIZE) "($29)\n\
@@ -339,7 +339,7 @@ do {									\
 	addu $16, $4\n\
 	move $17, $2\n\
 	move $28, $16\n\
-	# Call _dl_init (struct link_map *main_map, int argc, char **argv, char **env) \n\
+	# Call _dl_init (struct link_map_private *main_map, int argc, char **argv, char **env) \n\
 	lw $4, %got(_rtld_local)($16)\n\
 	lw $4, 0($4)\n\
 	lw $5, 0($sp)\n\
@@ -403,7 +403,7 @@ dl_platform_init (void)
    point at the symbol with address VALUE.  For a writable PLT, rewrite
    the corresponding PLT entry instead.  */
 static inline ElfW(Addr)
-elf_machine_fixup_plt (struct link_map *map, lookup_t t,
+elf_machine_fixup_plt (struct link_map_private *map, lookup_t t,
 		       const ElfW(Sym) *refsym, const ElfW(Sym) *sym,
 		       const ElfW(Rel) *reloc,
 		       ElfW(Addr) *reloc_addr, ElfW(Addr) value)
@@ -412,7 +412,7 @@ elf_machine_fixup_plt (struct link_map *map, lookup_t t,
 }
 
 static inline ElfW(Addr)
-elf_machine_plt_value (struct link_map *map, const ElfW(Rel) *reloc,
+elf_machine_plt_value (struct link_map_private *map, const ElfW(Rel) *reloc,
 		       ElfW(Addr) value)
 {
   return value;
@@ -428,7 +428,7 @@ elf_machine_plt_value (struct link_map *map, const ElfW(Rel) *reloc,
 
 static inline void
 __attribute__ ((always_inline))
-elf_machine_reloc (struct link_map *map, struct r_scope_elem *scope[],
+elf_machine_reloc (struct link_map_private *map, struct r_scope_elem *scope[],
 		   ElfW(Addr) r_info, const ElfW(Sym) *sym,
 		   const struct r_found_version *version, void *reloc_addr,
 		   ElfW(Addr) r_addend, int inplace_p)
@@ -459,8 +459,8 @@ elf_machine_reloc (struct link_map *map, struct r_scope_elem *scope[],
     case R_MIPS_TLS_TPREL32:
 # endif
       {
-	struct link_map *sym_map = RESOLVE_MAP (map, scope, &sym, version,
-						r_type);
+	struct link_map_private *sym_map
+	  = RESOLVE_MAP (map, scope, &sym, version, r_type);
 
 	switch (r_type)
 	  {
@@ -555,7 +555,7 @@ elf_machine_reloc (struct link_map *map, struct r_scope_elem *scope[],
 #ifndef RTLD_BOOTSTRAP
 	  if (map != &GL(dl_rtld_map))
 #endif
-	    reloc_value += map->l_addr;
+	    reloc_value += map->l_public.l_addr;
 
 	__builtin_memcpy (reloc_addr, &reloc_value, sizeof (reloc_value));
       }
@@ -590,14 +590,14 @@ elf_machine_reloc (struct link_map *map, struct r_scope_elem *scope[],
 
     case R_MIPS_JUMP_SLOT:
       {
-	struct link_map *sym_map;
+	struct link_map_private *sym_map;
 	ElfW(Addr) value;
 
 	/* The addend for a jump slot relocation must always be zero:
 	   calls via the PLT always branch to the symbol's address and
 	   not to the address plus a non-zero offset.  */
 	if (r_addend != 0)
-	  _dl_signal_error (0, map->l_name, NULL,
+	  _dl_signal_error (0, map->l_public.l_name, NULL,
 			    "found jump slot relocation with non-zero addend");
 
 	sym_map = RESOLVE_MAP (map, scope, &sym, version, r_type);
@@ -610,7 +610,7 @@ elf_machine_reloc (struct link_map *map, struct r_scope_elem *scope[],
     case R_MIPS_COPY:
       {
 	const ElfW(Sym) *const refsym = sym;
-	struct link_map *sym_map;
+	struct link_map_private *sym_map;
 	ElfW(Addr) value;
 
 	/* Calculate the address of the symbol.  */
@@ -663,7 +663,7 @@ elf_machine_reloc (struct link_map *map, struct r_scope_elem *scope[],
 
 static inline void
 __attribute__ ((always_inline))
-elf_machine_rel (struct link_map *map, struct r_scope_elem *scope[],
+elf_machine_rel (struct link_map_private *map, struct r_scope_elem *scope[],
 		 const ElfW(Rel) *reloc, const ElfW(Sym) *sym,
 		 const struct r_found_version *version, void *const reloc_addr,
 		 int skip_ifunc)
@@ -681,7 +681,8 @@ elf_machine_rel_relative (ElfW(Addr) l_addr, const ElfW(Rel) *reloc,
 
 static inline void
 __attribute__((always_inline))
-elf_machine_lazy_rel (struct link_map *map, struct r_scope_elem *scope[],
+elf_machine_lazy_rel (struct link_map_private *map,
+		      struct r_scope_elem *scope[],
 		      ElfW(Addr) l_addr, const ElfW(Rel) *reloc,
 		      int skip_ifunc)
 {
@@ -704,7 +705,8 @@ elf_machine_lazy_rel (struct link_map *map, struct r_scope_elem *scope[],
 
 static inline void
 __attribute__ ((always_inline))
-elf_machine_rela (struct link_map *map, struct r_scope_elem *scope[], const ElfW(Rela) *reloc,
+elf_machine_rela (struct link_map_private *map,
+		  struct r_scope_elem *scope[], const ElfW(Rela) *reloc,
 		  const ElfW(Sym) *sym, const struct r_found_version *version,
 		  void *const reloc_addr, int skip_ifunc)
 {
@@ -723,7 +725,8 @@ elf_machine_rela_relative (ElfW(Addr) l_addr, const ElfW(Rela) *reloc,
 /* Relocate GOT. */
 static inline void
 __attribute__((always_inline))
-elf_machine_got_rel (struct link_map *map, struct r_scope_elem *scope[], int lazy)
+elf_machine_got_rel (struct link_map_private *map,
+		     struct r_scope_elem *scope[], int lazy)
 {
   ElfW(Addr) *got;
   ElfW(Sym) *sym;
@@ -735,7 +738,7 @@ elf_machine_got_rel (struct link_map *map, struct r_scope_elem *scope[], int laz
       const ElfW(Sym) *ref = sym;					  \
       const struct r_found_version *version __attribute__ ((unused))	  \
 	= vernum ? &map->l_versions[vernum[sym_index] & 0x7fff] : NULL;	  \
-      struct link_map *sym_map;						  \
+      struct link_map_private *sym_map;					  \
       sym_map = RESOLVE_MAP (map, scope, &ref, version, reloc);		  \
       SYMBOL_ADDRESS (sym_map, ref, true);				  \
     })
@@ -757,10 +760,10 @@ elf_machine_got_rel (struct link_map *map, struct r_scope_elem *scope[], int laz
 
       /* Add the run-time displacement to all local got entries if
 	 needed.  */
-      if (__builtin_expect (map->l_addr != 0, 0))
+      if (__builtin_expect (map->l_public.l_addr != 0, 0))
 	{
 	  while (i < n)
-	    got[i++] += map->l_addr;
+	    got[i++] += map->l_public.l_addr;
 	}
     }
 
@@ -796,7 +799,7 @@ elf_machine_got_rel (struct link_map *map, struct r_scope_elem *scope[], int laz
 	       && *got != sym->st_value)
 	{
 	  if (lazy)
-	    *got += map->l_addr;
+	    *got += map->l_public.l_addr;
 	  else
 	    /* This is a lazy-binding stub, so we don't need the
 	       canonical address.  */
@@ -805,7 +808,7 @@ elf_machine_got_rel (struct link_map *map, struct r_scope_elem *scope[], int laz
       else if (ELFW(ST_TYPE) (sym->st_info) == STT_SECTION)
 	{
 	  if (sym->st_other == 0)
-	    *got += map->l_addr;
+	    *got += map->l_public.l_addr;
 	}
       else
 	*got = RESOLVE_GOTSYM (sym, vernum, symidx, R_MIPS_32);
@@ -824,7 +827,8 @@ elf_machine_got_rel (struct link_map *map, struct r_scope_elem *scope[], int laz
 
 static inline int
 __attribute__((always_inline))
-elf_machine_runtime_setup (struct link_map *l, struct r_scope_elem *scope[],
+elf_machine_runtime_setup (struct link_map_private *l,
+			   struct r_scope_elem *scope[],
 			   int lazy, int profile)
 {
 # ifndef RTLD_BOOTSTRAP
@@ -866,7 +870,7 @@ elf_machine_runtime_setup (struct link_map *l, struct r_scope_elem *scope[],
 	 we have to be able to undo the prelinking of .got.plt.
 	 The prelinker saved the address of .plt for us here.  */
       if (gotplt[1])
-	l->l_mach.plt = gotplt[1] + l->l_addr;
+	l->l_mach.plt = gotplt[1] + l->l_public.l_addr;
       gotplt[0] = (ElfW(Addr)) &_dl_runtime_pltresolve;
       gotplt[1] = (ElfW(Addr)) l;
     }
diff --git a/sysdeps/mips/dl-trampoline.c b/sysdeps/mips/dl-trampoline.c
index 1771f9eb6a..0c9a79a360 100644
--- a/sysdeps/mips/dl-trampoline.c
+++ b/sysdeps/mips/dl-trampoline.c
@@ -26,7 +26,7 @@
 #include <sysdep-cancel.h>
 
 /* Get link map for callers object containing STUB_PC.  */
-static inline struct link_map *
+static inline struct link_map_private *
 elf_machine_runtime_link_map (ElfW(Addr) gpreg, ElfW(Addr) stub_pc)
 {
   extern int _dl_mips_gnu_objects;
@@ -45,8 +45,8 @@ elf_machine_runtime_link_map (ElfW(Addr) gpreg, ElfW(Addr) stub_pc)
 
       if ((g1 & ELF_MIPS_GNU_GOT1_MASK) != 0)
 	{
-	  struct link_map *l =
-	    (struct link_map *) (g1 & ~ELF_MIPS_GNU_GOT1_MASK);
+	  struct link_map_private *l =
+	    (struct link_map_private *) (g1 & ~ELF_MIPS_GNU_GOT1_MASK);
 	  ElfW(Addr) base, limit;
 	  const ElfW(Phdr) *p = l->l_phdr;
 	  ElfW(Half) this, nent = l->l_phnum;
@@ -59,7 +59,7 @@ elf_machine_runtime_link_map (ElfW(Addr) gpreg, ElfW(Addr) stub_pc)
 	    {
 	      if (p[this].p_type == PT_LOAD)
 		{
-		  base = p[this].p_vaddr + l->l_addr;
+		  base = p[this].p_vaddr + l->l_public.l_addr;
 		  limit = base + p[this].p_memsz;
 		  if (stub_pc >= base && stub_pc < limit)
 		    return l;
@@ -68,11 +68,11 @@ elf_machine_runtime_link_map (ElfW(Addr) gpreg, ElfW(Addr) stub_pc)
 	}
     }
 
-    struct link_map *l;
+    struct link_map_private *l;
     Lmid_t nsid;
 
     for (nsid = 0; nsid < DL_NNS; ++nsid)
-      for (l = GL(dl_ns)[nsid]._ns_loaded; l != NULL; l = l->l_next)
+      for (l = GL(dl_ns)[nsid]._ns_loaded; l != NULL; l = l_next (l))
 	{
 	  ElfW(Addr) base, limit;
 	  const ElfW(Phdr) *p = l->l_phdr;
@@ -82,7 +82,7 @@ elf_machine_runtime_link_map (ElfW(Addr) gpreg, ElfW(Addr) stub_pc)
 	    {
 	      if (p[this].p_type == PT_LOAD)
 		{
-		  base = p[this].p_vaddr + l->l_addr;
+		  base = p[this].p_vaddr + l->l_public.l_addr;
 		  limit = base + p[this].p_memsz;
 		  if (stub_pc >= base && stub_pc < limit)
 		    return l;
@@ -121,7 +121,8 @@ __dl_runtime_resolve (ElfW(Word) sym_index,
 		      ElfW(Addr) old_gpreg,
 		      ElfW(Addr) stub_pc)
 {
-  struct link_map *l = elf_machine_runtime_link_map (old_gpreg, stub_pc);
+  struct link_map_private *l
+    = elf_machine_runtime_link_map (old_gpreg, stub_pc);
   const ElfW(Sym) *const symtab
     = (const ElfW(Sym) *) D_PTR (l, l_info[DT_SYMTAB]);
   const char *strtab = (const void *) D_PTR (l, l_info[DT_STRTAB]);
@@ -132,7 +133,7 @@ __dl_runtime_resolve (ElfW(Word) sym_index,
   const ElfW(Word) gotsym
     = (const ElfW(Word)) l->l_info[DT_MIPS (GOTSYM)]->d_un.d_val;
   const ElfW(Sym) *sym = &symtab[sym_index];
-  struct link_map *sym_map;
+  struct link_map_private *sym_map;
   ElfW(Addr) value;
 
   /* FIXME: The symbol versioning stuff is not tested yet.  */
diff --git a/sysdeps/nios2/dl-init.c b/sysdeps/nios2/dl-init.c
index 5b8407b986..667bf0619b 100644
--- a/sysdeps/nios2/dl-init.c
+++ b/sysdeps/nios2/dl-init.c
@@ -19,10 +19,10 @@
 #include <elf/dl-init.c>
 
 unsigned int
-_dl_nios2_get_gp_value (struct link_map *main_map)
+_dl_nios2_get_gp_value (struct link_map_private *main_map)
 {
-  ElfW(Dyn) *dyn = main_map->l_ld;
-  for (dyn = main_map->l_ld; dyn->d_tag != DT_NULL; ++dyn)
+  ElfW(Dyn) *dyn = main_map->l_public.l_ld;
+  for (dyn = main_map->l_public.l_ld; dyn->d_tag != DT_NULL; ++dyn)
     if (dyn->d_tag == DT_NIOS2_GP)
       return (unsigned int)(dyn->d_un.d_ptr);
   return 0;
diff --git a/sysdeps/nios2/dl-machine.h b/sysdeps/nios2/dl-machine.h
index f151d29242..bbfc6f7354 100644
--- a/sysdeps/nios2/dl-machine.h
+++ b/sysdeps/nios2/dl-machine.h
@@ -69,7 +69,8 @@ elf_machine_load_address (void)
    entries will jump to the on-demand fixup code in dl-runtime.c.  */
 
 static inline int __attribute__ ((always_inline))
-elf_machine_runtime_setup (struct link_map *l, struct r_scope_elem *scope[],
+elf_machine_runtime_setup (struct link_map_private *l,
+			   struct r_scope_elem *scope[],
 			   int lazy, int profile)
 {
   extern void _dl_runtime_resolve (Elf32_Word);
@@ -174,7 +175,7 @@ _start:\n\
 /* Fixup a PLT entry to bounce directly to the function at VALUE.  */
 
 static inline Elf32_Addr
-elf_machine_fixup_plt (struct link_map *map, lookup_t t,
+elf_machine_fixup_plt (struct link_map_private *map, lookup_t t,
 		       const ElfW(Sym) *refsym, const ElfW(Sym) *sym,
 		       const Elf32_Rela *reloc,
 		       Elf32_Addr *reloc_addr, Elf32_Addr value)
@@ -184,7 +185,7 @@ elf_machine_fixup_plt (struct link_map *map, lookup_t t,
 
 /* Return the final value of a plt relocation.  */
 static inline Elf32_Addr
-elf_machine_plt_value (struct link_map *map, const Elf32_Rela *reloc,
+elf_machine_plt_value (struct link_map_private *map, const Elf32_Rela *reloc,
                        Elf32_Addr value)
 {
   return value;
@@ -203,7 +204,8 @@ elf_machine_plt_value (struct link_map *map, const Elf32_Rela *reloc,
    by DT_* of the .dynamic section info.  */
 
 static inline void __attribute__ ((always_inline))
-elf_machine_rela (struct link_map *map, struct r_scope_elem *scope[],
+elf_machine_rela (struct link_map_private *map,
+		  struct r_scope_elem *scope[],
 		  const ElfW(Rela) *reloc, const ElfW(Sym) *sym,
 		  const struct r_found_version *version,
 		  void *const reloc_addr_arg, int skip_ifunc)
@@ -212,14 +214,14 @@ elf_machine_rela (struct link_map *map, struct r_scope_elem *scope[],
   const unsigned int r_type = ELF32_R_TYPE (reloc->r_info);
 
   if (__glibc_unlikely (r_type == R_NIOS2_RELATIVE))
-    *reloc_addr = map->l_addr + reloc->r_addend;
+    *reloc_addr = map->l_public.l_addr + reloc->r_addend;
   else if (__glibc_unlikely (r_type == R_NIOS2_NONE))
     return;
   else
     {
       const Elf32_Sym *const refsym = sym;
-      struct link_map *sym_map = RESOLVE_MAP (map, scope, &sym, version,
-					      r_type);
+      struct link_map_private *sym_map
+	= RESOLVE_MAP (map, scope, &sym, version, r_type);
       Elf32_Addr value = SYMBOL_ADDRESS (sym_map, sym, true);
 
       switch (r_type)
@@ -293,7 +295,8 @@ elf_machine_rela_relative (ElfW(Addr) l_addr, const ElfW(Rela) *reloc,
 }
 
 static inline void __attribute__((always_inline))
-elf_machine_lazy_rel (struct link_map *map, struct r_scope_elem *scope[],
+elf_machine_lazy_rel (struct link_map_private *map,
+		      struct r_scope_elem *scope[],
 		      ElfW(Addr) l_addr, const ElfW(Rela) *reloc,
 		      int skip_ifunc)
 {
diff --git a/sysdeps/nptl/dl-mutex.c b/sysdeps/nptl/dl-mutex.c
index 415df854fe..8c5fed62b3 100644
--- a/sysdeps/nptl/dl-mutex.c
+++ b/sysdeps/nptl/dl-mutex.c
@@ -34,7 +34,7 @@ __rtld_mutex_init (void)
      it happens directly in dl_main in elf/rtld.c, and not some ELF
      constructor while holding loader locks.  */
 
-  struct link_map *libc_map = GL (dl_ns)[LM_ID_BASE].libc_map;
+  struct link_map_private *libc_map = GL (dl_ns)[LM_ID_BASE].libc_map;
 
   const ElfW(Sym) *sym
     = _dl_lookup_direct (libc_map, "pthread_mutex_lock",
diff --git a/sysdeps/or1k/dl-machine.h b/sysdeps/or1k/dl-machine.h
index 27dfd7bcdd..d016493be9 100644
--- a/sysdeps/or1k/dl-machine.h
+++ b/sysdeps/or1k/dl-machine.h
@@ -107,7 +107,8 @@ elf_machine_load_address (void)
 /* Set up the loaded object described by L so its unrelocated PLT
    entries will jump to the on-demand fixup code in dl-runtime.c.  */
 static inline int __attribute__ ((unused, always_inline))
-elf_machine_runtime_setup (struct link_map *l, struct r_scope_elem *scope[],
+elf_machine_runtime_setup (struct link_map_private *l,
+			   struct r_scope_elem *scope[],
 			   int lazy, int profile)
 {
   ElfW(Addr) *pltgot;
@@ -151,7 +152,7 @@ dl_platform_init (void)
 }
 
 static inline ElfW(Addr)
-elf_machine_fixup_plt (struct link_map *map, lookup_t t,
+elf_machine_fixup_plt (struct link_map_private *map, lookup_t t,
 		       const ElfW(Sym) *refsym, const ElfW(Sym) *sym,
 		       const ElfW(Rela) *reloc,
 		       ElfW(Addr) *reloc_addr, ElfW(Addr) value)
@@ -161,7 +162,7 @@ elf_machine_fixup_plt (struct link_map *map, lookup_t t,
 
 /* Return the final value of a plt relocation.  */
 static inline Elf32_Addr
-elf_machine_plt_value (struct link_map *map, const Elf32_Rela *reloc,
+elf_machine_plt_value (struct link_map_private *map, const Elf32_Rela *reloc,
 		       Elf32_Addr value)
 {
   return value + reloc->r_addend;
@@ -177,7 +178,7 @@ elf_machine_plt_value (struct link_map *map, const Elf32_Rela *reloc,
 
 static inline void
 __attribute ((always_inline))
-elf_machine_rela (struct link_map *map, struct r_scope_elem *scope[],
+elf_machine_rela (struct link_map_private *map, struct r_scope_elem *scope[],
 		  const ElfW(Rela) *reloc, const ElfW(Sym) *sym,
 		  const struct r_found_version *version,
 		  void *const reloc_addr_arg, int skip_ifunc)
@@ -190,8 +191,8 @@ elf_machine_rela (struct link_map *map, struct r_scope_elem *scope[],
   else
     {
       const Elf32_Sym *const refsym = sym;
-      struct link_map *sym_map = RESOLVE_MAP (map, scope, &sym, version,
-					      r_type);
+      struct link_map_private *sym_map
+	= RESOLVE_MAP (map, scope, &sym, version, r_type);
       Elf32_Addr value = SYMBOL_ADDRESS (sym_map, sym, true);
 
       if (sym != NULL
@@ -278,7 +279,8 @@ elf_machine_rela_relative (Elf32_Addr l_addr, const Elf32_Rela *reloc,
 
 static inline void
 __attribute__ ((always_inline))
-elf_machine_lazy_rel (struct link_map *map, struct r_scope_elem *scope[],
+elf_machine_lazy_rel (struct link_map_private *map,
+		      struct r_scope_elem *scope[],
 		      ElfW(Addr) l_addr, const ElfW(Rela) *reloc,
 		      int skip_ifunc)
 {
diff --git a/sysdeps/powerpc/powerpc32/dl-machine.c b/sysdeps/powerpc/powerpc32/dl-machine.c
index e6b603de94..70f2b0de2b 100644
--- a/sysdeps/powerpc/powerpc32/dl-machine.c
+++ b/sysdeps/powerpc/powerpc32/dl-machine.c
@@ -87,11 +87,11 @@
    mapped somewhere else.  */
 
 ElfW(Addr)
-__elf_preferred_address (struct link_map *loader, size_t maplength,
+__elf_preferred_address (struct link_map_private *loader, size_t maplength,
 			 ElfW(Addr) mapstartpref)
 {
   ElfW(Addr) low, high;
-  struct link_map *l;
+  struct link_map_private *l;
   Lmid_t nsid;
 
   /* If the object has a preference, load it there!  */
@@ -105,7 +105,7 @@ __elf_preferred_address (struct link_map *loader, size_t maplength,
   low =  0x0003FFFF;
   high = 0x70000000;
   for (nsid = 0; nsid < DL_NNS; ++nsid)
-    for (l = GL(dl_ns)[nsid]._ns_loaded; l; l = l->l_next)
+    for (l = GL(dl_ns)[nsid]._ns_loaded; l; l = l_next (l))
       {
 	ElfW(Addr) mapstart, mapend;
 	mapstart = l->l_map_start & ~(GLRO(dl_pagesize) - 1);
@@ -196,7 +196,8 @@ __elf_preferred_address (struct link_map *loader, size_t maplength,
    Once this is done, and is visible to all processors, the `lwzu' can
    safely be changed to a `lwz'.  */
 int
-__elf_machine_runtime_setup (struct link_map *map, int lazy, int profile)
+__elf_machine_runtime_setup (struct link_map_private *map, int lazy,
+			     int profile)
 {
   if (map->l_info[DT_JMPREL])
     {
@@ -329,7 +330,7 @@ __elf_machine_runtime_setup (struct link_map *map, int lazy, int profile)
 }
 
 Elf32_Addr
-__elf_machine_fixup_plt (struct link_map *map,
+__elf_machine_fixup_plt (struct link_map_private *map,
 			 Elf32_Addr *reloc_addr, Elf32_Addr finaladdr)
 {
   Elf32_Sword delta = finaladdr - (Elf32_Word) reloc_addr;
@@ -378,7 +379,7 @@ __elf_machine_fixup_plt (struct link_map *map,
 }
 
 void
-_dl_reloc_overflow (struct link_map *map,
+_dl_reloc_overflow (struct link_map_private *map,
 		    const char *name,
 		    Elf32_Addr *const reloc_addr,
 		    const Elf32_Sym *refsym)
@@ -398,13 +399,13 @@ _dl_reloc_overflow (struct link_map *map,
       t = stpcpy (t, "'");
     }
   t = stpcpy (t, " out of range");
-  _dl_signal_error (0, map->l_name, NULL, buffer);
+  _dl_signal_error (0, map->l_public.l_name, NULL, buffer);
 }
 
 void
-__process_machine_rela (struct link_map *map,
+__process_machine_rela (struct link_map_private *map,
 			const Elf32_Rela *reloc,
-			struct link_map *sym_map,
+			struct link_map_private *sym_map,
 			const Elf32_Sym *sym,
 			const Elf32_Sym *refsym,
 			Elf32_Addr *const reloc_addr,
diff --git a/sysdeps/powerpc/powerpc32/dl-machine.h b/sysdeps/powerpc/powerpc32/dl-machine.h
index 1ff46d5f8a..789255e427 100644
--- a/sysdeps/powerpc/powerpc32/dl-machine.h
+++ b/sysdeps/powerpc/powerpc32/dl-machine.h
@@ -124,7 +124,7 @@ elf_machine_load_address (void)
 
 /* Decide where a relocatable object should be loaded.  */
 extern ElfW(Addr)
-__elf_preferred_address(struct link_map *loader, size_t maplength,
+__elf_preferred_address(struct link_map_private *loader, size_t maplength,
 			ElfW(Addr) mapstartpref);
 #define ELF_PREFERRED_ADDRESS(loader, maplength, mapstartpref) \
   __elf_preferred_address (loader, maplength, mapstartpref)
@@ -164,11 +164,12 @@ dl_platform_init (void)
    entries will jump to the on-demand fixup code in dl-runtime.c.
    Also install a small trampoline to be used by entries that have
    been relocated to an address too far away for a single branch.  */
-extern int __elf_machine_runtime_setup (struct link_map *map,
+extern int __elf_machine_runtime_setup (struct link_map_private *map,
 					int lazy, int profile);
 
 static inline int
-elf_machine_runtime_setup (struct link_map *map, struct r_scope_elem *scope[],
+elf_machine_runtime_setup (struct link_map_private *map,
+			   struct r_scope_elem *scope[],
 			   int lazy, int profile)
 {
   if (map->l_info[DT_JMPREL] == 0)
@@ -179,7 +180,7 @@ elf_machine_runtime_setup (struct link_map *map, struct r_scope_elem *scope[],
     return __elf_machine_runtime_setup (map, lazy, profile);
 
   /* New style non-exec PLT consisting of an array of addresses.  */
-  map->l_info[DT_PPC(GOT)]->d_un.d_ptr += map->l_addr;
+  map->l_info[DT_PPC(GOT)]->d_un.d_ptr += map->l_public.l_addr;
   if (lazy)
     {
       Elf32_Addr *plt, *got, glink;
@@ -217,24 +218,24 @@ elf_machine_runtime_setup (struct link_map *map, struct r_scope_elem *scope[],
 	 section's start.  */
       if (glink)
 	{
-	  glink += map->l_addr;
+	  glink += map->l_public.l_addr;
 	  while (num_plt_entries-- != 0)
 	    *plt++ = glink, glink += 4;
 	}
       else
 	while (num_plt_entries-- != 0)
-	  *plt++ += map->l_addr;
+	  *plt++ += map->l_public.l_addr;
     }
   return lazy;
 }
 
 /* Change the PLT entry whose reloc is 'reloc' to call the actual routine.  */
-extern Elf32_Addr __elf_machine_fixup_plt (struct link_map *map,
+extern Elf32_Addr __elf_machine_fixup_plt (struct link_map_private *map,
 					   Elf32_Addr *reloc_addr,
 					   Elf32_Addr finaladdr);
 
 static inline Elf32_Addr
-elf_machine_fixup_plt (struct link_map *map, lookup_t t,
+elf_machine_fixup_plt (struct link_map_private *map, lookup_t t,
 		       const ElfW(Sym) *refsym, const ElfW(Sym) *sym,
 		       const Elf32_Rela *reloc,
 		       Elf32_Addr *reloc_addr, Elf64_Addr finaladdr)
@@ -249,7 +250,7 @@ elf_machine_fixup_plt (struct link_map *map, lookup_t t,
 
 /* Return the final value of a plt relocation.  */
 static inline Elf32_Addr
-elf_machine_plt_value (struct link_map *map, const Elf32_Rela *reloc,
+elf_machine_plt_value (struct link_map_private *map, const Elf32_Rela *reloc,
 		       Elf32_Addr value)
 {
   return value + reloc->r_addend;
@@ -266,9 +267,9 @@ elf_machine_plt_value (struct link_map *map, const Elf32_Rela *reloc,
 
 /* Do the actual processing of a reloc, once its target address
    has been determined.  */
-extern void __process_machine_rela (struct link_map *map,
+extern void __process_machine_rela (struct link_map_private *map,
 				    const Elf32_Rela *reloc,
-				    struct link_map *sym_map,
+				    struct link_map_private *sym_map,
 				    const Elf32_Sym *sym,
 				    const Elf32_Sym *refsym,
 				    Elf32_Addr *const reloc_addr,
@@ -277,7 +278,7 @@ extern void __process_machine_rela (struct link_map *map,
   attribute_hidden;
 
 /* Call _dl_signal_error when a resolved value overflows a relocated area.  */
-extern void _dl_reloc_overflow (struct link_map *map,
+extern void _dl_reloc_overflow (struct link_map_private *map,
 				const char *name,
 				Elf32_Addr *const reloc_addr,
 				const Elf32_Sym *refsym) attribute_hidden;
@@ -287,7 +288,7 @@ extern void _dl_reloc_overflow (struct link_map *map,
    by DT_* of the .dynamic section info.  */
 
 static inline void __attribute__ ((always_inline))
-elf_machine_rela (struct link_map *map, struct r_scope_elem *scope[],
+elf_machine_rela (struct link_map_private *map, struct r_scope_elem *scope[],
 		  const Elf32_Rela *reloc, const Elf32_Sym *sym,
 		  const struct r_found_version *version,
 		  void *const reloc_addr_arg, int skip_ifunc)
@@ -296,11 +297,11 @@ elf_machine_rela (struct link_map *map, struct r_scope_elem *scope[],
   const Elf32_Sym *const refsym = sym;
   Elf32_Addr value;
   const int r_type = ELF32_R_TYPE (reloc->r_info);
-  struct link_map *sym_map = NULL;
+  struct link_map_private *sym_map = NULL;
 
   if (r_type == R_PPC_RELATIVE)
     {
-      *reloc_addr = map->l_addr + reloc->r_addend;
+      *reloc_addr = map->l_public.l_addr + reloc->r_addend;
       return;
     }
 
@@ -313,7 +314,7 @@ elf_machine_rela (struct link_map *map, struct r_scope_elem *scope[],
       && sym->st_shndx != SHN_UNDEF)
     {
       sym_map = map;
-      value = map->l_addr;
+      value = map->l_public.l_addr;
     }
   else
     {
@@ -442,7 +443,8 @@ elf_machine_rela_relative (Elf32_Addr l_addr, const Elf32_Rela *reloc,
 }
 
 static inline void __attribute__ ((always_inline))
-elf_machine_lazy_rel (struct link_map *map, struct r_scope_elem *scope[],
+elf_machine_lazy_rel (struct link_map_private *map,
+		      struct r_scope_elem *scope[],
 		      Elf32_Addr l_addr, const Elf32_Rela *reloc,
 		      int skip_ifunc)
 {
diff --git a/sysdeps/powerpc/powerpc64/dl-machine.c b/sysdeps/powerpc/powerpc64/dl-machine.c
index 3b4b08f51f..7db68eb0e4 100644
--- a/sysdeps/powerpc/powerpc64/dl-machine.c
+++ b/sysdeps/powerpc/powerpc64/dl-machine.c
@@ -23,7 +23,7 @@
 #include <dl-machine.h>
 
 void
-_dl_reloc_overflow (struct link_map *map,
+_dl_reloc_overflow (struct link_map_private *map,
 		    const char *name,
 		    Elf64_Addr *const reloc_addr,
 		    const Elf64_Sym *refsym)
@@ -46,12 +46,12 @@ _dl_reloc_overflow (struct link_map *map,
       t = stpcpy (t, "'");
     }
   t = stpcpy (t, " out of range");
-  _dl_signal_error (0, map->l_name, NULL, buffer);
+  _dl_signal_error (0, map->l_public.l_name, NULL, buffer);
 }
 
 #if _CALL_ELF == 2
 void
-_dl_error_localentry (struct link_map *map, const Elf64_Sym *refsym)
+_dl_error_localentry (struct link_map_private *map, const Elf64_Sym *refsym)
 {
   char buffer[1024];
   char *t;
@@ -61,6 +61,6 @@ _dl_error_localentry (struct link_map *map, const Elf64_Sym *refsym)
   t = stpcpy (buffer, "expected localentry:0 `");
   t = stpcpy (t, strtab + refsym->st_name);
   t = stpcpy (t, "'");
-  _dl_signal_error (0, map->l_name, NULL, buffer);
+  _dl_signal_error (0, map->l_public.l_name, NULL, buffer);
 }
 #endif
diff --git a/sysdeps/powerpc/powerpc64/dl-machine.h b/sysdeps/powerpc/powerpc64/dl-machine.h
index 601c3cba9d..9db1838f44 100644
--- a/sysdeps/powerpc/powerpc64/dl-machine.h
+++ b/sysdeps/powerpc/powerpc64/dl-machine.h
@@ -332,7 +332,8 @@ dl_platform_init (void)
 /* Set up the loaded object described by MAP so its unrelocated PLT
    entries will jump to the on-demand fixup code in dl-runtime.c.  */
 static inline int __attribute__ ((always_inline))
-elf_machine_runtime_setup (struct link_map *map, struct r_scope_elem *scope[],
+elf_machine_runtime_setup (struct link_map_private *map,
+			   struct r_scope_elem *scope[],
 			   int lazy, int profile)
 {
   if (map->l_info[DT_JMPREL])
@@ -342,7 +343,7 @@ elf_machine_runtime_setup (struct link_map *map, struct r_scope_elem *scope[],
       Elf64_Xword *plt = (Elf64_Xword *) D_PTR (map, l_info[DT_PLTGOT]);
       Elf64_Word num_plt_entries = (map->l_info[DT_PLTRELSZ]->d_un.d_val
 				    / sizeof (Elf64_Rela));
-      Elf64_Addr l_addr = map->l_addr;
+      Elf64_Addr l_addr = map->l_public.l_addr;
       Elf64_Dyn **info = map->l_info;
       char *p;
 
@@ -436,13 +437,13 @@ elf_machine_runtime_setup (struct link_map *map, struct r_scope_elem *scope[],
 }
 
 #if _CALL_ELF == 2
-extern void attribute_hidden _dl_error_localentry (struct link_map *map,
-						   const Elf64_Sym *refsym);
+void attribute_hidden _dl_error_localentry (struct link_map_private *map,
+					    const Elf64_Sym *refsym);
 
 /* If the PLT entry resolves to a function in the same object, return
    the target function's local entry point offset if usable.  */
 static inline Elf64_Addr __attribute__ ((always_inline))
-ppc64_local_entry_offset (struct link_map *map, lookup_t sym_map,
+ppc64_local_entry_offset (struct link_map_private *map, lookup_t sym_map,
 			  const ElfW(Sym) *refsym, const ElfW(Sym) *sym)
 {
   /* If the target function is in a different object, we cannot
@@ -481,7 +482,7 @@ ppc64_local_entry_offset (struct link_map *map, lookup_t sym_map,
 /* Change the PLT entry whose reloc is 'reloc' to call the actual
    routine.  */
 static inline Elf64_Addr __attribute__ ((always_inline))
-elf_machine_fixup_plt (struct link_map *map, lookup_t sym_map,
+elf_machine_fixup_plt (struct link_map_private *map, lookup_t sym_map,
 		       const ElfW(Sym) *refsym, const ElfW(Sym) *sym,
 		       const Elf64_Rela *reloc,
 		       Elf64_Addr *reloc_addr, Elf64_Addr finaladdr)
@@ -521,7 +522,7 @@ elf_machine_fixup_plt (struct link_map *map, lookup_t sym_map,
       && sym_map != &GL(dl_rtld_map)
 #endif
       )
-    offset = sym_map->l_addr;
+    offset = sym_map->l_public.l_addr;
 
   /* For PPC64, fixup_plt copies the function descriptor from opd
      over the corresponding PLT entry.
@@ -547,7 +548,7 @@ elf_machine_fixup_plt (struct link_map *map, lookup_t sym_map,
 
 /* Return the final value of a plt relocation.  */
 static inline Elf64_Addr
-elf_machine_plt_value (struct link_map *map, const Elf64_Rela *reloc,
+elf_machine_plt_value (struct link_map_private *map, const Elf64_Rela *reloc,
 		       Elf64_Addr value)
 {
   return value + reloc->r_addend;
@@ -600,7 +601,7 @@ ppc_init_fake_thread_pointer (void)
 
 #define dont_expect(X) __builtin_expect ((X), 0)
 
-extern void attribute_hidden _dl_reloc_overflow (struct link_map *map,
+extern void attribute_hidden _dl_reloc_overflow (struct link_map_private *map,
 						 const char *name,
 						 Elf64_Addr *const reloc_addr,
 						 const Elf64_Sym *refsym);
@@ -615,8 +616,8 @@ elf_machine_rela_relative (Elf64_Addr l_addr, const Elf64_Rela *reloc,
 
 /* This computes the value used by TPREL* relocs.  */
 static inline Elf64_Addr __attribute__ ((always_inline, const))
-elf_machine_tprel (struct link_map *map,
-		   struct link_map *sym_map,
+elf_machine_tprel (struct link_map_private *map,
+		   struct link_map_private *sym_map,
 		   const Elf64_Sym *sym,
 		   const Elf64_Rela *reloc)
 {
@@ -635,7 +636,8 @@ elf_machine_tprel (struct link_map *map,
 /* Call function at address VALUE (an OPD entry) to resolve ifunc relocs.  */
 static inline Elf64_Addr __attribute__ ((always_inline))
 resolve_ifunc (Elf64_Addr value,
-	       const struct link_map *map, const struct link_map *sym_map)
+	       const struct link_map_private *map,
+	       const struct link_map_private *sym_map)
 {
 #if _CALL_ELF != 2
   /* The function we are calling may not yet have its opd entry relocated.  */
@@ -648,8 +650,8 @@ resolve_ifunc (Elf64_Addr value,
       && !sym_map->l_relocated)
     {
       Elf64_FuncDesc *func = (Elf64_FuncDesc *) value;
-      opd.fd_func = func->fd_func + sym_map->l_addr;
-      opd.fd_toc = func->fd_toc + sym_map->l_addr;
+      opd.fd_func = func->fd_func + sym_map->l_public.l_addr;
+      opd.fd_toc = func->fd_toc + sym_map->l_public.l_addr;
       opd.fd_aux = func->fd_aux;
       /* GCC 4.9+ eliminates the branch as dead code, force the odp set
          dependency.  */
@@ -662,7 +664,7 @@ resolve_ifunc (Elf64_Addr value,
 /* Perform the relocation specified by RELOC and SYM (which is fully
    resolved).  MAP is the object containing the reloc.  */
 static inline void __attribute__ ((always_inline))
-elf_machine_rela (struct link_map *map, struct r_scope_elem *scope[],
+elf_machine_rela (struct link_map_private *map, struct r_scope_elem *scope[],
 		  const Elf64_Rela *reloc,
 		  const Elf64_Sym *sym,
 		  const struct r_found_version *version,
@@ -681,7 +683,7 @@ elf_machine_rela (struct link_map *map, struct r_scope_elem *scope[],
 
   if (r_type == R_PPC64_RELATIVE)
     {
-      *reloc_addr = map->l_addr + reloc->r_addend;
+      *reloc_addr = map->l_public.l_addr + reloc->r_addend;
       return;
     }
 
@@ -690,7 +692,8 @@ elf_machine_rela (struct link_map *map, struct r_scope_elem *scope[],
 
   /* We need SYM_MAP even in the absence of TLS, for elf_machine_fixup_plt
      and STT_GNU_IFUNC.  */
-  struct link_map *sym_map = RESOLVE_MAP (map, scope, &sym, version, r_type);
+  struct link_map_private *sym_map
+    = RESOLVE_MAP (map, scope, &sym, version, r_type);
   Elf64_Addr value = SYMBOL_ADDRESS (sym_map, sym, true) + reloc->r_addend;
 
   if (sym != NULL
@@ -1016,7 +1019,8 @@ elf_machine_rela (struct link_map *map, struct r_scope_elem *scope[],
 }
 
 static inline void __attribute__ ((always_inline))
-elf_machine_lazy_rel (struct link_map *map, struct r_scope_elem *scope[],
+elf_machine_lazy_rel (struct link_map_private *map,
+		      struct r_scope_elem *scope[],
 		      Elf64_Addr l_addr, const Elf64_Rela *reloc,
 		      int skip_ifunc)
 {
diff --git a/sysdeps/riscv/dl-machine.h b/sysdeps/riscv/dl-machine.h
index c0c9bd93ad..a05a166514 100644
--- a/sysdeps/riscv/dl-machine.h
+++ b/sysdeps/riscv/dl-machine.h
@@ -109,7 +109,7 @@ elf_machine_dynamic (void)
 	mv s0, a0\n\
 	# Load the adjusted argument count.\n\
 	" STRINGXP (REG_L) " a1, 0(sp)\n\
-	# Call _dl_init (struct link_map *main_map, int argc, char **argv, char **env) \n\
+	# Call _dl_init (struct link_map_private *main_map, int argc, char **argv, char **env) \n\
 	" STRINGXP (REG_L) " a0, _rtld_local\n\
 	add a2, sp, " STRINGXP (SZREG) "\n\
 	sll a3, a1, " STRINGXP (PTRLOG) "\n\
@@ -140,7 +140,7 @@ elf_machine_dynamic (void)
 #define elf_machine_plt_value(map, reloc, value) (value)
 
 static inline ElfW(Addr)
-elf_machine_fixup_plt (struct link_map *map, lookup_t t,
+elf_machine_fixup_plt (struct link_map_private *map, lookup_t t,
 		       const ElfW(Sym) *refsym, const ElfW(Sym) *sym,
 		       const ElfW(Rela) *reloc,
 		       ElfW(Addr) *reloc_addr, ElfW(Addr) value)
@@ -169,7 +169,7 @@ elf_machine_rela_relative (ElfW(Addr) l_addr, const ElfW(Rela) *reloc,
 
 static inline void
 __attribute__ ((always_inline))
-elf_machine_rela (struct link_map *map, struct r_scope_elem *scope[],
+elf_machine_rela (struct link_map_private *map, struct r_scope_elem *scope[],
 		  const ElfW(Rela) *reloc, const ElfW(Sym) *sym,
 		  const struct r_found_version *version,
 		  void *const reloc_addr, int skip_ifunc)
@@ -178,7 +178,8 @@ elf_machine_rela (struct link_map *map, struct r_scope_elem *scope[],
   const unsigned long int r_type = ELFW (R_TYPE) (r_info);
   ElfW(Addr) *addr_field = (ElfW(Addr) *) reloc_addr;
   const ElfW(Sym) *const __attribute__ ((unused)) refsym = sym;
-  struct link_map *sym_map = RESOLVE_MAP (map, scope, &sym, version, r_type);
+  struct link_map_private *sym_map
+    = RESOLVE_MAP (map, scope, &sym, version, r_type);
   ElfW(Addr) value = 0;
   if (sym_map != NULL)
     value = SYMBOL_ADDRESS (sym_map, sym, true) + reloc->r_addend;
@@ -193,7 +194,7 @@ elf_machine_rela (struct link_map *map, struct r_scope_elem *scope[],
   switch (r_type)
     {
     case R_RISCV_RELATIVE:
-      elf_machine_rela_relative (map->l_addr, reloc, addr_field);
+      elf_machine_rela_relative (map->l_public.l_addr, reloc, addr_field);
       break;
     case R_RISCV_JUMP_SLOT:
     case __WORDSIZE == 64 ? R_RISCV_64 : R_RISCV_32:
@@ -232,7 +233,8 @@ elf_machine_rela (struct link_map *map, struct r_scope_elem *scope[],
 	    /* There's nothing to do if the symbol is in .tbss.  */
 	    if (__glibc_likely (sym->st_value >= sym_map->l_tls_initimage_size))
 	      break;
-	    value += (ElfW(Addr)) sym_map->l_tls_initimage - sym_map->l_addr;
+	    value += ((ElfW(Addr)) sym_map->l_tls_initimage
+		      - sym_map->l_public.l_addr);
 	  }
 
 	size_t size = sym->st_size;
@@ -253,7 +255,7 @@ elf_machine_rela (struct link_map *map, struct r_scope_elem *scope[],
       }
 
     case R_RISCV_IRELATIVE:
-      value = map->l_addr + reloc->r_addend;
+      value = map->l_public.l_addr + reloc->r_addend;
       if (__glibc_likely (!skip_ifunc))
         value = elf_ifunc_invoke (value);
       *addr_field = value;
@@ -271,7 +273,8 @@ elf_machine_rela (struct link_map *map, struct r_scope_elem *scope[],
 
 static inline void
 __attribute__ ((always_inline))
-elf_machine_lazy_rel (struct link_map *map, struct r_scope_elem *scope[],
+elf_machine_lazy_rel (struct link_map_private *map,
+		      struct r_scope_elem *scope[],
 		      ElfW(Addr) l_addr, const ElfW(Rela) *reloc,
 		      int skip_ifunc)
 {
@@ -291,7 +294,7 @@ elf_machine_lazy_rel (struct link_map *map, struct r_scope_elem *scope[],
     }
   else if (__glibc_unlikely (r_type == R_RISCV_IRELATIVE))
     {
-      ElfW(Addr) value = map->l_addr + reloc->r_addend;
+      ElfW(Addr) value = map->l_public.l_addr + reloc->r_addend;
       if (__glibc_likely (!skip_ifunc))
         value = elf_ifunc_invoke (value);
       *reloc_addr = value;
@@ -305,7 +308,8 @@ elf_machine_lazy_rel (struct link_map *map, struct r_scope_elem *scope[],
 
 static inline int
 __attribute__ ((always_inline))
-elf_machine_runtime_setup (struct link_map *l, struct r_scope_elem *scope[],
+elf_machine_runtime_setup (struct link_map_private *l,
+			   struct r_scope_elem *scope[],
 			   int lazy, int profile)
 {
 #ifndef RTLD_BOOTSTRAP
@@ -318,7 +322,7 @@ elf_machine_runtime_setup (struct link_map *l, struct r_scope_elem *scope[],
 	 we have to be able to undo the prelinking of .got.plt.
 	 The prelinker saved the address of .plt for us here.  */
       if (gotplt[1])
-	l->l_mach.plt = gotplt[1] + l->l_addr;
+	l->l_mach.plt = gotplt[1] + l->l_public.l_addr;
       gotplt[0] = (ElfW(Addr)) &_dl_runtime_resolve;
       gotplt[1] = (ElfW(Addr)) l;
     }
diff --git a/sysdeps/s390/s390-32/dl-machine.h b/sysdeps/s390/s390-32/dl-machine.h
index b8bf2796c7..a92248d2ed 100644
--- a/sysdeps/s390/s390-32/dl-machine.h
+++ b/sysdeps/s390/s390-32/dl-machine.h
@@ -89,7 +89,8 @@ elf_machine_load_address (void)
    entries will jump to the on-demand fixup code in dl-runtime.c.  */
 
 static inline int __attribute__ ((unused))
-elf_machine_runtime_setup (struct link_map *l, struct r_scope_elem *scope[],
+elf_machine_runtime_setup (struct link_map_private *l,
+			   struct r_scope_elem *scope[],
 			   int lazy, int profile)
 {
   extern void _dl_runtime_resolve (Elf32_Word);
@@ -113,7 +114,7 @@ elf_machine_runtime_setup (struct link_map *l, struct r_scope_elem *scope[],
 	 The prelinker saved us here address of .plt + 0x2c.  */
       if (got[1])
 	{
-	  l->l_mach.plt = got[1] + l->l_addr;
+	  l->l_mach.plt = got[1] + l->l_public.l_addr;
 	  l->l_mach.jmprel = (const Elf32_Rela *) D_PTR (l, l_info[DT_JMPREL]);
 	}
       got[1] = (Elf32_Addr) l;	/* Identify this shared object.  */
@@ -256,7 +257,7 @@ dl_platform_init (void)
 }
 
 static inline Elf32_Addr
-elf_machine_fixup_plt (struct link_map *map, lookup_t t,
+elf_machine_fixup_plt (struct link_map_private *map, lookup_t t,
 		       const ElfW(Sym) *refsym, const ElfW(Sym) *sym,
 		       const Elf32_Rela *reloc,
 		       Elf32_Addr *reloc_addr, Elf32_Addr value)
@@ -266,7 +267,7 @@ elf_machine_fixup_plt (struct link_map *map, lookup_t t,
 
 /* Return the final value of a plt relocation.  */
 static inline Elf32_Addr
-elf_machine_plt_value (struct link_map *map, const Elf32_Rela *reloc,
+elf_machine_plt_value (struct link_map_private *map, const Elf32_Rela *reloc,
 		       Elf32_Addr value)
 {
   return value;
@@ -286,7 +287,7 @@ elf_machine_plt_value (struct link_map *map, const Elf32_Rela *reloc,
 
 static inline void
 __attribute__ ((always_inline))
-elf_machine_rela (struct link_map *map, struct r_scope_elem *scope[],
+elf_machine_rela (struct link_map_private *map, struct r_scope_elem *scope[],
 		  const Elf32_Rela *reloc, const Elf32_Sym *sym,
 		  const struct r_found_version *version,
 		  void *const reloc_addr_arg, int skip_ifunc)
@@ -296,7 +297,7 @@ elf_machine_rela (struct link_map *map, struct r_scope_elem *scope[],
 
 #if !defined RTLD_BOOTSTRAP
   if (__glibc_unlikely (r_type == R_390_RELATIVE))
-    *reloc_addr = map->l_addr + reloc->r_addend;
+    *reloc_addr = map->l_public.l_addr + reloc->r_addend;
   else
 #endif
   if (__glibc_unlikely (r_type == R_390_NONE))
@@ -307,8 +308,8 @@ elf_machine_rela (struct link_map *map, struct r_scope_elem *scope[],
       /* Only needed for R_390_COPY below.  */
       const Elf32_Sym *const refsym = sym;
 #endif
-      struct link_map *sym_map = RESOLVE_MAP (map, scope, &sym, version,
-					      r_type);
+      struct link_map_private *sym_map
+	= RESOLVE_MAP (map, scope, &sym, version, r_type);
       Elf32_Addr value = SYMBOL_ADDRESS (sym_map, sym, true);
 
       if (sym != NULL
@@ -320,7 +321,7 @@ elf_machine_rela (struct link_map *map, struct r_scope_elem *scope[],
       switch (r_type)
 	{
 	case R_390_IRELATIVE:
-	  value = map->l_addr + reloc->r_addend;
+	  value = map->l_public.l_addr + reloc->r_addend;
 	  if (__glibc_likely (!skip_ifunc))
 	    value = elf_ifunc_invoke (value);
 	  *reloc_addr = value;
@@ -440,7 +441,8 @@ elf_machine_rela_relative (Elf32_Addr l_addr, const Elf32_Rela *reloc,
 
 static inline void
 __attribute__ ((always_inline))
-elf_machine_lazy_rel (struct link_map *map, struct r_scope_elem *scope[],
+elf_machine_lazy_rel (struct link_map_private *map,
+		      struct r_scope_elem *scope[],
 		      Elf32_Addr l_addr, const Elf32_Rela *reloc,
 		      int skip_ifunc)
 {
@@ -456,7 +458,7 @@ elf_machine_lazy_rel (struct link_map *map, struct r_scope_elem *scope[],
     }
   else if (__glibc_likely (r_type == R_390_IRELATIVE))
     {
-      Elf32_Addr value = map->l_addr + reloc->r_addend;
+      Elf32_Addr value = map->l_public.l_addr + reloc->r_addend;
       if (__glibc_likely (!skip_ifunc))
 	value = elf_ifunc_invoke (value);
       *reloc_addr = value;
diff --git a/sysdeps/s390/s390-64/dl-machine.h b/sysdeps/s390/s390-64/dl-machine.h
index 82259dad64..f21df5232c 100644
--- a/sysdeps/s390/s390-64/dl-machine.h
+++ b/sysdeps/s390/s390-64/dl-machine.h
@@ -77,7 +77,8 @@ elf_machine_load_address (void)
    entries will jump to the on-demand fixup code in dl-runtime.c.  */
 
 static inline int __attribute__ ((unused))
-elf_machine_runtime_setup (struct link_map *l, struct r_scope_elem *scope[],
+elf_machine_runtime_setup (struct link_map_private *l,
+			   struct r_scope_elem *scope[],
 			   int lazy, int profile)
 {
   extern void _dl_runtime_resolve (Elf64_Word);
@@ -100,7 +101,7 @@ elf_machine_runtime_setup (struct link_map *l, struct r_scope_elem *scope[],
 	 The prelinker saved us here address of .plt + 0x2e.  */
       if (got[1])
 	{
-	  l->l_mach.plt = got[1] + l->l_addr;
+	  l->l_mach.plt = got[1] + l->l_public.l_addr;
 	  l->l_mach.jmprel = (const Elf64_Rela *) D_PTR (l, l_info[DT_JMPREL]);
 	}
       got[1] = (Elf64_Addr) l;	/* Identify this shared object.	 */
@@ -233,7 +234,7 @@ dl_platform_init (void)
 }
 
 static inline Elf64_Addr
-elf_machine_fixup_plt (struct link_map *map, lookup_t t,
+elf_machine_fixup_plt (struct link_map_private *map, lookup_t t,
 		       const ElfW(Sym) *refsym, const ElfW(Sym) *sym,
 		       const Elf64_Rela *reloc,
 		       Elf64_Addr *reloc_addr, Elf64_Addr value)
@@ -243,7 +244,7 @@ elf_machine_fixup_plt (struct link_map *map, lookup_t t,
 
 /* Return the final value of a plt relocation.	*/
 static inline Elf64_Addr
-elf_machine_plt_value (struct link_map *map, const Elf64_Rela *reloc,
+elf_machine_plt_value (struct link_map_private *map, const Elf64_Rela *reloc,
 		       Elf64_Addr value)
 {
   return value;
@@ -262,7 +263,7 @@ elf_machine_plt_value (struct link_map *map, const Elf64_Rela *reloc,
 
 static inline void
 __attribute__ ((always_inline))
-elf_machine_rela (struct link_map *map, struct r_scope_elem *scope[],
+elf_machine_rela (struct link_map_private *map, struct r_scope_elem *scope[],
 		  const Elf64_Rela *reloc, const Elf64_Sym *sym,
 		  const struct r_found_version *version,
 		  void *const reloc_addr_arg, int skip_ifunc)
@@ -272,7 +273,7 @@ elf_machine_rela (struct link_map *map, struct r_scope_elem *scope[],
 
 #if !defined RTLD_BOOTSTRAP
   if (__glibc_unlikely (r_type == R_390_RELATIVE))
-    *reloc_addr = map->l_addr + reloc->r_addend;
+    *reloc_addr = map->l_public.l_addr + reloc->r_addend;
   else
 #endif
   if (__glibc_unlikely (r_type == R_390_NONE))
@@ -283,8 +284,8 @@ elf_machine_rela (struct link_map *map, struct r_scope_elem *scope[],
       /* Only needed for R_390_COPY below.  */
       const Elf64_Sym *const refsym = sym;
 #endif
-      struct link_map *sym_map = RESOLVE_MAP (map, scope, &sym, version,
-					      r_type);
+      struct link_map_private *sym_map
+	= RESOLVE_MAP (map, scope, &sym, version, r_type);
       Elf64_Addr value = SYMBOL_ADDRESS (sym_map, sym, true);
 
       if (sym != NULL
@@ -297,7 +298,7 @@ elf_machine_rela (struct link_map *map, struct r_scope_elem *scope[],
       switch (r_type)
 	{
 	case R_390_IRELATIVE:
-	  value = map->l_addr + reloc->r_addend;
+	  value = map->l_public.l_addr + reloc->r_addend;
 	  if (__glibc_likely (!skip_ifunc))
 	    value = elf_ifunc_invoke (value);
 	  *reloc_addr = value;
@@ -423,7 +424,8 @@ elf_machine_rela_relative (Elf64_Addr l_addr, const Elf64_Rela *reloc,
 
 static inline void
 __attribute__ ((always_inline))
-elf_machine_lazy_rel (struct link_map *map, struct r_scope_elem *scope[],
+elf_machine_lazy_rel (struct link_map_private *map,
+		      struct r_scope_elem *scope[],
 		      Elf64_Addr l_addr, const Elf64_Rela *reloc,
 		      int skip_ifunc)
 {
@@ -439,7 +441,7 @@ elf_machine_lazy_rel (struct link_map *map, struct r_scope_elem *scope[],
     }
   else if (__glibc_likely (r_type == R_390_IRELATIVE))
     {
-      Elf64_Addr value = map->l_addr + reloc->r_addend;
+      Elf64_Addr value = map->l_public.l_addr + reloc->r_addend;
       if (__glibc_likely (!skip_ifunc))
 	value = elf_ifunc_invoke (value);
       *reloc_addr = value;
diff --git a/sysdeps/sh/dl-machine.h b/sysdeps/sh/dl-machine.h
index e0480eae5a..6841671ae6 100644
--- a/sysdeps/sh/dl-machine.h
+++ b/sysdeps/sh/dl-machine.h
@@ -71,7 +71,8 @@ elf_machine_load_address (void)
    entries will jump to the on-demand fixup code in dl-runtime.c.  */
 
 static inline int __attribute__ ((unused, always_inline))
-elf_machine_runtime_setup (struct link_map *l, struct r_scope_elem *scope[],
+elf_machine_runtime_setup (struct link_map_private *l,
+			   struct r_scope_elem *scope[],
 			   int lazy, int profile)
 {
   Elf32_Addr *got;
@@ -90,7 +91,7 @@ elf_machine_runtime_setup (struct link_map *l, struct r_scope_elem *scope[],
 	 The prelinker saved us here address of .plt + 36.  */
       if (got[1])
 	{
-	  l->l_mach.plt = got[1] + l->l_addr;
+	  l->l_mach.plt = got[1] + l->l_public.l_addr;
 	  l->l_mach.gotplt = (Elf32_Addr) &got[3];
 	}
       got[1] = (Elf32_Addr) l;	/* Identify this shared object.	 */
@@ -220,7 +221,7 @@ dl_platform_init (void)
 }
 
 static inline Elf32_Addr
-elf_machine_fixup_plt (struct link_map *map, lookup_t t,
+elf_machine_fixup_plt (struct link_map_private *map, lookup_t t,
 		       const ElfW(Sym) *refsym, const ElfW(Sym) *sym,
 		       const Elf32_Rela *reloc,
 		       Elf32_Addr *reloc_addr, Elf32_Addr value)
@@ -230,7 +231,7 @@ elf_machine_fixup_plt (struct link_map *map, lookup_t t,
 
 /* Return the final value of a plt relocation.	*/
 static inline Elf32_Addr
-elf_machine_plt_value (struct link_map *map, const Elf32_Rela *reloc,
+elf_machine_plt_value (struct link_map_private *map, const Elf32_Rela *reloc,
 		       Elf32_Addr value)
 {
   return value + reloc->r_addend;
@@ -248,7 +249,7 @@ elf_machine_plt_value (struct link_map *map, const Elf32_Rela *reloc,
 
 static inline void
 __attribute ((always_inline))
-elf_machine_rela (struct link_map *map, struct r_scope_elem *scope[],
+elf_machine_rela (struct link_map_private *map, struct r_scope_elem *scope[],
 		  const Elf32_Rela *reloc, const Elf32_Sym *sym,
 		  const struct r_found_version *version,
 		  void *const reloc_addr_arg, int skip_ifunc)
@@ -288,12 +289,12 @@ elf_machine_rela (struct link_map *map, struct r_scope_elem *scope[],
 #endif
 	{
 	  if (reloc->r_addend)
-	    value = map->l_addr + reloc->r_addend;
+	    value = map->l_public.l_addr + reloc->r_addend;
 	  else
 	    {
 	      COPY_UNALIGNED_WORD (reloc_addr_arg, &value,
 				   (int) reloc_addr_arg & 3);
-	      value += map->l_addr;
+	      value += map->l_public.l_addr;
 	    }
 	  COPY_UNALIGNED_WORD (&value, reloc_addr_arg,
 			       (int) reloc_addr_arg & 3);
@@ -306,8 +307,8 @@ elf_machine_rela (struct link_map *map, struct r_scope_elem *scope[],
   else
     {
       const Elf32_Sym *const refsym = sym;
-      struct link_map *sym_map = RESOLVE_MAP (map, scope, &sym, version,
-					      r_type);
+      struct link_map_private *sym_map
+	= RESOLVE_MAP (map, scope, &sym, version, r_type);
 
       value = SYMBOL_ADDRESS (sym_map, sym, true);
       value += reloc->r_addend;
@@ -434,7 +435,8 @@ elf_machine_rela_relative (Elf32_Addr l_addr, const Elf32_Rela *reloc,
 
 static inline void
 __attribute__ ((always_inline))
-elf_machine_lazy_rel (struct link_map *map, struct r_scope_elem *scope[],
+elf_machine_lazy_rel (struct link_map_private *map,
+		      struct r_scope_elem *scope[],
 		      Elf32_Addr l_addr, const Elf32_Rela *reloc,
 		      int skip_ifunc)
 {
diff --git a/sysdeps/sparc/sparc32/dl-machine.h b/sysdeps/sparc/sparc32/dl-machine.h
index b10e541810..2e9c84e771 100644
--- a/sysdeps/sparc/sparc32/dl-machine.h
+++ b/sysdeps/sparc/sparc32/dl-machine.h
@@ -100,7 +100,8 @@ elf_machine_load_address (void)
    entries will jump to the on-demand fixup code in dl-runtime.c.  */
 
 static inline int
-elf_machine_runtime_setup (struct link_map *l, struct r_scope_elem *scope[],
+elf_machine_runtime_setup (struct link_map_private *l,
+			   struct r_scope_elem *scope[],
 			   int lazy, int profile)
 {
   Elf32_Addr *plt;
@@ -218,7 +219,7 @@ _dl_start_user:\n\
 	.previous");
 
 static inline Elf32_Addr
-elf_machine_fixup_plt (struct link_map *map, lookup_t t,
+elf_machine_fixup_plt (struct link_map_private *map, lookup_t t,
 		       const ElfW(Sym) *refsym, const ElfW(Sym) *sym,
 		       const Elf32_Rela *reloc,
 		       Elf32_Addr *reloc_addr, Elf32_Addr value)
@@ -236,7 +237,7 @@ elf_machine_fixup_plt (struct link_map *map, lookup_t t,
 
 /* Return the final value of a plt relocation.  */
 static inline Elf32_Addr
-elf_machine_plt_value (struct link_map *map, const Elf32_Rela *reloc,
+elf_machine_plt_value (struct link_map_private *map, const Elf32_Rela *reloc,
 		       Elf32_Addr value)
 {
   return value + reloc->r_addend;
@@ -254,7 +255,7 @@ elf_machine_plt_value (struct link_map *map, const Elf32_Rela *reloc,
 
 static inline void
 __attribute__ ((always_inline))
-elf_machine_rela (struct link_map *map, struct r_scope_elem *scope[],
+elf_machine_rela (struct link_map_private *map, struct r_scope_elem *scope[],
 		  const Elf32_Rela *reloc, const Elf32_Sym *sym,
 		  const struct r_found_version *version,
 		  void *const reloc_addr_arg, int skip_ifunc)
@@ -265,7 +266,7 @@ elf_machine_rela (struct link_map *map, struct r_scope_elem *scope[],
 #endif
   Elf32_Addr value;
   const unsigned int r_type = ELF32_R_TYPE (reloc->r_info);
-  struct link_map *sym_map = NULL;
+  struct link_map_private *sym_map = NULL;
 
   if (__glibc_unlikely (r_type == R_SPARC_NONE))
     return;
@@ -279,7 +280,7 @@ elf_machine_rela (struct link_map *map, struct r_scope_elem *scope[],
 #if !defined RTLD_BOOTSTRAP
   if (__glibc_unlikely (r_type == R_SPARC_RELATIVE))
     {
-      *reloc_addr += map->l_addr + reloc->r_addend;
+      *reloc_addr += map->l_public.l_addr + reloc->r_addend;
       return;
     }
 #endif
@@ -288,7 +289,7 @@ elf_machine_rela (struct link_map *map, struct r_scope_elem *scope[],
       && sym->st_shndx != SHN_UNDEF)
     {
       sym_map = map;
-      value = map->l_addr;
+      value = map->l_public.l_addr;
     }
   else
     {
@@ -453,7 +454,8 @@ elf_machine_rela_relative (Elf32_Addr l_addr, const Elf32_Rela *reloc,
 
 static inline void
 __attribute__ ((always_inline))
-elf_machine_lazy_rel (struct link_map *map, struct r_scope_elem *scope[],
+elf_machine_lazy_rel (struct link_map_private *map,
+		      struct r_scope_elem *scope[],
 		      Elf32_Addr l_addr, const Elf32_Rela *reloc,
 		      int skip_ifunc)
 {
@@ -464,7 +466,7 @@ elf_machine_lazy_rel (struct link_map *map, struct r_scope_elem *scope[],
     ;
   else if (r_type == R_SPARC_JMP_IREL)
     {
-      Elf32_Addr value = map->l_addr + reloc->r_addend;
+      Elf32_Addr value = map->l_public.l_addr + reloc->r_addend;
       if (__glibc_likely (!skip_ifunc))
 	value = ((Elf32_Addr (*) (int)) value) (GLRO(dl_hwcap));
       sparc_fixup_plt (reloc, reloc_addr, value, 1, 1);
diff --git a/sysdeps/sparc/sparc64/dl-irel.h b/sysdeps/sparc/sparc64/dl-irel.h
index 4010e1d2c6..84f0389b07 100644
--- a/sysdeps/sparc/sparc64/dl-irel.h
+++ b/sysdeps/sparc/sparc64/dl-irel.h
@@ -50,7 +50,7 @@ elf_irela (const Elf64_Rela *reloc)
     {
       Elf64_Addr *const reloc_addr = (void *) reloc->r_offset;
       Elf64_Addr value = elf_ifunc_invoke(reloc->r_addend);
-      struct link_map map = { .l_addr = 0 };
+      struct link_map_private map = { };
 
       /* 'high' is always zero, for large PLT entries the linker
 	 emits an R_SPARC_IRELATIVE.  */
diff --git a/sysdeps/sparc/sparc64/dl-machine.h b/sysdeps/sparc/sparc64/dl-machine.h
index 98469e7604..c06f568a45 100644
--- a/sysdeps/sparc/sparc64/dl-machine.h
+++ b/sysdeps/sparc/sparc64/dl-machine.h
@@ -86,7 +86,7 @@ elf_machine_load_address (void)
 }
 
 static inline Elf64_Addr __attribute__ ((always_inline))
-elf_machine_fixup_plt (struct link_map *map, lookup_t t,
+elf_machine_fixup_plt (struct link_map_private *map, lookup_t t,
 		       const ElfW(Sym) *refsym, const ElfW(Sym) *sym,
 		       const Elf64_Rela *reloc,
 		       Elf64_Addr *reloc_addr, Elf64_Addr value)
@@ -98,7 +98,7 @@ elf_machine_fixup_plt (struct link_map *map, lookup_t t,
 
 /* Return the final value of a plt relocation.  */
 static inline Elf64_Addr
-elf_machine_plt_value (struct link_map *map, const Elf64_Rela *reloc,
+elf_machine_plt_value (struct link_map_private *map, const Elf64_Rela *reloc,
 		       Elf64_Addr value)
 {
   /* Don't add addend here, but in elf_machine_fixup_plt instead.
@@ -124,8 +124,8 @@ elf_machine_plt_value (struct link_map *map, const Elf64_Rela *reloc,
    entries will jump to the on-demand fixup code in dl-runtime.c.  */
 
 static inline int
-elf_machine_runtime_setup (struct link_map *l, struct r_scope_elem *scope[],
-			   int lazy, int profile)
+elf_machine_runtime_setup (struct link_map_private *l,
+			   struct r_scope_elem *scope[], int lazy, int profile)
 {
   if (l->l_info[DT_JMPREL] && lazy)
     {
@@ -197,7 +197,7 @@ elf_machine_runtime_setup (struct link_map *l, struct r_scope_elem *scope[],
 
       /* Now put the magic cookie at the beginning of .PLT2
 	 Entry .PLT3 is unused by this implementation.  */
-      *((struct link_map **)(&plt[16])) = l;
+      *((struct link_map_private **)(&plt[16])) = l;
     }
 
   return lazy;
@@ -277,7 +277,7 @@ elf_machine_runtime_setup (struct link_map *l, struct r_scope_elem *scope[],
 
 static inline void
 __attribute__ ((always_inline))
-elf_machine_rela (struct link_map *map, struct r_scope_elem *scope[],
+elf_machine_rela (struct link_map_private *map, struct r_scope_elem *scope[],
 		  const Elf64_Rela *reloc, const Elf64_Sym *sym,
 		  const struct r_found_version *version,
 		  void *const reloc_addr_arg, int skip_ifunc)
@@ -288,7 +288,7 @@ elf_machine_rela (struct link_map *map, struct r_scope_elem *scope[],
 #endif
   Elf64_Addr value;
   const unsigned long int r_type = ELF64_R_TYPE_ID (reloc->r_info);
-  struct link_map *sym_map = NULL;
+  struct link_map_private *sym_map = NULL;
 
   if (__glibc_unlikely (r_type == R_SPARC_NONE))
     return;
@@ -302,7 +302,7 @@ elf_machine_rela (struct link_map *map, struct r_scope_elem *scope[],
 #if !defined RTLD_BOOTSTRAP
   if (__glibc_unlikely (r_type == R_SPARC_RELATIVE))
     {
-      *reloc_addr += map->l_addr + reloc->r_addend;
+      *reloc_addr += map->l_public.l_addr + reloc->r_addend;
       return;
     }
 #endif
@@ -311,7 +311,7 @@ elf_machine_rela (struct link_map *map, struct r_scope_elem *scope[],
       && sym->st_shndx != SHN_UNDEF)
     {
       sym_map = map;
-      value = map->l_addr;
+      value = map->l_public.l_addr;
     }
   else
     {
@@ -545,7 +545,8 @@ elf_machine_rela_relative (Elf64_Addr l_addr, const Elf64_Rela *reloc,
 
 static inline void
 __attribute__ ((always_inline))
-elf_machine_lazy_rel (struct link_map *map, struct r_scope_elem *scope[],
+elf_machine_lazy_rel (struct link_map_private *map,
+		      struct r_scope_elem *scope[],
 		      Elf64_Addr l_addr, const Elf64_Rela *reloc,
 		      int skip_ifunc)
 {
@@ -557,7 +558,7 @@ elf_machine_lazy_rel (struct link_map *map, struct r_scope_elem *scope[],
   else if (r_type == R_SPARC_JMP_IREL
 	   || r_type == R_SPARC_IRELATIVE)
     {
-      Elf64_Addr value = map->l_addr + reloc->r_addend;
+      Elf64_Addr value = map->l_public.l_addr + reloc->r_addend;
       if (__glibc_likely (!skip_ifunc))
 	value = ((Elf64_Addr (*) (int)) value) (GLRO(dl_hwcap));
       if (r_type == R_SPARC_JMP_IREL)
diff --git a/sysdeps/sparc/sparc64/dl-plt.h b/sysdeps/sparc/sparc64/dl-plt.h
index 900563bb87..e2350ab968 100644
--- a/sysdeps/sparc/sparc64/dl-plt.h
+++ b/sysdeps/sparc/sparc64/dl-plt.h
@@ -22,7 +22,7 @@
 /* We have 4 cases to handle.  And we code different code sequences
    for each one.  I love V9 code models...  */
 static inline void __attribute__ ((always_inline))
-sparc64_fixup_plt (struct link_map *map, const Elf64_Rela *reloc,
+sparc64_fixup_plt (struct link_map_private *map, const Elf64_Rela *reloc,
 		   Elf64_Addr *reloc_addr, Elf64_Addr value,
 		   Elf64_Addr high, int t)
 {
@@ -43,7 +43,7 @@ sparc64_fixup_plt (struct link_map *map, const Elf64_Rela *reloc,
   /* PLT entries .PLT32768 and above look always the same.  */
   if (__builtin_expect (high, 0) != 0)
     {
-      *reloc_addr = value - map->l_addr;
+      *reloc_addr = value - map->l_public.l_addr;
     }
   /* Near destination.  */
   else if (disp >= -0x800000 && disp < 0x800000)
diff --git a/sysdeps/unix/sysv/linux/dl-vdso.h b/sysdeps/unix/sysv/linux/dl-vdso.h
index 64002cd075..bfe6b82f10 100644
--- a/sysdeps/unix/sysv/linux/dl-vdso.h
+++ b/sysdeps/unix/sysv/linux/dl-vdso.h
@@ -37,7 +37,7 @@
 static inline void *
 dl_vdso_vsym (const char *name)
 {
-  struct link_map *map = GLRO (dl_sysinfo_map);
+  struct link_map_private *map = GLRO (dl_sysinfo_map);
   if (map == NULL)
     return NULL;
 
diff --git a/sysdeps/unix/sysv/linux/powerpc/libc-start.c b/sysdeps/unix/sysv/linux/powerpc/libc-start.c
index b6aec4615d..4781d2bcdd 100644
--- a/sysdeps/unix/sysv/linux/powerpc/libc-start.c
+++ b/sysdeps/unix/sysv/linux/powerpc/libc-start.c
@@ -101,7 +101,7 @@ __libc_start_main_impl (int argc, char **argv,
 
   void *stmain = stinfo->main;
 #if ENABLE_STATIC_PIE && !defined SHARED
-  struct link_map *map = _dl_get_dl_main_map ();
+  struct link_map_private *map = _dl_get_dl_main_map ();
   if (!map->l_relocated)
     stmain = (char *) stmain + elf_machine_load_address ();
 #endif
diff --git a/sysdeps/unix/sysv/linux/powerpc/powerpc64/ldsodefs.h b/sysdeps/unix/sysv/linux/powerpc/powerpc64/ldsodefs.h
index d9f2e0b8cb..5ed1a30535 100644
--- a/sysdeps/unix/sysv/linux/powerpc/powerpc64/ldsodefs.h
+++ b/sysdeps/unix/sysv/linux/powerpc/powerpc64/ldsodefs.h
@@ -26,19 +26,21 @@
 #if _CALL_ELF != 2
 
 static __always_inline bool
-_dl_ppc64_is_opd_sym (const struct link_map *l, const ElfW(Sym) *sym)
+_dl_ppc64_is_opd_sym (const struct link_map_private *l, const ElfW(Sym) *sym)
 {
   return (ELFW(ST_TYPE) (sym->st_info) == STT_FUNC
-	  && l->l_addr + sym->st_value >= (ElfW(Addr)) l->l_ld
-	  && l->l_addr + sym->st_value < l->l_map_end
+	  && (l->l_public.l_addr + sym->st_value
+	      >= (ElfW(Addr)) l->l_public.l_ld)
+	  && l->l_public.l_addr + sym->st_value < l->l_map_end
 	  && sym->st_size != 0);
 }
 
 static __always_inline bool
-_dl_ppc64_addr_sym_match (const struct link_map *l, const ElfW(Sym) *sym,
+_dl_ppc64_addr_sym_match (const struct link_map_private *l,
+			  const ElfW(Sym) *sym,
 			  const ElfW(Sym) *matchsym, ElfW(Addr) addr)
 {
-  ElfW(Addr) value = l->l_addr + sym->st_value;
+  ElfW(Addr) value = l->l_public.l_addr + sym->st_value;
   if (_dl_ppc64_is_opd_sym (l, sym))
     {
       if (addr < value || addr >= value + 24)
@@ -59,7 +61,7 @@ _dl_ppc64_addr_sym_match (const struct link_map *l, const ElfW(Sym) *sym,
   if (matchsym == NULL)
     return true;
 
-  ElfW(Addr) matchvalue = l->l_addr + matchsym->st_value;
+  ElfW(Addr) matchvalue = l->l_public.l_addr + matchsym->st_value;
   if (_dl_ppc64_is_opd_sym (l, matchsym)
       && (addr < matchvalue || addr > matchvalue + 24))
     matchvalue = *(ElfW(Addr) *) matchvalue;
diff --git a/sysdeps/unix/sysv/linux/powerpc/rtld_static_init.h b/sysdeps/unix/sysv/linux/powerpc/rtld_static_init.h
index 53f7d3c2d9..e301b34b81 100644
--- a/sysdeps/unix/sysv/linux/powerpc/rtld_static_init.h
+++ b/sysdeps/unix/sysv/linux/powerpc/rtld_static_init.h
@@ -17,7 +17,8 @@
    <https://www.gnu.org/licenses/>.  */
 
 static inline void
-__rtld_static_init_arch (struct link_map *map, struct rtld_global_ro *dl)
+__rtld_static_init_arch (struct link_map_private *map,
+                         struct rtld_global_ro *dl)
 {
   /* This field does not exist in the generic _rtld_global_ro version.  */
 
diff --git a/sysdeps/x86/dl-lookupcfg.h b/sysdeps/x86/dl-lookupcfg.h
index 1f6be346c1..4a8904b4c4 100644
--- a/sysdeps/x86/dl-lookupcfg.h
+++ b/sysdeps/x86/dl-lookupcfg.h
@@ -20,8 +20,8 @@
 
 #include_next <dl-lookupcfg.h>
 
-struct link_map;
+struct link_map_private;
 
-extern void _dl_unmap (struct link_map *map) attribute_hidden;
+extern void _dl_unmap (struct link_map_private *map) attribute_hidden;
 
 #define DL_UNMAP(map) _dl_unmap (map)
diff --git a/sysdeps/x86/dl-prop.h b/sysdeps/x86/dl-prop.h
index b2836f3009..ba70b06c3a 100644
--- a/sysdeps/x86/dl-prop.h
+++ b/sysdeps/x86/dl-prop.h
@@ -21,17 +21,17 @@
 
 #include <libintl.h>
 
-extern void _dl_cet_check (struct link_map *, const char *)
+extern void _dl_cet_check (struct link_map_private *, const char *)
     attribute_hidden;
-extern void _dl_cet_open_check (struct link_map *)
+extern void _dl_cet_open_check (struct link_map_private *)
     attribute_hidden;
 
 static void
-dl_isa_level_check (struct link_map *m, const char *program)
+dl_isa_level_check (struct link_map_private *m, const char *program)
 {
   const struct cpu_features *cpu_features = __get_cpu_features ();
   unsigned int i;
-  struct link_map *l;
+  struct link_map_private *l;
 
   i = m->l_searchlist.r_nlist;
   while (i-- > 0)
@@ -55,16 +55,17 @@ dl_isa_level_check (struct link_map *m, const char *program)
 	{
 	  if (program)
 	    _dl_fatal_printf ("%s: CPU ISA level is lower than required\n",
-			      *l->l_name != '\0' ? l->l_name : program);
+			      *l->l_public.l_name != '\0'
+			      ? l->l_public.l_name : program);
 	  else
-	    _dl_signal_error (0, l->l_name, "dlopen",
+	    _dl_signal_error (0, l->l_public.l_name, "dlopen",
 			      N_("CPU ISA level is lower than required"));
 	}
     }
 }
 
 static inline void __attribute__ ((always_inline))
-_rtld_main_check (struct link_map *m, const char *program)
+_rtld_main_check (struct link_map_private *m, const char *program)
 {
   dl_isa_level_check (m, program);
 #if CET_ENABLED
@@ -73,7 +74,7 @@ _rtld_main_check (struct link_map *m, const char *program)
 }
 
 static inline void __attribute__ ((always_inline))
-_dl_open_check (struct link_map *m)
+_dl_open_check (struct link_map_private *m)
 {
   dl_isa_level_check (m, NULL);
 #if CET_ENABLED
@@ -82,7 +83,7 @@ _dl_open_check (struct link_map *m)
 }
 
 static inline void __attribute__ ((unused))
-_dl_process_property_note (struct link_map *l, const ElfW(Nhdr) *note,
+_dl_process_property_note (struct link_map_private *l, const ElfW(Nhdr) *note,
 			   const ElfW(Addr) size, const ElfW(Addr) align)
 {
   /* Skip if we have seen a NT_GNU_PROPERTY_TYPE_0 note before.  */
@@ -207,14 +208,14 @@ _dl_process_property_note (struct link_map *l, const ElfW(Nhdr) *note,
 }
 
 static inline void __attribute__ ((unused))
-_dl_process_pt_note (struct link_map *l, int fd, const ElfW(Phdr) *ph)
+_dl_process_pt_note (struct link_map_private *l, int fd, const ElfW(Phdr) *ph)
 {
-  const ElfW(Nhdr) *note = (const void *) (ph->p_vaddr + l->l_addr);
+  const ElfW(Nhdr) *note = (const void *) (ph->p_vaddr + l->l_public.l_addr);
   _dl_process_property_note (l, note, ph->p_memsz, ph->p_align);
 }
 
 static inline int __attribute__ ((always_inline))
-_dl_process_gnu_property (struct link_map *l, int fd, uint32_t type,
+_dl_process_gnu_property (struct link_map_private *l, int fd, uint32_t type,
 			  uint32_t datasz, void *data)
 {
   return 0;
diff --git a/sysdeps/x86_64/dl-machine.h b/sysdeps/x86_64/dl-machine.h
index 581a2f1a9e..915ac77dd8 100644
--- a/sysdeps/x86_64/dl-machine.h
+++ b/sysdeps/x86_64/dl-machine.h
@@ -58,8 +58,8 @@ elf_machine_dynamic (void)
    entries will jump to the on-demand fixup code in dl-runtime.c.  */
 
 static inline int __attribute__ ((unused, always_inline))
-elf_machine_runtime_setup (struct link_map *l, struct r_scope_elem *scope[],
-			   int lazy, int profile)
+elf_machine_runtime_setup (struct link_map_private *l,
+			   struct r_scope_elem *scope[], int lazy, int profile)
 {
   Elf64_Addr *got;
   extern void _dl_runtime_resolve_fxsave (ElfW(Word)) attribute_hidden;
@@ -81,7 +81,7 @@ elf_machine_runtime_setup (struct link_map *l, struct r_scope_elem *scope[],
 	 The prelinker saved us here address of .plt + 0x16.  */
       if (got[1])
 	{
-	  l->l_mach.plt = got[1] + l->l_addr;
+	  l->l_mach.plt = got[1] + l->l_public.l_addr;
 	  l->l_mach.gotplt = (ElfW(Addr)) &got[3];
 	}
       /* Identify this shared object.  */
@@ -148,7 +148,7 @@ _dl_start_user:\n\
 	movq %rax, %r12\n\
 	# Read the original argument count.\n\
 	movq (%rsp), %rdx\n\
-	# Call _dl_init (struct link_map *main_map, int argc, char **argv, char **env)\n\
+	# Call _dl_init (struct link_map_private *main_map, int argc, char **argv, char **env)\n\
 	# argc -> rsi\n\
 	movq %rdx, %rsi\n\
 	# Save %rsp value in %r13.\n\
@@ -214,7 +214,7 @@ dl_platform_init (void)
 }
 
 static inline ElfW(Addr)
-elf_machine_fixup_plt (struct link_map *map, lookup_t t,
+elf_machine_fixup_plt (struct link_map_private *map, lookup_t t,
 		       const ElfW(Sym) *refsym, const ElfW(Sym) *sym,
 		       const ElfW(Rela) *reloc,
 		       ElfW(Addr) *reloc_addr, ElfW(Addr) value)
@@ -225,7 +225,7 @@ elf_machine_fixup_plt (struct link_map *map, lookup_t t,
 /* Return the final value of a PLT relocation.  On x86-64 the
    JUMP_SLOT relocation ignores the addend.  */
 static inline ElfW(Addr)
-elf_machine_plt_value (struct link_map *map, const ElfW(Rela) *reloc,
+elf_machine_plt_value (struct link_map_private *map, const ElfW(Rela) *reloc,
 		       ElfW(Addr) value)
 {
   return value;
@@ -244,7 +244,7 @@ elf_machine_plt_value (struct link_map *map, const ElfW(Rela) *reloc,
    MAP is the object containing the reloc.  */
 
 static inline void __attribute__((always_inline))
-elf_machine_rela(struct link_map *map, struct r_scope_elem *scope[],
+elf_machine_rela(struct link_map_private *map, struct r_scope_elem *scope[],
 		 const ElfW(Rela) *reloc, const ElfW(Sym) *sym,
 		 const struct r_found_version *version,
 		 void *const reloc_addr_arg, int skip_ifunc) {
@@ -253,14 +253,15 @@ elf_machine_rela(struct link_map *map, struct r_scope_elem *scope[],
 
 # if !defined RTLD_BOOTSTRAP
   if (__glibc_unlikely (r_type == R_X86_64_RELATIVE))
-    *reloc_addr = map->l_addr + reloc->r_addend;
+    *reloc_addr = map->l_public.l_addr + reloc->r_addend;
   else
 # endif
 # if !defined RTLD_BOOTSTRAP
   /* l_addr + r_addend may be > 0xffffffff and R_X86_64_RELATIVE64
      relocation updates the whole 64-bit entry.  */
   if (__glibc_unlikely (r_type == R_X86_64_RELATIVE64))
-    *(Elf64_Addr *) reloc_addr = (Elf64_Addr) map->l_addr + reloc->r_addend;
+    *(Elf64_Addr *) reloc_addr
+      = (Elf64_Addr) map->l_public.l_addr + reloc->r_addend;
   else
 # endif
   if (__glibc_unlikely (r_type == R_X86_64_NONE))
@@ -270,7 +271,7 @@ elf_machine_rela(struct link_map *map, struct r_scope_elem *scope[],
 # ifndef RTLD_BOOTSTRAP
       const ElfW(Sym) *const refsym = sym;
 # endif
-      struct link_map *sym_map = RESOLVE_MAP (map, scope, &sym, version,
+      struct link_map_private *sym_map = RESOLVE_MAP (map, scope, &sym, version,
 					      r_type);
       ElfW(Addr) value = SYMBOL_ADDRESS (sym_map, sym, true);
 
@@ -290,12 +291,12 @@ elf_machine_rela(struct link_map *map, struct r_scope_elem *scope[],
 %s: IFUNC symbol '%s' referenced in '%s' is defined in the executable \
 and creates an unsatisfiable circular dependency.\n",
 				  RTLD_PROGNAME, strtab + refsym->st_name,
-				  map->l_name);
+				  map->l_public.l_name);
 	      else
 		_dl_error_printf ("\
 %s: Relink `%s' with `%s' for IFUNC symbol `%s'\n",
-				  RTLD_PROGNAME, map->l_name,
-				  sym_map->l_name,
+				  RTLD_PROGNAME, map->l_public.l_name,
+				  sym_map->l_public.l_name,
 				  strtab + refsym->st_name);
 	    }
 # endif
@@ -459,7 +460,7 @@ and creates an unsatisfiable circular dependency.\n",
 	    }
 	  break;
 	case R_X86_64_IRELATIVE:
-	  value = map->l_addr + reloc->r_addend;
+	  value = map->l_public.l_addr + reloc->r_addend;
 	  if (__glibc_likely (!skip_ifunc))
 	    value = ((ElfW(Addr) (*) (void)) value) ();
 	  *reloc_addr = value;
@@ -493,7 +494,8 @@ elf_machine_rela_relative (ElfW(Addr) l_addr, const ElfW(Rela) *reloc,
 
 static inline void
 __attribute ((always_inline))
-elf_machine_lazy_rel (struct link_map *map, struct r_scope_elem *scope[],
+elf_machine_lazy_rel (struct link_map_private *map,
+		      struct r_scope_elem *scope[],
 		      ElfW(Addr) l_addr, const ElfW(Rela) *reloc,
 		      int skip_ifunc)
 {
@@ -531,7 +533,7 @@ elf_machine_lazy_rel (struct link_map *map, struct r_scope_elem *scope[],
     }
   else if (__glibc_unlikely (r_type == R_X86_64_IRELATIVE))
     {
-      ElfW(Addr) value = map->l_addr + reloc->r_addend;
+      ElfW(Addr) value = map->l_public.l_addr + reloc->r_addend;
       if (__glibc_likely (!skip_ifunc))
 	value = ((ElfW(Addr) (*) (void)) value) ();
       *reloc_addr = value;
diff --git a/sysdeps/x86_64/dl-tlsdesc.h b/sysdeps/x86_64/dl-tlsdesc.h
index 4931ccbe33..ebff5e819d 100644
--- a/sysdeps/x86_64/dl-tlsdesc.h
+++ b/sysdeps/x86_64/dl-tlsdesc.h
@@ -58,7 +58,7 @@ extern ptrdiff_t attribute_hidden
   _dl_tlsdesc_undefweak(struct tlsdesc *on_rax);
 
 # ifdef SHARED
-extern void *_dl_make_tlsdesc_dynamic (struct link_map *map,
+extern void *_dl_make_tlsdesc_dynamic (struct link_map_private *map,
 				       size_t ti_offset)
   attribute_hidden;
 
diff --git a/sysdeps/x86_64/tlsdesc.c b/sysdeps/x86_64/tlsdesc.c
index 30aa8eb9ae..2222622c8e 100644
--- a/sysdeps/x86_64/tlsdesc.c
+++ b/sysdeps/x86_64/tlsdesc.c
@@ -26,7 +26,7 @@
    if there is one.  */
 
 void
-_dl_unmap (struct link_map *map)
+_dl_unmap (struct link_map_private *map)
 {
   _dl_unmap_segments (map);
 
