Help with error message from gcc - c

Any idea about this error?
gcc -oxtmpmain.exe xtmpmain.o fiber_driver.o xtmp_options.o getopt.o D:\usr\xtensa\XtDevToolsDE\in
stall\tools\RB-2008.4-win32\XtensaTools\lib\iss\xtmp.lib
xtmpmain.o(.text+0x213):xtmpmain.c: undefined reference to `_uart_setup'
xtmpmain.o(.text+0x2da):xtmpmain.c: undefined reference to `_uart_cleanup'
collect2: ld returned 1 exit status
make: *** [xtmpmain.exe] Error 1

This is a plain linking error. You're calling two functions, uart_setup() and uart_cleanup(), that the linker is not finding.
There might be several causes, including (but certainly not limited to):
They really are missing, perhaps you forgot to link against one object file
Namespacing preventing the existing function from being found
Library paths
Marshalling or problems with external names and underscores
Without more detail, it's hard to tell for sure.

It means that xtmpmain.c called functions named uart_setup() and uart_cleanup(), but they weren't found by the linker. You probably need to include a library, or to implement those functions for Windows in terms of the Win32 API.
Some "is it plugged in questions" are:
Are the functions declared?
Are the functions defined (i.e. implemented)?
With exactly those names?
Were those definitions excluded by the preprocessor?
There is a gcc option that controls the presence or absence of a leading underscore. You didn't accidentally use that for one file and not others, right?
Verify the declared calling convention. __cdecl and __stdcall are very different animals. They usually produce mismatched exported symbol names for safety, and this error can be a symptom of that.
If this is a porting project, then it is likely that the original implementation of a UART-related function is written in a platform-dependent way. In that case, they often would be guarded by a #ifdef of some form that depends on the compile-time platform.
To resolve that, you would need to implement them for this platform, in a style consistent with their usage in the rest of the application, and similarly guarded.

Related

Undefined reference to symbol on a static library

