mirror of
https://github.com/apache/nuttx.git
synced 2026-06-06 00:14:22 +08:00
A little more ELF loader logic
git-svn-id: svn://svn.code.sf.net/p/nuttx/code/trunk@5256 42af7a65-404d-4744-a932-0658087f49c3
This commit is contained in:
@@ -107,8 +107,9 @@ int elf_init(FAR const char *filename, FAR struct elf_loadinfo_s *loadinfo)
|
|||||||
loadinfo->filfd = open(filename, O_RDONLY);
|
loadinfo->filfd = open(filename, O_RDONLY);
|
||||||
if (loadinfo->filfd < 0)
|
if (loadinfo->filfd < 0)
|
||||||
{
|
{
|
||||||
bdbg("Failed to open ELF binary %s: %d\n", filename, ret);
|
int errval = errno;
|
||||||
return -errno;
|
bdbg("Failed to open ELF binary %s: %d\n", filename, errval);
|
||||||
|
return -errval;
|
||||||
}
|
}
|
||||||
|
|
||||||
/* Read the ELF ehdr from offset 0 */
|
/* Read the ELF ehdr from offset 0 */
|
||||||
|
|||||||
+44
-67
@@ -115,69 +115,6 @@ static inline int elf_filelen(FAR struct elf_loadinfo_s *loadinfo)
|
|||||||
return OK;
|
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
|
* 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 */
|
/* 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)
|
if (ret < 0)
|
||||||
{
|
{
|
||||||
bdbg("Failed to read section header table: %d\n", ret);
|
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 */
|
/* 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)
|
if (ret < 0)
|
||||||
{
|
{
|
||||||
bdbg("Failed to read section %d: %d\n", i, ret);
|
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)
|
int elf_load(FAR struct elf_loadinfo_s *loadinfo)
|
||||||
{
|
{
|
||||||
# warning "Missing logic"
|
int ret;
|
||||||
return -ENOSYS;
|
|
||||||
|
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;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
+21
-24
@@ -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 */
|
ssize_t nbytes; /* Number of bytes read */
|
||||||
off_t rpos; /* Position returned by lseek */
|
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
|
/* Loop until all of the requested data has been read. */
|
||||||
* data is saved.
|
|
||||||
*/
|
|
||||||
|
|
||||||
bytesread = 0;
|
while (readsize > 0)
|
||||||
bufptr = buffer;
|
|
||||||
bytesleft = readsize;
|
|
||||||
do
|
|
||||||
{
|
{
|
||||||
|
/* Seek to the next read position */
|
||||||
|
|
||||||
rpos = lseek(loadinfo->filfd, offset, SEEK_SET);
|
rpos = lseek(loadinfo->filfd, offset, SEEK_SET);
|
||||||
if (rpos != offset)
|
if (rpos != offset)
|
||||||
{
|
{
|
||||||
bdbg("Failed to seek to position %d: %d\n", offset, errno);
|
int errval = errno;
|
||||||
return -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 */
|
/* 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 (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);
|
bdbg("Read of .data failed: %d\n", errval);
|
||||||
return -errno;
|
return -errval;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
else if (nbytes == 0)
|
else if (nbytes == 0)
|
||||||
@@ -150,15 +150,12 @@ int elf_read(struct elf_loadinfo_s *loadinfo, char *buffer, int readsize, int of
|
|||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
bytesread += nbytes;
|
readsize -= nbytes;
|
||||||
bytesleft -= nbytes;
|
buffer += nbytes;
|
||||||
bufptr += nbytes;
|
offset += nbytes;
|
||||||
offset += nbytes;
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
while (bytesread < readsize);
|
|
||||||
|
|
||||||
elf_dumpreaddata(buffer, readsize);
|
elf_dumpreaddata(buffer, readsize);
|
||||||
return OK;
|
return OK;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -112,8 +112,9 @@ int nxflat_init(const char *filename, struct nxflat_loadinfo_s *loadinfo)
|
|||||||
loadinfo->filfd = open(filename, O_RDONLY);
|
loadinfo->filfd = open(filename, O_RDONLY);
|
||||||
if (loadinfo->filfd < 0)
|
if (loadinfo->filfd < 0)
|
||||||
{
|
{
|
||||||
bdbg("Failed to open NXFLAT binary %s: %d\n", filename, ret);
|
int errval = errno;
|
||||||
return -errno;
|
bdbg("Failed to open NXFLAT binary %s: %d\n", filename, errval);
|
||||||
|
return -errval;
|
||||||
}
|
}
|
||||||
|
|
||||||
/* Read the NXFLAT header from offset 0 */
|
/* Read the NXFLAT header from offset 0 */
|
||||||
|
|||||||
@@ -129,8 +129,9 @@ int nxflat_read(struct nxflat_loadinfo_s *loadinfo, char *buffer, int readsize,
|
|||||||
rpos = lseek(loadinfo->filfd, offset, SEEK_SET);
|
rpos = lseek(loadinfo->filfd, offset, SEEK_SET);
|
||||||
if (rpos != offset)
|
if (rpos != offset)
|
||||||
{
|
{
|
||||||
bdbg("Failed to seek to position %d: %d\n", offset, errno);
|
int errval = errno;
|
||||||
return -errno;
|
bdbg("Failed to seek to position %d: %d\n", offset, errval);
|
||||||
|
return -errval;
|
||||||
}
|
}
|
||||||
|
|
||||||
/* Read the file data at offset into the user buffer */
|
/* 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);
|
nbytes = read(loadinfo->filfd, bufptr, bytesleft);
|
||||||
if (nbytes < 0)
|
if (nbytes < 0)
|
||||||
{
|
{
|
||||||
if (errno != EINTR)
|
int errval = errno;
|
||||||
|
if (errval != EINTR)
|
||||||
{
|
{
|
||||||
bdbg("Read of .data failed: %d\n", errno);
|
bdbg("Read of .data failed: %d\n", errval);
|
||||||
return -errno;
|
return -errval;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
else if (nbytes == 0)
|
else if (nbytes == 0)
|
||||||
|
|||||||
@@ -165,8 +165,8 @@ EXTERN int elf_load(FAR struct elf_loadinfo_s *loadinfo);
|
|||||||
*
|
*
|
||||||
****************************************************************************/
|
****************************************************************************/
|
||||||
|
|
||||||
EXTERN int elf_read(FAR struct elf_loadinfo_s *loadinfo, FAR char *buffer,
|
EXTER int elf_read(FAR struct elf_loadinfo_s *loadinfo, FAR uint8_t *buffer,
|
||||||
FAR int readsize, int offset);
|
size_t readsize, off_t offset);
|
||||||
|
|
||||||
/****************************************************************************
|
/****************************************************************************
|
||||||
* Name: elf_bind
|
* Name: elf_bind
|
||||||
|
|||||||
Reference in New Issue
Block a user