<s> unsigned BPFMCCodeEmitter :: getMachineOpValue ( const MCInst & MI , const MCOperand & MO , SmallVectorImpl < MCFixup > & Fixups ) const { if ( MO . isReg ( ) ) return getBPFRegisterNumbering ( MO . getReg ( ) ) ; if ( MO . isImm ( ) ) return static_cast < unsigned > ( MO . getImm ( ) ) ; assert ( MO . isExpr ( ) ) ; const MCExpr * Expr = MO . getExpr ( ) ; MCExpr :: ExprKind Kind = Expr -> getKind ( ) ; assert ( Kind == MCExpr :: SymbolRef ) ; if ( MI . getOpcode ( ) == BPF :: JAL ) { Fixups . push_back ( MCFixup :: Create ( 0 , Expr , FK_SecRel_4 ) ) ; } else if ( MI . getOpcode ( ) == BPF :: LD_imm64 ) { Fixups . push_back ( MCFixup :: Create ( 0 , Expr , FK_SecRel_8 ) ) ; } else { Fixups . push_back ( MCFixup :: Create ( 0 , Expr , FK_PCRel_2 ) ) ; } return 0 ; } </s>


<s> unsigned BPFMCCodeEmitter :: getMachineOpValue ( const MCInst & MI , const MCOperand & MO , SmallVectorImpl < MCFixup > & Fixups , const MCSubtargetInfo & STI ) const { if ( MO . isReg ( ) ) return MRI . getEncodingValue ( MO . getReg ( ) ) ; if ( MO . isImm ( ) ) return static_cast < unsigned > ( MO . getImm ( ) ) ; assert ( MO . isExpr ( ) ) ; const MCExpr * Expr = MO . getExpr ( ) ; assert ( Expr -> getKind ( ) == MCExpr :: SymbolRef ) ; if ( MI . getOpcode ( ) == BPF :: JAL ) Fixups . push_back ( MCFixup :: Create ( 0 , Expr , FK_SecRel_4 ) ) ; else if ( MI . getOpcode ( ) == BPF :: LD_imm64 ) Fixups . push_back ( MCFixup :: Create ( 0 , Expr , FK_SecRel_8 ) ) ; else Fixups . push_back ( MCFixup :: Create ( 0 , Expr , FK_PCRel_2 ) ) ; return 0 ; } </s>

getMachineOpValue - Return binary encoding of operand .


<s> unsigned BPFMCCodeEmitter :: getMachineOpValue ( const MCInst & MI , const MCOperand & MO , SmallVectorImpl < MCFixup > & Fixups , const MCSubtargetInfo & STI ) const { if ( MO . isReg ( ) ) return MRI . getEncodingValue ( MO . getReg ( ) ) ; if ( MO . isImm ( ) ) return static_cast < unsigned > ( MO . getImm ( ) ) ; assert ( MO . isExpr ( ) ) ; const MCExpr * Expr = MO . getExpr ( ) ; MCExpr :: ExprKind Kind = Expr -> getKind ( ) ; assert ( Kind == MCExpr :: SymbolRef ) ; if ( MI . getOpcode ( ) == BPF :: JAL ) Fixups . push_back ( MCFixup :: Create ( 0 , Expr , FK_SecRel_4 ) ) ; else if ( MI . getOpcode ( ) == BPF :: LD_imm64 ) Fixups . push_back ( MCFixup :: Create ( 0 , Expr , FK_SecRel_8 ) ) ; else Fixups . push_back ( MCFixup :: Create ( 0 , Expr , FK_PCRel_2 ) ) ; return 0 ; } </s>


<s> void BPFMCCodeEmitter :: encodeInstruction ( const MCInst & MI , raw_ostream & OS , SmallVectorImpl < MCFixup > & Fixups , const MCSubtargetInfo & STI ) const { unsigned Opcode = MI . getOpcode ( ) ; support :: endian :: Writer < support :: little > LE ( OS ) ; support :: endian :: Writer < support :: big > BE ( OS ) ; if ( Opcode == BPF :: LD_imm64 || Opcode == BPF :: LD_pseudo ) { uint64_t Value = getBinaryCodeForInstr ( MI , Fixups , STI ) ; LE . write < uint8_t > ( Value >> 56 ) ; if ( IsLittleEndian ) LE . write < uint8_t > ( ( Value >> 48 ) & 0xff ) ; else LE . write < uint8_t > ( SwapBits ( ( Value >> 48 ) & 0xff ) ) ; LE . write < uint16_t > ( 0 ) ; if ( IsLittleEndian ) LE . write < uint32_t > ( Value & 0xffffFFFF ) ; else BE . write < uint32_t > ( Value & 0xffffFFFF ) ; const MCOperand & MO = MI . getOperand ( 1 ) ; uint64_t Imm = MO . isImm ( ) ? MO . getImm ( ) : 0 ; LE . write < uint8_t > ( 0 ) ; LE . write < uint8_t > ( 0 ) ; LE . write < uint16_t > ( 0 ) ; if ( IsLittleEndian ) LE . write < uint32_t > ( Imm >> 32 ) ; else BE . write < uint32_t > ( Imm >> 32 ) ; } else { uint64_t Value = getBinaryCodeForInstr ( MI , Fixups , STI ) ; LE . write < uint8_t > ( Value >> 56 ) ; if ( IsLittleEndian ) { LE . write < uint8_t > ( ( Value >> 48 ) & 0xff ) ; LE . write < uint16_t > ( ( Value >> 32 ) & 0xffff ) ; LE . write < uint32_t > ( Value & 0xffffFFFF ) ; } else { LE . write < uint8_t > ( SwapBits ( ( Value >> 48 ) & 0xff ) ) ; BE . write < uint16_t > ( ( Value >> 32 ) & 0xffff ) ; BE . write < uint32_t > ( Value & 0xffffFFFF ) ; } } } </s>

Encode the given Inst to bytes and append to CB .


<s> unsigned BPFMCCodeEmitter :: getMachineOpValue ( const MCInst & MI , const MCOperand & MO , SmallVectorImpl < MCFixup > & Fixups , const MCSubtargetInfo & STI ) const { if ( MO . isReg ( ) ) return MRI . getEncodingValue ( MO . getReg ( ) ) ; if ( MO . isImm ( ) ) return static_cast < unsigned > ( MO . getImm ( ) ) ; assert ( MO . isExpr ( ) ) ; const MCExpr * Expr = MO . getExpr ( ) ; assert ( Expr -> getKind ( ) == MCExpr :: SymbolRef ) ; if ( MI . getOpcode ( ) == BPF :: JAL ) Fixups . push_back ( MCFixup :: create ( 0 , Expr , FK_SecRel_4 ) ) ; else if ( MI . getOpcode ( ) == BPF :: LD_imm64 ) Fixups . push_back ( MCFixup :: create ( 0 , Expr , FK_SecRel_8 ) ) ; else Fixups . push_back ( MCFixup :: create ( 0 , Expr , FK_PCRel_2 ) ) ; return 0 ; } </s>


<s> MCSymbol * BPFMCInstLower :: GetExternalSymbolSymbol ( const MachineOperand & MO ) const { return Printer . GetExternalSymbolSymbol ( MO . getSymbolName ( ) ) ; } </s>

Return the MCSymbol for the specified ExternalSymbol .


<s> bool evaluateBranch ( const MCInst & Inst , uint64_t Addr , uint64_t Size , uint64_t & Target ) const override { int16_t Imm ; if ( isConditionalBranch ( Inst ) ) { Imm = Inst . getOperand ( 2 ) . getImm ( ) ; } else if ( isUnconditionalBranch ( Inst ) ) Imm = Inst . getOperand ( 0 ) . getImm ( ) ; else return false ; Target = Addr + Size + Imm * Size ; return true ; } </s>

Given a branch instruction try to get the address the branch targets .


<s> bool runOnMachineFunction ( MachineFunction & MF ) override { if ( ! skipFunction ( MF . getFunction ( ) ) ) { initialize ( MF ) ; return processAtomicInsts ( ) ; } return false ; } </s>

runOnMachineFunction - Emit the function body .


<s>
void
BPFMIPreEmitChecking
::
initialize
(
MachineFunction
&
MFParm
)
{
MF
=
&
MFParm
;
TRI
=
MF
->
getSubtarget
<
BPFSubtarget
>
(
)
.
getRegisterInfo
(
)
;
LLVM_DEBUG
(
dbgs
(
)
<<
"*** BPF PreEmit checking pass ***\n\n"
)
;
}
</s>

Initialize the strategy after building the DAG for a new region .

BPF
BPF
BPF
"*** BPF PreEmit checking pass ***\n\n"


<s> bool runOnMachineFunction ( MachineFunction & MF ) override { if ( ! skipFunction ( MF . getFunction ( ) ) ) { initialize ( MF ) ; checkingIllegalXADD ( ) ; } return false ; } </s>


<s>
void
BPFMIPreEmitPeephole
::
initialize
(
MachineFunction
&
MFParm
)
{
MF
=
&
MFParm
;
TRI
=
MF
->
getSubtarget
<
BPFSubtarget
>
(
)
.
getRegisterInfo
(
)
;
DEBUG
(
dbgs
(
)
<<
"*** BPF PreEmit peephole pass ***\n\n"
)
;
}
</s>

BPF
BPF
BPF
"*** BPF PreEmit peephole pass ***\n\n"


<s> bool runOnMachineFunction ( MachineFunction & MF ) override { if ( skipFunction ( MF . getFunction ( ) ) ) return false ; initialize ( MF ) ; bool ZExtSeqExist , ZExtExist ; ZExtSeqExist = eliminateZExtSeq ( ) ; ZExtExist = eliminateZExt ( ) ; return ZExtSeqExist || ZExtExist ; } </s>


"*** BPF MachineSSA peephole pass ***\n\n"


"*** BPF MachineSSA TRUNC Elim peephole pass ***\n\n"


<s> bool runOnMachineFunction ( MachineFunction & MF ) override { if ( skipFunction ( MF . getFunction ( ) ) ) return false ; initialize ( MF ) ; return eliminateTruncSeq ( ) ; } </s>


<s> bool runOnMachineFunction ( MachineFunction & MF ) override { if ( skipFunction ( MF . getFunction ( ) ) ) return false ; initialize ( MF ) ; return removeLD ( ) ; } </s>


"*** BPF simplify patchable insts pass ***\n\n"


<s> bool runOnMachineFunction ( MachineFunction & MF ) override { if ( ! skipFunction ( MF . getFunction ( ) ) ) { initialize ( MF ) ; } return removeLD ( ) ; } </s>


<s>
StringRef
getPassName
(
)
const
override
{
return
"BPF Preserve DebugInfo Type"
;
}
</s>

getPassName - Return a nice clean name for a pass .


runOnModule - Virtual method overriden by subclasses to process the module being operated on .


runOnFunction - Virtual method overriden by subclasses to do the per-function processing of the pass .


<s> PreservedAnalyses BPFPreserveDITypePass :: run ( Function & F , FunctionAnalysisManager & AM ) { return BPFPreserveDITypeImpl ( F ) ? PreservedAnalyses :: none ( ) : PreservedAnalyses :: all ( ) ; } </s>

Run the analysis pass over a function and produce a dominator tree .


<s> bool BPFPreserveDIType :: runOnFunction ( Function & F ) { return BPFPreserveDITypeImpl ( F ) ; } </s>


"Instr doesn't have FrameIndex operand!"

This method must be overriden to eliminate abstract frame indices from instructions which may use them .


<s> const MCPhysReg * BPFRegisterInfo :: getCalleeSavedRegs ( const MachineFunction * MF ) const { return CSR_SaveList ; } </s>


<s> unsigned BPFRegisterInfo :: getFrameRegister ( const MachineFunction & MF ) const { return BPF :: R10 ; } </s>


<s> BitVector BPFRegisterInfo :: getReservedRegs ( const MachineFunction & MF ) const { BitVector Reserved ( getNumRegs ( ) ) ; Reserved . set ( BPF :: R10 ) ; Reserved . set ( BPF :: R11 ) ; return Reserved ; } </s>

getReservedRegs - Returns a bitset indexed by physical register number indicating if a register is a special register that has particular uses and should be considered unavailable at all times , e.g .


<s> BitVector BPFRegisterInfo :: getReservedRegs ( const MachineFunction & MF ) const { BitVector Reserved ( getNumRegs ( ) ) ; markSuperRegs ( Reserved , BPF :: W10 ) ; markSuperRegs ( Reserved , BPF :: W11 ) ; return Reserved ; } </s>


<s> const uint16_t * BPFRegisterInfo :: getCalleeSavedRegs ( const MachineFunction * MF ) const { return CSR_SaveList ; } </s>


<s> unsigned BPFRegisterInfo :: getRARegister ( ) const { return BPF :: R0 ; } </s>

This method should return the register where the return address can be found .


<s> void BPFRegisterInfo :: processFunctionBeforeFrameFinalized ( MachineFunction & MF ) const { } </s>

processFunctionBeforeFrameFinalized - This method is called immediately before the specified function 's frame layout ( MF.getFrameInfo ( ) ) is finalized .


<s> bool BPFRegisterInfo :: requiresRegisterScavenging ( const MachineFunction & MF ) const { return true ; } </s>

Returns true if the target requires ( and can make use of ) the register scavenger .