I'm trying to compile a binary linking it with a static library libfoo.a:
gcc -L. -o myapp myapp.o -lfoo
But I'm getting the following error from the linker:
libfoo.c:101: undefined reference to `_TRACE'
The problem is I don't have the source code for libfoo.a library.
I tried to get the reference for _TRACE symbol in the library and I got this:
nm libfoo.a | grep TRACE
U _TRACE
Assuming that _TRACE will not affect the inner workings in libfoo.a, is it possible to get the linker to define some placeholder value for this symbol so that I can compile my code?
Assuming that _TRACE will not affect the inner workings in libfoo.a
That seems an unreasonably hopeful assumption.
is it possible to get the linker to define some placeholder value for this symbol so that I can compile my code?
The first thing to do is to check libfoo's documentation. It is unusual for a static library to depend on a symbol that the user is expected to define; in fact, such an arrangement does not work cleanly with traditional linkers. I see several plausible explanations:
You need to link some other (specific) library after libfoo to provide a definition for that symbol.
Code that uses libfoo is expected to #include an associated header, and that header provides a tentative definition of _TRACE.
Programs that use libfoo are required to be built with a specific toolchain and maybe specific options.
It's just broken.
Only in case (4) is it appropriate to try to manually provide a definition for the symbol in question, and in that case your best bet is to proceed more or less as in case (1), by building an object that provides the definition and linking it after the library. Of course, that leaves you trying to guess what the definition should be.
If _TRACE is a global variable then defining it as an intmax_t with initial value 0 might work even if the library expects a different-size integer or one with different signedness. If it is supposed to be a function, however, then you're probably toast. There are too many signatures it could have, too many possible expectations for behavior. There is no reason to think that you could provide a suitable place-holder.
As I suspected, the _TRACE function is a sort of debugging function. And I was right assuming it would not affect the inner workings of libfoo.a.
I solved the problem defining the _TRACE function as:
int _TRACE(char*, ...) { return 0; }
Of course, this solution is only temporary and cannot be used in production, but it fits my purposes of compiling the code.
If you're using GCC 5.1 or later and/or C++11, there was an ABI change.
You can spot this issue using nm -C: if the symbol is defined (not U) but has a [abi:cxx11] appended to it, then it was compiled with the new ABI. From the link:
If you get linker errors about undefined references to symbols that involve types in the std::__cxx11 namespace or the tag [abi:cxx11] then it probably indicates that you are trying to link together object files that were compiled with different values for the _GLIBCXX_USE_CXX11_ABI macro.
If you have access to the source code (not your case specifically), you can use -Wabi-tag -D_GLIBCXX_USE_CXX11_ABI=0, the latter forcing the compiler not to use the new ABI.
All your code, including libraries, should be consistent.

Cannot use standard library function name for a global variable, even when no headers are included

Declaring a global variable with the same name as a standard function produces an error in clang (but not gcc). It is not due to a previous declaration in a header file. I can get the error by compiling the following one-line file:
extern void *memcpy[];
Clang says
foo.c:1:14: error: redefinition of 'memcpy' as different kind of symbol
foo.c:1:14: note: previous definition is here
Apparently this only happens for a few standard functions. printf produces an error, fprintf produces a warning, fseek just works.
Why is this an error? Is there a way to work around it?
Motivation. I am using the C compiler as a compiler backend. C code is programmatically generated. The generated code relies on byte-level address arithmetic and pointer type casting. All external symbols are declared as extern void *variablename[];.
According to the C standard (ISO 9899:1999 section 7.1.3), "all external identifiers defined by the library are reserved in a hosted environment. This means, in effect, that no user-supplied external names may match library names."
Your problem can be easily solved by adding a unique prefix to all your identifiers, e.g. "mylang_".
As an alternative, you can avoid the problem by using the LLVM or GCC -ffreestanding flag, which will compile your code for a non-hosted environment. (The C standard specifies that the restriction only applies to a hosted environment.) In this case you can use all the names you want (apart from main, which is still your program's entry point), but you must make your own arrangements for your library. This is how operating system kernels can legally define their own versions of the C library functions.
The reason is explained here and a relevant extract is given below. http://www.gnu.org/software/libc/manual/html_node/Reserved-Names.html
I get an error in gcc as well.
The names of all library types, macros, variables and functions that come from the ISO C standard are reserved unconditionally; your program may not redefine these names. All other library names are reserved if your program explicitly includes the header file that defines or declares them. There are several reasons for these restrictions:
Other people reading your code could get very confused if you were using a function named exit to do something completely different from what the standard exit function does, for example. Preventing this situation helps to make your programs easier to understand and contributes to modularity and maintainability.
It avoids the possibility of a user accidentally redefining a library function that is called by other library functions. If redefinition were allowed, those other functions would not work properly.
It allows the compiler to do whatever special optimizations it pleases on calls to these functions, without the possibility that they may have been redefined by the user. Some library facilities, such as those for dealing with variadic arguments (see Variadic Functions) and non-local exits (see Non-Local Exits), actually require a considerable amount of cooperation on the part of the C compiler, and with respect to the implementation, it might be easier for the compiler to treat these as built-in parts of the language.
The page also describes other restricted names.

dlopen: Is it possible to trap unresolved symbols, "manually" resolving them as they happen?

Is it possible to trap unresolved symbol references when they happen, so that a function is called to try to resolve the symbol as needed? Or is it possible to add new symbols to the dynamic symbol table at runtime without creating a library file and dlopen'ing it? I am on GNU/Linux, using GCC. (Portability to other Unixes would be nice, but is not a key concern.)
Thanks in advance!
Edit: I should have given more detail about what I am trying to do. I want to write an interpreter for a programming language, which is expected to support both compiled (dlopen'ed) and interpreted modules. I wanted calls from a compiled module to functions defined elsewhere to be resolved by the linker, to avoid a lookup for the function at every call, but calls to interpreted code would be left unresolved. I wanted to trap those calls, so that I could call the appropriate interpreted function when needed (or signal an error if the function does not exist).
If you know what symbols are missing, you could write a library just with them, and LD_PRELOAD it prior to the application execution.
If you don't have the list of the symbols that are missing, you could discover them by using either 'nm' or 'objdump' on the binary, and, with base on that, write a script which will build the library with the missing symbols prior to the application execution, and then LD_PRELOAD it as well.
Also, you could use gdb to inject new 'code' into applications, making the functions point to what you need.
Finally, you could also override some of the ld.so functions to detect the missing symbols, and do something about them.
But in any case, if you could explain what you are trying to accomplish, it would be easier to provide a proper solution.
I'm making a wild guess that the problem you're trying to address is the case where you dlopen and start using a loadable module, then suddenly crash due to unresolved symbols. If so, this is a result of lazy binding, and you can disable it by exporting LD_BIND_NOW=1 (or any value, as long as it's set) in the environment. This will ensure that all symbols can be resolved before dlopen returns, and if any can't, the dlopen operation will fail, letting you handle the situation gracefully.

Generating link-time error for deprecated functions

Is there a way with gcc and GNU binutils to mark some functions such that they will generate an error at link-time if used? My situation is that I have some library functions which I am not removing for the sake of compatibility with existing binaries, but I want to ensure that no newly-compiled binary tries to make use of the functions. I can't just use compile-time gcc attributes because the offending code is ignoring my headers and detecting the presence of the functions with a configure script and prototyping them itself. My goal is to generate a link-time error for the bad configure scripts so that they stop detecting the existence of the functions.
Edit: An idea.. would using assembly to specify the wrong .type for the entry points be compatible with the dynamic linker but generate link errors when trying to link new programs?
FreeBSD 9.x does something very close to what you want with the ttyslot() function. This function is meaningless with utmpx. The trick is that there are only non-default versions of this symbol. Therefore, ld will not find it, but rtld will find the versioned definition when an old binary is run. I don't know what happens if an old binary has an unversioned reference, but it is probably sensible if there is only one definition.
For example,
__asm__(".symver hidden_badfunc, badfunc#MYLIB_1.0");
Normally, there would also be a default version, like
__asm__(".symver new_badfunc, badfunc##MYLIB_1.1");
or via a Solaris-compatible version script, but the trick is not to add one.
Typically, the asm directive is wrapped into a macro.
The trick depends on the GNU extensions to define symbol versions with the .symver assembler directive, so it will probably only work on Linux and FreeBSD. The Solaris-compatible version scripts can only express one definition per symbol.
More information: .symver directive in info gas, Ulrich Drepper's "How to write shared libraries", the commit that deprecated ttyslot() at http://gitorious.org/freebsd/freebsd/commit/3f59ed0d571ac62355fc2bde3edbfe9a4e722845
One idea could be to generate a stub library that has these symbols but with unexpected properties.
perhaps create objects that have the name of the functions, so the linker in the configuration phase might complain that the symbols are not compatible
create functions that have a dependency "dont_use_symbol_XXX" that is never resolved
or fake a .a file with a global index that would have your functions but where the .o members in the archive have the wrong format
The best way to generate a link-time error for deprecated functions that you do not want people to use is to make sure the deprecated functions are not present in the libraries - which makes them one stage beyond 'deprecated'.
Maybe you can provide an auxilliary library with the deprecated function in it; the reprobates who won't pay attention can link with the auxilliary library, but people in the mainstream won't use the auxilliary library and therefore won't use the functions. However, it is still taking it beyond the 'deprecated' stage.
Getting a link-time warning is tricky. Clearly, GCC does that for some function (mktemp() et al), and Apple has GCC warn if you run a program that uses gets(). I don't know what they do to make that happen.
In the light of the comments, I think you need to head the problem off at compile time, rather than waiting until link time or run time.
The GCC attributes include (from the GCC 4.4.1 manual):
error ("message")
If this attribute is used on a function declaration and a call to such a function is
not eliminated through dead code elimination or other optimizations, an error
which will include message will be diagnosed. This is useful for compile time
checking, especially together with __builtin_constant_p and inline functions
where checking the inline function arguments is not possible through extern
char [(condition) ? 1 : -1]; tricks. While it is possible to leave the function
undefined and thus invoke a link failure, when using this attribute the problem
will be diagnosed earlier and with exact location of the call even in presence of
inline functions or when not emitting debugging information.
warning ("message")
If this attribute is used on a function declaration and a call to such a function is
not eliminated through dead code elimination or other optimizations, a warning
which will include message will be diagnosed. This is useful for compile time
checking, especially together with __builtin_constant_p and inline functions.
While it is possible to define the function with a message in .gnu.warning*
section, when using this attribute the problem will be diagnosed earlier and
with exact location of the call even in presence of inline functions or when not
emitting debugging information.
If the configuration programs ignore the errors, they're simply broken. This means that new code could not be compiled using the functions, but the existing code can continue to use the deprecated functions in the libraries (up until it needs to be recompiled).

How to catch unintentional function interpositioning?

Reading through my book Expert C Programming, I came across the chapter on function interpositioning and how it can lead to some serious hard to find bugs if done unintentionally.
The example given in the book is the following:
my_source.c
mktemp() { ... }
main() {
mktemp();
getwd();
}
libc
mktemp(){ ... }
getwd(){ ...; mktemp(); ... }
According to the book, what happens in main() is that mktemp() (a standard C library function) is interposed by the implementation in my_source.c. Although having main() call my implementation of mktemp() is intended behavior, having getwd() (another C library function) also call my implementation of mktemp() is not.
Apparently, this example was a real life bug that existed in SunOS 4.0.3's version of lpr. The book goes on to explain the fix was to add the keyword static to the definition of mktemp() in my_source.c; although changing the name altogether should have fixed this problem as well.
This chapter leaves me with some unresolved questions that I hope you guys could answer:
Does GCC have a way to warn about function interposition? We certainly don't ever intend on this happening and I'd like to know about it if it does.
Should our software group adopt the practice of putting the keyword static in front of all functions that we don't want to be exposed?
Can interposition happen with functions introduced by static libraries?
Thanks for the help.
EDIT
I should note that my question is not just aimed at interposing over standard C library functions, but also functions contained in other libraries, perhaps 3rd party, perhaps ones created in-house. Essentially, I want to catch any instance of interpositioning regardless of where the interposed function resides.
This is really a linker issue.
When you compile a bunch of C source files the compiler will create an object file for each one. Each .o file will contain a list of the public functions in this module, plus a list of functions that are called by code in the module, but are not actually defined there i.e. functions that this module is expecting some library to provide.
When you link a bunch of .o files together to make an executable the linker must resolve all of these missing references. This is the point where interposing can happen. If there are unresolved references to a function called "mktemp" and several libraries provide a public function with that name, which version should it use? There's no easy answer to this and yes odd things can happen if the wrong one is chosen
So yes, it's a good idea in C to "static" everything unless you really do need to use it from other source files. In fact in many other languages this is the default behavior and you have to mark things "public" if you want them accessible from outside.
It sounds like what you want is for the tools to detect that there are name conflicts in functions - ie., you don't want your externally accessible function names form accidentally having the same name and therefore 'override' or hide functions with the same name in a library.
There was a recent SO question related to this problem: Linking Libraries with Duplicate Class Names using GCC
Using the --whole-archive option on all the libraries you link against may help (but as I mentioned in the answer over there, I really don't know how well this works or how easy it is to convince builds to apply the option to all libraries)
Purely formally, the interpositioning you describe is a straightforward violation of C language definition rules (ODR rule, in C++ parlance). Any decent compiler must either detect these situations, or provide options for detecting them. It is simply illegal to define more than one function with the same name in C language, regardless of where these functions are defined (Standard library, other user library etc.)
I understand that many platforms provide means to customize the [standard] library behavior by defining some standard functions as weak symbols. While this is indeed a useful feature, I believe the compilers must still provide the user with means to enforce the standard diagnostics (on per-function or per-library basis preferably).
So, again, you should not worry about interpositioning if you have no weak symbols in your libraries. If you do (or if you suspect that you do), you have to consult your compiler documentation to find out if it offers you with means to inspect the weak symbol resolution.
In GCC, for example, you can disable the weak symbol functionality by using -fno-weak, but this basically kills everything related to weak symbols, which is not always desirable.
If the function does not need to be accessed outside of the C file it lives in then yes, I would recommend making the function static.
One thing you can do to help catch this is to use an editor that has configurable syntax highlighting. I personally use SciTE, and I have configured it to display all standard library function names in red. That way, it's easy to spot if I am re-using a name I shouldn't be using (nothing is enforced by the compiler, though).
It's relatively easy to write a script that runs nm -o on all your .o files and your libraries and checks to see if an external name is defined both in your program and in a library. Just one of the many sane sensible services that the Unix linker doesn't provide because it's stuck in 1974, looking at one file at a time. (Try putting libraries in the wrong order and see if you get a useful error message!)
The Interposistioning occurs when the linker is trying to link separate modules.
It cannot occur within a module. If there are duplicate symbols in a module the linker will report this as an error.
For *nix linkers, unintended Interposistioning is a problem and it is difficult for the linker to guard against it.
For the purposes of this answer consider the two linking stages:
The linker links translation units into modulles (basically
applications or libraries).
The linker links any remaining unfound symbols by searching in modules.
Consider the scenario described in 'Expert C programming' and in SiegeX's question.
The linker fist tries to build the application module.
It sess that the symbol mktemp() is an external and tries to find a funcion definiton for the symbol. The linker finds
the definition for the function in the object code of the application module and marks the symbol as found.
At this stage the symbol mktemp() is completely resolved. It is not considered in any way tentative so as to allow
for the possibility that the anothere module might define the symbol.
In many ways this makes sense, since the linker should first try and resolve external symbols within the module it is
currently linking. It is only unfound symbols that it searches for when linking in other modules.
Furthermore, since the symbol has been marked as resolved, the linker will use the applications mktemp() in any
other cases where is needs to resolve this symbol.
Thus the applications version of mktemp() will be used by the library.
A simple way to guard agains the problem is to try and make all external sysmbols in your application or library unique.
For modules that are only going to shared on a limited basis, this can fairly easily be done by making sure all
extenal symbols in your module are unique by appending a unique identifier.
For modules that are widely shared making up unique names is a problem.

Resources