feat: Support -z pack-relative-relocs#1701
feat: Support -z pack-relative-relocs#1701mati865 wants to merge 15 commits intowild-linker:mainfrom
-z pack-relative-relocs#1701Conversation
|
Ah, I have misunderstood that part. That version has to be just declared, not assigned to any symbol. |
|
It works now but doesn't support the major selling point of RELR which is compacting of the addresses via bitmaps. I'm not sure how to approach that as we need sorted entries before they are written for it work (use a temp buffer?). Currently, I'm working around the problem by sorting the entries after they are already written. Clang release (without debuginfo) builds without and with Even without the compaction this is a small win to the size. This is how compacted vs non-compacted entries look like: Performance impact is not bad considering the sort workaround |
5085561 to
5e53268
Compare
davidlattimore
left a comment
There was a problem hiding this comment.
Given this is marked as a draft, I assume there's still stuff that you want to address, so I haven't reviewed thoroughly yet. I did skim over it though.
libwild/src/elf.rs
Outdated
| let mut verneed_info = state.verneed_info; | ||
|
|
||
| if let Some(v) = state.verneed_info.as_ref() | ||
| if let Some(v) = &mut verneed_info |
There was a problem hiding this comment.
It looks like this mut perhaps isn't needed.
There was a problem hiding this comment.
Good catch, this is a leftover from one of the previous attempts at making glibc special symbol logic not feel like a plaster on a broken limb. This version I'm fairly satisfied with, but as you noticed it needs a bit of clean-up still.
Also, too bad none of the linter caught it.
|
Thanks, the status from #1701 (comment) is still up-to-date. Not much progress, so far. At least I no longer hate the way this PR implements glibc special symbol version. |
Its location doesn't matter, GNU ld just reversely sorts the versions within each verneed.
5e53268 to
00d2009
Compare
|
Looking at But if I map addresses to the sections we get: The relocations are not as unordered as I previously thought. Currently, sections are written at the first available slot, but relocations within each section are already ordered (not verified but seems plausible). GOTs won't be a problem as well (at least in Clang's case). Even though there are 2002 entries with relative reloc: They are sequential: Other relocations should be irrelevant here. With some creativity this solution could be extended to avoid overallcoation as well. If we store first and last addresses of each written relocations chunk for each section somewhere, we can increment the sizes by the chunk size, instead of relocations count. Maybe it will be clearer that way: |
|
There is something I didn't account for: buckets and groups. It works only for simple cases: using single thread ( Shows the addresses are in order, but adding threads or inputs makes the offsets fall apart. EDIT: Regarding the fields in common structs, some of those were ELF specific when I started and I didn't bother cleaning up the code that doesn't even work when rebasing. I'll move them if this ever starts working correctly. |
|
The closest equivalent I can think of in the linker is how dynamic symbol definitions are handled. During the GC phase, objects collect up the dynamic symbols that they need to define, storing them in |
Works now but doesn't pack RELR entries via bitmaps, so the size reduction is not that big.
Doesn't work yet:I haven't yet figured out how to cleanly synthesiseGLIBC_ABI_DT_RELRversion for__libc_start_mainsymbol. I'd prefer to avoid matching that symbol by the name, but there might be no other choice.