error in kernel source code of linux? - c

I modified the kernel source code r8169.c and calculating the timestamp as below:
s64 a;
EXPORT_SYMBOL(a);
a = time();
I did not add the original timestamp function call
I am using the variable a in another source file in kernel: ip_input.c
extern s64 a;
s64 b,c;
b= time();
c = b-a;
I receive this error:
ERROR: undefined reference to a
How to solve it?

From the incomplete source code, I guess that
s64 a;
EXPORT_SYMBOL(a);
a = time();
is inside a function and therefore, a cannot be exported, because it is local to that function.
To use a outside of this module, you must define it with file scope, e.g.
s64 a;
EXPORT_SYMBOL(a);
void some_function()
{
a = time();
}
This allows the symbol for a to be exported and then used in another module.

r8169.c is a module, whereas ip_input.c is in the main kernel. The main kernel cannot import symbols from a module. The fix for this is to declare your variable within ip_input.c, and import it from r8169.c. You also have to use file scope as Olaf mentioned.
ip_input.c:
s64 a, b, c;
EXPORT_SYMBOL(a);
void someFunc() {
b=time();
c=b-a;
}
r8169.c:
extern s64 a;
void someFunc() {
a=time();
}

Related

Calling C function pointer as callback from Go code

I try to call a C function pointer as a callback from a Go function but get a linker error I don't understand.
package main
/*
typedef void (*int_int)(int, int);
void bridge_int_int(int a, int b, int_int f){
f(a, b);
}
*/
import "C"
//export IntIntCallback
func IntIntCallback(a, b C.int, cb C.int_int) {
C.bridge_int_int(a, b, cb)
}
func main() {
// Noop, required to make CGO happy: `-buildmode=c-*` requires exactly one
// main package, which in turn needs a `main` function`.
}
The error is:
c:/mingw32/bin/../lib/gcc/i686-w64-mingw32/11.2.0/../../../../i686-w64-mingw32/bin/ld.exe: $WORK\b001\_x002.o: in function `bridge_int_int':
./test.go:6: multiple definition of `bridge_int_int'; $WORK\b001\_x001.o:/tmp/test.go:6: first defined here
collect2.exe: error: ld returned 1 exit status
I don't understand where this multiple definition problem comes from.
Problem solved. See: https://pkg.go.dev/cmd/cgo#hdr-C_references_to_Go
Using //export in a file places a restriction on the preamble: since it is copied into two different C output files, it must not contain any definitions, only declarations. If a file contains both definitions and declarations, then the two output files will produce duplicate symbols and the linker will fail. To avoid this, definitions must be placed in preambles in other files, or in C source files.
Moving the following code into a separate .go file:
/*
typedef void (*int_int)(int, int);
void bridge_int_int(int a, int b, int_int f){
f(a, b);
}
*/
import "C"
and changing it to
/*
typedef void (*int_int)(int, int);
extern bridge_int_int(int a, int b, int_int f);
}
*/
import "C"
...
in the original file solved the problem

Call function of kernel module from another kernel module

I am new to kernel driver development. So I am just stuck in that. How can I call the function of the kernel module from another kernel module? These are both my .c files.
module1.c:
#include<linux/module.h>
#include<linux/kernel.h>
#include<linux/init.h>
int multiplication(int a, int b)
{
int ans=0;
ans = a * b;
printk(KERN_INFO"Returns the Multiplication to Module2!: %d\n", ans);
return ans;
}
module2.c:
#include<linux/module.h>
#include<linux/kernel.h>
#include<linux/init.h>
void calling()
{
int a=2,b=3;
int ans=0;
ans = multiplication(a,b) // function of module1.c.
printk(KERN_INFO"Multiplication recieved from Module1!: %d\n", ans);
}
I want to call the multiplication function in module2.c from module1.c. How can I do that?
To call a function defined in another kernel module you would have to export that function.
EXPORT_SYMBOL
EXPORT_SYMBOL() helps you provide APIs to other modules/code.
The functions which you EXPORT are available to the other modules/code.
Start with using the EXPORT_SYMBOL() function in module1.c after defining the function:
EXPORT_SYMBOL(multiplication);
Then you can declare the function as an external symbol using the extern keyword in module2.c:
extern int multiplcation(int, int);
Once you have built the modules, insert the module that is exporting the symbol and then insert the module that is importing the symbol. In this case, you would insert module1.ko and then module2.ko
There are some examples available at the "EXPORT_SYMBOL" hyperlink above

Inlined Setter and Getter functions in C

