1 | //===- llvm/MC/MCLinkerOptimizationHint.cpp ----- LOH handling ------------===// |
2 | // |
3 | // Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. |
4 | // See https://llvm.org/LICENSE.txt for license information. |
5 | // SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception |
6 | // |
7 | //===----------------------------------------------------------------------===// |
8 | |
9 | #include "llvm/MC/MCLinkerOptimizationHint.h" |
10 | #include "llvm/MC/MCMachObjectWriter.h" |
11 | #include "llvm/Support/LEB128.h" |
12 | #include "llvm/Support/raw_ostream.h" |
13 | #include <cstddef> |
14 | #include <cstdint> |
15 | |
16 | using namespace llvm; |
17 | |
18 | // Each LOH is composed by, in this order (each field is encoded using ULEB128): |
19 | // - Its kind. |
20 | // - Its number of arguments (let say N). |
21 | // - Its arg1. |
22 | // - ... |
23 | // - Its argN. |
24 | // <arg1> to <argN> are absolute addresses in the object file, i.e., |
25 | // relative addresses from the beginning of the object file. |
26 | void MCLOHDirective::emit_impl(const MCAssembler &Asm, raw_ostream &OutStream, |
27 | const MachObjectWriter &ObjWriter |
28 | |
29 | ) const { |
30 | encodeULEB128(Value: Kind, OS&: OutStream); |
31 | encodeULEB128(Value: Args.size(), OS&: OutStream); |
32 | for (const MCSymbol *Arg : Args) |
33 | encodeULEB128(Value: ObjWriter.getSymbolAddress(S: *Arg, Asm), OS&: OutStream); |
34 | } |
35 | |
36 | void MCLOHDirective::emit(const MCAssembler &Asm, |
37 | MachObjectWriter &ObjWriter) const { |
38 | raw_ostream &OutStream = ObjWriter.W.OS; |
39 | emit_impl(Asm, OutStream, ObjWriter); |
40 | } |
41 | |
42 | uint64_t MCLOHDirective::getEmitSize(const MCAssembler &Asm, |
43 | const MachObjectWriter &ObjWriter) const { |
44 | class raw_counting_ostream : public raw_ostream { |
45 | uint64_t Count = 0; |
46 | |
47 | void write_impl(const char *, size_t size) override { Count += size; } |
48 | |
49 | uint64_t current_pos() const override { return Count; } |
50 | |
51 | public: |
52 | raw_counting_ostream() = default; |
53 | ~raw_counting_ostream() override { flush(); } |
54 | }; |
55 | |
56 | raw_counting_ostream OutStream; |
57 | emit_impl(Asm, OutStream, ObjWriter); |
58 | return OutStream.tell(); |
59 | } |
60 | |