gpt4 book ai didi

c++ - 将COFF文件的COMDAT符号解释为人类可读的功能签名

转载 作者:塔克拉玛干 更新时间:2023-11-03 07:16:59 25 4
gpt4 key购买 nike

我想解释COFF文件的COMDAT符号
COMDAT符号是
?make@DNameStatusNode@@SAPAV1@W4DNameStatus@@@Z
我如何解释为
(public: static class DNameStatusNode * __cdecl DNameStatusNode::make(enum DNameStatus))
谢谢。

最佳答案

这将是Visual Studio(和与VS兼容的Windows编译器)生成的“修饰的”(混杂的)C++函数名称,而不是COMDAT符号。

最简单的方法是通过UNDNAME.EXE(Visual Studio附带的实用程序)运行符号。除此以外,您可以使用库UnDecorateSymbolName()中的 Dbghelp.dll 函数或未记录的内部函数__unDName()(据我所知,这是UNDNAME使用的函数);考虑到DName是它的帮助程序类之一,我认为您至少对该函数有些熟悉。 [请注意,尽管这些工具大多数都是准确的,但在某些情况下会动摇(例如const指针,某些C++ / CLI符号或extern "C"函数中声明的函数局部类(包括main())。)

如果所有其他方法都失败了,您也可以尝试手动取消名称的名称,这需要熟悉处理方案本身。如果您不了解MS内部信息,则可能需要进行大量的实验和/或研究,但这是最准确的方法。但是,有一些简单的准则可以帮助您:

  • 名称几乎总是以开头的?开头。如果不是这样,则?之前将带有特殊修饰符(例如__imp___declspec(dllimport)或CodeView的?@),其名称应以?开头。
  • 在开头的?之后,直到@@为止的段都是实体的限定名称,分为单独的组件名称(首先是符号名称,然后是每个包含范围的名称;在此步骤中, namespace 范围和类范围被相同地处理处理过程);组成限定名称的每个组件名称都紧随其后的是单个@,它充当该名称的终止符,并且全名以独立的@终止(通常创建一个双@@)。从右到左读取它,用范围运算符@替换任何单个::,并在双@中的第二个@@处停止。 [请注意,在某些情况下,没有遵守此规则,并且模板化实体名称确实很奇怪。还要注意,当在类型信息期间遇到用户定义的类型(枚举,类,结构,联合)时,将根据普通的限定名称处理规则使用其限定名称,但1)除外。标识符而不是问号1,并且2)如果可能,将缩写名称2。]
  • 某些特殊实体(例如运算符,内部帮助器函数和内部帮助器对象)将具有特殊名称,其格式为?x,其中x是数字或大写字母,后跟0-2下划线;请注意,这些名称充当特殊缩写2,因此,它们不以单个@终止。因此,特殊成员实体的名称将类似于??_FCLS@@QAEXXZ(class ::CLS的默认构造函数闭包),特殊非成员实体的名称将以单个@而不是双@@终止(例如vector构造函数迭代器??_H@YGXPAXIHP6EPAX0@Z@Z;请注意??_H@是其完全限定的名称,其后的所有内容都是类型信息)。
  • @@后的段包含所有相关的类型信息,并且在不进行大量详细说明的情况下很难解释。我建议使用诸如Agner Fog的“不同C++编译器和操作系统的调用约定” PDF和/或Wikiversity页面“Visual C++名称修改”之类的资源作为引用。尽管他们的信息不是100%准确,但它足够准确以读取您会遇到的大多数错误名称。

  • 希望这可以帮助。

    1:将使用以下之一指示UDT的类型:
  • 枚举:W4 [注意,从技术上讲,它表示enum : int,但是由于某种原因,编译器会将所有枚举类型都转换为W4,并将基础类型信息存储在其他位置。]
  • 类:V
  • 结构:U
  • 联盟:T

  • 它后面将是UDT的限定名称,该名称以通常的 @@结尾。
    class  CL; // Is: VCL@@
    struct ST; // Is: UST@@
    enum EN; // Is: W4EN@@
    union UN; // Is: TUN@@

    namespace X { class CL; } // Is: VCL@X@@

    2:如果在处理符号时已经遇到过UDT限定名称中的任何组件名称(无论是作为符号限定名称的一部分,还是作为参数限定名称的一部分(从左到右读取参数)),并且它是遇到的前10个名称之一,该名称及其终止 @都将缩写为一个数字,代表该先前使用的名称。缩写为零索引,符号的实际名称计为名称 0
    namespace Y {
    void func(X::CL param);
    // Is: ?func@Y@@YAXVCL@X@@@Z
    }

    namespace X {
    void func(CL param);
    // Is: ?func@Y@@YAXVCL@1@@Z
    // "X@" is replaced with "1".
    }

    如前所述,某些特殊实体(运算符,某些内部帮助器函数和某些内部帮助器对象)也使用名称缩写规则,并使用硬编码到编译器中的特殊缩写。有趣的是,大多数非 operator实体都有内部名称,这与缩写词不同。与普通缩写一样,这些特殊缩写会扩展为名称及其终止的 @;因此,特殊的缩写将紧跟在限定名称终止的第二个 @或任何包含范围的后面。
    // Containing scopes example, with 'scalar deleting destructor':
    class CL {
    public:
    ~CL();
    };
    CL::~CL() {} // Non-trivial destructor.

    // If an instance of the above class is deleted with "delete", the compiler will create
    // hidden member functions 'scalar deleting destructor' and 'vector deleting destructor'.
    // The former will have this mangled symbol:
    // ??_GCL@@QAEPAXI@Z
    // Note that there's no '@' between '?_G' (function name) & 'CL@' (containing scope name).


    // Global example, with 'vector constructor iterator':
    class CL {
    public:
    CL();
    };
    CL::CL() {} // Non-trivial constructor.

    CL cls[3]; // Create an array of class with non-trivial ctor.
    // The compiler uses the 'vector constructor iterator' to create the array and initialise
    // each instance.
    // It has the mangled symbol:
    // ??_H@YGXPAXIHP6EPAX0@Z@Z
    // Note that there's no '@' between '?_H' (function name) & '@' (qualified name terminator).

    关于c++ - 将COFF文件的COMDAT符号解释为人类可读的功能签名,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/32236263/

    25 4 0
    Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
    广告合作:1813099741@qq.com 6ren.com