Symbol addresses in ELF - symbols

I am trying to read ELF symbol table.
I am facing following discrepancy in shared libraries and can't understand the reason behind it.
For libc, using readelf i got following output.
Num: Value Size Type Bind Vis Ndx Name
7: 00000033c32160b0 146 FUNC WEAK DEFAULT 11 realloc##GLIBC_2.2.5
8: 00000033c3421000 4 OBJECT WEAK DEFAULT 21 _dl_starting_up##GLIBC_PRIVATE
9: 00000033c32118f0 382 FUNC GLOBAL DEFAULT 11 _dl_allocate_tls##GLIBC_PRIVATE
10: 00000033c3421280 40 OBJECT GLOBAL DEFAULT 21 _r_debug##GLIBC_2.2.5
11: 00000033c341fdc8 8 OBJECT GLOBAL DEFAULT 17 __libc_stack_end##GLIBC_2.2.5
12: 00000033c3215f30 252 FUNC WEAK DEFAULT 11 __libc_memalign##GLIBC_2.2.5
13: 00000033c3211a70 140 FUNC GLOBAL DEFAULT 11 _dl_deallocate_tls##GLIBC_PRIVATE
14: 00000033c3216040 52 FUNC WEAK DEFAULT 11 calloc##GLIBC_2.2.5
15: 00000033c341fc88 8 OBJECT GLOBAL DEFAULT 17 _dl_argv##GLIBC_PRIVATE
16: 00000033c3211000 599 FUNC GLOBAL DEFAULT 11 _dl_mcount##GLIBC_2.2.5
and for my own shared library build using following commands
gcc -rdynamic -Wint-to-pointer-cast -g -fPIC -lpthread -c probes.c -ldl -lelf
gcc -shared -lpthread -Wl,--no-as-needed,-soname,libprobes.so.1 -o libprobes.so.1 mutrace.o -ldl -lelf
the output was
Num: Value Size Type Bind Vis Ndx Name
.
.
.
34: 00000000000040d0 66 FUNC GLOBAL DEFAULT 11 pthread_create
35: 0000000000001d72 109 FUNC GLOBAL DEFAULT 11 thread_local_init
36: 0000000000002b21 481 FUNC GLOBAL DEFAULT 11 trylock_ret_event
37: 00000000000030c4 652 FUNC GLOBAL DEFAULT 11 lock_init_event
38: 0000000000003e4d 130 FUNC GLOBAL DEFAULT 11 pthread_mutex_init
39: 0000000000004668 0 FUNC GLOBAL DEFAULT 12 _fini
40: 0000000000003dd0 125 FUNC GLOBAL DEFAULT 11 pthread_cond_timedwait
41: 0000000000001b03 92 FUNC GLOBAL DEFAULT 11 backtrace
42: 0000000000001b5f 94 FUNC GLOBAL DEFAULT 11 backtrace_symbols
43: 0000000000002ee3 481 FUNC GLOBAL DEFAULT 11 unlock_ret_event
44: 0000000000004026 95 FUNC GLOBAL DEFAULT 11 pthread_mutex_trylock
45: 0000000000003531 476 FUNC GLOBAL DEFAULT 11 lock_destroy_event
46: 0000000000004112 1012 FUNC GLOBAL DEFAULT 11 print_symtable
For libc the symbol values are absolute ( virtual address ) but in my library, the values are relative. What decides this behaviour ?
I have tried following the information from http://docs.oracle.com/cd/E19082-01/819-0690/chapter6-35166/index.html , but latter when i checked the ELF header, both the libraries had same type.

