Recently, when making a Docker image, I found the image file is very large, need to find out the application library, reduce the size of the program, so the related tools have been organized. Basically, these tools are in the GNU Binutils.
GNU Binary Utilities or binutils is a complete set of programming language tool programs for processing many formats of target files. The current version was originally written by a programmer in Cygnus solutions with the binary File Descriptor Library (LIBBFD). This utility is typically used with GCC, make, and GDB.
It contains about 20 tools, and this article describes some of the tools I use when creating a docker image.
LDd
LDD is not a tool in the GNU Binutils toolset, but it is a useful tool to display the shared libraries required by a program or shared library.
For example:
12345 |
# LDD mainlinux-vdso.so. 1 = (0x00007ffc88fd4000) libpthread.so. 0 =/lib64/libpthread.so. 0 (0x00007faee13b8000) libc.so. 6 =/lib64/libc.so. 6 (0x00007faee0feb000)/lib64/ld-linux-x86-. So. 2 (0x00007faee15d4000) |
In accordance with the LDD Handbook, sometimes LDD can obtain dependent information through the execution of procedures, and for unknown programs, the execution of these programs may pose a risk, so that for unknown source programs, it may be used for objdump
analysis.
Objdump
Onjdump can display information about a target file, and you can control what is displayed by parameters.
For example -p
, you can display the contents of a file header, and grep
you can view dependent libraries.
1234 |
# objdump-p main|grep GLIBC00 glibc_2. 2.5 0 0 glibc_2. 3.2 0 0 glibc_2. 2.5 |
You can even view -T
the contents of a dynamic symbol table:
1234567891011121314 |
# objdump-t Main|grep GLIBC0000000000000000Do *und*0000000000000000Glibc_2.2.5StdErr0000000000000000Do *und*0000000000000000Glibc_2.2.5Fwrite0000000000000000Do *und*0000000000000000Glibc_2.2.5vfprintf0000000000000000Do *und*0000000000000000Glibc_2.2.5Fputc0000000000000000Do *und*0000000000000000Glibc_2.2.5Abort0000000000000000Do *und*0000000000000000Glibc_2.2.5Pthread_mutex_lock0000000000000000Do *und*0000000000000000Glibc_2.3.2Pthread_cond_wait0000000000000000Do *und*0000000000000000Glibc_2.2.5Pthread_mutex_unlock0000000000000000Do *und*0000000000000000Glibc_2.3.2Pthread_cond_broadcast0000000000000000Do *und*0000000000000000Glibc_2.2.5Pthread_create0000000000000000Do *und*0000000000000000Glibc_2.2.5Nanosleep0000000000000000Do *und*0000000000000000Glibc_2.2.5Pthread_detach ... |
Nm
NM Displays the symbol for the target file.
12345678910111213141516171819202122 |
# nm Go/bin/glide |more0000000000908680R Andmask0000000000901d00 R Bswapmask00000000009036C0 R Bswap_shufb_ctl0000000000B000e0 B Bufio. Erradvancetoofar0000000000B000f0 B Bufio. Errbufferfull0000000000b00100 B Bufio. Errfinaltoken0000000000b00110 B Bufio. Errinvalidunreadbyte0000000000b00120 B Bufio. Errinvalidunreadrune0000000000b00130 B Bufio. Errnegativeadvance0000000000b00140 B Bufio. Errnegativecount0000000000b00160 B Bufio.errnegativeread0000000000b00170 B Bufio.errnegativewrite0000000000b00150 B Bufio. Errtoolong00000000004d9140 T Bufio.init0000000000b21120 B Bufio.initdone.00000000004d6510 T Bufio. (*reader). Buffered00000000004D59d0 T Bufio. (*reader). Discard00000000004d5590 T Bufio. (*reader). Fill00000000004D57c0 T Bufio. (*reader). Peek00000000004D5b70 T Bufio. (*reader). Read ... |
Strings
strings displays the printable characters in the file.
1234 |
# strings Main|grep GLIBC Glibc_2. 2.5 Glibc_2. 3.2 Glibc_2. 2.5 |
Strip
With the tools above, you can analyze the dependencies of a file, and create a docker image by simply adding the required dependencies in the library.
If the program itself is larger, you can compress the program, removing some data that you do not need, such as using strip
to crop.
You can control which symbols you want to discard by using parameters.
For example, remove symbol table and line number information: