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