Remix.run Logo
Joker_vD 3 days ago

Yeah, good thing that e.g. RV64 has RIP-relative addressing mode that can address anywhere in the whole 56-bits of available space with no problems, unlike the silly 8086 that resorted to using a base register to overcome the short size of its immediate fields.

akira2501 3 days ago | parent [-]

...and then x86_64 went ahead and added RIP relative addressing back in, and you get the full 64 bits of address space.

Joker_vD 3 days ago | parent [-]

...you know that that's not true, neither for x64 nor RV64, and my comment was sarcastic, right? Both can only straightforwardly address ±2 GiB from the instruction pointer; beyond that, it's "large code model" all over again, with the same inelegant workarounds that's been rediscovered since the late sixties or so. GOT and PLT versus pools of absolute 64-bit addresses, pick the least worst one.

akira2501 3 days ago | parent [-]

> and my comment was sarcastic, right?

Pardon me for not realizing and treating it appropriately.

> with the same inelegant workarounds that's been rediscovered since the late sixties or so

Short of creating instructions that take 64bit immediate operands you're always going to pay the same price. An indirection. This will look different because it will be implemented most efficiently differently on different architectures.

> GOT and PLT versus pools of absolute 64-bit addresses, pick the least worst one.

Or statically define all those addresses within your binary. That seems more "elegant" to you? You'll have the same problem but your loader will now be inside out or you'll have none of the features the loader can provide for you.

At that point just statically link all your dependencies and call it an early day.

Joker_vD 3 days ago | parent [-]

> You're always going to pay the same price. An indirection.

There is a difference between indirecting through a register, or through a memory (which in the end also requires a register, in addition to a memory load). On the other hand, I$ is more precious, and the most popular parts of GOT are likely to be in the voluminous D$ anyhow, so it's hard to tell which is more efficient.

> Or statically define all those addresses within your binary. That seems more "elegant" to you?

Of course not. I personally think a directly specifiable 64-bit offset from the base register that holds the start of the data section is more elegant. But dynamic libraries don't mesh too well with this approach although IIRC it has been tried.

> you'll have none of the features the loader can provide for you. At that point just statically link all your dependencies and call it an early day.

This works surprisingly well in practice, actually. Data relocations are still an issue though.