Why are __stat & __fstat linked statically? - glibc

I'm monkeying around with LD_PRELOAD to wrap libc functions for call tracking purposes. Everything has been going swell until I attempted to wrap __stat and __fstat. It appears these two functions are statically linked, unlike open, fdopen, etc which are dynamically linked (and thus wrap able).
I would love to understand: Why this is the case?
Bonus points if you can answer: How can I wrap __stat & __fstat calls?
Thanks!
matt#matt-laptop:~/code/test$ scons
scons: Reading SConscript files ...
scons: done reading SConscript files.
scons: Building targets ...
g++ -o build/libc_wrapper_lib/libc_wrapper.os -c -D_GNU_SOURCE -D_REENTRANT -std=gnu++11 -g -fPIC build/libc_wrapper_lib/libc_wrapper.cpp
g++ -o lib/libc_wrapper.so -nostartfiles -fPIC -pthread -shared build/libc_wrapper_lib/libc_wrapper.os -ldl
/usr/lib/x86_64-linux-gnu/libc_nonshared.a(stat.oS): In function `__stat':
(.text+0x0): multiple definition of `__stat'
build/libc_wrapper_lib/libc_wrapper.os:/home/matt/code/test/build/libc_wrapper_lib/libc_wrapper.cpp:252: first defined here
/usr/lib/x86_64-linux-gnu/libc_nonshared.a(fstat.oS): In function `__fstat':
(.text+0x0): multiple definition of `__fstat'
build/libc_wrapper_lib/libc_wrapper.os:/home/matt/code/test/build/libc_wrapper_lib/libc_wrapper.cpp:283: first defined here
collect2: error: ld returned 1 exit status
scons: *** [lib/libc_wrapper.so] Error 1
scons: building terminated because of errors.

I would love to understand: Why this is the case?
This answer explains why that is the case.
You'll need to wrap __xstat instead.

Related

Making relocatable object with gcc causes "cannot find -lgcc_s" error

I'm trying to make a relocatable object file with gcc. I use solution from this post. The solution works fine with ld:
$ ld -r a.o b.o -o c.o
However when I try to use it with gcc, the following error happens:
$ gcc -r a.o b.o -o c.o
/usr/bin/ld: cannot find -lgcc_s
/usr/bin/ld: cannot find -lgcc_s
collect2: ld returned 1 exit status
Using the -Wl,-r and -Wl,--relocatable options gives the same result.
Is there any way to link relocatable object file with gcc or I'm forced to use ld for doing this?
To solve this problem, the -nostdlib option must also be passed to gcc:
$ gcc -r -nostdlib a.o b.o -o c.o
I don't know it for sure, but it seems without this option gcc tries to link standard libraries into output relocatable object.

linker option to ignore unused dependencies

I would like to remove all unused symbols from my compiled C++ binary. I saw this, which gives an overview using gcc, which is the toolchain I'm using: How to remove unused C/C++ symbols with GCC and ld?
However, on my system, the linking option (-Wl,--gc-sections) is rejected:
$ gcc -fdata-sections -ffunction-sections a.c -o a.o -Wl,--gc-sections
ld: fatal: unrecognized option '--'
ld: fatal: use the -z help option for usage information
collect2: error: ld returned 1 exit status
I'm running on illumos, which is a (relatively) recent fork of Solaris, with GCC 4.7. Anybody know what the correct linker option to use here is?
Edit: searching the man pages more closely turned up "-zignore":
-z ignore | record
Ignores, or records, dynamic dependencies that are not
referenced as part of the link-edit. Ignores, or
records, unreferenced ELF sections from the relocatable
objects that are read as part of the link-edit. By
default, -z record is in effect.
If an ELF section is ignored, the section is eliminated
from the output file being generated. A section is
ignored when three conditions are true. The eliminated
section must contribute to an allocatable segment. The
eliminated section must provide no global symbols. No
other section from any object that contributes to the
link-edit, must reference an eliminated section.
However the following sequence still puts FUNCTION_SHOULD_BE_REMOVED in the ELF section .text.FUNCTION:
$ cat a.c
int main() {
return 0;
}
$ cat b.c
int FUNCTION_SHOULD_BE_REMOVED() {
return 0;
}
$ gcc -fdata-sections -ffunction-sections -c a.c -Wl,-zignore
$ gcc -fdata-sections -ffunction-sections -c b.c -Wl,-zignore
$ gcc -fdata-sections -ffunction-sections a.o b.o -Wl,-zignore
$ elfdump -s a.out # I removed a lot of output for brevity
Symbol Table Section: .dynsym
[2] 0x08050e72 0x0000000a FUNC GLOB D 1 .text.FUNCTION FUNCTION_SHOULD_BE_REMOVED
Symbol Table Section: .symtab
[71] 0x08050e72 0x0000000a FUNC GLOB D 0 .text.FUNCTION FUNCTION_SHOULD_BE_REMOVED
Because the man pages say "no global symbols", I tried making the function "static" and that had the same end result.
The ld '-z ignore' option is positional, it applies to those input objects which occur after it on the command line. The example you gave:
gcc a.o b.o -Wl,-zignore
Applies the option to no objects -- so nothing is done.
gcc -Wl,-zignore a.o b.o
Should work

Combining multiple .o files into an executable

