private void LoadNotes() { if (_notes != null) { return; } LoadProgramHeaders(); ElfProgramHeader noteHeader = _programHeaders.SingleOrDefault(ph => ph.Header.Type == ELFProgramHeaderType.Note); if (noteHeader == null) { _notes = new ElfNote[0]; return; } List <ElfNote> notes = new List <ElfNote>(); Reader reader = new Reader(noteHeader.AddressSpace); long position = 0; while (position < reader.DataSource.Length) { ElfNote note = new ElfNote(reader, position); notes.Add(note); position += note.TotalSize; } _notes = notes.ToArray(); }
private int GetFirstSegmentContaining(long address) { int lower = 0; int upper = _segments.Length - 1; while (lower <= upper) { int mid = (lower + upper) >> 1; ElfProgramHeader segment = _segments[mid]; long virtualAddress = segment.VirtualAddress; long virtualSize = segment.VirtualSize; if (virtualAddress <= address && address < virtualAddress + virtualSize) { while (mid > 0 && address < _segments[mid - 1].VirtualAddress + _segments[mid - 1].VirtualSize) { mid--; } return(mid); } if (address < virtualAddress) { upper = mid - 1; } else { lower = mid + 1; } } return(-1); }
public ElfVirtualAddressSpace(ImmutableArray <ElfProgramHeader> segments, IAddressSpace addressSpace) { // FileSize == 0 means the segment isn't backed by any data _segments = segments.Where(segment => segment.FileSize > 0).OrderBy(segment => segment.VirtualAddress).ThenBy(segment => segment.VirtualSize).ToArray(); ElfProgramHeader lastSegment = _segments[_segments.Length - 1]; Length = lastSegment.VirtualAddress + lastSegment.FileSize; _addressSpace = addressSpace; }
public int Read(long address, Span <byte> buffer) { if (address == 0 || buffer.Length == 0) { return(0); } int i = GetFirstSegmentContaining(address); if (i < 0) { return(0); } int bytesRead = 0; for (; i < _segments.Length; i++) { ElfProgramHeader segment = _segments[i]; long virtualAddress = segment.VirtualAddress; long virtualSize = segment.VirtualSize; if (virtualAddress > address) { break; } if (address >= virtualAddress + virtualSize) { continue; } long offset = address - virtualAddress; int toRead = (int)Math.Min(buffer.Length - bytesRead, virtualSize - offset); Span <byte> slice = buffer.Slice(bytesRead, toRead); int read = segment.AddressSpace.Read(offset, slice); if (read < toRead) { break; } bytesRead += read; if (bytesRead == buffer.Length) { break; } address += read; } return(bytesRead); }
private void LoadProgramHeaders() { if (_programHeaders != null) { return; } _programHeaders = new ElfProgramHeader[Header.ProgramHeaderCount]; for (int i = 0; i < _programHeaders.Length; i++) { _programHeaders[i] = new ElfProgramHeader(_reader, _position + (long)Header.ProgramHeaderOffset + i * Header.ProgramHeaderEntrySize, _position, _virtual); } }
public int Read(long position, Span <byte> buffer) { int bytesRead = 0; while (bytesRead != buffer.Length) { int i = 0; for (; i < _segments.Length; i++) { ElfProgramHeader segment = _segments[i]; long virtualAddress = segment.VirtualAddress; long virtualSize = segment.VirtualSize; long upperAddress = virtualAddress + virtualSize; if (virtualAddress <= position && position < upperAddress) { int bytesToReadRange = (int)Math.Min(buffer.Length - bytesRead, upperAddress - position); long segmentOffset = position - virtualAddress; Span <byte> slice = buffer.Slice(bytesRead, bytesToReadRange); int bytesReadRange = segment.AddressSpace.Read(segmentOffset, slice); if (bytesReadRange == 0) { goto done; } position += bytesReadRange; bytesRead += bytesReadRange; if (bytesReadRange < bytesToReadRange) { goto done; } break; } } if (i == _segments.Length) { break; } } done: buffer.Slice(bytesRead).Clear(); return(bytesRead); }