facebookarchive / BOLT

Binary Optimization and Layout Tool - A linux command-line utility used for optimizing performance of binaries
2.51k stars 176 forks source link

LongJmp: Fix alignment issues #241

Closed yota9 closed 2 years ago

yota9 commented 2 years ago

This patch fixes multiple problems:

Vladislav Khmelevsky, Advanced Software Technology Lab, Huawei

rafaelauler commented 2 years ago

Hi Vladislav! Can you elaborate on why do we need LongJmp running on X86? This is a very expensive pass and we should consider alternative solutions first, if possible.

It would help to have test cases showing the problem being solved so we can work on a solution together. I feel the PR, currently, is missing other changes and context to demonstrate what is being solved. For example, by the looks of it, I couldn't find a change that actually activated this pass for X86, right?

yota9 commented 2 years ago

Hello @rafaelauler ! This pass will be used with golang support. The problem with golang that we need exactly byte-to-byte binary reading from the source file and need byte-to-byte layout of the new binary before emitting it. So LLVM should not relax instructions by it's own after golang pass is finished. I've added longjmp support for x86 just recently, before that I've just relaxed all branches to long jumps in order to work with golang. So it will be activated only for golang :) P.S. This patch also solved couple of issues in with this pass in order to make it more accurate.

yota9 commented 2 years ago

@rafaelauler Actually it is not very expensive for x86, since here we rely on instruction relaxation. So no stubs are inserted and no fixbranches are needed easier. I didn't fix shortJmp/longJmp creation for x86, since +- 2Gb are seems to be enough for us currently :)

rafaelauler commented 2 years ago

Thanks for explaining it! How hard is it to add a test case that showcases this functionality being used? Also, it it possible to add to this PR the missing bits that will actually turn it on this pass on X86?

If I understood correctly, there is another pass that uses this, and that's why this feels, as it is, incomplete. What if we land first the module that uses this? Or maybe merge everything in the same PR? I don't have a problem with having a larger PR, as long as it is doing one thing that can be tested with a test case, and no dead code is being added.

rafaelauler commented 2 years ago

Another thing we can do, instead of doing one larger PR, is to open a new PR with a commit on top of this one, showing how this is used. But ideally, we would have a "self-contained" PR, that is, a set of changes that we can test with a test case.

yota9 commented 2 years ago

@rafaelauler Sure, let me remove x86 support (e.g. instruction relaxation), there are enough fixes not related to architecture support :)

rafaelauler commented 2 years ago

Sounds good!

yota9 commented 2 years ago

Hello @rafaelauler ! I've reverted the x86 specifics. Not completely, like the "InstSize" in getTargetOffset stays unused for now, but I dont't think it is a big deal, the rest of the code I've removed will be submitted with golang support.

rafaelauler commented 2 years ago

I'm getting a conflict on BinaryEmitter.cpp at the moment, can you rebase this?

PS: Use git -c merge.renamelimit=230 rebase (or cherry-pick, depending on your workflow)

yota9 commented 2 years ago

@rafaelauler Sure, done

HShan886 commented 2 years ago

Can this pr fix the core in #206 ?

yota9 commented 2 years ago

@Haishan312 You should check it :) P.S. Don't use align-blocks, it is unsupported and not related to this PR.

HShan886 commented 2 years ago

@Haishan312 You should check it :) P.S. Don't use align-blocks, it is unsupported and not related to this PR.

But, I still get a failure information "Assertion `isInt<21>(BranchImm)' failed". and it is same to #206 My binary is 602.gcc_s