446cf2
commit e1d559f337de2c8ab68a6749dfe873477c883807
446cf2
Author: Florian Weimer <fweimer@redhat.com>
446cf2
Date:   Sat Nov 2 20:04:02 2019 +0100
446cf2
446cf2
    Introduce link_map_audit_state accessor function
446cf2
    
446cf2
    To improve GCC 10 compatibility, it is necessary to remove the l_audit
446cf2
    zero-length array from the end of struct link_map.  In preparation of
446cf2
    that, this commit introduces an accessor function for the audit state,
446cf2
    so that it is possible to change the representation of the audit state
446cf2
    without adjusting the code that accesses it.
446cf2
    
446cf2
    Tested on x86_64-linux-gnu.  Built on i686-gnu.
446cf2
    
446cf2
    Change-Id: Id815673c29950fc011ae5301d7cde12624f658df
446cf2
446cf2
diff --git a/csu/libc-start.c b/csu/libc-start.c
446cf2
index 494132368f8fe486..dfbf195328239a17 100644
446cf2
--- a/csu/libc-start.c
446cf2
+++ b/csu/libc-start.c
446cf2
@@ -272,7 +272,7 @@ LIBC_START_MAIN (int (*main) (int, char **, char ** MAIN_AUXVEC_DECL),
446cf2
       for (unsigned int cnt = 0; cnt < GLRO(dl_naudit); ++cnt)
446cf2
 	{
446cf2
 	  if (afct->preinit != NULL)
446cf2
-	    afct->preinit (&head->l_audit[cnt].cookie);
446cf2
+	    afct->preinit (&link_map_audit_state (head, cnt)->cookie);
446cf2
 
446cf2
 	  afct = afct->next;
446cf2
 	}
446cf2
diff --git a/elf/dl-close.c b/elf/dl-close.c
446cf2
index a9ecdff62dba88fb..1ece0ae1dd062d1e 100644
446cf2
--- a/elf/dl-close.c
446cf2
+++ b/elf/dl-close.c
446cf2
@@ -305,8 +305,12 @@ _dl_close_worker (struct link_map *map, bool force)
446cf2
 	      for (unsigned int cnt = 0; cnt < GLRO(dl_naudit); ++cnt)
446cf2
 		{
446cf2
 		  if (afct->objclose != NULL)
446cf2
-		    /* Return value is ignored.  */
446cf2
-		    (void) afct->objclose (&imap->l_audit[cnt].cookie);
446cf2
+		    {
446cf2
+		      struct auditstate *state
446cf2
+			= link_map_audit_state (imap, cnt);
446cf2
+		      /* Return value is ignored.  */
446cf2
+		      (void) afct->objclose (&state->cookie);
446cf2
+		    }
446cf2
 
446cf2
 		  afct = afct->next;
446cf2
 		}
446cf2
@@ -481,7 +485,10 @@ _dl_close_worker (struct link_map *map, bool force)
446cf2
 	  for (unsigned int cnt = 0; cnt < GLRO(dl_naudit); ++cnt)
446cf2
 	    {
446cf2
 	      if (afct->activity != NULL)
446cf2
-		afct->activity (&head->l_audit[cnt].cookie, LA_ACT_DELETE);
446cf2
+		{
446cf2
+		  struct auditstate *state = link_map_audit_state (head, cnt);
446cf2
+		  afct->activity (&state->cookie, LA_ACT_DELETE);
446cf2
+		}
446cf2
 
446cf2
 	      afct = afct->next;
446cf2
 	    }
446cf2
@@ -781,7 +788,10 @@ _dl_close_worker (struct link_map *map, bool force)
446cf2
 	  for (unsigned int cnt = 0; cnt < GLRO(dl_naudit); ++cnt)
446cf2
 	    {
446cf2
 	      if (afct->activity != NULL)
446cf2
-		afct->activity (&head->l_audit[cnt].cookie, LA_ACT_CONSISTENT);
446cf2
+		{
446cf2
+		  struct auditstate *state = link_map_audit_state (head, cnt);
446cf2
+		  afct->activity (&state->cookie, LA_ACT_CONSISTENT);
446cf2
+		}
446cf2
 
446cf2
 	      afct = afct->next;
446cf2
 	    }
446cf2
diff --git a/elf/dl-fini.c b/elf/dl-fini.c
446cf2
index 3cfc262400da4db9..915ceb104e1c81d6 100644
446cf2
--- a/elf/dl-fini.c
446cf2
+++ b/elf/dl-fini.c
446cf2
@@ -152,9 +152,12 @@ _dl_fini (void)
446cf2
 		      for (unsigned int cnt = 0; cnt < GLRO(dl_naudit); ++cnt)
446cf2
 			{
446cf2
 			  if (afct->objclose != NULL)
446cf2
-			    /* Return value is ignored.  */
446cf2
-			    (void) afct->objclose (&l->l_audit[cnt].cookie);
446cf2
-
446cf2
+			    {
446cf2
+			      struct auditstate *state
446cf2
+				= link_map_audit_state (l, cnt);
446cf2
+			      /* Return value is ignored.  */
446cf2
+			      (void) afct->objclose (&state->cookie);
446cf2
+			    }
446cf2
 			  afct = afct->next;
446cf2
 			}
446cf2
 		    }
