@@ -112,7 +112,8 @@ public static bool IsEmptyAOTLibrary (TaskLoggingHelper log, string path)
112112 }
113113
114114 try {
115- return IsEmptyAOTLibrary ( log , path , ELFReader . Load ( path ) ) ;
115+ using IELF elf = ELFReader . Load ( path ) ;
116+ return IsEmptyAOTLibrary ( log , path , elf ) ;
116117 } catch ( Exception ex ) {
117118 log . LogWarning ( $ "Attempt to check whether '{ path } ' is a valid ELF file failed with exception, ignoring AOT check for the file.") ;
118119 log . LogWarningFromException ( ex , showStackTrace : true ) ;
@@ -126,7 +127,7 @@ public static bool ReferencesLibrary (string libraryPath, string referencedLibra
126127 return false ;
127128 }
128129
129- IELF elf = ELFReader . Load ( libraryPath ) ;
130+ using IELF elf = ELFReader . Load ( libraryPath ) ;
130131 var dynstr = GetSection ( elf , ".dynstr" ) as IStringTable ;
131132 if ( dynstr == null ) {
132133 return false ;
@@ -143,6 +144,44 @@ public static bool ReferencesLibrary (string libraryPath, string referencedLibra
143144 return false ;
144145 }
145146
147+ public static bool LibraryHasSymbol ( TaskLoggingHelper log , string elfPath , string sectionName , string symbolName , ELFSymbolType symbolType = ELFSymbolType . NotSpecified )
148+ {
149+ if ( elfPath . IsNullOrEmpty ( ) || ! File . Exists ( elfPath ) ) {
150+ return false ;
151+ }
152+
153+ try {
154+ using IELF elf = ELFReader . Load ( elfPath ) ;
155+ return HasSymbol ( elf , sectionName , symbolName , symbolType ) ;
156+ } catch ( Exception ex ) {
157+ log . LogWarning ( $ "Attempt to check whether '{ elfPath } ' is a valid ELF file failed with exception, ignoring symbol '{ symbolName } @{ sectionName } ' check for the file.") ;
158+ log . LogWarningFromException ( ex , showStackTrace : true ) ;
159+ return false ;
160+ }
161+ }
162+
163+ public static bool LibraryHasPublicSymbol ( TaskLoggingHelper log , string elfPath , string symbolName , ELFSymbolType symbolType = ELFSymbolType . NotSpecified ) => LibraryHasSymbol ( log , elfPath , ".dynsym" , symbolName , symbolType ) ;
164+
165+ public static bool HasSymbol ( IELF elf , string sectionName , string symbolName , ELFSymbolType symbolType = ELFSymbolType . NotSpecified )
166+ {
167+ ISymbolTable ? symtab = GetSymbolTable ( elf , sectionName ) ;
168+ if ( symtab == null ) {
169+ return false ;
170+ }
171+
172+ foreach ( var entry in symtab . Entries ) {
173+ if ( MonoAndroidHelper . StringEquals ( symbolName , entry . Name ) && ( symbolType == ELFSymbolType . NotSpecified || entry . Type == symbolType ) ) {
174+ return true ;
175+ }
176+ }
177+
178+ return false ;
179+ }
180+
181+ public static bool HasPublicSymbol ( IELF elf , string symbolName , ELFSymbolType symbolType = ELFSymbolType . NotSpecified ) => HasSymbol ( elf , ".dynsym" , symbolName , symbolType ) ;
182+
183+ public static bool IsJniLibrary ( TaskLoggingHelper log , string elfPath ) => LibraryHasPublicSymbol ( log , elfPath , "JNI_OnLoad" , ELFSymbolType . Function ) ;
184+
146185 static bool IsLibraryReference ( IStringTable stringTable , IDynamicEntry dynEntry , string referencedLibraryName )
147186 {
148187 if ( dynEntry . Tag != DynamicTag . Needed ) {
@@ -163,26 +202,12 @@ static bool IsLibraryReference (IStringTable stringTable, IDynamicEntry dynEntry
163202
164203 static bool IsEmptyAOTLibrary ( TaskLoggingHelper log , string path , IELF elf )
165204 {
166- ISymbolTable ? symtab = GetSymbolTable ( elf , ".dynsym" ) ;
167- if ( symtab == null ) {
168- // We can't be sure what the DSO is, play safe
169- return false ;
170- }
171-
172- bool mono_aot_file_info_found = false ;
173- foreach ( var entry in symtab . Entries ) {
174- if ( MonoAndroidHelper . StringEquals ( "mono_aot_file_info" , entry . Name ) && entry . Type == ELFSymbolType . Object ) {
175- mono_aot_file_info_found = true ;
176- break ;
177- }
178- }
179-
180- if ( ! mono_aot_file_info_found ) {
205+ if ( ! HasPublicSymbol ( elf , "mono_aot_file_info" , ELFSymbolType . Object ) ) {
181206 // Not a MonoVM AOT assembly
182207 return false ;
183208 }
184209
185- symtab = GetSymbolTable ( elf , ".symtab" ) ;
210+ ISymbolTable ? symtab = GetSymbolTable ( elf , ".symtab" ) ;
186211 if ( symtab == null ) {
187212 // The DSO is stripped, we can't tell if there are any functions defined (.text will be present anyway)
188213 // We perhaps **can** take a look at the .text section size, but it's not a solid check...
0 commit comments