This is the mail archive of the libc-hacker@sources.redhat.com mailing list for the glibc project.

Note that libc-hacker is a closed list. You may look at the archives of this list, but subscription and posting are not open.


Index Nav: [Date Index] [Subject Index] [Author Index] [Thread Index]
Message Nav: [Date Prev] [Date Next] [Thread Prev] [Thread Next]
Other format: [Raw text]

New read etc. checking macros


Hi!

As shown on the testcase below, we generate __read_chk calls unnecessarily
and the currently implemented -DA variant generates largest and slowest code.
One alternative (-DB) is to only call __read_chk if we don't know if the buffer
is big enough, but know the size.
Another, which has the advantage that no new @GLIBC_2.4 entrypoints are needed,
does the checking in the caller, either at compile time if the compiler can
optimize it at compile time, or at runtime if not.

#include <unistd.h>

#undef read
extern void __chk_fail (void) __attribute__((noreturn));

#ifdef A
extern ssize_t __read_chk (int __fd, void *__buf, size_t __nbytes,
                           size_t __buflen) __wur;
#define read(fd, buf, nbytes) \
  (__bos (buf) != (size_t) -1                                                 \
   ? __read_chk (fd, buf, nbytes, __bos (buf))                                \
   : read (fd, buf, nbytes))

#elif defined B

extern ssize_t __read_chk (int __fd, void *__buf, size_t __nbytes,
                           size_t __buflen) __wur;
#define read(fd, buf, nbytes) \
  (__bos (buf) != (size_t) -1                                                 \
   && (!__builtin_constant_p (nbytes) || nbytes > __bos (buf))                \
   ? __read_chk (fd, buf, nbytes, __bos (buf))                                \
   : read (fd, buf, nbytes))

#else

#define read(fd, buf, nbytes) \
  ({ size_t __nbytes = (nbytes);                                              \
     if (__bos (buf) != (size_t) -1 && __nbytes > __bos (buf))                \
       __chk_fail ();                                                         \
     read (fd, buf, __nbytes); })

#endif

size_t n = 4;

int main (void)
{
  char buf[4];
  volatile ssize_t ret;
  ret = read (0, buf, sizeof (buf));
  ret = read (0, buf, 2);
  ret = read (0, buf, n++);
  ret = read (0, buf, n);
  ret = read (0, buf, 5);
  return 0;
}

	Jakub


Index Nav: [Date Index] [Subject Index] [Author Index] [Thread Index]
Message Nav: [Date Prev] [Date Next] [Thread Prev] [Thread Next]