Search code examples
gcclinker-flags

MSVC '/SECTION:.data,EWR' linker option equivalent for GCC


I want to add EWR(Execute/Write/Read) memory attribute to the .data section at compile time.

MSVC compiler can do this by simply adding the "/SECTION:.data,EWR" linker option.

But I don't know how to do this in GCC compiler (MinGW).

Please help!


Solution

  • The simplest way I could think of is adding a dummy file to the link with a .data.* section that has the desired flags. That dummy file is easy to produce using assembly:

    .section .data.fake, "axw"
    

    (assuming you are on an ELF platrofm, using gas).

    Say, the file containing the above is called dummy.s, then you can either assemble it manually, and then add the result to the link

    as dummy.s -o dummy.o
    gcc <all your normal .o files> dummy.o  # or `ld`
    

    Or just pass the assebmly file to the driver:

    gcc <all your normal files> dummy.s
    

    Note that the assembler gives a warning:

    Warning: setting incorrect section attributes for .data.fake
    

    because of the unusual flags. It does set them as asked though.

    Now, let me explain a little what is going on.

    All the input .data* sections are merged into the output .data section. See the default linker script (ld --verbose):

    .data           :
    {
      *(.data .data.* .gnu.linkonce.d.*)
      SORT(CONSTRUCTORS)
    }
    

    The flags of the output section are the union of the flags of the input section (I'm pretty sure this behavior is documented in the linker manual). That is how the trick works. The flags for the segment holding the resulting .data are then also computed as the union of the flags of the sections it contains. See the output of readelf -lW to make sure you got the result you expect. I have

    ...
    LOAD 0x002e28 0x0000000000003e28 0x0000000000003e28 0x000200 0x000208 *RWE* 0x1000
    ...
    05 .init_array .fini_array .dynamic .got .got.plt *.data* .bss