//===-- TargetLDBackend.h - Target LD Backend -------------------*- C++ -*-===// // // The MCLinker Project // // This file is distributed under the University of Illinois Open Source // License. See LICENSE.TXT for details. // //===----------------------------------------------------------------------===// #ifndef MCLD_TARGET_TARGETLDBACKEND_H_ #define MCLD_TARGET_TARGETLDBACKEND_H_ #include "mcld/Fragment/Relocation.h" #include "mcld/LD/GarbageCollection.h" #include "mcld/Support/Compiler.h" #include "mcld/Support/GCFactoryListTraits.h" #include #include #include namespace mcld { class ArchiveReader; class BinaryReader; class BinaryWriter; class BranchIslandFactory; class DynObjReader; class DynObjWriter; class ExecWriter; class FileOutputBuffer; class IRBuilder; class Input; class LDSection; class LDSymbol; class LinkerConfig; class Module; class ObjectBuilder; class ObjectReader; class ObjectWriter; class Relocator; class ResolveInfo; class SectionData; class SectionReachedListMap; class StubFactory; //===----------------------------------------------------------------------===// /// TargetLDBackend - Generic interface to target specific assembler backends. //===----------------------------------------------------------------------===// class TargetLDBackend { public: typedef llvm::iplist > ExtraRelocList; typedef ExtraRelocList::iterator extra_reloc_iterator; protected: explicit TargetLDBackend(const LinkerConfig& pConfig); public: virtual ~TargetLDBackend(); // ----- target dependent ----- // virtual void initTargetSegments(IRBuilder& pBuilder) {} virtual void initTargetSections(Module& pModule, ObjectBuilder& pBuilder) {} virtual void initTargetSymbols(IRBuilder& pBuilder, Module& pModule) {} virtual void initTargetRelocation(IRBuilder& pBuilder) {} virtual bool initStandardSymbols(IRBuilder& pBuilder, Module& pModule) = 0; virtual bool initRelocator() = 0; virtual Relocator* getRelocator() = 0; virtual const Relocator* getRelocator() const = 0; // ----- format dependent ----- // virtual ArchiveReader* createArchiveReader(Module&) = 0; virtual ObjectReader* createObjectReader(IRBuilder&) = 0; virtual DynObjReader* createDynObjReader(IRBuilder&) = 0; virtual BinaryReader* createBinaryReader(IRBuilder&) = 0; virtual ObjectWriter* createWriter() = 0; virtual bool initStdSections(ObjectBuilder& pBuilder) = 0; /// layout - layout method virtual void layout(Module& pModule) = 0; /// preLayout - Backend can do any needed modification before layout virtual void preLayout(Module& pModule, IRBuilder& pBuilder) = 0; /// postLayout - Backend can do any needed modification after layout virtual void postLayout(Module& pModule, IRBuilder& pBuilder) = 0; /// postProcessing - Backend can do any needed modification in the final stage virtual void postProcessing(FileOutputBuffer& pOutput) = 0; /// section start offset in the output file virtual size_t sectionStartOffset() const = 0; /// computeSectionOrder - compute the layout order of the given section virtual unsigned int getSectionOrder(const LDSection& pSectHdr) const = 0; /// sizeNamePools - compute the size of regular name pools /// In ELF executable files, regular name pools are .symtab, .strtab., /// .dynsym, .dynstr, and .hash virtual void sizeNamePools(Module& pModule) = 0; /// finalizeSymbol - Linker checks pSymbol.reserved() if it's not zero, /// then it will ask backend to finalize the symbol value. /// @return ture - if backend set the symbol value sucessfully /// @return false - if backend do not recognize the symbol virtual bool finalizeSymbols() = 0; /// finalizeTLSSymbol - Linker asks backend to set the symbol value when it /// meets a TLS symbol virtual bool finalizeTLSSymbol(LDSymbol& pSymbol) = 0; /// allocateCommonSymbols - allocate common symbols in the corresponding /// sections. virtual bool allocateCommonSymbols(Module& pModule) = 0; /// preMergeSections - hooks to be executed before merging sections virtual void preMergeSections(Module& pModule) { } /// postMergeSections - hooks to be executed after merging sections virtual void postMergeSections(Module& pModule) { } /// mergeSection - merge target dependent sections. virtual bool mergeSection(Module& pModule, const Input& pInputFile, LDSection& pInputSection) { return true; } /// setUpReachedSectionsForGC - set the reference between two sections for /// some special target sections. GC will set up the reference for the Regular /// and BSS sections. Backends can also set up the reference if need. virtual void setUpReachedSectionsForGC( const Module& pModule, GarbageCollection::SectionReachedListMap& pSectReachedListMap) const {} /// updateSectionFlags - update pTo's flags when merging pFrom /// update the output section flags based on input section flags. /// FIXME: (Luba) I know ELF need to merge flags, but I'm not sure if /// MachO and COFF also need this. virtual bool updateSectionFlags(LDSection& pTo, const LDSection& pFrom) { return true; } /// readSection - read a target dependent section virtual bool readSection(Input& pInput, SectionData& pSD) { return true; } /// sizeInterp - compute the size of program interpreter's name /// In ELF executables, this is the length of dynamic linker's path name virtual void sizeInterp() = 0; /// getEntry - get the entry point name virtual llvm::StringRef getEntry(const Module& pModule) const = 0; // ----- relaxation ----- // virtual bool initBRIslandFactory() = 0; virtual bool initStubFactory() = 0; virtual bool initTargetStubs() { return true; } virtual BranchIslandFactory* getBRIslandFactory() = 0; virtual StubFactory* getStubFactory() = 0; /// relax - the relaxation pass virtual bool relax(Module& pModule, IRBuilder& pBuilder) = 0; /// mayRelax - return true if the backend needs to do relaxation virtual bool mayRelax() = 0; /// commonPageSize - the common page size of the target machine virtual uint64_t commonPageSize() const = 0; /// abiPageSize - the abi page size of the target machine virtual uint64_t abiPageSize() const = 0; /// sortRelocation - sort the dynamic relocations to let dynamic linker /// process relocations more efficiently virtual void sortRelocation(LDSection& pSection) = 0; /// createAndSizeEhFrameHdr - This is seperated since we may add eh_frame /// entry in the middle virtual void createAndSizeEhFrameHdr(Module& pModule) = 0; /// isSymbolPreemptible - whether the symbol can be preemted by other link /// units virtual bool isSymbolPreemptible(const ResolveInfo& pSym) const = 0; /// mayHaveUnsafeFunctionPointerAccess - check if the section may have unsafe /// function pointer access virtual bool mayHaveUnsafeFunctionPointerAccess( const LDSection& pSection) const = 0; extra_reloc_iterator extra_reloc_begin() { return m_ExtraReloc.begin(); } extra_reloc_iterator extra_reloc_end() { return m_ExtraReloc.end(); } protected: const LinkerConfig& config() const { return m_Config; } /// addExtraRelocation - Add an extra relocation which are automatically /// generated by the LD backend. void addExtraRelocation(Relocation* reloc) { m_ExtraReloc.push_back(reloc); } private: const LinkerConfig& m_Config; /// m_ExtraReloc - Extra relocations that are automatically generated by the /// linker. ExtraRelocList m_ExtraReloc; private: DISALLOW_COPY_AND_ASSIGN(TargetLDBackend); }; } // namespace mcld #endif // MCLD_TARGET_TARGETLDBACKEND_H_