Mirror of strace – the linux syscall tracer
You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

util.c 32KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734735736737738739740741742743744745746747748749750751752753754755756757758759760761762763764765766767768769770771772773774775776777778779780781782783784785786787788789790791792793794795796797798799800801802803804805806807808809810811812813814815816817818819820821822823824825826827828829830831832833834835836837838839840841842843844845846847848849850851852853854855856857858859860861862863864865866867868869870871872873874875876877878879880881882883884885886887888889890891892893894895896897898899900901902903904905906907908909910911912913914915916917918919920921922923924925926927928929930931932933934935936937938939940941942943944945946947948949950951952953954955956957958959960961962963964965966967968969970971972973974975976977978979980981982983984985986987988989990991992993994995996997998999100010011002100310041005100610071008100910101011101210131014101510161017101810191020102110221023102410251026102710281029103010311032103310341035103610371038103910401041104210431044104510461047104810491050105110521053105410551056105710581059106010611062106310641065106610671068106910701071107210731074107510761077107810791080108110821083108410851086108710881089109010911092109310941095109610971098109911001101110211031104110511061107110811091110111111121113111411151116111711181119112011211122112311241125112611271128112911301131113211331134113511361137113811391140114111421143114411451146114711481149115011511152115311541155115611571158115911601161116211631164116511661167116811691170117111721173117411751176117711781179118011811182118311841185118611871188118911901191119211931194119511961197119811991200120112021203120412051206120712081209121012111212121312141215121612171218121912201221122212231224122512261227122812291230123112321233123412351236123712381239124012411242124312441245124612471248124912501251125212531254125512561257125812591260126112621263126412651266126712681269127012711272127312741275127612771278127912801281128212831284128512861287128812891290129112921293129412951296129712981299130013011302130313041305130613071308130913101311131213131314131513161317131813191320132113221323132413251326132713281329133013311332133313341335133613371338133913401341134213431344134513461347134813491350135113521353135413551356135713581359136013611362136313641365136613671368136913701371137213731374137513761377137813791380138113821383138413851386138713881389
  1. /*
  2. * Copyright (c) 1991, 1992 Paul Kranenburg <pk@cs.few.eur.nl>
  3. * Copyright (c) 1993 Branko Lankester <branko@hacktic.nl>
  4. * Copyright (c) 1993, 1994, 1995, 1996 Rick Sladkey <jrs@world.std.com>
  5. * Copyright (c) 1996-1999 Wichert Akkerman <wichert@cistron.nl>
  6. * Copyright (c) 1999 IBM Deutschland Entwicklung GmbH, IBM Corporation
  7. * Linux for s390 port by D.J. Barrow
  8. * <barrow_dj@mail.yahoo.com,djbarrow@de.ibm.com>
  9. * Copyright (c) 1999-2018 The strace developers.
  10. * All rights reserved.
  11. *
  12. * SPDX-License-Identifier: LGPL-2.1-or-later
  13. */
  14. #include "defs.h"
  15. #include <limits.h>
  16. #include <fcntl.h>
  17. #include <stdarg.h>
  18. #include <sys/stat.h>
  19. #include <sys/sysmacros.h>
  20. #ifdef HAVE_SYS_XATTR_H
  21. # include <sys/xattr.h>
  22. #endif
  23. #include <sys/uio.h>
  24. #include "largefile_wrappers.h"
  25. #include "print_utils.h"
  26. #include "static_assert.h"
  27. #include "xlat.h"
  28. #include "xstring.h"
  29. int
  30. ts_nz(const struct timespec *a)
  31. {
  32. return a->tv_sec || a->tv_nsec;
  33. }
  34. int
  35. ts_cmp(const struct timespec *a, const struct timespec *b)
  36. {
  37. if (a->tv_sec < b->tv_sec
  38. || (a->tv_sec == b->tv_sec && a->tv_nsec < b->tv_nsec))
  39. return -1;
  40. if (a->tv_sec > b->tv_sec
  41. || (a->tv_sec == b->tv_sec && a->tv_nsec > b->tv_nsec))
  42. return 1;
  43. return 0;
  44. }
  45. double
  46. ts_float(const struct timespec *tv)
  47. {
  48. return tv->tv_sec + tv->tv_nsec/1000000000.0;
  49. }
  50. void
  51. ts_add(struct timespec *tv, const struct timespec *a, const struct timespec *b)
  52. {
  53. tv->tv_sec = a->tv_sec + b->tv_sec;
  54. tv->tv_nsec = a->tv_nsec + b->tv_nsec;
  55. if (tv->tv_nsec >= 1000000000) {
  56. tv->tv_sec++;
  57. tv->tv_nsec -= 1000000000;
  58. }
  59. }
  60. void
  61. ts_sub(struct timespec *tv, const struct timespec *a, const struct timespec *b)
  62. {
  63. tv->tv_sec = a->tv_sec - b->tv_sec;
  64. tv->tv_nsec = a->tv_nsec - b->tv_nsec;
  65. if (tv->tv_nsec < 0) {
  66. tv->tv_sec--;
  67. tv->tv_nsec += 1000000000;
  68. }
  69. }
  70. void
  71. ts_div(struct timespec *tv, const struct timespec *a, int n)
  72. {
  73. long long nsec = (a->tv_sec % n * 1000000000LL + a->tv_nsec + n / 2) / n;
  74. tv->tv_sec = a->tv_sec / n + nsec / 1000000000;
  75. tv->tv_nsec = nsec % 1000000000;
  76. }
  77. void
  78. ts_mul(struct timespec *tv, const struct timespec *a, int n)
  79. {
  80. long long nsec = a->tv_nsec * n;
  81. tv->tv_sec = a->tv_sec * n + nsec / 1000000000;
  82. tv->tv_nsec = nsec % 1000000000;
  83. }
  84. #if !defined HAVE_STPCPY
  85. char *
  86. stpcpy(char *dst, const char *src)
  87. {
  88. while ((*dst = *src++) != '\0')
  89. dst++;
  90. return dst;
  91. }
  92. #endif
  93. /* Find a next bit which is set.
  94. * Starts testing at cur_bit.
  95. * Returns -1 if no more bits are set.
  96. *
  97. * We never touch bytes we don't need to.
  98. * On big-endian, array is assumed to consist of
  99. * current_wordsize wide words: for example, is current_wordsize is 4,
  100. * the bytes are walked in 3,2,1,0, 7,6,5,4, 11,10,9,8 ... sequence.
  101. * On little-endian machines, word size is immaterial.
  102. */
  103. int
  104. next_set_bit(const void *bit_array, unsigned cur_bit, unsigned size_bits)
  105. {
  106. const unsigned endian = 1;
  107. int little_endian = *(char *) (void *) &endian;
  108. const uint8_t *array = bit_array;
  109. unsigned pos = cur_bit / 8;
  110. unsigned pos_xor_mask = little_endian ? 0 : current_wordsize-1;
  111. for (;;) {
  112. uint8_t bitmask;
  113. uint8_t cur_byte;
  114. if (cur_bit >= size_bits)
  115. return -1;
  116. cur_byte = array[pos ^ pos_xor_mask];
  117. if (cur_byte == 0) {
  118. cur_bit = (cur_bit + 8) & (-8);
  119. pos++;
  120. continue;
  121. }
  122. bitmask = 1 << (cur_bit & 7);
  123. for (;;) {
  124. if (cur_byte & bitmask)
  125. return cur_bit;
  126. cur_bit++;
  127. if (cur_bit >= size_bits)
  128. return -1;
  129. bitmask <<= 1;
  130. /* This check *can't be* optimized out: */
  131. if (bitmask == 0)
  132. break;
  133. }
  134. pos++;
  135. }
  136. }
  137. /*
  138. * Fetch 64bit argument at position arg_no and
  139. * return the index of the next argument.
  140. */
  141. int
  142. getllval(struct tcb *tcp, unsigned long long *val, int arg_no)
  143. {
  144. #if SIZEOF_KERNEL_LONG_T > 4
  145. # ifndef current_klongsize
  146. if (current_klongsize < SIZEOF_KERNEL_LONG_T) {
  147. # if defined(AARCH64) || defined(POWERPC64)
  148. /* Align arg_no to the next even number. */
  149. arg_no = (arg_no + 1) & 0xe;
  150. # endif /* AARCH64 || POWERPC64 */
  151. *val = ULONG_LONG(tcp->u_arg[arg_no], tcp->u_arg[arg_no + 1]);
  152. arg_no += 2;
  153. } else
  154. # endif /* !current_klongsize */
  155. {
  156. *val = tcp->u_arg[arg_no];
  157. arg_no++;
  158. }
  159. #else /* SIZEOF_KERNEL_LONG_T == 4 */
  160. # if defined __ARM_EABI__ \
  161. || defined LINUX_MIPSO32 \
  162. || defined POWERPC \
  163. || defined XTENSA
  164. /* Align arg_no to the next even number. */
  165. arg_no = (arg_no + 1) & 0xe;
  166. # elif defined SH
  167. /*
  168. * The SH4 ABI does allow long longs in odd-numbered registers, but
  169. * does not allow them to be split between registers and memory - and
  170. * there are only four argument registers for normal functions. As a
  171. * result, pread, for example, takes an extra padding argument before
  172. * the offset. This was changed late in the 2.4 series (around 2.4.20).
  173. */
  174. if (arg_no == 3)
  175. arg_no++;
  176. # endif /* __ARM_EABI__ || LINUX_MIPSO32 || POWERPC || XTENSA || SH */
  177. *val = ULONG_LONG(tcp->u_arg[arg_no], tcp->u_arg[arg_no + 1]);
  178. arg_no += 2;
  179. #endif
  180. return arg_no;
  181. }
  182. /*
  183. * Print 64bit argument at position arg_no and
  184. * return the index of the next argument.
  185. */
  186. int
  187. printllval(struct tcb *tcp, const char *format, int arg_no)
  188. {
  189. unsigned long long val = 0;
  190. arg_no = getllval(tcp, &val, arg_no);
  191. tprintf(format, val);
  192. return arg_no;
  193. }
  194. void
  195. printaddr64(const uint64_t addr)
  196. {
  197. if (!addr)
  198. tprints("NULL");
  199. else
  200. tprintf("%#" PRIx64, addr);
  201. }
  202. #define DEF_PRINTNUM(name, type) \
  203. bool \
  204. printnum_ ## name(struct tcb *const tcp, const kernel_ulong_t addr, \
  205. const char *const fmt) \
  206. { \
  207. type num; \
  208. if (umove_or_printaddr(tcp, addr, &num)) \
  209. return false; \
  210. tprints("["); \
  211. tprintf(fmt, num); \
  212. tprints("]"); \
  213. return true; \
  214. }
  215. #define DEF_PRINTNUM_ADDR(name, type) \
  216. bool \
  217. printnum_addr_ ## name(struct tcb *tcp, const kernel_ulong_t addr) \
  218. { \
  219. type num; \
  220. if (umove_or_printaddr(tcp, addr, &num)) \
  221. return false; \
  222. tprints("["); \
  223. printaddr64(num); \
  224. tprints("]"); \
  225. return true; \
  226. }
  227. #define DEF_PRINTPAIR(name, type) \
  228. bool \
  229. printpair_ ## name(struct tcb *const tcp, const kernel_ulong_t addr, \
  230. const char *const fmt) \
  231. { \
  232. type pair[2]; \
  233. if (umove_or_printaddr(tcp, addr, &pair)) \
  234. return false; \
  235. tprints("["); \
  236. tprintf(fmt, pair[0]); \
  237. tprints(", "); \
  238. tprintf(fmt, pair[1]); \
  239. tprints("]"); \
  240. return true; \
  241. }
  242. DEF_PRINTNUM(int, int)
  243. DEF_PRINTNUM_ADDR(int, unsigned int)
  244. DEF_PRINTPAIR(int, int)
  245. DEF_PRINTNUM(short, short)
  246. DEF_PRINTNUM(int64, uint64_t)
  247. DEF_PRINTNUM_ADDR(int64, uint64_t)
  248. DEF_PRINTPAIR(int64, uint64_t)
  249. #ifndef current_wordsize
  250. bool
  251. printnum_long_int(struct tcb *const tcp, const kernel_ulong_t addr,
  252. const char *const fmt_long, const char *const fmt_int)
  253. {
  254. if (current_wordsize > sizeof(int)) {
  255. return printnum_int64(tcp, addr, fmt_long);
  256. } else {
  257. return printnum_int(tcp, addr, fmt_int);
  258. }
  259. }
  260. bool
  261. printnum_addr_long_int(struct tcb *tcp, const kernel_ulong_t addr)
  262. {
  263. if (current_wordsize > sizeof(int)) {
  264. return printnum_addr_int64(tcp, addr);
  265. } else {
  266. return printnum_addr_int(tcp, addr);
  267. }
  268. }
  269. #endif /* !current_wordsize */
  270. #ifndef current_klongsize
  271. bool
  272. printnum_addr_klong_int(struct tcb *tcp, const kernel_ulong_t addr)
  273. {
  274. if (current_klongsize > sizeof(int)) {
  275. return printnum_addr_int64(tcp, addr);
  276. } else {
  277. return printnum_addr_int(tcp, addr);
  278. }
  279. }
  280. #endif /* !current_klongsize */
  281. /**
  282. * Prints time to a (static internal) buffer and returns pointer to it.
  283. * Returns NULL if the provided time specification is not correct.
  284. *
  285. * @param sec Seconds since epoch.
  286. * @param part_sec Amount of second parts since the start of a second.
  287. * @param max_part_sec Maximum value of a valid part_sec.
  288. * @param width 1 + floor(log10(max_part_sec)).
  289. * @return Pointer to a statically allocated string on success,
  290. * NULL on error.
  291. */
  292. static const char *
  293. sprinttime_ex(const long long sec, const unsigned long long part_sec,
  294. const unsigned int max_part_sec, const int width)
  295. {
  296. static char buf[sizeof(int) * 3 * 6 + sizeof(part_sec) * 3
  297. + sizeof("+0000")];
  298. if ((sec == 0 && part_sec == 0) || part_sec > max_part_sec)
  299. return NULL;
  300. time_t t = (time_t) sec;
  301. struct tm *tmp = (sec == t) ? localtime(&t) : NULL;
  302. if (!tmp)
  303. return NULL;
  304. size_t pos = strftime(buf, sizeof(buf), "%FT%T", tmp);
  305. if (!pos)
  306. return NULL;
  307. if (part_sec > 0)
  308. pos += xsnprintf(buf + pos, sizeof(buf) - pos, ".%0*llu",
  309. width, part_sec);
  310. return strftime(buf + pos, sizeof(buf) - pos, "%z", tmp) ? buf : NULL;
  311. }
  312. const char *
  313. sprinttime(long long sec)
  314. {
  315. return sprinttime_ex(sec, 0, 0, 0);
  316. }
  317. const char *
  318. sprinttime_usec(long long sec, unsigned long long usec)
  319. {
  320. return sprinttime_ex(sec, usec, 999999, 6);
  321. }
  322. const char *
  323. sprinttime_nsec(long long sec, unsigned long long nsec)
  324. {
  325. return sprinttime_ex(sec, nsec, 999999999, 9);
  326. }
  327. void
  328. print_uuid(const unsigned char *uuid)
  329. {
  330. const char str[] = {
  331. BYTE_HEX_CHARS(uuid[0]),
  332. BYTE_HEX_CHARS(uuid[1]),
  333. BYTE_HEX_CHARS(uuid[2]),
  334. BYTE_HEX_CHARS(uuid[3]),
  335. '-',
  336. BYTE_HEX_CHARS(uuid[4]),
  337. BYTE_HEX_CHARS(uuid[5]),
  338. '-',
  339. BYTE_HEX_CHARS(uuid[6]),
  340. BYTE_HEX_CHARS(uuid[7]),
  341. '-',
  342. BYTE_HEX_CHARS(uuid[8]),
  343. BYTE_HEX_CHARS(uuid[9]),
  344. '-',
  345. BYTE_HEX_CHARS(uuid[10]),
  346. BYTE_HEX_CHARS(uuid[11]),
  347. BYTE_HEX_CHARS(uuid[12]),
  348. BYTE_HEX_CHARS(uuid[13]),
  349. BYTE_HEX_CHARS(uuid[14]),
  350. BYTE_HEX_CHARS(uuid[15]),
  351. '\0'
  352. };
  353. tprints(str);
  354. }
  355. enum sock_proto
  356. getfdproto(struct tcb *tcp, int fd)
  357. {
  358. #ifdef HAVE_SYS_XATTR_H
  359. size_t bufsize = 256;
  360. char buf[bufsize];
  361. ssize_t r;
  362. char path[sizeof("/proc/%u/fd/%u") + 2 * sizeof(int)*3];
  363. if (fd < 0)
  364. return SOCK_PROTO_UNKNOWN;
  365. xsprintf(path, "/proc/%u/fd/%u", tcp->pid, fd);
  366. r = tracee_getxattr(tcp, path, "system.sockprotoname", buf,
  367. bufsize - 1);
  368. if (r <= 0)
  369. return SOCK_PROTO_UNKNOWN;
  370. else {
  371. /*
  372. * This is a protection for the case when the kernel
  373. * side does not append a null byte to the buffer.
  374. */
  375. buf[r] = '\0';
  376. return get_proto_by_name(buf);
  377. }
  378. #else
  379. return SOCK_PROTO_UNKNOWN;
  380. #endif
  381. }
  382. unsigned long
  383. getfdinode(struct tcb *tcp, int fd)
  384. {
  385. char path[PATH_MAX + 1];
  386. if (getfdpath(tcp, fd, path, sizeof(path)) >= 0) {
  387. const char *str = STR_STRIP_PREFIX(path, "socket:[");
  388. if (str != path) {
  389. const size_t str_len = strlen(str);
  390. if (str_len && str[str_len - 1] == ']')
  391. return strtoul(str, NULL, 10);
  392. }
  393. }
  394. return 0;
  395. }
  396. static bool
  397. printsocket(struct tcb *tcp, int fd, const char *path)
  398. {
  399. const char *str = STR_STRIP_PREFIX(path, "socket:[");
  400. size_t len;
  401. unsigned long inode;
  402. return (str != path)
  403. && (len = strlen(str))
  404. && (str[len - 1] == ']')
  405. && (inode = strtoul(str, NULL, 10))
  406. && print_sockaddr_by_inode(tcp, fd, inode);
  407. }
  408. static bool
  409. printdev(struct tcb *tcp, int fd, const char *path)
  410. {
  411. strace_stat_t st;
  412. if (path[0] != '/')
  413. return false;
  414. if (tracee_stat(tcp, path, &st)) {
  415. debug_func_perror_msg("stat(\"%s\")", path);
  416. return false;
  417. }
  418. switch (st.st_mode & S_IFMT) {
  419. case S_IFBLK:
  420. case S_IFCHR:
  421. print_quoted_string_ex(path, strlen(path),
  422. QUOTE_OMIT_LEADING_TRAILING_QUOTES,
  423. "<>");
  424. tprintf("<%s %u:%u>",
  425. S_ISBLK(st.st_mode)? "block" : "char",
  426. major(st.st_rdev), minor(st.st_rdev));
  427. return true;
  428. }
  429. return false;
  430. }
  431. void
  432. printfd(struct tcb *tcp, int fd)
  433. {
  434. char path[PATH_MAX + 1];
  435. if (show_fd_path && getfdpath(tcp, fd, path, sizeof(path)) >= 0) {
  436. tprintf("%d<", fd);
  437. if (show_fd_path <= 1
  438. || (!printsocket(tcp, fd, path)
  439. && !printdev(tcp, fd, path))) {
  440. print_quoted_string_ex(path, strlen(path),
  441. QUOTE_OMIT_LEADING_TRAILING_QUOTES, "<>");
  442. }
  443. tprints(">");
  444. } else
  445. tprintf("%d", fd);
  446. }
  447. /*
  448. * Quote string `instr' of length `size'
  449. * Write up to (3 + `size' * 4) bytes to `outstr' buffer.
  450. *
  451. * `escape_chars' specifies characters (in addition to characters with
  452. * codes 0..31, 127..255, single and double quotes) that should be escaped.
  453. *
  454. * If QUOTE_0_TERMINATED `style' flag is set,
  455. * treat `instr' as a NUL-terminated string,
  456. * checking up to (`size' + 1) bytes of `instr'.
  457. *
  458. * If QUOTE_OMIT_LEADING_TRAILING_QUOTES `style' flag is set,
  459. * do not add leading and trailing quoting symbols.
  460. *
  461. * Returns 0 if QUOTE_0_TERMINATED is set and NUL was seen, 1 otherwise.
  462. * Note that if QUOTE_0_TERMINATED is not set, always returns 1.
  463. */
  464. int
  465. string_quote(const char *instr, char *outstr, const unsigned int size,
  466. const unsigned int style, const char *escape_chars)
  467. {
  468. const unsigned char *ustr = (const unsigned char *) instr;
  469. char *s = outstr;
  470. unsigned int i;
  471. int usehex, c, eol;
  472. bool printable;
  473. if (style & QUOTE_0_TERMINATED)
  474. eol = '\0';
  475. else
  476. eol = 0x100; /* this can never match a char */
  477. usehex = 0;
  478. if ((xflag > 1) || (style & QUOTE_FORCE_HEX)) {
  479. usehex = 1;
  480. } else if (xflag) {
  481. /* Check for presence of symbol which require
  482. to hex-quote the whole string. */
  483. for (i = 0; i < size; ++i) {
  484. c = ustr[i];
  485. /* Check for NUL-terminated string. */
  486. if (c == eol)
  487. break;
  488. /* Force hex unless c is printable or whitespace */
  489. if (c > 0x7e) {
  490. usehex = 1;
  491. break;
  492. }
  493. /* In ASCII isspace is only these chars: "\t\n\v\f\r".
  494. * They happen to have ASCII codes 9,10,11,12,13.
  495. */
  496. if (c < ' ' && (unsigned)(c - 9) >= 5) {
  497. usehex = 1;
  498. break;
  499. }
  500. }
  501. }
  502. if (style & QUOTE_EMIT_COMMENT)
  503. s = stpcpy(s, " /* ");
  504. if (!(style & QUOTE_OMIT_LEADING_TRAILING_QUOTES))
  505. *s++ = '\"';
  506. if (usehex) {
  507. /* Hex-quote the whole string. */
  508. for (i = 0; i < size; ++i) {
  509. c = ustr[i];
  510. /* Check for NUL-terminated string. */
  511. if (c == eol)
  512. goto asciz_ended;
  513. *s++ = '\\';
  514. *s++ = 'x';
  515. s = sprint_byte_hex(s, c);
  516. }
  517. goto string_ended;
  518. }
  519. for (i = 0; i < size; ++i) {
  520. c = ustr[i];
  521. /* Check for NUL-terminated string. */
  522. if (c == eol)
  523. goto asciz_ended;
  524. if ((i == (size - 1)) &&
  525. (style & QUOTE_OMIT_TRAILING_0) && (c == '\0'))
  526. goto asciz_ended;
  527. switch (c) {
  528. case '\"': case '\\':
  529. *s++ = '\\';
  530. *s++ = c;
  531. break;
  532. case '\f':
  533. *s++ = '\\';
  534. *s++ = 'f';
  535. break;
  536. case '\n':
  537. *s++ = '\\';
  538. *s++ = 'n';
  539. break;
  540. case '\r':
  541. *s++ = '\\';
  542. *s++ = 'r';
  543. break;
  544. case '\t':
  545. *s++ = '\\';
  546. *s++ = 't';
  547. break;
  548. case '\v':
  549. *s++ = '\\';
  550. *s++ = 'v';
  551. break;
  552. default:
  553. printable = is_print(c);
  554. if (printable && escape_chars)
  555. printable = !strchr(escape_chars, c);
  556. if (printable) {
  557. *s++ = c;
  558. } else {
  559. /* Print \octal */
  560. *s++ = '\\';
  561. if (i + 1 < size
  562. && ustr[i + 1] >= '0'
  563. && ustr[i + 1] <= '7'
  564. ) {
  565. /* Print \ooo */
  566. *s++ = '0' + (c >> 6);
  567. *s++ = '0' + ((c >> 3) & 0x7);
  568. } else {
  569. /* Print \[[o]o]o */
  570. if ((c >> 3) != 0) {
  571. if ((c >> 6) != 0)
  572. *s++ = '0' + (c >> 6);
  573. *s++ = '0' + ((c >> 3) & 0x7);
  574. }
  575. }
  576. *s++ = '0' + (c & 0x7);
  577. }
  578. }
  579. }
  580. string_ended:
  581. if (!(style & QUOTE_OMIT_LEADING_TRAILING_QUOTES))
  582. *s++ = '\"';
  583. if (style & QUOTE_EMIT_COMMENT)
  584. s = stpcpy(s, " */");
  585. *s = '\0';
  586. /* Return zero if we printed entire ASCIZ string (didn't truncate it) */
  587. if (style & QUOTE_0_TERMINATED && ustr[i] == '\0') {
  588. /* We didn't see NUL yet (otherwise we'd jump to 'asciz_ended')
  589. * but next char is NUL.
  590. */
  591. return 0;
  592. }
  593. return 1;
  594. asciz_ended:
  595. if (!(style & QUOTE_OMIT_LEADING_TRAILING_QUOTES))
  596. *s++ = '\"';
  597. if (style & QUOTE_EMIT_COMMENT)
  598. s = stpcpy(s, " */");
  599. *s = '\0';
  600. /* Return zero: we printed entire ASCIZ string (didn't truncate it) */
  601. return 0;
  602. }
  603. #ifndef ALLOCA_CUTOFF
  604. # define ALLOCA_CUTOFF 4032
  605. #endif
  606. #define use_alloca(n) ((n) <= ALLOCA_CUTOFF)
  607. /*
  608. * Quote string `str' of length `size' and print the result.
  609. *
  610. * If QUOTE_0_TERMINATED `style' flag is set,
  611. * treat `str' as a NUL-terminated string and
  612. * quote at most (`size' - 1) bytes.
  613. *
  614. * If QUOTE_OMIT_LEADING_TRAILING_QUOTES `style' flag is set,
  615. * do not add leading and trailing quoting symbols.
  616. *
  617. * Returns 0 if QUOTE_0_TERMINATED is set and NUL was seen, 1 otherwise.
  618. * Note that if QUOTE_0_TERMINATED is not set, always returns 1.
  619. */
  620. int
  621. print_quoted_string_ex(const char *str, unsigned int size,
  622. const unsigned int style, const char *escape_chars)
  623. {
  624. char *buf;
  625. char *outstr;
  626. unsigned int alloc_size;
  627. int rc;
  628. if (size && style & QUOTE_0_TERMINATED)
  629. --size;
  630. alloc_size = 4 * size;
  631. if (alloc_size / 4 != size) {
  632. error_func_msg("requested %u bytes exceeds %u bytes limit",
  633. size, -1U / 4);
  634. tprints("???");
  635. return -1;
  636. }
  637. alloc_size += 1 + (style & QUOTE_OMIT_LEADING_TRAILING_QUOTES ? 0 : 2) +
  638. (style & QUOTE_EMIT_COMMENT ? 7 : 0);
  639. if (use_alloca(alloc_size)) {
  640. outstr = alloca(alloc_size);
  641. buf = NULL;
  642. } else {
  643. outstr = buf = malloc(alloc_size);
  644. if (!buf) {
  645. error_func_msg("memory exhausted when tried to allocate"
  646. " %u bytes", alloc_size);
  647. tprints("???");
  648. return -1;
  649. }
  650. }
  651. rc = string_quote(str, outstr, size, style, escape_chars);
  652. tprints(outstr);
  653. free(buf);
  654. return rc;
  655. }
  656. inline int
  657. print_quoted_string(const char *str, unsigned int size,
  658. const unsigned int style)
  659. {
  660. return print_quoted_string_ex(str, size, style, NULL);
  661. }
  662. /*
  663. * Quote a NUL-terminated string `str' of length up to `size' - 1
  664. * and print the result.
  665. *
  666. * Returns 0 if NUL was seen, 1 otherwise.
  667. */
  668. int
  669. print_quoted_cstring(const char *str, unsigned int size)
  670. {
  671. int unterminated =
  672. print_quoted_string(str, size, QUOTE_0_TERMINATED);
  673. if (unterminated)
  674. tprints("...");
  675. return unterminated;
  676. }
  677. /*
  678. * Print path string specified by address `addr' and length `n'.
  679. * If path length exceeds `n', append `...' to the output.
  680. *
  681. * Returns the result of umovenstr.
  682. */
  683. int
  684. printpathn(struct tcb *const tcp, const kernel_ulong_t addr, unsigned int n)
  685. {
  686. char path[PATH_MAX];
  687. int nul_seen;
  688. if (!addr) {
  689. tprints("NULL");
  690. return -1;
  691. }
  692. /* Cap path length to the path buffer size */
  693. if (n > sizeof(path) - 1)
  694. n = sizeof(path) - 1;
  695. /* Fetch one byte more to find out whether path length > n. */
  696. nul_seen = umovestr(tcp, addr, n + 1, path);
  697. if (nul_seen < 0)
  698. printaddr(addr);
  699. else {
  700. path[n++] = !nul_seen;
  701. print_quoted_cstring(path, n);
  702. }
  703. return nul_seen;
  704. }
  705. int
  706. printpath(struct tcb *const tcp, const kernel_ulong_t addr)
  707. {
  708. /* Size must correspond to char path[] size in printpathn */
  709. return printpathn(tcp, addr, PATH_MAX - 1);
  710. }
  711. /*
  712. * Print string specified by address `addr' and length `len'.
  713. * If `user_style' has QUOTE_0_TERMINATED bit set, treat the string
  714. * as a NUL-terminated string.
  715. * Pass `user_style' on to `string_quote'.
  716. * Append `...' to the output if either the string length exceeds `max_strlen',
  717. * or QUOTE_0_TERMINATED bit is set and the string length exceeds `len'.
  718. *
  719. * Returns the result of umovenstr if style has QUOTE_0_TERMINATED,
  720. * or the result of umoven otherwise.
  721. */
  722. int
  723. printstr_ex(struct tcb *const tcp, const kernel_ulong_t addr,
  724. const kernel_ulong_t len, const unsigned int user_style)
  725. {
  726. static char *str;
  727. static char *outstr;
  728. unsigned int size;
  729. unsigned int style = user_style;
  730. int rc;
  731. int ellipsis;
  732. if (!addr) {
  733. tprints("NULL");
  734. return -1;
  735. }
  736. /* Allocate static buffers if they are not allocated yet. */
  737. if (!str) {
  738. const unsigned int outstr_size =
  739. 4 * max_strlen + /* for quotes and NUL */ 3;
  740. /*
  741. * We can assume that outstr_size / 4 == max_strlen
  742. * since we have a guarantee that max_strlen <= -1U / 4.
  743. */
  744. str = xmalloc(max_strlen + 1);
  745. outstr = xmalloc(outstr_size);
  746. }
  747. /* Fetch one byte more because string_quote may look one byte ahead. */
  748. size = max_strlen + 1;
  749. if (size > len)
  750. size = len;
  751. if (style & QUOTE_0_TERMINATED)
  752. rc = umovestr(tcp, addr, size, str);
  753. else
  754. rc = umoven(tcp, addr, size, str);
  755. if (rc < 0) {
  756. printaddr(addr);
  757. return rc;
  758. }
  759. if (size > max_strlen)
  760. size = max_strlen;
  761. else
  762. str[size] = '\xff';
  763. /* If string_quote didn't see NUL and (it was supposed to be ASCIZ str
  764. * or we were requested to print more than -s NUM chars)...
  765. */
  766. ellipsis = string_quote(str, outstr, size, style, NULL)
  767. && len
  768. && ((style & QUOTE_0_TERMINATED)
  769. || len > max_strlen);
  770. tprints(outstr);
  771. if (ellipsis)
  772. tprints("...");
  773. return rc;
  774. }
  775. void
  776. dumpiov_upto(struct tcb *const tcp, const int len, const kernel_ulong_t addr,
  777. kernel_ulong_t data_size)
  778. {
  779. #if ANY_WORDSIZE_LESS_THAN_KERNEL_LONG
  780. union {
  781. struct { uint32_t base; uint32_t len; } *iov32;
  782. struct { uint64_t base; uint64_t len; } *iov64;
  783. } iovu;
  784. # define iov iovu.iov64
  785. # define sizeof_iov \
  786. (current_wordsize == 4 ? (unsigned int) sizeof(*iovu.iov32) \
  787. : (unsigned int) sizeof(*iovu.iov64))
  788. # define iov_iov_base(i) \
  789. (current_wordsize == 4 ? (uint64_t) iovu.iov32[i].base : iovu.iov64[i].base)
  790. # define iov_iov_len(i) \
  791. (current_wordsize == 4 ? (uint64_t) iovu.iov32[i].len : iovu.iov64[i].len)
  792. #else
  793. struct iovec *iov;
  794. # define sizeof_iov ((unsigned int) sizeof(*iov))
  795. # define iov_iov_base(i) ptr_to_kulong(iov[i].iov_base)
  796. # define iov_iov_len(i) iov[i].iov_len
  797. #endif
  798. int i;
  799. unsigned int size = sizeof_iov * len;
  800. if (size / sizeof_iov != (unsigned int) len) {
  801. error_func_msg("requested %u iovec elements exceeds"
  802. " %u iovec limit", len, -1U / sizeof_iov);
  803. return;
  804. }
  805. iov = malloc(size);
  806. if (!iov) {
  807. error_func_msg("memory exhausted when tried to allocate"
  808. " %u bytes", size);
  809. return;
  810. }
  811. if (umoven(tcp, addr, size, iov) >= 0) {
  812. for (i = 0; i < len; i++) {
  813. kernel_ulong_t iov_len = iov_iov_len(i);
  814. if (iov_len > data_size)
  815. iov_len = data_size;
  816. if (!iov_len)
  817. break;
  818. data_size -= iov_len;
  819. /* include the buffer number to make it easy to
  820. * match up the trace with the source */
  821. tprintf(" * %" PRI_klu " bytes in buffer %d\n", iov_len, i);
  822. dumpstr(tcp, iov_iov_base(i), iov_len);
  823. }
  824. }
  825. free(iov);
  826. #undef sizeof_iov
  827. #undef iov_iov_base
  828. #undef iov_iov_len
  829. #undef iov
  830. }
  831. #define ILOG2_ITER_(val_, ret_, bit_) \
  832. do { \
  833. typeof(ret_) shift_ = \
  834. ((val_) > ((((typeof(val_)) 1) \
  835. << (1 << (bit_))) - 1)) << (bit_); \
  836. (val_) >>= shift_; \
  837. (ret_) |= shift_; \
  838. } while (0)
  839. /**
  840. * Calculate floor(log2(val)), with the exception of val == 0, for which 0
  841. * is returned as well.
  842. *
  843. * @param val 64-bit value to calculate integer base-2 logarithm for.
  844. * @return (unsigned int) floor(log2(val)) if val > 0, 0 if val == 0.
  845. */
  846. static inline unsigned int
  847. ilog2_64(uint64_t val)
  848. {
  849. unsigned int ret = 0;
  850. ILOG2_ITER_(val, ret, 5);
  851. ILOG2_ITER_(val, ret, 4);
  852. ILOG2_ITER_(val, ret, 3);
  853. ILOG2_ITER_(val, ret, 2);
  854. ILOG2_ITER_(val, ret, 1);
  855. ILOG2_ITER_(val, ret, 0);
  856. return ret;
  857. }
  858. /**
  859. * Calculate floor(log2(val)), with the exception of val == 0, for which 0
  860. * is returned as well.
  861. *
  862. * @param val 32-bit value to calculate integer base-2 logarithm for.
  863. * @return (unsigned int) floor(log2(val)) if val > 0, 0 if val == 0.
  864. */
  865. static inline unsigned int
  866. ilog2_32(uint32_t val)
  867. {
  868. unsigned int ret = 0;
  869. ILOG2_ITER_(val, ret, 4);
  870. ILOG2_ITER_(val, ret, 3);
  871. ILOG2_ITER_(val, ret, 2);
  872. ILOG2_ITER_(val, ret, 1);
  873. ILOG2_ITER_(val, ret, 0);
  874. return ret;
  875. }
  876. #undef ILOG2_ITER_
  877. #if SIZEOF_KERNEL_LONG_T > 4
  878. # define ilog2_klong ilog2_64
  879. #else
  880. # define ilog2_klong ilog2_32
  881. #endif
  882. void
  883. dumpstr(struct tcb *const tcp, const kernel_ulong_t addr,
  884. const kernel_ulong_t len)
  885. {
  886. /* xx xx xx xx xx xx xx xx xx xx xx xx xx xx xx xx 1234567890123456 */
  887. enum {
  888. HEX_BIT = 4,
  889. DUMPSTR_GROUP_BYTES = 8,
  890. DUMPSTR_GROUPS = 2,
  891. DUMPSTR_WIDTH_BYTES = DUMPSTR_GROUP_BYTES * DUMPSTR_GROUPS,
  892. /** Width of formatted dump in characters. */
  893. DUMPSTR_WIDTH_CHARS = DUMPSTR_WIDTH_BYTES +
  894. sizeof("xx") * DUMPSTR_WIDTH_BYTES + DUMPSTR_GROUPS,
  895. DUMPSTR_GROUP_MASK = DUMPSTR_GROUP_BYTES - 1,
  896. DUMPSTR_BYTES_MASK = DUMPSTR_WIDTH_BYTES - 1,
  897. /** Minimal width of the offset field in the output. */
  898. DUMPSTR_OFFS_MIN_CHARS = 5,
  899. /** Arbitrarily chosen internal dumpstr buffer limit. */
  900. DUMPSTR_BUF_MAXSZ = 1 << 16,
  901. };
  902. static_assert(!(DUMPSTR_BUF_MAXSZ % DUMPSTR_WIDTH_BYTES),
  903. "Maximum internal buffer size should be divisible "
  904. "by amount of bytes dumped per line");
  905. static_assert(!(DUMPSTR_GROUP_BYTES & DUMPSTR_GROUP_MASK),
  906. "DUMPSTR_GROUP_BYTES is not power of 2");
  907. static_assert(!(DUMPSTR_WIDTH_BYTES & DUMPSTR_BYTES_MASK),
  908. "DUMPSTR_WIDTH_BYTES is not power of 2");
  909. if (len > len + DUMPSTR_WIDTH_BYTES || addr + len < addr) {
  910. debug_func_msg("len %" PRI_klu " at addr %#" PRI_klx
  911. " is too big, skipped", len, addr);
  912. return;
  913. }
  914. static kernel_ulong_t strsize;
  915. static unsigned char *str;
  916. const kernel_ulong_t alloc_size =
  917. MIN(ROUNDUP(len, DUMPSTR_WIDTH_BYTES), DUMPSTR_BUF_MAXSZ);
  918. if (strsize < alloc_size) {
  919. free(str);
  920. str = malloc(alloc_size);
  921. if (!str) {
  922. strsize = 0;
  923. error_func_msg("memory exhausted when tried to allocate"
  924. " %" PRI_klu " bytes", alloc_size);
  925. return;
  926. }
  927. strsize = alloc_size;
  928. }
  929. /**
  930. * Characters needed in order to print the offset field. We calculate
  931. * it this way in order to avoid ilog2_64 call most of the time.
  932. */
  933. const int offs_chars = len > (1 << (DUMPSTR_OFFS_MIN_CHARS * HEX_BIT))
  934. ? 1 + ilog2_klong(len - 1) / HEX_BIT : DUMPSTR_OFFS_MIN_CHARS;
  935. kernel_ulong_t i = 0;
  936. const unsigned char *src;
  937. while (i < len) {
  938. /*
  939. * It is important to overwrite all the byte values, as we
  940. * re-use the buffer in order to avoid its re-initialisation.
  941. */
  942. static char outbuf[] = {
  943. [0 ... DUMPSTR_WIDTH_CHARS - 1] = ' ',
  944. '\0'
  945. };
  946. char *dst = outbuf;
  947. /* Fetching data from tracee. */
  948. if (!i || (i % DUMPSTR_BUF_MAXSZ) == 0) {
  949. kernel_ulong_t fetch_size = MIN(len - i, alloc_size);
  950. if (umoven(tcp, addr + i, fetch_size, str) < 0) {
  951. /*
  952. * Don't silently abort if we have printed
  953. * something already.
  954. */
  955. if (i)
  956. tprintf(" | <Cannot fetch %" PRI_klu
  957. " byte%s from pid %d"
  958. " @%#" PRI_klx ">\n",
  959. fetch_size,
  960. fetch_size == 1 ? "" : "s",
  961. tcp->pid, addr + i);
  962. return;
  963. }
  964. src = str;
  965. }
  966. /* hex dump */
  967. do {
  968. if (i < len) {
  969. dst = sprint_byte_hex(dst, *src);
  970. } else {
  971. *dst++ = ' ';
  972. *dst++ = ' ';
  973. }
  974. dst++; /* space is there */
  975. i++;
  976. if ((i & DUMPSTR_GROUP_MASK) == 0)
  977. dst++; /* space is there */
  978. src++;
  979. } while (i & DUMPSTR_BYTES_MASK);
  980. /* ASCII dump */
  981. i -= DUMPSTR_WIDTH_BYTES;
  982. src -= DUMPSTR_WIDTH_BYTES;
  983. do {
  984. if (i < len) {
  985. if (is_print(*src))
  986. *dst++ = *src;
  987. else
  988. *dst++ = '.';
  989. } else {
  990. *dst++ = ' ';
  991. }
  992. src++;
  993. } while (++i & DUMPSTR_BYTES_MASK);
  994. tprintf(" | %0*" PRI_klx " %s |\n",
  995. offs_chars, i - DUMPSTR_WIDTH_BYTES, outbuf);
  996. }
  997. }
  998. bool
  999. tfetch_mem64(struct tcb *const tcp, const uint64_t addr,
  1000. const unsigned int len, void *const our_addr)
  1001. {
  1002. return addr && verbose(tcp) &&
  1003. (entering(tcp) || !syserror(tcp)) &&
  1004. !umoven(tcp, addr, len, our_addr);
  1005. }
  1006. bool
  1007. tfetch_mem64_ignore_syserror(struct tcb *const tcp, const uint64_t addr,
  1008. const unsigned int len, void *const our_addr)
  1009. {
  1010. return addr && verbose(tcp) &&
  1011. !umoven(tcp, addr, len, our_addr);
  1012. }
  1013. int
  1014. umoven_or_printaddr64(struct tcb *const tcp, const uint64_t addr,
  1015. const unsigned int len, void *const our_addr)
  1016. {
  1017. if (tfetch_mem64(tcp, addr, len, our_addr))
  1018. return 0;
  1019. printaddr64(addr);
  1020. return -1;
  1021. }
  1022. int
  1023. umoven_or_printaddr64_ignore_syserror(struct tcb *const tcp,
  1024. const uint64_t addr,
  1025. const unsigned int len,
  1026. void *const our_addr)
  1027. {
  1028. if (tfetch_mem64_ignore_syserror(tcp, addr, len, our_addr))
  1029. return 0;
  1030. printaddr64(addr);
  1031. return -1;
  1032. }
  1033. bool
  1034. print_int32_array_member(struct tcb *tcp, void *elem_buf, size_t elem_size,
  1035. void *data)
  1036. {
  1037. tprintf("%" PRId32, *(int32_t *) elem_buf);
  1038. return true;
  1039. }
  1040. bool
  1041. print_uint32_array_member(struct tcb *tcp, void *elem_buf, size_t elem_size,
  1042. void *data)
  1043. {
  1044. tprintf("%" PRIu32, *(uint32_t *) elem_buf);
  1045. return true;
  1046. }
  1047. bool
  1048. print_uint64_array_member(struct tcb *tcp, void *elem_buf, size_t elem_size,
  1049. void *data)
  1050. {
  1051. tprintf("%" PRIu64, *(uint64_t *) elem_buf);
  1052. return true;
  1053. }
  1054. /*
  1055. * Iteratively fetch and print up to nmemb elements of elem_size size
  1056. * from the array that starts at tracee's address start_addr.
  1057. *
  1058. * Array elements are being fetched to the address specified by elem_buf.
  1059. *
  1060. * The fetcher callback function specified by tfetch_mem_func should follow
  1061. * the same semantics as tfetch_mem function.
  1062. *
  1063. * The printer callback function specified by print_func is expected
  1064. * to print something; if it returns false, no more iterations will be made.
  1065. *
  1066. * The pointer specified by opaque_data is passed to each invocation
  1067. * of print_func callback function.
  1068. *
  1069. * This function prints:
  1070. * - "NULL", if start_addr is NULL;
  1071. * - "[]", if nmemb is 0;
  1072. * - start_addr, if nmemb * elem_size overflows or wraps around;
  1073. * - start_addr, if the first tfetch_mem_func invocation returned false;
  1074. * - elements of the array, delimited by ", ", with the array itself
  1075. * enclosed with [] brackets.
  1076. *
  1077. * If abbrev(tcp) is true, then
  1078. * - the maximum number of elements printed equals to max_strlen;
  1079. * - "..." is printed instead of max_strlen+1 element
  1080. * and no more iterations will be made.
  1081. *
  1082. * This function returns true only if tfetch_mem_func has returned true
  1083. * at least once.
  1084. */
  1085. bool
  1086. print_array_ex(struct tcb *const tcp,
  1087. const kernel_ulong_t start_addr,
  1088. const size_t nmemb,
  1089. void *const elem_buf,
  1090. const size_t elem_size,
  1091. tfetch_mem_fn tfetch_mem_func,
  1092. print_fn print_func,
  1093. void *const opaque_data,
  1094. unsigned int flags,
  1095. const struct xlat *index_xlat,
  1096. size_t index_xlat_size,
  1097. const char *index_dflt)
  1098. {
  1099. if (!start_addr) {
  1100. tprints("NULL");
  1101. return false;
  1102. }
  1103. if (!nmemb) {
  1104. tprints("[]");
  1105. return false;
  1106. }
  1107. const size_t size = nmemb * elem_size;
  1108. const kernel_ulong_t end_addr = start_addr + size;
  1109. if (end_addr <= start_addr || size / elem_size != nmemb) {
  1110. printaddr(start_addr);
  1111. return false;
  1112. }
  1113. const kernel_ulong_t abbrev_end =
  1114. (abbrev(tcp) && max_strlen < nmemb) ?
  1115. start_addr + elem_size * max_strlen : end_addr;
  1116. kernel_ulong_t cur;
  1117. kernel_ulong_t idx = 0;
  1118. enum xlat_style xlat_style = flags & XLAT_STYLE_MASK;
  1119. for (cur = start_addr; cur < end_addr; cur += elem_size, idx++) {
  1120. if (cur != start_addr)
  1121. tprints(", ");
  1122. if (!tfetch_mem_func(tcp, cur, elem_size, elem_buf)) {
  1123. if (cur == start_addr)
  1124. printaddr(cur);
  1125. else {
  1126. tprints("...");
  1127. printaddr_comment(cur);
  1128. }
  1129. break;
  1130. }
  1131. if (cur == start_addr)
  1132. tprints("[");
  1133. if (cur >= abbrev_end) {
  1134. tprints("...");
  1135. cur = end_addr;
  1136. break;
  1137. }
  1138. if (flags & PAF_PRINT_INDICES) {
  1139. tprints("[");
  1140. if (!index_xlat) {
  1141. print_xlat_ex(idx, NULL, xlat_style);
  1142. } else if (flags & PAF_INDEX_XLAT_VALUE_INDEXED) {
  1143. printxval_indexn_ex(index_xlat,
  1144. index_xlat_size, idx,
  1145. index_dflt, xlat_style);
  1146. } else {
  1147. printxvals_ex(idx, index_dflt, xlat_style,
  1148. (flags & PAF_INDEX_XLAT_SORTED)
  1149. && idx ? NULL : index_xlat,
  1150. NULL);
  1151. }
  1152. tprints("] = ");
  1153. }
  1154. if (!print_func(tcp, elem_buf, elem_size, opaque_data)) {
  1155. cur = end_addr;
  1156. break;
  1157. }
  1158. }
  1159. if (cur != start_addr)
  1160. tprints("]");
  1161. return cur >= end_addr;
  1162. }
  1163. int
  1164. printargs(struct tcb *tcp)
  1165. {
  1166. const int n = n_args(tcp);
  1167. int i;
  1168. for (i = 0; i < n; ++i)
  1169. tprintf("%s%#" PRI_klx, i ? ", " : "", tcp->u_arg[i]);
  1170. return RVAL_DECODED;
  1171. }
  1172. int
  1173. printargs_u(struct tcb *tcp)
  1174. {
  1175. const int n = n_args(tcp);
  1176. int i;
  1177. for (i = 0; i < n; ++i)
  1178. tprintf("%s%u", i ? ", " : "",
  1179. (unsigned int) tcp->u_arg[i]);
  1180. return RVAL_DECODED;
  1181. }
  1182. int
  1183. printargs_d(struct tcb *tcp)
  1184. {
  1185. const int n = n_args(tcp);
  1186. int i;
  1187. for (i = 0; i < n; ++i)
  1188. tprintf("%s%d", i ? ", " : "",
  1189. (int) tcp->u_arg[i]);
  1190. return RVAL_DECODED;
  1191. }
  1192. /* Print abnormal high bits of a kernel_ulong_t value. */
  1193. void
  1194. print_abnormal_hi(const kernel_ulong_t val)
  1195. {
  1196. if (current_klongsize > 4) {
  1197. const unsigned int hi = (unsigned int) ((uint64_t) val >> 32);
  1198. if (hi)
  1199. tprintf("%#x<<32|", hi);
  1200. }
  1201. }
  1202. int
  1203. read_int_from_file(struct tcb *tcp, const char *const fname, int *const pvalue)
  1204. {
  1205. const int fd = tracee_open(tcp, fname, O_RDONLY, 0);
  1206. if (fd < 0)
  1207. return -1;
  1208. long lval;
  1209. char buf[sizeof(lval) * 3];
  1210. int n = tracee_pread(tcp, fd, buf, sizeof(buf) - 1, 0);
  1211. int saved_errno = errno;
  1212. tracee_close(tcp, fd);
  1213. if (n < 0) {
  1214. errno = saved_errno;
  1215. return -1;
  1216. }
  1217. buf[n] = '\0';
  1218. char *endptr = 0;
  1219. errno = 0;
  1220. lval = strtol(buf, &endptr, 10);
  1221. if (!endptr || (*endptr && '\n' != *endptr)
  1222. #if INT_MAX < LONG_MAX
  1223. || lval > INT_MAX || lval < INT_MIN
  1224. #endif
  1225. || ERANGE == errno) {
  1226. if (!errno)
  1227. errno = EINVAL;
  1228. return -1;
  1229. }
  1230. *pvalue = (int) lval;
  1231. return 0;
  1232. }