<s> Register BPFRegisterInfo :: getFrameRegister ( const MachineFunction & MF ) const { return BPF :: R10 ; } </s>


<s> void eliminateCallFramePseudoInstr ( MachineFunction & MF , MachineBasicBlock & MBB , MachineBasicBlock :: iterator I ) const { MBB . erase ( I ) ; } </s>

This method is called during prolog/epilog code insertion to eliminate call frame setup and destroy pseudo instructions ( but only if the Target is using them ) .


<s> SDValue BPFSelectionDAGInfo :: EmitTargetCodeForMemcpy ( SelectionDAG & DAG , const SDLoc & dl , SDValue Chain , SDValue Dst , SDValue Src , SDValue Size , Align Alignment , bool isVolatile , bool AlwaysInline , MachinePointerInfo DstPtrInfo , MachinePointerInfo SrcPtrInfo ) const { ConstantSDNode * ConstantSize = dyn_cast < ConstantSDNode > ( Size ) ; if ( ! ConstantSize ) return SDValue ( ) ; unsigned CopyLen = ConstantSize -> getZExtValue ( ) ; unsigned StoresNumEstimate = alignTo ( CopyLen , Alignment ) >> Log2 ( Alignment ) ; if ( StoresNumEstimate > getCommonMaxStoresPerMemFunc ( ) ) return SDValue ( ) ; SDVTList VTs = DAG . getVTList ( MVT :: Other , MVT :: Glue ) ; Dst = DAG . getNode ( BPFISD :: MEMCPY , dl , VTs , Chain , Dst , Src , DAG . getConstant ( CopyLen , dl , MVT :: i64 ) , DAG . getConstant ( Alignment . value ( ) , dl , MVT :: i64 ) ) ; return Dst . getValue ( 0 ) ; } </s>

Emit target-specific code that performs a memcpy .


<s> SDValue BPFSelectionDAGInfo :: EmitTargetCodeForMemcpy ( SelectionDAG & DAG , const SDLoc & dl , SDValue Chain , SDValue Dst , SDValue Src , SDValue Size , Align Alignment , bool isVolatile , bool AlwaysInline , bool MustPreserveCheriCapabilities , MachinePointerInfo DstPtrInfo , MachinePointerInfo SrcPtrInfo ) const { ConstantSDNode * ConstantSize = dyn_cast < ConstantSDNode > ( Size ) ; if ( ! ConstantSize ) return SDValue ( ) ; unsigned CopyLen = ConstantSize -> getZExtValue ( ) ; unsigned StoresNumEstimate = alignTo ( CopyLen , Alignment ) >> Log2 ( Alignment ) ; if ( StoresNumEstimate > getCommonMaxStoresPerMemFunc ( ) ) return SDValue ( ) ; SDVTList VTs = DAG . getVTList ( MVT :: Other , MVT :: Glue ) ; Dst = DAG . getNode ( BPFISD :: MEMCPY , dl , VTs , Chain , Dst , Src , DAG . getConstant ( CopyLen , dl , MVT :: i64 ) , DAG . getConstant ( Alignment . value ( ) , dl , MVT :: i64 ) ) ; return Dst . getValue ( 0 ) ; } </s>


<s> SDValue BPFSelectionDAGInfo :: EmitTargetCodeForMemcpy ( SelectionDAG & DAG , const SDLoc & dl , SDValue Chain , SDValue Dst , SDValue Src , SDValue Size , unsigned Align , bool isVolatile , bool AlwaysInline , MachinePointerInfo DstPtrInfo , MachinePointerInfo SrcPtrInfo ) const { ConstantSDNode * ConstantSize = dyn_cast < ConstantSDNode > ( Size ) ; if ( ! ConstantSize ) return SDValue ( ) ; unsigned CopyLen = ConstantSize -> getZExtValue ( ) ; unsigned StoresNumEstimate = alignTo ( CopyLen , Align ) >> Log2_32 ( Align ) ; if ( StoresNumEstimate > getCommonMaxStoresPerMemFunc ( ) ) return SDValue ( ) ; SDVTList VTs = DAG . getVTList ( MVT :: Other , MVT :: Glue ) ; Dst = DAG . getNode ( BPFISD :: MEMCPY , dl , VTs , Chain , Dst , Src , DAG . getConstant ( CopyLen , dl , MVT :: i64 ) , DAG . getConstant ( Align , dl , MVT :: i64 ) ) ; return Dst . getValue ( 0 ) ; } </s>


<s> BPFSubtarget & BPFSubtarget :: initializeSubtargetDependencies ( StringRef CPU , StringRef FS ) { initializeEnvironment ( ) ; initSubtargetFeatures ( CPU , FS ) ; ParseSubtargetFeatures ( CPU , CPU , FS ) ; return * this ; } </s>

initializeSubtargetDependencies - Initializes using a CPU , a TuneCPU , and feature string so that we can use initializer lists for subtarget initialization .


<s> BPFSubtarget & BPFSubtarget :: initializeSubtargetDependencies ( StringRef CPU , StringRef FS ) { initializeEnvironment ( ) ; initSubtargetFeatures ( CPU , FS ) ; return * this ; } </s>


<s> const BPFInstrInfo * getInstrInfo ( ) const override { return & InstrInfo ; } </s>


<s> const TargetRegisterInfo * getRegisterInfo ( ) const override { return & InstrInfo . getRegisterInfo ( ) ; } </s>

getRegisterInfo - TargetInstrInfo is a superset of MRegister info .


<s> BPFSubtarget & BPFSubtarget :: initializeSubtargetDependencies ( StringRef CPU , StringRef FS ) { initializeEnvironment ( ) ; initSubtargetFeatures ( CPU , FS ) ; ParseSubtargetFeatures ( CPU , FS ) ; return * this ; } </s>


<s> void BPFPassConfig :: addMachineSSAOptimization ( ) { TargetPassConfig :: addMachineSSAOptimization ( ) ; const BPFSubtarget * Subtarget = getBPFTargetMachine ( ) . getSubtargetImpl ( ) ; if ( Subtarget -> getHasAlu32 ( ) && ! DisableMIPeephole ) addPass ( createBPFMIPeepholePass ( ) ) ; } </s>

Methods with trivial inline returns are convenient points in the common codegen pass pipeline where targets may insert passes .


<s> void BPFPassConfig :: addPreEmitPass ( ) { const BPFSubtarget * Subtarget = getBPFTargetMachine ( ) . getSubtargetImpl ( ) ; addPass ( createBPFMIPreEmitCheckingPass ( ) ) ; if ( getOptLevel ( ) != CodeGenOpt :: None ) if ( Subtarget -> getHasAlu32 ( ) && ! DisableMIPeephole ) addPass ( createBPFMIPreEmitPeepholePass ( ) ) ; } </s>

This pass may be implemented by targets that want to run passes immediately before machine code is emitted .


<s> TargetPassConfig * BPFTargetMachine :: createPassConfig ( PassManagerBase & PM ) { return new BPFPassConfig ( * this , PM ) ; } </s>

Create a pass configuration object to be used by addPassToEmitX methods for generating a pipeline of CodeGen passes .


<s> bool BPFPassConfig :: addInstSelector ( ) { addPass ( createBPFISelDag ( getBPFTargetMachine ( ) ) ) ; return false ; } </s>

addInstSelector - This method should install an instruction selector pass , which converts from LLVM code to machine instructions .


<s> TargetPassConfig * BPFTargetMachine :: createPassConfig ( PassManagerBase & PM ) { return new BPFPassConfig ( this , PM ) ; } </s>


<s> void BPFPassConfig :: addIRPasses ( ) { addPass ( createBPFAbstractMemberAccess ( & getBPFTargetMachine ( ) ) ) ; TargetPassConfig :: addIRPasses ( ) ; } </s>

Add common target configurable passes that perform LLVM IR to IR transforms following machine independent optimization .


<s> void BPFPassConfig :: addMachineSSAOptimization ( ) { addPass ( createBPFMISimplifyPatchablePass ( ) ) ; TargetPassConfig :: addMachineSSAOptimization ( ) ; const BPFSubtarget * Subtarget = getBPFTargetMachine ( ) . getSubtargetImpl ( ) ; if ( Subtarget -> getHasAlu32 ( ) && ! DisableMIPeephole ) addPass ( createBPFMIPeepholePass ( ) ) ; } </s>


Invoke the PassBuilder callback registration .


<s> virtual const DataLayout * getDataLayout ( ) const { return & DL ; } </s>

Return the DataLayout associated with the module this SCEV instance is operating on .


<s> virtual const BPFInstrInfo * getInstrInfo ( ) const { return & InstrInfo ; } </s>


<s> virtual const BPFRegisterInfo * getRegisterInfo ( ) const { return & InstrInfo . getRegisterInfo ( ) ; } </s>


<s> virtual const BPFSubtarget * getSubtargetImpl ( ) const { return & Subtarget ; } </s>

Virtual method implemented by subclasses that returns a reference to that target 's TargetSubtargetInfo-derived member variable .


<s> TargetTransformInfo BPFTargetMachine :: getTargetTransformInfo ( const Function & F ) const { return TargetTransformInfo ( BPFTTIImpl ( this , F ) ) ; } </s>

Get a TargetTransformInfo implementation for the target .


<s> void BPFTargetMachine :: registerPassBuilderCallbacks ( PassBuilder & PB , bool DebugPassManager ) { PB . registerPipelineStartEPCallback ( [ = ] ( ModulePassManager & MPM , PassBuilder :: OptimizationLevel ) { FunctionPassManager FPM ( DebugPassManager ) ; FPM . addPass ( BPFAbstractMemberAccessPass ( this ) ) ; FPM . addPass ( BPFPreserveDITypePass ( ) ) ; MPM . addPass ( createModuleToFunctionPassAdaptor ( std :: move ( FPM ) ) ) ; } ) ; PB . registerPeepholeEPCallback ( [ = ] ( FunctionPassManager & FPM , PassBuilder :: OptimizationLevel Level ) { FPM . addPass ( SimplifyCFGPass ( SimplifyCFGOptions ( ) . hoistCommonInsts ( true ) ) ) ; } ) ; } </s>


<s> void BPFPassConfig :: addIRPasses ( ) { addPass ( createBPFAbstractMemberAccess ( & getBPFTargetMachine ( ) ) ) ; addPass ( createBPFPreserveDIType ( ) ) ; TargetPassConfig :: addIRPasses ( ) ; } </s>


<s> void BPFPassConfig :: addPreEmitPass ( ) { const BPFSubtarget * Subtarget = getBPFTargetMachine ( ) . getSubtargetImpl ( ) ; if ( getOptLevel ( ) != CodeGenOpt :: None ) if ( Subtarget -> getHasAlu32 ( ) && ! DisableMIPeephole ) addPass ( createBPFMIPreEmitPeepholePass ( ) ) ; } </s>


<s> void BPFPassConfig :: addIRPasses ( ) { addPass ( createBPFAbstractMemberAccess ( ) ) ; TargetPassConfig :: addIRPasses ( ) ; } </s>


<s> const DataLayout * getDataLayout ( ) const override { return & DL ; } </s>


<s> const BPFSubtarget * getSubtargetImpl ( ) const override { return & Subtarget ; } </s>


<s> void BPFTargetMachine :: registerPassBuilderCallbacks ( PassBuilder & PB , bool DebugPassManager ) { PB . registerPipelineStartEPCallback ( [ = ] ( ModulePassManager & MPM ) { FunctionPassManager FPM ( DebugPassManager ) ; FPM . addPass ( BPFAbstractMemberAccessPass ( this ) ) ; FPM . addPass ( BPFPreserveDITypePass ( ) ) ; MPM . addPass ( createModuleToFunctionPassAdaptor ( std :: move ( FPM ) ) ) ; } ) ; PB . registerPeepholeEPCallback ( [ = ] ( FunctionPassManager & FPM , PassBuilder :: OptimizationLevel Level ) { FPM . addPass ( SimplifyCFGPass ( SimplifyCFGOptions ( ) . hoistCommonInsts ( true ) ) ) ; } ) ; } </s>


<s> void BPFPassConfig :: addIRPasses ( ) { addPass ( createBPFCheckAndAdjustIR ( ) ) ; TargetPassConfig :: addIRPasses ( ) ; } </s>


<s> void BPFPassConfig :: addMachineSSAOptimization ( ) { addPass ( createBPFMISimplifyPatchablePass ( ) ) ; TargetPassConfig :: addMachineSSAOptimization ( ) ; const BPFSubtarget * Subtarget = getBPFTargetMachine ( ) . getSubtargetImpl ( ) ; if ( ! DisableMIPeephole ) { if ( Subtarget -> getHasAlu32 ( ) ) addPass ( createBPFMIPeepholePass ( ) ) ; addPass ( createBPFMIPeepholeTruncElimPass ( ) ) ; } } </s>


<s> void BPFPassConfig :: addPreEmitPass ( ) { addPass ( createBPFMIPreEmitCheckingPass ( ) ) ; if ( getOptLevel ( ) != CodeGenOpt :: None ) if ( ! DisableMIPeephole ) addPass ( createBPFMIPreEmitPeepholePass ( ) ) ; } </s>


<s> TargetLoweringObjectFile * getObjFileLowering ( ) const override { return TLOF . get ( ) ; } </s>

