From e187b00be3ad3b84e598983363efea1a3e152d64 Mon Sep 17 00:00:00 2001 From: Aleksey Kliger Date: Tue, 16 May 2023 09:52:27 -0400 Subject: [PATCH] Don't modify MonoImageStorage:raw_data instead just keep track of the webcil offset in the MonoImageStorage. This introduces a situation where MonoImage:raw_data is different from MonoImageStorage:raw_data. The one to use for accessing IL and metadata is MonoImage:raw_data. The storage pointer is just used by the image loading machinery --- src/mono/mono/metadata/metadata-internals.h | 8 +++++++- src/mono/mono/metadata/webcil-loader.c | 14 +++++++++----- 2 files changed, 16 insertions(+), 6 deletions(-) diff --git a/src/mono/mono/metadata/metadata-internals.h b/src/mono/mono/metadata/metadata-internals.h index 009861f03dfe4..e073ab2ea4831 100644 --- a/src/mono/mono/metadata/metadata-internals.h +++ b/src/mono/mono/metadata/metadata-internals.h @@ -282,6 +282,12 @@ typedef struct { /* Module entry point is _CorDllMain. */ guint8 has_entry_point : 1; #endif +#ifdef ENABLE_WEBCIL + /* set to a non-zero value when we load a webcil-in-wasm image. + * Note that in that case MonoImage:raw_data is not equal to MonoImageStorage:raw_data + */ + int32_t webcil_section_adjustment; +#endif } MonoImageStorage; struct _MonoImage { @@ -297,7 +303,7 @@ struct _MonoImage { MonoImageStorage *storage; - /* Aliases storage->raw_data when storage is non-NULL. Otherwise NULL. */ + /* Points into storage->raw_data when storage is non-NULL. Otherwise NULL. */ char *raw_data; guint32 raw_data_len; diff --git a/src/mono/mono/metadata/webcil-loader.c b/src/mono/mono/metadata/webcil-loader.c index 00d4987c6e84f..c96523af29373 100644 --- a/src/mono/mono/metadata/webcil-loader.c +++ b/src/mono/mono/metadata/webcil-loader.c @@ -137,12 +137,16 @@ webcil_image_load_pe_data (MonoImage *image) goto invalid_image; /* HACK! RVAs and debug table entry pointers are from the beginning of the webcil payload. adjust MonoImage:raw_data to point to it */ g_assert (image->ref_count == 1); - g_assert (image->storage->ref.ref == 1); + // NOTE: image->storage->raw_data could be shared if we loaded this image multiple times (for different ALCs, for example) + // Do not adjust image->storage->raw_data. +#ifdef ENABLE_WEBCIL + int32_t old_adjustment; + old_adjustment = mono_atomic_cas_i32 ((volatile gint32*)&image->storage->webcil_section_adjustment, webcil_section_adjustment, 0); + g_assert (old_adjustment == 0 || old_adjustment == webcil_section_adjustment); +#endif mono_trace (G_LOG_LEVEL_DEBUG, MONO_TRACE_ASSEMBLY, "Adjusting offset image %s [%p].", image->name, image); - image->storage->raw_data += webcil_section_adjustment; - image->storage->raw_data_len -= webcil_section_adjustment; - image->raw_data = image->storage->raw_data; - image->raw_data_len = image->storage->raw_data_len; + image->raw_data += webcil_section_adjustment; + image->raw_data_len -= webcil_section_adjustment; offset -= webcil_section_adjustment; // parts of ecma-335 loading depend on 4-byte alignment of the image g_assertf (((intptr_t)image->raw_data) % 4 == 0, "webcil image %s [%p] raw data %p not 4 byte aligned\n", image->name, image, image->raw_data);