module_param: display value in hex instead of decimal - linux-kernel

Is it possible to display value of module_param when read, in hex?
I have this code in my linux device driver:
module_param(num_in_hex, ulong, 0644)
$cat /sys/module/my_module/parameters/num_in_hex
1234512345
Would like to see that value in hex, instead of decimal. Or, should I use different way like debugfs for this?

There is no ready parameter type (2nd argument of module_param macro), which output its argument as hexadecimal. But it is not difficult to implement it.
Module parameters are driven by callback functions, which extract parameter's value from string and write parameter's value to string.
// Set hexadecimal parameter
int param_set_hex(const char *val, const struct kernel_param *kp)
{
return kstrtoul(val, 16, (unsigned long*)kp->arg);
}
// Read hexadecimal parameter
int param_get_hex(char *buffer, const struct kernel_param *kp)
{
return scnprintf(buffer, PAGE_SIZE, "%lx", *((unsigned long*)kp->arg));
}
// Combine operations together
const struct kernel_param_ops param_ops_hex = {
.set = param_set_hex,
.get = param_get_hex
};
/*
* Macro for check type of variable, passed to `module_param`.
* Just reuse already existed macro for `ulong` type.
*/
#define param_check_hex(name, p) param_check_ulong(name, p)
// Everything is ready for use `module_param` with new type.
module_param(num_in_hex, hex, 0644);
Check include/linux/moduleparam.h for implementation module_param macro and kernel/params.c for implementation of operations for ready-made types (macro STANDARD_PARAM_DEF).

Related

how can i safely convert an ascii integer back to its associated ascii character using curses in c++?

I have not been able to find a reliable solution for my problem, what i'm simply trying to do is create some function which:
takes an rows and columns position in the terminal.
calls mvinch(window_object , rows, cols), which returns an unsigned int which corresponds to the character in the terminal at that position.
returns the ascii character associated with that unsigned int, effectively casting it back to a char.
Here is an example of my code in c++11:
char Kmenu::getChrfromW(size_t const y, size_t const x,
bool const save_cursor) const {
size_t curr_y, curr_x;
getyx(_win, curr_y, curr_x);
char ich = mvwinch(_win, y, x);
char ch = ich;
if (save_cursor)
wmove(_win, curr_y, curr_x);
return ch;
}
If for example the character in the terminal at position 2,3 is the letter 'a', i want this function to return the letter 'a'.
I tried the solution described here:
Convert ASCII number to ASCII Character in C
which effectively casts an integer as char.
unfortunately what i get back is still the integer: testing with a screen filled with 'w's, i get back the integer 119.
the man page for the curses function mvwinch() describes the function to return chtype, which the compiler recognises as unsigned int.
Is there a built in a curses function which gives the char back directly without casting to unsigned int, or some other way i can achieve this?
Edit: ch to ich, as in the actual code
A chtype contains a character along with other data. The curses.h header has several symbols which are useful for extracting those bits. If you mask it with A_CHARTEXT and cast that to a char, you will get a character:
char c = (char)((A_CHARTEXT) & n);
Your example should not compile, since it declares ch twice. You may have meant this:
char Kmenu::getChrfromW(size_t const y, size_t const x,
bool const save_cursor) const {
int curr_y, curr_x; // size_t is inappropriate...
getyx(_win, curr_y, curr_x);
char ch = (char)((A_CHARTEXT) & mvwinch(_win, y, x));
// char ch = ich;
if (save_cursor)
wmove(_win, curr_y, curr_x);
return ch;
}
The manual page for mvwinch mentions the A_CHARTEXT mask in the Attributes section, assuming the reader is familiar with things like that:
The following bit-masks may be AND-ed with characters returned by
winch.
A_CHARTEXT Bit-mask to extract character
A_ATTRIBUTES Bit-mask to extract attributes
A_COLOR Bit-mask to extract color-pair field information

Struct structure with method in linux source code

