mirror of
https://github.com/apache/nuttx.git
synced 2026-05-22 22:20:01 +08:00
New relocation types
git-svn-id: svn://svn.code.sf.net/p/nuttx/code/trunk@1925 42af7a65-404d-4744-a932-0658087f49c3
This commit is contained in:
@@ -40,6 +40,7 @@
|
||||
#include <nuttx/config.h>
|
||||
#include <sys/types.h>
|
||||
|
||||
#include <string.h>
|
||||
#include <nxflat.h>
|
||||
#include <errno.h>
|
||||
#include <assert.h>
|
||||
@@ -66,11 +67,243 @@
|
||||
****************************************************************************/
|
||||
|
||||
/****************************************************************************
|
||||
* Public Functions
|
||||
* Name: nxflat_bindrel32i
|
||||
*
|
||||
* Description:
|
||||
* Perform the NXFLAT_RELOC_TYPE_REL32I binding:
|
||||
*
|
||||
* Meaning: Object file contains a 32-bit offset into I-Space at the the offset.
|
||||
* Fixup: Add mapped I-Space address to the offset.
|
||||
*
|
||||
* Returned Value:
|
||||
* 0 (OK) is returned on success and a negated errno is returned on
|
||||
* failure.
|
||||
*
|
||||
****************************************************************************/
|
||||
|
||||
/***********************************************************************
|
||||
* Name: nxflat_bind
|
||||
static inline int nxflat_bindrel32i(FAR struct nxflat_loadinfo_s *loadinfo,
|
||||
uint32 offset)
|
||||
{
|
||||
uint32 *addr;
|
||||
|
||||
bvdbg("NXFLAT_RELOC_TYPE_REL32I Offset: %08x I-Space: %p\n",
|
||||
offset, loadinfo->ispace);
|
||||
|
||||
if (offset < loadinfo->dsize)
|
||||
{
|
||||
addr = (uint32*)(offset + loadinfo->dspace->region);
|
||||
bvdbg(" Before: %08x\n", *addr);
|
||||
*addr += (uint32)(loadinfo->ispace);
|
||||
bvdbg(" After: %08x\n", *addr);
|
||||
return OK;
|
||||
}
|
||||
else
|
||||
{
|
||||
bdbg("Offset: %08 does not lie in D-Space size: %08x\n",
|
||||
offset, loadinfo->dsize);
|
||||
return -EINVAL;
|
||||
}
|
||||
}
|
||||
|
||||
/****************************************************************************
|
||||
* Name: nxflat_bindrel32d
|
||||
*
|
||||
* Description:
|
||||
* Perform the NXFLAT_RELOC_TYPE_REL32D binding:
|
||||
*
|
||||
* Meaning: Object file contains a 32-bit offset into D-Space at the the offset.
|
||||
* Fixup: Add allocated D-Space address to the offset.
|
||||
*
|
||||
* Returned Value:
|
||||
* 0 (OK) is returned on success and a negated errno is returned on
|
||||
* failure.
|
||||
*
|
||||
****************************************************************************/
|
||||
|
||||
static inline int nxflat_bindrel32d(FAR struct nxflat_loadinfo_s *loadinfo,
|
||||
uint32 offset)
|
||||
{
|
||||
uint32 *addr;
|
||||
|
||||
bvdbg("NXFLAT_RELOC_TYPE_REL32D Offset: %08x D-Space: %p\n",
|
||||
offset, loadinfo->dspace->region);
|
||||
|
||||
if (offset < loadinfo->dsize)
|
||||
{
|
||||
addr = (uint32*)(offset + loadinfo->dspace->region);
|
||||
bvdbg(" Before: %08x\n", *addr);
|
||||
*addr += (uint32)(loadinfo->dspace->region);
|
||||
bvdbg(" After: %08x\n", *addr);
|
||||
return OK;
|
||||
}
|
||||
else
|
||||
{
|
||||
bdbg("Offset: %08 does not lie in D-Space size: %08x\n",
|
||||
offset, loadinfo->dsize);
|
||||
return -EINVAL;
|
||||
}
|
||||
}
|
||||
|
||||
/****************************************************************************
|
||||
* Name: nxflat_bindrel32id
|
||||
*
|
||||
* Description:
|
||||
* Perform the NXFLAT_RELOC_TYPE_REL32ID binding:
|
||||
*
|
||||
* Meaning: Object file contains a 32-bit offsetinto I-Space at the the
|
||||
* offset, but will be referenced as data
|
||||
* Fixup: Add mapped I-Space address - allocated D-Space address to the
|
||||
* offset.
|
||||
*
|
||||
* Returned Value:
|
||||
* 0 (OK) is returned on success and a negated errno is returned on
|
||||
* failure.
|
||||
*
|
||||
****************************************************************************/
|
||||
|
||||
static inline int nxflat_bindrel32id(FAR struct nxflat_loadinfo_s *loadinfo,
|
||||
uint32 offset)
|
||||
{
|
||||
uint32 *addr;
|
||||
|
||||
bvdbg("NXFLAT_RELOC_TYPE_REL32I Offset: %08x I-Space: %p D-Space: %p\n",
|
||||
offset, loadinfo->ispace, loadinfo->dspace->region);
|
||||
|
||||
if (offset < loadinfo->dsize)
|
||||
{
|
||||
addr = (uint32*)(offset + loadinfo->dspace->region);
|
||||
bvdbg(" Before: %08x\n", *addr);
|
||||
*addr += ((uint32)(loadinfo->ispace) - (uint32)(loadinfo->dspace->region));
|
||||
bvdbg(" After: %08x\n", *addr);
|
||||
return OK;
|
||||
}
|
||||
else
|
||||
{
|
||||
bdbg("Offset: %08 does not lie in D-Space size: %08x\n",
|
||||
offset, loadinfo->dsize);
|
||||
return -EINVAL;
|
||||
}
|
||||
}
|
||||
|
||||
/****************************************************************************
|
||||
* Name: nxflat_gotrelocs
|
||||
*
|
||||
* Description:
|
||||
* Bind all of the GOT relocations in the loaded module described by
|
||||
* 'loadinfo'
|
||||
*
|
||||
* Returned Value:
|
||||
* 0 (OK) is returned on success and a negated errno is returned on
|
||||
* failure.
|
||||
*
|
||||
****************************************************************************/
|
||||
|
||||
static inline int nxflat_gotrelocs(FAR struct nxflat_loadinfo_s *loadinfo)
|
||||
{
|
||||
FAR struct nxflat_reloc_s *relocs;
|
||||
FAR struct nxflat_reloc_s reloc;
|
||||
FAR struct nxflat_hdr_s *hdr;
|
||||
uint32 offset;
|
||||
uint16 nrelocs;
|
||||
int ret;
|
||||
int result;
|
||||
int i;
|
||||
|
||||
/* The NXFLAT header is the first thing at the beginning of the ISpace. */
|
||||
|
||||
hdr = (FAR struct nxflat_hdr_s*)loadinfo->ispace;
|
||||
|
||||
/* From this, we can get the offset to the list of relocation entries */
|
||||
|
||||
offset = ntohl(hdr->h_relocstart);
|
||||
nrelocs = ntohs(hdr->h_reloccount);
|
||||
|
||||
/* The value of the relocation list that we get from the header is a
|
||||
* file offset. We will have to convert this to an offset into the
|
||||
* DSpace segment to get the pointer to the beginning of the relocation
|
||||
* list.
|
||||
*/
|
||||
|
||||
DEBUGASSERT(offset >= loadinfo->isize && offset < (loadinfo->isize + loadinfo->dsize));
|
||||
relocs = (FAR struct nxflat_reloc_s*)(offset - loadinfo->isize + loadinfo->dspace->region);
|
||||
|
||||
/* Now, traverse the relocation list of imported symbols and attempt to bind
|
||||
* each GOT relocation (imported symbols will be handled elsewhere).
|
||||
*/
|
||||
|
||||
ret = OK; /* Assume success */
|
||||
for (i = 0; i < nrelocs; i++)
|
||||
{
|
||||
/* Handle the relocation by the relocation type */
|
||||
|
||||
reloc = *relocs++;
|
||||
result = OK;
|
||||
switch (NXFLAT_RELOC_TYPE(reloc.r_info))
|
||||
{
|
||||
|
||||
/* NXFLAT_RELOC_TYPE_REL32I Meaning: Object file contains a 32-bit offset
|
||||
* into I-Space at the the offset.
|
||||
* Fixup: Add mapped I-Space address to the offset.
|
||||
*/
|
||||
|
||||
case NXFLAT_RELOC_TYPE_REL32I:
|
||||
{
|
||||
result = nxflat_bindrel32i(loadinfo, NXFLAT_RELOC_OFFSET(reloc.r_info));
|
||||
}
|
||||
break;
|
||||
|
||||
/* NXFLAT_RELOC_TYPE_REL32D Meaning: Object file contains a 32-bit offset
|
||||
* into D-Space at the the offset.
|
||||
* Fixup: Add allocated D-Space address to the
|
||||
* offset.
|
||||
*/
|
||||
|
||||
case NXFLAT_RELOC_TYPE_REL32D:
|
||||
{
|
||||
result = nxflat_bindrel32d(loadinfo, NXFLAT_RELOC_OFFSET(reloc.r_info));
|
||||
}
|
||||
break;
|
||||
|
||||
/* NXFLAT_RELOC_TYPE_REL32ID Meaning: Object file contains a 32-bit offset
|
||||
* into I-Space at the the offset, but will
|
||||
* be referenced as data
|
||||
* Fixup: Add mapped I-Space address - allocated
|
||||
* D-Space address to the offset.
|
||||
*/
|
||||
|
||||
case NXFLAT_RELOC_TYPE_REL32ID:
|
||||
{
|
||||
result = nxflat_bindrel32id(loadinfo, NXFLAT_RELOC_OFFSET(reloc.r_info));
|
||||
}
|
||||
break;
|
||||
|
||||
/* NXFLAT_RELOC_TYPE_ABS32 Meaning: Offset refers to a struct nxflat_import_s
|
||||
* describing a function pointer to be
|
||||
* imported.
|
||||
* Fixup: Provide the absolute function address
|
||||
* in the struct nxflat_import_s instance.
|
||||
*/
|
||||
|
||||
case NXFLAT_RELOC_TYPE_ABS32:
|
||||
{
|
||||
/* These will be handled together in nxflat_bindimports */
|
||||
}
|
||||
break;
|
||||
}
|
||||
|
||||
/* Check for failures */
|
||||
|
||||
if (result < 0 && ret == OK)
|
||||
{
|
||||
ret = result;
|
||||
}
|
||||
}
|
||||
|
||||
return ret;
|
||||
}
|
||||
|
||||
/****************************************************************************
|
||||
* Name: nxflat_bindimports
|
||||
*
|
||||
* Description:
|
||||
* Bind the imported symbol names in the loaded module described by
|
||||
@@ -80,10 +313,11 @@
|
||||
* 0 (OK) is returned on success and a negated errno is returned on
|
||||
* failure.
|
||||
*
|
||||
***********************************************************************/
|
||||
****************************************************************************/
|
||||
|
||||
int nxflat_bind(FAR struct nxflat_loadinfo_s *loadinfo,
|
||||
FAR const struct symtab_s *exports, int nexports)
|
||||
static inline int nxflat_bindimports(FAR struct nxflat_loadinfo_s *loadinfo,
|
||||
FAR const struct symtab_s *exports,
|
||||
int nexports)
|
||||
{
|
||||
FAR struct nxflat_import_s *imports;
|
||||
FAR struct nxflat_hdr_s *hdr;
|
||||
@@ -94,9 +328,7 @@ int nxflat_bind(FAR struct nxflat_loadinfo_s *loadinfo,
|
||||
uint16 nimports;
|
||||
int i;
|
||||
|
||||
/* Get the ISpace load address of the module. The NXFLAT header is the
|
||||
* first thing at the beginning of the ISpace.
|
||||
*/
|
||||
/* The NXFLAT header is the first thing at the beginning of the ISpace. */
|
||||
|
||||
hdr = (FAR struct nxflat_hdr_s*)loadinfo->ispace;
|
||||
|
||||
@@ -125,9 +357,9 @@ int nxflat_bind(FAR struct nxflat_loadinfo_s *loadinfo,
|
||||
offset < loadinfo->isize + loadinfo->dsize);
|
||||
|
||||
imports = (struct nxflat_import_s*)
|
||||
(offset - loadinfo->isize + loadinfo->dspace);
|
||||
(offset - loadinfo->isize + loadinfo->dspace->region);
|
||||
|
||||
/* Now, search the list of imported symbols and attempt to bind
|
||||
/* Now, traverse the list of imported symbols and attempt to bind
|
||||
* each symbol to the value exported by from the exported symbol
|
||||
* table.
|
||||
*/
|
||||
@@ -170,3 +402,50 @@ int nxflat_bind(FAR struct nxflat_loadinfo_s *loadinfo,
|
||||
return OK;
|
||||
}
|
||||
|
||||
/****************************************************************************
|
||||
* Public Functions
|
||||
****************************************************************************/
|
||||
|
||||
/****************************************************************************
|
||||
* Name: nxflat_bind
|
||||
*
|
||||
* Description:
|
||||
* Bind the imported symbol names in the loaded module described by
|
||||
* 'loadinfo' using the exported symbol values provided by 'symtab'.
|
||||
* After binding the module, clear the BSS region (which held the relocation
|
||||
* data) in preparation for execution.
|
||||
*
|
||||
* Returned Value:
|
||||
* 0 (OK) is returned on success and a negated errno is returned on
|
||||
* failure.
|
||||
*
|
||||
****************************************************************************/
|
||||
|
||||
int nxflat_bind(FAR struct nxflat_loadinfo_s *loadinfo,
|
||||
FAR const struct symtab_s *exports, int nexports)
|
||||
{
|
||||
/* First bind all GOT relocations (omitting absolute symbol relocations) */
|
||||
|
||||
int ret = nxflat_gotrelocs(loadinfo);
|
||||
if (ret == OK)
|
||||
{
|
||||
/* Then bind the imported symbol, absolute relocations separately.
|
||||
* There is no particular reason to do these separately over than
|
||||
* traversing the import list directly is simpler than traversing
|
||||
* it indirectly through the relocation list.
|
||||
*/
|
||||
|
||||
ret = nxflat_bindimports(loadinfo, exports, nexports);
|
||||
if (ret == OK)
|
||||
{
|
||||
/* Zero the BSS area, trashing the relocations that lived in space
|
||||
* in the file.
|
||||
*/
|
||||
|
||||
memset((void*)(loadinfo->dspace->region + loadinfo->datasize),
|
||||
0, loadinfo->bsssize);
|
||||
}
|
||||
}
|
||||
return ret;
|
||||
}
|
||||
|
||||
|
||||
@@ -68,6 +68,15 @@
|
||||
|
||||
/****************************************************************************
|
||||
* Name: nxflat_init
|
||||
*
|
||||
* Description:
|
||||
* This function is called to configure the library to process an NXFLAT
|
||||
* program binary.
|
||||
*
|
||||
* Returned Value:
|
||||
* 0 (OK) is returned on success and a negated errno is returned on
|
||||
* failure.
|
||||
*
|
||||
****************************************************************************/
|
||||
|
||||
int nxflat_init(const char *filename, struct nxflat_hdr_s *header,
|
||||
|
||||
@@ -42,7 +42,6 @@
|
||||
#include <sys/mman.h>
|
||||
|
||||
#include <stdlib.h>
|
||||
#include <string.h>
|
||||
#include <nxflat.h>
|
||||
#include <debug.h>
|
||||
#include <errno.h>
|
||||
@@ -63,131 +62,52 @@
|
||||
****************************************************************************/
|
||||
|
||||
#if defined(CONFIG_DEBUG_VERBOSE) && defined(CONFIG_DEBUG_BINFMT)
|
||||
static const char g_textsegment[] = "TEXT";
|
||||
static const char g_datasegment[] = "DATA";
|
||||
static const char g_bsssegment[] = "BSS";
|
||||
static const char g_unksegment[] = "UNKNOWN";
|
||||
static const char g_relocrel32i[] = "RELOC_REL32I";
|
||||
static const char g_relocrel32d[] = "RELOC_REL32D";
|
||||
static const char g_relocrel32id[] = "RELOC_REL32ID";
|
||||
static const char g_relocabs32[] = "RELOC_AB32";
|
||||
|
||||
static const char *g_segment[] =
|
||||
static const char *g_reloctype[] =
|
||||
{
|
||||
g_textsegment,
|
||||
g_datasegment,
|
||||
g_bsssegment,
|
||||
g_unksegment
|
||||
g_relocrel32i,
|
||||
g_relocrel32d,
|
||||
g_relocrel32id,
|
||||
g_relocabs32
|
||||
};
|
||||
|
||||
# define SEGNAME(rl) g_segment[NXFLAT_RELOC_TYPE(rl)]
|
||||
# define RELONAME(rl) g_reloctype[NXFLAT_RELOC_TYPE(rl)]
|
||||
#else
|
||||
# define SEGNAME(rl) "(no name)"
|
||||
# define RELONAME(rl) "(no name)"
|
||||
#endif
|
||||
|
||||
/****************************************************************************
|
||||
* Private Functions
|
||||
****************************************************************************/
|
||||
|
||||
/****************************************************************************
|
||||
* Name: nxflat_reloc
|
||||
****************************************************************************/
|
||||
|
||||
static void nxflat_reloc(struct nxflat_loadinfo_s *loadinfo, uint32 rl)
|
||||
{
|
||||
uint32 *ptr;
|
||||
ubyte *datastart;
|
||||
|
||||
/* We only support relocations in the data sections. Verify that the
|
||||
* relocation address lies in the data section of the file image.
|
||||
*/
|
||||
|
||||
if (NXFLAT_RELOC_OFFSET(rl) > loadinfo->datasize)
|
||||
{
|
||||
bdbg("ERROR: Relocation at %08x invalid -- "
|
||||
"does not lie in the data segment, size: %08x\n",
|
||||
NXFLAT_RELOC_OFFSET(rl), loadinfo->datasize);
|
||||
bdbg(" Relocation not performed!\n");
|
||||
}
|
||||
else if ((NXFLAT_RELOC_OFFSET(rl) & 0x00000003) != 0)
|
||||
{
|
||||
bdbg("ERROR: Relocation at %08x invalid -- "
|
||||
"Improperly aligned\n",
|
||||
NXFLAT_RELOC_OFFSET(rl));
|
||||
}
|
||||
else
|
||||
{
|
||||
/* Get a reference to the "real" start of data. It is
|
||||
* offset slightly from the beginning of the allocated
|
||||
* DSpace to hold information needed by ld.so at run time.
|
||||
*/
|
||||
|
||||
datastart = loadinfo->dspace->region;
|
||||
|
||||
/* Get a pointer to the value that needs relocation in
|
||||
* DSpace.
|
||||
*/
|
||||
|
||||
ptr = (uint32*)(datastart + NXFLAT_RELOC_OFFSET(rl));
|
||||
|
||||
bvdbg("Relocation of variable at DATASEG+%08x "
|
||||
"(address %p, currently %08x) into segment %s\n",
|
||||
NXFLAT_RELOC_OFFSET(rl), ptr, *ptr, SEGNAME(rl));
|
||||
|
||||
switch (NXFLAT_RELOC_TYPE(rl))
|
||||
{
|
||||
/* TEXT is located at an offset of sizeof(struct nxflat_hdr_s) from
|
||||
* the allocated/mapped ISpace region.
|
||||
*/
|
||||
|
||||
case NXFLAT_RELOC_TYPE_TEXT:
|
||||
*ptr += loadinfo->ispace + sizeof(struct nxflat_hdr_s);
|
||||
break;
|
||||
|
||||
/* DATA and BSS are always contiguous regions. DATA
|
||||
* begins at the beginning of the allocated data segment.
|
||||
* BSS is positioned after DATA, unrelocated references
|
||||
* to BSS include the data offset.
|
||||
*
|
||||
* In other contexts, is it necessary to add the datasize
|
||||
* to get the BSS offset like:
|
||||
*
|
||||
* *ptr += datastart + loadinfo->datasize;
|
||||
*/
|
||||
|
||||
case NXFLAT_RELOC_TYPE_DATA:
|
||||
case NXFLAT_RELOC_TYPE_BSS:
|
||||
*ptr += (uint32)datastart;
|
||||
break;
|
||||
|
||||
/* This case happens normally if the symbol is a weak
|
||||
* undefined symbol. We permit these.
|
||||
*/
|
||||
|
||||
case NXFLAT_RELOC_TYPE_NONE:
|
||||
bdbg("NULL relocation!\n");
|
||||
break;
|
||||
|
||||
default:
|
||||
bdbg("ERROR: Unknown relocation type: %d\n", NXFLAT_RELOC_TYPE(rl));
|
||||
break;
|
||||
}
|
||||
|
||||
bvdbg("Relocation became %08x\n", *ptr);
|
||||
}
|
||||
}
|
||||
|
||||
/****************************************************************************
|
||||
* Public Functions
|
||||
****************************************************************************/
|
||||
|
||||
/****************************************************************************
|
||||
* Name: nxflat_load
|
||||
*
|
||||
* Description:
|
||||
* Loads the binary specified by nxflat_init into memory, mapping
|
||||
* the I-space executable regions, allocating the D-Space region,
|
||||
* and inializing the data segment (relocation information is
|
||||
* temporarily loaded into the BSS region. BSS will be cleared
|
||||
* by nxflat_bind() after the relocation data has been processed).
|
||||
*
|
||||
* Returned Value:
|
||||
* 0 (OK) is returned on success and a negated errno is returned on
|
||||
* failure.
|
||||
*
|
||||
****************************************************************************/
|
||||
|
||||
int nxflat_load(struct nxflat_loadinfo_s *loadinfo)
|
||||
{
|
||||
off_t doffset; /* Offset to .data in the NXFLAT file */
|
||||
uint32 *reloctab; /* Address of the relocation table */
|
||||
uint32 dreadsize; /* Total number of bytes of .data to be read */
|
||||
int ret = OK;
|
||||
int i;
|
||||
|
||||
/* Calculate the extra space we need to allocate. This extra space will be
|
||||
* the size of the BSS section. This extra space will also be used
|
||||
@@ -266,7 +186,7 @@ int nxflat_load(struct nxflat_loadinfo_s *loadinfo)
|
||||
}
|
||||
loadinfo->dspace->crefs = 1;
|
||||
|
||||
bvdbg("Allocated DSpace (%d bytes) at %p\n", loadinfo->dsize, loadinfo->dspace);
|
||||
bvdbg("Allocated DSpace (%d bytes) at %p\n", loadinfo->dsize, loadinfo->dspace->region);
|
||||
|
||||
/* Now, read the data into allocated DSpace at doffset into the
|
||||
* allocated DSpace memory.
|
||||
@@ -282,30 +202,6 @@ int nxflat_load(struct nxflat_loadinfo_s *loadinfo)
|
||||
bvdbg("TEXT: %08x Entry point offset: %08x Data offset: %08x\n",
|
||||
loadinfo->ispace, loadinfo->entryoffs, doffset);
|
||||
|
||||
/* Resolve the address of the relocation table. In the file, the
|
||||
* relocations should lie at the same offset as BSS. The current
|
||||
* value of relocstart is the offset from the beginning of the file.
|
||||
* The following adjustment will convert it to an address in dspace->
|
||||
*/
|
||||
|
||||
reloctab = (uint32*)(loadinfo->relocstart + (uint32)loadinfo->dspace->region - loadinfo->isize);
|
||||
|
||||
bvdbg("Relocation table at %p, reloccount: %d\n",
|
||||
reloctab, loadinfo->reloccount);
|
||||
|
||||
/* Now run through the relocation entries. */
|
||||
|
||||
for (i=0; i < loadinfo->reloccount; i++)
|
||||
{
|
||||
nxflat_reloc(loadinfo, htonl(reloctab[i]));
|
||||
}
|
||||
|
||||
/* Zero the BSS area, trashing the relocations that lived in space
|
||||
* in the file.
|
||||
*/
|
||||
|
||||
memset((void*)(loadinfo->dspace->region + loadinfo->datasize),
|
||||
0, loadinfo->bsssize);
|
||||
return OK;
|
||||
|
||||
errout:
|
||||
|
||||
@@ -67,6 +67,14 @@
|
||||
|
||||
/****************************************************************************
|
||||
* Name: nxflat_read
|
||||
*
|
||||
* Description:
|
||||
* Read 'readsize' bytes from the object file at 'offset'
|
||||
*
|
||||
* Returned Value:
|
||||
* 0 (OK) is returned on success and a negated errno is returned on
|
||||
* failure.
|
||||
*
|
||||
****************************************************************************/
|
||||
|
||||
int nxflat_read(struct nxflat_loadinfo_s *loadinfo, char *buffer, int readsize, int offset)
|
||||
|
||||
@@ -66,6 +66,15 @@
|
||||
|
||||
/****************************************************************************
|
||||
* Name: nxflat_uninit
|
||||
*
|
||||
* Description:
|
||||
* Releases any resources committed by nxflat_init(). This essentially
|
||||
* undoes the actions of nxflat_init.
|
||||
*
|
||||
* Returned Value:
|
||||
* 0 (OK) is returned on success and a negated errno is returned on
|
||||
* failure.
|
||||
*
|
||||
****************************************************************************/
|
||||
|
||||
int nxflat_uninit(struct nxflat_loadinfo_s *loadinfo)
|
||||
|
||||
@@ -69,6 +69,10 @@
|
||||
* This function unloads the object from memory. This essentially
|
||||
* undoes the actions of nxflat_load.
|
||||
*
|
||||
* Returned Value:
|
||||
* 0 (OK) is returned on success and a negated errno is returned on
|
||||
* failure.
|
||||
*
|
||||
****************************************************************************/
|
||||
|
||||
int nxflat_unload(struct nxflat_loadinfo_s *loadinfo)
|
||||
|
||||
@@ -63,6 +63,15 @@
|
||||
|
||||
/****************************************************************************
|
||||
* Name: nxflat_verifyheader
|
||||
*
|
||||
* Description:
|
||||
* Given the header from a possible NXFLAT executable, verify that it
|
||||
* is an NXFLAT executable.
|
||||
*
|
||||
* Returned Value:
|
||||
* 0 (OK) is returned on success and a negated errno is returned on
|
||||
* failure.
|
||||
*
|
||||
****************************************************************************/
|
||||
|
||||
int nxflat_verifyheader(const struct nxflat_hdr_s *header)
|
||||
|
||||
@@ -26,6 +26,7 @@ echo "#include <nuttx/symtab.h>"
|
||||
echo ""
|
||||
echo "static const struct symtab_s exports[] = "
|
||||
echo "{"
|
||||
|
||||
for string in $varlist; do
|
||||
var=`echo $string | sed -e "s/\"//g"`
|
||||
echo " {$string, $var},"
|
||||
|
||||
+13
-8
@@ -107,7 +107,7 @@ extern "C" {
|
||||
****************************************************************************/
|
||||
|
||||
/***********************************************************************
|
||||
* Name:
|
||||
* Name: nxflat_verifyheader
|
||||
*
|
||||
* Description:
|
||||
* Given the header from a possible NXFLAT executable, verify that it
|
||||
@@ -122,7 +122,7 @@ extern "C" {
|
||||
EXTERN int nxflat_verifyheader(const struct nxflat_hdr_s *header);
|
||||
|
||||
/***********************************************************************
|
||||
* Name:
|
||||
* Name: nxflat_init
|
||||
*
|
||||
* Description:
|
||||
* This function is called to configure the library to process an NXFLAT
|
||||
@@ -138,7 +138,7 @@ EXTERN int nxflat_init(const char *filename, struct nxflat_hdr_s *header,
|
||||
struct nxflat_loadinfo_s *loadinfo);
|
||||
|
||||
/***********************************************************************
|
||||
* Name:
|
||||
* Name: nxflat_uninit
|
||||
*
|
||||
* Description:
|
||||
* Releases any resources committed by nxflat_init(). This essentially
|
||||
@@ -153,11 +153,14 @@ EXTERN int nxflat_init(const char *filename, struct nxflat_hdr_s *header,
|
||||
EXTERN int nxflat_uninit(struct nxflat_loadinfo_s *loadinfo);
|
||||
|
||||
/***********************************************************************
|
||||
* Name:
|
||||
* Name: nxflat_load
|
||||
*
|
||||
* Description:
|
||||
* Loads the binary specified by nxflat_init into memory,
|
||||
* Completes all relocations, and clears BSS.
|
||||
* Loads the binary specified by nxflat_init into memory, mapping
|
||||
* the I-space executable regions, allocating the D-Space region,
|
||||
* and inializing the data segment (relocation information is
|
||||
* temporarily loaded into the BSS region. BSS will be cleared
|
||||
* by nxflat_bind() after the relocation data has been processed).
|
||||
*
|
||||
* Returned Value:
|
||||
* 0 (OK) is returned on success and a negated errno is returned on
|
||||
@@ -168,7 +171,7 @@ EXTERN int nxflat_uninit(struct nxflat_loadinfo_s *loadinfo);
|
||||
EXTERN int nxflat_load(struct nxflat_loadinfo_s *loadinfo);
|
||||
|
||||
/***********************************************************************
|
||||
* Name:
|
||||
* Name: nxflat_read
|
||||
*
|
||||
* Description:
|
||||
* Read 'readsize' bytes from the object file at 'offset'
|
||||
@@ -188,6 +191,8 @@ EXTERN int nxflat_read(struct nxflat_loadinfo_s *loadinfo, char *buffer,
|
||||
* Description:
|
||||
* Bind the imported symbol names in the loaded module described by
|
||||
* 'loadinfo' using the exported symbol values provided by 'symtab'
|
||||
* After binding the module, clear the BSS region (which held the relocation
|
||||
* data) in preparation for execution.
|
||||
*
|
||||
* Returned Value:
|
||||
* 0 (OK) is returned on success and a negated errno is returned on
|
||||
@@ -200,7 +205,7 @@ EXTERN int nxflat_bind(FAR struct nxflat_loadinfo_s *loadinfo,
|
||||
FAR const struct symtab_s *exports, int nexports);
|
||||
|
||||
/***********************************************************************
|
||||
* Name:
|
||||
* Name: nxflat_unload
|
||||
*
|
||||
* Description:
|
||||
* This function unloads the object from memory. This essentially
|
||||
|
||||
+31
-11
@@ -104,7 +104,8 @@ struct nxflat_hdr_s
|
||||
|
||||
uint32 h_stacksize;
|
||||
|
||||
/* Relocation entries
|
||||
/* Relocation entries:
|
||||
*
|
||||
* h_relocstart - Offset to the beginning of an array of relocation
|
||||
* records (struct nxflat_reloc). The offset is
|
||||
* relative to the start of the file
|
||||
@@ -114,7 +115,7 @@ struct nxflat_hdr_s
|
||||
uint32 h_relocstart; /* Offset of relocation records */
|
||||
uint32 h_reloccount; /* Number of relocation records */
|
||||
|
||||
/* Imported symbol table (NOTE no symbols are exported)
|
||||
/* Imported symbol table (NOTE no symbols are exported):
|
||||
*
|
||||
* h_importsymbols - Offset to the beginning of an array of imported
|
||||
* symbol structures (struct nxflat_import). The
|
||||
@@ -143,27 +144,46 @@ struct nxflat_reloc_s
|
||||
|
||||
/* Pack the type and the offset into one 32-bit value */
|
||||
|
||||
#define NXFLAT_RELOC(t,o) (((u_int32_t)((t) & 3) << 28) | ((o) & 0x1fffffff))
|
||||
#define NXFLAT_RELOC(t,o) (((u_int32_t)((t) & 3) << 30) | ((o) & 0x1fffffff))
|
||||
|
||||
/* The top three bits of the relocation info is the relocation type (see the
|
||||
* NXFLAT_RELOC_TYPE_* definitions below. This is an unsigned value.
|
||||
*/
|
||||
|
||||
#define NXFLAT_RELOC_TYPE(r) ((uint32)(r) >> 28)
|
||||
#define NXFLAT_RELOC_TYPE(r) ((uint32)(r) >> 30)
|
||||
|
||||
/* The bottom 28 bits of the relocation info is the (non-negative) offset into
|
||||
* the D-Space that needs the fixup.
|
||||
*/
|
||||
|
||||
#define NXFLAT_RELOC_OFFSET(r) ((uint32)(r) & 0x1fffffff)
|
||||
#define NXFLAT_RELOC_OFFSET(r) ((uint32)(r) & 0x3fffffff)
|
||||
|
||||
/* These are possible values for the relocation type */
|
||||
/* These are possible values for the relocation type:
|
||||
*
|
||||
* NXFLAT_RELOC_TYPE_REL32I Meaning: Object file contains a 32-bit offset
|
||||
* into I-Space at the the offset.
|
||||
* Fixup: Add mapped I-Space address to the offset.
|
||||
* NXFLAT_RELOC_TYPE_REL32D Meaning: Object file contains a 32-bit offset
|
||||
* into D-Space at the the offset.
|
||||
* Fixup: Add allocated D-Space address to the
|
||||
* offset.
|
||||
* NXFLAT_RELOC_TYPE_REL32ID Meaning: Object file contains a 32-bit offset
|
||||
* into I-Space at the the offset, but will
|
||||
* be referenced as data
|
||||
* Fixup: Add mapped I-Space address - allocated
|
||||
* D-Space address to the offset.
|
||||
* NXFLAT_RELOC_TYPE_ABS32 Meaning: Offset refers to a struct nxflat_import_s
|
||||
* describing a function pointer to be
|
||||
* imported.
|
||||
* Fixup: Provide the absolute function address
|
||||
* in the struct nxflat_import_s instance.
|
||||
*/
|
||||
|
||||
#define NXFLAT_RELOC_TYPE_NONE 0 /* Invalid relocation type */
|
||||
#define NXFLAT_RELOC_TYPE_TEXT 1 /* Symbol lies in .text region */
|
||||
#define NXFLAT_RELOC_TYPE_DATA 2 /* Symbol lies in .data region */
|
||||
#define NXFLAT_RELOC_TYPE_BSS 3 /* Symbol lies in .bss region */
|
||||
#define NXFLAT_RELOC_TYPE_NUM 4
|
||||
#define NXFLAT_RELOC_TYPE_REL32I 0
|
||||
#define NXFLAT_RELOC_TYPE_REL32D 1
|
||||
#define NXFLAT_RELOC_TYPE_REL32ID 2
|
||||
#define NXFLAT_RELOC_TYPE_ABS32 3
|
||||
#define NXFLAT_RELOC_TYPE_NUM 4 /* Number of relocation types */
|
||||
|
||||
/****************************************************************************
|
||||
* NXFLAT Imported symbol type
|
||||
|
||||
Reference in New Issue
Block a user