|
|
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 |
|