Scenario: Running a debootstrapped Ubuntu 11.4 lxc guest on a Ubuntu 12.4 lxc host (both 64 bit)
Inside the lxc guest, rsyslogd is constantly crashing with SIGABRT stating:
libgcc_s.so.1 must be installed for pthread_cancel to work
0334.380551272:7f4128a84700:
Signal 6 (SIGABRT) occured, execution must be terminated.
I'm not sure why libgcc_s.so.1 cannot be found. If I run ldconfig -p:
$# ldconfig -p | grep libgcc
libgcc_s.so.1 (libc6,x86-64) => /lib/x86_64-linux-gnu/libgcc_s.so.1
libgcc_s.so.1 (libc6) => /usr/lib32/libgcc_s.so.1
It is listed. And both of those links are valid.
How do I resolve this problem?
EDIT: objdump -T output by request:
/lib/x86_64-linux-gnu/libgcc_s.so.1: file format elf64-x86-64
DYNAMIC SYMBOL TABLE:
00000000000025d8 l d .init 0000000000000000 .init
0000000000000000 DF *UND* 0000000000000000 GLIBC_2.2.5 memset
0000000000000000 DF *UND* 0000000000000000 GLIBC_2.2.5 abort
0000000000000000 w D *UND* 0000000000000000 __gmon_start__
0000000000000000 w D *UND* 0000000000000000 _Jv_RegisterClasses
0000000000000000 w D *UND* 0000000000000000 pthread_key_create
0000000000000000 DF *UND* 0000000000000000 GLIBC_2.2.5 malloc
0000000000000000 w D *UND* 0000000000000000 pthread_once
0000000000000000 DF *UND* 0000000000000000 GLIBC_2.2.5 free
0000000000000000 DF *UND* 0000000000000000 GLIBC_2.2.5 strlen
0000000000000000 w D *UND* 0000000000000000 pthread_getspecific
0000000000000000 w DF *UND* 0000000000000000 GLIBC_2.2.5 __cxa_finalize
0000000000000000 DF *UND* 0000000000000000 GLIBC_2.2.5 memcpy
0000000000000000 DF *UND* 0000000000000000 GLIBC_2.2.5 dl_iterate_phdr
0000000000000000 w D *UND* 0000000000000000 pthread_cancel
0000000000000000 DF *UND* 0000000000000000 GLIBC_2.2.5 calloc
0000000000000000 w DF *UND* 0000000000000000 GLIBC_2.2.5 pthread_mutex_lock
0000000000000000 DF *UND* 0000000000000000 GLIBC_2.2.5 realloc
0000000000000000 w DF *UND* 0000000000000000 GLIBC_2.2.5 pthread_mutex_unlock
0000000000000000 w D *UND* 0000000000000000 pthread_setspecific
0000000000002de0 g DF .text 0000000000000028 GCC_3.0 __mulvsi3
000000000000a8c0 g DF .text 000000000000034c GCC_4.3.0 __floatuntitf
000000000000c160 g DF .text 00000000000001cf GCC_4.3.0 __letf2
00000000000050a0 g DF .text 0000000000000223 GCC_3.0 __modti3
0000000000009530 g DF .text 0000000000000094 GCC_4.3.0 __unordtf2
0000000000004660 g DF .text 0000000000000007 GCC_4.3.0 __bswapdi2
0000000000004ea0 g DF .text 0000000000000045 GCC_4.2.0 __floatuntixf
0000000000011d80 g DF .text 000000000000017f GCC_4.3.0 __emutls_get_address
0000000000000000 g DO *ABS* 0000000000000000 GCC_3.0 GCC_3.0
0000000000006ac0 g DF .text 0000000000000a0f GCC_4.3.0 __divtf3
0000000000002b70 g DF .text 0000000000000032 GCC_3.0 __ucmpti2
0000000000000000 g DO *ABS* 0000000000000000 GCC_3.3 GCC_3.3
0000000000000000 g DO *ABS* 0000000000000000 GCC_3.4 GCC_3.4
0000000000002ac0 g DF .text 0000000000000062 GCC_3.0 __ashrti3
0000000000002c60 g DF .text 000000000000002d GCC_3.0 __addvdi3
0000000000003270 g DF .text 0000000000000036 GCC_3.4 __paritydi2
0000000000002cc0 g DF .text 0000000000000042 GCC_3.4.4 __addvti3
00000000000032b0 g DF .text 0000000000000039 GCC_3.4 __parityti2
00000000000098b0 g DF .text 00000000000000ee GCC_4.3.0 __floatsitf
0000000000002a60 g DF .text 000000000000005f GCC_3.0 __ashlti3
000000000000f830 g DF .text 00000000000000e5 GCC_3.0 _Unwind_Resume
000000000000fa40 g DF .text 00000000000000ab GCC_3.3 _Unwind_Backtrace
0000000000000000 g DO *ABS* 0000000000000000 GCC_3.4.2 GCC_3.4.2
00000000000036a0 g DF .text 00000000000002e7 GCC_4.0.0 __muldc3
000000000000cb30 g DF .text 0000000000000630 GCC_4.3.0 __multc3
000000000000cb30 g DF .text 0000000000000630 (GCC_4.0.0) __multc3
0000000000000000 g DO *ABS* 0000000000000000 GCC_3.4.4 GCC_3.4.4
00000000000029d0 g DF .text 0000000000000026 GCC_3.0 __negti2
000000000000c330 g DF .text 0000000000000132 GCC_4.3.0 __eqtf2
0000000000003340 g DF .text 000000000000004d GCC_4.0.0 __powidf2
000000000000d160 g DF .text 00000000000000a7 GCC_4.3.0 __powitf2
0000000000003180 g DF .text 0000000000000009 GCC_3.4 __clzdi2
000000000000d160 g DF .text 00000000000000a7 (GCC_4.0.0) __powitf2
0000000000003190 g DF .text 0000000000000022 GCC_3.4 __clzti2
00000000000052d0 g DF .text 0000000000000113 GCC_3.0 __udivti3
0000000000009e00 g DF .text 00000000000000fe GCC_4.3.0 __floatditf
000000000000b540 g DF .text 000000000000052f GCC_4.3.0 __trunctfdf2
0000000000004b10 g DF .text 00000000000000ca GCC_3.0 __floattisf
0000000000009c80 g DF .text 0000000000000173 GCC_4.3.0 __fixunstfdi
000000000000ac10 g DF .text 0000000000000172 GCC_4.3.0 __extendsftf2
000000000000d6a0 g DF .text 0000000000000008 GCC_3.0 _Unwind_GetLanguageSpecificData
000000000000d6c0 g DF .text 0000000000000023 GCC_3.3 _Unwind_FindEnclosingFunction
000000000000d670 g DF .text 0000000000000015 GCC_4.2.0 _Unwind_GetIPInfo
000000000000a2a0 g DF .text 000000000000024a GCC_4.3.0 __fixunstfti
00000000000112c0 g DF .text 0000000000000132 GCC_3.0 __deregister_frame_info_bases
0000000000003150 g DF .text 0000000000000010 GCC_3.0 __ffsdi2
0000000000003160 g DF .text 000000000000001e GCC_3.0 __ffsti2
00000000000047c0 g DF .text 0000000000000039 GCC_3.0 __fixxfti
000000000000d6f0 g DF .text 0000000000000008 GCC_3.0 _Unwind_GetDataRelBase
0000000000004070 g DF .text 00000000000002ef GCC_4.0.0 __divdc3
000000000000c470 g DF .text 00000000000006b1 GCC_4.3.0 __divtc3
000000000000c470 g DF .text 00000000000006b1 (GCC_4.0.0) __divtc3
0000000000000000 g DO *ABS* 0000000000000000 GCC_4.2.0 GCC_4.2.0
0000000000002dc0 g DF .text 0000000000000020 GCC_3.0 __mulvdi3
0000000000002c00 g DF .text 000000000000001b GCC_3.0 __absvsi2
0000000000002e10 g DF .text 000000000000028c GCC_3.4.4 __mulvti3
00000000000112a0 g DF .text 000000000000001a GCC_3.0 __register_frame_table
0000000000008170 g DF .text 00000000000013ba GCC_4.3.0 __subtf3
000000000000af30 g DF .text 000000000000016b GCC_4.3.0 __extendxftf2
0000000000003990 g DF .text 0000000000000413 GCC_4.0.0 __mulxc3
0000000000007e30 g DF .text 000000000000033e GCC_4.3.0 __negtf2
0000000000011210 g DF .text 0000000000000072 GCC_3.0 __register_frame_info_table_bases
0000000000003390 g DF .text 000000000000005f GCC_4.0.0 __powixf2
0000000000004be0 g DF .text 00000000000000ca GCC_3.0 __floattidf
000000000000d6b0 g DF .text 0000000000000008 GCC_3.0 _Unwind_GetRegionStart
000000000000a4f0 g DF .text 00000000000003c1 GCC_4.3.0 __floattitf
0000000000004cb0 g DF .text 000000000000002d GCC_3.0 __floattixf
000000000000ba70 g DF .text 0000000000000503 GCC_4.3.0 __trunctfxf2
0000000000011440 g DF .text 00000000000001fd GCC_3.0 _Unwind_Find_FDE
000000000000d690 g DF .text 0000000000000008 GCC_3.0 _Unwind_SetIP
00000000000053f0 g DF .text 000000000000018e GCC_3.0 __umodti3
000000000000d660 g DF .text 0000000000000008 GCC_3.0 _Unwind_GetIP
00000000000046d0 g DF .text 000000000000006b GCC_3.0 __fixunsxfdi
0000000000011130 g DF .text 000000000000009a GCC_3.0 __register_frame_info_bases
0000000000004940 g DF .text 00000000000001ce GCC_3.0 __fixunsxfti
0000000000004360 g DF .text 00000000000002e6 GCC_4.0.0 __divxc3
0000000000002d40 g DF .text 000000000000002c GCC_3.0 __subvsi3
0000000000004740 g DF .text 0000000000000037 GCC_3.0 __fixsfti
00000000000057c0 g DF .text 00000000000012f7 GCC_4.3.0 __addtf3
0000000000000000 g DO *ABS* 0000000000000000 GCC_4.3.0 GCC_4.3.0
00000000000030d0 g DF .text 0000000000000024 GCC_3.0 __negvsi2
0000000000002bd0 g DF .text 0000000000000025 GCC_3.0 __absvdi2
0000000000002980 g DF .text 000000000000004c GCC_3.0 __multi3
000000000000fa20 g DF .text 000000000000001a GCC_3.0 _Unwind_DeleteException
0000000000002c20 g DF .text 0000000000000034 GCC_3.4.4 __absvti2
000000000000d600 g DF .text 0000000000000008 GCC_3.3 _Unwind_GetCFA
0000000000002a00 g DF .text 000000000000005f GCC_3.0 __lshrti3
0000000000002bc0 g DF .text 0000000000000002 GCC_3.4.2 __enable_execute_stack
00000000000031f0 g DF .text 000000000000002c GCC_3.4 __popcountdi2
0000000000000000 g DO *ABS* 0000000000000000 GCC_4.0.0 GCC_4.0.0
0000000000003220 g DF .text 0000000000000045 GCC_3.4 __popcountti2
0000000000002bb0 g DF .text 0000000000000002 GCC_3.0 __clear_cache
000000000000c330 g DF .text 0000000000000132 (GCC_3.0) __netf2
000000000000c330 g DF .text 0000000000000132 GCC_4.3.0 __netf2
0000000000004780 g DF .text 0000000000000040 GCC_3.0 __fixdfti
00000000000099a0 g DF .text 00000000000000db GCC_4.3.0 __floatunsitf
00000000000095d0 g DF .text 0000000000000190 GCC_4.3.0 __fixtfsi
0000000000002b30 g DF .text 0000000000000032 GCC_3.0 __cmpti2
000000000000ad90 g DF .text 0000000000000195 GCC_4.3.0 __extenddftf2
0000000000004650 g DF .text 0000000000000005 GCC_4.3.0 __bswapsi2
000000000000f5d0 g DF .text 000000000000016c GCC_3.0 _Unwind_RaiseException
0000000000009f00 g DF .text 00000000000000d3 GCC_4.3.0 __floatunditf
0000000000002c90 g DF .text 000000000000002c GCC_3.0 __addvsi3
0000000000004ce0 g DF .text 00000000000000d6 GCC_4.2.0 __floatuntisf
000000000000bf80 g DF .text 00000000000001df (GCC_3.0) __gttf2
000000000000bf80 g DF .text 00000000000001df GCC_4.3.0 __gttf2
0000000000011410 g DF .text 0000000000000021 GCC_3.0 __deregister_frame
0000000000000000 g DO *ABS* 0000000000000000 GCC_3.3.1 GCC_3.3.1
00000000000031c0 g DF .text 0000000000000005 GCC_3.4 __ctzdi2
0000000000004ef0 g DF .text 00000000000001ab GCC_3.0 __divti3
00000000000033f0 g DF .text 00000000000002a5 GCC_4.0.0 __mulsc3
00000000000031d0 g DF .text 000000000000001b GCC_3.4 __ctzti2
0000000000011290 g DF .text 0000000000000009 GCC_3.0 __register_frame_info_table
00000000000111e0 g DF .text 0000000000000026 GCC_3.0 __register_frame
00000000000032f0 g DF .text 000000000000004b GCC_4.0.0 __powisf2
000000000000bf80 g DF .text 00000000000001df GCC_4.3.0 __getf2
0000000000004670 g DF .text 000000000000002c GCC_3.0 __fixunssfdi
000000000000b0a0 g DF .text 000000000000049b GCC_4.3.0 __trunctfsf2
00000000000074d0 g DF .text 000000000000095f GCC_4.3.0 __multf3
000000000000f920 g DF .text 00000000000000f9 GCC_3.3 _Unwind_Resume_or_Rethrow
0000000000011f00 g DF .text 0000000000000035 GCC_4.3.0 __emutls_register_common
0000000000002d10 g DF .text 000000000000002d GCC_3.0 __subvdi3
0000000000004800 g DF .text 000000000000009f GCC_3.0 __fixunssfti
0000000000002d70 g DF .text 0000000000000042 GCC_3.4.4 __subvti3
0000000000009a80 g DF .text 00000000000001fc GCC_4.3.0 __fixtfdi
00000000000111d0 g DF .text 0000000000000009 GCC_3.0 __register_frame_info
00000000000030a0 g DF .text 000000000000002a GCC_3.0 __negvdi2
0000000000005590 g DF .text 000000000000022a GCC_3.0 __udivmodti4
000000000000c160 g DF .text 00000000000001cf (GCC_3.0) __lttf2
0000000000003100 g DF .text 000000000000004e GCC_3.4.4 __negvti2
000000000000c160 g DF .text 00000000000001cf GCC_4.3.0 __lttf2
00000000000046a0 g DF .text 0000000000000030 GCC_3.0 __fixunsdfdi
0000000000009fe0 g DF .text 00000000000002b6 GCC_4.3.0 __fixtfti
0000000000011400 g DF .text 0000000000000005 GCC_3.0 __deregister_frame_info
0000000000009760 g DF .text 000000000000014b GCC_4.3.0 __fixunstfsi
0000000000011800 g DF .text 000000000000045c GCC_3.3.1 __gcc_personality_v0
00000000000048a0 g DF .text 0000000000000097 GCC_3.0 __fixunsdfti
000000000000d610 g DF .text 0000000000000050 GCC_3.0 _Unwind_SetGR
0000000000004dc0 g DF .text 00000000000000d6 GCC_4.2.0 __floatuntidf
0000000000003db0 g DF .text 00000000000002b8 GCC_4.0.0 __divsc3
000000000000d5b0 g DF .text 0000000000000048 GCC_3.0 _Unwind_GetGR
000000000000d700 g DF .text 0000000000000008 GCC_3.0 _Unwind_GetTextRelBase
000000000000f740 g DF .text 00000000000000ef GCC_3.0 _Unwind_ForcedUnwind
/usr/lib32/libgcc_s.so.1: file format elf32-i386
DYNAMIC SYMBOL TABLE:
00000000 DF *UND* 00000000 GLIBC_2.0 abort
00000000 w D *UND* 00000000 __gmon_start__
00000000 w D *UND* 00000000 _Jv_RegisterClasses
00000000 DF *UND* 00000000 GLIBC_2.0 realloc
00000000 DF *UND* 00000000 GLIBC_2.0 calloc
00000000 w D *UND* 00000000 pthread_key_create
00000000 DF *UND* 00000000 GLIBC_2.0 memset
00000000 w D *UND* 00000000 pthread_once
00000000 DF *UND* 00000000 GLIBC_2.0 free
00000000 w D *UND* 00000000 pthread_getspecific
00000000 w DF *UND* 00000000 GLIBC_2.0 pthread_mutex_unlock
00000000 DF *UND* 00000000 GLIBC_2.0 memcpy
00000000 DF *UND* 00000000 GLIBC_2.0 strlen
00000000 DF *UND* 00000000 GLIBC_2.0 malloc
00000000 w DF *UND* 00000000 GLIBC_2.0 pthread_mutex_lock
00000000 w D *UND* 00000000 pthread_cancel
00000000 DF *UND* 00000000 GLIBC_2.2.4 dl_iterate_phdr
00000000 w DF *UND* 00000000 GLIBC_2.1.3 __cxa_finalize
00000000 w D *UND* 00000000 pthread_setspecific
00007c10 g DF .text 000001d0 GLIBC_2.0 __moddi3
00002450 g DF .text 00000038 GCC_3.0 __mulvsi3
0000c120 g DF .text 00000225 GCC_4.4.0 __letf2
000103e0 g DF .text 00000096 GCC_4.4.0 __unordtf2
000074b0 g DF .text 0000000f GCC_4.3.0 __bswapdi2
000187b0 g DF .text 000001a8 GCC_4.3.0 __emutls_get_address
00000000 g DO *ABS* 00000000 GCC_3.0 GCC_3.0
00002200 g DF .text 0000003d GCC_3.0 __ucmpdi2
0000a810 g DF .text 0000156b GCC_4.4.0 __divtf3
00002160 g DF .text 00000060 GCC_3.0 __ashrdi3
00015da0 g DF .text 000000d9 GLIBC_2.0 __frame_state_for
00000000 g DO *ABS* 00000000 GCC_3.3 GCC_3.3
00000000 g DO *ABS* 00000000 GCC_3.4 GCC_3.4
00002330 g DF .text 00000069 GCC_3.0 __addvdi3
000028d0 g DF .text 0000002f GCC_3.4 __paritydi2
00013490 g DF .text 00000033 GCC_4.4.0 __fabstf2
000020f0 g DF .text 00000061 GCC_3.0 __ashldi3
000109a0 g DF .text 000001e8 GCC_4.4.0 __floatsitf
00016100 g DF .text 000000e2 GCC_3.0 _Unwind_Resume
00016300 g DF .text 00000089 GCC_3.3 _Unwind_Backtrace
00000000 g DO *ABS* 00000000 GCC_3.4.2 GCC_3.4.2
00002fd0 g DF .text 00000408 GCC_4.0.0 __muldc3
00002050 g DF .text 00000031 GCC_3.0 __negdi2
000037e0 g DF .text 000018a8 GCC_4.4.0 __multc3
0000bd80 g DF .text 00000185 GCC_4.4.0 __eqtf2
00002960 g DF .text 00000054 GCC_4.0.0 __powidf2
00007950 g DF .text 0000002c GCC_3.0 __floatdidf
00002790 g DF .text 00000020 GCC_3.4 __clzdi2
00002a20 g DF .text 000001ad GCC_4.4.0 __powitf2
00007de0 g DF .text 00000104 GLIBC_2.0 __udivdi3
000112f0 g DF .text 00000210 GCC_4.4.0 __floatditf
00012720 g DF .text 0000067b GCC_4.4.0 __trunctfdf2
00007980 g DF .text 0000002c GCC_3.0 __floatdixf
00011050 g DF .text 00000294 GCC_4.4.0 __fixunstfdi
000116f0 g DF .text 0000039e GCC_4.4.0 __extendsftf2
00013980 g DF .text 0000000b GCC_3.0 _Unwind_GetLanguageSpecificData
000139a0 g DF .text 00000037 GCC_3.3 _Unwind_FindEnclosingFunction
00013950 g DF .text 00000016 GCC_4.2.0 _Unwind_GetIPInfo
000076b0 g DF .text 00000047 GCC_3.0 __fixxfdi
00017c20 g DF .text 0000010f GCC_3.0 __deregister_frame_info_bases
00002750 g DF .text 0000002f GCC_3.0 __ffsdi2
00000000 g DO *ABS* 00000000 GCC_4.5.0 GCC_4.5.0
000139e0 g DF .text 0000000b GCC_3.0 _Unwind_GetDataRelBase
000075a0 g DF .text 00000062 GCC_3.0 __fixunsxfsi
00005390 g DF .text 000002f9 GCC_4.0.0 __divdc3
00005990 g DF .text 00001b0f GCC_4.4.0 __divtc3
00000000 g DO *ABS* 00000000 GCC_4.2.0 GCC_4.2.0
00002490 g DF .text 000001fe GCC_3.0 __mulvdi3
00002260 g DF .text 00000033 GCC_3.0 __absvsi2
00017be0 g DF .text 00000033 GLIBC_2.0 __register_frame_table
0000dd70 g DF .text 00002668 GCC_4.4.0 __subtf3
00011ea0 g DF .text 00000293 GCC_4.5.0 __extendxftf2
000027f0 g DF .text 00000050 GCC_3.4 __popcountsi2
000033e0 g DF .text 000003f8 GCC_4.0.0 __mulxc3
0000d7c0 g DF .text 000005a9 GCC_4.4.0 __negtf2
00017b00 g DF .text 00000093 GCC_3.0 __register_frame_info_table_bases
000029c0 g DF .text 00000054 GCC_4.0.0 __powixf2
00013990 g DF .text 0000000b GCC_3.0 _Unwind_GetRegionStart
00012da0 g DF .text 000006ab GCC_4.4.0 __trunctfxf2
00017da0 g DF .text 000001de GCC_3.0 _Unwind_Find_FDE
00013970 g DF .text 0000000e GCC_3.0 _Unwind_SetIP
00007ef0 g DF .text 00000145 GLIBC_2.0 __umoddi3
00013940 g DF .text 0000000b GCC_3.0 _Unwind_GetIP
000027b0 g DF .text 00000009 GCC_3.4 __ctzsi2
000077e0 g DF .text 000000e0 GCC_3.0 __fixunsxfdi
00013450 g DF .text 0000003e GCC_4.4.0 __copysigntf3
000179c0 g DF .text 000000a7 GCC_3.0 __register_frame_info_bases
000079b0 g DF .text 00000059 GCC_4.2.0 __floatundisf
00005690 g DF .text 000002fb GCC_4.0.0 __divxc3
00007610 g DF .text 00000047 GCC_3.0 __fixsfdi
000023a0 g DF .text 0000003c GCC_3.0 __subvsi3
00008230 g DF .text 000025da GCC_4.4.0 __addtf3
00000000 g DO *ABS* 00000000 GCC_4.3.0 GCC_4.3.0
00002010 g DF .text 00000035 GCC_3.0 __muldi3
00002690 g DF .text 00000036 GCC_3.0 __negvsi2
000022a0 g DF .text 00000050 GCC_3.0 __absvdi2
000162e0 g DF .text 0000001f GCC_3.0 _Unwind_DeleteException
000074c0 g DF .text 00000062 GCC_3.0 __fixunssfsi
00002090 g DF .text 0000005f GCC_3.0 __lshrdi3
000138c0 g DF .text 0000000b GCC_3.3 _Unwind_GetCFA
00007660 g DF .text 00000047 GCC_3.0 __fixdfdi
00002250 g DF .text 00000005 GCC_3.4.2 __enable_execute_stack
00002840 g DF .text 0000005b GCC_3.4 __popcountdi2
00000000 g DO *ABS* 00000000 GCC_4.0.0 GCC_4.0.0
00002240 g DF .text 00000005 GCC_3.0 __clear_cache
0000bd80 g DF .text 00000185 GCC_4.4.0 __netf2
00010b90 g DF .text 000001a7 GCC_4.4.0 __floatunsitf
00010480 g DF .text 000002b2 GCC_4.4.0 __fixtfsi
000021c0 g DF .text 0000003d GCC_3.0 __cmpdi2
00011a90 g DF .text 00000401 GCC_4.4.0 __extenddftf2
00007530 g DF .text 00000062 GCC_3.0 __fixunsdfsi
000074a0 g DF .text 0000000a GCC_4.3.0 __bswapsi2
00007a10 g DF .text 00000037 GCC_4.2.0 __floatundidf
00015e90 g DF .text 0000018e GCC_3.0 _Unwind_RaiseException
00011500 g DF .text 000001e7 GCC_4.4.0 __floatunditf
000022f0 g DF .text 0000003c GCC_3.0 __addvsi3
000028a0 g DF .text 0000002a GCC_3.4 __paritysi2
00007a50 g DF .text 00000037 GCC_4.2.0 __floatundixf
0000bf10 g DF .text 00000206 GCC_4.4.0 __gttf2
00017d60 g DF .text 00000031 GLIBC_2.0 __deregister_frame
00000000 g DO *ABS* 00000000 GCC_3.3.1 GCC_3.3.1
00007a90 g DF .text 00000177 GLIBC_2.0 __divdi3
000027c0 g DF .text 00000025 GCC_3.4 __ctzdi2
00002bd0 g DF .text 000003f0 GCC_4.0.0 __mulsc3
00017ba0 g DF .text 0000003a GLIBC_2.0 __register_frame_info_table
00017ab0 g DF .text 00000042 GLIBC_2.0 __register_frame
00002900 g DF .text 00000054 GCC_4.0.0 __powisf2
00002780 g DF .text 0000000c GCC_3.4 __clzsi2
0000bf10 g DF .text 00000206 GCC_4.4.0 __getf2
00007700 g DF .text 0000006c GCC_3.0 __fixunssfdi
00012140 g DF .text 000005d4 GCC_4.4.0 __trunctfsf2
0000c350 g DF .text 0000146a GCC_4.4.0 __multf3
000161f0 g DF .text 000000e2 GCC_3.3 _Unwind_Resume_or_Rethrow
00018960 g DF .text 00000033 GCC_4.3.0 __emutls_register_common
000023e0 g DF .text 00000069 GCC_3.0 __subvdi3
00000000 g DO *ABS* 00000000 GLIBC_2.0 GLIBC_2.0
00010d40 g DF .text 0000030d GCC_4.4.0 __fixtfdi
00017a70 g DF .text 0000003a GLIBC_2.0 __register_frame_info
00002730 g DF .text 00000014 GCC_4.3.0 __ffssi2
00008050 g DF .text 000001d8 GCC_3.0 __udivmoddi4
000078c0 g DF .text 0000008f GCC_3.0 __floatdisf
000026d0 g DF .text 0000005a GCC_3.0 __negvdi2
00000000 g DO *ABS* 00000000 GCC_4.4.0 GCC_4.4.0
0000c120 g DF .text 00000225 GCC_4.4.0 __lttf2
00007770 g DF .text 0000006c GCC_3.0 __fixunsdfdi
00017d30 g DF .text 00000023 GLIBC_2.0 __deregister_frame_info
00010740 g DF .text 0000025a GCC_4.4.0 __fixunstfsi
000181d0 g DF .text 00000463 GCC_3.3.1 __gcc_personality_v0
000138d0 g DF .text 0000006d GCC_3.0 _Unwind_SetGR
00005090 g DF .text 000002f1 GCC_4.0.0 __divsc3
00013850 g DF .text 00000065 GCC_3.0 _Unwind_GetGR
000139f0 g DF .text 0000000b GCC_3.0 _Unwind_GetTextRelBase
00016020 g DF .text 000000d8 GCC_3.0 _Unwind_ForcedUnwind
This sounds somewhat similar to a reported bug with rsyslogd on ubuntu. If you run out of options then upgrading to a later version of rsyslogd might be the way to go. You may have to build it from source.
Just for reference:
maybe it caused by 64bit system maybe NOT. I'm NOT sure, but I met some similar problems before, I just use 32bit lib, it seems OK. However, I'm now moving to openSUSE-12.X, seems problem solved...
You need to install libgcc 32 bit. If you check under /libs you will find a x86_64-linux-gnu folder but not i386-linux-gnu. This is due to unavailability of 32 bit library in 64 bit machine. You need to execute command:
aptitude install libgcc1:i386
After that you will find the folder i386-linux-gnu is created in libs and libgcc_s.so.1 is existing under that. This should solve the problem.
Related
There is a remote 64-bit *nix server that can compile a user-provided code (which should be written in Rust, but I don't think it matters since it uses LLVM). I don't know which compiler/linker flags it uses, but the compiled ELF executable looks weird - it has 4 LOAD segments:
$ readelf -e executable
...
Program Headers:
Type Offset VirtAddr PhysAddr
FileSiz MemSiz Flags Align
...
LOAD 0x0000000000000000 0x0000000000000000 0x0000000000000000
0x0000000000004138 0x0000000000004138 R 0x1000
LOAD 0x0000000000005000 0x0000000000005000 0x0000000000005000
0x00000000000305e9 0x00000000000305e9 R E 0x1000
LOAD 0x0000000000036000 0x0000000000036000 0x0000000000036000
0x000000000000d808 0x000000000000d808 R 0x1000
LOAD 0x0000000000043da0 0x0000000000044da0 0x0000000000044da0
0x0000000000002290 0x00000000000024a0 RW 0x1000
...
On my own system all executables that I was looking at only have 2 LOAD segments:
Program Headers:
Type Offset VirtAddr PhysAddr
FileSiz MemSiz Flags Align
...
LOAD 0x0000000000000000 0x0000000000000000 0x0000000000000000
0x00000000003000c0 0x00000000003000c0 R E 0x200000
LOAD 0x00000000003002b0 0x00000000005002b0 0x00000000005002b0
0x00000000000776c8 0x000000000009b200 RW 0x200000
...
What are the circumstances (compiler/linker versions, flags etc) under which a compiler might build an ELF with 4 LOAD segments?
What is the point of having 4 LOAD segments? I imagine that having a segment with read but not execute permission might help against certain exploits, but why have two such segments?
A typical BFD-ld or Gold linked Linux executable has 2 loadable segments, with the ELF header merged with .text and .rodata into the first RE segment, and .data, .bss and other writable sections merged into the second RW segment.
Here is the typical section to segment mapping:
$ echo "int foo; int main() { return 0;}" | clang -xc - -o a.out-gold -fuse-ld=gold
$ readelf -Wl a.out-gold
Elf file type is EXEC (Executable file)
Entry point 0x400420
There are 9 program headers, starting at offset 64
Program Headers:
Type Offset VirtAddr PhysAddr FileSiz MemSiz Flg Align
PHDR 0x000040 0x0000000000400040 0x0000000000400040 0x0001f8 0x0001f8 R 0x8
INTERP 0x000238 0x0000000000400238 0x0000000000400238 0x00001c 0x00001c R 0x1
[Requesting program interpreter: /lib64/ld-linux-x86-64.so.2]
LOAD 0x000000 0x0000000000400000 0x0000000000400000 0x0006b0 0x0006b0 R E 0x1000
LOAD 0x000e18 0x0000000000401e18 0x0000000000401e18 0x0001f8 0x000200 RW 0x1000
DYNAMIC 0x000e28 0x0000000000401e28 0x0000000000401e28 0x0001b0 0x0001b0 RW 0x8
NOTE 0x000254 0x0000000000400254 0x0000000000400254 0x000020 0x000020 R 0x4
GNU_EH_FRAME 0x00067c 0x000000000040067c 0x000000000040067c 0x000034 0x000034 R 0x4
GNU_STACK 0x000000 0x0000000000000000 0x0000000000000000 0x000000 0x000000 RW 0x10
GNU_RELRO 0x000e18 0x0000000000401e18 0x0000000000401e18 0x0001e8 0x0001e8 RW 0x8
Section to Segment mapping:
Segment Sections...
00
01 .interp
02 .interp .note.ABI-tag .dynsym .dynstr .gnu.hash .hash .gnu.version .gnu.version_r .rela.dyn .init .text .fini .rodata .eh_frame .eh_frame_hdr
03 .fini_array .init_array .dynamic .got .got.plt .data .bss
04 .dynamic
05 .note.ABI-tag
06 .eh_frame_hdr
07
08 .fini_array .init_array .dynamic .got .got.plt
This optimizes the number of mmaps that the kernel must perform to load such executable, but at a security cost: the data in .rodata shouldn't be executable, but is (because it's merged with .text, which must be executable). This may significantly increase the attack surface for someone trying to hijack a process.
Newer Linux systems, in particular using LLD to link binaries, prioritize security over speed, and put ELF header and .rodata into the first R-only segment, resulting in 3 load segments and improved security. Here is a typical mapping:
$ echo "int foo; int main() { return 0;}" | clang -xc - -o a.out-lld -fuse-ld=lld
$ readelf -Wl a.out-lld
Elf file type is EXEC (Executable file)
Entry point 0x201000
There are 10 program headers, starting at offset 64
Program Headers:
Type Offset VirtAddr PhysAddr FileSiz MemSiz Flg Align
PHDR 0x000040 0x0000000000200040 0x0000000000200040 0x000230 0x000230 R 0x8
INTERP 0x000270 0x0000000000200270 0x0000000000200270 0x00001c 0x00001c R 0x1
[Requesting program interpreter: /lib64/ld-linux-x86-64.so.2]
LOAD 0x000000 0x0000000000200000 0x0000000000200000 0x000558 0x000558 R 0x1000
LOAD 0x001000 0x0000000000201000 0x0000000000201000 0x000185 0x000185 R E 0x1000
LOAD 0x002000 0x0000000000202000 0x0000000000202000 0x001170 0x002005 RW 0x1000
DYNAMIC 0x003010 0x0000000000203010 0x0000000000203010 0x000150 0x000150 RW 0x8
GNU_RELRO 0x003000 0x0000000000203000 0x0000000000203000 0x000170 0x001000 R 0x1
GNU_EH_FRAME 0x000440 0x0000000000200440 0x0000000000200440 0x000034 0x000034 R 0x1
GNU_STACK 0x000000 0x0000000000000000 0x0000000000000000 0x000000 0x000000 RW 0
NOTE 0x00028c 0x000000000020028c 0x000000000020028c 0x000020 0x000020 R 0x4
Section to Segment mapping:
Segment Sections...
00
01 .interp
02 .interp .note.ABI-tag .rodata .dynsym .gnu.version .gnu.version_r .gnu.hash .hash .dynstr .rela.dyn .eh_frame_hdr .eh_frame
03 .text .init .fini
04 .data .tm_clone_table .fini_array .init_array .dynamic .got .bss
05 .dynamic
06 .fini_array .init_array .dynamic .got
07 .eh_frame_hdr
08
09 .note.ABI-tag
Not to be left behind, the newer BFD-ld (my version is 2.31.1) also makes ELF header and .rodata read-only, but fails to merge two R-only segments into one, resulting in 4 loadable segments:
$ echo "int foo; int main() { return 0;}" | clang -xc - -o a.out-bfd -fuse-ld=bfd
$ readelf -Wl a.out-bfd
Elf file type is EXEC (Executable file)
Entry point 0x401020
There are 11 program headers, starting at offset 64
Program Headers:
Type Offset VirtAddr PhysAddr FileSiz MemSiz Flg Align
PHDR 0x000040 0x0000000000400040 0x0000000000400040 0x000268 0x000268 R 0x8
INTERP 0x0002a8 0x00000000004002a8 0x00000000004002a8 0x00001c 0x00001c R 0x1
[Requesting program interpreter: /lib64/ld-linux-x86-64.so.2]
LOAD 0x000000 0x0000000000400000 0x0000000000400000 0x0003f8 0x0003f8 R 0x1000
LOAD 0x001000 0x0000000000401000 0x0000000000401000 0x00018d 0x00018d R E 0x1000
LOAD 0x002000 0x0000000000402000 0x0000000000402000 0x000110 0x000110 R 0x1000
LOAD 0x002e40 0x0000000000403e40 0x0000000000403e40 0x0001e8 0x0001f0 RW 0x1000
DYNAMIC 0x002e50 0x0000000000403e50 0x0000000000403e50 0x0001a0 0x0001a0 RW 0x8
NOTE 0x0002c4 0x00000000004002c4 0x00000000004002c4 0x000020 0x000020 R 0x4
GNU_EH_FRAME 0x002004 0x0000000000402004 0x0000000000402004 0x000034 0x000034 R 0x4
GNU_STACK 0x000000 0x0000000000000000 0x0000000000000000 0x000000 0x000000 RW 0x10
GNU_RELRO 0x002e40 0x0000000000403e40 0x0000000000403e40 0x0001c0 0x0001c0 R 0x1
Section to Segment mapping:
Segment Sections...
00
01 .interp
02 .interp .note.ABI-tag .hash .gnu.hash .dynsym .dynstr .gnu.version .gnu.version_r .rela.dyn
03 .init .text .fini
04 .rodata .eh_frame_hdr .eh_frame
05 .init_array .fini_array .dynamic .got .got.plt .data .bss
06 .dynamic
07 .note.ABI-tag
08 .eh_frame_hdr
09
10 .init_array .fini_array .dynamic .got
Finally, some of these choices are affected by the --(no)rosegment (or -Wl,z,noseparate-code for BFD ld) linker option.
I want to use go assembly implement below two functions
func AA(a, b int) {
var ret = sum(a, b)
println(ret)
}
func sum(a, b int) int {
return a+b
}
and use in main.go
func main() {
pkg.AA(1,2)
}
Below is my code:
pkg/pkg.go
func Sum(a,b int) int
func AA(a, b int)
pkg/pkg_amd64.s
TEXT ·AA(SB),NOSPLIT,$8-16
MOVQ arg1+0(FP), AX
MOVQ arg2+8(FP), BX
MOVQ AX, (SP)
MOVQ BX, +8(SP)
CALL ·Sum(SB)
RET
TEXT ·Sum(SB),NOSPLIT,$0
MOVQ arg1+0(FP), AX // AX = arg1
MOVQ arg2+8(FP), BX // BX = arg2
ADDQ AX, BX // BX += AX
MOVQ BX, ret1+16(FP)
RET
But when I execute go run main.go, there have some errors that hardly to debug,
I think the error is wrong way to call Sum, if you have any idea ,please give some advise for that error,thank a lot!
$ go run main.go
runtime: unexpected return pc for runtime.sigpanic called from 0x1
stack: frame={sp:0xc000056720, fp:0xc000056758} stack=[0xc000056000,0xc000056800)
000000c000056620: 0000000000000000 000000c0000566f0
000000c000056630: 000000000102ca65 <runtime.gopanic+293> 000000c000000180
000000c000056640: 000000000102b0fb <runtime.panicmem+91> 000000c000056700
000000c000056650: 0000000000000000 0000000000000055
000000c000056660: 000000000113a9f0 00000000010cb720
000000c000056670: 000000c0000566a8 000000000100aaea <runtime.(*mcache).nextFree+170>
000000c000056680: 000000000113a9f0 000000c000000180
000000c000056690: 0000000001004b85 <runtime.chanrecv+997> 000000c00006e000
000000c0000566a0: 000000000113a9f0 000000c000056730
000000c0000566b0: 000000c0000001a0 0000000000000000
000000c0000566c0: 0000000001067c40 00000000010c93b0
000000c0000566d0: 0000000000000000 0000000000000000
000000c0000566e0: 0000000000000000 0000000000000000
000000c0000566f0: 000000c000056710 000000000102b0fb <runtime.panicmem+91>
000000c000056700: 0000000001067c40 00000000010c93b0
000000c000056710: 000000c000056748 0000000001041dd9 <runtime.sigpanic+377>
000000c000056720: <00000000010cb720 0000000000000000
000000c000056730: 000000c000056778 000000c000056778
000000c000056740: 000000c000000180 000000c000056758
000000c000056750: !0000000000000001 >0000000000000002
000000c000056760: 000000000105e2f3 <main.main+51> 000000000105e2f5 <main.main+53>
000000c000056770: 0000000000000002 000000c0000567d0
000000c000056780: 000000000102fad6 <runtime.main+598> 000000c00007a000
000000c000056790: 0000000000000000 000000c00007a000
000000c0000567a0: 0000000000000000 0100000000000000
000000c0000567b0: 0000000000000000 000000c000000180
000000c0000567c0: 000000c0000567ae 0000000001078b80
000000c0000567d0: 0000000000000000 000000000105b061 <runtime.goexit+1>
000000c0000567e0: 0000000000000000 0000000000000000
000000c0000567f0: 0000000000000000 0000000000000000
fatal error: unknown caller pc
runtime stack:
runtime.throw(0x1074e46, 0x11)
/usr/local/go/src/runtime/panic.go:1117 +0x72
runtime.gentraceback(0x102b0fb, 0xc000056700, 0x0, 0xc000000180, 0x0, 0x0, 0x7fffffff, 0x7ffeefbff3c0, 0x0, 0x0, ...)
/usr/local/go/src/runtime/traceback.go:261 +0x1a56
runtime.addOneOpenDeferFrame.func1()
/usr/local/go/src/runtime/panic.go:717 +0x91
runtime.systemstack(0x0)
/usr/local/go/src/runtime/asm_amd64.s:379 +0x66
runtime.mstart()
/usr/local/go/src/runtime/proc.go:1246
goroutine 1 [running]:
runtime.systemstack_switch()
/usr/local/go/src/runtime/asm_amd64.s:339 fp=0xc0000565f8 sp=0xc0000565f0 pc=0x10593e0
runtime.addOneOpenDeferFrame(0xc000000180, 0x102b0fb, 0xc000056700)
/usr/local/go/src/runtime/panic.go:716 +0x7b fp=0xc000056638 sp=0xc0000565f8 pc=0x102bedb
panic(0x1067c40, 0x10c93b0)
/usr/local/go/src/runtime/panic.go:925 +0x125 fp=0xc000056700 sp=0xc000056638 pc=0x102ca65
runtime.panicmem()
/usr/local/go/src/runtime/panic.go:212 +0x5b fp=0xc000056720 sp=0xc000056700 pc=0x102b0fb
runtime: unexpected return pc for runtime.sigpanic called from 0x1
stack: frame={sp:0xc000056720, fp:0xc000056758} stack=[0xc000056000,0xc000056800)
000000c000056620: 0000000000000000 000000c0000566f0
000000c000056630: 000000000102ca65 <runtime.gopanic+293> 000000c000000180
000000c000056640: 000000000102b0fb <runtime.panicmem+91> 000000c000056700
000000c000056650: 0000000000000000 0000000000000055
000000c000056660: 000000000113a9f0 00000000010cb720
000000c000056670: 000000c0000566a8 000000000100aaea <runtime.(*mcache).nextFree+170>
000000c000056680: 000000000113a9f0 000000c000000180
000000c000056690: 0000000001004b85 <runtime.chanrecv+997> 000000c00006e000
000000c0000566a0: 000000000113a9f0 000000c000056730
000000c0000566b0: 000000c0000001a0 0000000000000000
000000c0000566c0: 0000000001067c40 00000000010c93b0
000000c0000566d0: 0000000000000000 0000000000000000
000000c0000566e0: 0000000000000000 0000000000000000
000000c0000566f0: 000000c000056710 000000000102b0fb <runtime.panicmem+91>
000000c000056700: 0000000001067c40 00000000010c93b0
000000c000056710: 000000c000056748 0000000001041dd9 <runtime.sigpanic+377>
000000c000056720: <00000000010cb720 0000000000000000
000000c000056730: 000000c000056778 000000c000056778
000000c000056740: 000000c000000180 000000c000056758
000000c000056750: !0000000000000001 >0000000000000002
000000c000056760: 000000000105e2f3 <main.main+51> 000000000105e2f5 <main.main+53>
000000c000056770: 0000000000000002 000000c0000567d0
000000c000056780: 000000000102fad6 <runtime.main+598> 000000c00007a000
000000c000056790: 0000000000000000 000000c00007a000
000000c0000567a0: 0000000000000000 0100000000000000
000000c0000567b0: 0000000000000000 000000c000000180
000000c0000567c0: 000000c0000567ae 0000000001078b80
000000c0000567d0: 0000000000000000 000000000105b061 <runtime.goexit+1>
000000c0000567e0: 0000000000000000 0000000000000000
000000c0000567f0: 0000000000000000 0000000000000000
runtime.sigpanic()
/usr/local/go/src/runtime/signal_unix.go:734 +0x179 fp=0xc000056758 sp=0xc000056720 pc=0x1041dd9
exit status 2
I do many methods and finally, and use the go tool compile -N -l -S main.go to debug below code for some useful infomation:
func printsum(a, b int) int{
return sum1(a, b)
}
func sum1(a, b int) int {
return a+b
}
and I find a method can pass the funtion,
TEXT ·AA(SB),NOSPLIT,$40-24
MOVQ a+0(FP), AX
MOVQ b+8(FP), BX
MOVQ AX, 0(SP) // need to put AX(arg1) in 0(SP), when call Sum, it will be used as the first param
MOVQ BX, 0x8(SP) // need to place BX(arg1) in 8(SP), when call Sum, it will be used as secnod param
CALL ·Sum(SB)
MOVQ 16(SP), AX
MOVQ AX,ret1+16(FP)
RET
TEXT ·Sum(SB),NOSPLIT,$0-24
MOVQ arg1+0(FP), AX // AX = arg1
MOVQ arg2+8(FP), BX // BX = arg2
ADDQ AX, BX // BX += AX
MOVQ BX, ret1+16(FP)
// MOVQ AX, (SP)
// CALL ·print(SB)
RET
But i still have a question, why use MOVQ 16(SP), AX can get the return value that from Sum, because i think the AA function stack is like this
------
ret0 (8 bytes)
------
arg1 (8 bytes)
------
arg0 (8 bytes)
------ FP
ret addr (8 bytes)
------
caller BP (8 bytes)
------ pseudo SP
frame content (8 bytes)
------ hardware SP
and if the function stack is correct, it will work withMOVQ 40(SP), AX , I'm very confusing about it😭
I'm developing a kernel module that I want to run on my router. The router model is DGN2200v2 by Netgear. It's running Linux 2.6.30 on MIPS. My problem is that when I load my module it seems that my module_init isn't getting called. I tried to narrow it down by modifying my module_init to return -3 (which indicates an error?) and insmod still reports success. I can see my module in the output of lsmod, but I don't see my printk output using dmesg.
For starters, I wanted to create the simplest possible module:
#include <linux/module.h>
#include <linux/kernel.h>
#include <linux/init.h>
static int my_init(void)
{
printk(KERN_EMERG "init_module() called\n");
return -3;
}
static void my_cleanup(void)
{
printk(KERN_EMERG "cleanup_module() called\n");
}
module_init(my_init);
module_exit(my_cleanup);
This is the Makefile I'm using:
TOOLCHAIN=/home/user/buildroot-2016.08/output/host/usr/bin/mips-buildroot-linux-uclibc-
ARCH=mips
CC = $(TOOLCHAIN)gcc
KBUILD_CFLAGS:=.
EXTRA_CFLAGS := -I/home/user/buildroot-2016.08/output/build/linux-headers-2.6.30/include\
-I/home/user/buildroot-2016.08/output/build/linux-headers-2.6.30/arch/mips/include/asm/mach-mipssim\
-I/home/user/buildroot-2016.08/output/build/linux-headers-2.6.30/arch/mips/include/asm/mach-generic\
-fno-pic -mno-abicalls -O2
obj-m := module.o
KDIR := /home/user/buildroot-2016.08/output/build/linux-headers-2.6.30
PWD := $(shell pwd)
default:
$(MAKE) -C $(KDIR) SUBDIRS=$(PWD) modules
I'm running make like so:
make ARCH=mips CROSS_COMPILE=/home/user/buildroot-2016.08/output/host/usr/bin/mips-buildroot-linux-uclibc-
which passes successfully.
As you can see, I'm using Buildroot which I (hopefully) configured correctly. I can paste my .config if needed.
I ran objdump on my module and didn't find a problem. In particular, the module_init symbol seems to point to the same place as my my_init function, and it seems to have the code I expect it to:
module.ko: file format elf32-tradbigmips
module.ko
architecture: mips:isa32, flags 0x00000011:
HAS_RELOC, HAS_SYMS
start address 0x00000000
private flags = 50001001: [abi=O32] [mips32] [not 32bitmode] [noreorder]
MIPS ABI Flags Version: 0
ISA: MIPS32
GPR size: 32
CPR1 size: 0
CPR2 size: 0
FP ABI: Soft float
ISA Extension: None
ASEs:
None
FLAGS 1: 00000001
FLAGS 2: 00000000
Sections:
Idx Name Size VMA LMA File off Algn
0 .MIPS.abiflags 00000018 00000000 00000000 00000038 2**3
CONTENTS, ALLOC, LOAD, READONLY, DATA, LINK_ONCE_SAME_SIZE
1 .reginfo 00000018 00000000 00000000 00000050 2**2
CONTENTS, ALLOC, LOAD, READONLY, DATA, LINK_ONCE_SAME_SIZE
2 .note.gnu.build-id 00000024 00000018 00000018 00000068 2**2
CONTENTS, ALLOC, LOAD, READONLY, DATA
3 .text 00000040 00000000 00000000 00000090 2**4
CONTENTS, ALLOC, LOAD, RELOC, READONLY, CODE
4 .rodata.str1.4 00000038 00000000 00000000 000000d0 2**2
CONTENTS, ALLOC, LOAD, READONLY, DATA
5 .modinfo 0000005c 00000000 00000000 00000108 2**2
CONTENTS, ALLOC, LOAD, READONLY, DATA
6 .data 00000000 00000000 00000000 00000170 2**4
CONTENTS, ALLOC, LOAD, DATA
7 .gnu.linkonce.this_module 0000014c 00000000 00000000 00000170 2**2
CONTENTS, ALLOC, LOAD, RELOC, DATA, LINK_ONCE_DISCARD
8 .bss 00000000 00000000 00000000 000002c0 2**4
ALLOC
9 .comment 00000040 00000000 00000000 000002c0 2**0
CONTENTS, READONLY
10 .pdr 00000040 00000000 00000000 00000300 2**2
CONTENTS, RELOC, READONLY
11 .gnu.attributes 00000010 00000000 00000000 00000340 2**0
CONTENTS, READONLY
12 .mdebug.abi32 00000000 00000000 00000000 00000350 2**0
CONTENTS, READONLY
SYMBOL TABLE:
00000000 l d .MIPS.abiflags 00000000 .MIPS.abiflags
00000000 l d .reginfo 00000000 .reginfo
00000018 l d .note.gnu.build-id 00000000 .note.gnu.build-id
00000000 l d .text 00000000 .text
00000000 l d .rodata.str1.4 00000000 .rodata.str1.4
00000000 l d .modinfo 00000000 .modinfo
00000000 l d .data 00000000 .data
00000000 l d .gnu.linkonce.this_module 00000000 .gnu.linkonce.this_module
00000000 l d .bss 00000000 .bss
00000000 l d .comment 00000000 .comment
00000000 l d .pdr 00000000 .pdr
00000000 l d .gnu.attributes 00000000 .gnu.attributes
00000000 l d .mdebug.abi32 00000000 .mdebug.abi32
00000000 l df *ABS* 00000000 module.c
00000000 l F .text 0000002c my_init
0000002c l F .text 00000014 my_cleanup
00000000 l .rodata.str1.4 00000000 $LC0
0000001c l .rodata.str1.4 00000000 $LC1
00000000 l df *ABS* 00000000 module.mod.c
00000000 l O .modinfo 00000023 __mod_srcversion23
00000024 l O .modinfo 00000009 __module_depends
00000030 l O .modinfo 0000002c __mod_vermagic5
00000000 g O .gnu.linkonce.this_module 0000014c __this_module
0000002c g F .text 00000014 cleanup_module
00000000 g F .text 0000002c init_module
00000000 *UND* 00000000 printk
Disassembly of section .MIPS.abiflags:
00000000 <.MIPS.abiflags>:
0: 00002001 movf a0,zero,$fcc0
4: 01000003 0x1000003
...
10: 00000001 movf zero,zero,$fcc0
14: 00000000 nop
Disassembly of section .reginfo:
00000000 <.reginfo>:
0: a2000014 sb zero,20(s0)
...
14: 00007fef 0x7fef
Disassembly of section .note.gnu.build-id:
00000018 <.note.gnu.build-id>:
18: 00000004 sllv zero,zero,zero
1c: 00000014 0x14
20: 00000003 sra zero,zero,0x0
24: 474e5500 c1 0x14e5500
28: c8e5d654 lwc2 $5,-10668(a3)
2c: cb477d3d lwc2 $7,32061(k0)
30: dfa48d71 ldc3 $4,-29327(sp)
34: c2ea16da ll t2,5850(s7)
38: f6bcae7d sdc1 $f28,-20867(s5)
Disassembly of section .text:
00000000 <init_module>:
0: 27bdffe8 addiu sp,sp,-24
4: 3c040000 lui a0,0x0
4: R_MIPS_HI16 $LC0
8: 3c020000 lui v0,0x0
8: R_MIPS_HI16 printk
c: afbf0014 sw ra,20(sp)
10: 24420000 addiu v0,v0,0
10: R_MIPS_LO16 printk
14: 0040f809 jalr v0
18: 24840000 addiu a0,a0,0
18: R_MIPS_LO16 $LC0
1c: 8fbf0014 lw ra,20(sp)
20: 2402fffd li v0,-3
24: 03e00008 jr ra
28: 27bd0018 addiu sp,sp,24
modinfo output also matches what I expect (same modinfo output as for another .ko that's found on the router, except for the srcversion which my module has but the other module on the router doesn't):
filename: /home/user/module/module.ko
srcversion: B0BADBA395A121CF49B74DC
depends:
vermagic: 2.6.30 mod_unload MIPS32_R1 32BIT
It's entirely possible that I messed something up in my Buildroot configuration, or something doesn't quite match the CPU type of the router, but my init code is so minimal that I'm out of ideas as to what could be wrong.
It turns out that the problem was related to a different kernel configuration between my development environment and the router. Specifically, my kernel was using CONFIG_UNUSED_SYMBOLS whereas the router's was not.
The reason this caused a problem even in a trivial module is that when the kernel loads a module it doesn't only look up the module_init symbol in the module's symbol table. Rather, it reads the module struct from the module (from the .gnu.linkonce.this_module section), and then calls the init module through that struct.
The offset of the init function pointer inside the module struct depends on the kernel configuration, which explains why the kernel can't find the init function if the configuration is different.
Thanks to Sam Protsenko for investing a lot of time in helping me crack this!
I want to hide symbol names which are not relevant to the end user and make visible only APIs in my shared or static library. I have a simple code like:
int f_b1(){
return 21 ;
}
int f_b3(){
return f_b1() ;
}
I applied the all methods stated here such as using __attribute__ ((visibility ("hidden"))) and static but without success. My operating system is Ubuntu on an x86_64 processor. Do I need to use special options while compiling with gcc? I am listing modules and function of libraries with nm command. In my example above I only want to make the f_b3 function visible. When I use attribute hidden macro compiler does not give any error but the function still exists in list outputted by the nm command.
The visibility("hidden") attribute does not suppress a symbol from
an object file and cannot prevent a symbol being extracted by nm. It just
instructs the dynamic linker that the symbol cannot be called from outside
a shared library that contains it.
Consider a source file file.c containing your example functions:
int f_b1(){
return 21 ;
}
int f_b3(){
return f_b1() ;
}
Compile the file:
gcc -c -o file.o file.c
Run nm file.o to list the symbols. Output:
0000000000000000 T f_b1
000000000000000b T f_b3
Now run objdump -t file.o for fuller information about the symbols. Output:
file.o: file format elf64-x86-64
SYMBOL TABLE:
0000000000000000 l df *ABS* 0000000000000000 file.c
0000000000000000 l d .text 0000000000000000 .text
0000000000000000 l d .data 0000000000000000 .data
0000000000000000 l d .bss 0000000000000000 .bss
0000000000000000 l d .note.GNU-stack 0000000000000000 .note.GNU-stack
0000000000000000 l d .eh_frame 0000000000000000 .eh_frame
0000000000000000 l d .comment 0000000000000000 .comment
0000000000000000 g F .text 000000000000000b f_b1
000000000000000b g F .text 000000000000000b f_b3
Here we see that f_b1 and f_b3 are global (g) functions (F) in the .text
section.
Now modify the file like this:
__attribute__((visibility ("hidden"))) int f_b1(void){
return 21 ;
}
__attribute__((visibility ("hidden"))) int f_b3(void){
return f_b1() ;
}
Run objdump again:
file.o: file format elf64-x86-64
SYMBOL TABLE:
0000000000000000 l df *ABS* 0000000000000000 file.c
0000000000000000 l d .text 0000000000000000 .text
0000000000000000 l d .data 0000000000000000 .data
0000000000000000 l d .bss 0000000000000000 .bss
0000000000000000 l d .note.GNU-stack 0000000000000000 .note.GNU-stack
0000000000000000 l d .eh_frame 0000000000000000 .eh_frame
0000000000000000 l d .comment 0000000000000000 .comment
0000000000000000 g F .text 000000000000000b .hidden f_b1
000000000000000b g F .text 000000000000000b .hidden f_b3
The output is the same, except that the symbols f_b1 and f_b3 are now marked
.hidden. They still have external (global) linkage and could be statically called, for
example, from other modules within a library that contains them, but could
not be dymamically called from outside that library.
So, if you want to conceal f_b1 and f_b3 from dynamic linkage in a shared
library, you can use visibility ("hidden") as shown.
If you want to conceal f_b1 and f_b3 from static linkage in a static
library, you cannot use the visibility attribute to do that at all.
In the case of a static library, you can "hide" a symbol only be giving it
internal instead of external linkage. The way to do that is by prefixing the
standard static keyword. But internal linkage means that the symbol is
visible only within its own compilation unit: it can't be referenced from
other modules. It is not available to the linker at all.
Modify file.c again, like this:
static int f_b1(void){
return 21 ;
}
static int f_b3(void){
return f_b1() ;
}
And run objump again:
file.o: file format elf64-x86-64
SYMBOL TABLE:
0000000000000000 l df *ABS* 0000000000000000 file.c
0000000000000000 l d .text 0000000000000000 .text
0000000000000000 l d .data 0000000000000000 .data
0000000000000000 l d .bss 0000000000000000 .bss
0000000000000000 l F .text 000000000000000b f_b1
000000000000000b l F .text 000000000000000b f_b3
0000000000000000 l d .note.GNU-stack 0000000000000000 .note.GNU-stack
0000000000000000 l d .eh_frame 0000000000000000 .eh_frame
0000000000000000 l d .comment 0000000000000000 .comment
You see that f_b1 and f_b3 are still reported as functions in the .text
section, but are now classified local (l), not global. That is internal linkage.
Run nm file.o and the output is:
0000000000000000 t f_b1
000000000000000b t f_b3
That is the same as for the original file, except that instead of 'T' flags
we now have 't' flags. Both flags mean that the symbol is in the .text section,
but 'T' means it is global and 't' means it is local.
Apparently, what you would like nm to report for this file is no symbols at all.
You should now understand that nm file.o will report a symbol if it exists in
file.o, but its existence has got nothing to do with whether it is visible
for static or dynamic linkage.
To make the function symbols disappear, compile file.c yet again
(still with the static keyword), this time with optimisation enabled:
gcc -c -O1 -o file.o file.c
Now, objdump reports:
file.o: file format elf64-x86-64
SYMBOL TABLE:
0000000000000000 l df *ABS* 0000000000000000 file.c
0000000000000000 l d .text 0000000000000000 .text
0000000000000000 l d .data 0000000000000000 .data
0000000000000000 l d .bss 0000000000000000 .bss
0000000000000000 l d .note.GNU-stack 0000000000000000 .note.GNU-stack
0000000000000000 l d .comment 0000000000000000 .comment
f_b1 and f_b3 are gone, and nm file.o reports nothing at all. Why?
Because static tells the compiler that these symbols can only be called
from within the file it is compiling, and optimisation decides that there
is no need to refer to them; so the compiler eliminates them from the
object code. But if they weren't already invisible to linker, without
optimisation, then we couldn't optimise them away.
Bottom line: It doesn't matter whether nm can extract a symbol. If the
symbol is local/internal, it can't be linked, either statically or dynamically.
If the symbol is marked .hidden then it can't be dynamically linked. You
can use visibility("hidden") to mark a symbol .hidden. Use the standard
static keyword to make a symbol local/internal.
I realize this is already an old thread. However, I'd like to share some facts about static linking in the sense of making hidden symbols local and hence prevent those symbols from (global) static linkage in an object file or static library. This does not mean making them invisible in the symbol table.
Mike Kingham's answer is very useful but not complete with respect to the following detail:
If you want to conceal f_b1 and f_b3 from static linkage in a static
library, you cannot use the visibility attribute to do that at all.
Let me show that hidden symbols can certainly be made local by using the example of the simple code in file.c and applying ypsu's answer in Symbol hiding in static libraries built with Xcode/gcc.
As a first step let's reproduce the objdump output with the hidden attribute visible on f_b1 and f_b3. This can be done by the following command, which gives all functions in file.c the hidden attribute:
gcc -fvisibility=hidden -c file.c
Output of objdump -t file.o gives
file.o: file format elf64-x86-64
SYMBOL TABLE:
0000000000000000 l df *ABS* 0000000000000000 file.c
0000000000000000 l d .text 0000000000000000 .text
0000000000000000 l d .data 0000000000000000 .data
0000000000000000 l d .bss 0000000000000000 .bss
0000000000000000 l d .note.GNU-stack 0000000000000000 .note.GNU-stack
0000000000000000 l d .eh_frame 0000000000000000 .eh_frame
0000000000000000 l d .comment 0000000000000000 .comment
0000000000000000 g F .text 000000000000000b .hidden f_b1
000000000000000b g F .text 0000000000000010 .hidden f_b3
This is exactly the same intermediate result as obtained by Mike Kingham. Now let's make the symbols with the hidden attribute local. That is accomplished by using objcopy from binutils as follows:
objcopy --localize-hidden --strip-unneeded file.o
Using objdump, gives
file.o: file format elf64-x86-64
SYMBOL TABLE:
0000000000000000 l d .text 0000000000000000 .text
0000000000000000 l F .text 000000000000000b .hidden f_b1
000000000000000b l F .text 0000000000000010 .hidden f_b3
0000000000000000 l d .data 0000000000000000 .data
0000000000000000 l d .bss 0000000000000000 .bss
0000000000000000 l d .comment 0000000000000000 .comment
0000000000000000 l d .note.GNU-stack 0000000000000000 .note.GNU-stack
0000000000000000 l d .eh_frame 0000000000000000 .eh_frame
Likewise, nm file.o gives
0000000000000000 t f_b1
000000000000000b t f_b3
Although f_b1 and f_b3 are still visible in the the symbol table they are local. Hence, functions f_b1 and f_b3 are concealed from static linking!
I'd also like to add a note on declaring functions static and by that having the possibility to remove them from the symbol table completely. First, the removal can be done deterministically and not depending on compiler optimization by using objcopy.
objcopy --strip-unneeded file.o
The static functions f_b1 and f_b2 are not anymore in the symbol table of file.o.
Secondly, this use of declaring functions static to let them disappear from the symbol table only works in single source file C-projects. As soon as a C-project consists of many components and hence files this only can be done by merging all C-source and -header files into one single source file and declare all internal interfaces (functions) static with obvious the exception of the global (top) interface. If that is not possible, one can fallback to the method originally described by ypsu (and probably many others - see for instance Restricting symbols in a Linux static library).
Note that for MacOS/iOS the linker has some extra options to control symbol visibility;
-[un|re]exported_symbols_list
-[un]exported_symbol
For more information check e.g. the ld64 documentation or have a look here.
Actually, in the ELF structure there are 2 symbol tables: "symtab" and "dynsym".
In my custom libs, I'm always stripping all the symbols, because they are not needed for proper linking - i.e. the "symtab" (which is printed by the "nm" utility) can be empty, because the linker is actually using the "dynsym" table.
This allows to reduce the lib size by ~10-20% (typically)
The functions with "hidden" attribute are removed only from "symtab", but they can still be visible in the "dynsym" table.
You can verify this by using:
readelf --syms --dyn-syms <your dso here>
The "dynsym" table always contains all the entries needed by the linker, including f.e. the STD:: functions, marked as "UND" (undefined -> to be resolved by the linker)
Regards.
This works with MSVC (compile and link).
extern void (_TMDLLENTRY * _TMDLLENTRY tpsetunsol _((void (_TMDLLENTRY *)(char _TM_FAR *, long, long)))) _((char _TM_FAR *, long, long));
But with GCC compiling is ok but linking phase fails with undefined reference pointing to this. Is this declaration already GCC compatible or is there possibly some other problem?
#define _TMDLLENTRY __stdcall
#define _TM_FAR
nm output from MSVC created object file:
00000000 N .debug$S
00000000 N .debug$S
00000000 N .debug$S
00000000 N .debug$S
00000000 N .debug$T
00000000 i .drectve
00000000 r .rdata
00000000 r .rdata
00000000 r .rdata
00000000 t .text
00000000 t .text
00000000 t .text
U #__security_check_cookie#4
00aa766f a #comp.id
00000001 a #feat.00
U ___security_cookie
U __imp__CloseClipboard#0
U __imp__EmptyClipboard#0
U __imp__GlobalAlloc#8
U __imp__GlobalLock#4
U __imp__GlobalUnlock#4
U __imp__MessageBoxA#16
U __imp__OpenClipboard#4
U __imp__SetClipboardData#8
00000000 T _CheckBroadcast#0
00000000 T _Inittpsetunsol#0
U _memcpy
U _memset
U _sprintf
U _tpchkunsol#0
U _tpsetunsol#4
00000000 T _vCSLMsgHandler#12
nm output from MinGW compiler:
nm Release/broadc.o
00000000 b .bss
00000000 d .data
00000000 N .debug_abbrev
00000000 N .debug_aranges
00000000 N .debug_info
00000000 N .debug_line
00000000 N .debug_loc
00000000 r .eh_frame
00000000 r .rdata
00000000 t .text
00000104 T _CheckBroadcast#0
U _CloseClipboard#0
U _EmptyClipboard#0
U _GlobalAlloc#8
U _GlobalLock#4
U _GlobalUnlock#4
0000010c T _Inittpsetunsol#0
U _MessageBoxA#16
U _OpenClipboard#4
U _SetClipboardData#8
U _sprintf
U _tpchkunsol#0
U _tpsetunsol
00000000 T _vCSLMsgHandler#12
Edit: Looking at _tpsetunsol symbol it is quite evident that MSVC and GCC produce different symbols.
GCC produces: U _tpsetunsol and MSVC: U _tpsetunsol#4
Is there a way to have GCC produce same symbol than MSVC?
Edit2: output from nm wtuxws32.lib (that is where tpsetunsol is defined)
WTUXWS32.dll:
00000000 i .idata$4
00000000 i .idata$5
00000000 t .text
00000000 I __imp__tpsetunsol#4
U __IMPORT_DESCRIPTOR_WTUXWS32
00000000 T _tpsetunsol#4
Is this impossible to get to work with GCC? Thanks.