5
5
using System ;
6
6
using System . Collections . Generic ;
7
7
using System . IO ;
8
+ using static System . Collections . Specialized . BitVector32 ;
8
9
9
10
namespace LibObjectFile . Elf
10
11
{
@@ -17,8 +18,8 @@ internal abstract class ElfReader<TDecoder> : ElfReader where TDecoder : struct,
17
18
private TDecoder _decoder ;
18
19
private ulong _startOfFile ;
19
20
private ushort _programHeaderCount ;
20
- private ushort _sectionHeaderCount ;
21
- private ushort _sectionStringTableIndex ;
21
+ private uint _sectionHeaderCount ;
22
+ private uint _sectionStringTableIndex ;
22
23
private bool _isFirstSectionValidNull ;
23
24
private bool _hasValidSectionStringTable ;
24
25
@@ -193,7 +194,7 @@ private ElfSegment ReadProgramHeader64(int phdrIndex)
193
194
194
195
private void ReadSections ( )
195
196
{
196
- if ( _sectionHeaderCount == 0 ) return ;
197
+ if ( Layout . OffsetOfSectionHeaderTable == 0 ) return ;
197
198
198
199
// Write section header table
199
200
ReadSectionHeaderTable ( ) ;
@@ -210,9 +211,25 @@ private void ReadSectionHeaderTable()
210
211
return ;
211
212
}
212
213
213
- for ( int i = 0 ; i < _sectionHeaderCount ; i ++ )
214
+ uint i = 0 ;
215
+
216
+ if ( _sectionHeaderCount == 0 )
214
217
{
215
- var offset = Layout . OffsetOfSectionHeaderTable + ( ulong ) i * Layout . SizeOfSectionHeaderEntry ;
218
+ // We are dealing with an object file that has more than SHN_LORESERVE
219
+ // (0xff00) sections. It has to begin with a NULL section header where
220
+ // its Size contains the real number of sections, and Link optionally
221
+ // points to string table section if it's section index is too high.
222
+ if ( ReadExtendedNullSectionTableEntry ( ) )
223
+ {
224
+ i = 1 ;
225
+ ObjectFile . AddSection ( new ElfNullSection ( ) ) ;
226
+ _isFirstSectionValidNull = true ;
227
+ }
228
+ }
229
+
230
+ for ( ; i < _sectionHeaderCount ; i ++ )
231
+ {
232
+ var offset = Layout . OffsetOfSectionHeaderTable + i * Layout . SizeOfSectionHeaderEntry ;
216
233
217
234
if ( offset >= ( ulong ) Stream . Length )
218
235
{
@@ -228,12 +245,12 @@ private void ReadSectionHeaderTable()
228
245
}
229
246
}
230
247
231
- private ElfSection ReadSectionTableEntry ( int sectionIndex )
248
+ private ElfSection ReadSectionTableEntry ( uint sectionIndex )
232
249
{
233
250
return ObjectFile . FileClass == ElfFileClass . Is32 ? ReadSectionTableEntry32 ( sectionIndex ) : ReadSectionTableEntry64 ( sectionIndex ) ;
234
251
}
235
252
236
- private ElfSection ReadSectionTableEntry32 ( int sectionIndex )
253
+ private ElfSection ReadSectionTableEntry32 ( uint sectionIndex )
237
254
{
238
255
var streamOffset = Stream . Position ;
239
256
if ( ! TryReadData ( Layout . SizeOfSectionHeaderEntry , out ElfNative . Elf32_Shdr rawSection ) )
@@ -267,7 +284,7 @@ private ElfSection ReadSectionTableEntry32(int sectionIndex)
267
284
return section ;
268
285
}
269
286
270
- private ElfSection ReadSectionTableEntry64 ( int sectionIndex )
287
+ private ElfSection ReadSectionTableEntry64 ( uint sectionIndex )
271
288
{
272
289
var streamOffset = Stream . Position ;
273
290
if ( ! TryReadData ( Layout . SizeOfSectionHeaderEntry , out ElfNative . Elf64_Shdr rawSection ) )
@@ -300,6 +317,68 @@ private ElfSection ReadSectionTableEntry64(int sectionIndex)
300
317
301
318
return section ;
302
319
}
320
+
321
+ private bool ReadExtendedNullSectionTableEntry ( )
322
+ {
323
+ uint sh_type ;
324
+ ulong sh_size ;
325
+ uint sh_link ;
326
+ bool isNull ;
327
+
328
+ Stream . Position = ( long ) Layout . OffsetOfSectionHeaderTable ;
329
+
330
+ if ( ObjectFile . FileClass == ElfFileClass . Is32 )
331
+ {
332
+
333
+ if ( ! TryReadData ( Layout . SizeOfSectionHeaderEntry , out ElfNative . Elf32_Shdr rawSection32 ) )
334
+ {
335
+ Diagnostics . Error ( DiagnosticId . ELF_ERR_IncompleteSectionHeader32Size , $ "Unable to read entirely NULL section header. Not enough data (size: { Layout . SizeOfSectionHeaderEntry } ) read at offset { Layout . OffsetOfSectionHeaderTable } from the stream") ;
336
+ return false ;
337
+ }
338
+
339
+ sh_type = _decoder . Decode ( rawSection32 . sh_type ) ;
340
+ sh_size = _decoder . Decode ( rawSection32 . sh_size ) ;
341
+ sh_link = _decoder . Decode ( rawSection32 . sh_link ) ;
342
+ rawSection32 . sh_size = 0 ;
343
+ rawSection32 . sh_link = 0 ;
344
+ isNull = rawSection32 . IsNull ;
345
+ }
346
+ else
347
+ {
348
+ if ( ! TryReadData ( Layout . SizeOfSectionHeaderEntry , out ElfNative . Elf64_Shdr rawSection64 ) )
349
+ {
350
+ Diagnostics . Error ( DiagnosticId . ELF_ERR_IncompleteSectionHeader64Size , $ "Unable to read entirely NULL section header. Not enough data (size: { Layout . SizeOfSectionHeaderEntry } ) read at offset { Layout . OffsetOfSectionHeaderTable } from the stream") ;
351
+ return false ;
352
+ }
353
+
354
+ sh_type = _decoder . Decode ( rawSection64 . sh_type ) ;
355
+ sh_size = _decoder . Decode ( rawSection64 . sh_size ) ;
356
+ sh_link = _decoder . Decode ( rawSection64 . sh_link ) ;
357
+ rawSection64 . sh_size = 0 ;
358
+ rawSection64 . sh_link = 0 ;
359
+ isNull = rawSection64 . IsNull ;
360
+ }
361
+
362
+ if ( ! isNull )
363
+ {
364
+ Diagnostics . Error ( DiagnosticId . ELF_ERR_InvalidFirstSectionExpectingUndefined , $ "Invalid Section [0] { ( ElfSectionType ) sh_type } . Expecting { ElfNative . SHN_UNDEF } ") ;
365
+ return false ;
366
+ }
367
+
368
+ if ( sh_size >= uint . MaxValue )
369
+ {
370
+ Diagnostics . Error ( DiagnosticId . ELF_ERR_InvalidSectionHeaderCount , $ "Extended section count [{ sh_size } ] exceeds { uint . MaxValue } ") ;
371
+ return false ;
372
+ }
373
+
374
+ _sectionHeaderCount = ( uint ) sh_size ;
375
+ if ( _sectionStringTableIndex == ElfNative . SHN_XINDEX )
376
+ {
377
+ _sectionStringTableIndex = sh_link ;
378
+ }
379
+
380
+ return true ;
381
+ }
303
382
304
383
public override ElfSectionLink ResolveLink ( ElfSectionLink link , string errorMessageFormat )
305
384
{
@@ -609,7 +688,7 @@ private void VerifyAndFixProgramHeadersAndSections()
609
688
}
610
689
}
611
690
612
- private ElfSection CreateElfSection ( int sectionIndex , ElfSectionType sectionType , bool isNullSection )
691
+ private ElfSection CreateElfSection ( uint sectionIndex , ElfSectionType sectionType , bool isNullSection )
613
692
{
614
693
ElfSection section = null ;
615
694
0 commit comments