for my own shared library build using following commands
gcc -rdynamic -Wint-to-pointer-cast -g -fPIC -lpthread -c probes.c -ldl -lelf
gcc -shared -lpthread -Wl,--no-as-needed,-soname,libprobes.so.1 -o libprobes.so.1
These commands are incorrect. The first one is a compilation command (because of -c flag). The linker options (-rdynamic, -lpthread, etc.) don't belong on it.
The second command is link command, and has the wrong library order. In addition, you forgot to actually use probes.o that you compiled. This would be better:
gcc -shared -o libprobes.so.1 -Wl,-soname=libprobes.so.1 probes.o -lpthread
For libc the symbol values are absolute
No, they are not. Your libc has apparently been prelinked at address 0x33c3210000 (or similar). That doesn't make the symbols absolute. You can undo prelinking (read man prelink) and you'll see similar "relative" addresses in libc.so.6.

Related

How to resolve the error like ‘atos cannot load symbols for the file APP for architecture armv7’? [duplicate]

I'm looking at a crash report provided by Apple
Hardware Model: iPhone4,1
Version: ??? (???)
Code Type: ARM (Native)
Parent Process: launchd [1]
Date/Time: 2012-11-18 16:03:44.951 -0600
OS Version: iOS 6.0.1 (10A523)
Report Version: 104
Exception Type: EXC_BAD_ACCESS (SIGSEGV)
Exception Codes: KERN_INVALID_ADDRESS at 0x51fe5264
Crashed Thread: 0
Thread 0 name: Dispatch queue: com.apple.main-thread
Thread 0 Crashed:
0 libobjc.A.dylib 0x352925b0 objc_msgSend + 16
1 MYAPP 0x0006573a -[MyViewController(Images) didReceiveImage:context:etag:expires:] + 42
2 MYAPP 0x0004fb26 -[MyImageTask didReceiveImage:] + 98
3 Foundation 0x361ac8e8 __NSThreadPerformPerform
4 CoreFoundation 0x3b37d680 __CFRUNLOOP_IS_CALLING_OUT_TO_A_SOURCE0_PERFORM_FUNCTION__
5 CoreFoundation 0x3b37cee4 __CFRunLoopDoSources0
6 CoreFoundation 0x3b37bcb2 __CFRunLoopRun
7 CoreFoundation 0x3b2eeeb8 CFRunLoopRunSpecific
8 CoreFoundation 0x3b2eed44 CFRunLoopRunInMode
9 GraphicsServices 0x396bc2e6 GSEventRunModal
10 UIKit 0x3452e2f4 UIApplicationMain
11 MYAPP 0x0004934a main + 70
12 MYAPP 0x000492fc start + 36
The funny thing is when I use atos to lookup the line of code that corresponds to address locations 0x0006573a and 0x0004fb26 I get completely different match. The atos output is not even from the same class that's mentioned in the crash log (MyViewController, MyImageTask). Instead atos points me to totally benign lines of code in a completely unrelated class. I verified again that I'm working with the exact dSYM and IPA that I submitted to Apple.
My atos command
/Applications/Xcode.app/Contents/Developer/usr/bin/atos -arch armv7 -o MYAPP.app/MYAPP 0x0004fb26
Same result with /usr/bin/atos and for armv7s.
Has anyone else experienced this issue? Can you please advise? Thanks.
A simpler alternative: you can use the atos -l flag to make it do the maths for you.
Say you've got the following line in your crash log that you want to symbolicate:
5 MyApp 0x0044e89a 0x29000 + 4348058
The first hex number is the stack address, and the second hex number is the load address. You can ignore the last number. You don't need to worry about slide addresses either.
To symbolicate, do the following:
atos -o MyApp.app/MyApp -arch armv7 -l 0x29000 0x0044e89a
If you can't find your MyApp.app/MyApp file, rename your '.ipa' file to a '.zip', unzip it, and it'll be in the Payload folder.
And if you're not sure which architecture to use (for example, armv7 or armv7s), scroll to the 'Binary Images' part of the crash file and you can find it in there.
Cheers
You have to calculate the address to use with atos, you can't just use the one in the stacktrace.
symbol address = slide + stack address - load address
The slide value is the value of vmaddr in LC_SEGMENT cmd (Mostly this is 0x1000). Run the following to get it:
otool -arch ARCHITECTURE -l "APP_BUNDLE/APP_EXECUTABLE" | grep -B 3 -A 8 -m 2 "__TEXT"
Replace ARCHITECTURE with the actual architecture the crash report shows, e.g. armv7.
Replace APP_BUNDLE/APP_EXECUTABLE with the path to the actual executable.
The stack address is the hex value from the crash report.
The load address can be is the first address showing in the Binary Images section at the very front of the line which contains your executable. (Usually the first entry).
Since in the past value of the slide was equal to value of the load address this always worked. But since Apple introduced Address space layout randomization beginning with iOS 4.3 (in different variations), the apps loading address is randomized for security reasons.
Simply use dwarfdump:
dwarfdump --arch armv7 myApp.dSYM --lookup 0xaabbccdd | grep 'Line table'
No need to do any calculations at all.
(From Get symbol by address (symbolicating binary, iOS build)).
For whom that certain times doesn't have the value for Load Address like this:
Jan 14 11:02:39 Dennins-iPhone AppName[584] <Critical>: Stack Trace: (
0 CoreFoundation 0x2c3084b7 <redacted> + 150
1 libobjc.A.dylib 0x39abec8b objc_exception_throw + 38
2 CoreFoundation 0x2c21cc35 CFRunLoopRemoveTimer + 0
3 AppName 0x0005a7db AppName + 272347
I've created a simple bash to help me debug:
#! /bin/bash
read -p "[Path] [App Name] [Stack Address] [DecimalSum] " path appName stackAddress decimalSum
loadAddress=`echo "obase=16;ibase=10;$((stackAddress-decimalSum))" | bc`
atos -o $path/Payload/$appName.app/$appName -l $loadAddress $stackAddress -arch armv7
It just reads the path for the app, the app name, the stack address, and the value after "+" signal (the decimal value) and then find the value for load address to run atos command.

690mb memory overhead for openmp program compiled with ifort

I was running some tests using openmp and fortran and came to realize that a binary compiled with ifort 15 (15.0.0 20140723) has 690MB of virtual memory overhead.
My sample program is:
program sharedmemtest
use omp_lib
implicit none
integer :: nroot1
integer, parameter :: dp = selected_real_kind(14,200)
real(dp),allocatable :: matrix_elementsy(:,:,:,:)
!$OMP PARALLEL NUM_THREADS(10) SHARED(matrix_elementsy)
nroot1=2
if (OMP_GET_THREAD_NUM() == 0) then
allocate(matrix_elementsy(nroot1,nroot1,nroot1,nroot1))
print *, "after allocation"
read(*,*)
end if
!$OMP BARRIER
!$OMP END PARALLEL
end program
running
ifort -openmp test_openmp_minimal.f90 && ./a.out
shows a memory usage of
50694 user 20 0 694m 8516 1340 S 0.0 0.0 0:03.58 a.out
in top. Running
gfortran -fopenmp test_openmp_minimal.f90 && ./a.out
shows a memory usage of
50802 user 20 0 36616 956 740 S 0.0 0.0 0:00.98 a.out
Where is the 690MB of overhead coming from when compiling with ifort? Am I doing something wrong? Or is this a bug in ifort?
For completeness: This is a minimal example taken from a much larger program. I am using gfortran 4.4 (4.4.7 20120313).
I appreciate all comments and ideas.
I don't believe top is reliable here. I do not see any evidence that the binary created from your test allocates anywhere near that much memory.
Below I have shown the result of generating the binary normally, with the Intel libraries linked statically and with everything linked statically. The static binary is in the ballpark of 2-3 megabytes.
It is possible that OpenMP thread stacks, which I believe are allocated from the heap, could be the source of the addition virtual memory here. Can you try this test with OMP_STACKSIZE=4K? I think the default is a few megabytes.
Dynamic Executable
jhammond#cori11:/tmp> ifort -O3 -qopenmp smt.f90 -o smt
jhammond#cori11:/tmp> size smt
text data bss dec hex filename
748065 13984 296024 1058073 102519 smt
jhammond#cori11:/tmp> ldd smt
linux-vdso.so.1 => (0x00002aaaaaaab000)
libm.so.6 => /lib64/libm.so.6 (0x00002aaaaab0c000)
libiomp5.so => /opt/intel/parallel_studio_xe_2016.0.047/compilers_and_libraries_2016.0.109/linux/compiler/lib/intel64/libiomp5.so (0x00002aaaaad86000)
libpthread.so.0 => /lib64/libpthread.so.0 (0x00002aaaab0c7000)
libc.so.6 => /lib64/libc.so.6 (0x00002aaaab2e4000)
libgcc_s.so.1 => /opt/gcc/5.1.0/snos/lib64/libgcc_s.so.1 (0x00002aaaab661000)
libdl.so.2 => /lib64/libdl.so.2 (0x00002aaaab878000)
/lib64/ld-linux-x86-64.so.2 (0x0000555555554000)
Dynamic Executable with Static Intel
jhammond#cori11:/tmp> ifort -O3 -qopenmp smt.f90 -static-intel -o smt
jhammond#cori11:/tmp> size smt
text data bss dec hex filename
1608953 41420 457016 2107389 2027fd smt
jhammond#cori11:/tmp> ls -l smt
-rwxr-x--- 1 jhammond jhammond 1872489 Jan 12 05:51 smt
Static Executable
jhammond#cori11:/tmp> ifort -O3 -qopenmp smt.f90 -static -o smt
jhammond#cori11:/tmp> size smt
text data bss dec hex filename
2262019 43120 487320 2792459 2a9c0b smt
jhammond#cori11:/tmp> ldd smt
not a dynamic executable

Dynamic library size bigger than static library and sum of linked objects size, how comes?

[See edit, it seems the extra size comes from debugging symbols added at linking time, but the reason why this happens is still unclear!]
I am cross compiling OpenCV 2.4.11 Ubuntu x86 64bit -> armeabi.
I am using the toolchain available here https://developer.android.com/tools/sdk/ndk/index.html, choosing the 4.9 compiler.
When I compile the dynamic libraries, they get considerably bigger than the static library. Examples:
3793082 Mar 12 17:21 libopencv_core.a
6131716 Mar 12 17:29 libopencv_core.so
446060 Mar 12 17:22 libopencv_highgui.a
5510352 Mar 12 17:30 libopencv_highgui.so
3477794 Mar 12 17:21 libopencv_imgproc.a
5325504 Mar 12 17:29 libopencv_imgproc.so
38004 Mar 12 17:19 libopencv_info.so
844990 Mar 12 17:21 libopencv_ml.a
3827136 Mar 12 17:29 libopencv_ml.so
747744 Mar 12 17:22 libopencv_objdetect.a
2370188 Mar 12 17:30 libopencv_objdetect.so
405920 Mar 12 17:22 libopencv_video.a
2196268 Mar 12 17:30 libopencv_video.so
For the static library the size corresponds more or less to the total size of the object files. Example for core and highgui.
du -chs `find -iname \*.o|grep opencv_core.dir`
[...]
3,5M total
du -chs `find -iname \*.o|grep opencv_highgui.dir`
[...]
352K total
The same happens if I build with make or ninja.
There is just a small difference in the compiler flags at build time, but if I check the object files generated for the static and the dynamic build, they have exactly the same size. That's the command I use to generate such a list:
ls -s `find -iname \*.o`|grep core
So, I thought, it must something in the linking phase. I took a look at the build.ninja file differences, and these are lines present only for the shared version:
LINK_FLAGS = -llog -Wl,--fix-cortex-a8 -Wl,--no-undefined -Wl,--gc-sections -Wl,-z,noexecstack -Wl,-z,relro -Wl,-z,now
LINK_LIBRARIES = lib/libopencv_features2d.so -ldl -lm -llog -ltbb lib/libopencv_flann.so lib/libopencv_highgui.so lib/libopencv_imgproc.so lib/libopencv_core.so
I do not think the additional libraries linked (dl, m, log, tbb) influence the final size, as they are all much smaller than the difference I found. Furthermore, I started to verify and for log there's only the .so available, and for tbb (100Kb) I have both shared and static version. BTW, I tried to build also without tbb.
To be 100% sure, I took the actual command line that was linking the object file, removed the -no-undefined option, and then removed all other options and linked libraries. The file size did not change, apart from when removing -Wl,--gc-sections which caused the file size to increase (it's some garbage collection option).
So, the only option that is left is a... linker bug?!? Does anybody have any idea what is happening?
Some additional information:
Compiler details:
./arm-linux-androideabi-gcc -v
Using built-in specs.
COLLECT_GCC=./arm-linux-androideabi-gcc
COLLECT_LTO_WRAPPER=/opt/toolchain-arm17/bin/../libexec/gcc/arm-linux-androideabi/4.9/lto-wrapper
Target: arm-linux-androideabi
Configured with: /s/ndk-toolchain/src/build/../gcc/gcc-4.9/configure --prefix=/tmp/ndk-andrewhsieh/build/toolchain/prefix --target=arm-linux-androideabi --host=x86_64-linux-gnu --build=x86_64-linux-gnu --with-gnu-as --with-gnu-ld --enable-languages=c,c++ --with-gmp=/tmp/ndk-andrewhsieh/build/toolchain/temp-install --with-mpfr=/tmp/ndk-andrewhsieh/build/toolchain/temp-install --with-mpc=/tmp/ndk-andrewhsieh/build/toolchain/temp-install --with-cloog=/tmp/ndk-andrewhsieh/build/toolchain/temp-install --with-isl=/tmp/ndk-andrewhsieh/build/toolchain/temp-install --with-ppl=/tmp/ndk-andrewhsieh/build/toolchain/temp-install --disable-ppl-version-check --disable-cloog-version-check --disable-isl-version-check --enable-cloog-backend=isl --with-host-libstdcxx='-static-libgcc -Wl,-Bstatic,-lstdc++,-Bdynamic -lm' --disable-libssp --enable-threads --disable-nls --disable-libmudflap --disable-libgomp --disable-libstdc__-v3 --disable-sjlj-exceptions --disable-shared --disable-tls --disable-libitm --with-float=soft --with-fpu=vfp --with-arch=armv5te --enable-target-optspace --enable-initfini-array --disable-nls --prefix=/tmp/ndk-andrewhsieh/build/toolchain/prefix --with-sysroot=/tmp/ndk-andrewhsieh/build/toolchain/prefix/sysroot --with-binutils-version=2.24 --with-mpfr-version=3.1.1 --with-mpc-version=1.0.1 --with-gmp-version=5.0.5 --with-gcc-version=4.9 --with-gdb-version=7.6 --with-python=/usr/local/google/home/andrewhsieh/mydroid/ndk/prebuilt/linux-x86_64/bin/python-config.sh --with-gxx-include-dir=/tmp/ndk-andrewhsieh/build/toolchain/prefix/include/c++/4.9 --with-bugurl=http://source.android.com/source/report-bugs.html --enable-languages=c,c++ --disable-bootstrap --enable-plugins --enable-libgomp --disable-libsanitizer --enable-gold --enable-graphite=yes --with-cloog-version=0.18.0 --with-isl-version=0.11.1 --enable-eh-frame-hdr-for-static --with-arch=armv5te --program-transform-name='s&^&arm-linux-androideabi-&' --enable-gold=default
Thread model: posix
gcc version 4.9 20140827 (prerelease) (GCC)
I also tried to see what would happen trying another version of the linker, but no changes in size
arm-linux-androideabi-g++.exe -v
Using built-in specs.
COLLECT_GCC=arm-linux-androideabi-g++.exe
COLLECT_LTO_WRAPPER=lto-wrapper.exe
Target: arm-linux-androideabi
Configured with: /s/ndk-toolchain/src/build/../gcc/gcc-4.8/configure --prefix=/tmp/ndk-andrewhsieh/build/toolchain/prefix --target=arm-linux-androideabi --host=x86_64-pc-mingw32msvc --build=x86_64-lin
ux-gnu --with-gnu-as --with-gnu-ld --enable-languages=c,c++ --with-gmp=/tmp/ndk-andrewhsieh/build/toolchain/temp-install --with-mpfr=/tmp/ndk-andrewhsieh/build/toolchain/temp-install --with-mpc=/tmp/n
dk-andrewhsieh/build/toolchain/temp-install --with-cloog=/tmp/ndk-andrewhsieh/build/toolchain/temp-install --with-isl=/tmp/ndk-andrewhsieh/build/toolchain/temp-install --with-ppl=/tmp/ndk-andrewhsieh/
build/toolchain/temp-install --disable-ppl-version-check --disable-cloog-version-check --disable-isl-version-check --enable-cloog-backend=isl --with-host-libstdcxx='-static-libgcc -Wl,-Bstatic,-lstdc+
+,-Bdynamic -lm' --disable-libssp --enable-threads --disable-nls --disable-libmudflap --disable-libgomp --disable-libstdc__-v3 --disable-sjlj-exceptions --disable-shared --disable-tls --disable-libitm
--with-float=soft --with-fpu=vfp --with-arch=armv5te --enable-target-optspace --enable-initfini-array --disable-nls --prefix=/tmp/ndk-andrewhsieh/build/toolchain/prefix --with-sysroot=/tmp/ndk-andrew
hsieh/build/toolchain/prefix/sysroot --with-binutils-version=2.24 --with-mpfr-version=3.1.1 --with-mpc-version=1.0.1 --with-gmp-version=5.0.5 --with-gcc-version=4.8 --with-gdb-version=7.6 --with-pytho
n=/usr/local/google/home/andrewhsieh/mydroid/ndk/prebuilt/windows-x86_64/bin/python-config.sh --with-gxx-include-dir=/tmp/ndk-andrewhsieh/build/toolchain/prefix/include/c++/4.8 --with-bugurl=http://so
urce.android.com/source/report-bugs.html --enable-languages=c,c++ --disable-bootstrap --enable-plugins --enable-libgomp --disable-libsanitizer --enable-gold --enable-graphite=yes --with-cloog-version=
0.18.0 --with-isl-version=0.11.1 --enable-eh-frame-hdr-for-static --with-arch=armv5te --program-transform-name='s&^&arm-linux-androideabi-&' --enable-gold=default
Thread model: posix
gcc version 4.8 (GCC)
EDIT:
As suggested by MarcB, I tried to strip the library. The result is suprising (to me :) )
$ arm-linux-androideabi/bin/strip -g libopencv_core.so -o libopencv_core_stripped.so
$ ls -la *core*
6293308 Mar 13 10:40 libopencv_core.so
3224840 Mar 13 12:18 libopencv_core_stripped.so
Where did all those debug symbols came out if the object files where compiled without -g (or even with -g0)?
Note: the library stripped like that seem to be fully functional. The nm -D output of the stripped/unstripped library are the same, and nm output is just a few lines smaller (like 50 lines less out of 12000).
Just to be sure, I tried also to strip objects before linking, but their file does not change (it increases just a bit), and linking the "stripped" object files produces a library of the same big size of before.
Those are not debug symbols. They are regular linker symbols.
A shared library may have two sets of symbols: one is for linking, the other one is for dynamic loading. strip removes the first kind of symbols. You cannot link with a stripped shared library, but you can load it at run time normally (e.g if you use dlopen, or link with the library then strip it).
See nm yourlib.so and nm -D yourlib.so both before and after running strip.
CORRECTION it is possible to link with a stripped library. A good explanation about the two kinds of symbol tables is here.

Application Loader error, binary is invalid

When i try to send my app to App Store, i'm getting this error:
The binary is invalid. The encryption info in the LC_ENCRYPTION_INFO load command is either missing or invalid, or the binary is already encrypted. This binary does not seems to have been built whit Apple's linker.
i don't know where is the error in my app
I had the same problem.
My solution :
Remove arm64 from Valid Architectures, the last IPA that I uploaded didn't have arm64 so I compared the LC_ENCRYPTION_INFO
I used this command to get LC_ENCRYPTION_INFO
otool -arch all -Vl YOURAPP.app/YOURAPP | grep -A5 LC_ENCRYP
Result with ARM64:
    
      cmd LC_ENCRYPTION_INFO
      cmdsize 20
    cryptoff  16384
    cryptsize 2375680
    cryptid   0
Load command 13
--
          cmd LC_ENCRYPTION_INFO
      cmdsize 20
    cryptoff  16384
    cryptsize 2375680
    cryptid   0
Load command 13
--
          cmd LC_ENCRYPTION_INFO_64
      cmdsize 24
    cryptoff  16384
    cryptsize 2801664
    cryptid   0
        pad   0
Result without ARM64
cmd LC_ENCRYPTION_INFO
cmdsize 20
cryptoff 16384
cryptsize 2375680
cryptid 0
Load command 13
--
cmd LC_ENCRYPTION_INFO
cmdsize 20
cryptoff 16384
cryptsize 2375680
cryptid 0
Load command 13
I hope this will help you, if someone know why remove ARM64 help to resolve this, the response interest me too.

How to measure the code (i.e. data + text) size of a static library?

I've looked on SO for an answer to this, but didn't find one. I have a large static library - it still has all its symbols so its huge. What I'd like to know is what the actual code size it consumes when linked into an app and stripped.
The library also all current architectures lipoed into it, so really what I need is the code (i.e. data + text) for each architecture.
I posted this originally because I was curious, but a client really wanted to know today so I had to dig. Turns out that there is a CLI command size that can help:
$ size -arch arm64 myLib.a
__TEXT __DATA __OBJC others dec hex
18436 7156 0 42642 68234 10a8a myLib.a(a.o)
1659 528 0 7209 9396 24b4 myLib.a(b.o)
...
Wow - that "others" looks really huge. Wonder what's in it? Hmmm, try the -m option, and you get a really long output of each file in the library, and the size of each segment in the library.
When I use the -m option on my library, I get a slew of segments with prefix names of "__debug":
myLib.a(a.o):
Segment : 47665
Section (__TEXT, __text): 9832
Section (__DWARF, __debug_info): 9625
Section (__DWARF, __debug_abbrev): 867
Section (__DWARF, __debug_aranges): 64
Section (__DWARF, __debug_macinfo): 0
Section (__DWARF, __debug_line): 2142
Section (__DWARF, __debug_loc): 7237
Section (__DWARF, __debug_str): 4750
Section (__DWARF, __debug_ranges): 240
Section (__DATA, __data): 0
Section (__TEXT, __literal8): 16
...
Section (__DWARF, __apple_names): 2364
Section (__DWARF, __apple_objc): 196
Section (__DWARF, __apple_namespac): 36
Section (__DWARF, __apple_types): 1924
total 47652
total 47665
To get a value of what this code will consume when stripped in the final app, I need to get the full segment size and subtract out the size of all the "__debug" prefixed segments.
# Get the full size of all object files in the library
$ size -m -arch arm64 *.a | grep '^.total' | sed -n -e 's/^.total //p' | awk '{s+=$1} END {print s}'
381423
$
# Get the size of the debugging sections:
$ size -m -arch arm64 *.a | grep __debug_ | sed -n -e 's/^.*: //p' | awk '{s+=$1} END {print s}'
212702
$
The total is thus 381423 - 212702 = 168721 # more or less
PS: awk script from This SO post

Resources