docs: def _load_from_native_memory(self, addr, data_type=None, data_size=None,
                                  no_of_elements=1, return_as_list=False):
          """
          Load from native memory.
  
          :param addr:            Native load address.
          :param data_type:       Java type of elements.
                                  If set, all loaded elements are casted to this type.
          :param data_size:       Size of each element.
                                  If not set, size is determined based on the given type.
          :param no_of_elements:  Number of elements to load.
          :param return_as_list:  Whether to wrap a single element in a list.
          :return:                The value or a list of loaded element(s).
          """
          # check if addr is symbolic
          if addr is not None and self.state.solver.symbolic(addr):
              raise NotImplementedError('Symbolic addresses are not supported.')
          # if data size is not set, derive it from the type
          if not data_size:
              if data_type:
                  data_size = ArchSoot.sizeof[data_type]//8
              else:
                  raise ValueError("Cannot determine the data size w/o a type.")
          native_memory_endness = self.state.arch.memory_endness
          # load elements
          values = []
          for i in range(no_of_elements):
              value = self.state.memory.load(addr + i*data_size,
                                            size=data_size,
                                            endness=native_memory_endness)
              if data_type:
                  value = self.state.project.simos.cast_primitive(self.state, value=value, to_type=data_type)
              values.append(value)
          # return element(s)
          if no_of_elements == 1 and not return_as_list:
              return values[0]
          else:
              return values