GNU LD Script для отлова групп C ++ / dynsym Sections - PullRequest
0 голосов
/ 11 сентября 2009

У меня есть инструмент, который может конвертировать перемещаемые объекты ELF32 в формат RDOFF2.
Для того, чтобы этот процесс работал, мне нужно предварительно связать входные файлы с помощью ld-скрипта, показанного ниже:

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)
    }
}

Цель состоит в том, чтобы уменьшить входной файл, содержащий только разделы .text, .data, .bss, .strtab, .symtab и .shstrtab.

Хотя текущая версия прекрасно работает с кодом C, она ломается для C ++, так как g++ / ld, похоже, генерирует секции типа SHT_DYNSYM, названные в честь некоторых из моих символов C ++.

Мой вопрос : Как изменить предоставленный скрипт компоновщика, чтобы перехватить эти случайные символы?

Вот мой пример источника:

/* 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();
}

Вывод objdump -h (только интересные разделы):

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

Тот же файл с 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

1 Ответ

0 голосов
/ 22 ноября 2010

Ну, у меня довольно простое предложение, настолько простое, что оно может не сработать ...

Соответственно:

http://ftp.gnu.org/old-gnu/Manuals/ld-2.9.1/html_node/ld_19.html

Вы можете указать только имя файла (.o) для всех его разделов, которые будут захвачены.

И вы можете использовать подстановочные знаки.

Может ли быть так, что строка только с * захватит все оставшиеся секции? Как это:

.bss  : {
    *(.dynbss)
    *(.bss .bss.* .gnu.linkonce.b.*)
    *(COMMON)
    *
}
...