|
23 | 23 | #include "llvm/MC/MCAsmInfo.h" |
24 | 24 | #include "llvm/MC/MCAssembler.h" |
25 | 25 | #include "llvm/MC/MCContext.h" |
| 26 | +#include "llvm/MC/MCELFExtras.h" |
26 | 27 | #include "llvm/MC/MCELFObjectWriter.h" |
27 | 28 | #include "llvm/MC/MCExpr.h" |
28 | 29 | #include "llvm/MC/MCFixup.h" |
@@ -903,44 +904,14 @@ void ELFWriter::WriteSecHdrEntry(uint32_t Name, uint32_t Type, uint64_t Flags, |
903 | 904 | WriteWord(EntrySize); // sh_entsize |
904 | 905 | } |
905 | 906 |
|
906 | | -template <class uint> |
| 907 | +template <bool Is64> |
907 | 908 | static void encodeCrel(ArrayRef<ELFRelocationEntry> Relocs, raw_ostream &OS) { |
908 | | - uint OffsetMask = 8, Offset = 0, Addend = 0; |
909 | | - uint32_t SymIdx = 0, Type = 0; |
910 | | - // hdr & 4 indicates 3 flag bits in delta offset and flags members. |
911 | | - for (const ELFRelocationEntry &Entry : Relocs) |
912 | | - OffsetMask |= Entry.Offset; |
913 | | - const int Shift = llvm::countr_zero(OffsetMask); |
914 | | - encodeULEB128(Relocs.size() * 8 + ELF::CREL_HDR_ADDEND + Shift, OS); |
915 | | - for (const ELFRelocationEntry &Entry : Relocs) { |
916 | | - // The delta offset and flags member may be larger than uint64_t. Special |
917 | | - // case the first byte (3 flag bits and 4 offset bits). Other ULEB128 bytes |
918 | | - // encode the remaining delta offset bits. |
919 | | - auto DeltaOffset = static_cast<uint>((Entry.Offset - Offset) >> Shift); |
920 | | - Offset = Entry.Offset; |
921 | | - uint32_t CurSymIdx = Entry.Symbol ? Entry.Symbol->getIndex() : 0; |
922 | | - uint8_t B = (DeltaOffset << 3) + (SymIdx != CurSymIdx) + |
923 | | - (Type != Entry.Type ? 2 : 0) + (Addend != Entry.Addend ? 4 : 0); |
924 | | - if (DeltaOffset < 0x10) { |
925 | | - OS << char(B); |
926 | | - } else { |
927 | | - OS << char(B | 0x80); |
928 | | - encodeULEB128(DeltaOffset >> 4, OS); |
929 | | - } |
930 | | - // Delta symidx/type/addend members (SLEB128). |
931 | | - if (B & 1) { |
932 | | - encodeSLEB128(static_cast<int32_t>(CurSymIdx - SymIdx), OS); |
933 | | - SymIdx = CurSymIdx; |
934 | | - } |
935 | | - if (B & 2) { |
936 | | - encodeSLEB128(static_cast<int32_t>(Entry.Type - Type), OS); |
937 | | - Type = Entry.Type; |
938 | | - } |
939 | | - if (B & 4) { |
940 | | - encodeSLEB128(std::make_signed_t<uint>(Entry.Addend - Addend), OS); |
941 | | - Addend = Entry.Addend; |
942 | | - } |
943 | | - } |
| 909 | + using uint = std::conditional_t<Is64, uint64_t, uint32_t>; |
| 910 | + ELF::encodeCrel<Is64>(OS, Relocs, [&](const ELFRelocationEntry &R) { |
| 911 | + uint32_t SymIdx = R.Symbol ? R.Symbol->getIndex() : 0; |
| 912 | + return ELF::Elf_Crel<Is64>{static_cast<uint>(R.Offset), SymIdx, R.Type, |
| 913 | + std::make_signed_t<uint>(R.Addend)}; |
| 914 | + }); |
944 | 915 | } |
945 | 916 |
|
946 | 917 | void ELFWriter::writeRelocations(const MCAssembler &Asm, |
@@ -989,9 +960,9 @@ void ELFWriter::writeRelocations(const MCAssembler &Asm, |
989 | 960 | } |
990 | 961 | } else if (TO && TO->Crel) { |
991 | 962 | if (is64Bit()) |
992 | | - encodeCrel<uint64_t>(Relocs, W.OS); |
| 963 | + encodeCrel<true>(Relocs, W.OS); |
993 | 964 | else |
994 | | - encodeCrel<uint32_t>(Relocs, W.OS); |
| 965 | + encodeCrel<false>(Relocs, W.OS); |
995 | 966 | } else { |
996 | 967 | for (const ELFRelocationEntry &Entry : Relocs) { |
997 | 968 | uint32_t Symidx = Entry.Symbol ? Entry.Symbol->getIndex() : 0; |
|
0 commit comments