Using NXFLAT in newer gcc

243 views
Skip to first unread message

Герман Цвветков

unread,
Apr 6, 2018, 4:44:33 AM4/6/18
to NuttX
Hello. 
After execute elf from file system, i tried run nxflat, for use less ram memory for external apps. 

I confused, because in different pages of nuttx.org writed radical differen info:

- In wiki page, i read about nxflat is dead in newer versions of gcc
- In doc page, i read what nxflat is alive and can work better then gcc 4.3.3

Where correct information? I need use buildroot toolchain with gcc 4.3.3 or i can work with my regular tools?

German

patacongo

unread,
Apr 7, 2018, 8:52:16 AM4/7/18
to NuttX
I confused, because in different pages of nuttx.org writed radical differen info:

- In wiki page, i read about nxflat is dead in newer versions of gcc
- In doc page, i read what nxflat is alive and can work better then gcc 4.3.3

Where correct information? I need use buildroot toolchain with gcc 4.3.3 or i can work with my regular tools?

I noticed the problem after 4.3.3.  It is clearly a violation of the ARM position-independent data ABI.  Perhaps it has been fixed newer versions?  Perhaps Clang does not have the problem?  I don't know.

Greg

Michael Jung

unread,
Apr 10, 2018, 12:56:19 PM4/10/18
to NuttX
I don't want to pretend that I understand the details, but to me it seems this message might be helpful in this regard:

https://gcc.gnu.org/ml/gcc-help/2015-07/msg00027.html

Thanks!
Michael

Sebastien Lorquet

unread,
Apr 11, 2018, 5:43:41 AM4/11/18
to NuttX
Hello

Looking at how PIC was working I stumbled across this page with the following
useful info:

https://sourceware.org/binutils/docs/ld/ARM.html

The ‘--fix-stm32l4xx-629360’ switch enables a link-time workaround for a bug in
the bus matrix / memory controller for some of the STM32 Cortex-M4 based
products (STM32L4xx). When accessing off-chip memory via the affected bus for
bus reads of 9 words or more, the bus can generate corrupt data and/or abort.
These are only core-initiated accesses (not DMA), and might affect any access:
integer loads such as LDM, POP and floating-point loads such as VLDM, VPOP.
Stores are not affected.

The bug can be avoided by splitting memory accesses into the necessary chunks to
keep bus reads below 8 words.

The workaround is not enabled by default, this is equivalent to use
‘--fix-stm32l4xx-629360=none’. If you know you are using buggy STM32L4xx
hardware, you can enable the workaround by specifying the linker option
‘--fix-stm32l4xx-629360’, or the equivalent ‘--fix-stm32l4xx-629360=default’.


Do we have any configuration with an stm32l4 and external memory?

Sebastien

Michael Jung

unread,
Apr 27, 2018, 1:20:25 PM4/27/18
to NuttX
Hello,

I was trying to figure out whether NXFLAT can be used with newer gcc versions.

On Debian 9 (gcc (Debian 6.3.0-18+deb9u1) 6.3.0 20170516) I had to make the
change shown below to ldnxflat.c to get it to compile:

diff --git a/toolchain/nxflat/ldnxflat.c b/toolchain/nxflat/ldnxflat.c
index b3ff262..9881d98 100644
--- a/toolchain/nxflat/ldnxflat.c
+++ b/toolchain/nxflat/ldnxflat.c
@@ -1559,7 +1559,7 @@ static void dump_symbol(asymbol * psym)
   printf("%c",  psym->flags & BSF_OLD_COMMON ? 'c' : '.');
   printf("%c",  psym->flags & BSF_SECTION_SYM ? 'S' : '.');
   printf("%c",  psym->flags & BSF_WEAK ? 'w' : '.');
-  printf("%c",  psym->flags & BSF_KEEP_G ? 'G' : '.');
+  //printf("%c",  psym->flags & BSF_KEEP_G ? 'G' : '.');
   printf("%c",  psym->flags & BSF_KEEP ? 'K' : '.');
   printf("%c",  psym->flags & BSF_FUNCTION ? 'f' : '.');
   printf("%c",  psym->flags & BSF_DEBUGGING ? 'd' : '.');



My target toolchain is:
arm-none-eabi-gcc (GNU Tools for ARM Embedded Processors) 5.4.1 20160609
(release) [ARM/embedded-5-branch revision 237715]

My target is an NXP PNEV5180B development board, which is based on an NXP LPC1769
MCU.  I copied the nxflat related Make.defs from olimex-lpc1766stk/thttpd-nxflat
and made the following change:

--- configs/olimex-lpc1766stk/thttpd-nxflat/Make.defs    2018-04-07 06:53:07.592971180 +0200
+++ configs/pnev5180b/nxflat/Make.defs    2018-04-27 18:21:15.330837703 +0200
@@ -82,7 +82,7 @@ ARCHCXXFLAGS = -fno-builtin -fno-excepti
 ARCHWARNINGS = -Wall -Wstrict-prototypes -Wshadow -Wundef
 ARCHWARNINGSXX = -Wall -Wshadow -Wundef
 ARCHDEFINES =
-ARCHPICFLAGS = -fpic -msingle-pic-base -mpic-register=r10
+ARCHPICFLAGS = -fpic -msingle-pic-base -mpic-register=r10 -mno-pic-data-is-text-relative
 
 CFLAGS = $(ARCHCFLAGS) $(ARCHWARNINGS) $(ARCHOPTIMIZATION) $(ARCHCPUFLAGS) $(ARCHINCLUDES) $(ARCHDEFINES) $(EXTRADEFINES) -pipe
 CPICFLAGS = $(ARCHPICFLAGS) $(CFLAGS)


I enabled CONFIG_EXAMPLES_NXFLAT to build the romfs image.  I get the results
shown below.  'hello' and 'errno' seem to work fine, 'struct' crashes on me.

Do you think this is sufficient to establish that NXFLAT is working ok with
'-mno-pic-data-is-text-relative'?  Or would you think I should try to debug
the 'struct' crash or do any further investigations?

Thanks!
Michael




ABDF
nxflat_initialize: Registering NXFLAT

