What does DEFINE_IDA mean? - linux-kernel

I was going through chipidea usb otg driver code and I see such similar definitions numerous times.
static DEFINE_IDA(ci_ida);
I don't get what it meant in the programming world and its purpose. Can someone please explain the same?

As already noted, DEFINE_IDE(name) is #defined as struct ida name = IDA_INIT(name). You should check out LXR which is very convenient for browsing kernel source.
IDR is a subsystem in the kernel that provides an efficient way to map ids to pointers. Normally you would use the id as an offset into an array of pointers, but this limits how big your ids are. IDR solves this by using radix trees instead for lookup.
Sometimes you just want unique ids without associating them with pointers and that's what IDA is for.
/* IDA - IDR based ID allocator
*
* This is id allocator without id -> pointer translation. Memory
* usage is much lower than full blown idr because each id only
* occupies a bit.

Related

What may be the problem with Clang's -fmerge-all-constants?

The compilation flag -fmerge-all-constants merges identical constants into a single variable. I keep reading that this results in non-conforming code, and Linus Torvalds wrote that it's inexcusable, but why?
What can possibly happen when you merge two or more identical constant variables?
There are times when programs declare a constant object because they need something with a unique address, and there are times when any address that points to storage holding the proper sequence of byte values would be equally usable. In C, if one writes:
char const * const HelloShared1 = "Hello";
char const * const HelloShared2 = "Hello";
char const HelloUnique1[] = "Hello";
char const HelloUnique2[] = "Hello";
a compiler would have to reserve space for at least three copies of the word Hello, followed by a zero byte. The names HelloUnique1 and HelloUnique2 would refer to two of those copies, and the names HelloShared1 and HelloShared2 would need to identify storage that was distinct from that used by HelloUnique1 and HelloUnique2, but HelloShared1 and HelloShared2 could at the compiler's convenience identify the same storage.
Unfortunately, while the C and C++ Standards usefully provides two ways of specifying objects that hold string literal data, so as to allow programmers to indicate when multiple copies of the same information may be placed in the same storage, it fails to specify any means of specifying the same semantics for any other kind of constant data. For most kinds of applications, situations where a program would care about whether two objects share the same address would be far less common than those where using the same storage for constant objects holding the same data would be advantageous.
Being able to invite an implementation to make optimizations which would not be allowable by the Standard is useful, if one recognizes that programs should not be expected to be compatible with all optimizations, nor vice versa, and if compiler writers do a good job of documenting what kinds of programs different optimizations are compatible with and letting compiler writers enable only optimizations that are known to be compatible with their code.
Fundamentally, optimizations that assume programs won't do X will be useful for applications that don't involve doing X, but at best counter-productive for those that do. The described optimizations would fall into this category. I wouldn't see any basis for complaining about a compiler that makes such optimizations available but doesn't enable them by default. On the other hand, some people believe any program that isn't compatible with any imaginable optimization as "broken".

application of get_user when there is copy_from_user

In Linux kernel programming, I see get_user and copy_from_user perform read from user space, earlier one reads fixed 1, 2 or 4 bytes while latter reads arbitrary number of bytes from user space. What was the need of get_user? Did copy_from_user come after get_user and hence get_user was kept for backward compatibility? Are there specific applications of get_user or is it obsolete now? Same queries for put_user and copy_to_user.
You can think about
copy_from_user(dest, src, size);
as some sort of
memcpy(dest, src, size);
and about
get_user(x, ptr);
as some sort of simple assignment:
x = *ptr;
Like a simple assignment is a cleaner(for code undestanding), shorter and faster way than a memcpy() function call, get_user is a cleaner, shorter and faster way than a copy_from_user.
The mostly known case, when the size of the data is constant and small(so get_user is applicable), is an ioctl implementation for devices. You can find many get_user usages by grep-ing kernel sources for get_user, or using online kernel code search service like Linux Cross Reference.

What is the benefit of offsets to pointers?

I'm using a memory editing application known as Cheat Engine. I attach Cheat Engine to a game. In my game, I have a 32-bit integer known as HP. HP is stored at a memory address A. If I restart my game, HP is stored at a new memory address B. It seems that using Cheat Engine, I can do a pointer scan and find a static memory address, C, that points to another memory address and its accompanying offset, D and offset, so that [D + offset] always stores HP's memory address during that session. So if I dereference [D + offset], I always get the memory address that stores HP.
Here is a diagram:
A or B --> HP
D + offset --> A or B
C --> D
What is the benefit of using offsets? Why can't C just point to A or B directly? I'm familiar that using offsets are beneficial when dealing with arrays in the C language. Does that mean that whenever I see an offset to a pointer, the pointer is pointing to the first element in an array and the offset is referring to one of the elements in the array?
It should be easy to imagine and understand if you know the C programming language. Anything you write in C is very close to the actual machine code that gets generated when compiling the program.
The abstraction of an object in C is often done with a "struct".
In your example imagine a very simple "Player" struct:
struct Player {
int id;
float xposition;
float yposition;
int health;
int maxhealth;
};
If you want to create an object like this you could do something like this:
struct Player *myPlayer = malloc(sizeof(struct Player));
What is a nice looking structured thing in the high language is actually just a block of memory in a compiled program.
To access for example "health" you do myPlayer->health; in C. But now how does this look in a compiled program that doesnt know about the beatiful names and just has a block of memory to work with?
It has to work with offsets from the base pointer. In the above example (assuming windows operating system and any default configured sane compiler) an access in some pseudo machine code will look something like this:
move myHealth, read4bytes[myPlayer + 12]
If you reverse-engineer a progam, you can't tell from an offset-access whether the block of memory was a struct, a array, or maybe a class (from C++ code) or something entirely different.

What is a good way to deal with byte alignment and endianess when packing a struct?

My current design involves communication between an embedded system and PC, where I am always buzzed by the struct design.
The two systems have different endianess that I need to deal with. However, I find that I cannot just do a simple byte-order switch for every 4 bytes to solve the problem. It turns out to depend on the struct.
For example, a struct like this:
{
uint16_t a;
uint32_t b;
}
would result in padding between a and b. Eventually, the endian switch has to be specific to a and b because the existence of the padding bytes. But it looks ugly because I need to change the endian switch logic every time I change the struct content.
What is a good strategy to arrange elements in a struct when padding comes in? Should we try to rearrange the elements so that there is only padding bytes at the end of the struct?
Thanks.
I'm afraid you'll need to do some more platform-neutral serialization, since different architectures have different alignment requirements. I don't think there is a safe and generic way to do something like grabbing a chunk of memory and sending it to another architecture where you just place it at some address and read from it (the correct data). Just convert and send the elements one-by-one - you can push the values into a buffer, that will not have any padding and you'll know exactly what is where. Plus you decide which part will do the conversions (typically the PC has more resources to do that). As a bonus you can checksum/sign the communication to catch errors/tampering.
BTW, afaik while the compiler keeps the order of the variables intact, it theoretically can put some additional padding between them (e.g. for performance reasons), so it's not just an architecture related thing.

Size reduction for enum storage in Fujitsu Softune

Fujitsu microcontroller used is 32bit.
Hence enum storage is also 32bit. But in my project actually enum elements do not exceed more than 256.
Is there any compiler options to size down the storage for enums?
You could use a bit field to be able to store 256 unique values in 8 words (256 bits / 32 bit words = 8), but then the compiler will no longer be able to enforce that only a single bit is set at a time. But, you could easily write a wrapper function to clear out all the previous bits before setting one. It would probably end up kind of messy, but that's what tends to happen when you start using these kinds of tricks at this level to save memory.
You could use preprocessor macros (#define) to map symbolic names to values. without knowing what your application is, it's hard to predict if this is sensible :)

Resources