- fsignatures args = { static_cast<off_t>(code->diskRep()->signingBase()), (void *)cd, cd->length() };
- UnixError::check(::fcntl(code->diskRep()->fd(), F_ADDSIGS, &args));
- } else
+ if (code->isDetached()) {
+ // Detached signatures need to attach their code directory from memory.
+ fsignatures args = { static_cast<off_t>(code->diskRep()->signingBase()), (void *)cd, cd->length() };
+ UnixError::check(::fcntl(code->diskRep()->fd(), F_ADDSIGS, &args));
+ } else {
+ // All other signatures can simply point to the signature in the main executable.
+ Universal *execImage = code->diskRep()->mainExecutableImage();
+ if (execImage == NULL) {
+ MacOSError::throwMe(errSecCSNoMainExecutable);
+ }
+
+ auto_ptr<MachO> arch(execImage->architecture());
+ if (arch.get() == NULL) {
+ MacOSError::throwMe(errSecCSNoMainExecutable);
+ }
+
+ size_t signatureOffset = arch->signingOffset();
+ size_t signatureLength = arch->signingLength();
+ if (signatureOffset == 0) {
+ MacOSError::throwMe(errSecCSUnsigned);
+ }
+
+ fsignatures args = {
+ static_cast<off_t>(code->diskRep()->signingBase()),
+ (void *)signatureOffset,
+ signatureLength,
+ };
+ UnixError::check(::fcntl(code->diskRep()->fd(), F_ADDFILESIGS, &args));
+ }
+ } else {