From a91b6552cdb1b147461b75128576012192d9e933 Mon Sep 17 00:00:00 2001 From: patacongo Date: Thu, 25 Oct 2012 03:13:11 +0000 Subject: A little more ELF loader logic git-svn-id: http://svn.code.sf.net/p/nuttx/code/trunk@5256 42af7a65-404d-4744-a932-0658087f49c3 --- nuttx/binfmt/libelf/libelf_init.c | 5 +- nuttx/binfmt/libelf/libelf_load.c | 111 +++++++++++++------------------- nuttx/binfmt/libelf/libelf_read.c | 45 ++++++------- nuttx/binfmt/libnxflat/libnxflat_init.c | 5 +- nuttx/binfmt/libnxflat/libnxflat_read.c | 12 ++-- 5 files changed, 78 insertions(+), 100 deletions(-) (limited to 'nuttx/binfmt') diff --git a/nuttx/binfmt/libelf/libelf_init.c b/nuttx/binfmt/libelf/libelf_init.c index b024f2d19..cf62666b9 100644 --- a/nuttx/binfmt/libelf/libelf_init.c +++ b/nuttx/binfmt/libelf/libelf_init.c @@ -107,8 +107,9 @@ int elf_init(FAR const char *filename, FAR struct elf_loadinfo_s *loadinfo) loadinfo->filfd = open(filename, O_RDONLY); if (loadinfo->filfd < 0) { - bdbg("Failed to open ELF binary %s: %d\n", filename, ret); - return -errno; + int errval = errno; + bdbg("Failed to open ELF binary %s: %d\n", filename, errval); + return -errval; } /* Read the ELF ehdr from offset 0 */ diff --git a/nuttx/binfmt/libelf/libelf_load.c b/nuttx/binfmt/libelf/libelf_load.c index 98e9abf38..c30c109ce 100644 --- a/nuttx/binfmt/libelf/libelf_load.c +++ b/nuttx/binfmt/libelf/libelf_load.c @@ -115,69 +115,6 @@ static inline int elf_filelen(FAR struct elf_loadinfo_s *loadinfo) return OK; } -/**************************************************************************** - * Name: elf_readfile - * - * Description: - * Allocate memory for the file and read the section data into the - * allocated memory. - * - * Returned Value: - * 0 (OK) is returned on success and a negated errno is returned on - * failure. - * - ****************************************************************************/ - -static int elf_readfile(FAR struct elf_loadinfo_s *loadinfo, FAR void *buffer, - off_t offset, size_t nbytes) -{ - FAR uint8_t *buffer; - ssize_t bytesread; - off_t result; - - /* Seek to the start of the section header table */ - - result = lseek(loadinfo->filfd, offset, SEEK_SET); - if (result == (off_t)-1) - { - int errval = errno; - bdbg("Seel to %ld failed: %d\n", (long)offset, errval); - return -errval; - } - - /* Now load the file data into memory */ - - buffer = (FAR uint8_t *)loadinfo->shdrs; - while (shdrsize > 0) - { - bytesread = read(loadinfo->filfd, buffer, shdrsize); - if (bytes < 0) - { - int errval = errno; - - /* EINTR just means that we received a signal */ - - if (errno != EINTR) - { - bdbg("read() failed: %d\n", errval); - return -errval; - } - } - else if (bytes == 0) - { - bdbg("Unexpected end of file\n"); - return -ENODATA; - } - else - { - buffer += bytesread; - shdrsize -= bytesread; - } - } - - return OK; -} - /**************************************************************************** * Name: elf_loadshdrs * @@ -225,7 +162,7 @@ static inline int elf_loadshdrs(FAR struct elf_loadinfo_s *loadinfo) /* Read the section header table into memory */ - ret = elf_readfile(loadinfo, loadinfo->shdrs, loadinfo->e_shoff, shdrsize); + ret = elf_read(loadinfo, loadinfo->shdrs, shdrsize, loadinfo->e_shoff); if (ret < 0) { bdbg("Failed to read section header table: %d\n", ret); @@ -330,7 +267,7 @@ static inline int elf_loadfile(FAR struct load_info *loadinfo) { /* Read the section data from sh_offset to dest */ - ret = elf_readfile(loadinfo, dest, shdr->sh_offset, shdr->sh_size); + ret = elf_read(loadinfo, dest, shdr->sh_size, shdr->sh_offset); if (ret < 0) { bdbg("Failed to read section %d: %d\n", i, ret); @@ -375,7 +312,47 @@ errout_with_alloc: int elf_load(FAR struct elf_loadinfo_s *loadinfo) { -# warning "Missing logic" - return -ENOSYS; + int ret; + + bvdbg("loadinfo: %p\n", loadinfo); + DEBUGASSERT(loadinfo && loadinfo->filfd >= 0); + + /* Get the length of the file. */ + + ret = elf_filelen(loadinfo); + { + return ret; + } + + /* Load section headers into memory */ + + ret = elf_loadshdrs(loadinfo); + if (ret < 0) + { + return ret; + } + + /* Determine total size to allocate */ + + elf_allocsize(loadinfo); + + /* Allocate memory and load sections into memory */ + + ret = elf_loadfile(loadinfo); + if (ret < 0) + { + goto errout_with_shdrs; + } + + return OK; + + /* Error exits */ + +errout_with_alloc: + kfree(loadinfo->alloc); +errout_with_shdrs: + kfree(loadinfo->shdrs); +errout: + return ret; } diff --git a/nuttx/binfmt/libelf/libelf_read.c b/nuttx/binfmt/libelf/libelf_read.c index 35b9090f9..0b01cf096 100644 --- a/nuttx/binfmt/libelf/libelf_read.c +++ b/nuttx/binfmt/libelf/libelf_read.c @@ -106,41 +106,41 @@ static inline void elf_dumpreaddata(char *buffer, int buflen) * ****************************************************************************/ -int elf_read(struct elf_loadinfo_s *loadinfo, char *buffer, int readsize, int offset) +int elf_read(FAR struct elf_loadinfo_s *loadinfo, FAR uint8_t *buffer, + size_t readsize, off_t offset) { ssize_t nbytes; /* Number of bytes read */ off_t rpos; /* Position returned by lseek */ - char *bufptr; /* Next buffer location to read into */ - int bytesleft; /* Number of bytes of .data left to read */ - int bytesread; /* Total number of bytes read */ - bvdbg("Read %d bytes from offset %d\n", readsize, offset); + bvdbg("Read %ld bytes from offset %ld\n", (long)readsize, (long)offset); - /* Seek to the position in the object file where the initialized - * data is saved. - */ + /* Loop until all of the requested data has been read. */ - bytesread = 0; - bufptr = buffer; - bytesleft = readsize; - do + while (readsize > 0) { + /* Seek to the next read position */ + rpos = lseek(loadinfo->filfd, offset, SEEK_SET); if (rpos != offset) { - bdbg("Failed to seek to position %d: %d\n", offset, errno); - return -errno; + int errval = errno; + bdbg("Failed to seek to position %ld: %d\n", (long)offset, errval); + return -errval; } /* Read the file data at offset into the user buffer */ - nbytes = read(loadinfo->filfd, bufptr, bytesleft); + nbytes = read(loadinfo->filfd, buffer, readsize); if (nbytes < 0) { - if (errno != EINTR) + int errval = errno; + + /* EINTR just means that we received a signal */ + + if (errval != EINTR) { - bdbg("Read of .data failed: %d\n", errno); - return -errno; + bdbg("Read of .data failed: %d\n", errval); + return -errval; } } else if (nbytes == 0) @@ -150,15 +150,12 @@ int elf_read(struct elf_loadinfo_s *loadinfo, char *buffer, int readsize, int of } else { - bytesread += nbytes; - bytesleft -= nbytes; - bufptr += nbytes; - offset += nbytes; + readsize -= nbytes; + buffer += nbytes; + offset += nbytes; } } - while (bytesread < readsize); elf_dumpreaddata(buffer, readsize); return OK; } - diff --git a/nuttx/binfmt/libnxflat/libnxflat_init.c b/nuttx/binfmt/libnxflat/libnxflat_init.c index 20f06c6ab..b7cac8d86 100644 --- a/nuttx/binfmt/libnxflat/libnxflat_init.c +++ b/nuttx/binfmt/libnxflat/libnxflat_init.c @@ -112,8 +112,9 @@ int nxflat_init(const char *filename, struct nxflat_loadinfo_s *loadinfo) loadinfo->filfd = open(filename, O_RDONLY); if (loadinfo->filfd < 0) { - bdbg("Failed to open NXFLAT binary %s: %d\n", filename, ret); - return -errno; + int errval = errno; + bdbg("Failed to open NXFLAT binary %s: %d\n", filename, errval); + return -errval; } /* Read the NXFLAT header from offset 0 */ diff --git a/nuttx/binfmt/libnxflat/libnxflat_read.c b/nuttx/binfmt/libnxflat/libnxflat_read.c index da05bc399..8deeb0805 100644 --- a/nuttx/binfmt/libnxflat/libnxflat_read.c +++ b/nuttx/binfmt/libnxflat/libnxflat_read.c @@ -129,8 +129,9 @@ int nxflat_read(struct nxflat_loadinfo_s *loadinfo, char *buffer, int readsize, rpos = lseek(loadinfo->filfd, offset, SEEK_SET); if (rpos != offset) { - bdbg("Failed to seek to position %d: %d\n", offset, errno); - return -errno; + int errval = errno; + bdbg("Failed to seek to position %d: %d\n", offset, errval); + return -errval; } /* Read the file data at offset into the user buffer */ @@ -138,10 +139,11 @@ int nxflat_read(struct nxflat_loadinfo_s *loadinfo, char *buffer, int readsize, nbytes = read(loadinfo->filfd, bufptr, bytesleft); if (nbytes < 0) { - if (errno != EINTR) + int errval = errno; + if (errval != EINTR) { - bdbg("Read of .data failed: %d\n", errno); - return -errno; + bdbg("Read of .data failed: %d\n", errval); + return -errval; } } else if (nbytes == 0) -- cgit v1.2.3