2019-04-12 01:29:48 +08:00
|
|
|
=====================================
|
|
|
|
CodeView Symbol Records
|
|
|
|
=====================================
|
|
|
|
|
|
|
|
|
|
|
|
.. contents::
|
|
|
|
:local:
|
|
|
|
|
|
|
|
.. _symbols_intro:
|
|
|
|
|
|
|
|
Introduction
|
|
|
|
============
|
|
|
|
|
|
|
|
This document describes the usage and serialization format of the various
|
|
|
|
CodeView symbol records that LLVM understands. Like
|
|
|
|
:doc:`CodeView Type Records <CodeViewTypes>`, we describe only the important
|
|
|
|
types which are generated by modern C++ toolchains.
|
|
|
|
|
|
|
|
Record Categories
|
|
|
|
=================
|
|
|
|
|
|
|
|
Symbol records share one major similarity with :doc:`type records <CodeViewTypes>`:
|
|
|
|
They start with the same :ref:`record prefix <leaf_types>`, which we will not describe
|
|
|
|
again (refer to the previous link for a description). As a result of this, a sequence
|
|
|
|
of symbol records can be processed with largely the same code as that which processes
|
|
|
|
type records. There are several important differences between symbol and type records:
|
|
|
|
|
|
|
|
* Symbol records only appear in the :doc:`PublicStream`, :doc:`GlobalStream`, and
|
|
|
|
:doc:`Module Info Streams <ModiStream>`.
|
|
|
|
* Type records only appear in the :doc:`TPI & IPI streams <TpiStream>`.
|
|
|
|
* While types are referenced from other CodeView records via :ref:`type indices <type_indices>`,
|
|
|
|
symbol records are referenced by the byte offset of the record in the stream that it appears
|
|
|
|
in.
|
|
|
|
* Types can reference types (via type indices), and symbols can reference both types (via type
|
|
|
|
indices) and symbols (via offsets), but types can never reference symbols.
|
|
|
|
* There is no notion of :ref:`Leaf Records <leaf_types>` and :ref:`Member Records <member_types>`
|
|
|
|
as there are with types. Every symbol record describes is own length.
|
|
|
|
* Certain special symbol records begin a "scope". For these records, all following records
|
|
|
|
up until the next ``S_END`` record are "children" of this symbol record. For example,
|
|
|
|
given a symbol record which describes a certain function, all local variables of this
|
|
|
|
function would appear following the function up until the corresponding ``S_END`` record.
|
|
|
|
|
|
|
|
Finally, there are three general categories of symbol record, grouped by where they are legal
|
|
|
|
to appear in a PDB file. Public Symbols (which appear only in the
|
|
|
|
:doc:`publics stream <PublicStream>`), Global Symbols (which appear only in the
|
|
|
|
:doc:`globals stream <GlobalStream>`) and module symbols (which appear in the
|
|
|
|
:doc:`module info stream <ModiStream>`).
|
|
|
|
|
|
|
|
|
|
|
|
.. _public_symbols:
|
|
|
|
|
|
|
|
Public Symbols
|
|
|
|
--------------
|
|
|
|
|
2019-04-12 23:51:40 +08:00
|
|
|
Public symbols are the CodeView equivalent of DWARF ``.debug_pubnames``. There
|
|
|
|
is one public symbol record for every function or variable in the program that
|
|
|
|
has a mangled name. The :doc:`Publics Stream <PublicStream>`, which contains these
|
|
|
|
records, additionally contains a hash table that allows one to quickly locate a
|
|
|
|
record by mangled name.
|
|
|
|
|
2019-04-12 01:29:48 +08:00
|
|
|
S_PUB32 (0x110e)
|
|
|
|
^^^^^^^^^^^^^^^^
|
|
|
|
|
2019-04-12 23:51:40 +08:00
|
|
|
There is only type of public symbol, an ``S_PUB32`` which describes a mangled
|
|
|
|
name, a flag indicating what kind of symbol it is (e.g. function, variable), and
|
|
|
|
the symbol's address. The :ref:`dbi_section_map_substream` of the
|
|
|
|
:doc:`DBI Stream <DbiStream>` can be consulted to determine what module this address
|
|
|
|
corresponds to, and from there that module's :doc:`module debug stream <ModiStream>`
|
|
|
|
can be consulted to locate full information for the symbol with the given address.
|
|
|
|
|
2019-04-12 01:29:48 +08:00
|
|
|
.. _global_symbols:
|
|
|
|
|
|
|
|
Global Symbols
|
|
|
|
--------------
|
|
|
|
|
2019-04-12 23:51:40 +08:00
|
|
|
While there is one :ref:`public symbol <public_symbols>` for every symbol in the
|
|
|
|
program with `external` linkage, there is one global symbol for every symbol in the
|
|
|
|
program with linkage (including internal linkage). As a result, global symbols do
|
|
|
|
not describe a mangled name *or* an address, since symbols with internal linkage
|
|
|
|
need not have any mangling at all, and also may not have an address. Thus, all
|
|
|
|
global symbols simply refer directly to the full symbol record via a module/offset
|
|
|
|
combination.
|
|
|
|
|
|
|
|
Similarly to :ref:`public symbols <public_symbols>`, all global symbols are contained
|
|
|
|
in a single :doc:`Globals Stream <GlobalStream>`, which contains a hash table mapping
|
|
|
|
fully qualified name to the corresponding record in the globals stream (which as
|
|
|
|
mentioned, then contains information allowing one to locate the full record in the
|
|
|
|
corresponding module symbol stream).
|
|
|
|
|
|
|
|
Note that a consequence and limitation of this design is that program-wide lookup
|
|
|
|
by anything other than an exact textually matching fully-qualified name of whatever
|
|
|
|
the compiler decided to emit is impractical. This differs from DWARF, where even
|
|
|
|
though we don't necessarily have O(1) lookup by basename within a given scope (including
|
|
|
|
O(1) scope, we at least have O(n) access within a given scope).
|
|
|
|
|
|
|
|
.. important::
|
|
|
|
Program-wide lookup of names by anything other than an exact textually matching fully
|
|
|
|
qualified name is not possible.
|
|
|
|
|
|
|
|
|
2019-04-12 01:29:48 +08:00
|
|
|
S_GDATA32
|
|
|
|
^^^^^^^^^^
|
|
|
|
|
|
|
|
S_GTHREAD32 (0x1113)
|
|
|
|
^^^^^^^^^^^^^^^^^^^^
|
|
|
|
|
|
|
|
S_PROCREF (0x1125)
|
|
|
|
^^^^^^^^^^^^^^^^^^
|
|
|
|
|
|
|
|
S_LPROCREF (0x1127)
|
|
|
|
^^^^^^^^^^^^^^^^^^^
|
|
|
|
|
|
|
|
S_GMANDATA (0x111d)
|
|
|
|
^^^^^^^^^^^^^^^^^^^
|
|
|
|
|
|
|
|
.. _module_symbols:
|
|
|
|
|
|
|
|
Module Symbols
|
|
|
|
--------------
|
|
|
|
|
|
|
|
S_END (0x0006)
|
|
|
|
^^^^^^^^^^^^^^
|
|
|
|
|
|
|
|
S_FRAMEPROC (0x1012)
|
|
|
|
^^^^^^^^^^^^^^^^^^^^
|
|
|
|
|
|
|
|
S_OBJNAME (0x1101)
|
|
|
|
^^^^^^^^^^^^^^^^^^
|
|
|
|
|
|
|
|
S_THUNK32 (0x1102)
|
|
|
|
^^^^^^^^^^^^^^^^^^
|
|
|
|
|
|
|
|
S_BLOCK32 (0x1103)
|
|
|
|
^^^^^^^^^^^^^^^^^^
|
|
|
|
|
|
|
|
S_LABEL32 (0x1105)
|
|
|
|
^^^^^^^^^^^^^^^^^^
|
|
|
|
|
|
|
|
S_REGISTER (0x1106)
|
|
|
|
^^^^^^^^^^^^^^^^^^^
|
|
|
|
|
|
|
|
S_BPREL32 (0x110b)
|
|
|
|
^^^^^^^^^^^^^^^^^^
|
|
|
|
|
|
|
|
S_LPROC32 (0x110f)
|
|
|
|
^^^^^^^^^^^^^^^^^^
|
|
|
|
|
|
|
|
S_GPROC32 (0x1110)
|
|
|
|
^^^^^^^^^^^^^^^^^^
|
|
|
|
|
|
|
|
S_REGREL32 (0x1111)
|
|
|
|
^^^^^^^^^^^^^^^^^^^
|
|
|
|
|
|
|
|
S_COMPILE2 (0x1116)
|
|
|
|
^^^^^^^^^^^^^^^^^^^
|
|
|
|
|
|
|
|
S_UNAMESPACE (0x1124)
|
|
|
|
^^^^^^^^^^^^^^^^^^^^^
|
|
|
|
|
|
|
|
S_TRAMPOLINE (0x112c)
|
|
|
|
^^^^^^^^^^^^^^^^^^^^^
|
|
|
|
|
|
|
|
S_SECTION (0x1136)
|
|
|
|
^^^^^^^^^^^^^^^^^^
|
|
|
|
|
|
|
|
S_COFFGROUP (0x1137)
|
|
|
|
^^^^^^^^^^^^^^^^^^^^
|
|
|
|
|
|
|
|
S_EXPORT (0x1138)
|
|
|
|
^^^^^^^^^^^^^^^^^
|
|
|
|
|
|
|
|
S_CALLSITEINFO (0x1139)
|
|
|
|
^^^^^^^^^^^^^^^^^^^^^^^
|
|
|
|
|
|
|
|
S_FRAMECOOKIE (0x113a)
|
|
|
|
^^^^^^^^^^^^^^^^^^^^^^
|
|
|
|
|
|
|
|
S_COMPILE3 (0x113c)
|
|
|
|
^^^^^^^^^^^^^^^^^^^
|
|
|
|
|
|
|
|
S_ENVBLOCK (0x113d)
|
|
|
|
^^^^^^^^^^^^^^^^^^^
|
|
|
|
|
|
|
|
S_LOCAL (0x113e)
|
|
|
|
^^^^^^^^^^^^^^^^
|
|
|
|
|
|
|
|
S_DEFRANGE (0x113f)
|
|
|
|
^^^^^^^^^^^^^^^^^^^
|
|
|
|
|
|
|
|
S_DEFRANGE_SUBFIELD (0x1140)
|
|
|
|
^^^^^^^^^^^^^^^^^^^^^^^^^^^^
|
|
|
|
|
|
|
|
S_DEFRANGE_REGISTER (0x1141)
|
|
|
|
^^^^^^^^^^^^^^^^^^^^^^^^^^^^
|
|
|
|
|
|
|
|
S_DEFRANGE_FRAMEPOINTER_REL (0x1142)
|
|
|
|
^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
|
|
|
|
|
|
|
|
S_DEFRANGE_SUBFIELD_REGISTER (0x1143)
|
|
|
|
^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
|
|
|
|
|
|
|
|
S_DEFRANGE_FRAMEPOINTER_REL_FULL_SCOPE (0x1144)
|
|
|
|
^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
|
|
|
|
|
|
|
|
S_DEFRANGE_REGISTER_REL (0x1145)
|
|
|
|
^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
|
|
|
|
|
|
|
|
S_LPROC32_ID (0x1146)
|
|
|
|
^^^^^^^^^^^^^^^^^^^^^
|
|
|
|
|
|
|
|
S_GPROC32_ID (0x1147)
|
|
|
|
^^^^^^^^^^^^^^^^^^^^^
|
|
|
|
|
|
|
|
S_BUILDINFO (0x114c)
|
|
|
|
^^^^^^^^^^^^^^^^^^^^
|
|
|
|
|
|
|
|
S_INLINESITE (0x114d)
|
|
|
|
^^^^^^^^^^^^^^^^^^^^^
|
|
|
|
|
|
|
|
S_INLINESITE_END (0x114e)
|
|
|
|
^^^^^^^^^^^^^^^^^^^^^^^^^
|
|
|
|
|
|
|
|
S_PROC_ID_END (0x114f)
|
|
|
|
^^^^^^^^^^^^^^^^^^^^^^
|
|
|
|
|
|
|
|
S_FILESTATIC (0x1153)
|
|
|
|
^^^^^^^^^^^^^^^^^^^^^
|
|
|
|
|
|
|
|
S_LPROC32_DPC (0x1155)
|
|
|
|
^^^^^^^^^^^^^^^^^^^^^^
|
|
|
|
|
|
|
|
S_LPROC32_DPC_ID (0x1156)
|
|
|
|
^^^^^^^^^^^^^^^^^^^^^^^^^
|
|
|
|
|
|
|
|
S_CALLEES (0x115a)
|
|
|
|
^^^^^^^^^^^^^^^^^^
|
|
|
|
|
|
|
|
S_CALLERS (0x115b)
|
|
|
|
^^^^^^^^^^^^^^^^^^
|
|
|
|
|
|
|
|
S_HEAPALLOCSITE (0x115e)
|
|
|
|
^^^^^^^^^^^^^^^^^^^^^^^^
|
|
|
|
|
|
|
|
S_FASTLINK (0x1167)
|
|
|
|
^^^^^^^^^^^^^^^^^^^
|
|
|
|
|
|
|
|
S_INLINEES (0x1168)
|
|
|
|
^^^^^^^^^^^^^^^^^^^
|
|
|
|
|
|
|
|
.. _module_and_global_symbols:
|
|
|
|
|
|
|
|
Symbols which can go in either/both of the module info stream & global stream
|
|
|
|
-----------------------------------------------------------------------------
|
|
|
|
|
|
|
|
S_CONSTANT (0x1107)
|
|
|
|
^^^^^^^^^^^^^^^^^^^
|
|
|
|
|
|
|
|
S_UDT (0x1108)
|
|
|
|
^^^^^^^^^^^^^^
|
|
|
|
|
|
|
|
S_LDATA32 (0x110c)
|
|
|
|
^^^^^^^^^^^^^^^^^^
|
|
|
|
|
|
|
|
S_LTHREAD32 (0x1112)
|
|
|
|
^^^^^^^^^^^^^^^^^^^^
|
|
|
|
|
|
|
|
S_LMANDATA (0x111c)
|
|
|
|
^^^^^^^^^^^^^^^^^^^
|
|
|
|
|
|
|
|
S_MANCONSTANT (0x112d)
|
|
|
|
^^^^^^^^^^^^^^^^^^^^^^
|
|
|
|
|