Return information about object file lowering .


<s> const BPFSubtarget * getSubtargetImpl ( const Function & ) const override { return & Subtarget ; } </s>


<s> TargetTransformInfo BPFTargetMachine :: getTargetTransformInfo ( const Function & F ) { return TargetTransformInfo ( BPFTTIImpl ( this , F ) ) ; } </s>


<s> InstructionCost getArithmeticInstrCost ( unsigned Opcode , Type * Ty , TTI :: TargetCostKind CostKind = TTI :: TCK_RecipThroughput , TTI :: OperandValueKind Opd1Info = TTI :: OK_AnyValue , TTI :: OperandValueKind Opd2Info = TTI :: OK_AnyValue , TTI :: OperandValueProperties Opd1PropInfo = TTI :: OP_None , TTI :: OperandValueProperties Opd2PropInfo = TTI :: OP_None , ArrayRef < const Value * > Args = ArrayRef < const Value * > ( ) , const Instruction * CxtI = nullptr ) { int ISD = TLI -> InstructionOpcodeToISD ( Opcode ) ; if ( ISD == ISD :: ADD && CostKind == TTI :: TCK_RecipThroughput ) return SCEVCheapExpansionBudget . getValue ( ) + 1 ; return BaseT :: getArithmeticInstrCost ( Opcode , Ty , CostKind , Opd1Info , Opd2Info , Opd1PropInfo , Opd2PropInfo ) ; } </s>

This is an approximation of reciprocal throughput of a math/logic op .


<s> InstructionCost getArithmeticInstrCost ( unsigned Opcode , Type * Ty , TTI :: TargetCostKind CostKind , TTI :: OperandValueKind Opd1Info = TTI :: OK_AnyValue , TTI :: OperandValueKind Opd2Info = TTI :: OK_AnyValue , TTI :: OperandValueProperties Opd1PropInfo = TTI :: OP_None , TTI :: OperandValueProperties Opd2PropInfo = TTI :: OP_None , ArrayRef < const Value * > Args = ArrayRef < const Value * > ( ) , const Instruction * CxtI = nullptr ) { int ISD = TLI -> InstructionOpcodeToISD ( Opcode ) ; if ( ISD == ISD :: ADD && CostKind == TTI :: TCK_RecipThroughput ) return SCEVCheapExpansionBudget . getValue ( ) + 1 ; return BaseT :: getArithmeticInstrCost ( Opcode , Ty , CostKind , Opd1Info , Opd2Info , Opd1PropInfo , Opd2PropInfo ) ; } </s>


<s> int getIntImmCost ( const APInt & Imm , Type * Ty , TTI :: TargetCostKind CostKind ) { if ( Imm . getBitWidth ( ) <= 64 && isInt < 32 > ( Imm . getSExtValue ( ) ) ) return TTI :: TCC_Free ; return TTI :: TCC_Basic ; } </s>

Calculate the cost of materializing a 64-bit value .


<s> const BPFTargetLowering * getTLI ( ) const { return TLI ; } </s>

Getter for generic TargetLowering class .


<s> uint32_t BTFStringTable :: addString ( StringRef S ) { for ( auto & OffsetM : OffsetToIdMap ) { if ( Table [ OffsetM . second ] == S ) return OffsetM . first ; } uint32_t Offset = Size ; OffsetToIdMap [ Offset ] = Table . size ( ) ; Table . push_back ( S ) ; Size += S . size ( ) + 1 ; return Offset ; } </s>


<s> uint32_t BTFDebug :: addType ( std :: unique_ptr < BTFTypeBase > TypeEntry ) { TypeEntry -> setId ( TypeEntries . size ( ) + 1 ) ; uint32_t Id = TypeEntry -> getId ( ) ; TypeEntries . push_back ( std :: move ( TypeEntry ) ) ; return Id ; } </s>

Add a new type attribute to the specified entity .


<s>
void
BTFDebug
::
beginFunctionImpl
(
const
MachineFunction
*
MF
)
{
auto
*
SP
=
MF
->
getFunction
(
)
.
getSubprogram
(
)
;
auto
*
Unit
=
SP
->
getUnit
(
)
;
if
(
Unit
->
getEmissionKind
(
)
==
DICompileUnit
::
NoDebug
)
{
SkipInstruction
=
true
;
return
;
}
SkipInstruction
=
false
;
std
::
unordered_map
<
uint32_t
,
StringRef
>
FuncArgNames
;
for
(
const
DINode
*
DN
:
SP
->
getRetainedNodes
(
)
)
{
if
(
const
auto
*
DV
=
dyn_cast
<
DILocalVariable
>
(
DN
)
)
{
visitTypeEntry
(
DV
->
getType
(
)
.
resolve
(
)
)
;
uint32_t
Arg
=
DV
->
getArg
(
)
;
if
(
Arg
)
FuncArgNames
[
Arg
]
=
DV
->
getName
(
)
;
}
}
uint32_t
ProtoTypeId
;
visitSubroutineType
(
SP
->
getType
(
)
,
true
,
FuncArgNames
,
ProtoTypeId
)
;
auto
FuncTypeEntry
=
llvm
::
make_unique
<
BTFTypeFunc
>
(
SP
->
getName
(
)
,
ProtoTypeId
)
;
uint32_t
FuncTypeId
=
addType
(
std
::
move
(
FuncTypeEntry
)
)
;
MCSymbol
*
FuncLabel
=
Asm
->
getFunctionBegin
(
)
;
BTFFuncInfo
FuncInfo
;
FuncInfo
.
Label
=
FuncLabel
;
FuncInfo
.
TypeId
=
FuncTypeId
;
if
(
FuncLabel
->
isInSection
(
)
)
{
MCSection
&
Section
=
FuncLabel
->
getSection
(
)
;
const
MCSectionELF
*
SectionELF
=
dyn_cast
<
MCSectionELF
>
(
&
Section
)
;
assert
(
SectionELF
&&
"Null section for Function Label"
)
;
SecNameOff
=
addString
(
SectionELF
->
getSectionName
(
)
)
;
}
else
{
SecNameOff
=
addString
(
".text"
)
;
}
FuncInfoTable
[
SecNameOff
]
.
push_back
(
FuncInfo
)
;
}
</s>

BPF
"Null section for Function Label"
".text"


<s> void BTFDebug :: beginInstruction ( const MachineInstr * MI ) { DebugHandlerBase :: beginInstruction ( MI ) ; if ( SkipInstruction || MI -> isMetaInstruction ( ) || MI -> getFlag ( MachineInstr :: FrameSetup ) ) return ; if ( MI -> isInlineAsm ( ) ) { unsigned NumDefs = 0 ; for ( ; MI -> getOperand ( NumDefs ) . isReg ( ) && MI -> getOperand ( NumDefs ) . isDef ( ) ; ++ NumDefs ) ; const char * AsmStr = MI -> getOperand ( NumDefs ) . getSymbolName ( ) ; if ( AsmStr [ 0 ] == 0 ) return ; } const DebugLoc & DL = MI -> getDebugLoc ( ) ; if ( ! DL || PrevInstLoc == DL ) { if ( LineInfoGenerated == false ) { auto * S = MI -> getMF ( ) -> getFunction ( ) . getSubprogram ( ) ; MCSymbol * FuncLabel = Asm -> getFunctionBegin ( ) ; constructLineInfo ( S , FuncLabel , S -> getLine ( ) , 0 ) ; LineInfoGenerated = true ; } return ; } MCSymbol * LineSym = OS . getContext ( ) . createTempSymbol ( ) ; OS . EmitLabel ( LineSym ) ; auto SP = DL . get ( ) -> getScope ( ) -> getSubprogram ( ) ; constructLineInfo ( SP , LineSym , DL . getLine ( ) , DL . getCol ( ) ) ; LineInfoGenerated = true ; PrevInstLoc = DL ; } </s>


<s>
BTFTypeDerived
::
BTFTypeDerived
(
const
DIDerivedType
*
DTy
,
unsigned
Tag
)
:
DTy
(
DTy
)
{
switch
(
Tag
)
{
case
dwarf
::
DW_TAG_pointer_type
:
Kind
=
BTF
::
BTF_KIND_PTR
;
break
;
case
dwarf
::
DW_TAG_const_type
:
Kind
=
BTF
::
BTF_KIND_CONST
;
break
;
case
dwarf
::
DW_TAG_volatile_type
:
Kind
=
BTF
::
BTF_KIND_VOLATILE
;
break
;
case
dwarf
::
DW_TAG_typedef
:
Kind
=
BTF
::
BTF_KIND_TYPEDEF
;
break
;
case
dwarf
::
DW_TAG_restrict_type
:
Kind
=
BTF
::
BTF_KIND_RESTRICT
;
break
;
default
:
llvm_unreachable
(
"Unknown DIDerivedType Tag"
)
;
}
BTFType
.
Info
=
Kind
<<
24
;
}
</s>


<s> BTFTypeFuncProto :: BTFTypeFuncProto ( const DISubroutineType * STy , uint32_t VLen , const std :: unordered_map < uint32_t , StringRef > & FuncArgNames ) : STy ( STy ) , FuncArgNames ( FuncArgNames ) { Kind = BTF :: BTF_KIND_FUNC_PROTO ; BTFType . Info = ( Kind << 24 ) | VLen ; } </s>

The Func kind represents both subprogram and pointee of function pointers .


<s> BTFTypeFwd :: BTFTypeFwd ( StringRef Name , bool IsUnion ) : Name ( Name ) { Kind = BTF :: BTF_KIND_FWD ; BTFType . Info = IsUnion << 31 | Kind << 24 ; BTFType . Type = 0 ; } </s>

Represent a struct/union forward declaration .


<s> BTFTypeStruct :: BTFTypeStruct ( const DICompositeType * STy , bool IsStruct , bool HasBitField , uint32_t Vlen ) : STy ( STy ) , HasBitField ( HasBitField ) { Kind = IsStruct ? BTF :: BTF_KIND_STRUCT : BTF :: BTF_KIND_UNION ; BTFType . Size = roundupToBytes ( STy -> getSizeInBits ( ) ) ; BTFType . Info = ( HasBitField << 31 ) | ( Kind << 24 ) | Vlen ; } </s>


<s> void BTFTypeFunc :: completeType ( BTFDebug & BDebug ) { BTFType . NameOff = BDebug . addString ( Name ) ; } </s>

Complete BTF type generation after all related DebugInfo types have been visited so their BTF type id 's are available for cross referece .


<s> void BTFDebug :: emitCommonHeader ( ) { OS . AddComment ( "0x" + Twine :: utohexstr ( BTF :: MAGIC ) ) ; OS . EmitIntValue ( BTF :: MAGIC , 2 ) ; OS . EmitIntValue ( BTF :: VERSION , 1 ) ; OS . EmitIntValue ( 0 , 1 ) ; } </s>

Emit the common part of the header for this unit .


<s> void BTFTypeFunc :: emitType ( MCStreamer & OS ) { BTFTypeBase :: emitType ( OS ) ; } </s>


<s> void BTFDebug :: endFunctionImpl ( const MachineFunction * MF ) { SkipInstruction = false ; LineInfoGenerated = false ; SecNameOff = 0 ; } </s>

Gather and emit post-function debug information .


<s> void BTFDebug :: endModule ( ) { const Module * M = MMI -> getModule ( ) ; for ( const DICompileUnit * CUNode : M -> debug_compile_units ( ) ) { for ( const auto * GVE : CUNode -> getGlobalVariables ( ) ) { DIGlobalVariable * GV = GVE -> getVariable ( ) ; visitTypeEntry ( GV -> getType ( ) . resolve ( ) ) ; } } for ( const auto & TypeEntry : TypeEntries ) TypeEntry -> completeType ( * this ) ; emitBTFSection ( ) ; emitBTFExtSection ( ) ; } </s>

Emit all exception information that should come after the content .


<s>
void
BTFDebug
::
beginFunctionImpl
(
const
MachineFunction
*
MF
)
{
auto
*
SP
=
MF
->
getFunction
(
)
.
getSubprogram
(
)
;
auto
*
Unit
=
SP
->
getUnit
(
)
;
if
(
Unit
->
getEmissionKind
(
)
==
DICompileUnit
::
NoDebug
)
{
SkipInstruction
=
true
;
return
;
}
SkipInstruction
=
false
;
if
(
MapDefNotCollected
)
{
processGlobals
(
true
)
;
MapDefNotCollected
=
false
;
}
std
::
unordered_map
<
uint32_t
,
StringRef
>
FuncArgNames
;
for
(
const
DINode
*
DN
:
SP
->
getRetainedNodes
(
)
)
{
if
(
const
auto
*
DV
=
dyn_cast
<
DILocalVariable
>
(
DN
)
)
{
uint32_t
Arg
=
DV
->
getArg
(
)
;
if
(
Arg
)
{
visitTypeEntry
(
DV
->
getType
(
)
)
;
FuncArgNames
[
Arg
]
=
DV
->
getName
(
)
;
}
}
}
uint32_t
ProtoTypeId
;
visitSubroutineType
(
SP
->
getType
(
)
,
true
,
FuncArgNames
,
ProtoTypeId
)
;
uint8_t
Scope
=
SP
->
isLocalToUnit
(
)
BTF
::
FUNC_STATIC
:
BTF
::
FUNC_GLOBAL
;
auto
FuncTypeEntry
=
std
::
make_unique
<
BTFTypeFunc
>
(
SP
->
getName
(
)
,
ProtoTypeId
,
Scope
)
;
uint32_t
FuncTypeId
=
addType
(
std
::
move
(
FuncTypeEntry
)
)
;
for
(
const
auto
&
TypeEntry
:
TypeEntries
)
TypeEntry
->
completeType
(
*
this
)
;
MCSymbol
*
FuncLabel
=
Asm
->
getFunctionBegin
(
)
;
BTFFuncInfo
FuncInfo
;
FuncInfo
.
Label
=
FuncLabel
;
FuncInfo
.
TypeId
=
FuncTypeId
;
if
(
FuncLabel
->
isInSection
(
)
)
{
MCSection
&
Section
=
FuncLabel
->
getSection
(
)
;
const
MCSectionELF
*
SectionELF
=
dyn_cast
<
MCSectionELF
>
(
&
Section
)
;
assert
(
SectionELF
&&
"Null section for Function Label"
)
;
SecNameOff
=
addString
(
SectionELF
->
getName
(
)
)
;
}
else
{
SecNameOff
=
addString
(
".text"
)
;
}
FuncInfoTable
[
SecNameOff
]
.
push_back
(
FuncInfo
)
;
}
</s>


