LLVM: lib/Target/BPF/BTFDebug.cpp Source File (original) (raw)

1

2

3

4

5

6

7

8

9

10

11

12

31#include

32

33using namespace llvm;

34

36#define HANDLE_BTF_KIND(ID, NAME) "BTF_KIND_" #NAME,

37#include "llvm/DebugInfo/BTF/BTF.def"

38};

39

41 if (!Ty)

42 return Ty;

44 if (DerivedTy && DerivedTy->getTag() == dwarf::DW_TAG_atomic_type)

45 return DerivedTy->getBaseType();

46 return Ty;

47}

48

49

58

60 bool NeedsFixup)

61 : DTy(DTy), NeedsFixup(NeedsFixup), Name(DTy->getName()) {

62 switch (Tag) {

63 case dwarf::DW_TAG_pointer_type:

64 Kind = BTF::BTF_KIND_PTR;

65 break;

66 case dwarf::DW_TAG_const_type:

67 Kind = BTF::BTF_KIND_CONST;

68 break;

69 case dwarf::DW_TAG_volatile_type:

70 Kind = BTF::BTF_KIND_VOLATILE;

71 break;

72 case dwarf::DW_TAG_typedef:

73 Kind = BTF::BTF_KIND_TYPEDEF;

74 break;

75 case dwarf::DW_TAG_restrict_type:

76 Kind = BTF::BTF_KIND_RESTRICT;

77 break;

78 default:

80 }

82}

83

84

87 : DTy(nullptr), NeedsFixup(false), Name(Name) {

88 Kind = BTF::BTF_KIND_PTR;

90 BTFType.Type = NextTypeId;

91}

92

95 return;

97

98 switch (Kind) {

99 case BTF::BTF_KIND_PTR:

100 case BTF::BTF_KIND_CONST:

101 case BTF::BTF_KIND_VOLATILE:

102 case BTF::BTF_KIND_RESTRICT:

103

104

105

106

107

108

109

111 break;

112 default:

114 break;

115 }

116

117 if (NeedsFixup || !DTy)

118 return;

119

120

122 if (!ResolvedType) {

123 assert((Kind == BTF::BTF_KIND_PTR || Kind == BTF::BTF_KIND_CONST ||

124 Kind == BTF::BTF_KIND_VOLATILE) &&

125 "Invalid null basetype");

127 } else {

129 }

130}

131

133

135 BTFType.Type = PointeeType;

136}

137

138

140 Kind = BTF::BTF_KIND_FWD;

141 BTFType.Info = IsUnion << 31 | Kind << 24;

143}

144

152

154

157 : Name(TypeName) {

158

160 switch (Encoding) {

161 case dwarf::DW_ATE_boolean:

163 break;

164 case dwarf::DW_ATE_signed:

165 case dwarf::DW_ATE_signed_char:

167 break;

168 case dwarf::DW_ATE_unsigned:

169 case dwarf::DW_ATE_unsigned_char:

170 BTFEncoding = 0;

171 break;

172 default:

174 }

175

176 Kind = BTF::BTF_KIND_INT;

179 IntVal = (BTFEncoding << 24) | OffsetInBits << 16 | SizeInBits;

180}

181

189

195

197 bool IsSigned) : ETy(ETy) {

198 Kind = BTF::BTF_KIND_ENUM;

199 BTFType.Info = IsSigned << 31 | Kind << 24 | VLen;

201}

202

205 return;

207

209

210 DINodeArray Elements = ETy->getElements();

211 for (const auto Element : Elements) {

213

216

218 if (Enum->isUnsigned())

219 Value = static_cast<uint32_t>(Enum->getValue().getZExtValue());

220 else

221 Value = static_cast<uint32_t>(Enum->getValue().getSExtValue());

223 EnumValues.push_back(BTFEnum);

224 }

225}

226

229 for (const auto &Enum : EnumValues) {

232 }

233}

234

236 bool IsSigned) : ETy(ETy) {

237 Kind = BTF::BTF_KIND_ENUM64;

238 BTFType.Info = IsSigned << 31 | Kind << 24 | VLen;

240}

241

244 return;

246

248

249 DINodeArray Elements = ETy->getElements();

250 for (const auto Element : Elements) {

252

256 if (Enum->isUnsigned())

257 Value = Enum->getValue().getZExtValue();

258 else

259 Value = static_cast<uint64_t>(Enum->getValue().getSExtValue());

262 EnumValues.push_back(BTFEnum);

263 }

264}

265

268 for (const auto &Enum : EnumValues) {

274 }

275}

276

278 Kind = BTF::BTF_KIND_ARRAY;

282

283 ArrayInfo.ElemType = ElemTypeId;

284 ArrayInfo.Nelems = NumElems;

285}

286

287

290 return;

292

293

294

295

296

298}

299

306

307

309 bool HasBitField, uint32_t Vlen)

310 : STy(STy), HasBitField(HasBitField) {

311 Kind = IsStruct ? BTF::BTF_KIND_STRUCT : BTF::BTF_KIND_UNION;

313 BTFType.Info = (HasBitField << 31) | (Kind << 24) | Vlen;

314}

315

318 return;

320

322

323 if (STy->getTag() == dwarf::DW_TAG_variant_part) {

324

325

326

327

328

329

330

331

332 const auto *DTy = STy->getDiscriminator();

333 if (DTy) {

335

336 Discriminator.NameOff = BDebug.addString(DTy->getName());

337 Discriminator.Offset = DTy->getOffsetInBits();

338 const auto *BaseTy = DTy->getBaseType();

339 Discriminator.Type = BDebug.getTypeId(BaseTy);

340

341 Members.push_back(Discriminator);

342 }

343 }

344

345

346 const DINodeArray Elements = STy->getElements();

347 for (const auto *Element : Elements) {

349

350 switch (Element->getTag()) {

351 case dwarf::DW_TAG_member: {

353

355 if (HasBitField) {

356 uint8_t BitFieldSize = DDTy->isBitField() ? DDTy->getSizeInBits() : 0;

357 BTFMember.Offset = BitFieldSize << 24 | DDTy->getOffsetInBits();

358 } else {

359 BTFMember.Offset = DDTy->getOffsetInBits();

360 }

363 break;

364 }

365 case dwarf::DW_TAG_variant_part: {

367

369 BTFMember.Offset = DCTy->getOffsetInBits();

371 break;

372 }

373 default:

374 llvm_unreachable("Unexpected DI tag of a struct/union element");

375 }

376 Members.push_back(BTFMember);

377 }

378}

379

382 for (const auto &Member : Members) {

387 }

388}

389

391

392

393

394

395

396

399 const std::unordered_map<uint32_t, StringRef> &FuncArgNames)

400 : STy(STy), FuncArgNames(FuncArgNames) {

401 Kind = BTF::BTF_KIND_FUNC_PROTO;

403}

404

407 return;

409

414

415

416