446cf2
diff --git a/elf/dl-load.c b/elf/dl-load.c
446cf2
index b190b28e32e47391..8f8869ff524ab9f2 100644
446cf2
--- a/elf/dl-load.c
446cf2
+++ b/elf/dl-load.c
446cf2
@@ -979,7 +979,8 @@ _dl_map_object_from_fd (const char *name, const char *origname, int fd,
446cf2
 	      for (unsigned int cnt = 0; cnt < GLRO(dl_naudit); ++cnt)
446cf2
 		{
446cf2
 		  if (afct->activity != NULL)
446cf2
-		    afct->activity (&head->l_audit[cnt].cookie, LA_ACT_ADD);
446cf2
+		    afct->activity (&link_map_audit_state (head, cnt)->cookie,
446cf2
+				    LA_ACT_ADD);
446cf2
 
446cf2
 		  afct = afct->next;
446cf2
 		}
446cf2
@@ -1418,10 +1419,9 @@ cannot enable executable stack as shared object requires");
446cf2
 	{
446cf2
 	  if (afct->objopen != NULL)
446cf2
 	    {
446cf2
-	      l->l_audit[cnt].bindflags
446cf2
-		= afct->objopen (l, nsid, &l->l_audit[cnt].cookie);
446cf2
-
446cf2
-	      l->l_audit_any_plt |= l->l_audit[cnt].bindflags != 0;
446cf2
+	      struct auditstate *state = link_map_audit_state (l, cnt);
446cf2
+	      state->bindflags = afct->objopen (l, nsid, &state->cookie);
446cf2
+	      l->l_audit_any_plt |= state->bindflags != 0;
446cf2
 	    }
446cf2
 
446cf2
 	  afct = afct->next;
446cf2
@@ -1527,8 +1527,8 @@ open_verify (const char *name, int fd,
446cf2
 	{
446cf2
 	  if (afct->objsearch != NULL)
446cf2
 	    {
446cf2
-	      name = afct->objsearch (name, &loader->l_audit[cnt].cookie,
446cf2
-				      whatcode);
446cf2
+	      struct auditstate *state = link_map_audit_state (loader, cnt);
446cf2
+	      name = afct->objsearch (name, &state->cookie, whatcode);
446cf2
 	      if (name == NULL)
446cf2
 		/* Ignore the path.  */
446cf2
 		return -1;
446cf2
@@ -1998,8 +1998,8 @@ _dl_map_object (struct link_map *loader, const char *name,
446cf2
 	  if (afct->objsearch != NULL)
446cf2
 	    {
446cf2
 	      const char *before = name;
446cf2
-	      name = afct->objsearch (name, &loader->l_audit[cnt].cookie,
446cf2
-				      LA_SER_ORIG);
446cf2
+	      struct auditstate *state = link_map_audit_state (loader, cnt);
446cf2
+	      name = afct->objsearch (name, &state->cookie, LA_SER_ORIG);
446cf2
 	      if (name == NULL)
446cf2
 		{
446cf2
 		  /* Do not try anything further.  */
446cf2
diff --git a/elf/dl-object.c b/elf/dl-object.c
446cf2
index f6544a8fec45bdce..05a7750c65305771 100644
446cf2
--- a/elf/dl-object.c
446cf2
+++ b/elf/dl-object.c
446cf2
@@ -81,7 +81,7 @@ _dl_new_object (char *realname, const char *libname, int type,
446cf2
   struct link_map *new;
446cf2
   struct libname_list *newname;
446cf2
 #ifdef SHARED
446cf2
-  size_t audit_space = naudit * sizeof (new->l_audit[0]);
446cf2
+  size_t audit_space = naudit * sizeof (struct auditstate);
446cf2
 #else
446cf2
 # define audit_space 0
446cf2
 #endif
446cf2
@@ -134,10 +134,8 @@ _dl_new_object (char *realname, const char *libname, int type,
446cf2
 
446cf2
 #ifdef SHARED
446cf2
   for (unsigned int cnt = 0; cnt < naudit; ++cnt)
446cf2
-    {
446cf2
-      new->l_audit[cnt].cookie = (uintptr_t) new;
446cf2
-      /* new->l_audit[cnt].bindflags = 0; */
446cf2
-    }
446cf2
+    /* No need to initialize bindflags due to calloc.  */
446cf2
+    link_map_audit_state (new, cnt)->cookie = (uintptr_t) new;
446cf2
 #endif
446cf2
 
446cf2
   /* new->l_global = 0;	We use calloc therefore not necessary.  */
446cf2
diff --git a/elf/dl-open.c b/elf/dl-open.c
446cf2
index 46a4c1e5a3f8d2dd..7113c4a04f0fddbc 100644
446cf2
--- a/elf/dl-open.c
446cf2
+++ b/elf/dl-open.c
446cf2
@@ -589,7 +589,10 @@ dl_open_worker (void *a)
446cf2
 	  for (unsigned int cnt = 0; cnt < GLRO(dl_naudit); ++cnt)
446cf2
 	    {
446cf2
 	      if (afct->activity != NULL)
446cf2
-		afct->activity (&head->l_audit[cnt].cookie, LA_ACT_CONSISTENT);
446cf2
+		{
446cf2
+		  struct auditstate *state = link_map_audit_state (head, cnt);
446cf2
+		  afct->activity (&state->cookie, LA_ACT_CONSISTENT);
446cf2
+		}
446cf2
 
446cf2
 	      afct = afct->next;
446cf2
 	    }
446cf2
diff --git a/elf/dl-runtime.c b/elf/dl-runtime.c
446cf2
index 3d2f4a7a76e616e3..72b03e000dcf190e 100644
446cf2
--- a/elf/dl-runtime.c
446cf2
+++ b/elf/dl-runtime.c
446cf2
@@ -325,15 +325,18 @@ _dl_profile_fixup (
446cf2
 		{
446cf2
 		  /* XXX Check whether both DSOs must request action or
446cf2
 		     only one */
446cf2
-		  if ((l->l_audit[cnt].bindflags & LA_FLG_BINDFROM) != 0
446cf2
-		      && (result->l_audit[cnt].bindflags & LA_FLG_BINDTO) != 0)
446cf2
+		  struct auditstate *l_state = link_map_audit_state (l, cnt);
446cf2
+		  struct auditstate *result_state
446cf2
+		    = link_map_audit_state (result, cnt);
446cf2
+		  if ((l_state->bindflags & LA_FLG_BINDFROM) != 0
446cf2
+		      && (result_state->bindflags & LA_FLG_BINDTO) != 0)
446cf2
 		    {
446cf2
 		      if (afct->symbind != NULL)
446cf2
 			{
446cf2
 			  uintptr_t new_value
446cf2
 			    = afct->symbind (&sym, reloc_result->boundndx,
446cf2
-					     &l->l_audit[cnt].cookie,
446cf2
-					     &result->l_audit[cnt].cookie,
446cf2
+					     &l_state->cookie,
446cf2
+					     &result_state->cookie,
446cf2
 					     &flags,
446cf2
 					     strtab2 + defsym->st_name);
446cf2
 			  if (new_value != (uintptr_t) sym.st_value)
446cf2
@@ -421,10 +424,13 @@ _dl_profile_fixup (
446cf2
 		  & (LA_SYMB_NOPLTENTER << (2 * (cnt + 1)))) == 0)
446cf2
 	    {
446cf2
 	      long int new_framesize = -1;
446cf2
+	      struct auditstate *l_state = link_map_audit_state (l, cnt);
446cf2
+	      struct auditstate *bound_state
446cf2
+		= link_map_audit_state (reloc_result->bound, cnt);
446cf2
 	      uintptr_t new_value
446cf2
 		= afct->ARCH_LA_PLTENTER (&sym, reloc_result->boundndx,
446cf2
-					  &l->l_audit[cnt].cookie,
446cf2
-					  &reloc_result->bound->l_audit[cnt].cookie,
446cf2
+					  &l_state->cookie,
446cf2
+					  &bound_state->cookie,
446cf2
 					  regs, &flags, symname,
446cf2
 					  &new_framesize);
446cf2
 	      if (new_value != (uintptr_t) sym.st_value)
446cf2
@@ -504,9 +510,11 @@ _dl_call_pltexit (struct link_map *l, ElfW(Word) reloc_arg,
446cf2
 	  && (reloc_result->enterexit
446cf2
 	      & (LA_SYMB_NOPLTEXIT >> (2 * cnt))) == 0)
446cf2
 	{
446cf2
+	  struct auditstate *l_state = link_map_audit_state (l, cnt);
446cf2
+	  struct auditstate *bound_state
446cf2
+	    = link_map_audit_state (reloc_result->bound, cnt);
446cf2
 	  afct->ARCH_LA_PLTEXIT (&sym, reloc_result->boundndx,
446cf2
-				 &l->l_audit[cnt].cookie,
446cf2
-				 &reloc_result->bound->l_audit[cnt].cookie,
446cf2
+				 &l_state->cookie, &bound_state->cookie,
446cf2
 				 inregs, outregs, symname);
446cf2
 	}
446cf2
 
446cf2
diff --git a/elf/dl-sym.c b/elf/dl-sym.c
446cf2
index 189628adc05aedf1..286cf7e27fd59f20 100644
446cf2
--- a/elf/dl-sym.c
446cf2
+++ b/elf/dl-sym.c
446cf2
@@ -198,17 +198,20 @@ RTLD_NEXT used in code not dynamically loaded"));
446cf2
 
446cf2
 	      for (unsigned int cnt = 0; cnt < GLRO(dl_naudit); ++cnt)
446cf2
 		{
446cf2
+		  struct auditstate *match_audit
446cf2
+		    = link_map_audit_state (match, cnt);
446cf2
+		  struct auditstate *result_audit
446cf2
+		    = link_map_audit_state (result, cnt);
446cf2
 		  if (afct->symbind != NULL
446cf2
-		      && ((match->l_audit[cnt].bindflags & LA_FLG_BINDFROM)
446cf2
-			  != 0
446cf2
-			  || ((result->l_audit[cnt].bindflags & LA_FLG_BINDTO)
446cf2
+		      && ((match_audit->bindflags & LA_FLG_BINDFROM) != 0
446cf2
+			  || ((result_audit->bindflags & LA_FLG_BINDTO)
446cf2
 			      != 0)))
446cf2
 		    {
446cf2
 		      unsigned int flags = altvalue | LA_SYMB_DLSYM;
446cf2
 		      uintptr_t new_value
446cf2
 			= afct->symbind (&sym, ndx,
446cf2
-					 &match->l_audit[cnt].cookie,
446cf2
-					 &result->l_audit[cnt].cookie,
446cf2
+					 &match_audit->cookie,
446cf2
+					 &result_audit->cookie,
446cf2
 					 &flags, strtab + ref->st_name);
446cf2
 		      if (new_value != (uintptr_t) sym.st_value)
446cf2
 			{
446cf2
diff --git a/elf/rtld.c b/elf/rtld.c
446cf2
index f557f39a70669c09..18335bc666f2b89d 100644
446cf2
--- a/elf/rtld.c
446cf2
+++ b/elf/rtld.c
446cf2
@@ -1025,9 +1025,9 @@ ERROR: audit interface '%s' requires version %d (maximum supported version %d);
446cf2
   else
446cf2
     *last_audit = (*last_audit)->next = &newp->ifaces;
446cf2
 
446cf2
-  /* The dynamic linker link map is statically allocated, initialize
446cf2
-     the data now.  */
446cf2
-  GL (dl_rtld_map).l_audit[GLRO (dl_naudit)].cookie
446cf2
+  /* The dynamic linker link map is statically allocated, so the
446cf2
+     cookie in _dl_new_object has not happened.  */
446cf2
+  link_map_audit_state (&GL (dl_rtld_map), GLRO (dl_naudit))->cookie
446cf2
     = (intptr_t) &GL (dl_rtld_map);
446cf2
 
446cf2
   ++GLRO(dl_naudit);
446cf2
@@ -1046,9 +1046,9 @@ notify_audit_modules_of_loaded_object (struct link_map *map)
446cf2
     {
446cf2
       if (afct->objopen != NULL)
446cf2
 	{
446cf2
-	  map->l_audit[cnt].bindflags
446cf2
-	    = afct->objopen (map, LM_ID_BASE, &map->l_audit[cnt].cookie);
446cf2
-	  map->l_audit_any_plt |= map->l_audit[cnt].bindflags != 0;
446cf2
+	  struct auditstate *state = link_map_audit_state (map, cnt);
446cf2
+	  state->bindflags = afct->objopen (map, LM_ID_BASE, &state->cookie);
446cf2
+	  map->l_audit_any_plt |= state->bindflags != 0;
446cf2
 	}
446cf2
 
446cf2
       afct = afct->next;
446cf2
@@ -1660,7 +1660,8 @@ ERROR: '%s': cannot process note segment.\n", _dl_argv[0]);
446cf2
       for (unsigned int cnt = 0; cnt < GLRO(dl_naudit); ++cnt)
446cf2
 	{
446cf2
 	  if (afct->activity != NULL)
446cf2
-	    afct->activity (&main_map->l_audit[cnt].cookie, LA_ACT_ADD);
446cf2
+	    afct->activity (&link_map_audit_state (main_map, cnt)->cookie,
446cf2
+			    LA_ACT_ADD);
446cf2
 
446cf2
 	  afct = afct->next;
446cf2
 	}
446cf2
@@ -2331,7 +2332,8 @@ ERROR: '%s': cannot process note segment.\n", _dl_argv[0]);
446cf2
 	  for (unsigned int cnt = 0; cnt < GLRO(dl_naudit); ++cnt)
446cf2
 	    {
446cf2
 	      if (afct->activity != NULL)
446cf2
-		afct->activity (&head->l_audit[cnt].cookie, LA_ACT_CONSISTENT);
446cf2
+		afct->activity (&link_map_audit_state (head, cnt)->cookie,
446cf2
+				LA_ACT_CONSISTENT);
446cf2
 
446cf2
 	      afct = afct->next;
446cf2
 	    }
446cf2
diff --git a/sysdeps/generic/ldsodefs.h b/sysdeps/generic/ldsodefs.h
446cf2
index 3bdbdd6e67dacc85..a8fb0d211426e4b1 100644
446cf2
--- a/sysdeps/generic/ldsodefs.h
446cf2
+++ b/sysdeps/generic/ldsodefs.h
446cf2
@@ -1197,7 +1197,13 @@ rtld_active (void)
446cf2
      initialized and active ld.so copy.  */
446cf2
   return GLRO(dl_init_all_dirs) != NULL;
446cf2
 }
446cf2
-#endif
446cf2
+
446cf2
+static inline struct auditstate *
446cf2
+link_map_audit_state (struct link_map *l, size_t index)
446cf2
+{
446cf2
+  return &l->l_audit[index];
446cf2
+}
446cf2
+#endif /* SHARED */
446cf2
 
446cf2
 __END_DECLS
446cf2