1

I am looking to add xv6 page table functionality. However, for some reason I am getting errors with argaddr and argint. Why?

Lab reference: xv6 page table

int sys_pgaccess(void){
  uint64 fva;
  int pnum;
  uint64 abits;
  int res = 0;
  pte_t* pte_addr;
  pte_t pte;


  if(argaddr(0, &fva) < 0) {
    return -1;
  }
  if(argint(1, &pnum) < 0) {
    return -1;
  }
kernel/sysproc.c: In function 'sys_pgaccess':
kernel/sysproc.c:105:6: error: void value not ignored as it ought to be
  105 |   if(argaddr(0, &fva) < 0) {
      |      ^~~~~~~~~~~~~~~~
kernel/sysproc.c:108:6: error: void value not ignored as it ought to be
  108 |   if(argint(1, &pnum) < 0) {
      |      ^~~~~~~~~~~~~~~~

I am a beginner so I looked at the code for argaddr, etc., but could not understand it.

Oka
  • 23,367
  • 6
  • 42
  • 53
tsosilio
  • 13
  • 2
  • Where did you get the idea that these functions return a value `<0` in case of error? Did you find any manual for these functions indicating that? – Gerhardh Jul 03 '23 at 07:35

1 Answers1

4

The compiler is telling you that argaddr and argint are void functions, and do not return a value.

You cannot compare nothing with an integer.

Looking at kernel/syscall.c from mit-pdos/xv6-riscv, we can see the RISC-V function definitions:

// Fetch the nth 32-bit system call argument.
void
argint(int n, int *ip)
{
  *ip = argraw(n);
}

// Retrieve an argument as a pointer.
// Doesn't check for legality, since
// copyin/copyout will do that.
void
argaddr(int n, uint64 *ip)
{
  *ip = argraw(n);
}

The contents of the lab linked deal with RISC-V.

It appears you should simply remove the conditionals:

int sys_pgaccess(void)
{
  uint64 fva;
  int pnum;
  /* ... */
 
  argaddr(0, &fva);
  argint(1, &pnum);
  /* ... */
}

For completeness, the x86 versions of these functions do return values, so you may have read the wrong documentation.

syscall.c from the no longer maintained mit-pdos/xv6-public contains the x86 definitions:

// Fetch the int at addr from the current process.
int
fetchint(uint addr, int *ip)
{
  struct proc *curproc = myproc();

  if(addr >= curproc->sz || addr+4 > curproc->sz)
    return -1;
  *ip = *(int*)(addr);
  return 0;
}

// Fetch the nth 32-bit system call argument.
int
argint(int n, int *ip)
{
  return fetchint((myproc()->tf->esp) + 4 + 4*n, ip);
}

// Fetch the nth word-sized system call argument as a pointer
// to a block of memory of size bytes.  Check that the pointer
// lies within the process address space.
int
argptr(int n, char **pp, int size)
{
  int i;
  struct proc *curproc = myproc();
 
  if(argint(n, &i) < 0)
    return -1;
  if(size < 0 || (uint)i >= curproc->sz || (uint)i+size > curproc->sz)
    return -1;
  *pp = (char*)i;
  return 0;
}
Oka
  • 23,367
  • 6
  • 42
  • 53