Index: ELF/#Driver.cpp# =================================================================== --- /dev/null +++ ELF/#Driver.cpp# @@ -0,0 +1,190 @@ +//===- Driver.cpp ---------------------------------------------------------===// +// +// The LLVM Linker +// +// This file is distributed under the University of Illinois Open Source +// License. See LICENSE.TXT for details. +// +//===----------------------------------------------------------------------===// + +#include "Driver.h" +#include "Config.h" +#include "Error.h" +#include "InputFiles.h" +#include "SymbolTable.h" +#include "Writer.h" +#include "llvm/ADT/STLExtras.h" +#include "llvm/ADT/StringExtras.h" +#include "llvm/Support/FileSystem.h" +#include "llvm/Support/Path.h" + +using namespace llvm; +using namespace llvm::ELF; + +using namespace lld; +using namespace lld::elf2; + +Configuration *lld::elf2::Config; +LinkerDriver *lld::elf2::Driver; + +void lld::elf2::link(ArrayRef Args) { + Configuration C; + LinkerDriver D; + Config = &C; + Driver = &D; + Driver->link(Args.slice(1)); +} + +static void setELFType(StringRef Emul) { + if (Emul == "elf_i386") { + Config->ElfKind = ELF32LEKind; + Config->EMachine = EM_386; + return; + } + if (Emul == "elf_x86_64") { + Config->ElfKind = ELF64LEKind; + Config->EMachine = EM_X86_64; + return; + } + if (Emul == "elf32ppc") { + Config->ElfKind = ELF32BEKind; + Config->EMachine = EM_PPC; + return; + } + if (Emul == "elf64ppc") { + Config->ElfKind = ELF64BEKind; + Config->EMachine = EM_PPC64; + return; + } + error(Twine("Unknown emulation: ") + Emul); +} + +// Makes a path by concatenating Dir and File. +// If Dir starts with '=' the result will be preceded by Sysroot, +// which can be set with --sysroot command line switch. +static std::string buildSysrootedPath(StringRef Dir, StringRef File) { + SmallString<128> Path; + if (Dir.startswith("=")) + sys::path::append(Path, Config->Sysroot, Dir.substr(1), File); + else + sys::path::append(Path, Dir, File); + return Path.str().str(); +} + +// Searches a given library from input search paths, which are filled +// from -L command line switches. Returns a path to an existent library file. +static std::string searchLibrary(StringRef Path) { + std::vector Names; + if (Path[0] == ':') { + Names.push_back(Path.drop_front().str()); + } else { + if (!Config->Static) + Names.push_back((Twine("lib") + Path + ".so").str()); + Names.push_back((Twine("lib") + Path + ".a").str()); + } + for (StringRef Dir : Config->InputSearchPaths) { + for (const std::string &Name : Names) { + std::string FullPath = buildSysrootedPath(Dir, Name); + if (sys::fs::exists(FullPath)) + return FullPath; + } + } + error(Twine("Unable to find library -l") + Path); +} + +template