File indexing completed on 2026-05-10 08:44:13
0001
0002
0003
0004
0005
0006
0007
0008
0009 #ifndef LLVM_MC_MCELFEXTRAS_H
0010 #define LLVM_MC_MCELFEXTRAS_H
0011
0012 #include "llvm/ADT/STLExtras.h"
0013 #include "llvm/ADT/bit.h"
0014 #include "llvm/BinaryFormat/ELF.h"
0015 #include "llvm/Support/LEB128.h"
0016 #include "llvm/Support/raw_ostream.h"
0017
0018 #include <cstdint>
0019 #include <type_traits>
0020
0021 namespace llvm::ELF {
0022
0023
0024 template <bool Is64, class RelocsTy, class F>
0025 void encodeCrel(raw_ostream &OS, RelocsTy Relocs, F ToCrel) {
0026 using uint = std::conditional_t<Is64, uint64_t, uint32_t>;
0027 uint OffsetMask = 8, Offset = 0, Addend = 0;
0028 uint32_t SymIdx = 0, Type = 0;
0029 for (const auto &R : Relocs)
0030 OffsetMask |= ToCrel(R).r_offset;
0031 const int Shift = llvm::countr_zero(OffsetMask);
0032 encodeULEB128(Relocs.size() * 8 + ELF::CREL_HDR_ADDEND + Shift, OS);
0033 for (const auto &R : Relocs) {
0034 auto CR = ToCrel(R);
0035 auto DeltaOffset = static_cast<uint>((CR.r_offset - Offset) >> Shift);
0036 Offset = CR.r_offset;
0037 uint8_t B = (DeltaOffset << 3) + (SymIdx != CR.r_symidx) +
0038 (Type != CR.r_type ? 2 : 0) +
0039 (Addend != uint(CR.r_addend) ? 4 : 0);
0040 if (DeltaOffset < 0x10) {
0041 OS << char(B);
0042 } else {
0043 OS << char(B | 0x80);
0044 encodeULEB128(DeltaOffset >> 4, OS);
0045 }
0046
0047 if (B & 1) {
0048 encodeSLEB128(static_cast<int32_t>(CR.r_symidx - SymIdx), OS);
0049 SymIdx = CR.r_symidx;
0050 }
0051 if (B & 2) {
0052 encodeSLEB128(static_cast<int32_t>(CR.r_type - Type), OS);
0053 Type = CR.r_type;
0054 }
0055 if (B & 4) {
0056 encodeSLEB128(std::make_signed_t<uint>(CR.r_addend - Addend), OS);
0057 Addend = CR.r_addend;
0058 }
0059 }
0060 }
0061 }
0062
0063 #endif