Undefined Symbol _memset although _memset nowhere used? [duplicate] - c

I asked a similar question, but I have some update which is really confusing me. Essentially, I want to link a number of object files with the linker as follows:
/usr/ccs/bin/ld -o q -e start_master -dn -z defs -M ../../../mapfile.q {list of object files}
I get the following error:
Undefined first referenced
symbol in file
_memset reconf.o
The interesting things is, that memset is not referenced in reconf.c and I also grep'ed the whole directory but there is also no reference in any of the other files to _memset. Therefore I am wondering why I get this error message from the linker, although nowhere in my source code _memset is actually used. Anyone an idea what could be going on here?
Thanks so much, this error is driving us mental!
EDIT:
I tried to add the path to the library of memset and linked it with -lc and run it in verbose mode:
/usr/ccs/bin/ld -o q -e start_master -dn -z defs -z verbose -L/usr/lib -M ../../../mapfile.q {list of object files} -lc
Then I get the following error:
ld: fatal: library -lc: not found
ld: fatal: File processing errors. No output written to q
And this although libc.so is clearly in /usr/lib ...
Confusing
EDIT II:
Doing some more research it seems that on Solaris 10 static linking disappeard as you can read here:
http://blogs.oracle.com/rie/entry/static_linking_where_did_it
Probably this is my problem. Has anyone an idea how I could rewrite my linker command for a workaround to this problem?
Many thanks!

Probably you did:
struct S v = { 0 };
or
struct S v;
v = (some const-variable).
or
uint8_t b[100] = { 0 };
.
Some compilers are putting implicitly the built-in memset (or memcpy) for such things. The built-in memset then is called _memset (in your case). Once you link and your libc (or what provides standard-function in your case) does not providie it, you are getting this link error.

Assuming you're on Solaris, you'll find memset in the libc.so library :
/usr/lib-> nm libc.so | grep memset
[7122] | 201876| 104|FUNC |GLOB |0 |9 |_memset
Simply add -lc to the command line

