3

I'm trying to read the output of sysinfo system call from an assembly program but it seems that the system call leaves the sysinfo struct unchanged

.section .data
 result:
    uptime:
        .quad 00
    loads:
        .quad 00
    total_ram:
        .quad 00
    free_ram:
        .quad 00
    shared_ram:
        .quad 00, 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0

.section .bss
.section .text
.globl main
main:
    nop
    movq $99, %rax
    leaq result(%rip), %rdi
    syscall
    nop

strace shows that sysinfo is called correctly but using gdb to view the result after the syscall shows that all are still unchanged(0). Also rax is 0 which means that syscall is called successfully. So why did syscall didnt modify the result struct although it works normally using C so why did this happen.

/********************* Debugging part *************************/

gdb at last nop instruction ((gdb) x/9dg &result:

0x7ffff7faad80 <result>:        0       0
0x7ffff7faad90 <result+16>:     0       0
0x7ffff7faada0 <result+32>:     0       0
0x7ffff7faadb0 <result+48>:     0       0
0x7ffff7faadc0 <result+64>:     0

man page of sysinfo (man 2 sysinfo):

  int sysinfo(struct sysinfo *info);
struct sysinfo {
               long uptime;             /* Seconds since boot */
               unsigned long loads[3];  /* 1, 5, and 15 minute load averages */
               unsigned long totalram;  /* Total usable main memory size */
               unsigned long freeram;   /* Available memory size */
               unsigned long sharedram; /* Amount of shared memory */
               unsigned long bufferram; /* Memory used by buffers */
               unsigned long totalswap; /* Total swap space size */
               unsigned long freeswap;  /* Swap space still available */
               unsigned short procs;    /* Number of current processes */
               char _f[22];             /* Pads structure to 64 bytes */
           };

running strace ./sysinfo shows this line

sysinfo({uptime=21623, loads=[134496, 128288, 129056], totalram=6125535232, freeram=231415808, sharedram=593993728, bufferram=306745344, totalswap=2147479552, freeswap=2056269824, procs=887, totalhigh=0, freehigh=0, mem_unit=1}) = 0
KMG
  • 1,433
  • 1
  • 8
  • 19
  • I believe your structure is incorrect. Please cross-check with the manual. – fuz Feb 04 '21 at 14:27
  • Works fine here (I see stuff changing, I did not check your struct layout). You likely examined it wrong. [edit] your question with gdb output. – Jester Feb 04 '21 at 14:27
  • 1
    @Jester gonna edit the question with ```gdb``` output and man page of the struct – KMG Feb 04 '21 at 14:30
  • 1
    @Jester edited the question with debugging info . – KMG Feb 04 '21 at 14:37
  • 3
    gdb is picking up the wrong `result` symbol. Use `x/9dg $rdi`. – Jester Feb 04 '21 at 14:38
  • @Jester you are right but what is happening exactly? – KMG Feb 04 '21 at 14:43
  • 1
    `loads` is 3 quads. – Erik Eidt Feb 04 '21 at 16:38
  • Are you sure that `leaq result(%rip), %rdi` gives the correct address in rdi? – linuxfan says Reinstate Monica Feb 04 '21 at 17:04
  • `.globl result` might help get debug symbols to resolve `result` to yours instead of maybe one in libc (it looks like). @linuxfansaysReinstateMonica: the assembler will definitely resolve `result` to the symbol of that name defined in the same file. It's only once you're in GDB and symbols from the executable and libc are all available (with non-global symbols equivalent to C `static`) that there's any ambiguity. – Peter Cordes Feb 04 '21 at 18:48
  • Pretty sure this is a duplicate of [gdb behaves differently for symbols in the .bss, vs. symbols in .data](https://stackoverflow.com/a/39224443) - the same problem with glibc defining a non-global `buf` symbol. My answer there shows how to sort out what's going on. – Peter Cordes Feb 04 '21 at 18:52
  • @PeterCordes what I meant is: doesn't `leaq result(%rip)...` add %rip and the offset of `result`? And does this sum point to the intended buffer? I am not sure. – linuxfan says Reinstate Monica Feb 05 '21 at 13:44
  • @linuxfansaysReinstateMonica: Oh, you're concerned about the syntax itself, not which version of `result` it's referencing. It means result wrt. RIP, like NASM `[rel result]`. This is an inconsistency in GAS syntax between symbols vs. numeric literals that also exists in GAS .intel_syntax: [How do RIP-relative variable references like "\[RIP + \_a\]" in x86-64 GAS Intel-syntax work?](https://stackoverflow.com/q/54745872) – Peter Cordes Feb 05 '21 at 19:20
  • @PeterCordes TY, that's exactly what I meant, and the link you posted did clarify the doubt. – linuxfan says Reinstate Monica Feb 07 '21 at 17:22

0 Answers0