417 for (unsigned I = 1, N = Elements.size(); I < N; ++I) {

420 if (Element) {

421 Param.NameOff = BDebug.addString(FuncArgNames[I]);

422 Param.Type = BDebug.getTypeId(Element);

423 } else {

424 Param.NameOff = 0;

425 Param.Type = 0;

426 }

427 Parameters.push_back(Param);

428 }

429}

430

433 for (const auto &Param : Parameters) {

436 }

437}

438

441 : Name(FuncName) {

442 Kind = BTF::BTF_KIND_FUNC;

444 BTFType.Type = ProtoTypeId;

445}

446

454

456

458 : Name(VarName) {

459 Kind = BTF::BTF_KIND_VAR;

462 Info = VarInfo;

463}

464

468

473

475 : Asm(AsmPrt), Name(SecName) {

476 Kind = BTF::BTF_KIND_DATASEC;

479}

480

483 BTFType.Info |= Vars.size();

484}

485

488

489 for (const auto &V : Vars) {

491 Asm->emitLabelReference(std::get<1>(V), 4);

493 }

494}

495

497 : Name(TypeName) {

498 Kind = BTF::BTF_KIND_FLOAT;

501}

502

510

513 : Tag(Tag) {

514 Kind = BTF::BTF_KIND_DECL_TAG;

516 BTFType.Type = BaseTypeId;

517 Info = ComponentIdx;

518}

519

527

532

534 : DTy(nullptr), Tag(Tag) {

535 Kind = BTF::BTF_KIND_TYPE_TAG;

537 BTFType.Type = NextTypeId;

538}

539

541 : DTy(DTy), Tag(Tag) {

542 Kind = BTF::BTF_KIND_TYPE_TAG;

544}

545

548 return;

551 if (DTy) {

553 if (!ResolvedType)

555 else

557 }

558}

559

561

562 for (auto &OffsetM : OffsetToIdMap) {

563 if (Table[OffsetM.second] == S)

564 return OffsetM.first;

565 }

566

568 OffsetToIdMap[Offset] = Table.size();

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

570 Size += S.size() + 1;

572}

573

576 LineInfoGenerated(false), SecNameOff(0), ArrayIndexTypeId(0),

577 MapDefNotCollected(true) {

579}

580

581uint32_t BTFDebug::addType(std::unique_ptr TypeEntry,

583 TypeEntry->setId(TypeEntries.size() + 1);

584 uint32_t Id = TypeEntry->getId();

585 DIToIdMap[Ty] = Id;

586 TypeEntries.push_back(std::move(TypeEntry));

587 return Id;

588}

589

590uint32_t BTFDebug::addType(std::unique_ptr TypeEntry) {

591 TypeEntry->setId(TypeEntries.size() + 1);

592 uint32_t Id = TypeEntry->getId();

593 TypeEntries.push_back(std::move(TypeEntry));

594 return Id;

595}

596

597void BTFDebug::visitBasicType(const DIBasicType *BTy, uint32_t &TypeId) {

598

600 std::unique_ptr TypeEntry;

601 switch (Encoding) {

602 case dwarf::DW_ATE_boolean:

603 case dwarf::DW_ATE_signed:

604 case dwarf::DW_ATE_signed_char:

605 case dwarf::DW_ATE_unsigned:

606 case dwarf::DW_ATE_unsigned_char:

607

608

609 TypeEntry = std::make_unique(

611 break;

612 case dwarf::DW_ATE_float:

615 break;

616 default:

617 return;

618 }

619

620 TypeId = addType(std::move(TypeEntry), BTy);

621}

622

623

624void BTFDebug::visitSubroutineType(

626 const std::unordered_map<uint32_t, StringRef> &FuncArgNames,

627 uint32_t &TypeId) {

629 uint32_t VLen = Elements.size() - 1;

631 return;

632

633

634

635

636

637 auto TypeEntry = std::make_unique(STy, VLen, FuncArgNames);

638 if (ForSubprog)

639 TypeId = addType(std::move(TypeEntry));

640 else

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

642

643

644 for (const auto Element : Elements) {

645 visitTypeEntry(Element);

646 }

647}

648

649void BTFDebug::processDeclAnnotations(DINodeArray Annotations,

650 uint32_t BaseTypeId,

651 int ComponentIdx) {

652 if (!Annotations)

653 return;

654

655 for (const Metadata *Annotation : Annotations->operands()) {

658 if (Name->getString() != "btf_decl_tag")

659 continue;

660

662 auto TypeEntry = std::make_unique(BaseTypeId, ComponentIdx,

663 Value->getString());

664 addType(std::move(TypeEntry));

665 }

666}

667

668uint32_t BTFDebug::processDISubprogram(const DISubprogram *SP,

669 uint32_t ProtoTypeId, uint8_t Scope) {

670 auto FuncTypeEntry =

671 std::make_unique(SP->getName(), ProtoTypeId, Scope);

672 uint32_t FuncId = addType(std::move(FuncTypeEntry));

673

674

675 for (const DINode *DN : SP->getRetainedNodes()) {

677 uint32_t Arg = DV->getArg();

678 if (Arg)

679 processDeclAnnotations(DV->getAnnotations(), FuncId, Arg - 1);

680 }

681 }

682 processDeclAnnotations(SP->getAnnotations(), FuncId, -1);

683

684 return FuncId;

685}

686

687

688int BTFDebug::genBTFTypeTags(const DIDerivedType *DTy, int BaseTypeId) {

691 if (Annots) {

692

693

694 for (const Metadata *Annotations : Annots->operands()) {

695 const MDNode *MD = cast(Annotations);

697 if (Name->getString() != "btf_type_tag")

698 continue;

700 }

701 }

702

703 if (MDStrs.size() == 0)

704 return -1;

705

706

707

708

709

710 unsigned TmpTypeId;

711 std::unique_ptr TypeEntry;

712 if (BaseTypeId >= 0)

714 std::make_unique(BaseTypeId, MDStrs[0]->getString());

715 else

716 TypeEntry = std::make_unique(DTy, MDStrs[0]->getString());

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

718

719 for (unsigned I = 1; I < MDStrs.size(); I++) {

720 const MDString *Value = MDStrs[I];

721 TypeEntry = std::make_unique(TmpTypeId, Value->getString());

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

723 }

724 return TmpTypeId;

725}

726

727

728void BTFDebug::visitStructType(const DICompositeType *CTy, bool IsStruct,

729 uint32_t &TypeId) {

731 uint32_t VLen = Elements.size();

732

733

734

735 if (CTy->getTag() == dwarf::DW_TAG_variant_part) {

737 if (DTy) {

738 visitTypeEntry(DTy);

739 VLen++;

740 }

741 }

743 return;

744

745

746 bool HasBitField = false;

747 for (const auto *Element : Elements) {

748 if (Element->getTag() == dwarf::DW_TAG_member) {

750 if (E->isBitField()) {

751 HasBitField = true;

752 break;

753 }

754 }

755 }

756

758 std::make_unique(CTy, IsStruct, HasBitField, VLen);

759 StructTypes.push_back(TypeEntry.get());

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

761

762

763 processDeclAnnotations(CTy->getAnnotations(), TypeId, -1);

764

765

766 int FieldNo = 0;

767 for (const auto *Element : Elements) {

768 switch (Element->getTag()) {

769 case dwarf::DW_TAG_member: {

771 visitTypeEntry(Elem);

772 processDeclAnnotations(Elem->getAnnotations(), TypeId, FieldNo);

773 break;

774 }

775 case dwarf::DW_TAG_variant_part: {

777 visitTypeEntry(Elem);

778 processDeclAnnotations(Elem->getAnnotations(), TypeId, FieldNo);

779 break;

780 }

781 default:

782 llvm_unreachable("Unexpected DI tag of a struct/union element");

783 }

784 FieldNo++;

785 }

786}

