mirror of
https://github.com/apache/nuttx.git
synced 2026-08-01 20:28:58 +00:00
Two gaps that both fail quietly. DT_INIT_ARRAY and DT_FINI_ARRAY were ignored entirely. A C++ module with any global object therefore loaded, resolved every symbol and ran, with all of its globals left as .bss reading back zero -- no fault, no log, just wrong answers. Both arrays are now walked per object and in dependency order: an object joins the load's list before the DT_NEEDED walk appends its own dependencies, so walking that list backwards constructs a library before the module that needs it, and destruction mirrors it. Constructors run in whichever task called the loader, before the module's own task exists, so the FDPIC register does not already hold the object's data base the way it does once the module is running. fdpic_callfn() installs it around each call. That is safe only because the firmware reserves the register; being preempted mid-constructor is harmless, since the register is part of the saved context. DT_JMPREL was not parsed at all. Which table an imported function's descriptor lands in is a linker decision -- -z now puts it in DT_REL, and without it the same entry goes to DT_JMPREL -- so a module linked the second way loaded cleanly and then branched to an unrelocated address on its first call into the firmware. The symptom is an INVSTATE UsageFault escalated to a HardFault: no console, no crash dump. There is no lazy resolver here, so an unwalked table is not deferred work; both are now bound eagerly, and nothing is lost by that because a module carries a handful of relocations. The two tables are not walked identically, which is the part worth remembering. In DT_REL the word being overwritten is the addend, and dropping it breaks a static function reached through its section symbol. In DT_JMPREL that same word is the lazy-binding bootstrap -- the address of the entry's own PLT resolution stub, with a GOT half of -1 -- and adding it to the resolved symbol value produces an arbitrary address that faults exactly like the bug this change fixes. An eager binder overwrites the descriptor outright. The descriptor pool is sized from relsize + pltrelsz rather than relsize alone, so an R_ARM_FUNCDESC in the PLT table cannot run off the end of the allocation. GNU ld does not appear to emit that combination -- an address-taken function is not a call and so never becomes a PLT relocation -- but the failure it would cause is heap corruption, and the guard is two additions. An object declaring RELA PLT relocations is refused rather than misread: nothing here reads RELA, whose entries are twelve bytes rather than eight. Assisted-by: Claude Code:claude-opus-4-8 Signed-off-by: Marco Casaroli <marco.casaroli@gmail.com> |
||
|---|---|---|
| .. | ||
| android | ||
| arpa | ||
| crypto | ||
| cxx | ||
| net | ||
| netinet | ||
| netpacket | ||
| nuttx | ||
| ssp | ||
| sys | ||
| .gitignore | ||
| aio.h | ||
| alloca.h | ||
| assert.h | ||
| byteswap.h | ||
| ctype.h | ||
| debug.h | ||
| dirent.h | ||
| dlfcn.h | ||
| dsp.h | ||
| dspb16.h | ||
| elf.h | ||
| elf32.h | ||
| elf64.h | ||
| endian.h | ||
| err.h | ||
| errno.h | ||
| execinfo.h | ||
| fcntl.h | ||
| fixedmath.h | ||
| fnmatch.h | ||
| ftw.h | ||
| gcov.h | ||
| getopt.h | ||
| glob.h | ||
| grp.h | ||
| hex2bin.h | ||
| iconv.h | ||
| ifaddrs.h | ||
| imx_container.h | ||
| inttypes.h | ||
| iso646.h | ||
| langinfo.h | ||
| libgen.h | ||
| libintl.h | ||
| limits.h | ||
| locale.h | ||
| lzf.h | ||
| malloc.h | ||
| mqueue.h | ||
| netdb.h | ||
| nl_types.h | ||
| nxflat.h | ||
| obstack.h | ||
| poll.h | ||
| pthread.h | ||
| pty.h | ||
| pwd.h | ||
| regex.h | ||
| resolv.h | ||
| sched.h | ||
| search.h | ||
| semaphore.h | ||
| shadow.h | ||
| signal.h | ||
| spawn.h | ||
| stdbool.h | ||
| stddef.h | ||
| stdint.h | ||
| stdio.h | ||
| stdlib.h | ||
| stdnoreturn.h | ||
| string.h | ||
| strings.h | ||
| syscall.h | ||
| syslog.h | ||
| termios.h | ||
| threads.h | ||
| time.h | ||
| ulimit.h | ||
| unistd.h | ||
| utime.h | ||
| uuid.h | ||
| wait.h | ||
| wchar.h | ||
| wctype.h | ||