summaryrefslogtreecommitdiff
path: root/libelf/elf32_checksum.c
diff options
context:
space:
mode:
Diffstat (limited to 'libelf/elf32_checksum.c')
-rw-r--r--libelf/elf32_checksum.c27
1 files changed, 22 insertions, 5 deletions
diff --git a/libelf/elf32_checksum.c b/libelf/elf32_checksum.c
index 0e4ab9f7..ad040b80 100644
--- a/libelf/elf32_checksum.c
+++ b/libelf/elf32_checksum.c
@@ -1,5 +1,5 @@
/* Compute simple checksum from permanent parts of the ELF file.
- Copyright (C) 2002, 2003, 2004, 2005 Red Hat, Inc.
+ Copyright (C) 2002, 2003, 2004, 2005, 2009 Red Hat, Inc.
This file is part of Red Hat elfutils.
Written by Ulrich Drepper <drepper@redhat.com>, 2002.
@@ -90,7 +90,7 @@ elfw2(LIBELFBITS,checksum) (elf)
return -1l;
/* Find the section header string table. */
- if (INTUSE(elf_getshstrndx) (elf, &shstrndx) < 0)
+ if (INTUSE(elf_getshdrstrndx) (elf, &shstrndx) < 0)
{
/* This can only happen if the ELF handle is not for real. */
__libelf_seterrno (ELF_E_INVALID_HANDLE);
@@ -105,6 +105,14 @@ elfw2(LIBELFBITS,checksum) (elf)
|| (ident[EI_DATA] == ELFDATA2MSB
&& __BYTE_ORDER == __BIG_ENDIAN));
+ /* If we don't have native byte order, we will likely need to
+ convert the data with xlate functions. We do it upfront instead
+ of relocking mid-iteration. */
+ if (!likely (same_byte_order))
+ rwlock_wrlock (elf->lock);
+ else
+ rwlock_rdlock (elf->lock);
+
/* Iterate over all sections to find those which are not strippable. */
scn = NULL;
while ((scn = INTUSE(elf_nextscn) (elf, scn)) != NULL)
@@ -118,7 +126,8 @@ elfw2(LIBELFBITS,checksum) (elf)
if (shdr == NULL)
{
__libelf_seterrno (ELF_E_INVALID_SECTION_HEADER);
- return -1l;
+ result = -1l;
+ goto out;
}
if (SECTION_STRIP_P (shdr,
@@ -162,17 +171,25 @@ elfw2(LIBELFBITS,checksum) (elf)
/* Convert the data to file byte order. */
if (INTUSE(elfw2(LIBELFBITS,xlatetof)) (data, data, ident[EI_DATA])
== NULL)
- return -1l;
+ {
+ result = -1l;
+ goto out;
+ }
result = process_block (result, data);
/* And convert it back. */
if (INTUSE(elfw2(LIBELFBITS,xlatetom)) (data, data, ident[EI_DATA])
== NULL)
- return -1l;
+ {
+ result = -1l;
+ goto out;
+ }
}
}
+ out:
+ rwlock_unlock (elf->lock);
return result;
}
INTDEF(elfw2(LIBELFBITS,checksum))