787

788void BTFDebug::visitArrayType(const DICompositeType *CTy, uint32_t &TypeId) {

789

790 uint32_t ElemTypeId;

791 const DIType *ElemType = CTy->getBaseType();

792 visitTypeEntry(ElemType, ElemTypeId, false, false);

793

794

796 for (int I = Elements.size() - 1; I >= 0; --I) {

798 if (Element->getTag() == dwarf::DW_TAG_subrange_type) {

801 int64_t Count = CI->getSExtValue();

802

803

804

806 std::make_unique(ElemTypeId,

808 if (I == 0)

809 ElemTypeId = addType(std::move(TypeEntry), CTy);

810 else

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

812 }

813 }

814

815

816 TypeId = ElemTypeId;

817

818

819

820 if (!ArrayIndexTypeId) {

821 auto TypeEntry = std::make_unique(dwarf::DW_ATE_unsigned, 32,

822 0, "__ARRAY_SIZE_TYPE__");

823 ArrayIndexTypeId = addType(std::move(TypeEntry));

824 }

825}

826

827void BTFDebug::visitEnumType(const DICompositeType *CTy, uint32_t &TypeId) {

829 uint32_t VLen = Elements.size();

831 return;

832

833 bool IsSigned = false;

834 unsigned NumBits = 32;

835

836

839 IsSigned = BTy->getEncoding() == dwarf::DW_ATE_signed ||

840 BTy->getEncoding() == dwarf::DW_ATE_signed_char;

842 }

843

844 if (NumBits <= 32) {

845 auto TypeEntry = std::make_unique(CTy, VLen, IsSigned);

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

847 } else {

848 assert(NumBits == 64);

849 auto TypeEntry = std::make_unique(CTy, VLen, IsSigned);

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

851 }

852

853}

854

855

856void BTFDebug::visitFwdDeclType(const DICompositeType *CTy, bool IsUnion,

857 uint32_t &TypeId) {

858 auto TypeEntry = std::make_unique(CTy->getName(), IsUnion);

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

860}

861

862

863void BTFDebug::visitCompositeType(const DICompositeType *CTy,

864 uint32_t &TypeId) {

866 switch (Tag) {

867 case dwarf::DW_TAG_structure_type:

868 case dwarf::DW_TAG_union_type:

869 case dwarf::DW_TAG_variant_part:

870

872 visitFwdDeclType(CTy, Tag == dwarf::DW_TAG_union_type, TypeId);

873 else

874 visitStructType(CTy, Tag == dwarf::DW_TAG_structure_type, TypeId);

875 break;

876 case dwarf::DW_TAG_array_type:

877 visitArrayType(CTy, TypeId);

878 break;

879 case dwarf::DW_TAG_enumeration_type:

880 visitEnumType(CTy, TypeId);

881 break;

882 default:

884 }

885}

886

887bool BTFDebug::IsForwardDeclCandidate(const DIType *Base) {

889 auto CTag = CTy->getTag();

890 if ((CTag == dwarf::DW_TAG_structure_type ||

891 CTag == dwarf::DW_TAG_union_type) &&

893 return true;

894 }

895 return false;

896}

897

898

899void BTFDebug::visitDerivedType(const DIDerivedType *DTy, uint32_t &TypeId,

900 bool CheckPointer, bool SeenPointer) {

902

903 if (Tag == dwarf::DW_TAG_atomic_type)

904 return visitTypeEntry(DTy->getBaseType(), TypeId, CheckPointer,

905 SeenPointer);

906

907

908

909 if (CheckPointer && !SeenPointer) {

910 SeenPointer = Tag == dwarf::DW_TAG_pointer_type && !DTy->getAnnotations();

911 }

912

913 if (CheckPointer && SeenPointer) {

914 const DIType *Base = DTy->getBaseType();

916 if (IsForwardDeclCandidate(Base)) {

917

918

919

920 auto TypeEntry = std::make_unique(DTy, Tag, true);

922 Fixup.push_back(std::make_pair(DTy, TypeEntry.get()));

923 TypeId = addType(std::move(TypeEntry), DTy);

924 return;

925 }

926 }

927 }

928

929 if (Tag == dwarf::DW_TAG_pointer_type) {

930 int TmpTypeId = genBTFTypeTags(DTy, -1);

931 if (TmpTypeId >= 0) {

932 auto TypeDEntry =

933 std::make_unique(TmpTypeId, Tag, DTy->getName());

934 TypeId = addType(std::move(TypeDEntry), DTy);

935 } else {

936 auto TypeEntry = std::make_unique(DTy, Tag, false);

937 TypeId = addType(std::move(TypeEntry), DTy);

938 }

939 } else if (Tag == dwarf::DW_TAG_typedef || Tag == dwarf::DW_TAG_const_type ||

940 Tag == dwarf::DW_TAG_volatile_type ||

941 Tag == dwarf::DW_TAG_restrict_type) {

942 auto TypeEntry = std::make_unique(DTy, Tag, false);

943 TypeId = addType(std::move(TypeEntry), DTy);

944 if (Tag == dwarf::DW_TAG_typedef)

945 processDeclAnnotations(DTy->getAnnotations(), TypeId, -1);

946 } else if (Tag != dwarf::DW_TAG_member) {

947 return;

948 }

949

950

951

952 uint32_t TempTypeId = 0;

953 if (Tag == dwarf::DW_TAG_member)

954 visitTypeEntry(DTy->getBaseType(), TempTypeId, true, false);

955 else

956 visitTypeEntry(DTy->getBaseType(), TempTypeId, CheckPointer, SeenPointer);

957}

958

959

960

961

962

963

964

965

966void BTFDebug::visitTypeEntry(const DIType *Ty, uint32_t &TypeId,

967 bool CheckPointer, bool SeenPointer) {

968 if (!Ty || DIToIdMap.find(Ty) != DIToIdMap.end()) {

969 TypeId = DIToIdMap[Ty];

970

971

972

973

974

975

976

977

978

979

980

981

982

983

984

985

986

987

988

989

990

991

992

993

994

995

996

997

998

999

1000 if (Ty && (!CheckPointer || !SeenPointer)) {

1002 while (DTy) {

1003 const DIType *BaseTy = DTy->getBaseType();

1004 if (!BaseTy)

1005 break;

1006

1007 if (DIToIdMap.find(BaseTy) != DIToIdMap.end()) {

1009 } else {

1010 if (CheckPointer && DTy->getTag() == dwarf::DW_TAG_pointer_type &&

1012 SeenPointer = true;

1013 if (IsForwardDeclCandidate(BaseTy))

1014 break;

1015 }

1016 uint32_t TmpTypeId;

1017 visitTypeEntry(BaseTy, TmpTypeId, CheckPointer, SeenPointer);

1018 break;

1019 }

1020 }

1021 }

1022 }

1023

1024 return;

1025 }

