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:
patacongo 2012-10-10 19:36:32 +00:00
parent 6cb1bc7e67
commit b71fcbb0de
5 changed files with 131 additions and 18 deletions

View File

@ -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.

View File

@ -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;

View File

@ -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>

View File

@ -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)
^^^^^^^^^^^^^^^^^^^^^^^^^^^

View File

@ -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.*)