You can not select more than 25 topics
Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
224 lines
7.7 KiB
224 lines
7.7 KiB
//===-- 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 <llvm/ADT/StringRef.h>
|
|
#include <llvm/ADT/ilist.h>
|
|
#include <llvm/Support/DataTypes.h>
|
|
|
|
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<Relocation, GCFactoryListTraits<Relocation> >
|
|
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_
|