1026

1028 visitBasicType(BTy, TypeId);

1030 visitSubroutineType(STy, false, std::unordered_map<uint32_t, StringRef>(),

1031 TypeId);

1033 visitCompositeType(CTy, TypeId);

1035 visitDerivedType(DTy, TypeId, CheckPointer, SeenPointer);

1036 else

1038}

1039

1040void BTFDebug::visitTypeEntry(const DIType *Ty) {

1041 uint32_t TypeId;

1042 visitTypeEntry(Ty, TypeId, false, false);

1043}

1044

1045void BTFDebug::visitMapDefType(const DIType *Ty, uint32_t &TypeId) {

1046 if (!Ty || DIToIdMap.find(Ty) != DIToIdMap.end()) {

1047 TypeId = DIToIdMap[Ty];

1048 return;

1049 }

1050

1051 uint32_t TmpId;

1052 switch (Ty->getTag()) {

1053 case dwarf::DW_TAG_typedef:

1054 case dwarf::DW_TAG_const_type:

1055 case dwarf::DW_TAG_volatile_type:

1056 case dwarf::DW_TAG_restrict_type:

1057 case dwarf::DW_TAG_pointer_type:

1059 break;

1060 case dwarf::DW_TAG_array_type:

1061

1063 break;

1064 case dwarf::DW_TAG_structure_type: {

1065

1068 for (const auto *Element : Elements) {

1070 const DIType *MemberBaseType = MemberType->getBaseType();

1071

1072

1073

1074

1075

1076

1078 if (MemberCTy) {

1079 visitMapDefType(MemberBaseType, TmpId);

1080 } else {

1081 visitTypeEntry(MemberBaseType);

1082 }

1083 }

1084 break;

1085 }

1086 default:

1087 break;

1088 }

1089

1090

1091 visitTypeEntry(Ty, TypeId, false, false);

1092}

1093

1094

1095std::string BTFDebug::populateFileContent(const DIFile *File) {

1096 std::string FileName;

1097

1098 if (File->getFilename().starts_with("/") && File->getDirectory().size())

1099 FileName = File->getDirectory().str() + "/" + File->getFilename().str();

1100 else

1101 FileName = std::string(File->getFilename());

1102

1103

1104 if (FileContent.contains(FileName))

1105 return FileName;

1106

1107 std::vectorstd::string Content;

1108 std::string Line;

1109 Content.push_back(Line);

1110

1111 std::unique_ptr Buf;

1113 if (Source)

1115 else if (ErrorOr<std::unique_ptr> BufOrErr =

1117 Buf = std::move(*BufOrErr);

1118 if (Buf)

1119 for (line_iterator I(*Buf, false), E; I != E; ++I)

1120 Content.push_back(std::string(*I));

1121

1122 FileContent[FileName] = Content;

1123 return FileName;

1124}

1125

1126void BTFDebug::constructLineInfo(MCSymbol *Label, const DIFile *File,

1127 uint32_t Line, uint32_t Column) {

1128 std::string FileName = populateFileContent(File);

1129 BTFLineInfo LineInfo;

1130

1133

1134 const auto &Content = FileContent[FileName];

1135 if (Line < Content.size())

1137 else

1141 LineInfoTable[SecNameOff].push_back(LineInfo);

1142}

1143

1144void BTFDebug::emitCommonHeader() {

1148 OS.emitInt8(0);

1149}

1150

1151void BTFDebug::emitBTFSection() {

1152

1153 if (!TypeEntries.size() && StringTable.getSize() == 1)

1154 return;

1155

1156 MCContext &Ctx = OS.getContext();

1159 OS.switchSection(Sec);

1160

1161

1162 emitCommonHeader();

1164

1165 uint32_t TypeLen = 0, StrLen;

1166 for (const auto &TypeEntry : TypeEntries)

1167 TypeLen += TypeEntry->getSize();

1168 StrLen = StringTable.getSize();

1169

1170 OS.emitInt32(0);

1171 OS.emitInt32(TypeLen);

1172 OS.emitInt32(TypeLen);

1173 OS.emitInt32(StrLen);

1174

1175

1176 for (const auto &TypeEntry : TypeEntries)

1178

1179

1180 uint32_t StringOffset = 0;

1181 for (const auto &S : StringTable.getTable()) {

1182 OS.AddComment("string offset=" + std::to_string(StringOffset));

1183 OS.emitBytes(S);

1184 OS.emitBytes(StringRef("\0", 1));

1185 StringOffset += S.size() + 1;

1186 }

1187}

1188

1189void BTFDebug::emitBTFExtSection() {

1190

1191

1192 if (!FuncInfoTable.size() && !LineInfoTable.size() &&

1193 !FieldRelocTable.size())

1194 return;

1195

1196 MCContext &Ctx = OS.getContext();

1199 OS.switchSection(Sec);

1200

1201

1202 emitCommonHeader();

1204

1205

1206 uint32_t FuncLen = 4, LineLen = 4;

1207

1208 uint32_t FieldRelocLen = 0;

1209 for (const auto &FuncSec : FuncInfoTable) {

1212 }

1213 for (const auto &LineSec : LineInfoTable) {

1216 }

1217 for (const auto &FieldRelocSec : FieldRelocTable) {

1220 }

1221

1222 if (FieldRelocLen)

1223 FieldRelocLen += 4;

1224

1225 OS.emitInt32(0);

1226 OS.emitInt32(FuncLen);

1227 OS.emitInt32(FuncLen);

1228 OS.emitInt32(LineLen);

1229 OS.emitInt32(FuncLen + LineLen);

1230 OS.emitInt32(FieldRelocLen);

1231

1232

1233 OS.AddComment("FuncInfo");

1235 for (const auto &FuncSec : FuncInfoTable) {

1236 OS.AddComment("FuncInfo section string offset=" +

1237 std::to_string(FuncSec.first));

1238 OS.emitInt32(FuncSec.first);

1239 OS.emitInt32(FuncSec.second.size());

1240 for (const auto &FuncInfo : FuncSec.second) {

1241 Asm->emitLabelReference(FuncInfo.Label, 4);

1242 OS.emitInt32(FuncInfo.TypeId);

1243 }

1244 }

1245

1246

1247 OS.AddComment("LineInfo");

1249 for (const auto &LineSec : LineInfoTable) {

1250 OS.AddComment("LineInfo section string offset=" +

1251 std::to_string(LineSec.first));

1252 OS.emitInt32(LineSec.first);

1253 OS.emitInt32(LineSec.second.size());

1254 for (const auto &LineInfo : LineSec.second) {

1255 Asm->emitLabelReference(LineInfo.Label, 4);

1257 OS.emitInt32(LineInfo.LineOff);

1258 OS.AddComment("Line " + std::to_string(LineInfo.LineNum) + " Col " +

1259 std::to_string(LineInfo.ColumnNum));

1261 }

1262 }

1263

1264

1265 if (FieldRelocLen) {

1266 OS.AddComment("FieldReloc");

1268 for (const auto &FieldRelocSec : FieldRelocTable) {

1269 OS.AddComment("Field reloc section string offset=" +

1270 std::to_string(FieldRelocSec.first));

1271 OS.emitInt32(FieldRelocSec.first);

1272 OS.emitInt32(FieldRelocSec.second.size());

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

1274 Asm->emitLabelReference(FieldRelocInfo.Label, 4);

1275 OS.emitInt32(FieldRelocInfo.TypeID);

1276 OS.emitInt32(FieldRelocInfo.OffsetNameOff);

1277 OS.emitInt32(FieldRelocInfo.RelocKind);

1278 }

1279 }

1280 }

1281}

