skip to Main Content

Compiling this C code:

#include <stdio.h>

const char code[] __attribute__((section(".mySection"))) = "xb8x0dx00x00x00xc3";

int main(int argc, char **argv)
{
    int val = ((int(*)(void))code)();
    printf("val %dn", val);
}

together with this ld script:

MEMORY
{
  my_region (RWX) : ORIGIN = 0x405340, LENGTH = 4K
}

SECTIONS
{
  .mySegment 0x405340 : {KEEP(*(.mySection))} > my_region
}

as:

gcc link.ld t79.c

leads to:

/usr/bin/ld: warning: link.ld contains output sections; did you forget -T?
/usr/bin/ld: internal error ../../ld/ldlang.c 6101
collect2: error: ld returned 1 exit status

Why? How to fix?

ld version: 2.34
gcc version: 9.4.0
uname -a:
Linux xxx 5.15.0-25-generic #25~20.04.2-Ubuntu SMP Mon Apr 11 08:31:42 UTC 2022 x86_64 x86_64 x86_64 GNU/Linux

UPD: the internal error ../../ld/ldlang.c 6101 comes from here (function lang_size_relro_segment_1):

ASSERT (desired_end >= seg->base);

2

Answers


  1. Chosen as BEST ANSWER

    The internal error ../../ld/ldlang.c 6101 comes from RWX. I was mistakenly thinking that W stands for "write", while W stands for "read/write".

    In case of WX the output is the following:

    /usr/bin/ld: warning: link.ld contains output sections; did you forget -T?
    /usr/bin/ld: error: no memory region specified for loadable section `.interp'
    collect2: error: ld returned 1 exit status
    

    Instead of fixing it I use GCC exploit:

    #include <stdio.h>
    
    const char code[]
    __attribute__((section(".mySection,"awx"#"))) /* GCC exploit */
    = "xb8x0dx00x00x00xc3";
    
    int main(int argc, char **argv)
    {
        int val = ((int(*)(void))code)();
        printf("val %dn", val);
    }
    
    $ gcc t79.c && ./a.out
    val 13
    

  2. I’m not sure what you want to achieve but the direct way to solve this problem would be:

    1. At first use option -T to order the linker script to be read. That will lead you to the real problem.
    2. Use option -nostartfiles, so together gcc -T link.ld t79.c -nostartfiles, to get rid of the undefined references, as the standard system startup files than won’t be used when linking. The standard system libraries will be used normally.
    3. Remove the SECTIONS part from the linker script to avoid collisions of .mySegment with the other sections.

    After this kind of a brute force solution the program will be compiled and linked successfully, you’ll get a printout — I get a val 13 — and than the program will crash due to a segmentation fault.

    Login or Signup to reply.
Please signup or login to give your own answer.
Back To Top
Search