<s> return new <ISA_LIT>PassConfig ( this , PM ) ;


<s> <ISA_LIT>TargetMachine & get<ISA_LIT>TargetMachine ( ) const {

return getTM < <ISA_LIT>TargetMachine > ( ) ;


<s> return getTM < <ISA_LIT>TargetMachine > ( ) ;


<s> RegisterTargetMachine < <ISA_LIT>TargetMachine > X ( The<ISA_LIT>leTarget ) ; RegisterTargetMachine < <ISA_LIT>TargetMachine > Y ( The<ISA_LIT>beTarget ) ;

RegisterTargetMachine < <ISA_LIT>TargetMachine > Z ( The<ISA_LIT>Target ) ;


<s> RegisterTargetMachine < <ISA_LIT>TargetMachine > Z ( The<ISA_LIT>Target ) ;


<s> RegisterTargetMachine < <ISA_LIT>TargetMachine > X ( getThe<ISA_LIT>leTarget ( ) ) ;

RegisterTargetMachine < <ISA_LIT>TargetMachine > Y ( getThe<ISA_LIT>beTarget ( ) ) ;


<s> RegisterTargetMachine < <ISA_LIT>TargetMachine > Z ( getThe<ISA_LIT>Target ( ) ) ;


<s> void <ISA_LIT>PassConfig :: addIRPasses ( ) { addPass ( create<ISA_LIT>AbstractMemberAccess ( & get<ISA_LIT>TargetMachine ( ) ) ) ; TargetPassConfig :: addIRPasses ( ) ;


<s> void <ISA_LIT>PassConfig :: addIRPasses ( ) { addPass ( create<ISA_LIT>AbstractMemberAccess ( & get<ISA_LIT>TargetMachine ( ) ) ) ;


initialize<ISA_LIT>MIPeepholePass ( PR ) ;


<s> RegisterTargetMachine < <ISA_LIT>TargetMachine > X ( getThe<ISA_LIT>leTarget ( ) ) ; RegisterTargetMachine < <ISA_LIT>TargetMachine > Y ( getThe<ISA_LIT>beTarget ( ) ) ; RegisterTargetMachine < <ISA_LIT>TargetMachine > Z ( getThe<ISA_LIT>Target ( ) ) ;

PassRegistry & PR = * PassRegistry :: getPassRegistry ( ) ;


<s> PB . registerPipelineStartEPCallback ( [ = ] ( ModulePassManager & MPM , PassBuilder :: OptimizationLevel ) { FunctionPassManager FPM ( DebugPassManager ) ; FPM . addPass ( <ISA_LIT>AbstractMemberAccessPass ( this ) ) ; FPM . addPass ( <ISA_LIT>PreserveDITypePass ( ) ) ; MPM . addPass ( createModuleToFunctionPassAdaptor ( std :: move ( FPM ) ) ) ; } ) ; PB . registerPeepholeEPCallback ( [ = ] ( FunctionPassManager & FPM , PassBuilder :: OptimizationLevel Level ) {

FPM . addPass ( SimplifyCFGPass ( SimplifyCFGOptions ( ) . hoistCommonInsts ( true ) ) ) ;


MPM . addPass ( <ISA_LIT>AdjustOptPass ( ) ) ;


<s> void <ISA_LIT>TargetMachine :: registerPassBuilderCallbacks ( PassBuilder & PB ) { PB . registerPipelineStartEPCallback ( [ = ] ( ModulePassManager & MPM , OptimizationLevel ) { FunctionPassManager FPM ; FPM . addPass ( <ISA_LIT>AbstractMemberAccessPass ( this ) ) ; FPM . addPass ( <ISA_LIT>PreserveDITypePass ( ) ) ; MPM . addPass ( createModuleToFunctionPassAdaptor ( std :: move ( FPM ) ) ) ; } ) ; PB . registerPeepholeEPCallback ( [ = ] ( FunctionPassManager & FPM , OptimizationLevel Level ) { FPM . addPass ( SimplifyCFGPass ( SimplifyCFGOptions ( ) . hoistCommonInsts ( true ) ) ) ;


<s> FPM . addPass ( <ISA_LIT>AbstractMemberAccessPass ( this ) ) ; FPM . addPass ( <ISA_LIT>PreserveDITypePass ( ) ) ; MPM . addPass ( createModuleToFunctionPassAdaptor ( std :: move ( FPM ) ) ) ; } ) ; PB . registerPeepholeEPCallback ( [ = ] ( FunctionPassManager & FPM , OptimizationLevel Level ) { FPM . addPass ( SimplifyCFGPass ( SimplifyCFGOptions ( ) . hoistCommonInsts ( true ) ) ) ;


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


<s> virtual const TargetFrameLowering * getFrameLowering ( ) const { return & FrameLowering ;


<s> virtual const <ISA_LIT>RegisterInfo * getRegisterInfo ( ) const {

return & InstrInfo . getRegisterInfo ( ) ;


<s> virtual const <ISA_LIT>Subtarget * getSubtargetImpl ( ) const {


<s> virtual const <ISA_LIT>TargetLowering * getTargetLowering ( ) const { return & TLInfo ;


<s> PM . add ( create<ISA_LIT>AbstractMemberAccess ( this ) ) ; PM . add ( create<ISA_LIT>PreserveDIType ( ) ) ; } ) ; Builder . addExtension ( PassManagerBuilder :: EP_Peephole , [ & ] ( const PassManagerBuilder & , legacy :: PassManagerBase & PM ) {

PM . add ( createCFGSimplificationPass ( SimplifyCFGOptions ( ) . hoistCommonInsts ( true ) ) ) ;


<s> } ) ; Builder . addExtension ( PassManagerBuilder :: EP_Peephole , [ & ] ( const PassManagerBuilder & , legacy :: PassManagerBase & PM ) { PM . add ( createCFGSimplificationPass ( SimplifyCFGOptions ( ) . hoistCommonInsts ( true ) ) ) ; } ) ; Builder . addExtension ( PassManagerBuilder :: EP_ModuleOptimizerEarly , [ & ] ( const PassManagerBuilder & , legacy :: PassManagerBase & PM ) { PM . add ( create<ISA_LIT>AdjustOpt ( ) ) ;


<s> LLVM_EXTERNAL_VISIBILITY void LLVMInitialize<ISA_LIT>Target ( ) { RegisterTargetMachine < <ISA_LIT>TargetMachine > X ( getThe<ISA_LIT>leTarget ( ) ) ;


addPass ( create<ISA_LIT>PreserveDIType ( ) ) ;


<s> addPass ( create<ISA_LIT>AbstractMemberAccess ( & get<ISA_LIT>TargetMachine ( ) ) ) ;


<s> Builder . addExtension ( PassManagerBuilder :: EP_Peephole , [ & ] ( const PassManagerBuilder & , legacy :: PassManagerBase & PM ) { PM . add ( createCFGSimplificationPass ( SimplifyCFGOptions ( ) . hoistCommonInsts ( true ) ) ) ;


<s> void <ISA_LIT>TargetMachine :: adjustPassManager ( PassManagerBuilder & Builder ) { Builder . addExtension ( PassManagerBuilder :: EP_Peephole , [ & ] ( const PassManagerBuilder & , legacy :: PassManagerBase & PM ) {


<s> void <ISA_LIT>TargetMachine :: registerPassBuilderCallbacks ( PassBuilder & PB ) { PB . registerPipelineStartEPCallback ( [ = ] ( ModulePassManager & MPM , PassBuilder :: OptimizationLevel ) { FunctionPassManager FPM ; FPM . addPass ( <ISA_LIT>AbstractMemberAccessPass ( this ) ) ; FPM . addPass ( <ISA_LIT>PreserveDITypePass ( ) ) ; MPM . addPass ( createModuleToFunctionPassAdaptor ( std :: move ( FPM ) ) ) ; } ) ; PB . registerPeepholeEPCallback ( [ = ] ( FunctionPassManager & FPM , PassBuilder :: OptimizationLevel Level ) { FPM . addPass ( SimplifyCFGPass ( SimplifyCFGOptions ( ) . hoistCommonInsts ( true ) ) ) ; } ) ;


<s> void <ISA_LIT>PassConfig :: addPreEmitPass ( ) {

const <ISA_LIT>Subtarget * Subtarget = get<ISA_LIT>TargetMachine ( ) . getSubtargetImpl ( ) ;


<s> <ISA_LIT>TargetMachine :: <ISA_LIT>TargetMachine ( const Target & T , const Triple & TT , StringRef CPU , StringRef FS , const TargetOptions & Options , Optional < Reloc :: Model > RM , Optional < CodeModel :: Model > CM , CodeGenOpt :: Level OL , bool JIT ) : LLVMTargetMachine ( T , computeDataLayout ( TT ) , TT , CPU , FS , Options , getEffectiveRelocModel ( RM ) , getEffectiveCodeModel ( CM ) , OL ) , TLOF ( make_unique < TargetLoweringObjectFileELF > ( ) ) , Subtarget ( TT , CPU , FS , * this ) { initAsmInfo ( ) ; <ISA_LIT>MCAsmInfo * MAI = static_cast < <ISA_LIT>MCAsmInfo * > ( const_cast < MCAsmInfo * > ( AsmInfo ) ) ;

MAI -> setDwarfUsesRelocationsAcrossSections ( ! Subtarget . getUseDwarfRIS ( ) ) ;


<s> static CodeModel :: Model getEffectiveCodeModel ( Optional < CodeModel :: Model > CM ) {


<s> <ISA_LIT>TargetMachine :: <ISA_LIT>TargetMachine ( const Target & T , StringRef TT , StringRef CPU , StringRef FS , const TargetOptions & Options , Reloc :: Model RM , CodeModel :: Model CM , CodeGenOpt :: Level OL ) : LLVMTargetMachine ( T , computeDataLayout ( TT ) , TT , CPU , FS , Options , RM , CM , OL ) , TLOF ( make_unique < TargetLoweringObjectFileELF > ( ) ) , Subtarget ( TT , CPU , FS , * this ) {


<s> static std :: string computeDataLayout ( StringRef TT ) { if ( Triple ( TT ) . getArch ( ) == Triple :: bpfeb ) return <STR_LIT> ; else return <STR_LIT> ;


<s> Builder . addExtension ( PassManagerBuilder :: EP_EarlyAsPossible , [ & ] ( const PassManagerBuilder & , legacy :: PassManagerBase & PM ) { PM . add ( create<ISA_LIT>AbstractMemberAccess ( this ) ) ;

PM . add ( create<ISA_LIT>PreserveDIType ( ) ) ;


<s> <ISA_LIT>TargetMachine :: <ISA_LIT>TargetMachine ( const Target & T , StringRef TT , StringRef CPU , StringRef FS , const TargetOptions & Options , Reloc :: Model RM , CodeModel :: Model CM , CodeGenOpt :: Level OL ) : LLVMTargetMachine ( T , TT , CPU , FS , Options , RM , CM , OL ) , Subtarget ( TT , CPU , FS ) , DL ( <STR_LIT> ) , InstrInfo ( ) , TLInfo ( * this ) , TSInfo ( * this ) , FrameLowering ( Subtarget ) { initAsmInfo ( ) ;


<s> void LLVMInitialize<ISA_LIT>Target ( ) {

RegisterTargetMachine < <ISA_LIT>TargetMachine > X ( The<ISA_LIT>Target ) ;


<s> <ISA_LIT>TargetMachine :: <ISA_LIT>TargetMachine ( const Target & T , StringRef TT , StringRef CPU , StringRef FS , const TargetOptions & Options , Reloc :: Model RM , CodeModel :: Model CM , CodeGenOpt :: Level OL ) : LLVMTargetMachine ( T , <STR_LIT> , TT , CPU , FS , Options , RM , CM , OL ) , TLOF ( make_unique < TargetLoweringObjectFileELF > ( ) ) , Subtarget ( TT , CPU , FS , * this ) {


<s> void <ISA_LIT>PassConfig :: addIRPasses ( ) { addPass ( create<ISA_LIT>AbstractMemberAccess ( ) ) ;


<s> const DataLayout * getDataLayout ( ) const override {


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


<s> FPM . addPass ( <ISA_LIT>PreserveDITypePass ( ) ) ; MPM . addPass ( createModuleToFunctionPassAdaptor ( std :: move ( FPM ) ) ) ; } ) ; PB . registerPeepholeEPCallback ( [ = ] ( FunctionPassManager & FPM , PassBuilder :: OptimizationLevel Level ) {


<s> <ISA_LIT>TargetMachine :: <ISA_LIT>TargetMachine ( const Target & T , const Triple & TT , StringRef CPU , StringRef FS , const TargetOptions & Options , Optional < Reloc :: Model > RM , Optional < CodeModel :: Model > CM , CodeGenOpt :: Level OL , bool JIT ) : LLVMTargetMachine ( T , computeDataLayout ( TT ) , TT , CPU , FS , Options , getEffectiveRelocModel ( RM ) , getEffectiveCodeModel ( CM ) , OL ) , TLOF ( make_unique < TargetLoweringObjectFileELF > ( ) ) , Subtarget ( TT , CPU , FS , * this ) {


<s> <ISA_LIT>TargetMachine :: <ISA_LIT>TargetMachine ( const Target & T , const Triple & TT , StringRef CPU , StringRef FS , const TargetOptions & Options , Optional < Reloc :: Model > RM , Optional < CodeModel :: Model > CM , CodeGenOpt :: Level OL , bool JIT ) : LLVMTargetMachine ( T , computeDataLayout ( TT ) , TT , CPU , FS , Options , getEffectiveRelocModel ( RM ) , getEffectiveCodeModel ( CM ) , OL ) , TLOF ( make_unique < TargetLoweringObjectFileELF > ( ) ) , Subtarget ( TT , CPU , FS , * this ) { initAsmInfo ( ) ;


<s> <ISA_LIT>TargetMachine :: <ISA_LIT>TargetMachine ( const Target & T , StringRef TT , StringRef CPU , StringRef FS , const TargetOptions & Options , Reloc :: Model RM , CodeModel :: Model CM , CodeGenOpt :: Level OL ) : LLVMTargetMachine ( T , TT , CPU , FS , Options , RM , CM , OL ) , TLOF ( make_unique < TargetLoweringObjectFileELF > ( ) ) , DL ( <STR_LIT> ) , Subtarget ( TT , CPU , FS , * this ) { initAsmInfo ( ) ;


<s> addPass ( create<ISA_LIT>CheckAndAdjustIR ( ) ) ; TargetPassConfig :: addIRPasses ( ) ;


<s> const <ISA_LIT>Subtarget * Subtarget = get<ISA_LIT>TargetMachine ( ) . getSubtargetImpl ( ) ; if ( ! DisableMIPeephole ) { if ( Subtarget -> getHasAlu32 ( ) ) addPass ( create<ISA_LIT>MIPeepholePass ( ) ) ;

addPass ( create<ISA_LIT>MIPeepholeTruncElimPass ( ) ) ;


<s> if ( getOptLevel ( ) != CodeGenOpt :: None ) if ( ! DisableMIPeephole ) addPass ( create<ISA_LIT>MIPreEmitPeepholePass ( ) ) ;


<s> PM . add ( createCFGSimplificationPass ( SimplifyCFGOptions ( ) . hoistCommonInsts ( true ) ) ) ; } ) ; Builder . addExtension ( PassManagerBuilder :: EP_ModuleOptimizerEarly , [ & ] ( const PassManagerBuilder & , legacy :: PassManagerBase & PM ) { PM . add ( create<ISA_LIT>AdjustOpt ( ) ) ;


<s> PM . add ( create<ISA_LIT>AbstractMemberAccess ( this ) ) ; PM . add ( create<ISA_LIT>PreserveDIType ( ) ) ; PM . add ( create<ISA_LIT>IRPeephole ( ) ) ; } ) ;

Builder . addExtension ( PassManagerBuilder :: EP_Peephole , [ & ] ( const PassManagerBuilder & , legacy :: PassManagerBase & PM ) {


<s> <ISA_LIT>TargetMachine :: <ISA_LIT>TargetMachine ( const Target & T , const Triple & TT , StringRef CPU , StringRef FS , const TargetOptions & Options , Optional < Reloc :: Model > RM , Optional < CodeModel :: Model > CM , CodeGenOpt :: Level OL , bool JIT ) : LLVMTargetMachine ( T , computeDataLayout ( TT ) , TT , CPU , FS , Options , getEffectiveRelocModel ( RM ) , getEffectiveCodeModel ( CM , CodeModel :: Small ) , OL ) , TLOF ( std :: make_unique < TargetLoweringObjectFileELF > ( ) ) , Subtarget ( TT , std :: string ( CPU ) , std :: string ( FS ) , * this ) { initAsmInfo ( ) ; <ISA_LIT>MCAsmInfo * MAI = static_cast < <ISA_LIT>MCAsmInfo * > ( const_cast < MCAsmInfo * > ( AsmInfo . get ( ) ) ) ; MAI -> setDwarfUsesRelocationsAcrossSections ( ! Subtarget . getUseDwarfRIS ( ) ) ;


<s> if ( TT . getArch ( ) == Triple :: bpfeb ) return <STR_LIT> ;


<s> static Reloc :: Model getEffectiveRelocModel ( Optional < Reloc :: Model > RM ) { return RM . getValueOr ( Reloc :: PIC_ ) ;


<s> const <ISA_LIT>Subtarget * getSubtargetImpl ( const Function & ) const override {


<s> initialize<ISA_LIT>PreserveDITypePass ( PR ) ; initialize<ISA_LIT>IRPeepholePass ( PR ) ; initialize<ISA_LIT>AdjustOptPass ( PR ) ; initialize<ISA_LIT>CheckAndAdjustIRPass ( PR ) ; initialize<ISA_LIT>MIPeepholePass ( PR ) ;


<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 == <STR_LIT> && CostKind == TTI :: TCK_RecipThroughput ) return SCEVCheapExpansionBudget . getValue ( ) + <NUM_LIT> ;

return BaseT :: getArithmeticInstrCost ( Opcode , Ty , CostKind , Opd1Info , Opd2Info , Opd1PropInfo , Opd2PropInfo ) ;


<s> int ISD = TLI -> InstructionOpcodeToISD ( Opcode ) ; if ( ISD == <STR_LIT> && CostKind == TTI :: TCK_RecipThroughput ) return SCEVCheapExpansionBudget . getValue ( ) + <NUM_LIT> ; return BaseT :: getArithmeticInstrCost ( Opcode , Ty , CostKind , Opd1Info , Opd2Info , Opd1PropInfo , Opd2PropInfo ) ;


<s> int getCmpSelInstrCost ( unsigned Opcode , Type * ValTy , Type * CondTy , CmpInst :: Predicate VecPred , TTI :: TargetCostKind CostKind , const llvm :: Instruction * I = nullptr ) {

if ( Opcode == Instruction :: Select ) return SCEVCheapExpansionBudget ;


<s> explicit <ISA_LIT>TTIImpl ( const <ISA_LIT>TargetMachine * TM , const Function & F ) : BaseT ( TM , F . getParent ( ) -> getDataLayout ( ) ) , ST ( TM -> getSubtargetImpl ( F ) ) , TLI ( ST -> getTargetLowering ( ) ) {


<s> TTI :: MemCmpExpansionOptions Options ; Options . LoadSizes = { <NUM_LIT> , <NUM_LIT> , <NUM_LIT> , <NUM_LIT> } ; Options . MaxNumLoads = TLI -> getMaxExpandSizeMemcmp ( OptSize ) ;


<s> TTI :: MemCmpExpansionOptions enableMemCmpExpansion ( bool OptSize , bool IsZeroCmp ) const {


<s> int ISD = TLI -> InstructionOpcodeToISD ( Opcode ) ; if ( ISD == <STR_LIT> && CostKind == TTI :: TCK_RecipThroughput ) return SCEVCheapExpansionBudget . getValue ( ) + <NUM_LIT> ;


<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 ) ;


<s> if ( Opcode == Instruction :: Select ) return SCEVCheapExpansionBudget . getValue ( ) ;

return BaseT :: getCmpSelInstrCost ( Opcode , ValTy , CondTy , VecPred , CostKind , I ) ;


<s> int getIntImmCost ( const APInt & Imm , Type * Ty , TTI :: TargetCostKind CostKind ) {

if ( Imm . getBitWidth ( ) <= <NUM_LIT> && isInt < <NUM_LIT> > ( Imm . getSExtValue ( ) ) ) return TTI :: TCC_Free ;


<s> const <ISA_LIT>Subtarget * getST ( ) const { return ST ;


<s> const <ISA_LIT>TargetLowering * getTLI ( ) const {


<s> <ISA_LIT>AbstractMemberAccessPass ( <ISA_LIT>TargetMachine * TM ) : TM ( TM ) {


<s> uint32_t <STR_LIT> ( StringRef S ) { for ( auto & OffsetM : OffsetToIdMap ) { if ( Table [ OffsetM . second ] == S ) return OffsetM . first ;


<s> uint32_t Id = TypeEntry -> getId ( ) ; TypeEntries . push_back ( std :: move ( TypeEntry ) ) ; return Id ;


<s> uint32_t BTFDebug :: addType ( std :: unique_ptr < BTFTypeBase > TypeEntry ) {

TypeEntry -> setId ( TypeEntries . size ( ) + <NUM_LIT> ) ;


<s> 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 ;


<s> for ( ; MI -> getOperand ( NumDefs ) . isReg ( ) && MI -> getOperand ( NumDefs ) . isDef ( ) ; ++ NumDefs ) ; const char * AsmStr = MI -> getOperand ( NumDefs ) . getSymbolName ( ) ; if ( AsmStr [ <NUM_LIT> ] == <NUM_LIT> ) 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 ( ) , <NUM_LIT> ) ; LineInfoGenerated = true ; }


<s> BTFDebug :: BTFDebug ( AsmPrinter * AP ) : DebugHandlerBase ( AP ) , OS ( * Asm -> OutStreamer ) , SkipInstruction ( false ) , LineInfoGenerated ( false ) , SecNameOff ( <NUM_LIT> ) , ArrayIndexTypeId ( <NUM_LIT> ) { addString ( <STR_LIT> ) ;


<s> Kind = <STR_LIT> ; BTFType . Info = Kind << <NUM_LIT> ;


<s> BTFTypeDerived :: BTFTypeDerived ( const DIDerivedType * DTy , unsigned Tag ) : DTy ( DTy ) { switch ( Tag ) { case dwarf :: DW_TAG_pointer_type : Kind = <STR_LIT> ; break ; case dwarf :: DW_TAG_const_type : Kind = <STR_LIT> ; break ; case dwarf :: DW_TAG_volatile_type : Kind = <STR_LIT> ;


<s> BTFType . Info = Kind << <NUM_LIT> | VLen ;

BTFType . Size = roundupToBytes ( ETy -> getSizeInBits ( ) ) ;


<s> BTFType . Info = Kind << <NUM_LIT> ;


BTFType . Info = IsUnion << <NUM_LIT> | Kind << <NUM_LIT> ;


<s> <STR_LIT> ( uint32_t Encoding , uint32_t SizeInBits , uint32_t OffsetInBits , StringRef TypeName ) : Name ( TypeName ) { uint8_t BTFEncoding ; switch ( Encoding ) { case dwarf :: DW_ATE_boolean : BTFEncoding = <STR_LIT> ; break ; case dwarf :: DW_ATE_signed : case dwarf :: DW_ATE_signed_char : BTFEncoding = <STR_LIT> ; break ; case dwarf :: DW_ATE_unsigned : case dwarf :: DW_ATE_unsigned_char : BTFEncoding = <NUM_LIT> ; break ; default : llvm_unreachable ( <STR_LIT> ) ; } Kind = <STR_LIT> ; BTFType . Info = Kind << <NUM_LIT> ;

BTFType . Size = roundupToBytes ( SizeInBits ) ;


<s> BTFTypeStruct :: BTFTypeStruct ( const DICompositeType * STy , bool IsStruct , bool HasBitField , uint32_t Vlen ) : STy ( STy ) , HasBitField ( HasBitField ) { Kind = IsStruct ? <STR_LIT> : <STR_LIT> ; BTFType . Size = roundupToBytes ( STy -> getSizeInBits ( ) ) ;

BTFType . Info = ( HasBitField << <NUM_LIT> ) | ( Kind << <NUM_LIT> ) | Vlen ;


<s> BTFType . NameOff = BDebug . addString ( Name ) ;


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


<s> LineInfo . Label = Label ; LineInfo . FileNameOff = addString ( FileName ) ; if ( Line < FileContent [ FileName ] . size ( ) ) LineInfo . LineOff = addString ( FileContent [ FileName ] [ Line ] ) ;


<s> void BTFDebug :: constructLineInfo ( const DISubprogram * SP , MCSymbol * Label , uint32_t Line , uint32_t Column ) { std :: string FileName = populateFileContent ( SP ) ;


<s> OS . AddComment ( <STR_LIT> ) ; OS . EmitIntValue ( <STR_LIT> , <NUM_LIT> ) ; for ( const auto & LineSec : LineInfoTable ) { OS . AddComment ( <STR_LIT> + std :: to_string ( LineSec . first ) ) ; OS . EmitIntValue ( LineSec . first , <NUM_LIT> ) ; OS . EmitIntValue ( LineSec . second . size ( ) , <NUM_LIT> ) ; for ( const auto & LineInfo : LineSec . second ) { Asm -> EmitLabelReference ( LineInfo . Label , <NUM_LIT> ) ; OS . EmitIntValue ( LineInfo . FileNameOff , <NUM_LIT> ) ; OS . EmitIntValue ( LineInfo . LineOff , <NUM_LIT> ) ;

OS . AddComment ( <STR_LIT> + std :: to_string ( LineInfo . LineNum ) + <STR_LIT> + std :: to_string ( LineInfo . ColumnNum ) ) ;


<s> MCContext & Ctx = OS . getContext ( ) ; OS . SwitchSection ( Ctx . getELFSection ( <STR_LIT> , ELF :: SHT_PROGBITS , <NUM_LIT> ) ) ; emitCommonHeader ( ) ; OS . EmitIntValue ( <STR_LIT> , <NUM_LIT> ) ; uint32_t TypeLen = <NUM_LIT> , StrLen ; for ( const auto & TypeEntry : TypeEntries ) TypeLen += TypeEntry -> getSize ( ) ; StrLen = StringTable . getSize ( ) ; OS . EmitIntValue ( <NUM_LIT> , <NUM_LIT> ) ; OS . EmitIntValue ( TypeLen , <NUM_LIT> ) ; OS . EmitIntValue ( TypeLen , <NUM_LIT> ) ; OS . EmitIntValue ( StrLen , <NUM_LIT> ) ; for ( const auto & TypeEntry : TypeEntries ) TypeEntry -> emitType ( OS ) ; uint32_t StringOffset = <NUM_LIT> ; for ( const auto & S : StringTable . getTable ( ) ) { OS . AddComment ( <STR_LIT> + std :: to_string ( StringOffset ) ) ; OS . EmitBytes ( S ) ;

OS . EmitBytes ( StringRef ( <STR_LIT> , <NUM_LIT> ) ) ;


<s> OS . EmitIntValue ( <STR_LIT> , <NUM_LIT> ) ;

OS . EmitIntValue ( <NUM_LIT> , <NUM_LIT> ) ;


<s> void BTFDebug :: emitCommonHeader ( ) { OS . AddComment ( <STR_LIT> + Twine :: utohexstr ( <STR_LIT> ) ) ;

OS . EmitIntValue ( <STR_LIT> , <NUM_LIT> ) ;


<s> void BTFTypeFunc :: emitType ( MCStreamer & OS ) {


<s> DIGlobalVariable * GV = GVE -> getVariable ( ) ; visitTypeEntry ( GV -> getType ( ) . resolve ( ) ) ; } } for ( const auto & TypeEntry : TypeEntries ) TypeEntry -> completeType ( * this ) ; emitBTFSection ( ) ;


<s> if ( File -> getDirectory ( ) . size ( ) ) FileName = File -> getDirectory ( ) . str ( ) + <STR_LIT> + File -> getFilename ( ) . str ( ) ; else FileName = File -> getFilename ( ) ; if ( FileContent . find ( FileName ) != FileContent . end ( ) ) return FileName ; std :: vector < std :: string > Content ; std :: string Line ; Content . push_back ( Line ) ; auto Source = File -> getSource ( ) ; if ( Source ) { std :: istringstream InputString ( Source . getValue ( ) ) ; while ( std :: getline ( InputString , Line ) ) Content . push_back ( Line ) ; } else { std :: ifstream InputFile ( FileName ) ; while ( std :: getline ( InputFile , Line ) ) Content . push_back ( Line ) ; } FileContent [ FileName ] = Content ; return FileName ;


<s> Content . push_back ( Line ) ; auto Source = File -> getSource ( ) ; if ( Source ) { std :: istringstream InputString ( Source . getValue ( ) ) ; while ( std :: getline ( InputString , Line ) ) Content . push_back ( Line ) ; } else { std :: ifstream InputFile ( FileName ) ; while ( std :: getline ( InputFile , Line ) ) Content . push_back ( Line ) ;


<s> addType ( std :: move ( TypeEntry ) , CTy ) ; if ( ! ArrayIndexTypeId ) { auto TypeEntry = llvm :: make_unique < BTFTypeInt > ( dwarf :: DW_ATE_unsigned , <NUM_LIT> , <NUM_LIT> , <STR_LIT> ) ; ArrayIndexTypeId = addType ( std :: move ( TypeEntry ) ) ;


<s> if ( Encoding != dwarf :: DW_ATE_boolean && Encoding != dwarf :: DW_ATE_signed && Encoding != dwarf :: DW_ATE_signed_char && Encoding != dwarf :: DW_ATE_unsigned && Encoding != dwarf :: DW_ATE_unsigned_char ) return ;

auto TypeEntry = llvm :: make_unique < BTFTypeInt > ( Encoding , BTy -> getSizeInBits ( ) , BTy -> getOffsetInBits ( ) , BTy -> getName ( ) ) ;


<s> void BTFDebug :: visitCompositeType ( const DICompositeType * CTy ) { auto Tag = CTy -> getTag ( ) ; if ( Tag == dwarf :: DW_TAG_structure_type || Tag == dwarf :: DW_TAG_union_type ) {

if ( CTy -> isForwardDecl ( ) ) visitFwdDeclType ( CTy , Tag == dwarf :: DW_TAG_union_type ) ;


<s> } else if ( Tag == dwarf :: DW_TAG_array_type ) visitArrayType ( CTy ) ; else if ( Tag == dwarf :: DW_TAG_enumeration_type ) visitEnumType ( CTy ) ;


<s> if ( Tag == dwarf :: DW_TAG_pointer_type || Tag == dwarf :: DW_TAG_typedef || Tag == dwarf :: DW_TAG_const_type || Tag == dwarf :: DW_TAG_volatile_type || Tag == dwarf :: DW_TAG_restrict_type ) { auto TypeEntry = llvm :: make_unique < BTFTypeDerived > ( DTy , Tag ) ;

addType ( std :: move ( TypeEntry ) , DTy ) ;


<s> void BTFDebug :: visitDerivedType ( const DIDerivedType * DTy ) { unsigned Tag = DTy -> getTag ( ) ; if ( Tag == dwarf :: DW_TAG_pointer_type || Tag == dwarf :: DW_TAG_typedef || Tag == dwarf :: DW_TAG_const_type || Tag == dwarf :: DW_TAG_volatile_type || Tag == dwarf :: DW_TAG_restrict_type ) { auto TypeEntry = llvm :: make_unique < BTFTypeDerived > ( DTy , Tag ) ; addType ( std :: move ( TypeEntry ) , DTy ) ; } else if ( Tag != dwarf :: DW_TAG_member ) { return ; }

visitTypeEntry ( DTy -> getBaseType ( ) . resolve ( ) ) ;


<s> DINodeArray Elements = CTy -> getElements ( ) ; uint32_t VLen = Elements . size ( ) ; if ( VLen > <STR_LIT> ) return ; auto TypeEntry = llvm :: make_unique < BTFTypeEnum > ( CTy , VLen ) ;

addType ( std :: move ( TypeEntry ) , CTy ) ;


<s> auto TypeEntry = llvm :: make_unique < BTFTypeFwd > ( CTy -> getName ( ) , IsUnion ) ;


<s> uint32_t VLen = Elements . size ( ) ; if ( VLen > <STR_LIT> ) return ; bool HasBitField = false ; for ( const auto * Element : Elements ) { auto E = cast < DIDerivedType > ( Element ) ; if ( E -> isBitField ( ) ) { HasBitField = true ; break ; } } auto TypeEntry = llvm :: make_unique < BTFTypeStruct > ( CTy , IsStruct , HasBitField , VLen ) ; addType ( std :: move ( TypeEntry ) , CTy ) ;

for ( const auto * Element : Elements ) visitTypeEntry ( cast < DIDerivedType > ( Element ) ) ;


<s> } } auto TypeEntry = llvm :: make_unique < BTFTypeStruct > ( CTy , IsStruct , HasBitField , VLen ) ; addType ( std :: move ( TypeEntry ) , CTy ) ;


<s> if ( ForSubprog ) TypeId = addType ( std :: move ( TypeEntry ) ) ; else addType ( std :: move ( TypeEntry ) , STy ) ; for ( const auto Element : Elements ) {

visitTypeEntry ( Element . resolve ( ) ) ;


<s> else if ( const auto * CTy = dyn_cast < DICompositeType > ( Ty ) ) visitCompositeType ( CTy ) ; else if ( const auto * DTy = dyn_cast < DIDerivedType > ( Ty ) ) visitDerivedType ( DTy ) ; else llvm_unreachable ( <STR_LIT> ) ;


<s> void BTFDebug :: visitTypeEntry ( const DIType * Ty ) { if ( ! Ty || DIToIdMap . find ( Ty ) != DIToIdMap . end ( ) ) return ; uint32_t TypeId ; if ( const auto * BTy = dyn_cast < DIBasicType > ( Ty ) ) visitBasicType ( BTy ) ;

else if ( const auto * STy = dyn_cast < DISubroutineType > ( Ty ) ) visitSubroutineType ( STy , false , std :: unordered_map < uint32_t , StringRef > ( ) , TypeId ) ;


<s> 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 ( ) ? <STR_LIT> : <STR_LIT> ; 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 && <STR_LIT> ) ;

SecNameOff = addString ( SectionELF -> getName ( ) ) ;


<s> } 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 ( ) ? <STR_LIT> : <STR_LIT> ; 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 ;


<s> const char * AsmStr = MI -> getOperand ( NumDefs ) . getSymbolName ( ) ; if ( AsmStr [ <NUM_LIT> ] == <NUM_LIT> ) return ; } if ( MI -> getOpcode ( ) == <STR_LIT> ) { processReloc ( MI -> getOperand ( <NUM_LIT> ) ) ; } else if ( MI -> getOpcode ( ) == <STR_LIT> || MI -> getOpcode ( ) == <STR_LIT> || MI -> getOpcode ( ) == <STR_LIT> ) { processReloc ( MI -> getOperand ( <NUM_LIT> ) ) ; } else if ( MI -> getOpcode ( ) == <STR_LIT> ) { const MachineOperand & MO = MI -> getOperand ( <NUM_LIT> ) ; if ( MO . isGlobal ( ) ) { processFuncPrototypes ( dyn_cast < Function > ( MO . getGlobal ( ) ) ) ;


<s> OS . SwitchSection ( Ctx . getELFSection ( <STR_LIT> , ELF :: SHT_PROGBITS , <NUM_LIT> ) ) ; emitCommonHeader ( ) ; OS . emitInt32 ( <STR_LIT> ) ; uint32_t FuncLen = <NUM_LIT> , LineLen = <NUM_LIT> ; uint32_t FieldRelocLen = <NUM_LIT> ; for ( const auto & FuncSec : FuncInfoTable ) { FuncLen += <STR_LIT> ; FuncLen += FuncSec . second . size ( ) * <STR_LIT> ; } for ( const auto & LineSec : LineInfoTable ) { LineLen += <STR_LIT> ; LineLen += LineSec . second . size ( ) * <STR_LIT> ; } for ( const auto & FieldRelocSec : FieldRelocTable ) { FieldRelocLen += <STR_LIT> ; FieldRelocLen += FieldRelocSec . second . size ( ) * <STR_LIT> ; } if ( FieldRelocLen ) FieldRelocLen += <NUM_LIT> ; OS . emitInt32 ( <NUM_LIT> ) ; OS . emitInt32 ( FuncLen ) ; OS . emitInt32 ( FuncLen ) ; OS . emitInt32 ( LineLen ) ; OS . emitInt32 ( FuncLen + LineLen ) ; OS . emitInt32 ( FieldRelocLen ) ; OS . AddComment ( <STR_LIT> ) ;


<s> OS . emitInt32 ( <STR_LIT> ) ; uint32_t TypeLen = <NUM_LIT> , StrLen ; for ( const auto & TypeEntry : TypeEntries ) TypeLen += TypeEntry -> getSize ( ) ; StrLen = StringTable . getSize ( ) ; OS . emitInt32 ( <NUM_LIT> ) ; OS . emitInt32 ( TypeLen ) ; OS . emitInt32 ( TypeLen ) ; OS . emitInt32 ( StrLen ) ; for ( const auto & TypeEntry : TypeEntries ) TypeEntry -> emitType ( OS ) ; uint32_t StringOffset = <NUM_LIT> ; for ( const auto & S : StringTable . getTable ( ) ) { OS . AddComment ( <STR_LIT> + std :: to_string ( StringOffset ) ) ;


<s> OS . emitInt32 ( TypeLen ) ; OS . emitInt32 ( StrLen ) ; for ( const auto & TypeEntry : TypeEntries ) TypeEntry -> emitType ( OS ) ; uint32_t StringOffset = <NUM_LIT> ; for ( const auto & S : StringTable . getTable ( ) ) { OS . AddComment ( <STR_LIT> + std :: to_string ( StringOffset ) ) ; OS . emitBytes ( S ) ; OS . emitBytes ( StringRef ( <STR_LIT> , <NUM_LIT> ) ) ; StringOffset += S . size ( ) + <NUM_LIT> ;


<s> size_t SecondColon = AccessPattern . find_first_of ( ':' , FirstColon + <NUM_LIT> ) ; StringRef IndexPattern = AccessPattern . substr ( FirstDollar + <NUM_LIT> ) ; StringRef RelocKindStr = AccessPattern . substr ( FirstColon + <NUM_LIT> , SecondColon - FirstColon ) ; StringRef PatchImmStr = AccessPattern . substr ( SecondColon + <NUM_LIT> , FirstDollar - SecondColon ) ; FieldReloc . OffsetNameOff = addString ( IndexPattern ) ; FieldReloc . RelocKind = std :: stoull ( std :: string ( RelocKindStr ) ) ; PatchImms [ GVar ] = std :: stoul ( std :: string ( PatchImmStr ) ) ; } else { StringRef RelocStr = AccessPattern . substr ( FirstDollar + <NUM_LIT> ) ;

FieldReloc . OffsetNameOff = addString ( <STR_LIT> ) ;


<s> StringRef PatchImmStr = AccessPattern . substr ( SecondColon + <NUM_LIT> , FirstDollar - SecondColon ) ; FieldReloc . OffsetNameOff = addString ( IndexPattern ) ; FieldReloc . RelocKind = std :: stoull ( std :: string ( RelocKindStr ) ) ; PatchImms [ GVar ] = std :: stoul ( std :: string ( PatchImmStr ) ) ; } else { StringRef RelocStr = AccessPattern . substr ( FirstDollar + <NUM_LIT> ) ; FieldReloc . OffsetNameOff = addString ( <STR_LIT> ) ; FieldReloc . RelocKind = std :: stoull ( std :: string ( RelocStr ) ) ; PatchImms [ GVar ] = RootId ; } FieldRelocTable [ SecNameOff ] . push_back ( FieldReloc ) ;


<s> auto * GVar = dyn_cast < GlobalVariable > ( GVal ) ; if ( GVar && GVar -> hasAttribute ( <STR_LIT> ) ) { uint32_t Imm = PatchImms [ GVar ] ; OutMI . setOpcode ( MI -> getOperand ( <NUM_LIT> ) . getImm ( ) ) ; if ( MI -> getOperand ( <NUM_LIT> ) . isImm ( ) ) OutMI . addOperand ( MCOperand :: createImm ( MI -> getOperand ( <NUM_LIT> ) . getImm ( ) ) ) ; else OutMI . addOperand ( MCOperand :: createReg ( MI -> getOperand ( <NUM_LIT> ) . getReg ( ) ) ) ; OutMI . addOperand ( MCOperand :: createReg ( MI -> getOperand ( <NUM_LIT> ) . getReg ( ) ) ) ; OutMI . addOperand ( MCOperand :: createImm ( Imm ) ) ; return true ; } }


<s> const DISubprogram * SP = F -> getSubprogram ( ) ; if ( ! SP || SP -> isDefinition ( ) ) return ;

if ( ProtoFunctions . find ( F ) != ProtoFunctions . end ( ) ) return ;


<s> if ( GVs . size ( ) == <NUM_LIT> ) continue ; uint32_t GVTypeId = <NUM_LIT> ; for ( auto * GVE : GVs ) { if ( SecName . startswith ( <STR_LIT> ) ) visitMapDefType ( GVE -> getVariable ( ) -> getType ( ) , GVTypeId ) ; else visitTypeEntry ( GVE -> getVariable ( ) -> getType ( ) , GVTypeId , false , false ) ; break ; } auto Linkage = Global . getLinkage ( ) ; if ( Linkage != GlobalValue :: InternalLinkage && Linkage != GlobalValue :: ExternalLinkage && Linkage != GlobalValue :: WeakAnyLinkage && Linkage != GlobalValue :: ExternalWeakLinkage ) continue ; uint32_t GVarInfo ; if ( Linkage == GlobalValue :: InternalLinkage ) { GVarInfo = <STR_LIT> ; } else if ( Global . hasInitializer ( ) ) { GVarInfo = <STR_LIT> ; } else { GVarInfo = <STR_LIT> ; } auto VarEntry = std :: make_unique < BTFKindVar > ( Global . getName ( ) , GVTypeId , GVarInfo ) ; uint32_t VarId = addType ( std :: move ( VarEntry ) ) ; assert ( ! SecName . empty ( ) ) ; if ( DataSecEntries . find ( std :: string ( SecName ) ) == DataSecEntries . end ( ) ) {

DataSecEntries [ std :: string ( SecName ) ] = std :: make_unique < BTFKindDataSec > ( Asm , std :: string ( SecName ) ) ;


<s> } auto VarEntry = std :: make_unique < BTFKindVar > ( Global . getName ( ) , GVTypeId , GVarInfo ) ; uint32_t VarId = addType ( std :: move ( VarEntry ) ) ; assert ( ! SecName . empty ( ) ) ; if ( DataSecEntries . find ( std :: string ( SecName ) ) == DataSecEntries . end ( ) ) { DataSecEntries [ std :: string ( SecName ) ] = std :: make_unique < BTFKindDataSec > ( Asm , std :: string ( SecName ) ) ; } const DataLayout & DL = Global . getParent ( ) -> getDataLayout ( ) ; uint32_t Size = DL . getTypeAllocSize ( Global . getType ( ) -> getElementType ( ) ) ; DataSecEntries [ std :: string ( SecName ) ] -> addVar ( VarId , Asm -> getSymbol ( & Global ) , Size ) ; }


<s> if ( ! GVar ) return ; if ( ! GVar -> hasAttribute ( <STR_LIT> ) && ! GVar -> hasAttribute ( <STR_LIT> ) ) return ; MCSymbol * ORSym = OS . getContext ( ) . createTempSymbol ( ) ;


<s> void BTFDebug :: visitBasicType ( const DIBasicType * BTy , uint32_t & TypeId ) { uint32_t Encoding = BTy -> getEncoding ( ) ;

if ( Encoding != dwarf :: DW_ATE_boolean && Encoding != dwarf :: DW_ATE_signed && Encoding != dwarf :: DW_ATE_signed_char && Encoding != dwarf :: DW_ATE_unsigned && Encoding != dwarf :: DW_ATE_unsigned_char ) return ;


<s> SeenPointer = Tag == dwarf :: DW_TAG_pointer_type ; } if ( CheckPointer && SeenPointer ) { const DIType * Base = DTy -> getBaseType ( ) ; if ( Base ) { if ( const auto * CTy = dyn_cast < DICompositeType > ( Base ) ) { auto CTag = CTy -> getTag ( ) ; if ( ( CTag == dwarf :: DW_TAG_structure_type || CTag == dwarf :: DW_TAG_union_type ) && ! CTy -> isForwardDecl ( ) ) { auto TypeEntry = std :: make_unique < BTFTypeDerived > ( DTy , Tag , true ) ; auto & Fixup = FixupDerivedTypes [ CTy -> getName ( ) ] ;

Fixup . first = CTag == dwarf :: DW_TAG_union_type ;


<s> break ; } } auto TypeEntry = std :: make_unique < BTFTypeStruct > ( CTy , true , HasBitField , Elements . size ( ) ) ; StructTypes . push_back ( TypeEntry . get ( ) ) ; TypeId = addType ( std :: move ( TypeEntry ) , CTy ) ; for ( const auto * Element : Elements ) { const auto * MemberType = cast < DIDerivedType > ( Element ) ; visitTypeEntry ( MemberType -> getBaseType ( ) ) ; }


<s> auto TypeEntry = std :: make_unique < BTFTypeStruct > ( CTy , IsStruct , HasBitField , VLen ) ; StructTypes . push_back ( TypeEntry . get ( ) ) ; TypeId = addType ( std :: move ( TypeEntry ) , CTy ) ; for ( const auto * Element : Elements ) visitTypeEntry ( cast < DIDerivedType > ( Element ) ) ;


<s> else if ( const auto * STy = dyn_cast < DISubroutineType > ( Ty ) ) visitSubroutineType ( STy , false , std :: unordered_map < uint32_t , StringRef > ( ) , TypeId ) ;

else if ( const auto * CTy = dyn_cast < DICompositeType > ( Ty ) ) visitCompositeType ( CTy , TypeId ) ;


<s> 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 && <STR_LIT> ) ;

SecNameOff = addString ( SectionELF -> getSectionName ( ) ) ;


<s> 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 && <STR_LIT> ) ; SecNameOff = addString ( SectionELF -> getSectionName ( ) ) ; } else { SecNameOff = addString ( <STR_LIT> ) ;


<s> for ( ; MI -> getOperand ( NumDefs ) . isReg ( ) && MI -> getOperand ( NumDefs ) . isDef ( ) ; ++ NumDefs ) ; const char * AsmStr = MI -> getOperand ( NumDefs ) . getSymbolName ( ) ; if ( AsmStr [ <NUM_LIT> ] == <NUM_LIT> ) return ; } if ( MI -> getOpcode ( ) == <STR_LIT> ) processLDimm64 ( MI ) ; const DebugLoc & DL = MI -> getDebugLoc ( ) ; if ( ! DL || PrevInstLoc == DL ) { if ( LineInfoGenerated == false ) {

auto * S = MI -> getMF ( ) -> getFunction ( ) . getSubprogram ( ) ;


<s> if ( IsCompleted ) return ; IsCompleted = true ; BTFType . NameOff = BDebug . addString ( ETy -> getName ( ) ) ;

DINodeArray Elements = ETy -> getElements ( ) ;


<s> BTFType . NameOff = BDebug . addString ( ETy -> getName ( ) ) ; DINodeArray Elements = ETy -> getElements ( ) ; for ( const auto Element : Elements ) { const auto * Enum = cast < DIEnumerator > ( Element ) ; struct <STR_LIT> BTFEnum ; BTFEnum . NameOff = BDebug . addString ( Enum -> getName ( ) ) ; BTFEnum . Val = static_cast < uint32_t > ( Enum -> getValue ( ) ) ; EnumValues . push_back ( BTFEnum ) ; }


<s> FuncLen += <STR_LIT> ; FuncLen += FuncSec . second . size ( ) * <STR_LIT> ; } for ( const auto & LineSec : LineInfoTable ) { LineLen += <STR_LIT> ; LineLen += LineSec . second . size ( ) * <STR_LIT> ; } for ( const auto & FieldRelocSec : FieldRelocTable ) { FieldRelocLen += <STR_LIT> ; FieldRelocLen += FieldRelocSec . second . size ( ) * <STR_LIT> ; } for ( const auto & ExternRelocSec : ExternRelocTable ) { ExternRelocLen += <STR_LIT> ; ExternRelocLen += ExternRelocSec . second . size ( ) * <STR_LIT> ; } if ( FieldRelocLen ) FieldRelocLen += <NUM_LIT> ; if ( ExternRelocLen ) ExternRelocLen += <NUM_LIT> ; OS . EmitIntValue ( <NUM_LIT> , <NUM_LIT> ) ; OS . EmitIntValue ( FuncLen , <NUM_LIT> ) ; OS . EmitIntValue ( FuncLen , <NUM_LIT> ) ; OS . EmitIntValue ( LineLen , <NUM_LIT> ) ; OS . EmitIntValue ( FuncLen + LineLen , <NUM_LIT> ) ; OS . EmitIntValue ( FieldRelocLen , <NUM_LIT> ) ; OS . EmitIntValue ( FuncLen + LineLen + FieldRelocLen , <NUM_LIT> ) ; OS . EmitIntValue ( ExternRelocLen , <NUM_LIT> ) ; OS . AddComment ( <STR_LIT> ) ; OS . EmitIntValue ( <STR_LIT> , <NUM_LIT> ) ; for ( const auto & FuncSec : FuncInfoTable ) { OS . AddComment ( <STR_LIT> + std :: to_string ( FuncSec . first ) ) ; OS . EmitIntValue ( FuncSec . first , <NUM_LIT> ) ; OS . EmitIntValue ( FuncSec . second . size ( ) , <NUM_LIT> ) ; for ( const auto & FuncInfo : FuncSec . second ) { Asm -> EmitLabelReference ( FuncInfo . Label , <NUM_LIT> ) ; OS . EmitIntValue ( FuncInfo . TypeId , <NUM_LIT> ) ; } } OS . AddComment ( <STR_LIT> ) ; OS . EmitIntValue ( <STR_LIT> , <NUM_LIT> ) ; for ( const auto & LineSec : LineInfoTable ) { OS . AddComment ( <STR_LIT> + std :: to_string ( LineSec . first ) ) ; OS . EmitIntValue ( LineSec . first , <NUM_LIT> ) ;

OS . EmitIntValue ( LineSec . second . size ( ) , <NUM_LIT> ) ;


<s> for ( const auto & TypeEntry : TypeEntries ) TypeLen += TypeEntry -> getSize ( ) ; StrLen = StringTable . getSize ( ) ; OS . EmitIntValue ( <NUM_LIT> , <NUM_LIT> ) ; OS . EmitIntValue ( TypeLen , <NUM_LIT> ) ; OS . EmitIntValue ( TypeLen , <NUM_LIT> ) ; OS . EmitIntValue ( StrLen , <NUM_LIT> ) ; for ( const auto & TypeEntry : TypeEntries ) TypeEntry -> emitType ( OS ) ; uint32_t StringOffset = <NUM_LIT> ; for ( const auto & S : StringTable . getTable ( ) ) { OS . AddComment ( <STR_LIT> + std :: to_string ( StringOffset ) ) ; OS . EmitBytes ( S ) ;

OS . EmitBytes ( StringRef ( <STR_LIT> , <NUM_LIT> ) ) ;


<s> void BTFDebug :: emitBTFSection ( ) { if ( ! TypeEntries . size ( ) && StringTable . getSize ( ) == <NUM_LIT> ) return ; MCContext & Ctx = OS . getContext ( ) ; OS . SwitchSection ( Ctx . getELFSection ( <STR_LIT> , ELF :: SHT_PROGBITS , <NUM_LIT> ) ) ; emitCommonHeader ( ) ; OS . EmitIntValue ( <STR_LIT> , <NUM_LIT> ) ; uint32_t TypeLen = <NUM_LIT> , StrLen ;

for ( const auto & TypeEntry : TypeEntries ) TypeLen += TypeEntry -> getSize ( ) ;


<s> void BTFKindDataSec :: emitType ( MCStreamer & OS ) { <STR_LIT> ( OS ) ; for ( const auto & V : Vars ) { OS . EmitIntValue ( std :: get < <NUM_LIT> > ( V ) , <NUM_LIT> ) ;

Asm -> EmitLabelReference ( std :: get < <NUM_LIT> > ( V ) , <NUM_LIT> ) ;


<s> OS . EmitIntValue ( std :: get < <NUM_LIT> > ( V ) , <NUM_LIT> ) ; Asm -> EmitLabelReference ( std :: get < <NUM_LIT> > ( V ) , <NUM_LIT> ) ; OS . EmitIntValue ( std :: get < <NUM_LIT> > ( V ) , <NUM_LIT> ) ; }


<s> StringRef RelocKindStr = AccessPattern . substr ( FirstColon + <NUM_LIT> , SecondColon - FirstColon ) ; StringRef PatchImmStr = AccessPattern . substr ( SecondColon + <NUM_LIT> , FirstDollar - SecondColon ) ; BTFFieldReloc FieldReloc ; FieldReloc . Label = ORSym ; FieldReloc . OffsetNameOff = addString ( IndexPattern ) ; FieldReloc . TypeID = RootId ; FieldReloc . RelocKind = std :: stoull ( RelocKindStr ) ; PatchImms [ AccessPattern . str ( ) ] = std :: stoul ( PatchImmStr ) ;

FieldRelocTable [ SecNameOff ] . push_back ( FieldReloc ) ;


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


return <STR_LIT> ( ) + <STR_LIT> * Vars . size ( ) ;


<s> OutMI . addOperand ( MCOperand :: createImm ( Imm ) ) ; return true ; } else if ( GVar && ! GVar -> hasInitializer ( ) && GVar -> hasExternalLinkage ( ) && GVar -> getSection ( ) == <STR_LIT> ) { const IntegerType * IntTy = dyn_cast < IntegerType > ( GVar -> getValueType ( ) ) ; assert ( IntTy ) ;

if ( IntTy -> getBitWidth ( ) == <NUM_LIT> ) OutMI . setOpcode ( <STR_LIT> ) ;


<s> } else if ( GVar && ! GVar -> hasInitializer ( ) && GVar -> hasExternalLinkage ( ) && GVar -> getSection ( ) == <STR_LIT> ) { const IntegerType * IntTy = dyn_cast < IntegerType > ( GVar -> getValueType ( ) ) ; assert ( IntTy ) ; if ( IntTy -> getBitWidth ( ) == <NUM_LIT> ) OutMI . setOpcode ( <STR_LIT> ) ; else OutMI . setOpcode ( <STR_LIT> ) ; OutMI . addOperand ( MCOperand :: createReg ( MI -> getOperand ( <NUM_LIT> ) . getReg ( ) ) ) ; OutMI . addOperand ( MCOperand :: createImm ( <NUM_LIT> ) ) ; return true ; }


<s> if ( ! File -> getFilename ( ) . startswith ( <STR_LIT> ) && File -> getDirectory ( ) . size ( ) ) FileName = File -> getDirectory ( ) . str ( ) + <STR_LIT> + File -> getFilename ( ) . str ( ) ; else FileName = File -> getFilename ( ) ; if ( FileContent . find ( FileName ) != FileContent . end ( ) ) return FileName ; std :: vector < std :: string > Content ; std :: string Line ; Content . push_back ( Line ) ; std :: unique_ptr < MemoryBuffer > Buf ; auto Source = File -> getSource ( ) ;

if ( Source ) Buf = MemoryBuffer :: getMemBufferCopy ( * Source ) ;


<s> visitTypeEntry ( Ty , Id , false , false ) ; for ( const auto & TypeEntry : TypeEntries ) TypeEntry -> completeType ( * this ) ; return Id ;


<s> if ( Global . hasSection ( ) ) { SecName = Global . getSection ( ) ; } else { if ( Global . isConstant ( ) ) SecName = <STR_LIT> ; else SecName = Global . getInitializer ( ) -> isZeroValue ( ) ? <STR_LIT> : <STR_LIT> ; } if ( ProcessingMapDef != SecName . startswith ( <STR_LIT> ) ) continue ; SmallVector < DIGlobalVariableExpression * , <NUM_LIT> > GVs ; Global . getDebugInfo ( GVs ) ; uint32_t GVTypeId = <NUM_LIT> ; for ( auto * GVE : GVs ) { if ( SecName . startswith ( <STR_LIT> ) ) visitMapDefType ( GVE -> getVariable ( ) -> getType ( ) , GVTypeId ) ; else visitTypeEntry ( GVE -> getVariable ( ) -> getType ( ) , GVTypeId , false , false ) ; break ; } auto Linkage = Global . getLinkage ( ) ; if ( Linkage != GlobalValue :: InternalLinkage && ( Linkage != GlobalValue :: ExternalLinkage || ! Global . hasSection ( ) ) ) continue ; uint32_t GVarInfo = Linkage == GlobalValue :: ExternalLinkage ? <STR_LIT> : <STR_LIT> ; auto VarEntry = std :: make_unique < BTFKindVar > ( Global . getName ( ) , GVTypeId , GVarInfo ) ; uint32_t VarId = addType ( std :: move ( VarEntry ) ) ;

if ( DataSecEntries . find ( SecName ) == DataSecEntries . end ( ) ) {


<s> if ( SecName . startswith ( <STR_LIT> ) ) visitMapDefType ( GVE -> getVariable ( ) -> getType ( ) , GVTypeId ) ; else visitTypeEntry ( GVE -> getVariable ( ) -> getType ( ) , GVTypeId , false , false ) ; break ; } auto Linkage = Global . getLinkage ( ) ; if ( Linkage != GlobalValue :: InternalLinkage && ( Linkage != GlobalValue :: ExternalLinkage || ! Global . hasSection ( ) ) ) continue ; uint32_t GVarInfo = Linkage == GlobalValue :: ExternalLinkage ? <STR_LIT> : <STR_LIT> ; auto VarEntry = std :: make_unique < BTFKindVar > ( Global . getName ( ) , GVTypeId , GVarInfo ) ; uint32_t VarId = addType ( std :: move ( VarEntry ) ) ; if ( DataSecEntries . find ( SecName ) == DataSecEntries . end ( ) ) { DataSecEntries [ SecName ] = std :: make_unique < BTFKindDataSec > ( Asm , SecName ) ;


<s> generateFieldReloc ( MI , ORSym , Ty , GVar -> getName ( ) ) ; } else if ( GVar && ! GVar -> hasInitializer ( ) && GVar -> hasExternalLinkage ( ) && GVar -> getSection ( ) == <STR_LIT> ) { MCSymbol * ORSym = OS . getContext ( ) . createTempSymbol ( ) ; OS . EmitLabel ( ORSym ) ; BTFExternReloc ExternReloc ; ExternReloc . Label = ORSym ; ExternReloc . ExternNameOff = addString ( GVar -> getName ( ) ) ;

ExternRelocTable [ SecNameOff ] . push_back ( ExternReloc ) ;


<s> Kind = <STR_LIT> ; BTFType . Info = Kind << <NUM_LIT> ; BTFType . Type = NextTypeId ;


<s> BTFTypeDerived :: BTFTypeDerived ( unsigned NextTypeId , unsigned Tag , StringRef Name ) : DTy ( nullptr ) , NeedsFixup ( false ) , Name ( Name ) { Kind = <STR_LIT> ;


<s> BTFTypeTypeTag :: BTFTypeTypeTag ( const DIDerivedType * DTy , StringRef Tag ) : DTy ( DTy ) , Tag ( Tag ) { Kind = <STR_LIT> ;


<s> Kind = <STR_LIT> ; BTFType . Info = Kind << <NUM_LIT> ;


<s> if ( DTy ) { const DIType * ResolvedType = DTy -> getBaseType ( ) ; if ( ! ResolvedType ) BTFType . Type = <NUM_LIT> ; else BTFType . Type = BDebug . getTypeId ( ResolvedType ) ;


<s> bool IsUnion = CTy -> getTag ( ) == dwarf :: DW_TAG_union_type ; uint32_t StructTypeId = <NUM_LIT> ; for ( const auto & StructType : StructTypes ) { if ( StructType -> getName ( ) == TypeName ) { StructTypeId = StructType -> getId ( ) ; break ; } } if ( StructTypeId == <NUM_LIT> ) { 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 >= <NUM_LIT> ) BDType -> setPointeeType ( TmpTypeId ) ; else BDType -> setPointeeType ( StructTypeId ) ; } } for ( const auto & TypeEntry : TypeEntries ) TypeEntry -> completeType ( * this ) ;


<s> } if ( MDStrs . size ( ) == <NUM_LIT> ) return - <NUM_LIT> ; unsigned TmpTypeId ; std :: unique_ptr < BTFTypeTypeTag > TypeEntry ; if ( BaseTypeId >= <NUM_LIT> ) TypeEntry = std :: make_unique < BTFTypeTypeTag > ( BaseTypeId , MDStrs [ <NUM_LIT> ] -> getString ( ) ) ; else TypeEntry = std :: make_unique < BTFTypeTypeTag > ( DTy , MDStrs [ <NUM_LIT> ] -> getString ( ) ) ;

TmpTypeId = addType ( std :: move ( TypeEntry ) ) ;


<s> if ( SecName . startswith ( <STR_LIT> ) ) visitMapDefType ( DIGlobal -> getType ( ) , GVTypeId ) ; else visitTypeEntry ( DIGlobal -> getType ( ) , GVTypeId , false , false ) ; break ; } auto Linkage = Global . getLinkage ( ) ; if ( Linkage != GlobalValue :: InternalLinkage && Linkage != GlobalValue :: ExternalLinkage && Linkage != GlobalValue :: WeakAnyLinkage && Linkage != GlobalValue :: WeakODRLinkage && Linkage != GlobalValue :: ExternalWeakLinkage ) continue ; uint32_t GVarInfo ; if ( Linkage == GlobalValue :: InternalLinkage ) { GVarInfo = <STR_LIT> ; } else if ( Global . hasInitializer ( ) ) { GVarInfo = <STR_LIT> ; } else { GVarInfo = <STR_LIT> ; } auto VarEntry = std :: make_unique < BTFKindVar > ( Global . getName ( ) , GVTypeId , GVarInfo ) ; uint32_t VarId = addType ( std :: move ( VarEntry ) ) ; processDeclAnnotations ( DIGlobal -> getAnnotations ( ) , VarId , - <NUM_LIT> ) ; if ( SecName . empty ( ) ) continue ;

if ( DataSecEntries . find ( std :: string ( SecName ) ) == DataSecEntries . end ( ) ) {


<s> const Module * M = MMI -> getModule ( ) ; for ( const GlobalVariable & Global : M -> globals ( ) ) { StringRef SecName ; if ( Global . hasSection ( ) ) { SecName = Global . getSection ( ) ; } else if ( Global . hasInitializer ( ) ) { if ( Global . isConstant ( ) ) SecName = <STR_LIT> ; else SecName = Global . getInitializer ( ) -> isZeroValue ( ) ? <STR_LIT> : <STR_LIT> ; } if ( ProcessingMapDef != SecName . startswith ( <STR_LIT> ) ) continue ; if ( SecName == <STR_LIT> && Global . hasPrivateLinkage ( ) && DataSecEntries . find ( std :: string ( SecName ) ) == DataSecEntries . end ( ) ) { SectionKind GVKind = TargetLoweringObjectFile :: getKindForGlobal ( & Global , Asm -> TM ) ; if ( ! GVKind . isMergeableCString ( ) && ! GVKind . isMergeableConst ( ) ) { DataSecEntries [ std :: string ( SecName ) ] = std :: make_unique < BTFKindDataSec > ( Asm , std :: string ( SecName ) ) ; } } SmallVector < DIGlobalVariableExpression * , <NUM_LIT> > GVs ; Global . getDebugInfo ( GVs ) ; if ( GVs . size ( ) == <NUM_LIT> ) continue ; uint32_t GVTypeId = <NUM_LIT> ; DIGlobalVariable * DIGlobal = nullptr ; for ( auto * GVE : GVs ) { DIGlobal = GVE -> getVariable ( ) ; if ( SecName . startswith ( <STR_LIT> ) ) visitMapDefType ( DIGlobal -> getType ( ) , GVTypeId ) ; else visitTypeEntry ( DIGlobal -> getType ( ) , GVTypeId , false , false ) ; break ; } auto Linkage = Global . getLinkage ( ) ; if ( Linkage != GlobalValue :: InternalLinkage && Linkage != GlobalValue :: ExternalLinkage && Linkage != GlobalValue :: WeakAnyLinkage && Linkage != GlobalValue :: WeakODRLinkage && Linkage != GlobalValue :: ExternalWeakLinkage ) continue ; uint32_t GVarInfo ;

if ( Linkage == GlobalValue :: InternalLinkage ) {


<s> if ( ( CTag == dwarf :: DW_TAG_structure_type || CTag == dwarf :: DW_TAG_union_type ) && ! CTy -> getName ( ) . empty ( ) && ! CTy -> isForwardDecl ( ) ) { auto TypeEntry = std :: make_unique < BTFTypeDerived > ( DTy , Tag , true ) ; auto & Fixup = FixupDerivedTypes [ CTy ] ; Fixup . push_back ( std :: make_pair ( DTy , TypeEntry . get ( ) ) ) ; TypeId = addType ( std :: move ( TypeEntry ) , DTy ) ; return ; } } } } if ( Tag == dwarf :: DW_TAG_pointer_type ) { int TmpTypeId = genBTFTypeTags ( DTy , - <NUM_LIT> ) ; if ( TmpTypeId >= <NUM_LIT> ) { auto TypeDEntry = std :: make_unique < BTFTypeDerived > ( TmpTypeId , Tag , DTy -> getName ( ) ) ; TypeId = addType ( std :: move ( TypeDEntry ) , DTy ) ; } else { auto TypeEntry = std :: make_unique < BTFTypeDerived > ( DTy , Tag , false ) ; TypeId = addType ( std :: move ( TypeEntry ) , DTy ) ; } } else if ( Tag == dwarf :: DW_TAG_typedef || Tag == dwarf :: DW_TAG_const_type || Tag == dwarf :: DW_TAG_volatile_type || Tag == dwarf :: DW_TAG_restrict_type ) { auto TypeEntry = std :: make_unique < BTFTypeDerived > ( DTy , Tag , false ) ; TypeId = addType ( std :: move ( TypeEntry ) , DTy ) ; if ( Tag == dwarf :: DW_TAG_typedef ) processDeclAnnotations ( DTy -> getAnnotations ( ) , TypeId , - <NUM_LIT> ) ; } else if ( Tag != dwarf :: DW_TAG_member ) { return ;


<s> auto TypeDEntry = std :: make_unique < BTFTypeDerived > ( TmpTypeId , Tag , DTy -> getName ( ) ) ; TypeId = addType ( std :: move ( TypeDEntry ) , DTy ) ; } else { auto TypeEntry = std :: make_unique < BTFTypeDerived > ( DTy , Tag , false ) ; TypeId = addType ( std :: move ( TypeEntry ) , DTy ) ; } } else if ( Tag == dwarf :: DW_TAG_typedef || Tag == dwarf :: DW_TAG_const_type || Tag == dwarf :: DW_TAG_volatile_type || Tag == dwarf :: DW_TAG_restrict_type ) { auto TypeEntry = std :: make_unique < BTFTypeDerived > ( DTy , Tag , false ) ; TypeId = addType ( std :: move ( TypeEntry ) , DTy ) ; if ( Tag == dwarf :: DW_TAG_typedef ) processDeclAnnotations ( DTy -> getAnnotations ( ) , TypeId , - <NUM_LIT> ) ; } else if ( Tag != dwarf :: DW_TAG_member ) { return ;


<s> void BTFDebug :: visitTypeEntry ( const DIType * Ty , uint32_t & TypeId , bool CheckPointer , bool SeenPointer ) { if ( ! Ty || DIToIdMap . find ( Ty ) != DIToIdMap . end ( ) ) { TypeId = DIToIdMap [ Ty ] ; if ( Ty && ( ! CheckPointer || ! SeenPointer ) ) { if ( const auto * DTy = dyn_cast < DIDerivedType > ( Ty ) ) { while ( DTy ) { const DIType * BaseTy = DTy -> getBaseType ( ) ; if ( ! BaseTy ) break ; if ( DIToIdMap . find ( BaseTy ) != DIToIdMap . end ( ) ) {

DTy = dyn_cast < DIDerivedType > ( BaseTy ) ;


<s> TypeId = DIToIdMap [ Ty ] ; if ( Ty && ( ! CheckPointer || ! SeenPointer ) ) { if ( const auto * DTy = dyn_cast < DIDerivedType > ( Ty ) ) { while ( DTy ) { const DIType * BaseTy = DTy -> getBaseType ( ) ; if ( ! BaseTy ) break ; if ( DIToIdMap . find ( BaseTy ) != DIToIdMap . end ( ) ) { DTy = dyn_cast < DIDerivedType > ( BaseTy ) ; } else {


<s> visitSubroutineType ( SP -> getType ( ) , false , FuncArgNames , ProtoTypeId ) ; uint8_t Scope = <STR_LIT> ; auto FuncTypeEntry = std :: make_unique < BTFTypeFunc > ( SP -> getName ( ) , ProtoTypeId , Scope ) ; uint32_t FuncId = addType ( std :: move ( FuncTypeEntry ) ) ; if ( F -> hasSection ( ) ) { StringRef SecName = F -> getSection ( ) ; if ( DataSecEntries . find ( std :: string ( SecName ) ) == DataSecEntries . end ( ) ) { DataSecEntries [ std :: string ( SecName ) ] = std :: make_unique < BTFKindDataSec > ( Asm , std :: string ( SecName ) ) ; } DataSecEntries [ std :: string ( SecName ) ] -> addDataSecEntry ( FuncId , Asm -> getSymbol ( F ) , <NUM_LIT> ) ;


<s> uint32_t ProtoTypeId ; const std :: unordered_map < uint32_t , StringRef > FuncArgNames ; visitSubroutineType ( SP -> getType ( ) , false , FuncArgNames , ProtoTypeId ) ; uint8_t Scope = <STR_LIT> ; auto FuncTypeEntry = std :: make_unique < BTFTypeFunc > ( SP -> getName ( ) , ProtoTypeId , Scope ) ; uint32_t FuncId = addType ( std :: move ( FuncTypeEntry ) ) ; if ( F -> hasSection ( ) ) { StringRef SecName = F -> getSection ( ) ; if ( DataSecEntries . find ( std :: string ( SecName ) ) == DataSecEntries . end ( ) ) { DataSecEntries [ std :: string ( SecName ) ] = std :: make_unique < BTFKindDataSec > ( Asm , std :: string ( SecName ) ) ; }

DataSecEntries [ std :: string ( SecName ) ] -> addDataSecEntry ( FuncId , Asm -> getSymbol ( F ) , <NUM_LIT> ) ;


<s> const Module * M = MMI -> getModule ( ) ; for ( const GlobalVariable & Global : M -> globals ( ) ) { StringRef SecName ; if ( Global . hasSection ( ) ) { SecName = Global . getSection ( ) ; } else if ( Global . hasInitializer ( ) ) { if ( Global . isConstant ( ) ) SecName = <STR_LIT> ; else SecName = Global . getInitializer ( ) -> isZeroValue ( ) ? <STR_LIT> : <STR_LIT> ; } if ( ProcessingMapDef != SecName . startswith ( <STR_LIT> ) ) continue ; if ( SecName == <STR_LIT> && Global . hasPrivateLinkage ( ) && DataSecEntries . find ( std :: string ( SecName ) ) == DataSecEntries . end ( ) ) { SectionKind GVKind = TargetLoweringObjectFile :: getKindForGlobal ( & Global , Asm -> TM ) ; if ( ! GVKind . isMergeableCString ( ) && ! GVKind . isMergeableConst ( ) ) { DataSecEntries [ std :: string ( SecName ) ] = std :: make_unique < BTFKindDataSec > ( Asm , std :: string ( SecName ) ) ; } } SmallVector < DIGlobalVariableExpression * , <NUM_LIT> > GVs ; Global . getDebugInfo ( GVs ) ; if ( GVs . size ( ) == <NUM_LIT> ) continue ; uint32_t GVTypeId = <NUM_LIT> ; for ( auto * GVE : GVs ) { if ( SecName . startswith ( <STR_LIT> ) ) visitMapDefType ( GVE -> getVariable ( ) -> getType ( ) , GVTypeId ) ; else visitTypeEntry ( GVE -> getVariable ( ) -> getType ( ) , GVTypeId , false , false ) ; break ; } auto Linkage = Global . getLinkage ( ) ; if ( Linkage != GlobalValue :: InternalLinkage && Linkage != GlobalValue :: ExternalLinkage && Linkage != GlobalValue :: WeakAnyLinkage && Linkage != GlobalValue :: WeakODRLinkage && Linkage != GlobalValue :: ExternalWeakLinkage ) continue ; uint32_t GVarInfo ; if ( Linkage == GlobalValue :: InternalLinkage ) { GVarInfo = <STR_LIT> ; } else if ( Global . hasInitializer ( ) ) {


<s> if ( CheckPointer && ! SeenPointer ) { SeenPointer = Tag == dwarf :: DW_TAG_pointer_type ; } if ( CheckPointer && SeenPointer ) { const DIType * Base = DTy -> getBaseType ( ) ; if ( Base ) { if ( const auto * CTy = dyn_cast < DICompositeType > ( Base ) ) { auto CTag = CTy -> getTag ( ) ; if ( ( CTag == dwarf :: DW_TAG_structure_type || CTag == dwarf :: DW_TAG_union_type ) && ! CTy -> getName ( ) . empty ( ) && ! CTy -> isForwardDecl ( ) ) { auto TypeEntry = std :: make_unique < BTFTypeDerived > ( DTy , Tag , true ) ; auto & Fixup = FixupDerivedTypes [ CTy -> getName ( ) ] ; Fixup . first = CTag == dwarf :: DW_TAG_union_type ; Fixup . second . push_back ( TypeEntry . get ( ) ) ; TypeId = addType ( std :: move ( TypeEntry ) , DTy ) ; return ; } } }


<s> OS . EmitIntValue ( FuncLen + LineLen , <NUM_LIT> ) ; OS . EmitIntValue ( FieldRelocLen , <NUM_LIT> ) ; OS . AddComment ( <STR_LIT> ) ; OS . EmitIntValue ( <STR_LIT> , <NUM_LIT> ) ; for ( const auto & FuncSec : FuncInfoTable ) { OS . AddComment ( <STR_LIT> + std :: to_string ( FuncSec . first ) ) ; OS . EmitIntValue ( FuncSec . first , <NUM_LIT> ) ; OS . EmitIntValue ( FuncSec . second . size ( ) , <NUM_LIT> ) ; for ( const auto & FuncInfo : FuncSec . second ) { Asm -> EmitLabelReference ( FuncInfo . Label , <NUM_LIT> ) ; OS . EmitIntValue ( FuncInfo . TypeId , <NUM_LIT> ) ; } } OS . AddComment ( <STR_LIT> ) ; OS . EmitIntValue ( <STR_LIT> , <NUM_LIT> ) ; for ( const auto & LineSec : LineInfoTable ) { OS . AddComment ( <STR_LIT> + std :: to_string ( LineSec . first ) ) ; OS . EmitIntValue ( LineSec . first , <NUM_LIT> ) ; OS . EmitIntValue ( LineSec . second . size ( ) , <NUM_LIT> ) ; for ( const auto & LineInfo : LineSec . second ) { Asm -> EmitLabelReference ( LineInfo . Label , <NUM_LIT> ) ; OS . EmitIntValue ( LineInfo . FileNameOff , <NUM_LIT> ) ; OS . EmitIntValue ( LineInfo . LineOff , <NUM_LIT> ) ; OS . AddComment ( <STR_LIT> + std :: to_string ( LineInfo . LineNum ) + <STR_LIT> + std :: to_string ( LineInfo . ColumnNum ) ) ; OS . EmitIntValue ( LineInfo . LineNum << <NUM_LIT> | LineInfo . ColumnNum , <NUM_LIT> ) ; } } if ( FieldRelocLen ) { OS . AddComment ( <STR_LIT> ) ; OS . EmitIntValue ( <STR_LIT> , <NUM_LIT> ) ; for ( const auto & FieldRelocSec : FieldRelocTable ) { OS . AddComment ( <STR_LIT> + std :: to_string ( FieldRelocSec . first ) ) ; OS . EmitIntValue ( FieldRelocSec . first , <NUM_LIT> ) ; OS . EmitIntValue ( FieldRelocSec . second . size ( ) , <NUM_LIT> ) ; for ( const auto & FieldRelocInfo : FieldRelocSec . second ) { Asm -> EmitLabelReference ( FieldRelocInfo . Label , <NUM_LIT> ) ; OS . EmitIntValue ( FieldRelocInfo . TypeID , <NUM_LIT> ) ;

OS . EmitIntValue ( FieldRelocInfo . OffsetNameOff , <NUM_LIT> ) ;


<s> StructTypeId = StructType -> getId ( ) ; break ; } } if ( StructTypeId == <NUM_LIT> ) { auto FwdTypeEntry = std :: make_unique < BTFTypeFwd > ( TypeName , IsUnion ) ; StructTypeId = addType ( std :: move ( FwdTypeEntry ) ) ; }

for ( auto & DType : Fixup . second . second ) {


<s> auto * GVar = dyn_cast < GlobalVariable > ( GVal ) ; if ( GVar && GVar -> hasAttribute ( <STR_LIT> ) ) { uint32_t Imm = PatchImms [ GVar -> getName ( ) . str ( ) ] ; OutMI . setOpcode ( <STR_LIT> ) ; OutMI . addOperand ( MCOperand :: createReg ( MI -> getOperand ( <NUM_LIT> ) . getReg ( ) ) ) ; OutMI . addOperand ( MCOperand :: createImm ( Imm ) ) ; return true ;


<s> if ( GVar && GVar -> hasAttribute ( <STR_LIT> ) ) { uint32_t Imm = PatchImms [ GVar -> getName ( ) . str ( ) ] ; OutMI . setOpcode ( <STR_LIT> ) ; OutMI . addOperand ( MCOperand :: createReg ( MI -> getOperand ( <NUM_LIT> ) . getReg ( ) ) ) ; OutMI . addOperand ( MCOperand :: createImm ( Imm ) ) ; return true ; } } } return false ;


<s> const Module * M = MMI -> getModule ( ) ; for ( const Function & F : M -> functions ( ) ) { const DISubprogram * SP = F . getSubprogram ( ) ; if ( ! SP || SP -> isDefinition ( ) ) continue ; uint32_t ProtoTypeId ;

const std :: unordered_map < uint32_t , StringRef > FuncArgNames ;


<s> const Module * M = MMI -> getModule ( ) ; for ( const Function & F : M -> functions ( ) ) { const DISubprogram * SP = F . getSubprogram ( ) ; if ( ! SP || SP -> isDefinition ( ) ) continue ; uint32_t ProtoTypeId ; const std :: unordered_map < uint32_t , StringRef > FuncArgNames ; visitSubroutineType ( SP -> getType ( ) , false , FuncArgNames , ProtoTypeId ) ; auto VarEntry = std :: make_unique < BTFKindVar > ( SP -> getName ( ) , ProtoTypeId , <STR_LIT> ) ; uint32_t VarId = addType ( std :: move ( VarEntry ) ) ;

StringRef SecName = F . getSection ( ) ;


<s> SecName = Global . getSection ( ) ; } else if ( Global . hasInitializer ( ) ) { if ( Global . isConstant ( ) ) SecName = <STR_LIT> ; else SecName = Global . getInitializer ( ) -> isZeroValue ( ) ? <STR_LIT> : <STR_LIT> ; } else { SecName = <STR_LIT> ; } if ( ProcessingMapDef != SecName . startswith ( <STR_LIT> ) ) continue ; SmallVector < DIGlobalVariableExpression * , <NUM_LIT> > GVs ; Global . getDebugInfo ( GVs ) ; if ( GVs . size ( ) == <NUM_LIT> ) continue ; uint32_t GVTypeId = <NUM_LIT> ; for ( auto * GVE : GVs ) { if ( SecName . startswith ( <STR_LIT> ) ) visitMapDefType ( GVE -> getVariable ( ) -> getType ( ) , GVTypeId ) ; else visitTypeEntry ( GVE -> getVariable ( ) -> getType ( ) , GVTypeId , false , false ) ; break ; } auto Linkage = Global . getLinkage ( ) ; if ( Linkage != GlobalValue :: InternalLinkage && Linkage != GlobalValue :: ExternalLinkage && Linkage != GlobalValue :: WeakAnyLinkage && Linkage != GlobalValue :: ExternalWeakLinkage ) continue ; uint32_t GVarInfo ; if ( Linkage == GlobalValue :: InternalLinkage ) {


<s> if ( MI -> getOpcode ( ) == <STR_LIT> ) { processReloc ( MI -> getOperand ( <NUM_LIT> ) ) ; } else if ( MI -> getOpcode ( ) == <STR_LIT> || MI -> getOpcode ( ) == <STR_LIT> || MI -> getOpcode ( ) == <STR_LIT> ) { processReloc ( MI -> getOperand ( <NUM_LIT> ) ) ; } 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 ( ) , <NUM_LIT> ) ; LineInfoGenerated = true ; } return ; }

MCSymbol * LineSym = OS . getContext ( ) . createTempSymbol ( ) ;


<s> FieldReloc . Label = ORSym ; FieldReloc . OffsetNameOff = addString ( IndexPattern ) ; FieldReloc . TypeID = RootId ; FieldReloc . RelocKind = std :: stoull ( RelocKindStr ) ; PatchImms [ AccessPattern . str ( ) ] = std :: stoul ( PatchImmStr ) ;


<s> size_t SecondColon = AccessPattern . find_first_of ( ':' , FirstColon + <NUM_LIT> ) ; StringRef IndexPattern = AccessPattern . substr ( FirstDollar + <NUM_LIT> ) ; StringRef RelocKindStr = AccessPattern . substr ( FirstColon + <NUM_LIT> , SecondColon - FirstColon ) ; StringRef PatchImmStr = AccessPattern . substr ( SecondColon + <NUM_LIT> , FirstDollar - SecondColon ) ; BTFFieldReloc FieldReloc ; FieldReloc . Label = ORSym ; FieldReloc . OffsetNameOff = addString ( IndexPattern ) ;


<s> const MachineOperand & MO = MI -> getOperand ( <NUM_LIT> ) ; if ( MO . isGlobal ( ) ) { const GlobalValue * GVal = MO . getGlobal ( ) ; auto * GVar = dyn_cast < GlobalVariable > ( GVal ) ; if ( GVar && GVar -> hasAttribute ( <STR_LIT> ) ) { uint32_t Imm = PatchImms [ GVar -> getName ( ) . str ( ) ] ; OutMI . setOpcode ( <STR_LIT> ) ; OutMI . addOperand ( MCOperand :: createReg ( MI -> getOperand ( <NUM_LIT> ) . getReg ( ) ) ) ; OutMI . addOperand ( MCOperand :: createImm ( Imm ) ) ; return true ;


<s> auto * GVar = dyn_cast < GlobalVariable > ( GVal ) ; if ( GVar && GVar -> hasAttribute ( <STR_LIT> ) ) { MCSymbol * ORSym = OS . getContext ( ) . createTempSymbol ( ) ; OS . EmitLabel ( ORSym ) ; MDNode * MDN = GVar -> getMetadata ( LLVMContext :: MD_preserve_access_index ) ; DIType * Ty = dyn_cast < DIType > ( MDN ) ; generateFieldReloc ( ORSym , Ty , GVar -> getName ( ) ) ; } }


<s> size_t FirstDollar = AccessPattern . find_first_of ( '$' ) ; size_t FirstColon = AccessPattern . find_first_of ( ':' ) ; size_t SecondColon = AccessPattern . find_first_of ( ':' , FirstColon + <NUM_LIT> ) ; StringRef IndexPattern = AccessPattern . substr ( FirstDollar + <NUM_LIT> ) ; StringRef RelocKindStr = AccessPattern . substr ( FirstColon + <NUM_LIT> , SecondColon - FirstColon ) ;

StringRef PatchImmStr = AccessPattern . substr ( SecondColon + <NUM_LIT> , FirstDollar - SecondColon ) ;


<s> const GlobalValue * GVal = MO . getGlobal ( ) ; auto * GVar = dyn_cast < GlobalVariable > ( GVal ) ; if ( GVar && GVar -> hasAttribute ( <STR_LIT> ) ) {

MCSymbol * ORSym = OS . getContext ( ) . createTempSymbol ( ) ;


<s> const GlobalValue * GVal = MO . getGlobal ( ) ; auto * GVar = dyn_cast < GlobalVariable > ( GVal ) ; if ( GVar && GVar -> hasAttribute ( <STR_LIT> ) ) { MCSymbol * ORSym = OS . getContext ( ) . createTempSymbol ( ) ; OS . emitLabel ( ORSym ) ;

MDNode * MDN = GVar -> getMetadata ( LLVMContext :: MD_preserve_access_index ) ;


<s> 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 ( ) ;


<s> for ( ; MI -> getOperand ( NumDefs ) . isReg ( ) && MI -> getOperand ( NumDefs ) . isDef ( ) ; ++ NumDefs ) ; const char * AsmStr = MI -> getOperand ( NumDefs ) . getSymbolName ( ) ; if ( AsmStr [ <NUM_LIT> ] == <NUM_LIT> ) return ; } if ( MI -> getOpcode ( ) == <STR_LIT> ) { processReloc ( MI -> getOperand ( <NUM_LIT> ) ) ; } else if ( MI -> getOpcode ( ) == <STR_LIT> || MI -> getOpcode ( ) == <STR_LIT> || MI -> getOpcode ( ) == <STR_LIT> ) { processReloc ( MI -> getOperand ( <NUM_LIT> ) ) ; } else if ( MI -> getOpcode ( ) == <STR_LIT> ) { const MachineOperand & MO = MI -> getOperand ( <NUM_LIT> ) ; 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 ( ) , <NUM_LIT> ) ;


<s> if ( Arg ) { visitTypeEntry ( DV -> getType ( ) ) ; FuncArgNames [ Arg ] = DV -> getName ( ) ; } } } uint32_t ProtoTypeId ; visitSubroutineType ( SP -> getType ( ) , true , FuncArgNames , ProtoTypeId ) ; uint8_t Scope = SP -> isLocalToUnit ( ) ? <STR_LIT> : <STR_LIT> ; 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 - <NUM_LIT> ) ; } } processAnnotations ( SP -> getAnnotations ( ) , FuncTypeId , - <NUM_LIT> ) ; for ( const auto & TypeEntry : TypeEntries ) TypeEntry -> completeType ( * this ) ; MCSymbol * FuncLabel = Asm -> getFunctionBegin ( ) ; BTFFuncInfo FuncInfo ; FuncInfo . Label = FuncLabel ; FuncInfo . TypeId = FuncTypeId ;


<s> FuncArgNames [ Arg ] = DV -> getName ( ) ; } } } uint32_t ProtoTypeId ; visitSubroutineType ( SP -> getType ( ) , true , FuncArgNames , ProtoTypeId ) ; uint8_t Scope = SP -> isLocalToUnit ( ) ? <STR_LIT> : <STR_LIT> ; 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 - <NUM_LIT> ) ; } }

processAnnotations ( SP -> getAnnotations ( ) , FuncTypeId , - <NUM_LIT> ) ;


<s> BTFType . Info = ( ( ComponentId < <NUM_LIT> ) << <NUM_LIT> ) | ( Kind << <NUM_LIT> ) ; BTFType . Type = BaseTypeId ; Info = ComponentId < <NUM_LIT> ? <NUM_LIT> : ComponentId ;


<s> Kind = <STR_LIT> ; BTFType . Info = ( ( ComponentId < <NUM_LIT> ) << <NUM_LIT> ) | ( Kind << <NUM_LIT> ) ; BTFType . Type = BaseTypeId ;

Info = ComponentId < <NUM_LIT> ? <NUM_LIT> : ComponentId ;


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


<s> BTFType . NameOff = BDebug . addString ( Tag ) ;


<s> const MDNode * MD = cast < MDNode > ( Annotation ) ; const MDString * Name = cast < MDString > ( MD -> getOperand ( <NUM_LIT> ) ) ; if ( ! Name -> getString ( ) . equals ( <STR_LIT> ) ) continue ;

const MDString * Value = cast < MDString > ( MD -> getOperand ( <NUM_LIT> ) ) ;


<s> uint8_t Scope = <STR_LIT> ; auto FuncTypeEntry = std :: make_unique < BTFTypeFunc > ( SP -> getName ( ) , ProtoTypeId , Scope ) ; uint32_t FuncId = addType ( std :: move ( FuncTypeEntry ) ) ; processAnnotations ( SP -> getAnnotations ( ) , FuncId , - <NUM_LIT> ) ; if ( F -> hasSection ( ) ) { StringRef SecName = F -> getSection ( ) ; if ( DataSecEntries . find ( std :: string ( SecName ) ) == DataSecEntries . end ( ) ) { DataSecEntries [ std :: string ( SecName ) ] = std :: make_unique < BTFKindDataSec > ( Asm , std :: string ( SecName ) ) ; }


<s> if ( ! SP || SP -> isDefinition ( ) ) return ; if ( ProtoFunctions . find ( F ) != ProtoFunctions . end ( ) ) return ; ProtoFunctions . insert ( F ) ; uint32_t ProtoTypeId ; const std :: unordered_map < uint32_t , StringRef > FuncArgNames ; visitSubroutineType ( SP -> getType ( ) , false , FuncArgNames , ProtoTypeId ) ; uint8_t Scope = <STR_LIT> ; auto FuncTypeEntry = std :: make_unique < BTFTypeFunc > ( SP -> getName ( ) , ProtoTypeId , Scope ) ; uint32_t FuncId = addType ( std :: move ( FuncTypeEntry ) ) ; processAnnotations ( SP -> getAnnotations ( ) , FuncId , - <NUM_LIT> ) ; if ( F -> hasSection ( ) ) { StringRef SecName = F -> getSection ( ) ; if ( DataSecEntries . find ( std :: string ( SecName ) ) == DataSecEntries . end ( ) ) { DataSecEntries [ std :: string ( SecName ) ] = std :: make_unique < BTFKindDataSec > ( Asm , std :: string ( SecName ) ) ;


<s> if ( SecName == <STR_LIT> && Global . hasPrivateLinkage ( ) && DataSecEntries . find ( std :: string ( SecName ) ) == DataSecEntries . end ( ) ) { SectionKind GVKind = TargetLoweringObjectFile :: getKindForGlobal ( & Global , Asm -> TM ) ; if ( ! GVKind . isMergeableCString ( ) && ! GVKind . isMergeableConst ( ) ) { DataSecEntries [ std :: string ( SecName ) ] = std :: make_unique < BTFKindDataSec > ( Asm , std :: string ( SecName ) ) ; } } SmallVector < DIGlobalVariableExpression * , <NUM_LIT> > GVs ; Global . getDebugInfo ( GVs ) ; if ( GVs . size ( ) == <NUM_LIT> ) continue ; uint32_t GVTypeId = <NUM_LIT> ; DIGlobalVariable * DIGlobal = nullptr ; for ( auto * GVE : GVs ) { DIGlobal = GVE -> getVariable ( ) ; if ( SecName . startswith ( <STR_LIT> ) ) visitMapDefType ( DIGlobal -> getType ( ) , GVTypeId ) ; else visitTypeEntry ( DIGlobal -> getType ( ) , GVTypeId , false , false ) ; break ; } auto Linkage = Global . getLinkage ( ) ; if ( Linkage != GlobalValue :: InternalLinkage && Linkage != GlobalValue :: ExternalLinkage && Linkage != GlobalValue :: WeakAnyLinkage && Linkage != GlobalValue :: WeakODRLinkage && Linkage != GlobalValue :: ExternalWeakLinkage ) continue ; uint32_t GVarInfo ; if ( Linkage == GlobalValue :: InternalLinkage ) { GVarInfo = <STR_LIT> ; } else if ( Global . hasInitializer ( ) ) { GVarInfo = <STR_LIT> ; } else { GVarInfo = <STR_LIT> ; } auto VarEntry = std :: make_unique < BTFKindVar > ( Global . getName ( ) , GVTypeId , GVarInfo ) ; uint32_t VarId = addType ( std :: move ( VarEntry ) ) ; processAnnotations ( DIGlobal -> getAnnotations ( ) , VarId , - <NUM_LIT> ) ; if ( SecName . empty ( ) ) continue ; if ( DataSecEntries . find ( std :: string ( SecName ) ) == DataSecEntries . end ( ) ) { DataSecEntries [ std :: string ( SecName ) ] = std :: make_unique < BTFKindDataSec > ( Asm , std :: string ( SecName ) ) ; } const DataLayout & DL = Global . getParent ( ) -> getDataLayout ( ) ; uint32_t Size = DL . getTypeAllocSize ( Global . getType ( ) -> getElementType ( ) ) ; DataSecEntries [ std :: string ( SecName ) ] -> addDataSecEntry ( VarId , Asm -> getSymbol ( & Global ) , Size ) ; }


<s> uint32_t Offset = Size ; OffsetToIdMap [ Offset ] = Table . size ( ) ;

Table . push_back ( std :: string ( S ) ) ;


<s> OffsetToIdMap [ Offset ] = Table . size ( ) ; Table . push_back ( std :: string ( S ) ) ; Size += S . size ( ) + <NUM_LIT> ;


<s> TypeEntry -> setId ( TypeEntries . size ( ) + <NUM_LIT> ) ; uint32_t Id = TypeEntry -> getId ( ) ; DIToIdMap [ Ty ] = Id ; TypeEntries . push_back ( std :: move ( TypeEntry ) ) ; return Id ;


<s> Vars . push_back ( std :: make_tuple ( Id , Sym , Size ) ) ;


<s> uint32_t ProtoTypeId ; visitSubroutineType ( SP -> getType ( ) , true , FuncArgNames , ProtoTypeId ) ; uint8_t Scope = SP -> isLocalToUnit ( ) ? <STR_LIT> : <STR_LIT> ; 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 - <NUM_LIT> ) ; } } processDeclAnnotations ( SP -> getAnnotations ( ) , FuncTypeId , - <NUM_LIT> ) ; for ( const auto & TypeEntry : TypeEntries ) TypeEntry -> completeType ( * this ) ; MCSymbol * FuncLabel = Asm -> getFunctionBegin ( ) ; BTFFuncInfo FuncInfo ;


<s> 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 ( ) ? <STR_LIT> : <STR_LIT> ; 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 - <NUM_LIT> ) ; } } processDeclAnnotations ( SP -> getAnnotations ( ) , FuncTypeId , - <NUM_LIT> ) ; 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 ( ) ;


<s> for ( ; MI -> getOperand ( NumDefs ) . isReg ( ) && MI -> getOperand ( NumDefs ) . isDef ( ) ; ++ NumDefs ) ; const char * AsmStr = MI -> getOperand ( NumDefs ) . getSymbolName ( ) ; if ( AsmStr [ <NUM_LIT> ] == <NUM_LIT> ) return ; } if ( MI -> getOpcode ( ) == <STR_LIT> ) { processGlobalValue ( MI -> getOperand ( <NUM_LIT> ) ) ; } else if ( MI -> getOpcode ( ) == <STR_LIT> || MI -> getOpcode ( ) == <STR_LIT> || MI -> getOpcode ( ) == <STR_LIT> ) { processGlobalValue ( MI -> getOperand ( <NUM_LIT> ) ) ; } else if ( MI -> getOpcode ( ) == <STR_LIT> ) { const MachineOperand & MO = MI -> getOperand ( <NUM_LIT> ) ; 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 ( ) , <NUM_LIT> ) ; LineInfoGenerated = true ; } return ; } MCSymbol * LineSym = OS . getContext ( ) . createTempSymbol ( ) ; OS . emitLabel ( LineSym ) ; auto SP = DL . get ( ) -> getScope ( ) -> getSubprogram ( ) ;

constructLineInfo ( SP , LineSym , DL . getLine ( ) , DL . getCol ( ) ) ;


<s> BTFDebug :: BTFDebug ( AsmPrinter * AP ) : DebugHandlerBase ( AP ) , OS ( * Asm -> OutStreamer ) , SkipInstruction ( false ) , LineInfoGenerated ( false ) , SecNameOff ( <NUM_LIT> ) , ArrayIndexTypeId ( <NUM_LIT> ) , MapDefNotCollected ( true ) {


<s> BTFKindDataSec :: BTFKindDataSec ( AsmPrinter * AsmPrt , std :: string SecName ) : Asm ( AsmPrt ) , Name ( SecName ) { Kind = <STR_LIT> ;


<s> <STR_LIT> ( StringRef VarName , uint32_t TypeId , uint32_t VarInfo ) : Name ( VarName ) { Kind = <STR_LIT> ; BTFType . Info = Kind << <NUM_LIT> ; BTFType . Type = TypeId ;


<s> BTFTypeArray :: BTFTypeArray ( uint32_t ElemTypeId , uint32_t NumElems ) { Kind = <STR_LIT> ; BTFType . NameOff = <NUM_LIT> ; BTFType . Info = Kind << <NUM_LIT> ; BTFType . Size = <NUM_LIT> ;


<s> BTFTypeDeclTag :: BTFTypeDeclTag ( uint32_t BaseTypeId , int ComponentIdx , StringRef Tag ) : Tag ( Tag ) { Kind = <STR_LIT> ; BTFType . Info = Kind << <NUM_LIT> ; BTFType . Type = BaseTypeId ;


<s> <STR_LIT> ( uint32_t SizeInBits , StringRef TypeName ) : Name ( TypeName ) { Kind = <STR_LIT> ; BTFType . Info = Kind << <NUM_LIT> ;

BTFType . Size = roundupToBytes ( SizeInBits ) ;


<s> void BTFTypeDeclTag :: completeType ( BTFDebug & BDebug ) { if ( IsCompleted ) return ; IsCompleted = true ;

BTFType . NameOff = BDebug . addString ( Tag ) ;


<s> if ( FieldRelocLen ) FieldRelocLen += <NUM_LIT> ; OS . emitInt32 ( <NUM_LIT> ) ; OS . emitInt32 ( FuncLen ) ; OS . emitInt32 ( FuncLen ) ; OS . emitInt32 ( LineLen ) ; OS . emitInt32 ( FuncLen + LineLen ) ; OS . emitInt32 ( FieldRelocLen ) ; OS . AddComment ( <STR_LIT> ) ; OS . emitInt32 ( <STR_LIT> ) ; for ( const auto & FuncSec : FuncInfoTable ) { OS . AddComment ( <STR_LIT> + std :: to_string ( FuncSec . first ) ) ; OS . emitInt32 ( FuncSec . first ) ; OS . emitInt32 ( FuncSec . second . size ( ) ) ; for ( const auto & FuncInfo : FuncSec . second ) { Asm -> emitLabelReference ( FuncInfo . Label , <NUM_LIT> ) ; OS . emitInt32 ( FuncInfo . TypeId ) ; } } OS . AddComment ( <STR_LIT> ) ; OS . emitInt32 ( <STR_LIT> ) ; for ( const auto & LineSec : LineInfoTable ) { OS . AddComment ( <STR_LIT> + std :: to_string ( LineSec . first ) ) ; OS . emitInt32 ( LineSec . first ) ; OS . emitInt32 ( LineSec . second . size ( ) ) ; for ( const auto & LineInfo : LineSec . second ) { Asm -> emitLabelReference ( LineInfo . Label , <NUM_LIT> ) ; OS . emitInt32 ( LineInfo . FileNameOff ) ; OS . emitInt32 ( LineInfo . LineOff ) ; OS . AddComment ( <STR_LIT> + std :: to_string ( LineInfo . LineNum ) + <STR_LIT> + std :: to_string ( LineInfo . ColumnNum ) ) ; OS . emitInt32 ( LineInfo . LineNum << <NUM_LIT> | LineInfo . ColumnNum ) ; } } if ( FieldRelocLen ) { OS . AddComment ( <STR_LIT> ) ; OS . emitInt32 ( <STR_LIT> ) ; for ( const auto & FieldRelocSec : FieldRelocTable ) { OS . AddComment ( <STR_LIT> + std :: to_string ( FieldRelocSec . first ) ) ; OS . emitInt32 ( FieldRelocSec . first ) ; OS . emitInt32 ( FieldRelocSec . second . size ( ) ) ;

for ( const auto & FieldRelocInfo : FieldRelocSec . second ) {


<s> emitCommonHeader ( ) ; OS . emitInt32 ( <STR_LIT> ) ; uint32_t TypeLen = <NUM_LIT> , StrLen ; for ( const auto & TypeEntry : TypeEntries ) TypeLen += TypeEntry -> getSize ( ) ; StrLen = StringTable . getSize ( ) ; OS . emitInt32 ( <NUM_LIT> ) ; OS . emitInt32 ( TypeLen ) ; OS . emitInt32 ( TypeLen ) ; OS . emitInt32 ( StrLen ) ; for ( const auto & TypeEntry : TypeEntries ) TypeEntry -> emitType ( OS ) ; uint32_t StringOffset = <NUM_LIT> ; for ( const auto & S : StringTable . getTable ( ) ) { OS . AddComment ( <STR_LIT> + std :: to_string ( StringOffset ) ) ; OS . emitBytes ( S ) ; OS . emitBytes ( StringRef ( <STR_LIT> , <NUM_LIT> ) ) ;

StringOffset += S . size ( ) + <NUM_LIT> ;


<s> void BTFDebug :: emitBTFSection ( ) { if ( ! TypeEntries . size ( ) && StringTable . getSize ( ) == <NUM_LIT> ) return ; MCContext & Ctx = OS . getContext ( ) ; MCSectionELF * Sec = Ctx . getELFSection ( <STR_LIT> , ELF :: SHT_PROGBITS , <NUM_LIT> ) ; Sec -> setAlignment ( Align ( <NUM_LIT> ) ) ; OS . SwitchSection ( Sec ) ; emitCommonHeader ( ) ; OS . emitInt32 ( <STR_LIT> ) ; uint32_t TypeLen = <NUM_LIT> , StrLen ; for ( const auto & TypeEntry : TypeEntries ) TypeLen += TypeEntry -> getSize ( ) ; StrLen = StringTable . getSize ( ) ;


<s> OS . AddComment ( <STR_LIT> + Twine :: utohexstr ( <STR_LIT> ) ) ; OS . emitIntValue ( <STR_LIT> , <NUM_LIT> ) ; OS . emitInt8 ( <STR_LIT> ) ; OS . emitInt8 ( <NUM_LIT> ) ;


<s> OS . emitIntValue ( <STR_LIT> , <NUM_LIT> ) ; OS . emitInt8 ( <STR_LIT> ) ; OS . emitInt8 ( <NUM_LIT> ) ;


<s> <STR_LIT> ( OS ) ; OS . emitInt32 ( Info ) ;


<s> 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 = <NUM_LIT> ; for ( const auto & StructType : StructTypes ) { if ( StructType -> getName ( ) == TypeName ) { StructTypeId = StructType -> getId ( ) ; break ; } } if ( StructTypeId == <NUM_LIT> ) { 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 ) ;


<s> 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 = <NUM_LIT> ; for ( const auto & StructType : StructTypes ) { if ( StructType -> getName ( ) == TypeName ) { StructTypeId = StructType -> getId ( ) ; break ; } } if ( StructTypeId == <NUM_LIT> ) { 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 ) ;


<s> FieldReloc . RelocKind = std :: stoull ( std :: string ( RelocKindStr ) ) ; PatchImms [ GVar ] = std :: make_pair ( std :: stoll ( std :: string ( PatchImmStr ) ) , FieldReloc . RelocKind ) ; } else { StringRef RelocStr = AccessPattern . substr ( FirstDollar + <NUM_LIT> ) ; FieldReloc . OffsetNameOff = addString ( <STR_LIT> ) ; FieldReloc . RelocKind = std :: stoull ( std :: string ( RelocStr ) ) ; PatchImms [ GVar ] = std :: make_pair ( RootId , FieldReloc . RelocKind ) ; }

FieldRelocTable [ SecNameOff ] . push_back ( FieldReloc ) ;


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


<s> if ( GVar && GVar -> hasAttribute ( <STR_LIT> ) ) { uint32_t Imm = PatchImms [ GVar ] . first ; OutMI . setOpcode ( MI -> getOperand ( <NUM_LIT> ) . getImm ( ) ) ; if ( MI -> getOperand ( <NUM_LIT> ) . isImm ( ) ) OutMI . addOperand ( MCOperand :: createImm ( MI -> getOperand ( <NUM_LIT> ) . getImm ( ) ) ) ; else OutMI . addOperand ( MCOperand :: createReg ( MI -> getOperand ( <NUM_LIT> ) . getReg ( ) ) ) ; OutMI . addOperand ( MCOperand :: createReg ( MI -> getOperand ( <NUM_LIT> ) . getReg ( ) ) ) ; OutMI . addOperand ( MCOperand :: createImm ( Imm ) ) ; return true ; } }


<s> if ( ! File -> getFilename ( ) . startswith ( <STR_LIT> ) && File -> getDirectory ( ) . size ( ) ) FileName = File -> getDirectory ( ) . str ( ) + <STR_LIT> + File -> getFilename ( ) . str ( ) ; else FileName = std :: string ( File -> getFilename ( ) ) ;

if ( FileContent . find ( FileName ) != FileContent . end ( ) ) return FileName ;


<s> unsigned Id ; visitTypeEntry ( Ty , Id , false , false ) ;


visitTypeEntry ( Ty , Id , false , false ) ;


<s> for ( const Metadata * Annotation : Annotations -> operands ( ) ) { const MDNode * MD = cast < MDNode > ( Annotation ) ; const MDString * Name = cast < MDString > ( MD -> getOperand ( <NUM_LIT> ) ) ; if ( ! Name -> getString ( ) . equals ( <STR_LIT> ) ) continue ; const MDString * Value = cast < MDString > ( MD -> getOperand ( <NUM_LIT> ) ) ; auto TypeEntry = std :: make_unique < BTFTypeDeclTag > ( BaseTypeId , ComponentIdx , Value -> getString ( ) ) ; addType ( std :: move ( TypeEntry ) ) ;


<s> void BTFDebug :: processDeclAnnotations ( DINodeArray Annotations , uint32_t BaseTypeId , int ComponentIdx ) { if ( ! Annotations ) return ; for ( const Metadata * Annotation : Annotations -> operands ( ) ) { const MDNode * MD = cast < MDNode > ( Annotation ) ; const MDString * Name = cast < MDString > ( MD -> getOperand ( <NUM_LIT> ) ) ; if ( ! Name -> getString ( ) . equals ( <STR_LIT> ) ) continue ;


<s> const DISubprogram * SP = F -> getSubprogram ( ) ; if ( ! SP || SP -> isDefinition ( ) ) return ; if ( ProtoFunctions . find ( F ) != ProtoFunctions . end ( ) ) return ; ProtoFunctions . insert ( F ) ; uint32_t ProtoTypeId ; const std :: unordered_map < uint32_t , StringRef > FuncArgNames ; visitSubroutineType ( SP -> getType ( ) , false , FuncArgNames , ProtoTypeId ) ; uint8_t Scope = <STR_LIT> ; auto FuncTypeEntry = std :: make_unique < BTFTypeFunc > ( SP -> getName ( ) , ProtoTypeId , Scope ) ; uint32_t FuncId = addType ( std :: move ( FuncTypeEntry ) ) ;

processDeclAnnotations ( SP -> getAnnotations ( ) , FuncId , - <NUM_LIT> ) ;


<s> SectionKind GVKind = TargetLoweringObjectFile :: getKindForGlobal ( & Global , Asm -> TM ) ; if ( ! GVKind . isMergeableCString ( ) && ! GVKind . isMergeableConst ( ) ) { DataSecEntries [ std :: string ( SecName ) ] = std :: make_unique < BTFKindDataSec > ( Asm , std :: string ( SecName ) ) ; } } SmallVector < DIGlobalVariableExpression * , <NUM_LIT> > GVs ; Global . getDebugInfo ( GVs ) ; if ( GVs . size ( ) == <NUM_LIT> ) continue ; uint32_t GVTypeId = <NUM_LIT> ; DIGlobalVariable * DIGlobal = nullptr ; for ( auto * GVE : GVs ) { DIGlobal = GVE -> getVariable ( ) ; if ( SecName . startswith ( <STR_LIT> ) ) visitMapDefType ( DIGlobal -> getType ( ) , GVTypeId ) ; else visitTypeEntry ( DIGlobal -> getType ( ) , GVTypeId , false , false ) ; break ; } auto Linkage = Global . getLinkage ( ) ; if ( Linkage != GlobalValue :: InternalLinkage && Linkage != GlobalValue :: ExternalLinkage && Linkage != GlobalValue :: WeakAnyLinkage && Linkage != GlobalValue :: WeakODRLinkage && Linkage != GlobalValue :: ExternalWeakLinkage ) continue ; uint32_t GVarInfo ; if ( Linkage == GlobalValue :: InternalLinkage ) { GVarInfo = <STR_LIT> ; } else if ( Global . hasInitializer ( ) ) { GVarInfo = <STR_LIT> ; } else { GVarInfo = <STR_LIT> ; } auto VarEntry = std :: make_unique < BTFKindVar > ( Global . getName ( ) , GVTypeId , GVarInfo ) ; uint32_t VarId = addType ( std :: move ( VarEntry ) ) ; processDeclAnnotations ( DIGlobal -> getAnnotations ( ) , VarId , - <NUM_LIT> ) ; if ( SecName . empty ( ) ) continue ; if ( DataSecEntries . find ( std :: string ( SecName ) ) == DataSecEntries . end ( ) ) { DataSecEntries [ std :: string ( SecName ) ] = std :: make_unique < BTFKindDataSec > ( Asm , std :: string ( SecName ) ) ; } const DataLayout & DL = Global . getParent ( ) -> getDataLayout ( ) ; uint32_t Size = DL . getTypeAllocSize ( Global . getType ( ) -> getElementType ( ) ) ; DataSecEntries [ std :: string ( SecName ) ] -> addDataSecEntry ( VarId , Asm -> getSymbol ( & Global ) , Size ) ;


<s> DataSecEntries [ std :: string ( SecName ) ] = std :: make_unique < BTFKindDataSec > ( Asm , std :: string ( SecName ) ) ; } } SmallVector < DIGlobalVariableExpression * , <NUM_LIT> > GVs ; Global . getDebugInfo ( GVs ) ; if ( GVs . size ( ) == <NUM_LIT> ) continue ; uint32_t GVTypeId = <NUM_LIT> ; DIGlobalVariable * DIGlobal = nullptr ; for ( auto * GVE : GVs ) { DIGlobal = GVE -> getVariable ( ) ; if ( SecName . startswith ( <STR_LIT> ) ) visitMapDefType ( DIGlobal -> getType ( ) , GVTypeId ) ; else visitTypeEntry ( DIGlobal -> getType ( ) , GVTypeId , false , false ) ; break ; } auto Linkage = Global . getLinkage ( ) ; if ( Linkage != GlobalValue :: InternalLinkage && Linkage != GlobalValue :: ExternalLinkage && Linkage != GlobalValue :: WeakAnyLinkage && Linkage != GlobalValue :: WeakODRLinkage && Linkage != GlobalValue :: ExternalWeakLinkage ) continue ; uint32_t GVarInfo ; if ( Linkage == GlobalValue :: InternalLinkage ) { GVarInfo = <STR_LIT> ; } else if ( Global . hasInitializer ( ) ) { GVarInfo = <STR_LIT> ; } else { GVarInfo = <STR_LIT> ; } auto VarEntry = std :: make_unique < BTFKindVar > ( Global . getName ( ) , GVTypeId , GVarInfo ) ; uint32_t VarId = addType ( std :: move ( VarEntry ) ) ; processDeclAnnotations ( DIGlobal -> getAnnotations ( ) , VarId , - <NUM_LIT> ) ;


<s> void BTFDebug :: processGlobalValue ( const MachineOperand & MO ) { if ( MO . isGlobal ( ) ) { const GlobalValue * GVal = MO . getGlobal ( ) ; auto * GVar = dyn_cast < GlobalVariable > ( GVal ) ; if ( ! GVar ) {

processFuncPrototypes ( dyn_cast < Function > ( GVal ) ) ;


<s> void BTFTypeDerived :: setPointeeType ( uint32_t PointeeType ) { BTFType . Type = PointeeType ;


<s> const DISubrange * SR = cast < DISubrange > ( Element ) ; auto * CI = SR -> getCount ( ) . dyn_cast < ConstantInt * > ( ) ; int64_t Count = CI -> getSExtValue ( ) ; auto TypeEntry = std :: make_unique < BTFTypeArray > ( ElemTypeId , Count >= <NUM_LIT> ? Count : <NUM_LIT> ) ; if ( I == <NUM_LIT> ) ElemTypeId = addType ( std :: move ( TypeEntry ) , CTy ) ;

else ElemTypeId = addType ( std :: move ( TypeEntry ) ) ;


<s> TypeEntry = std :: make_unique < BTFTypeInt > ( Encoding , BTy -> getSizeInBits ( ) , BTy -> getOffsetInBits ( ) , BTy -> getName ( ) ) ; break ; case dwarf :: DW_ATE_float : TypeEntry = std :: make_unique < BTFTypeFloat > ( BTy -> getSizeInBits ( ) , BTy -> getName ( ) ) ; break ; default :


<s> case dwarf :: DW_ATE_float : TypeEntry = std :: make_unique < BTFTypeFloat > ( BTy -> getSizeInBits ( ) , BTy -> getName ( ) ) ; break ; default : return ; } TypeId = addType ( std :: move ( TypeEntry ) , BTy ) ;


<s> auto Tag = CTy -> getTag ( ) ; if ( Tag == dwarf :: DW_TAG_structure_type || Tag == dwarf :: DW_TAG_union_type ) { if ( CTy -> isForwardDecl ( ) ) visitFwdDeclType ( CTy , Tag == dwarf :: DW_TAG_union_type , TypeId ) ; else visitStructType ( CTy , Tag == dwarf :: DW_TAG_structure_type , TypeId ) ; } else if ( Tag == dwarf :: DW_TAG_array_type ) visitArrayType ( CTy , TypeId ) ;

else if ( Tag == dwarf :: DW_TAG_enumeration_type ) visitEnumType ( CTy , TypeId ) ;


<s> } if ( CheckPointer && SeenPointer ) { const DIType * Base = DTy -> getBaseType ( ) ; if ( Base ) { if ( const auto * CTy = dyn_cast < DICompositeType > ( Base ) ) { auto CTag = CTy -> getTag ( ) ; if ( ( CTag == dwarf :: DW_TAG_structure_type || CTag == dwarf :: DW_TAG_union_type ) && ! CTy -> getName ( ) . empty ( ) && ! CTy -> isForwardDecl ( ) ) { auto TypeEntry = std :: make_unique < BTFTypeDerived > ( DTy , Tag , true ) ; auto & Fixup = FixupDerivedTypes [ CTy -> getName ( ) ] ; Fixup . first = CTag == dwarf :: DW_TAG_union_type ; Fixup . second . push_back ( TypeEntry . get ( ) ) ; TypeId = addType ( std :: move ( TypeEntry ) , DTy ) ; return ; } } } } if ( Tag == dwarf :: DW_TAG_pointer_type || Tag == dwarf :: DW_TAG_typedef || Tag == dwarf :: DW_TAG_const_type || Tag == dwarf :: DW_TAG_volatile_type || Tag == dwarf :: DW_TAG_restrict_type ) { auto TypeEntry = std :: make_unique < BTFTypeDerived > ( DTy , Tag , false ) ; TypeId = addType ( std :: move ( TypeEntry ) , DTy ) ; if ( Tag == dwarf :: DW_TAG_typedef ) processDeclAnnotations ( DTy -> getAnnotations ( ) , TypeId , - <NUM_LIT> ) ; } else if ( Tag != dwarf :: DW_TAG_member ) { return ; } uint32_t TempTypeId = <NUM_LIT> ; if ( Tag == dwarf :: DW_TAG_member ) visitTypeEntry ( DTy -> getBaseType ( ) , TempTypeId , true , false ) ; else visitTypeEntry ( DTy -> getBaseType ( ) , TempTypeId , CheckPointer , SeenPointer ) ;


<s> if ( VLen > <STR_LIT> ) return ; auto TypeEntry = std :: make_unique < BTFTypeEnum > ( CTy , VLen ) ;

TypeId = addType ( std :: move ( TypeEntry ) , CTy ) ;


<s> auto Tag = CTy -> getTag ( ) ; if ( Tag != dwarf :: DW_TAG_structure_type || CTy -> isForwardDecl ( ) ) return ; const DINodeArray Elements = CTy -> getElements ( ) ; for ( const auto * Element : Elements ) { const auto * MemberType = cast < DIDerivedType > ( Element ) ; visitTypeEntry ( MemberType -> getBaseType ( ) ) ; }

visitTypeEntry ( OrigTy , TypeId , false , false ) ;


<s> break ; } } auto TypeEntry = std :: make_unique < BTFTypeStruct > ( CTy , IsStruct , HasBitField , VLen ) ; StructTypes . push_back ( TypeEntry . get ( ) ) ; TypeId = addType ( std :: move ( TypeEntry ) , CTy ) ; processDeclAnnotations ( CTy -> getAnnotations ( ) , TypeId , - <NUM_LIT> ) ;


<s> void BTFDebug :: visitSubroutineType ( const DISubroutineType * STy , bool ForSubprog , const std :: unordered_map < uint32_t , StringRef > & FuncArgNames , uint32_t & TypeId ) { DITypeRefArray Elements = STy -> getTypeArray ( ) ; uint32_t VLen = Elements . size ( ) - <NUM_LIT> ; if ( VLen > <STR_LIT> ) return ; auto TypeEntry = std :: make_unique < BTFTypeFuncProto > ( STy , VLen , FuncArgNames ) ; if ( ForSubprog ) TypeId = addType ( std :: move ( TypeEntry ) ) ;

else TypeId = addType ( std :: move ( TypeEntry ) , STy ) ;


visitTypeEntry ( Ty , TypeId , false , false ) ;


<s> void BTFDebug :: visitTypeEntry ( const DIType * Ty ) { uint32_t TypeId ;


<s> std :: string BTFDebug :: populateFileContent ( const DISubprogram * SP ) { auto File = SP -> getFile ( ) ; std :: string FileName ; if ( ! File -> getFilename ( ) . startswith ( <STR_LIT> ) && File -> getDirectory ( ) . size ( ) ) FileName = File -> getDirectory ( ) . str ( ) + <STR_LIT> + File -> getFilename ( ) . str ( ) ; else FileName = File -> getFilename ( ) ; if ( FileContent . find ( FileName ) != FileContent . end ( ) ) return FileName ; std :: vector < std :: string > Content ; std :: string Line ; Content . push_back ( Line ) ; auto Source = File -> getSource ( ) ; if ( Source ) { std :: istringstream InputString ( Source . getValue ( ) ) ; while ( std :: getline ( InputString , Line ) ) Content . push_back ( Line ) ;


<s> std :: string BTFDebug :: populateFileContent ( const DISubprogram * SP ) { auto File = SP -> getFile ( ) ; std :: string FileName ; if ( ! File -> getFilename ( ) . startswith ( <STR_LIT> ) && File -> getDirectory ( ) . size ( ) ) FileName = File -> getDirectory ( ) . str ( ) + <STR_LIT> + File -> getFilename ( ) . str ( ) ; else FileName = File -> getFilename ( ) ; if ( FileContent . find ( FileName ) != FileContent . end ( ) ) return FileName ; std :: vector < std :: string > Content ; std :: string Line ;