1282

1285 auto *Unit = SP->getUnit();

1286

1288 SkipInstruction = true;

1289 return;

1290 }

1291 SkipInstruction = false;

1292

1293

1294

1295

1296

1297

1298

1299

1300

1301

1302

1303

1304

1305

1306

1307

1308

1309

1310

1311

1312 if (MapDefNotCollected) {

1313 processGlobals(true);

1314 MapDefNotCollected = false;

1315 }

1316

1317

1318

1319

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

1321 for (const DINode *DN : SP->getRetainedNodes()) {

1323

1324 uint32_t Arg = DV->getArg();

1325 if (Arg) {

1326 visitTypeEntry(DV->getType());

1327 FuncArgNames[Arg] = DV->getName();

1328 }

1329 }

1330 }

1331

1332

1334 visitSubroutineType(SP->getType(), true, FuncArgNames, ProtoTypeId);

1335

1336

1338 uint32_t FuncTypeId = processDISubprogram(SP, ProtoTypeId, Scope);

1339

1340 for (const auto &TypeEntry : TypeEntries)

1341 TypeEntry->completeType(*this);

1342

1343

1344 MCSymbol *FuncLabel = Asm->getFunctionBegin();

1346 FuncInfo.Label = FuncLabel;

1347 FuncInfo.TypeId = FuncTypeId;

1351 } else {

1352 SecNameOff = addString(".text");

1353 }

1354 FuncInfoTable[SecNameOff].push_back(FuncInfo);

1355}

1356

1358 SkipInstruction = false;

1359 LineInfoGenerated = false;

1360 SecNameOff = 0;

1361}

1362

1363

1364

1365unsigned BTFDebug::populateType(const DIType *Ty) {

1366 unsigned Id;

1367 visitTypeEntry(Ty, Id, false, false);

1368 for (const auto &TypeEntry : TypeEntries)

1369 TypeEntry->completeType(*this);

1370 return Id;

1371}

1372

1373

1374void BTFDebug::generatePatchImmReloc(const MCSymbol *ORSym, uint32_t RootId,

1377 FieldReloc.Label = ORSym;

1378 FieldReloc.TypeID = RootId;

1379

1381 size_t FirstDollar = AccessPattern.find_first_of('$');

1382 if (IsAma) {

1383 size_t FirstColon = AccessPattern.find_first_of(':');

1384 size_t SecondColon = AccessPattern.find_first_of(':', FirstColon + 1);

1385 StringRef IndexPattern = AccessPattern.substr(FirstDollar + 1);

1386 StringRef RelocKindStr = AccessPattern.substr(FirstColon + 1,

1387 SecondColon - FirstColon);

1388 StringRef PatchImmStr = AccessPattern.substr(SecondColon + 1,

1389 FirstDollar - SecondColon);

1390

1392 FieldReloc.RelocKind = std::stoull(std::string(RelocKindStr));

1393 PatchImms[GVar] = std::make_pair(std::stoll(std::string(PatchImmStr)),

1395 } else {

1396 StringRef RelocStr = AccessPattern.substr(FirstDollar + 1);

1398 FieldReloc.RelocKind = std::stoull(std::string(RelocStr));

1399 PatchImms[GVar] = std::make_pair(RootId, FieldReloc.RelocKind);

1400 }

1401 FieldRelocTable[SecNameOff].push_back(FieldReloc);

1402}

1403

1404void BTFDebug::processGlobalValue(const MachineOperand &MO) {

1405

1407 const GlobalValue *GVal = MO.getGlobal();

1409 if (!GVar) {

1410

1412 return;

1413 }

1414

1417 return;

1418

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

1420 OS.emitLabel(ORSym);

1421

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

1424 generatePatchImmReloc(ORSym, RootId, GVar,

1426 }

1427}

1428

1431

1432 if (SkipInstruction || MI->isMetaInstruction() ||

1434 return;

1435

1436 if (MI->isInlineAsm()) {

1437

1438 unsigned NumDefs = 0;

1439 while (true) {

1442 ++NumDefs;

1443 continue;

1444 }

1445

1447 if (AsmStr[0] == 0)

1448 return;

1449 break;

1450 }

1451 }

1452

1453 if (MI->getOpcode() == BPF::LD_imm64) {

1454

1455

1456

1457

1458

1459

1460

1461

1462

1463

1464

1465

1466

1467

1468 processGlobalValue(MI->getOperand(1));

1469 } else if (MI->getOpcode() == BPF::CORE_LD64 ||

1470 MI->getOpcode() == BPF::CORE_LD32 ||

1471 MI->getOpcode() == BPF::CORE_ST ||

1472 MI->getOpcode() == BPF::CORE_SHIFT) {

1473

1474 processGlobalValue(MI->getOperand(3));

1475 } else if (MI->getOpcode() == BPF::JAL) {

1476

1480 }

1481 }

1482

1483 if (CurMI)

1484 return;

1485

1486

1487

1490

1491

1492 if (LineInfoGenerated == false) {

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

1494 if (!S)

1495 return;

1496 MCSymbol *FuncLabel = Asm->getFunctionBegin();

1497 constructLineInfo(FuncLabel, S->getFile(), S->getLine(), 0);

1498 LineInfoGenerated = true;

1499 }

1500

1501 return;

1502 }

1503

1504

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

1506 OS.emitLabel(LineSym);

1507

1508

1509 constructLineInfo(LineSym, DL->getFile(), DL.getLine(), DL.getCol());

1510

1511 LineInfoGenerated = true;

1513}

1514

