diff options
Diffstat (limited to 'ELF/Relocations.h')
-rw-r--r-- | ELF/Relocations.h | 34 |
1 files changed, 21 insertions, 13 deletions
diff --git a/ELF/Relocations.h b/ELF/Relocations.h index 445308b27..5548a5583 100644 --- a/ELF/Relocations.h +++ b/ELF/Relocations.h @@ -10,7 +10,7 @@ #ifndef LLD_ELF_RELOCATIONS_H #define LLD_ELF_RELOCATIONS_H -#include "lld/Core/LLVM.h" +#include "lld/Common/LLVM.h" #include "llvm/ADT/DenseMap.h" #include <map> #include <vector> @@ -21,12 +21,16 @@ class SymbolBody; class InputSection; class InputSectionBase; class OutputSection; -struct OutputSectionCommand; +class OutputSection; + +// Represents a relocation type, such as R_X86_64_PC32 or R_ARM_THM_CALL. +typedef uint32_t RelType; // List of target-independent relocation types. Relocations read // from files are converted to these types so that the main code // doesn't have to know about architecture-specific details. enum RelExpr { + R_INVALID, R_ABS, R_ARM_SBREL, R_GOT, @@ -103,14 +107,15 @@ struct RelExprMaskBuilder<Head, Tail...> { // RelExpr's as a constant bit mask and test for membership with a // couple cheap bitwise operations. template <RelExpr... Exprs> bool isRelExprOneOf(RelExpr Expr) { - assert(0 <= Expr && (int)Expr < 64 && "RelExpr is too large for 64-bit mask!"); + assert(0 <= Expr && (int)Expr < 64 && + "RelExpr is too large for 64-bit mask!"); return (uint64_t(1) << Expr) & RelExprMaskBuilder<Exprs...>::build(); } // Architecture-neutral representation of relocation. struct Relocation { RelExpr Expr; - uint32_t Type; + RelType Type; uint64_t Offset; int64_t Addend; SymbolBody *Sym; @@ -124,7 +129,7 @@ class Thunk; class ThunkCreator { public: // Return true if Thunks have been added to OutputSections - bool createThunks(ArrayRef<OutputSectionCommand *> OutputSections); + bool createThunks(ArrayRef<OutputSection *> OutputSections); // The number of completed passes of createThunks this permits us // to do one time initialization on Pass 0 and put a limit on the @@ -135,23 +140,26 @@ private: void mergeThunks(); ThunkSection *getOSThunkSec(OutputSection *OS, std::vector<InputSection *> *ISR); - ThunkSection *getISThunkSec(InputSection *IS, OutputSection *OS); + ThunkSection *getISThunkSec(InputSection *IS); void forEachExecInputSection( - ArrayRef<OutputSectionCommand *> OutputSections, + ArrayRef<OutputSection *> OutputSections, std::function<void(OutputSection *, std::vector<InputSection *> *, InputSection *)> Fn); - std::pair<Thunk *, bool> getThunk(SymbolBody &Body, uint32_t Type); + std::pair<Thunk *, bool> getThunk(SymbolBody &Body, RelType Type); ThunkSection *addThunkSection(OutputSection *OS, std::vector<InputSection *> *, uint64_t Off); - // Track Symbols that already have a Thunk - llvm::DenseMap<SymbolBody *, Thunk *> ThunkedSymbols; + // Record all the available Thunks for a Symbol + llvm::DenseMap<SymbolBody *, std::vector<Thunk *>> ThunkedSymbols; // Find a Thunk from the Thunks symbol definition, we can use this to find // the Thunk from a relocation to the Thunks symbol definition. llvm::DenseMap<SymbolBody *, Thunk *> Thunks; - // Track InputSections that have a ThunkSection placed in front + // Track InputSections that have an inline ThunkSection placed in front + // an inline ThunkSection may have control fall through to the section below + // so we need to make sure that there is only one of them. + // The Mips LA25 Thunk is an example of an inline ThunkSection. llvm::DenseMap<InputSection *, ThunkSection *> ThunkedSections; // All the ThunkSections that we have created, organised by OutputSection @@ -175,7 +183,7 @@ template <class ELFT> static inline int64_t getAddend(const typename ELFT::Rela &Rel) { return Rel.r_addend; } -} -} +} // namespace elf +} // namespace lld #endif |