10b57cec5SDimitry Andric //===- llvm/MC/MCLinkerOptimizationHint.cpp ----- LOH handling ------------===// 20b57cec5SDimitry Andric // 30b57cec5SDimitry Andric // Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. 40b57cec5SDimitry Andric // See https://llvm.org/LICENSE.txt for license information. 50b57cec5SDimitry Andric // SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception 60b57cec5SDimitry Andric // 70b57cec5SDimitry Andric //===----------------------------------------------------------------------===// 80b57cec5SDimitry Andric 90b57cec5SDimitry Andric #include "llvm/MC/MCLinkerOptimizationHint.h" 100b57cec5SDimitry Andric #include "llvm/MC/MCMachObjectWriter.h" 110b57cec5SDimitry Andric #include "llvm/Support/LEB128.h" 120b57cec5SDimitry Andric #include "llvm/Support/raw_ostream.h" 130b57cec5SDimitry Andric #include <cstddef> 140b57cec5SDimitry Andric #include <cstdint> 150b57cec5SDimitry Andric 160b57cec5SDimitry Andric using namespace llvm; 170b57cec5SDimitry Andric 180b57cec5SDimitry Andric // Each LOH is composed by, in this order (each field is encoded using ULEB128): 190b57cec5SDimitry Andric // - Its kind. 200b57cec5SDimitry Andric // - Its number of arguments (let say N). 210b57cec5SDimitry Andric // - Its arg1. 220b57cec5SDimitry Andric // - ... 230b57cec5SDimitry Andric // - Its argN. 240b57cec5SDimitry Andric // <arg1> to <argN> are absolute addresses in the object file, i.e., 250b57cec5SDimitry Andric // relative addresses from the beginning of the object file. 26*0fca6ea1SDimitry Andric void MCLOHDirective::emit_impl(const MCAssembler &Asm, raw_ostream &OutStream, 27*0fca6ea1SDimitry Andric const MachObjectWriter &ObjWriter 28*0fca6ea1SDimitry Andric 29*0fca6ea1SDimitry Andric ) const { 300b57cec5SDimitry Andric encodeULEB128(Kind, OutStream); 310b57cec5SDimitry Andric encodeULEB128(Args.size(), OutStream); 320b57cec5SDimitry Andric for (const MCSymbol *Arg : Args) 33*0fca6ea1SDimitry Andric encodeULEB128(ObjWriter.getSymbolAddress(*Arg, Asm), OutStream); 340b57cec5SDimitry Andric } 350b57cec5SDimitry Andric 36*0fca6ea1SDimitry Andric void MCLOHDirective::emit(const MCAssembler &Asm, 37*0fca6ea1SDimitry Andric MachObjectWriter &ObjWriter) const { 380b57cec5SDimitry Andric raw_ostream &OutStream = ObjWriter.W.OS; 39*0fca6ea1SDimitry Andric emit_impl(Asm, OutStream, ObjWriter); 400b57cec5SDimitry Andric } 410b57cec5SDimitry Andric 42*0fca6ea1SDimitry Andric uint64_t MCLOHDirective::getEmitSize(const MCAssembler &Asm, 43*0fca6ea1SDimitry Andric const MachObjectWriter &ObjWriter) const { 440b57cec5SDimitry Andric class raw_counting_ostream : public raw_ostream { 450b57cec5SDimitry Andric uint64_t Count = 0; 460b57cec5SDimitry Andric 470b57cec5SDimitry Andric void write_impl(const char *, size_t size) override { Count += size; } 480b57cec5SDimitry Andric 490b57cec5SDimitry Andric uint64_t current_pos() const override { return Count; } 500b57cec5SDimitry Andric 510b57cec5SDimitry Andric public: 520b57cec5SDimitry Andric raw_counting_ostream() = default; 530b57cec5SDimitry Andric ~raw_counting_ostream() override { flush(); } 540b57cec5SDimitry Andric }; 550b57cec5SDimitry Andric 560b57cec5SDimitry Andric raw_counting_ostream OutStream; 57*0fca6ea1SDimitry Andric emit_impl(Asm, OutStream, ObjWriter); 580b57cec5SDimitry Andric return OutStream.tell(); 590b57cec5SDimitry Andric } 60