Completes initial fragile integration
git-svn-id: https://nuttx.svn.sourceforge.net/svnroot/nuttx/trunk@1964 7fd9a85b-ad96-42d3-883c-3090e2eb8679
This commit is contained in:
parent
4aded70c45
commit
eb1fbf40bb
|
@ -236,6 +236,9 @@ static asymbol *entry_symbol = NULL;
|
|||
static asymbol *dynimport_begin_symbol = NULL;
|
||||
static asymbol *dynimport_end_symbol = NULL;
|
||||
|
||||
struct nxflat_reloc_s *nxflat_relocs;
|
||||
static int nxflat_nrelocs;
|
||||
|
||||
static struct nxflat_got_s *got_offsets; /* realloc'ed array of GOT entry descriptions */
|
||||
static u_int32_t got_size; /* The size of the GOT to be allocated */
|
||||
int ngot_offsets; /* Number of GOT offsets in got_offsets[] */
|
||||
|
@ -803,8 +806,10 @@ static void alloc_got_entry(asymbol *sym)
|
|||
static void
|
||||
resolve_segment_relocs(bfd *input_bfd, segment_info *inf, asymbol **syms)
|
||||
{
|
||||
struct nxflat_reloc_s *relocs;
|
||||
arelent **relpp;
|
||||
int relsize;
|
||||
int reloc_type;
|
||||
int relcount;
|
||||
int i;
|
||||
int j;
|
||||
|
@ -977,13 +982,14 @@ resolve_segment_relocs(bfd *input_bfd, segment_info *inf, asymbol **syms)
|
|||
dbg("Performing ABS32 link at addr %08lx [%08lx] to sym '%s' [%08lx]\n",
|
||||
(long)relpp[j]->address, (long)*target, rel_sym->name, (long)sym_value);
|
||||
|
||||
/* ABS32 links from .text are easy - since the fetches will */
|
||||
/* always be base relative. the ABS32 refs from data will be */
|
||||
/* handled the same */
|
||||
/* ABS32 links from .text are easy - since the fetches will
|
||||
* always be base relative. the ABS32 refs from data will be
|
||||
* handled the same
|
||||
*/
|
||||
|
||||
if (verbose > 1)
|
||||
{
|
||||
vdbg(" Original opcode @ %p is %08lx ",
|
||||
vdbg(" Original location %p is %08lx ",
|
||||
#ifdef ARCH_BIG_ENDIAN
|
||||
target, (long)nxflat_swap32(*target));
|
||||
#else
|
||||
|
@ -1007,12 +1013,9 @@ resolve_segment_relocs(bfd *input_bfd, segment_info *inf, asymbol **syms)
|
|||
#else
|
||||
saved = temp = *target;
|
||||
#endif
|
||||
/* Mask */
|
||||
/* Mask and sign extend */
|
||||
|
||||
temp &= how_to->src_mask;
|
||||
|
||||
/* Sign extend */
|
||||
|
||||
temp <<= (32 - how_to->bitsize);
|
||||
temp >>= (32 - how_to->bitsize);
|
||||
|
||||
|
@ -1028,12 +1031,67 @@ resolve_segment_relocs(bfd *input_bfd, segment_info *inf, asymbol **syms)
|
|||
|
||||
temp |= saved & (~how_to->dst_mask);
|
||||
|
||||
vdbg(" Modified opcode: %08lx\n", (long)temp);
|
||||
vdbg(" Modified location: %08lx\n", (long)temp);
|
||||
#ifdef ARCH_BIG_ENDIAN
|
||||
*target = (long)nxflat_swap32(temp);
|
||||
#else
|
||||
*target = (long)temp;
|
||||
#endif
|
||||
/* Determine where the symbol lies */
|
||||
|
||||
switch (get_reloc_type(rel_section, NULL))
|
||||
{
|
||||
case NXFLAT_RELOC_TARGET_UNKNOWN:
|
||||
default:
|
||||
{
|
||||
err("Symbol relocation section type is unknown\n");
|
||||
nerrors++;
|
||||
}
|
||||
/* Fall through and do something wrong */
|
||||
|
||||
case NXFLAT_RELOC_TARGET_BSS:
|
||||
case NXFLAT_RELOC_TARGET_DATA:
|
||||
{
|
||||
vdbg("Symbol '%s' lies in D-Space\n", rel_sym->name);
|
||||
reloc_type = NXFLAT_RELOC_TYPE_REL32D;
|
||||
}
|
||||
break;
|
||||
|
||||
case NXFLAT_RELOC_TARGET_TEXT:
|
||||
{
|
||||
vdbg("Symbol '%s' lies in I-Space\n", rel_sym->name);
|
||||
reloc_type = NXFLAT_RELOC_TYPE_REL32I;
|
||||
}
|
||||
break;
|
||||
}
|
||||
|
||||
/* Re-allocate memory to include this relocation */
|
||||
|
||||
relocs = (struct nxflat_reloc_s*)
|
||||
realloc(nxflat_relocs, sizeof(struct nxflat_reloc_s) * nxflat_nrelocs + 1);
|
||||
if (!relocs)
|
||||
{
|
||||
err("Failed to re-allocate memory ABS32 relocations (%d relocations)\n",
|
||||
nxflat_nrelocs);
|
||||
nerrors++;
|
||||
}
|
||||
else
|
||||
{
|
||||
/* Reallocation was successful. Update globlas */
|
||||
|
||||
nxflat_nrelocs++;
|
||||
nxflat_relocs = relocs;
|
||||
|
||||
/* Then add the relocation at the end of the table */
|
||||
|
||||
nxflat_relocs[nxflat_nrelocs-1].r_info =
|
||||
NXFLAT_RELOC(reloc_type, relpp[j]->address + got_size);
|
||||
|
||||
vdbg("relocs[%d]: type: %d offset: %08x\n",
|
||||
nxflat_nrelocs-1,
|
||||
NXFLAT_RELOC_TYPE(nxflat_relocs[nxflat_nrelocs-1].r_info),
|
||||
NXFLAT_RELOC_OFFSET(nxflat_relocs[nxflat_nrelocs-1].r_info));
|
||||
}
|
||||
}
|
||||
break;
|
||||
|
||||
|
@ -1645,13 +1703,16 @@ static void allocate_got(bfd *input_bfd, asymbol **symbols)
|
|||
|
||||
/* Pull the sections that make up this segment in off disk */
|
||||
|
||||
static void output_got(int fd, struct nxflat_reloc_s **pprelocs)
|
||||
static void output_got(int fd)
|
||||
{
|
||||
struct nxflat_reloc_s *relocs;
|
||||
u_int32_t *got;
|
||||
u_int32_t offset;
|
||||
int reloc_size;
|
||||
int reloc_type;
|
||||
int nrelocs;
|
||||
int i;
|
||||
int j;
|
||||
|
||||
if (ngot_offsets > 0)
|
||||
{
|
||||
|
@ -1665,14 +1726,15 @@ static void output_got(int fd, struct nxflat_reloc_s **pprelocs)
|
|||
exit(1);
|
||||
}
|
||||
|
||||
/* Allocate memory for the relocations */
|
||||
/* Re-allocate memory for the relocations to include the GOT relocations */
|
||||
|
||||
reloc_size = sizeof(struct nxflat_reloc_s) * ngot_offsets;
|
||||
relocs = (struct nxflat_reloc_s*)malloc(reloc_size);
|
||||
nrelocs = ngot_offsets + nxflat_nrelocs;
|
||||
reloc_size = sizeof(struct nxflat_reloc_s) * nrelocs;
|
||||
relocs = (struct nxflat_reloc_s*)realloc(nxflat_relocs, reloc_size);
|
||||
if (!relocs)
|
||||
{
|
||||
err("Failed to allocate memory for the GOT relocations (%d bytes, %d relocations)\n",
|
||||
reloc_size, ngot_offsets);
|
||||
err("Failed to re-allocate memory for the GOT relocations (%d bytes, %d relocations)\n",
|
||||
reloc_size, nrelocs);
|
||||
exit(1);
|
||||
}
|
||||
|
||||
|
@ -1684,6 +1746,10 @@ static void output_got(int fd, struct nxflat_reloc_s **pprelocs)
|
|||
asection *rel_section = rel_sym->section;
|
||||
symvalue sym_value = rel_sym->value;
|
||||
|
||||
/* j is the offset index into the relocatino table */
|
||||
|
||||
j = i + nxflat_nrelocs;
|
||||
|
||||
/* If the symbol is a thumb function, then set bit 1 of the value */
|
||||
|
||||
#ifdef NXFLAT_THUMB2
|
||||
|
@ -1735,10 +1801,10 @@ static void output_got(int fd, struct nxflat_reloc_s **pprelocs)
|
|||
|
||||
/* And output the relocation information associate with the GOT entry */
|
||||
|
||||
relocs[i].r_info = NXFLAT_RELOC(reloc_type, sizeof(u_int32_t) * i);
|
||||
relocs[j].r_info = NXFLAT_RELOC(reloc_type, sizeof(u_int32_t) * i);
|
||||
|
||||
vdbg("relocs[%d]: type: %d offset: %08x\n",
|
||||
i, NXFLAT_RELOC_TYPE(relocs[i].r_info), NXFLAT_RELOC_OFFSET(relocs[i].r_info));
|
||||
j, NXFLAT_RELOC_TYPE(relocs[j].r_info), NXFLAT_RELOC_OFFSET(relocs[j].r_info));
|
||||
}
|
||||
|
||||
/* Write the GOT on the provided file descriptor */
|
||||
|
@ -1752,8 +1818,8 @@ static void output_got(int fd, struct nxflat_reloc_s **pprelocs)
|
|||
(long)(sizeof(u_int32_t) * i), got[i]);
|
||||
}
|
||||
|
||||
printf("Got Relocations:\n");
|
||||
for (i = 0; i < ngot_offsets; i++)
|
||||
printf("Relocations:\n");
|
||||
for (i = 0; i < nrelocs; i++)
|
||||
{
|
||||
printf(" Offset %-3ld: %08x\n",
|
||||
(long)(sizeof(struct nxflat_reloc_s) * i), relocs[i].r_info);
|
||||
|
@ -1763,9 +1829,10 @@ static void output_got(int fd, struct nxflat_reloc_s **pprelocs)
|
|||
nxflat_write(fd, (const char *)got, got_size);
|
||||
free(got);
|
||||
|
||||
/* Return the relocation table */
|
||||
/* Return the relocation table (via global variables) */
|
||||
|
||||
*pprelocs = relocs;
|
||||
nxflat_relocs = relocs;
|
||||
nxflat_nrelocs = nrelocs;
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -1990,7 +2057,6 @@ static void parse_args(int argc, char **argv)
|
|||
int main(int argc, char **argv, char **envp)
|
||||
{
|
||||
struct nxflat_hdr_s hdr;
|
||||
struct nxflat_reloc_s *reloc;
|
||||
bfd *bf;
|
||||
asection *s;
|
||||
asymbol **symbol_table;
|
||||
|
@ -2207,7 +2273,7 @@ int main(int argc, char **argv, char **envp)
|
|||
put_xflat32(&hdr.h_bssend, offset);
|
||||
|
||||
put_xflat32(&hdr.h_stacksize, stack_size);
|
||||
put_xflat16(&hdr.h_reloccount, ngot_offsets);
|
||||
put_xflat16(&hdr.h_reloccount, nxflat_nrelocs + ngot_offsets);
|
||||
|
||||
put_entry_point(&hdr);
|
||||
|
||||
|
@ -2238,25 +2304,24 @@ int main(int argc, char **argv, char **envp)
|
|||
nxflat_write(fd, (const char *)&hdr, NXFLAT_HDR_SIZE);
|
||||
nxflat_write(fd, (const char *)text_info.contents, text_info.size);
|
||||
|
||||
reloc = NULL;
|
||||
if (ngot_offsets > 0)
|
||||
{
|
||||
output_got(fd, &reloc);
|
||||
output_got(fd);
|
||||
}
|
||||
|
||||
nxflat_write(fd, (const char *)data_info.contents, data_info.size);
|
||||
|
||||
if (reloc)
|
||||
if (nxflat_relocs)
|
||||
{
|
||||
vdbg("Number of GOT relocations: %d\n", ngot_offsets);
|
||||
|
||||
#ifdef RELOCS_IN_NETWORK_ORDER
|
||||
for (i = 0; i < ngot_offsets; i++)
|
||||
for (i = 0; i < nxflat_nrelocs; i++)
|
||||
{
|
||||
reloc[i] = htonl(reloc[i]);
|
||||
nxflat_relocs[i] = htonl(nxflat_relocs[i]);
|
||||
}
|
||||
#endif
|
||||
nxflat_write(fd, (const char *)reloc, sizeof(struct nxflat_reloc_s) * ngot_offsets);
|
||||
nxflat_write(fd, (const char *)nxflat_relocs, sizeof(struct nxflat_reloc_s) * nxflat_nrelocs);
|
||||
}
|
||||
|
||||
/* Finished! */
|
||||
|
|
|
@ -46,8 +46,8 @@
|
|||
* Pre-processor Definitions
|
||||
****************************************************************************/
|
||||
|
||||
#define NXFLAT_MAX_STRING_SIZE 64 /* Largest size of string (w/zterminator) */
|
||||
#define NXFLAT_MAGIC "NxFT" /* NXFLAT magic number */
|
||||
#define NXFLAT_MAX_STRING_SIZE 64 /* Largest size of string (w/zterminator) */
|
||||
#define NXFLAT_MAGIC "NxFT" /* NXFLAT magic number */
|
||||
|
||||
/****************************************************************************
|
||||
* Public Types
|
||||
|
@ -72,7 +72,7 @@ struct nxflat_hdr_s
|
|||
|
||||
/* The following fields provide the memory map for the nxflat binary.
|
||||
*
|
||||
* h_entry - Offset to the the first executable insruction from
|
||||
* h_entry - Offset to the first executable insruction from
|
||||
* the beginning of the file.
|
||||
* h_datastart - Offset to the beginning of the data segment from
|
||||
* the beginning of the file. This field can also
|
||||
|
@ -148,7 +148,7 @@ 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) << 30) | ((o) & 0x1fffffff))
|
||||
#define NXFLAT_RELOC(t,o) (((u_int32_t)((t) & 3) << 30) | ((o) & 0x3fffffff))
|
||||
|
||||
/* The top three bits of the relocation info is the relocation type (see the
|
||||
* NXFLAT_RELOC_TYPE_* definitions below. This is an unsigned value.
|
||||
|
|
Loading…
Reference in New Issue