|
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