NuttShell (NSH)
nsh> mount -t romfs /dev/ram0 /mnt
load_absmodule: Loading mount
nxflat_loadbinary: Loading file: mount
nxflat_init: filename: mount loadinfo: 100047f8
nxflat_init: Failed to open NXFLAT binary mount: 22
nxflat_dumploadinfo: LOAD_INFO:
nxflat_dumploadinfo:   ISPACE:
nxflat_dumploadinfo:     ispace:       00000000
nxflat_dumploadinfo:     entryoffs:    00000000
nxflat_dumploadinfo:     isize:        00000000
nxflat_dumploadinfo:   DSPACE:
nxflat_dumploadinfo:     dspace:       00000000
nxflat_dumploadinfo:     datasize:     00000000
nxflat_dumploadinfo:     bsssize:      00000000
nxflat_dumploadinfo:       (pad):      00000000
nxflat_dumploadinfo:     stacksize:    00000000
nxflat_dumploadinfo:     dsize:        00000000
nxflat_dumploadinfo:   RELOCS:
nxflat_dumploadinfo:     relocstart:   00000000
nxflat_dumploadinfo:     reloccount:   0
nxflat_dumploadinfo:   HANDLES:
nxflat_dumploadinfo:     filfd:        -1
nxflat_loadbinary: Failed to initialize for load of NXFLAT program: -22
exec: ERROR: Failed to load program 'mount': 22
nsh> /mnt/hello
load_absmodule: Loading /mnt/hello
nxflat_loadbinary: Loading file: /mnt/hello
nxflat_init: filename: /mnt/hello loadinfo: 100047f8
nxflat_read: Read 36 bytes from offset 0
nxflat_dumploadinfo: LOAD_INFO:
nxflat_dumploadinfo:   ISPACE:
nxflat_dumploadinfo:     ispace:       00000000
nxflat_dumploadinfo:     entryoffs:    00000050
nxflat_dumploadinfo:     isize:        00000130
nxflat_dumploadinfo:   DSPACE:
nxflat_dumploadinfo:     dspace:       00000000
nxflat_dumploadinfo:     datasize:     000000dc
nxflat_dumploadinfo:     bsssize:      00000000
nxflat_dumploadinfo:       (pad):      00000000
nxflat_dumploadinfo:     stacksize:    00000800
nxflat_dumploadinfo:     dsize:        000000dc
nxflat_dumploadinfo:   RELOCS:
nxflat_dumploadinfo:     relocstart:   0000020c
nxflat_dumploadinfo:     reloccount:   12
nxflat_dumploadinfo:   HANDLES:
nxflat_dumploadinfo:     filfd:        3
nxflat_load: Mapped ISpace (304 bytes) at 00015d24
nxflat_load: Allocated DSpace (268 bytes) at 10004e50
nxflat_read: Read 268 bytes from offset 304
nxflat_load: TEXT: 00015d24 Entry point offset: 00000050 Data offset: 00000130
nxflat_dumploadinfo: LOAD_INFO:
nxflat_dumploadinfo:   ISPACE:
nxflat_dumploadinfo:     ispace:       00015d24
nxflat_dumploadinfo:     entryoffs:    00000050
nxflat_dumploadinfo:     isize:        00000130
nxflat_dumploadinfo:   DSPACE:
nxflat_dumploadinfo:     dspace:       10004de0
nxflat_dumploadinfo:       crefs:      1
nxflat_dumploadinfo:       region:     10004e50
nxflat_dumploadinfo:     datasize:     000000dc
nxflat_dumploadinfo:     bsssize:      00000000
nxflat_dumploadinfo:       (pad):      00000030
nxflat_dumploadinfo:     stacksize:    00000800
nxflat_dumploadinfo:     dsize:        0000010c
nxflat_dumploadinfo:   RELOCS:
nxflat_dumploadinfo:     relocstart:   0000020c
nxflat_dumploadinfo:     reloccount:   12
nxflat_dumploadinfo:   HANDLES:
nxflat_dumploadinfo:     filfd:        3
nxflat_bindimports: Imports offset: 000001fc nimports: 2
nxflat_bindimports: Import[0] (10004f1c) offset: 00000000 func: 00000000
nxflat_bindimports: Bound import[0] (10004f1c) to export 'printf' (0001315d)
nxflat_bindimports: Import[1] (10004f24) offset: 00000007 func: 00000000
nxflat_bindimports: Bound import[1] (10004f24) to export 'puts' (00013181)
nxflat_gotrelocs: offset: 0000020c nrelocs: 12
nxflat_gotrelocs: isize: 00000130 dpsace: 10004e50 relocs: 10004f2c
nxflat_bindrel32i: NXFLAT_RELOC_TYPE_REL32I Offset: 000000cc I-Space: 15d48
nxflat_bindrel32i:   Before: 00000000
nxflat_bindrel32i:   After: 00015d48
nxflat_bindrel32i: NXFLAT_RELOC_TYPE_REL32I Offset: 000000d4 I-Space: 15d48
nxflat_bindrel32i:   Before: 00000007
nxflat_bindrel32i:   After: 00015d4f
nxflat_bindrel32d: NXFLAT_RELOC_TYPE_REL32D Offset: 00000000 D-Space: 10004e50
nxflat_bindrel32d:   Before: 00000028
nxflat_bindrel32d:   After: 10004e78
nxflat_bindrel32d: NXFLAT_RELOC_TYPE_REL32D Offset: 00000004 D-Space: 10004e50
nxflat_bindrel32d:   Before: 0000004d
nxflat_bindrel32d:   After: 10004e9d
nxflat_bindrel32d: NXFLAT_RELOC_TYPE_REL32D Offset: 00000008 D-Space: 10004e50
nxflat_bindrel32d:   Before: 0000005c
nxflat_bindrel32d:   After: 10004eac
nxflat_bindrel32d: NXFLAT_RELOC_TYPE_REL32D Offset: 0000000c D-Space: 10004e50
nxflat_bindrel32d:   Before: 0000006f
nxflat_bindrel32d:   After: 10004ebf
nxflat_bindrel32d: NXFLAT_RELOC_TYPE_REL32D Offset: 00000010 D-Space: 10004e50
nxflat_bindrel32d:   Before: 0000007a
nxflat_bindrel32d:   After: 10004eca
nxflat_bindrel32d: NXFLAT_RELOC_TYPE_REL32D Offset: 00000014 D-Space: 10004e50
nxflat_bindrel32d:   Before: 00000087
nxflat_bindrel32d:   After: 10004ed7
nxflat_bindrel32d: NXFLAT_RELOC_TYPE_REL32D Offset: 00000018 D-Space: 10004e50
nxflat_bindrel32d:   Before: 00000093
nxflat_bindrel32d:   After: 10004ee3
nxflat_bindrel32d: NXFLAT_RELOC_TYPE_REL32D Offset: 0000001c D-Space: 10004e50
nxflat_bindrel32d:   Before: 000000a0
nxflat_bindrel32d:   After: 10004ef0
nxflat_bindrel32d: NXFLAT_RELOC_TYPE_REL32D Offset: 00000020 D-Space: 10004e50
nxflat_bindrel32d:   Before: 000000a7
nxflat_bindrel32d:   After: 10004ef7
nxflat_bindrel32d: NXFLAT_RELOC_TYPE_REL32D Offset: 00000024 D-Space: 10004e50
nxflat_bindrel32d:   Before: 000000b8
nxflat_bindrel32d:   After: 10004f08
load_absmodule: Successfully loaded module /mnt/hello
dump_module: Module:
dump_module:   filename:  /mnt/hello
dump_module:   argv:      0
dump_module:   entrypt:   15d74
dump_module:   mapped:    15d24 size=304
dump_module:   alloc:     10004de0 0 0
dump_module:   stacksize: 2048
dump_module:   unload:    0
exec_module: Executing /mnt/hello
Getting ready to say "Hello, world"

Hello, world!
It has been said.