I am reading android kernel code and I'm facing this kind of data structures ,
static const struct file_operations tracing_fops = {
.open = tracing_open,
.read = seq_read,
.write = tracing_write_stub,
.llseek = tracing_seek,
.release = tracing_release,
};
can someone explain this syntax generally ? right side of equations are functions names and &tracing_fops later is passed as an argument to another function that inits debugfs file system.
The assignment is an example of using Compund Literals. According to C99 Section #6.5.2.5:
A postfix expression that consists of a parenthesized type name
followed by a brace- enclosed list of initializers is a compound
literal. It provides an unnamed object whose value is given by the
initializer list.
In simpler version, according to GCC docs: Compound literals:
A compound literal looks like a cast of a brace-enclosed aggregate
initializer list. Its value is an object of the type specified in the
cast, containing the elements specified in the initializer. Unlike the
result of a cast, a compound literal is an lvalue. ISO C99 and later
support compound literals. As an extension, GCC supports compound
literals also in C90 mode and in C++, although as explained below, the
C++ semantics are somewhat different.
An simple example:
struct foo { int x; int y; };
func() {
struct foo var = { .x = 2, .y = 3 };
...
}
In the question's example, the struct file_operations is defined in include/linux/fs.h and tracing_fops is in kernel/trace/trace.c file in Linux source tree.
struct file_operations {
struct module *owner;
loff_t (*llseek) (struct file *, loff_t, int);
ssize_t (*read) (struct file *, char __user *, size_t, loff_t *);
ssize_t (*write) (struct file *, const char __user *, size_t, loff_t *);
ssize_t (*read_iter) (struct kiocb *, struct iov_iter *);
ssize_t (*write_iter) (struct kiocb *, struct iov_iter *);
...
};
The open, read, write are Function Pointers which are pointers that points to a function. After dereferencing the function pointer, it can be used as normal function call. The tracing_fops structure is file_operations type. The values of function pointer members are assigned to the functions in the same trace.c file using compound literals.
With compound literals, we don't have to explicitly specify/assign all members in the structure type because other members are set to zero or null. Structure objects created using compound literals can be passed to functions without depending on member order. The function parameters should be same for both side. For example, the parameters of
int (*open) (struct inode *, struct file *);
is same as
int tracing_open(struct inode *inode, struct file *file);
In object oriented programming, this idea is somewhat similar as Virtual Function Table.
This is simply a struct initialization, using field names to assign values to specific fields only. You can take a look at struct initialization at cppreference which demonstrates these use cases (and even more advanced situations, such as omitting specific field names, etc.)
The Linux kernel sources often make use of structs consisting of sets of function pointers for related operations. These are used to provide distinct implementations of the same interface, akin to what would be accomplished using class inheritance in object-oriented languages. For instance, in C++ this same idea would be implemented using virtual methods and the function pointers would be stored in the class vtable (which means this would be implicit rather than explicit in C++.)
Using this struct in C is similar to how you'd use an object of a class using virtual methods in C++, since you can simply call one of the "methods" using:
int r = fops->open(inode, filp);
The actual code typically tests whether the struct member is set, since the struct initialization will keep the pointers that are not explicitly mentioned set to NULL, making it possible to use this kind of struct to implement optional operations as well.
The main difference being that in C++ you'd have an implicit reference to the object itself (this), while in C you have to pass that as an additional argument in cases where it's needed.

how to define a CAPL function taking a sysvar argument

