This is an archive of the discontinued LLVM Phabricator instance.

[BOLT][AArch64] Handle gold linker veneers
ClosedPublic

Authored by yota9 on Jul 7 2022, 1:15 AM.

Details

Summary

The gold linker veneers are written between functions without symbols,
so we to handle it specially in BOLT.

Vladislav Khmelevsky,
Advanced Software Technology Lab, Huawei

Diff Detail

Event Timeline

yota9 created this revision.Jul 7 2022, 1:15 AM
yota9 requested review of this revision.Jul 7 2022, 1:15 AM
Herald added a project: Restricted Project. · View Herald TranscriptJul 7 2022, 1:15 AM
yota9 added a comment.Jul 7 2022, 1:18 AM

@rafauler I've add isIgnored check, could you please verify that everything is OK now?
P.S. How do you think should we add a test case from your binary for future (out of scope of this patch). Thank you!

Looks good, let me kick off tests

There's a memory leak the two tests:

  • TEST 'BOLT :: AArch64/veneer-gold.s' FAILED *******
  • TEST 'BOLT :: AArch64/veneer.s' FAILED ****

This is detected by just running our regular test suite, but with bolt built with address sanitizer from llvm. If you are using cmake, just add -DLLVM_USE_SANITIZER=Address if you are building bolt with clang.

Here's the leak stack trace:

74287==ERROR: LeakSanitizer: detected memory leaks

Direct leak of 176 byte(s) in 2 object(s) allocated from:

#0 in operator new(unsigned long) (build/bin/llvm-bolt+0x769ce7)
#1 in llvm::bolt::BinaryContext::registerNameAtAddress(llvm::StringRef, unsigned long, unsigned long, unsigned short, unsigned int) /bolt/lib/Core/BinaryContext.cpp:985:10
#2 in llvm::bolt::BinaryContext::getOrCreateGlobalSymbol(unsigned long, llvm::Twine, unsigned long, unsigned short, unsigned int) /bolt/lib/Core/BinaryContext.cpp:743:10
#3 in operator() /bolt/lib/Core/BinaryFunction.cpp:1095:23
#4 in llvm::bolt::BinaryFunction::disassemble() /bolt/lib/Core/BinaryFunction.cpp:1300:28
#5 in llvm::bolt::RewriteInstance::disassembleFunctions() /bolt/lib/Rewrite/RewriteInstance.cpp:2836:19
#6 in llvm::bolt::RewriteInstance::run() /bolt/lib/Rewrite/RewriteInstance.cpp:747:3
#7 in main /bolt/tools/driver/llvm-bolt.cpp:244:24
#8 in __libc_start_main 
#9 in _start

Indirect leak of 16 byte(s) in 2 object(s) allocated from:

#0 in operator new(unsigned long) 
#1 in allocate 
#2 in allocate
#3 in _M_allocate
#4 in _M_realloc_insert<llvm::MCSymbol *> 
#5 in emplace_back<llvm::MCSymbol *>
#6 in push_back /
#7 in llvm::bolt::BinaryData::BinaryData(llvm::MCSymbol&, unsigned long, unsigned long, unsigned short, llvm::bolt::BinarySection&, unsigned int) /bolt/lib/Core/BinaryData.cpp:136:11
#8 in llvm::bolt::BinaryContext::registerNameAtAddress(llvm::StringRef, unsigned long, unsigned long, unsigned short, unsigned int) /bolt/lib/Core/BinaryContext.cpp:985:14
#9 in llvm::bolt::BinaryContext::getOrCreateGlobalSymbol(unsigned long, llvm::Twine, unsigned long, unsigned short, unsigned int) /bolt/lib/Core/BinaryContext.cpp:743:10
#10 in operator() /bolt/lib/Core/BinaryFunction.cpp:1095:23
#11 in llvm::bolt::BinaryFunction::disassemble() /bolt/lib/Core/BinaryFunction.cpp:1300:28
#12 in llvm::bolt::RewriteInstance::disassembleFunctions() /bolt/lib/Rewrite/RewriteInstance.cpp:2836:19
#13 in llvm::bolt::RewriteInstance::run() /bolt/lib/Rewrite/RewriteInstance.cpp:747:3
#14 in main /bolt/tools/driver/llvm-bolt.cpp:244:24
#15 in __libc_start_main 
#16 in _start
rafauler added inline comments.Jul 8 2022, 2:52 PM
bolt/include/bolt/Core/BinaryContext.h
647

nit: I suspect btw that a regular "std::vector" makes more sense here (since you're not doing any operation that would be faster with a linked list)

yota9 added a comment.Jul 8 2022, 3:16 PM

@rafauler I'll try to check the cause of memory leak, probably it is connected to the VeneerElimination pass, since it is unusual case to create the new functions after disassemble but also remove them during passes, probably something is not handled properly..

bolt/include/bolt/Core/BinaryContext.h
647

On the previous review I wrote a comment about the reasons I've choosed to use list here, newely-handled veneers will create new external references, that must be added to the end of the list while iterating it. Also I don't think we want to reallocate and copy the old vector each time, so I'd prefer to stay with the list here to be honest

yota9 updated this revision to Diff 443497.Jul 10 2022, 5:55 AM

@rafauler Thanks for sanitizer logs! Although I didn't try it my self, but I've checked them and as I said it was a problem in veneer elimination pass, which was not delete the allocated binarydata struct previously. Now everything should be fine :)

yota9 added inline comments.Jul 10 2022, 9:13 AM
bolt/lib/Passes/VeneerElimination.cpp
39

Maybe instead of erasing this function and all its symbols we can just set isPseudo flag for BF? @rafauler what do you think about it?

yota9 updated this revision to Diff 443513.Jul 10 2022, 9:33 AM

@rafauler I've decided to go with isPseudo() for veneers, I don't think that the pass is an appropriate place to remove functions/symbols. + A bit of code refactoring in pass :)

yota9 updated this revision to Diff 443514.Jul 10 2022, 9:51 AM

Use veneers symbols directly in pass.

rafauler accepted this revision.Jul 12 2022, 12:31 PM

I agree, erasing functions in that pass seems hacky. Thanks.

This revision is now accepted and ready to land.Jul 12 2022, 12:31 PM
This revision was automatically updated to reflect the committed changes.