argc    = 1
argv    = 0x10005834
argv[0] = (0x1000583c) "<noname>"
argv[1] = 0x0
Goodbye, world!
nsh> /mnt/errno
load_absmodule: Loading /mnt/errno
nxflat_loadbinary: Loading file: /mnt/errno
nxflat_init: filename: /mnt/errno loadinfo: 100047f8
nxflat_read: Read 36 bytes from offset 0
nxflat_dumploadinfo: LOAD_INFO:
nxflat_dumploadinfo:   ISPACE:
nxflat_dumploadinfo:     ispace:       00000000
nxflat_dumploadinfo:     entryoffs:    000000a8
nxflat_dumploadinfo:     isize:        00000148
nxflat_dumploadinfo:   DSPACE:
nxflat_dumploadinfo:     dspace:       00000000
nxflat_dumploadinfo:     datasize:     000000d0
nxflat_dumploadinfo:     bsssize:      00000000
nxflat_dumploadinfo:       (pad):      00000000
nxflat_dumploadinfo:     stacksize:    00000800
nxflat_dumploadinfo:     dsize:        000000d0
nxflat_dumploadinfo:   RELOCS:
nxflat_dumploadinfo:     relocstart:   00000218
nxflat_dumploadinfo:     reloccount:   11
nxflat_dumploadinfo:   HANDLES:
nxflat_dumploadinfo:     filfd:        3
nxflat_load: Mapped ISpace (328 bytes) at 00015f84
nxflat_load: Allocated DSpace (252 bytes) at 10004f70
nxflat_read: Read 252 bytes from offset 328
nxflat_load: TEXT: 00015f84 Entry point offset: 000000a8 Data offset: 00000148
nxflat_dumploadinfo: LOAD_INFO:
nxflat_dumploadinfo:   ISPACE:
nxflat_dumploadinfo:     ispace:       00015f84
nxflat_dumploadinfo:     entryoffs:    000000a8
nxflat_dumploadinfo:     isize:        00000148
nxflat_dumploadinfo:   DSPACE:
nxflat_dumploadinfo:     dspace:       10004de0
nxflat_dumploadinfo:       crefs:      1
nxflat_dumploadinfo:       region:     10004f70
nxflat_dumploadinfo:     datasize:     000000d0
nxflat_dumploadinfo:     bsssize:      00000000
nxflat_dumploadinfo:       (pad):      0000002c
nxflat_dumploadinfo:     stacksize:    00000800
nxflat_dumploadinfo:     dsize:        000000fc
nxflat_dumploadinfo:   RELOCS:
nxflat_dumploadinfo:     relocstart:   00000218
nxflat_dumploadinfo:     reloccount:   11
nxflat_dumploadinfo:   HANDLES:
nxflat_dumploadinfo:     filfd:        3
nxflat_bindimports: Imports offset: 000001f0 nimports: 5
nxflat_bindimports: Import[0] (10005018) offset: 00000000 func: 00000000
nxflat_bindimports: Bound import[0] (10005018) to export 'fprintf' (0001126d)
nxflat_bindimports: Import[1] (10005020) offset: 00000008 func: 00000000
nxflat_bindimports: Bound import[1] (10005020) to export 'get_errno_ptr' (00001781)
nxflat_bindimports: Import[2] (10005028) offset: 00000016 func: 00000000
nxflat_bindimports: Bound import[2] (10005028) to export 'sched_getstreams' (0000f145)
nxflat_bindimports: Import[3] (10005030) offset: 00000027 func: 00000000
nxflat_bindimports: Bound import[3] (10005030) to export 'fopen' (00010e99)
nxflat_bindimports: Import[4] (10005038) offset: 0000002d func: 00000000
nxflat_bindimports: Bound import[4] (10005038) to export 'exit' (00001711)
nxflat_gotrelocs: offset: 00000218 nrelocs: 11
nxflat_gotrelocs: isize: 00000148 dpsace: 10004f70 relocs: 10005040
nxflat_bindrel32i: NXFLAT_RELOC_TYPE_REL32I Offset: 000000a8 I-Space: 15fa8
nxflat_bindrel32i:   Before: 00000000
nxflat_bindrel32i:   After: 00015fa8
nxflat_bindrel32i: NXFLAT_RELOC_TYPE_REL32I Offset: 000000b0 I-Space: 15fa8
nxflat_bindrel32i:   Before: 00000008
nxflat_bindrel32i:   After: 00015fb0
nxflat_bindrel32i: NXFLAT_RELOC_TYPE_REL32I Offset: 000000b8 I-Space: 15fa8
nxflat_bindrel32i:   Before: 00000016
nxflat_bindrel32i:   After: 00015fbe
nxflat_bindrel32i: NXFLAT_RELOC_TYPE_REL32I Offset: 000000c0 I-Space: 15fa8
nxflat_bindrel32i:   Before: 00000027
nxflat_bindrel32i:   After: 00015fcf
nxflat_bindrel32i: NXFLAT_RELOC_TYPE_REL32I Offset: 000000c8 I-Space: 15fa8
nxflat_bindrel32i:   Before: 0000002d
nxflat_bindrel32i:   After: 00015fd5
nxflat_bindrel32d: NXFLAT_RELOC_TYPE_REL32D Offset: 00000000 D-Space: 10004f70
nxflat_bindrel32d:   Before: 00000028
nxflat_bindrel32d:   After: 10004f98
nxflat_bindrel32d: NXFLAT_RELOC_TYPE_REL32D Offset: 00000004 D-Space: 10004f70
nxflat_bindrel32d:   Before: 00000040
nxflat_bindrel32d:   After: 10004fb0
nxflat_bindrel32d: NXFLAT_RELOC_TYPE_REL32D Offset: 00000008 D-Space: 10004f70
nxflat_bindrel32d:   Before: 00000058
nxflat_bindrel32d:   After: 10004fc8
nxflat_bindrel32d: NXFLAT_RELOC_TYPE_REL32D Offset: 0000000c D-Space: 10004f70
nxflat_bindrel32d:   Before: 00000018
nxflat_bindrel32d:   After: 10004f88
nxflat_bindrel32d: NXFLAT_RELOC_TYPE_REL32D Offset: 00000010 D-Space: 10004f70
nxflat_bindrel32d:   Before: 0000005a
nxflat_bindrel32d:   After: 10004fca
nxflat_bindrel32d: NXFLAT_RELOC_TYPE_REL32D Offset: 00000014 D-Space: 10004f70
nxflat_bindrel32d:   Before: 00000081
nxflat_bindrel32d:   After: 10004ff1
load_absmodule: Successfully loaded module /mnt/errno
dump_module: Module:
dump_module:   filename:  /mnt/errno
dump_module:   argv:      0
dump_module:   entrypt:   1602c
dump_module:   mapped:    15f84 size=328
dump_module:   alloc:     10004de0 0 0
dump_module:   stacksize: 2048
dump_module:   unload:    0
exec_module: Executing /mnt/errno
Hello, World on stdout
Hello, World on stderr
We failed to open "aflav-sautga-ay!" errno is 22
nsh> /mnt/struct
load_absmodule: Loading /mnt/struct
nxflat_loadbinary: Loading file: /mnt/struct
nxflat_init: filename: /mnt/struct loadinfo: 100047f8
nxflat_read: Read 36 bytes from offset 0
nxflat_dumploadinfo: LOAD_INFO:
nxflat_dumploadinfo:   ISPACE:
nxflat_dumploadinfo:     ispace:       00000000
nxflat_dumploadinfo:     entryoffs:    00000068
nxflat_dumploadinfo:     isize:        000001d4
nxflat_dumploadinfo:   DSPACE:
nxflat_dumploadinfo:     dspace:       00000000
nxflat_dumploadinfo:     datasize:     0000015c
nxflat_dumploadinfo:     bsssize:      00000000
nxflat_dumploadinfo:       (pad):      00000000
nxflat_dumploadinfo:     stacksize:    00000800
nxflat_dumploadinfo:     dsize:        0000015c
nxflat_dumploadinfo:   RELOCS:
nxflat_dumploadinfo:     relocstart:   00000330
nxflat_dumploadinfo:     reloccount:   21
nxflat_dumploadinfo:   HANDLES:
nxflat_dumploadinfo:     filfd:        3
nxflat_load: Mapped ISpace (468 bytes) at 000161f4
nxflat_load: Allocated DSpace (432 bytes) at 10005080
nxflat_read: Read 432 bytes from offset 468
nxflat_load: TEXT: 000161f4 Entry point offset: 00000068 Data offset: 000001d4
nxflat_dumploadinfo: LOAD_INFO:
nxflat_dumploadinfo:   ISPACE:
nxflat_dumploadinfo:     ispace:       000161f4
nxflat_dumploadinfo:     entryoffs:    00000068
nxflat_dumploadinfo:     isize:        000001d4
nxflat_dumploadinfo:   DSPACE:
nxflat_dumploadinfo:     dspace:       10004de0
nxflat_dumploadinfo:       crefs:      1
nxflat_dumploadinfo:       region:     10005080
nxflat_dumploadinfo:     datasize:     0000015c
nxflat_dumploadinfo:     bsssize:      00000000
nxflat_dumploadinfo:       (pad):      00000054
nxflat_dumploadinfo:     stacksize:    00000800
nxflat_dumploadinfo:     dsize:        000001b0
nxflat_dumploadinfo:   RELOCS:
nxflat_dumploadinfo:     relocstart:   00000330
nxflat_dumploadinfo:     reloccount:   21
nxflat_dumploadinfo:   HANDLES:
nxflat_dumploadinfo:     filfd:        3
nxflat_bindimports: Imports offset: 00000318 nimports: 1
nxflat_bindimports: Import[0] (100051c4) offset: 0000002c func: 00000000
nxflat_bindimports: Bound import[0] (100051c4) to export 'printf' (0001315d)
nxflat_gotrelocs: offset: 00000330 nrelocs: 21
nxflat_gotrelocs: isize: 000001d4 dpsace: 10005080 relocs: 100051dc
nxflat_bindrel32i: NXFLAT_RELOC_TYPE_REL32I Offset: 00000144 I-Space: 16218
nxflat_bindrel32i:   Before: 0000002c
nxflat_bindrel32i:   After: 00016244
nxflat_bindrel32d: NXFLAT_RELOC_TYPE_REL32D Offset: 00000150 D-Space: 10005080
nxflat_bindrel32d:   Before: 00000140
nxflat_bindrel32d:   After: 100051c0
nxflat_bindrel32d: NXFLAT_RELOC_TYPE_REL32D Offset: 00000154 D-Space: 10005080
nxflat_bindrel32d:   Before: 00000044
nxflat_bindrel32d:   After: 100050c4
nxflat_bindrel32i: NXFLAT_RELOC_TYPE_REL32I Offset: 00000158 I-Space: 16218
nxflat_bindrel32i:   Before: 00000000
nxflat_bindrel32i:   After: 00016218
nxflat_bindrel32d: NXFLAT_RELOC_TYPE_REL32D Offset: 00000000 D-Space: 10005080
nxflat_bindrel32d:   Before: 00000048
nxflat_bindrel32d:   After: 100050c8
nxflat_bindrel32d: NXFLAT_RELOC_TYPE_REL32D Offset: 00000004 D-Space: 10005080
nxflat_bindrel32d:   Before: 0000014c
nxflat_bindrel32d:   After: 100051cc
nxflat_bindrel32d: NXFLAT_RELOC_TYPE_REL32D Offset: 00000008 D-Space: 10005080
nxflat_bindrel32d:   Before: 0000006a
nxflat_bindrel32d:   After: 100050ea
nxflat_bindrel32d: NXFLAT_RELOC_TYPE_REL32D Offset: 0000000c D-Space: 10005080
nxflat_bindrel32d:   Before: 0000007f
nxflat_bindrel32d:   After: 100050ff
nxflat_bindrel32d: NXFLAT_RELOC_TYPE_REL32D Offset: 00000010 D-Space: 10005080
nxflat_bindrel32d:   Before: 00000065
nxflat_bindrel32d:   After: 100050e5
nxflat_bindrel32d: NXFLAT_RELOC_TYPE_REL32D Offset: 00000014 D-Space: 10005080
nxflat_bindrel32d:   Before: 00000060
nxflat_bindrel32d:   After: 100050e0
nxflat_bindrel32d: NXFLAT_RELOC_TYPE_REL32D Offset: 00000018 D-Space: 10005080
nxflat_bindrel32d:   Before: 00000096
nxflat_bindrel32d:   After: 10005116
nxflat_bindrel32d: NXFLAT_RELOC_TYPE_REL32D Offset: 0000001c D-Space: 10005080
nxflat_bindrel32d:   Before: 00000140
nxflat_bindrel32d:   After: 100051c0
nxflat_bindrel32d: NXFLAT_RELOC_TYPE_REL32D Offset: 00000020 D-Space: 10005080
nxflat_bindrel32d:   Before: 000000ab
nxflat_bindrel32d:   After: 1000512b
nxflat_bindrel32d: NXFLAT_RELOC_TYPE_REL32D Offset: 00000024 D-Space: 10005080
nxflat_bindrel32d:   Before: 000000c1
nxflat_bindrel32d:   After: 10005141
nxflat_bindrel32d: NXFLAT_RELOC_TYPE_REL32D Offset: 00000028 D-Space: 10005080
nxflat_bindrel32d:   Before: 00000044
nxflat_bindrel32d:   After: 100050c4
nxflat_bindrel32d: NXFLAT_RELOC_TYPE_REL32D Offset: 0000002c D-Space: 10005080
nxflat_bindrel32d:   Before: 000000d7
nxflat_bindrel32d:   After: 10005157
nxflat_bindrel32d: NXFLAT_RELOC_TYPE_REL32D Offset: 00000030 D-Space: 10005080
nxflat_bindrel32d:   Before: 000000ed
nxflat_bindrel32d:   After: 1000516d
nxflat_bindrel32i: NXFLAT_RELOC_TYPE_REL32I Offset: 00000034 I-Space: 16218
nxflat_bindrel32i:   Before: 00000000
nxflat_bindrel32i:   After: 00016218
nxflat_bindrel32d: NXFLAT_RELOC_TYPE_REL32D Offset: 00000038 D-Space: 10005080
nxflat_bindrel32d:   Before: 00000106
nxflat_bindrel32d:   After: 10005186
nxflat_bindrel32d: NXFLAT_RELOC_TYPE_REL32D Offset: 0000003c D-Space: 10005080
nxflat_bindrel32d:   Before: 0000011c
nxflat_bindrel32d:   After: 1000519c
nxflat_bindrel32d: NXFLAT_RELOC_TYPE_REL32D Offset: 00000040 D-Space: 10005080
nxflat_bindrel32d:   Before: 00000134
nxflat_bindrel32d:   After: 100051b4
load_absmodule: Successfully loaded module /mnt/struct
dump_module: Module:
dump_module:   filename:  /mnt/struct
dump_module:   argv:      0
dump_module:   entrypt:   1625c
dump_module:   mapped:    161f4 size=468
dump_module:   alloc:     10004de0 0 0
dump_module:   stacksize: 2048
dump_module:   unload:    0
up_hardfault: PANIC!!! Hard fault: 40000000
up_assert: Assertion failed at file:armv7-m/up_hardfault.c line: 171
up_dumpstate: sp:         10005a48
up_dumpstate: stack base: 10005b00
up_dumpstate: stack size: 000007e4
up_stackdump: 10005a40: 00013e01 000007e4 000000ab 10005a68 10005a68 00003b5d 00000000 10005a68
up_stackdump: 10005a60: 00000003 00000319 00000000 00000d61 00000d21 10001c58 00000003 00000319
up_stackdump: 10005a80: 00000000 10005a98 00016218 00000000 00000000 00000253 10005ae0 00000000
up_stackdump: 10005aa0: 100051cc 00016218 00000000 00000000 00000000 00000000 10005080 00000000
up_stackdump: 10005ac0: 00000017 00000000 00007fff 00016218 0001315d 00016379 00016218 60000000
up_stackdump: 10005ae0: 1000519c 1000516d 00000000 00000101 00000000 00001709 00000000 00000000
up_registerdump: R0: 00000017 00000000 00007fff 00016218 100051cc 00016218 00000000 00000000
up_registerdump: R8: 00000000 00000000 10005080 00000000 0001315d 10005ae0 00016379 00016218
up_registerdump: xPSR: 60000000 PRIMASK: 00000000 CONTROL: 00000000

