diff options
author | Ulrich Drepper <drepper@redhat.com> | 2005-08-13 22:29:47 +0000 |
---|---|---|
committer | Ulrich Drepper <drepper@redhat.com> | 2005-08-13 22:29:47 +0000 |
commit | 1bb18a3a9680af49dbf1056098bae8cf4624b565 (patch) | |
tree | 27c051a4829625d7c47482bd79cafee03fc451a7 /libelf/elf_begin.c | |
parent | cc1ebdb0ed624f418102921c47f4a11181e8e99c (diff) | |
download | elfutils-1bb18a3a9680af49dbf1056098bae8cf4624b565.tar.gz |
Optimize memory handling. Copy pread if possible. Handle EINTR.
Diffstat (limited to 'libelf/elf_begin.c')
-rw-r--r-- | libelf/elf_begin.c | 42 |
1 files changed, 29 insertions, 13 deletions
diff --git a/libelf/elf_begin.c b/libelf/elf_begin.c index bed3f550..56c7a481 100644 --- a/libelf/elf_begin.c +++ b/libelf/elf_begin.c @@ -220,6 +220,7 @@ file_read_elf (int fildes, void *map_address, off_t offset, size_t maxsize, { /* We only read the ELF header now. */ unsigned char *e_ident; + unsigned char e_ident_mem[EI_NIDENT]; size_t scncnt; Elf *elf; @@ -229,9 +230,10 @@ file_read_elf (int fildes, void *map_address, off_t offset, size_t maxsize, e_ident = (unsigned char *) map_address + offset; else { - e_ident = (unsigned char *) alloca (EI_NIDENT); + e_ident = e_ident_mem; - if (pread (fildes, e_ident, EI_NIDENT, offset) != EI_NIDENT) + if (TEMP_FAILURE_RETRY (pread (fildes, e_ident, EI_NIDENT, offset)) + != EI_NIDENT) { __libelf_seterrno (ELF_E_READ_ERROR); return NULL; @@ -312,14 +314,21 @@ file_read_elf (int fildes, void *map_address, off_t offset, size_t maxsize, } else { - /* Read the data. */ - if (pread (elf->fildes, &elf->state.elf32.ehdr_mem, - sizeof (Elf32_Ehdr), offset) != sizeof (Elf32_Ehdr)) - { - /* We must be able to read the ELF header. */ - __libelf_seterrno (ELF_E_INVALID_FILE); - return NULL; - } + if (likely (map_address != NULL)) + /* Copy the data. */ + memcpy (&elf->state.elf32.ehdr_mem, + (char *) map_address + offset, sizeof (Elf32_Ehdr)); + else + /* Read the data. */ + if (TEMP_FAILURE_RETRY (pread (elf->fildes, + &elf->state.elf32.ehdr_mem, + sizeof (Elf32_Ehdr), offset)) + != sizeof (Elf32_Ehdr)) + { + /* We must be able to read the ELF header. */ + __libelf_seterrno (ELF_E_INVALID_FILE); + return NULL; + } if (e_ident[EI_DATA] != MY_ELFDATA) { @@ -397,9 +406,16 @@ file_read_elf (int fildes, void *map_address, off_t offset, size_t maxsize, } else { - /* Read the data. */ - if (pread (elf->fildes, &elf->state.elf64.ehdr_mem, - sizeof (Elf64_Ehdr), offset) != sizeof (Elf64_Ehdr)) + if (likely (map_address != NULL)) + /* Copy the data. */ + memcpy (&elf->state.elf64.ehdr_mem, + (char *) map_address + offset, sizeof (Elf64_Ehdr)); + else + /* Read the data. */ + if (TEMP_FAILURE_RETRY (pread (elf->fildes, + &elf->state.elf64.ehdr_mem, + sizeof (Elf64_Ehdr), offset)) + != sizeof (Elf64_Ehdr)) { /* We must be able to read the ELF header. */ __libelf_seterrno (ELF_E_INVALID_FILE); |