Created
April 3, 2022 21:10
-
-
Save mszoek/f5a84355b8649ead9f07b2bc71d1cfa4 to your computer and use it in GitHub Desktop.
LLVM patches for ELF Framework bundles on FreeBSD
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
diff --git a/contrib/llvm-project/clang/include/clang/Driver/Options.td b/contrib/llvm-project/clang/include/clang/Driver/Options.td | |
index a0cbcae0bdc3..a5ef948450c3 100644 | |
--- a/contrib/llvm-project/clang/include/clang/Driver/Options.td | |
+++ b/contrib/llvm-project/clang/include/clang/Driver/Options.td | |
@@ -634,7 +634,7 @@ def D : JoinedOrSeparate<["-"], "D">, Group<Preprocessor_Group>, | |
HelpText<"Define <macro> to <value> (or 1 if <value> omitted)">; | |
def E : Flag<["-"], "E">, Flags<[NoXarchOption,CC1Option, FlangOption, FC1Option]>, Group<Action_Group>, | |
HelpText<"Only run the preprocessor">; | |
-def F : JoinedOrSeparate<["-"], "F">, Flags<[RenderJoined,CC1Option]>, | |
+def F : JoinedOrSeparate<["-"], "F">, Flags<[RenderJoined,CC1Option,LinkerInput]>, | |
HelpText<"Add directory to framework include search path">; | |
def G : JoinedOrSeparate<["-"], "G">, Flags<[NoXarchOption]>, Group<m_Group>, | |
MetaVarName<"<size>">, HelpText<"Put objects of at most <size> bytes " | |
diff --git a/contrib/llvm-project/clang/lib/Basic/ObjCRuntime.cpp b/contrib/llvm-project/clang/lib/Basic/ObjCRuntime.cpp | |
index cfc437409b5d..1f803e090339 100644 | |
--- a/contrib/llvm-project/clang/lib/Basic/ObjCRuntime.cpp | |
+++ b/contrib/llvm-project/clang/lib/Basic/ObjCRuntime.cpp | |
@@ -72,7 +72,7 @@ bool ObjCRuntime::tryParse(StringRef input) { | |
} else if (runtimeName == "gnustep") { | |
// If no version is specified then default to the most recent one that we | |
// know about. | |
- Version = VersionTuple(1, 6); | |
+ Version = VersionTuple(2, 0); | |
kind = ObjCRuntime::GNUstep; | |
} else if (runtimeName == "gcc") { | |
kind = ObjCRuntime::GCC; | |
diff --git a/contrib/llvm-project/clang/lib/Basic/Targets/OSTargets.h b/contrib/llvm-project/clang/lib/Basic/Targets/OSTargets.h | |
index 3fe39ed64d9c..97ef94bdc90b 100644 | |
--- a/contrib/llvm-project/clang/lib/Basic/Targets/OSTargets.h | |
+++ b/contrib/llvm-project/clang/lib/Basic/Targets/OSTargets.h | |
@@ -218,6 +218,8 @@ | |
@@ -6984,7 +6984,7 @@ ObjCRuntime Clang::AddObjCRuntimeArgs(const ArgList &args, | |
objcABIVersion = 1 + nonFragileABIVersion; | |
} else { | |
- objcABIVersion = 1; | |
+ objcABIVersion = 3; | |
} | |
} | |
diff --git a/contrib/llvm-project/clang/lib/Driver/ToolChains/FreeBSD.cpp b/contrib/llvm-project/clang/lib/Driver/ToolChains/FreeBSD.cpp | |
index 5dcf74dabf4f..94a11cb60f2b 100644 | |
--- a/contrib/llvm-project/clang/lib/Driver/ToolChains/FreeBSD.cpp | |
+++ b/contrib/llvm-project/clang/lib/Driver/ToolChains/FreeBSD.cpp | |
@@ -12,6 +12,7 @@ | |
#include "Arch/Sparc.h" | |
#include "CommonArgs.h" | |
#include "clang/Driver/Compilation.h" | |
+#include "clang/Driver/Driver.h" | |
#include "clang/Driver/DriverDiagnostic.h" | |
#include "clang/Driver/Options.h" | |
#include "clang/Driver/SanitizerArgs.h" | |
@@ -247,6 +248,27 @@ void freebsd::Linker::ConstructJob(Compilation &C, const JobAction &JA, | |
assert(Output.isNothing() && "Invalid output."); | |
} | |
+ CmdArgs.push_back("-F"); | |
+ CmdArgs.push_back("/System/Library/Frameworks"); | |
+ CmdArgs.push_back("-F"); | |
+ CmdArgs.push_back("/Library/Frameworks"); | |
+ | |
+ Driver::InputList PPInputs; | |
+ D.BuildInputs(C.getDefaultToolChain(), C.getArgs(), PPInputs); | |
+ | |
+ // Auto | |
if (!Args.hasArg(options::OPT_nostdlib, options::OPT_nostartfiles)) { | |
const char *crt1 = nullptr; | |
if (!Args.hasArg(options::OPT_shared)) { | |
@@ -281,7 +303,7 @@ void freebsd::Linker::ConstructJob(Compilation &C, const JobAction &JA, | |
Args.AddAllArgs(CmdArgs, options::OPT_t); | |
Args.AddAllArgs(CmdArgs, options::OPT_Z_Flag); | |
Args.AddAllArgs(CmdArgs, options::OPT_r); | |
- | |
+ | |
if (D.isUsingLTO()) { | |
assert(!Inputs.empty() && "Must have at least one input."); | |
addLTOOptions(ToolChain, Args, CmdArgs, Output, Inputs[0], | |
diff --git a/contrib/llvm-project/clang/lib/Frontend/InitHeaderSearch.cpp b/contrib/llvm-project/clang/lib/Frontend/InitHeaderSearch.cpp | |
index ba9f96384f81..5aa10c20e716 100644 | |
--- a/contrib/llvm-project/clang/lib/Frontend/InitHeaderSearch.cpp | |
+++ b/contrib/llvm-project/clang/lib/Frontend/InitHeaderSearch.cpp | |
@@ -447,14 +447,14 @@ void InitHeaderSearch::AddDefaultIncludePaths(const LangOptions &Lang, | |
} | |
// All header search logic is handled in the Driver for Darwin. | |
- if (triple.isOSDarwin()) { | |
+ //if (triple.isOSDarwin()) { | |
if (HSOpts.UseStandardSystemIncludes) { | |
// Add the default framework include paths on Darwin. | |
AddPath("/System/Library/Frameworks", System, true); | |
AddPath("/Library/Frameworks", System, true); | |
} | |
- return; | |
- } | |
+ //return; | |
+ //} | |
if (Lang.CPlusPlus && !Lang.AsmPreprocessor && | |
HSOpts.UseStandardCXXIncludes && HSOpts.UseS | |
} | |
uptr internal_rename(const char *oldpath, const char *newpath) { | |
-#if defined(__riscv) | |
+#if defined(__riscv) && defined(__linux__) | |
return internal_syscall(SYSCALL(renameat2), AT_FDCWD, (uptr)oldpath, AT_FDCWD, | |
(uptr)newpath, 0); | |
#elif SANITIZER_USES_CANONICAL_LINUX_SYSCALLS | |
@@ -1218,7 +1218,8 @@ void ForEachMappedRegion(link_map *map, void (*cb)(const void *, uptr)) { | |
} | |
#endif | |
-#if defined(__x86_64__) && SANITIZER_LINUX | |
+#if SANITIZER_LINUX | |
+#if defined(__x86_64__) | |
// We cannot use glibc's clone wrapper, because it messes with the child | |
// task's TLS. It writes the PID and TID of the child task to its thread | |
// descriptor, but in our case the child task shares the thread descriptor with | |
diff --git a/contrib/llvm-project/lld/ELF/Config.h b/contrib/llvm-project/lld/ELF/Config.h | |
index e1abb4dfab36..64ac9d0a766b 100644 | |
--- a/contrib/llvm-project/lld/ELF/Config.h | |
+++ b/contrib/llvm-project/lld/ELF/Config.h | |
@@ -135,6 +135,8 @@ struct Configuration { | |
std::vector<llvm::StringRef> auxiliaryList; | |
std::vector<llvm::StringRef> filterList; | |
std::vector<llvm::StringRef> searchPaths; | |
+ std::vector<llvm::StringRef> frameworkSearchPaths; | |
+ std::vector<std::string> frameworkRunPaths; | |
std::vector<llvm::StringRef> symbolOrderingFile; | |
std::vector<llvm::StringRef> thinLTOModulesToCompile; | |
std::vector<llvm::StringRef> undefined; | |
@@ -199,6 +201,7 @@ struct Configuration { | |
bool optRemarksWithHotness; | |
bool picThunk; | |
bool pie; | |
+ bool preservePath; | |
bool printGcSections; | |
bool printIcfSections; | |
bool relocatable; | |
diff --git a/contrib/llvm-project/lld/ELF/Driver.cpp b/contrib/llvm-project/lld/ELF/Driver.cpp | |
index 594c20016827..33d346a346ea 100644 | |
--- a/contrib/llvm-project/lld/ELF/Driver.cpp | |
+++ b/contrib/llvm-project/lld/ELF/Driver.cpp | |
@@ -62,6 +62,7 @@ | |
#include "llvm/Support/raw_ostream.h" | |
#include <cstdlib> | |
#include <utility> | |
+#include <unistd.h> // readlink | |
using namespace llvm; | |
using namespace llvm::ELF; | |
@@ -272,8 +273,12 @@ void LinkerDriver::addFile(StringRef path, bool withLOption) { | |
// If a file was speci | |
} | |
+// Add all libraries within a framework found on the framework search path | |
+void LinkerDriver::addFramework(StringRef name) { | |
+ if (Optional<std::string> path = searchFramework(name)) { | |
+ path->append("/Versions/"); | |
+ | |
+ std::string rpath(path.getValue()); | |
+ | |
+ path->append("Current"); | |
+ config->searchPaths.push_back(path.getValue()); | |
+ | |
+ char buffer[_POSIX_PATH_MAX]; | |
+ int count = ::readlink(path.getValue().c_str(), buffer, sizeof(buffer)); | |
+ if(count > 0) | |
+ rpath.append(buffer, buffer + count); | |
+ else | |
+ rpath.append("Current"); | |
+ | |
+ // handle frameworks relative to executable (in the app bundle) | |
+ if(llvm::sys::path::is_relative(Twine(rpath))) { | |
+ std::string opath("$ORIGIN"); | |
+ opath.append("/"); | |
+ opath.append(rpath); | |
+ rpath = opath; | |
+ } | |
+ config->frameworkRunPaths.push_back(rpath); | |
+ | |
+ // Now that we've added the current version folder of the framework, find | |
+ // all the shared libs inside it and add them to the link | |
+ std::error_code EC; | |
+ llvm::sys::fs::directory_iterator Dir = llvm::sys::fs::directory_iterator(Twine(path.getValue()), EC, true); | |
+ llvm::sys::fs::directory_iterator DirEnd; | |
+ for(Dir; Dir != DirEnd && !EC; Dir.increment(EC)) { | |
+ i | |
config->filterList = args::getStrings(args, OPT_filter); | |
config->fini = args.getLastArgValue(OPT_fini, "_fini"); | |
+ config->frameworkSearchPaths = args::getStrings(args, OPT_F); | |
config->fixCortexA53Errata843419 = args.hasArg(OPT_fix_cortex_a53_843419) && | |
!args.hasArg(OPT_relocatable); | |
config->fixCortexA8 = | |
@@ -1484,6 +1531,9 @@ void LinkerDriver::createFiles(opt::InputArgList &args) { | |
case OPT_library: | |
addLibrary(arg->getValue()); | |
break; | |
+ case OPT_framework: | |
+ addFramework(arg->getValue()); | |
+ break; | |
case OPT_INPUT: | |
addFile(arg->getValue(), /*withLOption=*/false); | |
break; | |
@@ -1571,6 +1621,9 @@ void LinkerDriver::createFiles(opt::InputArgList &args) { | |
std::tie(config->asNeeded, config->isStatic, inWholeArchive) = stack.back(); | |
stack.pop_back(); | |
break; | |
+ case OPT_preserve_path: | |
+ config->preservePath = true; | |
+ break; | |
} | |
} | |
diff --git a/contrib/llvm-project/lld/ELF/Driver.h b/contrib/llvm-project/lld/ELF/Driver.h | |
index 96d040041c5a..edc985b3d76c 100644 | |
--- a/contrib/llvm-project/lld/ELF/Driver.h | |
+++ b/contrib/llvm-project/lld/ELF/Driver.h | |
@@ -29,6 +29,7 @@ class LinkerDriver { | |
void linkerMain(ArrayRef<const char *> args); | |
void addFile(StringRef path, bool withLOption); | |
void addLibrary(StringRef name); | |
+ void addFramework(StringRef name); | |
} // namespace lld | |
diff --git a/contrib/llvm-project/lld/ELF/DriverUtils.cpp b/contrib/llvm-project/lld/ELF/DriverUtils.cpp | |
index f49deb9012b2..b2444c82cafe 100644 | |
--- a/contrib/llvm-project/lld/ELF/DriverUtils.cpp | |
+++ b/contrib/llvm-project/lld/ELF/DriverUtils.cpp | |
@@ -251,6 +251,14 @@ Optional<std::string> elf::searchLibrary(StringRef name) { | |
return searchLibraryBaseName(name); | |
} | |
+Optional<std::string> elf::searchFramework(StringRef name) { | |
+ for (StringRef dir : config->frameworkSearchPaths) { | |
+ if (Optional<std::string> s = findFile(dir, name + ".framework")) | |
+ return s; | |
+ } | |
+ return None; | |
+} | |
+ | |
// If a linker/version script doesn't exist in the current directory, we also | |
// look for the script in the '-L' search paths. This matches the behaviour of | |
// '-T', --version-script=, and linker script INPUT() command in ld.bfd. | |
diff --git a/contrib/llvm-project/lld/ELF/InputFiles.cpp b/contrib/llvm-project/lld/ELF/InputFiles.cpp | |
index d5b9efbe18fc..0a031fd6cebc 100644 | |
--- a/contrib/llvm-project/lld/ELF/InputFiles.cpp | |
+++ b/contrib/llvm-project/lld/ELF/InputFiles.cpp | |
@@ -1491,7 +1491,8 @@ template <class ELFT> void SharedFile::parse() { | |
uint64_t val = dyn.getVal(); | |
if (val >= this->stringTable.size()) | |
fatal(toString(this) + ": invalid DT_SONAME entry"); | |
- soName = this->stringTable.data() + val; | |
+ if(!config->preservePath) | |
+ soName = this->stringTable.data() + val; | |
} | |
} | |
diff --git a/contrib/llvm-project/lld/ELF/Options.td b/contri | |
index f0e4c11b79eb..24ba51d39228 100644 | |
--- a/contrib/llvm-project/lld/ELF/Options.td | |
+++ b/contrib/llvm-project/lld/ELF/Options.td | |
@@ -52,6 +52,16 @@ def Bstatic: F<"Bstatic">, HelpText<"Do not link against shared libraries">; | |
def build_id: F<"build-id">, HelpText<"Alias for --build-id=fast">; | |
+def F : JoinedOrSeparate<["-"], "F">, | |
+ MetaVarName<"<dir>">, | |
+ HelpText<"Add directory to framework search path">; | |
+ | |
+def framework : Separate<["-"], "framework">, | |
+ MetaVarName<"<name>">, | |
+ HelpText<"Base name of framework searched for in -F directories">; | |
+ | |
+def preserve_path : FF<"preserve-path">, HelpText<"Preserve full path of DSOs">; | |
+ | |
def build_id_eq: J<"build-id=">, HelpText<"Generate build ID note">, | |
MetaVarName<"[fast,md5,sha1,uuid,0x<hexstring>]">; | |
@@ -516,7 +526,7 @@ def: Flag<["-"], "q">, Alias<emit_relocs>, HelpText<"Alias for --emit-relocs">; | |
def: Flag<["-"], ")">, Alias<end_group>, HelpText<"Alias for --end-group">; | |
def: JoinedOrSeparate<["-"], "e">, Alias<entry>, HelpText<"Alias for --entry">; | |
def: Flag<["-"], "E">, Alias<export_dynamic>, HelpText<"Alias for --export-dynamic">; | |
-def: Separate<["-"], "F">, Alias<filter>, HelpText<"Alias for --filter">; | |
+//def: Separate<["-"], "F">, Alias<filter>, HelpText<"Alias for --filter">; | |
def: Separate<["-"], "b">, Alias<format>, HelpText<"Alias for --format">; | |
def: JoinedOrSeparate<["-"], "l">, Alias<library>, HelpText<"Alias for --library">; | |
def: JoinedOrSeparate<["-"], "L">, Alias<library_path>, HelpText<"Alias for --library-path">; | |
diff --git a/contrib/llvm-project/lld/ELF/SyntheticSections.cpp b/contrib/llvm-project/lld/ELF/SyntheticSections.cpp | |
index 187b2ac90c21..b43e4463b228 100644 | |
--- a/contrib/llvm-project/lld/ELF/SyntheticSections.cpp | |
+++ b/contrib/llvm-project/lld/ELF/SyntheticSections.cpp | |
@@ -1336,6 +1336,14 @@ template <class ELFT> void DynamicSection<ELFT>::finalizeContents() { | |
for (StringRef s : config->auxiliaryList) | |
addInt(DT_AUXILIARY, part.dynStrTab->addString(s)); | |
+ if (!config->frameworkRunPaths.empty()) { | |
+ std::string s(llvm::join(config->frameworkRunPaths.begin(),config->frameworkRunPaths.end(),":")); | |
+ if(config->rpath.empty()) | |
+ config->rpath = s; | |
+ else | |
+ config->rpath.append(":" + s); | |
+ } | |
+ | |
if (!config->rpath.empty()) | |
addInt(config->enableNewDtags ? DT_RUNPATH : DT_RPATH, | |
part.dynStrTab->addString(config->rpath)); |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment