64 #define DEBUG_TYPE "reloc-info"
70 class ELFObjectWriter;
77 class SymbolTableWriter {
82 std::vector<uint32_t> ShndxIndexes;
87 void createSymtabShndx();
92 SymbolTableWriter(ELFWriter &EWriter,
bool Is64Bit);
101 ELFObjectWriter &OWriter;
112 bool Used,
bool Renamed);
115 struct ELFSymbolData {
131 unsigned LastLocalSymbolIndex;
133 unsigned StringTableIndex;
135 unsigned SymbolTableIndex;
138 std::vector<const MCSectionELF *> SectionTable;
153 bool IsLittleEndian, DwoMode
Mode)
164 template <
typename T>
void write(
T Val) {
170 void writeSymbol(SymbolTableWriter &Writer,
uint32_t StringIndex,
174 using SectionOffsetsTy =
175 std::map<const MCSectionELF *, std::pair<uint64_t, uint64_t>>;
186 const SectionIndexMapTy &SectionIndexMap,
187 const RevGroupMapTy &RevGroupMap,
188 SectionOffsetsTy &SectionOffsets);
190 void writeAddrsigSection();
198 const SectionIndexMapTy &SectionIndexMap,
199 const SectionOffsetsTy &SectionOffsets);
212 void writeSection(
const SectionIndexMapTy &SectionIndexMap,
219 std::unique_ptr<MCELFObjectTargetWriter> TargetObjectWriter;
225 bool SeenGnuAbi =
false;
227 bool hasRelocationAddend()
const;
232 unsigned Type)
const;
235 ELFObjectWriter(std::unique_ptr<MCELFObjectTargetWriter> MOTW)
238 void reset()
override {
245 bool isSymbolRefDifferenceFullyResolvedImpl(
const MCAssembler &
Asm,
248 bool IsPCRel)
const override;
263 void markGnuAbi()
override { SeenGnuAbi =
true; }
264 bool seenGnuAbi()
const {
return SeenGnuAbi; }
266 friend struct ELFWriter;
269 class ELFSingleObjectWriter :
public ELFObjectWriter {
274 ELFSingleObjectWriter(std::unique_ptr<MCELFObjectTargetWriter> MOTW,
276 : ELFObjectWriter(
std::move(MOTW)), OS(OS),
277 IsLittleEndian(IsLittleEndian) {}
280 return ELFWriter(*
this, OS, IsLittleEndian, ELFWriter::AllSections)
281 .writeObject(
Asm, Layout);
284 friend struct ELFWriter;
287 class ELFDwoObjectWriter :
public ELFObjectWriter {
292 ELFDwoObjectWriter(std::unique_ptr<MCELFObjectTargetWriter> MOTW,
295 : ELFObjectWriter(
std::move(MOTW)), OS(OS), DwoOS(DwoOS),
296 IsLittleEndian(IsLittleEndian) {}
300 if (isDwoSection(*
From)) {
301 Ctx.
reportError(Loc,
"A dwo section may not contain relocations");
304 if (To && isDwoSection(*To)) {
305 Ctx.
reportError(Loc,
"A relocation may not refer to a dwo section");
312 uint64_t Size = ELFWriter(*
this, OS, IsLittleEndian, ELFWriter::NonDwoOnly)
313 .writeObject(
Asm, Layout);
314 Size += ELFWriter(*
this, DwoOS, IsLittleEndian, ELFWriter::DwoOnly)
315 .writeObject(
Asm, Layout);
325 W.OS.write_zeros(NewOffset -
Offset);
329 unsigned ELFWriter::addToSectionTable(
const MCSectionELF *Sec) {
330 SectionTable.push_back(Sec);
331 StrTabBuilder.add(Sec->
getName());
332 return SectionTable.size();
335 void SymbolTableWriter::createSymtabShndx() {
336 if (!ShndxIndexes.empty())
339 ShndxIndexes.resize(NumWritten);
343 EWriter.write(
Value);
346 SymbolTableWriter::SymbolTableWriter(ELFWriter &EWriter,
bool Is64Bit)
347 : EWriter(EWriter), Is64Bit(Is64Bit), NumWritten(0) {}
357 if (!ShndxIndexes.empty()) {
359 ShndxIndexes.push_back(shndx);
361 ShndxIndexes.push_back(0);
386 return OWriter.TargetObjectWriter->is64Bit();
389 bool ELFWriter::usesRela(
const MCSectionELF &Sec)
const {
390 return OWriter.hasRelocationAddend() &&
414 uint8_t OSABI = OWriter.TargetObjectWriter->getOSABI();
419 W.OS << char(OWriter.TargetObjectWriter->getABIVersion());
425 W.write<
uint16_t>(OWriter.TargetObjectWriter->getEMachine());
470 uint8_t
Type = newType;
507 if (!
Symbol->isVariable() ||
508 !(
Value = dyn_cast<MCSymbolRefExpr>(
Symbol->getVariableValue())) ||
509 Value->getKind() != MCSymbolRefExpr::VK_None ||
517 void ELFWriter::writeSymbol(SymbolTableWriter &Writer,
uint32_t StringIndex,
519 const auto &
Symbol = cast<MCSymbolELF>(*MSD.Symbol);
528 uint8_t Binding =
Symbol.getBinding();
535 uint8_t
Info = (Binding << 4) |
Type;
539 uint8_t Visibility =
Symbol.getVisibility();
545 const MCExpr *ESize = MSD.Symbol->getSize();
546 if (!ESize &&
Base) {
548 ESize =
Base->getSize();
558 Sym = cast<MCSymbolELF>(&Expr->getSymbol());
580 bool Used,
bool Renamed) {
581 if (
Symbol.isVariable()) {
584 if (
const auto *
T = dyn_cast<MCTargetExpr>(Expr))
585 if (
T->inlineAssignedExpr())
588 if (
Ref->getKind() == MCSymbolRefExpr::VK_WEAKREF)
617 const auto &SymE = cast<MCSymbolELF>(Sym);
618 if (!SymE.isMemtag())
620 if (MemtagRelocs ==
nullptr) {
621 MemtagRelocs = OWriter.TargetObjectWriter->getMemtagRelocsSection(
Asm.getContext());
622 if (MemtagRelocs ==
nullptr)
624 Asm.registerSection(*MemtagRelocs);
627 OWriter.Relocations[MemtagRelocs].push_back(Rec);
631 void ELFWriter::computeSymbolTable(
633 const SectionIndexMapTy &SectionIndexMap,
const RevGroupMapTy &RevGroupMap,
634 SectionOffsetsTy &SectionOffsets) {
636 SymbolTableWriter Writer(*
this,
is64Bit());
643 SymbolTableIndex = addToSectionTable(SymtabSection);
648 Writer.writeSymbol(0, 0, 0, 0, 0, 0,
false);
650 std::vector<ELFSymbolData> LocalSymbolData;
651 std::vector<ELFSymbolData> ExternalSymbolData;
654 for (
const std::pair<std::string, size_t> &
F : FileNames)
655 StrTabBuilder.add(
F.first);
658 bool HasLargeSectionIndex =
false;
660 const auto &
Symbol = cast<MCSymbolELF>(It.value());
662 bool WeakrefUsed =
Symbol.isWeakrefUsedInReloc();
663 bool isSignature =
Symbol.isSignature();
666 OWriter.Renames.count(&
Symbol)))
675 MSD.Symbol = cast<MCSymbolELF>(&
Symbol);
676 MSD.Order = It.index();
681 if (
Symbol.isAbsolute()) {
683 }
else if (
Symbol.isCommon()) {
684 if (
Symbol.isTargetCommon()) {
685 MSD.SectionIndex =
Symbol.getIndex();
690 }
else if (
Symbol.isUndefined()) {
691 if (isSignature && !Used) {
692 MSD.SectionIndex = RevGroupMap.lookup(&
Symbol);
694 HasLargeSectionIndex =
true;
711 "Undefined section reference: " +
Symbol.getName());
717 MSD.SectionIndex = SectionIndexMap.lookup(&
Section);
718 assert(MSD.SectionIndex &&
"Invalid section index!");
720 HasLargeSectionIndex =
true;
728 StrTabBuilder.add(
Name);
732 LocalSymbolData.push_back(MSD);
734 ExternalSymbolData.push_back(MSD);
738 unsigned SymtabShndxSectionIndex = 0;
740 if (HasLargeSectionIndex) {
743 SymtabShndxSectionIndex = addToSectionTable(SymtabShndxSection);
747 StrTabBuilder.finalize();
751 auto FileNameIt = FileNames.begin();
752 if (!FileNames.empty())
753 FileNames[0].second = 0;
755 for (ELFSymbolData &MSD : LocalSymbolData) {
757 for (; FileNameIt != FileNames.end() && FileNameIt->second <= MSD.Order;
759 Writer.writeSymbol(StrTabBuilder.getOffset(FileNameIt->first),
767 : StrTabBuilder.getOffset(MSD.Name);
768 MSD.Symbol->setIndex(
Index++);
769 writeSymbol(Writer, StringIndex, MSD, Layout);
771 for (; FileNameIt != FileNames.end(); ++FileNameIt) {
772 Writer.writeSymbol(StrTabBuilder.getOffset(FileNameIt->first),
779 LastLocalSymbolIndex =
Index;
781 for (ELFSymbolData &MSD : ExternalSymbolData) {
782 unsigned StringIndex = StrTabBuilder.getOffset(MSD.Name);
783 MSD.Symbol->setIndex(
Index++);
784 writeSymbol(Writer, StringIndex, MSD, Layout);
789 SectionOffsets[SymtabSection] = std::make_pair(SecStart, SecEnd);
792 if (ShndxIndexes.
empty()) {
793 assert(SymtabShndxSectionIndex == 0);
796 assert(SymtabShndxSectionIndex != 0);
798 SecStart =
W.OS.tell();
800 SectionTable[SymtabShndxSectionIndex - 1];
803 SecEnd =
W.OS.tell();
804 SectionOffsets[SymtabShndxSection] = std::make_pair(SecStart, SecEnd);
807 void ELFWriter::writeAddrsigSection() {
808 for (
const MCSymbol *Sym : OWriter.AddrsigSyms)
815 if (OWriter.Relocations[&Sec].empty())
819 bool Rela = usesRela(Sec);
820 std::string RelaSectionName = Rela ?
".rela" :
".rel";
841 bool ELFWriter::maybeWriteCompression(
846 if (
Size <= HdrSize + CompressedContents.size())
869 auto &MC =
Asm.getContext();
870 const auto &MAI = MC.getAsmInfo();
881 Asm.writeSectionData(VecOS, &
Section, Layout);
883 ArrayRef(
reinterpret_cast<uint8_t *
>(UncompressedData.data()),
884 UncompressedData.size());
888 switch (CompressionType) {
891 case DebugCompressionType::Zlib:
894 case DebugCompressionType::Zstd:
900 if (!maybeWriteCompression(ChType, UncompressedData.size(), Compressed,
902 W.OS << UncompressedData;
925 WriteWord(Alignment ? Alignment->value() : 0);
926 WriteWord(EntrySize);
931 std::vector<ELFRelocationEntry> &Relocs = OWriter.Relocations[&Sec];
940 OWriter.TargetObjectWriter->sortRelocs(
Asm, Relocs);
942 const bool Rela = usesRela(Sec);
943 for (
unsigned i = 0,
e = Relocs.size();
i !=
e; ++
i) {
945 unsigned Index = Entry.Symbol ? Entry.Symbol->getIndex() : 0;
949 if (OWriter.TargetObjectWriter->getEMachine() ==
ELF::EM_MIPS) {
952 write(OWriter.TargetObjectWriter->getRSsym(Entry.Type));
953 write(OWriter.TargetObjectWriter->getRType3(Entry.Type));
954 write(OWriter.TargetObjectWriter->getRType2(Entry.Type));
955 write(OWriter.TargetObjectWriter->getRType(Entry.Type));
973 if (OWriter.TargetObjectWriter->getEMachine() ==
ELF::EM_MIPS) {
975 OWriter.TargetObjectWriter->getRType2(Entry.Type)) {
978 ERE32.setSymbolAndType(0, RType);
983 OWriter.TargetObjectWriter->getRType3(Entry.Type)) {
986 ERE32.setSymbolAndType(0, RType);
995 void ELFWriter::writeSection(
const SectionIndexMapTy &SectionIndexMap,
1011 sh_link = SymbolTableIndex;
1012 assert(sh_link &&
".symtab not found");
1014 sh_info = SectionIndexMap.lookup(cast<MCSectionELF>(InfoSection));
1019 sh_link = StringTableIndex;
1020 sh_info = LastLocalSymbolIndex;
1026 sh_link = SymbolTableIndex;
1030 sh_link = SymbolTableIndex;
1031 sh_info = GroupSymbolIndex;
1041 sh_link = SectionIndexMap.lookup(Sec);
1045 WriteSecHdrEntry(StrTabBuilder.getOffset(
Section.getName()),
1047 sh_link, sh_info,
Section.getAlign(),
1051 void ELFWriter::writeSectionHeader(
1052 const MCAsmLayout &Layout,
const SectionIndexMapTy &SectionIndexMap,
1053 const SectionOffsetsTy &SectionOffsets) {
1054 const unsigned NumSections = SectionTable.size();
1059 WriteSecHdrEntry(0, 0, 0, 0, 0, FirstSectionSize, 0, 0, std::nullopt, 0);
1065 GroupSymbolIndex = 0;
1067 GroupSymbolIndex =
Section->getGroup()->getIndex();
1069 const std::pair<uint64_t, uint64_t> &
Offsets =
1070 SectionOffsets.find(
Section)->second;
1077 writeSection(SectionIndexMap, GroupSymbolIndex,
Offsets.first,
Size,
1088 StringTableIndex = addToSectionTable(StrtabSection);
1090 createMemtagRelocs(
Asm);
1092 RevGroupMapTy RevGroupMap;
1093 SectionIndexMapTy SectionIndexMap;
1095 std::map<const MCSymbol *, std::vector<const MCSectionELF *>> GroupMembers;
1101 SectionOffsetsTy SectionOffsets;
1102 std::vector<MCSectionELF *>
Groups;
1103 std::vector<MCSectionELF *> Relocations;
1118 SectionOffsets[&
Section] = std::make_pair(SecStart, SecEnd);
1122 if (SignatureSymbol) {
1123 unsigned &GroupIdx = RevGroupMap[SignatureSymbol];
1127 GroupIdx = addToSectionTable(Group);
1131 std::vector<const MCSectionELF *> &Members =
1132 GroupMembers[SignatureSymbol];
1135 Members.push_back(RelSection);
1140 SectionIndexMap[RelSection] = addToSectionTable(RelSection);
1141 Relocations.push_back(RelSection);
1144 OWriter.TargetObjectWriter->addTargetSectionFlags(Ctx,
Section);
1154 for (
const MCSectionELF *Member : GroupMembers[SignatureSymbol]) {
1155 uint32_t SecIndex = SectionIndexMap.lookup(Member);
1160 SectionOffsets[Group] = std::make_pair(SecStart, SecEnd);
1163 if (
Mode == DwoOnly) {
1166 StrTabBuilder.finalize();
1169 if (OWriter.EmitAddrsigSection) {
1172 addToSectionTable(AddrsigSection);
1176 computeSymbolTable(
Asm, Layout, SectionIndexMap, RevGroupMap,
1183 writeRelocations(
Asm,
1187 SectionOffsets[RelSection] = std::make_pair(SecStart, SecEnd);
1190 if (OWriter.EmitAddrsigSection) {
1192 writeAddrsigSection();
1194 SectionOffsets[AddrsigSection] = std::make_pair(SecStart, SecEnd);
1200 StrTabBuilder.write(
W.OS);
1201 SectionOffsets[StrtabSection] = std::make_pair(SecStart,
W.OS.tell());
1207 writeSectionHeader(Layout, SectionIndexMap, SectionOffsets);
1209 uint16_t NumSections = support::endian::byte_swap<uint16_t>(
1211 : SectionTable.size() + 1,
1213 unsigned NumSectionsOffset;
1218 support::endian::byte_swap<uint64_t>(SectionHeaderOffset,
W.Endian);
1219 Stream.pwrite(
reinterpret_cast<char *
>(&Val),
sizeof(Val),
1224 support::endian::byte_swap<uint32_t>(SectionHeaderOffset,
W.Endian);
1225 Stream.pwrite(
reinterpret_cast<char *
>(&Val),
sizeof(Val),
1229 Stream.pwrite(
reinterpret_cast<char *
>(&NumSections),
sizeof(NumSections),
1232 return W.OS.tell() - StartOffset;
1235 bool ELFObjectWriter::hasRelocationAddend()
const {
1236 return TargetObjectWriter->hasRelocationAddend();
1245 const auto &
Symbol = cast<MCSymbolELF>(*
S.Sym);
1246 size_t Pos = AliasName.
find(
'@');
1247 assert(Pos != StringRef::npos);
1256 cast<MCSymbolELF>(
Asm.getContext().getOrCreateSymbol(
Prefix +
Tail));
1257 Asm.registerSymbol(*Alias);
1259 Alias->setVariableValue(
Value);
1263 Alias->setBinding(
Symbol.getBinding());
1264 Alias->setVisibility(
Symbol.getVisibility());
1265 Alias->setOther(
Symbol.getOther());
1267 if (!
Symbol.isUndefined() &&
S.KeepOriginalSym)
1272 Asm.getContext().reportError(
S.Loc,
"default version symbol " +
1273 AliasName +
" must be defined");
1277 if (Renames.count(&
Symbol) && Renames[&
Symbol] != Alias) {
1278 Asm.getContext().reportError(
S.Loc,
Twine(
"multiple versions for ") +
1283 Renames.insert(std::make_pair(&
Symbol, Alias));
1286 for (
const MCSymbol *&Sym : AddrsigSyms) {
1287 if (
const MCSymbol *
R = Renames.lookup(cast<MCSymbolELF>(Sym)))
1298 bool ELFObjectWriter::shouldRelocateWithSymbol(
const MCAssembler &
Asm,
1302 unsigned Type)
const {
1318 case MCSymbolRefExpr::VK_PPC_TOCBASE:
1325 case MCSymbolRefExpr::VK_GOT:
1326 case MCSymbolRefExpr::VK_PLT:
1327 case MCSymbolRefExpr::VK_GOTPCREL:
1328 case MCSymbolRefExpr::VK_GOTPCREL_NORELAX:
1329 case MCSymbolRefExpr::VK_PPC_GOT_LO:
1330 case MCSymbolRefExpr::VK_PPC_GOT_HI:
1331 case MCSymbolRefExpr::VK_PPC_GOT_HA:
1337 assert(Sym &&
"Expected a symbol");
1382 auto &Sec = cast<MCSectionELF>(Sym->
getSection());
1390 if (TargetObjectWriter->getEMachine() ==
ELF::EM_386 &&
1391 Type == ELF::R_386_GOTOFF)
1401 if (TargetObjectWriter->getEMachine() ==
ELF::EM_MIPS &&
1402 !hasRelocationAddend())
1418 if (
Asm.isThumbFunc(Sym))
1421 if (TargetObjectWriter->needsRelocateWithSymbol(*Sym,
Type))
1433 MCFixupKindInfo::FKF_IsPCRel;
1440 const auto &SymB = cast<MCSymbolELF>(RefB->getSymbol());
1441 if (SymB.isUndefined()) {
1443 Twine(
"symbol '") + SymB.getName() +
1444 "' can not be undefined in a subtraction expression");
1448 assert(!SymB.isAbsolute() &&
"Should have been folded");
1449 const MCSection &SecB = SymB.getSection();
1450 if (&SecB != &FixupSection) {
1452 "Cannot represent a difference across sections");
1456 assert(!IsPCRel &&
"should have been folded");
1463 const auto *SymA = RefA ? cast<MCSymbolELF>(&RefA->
getSymbol()) : nullptr;
1465 bool ViaWeakRef =
false;
1466 if (SymA && SymA->isVariable()) {
1467 const MCExpr *Expr = SymA->getVariableValue();
1468 if (
const auto *Inner = dyn_cast<MCSymbolRefExpr>(Expr)) {
1469 if (Inner->getKind() == MCSymbolRefExpr::VK_WEAKREF) {
1470 SymA = cast<MCSymbolELF>(&Inner->getSymbol());
1476 const MCSectionELF *SecA = (SymA && SymA->isInSection())
1477 ? cast<MCSectionELF>(&SymA->getSection())
1479 if (!checkRelocation(Ctx,
Fixup.getLoc(), &FixupSection, SecA))
1482 unsigned Type = TargetObjectWriter->getRelocType(Ctx,
Target,
Fixup, IsPCRel);
1483 const auto *Parent = cast<MCSectionELF>(Fragment->
getParent());
1485 bool RelocateWithSymbol =
1486 shouldRelocateWithSymbol(
Asm, RefA, SymA,
C,
Type) ||
1490 FixedValue = !RelocateWithSymbol && SymA && !SymA->isUndefined()
1493 if (hasRelocationAddend()) {
1494 Addend = FixedValue;
1498 if (!RelocateWithSymbol) {
1499 const auto *SectionSymbol =
1502 SectionSymbol->setUsedInReloc();
1504 Relocations[&FixupSection].push_back(Rec);
1519 Relocations[&FixupSection].push_back(Rec);
1522 bool ELFObjectWriter::isSymbolRefDifferenceFullyResolvedImpl(
1524 bool InSet,
bool IsPCRel)
const {
1525 const auto &SymA = cast<MCSymbolELF>(SA);
1532 return MCObjectWriter::isSymbolRefDifferenceFullyResolvedImpl(
Asm, SymA, FB,
1536 std::unique_ptr<MCObjectWriter>
1539 return std::make_unique<ELFSingleObjectWriter>(
std::move(MOTW), OS,
1543 std::unique_ptr<MCObjectWriter>
1546 bool IsLittleEndian) {
1547 return std::make_unique<ELFDwoObjectWriter>(
std::move(MOTW), OS, DwoOS,