function declaration in core.c - c

I found this declaration in kernel/sched/core.c and I do not understand what does this specify.
static void __sched __schedule(void)
Any help appreciated.
[EDIT] kernel version 3.5.4

__sched is actually a macro defined as __attribute__((__section__(".sched.text"))) in include/linux/sched.h. This attribute is picked up by the GCC compiler:
Normally, the compiler places the objects it generates in sections
like data and bss. Sometimes, however, you need additional sections,
or you need certain particular variables to appear in special
sections, for example to map to special hardware. The section
attribute specifies that a variable (or function) lives in a
particular section.

Related

Gcc Force global variable to a given address using linker only

I'm trying to force a global variable to a specific address without modifying the source code.
I'm well aware of solution such as:
// C source code
MyStruct globalVariable __attribute__((section(".myLinkerSection")));
// Linker script
. = 0x400000;
.myLinkerSection:
{
*(.myLinkerSection)
}
But in my case I would like to do the same thing without the __attribute__((section(".myLinkerSection"))) keyword.
Is it doable ?
EDIT:
I cannot modify the source code at all.
The variable is defined as follow:
file.h:
extern MyStruct globalVariable;
file.c:
MyStruct globalVariable;
I assume from the mentions of __attribute__ that you are using gcc / clang or something compatible. You can use the -fdata-sections option to make the compiler put every variable into its own section. With that option, your globalVariable, assuming it would otherwise go in .bss, will be placed in a section called .bss.globalVariable (the exact name might be platform-dependent). Then you can use your linker script to place this section at the desired address.
Note that this option will inhibit certain compiler optimizations. There is a guarantee that objects defined in the same section within the same assembler module are assembled in strict order, and that their addresses do not change after that. In some cases the compiler can take advantage of this; e.g. if it defines int variables foo and bar consecutively in the same section, then it knows their addresses are consecutive, and it can safely generate code that "hardcodes" their relative position. For instance, on some platforms such as ARM64, it takes multiple instructions to materialize the address of a global or static object. So if some function accesses both foo and bar, the compiler can materialize the address of foo, then add the fixed constant 4 to get the address of bar. But if foo and bar are in different sections, this can't be done, and you will pay the (small but nonzero) cost of materializing both addresses separately.
As such, you may want to use -fdata-sections only on the particular source files that define the particular variables of concern.
This also illustrates why you have to get the variable in its own section in order to set its address; you can't move just one variable from a section, since the compiler may have been relying on its relative position to some other variable in that section.
You can define this variable in a separate translation unit. Then list its object file in the appropriate section.

Why is a function defined in a .h file redefined in a .c file?

