1

thank you for read my question.

When i debug puts function in glibc, I found something which couldn't understand.

// glibc-2.27/libio/ioputs.c

int
_IO_puts (const char *str)
{
  int result = EOF;
  size_t len = strlen (str);
  _IO_acquire_lock (stdout);
  if ((_IO_vtable_offset (stdout) != 0
       || _IO_fwide (stdout, -1) == -1)
      && _IO_sputn (stdout, str, len) == len
      && _IO_putc_unlocked ('\n', stdout) != EOF)
    result = MIN (INT_MAX, len + 1);
  _IO_release_lock (stdout);
  return result;
}
weak_alias (_IO_puts, puts)

enter image description here

(part of calling _IO_sputn function in gdb)

As you can see, _IO_puts calls _IO_sputn function.

But when i check [r13+0x38] in gdb, there is a different value.

enter image description here

(different value)

  1. Why _IO_sputn function is called through _IO_file_jumps ?

  2. And what is _IO_file_jumps's role in glibc?

  3. How can _IO_sputn function calls _IO_new_file_xsputn finally ?

< Addition >

// glibc-2.27/libio/libioP.h

#define _IO_sputn(__fp, __s, __n) _IO_XSPUTN (__fp, __s, __n)
// glibc-2.27/libio/libioP.h

typedef size_t (*_IO_xsputn_t) (FILE *FP, const void *DATA,
                                    size_t N);
#define _IO_XSPUTN(FP, DATA, N) JUMP2 (__xsputn, FP, DATA, N)
#define _IO_WXSPUTN(FP, DATA, N) WJUMP2 (__xsputn, FP, DATA, N)

// glibc-2.27/libio/libioP.h

struct _IO_jump_t
{
    JUMP_FIELD(size_t, __dummy);
    JUMP_FIELD(size_t, __dummy2);
    JUMP_FIELD(_IO_finish_t, __finish);
    JUMP_FIELD(_IO_overflow_t, __overflow);
    JUMP_FIELD(_IO_underflow_t, __underflow);
    JUMP_FIELD(_IO_underflow_t, __uflow);
    JUMP_FIELD(_IO_pbackfail_t, __pbackfail);
    /* showmany */
    JUMP_FIELD(_IO_xsputn_t, __xsputn);
    JUMP_FIELD(_IO_xsgetn_t, __xsgetn);
    JUMP_FIELD(_IO_seekoff_t, __seekoff);
    JUMP_FIELD(_IO_seekpos_t, __seekpos);
    JUMP_FIELD(_IO_setbuf_t, __setbuf);
    JUMP_FIELD(_IO_sync_t, __sync);
    JUMP_FIELD(_IO_doallocate_t, __doallocate);
    JUMP_FIELD(_IO_read_t, __read);
    JUMP_FIELD(_IO_write_t, __write);
    JUMP_FIELD(_IO_seek_t, __seek);
    JUMP_FIELD(_IO_close_t, __close);
    JUMP_FIELD(_IO_stat_t, __stat);
    JUMP_FIELD(_IO_showmanyc_t, __showmanyc);
    JUMP_FIELD(_IO_imbue_t, __imbue);
};

This is everything which I could find about _IO_sputn with ctags and cscope.

leesh
  • 121
  • 2
  • 11

1 Answers1

2

Why _IO_sputn function is called through _IO_file_jumps ?

Because a file ("file" as an object) may implement putting characters differently, a dispatch table is used.

And what is _IO_file_jumps's role in glibc?

It's a dispatch table - an array of function pointers. It's there to specify a common stable virtual interface to be differently implemented by different files requiring differently implementations and abstractions for the requested operations.

How can _IO_sputn function calls _IO_new_file_xsputn finally ?

A function pointer is part of C language, that allows to call another function via a pointer that points to a function. _IO_sputn is a macro that expands to a function call on that function pointer. The macros are there to simplify passing the pointer to the object data itself to the function - it's not particularly beautiful, but simplifies writing the code.

KamilCuk
  • 120,984
  • 8
  • 59
  • 111
  • Thank you for answer my question :) And I wonder how `__xsputn` is connected to `__IO_new_file_xsputn` function. Is `__IO_new_file_xsputn` in `_IO_file_jump` table? If then, where is the source code which I can find? – leesh Dec 29 '20 at 14:07
  • `how __xsputn is connected to __IO_new_file_xsputn function` Somewhere around here https://github.com/lattera/glibc/blob/master/libio/iofopen.c#L73 for files. `Is __IO_new_file_xsputn in _IO_file_jump table?` Yes, `_IO_file_jump` is _the type_, an instantiation of that type is defined [here](https://github.com/lattera/glibc/blob/master/libio/fileops.c#L1448). Note that `versioned_symbol (libc, _IO_new_file_xsputn, _IO_file_xsputn, GLIBC_2_1);` above. – KamilCuk Dec 29 '20 at 14:56
  • `where is the source code which I can find?` github is good for browsing, mostly because google is indexing github very high, so I use google for searching. But https://code.woboq.org/userspace/glibc/ is better as it has some simple in-browser-tags-browsing (and is also high in google). – KamilCuk Dec 29 '20 at 15:00