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.

kexec.c 2.1KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103
  1. /*
  2. * Copyright (c) 2014-2015 Dmitry V. Levin <ldv@altlinux.org>
  3. * Copyright (c) 2014-2018 The strace developers.
  4. * All rights reserved.
  5. *
  6. * SPDX-License-Identifier: LGPL-2.1-or-later
  7. */
  8. #include "defs.h"
  9. #include "xlat/kexec_load_flags.h"
  10. #include "xlat/kexec_arch_values.h"
  11. #ifndef KEXEC_ARCH_MASK
  12. # define KEXEC_ARCH_MASK 0xffff0000
  13. #endif
  14. #ifndef KEXEC_SEGMENT_MAX
  15. # define KEXEC_SEGMENT_MAX 16
  16. #endif
  17. static bool
  18. print_seg(struct tcb *tcp, void *elem_buf, size_t elem_size, void *data)
  19. {
  20. const kernel_ulong_t *seg;
  21. kernel_ulong_t seg_buf[4];
  22. if (elem_size < sizeof(seg_buf)) {
  23. unsigned int i;
  24. for (i = 0; i < ARRAY_SIZE(seg_buf); ++i)
  25. seg_buf[i] = ((unsigned int *) elem_buf)[i];
  26. seg = seg_buf;
  27. } else {
  28. seg = elem_buf;
  29. }
  30. tprints("{buf=");
  31. printaddr(seg[0]);
  32. tprintf(", bufsz=%" PRI_klu ", mem=", seg[1]);
  33. printaddr(seg[2]);
  34. tprintf(", memsz=%" PRI_klu "}", seg[3]);
  35. return true;
  36. }
  37. static void
  38. print_kexec_segments(struct tcb *const tcp, const kernel_ulong_t addr,
  39. const kernel_ulong_t len)
  40. {
  41. if (len > KEXEC_SEGMENT_MAX) {
  42. printaddr(addr);
  43. return;
  44. }
  45. kernel_ulong_t seg[4];
  46. const size_t sizeof_seg = ARRAY_SIZE(seg) * current_wordsize;
  47. print_array(tcp, addr, len, seg, sizeof_seg,
  48. tfetch_mem, print_seg, 0);
  49. }
  50. SYS_FUNC(kexec_load)
  51. {
  52. /* entry, nr_segments */
  53. printaddr(tcp->u_arg[0]);
  54. tprintf(", %" PRI_klu ", ", tcp->u_arg[1]);
  55. /* segments */
  56. print_kexec_segments(tcp, tcp->u_arg[2], tcp->u_arg[1]);
  57. tprints(", ");
  58. /* flags */
  59. kernel_ulong_t n = tcp->u_arg[3];
  60. printxval64(kexec_arch_values, n & KEXEC_ARCH_MASK, "KEXEC_ARCH_???");
  61. n &= ~(kernel_ulong_t) KEXEC_ARCH_MASK;
  62. if (n) {
  63. tprints("|");
  64. printflags64(kexec_load_flags, n, "KEXEC_???");
  65. }
  66. return RVAL_DECODED;
  67. }
  68. #include "xlat/kexec_file_load_flags.h"
  69. SYS_FUNC(kexec_file_load)
  70. {
  71. /* kernel_fd */
  72. printfd(tcp, tcp->u_arg[0]);
  73. tprints(", ");
  74. /* initrd_fd */
  75. printfd(tcp, tcp->u_arg[1]);
  76. tprints(", ");
  77. /* cmdline_len */
  78. tprintf("%" PRI_klu ", ", tcp->u_arg[2]);
  79. /* cmdline */
  80. printstrn(tcp, tcp->u_arg[3], tcp->u_arg[2]);
  81. tprints(", ");
  82. /* flags */
  83. printflags64(kexec_file_load_flags, tcp->u_arg[4], "KEXEC_FILE_???");
  84. return RVAL_DECODED;
  85. }