Suspicious static-linked executable file size - c

I have a BB 10/QNX app in which I need to use more recent version of SQLite than is default on BB 10. I thought I could do that by linking my own SQLite code with my app. I realized that in my qmake-generated Makefile the option -lsqlite3 is passed to qcc. In the library location (/opt/bbndk/target_10_2_0_1155/qnx6/armle-v7/usr/lib) I found the following files:
size filename
559386 libsqlite3.a
560662 libsqlite3S.a
15 libsqlite3.so -> libsqlite3.so.1
496503 libsqlite3.so.1
I thought that I can replace libsqlite3.a with my own file compiled from latest sqlite3.c (amalgamation). What confuses me is that the size of my application executable is just 180 kB, so the code from libsqlite3.a doesn't seem to be present in it. If SQLite is dynamically linked, I'd expect the application archive (.bar) to contain libsqlite3.so, which also isn't true, because the archive is just 130 kB big. How is it possible that the application uses SQLite (via Qt database classes), but SQLite code never makes it to the application archive?

Static version
When linking an executable to a static library, the compiler know you're building a "finished product": nothing will depend on your executable. It allows the compiler to not include unused code. Let's say you're using only one function from the library, which itself is not using anything else from the library. The compiler will pick only the machine code corresponding to this specific function and gently ignore the rest.
Dynamic version
Regarding the size of the bar archive and the dynamic library, it goes down to what really is a bar archive. It's simply a zip archive (maybe with some metadata added, don't know in details). Two possibilities: either the .so file is greatly compressed, or the compiler relies on the system library and doesn't bundle it in the bar archive.

Related

Managing static libraries

I am linking few libs in one by using command
lib.exe /out:X.lib X.lib other1.lib other2.lib
The result lib becomes much bigger then it was.
When I am linking the result X.lib to my exe everything works perfect till I remove other1.lib or other2.lib from the file system.
I have 2 questions:
Why my result lib becomes SO big if still the original other1.lib and other2.lib are used.
How can I let linker to use data from the result X.lib and not from original libs?
Update:
this behavior is relevant just for boost libs in my case

How to stop file names/paths from appearing in compiled C binary

This may be compiler specific, in which case I am using the IAR EWARM 5.50 compiler (firmware development for the STM32 chip).
Our project consists of a bunch of C-code libraries that we compile first, and then the main application which compiles its C-code and then links in those libraries (pretty standard stuff).
However, if I use a hex editor and open up any of the library object files produced or the final application binary, I find a whole bunch of plain text references inside the output binary to the file paths of the C files that were compiled. (eg. I see "C:\Development\trunk\Common\Encryption\SHA_1.c")
Two issues with this:
we don't really want the file paths being easily readable as that indicates our design some what
the size of the binary grows if you have your C-files located in a long subdirectory (the binary contains the full path, not just the name)...this is especially important when we're dealing with firmware that has a limited amount of code space (256KB).
Any thoughts on this? I've tried all the switches in the compiler I can think of to "remove debug information", etc., but those paths are still in there.
"The command-line option --no_path_in_file_macros has been added. It removes the path leaving only the filename for the symbols FILE and BASE_FILE."
It is defined in the release notes if IAR.
http://supp.iar.com/FilesPublic/UPDINFO/005832/arm/doc/infocenter/iccarm_history.ENU.html
Or you can look for FILE and BASE_FILE macros and remove it you do not want to use the flag.

Appending data to an executable (Windows, Unix)