Memset is a library function from standard C library. If you don't use gcc for linking (which links your files with standard libraries by default) you should explicitly link your progrom with libc.
On the other option, probably you don't use libc. In this case memset call could be generated by gcc.
From man gcc:
-nodefaultlibs
Do not use the standard system libraries when linking. Only the libraries you specify will be passed to the linker, options specifying linkage of the system libraries, such as -static-libgcc or -shared-libgcc, will be ignored. The standard startup files are used normally, unless -nostartfiles is used. The compiler may generate calls to memcmp, memset, memcpy and memmove. These entries are usually resolved by entries in libc. These entry points should be supplied through some other mechanism when this option is specified.
In this case simply write memset (it's trivial proc.) and supply it to linker.

Related

proj.c:(.text+0x140): undefined reference to `pcap_open_offline'

I'm trying to use pcap functions, but it giving me compiler error:
project.c:(.text+0x140): undefined reference to `pcap_open_offline'
I have installed library and while compiling I give "-lpcap" at the and as it advised in many forums.
What can be wrong, please?
You need to understand what the arguments evoke into the linker.
I am supposing you are using Linux system with gcc, using ld as linker (note that this could change depending on the system and the linker used).
In such case, -Lpath tell the linker where to look for the libraries that you tell it that are needed to be linked with your program to create the final binary. For example -L/usr/lib.
when you type in for example:
# gcc -L/usr/lib -lcap my_program.c -o my_program
You are telling the linker to append /usr/lib to the list of paths to locate libraries, and to link the dynamic library "libcap.so" with your program.
Other modifiers for the path used to locate libraries is LD_LIBRAY_PATH (the name of this environment variable could change from one system to another, review the manual of your linker).
As you are using "-lcap" the error you get look to be related with the fact that no path is found where libcap.so exist. Locate that file into your system and pass the argument
-L/path/to/the/directory/that/contain/libcap.so
By the way, try to run this before any other thing and recompile:
# sudo ldconfig

Can IAR produce a static library that GCC can link to?

There is a vendor whose software I'd like to work with. They have a code base which they can only compile using IAR Embedded Workbench (as far as I know, their code does not compile with GCC). Unfortunately their hardware only works with their software stack, so I don't really have a choice about whether or not I'd like to use it. They distribute this code as a .a static library file (and accompanying headers) compiled for the ARM Cortex-M4 CPU. (They don't want to distribute sources.) For the sake of this discussion, let's call it evil_sw_stack.a.
I'd like to use this piece of code but I don't have an IAR license and have zero expertise with IAR. I'd like to use GCC.
Is there a way to make IAR produce such a static library that GCC can link to? What kind of compiler option would the vendor need to use to produce such a binary?
(I would guess that the ABI of the resulting binary can be somehow specified and set to a setting which statisfies GCC. )
Example usage of GCC
Their default software stack is very GCC-friendly, this specific one is the only one in their offering which isn't. Generally, I can compile a simple piece of example code if I have the following:
startup_(devicename).S: GCC-specific assembly file
system_(devicename).c
(devicename).ld: linker script
Some header files for the specific device
For example, I can compile a simple piece of example like this:
$ arm-none-eabi-gcc helloworld.c startup_(devicename).S system_(devicename).c -T (devicename).ld -o helloworld -D(devicename) -I. -fno-builtin -ffunction-sections -fdata-sections -mfpu=fpv4-sp-d16 -mfloat-abi=softfp -mcpu=cortex-m4 -mthumb -mno-sched-prolog -Wl,--start-group -lgcc -lc -lnosys -Wl,--end-group
So far, so good. No warnings, no errors.
How I try to use the static library
For the sake of this discussion, let's call it evil_sw_stack.a.
This is how I attempted to use it:
$ arm-none-eabi-gcc evil_sw_stack.a helloworld.c startup_(devicename).S system_(devicename).c -T (devicename).ld -o helloworld -D(devicename) -I. -fno-builtin -ffunction-sections -fdata-sections -mfpu=fpv4-sp-d16 -mfloat-abi=softfp -mcpu=cortex-m4 -mthumb -mno-sched-prolog -Wl,--start-group -lgcc -lc -lnosys -Wl,--end-group
Unfortunately this complains about multiple definitions of a bunch of functions that are defined in system_(devicename).c. Maybe they accidentally compiled that into this library? Or maybe IAR just compiled it this way? Now, if I try to remove system_(devicename).c from the GCC command line and simply link to the .a file, I get these errors:
/usr/lib/gcc/arm-none-eabi/5.2.0/../../../../arm-none-eabi/bin/ld: warning: thelibrary.a(startup_chipname.o) uses 2-byte wchar_t yet the output is to use 4-byte wchar_t; use of wchar_t values across objects may fail
undefined reference to `__iar_program_start'
undefined reference to `CSTACK$$Limit'
undefined reference to `__iar_program_start'
Poking the file with readelf gets me nowhere:
$ readelf -h evil_sw_stack.a
readelf: Error: evil_sw_stack.a: did not find a valid archive header
Interestingly though, this seems to be getting somewhere:
$ arm-none-eabi-ar x evil_sw_stack.a
Now I've got a bunch of object files which do have ELF headers according to readelf, and yup, they did compile a startup file (of another of their devices) into the library... I'm wondering why, but I think this is a mistake.
This also works:
$ arm-none-eabi-objdump -t evil_sw_stack_objfile.o
So now the question is, is it safe to try to compile these object files into my own application using GCC? According to this other SO question, the object file formats are not compatible.
I assume that the startup code is mistakenly compiled into the library. I can delete it:
$ arm-none-eabi-ar d evil_sw_stack.a startup_(otherdevicename).o
$ arm-none-eabi-ar d evil_sw_stack.a system_(otherdevicename).o
Now I get an evil_sw_stack.a which gcc can accept as an input without complaining.
However, there is one thing that still worries me. When I use the object files instead of the static library, I get these warnings:
/usr/lib/gcc/arm-none-eabi/5.2.0/../../../../arm-none-eabi/bin/ld: warning: evil_objfile.o uses 2-byte wchar_t yet the output is to use 4-byte wchar_t; use of wchar_t values across objects may fail
/usr/lib/gcc/arm-none-eabi/5.2.0/../../../../arm-none-eabi/bin/ld: warning: evil_objfile.o uses 32-bit enums yet the output is to use variable-size enums; use of enum values across objects may fail
So it seems that evil_sw_stack.a was compiled with (the IAR equivalents of) -fno-short-enums and -fshort-wchar. GCC doesn't complain about this when I use evil_sw_stack.a at its command line but it does complain when I try to use any object file that I extracted from the library. Should I worry about this?
I don't use wchar_t in my code so I believe that one doesn't matter, but I would like to pass enums between my code and the library.
Update
Even though the linker doesn't complain, it doesn't work when I actually call some functions from the static library. In that case, make sure to put the libraries in the correct order when you call the linker. According to the accepted answer to this question, they need to be in reverse order of dependency. After doing this, it still misses some IAR crap:
undefined reference to `__aeabi_memclr4'
undefined reference to `__aeabi_memclr'
undefined reference to `__aeabi_memmove'
undefined reference to `__aeabi_memset4'
undefined reference to `__aeabi_memset'
undefined reference to `__iar_vla_alloc2'
undefined reference to `__iar_vla_dealloc2'
undefined reference to `__aeabi_memclr4'
I've found out that the __aeabi functions are defined in libgcc but even though I link to libgcc too, the definition in libgcc doesn't seem to be good enough for the function inside evil_sw_stack.a.
EDIT: after some googling around, it seems that arm-none-eabi-gcc doesn't support these specific __aeabi functions. Take a look at this issue.
Anyway, after taking a look at ARM's runtime ABI docs, the missing __aeabi functions can be trivially implemented using their standard C library equivalents. But I'm not quite sure how __iar_vla_alloc2 and __iar_vla_dealloc2 should work and couldn't find any documentation on them online. The only thing I found out is that VLA means "variable length array".
So, it seems that this will never work unless the chip vendor can compile their static library in such a way that it doesn't use these symbols. Is that right?
Disclaimer
I'd prefer not to disclose who the vendor is and not to disclose which product I work with. They are not proud that this thing doesn't work properly and asked me not to. I'm asking this question to help and not to discredit them.

/usr/bin/ld: cannot find -lsqlite3.h

I am trying to use sqlite3 in my Eclipse C project, I have added sqlite3.h and its address: /usr/include/ to linker, but still get this error message:
make all
Building target: SQLiteTest
Invoking: GCC C Linker
gcc -L/usr/include/ -o "SQLiteTest" ./hello.o -lsqlite3.h
/usr/bin/ld: cannot find -lsqlite3.h
collect2: error: ld returned 1 exit status
make: *** [SQLiteTest] Error 1
I guess I have to add it to compiler as well, have tried many ways, but none of them worked.
Thanks for help
When compiling and linking C programs:
the -I/some/where/include option is used to specify where headers (include files) are found,
the -L/some/where/lib option is used to specify where libraries are found,
the -lname option is used to say "link with the library libname.so or libname.a"
The suffixes on libraries vary by platform — choose from .sl, .sa, .dll, .lib, .dylib, .bundle, to name but a few alternative extensions.
The -L/usr/include option is unlikely to be correct. Headers are stored in /usr/include, and not libraries. Changing that to -I/usr/include is unnecessary; the compiler will search in /usr/include anyway. If the sqlite3.h header is in /usr/include, it will be found without options. If it is somewhere else, like perhaps /usr/local/include or /opt/sqlite3/include, then you may well need to specify -I/usr/local/include or -I/opt/sqlite3/include on the command line. In each case, you might also need -L/usr/local/lib or -L/opt/sqlite3/lib as well. (Note that your compiler might, but probably won't, search in /usr/local automatically.)
As noted in the comments, you would not specify -lsqlite3.h on the command line. It would mean that there was a library such as libsqlite3.h.so somewhere on your system, which is an implausible name. Most likely, you should just specify -lsqlite3 on the linking command line.

Creating a dylib which gets linked at runtime

I am trying to create a dynamic library which is meant to be linked and loaded into a host environment at runtime (e.g. similar to how class loading works in Java). As such, I want the dynamic library to be left with a few "dangling" references, which I expect it to pick up from its host environment when it is loaded into that environment.
My problem is that I cannot figure out how to create the dynamic library without explicitly linking it to existing symbols. I am hoping to produce a dynamic library that does not depend on a specific host executable (or host library), rather one that is able to be loaded (e.g. by dlopen) in any host as long as the host makes a couple symbols available for use.
Right now, any linking command I've tried results in a complaint of missing symbols. I'd like it to allow symbols to be missing (ideally, just particularly specified symbols).
For example, here's a transcript with the error on OS X:
$ cat frotz.c
void blort(void);
void run(void) {
blort();
}
$ cc -c -o frotz.o frotz.c
$ cc -dynamiclib -o libfrotz.dylib frotz.o
Undefined symbols for architecture x86_64:
"_blort", referenced from:
_run in frotz.o
ld: symbol(s) not found for architecture x86_64
clang: error: linker command failed with exit code 1 (use -v to see invocation)
If I do the same thing using a GNU toolchain (on Linux), it helpfully tells me:
$ gcc -shared -o libfrotz.so frotz.o
/usr/bin/ld: frotz.o: relocation R_X86_64_PC32 against undefined symbol `blort'
can not be used when making a shared object; recompile with -fPIC
and indeed, adding -fPIC to the C compile command seems to fix the problem in that environment. However, it doesn't seem to have any effect in OS X.
All the other dynamic-linking questions I could find on SO seem to be about the more usual arrangement of libraries, where a library is being built to be linked into an executable before that executable runs, rather than the other way around. The closest related question I found was this:
Can an executable be linked to a dynamic library after its built?
which unfortunately has very little info, none of it relevant to the question I'm asking here.
UPDATE: I distilled the info from the answer along with everything else I'd figured
out, and put together this example:
https://github.com/danfuzz/dl-example
As far as my knowledge goes, you want to use weak linkage:
// mark function as weakly-linked
extern void foo() __attribute__((weak));
// inform the linker about that too
clang -dynamiclib -o bar.dylib bar.o -flat_namespace -undefined dynamic_lookup
If a weak function can be resolved at runtime, it will then be resolved. If it can't, it will be NULL, instead of generating a runtime (or, obviously, link-time) error.