patacongo

unread,
Apr 27, 2018, 1:53:40 PM4/27/18
to NuttX
Hi, Michael,


> I was trying to figure out whether NXFLAT can be used with newer gcc versions.
>
> On Debian 9 (gcc (Debian 6.3.0-18+deb9u1) 6.3.0 20170516) I had to make the
> change shown below to ldnxflat.c to get it to compile:
>
> -  printf("%c",  psym->flags & BSF_KEEP_G ? 'G' : '.');
> +  //printf("%c",  psym->flags & BSF_KEEP_G ? 'G' : '.');

Hmmm.. I wonder if other flags have been added?  We should change the code like

#ifdef BSF_KEEP_G

  printf("%c",  psym->flags & BSF_KEEP_G ? 'G' : '.');
#endif

Then it would work with any version of binutils.


> -ARCHPICFLAGS = -fpic -msingle-pic-base -mpic-register=r10
> +ARCHPICFLAGS = -fpic -msingle-pic-base -mpic-register=r10 -mno-pic-data-is-text-relative

That is a remarkably small change to get it work!

 
> I enabled CONFIG_EXAMPLES_NXFLAT to build the romfs image.  I get the results
> shown below.  'hello' and 'errno' seem to work fine, 'struct' crashes on me.
>
> Do you think this is sufficient to establish that NXFLAT is working ok with
> '-mno-pic-data-is-text-relative'?  Or would you think I should try to debug
> the 'struct' crash or do any further investigations?

Yes, just getting a successful build is proof that NXFLAT is working.  The crash indicates that something is different than before, however, and would eventually need to be understood, but that is probably not critical now for what you are doing.  If that crash is a systematic problem, it will come back later however.

It would be great to have NXFLAT working again.  This has some limitations (particularly with regard to the use of function pointers between different modules), but offers a lot of benefits for embedded systems:

1. XIP (eXecute In Place): You can execute loadable modules in FLASH in NOR or QSPI FLASH without copying to memory using the ROMFS file system.  That saves a lot of RAM!

2. You can have multiple copies of the same XIP program running with advantage that they share the common XIP image in the ROMFS file system, but each has a unique .bss and .data allocated separately.  With ELF modules the .text has to be copied to RAM and linked uniquely for each instance of the program.

But NXFLAT is special in this way:  All linking is done in the .bss and .data sections, no relocation is necessary in the .text section.  Each instance of an NXFLAT program uses the PIC register (r10 as you set it up) to reference the instance-specific data.  So all data accesses are PIC relative to r10.

