Search code examples
linuxx86cpu-registersptracei386

`gs` missing from user_regs_struct?


I've got the following piece of code which failed to compile on i386 with "gs" missing. I've looked at the struct definition, and it's clearly there. Any idea what I got wrong? Thanks!

struct user_regs_struct regs_struct;
  struct iovec pt_iov = {
      .iov_base = &regs,
      .iov_len = sizeof(regs),
  };
  if (ptrace(PTRACE_GETREGSET, tid, NT_PRSTATUS, &pt_iov) == 0) {
#if defined(__x86_64__)
    return regs_struct.fs;
#elif defined(__i386__)
    return regs_struct.gs;  <<< Got an error about "gs" not being a field of user_regs_struct 
  }

P.S: I know I should produce a small test case but I could not. It didn't hit this error on a standalone app. (never mind that I don't have the hardware to test it locally). All I knew was this error popped up when the code is part of a larger system, being built remotely. That's why I was hoping maybe somebody recognized this as a "known-issue" or have some intuition as to what might be the issue.


Solution

  • Looks like the i386 version of user_regs_struct calls it xgs for some reason.

    In sys/user.h, there's an #ifdef __x86_64__. The #else /* These are the 32-bit x86 structures. */ side of the file has this content:

    struct user_regs_struct
    {
      long int ebx;
      long int ecx;
      long int edx;
      long int esi;
      long int edi;
      long int ebp;
      long int eax;
      long int xds;
      long int xes;
      long int xfs;
      long int xgs;
      long int orig_eax;
      long int eip;
      long int xcs;
      long int eflags;
      long int esp;
      long int xss;
    };
    

    Perhaps that changed in some glibc version? This is on x86-64 Arch GNU/Linux, so those are plain vanilla glibc headers (taken from the Linux kernel).

    ack user_regs_struct /usr/include found the right file right away. (like grep -r).

    Note the top of the file says:

    /* The whole purpose of this file is for GDB and GDB only.  Don't read
       too much into it.  Don't use it for anything other than GDB unless
       you know what you are doing.  */
    

    I don't know exactly why there's such a stern warning, or if they really mean for ptrace in general. If it's more than that, I'd be cautious about using it blindly if reading the header and checking the struct member names wasn't obvious to you. Maybe it's fine, maybe it's not, just saying that I wouldn't rely on code you write using it for anything critical without more research.