Portable way to link statically against one of the libraries

I am creating a utility which depends on libassuan aside other depends. While these ‘others’ provide shared libraries, libassuan comes with static one only.
libassuan comes with simple libassuan-config tool which is meant to provide CFLAGS & LDFLAGS for the compiler/linker to use. These LDFLAGS refer to the library as -lassuan.
The result of standard call of make is then:
cc -I/usr/include/libmirage -I/usr/include/glib-2.0 -I/usr/lib64/glib-2.0/include -lmirage -lglib-2.0 -L/usr/lib64 -lassuan -o mirage2iso mirage2iso.c mirage-getopt.o mirage-wrapper.o mirage-password.o
mirage-password.o: In function `mirage_input_password':
mirage-password.c:(.text+0x1f): undefined reference to `assuan_pipe_connect'
mirage-password.c:(.text+0x32): undefined reference to `assuan_strerror'
collect2: ld returned 1 exit status
make: *** [mirage2iso] Error 1
(I've just started writing this unit and that's why there aren't more errors)
So, if I understand the result correctly, gcc doesn't want to link the app to libassuan.a.
Using -static here will cause gcc to prefer static libraries over shared which is unindented. I've seen solution suggesting using something like that:
-Wl,-Bstatic -lassuan -Wl,-Bdynamic
but I don't think it would be a portable one.
I think the best solution would be to provide full path to the static library file but libassuan-config doesn't provide much of help (all I can get from it is -L/usr/lib64 -lassuan).
Maybe I should just try to create the static library path by ‘parsing’ returned LDFLAGS and using -L for the directory name and -l for the library name — and then hoping that in all cases libassuan-config will return it like that.
What do you think about that? Is there any good, simple and portable solution to resolve the issue?
PS. Please note that although I'm referring to gcc here, I would like to use something that will work fine with other compilers.
PS2. One additional question: if package does install static library only, returning such LDFLAGS instead of full .la path can be considered as a bug?
gcc will link to libassuan.a if it doesn't find libassuan.so
It's probably the order symbols are looked up in the static library when you link. The order matters.
)
Assuming gcc can find libassuan.a and it actually provides the functions the linker complains about, try:
cc -I/usr/include/libmirage -I/usr/include/glib-2.0 -I/usr/lib64/glib-2.0/include -lmirage -lglib-2.0 -L/usr/lib64 -o mirage2iso mirage2iso.c mirage-getopt.o mirage-wrapper.o mirage-password.o -lassuan
Since you say libassuan is under /usr/lib64 it's probably a 64 bit library, are your app and the other libraries 64 bit as well ?
Compiler's command-line options are not a portable thing. There's no standard for it. Every compiler uses its own and several can merely informally agree to comply with each other in command-line format. The most portable way for your linking is to use libassuan-config, of course. I think, it can generate not only flags for gcc, but for other compilers as well. If it can't, then no portable way exists, I suppose (other than CMake or something on higher level).
The command line to cc you shown is totally correct. If you have a static library libassuan.la and path to it is supplied to -L option, then the compiler does link against it. You can see it from its output: has it not found the static library, would it complain with error message like "can't find -lassuan". I
Moreover, if no libassuan.so is found, then compiler links against your library statically, even if you haven't used -Wl,-Bstatic stuff or -static flag.
Your problem may be in persistence of several versions of libassuan in your system. Other that that, I don't see any errors in what you've provided.
Which directory is libassuan.a in
I think the first error is not gcc doesn't want to link the app to libassuan.a it is more gcc does not know where libassuan.a . You need to pass gcc a -L parameter giving the path to libassuan.a .
e.g.
-L /home/path

Resources