I use cscope in vim. I want to find the definition of struct platform_device. I try
: cs find g platform_device
But the result contains lots of other things. like:
variable named platform_device
declaration of struct platform_device
1 122 /work/pi/pi3_dev/linux-4.14/drivers/ata/pata_legacy.c <>
int (*setup)(struct platform_device *, struct legacy_probe *probe,
12 17 /work/pi/pi3_dev/linux-4.14/drivers/net/ethernet/qualcomm/emac/emac-sgmii.h <>
struct platform_device;
the definition is also included in the result, but it't very difficult to find it because the output is too long.
Can it let cscope find only the exact definition of struct platform_device
Related
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.
I'm running into some odd issue on kernel module load that I'm suspecting having to do with linking and loading. How to I programmatically figure out the address of each section after they are loaded in memory (from inside the module itself). Like where is .bss / .data / .text and so on.
From reading this article
https://lwn.net/Articles/90913/
It is sorta in the directly that I'm looking for.
You can see the sections begin addresses like this from userspace (need root permissions):
sudo cat /sys/module/<modulename>/sections/.text
I have browsed how syfs retrieves this addresses, and i found the following:
There is a section attributes in struct module
309 /* Section attributes */
310 struct module_sect_attrs *sect_attrs;
This attrs is a bunch of attr structs
1296 struct module_sect_attrs {
1297 struct attribute_group grp;
1298 unsigned int nsections;
1299 struct module_sect_attr attrs[0];
1300 };
where sect attr is the thing you are looking for
1290 struct module_sect_attr {
1291 struct module_attribute mattr;
1292 char *name;
1293 unsigned long address;
From the module's code THIS_MODULE macro is actually a pointer to the struct module object. Its module_init and module_core fields point to memory regions, where all module sections are loaded.
As I understand, sections division is inaccessible from the module code(struct load_info is dropped after module is loaded into memory). But having module's file you can easily deduce section's addresses after load:
module_init:
- init sections with code (.init.text)
- init sections with readonly data
- init sections with writable data
module_core:
- sections with code (.text)
- sections with readonly data
- sections with writable data
If several sections suit to one category, they are placed in the same order, as in the module's file.
Within module's code you can also print address of any its symbol, and after calculate start of the section, contained this symbol.
While this question is five years old, I thought I would contribute my two-cents. I was able to access the kernel's sections in a sort of hack-y way inspired by Alex Hoppus' answer. I don't advocate doing things this way, unless you are writing the kernel module to debug things or understand the kernel etc.
Anyway, I copy the following two structs into my module to help resolve incomplete types.
struct module_sect_attr {
struct module_attribute mattr;
char *name;
unsigned long address;
};
struct module_sect_attrs {
struct attribute_group grp;
unsigned int nsections;
struct module_sect_attr attrs[0];
};
Then, in my module initialization function, I do the following to get the section addresses.
unsigned long text = 0;
unsigned int nsections = 0;
unsigned int i;
struct module_sect_attr* sect_attr;
nsections = THIS_MODULE->sect_attrs->nsections;
sect_attr = THIS_MODULE->sect_attrs->attrs;
for (i = 0; i < nsections; i++) {
if (strcmp((sect_attr + i)->name, ".text") == 0)
text = (sect_attr + i)->address;
}
Finally, it should be noted that if you are looking for the address of .rodata, .bss, or .data you will need to define constant global variables, uninitialized global variables, or regular global variables, respectively, if you don't want those sections to be omitted.
In Linux kernel, structured types are defined like that:
typedef struct _TAG_ { ... };
and then used in routines like that:
struct _TAG_ structured_entity;
struct _TAG_ *pointer_to_structured_entity;
void function(struct _TAG_ *arg, ...);
Why not so:
typedef struct _TAG_ { ... } _typename_;
and then:
_typename_ structured_entity;
_typename_ *pointer_to_structured_entity;
void function(_typename_ *arg, ...);
What is the technical necessity to do so? Or is this simply tradition / style / magic?
The Linux kernel coding style - at kernel.org and in the Documentation directory that comes with the kernel - discourages using typedefs for structs:
Chapter 5: Typedefs
Please don't use things like "vps_t".
It's a _mistake_ to use typedef for structures and pointers. When you see a
vps_t a;
in the source, what does it mean?
In contrast, if it says
struct virtual_container *a;
you can actually tell what "a" is.
The document goes on to list cases where the author believes typedefs are useful - such as an opaque object that can only be accessed using accessor functions - concluding with:
In general, a pointer, or a struct that has elements that can reasonably
be directly accessed should _never_ be a typedef.
Where can I find the complete implementation/body of the following functions, defined as a function prototype in "include/linux/pci.h" in the Linux Kernel.
int pci_bus_read_config_byte (struct pci_bus *bus, unsigned int devfn, int where, u8 *val);
int pci_bus_write_config_byte (struct pci_bus *bus, unsigned int devfn, int where, u8 val);
I usually use free-electron's cross reference to find definitions of functions in the kernel. I've also used cscope to find the definitions of these functions but with no luck in both cases.
You can't find them using a "dumb" indexer/tagger because they are generated by macros here.
I am working on a C++ project on macOS X 10.6.2 with xcode.
I tried to compile my code on windows and do not have any problem, I guess Linux is working but I don't have one with me right now.
My problem is xcode do not accept this kind of instruction :
struct direction {
double x;
double y;
double z;
double t; };
typedef struct direction direction;
Here is my error :
/Users/sbarbier/dev/xcode/Infographie/TP9-RayTracing/RayTracing-Direction.h:22:0 /Users/sbarbier/dev/xcode/Infographie/TP9-RayTracing/RayTracing-Direction.h:22: error: changes meaning of 'direction' from 'typedef struct direction direction'
I am using GCC4.2 and haven't change anything. This code works on every platform, can any one help me ?
This isn't C. In C, to use a struct you had to use the keyword struct:
struct some_struct{ int i; };
struct some_struct myStruct;
This was alleviated like this, commonly:
typedef struct { int i; } some_struct;
some_struct myStruct;
In C++ this is not required. direction already has a type, then you're trying to make a new type of the same name, and that's bad. Take out your entire typedef, it isn't needed.
In C++, struct and class are used only when declaring or defining the struct or class. You might want the typedef in C, but in C++ it doesn't make any sense.