Fix issues associated with incorrect application of R_RISCV_RELAX#1289
Fix issues associated with incorrect application of R_RISCV_RELAX#1289Alexey Karyakin (quic-akaryaki) wants to merge 4 commits into
Conversation
|
This is one approach but there might be a simpler one. How about: Before we call relaxDeleteBytes, we can go through and change the This might be simpler than per-target relocation flags? Alternatively we could have an internal relocation that meant "there was a R_RISCV_RELAX here, but it relates to something deleted", which might make reconstructing reasonable output for emit-relocs easier. |
There are two approaches, not one? The first one is simple, but it will remove R_RISCV_RELAX from -emit-relocs output. It is debatable whether they should be there, but correctly they are, and lld keeps them too. The second one (internal temporary relocation) does not seem simper than a flag. It is really easier to check a bit than "what is the next relocation?" every time so the code that deals with R_RISCV_RELAX can be in one location. Adding internal relocations is also not simple. However, I think a longer-term direction would be to not load R_RISC_RELAX internally at all to reduce memory footprint, and later reconstruct them in -emit-relocs if needed. I looked into this, but we would need a target-specific hook in emitRelocation(). I didn't feel like I want to go that far. |
Shankar Easwaran (quic-seaswara)
left a comment
There was a problem hiding this comment.
It looks like we need to deal with creating a unordered map of Relocation * to bool.
f47b838 to
ca79f50
Compare
1bad100 to
af339ee
Compare
0447bf4 to
56cd6f8
Compare
56cd6f8 to
f2df8ea
Compare
| /// A map to keep track of the relocation that defines the base address for | ||
| /// relative relocations. This is a concept in RISC-V and applies to | ||
| /// relocations consisting of a HI20 and LO12 pairs. | ||
| llvm::DenseMap<const Relocation *, const Relocation *> m_BaseRelocs; |
There was a problem hiding this comment.
I had to make the pointed relocation pointer non-const because R_RISCV_QC_E_32 relaxation updates the access relocation and m_BaseRelocs are used to store pointers to access relocation for it.
|
I the latest push, I reverted the behavior change to apply R_RISCV_RELAX to all relocations at one offset. Now and as before, R_RISCV_RELAX is only applied to the previous relocation. |
Shankar Easwaran (quic-seaswara)
left a comment
There was a problem hiding this comment.
some initial comments, will review in detail shortly.
| llvm::DenseMap<const Relocation *, Relocation *> m_BaseRelocs; | ||
|
|
||
| /// Identify relocations that have an associated R_RISCV_RELAX. | ||
| llvm::DenseSet<const Relocation *> m_RelocsWithRelax; |
There was a problem hiding this comment.
can this be llvm:DenseSet<Relocation *> ?
There was a problem hiding this comment.
I would like keep the const because there is no need to update it through this set.
|
Sam Elliott (@lenary) ping pls. |
The relaxation loop is rewritten to test the "phase" in the outer layer and relocation type in the inner layer. This way the flow is clearer and it is easier to make modifications based on the type of relaxation. It may be also faster as we do not do multiple-choice tests when they are inapplicable. Moreover, the whole loop can now be rewritten as an explicit sequence of phases, if we want to. Signed-off-by: Alexey Karyakin <akaryaki@qti.qualcomm.com>
Previously, finding out if a relocation has an associated R_RISCV_RELAX was done by searching the list of relocations by offset. This led to picking a wrong R_RISCV_RELAX during relaxation because relocation offset can change during relaxation. The bug affects TLSDESC relocations and R_RISCV_QC_E_32/R_RISCV_QC_ACCESS_32/16 pairs (which were added just now) because their relaxation options depend on R_RISCV_RELAX attached to a different relocation. Create a side set to mark relocations that have R_RISCV_RELAX associated with them. The association has to be established after relocations are sorted by offset but before relaxation. It would be more efficient to add a flag in the Relocation object but that would increase it size. One option would be to shrink the type field, but unfortunately in ELF64 it has to be 32-bit. Fixes #1278 and #1276. Signed-off-by: Alexey Karyakin <akaryaki@qti.qualcomm.com>
Associate pcrel_lo/tlsdesc_lo relocations to the corresponding pcrel_hi tlsdesc_hi relocations after all relocations are sorted by offset. This allows us to remove the "pending" relocation list and create all relocations in the original order. This fixes the quadratic run time when every search for the pcrel_hi relocation required a full scan of the relocation list (three times!). the findRelocation() function is removed from ELFSection because it was only used for one purpose in the RISC-V backend only. Finding the vendor relocation still requires a linear search because handleVendorRelocation() can override creating the relocation by returning true, so this can't be moved after sorting. Signed-off-by: Alexey Karyakin <akaryaki@qti.qualcomm.com>
LastVisit was only used in the RISC-V backed to handle "pending" relocations. The addend is important and should not be omitted, and it never is. Signed-off-by: Alexey Karyakin <akaryaki@qti.qualcomm.com>
f2df8ea to
7f487df
Compare
Two related changes:
PCREL_LO12_*/RELAXrelocs when the LO is a forward reference #1276 and TLSDESC relaxations can incorrectly fire if they're next to a instruction markedRELAXthat will be deleted #1278)Fixes #1276 and #1278.