1515void BTFDebug::processGlobals(bool ProcessingMapDef) {

1516

1519

1521 std::optional GVKind;

1522

1523 if (Global.isDeclarationForLinker())

1525

1526 if (Global.isDeclarationForLinker())

1527 SecName = Global.hasSection() ? Global.getSection() : "";

1528 else if (GVKind->isCommon())

1529 SecName = ".bss";

1530 else {

1533 SecName = Sec->getName();

1534 }

1535

1536 if (ProcessingMapDef != SecName.starts_with(".maps"))

1537 continue;

1538

1539

1540

1541

1542 if (SecName == ".rodata" && Global.hasPrivateLinkage() &&

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

1544

1545 if (!GVKind->isMergeableCString() && !GVKind->isMergeableConst()) {

1546 DataSecEntries[std::string(SecName)] =

1547 std::make_unique(Asm, std::string(SecName));

1548 }

1549 }

1550

1552 Global.getDebugInfo(GVs);

1553

1554

1555 if (GVs.size() == 0)

1556 continue;

1557

1558 uint32_t GVTypeId = 0;

1559 DIGlobalVariable *DIGlobal = nullptr;

1560 for (auto *GVE : GVs) {

1561 DIGlobal = GVE->getVariable();

1563 visitMapDefType(DIGlobal->getType(), GVTypeId);

1564 else {

1566 visitTypeEntry(Ty, GVTypeId, false, false);

1567 }

1568 break;

1569 }

1570

1571

1572

1573

1574

1575

1576

1577

1584 continue;

1585

1586 uint32_t GVarInfo;

1589 } else if (Global.hasInitializer()) {

1591 } else {

1593 }

1594

1595 auto VarEntry =

1596 std::make_unique(Global.getName(), GVTypeId, GVarInfo);

1597 uint32_t VarId = addType(std::move(VarEntry));

1598

1599 processDeclAnnotations(DIGlobal->getAnnotations(), VarId, -1);

1600

1601

1602 if (SecName.empty())

1603 continue;

1604

1605

1606 auto [It, Inserted] = DataSecEntries.try_emplace(std::string(SecName));

1607 if (Inserted)

1608 It->second = std::make_unique(Asm, std::string(SecName));

1609

1610

1611 const DataLayout &DL = Global.getDataLayout();

1612 uint32_t Size = DL.getTypeAllocSize(Global.getValueType());

1613

1614 It->second->addDataSecEntry(VarId, Asm->getSymbol(&Global), Size);

1615

1616 if (Global.hasInitializer())

1617 processGlobalInitializer(Global.getInitializer());

1618 }

1619}

1620

1621

1622

1623

1624

1625

1626

1627

1628

1629

1630

1631

1632void BTFDebug::processGlobalInitializer(const Constant *C) {

1634 processFuncPrototypes(Fn);

1636 for (unsigned I = 0, N = CA->getNumOperands(); I < N; ++I)

1637 processGlobalInitializer(CA->getOperand(I));

1638 }

1639}

1640

1641

1643 if (MI->getOpcode() == BPF::LD_imm64) {

1648 if (GVar) {

1651 return false;

1652

1653

1654 auto [Imm, Reloc] = PatchImms[GVar];

1658 else

1662 return true;

1663 }

1664 }

1665 } else if (MI->getOpcode() == BPF::CORE_LD64 ||

1666 MI->getOpcode() == BPF::CORE_LD32 ||

1667 MI->getOpcode() == BPF::CORE_ST ||

1668 MI->getOpcode() == BPF::CORE_SHIFT) {

1674 uint32_t Imm = PatchImms[GVar].first;

1675 OutMI.setOpcode(MI->getOperand(1).getImm());

1676 if (MI->getOperand(0).isImm())

1678 else

1682 return true;

1683 }

1684 }

1685 }

1686 return false;

1687}

1688

1689void BTFDebug::processFuncPrototypes(const Function *F) {

1690 if (F)

1691 return;

1692

1694 if (!SP || SP->isDefinition())

1695 return;

1696

1697

1698 if (!ProtoFunctions.insert(F).second)

1699 return;

1700

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

1703 visitSubroutineType(SP->getType(), false, FuncArgNames, ProtoTypeId);

1705

1706 if (F->hasSection()) {

1707 StringRef SecName = F->getSection();

1708

1709 auto [It, Inserted] = DataSecEntries.try_emplace(std::string(SecName));

1710 if (Inserted)

1711 It->second = std::make_unique(Asm, std::string(SecName));

1712

1713

1714 It->second->addDataSecEntry(FuncId, Asm->getSymbol(F), 0);

1715 }

1716}

1717

1719

1720 if (MapDefNotCollected) {

1721 processGlobals(true);

1722 MapDefNotCollected = false;

1723 }

1724

1725

1726 processGlobals(false);

1727

1728

1729

1730 for (const Function &F : *MMI->getModule()) {

1732 processFuncPrototypes(&F);

1733 }

1734

1735 for (auto &DataSec : DataSecEntries)

1736 addType(std::move(DataSec.second));

1737

1738

1739 for (auto &Fixup : FixupDerivedTypes) {

1742 bool IsUnion = CTy->getTag() == dwarf::DW_TAG_union_type;

1743

1744

1746 for (const auto &StructType : StructTypes) {

1749 break;

1750 }

1751 }

1752

1753 if (StructTypeId == 0) {

1754 auto FwdTypeEntry = std::make_unique(TypeName, IsUnion);

1755 StructTypeId = addType(std::move(FwdTypeEntry));

1756 }

1757

1758 for (auto &TypeInfo : Fixup.second) {

1761

1762 int TmpTypeId = genBTFTypeTags(DTy, StructTypeId);

1763 if (TmpTypeId >= 0)

1765 else

1767 }

1768 }

1769

1770

1771 for (const auto &TypeEntry : TypeEntries)

1772 TypeEntry->completeType(*this);

1773

1774

1775 emitBTFSection();

1776 emitBTFExtSection();

1777}

assert(UImm &&(UImm !=~static_cast< T >(0)) &&"Invalid immediate!")

MachineBasicBlock MachineBasicBlock::iterator DebugLoc DL

static const char * BTFKindStr[]

Definition BTFDebug.cpp:35

static const DIType * tryRemoveAtomicType(const DIType *Ty)

Definition BTFDebug.cpp:40

This file contains support for writing BTF debug info.

static GCRegistry::Add< CoreCLRGC > E("coreclr", "CoreCLR-compatible GC")

This file contains constants used for implementing Dwarf debug support.

Module.h This file contains the declarations for the Module class.

PowerPC TLS Dynamic Call Fixup

static StringRef getName(Value *V)

static enum BaseType getBaseType(const Value *Val)

Return the baseType for Val which states whether Val is exclusively derived from constant/null,...

Annotations lets you mark points and ranges inside source code, for tests:

This class is intended to be used as a driving class for all asm writers.

MCSymbol * getSymbol(const GlobalValue *GV) const

TargetMachine & TM

Target machine description.

Collect and emit BTF information.

void endFunctionImpl(const MachineFunction *MF) override

Post process after all instructions in this function are processed.

Definition BTFDebug.cpp:1357

BTFDebug(AsmPrinter *AP)

Definition BTFDebug.cpp:574

void beginInstruction(const MachineInstr *MI) override

Process beginning of an instruction.

Definition BTFDebug.cpp:1429

bool InstLower(const MachineInstr *MI, MCInst &OutMI)

Emit proper patchable instructions.

Definition BTFDebug.cpp:1642

size_t addString(StringRef S)

Add string to the string table.

uint32_t getArrayIndexTypeId()

