mirror of
https://gitee.com/mirrors_PX4/PX4-Autopilot.git
synced 2026-10-28 06:23:33 +08:00
More fixes for ldnxflat. There are still problems with the GCC 4.6.3
git-svn-id: http://svn.code.sf.net/p/nuttx/code/trunk@5227 42af7a65-404d-4744-a932-0658087f49c3
This commit is contained in:
@@ -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
|
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
|
* R_ARM_REL32 logic is conditionally disabled because it has not been
|
||||||
tested.
|
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.
|
||||||
|
|
||||||
|
|||||||
@@ -800,11 +800,83 @@ static void alloc_got_entry(asymbol *sym)
|
|||||||
}
|
}
|
||||||
|
|
||||||
/***********************************************************************
|
/***********************************************************************
|
||||||
* relocate_arm32
|
* relocate_rel32
|
||||||
***********************************************************************/
|
***********************************************************************/
|
||||||
|
|
||||||
static void
|
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;
|
reloc_howto_type *how_to = relp->howto;
|
||||||
asymbol *rel_sym = *relp->sym_ptr_ptr;
|
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 */
|
/* Re-allocate memory to include this relocation */
|
||||||
|
|
||||||
relocs = (struct nxflat_reloc_s*)
|
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)
|
if (!relocs)
|
||||||
{
|
{
|
||||||
err("Failed to re-allocate memory ABS32 relocations (%d relocations)\n",
|
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",
|
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);
|
||||||
|
|
||||||
relocate_arm32(relpp[j], target, sym_value);
|
relocate_abs32(relpp[j], target, sym_value);
|
||||||
}
|
}
|
||||||
break;
|
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",
|
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);
|
(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 only valid REL32 relocation would be to relocate a reference from
|
||||||
* the symbol value is relative to the PC, and (2) we cannot permit
|
* I-Space to another symbol in I-Space. That should be handled by the
|
||||||
* REL32 relocations to data in I-Space. That just would not make sense.
|
* partially linking logic so we don't expect to see any R_ARM_REL32
|
||||||
*/
|
* relocations here.
|
||||||
#if 1
|
|
||||||
/* The logic below may or may not be correct. It has not been verified
|
|
||||||
* so, for now, it is disabled.
|
|
||||||
*/
|
*/
|
||||||
|
|
||||||
err("REL32 relocation not yet supported\n");
|
|
||||||
nerrors++;
|
|
||||||
#else
|
|
||||||
switch (get_reloc_type(rel_section, NULL))
|
switch (get_reloc_type(rel_section, NULL))
|
||||||
{
|
{
|
||||||
case NXFLAT_RELOC_TARGET_UNKNOWN:
|
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:
|
case NXFLAT_RELOC_TARGET_TEXT:
|
||||||
{
|
{
|
||||||
vdbg("Symbol '%s' lies in I-Space\n", rel_sym->name);
|
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;
|
break;
|
||||||
}
|
}
|
||||||
#endif
|
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
|
|
||||||
|
|||||||
@@ -522,7 +522,7 @@ cat ../syscall/syscall.csv ../lib/lib.csv | sort >tmp.csv
|
|||||||
</p>
|
</p>
|
||||||
|
|
||||||
<p><b>NOTE:</b>
|
<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>
|
</p>
|
||||||
<ol>
|
<ol>
|
||||||
<li>
|
<li>
|
||||||
|
|||||||
+41
-1
@@ -12,7 +12,7 @@ nuttx/
|
|||||||
(2) Signals (sched/, arch/)
|
(2) Signals (sched/, arch/)
|
||||||
(2) pthreads (sched/)
|
(2) pthreads (sched/)
|
||||||
(2) C++ Support
|
(2) C++ Support
|
||||||
(5) Binary loaders (binfmt/)
|
(6) Binary loaders (binfmt/)
|
||||||
(17) Network (net/, drivers/net)
|
(17) Network (net/, drivers/net)
|
||||||
(3) USB (drivers/usbdev, drivers/usbhost)
|
(3) USB (drivers/usbdev, drivers/usbhost)
|
||||||
(11) Libraries (lib/)
|
(11) Libraries (lib/)
|
||||||
@@ -395,6 +395,46 @@ o Binary loaders (binfmt/)
|
|||||||
Priority: There are too many references like the above. They will have
|
Priority: There are too many references like the above. They will have
|
||||||
to get fixed as needed for Windows native tool builds.
|
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)
|
o Network (net/, drivers/net)
|
||||||
^^^^^^^^^^^^^^^^^^^^^^^^^^^
|
^^^^^^^^^^^^^^^^^^^^^^^^^^^
|
||||||
|
|
||||||
|
|||||||
@@ -107,11 +107,16 @@ SECTIONS
|
|||||||
|
|
||||||
.data 0x00000000 :
|
.data 0x00000000 :
|
||||||
{
|
{
|
||||||
|
/* In this model, .rodata is access using PC-relative addressing
|
||||||
|
* and, hence, must also reside in the .text section.
|
||||||
|
*/
|
||||||
|
|
||||||
__data_start = . ;
|
__data_start = . ;
|
||||||
*(.rodata)
|
*(.rodata)
|
||||||
*(.rodata1)
|
*(.rodata1)
|
||||||
*(.rodata.*)
|
*(.rodata.*)
|
||||||
*(.gnu.linkonce.r*)
|
*(.gnu.linkonce.r*)
|
||||||
|
|
||||||
*(.data)
|
*(.data)
|
||||||
*(.data1)
|
*(.data1)
|
||||||
*(.data.*)
|
*(.data.*)
|
||||||
|
|||||||
Reference in New Issue
Block a user