3030#include " llvm/CodeGen/MachineFunctionPass.h"
3131#include " llvm/CodeGen/MachineInstrBuilder.h"
3232#include " llvm/CodeGen/MachineRegisterInfo.h"
33+ #include " llvm/IR/Module.h"
3334#include " llvm/Support/Debug.h"
3435#include < set>
3536
@@ -308,6 +309,7 @@ struct BPFMIPreEmitPeephole : public MachineFunctionPass {
308309 const TargetRegisterInfo *TRI;
309310 const BPFInstrInfo *TII;
310311 bool SupportGotol;
312+ bool DoneConvertPrivGlobal;
311313
312314 BPFMIPreEmitPeephole () : MachineFunctionPass(ID) {}
313315
@@ -321,6 +323,7 @@ struct BPFMIPreEmitPeephole : public MachineFunctionPass {
321323 bool insertMissingCallerSavedSpills ();
322324 bool removeMayGotoZero ();
323325 bool addExitAfterUnreachable ();
326+ bool convertPrivateGlobal ();
324327
325328public:
326329
@@ -338,6 +341,7 @@ struct BPFMIPreEmitPeephole : public MachineFunctionPass {
338341 Changed |= insertMissingCallerSavedSpills ();
339342 Changed |= removeMayGotoZero ();
340343 Changed |= addExitAfterUnreachable ();
344+ Changed |= convertPrivateGlobal ();
341345 return Changed;
342346 }
343347};
@@ -348,6 +352,7 @@ void BPFMIPreEmitPeephole::initialize(MachineFunction &MFParm) {
348352 TII = MF->getSubtarget <BPFSubtarget>().getInstrInfo ();
349353 TRI = MF->getSubtarget <BPFSubtarget>().getRegisterInfo ();
350354 SupportGotol = MF->getSubtarget <BPFSubtarget>().hasGotol ();
355+ DoneConvertPrivGlobal = false ;
351356 LLVM_DEBUG (dbgs () << " *** BPF PreEmit peephole pass ***\n\n " );
352357}
353358
@@ -750,6 +755,48 @@ bool BPFMIPreEmitPeephole::addExitAfterUnreachable() {
750755 return true ;
751756}
752757
758+ bool BPFMIPreEmitPeephole::convertPrivateGlobal () {
759+ if (DoneConvertPrivGlobal)
760+ return false ;
761+ DoneConvertPrivGlobal = true ;
762+
763+ // A jump table associated with indirectbr looks like:
764+ // @__const.foo.jt1 = private unnamed_addr constant [2 x ptr]
765+ // [ptr blockaddress(@foo, %l1), ptr blockaddress(@foo, %l2)], align 8
766+ Module *M = MF->getFunction ().getParent ();
767+ for (GlobalVariable &Global : M->globals ()) {
768+ if (Global.getLinkage () != GlobalValue::PrivateLinkage)
769+ continue ;
770+ if (!Global.isConstant ())
771+ continue ;
772+ if (!Global.hasInitializer ())
773+ continue ;
774+
775+ Constant *CV = dyn_cast<Constant>(Global.getInitializer ());
776+ if (!CV)
777+ continue ;
778+ ConstantArray *CA = dyn_cast<ConstantArray>(CV);
779+ if (!CA)
780+ continue ;
781+
782+ for (unsigned i = 1 , e = CA->getNumOperands (); i != e; ++i) {
783+ if (!dyn_cast<BlockAddress>(CA->getOperand (i)))
784+ continue ;
785+ }
786+
787+ // All jump tables in the same .jumptables section.
788+ Global.setSection (" .jumptables" );
789+
790+ // The global symbol with PrivateLinkage (e.g. __const.foo.jt1) will add
791+ // a prefix like '.L' (e.g. .L__const.foo.jt1) which will prevent symbol
792+ // from appearing in the symbol table. Changing linkage type from
793+ // PrivateLinkage to ExternalLinkage can preserve the symbol name in the
794+ // symbol table and use the symbol name in relocation.
795+ Global.setLinkage (GlobalValue::ExternalLinkage);
796+ }
797+ return true ;
798+ }
799+
753800} // end default namespace
754801
755802INITIALIZE_PASS (BPFMIPreEmitPeephole, " bpf-mi-pemit-peephole" ,
0 commit comments