Merge "Update mclinker with upstream patches"
diff --git a/include/mcld/GeneralOptions.h b/include/mcld/GeneralOptions.h
index 165c027..787c5eb 100644
--- a/include/mcld/GeneralOptions.h
+++ b/include/mcld/GeneralOptions.h
@@ -27,16 +27,26 @@
*/
class GeneralOptions {
public:
- enum StripSymbolMode {
+ enum class StripSymbolMode {
KeepAllSymbols,
StripTemporaries,
StripLocals,
StripAllSymbols
};
- enum HashStyle { SystemV = 0x1, GNU = 0x2, Both = 0x3 };
+ enum class HashStyle : uint8_t {
+ Unknown = 0x0,
+ SystemV = 0x1,
+ GNU = 0x2,
+ Both = 0x3
+ };
- enum ICF { ICF_None, ICF_All, ICF_Safe };
+ enum class ICF {
+ Unknown,
+ None,
+ All,
+ Safe
+ };
typedef std::vector<std::string> RpathList;
typedef RpathList::iterator rpath_iterator;
@@ -246,9 +256,17 @@
int getGPSize() const { return m_GPSize; }
- unsigned int getHashStyle() const { return m_HashStyle; }
+ HashStyle getHashStyle() const { return m_HashStyle; }
- void setHashStyle(unsigned int pStyle) { m_HashStyle = pStyle; }
+ bool hasGNUHash() const {
+ return m_HashStyle == HashStyle::GNU || m_HashStyle == HashStyle::Both;
+ }
+
+ bool hasSysVHash() const {
+ return m_HashStyle == HashStyle::SystemV || m_HashStyle == HashStyle::Both;
+ }
+
+ void setHashStyle(HashStyle pStyle) { m_HashStyle = pStyle; }
ICF getICFMode() const { return m_ICF; }
@@ -260,7 +278,7 @@
bool printICFSections() const { return m_bPrintICFSections; }
- void setPrintICFSections(bool pPrintICFSections) {
+ void setPrintICFSections(bool pPrintICFSections = true) {
m_bPrintICFSections = pPrintICFSections;
}
@@ -375,7 +393,7 @@
RpathList m_RpathList;
ScriptList m_ScriptList;
UndefSymList m_UndefSymList; // -u [symbol], --undefined [symbol]
- unsigned int m_HashStyle;
+ HashStyle m_HashStyle;
std::string m_Filter;
AuxiliaryList m_AuxiliaryList;
ExcludeLIBS m_ExcludeLIBS;
diff --git a/include/mcld/LD/DiagReaders.inc b/include/mcld/LD/DiagReaders.inc
index 2409946..4384420 100644
--- a/include/mcld/LD/DiagReaders.inc
+++ b/include/mcld/LD/DiagReaders.inc
@@ -12,5 +12,5 @@
"cannot scan .eh_frame section in input %0.")
DIAG(fatal_cannot_read_input,
DiagnosticEngine::Fatal,
- "cannot read input input %0",
+ "cannot read input %0",
"cannot read input %0")
diff --git a/include/mcld/LinkerScript.h b/include/mcld/LinkerScript.h
index 3e2737e..3d984c3 100644
--- a/include/mcld/LinkerScript.h
+++ b/include/mcld/LinkerScript.h
@@ -18,6 +18,7 @@
#include "mcld/Script/Assignment.h"
#include <llvm/ADT/StringRef.h>
+#include <llvm/ADT/SmallVector.h>
#include <string>
#include <vector>
@@ -43,6 +44,8 @@
typedef std::vector<AssertCmd> Assertions;
+ typedef llvm::SmallVector<std::string, 8> DefSyms;
+
public:
LinkerScript();
@@ -63,6 +66,9 @@
const Assertions& assertions() const { return m_Assertions; }
Assertions& assertions() { return m_Assertions; }
+ const DefSyms& defsyms() const { return m_DefSyms; }
+ DefSyms& defsyms() { return m_DefSyms; }
+
/// search directory
const SearchDirs& directories() const { return m_SearchDirs; }
SearchDirs& directories() { return m_SearchDirs; }
@@ -94,6 +100,7 @@
SectionMap m_SectionMap;
Assignments m_Assignments;
Assertions m_Assertions;
+ DefSyms m_DefSyms;
SearchDirs m_SearchDirs;
std::string m_Entry;
std::string m_OutputFile;
diff --git a/include/mcld/MC/CommandAction.h b/include/mcld/MC/CommandAction.h
index 85f3e2b..b1764d4 100644
--- a/include/mcld/MC/CommandAction.h
+++ b/include/mcld/MC/CommandAction.h
@@ -151,14 +151,14 @@
/// DefSymAction
class DefSymAction : public InputAction {
public:
- explicit DefSymAction(unsigned int pPosition, std::string& pAssignment);
+ explicit DefSymAction(unsigned int pPosition, const std::string& pAssignment);
bool activate(InputBuilder&) const;
const std::string& assignment() const { return m_Assignment; }
private:
- std::string& m_Assignment;
+ const std::string& m_Assignment;
};
/// ScriptAction
diff --git a/include/mcld/Support/CXADemangle.tcc b/include/mcld/Support/CXADemangle.tcc
index 4e66f84..e89bfec 100644
--- a/include/mcld/Support/CXADemangle.tcc
+++ b/include/mcld/Support/CXADemangle.tcc
@@ -1572,10 +1572,8 @@
const char* t = first+1;
if (t != last)
{
- bool externC = false;
if (*t == 'Y')
{
- externC = true;
if (++t == last)
return first;
}
diff --git a/include/mcld/Support/CommandLine.h b/include/mcld/Support/CommandLine.h
deleted file mode 100644
index 3474ce6..0000000
--- a/include/mcld/Support/CommandLine.h
+++ /dev/null
@@ -1,106 +0,0 @@
-//===- CommandLine.h ------------------------------------------------------===//
-//
-// The MCLinker Project
-//
-// This file is distributed under the University of Illinois Open Source
-// License. See LICENSE.TXT for details.
-//
-//===----------------------------------------------------------------------===//
-#ifndef MCLD_SUPPORT_COMMANDLINE_H_
-#define MCLD_SUPPORT_COMMANDLINE_H_
-#include "mcld/MC/ZOption.h"
-#include "mcld/Support/FileSystem.h"
-
-#include <llvm/ADT/StringRef.h>
-#include <llvm/ADT/Triple.h>
-#include <llvm/Support/CommandLine.h>
-
-#include <string>
-
-namespace llvm {
-namespace cl {
-
-//===----------------------------------------------------------------------===//
-// SearchDirParser
-//===----------------------------------------------------------------------===//
-class SearchDirParser final : public basic_parser<std::string> {
- public:
- explicit SearchDirParser(Option &O) : basic_parser(O) { }
-
- // parse - Return true on error.
- bool parse(Option& pOption,
- StringRef pArgName,
- StringRef pArg,
- std::string& pValue);
-
- const char* getValueName() const { return "searchdir"; }
-
- void printOptionDiff(const Option& pOption,
- StringRef pValue,
- OptVal pDefault,
- size_t pGlobalWidth) const;
-
- void anchor();
-};
-
-#if 0
-//===----------------------------------------------------------------------===//
-// FalseParser
-//===----------------------------------------------------------------------===//
-class FalseParser : public parser<bool> {
- public:
- explicit FalseParser(Option &O) : parser<bool>(O) { }
-
- // parse - Return true on error.
- bool parse(cl::Option& O, StringRef ArgName, StringRef Arg, bool& Val) {
- if (cl::parser<bool>::parse(O, ArgName, Arg, Val))
- return false;
- Val = false;
- return false;
- }
-};
-#endif
-
-//===----------------------------------------------------------------------===//
-// parser<mcld::sys::fs::Path>
-//===----------------------------------------------------------------------===//
-template <>
-class parser<mcld::sys::fs::Path> final : public basic_parser<mcld::sys::fs::Path> {
- public:
- explicit parser(Option &O) : basic_parser(O) { }
-
- bool parse(Option& O,
- StringRef ArgName,
- StringRef Arg,
- mcld::sys::fs::Path& Val);
-
- virtual const char* getValueName() const { return "path"; }
- void printOptionDiff(const Option& O,
- const mcld::sys::fs::Path& V,
- OptVal Default,
- size_t GlobalWidth) const;
- virtual void anchor();
-};
-
-//===----------------------------------------------------------------------===//
-// parser<mcld::ZOption>
-//===----------------------------------------------------------------------===//
-template <>
-class parser<mcld::ZOption> final : public basic_parser<mcld::ZOption> {
- public:
- explicit parser(Option &O) : basic_parser(O) { }
-
- bool parse(Option& O, StringRef ArgName, StringRef Arg, mcld::ZOption& Val);
-
- virtual const char* getValueName() const { return "z-option"; }
- void printOptionDiff(const Option& O,
- const mcld::ZOption& V,
- OptVal Default,
- size_t GlobalWidth) const;
- virtual void anchor();
-};
-
-} // namespace cl
-} // namespace llvm
-
-#endif // MCLD_SUPPORT_COMMANDLINE_H_
diff --git a/lib/Core/GeneralOptions.cpp b/lib/Core/GeneralOptions.cpp
index 6f7b57f..1996acf 100644
--- a/lib/Core/GeneralOptions.cpp
+++ b/lib/Core/GeneralOptions.cpp
@@ -20,7 +20,7 @@
: m_Verbose(-1),
m_MaxErrorNum(-1),
m_MaxWarnNum(-1),
- m_NumSpareDTags(1),
+ m_NumSpareDTags(5),
m_ExecStack(Unknown),
m_NoUndefined(Unknown),
m_MulDefs(Unknown),
@@ -59,11 +59,11 @@
m_bPrintGCSections(false),
m_bGenUnwindInfo(true),
m_bPrintICFSections(false),
- m_ICF(ICF_None),
- m_ICFIterations(0),
+ m_ICF(ICF::None),
+ m_ICFIterations(2),
m_GPSize(8),
- m_StripSymbols(KeepAllSymbols),
- m_HashStyle(SystemV) {
+ m_StripSymbols(StripSymbolMode::KeepAllSymbols),
+ m_HashStyle(HashStyle::SystemV) {
}
GeneralOptions::~GeneralOptions() {
diff --git a/lib/LD/IdenticalCodeFolding.cpp b/lib/LD/IdenticalCodeFolding.cpp
index 7e047d3..527dccb 100644
--- a/lib/LD/IdenticalCodeFolding.cpp
+++ b/lib/LD/IdenticalCodeFolding.cpp
@@ -137,7 +137,7 @@
}
// Safe icf
- if (m_Config.options().getICFMode() == GeneralOptions::ICF_Safe) {
+ if (m_Config.options().getICFMode() == GeneralOptions::ICF::Safe) {
RelocData::iterator rel, relEnd = (*sect)->getRelocData()->end();
for (rel = (*sect)->getRelocData()->begin(); rel != relEnd; ++rel) {
LDSymbol* sym = rel->symInfo()->outSymbol();
@@ -166,7 +166,7 @@
CandidateMap::iterator candidate, candidateEnd = candidate_map.end();
for (candidate = candidate_map.begin(); candidate != candidateEnd;
++candidate) {
- if ((m_Config.options().getICFMode() == GeneralOptions::ICF_All) ||
+ if ((m_Config.options().getICFMode() == GeneralOptions::ICF::All) ||
(funcptr_access_set.count(candidate->first) == 0)) {
size_t index = m_KeptSections.size();
m_KeptSections[candidate->first] = ObjectAndId(*obj, index);
diff --git a/lib/MC/CommandAction.cpp b/lib/MC/CommandAction.cpp
index 4439d7e..37ded34 100644
--- a/lib/MC/CommandAction.cpp
+++ b/lib/MC/CommandAction.cpp
@@ -214,7 +214,8 @@
//===----------------------------------------------------------------------===//
// DefSymAction
//===----------------------------------------------------------------------===//
-DefSymAction::DefSymAction(unsigned int pPosition, std::string& pAssignment)
+DefSymAction::DefSymAction(unsigned int pPosition,
+ const std::string& pAssignment)
: InputAction(pPosition), m_Assignment(pAssignment) {
}
@@ -223,8 +224,9 @@
Input* input = *pBuilder.getCurrentNode();
pBuilder.setContext(*input, false);
- m_Assignment.append(";");
- pBuilder.setMemory(*input, &m_Assignment[0], m_Assignment.size());
+ // FIXME
+ void* base = static_cast<void*>(const_cast<char*>(m_Assignment.data()));
+ pBuilder.setMemory(*input, base, m_Assignment.size());
return true;
}
diff --git a/lib/Object/ObjectLinker.cpp b/lib/Object/ObjectLinker.cpp
index 801cbaf..4d8ffeb 100644
--- a/lib/Object/ObjectLinker.cpp
+++ b/lib/Object/ObjectLinker.cpp
@@ -273,7 +273,7 @@
}
// Identical code folding
- if (m_Config.options().getICFMode() != GeneralOptions::ICF_None) {
+ if (m_Config.options().getICFMode() != GeneralOptions::ICF::None) {
IdenticalCodeFolding icf(m_Config, m_LDBackend, *m_pModule);
icf.foldIdenticalCode();
}
diff --git a/lib/Script/CMakeLists.txt b/lib/Script/CMakeLists.txt
index 1426a23..c2bb146 100644
--- a/lib/Script/CMakeLists.txt
+++ b/lib/Script/CMakeLists.txt
@@ -6,7 +6,7 @@
ADD_FLEX_BISON_DEPENDENCY(LEXER PARSER)
include_directories(${CMAKE_CURRENT_BINARY_DIR})
-add_mcld_library(MCLDScript
+add_llvm_library(MCLDScript
AssertCmd.cpp
Assignment.cpp
BinaryOp.cpp
diff --git a/lib/Support/Android.mk b/lib/Support/Android.mk
index ad36732..54cfc22 100644
--- a/lib/Support/Android.mk
+++ b/lib/Support/Android.mk
@@ -1,7 +1,6 @@
LOCAL_PATH:= $(call my-dir)
mcld_support_SRC_FILES := \
- CommandLine.cpp \
Demangle.cpp \
Directory.cpp \
FileHandle.cpp \
diff --git a/lib/Support/CommandLine.cpp b/lib/Support/CommandLine.cpp
deleted file mode 100644
index 15e739c..0000000
--- a/lib/Support/CommandLine.cpp
+++ /dev/null
@@ -1,164 +0,0 @@
-//===- CommandLine.cpp ----------------------------------------------------===//
-//
-// The MCLinker Project
-//
-// This file is distributed under the University of Illinois Open Source
-// License. See LICENSE.TXT for details.
-//
-//===----------------------------------------------------------------------===//
-#include "mcld/Support/CommandLine.h"
-
-#include <llvm/ADT/StringRef.h>
-#include <llvm/ADT/StringSwitch.h>
-#include <llvm/ADT/Twine.h>
-#include <llvm/Support/ErrorHandling.h>
-
-static const size_t MaxOptWidth = 8; // arbitrary spacing for printOptionDiff
-
-namespace llvm {
-namespace cl {
-
-//===----------------------------------------------------------------------===//
-// SearchDirParser
-//===----------------------------------------------------------------------===//
-// parse - Return true on error.
-bool SearchDirParser::parse(Option& pOption,
- StringRef pArgName,
- StringRef pArg,
- std::string& pValue) {
- char separator = *(pArgName.data() + 1);
- if (separator == '=')
- pValue = '=';
- pValue += pArg.str();
- return false;
-}
-
-void SearchDirParser::printOptionDiff(const Option& pOption,
- StringRef pValue,
- OptVal pDefault,
- size_t pGlobalWidth) const {
- printOptionName(pOption, pGlobalWidth);
- outs() << "= " << pValue;
- size_t NumSpaces =
- MaxOptWidth > pValue.size() ? MaxOptWidth - pValue.size() : 0;
- outs().indent(NumSpaces) << " (default: ";
- if (pDefault.hasValue())
- outs() << pDefault.getValue();
- else
- outs() << "*no default*";
- outs() << ")\n";
-}
-
-void SearchDirParser::anchor() {
- // do nothing
-}
-
-//===----------------------------------------------------------------------===//
-// parser<mcld::sys::fs::Path>
-//===----------------------------------------------------------------------===//
-bool parser<mcld::sys::fs::Path>::parse(llvm::cl::Option& O,
- llvm::StringRef ArgName,
- llvm::StringRef Arg,
- mcld::sys::fs::Path& Val) {
- Val.assign<llvm::StringRef::const_iterator>(Arg.begin(), Arg.end());
- return false;
-}
-
-void parser<mcld::sys::fs::Path>::printOptionDiff(
- const llvm::cl::Option& O,
- const mcld::sys::fs::Path& V,
- parser<mcld::sys::fs::Path>::OptVal Default,
- size_t GlobalWidth) const {
- printOptionName(O, GlobalWidth);
- outs() << "= " << V;
- size_t VSize = V.native().size();
- size_t NumSpaces = MaxOptWidth > VSize ? MaxOptWidth - VSize : 0;
- outs().indent(NumSpaces) << " (default: ";
- if (Default.hasValue())
- outs() << Default.getValue().c_str();
- else
- outs() << "*no default*";
- outs() << ")\n";
-}
-
-void parser<mcld::sys::fs::Path>::anchor() {
- // do nothing
-}
-
-//===----------------------------------------------------------------------===//
-// parser<mcld::ZOption>
-//===----------------------------------------------------------------------===//
-bool parser<mcld::ZOption>::parse(llvm::cl::Option& O,
- llvm::StringRef ArgName,
- llvm::StringRef Arg,
- mcld::ZOption& Val) {
- if (Arg.equals("combreloc"))
- Val.setKind(mcld::ZOption::CombReloc);
- else if (Arg.equals("nocombreloc"))
- Val.setKind(mcld::ZOption::NoCombReloc);
- else if (Arg.equals("defs"))
- Val.setKind(mcld::ZOption::Defs);
- else if (Arg.equals("execstack"))
- Val.setKind(mcld::ZOption::ExecStack);
- else if (Arg.equals("noexecstack"))
- Val.setKind(mcld::ZOption::NoExecStack);
- else if (Arg.equals("initfirst"))
- Val.setKind(mcld::ZOption::InitFirst);
- else if (Arg.equals("interpose"))
- Val.setKind(mcld::ZOption::InterPose);
- else if (Arg.equals("loadfltr"))
- Val.setKind(mcld::ZOption::LoadFltr);
- else if (Arg.equals("muldefs"))
- Val.setKind(mcld::ZOption::MulDefs);
- else if (Arg.equals("nocopyreloc"))
- Val.setKind(mcld::ZOption::NoCopyReloc);
- else if (Arg.equals("nodefaultlib"))
- Val.setKind(mcld::ZOption::NoDefaultLib);
- else if (Arg.equals("nodelete"))
- Val.setKind(mcld::ZOption::NoDelete);
- else if (Arg.equals("nodlopen"))
- Val.setKind(mcld::ZOption::NoDLOpen);
- else if (Arg.equals("nodump"))
- Val.setKind(mcld::ZOption::NoDump);
- else if (Arg.equals("relro"))
- Val.setKind(mcld::ZOption::Relro);
- else if (Arg.equals("norelro"))
- Val.setKind(mcld::ZOption::NoRelro);
- else if (Arg.equals("lazy"))
- Val.setKind(mcld::ZOption::Lazy);
- else if (Arg.equals("now"))
- Val.setKind(mcld::ZOption::Now);
- else if (Arg.equals("origin"))
- Val.setKind(mcld::ZOption::Origin);
- else if (Arg.startswith("common-page-size=")) {
- Val.setKind(mcld::ZOption::CommPageSize);
- long long unsigned size = 0;
- Arg.drop_front(17).getAsInteger(0, size);
- Val.setPageSize(static_cast<uint64_t>(size));
- } else if (Arg.startswith("max-page-size=")) {
- Val.setKind(mcld::ZOption::MaxPageSize);
- long long unsigned size = 0;
- Arg.drop_front(14).getAsInteger(0, size);
- Val.setPageSize(static_cast<uint64_t>(size));
- }
-
- if (mcld::ZOption::Unknown == Val.kind())
- llvm::report_fatal_error(llvm::Twine("unknown -z option: `") + Arg +
- llvm::Twine("'\n"));
- return false;
-}
-
-void parser<mcld::ZOption>::printOptionDiff(
- const llvm::cl::Option& O,
- const mcld::ZOption& V,
- parser<mcld::ZOption>::OptVal Default,
- size_t GlobalWidth) const {
- // TODO
-}
-
-void parser<mcld::ZOption>::anchor() {
- // do nothing
-}
-
-} // namespace cl
-} // namespace llvm
diff --git a/lib/Target/ARM/ARMLDBackend.cpp b/lib/Target/ARM/ARMLDBackend.cpp
index 5d7bc56..0907cac 100644
--- a/lib/Target/ARM/ARMLDBackend.cpp
+++ b/lib/Target/ARM/ARMLDBackend.cpp
@@ -693,8 +693,8 @@
*getBRIslandFactory());
if (stub != NULL) {
switch (config().options().getStripSymbolMode()) {
- case GeneralOptions::StripAllSymbols:
- case GeneralOptions::StripLocals:
+ case GeneralOptions::StripSymbolMode::StripAllSymbols:
+ case GeneralOptions::StripSymbolMode::StripLocals:
break;
default: {
// a stub symbol should be local
diff --git a/lib/Target/GNULDBackend.cpp b/lib/Target/GNULDBackend.cpp
index db612c1..79fa25f 100644
--- a/lib/Target/GNULDBackend.cpp
+++ b/lib/Target/GNULDBackend.cpp
@@ -737,7 +737,7 @@
2. check whether the symbol is used
*/
switch (config().options().getStripSymbolMode()) {
- case GeneralOptions::StripAllSymbols: {
+ case GeneralOptions::StripSymbolMode::StripAllSymbols: {
symtab = strtab = 0;
break;
}
@@ -775,8 +775,7 @@
dynsym_local_cnt = 1 + symbols.numOfLocalDyns();
// compute .gnu.hash
- if (GeneralOptions::GNU == config().options().getHashStyle() ||
- GeneralOptions::Both == config().options().getHashStyle()) {
+ if (config().options().hasGNUHash()) {
// count the number of dynsym to hash
size_t hashed_sym_cnt = 0;
symEnd = symbols.dynamicEnd();
@@ -795,8 +794,7 @@
}
// compute .hash
- if (GeneralOptions::SystemV == config().options().getHashStyle() ||
- GeneralOptions::Both == config().options().getHashStyle()) {
+ if (config().options().hasSysVHash()) {
// Both Elf32_Word and Elf64_Word are 4 bytes
hash = (2 + getHashBucketCount(dynsym, false) + dynsym) *
sizeof(llvm::ELF::Elf32_Word);
@@ -1026,13 +1024,11 @@
Module::SymbolTable& symbols = pModule.getSymbolTable();
// emit .gnu.hash
- if (GeneralOptions::GNU == config().options().getHashStyle() ||
- GeneralOptions::Both == config().options().getHashStyle())
+ if (config().options().hasGNUHash())
emitGNUHashTab(symbols, pOutput);
// emit .hash
- if (GeneralOptions::SystemV == config().options().getHashStyle() ||
- GeneralOptions::Both == config().options().getHashStyle())
+ if (config().options().hasSysVHash())
emitELFHashTab(symbols, pOutput);
// emit .dynsym, and .dynstr (emit LocalDyn and Dynamic category)
@@ -1296,13 +1292,13 @@
void GNULDBackend::orderSymbolTable(Module& pModule) {
Module::SymbolTable& symbols = pModule.getSymbolTable();
- if (GeneralOptions::GNU == config().options().getHashStyle() ||
- GeneralOptions::Both == config().options().getHashStyle())
+ if (config().options().hasGNUHash()) {
// Currently we may add output symbols after sizeNamePools(), and a
// non-stable sort is used in SymbolCategory::arrange(), so we just
// sort .dynsym right before emitting .gnu.hash
std::stable_sort(
symbols.dynamicBegin(), symbols.dynamicEnd(), DynsymCompare());
+ }
}
/// getSectionOrder
diff --git a/lib/Target/Mips/MipsLDBackend.cpp b/lib/Target/Mips/MipsLDBackend.cpp
index 63eeaf9..c629edd 100644
--- a/lib/Target/Mips/MipsLDBackend.cpp
+++ b/lib/Target/Mips/MipsLDBackend.cpp
@@ -287,8 +287,7 @@
} // anonymous namespace
void MipsGNULDBackend::orderSymbolTable(Module& pModule) {
- if (GeneralOptions::GNU == config().options().getHashStyle() ||
- GeneralOptions::Both == config().options().getHashStyle()) {
+ if (config().options().hasGNUHash()) {
// The MIPS ABI and .gnu.hash require .dynsym to be sorted
// in different ways. The MIPS ABI requires a mapping between
// the GOT and the symbol table. At the same time .gnu.hash
diff --git a/tools/mcld/Android.mk b/tools/mcld/Android.mk
index 8dcb836..a9e3dc6 100644
--- a/tools/mcld/Android.mk
+++ b/tools/mcld/Android.mk
@@ -8,17 +8,7 @@
MCLD_C_INCLUDES := $(LOCAL_PATH)/include
MCLD_SRC_FILES := \
- main.cpp \
- lib/DynamicSectionOptions.cpp \
- lib/OptimizationOptions.cpp \
- lib/OutputFormatOptions.cpp \
- lib/PositionalOptions.cpp \
- lib/PreferenceOptions.cpp \
- lib/ScriptOptions.cpp \
- lib/SearchPathOptions.cpp \
- lib/SymbolOptions.cpp \
- lib/TargetControlOptions.cpp \
- lib/TripleOptions.cpp
+ Main.cpp
MCLD_WHOLE_STATIC_LIBRARIES := \
@@ -43,9 +33,10 @@
MCLD_MODULE:= ld.mc
-# Executable the device
+# Executable for the device
# =====================================================
include $(CLEAR_VARS)
+include $(CLEAR_TBLGEN_VARS)
LOCAL_C_INCLUDES := $(MCLD_C_INCLUDES)
LOCAL_SRC_FILES := $(MCLD_SRC_FILES)
@@ -77,12 +68,21 @@
LOCAL_SHARED_LIBRARIES := $(MCLD_SHARED_LIBRARIES) libz
LOCAL_MODULE := $(MCLD_MODULE)
+LOCAL_MODULE_CLASS := EXECUTABLES
+
+# Build Options.inc from Options.td for the device
+intermediates := $(call local-generated-sources-dir)
+LOCAL_GENERATED_SOURCES += $(intermediates)/Options.inc
+$(intermediates)/Options.inc: $(LOCAL_PATH)/Options.td $(LLVM_ROOT_PATH)/include/llvm/Option/OptParser.td $(LLVM_TBLGEN)
+ $(call transform-device-td-to-out,opt-parser-defs)
+
include $(MCLD_DEVICE_BUILD_MK)
include $(BUILD_EXECUTABLE)
-# Executable the host
+# Executable for the host
# =====================================================
include $(CLEAR_VARS)
+include $(CLEAR_TBLGEN_VARS)
LOCAL_C_INCLUDES := $(MCLD_C_INCLUDES)
LOCAL_SRC_FILES := $(MCLD_SRC_FILES)
@@ -98,5 +98,14 @@
LOCAL_SHARED_LIBRARIES := $(MCLD_SHARED_LIBRARIES) libz-host
LOCAL_MODULE := $(MCLD_MODULE)
+LOCAL_MODULE_CLASS := EXECUTABLES
+LOCAL_IS_HOST_MODULE := true
+
+# Build Options.inc from Options.td for the host
+intermediates := $(call local-generated-sources-dir)
+LOCAL_GENERATED_SOURCES += $(intermediates)/Options.inc
+$(intermediates)/Options.inc: $(LOCAL_PATH)/Options.td $(LLVM_ROOT_PATH)/include/llvm/Option/OptParser.td $(LLVM_TBLGEN)
+ $(call transform-host-td-to-out,opt-parser-defs)
+
include $(MCLD_HOST_BUILD_MK)
include $(BUILD_HOST_EXECUTABLE)
diff --git a/tools/mcld/Main.cpp b/tools/mcld/Main.cpp
new file mode 100644
index 0000000..7231d3c
--- /dev/null
+++ b/tools/mcld/Main.cpp
@@ -0,0 +1,1064 @@
+//===- Main.cpp -----------------------------------------------------------===//
+//
+// The MCLinker Project
+//
+// This file is distributed under the University of Illinois Open Source
+// License. See LICENSE.TXT for details.
+//
+//===----------------------------------------------------------------------===//
+#include <mcld/Environment.h>
+#include <mcld/IRBuilder.h>
+#include <mcld/Linker.h>
+#include <mcld/LinkerConfig.h>
+#include <mcld/LinkerScript.h>
+#include <mcld/Module.h>
+#include <mcld/ADT/StringEntry.h>
+#include <mcld/MC/InputAction.h>
+#include <mcld/MC/CommandAction.h>
+#include <mcld/MC/FileAction.h>
+#include <mcld/MC/ZOption.h>
+#include <mcld/Support/raw_ostream.h>
+#include <mcld/Support/MsgHandling.h>
+#include <mcld/Support/Path.h>
+#include <mcld/Support/SystemUtils.h>
+#include <mcld/Support/TargetRegistry.h>
+
+#include <llvm/ADT/ArrayRef.h>
+#include <llvm/ADT/SmallVector.h>
+#include <llvm/ADT/STLExtras.h>
+#include <llvm/ADT/StringRef.h>
+#include <llvm/ADT/StringSwitch.h>
+#include <llvm/Option/Arg.h>
+#include <llvm/Option/ArgList.h>
+#include <llvm/Option/OptTable.h>
+#include <llvm/Option/Option.h>
+#include <llvm/Support/ManagedStatic.h>
+#include <llvm/Support/Process.h>
+#include <llvm/Support/Signals.h>
+
+#include <cassert>
+#include <cstdlib>
+#include <string>
+
+#if defined(HAVE_UNISTD_H)
+#include <unistd.h>
+#endif
+
+#if defined(_MSC_VER) || defined(__MINGW32__)
+#include <io.h>
+#ifndef STDIN_FILENO
+#define STDIN_FILENO 0
+#endif
+#ifndef STDOUT_FILENO
+#define STDOUT_FILENO 1
+#endif
+#ifndef STDERR_FILENO
+#define STDERR_FILENO 2
+#endif
+#endif
+
+namespace {
+
+class Driver {
+ private:
+ enum Option {
+ // This is not an option.
+ kOpt_INVALID = 0,
+#define OPTION(PREFIX, NAME, ID, KIND, GROUP, ALIAS, ALIASARGS, FLAGS, PARAM, \
+ HELPTEXT, METAVAR) \
+ kOpt_ ## ID,
+#include "Options.inc" // NOLINT
+#undef OPTION
+ kOpt_LastOption
+ };
+
+ class OptTable : public llvm::opt::OptTable {
+ private:
+#define PREFIX(NAME, VALUE) \
+ static const char* const NAME[];
+#include "Options.inc" // NOLINT
+#undef PREFIX
+ static const llvm::opt::OptTable::Info InfoTable[];
+
+ public:
+ OptTable();
+ };
+
+ private:
+ Driver(const char* prog_name, std::unique_ptr<llvm::opt::InputArgList> args)
+ : prog_name_(prog_name),
+ args_(std::move(args)),
+ module_(script_),
+ ir_builder_(module_, config_) {
+ return;
+ }
+
+ public:
+ static std::unique_ptr<Driver> Create(llvm::ArrayRef<const char*> argv);
+
+ bool Run();
+
+ private:
+ bool TranslateArguments();
+
+ private:
+ const char* prog_name_;
+
+ std::unique_ptr<llvm::opt::InputArgList> args_;
+
+ mcld::LinkerScript script_;
+
+ mcld::LinkerConfig config_;
+
+ mcld::Module module_;
+
+ mcld::IRBuilder ir_builder_;
+
+ mcld::Linker linker_;
+
+ private:
+ DISALLOW_COPY_AND_ASSIGN(Driver);
+};
+
+#define PREFIX(NAME, VALUE) \
+ const char* const Driver::OptTable::NAME[] = VALUE;
+#include "Options.inc" // NOLINT
+#undef PREFIX
+
+const llvm::opt::OptTable::Info Driver::OptTable::InfoTable[] = {
+#define OPTION(PREFIX, NAME, ID, KIND, GROUP, ALIAS, ALIASARGS, FLAGS, PARAM, \
+ HELPTEXT, METAVAR) \
+ { PREFIX, NAME, HELPTEXT, METAVAR, kOpt_ ## ID, \
+ llvm::opt::Option::KIND ## Class, PARAM, FLAGS, kOpt_ ## GROUP, \
+ kOpt_ ## ALIAS, ALIASARGS },
+#include "Options.inc"
+#undef OPTION
+};
+
+Driver::OptTable::OptTable()
+ : llvm::opt::OptTable(InfoTable, llvm::array_lengthof(InfoTable)) { }
+
+inline bool ShouldColorize() {
+ const char* term = getenv("TERM");
+ return term && (0 != strcmp(term, "dumb"));
+}
+
+/// ParseProgName - Parse program name
+/// This function simplifies cross-compiling by reading triple from the program
+/// name. For example, if the program name is `arm-linux-eabi-ld.mcld', we can
+/// get the triple is arm-linux-eabi by the program name.
+inline std::string ParseProgName(const char* prog_name) {
+ static const char* suffixes[] = {"ld", "ld.mcld"};
+
+ std::string name(mcld::sys::fs::Path(prog_name).stem().native());
+
+ for (size_t i = 0; i < sizeof(suffixes) / sizeof(suffixes[0]); ++i) {
+ if (name == suffixes[i])
+ return std::string();
+ }
+
+ llvm::StringRef prog_name_ref(prog_name);
+ llvm::StringRef prefix;
+
+ for (size_t i = 0; i < sizeof(suffixes) / sizeof(suffixes[0]); ++i) {
+ if (!prog_name_ref.endswith(suffixes[i]))
+ continue;
+
+ llvm::StringRef::size_type last_component =
+ prog_name_ref.rfind('-', prog_name_ref.size() - strlen(suffixes[i]));
+ if (last_component == llvm::StringRef::npos)
+ continue;
+ llvm::StringRef prefix = prog_name_ref.slice(0, last_component);
+ std::string ignored_error;
+ if (!mcld::TargetRegistry::lookupTarget(prefix, ignored_error))
+ continue;
+ return prefix.str();
+ }
+ return std::string();
+}
+
+inline void ParseEmulation(llvm::Triple& triple, const char* emulation) {
+ llvm::Triple emu_triple =
+ llvm::StringSwitch<llvm::Triple>(emulation)
+ .Case("aarch64linux", llvm::Triple("aarch64", "", "linux", "gnu"))
+ .Case("armelf_linux_eabi", llvm::Triple("arm", "", "linux", "gnu"))
+ .Case("elf_i386", llvm::Triple("i386", "", "", "gnu"))
+ .Case("elf_x86_64", llvm::Triple("x86_64", "", "", "gnu"))
+ .Case("elf32_x86_64", llvm::Triple("x86_64", "", "", "gnux32"))
+ .Case("elf_i386_fbsd", llvm::Triple("i386", "", "freebsd", "gnu"))
+ .Case("elf_x86_64_fbsd", llvm::Triple("x86_64", "", "freebsd", "gnu"))
+ .Case("elf32ltsmip", llvm::Triple("mipsel", "", "", "gnu"))
+ .Case("elf64ltsmip", llvm::Triple("mips64el", "", "", "gnu"))
+ .Default(llvm::Triple());
+
+ if (emu_triple.getArch() == llvm::Triple::UnknownArch &&
+ emu_triple.getOS() == llvm::Triple::UnknownOS &&
+ emu_triple.getEnvironment() == llvm::Triple::UnknownEnvironment)
+ mcld::error(mcld::diag::err_invalid_emulation) << emulation << "\n";
+
+ if (emu_triple.getArch() != llvm::Triple::UnknownArch)
+ triple.setArch(emu_triple.getArch());
+
+ if (emu_triple.getOS() != llvm::Triple::UnknownOS)
+ triple.setOS(emu_triple.getOS());
+
+ if (emu_triple.getEnvironment() != llvm::Triple::UnknownEnvironment)
+ triple.setEnvironment(emu_triple.getEnvironment());
+}
+
+/// Configure the output filename.
+inline bool ConfigureOutputName(llvm::StringRef output_name,
+ mcld::Module& module,
+ mcld::LinkerConfig& config) {
+ std::string output(output_name.str());
+ if (output.empty()) {
+ if (config.targets().triple().getOS() == llvm::Triple::Win32) {
+ output.assign("_out");
+ switch (config.codeGenType()) {
+ case mcld::LinkerConfig::Object: {
+ output += ".obj";
+ break;
+ }
+ case mcld::LinkerConfig::DynObj: {
+ output += ".dll";
+ break;
+ }
+ case mcld::LinkerConfig::Exec: {
+ output += ".exe";
+ break;
+ }
+ case mcld::LinkerConfig::External:
+ break;
+ default: {
+ return false;
+ break;
+ }
+ } // switch (config.codeGenType())
+ } else {
+ output.assign("a.out");
+ }
+ } // if (output.empty())
+
+ module.setName(output);
+ return true;
+}
+
+bool InitializeInputs(mcld::IRBuilder& ir_builder,
+ std::vector<std::unique_ptr<mcld::InputAction>>& input_actions) {
+ for (auto& action : input_actions) {
+ assert(action != nullptr);
+ action->activate(ir_builder.getInputBuilder());
+ }
+
+ if (ir_builder.getInputBuilder().isInGroup()) {
+ mcld::fatal(mcld::diag::fatal_forbid_nest_group);
+ return false;
+ }
+
+ return true;
+}
+
+bool Driver::TranslateArguments() {
+ //===--------------------------------------------------------------------===//
+ // Preference
+ //===--------------------------------------------------------------------===//
+
+ // --color=mode
+ if (llvm::opt::Arg* arg = args_->getLastArg(kOpt_Color)) {
+ bool res = llvm::StringSwitch<bool>(arg->getValue())
+ .Case("never", false)
+ .Case("always", true)
+ .Case("auto", ShouldColorize() &&
+ llvm::sys::Process::FileDescriptorIsDisplayed(
+ STDOUT_FILENO))
+ .Default(false);
+ config_.options().setColor(res);
+ mcld::outs().setColor(res);
+ mcld::errs().setColor(res);
+ }
+
+ // --trace
+ config_.options().setTrace(args_->hasArg(kOpt_Trace));
+
+ // --verbose=level
+ if (llvm::opt::Arg* arg = args_->getLastArg(kOpt_Verbose)) {
+ llvm::StringRef value = arg->getValue();
+ int level;
+ if (value.getAsInteger(0, level)) {
+ mcld::errs() << "Invalid value for" << arg->getOption().getPrefixedName()
+ << ": " << arg->getValue();
+ return false;
+ }
+ config_.options().setVerbose(level);
+ }
+
+ // --error-limit NUMBER
+ if (llvm::opt::Arg* arg = args_->getLastArg(kOpt_ErrorLimit)) {
+ llvm::StringRef value = arg->getValue();
+ int num;
+ if (value.getAsInteger(0, num) || (num < 0)) {
+ mcld::errs() << "Invalid value for" << arg->getOption().getPrefixedName()
+ << ": " << arg->getValue();
+ return false;
+ }
+ config_.options().setMaxErrorNum(num);
+ }
+
+ // --warning-limit NUMBER
+ if (llvm::opt::Arg* arg = args_->getLastArg(kOpt_WarningLimit)) {
+ llvm::StringRef value = arg->getValue();
+ int num;
+ if (value.getAsInteger(0, num) || (num < 0)) {
+ mcld::errs() << "Invalid value for" << arg->getOption().getPrefixedName()
+ << ": " << arg->getValue();
+ return false;
+ }
+ config_.options().setMaxWarnNum(num);
+ }
+
+ // --warn-shared-textrel
+ config_.options().setWarnSharedTextrel(args_->hasArg(kOpt_WarnSharedTextrel));
+
+ //===--------------------------------------------------------------------===//
+ // Target
+ //===--------------------------------------------------------------------===//
+ llvm::Triple triple;
+ if (llvm::opt::Arg* arg = args_->getLastArg(kOpt_Triple)) {
+ // 1. Use the triple from command.
+ // -mtriple=value
+ triple.setTriple(arg->getValue());
+ } else {
+ std::string prog_triple = ParseProgName(prog_name_);
+ if (!prog_triple.empty()) {
+ // 2. Use the triple from the program name prefix.
+ triple.setTriple(prog_triple);
+ } else {
+ // 3. Use the default target triple.
+ triple.setTriple(mcld::sys::getDefaultTargetTriple());
+ }
+ }
+
+ // If a specific emulation was requested, apply it now.
+ if (llvm::opt::Arg* arg = args_->getLastArg(kOpt_Emulation)) {
+ // -m emulation
+ ParseEmulation(triple, arg->getValue());
+ } else if (llvm::opt::Arg* arg = args_->getLastArg(kOpt_Arch)) {
+ // -march=value
+ config_.targets().setArch(arg->getValue());
+ }
+
+ if (llvm::opt::Arg* arg = args_->getLastArg(kOpt_CPU)) {
+ config_.targets().setTargetCPU(arg->getValue());
+ }
+
+ config_.targets().setTriple(triple);
+
+ // --gpsize=value
+ if (llvm::opt::Arg* arg = args_->getLastArg(kOpt_GPSize)) {
+ llvm::StringRef value = arg->getValue();
+ int size;
+ if (value.getAsInteger(0, size) || (size< 0)) {
+ mcld::errs() << "Invalid value for" << arg->getOption().getPrefixedName()
+ << ": " << arg->getValue() << "\n";
+ return false;
+ }
+ config_.options().setGPSize(size);
+ }
+
+ //===--------------------------------------------------------------------===//
+ // Dynamic
+ //===--------------------------------------------------------------------===//
+
+ // --entry=entry
+ if (llvm::opt::Arg* arg = args_->getLastArg(kOpt_Entry)) {
+ script_.setEntry(arg->getValue());
+ }
+
+ // -Bsymbolic
+ config_.options().setBsymbolic(args_->hasArg(kOpt_Bsymbolic));
+
+ // -Bgroup
+ config_.options().setBgroup(args_->hasArg(kOpt_Bgroup));
+
+ // -soname=name
+ if (llvm::opt::Arg* arg = args_->getLastArg(kOpt_SOName)) {
+ config_.options().setSOName(arg->getValue());
+ }
+
+ // --no-undefined
+ if (args_->hasArg(kOpt_NoUndef)) {
+ config_.options().setNoUndefined(true);
+ }
+
+ // --allow-multiple-definition
+ if (args_->hasArg(kOpt_AllowMulDefs)) {
+ config_.options().setMulDefs(true);
+ }
+
+ // -z options
+ for (llvm::opt::Arg* arg : args_->filtered(kOpt_Z)) {
+ llvm::StringRef value = arg->getValue();
+ mcld::ZOption z_opt =
+ llvm::StringSwitch<mcld::ZOption>(value)
+ .Case("combreloc", mcld::ZOption(mcld::ZOption::CombReloc))
+ .Case("nocombreloc", mcld::ZOption(mcld::ZOption::NoCombReloc))
+ .Case("defs", mcld::ZOption(mcld::ZOption::Defs))
+ .Case("execstack", mcld::ZOption(mcld::ZOption::ExecStack))
+ .Case("noexecstack", mcld::ZOption(mcld::ZOption::NoExecStack))
+ .Case("initfirst", mcld::ZOption(mcld::ZOption::InitFirst))
+ .Case("interpose", mcld::ZOption(mcld::ZOption::InterPose))
+ .Case("loadfltr", mcld::ZOption(mcld::ZOption::LoadFltr))
+ .Case("muldefs", mcld::ZOption(mcld::ZOption::MulDefs))
+ .Case("nocopyreloc", mcld::ZOption(mcld::ZOption::NoCopyReloc))
+ .Case("nodefaultlib", mcld::ZOption(mcld::ZOption::NoDefaultLib))
+ .Case("nodelete", mcld::ZOption(mcld::ZOption::NoDelete))
+ .Case("nodlopen", mcld::ZOption(mcld::ZOption::NoDLOpen))
+ .Case("nodump", mcld::ZOption(mcld::ZOption::NoDump))
+ .Case("relro", mcld::ZOption(mcld::ZOption::Relro))
+ .Case("norelro", mcld::ZOption(mcld::ZOption::NoRelro))
+ .Case("lazy", mcld::ZOption(mcld::ZOption::Lazy))
+ .Case("now", mcld::ZOption(mcld::ZOption::Now))
+ .Case("origin", mcld::ZOption(mcld::ZOption::Origin))
+ .Default(mcld::ZOption());
+
+ if (z_opt.kind() == mcld::ZOption::Unknown) {
+ if (value.startswith("common-page-size=")) {
+ // -z common-page-size=value
+ z_opt.setKind(mcld::ZOption::CommPageSize);
+ long long unsigned size = 0;
+ value.drop_front(17).getAsInteger(0, size);
+ z_opt.setPageSize(static_cast<uint64_t>(size));
+ } else if (value.startswith("max-page-size=")) {
+ // -z max-page-size=value
+ z_opt.setKind(mcld::ZOption::MaxPageSize);
+ long long unsigned size = 0;
+ value.drop_front(14).getAsInteger(0, size);
+ z_opt.setPageSize(static_cast<uint64_t>(size));
+ }
+ }
+ config_.options().addZOption(z_opt);
+ }
+
+ // --dynamic-linker=file
+ if (llvm::opt::Arg* arg = args_->getLastArg(kOpt_Dyld)) {
+ config_.options().setDyld(arg->getValue());
+ }
+
+ // --enable-new-dtags
+ config_.options().setNewDTags(args_->hasArg(kOpt_EnableNewDTags));
+
+ // --spare-dyanmic-tags COUNT
+ if (llvm::opt::Arg* arg = args_->getLastArg(kOpt_SpareDTags)) {
+ llvm::StringRef value = arg->getValue();
+ int num;
+ if (value.getAsInteger(0, num) || (num < 0)) {
+ mcld::errs() << "Invalid value for" << arg->getOption().getPrefixedName()
+ << ": " << arg->getValue() << "\n";
+ return false;
+ }
+ config_.options().setNumSpareDTags(num);
+ }
+
+ //===--------------------------------------------------------------------===//
+ // Output
+ //===--------------------------------------------------------------------===//
+
+ // Setup the codegen type.
+ if (args_->hasArg(kOpt_Shared) || args_->hasArg(kOpt_PIE)) {
+ // -shared, -pie
+ config_.setCodeGenType(mcld::LinkerConfig::DynObj);
+ } else if (args_->hasArg(kOpt_Relocatable)) {
+ // -r
+ config_.setCodeGenType(mcld::LinkerConfig::Object);
+ } else if (llvm::opt::Arg* arg = args_->getLastArg(kOpt_OutputFormat)) {
+ // --oformat=value
+ llvm::StringRef value = arg->getValue();
+ if (value.equals("binary")) {
+ config_.setCodeGenType(mcld::LinkerConfig::Binary);
+ }
+ } else {
+ config_.setCodeGenType(mcld::LinkerConfig::Exec);
+ }
+
+ // Setup the output filename.
+ llvm::StringRef output_name;
+ if (llvm::opt::Arg* arg = args_->getLastArg(kOpt_Output)) {
+ output_name = arg->getValue();
+ }
+ if (!ConfigureOutputName(output_name, module_, config_)) {
+ mcld::unreachable(mcld::diag::unrecognized_output_file) << module_.name();
+ return false;
+ } else {
+ if (!args_->hasArg(kOpt_SOName)) {
+ config_.options().setSOName(module_.name());
+ }
+ }
+
+ // --format=value
+ if (llvm::opt::Arg* arg = args_->getLastArg(kOpt_InputFormat)) {
+ llvm::StringRef value = arg->getValue();
+ if (value.equals("binary")) {
+ config_.options().setBinaryInput();
+ }
+ }
+
+ // Setup debug info stripping.
+ config_.options().setStripDebug(args_->hasArg(kOpt_StripDebug) ||
+ args_->hasArg(kOpt_StripAll));
+
+ // Setup symbol stripping mode.
+ if (args_->hasArg(kOpt_StripAll)) {
+ config_.options().setStripSymbols(
+ mcld::GeneralOptions::StripSymbolMode::StripAllSymbols);
+ } else if (args_->hasArg(kOpt_DiscardAll)) {
+ config_.options().setStripSymbols(
+ mcld::GeneralOptions::StripSymbolMode::StripLocals);
+ } else if (args_->hasArg(kOpt_DiscardLocals)) {
+ config_.options().setStripSymbols(
+ mcld::GeneralOptions::StripSymbolMode::StripTemporaries);
+ } else {
+ config_.options().setStripSymbols(
+ mcld::GeneralOptions::StripSymbolMode::KeepAllSymbols);
+ }
+
+ // --eh-frame-hdr
+ config_.options().setEhFrameHdr(args_->hasArg(kOpt_EHFrameHdr));
+
+ // -pie
+ config_.options().setPIE(args_->hasArg(kOpt_PIE));
+
+ // --nmagic
+ config_.options().setNMagic(args_->hasArg(kOpt_NMagic));
+
+ // --omagic
+ config_.options().setOMagic(args_->hasArg(kOpt_OMagic));
+
+ // --hash-style=style
+ if (llvm::opt::Arg* arg = args_->getLastArg(kOpt_HashStyle)) {
+ mcld::GeneralOptions::HashStyle style =
+ llvm::StringSwitch<mcld::GeneralOptions::HashStyle>(arg->getValue())
+ .Case("sysv", mcld::GeneralOptions::HashStyle::SystemV)
+ .Case("gnu", mcld::GeneralOptions::HashStyle::GNU)
+ .Case("both", mcld::GeneralOptions::HashStyle::Both)
+ .Default(mcld::GeneralOptions::HashStyle::Unknown);
+ if (style != mcld::GeneralOptions::HashStyle::Unknown) {
+ config_.options().setHashStyle(style);
+ }
+ }
+
+ // --[no]-export-dynamic
+ if (llvm::opt::Arg* arg = args_->getLastArg(kOpt_ExportDynamic,
+ kOpt_NoExportDynamic)) {
+ if (arg->getOption().matches(kOpt_ExportDynamic)) {
+ config_.options().setExportDynamic(true);
+ } else {
+ config_.options().setExportDynamic(false);
+ }
+ }
+
+ // --no-warn-mismatch
+ config_.options().setWarnMismatch(!args_->hasArg(kOpt_NoWarnMismatch));
+
+ // --exclude-libs
+ if (llvm::opt::Arg* arg = args_->getLastArg(kOpt_ExcludeLibs)) {
+ llvm::StringRef value = arg->getValue();
+ do {
+ std::pair<llvm::StringRef, llvm::StringRef> res = value.split(',');
+ config_.options().excludeLIBS().insert(res.first.str());
+ value = res.second;
+ } while (!value.empty());
+ }
+
+ //===--------------------------------------------------------------------===//
+ // Search Path
+ //===--------------------------------------------------------------------===//
+
+ // --sysroot
+ if (llvm::opt::Arg* arg = args_->getLastArg(kOpt_Sysroot)) {
+ mcld::sys::fs::Path path(arg->getValue());
+ if (mcld::sys::fs::exists(path) && mcld::sys::fs::is_directory(path)) {
+ script_.setSysroot(path);
+ }
+ }
+
+ // -L searchdir
+ for (llvm::opt::Arg* arg : args_->filtered(kOpt_LibraryPath)) {
+ if (!script_.directories().insert(arg->getValue())) {
+ // FIXME: need a warning function
+ mcld::errs() << "WARNING: can not open search directory `-L"
+ << arg->getValue() << "'.\n";
+ }
+ }
+
+ // -nostdlib
+ config_.options().setNoStdlib(args_->hasArg(kOpt_NoStdlib));
+
+ // -rpath=path
+ for (llvm::opt::Arg* arg : args_->filtered(kOpt_RPath)) {
+ config_.options().getRpathList().push_back(arg->getValue());
+ }
+
+ //===--------------------------------------------------------------------===//
+ // Symbol
+ //===--------------------------------------------------------------------===//
+
+ // -d/-dc/-dp
+ config_.options().setDefineCommon(args_->hasArg(kOpt_DefineCommon));
+
+ // -u symbol
+ for (llvm::opt::Arg* arg : args_->filtered(kOpt_Undefined)) {
+ config_.options().getUndefSymList().push_back(arg->getValue());
+ }
+
+ //===--------------------------------------------------------------------===//
+ // Script
+ //===--------------------------------------------------------------------===//
+
+ // --wrap=symbol
+ for (llvm::opt::Arg* arg : args_->filtered(kOpt_Wrap)) {
+ bool exist = false;
+ const char* symbol = arg->getValue();
+ // symbol -> __wrap_symbol
+ mcld::StringEntry<llvm::StringRef>* to_wrap =
+ script_.renameMap().insert(symbol, exist);
+
+ std::string to_wrap_str;
+ to_wrap_str.append("__wrap_")
+ .append(symbol);
+ to_wrap->setValue(to_wrap_str);
+
+ if (exist)
+ mcld::warning(mcld::diag::rewrap) << symbol << to_wrap_str;
+
+ // __real_symbol -> symbol
+ std::string from_real_str;
+ to_wrap_str.append("__real_")
+ .append(symbol);
+ mcld::StringEntry<llvm::StringRef>* from_real =
+ script_.renameMap().insert(from_real_str, exist);
+ from_real->setValue(symbol);
+
+ if (exist)
+ mcld::warning(mcld::diag::rewrap) << symbol << from_real_str;
+ }
+
+ // --portalbe=symbol
+ for (llvm::opt::Arg* arg : args_->filtered(kOpt_Wrap)) {
+ bool exist = false;
+ const char* symbol = arg->getValue();
+ // symbol -> symbol_portable
+ mcld::StringEntry<llvm::StringRef>* to_wrap =
+ script_.renameMap().insert(symbol, exist);
+
+ std::string to_wrap_str;
+ to_wrap_str.append(symbol)
+ .append("_portable");
+ to_wrap->setValue(to_wrap_str);
+
+ if (exist)
+ mcld::warning(mcld::diag::rewrap) << symbol << to_wrap_str;
+
+ // __real_symbol -> symbol
+ std::string from_real_str;
+ to_wrap_str.append("__real_")
+ .append(symbol);
+ mcld::StringEntry<llvm::StringRef>* from_real =
+ script_.renameMap().insert(from_real_str, exist);
+ from_real->setValue(symbol);
+
+ if (exist)
+ mcld::warning(mcld::diag::rewrap) << symbol << from_real_str;
+ }
+
+ // --section-start=section=addr
+ for (llvm::opt::Arg* arg : args_->filtered(kOpt_SectionStart)) {
+ llvm::StringRef value = arg->getValue();
+ const size_t pos = value.find('=');
+ uint64_t addr = 0;
+ value.substr(pos + 1).getAsInteger(0, addr);
+ bool exist = false;
+ mcld::StringEntry<uint64_t>* mapping =
+ script_.addressMap().insert(value.substr(0, pos), exist);
+ mapping->setValue(addr);
+ }
+
+ // -Tbss=value
+ if (llvm::opt::Arg* arg = args_->getLastArg(kOpt_Tbss)) {
+ llvm::StringRef value = arg->getValue();
+ uint64_t addr = 0;
+ if (value.getAsInteger(0, addr)) {
+ mcld::errs() << "Invalid value for" << arg->getOption().getPrefixedName()
+ << ": " << arg->getValue() << "\n";
+ return false;
+ }
+ bool exist = false;
+ mcld::StringEntry<uint64_t>* mapping =
+ script_.addressMap().insert(".bss", exist);
+ mapping->setValue(addr);
+ }
+
+ // -Tdata=value
+ if (llvm::opt::Arg* arg = args_->getLastArg(kOpt_Tdata)) {
+ llvm::StringRef value = arg->getValue();
+ uint64_t addr = 0;
+ if (value.getAsInteger(0, addr)) {
+ mcld::errs() << "Invalid value for" << arg->getOption().getPrefixedName()
+ << ": " << arg->getValue() << "\n";
+ return false;
+ }
+ bool exist = false;
+ mcld::StringEntry<uint64_t>* mapping =
+ script_.addressMap().insert(".data", exist);
+ mapping->setValue(addr);
+ }
+
+ // -Ttext=value
+ if (llvm::opt::Arg* arg = args_->getLastArg(kOpt_Ttext)) {
+ llvm::StringRef value = arg->getValue();
+ uint64_t addr = 0;
+ if (value.getAsInteger(0, addr)) {
+ mcld::errs() << "Invalid value for" << arg->getOption().getPrefixedName()
+ << ": " << arg->getValue() << "\n";
+ return false;
+ }
+ bool exist = false;
+ mcld::StringEntry<uint64_t>* mapping =
+ script_.addressMap().insert(".text", exist);
+ mapping->setValue(addr);
+ }
+
+ //===--------------------------------------------------------------------===//
+ // Optimization
+ //===--------------------------------------------------------------------===//
+
+ // --[no-]gc-sections
+ if (llvm::opt::Arg* arg = args_->getLastArg(kOpt_GCSections,
+ kOpt_NoGCSections)) {
+ if (arg->getOption().matches(kOpt_GCSections)) {
+ config_.options().setGCSections(true);
+ } else {
+ config_.options().setGCSections(false);
+ }
+ }
+
+ // --[no-]print-gc-sections
+ if (llvm::opt::Arg* arg = args_->getLastArg(kOpt_PrintGCSections,
+ kOpt_NoPrintGCSections)) {
+ if (arg->getOption().matches(kOpt_PrintGCSections)) {
+ config_.options().setPrintGCSections(true);
+ } else {
+ config_.options().setPrintGCSections(false);
+ }
+ }
+
+ // --[no-]ld-generated-unwind-info
+ if (llvm::opt::Arg* arg = args_->getLastArg(kOpt_LDGeneratedUnwindInfo,
+ kOpt_NoLDGeneratedUnwindInfo)) {
+ if (arg->getOption().matches(kOpt_LDGeneratedUnwindInfo)) {
+ config_.options().setGenUnwindInfo(true);
+ } else {
+ config_.options().setGenUnwindInfo(false);
+ }
+ }
+
+ // --icf=mode
+ if (llvm::opt::Arg* arg = args_->getLastArg(kOpt_ICF)) {
+ mcld::GeneralOptions::ICF mode =
+ llvm::StringSwitch<mcld::GeneralOptions::ICF>(arg->getValue())
+ .Case("none", mcld::GeneralOptions::ICF::None)
+ .Case("all", mcld::GeneralOptions::ICF::All)
+ .Case("safe", mcld::GeneralOptions::ICF::Safe)
+ .Default(mcld::GeneralOptions::ICF::Unknown);
+ if (mode == mcld::GeneralOptions::ICF::Unknown) {
+ mcld::errs() << "Invalid value for" << arg->getOption().getPrefixedName()
+ << ": " << arg->getValue() << "\n";
+ return false;
+ }
+ config_.options().setICFMode(mode);
+ }
+
+ // --icf-iterations
+ if (llvm::opt::Arg* arg = args_->getLastArg(kOpt_ICFIters)) {
+ llvm::StringRef value = arg->getValue();
+ int num;
+ if (value.getAsInteger(0, num) || (num < 0)) {
+ mcld::errs() << "Invalid value for" << arg->getOption().getPrefixedName()
+ << ": " << arg->getValue() << "\n";
+ return false;
+ }
+ config_.options().setICFIterations(num);
+ }
+
+ // --[no-]print-icf-sections
+ if (llvm::opt::Arg* arg = args_->getLastArg(kOpt_PrintICFSections,
+ kOpt_NoPrintICFSections)) {
+ if (arg->getOption().matches(kOpt_PrintICFSections)) {
+ config_.options().setPrintICFSections(true);
+ } else {
+ config_.options().setPrintICFSections(false);
+ }
+ }
+
+ //===--------------------------------------------------------------------===//
+ // Positional
+ //===--------------------------------------------------------------------===//
+
+ // # of regular objects, script, and namespec.
+ size_t input_num = 0;
+ typedef std::unique_ptr<mcld::InputAction> Action;
+
+ std::vector<Action> actions;
+ Action action;
+ actions.reserve(32);
+
+ for (llvm::opt::Arg* arg : *args_) {
+ const unsigned index = arg->getIndex();
+
+ switch (arg->getOption().getID()) {
+ // -T script
+ case kOpt_Script: {
+ const char* value = arg->getValue();
+ config_.options().getScriptList().push_back(value);
+
+ // FIXME: Let index of script file be 0.
+ action.reset(new mcld::ScriptAction(
+ 0x0, value, mcld::ScriptFile::LDScript, script_.directories()));
+ actions.push_back(std::move(action));
+
+ action.reset(new mcld::ContextAction(0x0));
+ actions.push_back(std::move(action));
+
+ action.reset(new mcld::MemoryAreaAction(0x0,
+ mcld::FileHandle::ReadOnly));
+ actions.push_back(std::move(action));
+
+ ++input_num;
+ break;
+ }
+
+ // --defsym=symbol=expr
+ case kOpt_DefSym: {
+ std::string expr;
+ expr.append(arg->getValue())
+ .append(";");
+ script_.defsyms().push_back(std::move(expr));
+ action.reset(new mcld::DefSymAction(index, script_.defsyms().back()));
+ actions.push_back(std::move(action));
+ break;
+ }
+
+ // -l namespec
+ case kOpt_Namespec: {
+ action.reset(new mcld::NamespecAction(
+ index, arg->getValue(), script_.directories()));
+ actions.push_back(std::move(action));
+
+ action.reset(new mcld::ContextAction(index));
+ actions.push_back(std::move(action));
+
+ action.reset(new mcld::MemoryAreaAction(index,
+ mcld::FileHandle::ReadOnly));
+ actions.push_back(std::move(action));
+
+ ++input_num;
+ break;
+ }
+
+ // --whole-archive
+ case kOpt_WholeArchive: {
+ action.reset(new mcld::WholeArchiveAction(index));
+ actions.push_back(std::move(action));
+ break;
+ }
+
+ // --no-whole-archive
+ case kOpt_NoWholeArchive: {
+ action.reset(new mcld::NoWholeArchiveAction(index));
+ actions.push_back(std::move(action));
+ break;
+ }
+
+ // --as-needed
+ case kOpt_AsNeeded: {
+ action.reset(new mcld::AsNeededAction(index));
+ actions.push_back(std::move(action));
+ break;
+ }
+
+ // --no-as-needed
+ case kOpt_NoAsNeeded: {
+ action.reset(new mcld::NoAsNeededAction(index));
+ actions.push_back(std::move(action));
+ break;
+ }
+
+ // --add-needed
+ // FIXME: This is deprecated. Should be --copy-dt-needed-entries.
+ case kOpt_AddNeeded:
+ case kOpt_CopyDTNeeded: {
+ action.reset(new mcld::AddNeededAction(index));
+ actions.push_back(std::move(action));
+ break;
+ }
+
+ // --no-add-needed
+ // FIXME: This is deprecated. Should be --no-copy-dt-needed-entries.
+ case kOpt_NoAddNeeded:
+ case kOpt_NoCopyDTNeeded: {
+ action.reset(new mcld::AddNeededAction(index));
+ actions.push_back(std::move(action));
+ break;
+ }
+
+ // -Bdynamic
+ case kOpt_Bdynamic: {
+ action.reset(new mcld::BDynamicAction(index));
+ actions.push_back(std::move(action));
+ break;
+ }
+
+ // -Bstatic
+ case kOpt_Bstatic: {
+ action.reset(new mcld::BStaticAction(index));
+ actions.push_back(std::move(action));
+ break;
+ }
+
+ // --start-group
+ case kOpt_StartGroup: {
+ action.reset(new mcld::StartGroupAction(index));
+ actions.push_back(std::move(action));
+ break;
+ }
+
+ // --end-group
+ case kOpt_EndGroup: {
+ action.reset(new mcld::EndGroupAction(index));
+ actions.push_back(std::move(action));
+ break;
+ }
+
+ case kOpt_INPUT: {
+ action.reset(new mcld::InputFileAction(index, arg->getValue()));
+ actions.push_back(std::move(action));
+
+ action.reset(new mcld::ContextAction(index));
+ actions.push_back(std::move(action));
+
+ action.reset(new mcld::MemoryAreaAction(index,
+ mcld::FileHandle::ReadOnly));
+ actions.push_back(std::move(action));
+
+ ++input_num;
+ break;
+ }
+
+ default:
+ break;
+ }
+ }
+
+ if (input_num == 0) {
+ mcld::fatal(mcld::diag::err_no_inputs);
+ return false;
+ }
+
+ // Stable sort
+ std::stable_sort(actions.begin(),
+ actions.end(),
+ [] (const Action& X, const Action& Y) {
+ return X->position() < Y->position();
+ });
+
+ if (!InitializeInputs(ir_builder_, actions)) {
+ mcld::errs() << "Failed to initialize input tree!\n";
+ return false;
+ }
+
+ return true;
+}
+
+std::unique_ptr<llvm::opt::InputArgList>
+ParseArgs(const llvm::opt::OptTable& opt_table,
+ llvm::ArrayRef<const char*> argv) {
+ unsigned missing_arg_idx;
+ unsigned missing_arg_count;
+
+ std::unique_ptr<llvm::opt::InputArgList> args(
+ opt_table.ParseArgs(argv.begin(), argv.end(), missing_arg_idx,
+ missing_arg_count));
+ if (missing_arg_count > 0) {
+ mcld::errs() << "Argument to '" << args->getArgString(missing_arg_idx)
+ << "' is missing (expected " << missing_arg_count
+ << ((missing_arg_count > 1) ? " values" : " value") << ")\n";
+ return nullptr;
+ }
+
+ return args;
+}
+
+std::unique_ptr<Driver> Driver::Create(llvm::ArrayRef<const char*> argv) {
+ // Parse command line options.
+ OptTable opt_table;
+ std::unique_ptr<llvm::opt::InputArgList> args = ParseArgs(opt_table,
+ argv.slice(1));
+ if (args == nullptr) {
+ return nullptr;
+ }
+
+ std::unique_ptr<Driver> result(new Driver(argv[0], std::move(args)));
+
+ // Return quickly if -help is specified.
+ if (result->args_->hasArg(kOpt_Help)) {
+ opt_table.PrintHelp(mcld::outs(), argv[0], "MCLinker",
+ /* FlagsToInclude */0, /* FlagsToExclude */0);
+ return nullptr;
+ }
+
+ // Print version information if requested.
+ if (result->args_->hasArg(kOpt_Version)) {
+ mcld::outs() << result->config_.options().getVersionString() << "\n";
+ }
+
+ // Setup instance from arguments.
+ if (!result->TranslateArguments()) {
+ return nullptr;
+ }
+
+ return result;
+}
+
+bool Driver::Run() {
+ mcld::Initialize();
+
+ if (!linker_.emulate(script_, config_)) {
+ mcld::errs() << "Failed to emulate target!\n";
+ return false;
+ }
+
+ if (!linker_.link(module_, ir_builder_)) {
+ mcld::errs() << "Failed to link objects!\n";
+ return false;
+ }
+
+ if (!linker_.emit(module_, module_.name())) {
+ mcld::errs() << "Failed to emit output!\n";
+ return false;
+ }
+
+ mcld::Finalize();
+ return true;
+}
+
+} // anonymous namespace
+
+int main(int argc, char** argv) {
+ std::unique_ptr<Driver> driver =
+ Driver::Create(llvm::makeArrayRef(argv, argc));
+
+ if ((driver == nullptr) || !driver->Run()) {
+ return EXIT_FAILURE;
+ } else {
+ return EXIT_SUCCESS;
+ }
+}
diff --git a/tools/mcld/Options.td b/tools/mcld/Options.td
new file mode 100644
index 0000000..80655a7
--- /dev/null
+++ b/tools/mcld/Options.td
@@ -0,0 +1,492 @@
+//===- Options.td ---------------------------------------------------------===//
+//
+// The MCLinker Project
+//
+// This file is distributed under the University of Illinois Open Source
+// License. See LICENSE.TXT for details.
+//
+//===----------------------------------------------------------------------===//
+include "llvm/Option/OptParser.td"
+
+//===----------------------------------------------------------------------===//
+// Dynamic
+//===----------------------------------------------------------------------===//
+def DynamicGroup : OptionGroup<"dynamic">,
+ HelpText<"DYNAMIC OPTIONS">;
+
+def Entry : Joined<["--"], "entry=">,
+ Group<DynamicGroup>,
+ HelpText<"Use the explicit symbol as the entrance of your program">;
+def EntryAlias : Separate<["-"], "e">,
+ Alias<Entry>;
+
+def Bsymbolic : Flag<["-"], "Bsymbolic">,
+ Group<DynamicGroup>,
+ HelpText<"Bind references within the shared library">;
+
+def Bgroup : Flag<["-"], "Bgroup">,
+ Group<DynamicGroup>,
+ HelpText<"Info the dynamic linker to lookup only inside the group">;
+
+def SOName : Joined<["-"], "soname=">,
+ Group<DynamicGroup>,
+ HelpText<"Set internal name of shared library">;
+def SONameAlias : Separate<["-"], "soname">,
+ Group<DynamicGroup>,
+ Alias<SOName>;
+
+def NoUndef : Flag<["--"], "no-undefined">,
+ Group<DynamicGroup>,
+ HelpText<"Do not allow unresolved references">;
+
+def AllowMulDefs : Flag<["--"], "allow-multiple-definition">,
+ Group<DynamicGroup>,
+ HelpText<"Allow multiple definitions">;
+
+def Z : Separate<["-"], "z">,
+ Group<DynamicGroup>,
+ HelpText<"Extensions for GNU ld compatibility">;
+
+def Dyld : Joined<["--"], "dynamic-linker=">,
+ Group<DynamicGroup>,
+ HelpText<"Set the name of the dynamic linker">;
+def DyldAlias : Separate<["-"], "dynamic-linker">,
+ Group<DynamicGroup>,
+ Alias<Dyld>;
+
+def EnableNewDTags : Flag<["--"], "enable-new-dtags">,
+ Group<DynamicGroup>,
+ HelpText<"Enable use of DT_RUNPATH and DT_FLAGS">;
+
+def SpareDTags: Separate<["--"], "spare-dynamic-tags">,
+ Group<DynamicGroup>,
+ HelpText<"Set the number of spare dyanmic tags (DT_NULL)">;
+
+//===----------------------------------------------------------------------===//
+// Optimization
+//===----------------------------------------------------------------------===//
+def OptimizationGroup : OptionGroup<"optimization">,
+ HelpText<"OPTIMIZATION OPTIONS">;
+
+def GCSections : Flag<["--"], "gc-sections">,
+ Group<OptimizationGroup>,
+ HelpText<"Enable garbage collection of unused input sections">;
+
+def NoGCSections : Flag<["--"], "no-gc-sections">,
+ Group<OptimizationGroup>,
+ HelpText<"Disable garbage collection of unused input sections">;
+
+def PrintGCSections : Flag<["--"], "print-gc-sections">,
+ Group<OptimizationGroup>,
+ HelpText<"List all sections removed by garbage collection">;
+
+def NoPrintGCSections : Flag<["--"], "no-print-gc-sections">,
+ Group<OptimizationGroup>,
+ HelpText<"Do not list sections removed by garbage collection">;
+
+def LDGeneratedUnwindInfo : Flag<["--"], "ld-generated-unwind-info">,
+ Group<OptimizationGroup>,
+ HelpText<"Request creation of unwind info for linker generated code sections like PLT">;
+
+def NoLDGeneratedUnwindInfo : Flag<["--"], "no-ld-generated-unwind-info">,
+ Group<OptimizationGroup>,
+ HelpText<"Don't create unwind info for linker generated sections to save size">;
+
+def ICF : Joined<["--"], "icf=">,
+ Group<OptimizationGroup>,
+ HelpText<"Identical Code Folding">;
+
+def ICFIters : Separate<["--"], "icf-iterations">,
+ Group<OptimizationGroup>,
+ HelpText<"Set number of iterations to do ICF">;
+
+def PrintICFSections : Flag<["--"], "print-icf-sections">,
+ Group<OptimizationGroup>,
+ HelpText<"List all sections folded by ICF">;
+
+def NoPrintICFSections : Flag<["--"], "no-print-icf-sections">,
+ Group<OptimizationGroup>,
+ HelpText<"Do not list sections folded by ICF">;
+
+//===----------------------------------------------------------------------===//
+// Output
+//===----------------------------------------------------------------------===//
+def OutputGroup : OptionGroup<"output">,
+ HelpText<"OUTPUT OPTIONS">;
+
+def Output : Separate<["-"], "o">,
+ Group<OutputGroup>,
+ HelpText<"Output filename">;
+def OutputAlias : Joined<["--"], "output=">,
+ Group<OutputGroup>,
+ Alias<Output>;
+
+def OutputFormat: Joined<["--"], "oformat=">,
+ Group<OutputGroup>,
+ HelpText<"Output format">;
+
+def Shared : Flag<["-"], "shared">,
+ Group<OutputGroup>,
+ HelpText<"Create a shared library">;
+def Bshareable : Flag<["-"], "Bshareable">,
+ Group<OutputGroup>,
+ Alias<Shared>;
+
+def Bdynamic : Flag<["-"], "Bdynamic">,
+ Group<OutputGroup>,
+ HelpText<"Link against dynamic library">;
+def BdynamicAlias1 : Flag<["-"], "dy">,
+ Group<OutputGroup>,
+ Alias<Bdynamic>;
+def BdynamicAlias2 : Flag<["-"], "call_shared">,
+ Group<OutputGroup>,
+ Alias<Bdynamic>;
+
+def Bstatic : Flag<["-"], "Bstatic">,
+ Group<OutputGroup>,
+ HelpText<"Link against static library">;
+def BstaticAlias1 : Flag<["-"], "dn">,
+ Group<OutputGroup>,
+ Alias<Bstatic>;
+def BstaticAlias2 : Flag<["-"], "non_shared">,
+ Group<OutputGroup>,
+ Alias<Bstatic>;
+def BstaticAlias3 : Flag<["-"], "static">,
+ Group<OutputGroup>,
+ Alias<Bstatic>;
+
+def PIE : Flag<["-"], "pie">,
+ Group<OutputGroup>,
+ HelpText<"Emit a position-independent executable file">;
+def PICExec : Flag<["--"], "pic-executable">,
+ Group<OutputGroup>,
+ Alias<PIE>;
+
+def Relocatable : Flag<["--"], "relocatable">,
+ Group<OutputGroup>,
+ HelpText<"Generate relocatable output">;
+def RelocatableAlias : Flag<["-"], "r">,
+ Group<OutputGroup>,
+ Alias<Relocatable>;
+
+def InputFormat : Joined<["--"], "format=">,
+ Group<OutputGroup>,
+ HelpText<"Specify the binary format for input object files that follow this option on the command line">;
+def InputFormatAlias : Separate<["-"], "b">,
+ Group<OutputGroup>,
+ Alias<InputFormat>;
+
+def StripDebug : Flag<["--"], "strip-debug">,
+ Group<OutputGroup>,
+ HelpText<"Omit debugger symbol information from the output file">;
+def StripDebugAlias : Flag<["-"], "S">,
+ Group<OutputGroup>,
+ Alias<StripDebug>;
+
+def StripAll : Flag<["--"], "strip-all">,
+ Group<OutputGroup>,
+ HelpText<"Omit all symbol information from the output file">;
+def StripAllAlias : Flag<["-"], "s">,
+ Group<OutputGroup>,
+ Alias<StripAll>;
+
+def DiscardLocals : Flag<["--"], "discard-debug">,
+ Group<OutputGroup>,
+ HelpText<"Discard all temporary local symbols">;
+def DiscardLocalsAlias : Flag<["-"], "X">,
+ Group<OutputGroup>,
+ Alias<DiscardLocals>;
+
+def DiscardAll : Flag<["--"], "discard-all">,
+ Group<OutputGroup>,
+ HelpText<"Discard all local symbols">;
+def DiscardAllAlias : Flag<["-"], "x">,
+ Group<OutputGroup>,
+ Alias<DiscardAll>;
+
+def EHFrameHdr : Flag<["--"], "eh-frame-hdr">,
+ Group<OutputGroup>,
+ HelpText<"Request creation of .eh_frame_hdr section and PT_GNU_EH_FRAME segment">;
+
+def NMagic : Flag<["--"], "nmagic">,
+ Group<OutputGroup>,
+ HelpText<"Do not page align data">;
+def NMagicAlias : Flag<["-"], "n">,
+ Group<OutputGroup>,
+ Alias<NMagic>;
+
+def OMagic : Flag<["--"], "omagic">,
+ Group<OutputGroup>,
+ HelpText<"Do not page align data, do not make text readonly">;
+def OMagicAlias : Flag<["-"], "N">,
+ Group<OutputGroup>,
+ Alias<OMagic>;
+
+def HashStyle : Joined<["--"], "hash-style=">,
+ Group<OutputGroup>,
+ HelpText<"Set the type of linker's hash table(s)">;
+
+def ExportDynamic : Flag<["--"], "export-dynamic">,
+ Group<OutputGroup>,
+ HelpText<"Export all dynamic symbols">;
+def ExportDynamicAlias : Flag<["-"], "E">,
+ Group<OutputGroup>,
+ Alias<ExportDynamic>;
+
+def NoExportDynamic : Flag<["--"], "no-export-dynamic">,
+ Group<OutputGroup>,
+ HelpText<"Not export all dynamic symbols">;
+
+
+
+def NoWarnMismatch : Flag<["--"], "no-warn-mismatch">,
+ Group<OutputGroup>,
+ HelpText<"Allow linking together mismatched input files">;
+
+def ExcludeLibs : Separate<["--"], "exclude-libs">,
+ Group<OutputGroup>,
+ HelpText<"Allow linking together mismatched input files">;
+
+def BuildID : Flag<["--"], "build-id">,
+ Group<OutputGroup>,
+ HelpText<"Request creation of .note.gnu.build-id ELF note section">;
+
+//===----------------------------------------------------------------------===//
+// Positional
+//===----------------------------------------------------------------------===//
+def PositionalGroup : OptionGroup<"positional">,
+ HelpText<"POSITIONAL OPTIONS">;
+
+def Script : Joined<["--"], "script=">,
+ Group<PositionalGroup>,
+ HelpText<"Use the given file as the linker script">;
+def ScriptAlias : Separate<["-"], "T">,
+ Group<PositionalGroup>,
+ Alias<Script>;
+
+def Namespec : Joined<["--"], "library=">,
+ Group<PositionalGroup>,
+ HelpText<"Add the archive or object file specified by namespec to the list of files to link">;
+def NamespecAlias : Joined<["-"], "l">,
+ Group<PositionalGroup>,
+ Alias<Namespec>;
+
+def WholeArchive : Flag<["--"], "whole-archive">,
+ Group<PositionalGroup>,
+ HelpText<"Include every object file in the archive in the link">;
+
+def NoWholeArchive : Flag<["--"], "no-whole-archive">,
+ Group<PositionalGroup>,
+ HelpText<"Turn off the effect of the --whole-archive option">;
+
+def AsNeeded : Flag<["--"], "as-needed">,
+ Group<PositionalGroup>,
+ HelpText<"Add the dynamic libraries mentioned to DT_NEEDED where there is "
+ "a non-weak undefined symbol reference from">;
+
+def NoAsNeeded : Flag<["--"], "no-as-needed">,
+ Group<PositionalGroup>,
+ HelpText<"Turn off the effect of the --as-needed">;
+
+def AddNeeded : Flag<["--"], "add-needed">,
+ Group<PositionalGroup>,
+ HelpText<"Deprecated">;
+
+def NoAddNeeded : Flag<["--"], "no-add-needed">,
+ Group<PositionalGroup>,
+ HelpText<"Deprecated">;
+
+def CopyDTNeeded : Flag<["--"], "copy-dt-needed-entries">,
+ Group<PositionalGroup>,
+ HelpText<"Add the dynamic libraries mentioned to DT_NEEDED">;
+
+def NoCopyDTNeeded : Flag<["--"], "no-copy-dt-needed-entries">,
+ Group<PositionalGroup>,
+ HelpText<"Turn off the effect of the --copy-dt-needed-entries">;
+
+def StartGroup : Flag<["--"], "start-group">,
+ Group<PositionalGroup>,
+ HelpText<"Start to record a group of archives">;
+def StartGroupAlias : Flag<["-"], "(">,
+ Group<PositionalGroup>,
+ Alias<StartGroup>;
+
+def EndGroup : Flag<["--"], "end-group">,
+ Group<PositionalGroup>,
+ HelpText<"Stop recording a group of archives">;
+def EndGroupAlias : Flag<["-"], ")">,
+ Group<PositionalGroup>,
+ Alias<EndGroup>;
+
+//===----------------------------------------------------------------------===//
+// Preference
+//===----------------------------------------------------------------------===//
+def PreferenceGroup : OptionGroup<"preference">,
+ HelpText<"PREFERENCE OPTIONS">;
+
+def Color : Joined<["--"], "colormc=">,
+ Group<PreferenceGroup>,
+ HelpText<"Surround the result strings with the marker">;
+
+def Trace : Flag<["--"], "trace">,
+ Group<PreferenceGroup>,
+ HelpText<"Print the names of the input files as ld processes them">;
+def TraceAlias : Flag<["-"], "t">,
+ Group<PreferenceGroup>,
+ Alias<Trace>;
+
+def Help : Flag<["-", "--"], "help">,
+ Group<PreferenceGroup>,
+ HelpText<"Display available options (to standard output)">;
+def HelpAlias : Flag<["-"], "h">,
+ Group<PreferenceGroup>,
+ Alias<Help>;
+
+def Verbose : Joined<["--"], "verbose=">,
+ Group<PreferenceGroup>,
+ HelpText<"Set linker diagnostic output level">;
+
+def Version : Flag<["--"], "version">,
+ Group<PreferenceGroup>,
+ HelpText<"Display MCLinker version">;
+def VersionAlias1 : Flag<["-"], "v">,
+ Group<PreferenceGroup>,
+ Alias<Version>;
+def VersionAlias2 : Flag<["-"], "V">,
+ Group<PreferenceGroup>,
+ Alias<Version>;
+
+def ErrorLimit : Joined<["--"], "error-limit=">,
+ Group<PreferenceGroup>,
+ HelpText<"Set the maximum limit of errors">;
+
+def WarningLimit : Joined<["--"], "warning-limit=">,
+ Group<PreferenceGroup>,
+ HelpText<"Set the maximum limit of warnings">;
+
+def FatalWarnings : Flag<["--"], "fatal-warnings">,
+ Group<PreferenceGroup>,
+ HelpText<"Turn all warnings into errors">;
+
+def NoFatalWarnings : Flag<["--"], "no-fatal-warnings">,
+ Group<PreferenceGroup>,
+ HelpText<"Do not turn all warnings into errors">;
+
+def WarnSharedTextrel : Flag<["--"], "warn-shared-textrel">,
+ Group<PreferenceGroup>,
+ HelpText<"Warn if there is a text relocation in the output shared object">;
+
+//===----------------------------------------------------------------------===//
+// Script
+//===----------------------------------------------------------------------===//
+def ScriptGroup : OptionGroup<"script">,
+ HelpText<"SCRIPT OPTIONS">;
+
+def DefSym : Joined<["--"], "defsym=">,
+ Group<ScriptGroup>,
+ HelpText<"Define a symbol">;
+
+def Wrap : Joined<["--"], "wrap=">,
+ Group<ScriptGroup>,
+ HelpText<"Use a wrap function for the symbol">;
+
+def Portable : Joined<["--"], "portable=">,
+ Group<ScriptGroup>,
+ HelpText<"Use a portable function for the symbol">;
+
+def SectionStart : Joined<["--"], "section-start=">,
+ Group<ScriptGroup>,
+ HelpText<"Locate a output section at the given absolute address">;
+
+def Tbss : Joined<["-"], "Tbss=">,
+ Group<ScriptGroup>,
+ HelpText<"Set the address of the bss segment">;
+
+def Tdata : Joined<["-"], "Tdata=">,
+ Group<ScriptGroup>,
+ HelpText<"Set the address of the data segment">;
+
+def Ttext : Joined<["-"], "Ttext=">,
+ Group<ScriptGroup>,
+ HelpText<"Set the address of the text segment">;
+
+//===----------------------------------------------------------------------===//
+// Search Path
+//===----------------------------------------------------------------------===//
+def SearchpathGroup : OptionGroup<"searchpath">,
+ HelpText<"SEARCHPATH OPTIONS">;
+
+def Sysroot : Joined<["--"], "sysroot=">,
+ Group<SearchpathGroup>,
+ HelpText<"Use the given directory as the location of the sysroot">;
+
+def LibraryPath : Joined<["--"], "library-path=">,
+ Group<SearchpathGroup>,
+ HelpText<"Add the given directory to the list of search paths">;
+def LibraryPathAlias : Joined<["-"], "L">,
+ Group<SearchpathGroup>,
+ Alias<LibraryPath>;
+
+def NoStdlib : Flag<["-"], "nostdlib">,
+ Group<SearchpathGroup>,
+ HelpText<"Only search lib dirs explicitly specified on cmdline">;
+
+def RPath : Joined<["-"], "rpath=">,
+ Group<SearchpathGroup>,
+ HelpText<"Add a directory to the runtime library search path">;
+
+def RPathLink : Joined<["-"], "rpath-link=">,
+ Group<SearchpathGroup>,
+ HelpText<"Add a directory to the link time library search path">;
+
+//===----------------------------------------------------------------------===//
+// Symbol
+//===----------------------------------------------------------------------===//
+def SymbolGroup : OptionGroup<"symbol">,
+ HelpText<"SYMBOL OPTIONS">;
+
+def Undefined : Joined<["--"], "undefined=">,
+ Group<SymbolGroup>,
+ HelpText<"Force symbol to be undefined in the output file">;
+def UndefinedAlias : Separate<["-"], "u">,
+ Group<SymbolGroup>,
+ Alias<Undefined>;
+
+def DefineCommon : Flag<["-"], "d">,
+ Group<SymbolGroup>,
+ HelpText<"Define common symbol">;
+def DefineCommonAlias1 : Flag<["-"], "dc">,
+ Group<SymbolGroup>,
+ Alias<DefineCommon>;
+def DefineCommonAlias2 : Flag<["-"], "dp">,
+ Group<SymbolGroup>,
+ Alias<DefineCommon>;
+
+//===----------------------------------------------------------------------===//
+// Target
+//===----------------------------------------------------------------------===//
+def TargetGroup : OptionGroup<"target">,
+ HelpText<"TARGET OPTIONS">;
+
+def GPSize : Joined<["--"], "gpsize=">,
+ Group<TargetGroup>,
+ HelpText<"Set the maximum size of objects to be optimized using GP">;
+def GPSizeAlias : Separate<["-"], "G">,
+ Group<TargetGroup>,
+ Alias<GPSize>;
+
+def Triple : Joined<["-"], "mtriple=">,
+ Group<TargetGroup>,
+ HelpText<"Override target triple for module">;
+
+def Arch : Joined<["-"], "march=">,
+ Group<TargetGroup>,
+ HelpText<"Architecture to generate code for">;
+
+def CPU : Joined<["-"], "mcpu=">,
+ Group<TargetGroup>,
+ HelpText<"Set a specific cpu type">;
+
+def Emulation : Separate<["-"], "m">,
+ Group<TargetGroup>,
+ HelpText<"Set GNU linker emulation">;
diff --git a/tools/mcld/include/mcld/DynamicSectionOptions.h b/tools/mcld/include/mcld/DynamicSectionOptions.h
deleted file mode 100644
index 2902118..0000000
--- a/tools/mcld/include/mcld/DynamicSectionOptions.h
+++ /dev/null
@@ -1,45 +0,0 @@
-//===- DynamicSectionOptions.h --------------------------------------------===//
-//
-// The MCLinker Project
-//
-// This file is distributed under the University of Illinois Open Source
-// License. See LICENSE.TXT for details.
-//
-//===----------------------------------------------------------------------===//
-#ifndef MCLD_LDLITE_DYNAMIC_SECTION_OPTIONS_H
-#define MCLD_LDLITE_DYNAMIC_SECTION_OPTIONS_H
-#include <llvm/Support/CommandLine.h>
-#include <mcld/Support/CommandLine.h>
-#include <string>
-
-namespace mcld {
-
-class ZOption;
-class LinkerConfig;
-class LinkerScript;
-
-class DynamicSectionOptions {
- public:
- DynamicSectionOptions();
-
- bool parse(LinkerConfig& pConfig, LinkerScript& pScript);
-
- private:
- llvm::cl::opt<std::string>& m_Entry;
- llvm::cl::opt<bool>& m_Bsymbolic;
- llvm::cl::opt<bool>& m_Bgroup;
- llvm::cl::opt<std::string>& m_SOName;
- llvm::cl::opt<llvm::cl::boolOrDefault>& m_NoUndefined;
- llvm::cl::opt<llvm::cl::boolOrDefault>& m_AllowMulDefs;
- llvm::cl::list<ZOption, bool, llvm::cl::parser<ZOption> >& m_ZOptionList;
- llvm::cl::opt<std::string>& m_Dyld;
- llvm::cl::opt<bool>& m_EnableNewDTags;
- llvm::cl::opt<unsigned>& m_NumSpareDTags;
-
- llvm::cl::list<std::string>& m_Auxiliary;
- llvm::cl::opt<std::string>& m_Filter;
-};
-
-} // namespace of mcld
-
-#endif
diff --git a/tools/mcld/include/mcld/OptimizationOptions.h b/tools/mcld/include/mcld/OptimizationOptions.h
deleted file mode 100644
index 1016c87..0000000
--- a/tools/mcld/include/mcld/OptimizationOptions.h
+++ /dev/null
@@ -1,39 +0,0 @@
-//===- OptimizationOptions.h ----------------------------------------------===//
-//
-// The MCLinker Project
-//
-// This file is distributed under the University of Illinois Open Source
-// License. See LICENSE.TXT for details.
-//
-//===----------------------------------------------------------------------===//
-#ifndef MCLD_LDLITE_OPTIMIZATION_OPTIONS_H
-#define MCLD_LDLITE_OPTIMIZATION_OPTIONS_H
-#include <mcld/GeneralOptions.h>
-#include <llvm/Support/CommandLine.h>
-#include <string>
-
-namespace mcld {
-
-class LinkerConfig;
-
-class OptimizationOptions {
- public:
- OptimizationOptions();
-
- bool parse(LinkerConfig& pConfig);
-
- private:
- bool& m_GCSections;
- bool& m_PrintGCSections;
- bool& m_GenUnwindInfo;
- llvm::cl::opt<mcld::GeneralOptions::ICF>& m_ICF;
- llvm::cl::opt<unsigned>& m_ICFIterations;
- llvm::cl::opt<bool>& m_PrintICFSections;
- llvm::cl::opt<char>& m_OptLevel;
- llvm::cl::list<std::string>& m_Plugin;
- llvm::cl::list<std::string>& m_PluginOpt;
-};
-
-} // namespace of mcld
-
-#endif
diff --git a/tools/mcld/include/mcld/OutputFormatOptions.h b/tools/mcld/include/mcld/OutputFormatOptions.h
deleted file mode 100644
index 81810eb..0000000
--- a/tools/mcld/include/mcld/OutputFormatOptions.h
+++ /dev/null
@@ -1,59 +0,0 @@
-//===- OutputFormatOptions.h ----------------------------------------------===//
-//
-// The MCLinker Project
-//
-// This file is distributed under the University of Illinois Open Source
-// License. See LICENSE.TXT for details.
-//
-//===----------------------------------------------------------------------===//
-#ifndef MCLD_LDLITE_OUTPUT_FORMAT_OPTIONS_H
-#define MCLD_LDLITE_OUTPUT_FORMAT_OPTIONS_H
-#include <llvm/Support/CommandLine.h>
-#include <mcld/Support/CommandLine.h>
-#include <mcld/LinkerConfig.h>
-#include <mcld/GeneralOptions.h>
-#include <mcld/Support/Path.h>
-#include <mcld/MC/Input.h>
-#include <string>
-
-namespace mcld {
-
-class Module;
-
-class OutputFormatOptions {
- public:
- OutputFormatOptions();
-
- bool parse(Module& pModule, LinkerConfig& pConfig);
-
- bool parseOutput(Module& pModule, LinkerConfig& pConfig);
-
- private:
- llvm::cl::opt<mcld::sys::fs::Path,
- false,
- llvm::cl::parser<mcld::sys::fs::Path> >& m_OutputFilename;
- llvm::cl::opt<mcld::LinkerConfig::CodeGenType>& m_FileType;
- llvm::cl::opt<mcld::LinkerConfig::CodeGenType>& m_OFormat;
- llvm::cl::opt<bool>& m_Shared;
- llvm::cl::opt<bool>& m_PIE;
- llvm::cl::opt<bool>& m_Relocatable;
- llvm::cl::opt<mcld::Input::Type>& m_Format;
- llvm::cl::opt<bool>& m_StripDebug;
- llvm::cl::opt<bool>& m_StripAll;
- llvm::cl::opt<bool>& m_DiscardAll;
- llvm::cl::opt<bool>& m_DiscardLocals;
- llvm::cl::opt<bool>& m_EhFrameHdr;
- llvm::cl::opt<bool>& m_NMagic;
- llvm::cl::opt<bool>& m_OMagic;
- llvm::cl::opt<mcld::GeneralOptions::HashStyle>& m_HashStyle;
-
- llvm::cl::opt<bool>& m_ExportDynamic;
- llvm::cl::opt<std::string>& m_BuildID;
- llvm::cl::list<std::string>& m_ExcludeLIBS;
-
- llvm::cl::opt<bool>& m_NoWarnMismatch;
-};
-
-} // namespace of mcld
-
-#endif
diff --git a/tools/mcld/include/mcld/PositionalOptions.h b/tools/mcld/include/mcld/PositionalOptions.h
deleted file mode 100644
index 326a2d0..0000000
--- a/tools/mcld/include/mcld/PositionalOptions.h
+++ /dev/null
@@ -1,68 +0,0 @@
-//===- PositionalOptions.h ------------------------------------------------===//
-//
-// The MCLinker Project
-//
-// This file is distributed under the University of Illinois Open Source
-// License. See LICENSE.TXT for details.
-//
-//===----------------------------------------------------------------------===//
-#ifndef MCLD_LDLITE_POSITIONAL_OPTIONS_H
-#define MCLD_LDLITE_POSITIONAL_OPTIONS_H
-#include <llvm/Support/CommandLine.h>
-#include <mcld/Support/CommandLine.h>
-#include <mcld/Support/Path.h>
-#include <string>
-
-namespace mcld {
-
-class InputAction;
-class LinkerConfig;
-class LinkerScript;
-
-/** \class PositionalOptions
- *
- * The meaning of a positional option depends on its position and its related
- * positions with the other positional options. There are four kinds of
- * positional options:
- * 1. Inputs, object files, such as /tmp/XXXX.o
- * 2. Namespecs, short names of libraries. A namespec may refer to an archive
- * or a shared library. For example, -lm.
- * 3. Attributes of inputs. Attributes describe inputs appears after them.
- * For example, --as-needed and --whole-archive.
- * 4. Groups. A Group is a set of archives. Linkers repeatedly read archives
- * in groups until there is no new undefined symbols.
- * 5. Definitions of symbols. --defsym option depends on
- */
-class PositionalOptions {
- public:
- PositionalOptions();
-
- size_t numOfInputs() const;
-
- bool parse(std::vector<InputAction*>& pActions,
- LinkerConfig& pConfig,
- const LinkerScript& pScript);
-
- private:
- size_t numOfActions() const;
-
- private:
- llvm::cl::list<mcld::sys::fs::Path>& m_InputObjectFiles;
- llvm::cl::list<std::string>& m_LinkerScript;
- llvm::cl::list<std::string>& m_NameSpecList;
- llvm::cl::list<bool>& m_WholeArchiveList;
- llvm::cl::list<bool>& m_NoWholeArchiveList;
- llvm::cl::list<bool>& m_AsNeededList;
- llvm::cl::list<bool>& m_NoAsNeededList;
- llvm::cl::list<bool>& m_AddNeededList;
- llvm::cl::list<bool>& m_NoAddNeededList;
- llvm::cl::list<bool>& m_BDynamicList;
- llvm::cl::list<bool>& m_BStaticList;
- llvm::cl::list<bool>& m_StartGroupList;
- llvm::cl::list<bool>& m_EndGroupList;
- llvm::cl::list<std::string>& m_DefSymList;
-};
-
-} // namespace of mcld
-
-#endif
diff --git a/tools/mcld/include/mcld/PreferenceOptions.h b/tools/mcld/include/mcld/PreferenceOptions.h
deleted file mode 100644
index 523c133..0000000
--- a/tools/mcld/include/mcld/PreferenceOptions.h
+++ /dev/null
@@ -1,40 +0,0 @@
-//===- PreferenceOptions.h ------------------------------------------------===//
-//
-// The MCLinker Project
-//
-// This file is distributed under the University of Illinois Open Source
-// License. See LICENSE.TXT for details.
-//
-//===----------------------------------------------------------------------===//
-#ifndef MCLD_LDLITE_PREFERENCE_OPTIONS_H
-#define MCLD_LDLITE_PREFERENCE_OPTIONS_H
-#include <llvm/Support/CommandLine.h>
-#include <string>
-
-namespace mcld {
-
-class LinkerConfig;
-
-class PreferenceOptions {
- public:
- enum Color { COLOR_Never, COLOR_Always, COLOR_Auto };
-
- public:
- PreferenceOptions();
-
- bool parse(LinkerConfig& pConfig);
-
- private:
- llvm::cl::opt<bool>& m_Trace;
- llvm::cl::opt<int>& m_Verbose;
- llvm::cl::opt<bool>& m_Version;
- llvm::cl::opt<int>& m_MaxErrorNum;
- llvm::cl::opt<int>& m_MaxWarnNum;
- llvm::cl::opt<Color>& m_Color;
- llvm::cl::opt<bool>& m_PrintMap;
- bool& m_FatalWarnings;
-};
-
-} // namespace of mcld
-
-#endif
diff --git a/tools/mcld/include/mcld/ScriptOptions.h b/tools/mcld/include/mcld/ScriptOptions.h
deleted file mode 100644
index 55e3204..0000000
--- a/tools/mcld/include/mcld/ScriptOptions.h
+++ /dev/null
@@ -1,40 +0,0 @@
-//===- ScriptOptions.h ----------------------------------------------------===//
-//
-// The MCLinker Project
-//
-// This file is distributed under the University of Illinois Open Source
-// License. See LICENSE.TXT for details.
-//
-//===----------------------------------------------------------------------===//
-#ifndef MCLD_LDLITE_SCRIPT_OPTIONS_H
-#define MCLD_LDLITE_SCRIPT_OPTIONS_H
-#include <llvm/Support/CommandLine.h>
-#include <string>
-
-namespace mcld {
-
-class LinkerScript;
-
-/** \class ScriptOptions
- * \brief ScriptOptions are used to modify the default link script. Some
- * positional options, such as --defsym, also can modify default link script
- * is not listed here. These special options belong to Positional Options.
- */
-class ScriptOptions {
- public:
- ScriptOptions();
-
- bool parse(LinkerScript& pScript);
-
- private:
- llvm::cl::list<std::string>& m_WrapList;
- llvm::cl::list<std::string>& m_PortList;
- llvm::cl::list<std::string>& m_AddressMapList;
- llvm::cl::opt<unsigned long long>& m_BssSegAddr;
- llvm::cl::opt<unsigned long long>& m_DataSegAddr;
- llvm::cl::opt<unsigned long long>& m_TextSegAddr;
-};
-
-} // namespace of mcld
-
-#endif
diff --git a/tools/mcld/include/mcld/SearchPathOptions.h b/tools/mcld/include/mcld/SearchPathOptions.h
deleted file mode 100644
index ec5a956..0000000
--- a/tools/mcld/include/mcld/SearchPathOptions.h
+++ /dev/null
@@ -1,43 +0,0 @@
-//===- SearchPathOptions.h ------------------------------------------------===//
-//
-// The MCLinker Project
-//
-// This file is distributed under the University of Illinois Open Source
-// License. See LICENSE.TXT for details.
-//
-//===----------------------------------------------------------------------===//
-#ifndef MCLD_LDLITE_SEARCH_PATH_OPTIONS_H
-#define MCLD_LDLITE_SEARCH_PATH_OPTIONS_H
-#include <llvm/Support/CommandLine.h>
-#include <mcld/Support/Path.h>
-#include <mcld/Support/CommandLine.h>
-#include <string>
-
-namespace mcld {
-
-class LinkerConfig;
-class LinkerScript;
-
-class SearchPathOptions {
- public:
- SearchPathOptions();
-
- bool parse(LinkerConfig& pConfig, LinkerScript& pScript);
-
- private:
- llvm::cl::opt<mcld::sys::fs::Path,
- false,
- llvm::cl::parser<mcld::sys::fs::Path> >& m_SysRoot;
- llvm::cl::list<std::string, bool, llvm::cl::SearchDirParser>& m_SearchDirList;
- llvm::cl::opt<bool>& m_NoStdlib;
- llvm::cl::list<std::string, bool, llvm::cl::SearchDirParser>& m_RuntimePath;
-
- // not supported yet
- llvm::cl::list<std::string, bool, llvm::cl::SearchDirParser>&
- m_RuntimePathLink;
- llvm::cl::list<std::string>& m_Y;
-};
-
-} // namespace of mcld
-
-#endif
diff --git a/tools/mcld/include/mcld/SymbolOptions.h b/tools/mcld/include/mcld/SymbolOptions.h
deleted file mode 100644
index 8e7124c..0000000
--- a/tools/mcld/include/mcld/SymbolOptions.h
+++ /dev/null
@@ -1,34 +0,0 @@
-//===- SymbolOptions.h ----------------------------------------------------===//
-//
-// The MCLinker Project
-//
-// This file is distributed under the University of Illinois Open Source
-// License. See LICENSE.TXT for details.
-//
-//===----------------------------------------------------------------------===//
-#ifndef MCLD_LDLITE_SYMBOL_OPTIONS_H
-#define MCLD_LDLITE_SYMBOL_OPTIONS_H
-#include <llvm/Support/CommandLine.h>
-#include <string>
-
-namespace mcld {
-
-class LinkerConfig;
-
-class SymbolOptions {
- public:
- SymbolOptions();
-
- bool parse(LinkerConfig& pConfig);
-
- private:
- // not supported yet
- llvm::cl::list<std::string>& m_ForceUndefined;
- llvm::cl::opt<std::string>& m_VersionScript;
- llvm::cl::opt<bool>& m_WarnCommon;
- llvm::cl::opt<bool>& m_DefineCommon;
-};
-
-} // namespace of mcld
-
-#endif
diff --git a/tools/mcld/include/mcld/TargetControlOptions.h b/tools/mcld/include/mcld/TargetControlOptions.h
deleted file mode 100644
index 1603452..0000000
--- a/tools/mcld/include/mcld/TargetControlOptions.h
+++ /dev/null
@@ -1,35 +0,0 @@
-//===- TargetControlOptions.h ---------------------------------------------===//
-//
-// The MCLinker Project
-//
-// This file is distributed under the University of Illinois Open Source
-// License. See LICENSE.TXT for details.
-//
-//===----------------------------------------------------------------------===//
-#ifndef MCLD_LDLITE_TARGET_CONTROL_OPTIONS_H
-#define MCLD_LDLITE_TARGET_CONTROL_OPTIONS_H
-#include <llvm/Support/CommandLine.h>
-
-namespace mcld {
-
-class LinkerConfig;
-
-class TargetControlOptions {
- public:
- TargetControlOptions();
-
- bool parse(LinkerConfig& pConfig);
-
- private:
- llvm::cl::opt<int>& m_GPSize;
- llvm::cl::opt<bool>& m_WarnSharedTextrel;
- llvm::cl::opt<bool>& m_FIXCA8;
- llvm::cl::opt<bool>& m_FIXCA53Erratum835769;
- llvm::cl::opt<bool>& m_EB;
- llvm::cl::opt<bool>& m_EL;
- llvm::cl::opt<bool>& m_SVR4Compatibility;
-};
-
-} // namespace of mcld
-
-#endif
diff --git a/tools/mcld/include/mcld/TripleOptions.h b/tools/mcld/include/mcld/TripleOptions.h
deleted file mode 100644
index 7b10958..0000000
--- a/tools/mcld/include/mcld/TripleOptions.h
+++ /dev/null
@@ -1,33 +0,0 @@
-//===- TripleOptions.h ----------------------------------------------------===//
-//
-// The MCLinker Project
-//
-// This file is distributed under the University of Illinois Open Source
-// License. See LICENSE.TXT for details.
-//
-//===----------------------------------------------------------------------===//
-#ifndef MCLD_LDLITE_TRIPLE_OPTIONS_H
-#define MCLD_LDLITE_TRIPLE_OPTIONS_H
-#include <llvm/Support/CommandLine.h>
-#include <string>
-
-namespace mcld {
-
-class LinkerConfig;
-
-class TripleOptions {
- public:
- TripleOptions();
-
- bool parse(int pArgc, char* pArgv[], LinkerConfig& pConfig);
-
- private:
- llvm::cl::opt<std::string>& m_TargetTriple;
- llvm::cl::opt<std::string>& m_MArch;
- llvm::cl::opt<std::string>& m_MCPU;
- llvm::cl::opt<std::string>& m_Emulation;
-};
-
-} // namespace of mcld
-
-#endif
diff --git a/tools/mcld/lib/DynamicSectionOptions.cpp b/tools/mcld/lib/DynamicSectionOptions.cpp
deleted file mode 100644
index 958a94d..0000000
--- a/tools/mcld/lib/DynamicSectionOptions.cpp
+++ /dev/null
@@ -1,166 +0,0 @@
-//===- DynamicSectionOptions.cpp ------------------------------------------===//
-//
-// The MCLinker Project
-//
-// This file is distributed under the University of Illinois Open Source
-// License. See LICENSE.TXT for details.
-//
-//===----------------------------------------------------------------------===//
-#include <mcld/DynamicSectionOptions.h>
-#include <mcld/LinkerConfig.h>
-#include <mcld/LinkerScript.h>
-#include <mcld/MC/ZOption.h>
-
-namespace {
-
-llvm::cl::opt<std::string> ArgEntry(
- "e",
- llvm::cl::desc("Use the explicit symbol as the entrance of your program."),
- llvm::cl::value_desc("entry"),
- llvm::cl::ValueRequired);
-
-llvm::cl::alias ArgEntryAlias("entry",
- llvm::cl::desc("alias for -e"),
- llvm::cl::aliasopt(ArgEntry));
-
-llvm::cl::opt<bool> ArgBsymbolic(
- "Bsymbolic",
- llvm::cl::ZeroOrMore,
- llvm::cl::desc("Bind references within the shared library."),
- llvm::cl::init(false));
-
-llvm::cl::opt<bool> ArgBgroup(
- "Bgroup",
- llvm::cl::desc("Info the dynamic linker to lookups only inside the group."),
- llvm::cl::init(false));
-
-llvm::cl::opt<std::string> ArgSOName(
- "soname",
- llvm::cl::desc("Set internal name of shared library"),
- llvm::cl::value_desc("name"));
-
-llvm::cl::opt<llvm::cl::boolOrDefault> ArgNoUndefined(
- "no-undefined",
- llvm::cl::ZeroOrMore,
- llvm::cl::desc("Do not allow unresolved references"));
-
-llvm::cl::opt<llvm::cl::boolOrDefault> ArgAllowMulDefs(
- "allow-multiple-definition",
- llvm::cl::desc("Allow multiple definition"));
-
-llvm::cl::list<mcld::ZOption, bool, llvm::cl::parser<mcld::ZOption> >
- ArgZOptionList("z",
- llvm::cl::ZeroOrMore,
- llvm::cl::desc("The -z options for GNU ld compatibility."),
- llvm::cl::value_desc("keyword"),
- llvm::cl::Prefix);
-
-llvm::cl::opt<std::string> ArgDyld(
- "dynamic-linker",
- llvm::cl::ZeroOrMore,
- llvm::cl::desc("Set the name of the dynamic linker."),
- llvm::cl::value_desc("Program"));
-
-llvm::cl::opt<bool> ArgEnableNewDTags(
- "enable-new-dtags",
- llvm::cl::desc("Enable use of DT_RUNPATH and DT_FLAGS"),
- llvm::cl::init(false));
-
-llvm::cl::opt<unsigned> ArgNumSpareDTags(
- "spare-dynamic-tags",
- llvm::cl::desc("Set the number of spare dyanmic tags (DT_NULL)"),
- llvm::cl::init(5));
-
-// Not supported yet {
-llvm::cl::list<std::string> ArgAuxiliary(
- "f",
- llvm::cl::ZeroOrMore,
- llvm::cl::desc("Auxiliary filter for shared object symbol table"),
- llvm::cl::value_desc("name"));
-
-llvm::cl::alias ArgAuxiliaryAlias("auxiliary",
- llvm::cl::desc("alias for -f"),
- llvm::cl::aliasopt(ArgAuxiliary));
-
-llvm::cl::opt<std::string> ArgFilter(
- "F",
- llvm::cl::desc("Filter for shared object symbol table"),
- llvm::cl::value_desc("name"));
-
-llvm::cl::alias ArgFilterAlias("filter",
- llvm::cl::desc("alias for -F"),
- llvm::cl::aliasopt(ArgFilter));
-
-// } Not supported yet
-
-} // anonymous namespace
-
-using namespace mcld;
-
-//===----------------------------------------------------------------------===//
-// DynamicSectionOptions
-//===----------------------------------------------------------------------===//
-DynamicSectionOptions::DynamicSectionOptions()
- : m_Entry(ArgEntry),
- m_Bsymbolic(ArgBsymbolic),
- m_Bgroup(ArgBgroup),
- m_SOName(ArgSOName),
- m_NoUndefined(ArgNoUndefined),
- m_AllowMulDefs(ArgAllowMulDefs),
- m_ZOptionList(ArgZOptionList),
- m_Dyld(ArgDyld),
- m_EnableNewDTags(ArgEnableNewDTags),
- m_NumSpareDTags(ArgNumSpareDTags),
- m_Auxiliary(ArgAuxiliary),
- m_Filter(ArgFilter) {
-}
-
-bool DynamicSectionOptions::parse(LinkerConfig& pConfig,
- LinkerScript& pScript) {
- // set up entry point from -e
- pScript.setEntry(m_Entry);
-
- // --Bsymbolic
- pConfig.options().setBsymbolic(m_Bsymbolic);
-
- // --Bgroup
- pConfig.options().setBgroup(m_Bgroup);
-
- // set --soname [soname]
- pConfig.options().setSOName(m_SOName);
-
- // set -z options
- llvm::cl::list<ZOption>::iterator zOpt;
- llvm::cl::list<ZOption>::iterator zOptEnd = m_ZOptionList.end();
- for (zOpt = m_ZOptionList.begin(); zOpt != zOptEnd; ++zOpt) {
- pConfig.options().addZOption(*zOpt);
- }
-
- // set --no-undefined
- if (llvm::cl::BOU_UNSET != m_NoUndefined)
- pConfig.options().setNoUndefined(llvm::cl::BOU_TRUE == m_NoUndefined);
-
- // set --allow-multiple-definition
- if (llvm::cl::BOU_UNSET != m_AllowMulDefs)
- pConfig.options().setMulDefs(llvm::cl::BOU_TRUE == m_AllowMulDefs);
-
- // set --dynamic-linker [dyld]
- pConfig.options().setDyld(m_Dyld);
-
- // set --enable-new-dtags
- pConfig.options().setNewDTags(m_EnableNewDTags);
-
- // set --spare-dyanmic-tags
- pConfig.options().setNumSpareDTags(m_NumSpareDTags);
-
- // set --auxiliary, -f
- llvm::cl::list<std::string>::iterator aux;
- llvm::cl::list<std::string>::iterator auxEnd = m_Auxiliary.end();
- for (aux = m_Auxiliary.begin(); aux != auxEnd; ++aux)
- pConfig.options().getAuxiliaryList().push_back(*aux);
-
- // set --filter, -F
- pConfig.options().setFilter(m_Filter);
-
- return true;
-}
diff --git a/tools/mcld/lib/OptimizationOptions.cpp b/tools/mcld/lib/OptimizationOptions.cpp
deleted file mode 100644
index 50ea73f..0000000
--- a/tools/mcld/lib/OptimizationOptions.cpp
+++ /dev/null
@@ -1,151 +0,0 @@
-//===- OptimizationOptions.cpp --------------------------------------------===//
-//
-// The MCLinker Project
-//
-// This file is distributed under the University of Illinois Open Source
-// License. See LICENSE.TXT for details.
-//
-//===----------------------------------------------------------------------===//
-#include <mcld/OptimizationOptions.h>
-#include <mcld/LinkerConfig.h>
-#include <mcld/Support/CommandLine.h>
-#include <mcld/Support/MsgHandling.h>
-
-namespace {
-
-bool ArgGCSections;
-
-llvm::cl::opt<bool, true> ArgGCSectionsFlag(
- "gc-sections",
- llvm::cl::ZeroOrMore,
- llvm::cl::location(ArgGCSections),
- llvm::cl::desc("Enable garbage collection of unused input sections."),
- llvm::cl::init(false));
-
-llvm::cl::opt<bool, true> ArgNoGCSectionsFlag(
- "no-gc-sections",
- llvm::cl::ZeroOrMore,
- llvm::cl::location(ArgGCSections),
- llvm::cl::desc("disable garbage collection of unused input sections."),
- llvm::cl::init(false));
-
-bool ArgPrintGCSections;
-
-llvm::cl::opt<bool, true> ArgPrintGCSectionsFlag(
- "print-gc-sections",
- llvm::cl::ZeroOrMore,
- llvm::cl::location(ArgPrintGCSections),
- llvm::cl::desc("List all sections removed by garbage collection."),
- llvm::cl::init(false));
-
-llvm::cl::opt<bool, true> ArgNoPrintGCSectionsFlag(
- "no-print-gc-sections",
- llvm::cl::ZeroOrMore,
- llvm::cl::location(ArgPrintGCSections),
- llvm::cl::desc("disable --print-gc-sections"),
- llvm::cl::init(false));
-
-bool ArgGenUnwindInfo;
-
-llvm::cl::opt<bool, true> ArgNoGenUnwindInfoFlag(
- "no-ld-generated-unwind-info",
- llvm::cl::ZeroOrMore,
- llvm::cl::location(ArgGenUnwindInfo),
- llvm::cl::desc(
- "Don't create unwind info for linker"
- " generated sections to save size"),
- llvm::cl::init(false),
- llvm::cl::ValueDisallowed);
-llvm::cl::opt<bool, true> ArgGenUnwindInfoFlag(
- "ld-generated-unwind-info",
- llvm::cl::ZeroOrMore,
- llvm::cl::location(ArgGenUnwindInfo),
- llvm::cl::desc(
- "Request creation of unwind info for linker"
- " generated code sections like PLT."),
- llvm::cl::init(true),
- llvm::cl::ValueDisallowed);
-
-llvm::cl::opt<mcld::GeneralOptions::ICF> ArgICF(
- "icf",
- llvm::cl::ZeroOrMore,
- llvm::cl::desc("Identical Code Folding"),
- llvm::cl::init(mcld::GeneralOptions::ICF_None),
- llvm::cl::values(
- clEnumValN(mcld::GeneralOptions::ICF_None,
- "none",
- "do not perform cold folding"),
- clEnumValN(mcld::GeneralOptions::ICF_All,
- "all",
- "always preform cold folding"),
- clEnumValN(mcld::GeneralOptions::ICF_Safe,
- "safe",
- "Folds those whose pointers are definitely not taken."),
- clEnumValEnd));
-
-llvm::cl::opt<unsigned> ArgICFIterations(
- "icf-iterations",
- llvm::cl::desc("Number of iterations to do ICF."),
- llvm::cl::init(2));
-
-llvm::cl::opt<bool> ArgPrintICFSections(
- "print-icf-sections",
- llvm::cl::desc("Print the folded identical sections."),
- llvm::cl::init(false));
-
-llvm::cl::opt<char> ArgOptLevel(
- "O",
- llvm::cl::desc(
- "Optimization level. [-O0, -O1, -O2, or -O3] "
- "(default = '-O2')"),
- llvm::cl::Prefix,
- llvm::cl::ZeroOrMore,
- llvm::cl::init(' '));
-
-llvm::cl::list<std::string> ArgPlugin("plugin",
- llvm::cl::desc("Load a plugin library."),
- llvm::cl::value_desc("plugin"));
-
-llvm::cl::list<std::string> ArgPluginOpt(
- "plugin-opt",
- llvm::cl::desc("Pass an option to the plugin."),
- llvm::cl::value_desc("option"));
-
-} // anonymous namespace
-
-using namespace mcld;
-
-//===----------------------------------------------------------------------===//
-// OptimizationOptions
-//===----------------------------------------------------------------------===//
-OptimizationOptions::OptimizationOptions()
- : m_GCSections(ArgGCSections),
- m_PrintGCSections(ArgPrintGCSections),
- m_GenUnwindInfo(ArgGenUnwindInfo),
- m_ICF(ArgICF),
- m_ICFIterations(ArgICFIterations),
- m_PrintICFSections(ArgPrintICFSections),
- m_OptLevel(ArgOptLevel),
- m_Plugin(ArgPlugin),
- m_PluginOpt(ArgPluginOpt) {
-}
-
-bool OptimizationOptions::parse(LinkerConfig& pConfig) {
- // set --gc-sections
- if (m_GCSections)
- pConfig.options().setGCSections();
-
- // set --print-gc-sections
- if (m_PrintGCSections)
- pConfig.options().setPrintGCSections();
-
- // set --ld-generated-unwind-info (or not)
- pConfig.options().setGenUnwindInfo(m_GenUnwindInfo);
-
- // set --icf [mode]
- pConfig.options().setICFMode(m_ICF);
- pConfig.options().setICFIterations(m_ICFIterations);
- pConfig.options().setPrintICFSections(m_PrintICFSections);
-
- return true;
-}
diff --git a/tools/mcld/lib/OutputFormatOptions.cpp b/tools/mcld/lib/OutputFormatOptions.cpp
deleted file mode 100644
index 5dd91c7..0000000
--- a/tools/mcld/lib/OutputFormatOptions.cpp
+++ /dev/null
@@ -1,331 +0,0 @@
-//===- OutputFormatOptions.cpp --------------------------------------------===//
-//
-// The MCLinker Project
-//
-// This file is distributed under the University of Illinois Open Source
-// License. See LICENSE.TXT for details.
-//
-//===----------------------------------------------------------------------===//
-#include <mcld/OutputFormatOptions.h>
-#include <mcld/Module.h>
-#include <mcld/Support/MsgHandling.h>
-
-namespace {
-
-llvm::cl::opt<mcld::sys::fs::Path,
- false,
- llvm::cl::parser<mcld::sys::fs::Path> >
- ArgOutputFilename("o",
- llvm::cl::desc("Output filename"),
- llvm::cl::value_desc("filename"));
-
-llvm::cl::alias AliasOutputFilename("output",
- llvm::cl::desc("alias for -o"),
- llvm::cl::aliasopt(ArgOutputFilename));
-
-llvm::cl::opt<mcld::LinkerConfig::CodeGenType> ArgFileType(
- "filetype",
- llvm::cl::init(mcld::LinkerConfig::Exec),
- llvm::cl::desc(
- "Choose a file type\n"
- "(not all types are supported by all targets):"),
- llvm::cl::values(
- clEnumValN(mcld::LinkerConfig::Object,
- "obj",
- "Emit a relocatable object ('.o') file"),
- clEnumValN(mcld::LinkerConfig::DynObj,
- "dso",
- "Emit an dynamic shared object ('.so') file"),
- clEnumValN(mcld::LinkerConfig::Exec,
- "exe",
- "Emit an executable ('.exe') file"),
- clEnumValN(mcld::LinkerConfig::Binary, "bin", "Emit a binary file"),
- clEnumValN(mcld::LinkerConfig::External,
- "null",
- "Emit nothing for performance testing"),
- clEnumValEnd));
-
-llvm::cl::opt<mcld::LinkerConfig::CodeGenType> ArgOFormat(
- "oformat",
- llvm::cl::value_desc("Format"),
- llvm::cl::desc("set output format"),
- llvm::cl::init(mcld::LinkerConfig::Unknown),
- llvm::cl::values(clEnumValN(mcld::LinkerConfig::Binary,
- "binary",
- "generate binary machine code."),
- clEnumValEnd));
-
-llvm::cl::opt<bool> ArgShared("shared",
- llvm::cl::ZeroOrMore,
- llvm::cl::desc("Create a shared library."),
- llvm::cl::init(false));
-
-llvm::cl::alias ArgSharedAlias("Bshareable",
- llvm::cl::desc("alias for -shared"),
- llvm::cl::aliasopt(ArgShared));
-
-llvm::cl::opt<bool> ArgPIE(
- "pie",
- llvm::cl::ZeroOrMore,
- llvm::cl::desc("Emit a position-independent executable file"),
- llvm::cl::init(false));
-
-llvm::cl::opt<bool> ArgRelocatable(
- "relocatable",
- llvm::cl::desc("Generate relocatable output"),
- llvm::cl::init(false));
-
-llvm::cl::alias ArgRelocatableAlias("r",
- llvm::cl::desc("alias for --relocatable"),
- llvm::cl::aliasopt(ArgRelocatable));
-
-llvm::cl::opt<mcld::Input::Type> ArgFormat(
- "b",
- llvm::cl::value_desc("Format"),
- llvm::cl::desc("set input format"),
- llvm::cl::init(mcld::Input::Unknown),
- llvm::cl::values(clEnumValN(mcld::Input::Binary,
- "binary",
- "read in binary machine code."),
- clEnumValEnd));
-
-llvm::cl::alias ArgFormatAlias("format",
- llvm::cl::desc("alias for -b"),
- llvm::cl::aliasopt(ArgFormat));
-
-llvm::cl::opt<bool> ArgStripDebug(
- "strip-debug",
- llvm::cl::desc("Omit debugger symbol information from the output file."),
- llvm::cl::init(false));
-
-llvm::cl::alias ArgStripDebugAlias("S",
- llvm::cl::desc("alias for --strip-debug"),
- llvm::cl::aliasopt(ArgStripDebug));
-
-llvm::cl::opt<bool> ArgStripAll(
- "strip-all",
- llvm::cl::desc("Omit all symbol information from the output file."),
- llvm::cl::init(false));
-
-llvm::cl::alias ArgStripAllAlias("s",
- llvm::cl::desc("alias for --strip-all"),
- llvm::cl::aliasopt(ArgStripAll));
-
-llvm::cl::opt<bool> ArgDiscardAll("discard-all",
- llvm::cl::desc("Delete all local symbols."),
- llvm::cl::init(false));
-
-llvm::cl::alias ArgDiscardAllAlias("x",
- llvm::cl::desc("alias for --discard-all"),
- llvm::cl::aliasopt(ArgDiscardAll));
-
-llvm::cl::opt<bool> ArgDiscardLocals(
- "discard-locals",
- llvm::cl::desc("Delete all temporary local symbols."),
- llvm::cl::init(false));
-
-llvm::cl::alias ArgDiscardLocalsAlias(
- "X",
- llvm::cl::desc("alias for --discard-locals"),
- llvm::cl::aliasopt(ArgDiscardLocals));
-
-llvm::cl::opt<bool> ArgEhFrameHdr(
- "eh-frame-hdr",
- llvm::cl::ZeroOrMore,
- llvm::cl::desc(
- "Request creation of \".eh_frame_hdr\" section and\n"
- "ELF \"PT_GNU_EH_FRAME\" segment header."),
- llvm::cl::init(false));
-
-llvm::cl::opt<bool> ArgNMagic("nmagic",
- llvm::cl::desc("Do not page align data"),
- llvm::cl::init(false));
-
-llvm::cl::alias ArgNMagicAlias("n",
- llvm::cl::desc("alias for --nmagic"),
- llvm::cl::aliasopt(ArgNMagic));
-
-llvm::cl::opt<bool> ArgOMagic(
- "omagic",
- llvm::cl::desc("Do not page align data, do not make text readonly"),
- llvm::cl::init(false));
-
-llvm::cl::alias ArgOMagicAlias("N",
- llvm::cl::desc("alias for --omagic"),
- llvm::cl::aliasopt(ArgOMagic));
-
-llvm::cl::opt<mcld::GeneralOptions::HashStyle> ArgHashStyle(
- "hash-style",
- llvm::cl::ZeroOrMore,
- llvm::cl::init(mcld::GeneralOptions::SystemV),
- llvm::cl::desc("Set the type of linker's hash table(s)."),
- llvm::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));
-
-llvm::cl::opt<bool> ArgNoWarnMismatch(
- "no-warn-mismatch",
- llvm::cl::desc("Allow linking together mismatched input files."),
- llvm::cl::init(false));
-
-// Not supported yet {
-llvm::cl::opt<bool> ArgExportDynamic(
- "export-dynamic",
- llvm::cl::desc("Export all dynamic symbols"),
- llvm::cl::init(false));
-
-llvm::cl::alias ArgExportDynamicAlias(
- "E",
- llvm::cl::desc("alias for --export-dynamic"),
- llvm::cl::aliasopt(ArgExportDynamic));
-
-llvm::cl::opt<std::string> ArgBuildID(
- "build-id",
- llvm::cl::desc(
- "Request creation of \".note.gnu.build-id\" ELF note section."),
- llvm::cl::value_desc("style"),
- llvm::cl::ValueOptional);
-
-llvm::cl::list<std::string> ArgExcludeLIBS(
- "exclude-libs",
- llvm::cl::CommaSeparated,
- llvm::cl::desc("Exclude libraries from automatic export"),
- llvm::cl::value_desc("lib1,lib2,..."));
-
-// } Not supported yet
-
-} // anonymous namespace
-
-using namespace mcld;
-
-//===----------------------------------------------------------------------===//
-// OutputFormatOptions
-//===----------------------------------------------------------------------===//
-OutputFormatOptions::OutputFormatOptions()
- : m_OutputFilename(ArgOutputFilename),
- m_FileType(ArgFileType),
- m_OFormat(ArgOFormat),
- m_Shared(ArgShared),
- m_PIE(ArgPIE),
- m_Relocatable(ArgRelocatable),
- m_Format(ArgFormat),
- m_StripDebug(ArgStripDebug),
- m_StripAll(ArgStripAll),
- m_DiscardAll(ArgDiscardAll),
- m_DiscardLocals(ArgDiscardLocals),
- m_EhFrameHdr(ArgEhFrameHdr),
- m_NMagic(ArgNMagic),
- m_OMagic(ArgOMagic),
- m_HashStyle(ArgHashStyle),
- m_ExportDynamic(ArgExportDynamic),
- m_BuildID(ArgBuildID),
- m_ExcludeLIBS(ArgExcludeLIBS),
- m_NoWarnMismatch(ArgNoWarnMismatch) {
-}
-
-bool OutputFormatOptions::parse(mcld::Module& pModule, LinkerConfig& pConfig) {
- if (!parseOutput(pModule, pConfig)) {
- mcld::unreachable(mcld::diag::unrecognized_output_file) << pModule.name();
- return false;
- }
-
- if (mcld::Input::Binary == m_Format)
- pConfig.options().setBinaryInput();
-
- pConfig.options().setStripDebug(m_StripDebug || m_StripAll);
- if (m_StripAll)
- pConfig.options().setStripSymbols(mcld::GeneralOptions::StripAllSymbols);
- else if (m_DiscardAll)
- pConfig.options().setStripSymbols(mcld::GeneralOptions::StripLocals);
- else if (m_DiscardLocals)
- pConfig.options().setStripSymbols(mcld::GeneralOptions::StripTemporaries);
- else
- pConfig.options().setStripSymbols(mcld::GeneralOptions::KeepAllSymbols);
-
- pConfig.options().setEhFrameHdr(m_EhFrameHdr);
- pConfig.options().setPIE(m_PIE);
- pConfig.options().setNMagic(m_NMagic);
- pConfig.options().setOMagic(m_OMagic);
- pConfig.options().setHashStyle(m_HashStyle);
- pConfig.options().setExportDynamic(m_ExportDynamic);
-
- // --exclude-libs
- llvm::cl::list<std::string>::iterator exclude,
- excludeEnd = m_ExcludeLIBS.end();
- for (exclude = m_ExcludeLIBS.begin(); exclude != excludeEnd; ++exclude) {
- pConfig.options().excludeLIBS().insert(*exclude);
- }
-
- if (m_NoWarnMismatch)
- pConfig.options().setWarnMismatch(false);
- else
- pConfig.options().setWarnMismatch(true);
- // build-id
- // exclude-libs
-
- return true;
-}
-
-/// configure the output filename
-bool OutputFormatOptions::parseOutput(Module& pModule, LinkerConfig& pConfig) {
- if (true == m_Shared || true == m_PIE) {
- // -shared or -pie
- m_FileType = mcld::LinkerConfig::DynObj;
- } else if (true == m_Relocatable) {
- // partial linking
- m_FileType = mcld::LinkerConfig::Object;
- } else if (mcld::LinkerConfig::Binary == m_OFormat) {
- // binary output
- m_FileType = mcld::LinkerConfig::Binary;
- }
-
- pConfig.setCodeGenType(m_FileType);
-
- std::string output_filename(m_OutputFilename.native());
-
- if (m_OutputFilename.empty()) {
- if (llvm::Triple::Win32 == pConfig.targets().triple().getOS()) {
- output_filename.assign("_out");
- switch (m_FileType) {
- case mcld::LinkerConfig::Object: {
- output_filename += ".obj";
- break;
- }
- case mcld::LinkerConfig::DynObj: {
- output_filename += ".dll";
- break;
- }
- case mcld::LinkerConfig::Exec: {
- output_filename += ".exe";
- break;
- }
- case mcld::LinkerConfig::External:
- break;
- default: {
- return false;
- break;
- }
- } // switch
- } else {
- if (mcld::LinkerConfig::Object == m_FileType ||
- mcld::LinkerConfig::DynObj == m_FileType ||
- mcld::LinkerConfig::Exec == m_FileType ||
- mcld::LinkerConfig::External == m_FileType) {
- output_filename.assign("a.out");
- } else {
- return false;
- }
- }
- } // end of if empty m_OutputFilename
-
- pModule.setName(output_filename);
- return true;
-}
diff --git a/tools/mcld/lib/PositionalOptions.cpp b/tools/mcld/lib/PositionalOptions.cpp
deleted file mode 100644
index 43d271b..0000000
--- a/tools/mcld/lib/PositionalOptions.cpp
+++ /dev/null
@@ -1,346 +0,0 @@
-//===- PositionalOptions.cpp ----------------------------------------------===//
-//
-// The MCLinker Project
-//
-// This file is distributed under the University of Illinois Open Source
-// License. See LICENSE.TXT for details.
-//
-//===----------------------------------------------------------------------===//
-#include <mcld/PositionalOptions.h>
-#include <mcld/LinkerConfig.h>
-#include <mcld/LinkerScript.h>
-#include <mcld/MC/InputAction.h>
-#include <mcld/MC/CommandAction.h>
-#include <mcld/MC/FileAction.h>
-#include <mcld/Support/MsgHandling.h>
-
-namespace {
-
-//===----------------------------------------------------------------------===//
-// Normal input files
-//===----------------------------------------------------------------------===//
-llvm::cl::list<mcld::sys::fs::Path> ArgInputObjectFiles(
- llvm::cl::Positional,
- llvm::cl::desc("[input object files]"),
- llvm::cl::ZeroOrMore);
-
-// --script is an alias, but cl::alias doesn't work correctly with cl::list.
-llvm::cl::list<std::string> ArgLinkerScript("T",
- llvm::cl::ZeroOrMore,
- llvm::cl::desc("Linker script"),
- llvm::cl::value_desc("file"));
-
-//===----------------------------------------------------------------------===//
-// Namespecs
-//===----------------------------------------------------------------------===//
-llvm::cl::list<std::string> ArgNameSpecList(
- "l",
- llvm::cl::ZeroOrMore,
- llvm::cl::desc(
- "Add the archive or object file specified by namespec to\n"
- "the list of files to link."),
- llvm::cl::value_desc("namespec"),
- llvm::cl::Prefix);
-
-llvm::cl::alias ArgNameSpecListAlias("library",
- llvm::cl::desc("alias for -l"),
- llvm::cl::aliasopt(ArgNameSpecList));
-
-//===----------------------------------------------------------------------===//
-// Attributes
-//===----------------------------------------------------------------------===//
-llvm::cl::list<bool> ArgWholeArchiveList(
- "whole-archive",
- llvm::cl::ValueDisallowed,
- llvm::cl::desc(
- "For each archive mentioned on the command line after\n"
- "the --whole-archive option, include all object files\n"
- "in the archive."));
-
-llvm::cl::list<bool> ArgNoWholeArchiveList(
- "no-whole-archive",
- llvm::cl::ValueDisallowed,
- llvm::cl::desc(
- "Turn off the effect of the --whole-archive option for\n"
- "subsequent archive files."));
-
-llvm::cl::list<bool> ArgAsNeededList(
- "as-needed",
- llvm::cl::ValueDisallowed,
- llvm::cl::desc(
- "This option affects ELF DT_NEEDED tags for dynamic\n"
- "libraries mentioned on the command line after the\n"
- "--as-needed option."));
-
-llvm::cl::list<bool> ArgNoAsNeededList(
- "no-as-needed",
- llvm::cl::ValueDisallowed,
- llvm::cl::desc(
- "Turn off the effect of the --as-needed option for\n"
- "subsequent dynamic libraries"));
-
-llvm::cl::list<bool> ArgAddNeededList(
- "add-needed",
- llvm::cl::ValueDisallowed,
- llvm::cl::desc(
- "--add-needed causes DT_NEEDED tags are always\n"
- "emitted for those libraries from DT_NEEDED tags.\n"
- "This is the default behavior."));
-
-llvm::cl::list<bool> ArgNoAddNeededList(
- "no-add-needed",
- llvm::cl::ValueDisallowed,
- llvm::cl::desc(
- "--no-add-needed causes DT_NEEDED tags will never be\n"
- "emitted for those libraries from DT_NEEDED tags"));
-
-llvm::cl::list<bool> ArgBDynamicList(
- "Bdynamic",
- llvm::cl::ValueDisallowed,
- llvm::cl::desc("Link against dynamic library"));
-
-llvm::cl::alias ArgBDynamicListAlias1("dy",
- llvm::cl::desc("alias for --Bdynamic"),
- llvm::cl::aliasopt(ArgBDynamicList));
-
-llvm::cl::alias ArgBDynamicListAlias2("call_shared",
- llvm::cl::desc("alias for --Bdynamic"),
- llvm::cl::aliasopt(ArgBDynamicList));
-
-llvm::cl::list<bool> ArgBStaticList(
- "Bstatic",
- llvm::cl::ValueDisallowed,
- llvm::cl::desc("Link against static library"));
-
-llvm::cl::alias ArgBStaticListAlias1("dn",
- llvm::cl::desc("alias for --Bstatic"),
- llvm::cl::aliasopt(ArgBStaticList));
-
-llvm::cl::alias ArgBStaticListAlias2("static",
- llvm::cl::desc("alias for --Bstatic"),
- llvm::cl::aliasopt(ArgBStaticList));
-
-llvm::cl::alias ArgBStaticListAlias3("non_shared",
- llvm::cl::desc("alias for --Bstatic"),
- llvm::cl::aliasopt(ArgBStaticList));
-
-//===----------------------------------------------------------------------===//
-// Groups
-//===----------------------------------------------------------------------===//
-llvm::cl::list<bool> ArgStartGroupList(
- "start-group",
- llvm::cl::ValueDisallowed,
- llvm::cl::desc("start to record a group of archives"));
-
-llvm::cl::alias ArgStartGroupListAlias(
- "(",
- llvm::cl::desc("alias for --start-group"),
- llvm::cl::aliasopt(ArgStartGroupList));
-
-llvm::cl::list<bool> ArgEndGroupList(
- "end-group",
- llvm::cl::ValueDisallowed,
- llvm::cl::desc("stop recording a group of archives"));
-
-llvm::cl::alias ArgEndGroupListAlias(")",
- llvm::cl::desc("alias for --end-group"),
- llvm::cl::aliasopt(ArgEndGroupList));
-
-//===----------------------------------------------------------------------===//
-// --defsym
-//===----------------------------------------------------------------------===//
-llvm::cl::list<std::string> ArgDefSymList(
- "defsym",
- llvm::cl::ZeroOrMore,
- llvm::cl::desc("Define a symbol"),
- llvm::cl::value_desc("symbol=expression"));
-
-//===----------------------------------------------------------------------===//
-// Help Functions
-//===----------------------------------------------------------------------===//
-inline bool CompareAction(const mcld::InputAction* X,
- const mcld::InputAction* Y) {
- return (X->position() < Y->position());
-}
-
-} // anonymous namespace
-
-using namespace mcld;
-
-//===----------------------------------------------------------------------===//
-// PositionalOptions
-//===----------------------------------------------------------------------===//
-PositionalOptions::PositionalOptions()
- : m_InputObjectFiles(ArgInputObjectFiles),
- m_LinkerScript(ArgLinkerScript),
- m_NameSpecList(ArgNameSpecList),
- m_WholeArchiveList(ArgWholeArchiveList),
- m_NoWholeArchiveList(ArgNoWholeArchiveList),
- m_AsNeededList(ArgAsNeededList),
- m_NoAsNeededList(ArgNoAsNeededList),
- m_AddNeededList(ArgAddNeededList),
- m_NoAddNeededList(ArgNoAddNeededList),
- m_BDynamicList(ArgBDynamicList),
- m_BStaticList(ArgBStaticList),
- m_StartGroupList(ArgStartGroupList),
- m_EndGroupList(ArgEndGroupList),
- m_DefSymList(ArgDefSymList) {
-}
-
-size_t PositionalOptions::numOfActions() const {
- return m_InputObjectFiles.size() + m_LinkerScript.size() +
- m_NameSpecList.size() + m_WholeArchiveList.size() +
- m_NoWholeArchiveList.size() + m_AsNeededList.size() +
- m_NoAsNeededList.size() + m_AddNeededList.size() +
- m_NoAddNeededList.size() + m_BDynamicList.size() +
- m_BStaticList.size() + m_StartGroupList.size() +
- m_EndGroupList.size() + m_DefSymList.size();
-}
-
-size_t PositionalOptions::numOfInputs() const {
- return (m_InputObjectFiles.size() + m_LinkerScript.size() +
- m_NameSpecList.size());
-}
-
-bool PositionalOptions::parse(std::vector<InputAction*>& pActions,
- LinkerConfig& pConfig,
- const LinkerScript& pScript) {
- if (0 == numOfInputs()) {
- fatal(diag::err_no_inputs);
- return false;
- }
-
- pActions.reserve(numOfActions());
-
- // -T/--script
- // FIXME:
- llvm::cl::list<std::string>::iterator sp;
- llvm::cl::list<std::string>::iterator spEnd = m_LinkerScript.end();
- for (sp = m_LinkerScript.begin(); sp != spEnd; ++sp) {
- pConfig.options().getScriptList().push_back(*sp);
-
- pActions.push_back(new ScriptAction(
- 0x0, *sp, ScriptFile::LDScript, pScript.directories()));
- pActions.push_back(new ContextAction(0x0));
- pActions.push_back(new MemoryAreaAction(0x0, FileHandle::ReadOnly));
- }
-
- // --defsym
- llvm::cl::list<std::string>::iterator defsym, dsBegin, dsEnd;
- dsBegin = m_DefSymList.begin();
- dsEnd = m_DefSymList.end();
- for (defsym = dsBegin; defsym != dsEnd; ++defsym) {
- unsigned int pos = m_DefSymList.getPosition(defsym - dsBegin);
- pActions.push_back(new DefSymAction(pos, *defsym));
- }
-
- // set input
- llvm::cl::list<mcld::sys::fs::Path>::iterator input, inBegin, inEnd;
- inBegin = m_InputObjectFiles.begin();
- inEnd = m_InputObjectFiles.end();
- for (input = inBegin; input != inEnd; ++input) {
- unsigned int pos = m_InputObjectFiles.getPosition(input - inBegin);
- pActions.push_back(new InputFileAction(pos, *input));
- pActions.push_back(new ContextAction(pos));
- pActions.push_back(new MemoryAreaAction(pos, FileHandle::ReadOnly));
- }
-
- // set -l[namespec]
- llvm::cl::list<std::string>::iterator namespec, nsBegin, nsEnd;
- nsBegin = m_NameSpecList.begin();
- nsEnd = m_NameSpecList.end();
- for (namespec = nsBegin; namespec != nsEnd; ++namespec) {
- unsigned int pos = m_NameSpecList.getPosition(namespec - nsBegin);
- pActions.push_back(
- new NamespecAction(pos, *namespec, pScript.directories()));
- pActions.push_back(new ContextAction(pos));
- pActions.push_back(new MemoryAreaAction(pos, FileHandle::ReadOnly));
- }
-
- // set --whole-archive
- llvm::cl::list<bool>::iterator attr, attrBegin, attrEnd;
- attrBegin = m_WholeArchiveList.begin();
- attrEnd = m_WholeArchiveList.end();
- for (attr = attrBegin; attr != attrEnd; ++attr) {
- unsigned int pos = m_WholeArchiveList.getPosition(attr - attrBegin);
- pActions.push_back(new WholeArchiveAction(pos));
- }
-
- // set --no-whole-archive
- attrBegin = m_NoWholeArchiveList.begin();
- attrEnd = m_NoWholeArchiveList.end();
- for (attr = attrBegin; attr != attrEnd; ++attr) {
- unsigned int pos = m_NoWholeArchiveList.getPosition(attr - attrBegin);
- pActions.push_back(new NoWholeArchiveAction(pos));
- }
-
- // set --as-needed
- attrBegin = m_AsNeededList.begin();
- attrEnd = m_AsNeededList.end();
- for (attr = attrBegin; attr != attrEnd; ++attr) {
- unsigned int pos = m_AsNeededList.getPosition(attr - attrBegin);
- pActions.push_back(new AsNeededAction(pos));
- }
-
- // set --no-as-needed
- attrBegin = m_NoAsNeededList.begin();
- attrEnd = m_NoAsNeededList.end();
- for (attr = attrBegin; attr != attrEnd; ++attr) {
- unsigned int pos = m_NoAsNeededList.getPosition(attr - attrBegin);
- pActions.push_back(new NoAsNeededAction(pos));
- }
-
- // set --add--needed
- attrBegin = m_AddNeededList.begin();
- attrEnd = m_AddNeededList.end();
- for (attr = attrBegin; attr != attrEnd; ++attr) {
- unsigned int pos = m_AddNeededList.getPosition(attr - attrBegin);
- pActions.push_back(new AddNeededAction(pos));
- }
-
- // set --no-add--needed
- attrBegin = m_NoAddNeededList.begin();
- attrEnd = m_NoAddNeededList.end();
- for (attr = attrBegin; attr != attrEnd; ++attr) {
- unsigned int pos = m_NoAddNeededList.getPosition(attr - attrBegin);
- pActions.push_back(new NoAddNeededAction(pos));
- }
-
- // set --Bdynamic
- attrBegin = m_BDynamicList.begin();
- attrEnd = m_BDynamicList.end();
- for (attr = attrBegin; attr != attrEnd; ++attr) {
- unsigned int pos = m_BDynamicList.getPosition(attr - attrBegin);
- pActions.push_back(new BDynamicAction(pos));
- }
-
- // set --Bstatic
- attrBegin = m_BStaticList.begin();
- attrEnd = m_BStaticList.end();
- for (attr = attrBegin; attr != attrEnd; ++attr) {
- unsigned int pos = m_BStaticList.getPosition(attr - attrBegin);
- pActions.push_back(new BStaticAction(pos));
- }
-
- // set --start-group
- llvm::cl::list<bool>::iterator group, gsBegin, gsEnd;
- gsBegin = m_StartGroupList.begin();
- gsEnd = m_StartGroupList.end();
- for (group = gsBegin; group != gsEnd; ++group) {
- unsigned int pos = m_StartGroupList.getPosition(group - gsBegin);
- pActions.push_back(new StartGroupAction(pos));
- }
-
- // set --end-group
- gsBegin = m_EndGroupList.begin();
- gsEnd = m_EndGroupList.end();
- for (group = gsBegin; group != gsEnd; ++group) {
- unsigned int pos = m_EndGroupList.getPosition(group - gsBegin);
- pActions.push_back(new EndGroupAction(pos));
- }
-
- // stable sort
- std::stable_sort(pActions.begin(), pActions.end(), CompareAction);
-
- return true;
-}
diff --git a/tools/mcld/lib/PreferenceOptions.cpp b/tools/mcld/lib/PreferenceOptions.cpp
deleted file mode 100644
index ec20d88..0000000
--- a/tools/mcld/lib/PreferenceOptions.cpp
+++ /dev/null
@@ -1,183 +0,0 @@
-//===- PreferenceOptions.cpp ----------------------------------------------===//
-//
-// The MCLinker Project
-//
-// This file is distributed under the University of Illinois Open Source
-// License. See LICENSE.TXT for details.
-//
-//===----------------------------------------------------------------------===//
-#include <mcld/PreferenceOptions.h>
-#include <mcld/LinkerConfig.h>
-#include <mcld/Support/CommandLine.h>
-#include <mcld/Support/raw_ostream.h>
-#include <llvm/Support/Process.h>
-
-#if defined(HAVE_UNISTD_H)
-#include <unistd.h>
-#endif
-
-#if defined(_MSC_VER) || defined(__MINGW32__)
-#include <io.h>
-#ifndef STDIN_FILENO
-#define STDIN_FILENO 0
-#endif
-#ifndef STDOUT_FILENO
-#define STDOUT_FILENO 1
-#endif
-#ifndef STDERR_FILENO
-#define STDERR_FILENO 2
-#endif
-#endif
-
-namespace {
-
-llvm::cl::opt<bool> ArgTrace(
- "t",
- llvm::cl::desc("Print the names of the input files as ld processes them."));
-
-llvm::cl::alias ArgTraceAlias("trace",
- llvm::cl::desc("alias for -t"),
- llvm::cl::aliasopt(ArgTrace));
-
-llvm::cl::opt<int> ArgVerbose(
- "verbose",
- llvm::cl::init(-1),
- llvm::cl::desc(
- "Display the version number for ld and list the\n"
- "linker emulations supported."));
-
-llvm::cl::opt<bool> ArgVersion(
- "Version",
- llvm::cl::init(false),
- llvm::cl::desc("Display the version number for MCLinker."));
-
-llvm::cl::alias ArgVersionAlias("v",
- llvm::cl::desc("alias for -Version"),
- llvm::cl::aliasopt(ArgVersion));
-
-llvm::cl::opt<int> ArgMaxErrorNum(
- "error-limit",
- llvm::cl::init(-1),
- llvm::cl::desc("limits the maximum number of erros."));
-
-llvm::cl::opt<int> ArgMaxWarnNum(
- "warning-limit",
- llvm::cl::init(-1),
- llvm::cl::desc("limits the maximum number of warnings."));
-
-llvm::cl::opt<mcld::PreferenceOptions::Color> ArgColor(
- "colormc",
- llvm::cl::value_desc("When"),
- llvm::cl::desc("Surround the result strings with the marker"),
- llvm::cl::init(mcld::PreferenceOptions::COLOR_Auto),
- llvm::cl::values(
- clEnumValN(mcld::PreferenceOptions::COLOR_Never,
- "never",
- "do not surround result"),
- clEnumValN(mcld::PreferenceOptions::COLOR_Always,
- "always",
- "always surround results, even the output is a plain file"),
- clEnumValN(mcld::PreferenceOptions::COLOR_Auto,
- "auto",
- "surround result strings only if the output is a tty"),
- clEnumValEnd));
-
-llvm::cl::opt<bool> ArgPrintMap(
- "M",
- llvm::cl::desc("Print a link map to the standard output."),
- llvm::cl::init(false));
-
-llvm::cl::alias ArgPrintMapAlias("print-map",
- llvm::cl::desc("alias for -M"),
- llvm::cl::aliasopt(ArgPrintMap));
-
-bool ArgFatalWarnings;
-
-llvm::cl::opt<bool, true> ArgNoFatalWarnings(
- "no-fatal-warnings",
- llvm::cl::location(ArgFatalWarnings),
- llvm::cl::desc("do not turn warnings into errors"),
- llvm::cl::init(false),
- llvm::cl::ValueDisallowed);
-
-llvm::cl::opt<bool, true> ArgFatalWarningsFlag(
- "fatal-warnings",
- llvm::cl::ZeroOrMore,
- llvm::cl::location(ArgFatalWarnings),
- llvm::cl::desc("turn all warnings into errors"),
- llvm::cl::init(false),
- llvm::cl::ValueDisallowed);
-
-llvm::cl::opt<std::string> ArgUseLD(
- "fuse-ld",
- llvm::cl::desc("Ignored for GCC/collect2 linker compatibility."),
- llvm::cl::init("mcld"));
-
-llvm::cl::opt<bool> ArgUseMCLD(
- "use-mcld",
- llvm::cl::desc("Ignored for GCC/collect2 linker compatibility."),
- llvm::cl::init(false));
-
-//===----------------------------------------------------------------------===//
-// Non-member functions
-//===----------------------------------------------------------------------===//
-inline bool ShouldColorize() {
- const char* term = getenv("TERM");
- return term && (0 != strcmp(term, "dumb"));
-}
-
-} // anonymous namespace
-
-using namespace mcld;
-
-//===----------------------------------------------------------------------===//
-// PreferenceOptions
-//===----------------------------------------------------------------------===//
-PreferenceOptions::PreferenceOptions()
- : m_Trace(ArgTrace),
- m_Verbose(ArgVerbose),
- m_Version(ArgVersion),
- m_MaxErrorNum(ArgMaxErrorNum),
- m_MaxWarnNum(ArgMaxWarnNum),
- m_Color(ArgColor),
- m_PrintMap(ArgPrintMap),
- m_FatalWarnings(ArgFatalWarnings) {
-}
-
-bool PreferenceOptions::parse(LinkerConfig& pConfig) {
- // set -t
- pConfig.options().setTrace(m_Trace);
-
- // set --verbose
- pConfig.options().setVerbose(m_Verbose);
-
- // set --error-limit [number]
- pConfig.options().setMaxErrorNum(m_MaxErrorNum);
-
- // set --warning-limit [number]
- pConfig.options().setMaxWarnNum(m_MaxWarnNum);
-
- // set --color [mode]
- switch (m_Color) {
- case COLOR_Never:
- pConfig.options().setColor(false);
- break;
- case COLOR_Always:
- pConfig.options().setColor(true);
- break;
- case COLOR_Auto:
- bool color_option =
- ShouldColorize() &&
- llvm::sys::Process::FileDescriptorIsDisplayed(STDOUT_FILENO);
- pConfig.options().setColor(color_option);
- break;
- }
-
- mcld::outs().setColor(pConfig.options().color());
- mcld::errs().setColor(pConfig.options().color());
-
- if (m_Version)
- mcld::outs() << pConfig.options().getVersionString() << "\n";
-
- return true;
-}
diff --git a/tools/mcld/lib/ScriptOptions.cpp b/tools/mcld/lib/ScriptOptions.cpp
deleted file mode 100644
index 55dadab..0000000
--- a/tools/mcld/lib/ScriptOptions.cpp
+++ /dev/null
@@ -1,169 +0,0 @@
-//===- ScriptOptions.cpp --------------------------------------------------===//
-//
-// The MCLinker Project
-//
-// This file is distributed under the University of Illinois Open Source
-// License. See LICENSE.TXT for details.
-//
-//===----------------------------------------------------------------------===//
-#include <mcld/ScriptOptions.h>
-#include <mcld/LinkerScript.h>
-#include <mcld/ADT/StringEntry.h>
-#include <mcld/Support/MsgHandling.h>
-
-namespace {
-
-//===----------------------------------------------------------------------===//
-// Script Options
-// Script options are used to modify the default link script. Some positional
-// options, such as --defsym, also can modify default link script is not listed
-// here. These special options belong to Positional Options.
-//===----------------------------------------------------------------------===//
-static llvm::cl::list<std::string> ArgWrapList(
- "wrap",
- llvm::cl::ZeroOrMore,
- llvm::cl::desc("Use a wrap function fo symbol."),
- llvm::cl::value_desc("symbol"));
-
-static llvm::cl::list<std::string> ArgPortList(
- "portable",
- llvm::cl::ZeroOrMore,
- llvm::cl::desc("Use a portable function fo symbol."),
- llvm::cl::value_desc("symbol"));
-
-static llvm::cl::list<std::string> ArgAddressMapList(
- "section-start",
- llvm::cl::ZeroOrMore,
- llvm::cl::desc("Locate a output section at the given absolute address"),
- llvm::cl::value_desc("Set address of section"),
- llvm::cl::Prefix);
-
-static llvm::cl::opt<unsigned long long> ArgBssSegAddr(
- "Tbss",
- llvm::cl::desc("Set the address of the bss segment"),
- llvm::cl::init(-1U));
-
-static llvm::cl::opt<unsigned long long> ArgDataSegAddr(
- "Tdata",
- llvm::cl::desc("Set the address of the data segment"),
- llvm::cl::init(-1U));
-
-static llvm::cl::opt<unsigned long long> ArgTextSegAddr(
- "Ttext",
- llvm::cl::desc("Set the address of the text segment"),
- llvm::cl::init(-1U));
-
-static llvm::cl::alias ArgTextSegAddrAlias("Ttext-segment",
- llvm::cl::desc("alias for -Ttext"),
- llvm::cl::aliasopt(ArgTextSegAddr));
-
-} // anonymous namespace
-
-using namespace mcld;
-
-//===----------------------------------------------------------------------===//
-// ScriptOptions
-//===----------------------------------------------------------------------===//
-ScriptOptions::ScriptOptions()
- : m_WrapList(ArgWrapList),
- m_PortList(ArgPortList),
- m_AddressMapList(ArgAddressMapList),
- m_BssSegAddr(ArgBssSegAddr),
- m_DataSegAddr(ArgDataSegAddr),
- m_TextSegAddr(ArgTextSegAddr) {
-}
-
-bool ScriptOptions::parse(LinkerScript& pScript) {
- // set up rename map, for --wrap
- llvm::cl::list<std::string>::iterator wname;
- llvm::cl::list<std::string>::iterator wnameEnd = ArgWrapList.end();
- for (wname = ArgWrapList.begin(); wname != wnameEnd; ++wname) {
- bool exist = false;
-
- // add wname -> __wrap_wname
- StringEntry<llvm::StringRef>* to_wrap =
- pScript.renameMap().insert(*wname, exist);
-
- std::string to_wrap_str = "__wrap_" + *wname;
- to_wrap->setValue(to_wrap_str);
-
- if (exist)
- warning(mcld::diag::rewrap) << *wname << to_wrap_str;
-
- // add __real_wname -> wname
- std::string from_real_str = "__real_" + *wname;
- StringEntry<llvm::StringRef>* from_real =
- pScript.renameMap().insert(from_real_str, exist);
- from_real->setValue(*wname);
- if (exist)
- mcld::warning(mcld::diag::rewrap) << *wname << from_real_str;
- }
-
- // set up rename map, for --portable
- llvm::cl::list<std::string>::iterator pname;
- llvm::cl::list<std::string>::iterator pnameEnd = ArgPortList.end();
- for (pname = ArgPortList.begin(); pname != pnameEnd; ++pname) {
- bool exist = false;
-
- // add pname -> pname_portable
- StringEntry<llvm::StringRef>* to_port =
- pScript.renameMap().insert(*pname, exist);
-
- std::string to_port_str = *pname + "_portable";
- to_port->setValue(to_port_str);
-
- if (exist)
- warning(mcld::diag::rewrap) << *pname << to_port_str;
-
- // add __real_pname -> pname
- std::string from_real_str = "__real_" + *pname;
- StringEntry<llvm::StringRef>* from_real =
- pScript.renameMap().insert(from_real_str, exist);
-
- from_real->setValue(*pname);
- if (exist)
- warning(mcld::diag::rewrap) << *pname << from_real_str;
- } // end of for
-
- // set --section-start SECTION=ADDRESS
- for (llvm::cl::list<std::string>::iterator it = ArgAddressMapList.begin(),
- ie = ArgAddressMapList.end();
- it != ie;
- ++it) {
- // FIXME: Add a cl::parser
- size_t pos = (*it).find_last_of('=');
- llvm::StringRef script(*it);
- uint64_t address = 0x0;
- script.substr(pos + 1).getAsInteger(0, address);
- bool exist = false;
- StringEntry<uint64_t>* addr_mapping =
- pScript.addressMap().insert(script.substr(0, pos), exist);
- addr_mapping->setValue(address);
- }
-
- // set -Tbss [address]
- if (-1U != ArgBssSegAddr) {
- bool exist = false;
- StringEntry<uint64_t>* bss_mapping =
- pScript.addressMap().insert(".bss", exist);
- bss_mapping->setValue(ArgBssSegAddr);
- }
-
- // set -Tdata [address]
- if (-1U != ArgDataSegAddr) {
- bool exist = false;
- StringEntry<uint64_t>* data_mapping =
- pScript.addressMap().insert(".data", exist);
- data_mapping->setValue(ArgDataSegAddr);
- }
-
- // set -Ttext [address]
- if (-1U != ArgTextSegAddr) {
- bool exist = false;
- StringEntry<uint64_t>* text_mapping =
- pScript.addressMap().insert(".text", exist);
- text_mapping->setValue(ArgTextSegAddr);
- }
-
- return true;
-}
diff --git a/tools/mcld/lib/SearchPathOptions.cpp b/tools/mcld/lib/SearchPathOptions.cpp
deleted file mode 100644
index 8096b90..0000000
--- a/tools/mcld/lib/SearchPathOptions.cpp
+++ /dev/null
@@ -1,108 +0,0 @@
-//===- SearchPathOptions.cpp ----------------------------------------------===//
-//
-// The MCLinker Project
-//
-// This file is distributed under the University of Illinois Open Source
-// License. See LICENSE.TXT for details.
-//
-//===----------------------------------------------------------------------===//
-#include <mcld/SearchPathOptions.h>
-#include <mcld/LinkerConfig.h>
-#include <mcld/LinkerScript.h>
-#include <mcld/Support/raw_ostream.h>
-
-namespace {
-
-llvm::cl::opt<mcld::sys::fs::Path,
- false,
- llvm::cl::parser<mcld::sys::fs::Path> >
- ArgSysRoot("sysroot",
- llvm::cl::desc("Use directory as the location of the sysroot"),
- llvm::cl::value_desc("directory"),
- llvm::cl::ValueRequired);
-
-llvm::cl::list<std::string, bool, llvm::cl::SearchDirParser> ArgSearchDirList(
- "L",
- llvm::cl::ZeroOrMore,
- llvm::cl::desc("Add [searchdir] to the list of search paths"),
- llvm::cl::value_desc("searchdir"),
- llvm::cl::Prefix);
-
-llvm::cl::alias ArgSearchDirListAlias("library-path",
- llvm::cl::desc("alias for -L"),
- llvm::cl::aliasopt(ArgSearchDirList));
-
-llvm::cl::opt<bool> ArgNoStdlib(
- "nostdlib",
- llvm::cl::desc("Only search lib dirs explicitly specified on cmdline"),
- llvm::cl::init(false));
-
-llvm::cl::list<std::string, bool, llvm::cl::SearchDirParser> ArgRuntimePath(
- "rpath",
- llvm::cl::ZeroOrMore,
- llvm::cl::desc("Add a directory to the runtime library search path"),
- llvm::cl::value_desc("dir"));
-
-llvm::cl::alias ArgRuntimePathAlias("R",
- llvm::cl::desc("alias for --rpath"),
- llvm::cl::aliasopt(ArgRuntimePath),
- llvm::cl::Prefix);
-
-// Not supported yet {
-llvm::cl::list<std::string, bool, llvm::cl::SearchDirParser> ArgRuntimePathLink(
- "rpath-link",
- llvm::cl::ZeroOrMore,
- llvm::cl::desc("Add a directory to the link time library search path"),
- llvm::cl::value_desc("dir"));
-
-llvm::cl::list<std::string> ArgY(
- "Y",
- llvm::cl::desc("Add path to the default library search path"),
- llvm::cl::value_desc("default-search-path"));
-// } Not supported yet
-
-} // anonymous namespace
-
-using namespace mcld;
-
-//===----------------------------------------------------------------------===//
-// SearchPathOptions
-//===----------------------------------------------------------------------===//
-SearchPathOptions::SearchPathOptions()
- : m_SysRoot(ArgSysRoot),
- m_SearchDirList(ArgSearchDirList),
- m_NoStdlib(ArgNoStdlib),
- m_RuntimePath(ArgRuntimePath),
- m_RuntimePathLink(ArgRuntimePathLink),
- m_Y(ArgY) {
-}
-
-bool SearchPathOptions::parse(LinkerConfig& pConfig, LinkerScript& pScript) {
- // set --sysroot
- if (!m_SysRoot.empty()) {
- if (exists(m_SysRoot) && is_directory(m_SysRoot))
- pScript.setSysroot(m_SysRoot);
- }
-
- // set -L[path]
- llvm::cl::list<std::string>::iterator sd;
- llvm::cl::list<std::string>::iterator sdEnd = m_SearchDirList.end();
- for (sd = m_SearchDirList.begin(); sd != sdEnd; ++sd) {
- if (!pScript.directories().insert(*sd)) {
- // FIXME: need a warning function
- errs() << "WARNING: can not open search directory `-L" << *sd << "'.\n";
- }
- }
-
- // set -no-stdlib
- pConfig.options().setNoStdlib(m_NoStdlib);
-
- // set --rpath [path]
- llvm::cl::list<std::string>::iterator rp;
- llvm::cl::list<std::string>::iterator rpEnd = m_RuntimePath.end();
- for (rp = m_RuntimePath.begin(); rp != rpEnd; ++rp) {
- pConfig.options().getRpathList().push_back(*rp);
- }
-
- return true;
-}
diff --git a/tools/mcld/lib/SymbolOptions.cpp b/tools/mcld/lib/SymbolOptions.cpp
deleted file mode 100644
index 389aa12..0000000
--- a/tools/mcld/lib/SymbolOptions.cpp
+++ /dev/null
@@ -1,76 +0,0 @@
-//===- SymbolOptions.cpp --------------------------------------------------===//
-//
-// The MCLinker Project
-//
-// This file is distributed under the University of Illinois Open Source
-// License. See LICENSE.TXT for details.
-//
-//===----------------------------------------------------------------------===//
-#include <mcld/SymbolOptions.h>
-#include <mcld/LinkerConfig.h>
-
-namespace {
-
-// Not supprted yet {
-llvm::cl::list<std::string> ArgForceUndefined(
- "u",
- llvm::cl::ZeroOrMore,
- llvm::cl::desc("Force symbol to be undefined in the output file"),
- llvm::cl::value_desc("symbol"));
-
-llvm::cl::alias ArgForceUndefinedAlias("undefined",
- llvm::cl::ZeroOrMore,
- llvm::cl::desc("alias for -u"),
- llvm::cl::aliasopt(ArgForceUndefined));
-
-llvm::cl::opt<std::string> ArgVersionScript(
- "version-script",
- llvm::cl::desc("Version script."),
- llvm::cl::value_desc("Version script"));
-
-llvm::cl::opt<bool> ArgWarnCommon("warn-common",
- llvm::cl::desc("warn common symbol"),
- llvm::cl::init(false));
-
-llvm::cl::opt<bool> ArgDefineCommon("d",
- llvm::cl::ZeroOrMore,
- llvm::cl::desc("Define common symbol"),
- llvm::cl::init(false));
-
-llvm::cl::alias ArgDefineCommonAlias1("dc",
- llvm::cl::ZeroOrMore,
- llvm::cl::desc("alias for -d"),
- llvm::cl::aliasopt(ArgDefineCommon));
-
-llvm::cl::alias ArgDefineCommonAlias2("dp",
- llvm::cl::ZeroOrMore,
- llvm::cl::desc("alias for -d"),
- llvm::cl::aliasopt(ArgDefineCommon));
-
-// } Not supported yet
-
-} // anonymous namespace
-
-using namespace mcld;
-
-//===----------------------------------------------------------------------===//
-// SymbolOptions
-//===----------------------------------------------------------------------===//
-SymbolOptions::SymbolOptions()
- : m_ForceUndefined(ArgForceUndefined),
- m_VersionScript(ArgVersionScript),
- m_WarnCommon(ArgWarnCommon),
- m_DefineCommon(ArgDefineCommon) {
-}
-
-bool SymbolOptions::parse(LinkerConfig& pConfig) {
- // set -d
- pConfig.options().setDefineCommon(m_DefineCommon);
-
- // set -u/--undefined symbols
- llvm::cl::list<std::string>::iterator usym, usymEnd = m_ForceUndefined.end();
- for (usym = m_ForceUndefined.begin(); usym != usymEnd; ++usym)
- pConfig.options().getUndefSymList().push_back(*usym);
-
- return true;
-}
diff --git a/tools/mcld/lib/TargetControlOptions.cpp b/tools/mcld/lib/TargetControlOptions.cpp
deleted file mode 100644
index 365bafd..0000000
--- a/tools/mcld/lib/TargetControlOptions.cpp
+++ /dev/null
@@ -1,90 +0,0 @@
-//===- TargetControlOptions.cpp -------------------------------------------===//
-//
-// The MCLinker Project
-//
-// This file is distributed under the University of Illinois Open Source
-// License. See LICENSE.TXT for details.
-//
-//===----------------------------------------------------------------------===//
-#include <mcld/TargetControlOptions.h>
-#include <mcld/LinkerConfig.h>
-#include <mcld/Support/MsgHandling.h>
-
-namespace {
-
-llvm::cl::opt<int> ArgGPSize(
- "G",
- llvm::cl::desc("Set the maximum size of objects to be optimized using GP"),
- llvm::cl::init(8));
-
-llvm::cl::opt<bool> ArgWarnSharedTextrel(
- "warn-shared-textrel",
- llvm::cl::ZeroOrMore,
- llvm::cl::desc("Warn if adding DT_TEXTREL in a shared object."),
- llvm::cl::init(false));
-
-// Not supported yet {
-llvm::cl::opt<bool> ArgFIXCA8(
- "fix-cortex-a8",
- llvm::cl::desc("Enable Cortex-A8 Thumb-2 branch erratum fix"),
- llvm::cl::init(false));
-
-llvm::cl::opt<bool> ArgFixCA53Erratum835769(
- "fix-cortex-a53-835769",
- llvm::cl::desc("Enable Cortex-CA53 Erratum 835769 fix"),
- llvm::cl::init(false));
-
-llvm::cl::opt<bool> ArgEB(
- "EB",
- llvm::cl::desc("Link big-endian objects. This affects the output format."),
- llvm::cl::init(false));
-
-llvm::cl::opt<bool> ArgEL(
- "EL",
- llvm::cl::desc(
- "Link little-endian objects. This affects the output format."),
- llvm::cl::init(false));
-
-llvm::cl::opt<bool> ArgSVR4Compatibility(
- "Qy",
- llvm::cl::desc("This option is ignored for SVR4 compatibility"),
- llvm::cl::init(false));
-
-// } Not supported yet
-
-} // anonymous namespace
-
-using namespace mcld;
-
-//===----------------------------------------------------------------------===//
-// TargetControlOptions
-//===----------------------------------------------------------------------===//
-TargetControlOptions::TargetControlOptions()
- : m_GPSize(ArgGPSize),
- m_WarnSharedTextrel(ArgWarnSharedTextrel),
- m_FIXCA8(ArgFIXCA8),
- m_FIXCA53Erratum835769(ArgFixCA53Erratum835769),
- m_EB(ArgEB),
- m_EL(ArgEL),
- m_SVR4Compatibility(ArgSVR4Compatibility) {
-}
-
-bool TargetControlOptions::parse(LinkerConfig& pConfig) {
- // set -G [size]
- pConfig.options().setGPSize(m_GPSize);
-
- // set --warn-shared-textrel
- pConfig.options().setWarnSharedTextrel(m_WarnSharedTextrel);
-
- // set --fix-cortex-a8
- if (m_FIXCA8)
- mcld::warning(mcld::diag::warn_unsupported_option) << m_FIXCA8.ArgStr;
-
- // set --fix-cortex-a53-835769
- if (m_FIXCA53Erratum835769) {
- mcld::warning(mcld::diag::warn_unsupported_option)
- << m_FIXCA53Erratum835769.ArgStr;
- }
-
- return true;
-}
diff --git a/tools/mcld/lib/TripleOptions.cpp b/tools/mcld/lib/TripleOptions.cpp
deleted file mode 100644
index d4217c6..0000000
--- a/tools/mcld/lib/TripleOptions.cpp
+++ /dev/null
@@ -1,147 +0,0 @@
-//===- TripleOptions.cpp --------------------------------------------------===//
-//
-// The MCLinker Project
-//
-// This file is distributed under the University of Illinois Open Source
-// License. See LICENSE.TXT for details.
-//
-//===----------------------------------------------------------------------===//
-#include <mcld/TripleOptions.h>
-
-#include <mcld/LinkerConfig.h>
-#include <mcld/Support/Path.h>
-#include <mcld/Support/TargetRegistry.h>
-#include <mcld/Support/MsgHandling.h>
-#include <mcld/Support/SystemUtils.h>
-
-#include <llvm/ADT/StringSwitch.h>
-
-namespace {
-
-llvm::cl::opt<std::string> ArgTargetTriple(
- "mtriple",
- llvm::cl::desc("Override target triple for module"));
-
-llvm::cl::opt<std::string> ArgMArch(
- "march",
- llvm::cl::desc("Architecture to generate code for (see --version)"));
-
-llvm::cl::opt<std::string> ArgMCPU(
- "mcpu",
- llvm::cl::desc("Target a specific cpu type (-mcpu=help for details)"),
- llvm::cl::value_desc("cpu-name"),
- llvm::cl::init(""));
-
-llvm::cl::opt<std::string> ArgEmulation(
- "m",
- llvm::cl::ZeroOrMore,
- llvm::cl::desc("Set GNU linker emulation"),
- llvm::cl::value_desc("emulation"),
- llvm::cl::Prefix);
-
-/// ParseProgName - Parse program name
-/// This function simplifies cross-compiling by reading triple from the program
-/// name. For example, if the program name is `arm-linux-eabi-ld.mcld', we can
-/// get the triple is arm-linux-eabi by the program name.
-inline std::string ParseProgName(const char* pProgName) {
- static const char* suffixes[] = {"ld", "ld.mcld"};
-
- std::string ProgName(mcld::sys::fs::Path(pProgName).stem().native());
-
- for (size_t i = 0; i < sizeof(suffixes) / sizeof(suffixes[0]); ++i) {
- if (ProgName == suffixes[i])
- return std::string();
- }
-
- llvm::StringRef ProgNameRef(ProgName);
- llvm::StringRef Prefix;
-
- for (size_t i = 0; i < sizeof(suffixes) / sizeof(suffixes[0]); ++i) {
- if (!ProgNameRef.endswith(suffixes[i]))
- continue;
-
- llvm::StringRef::size_type LastComponent =
- ProgNameRef.rfind('-', ProgNameRef.size() - strlen(suffixes[i]));
- if (LastComponent == llvm::StringRef::npos)
- continue;
- llvm::StringRef Prefix = ProgNameRef.slice(0, LastComponent);
- std::string IgnoredError;
- if (!mcld::TargetRegistry::lookupTarget(Prefix, IgnoredError))
- continue;
- return Prefix.str();
- }
- return std::string();
-}
-
-inline void ParseEmulation(llvm::Triple& pTriple,
- const std::string& pEmulation) {
- llvm::Triple triple =
- llvm::StringSwitch<llvm::Triple>(pEmulation)
- .Case("aarch64linux", llvm::Triple("aarch64", "", "linux", "gnu"))
- .Case("armelf_linux_eabi",
- llvm::Triple("arm", "", "linux", "gnueabi"))
- .Case("elf_i386", llvm::Triple("i386", "", "", "gnu"))
- .Case("elf_x86_64", llvm::Triple("x86_64", "", "", "gnu"))
- .Case("elf32_x86_64", llvm::Triple("x86_64", "", "", "gnux32"))
- .Case("elf_i386_fbsd", llvm::Triple("i386", "", "freebsd", "gnu"))
- .Case("elf_x86_64_fbsd", llvm::Triple("x86_64", "", "freebsd", "gnu"))
- .Case("elf32ltsmip", llvm::Triple("mipsel", "", "", "gnu"))
- .Case("elf64ltsmip", llvm::Triple("mips64el", "", "", "gnu"))
- .Default(llvm::Triple());
-
- if (triple.getArch() == llvm::Triple::UnknownArch &&
- triple.getOS() == llvm::Triple::UnknownOS &&
- triple.getEnvironment() == llvm::Triple::UnknownEnvironment)
- mcld::error(mcld::diag::err_invalid_emulation) << pEmulation << "\n";
-
- if (triple.getArch() != llvm::Triple::UnknownArch)
- pTriple.setArch(triple.getArch());
-
- if (triple.getOS() != llvm::Triple::UnknownOS)
- pTriple.setOS(triple.getOS());
-
- if (triple.getEnvironment() != llvm::Triple::UnknownEnvironment)
- pTriple.setEnvironment(triple.getEnvironment());
-}
-
-} // anonymous namespace
-
-using namespace mcld;
-
-//===----------------------------------------------------------------------===//
-// TripleOptions
-//===----------------------------------------------------------------------===//
-TripleOptions::TripleOptions()
- : m_TargetTriple(ArgTargetTriple),
- m_MArch(ArgMArch),
- m_MCPU(ArgMCPU),
- m_Emulation(ArgEmulation) {
-}
-
-bool TripleOptions::parse(int pArgc, char* pArgv[], LinkerConfig& pConfig) {
- llvm::Triple triple;
- if (!m_TargetTriple.empty()) {
- // 1. Use the triple from command.
- triple.setTriple(m_TargetTriple);
- } else {
- std::string prog_triple = ParseProgName(pArgv[0]);
- if (!prog_triple.empty()) {
- // 2. Use the triple from the program name prefix.
- triple.setTriple(prog_triple);
- } else {
- // 3. Use the default target triple.
- triple.setTriple(mcld::sys::getDefaultTargetTriple());
- }
- }
-
- // If a specific emulation was requested, apply it now.
- if (!m_Emulation.empty())
- ParseEmulation(triple, m_Emulation);
- else
- pConfig.targets().setArch(m_MArch);
-
- pConfig.targets().setTriple(triple);
- pConfig.targets().setTargetCPU(m_MCPU);
-
- return true;
-}
diff --git a/tools/mcld/main.cpp b/tools/mcld/main.cpp
deleted file mode 100644
index 68900ba..0000000
--- a/tools/mcld/main.cpp
+++ /dev/null
@@ -1,164 +0,0 @@
-//===- main.cpp -----------------------------------------------------------===//
-//
-// The MCLinker Project
-//
-// This file is distributed under the University of Illinois Open Source
-// License. See LICENSE.TXT for details.
-//
-//===----------------------------------------------------------------------===//
-#include <mcld/PreferenceOptions.h>
-#include <mcld/TripleOptions.h>
-#include <mcld/DynamicSectionOptions.h>
-#include <mcld/OutputFormatOptions.h>
-#include <mcld/SearchPathOptions.h>
-#include <mcld/OptimizationOptions.h>
-#include <mcld/SymbolOptions.h>
-#include <mcld/TargetControlOptions.h>
-#include <mcld/ScriptOptions.h>
-#include <mcld/PositionalOptions.h>
-
-#include <mcld/Module.h>
-#include <mcld/Environment.h>
-#include <mcld/LinkerConfig.h>
-#include <mcld/LinkerScript.h>
-#include <mcld/Linker.h>
-#include <mcld/IRBuilder.h>
-#include <mcld/MC/InputAction.h>
-#include <mcld/Support/raw_ostream.h>
-#include <mcld/Support/MsgHandling.h>
-#include <llvm/Support/ManagedStatic.h>
-#include <llvm/Support/Signals.h>
-#include <string>
-#include <cassert>
-#include <cstdlib>
-
-/// configure linker
-static inline bool ConfigLinker(
- int pArgc,
- char* pArgv[],
- const char* pName,
- mcld::Module& pModule,
- mcld::LinkerScript& pScript,
- mcld::LinkerConfig& pConfig,
- mcld::IRBuilder& pBuilder,
- std::vector<mcld::InputAction*>& pInputActions) {
- mcld::PreferenceOptions preference;
- mcld::TripleOptions triple;
- mcld::DynamicSectionOptions dynamic_section;
- mcld::OutputFormatOptions output_format;
- mcld::SearchPathOptions search_path;
- mcld::OptimizationOptions optimization;
- mcld::SymbolOptions symbol;
- mcld::TargetControlOptions target_control;
- mcld::ScriptOptions script;
- mcld::PositionalOptions positional;
-
- llvm::cl::ParseCommandLineOptions(pArgc, pArgv, pName);
-
- if (!preference.parse(pConfig))
- return false;
-
- if (!triple.parse(pArgc, pArgv, pConfig))
- return false;
-
- if (!dynamic_section.parse(pConfig, pScript))
- return false;
-
- if (!output_format.parse(pModule, pConfig))
- return false;
-
- if (!search_path.parse(pConfig, pScript))
- return false;
-
- if (!optimization.parse(pConfig))
- return false;
-
- if (!symbol.parse(pConfig))
- return false;
-
- if (!target_control.parse(pConfig))
- return false;
-
- if (!script.parse(pScript))
- return false;
-
- if (!positional.parse(pInputActions, pConfig, pScript))
- return false;
-
- if (pConfig.options().soname().empty())
- pConfig.options().setSOName(pModule.name());
-
- return true;
-}
-
-static inline bool InitializeInputs(
- mcld::IRBuilder& pBuilder,
- std::vector<mcld::InputAction*>& pInputActions) {
- for (
- std::vector<mcld::InputAction*>::iterator action = pInputActions.begin(),
- actionEnd = pInputActions.end();
- action != actionEnd;
- ++action) {
- assert(*action != NULL);
- (*action)->activate(pBuilder.getInputBuilder());
- delete *action;
- }
-
- if (pBuilder.getInputBuilder().isInGroup()) {
- mcld::fatal(mcld::diag::fatal_forbid_nest_group);
- return false;
- }
-
- return true;
-}
-
-int main(int argc, char* argv[]) {
- llvm::sys::PrintStackTraceOnErrorSignal();
- llvm::llvm_shutdown_obj Y; // Call llvm_shutdown() on exit.
- mcld::Initialize();
-
- mcld::LinkerScript script;
- mcld::LinkerConfig config;
- mcld::Module module(script);
- mcld::IRBuilder builder(module, config);
- std::vector<mcld::InputAction*> input_actions;
-
- if (!ConfigLinker(argc,
- argv,
- "MCLinker\n",
- module,
- script,
- config,
- builder,
- input_actions)) {
- mcld::errs() << argv[0]
- << ": failed to process linker options from command line!\n";
- return EXIT_FAILURE;
- }
-
- mcld::Linker linker;
- if (!linker.emulate(script, config)) {
- mcld::errs() << argv[0] << ": failed to emulate target!\n";
- return EXIT_FAILURE;
- }
-
- // FIXME: is it possible to have a lightweight MCLinker pass?
- if (!InitializeInputs(builder, input_actions)) {
- mcld::errs() << argv[0] << ": failed to initialize input tree!\n";
- return EXIT_FAILURE;
- }
-
- if (!linker.link(module, builder)) {
- mcld::errs() << argv[0] << ": failed to link objects!\n";
- return EXIT_FAILURE;
- }
-
- if (!linker.emit(module, module.name())) {
- mcld::errs() << argv[0] << ": failed to emit output!\n";
- return EXIT_FAILURE;
- }
-
- mcld::Finalize();
-
- return EXIT_SUCCESS;
-}
diff --git a/unittests/DirIteratorTest.cpp b/unittests/DirIteratorTest.cpp
index 2684466..cc440ca 100644
--- a/unittests/DirIteratorTest.cpp
+++ b/unittests/DirIteratorTest.cpp
@@ -49,8 +49,10 @@
size_t size = 0;
while (entry != enEnd) {
- if (0 != entry.path())
+ if (0 != entry.path()) {
size = entry.path()->native().size();
+ ASSERT_TRUE(size != 0);
+ }
++entry;
}
diff --git a/unittests/HashTableTest.cpp b/unittests/HashTableTest.cpp
index 595b1e1..695ccb8 100644
--- a/unittests/HashTableTest.cpp
+++ b/unittests/HashTableTest.cpp
@@ -67,9 +67,7 @@
HashTableTy* hashTable = new HashTableTy(0);
bool exist;
- HashTableTy::entry_type* entry = 0;
-
- entry = hashTable->insert(pA, exist);
+ hashTable->insert(pA, exist);
EXPECT_FALSE(hashTable->empty());
@@ -135,9 +133,8 @@
HashTableTy* hashTable = new HashTableTy(0);
bool exist;
- HashTableTy::entry_type* entry = 0;
for (unsigned int key = 0; key < 100; ++key)
- entry = hashTable->insert(key, exist);
+ hashTable->insert(key, exist);
EXPECT_FALSE(hashTable->empty());
@@ -161,9 +158,8 @@
HashTableTy* hashTable = new HashTableTy(22);
bool exist;
- HashTableTy::entry_type* entry = 0;
for (unsigned int key = 0; key < 100; ++key) {
- entry = hashTable->insert(key, exist);
+ hashTable->insert(key, exist);
}
hashTable->clear();
@@ -185,9 +181,8 @@
HashTableTy* hashTable = new HashTableTy();
bool exist;
- HashTableTy::entry_type* entry = 0;
for (unsigned int key = 0; key < 100; ++key) {
- entry = hashTable->insert(key, exist);
+ hashTable->insert(key, exist);
}
EXPECT_FALSE(hashTable->empty());
@@ -207,7 +202,7 @@
}
for (unsigned int key = 0; key < 20; ++key) {
- entry = hashTable->insert(key, exist);
+ hashTable->insert(key, exist);
}
EXPECT_TRUE(100 == hashTable->numOfEntries());
EXPECT_TRUE(197 == hashTable->numOfBuckets());