summaryrefslogtreecommitdiff
path: root/libelf/elf32_updatefile.c
diff options
context:
space:
mode:
authorRoland McGrath <roland@redhat.com>2010-01-07 19:41:04 -0800
committerRoland McGrath <roland@redhat.com>2010-01-07 19:43:42 -0800
commit6fd3cd104adf4107aa64e1c1e84028b4ea0b3296 (patch)
tree6d42f1017e802ccf94abbe5af598eec8b2600166 /libelf/elf32_updatefile.c
parent7452e1953a4a4e70af3fb472e609e89776031e53 (diff)
downloadelfutils-6fd3cd104adf4107aa64e1c1e84028b4ea0b3296.tar.gz
Add elf_getphdrnum, support >65536 phdrs.
Diffstat (limited to 'libelf/elf32_updatefile.c')
-rw-r--r--libelf/elf32_updatefile.c26
1 files changed, 16 insertions, 10 deletions
diff --git a/libelf/elf32_updatefile.c b/libelf/elf32_updatefile.c
index 8be19948..898cf1ab 100644
--- a/libelf/elf32_updatefile.c
+++ b/libelf/elf32_updatefile.c
@@ -1,5 +1,5 @@
/* Write changed data structures.
- Copyright (C) 2000, 2001, 2002, 2004, 2005, 2006, 2007, 2008 Red Hat, Inc.
+ Copyright (C) 2000-2010 Red Hat, Inc.
This file is part of Red Hat elfutils.
Written by Ulrich Drepper <drepper@redhat.com>, 2000.
@@ -165,6 +165,10 @@ __elfw2(LIBELFBITS,updatemmap) (Elf *elf, int change_bo, size_t shnum)
previous_scn_changed = elf->state.ELFW(elf,LIBELFBITS).phdr == NULL;
}
+ size_t phnum;
+ if (unlikely (__elf_getphdrnum_rdlock (elf, &phnum) != 0))
+ return -1;
+
/* Write out the program header table. */
if (elf->state.ELFW(elf,LIBELFBITS).phdr != NULL
&& ((elf->state.ELFW(elf,LIBELFBITS).phdr_flags | elf->flags)
@@ -195,12 +199,12 @@ __elfw2(LIBELFBITS,updatemmap) (Elf *elf, int change_bo, size_t shnum)
/* Do the real work. */
(*fctp) (elf->map_address + elf->start_offset + ehdr->e_phoff,
elf->state.ELFW(elf,LIBELFBITS).phdr,
- sizeof (ElfW2(LIBELFBITS,Phdr)) * ehdr->e_phnum, 1);
+ sizeof (ElfW2(LIBELFBITS,Phdr)) * phnum, 1);
}
else
memcpy (elf->map_address + elf->start_offset + ehdr->e_phoff,
elf->state.ELFW(elf,LIBELFBITS).phdr,
- sizeof (ElfW2(LIBELFBITS,Phdr)) * ehdr->e_phnum);
+ sizeof (ElfW2(LIBELFBITS,Phdr)) * phnum);
elf->state.ELFW(elf,LIBELFBITS).phdr_flags &= ~ELF_F_DIRTY;
@@ -214,8 +218,7 @@ __elfw2(LIBELFBITS,updatemmap) (Elf *elf, int change_bo, size_t shnum)
char *last_position = ((char *) elf->map_address + elf->start_offset
+ MAX (elf_typesize (LIBELFBITS, ELF_T_EHDR, 1),
ehdr->e_phoff)
- + elf_typesize (LIBELFBITS, ELF_T_PHDR,
- ehdr->e_phnum));
+ + elf_typesize (LIBELFBITS, ELF_T_PHDR, phnum));
/* Write all the sections. Well, only those which are modified. */
if (shnum > 0)
@@ -563,6 +566,10 @@ __elfw2(LIBELFBITS,updatefile) (Elf *elf, int change_bo, size_t shnum)
assert (sizeof (ElfW2(LIBELFBITS,Phdr))
== elf_typesize (LIBELFBITS, ELF_T_PHDR, 1));
+ size_t phnum;
+ if (unlikely (__elf_getphdrnum_rdlock (elf, &phnum) != 0))
+ return -1;
+
/* Write out the program header table. */
if (elf->state.ELFW(elf,LIBELFBITS).phdr != NULL
&& ((elf->state.ELFW(elf,LIBELFBITS).phdr_flags | elf->flags)
@@ -592,7 +599,7 @@ __elfw2(LIBELFBITS,updatefile) (Elf *elf, int change_bo, size_t shnum)
/* Allocate sufficient memory. */
tmp_phdr = (ElfW2(LIBELFBITS,Phdr) *)
- malloc (sizeof (ElfW2(LIBELFBITS,Phdr)) * ehdr->e_phnum);
+ malloc (sizeof (ElfW2(LIBELFBITS,Phdr)) * phnum);
if (tmp_phdr == NULL)
{
__libelf_seterrno (ELF_E_NOMEM);
@@ -601,14 +608,14 @@ __elfw2(LIBELFBITS,updatefile) (Elf *elf, int change_bo, size_t shnum)
/* Write the converted ELF header in a temporary buffer. */
(*fctp) (tmp_phdr, elf->state.ELFW(elf,LIBELFBITS).phdr,
- sizeof (ElfW2(LIBELFBITS,Phdr)) * ehdr->e_phnum, 1);
+ sizeof (ElfW2(LIBELFBITS,Phdr)) * phnum, 1);
/* This is the buffer we want to write. */
out_phdr = tmp_phdr;
}
/* Write out the ELF header. */
- size_t phdr_size = sizeof (ElfW2(LIBELFBITS,Phdr)) * ehdr->e_phnum;
+ size_t phdr_size = sizeof (ElfW2(LIBELFBITS,Phdr)) * phnum;
if (unlikely ((size_t) pwrite_retry (elf->fildes, out_phdr,
phdr_size, ehdr->e_phoff)
!= phdr_size))
@@ -633,8 +640,7 @@ __elfw2(LIBELFBITS,updatefile) (Elf *elf, int change_bo, size_t shnum)
if (elf->state.ELFW(elf,LIBELFBITS).phdr == NULL)
last_offset = elf_typesize (LIBELFBITS, ELF_T_EHDR, 1);
else
- last_offset = (ehdr->e_phoff
- + sizeof (ElfW2(LIBELFBITS,Phdr)) * ehdr->e_phnum);
+ last_offset = (ehdr->e_phoff + sizeof (ElfW2(LIBELFBITS,Phdr)) * phnum);
/* Write all the sections. Well, only those which are modified. */
if (shnum > 0)