MCLinker upstream commit 7720f766. BUG=6886348.
Change-Id: Ifc03fbe870c8993893e92c2e55a9c3f6e3877849
diff --git a/include/mcld/ADT/BinTree.h b/include/mcld/ADT/BinTree.h
index da30a89..f015ac8 100644
--- a/include/mcld/ADT/BinTree.h
+++ b/include/mcld/ADT/BinTree.h
@@ -135,11 +135,8 @@
reference operator->() const
{ return *static_cast<node_type*>(IteratorType::m_pNode)->data; }
- bool isRoot() const
- { return (IteratorType::m_pNode->right == IteratorType::m_pNode); }
-
bool hasData() const
- { return (!isRoot() && (0 != static_cast<node_type*>(IteratorType::m_pNode)->data)); }
+ { return (!IteratorType::isRoot() && (0 != static_cast<node_type*>(IteratorType::m_pNode)->data)); }
};
diff --git a/include/mcld/ADT/TreeBase.h b/include/mcld/ADT/TreeBase.h
index 4df8d0d..10e0892 100644
--- a/include/mcld/ADT/TreeBase.h
+++ b/include/mcld/ADT/TreeBase.h
@@ -70,6 +70,9 @@
proxy::move<DIRECT>(m_pNode);
}
+ bool isRoot() const
+ { return (m_pNode->right == m_pNode); }
+
bool hasRightChild() const
{ return ((m_pNode->right) != (m_pNode->right->right)); }
diff --git a/include/mcld/LD/DiagCommonKinds.inc b/include/mcld/LD/DiagCommonKinds.inc
index 25cbb8f..ac3d0e1 100644
--- a/include/mcld/LD/DiagCommonKinds.inc
+++ b/include/mcld/LD/DiagCommonKinds.inc
@@ -34,8 +34,11 @@
DIAG(err_cannot_write_file, DiagnosticEngine::Error, "cannot write file %0 from offset %1 to length %2.", "cannot write file %0 from offset %1 to length %2.")
DIAG(warn_illegal_input_section, DiagnosticEngine::Warning, "section `%0' should not appear in input file `%1': %2", "section `%0' should not appear in input file `%1': %2")
DIAG(err_cannot_trace_file, DiagnosticEngine::Unreachable, "cannot identify the type (%0) of input file `%1'.\n %2", "cannot identify the type (%0) of input file `%1'.\n %2")
-DIAG(err_out_of_range_region, DiagnosticEngine::Unreachable, "requested memory region is out of range.", "requested memory region is out of range.")
+DIAG(err_out_of_range_region, DiagnosticEngine::Unreachable, "requested memory region [%0, %1] is out of range.", "requested memory region [%0, %1] is out of range.")
DIAG(debug_eh_unsupport, DiagnosticEngine::Debug, "unsupported eh_frame: %0", "unsupported eh_frame: %0")
DIAG(note_ehframe, DiagnosticEngine::Note, "eh_frame: %0", "eh_frame: %0")
DIAG(note_eh_cie, DiagnosticEngine::Note, "CIE length: %0, aug_string: %1, fde_encodeing: %2", "CIE length: %0, aug_string: %1, fde_encodeing: %2")
DIAG(note_eh_fde, DiagnosticEngine::Note, "FDE length: %0, offset of PC Begin: %1", "FDE length: %0, offset of PC Begin: %1")
+DIAG(fatal_cannot_init_target, DiagnosticEngine::Fatal, "Cannot initialize mcld::Target for given triple '%0'.\n(Detail: %1)", "Cannot initialize mcld::Target for given triple '%0'.\n(Detail: %1)")
+DIAG(fatal_cannot_init_lineinfo, DiagnosticEngine::Fatal, "Cannot initialize mcld::DiagnosticLineInfo for given triple '%0'", "Cannot initialize mcld::DiagnosticLineInfo for given triple '%0'")
+DIAG(fatal_cannot_init_backend, DiagnosticEngine::Fatal, "Cannot initialize mcld::TargetLDBackend for given triple '%0'.", "Cannot initialize mcld::TargetLDBackend for given triple '%0'.")
diff --git a/include/mcld/LD/DiagnosticEngine.h b/include/mcld/LD/DiagnosticEngine.h
index 9c106e5..77666ab 100644
--- a/include/mcld/LD/DiagnosticEngine.h
+++ b/include/mcld/LD/DiagnosticEngine.h
@@ -57,14 +57,14 @@
};
public:
- DiagnosticEngine(const MCLDInfo& pLDInfo,
- DiagnosticLineInfo* pLineInfo = NULL,
- DiagnosticPrinter* pPrinter = NULL,
- bool pShouldOwnPrinter = true);
+ DiagnosticEngine();
~DiagnosticEngine();
- // ----- printer functions ----- //
+ void reset(const MCLDInfo& pLDInfo);
+
+ void setLineInfo(DiagnosticLineInfo& pLineInfo);
+
void setPrinter(DiagnosticPrinter& pPrinter, bool pShouldOwnPrinter = true);
DiagnosticPrinter* getPrinter()
@@ -128,17 +128,21 @@
const State& state() const
{ return m_State; }
- DiagnosticInfos& infoMap()
- { return m_InfoMap; }
+ DiagnosticInfos& infoMap() {
+ assert(NULL != m_pInfoMap && "DiagnosticEngine was not initialized!");
+ return *m_pInfoMap;
+ }
- const DiagnosticInfos& infoMap() const
- { return m_InfoMap; }
+ const DiagnosticInfos& infoMap() const {
+ assert(NULL != m_pInfoMap && "DiagnosticEngine was not initialized!");
+ return *m_pInfoMap;
+ }
private:
- const MCLDInfo& m_LDInfo;
+ const MCLDInfo* m_pLDInfo;
DiagnosticLineInfo* m_pLineInfo;
DiagnosticPrinter* m_pPrinter;
- DiagnosticInfos m_InfoMap;
+ DiagnosticInfos* m_pInfoMap;
bool m_OwnPrinter;
State m_State;
diff --git a/include/mcld/LD/ELFReader.h b/include/mcld/LD/ELFReader.h
index d232cab..a247804 100644
--- a/include/mcld/LD/ELFReader.h
+++ b/include/mcld/LD/ELFReader.h
@@ -86,6 +86,7 @@
const char* StrTab) const = 0;
/// readSymbol - read a symbol from the given Input and index in symtab
+ /// This is used to get the signature of a group section.
virtual ResolveInfo* readSymbol(Input& pInput,
LDSection& pSymTab,
MCLDInfo& pLDInfo,
@@ -207,6 +208,7 @@
const char* StrTab) const;
/// readSymbol - read a symbol from the given Input and index in symtab
+ /// This is used to get the signature of a group section.
inline ResolveInfo* readSymbol(Input& pInput,
LDSection& pSymTab,
MCLDInfo& pLDInfo,
diff --git a/include/mcld/LD/ELFReader.tcc b/include/mcld/LD/ELFReader.tcc
index 61e8331..4f5c036 100644
--- a/include/mcld/LD/ELFReader.tcc
+++ b/include/mcld/LD/ELFReader.tcc
@@ -112,7 +112,8 @@
if (0x0 == shoff)
return true;
- MemoryRegion* shdr_region = pInput.memArea()->request(shoff, shnum*shentsize);
+ MemoryRegion* shdr_region = pInput.memArea()->request(
+ pInput.fileOffset() + shoff, shnum*shentsize);
llvm::ELF::Elf32_Shdr* shdrTab =
reinterpret_cast<llvm::ELF::Elf32_Shdr*>(shdr_region->start());
@@ -136,8 +137,10 @@
sh_size = bswap32(shdr->sh_size);
}
- MemoryRegion* sect_name_region = pInput.memArea()->request(sh_offset, sh_size);
- const char* sect_name = reinterpret_cast<const char*>(sect_name_region->start());
+ MemoryRegion* sect_name_region = pInput.memArea()->request(
+ pInput.fileOffset() + sh_offset, sh_size);
+ const char* sect_name =
+ reinterpret_cast<const char*>(sect_name_region->start());
LinkInfoList link_info_list;
@@ -217,8 +220,8 @@
pInputSectHdr.type(),
pInputSectHdr.flag());
- MemoryRegion* region = pInput.memArea()->request(pInputSectHdr.offset(),
- pInputSectHdr.size());
+ MemoryRegion* region = pInput.memArea()->request(
+ pInput.fileOffset() + pInputSectHdr.offset(), pInputSectHdr.size());
llvm::MCSectionData& sect_data = pLinker.getOrCreateSectData(pInputSectHdr);
@@ -360,6 +363,7 @@
}
/// readSymbol - read a symbol from the given Input and index in symtab
+/// This is used to get the signature of a group section.
ResolveInfo* ELFReader<32, true>::readSymbol(Input& pInput,
LDSection& pSymTab,
MCLDInfo& pLDInfo,
@@ -369,7 +373,8 @@
LDSection* strtab = symtab->getLink();
assert(NULL != symtab && NULL != strtab);
- uint32_t offset = symtab->offset() + sizeof(llvm::ELF::Elf32_Sym) * pSymIdx;
+ uint32_t offset = pInput.fileOffset() + symtab->offset() +
+ sizeof(llvm::ELF::Elf32_Sym) * pSymIdx;
MemoryRegion* symbol_region =
pInput.memArea()->request(offset, sizeof(llvm::ELF::Elf32_Sym));
llvm::ELF::Elf32_Sym* entry =
@@ -396,11 +401,12 @@
st_shndx = bswap16(entry->st_shndx);
}
- MemoryRegion* strtab_region =
- pInput.memArea()->request(strtab->offset(), strtab->size());
+ MemoryRegion* strtab_region = pInput.memArea()->request(
+ pInput.fileOffset() + strtab->offset(), strtab->size());
// get ld_name
- llvm::StringRef ld_name(reinterpret_cast<char*>(strtab_region->start() + st_name));
+ llvm::StringRef ld_name(
+ reinterpret_cast<char*>(strtab_region->start() + st_name));
// get ld_type
ResolveInfo::Type ld_type = static_cast<ResolveInfo::Type>(st_info & 0xF);
@@ -409,7 +415,8 @@
ResolveInfo::Desc ld_desc = getSymDesc(st_shndx, pInput);
// get ld_binding
- ResolveInfo::Binding ld_binding = getSymBinding((st_info >> 4), st_shndx, st_other);
+ ResolveInfo::Binding ld_binding =
+ getSymBinding((st_info >> 4), st_shndx, st_other);
// get ld_vis
ResolveInfo::Visibility ld_vis = getSymVisibility(st_other);
@@ -539,11 +546,11 @@
fatal(diag::err_cannot_read_section) << ".dynstr";
}
- MemoryRegion* dynamic_region =
- pInput.memArea()->request(dynamic_sect->offset(), dynamic_sect->size());
+ MemoryRegion* dynamic_region = pInput.memArea()->request(
+ pInput.fileOffset() + dynamic_sect->offset(), dynamic_sect->size());
- MemoryRegion* dynstr_region =
- pInput.memArea()->request(dynstr_sect->offset(), dynstr_sect->size());
+ MemoryRegion* dynstr_region = pInput.memArea()->request(
+ pInput.fileOffset() + dynstr_sect->offset(), dynstr_sect->size());
assert(NULL != dynamic_region && NULL != dynstr_region);
diff --git a/include/mcld/LD/EhFrame.h b/include/mcld/LD/EhFrame.h
index 2e0d2c5..c303240 100644
--- a/include/mcld/LD/EhFrame.h
+++ b/include/mcld/LD/EhFrame.h
@@ -28,6 +28,7 @@
*/
class TargetLDBackend;
+class Input;
class EhFrame
{
@@ -54,6 +55,7 @@
uint64_t readEhFrame(Layout& pLayout,
const TargetLDBackend& pBackend,
llvm::MCSectionData& pSD,
+ const Input& pInput,
LDSection& pSection,
MemoryArea& pArea);
diff --git a/include/mcld/LD/RelocationFactory.h b/include/mcld/LD/RelocationFactory.h
index eed3eae..717a709 100644
--- a/include/mcld/LD/RelocationFactory.h
+++ b/include/mcld/LD/RelocationFactory.h
@@ -37,14 +37,22 @@
typedef Relocation::Address Address;
typedef Relocation::DWord DWord;
+ enum Result {
+ OK,
+ BadReloc,
+ Overflow,
+ Unsupport,
+ Unknown
+ };
+
public:
explicit RelocationFactory(size_t pNum);
virtual ~RelocationFactory();
/// apply - general apply function
- virtual void applyRelocation(Relocation& pRelocation,
- const MCLDInfo& pLDInfo) = 0;
+ virtual Result applyRelocation(Relocation& pRelocation,
+ const MCLDInfo& pLDInfo) = 0;
// ----- production ----- //
/// produce - produce a relocation entry
@@ -70,6 +78,8 @@
virtual const TargetLDBackend& getTarget() const = 0;
+ virtual const char* getName(Type pType) const = 0;
+
private:
const Layout* m_pLayout;
diff --git a/include/mcld/MC/InputTree.h b/include/mcld/MC/InputTree.h
index fa6ba8f..5916916 100644
--- a/include/mcld/MC/InputTree.h
+++ b/include/mcld/MC/InputTree.h
@@ -99,19 +99,19 @@
*/
struct Mover {
virtual ~Mover() {}
- virtual void connect(iterator& pFrom, const const_iterator& pTo) const = 0;
- virtual void move(iterator& pNode) const = 0;
+ virtual void connect(TreeIteratorBase& pFrom, const TreeIteratorBase& pTo) const = 0;
+ virtual void move(TreeIteratorBase& pNode) const = 0;
};
/** \class Succeeder
* \brief class Succeeder moves the iterator afterward.
*/
struct Succeeder : public Mover {
- virtual void connect(iterator& pFrom, const const_iterator& pTo) const {
+ virtual void connect(TreeIteratorBase& pFrom, const TreeIteratorBase& pTo) const {
proxy::hook<Positional>(pFrom.m_pNode, pTo.m_pNode);
}
- virtual void move(iterator& pNode) const {
+ virtual void move(TreeIteratorBase& pNode) const {
pNode.move<Positional>();
}
};
@@ -120,11 +120,11 @@
* \brief class Includer moves the iterator downward.
*/
struct Includer : public Mover {
- virtual void connect(iterator& pFrom, const const_iterator& pTo) const {
+ virtual void connect(TreeIteratorBase& pFrom, const TreeIteratorBase& pTo) const {
proxy::hook<Inclusive>(pFrom.m_pNode, pTo.m_pNode);
}
- virtual void move(iterator& pNode) const {
+ virtual void move(TreeIteratorBase& pNode) const {
pNode.move<Inclusive>();
}
};
@@ -146,33 +146,33 @@
// @param pRoot position the parent node
// @param pMover the direction of the connecting edge of the parent node.
template<size_t DIRECT>
- InputTree& insert(iterator pRoot,
+ InputTree& insert(TreeIteratorBase pRoot,
const std::string& pNamespec,
const sys::fs::Path& pPath,
unsigned int pType = Input::Unknown);
template<size_t DIRECT>
- InputTree& enterGroup(iterator pRoot);
+ InputTree& enterGroup(TreeIteratorBase pRoot);
template<size_t DIRECT>
- InputTree& insert(iterator pRoot,
+ InputTree& insert(TreeIteratorBase pRoot,
const Input& pInput);
- InputTree& merge(iterator pRoot,
+ InputTree& merge(TreeIteratorBase pRoot,
const Mover& pMover,
InputTree& pTree);
- InputTree& insert(iterator pRoot,
+ InputTree& insert(TreeIteratorBase pRoot,
const Mover& pMover,
const std::string& pNamespec,
const sys::fs::Path& pPath,
unsigned int pType = Input::Unknown);
- InputTree& insert(iterator pRoot,
+ InputTree& insert(TreeIteratorBase pRoot,
const Mover& pMover,
const Input& pInput);
- InputTree& enterGroup(iterator pRoot,
+ InputTree& enterGroup(TreeIteratorBase pRoot,
const Mover& pMover);
// ----- observers ----- //
@@ -200,7 +200,7 @@
// template member functions
template<size_t DIRECT>
mcld::InputTree&
-mcld::InputTree::insert(mcld::InputTree::iterator pRoot,
+mcld::InputTree::insert(mcld::TreeIteratorBase pRoot,
const std::string& pNamespec,
const mcld::sys::fs::Path& pPath,
unsigned int pType)
@@ -218,7 +218,7 @@
template<size_t DIRECT>
mcld::InputTree&
-mcld::InputTree::enterGroup(mcld::InputTree::iterator pRoot)
+mcld::InputTree::enterGroup(mcld::TreeIteratorBase pRoot)
{
BinTreeTy::node_type* node = createNode();
if (pRoot.isRoot())
@@ -231,7 +231,7 @@
}
template<size_t DIRECT>
-mcld::InputTree& mcld::InputTree::insert(mcld::InputTree::iterator pRoot,
+mcld::InputTree& mcld::InputTree::insert(mcld::TreeIteratorBase pRoot,
const mcld::Input& pInput)
{
BinTreeTy::node_type* node = createNode();
diff --git a/include/mcld/MC/MCLDInput.h b/include/mcld/MC/MCLDInput.h
index 2f1198c..e9bb4e6 100644
--- a/include/mcld/MC/MCLDInput.h
+++ b/include/mcld/MC/MCLDInput.h
@@ -82,6 +82,6 @@
};
} // namespace of mcld
-
+
#endif
diff --git a/include/mcld/MC/MCLinker.h b/include/mcld/MC/MCLinker.h
index 29e6a46..f592d6e 100644
--- a/include/mcld/MC/MCLinker.h
+++ b/include/mcld/MC/MCLinker.h
@@ -140,9 +140,12 @@
// ----- eh_frame sections ----- //
/// addEhFrame - add an exception handling section
+ /// @param pInput - the Input contains this section
/// @param pSection - the input section
/// @param pArea - the memory area which pSection is within.
- uint64_t addEhFrame(LDSection& pSection, MemoryArea& pArea);
+ uint64_t addEhFrame(const Input& pInput,
+ LDSection& pSection,
+ MemoryArea& pArea);
// ----- relocations ----- //
/// addRelocation - add a relocation entry in MCLinker (only for object file)
diff --git a/include/mcld/Support/MemoryArea.h b/include/mcld/Support/MemoryArea.h
index 5f4a29e..5337f48 100644
--- a/include/mcld/Support/MemoryArea.h
+++ b/include/mcld/Support/MemoryArea.h
@@ -53,10 +53,21 @@
*/
class MemoryArea : private Uncopyable
{
+ friend class MemoryAreaFactory;
public:
- // constructor
- MemoryArea(RegionFactory& pRegionFactory,
- FileHandle& pFileHandle);
+ typedef llvm::iplist<Space> SpaceList;
+
+public:
+ // constructor by file handler.
+ // If the given file handler is read-only, client can not request a region
+ // that out of the file size.
+ // @param pFileHandle - file handler
+ MemoryArea(RegionFactory& pRegionFactory, FileHandle& pFileHandle);
+
+ // constructor by set universal space.
+ // Client can not request a region that out of the universal space.
+ // @param pUniverse - file handler
+ MemoryArea(RegionFactory& pRegionFactory, Space& pUniverse);
// destructor
~MemoryArea();
@@ -80,21 +91,6 @@
const FileHandle* handler() const
{ return m_pFileHandle; }
-private:
- friend class MemoryAreaFactory;
-
-#if defined(ENABLE_UNITTEST)
- friend class mcldtest::MemoryAreaTest;
-#endif
-
- typedef llvm::iplist<Space> SpaceList;
-
-private:
- // ----- special methods ----- //
- // @param pRegionFactory The factory of regions.
- // @param pUniverse A initial univeral space.
- MemoryArea(RegionFactory& pRegionFactory, Space& pUniverse);
-
// ----- space list methods ----- //
Space* find(size_t pOffset, size_t pLength);
diff --git a/include/mcld/Support/Path.h b/include/mcld/Support/Path.h
index 113ff25..54b75c5 100644
--- a/include/mcld/Support/Path.h
+++ b/include/mcld/Support/Path.h
@@ -105,6 +105,7 @@
bool operator==(const Path& pLHS,const Path& pRHS);
bool operator!=(const Path& pLHS,const Path& pRHS);
+Path operator+(const Path& pLHS, const Path& pRHS);
//--------------------------------------------------------------------------//
// non-member functions //
diff --git a/include/mcld/Support/TargetRegistry.h b/include/mcld/Support/TargetRegistry.h
index b31bed4..8d0fee8 100644
--- a/include/mcld/Support/TargetRegistry.h
+++ b/include/mcld/Support/TargetRegistry.h
@@ -49,7 +49,7 @@
typedef TargetLDBackend *(*TargetLDBackendCtorTy)(const llvm::Target&,
const std::string&);
- typedef DiagnosticLineInfo *(*DiagnosticLineInfoCtorTy)(const llvm::Target&,
+ typedef DiagnosticLineInfo *(*DiagnosticLineInfoCtorTy)(const mcld::Target&,
const std::string&);
public:
@@ -97,7 +97,7 @@
}
/// createDiagnosticLineInfo - create target-specific DiagnosticLineInfo
- DiagnosticLineInfo* createDiagnosticLineInfo(const llvm::Target& pTarget,
+ DiagnosticLineInfo* createDiagnosticLineInfo(const mcld::Target& pTarget,
const std::string& pTriple) const
{
if (!DiagnosticLineInfoCtorFn)
diff --git a/include/mcld/Target/GNULDBackend.h b/include/mcld/Target/GNULDBackend.h
index 196420a..9f3e308 100644
--- a/include/mcld/Target/GNULDBackend.h
+++ b/include/mcld/Target/GNULDBackend.h
@@ -272,6 +272,14 @@
const MCLDInfo& pLDInfo,
const Output& pOutput) const;
+ /// symbolNeedsDynRel - return whether the symbol needs a dynamic relocation
+ /// @ref Google gold linker, symtab.h:645
+ bool symbolNeedsDynRel(const ResolveInfo& pSym,
+ bool pSymHasPLT,
+ const MCLDInfo& pLDInfo,
+ const Output& pOutput,
+ bool isAbsReloc) const;
+
protected:
uint64_t getSymbolSize(const LDSymbol& pSymbol) const;
@@ -295,21 +303,12 @@
/// isStaticLink - return whether we're doing static link
bool isStaticLink(const Output& pOutput, const MCLDInfo& pInfo) const;
-public:
/// symbolNeedsPLT - return whether the symbol needs a PLT entry
/// @ref Google gold linker, symtab.h:596
bool symbolNeedsPLT(const ResolveInfo& pSym,
const MCLDInfo& pLDInfo,
const Output& pOutput) const;
- /// symbolNeedsDynRel - return whether the symbol needs a dynamic relocation
- /// @ref Google gold linker, symtab.h:645
- bool symbolNeedsDynRel(const ResolveInfo& pSym,
- bool pSymHasPLT,
- const MCLDInfo& pLDInfo,
- const Output& pOutput,
- bool isAbsReloc) const;
-
/// symbolNeedsCopyReloc - return whether the symbol needs a copy relocation
bool symbolNeedsCopyReloc(const Layout& pLayout,
const Relocation& pReloc,
diff --git a/lib/LD/DiagnosticEngine.cpp b/lib/LD/DiagnosticEngine.cpp
index 11dbe1b..8b209c9 100644
--- a/lib/LD/DiagnosticEngine.cpp
+++ b/lib/LD/DiagnosticEngine.cpp
@@ -13,21 +13,12 @@
using namespace mcld;
-//==========================
+//===----------------------------------------------------------------------===//
// DiagnosticEngine
-DiagnosticEngine::DiagnosticEngine(const MCLDInfo& pLDInfo,
- DiagnosticLineInfo* pLineInfo,
- DiagnosticPrinter* pPrinter,
- bool pShouldOwnPrinter)
- : m_LDInfo(pLDInfo),
- m_pLineInfo(pLineInfo),
- m_pPrinter(pPrinter),
- m_InfoMap(pLDInfo),
- m_OwnPrinter(pShouldOwnPrinter) {
- if (NULL == m_pPrinter) {
- m_pPrinter = new DiagnosticPrinter(); // Dumb printer
- m_OwnPrinter = true;
- }
+//===----------------------------------------------------------------------===//
+DiagnosticEngine::DiagnosticEngine()
+ : m_pLDInfo(NULL), m_pLineInfo(NULL), m_pPrinter(NULL),
+ m_pInfoMap(NULL), m_OwnPrinter(false) {
}
DiagnosticEngine::~DiagnosticEngine()
@@ -39,10 +30,22 @@
delete m_pLineInfo;
}
+void DiagnosticEngine::reset(const MCLDInfo& pLDInfo)
+{
+ m_pLDInfo = &pLDInfo;
+ m_pInfoMap = new DiagnosticInfos(*m_pLDInfo);
+ m_State.reset();
+}
+
+void DiagnosticEngine::setLineInfo(DiagnosticLineInfo& pLineInfo)
+{
+ m_pLineInfo = &pLineInfo;
+}
+
void DiagnosticEngine::setPrinter(DiagnosticPrinter& pPrinter,
bool pShouldOwnPrinter)
{
- if (m_OwnPrinter && m_pPrinter != NULL)
+ if (m_OwnPrinter && NULL != m_pPrinter)
delete m_pPrinter;
m_pPrinter = &pPrinter;
m_OwnPrinter = pShouldOwnPrinter;
@@ -51,7 +54,7 @@
// emit - process current diagnostic.
bool DiagnosticEngine::emit()
{
- bool emitted = m_InfoMap.process(*this);
+ bool emitted = m_pInfoMap->process(*this);
m_State.reset();
return emitted;
}
diff --git a/lib/LD/ELFDynObjReader.cpp b/lib/LD/ELFDynObjReader.cpp
index de36104..1251656 100644
--- a/lib/LD/ELFDynObjReader.cpp
+++ b/lib/LD/ELFDynObjReader.cpp
@@ -44,7 +44,8 @@
// Don't warning about the frequently requests.
// MemoryArea has a list of cache to handle this.
size_t hdr_size = m_pELFReader->getELFHeaderSize();
- MemoryRegion* region = pInput.memArea()->request(0, hdr_size);
+ MemoryRegion* region = pInput.memArea()->request(pInput.fileOffset(),
+ hdr_size);
uint8_t* ELF_hdr = region->start();
bool result = true;
@@ -66,7 +67,8 @@
assert(pInput.hasMemArea());
size_t hdr_size = m_pELFReader->getELFHeaderSize();
- MemoryRegion* region = pInput.memArea()->request(0, hdr_size);
+ MemoryRegion* region = pInput.memArea()->request(pInput.fileOffset(),
+ hdr_size);
uint8_t* ELF_hdr = region->start();
bool shdr_result = m_pELFReader->readSectionHeaders(pInput, m_Linker, ELF_hdr);
@@ -99,13 +101,14 @@
return false;
}
- MemoryRegion* symtab_region = pInput.memArea()->request(symtab_shdr->offset(),
- symtab_shdr->size());
+ MemoryRegion* symtab_region = pInput.memArea()->request(
+ pInput.fileOffset() + symtab_shdr->offset(), symtab_shdr->size());
- MemoryRegion* strtab_region = pInput.memArea()->request(strtab_shdr->offset(),
- strtab_shdr->size());
+ MemoryRegion* strtab_region = pInput.memArea()->request(
+ pInput.fileOffset() + strtab_shdr->offset(), strtab_shdr->size());
char* strtab = reinterpret_cast<char*>(strtab_region->start());
- bool result = m_pELFReader->readSymbols(pInput, m_Linker, *symtab_region, strtab);
+ bool result = m_pELFReader->readSymbols(pInput, m_Linker, *symtab_region,
+ strtab);
pInput.memArea()->release(symtab_region);
pInput.memArea()->release(strtab_region);
diff --git a/lib/LD/ELFObjectReader.cpp b/lib/LD/ELFObjectReader.cpp
index 1ea81e2..c69149c 100644
--- a/lib/LD/ELFObjectReader.cpp
+++ b/lib/LD/ELFObjectReader.cpp
@@ -49,7 +49,8 @@
// Don't warning about the frequently requests.
// MemoryArea has a list of cache to handle this.
size_t hdr_size = m_pELFReader->getELFHeaderSize();
- MemoryRegion* region = pInput.memArea()->request(0, hdr_size);
+ MemoryRegion* region = pInput.memArea()->request(pInput.fileOffset(),
+ hdr_size);
uint8_t* ELF_hdr = region->start();
bool result = true;
@@ -71,7 +72,8 @@
assert(pInput.hasMemArea());
size_t hdr_size = m_pELFReader->getELFHeaderSize();
- MemoryRegion* region = pInput.memArea()->request(0, hdr_size);
+ MemoryRegion* region = pInput.memArea()->request(pInput.fileOffset(),
+ hdr_size);
uint8_t* ELF_hdr = region->start();
bool result = m_pELFReader->readSectionHeaders(pInput, m_Linker, ELF_hdr);
pInput.memArea()->release(region);
@@ -111,11 +113,10 @@
if (exist) {
// if this is not the first time we see this group signature, then
// ignore all the members in this group (set NULL)
- MemoryRegion* region =
- pInput.memArea()->request((*section)->offset(),
- (*section)->size());
+ MemoryRegion* region = pInput.memArea()->request(
+ pInput.fileOffset() + (*section)->offset(), (*section)->size());
llvm::ELF::Elf32_Word* value =
- reinterpret_cast<llvm::ELF::Elf32_Word*>(region->start());
+ reinterpret_cast<llvm::ELF::Elf32_Word*>(region->start());
size_t size = region->size() / sizeof(llvm::ELF::Elf32_Word);
if (llvm::ELF::GRP_COMDAT == *value) {
@@ -225,10 +226,10 @@
return false;
}
- MemoryRegion* symtab_region = pInput.memArea()->request(symtab_shdr->offset(),
- symtab_shdr->size());
- MemoryRegion* strtab_region = pInput.memArea()->request(strtab_shdr->offset(),
- strtab_shdr->size());
+ MemoryRegion* symtab_region = pInput.memArea()->request(
+ pInput.fileOffset() + symtab_shdr->offset(), symtab_shdr->size());
+ MemoryRegion* strtab_region = pInput.memArea()->request(
+ pInput.fileOffset() + strtab_shdr->offset(), strtab_shdr->size());
char* strtab = reinterpret_cast<char*>(strtab_region->start());
bool result = m_pELFReader->readSymbols(pInput,
m_Linker,
@@ -252,15 +253,18 @@
if ((*section)->type() == llvm::ELF::SHT_RELA &&
(*section)->kind() == LDFileFormat::Relocation) {
- MemoryRegion* region = mem->request((*section)->offset(), (*section)->size());
- bool result = m_pELFReader->readRela(pInput, m_Linker, **section, *region);
+ MemoryRegion* region = mem->request(
+ pInput.fileOffset() + (*section)->offset(), (*section)->size());
+ bool result = m_pELFReader->readRela(pInput, m_Linker, **section,
+ *region);
mem->release(region);
if (!result)
return false;
}
else if ((*section)->type() == llvm::ELF::SHT_REL &&
(*section)->kind() == LDFileFormat::Relocation) {
- MemoryRegion* region = mem->request((*section)->offset(), (*section)->size());
+ MemoryRegion* region = mem->request(
+ pInput.fileOffset() + (*section)->offset(), (*section)->size());
bool result = m_pELFReader->readRel(pInput, m_Linker, **section, *region);
mem->release(region);
if (!result)
diff --git a/lib/LD/ELFReader.cpp b/lib/LD/ELFReader.cpp
index 6aacc08..d74d314 100644
--- a/lib/LD/ELFReader.cpp
+++ b/lib/LD/ELFReader.cpp
@@ -141,7 +141,7 @@
uint16_t pShndx,
uint32_t pOffset) const
{
-
+
if (pShndx == llvm::ELF::SHN_UNDEF || pShndx >= llvm::ELF::SHN_LORESERVE)
return NULL;
@@ -150,7 +150,7 @@
if (NULL == sect_hdr)
unreachable(diag::unreachable_invalid_section_idx) << pShndx
<< pInput.path().native();
-
+
MCFragmentRef* result = pLinker.getLayout().getFragmentRef(*sect_hdr, pOffset);
return result;
}
@@ -197,7 +197,7 @@
pInputSectHdr.type(),
pInputSectHdr.flag());
- size_t size = pLinker.addEhFrame(pInputSectHdr, *pInput.memArea());
+ size_t size = pLinker.addEhFrame(pInput, pInputSectHdr, *pInput.memArea());
out_sect.setSize(out_sect.size() + size);
return true;
diff --git a/lib/LD/EhFrame.cpp b/lib/LD/EhFrame.cpp
index 76af403..4a84b00 100644
--- a/lib/LD/EhFrame.cpp
+++ b/lib/LD/EhFrame.cpp
@@ -28,11 +28,12 @@
uint64_t EhFrame::readEhFrame(Layout& pLayout,
const TargetLDBackend& pBackend,
llvm::MCSectionData& pSD,
+ const Input& pInput,
LDSection& pSection,
MemoryArea& pArea)
{
- MemoryRegion* region = pArea.request(pSection.offset(),
- pSection.size());
+ MemoryRegion* region = pArea.request(
+ pInput.fileOffset() + pSection.offset(), pSection.size());
// an empty .eh_frame
if (NULL == region) {
note(diag::note_ehframe) << "an empty eh_frame";
@@ -100,8 +101,8 @@
uint32_t ent_offset = static_cast<uint32_t>(p - eh_start - 4);
// get the MemoryRegion for this entry
- MemoryRegion* ent_region = pArea.request(pSection.offset() + ent_offset,
- len + 4);
+ MemoryRegion* ent_region = pArea.request(
+ pInput.fileOffset() + pSection.offset() + ent_offset, len + 4);
// create and add a CIE or FDE entry
uint32_t id = readVal(p, pBackend.isLittleEndian());
diff --git a/lib/LD/Relocation.cpp b/lib/LD/Relocation.cpp
index 0b84ad0..4a901ba 100644
--- a/lib/LD/Relocation.cpp
+++ b/lib/LD/Relocation.cpp
@@ -7,10 +7,10 @@
//
//===----------------------------------------------------------------------===//
#include <llvm/MC/MCAssembler.h>
-//#include <mcld/MC/MCLDInfo.h>
#include <mcld/LD/Relocation.h>
#include <mcld/LD/RelocationFactory.h>
#include <mcld/LD/Layout.h>
+#include <mcld/Support/MsgHandling.h>
using namespace mcld;
@@ -51,7 +51,30 @@
void Relocation::apply(RelocationFactory& pRelocFactory,
const MCLDInfo& pLDInfo)
{
- pRelocFactory.applyRelocation(*this, pLDInfo);
+ RelocationFactory::Result result =
+ pRelocFactory.applyRelocation(*this, pLDInfo);
+
+ switch (result) {
+ case RelocationFactory::OK: {
+ // do nothing
+ return;
+ }
+ case RelocationFactory::Overflow: {
+ error(diag::result_overflow) << pRelocFactory.getName(type())
+ << symInfo()->name();
+ return;
+ }
+ case RelocationFactory::BadReloc: {
+ error(diag::result_badreloc) << pRelocFactory.getName(type())
+ << symInfo()->name();
+ return;
+ }
+ case RelocationFactory::Unsupport: {
+ fatal(diag::unsupported_relocation) << type()
+ << "mclinker@googlegroups.com";
+ return;
+ }
+ } // end of switch
}
void Relocation::setType(Type pType)
diff --git a/lib/MC/InputTree.cpp b/lib/MC/InputTree.cpp
index a1d1449..1416b6a 100644
--- a/lib/MC/InputTree.cpp
+++ b/lib/MC/InputTree.cpp
@@ -24,7 +24,7 @@
{
}
-InputTree& InputTree::merge(InputTree::iterator pRoot,
+InputTree& InputTree::merge(TreeIteratorBase pRoot,
const InputTree::Mover& pMover,
InputTree& pTree)
{
@@ -41,7 +41,7 @@
return *this;
}
-InputTree& InputTree::insert(InputTree::iterator pRoot,
+InputTree& InputTree::insert(TreeIteratorBase pRoot,
const InputTree::Mover& pMover,
const std::string& pNamespec,
const sys::fs::Path& pPath,
@@ -53,7 +53,7 @@
return *this;
}
-InputTree& InputTree::enterGroup(InputTree::iterator pRoot,
+InputTree& InputTree::enterGroup(TreeIteratorBase pRoot,
const InputTree::Mover& pMover)
{
NodeBase* node = createNode();
@@ -61,7 +61,7 @@
return *this;
}
-InputTree& InputTree::insert(InputTree::iterator pRoot,
+InputTree& InputTree::insert(TreeIteratorBase pRoot,
const InputTree::Mover& pMover,
const mcld::Input& pInput)
{
diff --git a/lib/MC/MCLDInput.cpp b/lib/MC/MCLDInput.cpp
index 81a8b60..0803e00 100644
--- a/lib/MC/MCLDInput.cpp
+++ b/lib/MC/MCLDInput.cpp
@@ -16,7 +16,8 @@
Input::Input(llvm::StringRef pName, const AttributeProxy& pProxy)
: MCLDFile(pName),
m_pAttr(const_cast<Attribute*>(pProxy.attr())),
- m_bNeeded(false) {
+ m_bNeeded(false),
+ m_fileOffset(0) {
}
Input::Input(llvm::StringRef pName,
diff --git a/lib/MC/MCLinker.cpp b/lib/MC/MCLinker.cpp
index 4b9c50f..7321e49 100644
--- a/lib/MC/MCLinker.cpp
+++ b/lib/MC/MCLinker.cpp
@@ -660,7 +660,9 @@
/// addEhFrame - add an exception handling section
/// @param pSection - the input section
/// @param pArea - the memory area which pSection is within.
-uint64_t MCLinker::addEhFrame(LDSection& pSection, MemoryArea& pArea)
+uint64_t MCLinker::addEhFrame(const Input& pInput,
+ LDSection& pSection,
+ MemoryArea& pArea)
{
uint64_t size = 0;
@@ -672,8 +674,8 @@
EhFrame* ehframe = m_Backend.getEhFrame();
assert(NULL != ehframe);
if (ehframe->canRecognizeAllEhFrame()) {
- size = ehframe->readEhFrame(m_Layout, m_Backend, sect_data, pSection,
- pArea);
+ size = ehframe->readEhFrame(m_Layout, m_Backend, sect_data, pInput,
+ pSection, pArea);
// zero size indicate that this is an empty section or we can't recognize
// this eh_frame, handle it as a regular section.
if (0 != size)
@@ -682,7 +684,7 @@
}
// handle eh_frame as a regular section
- MemoryRegion* region = pArea.request(pSection.offset(),
+ MemoryRegion* region = pArea.request(pInput.fileOffset() + pSection.offset(),
pSection.size());
llvm::MCFragment* frag = NULL;
diff --git a/lib/Support/MemoryArea.cpp b/lib/Support/MemoryArea.cpp
index 78a9d36..844d8f6 100644
--- a/lib/Support/MemoryArea.cpp
+++ b/lib/Support/MemoryArea.cpp
@@ -16,6 +16,7 @@
//===--------------------------------------------------------------------===//
// MemoryArea
+//===--------------------------------------------------------------------===//
// MemoryArea - special constructor
// This constructor is used for *SPECIAL* situation. I'm sorry I can not
@@ -54,12 +55,11 @@
{
Space* space = find(pOffset, pLength);
if (NULL == space) {
-
// not found
if (NULL == m_pFileHandle) {
// if m_pFileHandle is NULL, clients delegate us an universal Space and
// we never remove it. In that way, space can not be NULL.
- unreachable(diag::err_out_of_range_region);
+ unreachable(diag::err_out_of_range_region) << pOffset << pLength;
}
space = Space::createSpace(*m_pFileHandle, pOffset, pLength);
@@ -94,8 +94,8 @@
Space::syncSpace(space, *m_pFileHandle);
}
Space::releaseSpace(space, *m_pFileHandle);
+ m_SpaceList.erase(space);
}
- m_SpaceList.erase(space);
}
}
diff --git a/lib/Support/MsgHandling.cpp b/lib/Support/MsgHandling.cpp
index 5b45289..d7611d2 100644
--- a/lib/Support/MsgHandling.cpp
+++ b/lib/Support/MsgHandling.cpp
@@ -17,58 +17,29 @@
using namespace mcld;
//===----------------------------------------------------------------------===//
-// DiagnosticInitializer
-class DiagnosticInitializer : public llvm::ManagedStaticBase
+// static variables
+//===----------------------------------------------------------------------===//
+static llvm::ManagedStatic<DiagnosticEngine> g_pEngine;
+
+void
+mcld::InitializeDiagnosticEngine(const mcld::MCLDInfo& pLDInfo,
+ DiagnosticLineInfo* pLineInfo,
+ DiagnosticPrinter* pPrinter)
{
-public:
- DiagnosticEngine* initialize(const MCLDInfo& pLDInfo,
- DiagnosticLineInfo* pLineInfo,
- DiagnosticPrinter* pPrinter)
- {
- RegisterManagedStatic(NULL, llvm::object_deleter<DiagnosticEngine>::call);
- if (llvm::llvm_is_multithreaded()) {
- llvm::llvm_acquire_global_lock();
- void* tmp = NULL;
- if (NULL != pPrinter)
- tmp = new DiagnosticEngine(pLDInfo, pLineInfo, pPrinter, false);
- else
- tmp = new DiagnosticEngine(pLDInfo, pLineInfo, NULL, false);
+ g_pEngine->reset(pLDInfo);
+ if (NULL != pLineInfo)
+ g_pEngine->setLineInfo(*pLineInfo);
- TsanHappensBefore(this);
- llvm::sys::MemoryFence();
- TsanIgnoreWritesBegin();
- Ptr = tmp;
- TsanIgnoreWritesEnd();
- llvm::llvm_release_global_lock();
- }
- else {
- if (NULL != pPrinter)
- Ptr = new DiagnosticEngine(pLDInfo, pLineInfo, pPrinter, false);
- else
- Ptr = new DiagnosticEngine(pLDInfo, pLineInfo, NULL, false);
- }
- return static_cast<DiagnosticEngine*>(Ptr);
- }
-};
-
-static DiagnosticInitializer g_DiagInitializer;
-static DiagnosticEngine* g_pDiagnosticEngine = NULL;
-
-void mcld::InitializeDiagnosticEngine(const mcld::MCLDInfo& pLDInfo,
- DiagnosticLineInfo* pLineInfo,
- DiagnosticPrinter* pPrinter)
-{
- if (NULL == g_pDiagnosticEngine) {
- g_pDiagnosticEngine = g_DiagInitializer.initialize(pLDInfo,
- pLineInfo,
- pPrinter);
+ if (NULL != pPrinter)
+ g_pEngine->setPrinter(*pPrinter, false);
+ else {
+ DiagnosticPrinter* printer = new DiagnosticPrinter();
+ g_pEngine->setPrinter(*printer, true);
}
}
DiagnosticEngine& mcld::getDiagnosticEngine()
{
- assert(NULL != g_pDiagnosticEngine &&
- "mcld::InitializeDiagnostics() is not called");
- return *g_pDiagnosticEngine;
+ return *g_pEngine;
}
diff --git a/lib/Support/Path.cpp b/lib/Support/Path.cpp
index 55baa52..e35132f 100644
--- a/lib/Support/Path.cpp
+++ b/lib/Support/Path.cpp
@@ -12,7 +12,8 @@
#include <locale>
#include <string.h>
-#include <iostream>
+#include <istream>
+#include <ostream>
using namespace mcld;
using namespace mcld::sys::fs;
@@ -142,7 +143,7 @@
Path Path::stem() const
{
size_t begin_pos = m_PathName.find_last_of(separator)+1;
- size_t end_pos = m_PathName.find_first_of(".", begin_pos);
+ size_t end_pos = m_PathName.find_last_of(".");
Path result_path(m_PathName.substr(begin_pos, end_pos - begin_pos));
return result_path;
}
@@ -156,6 +157,7 @@
//===--------------------------------------------------------------------===//
// non-member functions
+//===--------------------------------------------------------------------===//
bool mcld::sys::fs::operator==(const Path& pLHS,const Path& pRHS)
{
return (pLHS.generic_string()==pRHS.generic_string());
@@ -166,6 +168,13 @@
return !(pLHS==pRHS);
}
+Path mcld::sys::fs::operator+(const Path& pLHS, const Path& pRHS)
+{
+ mcld::sys::fs::Path result = pLHS;
+ result.append(pRHS);
+ return result;
+}
+
bool mcld::sys::fs::is_separator(char value)
{
return (value == separator
@@ -206,3 +215,4 @@
{
return pOS << pPath.native();
}
+
diff --git a/lib/Target/ARM/ARMDiagnostic.cpp b/lib/Target/ARM/ARMDiagnostic.cpp
index 1ecf7df..d6f3988 100644
--- a/lib/Target/ARM/ARMDiagnostic.cpp
+++ b/lib/Target/ARM/ARMDiagnostic.cpp
@@ -21,7 +21,7 @@
//===----------------------------------------------------------------------===//
// createARMDiagnostic - the help function to create corresponding ARMDiagnostic
//
-DiagnosticLineInfo* createARMDiagLineInfo(const llvm::Target& pTarget,
+DiagnosticLineInfo* createARMDiagLineInfo(const mcld::Target& pTarget,
const std::string &pTriple)
{
return new DWARFLineInfo();
diff --git a/lib/Target/ARM/ARMGOT.cpp b/lib/Target/ARM/ARMGOT.cpp
index 7430203..af37768 100644
--- a/lib/Target/ARM/ARMGOT.cpp
+++ b/lib/Target/ARM/ARMGOT.cpp
@@ -40,10 +40,9 @@
// Skip GOT0 entries.
iterator it = m_SectionData.begin();
- iterator ie = m_SectionData.end();
for (int i = 1; i < ARMGOT0Num; ++i) {
- assert((it != ie) && "Generation of GOT0 entries is incomplete!");
+ assert((it != m_SectionData.end()) && "Generation of GOT0 entries is incomplete!");
++it;
}
diff --git a/lib/Target/ARM/ARMLDBackend.cpp b/lib/Target/ARM/ARMLDBackend.cpp
index e0f5dcf..81915c9 100644
--- a/lib/Target/ARM/ARMLDBackend.cpp
+++ b/lib/Target/ARM/ARMLDBackend.cpp
@@ -35,6 +35,7 @@
m_pRelDyn(NULL),
m_pRelPLT(NULL),
m_pDynamic(NULL),
+ m_pGOTSymbol(NULL),
m_pEXIDX(NULL),
m_pEXTAB(NULL),
m_pAttributes(NULL) {
@@ -840,8 +841,8 @@
(0 != out_sect.size()))
return true;
- MemoryRegion* region = pInput.memArea()->request(pInputSectHdr.offset(),
- pInputSectHdr.size());
+ MemoryRegion* region = pInput.memArea()->request(
+ pInput.fileOffset() + pInputSectHdr.offset(), pInputSectHdr.size());
llvm::MCSectionData& sect_data = pLinker.getOrCreateSectData(pInputSectHdr);
diff --git a/lib/Target/ARM/ARMPLT.cpp b/lib/Target/ARM/ARMPLT.cpp
index 5528ef7..015d767 100644
--- a/lib/Target/ARM/ARMPLT.cpp
+++ b/lib/Target/ARM/ARMPLT.cpp
@@ -91,8 +91,7 @@
"The number of PLT Entries and ResolveInfo doesn't match");
ARMGOT::iterator got_it = m_GOT.getNextGOTPLTEntry();
- ARMGOT::iterator got_ie = m_GOT.getGOTPLTEnd();
- assert(got_it != got_ie && "The number of GOTPLT and PLT doesn't match");
+ assert(got_it != m_GOT.getGOTPLTEnd() && "The number of GOTPLT and PLT doesn't match");
PLTEntry = llvm::cast<ARMPLT1>(&(*m_PLTEntryIterator));
GOTPLTEntry = llvm::cast<GOTEntry>(&(*got_it));
@@ -119,8 +118,8 @@
"The number of PLT Entries and ResolveInfo doesn't match");
ARMGOT::iterator got_it = m_GOT.getNextGOTPLTEntry();
- ARMGOT::iterator got_ie = m_GOT.getGOTPLTEnd();
- assert(got_it != got_ie && "The number of GOTPLT and PLT doesn't match");
+ assert(got_it != m_GOT.getGOTPLTEnd() &&
+ "The number of GOTPLT and PLT doesn't match");
PLTEntry = llvm::cast<ARMPLT1>(&(*m_PLTEntryIterator));
GOTPLTEntry = llvm::cast<GOTEntry>(&(*got_it));
@@ -132,9 +131,9 @@
ARMPLT0* ARMPLT::getPLT0() const {
iterator first = m_SectionData.getFragmentList().begin();
- iterator end = m_SectionData.getFragmentList().end();
- assert(first!=end && "FragmentList is empty, getPLT0 failed!");
+ assert(first != m_SectionData.getFragmentList().end() &&
+ "FragmentList is empty, getPLT0 failed!");
ARMPLT0* plt0 = &(llvm::cast<ARMPLT0>(*first));
@@ -157,9 +156,9 @@
offset = (plt_base + 16) - got_base;
iterator first = m_SectionData.getFragmentList().begin();
- iterator end = m_SectionData.getFragmentList().end();
- assert(first!=end && "FragmentList is empty, applyPLT0 failed!");
+ assert(first != m_SectionData.getFragmentList().end() &&
+ "FragmentList is empty, applyPLT0 failed!");
ARMPLT0* plt0 = &(llvm::cast<ARMPLT0>(*first));
@@ -185,7 +184,7 @@
ARMPLT::iterator it = m_SectionData.begin();
ARMPLT::iterator ie = m_SectionData.end();
- assert(it!=ie && "FragmentList is empty, applyPLT1 failed!");
+ assert(it != ie && "FragmentList is empty, applyPLT1 failed!");
uint32_t GOTEntrySize = m_GOT.getEntrySize();
uint32_t GOTEntryAddress =
diff --git a/lib/Target/ARM/ARMRelocationFactory.cpp b/lib/Target/ARM/ARMRelocationFactory.cpp
index 4911658..3d4b0dc 100644
--- a/lib/Target/ARM/ARMRelocationFactory.cpp
+++ b/lib/Target/ARM/ARMRelocationFactory.cpp
@@ -20,10 +20,33 @@
using namespace mcld;
+//===--------------------------------------------------------------------===//
+// Relocation Functions and Tables
+//===--------------------------------------------------------------------===//
DECL_ARM_APPLY_RELOC_FUNCS
+/// the prototype of applying function
+typedef RelocationFactory::Result (*ApplyFunctionType)(
+ Relocation& pReloc,
+ const MCLDInfo& pLDInfo,
+ ARMRelocationFactory& pParent);
+
+// the table entry of applying functions
+struct ApplyFunctionTriple
+{
+ ApplyFunctionType func;
+ unsigned int type;
+ const char* name;
+};
+
+// declare the table of applying functions
+static const ApplyFunctionTriple ApplyFunctions[] = {
+ DECL_ARM_APPLY_RELOC_FUNC_PTRS
+};
+
//===--------------------------------------------------------------------===//
// ARMRelocationFactory
+//===--------------------------------------------------------------------===//
ARMRelocationFactory::ARMRelocationFactory(size_t pNum,
ARMGNULDBackend& pParent)
: RelocationFactory(pNum),
@@ -34,58 +57,24 @@
{
}
-void ARMRelocationFactory::applyRelocation(Relocation& pRelocation,
- const MCLDInfo& pLDInfo)
+RelocationFactory::Result
+ARMRelocationFactory::applyRelocation(Relocation& pRelocation,
+ const MCLDInfo& pLDInfo)
{
Relocation::Type type = pRelocation.type();
if (type > 130) { // 131-255 doesn't noted in ARM spec
fatal(diag::unknown_relocation) << (int)type
<< pRelocation.symInfo()->name();
- return;
+ return RelocationFactory::Unknown;
}
- /// the prototype of applying function
- typedef Result (*ApplyFunctionType)(Relocation& pReloc,
- const MCLDInfo& pLDInfo,
- ARMRelocationFactory& pParent);
-
- // the table entry of applying functions
- struct ApplyFunctionTriple {
- ApplyFunctionType func;
- unsigned int type;
- const char* name;
- };
-
- // declare the table of applying functions
- static ApplyFunctionTriple apply_functions[] = {
- DECL_ARM_APPLY_RELOC_FUNC_PTRS
- };
-
- // apply the relocation
- Result result = apply_functions[type].func(pRelocation, pLDInfo, *this);
-
- // check result
- if (OK == result) {
- return;
- }
- if (Overflow == result) {
- error(diag::result_overflow) << apply_functions[type].name
- << pRelocation.symInfo()->name();
- return;
- }
- if (BadReloc == result) {
- error(diag::result_badreloc) << apply_functions[type].name
- << pRelocation.symInfo()->name();
- return;
- }
- if (Unsupport == result) {
- fatal(diag::unsupported_relocation) << type
- << "mclinker@googlegroups.com";
- return;
- }
+ return ApplyFunctions[type].func(pRelocation, pLDInfo, *this);
}
-
+const char* ARMRelocationFactory::getName(RelocationFactory::Type pType) const
+{
+ return ApplyFunctions[pType].name;
+}
//===--------------------------------------------------------------------===//
// non-member functions
@@ -570,7 +559,8 @@
ARMRelocationFactory::DWord X = ((S + A) | T) - P;
// Check X is 24bit sign int. If not, we should use stub or PLT before apply.
- assert(!helper_check_signed_overflow(X, 26) && "Jump or Call target too far!");
+ if (helper_check_signed_overflow(X, 26))
+ return ARMRelocationFactory::Overflow;
// Make sure the Imm is 0. Result Mask.
pReloc.target() = (pReloc.target() & 0xFF000000u) | ((X & 0x03FFFFFEu) >> 2);
return ARMRelocationFactory::OK;
@@ -638,7 +628,6 @@
// FIXME: Check bit size is 24(thumb2) or 22?
if (helper_check_signed_overflow(X, 25)) {
- assert(!"Offset is too far. We need stub or PLT for it.");
return ARMRelocationFactory::Overflow;
}
@@ -664,10 +653,10 @@
ARMRelocationFactory::DWord X;
const LDSection* target_sect = pParent.getLayout().getOutputLDSection(
- *(pReloc.targetRef().frag()));
+ *(pReloc.targetRef().frag()));
assert(NULL != target_sect);
- // If the flag of target section is not ALLOC, we will not scan this relocation
- // but perform static relocation. (e.g., applying .debug section)
+ // If the flag of target section is not ALLOC, we will not scan this
+ // relocation but perform static relocation. (e.g., applying .debug section)
if (0x0 != (llvm::ELF::SHF_ALLOC & target_sect->flag())) {
// use plt
if (rsym->reserved() & ARMGNULDBackend::ReservePLT) {
@@ -676,15 +665,11 @@
}
}
- X = (S + A) | T ;
// perform static relocation
- pReloc.target() = (S + A) | T;
- if (helper_check_signed_overflow(X, 16)) {
- return ARMRelocationFactory::Overflow;
- } else {
- pReloc.target() = helper_insert_val_movw_movt_inst(pReloc.target(), X);
- return ARMRelocationFactory::OK;
- }
+ X = (S + A) | T;
+ pReloc.target() = helper_insert_val_movw_movt_inst(
+ pReloc.target() + pReloc.addend(), X);
+ return ARMRelocationFactory::OK;
}
// R_ARM_MOVW_PREL_NC: ((S + A) | T) - P
diff --git a/lib/Target/ARM/ARMRelocationFactory.h b/lib/Target/ARM/ARMRelocationFactory.h
index 636dbee..b0b3483 100644
--- a/lib/Target/ARM/ARMRelocationFactory.h
+++ b/lib/Target/ARM/ARMRelocationFactory.h
@@ -26,22 +26,10 @@
class ARMRelocationFactory : public RelocationFactory
{
public:
- /** \enum Reloc
- * \brief Reloc is the result of applying functions.
- */
- enum Result
- {
- OK,
- Overflow,
- BadReloc,
- Unsupport
- };
-
-public:
ARMRelocationFactory(size_t pNum, ARMGNULDBackend& pParent);
~ARMRelocationFactory();
- void applyRelocation(Relocation& pRelocation, const MCLDInfo& pLDInfo);
+ Result applyRelocation(Relocation& pRelocation, const MCLDInfo& pLDInfo);
ARMGNULDBackend& getTarget()
{ return m_Target; }
@@ -49,6 +37,8 @@
const ARMGNULDBackend& getTarget() const
{ return m_Target; }
+ const char* getName(Relocation::Type pType) const;
+
private:
ARMGNULDBackend& m_Target;
};
diff --git a/lib/Target/ARM/ARMSectLinker.cpp b/lib/Target/ARM/ARMSectLinker.cpp
index 06dba05..52a00e3 100644
--- a/lib/Target/ARM/ARMSectLinker.cpp
+++ b/lib/Target/ARM/ARMSectLinker.cpp
@@ -25,9 +25,11 @@
Triple theTriple(pTriple);
if (theTriple.isOSDarwin()) {
assert(0 && "MachO linker has not supported yet");
+ return NULL;
}
if (theTriple.isOSWindows()) {
assert(0 && "COFF linker has not supported yet");
+ return NULL;
}
// For now, use Android SectLinker directly
diff --git a/lib/Target/GNULDBackend.cpp b/lib/Target/GNULDBackend.cpp
index 9fff9e3..69d0927 100644
--- a/lib/Target/GNULDBackend.cpp
+++ b/lib/Target/GNULDBackend.cpp
@@ -99,21 +99,21 @@
bool GNULDBackend::initArchiveReader(MCLinker&, MCLDInfo &pInfo)
{
- if (0 == m_pArchiveReader)
+ if (NULL == m_pArchiveReader)
m_pArchiveReader = new GNUArchiveReader(pInfo);
return true;
}
bool GNULDBackend::initObjectReader(MCLinker& pLinker)
{
- if (0 == m_pObjectReader)
+ if (NULL == m_pObjectReader)
m_pObjectReader = new ELFObjectReader(*this, pLinker);
return true;
}
bool GNULDBackend::initDynObjReader(MCLinker& pLinker)
{
- if (0 == m_pDynObjReader)
+ if (NULL == m_pDynObjReader)
m_pDynObjReader = new ELFDynObjReader(*this, pLinker);
return true;
}
@@ -140,7 +140,7 @@
bool GNULDBackend::initExecSections(MCLinker& pMCLinker)
{
- if (0 == m_pExecFileFormat)
+ if (NULL == m_pExecFileFormat)
m_pExecFileFormat = new ELFExecFileFormat(*this);
// initialize standard sections
@@ -150,7 +150,7 @@
bool GNULDBackend::initDynObjSections(MCLinker& pMCLinker)
{
- if (0 == m_pDynObjFileFormat)
+ if (NULL == m_pDynObjFileFormat)
m_pDynObjFileFormat = new ELFDynObjFileFormat(*this);
// initialize standard sections
@@ -552,37 +552,37 @@
GNUArchiveReader *GNULDBackend::getArchiveReader()
{
- assert(0 != m_pArchiveReader);
+ assert(NULL != m_pArchiveReader);
return m_pArchiveReader;
}
const GNUArchiveReader *GNULDBackend::getArchiveReader() const
{
- assert(0 != m_pArchiveReader);
+ assert(NULL != m_pArchiveReader);
return m_pArchiveReader;
}
ELFObjectReader *GNULDBackend::getObjectReader()
{
- assert(0 != m_pObjectReader);
+ assert(NULL != m_pObjectReader);
return m_pObjectReader;
}
const ELFObjectReader *GNULDBackend::getObjectReader() const
{
- assert(0 != m_pObjectReader);
+ assert(NULL != m_pObjectReader);
return m_pObjectReader;
}
ELFDynObjReader *GNULDBackend::getDynObjReader()
{
- assert(0 != m_pDynObjReader);
+ assert(NULL != m_pDynObjReader);
return m_pDynObjReader;
}
const ELFDynObjReader *GNULDBackend::getDynObjReader() const
{
- assert(0 != m_pDynObjReader);
+ assert(NULL != m_pDynObjReader);
return m_pDynObjReader;
}
@@ -600,13 +600,13 @@
ELFDynObjWriter *GNULDBackend::getDynObjWriter()
{
- assert(0 != m_pDynObjWriter);
+ assert(NULL != m_pDynObjWriter);
return m_pDynObjWriter;
}
const ELFDynObjWriter *GNULDBackend::getDynObjWriter() const
{
- assert(0 != m_pDynObjWriter);
+ assert(NULL != m_pDynObjWriter);
return m_pDynObjWriter;
}
@@ -654,25 +654,25 @@
ELFDynObjFileFormat* GNULDBackend::getDynObjFileFormat()
{
- assert(0 != m_pDynObjFileFormat);
+ assert(NULL != m_pDynObjFileFormat);
return m_pDynObjFileFormat;
}
const ELFDynObjFileFormat* GNULDBackend::getDynObjFileFormat() const
{
- assert(0 != m_pDynObjFileFormat);
+ assert(NULL != m_pDynObjFileFormat);
return m_pDynObjFileFormat;
}
ELFExecFileFormat* GNULDBackend::getExecFileFormat()
{
- assert(0 != m_pExecFileFormat);
+ assert(NULL != m_pExecFileFormat);
return m_pExecFileFormat;
}
const ELFExecFileFormat* GNULDBackend::getExecFileFormat() const
{
- assert(0 != m_pExecFileFormat);
+ assert(NULL != m_pExecFileFormat);
return m_pExecFileFormat;
}
diff --git a/lib/Target/Mips/MipsDiagnostic.cpp b/lib/Target/Mips/MipsDiagnostic.cpp
index c90c6ef..f6b6339 100644
--- a/lib/Target/Mips/MipsDiagnostic.cpp
+++ b/lib/Target/Mips/MipsDiagnostic.cpp
@@ -18,7 +18,7 @@
//===----------------------------------------------------------------------===//
// createMipsDiagnostic - the help function to create corresponding
// MipsDiagnostic
-DiagnosticLineInfo* createMipsDiagLineInfo(const llvm::Target& pTarget,
+DiagnosticLineInfo* createMipsDiagLineInfo(const mcld::Target& pTarget,
const std::string &pTriple)
{
return new DWARFLineInfo();
diff --git a/lib/Target/Mips/MipsGOT.cpp b/lib/Target/Mips/MipsGOT.cpp
index 9baa033..57e5c70 100644
--- a/lib/Target/Mips/MipsGOT.cpp
+++ b/lib/Target/Mips/MipsGOT.cpp
@@ -38,10 +38,10 @@
// Skip GOT0 entries.
iterator it = m_SectionData.begin();
- iterator ie = m_SectionData.end();
for (size_t i = 1; i < MipsGOT0Num; ++i) {
- assert((it != ie) && "Generation of GOT0 entries is incomplete!");
+ assert((it != m_SectionData.end()) &&
+ "Generation of GOT0 entries is incomplete!");
++it;
}
diff --git a/lib/Target/Mips/MipsRelocationFactory.cpp b/lib/Target/Mips/MipsRelocationFactory.cpp
index 948e026..e9d26f8 100644
--- a/lib/Target/Mips/MipsRelocationFactory.cpp
+++ b/lib/Target/Mips/MipsRelocationFactory.cpp
@@ -18,10 +18,32 @@
using namespace mcld;
+//===----------------------------------------------------------------------===//
+// Relocation Functions and Tables
+//===----------------------------------------------------------------------===//
DECL_MIPS_APPLY_RELOC_FUNCS
-//==========================
+/// the prototype of applying function
+typedef RelocationFactory::Result (*ApplyFunctionType)(Relocation&,
+ const MCLDInfo& pLDInfo,
+ MipsRelocationFactory&);
+
+// the table entry of applying functions
+struct ApplyFunctionTriple
+{
+ ApplyFunctionType func;
+ unsigned int type;
+ const char* name;
+};
+
+// declare the table of applying functions
+static const ApplyFunctionTriple ApplyFunctions[] = {
+ DECL_MIPS_APPLY_RELOC_FUNC_PTRS
+};
+
+//===----------------------------------------------------------------------===//
// MipsRelocationFactory
+//===----------------------------------------------------------------------===//
MipsRelocationFactory::MipsRelocationFactory(size_t pNum,
MipsGNULDBackend& pParent)
: RelocationFactory(pNum),
@@ -30,58 +52,32 @@
{
}
-void MipsRelocationFactory::applyRelocation(Relocation& pRelocation,
- const MCLDInfo& pLDInfo)
+RelocationFactory::Result
+MipsRelocationFactory::applyRelocation(Relocation& pRelocation,
+ const MCLDInfo& pLDInfo)
{
- /// the prototype of applying function
- typedef Result (*ApplyFunctionType)(Relocation&,
- const MCLDInfo& pLDInfo,
- MipsRelocationFactory&);
-
- // the table entry of applying functions
- struct ApplyFunctionTriple {
- ApplyFunctionType func;
- unsigned int type;
- const char* name;
- };
-
- // declare the table of applying functions
- static ApplyFunctionTriple apply_functions[] = {
- DECL_MIPS_APPLY_RELOC_FUNC_PTRS
- };
-
Relocation::Type type = pRelocation.type();
- if (type >= sizeof(apply_functions) / sizeof(apply_functions[0])) {
+ if (type >= sizeof(ApplyFunctions) / sizeof(ApplyFunctions[0])) {
fatal(diag::unknown_relocation) << (int)type
<< pRelocation.symInfo()->name();
+ return Unknown;
}
// apply the relocation
- Result result = apply_functions[type].func(pRelocation, pLDInfo, *this);
-
- // check result
- if (OK == result) {
- return;
- }
- if (Overflow == result) {
- error(diag::result_overflow) << apply_functions[type].name
- << pRelocation.symInfo()->name();
- return;
- }
-
- if (BadReloc == result) {
- error(diag::result_badreloc) << apply_functions[type].name
- << pRelocation.symInfo()->name();
- return;
- }
+ return ApplyFunctions[type].func(pRelocation, pLDInfo, *this);
}
-//=========================================//
-// Relocation helper function //
-//=========================================//
+const char* MipsRelocationFactory::getName(Relocation::Type pType) const
+{
+ return ApplyFunctions[pType].name;
+}
+//===----------------------------------------------------------------------===//
+// Relocation helper function
+
+//===----------------------------------------------------------------------===//
static const char * const GP_DISP_NAME = "_gp_disp";
// Find next R_MIPS_LO16 relocation paired to pReloc.
diff --git a/lib/Target/Mips/MipsRelocationFactory.h b/lib/Target/Mips/MipsRelocationFactory.h
index 8f3bf93..a1c7b5d 100644
--- a/lib/Target/Mips/MipsRelocationFactory.h
+++ b/lib/Target/Mips/MipsRelocationFactory.h
@@ -25,20 +25,9 @@
class MipsRelocationFactory : public RelocationFactory
{
public:
- /** \enum Reloc
- * \brief Reloc is the result of applying functions.
- */
- enum Result
- {
- OK,
- Overflow,
- BadReloc
- };
-
-public:
MipsRelocationFactory(size_t pNum, MipsGNULDBackend& pParent);
- void applyRelocation(Relocation& pRelocation, const MCLDInfo& pLDInfo);
+ Result applyRelocation(Relocation& pRelocation, const MCLDInfo& pLDInfo);
MipsGNULDBackend& getTarget()
{ return m_Target; }
@@ -54,6 +43,8 @@
void setAHL(int32_t pAHL)
{ m_AHL = pAHL; }
+ const char* getName(Relocation::Type pType) const;
+
private:
MipsGNULDBackend& m_Target;
int32_t m_AHL;
diff --git a/lib/Target/Mips/MipsSectLinker.cpp b/lib/Target/Mips/MipsSectLinker.cpp
index 7a3082c..ed04edd 100644
--- a/lib/Target/Mips/MipsSectLinker.cpp
+++ b/lib/Target/Mips/MipsSectLinker.cpp
@@ -26,9 +26,11 @@
llvm::Triple theTriple(pTriple);
if (theTriple.isOSDarwin()) {
assert(0 && "MachO linker has not supported yet");
+ return NULL;
}
if (theTriple.isOSWindows()) {
assert(0 && "COFF linker has not supported yet");
+ return NULL;
}
return new MipsELFSectLinker(pOption, pLDBackend);
diff --git a/lib/Target/X86/X86Diagnostic.cpp b/lib/Target/X86/X86Diagnostic.cpp
index db12dde..98f0234 100644
--- a/lib/Target/X86/X86Diagnostic.cpp
+++ b/lib/Target/X86/X86Diagnostic.cpp
@@ -21,7 +21,7 @@
//===----------------------------------------------------------------------===//
// createX86Diagnostic - the help function to create corresponding X86Diagnostic
//
-DiagnosticLineInfo* createX86DiagLineInfo(const llvm::Target& pTarget,
+DiagnosticLineInfo* createX86DiagLineInfo(const mcld::Target& pTarget,
const std::string &pTriple)
{
return new DWARFLineInfo();
diff --git a/lib/Target/X86/X86GOTPLT.cpp b/lib/Target/X86/X86GOTPLT.cpp
index 960c86b..2ba5669 100644
--- a/lib/Target/X86/X86GOTPLT.cpp
+++ b/lib/Target/X86/X86GOTPLT.cpp
@@ -37,10 +37,10 @@
// Skip GOT0 entries.
iterator it = m_SectionData.begin();
- iterator ie = m_SectionData.end();
for (size_t i = 1; i < X86GOTPLT0Num; ++i) {
- assert((it != ie) && "Generation of GOT0 entries is incomplete!");
+ assert((it != m_SectionData.end()) &&
+ "Generation of GOT0 entries is incomplete!");
++it;
}
diff --git a/lib/Target/X86/X86LDBackend.cpp b/lib/Target/X86/X86LDBackend.cpp
index 79d160e..2355afc 100644
--- a/lib/Target/X86/X86LDBackend.cpp
+++ b/lib/Target/X86/X86LDBackend.cpp
@@ -33,7 +33,8 @@
m_pGOTPLT(NULL),
m_pRelDyn(NULL),
m_pRelPLT(NULL),
- m_pDynamic(NULL) {
+ m_pDynamic(NULL),
+ m_pGOTSymbol(NULL) {
}
X86GNULDBackend::~X86GNULDBackend()
diff --git a/lib/Target/X86/X86PLT.cpp b/lib/Target/X86/X86PLT.cpp
index caf6f32..2396a21 100644
--- a/lib/Target/X86/X86PLT.cpp
+++ b/lib/Target/X86/X86PLT.cpp
@@ -129,9 +129,9 @@
X86PLT0* X86PLT::getPLT0() const {
iterator first = m_SectionData.getFragmentList().begin();
- iterator end = m_SectionData.getFragmentList().end();
- assert(first!=end && "FragmentList is empty, getPLT0 failed!");
+ assert(first != m_SectionData.getFragmentList().end() &&
+ "FragmentList is empty, getPLT0 failed!");
X86PLT0* plt0 = &(llvm::cast<X86PLT0>(*first));
@@ -142,9 +142,9 @@
void X86PLT::applyPLT0() {
iterator first = m_SectionData.getFragmentList().begin();
- iterator end = m_SectionData.getFragmentList().end();
- assert(first!=end && "FragmentList is empty, applyPLT0 failed!");
+ assert(first != m_SectionData.getFragmentList().end() &&
+ "FragmentList is empty, applyPLT0 failed!");
X86PLT0* plt0 = &(llvm::cast<X86PLT0>(*first));
@@ -179,7 +179,7 @@
X86PLT::iterator it = m_SectionData.begin();
X86PLT::iterator ie = m_SectionData.end();
- assert(it!=ie && "FragmentList is empty, applyPLT1 failed!");
+ assert(it != ie && "FragmentList is empty, applyPLT1 failed!");
uint64_t GOTEntrySize = m_GOTPLT.getEntrySize();
diff --git a/lib/Target/X86/X86RelocationFactory.cpp b/lib/Target/X86/X86RelocationFactory.cpp
index 9090d1a..71fa344 100644
--- a/lib/Target/X86/X86RelocationFactory.cpp
+++ b/lib/Target/X86/X86RelocationFactory.cpp
@@ -19,10 +19,33 @@
using namespace mcld;
+//===--------------------------------------------------------------------===//
+// Relocation Functions and Tables
+//===--------------------------------------------------------------------===//
DECL_X86_APPLY_RELOC_FUNCS
+/// the prototype of applying function
+typedef RelocationFactory::Result
+ (*ApplyFunctionType)(Relocation& pReloc,
+ const MCLDInfo& pLDInfo,
+ X86RelocationFactory& pParent);
+
+// the table entry of applying functions
+struct ApplyFunctionTriple
+{
+ ApplyFunctionType func;
+ unsigned int type;
+ const char* name;
+};
+
+// declare the table of applying functions
+static const ApplyFunctionTriple ApplyFunctions[] = {
+ DECL_X86_APPLY_RELOC_FUNC_PTRS
+};
+
//===--------------------------------------------------------------------===//
// X86RelocationFactory
+//===--------------------------------------------------------------------===//
X86RelocationFactory::X86RelocationFactory(size_t pNum,
X86GNULDBackend& pParent)
: RelocationFactory(pNum),
@@ -33,61 +56,30 @@
{
}
-void X86RelocationFactory::applyRelocation(Relocation& pRelocation,
+RelocationFactory::Result
+X86RelocationFactory::applyRelocation(Relocation& pRelocation,
const MCLDInfo& pLDInfo)
{
Relocation::Type type = pRelocation.type();
- /// the prototype of applying function
- typedef Result (*ApplyFunctionType)(Relocation& pReloc,
- const MCLDInfo& pLDInfo,
- X86RelocationFactory& pParent);
-
- // the table entry of applying functions
- struct ApplyFunctionTriple {
- ApplyFunctionType func;
- unsigned int type;
- const char* name;
- };
-
- // declare the table of applying functions
- static ApplyFunctionTriple apply_functions[] = {
- DECL_X86_APPLY_RELOC_FUNC_PTRS
- };
-
- if (type >= sizeof (apply_functions) / sizeof (apply_functions[0]) ) {
+ if (type >= sizeof (ApplyFunctions) / sizeof (ApplyFunctions[0]) ) {
fatal(diag::unknown_relocation) << (int)type <<
pRelocation.symInfo()->name();
- return;
+ return Unknown;
}
// apply the relocation
- Result result = apply_functions[type].func(pRelocation, pLDInfo, *this);
-
- // check result
- if (OK == result) {
- return;
- }
- if (Overflow == result) {
- error(diag::result_overflow) << apply_functions[type].name
- << pRelocation.symInfo()->name();
- return;
- }
-
- if (BadReloc == result) {
- error(diag::result_badreloc) << apply_functions[type].name
- << pRelocation.symInfo()->name();
- return;
- }
+ return ApplyFunctions[type].func(pRelocation, pLDInfo, *this);
}
+const char* X86RelocationFactory::getName(Relocation::Type pType) const
+{
+ return ApplyFunctions[pType].name;
+}
-
-// non-member functions
-
-//=========================================//
-// Relocation helper function //
-//=========================================//
+//===--------------------------------------------------------------------===//
+// Relocation helper function
+//===--------------------------------------------------------------------===//
// Check if symbol can use relocation R_386_RELATIVE
static bool
@@ -257,6 +249,9 @@
ResolveInfo* rsym = pReloc.symInfo();
RelocationFactory::DWord A = pReloc.target() + pReloc.addend();
RelocationFactory::DWord S = pReloc.symValue();
+ bool has_dyn_rel = pParent.getTarget().symbolNeedsDynRel(
+ *rsym, (rsym->reserved() & X86GNULDBackend::ReservePLT),
+ pLDInfo, pLDInfo.output(), true);
const LDSection* target_sect = pParent.getLayout().getOutputLDSection(
*(pReloc.targetRef().frag()));
@@ -269,7 +264,7 @@
}
// A local symbol may need REL Type dynamic relocation
- if (rsym->isLocal() && (rsym->reserved() & X86GNULDBackend::ReserveRel)) {
+ if (rsym->isLocal() && has_dyn_rel) {
helper_DynRel(pReloc, llvm::ELF::R_386_RELATIVE, pParent);
pReloc.target() = S + A;
return X86RelocationFactory::OK;
@@ -284,7 +279,7 @@
// If we generate a dynamic relocation (except R_386_RELATIVE)
// for a place, we should not perform static relocation on it
// in order to keep the addend store in the place correct.
- if (rsym->reserved() & X86GNULDBackend::ReserveRel) {
+ if (has_dyn_rel) {
if (helper_use_relative_reloc(*rsym, pLDInfo, pParent)) {
helper_DynRel(pReloc, llvm::ELF::R_386_RELATIVE, pParent);
}
diff --git a/lib/Target/X86/X86RelocationFactory.h b/lib/Target/X86/X86RelocationFactory.h
index 6a6c372..4b413d7 100644
--- a/lib/Target/X86/X86RelocationFactory.h
+++ b/lib/Target/X86/X86RelocationFactory.h
@@ -26,21 +26,10 @@
class X86RelocationFactory : public RelocationFactory
{
public:
- /** \enum Reloc
- * \brief Reloc is the result of applying functions.
- */
- enum Result
- {
- OK,
- Overflow,
- BadReloc
- };
-
-public:
X86RelocationFactory(size_t pNum, X86GNULDBackend& pParent);
~X86RelocationFactory();
- void applyRelocation(Relocation& pRelocation, const MCLDInfo& pLDInfo);
+ Result applyRelocation(Relocation& pRelocation, const MCLDInfo& pLDInfo);
X86GNULDBackend& getTarget()
{ return m_Target; }
@@ -48,6 +37,8 @@
const X86GNULDBackend& getTarget() const
{ return m_Target; }
+ const char* getName(Relocation::Type pType) const;
+
private:
X86GNULDBackend& m_Target;
};
diff --git a/lib/Target/X86/X86SectLinker.cpp b/lib/Target/X86/X86SectLinker.cpp
index 300b112..a888f47 100644
--- a/lib/Target/X86/X86SectLinker.cpp
+++ b/lib/Target/X86/X86SectLinker.cpp
@@ -11,7 +11,6 @@
#include "X86.h"
#include "X86ELFSectLinker.h"
-#include <stdlib.h>
using namespace mcld;
@@ -26,16 +25,17 @@
Triple theTriple(pTriple);
if (theTriple.isOSDarwin()) {
assert(0 && "MachO linker has not supported yet");
+ return NULL;
}
if (theTriple.isOSWindows()) {
assert(0 && "COFF linker has not supported yet");
+ return NULL;
}
if (theTriple.isArch32Bit())
return new X86ELFSectLinker(pOption, pLDBackend);
assert(0 && "X86_64 has not supported yet");
- abort();
return NULL;
}
diff --git a/tools/llvm-mcld/llvm-mcld.cpp b/tools/llvm-mcld/llvm-mcld.cpp
index 7e6b9c8..726e08e 100644
--- a/tools/llvm-mcld/llvm-mcld.cpp
+++ b/tools/llvm-mcld/llvm-mcld.cpp
@@ -896,6 +896,13 @@
{
LLVMContext &Context = getGlobalContext();
llvm_shutdown_obj Y; // Call llvm_shutdown() on exit.
+ cl::ParseCommandLineOptions(argc, argv, "MCLinker\n");
+
+#ifdef ENABLE_UNITTEST
+ if (UnitTest) {
+ return unit_test( argc, argv );
+ }
+#endif
// Initialize targets first, so that --version shows registered targets.
InitializeAllTargets();
@@ -906,14 +913,6 @@
mcld::InitializeAllLinkers();
mcld::InitializeAllDiagnostics();
- cl::ParseCommandLineOptions(argc, argv, "MCLinker\n");
-
-#ifdef ENABLE_UNITTEST
- if (UnitTest) {
- return unit_test( argc, argv );
- }
-#endif
-
// Load the module to be compiled...
std::auto_ptr<Module> M;
@@ -1080,7 +1079,7 @@
// Set up MsgHandler
OwningPtr<mcld::DiagnosticLineInfo>
- diag_line_info(TheTarget->createDiagnosticLineInfo(*TheTarget->get(),
+ diag_line_info(TheTarget->createDiagnosticLineInfo(*TheTarget,
TheTriple.getTriple()));
OwningPtr<mcld::DiagnosticPrinter>
diag_printer(new mcld::TextDiagnosticPrinter(mcld::errs(),
diff --git a/tools/mcld/include/alone/Linker.h b/tools/mcld/include/alone/Linker.h
index 17f8baa..9321e94 100644
--- a/tools/mcld/include/alone/Linker.h
+++ b/tools/mcld/include/alone/Linker.h
@@ -6,13 +6,28 @@
// License. See LICENSE.TXT for details.
//
//===----------------------------------------------------------------------===//
+
#ifndef ALONE_LINKER_H
#define ALONE_LINKER_H
-#include <mcld/Support/MemoryAreaFactory.h>
-#include <mcld/Support/TargetRegistry.h>
-#include <mcld/MC/MCLDDriver.h>
-#include <mcld/MC/InputTree.h>
+#include <string>
+
+namespace mcld {
+
+class TargetLDBackend;
+class MCLDDriver;
+class MemoryFactory;
+class MCLDInfo;
+class TreeIteratorBase;
+class Input;
+
+namespace sys { namespace fs {
+
+class Path;
+
+} } // end namespace sys::fs
+
+} // end namespace mcld
namespace alone {
@@ -26,6 +41,7 @@
kDoubleConfig,
kCreateBackend,
kDelegateLDInfo,
+ kFindNameSpec,
kOpenNameSpec,
kOpenObjectFile,
kNotConfig,
@@ -42,9 +58,11 @@
private:
mcld::TargetLDBackend *mBackend;
mcld::MCLDDriver *mDriver;
- mcld::MCLDInfo *mLDInfo;
- mcld::InputTree::iterator mRoot;
MemoryFactory *mMemAreaFactory;
+ mcld::MCLDInfo *mLDInfo;
+ mcld::TreeIteratorBase *mRoot;
+ bool mShared;
+ std::string mSOName;
public:
Linker();
diff --git a/tools/mcld/lib/Core/Linker.cpp b/tools/mcld/lib/Core/Linker.cpp
index 0d112ba..9ab21cc 100644
--- a/tools/mcld/lib/Core/Linker.cpp
+++ b/tools/mcld/lib/Core/Linker.cpp
@@ -6,12 +6,16 @@
// License. See LICENSE.TXT for details.
//
//===----------------------------------------------------------------------===//
+
#include "alone/Linker.h"
#include "alone/Support/LinkerConfig.h"
#include "alone/Support/MemoryFactory.h"
+#include "alone/Support/Log.h"
#include <llvm/Support/ELF.h>
+#include <mcld/MC/MCLDDriver.h>
+#include <mcld/MC/InputTree.h>
#include <mcld/MC/MCLinker.h>
#include <mcld/MC/InputTree.h>
#include <mcld/LD/LDSection.h>
@@ -20,11 +24,12 @@
#include <mcld/Support/Path.h>
#include <mcld/Support/MemoryArea.h>
#include <mcld/Support/FileHandle.h>
+#include <mcld/Support/MemoryAreaFactory.h>
+#include <mcld/Support/TargetRegistry.h>
using namespace alone;
-const char* Linker::GetErrorString(enum Linker::ErrorCode pErrCode)
-{
+const char* Linker::GetErrorString(enum Linker::ErrorCode pErrCode) {
static const char* ErrorString[] = {
/* kSuccess */
"Successfully compiled.",
@@ -34,6 +39,8 @@
"Cannot create backend.",
/* kDelegateLDInfo */
"Cannot get linker information",
+ /* kFindNameSpec */
+ "Cannot find -lnamespec",
/* kOpenNameSpec */
"Cannot open -lnamespec",
/* kOpenObjectFile */
@@ -65,11 +72,13 @@
// Linker
//===----------------------------------------------------------------------===//
Linker::Linker()
- : mBackend(NULL), mDriver(NULL), mMemAreaFactory(NULL), mLDInfo(NULL) {
+ : mBackend(NULL), mDriver(NULL), mMemAreaFactory(NULL), mLDInfo(NULL),
+ mRoot(NULL), mShared(false) {
}
Linker::Linker(const LinkerConfig& pConfig)
- : mBackend(NULL), mDriver(NULL), mMemAreaFactory(NULL), mLDInfo(NULL) {
+ : mBackend(NULL), mDriver(NULL), mMemAreaFactory(NULL), mLDInfo(NULL),
+ mRoot(NULL), mShared(false) {
const std::string &triple = pConfig.getTriple();
@@ -82,36 +91,36 @@
return;
}
-Linker::~Linker()
-{
- if (NULL != mDriver)
- delete mDriver;
- if (NULL != mBackend)
- delete mBackend;
- if (NULL != mMemAreaFactory)
- delete mMemAreaFactory;
+Linker::~Linker() {
+ delete mDriver;
+ delete mBackend;
+ delete mMemAreaFactory;
}
-enum Linker::ErrorCode Linker::extractFiles(const LinkerConfig& pConfig)
-{
+enum Linker::ErrorCode Linker::extractFiles(const LinkerConfig& pConfig) {
mLDInfo = const_cast<mcld::MCLDInfo*>(pConfig.getLDInfo());
- if (NULL == mLDInfo)
+ if (mLDInfo == NULL) {
return kDelegateLDInfo;
+ }
- mRoot = mLDInfo->inputs().root();
+ mRoot = &mLDInfo->inputs().root();
+ mShared = pConfig.isShared();
+ mSOName = pConfig.getSOName();
+
return kSuccess;
}
-enum Linker::ErrorCode Linker::config(const LinkerConfig& pConfig)
-{
- if (NULL != mLDInfo)
+enum Linker::ErrorCode Linker::config(const LinkerConfig& pConfig) {
+ if (mLDInfo != NULL) {
return kDoubleConfig;
+ }
extractFiles(pConfig);
mBackend = pConfig.getTarget()->createLDBackend(pConfig.getTriple());
- if (NULL == mBackend)
+ if (mBackend == NULL) {
return kCreateBackend;
+ }
mDriver = new mcld::MCLDDriver(*mLDInfo, *mBackend);
@@ -122,32 +131,33 @@
return kSuccess;
}
-void Linker::advanceRoot()
-{
- if (mRoot.isRoot())
- --mRoot;
- else
- ++mRoot;
+void Linker::advanceRoot() {
+ if (mRoot->isRoot()) {
+ mRoot->move<mcld::TreeIteratorBase::Leftward>();
+ } else {
+ mRoot->move<mcld::TreeIteratorBase::Rightward>();
+ }
+ return;
}
-enum Linker::ErrorCode
-Linker::openFile(const mcld::sys::fs::Path& pPath, enum Linker::ErrorCode pCode, mcld::Input& pInput)
-{
+enum Linker::ErrorCode Linker::openFile(const mcld::sys::fs::Path& pPath,
+ enum Linker::ErrorCode pCode,
+ mcld::Input& pInput) {
mcld::MemoryArea *input_memory = mMemAreaFactory->produce(pPath,
mcld::FileHandle::ReadOnly);
- if (input_memory->handler()->isGood())
+ if (input_memory->handler()->isGood()) {
pInput.setMemArea(input_memory);
- else
+ } else {
return pCode;
+ }
mcld::LDContext *input_context = mLDInfo->contextFactory().produce(pPath);
pInput.setContext(input_context);
return kSuccess;
}
-enum Linker::ErrorCode Linker::addNameSpec(const std::string &pNameSpec)
-{
+enum Linker::ErrorCode Linker::addNameSpec(const std::string &pNameSpec) {
mcld::sys::fs::Path* path = NULL;
// find out the real path of the namespec.
if (mLDInfo->attrFactory().constraint().isSharedSystem()) {
@@ -156,23 +166,29 @@
if (mLDInfo->attrFactory().last().isStatic()) {
// with --static, we must search an archive.
- path = mLDInfo->options().directories().find(pNameSpec, mcld::Input::Archive);
+ path = mLDInfo->options().directories().find(pNameSpec,
+ mcld::Input::Archive);
}
else {
// otherwise, with --Bdynamic, we can find either an archive or a
// shared object.
- path = mLDInfo->options().directories().find(pNameSpec, mcld::Input::DynObj);
+ path = mLDInfo->options().directories().find(pNameSpec,
+ mcld::Input::DynObj);
}
}
else {
// In the system without shared object support, we only look for an
// archive.
- path = mLDInfo->options().directories().find(pNameSpec, mcld::Input::Archive);
+ path = mLDInfo->options().directories().find(pNameSpec,
+ mcld::Input::Archive);
}
+ if (NULL == path)
+ return kFindNameSpec;
+
mcld::Input* input = mLDInfo->inputFactory().produce(pNameSpec, *path,
- mcld::Input::Unknown);
- mLDInfo->inputs().insert<mcld::InputTree::Positional>(mRoot, *input);
+ mcld::Input::Unknown);
+ mLDInfo->inputs().insert<mcld::InputTree::Positional>(*mRoot, *input);
advanceRoot();
@@ -180,13 +196,12 @@
}
/// addObject - Add a object file by the filename.
-enum Linker::ErrorCode Linker::addObject(const std::string &pObjectPath)
-{
+enum Linker::ErrorCode Linker::addObject(const std::string &pObjectPath) {
mcld::Input* input = mLDInfo->inputFactory().produce(pObjectPath,
pObjectPath,
mcld::Input::Unknown);
- mLDInfo->inputs().insert<mcld::InputTree::Positional>(mRoot, *input);
+ mLDInfo->inputs().insert<mcld::InputTree::Positional>(*mRoot, *input);
advanceRoot();
@@ -194,14 +209,13 @@
}
/// addObject - Add a piece of memory. The memory is of ELF format.
-enum Linker::ErrorCode Linker::addObject(void* pMemory, size_t pSize)
-{
+enum Linker::ErrorCode Linker::addObject(void* pMemory, size_t pSize) {
mcld::Input* input = mLDInfo->inputFactory().produce("memory object",
"NAN",
mcld::Input::Unknown);
- mLDInfo->inputs().insert<mcld::InputTree::Positional>(mRoot, *input);
+ mLDInfo->inputs().insert<mcld::InputTree::Positional>(*mRoot, *input);
advanceRoot();
@@ -214,13 +228,12 @@
return kSuccess;
}
-enum Linker::ErrorCode Linker::addCode(void* pMemory, size_t pSize)
-{
+enum Linker::ErrorCode Linker::addCode(void* pMemory, size_t pSize) {
mcld::Input* input = mLDInfo->inputFactory().produce("code object",
- "NAN",
- mcld::Input::External);
+ "NAN",
+ mcld::Input::External);
- mLDInfo->inputs().insert<mcld::InputTree::Positional>(mRoot, *input);
+ mLDInfo->inputs().insert<mcld::InputTree::Positional>(*mRoot, *input);
advanceRoot();
@@ -232,17 +245,20 @@
// FIXME: So far, MCLinker must set up output before add input files.
// set up LDContext
- if (mDriver->hasInitLinker())
+ if (mDriver->hasInitLinker()) {
return kNotConfig;
+ }
- if (!mLDInfo->output().hasContext())
+ if (!mLDInfo->output().hasContext()) {
return kNotSetUpOutput;
+ }
// create NULL section
- mcld::LDSection& null = mDriver->getLinker()->createSectHdr("",
- mcld::LDFileFormat::Null,
- llvm::ELF::SHT_NULL,
- 0);
+ mcld::LDSection& null =
+ mDriver->getLinker()->createSectHdr("",
+ mcld::LDFileFormat::Null,
+ llvm::ELF::SHT_NULL,
+ 0);
null.setSize(0);
null.setOffset(0);
@@ -269,43 +285,52 @@
return kSuccess;
}
-enum Linker::ErrorCode Linker::setOutput(const std::string &pPath)
-{
- if (mLDInfo->output().hasContext())
+enum Linker::ErrorCode Linker::setOutput(const std::string &pPath) {
+ if (mLDInfo->output().hasContext()) {
return kDoubleConfig;
+ }
// ----- initialize output file ----- //
mcld::FileHandle::Permission perm = 0755;
mcld::MemoryArea* out_area = mMemAreaFactory->produce(
- pPath,
- mcld::FileHandle::ReadWrite | mcld::FileHandle::Truncate,
- perm);
+ pPath,
+ mcld::FileHandle::ReadWrite |
+ mcld::FileHandle::Truncate |
+ mcld::FileHandle::Create,
+ perm);
- if (!out_area->handler()->isGood())
+ if (!out_area->handler()->isGood()) {
return kOpenOutput;
+ }
- // FIXME: decide output type by command line option.
- mLDInfo->output().setType(mcld::Output::DynObj);
+ if (mShared) {
+ mLDInfo->output().setType(mcld::Output::DynObj);
+ } else {
+ mLDInfo->output().setType(mcld::Output::Exec);
+ }
+
+ mLDInfo->output().setSOName(mSOName);
mLDInfo->output().setMemArea(out_area);
mLDInfo->output().setContext(mLDInfo->contextFactory().produce(pPath));
// FIXME: We must initialize MCLinker before setOutput, and initialize
// standard sections here. This is because we have to build the section
// map before input files using it.
- if (!mDriver->hasInitLinker())
+ if (!mDriver->hasInitLinker()) {
return kNotConfig;
+ }
mDriver->initStdSections();
return kSuccess;
}
-enum Linker::ErrorCode Linker::setOutput(int pFileHandler)
-{
- if (mLDInfo->output().hasContext())
+enum Linker::ErrorCode Linker::setOutput(int pFileHandler) {
+ if (mLDInfo->output().hasContext()) {
return kDoubleConfig;
+ }
// ----- initialize output file ----- //
mcld::MemoryArea* out_area = mMemAreaFactory->produce(pFileHandler);
@@ -317,27 +342,29 @@
// FIXME: We must initialize MCLinker before setOutput, and initialize
// standard sections here. This is because we have to build the section
// map before input files using it.
- if (!mDriver->hasInitLinker())
+ if (!mDriver->hasInitLinker()) {
return kNotConfig;
+ }
+
mDriver->initStdSections();
return kSuccess;
}
-enum Linker::ErrorCode Linker::link()
-{
+enum Linker::ErrorCode Linker::link() {
mDriver->normalize();
- if (!mDriver->readSections() ||
- !mDriver->mergeSections())
+ if (!mDriver->readSections() || !mDriver->mergeSections()) {
return kReadSections;
+ }
- if (!mDriver->readSymbolTables())
+ if (!mDriver->readSymbolTables()) {
return kReadSymbols;
+ }
- if (!mDriver->addStandardSymbols() ||
- !mDriver->addTargetSymbols())
+ if (!mDriver->addStandardSymbols() || !mDriver->addTargetSymbols()) {
return kAddAdditionalSymbols;
+ }
mDriver->readRelocations();
mDriver->prelayout();
diff --git a/tools/mcld/lib/Support/LinkerConfig.cpp b/tools/mcld/lib/Support/LinkerConfig.cpp
index 8da9bbe..30506a8 100644
--- a/tools/mcld/lib/Support/LinkerConfig.cpp
+++ b/tools/mcld/lib/Support/LinkerConfig.cpp
@@ -8,10 +8,12 @@
//===----------------------------------------------------------------------===//
#include "alone/Support/LinkerConfig.h"
+#include "alone/Support/Log.h"
#include <llvm/Support/Signals.h>
#include <mcld/MC/MCLDInfo.h>
+#include <mcld/MC/MCLDFile.h>
#include <mcld/MC/MCLDDirectory.h>
#include <mcld/LD/TextDiagnosticPrinter.h>
#include <mcld/Support/Path.h>
@@ -21,23 +23,21 @@
using namespace alone;
LinkerConfig::LinkerConfig(const std::string &pTriple)
- : mTriple(pTriple), mTarget(NULL), mLDInfo(NULL), mDiagLineInfo(NULL),
- mDiagPrinter(NULL) {
+ : mTriple(pTriple), mShared(false), mSOName(), mTarget(NULL), mLDInfo(NULL),
+ mDiagLineInfo(NULL), mDiagPrinter(NULL) {
initializeTarget();
initializeLDInfo();
initializeDiagnostic();
}
-LinkerConfig::~LinkerConfig()
-{
- if (NULL != mLDInfo)
- delete mLDInfo;
+LinkerConfig::~LinkerConfig() {
+ delete mLDInfo;
- if (0 != mDiagPrinter->getNumErrors()) {
- // If we reached here, we are failing ungracefully. Run the interrupt handlers
- // to make sure any special cleanups get done, in particular that we remove
- // files registered with RemoveFileOnSignal.
+ if (mDiagPrinter->getNumErrors() != 0) {
+ // If here, the program failed ungracefully. Run the interrupt handlers to
+ // ensure any other cleanups (e.g., files that registered by
+ // RemoveFileOnSignal(...)) getting done before exit.
llvm::sys::RunInterruptHandlers();
}
mDiagPrinter->finish();
@@ -46,8 +46,7 @@
delete mDiagPrinter;
}
-bool LinkerConfig::initializeTarget()
-{
+bool LinkerConfig::initializeTarget() {
std::string error;
mTarget = mcld::TargetRegistry::lookupTarget(mTriple, error);
if (NULL != mTarget) {
@@ -59,8 +58,7 @@
}
}
-bool LinkerConfig::initializeLDInfo()
-{
+bool LinkerConfig::initializeLDInfo() {
if (NULL != mLDInfo) {
ALOGE("Cannot initialize mcld::MCLDInfo for given triple '%s!\n",
mTriple.c_str());
@@ -71,10 +69,9 @@
return true;
}
-bool LinkerConfig::initializeDiagnostic()
-{
- // Set up MsgHandler
- mDiagLineInfo = mTarget->createDiagnosticLineInfo(*mTarget->get(), mTriple);
+bool LinkerConfig::initializeDiagnostic() {
+ // Set up MsgHandler.
+ mDiagLineInfo = mTarget->createDiagnosticLineInfo(*mTarget, mTriple);
mDiagPrinter = new mcld::TextDiagnosticPrinter(mcld::errs(), *mLDInfo);
@@ -83,46 +80,99 @@
return true;
}
-void LinkerConfig::setSysRoot(const std::string &pSysRoot)
-{
- mLDInfo->options().setSysroot(mcld::sys::fs::Path(pSysRoot));
+void LinkerConfig::setShared(bool pEnable) {
+ mShared = pEnable;
+ return;
}
-void LinkerConfig::addWrap(const std::string &pWrapSymbol)
-{
+void LinkerConfig::setBsymbolic(bool pEnable) {
+ mLDInfo->options().setBsymbolic(pEnable);
+ return;
+}
+
+void LinkerConfig::setSOName(const std::string &pSOName) {
+ mLDInfo->output().setSOName(pSOName);
+ return;
+}
+
+void LinkerConfig::setDyld(const std::string &pDyld) {
+ mLDInfo->options().setDyld(pDyld);
+ return;
+}
+
+void LinkerConfig::setSysRoot(const std::string &pSysRoot) {
+ mLDInfo->options().setSysroot(mcld::sys::fs::Path(pSysRoot));
+ return;
+}
+
+void LinkerConfig::addWrap(const std::string &pWrapSymbol) {
bool exist = false;
- // add wname -> __wrap_wname
+ // Add wname -> __wrap_wname.
mcld::StringEntry<llvm::StringRef>* to_wrap =
mLDInfo->scripts().renameMap().insert(pWrapSymbol, exist);
std::string to_wrap_str = "__wrap_" + pWrapSymbol;
to_wrap->setValue(to_wrap_str);
- if (exist)
+ if (exist) {
mcld::warning(mcld::diag::rewrap) << pWrapSymbol << to_wrap_str;
+ }
- // add __real_wname -> wname
+ // Add __real_wname -> wname.
std::string from_real_str = "__real_" + pWrapSymbol;
mcld::StringEntry<llvm::StringRef>* from_real =
mLDInfo->scripts().renameMap().insert(from_real_str, exist);
from_real->setValue(pWrapSymbol);
- if (exist)
+ if (exist) {
mcld::warning(mcld::diag::rewrap) << pWrapSymbol << from_real_str;
+ }
+
+ return;
}
-void LinkerConfig::addSearchDir(const std::string &pDirPath)
-{
+void LinkerConfig::addPortable(const std::string &pPortableSymbol) {
+ bool exist = false;
+
+ // Add pname -> pname_portable.
+ mcld::StringEntry<llvm::StringRef>* to_port =
+ mLDInfo->scripts().renameMap().insert(pPortableSymbol, exist);
+
+ std::string to_port_str = pPortableSymbol + "_portable";
+ to_port->setValue(to_port_str);
+
+ if (exist) {
+ mcld::warning(mcld::diag::rewrap) << pPortableSymbol << to_port_str;
+}
+
+ // Add __real_pname -> pname.
+ std::string from_real_str = "__real_" + pPortableSymbol;
+ mcld::StringEntry<llvm::StringRef>* from_real =
+ mLDInfo->scripts().renameMap().insert(from_real_str, exist);
+
+ from_real->setValue(pPortableSymbol);
+
+ if (exist) {
+ mcld::warning(mcld::diag::rewrap) << pPortableSymbol << from_real_str;
+ }
+
+ return;
+}
+
+void LinkerConfig::addSearchDir(const std::string &pDirPath) {
// SearchDirs will remove the created MCLDDirectory.
mcld::MCLDDirectory* sd = new mcld::MCLDDirectory(pDirPath);
- if (sd->isInSysroot())
+ if (sd->isInSysroot()) {
sd->setSysroot(mLDInfo->options().sysroot());
+ }
+
if (exists(sd->path()) && is_directory(sd->path())) {
mLDInfo->options().directories().add(*sd);
- }
- else
+ } else {
mcld::warning(mcld::diag::warn_cannot_open_search_dir) << sd->name();
-}
+ }
+ return;
+}
diff --git a/unittests/Linker/TestLinker.cpp b/unittests/Linker/TestLinker.cpp
new file mode 100644
index 0000000..243be86
--- /dev/null
+++ b/unittests/Linker/TestLinker.cpp
@@ -0,0 +1,285 @@
+//===- TestLinker.cpp -----------------------------------------------------===//
+//
+// The MCLinker Project
+//
+// This file is distributed under the University of Illinois Open Source
+// License. See LICENSE.TXT for details.
+//
+//===----------------------------------------------------------------------===//
+#include "TestLinker.h"
+
+#include <iostream>
+
+#include <llvm/Support/TargetSelect.h>
+
+#include <mcld/LD/TextDiagnosticPrinter.h>
+#include <mcld/MC/InputTree.h>
+#include <mcld/Target/TargetLDBackend.h>
+#include <mcld/Support/RegionFactory.h>
+#include <mcld/Support/TargetSelect.h>
+#include <mcld/Support/MsgHandling.h>
+#include <mcld/Support/raw_ostream.h>
+#include <mcld/Support/SystemUtils.h>
+
+using namespace std;
+using namespace mcld;
+using namespace mcld::test;
+
+//===----------------------------------------------------------------------===//
+// TestLinker
+//===----------------------------------------------------------------------===//
+TestLinker::TestLinker()
+ : m_pTarget(NULL), m_pDriver(NULL), m_pInfo(NULL), m_pDiagLineInfo(NULL),
+ m_pDiagPrinter(NULL), m_pBackend(NULL), m_pRegionFactory(NULL) {
+}
+
+TestLinker::~TestLinker()
+{
+ std::list<mcld::FileHandle*>::iterator file, fEnd = m_FileHandleList.end();
+ for (file = m_FileHandleList.begin(); file != fEnd; ++file)
+ delete (*file);
+
+ std::list<mcld::MemoryArea*>::iterator mem, mEnd = m_MemAreaList.end() ;
+ for (mem = m_MemAreaList.begin(); mem != mEnd; ++mem)
+ delete (*mem);
+
+ delete m_pDriver;
+ delete m_pInfo;
+ delete m_pDiagLineInfo;
+ delete m_pDiagPrinter;
+ delete m_pBackend;
+ delete m_pRegionFactory;
+}
+
+bool TestLinker::initialize(const std::string &pTriple)
+{
+ bool is_initialized = false;
+
+ if (is_initialized)
+ return false;
+
+ // initilaize all llvm::Target and mcld::Target
+ llvm::InitializeAllTargets();
+ llvm::InitializeAllAsmPrinters();
+ llvm::InitializeAllAsmParsers();
+ llvm::InitializeAllTargetMCs();
+ mcld::InitializeAllTargets();
+ mcld::InitializeAllDiagnostics();
+
+ // create mcld::MCLDInfo
+ m_pInfo = new MCLDInfo(pTriple, 1, 32);
+ m_Root = m_pInfo->inputs().root();
+
+ // create mcld::RegionFactory
+ m_pRegionFactory = new mcld::RegionFactory(32);
+
+ // specify mcld::Target
+ std::string error;
+ m_pTarget = mcld::TargetRegistry::lookupTarget(pTriple, error);
+ if (NULL == m_pTarget) {
+ fatal(diag::fatal_cannot_init_target) << pTriple << error;
+ return false;
+ }
+
+ // create mcld::DiagnosticEngine
+ m_pDiagLineInfo = m_pTarget->createDiagnosticLineInfo(*m_pTarget, pTriple);
+ if (NULL == m_pDiagLineInfo) {
+ fatal(diag::fatal_cannot_init_lineinfo) << pTriple;
+ return false;
+ }
+
+ m_pDiagPrinter = new mcld::TextDiagnosticPrinter(mcld::errs(), *m_pInfo);
+
+ mcld::InitializeDiagnosticEngine(*m_pInfo, m_pDiagLineInfo, m_pDiagPrinter);
+
+ // create mcld::TargetLDBackend
+ m_pBackend = m_pTarget->createLDBackend(pTriple);
+ if (NULL == m_pBackend) {
+ fatal(diag::fatal_cannot_init_backend) << pTriple;
+ return false;
+ }
+
+ m_pDriver = new mcld::MCLDDriver(*m_pInfo, *m_pBackend);
+
+ m_pDriver->initMCLinker();
+
+ is_initialized = true;
+ return true;
+}
+
+void TestLinker::addObject(const std::string &pPath)
+{
+ mcld::Input* input = m_pInfo->inputFactory().produce(pPath, pPath,
+ mcld::Input::Unknown);
+
+ m_pInfo->inputs().insert<mcld::InputTree::Positional>(m_Root, *input);
+
+ advanceRoot();
+
+ mcld::FileHandle* handler = new mcld::FileHandle();
+ m_FileHandleList.push_back(handler);
+ if (!handler->open(pPath, mcld::FileHandle::ReadOnly)) {
+ mcld::error(mcld::diag::err_cannot_open_file)
+ << pPath
+ << mcld::sys::strerror(handler->error());
+ }
+
+ mcld::MemoryArea* input_memory = new MemoryArea(*m_pRegionFactory, *handler);
+ input->setMemArea(input_memory);
+ m_MemAreaList.push_back(input_memory);
+
+ mcld::LDContext* context = m_pInfo->contextFactory().produce(pPath);
+ input->setContext(context);
+}
+
+void TestLinker::addObject(void* pMemBuffer, size_t pSize)
+{
+ mcld::Input* input = m_pInfo->inputFactory().produce("memory object", "NAN",
+ mcld::Input::Unknown);
+
+ m_pInfo->inputs().insert<mcld::InputTree::Positional>(m_Root, *input);
+
+ advanceRoot();
+
+ mcld::Space* space = new mcld::Space(mcld::Space::EXTERNAL, pMemBuffer, pSize);
+ mcld::MemoryArea* input_memory = new MemoryArea(*m_pRegionFactory, *space);
+ input->setMemArea(input_memory);
+ m_MemAreaList.push_back(input_memory);
+
+ mcld::LDContext* context = m_pInfo->contextFactory().produce();
+ input->setContext(context);
+}
+
+void TestLinker::addObject(int pFileHandler)
+{
+ mcld::Input* input = m_pInfo->inputFactory().produce("handler object", "NAN",
+ mcld::Input::Unknown);
+
+ m_pInfo->inputs().insert<mcld::InputTree::Positional>(m_Root, *input);
+
+ advanceRoot();
+
+ mcld::FileHandle* handler = new mcld::FileHandle();
+ m_FileHandleList.push_back(handler);
+ handler->delegate(pFileHandler);
+
+ mcld::MemoryArea* input_memory = new MemoryArea(*m_pRegionFactory, *handler);
+ input->setMemArea(input_memory);
+ m_MemAreaList.push_back(input_memory);
+
+ mcld::LDContext* context = m_pInfo->contextFactory().produce();
+ input->setContext(context);
+}
+
+void TestLinker::addNameSpec(const std::string &pNameSpec)
+{
+ mcld::sys::fs::Path* path = NULL;
+ // find out the real path of the namespec.
+ if (m_pInfo->attrFactory().constraint().isSharedSystem()) {
+ // In the system with shared object support, we can find both archive
+ // and shared object.
+
+ if (m_pInfo->attrFactory().last().isStatic()) {
+ // with --static, we must search an archive.
+ path = m_pInfo->options().directories().find(pNameSpec,
+ mcld::Input::Archive);
+ }
+ else {
+ // otherwise, with --Bdynamic, we can find either an archive or a
+ // shared object.
+ path = m_pInfo->options().directories().find(pNameSpec,
+ mcld::Input::DynObj);
+ }
+ }
+ else {
+ // In the system without shared object support, we only look for an
+ // archive.
+ path = m_pInfo->options().directories().find(pNameSpec,
+ mcld::Input::Archive);
+ }
+
+ if (NULL == path) {
+ mcld::fatal(diag::err_cannot_find_namespec) << pNameSpec;
+ return;
+ }
+
+ mcld::Input* input = m_pInfo->inputFactory().produce(pNameSpec, *path,
+ mcld::Input::Unknown);
+
+ m_pInfo->inputs().insert<mcld::InputTree::Positional>(m_Root, *input);
+
+ advanceRoot();
+
+ mcld::FileHandle* handler = new mcld::FileHandle();
+ m_FileHandleList.push_back(handler);
+ if (!handler->open(*path, mcld::FileHandle::ReadOnly)) {
+ mcld::error(mcld::diag::err_cannot_open_file)
+ << *path
+ << mcld::sys::strerror(handler->error());
+ }
+
+ mcld::MemoryArea* input_memory = new MemoryArea(*m_pRegionFactory, *handler);
+ input->setMemArea(input_memory);
+ m_MemAreaList.push_back(input_memory);
+
+ mcld::LDContext* context = m_pInfo->contextFactory().produce(*path);
+ input->setContext(context);
+}
+
+bool TestLinker::setOutput(const std::string &pPath)
+{
+ if (m_pInfo->output().hasContext())
+ return false;
+
+ mcld::FileHandle* handler = new mcld::FileHandle();
+ m_FileHandleList.push_back(handler);
+ bool open_res = handler->open(pPath, mcld::FileHandle::ReadWrite |
+ mcld::FileHandle::Truncate |
+ mcld::FileHandle::Create,
+ mcld::FileHandle::Permission(0755));
+ if (!open_res) {
+ mcld::error(mcld::diag::err_cannot_open_file)
+ << pPath
+ << mcld::sys::strerror(handler->error());
+ }
+
+ mcld::MemoryArea* output_memory = new MemoryArea(*m_pRegionFactory, *handler);
+ m_pInfo->output().setMemArea(output_memory);
+ m_MemAreaList.push_back(output_memory);
+
+ mcld::LDContext* context = m_pInfo->contextFactory().produce(pPath);
+ m_pInfo->output().setContext(context);
+
+ // FIXME: remove the initStdSections().
+ m_pDriver->initStdSections();
+ return true;
+}
+
+bool TestLinker::setOutput(int pFileHandler)
+{
+ if (m_pInfo->output().hasContext())
+ return false;
+
+ mcld::FileHandle* handler = new mcld::FileHandle();
+ handler->delegate(pFileHandler);
+ m_FileHandleList.push_back(handler);
+
+ mcld::MemoryArea* output_memory = new MemoryArea(*m_pRegionFactory, *handler);
+ m_pInfo->output().setMemArea(output_memory);
+ m_MemAreaList.push_back(output_memory);
+
+ mcld::LDContext* context = m_pInfo->contextFactory().produce();
+ m_pInfo->output().setContext(context);
+
+ // FIXME: remove the initStdSections().
+ m_pDriver->initStdSections();
+ return true;
+}
+
+void TestLinker::advanceRoot()
+{
+ if (m_Root.isRoot())
+ --m_Root;
+ else
+ ++m_Root;
+}
diff --git a/unittests/Linker/TestLinker.h b/unittests/Linker/TestLinker.h
new file mode 100644
index 0000000..79b3010
--- /dev/null
+++ b/unittests/Linker/TestLinker.h
@@ -0,0 +1,112 @@
+//===- TestLinker.h -------------------------------------------------------===//
+//
+// The MCLinker Project
+//
+// This file is distributed under the University of Illinois Open Source
+// License. See LICENSE.TXT for details.
+//
+//===----------------------------------------------------------------------===//
+#ifndef MCLD_TEST_LINKER_H
+#define MCLD_TEST_LINKER_H
+
+#include <gtest.h>
+
+#include <string>
+#include <list>
+
+#include <mcld/MC/MCLDDriver.h>
+#include <mcld/MC/MCLinker.h>
+#include <mcld/LD/DiagnosticPrinter.h>
+#include <mcld/LD/DiagnosticLineInfo.h>
+#include <mcld/Support/TargetRegistry.h>
+#include <mcld/Support/Path.h>
+
+namespace mcld {
+
+class MCLDInfo;
+class TargetLDBackend;
+class RegionFactory;
+
+namespace test
+{
+
+class TestLinker
+{
+public:
+ TestLinker();
+
+ ~TestLinker();
+
+ bool initialize(const std::string &pTriple);
+
+ MCLDInfo* config() {
+ assert(NULL != m_pInfo);
+ return m_pInfo;
+ }
+
+ const MCLDInfo* config() const {
+ assert(NULL != m_pInfo);
+ return m_pInfo;
+ }
+
+ void addObject(const std::string &pPath);
+
+ void addObject(const mcld::sys::fs::Path &pPath)
+ { addObject(pPath.native()); }
+
+ void addObject(void* pMemBuffer, size_t pSize);
+
+ void addObject(int pFileHandler);
+
+ void addNameSpec(const std::string &pNameSpec);
+
+ bool setOutput(const std::string &pPath);
+
+ bool setOutput(int pFileHandler);
+
+ /// getDriver
+ MCLDDriver* getDriver() {
+ assert(NULL != m_pDriver);
+ return m_pDriver;
+ }
+
+ /// getDriver
+ const MCLDDriver* getDriver() const {
+ assert(NULL != m_pDriver);
+ return m_pDriver;
+ }
+
+ /// getLinker
+ MCLinker* getLinker() {
+ assert(NULL != m_pDriver);
+ return m_pDriver->getLinker();
+ }
+
+ /// getLinker
+ const MCLinker* getLinker() const {
+ assert(NULL != m_pDriver);
+ return m_pDriver->getLinker();
+ }
+
+private:
+ void advanceRoot();
+
+private:
+ const mcld::Target* m_pTarget;
+ mcld::MCLDDriver *m_pDriver;
+ mcld::MCLDInfo* m_pInfo;
+ mcld::DiagnosticLineInfo* m_pDiagLineInfo;
+ mcld::DiagnosticPrinter* m_pDiagPrinter;
+ mcld::TargetLDBackend* m_pBackend;
+ mcld::InputTree::iterator m_Root;
+ mcld::RegionFactory* m_pRegionFactory;
+
+ std::list<mcld::FileHandle*> m_FileHandleList;
+ std::list<mcld::MemoryArea*> m_MemAreaList;
+
+};
+
+} // namespace of test
+} // namespace of mcld
+#endif
+
diff --git a/unittests/StaticResolverTest.cpp b/unittests/StaticResolverTest.cpp
index 0e1e5c9..5839507 100644
--- a/unittests/StaticResolverTest.cpp
+++ b/unittests/StaticResolverTest.cpp
@@ -27,19 +27,21 @@
using namespace mcld;
using namespace mcldtest;
+//===----------------------------------------------------------------------===//
+// StaticResolverTest
+//===----------------------------------------------------------------------===//
// Constructor can do set-up work for all test here.
StaticResolverTest::StaticResolverTest()
-{
+ : m_pResolver(NULL), m_pFactory(NULL), m_pLDInfo(NULL), m_pLineInfo(NULL) {
// create testee. modify it if need
m_pResolver = new StaticResolver();
m_pFactory = new ResolveInfoFactory();
+
mcld::InitializeAllDiagnostics();
m_pLDInfo = new MCLDInfo("arm-none-linux-gnueabi", 10, 10);
m_pLineInfo = new DiagnosticLineInfo();
- m_pPrinter = new mcld::DiagnosticPrinter(); //llvm::errs(), *m_pLDInfo);
- mcld::InitializeDiagnosticEngine(*m_pLDInfo, m_pLineInfo, m_pPrinter);
-
+ mcld::InitializeDiagnosticEngine(*m_pLDInfo, m_pLineInfo, NULL);
}
// Destructor can do clean-up work that doesn't throw exceptions here.
diff --git a/unittests/TestLinkerTest.cpp b/unittests/TestLinkerTest.cpp
new file mode 100644
index 0000000..b6df3cf
--- /dev/null
+++ b/unittests/TestLinkerTest.cpp
@@ -0,0 +1,75 @@
+//===- TestLinkerTest.cpp -------------------------------------------------===//
+//
+// The MCLinker Project
+//
+// This file is distributed under the University of Illinois Open Source
+// License. See LICENSE.TXT for details.
+//
+//===----------------------------------------------------------------------===//
+#include "Linker/TestLinker.h"
+#include "TestLinkerTest.h"
+
+#include <mcld/Support/Path.h>
+#include <mcld/MC/MCLDDirectory.h>
+
+using namespace mcld;
+using namespace mcld::test;
+using namespace mcld::sys::fs;
+using namespace mcldtest;
+
+
+// Constructor can do set-up work for all test here.
+TestLinkerTest::TestLinkerTest()
+ : m_pLinker(NULL) {
+}
+
+// Destructor can do clean-up work that doesn't throw exceptions here.
+TestLinkerTest::~TestLinkerTest()
+{
+}
+
+// SetUp() will be called immediately before each test.
+void TestLinkerTest::SetUp()
+{
+ m_pLinker = new mcld::test::TestLinker();
+ m_pLinker->initialize("arm-none-linux-gnueabi");
+
+ // set up target-dependent constraints of attributes
+ m_pLinker->config()->attrFactory().constraint().enableWholeArchive();
+ m_pLinker->config()->attrFactory().constraint().disableAsNeeded();
+ m_pLinker->config()->attrFactory().constraint().setSharedSystem();
+
+ // set up the predefined attributes
+ m_pLinker->config()->attrFactory().predefined().setWholeArchive();
+ m_pLinker->config()->attrFactory().predefined().setDynamic();
+
+ // set up target dependent options
+ mcld::sys::fs::Path path = TOPDIR;
+ path.append("test/libs/ARM/Android/android-14");
+ m_pLinker->config()->options().setSysroot(path);
+ m_pLinker->config()->options().setDyld("/usr/lib/ld.so.1");
+ m_pLinker->config()->options().directories().add("=/");
+ m_pLinker->config()->options().setBsymbolic(true);
+}
+
+// TearDown() will be called immediately after each test.
+void TestLinkerTest::TearDown()
+{
+ delete m_pLinker;
+}
+
+//===----------------------------------------------------------------------===//
+// Testcases
+//===----------------------------------------------------------------------===//
+TEST_F( TestLinkerTest, test) {
+ m_pLinker->config()->options().setVerbose(3);
+ mcld::sys::fs::Path top_level = TOPDIR;
+ m_pLinker->addObject(top_level + "test/libs/ARM/Android/android-14/crtbegin_so.o");
+ m_pLinker->addObject(top_level + "test/Android/Plasma/ARM/plasma.o");
+ m_pLinker->addNameSpec("m");
+ m_pLinker->addNameSpec("log");
+ m_pLinker->addNameSpec("jnigraphics");
+ m_pLinker->addNameSpec("c");
+ m_pLinker->addObject(top_level + "test/libs/ARM/Android/android-14/crtend_so.o");
+}
+
diff --git a/unittests/TestLinkerTest.h b/unittests/TestLinkerTest.h
new file mode 100644
index 0000000..ba6efcf
--- /dev/null
+++ b/unittests/TestLinkerTest.h
@@ -0,0 +1,40 @@
+//===- TestLinkerTest.h ---------------------------------------------------===//
+//
+// The MCLinker Project
+//
+// This file is distributed under the University of Illinois Open Source
+// License. See LICENSE.TXT for details.
+//
+//===----------------------------------------------------------------------===//
+#ifndef MCLD_TEST_LINKER_TEST_H
+#define MCLD_TEST_LINKER_TEST_H
+#include <gtest.h>
+
+#include "Linker/TestLinker.h"
+
+namespace mcldtest
+{
+
+class TestLinkerTest : public ::testing::Test
+{
+public:
+ // Constructor can do set-up work for all test here.
+ TestLinkerTest();
+
+ // Destructor can do clean-up work that doesn't throw exceptions here.
+ virtual ~TestLinkerTest();
+
+ // SetUp() will be called immediately before each test.
+ virtual void SetUp();
+
+ // TearDown() will be called immediately after each test.
+ virtual void TearDown();
+
+protected:
+ mcld::test::TestLinker* m_pLinker;
+};
+
+} // namespace of mcldtest
+
+#endif
+
diff --git a/unittests/UniqueGCFactoryBaseTest.cpp b/unittests/UniqueGCFactoryBaseTest.cpp
index 328e924..067467b 100644
--- a/unittests/UniqueGCFactoryBaseTest.cpp
+++ b/unittests/UniqueGCFactoryBaseTest.cpp
@@ -24,8 +24,7 @@
m_pLDInfo = new MCLDInfo("arm-none-linux-gnueabi", 10, 10);
m_pLineInfo = new DiagnosticLineInfo();
- m_pPrinter = new mcld::DiagnosticPrinter(); //llvm::errs(), *m_pLDInfo);
- mcld::InitializeDiagnosticEngine(*m_pLDInfo, m_pLineInfo, m_pPrinter);
+ mcld::InitializeDiagnosticEngine(*m_pLDInfo, m_pLineInfo, NULL);
}
// Destructor can do clean-up work that doesn't throw exceptions here.