That is the part that was broken.  GCC was generating .text-relative data references even when compiled for position independent code.  So it was addressing relative to the PC, not to R10.  That is a violation of the ARM ABI and that is what broke NXFLAT.  I am happy to see that it is working again (even if there are some issues).

Thanks for checking that out,
Greg

Valmantas Palikša

unread,
Mar 9, 2019, 7:07:06 AM3/9/19
to NuttX
I've managed to find out why nxflat is hardfaulting with function pointers. It appears that gcc or linker for some reason generates non-thumb address for the callback function.

For example the caller function:
caller loads a function pointer to r0 and calls a function which is below.

08100209: 0x0000b580   push    {r3, lr}
0810020b: 0x00004708   blx     r0
0810020d: 0x0000bd00   pop     {r3, pc}

r0 here is generated 0x81001f4 which is an ARM address. If I change in debugger to 0x81001f5 the function is called succesfully in thumb mode.


It appears that -mno-thumb-interwork does not help.

Perhaps anyone has any clues how to workaround this?

Gregory Nutt

unread,
Mar 9, 2019, 9:03:36 AM3/9/19
to nu...@googlegroups.com

I've managed to find out why nxflat is hardfaulting with function pointers. It appears that gcc or linker for some reason generates non-thumb address for the callback function.

For example the caller function:
caller loads a function pointer to r0 and calls a function which is below.

08100209: 0x0000b580   push    {r3, lr}
0810020b: 0x00004708   blx     r0
0810020d: 0x0000bd00   pop     {r3, pc}

r0 here is generated 0x81001f4 which is an ARM address. If I change in debugger to 0x81001f5 the function is called succesfully in thumb mode.

I suspect that there is a problem with the way that your mknxflat toolchain was built.  If you build it for an ARM target, then it will generate only ARM code.  If you built if for ARMv7-M, it will generate only thumb2 code.  That cannot be changed at compile time and is hard-coded when the NxFLAT tools are built.

Valmantas Palikša

unread,
Mar 9, 2019, 12:06:02 PM3/9/19
to NuttX
I've checked the toolchain build, it appears nxflat tools are built with THUMB support properly.

Currently I have this code:

static const char g_nonexistent[] = "aflav-sautga-ay";

/****************************************************************************
 * Public Functions
 ****************************************************************************/
//defined in test.c
void callme(void(*cb)()); //caller
void func(); //callback

int main(int argc, char **argv)
{
  FILE *test_stream;

  /* Try using stdout and stderr explicitly.  These are global variables
   * exported from the base code.
   */

  fprintf(stdout, "Hello, World on stdout\n");
  fprintf(stderr, "Hello, World on stderr\n");
  
  callme(func);


  return 0;
}

Build output:
CC: errno.c
arm-none-eabi-gcc -c -fpic -msingle-pic-base -mpic-register=r10 -mno-pic-data-is-text-relative -fno-builtin -Wall -Wshadow -Wundef -g -Og -fno-strict-aliasing -fno-strength-reduce -nostartfiles -nostdlib -mno-thumb-interwork -fomit-frame-pointer -ffunction-sections -fdata-sections -mcpu=cortex-m7 -mthumb -mfpu=fpv5-d16 -mfloat-abi=hard -isystem /home/walmis/Electronics/DancerECU/nuttx/nuttx/include errno.c -o errno.o
errno.c: In function 'main':
errno.c:60:9: warning: unused variable 'test_stream' [-Wunused-variable]
   FILE *test_stream;
         ^~~~~~~~~~~
At top level:
errno.c:48:19: warning: 'g_nonexistent' defined but not used [-Wunused-const-variable=]
 static const char g_nonexistent[] = "aflav-sautga-ay";
                   ^~~~~~~~~~~~~
