Skip to content

Commit a38e3dc

Browse files
committed
Some progress
1 parent f930a23 commit a38e3dc

18 files changed

+924
-30
lines changed

src/Xamarin.Android.Build.Tasks/Utilities/ApplicationConfig.cs

+8
Original file line numberDiff line numberDiff line change
@@ -44,18 +44,26 @@ sealed class ApplicationConfig
4444
public uint number_of_aot_cache_entries;
4545
public uint number_of_shared_libraries;
4646

47+
#if !IN_APPTOOLS
4748
[NativeAssembler (NumberFormat = LLVMIR.LlvmIrVariableNumberFormat.Hexadecimal)]
49+
#endif
4850
public uint android_runtime_jnienv_class_token;
4951

52+
#if !IN_APPTOOLS
5053
[NativeAssembler (NumberFormat = LLVMIR.LlvmIrVariableNumberFormat.Hexadecimal)]
54+
#endif
5155
public uint jnienv_initialize_method_token;
5256

57+
#if !IN_APPTOOLS
5358
[NativeAssembler (NumberFormat = LLVMIR.LlvmIrVariableNumberFormat.Hexadecimal)]
59+
#endif
5460
public uint jnienv_registerjninatives_method_token;
5561
public uint jni_remapping_replacement_type_count;
5662
public uint jni_remapping_replacement_method_index_entry_count;
5763

64+
#if !IN_APPTOOLS
5865
[NativeAssembler (NumberFormat = LLVMIR.LlvmIrVariableNumberFormat.Hexadecimal)]
66+
#endif
5967
public uint mono_components_mask;
6068
public string android_package_name = String.Empty;
6169
public bool managed_marshal_methods_lookup_enabled;

src/Xamarin.Android.Build.Tasks/Utilities/ApplicationConfigCLR.cs

+6
Original file line numberDiff line numberDiff line change
@@ -38,13 +38,19 @@ sealed class ApplicationConfigCLR
3838
public uint number_of_aot_cache_entries;
3939
public uint number_of_shared_libraries;
4040

41+
#if !IN_APPTOOLS
4142
[NativeAssembler (NumberFormat = LLVMIR.LlvmIrVariableNumberFormat.Hexadecimal)]
43+
#endif
4244
public uint android_runtime_jnienv_class_token;
4345

46+
#if !IN_APPTOOLS
4447
[NativeAssembler (NumberFormat = LLVMIR.LlvmIrVariableNumberFormat.Hexadecimal)]
48+
#endif
4549
public uint jnienv_initialize_method_token;
4650

51+
#if !IN_APPTOOLS
4752
[NativeAssembler (NumberFormat = LLVMIR.LlvmIrVariableNumberFormat.Hexadecimal)]
53+
#endif
4854
public uint jnienv_registerjninatives_method_token;
4955
public uint jni_remapping_replacement_type_count;
5056
public uint jni_remapping_replacement_method_index_entry_count;
Original file line numberDiff line numberDiff line change
@@ -1,13 +1,36 @@
11
using System;
2+
using System.Collections.Generic;
23

34
using Xamarin.Android.Tools;
45

56
namespace Microsoft.Android.AppTools.Assemblies;
67