I'm trying to combine object files created from C++ files into an executable using gcc. Unfortunately, gcc is giving me thousands of undefined reference errors to strings, arrays, etc.
I am doing this on a Windows machine, so no terminal commands; only cmd commands.
I'm simply doing:
gcc a.o b.o c.o -o prgm.exe
What am I missing/doing wrong?
EDIT:
I recreated the .o files with g++ doing:
g++ a.cpp -g -c -Wall -std=c++0x -lSDLmain -lSDL -lSDL_image -lSDL_ttf -IC:\SDL-1.2.14\include -o a.o, where a.cpp and a.o are the directories where i keep the files, not the g++ directory
Then, I did g++ a.o b.o c.o -o prgm.exe. This gave dozens (I guess that's an improvement?) errors like
undefined reference to `_SDL_SetColorKey'
but I included SDL didnt I?
The final error from this is:
c:/program files (x86)/codeblocks/mingw/bin/../lib/gcc/mingw32/4.7.0/../../../li
bmingw32.a(main.o):main.c:(.text.startup+0xa7): undefined reference to `_WinMain
#16'
collect2.exe: error: ld returned 1 exit status
int main(int argc, char * argv[]) is in the code
You are trying to link a C++ program with the C linker. You need to use g++ instead of gcc.
Generally speaking gcc is for compiling/linking C, while g++ is for C++. IIRC compiling C++-code with gcc works by virtue of dispatching according to the file extension. Linking C++ code with gcc however does not work, since it won't link the C++ standard libraries, resulting in your undefined reference errors.
If this does not solve your problem, you might want to give us a more concrete description of your errors and your system.
Based upon your updates then I think you'd need to do the following:
g++ a.cpp b.cpp c.cpp -g -Wall -IC:\SDL-1.2.14\include -LC:\SDL-1.2.14\lib -std=c++0x -lSDLmain -lSDL -lSDL_image -lSDL_ttf -o prgm.exe
I'm guessing C:\SDL-1.2.14\lib exists based upon where the headers are located.
GCC is the C compiler. Your code is C++ so you need to use G++ to do the linking:
g++ a.o b.o c.o -o prgm.exe
This automatically adds the C++ libraries to the link line, resolving many if not all of your missing references.

make library not found

I'm trying to compile a program using a third party library, Omnet++ in my case. Apparently "make" does not find a library, but the path it uses is correct as you can see (in the sense that I can see the library under omnet++ source tree)
pv135168:basic Bob$ opp_makemake
Creating Makefile in /Users/Bob/Code/network_sim/basic... Makefile created, running "make depend" to add dependencies... opp_makedep -Y --objdirtree -I. -f Makefile -P\$O/ -- ./*.cc
pv135168:basic Bob$ make
g++ -c -g -Wall
-fno-stack-protector -m32 -DHAVE_PCAP -DXMLPARSER=libxml
-DWITH_PARSIM -DWITH_NETBUILDER -I.
-I/Users/Bob/Code/omnetpp-4.1/include -o out/gcc-debug//txc1.o txc1.cc g++ -m32 -Wl,-rpath,/Users/Bob/Code/omnetpp-4.1/lib -Wl,-rpath,. -o out/gcc-debug//basic out/gcc-debug//txc1.o -Wl,-all_load
-L"/Users/Bob/Code/omnetpp-4.1/lib/gcc"
-L"/Users/Bob/Code/omnetpp-4.1/lib" -u _tkenv_lib -lopptkenvd
-loppenvird -lopplayoutd -u _cmdenv_lib -loppcmdenvd -loppenvird
-loppsimd -lstdc++
ld: library not found for -lopptkenvd
collect2: ld returned 1 exit status make: *** [out/gcc-debug//basic]
Error 1 pv135168:basic Bob$
It's looking in the following directories for a file called libopptkenvd.dylib or libopptkenvd.a:
/Users/Bob/Code/omnetpp-4.1/lib/gcc
/Users/Bob/Code/omnetpp-4.1/lib
Is that file in one of those directories (or in the standard directories like /usr/lib)? I don't see an indication of that in your output.

is it possible to create an object file from other object files in gcc?

I was trying to do something like this in a makefile:
program.exe: ui.o main.o
gcc ......etc
ui.o: window1.o window2.o
gcc -c window1.o window2.o -o ui.o #this doesn't want to work
window1.o: window1.c window1.h window1_events.c window1_controls.c ...
gcc -c window1.c window1_events.c window1_controls.c... -o window1.o
window2.o: ...
gcc ...
main.o: ...
gcc ...
but when I compile like this, it gives the error "input file unused because linking not done," and then I get a bunch of unresolved externs, etc--problems which are resolved by changing
program.exe: ui.o main.o
gcc ...
to
program.exe: window1.o window2.o main.o
gcc ...
so is it possible to just link object files together, to avoid having mile-long lines in a makefile and break down the build process a little more?
Yes: to merge several object files into one, use ld -r or ld -Ur:
From "man ld" on Linux:
-r
--relocatable
Generate relocatable output---i.e., generate an output file that can
in turn serve as input to ld. This is often called partial linking.
As a side effect, in environments that support standard Unix magic
numbers, this option also sets the output file’s magic number to
"OMAGIC".
If this option is not specified, an absolute file is produced.
When linking C++ programs, this option will not resolve references to
constructors; to do that, use -Ur.
You could also do this with gcc:
gcc -Wl,-r foo.o bar.o -o foobar.o -nostdlib
Merging object files like this has some advantages over using an archive library: if merged files change very infrequently (compared to say main.c), your final executable links will be faster.
OTOH, with archived library, the linker will only use what it needs, so your executable may end up being smaller if e.g. window2.c ends up not being necessary.
I bunch of object files is a library. You can create a library with the ar
utility. The following example creates a library called mylib.a containing the files foo.o and bar.o
ar rvs mylib.a foo.o bar.o
You can then link with it by using it on the compiler command line:
gcc -o myexe main.c mylib.a
To create a library:
ar rvs somelib.a file1.o file2.o file3.o
To link it:
gcc -o program.exe file4.o somelib.a

Resources