I am reading through Linux v3.19's implementation of PID namespaces and in pid_namespace.h there are functions defined that are redefined in pid_namespace.c. For example, in pid_namespace.h there is the following definition:
static inline struct pid_namespace *copy_pid_ns(unsigned long flags,
struct user_namespace *user_ns, struct pid_namespace *ns)
{
if (flags & CLONE_NEWPID)
ns = ERR_PTR(-EINVAL);
return ns;
}
And then in pid_namespace.c there is a second copy_pid_ns definition:
struct pid_namespace *copy_pid_ns(unsigned long flags,
struct user_namespace *user_ns, struct pid_namespace *old_ns)
{
if (!(flags & CLONE_NEWPID))
return get_pid_ns(old_ns);
if (task_active_pid_ns(current) != old_ns)
return ERR_PTR(-EINVAL);
return create_pid_namespace(user_ns, old_ns);
}
What does this re-defining achieve? Why is it done? Thanks for your help!
These two definitions corresponds to two incompatible configurations:
Definition of copy_pid_ns in the include/linux/pid_namespace.h#L76 header is parsed only with CONFIG_PID_NS option disabled (see line 68 in that header).
The file kernel/pid_namespace.c is compiled only with CONFIG_PID_NS option enabled (it can be found from kernel/Makefile). For that configuration the header contains just a declaration of the function at line 62.
Situation when the header file declares some function twice is quite natural for the Linux kernel sources:
One declaration (without definition) corresponds to some functionality being enabled. In that configuration the function is defined in some source file which is compiled only with functionality being enabled.
Another declaration is a definition of static inline function and corresponds to disabled functionality.
Note
The question omits relevant information from the source code repository it extracted the source code from, so the answer below does not apply to the source code in those files. It appears at most one of the two definitions is selected based on build options, so they are not both used in the same build.
Old Answer Regarding static inline
The version in the header is marked static inline. In this declaration, static causes the name copy_pid_ns to have internal linkage, meaning the definition here will apply only to uses of copy_pid_ns in the current translation unit (the source file being compiled, including the files it includes). The idea of inline is that this function is so small, it would be good if, wherever it is called, the compiler just wrote the code for it in place of the call instead of actually using a subroutine call instruction for the function. (Technically inline is just a suggestion to the compiler in this regard. Good modern compilers mostly make their own decisions about which functions to inline.)
Because the definition in the header is static inline, it is not accessible to other translation units. The definition in the other source file has external linkage, meaning any uses of copy_pid_ns in other translation units can be linked to it (if they do not have their own private static version). Those uses in other translation units will have to use actual subroutine call instructions to call this function.
Providing an external version is not necessary if all uses of copy_pid_ns have the static version available, but one may be provided because that is not always the case or just as a safety fallback.
First look at qualifiers in front of the function:
static inline... -> static will be resolved only in included source files (*.c, *.cpp)
like private qualifier, inline will replace directly this function instead accessing it as reference
have no qualifiers -> more like a public external function. If you define your usage of the function as extern you should compile (*.c) file which contains implementation of the function and then the linker will resolve your call to the function as reference.
It's not a redefinition. The key to realizing what's intended here is the presence of static qualifier for the first definition, and knowing how programs are built with C. Also, inline is seldom used without static, at least with C89 and GNU extensions which is what is used to compile Linux, but inline in and out of itself doesn't play a role here.
The static inline definition in pid_namespace.h is only visible to the translation unit (.c file) that includes that header file, directly or indirectly. The static qualifier is what restricts this visibility. If you include pid_namespace.h from another translation unit, that translation unit will have its own, another copy of the function. Each object file will have its own copy of the function definition, available only to itself. Additionally, because of the inline qualifier, the function may not even exist as such because the compiler is free to "inline" it.
The second definition does not have a static qualifier and can thus be used by other translation units that do not themselves contain it. The C compiler compiles object files from their respective translation units, and the linker links these object files together and produces a program image where references to said definition are correctly resolved. The compiler does not care if more than one translation unit embed the same function -- to it they're just object files it needs to compile one by one. But the linker will abort because it isn't designed to have to choose between such multiple definitions in its input.
In practice, there is many ways this can be used. The former definition may be the short version used in kernel mode (privileged kernel code), while the latter is used in user mode, as result of processing a system call, for example.
In general, defining procedures several times is permitted as long as there is at most one object available to the linker (in case it needs to resolve references to the function, like function calls). You can juggle your .c and .h files however you like, as long as that requirement holds. If you also know how to use static and inline qualifiers, you can add definitions that are not externally visible (static) and benefit from compiler being able to inline them.

Variable defined but not used message in kernel module

