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:
patacongo
2009-06-22 22:12:19 +00:00
parent 7117b39923
commit bd11dc8305
10 changed files with 398 additions and 158 deletions
+290 -11
View File
@@ -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;
}
+9
View File
@@ -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,
+24 -128
View File
@@ -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:
+8
View File
@@ -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)
+9
View File
@@ -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)
+4
View File
@@ -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)
+9
View File
@@ -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)
+1
View File
@@ -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
View File
@@ -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
View File
@@ -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