1d3a6c897SEugene Zelenko //===- llvm/MC/MCLinkerOptimizationHint.cpp ----- LOH handling ------------===//
253d32518STim Northover //
3*2946cd70SChandler Carruth // Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
4*2946cd70SChandler Carruth // See https://llvm.org/LICENSE.txt for license information.
5*2946cd70SChandler Carruth // SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
653d32518STim Northover //
753d32518STim Northover //===----------------------------------------------------------------------===//
853d32518STim Northover 
953d32518STim Northover #include "llvm/MC/MCLinkerOptimizationHint.h"
1053d32518STim Northover #include "llvm/MC/MCAsmLayout.h"
11858239d5SReid Kleckner #include "llvm/MC/MCMachObjectWriter.h"
12d9903888SChandler Carruth #include "llvm/Support/LEB128.h"
13d3a6c897SEugene Zelenko #include "llvm/Support/raw_ostream.h"
14d3a6c897SEugene Zelenko #include <cstddef>
15d3a6c897SEugene Zelenko #include <cstdint>
1653d32518STim Northover 
1753d32518STim Northover using namespace llvm;
1853d32518STim Northover 
193c2b13b2SQuentin Colombet // Each LOH is composed by, in this order (each field is encoded using ULEB128):
203c2b13b2SQuentin Colombet // - Its kind.
213c2b13b2SQuentin Colombet // - Its number of arguments (let say N).
223c2b13b2SQuentin Colombet // - Its arg1.
233c2b13b2SQuentin Colombet // - ...
243c2b13b2SQuentin Colombet // - Its argN.
253c2b13b2SQuentin Colombet // <arg1> to <argN> are absolute addresses in the object file, i.e.,
263c2b13b2SQuentin Colombet // relative addresses from the beginning of the object file.
emit_impl(raw_ostream & OutStream,const MachObjectWriter & ObjWriter,const MCAsmLayout & Layout) const27249af2a0SJim Grosbach void MCLOHDirective::emit_impl(raw_ostream &OutStream,
2853d32518STim Northover                                const MachObjectWriter &ObjWriter,
2953d32518STim Northover                                const MCAsmLayout &Layout) const {
3053d32518STim Northover   encodeULEB128(Kind, OutStream);
3153d32518STim Northover   encodeULEB128(Args.size(), OutStream);
327b4658ffSBenjamin Kramer   for (const MCSymbol *Arg : Args)
337b4658ffSBenjamin Kramer     encodeULEB128(ObjWriter.getSymbolAddress(*Arg, Layout), OutStream);
3453d32518STim Northover }
35858239d5SReid Kleckner 
emit(MachObjectWriter & ObjWriter,const MCAsmLayout & Layout) const36858239d5SReid Kleckner void MCLOHDirective::emit(MachObjectWriter &ObjWriter,
37858239d5SReid Kleckner                           const MCAsmLayout &Layout) const {
38f17b149dSPeter Collingbourne   raw_ostream &OutStream = ObjWriter.W.OS;
39858239d5SReid Kleckner   emit_impl(OutStream, ObjWriter, Layout);
40858239d5SReid Kleckner }
41858239d5SReid Kleckner 
getEmitSize(const MachObjectWriter & ObjWriter,const MCAsmLayout & Layout) const42858239d5SReid Kleckner uint64_t MCLOHDirective::getEmitSize(const MachObjectWriter &ObjWriter,
43858239d5SReid Kleckner                                      const MCAsmLayout &Layout) const {
44858239d5SReid Kleckner   class raw_counting_ostream : public raw_ostream {
45d3a6c897SEugene Zelenko     uint64_t Count = 0;
46858239d5SReid Kleckner 
47858239d5SReid Kleckner     void write_impl(const char *, size_t size) override { Count += size; }
48858239d5SReid Kleckner 
49858239d5SReid Kleckner     uint64_t current_pos() const override { return Count; }
50858239d5SReid Kleckner 
51858239d5SReid Kleckner   public:
52d3a6c897SEugene Zelenko     raw_counting_ostream() = default;
53858239d5SReid Kleckner     ~raw_counting_ostream() override { flush(); }
54858239d5SReid Kleckner   };
55858239d5SReid Kleckner 
56858239d5SReid Kleckner   raw_counting_ostream OutStream;
57858239d5SReid Kleckner   emit_impl(OutStream, ObjWriter, Layout);
58858239d5SReid Kleckner   return OutStream.tell();
59858239d5SReid Kleckner }
60