<s> void BTFDebug :: beginInstruction ( const MachineInstr * MI ) { DebugHandlerBase :: beginInstruction ( MI ) ; if ( SkipInstruction || MI -> isMetaInstruction ( ) || MI -> getFlag ( MachineInstr :: FrameSetup ) ) return ; if ( MI -> isInlineAsm ( ) ) { unsigned NumDefs = 0 ; for ( ; MI -> getOperand ( NumDefs ) . isReg ( ) && MI -> getOperand ( NumDefs ) . isDef ( ) ; ++ NumDefs ) ; const char * AsmStr = MI -> getOperand ( NumDefs ) . getSymbolName ( ) ; if ( AsmStr [ 0 ] == 0 ) return ; } if ( MI -> getOpcode ( ) == BPF :: LD_imm64 ) { processReloc ( MI -> getOperand ( 1 ) ) ; } else if ( MI -> getOpcode ( ) == BPF :: CORE_MEM || MI -> getOpcode ( ) == BPF :: CORE_ALU32_MEM || MI -> getOpcode ( ) == BPF :: CORE_SHIFT ) { processReloc ( MI -> getOperand ( 3 ) ) ; } else if ( MI -> getOpcode ( ) == BPF :: JAL ) { const MachineOperand & MO = MI -> getOperand ( 0 ) ; if ( MO . isGlobal ( ) ) { processFuncPrototypes ( dyn_cast < Function > ( MO . getGlobal ( ) ) ) ; } } const DebugLoc & DL = MI -> getDebugLoc ( ) ; if ( ! DL || PrevInstLoc == DL ) { if ( LineInfoGenerated == false ) { auto * S = MI -> getMF ( ) -> getFunction ( ) . getSubprogram ( ) ; MCSymbol * FuncLabel = Asm -> getFunctionBegin ( ) ; constructLineInfo ( S , FuncLabel , S -> getLine ( ) , 0 ) ; LineInfoGenerated = true ; } return ; } MCSymbol * LineSym = OS . getContext ( ) . createTempSymbol ( ) ; OS . emitLabel ( LineSym ) ; auto SP = DL . get ( ) -> getScope ( ) -> getSubprogram ( ) ; constructLineInfo ( SP , LineSym , DL . getLine ( ) , DL . getCol ( ) ) ; LineInfoGenerated = true ; PrevInstLoc = DL ; } </s>


<s> bool BTFDebug :: InstLower ( const MachineInstr * MI , MCInst & OutMI ) { if ( MI -> getOpcode ( ) == BPF :: LD_imm64 ) { const MachineOperand & MO = MI -> getOperand ( 1 ) ; if ( MO . isGlobal ( ) ) { const GlobalValue * GVal = MO . getGlobal ( ) ; auto * GVar = dyn_cast < GlobalVariable > ( GVal ) ; if ( GVar ) { uint32_t Imm ; if ( GVar -> hasAttribute ( BPFCoreSharedInfo :: AmaAttr ) || GVar -> hasAttribute ( BPFCoreSharedInfo :: TypeIdAttr ) ) Imm = PatchImms [ GVar ] ; else return false ; OutMI . setOpcode ( BPF :: MOV_ri ) ; OutMI . addOperand ( MCOperand :: createReg ( MI -> getOperand ( 0 ) . getReg ( ) ) ) ; OutMI . addOperand ( MCOperand :: createImm ( Imm ) ) ; return true ; } } } else if ( MI -> getOpcode ( ) == BPF :: CORE_MEM || MI -> getOpcode ( ) == BPF :: CORE_ALU32_MEM || MI -> getOpcode ( ) == BPF :: CORE_SHIFT ) { const MachineOperand & MO = MI -> getOperand ( 3 ) ; if ( MO . isGlobal ( ) ) { const GlobalValue * GVal = MO . getGlobal ( ) ; auto * GVar = dyn_cast < GlobalVariable > ( GVal ) ; if ( GVar && GVar -> hasAttribute ( BPFCoreSharedInfo :: AmaAttr ) ) { uint32_t Imm = PatchImms [ GVar ] ; OutMI . setOpcode ( MI -> getOperand ( 1 ) . getImm ( ) ) ; if ( MI -> getOperand ( 0 ) . isImm ( ) ) OutMI . addOperand ( MCOperand :: createImm ( MI -> getOperand ( 0 ) . getImm ( ) ) ) ; else OutMI . addOperand ( MCOperand :: createReg ( MI -> getOperand ( 0 ) . getReg ( ) ) ) ; OutMI . addOperand ( MCOperand :: createReg ( MI -> getOperand ( 2 ) . getReg ( ) ) ) ; OutMI . addOperand ( MCOperand :: createImm ( Imm ) ) ; return true ; } } } return false ; } </s>


<s>
void
BTFDebug
::
beginFunctionImpl
(
const
MachineFunction
*
MF
)
{
auto
*
SP
=
MF
->
getFunction
(
)
.
getSubprogram
(
)
;
auto
*
Unit
=
SP
->
getUnit
(
)
;
if
(
Unit
->
getEmissionKind
(
)
==
DICompileUnit
::
NoDebug
)
{
SkipInstruction
=
true
;
return
;
}
SkipInstruction
=
false
;
if
(
MapDefNotCollected
)
{
processGlobals
(
true
)
;
MapDefNotCollected
=
false
;
}
std
::
unordered_map
<
uint32_t
,
StringRef
>
FuncArgNames
;
for
(
const
DINode
*
DN
:
SP
->
getRetainedNodes
(
)
)
{
if
(
const
auto
*
DV
=
dyn_cast
<
DILocalVariable
>
(
DN
)
)
{
uint32_t
Arg
=
DV
->
getArg
(
)
;
if
(
Arg
)
{
visitTypeEntry
(
DV
->
getType
(
)
)
;
FuncArgNames
[
Arg
]
=
DV
->
getName
(
)
;
}
}
}
uint32_t
ProtoTypeId
;
visitSubroutineType
(
SP
->
getType
(
)
,
true
,
FuncArgNames
,
ProtoTypeId
)
;
auto
FuncTypeEntry
=
std
::
make_unique
<
BTFTypeFunc
>
(
SP
->
getName
(
)
,
ProtoTypeId
)
;
uint32_t
FuncTypeId
=
addType
(
std
::
move
(
FuncTypeEntry
)
)
;
for
(
const
auto
&
TypeEntry
:
TypeEntries
)
TypeEntry
->
completeType
(
*
this
)
;
MCSymbol
*
FuncLabel
=
Asm
->
getFunctionBegin
(
)
;
BTFFuncInfo
FuncInfo
;
FuncInfo
.
Label
=
FuncLabel
;
FuncInfo
.
TypeId
=
FuncTypeId
;
if
(
FuncLabel
->
isInSection
(
)
)
{
MCSection
&
Section
=
FuncLabel
->
getSection
(
)
;
const
MCSectionELF
*
SectionELF
=
dyn_cast
<
MCSectionELF
>
(
&
Section
)
;
assert
(
SectionELF
&&
"Null section for Function Label"
)
;
SecNameOff
=
addString
(
SectionELF
->
getSectionName
(
)
)
;
}
else
{
SecNameOff
=
addString
(
".text"
)
;
}
FuncInfoTable
[
SecNameOff
]
.
push_back
(
FuncInfo
)
;
}
</s>


<s> void BTFDebug :: beginInstruction ( const MachineInstr * MI ) { DebugHandlerBase :: beginInstruction ( MI ) ; if ( SkipInstruction || MI -> isMetaInstruction ( ) || MI -> getFlag ( MachineInstr :: FrameSetup ) ) return ; if ( MI -> isInlineAsm ( ) ) { unsigned NumDefs = 0 ; for ( ; MI -> getOperand ( NumDefs ) . isReg ( ) && MI -> getOperand ( NumDefs ) . isDef ( ) ; ++ NumDefs ) ; const char * AsmStr = MI -> getOperand ( NumDefs ) . getSymbolName ( ) ; if ( AsmStr [ 0 ] == 0 ) return ; } if ( MI -> getOpcode ( ) == BPF :: LD_imm64 ) processLDimm64 ( MI ) ; const DebugLoc & DL = MI -> getDebugLoc ( ) ; if ( ! DL || PrevInstLoc == DL ) { if ( LineInfoGenerated == false ) { auto * S = MI -> getMF ( ) -> getFunction ( ) . getSubprogram ( ) ; MCSymbol * FuncLabel = Asm -> getFunctionBegin ( ) ; constructLineInfo ( S , FuncLabel , S -> getLine ( ) , 0 ) ; LineInfoGenerated = true ; } return ; } MCSymbol * LineSym = OS . getContext ( ) . createTempSymbol ( ) ; OS . EmitLabel ( LineSym ) ; auto SP = DL . get ( ) -> getScope ( ) -> getSubprogram ( ) ; constructLineInfo ( SP , LineSym , DL . getLine ( ) , DL . getCol ( ) ) ; LineInfoGenerated = true ; PrevInstLoc = DL ; } </s>


<s> void BTFTypeEnum :: completeType ( BTFDebug & BDebug ) { if ( IsCompleted ) return ; IsCompleted = true ; BTFType . NameOff = BDebug . addString ( ETy -> getName ( ) ) ; DINodeArray Elements = ETy -> getElements ( ) ; for ( const auto Element : Elements ) { const auto * Enum = cast < DIEnumerator > ( Element ) ; struct BTF :: BTFEnum BTFEnum ; BTFEnum . NameOff = BDebug . addString ( Enum -> getName ( ) ) ; BTFEnum . Val = static_cast < uint32_t > ( Enum -> getValue ( ) ) ; EnumValues . push_back ( BTFEnum ) ; } } </s>


<s> void BTFKindDataSec :: emitType ( MCStreamer & OS ) { BTFTypeBase :: emitType ( OS ) ; for ( const auto & V : Vars ) { OS . EmitIntValue ( std :: get < 0 > ( V ) , 4 ) ; Asm -> EmitLabelReference ( std :: get < 1 > ( V ) , 4 ) ; OS . EmitIntValue ( std :: get < 2 > ( V ) , 4 ) ; } } </s>


<s> std :: string BTFTypeStruct :: getName ( ) { return STy -> getName ( ) ; } </s>

Return a string with the name of the plan and the applicable VFs and UFs .


<s> uint32_t getSize ( ) { return BTFTypeBase :: getSize ( ) + BTF :: BTFDataSecVarSize * Vars . size ( ) ; } </s>

Return the number of bytes in the encoding of this instruction , or zero if the encoding size can not be known from the opcode .


<s> bool BTFDebug :: InstLower ( const MachineInstr * MI , MCInst & OutMI ) { if ( MI -> getOpcode ( ) == BPF :: LD_imm64 ) { const MachineOperand & MO = MI -> getOperand ( 1 ) ; if ( MO . isGlobal ( ) ) { const GlobalValue * GVal = MO . getGlobal ( ) ; auto * GVar = dyn_cast < GlobalVariable > ( GVal ) ; if ( GVar && GVar -> hasAttribute ( BPFCoreSharedInfo :: AmaAttr ) ) { uint32_t Imm = PatchImms [ GVar -> getName ( ) . str ( ) ] ; OutMI . setOpcode ( BPF :: MOV_ri ) ; OutMI . addOperand ( MCOperand :: createReg ( MI -> getOperand ( 0 ) . getReg ( ) ) ) ; OutMI . addOperand ( MCOperand :: createImm ( Imm ) ) ; return true ; } else if ( GVar && ! GVar -> hasInitializer ( ) && GVar -> hasExternalLinkage ( ) && GVar -> getSection ( ) == BPFCoreSharedInfo :: PatchableExtSecName ) { const IntegerType * IntTy = dyn_cast < IntegerType > ( GVar -> getValueType ( ) ) ; assert ( IntTy ) ; if ( IntTy -> getBitWidth ( ) == 64 ) OutMI . setOpcode ( BPF :: LD_imm64 ) ; else OutMI . setOpcode ( BPF :: MOV_ri ) ; OutMI . addOperand ( MCOperand :: createReg ( MI -> getOperand ( 0 ) . getReg ( ) ) ) ; OutMI . addOperand ( MCOperand :: createImm ( 0 ) ) ; return true ; } } } return false ; } </s>


