On 4/28/2024 5:56 PM, MitchAlsup1 wrote:
BGB wrote:
On 4/28/2024 2:24 PM, MitchAlsup1 wrote:
>
Still going to need to explain the semantics here...
>
IP+&GOT+disp-IP is a 64-bit pointer into GOT where the external linkage
pointer resides.
OK.
Not sure I follow here what exactly is going on...
While I am sure I don't understand what is going on....
As noted, if I did a similar thing to the RISC-V example, but with my own ISA (with the MOV.C extension):
MOV.Q (PC, Disp33), R0 // What data does this access ?
MOV.Q (GBR, 0), R18
MOV.C (R18, R0), GBR
It appears to me that you are placing an array of GOT pointers at the first entry of any particular GOT ?!?
They are not really GOTs in my PBO ABI, but rather the start of every ".data" section.
In this case, every ".data" section starts with a pointer to an array that holds a pointer to every other ".data" section in the process image, and every DLL is assigned an index in this array (except the main EXE, which always has an index value of 0).
Every program instance exists relative to this array of ".data" sections.
So, say, "Process 1" will have one version of this array, "Process 2" will have another, etc.
And, all of the data sections in Process 1 will point to the array for Process 1. And, all of the data sections in Process 2 will point to the array for Process 2. And so on...
So, even if all the ".text" sections are shared between "Process 1" and "Process 2" (with both existing within the same address space), because the data sections are separate; each has its own set of global variables, so the processes effectively don't see the other versions of the program running within the shared address space.
In some sense, FDPIC is vague similar, but does use GOTs, but effectively daisy-chains all the GOTs together with all the other GOTs (having a GOT pointer for every function pointer in the GOT).
But, as can be noted, this does add some overhead.
In my case, I had wanted to do something similar to FDPIC in the sense of allowing multiple instances without needing to duplicate the read-only sections. But, I also wanted a lower performance overhead.
Whereas My 66000 uses IP relative access to the GOT the linker (or LD.so) setup avoiding the indirection.
Then My 66000 does not have or need a pointer to GOT since it can
synthesize such a pointer at link time and then just use a IP relative
plus DISP32 to access said GOT.
This approach works so long as one has a one-to-one mapping between loaded binaries, and their associated sets of global variables (or, if each mapping exists in its own address space).
Doesn't work so well for a many-to-one mapping within a shared address space.
So, say, if you only have one instance of a binary, getting the GOT or data sections relative to PC/IP can work.
But, with multiple instances, it does not work. The data sections can only be relative to the other data sections (or to the process context).
Like, say, if you wanted to support a multitasking operating system on hardware that doesn't have either virtual memory or segments.
Or, if one does have virtual memory, but wants to keep it as optional.
Say, for example, uClinux...
So, say we have some external variables::
extern uint64_t fred, wilma, barney, betty;
AND we postulate that the linker found all 4 externs in the same module
so that it can access them all via 1 pointer. The linker assigns an
index into GOT and setups a relocation to that memory segment and when
LD.so runs, it stores a proper pointer in that index of GOT, call this
index fred_index.
And we access one of these::
if( fred at_work )
The compiler will obtain the pointer to the area fred is positioned via:
LDD Rfp,[IP,,#GOT+fred_index<<3] // *
And, the above is where the problem lies...
Would be valid for ELF PIC or PIE binaries, but is not valid for PBO or FDPIC.
and from here one can access barney, betty and wilma using the pointer to fred and standard offsetting.
LDD Rfred,[Rfp,#0] // fred
LDD Rbarn,[Rfp,#16] // barney
LDD Rbett,[Rfp,#24] // betty
LDD Rwilm,[Rfp,#8] // wilma
These offsets are known at link time and possibly not at compile time.
(*) if the LDD through GOT takes a page fault, we have a procedure setup
so LD.so can run figure out which entry is missing, look up where it is
(possibly load and resolve it) and insert the required data into GOT.
When control returns to LDD, the entry is now present, and we now have access to fred, wilma, barney and betty.
Yeah.
Differing mostly in that it doesn't require base relocs.
The normal version in my case avoids the extra memory load, but uses a base reloc for the table index.
....
{{ // this looks like stuff that should be accessible to LD.so
Though, the reloc format is at least semi-dense, eg, for a block of relocs:
{ DWORD rvaPage; //address of page (4K)
DWORD szRelocs; //size of relocs in block
}
With each reloc encoded as a 16-bit entry:
(15:12): Reloc Type
(11: 0): Address within Page (4K)
One downside is this format is less efficient for sparse relocs (current situation), where often there are only 1 or 2 relocs per page (typically the PBO index fixups and similar).
One situation could be to have a modified format that partially omits the block structuring, say:
0ddd: Advance current page position by ddd pages (4K);
0000: Effectively a NOP (as before)
1ddd..Cddd: Apply the given reloc.
These represent typical relocs, target dependent.
HI16, LO16, DIR32, HI32ADJ, ...
8ddd: Was assigned for PBO fixups;
Addd: Fixup for a 64-bit address, also semi common.
Dzzz/Ezzz: Extended Relocs
These ones are configurable from a larger set of reloc types.
Fzzz: Command-Escape
...
Where, say, rather than needing 1 block per 4K page, it is 1 block per PE section.
Tested the above tweak, it can reduce the size of the ".reloc" section by around 20%, but would break compatibility with previous versions of my PEL loader.
Though, base relocs are a relatively small part of the size of the binary.
To some extent, the PBO reloc is magic in that it works by pattern-matching the instruction that it finds at the given address. So, in effect, is only defined for a limited range of instructions.
Contrast with, say, the 1/2/3/4/A relocs, which expect raw 16/32/64 bit values. Though, a lot of these are not currently used for BJX2 (does not use 16-bit addressing nides, ...).
Here:
5/6/7/8/9/B/C, ended up used for BJX2 relocs in BJX2 mode.
For other targets, they would have other meanings.
D/E/F were reserved as expanded/escape-case relocs, in case I need to add more. These would differ partly in that the reloc sub-type would be assigned as a sort of state-machine.
but not the program itself}}
As noted, the base relocs are applied by the PE / PEL loader.
But, annoyingly, this would not map over so well to an ELF loader...
Note that despite PEL keeping the same high level structure as PE/COFF, in the case of PBO, effectively the binary is split in half.
So, the read-only sections (".text" and friends), and the read/write sections (".data" and ".bss") are entirely disjoint in memory.
Likewise, read-only sections may not point to read/write sections, and the reloc's are effectively applied in two different stages (for the read-only sections when the binary is loaded into memory; and to the read/write sections when a new instance is created).
Meanwhile, got the My66000 LLVM/Clang compiler built so far as that it at least seems to try to build something (and seems to know that the target exists).
But, also tends to die in s storm of error messages, eg:
/tmp/m_swap-822054.s:6: Error: no such instruction: `bitr r1,r1,<8:48>'
/tmp/m_swap-822054.s:14: Error: no such instruction: `srl r2,r1,<0:24>'
/tmp/m_swap-822054.s:15: Error: no such instruction: `srl r3,r1,<0:8>'
/tmp/m_swap-822054.s:16: Error: too many memory references for `and'
/tmp/m_swap-822054.s:17: Error: no such instruction: `sll r4,r1,<0:8>'
/tmp/m_swap-822054.s:18: Error: too many memory references for `and'
/tmp/m_swap-822054.s:19: Error: no such instruction: `sll r1,r1,<0:24>'
/tmp/m_swap-822054.s:20: Error: too many memory references for `or'
/tmp/m_swap-822054.s:21: Error: too many memory references for `or'
/tmp/m_swap-822054.s:22: Error: too many memory references for `or'
/tmp/m_cheat-f6c778.s: Assembler messages:
/tmp/m_cheat-f6c778.s:6: Error: no such instruction: `ldub r3,[ip,firsttime]'
/tmp/m_cheat-f6c778.s:7: Error: no such instruction: `bb1 0,r3,.LBB0_3'
/tmp/m_cheat-f6c778.s:8: Error: no such instruction: `stb '
/tmp/m_cheat-f6c778.s:9: Error: expecting operand after ','; got nothing
/tmp/m_cheat-f6c778.s:10: Error: too many memory references for `mov'
/tmp/m_cheat-f6c778.s:12: Error: no such instruction: `bitr r5,r4,<1:56>'
/tmp/m_cheat-f6c778.s:13: Error: no such instruction: `sll r6,r3,<0:1>'
/tmp/m_cheat-f6c778.s:14: Error: too many memory references for `and'
/tmp/m_cheat-f6c778.s:15: Error: no such instruction: `srl r7,r3,<0:1>'
/tmp/m_cheat-f6c778.s:16: Error: too many memory references for `and'
/tmp/m_cheat-f6c778.s:17: Error: no such instruction: `srl r8,r3,<0:5>'
/tmp/m_cheat-f6c778.s:18: Error: too many memory references for `and'
/tmp/m_cheat-f6c778.s:19: Error: no such instruction: `srl r9,r3,<1:7>'
/tmp/m_cheat-f6c778.s:20: Error: too many memory references for `and'
/tmp/m_cheat-f6c778.s:21: Error: too many memory references for `or'
/tmp/m_cheat-f6c778.s:22: Error: too many memory references for `or'
/tmp/m_cheat-f6c778.s:23: Error: too many memory references for `or'
/tmp/m_cheat-f6c778.s:24: Error: too many memory references for `or'
/tmp/m_cheat-f6c778.s:25: Warning: `r5' is not valid here (expected `(%rdi)')
/tmp/m_cheat-f6c778.s:25: Warning: `r5' is not valid here (expected `(%rdi)')
/tmp/m_cheat-f6c778.s:25: Error: too many memory references for `ins'
/tmp/m_cheat-f6c778.s:26: Error: no such instruction: `stb r5,[ip,r3,cheat_xlate_table]'
/tmp/m_cheat-f6c778.s:27: Error: too many memory references for `add'
/tmp/m_cheat-f6c778.s:28: Error: too many memory references for `add'
/tmp/m_cheat-f6c778.s:29: Error: too many memory references for `cmp'
/tmp/m_cheat-f6c778.s:30: Error: no such instruction: `bne r5,.LBB0_2'
/tmp/m_cheat-f6c778.s:32: Error: no such instruction: `ldd r4,[r1]'
/tmp/m_cheat-f6c778.s:33: Error: expecting operand after ','; got nothing
/tmp/m_cheat-f6c778.s:34: Error: no such instruction: `beq0 r4,.LBB0_17'
/tmp/m_cheat-f6c778.s:35: Error: no such instruction: `ldd r5,[r1,8]'
/tmp/m_cheat-f6c778.s:36: Error: no such instruction: `beq0 r5,.LBB0_5'
/tmp/m_cheat-f6c778.s:37: Error: no such instruction: `ldub r6,[r5]'
/tmp/m_cheat-f6c778.s:38: Error: no such instruction: `beq0 r6,.LBB0_7'
/tmp/m_cheat-f6c778.s:40: Error: too many memory references for `and'
/tmp/m_cheat-f6c778.s:41: Error: no such instruction: `ldub r2,[ip,r2,cheat_xlate_table]'
/tmp/m_cheat-f6c778.s:42: Error: too many memory references for `cmp'
/tmp/m_cheat-f6c778.s:43: Error: no such instruction: `bne r2,.LBB0_10'
/tmp/m_cheat-f6c778.s:44: Error: too many memory references for `add'
/tmp/m_cheat-f6c778.s:45: Error: too many memory references for `std'
/tmp/m_cheat-f6c778.s:46: Error: no such instruction: `ldub r2,[r4]'
/tmp/m_cheat-f6c778.s:47: Error: too many memory references for `cmp'
/tmp/m_cheat-f6c778.s:48: Error: no such instruction: `bne r5,.LBB0_12'
/tmp/m_cheat-f6c778.s:49: Error: no such instruction: `br .LBB0_14'
/tmp/m_cheat-f6c778.s:52: Error: too many memory references for `mov'
/tmp/m_cheat-f6c778.s:55: Error: too many memory references for `std'
/tmp/m_cheat-f6c778.s:56: Error: too many memory references for `mov'
/tmp/m_cheat-f6c778.s:57: Error: no such instruction: `ldub r6,[r5]'
/tmp/m_cheat-f6c778.s:58: Error: no such instruction: `bne0 r6,.LBB0_8'
/tmp/m_cheat-f6c778.s:60: Error: too many memory references for `add'
/tmp/m_cheat-f6c778.s:61: Error: too many memory references for `std'
/tmp/m_cheat-f6c778.s:62: Error: no such instruction: `stb r2,[r5]'
/tmp/m_cheat-f6c778.s:63: Error: no such instruction: `ldd r4,[r1,8]'
/tmp/m_cheat-f6c778.s:64: Error: no such instruction: `ldub r2,[r4]'
/tmp/m_cheat-f6c778.s:65: Error: too many memory references for `cmp'
/tmp/m_cheat-f6c778.s:66: Error: no such instruction: `bne r5,.LBB0_12'
/tmp/m_cheat-f6c778.s:68: Error: no such instruction: `ldd r2,[r1]'
/tmp/m_cheat-f6c778.s:69: Error: expecting operand after ','; got nothing
/tmp/m_cheat-f6c778.s:70: Error: too many memory references for `std'
/tmp/m_cheat-f6c778.s:71: Error: too many memory references for `mov'
/tmp/m_cheat-f6c778.s:74: Error: too many memory references for `std'
/tmp/m_cheat-f6c778.s:75: Error: no such instruction: `ldub r2,[r4]'
/tmp/m_cheat-f6c778.s:76: Error: too many memory references for `cmp'
/tmp/m_cheat-f6c778.s:77: Error: no such instruction: `beq r5,.LBB0_14'
/tmp/m_cheat-f6c778.s:79: Error: too many memory references for `cmp'
/tmp/m_cheat-f6c778.s:80: Error: no such instruction: `bne r2,.LBB0_16'
/tmp/m_cheat-f6c778.s:81: Error: too many memory references for `add'
/tmp/m_cheat-f6c778.s:82: Error: expecting operand after ','; got nothing
/tmp/m_cheat-f6c778.s:83: Error: too many memory references for `std'
/tmp/m_cheat-f6c778.s:84: Error: too many memory references for `mov'
/tmp/m_cheat-f6c778.s:92: Error: no such instruction: `ldd r3,[r1]'
/tmp/m_cheat-f6c778.s:94: Error: too many memory references for `add'
/tmp/m_cheat-f6c778.s:95: Error: no such instruction: `ldub r3,[r3]'
/tmp/m_cheat-f6c778.s:96: Error: too many memory references for `cmp'
/tmp/m_cheat-f6c778.s:97: Error: too many memory references for `mov'
/tmp/m_cheat-f6c778.s:98: Error: no such instruction: `bne r4,.LBB1_1'
/tmp/m_cheat-f6c778.s:99: Error: no such instruction: `ldub r4,[r1]'
/tmp/m_cheat-f6c778.s:100: Error: expecting operand after ','; got nothing
/tmp/m_cheat-f6c778.s:102: Error: too many memory references for `mov'
/tmp/m_cheat-f6c778.s:103: Error: no such instruction: `stb r4,[r2,r3,-1]'
/tmp/m_cheat-f6c778.s:104: Error: too many memory references for `and'
/tmp/m_cheat-f6c778.s:105: Error: no such instruction: `stb '
/tmp/m_cheat-f6c778.s:106: Error: no such instruction: `ldub r4,[r1,r3,0]'
/tmp/m_cheat-f6c778.s:107: Error: too many memory references for `and'
/tmp/m_cheat-f6c778.s:108: Error: no such instruction: `beq0 r6,.LBB1_5'
/tmp/m_cheat-f6c778.s:109: Error: too many memory references for `add'
/tmp/m_cheat-f6c778.s:110: Error: too many memory references for `cmp'
/tmp/m_cheat-f6c778.s:111: Error: no such instruction: `bne r5,.LBB1_3'
/tmp/m_cheat-f6c778.s:112: Error: no such instruction: `br .LBB1_6'
/tmp/m_cheat-f6c778.s:114: Error: too many memory references for `cmp'
/tmp/m_cheat-f6c778.s:115: Error: no such instruction: `beq r1,.LBB1_6'
/tmp/m_cheat-f6c778.s:118: Error: no such instruction: `stb '
/tmp/m_random-1b60b6.s: Assembler messages:
/tmp/m_random-1b60b6.s:6: Error: no such instruction: `lduw r1,[ip,prndindex]'
/tmp/m_random-1b60b6.s:7: Error: too many memory references for `add'
/tmp/m_random-1b60b6.s:8: Error: too many memory references for `and'
/tmp/m_random-1b60b6.s:9: Error: no such instruction: `stw r1,[ip,prndindex]'
/tmp/m_random-1b60b6.s:10: Error: no such instruction: `ldub r1,[ip,r1,rndtable]'
/tmp/m_random-1b60b6.s:18: Error: no such instruction: `lduw r1,[ip,rndindex]'
/tmp/m_random-1b60b6.s:19: Error: too many memory references for `add'
/tmp/m_random-1b60b6.s:20: Error: too many memory references for `and'
/tmp/m_random-1b60b6.s:21: Error: no such instruction: `stw r1,[ip,rndindex]'
/tmp/m_random-1b60b6.s:22: Error: no such instruction: `ldub r1,[ip,r1,rndtable]'
/tmp/m_random-1b60b6.s:30: Error: no such instruction: `stw '
/tmp/m_random-1b60b6.s:31: Error: no such instruction: `stw '
...
/tmp/sounds-95ce64.s: Assembler messages:
/tmp/sounds-95ce64.s:346: Error: unknown pseudo-op: `.dword'
/tmp/sounds-95ce64.s:349: Error: unknown pseudo-op: `.dword'
/tmp/sounds-95ce64.s:352: Error: unknown pseudo-op: `.dword'
/tmp/sounds-95ce64.s:355: Error: unknown pseudo-op: `.dword'
/tmp/sounds-95ce64.s:358: Error: unknown pseudo-op: `.dword'
/tmp/sounds-95ce64.s:361: Error: unknown pseudo-op: `.dword'
/tmp/sounds-95ce64.s:364: Error: unknown pseudo-op: `.dword'
...
and so on...