@@ -50,11 +50,14 @@ public class SharedLibrary : IAspect, IDisposable
5050
5151 protected IELF ELF => elf ;
5252
53- protected SharedLibrary ( Stream stream , string libraryName )
53+ protected SharedLibrary ( Stream stream , string libraryName , IAspectState state )
5454 {
55+ var libState = EnsureValidAspectState < SharedLibraryAspectState > ( state ) ;
56+
5557 this . libraryStream = stream ;
5658 this . libraryName = libraryName ;
57- ( elf , is64Bit , nativeArch ) = LoadELF ( stream , libraryName ) ;
59+ elf = libState . ElfImage ! ;
60+ ( is64Bit , nativeArch ) = ValidateELF ( libState . ElfImage ! , libraryName ) ;
5861 ( payloadOffset , payloadSize ) = FindAndroidPayload ( elf ) ;
5962 libraryAlignment = DetectAlignment ( elf , is64Bit ) ;
6063 ( hasDebugInfo , debugLink ) = DetectDebugInfo ( elf , libraryName ) ;
@@ -63,20 +66,31 @@ protected SharedLibrary (Stream stream, string libraryName)
6366 soname = GetSoname ( elf , is64Bit ) ;
6467 }
6568
69+ protected static T EnsureValidAspectState < T > ( IAspectState ? state ) where T : IAspectState
70+ {
71+ if ( ! ( state is SharedLibraryAspectState libState ) ) {
72+ throw new InvalidOperationException ( "Internal error: invalid aspect state, call ProbeAspect to get one." ) ;
73+ }
74+
75+ if ( ! libState . Success || libState . ElfImage == null ) {
76+ throw new InvalidOperationException ( "Internal error: ProbeAspect failed to detect a valid shared library." ) ;
77+ }
78+
79+ return ( T ) ( ( object ) libState ) ;
80+ }
81+
6682 public static IAspect LoadAspect ( Stream stream , IAspectState ? state , string ? description )
6783 {
6884 if ( String . IsNullOrEmpty ( description ) ) {
6985 throw new ArgumentException ( "Must be a shared library name" , nameof ( description ) ) ;
7086 }
7187
72- if ( ! IsSupportedELFSharedLibrary ( stream , description ) ) {
73- throw new InvalidOperationException ( "Stream is not a supported ELF shared library" ) ;
74- }
88+ var libState = EnsureValidAspectState < SharedLibraryAspectState > ( state ) ;
7589
76- return new SharedLibrary ( stream , description ) ;
90+ return new SharedLibrary ( stream , description , libState ) ;
7791 }
7892
79- public static IAspectState ProbeAspect ( Stream stream , string ? description ) => new BasicAspectState ( IsSupportedELFSharedLibrary ( stream , description ) ) ;
93+ public static IAspectState ProbeAspect ( Stream stream , string ? description ) => IsSupportedELFSharedLibrary ( stream , description ) ;
8094
8195 /// <summary>
8296 /// If the library has .NET for Android payload section, this
@@ -164,35 +178,26 @@ protected static bool IsSupportedELFSharedLibrary (Stream stream, string? descri
164178 return supported ;
165179 }
166180
167- protected static bool IsSupportedELFSharedLibrary ( Stream stream , string ? description )
181+ protected static IAspectState IsSupportedELFSharedLibrary ( Stream stream , string ? description )
168182 {
169183 if ( ! IsSupportedELFSharedLibrary ( stream , description , out IELF ? elf ) || elf == null ) {
170- return false ;
184+ return new SharedLibraryAspectState ( false , null ) ;
171185 }
172186
173- elf . Dispose ( ) ;
174- return true ;
187+ return new SharedLibraryAspectState ( true , elf ) ;
175188 }
176189
177- // We assume below that stream corresponds to a valid and supported by us ELF image. This should have been asserted by
178- // the `LoadAspect` method.
179- ( IELF elf , bool is64bit , NativeArchitecture nativeArch ) LoadELF ( Stream stream , string ? libraryName )
190+ ( bool is64bit , NativeArchitecture nativeArch ) ValidateELF ( IELF elf , string ? libraryName )
180191 {
181- stream . Seek ( 0 , SeekOrigin . Begin ) ;
182- if ( ! ELFReader . TryLoad ( stream , shouldOwnStream : false , out IELF ? elf ) || elf == null ) {
183- Log . Debug ( $ "SharedLibrary: stream ('{ libraryName } ') failed to load as an ELF image.") ;
184- throw new InvalidOperationException ( $ "Failed to load ELF library '{ libraryName } '.") ;
185- }
186-
187192 ( bool is64 , NativeArchitecture arch ) = elf . Machine switch {
188193 Machine . ARM => ( false , NativeArchitecture . Arm ) ,
189194 Machine . Intel386 => ( false , NativeArchitecture . X86 ) ,
190195 Machine . AArch64 => ( true , NativeArchitecture . Arm64 ) ,
191196 Machine . AMD64 => ( true , NativeArchitecture . X64 ) ,
192- _ => throw new NotSupportedException ( $ "Unsupported ELF architecture '{ elf . Machine } '")
197+ _ => throw new NotSupportedException ( $ "Unsupported ELF architecture '{ elf . Machine } ' for ' { libraryName } ' ")
193198 } ;
194199
195- return ( elf , is64 , arch ) ;
200+ return ( is64 , arch ) ;
196201 }
197202
198203 ( ulong offset , ulong size ) FindAndroidPayload ( IELF elf )
0 commit comments