<s> BTFTypeDerived :: BTFTypeDerived ( unsigned NextTypeId , unsigned Tag , StringRef Name ) : DTy ( nullptr ) , NeedsFixup ( false ) , Name ( Name ) { Kind = BTF :: BTF_KIND_PTR ; BTFType . Info = Kind << 24 ; BTFType . Type = NextTypeId ; } </s>


<s> void BTFTypeTypeTag :: completeType ( BTFDebug & BDebug ) { if ( IsCompleted ) return ; IsCompleted = true ; BTFType . NameOff = BDebug . addString ( Tag ) ; if ( DTy ) { const DIType * ResolvedType = DTy -> getBaseType ( ) ; if ( ! ResolvedType ) BTFType . Type = 0 ; else BTFType . Type = BDebug . getTypeId ( ResolvedType ) ; } } </s>


<s> void BTFDebug :: endModule ( ) { if ( MapDefNotCollected ) { processGlobals ( true ) ; MapDefNotCollected = false ; } processGlobals ( false ) ; for ( auto & DataSec : DataSecEntries ) addType ( std :: move ( DataSec . second ) ) ; for ( auto & Fixup : FixupDerivedTypes ) { const DICompositeType * CTy = Fixup . first ; StringRef TypeName = CTy -> getName ( ) ; bool IsUnion = CTy -> getTag ( ) == dwarf :: DW_TAG_union_type ; uint32_t StructTypeId = 0 ; for ( const auto & StructType : StructTypes ) { if ( StructType -> getName ( ) == TypeName ) { StructTypeId = StructType -> getId ( ) ; break ; } } if ( StructTypeId == 0 ) { auto FwdTypeEntry = std :: make_unique < BTFTypeFwd > ( TypeName , IsUnion ) ; StructTypeId = addType ( std :: move ( FwdTypeEntry ) ) ; } for ( auto & TypeInfo : Fixup . second ) { const DIDerivedType * DTy = TypeInfo . first ; BTFTypeDerived * BDType = TypeInfo . second ; int TmpTypeId = genBTFTypeTags ( DTy , StructTypeId ) ; if ( TmpTypeId >= 0 ) BDType -> setPointeeType ( TmpTypeId ) ; else BDType -> setPointeeType ( StructTypeId ) ; } } for ( const auto & TypeEntry : TypeEntries ) TypeEntry -> completeType ( * this ) ; emitBTFSection ( ) ; emitBTFExtSection ( ) ; } </s>


<s> void BTFDebug :: endModule ( ) { if ( MapDefNotCollected ) { processGlobals ( true ) ; MapDefNotCollected = false ; } processGlobals ( false ) ; processFuncPrototypes ( ) ; for ( auto & DataSec : DataSecEntries ) addType ( std :: move ( DataSec . second ) ) ; for ( auto & Fixup : FixupDerivedTypes ) { StringRef TypeName = Fixup . first ; bool IsUnion = Fixup . second . first ; uint32_t StructTypeId = 0 ; for ( const auto & StructType : StructTypes ) { if ( StructType -> getName ( ) == TypeName ) { StructTypeId = StructType -> getId ( ) ; break ; } } if ( StructTypeId == 0 ) { auto FwdTypeEntry = std :: make_unique < BTFTypeFwd > ( TypeName , IsUnion ) ; StructTypeId = addType ( std :: move ( FwdTypeEntry ) ) ; } for ( auto & DType : Fixup . second . second ) { DType -> setPointeeType ( StructTypeId ) ; } } for ( const auto & TypeEntry : TypeEntries ) TypeEntry -> completeType ( * this ) ; emitBTFSection ( ) ; emitBTFExtSection ( ) ; } </s>


<s> bool BTFDebug :: InstLower ( const MachineInstr * MI , MCInst & OutMI ) { if ( MI -> getOpcode ( ) == BPF :: LD_imm64 ) { const MachineOperand & MO = MI -> getOperand ( 1 ) ; if ( MO . isGlobal ( ) ) { const GlobalValue * GVal = MO . getGlobal ( ) ; auto * GVar = dyn_cast < GlobalVariable > ( GVal ) ; if ( GVar && GVar -> hasAttribute ( BPFCoreSharedInfo :: AmaAttr ) ) { uint32_t Imm = PatchImms [ GVar -> getName ( ) . str ( ) ] ; OutMI . setOpcode ( BPF :: MOV_ri ) ; OutMI . addOperand ( MCOperand :: createReg ( MI -> getOperand ( 0 ) . getReg ( ) ) ) ; OutMI . addOperand ( MCOperand :: createImm ( Imm ) ) ; return true ; } } } return false ; } </s>


<s> void BTFDebug :: beginInstruction ( const MachineInstr * MI ) { DebugHandlerBase :: beginInstruction ( MI ) ; if ( SkipInstruction || MI -> isMetaInstruction ( ) || MI -> getFlag ( MachineInstr :: FrameSetup ) ) return ; if ( MI -> isInlineAsm ( ) ) { unsigned NumDefs = 0 ; for ( ; MI -> getOperand ( NumDefs ) . isReg ( ) && MI -> getOperand ( NumDefs ) . isDef ( ) ; ++ NumDefs ) ; const char * AsmStr = MI -> getOperand ( NumDefs ) . getSymbolName ( ) ; if ( AsmStr [ 0 ] == 0 ) return ; } if ( MI -> getOpcode ( ) == BPF :: LD_imm64 ) { processReloc ( MI -> getOperand ( 1 ) ) ; } else if ( MI -> getOpcode ( ) == BPF :: CORE_MEM || MI -> getOpcode ( ) == BPF :: CORE_ALU32_MEM || MI -> getOpcode ( ) == BPF :: CORE_SHIFT ) { processReloc ( MI -> getOperand ( 3 ) ) ; } const DebugLoc & DL = MI -> getDebugLoc ( ) ; if ( ! DL || PrevInstLoc == DL ) { if ( LineInfoGenerated == false ) { auto * S = MI -> getMF ( ) -> getFunction ( ) . getSubprogram ( ) ; MCSymbol * FuncLabel = Asm -> getFunctionBegin ( ) ; constructLineInfo ( S , FuncLabel , S -> getLine ( ) , 0 ) ; LineInfoGenerated = true ; } return ; } MCSymbol * LineSym = OS . getContext ( ) . createTempSymbol ( ) ; OS . EmitLabel ( LineSym ) ; auto SP = DL . get ( ) -> getScope ( ) -> getSubprogram ( ) ; constructLineInfo ( SP , LineSym , DL . getLine ( ) , DL . getCol ( ) ) ; LineInfoGenerated = true ; PrevInstLoc = DL ; } </s>


<s> bool BTFDebug :: InstLower ( const MachineInstr * MI , MCInst & OutMI ) { if ( MI -> getOpcode ( ) == BPF :: LD_imm64 ) { const MachineOperand & MO = MI -> getOperand ( 1 ) ; if ( MO . isGlobal ( ) ) { const GlobalValue * GVal = MO . getGlobal ( ) ; auto * GVar = dyn_cast < GlobalVariable > ( GVal ) ; if ( GVar && GVar -> hasAttribute ( BPFCoreSharedInfo :: AmaAttr ) ) { uint32_t Imm = PatchImms [ GVar -> getName ( ) . str ( ) ] ; OutMI . setOpcode ( BPF :: MOV_ri ) ; OutMI . addOperand ( MCOperand :: createReg ( MI -> getOperand ( 0 ) . getReg ( ) ) ) ; OutMI . addOperand ( MCOperand :: createImm ( Imm ) ) ; return true ; } } } else if ( MI -> getOpcode ( ) == BPF :: CORE_MEM || MI -> getOpcode ( ) == BPF :: CORE_ALU32_MEM || MI -> getOpcode ( ) == BPF :: CORE_SHIFT ) { const MachineOperand & MO = MI -> getOperand ( 3 ) ; if ( MO . isGlobal ( ) ) { const GlobalValue * GVal = MO . getGlobal ( ) ; auto * GVar = dyn_cast < GlobalVariable > ( GVal ) ; if ( GVar && GVar -> hasAttribute ( BPFCoreSharedInfo :: AmaAttr ) ) { uint32_t Imm = PatchImms [ GVar -> getName ( ) . str ( ) ] ; OutMI . setOpcode ( MI -> getOperand ( 1 ) . getImm ( ) ) ; if ( MI -> getOperand ( 0 ) . isImm ( ) ) OutMI . addOperand ( MCOperand :: createImm ( MI -> getOperand ( 0 ) . getImm ( ) ) ) ; else OutMI . addOperand ( MCOperand :: createReg ( MI -> getOperand ( 0 ) . getReg ( ) ) ) ; OutMI . addOperand ( MCOperand :: createReg ( MI -> getOperand ( 2 ) . getReg ( ) ) ) ; OutMI . addOperand ( MCOperand :: createImm ( Imm ) ) ; return true ; } } } return false ; } </s>


<s>
void
BTFDebug
::
beginFunctionImpl
(
const
MachineFunction
*
MF
)
{
auto
*
SP
=
MF
->
getFunction
(
)
.
getSubprogram
(
)
;
auto
*
Unit
=
SP
->
getUnit
(
)
;
if
(
Unit
->
getEmissionKind
(
)
==
DICompileUnit
::
NoDebug
)
{
SkipInstruction
=
true
;
return
;
}
SkipInstruction
=
false
;
if
(
MapDefNotCollected
)
{
processGlobals
(
true
)
;
MapDefNotCollected
=
false
;
}
std
::
unordered_map
<
uint32_t
,
StringRef
>
FuncArgNames
;
for
(
const
DINode
*
DN
:
SP
->
getRetainedNodes
(
)
)
{
if
(
const
auto
*
DV
=
dyn_cast
<
DILocalVariable
>
(
DN
)
)
{
uint32_t
Arg
=
DV
->
getArg
(
)
;
if
(
Arg
)
{
visitTypeEntry
(
DV
->
getType
(
)
)
;
FuncArgNames
[
Arg
]
=
DV
->
getName
(
)
;
}
}
}
uint32_t
ProtoTypeId
;
visitSubroutineType
(
SP
->
getType
(
)
,
true
,
FuncArgNames
,
ProtoTypeId
)
;
uint8_t
Scope
=
SP
->
isLocalToUnit
(
)
BTF
::
FUNC_STATIC
:
BTF
::
FUNC_GLOBAL
;
auto
FuncTypeEntry
=
std
::
make_unique
<
BTFTypeFunc
>
(
SP
->
getName
(
)
,
ProtoTypeId
,
Scope
)
;
uint32_t
FuncTypeId
=
addType
(
std
::
move
(
FuncTypeEntry
)
)
;
for
(
const
auto
&
TypeEntry
:
TypeEntries
)
TypeEntry
->
completeType
(
*
this
)
;
MCSymbol
*
FuncLabel
=
Asm
->
getFunctionBegin
(
)
;
BTFFuncInfo
FuncInfo
;
FuncInfo
.
Label
=
FuncLabel
;
FuncInfo
.
TypeId
=
FuncTypeId
;
if
(
FuncLabel
->
isInSection
(
)
)
{
MCSection
&
Section
=
FuncLabel
->
getSection
(
)
;
const
MCSectionELF
*
SectionELF
=
dyn_cast
<
MCSectionELF
>
(
&
Section
)
;
assert
(
SectionELF
&&
"Null section for Function Label"
)
;
SecNameOff
=
addString
(
SectionELF
->
getSectionName
(
)
)
;
}
else
{
SecNameOff
=
addString
(
".text"
)
;
}
FuncInfoTable
[
SecNameOff
]
.
push_back
(
FuncInfo
)
;
}
</s>


<s> void BTFDebug :: beginInstruction ( const MachineInstr * MI ) { DebugHandlerBase :: beginInstruction ( MI ) ; if ( SkipInstruction || MI -> isMetaInstruction ( ) || MI -> getFlag ( MachineInstr :: FrameSetup ) ) return ; if ( MI -> isInlineAsm ( ) ) { unsigned NumDefs = 0 ; for ( ; MI -> getOperand ( NumDefs ) . isReg ( ) && MI -> getOperand ( NumDefs ) . isDef ( ) ; ++ NumDefs ) ; const char * AsmStr = MI -> getOperand ( NumDefs ) . getSymbolName ( ) ; if ( AsmStr [ 0 ] == 0 ) return ; } if ( MI -> getOpcode ( ) == BPF :: LD_imm64 ) { processReloc ( MI -> getOperand ( 1 ) ) ; } else if ( MI -> getOpcode ( ) == BPF :: CORE_MEM || MI -> getOpcode ( ) == BPF :: CORE_ALU32_MEM || MI -> getOpcode ( ) == BPF :: CORE_SHIFT ) { processReloc ( MI -> getOperand ( 3 ) ) ; } else if ( MI -> getOpcode ( ) == BPF :: JAL ) { const MachineOperand & MO = MI -> getOperand ( 0 ) ; if ( MO . isGlobal ( ) ) { processFuncPrototypes ( dyn_cast < Function > ( MO . getGlobal ( ) ) ) ; } } const DebugLoc & DL = MI -> getDebugLoc ( ) ; if ( ! DL || PrevInstLoc == DL ) { if ( LineInfoGenerated == false ) { auto * S = MI -> getMF ( ) -> getFunction ( ) . getSubprogram ( ) ; MCSymbol * FuncLabel = Asm -> getFunctionBegin ( ) ; constructLineInfo ( S , FuncLabel , S -> getLine ( ) , 0 ) ; LineInfoGenerated = true ; } return ; } MCSymbol * LineSym = OS . getContext ( ) . createTempSymbol ( ) ; OS . EmitLabel ( LineSym ) ; auto SP = DL . get ( ) -> getScope ( ) -> getSubprogram ( ) ; constructLineInfo ( SP , LineSym , DL . getLine ( ) , DL . getCol ( ) ) ; LineInfoGenerated = true ; PrevInstLoc = DL ; } </s>


