123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199 |
- #pragma once
- #ifdef __GNUC__
- #pragma GCC diagnostic push
- #pragma GCC diagnostic ignored "-Wunused-parameter"
- #endif
- //===- MCLinkerOptimizationHint.h - LOH interface ---------------*- C++ -*-===//
- //
- //
- // Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
- // See https://llvm.org/LICENSE.txt for license information.
- // SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
- //
- //===----------------------------------------------------------------------===//
- //
- // This file declares some helpers classes to handle Linker Optimization Hint
- // (LOH).
- //
- // FIXME: LOH interface supports only MachO format at the moment.
- //===----------------------------------------------------------------------===//
- #ifndef LLVM_MC_MCLINKEROPTIMIZATIONHINT_H
- #define LLVM_MC_MCLINKEROPTIMIZATIONHINT_H
- #include "llvm/ADT/SmallVector.h"
- #include "llvm/ADT/StringRef.h"
- #include "llvm/ADT/StringSwitch.h"
- #include "llvm/Support/raw_ostream.h"
- #include <cassert>
- #include <cstdint>
- namespace llvm {
- class MachObjectWriter;
- class MCAsmLayout;
- class MCSymbol;
- /// Linker Optimization Hint Type.
- enum MCLOHType {
- MCLOH_AdrpAdrp = 0x1u, ///< Adrp xY, _v1@PAGE -> Adrp xY, _v2@PAGE.
- MCLOH_AdrpLdr = 0x2u, ///< Adrp _v@PAGE -> Ldr _v@PAGEOFF.
- MCLOH_AdrpAddLdr = 0x3u, ///< Adrp _v@PAGE -> Add _v@PAGEOFF -> Ldr.
- MCLOH_AdrpLdrGotLdr = 0x4u, ///< Adrp _v@GOTPAGE -> Ldr _v@GOTPAGEOFF -> Ldr.
- MCLOH_AdrpAddStr = 0x5u, ///< Adrp _v@PAGE -> Add _v@PAGEOFF -> Str.
- MCLOH_AdrpLdrGotStr = 0x6u, ///< Adrp _v@GOTPAGE -> Ldr _v@GOTPAGEOFF -> Str.
- MCLOH_AdrpAdd = 0x7u, ///< Adrp _v@PAGE -> Add _v@PAGEOFF.
- MCLOH_AdrpLdrGot = 0x8u ///< Adrp _v@GOTPAGE -> Ldr _v@GOTPAGEOFF.
- };
- static inline StringRef MCLOHDirectiveName() {
- return StringRef(".loh");
- }
- static inline bool isValidMCLOHType(unsigned Kind) {
- return Kind >= MCLOH_AdrpAdrp && Kind <= MCLOH_AdrpLdrGot;
- }
- static inline int MCLOHNameToId(StringRef Name) {
- #define MCLOHCaseNameToId(Name) .Case(#Name, MCLOH_ ## Name)
- return StringSwitch<int>(Name)
- MCLOHCaseNameToId(AdrpAdrp)
- MCLOHCaseNameToId(AdrpLdr)
- MCLOHCaseNameToId(AdrpAddLdr)
- MCLOHCaseNameToId(AdrpLdrGotLdr)
- MCLOHCaseNameToId(AdrpAddStr)
- MCLOHCaseNameToId(AdrpLdrGotStr)
- MCLOHCaseNameToId(AdrpAdd)
- MCLOHCaseNameToId(AdrpLdrGot)
- .Default(-1);
- #undef MCLOHCaseNameToId
- }
- static inline StringRef MCLOHIdToName(MCLOHType Kind) {
- #define MCLOHCaseIdToName(Name) case MCLOH_ ## Name: return StringRef(#Name);
- switch (Kind) {
- MCLOHCaseIdToName(AdrpAdrp);
- MCLOHCaseIdToName(AdrpLdr);
- MCLOHCaseIdToName(AdrpAddLdr);
- MCLOHCaseIdToName(AdrpLdrGotLdr);
- MCLOHCaseIdToName(AdrpAddStr);
- MCLOHCaseIdToName(AdrpLdrGotStr);
- MCLOHCaseIdToName(AdrpAdd);
- MCLOHCaseIdToName(AdrpLdrGot);
- }
- return StringRef();
- #undef MCLOHCaseIdToName
- }
- static inline int MCLOHIdToNbArgs(MCLOHType Kind) {
- switch (Kind) {
- // LOH with two arguments
- case MCLOH_AdrpAdrp:
- case MCLOH_AdrpLdr:
- case MCLOH_AdrpAdd:
- case MCLOH_AdrpLdrGot:
- return 2;
- // LOH with three arguments
- case MCLOH_AdrpAddLdr:
- case MCLOH_AdrpLdrGotLdr:
- case MCLOH_AdrpAddStr:
- case MCLOH_AdrpLdrGotStr:
- return 3;
- }
- return -1;
- }
- /// Store Linker Optimization Hint information (LOH).
- class MCLOHDirective {
- MCLOHType Kind;
- /// Arguments of this directive. Order matters.
- SmallVector<MCSymbol *, 3> Args;
- /// Emit this directive in \p OutStream using the information available
- /// in the given \p ObjWriter and \p Layout to get the address of the
- /// arguments within the object file.
- void emit_impl(raw_ostream &OutStream, const MachObjectWriter &ObjWriter,
- const MCAsmLayout &Layout) const;
- public:
- using LOHArgs = SmallVectorImpl<MCSymbol *>;
- MCLOHDirective(MCLOHType Kind, const LOHArgs &Args)
- : Kind(Kind), Args(Args.begin(), Args.end()) {
- assert(isValidMCLOHType(Kind) && "Invalid LOH directive type!");
- }
- MCLOHType getKind() const { return Kind; }
- const LOHArgs &getArgs() const { return Args; }
- /// Emit this directive as:
- /// <kind, numArgs, addr1, ..., addrN>
- void emit(MachObjectWriter &ObjWriter, const MCAsmLayout &Layout) const;
- /// Get the size in bytes of this directive if emitted in \p ObjWriter with
- /// the given \p Layout.
- uint64_t getEmitSize(const MachObjectWriter &ObjWriter,
- const MCAsmLayout &Layout) const;
- };
- class MCLOHContainer {
- /// Keep track of the emit size of all the LOHs.
- mutable uint64_t EmitSize = 0;
- /// Keep track of all LOH directives.
- SmallVector<MCLOHDirective, 32> Directives;
- public:
- using LOHDirectives = SmallVectorImpl<MCLOHDirective>;
- MCLOHContainer() = default;
- /// Const accessor to the directives.
- const LOHDirectives &getDirectives() const {
- return Directives;
- }
- /// Add the directive of the given kind \p Kind with the given arguments
- /// \p Args to the container.
- void addDirective(MCLOHType Kind, const MCLOHDirective::LOHArgs &Args) {
- Directives.push_back(MCLOHDirective(Kind, Args));
- }
- /// Get the size of the directives if emitted.
- uint64_t getEmitSize(const MachObjectWriter &ObjWriter,
- const MCAsmLayout &Layout) const {
- if (!EmitSize) {
- for (const MCLOHDirective &D : Directives)
- EmitSize += D.getEmitSize(ObjWriter, Layout);
- }
- return EmitSize;
- }
- /// Emit all Linker Optimization Hint in one big table.
- /// Each line of the table is emitted by LOHDirective::emit.
- void emit(MachObjectWriter &ObjWriter, const MCAsmLayout &Layout) const {
- for (const MCLOHDirective &D : Directives)
- D.emit(ObjWriter, Layout);
- }
- void reset() {
- Directives.clear();
- EmitSize = 0;
- }
- };
- // Add types for specialized template using MCSymbol.
- using MCLOHArgs = MCLOHDirective::LOHArgs;
- using MCLOHDirectives = MCLOHContainer::LOHDirectives;
- } // end namespace llvm
- #endif // LLVM_MC_MCLINKEROPTIMIZATIONHINT_H
- #ifdef __GNUC__
- #pragma GCC diagnostic pop
- #endif
|