/* * Copyright (c) 2004 Ulrich Drepper * Copyright (c) 2004-2016 Dmitry V. Levin * Copyright (c) 2015-2021 The strace developers. * All rights reserved. * * SPDX-License-Identifier: LGPL-2.1-or-later */ #include "defs.h" #include DEF_MPERS_TYPE(struct_rtc_pll_info) #include #include typedef struct rtc_pll_info struct_rtc_pll_info; #include MPERS_DEFS typedef struct { uint64_t param; union { uint64_t uvalue; int64_t svalue; uint64_t ptr; }; uint32_t index; uint32_t __pad; } struct_rtc_param; #define XLAT_MACROS_ONLY # include "xlat/rtc_ioctl_cmds.h" # include "xlat/rtc_feature_bits.h" #undef XLAT_MACROS_ONLY #include "xlat/rtc_vl_flags.h" #include "xlat/rtc_params.h" #include "xlat/rtc_features.h" #include "xlat/rtc_backup_switch_modes.h" static void print_rtc_time(struct tcb *tcp, const struct rtc_time *rt) { tprint_struct_begin(); PRINT_FIELD_D(*rt, tm_sec); tprint_struct_next(); PRINT_FIELD_D(*rt, tm_min); tprint_struct_next(); PRINT_FIELD_D(*rt, tm_hour); tprint_struct_next(); PRINT_FIELD_D(*rt, tm_mday); tprint_struct_next(); PRINT_FIELD_D(*rt, tm_mon); tprint_struct_next(); PRINT_FIELD_D(*rt, tm_year); if (abbrev(tcp)) { tprint_struct_next(); tprint_more_data_follows(); } else { tprint_struct_next(); PRINT_FIELD_D(*rt, tm_wday); tprint_struct_next(); PRINT_FIELD_D(*rt, tm_yday); tprint_struct_next(); PRINT_FIELD_D(*rt, tm_isdst); } tprint_struct_end(); } static void decode_rtc_time(struct tcb *const tcp, const kernel_ulong_t addr) { struct rtc_time rt; if (!umove_or_printaddr(tcp, addr, &rt)) print_rtc_time(tcp, &rt); } static void decode_rtc_wkalrm(struct tcb *const tcp, const kernel_ulong_t addr) { struct rtc_wkalrm wk; if (umove_or_printaddr(tcp, addr, &wk)) return; tprint_struct_begin(); PRINT_FIELD_U(wk, enabled); tprint_struct_next(); PRINT_FIELD_U(wk, pending); tprint_struct_next(); PRINT_FIELD_OBJ_TCB_PTR(wk, time, tcp, print_rtc_time); tprint_struct_end(); } static void decode_rtc_pll_info(struct tcb *const tcp, const kernel_ulong_t addr) { struct_rtc_pll_info pll; if (umove_or_printaddr(tcp, addr, &pll)) return; tprint_struct_begin(); PRINT_FIELD_D(pll, pll_ctrl); tprint_struct_next(); PRINT_FIELD_D(pll, pll_value); tprint_struct_next(); PRINT_FIELD_D(pll, pll_max); tprint_struct_next(); PRINT_FIELD_D(pll, pll_min); tprint_struct_next(); PRINT_FIELD_D(pll, pll_posmult); tprint_struct_next(); PRINT_FIELD_D(pll, pll_negmult); tprint_struct_next(); PRINT_FIELD_D(pll, pll_clock); tprint_struct_end(); } static void decode_rtc_vl(struct tcb *const tcp, const kernel_ulong_t addr) { unsigned int val; if (umove_or_printaddr(tcp, addr, &val)) return; tprint_indirect_begin(); printflags(rtc_vl_flags, val, "RTC_VL_???"); tprint_indirect_end(); } static long decode_rtc_param(struct tcb *const tcp, const kernel_ulong_t addr, const bool get) { struct_rtc_param param; if (umove_or_printaddr(tcp, addr, ¶m)) return RVAL_IOCTL_DECODED; tprint_struct_begin(); if (entering(tcp)) PRINT_FIELD_XVAL(param, param, rtc_params, "RTC_PARAM_???"); if (entering(tcp) ^ get) { if (entering(tcp)) tprint_struct_next(); switch (param.param) { case RTC_PARAM_FEATURES: PRINT_FIELD_FLAGS(param, uvalue, rtc_features, "1<