Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Howto pass commands to the linker script via .pro file (Qt)

I'm using Qt 5.3.2 with GCC 4.8.2. I want to insert via the .pro file (qmake) a section definition to the linker script created by qmake.

What I want to insert:

SECTIONS 
{
.legacy_vars :
{
    *myModule.o (.bss)
    *myModule.o (.data)
}
.everything_else :
{
    * (.bss)
    * (.data)
    * (.text)
}
}

Is this possible? Thanks in advance!

To answer the question "why?":

I have legacy code in my project which I cannot change. But I need to reset its variables to reset its state. At the same time most of them are static and dont have functions to access them. Therefore I want to map the legacy codes variables to a defined section, read them when starting my program and if needed write them back in order to reset this part of the program.

like image 991
Burner Avatar asked Dec 03 '25 12:12

Burner


1 Answers

Found a solution:

First of all the "simple linker script examples" I found on the net are not correct/complete/working for a PC application (like this: link). So i did the following:

  1. Read out the default linker script of GCC into a file: "ld --verbose > ld_script.ld"
  2. Removed the leading additional information generated by the verbose command:

    GNU ld (GNU Binutils) 2.24
      Supported emulations:
       i386pe
    using internal linker script:
    ==================================================
    

and at the end:

    ==================================================
  1. Inserted my addition linkage commands into the linker script:

    .data BLOCK(__section_alignment__) : {
        __data_start__ = . ;
        _legacy_code_data_start = . ;
        *legacy_module_first.o(.data*)
        *legacy_module_next.o(.data*)
        *legacy_module_last.o(.data*)
        _legacy_code_data_end = . ;
        *(.data)
        *(.data2)
        *(SORT(.data$*))
        *(.jcr)
        __data_end__ = . ;
        *(.data_cygwin_nocopy)
    }
    

and:

    .bss BLOCK(__section_alignment__) : {
        __bss_start__ = . ;
        _legacy_code_bss_start = . ;
        *legacy_module_first.o(COMMON)
        *legacy_module_first.o(.bss)
        *legacy_module_next.o(COMMON)
        *legacy_module_next.o(.bss)
        *legacy_module_last.o(COMMON)
        *legacy_module_last.o(.bss)
        _legacy_code_bss_end = . ;
        *(.bss)
        *(COMMON)
        __bss_end__ = . ;
    }
  1. Added the script file to the Qt project
  2. Added the linker script to the linkage via the .pro file with:

    QMAKE_LFLAGS += "-T ../pathtoscript/ld_script.ld"
    
  3. Done.

"-T" tells the linker to use the defined file instead of the default one of the linker. Prior this resulted in errors since the linker files I wrote were not complete.

The result is the following and can be seen within a map file (to create a map file use: QMAKE_LFLAGS += "-Wl,-Map=output.map"):

The .data variables of the legacy modules defined in the linker script will be put between the symbols "_legacy_code_data_start" and "_legacy_code_data_end" and the .bss and COMMON variables will be put between the symbols "_legacy_code_bss_start" and "_legacy_code_bss_end". These symbols can be used by declaring them within the C/C++ code with: "extern void * legacy_code_data_start;" and so on. Therefore I'm now able to read these two data blocks and write them back whenever I want.

like image 170
Burner Avatar answered Dec 06 '25 02:12

Burner



Donate For Us

If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!