Repository navigation
ERL: four defects - a vacuous HI16/LO16 guard, a dropped export, three dangling dependencies, six erl_id/filename mismatches #924
Description
Four defects in the EE ERL machinery, found while porting ERL to the PS1. All re-verified against d317f8f0 today; ee/erl/src/erl.c has the same blob sha at 61a4b3f1 and d317f8f0, and none of the commits in between touch ee/erl/, ee/erl-loader/ or any erl-support.c.
1. ee/erl/src/erl.c:856 reads the wrong struct, which makes the HI16/LO16 pairing guard vacuous.
851 sym_n = reloc.r_info >> 8;
...
855 next_reloc = *((struct elf_reloc_t *) (reloc_section + ((j+1) * sec[i].sh_entsize)));
856 next_sym_n = reloc.r_info >> 8;next_reloc is fetched on line 855 and never consulted for the symbol index; line 856 is a byte-identical copy of 851. The consequence is at line 883:
882 (has_next_reloc && ((next_reloc.r_info & 255) == R_MIPS_LO16)) &&
883 (sec[sym[sym_n].st_shndx].sh_addr == sec[sym[next_sym_n].st_shndx].sh_addr) &&883 is only reached when has_next_reloc is true, which is the same path on which 856 ran, and reloc is not written in between - so next_sym_n == sym_n always and the section-address comparison is unconditionally true. The paired-section check does nothing. No uninitialised read: the short-circuit covers it.
Last touched by 8f16bbc0 ("fix: recalculate addresses when lower bits are greater than 0x8000", 2025-03-19) on both lines.
2. ee/erl-loader/src/build-exports.sh drops the last symbol from both the forward declarations and the export table.
6 sort -n |
7 awk ' { t[NR] = $0 }
9 for (i = 1; i < NR; i++) # forward decls
15 for (i = 1; i < NR; i++) # export_list[] bodyt[NR] is written and never read, so whichever symbol sorts last gets neither a prototype nor an export_list[] entry. Separately, line 6 applies sort -n to C identifiers coming out of awk '{print $8}', so every key sorts as 0 and the order is whatever order the input arrived in. Which symbol gets dropped is therefore not stable.
3. Three declared ERL dependencies have no provider anywhere in the tree.
36 erl-support.c files declare 12 distinct dependency strings between them. libc, libmath and libmf match no erl_id: git grep -n 'erl_id *= *"lib\(c\|math\|mf\)"' exits 1.
libc-ee/libcwas deleted by00b4130a("Move ee/libc to newlib", 2019-09-22)libmath-ee/math/was deleted by48cbff53(2020-03-24); at48cbff53^that directory declarederl_id = "libmath"libmf-ee/draw/src/erl-support.c:18is the only occurrence in the repo, andgit log -S 'erl_id = "libmf"'is empty, so I cannot say what form its provider took
Consumers are erl.c:1000 (erl_find_local_symbol("erl_dependancies", r)) and erl.c:1138 (r_unload_dependancies).
4. Six erl_id values do not match the .erl filename that directory produces.
erl.c:960 resolves a dependency with snprintf(tmpnam, ..., "%s.erl", erl_id), and the filename comes from EE_LIB through ee/Rules.make:126, which derives the .erl target strictly as $(EE_LIB:%.a=%.erl).
| produced file | declared erl_id |
declaration |
|---|---|---|
libps2ip.erl |
libps2ip141 |
ee/network/tcpip/src/erl-support.c:15 |
libps2ips.erl |
libps2ip |
ee/rpc/tcpips/src/erl-support.c:15 |
libkbd.erl |
libkeyboard |
ee/rpc/keyboard/src/erl-support.c:15 |
librm.erl |
libremote |
ee/rpc/remote/src/erl-support.c:15 |
libpatches.erl |
libsbv |
ee/sbv/src/erl-support.c:15 |
libps2snd.erl |
libps2kit |
ee/rpc/ps2snd/src/erl-support.c:15 |
The first pair is the interesting one. A request for libps2ip opens libps2ip.erl, which is tcpip's and registers itself as libps2ip141, so the id is never satisfied - while the module that does declare libps2ip ships as libps2ips.erl, a name no resolver will open. The other 30 declarations match.
Two more of the same shape, listed separately because they are conditional: under _XPAD, ee/rpc/pad/src/erl-support.c:16 declares libpadx while the directory still produces libpad.erl (EE_LIB_ALTNAMES aliases the .a only), and under _XINPUT, ee/input/src/erl-support.c:16 declares libinputx against libinput.erl. The default branch of each matches.
Adjacent and not counted: ee/Rules.release:36 symlinks three altnames (libsocket, libxcdvd, libpadx) onto files whose ids are libps2ip141, libcdvd and libpad.
Happy to send patches for any of these. 1 and 2 are one-liners; 3 and 4 are decisions about what the intended names are, which I would rather not guess at.
Activity
uyjulian commentedon Sep 22, 2026
Patches are fine. The intended names are the one declared in the buildsystem and not the one in erl-support.c
rixnobis commentedon Sep 22, 2026
Thanks. PR #925 has defects 1 and 2; I will follow the buildsystem name for 4.
One correction to what I wrote above, in defect 2. I said the
sort -non line 6 makes every key compare as 0 so the order is whatever order the input arrived in, and that which symbol gets dropped is therefore not stable. That is wrong, and I only found it because I went to change the line.GNU sort applies a whole-line last-resort comparison when the keys tie, so
sort -non identifiers produces the same order as plainsort:Only
-sgives input order. So the drop is deterministic: it is always the lexically last exported symbol, not an arbitrary one. The defect stands and is easier to spot than I made it sound. I have leftsort -nin place in the PR since it is not causing the bug.erl: use next_reloc for the paired symbol index, and stop dropping th…
rixnobis commentedon Oct 11, 2026
Defect 4 is up as #939. Defect 3 needs a call from you before I write anything:
libc,libmathandlibmfare declared inerl_dependanciesbut no library in the tree has those ids (ee/libcwent to newlib in 00b4130,ee/mathin 48cbff5). Should those entries be dropped, pointed at what replaced them (newlib's libc has noerl_id), or left for out-of-tree providers?fix(erl): match erl_id to the library name the build produces
uyjulian commentedon Oct 14, 2026
Missing entries should be dropped.
rixnobis commentedon Oct 18, 2026
Thanks. Defects 1, 2 and 4 are in (#925, #939); 3 is #940, dropping them as you said.