CC: test.c
arm-none-eabi-gcc -c -fpic -msingle-pic-base -mpic-register=r10 -mno-pic-data-is-text-relative -fno-builtin -Wall -Wshadow -Wundef -g -Og -fno-strict-aliasing -fno-strength-reduce -nostartfiles -nostdlib -mno-thumb-interwork -fomit-frame-pointer -ffunction-sections -fdata-sections -mcpu=cortex-m7 -mthumb -mfpu=fpv5-d16 -mfloat-abi=hard -isystem /home/walmis/Electronics/DancerECU/nuttx/nuttx/include test.c -o test.o
CC: testcpp.cpp
arm-none-eabi-g++ -c -fpic -msingle-pic-base -mpic-register=r10 -mno-pic-data-is-text-relative -fno-builtin -Wall -Wshadow -Wundef -g -Og -fno-strict-aliasing -fno-strength-reduce -nostartfiles -nostdlib -mno-thumb-interwork -fomit-frame-pointer -ffunction-sections -fdata-sections -mcpu=cortex-m7 -mthumb -mfpu=fpv5-d16 -mfloat-abi=hard -isystem /home/walmis/Electronics/DancerECU/nuttx/nuttx/include -nostartfiles -nostdlib -fno-rtti -fno-exceptions -isystem /home/walmis/Electronics/DancerECU/nuttx/nuttx/include/libcxx testcpp.cpp -o testcpp.o
LD: errno.o
arm-none-eabi-gcc -nostartfiles -nostdlib -mno-thumb-interwork -fomit-frame-pointer -ffunction-sections -fdata-sections -mcpu=cortex-m7 -mthumb -mfpu=fpv5-d16 -mfloat-abi=hard -isystem /home/walmis/Electronics/DancerECU/nuttx/nuttx/include -Wl,-r,-d,-warn-common -o errno.r1 errno.o test.o testcpp.o
MK: errno.r1
mknxflat -o errno-thunk.S errno.r1
AS: errno-thunk.S
arm-none-eabi-gcc -c -nostartfiles -nostdlib -mno-thumb-interwork -fomit-frame-pointer -ffunction-sections -fdata-sections -mcpu=cortex-m7 -mthumb -mfpu=fpv5-d16 -mfloat-abi=hard -isystem /home/walmis/Electronics/DancerECU/nuttx/nuttx/include -fpic -msingle-pic-base -mpic-register=r10 -mno-pic-data-is-text-relative -fno-builtin -Wall -Wshadow -Wundef -g -Og -fno-strict-aliasing -fno-strength-reduce errno-thunk.S -o errno-thunk.o
LD: errno-thunk.o
arm-none-eabi-gcc -nostartfiles -nostdlib -mno-thumb-interwork -fomit-frame-pointer -ffunction-sections -fdata-sections -mcpu=cortex-m7 -mthumb -mfpu=fpv5-d16 -mfloat-abi=hard -isystem /home/walmis/Electronics/DancerECU/nuttx/nuttx/include -Wl,-T/home/walmis/Electronics/DancerECU/nuttx/nuttx/binfmt/libnxflat/gnu-nxflat-gotoff.ld,-no-check-sections,-r,-d,-warn-common -o errno.r2 errno.o test.o  testcpp.o   errno-thunk.o
LD: errno.r2
ldnxflat -v -e main -s 2048 -o errno errno.r2
Reading section .text
Reading section .data
Reading section .bss
Reading section .comment
Reading section .ARM.attributes
Reading section .debug_abbrev
Reading section .debug_info
Reading section .debug_line
Reading section .debug_aranges
Reading section .debug_loc
Reading section .debug_ranges
Reading section .debug_str
Reading section .debug_frame
INPUT SECTIONS:
SECT LOW      HIGH     SIZE
TEXT 00000000 000000bc 000000bc
DATA 00000000 00000058 00000058
BSS  00000058 00000058 00000000
TEXT:       [ .text ]
DATA:       [ .data ]
BSS:       [ .bss ]
Sym [               .data] base 00000000, top 00000004
Sym [                .bss] base 00000058, top 0000005c
Sym [            .comment] base 00000000, top 00000004
Sym [     .ARM.attributes] base 00000000, top 00000004
Sym [       .debug_abbrev] base 00000000, top 00000004
Sym [         .debug_info] base 00000000, top 00000004
Sym [         .debug_line] base 00000000, top 00000004
Sym [      .debug_aranges] base 00000000, top 00000004
Sym [          .debug_loc] base 00000000, top 00000004
Sym [       .debug_ranges] base 00000000, top 00000004
Sym [          .debug_str] base 00000000, top 00000004
Sym [        .debug_frame] base 00000000, top 00000004
Sym [             errno.c] base 00000000, top 00000004
Sym [                  $d] base 00000000, top 00000004
Sym [                .LC0] base 00000000, top 00000004
Sym [                .LC1] base 00000018, top 0000001c
Sym [              test.c] base 00000000, top 00000004
Sym [                  $d] base 00000030, top 00000034
Sym [                .LC0] base 00000030, top 00000034
Sym [         testcpp.cpp] base 00000000, top 00000004
Sym [                  $d] base 00000038, top 0000003c
Sym [                .LC0] base 00000038, top 0000003c
Sym [       errno-thunk.o] base 00000000, top 00000004
Sym [     __dynimport0000] base 00000000, top 00000007
Sym [     __dynimport0001] base 00000007, top 0000000f
Sym [     __dynimport0002] base 0000000f, top 00000020
Sym [                  $d] base 00000040, top 00000044
WARNING -- Symbols '$d'[ .data] and '__dyninfo0000'[ .data] OVERLAP!
WARNING --   Sym '$d' base 00000040, top 00000044
WARNING --   Sym '__dyninfo0000' base 00000040, top 00000048
WARNING -- Symbols '$d'[ .data] and '__dynimport_begin'[ .data] OVERLAP!
WARNING --   Sym '$d' base 00000040, top 00000044
WARNING --   Sym '__dynimport_begin' base 00000040, top 00000058
Sym [       __dyninfo0000] base 00000040, top 00000048
WARNING -- Symbols '__dyninfo0000'[ .data] and '__dynimport_begin'[ .data] OVERLAP!
WARNING --   Sym '__dyninfo0000' base 00000040, top 00000048
WARNING --   Sym '__dynimport_begin' base 00000040, top 00000058
Sym [       __dyninfo0001] base 00000048, top 00000050
WARNING -- Symbols '__dyninfo0001'[ .data] and '__dynimport_begin'[ .data] OVERLAP!
WARNING --   Sym '__dyninfo0001' base 00000048, top 00000050
WARNING --   Sym '__dynimport_begin' base 00000040, top 00000058
Sym [       __dyninfo0002] base 00000050, top 00000058
WARNING -- Symbols '__dyninfo0002'[ .data] and '__dynimport_begin'[ .data] OVERLAP!
WARNING --   Sym '__dyninfo0002' base 00000050, top 00000058
WARNING --   Sym '__dynimport_begin' base 00000040, top 00000058
Sym [              printf] base 00000020, top 00000030
Sym [          _ctors_end] base 00000058, top 0000005c
Sym [     __dynimport_end] base 00000058, top 0000005c
Sym [   __dynimport_begin] base 00000040, top 00000058
Sym [               edata] base 00000060, top 00000064
Sym [          _dtors_end] base 00000058, top 0000005c
Sym [             fprintf] base 00000030, top 00000040
Sym [                 end] base 00000060, top 00000064
Sym [        _ctors_start] base 00000058, top 0000005c
Sym [    sched_getstreams] base 00000040, top 00000050
Sym [         __bss_start] base 00000058, top 0000005c
Sym [                main] base 00000050, top 0000008c
Sym [             cpptest] base 000000a8, top 000000bc
Sym [                func] base 0000008c, top 000000a0
Sym [              _edata] base 00000058, top 0000005c
Sym [                _end] base 00000060, top 00000064
Sym [        __data_start] base 00000000, top 00000004
Sym [              callme] base 000000a0, top 000000a6
Sym [        _dtors_start] base 00000058, top 0000005c
Sym [               .data] base 00000000, top 00000004
Sym [                .bss] base 00000058, top 0000005c
Sym [            .comment] base 00000000, top 00000004
Sym [     .ARM.attributes] base 00000000, top 00000004
Sym [       .debug_abbrev] base 00000000, top 00000004
Sym [         .debug_info] base 00000000, top 00000004
Sym [         .debug_line] base 00000000, top 00000004
Sym [      .debug_aranges] base 00000000, top 00000004
Sym [          .debug_loc] base 00000000, top 00000004
Sym [       .debug_ranges] base 00000000, top 00000004
Sym [          .debug_str] base 00000000, top 00000004
Sym [        .debug_frame] base 00000000, top 00000004
Sym [             errno.c] base 00000000, top 00000004
Sym [                  $d] base 00000000, top 00000004
Sym [                .LC0] base 00000000, top 00000004
Sym [                .LC1] base 00000018, top 0000001c
Sym [              test.c] base 00000000, top 00000004
Sym [                  $d] base 00000030, top 00000034
Sym [                .LC0] base 00000030, top 00000034
Sym [         testcpp.cpp] base 00000000, top 00000004
Sym [                  $d] base 00000038, top 0000003c
Sym [                .LC0] base 00000038, top 0000003c
Sym [       errno-thunk.o] base 00000000, top 00000004
Sym [     __dynimport0000] base 00000000, top 00000007
Sym [     __dynimport0001] base 00000007, top 0000000f
Sym [     __dynimport0002] base 0000000f, top 00000020
Sym [                  $d] base 00000040, top 00000044
WARNING -- Symbols '$d'[ .data] and '__dyninfo0000'[ .data] OVERLAP!
WARNING --   Sym '$d' base 00000040, top 00000044
WARNING --   Sym '__dyninfo0000' base 00000040, top 00000048
WARNING -- Symbols '$d'[ .data] and '__dynimport_begin'[ .data] OVERLAP!
WARNING --   Sym '$d' base 00000040, top 00000044
WARNING --   Sym '__dynimport_begin' base 00000040, top 00000058
Sym [       __dyninfo0000] base 00000040, top 00000048
WARNING -- Symbols '__dyninfo0000'[ .data] and '__dynimport_begin'[ .data] OVERLAP!
WARNING --   Sym '__dyninfo0000' base 00000040, top 00000048
WARNING --   Sym '__dynimport_begin' base 00000040, top 00000058
Sym [       __dyninfo0001] base 00000048, top 00000050
WARNING -- Symbols '__dyninfo0001'[ .data] and '__dynimport_begin'[ .data] OVERLAP!
WARNING --   Sym '__dyninfo0001' base 00000048, top 00000050
WARNING --   Sym '__dynimport_begin' base 00000040, top 00000058
Sym [       __dyninfo0002] base 00000050, top 00000058
WARNING -- Symbols '__dyninfo0002'[ .data] and '__dynimport_begin'[ .data] OVERLAP!
WARNING --   Sym '__dyninfo0002' base 00000050, top 00000058
WARNING --   Sym '__dynimport_begin' base 00000040, top 00000058
Sym [              printf] base 00000020, top 00000030
Sym [          _ctors_end] base 00000058, top 0000005c
Sym [     __dynimport_end] base 00000058, top 0000005c
Sym [   __dynimport_begin] base 00000040, top 00000058
Sym [               edata] base 00000060, top 00000064
Sym [          _dtors_end] base 00000058, top 0000005c
Sym [             fprintf] base 00000030, top 00000040
Sym [                 end] base 00000060, top 00000064
Sym [        _ctors_start] base 00000058, top 0000005c
Sym [    sched_getstreams] base 00000040, top 00000050
Sym [         __bss_start] base 00000058, top 0000005c
Sym [                main] base 00000050, top 0000008c
Sym [             cpptest] base 000000a8, top 000000bc
Sym [                func] base 0000008c, top 000000a0
Sym [              _edata] base 00000058, top 0000005c
Sym [                _end] base 00000060, top 00000064
Sym [        __data_start] base 00000000, top 00000004
Sym [              callme] base 000000a0, top 000000a6
Sym [        _dtors_start] base 00000058, top 0000005c
sym[0000] Sym[                   .text] @ 0000 align            sz 0000 tp 03  |........S....d.l|
sym[0001] Sym[                   .data] @ 0000 align            sz 0000 tp 03  |........S....d.l|
sym[0002] Sym[                    .bss] @ 0000 align            sz 0000 tp 03  |........S....d.l|
sym[0003] Sym[                .comment] @ 0000 align            sz 0000 tp 03  |........S....d.l|
sym[0004] Sym[         .ARM.attributes] @ 0000 align            sz 0000 tp 03  |........S....d.l|
sym[0005] Sym[           .debug_abbrev] @ 0000 align            sz 0000 tp 03  |........S....d.l|
sym[0006] Sym[             .debug_info] @ 0000 align            sz 0000 tp 03  |........S....d.l|
sym[0007] Sym[             .debug_line] @ 0000 align            sz 0000 tp 03  |........S....d.l|
sym[0008] Sym[          .debug_aranges] @ 0000 align            sz 0000 tp 03  |........S....d.l|
sym[0009] Sym[              .debug_loc] @ 0000 align            sz 0000 tp 03  |........S....d.l|
sym[0010] Sym[           .debug_ranges] @ 0000 align            sz 0000 tp 03  |........S....d.l|
sym[0011] Sym[              .debug_str] @ 0000 align            sz 0000 tp 03  |........S....d.l|
sym[0012] Sym[            .debug_frame] @ 0000 align            sz 0000 tp 03  |........S....d.l|
sym[0013] Sym[                 errno.c] @ 0000 align            sz 0000 tp 04  |..F..........d.l|
sym[0014] Sym[                      $t] @ 0050 align            sz 0000 tp 00  |...........K...l|
sym[0015] Sym[                      $d] @ 0080 align            sz 0000 tp 00  |...........K...l|
sym[0016] Sym[                      $d] @ 0000 align            sz 0000 tp 00  |...........K...l|
sym[0017] Sym[                    .LC0] @ 0000 align            sz 0000 tp 00  |...............l|
sym[0018] Sym[                    .LC1] @ 0018 align            sz 0000 tp 00  |...............l|
sym[0019] Sym[                  test.c] @ 0000 align            sz 0000 tp 04  |..F..........d.l|
sym[0020] Sym[                      $t] @ 008c align            sz 0000 tp 00  |...........K...l|
sym[0021] Sym[                      $d] @ 009c align            sz 0000 tp 00  |...........K...l|
sym[0022] Sym[                      $t] @ 00a0 align            sz 0000 tp 00  |...........K...l|
sym[0023] Sym[                      $d] @ 0030 align            sz 0000 tp 00  |...........K...l|
sym[0024] Sym[                    .LC0] @ 0030 align            sz 0000 tp 00  |...............l|
sym[0025] Sym[             testcpp.cpp] @ 0000 align            sz 0000 tp 04  |..F..........d.l|
sym[0026] Sym[                      $t] @ 00a8 align            sz 0000 tp 00  |...........K...l|
sym[0027] Sym[                      $d] @ 00b8 align            sz 0000 tp 00  |...........K...l|
sym[0028] Sym[                      $d] @ 0038 align            sz 0000 tp 00  |...........K...l|
sym[0029] Sym[                    .LC0] @ 0038 align            sz 0000 tp 00  |...............l|
sym[0030] Sym[           errno-thunk.o] @ 0000 align            sz 0000 tp 04  |..F..........d.l|
sym[0031] Sym[         __dynimport0000] @ 0000 align            sz 0007 tp 01  |O..............l|
sym[0032] Sym[                      $d] @ 0000 align            sz 0000 tp 00  |...........K...l|
sym[0033] Sym[         __dynimport0001] @ 0007 align            sz 0008 tp 01  |O..............l|
sym[0034] Sym[         __dynimport0002] @ 000f align            sz 0011 tp 01  |O..............l|
sym[0035] Sym[                      $d] @ 0040 align            sz 0000 tp 00  |...........K...l|
sym[0036] Sym[           __dyninfo0000] @ 0040 align            sz 0008 tp 01  |O..............l|
sym[0037] Sym[           __dyninfo0001] @ 0048 align            sz 0008 tp 01  |O..............l|
sym[0038] Sym[           __dyninfo0002] @ 0050 align            sz 0008 tp 01  |O..............l|
sym[0039] Sym[                      $t] @ 0020 align            sz 0000 tp 00  |...........K...l|
sym[0040] Sym[                      $d] @ 002c align            sz 0000 tp 00  |...........K...l|
sym[0041] Sym[                      $t] @ 0030 align            sz 0000 tp 00  |...........K...l|
sym[0042] Sym[                      $d] @ 003c align            sz 0000 tp 00  |...........K...l|
sym[0043] Sym[                      $t] @ 0040 align            sz 0000 tp 00  |...........K...l|
sym[0044] Sym[                      $d] @ 004c align            sz 0000 tp 00  |...........K...l|
sym[0045] Sym[                  printf] @ 0020 align            sz 0010 tp 12  |............f.g.|
sym[0046] Sym[                  _etext] @ 00bc align            sz 0000 tp 10  |..............g.|
sym[0047] Sym[              _ctors_end] @ 0058 align            sz 0000 tp 10  |..............g.|
sym[0048] Sym[         __dynimport_end] @ 0058 align            sz 0000 tp 11  |O.............g.|
sym[0049] Sym[       __dynimport_begin] @ 0040 align            sz 0018 tp 11  |O.............g.|
sym[0050] Sym[                   edata] @ 0060 align            sz 0000 tp 10  |..............g.|
sym[0051] Sym[              _dtors_end] @ 0058 align            sz 0000 tp 10  |..............g.|
sym[0052] Sym[                 fprintf] @ 0030 align            sz 0010 tp 12  |............f.g.|
sym[0053] Sym[                     end] @ 0008 align            sz 0000 tp 10  |..............g.|
sym[0054] Sym[            _ctors_start] @ 0058 align            sz 0000 tp 10  |..............g.|
sym[0055] Sym[        sched_getstreams] @ 0040 align            sz 0010 tp 12  |............f.g.|
sym[0056] Sym[             __bss_start] @ 0058 align            sz 0000 tp 10  |..............g.|
sym[0057] Sym[                    main] @ 0050 align            sz 003c tp 12  |............f.g.|
sym[0058] Sym[              text_start] @ 0000 align            sz 0000 tp 10  |..............g.|
sym[0059] Sym[                 cpptest] @ 00a8 align            sz 0014 tp 12  |............f.g.|
sym[0060] Sym[                    func] @ 008c align            sz 0014 tp 12  |............f.g.|
sym[0061] Sym[                  _edata] @ 0058 align            sz 0000 tp 10  |..............g.|
sym[0062] Sym[                    _end] @ 0008 align            sz 0000 tp 10  |..............g.|
sym[0063] Sym[            __data_start] @ 0000 align            sz 0000 tp 10  |..............g.|
sym[0064] Sym[                  callme] @ 00a0 align            sz 0006 tp 12  |............f.g.|
sym[0065] Sym[            _dtors_start] @ 0058 align            sz 0000 tp 10  |..............g.|
rel 0  : sym [       __dyninfo0000] s_addr @ 0000002c rel 00000000 how R_ARM_GOTOFF32
rel 1  : sym [       __dyninfo0001] s_addr @ 0000003c rel 00000000 how R_ARM_GOTOFF32
rel 2  : sym [       __dyninfo0002] s_addr @ 0000004c rel 00000000 how R_ARM_GOTOFF32
rel 3  : sym [    sched_getstreams] s_addr @ 00000052 rel 00000000 how R_ARM_THM_CALL
rel 4  : sym [             fprintf] s_addr @ 0000005e rel 00000000 how R_ARM_THM_CALL
rel 5  : sym [    sched_getstreams] s_addr @ 00000062 rel 00000000 how R_ARM_THM_CALL
rel 6  : sym [             fprintf] s_addr @ 0000006e rel 00000000 how R_ARM_THM_CALL
rel 7  : sym [              callme] s_addr @ 00000078 rel 00000000 how R_ARM_THM_CALL
rel 8  : sym [                .LC0] s_addr @ 00000080 rel 00000000 how R_ARM_GOT32
  Created GOT entry 0 for sym 0x559f896a8360 (offset 0)
