summaryrefslogtreecommitdiffstats
path: root/libelf/elf_begin.c
diff options
context:
space:
mode:
Diffstat (limited to 'libelf/elf_begin.c')
-rw-r--r--libelf/elf_begin.c23
1 files changed, 17 insertions, 6 deletions
diff --git a/libelf/elf_begin.c b/libelf/elf_begin.c
index bd385306..04670a45 100644
--- a/libelf/elf_begin.c
+++ b/libelf/elf_begin.c
@@ -750,7 +750,7 @@ read_long_names (Elf *elf)
/* Read the next archive header. */
int
internal_function
-__libelf_next_arhdr (elf)
+__libelf_next_arhdr_wrlock (elf)
Elf *elf;
{
struct ar_hdr *ar_hdr;
@@ -949,7 +949,7 @@ dup_elf (int fildes, Elf_Cmd cmd, Elf *ref)
pointing to. First read the header of the next member if this
has not happened already. */
if (ref->state.ar.elf_ar_hdr.ar_name == NULL
- && __libelf_next_arhdr (ref) != 0)
+ && __libelf_next_arhdr_wrlock (ref) != 0)
/* Something went wrong. Maybe there is no member left. */
return NULL;
@@ -1023,6 +1023,19 @@ elf_begin (fildes, cmd, ref)
return NULL;
}
+ Elf *lock_dup_elf ()
+ {
+ /* We need wrlock to dup an archive. */
+ if (ref->kind == ELF_K_AR)
+ {
+ rwlock_unlock (ref->lock);
+ rwlock_wrlock (ref->lock);
+ }
+
+ /* Duplicate the descriptor. */
+ return dup_elf (fildes, cmd, ref);
+ }
+
switch (cmd)
{
case ELF_C_NULL:
@@ -1043,8 +1056,7 @@ elf_begin (fildes, cmd, ref)
case ELF_C_READ:
case ELF_C_READ_MMAP:
if (ref != NULL)
- /* Duplicate the descriptor. */
- retval = dup_elf (fildes, cmd, ref);
+ retval = lock_dup_elf ();
else
/* Create descriptor for existing file. */
retval = read_file (fildes, 0, ~((size_t) 0), cmd, NULL);
@@ -1065,8 +1077,7 @@ elf_begin (fildes, cmd, ref)
retval = NULL;
}
else
- /* Duplicate this descriptor. */
- retval = dup_elf (fildes, cmd, ref);
+ retval = lock_dup_elf ();
}
else
/* Create descriptor for existing file. */