In Vector CANoe, is it possible to define a function that takes a system variable argument like the system function TestWaitForSignalMatch()?
For my use case it is not sufficient to supply the current value of the system variable because I want to pass the system variable to TestWaitForSignalMatch() or similar system functions.
The CANoe help seems to show examples:
long TestWaitForSignalMatch (Signal aSignal, float aCompareValue, dword aTimeout); // form 1
long TestWaitForSignalMatch (sysvar aSysVar, float aCompareValue, dword aTimeout); // form 3
I tried like this
void foo(sysvar aSysvar) {}
^
or this
void foo(sysvar *aSysvar) {}
^
but I get a parse error at the marked position of the sysvar keyword in both cases.
I successfully created functions that take a signal argument, but unlike the syntax in the CANoe help I have to use a pointer.
This works:
void foo(signal *aSignal) {}
Obviously the documentation in the help is not correct in this point. It results in a parse error after the signal keyword when I omit the * as shown in the help:
void bar(signal aSignal) {}
^
So what's the correct syntax for defining a function that takes a sysvar argument? (if possible)
In case the version matters, I'm currently testing with CANoe 9.0.53(SP1), 9.0.135(SP7) or 10.0.125(SP6).
You have to use the correct type. You have the following possibilities to declare system variables in functions:
Integer: sysvarInt*
Float: sysvarFloat*
String: sysvarString*
Integer Array: sysvarIntArray*
Float Array: sysvarFloatArray*
Data: sysvarData*
Examples:
void PutSysVarIntArrayToByteArray (sysvarIntArray * from, byte to[], word length)
{
word ii;
for (ii = 0; ii < length; ii++)
{
to[ii] = (byte)#from[ii];
}
}
You can also write to the system variable:
void PutByteToSysVarInt (byte from, sysvarInt * to) {
#to = from;
}
See also CANoe Help page "Test Features » XML » Declaration and Transfer of CAPL Test Case and Test Function Parameters"
Yes, you can. Just define a bit further your sysvar type, not just sysvar.
System variables, with indication of type and *. Possible types:
Data, Int, Float, String, IntArray, and FloatArray. Example
declaration: sysvarFloat * sv
You didn't specify the CANoe SP version, so it may not be supported in older versions, but to make sure of this, search for Function parameter in Help/Index, then you should get the full list of possible function parameters you can use in your current CANoe setup. Should start like this:
Integers (byte, word, dword, int, long, qword, int64) Example
declaration: long 1
Integers (byte, word, dword, int, long, qword, int64) Example
declaration: long 1
Individual characters (char) Example declaration: char ch
Enums Example declaration: enum Colors c
Associative fields Example declaration: int m[float]. Associative
fields are transferred as reference automatically.
.............
System variables, with indication of type and *. Possible types:
Data, Int, Float, String, IntArray, and FloatArray. Example
declaration: sysvarFloat * sv

Converting raw pointer to 16-bit Unicode character to file path in Rust

I'm replacing a DLL written in C++ with one written in Rust.
Currently the function in the DLL is called as follows:
BOOL calledFunction(wchar_t* pFileName)
I believe that in this context wchar_t is a 16-bit Unicode character, so I chose to expose the following function in my Rust DLL:
pub fn calledFunction(pFileName: *const u16)
What would be the best way to convert that raw pointer to something I could actually use to open the file from the Rust DLL?
Here is some example code:
use std::ffi::OsString;
use std::os::windows::prelude::*;
unsafe fn u16_ptr_to_string(ptr: *const u16) -> OsString {
let len = (0..).take_while(|&i| *ptr.offset(i) != 0).count();
let slice = std::slice::from_raw_parts(ptr, len);
OsString::from_wide(slice)
}
// main example
fn main() {
let buf = vec![97_u16, 98, 99, 100, 101, 102, 0];
let ptr = buf.as_ptr(); // raw pointer
let string = unsafe { u16_ptr_to_string(ptr) };
println!("{:?}", string);
}
In u16_ptr_to_string, you do 3 things:
get the length of the string by counting the non-zero characters using offset (unsafe)
create a slice using from_raw_parts (unsafe)
transform this &[u16] into an OsString with from_wide
It is better to use wchar_t and wcslen from the libc crate and use another crate for conversion. This is maybe a bad idea to reimplement something that is already maintained in a crate.
You need to use OsString, which represents the native string format used by the operating system. In Windows these are specifically 16-bit character strings (usually UTF-16).
Quoting the doc:
OsString and OsStr are useful when you need to transfer strings to and from the operating system itself, or when capturing the output of external commands. Conversions between OsString, OsStr and Rust strings work similarly to those for CString and CStr.
You first need to convert the pointer into a slice, using unsafe code:
use std::slice;
// manifest a slice out of thin air!
let ptr = 0x1234 as const *u16;
let nb_elements = 10;
unsafe {
let slice = slice::from_raw_parts(ptr, nb_elements);
}
This assumes you know the size of your string, meaning your function should also take the number of characters as argument.
The from_wide method should be the one needed to convert from a native format:
use std::ffi::OsString;
use std::os::windows::prelude::*;
// UTF-16 encoding for "Unicode".
let arr = [0x0055, 0x006E, 0x0069, 0x0063, 0x006F, 0x0064, 0x0065];
let string = OsString::from_wide(&arr[..]);