Get the special array index type id.

uint32_t getTypeId(const DIType *Ty)

Get the type id for a particular DIType.

void endModule() override

Complete all the types and emit the BTF sections.

Definition BTFDebug.cpp:1718

void beginFunctionImpl(const MachineFunction *MF) override

Gather pre-function debug information.

Definition BTFDebug.cpp:1283

void emitType(MCStreamer &OS) override

Emit types for this BTF type entry.

Definition BTFDebug.cpp:486

void completeType(BTFDebug &BDebug) override

Complete BTF type generation after all related DebugInfo types have been visited so their BTF type id...

Definition BTFDebug.cpp:481

BTFKindDataSec(AsmPrinter *AsmPrt, std::string SecName)

Definition BTFDebug.cpp:474

BTFKindVar(StringRef VarName, uint32_t TypeId, uint32_t VarInfo)

Definition BTFDebug.cpp:457

void emitType(MCStreamer &OS) override

Emit types for this BTF type entry.

Definition BTFDebug.cpp:469

void completeType(BTFDebug &BDebug) override

Complete BTF type generation after all related DebugInfo types have been visited so their BTF type id...

Definition BTFDebug.cpp:465

uint32_t addString(StringRef S)

Add a string to the string table and returns its offset in the table.

Definition BTFDebug.cpp:560

BTFTypeArray(uint32_t ElemTypeId, uint32_t NumElems)

Definition BTFDebug.cpp:277

void emitType(MCStreamer &OS) override

Emit types for this BTF type entry.

Definition BTFDebug.cpp:300

void completeType(BTFDebug &BDebug) override

Represent a BTF array.

Definition BTFDebug.cpp:288

struct BTF::CommonType BTFType

virtual void emitType(MCStreamer &OS)

Emit types for this BTF type entry.

Definition BTFDebug.cpp:50

uint32_t roundupToBytes(uint32_t NumBits)

void completeType(BTFDebug &BDebug) override

Complete BTF type generation after all related DebugInfo types have been visited so their BTF type id...

Definition BTFDebug.cpp:520

void emitType(MCStreamer &OS) override

Emit types for this BTF type entry.

Definition BTFDebug.cpp:528

BTFTypeDeclTag(uint32_t BaseTypeId, int ComponentId, StringRef Tag)

Definition BTFDebug.cpp:511

Handle several derived types include pointer, const, volatile, typedef and restrict.

void completeType(BTFDebug &BDebug) override

Complete BTF type generation after all related DebugInfo types have been visited so their BTF type id...

Definition BTFDebug.cpp:93

void emitType(MCStreamer &OS) override

Emit types for this BTF type entry.

Definition BTFDebug.cpp:132

void setPointeeType(uint32_t PointeeType)

Definition BTFDebug.cpp:134

BTFTypeDerived(const DIDerivedType *Ty, unsigned Tag, bool NeedsFixup)

Definition BTFDebug.cpp:59

void completeType(BTFDebug &BDebug) override

Complete BTF type generation after all related DebugInfo types have been visited so their BTF type id...

Definition BTFDebug.cpp:242

BTFTypeEnum64(const DICompositeType *ETy, uint32_t NumValues, bool IsSigned)

Definition BTFDebug.cpp:235

void emitType(MCStreamer &OS) override

Emit types for this BTF type entry.

Definition BTFDebug.cpp:266

void completeType(BTFDebug &BDebug) override

Complete BTF type generation after all related DebugInfo types have been visited so their BTF type id...

Definition BTFDebug.cpp:203

BTFTypeEnum(const DICompositeType *ETy, uint32_t NumValues, bool IsSigned)

Definition BTFDebug.cpp:196

void emitType(MCStreamer &OS) override

Emit types for this BTF type entry.

Definition BTFDebug.cpp:227

void completeType(BTFDebug &BDebug) override

Complete BTF type generation after all related DebugInfo types have been visited so their BTF type id...

Definition BTFDebug.cpp:503

BTFTypeFloat(uint32_t SizeInBits, StringRef TypeName)

Definition BTFDebug.cpp:496

BTFTypeFuncProto(const DISubroutineType *STy, uint32_t NumParams, const std::unordered_map< uint32_t, StringRef > &FuncArgNames)

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

Definition BTFDebug.cpp:397

void completeType(BTFDebug &BDebug) override

Complete BTF type generation after all related DebugInfo types have been visited so their BTF type id...

Definition BTFDebug.cpp:405

void emitType(MCStreamer &OS) override

Emit types for this BTF type entry.

Definition BTFDebug.cpp:431

void emitType(MCStreamer &OS) override

Emit types for this BTF type entry.

Definition BTFDebug.cpp:455

BTFTypeFunc(StringRef FuncName, uint32_t ProtoTypeId, uint32_t Scope)

Definition BTFDebug.cpp:439

void completeType(BTFDebug &BDebug) override

Complete BTF type generation after all related DebugInfo types have been visited so their BTF type id...

Definition BTFDebug.cpp:447

void emitType(MCStreamer &OS) override

Emit types for this BTF type entry.

Definition BTFDebug.cpp:153

BTFTypeFwd(StringRef Name, bool IsUnion)

Represent a struct/union forward declaration.

Definition BTFDebug.cpp:139

void completeType(BTFDebug &BDebug) override

Complete BTF type generation after all related DebugInfo types have been visited so their BTF type id...

Definition BTFDebug.cpp:145

void emitType(MCStreamer &OS) override

Emit types for this BTF type entry.

Definition BTFDebug.cpp:190

BTFTypeInt(uint32_t Encoding, uint32_t SizeInBits, uint32_t OffsetInBits, StringRef TypeName)

Definition BTFDebug.cpp:155

void completeType(BTFDebug &BDebug) override

Complete BTF type generation after all related DebugInfo types have been visited so their BTF type id...

Definition BTFDebug.cpp:182

void emitType(MCStreamer &OS) override

Emit types for this BTF type entry.

Definition BTFDebug.cpp:380

BTFTypeStruct(const DICompositeType *STy, bool IsStruct, bool HasBitField, uint32_t NumMembers)

Represent either a struct or a union.

Definition BTFDebug.cpp:308

void completeType(BTFDebug &BDebug) override

Complete BTF type generation after all related DebugInfo types have been visited so their BTF type id...

Definition BTFDebug.cpp:316

std::string getName()

Definition BTFDebug.cpp:390

void completeType(BTFDebug &BDebug) override

Complete BTF type generation after all related DebugInfo types have been visited so their BTF type id...

Definition BTFDebug.cpp:546

BTFTypeTypeTag(uint32_t NextTypeId, StringRef Tag)

Definition BTFDebug.cpp:533

This is an important base class in LLVM.

Basic type, like 'int' or 'float'.

unsigned getEncoding() const

DIDerivedType * getDiscriminator() const

DINodeArray getElements() const

DINodeArray getAnnotations() const

DIType * getBaseType() const

DINodeArray getAnnotations() const

Get annotations associated with this derived type.

DINodeArray getAnnotations() const

Tagged DWARF-like metadata node.

