LLVM: lib/MC/ELFObjectWriter.cpp Source File (original) (raw)
1
2
3
4
5
6
7
8
9
10
11
12
50#include
51#include
52#include
53#include
54#include
55#include
56#include
57
58using namespace llvm;
59
60#define DEBUG_TYPE "elf-object-writer"
61
62namespace {
64
65STATISTIC(ELFHeaderBytes, "Total size of ELF headers");
66STATISTIC(SectionHeaderBytes, "Total size of section headers table");
67STATISTIC(AllocTextBytes, "Total size of SHF_ALLOC text sections");
68STATISTIC(AllocROBytes, "Total size of SHF_ALLOC readonly sections");
69STATISTIC(AllocRWBytes, "Total size of SHF_ALLOC read-write sections");
70STATISTIC(StrtabBytes, "Total size of SHT_STRTAB sections");
71STATISTIC(SymtabBytes, "Total size of SHT_SYMTAB sections");
72STATISTIC(RelocationBytes, "Total size of relocation sections");
73STATISTIC(DynsymBytes, "Total size of SHT_DYNSYM sections");
74STATISTIC(DebugBytes, "Total size of debug info sections");
75STATISTIC(UnwindBytes, "Total size of unwind sections");
76STATISTIC(OtherBytes, "Total size of uncategorized sections");
77
78}
79
80struct ELFWriter;
81
84}
85
86class SymbolTableWriter {
87 ELFWriter &EWriter;
88 bool Is64Bit;
89
90
91 std::vector<uint32_t> ShndxIndexes;
92
93
94 unsigned NumWritten;
95
96 void createSymtabShndx();
97
98 template void write(T Value);
99
100public:
101 SymbolTableWriter(ELFWriter &EWriter, bool Is64Bit);
102
105
107};
108
109struct ELFWriter {
112
113 enum DwoMode {
114 AllSections,
115 NonDwoOnly,
116 DwoOnly,
118
121 bool Used, bool Renamed);
122
123
124 struct ELFSymbolData {
129 };
130
131
132
133
134
136
137
138
139
140 unsigned LastLocalSymbolIndex = ~0u;
141
142 unsigned StringTableIndex = ~0u;
143
144 unsigned SymbolTableIndex = ~0u;
145
146
147 std::vector<MCSectionELF *> SectionTable;
148 unsigned addToSectionTable(MCSectionELF *Sec);
149
150
152
154
157 Align Alignment);
158
159public:
161 bool IsLittleEndian, DwoMode Mode)
165
166 void writeWord(uint64_t Word) {
169 else
171 }
172
173 template void write(T Val) {
174 W.write(Val);
175 }
176
177 void writeHeader(const MCAssembler &Asm);
178
179 void writeSymbol(const MCAssembler &Asm, SymbolTableWriter &Writer,
180 uint32_t StringIndex, ELFSymbolData &MSD);
181
182
184
185
186
187
188
189 void computeSymbolTable(MCAssembler &Asm, const RevGroupMapTy &RevGroupMap);
190
191 void writeAddrsigSection();
192
195
196 void writeSectionHeaders(const MCAssembler &Asm);
197
199
204
206
210};
211}
212
216 W.OS.write_zeros(NewOffset - Offset);
217 return NewOffset;
218}
219
220unsigned ELFWriter::addToSectionTable(MCSectionELF *Sec) {
221 SectionTable.push_back(Sec);
222 StrTabBuilder.add(Sec->getName());
223 return SectionTable.size();
224}
225
226void SymbolTableWriter::createSymtabShndx() {
227 if (!ShndxIndexes.empty())
228 return;
229
230 ShndxIndexes.resize(NumWritten);
231}
232
233template void SymbolTableWriter::write(T Value) {
234 EWriter.write(Value);
235}
236
237SymbolTableWriter::SymbolTableWriter(ELFWriter &EWriter, bool Is64Bit)
238 : EWriter(EWriter), Is64Bit(Is64Bit), NumWritten(0) {}
239
244
245 if (LargeIndex)
246 createSymtabShndx();
247
248 if (!ShndxIndexes.empty()) {
249 if (LargeIndex)
250 ShndxIndexes.push_back(shndx);
251 else
252 ShndxIndexes.push_back(0);
253 }
254
256
257 if (Is64Bit) {
260 write(other);
261 write(Index);
263 write(size);
264 } else {
269 write(other);
270 write(Index);
271 }
272
273 ++NumWritten;
274}
275
276bool ELFWriter::is64Bit() const {
278}
279
280
281void ELFWriter::writeHeader(const MCAssembler &Asm) {
282
283
284
285
286
287
288
289
290 W.OS << ELF::ElfMagic;
291
293
294
297
299
303 : OSABI);
304
308
310
312
314
316 writeWord(0);
317 writeWord(0);
318 writeWord(0);
319
320
322
323
326
329
330
333
334
336
337
339 W.write<uint16_t>(StringTableIndex);
340}
341
343 if (Sym.isCommon())
344 return Sym.getCommonAlignment()->value();
345
347 if (.getSymbolOffset(Sym, Res))
348 return 0;
349
350 if (Asm.isThumbFunc(&Sym))
351 Res |= 1;
352
353 return Res;
354}
355
358
359
360
361
362
363
364 switch (origType) {
365 default:
366 break;
371 break;
376 break;
380 break;
385 break;
386 }
387
389}
390
394 if (!Symbol->isVariable() ||
395 !(Value = dyn_cast(Symbol->getVariableValue())) ||
398 return false;
399 Symbol = &cast(Value->getSymbol());
400 }
401 return true;
402}
403
404void ELFWriter::writeSymbol(const MCAssembler &Asm, SymbolTableWriter &Writer,
405 uint32_t StringIndex, ELFSymbolData &MSD) {
406 const auto &Symbol = cast(*MSD.Symbol);
408 cast_or_null(Asm.getBaseSymbol(Symbol));
409
410
411
412 bool IsReserved = || Symbol.isCommon();
413
414
421 }
423
424
425
428
431
432 const MCExpr *ESize = MSD.Symbol->getSize();
433 if (!ESize && Base) {
434
435 ESize = Base->getSize();
436
437
438
439
440
442 while (Sym->isVariable()) {
443 if (auto *Expr =
444 dyn_cast(Sym->getVariableValue(false))) {
445 Sym = cast(&Expr->getSymbol());
446 if (->getSize())
447 continue;
448 ESize = Sym->getSize();
449 }
450 break;
451 }
452 }
453
454 if (ESize) {
455 int64_t Res;
459 }
460
461
462 Writer.writeSymbol(StringIndex, Info, Value, Size, Other, MSD.SectionIndex,
463 IsReserved);
464}
465
467 bool Used, bool Renamed) {
468 if (Symbol.isVariable()) {
469 const MCExpr *Expr = Symbol.getVariableValue();
470
471 if (const auto *T = dyn_cast(Expr))
472 if (T->inlineAssignedExpr())
473 return false;
476 return false;
477 }
478 }
479
480 if (Used)
481 return true;
482
483 if (Renamed)
484 return false;
485
486 if (Symbol.isVariable() && Symbol.isUndefined()) {
487
488 Asm.getBaseSymbol(Symbol);
489 return false;
490 }
491
492 if (Symbol.isTemporary())
493 return false;
494
496 return false;
497
498 return true;
499}
500
501void ELFWriter::computeSymbolTable(MCAssembler &Asm,
502 const RevGroupMapTy &RevGroupMap) {
504 SymbolTableWriter Writer(*this, is64Bit());
505
506
511 SymbolTableIndex = addToSectionTable(SymtabSection);
512
514
515
516 Writer.writeSymbol(0, 0, 0, 0, 0, 0, false);
517
518 std::vector LocalSymbolData;
519 std::vector ExternalSymbolData;
522 for (const std::pair<std::string, size_t> &F : FileNames)
523 StrTabBuilder.add(F.first);
524
525
526 bool HasLargeSectionIndex = false;
528 const auto &Symbol = cast(It.value());
530 bool WeakrefUsed = Symbol.isWeakrefUsedInReloc();
531 bool isSignature = Symbol.isSignature();
532
533 if ((Asm, Symbol, Used || WeakrefUsed || isSignature,
534 OWriter.Renames.count(&Symbol)))
535 continue;
536
537 if (Symbol.isTemporary() && Symbol.isUndefined()) {
539 continue;
540 }
541
542 ELFSymbolData MSD;
543 MSD.Symbol = cast(&Symbol);
544 MSD.Order = It.index();
545
548
549 if (Symbol.isAbsolute()) {
551 } else if (Symbol.isCommon()) {
552 if (Symbol.isTargetCommon()) {
553 MSD.SectionIndex = Symbol.getIndex();
554 } else {
557 }
558 } else if (Symbol.isUndefined()) {
559 if (isSignature && !Used) {
560 MSD.SectionIndex = RevGroupMap.lookup(&Symbol);
562 HasLargeSectionIndex = true;
563 } else {
565 }
566 } else {
569
570
571
572
573
574
575 if (.isRegistered()) {
579 "Undefined section reference: " + Symbol.getName());
580 continue;
581 }
582
583 if (Mode == NonDwoOnly && isDwoSection(Section))
584 continue;
585 MSD.SectionIndex = Section.getOrdinal();
586 assert(MSD.SectionIndex && "Invalid section index!");
588 HasLargeSectionIndex = true;
589 }
590
591
592
593
594
596 if (Name.empty())
597 Name = ".L0 ";
598
599
601 MSD.Name = Name;
602 StrTabBuilder.add(Name);
603 }
604
606 LocalSymbolData.push_back(MSD);
607 else
608 ExternalSymbolData.push_back(MSD);
609 }
610
611
612 unsigned SymtabShndxSectionIndex = 0;
613
614 if (HasLargeSectionIndex) {
617 SymtabShndxSectionIndex = addToSectionTable(SymtabShndxSection);
619 }
620
621 StrTabBuilder.finalize();
622
623
624 unsigned Index = 1;
625 auto FileNameIt = FileNames.begin();
626 if (!FileNames.empty())
627 FileNames[0].second = 0;
628
629 for (ELFSymbolData &MSD : LocalSymbolData) {
630
631 for (; FileNameIt != FileNames.end() && FileNameIt->second <= MSD.Order;
632 ++FileNameIt) {
633 Writer.writeSymbol(StrTabBuilder.getOffset(FileNameIt->first),
637 }
638
639 unsigned StringIndex = MSD.Symbol->getType() == ELF::STT_SECTION
640 ? 0
641 : StrTabBuilder.getOffset(MSD.Name);
642 MSD.Symbol->setIndex(Index++);
643 writeSymbol(Asm, Writer, StringIndex, MSD);
644 }
645 for (; FileNameIt != FileNames.end(); ++FileNameIt) {
646 Writer.writeSymbol(StrTabBuilder.getOffset(FileNameIt->first),
650 }
651
652
653 LastLocalSymbolIndex = Index;
654
655 for (ELFSymbolData &MSD : ExternalSymbolData) {
656 unsigned StringIndex = StrTabBuilder.getOffset(MSD.Name);
657 MSD.Symbol->setIndex(Index++);
658 writeSymbol(Asm, Writer, StringIndex, MSD);
660 }
661
663 SymtabSection->setOffsets(SecStart, SecEnd);
664
666 if (ShndxIndexes.empty()) {
667 assert(SymtabShndxSectionIndex == 0);
668 return;
669 }
670 assert(SymtabShndxSectionIndex != 0);
671
672 SecStart = W.OS.tell();
673 MCSectionELF *SymtabShndxSection = SectionTable[SymtabShndxSectionIndex - 1];
674 for (uint32_t Index : ShndxIndexes)
676 SecEnd = W.OS.tell();
677 SymtabShndxSection->setOffsets(SecStart, SecEnd);
678}
679
680void ELFWriter::writeAddrsigSection() {
682 if (Sym->getIndex() != 0)
684}
685
689 return nullptr;
690
694
697 if (TO && TO->Crel) {
700 1, Sec.getGroup(), &Sec);
701 return RelaSection;
702 }
703
704 const bool Rela = OWriter.usesRela(TO, Sec);
705 unsigned EntrySize;
706 if (Rela)
708 else
710
714 EntrySize, Sec.getGroup(), &Sec);
716 return RelaSection;
717}
718
719
720bool ELFWriter::maybeWriteCompression(
725 if (Size <= HdrSize + CompressedContents.size())
726 return false;
727
729
734 } else {
735
739 }
740 return true;
741}
742
746 auto &Ctx = Asm.getContext();
749 : DebugCompressionType::None;
750 if (CompressionType == DebugCompressionType::None ||
752 Asm.writeSectionData(W.OS, &Section);
753 return;
754 }
755
758 Asm.writeSectionData(VecOS, &Section);
761 UncompressedData.size());
762
765 switch (CompressionType) {
766 case DebugCompressionType::None:
768 case DebugCompressionType::Zlib:
770 break;
771 case DebugCompressionType::Zstd:
773 break;
774 }
776 Compressed);
777 if (!maybeWriteCompression(ChType, UncompressedData.size(), Compressed,
779 W.OS << UncompressedData;
780 return;
781 }
782
784
785
788}
789
798 writeWord(Flags);
799 writeWord(Address);
800 writeWord(Offset);
801 writeWord(Size);
804 writeWord(Alignment ? Alignment->value() : 0);
805 writeWord(EntrySize);
806}
807
808template
810 using uint = std::conditional_t<Is64, uint64_t, uint32_t>;
812 uint32_t SymIdx = R.Symbol ? R.Symbol->getIndex() : 0;
814 std::make_signed_t(R.Addend)};
815 });
816}
817
818void ELFWriter::writeRelocations(const MCAssembler &Asm,
820 std::vector &Relocs = OWriter.Relocations[&Sec];
822 const bool Rela = OWriter.usesRela(TO, Sec);
823
824
826
837 if (Rela)
839 } else {
844 if (Rela)
852 }
859 }
860 }
861 }
862 } else if (TO && TO->Crel) {
864 encodeCrel(Relocs, W.OS);
865 else
866 encodeCrel(Relocs, W.OS);
867 } else {
875 if (Rela)
877 } else {
882 if (Rela)
884 }
885 }
886 }
887}
888
893
894 switch(Section.getType()) {
895 default:
896
897 break;
898
901
905 sh_link = SymbolTableIndex;
906 assert(sh_link && ".symtab not found");
909 break;
910 }
911
913 sh_link = StringTableIndex;
914 sh_info = LastLocalSymbolIndex;
915 break;
916
920 sh_link = SymbolTableIndex;
921 break;
922
924 sh_link = SymbolTableIndex;
925 sh_info = GroupSymbolIndex;
926 break;
927 }
928
930
931
933 if (Sym && Sym->isInSection())
934 sh_link = Sym->getSection().getOrdinal();
935 }
936
937 writeSectionHeaderEntry(StrTabBuilder.getOffset(Section.getName()),
939 Size, sh_link, sh_info, Section.getAlign(),
941}
942
943void ELFWriter::writeSectionHeaders(const MCAssembler &Asm) {
945 const unsigned NumSections = SectionTable.size();
946
947
950 writeSectionHeaderEntry(0, 0, 0, 0, 0, FirstSectionSize, 0, 0, std::nullopt,
951 0);
952
953 for (const MCSectionELF *Section : SectionTable) {
957 GroupSymbolIndex = 0;
958 else
959 GroupSymbolIndex = Section->getGroup()->getIndex();
960
961 std::pair<uint64_t, uint64_t> Offsets = Section->getOffsets();
964 Size = Asm.getSectionAddressSize(*Section);
965 else
967
968 auto SectionHasFlag = [&](uint64_t Flag) -> bool {
970 };
971
972 if (Section->getName().starts_with(".debug")) {
973 stats::DebugBytes += Size;
974 } else if (Section->getName().starts_with(".eh_frame")) {
975 stats::UnwindBytes += Size;
978 stats::AllocTextBytes += Size;
980 stats::AllocRWBytes += Size;
981 } else {
982 stats::AllocROBytes += Size;
983 }
984 } else {
985 switch (Section->getType()) {
987 stats::StrtabBytes += Size;
988 break;
990 stats::SymtabBytes += Size;
991 break;
993 stats::DynsymBytes += Size;
994 break;
998 stats::RelocationBytes += Size;
999 break;
1000 default:
1001 stats::OtherBytes += Size;
1002 break;
1003 }
1004 }
1005
1006 writeSectionHeader(GroupSymbolIndex, Offsets.first, Size, *Section);
1007 }
1008
1009 stats::SectionHeaderBytes += W.OS.tell() - Start;
1010}
1011
1013 uint64_t StartOffset = W.OS.tell();
1014
1018 StringTableIndex = addToSectionTable(StrtabSection);
1019
1020 RevGroupMapTy RevGroupMap;
1021
1022
1023 writeHeader(Asm);
1024
1025 stats::ELFHeaderBytes += W.OS.tell() - StartOffset;
1026
1027
1029
1034 if (Mode == NonDwoOnly && isDwoSection(Section))
1035 continue;
1036 if (Mode == DwoOnly && (Section))
1037 continue;
1038
1039
1041
1043 writeSectionData(Asm, Section);
1044
1046 Section.setOffsets(SecStart, SecEnd);
1047
1048 MCSectionELF *RelSection = createRelocationSection(Ctx, Section);
1049
1050 unsigned *GroupIdxEntry = nullptr;
1051 if (SignatureSymbol) {
1052 GroupIdxEntry = &RevGroupMap[SignatureSymbol];
1053 if (!*GroupIdxEntry) {
1056 *GroupIdxEntry = addToSectionTable(Group);
1058
1059 GroupMap.resize(*GroupIdxEntry + 1);
1060 GroupMap[*GroupIdxEntry] = Groups.size();
1062 }
1063 }
1064
1065 Section.setOrdinal(addToSectionTable(&Section));
1066 if (RelSection) {
1067 RelSection->setOrdinal(addToSectionTable(RelSection));
1068 Relocations.push_back(RelSection);
1069 }
1070
1071 if (GroupIdxEntry) {
1072 auto &Members = Groups[GroupMap[*GroupIdxEntry]];
1073 Members.second.push_back(Section.getOrdinal());
1074 if (RelSection)
1075 Members.second.push_back(RelSection->getOrdinal());
1076 }
1077 }
1078
1079 for (auto &[Group, Members] : Groups) {
1080
1082
1084 W.write<unsigned>(Members);
1085
1087 Group->setOffsets(SecStart, SecEnd);
1088 }
1089
1090 if (Mode == DwoOnly) {
1091
1092
1093 StrTabBuilder.finalize();
1094 } else {
1099 addToSectionTable(AddrsigSection);
1100 }
1101
1102
1103 computeSymbolTable(Asm, RevGroupMap);
1104
1105 for (MCSectionELF *RelSection : Relocations) {
1106
1108
1109 writeRelocations(Asm,
1111
1113 RelSection->setOffsets(SecStart, SecEnd);
1114 }
1115
1117 uint64_t SecStart = W.OS.tell();
1118 writeAddrsigSection();
1120 AddrsigSection->setOffsets(SecStart, SecEnd);
1121 }
1122 }
1123
1124 {
1125 uint64_t SecStart = W.OS.tell();
1126 StrTabBuilder.write(W.OS);
1127 StrtabSection->setOffsets(SecStart, W.OS.tell());
1128 }
1129
1131
1132
1133 writeSectionHeaders(Asm);
1134
1135 uint16_t NumSections = support::endian::byte_swap<uint16_t>(
1137 : SectionTable.size() + 1,
1138 W.Endian);
1139 unsigned NumSectionsOffset;
1140
1144 support::endian::byte_swap<uint64_t>(SectionHeaderOffset, W.Endian);
1145 Stream.pwrite(reinterpret_cast<char *>(&Val), sizeof(Val),
1148 } else {
1150 support::endian::byte_swap<uint32_t>(SectionHeaderOffset, W.Endian);
1151 Stream.pwrite(reinterpret_cast<char *>(&Val), sizeof(Val),
1154 }
1155 Stream.pwrite(reinterpret_cast<char *>(&NumSections), sizeof(NumSections),
1156 NumSectionsOffset);
1157
1158 return W.OS.tell() - StartOffset;
1159}
1160
1163 : TargetObjectWriter(std::move(MOTW)), OS(OS),
1164 IsLittleEndian(IsLittleEndian) {}
1168 : TargetObjectWriter(std::move(MOTW)), OS(OS), DwoOS(&DwoOS),
1169 IsLittleEndian(IsLittleEndian) {}
1170
1172 ELFHeaderEFlags = 0;
1179}
1180
1183}
1184
1186
1187
1190 const auto &Symbol = cast(*S.Sym);
1191 size_t Pos = AliasName.find('@');
1193
1198 Tail = Rest.substr(Symbol.isUndefined() ? 2 : 1);
1199
1200 auto *Alias =
1201 cast(Asm.getContext().getOrCreateSymbol(Prefix + Tail));
1202 Asm.registerSymbol(*Alias);
1204 Alias->setVariableValue(Value);
1205
1206
1207
1208 Alias->setBinding(Symbol.getBinding());
1209 Alias->setVisibility(Symbol.getVisibility());
1210 Alias->setOther(Symbol.getOther());
1211
1212 if (!Symbol.isUndefined() && S.KeepOriginalSym)
1213 continue;
1214
1215 if (Symbol.isUndefined() && Rest.starts_with("@@") &&
1217 Asm.getContext().reportError(S.Loc, "default version symbol " +
1218 AliasName + " must be defined");
1219 continue;
1220 }
1221
1222 if (auto It = Renames.find(&Symbol);
1223 It != Renames.end() && It->second != Alias) {
1224 Asm.getContext().reportError(S.Loc, Twine("multiple versions for ") +
1225 Symbol.getName());
1226 continue;
1227 }
1228
1229 Renames.insert(std::make_pair(&Symbol, Alias));
1230 }
1231
1234 Sym = R;
1235 if (Sym->isInSection() && Sym->getName().starts_with(".L"))
1236 Sym = Sym->getSection().getBeginSymbol();
1237 Sym->setUsedInReloc();
1238 }
1239}
1240
1241
1242
1243
1248 unsigned Type) const {
1250
1251
1252 if (!RefA)
1253 return false;
1254
1256 switch (Kind) {
1257 default:
1258 break;
1259
1260
1261
1262
1263
1264
1266 return false;
1267
1268
1269
1270
1271
1279 return true;
1280 }
1281
1282
1283
1284 assert(Sym && "Expected a symbol");
1285 if (Sym->isUndefined())
1286 return true;
1287
1288
1289
1290
1291
1292
1293
1294 if (Sym->isMemtag())
1295 return true;
1296
1297 unsigned Binding = Sym->getBinding();
1298 switch(Binding) {
1299 default:
1302 break;
1304
1305
1306
1307 return true;
1310
1311
1312 return true;
1313 }
1314
1315
1316
1317
1319 return true;
1320
1321
1322
1323
1324
1325
1326
1327
1328 if (Sym->isInSection()) {
1329 auto &Sec = cast(Sym->getSection());
1330 unsigned Flags = Sec.getFlags();
1332 if (C != 0)
1333 return true;
1334
1335
1336
1338 Type == ELF::R_386_GOTOFF)
1339 return true;
1340
1341
1342
1343
1344
1345
1346
1347
1350 return true;
1351 }
1352
1353
1354
1355
1356
1358 return true;
1359 }
1360
1361
1362
1363
1364
1365 if (Asm.isThumbFunc(Sym))
1366 return true;
1367
1369 return true;
1370 return false;
1371}
1372
1378 Ctx.reportError(Loc, "A dwo section may not contain relocations");
1379 return false;
1380 }
1382 Ctx.reportError(Loc, "A relocation may not refer to a dwo section");
1383 return false;
1384 }
1385 }
1386 return true;
1387}
1388
1398 uint64_t FixupOffset = Asm.getFragmentOffset(*Fragment) + Fixup.getOffset();
1399 MCContext &Ctx = Asm.getContext();
1401
1403 const auto &SymB = cast(RefB->getSymbol());
1404 if (SymB.isUndefined()) {
1406 Twine("symbol '") + SymB.getName() +
1407 "' can not be undefined in a subtraction expression");
1408 return;
1409 }
1410
1411 assert(!SymB.isAbsolute() && "Should have been folded");
1412 const MCSection &SecB = SymB.getSection();
1413 if (&SecB != &FixupSection) {
1415 "Cannot represent a difference across sections");
1416 return;
1417 }
1418
1419 assert(!IsPCRel && "should have been folded");
1420 IsPCRel = true;
1421 C += FixupOffset - Asm.getSymbolOffset(SymB);
1422 }
1423
1424
1426 const auto *SymA = RefA ? cast(&RefA->getSymbol()) : nullptr;
1427
1428 bool ViaWeakRef = false;
1429 if (SymA && SymA->isVariable()) {
1430 const MCExpr *Expr = SymA->getVariableValue();
1431 if (const auto *Inner = dyn_cast(Expr)) {
1433 SymA = cast(&Inner->getSymbol());
1434 ViaWeakRef = true;
1435 }
1436 }
1437 }
1438
1439 const MCSectionELF *SecA = (SymA && SymA->isInSection())
1440 ? cast(&SymA->getSection())
1441 : nullptr;
1443 return;
1444
1446 const auto *Parent = cast(Fragment->getParent());
1447
1448 bool RelocateWithSymbol =
1451 uint64_t Addend = !RelocateWithSymbol && SymA && !SymA->isUndefined()
1452 ? C + Asm.getSymbolOffset(*SymA)
1453 : C;
1454 FixedValue = usesRela(TO, FixupSection) ? 0 : Addend;
1455
1456 if (!RelocateWithSymbol) {
1457 const auto *SectionSymbol =
1458 SecA ? cast(SecA->getBeginSymbol()) : nullptr;
1459 if (SectionSymbol)
1460 SectionSymbol->setUsedInReloc();
1462 Relocations[&FixupSection].push_back(Rec);
1463 return;
1464 }
1465
1467 if (SymA) {
1469 RenamedSymA = R;
1470
1471 if (ViaWeakRef)
1473 else
1475 }
1477 Relocations[&FixupSection].push_back(Rec);
1478}
1479
1484 (TO && TO->Crel);
1485}
1486
1489 bool InSet, bool IsPCRel) const {
1490 const auto &SymA = cast(SA);
1491 if (IsPCRel) {
1495 return false;
1496 }
1497 return &SymA.getSection() == FB.getParent();
1498}
1499
1503 DwoOS ? ELFWriter::NonDwoOnly : ELFWriter::AllSections)
1504 .writeObject(Asm);
1507 .writeObject(Asm);
1508 return Size;
1509}
#define offsetof(TYPE, MEMBER)
BlockVerifier::State From
Analysis containing CSE Info
Given that RA is a live value
This file defines the DenseMap class.
static uint8_t mergeTypeForSet(uint8_t origType, uint8_t newType)
static void encodeCrel(ArrayRef< ELFRelocationEntry > Relocs, raw_ostream &OS)
static bool isIFunc(const MCSymbolELF *Symbol)
std::optional< std::vector< StOtherPiece > > Other
PowerPC TLS Dynamic Call Fixup
assert(ImpDefSCC.getReg()==AMDGPU::SCC &&ImpDefSCC.isDef())
This file defines the SmallVector class.
This file defines the 'Statistic' class, which is designed to be an easy way to expose various metric...
#define STATISTIC(VARNAME, DESC)
static SymbolRef::Type getType(const Symbol *Sym)
static bool isInSymtab(const MCSymbolWasm &Sym)
static bool isDwoSection(const MCSection &Sec)
static bool is64Bit(const char *name)
static const X86InstrFMA3Group Groups[]
ArrayRef - Represent a constant reference to an array (0 or more elements consecutively in memory),...
bool empty() const
empty - Check if the array is empty.
std::unique_ptr< MCELFObjectTargetWriter > TargetObjectWriter
ELFObjectWriter(std::unique_ptr< MCELFObjectTargetWriter > MOTW, raw_pwrite_stream &OS, bool IsLittleEndian)
unsigned getELFHeaderEFlags() const
bool shouldRelocateWithSymbol(const MCAssembler &Asm, const MCValue &Val, const MCSymbolELF *Sym, uint64_t C, unsigned Type) const
uint64_t writeObject(MCAssembler &Asm) override
Write the object file and returns the number of bytes written.
void executePostLayoutBinding(MCAssembler &Asm) override
Perform any late binding of symbols (for example, to assign symbol indices for use when generating re...
void reset() override
lifetime management
std::optional< uint8_t > OverrideABIVersion
void recordRelocation(MCAssembler &Asm, const MCFragment *Fragment, const MCFixup &Fixup, MCValue Target, uint64_t &FixedValue) override
Record a relocation entry.
DenseMap< const MCSectionELF *, std::vector< ELFRelocationEntry > > Relocations
SmallVector< Symver, 0 > Symvers
bool isSymbolRefDifferenceFullyResolvedImpl(const MCAssembler &Asm, const MCSymbol &SymA, const MCFragment &FB, bool InSet, bool IsPCRel) const override
bool hasRelocationAddend() const
bool checkRelocation(MCContext &Ctx, SMLoc Loc, const MCSectionELF *From, const MCSectionELF *To)
raw_pwrite_stream * DwoOS
bool usesRela(const MCTargetOptions *TO, const MCSectionELF &Sec) const
DenseMap< const MCSymbolELF *, const MCSymbolELF * > Renames
Generic interface to target specific assembler backends.
virtual const MCFixupKindInfo & getFixupKindInfo(MCFixupKind Kind) const
Get information on a fixup kind.
Context object for machine code objects.
MCSectionELF * createELFRelSection(const Twine &Name, unsigned Type, unsigned Flags, unsigned EntrySize, const MCSymbolELF *Group, const MCSectionELF *RelInfoSection)
MCSectionELF * getELFSection(const Twine &Section, unsigned Type, unsigned Flags)
void reportError(SMLoc L, const Twine &Msg)
const MCTargetOptions * getTargetOptions() const
MCSectionELF * createELFGroupSection(const MCSymbolELF *Group, bool IsComdat)
Base class for the full range of assembler expressions which are needed for parsing.
bool evaluateKnownAbsolute(int64_t &Res, const MCAssembler &Asm) const
Aggressive variant of evaluateAsRelocatable when relocations are unavailable (e.g.
Encode information on a single operation to perform on a byte sequence (e.g., an encoded instruction)...
MCSection * getParent() const
MutableArrayRef< std::pair< std::string, size_t > > getFileNames()
bool getEmitAddrsigSection()
std::vector< const MCSymbol * > & getAddrsigSyms()
virtual void reset()
lifetime management
std::vector< const MCSymbol * > AddrsigSyms
This represents a section on linux, lots of unix variants and some bare metal systems.
const MCSection * getLinkedToSection() const
unsigned getFlags() const
void setOffsets(uint64_t Start, uint64_t End)
const MCSymbolELF * getGroup() const
Instances of this class represent a uniqued identifier for a section in the current translation unit.
void setAlignment(Align Value)
unsigned getOrdinal() const
void setOrdinal(unsigned Value)
StringRef getName() const
MCSymbol * getBeginSymbol()
void setIsWeakrefUsedInReloc() const
Represent a reference to a symbol from inside an expression.
const MCSymbol & getSymbol() const
static const MCSymbolRefExpr * create(const MCSymbol *Symbol, MCContext &Ctx)
VariantKind getKind() const
MCSymbol - Instances of this class represent a symbol name in the MC file, and MCSymbols are created ...
void setUsedInReloc() const
DebugCompressionType CompressDebugSections
This represents an "assembler immediate".
const MCSymbolRefExpr * getSymA() const
MutableArrayRef - Represent a mutable reference to an array (0 or more elements consecutively in memo...
Represents a location in source code.
This class consists of common code factored out of the SmallVector class to reduce code duplication b...
void push_back(const T &Elt)
pointer data()
Return a pointer to the vector's buffer, even if empty().
This is a 'vector' (really, a variable-sized array), optimized for the case when the array is small.
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.
size_t find(char C, size_t From=0) const
Search for the first character C in the string.
bool ends_with(StringRef Suffix) const
Check if this string ends with the given Suffix.
static constexpr size_t npos
Utility for building string tables with deduplicated suffixes.
Target - Wrapper for Target specific information.
Twine - A lightweight data structure for efficiently representing the concatenation of temporary valu...
The instances of the Type class are immutable: once they are created, they are never changed.
LLVM Value Representation.
This class implements an extremely fast bulk output stream that can only output to a stream.
An abstract base class for streams implementations that also support a pwrite operation.
A raw_ostream that writes to an SmallVector or SmallString.
#define llvm_unreachable(msg)
Marks that the current location is not supposed to be reachable.
@ Tail
Attemps to make calls as fast as possible while guaranteeing that tail call optimization can always b...
@ C
The default llvm calling convention, compatible with C.
static const char ElfMagic[]
@ SHT_LLVM_CALL_GRAPH_PROFILE
Flag
These should be considered private to the implementation of the MCInstrDesc class.
Offsets
Offsets in bytes from the start of the input buffer.
void compress(Params P, ArrayRef< uint8_t > Input, SmallVectorImpl< uint8_t > &Output)
StringRef toStringRef(const std::optional< DWARFFormValue > &V, StringRef Default={})
Take an optional DWARFFormValue and try to extract a string value from it.
support::ulittle32_t Word
This is an optimization pass for GlobalISel generic memory operations.
auto enumerate(FirstRange &&First, RestRanges &&...Rest)
Given two or more input ranges, returns a new range whose values are tuples (A, B,...
Error write(MCStreamer &Out, ArrayRef< std::string > Inputs, OnCuIndexOverflow OverflowOptValue)
void report_fatal_error(Error Err, bool gen_crash_diag=true)
Report a serious error, calling any installed error handler.
@ Ref
The access may reference the value stored in memory.
uint64_t alignTo(uint64_t Size, Align A)
Returns a multiple of A needed to store Size bytes.
OutputIt move(R &&Range, OutputIt Out)
Provide wrappers to std::move which take ranges instead of having to pass begin/end explicitly.
unsigned encodeULEB128(uint64_t Value, raw_ostream &OS, unsigned PadTo=0)
Utility function to encode a ULEB128 value to an output stream.
Implement std::hash so that hash_code can be used in STL containers.
This struct is a compact representation of a valid (non-zero power of two) alignment.
uint64_t value() const
This is a hole in the type system and should not be abused.
void setSymbolAndType(Elf32_Word s, unsigned char t)
void setSymbolAndType(Elf64_Word s, Elf64_Word t)
@ FKF_IsPCRel
Is this fixup kind PCrelative? This is used by the assembler backend to evaluate fixup values in a ta...
unsigned Flags
Flags describing additional information on this fixup kind.
This struct is a compact representation of a valid (power of two) or undefined (0) alignment.
Adapter to write values to a stream in a particular byte order.