1 // SPDX-License-Identifier: GPL-2.0 2 /* 3 * seq_buf.c 4 * 5 * Copyright (C) 2014 Red Hat Inc, Steven Rostedt <srostedt@redhat.com> 6 * 7 * The seq_buf is a handy tool that allows you to pass a descriptor around 8 * to a buffer that other functions can write to. It is similar to the 9 * seq_file functionality but has some differences. 10 * 11 * To use it, the seq_buf must be initialized with seq_buf_init(). 12 * This will set up the counters within the descriptor. You can call 13 * seq_buf_init() more than once to reset the seq_buf to start 14 * from scratch. 15 */ 16 #include <linux/uaccess.h> 17 #include <linux/seq_file.h> 18 #include <linux/seq_buf.h> 19 20 /** 21 * seq_buf_can_fit - can the new data fit in the current buffer? 22 * @s: the seq_buf descriptor 23 * @len: The length to see if it can fit in the current buffer 24 * 25 * Returns true if there's enough unused space in the seq_buf buffer 26 * to fit the amount of new data according to @len. 27 */ 28 static bool seq_buf_can_fit(struct seq_buf *s, size_t len) 29 { 30 return s->len + len <= s->size; 31 } 32 33 /** 34 * seq_buf_print_seq - move the contents of seq_buf into a seq_file 35 * @m: the seq_file descriptor that is the destination 36 * @s: the seq_buf descriptor that is the source. 37 * 38 * Returns zero on success, non zero otherwise 39 */ 40 int seq_buf_print_seq(struct seq_file *m, struct seq_buf *s) 41 { 42 unsigned int len = seq_buf_used(s); 43 44 return seq_write(m, s->buffer, len); 45 } 46 47 /** 48 * seq_buf_vprintf - sequence printing of information. 49 * @s: seq_buf descriptor 50 * @fmt: printf format string 51 * @args: va_list of arguments from a printf() type function 52 * 53 * Writes a vnprintf() format into the sequencce buffer. 54 * 55 * Returns zero on success, -1 on overflow. 56 */ 57 int seq_buf_vprintf(struct seq_buf *s, const char *fmt, va_list args) 58 { 59 int len; 60 61 WARN_ON(s->size == 0); 62 63 if (s->len < s->size) { 64 len = vsnprintf(s->buffer + s->len, s->size - s->len, fmt, args); 65 if (s->len + len < s->size) { 66 s->len += len; 67 return 0; 68 } 69 } 70 seq_buf_set_overflow(s); 71 return -1; 72 } 73 74 /** 75 * seq_buf_printf - sequence printing of information 76 * @s: seq_buf descriptor 77 * @fmt: printf format string 78 * 79 * Writes a printf() format into the sequence buffer. 80 * 81 * Returns zero on success, -1 on overflow. 82 */ 83 int seq_buf_printf(struct seq_buf *s, const char *fmt, ...) 84 { 85 va_list ap; 86 int ret; 87 88 va_start(ap, fmt); 89 ret = seq_buf_vprintf(s, fmt, ap); 90 va_end(ap); 91 92 return ret; 93 } 94 EXPORT_SYMBOL_GPL(seq_buf_printf); 95 96 /** 97 * seq_buf_do_printk - printk seq_buf line by line 98 * @s: seq_buf descriptor 99 * @lvl: printk level 100 * 101 * printk()-s a multi-line sequential buffer line by line. The function 102 * makes sure that the buffer in @s is nul terminated and safe to read 103 * as a string. 104 */ 105 void seq_buf_do_printk(struct seq_buf *s, const char *lvl) 106 { 107 const char *start, *lf; 108 109 if (s->size == 0 || s->len == 0) 110 return; 111 112 start = seq_buf_str(s); 113 while ((lf = strchr(start, '\n'))) { 114 int len = lf - start + 1; 115 116 printk("%s%.*s", lvl, len, start); 117 start = ++lf; 118 } 119 120 /* No trailing LF */ 121 if (start < s->buffer + s->len) 122 printk("%s%s\n", lvl, start); 123 } 124 EXPORT_SYMBOL_GPL(seq_buf_do_printk); 125 126 #ifdef CONFIG_BINARY_PRINTF 127 /** 128 * seq_buf_bprintf - Write the printf string from binary arguments 129 * @s: seq_buf descriptor 130 * @fmt: The format string for the @binary arguments 131 * @binary: The binary arguments for @fmt. 132 * 133 * When recording in a fast path, a printf may be recorded with just 134 * saving the format and the arguments as they were passed to the 135 * function, instead of wasting cycles converting the arguments into 136 * ASCII characters. Instead, the arguments are saved in a 32 bit 137 * word array that is defined by the format string constraints. 138 * 139 * This function will take the format and the binary array and finish 140 * the conversion into the ASCII string within the buffer. 141 * 142 * Returns zero on success, -1 on overflow. 143 */ 144 int seq_buf_bprintf(struct seq_buf *s, const char *fmt, const u32 *binary) 145 { 146 unsigned int len = seq_buf_buffer_left(s); 147 int ret; 148 149 WARN_ON(s->size == 0); 150 151 if (s->len < s->size) { 152 ret = bstr_printf(s->buffer + s->len, len, fmt, binary); 153 if (s->len + ret < s->size) { 154 s->len += ret; 155 return 0; 156 } 157 } 158 seq_buf_set_overflow(s); 159 return -1; 160 } 161 #endif /* CONFIG_BINARY_PRINTF */ 162 163 /** 164 * seq_buf_puts - sequence printing of simple string 165 * @s: seq_buf descriptor 166 * @str: simple string to record 167 * 168 * Copy a simple string into the sequence buffer. 169 * 170 * Returns zero on success, -1 on overflow 171 */ 172 int seq_buf_puts(struct seq_buf *s, const char *str) 173 { 174 size_t len = strlen(str); 175 176 WARN_ON(s->size == 0); 177 178 /* Add 1 to len for the trailing null byte which must be there */ 179 len += 1; 180 181 if (seq_buf_can_fit(s, len)) { 182 memcpy(s->buffer + s->len, str, len); 183 /* Don't count the trailing null byte against the capacity */ 184 s->len += len - 1; 185 return 0; 186 } 187 seq_buf_set_overflow(s); 188 return -1; 189 } 190 EXPORT_SYMBOL_GPL(seq_buf_puts); 191 192 /** 193 * seq_buf_putc - sequence printing of simple character 194 * @s: seq_buf descriptor 195 * @c: simple character to record 196 * 197 * Copy a single character into the sequence buffer. 198 * 199 * Returns zero on success, -1 on overflow 200 */ 201 int seq_buf_putc(struct seq_buf *s, unsigned char c) 202 { 203 WARN_ON(s->size == 0); 204 205 if (seq_buf_can_fit(s, 1)) { 206 s->buffer[s->len++] = c; 207 return 0; 208 } 209 seq_buf_set_overflow(s); 210 return -1; 211 } 212 EXPORT_SYMBOL_GPL(seq_buf_putc); 213 214 /** 215 * seq_buf_putmem - write raw data into the sequenc buffer 216 * @s: seq_buf descriptor 217 * @mem: The raw memory to copy into the buffer 218 * @len: The length of the raw memory to copy (in bytes) 219 * 220 * There may be cases where raw memory needs to be written into the 221 * buffer and a strcpy() would not work. Using this function allows 222 * for such cases. 223 * 224 * Returns zero on success, -1 on overflow 225 */ 226 int seq_buf_putmem(struct seq_buf *s, const void *mem, unsigned int len) 227 { 228 WARN_ON(s->size == 0); 229 230 if (seq_buf_can_fit(s, len)) { 231 memcpy(s->buffer + s->len, mem, len); 232 s->len += len; 233 return 0; 234 } 235 seq_buf_set_overflow(s); 236 return -1; 237 } 238 239 #define MAX_MEMHEX_BYTES 8U 240 #define HEX_CHARS (MAX_MEMHEX_BYTES*2 + 1) 241 242 /** 243 * seq_buf_putmem_hex - write raw memory into the buffer in ASCII hex 244 * @s: seq_buf descriptor 245 * @mem: The raw memory to write its hex ASCII representation of 246 * @len: The length of the raw memory to copy (in bytes) 247 * 248 * This is similar to seq_buf_putmem() except instead of just copying the 249 * raw memory into the buffer it writes its ASCII representation of it 250 * in hex characters. 251 * 252 * Returns zero on success, -1 on overflow 253 */ 254 int seq_buf_putmem_hex(struct seq_buf *s, const void *mem, 255 unsigned int len) 256 { 257 unsigned char hex[HEX_CHARS]; 258 const unsigned char *data = mem; 259 unsigned int start_len; 260 int i, j; 261 262 WARN_ON(s->size == 0); 263 264 BUILD_BUG_ON(MAX_MEMHEX_BYTES * 2 >= HEX_CHARS); 265 266 while (len) { 267 start_len = min(len, MAX_MEMHEX_BYTES); 268 #ifdef __BIG_ENDIAN 269 for (i = 0, j = 0; i < start_len; i++) { 270 #else 271 for (i = start_len-1, j = 0; i >= 0; i--) { 272 #endif 273 hex[j++] = hex_asc_hi(data[i]); 274 hex[j++] = hex_asc_lo(data[i]); 275 } 276 if (WARN_ON_ONCE(j == 0 || j/2 > len)) 277 break; 278 279 /* j increments twice per loop */ 280 hex[j++] = ' '; 281 282 seq_buf_putmem(s, hex, j); 283 if (seq_buf_has_overflowed(s)) 284 return -1; 285 286 len -= start_len; 287 data += start_len; 288 } 289 return 0; 290 } 291 292 /** 293 * seq_buf_path - copy a path into the sequence buffer 294 * @s: seq_buf descriptor 295 * @path: path to write into the sequence buffer. 296 * @esc: set of characters to escape in the output 297 * 298 * Write a path name into the sequence buffer. 299 * 300 * Returns the number of written bytes on success, -1 on overflow 301 */ 302 int seq_buf_path(struct seq_buf *s, const struct path *path, const char *esc) 303 { 304 char *buf; 305 size_t size = seq_buf_get_buf(s, &buf); 306 int res = -1; 307 308 WARN_ON(s->size == 0); 309 310 if (size) { 311 char *p = d_path(path, buf, size); 312 if (!IS_ERR(p)) { 313 char *end = mangle_path(buf, p, esc); 314 if (end) 315 res = end - buf; 316 } 317 } 318 seq_buf_commit(s, res); 319 320 return res; 321 } 322 323 /** 324 * seq_buf_to_user - copy the sequence buffer to user space 325 * @s: seq_buf descriptor 326 * @ubuf: The userspace memory location to copy to 327 * @start: The first byte in the buffer to copy 328 * @cnt: The amount to copy 329 * 330 * Copies the sequence buffer into the userspace memory pointed to 331 * by @ubuf. It starts from @start and writes up to @cnt characters 332 * or until it reaches the end of the content in the buffer (@s->len), 333 * whichever comes first. 334 * 335 * On success, it returns a positive number of the number of bytes 336 * it copied. 337 * 338 * On failure it returns -EBUSY if all of the content in the 339 * sequence has been already read, which includes nothing in the 340 * sequence (@s->len == @start). 341 * 342 * Returns -EFAULT if the copy to userspace fails. 343 */ 344 int seq_buf_to_user(struct seq_buf *s, char __user *ubuf, size_t start, int cnt) 345 { 346 int len; 347 int ret; 348 349 if (!cnt) 350 return 0; 351 352 len = seq_buf_used(s); 353 354 if (len <= start) 355 return -EBUSY; 356 357 len -= start; 358 if (cnt > len) 359 cnt = len; 360 ret = copy_to_user(ubuf, s->buffer + start, cnt); 361 if (ret == cnt) 362 return -EFAULT; 363 364 return cnt - ret; 365 } 366 367 /** 368 * seq_buf_hex_dump - print formatted hex dump into the sequence buffer 369 * @s: seq_buf descriptor 370 * @prefix_str: string to prefix each line with; 371 * caller supplies trailing spaces for alignment if desired 372 * @prefix_type: controls whether prefix of an offset, address, or none 373 * is printed (%DUMP_PREFIX_OFFSET, %DUMP_PREFIX_ADDRESS, %DUMP_PREFIX_NONE) 374 * @rowsize: number of bytes to print per line; must be 16 or 32 375 * @groupsize: number of bytes to print at a time (1, 2, 4, 8; default = 1) 376 * @buf: data blob to dump 377 * @len: number of bytes in the @buf 378 * @ascii: include ASCII after the hex output 379 * 380 * Function is an analogue of print_hex_dump() and thus has similar interface. 381 * 382 * linebuf size is maximal length for one line. 383 * 32 * 3 - maximum bytes per line, each printed into 2 chars + 1 for 384 * separating space 385 * 2 - spaces separating hex dump and ascii representation 386 * 32 - ascii representation 387 * 1 - terminating '\0' 388 * 389 * Returns zero on success, -1 on overflow 390 */ 391 int seq_buf_hex_dump(struct seq_buf *s, const char *prefix_str, int prefix_type, 392 int rowsize, int groupsize, 393 const void *buf, size_t len, bool ascii) 394 { 395 const u8 *ptr = buf; 396 int i, linelen, remaining = len; 397 unsigned char linebuf[32 * 3 + 2 + 32 + 1]; 398 int ret; 399 400 if (rowsize != 16 && rowsize != 32) 401 rowsize = 16; 402 403 for (i = 0; i < len; i += rowsize) { 404 linelen = min(remaining, rowsize); 405 remaining -= rowsize; 406 407 hex_dump_to_buffer(ptr + i, linelen, rowsize, groupsize, 408 linebuf, sizeof(linebuf), ascii); 409 410 switch (prefix_type) { 411 case DUMP_PREFIX_ADDRESS: 412 ret = seq_buf_printf(s, "%s%p: %s\n", 413 prefix_str, ptr + i, linebuf); 414 break; 415 case DUMP_PREFIX_OFFSET: 416 ret = seq_buf_printf(s, "%s%.8x: %s\n", 417 prefix_str, i, linebuf); 418 break; 419 default: 420 ret = seq_buf_printf(s, "%s%s\n", prefix_str, linebuf); 421 break; 422 } 423 if (ret) 424 return ret; 425 } 426 return 0; 427 } 428