0

我正在维护一个可以将 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
4

1 回答 1

0

好吧,我有一个非常简单的建议,这么简单可能行不通......

据此:

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)
    *
}
于 2010-11-22T14:26:38.260 回答