views:

411

answers:

0

I'm maintaining a tool which can convert ELF32 relocatables to RDOFF2 format.
For this process to work I need to pre-link the input files currently using the ld-script shown below:

OUTPUT_FORMAT("elf32-i386", "elf32-i386", "elf32-i386")
OUTPUT_ARCH(i386)
FORCE_COMMON_ALLOCATION

SECTIONS {
    .text : {
            /* collect .init / .fini sections */

     PROVIDE_HIDDEN(__init_start = .);
     KEEP (*(.init))
     PROVIDE_HIDDEN(__init_end = .);

     PROVIDE_HIDDEN(__fini_start = .);
     KEEP (*(.fini))
     PROVIDE_HIDDEN(__fini_end = .);

            /* .text and .rodata */

     *(.text .text.* .gnu.linkonce.t.*)
     *(.rodata .rodata.* .gnu.linkonce.r.*)
     *(.rodata1)


            /* .init- / .fini_arrays */

     PROVIDE_HIDDEN (__preinit_array_start = .);
     KEEP (*(.preinit_array))
     PROVIDE_HIDDEN (__preinit_array_end = .);

     PROVIDE_HIDDEN (__init_array_start = .);
     KEEP (*(SORT(.init_array.*)))
     KEEP (*(.init_array))
     PROVIDE_HIDDEN (__init_array_end = .);

     PROVIDE_HIDDEN (__fini_array_start = .);
     KEEP (*(SORT(.fini_array.*)))
     KEEP (*(.fini_array))
     PROVIDE_HIDDEN (__fini_array_end = .);
    }
    .data : {
     *(.data .data.* .gnu.linkonce.d.*)
     *(.data1)

     SORT(CONSTRUCTORS)

            /* c++ ctors / dtors and exception tables */

     PROVIDE_HIDDEN (__gcc_except_table_start = .);
     *(.gcc_except_table .gcc_except_table.*)
     PROVIDE_HIDDEN (__gcc_except_table_end = .);

     PROVIDE_HIDDEN (__eh_frame_start = .);
     *(.eh_frame_hdr)
     *(.eh_frame)
     PROVIDE_HIDDEN (__eh_frame_end = .);

     PROVIDE_HIDDEN (__ctors_array_start = .);
     KEEP (*(SORT(.ctors.*)))
     KEEP (*(.ctors))
     PROVIDE_HIDDEN (__ctors_array_end = .);

     PROVIDE_HIDDEN (__dtors_array_start = .);
     KEEP (*(SORT(.dtors.*)))
     KEEP (*(.dtors))
     PROVIDE_HIDDEN (__dtors_array_end = .);
    }
    .bss  : {
     *(.dynbss)
     *(.bss .bss.* .gnu.linkonce.b.*)
     *(COMMON)

     . = ALIGN(. != 0 ? 32 / 8 : 1);
    }
    /DISCARD/ : {
     *(.note.GNU-stack)
     *(.gnu_debuglink)
    }
}

The goal is to reduce the input file to contain only .text, .data, .bss, .strtab, .symtab and .shstrtab sections.

While the curren version works fine with C code it breaks for C++ as g++ / ld seem to generate sections of type *SHT_DYNSYM* named after some of my C++ symbols.

My question: How would one modify the provided linker script to catch those stray symbols?

Here is my example source:

/* compile with g++ -c cxx_hello.cc */
/* generic sys write provided by syswrite_$arch.S */
void _syscall_write(int fd, const char *msg, unsigned len);

void syscall_write(int fd, const char *msg, unsigned len)
{
    _syscall_write(fd, msg, len);
}

class HelloBase
{
    public:
     HelloBase()  { syscall_write(1, "::HelloBase()\n", 14); i = 42; };
     ~HelloBase() { syscall_write(1, "::~HelloBase()\n", 15); };
     int res(void) { return i; }
    protected:
     void sayHi(void) { syscall_write(1, "Hello", 5); };
    private:
     int i;
};

class HelloDeriv : public HelloBase
{
    public:
     HelloDeriv()  { syscall_write(1, "::HelloDeriv()\n", 15); }
     ~HelloDeriv() { syscall_write(1, "::~HelloDeriv()\n", 16); }

     void greet(void) { this->sayHi(); syscall_write(1, ", World!\n", 9); }
}; 

int
_main(void)
{
    HelloDeriv hello;

    hello.greet();
    return hello.res();
}

The output of objdump -h (only interesting sections):

cxx_hello.o:     file format elf32-i386

Sections:
Idx Name          Size      VMA       LMA       File off  Algn
0 _ZN9HelloBase3resEv 00000008  00000000  00000000  00000034  2**2
              CONTENTS, READONLY, EXCLUDE, GROUP, LINK_ONCE_DISCARD

1 _ZN9HelloBaseC2Ev 00000008  00000000  00000000  0000003c  2**2
              CONTENTS, READONLY, EXCLUDE, GROUP, LINK_ONCE_DISCARD

2 _ZN9HelloBaseD2Ev 00000008  00000000  00000000  00000044  2**2
              CONTENTS, READONLY, EXCLUDE, GROUP, LINK_ONCE_DISCARD

3 _ZN10HelloDerivC1Ev 00000008  00000000  00000000  0000004c  2**2
              CONTENTS, READONLY, EXCLUDE, GROUP, LINK_ONCE_DISCARD

4 _ZN9HelloBase5sayHiEv 00000008  00000000  00000000  00000054  2**2
              CONTENTS, READONLY, EXCLUDE, GROUP, LINK_ONCE_DISCARD

5 _ZN10HelloDeriv5greetEv 00000008  00000000  00000000  0000005c  2**2
              CONTENTS, READONLY, EXCLUDE, GROUP, LINK_ONCE_DISCARD

6 _ZN10HelloDerivD1Ev 00000008  00000000  00000000  00000064  2**2
              CONTENTS, READONLY, EXCLUDE, GROUP, LINK_ONCE_DISCARD

7 .text         00000000  00000000  00000000  0000006c  2**2
              CONTENTS, ALLOC, LOAD, READONLY, CODE

8 .data         00000000  00000000  00000000  0000006c  2**2

              CONTENTS, ALLOC, LOAD, DATA
9 .bss          00000000  00000000  00000000  0000006c  2**2
              ALLOC

The same file with readelf -S There are 37 section headers, starting at offset 0x59c:

Section Headers:
[Nr] Name              Type            Addr     Off    Size   ES Flg Lk Inf Al
[ 0]                   NULL            00000000 000000 000000 00      0   0  0
[ 1] .group            GROUP           00000000 000034 000008 04     35  26  4
[ 2] .group            GROUP           00000000 00003c 000008 04     35  30  4
[ 3] .group            GROUP           00000000 000044 000008 04     35  31  4
[ 4] .group            GROUP           00000000 00004c 000008 04     35  33  4
[ 5] .group            GROUP           00000000 000054 000008 04     35  34  4
[ 6] .group            GROUP           00000000 00005c 000008 04     35  35  4
[ 7] .group            GROUP           00000000 000064 000008 04     35  36  4
[ 8] .text             PROGBITS        00000000 00006c 000000 00  AX  0   0  4
[ 9] .data             PROGBITS        00000000 00006c 000000 00  WA  0   0  4
[10] .bss              NOBITS          00000000 00006c 000000 00  WA  0   0  4