In my Kernel module, I have two very short C source files (the main file and a daq.c and daq.h file). The header file contains a number of variables and functions. When I compile the functions normally, by declaring the variable in the daq.h file:
volatile uint32_t *gpio;
I receive the following error:
error In function `.LANCHOR1':
daq.c:(.bss+0x50): multiple definition of `gpio'
This error is only solved by declaring the variable as static, as follows:
static volatile uint32_t *gpio;
The kernel module works fine but in this case I receive the following warning as a static declaration creates a separated copy on every file in which it is included:
warning: ‘gpio’ defined but not used [-Wunused-variable]: static volatile uint32_t *gpio;
I've tried to declare it extern or just simply declaring the variable as uint32_t *gpio instead of declaring it static but then I get a:
WARNING: "gpio" undefined!
followed by an "out-of-tree definition" message in the dmesg log when the module is inserted (and the module is not loaded).
So, in this case, how is the best way to proceed in order to declare the variable? Is it correct to declare it as:
static volatile uint32_t *gpio;
and just omit the "defined but not used" warning given by the compiler? I don't think just "omitting" the warnings is a good practice, especially when it comes to kernel modules.
Thanks in advance.
Your question is not very clear because a full context is missing; but anyway I think some advice can be given.
First, your sources will be used together with other files; those files define things you have to be aware of, otherwise things like multiple definition of 'gpio' come out. In this case (gpio), you must decide if you want to interact with the "other" gpio variable - if not, you must use another name (it is not mandatory, but it is better).
Second, you must understand how the C compiler works, especially if you interface with the kernel, which adds some mechanisms. In general, you don't want to define variables in a header (.h) file; instead, you do declare them, together with data types, macros, and function prototypes. In the source files (.c) you #include headers in order to use the declarations found in them.
Variables are defined in .c files, and made available to other modules through header files, if this is wanted. Otherwise, make them static and do not mention them in the header.
The difference between declaration and definition is this: a declaration tells the compiler "you will encounter (perhaps) this name, somewhere, which has the following properties"; a definition instead means "I create this name, with these properties, and this thing is exactly here.".
When more than a single piece of software are used together, often happens that one piece does something needed in another one... declaration are the way to let these pieces work together.
Hope this helps a little.

Why won't C compile if two separate source files in the same workspace share function names?

I'm using eclipse indigo, gcc and cdt in a project. If two functions in separate source files share names (regardless of return type or parameters), eclipse flags a redefinition error. This isn't a huge issue regarding this project given I can easily rename these functions, and I'm well aware of wrappers if it were. Although this isn't a critical issue, it does make me think I'm not understanding the c build process. What occurs during the build process in which a program structure like this would cause issue?
Here's some more info. on the situation, and where my understanding is so far -- not necessary to answer the question, although there must be a hole in my understanding.
In this case, the two functions are intended to be used only locally, as such their prototypes are not given in the .h interface, and for the sake of my point, neither are defined 'static'.
Neither of these source files are being included anywhere in the project, so they shouldn't be sharing any compilation units. With that in consideration, I would have assumed that the neither source file is aware of the presence of the other, and the compiler would have no problem indexing the two functions, as the separate files would allow for proper distinguishing between the two during linking -- so long as they weren't included in the same compilation unit.
I noticed that statically defining either instance of the function declaration removes the error. I remember reading at some point that every function not declared static is global -- although given these functions are not a part of the .h interface, the practical example in which including the .h interface doesn't allow for the including program to reference all .c functions would indicate "hiding" these functions would be of no issue.
What am I overlooking?
Some insight would be greatly appreciated, thanks!
This is the concept of "linkage". Every function and variable in C has a linkage type, one of "external", "internal", and "none". (Only variables can have no linkage.)
Functions have external linkage by default, which means that they can be called by name from any compilation unit (where "compilation unit" roughly means one source file and all the headers it includes). This can be expressed explicitly by declaring them extern, or it can be overridden by declaring them static. Functions declared static have internal linkage, meaning they can be referenced by name only from other functions in the same compilation unit.
No two external functions anywhere in the same program can have the same name, regardless of header files, but static functions in different compilation units may have the same name. A static function may have the same name as an external function, too -- then the name resolves to the static function within its compilation unit, and to the external function elsewhere. These restrictions make sense, for otherwise it would be possible for a function call to be ambiguous.
Header files don't factor into the linkage equation at all. They are primarily a vehicle for sharing declarations, but a function's linkage depends only on how it is declared, not on where.
I leave discussion of variables' linkage for another time.
It doesn't matter whether one source module includes headers for another. Header files only contain declarations for the purpose of local functions being able to find functions in other modules. It doesn't mean that functions not declared don't exist from the perspective of that module.
When everything gets linked together, anything not specifically defined to be local to one source module (i.e. static) has to have a unique name across all linked components.
remember reading at some point that every function not declared static is global
Having understood this you got the main point and reason for the behaviour observed.
.h files are not known to the linker, after pre-processing there are only translation units left (typically a .c file with all includes merged in), from which .o files are compiled.
There are no interfaces on language level in C.
Neither of these source files are being included anywhere in the project, so they shouldn't be sharing any compilation units.
Declare those functions as static. This is the only way to "hide" a function from the linker "inside" a translation unit.
C doesn't "mangle" function names the way C++ or Java do (since C doesn't support function polymorphism).
For example, in C++, the functions
void foo( void );
void foo( int x );
void foo( int x, double y );
have their names "mangled" into the unique symbols1
_Z3fooid
_Z3fooi
_Z3foov
which is how overloaded function/method calls are disambiguated at the machine level.
C doesn't do that; instead, the linker sees two different function definitions using the same symbol and yaks because it has no way to disambiguate the two.
1. This is what happens on my system, anyway