In C++ I can have a getter function declared inline in a header file:
class Cpp_Example
{
public:
unsigned int get_value(void)
{ return value;}
private:
unsigned int value;
};
By including this header file, client methods and functions can use the getter function to access a private variable.
I'm looking to model this concept in the C language:
hello.h:
#ifndef HELLO_H
#define HELLO_H
#include <stdio.h>
inline void Print_Hello(void)
{
extern const char hello_text[32];
puts(hello_text);
}
inline void Print_Value(void)
{
extern unsigned int value;
printf("Value is: %d\n", value);
}
#endif // HELLO_H
hello.c:
const char hello_text[32] = "Hello World!\n";
static unsigned int value = 5U;
main.c:
#include <stdio.h>
#include <stdlib.h>
#include "hello.h"
int main(void)
{
Print_Hello();
Print_Value();
// puts(hello_text);
return EXIT_SUCCESS;
}
I get a linker error from gcc:
$ gcc -o main.exe main.c hello.c
/tmp/cc41ZB8H.o:main.c:(.rdata$.refptr.value[.refptr.value]+0x0): undefined reference to `value'
collect2: error: ld returned 1 exit status
Is there a way to have an inline function (in a header file) access a static variable in another translation unit?
Or is there a way to implement an inlined getter function?
I'm using IAR Embedded Workbench, ARM7TDMI processor on an embedded platform.
The gcc compiler is used to testing concepts on the PC.
Edit 1: Background
I'm looking to optimize getter calls that are inside a critical section. The objective is to reduce the time spent in the critical section.
Edit 2: No Globals
The Coding Guidelines our shop uses states no global variables.
Also, this system is an RTOS running MicroCOSII.
First of all, the same way you have private variables in C++, you probably mean to have private variables for a struct rather than global. With that assumption, here's one model you can use:
/* some_type.h */
struct some_type
{
int public_data;
void *privates;
};
struct some_type_privates
{
char hello[32];
int value;
};
inline const char *get_hello(struct some_type *t)
{
struct some_type_privates *p = t->privates;
return p->hello;
}
inline int get_value(struct some_type *t)
{
struct some_type_privates *p = t->privates;
return p->value;
}
/* similarly for setters */
The same way that your private variables and their getters and setters are in the header file, you can do it in C, too.
On the side, I'd like to recommend not to try coding C++ in C. While C++ likes to complicate things a lot to prevent the idiot from breaking something, C on the other hand trusts the programmer has some degree of intelligence. Whether these assumptions are justified are not the matter of discussion. But what I mean to say is that the spirit of C is not to hide a variable so that the programmer doesn't mistakenly access it.
That said, this is how you would normally make a struct in C:
struct some_type
{
int public_data;
char hello[32]; /* read only */
/* internal */
int value;
};
(with enough documentation of course) which tells any programmer that she shouldn't write over hello but can freely read it (what you were trying to achieve by an inline getter). It also tells that value is private so the programmer shouldn't read or write it.
You can see this in many POSIX functions that take or return a struct. Some that don't need to control the access let you freely modify the struct, such as stat. Some that do need to check the input have setters, such as pthread_attr_*.
You need to remove the static keyword. static definitions are local to the compilation unit.
As Shabbas wrote, it doesn't really work that way in C.
The keyword inline implies static, even if the compilers doesn't actually inline it. If it is such a short function, it will probably inline it. But the point is, if it would not be static, it could not even consider inlineing it, as the function would need to be visible externally, it would need an address, which an inlined function doesn't have.
Since it is local in your compilation unit, it can only work on stuff known inside that compilation unit. Thus you need to say something about that value variable, much like you do need to mention it in the C++ header as well, only in C there is no such thing as private .
You can not have Inlineing and data hiding in the same case, neither in C, nor in C++.
Assuming you mean for global, statically-allocated variables you can do this:
In Example.h:
#ifndef Example
#define Example
extern int getValue();
#endif
In Example.c
#include "Example.h"
static int value;
inline int getValue() {
return value;
}
// All the functions in Example.c have read/write access
In UsesValueExample.c
#include "Example.h"
// All the functions in UsesValueExample.c have read-only access
void printValue() {
printf("value = %d", getValue());
}
If you want to get fancy and force all code to access through a getter and setter, e.g. if the variable is volatile and you want to heavily encourage all the methods to use a local cache of the variable to avoid the overhead of accessing the volatile, then:
In VolatileExample.h:
#ifndef VolatileExample
#define VolatileExample
extern int getValue();
#endif
In VolatileExample.c
#include "VolatileExample.h"
void setValue(); // Forward declaration to give write access
// All the functions in VolatileExample.c have read/write access via getters and setters
void addToValuesAndIncrementValue(int const values[], int const numValues) {
int value = getValue(); // Cache a local copy for fast access
// Do stuff with value
for (int i = 0; i < numValues; i++) {
values[i] += value;
}
value++;
// Write the cache out if it has changed
setValue(value);
}
// Put the definitions after the other functions so that direct access is denied
static volatile int value;
inline int getValue() {
return value;
}
inline void setValue(int const newValue) {
value = newValue;
}
In UsesVolatileValueExample.c
#include "VolatileExample.h"
// All the functions in UsesVolatileValueExample.c have read-only access
void printValue() {
printf("value = %d", getValue());
}
Here is a pattern I've been using to hide global variables.
Inside some header file, such as module_prefix.h, you declare the following:
typedef int value_t; // Type of the variable
static inline value_t get_name(void) __attribute__((always_inline));
static inline void set_name(value_t) __attribute__((always_inline));
static inline value_t get_name(void) {
extern value_t module_prefix_name;
return module_prefix_name;
}
static inline void set_name(value_t new_value) {
extern value_t module_prefix_name;
module_prefix_name = new_value;
}
/* Note that module_prefix_name is *no longer* in scope here. */
Then of course you have to define module_prefix_name in some compilation unit, without the static keyword, as discussed above, e.g. in module_prefix.c you have the following:
#include "module_prefix.h"
value_t module_prefix_name = MODULE_PREFIX_NAME_INIT_VALUE;
This is essentially the same pattern that Thomas Matthews tried to use, drilling down to the essence and making sure that the compiler inlines the functions always and does not unnecessarily generate explicit function bodies. Note the use of module_prefix as poor man's name spaces.

What's meaning of "EXPORT_SYMBOL" in Linux kernel code?

from here
48 struct snd_card *snd_cards[SNDRV_CARDS];
49 EXPORT_SYMBOL(snd_cards);
I am not getting whats the meaning of it and why that is used. I tried to search about it but not understanding the meaning of that.
It makes a symbol accessible to dynamically loaded modules (provided that said modules add an extern declaration).
Not long ago, someone asked how to use it.
Here is a good explanation.
https://www.quora.com/What-is-the-difference-between-extern-and-EXPORT_SYMBOL-in-Linux-kernel-codes
Extern is a C storage class keyword. In the kernel, as in any other C
code, it tells the compiler that the definition of the variable or
function it qualifies is implemented in another “file”, or rather,
more accurately Translation unit (programming) - Wikipedia. The
translation unit that does define it should not use the static
qualifier. Therefore, the symbol table has an entry corresponding to
it. At link time, the symbol is resolved as normal. There is nothing
kernel specific about “extern”.
EXPORT_SYMBOL() is a macro the Linux kernel headers define. It has not
much in common with extern. It tells the kbuild mechanism that the
symbol referred to should be part of the global list of kernel
symbols. That, in turn allows kernel modules to access them. Code that
is built into the kernel itself (as opposed to a module) can, of
course, access any non-static symbol via an extern declaration, in
accordance with regular C. The EXPORT_SYMBOL() mechanism allows us to
export a symbol for use by loadable modules as well. An interesting
thing is that a symbol thus exported by one module becomes accessible
to another module that may depend on it!
To summarise, extern is not kernel specific. It is used to qualify a
declaration to a non-static symbol from another translation unit.
EXPORT_SYMBOL() is specific to the Linux kernel. It is used in the
translation unit of the definition to make the symbol available to
loadable modules.
So EXPORT_SYMBOL is just a mechanism like extern, but it's for reference between loadable modules not file.
To move forwards, we can guess it's achived by the extern because extern is form C which is the foundation.
Here is a clue.
https://elixir.bootlin.com/linux/v4.6.7/source/include/linux/export.h#L56
#define EXPORT_SYMBOL(sym) \
__EXPORT_SYMBOL(sym, "")
/* For every exported symbol, place a struct in the __ksymtab section */
#define __EXPORT_SYMBOL(sym, sec) \
extern typeof(sym) sym; \
__CRC_SYMBOL(sym, sec) \
static const char __kstrtab_##sym[] __attribute__((section("__ksymtab_strings"), aligned(1))) = VMLINUX_SYMBOL_STR(sym); \
extern const struct kernel_symbol __ksymtab_##sym; \
__visible const struct kernel_symbol __ksymtab_##sym __used __attribute__((section("___ksymtab" sec "+" #sym), unused)) = { (unsigned long)&sym, __kstrtab_##sym }
First declare a extern sym.
Then a string __kstrtab_##sym = = VMLINUX_SYMBOL_STR(sym).
Last a extern struct kernel_symbol __ksymtab_##sym = { (unsigned long)&sym, __kstrtab_##sym }. &sym record the real address of the sym such as a function or variable, _kstrtab##sym record the name string.
Not an answer per se but a demonstration, as promised from my comment, that exported symbols are not required to be non-static. The below 2 modules demonstrate this:
/* mod1.c */
#include <linux/module.h>
static int mod1_exp_func(int i)
{
pr_info("%s:%d the value passed in is %d\n",
__func__, __LINE__, i);
return i;
}
EXPORT_SYMBOL(mod1_exp_func); /* export static symbol */
static int __init mod1_init(void)
{
pr_info("Initializing simple mod\n");
return 0;
}
static void __exit mod1_exit(void)
{
pr_info("This module is exiting\n");
}
module_init(mod1_init);
module_exit(mod1_exit);
MODULE_LICENSE("GPL v2");
And the second module
/* mod2.c */
#include <linux/module.h>
extern int mod1_exp_func(int);
static int __init mod2_init(void)
{
pr_info("Initializing mod2\n");
pr_info("Calling exported function in mod1\n");
mod1_exp_func(3);
return 0;
}
static void __exit mod2_exit(void)
{
pr_info("mod2 exiting\n");
}
module_init(mod2_init);
module_exit(mod2_exit);
MODULE_LICENSE("GPL v2");
These were tested on CentOS 6 & CentOS 7: kernels 2.6.32 and 3.10 (respectively). Loading mod1.ko and then mod2.ko will result in the value passed to mod1_exp_func() being printed to the kernel log buffers.

Hide struct definition in static library

I need to provide a C static library to the client and need to be able to make a struct definition unavailable. On top of that I need to be able to execute code before the main at library initialization using a global variable.
Here's my code:
private.h
#ifndef PRIVATE_H
#define PRIVATE_H
typedef struct TEST test;
#endif
private.c (this should end up in a static library)
#include "private.h"
#include <stdio.h>
struct TEST
{
TEST()
{
printf("Execute before main and have to be unavailable to the user.\n");
}
int a; // Can be modified by the user
int b; // Can be modified by the user
int c; // Can be modified by the user
} TEST;
main.c
test t;
int main( void )
{
t.a = 0;
t.b = 0;
t.c = 0;
return 0;
}
Obviously this code doesn't work... but show what I need to do... Anybody knows how to make this work? I google quite a bit but can't find an answer, any help would be greatly appreciated.
TIA!
If you're using gcc you can use the constructor attribute,
void runs_before_main(void) __attribute__((constructor))
{
...
}
From the gcc documentation
The constructor attribute causes the
function to be called automatically
be- fore execution enters main ().
Similarly, the destructor attribute
causes the function to be called
automatically after main () has
completed or exit () has been called.
Functions with these attributes are
useful for initializing data that will
be used implicitly during the
execution of the program.
You may provide an optional integer
priority to control the order in which
constructor and destructor functions
are run. A constructor with a smaller
priority number runs before a
constructor with a larger priority
number; the opposite relationship
holds for destructors. So, if you have
a constructor that allocates a
resource and a destructor that
deallocates the same resource, both
functions typically have the same
priority. The priorities for
constructor and destructor functions
are the same as those specified for
namespace-scope C++ objects
If you want to hide a struct from users, declare the struct in a header but define it in the c file, passing around pointers. As an example:
// foo.h
typedef struct private_foo foo;
foo * create_foo(void);
void free_foo(foo * f);
// foo.c
struct private_foo {
int i;
}
foo * create_foo(void){
foo * f = malloc(sizeof(*foo));
if (f) f->i = 1;
return f;
}
...
foo->i can then not be accessed outside foo.c.
If you want the client code to be able to use "t.a = ...", then you cannot hide the struct definition. What you want is called an opaque type, that will look something like this:
public.h:
struct foo;
set_a( struct foo *, int );
struct foo * new_foo(void);
main.c:
#include <public.h>
int main( void )
{
struct foo *k;
k = new_foo();
set_a( k, 5 );
}
The structure definition is only available to the library. If you do not make the library source code available, it is possible to completely hide it from the users of the library.
There is no portable way in C to ensure your code will run before main(). What I would do is just maintain an initialised flag in your library, set to false, and then refuse to do anything until your init function has been called.
As in:
static int initialised = 0;
int init (void) {
// do something.
initialised = 1;
return ERR_OK;
}
int all_other_functions (void) {
if (!init)
return ERR_NOT_INITED;
// do something.
return ERR_OK;
}

Resources