diff options
Diffstat (limited to 'rtemstoolkit/elftoolchain/libelf/elf_begin.c')
-rw-r--r-- | rtemstoolkit/elftoolchain/libelf/elf_begin.c | 189 |
1 files changed, 2 insertions, 187 deletions
diff --git a/rtemstoolkit/elftoolchain/libelf/elf_begin.c b/rtemstoolkit/elftoolchain/libelf/elf_begin.c index a6c9e4a..9f4f237 100644 --- a/rtemstoolkit/elftoolchain/libelf/elf_begin.c +++ b/rtemstoolkit/elftoolchain/libelf/elf_begin.c @@ -24,196 +24,11 @@ * SUCH DAMAGE. */ -#include <sys/cdefs.h> - -#include <sys/types.h> -#include <sys/errno.h> -#include <sys/mman.h> -#include <sys/stat.h> - -#include <ar.h> -#include <assert.h> -#include <ctype.h> -#include <errno.h> #include <libelf.h> -#include <stdlib.h> -#include <unistd.h> #include "_libelf.h" -LIBELF_VCSID("$Id: elf_begin.c 1923 2011-09-23 09:01:13Z jkoshy $"); - -#define _LIBELF_INITSIZE (64*1024) - -/* - * Read from a device file, pipe or socket. - */ -static void * -_libelf_read_special_file(int fd, size_t *fsz) -{ - ssize_t readsz; - size_t bufsz, datasz; - unsigned char *buf, *t; - - datasz = 0; - readsz = 0; - bufsz = _LIBELF_INITSIZE; - if ((buf = malloc(bufsz)) == NULL) - goto resourceerror; - - /* - * Read data from the file descriptor till we reach EOF, or - * till an error is encountered. - */ - do { - /* Check if we need to expand the data buffer. */ - if (datasz == bufsz) { - bufsz *= 2; - if ((t = realloc(buf, bufsz)) == NULL) - goto resourceerror; - buf = t; - } - - do { - readsz = bufsz - datasz; - t = buf + datasz; - if ((readsz = read(fd, t, readsz)) <= 0) - break; - datasz += readsz; - } while (datasz < bufsz); - - } while (readsz > 0); - - if (readsz < 0) { - LIBELF_SET_ERROR(IO, errno); - goto error; - } - - assert(readsz == 0); - - /* - * Free up extra buffer space. - */ - if (bufsz > datasz) { - if (datasz > 0) { - if ((t = realloc(buf, datasz)) == NULL) - goto resourceerror; - buf = t; - } else { /* Zero bytes read. */ - LIBELF_SET_ERROR(ARGUMENT, 0); - free(buf); - buf = NULL; - } - } - - *fsz = datasz; - return (buf); - -resourceerror: - LIBELF_SET_ERROR(RESOURCE, 0); -error: - if (buf != NULL) - free(buf); - return (NULL); -} - - -static Elf * -_libelf_open_object(int fd, Elf_Cmd c) -{ - Elf *e; - void *m; - mode_t mode; - size_t fsize; - struct stat sb; - unsigned int flags; - - assert(c == ELF_C_READ || c == ELF_C_RDWR || c == ELF_C_WRITE); - - if (fstat(fd, &sb) < 0) { - LIBELF_SET_ERROR(IO, errno); - return (NULL); - } - - mode = sb.st_mode; - fsize = (size_t) sb.st_size; - - /* - * Reject unsupported file types. - */ - if (!S_ISREG(mode) && !S_ISCHR(mode) && !S_ISFIFO(mode) && - !S_ISSOCK(mode)) { - LIBELF_SET_ERROR(ARGUMENT, 0); - return (NULL); - } - - /* - * For ELF_C_WRITE mode, allocate and return a descriptor. - */ - if (c == ELF_C_WRITE) { - if ((e = _libelf_allocate_elf()) != NULL) { - _libelf_init_elf(e, ELF_K_ELF); - e->e_byteorder = LIBELF_PRIVATE(byteorder); - e->e_fd = fd; - e->e_cmd = c; - if (!S_ISREG(mode)) - e->e_flags |= LIBELF_F_SPECIAL_FILE; - } - - return (e); - } - - - /* - * ELF_C_READ and ELF_C_RDWR mode. - */ - m = NULL; - flags = 0; - if (S_ISREG(mode)) { - /* - * Always map regular files in with 'PROT_READ' - * permissions. - * - * For objects opened in ELF_C_RDWR mode, when - * elf_update(3) is called, we remove this mapping, - * write file data out using write(2), and map the new - * contents back. - */ - if ((m = mmap(NULL, fsize, PROT_READ, MAP_PRIVATE, fd, - (off_t) 0)) == MAP_FAILED) { - LIBELF_SET_ERROR(IO, errno); - return (NULL); - } - - flags = LIBELF_F_RAWFILE_MMAP; - } else if ((m = _libelf_read_special_file(fd, &fsize)) != NULL) - flags = LIBELF_F_RAWFILE_MALLOC | LIBELF_F_SPECIAL_FILE; - else - return (NULL); - - if ((e = elf_memory(m, fsize)) == NULL) { - assert((flags & LIBELF_F_RAWFILE_MALLOC) || - (flags & LIBELF_F_RAWFILE_MMAP)); - if (flags & LIBELF_F_RAWFILE_MMAP) - (void) munmap(m, fsize); - else - free(m); - return (NULL); - } - - /* ar(1) archives aren't supported in RDWR mode. */ - if (c == ELF_C_RDWR && e->e_kind == ELF_K_AR) { - (void) elf_end(e); - LIBELF_SET_ERROR(ARGUMENT, 0); - return (NULL); - } - - e->e_flags |= flags; - e->e_fd = fd; - e->e_cmd = c; - - return (e); -} +ELFTC_VCSID("$Id: elf_begin.c 2364 2011-12-28 17:55:25Z jkoshy $"); Elf * elf_begin(int fd, Elf_Cmd c, Elf *a) @@ -266,7 +81,7 @@ elf_begin(int fd, Elf_Cmd c, Elf *a) } if (a == NULL) - e = _libelf_open_object(fd, c); + e = _libelf_open_object(fd, c, 1); else if (a->e_kind == ELF_K_AR) e = _libelf_ar_open_member(a->e_fd, c, a); else |