gcc - Third party C static library: Add -ffunction-sections -fdata-sections -


i in situation have c static library (compiled arm-gcc), provided third party. have no possibility (let third party) re-compile library.

when investigating library contents, found gcc options -ffunction-sections , -fdata-sections have not been used compiling library. helpful reducing binary size of project.

compilation done with: (gnu tools arm embedded processors) 4.8.4 20140526 (release) [arm/embedded-4_8-branch revision 211358].

is there way put every data , every function own separate section enable function-level-linking library, without needing recompile code?

i thought of possible approach:

  • split library object files.
  • for each object file:
    • write code move symbols own sections
  • put new object files archive file

could work, or have other suggestions, ideally use tools provided arm-gcc?

i'm aware old, came across problem well, , figured i'd provide findings.

tl;dr: it's possible, incredibly difficult. can't move symbols own sections. relocations bite you.

when compiler generates machine code, generate different instructions if -ffunction-sections , -fdata-sections flags are, or not, provided. due assumptions compiler able make symbols located. these assumptions change depending on flags provided.

this best illustrated example. take following simple code snippet:

int a, b;  int getaplusb() {     return + b; } 

the following result of arm-none-eabi-objdump -xdr test.o:

arm-none-eabi-gcc -c -os -mthumb -mcpu=cortexm3 -mlittle-endian -o test.o test.c:

symbol table: 00000000 g     f .text  0000000c getaplusb 00000004 g     o .bss   00000004 b 00000000 g     o .bss   00000004  disassembly of section .text:  00000024 <getaplusb>:   24:   4b01        ldr r3, [pc, #4]    ; (2c <getaplusb+0x8>)   26:   cb09        ldmia   r3, {r0, r3}   28:   4418        add r0, r3   2a:   4770        bx  lr   2c:   00000000    .word   0x00000000             2c: r_arm_abs32 .bss 

arm-none-eabi-gcc -c -os -ffunction-sections -fdata-sections \ -mthumb -mcpu=cortexm3 -mlittle-endian -o test.o test.c:

symbol table: 00000000 g     f .text.getaplusb    00000014 getaplusb 00000000 g     o .bss.b 00000004 b 00000000 g     o .bss.a 00000004  disassembly of section .text.getaplusb:  00000000 <getaplusb>:    0:   4b02        ldr r3, [pc, #8]    ; (c <getaplusb+0xc>)    2:   6818        ldr r0, [r3, #0]    4:   4b02        ldr r3, [pc, #8]    ; (10 <getaplusb+0x10>)    6:   681b        ldr r3, [r3, #0]    8:   4418        add r0, r3    a:   4770        bx  lr     ...             c: r_arm_abs32  .bss.a             10: r_arm_abs32 .bss.b 

the difference subtle, important. flag enabled code performs 2 separate loads, while disabled code performs single "load multiple." enabled code because knows both symbols contained in same section, in sequence. enabled code, not case. symbols in 2 separate sections, , while keep order , proximity, not guaranteed. what's more, if both sections not referenced, linker may decide 1 section not used, , remove it.

another example:

int a, b;  int getb() {   return b; } 

and generated code. first without flags:

symbol table: 00000000 g     f .text  0000000c getb 00000004 g     o .bss   00000004 b 00000000 g     o .bss   00000004  disassembly of section .text:  00000018 <getb>:   18:   4b01        ldr r3, [pc, #4]    ; (20 <getb+0x8>)   1a:   6858        ldr r0, [r3, #4]   1c:   4770        bx  lr   1e:   bf00        nop   20:   00000000    .word   0x00000000             20: r_arm_abs32 .bss 

and flags:

symbol table: 00000000 g     f .text.getb 00000014 getb 00000000 g     o .bss.b 00000004 b 00000000 g     o .bss.a 00000004  disassembly of section .text.getb:  00000000 <getb>:    0:   4b01        ldr r3, [pc, #4]    ; (8 <getb+0x8>)    2:   6818        ldr r0, [r3, #0]    4:   4770        bx  lr    6:   bf00        nop    8:   00000000    .word   0x00000000             8: r_arm_abs32  .bss.b 

in case, difference more subtle. enabled code loads offset of 0, while disabled code uses 4. since disabled code references beginning of section, needs offset location of b. enabled code references section contains solely b, , therefore not need offset. if split , change relocation, new code contain reference section a in, not b. this, again, cause linker garbage collect wrong section.

these 2 scenarios came across when looking @ problem, there may more.

producing valid object files functionally equivalent code compiled -ffunction-sections , -fdata-sections flags require parsing machine instructions looking these , other relocation issues come up. not easy task accomplish.


Comments