diff options
Diffstat (limited to 'src/libdwfl/open.c')
-rw-r--r-- | src/libdwfl/open.c | 182 |
1 files changed, 0 insertions, 182 deletions
diff --git a/src/libdwfl/open.c b/src/libdwfl/open.c deleted file mode 100644 index 40aac388..00000000 --- a/src/libdwfl/open.c +++ /dev/null @@ -1,182 +0,0 @@ -/* Decompression support for libdwfl: zlib (gzip) and/or bzlib (bzip2). - Copyright (C) 2009 Red Hat, Inc. - This file is part of elfutils. - - This file is free software; you can redistribute it and/or modify - it under the terms of either - - * the GNU Lesser General Public License as published by the Free - Software Foundation; either version 3 of the License, or (at - your option) any later version - - or - - * the GNU General Public License as published by the Free - Software Foundation; either version 2 of the License, or (at - your option) any later version - - or both in parallel, as here. - - elfutils is distributed in the hope that it will be useful, but - WITHOUT ANY WARRANTY; without even the implied warranty of - MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU - General Public License for more details. - - You should have received copies of the GNU General Public License and - the GNU Lesser General Public License along with this program. If - not, see <http://www.gnu.org/licenses/>. */ - -#include "../libelf/libelfP.h" -#undef _ -#include "libdwflP.h" - -#include <unistd.h> - -#if !USE_ZLIB -# define __libdw_gunzip(...) DWFL_E_BADELF -#endif - -#if !USE_BZLIB -# define __libdw_bunzip2(...) DWFL_E_BADELF -#endif - -#if !USE_LZMA -# define __libdw_unlzma(...) DWFL_E_BADELF -#endif - -/* Consumes and replaces *ELF only on success. */ -static Dwfl_Error -decompress (int fd __attribute__ ((unused)), Elf **elf) -{ - Dwfl_Error error = DWFL_E_BADELF; - void *buffer = NULL; - size_t size = 0; - -#if USE_ZLIB || USE_BZLIB || USE_LZMA - const off64_t offset = (*elf)->start_offset; - void *const mapped = ((*elf)->map_address == NULL ? NULL - : (*elf)->map_address + offset); - const size_t mapped_size = (*elf)->maximum_size; - if (mapped_size == 0) - return error; - - error = __libdw_gunzip (fd, offset, mapped, mapped_size, &buffer, &size); - if (error == DWFL_E_BADELF) - error = __libdw_bunzip2 (fd, offset, mapped, mapped_size, &buffer, &size); - if (error == DWFL_E_BADELF) - error = __libdw_unlzma (fd, offset, mapped, mapped_size, &buffer, &size); -#endif - - if (error == DWFL_E_NOERROR) - { - if (unlikely (size == 0)) - { - error = DWFL_E_BADELF; - free (buffer); - } - else - { - Elf *memelf = elf_memory (buffer, size); - if (memelf == NULL) - { - error = DWFL_E_LIBELF; - free (buffer); - } - else - { - memelf->flags |= ELF_F_MALLOCED; - elf_end (*elf); - *elf = memelf; - } - } - } - else - free (buffer); - - return error; -} - -static Dwfl_Error -what_kind (int fd, Elf **elfp, Elf_Kind *kind, bool *close_fd) -{ - Dwfl_Error error = DWFL_E_NOERROR; - *kind = elf_kind (*elfp); - if (unlikely (*kind == ELF_K_NONE)) - { - if (unlikely (*elfp == NULL)) - error = DWFL_E_LIBELF; - else - { - error = decompress (fd, elfp); - if (error == DWFL_E_NOERROR) - { - *close_fd = true; - *kind = elf_kind (*elfp); - } - } - } - return error; -} - -Dwfl_Error internal_function -__libdw_open_file (int *fdp, Elf **elfp, bool close_on_fail, bool archive_ok) -{ - bool close_fd = false; - - Elf *elf = elf_begin (*fdp, ELF_C_READ_MMAP_PRIVATE, NULL); - - Elf_Kind kind; - Dwfl_Error error = what_kind (*fdp, &elf, &kind, &close_fd); - if (error == DWFL_E_BADELF) - { - /* It's not an ELF file or a compressed file. - See if it's an image with a header preceding the real file. */ - - off64_t offset = elf->start_offset; - error = __libdw_image_header (*fdp, &offset, - (elf->map_address == NULL ? NULL - : elf->map_address + offset), - elf->maximum_size); - if (error == DWFL_E_NOERROR) - { - /* Pure evil. libelf needs some better interfaces. */ - elf->kind = ELF_K_AR; - elf->state.ar.elf_ar_hdr.ar_name = "libdwfl is faking you out"; - elf->state.ar.elf_ar_hdr.ar_size = elf->maximum_size - offset; - elf->state.ar.offset = offset - sizeof (struct ar_hdr); - Elf *subelf = elf_begin (-1, ELF_C_READ_MMAP_PRIVATE, elf); - elf->kind = ELF_K_NONE; - if (unlikely (subelf == NULL)) - error = DWFL_E_LIBELF; - else - { - subelf->parent = NULL; - subelf->flags |= elf->flags & (ELF_F_MMAPPED | ELF_F_MALLOCED); - elf->flags &= ~(ELF_F_MMAPPED | ELF_F_MALLOCED); - elf_end (elf); - elf = subelf; - error = what_kind (*fdp, &elf, &kind, &close_fd); - } - } - } - - if (error == DWFL_E_NOERROR - && kind != ELF_K_ELF - && !(archive_ok && kind == ELF_K_AR)) - error = DWFL_E_BADELF; - - if (error != DWFL_E_NOERROR) - { - elf_end (elf); - elf = NULL; - } - - if (error == DWFL_E_NOERROR ? close_fd : close_on_fail) - { - close (*fdp); - *fdp = -1; - } - - *elfp = elf; - return error; -} |