def bases
      file = "/proc/#{@pid}/maps"
      stat = MemoryIO::Util.file_permission(file)
      return {} unless stat && stat.readable?

      maps = ::IO.binread(file).split("\n").map do |line|
        # 7f76515cf000-7f76515da000 r-xp 00000000 fd:01 29360257  /lib/x86_64-linux-gnu/libnss_files-2.24.so
        addr, _perm, _offset, _dev, _inode, pathname = line.strip.split(' ', 6)
        next nil if pathname.nil?

        addr = addr.to_i(16)
        pathname = pathname[1..-2] if pathname =~ /^\[.+\]$/
        pathname = ::File.basename(pathname)
        [MemoryIO::Util.trim_libname(pathname).to_sym, addr]
      end
      maps.compact.reverse.to_h
    end
def bases
      file = "/proc/#{@pid}/maps"
      stat = MemoryIO::Util.file_permission(file)
      return {} unless stat && stat.readable?

      maps = ::IO.binread(file).split("\n").map do |line|
        # 7f76515cf000-7f76515da000 r-xp 00000000 fd:01 29360257  /lib/x86_64-linux-gnu/libnss_files-2.24.so
        addr, _perm, _offset, _dev, _inode, pathname = line.strip.split(' ', 6)
        next nil if pathname.nil?

        addr = addr.to_i(16)
        pathname = pathname[1..-2] if pathname =~ /^\[.+\]$/
        pathname = ::File.basename(pathname)
        [MemoryIO::Util.trim_libname(pathname).to_sym, addr]
      end
      maps.compact.reverse.to_h
    end
@api private

 Create process object from pid.

 @param [Integer] pid
   Process id.

 @note
   This class only supports procfs-based system. i.e. /proc is mounted and readable.

 @todo
   Support MacOS
 @todo
   Support Windows
 Parse +/proc/[pid]/maps+ to get all bases.

 @return [{Symbol => Integer}]
   Hash of bases.

 @example
   process = Process.new(`pidof victim`.to_i)
   puts process.bases.map { |key, val| format('%s: 0x%016x', key, val) }
   # vsyscall: 0xffffffffff600000
   # vdso: 0x00007ffd5b565000
   # vvar: 0x00007ffd5b563000
   # stack: 0x00007ffd5ad21000
   # ld: 0x00007f339a69b000
   # libc: 0x00007f33996f1000
   # heap: 0x00005571994a1000
   # victim: 0x0000557198bcb000
   #=> nil