summaryrefslogtreecommitdiff
path: root/misc
diff options
context:
space:
mode:
authorpatacongo <patacongo@42af7a65-404d-4744-a932-0658087f49c3>2009-06-26 18:59:28 +0000
committerpatacongo <patacongo@42af7a65-404d-4744-a932-0658087f49c3>2009-06-26 18:59:28 +0000
commit637f649b594579ff5e2b831cc999cfb57b161eb5 (patch)
tree977d32a5be19fb164db0f253f8103e380fea4e1e /misc
parent083b33a940fa68f8a0751677c6e861efb0e11dad (diff)
downloadpx4-nuttx-637f649b594579ff5e2b831cc999cfb57b161eb5.tar.gz
px4-nuttx-637f649b594579ff5e2b831cc999cfb57b161eb5.tar.bz2
px4-nuttx-637f649b594579ff5e2b831cc999cfb57b161eb5.zip
Completes initial fragile integration
git-svn-id: svn://svn.code.sf.net/p/nuttx/code/trunk@1964 42af7a65-404d-4744-a932-0658087f49c3
Diffstat (limited to 'misc')
-rw-r--r--misc/buildroot/toolchain/nxflat/ldnxflat.c123
-rw-r--r--misc/buildroot/toolchain/nxflat/nxflat.h8
2 files changed, 98 insertions, 33 deletions
diff --git a/misc/buildroot/toolchain/nxflat/ldnxflat.c b/misc/buildroot/toolchain/nxflat/ldnxflat.c
index 76644b0c5..3a4bf36aa 100644
--- a/misc/buildroot/toolchain/nxflat/ldnxflat.c
+++ b/misc/buildroot/toolchain/nxflat/ldnxflat.c
@@ -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! */
diff --git a/misc/buildroot/toolchain/nxflat/nxflat.h b/misc/buildroot/toolchain/nxflat/nxflat.h
index 994a68421..f8d28deb4 100644
--- a/misc/buildroot/toolchain/nxflat/nxflat.h
+++ b/misc/buildroot/toolchain/nxflat/nxflat.h
@@ -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.