summaryrefslogtreecommitdiff
path: root/include/mcld/LD/ELFReaderIf.h
blob: 245b542b84b5e77daed3a23808d415b086bb1b1e (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
//===- ELFReader.h --------------------------------------------------------===//
//
//                     The MCLinker Project
//
// This file is distributed under the University of Illinois Open Source
// License. See LICENSE.TXT for details.
//
//===----------------------------------------------------------------------===//
#ifndef MCLD_ELF_READER_INTERFACE_H
#define MCLD_ELF_READER_INTERFACE_H
#ifdef ENABLE_UNITTEST
#include <gtest.h>
#endif

#include <llvm/ADT/StringRef.h>
#include <llvm/Support/ELF.h>
#include <llvm/Support/Host.h>

#include <mcld/Module.h>
#include <mcld/LinkerConfig.h>
#include <mcld/LD/LDContext.h>
#include <mcld/Target/GNULDBackend.h>
#include <mcld/Support/MsgHandling.h>

namespace mcld {

class Module;
class IRBuilder;
class FragmentRef;
class SectionData;
class LDSection;

/** \class ELFReaderIF
 *  \brief ELFReaderIF provides common interface for all kind of ELF readers.
 */
class ELFReaderIF
{
public:
  ELFReaderIF(GNULDBackend& pBackend)
    : m_Backend(pBackend)
  { }

  virtual ~ELFReaderIF() { }

  /// ELFHeaderSize - return the size of the ELFHeader
  virtual size_t getELFHeaderSize() const = 0;

  /// isELF - is this a ELF file
  virtual bool isELF(void* pELFHeader) const = 0;

  /// isMyEndian - is this ELF file in the same endian to me?
  virtual bool isMyEndian(void* pELFHeader) const = 0;

  /// isMyMachine - is this ELF file generated for the same machine.
  virtual bool isMyMachine(void* pELFHeader) const = 0;

  /// fileType - the file type of this file
  virtual Input::Type fileType(void* pELFHeader) const = 0;

  /// target - the target backend
  const GNULDBackend& target() const { return m_Backend; }
  GNULDBackend&       target()       { return m_Backend; }


  /// readSectionHeaders - read ELF section header table and create LDSections
  virtual bool readSectionHeaders(Input& pInput, void* pELFHeader) const = 0;

  /// readRegularSection - read a regular section and create fragments.
  virtual bool readRegularSection(Input& pInput, SectionData& pSD) const = 0;

  /// readSymbols - read ELF symbols and create LDSymbol
  virtual bool readSymbols(Input& pInput,
                           IRBuilder& pBuilder,
                           const MemoryRegion& pRegion,
                           const char* StrTab) const = 0;

  /// readSignature - read a symbol from the given Input and index in symtab
  /// This is used to get the signature of a group section.
  virtual ResolveInfo* readSignature(Input& pInput,
                                     LDSection& pSymTab,
                                     uint32_t pSymIdx) const = 0;

  /// readRela - read ELF rela and create Relocation
  virtual bool readRela(Input& pInput,
                        LDSection& pSection,
                        const MemoryRegion& pRegion) const = 0;

  /// readRel - read ELF rel and create Relocation
  virtual bool readRel(Input& pInput,
                       LDSection& pSection,
                       const MemoryRegion& pRegion) const = 0;

  /// readDynamic - read ELF .dynamic in input dynobj
  virtual bool readDynamic(Input& pInput) const = 0;

protected:
  /// LinkInfo - some section needs sh_link and sh_info, remember them.
  struct LinkInfo {
    LDSection* section;
    uint32_t sh_link;
    uint32_t sh_info;
  };

  typedef std::vector<LinkInfo> LinkInfoList;

protected:
  ResolveInfo::Type getSymType(uint8_t pInfo, uint16_t pShndx) const;

  ResolveInfo::Desc getSymDesc(uint16_t pShndx, const Input& pInput) const;

  ResolveInfo::Binding getSymBinding(uint8_t pBinding,
                                     uint16_t pShndx,
                                     uint8_t pVisibility) const;

  uint64_t getSymValue(uint64_t pValue,
                       uint16_t pShndx,
                       const Input& pInput) const;

  FragmentRef* getSymFragmentRef(Input& pInput,
                                 uint16_t pShndx,
                                 uint32_t pOffset) const;

  ResolveInfo::Visibility getSymVisibility(uint8_t pVis) const;

protected:
  GNULDBackend& m_Backend;
};

} // namespace of mcld

#endif