How is scope of variable implemented in compiler at machine level or memory level

How is scope of a variable is implemented by compilers?
I mean, when we say static variable, the scope is limited to the block or functions that defined in the same file where the static variable is defined?
How is this achieved in machine level or at memory level?
How actually is this restriction achieved?
How is this scoping resolved at program run time?
It is not achieved at all at the machine level. The compiler checks for scopes before machine code is actually generated. The rules of C are implemented by the compiler, not by the machine. The compiler must check those rules, the machine does not and cannot.
A very simplistic explanation of how the compiler checks this:
Whenever a scope is introduced, the compiler gives it a name and puts it in a structure (a tree) that makes it easy to determine the position of that scope in relation to other scopes, and it is marked as being the current scope. When a variable is declared, its assigned to the current scope. When accessing a variable, it is looked for in the current scope. If not found, the tree is looked up to find the scope above the current one. This continues until we reach the topmost scope. If the variable is still not found, then we have a scope violation.
inside compilers, its implementation defined. For example if I were writing a compiler, I would use a tree to define 'scope' and it would definitely be a symbol table inside a binary tree.
Some would use an arbitrary depth Hash table. Its all implementation defined.
I'm not 100% sure I understand what you are asking, but if you mean "how are static variables and functions stored in the final program", that is implementation-defined.
That said, a common way of storing such variables and functions is in the same place as any other global symbols (and some non-global ones) -- the difference is that these are not "exported", and thus not visible in any outside code trying to link to our software.
In other words, a program which has the following in it:
int var;
static int svar;
int func() { static int func_static; ... }
static int sfunc() { ... }
... might have the following layout in memory (let's say our data starts at 0xF000 and functions at 0xFF00):
0xF000: var
0xF004: svar
0xF008: func.func_static
...
0xFF00: func's data
0xFF40: sfunc's data /* assuming we needed 0x40 bytes for `func`! */
The list of exports, however, would only contain the non-static symbols, aka the exported ones:
var v 0xF000
func f 0xFF00
Again -- note how, while the static data is still written into the files (it has to be stored somewhere!), it is not exported; in layman's terms, our program does not tell anyone that it contains svar, sfunc and similar.
In Unices, you can list the symbols that a library or a program exports with the nm tool: http://unixhelp.ed.ac.uk/CGI/man-cgi?nm ; there do exist similar tools for Windows (GnuWin32 might have something similar).
In practice, executable code is often stored separately from the data (so that it can be protected from writes, for example), and it both may get reordered to minimize memory use and cache misses, but the idea remains the same.
Of course, optimizations can be applied -- for example, a static function could be inlined in its every invokation, meaning that no code is generated for the function itself at all, and thus it does not exist on its own anywhere.

Resources