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