]>
git.saurik.com Git - apple/libsecurity_codesigning.git/blob - lib/slcrep.cpp
1ba4c49f3dd69ec704afcf5583186a5d1cf0cf38
2 * Copyright (c) 2009 Apple Inc. All Rights Reserved.
4 * @APPLE_LICENSE_HEADER_START@
6 * This file contains Original Code and/or Modifications of Original Code
7 * as defined in and that are subject to the Apple Public Source License
8 * Version 2.0 (the 'License'). You may not use this file except in
9 * compliance with the License. Please obtain a copy of the License at
10 * http://www.opensource.apple.com/apsl/ and read it before using this
13 * The Original Code and all software distributed under the License are
14 * distributed on an 'AS IS' basis, WITHOUT WARRANTY OF ANY KIND, EITHER
15 * EXPRESS OR IMPLIED, AND APPLE HEREBY DISCLAIMS ALL SUCH WARRANTIES,
16 * INCLUDING WITHOUT LIMITATION, ANY WARRANTIES OF MERCHANTABILITY,
17 * FITNESS FOR A PARTICULAR PURPOSE, QUIET ENJOYMENT OR NON-INFRINGEMENT.
18 * Please see the License for the specific language governing rights and
19 * limitations under the License.
21 * @APPLE_LICENSE_HEADER_END@
25 // slcrep - DiskRep representing the Mac OS Shared Library Cache
31 namespace CodeSigning
{
33 using namespace UnixPlusPlus
;
38 // We open the file lazily, so nothing much happens on constructions.
39 // We can construct directly from a file path, or from an architecture
40 // (represented by Context), which will find the file in its usual
43 DYLDCacheRep::DYLDCacheRep(const char *path
)
44 : SingleDiskRep(path
), mCache(path
)
49 DYLDCacheRep::DYLDCacheRep(const Context
*ctx
)
50 : SingleDiskRep(DYLDCache::pathFor(((ctx
&& ctx
->arch
) ? ctx
->arch
: Architecture::local()))),
56 void DYLDCacheRep::setup()
59 if (mCache
.totalSize() >= mCache
.mapSize() + sizeof(BlobCore
)) {
60 const EmbeddedSignatureBlob
*blob
= mCache
.at
<const EmbeddedSignatureBlob
>(mCache
.mapSize());
61 if (mCache
.totalSize() >= mCache
.mapSize() + blob
->length()) // entire blob fits in file
64 CODESIGN_DISKREP_CREATE_SLC(this, (char*)this->mainExecutablePath().c_str());
69 // Sniffer function for "plausible shared library cache file".
71 bool DYLDCacheRep::candidate(FileDesc
&fd
)
73 return DYLDCache::validate(fd
);
78 // Default to system page size for segmented (paged) signatures
80 size_t DYLDCacheRep::pageSize()
82 return segmentedPageSize
;
87 // Retrieve a component from the executable.
88 // Our mCache has mapped the entire file, so we just fish the contents out of
89 // the mapped area as needed.
91 CFDataRef
DYLDCacheRep::component(CodeDirectory::SpecialSlot slot
)
93 return mSigningData
? mSigningData
->component(slot
) : NULL
;
98 // Provide a (vaguely) human readable characterization of this code
100 string
DYLDCacheRep::format()
102 if (const char *name
= mCache
.architecture().name()) {
104 snprintf(result
, sizeof(result
), "OS X Shared Library Cache (%s @ 0x%llx)",
105 name
, mCache
.baseAddress());
108 return "OS X Shared Library Cache (unknown type)";
113 // DYLDCacheRep::Writers
115 DiskRep::Writer
*DYLDCacheRep::writer()
117 return new Writer(this);
122 // Write a component.
124 void DYLDCacheRep::Writer::component(CodeDirectory::SpecialSlot slot
, CFDataRef data
)
126 EmbeddedSignatureBlob::Maker::component(slot
, data
);
131 // Append the superblob we built to the cache file.
133 void DYLDCacheRep::Writer::flush()
135 delete mSigningData
; // ditch previous blob just in case
136 mSigningData
= Maker::make(); // assemble new signature SuperBlob
137 fd().seek(rep
->mCache
.mapSize()); // end of impage proper
138 fd().writeAll(*mSigningData
);
143 // The discretionary additions insert a Scatter vector describing the file's mapping table.
145 void DYLDCacheRep::Writer::addDiscretionary(CodeDirectory::Builder
&builder
)
147 unsigned count
= rep
->mCache
.mappingCount();
148 builder
.scatter(count
);
149 for (unsigned n
= 0; n
< count
; n
++) {
150 const DYLDCache::Mapping dmap
= rep
->mCache
.mapping(n
);
151 CodeDirectory::Scatter
*scatter
= builder
.scatter() + n
;
152 scatter
->targetOffset
= dmap
.address();
153 scatter
->base
= dmap
.offset() / segmentedPageSize
;
154 assert(dmap
.offset() % segmentedPageSize
== 0);
155 scatter
->count
= dmap
.size() / segmentedPageSize
;
156 assert(dmap
.size() % segmentedPageSize
== 0);
161 } // end namespace CodeSigning
162 } // end namespace Security