aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--misc/buildroot/ChangeLog3
-rw-r--r--misc/buildroot/toolchain/nxflat/ldnxflat.c97
-rw-r--r--nuttx/Documentation/NuttXNxFlat.html2
-rw-r--r--nuttx/TODO42
-rw-r--r--nuttx/binfmt/libnxflat/gnu-nxflat-gotoff.ld5
5 files changed, 131 insertions, 18 deletions
diff --git a/misc/buildroot/ChangeLog b/misc/buildroot/ChangeLog
index 3cfd60bf2..cdbef5da1 100644
--- a/misc/buildroot/ChangeLog
+++ b/misc/buildroot/ChangeLog
@@ -123,4 +123,7 @@ buildroot-1.11 2011-xx-xx <gnutt@nuttx.org>
type was not generated by GCC/LD prior to gcc-4.6.3
* R_ARM_REL32 logic is conditionally disabled because it has not been
tested.
+ * ldnxflat: Correct a memory allocation error that could cause written
+ past the end of allocated memory. Partial restoration of R_ARM_REL32
+ logic. There are lots of issues that I still do not understand here.
diff --git a/misc/buildroot/toolchain/nxflat/ldnxflat.c b/misc/buildroot/toolchain/nxflat/ldnxflat.c
index 5343e6b43..39fc98ce9 100644
--- a/misc/buildroot/toolchain/nxflat/ldnxflat.c
+++ b/misc/buildroot/toolchain/nxflat/ldnxflat.c
@@ -800,11 +800,83 @@ static void alloc_got_entry(asymbol *sym)
}
/***********************************************************************
- * relocate_arm32
+ * relocate_rel32
***********************************************************************/
static void
-relocate_arm32(arelent *relp, int32_t *target, symvalue sym_value)
+relocate_rel32(arelent *relp, int32_t *target, symvalue sym_value)
+{
+ reloc_howto_type *how_to = relp->howto;
+ asymbol *rel_sym = *relp->sym_ptr_ptr;
+ asection *rel_section = rel_sym->section;
+ int32_t value;
+ int32_t temp;
+ int32_t saved;
+ int reloc_type;
+
+ if (verbose > 1)
+ {
+ vdbg(" Original location %p is %08lx ",
+#ifdef ARCH_BIG_ENDIAN
+ target, (long)nxflat_swap32(*target));
+#else
+ target, (long)*target);
+#endif
+ if (verbose > 2)
+ {
+ printf("rsh %d ", how_to->rightshift);
+ printf(" sz %d ", how_to->size);
+ printf("bit %d ", how_to->bitsize);
+ printf("rel %d ", how_to->pc_relative);
+ printf("smask %08lx ", (long)how_to->src_mask);
+ printf("dmask %08lx ", (long)how_to->dst_mask);
+ printf("off %d ", how_to->pcrel_offset);
+ }
+
+ printf("\n");
+ }
+
+#ifdef ARCH_BIG_ENDIAN
+ saved = temp = (int32_t) nxflat_swap32(*target);
+#else
+ saved = temp = *target;
+#endif
+ /* Mask and sign extend */
+
+ temp &= how_to->src_mask;
+ temp <<= (32 - how_to->bitsize);
+ temp >>= (32 - how_to->bitsize);
+
+ /* Calculate the new value: Current value + VMA - current PC */
+
+ value = temp + sym_value + rel_section->vma - relp->address;
+
+ /* Offset */
+
+ temp += (value >> how_to->rightshift);
+
+ /* Mask upper bits from rollover */
+
+ temp &= how_to->dst_mask;
+
+ /* Replace data that was masked */
+
+ temp |= saved & (~how_to->dst_mask);
+
+ vdbg(" Modified location: %08lx\n", (long)temp);
+#ifdef ARCH_BIG_ENDIAN
+ *target = (long)nxflat_swap32(temp);
+#else
+ *target = (long)temp;
+#endif
+ }
+
+/***********************************************************************
+ * relocate_abs32
+ ***********************************************************************/
+
+static void
+relocate_abs32(arelent *relp, int32_t *target, symvalue sym_value)
{
reloc_howto_type *how_to = relp->howto;
asymbol *rel_sym = *relp->sym_ptr_ptr;
@@ -901,7 +973,7 @@ relocate_arm32(arelent *relp, int32_t *target, symvalue sym_value)
/* Re-allocate memory to include this relocation */
relocs = (struct nxflat_reloc_s*)
- realloc(nxflat_relocs, sizeof(struct nxflat_reloc_s) * nxflat_nrelocs + 1);
+ realloc(nxflat_relocs, sizeof(struct nxflat_reloc_s) * (nxflat_nrelocs + 1));
if (!relocs)
{
err("Failed to re-allocate memory ABS32 relocations (%d relocations)\n",
@@ -1105,7 +1177,7 @@ 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);
- relocate_arm32(relpp[j], target, sym_value);
+ relocate_abs32(relpp[j], target, sym_value);
}
break;
@@ -1114,18 +1186,12 @@ resolve_segment_relocs(bfd *input_bfd, segment_info *inf, asymbol **syms)
dbg("Performing REL32 link at addr %08lx [%08lx] to sym '%s' [%08lx]\n",
(long)relpp[j]->address, (long)*target, rel_sym->name, (long)sym_value);
- /* The REL32 relocation is just like the ABS32 relocation except that (1)
- * the symbol value is relative to the PC, and (2) we cannot permit
- * REL32 relocations to data in I-Space. That just would not make sense.
- */
-#if 1
- /* The logic below may or may not be correct. It has not been verified
- * so, for now, it is disabled.
+ /* The only valid REL32 relocation would be to relocate a reference from
+ * I-Space to another symbol in I-Space. That should be handled by the
+ * partially linking logic so we don't expect to see any R_ARM_REL32
+ * relocations here.
*/
- err("REL32 relocation not yet supported\n");
- nerrors++;
-#else
switch (get_reloc_type(rel_section, NULL))
{
case NXFLAT_RELOC_TARGET_UNKNOWN:
@@ -1148,11 +1214,10 @@ resolve_segment_relocs(bfd *input_bfd, segment_info *inf, asymbol **syms)
case NXFLAT_RELOC_TARGET_TEXT:
{
vdbg("Symbol '%s' lies in I-Space\n", rel_sym->name);
- relocate_arm32(relpp[j], target, sym_value - relpp[j]->address);
+ relocate_rel32(relpp[j], target, sym_value - relpp[j]->address);
}
break;
}
-#endif
}
break;
diff --git a/nuttx/Documentation/NuttXNxFlat.html b/nuttx/Documentation/NuttXNxFlat.html
index 4d70ed9c3..c51e3b6a1 100644
--- a/nuttx/Documentation/NuttXNxFlat.html
+++ b/nuttx/Documentation/NuttXNxFlat.html
@@ -522,7 +522,7 @@ cat ../syscall/syscall.csv ../lib/lib.csv | sort >tmp.csv
</p>
<p><b>NOTE:</b>
- There are two linker scripts located at <code>binfmt/libnxflat/gnu-nxflat-gotoff.ld</code>.
+ There are two linker scripts located at <code>binfmt/libnxflat/</code>.
</p>
<ol>
<li>
diff --git a/nuttx/TODO b/nuttx/TODO
index 30015ef50..90333c74c 100644
--- a/nuttx/TODO
+++ b/nuttx/TODO
@@ -12,7 +12,7 @@ nuttx/
(2) Signals (sched/, arch/)
(2) pthreads (sched/)
(2) C++ Support
- (5) Binary loaders (binfmt/)
+ (6) Binary loaders (binfmt/)
(17) Network (net/, drivers/net)
(3) USB (drivers/usbdev, drivers/usbhost)
(11) Libraries (lib/)
@@ -395,6 +395,46 @@ o Binary loaders (binfmt/)
Priority: There are too many references like the above. They will have
to get fixed as needed for Windows native tool builds.
+ Title: TOOLCHAIN COMPATIBILITY PROBLEM
+ Descripton: The older 4.3.3 compiler generates GOTOFF relocations to the constant
+ strings, like:
+
+ .L3:
+ .word .LC0(GOTOFF)
+ .word .LC1(GOTOFF)
+ .word .LC2(GOTOFF)
+ .word .LC3(GOTOFF)
+ .word .LC4(GOTOFF)
+
+ Where .LC0, LC1, LC2, LC3, and .LC4 are the labels correponding to strings in
+ the .rodata.str1.1 section. One consequence of this is that .rodata must reside
+ in D-Space since it will addressed relative to the GOT (see the section entitled
+ "Read-Only Data in RAM" at
+ http://nuttx.org/Documentation/NuttXNxFlat.html#limitations).
+
+ The newer 4.6.3compiler generated PC relative relocations to the strings:
+
+ .L2:
+ .word .LC0-(.LPIC0+4)
+ .word .LC1-(.LPIC1+4)
+ .word .LC2-(.LPIC2+4)
+ .word .LC3-(.LPIC4+4)
+ .word .LC4-(.LPIC5+4)
+
+ This is good and bad. This is good because it means that .rodata.str1.1 can not
+ reside in FLASH with .text and can be accessed using PC-relative addressing.
+ That can be accomplished by simply moving the .rodata from the .data section to
+ the .text section in the linker script. (The NXFLAT linker script is located at
+ nuttx/binfmt/libnxflat/gnu-nxflat.ld).
+
+ This is bad because a lot of stuff may get broken an a lot of test will need to
+ be done. One question that I have is does this apply to all kinds of .rodata?
+ Or just to .rodata.str1.1?
+
+ Status: Open. Many of the required changes are in place but, unfortunately, not enought
+ go be fully functional.
+ Priority: Medium. The workaround for now is to use the older, 4.3.3 OABI compiler.
+
o Network (net/, drivers/net)
^^^^^^^^^^^^^^^^^^^^^^^^^^^
diff --git a/nuttx/binfmt/libnxflat/gnu-nxflat-gotoff.ld b/nuttx/binfmt/libnxflat/gnu-nxflat-gotoff.ld
index c0487212a..47debd663 100644
--- a/nuttx/binfmt/libnxflat/gnu-nxflat-gotoff.ld
+++ b/nuttx/binfmt/libnxflat/gnu-nxflat-gotoff.ld
@@ -107,11 +107,16 @@ SECTIONS
.data 0x00000000 :
{
+ /* In this model, .rodata is access using PC-relative addressing
+ * and, hence, must also reside in the .text section.
+ */
+
__data_start = . ;
*(.rodata)
*(.rodata1)
*(.rodata.*)
*(.gnu.linkonce.r*)
+
*(.data)
*(.data1)
*(.data.*)