diff options
author | Stephen Hines <srhines@google.com> | 2014-04-24 14:41:24 -0700 |
---|---|---|
committer | Stephen Hines <srhines@google.com> | 2014-04-24 15:22:31 -0700 |
commit | 551ae4ebd3e9d137ea668fb83ae4a55b8cfba451 (patch) | |
tree | c4ea60679a6fe2630e21bf6d46177b2c4fcab33b | |
parent | 334c6f83c1265eabd58ac7c8b860898038831eab (diff) | |
download | mclinker-551ae4ebd3e9d137ea668fb83ae4a55b8cfba451.tar.gz |
Update MCLinker for LLVM 3.5.
Change-Id: Ib07513d0eb2f8b7d3516a7dd8823f98820943cc9
150 files changed, 3740 insertions, 865 deletions
@@ -24,6 +24,11 @@ subdirs += \ lib/Target/ARM \ lib/Target/ARM/TargetInfo +# AArch64 Code Generation Libraries +subdirs += \ + lib/Target/AArch64 \ + lib/Target/AArch64/TargetInfo + # MIPS Code Generation Libraries subdirs += \ lib/Target/Mips \ diff --git a/include/mcld/ADT/Flags.h b/include/mcld/ADT/Flags.h index c6a41e8..16515aa 100644 --- a/include/mcld/ADT/Flags.h +++ b/include/mcld/ADT/Flags.h @@ -65,7 +65,7 @@ public: Flags& operator^= (Flags pOther) { m_Data ^= pOther.m_Data; return *this; - } + } Flags& operator^= (Enum pOther) { m_Data ^= pOther; diff --git a/include/mcld/ADT/HashTable.h b/include/mcld/ADT/HashTable.h index 522ab48..c260f56 100644 --- a/include/mcld/ADT/HashTable.h +++ b/include/mcld/ADT/HashTable.h @@ -63,7 +63,7 @@ public: // ----- constructor ----- // explicit HashTable(size_type pSize=3); ~HashTable(); - + EntryFactoryTy& getEntryFactory() { return m_EntryFactory; } @@ -88,7 +88,7 @@ public: const_iterator find(const key_type& pKey) const; size_type count(const key_type& pKey) const; - + // ----- hash policy ----- // float load_factor() const; diff --git a/include/mcld/ADT/StringHash.h b/include/mcld/ADT/StringHash.h index 048f35f..df3caeb 100644 --- a/include/mcld/ADT/StringHash.h +++ b/include/mcld/ADT/StringHash.h @@ -80,7 +80,7 @@ struct StringHash<JS> : public std::unary_function<const llvm::StringRef&, uint3 for(unsigned int i = 0; i < pKey.size(); ++i) { hash_val ^= ((hash_val << 5) + pKey[i] + (hash_val >> 2)); - } + } return hash_val; } }; @@ -125,7 +125,7 @@ struct StringHash<ELF> : public std::unary_function<const llvm::StringRef&, uint for (unsigned int i = 0; i < pKey.size(); ++i) { hash_val = (hash_val << 4) + pKey[i]; if((x = hash_val & 0xF0000000L) != 0) - hash_val ^= (x >> 24); + hash_val ^= (x >> 24); hash_val &= ~x; } return hash_val; @@ -142,7 +142,7 @@ struct StringHash<BKDR> : public std::unary_function<const llvm::StringRef&, uin { const uint32_t seed = 131; uint32_t hash_val = 0; - + for(uint32_t i = 0; i < pKey.size(); ++i) hash_val = (hash_val * seed) + pKey[i]; return hash_val; @@ -250,13 +250,13 @@ struct StringHash<AP> : public std::unary_function<const llvm::StringRef&, uint3 uint32_t operator()(const llvm::StringRef& pKey) const { unsigned int hash_val = 0xAAAAAAAA; - - for(uint32_t i = 0; i < pKey.size(); ++i) { + + for(uint32_t i = 0; i < pKey.size(); ++i) { hash_val ^= ((i & 1) == 0)? ((hash_val << 7) ^ pKey[i] * (hash_val >> 3)): (~((hash_val << 11) + (pKey[i] ^ (hash_val >> 5)))); } - + return hash_val; } }; diff --git a/include/mcld/ADT/TreeAllocator.h b/include/mcld/ADT/TreeAllocator.h index b2bb39b..41efae7 100644 --- a/include/mcld/ADT/TreeAllocator.h +++ b/include/mcld/ADT/TreeAllocator.h @@ -25,7 +25,7 @@ namespace mcld { * NodeFactory provides delegation of memory. Sometimes, we have to merge two * NodeFactories, and NodeFactory::delegate() can move the memory from one * NodeFactories to another. - * + * * @see LinearAllocator */ template<typename DataType> diff --git a/include/mcld/Config/Linkers.def.in b/include/mcld/Config/Linkers.def.in index e8b870b..ec95925 100644 --- a/include/mcld/Config/Linkers.def.in +++ b/include/mcld/Config/Linkers.def.in @@ -7,8 +7,8 @@ // //===----------------------------------------------------------------------===// // -// This file enumerates all of the linkers supported by this build of MCLinker. -// Clients of this file should define the MCLD_LINKER macro to be a function-like +// This file enumerates all of the linkers supported by this build of MCLinker. +// Clients of this file should define the MCLD_LINKER macro to be a function-like // macro with a single parameter (the name of the target whose exe/dso can be // generated); including this file will then enumerate all of the targets with // linkers. diff --git a/include/mcld/Fragment/FragmentRef.h b/include/mcld/Fragment/FragmentRef.h index 3bfd804..36f310e 100644 --- a/include/mcld/Fragment/FragmentRef.h +++ b/include/mcld/Fragment/FragmentRef.h @@ -60,7 +60,7 @@ public: /// copy memory from the fragment to the pDesc. /// @pDest - the destination address /// @pNBytes - copies pNBytes from the fragment[offset()+pOffset] - /// @pOffset - additional offset. + /// @pOffset - additional offset. /// the start address offset from fragment[offset()] void memcpy(void* pDest, size_t pNBytes, Offset pOffset = 0) const; @@ -86,7 +86,7 @@ private: FragmentRef(); FragmentRef(Fragment& pFrag, Offset pOffset = 0); - + private: Fragment* m_pFragment; Offset m_Offset; diff --git a/include/mcld/LD/LDSymbol.h b/include/mcld/LD/LDSymbol.h index bebdd18..8d1813a 100644 --- a/include/mcld/LD/LDSymbol.h +++ b/include/mcld/LD/LDSymbol.h @@ -114,7 +114,7 @@ public: ResolveInfo* resolveInfo() { return m_pResolveInfo; } - const ResolveInfo* resolveInfo() const + const ResolveInfo* resolveInfo() const { return m_pResolveInfo; } bool hasFragRef() const; @@ -127,7 +127,7 @@ public: void setValue(ValueType pValue) { m_Value = pValue; } - + void setFragmentRef(FragmentRef* pFragmentRef); void setResolveInfo(const ResolveInfo& pInfo); diff --git a/include/mcld/LD/StaticResolver.h b/include/mcld/LD/StaticResolver.h index 586e44d..c73629a 100644 --- a/include/mcld/LD/StaticResolver.h +++ b/include/mcld/LD/StaticResolver.h @@ -75,7 +75,7 @@ private: w_D = ResolveInfo::weak_flag | ResolveInfo::regular_flag | ResolveInfo::define_flag, d_D = ResolveInfo::global_flag | ResolveInfo::dynamic_flag | ResolveInfo::define_flag, wd_D = ResolveInfo::weak_flag | ResolveInfo::dynamic_flag | ResolveInfo::define_flag, - C = ResolveInfo::global_flag | ResolveInfo::regular_flag | ResolveInfo::common_flag, + C = ResolveInfo::global_flag | ResolveInfo::regular_flag | ResolveInfo::common_flag, w_C = ResolveInfo::weak_flag | ResolveInfo::regular_flag | ResolveInfo::common_flag, d_C = ResolveInfo::global_flag | ResolveInfo::dynamic_flag | ResolveInfo::common_flag, wd_C = ResolveInfo::weak_flag | ResolveInfo::dynamic_flag | ResolveInfo::common_flag, diff --git a/include/mcld/MC/Attribute.h b/include/mcld/MC/Attribute.h index a7c7176..1c02505 100644 --- a/include/mcld/MC/Attribute.h +++ b/include/mcld/MC/Attribute.h @@ -159,7 +159,7 @@ public: bool isStaticSystem() const { return m_Static; } - + bool isLegal(const Attribute& pAttr) const; }; @@ -224,8 +224,8 @@ private: inline bool operator== (const Attribute& pLHS, const Attribute& pRHS) { return ((pLHS.isWholeArchive() == pRHS.isWholeArchive()) && - (pLHS.isAsNeeded() == pRHS.isAsNeeded()) && - (pLHS.isAddNeeded() == pRHS.isAddNeeded()) && + (pLHS.isAsNeeded() == pRHS.isAsNeeded()) && + (pLHS.isAddNeeded() == pRHS.isAddNeeded()) && (pLHS.isStatic() == pRHS.isStatic())); } diff --git a/include/mcld/Object/ObjectBuilder.h b/include/mcld/Object/ObjectBuilder.h index ec80528..bc20421 100644 --- a/include/mcld/Object/ObjectBuilder.h +++ b/include/mcld/Object/ObjectBuilder.h @@ -62,7 +62,7 @@ public: /// MergeSection - merge the pInput section to mcld::Module. /// This function moves all fragments in pInputSection to the corresponding - /// output section of mcld::Module. + /// output section of mcld::Module. /// /// @see SectionMap /// @param [in] pInputSection The merged input section. @@ -76,6 +76,10 @@ public: /// UpdateSectionAlign - update alignment for input section static void UpdateSectionAlign(LDSection& pTo, const LDSection& pFrom); + /// UpdateSectionAlign - update alignment for the section + static void UpdateSectionAlign(LDSection& pSection, + uint32_t pAlignConstraint); + /// @} /// @name Fragment Methods /// @{ diff --git a/include/mcld/Script/FlexLexer.h b/include/mcld/Script/FlexLexer.h index d7d8001..f09ab20 100644 --- a/include/mcld/Script/FlexLexer.h +++ b/include/mcld/Script/FlexLexer.h @@ -139,15 +139,8 @@ public: virtual int yywrap(); protected: -// BEGIN android-modified: work around flex differences on Darwin and Linux -#if !defined(DARWIN_FLEX) - virtual int LexerInput( char* buf, int max_size ); - virtual void LexerOutput( const char* buf, int size ); -#else - virtual size_t LexerInput( char* buf, size_t max_size ); - virtual void LexerOutput( const char* buf, size_t size ); -#endif -// END android-modified + virtual int LexerInput( char* buf, int max_size ); + virtual void LexerOutput( const char* buf, int size ); virtual void LexerError( const char* msg ); void yyunput( int c, char* buf_ptr ); diff --git a/include/mcld/Support/MemoryAreaFactory.h b/include/mcld/Support/MemoryAreaFactory.h index 302fbd1..c3c3a0d 100644 --- a/include/mcld/Support/MemoryAreaFactory.h +++ b/include/mcld/Support/MemoryAreaFactory.h @@ -24,7 +24,7 @@ namespace mcld * \brief MemoryAreaFactory avoids creating duplicated MemoryAreas of the * same file. * - * Users can give duplicated input files on the command line. In order to + * Users can give duplicated input files on the command line. In order to * prevent opening the same file twice, and create redundant MemoryRegions, * mcld::Input should not create MemoryArea directly. Instead, it should ask * MemoryAreaFactory and get the unique MemoryArea. diff --git a/include/mcld/Support/ToolOutputFile.h b/include/mcld/Support/ToolOutputFile.h index f1186c3..873a290 100644 --- a/include/mcld/Support/ToolOutputFile.h +++ b/include/mcld/Support/ToolOutputFile.h @@ -65,7 +65,7 @@ private: private: sys::fs::Path m_Path; - }; + }; private: FileHandle m_FileHandle; diff --git a/include/mcld/Target/ELFDynamic.h b/include/mcld/Target/ELFDynamic.h index c9b257f..4f70d34 100644 --- a/include/mcld/Target/ELFDynamic.h +++ b/include/mcld/Target/ELFDynamic.h @@ -185,6 +185,8 @@ protected: size_t symbolSize() const; + const LinkerConfig& config() const { return m_Config; } + private: EntryListType m_EntryList; EntryListType m_NeedList; diff --git a/include/mcld/Target/GOT.h b/include/mcld/Target/GOT.h index eb73741..bc1c0f8 100644 --- a/include/mcld/Target/GOT.h +++ b/include/mcld/Target/GOT.h @@ -67,7 +67,7 @@ public: // ----- observers -----// uint64_t addr() const { return m_Section.addr(); } - uint32_t size() const { return m_Section.size(); } + uint64_t size() const { return m_Section.size(); } const_iterator begin() const { return m_SectionData->begin(); } iterator begin() { return m_SectionData->begin(); } diff --git a/include/mcld/Target/PLT.h b/include/mcld/Target/PLT.h index 7305a74..ce14d98 100644 --- a/include/mcld/Target/PLT.h +++ b/include/mcld/Target/PLT.h @@ -86,14 +86,14 @@ public: uint64_t addr() const { return m_Section.addr(); } - const_iterator begin() const { return m_SectionData->begin(); } - iterator begin() { return m_SectionData->begin(); } - const_iterator end () const { return m_SectionData->end(); } - iterator end () { return m_SectionData->end(); } + const_iterator begin() const { return m_pSectionData->begin(); } + iterator begin() { return m_pSectionData->begin(); } + const_iterator end () const { return m_pSectionData->end(); } + iterator end () { return m_pSectionData->end(); } protected: LDSection& m_Section; - SectionData* m_SectionData; + SectionData* m_pSectionData; }; } // namespace of mcld diff --git a/lib/LD/Archive.cpp b/lib/LD/Archive.cpp index 864cedb..c555e67 100644 --- a/lib/LD/Archive.cpp +++ b/lib/LD/Archive.cpp @@ -52,13 +52,13 @@ const Input& Archive::getARFile() const return m_ArchiveFile; } -/// inputs - get the input tree built from this archive +/// inputs - get the input tree built from this archive InputTree& Archive::inputs() { return *m_pInputTree; } -/// inputs - get the input tree built from this archive +/// inputs - get the input tree built from this archive const InputTree& Archive::inputs() const { return *m_pInputTree; diff --git a/lib/LD/ArchiveReader.cpp b/lib/LD/ArchiveReader.cpp index f43c057..88957bc 100644 --- a/lib/LD/ArchiveReader.cpp +++ b/lib/LD/ArchiveReader.cpp @@ -19,4 +19,3 @@ ArchiveReader::ArchiveReader() ArchiveReader::~ArchiveReader() { } - diff --git a/lib/LD/Diagnostic.cpp b/lib/LD/Diagnostic.cpp index 49d6db0..5d57f29 100644 --- a/lib/LD/Diagnostic.cpp +++ b/lib/LD/Diagnostic.cpp @@ -29,7 +29,7 @@ Diagnostic::~Diagnostic() // arguments. The result is appended at on the pOutStr. void Diagnostic::format(std::string& pOutStr) const { - // we've not implemented DWARF LOC messages yet. So, keep pIsLoC false + // we've not implemented DWARF LOC messages yet. So, keep pIsLoC false llvm::StringRef desc = m_Engine.infoMap().getDescription(getID(), false); format(desc.begin(), desc.end(), pOutStr); diff --git a/lib/LD/ELFFileFormat.cpp b/lib/LD/ELFFileFormat.cpp index 067f48c..551a60d 100644 --- a/lib/LD/ELFFileFormat.cpp +++ b/lib/LD/ELFFileFormat.cpp @@ -148,7 +148,7 @@ void ELFFileFormat::initStdSections(ObjectBuilder& pBuilder, unsigned int pBitCl llvm::ELF::SHT_STRTAB, 0x0, 0x1); - // In ELF Spec Book I, p1-16. If symbol table and string table are in + // In ELF Spec Book I, p1-16. If symbol table and string table are in // loadable segments, set the attribute to SHF_ALLOC bit. But in the // real world, this bit always turn off. f_pSymTab = pBuilder.CreateSection(".symtab", diff --git a/lib/LD/RelocationFactory.cpp b/lib/LD/RelocationFactory.cpp index bb56cdd..08eb347 100644 --- a/lib/LD/RelocationFactory.cpp +++ b/lib/LD/RelocationFactory.cpp @@ -45,27 +45,27 @@ Relocation* RelocationFactory::produce(RelocationFactory::Type pType, DWord target_data = 0; // byte swapping if the host and target have different endian - if(llvm::sys::IsLittleEndianHost != m_pConfig->targets().isLittleEndian()) { - uint32_t tmp_data; + if (llvm::sys::IsLittleEndianHost != m_pConfig->targets().isLittleEndian()) { + uint32_t tmp_data; - switch (m_pConfig->targets().bitclass()) { - case 32: { - pFragRef.memcpy(&tmp_data, 4); - tmp_data = mcld::bswap32(tmp_data); - target_data = tmp_data; - break; - } - case 64: { - pFragRef.memcpy(&target_data, 8); - target_data = mcld::bswap64(target_data); - break; - } - default: { - fatal(diag::unsupported_bitclass) << m_pConfig->targets().triple().str() - << m_pConfig->targets().bitclass(); - return NULL; - } - } // end of switch + switch (m_pConfig->targets().bitclass()) { + case 32: { + pFragRef.memcpy(&tmp_data, 4); + tmp_data = mcld::bswap32(tmp_data); + target_data = tmp_data; + break; + } + case 64: { + pFragRef.memcpy(&target_data, 8); + target_data = mcld::bswap64(target_data); + break; + } + default: { + fatal(diag::unsupported_bitclass) << m_pConfig->targets().triple().str() + << m_pConfig->targets().bitclass(); + return NULL; + } + } // end of switch } else { pFragRef.memcpy(&target_data, (m_pConfig->targets().bitclass()/8)); diff --git a/lib/LD/Relocator.cpp b/lib/LD/Relocator.cpp index dc9445b..bf76573 100644 --- a/lib/LD/Relocator.cpp +++ b/lib/LD/Relocator.cpp @@ -16,7 +16,7 @@ #include <mcld/LD/SectionData.h> #include <mcld/Support/MsgHandling.h> #include <mcld/Module.h> -#if HAVE_CXXABI_H +#ifdef HAVE_CXXABI_H #include <cxxabi.h> #endif #include <sstream> @@ -27,7 +27,7 @@ using namespace mcld; // Helper functions //===----------------------------------------------------------------------===// std::string demangleSymbol(const std::string& mangled_name) { -#if HAVE_CXXABI_H +#ifdef HAVE_CXXABI_H // __cxa_demangle needs manually handle the memory release, so we wrap // it into this helper function. size_t output_leng; diff --git a/lib/LD/StaticResolver.cpp b/lib/LD/StaticResolver.cpp index 21826ef..d7daf1d 100644 --- a/lib/LD/StaticResolver.cpp +++ b/lib/LD/StaticResolver.cpp @@ -10,6 +10,8 @@ #include <mcld/LD/LDSymbol.h> #include <mcld/Support/MsgHandling.h> +#include <cxxabi.h> + using namespace mcld; //========================== @@ -118,7 +120,7 @@ bool StaticResolver::resolve(ResolveInfo& __restrict__ pOld, // We've seen a common symbol and now we see a definition. The // definition overrides. // - // NOTE: m_Mesg uses 'name' instead of `name' for being compatible to GNU ld. + // NOTE: m_Mesg uses 'name' instead of `name' for being compatible to GNU ld. ignore(diag::redefine_common) << old->name(); old->override(pNew); pOverride = true; @@ -169,6 +171,9 @@ bool StaticResolver::resolve(ResolveInfo& __restrict__ pOld, } /* Fall through */ case MDEF: { /* multiple definition error. */ + int status; + char* demangled_name = abi::__cxa_demangle(pNew.name(), NULL, NULL, + &status); if (pOld.isDefine() && pNew.isDefine() && pOld.isAbsolute() && pNew.isAbsolute() && (pOld.desc() == pNew.desc() || pOld.desc() == ResolveInfo::NoType || @@ -178,12 +183,21 @@ bool StaticResolver::resolve(ResolveInfo& __restrict__ pOld, old->override(pNew); break; } else { - error(diag::multiple_absolute_definitions) << pNew.name() - << pOld.outSymbol()->value() << pValue; + if (demangled_name != NULL) { + error(diag::multiple_absolute_definitions) << demangled_name + << pOld.outSymbol()->value() << pValue; + } else { + error(diag::multiple_absolute_definitions) << pNew.name() + << pOld.outSymbol()->value() << pValue; + } break; } } - error(diag::multiple_definitions) << pNew.name(); + if (demangled_name != NULL) { + error(diag::multiple_definitions) << demangled_name; + } else { + error(diag::multiple_definitions) << pNew.name(); + } break; } case REFC: { /* Mark indirect symbol referenced and then CYCLE. */ diff --git a/lib/MC/FileAction.cpp b/lib/MC/FileAction.cpp index 1c7e5ae..0de60ee 100644 --- a/lib/MC/FileAction.cpp +++ b/lib/MC/FileAction.cpp @@ -37,7 +37,7 @@ bool ContextAction::activate(InputBuilder& pBuilder) const } //===----------------------------------------------------------------------===// -// MemoryAreaAction +// MemoryAreaAction //===----------------------------------------------------------------------===// MemoryAreaAction::MemoryAreaAction(unsigned int pPosition, FileHandle::OpenMode pMode, diff --git a/lib/MC/SearchDirs.cpp b/lib/MC/SearchDirs.cpp index 971f866..1950f96 100644 --- a/lib/MC/SearchDirs.cpp +++ b/lib/MC/SearchDirs.cpp @@ -203,6 +203,6 @@ SearchDirs::find(const std::string& pNamespec, mcld::Input::Type pType) const default: break; } // end of switch - } // end of for + } // end of for return NULL; } diff --git a/lib/MC/SymbolCategory.cpp b/lib/MC/SymbolCategory.cpp index 241f18e..3bd3df6 100644 --- a/lib/MC/SymbolCategory.cpp +++ b/lib/MC/SymbolCategory.cpp @@ -120,19 +120,36 @@ SymbolCategory& SymbolCategory::arrange(LDSymbol& pSymbol, } assert(NULL != current); - assert(!current->empty()); - - // find the position of source - size_t pos = current->begin; - while (pos != current->end) { - if (m_OutputSymbols[pos] == &pSymbol) - break; - ++pos; + size_t pos = 0; + if (!current->empty()) { + // find the position of source + pos = current->begin; + while (pos != current->end) { + if (m_OutputSymbols[pos] == &pSymbol) + break; + ++pos; + } + } + // FIXME: Try to search the symbol explicitly, if symbol is not in the given + // source category. Or we need to add some logics like shouldForceLocal() in + // SymbolCategory::Category::categorize(). + if (current->end == pos || current->empty()) { + current = m_pFile; + do { + pos = current->begin; + while (pos != current->end) { + if (m_OutputSymbols[pos] == &pSymbol) { + distance = pTarget - current->type; + break; + } + ++pos; + } + if (pos != current->end) + break; + current = current->next; + } while (current != NULL); + assert(current != NULL); } - - // if symbol is not in the given source category, then do nothing - if (current->end == pos) - return *this; // The distance is positive. It means we should bubble sort downward. if (distance > 0) { diff --git a/lib/Object/ObjectBuilder.cpp b/lib/Object/ObjectBuilder.cpp index 6738c3c..09a193a 100644 --- a/lib/Object/ObjectBuilder.cpp +++ b/lib/Object/ObjectBuilder.cpp @@ -153,13 +153,21 @@ bool ObjectBuilder::MoveSectionData(SectionData& pFrom, SectionData& pTo) return true; } -/// UpdateSectionFlags - update alignment for input section +/// UpdateSectionAlign - update alignment for input section void ObjectBuilder::UpdateSectionAlign(LDSection& pTo, const LDSection& pFrom) { if (pFrom.align() > pTo.align()) pTo.setAlign(pFrom.align()); } +/// UpdateSectionAlign - update alignment for input section +void ObjectBuilder::UpdateSectionAlign(LDSection& pSection, + uint32_t pAlignConstraint) +{ + if (pSection.align() < pAlignConstraint) + pSection.setAlign(pAlignConstraint); +} + /// AppendFragment - To append pFrag to the given SectionData pSD. uint64_t ObjectBuilder::AppendFragment(Fragment& pFrag, SectionData& pSD, diff --git a/lib/Script/ScriptParser.yy b/lib/Script/ScriptParser.yy index 5b5730f..fc3e667 100644 --- a/lib/Script/ScriptParser.yy +++ b/lib/Script/ScriptParser.yy @@ -36,14 +36,9 @@ using namespace mcld; } -%pure-parser %require "2.4" %skeleton "glr.cc" -/* - * BEGIN android-removed: prevent bison from generating the header in current directory %defines "ScriptParser.h" - * END android-removed - */ %debug %error-verbose %define namespace "mcld" diff --git a/lib/Support/FileSystem.cpp b/lib/Support/FileSystem.cpp index 331297f..aaed86b 100644 --- a/lib/Support/FileSystem.cpp +++ b/lib/Support/FileSystem.cpp @@ -28,12 +28,12 @@ bool mcld::sys::fs::is_directory(const Path &pPath) return (file_status.type() == mcld::sys::fs::DirectoryFile); } -// Include the truly platform-specific parts. +// Include the truly platform-specific parts. #if defined(MCLD_ON_UNIX) #include "Unix/FileSystem.inc" -#include "Unix/PathV3.inc" -#endif +#include "Unix/PathV3.inc" +#endif #if defined(MCLD_ON_WIN32) #include "Windows/FileSystem.inc" -#include "Windows/PathV3.inc" -#endif +#include "Windows/PathV3.inc" +#endif diff --git a/lib/Support/MemoryArea.cpp b/lib/Support/MemoryArea.cpp index 862e6f1..0c7f3c1 100644 --- a/lib/Support/MemoryArea.cpp +++ b/lib/Support/MemoryArea.cpp @@ -7,6 +7,7 @@ // //===----------------------------------------------------------------------===// #include <mcld/Support/MemoryArea.h> +#include <mcld/Support/MsgHandling.h> #include <llvm/Support/system_error.h> #include <cassert> @@ -18,10 +19,12 @@ using namespace mcld; //===--------------------------------------------------------------------===// MemoryArea::MemoryArea(llvm::StringRef pFilename) { - llvm::MemoryBuffer::getFile(pFilename, - m_pMemoryBuffer, - /*FileSize*/ -1, - /*RequiresNullTerminator*/ false); + llvm::error_code ec = + llvm::MemoryBuffer::getFile(pFilename, m_pMemoryBuffer, /*FileSize*/ -1, + /*RequiresNullTerminator*/ false); + if (ec != llvm::errc::success) { + fatal(diag::fatal_cannot_read_input) << pFilename.str(); + } } MemoryArea::MemoryArea(const char* pMemBuffer, size_t pSize) diff --git a/lib/Support/SystemUtils.cpp b/lib/Support/SystemUtils.cpp index 19c5e90..b261db8 100644 --- a/lib/Support/SystemUtils.cpp +++ b/lib/Support/SystemUtils.cpp @@ -18,4 +18,4 @@ using namespace mcld::sys; #endif #if defined(MCLD_ON_WIN32) #include "Windows/System.inc" -#endif +#endif diff --git a/lib/Support/ToolOutputFile.cpp b/lib/Support/ToolOutputFile.cpp index 1223d93..a1c94f4 100644 --- a/lib/Support/ToolOutputFile.cpp +++ b/lib/Support/ToolOutputFile.cpp @@ -69,6 +69,8 @@ ToolOutputFile::ToolOutputFile(const sys::fs::Path& pPath, ToolOutputFile::~ToolOutputFile() { + if (m_pFormattedOstream != NULL) + delete m_pFormattedOstream; if (m_pFdOstream != NULL) delete m_pFdOstream; } diff --git a/lib/Target/AArch64/AArch64.h b/lib/Target/AArch64/AArch64.h new file mode 100644 index 0000000..df389e8 --- /dev/null +++ b/lib/Target/AArch64/AArch64.h @@ -0,0 +1,30 @@ +//===- AArch64.h ----------------------------------------------------------===// +// +// The MCLinker Project +// +// This file is distributed under the University of Illinois Open Source +// License. See LICENSE.TXT for details. +// +//===----------------------------------------------------------------------===// +#ifndef TARGET_AARCH64_AARCH64_H +#define TARGET_AARCH64_AARCH64_H +#include <string> + +namespace llvm { +class Target; +} // namespace of llvm + +namespace mcld { + +class Target; +class TargetLDBackend; + +extern mcld::Target TheAArch64Target; + +TargetLDBackend *createAArch64LDBackend(const llvm::Target&, + const std::string&); + +} // namespace of mcld + +#endif + diff --git a/lib/Target/AArch64/AArch64Diagnostic.cpp b/lib/Target/AArch64/AArch64Diagnostic.cpp new file mode 100644 index 0000000..6fddce4 --- /dev/null +++ b/lib/Target/AArch64/AArch64Diagnostic.cpp @@ -0,0 +1,36 @@ +//===- AArch64Diagnostic.cpp ----------------------------------------------===// +// +// The MCLinker Project +// +// This file is distributed under the University of Illinois Open Source +// License. See LICENSE.TXT for details. +// +//===----------------------------------------------------------------------===// +#include <mcld/Support/TargetRegistry.h> +#include <mcld/LD/DWARFLineInfo.h> +#include "AArch64.h" + +using namespace mcld; + +namespace mcld { +//===----------------------------------------------------------------------===// +// createAArch64Diagnostic - the help function to create corresponding +// AArch64Diagnostic +//===----------------------------------------------------------------------===// +DiagnosticLineInfo* createAArch64DiagLineInfo(const mcld::Target& pTarget, + const std::string &pTriple) +{ + return new DWARFLineInfo(); +} + +} // namespace of mcld + +//===----------------------------------------------------------------------===// +// InitializeAArch64Diagnostic +//===----------------------------------------------------------------------===// +extern "C" void MCLDInitializeAArch64DiagnosticLineInfo() { + // Register the linker frontend + mcld::TargetRegistry::RegisterDiagnosticLineInfo(TheAArch64Target, + createAArch64DiagLineInfo); +} + diff --git a/lib/Target/AArch64/AArch64ELFDynamic.cpp b/lib/Target/AArch64/AArch64ELFDynamic.cpp new file mode 100644 index 0000000..3aa572a --- /dev/null +++ b/lib/Target/AArch64/AArch64ELFDynamic.cpp @@ -0,0 +1,51 @@ +//===- AArch64ELFDynamic.cpp ----------------------------------------------===// +// +// The MCLinker Project +// +// This file is distributed under the University of Illinois Open Source +// License. See LICENSE.TXT for details. +// +//===----------------------------------------------------------------------===// +#include "AArch64ELFDynamic.h" + +#include <mcld/LD/ELFFileFormat.h> +#include <mcld/LinkerConfig.h> + +using namespace mcld; + +AArch64ELFDynamic::AArch64ELFDynamic(const GNULDBackend& pParent, + const LinkerConfig& pConfig) + : ELFDynamic(pParent, pConfig) +{ +} + +AArch64ELFDynamic::~AArch64ELFDynamic() +{ +} + +void AArch64ELFDynamic::reserveTargetEntries(const ELFFileFormat& pFormat) +{ + // reservePLTGOT + if (config().options().hasNow()) { + if (pFormat.hasGOT()) + reserveOne(llvm::ELF::DT_PLTGOT); + } + else { + if (pFormat.hasGOTPLT()) + reserveOne(llvm::ELF::DT_PLTGOT); + } +} + +void AArch64ELFDynamic::applyTargetEntries(const ELFFileFormat& pFormat) +{ + // applyPLTGOT + if (config().options().hasNow()) { + if (pFormat.hasGOT()) + applyOne(llvm::ELF::DT_PLTGOT, pFormat.getGOT().addr()); + } + else { + if (pFormat.hasGOTPLT()) + applyOne(llvm::ELF::DT_PLTGOT, pFormat.getGOTPLT().addr()); + } +} + diff --git a/lib/Target/AArch64/AArch64ELFDynamic.h b/lib/Target/AArch64/AArch64ELFDynamic.h new file mode 100644 index 0000000..04060ac --- /dev/null +++ b/lib/Target/AArch64/AArch64ELFDynamic.h @@ -0,0 +1,31 @@ +//===- AArch64ELFDynamic.h ------------------------------------------------===// +// +// The MCLinker Project +// +// This file is distributed under the University of Illinois Open Source +// License. See LICENSE.TXT for details. +// +//===----------------------------------------------------------------------===// +#ifndef TARGET_AARCH64_AARCH64ELFDYNAMIC_H +#define TARGET_AARCH64_AARCH64ELFDYNAMIC_H +#ifdef ENABLE_UNITTEST +#include <gtest.h> +#endif + +#include <mcld/Target/ELFDynamic.h> + +namespace mcld { + +class AArch64ELFDynamic : public ELFDynamic { +public: + AArch64ELFDynamic(const GNULDBackend& pParent, const LinkerConfig& pConfig); + ~AArch64ELFDynamic(); + +private: + void reserveTargetEntries(const ELFFileFormat& pFormat); + void applyTargetEntries(const ELFFileFormat& pFormat); +}; + +} // namespace of mcld + +#endif diff --git a/lib/Target/AArch64/AArch64ELFMCLinker.cpp b/lib/Target/AArch64/AArch64ELFMCLinker.cpp new file mode 100644 index 0000000..a311435 --- /dev/null +++ b/lib/Target/AArch64/AArch64ELFMCLinker.cpp @@ -0,0 +1,25 @@ +//===- AArch64ELFMCLinker.cpp ---------------------------------------------===// +// +// The MCLinker Project +// +// This file is distributed under the University of Illinois Open Source +// License. See LICENSE.TXT for details. +// +//===----------------------------------------------------------------------===// +#include "AArch64ELFMCLinker.h" + +#include <mcld/LinkerConfig.h> +#include <mcld/Object/SectionMap.h> + +using namespace mcld; + +AArch64ELFMCLinker::AArch64ELFMCLinker(LinkerConfig& pConfig, + mcld::Module &pModule, + FileHandle& pFileHandle) + : ELFMCLinker(pConfig, pModule, pFileHandle) { +} + +AArch64ELFMCLinker::~AArch64ELFMCLinker() +{ +} + diff --git a/lib/Target/AArch64/AArch64ELFMCLinker.h b/lib/Target/AArch64/AArch64ELFMCLinker.h new file mode 100644 index 0000000..36e4a5c --- /dev/null +++ b/lib/Target/AArch64/AArch64ELFMCLinker.h @@ -0,0 +1,37 @@ +//===- AArch64ELFMCLinker.h -----------------------------------------------===// +// +// The MCLinker Project +// +// This file is distributed under the University of Illinois Open Source +// License. See LICENSE.TXT for details. +// +//===----------------------------------------------------------------------===// +#ifndef TARGET_AARCH64_AARCH64ELFMCLINKER_H +#define TARGET_AARCH64_AARCH64ELFMCLINKER_H +#ifdef ENABLE_UNITTEST +#include <gtest.h> +#endif +#include <mcld/Target/ELFMCLinker.h> + +namespace mcld { + +class Module; +class FileHandle; + +/** \class AArch64ELFMCLinker + * \brief AArch64ELFMCLinker sets up the environment for linking. + */ +class AArch64ELFMCLinker : public ELFMCLinker +{ +public: + AArch64ELFMCLinker(LinkerConfig& pConfig, + mcld::Module& pModule, + FileHandle& pFileHandle); + + ~AArch64ELFMCLinker(); +}; + +} // namespace of mcld + +#endif + diff --git a/lib/Target/AArch64/AArch64Emulation.cpp b/lib/Target/AArch64/AArch64Emulation.cpp new file mode 100644 index 0000000..02f4b01 --- /dev/null +++ b/lib/Target/AArch64/AArch64Emulation.cpp @@ -0,0 +1,71 @@ +//===- AArch64Emulation.cpp -----------------------------------------------===// +// +// The MCLinker Project +// +// This file is distributed under the University of Illinois Open Source +// License. See LICENSE.TXT for details. +// +//===----------------------------------------------------------------------===// +#include "AArch64.h" +#include <mcld/LinkerConfig.h> +#include <mcld/LinkerScript.h> +#include <mcld/Target/ELFEmulation.h> +#include <mcld/Support/TargetRegistry.h> + +namespace mcld { + +static bool MCLDEmulateAArch64ELF(LinkerScript& pScript, LinkerConfig& pConfig) +{ + if (!MCLDEmulateELF(pScript, pConfig)) + return false; + + // set up bitclass and endian + pConfig.targets().setEndian(TargetOptions::Little); + pConfig.targets().setBitClass(64); + + // set up target-dependent constraints of attributes + pConfig.attribute().constraint().enableWholeArchive(); + pConfig.attribute().constraint().enableAsNeeded(); + pConfig.attribute().constraint().setSharedSystem(); + + // set up the predefined attributes + pConfig.attribute().predefined().unsetWholeArchive(); + pConfig.attribute().predefined().unsetAsNeeded(); + pConfig.attribute().predefined().setDynamic(); + + // set up section map + if (pConfig.options().getScriptList().empty() && + pConfig.codeGenType() != LinkerConfig::Object) { + pScript.sectionMap().insert(".ARM.attributes*", ".ARM.attributes"); + } + return true; +} + +//===----------------------------------------------------------------------===// +// emulateAArch64LD - the help function to emulate AArch64 ld +//===----------------------------------------------------------------------===// +bool emulateAArch64LD(LinkerScript& pScript, LinkerConfig& pConfig) +{ + if (pConfig.targets().triple().isOSDarwin()) { + assert(0 && "MachO linker has not supported yet"); + return false; + } + if (pConfig.targets().triple().isOSWindows()) { + assert(0 && "COFF linker has not supported yet"); + return false; + } + + return MCLDEmulateAArch64ELF(pScript, pConfig); +} + +} // namespace of mcld + +//===----------------------------------------------------------------------===// +// AArch64Emulation +//===----------------------------------------------------------------------===// +extern "C" void MCLDInitializeAArch64Emulation() { + // Register the emulation + mcld::TargetRegistry::RegisterEmulation(mcld::TheAArch64Target, + mcld::emulateAArch64LD); +} + diff --git a/lib/Target/AArch64/AArch64GNUInfo.h b/lib/Target/AArch64/AArch64GNUInfo.h new file mode 100644 index 0000000..554b27c --- /dev/null +++ b/lib/Target/AArch64/AArch64GNUInfo.h @@ -0,0 +1,35 @@ +//===- AArch64GNUInfo.h ---------------------------------------------------===// +// +// The MCLinker Project +// +// This file is distributed under the University of Illinois Open Source +// License. See LICENSE.TXT for details. +// +//===----------------------------------------------------------------------===// +#ifndef TARGET_AARCH64_AARCH64GNUINFO_H +#define TARGET_AARCH64_AARCH64GNUINFO_H +#include <mcld/Target/GNUInfo.h> + +#include <llvm/Support/ELF.h> + +namespace mcld { + +class AArch64GNUInfo : public GNUInfo +{ +public: + AArch64GNUInfo(const llvm::Triple& pTriple) : GNUInfo(pTriple) { } + + uint32_t machine() const { return llvm::ELF::EM_AARCH64; } + + uint64_t abiPageSize() const { return 0x10000; } + + uint64_t defaultTextSegmentAddr() const { return 0x400000; } + + // There are no processor-specific flags so this field shall contain zero. + uint64_t flags() const { return 0x0; } +}; + +} // namespace of mcld + +#endif + diff --git a/lib/Target/AArch64/AArch64GOT.cpp b/lib/Target/AArch64/AArch64GOT.cpp new file mode 100644 index 0000000..4864c07 --- /dev/null +++ b/lib/Target/AArch64/AArch64GOT.cpp @@ -0,0 +1,141 @@ +//===- AArch64GOT.cpp -----------------------------------------------------===// +// +// The MCLinker Project +// +// This file is distributed under the University of Illinois Open Source +// License. See LICENSE.TXT for details. +// +//===----------------------------------------------------------------------===// +#include "AArch64GOT.h" + +#include <llvm/Support/Casting.h> + +#include <mcld/LD/LDSection.h> +#include <mcld/LD/LDFileFormat.h> +#include <mcld/Support/MsgHandling.h> + +namespace { + const unsigned int AArch64GOT0Num = 3; +} // end of anonymous namespace + +using namespace mcld; + +//===----------------------------------------------------------------------===// +// AArch64GOT +AArch64GOT::AArch64GOT(LDSection& pSection) + : GOT(pSection), m_pGOTPLTFront(NULL), m_pGOTFront(NULL) +{ +} + +AArch64GOT::~AArch64GOT() +{ +} + +void AArch64GOT::createGOT0() +{ + // create GOT0, and put them into m_SectionData immediately + for (unsigned int i = 0; i < AArch64GOT0Num; ++i) + new AArch64GOTEntry(0, m_SectionData); +} + +bool AArch64GOT::hasGOT1() const +{ + return ((!m_GOT.empty()) || (!m_GOTPLT.empty())); +} + +AArch64GOTEntry* AArch64GOT::createGOT() +{ + AArch64GOTEntry* entry = new AArch64GOTEntry(0, NULL); + m_GOT.push_back(entry); + return entry; +} + +AArch64GOTEntry* AArch64GOT::createGOTPLT() +{ + AArch64GOTEntry* entry = new AArch64GOTEntry(0, NULL); + m_GOTPLT.push_back(entry); + return entry; +} + +void AArch64GOT::finalizeSectionSize() +{ + uint32_t offset = 0; + SectionData::FragmentListType& frag_list = m_SectionData->getFragmentList(); + // setup GOT0 offset + SectionData::iterator frag, fragEnd = m_SectionData->end(); + for (frag = m_SectionData->begin(); frag != fragEnd; ++frag) { + frag->setOffset(offset); + offset += frag->size(); + } + + // push GOTPLT into the SectionData and setup the offset + if (!m_GOTPLT.empty()) { + m_pGOTPLTFront = m_GOTPLT.front(); + entry_iterator it, end = m_GOTPLT.end(); + for (it = m_GOTPLT.begin(); it != end; ++it) { + AArch64GOTEntry* entry = *it; + frag_list.push_back(entry); + entry->setParent(m_SectionData); + entry->setOffset(offset); + offset += entry->size(); + + } + } + m_GOTPLT.clear(); + + // push GOT into the SectionData and setup the offset + if (!m_GOT.empty()) { + m_pGOTFront = m_GOT.front(); + entry_iterator it, end = m_GOT.end(); + for (it = m_GOT.begin(); it != end; ++it) { + AArch64GOTEntry* entry = *it; + frag_list.push_back(entry); + entry->setParent(m_SectionData); + entry->setOffset(offset); + offset += entry->size(); + } + } + m_GOT.clear(); + + // set section size + m_Section.setSize(offset); +} + +void AArch64GOT::applyGOT0(uint64_t pAddress) +{ + llvm::cast<AArch64GOTEntry> + (*(m_SectionData->getFragmentList().begin())).setValue(pAddress); +} + +void AArch64GOT::applyGOTPLT(uint64_t pPLTBase) +{ + if (NULL == m_pGOTPLTFront) + return; + + SectionData::iterator entry(m_pGOTPLTFront); + SectionData::iterator e_end; + if (NULL == m_pGOTFront) + e_end = m_SectionData->end(); + else + e_end = SectionData::iterator(m_pGOTFront); + + while (entry != e_end) { + llvm::cast<AArch64GOTEntry>(entry)->setValue(pPLTBase); + ++entry; + } +} + +uint64_t AArch64GOT::emit(MemoryRegion& pRegion) +{ + uint64_t* buffer = reinterpret_cast<uint64_t*>(pRegion.begin()); + + AArch64GOTEntry* got = NULL; + uint64_t result = 0x0; + for (iterator it = begin(), ie = end(); it != ie; ++it, ++buffer) { + got = &(llvm::cast<AArch64GOTEntry>((*it))); + *buffer = static_cast<uint64_t>(got->getValue()); + result += AArch64GOTEntry::EntrySize; + } + return result; +} + diff --git a/lib/Target/AArch64/AArch64GOT.h b/lib/Target/AArch64/AArch64GOT.h new file mode 100644 index 0000000..87d91eb --- /dev/null +++ b/lib/Target/AArch64/AArch64GOT.h @@ -0,0 +1,103 @@ +//===- AArch64GOT.h -------------------------------------------------------===// +// +// The MCLinker Project +// +// This file is distributed under the University of Illinois Open Source +// License. See LICENSE.TXT for details. +// +//===----------------------------------------------------------------------===// +#ifndef TARGET_AARCH64_AARCH64GOT_H +#define TARGET_AARCH64_AARCH64GOT_H +#ifdef ENABLE_UNITTEST +#include <gtest.h> +#endif + +#include <mcld/Support/MemoryRegion.h> +#include <mcld/Target/GOT.h> + +#include <llvm/ADT/DenseMap.h> + +#include <vector> + +namespace mcld { + +class LDSection; + +/** \class AArch64GOTEntry + * \brief GOT Entry with size of 8 bytes + */ +class AArch64GOTEntry : public GOT::Entry<8> +{ +public: + AArch64GOTEntry(uint64_t pContent, SectionData* pParent) + : GOT::Entry<8>(pContent, pParent) + {} +}; + +/** \class AArch64GOT + * \brief AArch64 Global Offset Table. + * + * AArch64 GOT integrates traditional .got.plt and .got sections into one. + * Traditional .got.plt is placed in the front part of GOT (PLTGOT), and + * traditional .got is placed in the rear part of GOT (GOT). When -z now and + * -z relro are given, the got section layout will be as below. Otherwise, + * there will be two seperated sections, .got and .got.plt. + * + * This class may be used as .got (with no GOTPLT entry), .got.plt (with only + * GOTPLT entries) or .got (with GOTPLT and normal GOT entries) + * + * AArch64 .got + * +--------------+ + * | GOT0 | + * +--------------+ + * | GOTPLT | + * +--------------+ + * | GOT | + * +--------------+ + * + */ +class AArch64GOT : public GOT +{ +public: + AArch64GOT(LDSection &pSection); + + ~AArch64GOT(); + + /// createGOT0 - create the defualt GOT0 entries. This function called when + /// it's a .got section (with GOTPLT entries and normal GOT entry) or it's a + /// .got.plt section + void createGOT0(); + + AArch64GOTEntry* createGOT(); + AArch64GOTEntry* createGOTPLT(); + + void finalizeSectionSize(); + + uint64_t emit(MemoryRegion& pRegion); + + void applyGOT0(uint64_t pAddress); + + void applyGOTPLT(uint64_t pPLTBase); + + bool hasGOT1() const; + +private: + typedef std::vector<AArch64GOTEntry*> EntryListType; + typedef EntryListType::iterator entry_iterator; + typedef EntryListType::const_iterator const_entry_iterator; + +private: + AArch64GOTEntry* m_pGOTPLTFront; + AArch64GOTEntry* m_pGOTFront; + + /// m_GOTPLTEntries - a list of gotplt entries + EntryListType m_GOTPLT; + + /// m_GOTEntris - a list of got entries + EntryListType m_GOT; +}; + +} // namespace of mcld + +#endif + diff --git a/lib/Target/AArch64/AArch64LDBackend.cpp b/lib/Target/AArch64/AArch64LDBackend.cpp new file mode 100644 index 0000000..254b912 --- /dev/null +++ b/lib/Target/AArch64/AArch64LDBackend.cpp @@ -0,0 +1,458 @@ +//===- AArch64LDBackend.cpp -----------------------------------------------===// +// +// The MCLinker Project +// +// This file is distributed under the University of Illinois Open Source +// License. See LICENSE.TXT for details. +// +//===----------------------------------------------------------------------===// +#include "AArch64.h" +#include "AArch64ELFDynamic.h" +#include "AArch64GNUInfo.h" +#include "AArch64LDBackend.h" +#include "AArch64Relocator.h" + +#include <cstring> + +#include <llvm/ADT/Triple.h> +#include <llvm/ADT/Twine.h> +#include <llvm/Support/ELF.h> +#include <llvm/Support/Casting.h> + +#include <mcld/IRBuilder.h> +#include <mcld/LinkerConfig.h> +#include <mcld/Fragment/FillFragment.h> +#include <mcld/Fragment/AlignFragment.h> +#include <mcld/Fragment/RegionFragment.h> +#include <mcld/Fragment/Stub.h> +#include <mcld/Fragment/NullFragment.h> +#include <mcld/Support/MemoryRegion.h> +#include <mcld/Support/MemoryArea.h> +#include <mcld/Support/MsgHandling.h> +#include <mcld/Support/TargetRegistry.h> +#include <mcld/LD/BranchIslandFactory.h> +#include <mcld/LD/StubFactory.h> +#include <mcld/LD/LDContext.h> +#include <mcld/LD/ELFFileFormat.h> +#include <mcld/LD/ELFSegmentFactory.h> +#include <mcld/LD/ELFSegment.h> +#include <mcld/Target/ELFAttribute.h> +#include <mcld/Target/GNUInfo.h> +#include <mcld/Object/ObjectBuilder.h> + +using namespace mcld; + +//===----------------------------------------------------------------------===// +// AArch64GNULDBackend +//===----------------------------------------------------------------------===// +AArch64GNULDBackend::AArch64GNULDBackend(const LinkerConfig& pConfig, + GNUInfo* pInfo) + : GNULDBackend(pConfig, pInfo), + m_pRelocator(NULL), + m_pGOT(NULL), + m_pGOTPLT(NULL), + m_pPLT(NULL), + m_pRelaDyn(NULL), + m_pRelaPLT(NULL), + // m_pAttrData(NULL), + m_pDynamic(NULL), + m_pGOTSymbol(NULL), + m_pAttributes(NULL) { +} + +AArch64GNULDBackend::~AArch64GNULDBackend() +{ + if (m_pRelocator != NULL) + delete m_pRelocator; + if (m_pGOT == m_pGOTPLT) { + if (m_pGOT != NULL) + delete m_pGOT; + } else { + if (m_pGOT != NULL) + delete m_pGOT; + if (m_pGOTPLT != NULL) + delete m_pGOTPLT; + } + if (m_pPLT != NULL) + delete m_pPLT; + if (m_pRelaDyn != NULL) + delete m_pRelaDyn; + if (m_pRelaPLT != NULL) + delete m_pRelaPLT; + if (m_pDynamic != NULL) + delete m_pDynamic; +} + +void AArch64GNULDBackend::initTargetSections(Module& pModule, + ObjectBuilder& pBuilder) +{ + // TODO + + if (LinkerConfig::Object != config().codeGenType()) { + ELFFileFormat* file_format = getOutputFormat(); + + // initialize .got + LDSection& got = file_format->getGOT(); + m_pGOT = new AArch64GOT(got); + if (config().options().hasNow()) { + // when -z now is given, there will be only one .got section (contains + // both GOTPLT and normal GOT entries), create GOT0 for .got section and + // set m_pGOTPLT to the same .got + m_pGOT->createGOT0(); + m_pGOTPLT = m_pGOT; + } + else { + // Otherwise, got should be seperated to two sections, .got and .got.plt + // initialize .got.plt + LDSection& gotplt = file_format->getGOTPLT(); + m_pGOTPLT = new AArch64GOT(gotplt); + m_pGOTPLT->createGOT0(); + } + + // initialize .plt + LDSection& plt = file_format->getPLT(); + m_pPLT = new AArch64PLT(plt, *m_pGOTPLT); + + // initialize .rela.plt + LDSection& relaplt = file_format->getRelaPlt(); + relaplt.setLink(&plt); + m_pRelaPLT = new OutputRelocSection(pModule, relaplt); + + // initialize .rela.dyn + LDSection& reladyn = file_format->getRelaDyn(); + m_pRelaDyn = new OutputRelocSection(pModule, reladyn); + } +} + +void AArch64GNULDBackend::initTargetSymbols(IRBuilder& pBuilder, + Module& pModule) +{ + // Define the symbol _GLOBAL_OFFSET_TABLE_ if there is a symbol with the + // same name in input + if (LinkerConfig::Object != config().codeGenType()) { + m_pGOTSymbol = pBuilder.AddSymbol<IRBuilder::AsReferred, IRBuilder::Resolve>( + "_GLOBAL_OFFSET_TABLE_", + ResolveInfo::Object, + ResolveInfo::Define, + ResolveInfo::Local, + 0x0, // size + 0x0, // value + FragmentRef::Null(), + ResolveInfo::Hidden); + } + // TODO +} + +bool AArch64GNULDBackend::initRelocator() +{ + if (NULL == m_pRelocator) { + m_pRelocator = new AArch64Relocator(*this, config()); + } + return true; +} + +Relocator* AArch64GNULDBackend::getRelocator() +{ + assert(NULL != m_pRelocator); + return m_pRelocator; +} + +void AArch64GNULDBackend::defineGOTSymbol(IRBuilder& pBuilder) +{ + // define symbol _GLOBAL_OFFSET_TABLE_ when .got create + if (m_pGOTSymbol != NULL) { + pBuilder.AddSymbol<IRBuilder::Force, IRBuilder::Unresolve>( + "_GLOBAL_OFFSET_TABLE_", + ResolveInfo::Object, + ResolveInfo::Define, + ResolveInfo::Local, + 0x0, // size + 0x0, // value + FragmentRef::Create(*(m_pGOTPLT->begin()), 0x0), + ResolveInfo::Hidden); + } + else { + m_pGOTSymbol = pBuilder.AddSymbol<IRBuilder::Force, IRBuilder::Resolve>( + "_GLOBAL_OFFSET_TABLE_", + ResolveInfo::Object, + ResolveInfo::Define, + ResolveInfo::Local, + 0x0, // size + 0x0, // value + FragmentRef::Create(*(m_pGOTPLT->begin()), 0x0), + ResolveInfo::Hidden); + } +} + +void AArch64GNULDBackend::doPreLayout(IRBuilder& pBuilder) +{ + // initialize .dynamic data + if (!config().isCodeStatic() && NULL == m_pDynamic) + m_pDynamic = new AArch64ELFDynamic(*this, config()); + + if (LinkerConfig::Object != config().codeGenType()) { + // set .got size + if (config().options().hasNow()) { + // when building shared object, the GOTPLT section is must + if (LinkerConfig::DynObj == config().codeGenType() || + m_pGOT->hasGOT1() || + NULL != m_pGOTSymbol) { + m_pGOT->finalizeSectionSize(); + defineGOTSymbol(pBuilder); + } + } + else { + // when building shared object, the GOTPLT section is must + if (LinkerConfig::DynObj == config().codeGenType() || + m_pGOTPLT->hasGOT1() || + NULL != m_pGOTSymbol) { + m_pGOTPLT->finalizeSectionSize(); + defineGOTSymbol(pBuilder); + } + if (m_pGOT->hasGOT1()) + m_pGOT->finalizeSectionSize(); + } + + // set .plt size + if (m_pPLT->hasPLT1()) + m_pPLT->finalizeSectionSize(); + + ELFFileFormat* file_format = getOutputFormat(); + // set .rela.dyn size + if (!m_pRelaDyn->empty()) { + assert(!config().isCodeStatic() && + "static linkage should not result in a dynamic relocation section"); + file_format->getRelaDyn().setSize( + m_pRelaDyn->numOfRelocs() * getRelaEntrySize()); + } + + // set .rela.plt size + if (!m_pRelaPLT->empty()) { + assert(!config().isCodeStatic() && + "static linkage should not result in a dynamic relocation section"); + file_format->getRelaPlt().setSize( + m_pRelaPLT->numOfRelocs() * getRelaEntrySize()); + } + } +} + +void AArch64GNULDBackend::doPostLayout(Module& pModule, IRBuilder& pBuilder) +{ + const ELFFileFormat *file_format = getOutputFormat(); + + // apply PLT + if (file_format->hasPLT()) { + assert(NULL != m_pPLT); + m_pPLT->applyPLT0(); + m_pPLT->applyPLT1(); + } + + // apply GOTPLT + if ((config().options().hasNow() && file_format->hasGOT()) || + file_format->hasGOTPLT()) { + assert(NULL != m_pGOTPLT); + if (LinkerConfig::DynObj == config().codeGenType()) + m_pGOTPLT->applyGOT0(file_format->getDynamic().addr()); + else { + // executable file and object file? should fill with zero. + m_pGOTPLT->applyGOT0(0); + } + } +} + +AArch64ELFDynamic& AArch64GNULDBackend::dynamic() +{ + assert(NULL != m_pDynamic); + return *m_pDynamic; +} + +const AArch64ELFDynamic& AArch64GNULDBackend::dynamic() const +{ + assert(NULL != m_pDynamic); + return *m_pDynamic; +} + +uint64_t AArch64GNULDBackend::emitSectionData(const LDSection& pSection, + MemoryRegion& pRegion) const +{ + assert(pRegion.size() && "Size of MemoryRegion is zero!"); + + const ELFFileFormat* file_format = getOutputFormat(); + + if (file_format->hasPLT() && (&pSection == &(file_format->getPLT()))) { + uint64_t result = m_pPLT->emit(pRegion); + return result; + } + + if (file_format->hasGOT() && (&pSection == &(file_format->getGOT()))) { + uint64_t result = m_pGOT->emit(pRegion); + return result; + } + + if (file_format->hasGOTPLT() && (&pSection == &(file_format->getGOTPLT()))) { + uint64_t result = m_pGOT->emit(pRegion); + return result; + } + + // TODO + return pRegion.size(); +} + +unsigned int +AArch64GNULDBackend::getTargetSectionOrder(const LDSection& pSectHdr) const +{ + const ELFFileFormat* file_format = getOutputFormat(); + + if (file_format->hasGOT() && (&pSectHdr == &file_format->getGOT())) { + if (config().options().hasNow()) + return SHO_RELRO; + return SHO_RELRO_LAST; + } + + if (file_format->hasGOTPLT() && (&pSectHdr == &file_format->getGOTPLT())) + return SHO_NON_RELRO_FIRST; + + if (file_format->hasPLT() && (&pSectHdr == &file_format->getPLT())) + return SHO_PLT; + + return SHO_UNDEFINED; +} + +bool AArch64GNULDBackend::doRelax(Module& pModule, + IRBuilder& pBuilder, + bool& pFinished) +{ + // TODO + return false; +} + +bool AArch64GNULDBackend::initTargetStubs() +{ + // TODO + return true; +} + +void AArch64GNULDBackend::doCreateProgramHdrs(Module& pModule) +{ + // TODO +} + +bool AArch64GNULDBackend::finalizeTargetSymbols() +{ + // TODO + return true; +} + +bool AArch64GNULDBackend::mergeSection(Module& pModule, + const Input& pInput, + LDSection& pSection) +{ + // TODO + return true; +} + +bool AArch64GNULDBackend::readSection(Input& pInput, SectionData& pSD) +{ + // TODO + return true; +} + +AArch64GOT& AArch64GNULDBackend::getGOT() +{ + assert(NULL != m_pGOT && "GOT section not exist"); + return *m_pGOT; +} + +const AArch64GOT& AArch64GNULDBackend::getGOT() const +{ + assert(NULL != m_pGOT && "GOT section not exist"); + return *m_pGOT; +} + +AArch64GOT& AArch64GNULDBackend::getGOTPLT() +{ + assert(NULL != m_pGOTPLT && "GOTPLT section not exist"); + return *m_pGOTPLT; +} + +const AArch64GOT& AArch64GNULDBackend::getGOTPLT() const +{ + assert(NULL != m_pGOTPLT && "GOTPLT section not exist"); + return *m_pGOTPLT; +} + +AArch64PLT& AArch64GNULDBackend::getPLT() +{ + assert(NULL != m_pPLT && "PLT section not exist"); + return *m_pPLT; +} + +const AArch64PLT& AArch64GNULDBackend::getPLT() const +{ + assert(NULL != m_pPLT && "PLT section not exist"); + return *m_pPLT; +} + +OutputRelocSection& AArch64GNULDBackend::getRelaDyn() +{ + assert(NULL != m_pRelaDyn && ".rela.dyn section not exist"); + return *m_pRelaDyn; +} + +const OutputRelocSection& AArch64GNULDBackend::getRelaDyn() const +{ + assert(NULL != m_pRelaDyn && ".rela.dyn section not exist"); + return *m_pRelaDyn; +} + +OutputRelocSection& AArch64GNULDBackend::getRelaPLT() +{ + assert(NULL != m_pRelaPLT && ".rela.plt section not exist"); + return *m_pRelaPLT; +} + +const OutputRelocSection& AArch64GNULDBackend::getRelaPLT() const +{ + assert(NULL != m_pRelaPLT && ".rela.plt section not exist"); + return *m_pRelaPLT; +} + +namespace mcld { + +//===----------------------------------------------------------------------===// +// createAArch64LDBackend - the help funtion to create corresponding +// AArch64LDBackend +//===----------------------------------------------------------------------===// +TargetLDBackend* createAArch64LDBackend(const LinkerConfig& pConfig) +{ + if (pConfig.targets().triple().isOSDarwin()) { + assert(0 && "MachO linker is not supported yet"); + /** + return new AArch64MachOLDBackend(createAArch64MachOArchiveReader, + createAArch64MachOObjectReader, + createAArch64MachOObjectWriter); + **/ + } + if (pConfig.targets().triple().isOSWindows()) { + assert(0 && "COFF linker is not supported yet"); + /** + return new AArch64COFFLDBackend(createAArch64COFFArchiveReader, + createAArch64COFFObjectReader, + createAArch64COFFObjectWriter); + **/ + } + return new AArch64GNULDBackend(pConfig, + new AArch64GNUInfo(pConfig.targets().triple())); +} + +} // namespace of mcld + +//===----------------------------------------------------------------------===// +// Force static initialization. +//===----------------------------------------------------------------------===// +extern "C" void MCLDInitializeAArch64LDBackend() { + // Register the linker backend + mcld::TargetRegistry::RegisterTargetLDBackend(TheAArch64Target, + createAArch64LDBackend); +} + diff --git a/lib/Target/AArch64/AArch64LDBackend.h b/lib/Target/AArch64/AArch64LDBackend.h new file mode 100644 index 0000000..1735043 --- /dev/null +++ b/lib/Target/AArch64/AArch64LDBackend.h @@ -0,0 +1,167 @@ +//===- AArch64LDBackend.h -------------------------------------------------===// +// +// The MCLinker Project +// +// This file is distributed under the University of Illinois Open Source +// License. See LICENSE.TXT for details. +// +//===----------------------------------------------------------------------===// +#ifndef TARGET_AARCH64_AARCH64LDBACKEND_H +#define TARGET_AARCH64_AARCH64LDBACKEND_H + +#include "AArch64ELFDynamic.h" +#include "AArch64GOT.h" +#include "AArch64PLT.h" +#include <mcld/LD/LDSection.h> +#include <mcld/Target/GNULDBackend.h> +#include <mcld/Target/OutputRelocSection.h> + +namespace mcld { + +class LinkerConfig; +class GNUInfo; + +//===----------------------------------------------------------------------===// +/// AArch64GNULDBackend - linker backend of AArch64 target of GNU ELF format +/// +class AArch64GNULDBackend : public GNULDBackend +{ +public: + AArch64GNULDBackend(const LinkerConfig& pConfig, GNUInfo* pInfo); + ~AArch64GNULDBackend(); + +public: + /// initTargetSections - initialize target dependent sections in output. + void initTargetSections(Module& pModule, ObjectBuilder& pBuilder); + + /// initTargetSymbols - initialize target dependent symbols in output. + void initTargetSymbols(IRBuilder& pBuilder, Module& pModule); + + /// initRelocator - create and initialize Relocator. + bool initRelocator(); + + /// getRelocator - return relocator. + Relocator* getRelocator(); + + + /// doPreLayout - Backend can do any needed modification before layout + void doPreLayout(IRBuilder& pBuilder); + + /// doPostLayout -Backend can do any needed modification after layout + void doPostLayout(Module& pModule, IRBuilder& pBuilder); + + /// dynamic - the dynamic section of the target machine. + /// Use co-variant return type to return its own dynamic section. + AArch64ELFDynamic& dynamic(); + + /// dynamic - the dynamic section of the target machine. + /// Use co-variant return type to return its own dynamic section. + const AArch64ELFDynamic& dynamic() const; + + + /// emitSectionData - write out the section data into the memory region. + /// When writers get a LDSection whose kind is LDFileFormat::Target, writers + /// call back target backend to emit the data. + /// + /// Backends handle the target-special tables (plt, gp,...) by themselves. + /// Backend can put the data of the tables in SectionData directly + /// - LDSection.getSectionData can get the section data. + /// Or, backend can put the data into special data structure + /// - backend can maintain its own map<LDSection, table> to get the table + /// from given LDSection. + /// + /// @param pSection - the given LDSection + /// @param pConfig - all options in the command line. + /// @param pRegion - the region to write out data + /// @return the size of the table in the file. + uint64_t emitSectionData(const LDSection& pSection, + MemoryRegion& pRegion) const; + + AArch64GOT& getGOT(); + const AArch64GOT& getGOT() const; + + AArch64GOT& getGOTPLT(); + const AArch64GOT& getGOTPLT() const; + + AArch64PLT& getPLT(); + const AArch64PLT& getPLT() const; + + OutputRelocSection& getRelaDyn(); + const OutputRelocSection& getRelaDyn() const; + + OutputRelocSection& getRelaPLT(); + const OutputRelocSection& getRelaPLT() const; + + LDSymbol* getGOTSymbol() { return m_pGOTSymbol; } + const LDSymbol* getGOTSymbol() const { return m_pGOTSymbol; } + + /// getTargetSectionOrder - compute the layout order of AArch64 target sections + unsigned int getTargetSectionOrder(const LDSection& pSectHdr) const; + + /// finalizeTargetSymbols - finalize the symbol value + bool finalizeTargetSymbols(); + + /// mergeSection - merge target dependent sections + bool mergeSection(Module& pModule, const Input& pInput, LDSection& pSection); + + /// readSection - read target dependent sections + bool readSection(Input& pInput, SectionData& pSD); + +private: + void defineGOTSymbol(IRBuilder& pBuilder); + + /// maxBranchOffset + /// FIXME: + uint64_t maxBranchOffset() { return 0x0; } + + /// mayRelax - Backends should override this function if they need relaxation + bool mayRelax() { return true; } + + /// doRelax - Backend can orevride this function to add its relaxation + /// implementation. Return true if the output (e.g., .text) is "relaxed" + /// (i.e. layout is changed), and set pFinished to true if everything is fit, + /// otherwise set it to false. + bool doRelax(Module& pModule, IRBuilder& pBuilder, bool& pFinished); + + /// initTargetStubs + bool initTargetStubs(); + + /// getRelEntrySize - the size in BYTE of rel type relocation + size_t getRelEntrySize() + { return 16; } + + /// getRelEntrySize - the size in BYTE of rela type relocation + size_t getRelaEntrySize() + { return 24; } + + /// doCreateProgramHdrs - backend can implement this function to create the + /// target-dependent segments + virtual void doCreateProgramHdrs(Module& pModule); + +private: + Relocator* m_pRelocator; + + AArch64GOT* m_pGOT; + AArch64GOT* m_pGOTPLT; + AArch64PLT* m_pPLT; + /// m_RelDyn - dynamic relocation table of .rel.dyn + OutputRelocSection* m_pRelaDyn; + /// m_RelPLT - dynamic relocation table of .rel.plt + OutputRelocSection* m_pRelaPLT; + + /// m_pAttrData - attribute data in public ("aeabi") attribute subsection + // AArch64ELFAttributeData* m_pAttrData; + + AArch64ELFDynamic* m_pDynamic; + LDSymbol* m_pGOTSymbol; + + // variable name : ELF + LDSection* m_pAttributes; // .ARM.attributes +// LDSection* m_pPreemptMap; // .AArch64.preemptmap +// LDSection* m_pDebugOverlay; // .AArch64.debug_overlay +// LDSection* m_pOverlayTable; // .AArch64.overlay_table +}; +} // namespace of mcld + +#endif + diff --git a/lib/Target/AArch64/AArch64MCLinker.cpp b/lib/Target/AArch64/AArch64MCLinker.cpp new file mode 100644 index 0000000..538461a --- /dev/null +++ b/lib/Target/AArch64/AArch64MCLinker.cpp @@ -0,0 +1,51 @@ +//===- AArch64MCLinker.cpp-------------------------------------------------===// +// +// The MCLinker Project +// +// This file is distributed under the University of Illinois Open Source +// License. See LICENSE.TXT for details. +// +//===----------------------------------------------------------------------===// +#include "AArch64ELFMCLinker.h" + +#include "AArch64.h" +#include <llvm/ADT/Triple.h> +#include <mcld/Module.h> +#include <mcld/Support/TargetRegistry.h> + +using namespace mcld; + +namespace mcld { +//===----------------------------------------------------------------------===// +// createAArch64MCLinker - the help function to create corresponding +// AArch64MCLinker +//===----------------------------------------------------------------------===// +MCLinker* createAArch64MCLinker(const std::string& pTriple, + LinkerConfig& pConfig, + mcld::Module& pModule, + FileHandle& pFileHandle) +{ + 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 AArch64ELFMCLinker(pConfig, pModule, pFileHandle); +} + +} // namespace of mcld + +//===----------------------------------------------------------------------===// +// AArch64MCLinker +//===----------------------------------------------------------------------===// +extern "C" void MCLDInitializeAArch64MCLinker() { + // Register the linker frontend + mcld::TargetRegistry::RegisterMCLinker(TheAArch64Target, + createAArch64MCLinker); +} + diff --git a/lib/Target/AArch64/AArch64PLT.cpp b/lib/Target/AArch64/AArch64PLT.cpp new file mode 100644 index 0000000..c24327d --- /dev/null +++ b/lib/Target/AArch64/AArch64PLT.cpp @@ -0,0 +1,171 @@ +//===- AArch64PLT.cpp -----------------------------------------------------===// +// +// The MCLinker Project +// +// This file is distributed under the University of Illinois Open Source +// License. See LICENSE.TXT for details. +// +//===----------------------------------------------------------------------===// +#include "AArch64GOT.h" +#include "AArch64PLT.h" +#include "AArch64RelocationHelpers.h" + +#include <new> + +#include <llvm/Support/Casting.h> + +#include <mcld/LD/LDSection.h> +#include <mcld/Support/MsgHandling.h> + +using namespace mcld; + +AArch64PLT0::AArch64PLT0(SectionData& pParent) + : PLT::Entry<sizeof(aarch64_plt0)>(pParent) {} + +AArch64PLT1::AArch64PLT1(SectionData& pParent) + : PLT::Entry<sizeof(aarch64_plt1)>(pParent) {} + +//===----------------------------------------------------------------------===// +// AArch64PLT + +AArch64PLT::AArch64PLT(LDSection& pSection, AArch64GOT &pGOTPLT) + : PLT(pSection), m_GOT(pGOTPLT) { + new AArch64PLT0(*m_pSectionData); +} + +AArch64PLT::~AArch64PLT() +{ +} + +bool AArch64PLT::hasPLT1() const +{ + return (m_pSectionData->size() > 1); +} + +void AArch64PLT::finalizeSectionSize() +{ + uint64_t size = (m_pSectionData->size() - 1) * sizeof(aarch64_plt1) + + sizeof(aarch64_plt0); + m_Section.setSize(size); + + uint32_t offset = 0; + SectionData::iterator frag, fragEnd = m_pSectionData->end(); + for (frag = m_pSectionData->begin(); frag != fragEnd; ++frag) { + frag->setOffset(offset); + offset += frag->size(); + } +} + +AArch64PLT1* AArch64PLT::create() +{ + AArch64PLT1* plt1_entry = new (std::nothrow) AArch64PLT1(*m_pSectionData); + if (!plt1_entry) + fatal(diag::fail_allocate_memory_plt); + return plt1_entry; +} + +void AArch64PLT::applyPLT0() +{ + // malloc plt0 + iterator first = m_pSectionData->getFragmentList().begin(); + assert(first != m_pSectionData->getFragmentList().end() && + "FragmentList is empty, applyPLT0 failed!"); + AArch64PLT0* plt0 = &(llvm::cast<AArch64PLT0>(*first)); + uint32_t* data = NULL; + data = static_cast<uint32_t*>(malloc(AArch64PLT0::EntrySize)); + if (data == NULL) + fatal(diag::fail_allocate_memory_plt); + memcpy(data, aarch64_plt0, AArch64PLT0::EntrySize); + + // apply plt0 + uint64_t plt_base = m_Section.addr(); + assert(plt_base && ".plt base address is NULL!"); + uint64_t got_base = m_GOT.addr(); + assert(got_base && ".got base address is NULL!"); + + // apply 2nd instruction + // get the address of got entry 2 + uint64_t got_ent2_base = got_base + sizeof(AArch64GOTEntry::EntrySize) * 2; + // compute the immediate + AArch64Relocator::DWord imm = helper_get_page_address(got_ent2_base) - + helper_get_page_address(plt_base + (sizeof(AArch64PLT0::EntrySize) * 8)); + data[1] = helper_reencode_adr_imm(data[1], imm >> 12); + // apply 3rd instruction + data[2] = helper_reencode_add_imm(data[2], + helper_get_page_offset(got_ent2_base) >> 3); + // apply 4th instruction + data[3] = helper_reencode_add_imm(data[3], + helper_get_page_offset(got_ent2_base)); + plt0->setValue(reinterpret_cast<unsigned char*>(data)); +} + +void AArch64PLT::applyPLT1() +{ + uint64_t plt_base = m_Section.addr(); + assert(plt_base && ".plt base address is NULL!"); + + uint64_t got_base = m_GOT.addr(); + assert(got_base && ".got base address is NULL!"); + + AArch64PLT::iterator it = m_pSectionData->begin(); + AArch64PLT::iterator ie = m_pSectionData->end(); + assert(it != ie && "FragmentList is empty, applyPLT1 failed!"); + + uint32_t GOTEntrySize = AArch64GOTEntry::EntrySize; + // first gotplt1 address + uint32_t GOTEntryAddress = got_base + GOTEntrySize * 3; + // first plt1 address + uint32_t PLTEntryAddress = plt_base + AArch64PLT0::EntrySize; + + ++it; //skip PLT0 + uint32_t PLT1EntrySize = AArch64PLT1::EntrySize; + AArch64PLT1* plt1 = NULL; + + uint32_t* Out = NULL; + while (it != ie) { + plt1 = &(llvm::cast<AArch64PLT1>(*it)); + Out = static_cast<uint32_t*>(malloc(AArch64PLT1::EntrySize)); + memcpy(Out, aarch64_plt1, AArch64PLT1::EntrySize); + // apply 1st instruction + AArch64Relocator::DWord imm = helper_get_page_address(GOTEntryAddress) - + helper_get_page_address(PLTEntryAddress); + Out[0] = helper_reencode_adr_imm(Out[0], imm >> 12); + // apply 2nd instruction + Out[1] = helper_reencode_add_imm( + Out[1], helper_get_page_offset(GOTEntryAddress) >> 3); + // apply 3rd instruction + Out[2] = helper_reencode_add_imm( + Out[2], helper_get_page_offset(GOTEntryAddress)); + + plt1->setValue(reinterpret_cast<unsigned char*>(Out)); + ++it; + + GOTEntryAddress += GOTEntrySize; + PLTEntryAddress += PLT1EntrySize; + } + + m_GOT.applyGOTPLT(plt_base); +} + +uint64_t AArch64PLT::emit(MemoryRegion& pRegion) +{ + uint64_t result = 0x0; + iterator it = begin(); + + unsigned char* buffer = pRegion.begin(); + memcpy(buffer, llvm::cast<AArch64PLT0>((*it)).getValue(), + AArch64PLT0::EntrySize); + result += AArch64PLT0::EntrySize; + ++it; + + AArch64PLT1* plt1 = NULL; + AArch64PLT::iterator ie = end(); + while (it != ie) { + plt1 = &(llvm::cast<AArch64PLT1>(*it)); + memcpy(buffer + result, plt1->getValue(), AArch64PLT1::EntrySize); + result += AArch64PLT1::EntrySize; + ++it; + } + return result; +} + diff --git a/lib/Target/AArch64/AArch64PLT.h b/lib/Target/AArch64/AArch64PLT.h new file mode 100644 index 0000000..c63e2e0 --- /dev/null +++ b/lib/Target/AArch64/AArch64PLT.h @@ -0,0 +1,86 @@ +//===- AArch64PLT.h -------------------------------------------------------===// +// +// The MCLinker Project +// +// This file is distributed under the University of Illinois Open Source +// License. See LICENSE.TXT for details. +// +//===----------------------------------------------------------------------===// +#ifndef TARGET_AARCH64_AARCH64PLT_H +#define TARGET_AARCH64_AARCH64PLT_H + +#include <mcld/Target/GOT.h> +#include <mcld/Target/PLT.h> +#include <mcld/Support/MemoryRegion.h> + +namespace { + +const uint8_t aarch64_plt0[] = { + 0xf0, 0x7b, 0xbf, 0xa9, /* stp x16, x30, [sp, #-16]! */ + 0x10, 0x00, 0x00, 0x90, /* adrp x16, (GOT+16) */ + 0x11, 0x0A, 0x40, 0xf9, /* ldr x17, [x16, #PLT_GOT+0x10] */ + 0x10, 0x42, 0x00, 0x91, /* add x16, x16,#PLT_GOT+0x10 */ + 0x20, 0x02, 0x1f, 0xd6, /* br x17 */ + 0x1f, 0x20, 0x03, 0xd5, /* nop */ + 0x1f, 0x20, 0x03, 0xd5, /* nop */ + 0x1f, 0x20, 0x03, 0xd5 /* nop */ +}; + +const uint8_t aarch64_plt1[] = { + 0x10, 0x00, 0x00, 0x90, /* adrp x16, PLTGOT + n * 8 */ + 0x11, 0x02, 0x40, 0xf9, /* ldr x17, [x16, PLTGOT + n * 8] */ + 0x10, 0x02, 0x00, 0x91, /* add x16, x16, :lo12:PLTGOT + n * 8 */ + 0x20, 0x02, 0x1f, 0xd6 /* br x17. */ +}; + +} // anonymous namespace + +namespace mcld { + +class AArch64GOT; + +class AArch64PLT0 : public PLT::Entry<sizeof(aarch64_plt0)> +{ +public: + AArch64PLT0(SectionData& pParent); +}; + +class AArch64PLT1 : public PLT::Entry<sizeof(aarch64_plt1)> +{ +public: + AArch64PLT1(SectionData& pParent); +}; + +/** \class AArch64PLT + * \brief AArch64 Procedure Linkage Table + */ +class AArch64PLT : public PLT +{ +public: + AArch64PLT(LDSection& pSection, AArch64GOT& pGOTPLT); + ~AArch64PLT(); + + // finalizeSectionSize - set LDSection size + void finalizeSectionSize(); + + // hasPLT1 - return if this plt section has any plt1 entry + bool hasPLT1() const; + + AArch64PLT1* create(); + + AArch64PLT0* getPLT0() const; + + void applyPLT0(); + + void applyPLT1(); + + uint64_t emit(MemoryRegion& pRegion); + +private: + AArch64GOT& m_GOT; +}; + +} // namespace of mcld + +#endif + diff --git a/lib/Target/AArch64/AArch64RelocationFunctions.h b/lib/Target/AArch64/AArch64RelocationFunctions.h new file mode 100644 index 0000000..14c8c73 --- /dev/null +++ b/lib/Target/AArch64/AArch64RelocationFunctions.h @@ -0,0 +1,110 @@ +//===- AArch64RelocationFunction.h ----------------------------------------===// +// +// The MCLinker Project +// +// This file is distributed under the University of Illinois Open Source +// License. See LICENSE.TXT for details. +// +//===----------------------------------------------------------------------===// + +#define DECL_AARCH64_APPLY_RELOC_FUNC(Name) \ +static AArch64Relocator::Result Name (Relocation& pEntry, AArch64Relocator& pParent); + +#define DECL_AARCH64_APPLY_RELOC_FUNCS \ +DECL_AARCH64_APPLY_RELOC_FUNC(none) \ +DECL_AARCH64_APPLY_RELOC_FUNC(abs) \ +DECL_AARCH64_APPLY_RELOC_FUNC(rel) \ +DECL_AARCH64_APPLY_RELOC_FUNC(call) \ +DECL_AARCH64_APPLY_RELOC_FUNC(condbr) \ +DECL_AARCH64_APPLY_RELOC_FUNC(adr_prel_pg_hi21) \ +DECL_AARCH64_APPLY_RELOC_FUNC(add_abs_lo12) \ +DECL_AARCH64_APPLY_RELOC_FUNC(adr_got_page) \ +DECL_AARCH64_APPLY_RELOC_FUNC(ld64_got_lo12) \ +DECL_AARCH64_APPLY_RELOC_FUNC(ldst_abs_lo12) \ +DECL_AARCH64_APPLY_RELOC_FUNC(unsupport) + +#define DECL_AARCH64_APPLY_RELOC_FUNC_PTRS(ValueType, MappedType) \ + ValueType(0x0, MappedType(&none, "R_AARCH64_NULL")), \ + ValueType(0x100, MappedType(&none, "R_AARCH64_NONE")), \ + ValueType(0x101, MappedType(&abs, "R_AARCH64_ABS64", 64)), \ + ValueType(0x102, MappedType(&abs, "R_AARCH64_ABS32", 32)), \ + ValueType(0x103, MappedType(&abs, "R_AARCH64_ABS16", 16)), \ + ValueType(0x104, MappedType(&rel, "R_AARCH64_PREL64", 64)), \ + ValueType(0x105, MappedType(&rel, "R_AARCH64_PREL32", 32)), \ + ValueType(0x106, MappedType(&rel, "R_AARCH64_PREL16", 16)), \ + ValueType(0x107, MappedType(&unsupport, "R_AARCH64_MOVW_UABS_G0")), \ + ValueType(0x108, MappedType(&unsupport, "R_AARCH64_MOVW_UABS_G0_NC")), \ + ValueType(0x109, MappedType(&unsupport, "R_AARCH64_MOVW_UABS_G1")), \ + ValueType(0x10a, MappedType(&unsupport, "R_AARCH64_MOVW_UABS_G1_NC")), \ + ValueType(0x10b, MappedType(&unsupport, "R_AARCH64_MOVW_UABS_G2")), \ + ValueType(0x10c, MappedType(&unsupport, "R_AARCH64_MOVW_UABS_G2_NC")), \ + ValueType(0x10d, MappedType(&unsupport, "R_AARCH64_MOVW_UABS_G3")), \ + ValueType(0x10e, MappedType(&unsupport, "R_AARCH64_MOVW_SABS_G0")), \ + ValueType(0x10f, MappedType(&unsupport, "R_AARCH64_MOVW_SABS_G1")), \ + ValueType(0x110, MappedType(&unsupport, "R_AARCH64_MOVW_SABS_G2")), \ + ValueType(0x111, MappedType(&unsupport, "R_AARCH64_LD_PREL_LO19")), \ + ValueType(0x112, MappedType(&unsupport, "R_AARCH64_ADR_PREL_LO21")), \ + ValueType(0x113, MappedType(&adr_prel_pg_hi21, "R_AARCH64_ADR_PREL_PG_HI21", 32)), \ + ValueType(0x114, MappedType(&adr_prel_pg_hi21, "R_AARCH64_ADR_PREL_PG_HI21_NC", 32)), \ + ValueType(0x115, MappedType(&add_abs_lo12, "R_AARCH64_ADD_ABS_LO12_NC", 32)), \ + ValueType(0x116, MappedType(&ldst_abs_lo12, "R_AARCH64_LDST8_ABS_LO12_NC", 32)), \ + ValueType(0x117, MappedType(&unsupport, "R_AARCH64_TSTBR14")), \ + ValueType(0x118, MappedType(&condbr, "R_AARCH64_CONDBR19", 32)), \ + ValueType(0x11a, MappedType(&call, "R_AARCH64_JUMP26", 32)), \ + ValueType(0x11b, MappedType(&call, "R_AARCH64_CALL26", 32)), \ + ValueType(0x11c, MappedType(&ldst_abs_lo12, "R_AARCH64_LDST16_ABS_LO12_NC", 32)), \ + ValueType(0x11d, MappedType(&ldst_abs_lo12, "R_AARCH64_LDST32_ABS_LO12_NC", 32)), \ + ValueType(0x11e, MappedType(&ldst_abs_lo12, "R_AARCH64_LDST64_ABS_LO12_NC", 32)), \ + ValueType(0x12b, MappedType(&ldst_abs_lo12, "R_AARCH64_LDST128_ABS_LO12_NC", 32)), \ + ValueType(0x137, MappedType(&adr_got_page, "R_AARCH64_ADR_GOT_PAGE", 32)), \ + ValueType(0x138, MappedType(&ld64_got_lo12, "R_AARCH64_LD64_GOT_LO12_NC", 32)), \ + ValueType(0x20b, MappedType(&unsupport, "R_AARCH64_TLSLD_MOVW_DTPREL_G2")), \ + ValueType(0x20c, MappedType(&unsupport, "R_AARCH64_TLSLD_MOVW_DTPREL_G1")), \ + ValueType(0x20d, MappedType(&unsupport, "R_AARCH64_TLSLD_MOVW_DTPREL_G1_NC")), \ + ValueType(0x20e, MappedType(&unsupport, "R_AARCH64_TLSLD_MOVW_DTPREL_G0")), \ + ValueType(0x20f, MappedType(&unsupport, "R_AARCH64_TLSLD_MOVW_DTPREL_G0_NC")), \ + ValueType(0x210, MappedType(&unsupport, "R_AARCH64_TLSLD_ADD_DTPREL_HI12")), \ + ValueType(0x211, MappedType(&unsupport, "R_AARCH64_TLSLD_ADD_DTPREL_LO12")), \ + ValueType(0x212, MappedType(&unsupport, "R_AARCH64_TLSLD_ADD_DTPREL_LO12_NC")), \ + ValueType(0x213, MappedType(&unsupport, "R_AARCH64_TLSLD_LDST8_DTPREL_LO12")), \ + ValueType(0x214, MappedType(&unsupport, "R_AARCH64_TLSLD_LDST8_DTPREL_LO12_NC")), \ + ValueType(0x215, MappedType(&unsupport, "R_AARCH64_TLSLD_LDST16_DTPREL_LO12")), \ + ValueType(0x216, MappedType(&unsupport, "R_AARCH64_TLSLD_LDST16_DTPREL_LO12_NC")), \ + ValueType(0x217, MappedType(&unsupport, "R_AARCH64_TLSLD_LDST32_DTPREL_LO12")), \ + ValueType(0x218, MappedType(&unsupport, "R_AARCH64_TLSLD_LDST32_DTPREL_LO12_NC")), \ + ValueType(0x219, MappedType(&unsupport, "R_AARCH64_TLSLD_LDST64_DTPREL_LO12")), \ + ValueType(0x21a, MappedType(&unsupport, "R_AARCH64_TLSLD_LDST64_DTPREL_LO12_NC")), \ + ValueType(0x21b, MappedType(&unsupport, "R_AARCH64_TLSIE_MOVW_GOTTPREL_G1")), \ + ValueType(0x21c, MappedType(&unsupport, "R_AARCH64_TLSIE_MOVW_GOTTPREL_G0_NC")), \ + ValueType(0x21d, MappedType(&unsupport, "R_AARCH64_TLSIE_ADR_GOTTPREL_PAGE21")), \ + ValueType(0x21e, MappedType(&unsupport, "R_AARCH64_TLSIE_LD64_GOTTPREL_LO12_NC")), \ + ValueType(0x21f, MappedType(&unsupport, "R_AARCH64_TLSIE_LD_GOTTPREL_PREL19")), \ + ValueType(0x220, MappedType(&unsupport, "R_AARCH64_TLSLE_MOVW_TPREL_G2")), \ + ValueType(0x221, MappedType(&unsupport, "R_AARCH64_TLSLE_MOVW_TPREL_G1")), \ + ValueType(0x222, MappedType(&unsupport, "R_AARCH64_TLSLE_MOVW_TPREL_G1_NC")), \ + ValueType(0x223, MappedType(&unsupport, "R_AARCH64_TLSLE_MOVW_TPREL_G0")), \ + ValueType(0x224, MappedType(&unsupport, "R_AARCH64_TLSLE_MOVW_TPREL_G0_NC")), \ + ValueType(0x225, MappedType(&unsupport, "R_AARCH64_TLSLE_ADD_TPREL_HI12")), \ + ValueType(0x226, MappedType(&unsupport, "R_AARCH64_TLSLE_ADD_TPREL_LO12")), \ + ValueType(0x227, MappedType(&unsupport, "R_AARCH64_TLSLE_ADD_TPREL_LO12_NC")), \ + ValueType(0x228, MappedType(&unsupport, "R_AARCH64_TLSLE_LDST8_TPREL_LO12")), \ + ValueType(0x229, MappedType(&unsupport, "R_AARCH64_TLSLE_LDST8_TPREL_LO12_NC")), \ + ValueType(0x22a, MappedType(&unsupport, "R_AARCH64_TLSLE_LDST16_TPREL_LO12")), \ + ValueType(0x22b, MappedType(&unsupport, "R_AARCH64_TLSLE_LDST16_TPREL_LO12_NC")), \ + ValueType(0x22c, MappedType(&unsupport, "R_AARCH64_TLSLE_LDST32_TPREL_LO12")), \ + ValueType(0x22d, MappedType(&unsupport, "R_AARCH64_TLSLE_LDST32_TPREL_LO12_NC")), \ + ValueType(0x22e, MappedType(&unsupport, "R_AARCH64_TLSLE_LDST64_TPREL_LO12")), \ + ValueType(0x22f, MappedType(&unsupport, "R_AARCH64_TLSLE_LDST64_TPREL_LO12_NC")), \ + ValueType(0x232, MappedType(&unsupport, "R_AARCH64_TLSDESC_ADR_PAGE")), \ + ValueType(0x233, MappedType(&unsupport, "R_AARCH64_TLSDESC_LD64_LO12_NC")), \ + ValueType(0x234, MappedType(&unsupport, "R_AARCH64_TLSDESC_ADD_LO12_NC")), \ + ValueType(0x239, MappedType(&unsupport, "R_AARCH64_TLSDESC_CALL")), \ + ValueType( 1024, MappedType(&unsupport, "R_AARCH64_COPY")), \ + ValueType( 1025, MappedType(&unsupport, "R_AARCH64_GLOB_DAT")), \ + ValueType( 1026, MappedType(&unsupport, "R_AARCH64_JUMP_SLOT")), \ + ValueType( 1027, MappedType(&unsupport, "R_AARCH64_RELATIVE")), \ + ValueType( 1028, MappedType(&unsupport, "R_AARCH64_TLS_DTPREL64")), \ + ValueType( 1029, MappedType(&unsupport, "R_AARCH64_TLS_DTPMOD64")), \ + ValueType( 1030, MappedType(&unsupport, "R_AARCH64_TLS_TPREL64")), \ + ValueType( 1031, MappedType(&unsupport, "R_AARCH64_TLSDESC")), \ + ValueType( 1032, MappedType(&unsupport, "R_AARCH64_IRELATIVE")) diff --git a/lib/Target/AArch64/AArch64RelocationHelpers.h b/lib/Target/AArch64/AArch64RelocationHelpers.h new file mode 100644 index 0000000..beb6be8 --- /dev/null +++ b/lib/Target/AArch64/AArch64RelocationHelpers.h @@ -0,0 +1,212 @@ +//===- AArch64RelocationHelpers.h -----------------------------------------===// +// +// The MCLinker Project +// +// This file is distributed under the University of Illinois Open Source +// License. See LICENSE.TXT for details. +// +//===----------------------------------------------------------------------===// +#ifndef TARGET_AARCH64_AARCH64RELOCATIONHELPERS_H +#define TARGET_AARCH64_AARCH64RELOCATIONHELPERS_H + +#include "AArch64Relocator.h" +#include <llvm/Support/Host.h> + +namespace mcld { +//===----------------------------------------------------------------------===// +// Relocation helper functions +//===----------------------------------------------------------------------===// +// Return true if overflow +static inline bool +helper_check_signed_overflow(Relocator::DWord pValue, unsigned bits) +{ + if (bits >= sizeof(int64_t) * 8) + return false; + int64_t signed_val = static_cast<int64_t>(pValue); + int64_t max = (1 << (bits - 1)) - 1; + int64_t min = -(1 << (bits - 1)); + if (signed_val > max || signed_val < min) + return true; + return false; +} + +static inline Relocator::Address +helper_get_page_address(Relocator::Address pValue) +{ + return (pValue & ~ (Relocator::Address) 0xFFF); +} + +static inline Relocator::Address +helper_get_page_offset(Relocator::Address pValue) +{ + return (pValue & (Relocator::Address) 0xFFF); +} + +static inline uint32_t get_mask(uint32_t pValue) +{ + return ((1u << (pValue)) - 1); +} + +static inline uint32_t +helper_reencode_adr_imm(uint32_t pInst, uint32_t pImm) +{ + return (pInst & ~((get_mask(2) << 29) | (get_mask(19) << 5))) + | ((pImm & get_mask(2)) << 29) | ((pImm & (get_mask(19) << 2)) << 3); +} + +// Reencode the imm field of add immediate. +static inline uint32_t helper_reencode_add_imm(uint32_t pInst, uint32_t pImm) +{ + return (pInst & ~(get_mask(12) << 10)) | ((pImm & get_mask(12)) << 10); +} + +// Encode the 26-bit offset of unconditional branch. +static inline uint32_t +helper_reencode_branch_offset_26(uint32_t pInst, uint32_t pOff) +{ + return (pInst & ~get_mask(26)) | (pOff & get_mask(26)); +} + +// Encode the 19-bit offset of conditional branch and compare & branch. +static inline uint32_t +helper_reencode_cond_branch_ofs_19(uint32_t pInst, uint32_t pOff) +{ + return (pInst & ~(get_mask(19) << 5)) | ((pOff & get_mask(19)) << 5); +} + +// Reencode the imm field of ld/st pos immediate. +static inline uint32_t +helper_reencode_ldst_pos_imm (uint32_t pInst, uint32_t pImm) +{ + return (pInst & ~(get_mask(12) << 10)) | ((pImm & get_mask(12)) << 10); +} + +static inline uint32_t helper_get_upper32(Relocator::DWord pData) +{ + if (llvm::sys::IsLittleEndianHost) + return pData >> 32; + return pData & 0xFFFFFFFF; +} + +static inline void helper_put_upper32(uint32_t pData, Relocator::DWord& pDes) +{ + *(reinterpret_cast<uint32_t*>(&pDes)) = pData; +} + +static inline Relocator::Address +helper_get_PLT_address(ResolveInfo& pSym, AArch64Relocator& pParent) +{ + PLTEntryBase* plt_entry = pParent.getSymPLTMap().lookUp(pSym); + assert(NULL != plt_entry); + return pParent.getTarget().getPLT().addr() + plt_entry->getOffset(); +} + +static inline AArch64PLT1& +helper_PLT_init(Relocation& pReloc, AArch64Relocator& pParent) +{ + // rsym - The relocation target symbol + ResolveInfo* rsym = pReloc.symInfo(); + AArch64GNULDBackend& ld_backend = pParent.getTarget(); + assert(NULL == pParent.getSymPLTMap().lookUp(*rsym)); + + AArch64PLT1* plt_entry = ld_backend.getPLT().create(); + pParent.getSymPLTMap().record(*rsym, *plt_entry); + + // initialize plt and the corresponding gotplt and dyn rel entry. + assert(NULL == pParent.getSymGOTPLTMap().lookUp(*rsym) && + "PLT entry not exist, but DynRel entry exist!"); + AArch64GOTEntry* gotplt_entry = ld_backend.getGOTPLT().createGOTPLT(); + pParent.getSymGOTPLTMap().record(*rsym, *gotplt_entry); + + // init the corresponding rel entry in .rela.plt + Relocation& rel_entry = *ld_backend.getRelaPLT().create(); + rel_entry.setType(R_AARCH64_JUMP_SLOT); + rel_entry.targetRef().assign(*gotplt_entry); + rel_entry.setSymInfo(rsym); + return *plt_entry; +} + +/// helper_DynRel - Get an relocation entry in .rela.dyn +static inline Relocation& +helper_DynRela_init(ResolveInfo* pSym, + Fragment& pFrag, + uint64_t pOffset, + Relocator::Type pType, + AArch64Relocator& pParent) +{ + AArch64GNULDBackend& ld_backend = pParent.getTarget(); + Relocation& rel_entry = *ld_backend.getRelaDyn().create(); + rel_entry.setType(pType); + rel_entry.targetRef().assign(pFrag, pOffset); + if (pType == R_AARCH64_RELATIVE || NULL == pSym) + rel_entry.setSymInfo(NULL); + else + rel_entry.setSymInfo(pSym); + + return rel_entry; +} + +/// helper_use_relative_reloc - Check if symbol can use relocation +/// R_AARCH64_RELATIVE +static inline bool +helper_use_relative_reloc(const ResolveInfo& pSym, + const AArch64Relocator& pParent) + +{ + // if symbol is dynamic or undefine or preemptible + if (pSym.isDyn() || + pSym.isUndef() || + pParent.getTarget().isSymbolPreemptible(pSym)) + return false; + return true; +} + +static inline Relocator::Address +helper_get_GOT_address(ResolveInfo& pSym, AArch64Relocator& pParent) +{ + AArch64GOTEntry* got_entry = pParent.getSymGOTMap().lookUp(pSym); + assert(NULL != got_entry); + return pParent.getTarget().getGOT().addr() + got_entry->getOffset(); +} + +static inline Relocator::Address +helper_GOT_ORG(AArch64Relocator& pParent) +{ + return pParent.getTarget().getGOT().addr(); +} + +static inline AArch64GOTEntry& +helper_GOT_init(Relocation& pReloc, bool pHasRel, AArch64Relocator& pParent) +{ + // rsym - The relocation target symbol + ResolveInfo* rsym = pReloc.symInfo(); + AArch64GNULDBackend& ld_backend = pParent.getTarget(); + assert(NULL == pParent.getSymGOTMap().lookUp(*rsym)); + + AArch64GOTEntry* got_entry = ld_backend.getGOT().createGOT(); + pParent.getSymGOTMap().record(*rsym, *got_entry); + + // If we first get this GOT entry, we should initialize it. + if (!pHasRel) { + // No corresponding dynamic relocation, initialize to the symbol value. + got_entry->setValue(AArch64Relocator::SymVal); + } + else { + // Initialize got_entry content and the corresponding dynamic relocation. + if (helper_use_relative_reloc(*rsym, pParent)) { + got_entry->setValue(AArch64Relocator::SymVal); + Relocation& rel_entry = helper_DynRela_init(rsym, *got_entry, 0x0, + R_AARCH64_RELATIVE, pParent); + rel_entry.setAddend(AArch64Relocator::SymVal); + pParent.getRelRelMap().record(pReloc, rel_entry); + } + else { + helper_DynRela_init(rsym, *got_entry, 0x0, R_AARCH64_GLOB_DAT, pParent); + got_entry->setValue(0); + } + } + return *got_entry; +} + +} +#endif diff --git a/lib/Target/AArch64/AArch64Relocator.cpp b/lib/Target/AArch64/AArch64Relocator.cpp new file mode 100644 index 0000000..db99762 --- /dev/null +++ b/lib/Target/AArch64/AArch64Relocator.cpp @@ -0,0 +1,694 @@ +//===- AArch64Relocator.cpp ----------------------------------------------===// +// +// The MCLinker Project +// +// This file is distributed under the University of Illinois Open Source +// License. See LICENSE.TXT for details. +// +//===----------------------------------------------------------------------===// + +#include <mcld/LinkerConfig.h> +#include <mcld/IRBuilder.h> +#include <mcld/Support/MsgHandling.h> +#include <mcld/LD/LDSymbol.h> +#include <mcld/LD/ELFFileFormat.h> +#include <mcld/Object/ObjectBuilder.h> + +#include <llvm/ADT/Twine.h> +#include <llvm/Support/DataTypes.h> +#include <llvm/Support/ELF.h> +#include <llvm/Support/Host.h> + +#include "AArch64Relocator.h" +#include "AArch64RelocationFunctions.h" +#include "AArch64RelocationHelpers.h" + +using namespace mcld; + +//===----------------------------------------------------------------------===// +// Relocation Functions and Tables +//===----------------------------------------------------------------------===// +DECL_AARCH64_APPLY_RELOC_FUNCS + +/// the prototype of applying function +typedef Relocator::Result (*ApplyFunctionType)(Relocation& pReloc, + AArch64Relocator& pParent); + +// the table entry of applying functions +class ApplyFunctionEntry { +public: + ApplyFunctionEntry() {} + ApplyFunctionEntry(ApplyFunctionType pFunc, + const char* pName, + size_t pSize = 0) + : func(pFunc), name(pName), size(pSize) { } + ApplyFunctionType func; + const char* name; + size_t size; +}; +typedef std::map<Relocator::Type, ApplyFunctionEntry> ApplyFunctionMap; + +static const ApplyFunctionMap::value_type ApplyFunctionList[] = { + DECL_AARCH64_APPLY_RELOC_FUNC_PTRS(ApplyFunctionMap::value_type, + ApplyFunctionEntry) +}; + +// declare the table of applying functions +static ApplyFunctionMap ApplyFunctions(ApplyFunctionList, + ApplyFunctionList + sizeof(ApplyFunctionList)/sizeof(ApplyFunctionList[0])); + +//===----------------------------------------------------------------------===// +// AArch64Relocator +//===----------------------------------------------------------------------===// +AArch64Relocator::AArch64Relocator(AArch64GNULDBackend& pParent, + const LinkerConfig& pConfig) + : Relocator(pConfig), + m_Target(pParent) { +} + +AArch64Relocator::~AArch64Relocator() +{ +} + +Relocator::Result AArch64Relocator::applyRelocation(Relocation& pRelocation) +{ + Relocation::Type type = pRelocation.type(); + // valid types are 0x0, 0x100-0x239 + if ((type < 0x100 || type > 0x239) && (type != 0x0)) { + return Relocator::Unknown; + } + assert(ApplyFunctions.find(type) != ApplyFunctions.end()); + return ApplyFunctions[type].func(pRelocation, *this); +} + +const char* AArch64Relocator::getName(Relocator::Type pType) const +{ + assert(ApplyFunctions.find(pType) != ApplyFunctions.end()); + return ApplyFunctions[pType].name; +} + +Relocator::Size AArch64Relocator::getSize(Relocation::Type pType) const +{ + return ApplyFunctions[pType].size; +} + +void AArch64Relocator::addCopyReloc(ResolveInfo& pSym) +{ + Relocation& rel_entry = *getTarget().getRelaDyn().create(); + rel_entry.setType(R_AARCH64_COPY); + assert(pSym.outSymbol()->hasFragRef()); + rel_entry.targetRef().assign(*pSym.outSymbol()->fragRef()); + rel_entry.setSymInfo(&pSym); +} + +/// defineSymbolForCopyReloc +/// For a symbol needing copy relocation, define a copy symbol in the BSS +/// section and all other reference to this symbol should refer to this +/// copy. +/// This is executed at scan relocation stage. +LDSymbol& AArch64Relocator::defineSymbolforCopyReloc(IRBuilder& pBuilder, + const ResolveInfo& pSym) +{ + // get or create corresponding BSS LDSection + LDSection* bss_sect_hdr = NULL; + ELFFileFormat* file_format = getTarget().getOutputFormat(); + if (ResolveInfo::ThreadLocal == pSym.type()) + bss_sect_hdr = &file_format->getTBSS(); + else + bss_sect_hdr = &file_format->getBSS(); + + // get or create corresponding BSS SectionData + SectionData* bss_data = NULL; + if (bss_sect_hdr->hasSectionData()) + bss_data = bss_sect_hdr->getSectionData(); + else + bss_data = IRBuilder::CreateSectionData(*bss_sect_hdr); + + // Determine the alignment by the symbol value + // FIXME: here we use the largest alignment + uint32_t addralign = config().targets().bitclass() / 8; + + // allocate space in BSS for the copy symbol + Fragment* frag = new FillFragment(0x0, 1, pSym.size()); + uint64_t size = ObjectBuilder::AppendFragment(*frag, *bss_data, addralign); + bss_sect_hdr->setSize(bss_sect_hdr->size() + size); + + // change symbol binding to Global if it's a weak symbol + ResolveInfo::Binding binding = (ResolveInfo::Binding)pSym.binding(); + if (binding == ResolveInfo::Weak) + binding = ResolveInfo::Global; + + // Define the copy symbol in the bss section and resolve it + LDSymbol* cpy_sym = pBuilder.AddSymbol<IRBuilder::Force, IRBuilder::Resolve>( + pSym.name(), + (ResolveInfo::Type)pSym.type(), + ResolveInfo::Define, + binding, + pSym.size(), // size + 0x0, // value + FragmentRef::Create(*frag, 0x0), + (ResolveInfo::Visibility)pSym.other()); + + return *cpy_sym; +} + +void +AArch64Relocator::scanLocalReloc(Relocation& pReloc, const LDSection& pSection) +{ + // rsym - The relocation target symbol + ResolveInfo* rsym = pReloc.symInfo(); + switch(pReloc.type()) { + case llvm::ELF::R_AARCH64_ABS64: + // If buiding PIC object (shared library or PIC executable), + // a dynamic relocations with RELATIVE type to this location is needed. + // Reserve an entry in .rel.dyn + if (config().isCodeIndep()) { + // set Rel bit + rsym->setReserved(rsym->reserved() | ReserveRel); + getTarget().checkAndSetHasTextRel(*pSection.getLink()); + // set up the dyn rel directly + Relocation& reloc = helper_DynRela_init(rsym, + *pReloc.targetRef().frag(), + pReloc.targetRef().offset(), + R_AARCH64_RELATIVE, + *this); + getRelRelMap().record(pReloc, reloc); + } + return; + + case llvm::ELF::R_AARCH64_ABS32: + case llvm::ELF::R_AARCH64_ABS16: + // If buiding PIC object (shared library or PIC executable), + // a dynamic relocations with RELATIVE type to this location is needed. + // Reserve an entry in .rel.dyn + if (config().isCodeIndep()) { + // set up the dyn rel directly + Relocation& reloc = helper_DynRela_init(rsym, + *pReloc.targetRef().frag(), + pReloc.targetRef().offset(), pReloc.type(), *this); + getRelRelMap().record(pReloc, reloc); + // set Rel bit + rsym->setReserved(rsym->reserved() | ReserveRel); + getTarget().checkAndSetHasTextRel(*pSection.getLink()); + } + return; + + case llvm::ELF::R_AARCH64_ADR_GOT_PAGE: + case llvm::ELF::R_AARCH64_LD64_GOT_LO12_NC: { + // Symbol needs GOT entry, reserve entry in .got + // return if we already create GOT for this symbol + if (rsym->reserved() & ReserveGOT) + return; + // If building PIC object, a dynamic relocation with + // type RELATIVE is needed to relocate this GOT entry. + if (config().isCodeIndep()) + helper_GOT_init(pReloc, true, *this); + else + helper_GOT_init(pReloc, false, *this); + // set GOT bit + rsym->setReserved(rsym->reserved() | ReserveGOT); + return; + } + + default: + break; + } +} + +void AArch64Relocator::scanGlobalReloc(Relocation& pReloc, + IRBuilder& pBuilder, + const LDSection& pSection) +{ + // rsym - The relocation target symbol + ResolveInfo* rsym = pReloc.symInfo(); + switch(pReloc.type()) { + case llvm::ELF::R_AARCH64_ABS64: + case llvm::ELF::R_AARCH64_ABS32: + case llvm::ELF::R_AARCH64_ABS16: + // Absolute relocation type, symbol may needs PLT entry or + // dynamic relocation entry + if (getTarget().symbolNeedsPLT(*rsym)) { + // create plt for this symbol if it does not have one + if (!(rsym->reserved() & ReservePLT)){ + // Symbol needs PLT entry, we need a PLT entry + // and the corresponding GOT and dynamic relocation entry + // in .got and .rel.plt. + helper_PLT_init(pReloc, *this); + // set PLT bit + rsym->setReserved(rsym->reserved() | ReservePLT); + } + } + + if (getTarget().symbolNeedsDynRel(*rsym, (rsym->reserved() & ReservePLT), + true)) { + // symbol needs dynamic relocation entry, set up the dynrel entry + if (getTarget().symbolNeedsCopyReloc(pReloc, *rsym)) { + LDSymbol& cpy_sym = defineSymbolforCopyReloc(pBuilder, *rsym); + addCopyReloc(*cpy_sym.resolveInfo()); + } + else { + // set Rel bit and the dyn rel + rsym->setReserved(rsym->reserved() | ReserveRel); + getTarget().checkAndSetHasTextRel(*pSection.getLink()); + if (llvm::ELF::R_AARCH64_ABS64 == pReloc.type() && + helper_use_relative_reloc(*rsym, *this)) { + Relocation& reloc = helper_DynRela_init(rsym, + *pReloc.targetRef().frag(), + pReloc.targetRef().offset(), + R_AARCH64_RELATIVE, + *this); + getRelRelMap().record(pReloc, reloc); + } + else { + Relocation& reloc = helper_DynRela_init(rsym, + *pReloc.targetRef().frag(), + pReloc.targetRef().offset(), + pReloc.type(), + *this); + getRelRelMap().record(pReloc, reloc); + } + } + } + return; + + case llvm::ELF::R_AARCH64_PREL64: + case llvm::ELF::R_AARCH64_PREL32: + case llvm::ELF::R_AARCH64_PREL16: + if (getTarget().symbolNeedsPLT(*rsym) && + LinkerConfig::DynObj != config().codeGenType()) { + // create plt for this symbol if it does not have one + if (!(rsym->reserved() & ReservePLT)){ + // Symbol needs PLT entry, we need a PLT entry + // and the corresponding GOT and dynamic relocation entry + // in .got and .rel.plt. + helper_PLT_init(pReloc, *this); + // set PLT bit + rsym->setReserved(rsym->reserved() | ReservePLT); + } + } + + // Only PC relative relocation against dynamic symbol needs a + // dynamic relocation. Only dynamic copy relocation is allowed + // and PC relative relocation will be resolved to the local copy. + // All other dynamic relocations may lead to run-time relocation + // overflow. + if (getTarget().isDynamicSymbol(*rsym) && + getTarget().symbolNeedsDynRel(*rsym, + (rsym->reserved() & ReservePLT), + false) && + getTarget().symbolNeedsCopyReloc(pReloc, *rsym)) { + LDSymbol& cpy_sym = defineSymbolforCopyReloc(pBuilder, *rsym); + addCopyReloc(*cpy_sym.resolveInfo()); + } + return; + + case llvm::ELF::R_AARCH64_CONDBR19: + case llvm::ELF::R_AARCH64_JUMP26: + case llvm::ELF::R_AARCH64_CALL26: { + // return if we already create plt for this symbol + if (rsym->reserved() & ReservePLT) + return; + + // if the symbol's value can be decided at link time, then no need plt + if (getTarget().symbolFinalValueIsKnown(*rsym)) + return; + + // if symbol is defined in the ouput file and it's not + // preemptible, no need plt + if (rsym->isDefine() && !rsym->isDyn() && + !getTarget().isSymbolPreemptible(*rsym)) { + return; + } + + // Symbol needs PLT entry, we need to reserve a PLT entry + // and the corresponding GOT and dynamic relocation entry + // in .got and .rel.plt. + helper_PLT_init(pReloc, *this); + // set PLT bit + rsym->setReserved(rsym->reserved() | ReservePLT); + return; + } + + case llvm::ELF::R_AARCH64_ADR_PREL_PG_HI21: + case R_AARCH64_ADR_PREL_PG_HI21_NC: + if (getTarget().symbolNeedsDynRel(*rsym, + (rsym->reserved() & ReservePLT), + false)) { + if (getTarget().symbolNeedsCopyReloc(pReloc, *rsym)) { + LDSymbol& cpy_sym = defineSymbolforCopyReloc(pBuilder, *rsym); + addCopyReloc(*cpy_sym.resolveInfo()); + } + } + if (getTarget().symbolNeedsPLT(*rsym)) { + // create plt for this symbol if it does not have one + if (!(rsym->reserved() & ReservePLT)){ + // Symbol needs PLT entry, we need a PLT entry + // and the corresponding GOT and dynamic relocation entry + // in .got and .rel.plt. + helper_PLT_init(pReloc, *this); + // set PLT bit + rsym->setReserved(rsym->reserved() | ReservePLT); + } + } + return; + + case llvm::ELF::R_AARCH64_ADR_GOT_PAGE: + case llvm::ELF::R_AARCH64_LD64_GOT_LO12_NC: { + // Symbol needs GOT entry, reserve entry in .got + // return if we already create GOT for this symbol + if (rsym->reserved() & ReserveGOT) + return; + // if the symbol cannot be fully resolved at link time, then we need a + // dynamic relocation + if (!getTarget().symbolFinalValueIsKnown(*rsym)) + helper_GOT_init(pReloc, true, *this); + else + helper_GOT_init(pReloc, false, *this); + // set GOT bit + rsym->setReserved(rsym->reserved() | ReserveGOT); + return; + } + + default: + break; + } +} + +void AArch64Relocator::scanRelocation(Relocation& pReloc, + IRBuilder& pBuilder, + Module& pModule, + LDSection& pSection, + Input& pInput) +{ + ResolveInfo* rsym = pReloc.symInfo(); + assert(NULL != rsym && + "ResolveInfo of relocation not set while scanRelocation"); + + assert(NULL != pSection.getLink()); + if (0 == (pSection.getLink()->flag() & llvm::ELF::SHF_ALLOC)) + return; + + // Scan relocation type to determine if an GOT/PLT/Dynamic Relocation + // entries should be created. + // FIXME: Below judgements concern nothing about TLS related relocation + + // rsym is local + if (rsym->isLocal()) + scanLocalReloc(pReloc, pSection); + // rsym is external + else + scanGlobalReloc(pReloc, pBuilder, pSection); + + // check if we shoule issue undefined reference for the relocation target + // symbol + if (rsym->isUndef() && !rsym->isDyn() && !rsym->isWeak() && !rsym->isNull()) + issueUndefRef(pReloc, pSection, pInput); +} + +//===----------------------------------------------------------------------===// +// Each relocation function implementation +//===----------------------------------------------------------------------===// + +// R_AARCH64_NONE +Relocator::Result none(Relocation& pReloc, AArch64Relocator& pParent) +{ + return Relocator::OK; +} + +Relocator::Result unsupport(Relocation& pReloc, AArch64Relocator& pParent) +{ + return Relocator::Unsupport; +} + +// R_AARCH64_ABS64: S + A +// R_AARCH64_ABS32: S + A +// R_AARCH64_ABS16: S + A +Relocator::Result abs(Relocation& pReloc, AArch64Relocator& pParent) +{ + ResolveInfo* rsym = pReloc.symInfo(); + Relocator::DWord A = pReloc.target() + pReloc.addend(); + Relocator::DWord S = pReloc.symValue(); + Relocation* dyn_rel = pParent.getRelRelMap().lookUp(pReloc); + bool has_dyn_rel = (NULL != dyn_rel); + + LDSection& target_sect = pReloc.targetRef().frag()->getParent()->getSection(); + // 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())) { + pReloc.target() = S + A; + return Relocator::OK; + } + // A local symbol may need RELATIVE Type dynamic relocation + if (rsym->isLocal() && has_dyn_rel) { + dyn_rel->setAddend(S + A); + } + + // An external symbol may need PLT and dynamic relocation + if (!rsym->isLocal()) { + if (rsym->reserved() & AArch64Relocator::ReservePLT) { + S = helper_get_PLT_address(*rsym, pParent); + } + // If we generate a dynamic relocation (except R_AARCH64_64_RELATIVE) + // for a place, we should not perform static relocation on it + // in order to keep the addend store in the place correct. + if (has_dyn_rel) { + if (llvm::ELF::R_AARCH64_ABS64 == pReloc.type() && + R_AARCH64_RELATIVE == dyn_rel->type()) { + dyn_rel->setAddend(S + A); + } + else { + dyn_rel->setAddend(A); + return Relocator::OK; + } + } + } + + // perform static relocation + pReloc.target() = S + A; + return Relocator::OK; +} + +// R_AARCH64_PREL64: S + A - P +// R_AARCH64_PREL32: S + A - P +// R_AARCH64_PREL16: S + A - P +Relocator::Result rel(Relocation& pReloc, AArch64Relocator& pParent) +{ + ResolveInfo* rsym = pReloc.symInfo(); + Relocator::Address S = pReloc.symValue(); + Relocator::DWord A = pReloc.addend(); + Relocator::DWord P = pReloc.place(); + + if (llvm::ELF::R_AARCH64_PREL64 != pReloc.type()) + A += pReloc.target() & get_mask(pParent.getSize(pReloc.type())); + else + A += pReloc.target(); + + LDSection& target_sect = pReloc.targetRef().frag()->getParent()->getSection(); + // 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())) { + // if plt entry exists, the S value is the plt entry address + if (!rsym->isLocal()) { + if (rsym->reserved() & AArch64Relocator::ReservePLT) { + S = helper_get_PLT_address(*rsym, pParent); + } + } + } + + Relocator::DWord X = S + A - P; + pReloc.target() = X; + + if (llvm::ELF::R_AARCH64_PREL64 != pReloc.type() && + helper_check_signed_overflow(X, pParent.getSize(pReloc.type()))) + return Relocator::Overflow; + return Relocator::OK; +} + +// R_AARCH64_ADD_ABS_LO12_NC: S + A +Relocator::Result add_abs_lo12(Relocation& pReloc, AArch64Relocator& pParent) +{ + Relocator::Address value = 0x0; + Relocator::Address S = pReloc.symValue(); + Relocator::DWord A = pReloc.addend(); + + value = helper_get_page_offset(S + A); + pReloc.target() = helper_reencode_add_imm(pReloc.target(), value); + + return Relocator::OK; +} + +// R_AARCH64_ADR_PREL_PG_HI21: ((PG(S + A) - PG(P)) >> 12) +// R_AARCH64_ADR_PREL_PG_HI21_NC: ((PG(S + A) - PG(P)) >> 12) +Relocator::Result +adr_prel_pg_hi21(Relocation& pReloc, AArch64Relocator& pParent) +{ + ResolveInfo* rsym = pReloc.symInfo(); + Relocator::Address S = pReloc.symValue(); + // if plt entry exists, the S value is the plt entry address + if (rsym->reserved() & AArch64Relocator::ReservePLT) { + S = helper_get_PLT_address(*rsym, pParent); + } + Relocator::DWord A = pReloc.addend(); + Relocator::DWord P = pReloc.place() ; + Relocator::DWord X = helper_get_page_address(S + A) - + helper_get_page_address(P); + + pReloc.target() = helper_reencode_adr_imm(pReloc.target(), (X >> 12)); + + return Relocator::OK; +} + +// R_AARCH64_CALL26: S + A - P +// R_AARCH64_JUMP26: S + A - P +Relocator::Result call(Relocation& pReloc, AArch64Relocator& pParent) +{ + // If target is undefined weak symbol, we only need to jump to the + // next instruction unless it has PLT entry. Rewrite instruction + // to NOP. + if (pReloc.symInfo()->isWeak() && + pReloc.symInfo()->isUndef() && + !pReloc.symInfo()->isDyn() && + !(pReloc.symInfo()->reserved() & AArch64Relocator::ReservePLT)) { + // change target to NOP + pReloc.target() = 0xd503201f; + return Relocator::OK; + } + + Relocator::Address S = pReloc.symValue(); + Relocator::DWord A = pReloc.addend(); + Relocator::Address P = pReloc.place(); + + // S depends on PLT exists or not + if (pReloc.symInfo()->reserved() & AArch64Relocator::ReservePLT) + S = helper_get_PLT_address(*pReloc.symInfo(), pParent); + + Relocator::DWord X = S + A - P; + // TODO: check overflow.. + + pReloc.target() = helper_reencode_branch_offset_26(pReloc.target(), X >> 2); + + return Relocator::OK; +} + +// R_AARCH64_CONDBR19: S + A - P +Relocator::Result condbr(Relocation& pReloc, AArch64Relocator& pParent) +{ + // If target is undefined weak symbol, we only need to jump to the + // next instruction unless it has PLT entry. Rewrite instruction + // to NOP. + if (pReloc.symInfo()->isWeak() && + pReloc.symInfo()->isUndef() && + !pReloc.symInfo()->isDyn() && + !(pReloc.symInfo()->reserved() & AArch64Relocator::ReservePLT)) { + // change target to NOP + pReloc.target() = 0xd503201f; + return Relocator::OK; + } + + Relocator::Address S = pReloc.symValue(); + Relocator::DWord A = pReloc.addend(); + Relocator::Address P = pReloc.place(); + + // S depends on PLT exists or not + if (pReloc.symInfo()->reserved() & AArch64Relocator::ReservePLT) + S = helper_get_PLT_address(*pReloc.symInfo(), pParent); + + Relocator::DWord X = S + A - P; + // TODO: check overflow.. + + pReloc.target() = helper_reencode_cond_branch_ofs_19(pReloc.target(), X >> 2); + + return Relocator::OK; +} + +// R_AARCH64_ADR_GOT_PAGE: Page(G(GDAT(S+A))) - Page(P) +Relocator::Result adr_got_page(Relocation& pReloc, AArch64Relocator& pParent) +{ + if (!(pReloc.symInfo()->reserved() & AArch64Relocator::ReserveGOT)) { + return Relocator::BadReloc; + } + + Relocator::Address GOT_S = helper_get_GOT_address(*pReloc.symInfo(), pParent); + Relocator::DWord A = pReloc.addend(); + Relocator::Address P = pReloc.place(); + Relocator::DWord X = helper_get_page_address(GOT_S + A) - + helper_get_page_address(P); + + pReloc.target() = helper_reencode_adr_imm(pReloc.target(), (X >> 12)); + + // setup got entry value if needed + AArch64GOTEntry* got_entry = pParent.getSymGOTMap().lookUp(*pReloc.symInfo()); + if (NULL != got_entry && AArch64Relocator::SymVal == got_entry->getValue()) + got_entry->setValue(pReloc.symValue()); + // setup relocation addend if needed + Relocation* dyn_rela = pParent.getRelRelMap().lookUp(pReloc); + if ((NULL != dyn_rela) && (AArch64Relocator::SymVal == dyn_rela->addend())) { + dyn_rela->setAddend(pReloc.symValue()); + } + return Relocator::OK; +} + +// R_AARCH64_LD64_GOT_LO12_NC: G(GDAT(S+A)) +Relocator::Result ld64_got_lo12(Relocation& pReloc, AArch64Relocator& pParent) +{ + if (!(pReloc.symInfo()->reserved() & AArch64Relocator::ReserveGOT)) { + return Relocator::BadReloc; + } + + Relocator::Address GOT_S = helper_get_GOT_address(*pReloc.symInfo(), pParent); + Relocator::DWord A = pReloc.addend(); + Relocator::DWord X = helper_get_page_offset(GOT_S + A); + + pReloc.target() = helper_reencode_ldst_pos_imm(pReloc.target(), (X >> 3)); + + // setup got entry value if needed + AArch64GOTEntry* got_entry = pParent.getSymGOTMap().lookUp(*pReloc.symInfo()); + if (NULL != got_entry && AArch64Relocator::SymVal == got_entry->getValue()) + got_entry->setValue(pReloc.symValue()); + + // setup relocation addend if needed + Relocation* dyn_rela = pParent.getRelRelMap().lookUp(pReloc); + if ((NULL != dyn_rela) && (AArch64Relocator::SymVal == dyn_rela->addend())) { + dyn_rela->setAddend(pReloc.symValue()); + } + + return Relocator::OK; +} + +// R_AARCH64_LDST8_ABS_LO12_NC: S + A +// R_AARCH64_LDST16_ABS_LO12_NC: S + A +// R_AARCH64_LDST32_ABS_LO12_NC: S + A +// R_AARCH64_LDST64_ABS_LO12_NC: S + A +// R_AARCH64_LDST128_ABS_LO12_NC: S + A +Relocator::Result ldst_abs_lo12(Relocation& pReloc, AArch64Relocator& pParent) +{ + Relocator::Address S = pReloc.symValue(); + Relocator::DWord A = pReloc.addend(); + Relocator::DWord X = helper_get_page_offset(S + A); + + switch(pReloc.type()) { + case llvm::ELF::R_AARCH64_LDST8_ABS_LO12_NC: + pReloc.target() = helper_reencode_ldst_pos_imm(pReloc.target(), X); + break; + case llvm::ELF::R_AARCH64_LDST16_ABS_LO12_NC: + pReloc.target() = helper_reencode_ldst_pos_imm(pReloc.target(), + (X >> 1)); + break; + case llvm::ELF::R_AARCH64_LDST32_ABS_LO12_NC: + pReloc.target() = helper_reencode_ldst_pos_imm(pReloc.target(), + (X >> 2)); + break; + case llvm::ELF::R_AARCH64_LDST64_ABS_LO12_NC: + pReloc.target() = helper_reencode_ldst_pos_imm(pReloc.target(), + (X >> 3)); + break; + case llvm::ELF::R_AARCH64_LDST128_ABS_LO12_NC: + pReloc.target() = helper_reencode_ldst_pos_imm(pReloc.target(), + (X >> 4)); + break; + default: + break; + } + return Relocator::OK; +} + diff --git a/lib/Target/AArch64/AArch64Relocator.h b/lib/Target/AArch64/AArch64Relocator.h new file mode 100644 index 0000000..d49f85f --- /dev/null +++ b/lib/Target/AArch64/AArch64Relocator.h @@ -0,0 +1,151 @@ +//===- AArch64Relocator.h ------------------------------------------------===// +// +// The MCLinker Project +// +// This file is distributed under the University of Illinois Open Source +// License. See LICENSE.TXT for details. +// +//===----------------------------------------------------------------------===// +#ifndef TARGET_AARCH64_AARCH64RELOCATOR_H +#define TARGET_AARCH64_AARCH64RELOCATOR_H +#ifdef ENABLE_UNITTEST +#include <gtest.h> +#endif + +#include <mcld/LD/Relocator.h> +#include <mcld/Target/GOT.h> +#include <mcld/Target/KeyEntryMap.h> +#include "AArch64LDBackend.h" + +namespace mcld { +// FIXME: llvm::ELF doesn't define AArch64 dynamic relocation types +enum { + // static relocations + R_AARCH64_ADR_PREL_PG_HI21_NC = 0x114, + // dyanmic rlocations + R_AARCH64_COPY = 1024, + R_AARCH64_GLOB_DAT = 1025, + R_AARCH64_JUMP_SLOT = 1026, + R_AARCH64_RELATIVE = 1027, + R_AARCH64_TLS_DTPREL64 = 1028, + R_AARCH64_TLS_DTPMOD64 = 1029, + R_AARCH64_TLS_TPREL64 = 1030, + R_AARCH64_TLSDESC = 1031, + R_AARCH64_IRELATIVE = 1032 +}; + +/** \class AArch64Relocator + * \brief AArch64Relocator creates and destroys the AArch64 relocations. + * + */ +class AArch64Relocator : public Relocator +{ +public: + typedef KeyEntryMap<ResolveInfo, AArch64GOTEntry> SymGOTMap; + typedef KeyEntryMap<ResolveInfo, AArch64PLT1> SymPLTMap; + typedef KeyEntryMap<Relocation, Relocation> RelRelMap; + + /** \enum ReservedEntryType + * \brief The reserved entry type of reserved space in ResolveInfo. + * + * This is used for sacnRelocation to record what kinds of entries are + * reserved for this resolved symbol In AArch64, there are three kinds of + * entries, GOT, PLT, and dynamic reloction. + * + * bit: 3 2 1 0 + * | | PLT | GOT | Rel | + * + * value Name - Description + * + * 0000 None - no reserved entry + * 0001 ReserveRel - reserve an dynamic relocation entry + * 0010 ReserveGOT - reserve an GOT entry + * 0100 ReservePLT - reserve an PLT entry and the corresponding GOT, + * + */ + enum ReservedEntryType { + None = 0, + ReserveRel = 1, + ReserveGOT = 2, + ReservePLT = 4, + }; + + /** \enum EntryValue + * \brief The value of the entries. The symbol value will be decided at after + * layout, so we mark the entry during scanRelocation and fill up the actual + * value when applying relocations. + */ + enum EntryValue { + Default = 0, + SymVal = 1 + }; + +public: + AArch64Relocator(AArch64GNULDBackend& pParent, const LinkerConfig& pConfig); + ~AArch64Relocator(); + + Result applyRelocation(Relocation& pRelocation); + + AArch64GNULDBackend& getTarget() + { return m_Target; } + + const AArch64GNULDBackend& getTarget() const + { return m_Target; } + + const char* getName(Relocation::Type pType) const; + + Size getSize(Relocation::Type pType) const; + + const SymGOTMap& getSymGOTMap() const { return m_SymGOTMap; } + SymGOTMap& getSymGOTMap() { return m_SymGOTMap; } + + const SymPLTMap& getSymPLTMap() const { return m_SymPLTMap; } + SymPLTMap& getSymPLTMap() { return m_SymPLTMap; } + + const SymGOTMap& getSymGOTPLTMap() const { return m_SymGOTPLTMap; } + SymGOTMap& getSymGOTPLTMap() { return m_SymGOTPLTMap; } + + const RelRelMap& getRelRelMap() const { return m_RelRelMap; } + RelRelMap& getRelRelMap() { return m_RelRelMap; } + + /// scanRelocation - determine the empty entries are needed or not and create + /// the empty entries if needed. + /// For AArch64, following entries are check to create: + /// - GOT entry (for .got section) + /// - PLT entry (for .plt section) + /// - dynamin relocation entries (for .rel.plt and .rel.dyn sections) + void scanRelocation(Relocation& pReloc, + IRBuilder& pBuilder, + Module& pModule, + LDSection& pSection, + Input& pInput); + +private: + void scanLocalReloc(Relocation& pReloc, const LDSection& pSection); + + void scanGlobalReloc(Relocation& pReloc, + IRBuilder& pBuilder, + const LDSection& pSection); + + /// addCopyReloc - add a copy relocation into .rel.dyn for pSym + /// @param pSym - A resolved copy symbol that defined in BSS section + void addCopyReloc(ResolveInfo& pSym); + + /// defineSymbolforCopyReloc - allocate a space in BSS section and + /// and force define the copy of pSym to BSS section + /// @return the output LDSymbol of the copy symbol + LDSymbol& defineSymbolforCopyReloc(IRBuilder& pLinker, + const ResolveInfo& pSym); + +private: + AArch64GNULDBackend& m_Target; + SymGOTMap m_SymGOTMap; + SymPLTMap m_SymPLTMap; + SymGOTMap m_SymGOTPLTMap; + RelRelMap m_RelRelMap; +}; + +} // namespace of mcld + +#endif + diff --git a/lib/Target/AArch64/AArch64TargetMachine.cpp b/lib/Target/AArch64/AArch64TargetMachine.cpp new file mode 100644 index 0000000..c0515f4 --- /dev/null +++ b/lib/Target/AArch64/AArch64TargetMachine.cpp @@ -0,0 +1,30 @@ +//===- AArch64TargetMachine.cpp -------------------------------------------===// +// +// The MCLinker Project +// +// This file is distributed under the University of Illinois Open Source +// License. See LICENSE.TXT for details. +// +//===----------------------------------------------------------------------===// +#include "AArch64TargetMachine.h" +#include "AArch64.h" + +#include <mcld/Support/TargetRegistry.h> + +using namespace mcld; + +AArch64BaseTargetMachine::AArch64BaseTargetMachine(llvm::TargetMachine& pPM, + const llvm::Target &pLLVMTarget, + const mcld::Target &pMCLDTarget, + const std::string& pTriple) + : MCLDTargetMachine(pPM, pLLVMTarget, pMCLDTarget, pTriple) { +} + +//===----------------------------------------------------------------------===// +// Initialize MCLDTargetMachine +//===----------------------------------------------------------------------===// +extern "C" void MCLDInitializeAArch64LDTarget() { + // Register createTargetMachine function pointer to mcld::Target + mcld::RegisterTargetMachine<mcld::AArch64BaseTargetMachine> X(mcld::TheAArch64Target); +} + diff --git a/lib/Target/AArch64/AArch64TargetMachine.h b/lib/Target/AArch64/AArch64TargetMachine.h new file mode 100644 index 0000000..aee0e8c --- /dev/null +++ b/lib/Target/AArch64/AArch64TargetMachine.h @@ -0,0 +1,29 @@ +//===- AArch64TargetMachine.h ---------------------------------------------===// +// +// The MCLinker Project +// +// This file is distributed under the University of Illinois Open Source +// License. See LICENSE.TXT for details. +// +//===----------------------------------------------------------------------===// +#ifndef TARGET_AARCH64_AARCH64TARGETMACHINE_H +#define TARGET_AARCH64_AARCH64TARGETMACHINE_H + +#include "AArch64.h" +#include <mcld/CodeGen/TargetMachine.h> + +namespace mcld { + +class AArch64BaseTargetMachine : public MCLDTargetMachine +{ +public: + AArch64BaseTargetMachine(llvm::TargetMachine& pTM, + const llvm::Target& pLLVMTarget, + const mcld::Target& pMCLDTarget, + const std::string& pTriple); +}; + +} // namespace of mcld + +#endif + diff --git a/lib/Target/AArch64/Android.mk b/lib/Target/AArch64/Android.mk new file mode 100644 index 0000000..31383bf --- /dev/null +++ b/lib/Target/AArch64/Android.mk @@ -0,0 +1,38 @@ +LOCAL_PATH:= $(call my-dir) + +mcld_aarch64_target_SRC_FILES := \ + AArch64Diagnostic.cpp \ + AArch64ELFDynamic.cpp \ + AArch64ELFMCLinker.cpp \ + AArch64Emulation.cpp \ + AArch64GOT.cpp \ + AArch64LDBackend.cpp \ + AArch64MCLinker.cpp \ + AArch64PLT.cpp \ + AArch64Relocator.cpp \ + AArch64TargetMachine.cpp + +# For the host +# ===================================================== +include $(CLEAR_VARS) + +LOCAL_SRC_FILES := $(mcld_aarch64_target_SRC_FILES) +LOCAL_MODULE:= libmcldAArch64Target + +LOCAL_MODULE_TAGS := optional + +include $(MCLD_HOST_BUILD_MK) +include $(BUILD_HOST_STATIC_LIBRARY) + +# For the device +# ===================================================== +include $(CLEAR_VARS) + +LOCAL_SRC_FILES := $(mcld_aarch64_target_SRC_FILES) +LOCAL_MODULE:= libmcldAArch64Target + +LOCAL_MODULE_TAGS := optional + +include $(MCLD_DEVICE_BUILD_MK) +include $(BUILD_STATIC_LIBRARY) + diff --git a/lib/Target/AArch64/TargetInfo/AArch64TargetInfo.cpp b/lib/Target/AArch64/TargetInfo/AArch64TargetInfo.cpp new file mode 100644 index 0000000..13472c9 --- /dev/null +++ b/lib/Target/AArch64/TargetInfo/AArch64TargetInfo.cpp @@ -0,0 +1,22 @@ +//===- AArch64TargetInfo.cpp ----------------------------------------------===// +// +// The MCLinker Project +// +// This file is distributed under the University of Illinois Open Source +// License. See LICENSE.TXT for details. +// +//===----------------------------------------------------------------------===// +#include <mcld/Support/TargetRegistry.h> +#include <mcld/Support/Target.h> + +namespace mcld { + +mcld::Target TheAArch64Target; + +extern "C" void MCLDInitializeAArch64LDTargetInfo() { + // register into mcld::TargetRegistry + mcld::RegisterTarget<llvm::Triple::aarch64> X(TheAArch64Target, "aarch64"); +} + +} // namespace of mcld + diff --git a/lib/Target/AArch64/TargetInfo/Android.mk b/lib/Target/AArch64/TargetInfo/Android.mk new file mode 100644 index 0000000..1b4026d --- /dev/null +++ b/lib/Target/AArch64/TargetInfo/Android.mk @@ -0,0 +1,28 @@ +LOCAL_PATH:= $(call my-dir) + +mcld_arm_info_SRC_FILES := \ + AArch64TargetInfo.cpp + +# For the host +# ===================================================== +include $(CLEAR_VARS) + +LOCAL_SRC_FILES := $(mcld_arm_info_SRC_FILES) +LOCAL_MODULE:= libmcldAArch64Info + +LOCAL_MODULE_TAGS := optional + +include $(MCLD_HOST_BUILD_MK) +include $(BUILD_HOST_STATIC_LIBRARY) + +# For the device +# ===================================================== +include $(CLEAR_VARS) + +LOCAL_SRC_FILES := $(mcld_arm_info_SRC_FILES) +LOCAL_MODULE:= libmcldAArch64Info + +LOCAL_MODULE_TAGS := optional + +include $(MCLD_DEVICE_BUILD_MK) +include $(BUILD_STATIC_LIBRARY) diff --git a/lib/Target/ARM/ARM.h b/lib/Target/ARM/ARM.h index 6fec04e..f368ba8 100644 --- a/lib/Target/ARM/ARM.h +++ b/lib/Target/ARM/ARM.h @@ -6,8 +6,8 @@ // License. See LICENSE.TXT for details. // //===----------------------------------------------------------------------===// -#ifndef MCLD_TARGET_ARM_H -#define MCLD_TARGET_ARM_H +#ifndef TARGET_ARM_ARM_H +#define TARGET_ARM_ARM_H #include <string> namespace llvm { diff --git a/lib/Target/ARM/ARMELFAttributeData.h b/lib/Target/ARM/ARMELFAttributeData.h index 01e7816..d4b0d4d 100644 --- a/lib/Target/ARM/ARMELFAttributeData.h +++ b/lib/Target/ARM/ARMELFAttributeData.h @@ -6,8 +6,8 @@ // License. See LICENSE.TXT for details. // //===----------------------------------------------------------------------===// -#ifndef MCLD_ARM_ELF_ATTRIBUTE_DATA_H -#define MCLD_ARM_ELF_ATTRIBUTE_DATA_H +#ifndef TARGET_ARM_ARMELFATTRIBUTEDATA_H +#define TARGET_ARM_ARMELFATTRIBUTEDATA_H #ifdef ENABLE_UNITTEST #include <gtest.h> #endif diff --git a/lib/Target/ARM/ARMELFDynamic.h b/lib/Target/ARM/ARMELFDynamic.h index 826070b..ef83156 100644 --- a/lib/Target/ARM/ARMELFDynamic.h +++ b/lib/Target/ARM/ARMELFDynamic.h @@ -6,8 +6,8 @@ // License. See LICENSE.TXT for details. // //===----------------------------------------------------------------------===// -#ifndef MCLD_ARM_ELFDYNAMIC_SECTION_H -#define MCLD_ARM_ELFDYNAMIC_SECTION_H +#ifndef TARGET_ARM_ARMELFDYNAMIC_H +#define TARGET_ARM_ARMELFDYNAMIC_H #ifdef ENABLE_UNITTEST #include <gtest.h> #endif diff --git a/lib/Target/ARM/ARMELFMCLinker.h b/lib/Target/ARM/ARMELFMCLinker.h index 1306bc9..813a1b5 100644 --- a/lib/Target/ARM/ARMELFMCLinker.h +++ b/lib/Target/ARM/ARMELFMCLinker.h @@ -6,8 +6,8 @@ // License. See LICENSE.TXT for details. // //===----------------------------------------------------------------------===// -#ifndef ARM_ELF_SECTION_LINKER_H -#define ARM_ELF_SECTION_LINKER_H +#ifndef TARGET_ARM_ARMELFMCLINKER_H +#define TARGET_ARM_ARMELFMCLINKER_H #ifdef ENABLE_UNITTEST #include <gtest.h> #endif diff --git a/lib/Target/ARM/ARMGNUInfo.h b/lib/Target/ARM/ARMGNUInfo.h index 531a817..79f2463 100644 --- a/lib/Target/ARM/ARMGNUInfo.h +++ b/lib/Target/ARM/ARMGNUInfo.h @@ -6,8 +6,8 @@ // License. See LICENSE.TXT for details. // //===----------------------------------------------------------------------===// -#ifndef MCLD_TARGET_ARM_GNU_INFO_H -#define MCLD_TARGET_ARM_GNU_INFO_H +#ifndef TARGET_ARM_ARMGNUINFO_H +#define TARGET_ARM_ARMGNUINFO_H #include <mcld/Target/GNUInfo.h> #include <llvm/Support/ELF.h> diff --git a/lib/Target/ARM/ARMGOT.cpp b/lib/Target/ARM/ARMGOT.cpp index 3e9dc31..7ad10ac 100644 --- a/lib/Target/ARM/ARMGOT.cpp +++ b/lib/Target/ARM/ARMGOT.cpp @@ -1,4 +1,4 @@ -//===- impl.cpp -----------------------------------------------------------===// +//===- ARMGOT.cpp ---------------------------------------------------------===// // // The MCLinker Project // diff --git a/lib/Target/ARM/ARMGOT.h b/lib/Target/ARM/ARMGOT.h index dc85fb0..750659a 100644 --- a/lib/Target/ARM/ARMGOT.h +++ b/lib/Target/ARM/ARMGOT.h @@ -6,8 +6,8 @@ // License. See LICENSE.TXT for details. // //===----------------------------------------------------------------------===// -#ifndef MCLD_ARM_GOT_H -#define MCLD_ARM_GOT_H +#ifndef TARGET_ARM_ARMGOT_H +#define TARGET_ARM_ARMGOT_H #ifdef ENABLE_UNITTEST #include <gtest.h> #endif diff --git a/lib/Target/ARM/ARMLDBackend.h b/lib/Target/ARM/ARMLDBackend.h index 5567293..cae589d 100644 --- a/lib/Target/ARM/ARMLDBackend.h +++ b/lib/Target/ARM/ARMLDBackend.h @@ -6,8 +6,8 @@ // License. See LICENSE.TXT for details. // //===----------------------------------------------------------------------===// -#ifndef MCLD_ARM_LDBACKEND_H -#define MCLD_ARM_LDBACKEND_H +#ifndef TARGET_ARM_ARMLDBACKEND_H +#define TARGET_ARM_ARMLDBACKEND_H #include "ARMELFDynamic.h" #include "ARMGOT.h" diff --git a/lib/Target/ARM/ARMPLT.cpp b/lib/Target/ARM/ARMPLT.cpp index 467bbeb..9ca2af1 100644 --- a/lib/Target/ARM/ARMPLT.cpp +++ b/lib/Target/ARM/ARMPLT.cpp @@ -29,7 +29,7 @@ ARMPLT1::ARMPLT1(SectionData& pParent) ARMPLT::ARMPLT(LDSection& pSection, ARMGOT &pGOTPLT) : PLT(pSection), m_GOT(pGOTPLT) { - new ARMPLT0(*m_SectionData); + new ARMPLT0(*m_pSectionData); } ARMPLT::~ARMPLT() @@ -38,18 +38,18 @@ ARMPLT::~ARMPLT() bool ARMPLT::hasPLT1() const { - return (m_SectionData->size() > 1); + return (m_pSectionData->size() > 1); } void ARMPLT::finalizeSectionSize() { - uint64_t size = (m_SectionData->size() - 1) * sizeof(arm_plt1) + + uint64_t size = (m_pSectionData->size() - 1) * sizeof(arm_plt1) + sizeof(arm_plt0); m_Section.setSize(size); uint32_t offset = 0; - SectionData::iterator frag, fragEnd = m_SectionData->end(); - for (frag = m_SectionData->begin(); frag != fragEnd; ++frag) { + SectionData::iterator frag, fragEnd = m_pSectionData->end(); + for (frag = m_pSectionData->begin(); frag != fragEnd; ++frag) { frag->setOffset(offset); offset += frag->size(); } @@ -57,14 +57,14 @@ void ARMPLT::finalizeSectionSize() ARMPLT1* ARMPLT::create() { - ARMPLT1* plt1_entry = new (std::nothrow) ARMPLT1(*m_SectionData); + ARMPLT1* plt1_entry = new (std::nothrow) ARMPLT1(*m_pSectionData); if (!plt1_entry) fatal(diag::fail_allocate_memory_plt); return plt1_entry; } -void ARMPLT::applyPLT0() { - +void ARMPLT::applyPLT0() +{ uint64_t plt_base = m_Section.addr(); assert(plt_base && ".plt base address is NULL!"); @@ -78,9 +78,9 @@ void ARMPLT::applyPLT0() { else offset = (plt_base + 16) - got_base; - iterator first = m_SectionData->getFragmentList().begin(); + iterator first = m_pSectionData->getFragmentList().begin(); - assert(first != m_SectionData->getFragmentList().end() && + assert(first != m_pSectionData->getFragmentList().end() && "FragmentList is empty, applyPLT0 failed!"); ARMPLT0* plt0 = &(llvm::cast<ARMPLT0>(*first)); @@ -97,16 +97,16 @@ void ARMPLT::applyPLT0() { plt0->setValue(reinterpret_cast<unsigned char*>(data)); } -void ARMPLT::applyPLT1() { - +void ARMPLT::applyPLT1() +{ uint64_t plt_base = m_Section.addr(); assert(plt_base && ".plt base address is NULL!"); uint64_t got_base = m_GOT.addr(); assert(got_base && ".got base address is NULL!"); - ARMPLT::iterator it = m_SectionData->begin(); - ARMPLT::iterator ie = m_SectionData->end(); + ARMPLT::iterator it = m_pSectionData->begin(); + ARMPLT::iterator ie = m_pSectionData->end(); assert(it != ie && "FragmentList is empty, applyPLT1 failed!"); uint32_t GOTEntrySize = ARMGOTEntry::EntrySize; diff --git a/lib/Target/ARM/ARMPLT.h b/lib/Target/ARM/ARMPLT.h index e1c8a74..bacda93 100644 --- a/lib/Target/ARM/ARMPLT.h +++ b/lib/Target/ARM/ARMPLT.h @@ -6,8 +6,8 @@ // License. See LICENSE.TXT for details. // //===----------------------------------------------------------------------===// -#ifndef MCLD_ARM_PLT_H -#define MCLD_ARM_PLT_H +#ifndef TARGET_ARM_ARMPLT_H +#define TARGET_ARM_ARMPLT_H #include <mcld/Target/GOT.h> #include <mcld/Target/PLT.h> @@ -20,13 +20,13 @@ const uint32_t arm_plt0[] = { 0xe59fe004, // ldr lr, [pc, #4] 0xe08fe00e, // add lr, pc, lr 0xe5bef008, // ldr pc, [lr, #8]! - 0x00000000, // &GOT[0] - . + 0x00000000 // &GOT[0] - . }; const uint32_t arm_plt1[] = { 0xe28fc600, // add ip, pc, #0xNN00000 0xe28cca00, // add ip, ip, #0xNN000 - 0xe5bcf000, // ldr pc, [ip, #0xNNN]! + 0xe5bcf000 // ldr pc, [ip, #0xNNN]! }; } // anonymous namespace diff --git a/lib/Target/ARM/ARMRelocator.cpp b/lib/Target/ARM/ARMRelocator.cpp index 415c36e..088b219 100644 --- a/lib/Target/ARM/ARMRelocator.cpp +++ b/lib/Target/ARM/ARMRelocator.cpp @@ -73,14 +73,14 @@ helper_use_relative_reloc(const ResolveInfo& pSym, } // Strip LSB (THUMB bit) if "S" is a THUMB target. -static inline void helper_clear_thumb_bit(ARMRelocator::DWord& pValue) +static inline void helper_clear_thumb_bit(Relocator::DWord& pValue) { pValue &= (~0x1); } static -ARMRelocator::Address helper_get_GOT_address(ResolveInfo& pSym, - ARMRelocator& pParent) +Relocator::Address helper_get_GOT_address(ResolveInfo& pSym, + ARMRelocator& pParent) { ARMGOTEntry* got_entry = pParent.getSymGOTMap().lookUp(pSym); assert(NULL != got_entry); @@ -125,14 +125,14 @@ ARMGOTEntry& helper_GOT_init(Relocation& pReloc, } static -ARMRelocator::Address helper_GOT_ORG(ARMRelocator& pParent) +Relocator::Address helper_GOT_ORG(ARMRelocator& pParent) { return pParent.getTarget().getGOT().addr(); } static -ARMRelocator::Address helper_get_PLT_address(ResolveInfo& pSym, - ARMRelocator& pParent) +Relocator::Address helper_get_PLT_address(ResolveInfo& pSym, + ARMRelocator& pParent) { ARMPLT1* plt_entry = pParent.getSymPLTMap().lookUp(pSym); assert(NULL != plt_entry); @@ -169,7 +169,7 @@ ARMPLT1& helper_PLT_init(Relocation& pReloc, ARMRelocator& pParent) // pReloc->symInfo() static void helper_DynRel_init(Relocation& pReloc, - ARMRelocator::Type pType, + Relocator::Type pType, ARMRelocator& pParent) { // rsym - The relocation target symbol @@ -186,17 +186,17 @@ void helper_DynRel_init(Relocation& pReloc, rel_entry.setSymInfo(rsym); } -static ARMRelocator::DWord -helper_extract_movw_movt_addend(ARMRelocator::DWord pTarget) +static Relocator::DWord +helper_extract_movw_movt_addend(Relocator::DWord pTarget) { // imm16: [19-16][11-0] return helper_sign_extend((((pTarget >> 4)) & 0xf000U) | (pTarget & 0xfffU), 16); } -static ARMRelocator::DWord -helper_insert_val_movw_movt_inst(ARMRelocator::DWord pTarget, - ARMRelocator::DWord pImm) +static Relocator::DWord +helper_insert_val_movw_movt_inst(Relocator::DWord pTarget, + Relocator::DWord pImm) { // imm16: [19-16][11-0] pTarget &= 0xfff0f000U; @@ -205,8 +205,8 @@ helper_insert_val_movw_movt_inst(ARMRelocator::DWord pTarget, return pTarget; } -static ARMRelocator::DWord -helper_extract_thumb_movw_movt_addend(ARMRelocator::DWord pValue) +static Relocator::DWord +helper_extract_thumb_movw_movt_addend(Relocator::DWord pValue) { // imm16: [19-16][26][14-12][7-0] return helper_sign_extend((((pValue >> 4) & 0xf000U) | @@ -216,9 +216,9 @@ helper_extract_thumb_movw_movt_addend(ARMRelocator::DWord pValue) 16); } -static ARMRelocator::DWord -helper_insert_val_thumb_movw_movt_inst(ARMRelocator::DWord pValue, - ARMRelocator::DWord pImm) +static Relocator::DWord +helper_insert_val_thumb_movw_movt_inst(Relocator::DWord pValue, + Relocator::DWord pImm) { // imm16: [19-16][26][14-12][7-0] pValue &= 0xfbf08f00U; @@ -229,16 +229,16 @@ helper_insert_val_thumb_movw_movt_inst(ARMRelocator::DWord pValue, return pValue; } -static ARMRelocator::DWord -helper_thumb32_branch_offset(ARMRelocator::DWord pUpper16, - ARMRelocator::DWord pLower16) +static Relocator::DWord +helper_thumb32_branch_offset(Relocator::DWord pUpper16, + Relocator::DWord pLower16) { - ARMRelocator::DWord s = (pUpper16 & (1U << 10)) >> 10, // 26 bit + Relocator::DWord s = (pUpper16 & (1U << 10)) >> 10, // 26 bit u = pUpper16 & 0x3ffU, // 25-16 l = pLower16 & 0x7ffU, // 10-0 j1 = (pLower16 & (1U << 13)) >> 13, // 13 j2 = (pLower16 & (1U << 11)) >> 11; // 11 - ARMRelocator::DWord i1 = j1 ^ s? 0: 1, + Relocator::DWord i1 = j1 ^ s? 0: 1, i2 = j2 ^ s? 0: 1; // [31-25][24][23][22][21-12][11-1][0] @@ -248,17 +248,17 @@ helper_thumb32_branch_offset(ARMRelocator::DWord pUpper16, 25); } -static ARMRelocator::DWord -helper_thumb32_branch_upper(ARMRelocator::DWord pUpper16, - ARMRelocator::DWord pOffset) +static Relocator::DWord +helper_thumb32_branch_upper(Relocator::DWord pUpper16, + Relocator::DWord pOffset) { uint32_t sign = ((pOffset & 0x80000000U) >> 31); return (pUpper16 & ~0x7ffU) | ((pOffset >> 12) & 0x3ffU) | (sign << 10); } -static ARMRelocator::DWord -helper_thumb32_branch_lower(ARMRelocator::DWord pLower16, - ARMRelocator::DWord pOffset) +static Relocator::DWord +helper_thumb32_branch_lower(Relocator::DWord pLower16, + Relocator::DWord pOffset) { uint32_t sign = ((pOffset & 0x80000000U) >> 31); return ((pLower16 & ~0x2fffU) | @@ -267,9 +267,9 @@ helper_thumb32_branch_lower(ARMRelocator::DWord pLower16, ((pOffset >> 1) & 0x7ffU)); } -static ARMRelocator::DWord -helper_thumb32_cond_branch_offset(ARMRelocator::DWord pUpper16, - ARMRelocator::DWord pLower16) +static Relocator::DWord +helper_thumb32_cond_branch_offset(Relocator::DWord pUpper16, + Relocator::DWord pLower16) { uint32_t s = (pUpper16 & 0x0400U) >> 10; uint32_t j1 = (pLower16 & 0x2000U) >> 13; @@ -279,17 +279,17 @@ helper_thumb32_cond_branch_offset(ARMRelocator::DWord pUpper16, return helper_sign_extend((upper << 12) | (lower << 1), 21); } -static ARMRelocator::DWord -helper_thumb32_cond_branch_upper(ARMRelocator::DWord pUpper16, - ARMRelocator::DWord pOffset) +static Relocator::DWord +helper_thumb32_cond_branch_upper(Relocator::DWord pUpper16, + Relocator::DWord pOffset) { uint32_t sign = ((pOffset & 0x80000000U) >> 31); return (pUpper16 & 0xfbc0U) | (sign << 10) | ((pOffset & 0x0003f000U) >> 12); } -static ARMRelocator::DWord -helper_thumb32_cond_branch_lower(ARMRelocator::DWord pLower16, - ARMRelocator::DWord pOffset) +static Relocator::DWord +helper_thumb32_cond_branch_lower(Relocator::DWord pLower16, + Relocator::DWord pOffset) { uint32_t j2 = (pOffset & 0x00080000U) >> 19; uint32_t j1 = (pOffset & 0x00040000U) >> 18; @@ -299,7 +299,7 @@ helper_thumb32_cond_branch_lower(ARMRelocator::DWord pLower16, // Return true if overflow static bool -helper_check_signed_overflow(ARMRelocator::DWord pValue, +helper_check_signed_overflow(Relocator::DWord pValue, unsigned bits) { int32_t signed_val = static_cast<int32_t>(pValue); @@ -809,16 +809,16 @@ void ARMRelocator::scanRelocation(Relocation& pReloc, // R_ARM_NONE ARMRelocator::Result none(Relocation& pReloc, ARMRelocator& pParent) { - return ARMRelocator::OK; + return Relocator::OK; } // R_ARM_ABS32: (S + A) | T ARMRelocator::Result abs32(Relocation& pReloc, ARMRelocator& pParent) { ResolveInfo* rsym = pReloc.symInfo(); - ARMRelocator::DWord T = getThumbBit(pReloc); - ARMRelocator::DWord A = pReloc.target() + pReloc.addend(); - ARMRelocator::DWord S = pReloc.symValue(); + Relocator::DWord T = getThumbBit(pReloc); + Relocator::DWord A = pReloc.target() + pReloc.addend(); + Relocator::DWord S = pReloc.symValue(); if (T != 0x0) helper_clear_thumb_bit(S); @@ -827,7 +827,7 @@ ARMRelocator::Result abs32(Relocation& pReloc, ARMRelocator& pParent) if (0x0 == (llvm::ELF::SHF_ALLOC & pReloc.targetRef().frag()->getParent()->getSection().flag())) { pReloc.target() = (S + A) | T; - return ARMRelocator::OK; + return Relocator::OK; } // An external symbol may need PLT and dynamic relocation @@ -841,21 +841,21 @@ ARMRelocator::Result abs32(Relocation& pReloc, ARMRelocator& pParent) // in order to keep the addend store in the place correct. if ((rsym->reserved() & ARMRelocator::ReserveRel) && (!helper_use_relative_reloc(*rsym, pParent))) - return ARMRelocator::OK; + return Relocator::OK; } // perform static relocation pReloc.target() = (S + A) | T; - return ARMRelocator::OK; + return Relocator::OK; } // R_ARM_REL32: ((S + A) | T) - P ARMRelocator::Result rel32(Relocation& pReloc, ARMRelocator& pParent) { // perform static relocation - ARMRelocator::Address S = pReloc.symValue(); - ARMRelocator::DWord T = getThumbBit(pReloc); - ARMRelocator::DWord A = pReloc.target() + pReloc.addend(); + Relocator::Address S = pReloc.symValue(); + Relocator::DWord T = getThumbBit(pReloc); + Relocator::DWord A = pReloc.target() + pReloc.addend(); // An external symbol may need PLT (this reloc is from a stub/veneer) if (!pReloc.symInfo()->isLocal()) { @@ -871,42 +871,41 @@ ARMRelocator::Result rel32(Relocation& pReloc, ARMRelocator& pParent) // perform relocation pReloc.target() = ((S + A) | T) - pReloc.place(); - return ARMRelocator::OK; + return Relocator::OK; } // R_ARM_BASE_PREL: B(S) + A - P ARMRelocator::Result base_prel(Relocation& pReloc, ARMRelocator& pParent) { // perform static relocation - ARMRelocator::DWord A = pReloc.target() + pReloc.addend(); + Relocator::DWord A = pReloc.target() + pReloc.addend(); pReloc.target() = pReloc.symValue() + A - pReloc.place(); - return ARMRelocator::OK; + return Relocator::OK; } // R_ARM_GOTOFF32: ((S + A) | T) - GOT_ORG ARMRelocator::Result gotoff32(Relocation& pReloc, ARMRelocator& pParent) { - ARMRelocator::DWord T = getThumbBit(pReloc); - ARMRelocator::DWord A = pReloc.target() + pReloc.addend(); - ARMRelocator::Address GOT_ORG = helper_GOT_ORG(pParent); - ARMRelocator::Address S = pReloc.symValue(); + Relocator::DWord T = getThumbBit(pReloc); + Relocator::DWord A = pReloc.target() + pReloc.addend(); + Relocator::Address GOT_ORG = helper_GOT_ORG(pParent); + Relocator::Address S = pReloc.symValue(); if (T != 0x0) helper_clear_thumb_bit(S); pReloc.target() = ((S + A) | T) - GOT_ORG; - return ARMRelocator::OK; + return Relocator::OK; } // R_ARM_GOT_BREL: GOT(S) + A - GOT_ORG ARMRelocator::Result got_brel(Relocation& pReloc, ARMRelocator& pParent) { if (!(pReloc.symInfo()->reserved() & ARMRelocator::ReserveGOT)) - return ARMRelocator::BadReloc; + return Relocator::BadReloc; - ARMRelocator::Address GOT_S = helper_get_GOT_address(*pReloc.symInfo(), - pParent); - ARMRelocator::DWord A = pReloc.target() + pReloc.addend(); - ARMRelocator::Address GOT_ORG = helper_GOT_ORG(pParent); + Relocator::Address GOT_S = helper_get_GOT_address(*pReloc.symInfo(), pParent); + Relocator::DWord A = pReloc.target() + pReloc.addend(); + Relocator::Address GOT_ORG = helper_GOT_ORG(pParent); // Apply relocation. pReloc.target() = GOT_S + A - GOT_ORG; @@ -914,19 +913,18 @@ ARMRelocator::Result got_brel(Relocation& pReloc, ARMRelocator& pParent) ARMGOTEntry* got_entry = pParent.getSymGOTMap().lookUp(*pReloc.symInfo()); if (NULL != got_entry && ARMRelocator::SymVal == got_entry->getValue()) got_entry->setValue(pReloc.symValue()); - return ARMRelocator::OK; + return Relocator::OK; } // R_ARM_GOT_PREL: GOT(S) + A - P ARMRelocator::Result got_prel(Relocation& pReloc, ARMRelocator& pParent) { if (!(pReloc.symInfo()->reserved() & ARMRelocator::ReserveGOT)) { - return ARMRelocator::BadReloc; + return Relocator::BadReloc; } - ARMRelocator::Address GOT_S = helper_get_GOT_address(*pReloc.symInfo(), - pParent); - ARMRelocator::DWord A = pReloc.target() + pReloc.addend(); - ARMRelocator::Address P = pReloc.place(); + Relocator::Address GOT_S = helper_get_GOT_address(*pReloc.symInfo(), pParent); + Relocator::DWord A = pReloc.target() + pReloc.addend(); + Relocator::Address P = pReloc.place(); // Apply relocation. pReloc.target() = GOT_S + A - P; @@ -935,27 +933,26 @@ ARMRelocator::Result got_prel(Relocation& pReloc, ARMRelocator& pParent) ARMGOTEntry* got_entry = pParent.getSymGOTMap().lookUp(*pReloc.symInfo()); if (NULL != got_entry && ARMRelocator::SymVal == got_entry->getValue()) got_entry->setValue(pReloc.symValue()); - return ARMRelocator::OK; + return Relocator::OK; } // R_ARM_THM_JUMP11: S + A - P ARMRelocator::Result thm_jump11(Relocation& pReloc, ARMRelocator& pParent) { - ARMRelocator::DWord P = pReloc.place(); - ARMRelocator::DWord A = - helper_sign_extend((pReloc.target() & 0x07ff) << 1, 11) + + Relocator::DWord P = pReloc.place(); + Relocator::DWord A = helper_sign_extend((pReloc.target() & 0x07ff) << 1, 11) + pReloc.addend(); // S depends on PLT exists or not - ARMRelocator::Address S = pReloc.symValue(); + Relocator::Address S = pReloc.symValue(); if (pReloc.symInfo()->reserved() & ARMRelocator::ReservePLT) S = helper_get_PLT_address(*pReloc.symInfo(), pParent); - ARMRelocator::DWord X = S + A - P; + Relocator::DWord X = S + A - P; if (helper_check_signed_overflow(X, 11)) - return ARMRelocator::Overflow; + return Relocator::Overflow; // Make sure the Imm is 0. Result Mask. pReloc.target() = (pReloc.target() & 0xFFFFF800u) | ((X & 0x0FFEu) >> 1); - return ARMRelocator::OK; + return Relocator::OK; } // R_ARM_THM_JUMP19: ((S + A) | T) - P @@ -965,11 +962,11 @@ ARMRelocator::Result thm_jump19(Relocation& pReloc, ARMRelocator& pParent) uint16_t upper_inst = *(reinterpret_cast<uint16_t*>(&pReloc.target())); uint16_t lower_inst = *(reinterpret_cast<uint16_t*>(&pReloc.target()) + 1); - ARMRelocator::DWord T = getThumbBit(pReloc); - ARMRelocator::DWord A = helper_thumb32_cond_branch_offset(upper_inst, + Relocator::DWord T = getThumbBit(pReloc); + Relocator::DWord A = helper_thumb32_cond_branch_offset(upper_inst, lower_inst); - ARMRelocator::Address P = pReloc.place(); - ARMRelocator::Address S; + Relocator::Address P = pReloc.place(); + Relocator::Address S; // if symbol has plt if (pReloc.symInfo()->reserved() & ARMRelocator::ReservePLT) { S = helper_get_PLT_address(*pReloc.symInfo(), pParent); @@ -984,12 +981,12 @@ ARMRelocator::Result thm_jump19(Relocation& pReloc, ARMRelocator& pParent) if (0x0 == T) { // FIXME: conditional branch to PLT in THUMB-2 not supported yet error(diag::unsupport_cond_branch_reloc) << (int)pReloc.type(); - return ARMRelocator::BadReloc; + return Relocator::BadReloc; } - ARMRelocator::DWord X = ((S + A) | T) - P; + Relocator::DWord X = ((S + A) | T) - P; if (helper_check_signed_overflow(X, 21)) - return ARMRelocator::Overflow; + return Relocator::Overflow; upper_inst = helper_thumb32_cond_branch_upper(upper_inst, X); lower_inst = helper_thumb32_cond_branch_lower(lower_inst, X); @@ -997,7 +994,7 @@ ARMRelocator::Result thm_jump19(Relocation& pReloc, ARMRelocator& pParent) *(reinterpret_cast<uint16_t*>(&pReloc.target())) = upper_inst; *(reinterpret_cast<uint16_t*>(&pReloc.target()) + 1) = lower_inst; - return ARMRelocator::OK; + return Relocator::OK; } // R_ARM_PC24: ((S + A) | T) - P @@ -1015,15 +1012,15 @@ ARMRelocator::Result call(Relocation& pReloc, ARMRelocator& pParent) !(pReloc.symInfo()->reserved() & ARMRelocator::ReservePLT)) { // change target to NOP : mov r0, r0 pReloc.target() = (pReloc.target() & 0xf0000000U) | 0x01a00000; - return ARMRelocator::OK; + return Relocator::OK; } - ARMRelocator::DWord T = getThumbBit(pReloc); - ARMRelocator::DWord A = + Relocator::DWord T = getThumbBit(pReloc); + Relocator::DWord A = helper_sign_extend((pReloc.target() & 0x00FFFFFFu) << 2, 26) + pReloc.addend(); - ARMRelocator::Address P = pReloc.place(); - ARMRelocator::Address S = pReloc.symValue(); + Relocator::Address P = pReloc.place(); + Relocator::Address S = pReloc.symValue(); if (T != 0x0) helper_clear_thumb_bit(S); @@ -1040,22 +1037,22 @@ ARMRelocator::Result call(Relocation& pReloc, ARMRelocator& pParent) if (T != 0) { // cannot rewrite to blx for R_ARM_JUMP24 if (pReloc.type() == llvm::ELF::R_ARM_JUMP24) - return ARMRelocator::BadReloc; + return Relocator::BadReloc; if (pReloc.type() == llvm::ELF::R_ARM_PC24) - return ARMRelocator::BadReloc; + return Relocator::BadReloc; pReloc.target() = (pReloc.target() & 0xffffff) | 0xfa000000 | (((S + A - P) & 2) << 23); } - ARMRelocator::DWord X = ((S + A) | T) - P; + Relocator::DWord X = ((S + A) | T) - P; // Check X is 24bit sign int. If not, we should use stub or PLT before apply. if (helper_check_signed_overflow(X, 26)) - return ARMRelocator::Overflow; + return Relocator::Overflow; // Make sure the Imm is 0. Result Mask. pReloc.target() = (pReloc.target() & 0xFF000000u) | ((X & 0x03FFFFFEu) >> 2); - return ARMRelocator::OK; + return Relocator::OK; } // R_ARM_THM_CALL: ((S + A) | T) - P @@ -1070,17 +1067,17 @@ ARMRelocator::Result thm_call(Relocation& pReloc, ARMRelocator& pParent) !pReloc.symInfo()->isDyn() && !(pReloc.symInfo()->reserved() & ARMRelocator::ReservePLT)) { pReloc.target() = (0xe000U << 16) | 0xbf00U; - return ARMRelocator::OK; + return Relocator::OK; } // get lower and upper 16 bit instructions from relocation targetData uint16_t upper_inst = *(reinterpret_cast<uint16_t*>(&pReloc.target())); uint16_t lower_inst = *(reinterpret_cast<uint16_t*>(&pReloc.target()) + 1); - ARMRelocator::DWord T = getThumbBit(pReloc); - ARMRelocator::DWord A = helper_thumb32_branch_offset(upper_inst, lower_inst); - ARMRelocator::Address P = pReloc.place(); - ARMRelocator::Address S; + Relocator::DWord T = getThumbBit(pReloc); + Relocator::DWord A = helper_thumb32_branch_offset(upper_inst, lower_inst); + Relocator::Address P = pReloc.place(); + Relocator::Address S; // if symbol has plt if (pReloc.symInfo()->reserved() & ARMRelocator::ReservePLT) { @@ -1102,7 +1099,7 @@ ARMRelocator::Result thm_call(Relocation& pReloc, ARMRelocator& pParent) if (T == 0) { // cannot rewrite to blx for R_ARM_THM_JUMP24 if (pReloc.type() == llvm::ELF::R_ARM_THM_JUMP24) - return ARMRelocator::BadReloc; + return Relocator::BadReloc; // for BLX, select bit 1 from relocation base address to jump target // address @@ -1115,11 +1112,11 @@ ARMRelocator::Result thm_call(Relocation& pReloc, ARMRelocator& pParent) lower_inst |= 0x1000U; } - ARMRelocator::DWord X = (S | T) - P; + Relocator::DWord X = (S | T) - P; // FIXME: Check bit size is 24(thumb2) or 22? if (helper_check_signed_overflow(X, 25)) { - return ARMRelocator::Overflow; + return Relocator::Overflow; } upper_inst = helper_thumb32_branch_upper(upper_inst, X); @@ -1128,17 +1125,17 @@ ARMRelocator::Result thm_call(Relocation& pReloc, ARMRelocator& pParent) *(reinterpret_cast<uint16_t*>(&pReloc.target())) = upper_inst; *(reinterpret_cast<uint16_t*>(&pReloc.target()) + 1) = lower_inst; - return ARMRelocator::OK; + return Relocator::OK; } // R_ARM_MOVW_ABS_NC: (S + A) | T ARMRelocator::Result movw_abs_nc(Relocation& pReloc, ARMRelocator& pParent) { ResolveInfo* rsym = pReloc.symInfo(); - ARMRelocator::Address S = pReloc.symValue(); - ARMRelocator::DWord T = getThumbBit(pReloc); - ARMRelocator::DWord A = - helper_extract_movw_movt_addend(pReloc.target()) + pReloc.addend(); + Relocator::Address S = pReloc.symValue(); + Relocator::DWord T = getThumbBit(pReloc); + Relocator::DWord A = + helper_extract_movw_movt_addend(pReloc.target()) + pReloc.addend(); if (T != 0x0) helper_clear_thumb_bit(S); @@ -1155,29 +1152,29 @@ ARMRelocator::Result movw_abs_nc(Relocation& pReloc, ARMRelocator& pParent) } // perform static relocation - ARMRelocator::DWord X = (S + A) | T; + Relocator::DWord X = (S + A) | T; pReloc.target() = helper_insert_val_movw_movt_inst( pReloc.target() + pReloc.addend(), X); - return ARMRelocator::OK; + return Relocator::OK; } // R_ARM_MOVW_PREL_NC: ((S + A) | T) - P ARMRelocator::Result movw_prel_nc(Relocation& pReloc, ARMRelocator& pParent) { - ARMRelocator::Address S = pReloc.symValue(); - ARMRelocator::DWord T = getThumbBit(pReloc); - ARMRelocator::DWord P = pReloc.place(); - ARMRelocator::DWord A = - helper_extract_movw_movt_addend(pReloc.target()) + pReloc.addend(); + Relocator::Address S = pReloc.symValue(); + Relocator::DWord T = getThumbBit(pReloc); + Relocator::DWord P = pReloc.place(); + Relocator::DWord A = + helper_extract_movw_movt_addend(pReloc.target()) + pReloc.addend(); if (T != 0x0) helper_clear_thumb_bit(S); - ARMRelocator::DWord X = ((S + A) | T) - P; + Relocator::DWord X = ((S + A) | T) - P; if (helper_check_signed_overflow(X, 16)) { - return ARMRelocator::Overflow; + return Relocator::Overflow; } else { pReloc.target() = helper_insert_val_movw_movt_inst(pReloc.target(), X); - return ARMRelocator::OK; + return Relocator::OK; } } @@ -1185,9 +1182,9 @@ ARMRelocator::Result movw_prel_nc(Relocation& pReloc, ARMRelocator& pParent) ARMRelocator::Result movt_abs(Relocation& pReloc, ARMRelocator& pParent) { ResolveInfo* rsym = pReloc.symInfo(); - ARMRelocator::Address S = pReloc.symValue(); - ARMRelocator::DWord A = - helper_extract_movw_movt_addend(pReloc.target()) + pReloc.addend(); + Relocator::Address S = pReloc.symValue(); + Relocator::DWord A = + helper_extract_movw_movt_addend(pReloc.target()) + pReloc.addend(); LDSection& target_sect = pReloc.targetRef().frag()->getParent()->getSection(); @@ -1200,41 +1197,41 @@ ARMRelocator::Result movt_abs(Relocation& pReloc, ARMRelocator& pParent) } } - ARMRelocator::DWord X = S + A; + Relocator::DWord X = S + A; X >>= 16; // perform static relocation pReloc.target() = helper_insert_val_movw_movt_inst(pReloc.target(), X); - return ARMRelocator::OK; + return Relocator::OK; } // R_ARM_MOVT_PREL: S + A - P ARMRelocator::Result movt_prel(Relocation& pReloc, ARMRelocator& pParent) { - ARMRelocator::Address S = pReloc.symValue(); - ARMRelocator::DWord P = pReloc.place(); - ARMRelocator::DWord A = + Relocator::Address S = pReloc.symValue(); + Relocator::DWord P = pReloc.place(); + Relocator::DWord A = helper_extract_movw_movt_addend(pReloc.target()) + pReloc.addend(); - ARMRelocator::DWord X = S + A - P; + Relocator::DWord X = S + A - P; X >>= 16; pReloc.target() = helper_insert_val_movw_movt_inst(pReloc.target(), X); - return ARMRelocator::OK; + return Relocator::OK; } // R_ARM_THM_MOVW_ABS_NC: (S + A) | T ARMRelocator::Result thm_movw_abs_nc(Relocation& pReloc, ARMRelocator& pParent) { ResolveInfo* rsym = pReloc.symInfo(); - ARMRelocator::Address S = pReloc.symValue(); - ARMRelocator::DWord T = getThumbBit(pReloc); + Relocator::Address S = pReloc.symValue(); + Relocator::DWord T = getThumbBit(pReloc); if (T != 0x0) helper_clear_thumb_bit(S); // get lower and upper 16 bit instructions from relocation targetData uint16_t upper_inst = *(reinterpret_cast<uint16_t*>(&pReloc.target())); uint16_t lower_inst = *(reinterpret_cast<uint16_t*>(&pReloc.target()) + 1); - ARMRelocator::DWord val = ((upper_inst) << 16) | (lower_inst); - ARMRelocator::DWord A = + Relocator::DWord val = ((upper_inst) << 16) | (lower_inst); + Relocator::DWord A = helper_extract_thumb_movw_movt_addend(val) + pReloc.addend(); LDSection& target_sect = pReloc.targetRef().frag()->getParent()->getSection(); @@ -1247,76 +1244,76 @@ ARMRelocator::Result thm_movw_abs_nc(Relocation& pReloc, ARMRelocator& pParent) T = 0; // PLT is not thumb } } - ARMRelocator::DWord X = (S + A) | T; + Relocator::DWord X = (S + A) | T; val = helper_insert_val_thumb_movw_movt_inst(val, X); *(reinterpret_cast<uint16_t*>(&pReloc.target())) = val >> 16; *(reinterpret_cast<uint16_t*>(&pReloc.target()) + 1) = val & 0xFFFFu; - return ARMRelocator::OK; + return Relocator::OK; } // R_ARM_THM_MOVW_PREL_NC: ((S + A) | T) - P ARMRelocator::Result thm_movw_prel_nc(Relocation& pReloc, ARMRelocator& pParent) { - ARMRelocator::Address S = pReloc.symValue(); - ARMRelocator::DWord T = getThumbBit(pReloc); - ARMRelocator::DWord P = pReloc.place(); + Relocator::Address S = pReloc.symValue(); + Relocator::DWord T = getThumbBit(pReloc); + Relocator::DWord P = pReloc.place(); if (T != 0x0) helper_clear_thumb_bit(S); // get lower and upper 16 bit instructions from relocation targetData uint16_t upper_inst = *(reinterpret_cast<uint16_t*>(&pReloc.target())); uint16_t lower_inst = *(reinterpret_cast<uint16_t*>(&pReloc.target()) + 1); - ARMRelocator::DWord val = ((upper_inst) << 16) | (lower_inst); - ARMRelocator::DWord A = + Relocator::DWord val = ((upper_inst) << 16) | (lower_inst); + Relocator::DWord A = helper_extract_thumb_movw_movt_addend(val) + pReloc.addend(); - ARMRelocator::DWord X = ((S + A) | T) - P; + Relocator::DWord X = ((S + A) | T) - P; val = helper_insert_val_thumb_movw_movt_inst(val, X); *(reinterpret_cast<uint16_t*>(&pReloc.target())) = val >> 16; *(reinterpret_cast<uint16_t*>(&pReloc.target()) + 1) = val & 0xFFFFu; - return ARMRelocator::OK; + return Relocator::OK; } // R_ARM_THM_MOVW_BREL_NC: ((S + A) | T) - B(S) // R_ARM_THM_MOVW_BREL: ((S + A) | T) - B(S) ARMRelocator::Result thm_movw_brel(Relocation& pReloc, ARMRelocator& pParent) { - ARMRelocator::Address S = pReloc.symValue(); - ARMRelocator::DWord T = getThumbBit(pReloc); - ARMRelocator::DWord P = pReloc.place(); + Relocator::Address S = pReloc.symValue(); + Relocator::DWord T = getThumbBit(pReloc); + Relocator::DWord P = pReloc.place(); if (T != 0x0) helper_clear_thumb_bit(S); // get lower and upper 16 bit instructions from relocation targetData uint16_t upper_inst = *(reinterpret_cast<uint16_t*>(&pReloc.target())); uint16_t lower_inst = *(reinterpret_cast<uint16_t*>(&pReloc.target()) + 1); - ARMRelocator::DWord val = ((upper_inst) << 16) | (lower_inst); - ARMRelocator::DWord A = + Relocator::DWord val = ((upper_inst) << 16) | (lower_inst); + Relocator::DWord A = helper_extract_thumb_movw_movt_addend(val) + pReloc.addend(); - ARMRelocator::DWord X = ((S + A) | T) - P; + Relocator::DWord X = ((S + A) | T) - P; val = helper_insert_val_thumb_movw_movt_inst(val, X); *(reinterpret_cast<uint16_t*>(&pReloc.target())) = val >> 16; *(reinterpret_cast<uint16_t*>(&pReloc.target()) + 1) = val & 0xFFFFu; - return ARMRelocator::OK; + return Relocator::OK; } // R_ARM_THM_MOVT_ABS: S + A ARMRelocator::Result thm_movt_abs(Relocation& pReloc, ARMRelocator& pParent) { ResolveInfo* rsym = pReloc.symInfo(); - ARMRelocator::Address S = pReloc.symValue(); + Relocator::Address S = pReloc.symValue(); // get lower and upper 16 bit instructions from relocation targetData uint16_t upper_inst = *(reinterpret_cast<uint16_t*>(&pReloc.target())); uint16_t lower_inst = *(reinterpret_cast<uint16_t*>(&pReloc.target()) + 1); - ARMRelocator::DWord val = ((upper_inst) << 16) | (lower_inst); - ARMRelocator::DWord A = + Relocator::DWord val = ((upper_inst) << 16) | (lower_inst); + Relocator::DWord A = helper_extract_thumb_movw_movt_addend(val) + pReloc.addend(); LDSection& target_sect = pReloc.targetRef().frag()->getParent()->getSection(); @@ -1329,16 +1326,16 @@ ARMRelocator::Result thm_movt_abs(Relocation& pReloc, ARMRelocator& pParent) } } - ARMRelocator::DWord X = S + A; + Relocator::DWord X = S + A; X >>= 16; // check 16-bit overflow if (helper_check_signed_overflow(X, 16)) - return ARMRelocator::Overflow; + return Relocator::Overflow; val = helper_insert_val_thumb_movw_movt_inst(val, X); *(reinterpret_cast<uint16_t*>(&pReloc.target())) = val >> 16; *(reinterpret_cast<uint16_t*>(&pReloc.target()) + 1) = val & 0xFFFFu; - return ARMRelocator::OK; + return Relocator::OK; } @@ -1346,33 +1343,33 @@ ARMRelocator::Result thm_movt_abs(Relocation& pReloc, ARMRelocator& pParent) // R_ARM_THM_MOVT_BREL: S + A - B(S) ARMRelocator::Result thm_movt_prel(Relocation& pReloc, ARMRelocator& pParent) { - ARMRelocator::Address S = pReloc.symValue(); - ARMRelocator::DWord P = pReloc.place(); + Relocator::Address S = pReloc.symValue(); + Relocator::DWord P = pReloc.place(); // get lower and upper 16 bit instructions from relocation targetData uint16_t upper_inst = *(reinterpret_cast<uint16_t*>(&pReloc.target())); uint16_t lower_inst = *(reinterpret_cast<uint16_t*>(&pReloc.target()) + 1); - ARMRelocator::DWord val = ((upper_inst) << 16) | (lower_inst); - ARMRelocator::DWord A = + Relocator::DWord val = ((upper_inst) << 16) | (lower_inst); + Relocator::DWord A = helper_extract_thumb_movw_movt_addend(val) + pReloc.addend(); - ARMRelocator::DWord X = S + A - P; + Relocator::DWord X = S + A - P; X >>= 16; val = helper_insert_val_thumb_movw_movt_inst(val, X); *(reinterpret_cast<uint16_t*>(&pReloc.target())) = val >> 16; *(reinterpret_cast<uint16_t*>(&pReloc.target()) + 1) = val & 0xFFFFu; - return ARMRelocator::OK; + return Relocator::OK; } // R_ARM_PREL31: ((S + A) | T) - P ARMRelocator::Result prel31(Relocation& pReloc, ARMRelocator& pParent) { - ARMRelocator::DWord target = pReloc.target(); - ARMRelocator::DWord T = getThumbBit(pReloc); - ARMRelocator::DWord A = helper_sign_extend(target, 31) + pReloc.addend(); - ARMRelocator::DWord P = pReloc.place(); - ARMRelocator::Address S = pReloc.symValue(); + Relocator::DWord target = pReloc.target(); + Relocator::DWord T = getThumbBit(pReloc); + Relocator::DWord A = helper_sign_extend(target, 31) + pReloc.addend(); + Relocator::DWord P = pReloc.place(); + Relocator::Address S = pReloc.symValue(); if (T != 0x0) helper_clear_thumb_bit(S); @@ -1382,11 +1379,11 @@ ARMRelocator::Result prel31(Relocation& pReloc, ARMRelocator& pParent) T = 0; // PLT is not thumb. } - ARMRelocator::DWord X = ((S + A) | T) - P; + Relocator::DWord X = ((S + A) | T) - P; pReloc.target() = helper_bit_select(target, X, 0x7fffffffU); if (helper_check_signed_overflow(X, 31)) - return ARMRelocator::Overflow; - return ARMRelocator::OK; + return Relocator::Overflow; + return Relocator::OK; } // R_ARM_TLS_GD32: GOT(S) + A - P @@ -1394,10 +1391,10 @@ ARMRelocator::Result prel31(Relocation& pReloc, ARMRelocator& pParent) // R_ARM_TLS_LE32: S + A - tp ARMRelocator::Result tls(Relocation& pReloc, ARMRelocator& pParent) { - return ARMRelocator::Unsupport; + return Relocator::Unsupport; } ARMRelocator::Result unsupport(Relocation& pReloc, ARMRelocator& pParent) { - return ARMRelocator::Unsupport; + return Relocator::Unsupport; } diff --git a/lib/Target/ARM/ARMRelocator.h b/lib/Target/ARM/ARMRelocator.h index f1c4643..7c09b56 100644 --- a/lib/Target/ARM/ARMRelocator.h +++ b/lib/Target/ARM/ARMRelocator.h @@ -6,8 +6,8 @@ // License. See LICENSE.TXT for details. // //===----------------------------------------------------------------------===// -#ifndef ARM_RELOCATION_FACTORY_H -#define ARM_RELOCATION_FACTORY_H +#ifndef TARGET_ARM_ARMRELOCATOR_H +#define TARGET_ARM_ARMRELOCATOR_H #ifdef ENABLE_UNITTEST #include <gtest.h> #endif diff --git a/lib/Target/ARM/ARMTargetMachine.h b/lib/Target/ARM/ARMTargetMachine.h index 375f7b2..ddcf73d 100644 --- a/lib/Target/ARM/ARMTargetMachine.h +++ b/lib/Target/ARM/ARMTargetMachine.h @@ -6,8 +6,8 @@ // License. See LICENSE.TXT for details. // //===----------------------------------------------------------------------===// -#ifndef MCLD_ARM_TARGET_MACHINE_H -#define MCLD_ARM_TARGET_MACHINE_H +#ifndef TARGET_ARM_ARMTARGETMACHINE_H +#define TARGET_ARM_ARMTARGETMACHINE_H #include "ARM.h" #include <mcld/CodeGen/TargetMachine.h> diff --git a/lib/Target/ARM/ARMToARMStub.h b/lib/Target/ARM/ARMToARMStub.h index 107f172..dda5fcb 100644 --- a/lib/Target/ARM/ARMToARMStub.h +++ b/lib/Target/ARM/ARMToARMStub.h @@ -7,8 +7,8 @@ // //===----------------------------------------------------------------------===// -#ifndef MCLD_ARM_ARMTOARMSTUB_H -#define MCLD_ARM_ARMTOARMSTUB_H +#ifndef TARGET_ARM_ARMTOARMSTUB_H +#define TARGET_ARM_ARMTOARMSTUB_H #ifdef ENABLE_UNITTEST #include <gtest.h> #endif diff --git a/lib/Target/ARM/ARMToTHMStub.h b/lib/Target/ARM/ARMToTHMStub.h index b38303e..c26b813 100644 --- a/lib/Target/ARM/ARMToTHMStub.h +++ b/lib/Target/ARM/ARMToTHMStub.h @@ -7,8 +7,8 @@ // //===----------------------------------------------------------------------===// -#ifndef MCLD_ARM_ARMToTHMStub_H -#define MCLD_ARM_ARMToTHMStub_H +#ifndef TARGET_ARM_ARMTOTHMSTUB_H +#define TARGET_ARM_ARMTOTHMSTUB_H #ifdef ENABLE_UNITTEST #include <gtest.h> #endif diff --git a/lib/Target/ARM/THMToARMStub.h b/lib/Target/ARM/THMToARMStub.h index 994cc23..43bde12 100644 --- a/lib/Target/ARM/THMToARMStub.h +++ b/lib/Target/ARM/THMToARMStub.h @@ -7,8 +7,8 @@ // //===----------------------------------------------------------------------===// -#ifndef MCLD_ARM_THMToARMStub_H -#define MCLD_ARM_THMToARMStub_H +#ifndef TARGET_ARM_THMTOARMSTUB_H +#define TARGET_ARM_THMTOARMSTUB_H #ifdef ENABLE_UNITTEST #include <gtest.h> #endif diff --git a/lib/Target/ARM/THMToTHMStub.h b/lib/Target/ARM/THMToTHMStub.h index f8d6009..2f58461 100644 --- a/lib/Target/ARM/THMToTHMStub.h +++ b/lib/Target/ARM/THMToTHMStub.h @@ -7,8 +7,8 @@ // //===----------------------------------------------------------------------===// -#ifndef MCLD_ARM_THMToTHMStub_H -#define MCLD_ARM_THMToTHMStub_H +#ifndef TARGET_ARM_THMTOTHMSTUB_H +#define TARGET_ARM_THMTOTHMSTUB_H #ifdef ENABLE_UNITTEST #include <gtest.h> #endif diff --git a/lib/Target/ELFDynamic.cpp b/lib/Target/ELFDynamic.cpp index 25c56c1..86de446 100644 --- a/lib/Target/ELFDynamic.cpp +++ b/lib/Target/ELFDynamic.cpp @@ -110,6 +110,11 @@ void ELFDynamic::reserveEntries(const ELFFileFormat& pFormat) if (pFormat.hasFini()) reserveOne(llvm::ELF::DT_FINI); // DT_FINI + if (pFormat.hasPreInitArray()) { + reserveOne(llvm::ELF::DT_PREINIT_ARRAY); // DT_PREINIT_ARRAY + reserveOne(llvm::ELF::DT_PREINIT_ARRAYSZ); // DT_PREINIT_ARRAYSZ + } + if (pFormat.hasInitArray()) { reserveOne(llvm::ELF::DT_INIT_ARRAY); // DT_INIT_ARRAY reserveOne(llvm::ELF::DT_INIT_ARRAYSZ); // DT_INIT_ARRAYSZ @@ -208,6 +213,13 @@ void ELFDynamic::applyEntries(const ELFFileFormat& pFormat) if (pFormat.hasFini()) applyOne(llvm::ELF::DT_FINI, pFormat.getFini().addr()); // DT_FINI + if (pFormat.hasPreInitArray()) { + // DT_PREINIT_ARRAY + applyOne(llvm::ELF::DT_PREINIT_ARRAY, pFormat.getPreInitArray().addr()); + // DT_PREINIT_ARRAYSZ + applyOne(llvm::ELF::DT_PREINIT_ARRAYSZ, pFormat.getPreInitArray().size()); + } + if (pFormat.hasInitArray()) { // DT_INIT_ARRAY applyOne(llvm::ELF::DT_INIT_ARRAY, pFormat.getInitArray().addr()); diff --git a/lib/Target/GNULDBackend.cpp b/lib/Target/GNULDBackend.cpp index 796c93e..e888bc9 100644 --- a/lib/Target/GNULDBackend.cpp +++ b/lib/Target/GNULDBackend.cpp @@ -1613,12 +1613,14 @@ GNULDBackend::allocateCommonSymbols(Module& pModule) tbss_offset += ObjectBuilder::AppendFragment(*frag, *tbss_sect_data, (*com_sym)->value()); + ObjectBuilder::UpdateSectionAlign(tbss_sect, (*com_sym)->value()); (*com_sym)->setFragmentRef(FragmentRef::Create(*frag, 0)); } else { bss_offset += ObjectBuilder::AppendFragment(*frag, *bss_sect_data, (*com_sym)->value()); + ObjectBuilder::UpdateSectionAlign(bss_sect, (*com_sym)->value()); (*com_sym)->setFragmentRef(FragmentRef::Create(*frag, 0)); } } @@ -1640,12 +1642,14 @@ GNULDBackend::allocateCommonSymbols(Module& pModule) tbss_offset += ObjectBuilder::AppendFragment(*frag, *tbss_sect_data, (*com_sym)->value()); + ObjectBuilder::UpdateSectionAlign(tbss_sect, (*com_sym)->value()); (*com_sym)->setFragmentRef(FragmentRef::Create(*frag, 0)); } else { bss_offset += ObjectBuilder::AppendFragment(*frag, *bss_sect_data, (*com_sym)->value()); + ObjectBuilder::UpdateSectionAlign(bss_sect, (*com_sym)->value()); (*com_sym)->setFragmentRef(FragmentRef::Create(*frag, 0)); } } diff --git a/lib/Target/Hexagon/Hexagon.h b/lib/Target/Hexagon/Hexagon.h index 731a878..437a839 100644 --- a/lib/Target/Hexagon/Hexagon.h +++ b/lib/Target/Hexagon/Hexagon.h @@ -6,8 +6,8 @@ // License. See LICENSE.TXT for details. // //===----------------------------------------------------------------------===// -#ifndef MCLD_TARGET_HEXAGON_H -#define MCLD_TARGET_HEXAGON_H +#ifndef TARGET_HEXAGON_HEXAGON_H +#define TARGET_HEXAGON_HEXAGON_H #include <string> namespace llvm { diff --git a/lib/Target/Hexagon/HexagonAbsoluteStub.h b/lib/Target/Hexagon/HexagonAbsoluteStub.h index f5a3994..0f86318 100644 --- a/lib/Target/Hexagon/HexagonAbsoluteStub.h +++ b/lib/Target/Hexagon/HexagonAbsoluteStub.h @@ -7,8 +7,8 @@ // //===----------------------------------------------------------------------===// -#ifndef MCLD_HEXAGON_ABSOLUTE_STUB_H -#define MCLD_HEXAGON_ABSOLUTE_STUB_H +#ifndef TARGET_HEXAGON_HEXAGONABSOLUTESTUB_H +#define TARGET_HEXAGON_HEXAGONABSOLUTESTUB_H #ifdef ENABLE_UNITTEST #include <gtest.h> #endif diff --git a/lib/Target/Hexagon/HexagonELFDynamic.cpp b/lib/Target/Hexagon/HexagonELFDynamic.cpp index 96d0946..96534cc 100644 --- a/lib/Target/Hexagon/HexagonELFDynamic.cpp +++ b/lib/Target/Hexagon/HexagonELFDynamic.cpp @@ -32,6 +32,6 @@ void HexagonELFDynamic::applyTargetEntries(const ELFFileFormat& pFormat) { // applyPLTGOT if (pFormat.hasGOTPLT()) - applyOne(llvm::ELF::DT_PLTGOT, pFormat.getGOTPLT().addr()); + applyOne(llvm::ELF::DT_PLTGOT, pFormat.getGOTPLT().addr()); } diff --git a/lib/Target/Hexagon/HexagonELFDynamic.h b/lib/Target/Hexagon/HexagonELFDynamic.h index 423d918..092243d 100644 --- a/lib/Target/Hexagon/HexagonELFDynamic.h +++ b/lib/Target/Hexagon/HexagonELFDynamic.h @@ -6,8 +6,8 @@ // License. See LICENSE.TXT for details. // //===----------------------------------------------------------------------===// -#ifndef MCLD_HEXAGON_ELFDYNAMIC_SECTION_H -#define MCLD_HEXAGON_ELFDYNAMIC_SECTION_H +#ifndef TARGET_HEXAGON_HEXAGONELFDYNAMIC_H +#define TARGET_HEXAGON_HEXAGONELFDYNAMIC_H #ifdef ENABLE_UNITTEST #include <gtest.h> #endif diff --git a/lib/Target/Hexagon/HexagonELFMCLinker.h b/lib/Target/Hexagon/HexagonELFMCLinker.h index 6bbfe26..e7510e0 100644 --- a/lib/Target/Hexagon/HexagonELFMCLinker.h +++ b/lib/Target/Hexagon/HexagonELFMCLinker.h @@ -6,8 +6,8 @@ // License. See LICENSE.TXT for details. // //===----------------------------------------------------------------------===// -#ifndef HEXAGON_ELFSECTLINKER_H -#define HEXAGON_ELFSECTLINKER_H +#ifndef TARGET_HEXAGON_HEXAGONELFMCLINKER_H +#define TARGET_HEXAGON_HEXAGONELFMCLINKER_H #ifdef ENABLE_UNITTEST #include <gtest.h> #endif diff --git a/lib/Target/Hexagon/HexagonEncodings.h b/lib/Target/Hexagon/HexagonEncodings.h index e26f73b..2a2e9db 100644 --- a/lib/Target/Hexagon/HexagonEncodings.h +++ b/lib/Target/Hexagon/HexagonEncodings.h @@ -6,8 +6,8 @@ // License. See LICENSE.TXT for details. // //===----------------------------------------------------------------------===// -#ifndef HEXAGON_ENCODINGS_H -#define HEXAGON_ENCODINGS_H +#ifndef TARGET_HEXAGON_HEXAGONENCODINGS_H +#define TARGET_HEXAGON_HEXAGONENCODINGS_H Instruction insn_encodings[] = { { "if (Pv4) memb(Rs32+#u6:0)=Rt32", diff --git a/lib/Target/Hexagon/HexagonGNUInfo.h b/lib/Target/Hexagon/HexagonGNUInfo.h index d7b471c..0173e65 100644 --- a/lib/Target/Hexagon/HexagonGNUInfo.h +++ b/lib/Target/Hexagon/HexagonGNUInfo.h @@ -6,8 +6,8 @@ // License. See LICENSE.TXT for details. // //===----------------------------------------------------------------------===// -#ifndef MCLD_TARGET_HEXAGON_GNU_INFO_H -#define MCLD_TARGET_HEXAGON_GNU_INFO_H +#ifndef TARGET_HEXAGON_HEXAGONGNUINFO_H +#define TARGET_HEXAGON_HEXAGONGNUINFO_H #include <mcld/Target/GNUInfo.h> #include <mcld/TargetOptions.h> diff --git a/lib/Target/Hexagon/HexagonGOT.h b/lib/Target/Hexagon/HexagonGOT.h index c29239c..0bde189 100644 --- a/lib/Target/Hexagon/HexagonGOT.h +++ b/lib/Target/Hexagon/HexagonGOT.h @@ -6,8 +6,8 @@ // License. See LICENSE.TXT for details. // //===----------------------------------------------------------------------===// -#ifndef MCLD_TARGET_HEXAGON_GOT_H -#define MCLD_TARGET_HEXAGON_GOT_H +#ifndef TARGET_HEXAGON_HEXAGONGOT_H +#define TARGET_HEXAGON_HEXAGONGOT_H #ifdef ENABLE_UNITTEST #include <gtest.h> #endif diff --git a/lib/Target/Hexagon/HexagonGOTPLT.h b/lib/Target/Hexagon/HexagonGOTPLT.h index 9fc67cd..a815229 100644 --- a/lib/Target/Hexagon/HexagonGOTPLT.h +++ b/lib/Target/Hexagon/HexagonGOTPLT.h @@ -6,8 +6,8 @@ // License. See LICENSE.TXT for details. // //===----------------------------------------------------------------------===// -#ifndef MCLD_HEXAGON_GOTPLT_H -#define MCLD_HEXAGON_GOTPLT_H +#ifndef TARGET_HEXAGON_HEXAGONGOTPLT_H +#define TARGET_HEXAGON_HEXAGONGOTPLT_H #ifdef ENABLE_UNITTEST #include <gtest.h> #endif diff --git a/lib/Target/Hexagon/HexagonLDBackend.h b/lib/Target/Hexagon/HexagonLDBackend.h index e2bc2bb..21d2e38 100644 --- a/lib/Target/Hexagon/HexagonLDBackend.h +++ b/lib/Target/Hexagon/HexagonLDBackend.h @@ -6,8 +6,8 @@ // License. See LICENSE.TXT for details. // //===----------------------------------------------------------------------===// -#ifndef HEXAGON_LDBACKEND_H -#define HEXAGON_LDBACKEND_H +#ifndef TARGET_HEXAGON_HEXAGONLDBACKEND_H +#define TARGET_HEXAGON_HEXAGONLDBACKEND_H #include "HexagonELFDynamic.h" #include "HexagonGOT.h" @@ -169,7 +169,7 @@ private: virtual uint64_t emitGOTSectionData(MemoryRegion& pRegion) const; virtual uint64_t emitGOTPLTSectionData(MemoryRegion& pRegion, - const ELFFileFormat* FileFormat) const; + const ELFFileFormat* FileFormat) const; virtual void setRelaDynSize(); virtual void setRelaPLTSize(); diff --git a/lib/Target/Hexagon/HexagonPLT.cpp b/lib/Target/Hexagon/HexagonPLT.cpp index 6309408..3d692fd 100644 --- a/lib/Target/Hexagon/HexagonPLT.cpp +++ b/lib/Target/Hexagon/HexagonPLT.cpp @@ -48,7 +48,7 @@ HexagonPLT::HexagonPLT(LDSection& pSection, m_PLT0 = hexagon_plt0; m_PLT0Size = sizeof (hexagon_plt0); // create PLT0 - new HexagonPLT0(*m_SectionData); + new HexagonPLT0(*m_pSectionData); pSection.setAlign(16); } @@ -58,9 +58,9 @@ HexagonPLT::~HexagonPLT() PLTEntryBase* HexagonPLT::getPLT0() const { - iterator first = m_SectionData->getFragmentList().begin(); + iterator first = m_pSectionData->getFragmentList().begin(); - assert(first != m_SectionData->getFragmentList().end() && + assert(first != m_pSectionData->getFragmentList().end() && "FragmentList is empty, getPLT0 failed!"); PLTEntryBase* plt0 = &(llvm::cast<PLTEntryBase>(*first)); @@ -80,13 +80,13 @@ void HexagonPLT::finalizeSectionSize() if (end() != it) { // plt1 size PLTEntryBase* plt1 = &(llvm::cast<PLTEntryBase>(*it)); - size += (m_SectionData->size() - 1) * plt1->size(); + size += (m_pSectionData->size() - 1) * plt1->size(); } m_Section.setSize(size); uint32_t offset = 0; - SectionData::iterator frag, fragEnd = m_SectionData->end(); - for (frag = m_SectionData->begin(); frag != fragEnd; ++frag) { + SectionData::iterator frag, fragEnd = m_pSectionData->end(); + for (frag = m_pSectionData->begin(); frag != fragEnd; ++frag) { frag->setOffset(offset); offset += frag->size(); } @@ -94,12 +94,12 @@ void HexagonPLT::finalizeSectionSize() bool HexagonPLT::hasPLT1() const { - return (m_SectionData->size() > 1); + return (m_pSectionData->size() > 1); } HexagonPLT1* HexagonPLT::create() { - return new HexagonPLT1(*m_SectionData); + return new HexagonPLT1(*m_pSectionData); } void HexagonPLT::applyPLT0() @@ -135,8 +135,8 @@ void HexagonPLT::applyPLT1() { uint64_t got_base = m_GOTPLT.addr(); assert(got_base && ".got base address is NULL!"); - HexagonPLT::iterator it = m_SectionData->begin(); - HexagonPLT::iterator ie = m_SectionData->end(); + HexagonPLT::iterator it = m_pSectionData->begin(); + HexagonPLT::iterator ie = m_pSectionData->end(); assert(it != ie && "FragmentList is empty, applyPLT1 failed!"); uint32_t GOTEntrySize = HexagonGOTEntry::EntrySize; diff --git a/lib/Target/Hexagon/HexagonPLT.h b/lib/Target/Hexagon/HexagonPLT.h index abdb4ea..4acce49 100644 --- a/lib/Target/Hexagon/HexagonPLT.h +++ b/lib/Target/Hexagon/HexagonPLT.h @@ -6,8 +6,8 @@ // License. See LICENSE.TXT for details. // //===----------------------------------------------------------------------===// -#ifndef MCLD_TARGET_HEXAGON_PLT_H -#define MCLD_TARGET_HEXAGON_PLT_H +#ifndef TARGET_HEXAGON_HEXAGONPLT_H +#define TARGET_HEXAGON_HEXAGONPLT_H #include "HexagonGOT.h" #include "HexagonGOTPLT.h" @@ -29,14 +29,14 @@ const uint8_t hexagon_plt0[] = { 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00 }; const uint8_t hexagon_plt1[] = { 0x00, 0x40, 0x00, 0x00, // { immext (#0) 0x0e, 0xc0, 0x49, 0x6a, // r14 = add (pc, ##GOTn@PCREL) } # address of GOTn 0x1c, 0xc0, 0x8e, 0x91, // r28 = memw (r14) # contents of GOTn - 0x00, 0xc0, 0x9c, 0x52, // jumpr r28 # call it + 0x00, 0xc0, 0x9c, 0x52 // jumpr r28 # call it }; } // anonymous namespace diff --git a/lib/Target/Hexagon/HexagonRelocationFunctions.h b/lib/Target/Hexagon/HexagonRelocationFunctions.h index 6f9acad..6c60954 100644 --- a/lib/Target/Hexagon/HexagonRelocationFunctions.h +++ b/lib/Target/Hexagon/HexagonRelocationFunctions.h @@ -7,11 +7,11 @@ // //===----------------------------------------------------------------------===// typedef struct { - const char *insnSyntax; - uint32_t insnMask; - uint32_t insnCmpMask; - uint32_t insnBitMask; - bool isDuplex; + const char *insnSyntax; + uint32_t insnMask; + uint32_t insnCmpMask; + uint32_t insnBitMask; + bool isDuplex; } Instruction; //===--------------------------------------------------------------------===// diff --git a/lib/Target/Hexagon/HexagonRelocator.cpp b/lib/Target/Hexagon/HexagonRelocator.cpp index b82bbcd..d02b640 100644 --- a/lib/Target/Hexagon/HexagonRelocator.cpp +++ b/lib/Target/Hexagon/HexagonRelocator.cpp @@ -26,7 +26,7 @@ using namespace mcld; static Relocation &helper_DynRel_init(ResolveInfo *pSym, Fragment &pFrag, uint64_t pOffset, - HexagonRelocator::Type pType, + Relocator::Type pType, HexagonRelocator &pParent) { HexagonLDBackend &ld_backend = pParent.getTarget(); Relocation &rela_entry = *ld_backend.getRelaDyn().create(); @@ -82,7 +82,7 @@ static HexagonGOTEntry &helper_GOT_init(Relocation &pReloc, return *got_entry; } -static HexagonRelocator::Address helper_get_GOT_address(ResolveInfo &pSym, +static Relocator::Address helper_get_GOT_address(ResolveInfo &pSym, HexagonRelocator &pParent) { HexagonGOTEntry *got_entry = pParent.getSymGOTMap().lookUp(pSym); assert(NULL != got_entry); @@ -112,7 +112,7 @@ static PLTEntryBase &helper_PLT_init(Relocation &pReloc, return *plt_entry; } -static HexagonRelocator::Address helper_get_PLT_address(ResolveInfo& pSym, +static Relocator::Address helper_get_PLT_address(ResolveInfo& pSym, HexagonRelocator &pParent) { PLTEntryBase *plt_entry = pParent.getSymPLTMap().lookUp(pSym); assert(NULL != plt_entry); @@ -124,9 +124,9 @@ static HexagonRelocator::Address helper_get_PLT_address(ResolveInfo& pSym, //===--------------------------------------------------------------------===// DECL_HEXAGON_APPLY_RELOC_FUNCS - /// the prototype of applying function - typedef Relocator::Result (*ApplyFunctionType)(Relocation &pReloc, - HexagonRelocator &pParent); +/// the prototype of applying function +typedef Relocator::Result (*ApplyFunctionType)(Relocation &pReloc, + HexagonRelocator &pParent); // the table entry of applying functions struct ApplyFunctionTriple { @@ -480,16 +480,16 @@ void HexagonRelocator::partialScanRelocation(Relocation &pReloc, //=========================================// // R_HEX_NONE -HexagonRelocator::Result none(Relocation &pReloc, HexagonRelocator &pParent) { - return HexagonRelocator::OK; +Relocator::Result none(Relocation &pReloc, HexagonRelocator &pParent) { + return Relocator::OK; } //R_HEX_32 and its class of relocations use only addend and symbol value // S + A : result is unsigned truncate. // Exception: R_HEX_32_6_X : unsigned verify -HexagonRelocator::Result applyAbs(Relocation &pReloc) { - HexagonRelocator::Address S = pReloc.symValue(); - HexagonRelocator::DWord A = pReloc.addend(); +Relocator::Result applyAbs(Relocation &pReloc) { + Relocator::Address S = pReloc.symValue(); + Relocator::DWord A = pReloc.addend(); uint32_t result = (uint32_t)(S + A); uint32_t bitMask = 0; uint32_t effectiveBits = 0; @@ -548,25 +548,25 @@ HexagonRelocator::Result applyAbs(Relocation &pReloc) { } if ((shift != 0) && (result % alignment != 0)) - return HexagonRelocator::BadReloc; + return Relocator::BadReloc; result >>= shift; if (effectiveBits) { uint32_t range = 1 << effectiveBits; if (result > (range - 1)) - return HexagonRelocator::Overflow; + return Relocator::Overflow; } pReloc.target() |= ApplyMask<uint32_t>(bitMask, result); - return HexagonRelocator::OK; + return Relocator::OK; } //R_HEX_B22_PCREL and its class of relocations, use // S + A - P : result is signed verify. // Exception: R_HEX_B32_PCREL_X : signed truncate // Another Exception: R_HEX_6_PCREL_X is unsigned truncate -HexagonRelocator::Result applyRel(Relocation &pReloc, int64_t pResult) { +Relocator::Result applyRel(Relocation &pReloc, int64_t pResult) { uint32_t bitMask = 0; uint32_t effectiveBits = 0; uint32_t alignment = 1; @@ -654,7 +654,7 @@ HexagonRelocator::Result applyRel(Relocation &pReloc, int64_t pResult) { bitMask = FINDBITMASK(pReloc.target()); result = pReloc.addend() + pReloc.symValue() - pReloc.place(); pReloc.target() |= ApplyMask<uint32_t>(bitMask, result); - return HexagonRelocator::OK; + return Relocator::OK; default: // show proper error @@ -663,25 +663,24 @@ HexagonRelocator::Result applyRel(Relocation &pReloc, int64_t pResult) { } if ((shift != 0) && (pResult % alignment != 0)) - return HexagonRelocator::BadReloc; + return Relocator::BadReloc; pResult >>= shift; if (effectiveBits) { int64_t range = 1LL << (effectiveBits - 1); if ((pResult > (range - 1)) || (pResult < -range)) - return HexagonRelocator::Overflow; + return Relocator::Overflow; } pReloc.target() |= (uint32_t) ApplyMask<int32_t>(bitMask, pResult); - return HexagonRelocator::OK; + return Relocator::OK; } -HexagonRelocator::Result relocAbs(Relocation &pReloc, - HexagonRelocator &pParent) { +Relocator::Result relocAbs(Relocation &pReloc, HexagonRelocator &pParent) { ResolveInfo *rsym = pReloc.symInfo(); - HexagonRelocator::Address S = pReloc.symValue(); - HexagonRelocator::DWord A = pReloc.addend(); + Relocator::Address S = pReloc.symValue(); + Relocator::DWord A = pReloc.addend(); Relocation* rel_entry = pParent.getRelRelMap().lookUp(pReloc); bool has_dyn_rel = (NULL != rel_entry); @@ -696,7 +695,7 @@ HexagonRelocator::Result relocAbs(Relocation &pReloc, // a local symbol with .rela type relocation if (rsym->isLocal() && has_dyn_rel) { rel_entry->setAddend(S + A); - return HexagonRelocator::OK; + return Relocator::OK; } if (!rsym->isLocal()) { @@ -710,7 +709,7 @@ HexagonRelocator::Result relocAbs(Relocation &pReloc, rel_entry->setAddend(S + A); } else { rel_entry->setAddend(A); - return HexagonRelocator::OK; + return Relocator::OK; } } } @@ -718,14 +717,13 @@ HexagonRelocator::Result relocAbs(Relocation &pReloc, return applyAbs(pReloc); } -HexagonRelocator::Result relocPCREL(Relocation &pReloc, - HexagonRelocator &pParent) { +Relocator::Result relocPCREL(Relocation &pReloc, HexagonRelocator &pParent) { ResolveInfo *rsym = pReloc.symInfo(); int64_t result; - HexagonRelocator::Address S = pReloc.symValue(); - HexagonRelocator::DWord A = pReloc.addend(); - HexagonRelocator::DWord P = pReloc.place(); + Relocator::Address S = pReloc.symValue(); + Relocator::DWord A = pReloc.addend(); + Relocator::DWord P = pReloc.place(); FragmentRef &target_fragref = pReloc.targetRef(); Fragment *target_frag = target_fragref.frag(); @@ -743,7 +741,7 @@ HexagonRelocator::Result relocPCREL(Relocation &pReloc, S = helper_get_PLT_address(*rsym, pParent); result = (int64_t)(S + A - P); applyRel(pReloc, result); - return HexagonRelocator::OK; + return Relocator::OK; } } @@ -751,11 +749,10 @@ HexagonRelocator::Result relocPCREL(Relocation &pReloc, } // R_HEX_GPREL16_0 and its class : Unsigned Verify -HexagonRelocator::Result relocGPREL(Relocation &pReloc, - HexagonRelocator &pParent) { - HexagonRelocator::Address S = pReloc.symValue(); - HexagonRelocator::DWord A = pReloc.addend(); - HexagonRelocator::DWord GP = pParent.getTarget().getGP(); +Relocator::Result relocGPREL(Relocation &pReloc, HexagonRelocator &pParent) { + Relocator::Address S = pReloc.symValue(); + Relocator::DWord A = pReloc.addend(); + Relocator::DWord GP = pParent.getTarget().getGP(); uint32_t result = (uint32_t)(S + A - GP); uint32_t shift = 0; @@ -790,40 +787,39 @@ HexagonRelocator::Result relocGPREL(Relocation &pReloc, uint32_t bitMask = FINDBITMASK(pReloc.target()); if ((shift != 0) && (result % alignment != 0)) - return HexagonRelocator::BadReloc; + return Relocator::BadReloc; result >>= shift; if (result < range - 1) { pReloc.target() |= ApplyMask<uint32_t>(bitMask, result); - return HexagonRelocator::OK; + return Relocator::OK; } - return HexagonRelocator::Overflow; + return Relocator::Overflow; } // R_HEX_PLT_B22_PCREL: PLT(S) + A - P -HexagonRelocator::Result relocPLTB22PCREL(Relocation &pReloc, - HexagonRelocator &pParent) { +Relocator::Result relocPLTB22PCREL(Relocation &pReloc, + HexagonRelocator &pParent) { // PLT_S depends on if there is a PLT entry. - HexagonRelocator::Address PLT_S; + Relocator::Address PLT_S; if ((pReloc.symInfo()->reserved() & HexagonRelocator::ReservePLT)) PLT_S = helper_get_PLT_address(*pReloc.symInfo(), pParent); else PLT_S = pReloc.symValue(); - HexagonRelocator::Address P = pReloc.place(); + Relocator::Address P = pReloc.place(); uint32_t bitMask = FINDBITMASK(pReloc.target()); uint32_t result = (PLT_S + pReloc.addend() - P) >> 2; pReloc.target() = pReloc.target() | ApplyMask<uint32_t>(bitMask, result); - return HexagonRelocator::OK; + return Relocator::OK; } //R_HEX_GOT_LO16 and its class : (G) Signed Truncate //Exception: R_HEX_GOT_16(_X): signed verify // Exception: R_HEX_GOT_11_X : unsigned truncate -HexagonRelocator::Result relocGOT(Relocation &pReloc, - HexagonRelocator &pParent) { +Relocator::Result relocGOT(Relocation &pReloc, HexagonRelocator &pParent) { if (!(pReloc.symInfo()->reserved() & HexagonRelocator::ReserveGOT)) { - return HexagonRelocator::BadReloc; + return Relocator::BadReloc; } // set got entry value if needed @@ -832,9 +828,9 @@ HexagonRelocator::Result relocGOT(Relocation &pReloc, if (HexagonRelocator::SymVal == got_entry->getValue()) got_entry->setValue(pReloc.symValue()); - HexagonRelocator::Address GOT_S = + Relocator::Address GOT_S = helper_get_GOT_address(*pReloc.symInfo(), pParent); - HexagonRelocator::Address GOT = pParent.getTarget().getGOTSymbolAddr(); + Relocator::Address GOT = pParent.getTarget().getGOTSymbolAddr(); int32_t result = (int32_t)(GOT_S - GOT); uint32_t effectiveBits = 0; uint32_t alignment = 1; @@ -876,7 +872,7 @@ HexagonRelocator::Result relocGOT(Relocation &pReloc, bitMask = FINDBITMASK(pReloc.target()); result_u = GOT_S - GOT; pReloc.target() |= ApplyMask<uint32_t>(bitMask, result_u); - return HexagonRelocator::OK; + return Relocator::OK; default: // show proper error @@ -885,26 +881,25 @@ HexagonRelocator::Result relocGOT(Relocation &pReloc, } if ((shift != 0) && (result % alignment != 0)) - return HexagonRelocator::BadReloc; + return Relocator::BadReloc; result >>= shift; if (effectiveBits) { int32_t range = 1 << (effectiveBits - 1); if ((result > range - 1) || (result < -range)) - return HexagonRelocator::Overflow; + return Relocator::Overflow; } pReloc.target() |= ApplyMask<int32_t>(bitMask, result); - return HexagonRelocator::OK; + return Relocator::OK; } // R_HEX_GOTREL_LO16: and its class of relocs // (S + A - GOT) : Signed Truncate -HexagonRelocator::Result relocGOTREL(Relocation &pReloc, - HexagonRelocator &pParent) { - HexagonRelocator::Address S = pReloc.symValue(); - HexagonRelocator::DWord A = pReloc.addend(); - HexagonRelocator::Address GOT = pParent.getTarget().getGOTSymbolAddr(); +Relocator::Result relocGOTREL(Relocation &pReloc, HexagonRelocator &pParent) { + Relocator::Address S = pReloc.symValue(); + Relocator::DWord A = pReloc.addend(); + Relocator::Address GOT = pParent.getTarget().getGOTSymbolAddr(); uint32_t bitMask = 0; uint32_t alignment = 1; @@ -944,15 +939,14 @@ HexagonRelocator::Result relocGOTREL(Relocation &pReloc, } if (result % alignment != 0) - return HexagonRelocator::BadReloc; + return Relocator::BadReloc; result >>= shift; pReloc.target() |= ApplyMask<uint32_t>(bitMask, result); - return HexagonRelocator::OK; + return Relocator::OK; } -HexagonRelocator::Result unsupport(Relocation &pReloc, - HexagonRelocator &pParent) { - return HexagonRelocator::Unsupport; +Relocator::Result unsupport(Relocation &pReloc, HexagonRelocator &pParent) { + return Relocator::Unsupport; } diff --git a/lib/Target/Hexagon/HexagonRelocator.h b/lib/Target/Hexagon/HexagonRelocator.h index 02e99c9..79e66eb 100644 --- a/lib/Target/Hexagon/HexagonRelocator.h +++ b/lib/Target/Hexagon/HexagonRelocator.h @@ -6,8 +6,8 @@ // License. See LICENSE.TXT for details. // //===----------------------------------------------------------------------===// -#ifndef HEXAGON_RELOCATION_FACTORY_H -#define HEXAGON_RELOCATION_FACTORY_H +#ifndef TARGET_HEXAGON_HEXAGONRELOCATOR_H +#define TARGET_HEXAGON_HEXAGONRELOCATOR_H #ifdef ENABLE_UNITTEST #include <gtest.h> #endif diff --git a/lib/Target/Hexagon/HexagonTargetMachine.h b/lib/Target/Hexagon/HexagonTargetMachine.h index 9b131c1..5ebf434 100644 --- a/lib/Target/Hexagon/HexagonTargetMachine.h +++ b/lib/Target/Hexagon/HexagonTargetMachine.h @@ -6,8 +6,8 @@ // License. See LICENSE.TXT for details. // //===----------------------------------------------------------------------===// -#ifndef MCLD_HEXAGON_TARGET_MACHINE_H -#define MCLD_HEXAGON_TARGET_MACHINE_H +#ifndef TARGET_HEXAGON_HEXAGONTARGETMACHINE_H +#define TARGET_HEXAGON_HEXAGONTARGETMACHINE_H #include "Hexagon.h" #include <mcld/CodeGen/TargetMachine.h> diff --git a/lib/Target/Mips/Mips.h b/lib/Target/Mips/Mips.h index 35be4b4..c3fe7a2 100644 --- a/lib/Target/Mips/Mips.h +++ b/lib/Target/Mips/Mips.h @@ -6,8 +6,8 @@ // License. See LICENSE.TXT for details. // //===----------------------------------------------------------------------===// -#ifndef MCLD_MIPS_H -#define MCLD_MIPS_H +#ifndef TARGET_MIPS_MIPS_H +#define TARGET_MIPS_MIPS_H namespace mcld { diff --git a/lib/Target/Mips/MipsELFDynamic.h b/lib/Target/Mips/MipsELFDynamic.h index bb7e579..35de3e6 100644 --- a/lib/Target/Mips/MipsELFDynamic.h +++ b/lib/Target/Mips/MipsELFDynamic.h @@ -6,8 +6,8 @@ // License. See LICENSE.TXT for details. // //===----------------------------------------------------------------------===// -#ifndef MCLD_Mips_ELFDYNAMIC_SECTION_H -#define MCLD_Mips_ELFDYNAMIC_SECTION_H +#ifndef TARGET_MIPS_MIPSELFDYNAMIC_H +#define TARGET_MIPS_MIPSELFDYNAMIC_H #ifdef ENABLE_UNITTEST #include <gtest.h> #endif diff --git a/lib/Target/Mips/MipsELFMCLinker.h b/lib/Target/Mips/MipsELFMCLinker.h index cdffdd5..bf4b31d 100644 --- a/lib/Target/Mips/MipsELFMCLinker.h +++ b/lib/Target/Mips/MipsELFMCLinker.h @@ -6,8 +6,8 @@ // License. See LICENSE.TXT for details. // //===----------------------------------------------------------------------===// -#ifndef MIPS_ELF_SECTION_LINKER_H -#define MIPS_ELF_SECTION_LINKER_H +#ifndef TARGET_MIPS_MIPSELFMCLINKER_H +#define TARGET_MIPS_MIPSELFMCLINKER_H #ifdef ENABLE_UNITTEST #include <gtest.h> #endif diff --git a/lib/Target/Mips/MipsGNUInfo.h b/lib/Target/Mips/MipsGNUInfo.h index 2e43d80..8b5d9b6 100644 --- a/lib/Target/Mips/MipsGNUInfo.h +++ b/lib/Target/Mips/MipsGNUInfo.h @@ -6,8 +6,8 @@ // License. See LICENSE.TXT for details. // //===----------------------------------------------------------------------===// -#ifndef MCLD_TARGET_MIPS_GNU_INFO_H -#define MCLD_TARGET_MIPS_GNU_INFO_H +#ifndef TARGET_MIPS_MIPSGNUINFO_H +#define TARGET_MIPS_MIPSGNUINFO_H #include <llvm/Support/ELF.h> #include <mcld/Target/GNUInfo.h> diff --git a/lib/Target/Mips/MipsGOT.h b/lib/Target/Mips/MipsGOT.h index e3a9b9e..a2a33e1 100644 --- a/lib/Target/Mips/MipsGOT.h +++ b/lib/Target/Mips/MipsGOT.h @@ -6,8 +6,8 @@ // License. See LICENSE.TXT for details. // //===----------------------------------------------------------------------===// -#ifndef MCLD_MIPS_GOT_H -#define MCLD_MIPS_GOT_H +#ifndef TARGET_MIPS_MIPSGOT_H +#define TARGET_MIPS_MIPSGOT_H #include <map> #include <vector> @@ -79,7 +79,7 @@ public: bool hasMultipleGOT() const; - /// Create GOT entries and reserve dynrel entries. + /// Create GOT entries and reserve dynrel entries. void finalizeScanning(OutputRelocSection& pRelDyn); /// Compare two symbols to define order in the .dynsym. diff --git a/lib/Target/Mips/MipsGOTPLT.h b/lib/Target/Mips/MipsGOTPLT.h index ccf521e..9220f8d 100644 --- a/lib/Target/Mips/MipsGOTPLT.h +++ b/lib/Target/Mips/MipsGOTPLT.h @@ -6,8 +6,8 @@ // License. See LICENSE.TXT for details. // //===----------------------------------------------------------------------===// -#ifndef MCLD_MIPS_GOTPLT_H -#define MCLD_MIPS_GOTPLT_H +#ifndef TARGET_MIPS_MIPSGOTPLT_H +#define TARGET_MIPS_MIPSGOTPLT_H #ifdef ENABLE_UNITTEST #include <gtest.h> #endif diff --git a/lib/Target/Mips/MipsLA25Stub.h b/lib/Target/Mips/MipsLA25Stub.h index 126cfd7..f4b4d9e 100644 --- a/lib/Target/Mips/MipsLA25Stub.h +++ b/lib/Target/Mips/MipsLA25Stub.h @@ -6,8 +6,8 @@ // License. See LICENSE.TXT for details. // //===----------------------------------------------------------------------===// -#ifndef MCLD_MIPS_LA25_STUB_H -#define MCLD_MIPS_LA25_STUB_H +#ifndef TARGET_MIPS_MIPSLA25STUB_H +#define TARGET_MIPS_MIPSLA25STUB_H #ifdef ENABLE_UNITTEST #include <gtest.h> #endif diff --git a/lib/Target/Mips/MipsLDBackend.cpp b/lib/Target/Mips/MipsLDBackend.cpp index a6fd40b..46c580d 100644 --- a/lib/Target/Mips/MipsLDBackend.cpp +++ b/lib/Target/Mips/MipsLDBackend.cpp @@ -548,6 +548,7 @@ bool MipsGNULDBackend::allocateCommonSymbols(Module& pModule) tbss_offset += ObjectBuilder::AppendFragment(*frag, *tbss_sect_data, (*com_sym)->value()); + ObjectBuilder::UpdateSectionAlign(tbss_sect, (*com_sym)->value()); (*com_sym)->setFragmentRef(FragmentRef::Create(*frag, 0)); } // FIXME: how to identify small and large common symbols? @@ -555,6 +556,7 @@ bool MipsGNULDBackend::allocateCommonSymbols(Module& pModule) bss_offset += ObjectBuilder::AppendFragment(*frag, *bss_sect_data, (*com_sym)->value()); + ObjectBuilder::UpdateSectionAlign(bss_sect, (*com_sym)->value()); (*com_sym)->setFragmentRef(FragmentRef::Create(*frag, 0)); } } @@ -576,6 +578,7 @@ bool MipsGNULDBackend::allocateCommonSymbols(Module& pModule) tbss_offset += ObjectBuilder::AppendFragment(*frag, *tbss_sect_data, (*com_sym)->value()); + ObjectBuilder::UpdateSectionAlign(tbss_sect, (*com_sym)->value()); (*com_sym)->setFragmentRef(FragmentRef::Create(*frag, 0)); } // FIXME: how to identify small and large common symbols? @@ -583,6 +586,7 @@ bool MipsGNULDBackend::allocateCommonSymbols(Module& pModule) bss_offset += ObjectBuilder::AppendFragment(*frag, *bss_sect_data, (*com_sym)->value()); + ObjectBuilder::UpdateSectionAlign(bss_sect, (*com_sym)->value()); (*com_sym)->setFragmentRef(FragmentRef::Create(*frag, 0)); } } diff --git a/lib/Target/Mips/MipsLDBackend.h b/lib/Target/Mips/MipsLDBackend.h index 5c4d12b..78c5c58 100644 --- a/lib/Target/Mips/MipsLDBackend.h +++ b/lib/Target/Mips/MipsLDBackend.h @@ -6,8 +6,8 @@ // License. See LICENSE.TXT for details. // //===----------------------------------------------------------------------===// -#ifndef MIPS_LDBACKEND_H -#define MIPS_LDBACKEND_H +#ifndef TARGET_MIPS_MIPSLDBACKEND_H +#define TARGET_MIPS_MIPSLDBACKEND_H #include <mcld/Target/GNULDBackend.h> #include "MipsELFDynamic.h" #include "MipsGOT.h" diff --git a/lib/Target/Mips/MipsPLT.cpp b/lib/Target/Mips/MipsPLT.cpp index a00b7c8..81c05c0 100644 --- a/lib/Target/Mips/MipsPLT.cpp +++ b/lib/Target/Mips/MipsPLT.cpp @@ -64,19 +64,19 @@ public: MipsPLT::MipsPLT(LDSection& pSection) : PLT(pSection) { - new MipsPLT0(*m_SectionData); - m_Last = m_SectionData->begin(); + new MipsPLT0(*m_pSectionData); + m_Last = m_pSectionData->begin(); } void MipsPLT::finalizeSectionSize() { uint64_t size = sizeof(PLT0) + - (m_SectionData->size() - 1) * sizeof(PLTA); + (m_pSectionData->size() - 1) * sizeof(PLTA); m_Section.setSize(size); uint32_t offset = 0; - SectionData::iterator frag, fragEnd = m_SectionData->end(); - for (frag = m_SectionData->begin(); frag != fragEnd; ++frag) { + SectionData::iterator frag, fragEnd = m_pSectionData->end(); + for (frag = m_pSectionData->begin(); frag != fragEnd; ++frag) { frag->setOffset(offset); offset += frag->size(); } @@ -84,7 +84,7 @@ void MipsPLT::finalizeSectionSize() bool MipsPLT::hasPLT1() const { - return m_SectionData->size() > 1; + return m_pSectionData->size() > 1; } uint64_t MipsPLT::emit(MemoryRegion& pRegion) @@ -109,7 +109,7 @@ uint64_t MipsPLT::emit(MemoryRegion& pRegion) void MipsPLT::reserveEntry(size_t pNum) { for (size_t i = 0; i < pNum; ++i) { - Fragment* entry = new (std::nothrow) MipsPLTA(*m_SectionData); + Fragment* entry = new (std::nothrow) MipsPLTA(*m_pSectionData); if (NULL == entry) fatal(diag::fail_allocate_memory_plt); @@ -119,7 +119,7 @@ void MipsPLT::reserveEntry(size_t pNum) Fragment* MipsPLT::consume() { ++m_Last; - assert(m_Last != m_SectionData->end() && + assert(m_Last != m_pSectionData->end() && "The number of PLT Entries and ResolveInfo doesn't match"); return &(*m_Last); } @@ -129,10 +129,10 @@ void MipsPLT::applyAllPLT(MipsGOTPLT& pGOTPLT) assert(m_Section.addr() && ".plt base address is NULL!"); size_t count = 0; - for (iterator it = m_SectionData->begin(); it != m_SectionData->end(); ++it) { + for (iterator it = m_pSectionData->begin(); it != m_pSectionData->end(); ++it) { PLTEntryBase* plt = &(llvm::cast<PLTEntryBase>(*it)); - if (it == m_SectionData->begin()) { + if (it == m_pSectionData->begin()) { uint32_t* data = static_cast<uint32_t*>(malloc(plt->size())); if (!data) diff --git a/lib/Target/Mips/MipsPLT.h b/lib/Target/Mips/MipsPLT.h index f2ad0c8..a1d1b4a 100644 --- a/lib/Target/Mips/MipsPLT.h +++ b/lib/Target/Mips/MipsPLT.h @@ -6,8 +6,8 @@ // License. See LICENSE.TXT for details. // //===----------------------------------------------------------------------===// -#ifndef MCLD_TARGET_MIPS_PLT_H -#define MCLD_TARGET_MIPS_PLT_H +#ifndef TARGET_MIPS_MIPSPLT_H +#define TARGET_MIPS_MIPSPLT_H #include <mcld/Target/PLT.h> #include <mcld/Support/MemoryRegion.h> diff --git a/lib/Target/Mips/MipsRelocator.cpp b/lib/Target/Mips/MipsRelocator.cpp index 314a6ad..8f1c5e2 100644 --- a/lib/Target/Mips/MipsRelocator.cpp +++ b/lib/Target/Mips/MipsRelocator.cpp @@ -795,7 +795,7 @@ void Mips64Relocator::setupRelDynEntry(FragmentRef& pFragRef, ResolveInfo* pSym) static MipsRelocator::Result none(MipsRelocationInfo& pReloc, MipsRelocator& pParent) { - return MipsRelocator::OK; + return Relocator::OK; } // R_MIPS_32: S + A @@ -814,17 +814,17 @@ MipsRelocator::Result abs32(MipsRelocationInfo& pReloc, MipsRelocator& pParent) // but perform static relocation. (e.g., applying .debug section) if (0x0 == (llvm::ELF::SHF_ALLOC & target_sect.flag())) { pReloc.result() = S + A; - return MipsRelocator::OK; + return Relocator::OK; } if (rsym->reserved() & MipsRelocator::ReserveRel) { pParent.createDynRel(pReloc); - return MipsRelocator::OK; + return Relocator::OK; } pReloc.result() = S + A; - return MipsRelocator::OK; + return Relocator::OK; } // R_MIPS_26: @@ -848,7 +848,7 @@ MipsRelocator::Result rel26(MipsRelocationInfo& pReloc, MipsRelocator& pParent) pReloc.result() = (pReloc.result() + S) >> 2; - return MipsRelocator::OK; + return Relocator::OK; } // R_MIPS_HI16: @@ -872,7 +872,7 @@ MipsRelocator::Result hi16(MipsRelocationInfo& pReloc, MipsRelocator& pParent) pReloc.result() = ((AHL + S) - (int16_t)(AHL + S)) >> 16; } - return MipsRelocator::OK; + return Relocator::OK; } // R_MIPS_LO16: @@ -898,7 +898,7 @@ MipsRelocator::Result lo16(MipsRelocationInfo& pReloc, MipsRelocator& pParent) pParent.applyPostponedRelocations(pReloc); - return MipsRelocator::OK; + return Relocator::OK; } // R_MIPS_GPREL16: @@ -919,7 +919,7 @@ MipsRelocator::Result gprel16(MipsRelocationInfo& pReloc, MipsRelocator& pParent else pReloc.result() = A + S - GP; - return MipsRelocator::OK; + return Relocator::OK; } // R_MIPS_GOT16: @@ -943,7 +943,7 @@ MipsRelocator::Result got16(MipsRelocationInfo& pReloc, MipsRelocator& pParent) pReloc.result() = pParent.getGOTOffset(pReloc); } - return MipsRelocator::OK; + return Relocator::OK; } // R_MIPS_GOTHI16: @@ -956,7 +956,7 @@ MipsRelocator::Result gothi16(MipsRelocationInfo& pReloc, MipsRelocator& pParent pReloc.result() = (G - (int16_t)G) >> (16 + A); - return MipsRelocator::OK; + return Relocator::OK; } // R_MIPS_GOTLO16: @@ -966,7 +966,7 @@ MipsRelocator::Result gotlo16(MipsRelocationInfo& pReloc, MipsRelocator& pParent { pReloc.result() = pParent.getGOTOffset(pReloc) & 0xffff; - return MipsRelocator::OK; + return Relocator::OK; } // R_MIPS_SUB: @@ -979,7 +979,7 @@ MipsRelocator::Result sub(MipsRelocationInfo& pReloc, MipsRelocator& pParent) pReloc.result() = S - A; - return MipsRelocator::OK; + return Relocator::OK; } // R_MIPS_CALL16: G @@ -988,7 +988,7 @@ MipsRelocator::Result call16(MipsRelocationInfo& pReloc, MipsRelocator& pParent) { pReloc.result() = pParent.getGOTOffset(pReloc); - return MipsRelocator::OK; + return Relocator::OK; } // R_MIPS_GPREL32: A + S + GP0 - GP @@ -1003,7 +1003,7 @@ MipsRelocator::Result gprel32(MipsRelocationInfo& pReloc, MipsRelocator& pParent pReloc.result() = A + S + GP0 - GP; - return MipsRelocator::OK; + return Relocator::OK; } // R_MIPS_64: S + A @@ -1024,17 +1024,17 @@ MipsRelocator::Result abs64(MipsRelocationInfo& pReloc, MipsRelocator& pParent) // but perform static relocation. (e.g., applying .debug section) if (0x0 == (llvm::ELF::SHF_ALLOC & target_sect.flag())) { pReloc.result() = S + A; - return MipsRelocator::OK; + return Relocator::OK; } if (rsym->reserved() & MipsRelocator::ReserveRel) { pParent.createDynRel(pReloc); - return MipsRelocator::OK; + return Relocator::OK; } pReloc.result() = S + A; - return MipsRelocator::OK; + return Relocator::OK; } // R_MIPS_GOT_DISP / R_MIPS_GOT_PAGE: G @@ -1043,7 +1043,7 @@ MipsRelocator::Result gotdisp(MipsRelocationInfo& pReloc, MipsRelocator& pParent { pReloc.result() = pParent.getGOTOffset(pReloc); - return MipsRelocator::OK; + return Relocator::OK; } // R_MIPS_GOT_OFST: @@ -1051,14 +1051,14 @@ static MipsRelocator::Result gotoff(MipsRelocationInfo& pReloc, MipsRelocator& pParent) { // FIXME (simon): Needs to be implemented. - return MipsRelocator::OK; + return Relocator::OK; } // R_MIPS_JALR: static MipsRelocator::Result jalr(MipsRelocationInfo& pReloc, MipsRelocator& pParent) { - return MipsRelocator::OK; + return Relocator::OK; } // R_MIPS_LA25_LUI @@ -1069,7 +1069,7 @@ MipsRelocator::Result la25lui(MipsRelocationInfo& pReloc, MipsRelocator& pParent pReloc.result() = (S + 0x8000) >> 16; - return MipsRelocator::OK; + return Relocator::OK; } // R_MIPS_LA25_J @@ -1080,7 +1080,7 @@ MipsRelocator::Result la25j(MipsRelocationInfo& pReloc, MipsRelocator& pParent) pReloc.result() = S >> 2; - return MipsRelocator::OK; + return Relocator::OK; } // R_MIPS_LA25_ADD @@ -1089,18 +1089,18 @@ MipsRelocator::Result la25add(MipsRelocationInfo& pReloc, MipsRelocator& pParent { pReloc.result() = pReloc.S(); - return MipsRelocator::OK; + return Relocator::OK; } // R_MIPS_PC32: static MipsRelocator::Result pc32(MipsRelocationInfo& pReloc, MipsRelocator& pParent) { - return MipsRelocator::OK; + return Relocator::OK; } static MipsRelocator::Result unsupport(MipsRelocationInfo& pReloc, MipsRelocator& pParent) { - return MipsRelocator::Unsupport; + return Relocator::Unsupport; } diff --git a/lib/Target/Mips/MipsRelocator.h b/lib/Target/Mips/MipsRelocator.h index 4e24329..9394a7b 100644 --- a/lib/Target/Mips/MipsRelocator.h +++ b/lib/Target/Mips/MipsRelocator.h @@ -6,8 +6,8 @@ // License. See LICENSE.TXT for details. // //===----------------------------------------------------------------------===// -#ifndef MIPS_RELOCATION_FACTORY_H -#define MIPS_RELOCATION_FACTORY_H +#ifndef TARGET_MIPS_MIPSRELOCATOR_H +#define TARGET_MIPS_MIPSRELOCATOR_H #ifdef ENABLE_UNITTEST #include <gtest.h> #endif diff --git a/lib/Target/Mips/MipsTargetMachine.h b/lib/Target/Mips/MipsTargetMachine.h index 964a6d1..955d10a 100644 --- a/lib/Target/Mips/MipsTargetMachine.h +++ b/lib/Target/Mips/MipsTargetMachine.h @@ -6,8 +6,8 @@ // License. See LICENSE.TXT for details. // //===----------------------------------------------------------------------===// -#ifndef MIPS_TARGET_MACHINE_H -#define MIPS_TARGET_MACHINE_H +#ifndef TARGET_MIPS_MIPSTARGETMACHINE_H +#define TARGET_MIPS_MIPSTARGETMACHINE_H #include <mcld/CodeGen/TargetMachine.h> diff --git a/lib/Target/PLT.cpp b/lib/Target/PLT.cpp index 60e219e..6f9524e 100644 --- a/lib/Target/PLT.cpp +++ b/lib/Target/PLT.cpp @@ -20,7 +20,7 @@ class GOT; PLT::PLT(LDSection& pSection) :m_Section(pSection) { - m_SectionData = IRBuilder::CreateSectionData(pSection); + m_pSectionData = IRBuilder::CreateSectionData(pSection); } PLT::~PLT() diff --git a/lib/Target/X86/X86.h b/lib/Target/X86/X86.h index 5927f44..5090a67 100644 --- a/lib/Target/X86/X86.h +++ b/lib/Target/X86/X86.h @@ -6,8 +6,8 @@ // License. See LICENSE.TXT for details. // //===----------------------------------------------------------------------===// -#ifndef MCLD_TARGET_X86_H -#define MCLD_TARGET_X86_H +#ifndef TARGET_X86_X86_H +#define TARGET_X86_X86_H #include <string> namespace llvm { diff --git a/lib/Target/X86/X86ELFDynamic.cpp b/lib/Target/X86/X86ELFDynamic.cpp index c74cc13..74611c5 100644 --- a/lib/Target/X86/X86ELFDynamic.cpp +++ b/lib/Target/X86/X86ELFDynamic.cpp @@ -33,6 +33,5 @@ void X86ELFDynamic::applyTargetEntries(const ELFFileFormat& pFormat) { // applyPLTGOT if (pFormat.hasGOTPLT()) - applyOne(llvm::ELF::DT_PLTGOT, pFormat.getGOTPLT().addr()); + applyOne(llvm::ELF::DT_PLTGOT, pFormat.getGOTPLT().addr()); } - diff --git a/lib/Target/X86/X86ELFDynamic.h b/lib/Target/X86/X86ELFDynamic.h index e3d5338..aac3482 100644 --- a/lib/Target/X86/X86ELFDynamic.h +++ b/lib/Target/X86/X86ELFDynamic.h @@ -6,8 +6,8 @@ // License. See LICENSE.TXT for details. // //===----------------------------------------------------------------------===// -#ifndef MCLD_X86_ELFDYNAMIC_SECTION_H -#define MCLD_X86_ELFDYNAMIC_SECTION_H +#ifndef TARGET_X86_X86ELFDYNAMIC_H +#define TARGET_X86_X86ELFDYNAMIC_H #ifdef ENABLE_UNITTEST #include <gtest.h> #endif diff --git a/lib/Target/X86/X86ELFMCLinker.h b/lib/Target/X86/X86ELFMCLinker.h index 4b64d28..9dfe0e7 100644 --- a/lib/Target/X86/X86ELFMCLinker.h +++ b/lib/Target/X86/X86ELFMCLinker.h @@ -6,8 +6,8 @@ // License. See LICENSE.TXT for details. // //===----------------------------------------------------------------------===// -#ifndef X86_ELFSECTLINKER_H -#define X86_ELFSECTLINKER_H +#ifndef TARGET_X86_X86ELFMCLINKER_H +#define TARGET_X86_X86ELFMCLINKER_H #ifdef ENABLE_UNITTEST #include <gtest.h> #endif diff --git a/lib/Target/X86/X86GNUInfo.h b/lib/Target/X86/X86GNUInfo.h index 65b0451..da4cb24 100644 --- a/lib/Target/X86/X86GNUInfo.h +++ b/lib/Target/X86/X86GNUInfo.h @@ -6,8 +6,8 @@ // License. See LICENSE.TXT for details. // //===----------------------------------------------------------------------===// -#ifndef MCLD_TARGET_X86_GNU_INFO_H -#define MCLD_TARGET_X86_GNU_INFO_H +#ifndef TARGET_X86_X86GNUINFO_H +#define TARGET_X86_X86GNUINFO_H #include <mcld/Target/GNUInfo.h> #include <llvm/Support/ELF.h> diff --git a/lib/Target/X86/X86GOT.h b/lib/Target/X86/X86GOT.h index 67c3163..91647b9 100644 --- a/lib/Target/X86/X86GOT.h +++ b/lib/Target/X86/X86GOT.h @@ -6,8 +6,8 @@ // License. See LICENSE.TXT for details. // //===----------------------------------------------------------------------===// -#ifndef MCLD_TARGET_X86_GOT_H -#define MCLD_TARGET_X86_GOT_H +#ifndef TARGET_X86_X86GOT_H +#define TARGET_X86_X86GOT_H #ifdef ENABLE_UNITTEST #include <gtest.h> #endif diff --git a/lib/Target/X86/X86GOTPLT.h b/lib/Target/X86/X86GOTPLT.h index 8e13fac..0c12388 100644 --- a/lib/Target/X86/X86GOTPLT.h +++ b/lib/Target/X86/X86GOTPLT.h @@ -6,8 +6,8 @@ // License. See LICENSE.TXT for details. // //===----------------------------------------------------------------------===// -#ifndef MCLD_X86_GOTPLT_H -#define MCLD_X86_GOTPLT_H +#ifndef TARGET_X86_X86GOTPLT_H +#define TARGET_X86_X86GOTPLT_H #ifdef ENABLE_UNITTEST #include <gtest.h> #endif diff --git a/lib/Target/X86/X86LDBackend.cpp b/lib/Target/X86/X86LDBackend.cpp index 04e858c..f105dd3 100644 --- a/lib/Target/X86/X86LDBackend.cpp +++ b/lib/Target/X86/X86LDBackend.cpp @@ -34,8 +34,8 @@ using namespace mcld; // X86GNULDBackend //===----------------------------------------------------------------------===// X86GNULDBackend::X86GNULDBackend(const LinkerConfig& pConfig, - GNUInfo* pInfo, - Relocation::Type pCopyRel) + GNUInfo* pInfo, + Relocation::Type pCopyRel) : GNULDBackend(pConfig, pInfo), m_pRelocator(NULL), m_pPLT(NULL), @@ -132,8 +132,7 @@ const X86ELFDynamic& X86GNULDBackend::dynamic() const return *m_pDynamic; } -void X86GNULDBackend::defineGOTSymbol(IRBuilder& pBuilder, - Fragment& pFrag) +void X86GNULDBackend::defineGOTSymbol(IRBuilder& pBuilder, Fragment& pFrag) { // define symbol _GLOBAL_OFFSET_TABLE_ if (m_pGOTSymbol != NULL) { @@ -345,7 +344,7 @@ void X86GNULDBackend::doCreateProgramHdrs(Module& pModule) } X86_32GNULDBackend::X86_32GNULDBackend(const LinkerConfig& pConfig, - GNUInfo* pInfo) + GNUInfo* pInfo) : X86GNULDBackend(pConfig, pInfo, llvm::ELF::R_386_COPY), m_pGOT (NULL), m_pGOTPLT (NULL) { @@ -366,7 +365,7 @@ bool X86_32GNULDBackend::initRelocator() } void X86_32GNULDBackend::initTargetSections(Module& pModule, - ObjectBuilder& pBuilder) + ObjectBuilder& pBuilder) { if (LinkerConfig::Object != config().codeGenType()) { ELFFileFormat* file_format = getOutputFormat(); @@ -381,9 +380,7 @@ void X86_32GNULDBackend::initTargetSections(Module& pModule, // initialize .plt LDSection& plt = file_format->getPLT(); plt.setAlign(16u); - m_pPLT = new X86_32PLT(plt, - *m_pGOTPLT, - config()); + m_pPLT = new X86_32PLT(plt, *m_pGOTPLT, config()); // initialize .rel.plt LDSection& relplt = file_format->getRelPlt(); @@ -524,7 +521,7 @@ uint64_t X86_32GNULDBackend::emitGOTSectionData(MemoryRegion& pRegion) const } uint64_t X86_32GNULDBackend::emitGOTPLTSectionData(MemoryRegion& pRegion, - const ELFFileFormat* FileFormat) const + const ELFFileFormat* FileFormat) const { assert(m_pGOTPLT && "emitGOTPLTSectionData failed, m_pGOTPLT is NULL!"); m_pGOTPLT->applyGOT0(FileFormat->getDynamic().addr()); @@ -547,7 +544,7 @@ uint64_t X86_32GNULDBackend::emitGOTPLTSectionData(MemoryRegion& pRegion, } X86_64GNULDBackend::X86_64GNULDBackend(const LinkerConfig& pConfig, - GNUInfo* pInfo) + GNUInfo* pInfo) : X86GNULDBackend(pConfig, pInfo, llvm::ELF::R_X86_64_COPY), m_pGOT (NULL), m_pGOTPLT (NULL) { @@ -659,7 +656,7 @@ void X86_64GNULDBackend::setRelPLTSize() } void X86_64GNULDBackend::initTargetSections(Module& pModule, - ObjectBuilder& pBuilder) + ObjectBuilder& pBuilder) { if (LinkerConfig::Object != config().codeGenType()) { ELFFileFormat* file_format = getOutputFormat(); @@ -674,9 +671,7 @@ void X86_64GNULDBackend::initTargetSections(Module& pModule, // initialize .plt LDSection& plt = file_format->getPLT(); plt.setAlign(16u); - m_pPLT = new X86_64PLT(plt, - *m_pGOTPLT, - config()); + m_pPLT = new X86_64PLT(plt, *m_pGOTPLT, config()); // initialize .rela.plt LDSection& relplt = file_format->getRelaPlt(); @@ -725,8 +720,9 @@ uint64_t X86_64GNULDBackend::emitGOTSectionData(MemoryRegion& pRegion) const return RegionSize; } -uint64_t X86_64GNULDBackend::emitGOTPLTSectionData(MemoryRegion& pRegion, - const ELFFileFormat* FileFormat) const +uint64_t +X86_64GNULDBackend::emitGOTPLTSectionData(MemoryRegion& pRegion, + const ELFFileFormat* FileFormat) const { assert(m_pGOTPLT && "emitGOTPLTSectionData failed, m_pGOTPLT is NULL!"); m_pGOTPLT->applyGOT0(FileFormat->getDynamic().addr()); @@ -774,10 +770,10 @@ TargetLDBackend* createX86LDBackend(const LinkerConfig& pConfig) llvm::Triple::ArchType arch = pConfig.targets().triple().getArch(); if (arch == llvm::Triple::x86) return new X86_32GNULDBackend(pConfig, - new X86_32GNUInfo(pConfig.targets().triple())); + new X86_32GNUInfo(pConfig.targets().triple())); assert (arch == llvm::Triple::x86_64); return new X86_64GNULDBackend(pConfig, - new X86_64GNUInfo(pConfig.targets().triple())); + new X86_64GNUInfo(pConfig.targets().triple())); } } // namespace of mcld diff --git a/lib/Target/X86/X86LDBackend.h b/lib/Target/X86/X86LDBackend.h index 4ef5311..779c2d1 100644 --- a/lib/Target/X86/X86LDBackend.h +++ b/lib/Target/X86/X86LDBackend.h @@ -6,8 +6,8 @@ // License. See LICENSE.TXT for details. // //===----------------------------------------------------------------------===// -#ifndef X86_LDBACKEND_H -#define X86_LDBACKEND_H +#ifndef TARGET_X86_X86LDBACKEND_H +#define TARGET_X86_X86LDBACKEND_H #include "X86ELFDynamic.h" #include "X86GOT.h" @@ -29,8 +29,8 @@ class X86GNULDBackend : public GNULDBackend { public: X86GNULDBackend(const LinkerConfig& pConfig, - GNUInfo* pInfo, - Relocation::Type pCopyRel); + GNUInfo* pInfo, + Relocation::Type pCopyRel); ~X86GNULDBackend(); @@ -124,8 +124,9 @@ private: virtual uint64_t emitGOTSectionData(MemoryRegion& pRegion) const = 0; - virtual uint64_t emitGOTPLTSectionData(MemoryRegion& pRegion, - const ELFFileFormat* FileFormat) const = 0; + virtual uint64_t + emitGOTPLTSectionData(MemoryRegion& pRegion, + const ELFFileFormat* FileFormat) const = 0; virtual void setRelDynSize() = 0; virtual void setRelPLTSize() = 0; @@ -182,7 +183,7 @@ private: uint64_t emitGOTSectionData(MemoryRegion& pRegion) const; uint64_t emitGOTPLTSectionData(MemoryRegion& pRegion, - const ELFFileFormat* FileFormat) const; + const ELFFileFormat* FileFormat) const; void setRelDynSize(); void setRelPLTSize(); @@ -225,7 +226,7 @@ private: uint64_t emitGOTSectionData(MemoryRegion& pRegion) const; uint64_t emitGOTPLTSectionData(MemoryRegion& pRegion, - const ELFFileFormat* FileFormat) const; + const ELFFileFormat* FileFormat) const; void setRelDynSize(); void setRelPLTSize(); diff --git a/lib/Target/X86/X86PLT.cpp b/lib/Target/X86/X86PLT.cpp index d73693b..09b25c4 100644 --- a/lib/Target/X86/X86PLT.cpp +++ b/lib/Target/X86/X86PLT.cpp @@ -54,9 +54,7 @@ X86_64PLT1::X86_64PLT1(SectionData& pParent) //===----------------------------------------------------------------------===// // X86PLT //===----------------------------------------------------------------------===// -X86PLT::X86PLT(LDSection& pSection, - const LinkerConfig& pConfig, - int got_size) +X86PLT::X86PLT(LDSection& pSection, const LinkerConfig& pConfig, int got_size) : PLT(pSection), m_Config(pConfig) { @@ -71,7 +69,7 @@ X86PLT::X86PLT(LDSection& pSection, m_PLT0Size = sizeof (x86_32_dyn_plt0); m_PLT1Size = sizeof (x86_32_dyn_plt1); // create PLT0 - new X86_32DynPLT0(*m_SectionData); + new X86_32DynPLT0(*m_pSectionData); } else { m_PLT0 = x86_32_exec_plt0; @@ -79,7 +77,7 @@ X86PLT::X86PLT(LDSection& pSection, m_PLT0Size = sizeof (x86_32_exec_plt0); m_PLT1Size = sizeof (x86_32_exec_plt1); // create PLT0 - new X86_32ExecPLT0(*m_SectionData); + new X86_32ExecPLT0(*m_pSectionData); } } else { @@ -89,7 +87,7 @@ X86PLT::X86PLT(LDSection& pSection, m_PLT0Size = sizeof (x86_64_plt0); m_PLT1Size = sizeof (x86_64_plt1); // create PLT0 - new X86_64PLT0(*m_SectionData); + new X86_64PLT0(*m_pSectionData); } } @@ -109,13 +107,13 @@ void X86PLT::finalizeSectionSize() if (end() != it) { // plt1 size PLTEntryBase* plt1 = &(llvm::cast<PLTEntryBase>(*it)); - size += (m_SectionData->size() - 1) * plt1->size(); + size += (m_pSectionData->size() - 1) * plt1->size(); } m_Section.setSize(size); uint32_t offset = 0; - SectionData::iterator frag, fragEnd = m_SectionData->end(); - for (frag = m_SectionData->begin(); frag != fragEnd; ++frag) { + SectionData::iterator frag, fragEnd = m_pSectionData->end(); + for (frag = m_pSectionData->begin(); frag != fragEnd; ++frag) { frag->setOffset(offset); offset += frag->size(); } @@ -123,22 +121,22 @@ void X86PLT::finalizeSectionSize() bool X86PLT::hasPLT1() const { - return (m_SectionData->size() > 1); + return (m_pSectionData->size() > 1); } PLTEntryBase* X86PLT::create() { if (LinkerConfig::DynObj == m_Config.codeGenType()) - return new X86_32DynPLT1(*m_SectionData); + return new X86_32DynPLT1(*m_pSectionData); else - return new X86_32ExecPLT1(*m_SectionData); + return new X86_32ExecPLT1(*m_pSectionData); } PLTEntryBase* X86PLT::getPLT0() const { - iterator first = m_SectionData->getFragmentList().begin(); + iterator first = m_pSectionData->getFragmentList().begin(); - assert(first != m_SectionData->getFragmentList().end() && + assert(first != m_pSectionData->getFragmentList().end() && "FragmentList is empty, getPLT0 failed!"); PLTEntryBase* plt0 = &(llvm::cast<PLTEntryBase>(*first)); @@ -150,8 +148,8 @@ PLTEntryBase* X86PLT::getPLT0() const // X86_32PLT //===----------------------------------------------------------------------===// X86_32PLT::X86_32PLT(LDSection& pSection, - X86_32GOTPLT& pGOTPLT, - const LinkerConfig& pConfig) + X86_32GOTPLT& pGOTPLT, + const LinkerConfig& pConfig) : X86PLT(pSection, pConfig, 32), m_GOTPLT(pGOTPLT) { } @@ -184,8 +182,8 @@ void X86_32PLT::applyPLT1() { assert(m_Section.addr() && ".plt base address is NULL!"); - X86PLT::iterator it = m_SectionData->begin(); - X86PLT::iterator ie = m_SectionData->end(); + X86PLT::iterator it = m_pSectionData->begin(); + X86PLT::iterator ie = m_pSectionData->end(); assert(it != ie && "FragmentList is empty, applyPLT1 failed!"); uint64_t GOTEntrySize = X86_32GOTEntry::EntrySize; @@ -236,8 +234,8 @@ void X86_32PLT::applyPLT1() // X86_64PLT //===----------------------------------------------------------------------===// X86_64PLT::X86_64PLT(LDSection& pSection, - X86_64GOTPLT& pGOTPLT, - const LinkerConfig& pConfig) + X86_64GOTPLT& pGOTPLT, + const LinkerConfig& pConfig) : X86PLT(pSection, pConfig, 64), m_GOTPLT(pGOTPLT) { } @@ -270,8 +268,8 @@ void X86_64PLT::applyPLT1() { assert(m_Section.addr() && ".plt base address is NULL!"); - X86PLT::iterator it = m_SectionData->begin(); - X86PLT::iterator ie = m_SectionData->end(); + X86PLT::iterator it = m_pSectionData->begin(); + X86PLT::iterator ie = m_pSectionData->end(); assert(it != ie && "FragmentList is empty, applyPLT1 failed!"); uint64_t GOTEntrySize = X86_64GOTEntry::EntrySize; diff --git a/lib/Target/X86/X86PLT.h b/lib/Target/X86/X86PLT.h index 2578d67..a220efc 100644 --- a/lib/Target/X86/X86PLT.h +++ b/lib/Target/X86/X86PLT.h @@ -6,8 +6,8 @@ // License. See LICENSE.TXT for details. // //===----------------------------------------------------------------------===// -#ifndef MCLD_TARGET_X86_PLT_H -#define MCLD_TARGET_X86_PLT_H +#ifndef TARGET_X86_X86PLT_H +#define TARGET_X86_X86PLT_H #include <mcld/Target/PLT.h> @@ -110,7 +110,7 @@ class X86PLT : public PLT public: X86PLT(LDSection& pSection, const LinkerConfig& pConfig, - int got_size); + int got_size); ~X86PLT(); // finalizeSectionSize - set LDSection size @@ -150,8 +150,8 @@ class X86_32PLT : public X86PLT { public: X86_32PLT(LDSection& pSection, - X86_32GOTPLT& pGOTPLT, - const LinkerConfig& pConfig); + X86_32GOTPLT& pGOTPLT, + const LinkerConfig& pConfig); void applyPLT0(); @@ -171,8 +171,8 @@ class X86_64PLT : public X86PLT { public: X86_64PLT(LDSection& pSection, - X86_64GOTPLT& pGOTPLT, - const LinkerConfig& pConfig); + X86_64GOTPLT& pGOTPLT, + const LinkerConfig& pConfig); void applyPLT0(); diff --git a/lib/Target/X86/X86Relocator.cpp b/lib/Target/X86/X86Relocator.cpp index 6e3234f..8cc916e 100644 --- a/lib/Target/X86/X86Relocator.cpp +++ b/lib/Target/X86/X86Relocator.cpp @@ -32,7 +32,7 @@ static Relocation& helper_DynRel_init(ResolveInfo* pSym, Fragment& pFrag, uint64_t pOffset, - X86Relocator::Type pType, + Relocator::Type pType, X86_32Relocator& pParent) { X86_32GNULDBackend& ld_backend = pParent.getTarget(); @@ -65,7 +65,7 @@ helper_use_relative_reloc(const ResolveInfo& pSym, static X86_32GOTEntry& helper_GOT_init(Relocation& pReloc, bool pHasRel, - X86_32Relocator& pParent) + X86_32Relocator& pParent) { // rsym - The relocation target symbol ResolveInfo* rsym = pReloc.symInfo(); @@ -96,13 +96,13 @@ X86_32GOTEntry& helper_GOT_init(Relocation& pReloc, } static -X86Relocator::Address helper_GOT_ORG(X86_32Relocator& pParent) +Relocator::Address helper_GOT_ORG(X86_32Relocator& pParent) { return pParent.getTarget().getGOTPLT().addr(); } static -X86Relocator::Address helper_get_GOT_address(Relocation& pReloc, +Relocator::Address helper_get_GOT_address(Relocation& pReloc, X86_32Relocator& pParent) { X86_32GOTEntry* got_entry = pParent.getSymGOTMap().lookUp(*pReloc.symInfo()); @@ -135,8 +135,8 @@ PLTEntryBase& helper_PLT_init(Relocation& pReloc, X86_32Relocator& pParent) return *plt_entry; } -static -X86Relocator::Address helper_get_PLT_address(ResolveInfo& pSym, X86_32Relocator& pParent) +static Relocator::Address +helper_get_PLT_address(ResolveInfo& pSym, X86_32Relocator& pParent) { PLTEntryBase* plt_entry = pParent.getSymPLTMap().lookUp(pSym); assert(NULL != plt_entry); @@ -150,7 +150,7 @@ DECL_X86_32_APPLY_RELOC_FUNCS /// the prototype of applying function typedef Relocator::Result (*X86_32ApplyFunctionType)(Relocation& pReloc, - X86_32Relocator& pParent); + X86_32Relocator& pParent); // the table entry of applying functions struct X86_32ApplyFunctionTriple @@ -802,36 +802,37 @@ void X86_32Relocator::convertTLSIEtoLE(Relocation& pReloc, assert(pReloc.type() == llvm::ELF::R_386_TLS_IE); assert(NULL != pReloc.targetRef().frag()); - // 1. create the fragment references and new relocs - uint64_t off = pReloc.targetRef().offset(); - if (off >= 4) - off -= 4; - else - off = 0; - - FragmentRef* fragref = FragmentRef::Create(*pReloc.targetRef().frag(), off); - Relocation* reloc = Relocation::Create(X86_32Relocator::R_386_TLS_OPT, - *fragref, - 0x0); + // 1. create the new relocs + Relocation* reloc = + Relocation::Create(X86_32Relocator::R_386_TLS_OPT, + *FragmentRef::Create(*pReloc.targetRef().frag(), + pReloc.targetRef().offset() - 1), + 0x0); // FIXME: should we create a special symbol for the tls opt instead? reloc->setSymInfo(pReloc.symInfo()); // 2. modify the opcodes to the appropriate ones uint8_t* op = (reinterpret_cast<uint8_t*>(&reloc->target())); - off = pReloc.targetRef().offset() - reloc->targetRef().offset() - 1; - if (op[off] == 0xa1) { - op[off] = 0xb8; + if (op[0] == 0xa1) { + op[0] = 0xb8; } else { - switch (op[off - 1]) { + // create the new reloc (move 1 byte forward). + reloc = Relocation::Create(X86_32Relocator::R_386_TLS_OPT, + *FragmentRef::Create(*pReloc.targetRef().frag(), + pReloc.targetRef().offset() - 2), + 0x0); + reloc->setSymInfo(pReloc.symInfo()); + op = (reinterpret_cast<uint8_t*>(&reloc->target())); + switch (op[0]) { case 0x8b: - assert((op[off] & 0xc7) == 0x05); - op[off - 1] = 0xc7; - op[off] = 0xc0 | ((op[off] >> 3) & 7); + assert((op[1] & 0xc7) == 0x05); + op[0] = 0xc7; + op[1] = 0xc0 | ((op[1] >> 3) & 7); break; case 0x03: - assert((op[off] & 0xc7) == 0x05); - op[off - 1] = 0x81; - op[off] = 0xc0 | ((op[off] >> 3) & 7); + assert((op[1] & 0xc7) == 0x05); + op[0] = 0x81; + op[1] = 0xc0 | ((op[1] >> 3) & 7); break; default: assert(0); @@ -840,6 +841,7 @@ void X86_32Relocator::convertTLSIEtoLE(Relocation& pReloc, } // 3. insert the new relocs "BEFORE" the original reloc. + assert(reloc != NULL); pSection.getRelocData()->getRelocationList().insert( RelocData::iterator(pReloc), reloc); @@ -852,15 +854,15 @@ void X86_32Relocator::convertTLSIEtoLE(Relocation& pReloc, //================================================// // R_386_NONE -X86Relocator::Result none(Relocation& pReloc, X86_32Relocator& pParent) +Relocator::Result none(Relocation& pReloc, X86_32Relocator& pParent) { - return X86Relocator::OK; + return Relocator::OK; } // R_386_32: S + A // R_386_16 // R_386_8 -X86Relocator::Result abs(Relocation& pReloc, X86_32Relocator& pParent) +Relocator::Result abs(Relocation& pReloc, X86_32Relocator& pParent) { ResolveInfo* rsym = pReloc.symInfo(); Relocator::DWord A = pReloc.target() + pReloc.addend(); @@ -876,7 +878,7 @@ X86Relocator::Result abs(Relocation& pReloc, X86_32Relocator& pParent) // but perform static relocation. (e.g., applying .debug section) if (0x0 == (llvm::ELF::SHF_ALLOC & target_sect.flag())) { pReloc.target() = S + A; - return X86Relocator::OK; + return Relocator::OK; } // An external symbol may need PLT and dynamic relocation @@ -890,18 +892,18 @@ X86Relocator::Result abs(Relocation& pReloc, X86_32Relocator& pParent) if (has_dyn_rel) if (llvm::ELF::R_386_32 != pReloc.type() || (!helper_use_relative_reloc(*rsym, pParent))) - return X86Relocator::OK; + return Relocator::OK; } // perform static relocation pReloc.target() = S + A; - return X86Relocator::OK; + return Relocator::OK; } // R_386_PC32: S + A - P // R_386_PC16 // R_386_PC8 -X86Relocator::Result rel(Relocation& pReloc, X86_32Relocator& pParent) +Relocator::Result rel(Relocation& pReloc, X86_32Relocator& pParent) { ResolveInfo* rsym = pReloc.symInfo(); Relocator::DWord A = pReloc.target() + pReloc.addend(); @@ -917,7 +919,7 @@ X86Relocator::Result rel(Relocation& pReloc, X86_32Relocator& pParent) // but perform static relocation. (e.g., applying .debug section) if (0x0 == (llvm::ELF::SHF_ALLOC & target_sect.flag())) { pReloc.target() = S + A - P; - return X86Relocator::OK; + return Relocator::OK; } // An external symbol may need PLT and dynamic relocation @@ -928,41 +930,41 @@ X86Relocator::Result rel(Relocation& pReloc, X86_32Relocator& pParent) } if (has_dyn_rel) if (!helper_use_relative_reloc(*rsym, pParent)) - return X86Relocator::OK; + return Relocator::OK; } // perform static relocation pReloc.target() = S + A - P; - return X86Relocator::OK; + return Relocator::OK; } // R_386_GOTOFF: S + A - GOT_ORG -X86Relocator::Result gotoff32(Relocation& pReloc, X86_32Relocator& pParent) +Relocator::Result gotoff32(Relocation& pReloc, X86_32Relocator& pParent) { Relocator::DWord A = pReloc.target() + pReloc.addend(); - X86Relocator::Address GOT_ORG = helper_GOT_ORG(pParent); - X86Relocator::Address S = pReloc.symValue(); + Relocator::Address GOT_ORG = helper_GOT_ORG(pParent); + Relocator::Address S = pReloc.symValue(); pReloc.target() = S + A - GOT_ORG; - return X86Relocator::OK; + return Relocator::OK; } // R_386_GOTPC: GOT_ORG + A - P -X86Relocator::Result gotpc32(Relocation& pReloc, X86_32Relocator& pParent) +Relocator::Result gotpc32(Relocation& pReloc, X86_32Relocator& pParent) { Relocator::DWord A = pReloc.target() + pReloc.addend(); - X86Relocator::Address GOT_ORG = helper_GOT_ORG(pParent); + Relocator::Address GOT_ORG = helper_GOT_ORG(pParent); // Apply relocation. pReloc.target() = GOT_ORG + A - pReloc.place(); - return X86Relocator::OK; + return Relocator::OK; } // R_386_GOT32: GOT(S) + A - GOT_ORG -X86Relocator::Result got32(Relocation& pReloc, X86_32Relocator& pParent) +Relocator::Result got32(Relocation& pReloc, X86_32Relocator& pParent) { ResolveInfo* rsym = pReloc.symInfo(); if (!(rsym->reserved() & (X86Relocator::ReserveGOT))) - return X86Relocator::BadReloc; + return Relocator::BadReloc; // set up got entry value if the got has no dyn rel or // the dyn rel is RELATIVE @@ -971,37 +973,37 @@ X86Relocator::Result got32(Relocation& pReloc, X86_32Relocator& pParent) if (got_entry->getValue() == X86Relocator::SymVal) got_entry->setValue(pReloc.symValue()); - X86Relocator::Address GOT_S = helper_get_GOT_address(pReloc, pParent); + Relocator::Address GOT_S = helper_get_GOT_address(pReloc, pParent); Relocator::DWord A = pReloc.target() + pReloc.addend(); - X86Relocator::Address GOT_ORG = helper_GOT_ORG(pParent); + Relocator::Address GOT_ORG = helper_GOT_ORG(pParent); // Apply relocation. pReloc.target() = GOT_S + A - GOT_ORG; - return X86Relocator::OK; + return Relocator::OK; } // R_386_PLT32: PLT(S) + A - P -X86Relocator::Result plt32(Relocation& pReloc, X86_32Relocator& pParent) +Relocator::Result plt32(Relocation& pReloc, X86_32Relocator& pParent) { // PLT_S depends on if there is a PLT entry. - X86Relocator::Address PLT_S; + Relocator::Address PLT_S; if ((pReloc.symInfo()->reserved() & X86Relocator::ReservePLT)) PLT_S = helper_get_PLT_address(*pReloc.symInfo(), pParent); else PLT_S = pReloc.symValue(); Relocator::DWord A = pReloc.target() + pReloc.addend(); - X86Relocator::Address P = pReloc.place(); + Relocator::Address P = pReloc.place(); pReloc.target() = PLT_S + A - P; - return X86Relocator::OK; + return Relocator::OK; } // R_386_TLS_GD: -X86Relocator::Result tls_gd(Relocation& pReloc, X86_32Relocator& pParent) +Relocator::Result tls_gd(Relocation& pReloc, X86_32Relocator& pParent) { // global-dynamic ResolveInfo* rsym = pReloc.symInfo(); // must reserve two pairs of got and dynamic relocation if (!(rsym->reserved() & X86Relocator::ReserveGOT)) - return X86Relocator::BadReloc; + return Relocator::BadReloc; ELFFileFormat* file_format = pParent.getTarget().getOutputFormat(); // setup corresponding got and dynamic relocatio entries: @@ -1018,16 +1020,16 @@ X86Relocator::Result tls_gd(Relocation& pReloc, X86_32Relocator& pParent) Relocator::DWord A = pReloc.target() + pReloc.addend(); // GOT_OFF - the offset between the got_entry1 and _GLOBAL_OFFSET_TABLE (the // .got.plt section) - X86Relocator::Address GOT_OFF = + Relocator::Address GOT_OFF = file_format->getGOT().addr() + got_entry1->getOffset() - file_format->getGOTPLT().addr(); pReloc.target() = GOT_OFF + A; - return X86Relocator::OK; + return Relocator::OK; } // R_386_TLS_LDM -X86Relocator::Result tls_ldm(Relocation& pReloc, X86_32Relocator& pParent) +Relocator::Result tls_ldm(Relocation& pReloc, X86_32Relocator& pParent) { // FIXME: no linker optimization for TLS relocation const X86_32GOTEntry& got_entry = pParent.getTLSModuleID(); @@ -1039,46 +1041,46 @@ X86Relocator::Result tls_ldm(Relocation& pReloc, X86_32Relocator& pParent) Relocator::DWord A = pReloc.target() + pReloc.addend(); pReloc.target() = GOT_S + A; - return X86Relocator::OK; + return Relocator::OK; } // R_386_TLS_LDO_32 -X86Relocator::Result tls_ldo_32(Relocation& pReloc, X86_32Relocator& pParent) +Relocator::Result tls_ldo_32(Relocation& pReloc, X86_32Relocator& pParent) { // FIXME: no linker optimization for TLS relocation Relocator::DWord A = pReloc.target() + pReloc.addend(); - X86Relocator::Address S = pReloc.symValue(); + Relocator::Address S = pReloc.symValue(); pReloc.target() = S + A; - return X86Relocator::OK; + return Relocator::OK; } // R_X86_TLS_IE -X86Relocator::Result tls_ie(Relocation& pReloc, X86_32Relocator& pParent) +Relocator::Result tls_ie(Relocation& pReloc, X86_32Relocator& pParent) { ResolveInfo* rsym = pReloc.symInfo(); if (!(rsym->reserved() & X86Relocator::ReserveGOT)) { - return X86Relocator::BadReloc; + return Relocator::BadReloc; } // set up the got and dynamic relocation entries if not exist X86_32GOTEntry* got_entry = pParent.getSymGOTMap().lookUp(*rsym); assert(NULL != got_entry); // perform relocation to the absolute address of got_entry - X86Relocator::Address GOT_S = - pParent.getTarget().getGOT().addr() + got_entry->getOffset(); + Relocator::Address GOT_S = + pParent.getTarget().getGOT().addr() + got_entry->getOffset(); Relocator::DWord A = pReloc.target() + pReloc.addend(); pReloc.target() = GOT_S + A; - return X86Relocator::OK; + return Relocator::OK; } // R_386_TLS_GOTIE -X86Relocator::Result tls_gotie(Relocation& pReloc, X86_32Relocator& pParent) +Relocator::Result tls_gotie(Relocation& pReloc, X86_32Relocator& pParent) { ResolveInfo* rsym = pReloc.symInfo(); if (!(rsym->reserved() & X86Relocator::ReserveGOT)) { - return X86Relocator::BadReloc; + return Relocator::BadReloc; } // set up the got and dynamic relocation entries if not exist @@ -1091,14 +1093,14 @@ X86Relocator::Result tls_gotie(Relocation& pReloc, X86_32Relocator& pParent) Relocator::DWord A = pReloc.target() + pReloc.addend(); pReloc.target() = GOT_S + A; - return X86Relocator::OK; + return Relocator::OK; } // R_X86_TLS_LE -X86Relocator::Result tls_le(Relocation& pReloc, X86_32Relocator& pParent) +Relocator::Result tls_le(Relocation& pReloc, X86_32Relocator& pParent) { if (pReloc.symInfo()->reserved() & X86Relocator::ReserveRel) - return X86Relocator::OK; + return Relocator::OK; // perform static relocation // get TLS segment @@ -1108,14 +1110,14 @@ X86Relocator::Result tls_le(Relocation& pReloc, X86_32Relocator& pParent) 0x0); assert(tls_seg != pParent.getTarget().elfSegmentTable().end()); Relocator::DWord A = pReloc.target() + pReloc.addend(); - X86Relocator::Address S = pReloc.symValue(); + Relocator::Address S = pReloc.symValue(); pReloc.target() = S + A - (*tls_seg)->memsz(); - return X86Relocator::OK; + return Relocator::OK; } -X86Relocator::Result unsupport(Relocation& pReloc, X86_32Relocator& pParent) +Relocator::Result unsupport(Relocation& pReloc, X86_32Relocator& pParent) { - return X86Relocator::Unsupport; + return Relocator::Unsupport; } //===--------------------------------------------------------------------===// @@ -1126,7 +1128,7 @@ static Relocation& helper_DynRel_init(ResolveInfo* pSym, Fragment& pFrag, uint64_t pOffset, - X86Relocator::Type pType, + Relocator::Type pType, X86_64Relocator& pParent) { X86_64GNULDBackend& ld_backend = pParent.getTarget(); @@ -1193,14 +1195,14 @@ X86_64GOTEntry& helper_GOT_init(Relocation& pReloc, } static -X86Relocator::Address helper_GOT_ORG(X86_64Relocator& pParent) +Relocator::Address helper_GOT_ORG(X86_64Relocator& pParent) { return pParent.getTarget().getGOT().addr(); } static -X86Relocator::Address helper_get_GOT_address(Relocation& pReloc, - X86_64Relocator& pParent) +Relocator::Address helper_get_GOT_address(Relocation& pReloc, + X86_64Relocator& pParent) { X86_64GOTEntry* got_entry = pParent.getSymGOTMap().lookUp(*pReloc.symInfo()); assert(NULL != got_entry); @@ -1208,8 +1210,8 @@ X86Relocator::Address helper_get_GOT_address(Relocation& pReloc, } static -X86Relocator::Address helper_get_PLT_address(ResolveInfo& pSym, - X86_64Relocator& pParent) +Relocator::Address helper_get_PLT_address(ResolveInfo& pSym, + X86_64Relocator& pParent) { PLTEntryBase* plt_entry = pParent.getSymPLTMap().lookUp(pSym); assert(NULL != plt_entry); @@ -1248,7 +1250,7 @@ DECL_X86_64_APPLY_RELOC_FUNCS /// the prototype of applying function typedef Relocator::Result (*X86_64ApplyFunctionType)(Relocation& pReloc, - X86_64Relocator& pParent); + X86_64Relocator& pParent); // the table entry of applying functions struct X86_64ApplyFunctionTriple @@ -1426,7 +1428,7 @@ void X86_64Relocator::scanGlobalReloc(Relocation& pReloc, *this); getRelRelMap().record(pReloc, reloc); } - getTarget().checkAndSetHasTextRel(*pSection.getLink()); + getTarget().checkAndSetHasTextRel(*pSection.getLink()); } } return; @@ -1497,12 +1499,12 @@ void X86_64Relocator::scanGlobalReloc(Relocation& pReloc, // All other dynamic relocations may lead to run-time relocation // overflow. if (getTarget().isDynamicSymbol(*rsym) && - getTarget().symbolNeedsDynRel(*rsym, + getTarget().symbolNeedsDynRel(*rsym, (rsym->reserved() & ReservePLT), false) && - getTarget().symbolNeedsCopyReloc(pReloc, *rsym)) { - LDSymbol& cpy_sym = defineSymbolforCopyReloc(pBuilder, *rsym, getTarget()); - addCopyReloc(*cpy_sym.resolveInfo(), getTarget()); + getTarget().symbolNeedsCopyReloc(pReloc, *rsym)) { + LDSymbol& cpy_sym = defineSymbolforCopyReloc(pBuilder, *rsym, getTarget()); + addCopyReloc(*cpy_sym.resolveInfo(), getTarget()); } return; @@ -1517,16 +1519,16 @@ void X86_64Relocator::scanGlobalReloc(Relocation& pReloc, // // === // R_X86_64_NONE -X86Relocator::Result none(Relocation& pReloc, X86_64Relocator& pParent) +Relocator::Result none(Relocation& pReloc, X86_64Relocator& pParent) { - return X86Relocator::OK; + return Relocator::OK; } // R_X86_64_64: S + A // R_X86_64_32: // R_X86_64_16: // R_X86_64_8 -X86Relocator::Result abs(Relocation& pReloc, X86_64Relocator& pParent) +Relocator::Result abs(Relocation& pReloc, X86_64Relocator& pParent) { ResolveInfo* rsym = pReloc.symInfo(); Relocator::DWord A = pReloc.target() + pReloc.addend(); @@ -1539,13 +1541,13 @@ X86Relocator::Result abs(Relocation& pReloc, X86_64Relocator& pParent) // but perform static relocation. (e.g., applying .debug section) if (0x0 == (llvm::ELF::SHF_ALLOC & target_sect.flag())) { pReloc.target() = S + A; - return X86Relocator::OK; + return Relocator::OK; } // A local symbol may need RELA Type dynamic relocation if (rsym->isLocal() && has_dyn_rel) { dyn_rel->setAddend(S + A); - return X86Relocator::OK; + return Relocator::OK; } // An external symbol may need PLT and dynamic relocation @@ -1563,18 +1565,18 @@ X86Relocator::Result abs(Relocation& pReloc, X86_64Relocator& pParent) } else { dyn_rel->setAddend(A); - return X86Relocator::OK; + return Relocator::OK; } } } // perform static relocation pReloc.target() = S + A; - return X86Relocator::OK; + return Relocator::OK; } // R_X86_64_32S: S + A -X86Relocator::Result signed32(Relocation& pReloc, X86_64Relocator& pParent) +Relocator::Result signed32(Relocation& pReloc, X86_64Relocator& pParent) { ResolveInfo* rsym = pReloc.symInfo(); Relocator::DWord A = pReloc.target() + pReloc.addend(); @@ -1582,7 +1584,7 @@ X86Relocator::Result signed32(Relocation& pReloc, X86_64Relocator& pParent) // There should be no dynamic relocations for R_X86_64_32S. if (NULL != pParent.getRelRelMap().lookUp(pReloc)) - return X86Relocator::BadReloc; + return Relocator::BadReloc; LDSection& target_sect = pReloc.targetRef().frag()->getParent()->getSection(); // If the flag of target section is not ALLOC, we will not scan this relocation @@ -1596,19 +1598,19 @@ X86Relocator::Result signed32(Relocation& pReloc, X86_64Relocator& pParent) // Check 32-bit signed overflow. Relocator::SWord V = S + A; if (V > INT64_C(0x7fffffff) || V < INT64_C(-0x80000000)) - return X86Relocator::Overflow; + return Relocator::Overflow; #endif // perform static relocation pReloc.target() = S + A; - return X86Relocator::OK; + return Relocator::OK; } // R_X86_64_GOTPCREL: GOT(S) + GOT_ORG + A - P -X86Relocator::Result gotpcrel(Relocation& pReloc, X86_64Relocator& pParent) +Relocator::Result gotpcrel(Relocation& pReloc, X86_64Relocator& pParent) { if (!(pReloc.symInfo()->reserved() & X86Relocator::ReserveGOT)) { - return X86Relocator::BadReloc; + return Relocator::BadReloc; } // set symbol value of the got entry if needed @@ -1622,33 +1624,33 @@ X86Relocator::Result gotpcrel(Relocation& pReloc, X86_64Relocator& pParent) dyn_rel->setAddend(pReloc.symValue()); } - X86Relocator::Address GOT_S = helper_get_GOT_address(pReloc, pParent); - Relocator::DWord A = pReloc.target() + pReloc.addend(); - X86Relocator::Address GOT_ORG = helper_GOT_ORG(pParent); + Relocator::Address GOT_S = helper_get_GOT_address(pReloc, pParent); + Relocator::DWord A = pReloc.target() + pReloc.addend(); + Relocator::Address GOT_ORG = helper_GOT_ORG(pParent); // Apply relocation. pReloc.target() = GOT_S + GOT_ORG + A - pReloc.place(); - return X86Relocator::OK; + return Relocator::OK; } // R_X86_64_PLT32: PLT(S) + A - P -X86Relocator::Result plt32(Relocation& pReloc, X86_64Relocator& pParent) +Relocator::Result plt32(Relocation& pReloc, X86_64Relocator& pParent) { // PLT_S depends on if there is a PLT entry. - X86Relocator::Address PLT_S; + Relocator::Address PLT_S; if ((pReloc.symInfo()->reserved() & X86Relocator::ReservePLT)) PLT_S = helper_get_PLT_address(*pReloc.symInfo(), pParent); else PLT_S = pReloc.symValue(); - Relocator::DWord A = pReloc.target() + pReloc.addend(); - X86Relocator::Address P = pReloc.place(); + Relocator::DWord A = pReloc.target() + pReloc.addend(); + Relocator::Address P = pReloc.place(); pReloc.target() = PLT_S + A - P; - return X86Relocator::OK; + return Relocator::OK; } // R_X86_64_PC32: S + A - P // R_X86_64_PC16 // R_X86_64_PC8 -X86Relocator::Result rel(Relocation& pReloc, X86_64Relocator& pParent) +Relocator::Result rel(Relocation& pReloc, X86_64Relocator& pParent) { ResolveInfo* rsym = pReloc.symInfo(); Relocator::DWord A = pReloc.target() + pReloc.addend(); @@ -1660,7 +1662,7 @@ X86Relocator::Result rel(Relocation& pReloc, X86_64Relocator& pParent) // but perform static relocation. (e.g., applying .debug section) if (0x0 == (llvm::ELF::SHF_ALLOC & target_sect.flag())) { pReloc.target() = S + A - P; - return X86Relocator::OK; + return Relocator::OK; } // setup relocation addend if needed @@ -1678,16 +1680,16 @@ X86Relocator::Result rel(Relocation& pReloc, X86_64Relocator& pParent) *rsym, (rsym->reserved() & X86Relocator::ReservePLT), false)) { - return X86Relocator::Overflow; + return Relocator::Overflow; } } // perform static relocation pReloc.target() = S + A - P; - return X86Relocator::OK; + return Relocator::OK; } -X86Relocator::Result unsupport(Relocation& pReloc, X86_64Relocator& pParent) +Relocator::Result unsupport(Relocation& pReloc, X86_64Relocator& pParent) { - return X86Relocator::Unsupport; + return Relocator::Unsupport; } diff --git a/lib/Target/X86/X86Relocator.h b/lib/Target/X86/X86Relocator.h index da67464..596c15b 100644 --- a/lib/Target/X86/X86Relocator.h +++ b/lib/Target/X86/X86Relocator.h @@ -6,8 +6,8 @@ // License. See LICENSE.TXT for details. // //===----------------------------------------------------------------------===// -#ifndef X86_RELOCATION_FACTORY_H -#define X86_RELOCATION_FACTORY_H +#ifndef TARGET_X86_X86RELOCATOR_H +#define TARGET_X86_X86RELOCATOR_H #ifdef ENABLE_UNITTEST #include <gtest.h> #endif diff --git a/lib/Target/X86/X86TargetMachine.h b/lib/Target/X86/X86TargetMachine.h index b9d78e1..c3893da 100644 --- a/lib/Target/X86/X86TargetMachine.h +++ b/lib/Target/X86/X86TargetMachine.h @@ -6,8 +6,8 @@ // License. See LICENSE.TXT for details. // //===----------------------------------------------------------------------===// -#ifndef MCLD_X86_TARGET_MACHINE_H -#define MCLD_X86_TARGET_MACHINE_H +#ifndef TARGET_X86_X86TARGETMACHINE_H +#define TARGET_X86_X86TARGETMACHINE_H #include "X86.h" #include <mcld/CodeGen/TargetMachine.h> diff --git a/templates/implTest.cpp b/templates/implTest.cpp index fbfdf05..660fde5 100644 --- a/templates/implTest.cpp +++ b/templates/implTest.cpp @@ -36,7 +36,7 @@ void ${class_name}Test::TearDown() //===----------------------------------------------------------------------===// // Testcases //===----------------------------------------------------------------------===// -/** +/** TEST_F( ${class_name}Test, name of the testcase for ${class_name} ) { Write you exercise here } diff --git a/tools/mcld/main.cpp b/tools/mcld/main.cpp index dcb8140..a10f1af 100644 --- a/tools/mcld/main.cpp +++ b/tools/mcld/main.cpp @@ -230,9 +230,9 @@ OverrideStackAlignment("stack-alignment", // --script is an alias, but cl::alias doesn't work correctly with cl::list. static cl::list<std::string> ArgLinkerScript("T", - cl::ZeroOrMore, - cl::desc("Linker script"), - cl::value_desc("file")); + cl::ZeroOrMore, + cl::desc("Linker script"), + cl::value_desc("file")); static cl::opt<std::string> TrapFuncName("trap-func", cl::Hidden, @@ -258,36 +258,41 @@ SegmentedStacks("segmented-stacks", //===----------------------------------------------------------------------===// // Bitcode Options //===----------------------------------------------------------------------===// -static cl::opt<mcld::sys::fs::Path, false, llvm::cl::parser<mcld::sys::fs::Path> > +static +cl::opt<mcld::sys::fs::Path, false, llvm::cl::parser<mcld::sys::fs::Path> > ArgBitcodeFilename("dB", - cl::desc("set default bitcode"), - cl::value_desc("bitcode")); + cl::desc("set default bitcode"), + cl::value_desc("bitcode")); //===----------------------------------------------------------------------===// // General Options //===----------------------------------------------------------------------===// -static cl::opt<mcld::sys::fs::Path, false, llvm::cl::parser<mcld::sys::fs::Path> > +static +cl::opt<mcld::sys::fs::Path, false, llvm::cl::parser<mcld::sys::fs::Path> > ArgOutputFilename("o", - cl::desc("Output filename"), - cl::value_desc("filename")); + cl::desc("Output filename"), + cl::value_desc("filename")); static cl::alias AliasOutputFilename("output", cl::desc("alias for -o"), cl::aliasopt(ArgOutputFilename)); -static cl::opt<mcld::sys::fs::Path, false, llvm::cl::parser<mcld::sys::fs::Path> > +static +cl::opt<mcld::sys::fs::Path, false, llvm::cl::parser<mcld::sys::fs::Path> > ArgSysRoot("sysroot", - cl::desc("Use directory as the location of the sysroot, overriding the configure-time default."), + cl::desc("Use directory as the location of the sysroot, overriding " + "the configure-time default."), cl::value_desc("directory"), cl::ValueRequired); static cl::list<std::string, bool, llvm::cl::SearchDirParser> ArgSearchDirList("L", - cl::ZeroOrMore, - cl::desc("Add path searchdir to the list of paths that ld will search for archive libraries and ld control scripts."), - cl::value_desc("searchdir"), - cl::Prefix); + cl::ZeroOrMore, + cl::desc("Add path searchdir to the list of paths that ld will search for " + "archive libraries and ld control scripts."), + cl::value_desc("searchdir"), + cl::Prefix); static cl::alias ArgSearchDirListAlias("library-path", @@ -306,7 +311,8 @@ ArgTraceAlias("trace", static cl::opt<int> ArgVerbose("verbose", cl::init(-1), - cl::desc("Display the version number for ld and list the linker emulations supported.")); + cl::desc("Display the version number for ld and list the linker " + "emulations supported.")); static cl::opt<bool> ArgVersion("V", @@ -325,7 +331,8 @@ ArgMaxWarnNum("warning-limit", static cl::opt<std::string> ArgEntry("e", - cl::desc("Use entry as the explicit symbol for beginning execution of your program."), + cl::desc("Use entry as the explicit symbol for beginning execution of " + "your program."), cl::value_desc("entry"), cl::ValueRequired); @@ -336,13 +343,14 @@ ArgEntryAlias("entry", static cl::opt<bool> ArgBsymbolic("Bsymbolic", + cl::ZeroOrMore, cl::desc("Bind references within the shared library."), cl::init(false)); static cl::opt<bool> ArgBgroup("Bgroup", - cl::desc("Info the dynamic linker to perform lookups only inside the group."), - cl::init(false)); + cl::desc("Info the dynamic linker to perform lookups only inside the group."), + cl::init(false)); static cl::opt<std::string> ArgSOName("soname", @@ -351,6 +359,7 @@ ArgSOName("soname", static cl::opt<bool> ArgNoUndefined("no-undefined", + cl::ZeroOrMore, cl::desc("Do not allow unresolved references"), cl::init(false)); @@ -361,9 +370,10 @@ ArgAllowMulDefs("allow-multiple-definition", static cl::opt<bool> ArgEhFrameHdr("eh-frame-hdr", - cl::ZeroOrMore, - cl::desc("Request creation of \".eh_frame_hdr\" section and ELF \"PT_GNU_EH_FRAME\" segment header."), - cl::init(false)); + cl::ZeroOrMore, + cl::desc("Request creation of \".eh_frame_hdr\" section and ELF \"" + "PT_GNU_EH_FRAME\" segment header."), + cl::init(false)); static cl::list<mcld::ZOption, bool, llvm::cl::parser<mcld::ZOption> > ArgZOptionList("z", @@ -376,20 +386,21 @@ cl::opt<mcld::CodeGenFileType> ArgFileType("filetype", cl::init(mcld::CGFT_EXEFile), cl::desc("Choose a file type (not all types are supported by all targets):"), cl::values( - clEnumValN(mcld::CGFT_ASMFile, "asm", - "Emit an assembly ('.s') file"), - clEnumValN(mcld::CGFT_OBJFile, "obj", - "Emit a relocatable object ('.o') file"), - clEnumValN(mcld::CGFT_DSOFile, "dso", - "Emit an dynamic shared object ('.so') file"), - clEnumValN(mcld::CGFT_EXEFile, "exe", - "Emit a executable ('.exe') file"), - clEnumValN(mcld::CGFT_NULLFile, "null", - "Emit nothing, for performance testing"), - clEnumValEnd)); + clEnumValN(mcld::CGFT_ASMFile, "asm", + "Emit an assembly ('.s') file"), + clEnumValN(mcld::CGFT_OBJFile, "obj", + "Emit a relocatable object ('.o') file"), + clEnumValN(mcld::CGFT_DSOFile, "dso", + "Emit an dynamic shared object ('.so') file"), + clEnumValN(mcld::CGFT_EXEFile, "exe", + "Emit a executable ('.exe') file"), + clEnumValN(mcld::CGFT_NULLFile, "null", + "Emit nothing, for performance testing"), + clEnumValEnd)); static cl::opt<bool> ArgShared("shared", + cl::ZeroOrMore, cl::desc("Create a shared library."), cl::init(false)); @@ -419,19 +430,19 @@ ArgRelocModel("relocation-model", cl::init(Reloc::Default), cl::values( clEnumValN(Reloc::Default, "default", - "Target default relocation model"), + "Target default relocation model"), clEnumValN(Reloc::Static, "static", - "Non-relocatable code"), + "Non-relocatable code"), clEnumValN(Reloc::PIC_, "pic", - "Fully relocatable, position independent code"), + "Fully relocatable, position independent code"), clEnumValN(Reloc::DynamicNoPIC, "dynamic-no-pic", - "Relocatable external references, non-relocatable code"), + "Relocatable external references, non-relocatable code"), clEnumValEnd)); static cl::opt<bool> ArgFPIC("fPIC", - cl::desc("Set relocation model to pic. The same as -relocation-model=pic."), - cl::init(false)); + cl::desc("Set relocation model to pic. The same as -relocation-model=pic."), + cl::init(false)); static cl::opt<std::string> ArgDyld("dynamic-linker", @@ -483,7 +494,7 @@ ArgDiscardAllAlias("x", static cl::opt<bool> ArgStripDebug("strip-debug", - cl::desc("Omit debugger symbol information from the output file."), + cl::desc("Omit debug symbol information from the output file."), cl::init(false)); static cl::alias @@ -543,21 +554,42 @@ ArgGenUnwindInfoFlag("ld-generated-unwind-info", " generated code sections like PLT."), cl::init(true), cl::ValueDisallowed); -/// @{ -/// @{ -/// @name FIXME: begin of unsupported options -/// @} + static cl::opt<bool> ArgGCSections("gc-sections", - cl::ZeroOrMore, - cl::desc("Enable garbage collection of unused input sections."), - cl::init(false)); + cl::ZeroOrMore, + cl::desc("Enable garbage collection of unused input sections."), + cl::init(false)); static cl::opt<bool> ArgNoGCSections("no-gc-sections", - cl::ZeroOrMore, - cl::desc("disable garbage collection of unused input sections."), - cl::init(false)); + cl::ZeroOrMore, + cl::desc("disable garbage collection of unused input sections."), + cl::init(false)); + +static cl::opt<std::string> +ArgEmulation("m", + cl::ZeroOrMore, + cl::desc("Set GNU linker emulation"), + cl::value_desc("emulation"), + cl::Prefix); + +static cl::opt<mcld::GeneralOptions::HashStyle> +ArgHashStyle("hash-style", cl::init(mcld::GeneralOptions::SystemV), + cl::desc("Set the type of linker's hash table(s)."), + cl::values( + clEnumValN(mcld::GeneralOptions::SystemV, "sysv", + "classic ELF .hash section"), + clEnumValN(mcld::GeneralOptions::GNU, "gnu", + "new style GNU .gnu.hash section"), + clEnumValN(mcld::GeneralOptions::Both, "both", + "both the classic ELF and new style GNU hash tables"), + clEnumValEnd)); + +/// @{ +/// @{ +/// @name FIXME: begin of unsupported options +/// @} namespace icf { enum Mode { @@ -569,17 +601,18 @@ enum Mode { static cl::opt<icf::Mode> ArgICF("icf", - cl::ZeroOrMore, - cl::desc("Identical Code Folding"), - cl::init(icf::None), - cl::values( - clEnumValN(icf::None, "none", - "do not perform cold folding"), - clEnumValN(icf::All, "all", - "always preform cold folding"), - clEnumValN(icf::Safe, "safe", - "Folds ctors, dtors and functions whose pointers are definitely not taken."), - clEnumValEnd)); + cl::ZeroOrMore, + cl::desc("Identical Code Folding"), + cl::init(icf::None), + cl::values( + clEnumValN(icf::None, "none", + "do not perform cold folding"), + clEnumValN(icf::All, "all", + "always preform cold folding"), + clEnumValN(icf::Safe, "safe", + "Folds ctors, dtors and functions whose pointers are definitely not " + "taken."), + clEnumValEnd)); // FIXME: add this to target options? static cl::opt<bool> @@ -597,18 +630,11 @@ ArgExportDynamicAlias("E", cl::desc("alias for --export-dynamic"), cl::aliasopt(ArgExportDynamic)); -static cl::opt<std::string> -ArgEmulation("m", - cl::ZeroOrMore, - cl::desc("Set GNU linker emulation"), - cl::value_desc("emulation"), - cl::Prefix); - static cl::list<std::string, bool, llvm::cl::SearchDirParser> ArgRuntimePathLink("rpath-link", - cl::ZeroOrMore, - cl::desc("Add a directory to the link time library search path"), - cl::value_desc("dir")); + cl::ZeroOrMore, + cl::desc("Add a directory to the link time library search path"), + cl::value_desc("dir")); static cl::list<std::string> ArgExcludeLIBS("exclude-libs", @@ -618,9 +644,9 @@ ArgExcludeLIBS("exclude-libs", static cl::opt<std::string> ArgBuildID("build-id", - cl::desc("Request creation of \".note.gnu.build-id\" ELF note section."), - cl::value_desc("style"), - cl::ValueOptional); + cl::desc("Request creation of \".note.gnu.build-id\" ELF note section."), + cl::value_desc("style"), + cl::ValueOptional); static cl::opt<std::string> ArgForceUndefined("u", @@ -642,18 +668,6 @@ ArgWarnCommon("warn-common", cl::desc("warn common symbol"), cl::init(false)); -static cl::opt<mcld::GeneralOptions::HashStyle> -ArgHashStyle("hash-style", cl::init(mcld::GeneralOptions::SystemV), - cl::desc("Set the type of linker's hash table(s)."), - cl::values( - clEnumValN(mcld::GeneralOptions::SystemV, "sysv", - "classic ELF .hash section"), - clEnumValN(mcld::GeneralOptions::GNU, "gnu", - "new style GNU .gnu.hash section"), - clEnumValN(mcld::GeneralOptions::Both, "both", - "both the classic ELF and new style GNU hash tables"), - clEnumValEnd)); - static cl::opt<std::string> ArgFilter("F", cl::desc("Filter for shared object symbol table"), @@ -677,28 +691,29 @@ ArgAuxiliaryAlias("auxiliary", static cl::opt<bool> ArgUseGold("use-gold", - cl::desc("GCC/collect2 compatibility: uses ld.gold. Ignored"), + cl::desc("GCC/collect2 compatibility: uses ld.gold. Ignored"), cl::init(false)); static cl::opt<bool> ArgUseMCLD("use-mcld", - cl::desc("GCC/collect2 compatibility: uses ld.mcld. Ignored"), + cl::desc("GCC/collect2 compatibility: uses ld.mcld. Ignored"), cl::init(false)); static cl::opt<bool> ArgUseLD("use-ld", - cl::desc("GCC/collect2 compatibility: uses ld.bfd. Ignored"), + cl::desc("GCC/collect2 compatibility: uses ld.bfd. Ignored"), cl::init(false)); static cl::opt<bool> ArgEB("EB", - cl::desc("Link big-endian objects. This affects the default output format."), - cl::init(false)); + cl::desc("Link big-endian objects. This affects the default output format."), + cl::init(false)); static cl::opt<bool> ArgEL("EL", - cl::desc("Link little-endian objects. This affects the default output format."), - cl::init(false)); + cl::desc("Link little-endian objects. This affects the default output " + "format."), + cl::init(false)); static cl::list<std::string> ArgPlugin("plugin", @@ -712,8 +727,8 @@ ArgPluginOpt("plugin-opt", static cl::opt<bool> ArgSVR4Compatibility("Qy", - cl::desc("This option is ignored for SVR4 compatibility"), - cl::init(false)); + cl::desc("This option is ignored for SVR4 compatibility"), + cl::init(false)); static cl::list<std::string> ArgY("Y", @@ -769,20 +784,22 @@ static bool ArgFatalWarnings; static cl::opt<bool, true, cl::FalseParser> ArgNoFatalWarnings("no-fatal-warnings", - cl::location(ArgFatalWarnings), - cl::desc("do not turn warnings into errors"), - cl::init(false), - cl::ValueDisallowed); + cl::location(ArgFatalWarnings), + cl::desc("do not turn warnings into errors"), + cl::init(false), + cl::ValueDisallowed); static cl::opt<bool, true> ArgFatalWarningsFlag("fatal-warnings", - cl::location(ArgFatalWarnings), - cl::desc("turn all warnings into errors"), - cl::init(false), - cl::ValueDisallowed); + cl::ZeroOrMore, + cl::location(ArgFatalWarnings), + cl::desc("turn all warnings into errors"), + cl::init(false), + cl::ValueDisallowed); static cl::opt<bool> ArgWarnSharedTextrel("warn-shared-textrel", + cl::ZeroOrMore, cl::desc("Warn if adding DT_TEXTREL in a shared object."), cl::init(false)); @@ -853,10 +870,10 @@ ArgPortList("portable", static cl::list<std::string> ArgAddressMapList("section-start", - cl::ZeroOrMore, - cl::desc("Locate a output section at the given absolute address"), - cl::value_desc("Set address of section"), - cl::Prefix); + cl::ZeroOrMore, + cl::desc("Locate a output section at the given absolute address"), + cl::value_desc("Set address of section"), + cl::Prefix); static cl::opt<unsigned long long> ArgBssSegAddr("Tbss", @@ -882,11 +899,12 @@ ArgTextSegAddrAlias("Ttext-segment", // non-member functions //===----------------------------------------------------------------------===// /// GetOutputStream - get the output stream. -static mcld::ToolOutputFile *GetOutputStream(const char* pTargetName, - Triple::OSType pOSType, - mcld::CodeGenFileType pFileType, - const mcld::sys::fs::Path& pInputFilename, - mcld::sys::fs::Path& pOutputFilename) +static +mcld::ToolOutputFile *GetOutputStream(const char* pTargetName, + Triple::OSType pOSType, + mcld::CodeGenFileType pFileType, + const mcld::sys::fs::Path& pInputFilename, + mcld::sys::fs::Path& pOutputFilename) { if (pOutputFilename.empty()) { if (0 == pInputFilename.native().compare("-")) @@ -1036,6 +1054,7 @@ static std::string ParseProgName(const char *progname) static Triple ParseEmulation(const std::string& pEmulation) { Triple result = StringSwitch<Triple>(pEmulation) + .Case("aarch64linux", Triple("aarch64", "", "linux", "gnu")) .Case("armelf_linux_eabi", Triple("arm", "", "linux", "gnueabi")) .Case("elf_i386", Triple("i386", "", "", "gnu")) .Case("elf_x86_64", Triple("x86_64", "", "", "gnu")) @@ -1073,7 +1092,7 @@ static bool ProcessLinkerOptionsFromCommand(mcld::LinkerScript& pScript, break; case color::Auto: bool color_option = ShouldColorize() && - llvm::sys::Process::FileDescriptorIsDisplayed(STDOUT_FILENO); + llvm::sys::Process::FileDescriptorIsDisplayed(STDOUT_FILENO); pConfig.options().setColor(color_option); break; } @@ -1191,7 +1210,7 @@ static bool ProcessLinkerOptionsFromCommand(mcld::LinkerScript& pScript, // add wname -> __wrap_wname mcld::StringEntry<llvm::StringRef>* to_wrap = - pScript.renameMap().insert(*wname, exist); + pScript.renameMap().insert(*wname, exist); std::string to_wrap_str = "__wrap_" + *wname; to_wrap->setValue(to_wrap_str); @@ -1202,7 +1221,7 @@ static bool ProcessLinkerOptionsFromCommand(mcld::LinkerScript& pScript, // add __real_wname -> wname std::string from_real_str = "__real_" + *wname; mcld::StringEntry<llvm::StringRef>* from_real = - pScript.renameMap().insert(from_real_str, exist); + pScript.renameMap().insert(from_real_str, exist); from_real->setValue(*wname); if (exist) mcld::warning(mcld::diag::rewrap) << *wname << from_real_str; @@ -1216,7 +1235,7 @@ static bool ProcessLinkerOptionsFromCommand(mcld::LinkerScript& pScript, // add pname -> pname_portable mcld::StringEntry<llvm::StringRef>* to_port = - pScript.renameMap().insert(*pname, exist); + pScript.renameMap().insert(*pname, exist); std::string to_port_str = *pname + "_portable"; to_port->setValue(to_port_str); @@ -1227,7 +1246,7 @@ static bool ProcessLinkerOptionsFromCommand(mcld::LinkerScript& pScript, // add __real_pname -> pname std::string from_real_str = "__real_" + *pname; mcld::StringEntry<llvm::StringRef>* from_real = - pScript.renameMap().insert(from_real_str, exist); + pScript.renameMap().insert(from_real_str, exist); from_real->setValue(*pname); if (exist) @@ -1261,21 +1280,21 @@ static bool ProcessLinkerOptionsFromCommand(mcld::LinkerScript& pScript, if (-1U != ArgTextSegAddr) { bool exist = false; mcld::StringEntry<uint64_t>* text_mapping = - pScript.addressMap().insert(".text", exist); + pScript.addressMap().insert(".text", exist); text_mapping->setValue(ArgTextSegAddr); } // -Tdata if (-1U != ArgDataSegAddr) { bool exist = false; mcld::StringEntry<uint64_t>* data_mapping = - pScript.addressMap().insert(".data", exist); + pScript.addressMap().insert(".data", exist); data_mapping->setValue(ArgDataSegAddr); } // -Tbss if (-1U != ArgBssSegAddr) { bool exist = false; mcld::StringEntry<uint64_t>* bss_mapping = - pScript.addressMap().insert(".bss", exist); + pScript.addressMap().insert(".bss", exist); bss_mapping->setValue(ArgBssSegAddr); } // --section-start SECTION=ADDRESS @@ -1289,7 +1308,7 @@ static bool ProcessLinkerOptionsFromCommand(mcld::LinkerScript& pScript, script.substr(pos + 1).getAsInteger(0, address); bool exist = false; mcld::StringEntry<uint64_t>* addr_mapping = - pScript.addressMap().insert(script.substr(0, pos), exist); + pScript.addressMap().insert(script.substr(0, pos), exist); addr_mapping->setValue(address); } @@ -1422,8 +1441,8 @@ int main(int argc, char* argv[]) // specified an architecture to compile for. If so we have to look it up by // name, because it might be a backend that has no mapping to a target triple. const mcld::Target *MCLDTarget = mcld::TargetRegistry::lookupTarget(MArch, - TheTriple, - error); + TheTriple, + error); if (NULL == MCLDTarget) { errs() << argv[0] << ": " << error; return 1; @@ -1465,7 +1484,7 @@ int main(int argc, char* argv[]) Options.NoInfsFPMath = EnableNoInfsFPMath; Options.NoNaNsFPMath = EnableNoNaNsFPMath; Options.HonorSignDependentRoundingFPMathOption = - EnableHonorSignDependentRoundingFPMath; + EnableHonorSignDependentRoundingFPMath; Options.UseSoftFloat = GenerateSoftFloatCalls; if (FloatABIForCalls != FloatABI::Default) Options.FloatABIType = FloatABIForCalls; @@ -1482,10 +1501,10 @@ int main(int argc, char* argv[]) MCPU, FeaturesStr, Options, ArgRelocModel, CMModel, OLvl)); - std::auto_ptr<mcld::MCLDTargetMachine> target_machine( - MCLDTarget->createTargetMachine(TheTriple.getTriple(), - *LLVMTarget, - *TM.get())); + std::auto_ptr<mcld::MCLDTargetMachine> + target_machine(MCLDTarget->createTargetMachine(TheTriple.getTriple(), + *LLVMTarget, + *TM.get())); assert(target_machine.get() && "Could not allocate target machine!"); mcld::MCLDTargetMachine &TheTargetMachine = *target_machine.get(); @@ -1500,7 +1519,7 @@ int main(int argc, char* argv[]) // finish LineInfo's implementation. OwningPtr<mcld::DiagnosticLineInfo> diag_line_info(MCLDTarget->createDiagnosticLineInfo(*MCLDTarget, - TheTriple.getTriple())); + TheTriple.getTriple())); mcld::getDiagnosticEngine().setLineInfo(*diag_line_info.take()); diff --git a/unittests/BinTreeTest.h b/unittests/BinTreeTest.h index 3e8fab4..7f4a7f7 100644 --- a/unittests/BinTreeTest.h +++ b/unittests/BinTreeTest.h @@ -25,7 +25,7 @@ namespace mcldtest /** \class BinTreeTest * \brief Make sure the interface of BinTree , such as insert , traversal , etc.. * - * \see BinTree + * \see BinTree */ class BinTreeTest : public ::testing::Test { diff --git a/unittests/DirIteratorTest.h b/unittests/DirIteratorTest.h index 1f6e616..ea6aaf7 100644 --- a/unittests/DirIteratorTest.h +++ b/unittests/DirIteratorTest.h @@ -24,9 +24,9 @@ namespace mcldtest { /** \class DirIteratorTest - * \brief + * \brief * - * \see DirIterator + * \see DirIterator */ class DirIteratorTest : public ::testing::Test { diff --git a/unittests/FactoriesTest.h b/unittests/FactoriesTest.h index ee7badf..484b801 100644 --- a/unittests/FactoriesTest.h +++ b/unittests/FactoriesTest.h @@ -18,7 +18,7 @@ namespace mcldtest /** \class FactoriesTest * \brief Test cases for factories - NodeFactory and MCLDFileFactory. * - * \see Factories + * \see Factories */ class FactoriesTest : public ::testing::Test { diff --git a/unittests/FileHandleTest.h b/unittests/FileHandleTest.h index 88e2653..45d4ab1 100644 --- a/unittests/FileHandleTest.h +++ b/unittests/FileHandleTest.h @@ -21,9 +21,9 @@ namespace mcldtest { /** \class FileHandleTest - * \brief + * \brief * - * \see FileHandle + * \see FileHandle */ class FileHandleTest : public ::testing::Test { diff --git a/unittests/FragmentRefTest.h b/unittests/FragmentRefTest.h index 340bd77..17de587 100644 --- a/unittests/FragmentRefTest.h +++ b/unittests/FragmentRefTest.h @@ -24,7 +24,7 @@ namespace mcldtest /** \class FragmentRefTest * \brief Reference Test * - * \see FragmentRef + * \see FragmentRef */ class FragmentRefTest : public ::testing::Test { diff --git a/unittests/FragmentTest.cpp b/unittests/FragmentTest.cpp index 43f51b6..273c98d 100644 --- a/unittests/FragmentTest.cpp +++ b/unittests/FragmentTest.cpp @@ -38,7 +38,7 @@ void FragmentTest::TearDown() //===----------------------------------------------------------------------===// // Testcases - + TEST_F( FragmentTest, Fragment_constructor ) { LDSection* test = LDSection::Create("test", LDFileFormat::Null, 0, 0); SectionData* s = SectionData::Create(*test); @@ -58,7 +58,7 @@ TEST_F( FragmentTest, Fragment_trivial_function ) { LDSection* test = LDSection::Create("test", LDFileFormat::Null, 0, 0); SectionData* s = SectionData::Create(*test); Fragment* f = new Fragment(Fragment::Alignment, s); - + EXPECT_TRUE(Fragment::Alignment == f->getKind()); f->setOffset(5566); @@ -66,7 +66,7 @@ TEST_F( FragmentTest, Fragment_trivial_function ) { //always return true EXPECT_TRUE(f->classof(new Fragment(Fragment::Region, s)) ); - + LDSection::Destroy(test); // SectionData::Destroy(s); } diff --git a/unittests/FragmentTest.h b/unittests/FragmentTest.h index 84ac7b7..8c1489c 100644 --- a/unittests/FragmentTest.h +++ b/unittests/FragmentTest.h @@ -23,7 +23,7 @@ namespace mcldtest /** \class FragmentTest * \brief Unit test for mcld::Fragment. * - * \see Fragment + * \see Fragment */ class FragmentTest : public ::testing::Test { diff --git a/unittests/GraphTest.cpp b/unittests/GraphTest.cpp index 38fc0d4..0c97567 100644 --- a/unittests/GraphTest.cpp +++ b/unittests/GraphTest.cpp @@ -237,7 +237,7 @@ TEST_F(GraphTest, list_digraph_add_n_erase_arcs_1) ListDigraph::Arc* a3 = graph.addArc(*u3, *u1); graph.erase(*a2); - + ASSERT_TRUE(u1 == a1->source && u2 == a1->target); ASSERT_TRUE(u3 == a3->source && u1 == a3->target); @@ -265,7 +265,7 @@ TEST_F(GraphTest, list_digraph_add_n_erase_arcs_2) ListDigraph::Arc* a3 = graph.addArc(*u3, *u1); graph.erase(*a1); - + ASSERT_TRUE(u2 == a2->source && u3 == a2->target); ASSERT_TRUE(u3 == a3->source && u1 == a3->target); @@ -292,7 +292,7 @@ TEST_F(GraphTest, list_digraph_add_n_erase_arcs_3) ListDigraph::Arc* a3 = graph.addArc(*u3, *u1); graph.erase(*a3); - + ASSERT_TRUE(u1 == a1->source && u2 == a1->target); ASSERT_TRUE(u2 == a2->source && u3 == a2->target); diff --git a/unittests/HashTableTest.h b/unittests/HashTableTest.h index 4bf2c50..c07c991 100644 --- a/unittests/HashTableTest.h +++ b/unittests/HashTableTest.h @@ -18,7 +18,7 @@ namespace mcldtest /** \class HashTableTest * \brief Testcase for HashTable * - * \see HashTable + * \see HashTable */ class HashTableTest : public ::testing::Test { diff --git a/unittests/InputTreeTest.cpp b/unittests/InputTreeTest.cpp index 1b1e061..6af81d8 100644 --- a/unittests/InputTreeTest.cpp +++ b/unittests/InputTreeTest.cpp @@ -31,7 +31,7 @@ InputTreeTest::InputTreeTest() m_pAlloc = new mcld::InputFactory(10, *m_pConfig); m_pBuilder = new mcld::InputBuilder(*m_pConfig, *m_pAlloc, - m_ContextFactory, + m_ContextFactory, m_MemFactory, false); m_pTestee = new mcld::InputTree(); @@ -74,7 +74,7 @@ TEST_F( InputTreeTest, Basic_operation ) { (*action)->activate(*m_pBuilder); delete *action; } - + InputTree::iterator node = m_pTestee->root(); InputTree::const_iterator const_node = node; --node; @@ -104,13 +104,13 @@ TEST_F( InputTreeTest, Basic_operation ) { TEST_F( InputTreeTest, forLoop_TEST ) { InputTree::iterator node = m_pTestee->root(); - + Input* input = m_pAlloc->produce("FileSpec", "path1"); m_pTestee->insert<InputTree::Inclusive>(node, *input); InputTree::const_iterator const_node = node; --node; - for(int i=0 ; i<100 ; ++i) + for(int i=0 ; i<100 ; ++i) { Input* input = m_pAlloc->produce("FileSpec", "path1"); m_pTestee->insert<InputTree::Inclusive>(node, *input); @@ -129,9 +129,9 @@ TEST_F( InputTreeTest, forLoop_TEST ) { } TEST_F( InputTreeTest, Nesting_Case ) { - InputTree::iterator node = m_pTestee->root(); + InputTree::iterator node = m_pTestee->root(); - for(int i=0 ; i<50 ; ++i) + for(int i=0 ; i<50 ; ++i) { m_pTestee->enterGroup(node, InputTree::Downward); --node; @@ -140,7 +140,7 @@ TEST_F( InputTreeTest, Nesting_Case ) { m_pTestee->insert(node, InputTree::Afterward, *input); ++node; } - + ASSERT_FALSE(node.isRoot()); ASSERT_FALSE(isGroup(node)); ASSERT_FALSE(m_pAlloc->empty()); @@ -150,8 +150,8 @@ TEST_F( InputTreeTest, Nesting_Case ) { TEST_F( InputTreeTest, DFSIterator_BasicTraversal) { - - InputTree::iterator node = m_pTestee->root(); + + InputTree::iterator node = m_pTestee->root(); Input* input = m_pAlloc->produce("111", "/"); m_pTestee->insert<InputTree::Inclusive>(node, *input); node.move<InputTree::Inclusive>(); @@ -166,8 +166,8 @@ TEST_F( InputTreeTest, DFSIterator_BasicTraversal) input = m_pAlloc->produce("8", "/"); m_pTestee->insert<InputTree::Positional>(node, *input); - InputTree::dfs_iterator dfs_it = m_pTestee->dfs_begin(); - InputTree::dfs_iterator dfs_end = m_pTestee->dfs_end(); + InputTree::dfs_iterator dfs_it = m_pTestee->dfs_begin(); + InputTree::dfs_iterator dfs_end = m_pTestee->dfs_end(); ASSERT_STREQ("111", (*dfs_it)->name().c_str()); ++dfs_it; ASSERT_STREQ("7", (**dfs_it).name().c_str()); diff --git a/unittests/InputTreeTest.h b/unittests/InputTreeTest.h index c0f59a7..31be6fd 100644 --- a/unittests/InputTreeTest.h +++ b/unittests/InputTreeTest.h @@ -23,9 +23,9 @@ class LinkerConfig; namespace test { /** \class InputTreeTest - * \brief + * \brief * - * \see InputTree + * \see InputTree */ class InputTreeTest : public ::testing::Test { diff --git a/unittests/LinearAllocatorTest.h b/unittests/LinearAllocatorTest.h index a6be2b7..24b8715 100644 --- a/unittests/LinearAllocatorTest.h +++ b/unittests/LinearAllocatorTest.h @@ -18,7 +18,7 @@ namespace mcldtest /** \class LinearAllocatorTest * \brief The testcase for LinearAllocator * - * \see LinearAllocator + * \see LinearAllocator */ class LinearAllocatorTest : public ::testing::Test { diff --git a/unittests/LinkerTest.cpp b/unittests/LinkerTest.cpp index 479bbb9..f9d3224 100644 --- a/unittests/LinkerTest.cpp +++ b/unittests/LinkerTest.cpp @@ -430,7 +430,7 @@ TEST_F( LinkerTest, plasma_object) { builder.AddSymbol(*input, "Output/gotplt.bc", ResolveInfo::File, ResolveInfo::Define, ResolveInfo::Local, 0); - /// 2: 00000000 0 SECTION LOCAL DEFAULT 1 + /// 2: 00000000 0 SECTION LOCAL DEFAULT 1 builder.AddSymbol(*input, ".text", ResolveInfo::Section, ResolveInfo::Define, ResolveInfo::Local, 0, 0x0, text); @@ -438,11 +438,11 @@ TEST_F( LinkerTest, plasma_object) { builder.AddSymbol(*input, ".data", ResolveInfo::Section, ResolveInfo::Define, ResolveInfo::Local, 0, 0x0, data); - /// 4: 00000000 0 SECTION LOCAL DEFAULT 4 + /// 4: 00000000 0 SECTION LOCAL DEFAULT 4 builder.AddSymbol(*input, ".bss", ResolveInfo::Section, ResolveInfo::Define, ResolveInfo::Local, 0, 0x0, bss); - /// 5: 00000000 0 SECTION LOCAL DEFAULT 5 + /// 5: 00000000 0 SECTION LOCAL DEFAULT 5 builder.AddSymbol(*input, ".ARM.attributes", ResolveInfo::Section, ResolveInfo::Define, ResolveInfo::Local, 0, 0x0, attr); diff --git a/unittests/MCRegionFragmentTest.h b/unittests/MCRegionFragmentTest.h index 15434fd..3d1dab8 100644 --- a/unittests/MCRegionFragmentTest.h +++ b/unittests/MCRegionFragmentTest.h @@ -24,7 +24,7 @@ namespace mcldtest /** \class MCRegionFragmentTest * \brief The testcase of MCRegionFragment. * - * \see MCRegionFragment + * \see MCRegionFragment */ class MCRegionFragmentTest : public ::testing::Test { diff --git a/unittests/NamePoolTest.h b/unittests/NamePoolTest.h index 12103e0..2e4a494 100644 --- a/unittests/NamePoolTest.h +++ b/unittests/NamePoolTest.h @@ -21,9 +21,9 @@ namespace mcldtest { /** \class NamePoolTest - * \brief + * \brief * - * \see NamePool + * \see NamePool */ class NamePoolTest : public ::testing::Test { diff --git a/unittests/PathSetTest.h b/unittests/PathSetTest.h index d64b2a8..23a2dbf 100644 --- a/unittests/PathSetTest.h +++ b/unittests/PathSetTest.h @@ -23,7 +23,7 @@ namespace mcldtest /** \class PathSetTest * \brief The testcase of PathSet * - * \see PathSet + * \see PathSet */ class PathSetTest : public ::testing::Test { diff --git a/unittests/PathTest.h b/unittests/PathTest.h index 968ce0e..417a07f 100644 --- a/unittests/PathTest.h +++ b/unittests/PathTest.h @@ -18,7 +18,7 @@ namespace mcldtest /** \class PathTest * \brief a testcase for mcld::Path and its non-member funtions. * - * \see Path + * \see Path */ class PathTest : public ::testing::Test { diff --git a/unittests/RTLinearAllocatorTest.h b/unittests/RTLinearAllocatorTest.h index d58442a..3ba0cd9 100644 --- a/unittests/RTLinearAllocatorTest.h +++ b/unittests/RTLinearAllocatorTest.h @@ -16,9 +16,9 @@ namespace mcldtest { /** \class RTLinearAllocatorTest - * \brief + * \brief * - * \see RTLinearAllocator + * \see RTLinearAllocator */ class RTLinearAllocatorTest : public ::testing::Test { diff --git a/unittests/SectionDataTest.cpp b/unittests/SectionDataTest.cpp index dfabc15..6a7e366 100644 --- a/unittests/SectionDataTest.cpp +++ b/unittests/SectionDataTest.cpp @@ -39,14 +39,14 @@ void SectionDataTest::TearDown() //===----------------------------------------------------------------------===// // Testcases //===----------------------------------------------------------------------===// - + TEST_F( SectionDataTest, constructor_and_trivial_func ) { LDSection* test = LDSection::Create("test", LDFileFormat::Null, 0, 0); - + SectionData* s = SectionData::Create(*test); EXPECT_TRUE(s->getSection().name() == "test" && \ s->getSection().kind() == LDFileFormat::Null); - + LDSection::Destroy(test); } diff --git a/unittests/StaticResolverTest.cpp b/unittests/StaticResolverTest.cpp index eb3accc..a474cdd 100644 --- a/unittests/StaticResolverTest.cpp +++ b/unittests/StaticResolverTest.cpp @@ -67,7 +67,7 @@ TEST_F( StaticResolverTest, MDEF ) { TEST_F( StaticResolverTest, DynDefAfterDynUndef ) { ResolveInfo* old_sym = ResolveInfo::Create("abc"); ResolveInfo* new_sym = ResolveInfo::Create("abc"); - + new_sym->setBinding(ResolveInfo::Global); old_sym->setBinding(ResolveInfo::Global); new_sym->setDesc(ResolveInfo::Undefined); @@ -94,7 +94,7 @@ TEST_F( StaticResolverTest, DynDefAfterDynUndef ) { TEST_F( StaticResolverTest, DynDefAfterDynDef ) { ResolveInfo* old_sym = ResolveInfo::Create("abc"); ResolveInfo* new_sym = ResolveInfo::Create("abc"); - + new_sym->setBinding(ResolveInfo::Global); old_sym->setBinding(ResolveInfo::Global); new_sym->setDesc(ResolveInfo::Define); @@ -121,7 +121,7 @@ TEST_F( StaticResolverTest, DynDefAfterDynDef ) { TEST_F( StaticResolverTest, DynUndefAfterDynUndef ) { ResolveInfo* old_sym = ResolveInfo::Create("abc"); ResolveInfo* new_sym = ResolveInfo::Create("abc"); - + new_sym->setBinding(ResolveInfo::Global); old_sym->setBinding(ResolveInfo::Global); new_sym->setDesc(ResolveInfo::Undefined); @@ -149,7 +149,7 @@ TEST_F( StaticResolverTest, OverrideWeakByGlobal ) { ResolveInfo* old_sym = ResolveInfo::Create("abc"); ResolveInfo* new_sym = ResolveInfo::Create("abc"); - + new_sym->setBinding(ResolveInfo::Global); old_sym->setBinding(ResolveInfo::Weak); new_sym->setSize(0); @@ -170,7 +170,7 @@ TEST_F( StaticResolverTest, OverrideWeakByGlobal ) TEST_F( StaticResolverTest, DynWeakAfterDynDef ) { ResolveInfo* old_sym = ResolveInfo::Create("abc"); ResolveInfo* new_sym = ResolveInfo::Create("abc"); - + old_sym->setBinding(ResolveInfo::Weak); new_sym->setBinding(ResolveInfo::Global); @@ -200,7 +200,7 @@ TEST_F( StaticResolverTest, MarkByBiggerCommon ) { ResolveInfo* old_sym = ResolveInfo::Create("abc"); ResolveInfo* new_sym = ResolveInfo::Create("abc"); - + new_sym->setDesc(ResolveInfo::Common); old_sym->setDesc(ResolveInfo::Common); new_sym->setSize(999); @@ -222,7 +222,7 @@ TEST_F( StaticResolverTest, OverrideByBiggerCommon ) { ResolveInfo* old_sym = ResolveInfo::Create("abc"); ResolveInfo* new_sym = ResolveInfo::Create("abc"); - + new_sym->setDesc(ResolveInfo::Common); old_sym->setDesc(ResolveInfo::Common); old_sym->setBinding(ResolveInfo::Weak); @@ -247,7 +247,7 @@ TEST_F( StaticResolverTest, OverrideCommonByDefine) { ResolveInfo* old_sym = ResolveInfo::Create("abc"); ResolveInfo* new_sym = ResolveInfo::Create("abc"); - + old_sym->setDesc(ResolveInfo::Common); old_sym->setSize(0); @@ -270,7 +270,7 @@ TEST_F( StaticResolverTest, OverrideCommonByDefine) TEST_F( StaticResolverTest, SetUpDesc) { ResolveInfo* sym = ResolveInfo::Create("abc"); - + sym->setIsSymbol(true); // ASSERT_FALSE( sym->isSymbol() ); @@ -370,7 +370,7 @@ TEST_F( StaticResolverTest, SetUpDesc) TEST_F( StaticResolverTest, SetUpBinding) { ResolveInfo* sym = ResolveInfo::Create("abc"); - + sym->setIsSymbol(true); // ASSERT_FALSE( sym->isSymbol() ); diff --git a/unittests/StaticResolverTest.h b/unittests/StaticResolverTest.h index 89157f0..c6f0699 100644 --- a/unittests/StaticResolverTest.h +++ b/unittests/StaticResolverTest.h @@ -26,7 +26,7 @@ namespace mcldtest /** \class StaticResolverTest * \brief The testcases for static resolver * - * \see StaticResolver + * \see StaticResolver */ class StaticResolverTest : public ::testing::Test { diff --git a/unittests/StringTableTest.h b/unittests/StringTableTest.h index 0b397e8..60d7f00 100644 --- a/unittests/StringTableTest.h +++ b/unittests/StringTableTest.h @@ -21,9 +21,9 @@ namespace mcldtest { /** \class StringTableTest - * \brief + * \brief * - * \see StringTable + * \see StringTable */ class StringTableTest : public ::testing::Test { diff --git a/unittests/SymbolCategoryTest.h b/unittests/SymbolCategoryTest.h index ff5f1a6..a7109ed 100644 --- a/unittests/SymbolCategoryTest.h +++ b/unittests/SymbolCategoryTest.h @@ -23,7 +23,7 @@ namespace mcldtest /** \class SymbolCategoryTest * \brief The testcases of symbol category. * - * \see SymbolCategory + * \see SymbolCategory */ class SymbolCategoryTest : public ::testing::Test { diff --git a/unittests/SymbolTableTest.h b/unittests/SymbolTableTest.h index 9076ac9..39e8751 100644 --- a/unittests/SymbolTableTest.h +++ b/unittests/SymbolTableTest.h @@ -21,9 +21,9 @@ namespace mcldtest { /** \class SymbolTableTest - * \brief + * \brief * - * \see SymbolTable + * \see SymbolTable */ class SymbolTableTest : public ::testing::Test { diff --git a/unittests/TargetMachineTest.h b/unittests/TargetMachineTest.h index 3f77da7..88a44dc 100644 --- a/unittests/TargetMachineTest.h +++ b/unittests/TargetMachineTest.h @@ -15,9 +15,9 @@ namespace mcldTEST { /** \class TargetMachineTest - * \brief + * \brief * - * \see TargetMachine + * \see TargetMachine */ class TargetMachineTest : public ::testing::Test { diff --git a/unittests/UniqueGCFactoryBaseTest.cpp b/unittests/UniqueGCFactoryBaseTest.cpp index 45a2aca..a6f7289 100644 --- a/unittests/UniqueGCFactoryBaseTest.cpp +++ b/unittests/UniqueGCFactoryBaseTest.cpp @@ -42,7 +42,7 @@ void UniqueGCFactoryBaseTest::TearDown() // Testcases // TEST_F( UniqueGCFactoryBaseTest, number_constructor ) { - ContextFactory *contextFactory = new ContextFactory(10); + ContextFactory *contextFactory = new ContextFactory(10); contextFactory->produce("/"); contextFactory->produce("ab/c"); ASSERT_TRUE( 2 == contextFactory->size()); @@ -50,7 +50,7 @@ TEST_F( UniqueGCFactoryBaseTest, number_constructor ) { } TEST_F( UniqueGCFactoryBaseTest, unique_produce ) { - ContextFactory *contextFactory = new ContextFactory(10); + ContextFactory *contextFactory = new ContextFactory(10); LDContext* context1 = contextFactory->produce("/"); contextFactory->produce("ab/c"); ASSERT_TRUE( 2 == contextFactory->size()); @@ -60,7 +60,7 @@ TEST_F( UniqueGCFactoryBaseTest, unique_produce ) { } TEST_F( UniqueGCFactoryBaseTest, unique_produce2 ) { - ContextFactory *contextFactory = new ContextFactory(10); + ContextFactory *contextFactory = new ContextFactory(10); LDContext* context1 = contextFactory->produce("abc/def"); contextFactory->produce("ab/c"); ASSERT_TRUE( 2 == contextFactory->size()); @@ -72,7 +72,7 @@ TEST_F( UniqueGCFactoryBaseTest, unique_produce2 ) { TEST_F( UniqueGCFactoryBaseTest, iterator ) { sys::fs::Path path1(TOPDIR), path2(TOPDIR); - path1.append("unittests/test1.txt"); + path1.append("unittests/test.txt"); path2.append("unittests/test2.txt"); MemoryAreaFactory* memFactory = new MemoryAreaFactory(10); @@ -81,7 +81,7 @@ TEST_F( UniqueGCFactoryBaseTest, iterator ) ASSERT_NE( area1, area2); MemoryArea* area3 = memFactory->produce(path1, FileHandle::ReadOnly); - + ASSERT_EQ(area1, area3); ASSERT_FALSE( memFactory->empty()); ASSERT_TRUE( 2 == memFactory->size()); diff --git a/unittests/test3.txt b/unittests/test3.txt index 2689bfd..0b4a379 100644 --- a/unittests/test3.txt +++ b/unittests/test3.txt @@ -5,12 +5,12 @@ HELLOopyright (C@@1990, 1991, 1992, 1993, 1994, 1995, 1996, 1997, 1998, # it under the terms of the GNU General Public License as published by # the Free Software Foundation; either version 2 of the License, or # (at your option) any later version. -# +# # This program is distributed in the hope that it will be useful, # but WITHOUT ANY WARRANTY; without even the implied warranty of # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the # GNU General Public License for more details. -# +# # You should have received a copy of the GNU General Public License # along with this program; if not, write to the Free Software # Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. |