-
Notifications
You must be signed in to change notification settings - Fork 68
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Describe the relocations that LLVM is currently using. #7
Conversation
Because we want to be able to write C++ global addresses into the data section, we can't count on using a get_global to read the value of an imported global to get the C++ global address. In view of that, and the fact that it's also simpler to write addresses directly into the code section than use an actual get_global, drop the get_globals altogether. This results in several changes to the relocations. And, add an addend field to C++ global address relocations. I think this ends up making sense because it makes sense for the addend to be signed, but some of the relocations apply to fields which are unsigned, so storing the addend in them is awkward.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
lgtm % comments.
Thanks for working on this. This approach makes sense to me.
Linking.md
Outdated
instruction. | ||
- `4 / R_WEBASSEMBLY_GLOBAL_ADDR_SLEB` - a global index encoded as a 5-byte | ||
[varint32]. Used for the immediate argument of a `i32.const` instruction, | ||
e.g. taking the address of a function. |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
taking the address of a global?
Linking.md
Outdated
[uint32]. | ||
- `3 / R_WEBASSEMBLY_GLOBAL_ADDR_LEB` - a global index encoded as a 5-byte | ||
[varuint32]. Used for the immediate argument of a `load` or `store` | ||
instruction. |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
e.g. reading/writing to a global?
Linking.md
Outdated
5-byte [varint32]. Used to refer to the immediate argument of a `i32.const` | ||
instruction, e.g. taking the address of a function. | ||
- `2 / R_WEBASSEMBLY_TABLE_INDEX_I32` - a function table index encoded as a | ||
[uint32]. |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I guess this is for function addresses stored in the data segment? perhaps mention that?
Add explanations for the relocations that didn't have them, and fix copypasta.
Linking.md
Outdated
i32 global initialized to "STACKTOP" in the "env" module. During linking, only | ||
one of these globals is kept, and it remains the first global. This is a | ||
simple convention which allows code to reference global `0` without needing to | ||
be rewritten. |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
What about the fact that any imported globals come first in the index space of globals? Are we relying on the fact that there will be no imported globals in the final linked executable?
Can/should we land this now? I'd like to update wabt to support these changes. |
This eliminates some ambiguity; this isn't a relocation for an address of a C++ global, not to be confused with a wasm global.
For example, for the stack pointer global.
I'm still working on the stack pointer issue, but we can merge it now and continue to iterate if that works for you. |
This is currently used to identify a stack pointer.
Yes, lets merge this now and iterate. lgtm |
Can you explain how and why the linker would make use of the new R_WEBASSEMBLY_STACK_POINTER? Is it so that the stack point of each object can be merged into a single global in the output? |
Merging, as discussed above. We'll continue to iterate. Yes, the purpose of R_WEBASSEMBLY_STACK_POINTER is so that the stack pointers of each object can be merged. I'm open to other ideas too. |
Because we want to be able to write C++ global addresses into the data section,
we can't count on using a get_global to read the value of an imported global to
get the C++ global address. In view of that, and the fact that it's also simpler
to write addresses directly into the code section than use an actual get_global,
drop the get_globals altogether. This results in several changes to the
relocations.
And, add an addend field to C++ global address relocations. I think this ends
up making sense because it makes sense for the addend to be signed, but some of
the relocations apply to fields which are unsigned, so storing the addend in them
is awkward.
LLVM isn't quite finished implementing the stack pointer part of this, and as I wrote this up, I also realized that it's missing support for relocating type indices in
call_indirect
instructions, however I'm posting it now so that we can start talking about the other parts.