<s>
void
BTFDebug
::
beginFunctionImpl
(
const
MachineFunction
*
MF
)
{
auto
*
SP
=
MF
->
getFunction
(
)
.
getSubprogram
(
)
;
auto
*
Unit
=
SP
->
getUnit
(
)
;
if
(
Unit
->
getEmissionKind
(
)
==
DICompileUnit
::
NoDebug
)
{
SkipInstruction
=
true
;
return
;
}
SkipInstruction
=
false
;
if
(
MapDefNotCollected
)
{
processGlobals
(
true
)
;
MapDefNotCollected
=
false
;
}
std
::
unordered_map
<
uint32_t
,
StringRef
>
FuncArgNames
;
for
(
const
DINode
*
DN
:
SP
->
getRetainedNodes
(
)
)
{
if
(
const
auto
*
DV
=
dyn_cast
<
DILocalVariable
>
(
DN
)
)
{
uint32_t
Arg
=
DV
->
getArg
(
)
;
if
(
Arg
)
{
visitTypeEntry
(
DV
->
getType
(
)
)
;
FuncArgNames
[
Arg
]
=
DV
->
getName
(
)
;
}
}
}
uint32_t
ProtoTypeId
;
visitSubroutineType
(
SP
->
getType
(
)
,
true
,
FuncArgNames
,
ProtoTypeId
)
;
uint8_t
Scope
=
SP
->
isLocalToUnit
(
)
BTF
::
FUNC_STATIC
:
BTF
::
FUNC_GLOBAL
;
auto
FuncTypeEntry
=
std
::
make_unique
<
BTFTypeFunc
>
(
SP
->
getName
(
)
,
ProtoTypeId
,
Scope
)
;
uint32_t
FuncTypeId
=
addType
(
std
::
move
(
FuncTypeEntry
)
)
;
for
(
const
DINode
*
DN
:
SP
->
getRetainedNodes
(
)
)
{
if
(
const
auto
*
DV
=
dyn_cast
<
DILocalVariable
>
(
DN
)
)
{
uint32_t
Arg
=
DV
->
getArg
(
)
;
if
(
Arg
)
processAnnotations
(
DV
->
getAnnotations
(
)
,
FuncTypeId
,
Arg
1
)
;
}
}
processAnnotations
(
SP
->
getAnnotations
(
)
,
FuncTypeId
,
1
)
;
for
(
const
auto
&
TypeEntry
:
TypeEntries
)
TypeEntry
->
completeType
(
*
this
)
;
MCSymbol
*
FuncLabel
=
Asm
->
getFunctionBegin
(
)
;
BTFFuncInfo
FuncInfo
;
FuncInfo
.
Label
=
FuncLabel
;
FuncInfo
.
TypeId
=
FuncTypeId
;
if
(
FuncLabel
->
isInSection
(
)
)
{
MCSection
&
Section
=
FuncLabel
->
getSection
(
)
;
const
MCSectionELF
*
SectionELF
=
dyn_cast
<
MCSectionELF
>
(
&
Section
)
;
assert
(
SectionELF
&&
"Null section for Function Label"
)
;
SecNameOff
=
addString
(
SectionELF
->
getName
(
)
)
;
}
else
{
SecNameOff
=
addString
(
".text"
)
;
}
FuncInfoTable
[
SecNameOff
]
.
push_back
(
FuncInfo
)
;
}
</s>


<s> void BTFTypeTag :: completeType ( BTFDebug & BDebug ) { if ( IsCompleted ) return ; IsCompleted = true ; BTFType . NameOff = BDebug . addString ( Tag ) ; } </s>


<s> void BTFTypeTag :: emitType ( MCStreamer & OS ) { BTFTypeBase :: emitType ( OS ) ; OS . emitInt32 ( Info ) ; } </s>


<s> uint32_t BTFStringTable :: addString ( StringRef S ) { for ( auto & OffsetM : OffsetToIdMap ) { if ( Table [ OffsetM . second ] == S ) return OffsetM . first ; } uint32_t Offset = Size ; OffsetToIdMap [ Offset ] = Table . size ( ) ; Table . push_back ( std :: string ( S ) ) ; Size += S . size ( ) + 1 ; return Offset ; } </s>


<s> uint32_t BTFDebug :: addType ( std :: unique_ptr < BTFTypeBase > TypeEntry , const DIType * Ty ) { TypeEntry -> setId ( TypeEntries . size ( ) + 1 ) ; uint32_t Id = TypeEntry -> getId ( ) ; DIToIdMap [ Ty ] = Id ; TypeEntries . push_back ( std :: move ( TypeEntry ) ) ; return Id ; } </s>


<s>
void
BTFDebug
::
beginFunctionImpl
(
const
MachineFunction
*
MF
)
{
auto
*
SP
=
MF
->
getFunction
(
)
.
getSubprogram
(
)
;
auto
*
Unit
=
SP
->
getUnit
(
)
;
if
(
Unit
->
getEmissionKind
(
)
==
DICompileUnit
::
NoDebug
)
{
SkipInstruction
=
true
;
return
;
}
SkipInstruction
=
false
;
if
(
MapDefNotCollected
)
{
processGlobals
(
true
)
;
MapDefNotCollected
=
false
;
}
std
::
unordered_map
<
uint32_t
,
StringRef
>
FuncArgNames
;
for
(
const
DINode
*
DN
:
SP
->
getRetainedNodes
(
)
)
{
if
(
const
auto
*
DV
=
dyn_cast
<
DILocalVariable
>
(
DN
)
)
{
uint32_t
Arg
=
DV
->
getArg
(
)
;
if
(
Arg
)
{
visitTypeEntry
(
DV
->
getType
(
)
)
;
FuncArgNames
[
Arg
]
=
DV
->
getName
(
)
;
}
}
}
uint32_t
ProtoTypeId
;
visitSubroutineType
(
SP
->
getType
(
)
,
true
,
FuncArgNames
,
ProtoTypeId
)
;
uint8_t
Scope
=
SP
->
isLocalToUnit
(
)
BTF
::
FUNC_STATIC
:
BTF
::
FUNC_GLOBAL
;
auto
FuncTypeEntry
=
std
::
make_unique
<
BTFTypeFunc
>
(
SP
->
getName
(
)
,
ProtoTypeId
,
Scope
)
;
uint32_t
FuncTypeId
=
addType
(
std
::
move
(
FuncTypeEntry
)
)
;
for
(
const
DINode
*
DN
:
SP
->
getRetainedNodes
(
)
)
{
if
(
const
auto
*
DV
=
dyn_cast
<
DILocalVariable
>
(
DN
)
)
{
uint32_t
Arg
=
DV
->
getArg
(
)
;
if
(
Arg
)
processDeclAnnotations
(
DV
->
getAnnotations
(
)
,
FuncTypeId
,
Arg
1
)
;
}
}
processDeclAnnotations
(
SP
->
getAnnotations
(
)
,
FuncTypeId
,
1
)
;
for
(
const
auto
&
TypeEntry
:
TypeEntries
)
TypeEntry
->
completeType
(
*
this
)
;
MCSymbol
*
FuncLabel
=
Asm
->
getFunctionBegin
(
)
;
BTFFuncInfo
FuncInfo
;
FuncInfo
.
Label
=
FuncLabel
;
FuncInfo
.
TypeId
=
FuncTypeId
;
if
(
FuncLabel
->
isInSection
(
)
)
{
MCSection
&
Section
=
FuncLabel
->
getSection
(
)
;
const
MCSectionELF
*
SectionELF
=
dyn_cast
<
MCSectionELF
>
(
&
Section
)
;
assert
(
SectionELF
&&
"Null section for Function Label"
)
;
SecNameOff
=
addString
(
SectionELF
->
getName
(
)
)
;
}
else
{
SecNameOff
=
addString
(
".text"
)
;
}
FuncInfoTable
[
SecNameOff
]
.
push_back
(
FuncInfo
)
;
}
</s>


<s> void BTFDebug :: beginInstruction ( const MachineInstr * MI ) { DebugHandlerBase :: beginInstruction ( MI ) ; if ( SkipInstruction || MI -> isMetaInstruction ( ) || MI -> getFlag ( MachineInstr :: FrameSetup ) ) return ; if ( MI -> isInlineAsm ( ) ) { unsigned NumDefs = 0 ; for ( ; MI -> getOperand ( NumDefs ) . isReg ( ) && MI -> getOperand ( NumDefs ) . isDef ( ) ; ++ NumDefs ) ; const char * AsmStr = MI -> getOperand ( NumDefs ) . getSymbolName ( ) ; if ( AsmStr [ 0 ] == 0 ) return ; } if ( MI -> getOpcode ( ) == BPF :: LD_imm64 ) { processGlobalValue ( MI -> getOperand ( 1 ) ) ; } else if ( MI -> getOpcode ( ) == BPF :: CORE_MEM || MI -> getOpcode ( ) == BPF :: CORE_ALU32_MEM || MI -> getOpcode ( ) == BPF :: CORE_SHIFT ) { processGlobalValue ( MI -> getOperand ( 3 ) ) ; } else if ( MI -> getOpcode ( ) == BPF :: JAL ) { const MachineOperand & MO = MI -> getOperand ( 0 ) ; if ( MO . isGlobal ( ) ) { processFuncPrototypes ( dyn_cast < Function > ( MO . getGlobal ( ) ) ) ; } } if ( ! CurMI ) return ; const DebugLoc & DL = MI -> getDebugLoc ( ) ; if ( ! DL || PrevInstLoc == DL ) { if ( LineInfoGenerated == false ) { auto * S = MI -> getMF ( ) -> getFunction ( ) . getSubprogram ( ) ; MCSymbol * FuncLabel = Asm -> getFunctionBegin ( ) ; constructLineInfo ( S , FuncLabel , S -> getLine ( ) , 0 ) ; LineInfoGenerated = true ; } return ; } MCSymbol * LineSym = OS . getContext ( ) . createTempSymbol ( ) ; OS . emitLabel ( LineSym ) ; auto SP = DL . get ( ) -> getScope ( ) -> getSubprogram ( ) ; constructLineInfo ( SP , LineSym , DL . getLine ( ) , DL . getCol ( ) ) ; LineInfoGenerated = true ; PrevInstLoc = DL ; } </s>


<s>
BTFTypeDerived
::
BTFTypeDerived
(
const
DIDerivedType
*
DTy
,
unsigned
Tag
,
bool
NeedsFixup
)
:
DTy
(
DTy
)
,
NeedsFixup
(
NeedsFixup
)
{
switch
(
Tag
)
{
case
dwarf
::
DW_TAG_pointer_type
:
Kind
=
BTF
::
BTF_KIND_PTR
;
break
;
case
dwarf
::
DW_TAG_const_type
:
Kind
=
BTF
::
BTF_KIND_CONST
;
break
;
case
dwarf
::
DW_TAG_volatile_type
:
Kind
=
BTF
::
BTF_KIND_VOLATILE
;
break
;
case
dwarf
::
DW_TAG_typedef
:
Kind
=
BTF
::
BTF_KIND_TYPEDEF
;
break
;
case
dwarf
::
DW_TAG_restrict_type
:
Kind
=
BTF
::
BTF_KIND_RESTRICT
;
break
;
default
:
llvm_unreachable
(
"Unknown DIDerivedType Tag"
)
;
}
BTFType
.
Info
=
Kind
<<
24
;
}
</s>


<s> void BTFTypeDeclTag :: completeType ( BTFDebug & BDebug ) { if ( IsCompleted ) return ; IsCompleted = true ; BTFType . NameOff = BDebug . addString ( Tag ) ; } </s>


<s> void BTFDebug :: emitCommonHeader ( ) { OS . AddComment ( "0x" + Twine :: utohexstr ( BTF :: MAGIC ) ) ; OS . emitIntValue ( BTF :: MAGIC , 2 ) ; OS . emitInt8 ( BTF :: VERSION ) ; OS . emitInt8 ( 0 ) ; } </s>


<s> void BTFTypeDeclTag :: emitType ( MCStreamer & OS ) { BTFTypeBase :: emitType ( OS ) ; OS . emitInt32 ( Info ) ; } </s>


