path = external/boringssl
url = git://github.com/mono/boringssl.git
branch = mono
+[submodule "external/corefx"]
+ path = external/corefx
+ url = git://github.com/mono/corefx.git
dnl *** Btls ***
dnl **************
-AC_ARG_ENABLE(btls, [ --disable-blts Disable the BoringTls provider], enable_btls=$enableval, enable_btls=$BTLS_SUPPORTED)
+AC_ARG_ENABLE(btls, [ --disable-btls Disable the BoringTls provider], enable_btls=$enableval, enable_btls=$BTLS_SUPPORTED)
AC_ARG_WITH(btls_android_ndk, [ --with-btls-android-ndk Android NDK for BoringTls])
AM_CONDITIONAL(BTLS, test x$enable_btls = xyes)
--- /dev/null
+Subproject commit b1aa1d92ca33d0cb8ffbac9b6ff73b284db6bbf1
if (t != Token.Type.Token)
return false;
- int nvalue;
+ long nvalue;
if (!lexer.IsStarStringValue (t)) {
if (!lexer.TryGetNumericValue (t, out nvalue)) {
var s = lexer.GetStringValue (t);
if (sep.Length != 2)
return false;
- if (!int.TryParse (sep[0], NumberStyles.None, CultureInfo.InvariantCulture, out nvalue))
+ if (!long.TryParse (sep[0], NumberStyles.None, CultureInfo.InvariantCulture, out nvalue))
return false;
value.From = nvalue;
- if (!int.TryParse (sep[1], NumberStyles.None, CultureInfo.InvariantCulture, out nvalue))
+ if (!long.TryParse (sep[1], NumberStyles.None, CultureInfo.InvariantCulture, out nvalue))
return false;
value.To = nvalue;
}
} catch (WebException we) {
if (we.Status != WebExceptionStatus.RequestCanceled)
- throw;
+ throw new HttpRequestException ("An error occurred while sending the request", we);
+ } catch (System.IO.IOException ex) {
+ throw new HttpRequestException ("An error occurred while sending the request", ex);
}
if (cancellationToken.IsCancellationRequested) {
Assert.IsNull (res.To, "#22");
Assert.IsNull (res.Length, "#23");
Assert.AreEqual ("by */*", res.ToString (), "#24");
+
+ res = ContentRangeHeaderValue.Parse("bytes 199999999999999999 - 999999999999999999/ 9223372036854775807");
+ Assert.AreEqual (199999999999999999, res.From, "#31");
+ Assert.AreEqual (999999999999999999, res.To, "#32");
+ Assert.AreEqual (9223372036854775807, res.Length, "#33");
+ Assert.AreEqual ("bytes 199999999999999999-999999999999999999/9223372036854775807", res.ToString (), "#34");
}
[Test]
void SetupCertificateStore ()
{
-#if MONODROID
- ctx.CertificateStore.SetDefaultPaths ();
- ctx.CertificateStore.AddAndroidLookup ();
-#else
- var userPath = MonoBtlsX509StoreManager.GetStorePath (MonoBtlsX509StoreType.UserTrustedRoots);
- if (Directory.Exists (userPath))
- ctx.CertificateStore.AddDirectoryLookup (userPath, MonoBtlsX509FileType.PEM);
- var machinePath = MonoBtlsX509StoreManager.GetStorePath (MonoBtlsX509StoreType.MachineTrustedRoots);
- if (Directory.Exists (machinePath))
- ctx.CertificateStore.AddDirectoryLookup (machinePath, MonoBtlsX509FileType.PEM);
-#endif
+ MonoBtlsProvider.SetupCertificateStore (ctx.CertificateStore);
if (Settings != null && Settings.TrustAnchors != null) {
var trust = IsServer ? MonoBtlsX509TrustKind.TRUST_CLIENT : MonoBtlsX509TrustKind.TRUST_SERVER;
return buffer;
}
+ public bool IsRsa {
+ get {
+ return mono_btls_key_is_rsa (Handle.DangerousGetHandle ()) != 0;
+ }
+ }
+
public MonoBtlsKey Copy ()
{
CheckThrow ();
var passptr = IntPtr.Zero;
fixed (void* ptr = buffer)
try {
- passptr = Marshal.StringToHGlobalAnsi (password ?? string.Empty);
+ if (password != null)
+ passptr = Marshal.StringToHGlobalAnsi (password);
var ret = mono_btls_pkcs12_import (
Handle.DangerousGetHandle (), ptr,
buffer.Length, passptr);
internal override X509Certificate2Impl GetNativeCertificate (
byte[] data, string password, X509KeyStorageFlags flags)
{
- var impl = new X509CertificateImplBtls (true);
+ var impl = new X509CertificateImplBtls (false);
impl.Import (data, password, flags);
return impl;
}
using (var nativeChain = MonoBtlsProvider.GetNativeChain (certificates))
using (var param = GetVerifyParam (targetHost, serverMode))
using (var storeCtx = new MonoBtlsX509StoreCtx ()) {
- store.LoadLocations (null, GetSystemStoreLocation ());
- store.SetDefaultPaths ();
+ SetupCertificateStore (store);
storeCtx.Initialize (store, nativeChain);
}
}
+ internal static bool ValidateCertificate (MonoBtlsX509Chain chain, MonoBtlsX509VerifyParam param)
+ {
+ using (var store = new MonoBtlsX509Store ())
+ using (var storeCtx = new MonoBtlsX509StoreCtx ()) {
+ SetupCertificateStore (store);
+
+ storeCtx.Initialize (store, chain);
+
+ if (param != null)
+ storeCtx.SetVerifyParam (param);
+
+ var ret = storeCtx.Verify ();
+
+ return ret == 1;
+ }
+ }
+
void CheckValidationResult (
ICertificateValidator validator, string targetHost, bool serverMode,
X509CertificateCollection certificates, bool wantsChain,
}
}
+ internal static void SetupCertificateStore (MonoBtlsX509Store store)
+ {
+#if MONODROID
+ store.SetDefaultPaths ();
+ store.AddAndroidLookup ();
+#else
+ var userPath = MonoBtlsX509StoreManager.GetStorePath (MonoBtlsX509StoreType.UserTrustedRoots);
+ if (Directory.Exists (userPath))
+ store.AddDirectoryLookup (userPath, MonoBtlsX509FileType.PEM);
+ var machinePath = MonoBtlsX509StoreManager.GetStorePath (MonoBtlsX509StoreType.MachineTrustedRoots);
+ if (Directory.Exists (machinePath))
+ store.AddDirectoryLookup (machinePath, MonoBtlsX509FileType.PEM);
+#endif
+ }
+
public static string GetSystemStoreLocation ()
{
#if ANDROID
if (Compare (oidValue, emailOid))
type = MonoBtlsX509NameEntryType.Email;
}
- var text = name.GetEntryValue (index);
+ int tag;
+ var text = name.GetEntryValue (index, out tag);
if (text == null)
return false;
var oid = name.GetEntryOid (index);
// 16bits or 8bits string ? TODO not complete (+special chars!)
char[] specials = { ',', '+', '"', '\\', '<', '>', ';' };
- if (quotes) {
+ if (quotes && tag != 0x1E) {
if ((text.IndexOfAny (specials, 0, text.Length) > 0) ||
text.StartsWith (" ") || (text.EndsWith (" ")))
text = "\"" + text + "\"";
extern static int mono_btls_x509_name_get_entry_oid_data (IntPtr name, int index, out IntPtr data);
[MethodImpl (MethodImplOptions.InternalCall)]
- extern static int mono_btls_x509_name_get_entry_value (IntPtr name, int index, out IntPtr str);
+ extern static int mono_btls_x509_name_get_entry_value (IntPtr name, int index, out int tag, out IntPtr str);
[MethodImpl (MethodImplOptions.InternalCall)]
extern unsafe static IntPtr mono_btls_x509_name_from_data (void* data, int len, int use_canon_enc);
return bytes;
}
- public unsafe string GetEntryValue (int index)
+ public unsafe string GetEntryValue (int index, out int tag)
{
if (index >= GetEntryCount ())
throw new ArgumentOutOfRangeException ();
IntPtr data;
var ret = mono_btls_x509_name_get_entry_value (
- Handle.DangerousGetHandle (), index, out data);
+ Handle.DangerousGetHandle (), index, out tag, out data);
if (ret <= 0)
return null;
try {
// OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
// THE SOFTWARE.
#if SECURITY_DEP
+#if MONO_SECURITY_ALIAS
+extern alias MonoSecurity;
+#endif
+
+#if MONO_SECURITY_ALIAS
+using MX = MonoSecurity::Mono.Security.X509;
+#else
+using MX = Mono.Security.X509;
+#endif
+
using System;
using System.Text;
+using System.Collections;
using System.Security;
using System.Security.Cryptography;
using System.Security.Cryptography.X509Certificates;
-using MX = Mono.Security.X509;
+using Mono.Security.Cryptography;
namespace Mono.Btls
{
return true;
}
- protected override byte [] GetCertHash (bool lazy)
+ protected override byte[] GetCertHash (bool lazy)
{
return X509.GetCertHash ();
}
- public override byte [] GetRawCertData ()
+ public override byte[] GetRawCertData ()
{
return X509.GetRawData (MonoBtlsX509Format.DER);
}
return PublicKey.EncodedParameters.RawData;
}
- public override byte [] Export (X509ContentType contentType, byte [] password)
+ public override byte[] Export (X509ContentType contentType, byte[] password)
{
ThrowIfContextInvalid ();
throw new InvalidOperationException ();
if (fallback != null)
return;
- fallback = X509Helper2.Import (GetRawCertData (), null, X509KeyStorageFlags.DefaultKeySet);
+ fallback = X509Helper2.Import (GetRawCertData (), null, X509KeyStorageFlags.DefaultKeySet, true);
}
- internal X509Certificate2Impl FallbackImpl {
+ internal override X509Certificate2Impl FallbackImpl {
get {
MustFallback ();
return fallback;
}
public override bool HasPrivateKey {
- get { return FallbackImpl.HasPrivateKey; }
+ get { return privateKey != null; }
}
public override X500DistinguishedName IssuerName {
}
public override AsymmetricAlgorithm PrivateKey {
- get { return FallbackImpl.PrivateKey; }
+ get {
+ if (privateKey == null || !privateKey.IsRsa)
+ return null;
+ var bytes = privateKey.GetBytes (true);
+ return PKCS8.PrivateKeyInfo.DecodeRSA (bytes);
+ }
set { FallbackImpl.PrivateKey = value; }
}
return FallbackImpl.GetNameInfo (nameType, forIssuer);
}
- public override void Import (byte [] data, string password, X509KeyStorageFlags keyStorageFlags)
+ public override void Import (byte[] data, string password, X509KeyStorageFlags keyStorageFlags)
{
if (password == null) {
- // Does it look like PEM?
- if ((data.Length > 0) && (data [0] != 0x30))
- x509 = MonoBtlsX509.LoadFromData (data, MonoBtlsX509Format.PEM);
- else
- x509 = MonoBtlsX509.LoadFromData (data, MonoBtlsX509Format.DER);
- return;
+ try {
+ Import (data);
+ } catch (Exception e) {
+ try {
+ ImportPkcs12 (data, null);
+ } catch {
+ string msg = Locale.GetText ("Unable to decode certificate.");
+ // inner exception is the original (not second) exception
+ throw new CryptographicException (msg, e);
+ }
+ }
+ } else {
+ // try PKCS#12
+ try {
+ ImportPkcs12 (data, password);
+ } catch (Exception e) {
+ try {
+ // it's possible to supply a (unrequired/unusued) password
+ // fix bug #79028
+ Import (data);
+ } catch {
+ string msg = Locale.GetText ("Unable to decode certificate.");
+ // inner exception is the original (not second) exception
+ throw new CryptographicException (msg, e);
+ }
+ }
}
+ }
+
+ void Import (byte[] data)
+ {
+ // Does it look like PEM?
+ if ((data.Length > 0) && (data [0] != 0x30))
+ x509 = MonoBtlsX509.LoadFromData (data, MonoBtlsX509Format.PEM);
+ else
+ x509 = MonoBtlsX509.LoadFromData (data, MonoBtlsX509Format.DER);
+ }
+ void ImportPkcs12 (byte[] data, string password)
+ {
using (var pkcs12 = new MonoBtlsPkcs12 ()) {
- pkcs12.Import (data, password);
+ if (string.IsNullOrEmpty (password)) {
+ try {
+ // Support both unencrypted PKCS#12..
+ pkcs12.Import (data, null);
+ } catch {
+ // ..and PKCS#12 encrypted with an empty password
+ pkcs12.Import (data, string.Empty);
+ }
+ } else {
+ pkcs12.Import (data, password);
+ }
+
x509 = pkcs12.GetCertificate (0);
if (pkcs12.HasPrivateKey)
privateKey = pkcs12.GetPrivateKey ();
}
}
- public override byte [] Export (X509ContentType contentType, string password)
+ public override byte[] Export (X509ContentType contentType, string password)
{
- return FallbackImpl.Export (contentType, password);
+ ThrowIfContextInvalid ();
+
+ switch (contentType) {
+ case X509ContentType.Cert:
+ return GetRawCertData ();
+ case X509ContentType.Pfx: // this includes Pkcs12
+ return ExportPkcs12 (password);
+ case X509ContentType.SerializedCert:
+ // TODO
+ throw new NotSupportedException ();
+ default:
+ string msg = Locale.GetText ("This certificate format '{0}' cannot be exported.", contentType);
+ throw new CryptographicException (msg);
+ }
+ }
+
+ byte[] ExportPkcs12 (string password)
+ {
+ var pfx = new MX.PKCS12 ();
+ try {
+ var attrs = new Hashtable ();
+ var localKeyId = new ArrayList ();
+ localKeyId.Add (new byte[] { 1, 0, 0, 0 });
+ attrs.Add (MX.PKCS9.localKeyId, localKeyId);
+ if (password != null)
+ pfx.Password = password;
+ pfx.AddCertificate (new MX.X509Certificate (GetRawCertData ()), attrs);
+ if (IntermediateCertificates != null) {
+ for (int i = 0; i < IntermediateCertificates.Count; i++)
+ pfx.AddCertificate (new MX.X509Certificate (IntermediateCertificates [i].GetRawCertData ()));
+ }
+ var privateKey = PrivateKey;
+ if (privateKey != null)
+ pfx.AddPkcs8ShroudedKeyBag (privateKey, attrs);
+ return pfx.GetBytes ();
+ } finally {
+ pfx.Password = null;
+ }
}
public override bool Verify (X509Certificate2 thisCertificate)
{
- return FallbackImpl.Verify (thisCertificate);
+ using (var chain = new MonoBtlsX509Chain ()) {
+ chain.AddCertificate (x509.Copy ());
+ if (intermediateCerts != null) {
+ for (int i = 0; i < intermediateCerts.Count; i++) {
+ var intermediate = (X509CertificateImplBtls)intermediateCerts [i];
+ chain.AddCertificate (intermediate.x509.Copy ());
+ }
+ }
+ return MonoBtlsProvider.ValidateCertificate (chain, null);
+ }
}
public override void Reset ()
}
internal X500DistinguishedName (byte[] encoded, byte[] canonEncoding, string name)
- : this (encoded)
{
this.canonEncoding = canonEncoding;
this.name = name;
// internal stuff because X509Certificate2 isn't complete enough
// (maybe X509Certificate3 will be better?)
- [Obsolete ("KILL")]
+ [MonoTODO ("See comment in X509Helper2.GetMonoCertificate().")]
internal MX.X509Certificate MonoCertificate {
get {
- var monoImpl = Impl as X509Certificate2ImplMono;
- if (monoImpl == null)
- throw new NotSupportedException ();
- return monoImpl.MonoCertificate;
+ return X509Helper2.GetMonoCertificate (this);
}
}
get;
}
+ internal abstract X509Certificate2Impl FallbackImpl {
+ get;
+ }
+
public abstract string GetNameInfo (X509NameType nameType, bool forIssuer);
public abstract void Import (byte[] rawData, string password, X509KeyStorageFlags keyStorageFlags);
[MonoTODO ("missing KeyStorageFlags support")]
public override void Import (byte[] rawData, string password, X509KeyStorageFlags keyStorageFlags)
{
+ Reset ();
MX.X509Certificate cert = null;
if (password == null) {
try {
internal MX.X509Certificate MonoCertificate {
get { return _cert; }
}
+
+ internal override X509Certificate2Impl FallbackImpl {
+ get { return this; }
+ }
}
}
#if MONO_SECURITY_ALIAS
using MonoSecurity::Mono.Security.Interface;
+using MX = MonoSecurity::Mono.Security.X509;
#else
#if !FEATURE_NO_BSD_SOCKETS
using Mono.Security.Interface;
#endif
+using MX = Mono.Security.X509;
#endif
#if !FEATURE_NO_BSD_SOCKETS
}
#endif // !FEATURE_NO_BSD_SOCKETS
- internal static X509Certificate2Impl Import (byte[] rawData, string password, X509KeyStorageFlags keyStorageFlags)
+ internal static X509Certificate2Impl Import (byte[] rawData, string password, X509KeyStorageFlags keyStorageFlags, bool disableProvider = false)
{
#if !FEATURE_NO_BSD_SOCKETS
- var provider = MonoTlsProviderFactory.GetProvider ();
- if (provider.HasNativeCertificates) {
- var impl = provider.GetNativeCertificate (rawData, password, keyStorageFlags);
- return impl;
+ if (!disableProvider) {
+ var provider = MonoTlsProviderFactory.GetProvider ();
+ if (provider.HasNativeCertificates) {
+ var impl = provider.GetNativeCertificate (rawData, password, keyStorageFlags);
+ return impl;
+ }
}
#endif // FEATURE_NO_BSD_SOCKETS
var impl2 = new X509Certificate2ImplMono ();
return impl2;
}
- internal static X509Certificate2Impl Import (X509Certificate cert)
+ internal static X509Certificate2Impl Import (X509Certificate cert, bool disableProvider = false)
{
#if !FEATURE_NO_BSD_SOCKETS
- var provider = MonoTlsProviderFactory.GetProvider ();
- if (provider.HasNativeCertificates) {
- var impl = provider.GetNativeCertificate (cert);
- return impl;
+ if (!disableProvider) {
+ var provider = MonoTlsProviderFactory.GetProvider ();
+ if (provider.HasNativeCertificates) {
+ var impl = provider.GetNativeCertificate (cert);
+ return impl;
+ }
}
#endif // FEATURE_NO_BSD_SOCKETS
var impl2 = cert.Impl as X509Certificate2Impl;
return Import (cert.GetRawCertData (), null, X509KeyStorageFlags.DefaultKeySet);
}
+ /*
+ * This is used by X509ChainImplMono
+ *
+ * Some of the missing APIs such as X509v3 extensions can be added to the native
+ * BTLS implementation.
+ *
+ * We should also consider replacing X509ChainImplMono with a new X509ChainImplBtls
+ * at some point.
+ */
+ [MonoTODO ("Investigate replacement; see comments in source.")]
+ internal static MX.X509Certificate GetMonoCertificate (X509Certificate2 certificate)
+ {
+ var impl2 = certificate.Impl as X509Certificate2Impl;
+ if (impl2 == null)
+ impl2 = Import (certificate, true);
+ var fallbackImpl = impl2.FallbackImpl as X509Certificate2ImplMono;
+ if (fallbackImpl == null)
+ throw new NotSupportedException ();
+ return fallbackImpl.MonoCertificate;
+ }
+
internal static X509ChainImpl CreateChainImpl (bool useMachineContext)
{
return new X509ChainImplMono (useMachineContext);
resources/collation.cjkKO.bin \
resources/collation.cjkKOlv2.bin
-REFERENCE_SOURCES_FLAGS = -d:FEATURE_PAL,GENERICS_WORK,FEATURE_LIST_PREDICATES,FEATURE_SERIALIZATION,FEATURE_ASCII,FEATURE_LATIN1,FEATURE_UTF7,FEATURE_UTF32,MONO_HYBRID_ENCODING_SUPPORT,FEATURE_ASYNC_IO,NEW_EXPERIMENTAL_ASYNC_IO,FEATURE_UTF32,FEATURE_EXCEPTIONDISPATCHINFO,FEATURE_CORRUPTING_EXCEPTIONS,FEATURE_EXCEPTION_NOTIFICATIONS,FEATURE_STRONGNAME_MIGRATION,FEATURE_USE_LCID,FEATURE_FUSION,FEATURE_CRYPTO,FEATURE_X509_SECURESTRINGS,FEATURE_SYNCHRONIZATIONCONTEXT,FEATURE_SYNCHRONIZATIONCONTEXT_WAIT
+REFERENCE_SOURCES_FLAGS = -d:FEATURE_PAL,GENERICS_WORK,FEATURE_LIST_PREDICATES,FEATURE_SERIALIZATION,FEATURE_ASCII,FEATURE_LATIN1,FEATURE_UTF7,FEATURE_UTF32,MONO_HYBRID_ENCODING_SUPPORT,FEATURE_ASYNC_IO,NEW_EXPERIMENTAL_ASYNC_IO,FEATURE_UTF32,FEATURE_EXCEPTIONDISPATCHINFO,FEATURE_CORRUPTING_EXCEPTIONS,FEATURE_EXCEPTION_NOTIFICATIONS,FEATURE_STRONGNAME_MIGRATION,FEATURE_USE_LCID,FEATURE_FUSION,FEATURE_CRYPTO,FEATURE_X509_SECURESTRINGS,FEATURE_SYNCHRONIZATIONCONTEXT,FEATURE_SYNCHRONIZATIONCONTEXT_WAIT,HAS_CORLIB_CONTRACTS
ifndef MOBILE_PROFILE
REFERENCE_SOURCES_FLAGS += -d:FEATURE_MACL
public void MakeArrayTypeTest ()
{
// This should not crash:
- typeof (void).MakeArrayType ();
+ Type t = typeof (void).MakeArrayType ();
}
+ [Test]
+ [ExpectedException (typeof (InvalidProgramException))]
+ public void MakeArrayTypedReferenceInstanceTest ()
+ {
+ object o = Array.CreateInstance (typeof (global::System.TypedReference), 1);
+ }
[ComVisible (true)]
public class ComFoo<T> {
--- /dev/null
+// TODO: Should be auto-generated from resources.resx
+
+static class SR
+{
+ public const string ArgumentException_ValueTupleIncorrectType = "The parameter should be a ValueTuple type of appropriate arity.";
+ public const string ArgumentException_ValueTupleLastArgumentNotAValueTuple = "The TRest type argument of ValueTuple`8 must be a ValueTuple.";
+}
\ No newline at end of file
ReferenceSources/SecurityContext.cs
ReferenceSources/PathInternal.cs
ReferenceSources/BinaryCompatibility.cs
+ReferenceSources/String.cs
+ReferenceSources/Type.cs
../referencesource/mscorlib/system/__filters.cs
../referencesource/mscorlib/system/__hresults.cs
../referencesource/mscorlib/microsoft/win32/safehandles/safewaithandle.cs
../referencesource/mscorlib/microsoft/win32/safehandles/win32safehandles.cs
-ReferenceSources/String.cs
-ReferenceSources/Type.cs
+corefx/SR.cs
+
+../../../external/corefx/src/Common/src/System/Numerics/Hashing/HashHelpers.cs
+
+../../../external/corefx/src/System.ValueTuple/src/System/ValueTuple/ValueTuple.cs
+../../../external/corefx/src/System.ValueTuple/src/System/ValueTuple/TupleExtensions.cs
+../../../external/corefx/src/System.ValueTuple/src/System/Runtime/CompilerServices/TupleElementNamesAttribute.cs
StreamReadMode outputStreamReadMode;
StreamReadMode errorStreamReadMode;
+#if MONO
+ StreamReadMode inputStreamReadMode;
+#endif
// Support for asynchrously reading streams
[Browsable(true), MonitoringDescription(SR.ProcessAssociated)]
throw new InvalidOperationException(SR.GetString(SR.CantGetStandardIn));
}
+#if MONO
+ inputStreamReadMode = StreamReadMode.syncMode;
+#endif
return standardInput;
}
}
machineName = ".";
raisedOnExited = false;
+#if MONO
+ //Call close on streams if the user never saw them.
+ //A stream in the undefined mode was never fetched by the user.
+ //A stream in the async mode is wrapped on a AsyncStreamReader and we should dispose that instead.
+ // no way for users to get a hand on a AsyncStreamReader.
+ var tmpIn = standardInput;
+ standardInput = null;
+ if (inputStreamReadMode == StreamReadMode.undefined && tmpIn != null)
+ tmpIn.Close ();
+
+ var tmpOut = standardOutput;
+ standardOutput = null;
+ if (outputStreamReadMode == StreamReadMode.undefined && tmpOut != null)
+ tmpOut.Close ();
+
+ tmpOut = standardError;
+ standardError = null;
+ if (errorStreamReadMode == StreamReadMode.undefined && tmpOut != null)
+ tmpOut.Close ();
+
+ var tmpAsync = output;
+ output = null;
+ if (outputStreamReadMode == StreamReadMode.asyncMode && tmpAsync != null)
+ tmpAsync.Close ();
+
+ tmpAsync = error;
+ error = null;
+ if (errorStreamReadMode == StreamReadMode.asyncMode && tmpAsync != null)
+ tmpAsync.Close ();
+#else
//Don't call close on the Readers and writers
//since they might be referenced by somebody else while the
//process is still alive but this method called.
output = null;
error = null;
+#endif
Refresh();
}
}
if (version_mismatch != null) {
- if (version_mismatch is AssemblyBuilder)
+ if (is_fx_assembly || version_mismatch is AssemblyBuilder)
return version_mismatch;
var ref_an = new AssemblyName (refname);
var v1 = ref_an.Version;
var v2 = version_mismatch.GetName ().Version;
+ AssemblyReferenceMessageInfo messageInfo;
if (v1 > v2) {
- var messageInfo = new AssemblyReferenceMessageInfo (ref_an, report => {
+ messageInfo = new AssemblyReferenceMessageInfo (ref_an, report => {
report.SymbolRelatedToPreviousError (args.RequestingAssembly.Location);
report.Error (1705, string.Format ("Assembly `{0}' depends on `{1}' which has a higher version number than referenced assembly `{2}'",
args.RequestingAssembly.FullName, refname, version_mismatch.GetName ().FullName));
});
- AddReferenceVersionMismatch (args.RequestingAssembly.GetName (), messageInfo);
- return version_mismatch;
- }
-
- if (!is_fx_assembly) {
- var messageInfo = new AssemblyReferenceMessageInfo (ref_an, report => {
+ } else {
+ messageInfo = new AssemblyReferenceMessageInfo (ref_an, report => {
if (v1.Major != v2.Major || v1.Minor != v2.Minor) {
report.Warning (1701, 2,
"Assuming assembly reference `{0}' matches assembly `{1}'. You may need to supply runtime policy",
refname, version_mismatch.GetName ().FullName);
}
});
-
- AddReferenceVersionMismatch (args.RequestingAssembly.GetName (), messageInfo);
}
+ AddReferenceVersionMismatch (args.RequestingAssembly.GetName (), messageInfo);
+
return version_mismatch;
}
protected virtual void InitializeAssembly (AssemblyDefinition assembly)
{
MarkAssembly (assembly);
- foreach (TypeDefinition type in assembly.MainModule.Types) {
- if (!Annotations.IsMarked (type))
- continue;
+ foreach (TypeDefinition type in assembly.MainModule.Types)
InitializeType (type);
- }
}
void InitializeType (TypeDefinition type)
{
+ if (type.HasNestedTypes) {
+ foreach (var nested in type.NestedTypes)
+ InitializeType (nested);
+ }
+
+ if (!Annotations.IsMarked (type))
+ return;
+
MarkType (type);
if (type.HasFields)
InitializeFields (type);
if (type.HasMethods)
InitializeMethods (type.Methods);
-
- if (type.HasNestedTypes) {
- foreach (var nested in type.NestedTypes) {
- if (Annotations.IsMarked (nested))
- InitializeType (nested);
- }
- }
}
void InitializeFields (TypeDefinition type)
MONO_PATH="$(topdir)/class/lib/$(PROFILE)$(PLATFORM_PATH_SEPARATOR)$$MONO_PATH" \
$(RUNTIME) $(RUNTIME_FLAGS)
+DIFF = diff -rup
+DIFF_QUIET = diff --brief
+ifeq ($(PLATFORM), win32)
+DIFF = diff -rupZ
+DIFF_QUIET = diff --brief -Z
+endif
+
dist-local: dist-default dist-tests
dist-tests:
$(MONO) $(PROGRAM) update --exceptions=all -o Test/en.actual Test/DocTest-addNonGeneric-v2.dll
$(MONO) $(PROGRAM) update --exceptions=all -o Test/en.actual Test/DocTest-addNonGeneric-v2.dll
$(MONO) $(PROGRAM) update --exceptions=all -o Test/en.actual Test/DocTest-addNonGeneric-v2.dll
- diff -rup Test/en.expected-addNonGeneric Test/en.actual
+ $(DIFF) Test/en.expected-addNonGeneric Test/en.actual
check-monodocer-dropns-classic: $(PROGRAM)
# tests the simplest --dropns case, a single class where the root namespace was dropped.
$(MAKE) Test/DocTest-DropNS-classic.dll
$(MONO) $(PROGRAM) update --exceptions=all -o Test/en.actual Test/DocTest-DropNS-classic.dll --api-style=classic
$(MAKE) update-monodocer-dropns-unified
- diff -rup Test/en.expected-dropns-classic-v1 Test/en.actual
+ $(DIFF) Test/en.expected-dropns-classic-v1 Test/en.actual
check-monodocer-dropns-multi: $(PROGRAM)
-rm -Rf Test/en.actual
$(MONO) $(PROGRAM) update --exceptions=all -o Test/en.actual $(MULTI-CLASSIC) --api-style=classic
$(MONO) $(PROGRAM) update --exceptions=all -o Test/en.actual $(MULTI-UNIFIED) --api-style=unified --dropns Test/DocTest-DropNS-unified.dll=MyFramework --dropns Test/DocTest-DropNS-unified-multitest.dll=MyFramework
- diff -rup Test/en.expected-dropns-multi Test/en.actual
+ $(DIFF) Test/en.expected-dropns-multi Test/en.actual
check-monodocer-dropns-multi-withexisting: $(PROGRAM)
$(MONO) $(PROGRAM) update --exceptions=all -o Test/en.actual $(MULTI-CLASSIC) --api-style=classic
$(MONO) $(PROGRAM) update --exceptions=all -o Test/en.actual $(MULTI-UNIFIED) --api-style=unified --dropns Test/DocTest-DropNS-unified.dll=MyFramework --dropns Test/DocTest-DropNS-unified-multitest.dll=MyFramework
- diff -rup Test/en.expected-dropns-multi-withexisting Test/en.actual
+ $(DIFF) Test/en.expected-dropns-multi-withexisting Test/en.actual
check-monodocer-dropns-delete: $(PROGRAM)
-rm -Rf Test/en.actual
$(MONO) $(PROGRAM) update --delete --exceptions=all -o Test/en.actual Test/DocTest-DropNS-classic-deletetest.dll --api-style=classic
$(MAKE) Test/DocTest-DropNS-unified-deletetest-V2.dll
$(MONO) $(PROGRAM) update --delete --exceptions=all -o Test/en.actual Test/DocTest-DropNS-unified-deletetest.dll --api-style=unified --dropns Test/DocTest-DropNS-unified-deletetest.dll=MyFramework
- diff -rup Test/en.expected-dropns-delete Test/en.actual
+ $(DIFF) Test/en.expected-dropns-delete Test/en.actual
check-monodocer-dropns-classic-withsecondary: $(PROGRAM)
# tests case where a secondary assembly is included with a --dropns parameter
$(MAKE) Test/DocTest-DropNS-classic-secondary.dll
$(MONO) $(PROGRAM) update --exceptions=all -o Test/en.actual Test/DocTest-DropNS-classic.dll Test/DocTest-DropNS-classic-secondary.dll --api-style=classic
$(MAKE) update-monodocer-dropns-unified-withsecondary
- diff -rup Test/en.expected-dropns-classic-withsecondary Test/en.actual
+ $(DIFF) Test/en.expected-dropns-classic-withsecondary Test/en.actual
update-monodocer-dropns-unified: $(PROGRAM)
$(MAKE) Test/DocTest-DropNS-unified.dll
-rm -Rf Test/en.actual
$(MAKE) Test/DocTest-InternalInterface.dll
$(MONO) $(PROGRAM) update --exceptions=all -o Test/en.actual Test/DocTest-InternalInterface.dll
- diff -rup Test/en.expected-internal-interface Test/en.actual
+ $(DIFF) Test/en.expected-internal-interface Test/en.actual
check-monodocer-enumerations: $(PROGRAM)
-rm -Rf Test/en.actual
$(MAKE) Test/DocTest-enumerations.dll
$(MONO) $(PROGRAM) update --exceptions=all -o Test/en.actual Test/DocTest-enumerations.dll
- diff -rup Test/en.expected-enumerations Test/en.actual
+ $(DIFF) Test/en.expected-enumerations Test/en.actual
check-monodocer-update: $(PROGRAM)
find Test/en.expected -name \*.xml -exec rm "{}" \;
-rm -Rf Test/en.actual
$(MAKE) Test/DocTest.dll-v1
$(MONO) $(PROGRAM) update --debug --exceptions=all -o Test/en.actual Test/DocTest.dll
- diff -rup Test/en.expected Test/en.actual
+ $(DIFF) Test/en.expected Test/en.actual
$(MONO) $(PROGRAM) update --debug --exceptions=all -o Test/en.actual Test/DocTest.dll
- diff -rup Test/en.expected Test/en.actual
+ $(DIFF) Test/en.expected Test/en.actual
check-monodocer-since-update: $(PROGRAM)
find Test/en.expected.since -name \*.xml -exec rm "{}" \;
$(MAKE) Test/DocTest.dll-v2
$(MONO) $(PROGRAM) --debug update --exceptions=all --since="Version 2.0" \
-o Test/en.actual Test/DocTest.dll
- diff -rup Test/en.expected.since Test/en.actual
+ $(DIFF) Test/en.expected.since Test/en.actual
check-monodocer-delete-update: $(PROGRAM)
find Test/en.expected.delete -type f -exec rm "{}" \;
$(MONO) $(PROGRAM) --debug update --exceptions=all -o Test/en.actual Test/DocTest.dll
$(MAKE) Test/DocTest.dll-v1
$(MONO) $(PROGRAM) --debug update -fno-assembly-versions --delete --exceptions=all -o Test/en.actual Test/DocTest.dll
- diff -rup Test/en.expected.delete Test/en.actual
+ $(DIFF) Test/en.expected.delete Test/en.actual
check-monodocer-importslashdoc-update: $(PROGRAM)
find Test/en.expected.importslashdoc -name \*.xml -exec rm "{}" \;
$(MAKE) Test/DocTest.dll-v1 TEST_CSCFLAGS=-doc:Test/DocTest.xml
$(MONO) $(PROGRAM) --debug update --exceptions=all -i Test/DocTest.xml \
-o Test/en.actual Test/DocTest.dll
- diff -rup Test/en.expected.importslashdoc Test/en.actual
+ $(DIFF) Test/en.expected.importslashdoc Test/en.actual
check-monodocer-importecmadoc-update: $(PROGRAM)
find Test/en.expected.importecmadoc -name \*.xml -exec rm "{}" \;
'--type=System.Action`1' --type=System.AsyncCallback \
--type=System.Environment --type=System.Array \
-o Test/en.actual Test/DocTest.dll
- diff -rup Test/en.expected.importecmadoc Test/en.actual
+ $(DIFF) Test/en.expected.importecmadoc Test/en.actual
check-mdoc-export-html-update: $(PROGRAM)
find Test/html.expected -name \*.html -exec rm "{}" \;
rm -Rf Test/html.actual
$(MONO) $(PROGRAM) export-html -o Test/html.actual \
Test/en.expected.importslashdoc
- diff -rup Test/html.expected Test/html.actual
+ $(DIFF) Test/html.expected Test/html.actual
check-mdoc-export-html-with-version: $(PROGRAM)
rm -Rf Test/html.actual.v0 Test/html.actual.since-with-v0 .v0.txt .v2.txt
Test/en.expected.since -with-version 0.0.0.0
(cd Test/html.actual.v0 && find . -type f) | sort > .v0.txt
(cd Test/html.actual.since-with-v0 && find . -type f) | sort > .v2.txt
- diff -rup .v0.txt .v2.txt # assert no types added
+ $(DIFF) .v0.txt .v2.txt # assert no types added
check-md-html-dir: $(PROGRAM)
rm -Rf Test/html.actual
$(MONO) $(PROGRAM) export-html -dest:Test/html.actual $(DIR)
- diff -rup Test/html.expected Test/html.actual
+ $(DIFF) Test/html.expected Test/html.actual
check-mdoc-export-msxdoc-update:
$(MONO) $(PROGRAM) export-msxdoc -o - Test/en.expected.importslashdoc \
check-mdoc-export-msxdoc:
$(MONO) $(PROGRAM) export-msxdoc -o - Test/en.expected.importslashdoc \
- | diff --brief - Test/msxdoc-expected.importslashdoc.xml
+ | $(DIFF_QUIET) - Test/msxdoc-expected.importslashdoc.xml
my_abs_top_srcdir = $(shell cd . && pwd)
check-mdoc-validate: $(PROGRAM)
$(MONO) $(PROGRAM) validate -f ecma Test/en.expected 2>&1 | \
sed 's#file://$(my_abs_top_srcdir)/##g' | \
- diff - Test/validate.check.monodocer
+ $(DIFF_QUIET) - Test/validate.check.monodocer
$(MONO) $(PROGRAM) validate -f ecma Test/en.expected.importslashdoc 2>&1 | \
sed 's#file://$(my_abs_top_srcdir)/##g' | \
- diff --brief - Test/validate.check.monodocer.importslashdoc
+ $(DIFF_QUIET) - Test/validate.check.monodocer.importslashdoc
$(MONO) $(PROGRAM) validate -f ecma Test/en.expected.since 2>&1 | \
sed 's#file://$(my_abs_top_srcdir)/##g' | \
- diff --brief - Test/validate.check.monodocer.since
+ $(DIFF_QUIET) - Test/validate.check.monodocer.since
run-test-local: check-doc-tools
}
int
-mono_btls_x509_name_get_entry_value (MonoBtlsX509Name *name, int index, unsigned char **str)
+mono_btls_x509_name_get_entry_value (MonoBtlsX509Name *name, int index, int *tag, unsigned char **str)
{
X509_NAME_ENTRY *entry;
ASN1_STRING *data;
*str = NULL;
+ *tag = 0;
if (index >= X509_NAME_entry_count (name->name))
return 0;
if (!data)
return 0;
+ *tag = data->type;
return ASN1_STRING_to_UTF8 (str, data);
}
mono_btls_x509_name_get_entry_oid_data (MonoBtlsX509Name *name, int index, const void **data);
int
-mono_btls_x509_name_get_entry_value (MonoBtlsX509Name *name, int index, unsigned char **str);
+mono_btls_x509_name_get_entry_value (MonoBtlsX509Name *name, int index, int *tag, unsigned char **str);
#endif /* __btls__btls_x509_name__ */
int pid;
struct MonoProcess *p;
- MONO_TRACE (G_LOG_LEVEL_DEBUG, MONO_TRACE_IO_LAYER, "SIG CHILD handler for pid: %i\n", info->si_pid);
-
do {
do {
pid = waitpid (-1, &status, WNOHANG);
if (pid <= 0)
break;
- MONO_TRACE (G_LOG_LEVEL_DEBUG, MONO_TRACE_IO_LAYER, "child ended: %i", pid);
-
/*
* This can run concurrently with the code in the rest of this module.
*/
p->freeable = TRUE;
}
} while (1);
-
- MONO_TRACE (G_LOG_LEVEL_DEBUG, MONO_TRACE_IO_LAYER, "SIG CHILD handler: done looping.");
}
#endif
guint has_finalize_inited : 1; /* has_finalize is initialized */
guint fields_inited : 1; /* fields is initialized */
guint setup_fields_called : 1; /* to prevent infinite loops in setup_fields */
-
- guint8 exception_type; /* MONO_EXCEPTION_* */
-
- /* Additional information about the exception */
- /* Stored as property MONO_CLASS_PROP_EXCEPTION_DATA */
- //void *exception_data;
+ guint has_failure : 1; /* See MONO_CLASS_PROP_EXCEPTION_DATA for a MonoErrorBoxed with the details */
MonoClass *parent;
MonoClass *nested_in;
mono_lookup_jit_icall_symbol (const char *name);
gboolean
-mono_class_set_failure (MonoClass *klass, guint32 ex_type, void *ex_data);
-
-gpointer
-mono_class_get_exception_data (MonoClass *klass);
+mono_class_set_type_load_failure (MonoClass *klass, const char * fmt, ...) MONO_ATTR_FORMAT_PRINTF(2,3);
MonoException*
mono_class_get_exception_for_failure (MonoClass *klass);
mono_class_try_load_from_name (MonoImage *image, const char* name_space, const char *name);
void
-mono_error_set_for_class_failure (MonoError *orerror, MonoClass *klass);
+mono_error_set_for_class_failure (MonoError *orerror, const MonoClass *klass);
-static inline guint8
-mono_class_get_failure (MonoClass *klass)
-{
- g_assert (klass != NULL);
- return klass->exception_type;
-}
-
-static inline gboolean
-mono_class_has_failure (MonoClass *klass)
-{
- g_assert (klass != NULL);
- return mono_class_get_failure (klass) != MONO_EXCEPTION_NONE;
-}
+gboolean
+mono_class_has_failure (const MonoClass *klass);
#endif /* __MONO_METADATA_CLASS_INTERNALS_H__ */
static void mono_class_setup_vtable_full (MonoClass *klass, GList *in_setup);
static void mono_generic_class_setup_parent (MonoClass *klass, MonoClass *gklass);
+static gboolean mono_class_set_failure (MonoClass *klass, MonoErrorBoxed *boxed_error);
+static gpointer mono_class_get_exception_data (const MonoClass *klass);
+
+
/*
We use gclass recording to allow recursive system f types to be referenced by a parent.
}
/*
- * Checks for MonoClass::exception_type without resolving all MonoType's into MonoClass'es
+ * Checks for MonoClass::has_failure without resolving all MonoType's into MonoClass'es
*/
static gboolean
mono_type_has_exceptions (MonoType *type)
}
void
-mono_error_set_for_class_failure (MonoError *oerror, MonoClass *klass)
+mono_error_set_for_class_failure (MonoError *oerror, const MonoClass *klass)
{
- gpointer exception_data = mono_class_get_exception_data (klass);
-
- switch (mono_class_get_failure(klass)) {
- case MONO_EXCEPTION_TYPE_LOAD: {
- mono_error_set_type_load_class (oerror, klass, "Error Loading class");
- return;
- }
- case MONO_EXCEPTION_INVALID_PROGRAM: {
- mono_error_set_invalid_program (oerror, "%s", (const char *)exception_data);
- return;
- }
- case MONO_EXCEPTION_MISSING_METHOD:
- case MONO_EXCEPTION_MISSING_FIELD:
- case MONO_EXCEPTION_FILE_NOT_FOUND:
- case MONO_EXCEPTION_BAD_IMAGE:
- default:
- g_assert_not_reached ();
- }
+ g_assert (mono_class_has_failure (klass));
+ MonoErrorBoxed *box = (MonoErrorBoxed*)mono_class_get_exception_data (klass);
+ mono_error_set_from_boxed (oerror, box);
}
}
}
+/**
+ * mono_class_set_failure_causedby_class:
+ * @klass: the class that is failing
+ * @caused_by: the class that caused the failure
+ * @msg: Why @klass is failing.
+ *
+ * If @caused_by has a failure, sets a TypeLoadException failure on
+ * @klass with message "@msg, due to: {@caused_by message}".
+ *
+ * Returns: TRUE if a failiure was set, or FALSE if @caused_by doesn't have a failure.
+ */
+static gboolean
+mono_class_set_type_load_failure_causedby_class (MonoClass *klass, const MonoClass *caused_by, const gchar* msg)
+{
+ if (mono_class_has_failure (caused_by)) {
+ MonoError cause_error;
+ mono_error_init (&cause_error);
+ mono_error_set_for_class_failure (&cause_error, caused_by);
+ mono_class_set_type_load_failure (klass, "%s, due to: %s", msg, mono_error_get_message (&cause_error));
+ mono_error_cleanup (&cause_error);
+ return TRUE;
+ } else {
+ return FALSE;
+ }
+}
+
+
/**
* mono_class_setup_fields:
* @class: The class to initialize
if (gtd) {
mono_class_setup_fields (gtd);
- if (mono_class_has_failure (gtd)) {
- mono_class_set_failure (klass, MONO_EXCEPTION_TYPE_LOAD, NULL);
+ if (mono_class_set_type_load_failure_causedby_class (klass, gtd, "Generic type definition failed"))
return;
- }
}
instance_size = 0;
mono_class_init (klass->parent);
if (!klass->parent->size_inited) {
mono_class_setup_fields (klass->parent);
- if (mono_class_has_failure (klass->parent)) {
- mono_class_set_failure (klass, MONO_EXCEPTION_TYPE_LOAD, NULL);
+ if (mono_class_set_type_load_failure_causedby_class (klass, klass->parent, "Could not set up parent class"))
return;
- }
}
instance_size += klass->parent->instance_size;
klass->min_align = klass->parent->min_align;
if (explicit_size) {
if ((packing_size & 0xffffff00) != 0) {
- char *err_msg = g_strdup_printf ("Could not load struct '%s' with packing size %d >= 256", klass->name, packing_size);
- mono_class_set_failure (klass, MONO_EXCEPTION_TYPE_LOAD, err_msg);
+ mono_class_set_type_load_failure (klass, "Could not load struct '%s' with packing size %d >= 256", klass->name, packing_size);
return;
}
klass->packing_size = packing_size;
field->offset = offset;
if (field->offset == (guint32)-1 && !(field->type->attrs & FIELD_ATTRIBUTE_STATIC)) {
- mono_class_set_failure (klass, MONO_EXCEPTION_TYPE_LOAD, mono_image_strdup_printf (klass->image, "Missing field layout info for %s", field->name));
+ mono_class_set_type_load_failure (klass, "Missing field layout info for %s", field->name);
break;
}
if (field->offset < -1) { /*-1 is used to encode special static fields */
- mono_class_set_failure (klass, MONO_EXCEPTION_TYPE_LOAD, mono_image_strdup_printf (klass->image, "Invalid negative field offset %d for %s", field->offset, field->name));
+ mono_class_set_type_load_failure (klass, "Field '%s' has a negative offset %d", field->name, field->offset);
break;
}
if (klass->generic_container) {
- mono_class_set_failure (klass, MONO_EXCEPTION_TYPE_LOAD, mono_image_strdup_printf (klass->image, "Generic class cannot have explicit layout."));
+ mono_class_set_type_load_failure (klass, "Generic class cannot have explicit layout.");
break;
}
}
if (field_class) {
mono_class_setup_fields (field_class);
if (mono_class_has_failure (field_class)) {
- mono_class_set_failure (klass, MONO_EXCEPTION_TYPE_LOAD, NULL);
+ MonoError field_error;
+ mono_error_init (&field_error);
+ mono_error_set_for_class_failure (&field_error, field_class);
+ mono_class_set_type_load_failure (klass, "Could not set up field '%s' due to: %s", field->name, mono_error_get_message (&field_error));
+ mono_error_cleanup (&field_error);
break;
}
}
char *class_name = mono_type_get_full_name (klass);
char *type_name = mono_type_full_name (field->type);
- mono_class_set_failure (klass, MONO_EXCEPTION_TYPE_LOAD, NULL);
+ mono_class_set_type_load_failure (klass, "");
g_warning ("Invalid type %s for instance field %s:%s", type_name, class_name, field->name);
g_free (class_name);
g_free (type_name);
klass->blittable = blittable;
if (klass->enumtype && !mono_class_enum_basetype (klass)) {
- mono_class_set_failure (klass, MONO_EXCEPTION_TYPE_LOAD, NULL);
+ mono_class_set_type_load_failure (klass, "The enumeration's base type is invalid.");
return;
}
if (explicit_size && real_size) {
/*valuetypes can't be neither bigger than 1Mb or empty. */
if (klass->valuetype && (klass->instance_size <= 0 || klass->instance_size > (0x100000 + sizeof (MonoObject))))
- mono_class_set_failure (klass, MONO_EXCEPTION_TYPE_LOAD, NULL);
+ mono_class_set_type_load_failure (klass, "Value type instance size (%d) cannot be zero, negative, or bigger than 1Mb", klass->instance_size);
mono_memory_barrier ();
klass->fields_inited = 1;
if (klass->parent) {
mono_class_setup_fields (klass->parent);
- if (mono_class_has_failure (klass->parent)) {
- mono_class_set_failure (klass, MONO_EXCEPTION_TYPE_LOAD, NULL);
+ if (mono_class_set_type_load_failure_causedby_class (klass, klass->parent, "Cannot initialize parent class"))
return;
- }
real_size = klass->parent->instance_size;
} else {
real_size = sizeof (MonoObject);
ftype = mono_type_get_basic_type_from_generic (ftype);
if (type_has_references (klass, ftype)) {
if (field->offset % sizeof (gpointer)) {
- mono_class_set_failure (klass, MONO_EXCEPTION_TYPE_LOAD, NULL);
+ mono_class_set_type_load_failure (klass, "Reference typed field '%s' has explicit offset that is not pointer-size aligned.", field->name);
}
}
// FIXME: Too much code does this
#if 0
if (!MONO_TYPE_IS_REFERENCE (field->type) && ref_bitmap [field->offset / sizeof (gpointer)]) {
- char *err_msg = mono_image_strdup_printf (klass->image, "Could not load type '%s' because it contains an object field at offset %d that is incorrectly aligned or overlapped by a non-object field.", klass->name, field->offset);
- mono_class_set_failure (klass, MONO_EXCEPTION_TYPE_LOAD, err_msg);
+ mono_class_set_type_load_failure (klass, "Could not load type '%s' because it contains an object field at offset %d that is incorrectly aligned or overlapped by a non-object field.", klass->name, field->offset);
}
#endif
}
continue;
if (mono_type_has_exceptions (field->type)) {
- mono_class_set_failure (klass, MONO_EXCEPTION_TYPE_LOAD, NULL);
+ mono_class_set_type_load_failure (klass, "Field '%s' has an invalid type.", field->name);
break;
}
* Methods belonging to an interface are assigned a sequential slot starting
* from 0.
*
- * On failure this function sets klass->exception_type
+ * On failure this function sets klass->has_failure and stores a MonoErrorBoxed with details
*/
void
mono_class_setup_methods (MonoClass *klass)
mono_class_init (gklass);
if (!mono_class_has_failure (gklass))
mono_class_setup_methods (gklass);
- if (mono_class_has_failure (gklass)) {
- /* FIXME make exception_data less opaque so it's possible to dup it here */
- mono_class_set_failure (klass, MONO_EXCEPTION_TYPE_LOAD, mono_image_strdup (klass->image, "Generic type definition failed to load"));
+ if (mono_class_set_type_load_failure_causedby_class (klass, gklass, "Generic type definition failed to load"))
return;
- }
/* The + 1 makes this always non-NULL to pass the check in mono_class_setup_methods () */
count = gklass->method.count;
gklass->methods [i], klass, mono_class_get_context (klass), &error);
if (!mono_error_ok (&error)) {
char *method = mono_method_full_name (gklass->methods [i], TRUE);
- mono_class_set_failure (klass, MONO_EXCEPTION_TYPE_LOAD, mono_image_strdup_printf (klass->image, "Could not inflate method %s due to %s", method, mono_error_get_message (&error)));
+ mono_class_set_type_load_failure (klass, "Could not inflate method %s due to %s", method, mono_error_get_message (&error));
g_free (method);
mono_error_cleanup (&error);
int idx = mono_metadata_translate_token_index (klass->image, MONO_TABLE_METHOD, klass->method.first + i + 1);
methods [i] = mono_get_method_checked (klass->image, MONO_TOKEN_METHOD_DEF | idx, klass, NULL, &error);
if (!methods [i]) {
- mono_class_set_failure (klass, MONO_EXCEPTION_TYPE_LOAD, mono_image_strdup_printf (klass->image, "Could not load method %d due to %s", i, mono_error_get_message (&error)));
+ mono_class_set_type_load_failure (klass, "Could not load method %d due to %s", i, mono_error_get_message (&error));
mono_error_cleanup (&error);
}
}
mono_class_init (gklass);
mono_class_setup_properties (gklass);
- if (mono_class_has_failure (gklass)) {
- mono_class_set_failure (klass, MONO_EXCEPTION_TYPE_LOAD, mono_image_strdup (klass->image, "Generic type definition failed to load"));
+ if (mono_class_set_type_load_failure_causedby_class (klass, gklass, "Generic type definition failed to load"))
return;
- }
properties = mono_class_new0 (klass, MonoProperty, gklass->ext->property.count + 1);
MonoGenericContext *context = NULL;
mono_class_setup_events (gklass);
- if (mono_class_has_failure (gklass)) {
- mono_class_set_failure (klass, MONO_EXCEPTION_TYPE_LOAD, mono_image_strdup (klass->image, "Generic type definition failed to load"));
+ if (mono_class_set_type_load_failure_causedby_class (klass, gklass, "Generic type definition failed to load"))
return;
- }
first = gklass->ext->event.first;
count = gklass->ext->event.count;
if (count) {
mono_class_setup_methods (klass);
if (mono_class_has_failure (klass)) {
- mono_class_set_failure (klass, MONO_EXCEPTION_TYPE_LOAD, mono_image_strdup (klass->image, "Generic type definition failed to load"));
return;
}
}
/*
* LOCKING: this is supposed to be called with the loader lock held.
- * Return -1 on failure and set exception_type
+ * Return -1 on failure and set klass->has_failure and store a MonoErrorBoxed with the details.
*/
static int
setup_interface_offsets (MonoClass *klass, int cur_slot, gboolean overwrite)
ifaces = mono_class_get_implemented_interfaces (k, &error);
if (!mono_error_ok (&error)) {
char *name = mono_type_get_full_name (k);
- mono_class_set_failure (klass, MONO_EXCEPTION_TYPE_LOAD, mono_image_strdup_printf (klass->image, "Error getting the interfaces of %s due to %s", name, mono_error_get_message (&error)));
+ mono_class_set_type_load_failure (klass, "Error getting the interfaces of %s due to %s", name, mono_error_get_message (&error));
g_free (name);
mono_error_cleanup (&error);
cur_slot = -1;
count = count_virtual_methods (ic);
if (count == -1) {
char *name = mono_type_get_full_name (ic);
- mono_class_set_failure (klass, MONO_EXCEPTION_TYPE_LOAD, mono_image_strdup_printf (klass->image, "Error calculating interface offset of %s", name));
+ mono_class_set_type_load_failure (klass, "Error calculating interface offset of %s", name);
g_free (name);
cur_slot = -1;
goto end;
}
mono_class_setup_vtable_full (mono_class_get_generic_type_definition (klass), in_setup);
- if (mono_class_has_failure (klass->generic_class->container_class)) {
- mono_class_set_failure (klass, MONO_EXCEPTION_TYPE_LOAD, mono_image_strdup (klass->image, "Failed to load generic definition vtable"));
+ if (mono_class_set_type_load_failure_causedby_class (klass, klass->generic_class->container_class, "Failed to load generic definition vtable"))
return FALSE;
- }
ginst = klass->generic_class->context.class_inst;
for (i = 0; i < ginst->type_argc; ++i) {
if (mono_class_has_gtd_parent (klass, arg) || mono_class_has_gtd_parent (arg, klass))
continue;
if (!mono_class_check_vtable_constraints (arg, in_setup)) {
- mono_class_set_failure (klass, MONO_EXCEPTION_TYPE_LOAD, mono_image_strdup_printf (klass->image, "Failed to load generic parameter %d", i));
+ mono_class_set_type_load_failure (klass, "Failed to load generic parameter %d", i);
return FALSE;
}
}
* - vtable
* - vtable_size
* Plus all the fields initialized by setup_interface_offsets ().
- * If there is an error during vtable construction, klass->exception_type is set.
+ * If there is an error during vtable construction, klass->has_failure
+ * is set and details are stored in a MonoErrorBoxed.
*
* LOCKING: Acquires the loader lock.
*/
if (!is_ok (&error)) {
mono_loader_unlock ();
g_list_remove (in_setup, klass);
- mono_class_set_failure (klass, MONO_EXCEPTION_TYPE_LOAD, mono_image_strdup_printf(klass->image, "Could not load list of method overrides due to %s", mono_error_get_message (&error)));
+ mono_class_set_type_load_failure (klass, "Could not load list of method overrides due to %s", mono_error_get_message (&error));
mono_error_cleanup (&error);
return;
}
if (ok)
mono_class_setup_vtable_general (klass, overrides, onum, in_setup);
else
- mono_class_set_failure (klass, MONO_EXCEPTION_TYPE_LOAD, mono_image_strdup (klass->image, "Could not load list of method overrides"));
+ mono_class_set_type_load_failure (klass, "Could not load list of method overrides");
g_free (overrides);
cmsig = mono_method_signature (cm);
imsig = mono_method_signature (im);
if (!cmsig || !imsig) {
- mono_class_set_failure (klass, MONO_EXCEPTION_TYPE_LOAD, mono_image_strdup (klass->image, "Could not resolve the signature of a virtual method"));
+ mono_class_set_type_load_failure (klass, "Could not resolve the signature of a virtual method");
return FALSE;
}
if (is_wcf_hack_disabled () && !mono_method_can_access_method_full (cm, im, NULL)) {
char *body_name = mono_method_full_name (cm, TRUE);
char *decl_name = mono_method_full_name (im, TRUE);
- mono_class_set_failure (klass, MONO_EXCEPTION_TYPE_LOAD, mono_image_strdup_printf (klass->image, "Method %s overrides method '%s' which is not accessible", body_name, decl_name));
+ mono_class_set_type_load_failure (klass, "Method %s overrides method '%s' which is not accessible", body_name, decl_name);
g_free (body_name);
g_free (decl_name);
return FALSE;
cmsig = mono_method_signature (cm);
imsig = mono_method_signature (im);
if (!cmsig || !imsig) {
- mono_class_set_failure (klass, MONO_EXCEPTION_TYPE_LOAD, mono_image_strdup (klass->image, "Could not resolve the signature of a virtual method"));
+ mono_class_set_type_load_failure (klass, "Could not resolve the signature of a virtual method");
return FALSE;
}
if (is_wcf_hack_disabled () && !mono_method_can_access_method_full (cm, im, NULL)) {
char *body_name = mono_method_full_name (cm, TRUE);
char *decl_name = mono_method_full_name (im, TRUE);
- mono_class_set_failure (klass, MONO_EXCEPTION_TYPE_LOAD, mono_image_strdup_printf (klass->image, "Method %s overrides method '%s' which is not accessible", body_name, decl_name));
+ mono_class_set_type_load_failure (klass, "Method %s overrides method '%s' which is not accessible", body_name, decl_name);
g_free (body_name);
g_free (decl_name);
return FALSE;
MonoMethod *body = overrides [i * 2 + 1];
if (mono_class_get_generic_type_definition (body->klass) != mono_class_get_generic_type_definition (klass)) {
- mono_class_set_failure (klass, MONO_EXCEPTION_TYPE_LOAD, mono_image_strdup (klass->image, "Method belongs to a different class than the declared one"));
+ mono_class_set_type_load_failure (klass, "Method belongs to a different class than the declared one");
return FALSE;
}
if (!(body->flags & METHOD_ATTRIBUTE_VIRTUAL) || (body->flags & METHOD_ATTRIBUTE_STATIC)) {
if (body->flags & METHOD_ATTRIBUTE_STATIC)
- mono_class_set_failure (klass, MONO_EXCEPTION_TYPE_LOAD, mono_image_strdup (klass->image, "Method must not be static to override a base type"));
+ mono_class_set_type_load_failure (klass, "Method must not be static to override a base type");
else
- mono_class_set_failure (klass, MONO_EXCEPTION_TYPE_LOAD, mono_image_strdup (klass->image, "Method must be virtual to override a base type"));
+ mono_class_set_type_load_failure (klass, "Method must be virtual to override a base type");
return FALSE;
}
if (!(decl->flags & METHOD_ATTRIBUTE_VIRTUAL) || (decl->flags & METHOD_ATTRIBUTE_STATIC)) {
if (body->flags & METHOD_ATTRIBUTE_STATIC)
- mono_class_set_failure (klass, MONO_EXCEPTION_TYPE_LOAD, mono_image_strdup (klass->image, "Cannot override a static method in a base type"));
+ mono_class_set_type_load_failure (klass, "Cannot override a static method in a base type");
else
- mono_class_set_failure (klass, MONO_EXCEPTION_TYPE_LOAD, mono_image_strdup (klass->image, "Cannot override a non virtual method in a base type"));
+ mono_class_set_type_load_failure (klass, "Cannot override a non virtual method in a base type");
return FALSE;
}
if (!mono_class_is_assignable_from_slow (decl->klass, klass)) {
- mono_class_set_failure (klass, MONO_EXCEPTION_TYPE_LOAD, mono_image_strdup (klass->image, "Method overrides a class or interface that is not extended or implemented by this type"));
+ mono_class_set_type_load_failure (klass, "Method overrides a class or interface that is not extended or implemented by this type");
return FALSE;
}
if (is_wcf_hack_disabled () && !mono_method_can_access_method_full (body, decl, NULL)) {
char *body_name = mono_method_full_name (body, TRUE);
char *decl_name = mono_method_full_name (decl, TRUE);
- mono_class_set_failure (klass, MONO_EXCEPTION_TYPE_LOAD, mono_image_strdup_printf (klass->image, "Method %s overrides method '%s' which is not accessible", body_name, decl_name));
+ mono_class_set_type_load_failure (klass, "Method %s overrides method '%s' which is not accessible", body_name, decl_name);
g_free (body_name);
g_free (decl_name);
return FALSE;
ifaces = mono_class_get_implemented_interfaces (klass, &error);
if (!mono_error_ok (&error)) {
char *name = mono_type_get_full_name (klass);
- mono_class_set_failure (klass, MONO_EXCEPTION_TYPE_LOAD, mono_image_strdup_printf (klass->image, "Could not resolve %s interfaces due to %s", name, mono_error_get_message (&error)));
+ mono_class_set_type_load_failure (klass, "Could not resolve %s interfaces due to %s", name, mono_error_get_message (&error));
g_free (name);
mono_error_cleanup (&error);
return;
mono_class_init (klass->parent);
mono_class_setup_vtable_full (klass->parent, in_setup);
- if (mono_class_has_failure (klass->parent)) {
- char *name = mono_type_get_full_name (klass->parent);
- mono_class_set_failure (klass, MONO_EXCEPTION_TYPE_LOAD, mono_image_strdup_printf (klass->image, "Parent %s failed to load", name));
- g_free (name);
+ if (mono_class_set_type_load_failure_causedby_class (klass, klass->parent, "Parent class failed to load"))
return;
- }
max_vtsize += klass->parent->vtable_size;
cur_slot = klass->parent->vtable_size;
MonoMethod **tmp;
mono_class_setup_vtable_full (gklass, in_setup);
- if (mono_class_has_failure (gklass)) {
- mono_class_set_failure (klass, MONO_EXCEPTION_TYPE_LOAD, NULL);
+ if (mono_class_set_type_load_failure_causedby_class (klass, gklass, "Could not load generic definition"))
return;
- }
tmp = (MonoMethod **)mono_class_alloc0 (klass, sizeof (gpointer) * gklass->vtable_size);
klass->vtable_size = gklass->vtable_size;
if (gklass->vtable [i]) {
MonoMethod *inflated = mono_class_inflate_generic_method_full_checked (gklass->vtable [i], klass, mono_class_get_context (klass), &error);
if (!mono_error_ok (&error)) {
- char *err_msg = mono_image_strdup_printf (klass->image, "Could not inflate method due to %s", mono_error_get_message (&error));
- mono_class_set_failure (klass, MONO_EXCEPTION_TYPE_LOAD, err_msg);
+ mono_class_set_type_load_failure (klass, "Could not inflate method due to %s", mono_error_get_message (&error));
mono_error_cleanup (&error);
return;
}
int dslot;
dslot = mono_method_get_vtable_slot (decl);
if (dslot == -1) {
- mono_class_set_failure (klass, MONO_EXCEPTION_TYPE_LOAD, NULL);
+ mono_class_set_type_load_failure (klass, "");
return;
}
m1sig = mono_method_signature (m1);
if (!cmsig || !m1sig) {
- mono_class_set_failure (klass, MONO_EXCEPTION_TYPE_LOAD, NULL);
+ /* FIXME proper error message */
+ mono_class_set_type_load_failure (klass, "");
return;
}
if (is_wcf_hack_disabled () && !mono_method_can_access_method_full (cm, m1, NULL)) {
char *body_name = mono_method_full_name (cm, TRUE);
char *decl_name = mono_method_full_name (m1, TRUE);
- mono_class_set_failure (klass, MONO_EXCEPTION_TYPE_LOAD, mono_image_strdup_printf (klass->image, "Method %s overrides method '%s' which is not accessible", body_name, decl_name));
+ mono_class_set_type_load_failure (klass, "Method %s overrides method '%s' which is not accessible", body_name, decl_name);
g_free (body_name);
g_free (decl_name);
goto fail;
if (vtable [i] == NULL || (vtable [i]->flags & (METHOD_ATTRIBUTE_ABSTRACT | METHOD_ATTRIBUTE_STATIC))) {
char *type_name = mono_type_get_full_name (klass);
char *method_name = vtable [i] ? mono_method_full_name (vtable [i], TRUE) : g_strdup ("none");
- mono_class_set_failure (klass, MONO_EXCEPTION_TYPE_LOAD, mono_image_strdup_printf (klass->image, "Type %s has invalid vtable method slot %d with method %s", type_name, i, method_name));
+ mono_class_set_type_load_failure (klass, "Type %s has invalid vtable method slot %d with method %s", type_name, i, method_name);
g_free (type_name);
g_free (method_name);
return;
fail:
{
char *name = mono_type_get_full_name (klass);
- mono_class_set_failure (klass, MONO_EXCEPTION_TYPE_LOAD, mono_image_strdup_printf (klass->image, "VTable setup of type %s failed", name));
+ mono_class_set_type_load_failure (klass, "VTable setup of type %s failed", name);
g_free (name);
if (override_map)
g_hash_table_destroy (override_map);
}
if (klass->init_pending) {
- mono_class_set_failure (klass, MONO_EXCEPTION_TYPE_LOAD, mono_image_strdup (klass->image, "Recursive type definition detected"));
+ mono_class_set_type_load_failure (klass, "Recursive type definition detected");
goto leave;
}
klass->init_pending = 1;
if (mono_verifier_is_enabled_for_class (klass) && !mono_verifier_verify_class (klass)) {
- mono_class_set_failure (klass, MONO_EXCEPTION_TYPE_LOAD, concat_two_strings_with_zero (klass->image, klass->name, klass->image->assembly_name));
+ mono_class_set_type_load_failure (klass, "%s", concat_two_strings_with_zero (klass->image, klass->name, klass->image->assembly_name));
goto leave;
}
MonoClass *element_class = klass->element_class;
if (!element_class->inited)
mono_class_init (element_class);
- if (mono_class_has_failure (element_class)) {
- mono_class_set_failure (klass, MONO_EXCEPTION_TYPE_LOAD, NULL);
+ if (mono_class_set_type_load_failure_causedby_class (klass, element_class, "Could not load array element class"))
goto leave;
- }
}
mono_stats.initialized_class_count++;
// FIXME: Why is this needed ?
if (!mono_class_has_failure (gklass))
mono_class_setup_methods (gklass);
- if (mono_class_has_failure (gklass)) {
- mono_class_set_failure (klass, MONO_EXCEPTION_TYPE_LOAD, mono_image_strdup_printf (klass->image, "Generic Type Defintion failed to init"));
+ if (mono_class_set_type_load_failure_causedby_class (klass, gklass, "Generic Type Definition failed to init"))
goto leave;
- }
if (MONO_CLASS_IS_INTERFACE (klass))
klass->interface_id = mono_get_unique_iid (klass);
klass->has_cctor = gklass->has_cctor;
mono_class_setup_vtable (gklass);
- if (mono_class_has_failure (gklass)) {
- mono_class_set_failure (klass, MONO_EXCEPTION_TYPE_LOAD, NULL);
+ if (mono_class_set_type_load_failure_causedby_class (klass, gklass, "Generic type definition failed to init"))
goto leave;
- }
klass->vtable_size = gklass->vtable_size;
} else {
}
if (klass->parent) {
+ MonoError parent_error;
+ mono_error_init (&parent_error);
int first_iface_slot;
/* This will compute klass->parent->vtable_size for some classes */
mono_class_init (klass->parent);
- if (mono_class_has_failure (klass->parent)) {
- mono_class_set_failure (klass, MONO_EXCEPTION_TYPE_LOAD, NULL);
+ if (mono_class_set_type_load_failure_causedby_class (klass, klass->parent, "Parent class failed to initialize")) {
goto leave;
}
if (!klass->parent->vtable_size) {
/* FIXME: Get rid of this somehow */
mono_class_setup_vtable (klass->parent);
- if (mono_class_has_failure (klass->parent)) {
- mono_class_set_failure (klass, MONO_EXCEPTION_TYPE_LOAD, NULL);
+ if (mono_class_set_type_load_failure_causedby_class (klass, klass->parent, "Parent class vtable failed to initialize")) {
goto leave;
}
}
mono_security_core_clr_check_inheritance (klass);
if (klass->generic_class && !mono_verifier_class_is_valid_generic_instantiation (klass))
- mono_class_set_failure (klass, MONO_EXCEPTION_TYPE_LOAD, mono_image_strdup (klass->image, "Invalid generic instantiation"));
+ mono_class_set_type_load_failure (klass, "Invalid generic instantiation");
goto leave;
/* but it can not be made available for application (i.e. user code) since all COM calls
* are considered native calls. In this case we fail with a TypeLoadException (just like
* Silverlight 2 does */
- mono_class_set_failure (klass, MONO_EXCEPTION_TYPE_LOAD, NULL);
+ mono_class_set_type_load_failure (klass, "");
return;
}
}
if (!parent) {
/* set the parent to something useful and safe, but mark the type as broken */
parent = mono_defaults.object_class;
- mono_class_set_failure (klass, MONO_EXCEPTION_TYPE_LOAD, NULL);
+ mono_class_set_type_load_failure (klass, "");
}
klass->parent = parent;
static void
mono_class_set_failure_and_error (MonoClass *klass, MonoError *error, const char *msg)
{
- mono_class_set_failure (klass, MONO_EXCEPTION_TYPE_LOAD, mono_image_strdup (klass->image, msg));
+ mono_class_set_type_load_failure (klass, "%s", msg);
mono_error_set_type_load_class (error, klass, "%s", msg);
}
parent = mono_class_inflate_generic_class_checked (parent, context, error);
if (parent == NULL) {
- mono_class_set_failure (klass, MONO_EXCEPTION_TYPE_LOAD, mono_image_strdup (klass->image, mono_error_get_message (error)));
+ mono_class_set_type_load_failure (klass, "%s", mono_error_get_message (error));
goto parent_failure;
}
klass->nested_in = mono_class_create_from_typedef (image, nesting_tokeen, error);
if (!mono_error_ok (error)) {
/*FIXME implement a mono_class_set_failure_from_mono_error */
- mono_class_set_failure (klass, MONO_EXCEPTION_TYPE_LOAD, mono_image_strdup (klass->image, mono_error_get_message (error)));
+ mono_class_set_type_load_failure (klass, "%s", mono_error_get_message (error));
mono_loader_unlock ();
mono_profiler_class_loaded (klass, MONO_PROFILE_FAILED);
return NULL;
if (!mono_metadata_interfaces_from_typedef_full (
image, type_token, &interfaces, &icount, FALSE, context, error)){
- mono_class_set_failure (klass, MONO_EXCEPTION_TYPE_LOAD, mono_image_strdup (klass->image, mono_error_get_message (error)));
+ mono_class_set_type_load_failure (klass, "%s", mono_error_get_message (error));
mono_loader_unlock ();
mono_profiler_class_loaded (klass, MONO_PROFILE_FAILED);
return NULL;
if (!enum_basetype) {
/*set it to a default value as the whole runtime can't handle this to be null*/
klass->cast_class = klass->element_class = mono_defaults.int32_class;
- mono_class_set_failure (klass, MONO_EXCEPTION_TYPE_LOAD, mono_image_strdup (klass->image, mono_error_get_message (error)));
+ mono_class_set_type_load_failure (klass, "%s", mono_error_get_message (error));
mono_loader_unlock ();
mono_profiler_class_loaded (klass, MONO_PROFILE_FAILED);
return NULL;
* work.
*/
if (klass->generic_container && !mono_metadata_load_generic_param_constraints_checked (image, type_token, klass->generic_container, error)) {
- mono_class_set_failure (klass, MONO_EXCEPTION_TYPE_LOAD, mono_image_strdup_printf (klass->image, "Could not load generic parameter constrains due to %s", mono_error_get_message (error)));
+ mono_class_set_type_load_failure (klass, "Could not load generic parameter constrains due to %s", mono_error_get_message (error));
mono_loader_unlock ();
mono_profiler_class_loaded (klass, MONO_PROFILE_FAILED);
return NULL;
if (!mono_error_ok (&error)) {
/*Set parent to something safe as the runtime doesn't handle well this kind of failure.*/
klass->parent = mono_defaults.object_class;
- mono_class_set_failure (klass, MONO_EXCEPTION_TYPE_LOAD, NULL);
+ mono_class_set_type_load_failure (klass, "Parent is a generic type instantiation that failed due to: %s", mono_error_get_message (&error));
mono_error_cleanup (&error);
}
}
if (count - pos > 0) {
mono_class_setup_vtable (klass->parent);
if (mono_class_has_failure (klass->parent))
- mono_class_set_failure (klass, MONO_EXCEPTION_TYPE_LOAD, mono_image_strdup (klass->image, "Failed to setup parent interfaces"));
+ mono_class_set_type_load_failure (klass, "Failed to setup parent interfaces");
else
setup_interface_offsets (klass, klass->parent->vtable_size, TRUE);
}
if (eclass->byval_arg.type == MONO_TYPE_TYPEDBYREF || eclass->byval_arg.type == MONO_TYPE_VOID) {
/*Arrays of those two types are invalid.*/
- mono_class_set_failure (klass, MONO_EXCEPTION_INVALID_PROGRAM, NULL);
+ MonoError prepared_error;
+ mono_error_init (&prepared_error);
+ mono_error_set_invalid_program (&prepared_error, "Arrays of void or System.TypedReference types are invalid.");
+ mono_class_set_failure (klass, mono_error_box (&prepared_error, klass->image));
+ mono_error_cleanup (&prepared_error);
} else if (eclass->enumtype && !mono_class_enum_basetype (eclass)) {
if (!eclass->ref_info_handle || eclass->wastypebuilder) {
g_warning ("Only incomplete TypeBuilder objects are allowed to be an enum without base_type");
mono_class_init (eclass);
if (!eclass->size_inited)
mono_class_setup_fields (eclass);
- if (mono_class_has_failure (eclass)) /*FIXME we fail the array type, but we have to let other fields be set.*/
- mono_class_set_failure (klass, MONO_EXCEPTION_TYPE_LOAD, NULL);
+ mono_class_set_type_load_failure_causedby_class (klass, eclass, "Could not load array element type");
+ /*FIXME we fail the array type, but we have to let other fields be set.*/
klass->has_references = MONO_TYPE_IS_REFERENCE (&eclass->byval_arg) || eclass->has_references? TRUE: FALSE;
*
* LOCKING: Acquires the loader lock.
*/
-gboolean
-mono_class_set_failure (MonoClass *klass, guint32 ex_type, void *ex_data)
+static gboolean
+mono_class_set_failure (MonoClass *klass, MonoErrorBoxed *boxed_error)
{
+ g_assert (boxed_error != NULL);
+
if (mono_class_has_failure (klass))
return FALSE;
mono_loader_lock ();
- klass->exception_type = ex_type;
- if (ex_data)
- mono_image_property_insert (klass->image, klass, MONO_CLASS_PROP_EXCEPTION_DATA, ex_data);
+ klass->has_failure = 1;
+ mono_image_property_insert (klass->image, klass, MONO_CLASS_PROP_EXCEPTION_DATA, boxed_error);
mono_loader_unlock ();
return TRUE;
}
+gboolean
+mono_class_has_failure (const MonoClass *klass)
+{
+ g_assert (klass != NULL);
+ return klass->has_failure != 0;
+}
+
+
+/**
+ * mono_class_set_type_load_failure:
+ * @klass: class in which the failure was detected
+ * @fmt: Printf-style error message string.
+ *
+ * Collect detected failure informaion in the class for later processing.
+ * The error is stored as a MonoErrorBoxed as with mono_error_set_type_load_class ()
+ * Note that only the first failure is kept.
+ *
+ * Returns FALSE if a failure was already set on the class, or TRUE otherwise.
+ *
+ * LOCKING: Acquires the loader lock.
+ */
+gboolean
+mono_class_set_type_load_failure (MonoClass *klass, const char * fmt, ...)
+{
+ MonoError prepare_error;
+ va_list args;
+
+ if (mono_class_has_failure (klass))
+ return FALSE;
+
+ mono_error_init (&prepare_error);
+
+ va_start (args, fmt);
+ mono_error_vset_type_load_class (&prepare_error, klass, fmt, args);
+ va_end (args);
+
+ MonoErrorBoxed *box = mono_error_box (&prepare_error, klass->image);
+ mono_error_cleanup (&prepare_error);
+ return mono_class_set_failure (klass, box);
+}
+
/*
* mono_class_get_exception_data:
*
*
* LOCKING: Acquires the loader lock.
*/
-gpointer
-mono_class_get_exception_data (MonoClass *klass)
+static gpointer
+mono_class_get_exception_data (const MonoClass *klass)
{
- return mono_image_property_lookup (klass->image, klass, MONO_CLASS_PROP_EXCEPTION_DATA);
+ return mono_image_property_lookup (klass->image, (MonoClass*)klass, MONO_CLASS_PROP_EXCEPTION_DATA);
}
/**
MonoException*
mono_class_get_exception_for_failure (MonoClass *klass)
{
- gpointer exception_data = mono_class_get_exception_data (klass);
-
- switch (mono_class_get_failure(klass)) {
- case MONO_EXCEPTION_TYPE_LOAD: {
- MonoString *name;
- MonoException *ex;
- char *str = mono_type_get_full_name (klass);
- char *astr = klass->image->assembly? mono_stringify_assembly_name (&klass->image->assembly->aname): NULL;
- name = mono_string_new (mono_domain_get (), str);
- g_free (str);
- ex = mono_get_exception_type_load (name, astr);
- g_free (astr);
- return ex;
- }
- case MONO_EXCEPTION_MISSING_METHOD: {
- char *class_name = (char *)exception_data;
- char *assembly_name = class_name + strlen (class_name) + 1;
-
- return mono_get_exception_missing_method (class_name, assembly_name);
- }
- case MONO_EXCEPTION_MISSING_FIELD: {
- char *class_name = (char *)exception_data;
- char *member_name = class_name + strlen (class_name) + 1;
-
- return mono_get_exception_missing_field (class_name, member_name);
- }
- case MONO_EXCEPTION_FILE_NOT_FOUND: {
- char *msg_format = (char *)exception_data;
- char *assembly_name = msg_format + strlen (msg_format) + 1;
- char *msg = g_strdup_printf (msg_format, assembly_name);
- MonoException *ex;
-
- ex = mono_get_exception_file_not_found2 (msg, mono_string_new (mono_domain_get (), assembly_name));
-
- g_free (msg);
-
- return ex;
- }
- case MONO_EXCEPTION_BAD_IMAGE: {
- return mono_get_exception_bad_image_format ((const char *)exception_data);
- }
- case MONO_EXCEPTION_INVALID_PROGRAM: {
- return mono_exception_from_name_msg (mono_defaults.corlib, "System", "InvalidProgramException", "");
- }
- default: {
- /* TODO - handle other class related failures */
- return mono_get_exception_execution_engine ("Unknown class failure");
- }
- }
+ if (!mono_class_has_failure (klass))
+ return NULL;
+ MonoError unboxed_error;
+ mono_error_init (&unboxed_error);
+ mono_error_set_for_class_failure (&unboxed_error, klass);
+ return mono_error_convert_to_exception (&unboxed_error);
}
static gboolean
mono_class_setup_interfaces (gklass, error);
if (!mono_error_ok (error)) {
- mono_class_set_failure (klass, MONO_EXCEPTION_TYPE_LOAD, mono_image_strdup (klass->image, "Could not setup the interfaces"));
+ mono_class_set_type_load_failure (klass, "Could not setup the interfaces");
return;
}
for (i = 0; i < interface_count; i++) {
interfaces [i] = mono_class_inflate_generic_class_checked (gklass->interfaces [i], mono_generic_class_get_context (klass->generic_class), error);
if (!mono_error_ok (error)) {
- mono_class_set_failure (klass, MONO_EXCEPTION_TYPE_LOAD, mono_image_strdup (klass->image, "Could not setup the interfaces"));
+ mono_class_set_type_load_failure (klass, "Could not setup the interfaces");
return;
}
}
MonoClassField *gfield = >d->fields [field_idx];
MonoType *gtype = mono_field_get_type_checked (gfield, error);
if (!mono_error_ok (error)) {
- char *err_msg = mono_image_strdup_printf (klass->image, "Could not load field %d type due to: %s", field_idx, mono_error_get_message (error));
- mono_class_set_failure (klass, MONO_EXCEPTION_TYPE_LOAD, err_msg);
+ mono_class_set_type_load_failure (klass, "Could not load field %d type due to: %s", field_idx, mono_error_get_message (error));
}
field->type = mono_class_inflate_generic_type_no_copy (image, gtype, mono_class_get_context (klass), error);
if (!mono_error_ok (error)) {
- char *err_msg = mono_image_strdup_printf (klass->image, "Could not load field %d type due to: %s", field_idx, mono_error_get_message (error));
- mono_class_set_failure (klass, MONO_EXCEPTION_TYPE_LOAD, err_msg);
+ mono_class_set_type_load_failure (klass, "Could not load field %d type due to: %s", field_idx, mono_error_get_message (error));
}
} else {
const char *sig;
if (!mono_verifier_verify_field_signature (image, cols [MONO_FIELD_SIGNATURE], NULL)) {
mono_error_set_type_load_class (error, klass, "Could not verify field %s signature", field->name);;
- mono_class_set_failure (klass, MONO_EXCEPTION_TYPE_LOAD, mono_image_strdup (klass->image, mono_error_get_message (error)));
+ mono_class_set_type_load_failure (klass, "%s", mono_error_get_message (error));
return;
}
field->type = mono_metadata_parse_type_checked (image, container, cols [MONO_FIELD_FLAGS], FALSE, sig + 1, &sig, error);
if (!field->type) {
- char *err_msg = mono_image_strdup_printf (klass->image, "Could not load field %d type due to: %s", field_idx, mono_error_get_message (error));
- mono_class_set_failure (klass, MONO_EXCEPTION_TYPE_LOAD, err_msg);
+ mono_class_set_type_load_failure (klass, "Could not load field %d type due to: %s", field_idx, mono_error_get_message (error));
}
}
}
/* need to report exceptions ? */
if (throwOnError && mono_class_has_failure (klass)) {
/* report SecurityException (or others) that occured when loading the assembly */
- MonoException *exc = mono_class_get_exception_for_failure (klass);
- mono_set_pending_exception (exc);
+ mono_error_set_for_class_failure (&error, klass);
+ mono_error_set_pending_exception (&error);
return NULL;
}
}
check_for_invalid_type (MonoClass *klass, MonoError *error)
{
char *name;
- MonoString *str;
mono_error_init (error);
return;
name = mono_type_get_full_name (klass);
- str = mono_string_new (mono_domain_get (), name);
- g_free (name);
- mono_error_set_exception_instance (error, mono_get_exception_type_load (str, NULL));
-
+ mono_error_set_type_load_name (error, name, g_strdup (""), "");
}
ICALL_EXPORT MonoReflectionType *
ves_icall_RuntimeType_make_array_type (MonoReflectionType *type, int rank)
klass = mono_class_from_mono_type (type->type);
check_for_invalid_type (klass, &error);
- mono_error_set_pending_exception (&error);
+ if (mono_error_set_pending_exception (&error))
+ return NULL;
if (rank == 0) //single dimentional array
aklass = mono_array_class_get (klass, 1);
#endif
if (method->klass->valuetype && !(method->flags & MONO_METHOD_ATTR_STATIC)) {
- mono_class_set_failure (method->klass, MONO_EXCEPTION_TYPE_LOAD, NULL);
+ /* FIXME Is this really the best way to signal an error here? Isn't this called much later after class setup? -AK */
+ mono_class_set_type_load_failure (method->klass, "");
#ifndef DISABLE_JIT
/* This will throw the type load exception when the wrapper is compiled */
mono_mb_emit_byte (mb, CEE_LDNULL);
if (mono_class_has_failure (element_class)) {
/*Can happen if element_class only got bad after mono_class_setup_vtable*/
if (!mono_class_has_failure (klass))
- mono_class_set_failure (klass, MONO_EXCEPTION_TYPE_LOAD, NULL);
+ mono_class_set_type_load_failure (klass, "");
mono_domain_unlock (domain);
mono_loader_unlock ();
mono_error_set_for_class_failure (error, klass);
g_free (type_name);
mono_trace (G_LOG_LEVEL_WARNING, MONO_TRACE_SECURITY, "%s", message);
- mono_class_set_failure (klass, MONO_EXCEPTION_TYPE_LOAD, message);
+ mono_class_set_type_load_failure (klass, "%s", message);
// note: do not free string given to mono_class_set_failure
}
g_free (method_name);
mono_trace (G_LOG_LEVEL_WARNING, MONO_TRACE_SECURITY, "%s", message);
- mono_class_set_failure (override->klass, MONO_EXCEPTION_TYPE_LOAD, message);
+ mono_class_set_type_load_failure (override->klass, "%s", message);
// note: do not free string given to mono_class_set_failure
}
}
} else if (klass->generic_class){
if (!ensure_generic_class_runtime_vtable (klass, error)) {
- mono_class_set_failure (klass, MONO_EXCEPTION_TYPE_LOAD, NULL);
+ mono_class_set_type_load_failure (klass, "Could not initialize vtable for generic class due to: %s", mono_error_get_message (error));
return FALSE;
}
}
if (tb->class_size) {
if ((tb->packing_size & 0xffffff00) != 0) {
- char *err_msg = mono_image_strdup_printf (klass->image, "Could not load struct '%s' with packing size %d >= 256", klass->name, tb->packing_size);
- mono_class_set_failure (klass, MONO_EXCEPTION_TYPE_LOAD, err_msg);
+ mono_class_set_type_load_failure (klass, "Could not load struct '%s' with packing size %d >= 256", klass->name, tb->packing_size);
return;
}
klass->packing_size = tb->packing_size;
MonoClass *inst_klass = mono_class_from_mono_type (type);
//Ensure it's safe to use it.
if (!fix_partial_generic_class (inst_klass, error)) {
- mono_class_set_failure (inst_klass, MONO_EXCEPTION_TYPE_LOAD, NULL);
+ mono_class_set_type_load_failure (inst_klass, "Could not initialized generic type instance due to: %s", mono_error_get_message (error));
// Marked the class with failure, but since some other instantiation already failed,
// just report that one, and swallow the error from this one.
if (already_failed)
mono_loader_unlock ();
if (klass->enumtype && !mono_class_is_valid_enum (klass)) {
- mono_class_set_failure (klass, MONO_EXCEPTION_TYPE_LOAD, NULL);
+ mono_class_set_type_load_failure (klass, "Not a valid enumeration");
mono_error_set_type_load_class (&error, klass, "Not a valid enumeration");
goto failure_unlocked;
}
return res;
failure:
- mono_class_set_failure (klass, MONO_EXCEPTION_TYPE_LOAD, NULL);
+ mono_class_set_type_load_failure (klass, "TypeBuilder could not create runtime class due to: %s", mono_error_get_message (&error));
klass->wastypebuilder = TRUE;
mono_domain_unlock (domain);
mono_loader_unlock ();
windows_sources = \
mini-windows.c \
+ mini-windows.h \
mini-windows-dllmain.c
posix_sources = \
static void
generate_aotid (guint8* aotid)
{
- gpointer *rand_handle;
+ gpointer rand_handle;
MonoError error;
mono_rand_open ();
rand_handle = mono_rand_init (NULL, 0);
- mono_rand_try_get_bytes (rand_handle, aotid, 16, &error);
+ mono_rand_try_get_bytes (&rand_handle, aotid, 16, &error);
mono_error_assert_ok (&error);
mono_rand_close (rand_handle);
#include <mono/utils/mono-time.h>
#include <mono/utils/mono-threads.h>
#include <mono/utils/networking.h>
+#include <mono/utils/mono-proclib.h>
#include "debugger-agent.h"
#include "mini.h"
#include "seq-points.h"
/* Waiting for deferred attachment */
agent_config.defer = TRUE;
if (agent_config.address == NULL) {
- agent_config.address = g_strdup_printf ("0.0.0.0:%u", 56000 + (getpid () % 1000));
+ agent_config.address = g_strdup_printf ("0.0.0.0:%u", 56000 + (mono_process_current_pid () % 1000));
}
}
exit (1);
}
-#ifdef HOST_WIN32
+#if defined(HOST_WIN32) && G_HAVE_API_SUPPORT(HAVE_CLASSIC_WINAPI_SUPPORT)
/* Detach console when executing IMAGE_SUBSYSTEM_WINDOWS_GUI on win32 */
if (!enable_debugging && !mono_compile_aot && ((MonoCLIImageInfo*)(mono_assembly_get_image (assembly)->image_info))->cli_header.nt.pe_subsys_required == IMAGE_SUBSYSTEM_WINDOWS_GUI)
FreeConsole ();
#endif /* TARGET_WIN32 */
+#ifndef DISABLE_JIT
/*
* mono_arch_get_restore_context:
*
return start;
}
+#endif /* !DISABLE_JIT */
/*
* The first few arguments are dummy, to force the other arguments to be passed on
mono_resume_unwind (&ctx);
}
+#ifndef DISABLE_JIT
/*
* get_throw_trampoline:
*
{
return get_throw_trampoline (info, FALSE, TRUE, FALSE, FALSE, "throw_corlib_exception", aot);
}
+#endif /* !DISABLE_JIT */
/*
* mono_arch_unwind_frame:
return lmf->rip;
}
+#ifndef DISABLE_JIT
GSList*
mono_amd64_get_exception_trampolines (gboolean aot)
{
return tramps;
}
+#endif /* !DISABLE_JIT */
void
mono_arch_exceptions_init (void)
}
}
-#ifdef TARGET_WIN32
+#if defined(TARGET_WIN32) && !defined(DISABLE_JIT)
/*
* The mono_arch_unwindinfo* methods are used to build and add
RtlInstallFunctionTableCallback (((DWORD64)code) | 0x3, (DWORD64)code, code_size, MONO_GET_RUNTIME_FUNCTION_CALLBACK, code, NULL);
}
-#endif
+#endif /* defined(TARGET_WIN32) !defined(DISABLE_JIT) */
-#if MONO_SUPPORT_TASKLETS
+#if MONO_SUPPORT_TASKLETS && !defined(DISABLE_JIT)
MonoContinuationRestore
mono_tasklets_arch_restore (void)
{
saved = start;
return (MonoContinuationRestore)saved;
}
-#endif
+#endif /* MONO_SUPPORT_TASKLETS && !defined(DISABLE_JIT) */
/*
* mono_arch_setup_resume_sighandler_ctx:
MONO_CONTEXT_SET_SP (ctx, (guint64)MONO_CONTEXT_GET_SP (ctx) - 8);
MONO_CONTEXT_SET_IP (ctx, func);
}
+
+#ifdef DISABLE_JIT
+gpointer
+mono_arch_get_restore_context (MonoTrampInfo **info, gboolean aot)
+{
+ g_assert_not_reached ();
+ return NULL;
+}
+
+gpointer
+mono_arch_get_call_filter (MonoTrampInfo **info, gboolean aot)
+{
+ g_assert_not_reached ();
+ return NULL;
+}
+
+gpointer
+mono_arch_get_throw_exception (MonoTrampInfo **info, gboolean aot)
+{
+ g_assert_not_reached ();
+ return NULL;
+}
+
+gpointer
+mono_arch_get_rethrow_exception (MonoTrampInfo **info, gboolean aot)
+{
+ g_assert_not_reached ();
+ return NULL;
+}
+
+gpointer
+mono_arch_get_throw_corlib_exception (MonoTrampInfo **info, gboolean aot)
+{
+ g_assert_not_reached ();
+ return NULL;
+}
+
+GSList*
+mono_amd64_get_exception_trampolines (gboolean aot)
+{
+ g_assert_not_reached ();
+ return NULL;
+}
+#endif /* DISABLE_JIT */
+
+#if !MONO_SUPPORT_TASKLETS || defined(DISABLE_JIT)
+MonoContinuationRestore
+mono_tasklets_arch_restore (void)
+{
+ g_assert_not_reached ();
+ return NULL;
+}
+#endif /* !MONO_SUPPORT_TASKLETS || defined(DISABLE_JIT) */
--- /dev/null
+/*
+ * mini-windows-uwp.c: UWP profiler stat support for Mono.
+ *
+ * Copyright 2016 Microsoft
+ * Licensed under the MIT license. See LICENSE file in the project root for full license information.
+ */
+#include <config.h>
+#include <glib.h>
+
+#if G_HAVE_API_SUPPORT(HAVE_UWP_WINAPI_SUPPORT)
+#include <Windows.h>
+
+void
+mono_runtime_setup_stat_profiler (void)
+{
+ g_unsupported_api ("OpenThread, GetThreadContext");
+ SetLastError (ERROR_NOT_SUPPORTED);
+ return;
+}
+
+void
+mono_runtime_shutdown_stat_profiler (void)
+{
+ g_unsupported_api ("OpenThread, GetThreadContext");
+ SetLastError (ERROR_NOT_SUPPORTED);
+ return;
+}
+
+static gboolean
+mono_setup_thread_context(DWORD thread_id, MonoContext *mono_context)
+{
+ memset (mono_context, 0, sizeof (MonoContext));
+ return FALSE;
+}
+
+#else /* G_HAVE_API_SUPPORT(HAVE_UWP_WINAPI_SUPPORT) */
+
+#ifdef _MSC_VER
+// Quiet Visual Studio linker warning, LNK4221, in cases when this source file intentional ends up empty.
+void __mono_win32_mini_windows_uwp_quiet_lnk4221(void) {}
+#endif
+#endif /* G_HAVE_API_SUPPORT(HAVE_UWP_WINAPI_SUPPORT) */
+
#include <mono/utils/dtrace.h>
#include "mini.h"
+#include "mini-windows.h"
#include <string.h>
#include <ctype.h>
#include "trace.h"
#include "jit-icalls.h"
-#ifdef _WIN32
+#if G_HAVE_API_SUPPORT(HAVE_CLASSIC_WINAPI_SUPPORT)
#include <mmsystem.h>
#endif
return TRUE;
}
-static HANDLE win32_main_thread;
-static MMRESULT win32_timer;
+#if G_HAVE_API_SUPPORT(HAVE_CLASSIC_WINAPI_SUPPORT)
+static MMRESULT g_timer_event = 0;
+static HANDLE g_timer_main_thread = INVALID_HANDLE_VALUE;
-static void CALLBACK
-win32_time_proc (UINT uID, UINT uMsg, DWORD dwUser, DWORD dw1, DWORD dw2)
+static VOID
+thread_timer_expired (HANDLE thread)
{
CONTEXT context;
context.ContextFlags = CONTEXT_CONTROL;
- if (GetThreadContext (win32_main_thread, &context)) {
+ if (GetThreadContext (thread, &context)) {
#ifdef _WIN64
mono_profiler_stat_hit ((guchar *) context.Rip, &context);
#else
}
}
-void
-mono_runtime_setup_stat_profiler (void)
+static VOID CALLBACK
+timer_event_proc (UINT uID, UINT uMsg, DWORD_PTR dwUser, DWORD_PTR dw1, DWORD_PTR dw2)
{
- static int inited = 0;
- TIMECAPS timecaps;
+ thread_timer_expired ((HANDLE)dwUser);
+}
- if (inited)
- return;
+static VOID
+stop_profiler_timer_event (void)
+{
+ if (g_timer_event != 0) {
+
+ timeKillEvent (g_timer_event);
+ g_timer_event = 0;
+ }
+
+ if (g_timer_main_thread != INVALID_HANDLE_VALUE) {
+
+ CloseHandle (g_timer_main_thread);
+ g_timer_main_thread = INVALID_HANDLE_VALUE;
+ }
+}
+
+static VOID
+start_profiler_timer_event (void)
+{
+ g_return_if_fail (g_timer_main_thread == INVALID_HANDLE_VALUE && g_timer_event == 0);
+
+ TIMECAPS timecaps;
- inited = 1;
if (timeGetDevCaps (&timecaps, sizeof (timecaps)) != TIMERR_NOERROR)
return;
- if ((win32_main_thread = OpenThread (READ_CONTROL | THREAD_GET_CONTEXT, FALSE, GetCurrentThreadId ())) == NULL)
+ g_timer_main_thread = OpenThread (READ_CONTROL | THREAD_GET_CONTEXT, FALSE, GetCurrentThreadId ());
+ if (g_timer_main_thread == NULL)
return;
if (timeBeginPeriod (1) != TIMERR_NOERROR)
return;
- if ((win32_timer = timeSetEvent (1, 0, (LPTIMECALLBACK)win32_time_proc, (DWORD_PTR)NULL, TIME_PERIODIC)) == 0) {
+ g_timer_event = timeSetEvent (1, 0, (LPTIMECALLBACK)timer_event_proc, (DWORD_PTR)g_timer_main_thread, TIME_PERIODIC | TIME_KILL_SYNCHRONOUS);
+ if (g_timer_event == 0) {
timeEndPeriod (1);
return;
}
}
+void
+mono_runtime_setup_stat_profiler (void)
+{
+ start_profiler_timer_event ();
+ return;
+}
+
void
mono_runtime_shutdown_stat_profiler (void)
{
+ stop_profiler_timer_event ();
+ return;
}
gboolean
-mono_thread_state_init_from_handle (MonoThreadUnwindState *tctx, MonoThreadInfo *info)
+mono_setup_thread_context(DWORD thread_id, MonoContext *mono_context)
{
- DWORD id = mono_thread_info_get_tid (info);
HANDLE handle;
CONTEXT context;
- DWORD result;
- MonoContext *ctx;
- MonoJitTlsData *jit_tls;
- void *domain;
- MonoLMF *lmf = NULL;
- gpointer *addr;
-
- tctx->valid = FALSE;
- tctx->unwind_data [MONO_UNWIND_DATA_DOMAIN] = NULL;
- tctx->unwind_data [MONO_UNWIND_DATA_LMF] = NULL;
- tctx->unwind_data [MONO_UNWIND_DATA_JIT_TLS] = NULL;
- g_assert (id != GetCurrentThreadId ());
+ g_assert (thread_id != GetCurrentThreadId ());
- handle = OpenThread (THREAD_ALL_ACCESS, FALSE, id);
+ handle = OpenThread (THREAD_ALL_ACCESS, FALSE, thread_id);
g_assert (handle);
context.ContextFlags = CONTEXT_INTEGER | CONTEXT_CONTROL;
g_assert (context.ContextFlags & CONTEXT_INTEGER);
g_assert (context.ContextFlags & CONTEXT_CONTROL);
- ctx = &tctx->ctx;
+ memset (mono_context, 0, sizeof (MonoContext));
+ mono_sigctx_to_monoctx (&context, mono_context);
- memset (ctx, 0, sizeof (MonoContext));
- mono_sigctx_to_monoctx (&context, ctx);
+ CloseHandle (handle);
+ return TRUE;
+}
+#endif /* G_HAVE_API_SUPPORT(HAVE_UWP_WINAPI_SUPPORT) */
+
+gboolean
+mono_thread_state_init_from_handle (MonoThreadUnwindState *tctx, MonoThreadInfo *info)
+{
+ DWORD id = mono_thread_info_get_tid (info);
+ MonoJitTlsData *jit_tls;
+ void *domain;
+ MonoLMF *lmf = NULL;
+ gpointer *addr;
+
+ tctx->valid = FALSE;
+ tctx->unwind_data [MONO_UNWIND_DATA_DOMAIN] = NULL;
+ tctx->unwind_data [MONO_UNWIND_DATA_LMF] = NULL;
+ tctx->unwind_data [MONO_UNWIND_DATA_JIT_TLS] = NULL;
+
+ mono_setup_thread_context(id, &tctx->ctx);
/* mono_set_jit_tls () sets this */
jit_tls = mono_thread_info_tls_get (info, TLS_KEY_JIT_TLS);
return TRUE;
}
-
--- /dev/null
+#ifndef __MONO_MINI_WINDOWS_H__
+#define __MONO_MINI_WINDOWS_H__
+
+#include <config.h>
+#include <glib.h>
+
+#ifdef HOST_WIN32
+#include "Windows.h"
+#include "mini.h"
+#include "mono/utils/mono-context.h"
+
+gboolean
+mono_setup_thread_context(DWORD thread_id, MonoContext *mono_context);
+#endif /* HOST_WIN32 */
+#endif /* __MONO_MINI_WINDOWS_H__ */
#define IS_REX(inst) (((inst) >= 0x40) && ((inst) <= 0x4f))
+#ifndef DISABLE_JIT
/*
* mono_arch_get_unbox_trampoline:
* @m: method pointer
return start;
}
+#endif /* !DISABLE_JIT */
#ifdef _WIN64
// Workaround lack of Valgrind support for 64-bit Windows
}
}
+#ifndef DISABLE_JIT
guint8*
mono_arch_create_llvm_native_thunk (MonoDomain *domain, guint8 *addr)
{
mono_profiler_code_buffer_new (thunk_start, thunk_code - thunk_start, MONO_PROFILER_CODE_BUFFER_HELPER, NULL);
return addr;
}
+#endif /* !DISABLE_JIT */
void
mono_arch_patch_plt_entry (guint8 *code, gpointer *got, mgreg_t *regs, guint8 *addr)
InterlockedExchangePointer (plt_jump_table_entry, addr);
}
+#ifndef DISABLE_JIT
static void
stack_unaligned (MonoTrampolineType tramp_type)
{
x86_push_imm (code, (guint64)func_arg);
amd64_call_reg (code, AMD64_R11);
}
+#endif /* !DISABLE_JIT */
gpointer
mono_amd64_handler_block_trampoline_helper (void)
return jit_tls->handler_block_return_address;
}
+#ifndef DISABLE_JIT
gpointer
mono_arch_create_handler_block_trampoline (MonoTrampInfo **info, gboolean aot)
{
return buf;
}
+#endif /* !DISABLE_JIT */
/*
* mono_arch_get_call_target:
return *(guint32*)(plt_entry + 6);
}
+#ifndef DISABLE_JIT
/*
* mono_arch_create_sdb_trampoline:
*
return buf;
}
+#endif /* !DISABLE_JIT */
+
+#ifdef DISABLE_JIT
+gpointer
+mono_arch_get_unbox_trampoline (MonoMethod *m, gpointer addr)
+{
+ g_assert_not_reached ();
+ return NULL;
+}
+
+gpointer
+mono_arch_get_static_rgctx_trampoline (MonoMethod *m, MonoMethodRuntimeGenericContext *mrgctx, gpointer addr)
+{
+ g_assert_not_reached ();
+ return NULL;
+}
+
+gpointer
+mono_arch_create_rgctx_lazy_fetch_trampoline (guint32 slot, MonoTrampInfo **info, gboolean aot)
+{
+ g_assert_not_reached ();
+ return NULL;
+}
+
+guchar*
+mono_arch_create_generic_trampoline (MonoTrampolineType tramp_type, MonoTrampInfo **info, gboolean aot)
+{
+ g_assert_not_reached ();
+ return NULL;
+}
+
+gpointer
+mono_arch_create_specific_trampoline (gpointer arg1, MonoTrampolineType tramp_type, MonoDomain *domain, guint32 *code_len)
+{
+ g_assert_not_reached ();
+ return NULL;
+}
+
+gpointer
+mono_arch_create_general_rgctx_lazy_fetch_trampoline (MonoTrampInfo **info, gboolean aot)
+{
+ g_assert_not_reached ();
+ return NULL;
+}
+
+gpointer
+mono_arch_create_handler_block_trampoline (MonoTrampInfo **info, gboolean aot)
+{
+ g_assert_not_reached ();
+ return NULL;
+}
+
+void
+mono_arch_invalidate_method (MonoJitInfo *ji, void *func, gpointer func_arg)
+{
+ g_assert_not_reached ();
+ return;
+}
+
+guint8*
+mono_arch_create_sdb_trampoline (gboolean single_step, MonoTrampInfo **info, gboolean aot)
+{
+ g_assert_not_reached ();
+ return NULL;
+}
+#endif /* DISABLE_JIT */
mono-dl-darwin.c \
mono-dl-posix.c \
mono-dl.h \
+ mono-dl-windows.h \
mono-log-windows.c \
mono-log-common.c \
mono-log-posix.c \
mono-filemap.c \
mono-math.c \
mono-mmap.c \
+ mono-mmap-windows.c \
mono-mmap.h \
mono-mmap-internals.h \
+ mono-mmap-windows.h \
mono-os-mutex.h \
mono-coop-mutex.h \
mono-once.h \
mono-networkinterfaces.c \
mono-networkinterfaces.h \
mono-proclib.c \
+ mono-proclib-windows.c \
mono-proclib.h \
+ mono-proclib-windows.h \
mono-publib.c \
mono-string.h \
mono-time.c \
networking-windows.c \
networking.h \
mono-rand.c \
+ mono-rand-windows.c \
mono-rand.h \
+ mono-rand-windows.h \
memfuncs.c \
memfuncs.h \
parse.c \
return(old);
}
+#endif
#endif
+#if defined(HOST_WIN32) && defined(_MSC_VER)
+// Quiet Visual Studio linker warning, LNK4221, in cases when this source file intentional ends up empty.
+void __mono_win32_atomic_lnk4221(void) {}
#endif
#include <direct.h>
#define mkdir(x) _mkdir(x)
-/* GCC specific functions aren't available */
-#define __builtin_return_address(x) NULL
-
#define __func__ __FUNCTION__
#include <BaseTsd.h>
--- /dev/null
+/*
+ * mono-dl-windows-uwp.c: UWP dl support for Mono.
+ *
+ * Copyright 2016 Microsoft
+ * Licensed under the MIT license. See LICENSE file in the project root for full license information.
+*/
+#include <config.h>
+#include <glib.h>
+
+#if G_HAVE_API_SUPPORT(HAVE_UWP_WINAPI_SUPPORT)
+#include <Windows.h>
+#include "mono/utils/mono-dl-windows.h"
+
+void*
+mono_dl_lookup_symbol_in_process (const char *symbol_name)
+{
+ g_unsupported_api ("EnumProcessModules");
+ SetLastError (ERROR_NOT_SUPPORTED);
+
+ return NULL;
+}
+
+char*
+mono_dl_current_error_string (void)
+{
+ char *ret = NULL;
+ TCHAR buf [1024];
+ DWORD code = GetLastError ();
+
+ if (!FormatMessage (FORMAT_MESSAGE_FROM_SYSTEM | FORMAT_MESSAGE_IGNORE_INSERTS, NULL,
+ code, MAKELANGID(LANG_NEUTRAL, SUBLANG_DEFAULT), buf, G_N_ELEMENTS(buf) - 1, NULL))
+ buf[0] = TEXT('\0');
+
+ ret = u16to8 (buf);
+ return ret;
+}
+
+#else /* G_HAVE_API_SUPPORT(HAVE_UWP_WINAPI_SUPPORT) */
+
+#ifdef _MSC_VER
+// Quiet Visual Studio linker warning, LNK4221, in cases when this source file intentional ends up empty.
+void __mono_win32_mono_dl_windows_uwp_quiet_lnk4221(void) {}
+#endif
+#endif /* G_HAVE_API_SUPPORT(HAVE_UWP_WINAPI_SUPPORT) */
#if defined(HOST_WIN32)
#include "mono/utils/mono-dl.h"
+#include "mono/utils/mono-dl-windows.h"
#include "mono/utils/mono-embed.h"
#include "mono/utils/mono-path.h"
#include <windows.h>
#include <psapi.h>
-
const char*
mono_dl_get_so_prefix (void)
{
gpointer hModule = NULL;
if (file) {
gunichar2* file_utf16 = g_utf8_to_utf16 (file, strlen (file), NULL, NULL, NULL);
+
+#if G_HAVE_API_SUPPORT(HAVE_CLASSIC_WINAPI_SUPPORT)
guint last_sem = SetErrorMode (SEM_FAILCRITICALERRORS);
+#endif
guint32 last_error = 0;
hModule = LoadLibrary (file_utf16);
if (!hModule)
last_error = GetLastError ();
+#if G_HAVE_API_SUPPORT(HAVE_CLASSIC_WINAPI_SUPPORT)
SetErrorMode (last_sem);
+#endif
+
g_free (file_utf16);
if (!hModule)
FreeLibrary (module->handle);
}
+#if G_HAVE_API_SUPPORT(HAVE_CLASSIC_WINAPI_SUPPORT)
void*
-mono_dl_lookup_symbol (MonoDl *module, const char *symbol_name)
+mono_dl_lookup_symbol_in_process (const char *symbol_name)
{
HMODULE *modules;
DWORD buffer_size = sizeof (HMODULE) * 1024;
DWORD needed, i;
gpointer proc = NULL;
- /* get the symbol directly from the specified module */
- if (!module->main_module)
- return GetProcAddress (module->handle, symbol_name);
-
- /* get the symbol from the main module */
- proc = GetProcAddress (module->handle, symbol_name);
- if (proc != NULL)
- return proc;
-
/* get the symbol from the loaded DLLs */
modules = (HMODULE *) g_malloc (buffer_size);
if (modules == NULL)
g_free (modules);
return NULL;
}
+#endif /* G_HAVE_API_SUPPORT(HAVE_CLASSIC_WINAPI_SUPPORT) */
+
+void*
+mono_dl_lookup_symbol (MonoDl *module, const char *symbol_name)
+{
+ gpointer proc = NULL;
+
+ /* get the symbol directly from the specified module */
+ if (!module->main_module)
+ return GetProcAddress (module->handle, symbol_name);
+
+ /* get the symbol from the main module */
+ proc = GetProcAddress (module->handle, symbol_name);
+ if (proc != NULL)
+ return proc;
+
+ /* get the symbol from the loaded DLLs */
+ return mono_dl_lookup_symbol_in_process (symbol_name);
+}
int
mono_dl_convert_flags (int flags)
return 0;
}
+#if G_HAVE_API_SUPPORT(HAVE_CLASSIC_WINAPI_SUPPORT)
char*
mono_dl_current_error_string (void)
{
}
return ret;
}
+#endif /* G_HAVE_API_SUPPORT(HAVE_CLASSIC_WINAPI_SUPPORT) */
int
mono_dl_get_executable_path (char *buf, int buflen)
{
return NULL;
}
-
#endif
--- /dev/null
+#ifndef __MONO_UTILS_DL_WINDOWS_H__
+#define __MONO_UTILS_DL_WINDOWS_H__
+
+#include <config.h>
+#include <glib.h>
+
+#ifdef HOST_WIN32
+#include "mono/utils/mono-dl.h"
+
+void*
+mono_dl_lookup_symbol_in_process (const char *symbol_name);
+#endif /* HOST_WIN32 */
+#endif /* __MONO_UTILS_DL_WINDOWS_H__ */
+
void *padding [3];
} MonoErrorInternal;
+/* Invariant: the error strings are allocated in the mempool of the given image */
+struct _MonoErrorBoxed {
+ MonoError error;
+ MonoImage *image;
+};
+
#define error_init(error) do { \
((MonoErrorInternal*)(error))->error_code = MONO_ERROR_NONE; \
((MonoErrorInternal*)(error))->flags = 0; \
void
mono_error_set_type_load_class (MonoError *error, MonoClass *klass, const char *msg_format, ...) MONO_ATTR_FORMAT_PRINTF(3,4);
+void
+mono_error_vset_type_load_class (MonoError *error, MonoClass *klass, const char *msg_format, va_list args);
+
void
mono_error_set_type_load_name (MonoError *error, const char *type_name, const char *assembly_name, const char *msg_format, ...) MONO_ATTR_FORMAT_PRINTF(4,5);
void
mono_error_move (MonoError *dest, MonoError *src);
+MonoErrorBoxed*
+mono_error_box (const MonoError *error, MonoImage *image);
+
+gboolean
+mono_error_set_from_boxed (MonoError *error, const MonoErrorBoxed *from);
+
+
#endif
return (error->error_code == MONO_ERROR_EXCEPTION_INSTANCE);
}
+static gboolean
+is_boxed (MonoErrorInternal *error)
+{
+ return ((error->flags & MONO_ERROR_MEMPOOL_BOXED) != 0);
+}
+
static void
mono_error_prepare (MonoErrorInternal *error)
{
/* Two cleanups in a row without an intervening init. */
g_assert (orig_error_code != MONO_ERROR_CLEANUP_CALLED_SENTINEL);
+ /* Mempool stored error shouldn't be cleaned up */
+ g_assert (!is_boxed (error));
/* Mark it as cleaned up. */
error->error_code = MONO_ERROR_CLEANUP_CALLED_SENTINEL;
void
mono_error_set_type_load_class (MonoError *oerror, MonoClass *klass, const char *msg_format, ...)
+{
+ va_list args;
+ va_start (args, msg_format);
+ mono_error_vset_type_load_class (oerror, klass, msg_format, args);
+ va_end (args);
+}
+
+void
+mono_error_vset_type_load_class (MonoError *oerror, MonoClass *klass, const char *msg_format, va_list args)
{
MonoErrorInternal *error = (MonoErrorInternal*)oerror;
mono_error_prepare (error);
error->error_code = MONO_ERROR_TYPE_LOAD;
mono_error_set_class (oerror, klass);
- set_error_message ();
+ set_error_messagev ();
}
/*
MonoError error;
MonoException *ex;
+ /* Mempool stored error shouldn't be cleaned up */
+ g_assert (!is_boxed ((MonoErrorInternal*)target_error));
+
if (mono_error_ok (target_error))
return NULL;
memcpy (dest, src, sizeof (MonoErrorInternal));
mono_error_init (src);
}
+
+/**
+ * mono_error_box:
+ * @ierror: The input error that will be boxed.
+ * @image: The mempool of this image will hold the boxed error.
+ *
+ * Creates a new boxed error in the given mempool from MonoError.
+ * It does not alter ierror, so you still have to clean it up with
+ * mono_error_cleanup or mono_error_convert_to_exception or another such function.
+ *
+ * Returns the boxed error, or NULL if the mempool could not allocate.
+ */
+MonoErrorBoxed*
+mono_error_box (const MonoError *ierror, MonoImage *image)
+{
+ MonoErrorInternal *from = (MonoErrorInternal*)ierror;
+ /* Don't know how to box a gchandle */
+ g_assert (!is_managed_exception (from));
+ MonoErrorBoxed* box = mono_image_alloc (image, sizeof (MonoErrorBoxed));
+ box->image = image;
+ mono_error_init_flags (&box->error, MONO_ERROR_MEMPOOL_BOXED);
+ MonoErrorInternal *to = (MonoErrorInternal*)&box->error;
+
+#define DUP_STR(field) do { \
+ if (from->field) { \
+ if (!(to->field = mono_image_strdup (image, from->field))) \
+ to->flags |= MONO_ERROR_INCOMPLETE; \
+ } else { \
+ to->field = NULL; \
+ } \
+ } while (0)
+
+ to->error_code = from->error_code;
+ DUP_STR (type_name);
+ DUP_STR (assembly_name);
+ DUP_STR (member_name);
+ DUP_STR (exception_name_space);
+ DUP_STR (exception_name);
+ DUP_STR (full_message);
+ DUP_STR (full_message_with_fields);
+ DUP_STR (first_argument);
+ to->exn.klass = from->exn.klass;
+
+#undef DUP_STR
+
+ return box;
+}
+
+
+/**
+ * mono_error_set_from_boxed:
+ * @oerror: The error that will be set to the contents of the box.
+ * @box: A mempool-allocated error.
+ *
+ * Sets the error condition in the oerror from the contents of the
+ * given boxed error. Does not alter the boxed error, so it can be
+ * used in a future call to mono_error_set_from_boxed as needed. The
+ * oerror should've been previously initialized with mono_error_init,
+ * as usual.
+ *
+ * Returns TRUE on success or FALSE on failure.
+ */
+gboolean
+mono_error_set_from_boxed (MonoError *oerror, const MonoErrorBoxed *box)
+{
+ MonoErrorInternal* to = (MonoErrorInternal*)oerror;
+ MonoErrorInternal* from = (MonoErrorInternal*)&box->error;
+ g_assert (!is_managed_exception (from));
+
+ mono_error_prepare (to);
+ to->flags |= MONO_ERROR_FREE_STRINGS;
+#define DUP_STR(field) do { \
+ if (from->field) { \
+ if (!(to->field = g_strdup (from->field))) \
+ to->flags |= MONO_ERROR_INCOMPLETE; \
+ } else { \
+ to->field = NULL; \
+ } \
+ } while (0)
+
+ to->error_code = from->error_code;
+ DUP_STR (type_name);
+ DUP_STR (assembly_name);
+ DUP_STR (member_name);
+ DUP_STR (exception_name_space);
+ DUP_STR (exception_name);
+ DUP_STR (full_message);
+ DUP_STR (full_message_with_fields);
+ DUP_STR (first_argument);
+ to->exn.klass = from->exn.klass;
+
+#undef DUP_STR
+ return (to->flags & MONO_ERROR_INCOMPLETE) == 0 ;
+}
/*
Something happened while processing the error and the resulting message is incomplete.
*/
- MONO_ERROR_INCOMPLETE = 0x0002
+ MONO_ERROR_INCOMPLETE = 0x0002,
+ /*
+ This MonoError is heap allocated in a mempool
+ */
+ MONO_ERROR_MEMPOOL_BOXED = 0x0004
};
enum {
void *hidden_1 [12]; /*DON'T TOUCH */
} MonoError;
+/* Mempool-allocated MonoError.*/
+typedef struct _MonoErrorBoxed MonoErrorBoxed;
+
MONO_BEGIN_DECLS
MONO_API void
g_free (new_pathname);
return(NULL);
}
+
+#else /* DISABLE_PORTABILITY */
+
+#ifdef _MSC_VER
+// Quiet Visual Studio linker warning, LNK4221, in cases when this source file intentional ends up empty.
+void __mono_win32_mono_io_portability_quiet_lnk4221(void) {}
#endif
+#endif /* DISABLE_PORTABILITY */
#include <process.h>
#endif
#include "mono-logger-internals.h"
+#include "mono-proclib.h"
static FILE *logFile = NULL;
static void *logUserData = NULL;
struct tm *tod;
time(&t);
tod = localtime(&t);
- pid = _getpid();
+ pid = mono_process_current_pid ();
strftime(logTime, sizeof(logTime), "%F %T", tod);
#endif
fprintf (logFile, "%s level[%c] mono[%d]: %s\n", logTime, mapLogFileLevel (level), pid, message);
#include <time.h>
#include <process.h>
#include "mono-logger-internals.h"
+#include "mono-proclib.h"
static FILE *logFile = NULL;
static void *logUserData = NULL;
mono_log_write_syslog(const char *domain, GLogLevelFlags level, mono_bool hdr, const char *message)
{
time_t t;
- pid_t pid;
+ int pid;
char logTime [80];
if (logFile == NULL)
struct tm *tod;
time(&t);
tod = localtime(&t);
- pid = _getpid();
+ pid = mono_process_current_pid ();
strftime(logTime, sizeof(logTime), "%F %T", tod);
fprintf (logFile, "%s level[%c] mono[%d]: %s\n", logTime, mapLogFileLevel (level), pid, message);
continue;
}
for (i = 0; valid_flags[i]; i++) {
- int len = strlen (valid_flags[i]);
+ size_t len = strlen (valid_flags[i]);
if (strncmp (tok, valid_flags[i], len) == 0 && (tok[len] == 0 || tok[len] == ',')) {
flags |= valid_masks[i];
tok += len;
#include "mono-compiler.h"
-int mono_pages_not_faulted (void *addr, size_t length);
+void *
+malloc_shared_area (int pid);
+
+char*
+aligned_address (char *mem, size_t size, size_t alignment);
+
+void
+account_mem (MonoMemAccountType type, ssize_t size);
+
+int
+mono_pages_not_faulted (void *addr, size_t length);
#endif /* __MONO_UTILS_MMAP_INTERNAL_H__ */
--- /dev/null
+/*
+ * mono-dl-windows-uwp.c: UWP dl support for Mono.
+ *
+ * Copyright 2016 Microsoft
+ * Licensed under the MIT license. See LICENSE file in the project root for full license information.
+*/
+#include <config.h>
+#include <glib.h>
+
+#if G_HAVE_API_SUPPORT(HAVE_UWP_WINAPI_SUPPORT)
+#include <Windows.h>
+#include <mono/utils/mono-mmap-windows.h>
+
+void*
+mono_file_map (size_t length, int flags, int fd, guint64 offset, void **ret_handle)
+{
+ void *ptr;
+ int mflags = 0;
+ HANDLE file, mapping;
+ int prot = mono_mmap_win_prot_from_flags (flags);
+
+ mflags = FILE_MAP_READ;
+ if (flags & MONO_MMAP_WRITE)
+ mflags = FILE_MAP_COPY;
+
+ file = (HANDLE) _get_osfhandle (fd);
+ mapping = CreateFileMappingFromApp (file, NULL, prot, length, NULL);
+
+ if (mapping == NULL)
+ return NULL;
+
+ ptr = MapViewOfFileFromApp (mapping, mflags, offset, length);
+
+ if (ptr == NULL) {
+ CloseHandle (mapping);
+ return NULL;
+ }
+
+ *ret_handle = (void*)mapping;
+ return ptr;
+}
+
+int
+mono_file_unmap (void *addr, void *handle)
+{
+ UnmapViewOfFile (addr);
+ CloseHandle ((HANDLE)handle);
+ return 0;
+}
+
+#else /* G_HAVE_API_SUPPORT(HAVE_UWP_WINAPI_SUPPORT) */
+
+#ifdef _MSC_VER
+// Quiet Visual Studio linker warning, LNK4221, in cases when this source file intentional ends up empty.
+void __mono_win32_mono_mmap_windows_uwp_quiet_lnk4221(void) {}
+#endif
+#endif /* G_HAVE_API_SUPPORT(HAVE_UWP_WINAPI_SUPPORT) */
--- /dev/null
+/*
+ * mono-mmap-windows.c: Windows support for mapping code into the process address space
+ *
+ * Author:
+ * Mono Team (mono-list@lists.ximian.com)
+ *
+ * Copyright 2001-2008 Novell, Inc.
+ * Licensed under the MIT license. See LICENSE file in the project root for full license information.
+ */
+
+#include <config.h>
+#include <glib.h>
+
+#if defined(HOST_WIN32)
+#include <Windows.h>
+#include "mono/utils/mono-mmap-windows.h"
+#include <mono/utils/mono-counters.h>
+#include <io.h>
+
+static void *malloced_shared_area = NULL;
+
+int
+mono_pagesize (void)
+{
+ SYSTEM_INFO info;
+ static int saved_pagesize = 0;
+ if (saved_pagesize)
+ return saved_pagesize;
+ GetSystemInfo (&info);
+ saved_pagesize = info.dwAllocationGranularity;
+ return saved_pagesize;
+}
+
+int
+mono_mmap_win_prot_from_flags (int flags)
+{
+ int prot = flags & (MONO_MMAP_READ|MONO_MMAP_WRITE|MONO_MMAP_EXEC);
+ switch (prot) {
+ case 0: prot = PAGE_NOACCESS; break;
+ case MONO_MMAP_READ: prot = PAGE_READONLY; break;
+ case MONO_MMAP_READ|MONO_MMAP_EXEC: prot = PAGE_EXECUTE_READ; break;
+ case MONO_MMAP_READ|MONO_MMAP_WRITE: prot = PAGE_READWRITE; break;
+ case MONO_MMAP_READ|MONO_MMAP_WRITE|MONO_MMAP_EXEC: prot = PAGE_EXECUTE_READWRITE; break;
+ case MONO_MMAP_WRITE: prot = PAGE_READWRITE; break;
+ case MONO_MMAP_WRITE|MONO_MMAP_EXEC: prot = PAGE_EXECUTE_READWRITE; break;
+ case MONO_MMAP_EXEC: prot = PAGE_EXECUTE; break;
+ default:
+ g_assert_not_reached ();
+ }
+ return prot;
+}
+
+void*
+mono_valloc (void *addr, size_t length, int flags, MonoMemAccountType type)
+{
+ void *ptr;
+ int mflags = MEM_RESERVE|MEM_COMMIT;
+ int prot = mono_mmap_win_prot_from_flags (flags);
+ /* translate the flags */
+
+ ptr = VirtualAlloc (addr, length, mflags, prot);
+
+ account_mem (type, (ssize_t)length);
+
+ return ptr;
+}
+
+void*
+mono_valloc_aligned (size_t length, size_t alignment, int flags, MonoMemAccountType type)
+{
+ int prot = mono_mmap_win_prot_from_flags (flags);
+ char *mem = VirtualAlloc (NULL, length + alignment, MEM_RESERVE, prot);
+ char *aligned;
+
+ if (!mem)
+ return NULL;
+
+ aligned = aligned_address (mem, length, alignment);
+
+ aligned = VirtualAlloc (aligned, length, MEM_COMMIT, prot);
+ g_assert (aligned);
+
+ account_mem (type, (ssize_t)length);
+
+ return aligned;
+}
+
+int
+mono_vfree (void *addr, size_t length, MonoMemAccountType type)
+{
+ MEMORY_BASIC_INFORMATION mbi;
+ SIZE_T query_result = VirtualQuery (addr, &mbi, sizeof (mbi));
+ BOOL res;
+
+ g_assert (query_result);
+
+ res = VirtualFree (mbi.AllocationBase, 0, MEM_RELEASE);
+
+ g_assert (res);
+
+ account_mem (type, -(ssize_t)length);
+
+ return 0;
+}
+
+#if G_HAVE_API_SUPPORT(HAVE_CLASSIC_WINAPI_SUPPORT)
+void*
+mono_file_map (size_t length, int flags, int fd, guint64 offset, void **ret_handle)
+{
+ void *ptr;
+ int mflags = 0;
+ HANDLE file, mapping;
+ int prot = mono_mmap_win_prot_from_flags (flags);
+ /* translate the flags */
+ /*if (flags & MONO_MMAP_PRIVATE)
+ mflags |= MAP_PRIVATE;
+ if (flags & MONO_MMAP_SHARED)
+ mflags |= MAP_SHARED;
+ if (flags & MONO_MMAP_ANON)
+ mflags |= MAP_ANONYMOUS;
+ if (flags & MONO_MMAP_FIXED)
+ mflags |= MAP_FIXED;
+ if (flags & MONO_MMAP_32BIT)
+ mflags |= MAP_32BIT;*/
+
+ mflags = FILE_MAP_READ;
+ if (flags & MONO_MMAP_WRITE)
+ mflags = FILE_MAP_COPY;
+
+ file = (HANDLE) _get_osfhandle (fd);
+
+ mapping = CreateFileMapping (file, NULL, prot, 0, 0, NULL);
+
+ if (mapping == NULL)
+ return NULL;
+
+ ptr = MapViewOfFile (mapping, mflags, 0, offset, length);
+
+ if (ptr == NULL) {
+ CloseHandle (mapping);
+ return NULL;
+ }
+ *ret_handle = (void*)mapping;
+ return ptr;
+}
+
+int
+mono_file_unmap (void *addr, void *handle)
+{
+ UnmapViewOfFile (addr);
+ CloseHandle ((HANDLE)handle);
+ return 0;
+}
+#endif /* G_HAVE_API_SUPPORT(HAVE_CLASSIC_WINAPI_SUPPORT) */
+
+int
+mono_mprotect (void *addr, size_t length, int flags)
+{
+ DWORD oldprot;
+ int prot = mono_mmap_win_prot_from_flags (flags);
+
+ if (flags & MONO_MMAP_DISCARD) {
+ VirtualFree (addr, length, MEM_DECOMMIT);
+ VirtualAlloc (addr, length, MEM_COMMIT, prot);
+ return 0;
+ }
+ return VirtualProtect (addr, length, prot, &oldprot) == 0;
+}
+
+void*
+mono_shared_area (void)
+{
+ if (!malloced_shared_area)
+ malloced_shared_area = malloc_shared_area (0);
+ /* get the pid here */
+ return malloced_shared_area;
+}
+
+void
+mono_shared_area_remove (void)
+{
+ if (malloced_shared_area)
+ g_free (malloced_shared_area);
+ malloced_shared_area = NULL;
+}
+
+void*
+mono_shared_area_for_pid (void *pid)
+{
+ return NULL;
+}
+
+void
+mono_shared_area_unload (void *area)
+{
+}
+
+int
+mono_shared_area_instances (void **array, int count)
+{
+ return 0;
+}
+
+#endif
--- /dev/null
+#ifndef __MONO_UTILS_MMAP_WINDOWS_H__
+#define __MONO_UTILS_MMAP_WINDOWS_H__
+
+#include <config.h>
+#include <glib.h>
+
+#ifdef HOST_WIN32
+#include "mono/utils/mono-mmap.h"
+#include "mono/utils/mono-mmap-internals.h"
+
+int
+mono_mmap_win_prot_from_flags (int flags);
+#endif /* HOST_WIN32 */
+#endif /* __MONO_UTILS_MMAP_WINDOWS_H__ */
+
* Licensed under the MIT license. See LICENSE file in the project root for full license information.
*/
-#include "config.h"
+#include <config.h>
-#ifdef HOST_WIN32
-#include <windows.h>
-#include <io.h>
-#else
+#ifndef HOST_WIN32
#include <sys/types.h>
#if HAVE_SYS_STAT_H
#include <sys/stat.h>
#include <unistd.h>
#include <stdlib.h>
#include <errno.h>
-#endif
+#endif /* !HOST_WIN32 */
#include "mono-mmap.h"
#include "mono-mmap-internals.h"
#include <mono/utils/atomic.h>
#include <mono/utils/mono-counters.h>
-
#define BEGIN_CRITICAL_SECTION do { \
MonoThreadInfo *__info = mono_thread_info_current_unchecked (); \
if (__info) __info->inside_critical_region = TRUE; \
short stats_end;
} SAreaHeader;
-static void* malloced_shared_area = NULL;
-
-static void*
+void*
malloc_shared_area (int pid)
{
int size = mono_pagesize ();
return sarea;
}
-static char*
+char*
aligned_address (char *mem, size_t size, size_t alignment)
{
char *aligned = (char*)((size_t)(mem + (alignment - 1)) & ~(alignment - 1));
static volatile size_t allocation_count [MONO_MEM_ACCOUNT_MAX];
-static void
+void
account_mem (MonoMemAccountType type, ssize_t size)
{
#if SIZEOF_VOID_P == 4
}
#ifdef HOST_WIN32
-
-int
-mono_pagesize (void)
-{
- SYSTEM_INFO info;
- static int saved_pagesize = 0;
- if (saved_pagesize)
- return saved_pagesize;
- GetSystemInfo (&info);
- saved_pagesize = info.dwAllocationGranularity;
- return saved_pagesize;
-}
-
-static int
-prot_from_flags (int flags)
-{
- int prot = flags & (MONO_MMAP_READ|MONO_MMAP_WRITE|MONO_MMAP_EXEC);
- switch (prot) {
- case 0: prot = PAGE_NOACCESS; break;
- case MONO_MMAP_READ: prot = PAGE_READONLY; break;
- case MONO_MMAP_READ|MONO_MMAP_EXEC: prot = PAGE_EXECUTE_READ; break;
- case MONO_MMAP_READ|MONO_MMAP_WRITE: prot = PAGE_READWRITE; break;
- case MONO_MMAP_READ|MONO_MMAP_WRITE|MONO_MMAP_EXEC: prot = PAGE_EXECUTE_READWRITE; break;
- case MONO_MMAP_WRITE: prot = PAGE_READWRITE; break;
- case MONO_MMAP_WRITE|MONO_MMAP_EXEC: prot = PAGE_EXECUTE_READWRITE; break;
- case MONO_MMAP_EXEC: prot = PAGE_EXECUTE; break;
- default:
- g_assert_not_reached ();
- }
- return prot;
-}
-
-void*
-mono_valloc (void *addr, size_t length, int flags, MonoMemAccountType type)
-{
- void *ptr;
- int mflags = MEM_RESERVE|MEM_COMMIT;
- int prot = prot_from_flags (flags);
- /* translate the flags */
-
- ptr = VirtualAlloc (addr, length, mflags, prot);
-
- account_mem (type, (ssize_t)length);
-
- return ptr;
-}
-
-void*
-mono_valloc_aligned (size_t length, size_t alignment, int flags, MonoMemAccountType type)
-{
- int prot = prot_from_flags (flags);
- char *mem = VirtualAlloc (NULL, length + alignment, MEM_RESERVE, prot);
- char *aligned;
-
- if (!mem)
- return NULL;
-
- aligned = aligned_address (mem, length, alignment);
-
- aligned = VirtualAlloc (aligned, length, MEM_COMMIT, prot);
- g_assert (aligned);
-
- account_mem (type, (ssize_t)length);
-
- return aligned;
-}
-
+// Windows specific implementation in mono-mmap-windows.c
#define HAVE_VALLOC_ALIGNED
-int
-mono_vfree (void *addr, size_t length, MonoMemAccountType type)
-{
- MEMORY_BASIC_INFORMATION mbi;
- SIZE_T query_result = VirtualQuery (addr, &mbi, sizeof (mbi));
- BOOL res;
-
- g_assert (query_result);
-
- res = VirtualFree (mbi.AllocationBase, 0, MEM_RELEASE);
-
- g_assert (res);
-
- account_mem (type, -(ssize_t)length);
-
- return 0;
-}
-
-void*
-mono_file_map (size_t length, int flags, int fd, guint64 offset, void **ret_handle)
-{
- void *ptr;
- int mflags = 0;
- HANDLE file, mapping;
- int prot = prot_from_flags (flags);
- /* translate the flags */
- /*if (flags & MONO_MMAP_PRIVATE)
- mflags |= MAP_PRIVATE;
- if (flags & MONO_MMAP_SHARED)
- mflags |= MAP_SHARED;
- if (flags & MONO_MMAP_ANON)
- mflags |= MAP_ANONYMOUS;
- if (flags & MONO_MMAP_FIXED)
- mflags |= MAP_FIXED;
- if (flags & MONO_MMAP_32BIT)
- mflags |= MAP_32BIT;*/
-
- mflags = FILE_MAP_READ;
- if (flags & MONO_MMAP_WRITE)
- mflags = FILE_MAP_COPY;
-
- file = (HANDLE) _get_osfhandle (fd);
- mapping = CreateFileMapping (file, NULL, prot, 0, 0, NULL);
- if (mapping == NULL)
- return NULL;
- ptr = MapViewOfFile (mapping, mflags, 0, offset, length);
- if (ptr == NULL) {
- CloseHandle (mapping);
- return NULL;
- }
- *ret_handle = (void*)mapping;
- return ptr;
-}
-
-int
-mono_file_unmap (void *addr, void *handle)
-{
- UnmapViewOfFile (addr);
- CloseHandle ((HANDLE)handle);
- return 0;
-}
-
-int
-mono_mprotect (void *addr, size_t length, int flags)
-{
- DWORD oldprot;
- int prot = prot_from_flags (flags);
-
- if (flags & MONO_MMAP_DISCARD) {
- VirtualFree (addr, length, MEM_DECOMMIT);
- VirtualAlloc (addr, length, MEM_COMMIT, prot);
- return 0;
- }
- return VirtualProtect (addr, length, prot, &oldprot) == 0;
-}
-
-void*
-mono_shared_area (void)
-{
- if (!malloced_shared_area)
- malloced_shared_area = malloc_shared_area (0);
- /* get the pid here */
- return malloced_shared_area;
-}
-
-void
-mono_shared_area_remove (void)
-{
- if (malloced_shared_area)
- g_free (malloced_shared_area);
- malloced_shared_area = NULL;
-}
-
-void*
-mono_shared_area_for_pid (void *pid)
-{
- return NULL;
-}
-
-void
-mono_shared_area_unload (void *area)
-{
-}
-
-int
-mono_shared_area_instances (void **array, int count)
-{
- return 0;
-}
-
#else
+
+static void* malloced_shared_area = NULL;
#if defined(HAVE_MMAP)
/**
--- /dev/null
+/*
+ * mono-proclib-windows-uwp.c: UWP proclib support for Mono.
+ *
+ * Copyright 2016 Microsoft
+ * Licensed under the MIT license. See LICENSE file in the project root for full license information.
+*/
+#include <config.h>
+#include <glib.h>
+
+#if G_HAVE_API_SUPPORT(HAVE_UWP_WINAPI_SUPPORT)
+#include <Windows.h>
+#include <mono/utils/mono-proclib.h>
+
+gint32
+mono_cpu_usage (MonoCpuUsageState *prev)
+{
+ gint32 cpu_usage = 0;
+ gint64 cpu_total_time;
+ gint64 cpu_busy_time;
+ guint64 idle_time;
+ guint64 kernel_time;
+ guint64 user_time;
+ guint64 current_time;
+ guint64 creation_time;
+ guint64 exit_time;
+
+ GetSystemTimeAsFileTime ((FILETIME*)¤t_time);
+ if (!GetProcessTimes (GetCurrentProcess (), (FILETIME*)&creation_time, (FILETIME*)&exit_time, (FILETIME*)&kernel_time, (FILETIME*)&user_time)) {
+ g_error ("GetProcessTimes() failed, error code is %d\n", GetLastError ());
+ return -1;
+ }
+
+ // GetProcessTimes user_time is a sum of user time spend by all threads in the process.
+ // This means that the total user time can be more than real time. In order to adjust for this
+ // the total available time that we can be scheduled depends on the number of available cores.
+ // For example, having 2 threads running 100% on a 2 core system for 100 ms will return a user_time of 200ms
+ // but the current_time - creation_time will only be 100ms but by adjusting the available time based on number of
+ // of availalbe cores will gives use the total load of the process.
+ guint64 total_available_time = (current_time - creation_time) * mono_cpu_count ();
+
+ idle_time = total_available_time - (kernel_time + user_time);
+
+ cpu_total_time = (gint64)((idle_time - (prev ? prev->idle_time : 0)) + (user_time - (prev ? prev->user_time : 0)) + (kernel_time - (prev ? prev->kernel_time : 0)));
+ cpu_busy_time = (gint64)(cpu_total_time - (idle_time - (prev ? prev->idle_time : 0)));
+
+ if (prev) {
+ prev->idle_time = idle_time;
+ prev->kernel_time = kernel_time;
+ prev->user_time = user_time;
+ }
+
+ if (cpu_total_time > 0 && cpu_busy_time > 0)
+ cpu_usage = (gint32)(cpu_busy_time * 100 / cpu_total_time);
+
+ return cpu_usage;
+}
+
+#else /* G_HAVE_API_SUPPORT(HAVE_UWP_WINAPI_SUPPORT) */
+
+#ifdef _MSC_VER
+// Quiet Visual Studio linker warning, LNK4221, in cases when this source file intentional ends up empty.
+void __mono_win32_mono_proclib_windows_uwp_quiet_lnk4221(void) {}
+#endif
+#endif /* G_HAVE_API_SUPPORT(HAVE_UWP_WINAPI_SUPPORT) */
--- /dev/null
+/*
+ * mono-proclib-windows.c: Windows proclib support for Mono.
+ *
+ * Copyright 2016 Microsoft
+ * Licensed under the MIT license. See LICENSE file in the project root for full license information.
+*/
+
+#include <config.h>
+#include <glib.h>
+
+#ifdef HOST_WIN32
+#include <windows.h>
+#include "mono/utils/mono-proclib.h"
+
+int
+mono_process_current_pid ()
+{
+ return (int) GetCurrentProcessId ();
+}
+
+/**
+ * mono_cpu_count:
+ *
+ * Return the number of processors on the system.
+ */
+int
+mono_cpu_count (void)
+{
+ SYSTEM_INFO info;
+ GetSystemInfo (&info);
+ return info.dwNumberOfProcessors;
+}
+
+/*
+ * This function returns the cpu usage in percentage,
+ * normalized on the number of cores.
+ *
+ * Warning : the percentage returned can be > 100%. This
+ * might happens on systems like Android which, for
+ * battery and performance reasons, shut down cores and
+ * lie about the number of active cores.
+ */
+#if G_HAVE_API_SUPPORT(HAVE_CLASSIC_WINAPI_SUPPORT)
+gint32
+mono_cpu_usage (MonoCpuUsageState *prev)
+{
+ gint32 cpu_usage = 0;
+ gint64 cpu_total_time;
+ gint64 cpu_busy_time;
+ guint64 idle_time;
+ guint64 kernel_time;
+ guint64 user_time;
+
+ if (!GetSystemTimes ((FILETIME*) &idle_time, (FILETIME*) &kernel_time, (FILETIME*) &user_time)) {
+ g_error ("GetSystemTimes() failed, error code is %d\n", GetLastError ());
+ return -1;
+ }
+
+ cpu_total_time = (gint64)((user_time - (prev ? prev->user_time : 0)) + (kernel_time - (prev ? prev->kernel_time : 0)));
+ cpu_busy_time = (gint64)(cpu_total_time - (idle_time - (prev ? prev->idle_time : 0)));
+
+ if (prev) {
+ prev->idle_time = idle_time;
+ prev->kernel_time = kernel_time;
+ prev->user_time = user_time;
+ }
+
+ if (cpu_total_time > 0 && cpu_busy_time > 0)
+ cpu_usage = (gint32)(cpu_busy_time * 100 / cpu_total_time);
+
+ return cpu_usage;
+}
+#endif /* G_HAVE_API_SUPPORT(HAVE_CLASSIC_WINAPI_SUPPORT) */
+#endif /* HOST_WIN32*/
--- /dev/null
+#ifndef __MONO_UTILS_PROCLIB_WINDOWS_H__
+#define __MONO_UTILS_PROCLIB_WINDOWS_H__
+
+#include <config.h>
+#include <glib.h>
+
+#ifdef HOST_WIN32
+#include <process.h>
+#include "mono/utils/mono-proclib.h"
+
+#endif /* HOST_WIN32 */
+#endif /* __MONO_UTILS_PROCLIB_WINDOWS_H__ */
+
#include <sched.h>
#endif
-#ifdef HOST_WIN32
-#include <windows.h>
-#include <process.h>
-#endif
-
#if defined(_POSIX_VERSION)
#include <sys/errno.h>
#include <sys/param.h>
char buf [256];
char *s;
FILE *f;
- int len = strlen (item);
+ size_t len = strlen (item);
g_snprintf (buf, sizeof (buf), "/proc/%d/status", pid);
f = fopen (buf, "r");
char fname [128];
FILE *file;
char *p;
- int r;
+ size_t r;
sprintf (fname, "/proc/%d/cmdline", GPOINTER_TO_INT (pid));
buf [0] = 0;
file = fopen (fname, "r");
char buf [512];
char *s, *end;
FILE *f;
- int len, i;
+ size_t len;
+ int i;
gint64 value;
g_snprintf (buf, sizeof (buf), "/proc/%d/stat", pid);
return mono_process_get_data_with_error (pid, data, &error);
}
+#ifndef HOST_WIN32
int
mono_process_current_pid ()
{
#if defined(HAVE_UNISTD_H)
return (int) getpid ();
-#elif defined(HOST_WIN32)
- return (int) GetCurrentProcessId ();
#else
#error getpid
#endif
}
+#endif /* !HOST_WIN32 */
/**
* mono_cpu_count:
*
* Return the number of processors on the system.
*/
+#ifndef HOST_WIN32
int
mono_cpu_count (void)
{
-#ifdef HOST_WIN32
- SYSTEM_INFO info;
- GetSystemInfo (&info);
- return info.dwNumberOfProcessors;
-#else
#ifdef PLATFORM_ANDROID
/* Android tries really hard to save power by powering off CPUs on SMP phones which
* means the normal way to query cpu count returns a wrong value with userspace API.
return count;
}
#endif
-#endif /* HOST_WIN32 */
/* FIXME: warn */
return 1;
}
+#endif /* !HOST_WIN32 */
static void
get_cpu_times (int cpu_id, gint64 *user, gint64 *systemt, gint64 *irq, gint64 *sirq, gint64 *idle)
* battery and performance reasons, shut down cores and
* lie about the number of active cores.
*/
+#ifndef HOST_WIN32
gint32
mono_cpu_usage (MonoCpuUsageState *prev)
{
gint32 cpu_usage = 0;
gint64 cpu_total_time;
gint64 cpu_busy_time;
-
-#ifndef HOST_WIN32
struct rusage resource_usage;
gint64 current_time;
gint64 kernel_time;
prev->user_time = user_time;
prev->current_time = current_time;
}
-#else
- guint64 idle_time;
- guint64 kernel_time;
- guint64 user_time;
-
- if (!GetSystemTimes ((FILETIME*) &idle_time, (FILETIME*) &kernel_time, (FILETIME*) &user_time)) {
- g_error ("GetSystemTimes() failed, error code is %d\n", GetLastError ());
- return -1;
- }
-
- cpu_total_time = (gint64)((user_time - (prev ? prev->user_time : 0)) + (kernel_time - (prev ? prev->kernel_time : 0)));
- cpu_busy_time = (gint64)(cpu_total_time - (idle_time - (prev ? prev->idle_time : 0)));
-
- if (prev) {
- prev->idle_time = idle_time;
- prev->kernel_time = kernel_time;
- prev->user_time = user_time;
- }
-#endif
if (cpu_total_time > 0 && cpu_busy_time > 0)
cpu_usage = (gint32)(cpu_busy_time * 100 / cpu_total_time);
return cpu_usage;
}
+#endif /* !HOST_WIN32 */
--- /dev/null
+/*
+ * mono-rand-windows-uwp.c: UWP rand support for Mono.
+ *
+ * Copyright 2016 Microsoft
+ * Licensed under the MIT license. See LICENSE file in the project root for full license information.
+*/
+#include <config.h>
+#include <glib.h>
+
+#if G_HAVE_API_SUPPORT(HAVE_UWP_WINAPI_SUPPORT)
+#include <Windows.h>
+#include "mono/utils/mono-rand-windows.h"
+
+MONO_WIN32_CRYPT_PROVIDER_HANDLE
+mono_rand_win_open_provider (void)
+{
+ MONO_WIN32_CRYPT_PROVIDER_HANDLE provider = 0;
+
+ if (!BCRYPT_SUCCESS (BCryptOpenAlgorithmProvider (&provider, BCRYPT_RNG_ALGORITHM, NULL, 0)))
+ provider = 0;
+
+ return provider;
+}
+
+gboolean
+mono_rand_win_gen (MONO_WIN32_CRYPT_PROVIDER_HANDLE provider, guchar *buffer, size_t buffer_size)
+{
+ g_assert (provider != 0 && buffer != 0);
+ return (BCRYPT_SUCCESS (BCryptGenRandom (provider, buffer, (ULONG) buffer_size, 0))) ? TRUE : FALSE;
+}
+
+gboolean
+mono_rand_win_seed (MONO_WIN32_CRYPT_PROVIDER_HANDLE provider, guchar *seed, size_t seed_size)
+{
+ g_assert (provider != 0 && seed != 0);
+ return (BCRYPT_SUCCESS (BCryptGenRandom (provider, seed, (ULONG) seed_size, BCRYPT_RNG_USE_ENTROPY_IN_BUFFER))) ? TRUE : FALSE;
+}
+
+void
+mono_rand_win_close_provider (MONO_WIN32_CRYPT_PROVIDER_HANDLE provider)
+{
+ g_assert (provider != 0);
+ BCryptCloseAlgorithmProvider (provider, 0);
+}
+
+#else /* G_HAVE_API_SUPPORT(HAVE_UWP_WINAPI_SUPPORT) */
+
+#ifdef _MSC_VER
+// Quiet Visual Studio linker warning, LNK4221, in cases when this source file intentional ends up empty.
+void __mono_win32_mono_rand_windows_uwp_quiet_lnk4221(void) {}
+#endif
+#endif /* G_HAVE_API_SUPPORT(HAVE_UWP_WINAPI_SUPPORT) */
--- /dev/null
+/*
+ * mono-rand-windows.c: Windows rand support for Mono.
+ *
+ * Copyright 2016 Microsoft
+ * Licensed under the MIT license. See LICENSE file in the project root for full license information.
+*/
+#include <config.h>
+#include <glib.h>
+#include "mono-error.h"
+#include "mono-error-internals.h"
+#include "mono-rand.h"
+
+#if defined(HOST_WIN32)
+#include <windows.h>
+#include "mono/utils/mono-rand-windows.h"
+
+#if G_HAVE_API_SUPPORT(HAVE_CLASSIC_WINAPI_SUPPORT)
+#ifndef PROV_INTEL_SEC
+#define PROV_INTEL_SEC 22
+#endif
+#ifndef CRYPT_VERIFY_CONTEXT
+#define CRYPT_VERIFY_CONTEXT 0xF0000000
+#endif
+
+MONO_WIN32_CRYPT_PROVIDER_HANDLE
+mono_rand_win_open_provider (void)
+{
+ MONO_WIN32_CRYPT_PROVIDER_HANDLE provider = 0;
+
+ /* There is no need to create a container for just random data,
+ * so we can use CRYPT_VERIFY_CONTEXT (one call) see:
+ * http://blogs.msdn.com/dangriff/archive/2003/11/19/51709.aspx */
+
+ /* We first try to use the Intel PIII RNG if drivers are present */
+ if (!CryptAcquireContext (&provider, NULL, NULL, PROV_INTEL_SEC, CRYPT_VERIFY_CONTEXT)) {
+ /* not a PIII or no drivers available, use default RSA CSP */
+ if (!CryptAcquireContext (&provider, NULL, NULL, PROV_RSA_FULL, CRYPT_VERIFY_CONTEXT)) {
+ /* exception will be thrown in managed code */
+ provider = 0;
+ }
+ }
+
+ return provider;
+}
+
+void
+mono_rand_win_close_provider (MONO_WIN32_CRYPT_PROVIDER_HANDLE provider)
+{
+ CryptReleaseContext (provider, 0);
+}
+
+gboolean
+mono_rand_win_gen (MONO_WIN32_CRYPT_PROVIDER_HANDLE provider, guchar *buffer, size_t buffer_size)
+{
+ return CryptGenRandom (provider, (DWORD) buffer_size, buffer);
+}
+
+gboolean
+mono_rand_win_seed (MONO_WIN32_CRYPT_PROVIDER_HANDLE provider, guchar *seed, size_t seed_size)
+{
+ /* add seeding material to the RNG */
+ return CryptGenRandom (provider, (DWORD) seed_size, seed);
+}
+#endif /* G_HAVE_API_SUPPORT(HAVE_CLASSIC_WINAPI_SUPPORT) */
+
+/**
+ * mono_rand_open:
+ *
+ * Returns: True if random source is global, false if mono_rand_init can be called repeatedly to get randomness instances.
+ *
+ * Initializes entire RNG system. Must be called once per process before calling mono_rand_init.
+ */
+gboolean
+mono_rand_open (void)
+{
+ return FALSE;
+}
+
+/**
+ * mono_rand_init:
+ * @seed: A string containing seed data
+ * @seed_size: Length of seed string
+ *
+ * Returns: On success, a non-NULL handle which can be used to fetch random data from mono_rand_try_get_bytes. On failure, NULL.
+ *
+ * Initializes an RNG client.
+ */
+gpointer
+mono_rand_init (guchar *seed, gint seed_size)
+{
+ MONO_WIN32_CRYPT_PROVIDER_HANDLE provider = 0;
+
+ /* try to open crypto provider. */
+ provider = mono_rand_win_open_provider ();
+
+ /* seed the CSP with the supplied buffer (if present) */
+ if (provider != 0 && seed != NULL) {
+ /* the call we replace the seed with random - this isn't what is
+ * expected from the class library user */
+ guchar *data = g_malloc (seed_size);
+ if (data != NULL) {
+ memcpy (data, seed, seed_size);
+ /* add seeding material to the RNG */
+ mono_rand_win_seed (provider, data, seed_size);
+ /* zeroize and free */
+ memset (data, 0, seed_size);
+ g_free (data);
+ }
+ }
+
+ return (gpointer) provider;
+}
+
+/**
+ * mono_rand_try_get_bytes:
+ * @handle: A pointer to an RNG handle. Handle is set to NULL on failure.
+ * @buffer: A buffer into which to write random data.
+ * @buffer_size: Number of bytes to write into buffer.
+ * @error: Set on error.
+ *
+ * Returns: FALSE on failure and sets @error, TRUE on success.
+ *
+ * Extracts bytes from an RNG handle.
+ */
+gboolean
+mono_rand_try_get_bytes (gpointer *handle, guchar *buffer, gint buffer_size, MonoError *error)
+{
+ MONO_WIN32_CRYPT_PROVIDER_HANDLE provider;
+
+ mono_error_init (error);
+
+ g_assert (handle);
+ provider = (MONO_WIN32_CRYPT_PROVIDER_HANDLE) *handle;
+
+ /* generate random bytes */
+ if (!mono_rand_win_gen (provider, buffer, buffer_size)) {
+ mono_rand_win_close_provider (provider);
+ /* we may have lost our context with CryptoAPI, but all hope isn't lost yet! */
+ provider = mono_rand_win_open_provider ();
+ if (provider != 0) {
+
+ /* retry generate of random bytes */
+ if (!mono_rand_win_gen (provider, buffer, buffer_size)) {
+ /* failure, close provider */
+ mono_rand_win_close_provider (provider);
+ provider = 0;
+ }
+ }
+
+ /* make sure client gets new opened provider handle or NULL on failure */
+ *handle = (gpointer) provider;
+ if (*handle == 0) {
+ /* exception will be thrown in managed code */
+ mono_error_set_execution_engine (error, "Failed to gen random bytes (%d)", GetLastError ());
+ return FALSE;
+ }
+ }
+ return TRUE;
+}
+
+/**
+ * mono_rand_close:
+ * @handle: An RNG handle.
+ *
+ * Releases an RNG handle.
+ */
+void
+mono_rand_close (gpointer handle)
+{
+ mono_rand_win_close_provider ((MONO_WIN32_CRYPT_PROVIDER_HANDLE) handle);
+}
+#endif /* HOST_WIN32 */
--- /dev/null
+#ifndef _MONO_UTILS_RAND_WINDOWS_H_
+#define _MONO_UTILS_RAND_WINDOWS_H_
+
+#include <config.h>
+#include <glib.h>
+
+#ifdef HOST_WIN32
+
+#if G_HAVE_API_SUPPORT(HAVE_CLASSIC_WINAPI_SUPPORT)
+#include <wincrypt.h>
+#define MONO_WIN32_CRYPT_PROVIDER_HANDLE HCRYPTPROV
+
+#else
+
+#include <bcrypt.h>
+#define MONO_WIN32_CRYPT_PROVIDER_HANDLE BCRYPT_ALG_HANDLE
+#endif
+
+MONO_WIN32_CRYPT_PROVIDER_HANDLE
+mono_rand_win_open_provider (void);
+
+gboolean
+mono_rand_win_gen (MONO_WIN32_CRYPT_PROVIDER_HANDLE provider, guchar *buffer, size_t buffer_size);
+
+gboolean
+mono_rand_win_seed (MONO_WIN32_CRYPT_PROVIDER_HANDLE provider, guchar *seed, size_t seed_size);
+
+void
+mono_rand_win_close_provider (MONO_WIN32_CRYPT_PROVIDER_HANDLE provider);
+
+#endif /* HOST_WIN32 */
+#endif /* _MONO_UTILS_RAND_WINDOWS_H_ */
+
* Licensed under the MIT license. See LICENSE file in the project root for full license information.
*/
-
#include <glib.h>
#include <config.h>
#include "metadata/object.h"
#ifdef HOST_WIN32
-
-#include <windows.h>
-#include <wincrypt.h>
-
-#ifndef PROV_INTEL_SEC
-#define PROV_INTEL_SEC 22
-#endif
-#ifndef CRYPT_VERIFY_CONTEXT
-#define CRYPT_VERIFY_CONTEXT 0xF0000000
-#endif
-
-/**
- * mono_rand_open:
- *
- * Returns: True if random source is global, false if mono_rand_init can be called repeatedly to get randomness instances.
- *
- * Initializes entire RNG system. Must be called once per process before calling mono_rand_init.
- */
-gboolean
-mono_rand_open (void)
-{
- return FALSE;
-}
-
-/**
- * mono_rand_init:
- * @seed: A string containing seed data
- * @seed_size: Length of seed string
- *
- * Returns: On success, a non-NULL handle which can be used to fetch random data from mono_rand_try_get_bytes. On failure, NULL.
- *
- * Initializes an RNG client.
- */
-gpointer
-mono_rand_init (guchar *seed, gint seed_size)
-{
- HCRYPTPROV provider = 0;
-
- /* There is no need to create a container for just random data,
- * so we can use CRYPT_VERIFY_CONTEXT (one call) see:
- * http://blogs.msdn.com/dangriff/archive/2003/11/19/51709.aspx */
-
- /* We first try to use the Intel PIII RNG if drivers are present */
- if (!CryptAcquireContext (&provider, NULL, NULL, PROV_INTEL_SEC, CRYPT_VERIFY_CONTEXT)) {
- /* not a PIII or no drivers available, use default RSA CSP */
- if (!CryptAcquireContext (&provider, NULL, NULL, PROV_RSA_FULL, CRYPT_VERIFY_CONTEXT)) {
- /* exception will be thrown in managed code */
- provider = 0;
- }
- }
-
- /* seed the CSP with the supplied buffer (if present) */
- if (provider != 0 && seed) {
- /* the call we replace the seed with random - this isn't what is
- * expected from the class library user */
- guchar *data = g_malloc (seed_size);
- if (data) {
- memcpy (data, seed, seed_size);
- /* add seeding material to the RNG */
- CryptGenRandom (provider, seed_size, data);
- /* zeroize and free */
- memset (data, 0, seed_size);
- g_free (data);
- }
- }
-
- return (gpointer) provider;
-}
-
-/**
- * mono_rand_try_get_bytes:
- * @handle: A pointer to an RNG handle. Handle is set to NULL on failure.
- * @buffer: A buffer into which to write random data.
- * @buffer_size: Number of bytes to write into buffer.
- * @error: Set on error.
- *
- * Returns: FALSE on failure and sets @error, TRUE on success.
- *
- * Extracts bytes from an RNG handle.
- */
-gboolean
-mono_rand_try_get_bytes (gpointer *handle, guchar *buffer, gint buffer_size, MonoError *error)
-{
- HCRYPTPROV provider;
-
- mono_error_init (error);
-
- g_assert (handle);
- provider = (HCRYPTPROV) *handle;
-
- if (!CryptGenRandom (provider, buffer_size, buffer)) {
- CryptReleaseContext (provider, 0);
- /* we may have lost our context with CryptoAPI, but all hope isn't lost yet! */
- provider = (HCRYPTPROV) mono_rand_init (NULL, 0);
- if (!CryptGenRandom (provider, buffer_size, buffer)) {
- /* exception will be thrown in managed code */
- CryptReleaseContext (provider, 0);
- *handle = 0;
- mono_error_set_execution_engine (error, "Failed to gen random bytes (%d)", GetLastError ());
- return FALSE;
- }
- }
- return TRUE;
-}
-
-/**
- * mono_rand_close:
- * @handle: An RNG handle.
- * @buffer: A buffer into which to write random data.
- * @buffer_size: Number of bytes to write into buffer.
- *
- * Releases an RNG handle.
- */
-void
-mono_rand_close (gpointer handle)
-{
- CryptReleaseContext ((HCRYPTPROV) handle, 0);
-}
-
+// Windows specific implementation in mono-rand-windows.c
#elif defined (HAVE_SYS_UN_H) && !defined(__native_client__)
#include <errno.h>
return -1;
}
+#else /* !HAVE_INET_PTON */
+
+#ifdef _MSC_VER
+// Quiet Visual Studio linker warning, LNK4221, in cases when this source file intentional ends up empty.
+void __mono_win32_networking_missing_lnk4221(void) {}
+#endif
#endif /* !HAVE_INET_PTON */
<ExcludedFromBuild Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">true</ExcludedFromBuild>\r
<ExcludedFromBuild Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">true</ExcludedFromBuild>\r
</ClInclude>\r
+ <ClInclude Include="..\mono\mini\mini-windows.h" />\r
<ClInclude Include="..\mono\mini\mini-x86.h">\r
<ExcludedFromBuild Condition="'$(Configuration)|$(Platform)'=='Debug|x64'">true</ExcludedFromBuild>\r
<ExcludedFromBuild Condition="'$(Configuration)|$(Platform)'=='Release|x64'">true</ExcludedFromBuild>\r
<ClInclude Include="..\mono\mini\mini-amd64-gsharedvt.h">\r
<Filter>Header Files</Filter>\r
</ClInclude>\r
+ <ClInclude Include="..\mono\mini\mini-windows.h">\r
+ <Filter>Header Files</Filter>\r
+ </ClInclude>\r
</ItemGroup>\r
<ItemGroup>\r
<Filter Include="Header Files">\r
<ClCompile Include="..\mono\utils\mono-log-common.c" />\r
<ClCompile Include="..\mono\utils\mono-math.c" />\r
<ClCompile Include="..\mono\utils\mono-md5.c" />\r
+ <ClCompile Include="..\mono\utils\mono-mmap-windows.c" />\r
<ClCompile Include="..\mono\utils\mono-mmap.c" />\r
<ClCompile Include="..\mono\utils\mono-networkinterfaces.c" />\r
+ <ClCompile Include="..\mono\utils\mono-proclib-windows.c" />\r
+ <ClCompile Include="..\mono\utils\mono-rand-windows.c" />\r
<ClCompile Include="..\mono\utils\mono-rand.c" />\r
<ClCompile Include="..\mono\utils\mono-threads-state-machine.c" />\r
<ClCompile Include="..\mono\utils\networking.c" />\r
<ClInclude Include="..\mono\utils\mono-counters.h" />\r
<ClInclude Include="..\mono\utils\mono-digest.h" />\r
<ClInclude Include="..\mono\utils\mono-dl-fallback.h" />\r
+ <ClInclude Include="..\mono\utils\mono-dl-windows.h" />\r
<ClInclude Include="..\mono\utils\mono-dl.h" />\r
<ClInclude Include="..\mono\utils\mono-error-internals.h" />\r
<ClInclude Include="..\mono\utils\mono-error.h" />\r
<ClInclude Include="..\mono\utils\mono-math.h" />\r
<ClInclude Include="..\mono\utils\mono-membar.h" />\r
<ClInclude Include="..\mono\utils\mono-memory-model.h" />\r
+ <ClInclude Include="..\mono\utils\mono-mmap-windows.h" />\r
<ClInclude Include="..\mono\utils\mono-mmap.h" />\r
<ClInclude Include="..\mono\utils\mono-networkinterfaces.h" />\r
<ClInclude Include="..\mono\utils\mono-once.h" />\r
<ClInclude Include="..\mono\utils\mono-os-semaphore.h" />\r
<ClInclude Include="..\mono\utils\mono-path.h" />\r
<ClInclude Include="..\mono\utils\mono-poll.h" />\r
+ <ClInclude Include="..\mono\utils\mono-proclib-windows.h" />\r
<ClInclude Include="..\mono\utils\mono-proclib.h" />\r
<ClInclude Include="..\mono\utils\mono-property-hash.h" />\r
<ClInclude Include="..\mono\utils\mono-publib.h" />\r
+ <ClInclude Include="..\mono\utils\mono-rand-windows.h" />\r
<ClInclude Include="..\mono\utils\mono-rand.h" />\r
<ClInclude Include="..\mono\utils\mono-sigcontext.h" />\r
<ClInclude Include="..\mono\utils\mono-stack-unwinding.h" />\r
<ImportGroup Label="ExtensionTargets">\r
<Import Project="$(VCTargetsPath)\BuildCustomizations\masm.targets" />\r
</ImportGroup>\r
-</Project>
+</Project>
\ No newline at end of file
<ClCompile Include="..\mono\utils\mono-log-windows.c">\r
<Filter>Source Files</Filter>\r
</ClCompile>\r
+ <ClCompile Include="..\mono\utils\mono-rand-windows.c">\r
+ <Filter>Source Files</Filter>\r
+ </ClCompile>\r
+ <ClCompile Include="..\mono\utils\mono-proclib-windows.c">\r
+ <Filter>Source Files</Filter>\r
+ </ClCompile>\r
+ <ClCompile Include="..\mono\utils\mono-mmap-windows.c">\r
+ <Filter>Source Files</Filter>\r
+ </ClCompile>\r
</ItemGroup>\r
<ItemGroup>\r
<ClInclude Include="..\mono\utils\atomic.h">\r
<ClInclude Include="..\mono\utils\valgrind.h">\r
<Filter>Header Files</Filter>\r
</ClInclude>\r
+ <ClInclude Include="..\mono\utils\mono-rand-windows.h">\r
+ <Filter>Header Files</Filter>\r
+ </ClInclude>\r
+ <ClInclude Include="..\mono\utils\mono-dl-windows.h">\r
+ <Filter>Header Files</Filter>\r
+ </ClInclude>\r
+ <ClInclude Include="..\mono\utils\mono-mmap-windows.h">\r
+ <Filter>Header Files</Filter>\r
+ </ClInclude>\r
+ <ClInclude Include="..\mono\utils\mono-proclib-windows.h">\r
+ <Filter>Header Files</Filter>\r
+ </ClInclude>\r
</ItemGroup>\r
<ItemGroup>\r
<Filter Include="Header Files">\r
${TESTCMD} --label=profiler --timeout=30m make -w -C mono/profiler -k check
${TESTCMD} --label=compiler --timeout=30m make -w -C mcs/tests run-test
${TESTCMD} --label=compiler-errors --timeout=30m make -w -C mcs/errors run-test
+export MONO_TLS_PROVIDER=legacy
if [[ -n "${ghprbPullId}" ]] && [[ ${label} == w* ]]; then ${TESTCMD} --label=System --skip; else ${TESTCMD} --label=System --timeout=10m make -w -C mcs/class/System run-test; fi
+if [[ ${label} == osx-* ]]; then export MONO_TLS_PROVIDER=btls && ${TESTCMD} --label=System-btls --timeout=10m make -w -C mcs/class/System run-test; fi
+unset MONO_TLS_PROVIDER
${TESTCMD} --label=System.XML --timeout=5m make -w -C mcs/class/System.XML run-test
${TESTCMD} --label=Mono.Security --timeout=5m make -w -C mcs/class/Mono.Security run-test
if [[ -n "${ghprbPullId}" ]] && [[ ${label} == w* ]]; then ${TESTCMD} --label=System.Security --skip; else ${TESTCMD} --label=System.Security --timeout=5m make -w -C mcs/class/System.Security run-test; fi
${TESTCMD} --label=System.Threading.Tasks.Dataflow --timeout=5m make -w -C mcs/class/System.Threading.Tasks.Dataflow run-test
${TESTCMD} --label=Mono.Debugger.Soft --timeout=5m make -w -C mcs/class/Mono.Debugger.Soft run-test
if [[ -n "${ghprbPullId}" ]] && [[ ${label} == w* ]]; then ${TESTCMD} --label=Microsoft.Build --skip; else ${TESTCMD} --label=Microsoft.Build --timeout=5m make -w -C mcs/class/Microsoft.Build run-test; fi
-if [[ -n "${ghprbPullId}" ]] && [[ ${label} == w* ]]; then ${TESTCMD} --label=monodoc --skip; else ${TESTCMD} --label=monodoc --timeout=10m make -w -C mcs/tools/mdoc run-test; fi
+${TESTCMD} --label=monodoc --timeout=10m make -w -C mcs/tools/mdoc run-test
if [[ -n "${ghprbPullId}" ]] && [[ ${label} == w* ]]; then ${TESTCMD} --label=Microsoft.Build-12 --skip; else ${TESTCMD} --label=Microsoft.Build-12 --timeout=10m make -w -C mcs/class/Microsoft.Build run-test PROFILE=xbuild_12; fi
if [[ -n "${ghprbPullId}" ]] && [[ ${label} == w* ]]; then ${TESTCMD} --label=Microsoft.Build.Engine-12 --skip; else ${TESTCMD} --label=Microsoft.Build.Engine-12 --timeout=60m make -w -C mcs/class/Microsoft.Build.Engine run-test PROFILE=xbuild_12; fi
${TESTCMD} --label=Microsoft.Build.Framework-12 --timeout=60m make -w -C mcs/class/Microsoft.Build.Framework run-test PROFILE=xbuild_12