LLVM_ABI dwarf::Tag getTag() const

Subprogram description. Uses SubclassData1.

LLVM_ABI BoundType getCount() const

Type array for a subprogram.

DITypeRefArray getTypeArray() const

uint64_t getOffsetInBits() const

StringRef getName() const

bool isForwardDecl() const

uint64_t getSizeInBits() const

const MachineInstr * CurMI

If nonnull, stores the current machine instruction we're processing.

AsmPrinter * Asm

Target of debug info emission.

MachineModuleInfo * MMI

Collected machine module information.

DebugLoc PrevInstLoc

Previous instruction's location information.

DebugHandlerBase(AsmPrinter *A)

void beginInstruction(const MachineInstr *MI) override

Process beginning of an instruction.

DISubprogram * getSubprogram() const

Get the attached subprogram.

MDNode * getMetadata(unsigned KindID) const

Get the current metadata attachments for the given kind, if any.

@ InternalLinkage

Rename collisions when linking (static functions).

@ WeakODRLinkage

Same, but only replaced by something equivalent.

@ ExternalLinkage

Externally visible function.

@ WeakAnyLinkage

Keep one copy of named function when linking (weak)

@ ExternalWeakLinkage

ExternalWeak linkage description.

bool hasAttribute(Attribute::AttrKind Kind) const

Return true if the attribute exists.

MCSectionELF * getELFSection(const Twine &Section, unsigned Type, unsigned Flags)

Instances of this class represent a single low-level machine instruction.

void addOperand(const MCOperand Op)

void setOpcode(unsigned Op)

static MCOperand createReg(MCRegister Reg)

static MCOperand createImm(int64_t Val)

This represents a section on linux, lots of unix variants and some bare metal systems.

Instances of this class represent a uniqued identifier for a section in the current translation unit.

void setAlignment(Align Value)

StringRef getName() const

Streaming machine code generation interface.

virtual void AddComment(const Twine &T, bool EOL=true)

Add a textual comment.

void emitInt32(uint64_t Value)

MCSymbol - Instances of this class represent a symbol name in the MC file, and MCSymbols are created ...

bool isInSection() const

isInSection - Check if this symbol is defined in some section (i.e., it is defined but not absolute).

MCSection & getSection() const

Get the section associated with a defined, non-absolute symbol.

const MDOperand & getOperand(unsigned I) const

Function & getFunction()

Return the LLVM function that this machine code represents.

Representation of each machine instruction.

const Module * getModule() const

MachineOperand class - Representation of each machine instruction operand.

const GlobalValue * getGlobal() const

bool isReg() const

isReg - Tests if this is a MO_Register operand.

bool isGlobal() const

isGlobal - Tests if this is a MO_GlobalAddress operand.

const char * getSymbolName() const

static std::unique_ptr< MemoryBuffer > getMemBufferCopy(StringRef InputData, const Twine &BufferName="")

Open the specified memory range as a MemoryBuffer, copying the contents and taking ownership of it.

static ErrorOr< std::unique_ptr< MemoryBuffer > > getFile(const Twine &Filename, bool IsText=false, bool RequiresNullTerminator=true, bool IsVolatile=false, std::optional< Align > Alignment=std::nullopt)

Open the specified file as a MemoryBuffer, returning a new MemoryBuffer if successful,...

A Module instance is used to store all the information related to an LLVM module.

void push_back(const T &Elt)

StringRef - Represent a constant reference to a string, i.e.

constexpr StringRef substr(size_t Start, size_t N=npos) const

Return a reference to the substring from [Start, Start + N).

bool starts_with(StringRef Prefix) const

Check if this string starts with the given Prefix.

constexpr bool empty() const

empty - Check if the string is empty.

constexpr size_t size() const

size - Get the string size.

size_t find_first_of(char C, size_t From=0) const

Find the first character in the string that is C, or npos if not found.

Class to represent struct types.

LLVM_ABI StringRef getName() const

Return the name for this struct type if it has an identity.

static SectionKind getKindForGlobal(const GlobalObject *GO, const TargetMachine &TM)

Classify the specified global variable into a set of target independent categories embodied in Sectio...

MCSection * SectionForGlobal(const GlobalObject *GO, SectionKind Kind, const TargetMachine &TM) const

This method computes the appropriate section to emit the specified global variable or function defini...

virtual TargetLoweringObjectFile * getObjFileLowering() const

static Twine utohexstr(uint64_t Val)

LLVM Value Representation.

LLVM_ABI StringRef getName() const

Return a constant reference to the value's name.

#define llvm_unreachable(msg)

Marks that the current location is not supposed to be reachable.

constexpr char Align[]

Key for Kernel::Arg::Metadata::mAlign.

@ VAR_GLOBAL_ALLOCATED

Linkage: ExternalLinkage.

@ VAR_STATIC

Linkage: InternalLinkage.

@ VAR_GLOBAL_EXTERNAL

Linkage: ExternalLinkage.

@ MAX_VLEN

Max # of struct/union/enum members or func args.

@ C

The default llvm calling convention, compatible with C.

StringMapEntry< std::atomic< TypeEntryBody * > > TypeEntry

This is an optimization pass for GlobalISel generic memory operations.

FunctionAddr VTableAddr Value

decltype(auto) dyn_cast(const From &Val)

dyn_cast - Return the argument parameter cast to the specified type.

auto dyn_cast_or_null(const Y &Val)

FunctionAddr VTableAddr Count

class LLVM_GSL_OWNER SmallVector

Forward declaration of SmallVector so that calculateSmallVectorDefaultInlinedElements can reference s...

@ Global

Append to llvm.global_dtors.

decltype(auto) cast(const From &Val)

cast - Return the argument parameter cast to the specified type.

Represent one field relocation.

uint32_t RelocKind

What to patch the instruction.

const MCSymbol * Label

MCSymbol identifying insn for the reloc.

uint32_t OffsetNameOff

The string to traverse types.

Represent one func and its type id.

uint32_t TypeId

Type id referring to .BTF type section.

const MCSymbol * Label

Func MCSymbol.

uint32_t LineOff

line offset in the .BTF string table

MCSymbol * Label

MCSymbol identifying insn for the lineinfo.

uint32_t ColumnNum

the column number

uint32_t FileNameOff

file name offset in the .BTF string table

uint32_t LineNum

the line number

BTF_KIND_ENUM64 is followed by multiple "struct BTFEnum64".

uint32_t NameOff

Enum name offset in the string table.

uint32_t Val_Hi32

Enum member hi32 value.

uint32_t Val_Lo32

Enum member lo32 value.

BTF_KIND_ENUM is followed by multiple "struct BTFEnum".

int32_t Val

Enum member value.

uint32_t NameOff

Enum name offset in the string table.

BTF_KIND_STRUCT and BTF_KIND_UNION are followed by multiple "struct BTFMember".

uint32_t NameOff

Member name offset in the string table.

uint32_t Offset

BitOffset or BitFieldSize+BitOffset.

uint32_t Type

Member type.

BTF_KIND_FUNC_PROTO are followed by multiple "struct BTFParam".