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_begin_symbol = NULL;
|
||||||
static asymbol *dynimport_end_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 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 */
|
static u_int32_t got_size; /* The size of the GOT to be allocated */
|
||||||
int ngot_offsets; /* Number of GOT offsets in got_offsets[] */
|
int ngot_offsets; /* Number of GOT offsets in got_offsets[] */
|
||||||
|
@ -803,8 +806,10 @@ static void alloc_got_entry(asymbol *sym)
|
||||||
static void
|
static void
|
||||||
resolve_segment_relocs(bfd *input_bfd, segment_info *inf, asymbol **syms)
|
resolve_segment_relocs(bfd *input_bfd, segment_info *inf, asymbol **syms)
|
||||||
{
|
{
|
||||||
|
struct nxflat_reloc_s *relocs;
|
||||||
arelent **relpp;
|
arelent **relpp;
|
||||||
int relsize;
|
int relsize;
|
||||||
|
int reloc_type;
|
||||||
int relcount;
|
int relcount;
|
||||||
int i;
|
int i;
|
||||||
int j;
|
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",
|
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);
|
(long)relpp[j]->address, (long)*target, rel_sym->name, (long)sym_value);
|
||||||
|
|
||||||
/* ABS32 links from .text are easy - since the fetches will */
|
/* ABS32 links from .text are easy - since the fetches will
|
||||||
/* always be base relative. the ABS32 refs from data will be */
|
* always be base relative. the ABS32 refs from data will be
|
||||||
/* handled the same */
|
* handled the same
|
||||||
|
*/
|
||||||
|
|
||||||
if (verbose > 1)
|
if (verbose > 1)
|
||||||
{
|
{
|
||||||
vdbg(" Original opcode @ %p is %08lx ",
|
vdbg(" Original location %p is %08lx ",
|
||||||
#ifdef ARCH_BIG_ENDIAN
|
#ifdef ARCH_BIG_ENDIAN
|
||||||
target, (long)nxflat_swap32(*target));
|
target, (long)nxflat_swap32(*target));
|
||||||
#else
|
#else
|
||||||
|
@ -1007,12 +1013,9 @@ resolve_segment_relocs(bfd *input_bfd, segment_info *inf, asymbol **syms)
|
||||||
#else
|
#else
|
||||||
saved = temp = *target;
|
saved = temp = *target;
|
||||||
#endif
|
#endif
|
||||||
/* Mask */
|
/* Mask and sign extend */
|
||||||
|
|
||||||
temp &= how_to->src_mask;
|
temp &= how_to->src_mask;
|
||||||
|
|
||||||
/* Sign extend */
|
|
||||||
|
|
||||||
temp <<= (32 - how_to->bitsize);
|
temp <<= (32 - how_to->bitsize);
|
||||||
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);
|
temp |= saved & (~how_to->dst_mask);
|
||||||
|
|
||||||
vdbg(" Modified opcode: %08lx\n", (long)temp);
|
vdbg(" Modified location: %08lx\n", (long)temp);
|
||||||
#ifdef ARCH_BIG_ENDIAN
|
#ifdef ARCH_BIG_ENDIAN
|
||||||
*target = (long)nxflat_swap32(temp);
|
*target = (long)nxflat_swap32(temp);
|
||||||
#else
|
#else
|
||||||
*target = (long)temp;
|
*target = (long)temp;
|
||||||
#endif
|
#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;
|
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 */
|
/* 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;
|
struct nxflat_reloc_s *relocs;
|
||||||
u_int32_t *got;
|
u_int32_t *got;
|
||||||
|
u_int32_t offset;
|
||||||
int reloc_size;
|
int reloc_size;
|
||||||
int reloc_type;
|
int reloc_type;
|
||||||
|
int nrelocs;
|
||||||
int i;
|
int i;
|
||||||
|
int j;
|
||||||
|
|
||||||
if (ngot_offsets > 0)
|
if (ngot_offsets > 0)
|
||||||
{
|
{
|
||||||
|
@ -1665,14 +1726,15 @@ static void output_got(int fd, struct nxflat_reloc_s **pprelocs)
|
||||||
exit(1);
|
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;
|
nrelocs = ngot_offsets + nxflat_nrelocs;
|
||||||
relocs = (struct nxflat_reloc_s*)malloc(reloc_size);
|
reloc_size = sizeof(struct nxflat_reloc_s) * nrelocs;
|
||||||
|
relocs = (struct nxflat_reloc_s*)realloc(nxflat_relocs, reloc_size);
|
||||||
if (!relocs)
|
if (!relocs)
|
||||||
{
|
{
|
||||||
err("Failed to allocate memory for the GOT relocations (%d bytes, %d relocations)\n",
|
err("Failed to re-allocate memory for the GOT relocations (%d bytes, %d relocations)\n",
|
||||||
reloc_size, ngot_offsets);
|
reloc_size, nrelocs);
|
||||||
exit(1);
|
exit(1);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -1684,6 +1746,10 @@ static void output_got(int fd, struct nxflat_reloc_s **pprelocs)
|
||||||
asection *rel_section = rel_sym->section;
|
asection *rel_section = rel_sym->section;
|
||||||
symvalue sym_value = rel_sym->value;
|
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 */
|
/* If the symbol is a thumb function, then set bit 1 of the value */
|
||||||
|
|
||||||
#ifdef NXFLAT_THUMB2
|
#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 */
|
/* 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",
|
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 */
|
/* 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]);
|
(long)(sizeof(u_int32_t) * i), got[i]);
|
||||||
}
|
}
|
||||||
|
|
||||||
printf("Got Relocations:\n");
|
printf("Relocations:\n");
|
||||||
for (i = 0; i < ngot_offsets; i++)
|
for (i = 0; i < nrelocs; i++)
|
||||||
{
|
{
|
||||||
printf(" Offset %-3ld: %08x\n",
|
printf(" Offset %-3ld: %08x\n",
|
||||||
(long)(sizeof(struct nxflat_reloc_s) * i), relocs[i].r_info);
|
(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);
|
nxflat_write(fd, (const char *)got, got_size);
|
||||||
free(got);
|
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)
|
int main(int argc, char **argv, char **envp)
|
||||||
{
|
{
|
||||||
struct nxflat_hdr_s hdr;
|
struct nxflat_hdr_s hdr;
|
||||||
struct nxflat_reloc_s *reloc;
|
|
||||||
bfd *bf;
|
bfd *bf;
|
||||||
asection *s;
|
asection *s;
|
||||||
asymbol **symbol_table;
|
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_bssend, offset);
|
||||||
|
|
||||||
put_xflat32(&hdr.h_stacksize, stack_size);
|
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);
|
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 *)&hdr, NXFLAT_HDR_SIZE);
|
||||||
nxflat_write(fd, (const char *)text_info.contents, text_info.size);
|
nxflat_write(fd, (const char *)text_info.contents, text_info.size);
|
||||||
|
|
||||||
reloc = NULL;
|
|
||||||
if (ngot_offsets > 0)
|
if (ngot_offsets > 0)
|
||||||
{
|
{
|
||||||
output_got(fd, &reloc);
|
output_got(fd);
|
||||||
}
|
}
|
||||||
|
|
||||||
nxflat_write(fd, (const char *)data_info.contents, data_info.size);
|
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);
|
vdbg("Number of GOT relocations: %d\n", ngot_offsets);
|
||||||
|
|
||||||
#ifdef RELOCS_IN_NETWORK_ORDER
|
#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
|
#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! */
|
/* Finished! */
|
||||||
|
|
|
@ -46,8 +46,8 @@
|
||||||
* Pre-processor Definitions
|
* Pre-processor Definitions
|
||||||
****************************************************************************/
|
****************************************************************************/
|
||||||
|
|
||||||
#define NXFLAT_MAX_STRING_SIZE 64 /* Largest size of string (w/zterminator) */
|
#define NXFLAT_MAX_STRING_SIZE 64 /* Largest size of string (w/zterminator) */
|
||||||
#define NXFLAT_MAGIC "NxFT" /* NXFLAT magic number */
|
#define NXFLAT_MAGIC "NxFT" /* NXFLAT magic number */
|
||||||
|
|
||||||
/****************************************************************************
|
/****************************************************************************
|
||||||
* Public Types
|
* Public Types
|
||||||
|
@ -72,7 +72,7 @@ struct nxflat_hdr_s
|
||||||
|
|
||||||
/* The following fields provide the memory map for the nxflat binary.
|
/* 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.
|
* the beginning of the file.
|
||||||
* h_datastart - Offset to the beginning of the data segment from
|
* h_datastart - Offset to the beginning of the data segment from
|
||||||
* the beginning of the file. This field can also
|
* 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 */
|
/* 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
|
/* The top three bits of the relocation info is the relocation type (see the
|
||||||
* NXFLAT_RELOC_TYPE_* definitions below. This is an unsigned value.
|
* NXFLAT_RELOC_TYPE_* definitions below. This is an unsigned value.
|
||||||
|
|
Loading…
Reference in New Issue