@@ -16,6 +16,7 @@ namespace Xamarin.Android.Tasks;
16
16
// [HEADER]
17
17
// [INDEX]
18
18
// [ASSEMBLY_DESCRIPTORS]
19
+ // [ASSEMBLY_NAMES]
19
20
// [ASSEMBLY DATA]
20
21
//
21
22
// Formats of the sections above are as follows:
@@ -30,6 +31,7 @@ namespace Xamarin.Android.Tasks;
30
31
// INDEX (variable size, HEADER.ENTRY_COUNT*2 entries, for assembly names with and without the extension)
31
32
// [NAME_HASH] uint on 32-bit platforms, ulong on 64-bit platforms; xxhash of the assembly name
32
33
// [DESCRIPTOR_INDEX] uint; index into in-store assembly descriptor array
34
+ // [IGNORE] byte; if set to anything other than 0, the assembly is to be ignored when loading
33
35
//
34
36
// ASSEMBLY_DESCRIPTORS (variable size, HEADER.ENTRY_COUNT entries), each entry formatted as follows:
35
37
// [MAPPING_INDEX] uint; index into a runtime array where assembly data pointers are stored
@@ -50,19 +52,14 @@ partial class AssemblyStoreGenerator
50
52
const uint ASSEMBLY_STORE_MAGIC = 0x41424158 ; // 'XABA', little-endian, must match the BUNDLED_ASSEMBLIES_BLOB_MAGIC native constant
51
53
52
54
// Bit 31 is set for 64-bit platforms, cleared for the 32-bit ones
53
- const uint ASSEMBLY_STORE_FORMAT_VERSION_64BIT = 0x80000002 ; // Must match the ASSEMBLY_STORE_FORMAT_VERSION native constant
54
- const uint ASSEMBLY_STORE_FORMAT_VERSION_32BIT = 0x00000002 ;
55
+ const uint ASSEMBLY_STORE_FORMAT_VERSION_64BIT = 0x80000003 ; // Must match the ASSEMBLY_STORE_FORMAT_VERSION native constant
56
+ const uint ASSEMBLY_STORE_FORMAT_VERSION_32BIT = 0x00000003 ;
55
57
56
58
const uint ASSEMBLY_STORE_ABI_AARCH64 = 0x00010000 ;
57
59
const uint ASSEMBLY_STORE_ABI_ARM = 0x00020000 ;
58
60
const uint ASSEMBLY_STORE_ABI_X64 = 0x00030000 ;
59
61
const uint ASSEMBLY_STORE_ABI_X86 = 0x00040000 ;
60
62
61
- // This must be the same value as the native AssemblyStore::ASSEMBLY_STORE_IGNORED_INDEX_ENTRY constant,
62
- // found in src/native/clr/include/host/assembly-store.hh
63
- //
64
- const uint ASSEMBLY_STORE_IGNORED_INDEX_ENTRY = UInt32 . MaxValue ;
65
-
66
63
readonly TaskLoggingHelper log ;
67
64
readonly Dictionary < AndroidTargetArch , List < AssemblyStoreAssemblyInfo > > assemblies ;
68
65
@@ -127,22 +124,29 @@ string Generate (string baseOutputDirectory, AndroidTargetArch arch, List<Assemb
127
124
using var fs = File . Open ( storePath , FileMode . Create , FileAccess . Write , FileShare . Read ) ;
128
125
fs . Seek ( ( long ) curPos , SeekOrigin . Begin ) ;
129
126
127
+ uint mappingIndex = 0 ;
130
128
foreach ( AssemblyStoreAssemblyInfo info in infos ) {
129
+ ( AssemblyStoreEntryDescriptor desc , curPos ) = MakeDescriptor ( info , curPos ) ;
131
130
if ( info . Ignored ) {
132
- AddToIndex ( info , ASSEMBLY_STORE_IGNORED_INDEX_ENTRY ) ;
133
- descriptors . Add ( new AssemblyStoreEntryDescriptor ( ) ) ;
134
- continue ;
131
+ desc . mapping_index = 0 ;
132
+ } else {
133
+ desc . mapping_index = mappingIndex ++ ;
135
134
}
136
-
137
- ( AssemblyStoreEntryDescriptor desc , curPos ) = MakeDescriptor ( info , curPos ) ;
138
- desc . mapping_index = ( uint ) descriptors . Count ;
135
+ uint entryIndex = ( uint ) descriptors . Count ;
139
136
descriptors . Add ( desc ) ;
140
137
141
- if ( ( uint ) fs . Position != desc . data_offset ) {
138
+ if ( ! info . Ignored && ( uint ) fs . Position != desc . data_offset ) {
142
139
throw new InvalidOperationException ( $ "Internal error: corrupted store '{ storePath } ' stream") ;
143
140
}
144
141
145
- AddToIndex ( info , desc . mapping_index ) ;
142
+ ulong name_with_ext_hash = MonoAndroidHelper . GetXxHash ( info . AssemblyNameBytes , is64Bit ) ;
143
+ ulong name_no_ext_hash = MonoAndroidHelper . GetXxHash ( info . AssemblyNameNoExtBytes , is64Bit ) ;
144
+ index . Add ( new AssemblyStoreIndexEntry ( info . AssemblyName , name_with_ext_hash , entryIndex , info . Ignored ) ) ;
145
+ index . Add ( new AssemblyStoreIndexEntry ( info . AssemblyNameNoExt , name_no_ext_hash , entryIndex , info . Ignored ) ) ;
146
+
147
+ if ( info . Ignored ) {
148
+ continue ;
149
+ }
146
150
147
151
CopyData ( info . SourceFile , fs , storePath ) ;
148
152
CopyData ( info . SymbolsFile , fs , storePath ) ;
@@ -175,14 +179,6 @@ string Generate (string baseOutputDirectory, AndroidTargetArch arch, List<Assemb
175
179
176
180
return storePath ;
177
181
178
- void AddToIndex ( AssemblyStoreAssemblyInfo info , uint offset )
179
- {
180
- ulong name_with_ext_hash = MonoAndroidHelper . GetXxHash ( info . AssemblyNameBytes , is64Bit ) ;
181
- ulong name_no_ext_hash = MonoAndroidHelper . GetXxHash ( info . AssemblyNameNoExtBytes , is64Bit ) ;
182
- index . Add ( new AssemblyStoreIndexEntry ( info . AssemblyName , name_with_ext_hash , offset ) ) ;
183
- index . Add ( new AssemblyStoreIndexEntry ( info . AssemblyNameNoExt , name_no_ext_hash , offset ) ) ;
184
- }
185
-
186
182
uint IndexEntrySize ( ) => is64Bit ? AssemblyStoreIndexEntry . NativeSize64 : AssemblyStoreIndexEntry . NativeSize32 ;
187
183
}
188
184
@@ -200,8 +196,8 @@ void CopyData (FileInfo? src, Stream dest, string storePath)
200
196
static ( AssemblyStoreEntryDescriptor desc , ulong newPos ) MakeDescriptor ( AssemblyStoreAssemblyInfo info , ulong curPos )
201
197
{
202
198
var ret = new AssemblyStoreEntryDescriptor {
203
- data_offset = ( uint ) curPos ,
204
- data_size = GetDataLength ( info . SourceFile ) ,
199
+ data_offset = info . Ignored ? 0 : ( uint ) curPos ,
200
+ data_size = info . Ignored ? 0 : GetDataLength ( info . SourceFile ) ,
205
201
} ;
206
202
if ( info . SymbolsFile != null ) {
207
203
ret . debug_data_offset = ret . data_offset + ret . data_size ;
@@ -213,9 +209,11 @@ void CopyData (FileInfo? src, Stream dest, string storePath)
213
209
ret . config_data_size = GetDataLength ( info . ConfigFile ) ;
214
210
}
215
211
216
- curPos += ret . data_size + ret . debug_data_size + ret . config_data_size ;
217
- if ( curPos > UInt32 . MaxValue ) {
218
- throw new NotSupportedException ( "Assembly store size exceeds the maximum supported value" ) ;
212
+ if ( ! info . Ignored ) {
213
+ curPos += ret . data_size + ret . debug_data_size + ret . config_data_size ;
214
+ if ( curPos > UInt32 . MaxValue ) {
215
+ throw new NotSupportedException ( "Assembly store size exceeds the maximum supported value" ) ;
216
+ }
219
217
}
220
218
221
219
return ( ret , curPos ) ;
@@ -268,21 +266,22 @@ void WriteIndex (BinaryWriter writer, StreamWriter manifestWriter, List<Assembly
268
266
manifestWriter . Write ( $ "0x{ ( uint ) entry . name_hash : x} ") ;
269
267
}
270
268
writer . Write ( entry . descriptor_index ) ;
271
-
272
- if ( entry . descriptor_index == ASSEMBLY_STORE_IGNORED_INDEX_ENTRY ) {
273
- manifestWriter . Write ( " <IGNORED>" ) ;
274
- } else {
275
- manifestWriter . Write ( $ " di:{ entry . descriptor_index } ") ;
276
- AssemblyStoreEntryDescriptor desc = descriptors [ ( int ) entry . descriptor_index ] ;
277
- manifestWriter . Write ( $ " mi:{ desc . mapping_index } ") ;
278
- manifestWriter . Write ( $ " do:{ desc . data_offset } ") ;
279
- manifestWriter . Write ( $ " ds:{ desc . data_size } ") ;
280
- manifestWriter . Write ( $ " ddo:{ desc . debug_data_offset } ") ;
281
- manifestWriter . Write ( $ " dds:{ desc . debug_data_size } ") ;
282
- manifestWriter . Write ( $ " cdo:{ desc . config_data_offset } ") ;
283
- manifestWriter . Write ( $ " cds:{ desc . config_data_size } ") ;
269
+ writer . Write ( ( byte ) ( entry . ignore ? 1 : 0 ) ) ;
270
+
271
+ manifestWriter . Write ( $ " di:{ entry . descriptor_index } ") ;
272
+ AssemblyStoreEntryDescriptor desc = descriptors [ ( int ) entry . descriptor_index ] ;
273
+ manifestWriter . Write ( $ " mi:{ desc . mapping_index } ") ;
274
+ manifestWriter . Write ( $ " do:{ desc . data_offset } ") ;
275
+ manifestWriter . Write ( $ " ds:{ desc . data_size } ") ;
276
+ manifestWriter . Write ( $ " ddo:{ desc . debug_data_offset } ") ;
277
+ manifestWriter . Write ( $ " dds:{ desc . debug_data_size } ") ;
278
+ manifestWriter . Write ( $ " cdo:{ desc . config_data_offset } ") ;
279
+ manifestWriter . Write ( $ " cds:{ desc . config_data_size } ") ;
280
+ manifestWriter . Write ( $ " { entry . name } ") ;
281
+ if ( entry . ignore ) {
282
+ manifestWriter . Write ( " (ignored)" ) ;
284
283
}
285
- manifestWriter . WriteLine ( $ " { entry . name } " ) ;
284
+ manifestWriter . WriteLine ( ) ;
286
285
}
287
286
}
288
287
@@ -305,7 +304,9 @@ List<AssemblyStoreIndexEntry> ReadIndex (BinaryReader reader, AssemblyStoreHeade
305
304
}
306
305
307
306
uint descriptor_index = reader . ReadUInt32 ( ) ;
308
- index . Add ( new AssemblyStoreIndexEntry ( String . Empty , name_hash , descriptor_index ) ) ;
307
+ bool ignored = reader . ReadByte ( ) != 0 ;
308
+
309
+ index . Add ( new AssemblyStoreIndexEntry ( String . Empty , name_hash , descriptor_index , ignored ) ) ;
309
310
}
310
311
311
312
return index ;
0 commit comments