<s> void BTFDebug :: endModule ( ) { if ( MapDefNotCollected ) { processGlobals ( true ) ; MapDefNotCollected = false ; } processGlobals ( false ) ; for ( auto & DataSec : DataSecEntries ) addType ( std :: move ( DataSec . second ) ) ; for ( auto & Fixup : FixupDerivedTypes ) { StringRef TypeName = Fixup . first ; bool IsUnion = Fixup . second . first ; uint32_t StructTypeId = 0 ; for ( const auto & StructType : StructTypes ) { if ( StructType -> getName ( ) == TypeName ) { StructTypeId = StructType -> getId ( ) ; break ; } } if ( StructTypeId == 0 ) { auto FwdTypeEntry = std :: make_unique < BTFTypeFwd > ( TypeName , IsUnion ) ; StructTypeId = addType ( std :: move ( FwdTypeEntry ) ) ; } for ( auto & DType : Fixup . second . second ) { DType -> setPointeeType ( StructTypeId ) ; } } for ( const auto & TypeEntry : TypeEntries ) TypeEntry -> completeType ( * this ) ; emitBTFSection ( ) ; emitBTFExtSection ( ) ; } </s>


<s> std :: string BTFTypeStruct :: getName ( ) { return std :: string ( STy -> getName ( ) ) ; } </s>


<s> bool BTFDebug :: InstLower ( const MachineInstr * MI , MCInst & OutMI ) { if ( MI -> getOpcode ( ) == BPF :: LD_imm64 ) { const MachineOperand & MO = MI -> getOperand ( 1 ) ; if ( MO . isGlobal ( ) ) { const GlobalValue * GVal = MO . getGlobal ( ) ; auto * GVar = dyn_cast < GlobalVariable > ( GVal ) ; if ( GVar ) { int64_t Imm ; uint32_t Reloc ; if ( GVar -> hasAttribute ( BPFCoreSharedInfo :: AmaAttr ) || GVar -> hasAttribute ( BPFCoreSharedInfo :: TypeIdAttr ) ) { Imm = PatchImms [ GVar ] . first ; Reloc = PatchImms [ GVar ] . second ; } else { return false ; } if ( Reloc == BPFCoreSharedInfo :: ENUM_VALUE_EXISTENCE || Reloc == BPFCoreSharedInfo :: ENUM_VALUE || Reloc == BPFCoreSharedInfo :: BTF_TYPE_ID_LOCAL || Reloc == BPFCoreSharedInfo :: BTF_TYPE_ID_REMOTE ) OutMI . setOpcode ( BPF :: LD_imm64 ) ; else OutMI . setOpcode ( BPF :: MOV_ri ) ; OutMI . addOperand ( MCOperand :: createReg ( MI -> getOperand ( 0 ) . getReg ( ) ) ) ; OutMI . addOperand ( MCOperand :: createImm ( Imm ) ) ; return true ; } } } else if ( MI -> getOpcode ( ) == BPF :: CORE_MEM || MI -> getOpcode ( ) == BPF :: CORE_ALU32_MEM || MI -> getOpcode ( ) == BPF :: CORE_SHIFT ) { const MachineOperand & MO = MI -> getOperand ( 3 ) ; if ( MO . isGlobal ( ) ) { const GlobalValue * GVal = MO . getGlobal ( ) ; auto * GVar = dyn_cast < GlobalVariable > ( GVal ) ; if ( GVar && GVar -> hasAttribute ( BPFCoreSharedInfo :: AmaAttr ) ) { uint32_t Imm = PatchImms [ GVar ] . first ; OutMI . setOpcode ( MI -> getOperand ( 1 ) . getImm ( ) ) ; if ( MI -> getOperand ( 0 ) . isImm ( ) ) OutMI . addOperand ( MCOperand :: createImm ( MI -> getOperand ( 0 ) . getImm ( ) ) ) ; else OutMI . addOperand ( MCOperand :: createReg ( MI -> getOperand ( 0 ) . getReg ( ) ) ) ; OutMI . addOperand ( MCOperand :: createReg ( MI -> getOperand ( 2 ) . getReg ( ) ) ) ; OutMI . addOperand ( MCOperand :: createImm ( Imm ) ) ; return true ; } } } return false ; } </s>


<s> void BTFDebug :: emitCommonHeader ( ) { OS . AddComment ( "0x" + Twine :: utohexstr ( BTF :: MAGIC ) ) ; OS . emitIntValue ( BTF :: MAGIC , 2 ) ; OS . emitIntValue ( BTF :: VERSION , 1 ) ; OS . emitIntValue ( 0 , 1 ) ; } </s>


<s> void BTFKindDataSec :: emitType ( MCStreamer & OS ) { BTFTypeBase :: emitType ( OS ) ; for ( const auto & V : Vars ) { OS . emitIntValue ( std :: get < 0 > ( V ) , 4 ) ; Asm -> emitLabelReference ( std :: get < 1 > ( V ) , 4 ) ; OS . emitIntValue ( std :: get < 2 > ( V ) , 4 ) ; } } </s>


<s> void BTFDebug :: beginInstruction ( const MachineInstr * MI ) { DebugHandlerBase :: beginInstruction ( MI ) ; if ( SkipInstruction || MI -> isMetaInstruction ( ) || MI -> getFlag ( MachineInstr :: FrameSetup ) ) return ; if ( MI -> isInlineAsm ( ) ) { unsigned NumDefs = 0 ; for ( ; MI -> getOperand ( NumDefs ) . isReg ( ) && MI -> getOperand ( NumDefs ) . isDef ( ) ; ++ NumDefs ) ; const char * AsmStr = MI -> getOperand ( NumDefs ) . getSymbolName ( ) ; if ( AsmStr [ 0 ] == 0 ) return ; } if ( MI -> getOpcode ( ) == BPF :: LD_imm64 ) { processReloc ( MI -> getOperand ( 1 ) ) ; } else if ( MI -> getOpcode ( ) == BPF :: CORE_MEM || MI -> getOpcode ( ) == BPF :: CORE_ALU32_MEM || MI -> getOpcode ( ) == BPF :: CORE_SHIFT ) { processReloc ( MI -> getOperand ( 3 ) ) ; } else if ( MI -> getOpcode ( ) == BPF :: JAL ) { const MachineOperand & MO = MI -> getOperand ( 0 ) ; if ( MO . isGlobal ( ) ) { processFuncPrototypes ( dyn_cast < Function > ( MO . getGlobal ( ) ) ) ; } } if ( ! CurMI ) return ; const DebugLoc & DL = MI -> getDebugLoc ( ) ; if ( ! DL || PrevInstLoc == DL ) { if ( LineInfoGenerated == false ) { auto * S = MI -> getMF ( ) -> getFunction ( ) . getSubprogram ( ) ; MCSymbol * FuncLabel = Asm -> getFunctionBegin ( ) ; constructLineInfo ( S , FuncLabel , S -> getLine ( ) , 0 ) ; LineInfoGenerated = true ; } return ; } MCSymbol * LineSym = OS . getContext ( ) . createTempSymbol ( ) ; OS . emitLabel ( LineSym ) ; auto SP = DL . get ( ) -> getScope ( ) -> getSubprogram ( ) ; constructLineInfo ( SP , LineSym , DL . getLine ( ) , DL . getCol ( ) ) ; LineInfoGenerated = true ; PrevInstLoc = DL ; } </s>


<s> bool BTFDebug :: InstLower ( const MachineInstr * MI , MCInst & OutMI ) { if ( MI -> getOpcode ( ) == BPF :: LD_imm64 ) { const MachineOperand & MO = MI -> getOperand ( 1 ) ; if ( MO . isGlobal ( ) ) { const GlobalValue * GVal = MO . getGlobal ( ) ; auto * GVar = dyn_cast < GlobalVariable > ( GVal ) ; if ( GVar ) { int64_t Imm ; uint32_t Reloc ; if ( GVar -> hasAttribute ( BPFCoreSharedInfo :: AmaAttr ) || GVar -> hasAttribute ( BPFCoreSharedInfo :: TypeIdAttr ) ) { Imm = PatchImms [ GVar ] . first ; Reloc = PatchImms [ GVar ] . second ; } else { return false ; } if ( Reloc == BPFCoreSharedInfo :: ENUM_VALUE_EXISTENCE || Reloc == BPFCoreSharedInfo :: ENUM_VALUE ) OutMI . setOpcode ( BPF :: LD_imm64 ) ; else OutMI . setOpcode ( BPF :: MOV_ri ) ; OutMI . addOperand ( MCOperand :: createReg ( MI -> getOperand ( 0 ) . getReg ( ) ) ) ; OutMI . addOperand ( MCOperand :: createImm ( Imm ) ) ; return true ; } } } else if ( MI -> getOpcode ( ) == BPF :: CORE_MEM || MI -> getOpcode ( ) == BPF :: CORE_ALU32_MEM || MI -> getOpcode ( ) == BPF :: CORE_SHIFT ) { const MachineOperand & MO = MI -> getOperand ( 3 ) ; if ( MO . isGlobal ( ) ) { const GlobalValue * GVal = MO . getGlobal ( ) ; auto * GVar = dyn_cast < GlobalVariable > ( GVal ) ; if ( GVar && GVar -> hasAttribute ( BPFCoreSharedInfo :: AmaAttr ) ) { uint32_t Imm = PatchImms [ GVar ] . first ; OutMI . setOpcode ( MI -> getOperand ( 1 ) . getImm ( ) ) ; if ( MI -> getOperand ( 0 ) . isImm ( ) ) OutMI . addOperand ( MCOperand :: createImm ( MI -> getOperand ( 0 ) . getImm ( ) ) ) ; else OutMI . addOperand ( MCOperand :: createReg ( MI -> getOperand ( 0 ) . getReg ( ) ) ) ; OutMI . addOperand ( MCOperand :: createReg ( MI -> getOperand ( 2 ) . getReg ( ) ) ) ; OutMI . addOperand ( MCOperand :: createImm ( Imm ) ) ; return true ; } } } return false ; } </s>


<s>
void
BTFDebug
::
beginFunctionImpl
(
const
MachineFunction
*
MF
)
{
auto
*
SP
=
MF
->
getFunction
(
)
.
getSubprogram
(
)
;
auto
*
Unit
=
SP
->
getUnit
(
)
;
if
(
Unit
->
getEmissionKind
(
)
==
DICompileUnit
::
NoDebug
)
{
SkipInstruction
=
true
;
return
;
}
SkipInstruction
=
false
;
std
::
unordered_map
<
uint32_t
,
StringRef
>
FuncArgNames
;
for
(
const
DINode
*
DN
:
SP
->
getRetainedNodes
(
)
)
{
if
(
const
auto
*
DV
=
dyn_cast
<
DILocalVariable
>
(
DN
)
)
{
uint32_t
Arg
=
DV
->
getArg
(
)
;
if
(
Arg
)
{
visitTypeEntry
(
DV
->
getType
(
)
.
resolve
(
)
)
;
FuncArgNames
[
Arg
]
=
DV
->
getName
(
)
;
}
}
}
uint32_t
ProtoTypeId
;
visitSubroutineType
(
SP
->
getType
(
)
,
true
,
FuncArgNames
,
ProtoTypeId
)
;
auto
FuncTypeEntry
=
llvm
::
make_unique
<
BTFTypeFunc
>
(
SP
->
getName
(
)
,
ProtoTypeId
)
;
uint32_t
FuncTypeId
=
addType
(
std
::
move
(
FuncTypeEntry
)
)
;
MCSymbol
*
FuncLabel
=
Asm
->
getFunctionBegin
(
)
;
BTFFuncInfo
FuncInfo
;
FuncInfo
.
Label
=
FuncLabel
;
FuncInfo
.
TypeId
=
FuncTypeId
;
if
(
FuncLabel
->
isInSection
(
)
)
{
MCSection
&
Section
=
FuncLabel
->
getSection
(
)
;
const
MCSectionELF
*
SectionELF
=
dyn_cast
<
MCSectionELF
>
(
&
Section
)
;
assert
(
SectionELF
&&
"Null section for Function Label"
)
;
SecNameOff
=
addString
(
SectionELF
->
getSectionName
(
)
)
;
}
else
{
SecNameOff
=
addString
(
".text"
)
;
}
FuncInfoTable
[
SecNameOff
]
.
push_back
(
FuncInfo
)
;
}
</s>


<s> void BTFTypeArray :: completeType ( BTFDebug & BDebug ) { ArrayInfo . IndexType = BDebug . getArrayIndexTypeId ( ) ; } </s>


<s> void BTFDebug :: endModule ( ) { processGlobals ( ) ; for ( const auto & TypeEntry : TypeEntries ) TypeEntry -> completeType ( * this ) ; emitBTFSection ( ) ; emitBTFExtSection ( ) ; } </s>