rel 9  : sym [                .LC1] s_addr @ 00000084 rel 00000000 how R_ARM_GOT32
  Created GOT entry 1 for sym 0x559f896a83c0 (offset 4)
rel 10 : sym [                func] s_addr @ 00000088 rel 00000000 how R_ARM_GOT32
  Created GOT entry 2 for sym 0x559f896a9380 (offset 8)
rel 11 : sym [              printf] s_addr @ 00000094 rel 00000000 how R_ARM_THM_CALL
rel 12 : sym [                .LC0] s_addr @ 0000009c rel 00000000 how R_ARM_GOT32
  Created GOT entry 3 for sym 0x559f896a8600 (offset 12)
rel 13 : sym [              printf] s_addr @ 000000b0 rel 00000000 how R_ARM_THM_CALL
rel 14 : sym [                .LC0] s_addr @ 000000b8 rel 00000000 how R_ARM_GOT32
  Created GOT entry 4 for sym 0x559f896a87e0 (offset 16)
rel 0  : sym [               .text] s_addr @ 00000040 rel 00000000 how R_ARM_ABS32
rel 1  : sym [               .text] s_addr @ 00000048 rel 00000000 how R_ARM_ABS32
rel 2  : sym [               .text] s_addr @ 00000050 rel 00000000 how R_ARM_ABS32
rel 0  : sym [       __dyninfo0000] s_addr @ 0000002c val 00000040-00000054 rel 00000000 how R_ARM_GOTOFF32
Perfoming GOTOFF reloc at addr 0000002c [00000000] to sym '__dyninfo0000' [00000054]
rel 1  : sym [       __dyninfo0001] s_addr @ 0000003c val 00000048-0000005c rel 00000000 how R_ARM_GOTOFF32
Perfoming GOTOFF reloc at addr 0000003c [00000000] to sym '__dyninfo0001' [0000005c]
rel 2  : sym [       __dyninfo0002] s_addr @ 0000004c val 00000050-00000064 rel 00000000 how R_ARM_GOTOFF32
Perfoming GOTOFF reloc at addr 0000004c [00000000] to sym '__dyninfo0002' [00000064]
rel 3  : sym [    sched_getstreams] s_addr @ 00000052 val 00000040-00000040 rel 00000000 how R_ARM_THM_CALL
Performing THM link at addr 00000052 [f7ff fffe] to sym 'sched_getstreams' [00000040]
rel 4  : sym [             fprintf] s_addr @ 0000005e val 00000030-00000030 rel 00000000 how R_ARM_THM_CALL
Performing THM link at addr 0000005e [f7ff fffe] to sym 'fprintf' [00000030]
rel 5  : sym [    sched_getstreams] s_addr @ 00000062 val 00000040-00000040 rel 00000000 how R_ARM_THM_CALL
Performing THM link at addr 00000062 [f7ff fffe] to sym 'sched_getstreams' [00000040]
rel 6  : sym [             fprintf] s_addr @ 0000006e val 00000030-00000030 rel 00000000 how R_ARM_THM_CALL
Performing THM link at addr 0000006e [f7ff fffe] to sym 'fprintf' [00000030]
rel 7  : sym [              callme] s_addr @ 00000078 val 000000a0-000000a0 rel 00000000 how R_ARM_THM_CALL
Performing THM link at addr 00000078 [f7ff fffe] to sym 'callme' [000000a0]
rel 8  : sym [                .LC0] s_addr @ 00000080 val 00000000-00000014 rel 00000000 how R_ARM_GOT32
Performing GOT32 reloc at addr 00000080 [00000000] to sym '.LC0' [00000014]
rel 9  : sym [                .LC1] s_addr @ 00000084 val 00000018-0000002c rel 00000000 how R_ARM_GOT32
Performing GOT32 reloc at addr 00000084 [00000000] to sym '.LC1' [0000002c]
rel 10 : sym [                func] s_addr @ 00000088 val 0000008c-0000008c rel 00000000 how R_ARM_GOT32
Performing GOT32 reloc at addr 00000088 [00000000] to sym 'func' [0000008c]
rel 11 : sym [              printf] s_addr @ 00000094 val 00000020-00000020 rel 00000000 how R_ARM_THM_CALL
Performing THM link at addr 00000094 [f7ff fffe] to sym 'printf' [00000020]
rel 12 : sym [                .LC0] s_addr @ 0000009c val 00000030-00000044 rel 00000000 how R_ARM_GOT32
Performing GOT32 reloc at addr 0000009c [00000000] to sym '.LC0' [00000044]
rel 13 : sym [              printf] s_addr @ 000000b0 val 00000020-00000020 rel 00000000 how R_ARM_THM_CALL
Performing THM link at addr 000000b0 [f7ff fffe] to sym 'printf' [00000020]
rel 14 : sym [                .LC0] s_addr @ 000000b8 val 00000038-0000004c rel 00000000 how R_ARM_GOT32
Performing GOT32 reloc at addr 000000b8 [00000000] to sym '.LC0' [0000004c]
rel 0  : sym [               .text] s_addr @ 00000040 val 00000000-00000000 rel 00000000 how R_ARM_ABS32
Performing ABS32 link at addr 00000040 [00000000] to sym '.text' [00000000]
rel 1  : sym [               .text] s_addr @ 00000048 val 00000000-00000000 rel 00000000 how R_ARM_ABS32
Performing ABS32 link at addr 00000048 [00000007] to sym '.text' [00000000]
rel 2  : sym [               .text] s_addr @ 00000050 val 00000000-00000000 rel 00000000 how R_ARM_ABS32
Performing ABS32 link at addr 00000050 [0000000f] to sym '.text' [00000000]
Entry symbol "main": 00000074 in section ".text"
  HDR: 00000024 + Section VMA: 00000000 + Symbol Value: 00000050
