Repository navigation
dos: keep a hunk file's 32-bit relocations with its seglist (GSLI_68KRELOCS) - #1855
Conversation
Record the three kinds of programs, the per-run ownership rule for system-friendly programs that use the chipset (display, Paula, CIAs, interrupts, input), and the concrete points to agree with the high-level pull request series aros-development-team#1855-aros-development-team#1859. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_014XzsDvVVNZd96oEtyVMjbi
…ries A short write-up for the author of the high-level m68kemu series (aros-development-team#1855-aros-development-team#1859): where the two directions meet, the two designs for system-friendly programs that use the chipset, and the points that would help either way. RIGEL.md holds the details. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_014XzsDvVVNZd96oEtyVMjbi
|
Blocking issues:
|
e978e8e to
be6da9e
Compare
|
Both fixed, and the branch is rebased onto master past #1922.
|
|
be6da9e to
f9309a0
Compare
|
All three, in the one commit (rebased on master):
Test: developer/debug/test/dos/seglistrelocs, a two-hunk file with one relocation of each kind, loaded and checked against the segment addresses and the table; it also checks the 68k behaviour when built for 68k. Its first run failed on the ABSRELOC16 relocation and showed a loader bug on master: the 16-bit count of a RELOC32SHORT/DREL32/ABSRELOC16 block goes through AROS_BE2LONG, so any count below 256 reads as zero and the block is misparsed from there. That is a one-word fix (AROS_BE2WORD) and is in this commit, since the test covers it; say if you want it on its own. pc-x86_64 in QEMU: all ten checks pass, |
|
Thanks, all three points are addressed. Built for amiga-m68k (dos.library, libloadseg, AROSBootstrap) and ran seglistrelocs on pc-x86_64 in QEMU: all ten checks pass. Against master the same test fails the ABSRELOC16 check, which confirms the RELOC32SHORT/DREL32/ABSRELOC16 count byte-swap bug. Please split that one-line loader fix into its own commit, as it is independent of the table. One issue to fix before merging: acc_room() can loop forever on a corrupt relocation count. The HUNK_RELOC32 count is a full 32-bit value from the file. If the first block claims more than 0x80000000 entries, "ncap *= 2" overflows to 0 and the while loop never ends, so LoadSeg() hangs where it used to fail at end of file. Counts between 0x40000000 and 0x80000000 overflow "ncap * elem" instead. Please cap the count (for example at the hunk size / 4) or check for overflow in acc_room() and mark the list lost. Minor:
|
The count that follows the first word of these blocks is a 16-bit word, like the first one, but the loader byte-swapped it as a longword. On a little-endian host that leaves zero, so the block's relocations are not applied and the words that follow are parsed as the next block. The seglistrelocs test added with the relocation table fails its ABSRELOC16 check on master because of this.
…RELOCS) On a non-68k host LoadSeg() relocates a hunk file to the addresses of its own segments and nothing can run it there; an emulator copies the segments into its own memory and needs to relocate them again. Record the 32-bit relocations the loader applies, as the file groups them (one group per relocation block and target hunk: hunk, target, kind, and the offsets), in the seglist's segdata node, in the same allocation, and hand the table out through a new GetSegListInfo() tag. The cost is four bytes a relocation and a group header for each block, for the life of the seglist, on the hosts where a hunk file can only be run through an emulator. A failed allocation marks the table lost rather than handing out a partial one. On 68k nothing is recorded and the tag is not answered, as the segments run where they were loaded. The three kinds are the three ways the loader patches a longword: HUNK_RELOC32 and RELOC32SHORT add the target hunk's base; ABSRELOC16 adds it less the address of the longword; HUNK_RELRELOC32 adds it less the base of the hunk holding the longword. The structures and kinds are in dos/doshunks.h with the hunk types, the tag in dos/dostags.h with the other GetSegListInfo() tags, which the autodoc now describes. The m68k-amiga bootstrap has an empty register_hunk() of its own, which takes the new argument too. The test developer/debug/test/dos/seglistrelocs writes a two-hunk file with one relocation of each kind, loads it, checks the relocated longwords and the table, that 68k does not answer the tag, and that a relocation count the table cannot hold fails the load instead of hanging or overflowing it.
f9309a0 to
b3012bc
Compare
|
Done, rebased on master, two commits:
pc-x86_64 in QEMU (alpha18c5 image with this dos.library): all twelve checks pass, #1905 is rebased onto these two commits. |
This touches dos.library, so it needs your call; the m68kemu pull requests that follow build on it.
On a non-68k host LoadSeg() relocates a hunk file to the addresses of its own segments, and nothing can run it there. m68kemu copies the segments into its own memory and has to relocate them again, which needs the relocations the loader applied. This records the 32-bit relocations as the file groups them, one group per relocation block and target hunk (hunk, target, kind, and the offsets), in the seglist's segdata node, in the same allocation, and hands the table out through a new GetSegListInfo() tag, GSLI_68KRELOCS. The cost is four bytes a relocation plus a group header per block, for the life of the seglist, on the hosts where a hunk file can only be run through an emulator. A failed allocation marks the table lost instead of handing out a partial one. On 68k nothing is recorded and the tag is not answered. Nothing changes for callers that do not ask for the tag.
The structures and the three kinds are in
dos/doshunks.hnext to the hunk types; the tag stays indos/dostags.hwith the other GetSegListInfo() tags, and the autodoc describes it.Two commits. The first is a one-line loader fix the test found: the 16-bit relocation count of a HUNK_RELOC32SHORT, HUNK_DREL32 or HUNK_ABSRELOC16 block was byte-swapped as a longword, so on a little-endian host it read as zero and the block could not be parsed. The second is the table.
Test: developer/debug/test/dos/seglistrelocs writes a two-hunk file with one relocation of each kind (HUNK_RELOC32, HUNK_ABSRELOC16, HUNK_RELRELOC32), loads it, checks the three relocated longwords against the segment addresses and the table against the file, on 68k that the tag is not answered, and that a relocation count the table cannot hold (above 2^31, and above 2^30 where the allocation size would overflow) fails the load instead of hanging it. pc-x86_64 in QEMU (alpha18c5 image with this dos.library): all twelve checks pass,
SEGLISTRELOCS PASS; the changed files also compile for pc-i386.