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 33KB

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