1
1
// Licensed to the .NET Foundation under one or more agreements.
2
2
// The .NET Foundation licenses this file to you under the MIT license.
3
3
4
+ using System ;
4
5
using System . IO ;
6
+ using System . Text ;
5
7
using Microsoft . Diagnostics . DataContractReader . Decoder . PETypes ;
6
- using Microsoft . Diagnostics . DataContractReader . Legacy ;
7
8
8
9
namespace Microsoft . Diagnostics . DataContractReader . Decoder ;
9
- internal sealed class PEDecoder
10
+ internal sealed class PEDecoder : IDisposable
10
11
{
11
- private readonly ICLRDataTarget _dataTarget ;
12
- private readonly ulong _baseAddress ;
12
+ private readonly Stream _stream ;
13
13
private uint _peSigOffset ;
14
14
private ushort _optHeaderMagic ;
15
15
private IMAGE_EXPORT_DIRECTORY _exportDir ;
16
+ private bool _disposedValue ;
16
17
17
18
public bool IsValid { get ; init ; }
18
19
19
- public PEDecoder ( ICLRDataTarget dataTarget , ulong baseAddress )
20
+ /// <summary>
21
+ /// Create PEDecoder with stream beginning at the base address of the module.
22
+ /// </summary>
23
+ public PEDecoder ( Stream stream )
20
24
{
21
- _dataTarget = dataTarget ;
22
- _baseAddress = baseAddress ;
25
+ _stream = stream ;
23
26
24
27
IsValid = Initialize ( ) ;
25
28
}
26
29
27
30
private bool Initialize ( )
28
31
{
29
- using BinaryReader reader = new ( new DataTargetStream ( _dataTarget , _baseAddress ) ) ;
32
+ using BinaryReader reader = new ( _stream , Encoding . UTF8 , leaveOpen : true ) ;
30
33
31
34
ushort dosMagic = reader . ReadUInt16 ( ) ;
32
35
if ( dosMagic != 0x5A4D ) // "MZ"
@@ -71,12 +74,13 @@ private bool Initialize()
71
74
return true ;
72
75
}
73
76
74
- public TargetPointer GetSymbolAddress ( string symbol )
77
+ public bool TryGetRelativeSymbolAddress ( string symbol , out ulong address )
75
78
{
79
+ address = 0 ;
76
80
if ( ! IsValid )
77
- return TargetPointer . Null ;
81
+ return false ;
78
82
79
- using BinaryReader reader = new ( new DataTargetStream ( _dataTarget , _baseAddress ) ) ;
83
+ using BinaryReader reader = new ( _stream , Encoding . UTF8 , leaveOpen : true ) ;
80
84
81
85
for ( int nameIndex = 0 ; nameIndex < _exportDir . NumberOfNames ; nameIndex ++ )
82
86
{
@@ -99,10 +103,31 @@ public TargetPointer GetSymbolAddress(string symbol)
99
103
reader . BaseStream . Seek ( _exportDir . AddressOfFunctions + sizeof ( uint ) * ordinalForNamedExport , SeekOrigin . Begin ) ;
100
104
uint symbolRVA = reader . ReadUInt32 ( ) ;
101
105
102
- return new TargetPointer ( _baseAddress + symbolRVA ) ;
106
+ address = symbolRVA ;
107
+ return true ;
108
+ }
109
+ }
110
+
111
+ return false ;
112
+ }
113
+
114
+ private void Dispose ( bool disposing )
115
+ {
116
+ if ( ! _disposedValue )
117
+ {
118
+ if ( disposing )
119
+ {
120
+ _stream . Close ( ) ;
103
121
}
122
+
123
+ _disposedValue = true ;
104
124
}
125
+ }
105
126
106
- return TargetPointer . Null ;
127
+ void IDisposable . Dispose ( )
128
+ {
129
+ // Do not change this code. Put cleanup code in 'Dispose(bool disposing)' method
130
+ Dispose ( disposing : true ) ;
131
+ GC . SuppressFinalize ( this ) ;
107
132
}
108
133
}
0 commit comments