I have a program which compiles and runs scripts.
To create a standalone version of the script, I reserve a large static buffer to hold the compiled script. The compiled script is copied into a copy of the program and it can then be run from that copy.
This works fine. It has some disadvantages however:
the buffer is static and takes up space if there's no compiled
program in it.
if the script to be included exceeds the buffer's size, I need to build a new version with a larger buffer.
I'd like to add the compiled script to the end of the program, but naively doing so doesn't work as the exe loader chokes on the new file size.
Is there a way to manipulate the exe so it would be acceptable for the loaders (mind this is a cross platform program)?
would be acceptable for the loaders (mind this is a cross platform program)?
I would think that this is unlikely to be possible without being platform specific. Time for a common interface with different implementations (so the code that saves/loads the script is common, but the executable manipulation is specific).
On Windows you'll hit the problem that a running executable file is locked against modification. By working on copies this can be worked around (but the only way to rename back in a completely deterministic way it is perform the move on boot, but scheduling a job might be acceptable).
On Windows the easiest way to add data to an image (executable or dll) is using resources. Define a custom resource type and add into the image (UpdateResource function) and later retrieve with LoadResource.
You said "script", so I suppose you have a separate file containing the script (a text file?). You could write a simple program that reads the script file and convert it in a compilable form (e.g. a C source containing the initialization of an array of byte). There are also tools you can use to convert an arbitrary file into a linkable object (.o or .obj). In the past I have used the command "objcopy" from GNU bimutils. In particular, on linux:
objcopy -I binary -O elf32-i386 mydata mydata.o
This command creates an object and three public symbols you can use to find the start, the end and the size of your data block:
_binary_mydata_start
_binary_mydata_end
_binary_mydata_size
Something similar may work also on Windows, provided that you install a Windows version of GNU binutils (e.g. cygwin).

shared library file size

On creating a shared library the ./sl file size is coming out to be greater than 60KB.
There are 2 .o files whose total size is over 20KB.
Checked the utlities : ldd and elfdump to determine libraries being referenced.
Apart from the original files used I see references of :/usr/ccs/lib/pa20_64/lddstub and
SOURCE FILE INFO: movelr1 PA-RISC 2.0 Assembler.
What are the possible reasons for shared lib file size increase ?.
[(Novice in C) : Working on OS : HP Unix 11i V2 PA RISC-64]
I am not an HP-UX expert but my best guess is that the HP-UX vendor linker is adding some additional stuff to dynamic library it is creating in addition to the 20kB of object files.
You could use the strip(1) utility to make the shared library smaller.
Thanks Sean!, However using the strip utility did effect the file size, ~7KB , but in a small way.
Another option we found was: elfdump -dc TestProg.sl
On doing that we found that system file is included and also the date/time of compilation of the source files. One probability is that the earlier version of the sl file had older version of prog/os system file included and this could be a possible cause in size difference.
The sys file included in shared lib:
[movelr1.o]: in the path /usr/lib/pa20_64/milli.a influences the size of the ./sl file created.

What exactly does "ar" utility do?

I don't really understand what ar utility does on Unix systems.
I know it can be somehow used for creating c libraries, but all that man page tells me is that it is used to make archives from files, which sounds similar to, for example, tar....
The primary purpose is to take individual object files (*.o) and bundle them together into a static library file (*.a). The .a file contains an index that allows the linker to quickly locate symbols in the library.
Tar doesn't create files that linkers understand.
ar is a general purpose archiver, just like tar. It just "happens" to be used mostly for creating static library archives, one of its traditional uses, but you can still use it for general purpose archiving, though tar would probably be a better choice. ar is also used for Debian .deb packages.
Exactly, ar is an archiver. It simply takes a set of object files (*.o) and put them in an archive that you call a static library.
It takes code in the form of object files (.obj, .o, etc) and makes a static library (archive). The library can then be included when linking with ld to include the object code into your executable.
Take a look at the example usage in the Wikipedia article.
You might want to run man ar to get the full picture. Here's a copy of that on the web.
To quote:
The GNU ar program creates, modifies, and extracts from archives. An
archive is a single file holding a collection of other files in a
structure that makes it possible to retrieve the original individual
files (called members of the archive).
ar is considered a binary utility because archives of this sort are
most often used as libraries holding commonly needed subroutines.
ar is specifically for archives (or libraries) of object code; tar is for archives of arbitrary files. Anybody's guess why GNU refers to these as 'archives', in other environments this utility is called the 'librarian', and the resulting files just libraries.

Resources