GNU链接器:适应名称更改算法的更改 [英] GNU linker: Adapt to change of name mangling algorithm

查看:84
本文介绍了GNU链接器:适应名称更改算法的更改的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我正在尝试重新编译现有的C ++应用程序. 不幸的是,我必须依靠我只有一个预编译的静态存档的专有库.

I am trying to re-compile an existing C++ application. Unfortunately, I must rely on a proprietary library I only have a pre-compiled static archive of.

我使用的是g ++版本7.3.0和ld版本2.30.
无论使用哪种GCC版本,它都是古老的.

I use g++ version 7.3.0 and ld version 2.30.
Whatever GCC version it was compiled with, it is ancient.

头文件定义了方法:

class foo {
    int bar(int & i);
}

nm lib.a所示,库存档包含相应的导出函数:

As nm lib.a shows, the library archive contains the corresponding exported function:

T bar__4fooRi

nm app.o显示了我最近使用不同类型名称处理的编译器:

nm app.o shows my recent compiler employing a different kind of name mangling:

U _ZN4foo9barERi

因此,链接程序无法解析库提供的符号.

Hence the linker cannot resolve the symbols provided by the library.

是否可以选择名称处理算法?
我可以引入地图还是明确定义错误的名称?

Is there any option to chose the name mangling algorithm?
Can I introduce a map or define the mangled names explicitly?

推荐答案

@Botje的建议使我编写了这样的链接描述文件(PROVIDE节中的空格很重要):

@Botje's suggestion lead me to writing a linker script like this (the spaces in the PROVIDE stanza are significant):

EXTERN(bar__4fooRi);
PROVIDE(_ZN4foo9barERi = bar__4fooRi);

据我了解,这会将bar__4fooRi视为一个外部定义的符号(它是).如果搜索但未定义_ZN4foo9barERi,则bar__4fooRi将取代其位置.

As far as I understood, this will regard bar__4fooRi as an externally defined symbol (which it is). If _ZN4foo9barERi is searched for, but not defined, bar__4fooRi will take its place.

我是这样从GNU工具链中调用链接器的(注意顺序–脚本需要在依赖对象之后但在定义库之前):

I am calling the linker from the GNU toolchain like this (mind the order – the script needs to be after the dependant object but before the defining library):

g++ -o application application.o script.ld -lfoo

看来这可行.
至少在理论上.
现在,链接器将考虑库的其他部分,这些部分又依赖于其他不可解析的符号,包括(但不限于)__throw__cp_pop_exception__builtin_delete.我不知道现在在哪里定义这些功能. Joxean Koret在

It looks like this could work.
At least in theory.
The linker now regards other parts of the library, which in turn depends on other unresolvable symbols including (but not limited to) __throw, __cp_pop_exception, and __builtin_delete. I have no idea where these functions are defined nowadays. Joxean Koret shows some locations in this blog post based on guesswork (__builtin_new probably is malloc) – but I am not that confident.

这些发现使我得出一个结论,即该库也依赖于不同类型的异常处理以及可能的内存管理.

These findings lead me to the conclusion that the library relies on a different style of exception handling and probably memory management, too.

编辑:由于@eukaryota指出的ABI更改,结果可能纯粹是学术上的,链接脚本的确可以用于别名"符号.这是一个完整的最小示例:

The result may be purely academical due to ABI changes as pointed out by @eukaryota, a linker script can indeed be used to "alias" symbols. Here is a complete minimal example:

foo.h:

class Foo {
    public:
    int bar(int);
};

foo.cpp:

#include "foo.h"
int Foo::bar(int i) {
    return i+21;
}

main.cpp:

class Foo {
    public:
    int baa(int); // use in-place "header" to simulate different name mangling algorithm
};

int main(int, char**) {
    Foo f;
    return f.baa(21);
}

script.ld:

script.ld:

EXTERN(_ZN3Foo3barEi);
PROVIDE(_ZN3Foo3baaEi = _ZN3Foo3barEi); /* declare "alias" */

构建过程:

g++ -o libfoo.o -c foo.c
ar rvs libfoo.a libfoo.o # simulate building a library
g++ -o app main.o -L. script.ld -lfoo

app已编译,可以执行并返回预期结果.

app is compiled, can be executed and returns expected result.

这篇关于GNU链接器:适应名称更改算法的更改的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