<s> bool BTFDebug :: InstLower ( const MachineInstr * MI , MCInst & OutMI ) { if ( MI -> getOpcode ( ) == BPF :: LD_imm64 ) { const MachineOperand & MO = MI -> getOperand ( 1 ) ; if ( MO . isGlobal ( ) ) { const GlobalValue * GVal = MO . getGlobal ( ) ; auto * GVar = dyn_cast < GlobalVariable > ( GVal ) ; if ( GVar && GVar -> hasAttribute ( BPFCoreSharedInfo :: AmaAttr ) ) { MDNode * MDN = GVar -> getMetadata ( LLVMContext :: MD_preserve_access_index ) ; DIType * Ty = dyn_cast < DIType > ( MDN ) ; std :: string TypeName = Ty -> getName ( ) ; int64_t Imm = AccessOffsets [ GVar -> getName ( ) . str ( ) ] ; OutMI . setOpcode ( BPF :: MOV_ri ) ; OutMI . addOperand ( MCOperand :: createReg ( MI -> getOperand ( 0 ) . getReg ( ) ) ) ; OutMI . addOperand ( MCOperand :: createImm ( Imm ) ) ; return true ; } else if ( GVar && ! GVar -> hasInitializer ( ) && GVar -> hasExternalLinkage ( ) && GVar -> getSection ( ) == BPFCoreSharedInfo :: PatchableExtSecName ) { const IntegerType * IntTy = dyn_cast < IntegerType > ( GVar -> getValueType ( ) ) ; assert ( IntTy ) ; if ( IntTy -> getBitWidth ( ) == 64 ) OutMI . setOpcode ( BPF :: LD_imm64 ) ; else OutMI . setOpcode ( BPF :: MOV_ri ) ; OutMI . addOperand ( MCOperand :: createReg ( MI -> getOperand ( 0 ) . getReg ( ) ) ) ; OutMI . addOperand ( MCOperand :: createImm ( 0 ) ) ; return true ; } } } return false ; } </s>


<s>
void
BTFDebug
::
beginFunctionImpl
(
const
MachineFunction
*
MF
)
{
auto
*
SP
=
MF
->
getFunction
(
)
.
getSubprogram
(
)
;
auto
*
Unit
=
SP
->
getUnit
(
)
;
if
(
Unit
->
getEmissionKind
(
)
==
DICompileUnit
::
NoDebug
)
{
SkipInstruction
=
true
;
return
;
}
SkipInstruction
=
false
;
if
(
MapDefNotCollected
)
{
processGlobals
(
true
)
;
MapDefNotCollected
=
false
;
}
std
::
unordered_map
<
uint32_t
,
StringRef
>
FuncArgNames
;
for
(
const
DINode
*
DN
:
SP
->
getRetainedNodes
(
)
)
{
if
(
const
auto
*
DV
=
dyn_cast
<
DILocalVariable
>
(
DN
)
)
{
uint32_t
Arg
=
DV
->
getArg
(
)
;
if
(
Arg
)
{
visitTypeEntry
(
DV
->
getType
(
)
)
;
FuncArgNames
[
Arg
]
=
DV
->
getName
(
)
;
}
}
}
uint32_t
ProtoTypeId
;
visitSubroutineType
(
SP
->
getType
(
)
,
true
,
FuncArgNames
,
ProtoTypeId
)
;
auto
FuncTypeEntry
=
llvm
::
make_unique
<
BTFTypeFunc
>
(
SP
->
getName
(
)
,
ProtoTypeId
)
;
uint32_t
FuncTypeId
=
addType
(
std
::
move
(
FuncTypeEntry
)
)
;
for
(
const
auto
&
TypeEntry
:
TypeEntries
)
TypeEntry
->
completeType
(
*
this
)
;
MCSymbol
*
FuncLabel
=
Asm
->
getFunctionBegin
(
)
;
BTFFuncInfo
FuncInfo
;
FuncInfo
.
Label
=
FuncLabel
;
FuncInfo
.
TypeId
=
FuncTypeId
;
if
(
FuncLabel
->
isInSection
(
)
)
{
MCSection
&
Section
=
FuncLabel
->
getSection
(
)
;
const
MCSectionELF
*
SectionELF
=
dyn_cast
<
MCSectionELF
>
(
&
Section
)
;
assert
(
SectionELF
&&
"Null section for Function Label"
)
;
SecNameOff
=
addString
(
SectionELF
->
getSectionName
(
)
)
;
}
else
{
SecNameOff
=
addString
(
".text"
)
;
}
FuncInfoTable
[
SecNameOff
]
.
push_back
(
FuncInfo
)
;
}
</s>


<s> void BTFTypeStruct :: completeType ( BTFDebug & BDebug ) { if ( IsCompleted ) return ; IsCompleted = true ; BTFType . NameOff = BDebug . addString ( STy -> getName ( ) ) ; const DINodeArray Elements = STy -> getElements ( ) ; for ( const auto * Element : Elements ) { struct BTF :: BTFMember BTFMember ; const auto * DDTy = cast < DIDerivedType > ( Element ) ; BTFMember . NameOff = BDebug . addString ( DDTy -> getName ( ) ) ; if ( HasBitField ) { uint8_t BitFieldSize = DDTy -> isBitField ( ) ? DDTy -> getSizeInBits ( ) : 0 ; BTFMember . Offset = BitFieldSize << 24 | DDTy -> getOffsetInBits ( ) ; } else { BTFMember . Offset = DDTy -> getOffsetInBits ( ) ; } BTFMember . Type = BDebug . getTypeId ( DDTy -> getBaseType ( ) ) ; Members . push_back ( BTFMember ) ; } } </s>


<s> void BTFDebug :: endModule ( ) { if ( MapDefNotCollected ) { processGlobals ( true ) ; MapDefNotCollected = false ; } processGlobals ( false ) ; for ( auto & DataSec : DataSecEntries ) addType ( std :: move ( DataSec . second ) ) ; for ( auto & Fixup : FixupDerivedTypes ) { StringRef TypeName = Fixup . first ; bool IsUnion = Fixup . second . first ; uint32_t StructTypeId = 0 ; for ( const auto & StructType : StructTypes ) { if ( StructType -> getName ( ) == TypeName ) { StructTypeId = StructType -> getId ( ) ; break ; } } if ( StructTypeId == 0 ) { auto FwdTypeEntry = llvm :: make_unique < BTFTypeFwd > ( TypeName , IsUnion ) ; StructTypeId = addType ( std :: move ( FwdTypeEntry ) ) ; } for ( auto & DType : Fixup . second . second ) { DType -> setPointeeType ( StructTypeId ) ; } } for ( const auto & TypeEntry : TypeEntries ) TypeEntry -> completeType ( * this ) ; emitBTFSection ( ) ; emitBTFExtSection ( ) ; } </s>


<s> bool BTFDebug :: InstLower ( const MachineInstr * MI , MCInst & OutMI ) { if ( MI -> getOpcode ( ) == BPF :: LD_imm64 ) { const MachineOperand & MO = MI -> getOperand ( 1 ) ; if ( MO . isGlobal ( ) ) { const GlobalValue * GVal = MO . getGlobal ( ) ; auto * GVar = dyn_cast < GlobalVariable > ( GVal ) ; if ( GVar && GVar -> hasAttribute ( BPFCoreSharedInfo :: AmaAttr ) ) { MDNode * MDN = GVar -> getMetadata ( LLVMContext :: MD_preserve_access_index ) ; DIType * Ty = dyn_cast < DIType > ( MDN ) ; std :: string TypeName = Ty -> getName ( ) ; int64_t Imm = AccessOffsets [ TypeName + ":" + GVar -> getName ( ) . str ( ) ] ; OutMI . setOpcode ( BPF :: MOV_ri ) ; OutMI . addOperand ( MCOperand :: createReg ( MI -> getOperand ( 0 ) . getReg ( ) ) ) ; OutMI . addOperand ( MCOperand :: createImm ( Imm ) ) ; return true ; } else if ( GVar && ! GVar -> hasInitializer ( ) && GVar -> hasExternalLinkage ( ) && GVar -> getSection ( ) == BPFCoreSharedInfo :: PatchableExtSecName ) { const IntegerType * IntTy = dyn_cast < IntegerType > ( GVar -> getValueType ( ) ) ; assert ( IntTy ) ; if ( IntTy -> getBitWidth ( ) == 64 ) OutMI . setOpcode ( BPF :: LD_imm64 ) ; else OutMI . setOpcode ( BPF :: MOV_ri ) ; OutMI . addOperand ( MCOperand :: createReg ( MI -> getOperand ( 0 ) . getReg ( ) ) ) ; OutMI . addOperand ( MCOperand :: createImm ( 0 ) ) ; return true ; } } } return false ; } </s>


<s>
void
BTFDebug
::
beginFunctionImpl
(
const
MachineFunction
*
MF
)
{
auto
*
SP
=
MF
->
getFunction
(
)
.
getSubprogram
(
)
;
auto
*
Unit
=
SP
->
getUnit
(
)
;
if
(
Unit
->
getEmissionKind
(
)
==
DICompileUnit
::
NoDebug
)
{
SkipInstruction
=
true
;
return
;
}
SkipInstruction
=
false
;
std
::
unordered_map
<
uint32_t
,
StringRef
>
FuncArgNames
;
for
(
const
DINode
*
DN
:
SP
->
getRetainedNodes
(
)
)
{
if
(
const
auto
*
DV
=
dyn_cast
<
DILocalVariable
>
(
DN
)
)
{
uint32_t
Arg
=
DV
->
getArg
(
)
;
if
(
Arg
)
{
visitTypeEntry
(
DV
->
getType
(
)
)
;
FuncArgNames
[
Arg
]
=
DV
->
getName
(
)
;
}
}
}
uint32_t
ProtoTypeId
;
visitSubroutineType
(
SP
->
getType
(
)
,
true
,
FuncArgNames
,
ProtoTypeId
)
;
auto
FuncTypeEntry
=
llvm
::
make_unique
<
BTFTypeFunc
>
(
SP
->
getName
(
)
,
ProtoTypeId
)
;
uint32_t
FuncTypeId
=
addType
(
std
::
move
(
FuncTypeEntry
)
)
;
MCSymbol
*
FuncLabel
=
Asm
->
getFunctionBegin
(
)
;
BTFFuncInfo
FuncInfo
;
FuncInfo
.
Label
=
FuncLabel
;
FuncInfo
.
TypeId
=
FuncTypeId
;
if
(
FuncLabel
->
isInSection
(
)
)
{
MCSection
&
Section
=
FuncLabel
->
getSection
(
)
;
const
MCSectionELF
*
SectionELF
=
dyn_cast
<
MCSectionELF
>
(
&
Section
)
;
assert
(
SectionELF
&&
"Null section for Function Label"
)
;
SecNameOff
=
addString
(
SectionELF
->
getSectionName
(
)
)
;
}
else
{
SecNameOff
=
addString
(
".text"
)
;
}
FuncInfoTable
[
SecNameOff
]
.
push_back
(
FuncInfo
)
;
}
</s>


<s> void BTFTypeFuncProto :: completeType ( BTFDebug & BDebug ) { DITypeRefArray Elements = STy -> getTypeArray ( ) ; auto RetType = Elements [ 0 ] ; BTFType . Type = RetType ? BDebug . getTypeId ( RetType ) : 0 ; BTFType . NameOff = 0 ; for ( unsigned I = 1 , N = Elements . size ( ) ; I < N ; ++ I ) { struct BTF :: BTFParam Param ; auto Element = Elements [ I ] ; if ( Element ) { Param . NameOff = BDebug . addString ( FuncArgNames [ I ] ) ; Param . Type = BDebug . getTypeId ( Element ) ; } else { Param . NameOff = 0 ; Param . Type = 0 ; } Parameters . push_back ( Param ) ; } } </s>


<s> void BTFTypeStruct :: completeType ( BTFDebug & BDebug ) { if ( IsCompleted ) return ; IsCompleted = true ; BTFType . NameOff = BDebug . addString ( STy -> getName ( ) ) ; const DINodeArray Elements = STy -> getElements ( ) ; for ( const auto * Element : Elements ) { struct BTF :: BTFMember BTFMember ; const auto * DDTy = cast < DIDerivedType > ( Element ) ; BTFMember . NameOff = BDebug . addString ( DDTy -> getName ( ) ) ; if ( HasBitField ) { uint8_t BitFieldSize = DDTy -> isBitField ( ) ? DDTy -> getSizeInBits ( ) : 0 ; BTFMember . Offset = BitFieldSize << 24 | DDTy -> getOffsetInBits ( ) ; } else { BTFMember . Offset = DDTy -> getOffsetInBits ( ) ; } const auto * BaseTy = DDTy -> getBaseType ( ) ; BTFMember . Type = BDebug . getTypeId ( BaseTy ) ; MemberTypeNoQual . push_back ( BDebug . getTypeId ( stripQualifiers ( BaseTy ) ) ) ; Members . push_back ( BTFMember ) ; } } </s>


<s> size_t addString ( StringRef S ) { return StringTable . addString ( S ) ; } </s>


<s> virtual void completeType ( BTFDebug & BDebug ) { } </s>


<s> uint32_t getArrayIndexTypeId ( ) { assert ( ArrayIndexTypeId ) ; return ArrayIndexTypeId ; } </s>


<s> std :: string getName ( ) { return Name ; } </s>


<s> uint32_t getSize ( ) { return Size ; } </s>


<s>
uint32_t
getTypeId
(
const
DIType
*
Ty
)
{
assert
(
Ty
&&
"Invalid null Type"
)
;
assert
(
DIToIdMap
.
find
(
Ty
)
!=
DIToIdMap
.
end
(
)
&&
"DIType not added in the BDIToIdMap"
)
;
return
DIToIdMap
[
Ty
]
;
}
</s>

Get the type id for a particular DIType .

BPF
"Invalid null Type"
"DIType not added in the BDIToIdMap"


<s> void setSymbolSize ( const MCSymbol * Symbol , uint64_t Size ) override { } </s>

For symbols that have a size designated ( e.g .