diff options
| author | sin | 2015-03-13 17:03:52 +0000 |
|---|---|---|
| committer | sin | 2015-03-13 17:03:52 +0000 |
| commit | c8ecc164f1635bf713d6c9d7cd4b1311f42f4bc1 (patch) | |
| tree | e0ecee22b2d888e61143999b41c7ee82a85a46f2 | |
| parent | c2b0ad0bf55d5fe63c6e56e64cbd252a772dbbc0 (diff) | |
Implement snprintf() and sprintf() using __builtin_va_arg_pack()
Requires at least GCC 4.3.
| -rw-r--r-- | include/stdio.h | 49 |
1 files changed, 28 insertions, 21 deletions
diff --git a/include/stdio.h b/include/stdio.h index f157038..f87bd59 100644 --- a/include/stdio.h +++ b/include/stdio.h | |||
| @@ -84,28 +84,35 @@ int vsprintf(char *s, const char *fmt, __builtin_va_list ap) | |||
| 84 | return r; | 84 | return r; |
| 85 | } | 85 | } |
| 86 | 86 | ||
| 87 | #undef snprintf | 87 | extern int __snprintf_orig(char *, size_t, const char *, ...) |
| 88 | #define snprintf(s, n, fmt, ...) ({ \ | 88 | __asm__(__USER_LABEL_PREFIX__ "snprintf"); |
| 89 | size_t _n = n; \ | 89 | extern __inline __attribute__((__always_inline__,__gnu_inline__)) |
| 90 | size_t bos = __builtin_object_size(s, 0); \ | 90 | int snprintf(char *s, size_t n, const char *fmt, ...) |
| 91 | if (_n > bos) \ | 91 | { |
| 92 | __builtin_trap(); \ | 92 | size_t bos = __builtin_object_size(s, 0); |
| 93 | (snprintf)(s, _n, fmt, ## __VA_ARGS__); \ | ||
| 94 | }) | ||
| 95 | 93 | ||
| 96 | #undef sprintf | 94 | if (n > bos) |
| 97 | #define sprintf(s, fmt, ...) ({ \ | 95 | __builtin_trap(); |
| 98 | size_t bos = __builtin_object_size(s, 0); \ | 96 | return __snprintf_orig(s, n, fmt, __builtin_va_arg_pack()); |
| 99 | int r; \ | 97 | } |
| 100 | if (bos != (size_t)-1) { \ | 98 | |
| 101 | r = (snprintf)(s, bos, fmt, ## __VA_ARGS__); \ | 99 | extern int __sprintf_orig(char *, const char *, ...) |
| 102 | if (r != -1 && (size_t)r >= bos) \ | 100 | __asm__(__USER_LABEL_PREFIX__ "sprintf"); |
| 103 | __builtin_trap(); \ | 101 | extern __inline __attribute__((__always_inline__,__gnu_inline__)) |
| 104 | } else { \ | 102 | int sprintf(char *s, const char *fmt, ...) |
| 105 | r = (sprintf)(s, fmt, ## __VA_ARGS__); \ | 103 | { |
| 106 | } \ | 104 | size_t bos = __builtin_object_size(s, 0); |
| 107 | r; \ | 105 | int r; |
| 108 | }) | 106 | |
| 107 | if (bos != (size_t)-1) { | ||
| 108 | r = __snprintf_orig(s, bos, fmt, __builtin_va_arg_pack()); | ||
| 109 | if (r != -1 && (size_t)r >= bos) | ||
| 110 | __builtin_trap(); | ||
| 111 | } else { | ||
| 112 | r = __sprintf_orig(s, fmt, __builtin_va_arg_pack()); | ||
| 113 | } | ||
| 114 | return r; | ||
| 115 | } | ||
| 109 | 116 | ||
| 110 | #endif | 117 | #endif |
| 111 | 118 | ||
