I know there's EXPORT_SYMBOL for kernel modules to expose it's global variables statically.
My question is:
Is it possible to EXPORT_SYMBOL at runtime?
I'm developing a kernel driver for multiple IC modules.
There's a global struct list "A" for each IC modules(ko) to add their own IC detection function. And there will be an action to trigger the scanning of "A".
The design is, there is ko(s) for each IC and a main ko for main functions.
For example, there's m1.ko, m2.ko and mm.ko.
I'll insmod m1.ko (create "A" and add it's own detect function),
insmod m2.ko (check "A" existence, if exist, add it's own, if not create "A" and add) and insmod mm.ko (check "A" existence, if exist, trigger the scanning of "A", else do nothing).
I can check kernel symbol "A" by kallsym_lookup_name, but when I came to create "A" if not exist, I can't find a function to add kernel symbol dynamically.
Is there a method to add kernel symbol at runtime correctly? Or there's an alternative way to achieve the goal?
Related
I have multiple boards which were having different screen sizes(4",7",12" etc...). I need this info at multiple places in the Linux Kernel during boot time. We can know the device screen size by reading values on two input lines. I don't want to read every time these lines whenever I want to know the device screen size. I want to read these lines once at the beginning(maybe in the board file) and store it in a global variable. Check this global variable value where ever I need the screen size. Can anyone suggest where I can declare this global variable or any better way for this?
So you've given some thought to your problem and you think a "global" variable in the Linux kernel is the fastest/best solution. Where a "global" variable is a variable that one module defines and initializes and other modules can also read and modify it. You can do that by exporting the symbol with the EXPORT_SYMBOL macro.
As an example, look at this file on lines 54 and 55 the symbol drm_debug is declared as an unsigned int and exported for other driver modules to use. The other modules need to be informed about that symbol's existance before they can use it. In this case, that happens in this header file on line 781. So when another file or module wants to use that symbol, that source file includes the header, and then it just uses the variable as if it were declared in that file. If you don't want to create a header file for your "personal" global variables, you can just add that "extern" as a 1-liner to your global scope declarations for that source code file, and it will have the same effect.
In addition to exporting variables, you can also export functions in the same fashion. If you grep for "EXPORT_SYMBOL" in your kernel most of the hits are going to be functions. When you pass around a variable there is the chance that one module might change it at an inopportune moment when another module might be reading it causing undesired outcomes. I like to think of the function as a "read only" version of a variable, so only one module can change it, but everyone else can see it. Having one module being "responsible" for reading and interpreting the GPIO and then sharing that information with other modules to me seems to fit better with the exported function than with the exported variable.
Lastly, whenever you start sharing symbols in the kernel, you should give thought to the name of the global variable you choose. For example, don't take something that's already taken or likely to be taken.
I have an executable that runs ruby code(RGSS3, precisely) and I also managed to build a DLL that included ruby.h and it's imported to the exe via LoadLibraryA.
I want to ask whether it is possible to share the object/memory between the exe and the dll? If yes, what should I do to make dll access the objects created by the exe and vice versa?
Yes, it is possible.
Ruby objects are represented in C with VALUE, which is basically a pointer. It's a bit hacky to call those functions from RGSS3, though: you have to get the object's memory address (object.object_id << 1) and pass that to the function.
Take a look at this repository, specifically this file. It declares ands exports a function you can use from RPG Maker importing it with Win32API. Supposing you compile the test.c from that repository into test.dll:
# Load RGSS3 dll
LoadLibrary = Win32API.new("kernel32", "LoadLibraryA", "p")
rgss3_dll = LoadLibrary.call("RGSS301.dll")
# Call function from your dll
bitmap = Bitmap.new(32, 32)
BitmapTest = Win32API.new("test.dll", "BitmapTest", "ll")
p BitmapTest.call(rgss3_dll, bitmap.object_id << 1)
I have two Omnet++ projects A and B. A currently needs B. Is it possible to declare B as a feature of A somehow, so I can turn it on and off? I want to have the separate projects as B can be reused in other projects. I added a feature using a new .oppfeatures file in A and I added corresponding ifdef statements in the C++ code. Currently I struggle with the ned file:
import namespaceB.B;
network Network
{
parameters:
[...]
bool bDisabled = default(false);
submodules:
[...]
b: B if !bDisabled;
}
How can I conditionally import the ned file of B? If I use a wildcard for importing Omnet complains about "no such module type" in the submodule declaration. Is my idea to have an external project as feature possible at all? Any other idea how I can accomplish this (maybe a git submodule or something)?
Thanks!
Try to follow the pattern what INET is using with regards to the TCP implementations. INET has it's own TCP module (in the TCP_INET feature) and also two alternative implementation defined by the TCP_lwIP and TCP_NSC features. Take a look at the src/makefrags file to check the wizardry how to add compiler and linker flags based on the enablement of a particular feature. e.g.:
WITH_TCP_LWIP := $(shell (cd .. && ./bin/inet_featuretool -q isenabled TCP_lwIP && echo enabled) )
ifeq ($(WITH_TCP_LWIP), enabled)
INCLUDE_PATH += -Iinet/transportlayer/tcp_lwip/lwip/include -Iinet/transportlayer/tcp_lwip/lwip/include/ipv4 -Iinet/transportlayer/tcp_lw
endif
This code checks whether the TCP_lwIP feature is enabled and adds the necessary include paths. You can add also linker flags if you have to link with the external project. (you can add compiler and linker flags also in the oppfeatures file if you don't need anything complicated )
Now, how to deal with the optional NED types? Also take a look at how the TCP module is defined in the StandardHost:
tcp: <default(firstAvailable("Tcp", "TcpLwip", "TcpNsc"))> like ITcp
As the given module is optional, you always have to have "something" that could be used instead of it. At least a dummy module. Now the there is an ITcp interface module (that is always present) and all the different TCP implementations "implement" it. What you see here is that tcp is a module which looks like the ITcp module and during the build up, the actual implementation will be either Tcp, TcpLwip or TcpNsc in this particular order. Whichever is present actually in the ned type tree. By disabling a feature, we actually remove the given ned type from the ned path too (the feature excludes the given NED package that contains the implememtation).
from the OMNeT++ API (NED functions):
string firstAvailable(...)
Accepts any number of strings, interprets them as NED type names (qualified or unqualified), and returns the first one that exists and its C++ implementation class is also available. Throws an error if none of the types are available.
This NED function was specifically invented and added to OMNeT++ for these purposes (to scan for the presence of a given NED type)
I am not sure if I am phrasing the question correctly, but basically I want to know how the call instruction is generated when calling an imported function from another library.
For example
GetModuleFileName(...)
is compiled to
call 0x4D0000
where 0x4D0000 is the address of the imported function which is dynamic.
How does windows set those calls and would it be possible to circumvent it and set a custom address instead.
The address used in the call statement isn't dynamic. It's a relative address that's fixed at link time like a call to any other function. That's because the call is actually to a stub, and the stub performs an indirect jump to the real function. The indirect jump uses a memory operand that refers to location in the import table. When the executable (or DLL) is loaded by Windows it updates the import table with addresses of all the functions the executable or DLL uses in any DLLs it's linked to.
So if an executable a call instruction like this:
call _GetModuleFileNameA#12
Then somewhere else in the same executable is astub like this:
_GetModuleFileNameA#12:
jmp [__imp__GetModuleFileNameA#12]
And somewhere in the import table there is a definition like this:
__imp__GetModuleFileNameA#12:
DD ?
Windows sets the value of __imp_GetModuleFileName#12 in the import table when the executable (or DLL) is loaded. There's not much you can do change this, though it's not too hard to change the value after the executable (or DLL) has been loaded. Note that the import table might be located in a read-only section, meaning you may need to change the virtual memory protections in order to do this.
My main application statically links to a static library A with a function ABC and my dynamic library xyz.dylib also statically links to the same static library A which has the same function ABC. The function ABC uses a globally defined variable.
Now when the main application Loads xyz.dylib using dlopen on runtime. The initializer gets called where i have called ABC function. This function ABC and uses the global variable from main application address space.
On Osx, functions which are inline the dylib linker will use the first one that is used. So for example, if an inline function is used in your main executable first, and then used in the loaded dylib, it will use the one in the main executable.
This is normally fine, unless your inline makes reference to a global symbol, in which case you are now be using one if your globals for both the dylib, and your executable.
Again this is usually fine, since the same version is used consistently.
The problem happens when you have 2 inline functions that reference a global that is in both executable and dylib, and one function gets used first in the executable, and another one used first in the dylib. Then you have a mismatched pair. For example:
class MagicAlloc
{
void* Alloc() { return gAlloc.get(); }
void Free( void* v ) { gAlloc.free( v ); }
static RealAllocator gAlloc;
};
Suppose you call MagicAlloc::Alloc in the executable, then call it in the dylib, now for all allocations in both you will use the gAlloc in the executable. Then the first call to MagicAlloc::Free happens in the dylib. Then you will try to free something allocated in the binary on the globals from the dylib.
There are two solutions:
Don't use inlines to reference globals/statics. Move the global structure, and the function definitions into the same translation unit ( object file ). Mark the globals "static" so they aren't even visible outside the TLU. Now your functions will be resolved statically in the link step, and bound to the right global.
Hide all the symbols in the executable except the plugin api. Link as normal, but when linking the binary itself pass the following to the linker:
-Wl,-exported_symbols_list,export_file
Where export file is a list of link symbols that should be exported. E.g. you will need to at least have "_main" in that file. Now when your dylib runs it won't be able to dynamically link to the wrong inlines, because they won't be in the dynamic symbol table. The second solution is also more secure, since a malicious plugin won't be able to access globals as easily.