Symbol __dynimport_begin: value: 00000040 section offset: 00000000 file offset: 00000134 count: 3
cp errno rom
genromfs -f rom.img -d rom -a 16

What is interesting is that normal functions are linked as R_ARM_THM_CALL and function pointer func is linked as R_ARM_GOT32

rel 10 : sym [                func] s_addr @ 00000088 val 0000008c-0000008c rel 00000000 how R_ARM_GOT32

Gregory Nutt

unread,
Mar 10, 2019, 9:49:03 AM3/10/19
to nu...@googlegroups.com

Currently I have this code:

static const char g_nonexistent[] = "aflav-sautga-ay";

/****************************************************************************
 * Public Functions
 ****************************************************************************/
//defined in test.c
void callme(void(*cb)()); //caller
void func(); //callback

int main(int argc, char **argv)
{
  FILE *test_stream;

  /* Try using stdout and stderr explicitly.  These are global variables
   * exported from the base code.
   */

  fprintf(stdout, "Hello, World on stdout\n");
  fprintf(stderr, "Hello, World on stderr\n");
  
  callme(func);


  return 0;
}

You are aware that there are issues using generic function pointers with NxFLAT, right?  In the "normal" case, you need only a target address and a return address.  But NxFLAT operates PIC/PID and requires a target address, a target PID register, a return address and return PID register.  That is normally a accomplished with at "thunk" layer that mediates the function call (swapping the PID registers on entry and return as needed).

At one time, there was a modified GCC version floating around that had instrumentation that allowed every function to recover its PID register on entry and restore the caller's PID register on return, but that was never incorporated into the the mainline, however.  GCC is very focused on Linux and only gives token support for embedded systems.

Build output:
...

What is interesting is that normal functions are linked as R_ARM_THM_CALL and function pointer func is linked as R_ARM_GOT32

rel 10 : sym [                func] s_addr @ 00000088 val 0000008c-0000008c rel 00000000 how R_ARM_GOT32


That would be normal if 'func' were a function pointer and not a function.   But it looks like a real function in your example (although it does pass a reference to the function).

Greg


patacongo

unread,
Mar 10, 2019, 12:35:40 PM3/10/19
to NuttX


Build output:
...

What is interesting is that normal functions are linked as R_ARM_THM_CALL and function pointer func is linked as R_ARM_GOT32

rel 10 : sym [                func] s_addr @ 00000088 val 0000008c-0000008c rel 00000000 how R_ARM_GOT32


That would be normal if 'func' were a function pointer and not a function.   But it looks like a real function in your example (although it does pass a reference to the function).


Is 'func' and external, undefined function?  If so, then that is probably the difference.  mknxflat will replace all of the missing, undefined functions with "thunk" layers that fetch the true address of 'func' that will be bound at runtime by the dynamic loader, then jump to that address.  Perhaps there is some issue in the format of the the thunk layer for 'func'

That thunk layer will be generated as an assembly language file and assembled and linked into the system at build time.  Check around, you should have some file called "xzy-thunk.S" or something like that.  You can look at how mknxflat implemented the thunk.  Maybe it is doing something that is incompatible with the more recent GCC?

That temporary file is usually deleted.  You might have to so some thing special to preserve it.

Greg



Reply all
Reply to author
Forward
0 new messages