diff options
Diffstat (limited to 'libelf/elf32_checksum.c')
-rw-r--r-- | libelf/elf32_checksum.c | 27 |
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)) |