Skip to content

Instantly share code, notes, and snippets.

@mszoek
Created April 3, 2022 21:10
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save mszoek/f5a84355b8649ead9f07b2bc71d1cfa4 to your computer and use it in GitHub Desktop.
Save mszoek/f5a84355b8649ead9f07b2bc71d1cfa4 to your computer and use it in GitHub Desktop.
LLVM patches for ELF Framework bundles on FreeBSD
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