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