How do you convert a 'System::String ^' to 'TCHAR'?

i asked a question here involving C++ and C# communicating. The problem got solved but led to a new problem.
this returns a String (C#)
return Marshal.PtrToStringAnsi(decryptsn(InpData));
this expects a TCHAR* (C++)
lpAlpha2[0] = Company::Pins::Bank::Decryption::Decrypt::Decryption("123456");
i've googled how to solve this problem, but i am not sure why the String has a carrot(^) on it. Would it be best to change the return from String to something else that C++ would accept? or would i need to do a convert before assigning the value?
String has a ^ because that's the marker for a managed reference. Basically, it's used the same way as * in unmanaged land, except it can only point to an object type, not to other pointer types, or to void.
TCHAR is #defined (or perhaps typedefed, I can't remember) to either char or wchar_t, based on the _UNICODE preprocessor definition. Therefore, I would use that and write the code twice.
Either inline:
TCHAR* str;
String^ managedString
#ifdef _UNICODE
str = (TCHAR*) Marshal::StringToHGlobalUni(managedString).ToPointer();
#else
str = (TCHAR*) Marshal::StringToHGlobalAnsi(managedString).ToPointer();
#endif
// use str.
Marshal::FreeHGlobal(IntPtr(str));
or as a pair of conversion methods, both of which assume that the output buffer has already been allocated and is large enough. Method overloading should make it pick the correct one, based on what TCHAR is defined as.
void ConvertManagedString(String^ managedString, char* outString)
{
char* str;
str = (char*) Marshal::StringToHGlobalAnsi(managedString).ToPointer();
strcpy(outString, str);
Marshal::FreeHGlobal(IntPtr(str));
}
void ConvertManagedString(String^ managedString, wchar_t* outString)
{
wchar_t* str;
str = (wchar_t*) Marshal::StringToHGlobalUni(managedString).ToPointer();
wcscpy(outString, str);
Marshal::FreeHGlobal(IntPtr(str));
}
The syntax String^ is C++/CLI talk for "(garbage collected) reference to a System.String".
You have a couple of options for the conversion of a String into a C string, which is another way to express the TCHAR*. My preferred way in C++ would be to store the converted string into a C++ string type, either std::wstring or std::string, depending on you building the project as a Unicode or MBCS project.
In either case you can use something like this:
std::wstring tmp = msclr::interop::marshal_as<std::wstring>( /* Your .NET String */ );
or
std::string tmp = msclr::interop::marshal_as<std::string>(...);
Once you've converted the string into the correct wide or narrow string format, you can then access its C string representation using the c_str() function, like so:
callCFunction(tmp.c_str());
Assuming that callCFunction expects you to pass it a C-style char* or wchar_t* (which TCHAR* will "degrade" to depending on your compilation settings.
That is a really rambling way to ask the question, but if you mean how to convert a String ^ to a char *, then you use the same marshaller you used before, only backwards:
char* unmanagedstring = (char *) Marshal::StringToHGlobalAnsi(managedstring).ToPointer();
Edit: don't forget to release the memory allocated when you're done using Marshal::FreeHGlobal.

Resources