Example #1
0
        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);
        }
Example #5
0
        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);
            }
        }
Example #6
0
        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);
        }