How can I get a protocol working under GNU-EFI? - c

I use GNU-EFI to develop UEFI apps. I have some trouble getting a protocol (EFI_SHELL_PROTOCOL) working under GNU-EFI. My compiler says that it is undefined. Should I include something? I already included efi.h and efilib.h. Do I need more?
Code that I tried:
EFI_SHELL_PROTOCOL shell;
The error that I got:
error: unknown type name ‘EFI_SHELL_PROTOCOL’; did you mean ‘EFI_OPEN_PROTOCOL’?
161 | EFI_SHELL_PROTOCOL shell;

The EFI_SHELL_PROTOCOL isn't part of the main UEFI interface, and is therefore not included in the main header files (e.g. efi.h) and not included in the main UEFI standard.
Instead, EFI_SHELL_PROTOCOL is just an optional extension (that may not exist, and I'd assume is only likely to exist when a shell is being used and provides it), with its own separate standard and its own separate header file.
Assuming you're using GNU's tools; the right files to include are probably efishellintf.h and efishellparm.h.

Currently, GNU-EFI does not support EFI_SHELL_PROTOCOL. It doesn't contain any related definitions about it.
If you want to use it with GNU-EFI, you can use this header file from edk2 (put it in inc folder, for example, inc/efishell.h). Then include this header file in inc/efi.h and add these lines:
lib/data.c:
EFI_GUID ShellProtocol = EFI_SHELL_PROTOCOL_GUID;
inc/efilib.h:
extern EFI_GUID ShellProtocol;
Rebuild your GNU-EFI and now you can use EFI_SHELL_PROTOCOL by locating it first.
EFI_SHELL_PROTOCOL *SP;
uefi_call_wrapper(BS->LocateProtocol, 3, &ShellProtocol, NULL, &SP);

The EFI_SHELL_PROTOCOL is fully documented in the UEFI Shell Specification (currently v2.2) which can be downloaded at https://uefi.org/specifications
GNU EFI does not currently implement EFI_SHELL_PROTOCOL or, indeed, all of the current UEFI Specification. For a reference implementation of the UEFI Shell Specification look at the EDK11 ShellPkg source code.

Related

What does the "MODULE_INFO(retpoline, "Y")" macro?

I see in some driver source code the line:
MODULE_INFO(retpoline, "Y")
What is does?
This macro defines key-value pairs that are stored in the compiled module files. You can use the modinfo command to display them. For example, when you compile this module, modinfo my_module.ko will include a line
retpoline: Y
You can find the definition of the macro and its documentation (such as it is) by searching on an LXR interface. It works by defining a symbol in the .modinfo section of the object file.
This mechanism is used for various metadata used by the module loaded in the kernel and by userland tools such as modprobe. Standard metadata include aliases, license, version, etc.
The retpoline tag indicates that the module is built with support for a mitigation against Spectre. I don't know why driver source code would declare this explicitly: as far as I understand, this should automatically be inserted (via a header) when compiling with retpoline support: this is a compiler feature, not a property of the source code.

Importing Modules — customized Modules in C

I am currently learning the C programming language and I'm having some issues with importing modules I created.
I created a small module to read with fgets and flush the buffer from stdin perfectly and I don't want to keep writing the code every single time. I just want to import this small module like I used to do in Python. I didn't knew how because I'm not using an IDE. I'm just compiling with gcc in terminal and using a text editor. I tried to search with Google,but in vain.
You should create a header for your module that declares the functions in the module – and any other information that a consumer of the module needs. You might call that header weekly.h, a pun on your name, but you can choose any name you like within reason.
You should create a library (shared or static — that's up to you) that contains the functions (and any global variables, if you're so gauche as to have any) defined by your module. You might call it libweekly.so or libweekly.a — or using the extensions appropriate to your machine (.dylib and .a on macOS, for example). The source files might or might not be weekly.c — if there's more than one function, you'll probably have multiple source files, so they won't all be weekly.c. You should put this code (the header and the source files and their makefile) into a separate source directory.
You should install the header(s) and the library in a well-known location (e.g. $HOME/include for headers and $HOME/lib for the library — or maybe in the corresponding directories under /usr/local), and then ensure that the right options are used when compiling (-I$HOME/include for the headers) or linking (-L$HOME/lib and -lweekly).
Your source code using the module would contain:
#include "weekly.h"
and your code would be available. With shared libraries in $HOME/lib, you would have to ensure that the runtime system knows where to find the library. If you install it in /usr/local, that is done for you already. If you install it in $HOME/lib, you have to investigate things like /etc/ld.so.conf or the LD_LIBRARY_PATH or DYLIB_LIBRARY_PATH environment variables, etc.
You need to create a header file (.h) with your function declarations types and extern variables. Then in the program where you want to use those functions include this .h file and and add the compiled .o file (with your functions) to the object file list. And you are done.

How to find out functions missing from a library, but which are present in the exposed header file released along with the library?

We have a legacy library implementation and associated exposed header files. Recently we found that, some of the functions in the exposed header file, don't have corresponding definitions in the library implementation.
We want to check if there could be some more such functions. Is there any easier way of doing this rather than sifting through each and every API present in header and then checking if there is a definition for it?
You can generate C source from the header (Perl is a way to go!) that calls all the functions and try to compile it. Linker will complain about missing functions.
Try to create the ABI dump file by the abi-compliance-checker tool:
abi-compliance-checker -lib NAME -dump DESC.xml
DESC.xml file is the following:
<version>
1.0
</version>
<headers>
/path(s)/to/headers
</headers>
<libs>
/path(s)/to/libraries
</libs>
The resulting ABI dump file will contain the information you need about symbols declared in header files (SymbolInfo) and symbols exported by shared libraries (Symbols).
You can also generate ABI dump in the xml format by adding --xml option.
If this is C, you can do something like:
printf("", /* insert all functions here */);
That should pass them all as function pointers to printf. The ones that do not exist should show up as linker errors.
(In C++, you would have to list overloads explicitly, which makes it a bit more difficult.)
I'd be inclined to use ctags to generate a list of identifiers from the header file then use ar, emfar or elfdump in Unix or lib.exe or dumpbin.exe in Windows (see discussion here) to dump a list of identifiers from the library and then sort and diff the two lists.

Get file extension in C

Is there a C library function to get the extension of file? I know that I can design a function on my own to get extension after '.' but not all files are stored with their extensions when we read them.
So you'd like to get the type of a file? Maybe the command 'file' in Linux is what you want. You can check its source code.
The file command in Linux uses a library called libmagic (don't confuse with libmagick) to check the 'magic' bytes in the file itself to determine the likely content type.
The library is fairly cross platform, it's well documented, for example here:
http://linux.die.net/man/3/libmagic

Using List.h in C files, Ubuntu10.10

I am running Ubuntu 10.10 on an IBM R51 machine. When I access list.h to read it(manually/humanly) I open /usr/src/linux-headers-2.6.35-22/include/linux .
But when coding a C program in terminal, I cant invoke any #include because it is not in the default /usr/include folders.
When I change the statement to reflect the path by typing #include "/usr/src/linux-headers-2.6.35-22/include/linux/list.h" it returns errors as list.h in turn calls other header files which are mentioned as located in "linux" folder
The header files are as you must be aware:
"linux/poison.h", "linux/prefetch.h" and "asm/system.h"
So if I have to copy each, I can but prefetch in turn calls other dependencies, which are not present in /usr/include directory. I hope you understand.
How can I solve this problem?
Are you sure these headers are really what you need ? The standard C headers should be under /usr/include
Anyhow you need to pass the header search path to the compiler via the '-I' flag.
Pass the path via -I
-I/usr/src/linux-headers-2.6.35-22/include/linux
Then in your C code
#include "list.h"
Link to GCC manual & preprocessor directives
The header files you are using are designed for internal use of the Linux kernel. They were not designed to be used by a userland program.
If you MUST use these headers (the Linux kernel list implementation is brilliant), copy the headers into your program source directory. Copy each file that is referenced, edit each one to remove whatever assumptions exist about being used in-kernel, and recurse until you're finished. I might suggest to make your own prefetch() macro that simply does nothing, rather than try to untangle <linux/prefetch.h>. Do the same for <linux/poison.h>, and untangle <linux/types> and <linux/stddef.h> (not too hard here :) as best you can.
And also be sure you license your project GPLv2 (and specifically GPLv2, the Linux kernel's COPYING file is quite strict that GPLv2 is the only license that applies; there is debate whether the GPL allows specifying only one version, but that is the license Linus chose ages ago, and the license that is valid on all files unless specified otherwise).
adding -I/usr/src/linux is a no-go, since unsanitized header files are not meant to be used from user programs
you could manually copy list.h to your own project and sanitize
or use a library that is specifically for userspace and provides the same functionality (since you already used libHX elsewhere, you might want to continue reading into the linked list chapter)

Resources