summaryrefslogtreecommitdiff
path: root/nuttx/binfmt
diff options
context:
space:
mode:
authorpatacongo <patacongo@42af7a65-404d-4744-a932-0658087f49c3>2012-10-25 03:13:11 +0000
committerpatacongo <patacongo@42af7a65-404d-4744-a932-0658087f49c3>2012-10-25 03:13:11 +0000
commitcb3be8c6e6920198440d9654f05b122853724868 (patch)
treea018506cf7763c9e12ab56b1b81d9677b97264f6 /nuttx/binfmt
parent087d2899c1a9f80de11b569d57862c7be8a92974 (diff)
downloadpx4-nuttx-cb3be8c6e6920198440d9654f05b122853724868.tar.gz
px4-nuttx-cb3be8c6e6920198440d9654f05b122853724868.tar.bz2
px4-nuttx-cb3be8c6e6920198440d9654f05b122853724868.zip
A little more ELF loader logic
git-svn-id: svn://svn.code.sf.net/p/nuttx/code/trunk@5256 42af7a65-404d-4744-a932-0658087f49c3
Diffstat (limited to 'nuttx/binfmt')
-rw-r--r--nuttx/binfmt/libelf/libelf_init.c5
-rw-r--r--nuttx/binfmt/libelf/libelf_load.c111
-rw-r--r--nuttx/binfmt/libelf/libelf_read.c45
-rw-r--r--nuttx/binfmt/libnxflat/libnxflat_init.c5
-rw-r--r--nuttx/binfmt/libnxflat/libnxflat_read.c12
5 files changed, 78 insertions, 100 deletions
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
@@ -116,69 +116,6 @@ static inline int elf_filelen(FAR struct elf_loadinfo_s *loadinfo)
}
/****************************************************************************
- * 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
*
* Description:
@@ -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)