78
public class AssemblyStore
89
{
10+
static List<AssemblyStoreItem>? emptyAssemblyList;
11+
12+
readonly ILogger log;
13+
readonly AssemblyStoreExplorer explorer;
14+
15+
public IList<AssemblyStoreItem> Assemblies => explorer.Assemblies ?? GetEmptyAssemblyList ();
916
public uint FullFormatVersion { get; private set; } = 0;
10-
public ulong NumberOfAssemblies { get; private set; } = 0;
11-
public AndroidTargetArch TargetArchitecture { get; private set; } = AndroidTargetArch.None;
17+
public ulong NumberOfAssemblies => explorer.AssemblyCount;
18+
public AndroidTargetArch TargetArchitecture => explorer.TargetArch ?? AndroidTargetArch.None;
1219
public Version? Version { get; private set; }
20+
21+
internal AssemblyStore (ILogger log, AssemblyStoreExplorer explorer)
22+
{
23+
this.log = log;
24+
this.explorer = explorer;
25+
}
26+
27+
static List<AssemblyStoreItem> GetEmptyAssemblyList ()
28+
{
29+
if (emptyAssemblyList != null) {
30+
return emptyAssemblyList;
31+
}
32+
33+
emptyAssemblyList = new List<AssemblyStoreItem> ();
34+
return emptyAssemblyList;
35+
}
1336
}
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,212 @@
1+
using System;
2+
using System.Collections.Generic;
3+
using System.IO;
4+
5+
using Xamarin.Android.Tools;
6+
using Xamarin.Tools.Zip;
7+
8+
namespace Microsoft.Android.AppTools.Assemblies;
9+
10+
class AssemblyStoreExplorer
11+
{
12+
readonly AssemblyStoreReader reader;
13+
14+
public string StorePath { get; }
15+
public AndroidTargetArch? TargetArch { get; }
16+
public uint AssemblyCount { get; }
17+
public uint IndexEntryCount { get; }
18+
public IList<AssemblyStoreItem>? Assemblies { get; }
19+
public IDictionary<string, AssemblyStoreItem>? AssembliesByName { get; }
20+
public bool Is64Bit { get; }
21+
22+
protected AssemblyStoreExplorer (Stream storeStream, string path)
23+
{
24+
StorePath = path;
25+
var storeReader = AssemblyStoreReader.Create (storeStream, path);
26+
if (storeReader == null) {
27+
storeStream.Dispose ();
28+
throw new NotSupportedException ($"Format of assembly store '{path}' is unsupported");
29+
}
30+
31+
reader = storeReader;
32+
TargetArch = reader.TargetArch;
33+
AssemblyCount = reader.AssemblyCount;
34+
IndexEntryCount = reader.IndexEntryCount;
35+
Assemblies = reader.Assemblies;
36+
Is64Bit = reader.Is64Bit;
37+
38+
if (Assemblies == null) {
39+
return;
40+
}
41+
42+
var dict = new Dictionary<string, AssemblyStoreItem> (StringComparer.Ordinal);
43+
foreach (AssemblyStoreItem item in Assemblies) {
44+
dict.Add (item.Name, item);
45+
}
46+
AssembliesByName = dict.AsReadOnly ();
47+
}
48+
49+
protected AssemblyStoreExplorer (FileInfo storeInfo)
50+
: this (storeInfo.OpenRead (), storeInfo.FullName)
51+
{}
52+
53+
public static IList<AssemblyStoreExplorer>? Open (ILogger log, string inputFile, FileFormat format, FileInfo info)
54+
{
55+
switch (format) {
56+
case FileFormat.Unknown:
57+
log.Debug ($"File '{inputFile}' has an unknown format.");
58+
return null;
59+
60+
case FileFormat.Zip:
61+
log.Debug ($"File '{inputFile}' is a ZIP archive, but not an Android one.");
62+
return null;
63+
64+
case FileFormat.AssemblyStore:
65+
case FileFormat.ELF:
66+
return new List<AssemblyStoreExplorer> { new AssemblyStoreExplorer (info)};
67+
68+
case FileFormat.Aab:
69+
return OpenAab (log, info);
70+
71+
case FileFormat.AabBase:
72+
return OpenAabBase (log, info);
73+
74+
case FileFormat.Apk:
75+
return OpenApk (log, info);
76+
77+
default:
78+
log.Debug ($"File '{inputFile}' has an unsupported format '{format}'");
79+
return null;
80+
}
81+
}
82+
83+
static IList<AssemblyStoreExplorer>? OpenAab (ILogger log, FileInfo fi)
84+
{
85+
return OpenCommon (
86+
log,
87+
fi,
88+
new List<IList<string>> {
89+
StoreReader_V2.AabPaths,
90+
}
91+
);
92+
}
93+
94+
static IList<AssemblyStoreExplorer>? OpenAabBase (ILogger log, FileInfo fi)
95+
{
96+
return OpenCommon (
97+
log,
98+
fi,
99+
new List<IList<string>> {
100+
StoreReader_V2.AabBasePaths,
101+
}
102+
);
103+
}
104+
105+
static IList<AssemblyStoreExplorer>? OpenApk (ILogger log, FileInfo fi)
106+
{
107+
return OpenCommon (
108+
log,
109+
fi,
110+
new List<IList<string>> {
111+
StoreReader_V2.ApkPaths,
112+
}
113+
);
114+
}
115+
116+
static IList<AssemblyStoreExplorer>? OpenCommon (ILogger log, FileInfo fi, List<IList<string>> pathLists)
117+
{
118+
using var zip = ZipArchive.Open (fi.FullName, FileMode.Open);
119+
IList<AssemblyStoreExplorer>? explorers;
120+
bool pathsFound;
121+
122+
foreach (IList<string> paths in pathLists) {
123+
(explorers, pathsFound) = TryLoad (log, fi, zip, paths);
124+
if (pathsFound) {
125+
return explorers;
126+
}
127+
}
128+
129+
log.Debug ("Unable to find any blob entries");
130+
return null;
131+
}
132+
133+
static (IList<AssemblyStoreExplorer>? explorers, bool pathsFound) TryLoad (ILogger log, FileInfo fi, ZipArchive zip, IList<string> paths)
134+
{
135+
var ret = new List<AssemblyStoreExplorer> ();
136+
137+
foreach (string path in paths) {
138+
if (!zip.ContainsEntry (path)) {
139+
continue;
140+
}
141+
142+
ZipEntry entry = zip.ReadEntry (path);
143+
var stream = new MemoryStream ();
144+
entry.Extract (stream);
145+
ret.Add (new AssemblyStoreExplorer (stream, $"{fi.FullName}!{path}"));
146+
}
147+
148+
if (ret.Count == 0) {
149+
return (null, false);
150+
}
151+
152+
return (ret, true);
153+
}
154+
155+
public Stream? ReadImageData (AssemblyStoreItem item, bool uncompressIfNeeded = false)
156+
{
157+
return reader.ReadEntryImageData (item, uncompressIfNeeded);
158+
}
159+
160+
string EnsureCorrectAssemblyName (string assemblyName)
161+
{
162+
assemblyName = Path.GetFileName (assemblyName);
163+
if (reader.NeedsExtensionInName) {
164+
if (!assemblyName.EndsWith (".dll", StringComparison.OrdinalIgnoreCase)) {
165+
return $"{assemblyName}.dll";
166+
}
167+
} else {
168+
if (assemblyName.EndsWith (".dll", StringComparison.OrdinalIgnoreCase)) {
169+
return Path.GetFileNameWithoutExtension (assemblyName);
170+
}
171+
}
172+
173+
return assemblyName;
174+
}
175+
176+
public IList<AssemblyStoreItem>? Find (string assemblyName, AndroidTargetArch? targetArch = null)
177+
{
178+
if (Assemblies == null) {
179+
return null;
180+
}
181+
182+
assemblyName = EnsureCorrectAssemblyName (assemblyName);
183+
var items = new List<AssemblyStoreItem> ();
184+
foreach (AssemblyStoreItem item in Assemblies) {
185+
if (String.CompareOrdinal (assemblyName, item.Name) != 0) {
186+
continue;
187+
}
188+
189+
if (targetArch != null && item.TargetArch != targetArch) {
190+
continue;
191+
}
192+
193+
items.Add (item);
194+
}
195+
196+
if (items.Count == 0) {
197+
return null;
198+
}
199+
200+
return items;
201+
}
202+
203+
public bool Contains (string assemblyName, AndroidTargetArch? targetArch = null)
204+
{
205+
IList<AssemblyStoreItem>? items = Find (assemblyName, targetArch);
206+
if (items == null || items.Count == 0) {
207+
return false;
208+
}
209+
210+
return true;
211+
}
212+
}
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,26 @@
1+
using System.Collections.Generic;
2+
3+
using Xamarin.Android.Tools;
4+
5+
namespace Microsoft.Android.AppTools.Assemblies;
6+
7+
public abstract class AssemblyStoreItem
8+
{
9+
public string Name { get; }
10+
public IList<ulong> Hashes { get; }
11+
public bool Is64Bit { get; }
12+
public uint DataOffset { get; protected set; }
13+
public uint DataSize { get; protected set; }
14+
public uint DebugOffset { get; protected set; }
15+
public uint DebugSize { get; protected set; }
16+
public uint ConfigOffset { get; protected set; }
17+
public uint ConfigSize { get; protected set; }
18+
public AndroidTargetArch TargetArch { get; protected set; }
19+
20+
protected AssemblyStoreItem (string name, bool is64Bit, List<ulong> hashes)
21+
{
22+
Name = name;
23+
Hashes = hashes.AsReadOnly ();
24+
Is64Bit = is64Bit;
25+
}
26+
}

0 commit comments

Comments
 (0)