ld64: init at 951.9
This commit is contained in:
parent
cdf968c68d
commit
f02b50ba18
181
pkgs/by-name/ld/ld64/0004-Use-std-atomics-and-std-mutex.patch
Normal file
181
pkgs/by-name/ld/ld64/0004-Use-std-atomics-and-std-mutex.patch
Normal file
@ -0,0 +1,181 @@
|
||||
From 5e92d65ef2b5cc07dc25b5b1bf645b314599f5d1 Mon Sep 17 00:00:00 2001
|
||||
From: Randy Eckenrode <randy@largeandhighquality.com>
|
||||
Date: Sat, 6 Apr 2024 20:29:25 -0400
|
||||
Subject: [PATCH 4/8] Use std::atomics and std::mutex
|
||||
|
||||
---
|
||||
src/ld/InputFiles.cpp | 13 ++++++-------
|
||||
src/ld/InputFiles.h | 9 +++++----
|
||||
src/ld/OutputFile.cpp | 13 ++++++-------
|
||||
src/ld/ld.cpp | 11 +++++------
|
||||
4 files changed, 22 insertions(+), 24 deletions(-)
|
||||
|
||||
diff --git a/src/ld/InputFiles.cpp b/src/ld/InputFiles.cpp
|
||||
index ec53a60..427ab09 100644
|
||||
--- a/src/ld/InputFiles.cpp
|
||||
+++ b/src/ld/InputFiles.cpp
|
||||
@@ -42,7 +42,6 @@
|
||||
#include <mach-o/dyld.h>
|
||||
#include <mach-o/fat.h>
|
||||
#include <sys/sysctl.h>
|
||||
-#include <libkern/OSAtomic.h>
|
||||
#if HAVE_LIBDISPATCH
|
||||
#include <dispatch/dispatch.h>
|
||||
#endif
|
||||
@@ -387,16 +386,16 @@ ld::File* InputFiles::makeFile(const Options::FileInfo& info, bool indirectDylib
|
||||
|
||||
ld::relocatable::File* objResult = mach_o::relocatable::parse(p, len, info.path, info.modTime, info.ordinal, objOpts);
|
||||
if ( objResult != NULL ) {
|
||||
- OSAtomicAdd64(len, &_totalObjectSize);
|
||||
- OSAtomicIncrement32(&_totalObjectLoaded);
|
||||
+ _totalObjectSize += len;
|
||||
+ ++_totalObjectLoaded;
|
||||
return objResult;
|
||||
}
|
||||
|
||||
// see if it is an llvm object file
|
||||
objResult = lto::parse(p, len, info.path, info.modTime, info.ordinal, _options.architecture(), _options.subArchitecture(), _options.logAllFiles(), _options.verboseOptimizationHints());
|
||||
if ( objResult != NULL ) {
|
||||
- OSAtomicAdd64(len, &_totalObjectSize);
|
||||
- OSAtomicIncrement32(&_totalObjectLoaded);
|
||||
+ _totalObjectSize += len;
|
||||
+ ++_totalObjectLoaded;
|
||||
return objResult;
|
||||
}
|
||||
|
||||
@@ -444,8 +443,8 @@ ld::File* InputFiles::makeFile(const Options::FileInfo& info, bool indirectDylib
|
||||
ld::archive::File* archiveResult = ::archive::parse(p, len, info.path, info.modTime, info.ordinal, archOpts);
|
||||
if ( archiveResult != NULL ) {
|
||||
|
||||
- OSAtomicAdd64(len, &_totalArchiveSize);
|
||||
- OSAtomicIncrement32(&_totalArchivesLoaded);
|
||||
+ _totalArchiveSize += len;
|
||||
+ ++_totalArchivesLoaded;
|
||||
return archiveResult;
|
||||
}
|
||||
|
||||
diff --git a/src/ld/InputFiles.h b/src/ld/InputFiles.h
|
||||
index c18ccf8..ffff26b 100644
|
||||
--- a/src/ld/InputFiles.h
|
||||
+++ b/src/ld/InputFiles.h
|
||||
@@ -46,6 +46,7 @@
|
||||
#include <pthread.h>
|
||||
#endif
|
||||
|
||||
+#include <atomic>
|
||||
#include <vector>
|
||||
|
||||
#include "Options.h"
|
||||
@@ -78,10 +79,10 @@ public:
|
||||
size_t count() const { return _inputFiles.size(); }
|
||||
|
||||
// for -print_statistics
|
||||
- volatile int64_t _totalObjectSize;
|
||||
- volatile int64_t _totalArchiveSize;
|
||||
- volatile int32_t _totalObjectLoaded;
|
||||
- volatile int32_t _totalArchivesLoaded;
|
||||
+ std::atomic<int64_t> _totalObjectSize;
|
||||
+ std::atomic<int64_t> _totalArchiveSize;
|
||||
+ std::atomic<int32_t> _totalObjectLoaded;
|
||||
+ std::atomic<int32_t> _totalArchivesLoaded;
|
||||
int32_t _totalDylibsLoaded;
|
||||
|
||||
|
||||
diff --git a/src/ld/OutputFile.cpp b/src/ld/OutputFile.cpp
|
||||
index e2c0397..15912a2 100644
|
||||
--- a/src/ld/OutputFile.cpp
|
||||
+++ b/src/ld/OutputFile.cpp
|
||||
@@ -43,11 +43,10 @@
|
||||
#include <mach-o/dyld.h>
|
||||
#include <mach-o/fat.h>
|
||||
#include <dispatch/dispatch.h>
|
||||
-#include <os/lock_private.h>
|
||||
extern "C" {
|
||||
#include <corecrypto/ccsha2.h>
|
||||
}
|
||||
-#include <string>
|
||||
+#include <mutex>
|
||||
#include <string>
|
||||
#include <list>
|
||||
#include <algorithm>
|
||||
@@ -1362,7 +1361,7 @@ void OutputFile::rangeCheckRISCVBranch20(int64_t displacement, ld::Internal& sta
|
||||
|
||||
|
||||
#if SUPPORT_ARCH_arm64e
|
||||
-static os_lock_unfair_s sAuthenticatedFixupDataLock = OS_LOCK_UNFAIR_INIT; // to serialize building of _authenticatedFixupData
|
||||
+static std::mutex sAuthenticatedFixupDataLock; // to serialize building of _authenticatedFixupData
|
||||
#endif
|
||||
|
||||
void OutputFile::applyFixUps(ld::Internal& state, uint64_t mhAddress, const ld::Atom* atom, uint8_t* buffer)
|
||||
@@ -1737,11 +1736,11 @@ void OutputFile::applyFixUps(ld::Internal& state, uint64_t mhAddress, const ld::
|
||||
}
|
||||
else {
|
||||
auto fixupOffset = (uintptr_t)(fixUpLocation - mhAddress);
|
||||
- os_lock_lock(&sAuthenticatedFixupDataLock);
|
||||
+ sAuthenticatedFixupDataLock.lock();
|
||||
assert(_authenticatedFixupData.find(fixupOffset) == _authenticatedFixupData.end());
|
||||
auto authneticatedData = std::make_pair(authData, accumulator);
|
||||
_authenticatedFixupData[fixupOffset] = authneticatedData;
|
||||
- os_lock_unlock(&sAuthenticatedFixupDataLock);
|
||||
+ sAuthenticatedFixupDataLock.unlock();
|
||||
// Zero out this entry which we will expect later.
|
||||
set64LE(fixUpLocation, 0);
|
||||
}
|
||||
@@ -1768,11 +1767,11 @@ void OutputFile::applyFixUps(ld::Internal& state, uint64_t mhAddress, const ld::
|
||||
}
|
||||
else {
|
||||
auto fixupOffset = (uintptr_t)(fixUpLocation - mhAddress);
|
||||
- os_lock_lock(&sAuthenticatedFixupDataLock);
|
||||
+ sAuthenticatedFixupDataLock.lock();
|
||||
assert(_authenticatedFixupData.find(fixupOffset) == _authenticatedFixupData.end());
|
||||
auto authneticatedData = std::make_pair(authData, accumulator);
|
||||
_authenticatedFixupData[fixupOffset] = authneticatedData;
|
||||
- os_lock_unlock(&sAuthenticatedFixupDataLock);
|
||||
+ sAuthenticatedFixupDataLock.unlock();
|
||||
// Zero out this entry which we will expect later.
|
||||
set64LE(fixUpLocation, 0);
|
||||
}
|
||||
diff --git a/src/ld/ld.cpp b/src/ld/ld.cpp
|
||||
index b7590a3..f1bf9df 100644
|
||||
--- a/src/ld/ld.cpp
|
||||
+++ b/src/ld/ld.cpp
|
||||
@@ -47,9 +47,8 @@ extern "C" double log2 ( double );
|
||||
#include <mach-o/dyld.h>
|
||||
#include <dlfcn.h>
|
||||
#include <AvailabilityMacros.h>
|
||||
-#include <os/lock_private.h>
|
||||
|
||||
-#include <string>
|
||||
+#include <mutex>
|
||||
#include <map>
|
||||
#include <set>
|
||||
#include <string>
|
||||
@@ -1603,8 +1602,8 @@ int main(int argc, const char* argv[])
|
||||
statistics.vmEnd.faults-statistics.vmStart.faults);
|
||||
fprintf(stderr, "memory active: %lu, wired: %lu\n", statistics.vmEnd.active_count * vm_page_size, statistics.vmEnd.wire_count * vm_page_size);
|
||||
char temp[40];
|
||||
- fprintf(stderr, "processed %3u object files, totaling %15s bytes\n", inputFiles._totalObjectLoaded, commatize(inputFiles._totalObjectSize, temp));
|
||||
- fprintf(stderr, "processed %3u archive files, totaling %15s bytes\n", inputFiles._totalArchivesLoaded, commatize(inputFiles._totalArchiveSize, temp));
|
||||
+ fprintf(stderr, "processed %3u object files, totaling %15s bytes\n", inputFiles._totalObjectLoaded.load(), commatize(inputFiles._totalObjectSize.load(), temp));
|
||||
+ fprintf(stderr, "processed %3u archive files, totaling %15s bytes\n", inputFiles._totalArchivesLoaded.load(), commatize(inputFiles._totalArchiveSize.load(), temp));
|
||||
fprintf(stderr, "processed %3u dylib files\n", inputFiles._totalDylibsLoaded);
|
||||
fprintf(stderr, "wrote output file totaling %15s bytes\n", commatize(out.fileSize(), temp));
|
||||
}
|
||||
@@ -1634,12 +1633,12 @@ int main(int argc, const char* argv[])
|
||||
#ifndef NDEBUG
|
||||
|
||||
// now that the linker is multi-threaded, only allow one assert() to be processed
|
||||
-static os_lock_unfair_s sAssertLock = OS_LOCK_UNFAIR_INIT;
|
||||
+static std::mutex sAssertLock;
|
||||
|
||||
// implement assert() function to print out a backtrace before aborting
|
||||
void __assert_rtn(const char* func, const char* file, int line, const char* failedexpr)
|
||||
{
|
||||
- os_lock_lock(&sAssertLock);
|
||||
+ sAssertLock.lock();
|
||||
|
||||
Snapshot *snapshot = Snapshot::globalSnapshot;
|
||||
|
||||
--
|
||||
2.45.1
|
||||
|
48
pkgs/by-name/ld/ld64/0005-Support-LTO-in-nixpkgs.patch
Normal file
48
pkgs/by-name/ld/ld64/0005-Support-LTO-in-nixpkgs.patch
Normal file
@ -0,0 +1,48 @@
|
||||
From faa5ab7c6e8d9a6c6157a2b681edad592ce78555 Mon Sep 17 00:00:00 2001
|
||||
From: Randy Eckenrode <randy@largeandhighquality.com>
|
||||
Date: Sun, 7 Apr 2024 15:33:36 -0400
|
||||
Subject: [PATCH 5/8] Support LTO in nixpkgs
|
||||
|
||||
---
|
||||
src/ld/InputFiles.cpp | 11 ++---------
|
||||
src/ld/parsers/lto_file.cpp | 2 +-
|
||||
2 files changed, 3 insertions(+), 10 deletions(-)
|
||||
|
||||
diff --git a/src/ld/InputFiles.cpp b/src/ld/InputFiles.cpp
|
||||
index 427ab09..b8a9870 100644
|
||||
--- a/src/ld/InputFiles.cpp
|
||||
+++ b/src/ld/InputFiles.cpp
|
||||
@@ -464,15 +464,8 @@ ld::File* InputFiles::makeFile(const Options::FileInfo& info, bool indirectDylib
|
||||
if ( _options.overridePathlibLTO() != NULL ) {
|
||||
libLTO = _options.overridePathlibLTO();
|
||||
}
|
||||
- else if ( _NSGetExecutablePath(ldPath, &bufSize) != -1 ) {
|
||||
- if ( realpath(ldPath, tmpPath) != NULL ) {
|
||||
- char* lastSlash = strrchr(tmpPath, '/');
|
||||
- if ( lastSlash != NULL )
|
||||
- strcpy(lastSlash, "/../lib/libLTO.dylib");
|
||||
- libLTO = tmpPath;
|
||||
- if ( realpath(tmpPath, libLTOPath) != NULL )
|
||||
- libLTO = libLTOPath;
|
||||
- }
|
||||
+ else {
|
||||
+ libLTO = "@libllvm@/lib/libLTO.dylib";
|
||||
}
|
||||
throwf("could not process llvm bitcode object file, because %s could not be loaded", libLTO);
|
||||
}
|
||||
diff --git a/src/ld/parsers/lto_file.cpp b/src/ld/parsers/lto_file.cpp
|
||||
index 5318212..e18e974 100644
|
||||
--- a/src/ld/parsers/lto_file.cpp
|
||||
+++ b/src/ld/parsers/lto_file.cpp
|
||||
@@ -1807,7 +1807,7 @@ bool optimize( const std::vector<const ld::Atom*>& allAtoms,
|
||||
|
||||
}; // namespace lto
|
||||
|
||||
-static const char *sLTODylib = "@rpath/libLTO.dylib";
|
||||
+static const char *sLTODylib = "@libllvm@/lib/libLTO.dylib";
|
||||
static std::atomic<bool> sLTOIsLoaded(false);
|
||||
|
||||
static void *getHandle() {
|
||||
--
|
||||
2.45.1
|
||||
|
@ -0,0 +1,113 @@
|
||||
From add8bae5577ebe1c98cf7a711f87a3578a51d313 Mon Sep 17 00:00:00 2001
|
||||
From: Randy Eckenrode <randy@largeandhighquality.com>
|
||||
Date: Mon, 8 Apr 2024 22:42:40 -0400
|
||||
Subject: [PATCH 6/8] Add libcd_is_blob_a_linker_signature implementation
|
||||
|
||||
---
|
||||
compat/libcodedirectory.c | 74 +++++++++++++++++++++++++++++++++++++++
|
||||
src/ld/libcodedirectory.h | 8 +++++
|
||||
2 files changed, 82 insertions(+)
|
||||
create mode 100644 compat/libcodedirectory.c
|
||||
|
||||
diff --git a/compat/libcodedirectory.c b/compat/libcodedirectory.c
|
||||
new file mode 100644
|
||||
index 0000000..e584dfc
|
||||
--- /dev/null
|
||||
+++ b/compat/libcodedirectory.c
|
||||
@@ -0,0 +1,74 @@
|
||||
+// SPDX-License-Identifier: APSL-2.0
|
||||
+// libcd_is_blob_a_linker_signature implementation written by Randy Eckenrode © 2024
|
||||
+
|
||||
+#include <libcodedirectory.h>
|
||||
+
|
||||
+#include <stdbool.h>
|
||||
+
|
||||
+// References:
|
||||
+// - https://forums.developer.apple.com/forums/thread/702351
|
||||
+// - https://redmaple.tech/blogs/macho-files/#codedirectory-blob
|
||||
+
|
||||
+static inline uint32_t read32be(const uint8_t* data)
|
||||
+{
|
||||
+ return (data[0] << 24) + (data[1] << 16) + (data[2] << 8) + data[3];
|
||||
+}
|
||||
+
|
||||
+static inline bool is_embedded_signature(uint32_t magic) {
|
||||
+ switch (magic) {
|
||||
+ case CSMAGIC_EMBEDDED_SIGNATURE:
|
||||
+ case CSMAGIC_EMBEDDED_SIGNATURE_OLD:
|
||||
+ return true;
|
||||
+ default:
|
||||
+ return false;
|
||||
+ }
|
||||
+}
|
||||
+
|
||||
+static inline const uint8_t* find_code_directory(const uint8_t* data, size_t size) {
|
||||
+ const uint8_t* index_ptr = data + offsetof(CS_SuperBlob, index);
|
||||
+
|
||||
+ // There also needs to be space for the actual blobs, but there must be at least enough space
|
||||
+ // for the blob indexes. If there’s not, then something’s wrong, and the blob is invalid.
|
||||
+ uint32_t count = read32be(data + offsetof(CS_SuperBlob, count));
|
||||
+ if (count > ((data + size) - index_ptr) / sizeof(CS_BlobIndex)) {
|
||||
+ return NULL;
|
||||
+ }
|
||||
+
|
||||
+ for (uint32_t n = 0; n < count; ++n) {
|
||||
+ const uint8_t* current_index_ptr = index_ptr + n * sizeof(CS_BlobIndex);
|
||||
+ uint32_t type = read32be(current_index_ptr + offsetof(CS_BlobIndex, type));
|
||||
+ if (type == CSSLOT_CODEDIRECTORY) {
|
||||
+ uint32_t offset = read32be(current_index_ptr + offsetof(CS_BlobIndex, offset));
|
||||
+ if (offset > size - sizeof(CS_CodeDirectory)) {
|
||||
+ return NULL;
|
||||
+ } else {
|
||||
+ return data + offset;
|
||||
+ }
|
||||
+ }
|
||||
+ }
|
||||
+ return NULL;
|
||||
+}
|
||||
+
|
||||
+enum libcd_signature_query_ret
|
||||
+libcd_is_blob_a_linker_signature(const uint8_t* data, size_t size, int* linker_signed)
|
||||
+{
|
||||
+ if (size < sizeof(CS_SuperBlob) + sizeof(CS_BlobIndex) + sizeof(CS_CodeDirectory)) {
|
||||
+ return LIBCD_SIGNATURE_QUERY_INVALID_ARGUMENT;
|
||||
+ }
|
||||
+
|
||||
+ if (!is_embedded_signature(read32be(data + offsetof(CS_SuperBlob, magic)))) {
|
||||
+ return LIBCD_SIGNATURE_QUERY_NOT_A_SIGNATURE;
|
||||
+ }
|
||||
+
|
||||
+ const uint8_t* cd = find_code_directory(data, size);
|
||||
+ if (!cd) {
|
||||
+ return LIBCD_SIGNATURE_QUERY_INVALID_ARGUMENT;
|
||||
+ }
|
||||
+
|
||||
+ uint32_t flags = read32be(cd + offsetof(CS_CodeDirectory, flags));
|
||||
+ if ((flags & CS_LINKER_SIGNED) == CS_LINKER_SIGNED) {
|
||||
+ *linker_signed = 1;
|
||||
+ }
|
||||
+
|
||||
+ return LIBCD_SIGNATURE_QUERY_SUCCESS;
|
||||
+}
|
||||
diff --git a/src/ld/libcodedirectory.h b/src/ld/libcodedirectory.h
|
||||
index 0e989a9..7532648 100644
|
||||
--- a/src/ld/libcodedirectory.h
|
||||
+++ b/src/ld/libcodedirectory.h
|
||||
@@ -116,6 +116,14 @@ enum libcd_set_linkage_ret {
|
||||
|
||||
enum libcd_set_linkage_ret libcd_set_linkage(libcd *s, int linkage_hash_type, uint8_t *linkage_hash);
|
||||
|
||||
+enum libcd_signature_query_ret {
|
||||
+ LIBCD_SIGNATURE_QUERY_SUCCESS,
|
||||
+ LIBCD_SIGNATURE_QUERY_INVALID_ARGUMENT,
|
||||
+ LIBCD_SIGNATURE_QUERY_NOT_A_SIGNATURE,
|
||||
+};
|
||||
+
|
||||
+enum libcd_signature_query_ret libcd_is_blob_a_linker_signature(const uint8_t* data, size_t size, int* linker_signed);
|
||||
+
|
||||
__END_DECLS
|
||||
|
||||
#endif // H_LIBCODEDIRECTORY
|
||||
--
|
||||
2.45.1
|
||||
|
@ -0,0 +1,311 @@
|
||||
From 36767c7345161baf0ab125f95c8557f8e24f25db Mon Sep 17 00:00:00 2001
|
||||
From: Randy Eckenrode <randy@largeandhighquality.com>
|
||||
Date: Tue, 9 Apr 2024 19:28:17 -0400
|
||||
Subject: [PATCH 7/8] Add OpenSSL-based CoreCrypto digest functions
|
||||
|
||||
---
|
||||
compat/CommonCrypto/CommonDigest.h | 6 +++
|
||||
compat/CommonCrypto/CommonDigestSPI.c | 21 +++++++++++
|
||||
compat/CommonCrypto/CommonDigestSPI.h | 14 +++++++
|
||||
compat/corecrypto/api_defines.h | 10 +++++
|
||||
compat/corecrypto/ccdigest.c | 53 +++++++++++++++++++++++++++
|
||||
compat/corecrypto/ccdigest.h | 27 ++++++++++++++
|
||||
compat/corecrypto/ccdigest_private.h | 19 ++++++++++
|
||||
compat/corecrypto/ccsha1.c | 22 +++++++++++
|
||||
compat/corecrypto/ccsha1.h | 9 +++++
|
||||
compat/corecrypto/ccsha2.c | 22 +++++++++++
|
||||
compat/corecrypto/ccsha2.h | 9 +++++
|
||||
11 files changed, 212 insertions(+)
|
||||
create mode 100644 compat/CommonCrypto/CommonDigest.h
|
||||
create mode 100644 compat/CommonCrypto/CommonDigestSPI.c
|
||||
create mode 100644 compat/CommonCrypto/CommonDigestSPI.h
|
||||
create mode 100644 compat/corecrypto/api_defines.h
|
||||
create mode 100644 compat/corecrypto/ccdigest.c
|
||||
create mode 100644 compat/corecrypto/ccdigest.h
|
||||
create mode 100644 compat/corecrypto/ccdigest_private.h
|
||||
create mode 100644 compat/corecrypto/ccsha1.c
|
||||
create mode 100644 compat/corecrypto/ccsha1.h
|
||||
create mode 100644 compat/corecrypto/ccsha2.c
|
||||
create mode 100644 compat/corecrypto/ccsha2.h
|
||||
|
||||
diff --git a/compat/CommonCrypto/CommonDigest.h b/compat/CommonCrypto/CommonDigest.h
|
||||
new file mode 100644
|
||||
index 0000000..a60eba7
|
||||
--- /dev/null
|
||||
+++ b/compat/CommonCrypto/CommonDigest.h
|
||||
@@ -0,0 +1,6 @@
|
||||
+// SPDX-License-Identifier: APSL-2.0
|
||||
+// CoreCrypto compatibility shims written by Randy Eckenrode © 2024
|
||||
+
|
||||
+#pragma once
|
||||
+
|
||||
+#define CCSHA256_OUTPUT_SIZE 32
|
||||
diff --git a/compat/CommonCrypto/CommonDigestSPI.c b/compat/CommonCrypto/CommonDigestSPI.c
|
||||
new file mode 100644
|
||||
index 0000000..41269fc
|
||||
--- /dev/null
|
||||
+++ b/compat/CommonCrypto/CommonDigestSPI.c
|
||||
@@ -0,0 +1,21 @@
|
||||
+// SPDX-License-Identifier: APSL-2.0
|
||||
+// CoreCrypto compatibility shims written by Randy Eckenrode © 2024
|
||||
+
|
||||
+#include "CommonDigestSPI.h"
|
||||
+
|
||||
+#include <stdlib.h>
|
||||
+#include <string.h>
|
||||
+
|
||||
+#include <corecrypto/ccsha2.h>
|
||||
+
|
||||
+void CCDigest(int type, const uint8_t* bytes, size_t count, uint8_t* digest) {
|
||||
+ if (type != kCCDigestSHA256) {
|
||||
+ abort();
|
||||
+ }
|
||||
+ const struct ccdigest_info* di = ccsha256_di();
|
||||
+
|
||||
+ ccdigest_di_decl(_di, ctx);
|
||||
+ ccdigest_init(di, ctx);
|
||||
+ ccdigest_update(di, ctx, count, bytes);
|
||||
+ ccdigest_final(di, ctx, digest);
|
||||
+}
|
||||
diff --git a/compat/CommonCrypto/CommonDigestSPI.h b/compat/CommonCrypto/CommonDigestSPI.h
|
||||
new file mode 100644
|
||||
index 0000000..172742a
|
||||
--- /dev/null
|
||||
+++ b/compat/CommonCrypto/CommonDigestSPI.h
|
||||
@@ -0,0 +1,14 @@
|
||||
+// SPDX-License-Identifier: APSL-2.0
|
||||
+// CoreCrypto compatibility shims written by Randy Eckenrode © 2024
|
||||
+
|
||||
+#pragma once
|
||||
+
|
||||
+#include <stdint.h>
|
||||
+
|
||||
+#include <corecrypto/ccdigest.h>
|
||||
+#include <cs_blobs.h>
|
||||
+
|
||||
+
|
||||
+#define kCCDigestSHA256 10
|
||||
+
|
||||
+EXTERN_C void CCDigest(int type, const uint8_t* bytes, size_t count, uint8_t* digest);
|
||||
diff --git a/compat/corecrypto/api_defines.h b/compat/corecrypto/api_defines.h
|
||||
new file mode 100644
|
||||
index 0000000..13d1e7a
|
||||
--- /dev/null
|
||||
+++ b/compat/corecrypto/api_defines.h
|
||||
@@ -0,0 +1,10 @@
|
||||
+// SPDX-License-Identifier: APSL-2.0
|
||||
+// CoreCrypto compatibility shims written by Randy Eckenrode © 2024
|
||||
+
|
||||
+#pragma once
|
||||
+
|
||||
+#ifdef __cplusplus
|
||||
+#define EXTERN_C extern "C"
|
||||
+#else
|
||||
+#define EXTERN_C
|
||||
+#endif
|
||||
diff --git a/compat/corecrypto/ccdigest.c b/compat/corecrypto/ccdigest.c
|
||||
new file mode 100644
|
||||
index 0000000..e29dcb8
|
||||
--- /dev/null
|
||||
+++ b/compat/corecrypto/ccdigest.c
|
||||
@@ -0,0 +1,53 @@
|
||||
+// SPDX-License-Identifier: APSL-2.0
|
||||
+// CoreCrypto compatibility shims written by Randy Eckenrode © 2024
|
||||
+
|
||||
+#include "ccdigest.h"
|
||||
+#include "ccdigest_private.h"
|
||||
+
|
||||
+#include <stdlib.h>
|
||||
+
|
||||
+#include <openssl/err.h>
|
||||
+
|
||||
+
|
||||
+struct ccdigest_context* _ccdigest_context_new(void)
|
||||
+{
|
||||
+ struct ccdigest_context* ctx = malloc(sizeof(struct ccdigest_context));
|
||||
+ ctx->context = EVP_MD_CTX_new();
|
||||
+ return ctx;
|
||||
+}
|
||||
+
|
||||
+struct ccdigest_info* _ccdigest_newprovider(const char* name)
|
||||
+{
|
||||
+ struct ccdigest_info* di = malloc(sizeof(struct ccdigest_info));
|
||||
+ di->provider = EVP_MD_fetch(NULL, name, NULL);
|
||||
+ return di;
|
||||
+}
|
||||
+
|
||||
+void ccdigest_init(const struct ccdigest_info* di, struct ccdigest_context* ctx)
|
||||
+{
|
||||
+ if (!EVP_DigestInit_ex2(ctx->context, di->provider, NULL)) {
|
||||
+ ERR_print_errors_fp(stderr);
|
||||
+ abort();
|
||||
+ }
|
||||
+}
|
||||
+
|
||||
+void ccdigest_update(
|
||||
+ const struct ccdigest_info* _di,
|
||||
+ struct ccdigest_context* ctx,
|
||||
+ size_t count,
|
||||
+ const void* bytes
|
||||
+)
|
||||
+{
|
||||
+ if (!EVP_DigestUpdate(ctx->context, bytes, count)) {
|
||||
+ ERR_print_errors_fp(stderr);
|
||||
+ abort();
|
||||
+ }
|
||||
+}
|
||||
+
|
||||
+void ccdigest_final(const struct ccdigest_info* _di, struct ccdigest_context* ctx, uint8_t* digest)
|
||||
+{
|
||||
+ if (!EVP_DigestFinal_ex(ctx->context, digest, NULL)) {
|
||||
+ ERR_print_errors_fp(stderr);
|
||||
+ abort();
|
||||
+ }
|
||||
+}
|
||||
diff --git a/compat/corecrypto/ccdigest.h b/compat/corecrypto/ccdigest.h
|
||||
new file mode 100644
|
||||
index 0000000..9af2394
|
||||
--- /dev/null
|
||||
+++ b/compat/corecrypto/ccdigest.h
|
||||
@@ -0,0 +1,27 @@
|
||||
+// SPDX-License-Identifier: APSL-2.0
|
||||
+// CoreCrypto compatibility shims written by Randy Eckenrode © 2024
|
||||
+
|
||||
+#pragma once
|
||||
+
|
||||
+#include <stddef.h>
|
||||
+#include <stdint.h>
|
||||
+
|
||||
+#include "api_defines.h"
|
||||
+
|
||||
+
|
||||
+struct ccdigest_info;
|
||||
+struct ccdigest_context;
|
||||
+
|
||||
+EXTERN_C struct ccdigest_context* _ccdigest_context_new(void);
|
||||
+
|
||||
+#define ccdigest_di_decl(_di, ctxvar) \
|
||||
+ struct ccdigest_context* (ctxvar) = _ccdigest_context_new()
|
||||
+
|
||||
+EXTERN_C void ccdigest_init(const struct ccdigest_info* di, struct ccdigest_context* ctx);
|
||||
+EXTERN_C void ccdigest_update(
|
||||
+ const struct ccdigest_info* _di,
|
||||
+ struct ccdigest_context* ctx,
|
||||
+ size_t count,
|
||||
+ const void* bytes
|
||||
+);
|
||||
+EXTERN_C void ccdigest_final(const struct ccdigest_info* _di, struct ccdigest_context* ctx, uint8_t* digest);
|
||||
diff --git a/compat/corecrypto/ccdigest_private.h b/compat/corecrypto/ccdigest_private.h
|
||||
new file mode 100644
|
||||
index 0000000..0ea9759
|
||||
--- /dev/null
|
||||
+++ b/compat/corecrypto/ccdigest_private.h
|
||||
@@ -0,0 +1,19 @@
|
||||
+// SPDX-License-Identifier: APSL-2.0
|
||||
+// CoreCrypto compatibility shims written by Randy Eckenrode © 2024
|
||||
+
|
||||
+#pragma once
|
||||
+
|
||||
+#include "api_defines.h"
|
||||
+
|
||||
+#include <openssl/evp.h>
|
||||
+
|
||||
+
|
||||
+struct ccdigest_info {
|
||||
+ EVP_MD* provider;
|
||||
+};
|
||||
+
|
||||
+struct ccdigest_context {
|
||||
+ EVP_MD_CTX* context;
|
||||
+};
|
||||
+
|
||||
+EXTERN_C struct ccdigest_info* _ccdigest_newprovider(const char* name);
|
||||
diff --git a/compat/corecrypto/ccsha1.c b/compat/corecrypto/ccsha1.c
|
||||
new file mode 100644
|
||||
index 0000000..e02b2b6
|
||||
--- /dev/null
|
||||
+++ b/compat/corecrypto/ccsha1.c
|
||||
@@ -0,0 +1,22 @@
|
||||
+// SPDX-License-Identifier: APSL-2.0
|
||||
+// CoreCrypto compatibility shims written by Randy Eckenrode © 2024
|
||||
+
|
||||
+#include "ccsha1.h"
|
||||
+
|
||||
+#include <assert.h>
|
||||
+
|
||||
+#include <cs_blobs.h>
|
||||
+
|
||||
+#include "ccdigest_private.h"
|
||||
+
|
||||
+
|
||||
+static struct ccdigest_info* di = NULL;
|
||||
+
|
||||
+const struct ccdigest_info* ccsha1_di(void)
|
||||
+{
|
||||
+ if (!di) {
|
||||
+ di = _ccdigest_newprovider("SHA-1");
|
||||
+ assert(EVP_MD_get_size(di->provider) == CS_SHA1_LEN);
|
||||
+ }
|
||||
+ return di;
|
||||
+}
|
||||
diff --git a/compat/corecrypto/ccsha1.h b/compat/corecrypto/ccsha1.h
|
||||
new file mode 100644
|
||||
index 0000000..8e3f85f
|
||||
--- /dev/null
|
||||
+++ b/compat/corecrypto/ccsha1.h
|
||||
@@ -0,0 +1,9 @@
|
||||
+// SPDX-License-Identifier: APSL-2.0
|
||||
+// CoreCrypto compatibility shims written by Randy Eckenrode © 2024
|
||||
+
|
||||
+#pragma once
|
||||
+
|
||||
+#include <corecrypto/ccdigest.h>
|
||||
+
|
||||
+
|
||||
+EXTERN_C const struct ccdigest_info* ccsha1_di(void);
|
||||
diff --git a/compat/corecrypto/ccsha2.c b/compat/corecrypto/ccsha2.c
|
||||
new file mode 100644
|
||||
index 0000000..6504503
|
||||
--- /dev/null
|
||||
+++ b/compat/corecrypto/ccsha2.c
|
||||
@@ -0,0 +1,22 @@
|
||||
+// SPDX-License-Identifier: APSL-2.0
|
||||
+// CoreCrypto compatibility shims written by Randy Eckenrode © 2024
|
||||
+
|
||||
+#include "ccsha2.h"
|
||||
+
|
||||
+#include <assert.h>
|
||||
+
|
||||
+#include <cs_blobs.h>
|
||||
+
|
||||
+#include "ccdigest_private.h"
|
||||
+
|
||||
+
|
||||
+static struct ccdigest_info* di = NULL;
|
||||
+
|
||||
+const struct ccdigest_info* ccsha256_di(void)
|
||||
+{
|
||||
+ if (!di) {
|
||||
+ di = _ccdigest_newprovider("SHA-256");
|
||||
+ assert(EVP_MD_get_size(di->provider) == CS_SHA256_LEN);
|
||||
+ }
|
||||
+ return di;
|
||||
+}
|
||||
diff --git a/compat/corecrypto/ccsha2.h b/compat/corecrypto/ccsha2.h
|
||||
new file mode 100644
|
||||
index 0000000..9f30e03
|
||||
--- /dev/null
|
||||
+++ b/compat/corecrypto/ccsha2.h
|
||||
@@ -0,0 +1,9 @@
|
||||
+// SPDX-License-Identifier: APSL-2.0
|
||||
+// CoreCrypto compatibility shims written by Randy Eckenrode © 2024
|
||||
+
|
||||
+#pragma once
|
||||
+
|
||||
+#include <corecrypto/ccdigest.h>
|
||||
+
|
||||
+
|
||||
+EXTERN_C const struct ccdigest_info* ccsha256_di(void);
|
||||
--
|
||||
2.45.1
|
||||
|
@ -0,0 +1,25 @@
|
||||
From 3e80d438e2a3ec50d666f2b6e32007c275d4a08a Mon Sep 17 00:00:00 2001
|
||||
From: Randy Eckenrode <randy@largeandhighquality.com>
|
||||
Date: Thu, 11 Apr 2024 23:13:29 -0400
|
||||
Subject: [PATCH 8/8] Disable searching in standard library locations
|
||||
|
||||
---
|
||||
src/ld/Options.cpp | 2 +-
|
||||
1 file changed, 1 insertion(+), 1 deletion(-)
|
||||
|
||||
diff --git a/src/ld/Options.cpp b/src/ld/Options.cpp
|
||||
index 67a9f53..611b583 100644
|
||||
--- a/src/ld/Options.cpp
|
||||
+++ b/src/ld/Options.cpp
|
||||
@@ -4320,7 +4320,7 @@ bool Options::shouldUseBuildVersion(ld::Platform plat, uint32_t minOSvers) const
|
||||
|
||||
void Options::buildSearchPaths(int argc, const char* argv[])
|
||||
{
|
||||
- bool addStandardLibraryDirectories = true;
|
||||
+ bool addStandardLibraryDirectories = false;
|
||||
ld::Platform platform = ld::Platform::unknown;
|
||||
std::vector<const char*> libraryPaths;
|
||||
std::vector<const char*> frameworkPaths;
|
||||
--
|
||||
2.45.1
|
||||
|
8
pkgs/by-name/ld/ld64/gen_compile_stubs.py
Normal file
8
pkgs/by-name/ld/ld64/gen_compile_stubs.py
Normal file
@ -0,0 +1,8 @@
|
||||
#!/usr/bin/env python
|
||||
import sys
|
||||
from pathlib import Path
|
||||
|
||||
byteseq = (str(int(x)) for x in Path(sys.argv[1]).read_bytes())
|
||||
|
||||
print("#pragma once")
|
||||
print(f"static const char compile_stubs[] = {{ {', '.join(byteseq)} }};")
|
249
pkgs/by-name/ld/ld64/meson.build
Normal file
249
pkgs/by-name/ld/ld64/meson.build
Normal file
@ -0,0 +1,249 @@
|
||||
# Build settings based on the upstream Xcode project.
|
||||
# See: https://github.com/apple-oss-distributions/ld64/blob/main/ld64.xcodeproj/project.pbxproj
|
||||
|
||||
# Project settings
|
||||
project(
|
||||
'ld64',
|
||||
'c', 'cpp',
|
||||
version : '@version@',
|
||||
default_options : {'cpp_std': 'c++20'},
|
||||
)
|
||||
|
||||
fs = import('fs')
|
||||
|
||||
# Options
|
||||
target_prefix = get_option('target_prefix')
|
||||
|
||||
|
||||
# Dependencies
|
||||
cc = meson.get_compiler('c')
|
||||
cxx = meson.get_compiler('cpp')
|
||||
python = find_program('python3')
|
||||
|
||||
libtapi = cxx.find_library('tapi')
|
||||
openssl = dependency('openssl', version : '>=3.0')
|
||||
xar = cc.find_library('xar')
|
||||
|
||||
|
||||
# Feature tests
|
||||
|
||||
# macOS 10.12 does not support `DISPATCH_APPLY_AUTO`. Fortunately, `DISPATCH_APPLY_CURRENT_ROOT_QUEUE` has the
|
||||
# same value and was repurposed in subsequent releases as `DISPATCH_APPLY_AUTO`.
|
||||
dispatch_apply_auto_test = '''
|
||||
#include <dispatch/dispatch.h>
|
||||
int main(int argc, char* argv[]) {
|
||||
dispatch_queue_t queue = DISPATCH_APPLY_AUTO;
|
||||
return 0;
|
||||
}
|
||||
'''
|
||||
if not cc.compiles(
|
||||
dispatch_apply_auto_test,
|
||||
args : '-Wno-unused-command-line-argument',
|
||||
name : 'supports DISPATCH_APPLY_AUTO',
|
||||
)
|
||||
add_project_arguments(
|
||||
'-include', 'dispatch/private.h',
|
||||
'-DDISPATCH_APPLY_AUTO=DISPATCH_APPLY_CURRENT_ROOT_QUEUE',
|
||||
'-DPRIVATE', # The required API is private on the 10.12 SDK.
|
||||
language: ['c', 'cpp'],
|
||||
)
|
||||
endif
|
||||
|
||||
# The return type of `dispatch_get_global_queue` was changed in 10.14.
|
||||
# Use the older type if the SDK does not support it.
|
||||
dispatch_queue_global_test = '''
|
||||
#include <dispatch/dispatch.h>
|
||||
int main(int argc, char* argv[]) {
|
||||
dispatch_queue_global_t queue = dispatch_get_global_queue(QOS_CLASS_USER_INITIATED, 0);
|
||||
return 0;
|
||||
}
|
||||
'''
|
||||
if not cc.compiles(
|
||||
dispatch_queue_global_test,
|
||||
args : '-Wno-unused-command-line-argument',
|
||||
name : 'supports dispatch_queue_global_t',
|
||||
)
|
||||
add_project_arguments('-Ddispatch_queue_global_t=dispatch_queue_t', language : ['c', 'cpp'])
|
||||
endif
|
||||
|
||||
|
||||
# Generated files
|
||||
|
||||
compile_stubs_h = custom_target(
|
||||
'compile_stubs.h',
|
||||
capture : true,
|
||||
command : [python, '@INPUT0@', '@INPUT1@'],
|
||||
input : ['gen_compile_stubs.py', 'compile_stubs'],
|
||||
output : ['compile_stubs.h'],
|
||||
)
|
||||
|
||||
configure_h = custom_target(
|
||||
'configure_h',
|
||||
command : ['bash', '@INPUT@'],
|
||||
env : {
|
||||
'DERIVED_FILE_DIR' : meson.current_build_dir(),
|
||||
'RC_ProjectSourceVersion': '@version@'
|
||||
},
|
||||
input : ['src/create_configure'],
|
||||
output : ['configure.h'],
|
||||
)
|
||||
|
||||
incdirs = include_directories(
|
||||
'compat',
|
||||
'include',
|
||||
'src/abstraction',
|
||||
'src/ld',
|
||||
'src/ld/code-sign-blobs',
|
||||
'src/ld/parsers',
|
||||
'src/ld/passes',
|
||||
'src/mach_o',
|
||||
)
|
||||
|
||||
# Dynamic libraries
|
||||
libcodedirectory = library(
|
||||
'codedirectory',
|
||||
dependencies : [openssl],
|
||||
include_directories : incdirs,
|
||||
install : true,
|
||||
sources : [
|
||||
'compat/corecrypto/ccdigest.c',
|
||||
'compat/corecrypto/ccsha1.c',
|
||||
'compat/corecrypto/ccsha2.c',
|
||||
'compat/libcodedirectory.c',
|
||||
'src/ld/libcodedirectory.c'
|
||||
],
|
||||
soversion : 1,
|
||||
)
|
||||
install_headers(
|
||||
'src/ld/cs_blobs.h',
|
||||
'src/ld/libcodedirectory.h',
|
||||
)
|
||||
|
||||
|
||||
# Static libraries
|
||||
libprunetrie = static_library(
|
||||
'prunetrie',
|
||||
include_directories : incdirs,
|
||||
install : true,
|
||||
override_options : {'b_lto': false},
|
||||
sources : [
|
||||
'src/mach_o/Error.cpp',
|
||||
'src/mach_o/ExportsTrie.cpp',
|
||||
'src/other/PruneTrie.cpp',
|
||||
],
|
||||
)
|
||||
install_headers(
|
||||
'src/other/prune_trie.h',
|
||||
subdir : 'mach-o',
|
||||
)
|
||||
|
||||
|
||||
# Binaries
|
||||
ld64 = executable(
|
||||
f'@target_prefix@ld',
|
||||
dependencies : [libtapi, openssl, xar],
|
||||
include_directories : incdirs,
|
||||
install : true,
|
||||
# These linker flags mirror those used in a release build of the Xcode project.
|
||||
# See: https://github.com/apple-oss-distributions/ld64/blob/47f477cb721755419018f7530038b272e9d0cdea/ld64.xcodeproj/project.pbxproj#L1292-L1299.
|
||||
link_args : [
|
||||
'-Wl,-exported_symbol,__mh_execute_header',
|
||||
'-Wl,-stack_size,0x02000000',
|
||||
'-Wl,-client_name,ld',
|
||||
],
|
||||
link_with : [libcodedirectory],
|
||||
sources : [
|
||||
compile_stubs_h,
|
||||
configure_h,
|
||||
'compat/CommonCrypto/CommonDigestSPI.c',
|
||||
'compat/corecrypto/ccdigest.c',
|
||||
'compat/corecrypto/ccsha1.c',
|
||||
'compat/corecrypto/ccsha2.c',
|
||||
'src/ld/FatFile.cpp',
|
||||
'src/ld/InputFiles.cpp',
|
||||
'src/ld/Mangling.cpp',
|
||||
'src/ld/Options.cpp',
|
||||
'src/ld/OutputFile.cpp',
|
||||
'src/ld/PlatformSupport.cpp',
|
||||
'src/ld/Resolver.cpp',
|
||||
'src/ld/ResponseFiles.cpp',
|
||||
'src/ld/Snapshot.cpp',
|
||||
'src/ld/SymbolTable.cpp',
|
||||
'src/ld/code-sign-blobs/blob.cpp',
|
||||
'src/ld/code-sign-blobs/blob.h',
|
||||
'src/ld/debugline.c',
|
||||
'src/ld/ld.cpp',
|
||||
'src/ld/parsers/archive_file.cpp',
|
||||
'src/ld/parsers/generic_dylib_file.cpp',
|
||||
'src/ld/parsers/lto_file.cpp',
|
||||
'src/ld/parsers/macho_dylib_file.cpp',
|
||||
'src/ld/parsers/macho_relocatable_file.cpp',
|
||||
'src/ld/parsers/opaque_section_file.cpp',
|
||||
'src/ld/parsers/textstub_dylib_file.cpp',
|
||||
'src/ld/passes/bitcode_bundle.cpp',
|
||||
'src/ld/passes/branch_island.cpp',
|
||||
'src/ld/passes/branch_shim.cpp',
|
||||
'src/ld/passes/code_dedup.cpp',
|
||||
'src/ld/passes/compact_unwind.cpp',
|
||||
'src/ld/passes/dtrace_dof.cpp',
|
||||
'src/ld/passes/dylibs.cpp',
|
||||
'src/ld/passes/got.cpp',
|
||||
'src/ld/passes/huge.cpp',
|
||||
'src/ld/passes/inits.cpp',
|
||||
'src/ld/passes/objc.cpp',
|
||||
'src/ld/passes/objc_constants.cpp',
|
||||
'src/ld/passes/objc_stubs.cpp',
|
||||
'src/ld/passes/order.cpp',
|
||||
'src/ld/passes/stubs/stubs.cpp',
|
||||
'src/ld/passes/thread_starts.cpp',
|
||||
'src/ld/passes/tlvp.cpp',
|
||||
'src/mach_o/Error.cpp',
|
||||
'src/mach_o/ExportsTrie.cpp',
|
||||
],
|
||||
)
|
||||
install_man('doc/man/man1/ld-classic.1')
|
||||
|
||||
# Extra tools
|
||||
unwinddump = executable(
|
||||
f'@target_prefix@unwinddump',
|
||||
include_directories : incdirs,
|
||||
install : true,
|
||||
sources : [
|
||||
configure_h,
|
||||
'src/other/UnwindDump.cpp',
|
||||
],
|
||||
)
|
||||
install_man('doc/man/man1/unwinddump.1')
|
||||
|
||||
machocheck = executable(
|
||||
f'@target_prefix@machocheck',
|
||||
include_directories : incdirs,
|
||||
install : true,
|
||||
sources : [
|
||||
configure_h,
|
||||
'src/other/machochecker.cpp',
|
||||
],
|
||||
)
|
||||
|
||||
objectdump = executable(
|
||||
f'@target_prefix@ObjectDump',
|
||||
include_directories : incdirs,
|
||||
install : true,
|
||||
sources : [
|
||||
configure_h,
|
||||
'src/ld/PlatformSupport.cpp',
|
||||
'src/ld/debugline.c',
|
||||
'src/ld/parsers/macho_relocatable_file.cpp',
|
||||
'src/other/ObjectDump.cpp',
|
||||
],
|
||||
)
|
||||
|
||||
objcimageinfo = executable(
|
||||
f'@target_prefix@objcimageinfo',
|
||||
include_directories : incdirs,
|
||||
install : true,
|
||||
sources : [
|
||||
configure_h,
|
||||
'src/other/objcimageinfo.cpp',
|
||||
],
|
||||
)
|
6
pkgs/by-name/ld/ld64/meson.options
Normal file
6
pkgs/by-name/ld/ld64/meson.options
Normal file
@ -0,0 +1,6 @@
|
||||
option(
|
||||
'target_prefix',
|
||||
type : 'string',
|
||||
value : '',
|
||||
description: 'Specifies the prefix to use when building for cross-compilation (e.g., `aarch64-apple-darwin`)'
|
||||
)
|
202
pkgs/by-name/ld/ld64/package.nix
Normal file
202
pkgs/by-name/ld/ld64/package.nix
Normal file
@ -0,0 +1,202 @@
|
||||
{
|
||||
lib,
|
||||
stdenv,
|
||||
fetchFromGitHub,
|
||||
fetchurl,
|
||||
darwin,
|
||||
libtapi,
|
||||
libunwind,
|
||||
llvm,
|
||||
meson,
|
||||
ninja,
|
||||
openssl,
|
||||
pkg-config,
|
||||
python3,
|
||||
swiftPackages,
|
||||
xar,
|
||||
gitUpdater,
|
||||
}:
|
||||
|
||||
let
|
||||
# The targetPrefix is prepended to binary names to allow multiple binutils on the PATH to be usable.
|
||||
targetPrefix = lib.optionalString (
|
||||
stdenv.targetPlatform != stdenv.hostPlatform
|
||||
) "${stdenv.targetPlatform.config}-";
|
||||
|
||||
# ld64 needs CrashReporterClient.h, which is hard to find, but WebKit2 has it.
|
||||
# Fetch it directly because the Darwin stdenv bootstrap can’t depend on fetchgit.
|
||||
crashreporter_h = fetchurl {
|
||||
url = "https://raw.githubusercontent.com/apple-oss-distributions/WebKit2/WebKit2-7605.1.33.0.2/Platform/spi/Cocoa/CrashReporterClientSPI.h";
|
||||
hash = "sha256-0ybVcwHuGEdThv0PPjYQc3SW0YVOyrM3/L9zG/l1Vtk=";
|
||||
};
|
||||
|
||||
# First version with all the required definitions. This is used in preference to darwin.xnu to make it easier
|
||||
# to support Linux and because the version of darwin.xnu available on x86_64-darwin in the 10.12 SDK is too old.
|
||||
xnu = fetchFromGitHub {
|
||||
name = "xnu-src";
|
||||
owner = "apple-oss-distributions";
|
||||
repo = "xnu";
|
||||
rev = "xnu-6153.11.26";
|
||||
hash = "sha256-dcnGcp7bIjQxeAn5pXt+mHSYEXb2Ad9Smhd/WUG4kb4=";
|
||||
};
|
||||
|
||||
# Avoid pulling in all of Swift just to build libdispatch
|
||||
libdispatch = swiftPackages.Dispatch.override { useSwift = false; };
|
||||
in
|
||||
stdenv.mkDerivation (finalAttrs: {
|
||||
pname = "ld64";
|
||||
version = "951.9";
|
||||
|
||||
outputs = [
|
||||
"out"
|
||||
"dev"
|
||||
"lib"
|
||||
];
|
||||
|
||||
src = fetchFromGitHub {
|
||||
owner = "apple-oss-distributions";
|
||||
repo = "ld64";
|
||||
rev = "ld64-${finalAttrs.version}";
|
||||
hash = "sha256-hLkfqgBwVPlO4gfriYOawTO5E1zSD63ZcNetm1E5I70";
|
||||
};
|
||||
|
||||
xcodeHash = "sha256-+j7Ed/6aD46SJnr3DWPfWuYWylb2FNJRPmWsUVxZJHM=";
|
||||
|
||||
postUnpack = ''
|
||||
unpackFile '${xnu}'
|
||||
|
||||
# Verify that the Xcode project has not changed unexpectedly.
|
||||
hashType=$(echo $xcodeHash | cut -d- -f1)
|
||||
expectedHash=$(echo $xcodeHash | cut -d- -f2)
|
||||
hash=$(openssl "$hashType" -binary "$sourceRoot/ld64.xcodeproj/project.pbxproj" | base64)
|
||||
|
||||
if [ "$hash" != "$expectedHash" ]; then
|
||||
echo 'error: hash mismatch in ld64.xcodeproj/project.pbxproj'
|
||||
echo " specified: $xcodeHash"
|
||||
echo " got: $hashType-$hash"
|
||||
echo
|
||||
echo 'Upstream Xcode project has changed. Update `meson.build` with any changes, then update `xcodeHash`.'
|
||||
echo 'Use `nix-hash --flat --sri --type sha256 ld64.xcodeproj/project.pbxproj` to regenerate it.'
|
||||
exit 1
|
||||
fi
|
||||
'';
|
||||
|
||||
patches = [
|
||||
# Use std::atomic for atomics. Replaces private APIs (`os/lock_private.h`) with standard APIs.
|
||||
./0004-Use-std-atomics-and-std-mutex.patch
|
||||
# ld64 assumes the default libLTO.dylib can be found relative to its bindir, which is
|
||||
# not the case in nixpkgs. Override it to default to `stdenv.cc`’s libLTO.dylib.
|
||||
./0005-Support-LTO-in-nixpkgs.patch
|
||||
# Add implementation of missing function required for code directory support.
|
||||
./0006-Add-libcd_is_blob_a_linker_signature-implementation.patch
|
||||
# Add OpenSSL implementation of CoreCrypto digest functions. Avoids use of private and non-free APIs.
|
||||
./0007-Add-OpenSSL-based-CoreCrypto-digest-functions.patch
|
||||
# ld64 will search `/usr/lib`, `/Library/Frameworks`, etc by default. Disable that.
|
||||
./0008-Disable-searching-in-standard-library-locations.patch
|
||||
];
|
||||
|
||||
postPatch = ''
|
||||
substitute ${./meson.build} meson.build \
|
||||
--subst-var version
|
||||
cp ${./meson.options} meson.options
|
||||
|
||||
# Copy headers for certain private APIs
|
||||
mkdir -p include
|
||||
substitute ${crashreporter_h} include/CrashReporterClient.h \
|
||||
--replace-fail 'USE(APPLE_INTERNAL_SDK)' '0'
|
||||
|
||||
# Copy from the source so the headers can be used on Linux and x86_64-darwin
|
||||
mkdir -p include/System
|
||||
for dir in arm i386 machine; do
|
||||
cp -r ../xnu-src/osfmk/$dir include/System/$dir
|
||||
done
|
||||
mkdir -p include/sys
|
||||
cp ../xnu-src/bsd/sys/commpage.h include/sys
|
||||
|
||||
# Match the version format used by upstream.
|
||||
sed -i src/ld/Options.cpp \
|
||||
-e '1iconst char ld_classicVersionString[] = "@(#)PROGRAM:ld PROJECT:ld64-${finalAttrs.version}\\n";'
|
||||
|
||||
# Instead of messing around with trying to extract and run the script from the Xcode project,
|
||||
# just use our own Python script to generate `compile_stubs.h`
|
||||
cp ${./gen_compile_stubs.py} gen_compile_stubs.py
|
||||
|
||||
# Enable LTO support using LLVM’s libLTO.dylib by default.
|
||||
substituteInPlace src/ld/InputFiles.cpp \
|
||||
--subst-var-by libllvm '${lib.getLib llvm}'
|
||||
substituteInPlace src/ld/parsers/lto_file.cpp \
|
||||
--subst-var-by libllvm '${lib.getLib llvm}'
|
||||
|
||||
# Use portable includes
|
||||
substituteInPlace src/ld/code-sign-blobs/endian.h \
|
||||
--replace-fail '#include <machine/endian.h>' '#include <sys/types.h>'
|
||||
'';
|
||||
|
||||
strictDeps = true;
|
||||
|
||||
nativeBuildInputs = [
|
||||
meson
|
||||
ninja
|
||||
openssl
|
||||
pkg-config
|
||||
python3
|
||||
];
|
||||
|
||||
buildInputs = [
|
||||
libtapi
|
||||
llvm
|
||||
libunwind
|
||||
openssl
|
||||
xar
|
||||
] ++ lib.optionals stdenv.isDarwin [ darwin.dyld ] ++ lib.optionals stdenv.isLinux [ libdispatch ];
|
||||
|
||||
# Note for overrides: ld64 cannot be built as a debug build because of UB in its iteration implementations,
|
||||
# which trigger libc++ debug assertions due to trying to take the address of the first element of an emtpy vector.
|
||||
mesonBuildType = "release";
|
||||
|
||||
mesonFlags = [
|
||||
(lib.mesonOption "b_ndebug" "if-release")
|
||||
(lib.mesonOption "default_library" (if stdenv.hostPlatform.isStatic then "static" else "shared"))
|
||||
] ++ lib.optionals (targetPrefix != "") [ (lib.mesonOption "target_prefix" targetPrefix) ];
|
||||
|
||||
doInstallCheck = stdenv.buildPlatform.canExecute stdenv.hostPlatform;
|
||||
|
||||
# ld64 has a test suite, but many of the tests fail (even with ld from Xcode). Instead
|
||||
# of running the test suite, rebuild ld64 using itself to link itself as a check.
|
||||
# LTO is enabled only to confirm that it is set up and working properly in nixpkgs.
|
||||
installCheckPhase = ''
|
||||
runHook preInstallCheck
|
||||
|
||||
cd "$NIX_BUILD_TOP/$sourceRoot"
|
||||
|
||||
export NIX_CFLAGS_COMPILE+=" --ld-path=$out/bin/${targetPrefix}ld"
|
||||
meson setup build-install-check -Db_lto=true --buildtype=$mesonBuildType
|
||||
|
||||
cd build-install-check
|
||||
ninja ${targetPrefix}ld "-j$NIX_BUILD_CORES"
|
||||
|
||||
# Confirm that ld found the LTO library and reports it.
|
||||
./${targetPrefix}ld -v 2>&1 | grep -q 'LTO support'
|
||||
|
||||
runHook postInstallCheck
|
||||
'';
|
||||
|
||||
postInstall = ''
|
||||
ln -s ld-classic.1 "$out/share/man/man1/ld.1"
|
||||
ln -s ld.1 "$out/share/man/man1/ld64.1"
|
||||
moveToOutput lib/libprunetrie.a "$dev"
|
||||
'';
|
||||
|
||||
__structuredAttrs = true;
|
||||
|
||||
passthru.updateScript = gitUpdater { rev-prefix = "ld64-"; };
|
||||
|
||||
meta = {
|
||||
description = "The classic linker for Darwin";
|
||||
homepage = "https://opensource.apple.com/releases/";
|
||||
license = lib.licenses.apple-psl20;
|
||||
mainProgram = "ld";
|
||||
maintainers = with lib.maintainers; [ reckenrode ];
|
||||
platforms = lib.platforms.darwin; # Porting to other platforms is incomplete. Support only Darwin for now.
|
||||
};
|
||||
})
|
Loading…
Reference in New Issue
Block a user