making global variables "hidden" and "aliased" - c

Is there any way to make a global variable both "hidden" and "aliased"? It would seem the following would be sufficient:
int __voo __attribute__((visibility("hidden")));
extern int voo __attribute__((weak,alias("__voo")));
But this results in:
$ gcc -c alias.c
/tmp/cczCek0H.s: Assembler messages:
/tmp/cczCek0H.s:5: Error: `voo' can't be equated to common symbol '__voo'
Removing "weak" has no effect.
However, adding "static" to the variable declaration allows the link to succeed, but is not the desired effect, as static limits the variable visibility scope to the compilation unit, not the broader scope of the linked object.
Intel System Studio 2019, GCC 4.8.5 and GCC 5.3.1 all show the same behavior.

I had a similar issue. I wasn't even trying to use hidden, and I still got the "can't be equated to common symbol" error. The fix was to initialize the int __voo to some value (even 0). Perhaps it was a BSS vs Data thing, or just a bug.

I got it to work by also supplying -fno-common to the compiler invocation. This might make some not strictly correct C code stop working though, so read what -fno-common does before using it.
It also works if I compile with clang.

Related

Resolve undefined reference by stripping unused code

Assume we have the following C code:
void undefined_reference(void);
void bad(void) {
undefined_reference();
}
int main(void) {}
In function bad we fall into the linker error undefined reference to 'undefined_reference', as expected. This function is not actually used anywhere in the code, though, and as such, for the execution of the program, this undefined reference doesn't matter.
Is it possible to compile this code successfully, such that bad simply gets removed as it is never called (similar to tree-shaking in JavaScript)?
This function is not actually used anywhere in the code!
You know that, I know that, but the compiler doesn't. It deals with one translation unit at a time. It cannot divine out that there are no other translation units.
But main doesn't call anything, so there cannot be other translation units!
There can be code that runs before and after main (in an implementation-defined manner).
OK what about the linker? It sees the whole program!
Not really. Code can be loaded dynamically at run time (also by code that the linker cannot see).
So neither the compiler nor linker even try to find unused function by default.
On some systems it is possible to instruct the compiler and the linker to try and garbage-collect unused code (and assume a whole-program view when doing so), but this is not usually the default mode of operation.
With gcc and gnu ld, you can use these options:
gcc -ffunction-sections -Wl,--gc-sections main.c -o main
Other systems may have different ways of doing this.
Many compilers (for example gcc) will compile and link it correctly if you
Enable optimizations
make function bad static. Otherwise, it will have external linkage.
https://godbolt.org/z/KrvfrYYdn
Another way is to add the stump version of this function (and pragma displaying warning)

GCC how to stop false positive warning implicit-function-declaration for functions in ROM?

I want to get rid of all implicit-function-declaration warnings in my codebase. But there is a problem because some functions are
programmed into the microcontroller ROM at the factory and during linking a linker script provides only the function address. These functions are called by code in the SDK.
During compilation gcc of course emits the warning implicit-function-declaration. How can I get rid of this warning?
To be clear I understand why the warning is there and what does it mean. But in this particular case the developers of SDK guarantee that the code will work with implicit rules (i.e. implicit function takes only ints and returns an int). So this warning is a false positive.
This is gnu-C-99 only, no c++.
Ideas:
Guess the argument types, write a prototype in a header and include that?
Tell gcc to treat such functions as false positive with some gcc attribute?
You can either create a prototype function in a header, or suppress the warnings with the following:
#pragma GCC diagnostic push
#pragma GCC diagnostic ignored "-Wimplicit-function-declaration"
/* line where GCC complains about implicit function declaration */
#pragma GCC diagnostic pop
Write a small program that generates a header file romfunctions.h from the linker script, with a line like this
int rom_function();
for each symbol defined by the ROM. Run this program from your Makefiles. Change all of the files that use these functions to include romfunctions.h. This way, if the linker script changes, you don't have to update the header file by hand.
Because most of my programming expertise was acquired by self-study, I intentionally have become somewhat anal about resolving non-fatal warnings, specifically to avoid picking up bad coding habits. But, this has revealed to me that such bad coding habits are quite common, even from formally trained programmers. In particular, for someone like me who is also anal about NOT using MS Windows, my self-study of so-called platform-independent code such as OpenGL and Vulkan has revealed a WORLD of bad coding habits, particularly as I examine code written assuming the student was using Visual Studio and a Windows C/C++ compiler.
Recently, I encountered NUMEROUS non-fatal warnings as I designed an Ubuntu Qt Console implementation of an online example of how to use SPIR-V shaders with OpenGL. I finally threw in the towel and added the following lines to my qmake .PRO file to get rid of the non-fatal-warnings (after, first, studying each one and convincing myself it could be safely ignored) :
QMAKE_CFLAGS += -Wno-implicit-function-declaration
-Wno-address-of-packed-member
[Completely written due to commends]
You are compiling the vendor SDK with your own code. This is not typically what you want to do.
What you do is you build their SDK files with gcc -c -Wno-implicit-function-declaration and and your own files with gcc -c or possibly gcc -o output all-your-c-files all-their-o-files.
C does not require that declarations be prototypes, so you can get rid of the problem (which should be a hard error, not a warning, since implicit declarations are not valid C) by using a non-prototype declaration, which requires only knowing the return type. For example:
int foo();
Since "implicit declarations" were historically treated as returning int, you can simply use int for all of them.
If you are using C program, use
#include <stdio.h>

GCC no reorder stack variables

Hi i'm trying to compile a C code without reordering my variables in stack but can't do it.
I've tryed using:
__attribute__((no_reorder))
But doesn't work, also tryed to compile with the flag:
-fno-toplevel-reorder
But didn't work... so i'm stuck.
Actual code:
uint8_t __attribute__((no_reorder)) first_buf[64];
uint8_t second_buf[32];
This is my compiler version:
gcc (Debian 7.2.0-19) 7.2.0
Thank you for reading!
from the gcc documentation here:
https://gcc.gnu.org/onlinedocs/gcc/Common-Function-Attributes.html
no_reorder
Do not reorder functions or variables marked no_reorder against each other or top level assembler statements the executable. The
actual order in the program will depend on the linker command line.
Static variables marked like this are also not removed. This has a
similar effect as the -fno-toplevel-reorder option, but only applies
to the marked symbols.
(emphasis mine)
So it would appear that you would need to apply the attribute to the variables the respective order of which you want preserved. Applying the attribute to only a single variable will only preserve the order of that variable with itsef, which has no effect.
-fno-stack-protector will do it. It will cancel stack canary and reordering of buffer on stack.
add that flag when you compile. i.e.
gcc myprogram.c -fno-stack-protector

C compiles with an undefined symbol

I am using an older version of the Diab C compiler.
In my code I have taken a function name and redefined it as a function pointer with the same signature. Before making this change the code worked. After the change it made it caused the embedded system to lock up.
The function pointer was declared extern in a header, defined in one .c file, and used in another .c file. When it was called from the second .c file it would cause the system to lock up. When I attempted to add debug information using sprintf it finally told me that it was an undefined symbol. I realized that the header file was was not included in the second .c file. When I #included it everything compiled and worked correctly.
My question is, is there some C rule that allowed the compiler to deduce the function signature even though the symbol was undefined at the call location? To my understanding there should have been an error long before I made any changes.
If no declaration is available, the compiler uses a default declaration of a function taking an unknown number of arguments and returning an int. If you turn up compiler warnings (eg -Wall -Wextra -Werror with gcc, check the documentation for your compiler), you should get a compile time warning.
Most likely, the code at first worked because it was compiled in the C89 or similar mode. The C standard from 1989 allows calling functions without first declaring them.
When you changed the code to use a pointer but didn't include the declaration of the pointer, the compiler assumed that your pointer was in fact a function and generated code to call into the pointer, as if the pointer had executable code inside. As the result, the program understandably stopped working.
What you should do is enable all possible warnings (for gcc: -Wall, -Wextra and make sure optimization is enabled (-O2 is good) because it enables code analysis), especially for calling functions without prototypes. A better thing might be to switch the compiler into the C99 mode (-std=c99 in gcc) or switch to a C99 compiler. The C standard from 1999 prohibits calling functions without prototypes and comes with some useful features absent in C89.

gcc - 2 versions, different treatment of inline functions

Recently I've come across a problem in my project. I normally compile it in gcc-4, but after trying to compile in gcc-3, I noticed a different treatment of inline functions. To illustrate this I've created a simple example:
main.c:
#include "header.h"
#include <stdio.h>
int main()
{
printf("f() %i\n", f());
return 0;
}
file.c:
#include "header.h"
int some_function()
{
return f();
}
header.h
inline int f()
{
return 2;
}
When I compile the code in gcc-3.4.6 with:
gcc main.c file.c -std=c99 -O2
I get linker error (multiple definition of f), the same if I remove the -O2 flag. I know the compiler does not have to inline anything if it doesn't want to, so I assumed it placed f in the object file instead of inlining it in case of both main.c and file.c, thus multiple definition error. Obviously I could fix this by making f static, then, in the worst case, having a few f's in the binary.
But I tried compiling this code in gcc-4.3.5 with:
gcc main.c file.c -std=c99 -O2
And everything worked fine, so I assumed the newer gcc inlined f in both cases and there was no function f in the binary at all (checked in gdb and I was right).
However, when I removed the -O2 flag, I got two undefined references to int f().
And here, I really don't understand what is happening. It seems like gcc assumed f would be inlined, so it didn't add it to the object file, but later (because there was no -O2) it decided to generate calls to these functions instead of inlining and that's where the linker error came from.
Now comes the question: how should I define and declare simple and small functions, which I want inline, so that they can be used throughout the project without the fear of problems in various compilers? And is making all of them static the right thing to do? Or maybe gcc-4 is broken and I should never have multiple definitions of inline functions in a few translation units unless they're static?
Yes, the behavior has been changed from gcc-4.3 onwards. The gcc inline doc (http://gcc.gnu.org/onlinedocs/gcc-4.1.2/gcc/Inline.html) details this.
Short story: plain inline only serves to tell gcc (in the old version anyway) to
inline calls to the from the same file scope. However, it does not tell gcc that
all callers would be from the file scope, thus gcc also keeps a linkable version
of f() around: which explains your duplicate symbols error above.
Gcc 4.3 changed this behavior to be compatible with c99.
And, to answer your specific question:
Now comes the question: how should I define and declare simple and small functions, which I want inline, so that they can be used throughout the project without the fear of problems in various compilers? And is making all of them static the right thing to do? Or maybe gcc-4 is broken and I should never have multiple definitions of inline functions in a few translation units unless they're static?
If you want portability across gcc versions use static inline.

Resources