diff options
author | patacongo <patacongo@42af7a65-404d-4744-a932-0658087f49c3> | 2012-10-10 19:36:32 +0000 |
---|---|---|
committer | patacongo <patacongo@42af7a65-404d-4744-a932-0658087f49c3> | 2012-10-10 19:36:32 +0000 |
commit | b71fcbb0de3d1e1ad8011303ade8bc38c83486d2 (patch) | |
tree | a7e079e6eb35c02ca4bc048c099c84b4b19ab2c5 | |
parent | 6cb1bc7e67e65faecdafc169b0f897645bb8ea83 (diff) | |
download | px4-firmware-b71fcbb0de3d1e1ad8011303ade8bc38c83486d2.tar.gz px4-firmware-b71fcbb0de3d1e1ad8011303ade8bc38c83486d2.tar.bz2 px4-firmware-b71fcbb0de3d1e1ad8011303ade8bc38c83486d2.zip |
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
-rw-r--r-- | misc/buildroot/ChangeLog | 3 | ||||
-rw-r--r-- | misc/buildroot/toolchain/nxflat/ldnxflat.c | 97 | ||||
-rw-r--r-- | nuttx/Documentation/NuttXNxFlat.html | 2 | ||||
-rw-r--r-- | nuttx/TODO | 42 | ||||
-rw-r--r-- | nuttx/binfmt/libnxflat/gnu-nxflat-gotoff.ld | 5 |
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.*) |