| .. _abidiff_label: |
| |
| ======= |
| abidiff |
| ======= |
| |
| abidiff compares the Application Binary Interfaces (ABI) of two shared |
| libraries in `ELF`_ format. It emits a meaningful report describing the |
| differences between the two ABIs. |
| |
| This tool can also compare the textual representations of the ABI of |
| two ELF binaries (as emitted by ``abidw``) or an ELF binary against a |
| textual representation of another ELF binary. |
| |
| For a comprehensive ABI change report that includes changes about |
| function and variable sub-types, the two input shared libraries must |
| be accompanied with their debug information in `DWARF`_ format. |
| Otherwise, only `ELF`_ symbols that were added or removed are |
| reported. |
| |
| .. _abidiff_invocation_label: |
| |
| Invocation |
| ========== |
| |
| :: |
| |
| abidiff [options] <first-shared-library> <second-shared-library> |
| |
| |
| Environment |
| =========== |
| |
| .. _abidiff_default_supprs_label: |
| |
| abidiff loads two default :ref:`suppression specifications files |
| <suppr_spec_label>`, merges their content and use it to filter out ABI |
| change reports that might be considered as false positives to users. |
| |
| * Default system-wide suppression specification file |
| |
| It's located by the optional environment variable |
| LIBABIGAIL_DEFAULT_SYSTEM_SUPPRESSION_FILE. If that environment |
| variable is not set, then abidiff tries to load the suppression file |
| $libdir/libabigail/libabigail-default.abignore. If that file is not |
| present, then no default system-wide suppression specification file |
| is loaded. |
| |
| * Default user suppression specification file. |
| |
| It's located by the optional environment |
| LIBABIGAIL_DEFAULT_USER_SUPPRESSION_FILE. If that environment |
| variable is not set, then abidiff tries to load the suppression file |
| $HOME/.abignore. If that file is not present, then no default user |
| suppression specification is loaded. |
| |
| .. _abidiff_options_label: |
| |
| Options |
| ======= |
| |
| * ``--help | -h`` |
| |
| Display a short help about the command and exit. |
| |
| * ``--debug`` |
| |
| In this mode, error messages are emitted for types which fail type canonicalization. |
| |
| This is an optional ebugging and sanity check option. To enable |
| it the libabigail package needs to be configured with |
| the --enable-debug-self-comparison option. |
| |
| |
| * ``--version | -v`` |
| |
| Display the version of the program and exit. |
| |
| * ``--debug-info-dir1 | --d1`` <*di-path1*> |
| |
| For cases where the debug information for *first-shared-library* |
| is split out into a separate file, tells ``abidiff`` where to find |
| that separate debug information file. |
| |
| Note that *di-path* must point to the root directory under which |
| the debug information is arranged in a tree-like manner. Under |
| Red Hat based systems, that directory is usually |
| ``<root>/usr/lib/debug``. |
| |
| This option can be provided several times with different root |
| directories. In that case, ``abidiff`` will potentially look into |
| all those root directories to find the split debug info for |
| *first-shared-library*. |
| |
| Note also that this option is not mandatory for split debug |
| information installed by your system's package manager because |
| then ``abidiff`` knows where to find it. |
| |
| * ``--debug-info-dir2 | --d2`` <*di-path2*> |
| |
| Like ``--debug-info-dir1``, this options tells ``abidiff`` where |
| to find the split debug information for the |
| *second-shared-library* file. |
| |
| This option can be provided several times with different root |
| directories. In that case, ``abidiff`` will potentially look into |
| all those root directories to find the split debug info for |
| *second-shared-library*. |
| |
| * ``--headers-dir1 | --hd1`` <headers-directory-path-1> |
| |
| Specifies where to find the public headers of the first shared |
| library (or binary in general) that the tool has to consider. The |
| tool will thus filter out ABI changes on types that are not |
| defined in public headers. |
| |
| Note that several public header directories can be specified for |
| the first shared library. In that case the ``--headers-dir1`` |
| option should be present several times on the command line, like |
| in the following example: :: |
| |
| $ abidiff --headers-dir1 /some/path \ |
| --headers-dir1 /some/other/path \ |
| binary-version-1 binary-version-2 |
| |
| * ``--header-file1 | --hf1`` <header-file-path-1> |
| |
| Specifies where to find one public header of the first shared |
| library that the tool has to consider. The tool will thus filter |
| out ABI changes on types that are not defined in public headers. |
| |
| * ``--headers-dir2 | --hd2`` <headers-directory-path-1> |
| |
| Specifies where to find the public headers of the second shared |
| library that the tool has to consider. The tool will thus filter |
| out ABI changes on types that are not defined in public headers. |
| |
| Note that several public header directories can be specified for |
| the second shared library. In that case the ``--headers-dir2`` |
| option should be present several times like in the following |
| example: :: |
| |
| $ abidiff --headers-dir2 /some/path \ |
| --headers-dir2 /some/other/path \ |
| binary-version-1 binary-version-2 |
| |
| * ``--header-file2 | --hf2`` <header-file-path-2> |
| |
| Specifies where to find one public header of the second shared |
| library that the tool has to consider. The tool will thus filter |
| out ABI changes on types that are not defined in public headers. |
| |
| * ``--no-linux-kernel-mode`` |
| |
| Without this option, if abidiff detects that the binaries it is |
| looking at are Linux Kernel binaries (either vmlinux or modules) |
| then it only considers functions and variables which ELF symbols |
| are listed in the __ksymtab and __ksymtab_gpl sections. |
| |
| With this option, abidiff considers the binary as a non-special |
| ELF binary. It thus considers functions and variables which are |
| defined and exported in the ELF sense. |
| |
| * ``--kmi-whitelist | -kaw`` <*path-to-whitelist*> |
| |
| When analyzing a Linux kernel binary, this option points to the |
| white list of names of ELF symbols of functions and variables |
| which ABI must be considered. That white list is called a "Kernel |
| Module Interface white list". This is because for the Kernel, we |
| don't talk about ``ABI``; we rather talk about the interface |
| between the Kernel and its module. Hence the term ``KMI`` rather |
| than ``ABI``. |
| |
| Any other function or variable which ELF symbol are not present in |
| that white list will not be considered by this tool. |
| |
| If this option is not provided -- thus if no white list is |
| provided -- then the entire KMI, that is, the set of all publicly |
| defined and exported functions and global variables by the Linux |
| Kernel binaries, is considered. |
| |
| * ``--drop-private-types`` |
| |
| This option is to be used with the ``--headers-dir1``, |
| ``header-file1``, ``header-file2`` and ``--headers-dir2`` options. |
| With this option, types that are *NOT* defined in the headers are |
| entirely dropped from the internal representation build by |
| Libabigail to represent the ABI. They thus don't have to be |
| filtered out from the final ABI change report because they are not |
| even present in Libabigail's representation. |
| |
| Without this option however, those private types are kept in the |
| internal representation and later filtered out from the report. |
| |
| This options thus potentially makes Libabigail consume less |
| memory. It's meant to be mainly used to optimize the memory |
| consumption of the tool on binaries with a lot of publicly defined |
| and exported types. |
| |
| * ``--stat`` |
| |
| Rather than displaying the detailed ABI differences between |
| *first-shared-library* and *second-shared-library*, just display |
| some summary statistics about these differences. |
| |
| * ``--symtabs`` |
| |
| Only display the symbol tables of the *first-shared-library* and |
| *second-shared-library*. |
| |
| * ``--deleted-fns`` |
| |
| In the resulting report about the differences between |
| *first-shared-library* and *second-shared-library*, only display |
| the globally defined functions that got deleted from |
| *first-shared-library*. |
| |
| * ``--changed-fns`` |
| |
| In the resulting report about the differences between |
| *first-shared-library* and *second-shared-library*, only display |
| the changes in sub-types of the global functions defined in |
| *first-shared-library*. |
| |
| * ``--added-fns`` |
| |
| In the resulting report about the differences between |
| *first-shared-library* and *second-shared-library*, only display |
| the globally defined functions that were added to |
| *second-shared-library*. |
| |
| * ``--deleted-vars`` |
| |
| In the resulting report about the differences between |
| *first-shared-library* and *second-shared-library*, only display |
| the globally defined variables that were deleted from |
| *first-shared-library*. |
| |
| * ``--changed-vars`` |
| |
| In the resulting report about the differences between |
| *first-shared-library* and *second-shared-library*, only display |
| the changes in the sub-types of the global variables defined in |
| *first-shared-library* |
| |
| * ``--added-vars`` |
| |
| In the resulting report about the differences between |
| *first-shared-library* and *second-shared-library*, only display |
| the global variables that were added (defined) to |
| *second-shared-library*. |
| |
| * ``--non-reachable-types|-t`` |
| |
| Analyze and emit change reports for all the types of the binary, |
| including those that are not reachable from global functions and |
| variables. |
| |
| This option might incur some serious performance degradation as |
| the number of types analyzed can be huge. However, if paired with |
| the ``--headers-dir{1,2}`` and/or ``header-file{1,2}`` options, |
| the additional non-reachable types analyzed are restricted to |
| those defined in public headers files, thus hopefully making the |
| performance hit acceptable. |
| |
| Also, using this option alongside suppression specifications (by |
| also using the ``--suppressions`` option) might help keep the number of |
| analyzed types (and the potential performance degradation) in |
| control. |
| |
| Note that without this option, only types that are reachable from |
| global functions and variables are analyzed, so the tool detects |
| and reports changes on these reachable types only. |
| |
| * ``--no-added-syms`` |
| |
| In the resulting report about the differences between |
| *first-shared-library* and *second-shared-library*, do not display |
| added functions or variables. Do not display added functions or |
| variables ELF symbols either. All other kinds of changes are |
| displayed unless they are explicitely forbidden by other options |
| on the command line. |
| |
| * ``--no-linkage-name`` |
| |
| In the resulting report, do not display the linkage names of |
| the added, removed, or changed functions or variables. |
| |
| * ``--no-show-locs`` |
| |
| Do not show information about where in the *second shared library* |
| the respective type was changed. |
| |
| * ``--show-bytes`` |
| |
| Show sizes and offsets in bytes, not bits. By default, sizes and |
| offsets are shown in bits. |
| |
| * ``--show-bits`` |
| |
| Show sizes and offsets in bits, not bytes. This option is |
| activated by default. |
| |
| * ``--show-hex`` |
| |
| Show sizes and offsets in hexadecimal base. |
| |
| * ``--show-dec`` |
| |
| Show sizes and offsets in decimal base. This option is activated |
| by default. |
| |
| * ``--no-show-relative-offset-changes`` |
| |
| Without this option, when the offset of a data member changes, |
| the change report not only mentions the older and newer offset, |
| but it also mentions by how many bits the data member changes. |
| With this option, the latter is not shown. |
| |
| * ``--no-unreferenced-symbols`` |
| |
| In the resulting report, do not display change information about |
| function and variable symbols that are not referenced by any debug |
| information. Note that for these symbols not referenced by any |
| debug information, the change information displayed is either |
| added or removed symbols. |
| |
| * ``--no-default-suppression`` |
| |
| Do not load the :ref:`default suppression specification files |
| <abidiff_default_supprs_label>`. |
| |
| * ``--suppressions | --suppr`` <*path-to-suppressions*> |
| |
| Use a :ref:`suppression specification <suppr_spec_label>` file |
| located at *path-to-suppressions*. Note that this option can |
| appear multiple times on the command line. In that case, all of |
| the provided suppression specification files are taken into |
| account. |
| |
| Please note that, by default, if this option is not provided, then |
| the :ref:`default suppression specification files |
| <abidiff_default_supprs_label>` are loaded . |
| |
| * ``--drop`` <*regex*> |
| |
| When reading the *first-shared-library* and |
| *second-shared-library* ELF input files, drop the globally defined |
| functions and variables which name match the regular expression |
| *regex*. As a result, no change involving these functions or |
| variables will be emitted in the diff report. |
| |
| * ``--drop-fn`` <*regex*> |
| |
| When reading the *first-shared-library* and |
| *second-shared-library* ELF input files, drop the globally defined |
| functions which name match the regular expression *regex*. As a |
| result, no change involving these functions will be emitted in the |
| diff report. |
| |
| * ``--drop-var`` <*regex*> |
| |
| When reading the *first-shared-library* and |
| *second-shared-library* ELF input files, drop the globally defined |
| variables matching a the regular expression *regex*. |
| |
| * ``--keep`` <*regex*> |
| |
| When reading the *first-shared-library* and |
| *second-shared-library* ELF input files, keep the globally defined |
| functions and variables which names match the regular expression |
| *regex*. All other functions and variables are dropped on the |
| floor and will thus not appear in the resulting diff report. |
| |
| * ``--keep-fn`` <*regex*> |
| |
| When reading the *first-shared-library* and |
| *second-shared-library* ELF input files, keep the globally defined |
| functions which name match the regular expression *regex*. All |
| other functions are dropped on the floor and will thus not appear |
| in the resulting diff report. |
| |
| * ``--keep-var`` <*regex*> |
| |
| When reading the *first-shared-library* and |
| *second-shared-library* ELF input files, keep the globally defined |
| which names match the regular expression *regex*. All other |
| variables are dropped on the floor and will thus not appear in the |
| resulting diff report. |
| |
| * ``--harmless`` |
| |
| In the diff report, display only the :ref:`harmless |
| <harmlesschangeconcept_label>` changes. By default, the harmless |
| changes are filtered out of the diff report keep the clutter to a |
| minimum and have a greater chance to spot real ABI issues. |
| |
| * ``--no-harmful`` |
| |
| In the diff report, do not display the :ref:`harmful |
| <harmfulchangeconcept_label>` changes. By default, only the |
| harmful changes are displayed in diff report. |
| |
| * ``--redundant`` |
| |
| In the diff report, do display redundant changes. A redundant |
| change is a change that has been displayed elsewhere in the |
| report. |
| |
| * ``--no-redundant`` |
| |
| In the diff report, do *NOT* display redundant changes. A |
| redundant change is a change that has been displayed elsewhere in |
| the report. This option is switched on by default. |
| |
| * ``--no-architecture`` |
| |
| Do not take architecture in account when comparing ABIs. |
| |
| * ``--no-corpus-path`` |
| |
| Do not emit the path attribute for the ABI corpus. |
| |
| * ``--fail-no-debug-info`` |
| |
| If no debug info was found, then this option makes the program to |
| fail. Otherwise, without this option, the program will attempt to |
| compare properties of the binaries that are not related to debug |
| info, like pure ELF properties. |
| |
| * ``--leaf-changes-only|-l`` only show leaf changes, so don't show |
| impact analysis report. This option implies ``--redundant``. |
| |
| The typical output of abidiff when comparing two binaries looks |
| like this :: |
| |
| $ abidiff libtest-v0.so libtest-v1.so |
| Functions changes summary: 0 Removed, 1 Changed, 0 Added function |
| Variables changes summary: 0 Removed, 0 Changed, 0 Added variable |
| |
| 1 function with some indirect sub-type change: |
| |
| [C]'function void fn(C&)' at test-v1.cc:13:1 has some indirect sub-type changes: |
| parameter 1 of type 'C&' has sub-type changes: |
| in referenced type 'struct C' at test-v1.cc:7:1: |
| type size hasn't changed |
| 1 data member change: |
| type of 'leaf* C::m0' changed: |
| in pointed to type 'struct leaf' at test-v1.cc:1:1: |
| type size changed from 32 to 64 bits |
| 1 data member insertion: |
| 'char leaf::m1', at offset 32 (in bits) at test-v1.cc:4:1 |
| |
| $ |
| |
| So in that example the report emits information about how the data |
| member insertion change of "struct leaf" is reachable from |
| function "void fn(C&)". In other words, the report not only shows |
| the data member change on "struct leaf", but it also shows the |
| impact of that change on the function "void fn(C&)". |
| |
| In abidiff parlance, the change on "struct leaf" is called a leaf |
| change. So the ``--leaf-changes-only --impacted-interfaces`` |
| options show, well, only the leaf change. And it goes like this: |
| :: |
| |
| $ abidiff -l libtest-v0.so libtest-v1.so |
| 'struct leaf' changed: |
| type size changed from 32 to 64 bits |
| 1 data member insertion: |
| 'char leaf::m1', at offset 32 (in bits) at test-v1.cc:4:1 |
| |
| one impacted interface: |
| function void fn(C&) |
| $ |
| |
| Note how the report ends by showing the list of interfaces |
| impacted by the leaf change. |
| |
| Now if you don't want to see that list of impacted interfaces, |
| then you can just avoid using the ``--impacted-interface`` option. |
| You can learn about that option below, in any case. |
| |
| |
| * ``--impacted-interfaces`` |
| |
| When showing leaf changes, this option instructs abidiff to show |
| the list of impacted interfaces. This option is thus to be used |
| in addition the ``--leaf-changes-only`` option, otherwise, it's |
| ignored. |
| |
| |
| * ``--dump-diff-tree`` |
| |
| After the diff report, emit a textual representation of the diff |
| nodes tree used by the comparison engine to represent the changed |
| functions and variables. That representation is emitted to the |
| error output for debugging purposes. Note that this diff tree is |
| relevant only to functions and variables that have some sub-type |
| changes. Added or removed functions and variables do not have any |
| diff nodes tree associated to them. |
| |
| * ``--ctf`` |
| |
| When comparing binaries, extract ABI information from CTF debug |
| information, if present. |
| |
| * ``--stats`` |
| |
| Emit statistics about various internal things. |
| |
| * ``--verbose`` |
| |
| Emit verbose logs about the progress of miscellaneous internal |
| things. |
| |
| .. _abidiff_return_value_label: |
| |
| Return values |
| ============= |
| |
| The exit code of the ``abidiff`` command is either 0 if the ABI of the |
| binaries being compared are equal, or non-zero if they differ or if |
| the tool encountered an error. |
| |
| In the later case, the exit code is a 8-bits-wide bit field in which |
| each bit has a specific meaning. |
| |
| The first bit, of value 1, named ``ABIDIFF_ERROR`` means there was an |
| error. |
| |
| The second bit, of value 2, named ``ABIDIFF_USAGE_ERROR`` means there |
| was an error in the way the user invoked the tool. It might be set, |
| for instance, if the user invoked the tool with an unknown command |
| line switch, with a wrong number or argument, etc. If this bit is |
| set, then the ``ABIDIFF_ERROR`` bit must be set as well. |
| |
| The third bit, of value 4, named ``ABIDIFF_ABI_CHANGE`` means the ABI |
| of the binaries being compared are different. |
| |
| The fourth bit, of value 8, named ``ABIDIFF_ABI_INCOMPATIBLE_CHANGE`` |
| means the ABI of the binaries compared are different in an |
| incompatible way. If this bit is set, then the ``ABIDIFF_ABI_CHANGE`` |
| bit must be set as well. If the ``ABIDIFF_ABI_CHANGE`` is set and the |
| ``ABIDIFF_INCOMPATIBLE_CHANGE`` is *NOT* set, then it means that the |
| ABIs being compared might or might not be compatible. In that case, a |
| human being needs to review the ABI changes to decide if they are |
| compatible or not. |
| |
| Note that, at the moment, there are only a few kinds of ABI changes |
| that would result in setting the flag ``ABIDIFF_ABI_INCOMPATIBLE_CHANGE``. |
| Those ABI changes are either: |
| |
| - the removal of the symbol of a function or variable that has been |
| defined and exported. |
| - the modification of the index of a member of a virtual function |
| table (for C++ programs and libraries). |
| |
| With time, when more ABI change patterns are found to *always* |
| constitute incompatible ABI changes, we will adapt the code to |
| recognize those cases and set the ``ABIDIFF_ABI_INCOMPATIBLE_CHANGE`` |
| accordingly. So, if you find such patterns, please let us know. |
| |
| The remaining bits are not used for the moment. |
| |
| .. _abidiff_usage_example_label: |
| |
| Usage examples |
| ============== |
| |
| 1. Detecting a change in a sub-type of a function: :: |
| |
| $ cat -n test-v0.cc |
| 1 // Compile this with: |
| 2 // g++ -g -Wall -shared -o libtest-v0.so test-v0.cc |
| 3 |
| 4 struct S0 |
| 5 { |
| 6 int m0; |
| 7 }; |
| 8 |
| 9 void |
| 10 foo(S0* /*parameter_name*/) |
| 11 { |
| 12 // do something with parameter_name. |
| 13 } |
| $ |
| $ cat -n test-v1.cc |
| 1 // Compile this with: |
| 2 // g++ -g -Wall -shared -o libtest-v1.so test-v1.cc |
| 3 |
| 4 struct type_base |
| 5 { |
| 6 int inserted; |
| 7 }; |
| 8 |
| 9 struct S0 : public type_base |
| 10 { |
| 11 int m0; |
| 12 }; |
| 13 |
| 14 void |
| 15 foo(S0* /*parameter_name*/) |
| 16 { |
| 17 // do something with parameter_name. |
| 18 } |
| $ |
| $ g++ -g -Wall -shared -o libtest-v0.so test-v0.cc |
| $ g++ -g -Wall -shared -o libtest-v1.so test-v1.cc |
| $ |
| $ ../build/tools/abidiff libtest-v0.so libtest-v1.so |
| Functions changes summary: 0 Removed, 1 Changed, 0 Added function |
| Variables changes summary: 0 Removed, 0 Changed, 0 Added variable |
| |
| 1 function with some indirect sub-type change: |
| |
| [C]'function void foo(S0*)' has some indirect sub-type changes: |
| parameter 0 of type 'S0*' has sub-type changes: |
| in pointed to type 'struct S0': |
| size changed from 32 to 64 bits |
| 1 base class insertion: |
| struct type_base |
| 1 data member change: |
| 'int S0::m0' offset changed from 0 to 32 |
| $ |
| |
| |
| 2. Detecting another change in a sub-type of a function: :: |
| |
| $ cat -n test-v0.cc |
| 1 // Compile this with: |
| 2 // g++ -g -Wall -shared -o libtest-v0.so test-v0.cc |
| 3 |
| 4 struct S0 |
| 5 { |
| 6 int m0; |
| 7 }; |
| 8 |
| 9 void |
| 10 foo(S0& /*parameter_name*/) |
| 11 { |
| 12 // do something with parameter_name. |
| 13 } |
| $ |
| $ cat -n test-v1.cc |
| 1 // Compile this with: |
| 2 // g++ -g -Wall -shared -o libtest-v1.so test-v1.cc |
| 3 |
| 4 struct S0 |
| 5 { |
| 6 char inserted_member; |
| 7 int m0; |
| 8 }; |
| 9 |
| 10 void |
| 11 foo(S0& /*parameter_name*/) |
| 12 { |
| 13 // do something with parameter_name. |
| 14 } |
| $ |
| $ g++ -g -Wall -shared -o libtest-v0.so test-v0.cc |
| $ g++ -g -Wall -shared -o libtest-v1.so test-v1.cc |
| $ |
| $ ../build/tools/abidiff libtest-v0.so libtest-v1.so |
| Functions changes summary: 0 Removed, 1 Changed, 0 Added function |
| Variables changes summary: 0 Removed, 0 Changed, 0 Added variable |
| |
| 1 function with some indirect sub-type change: |
| |
| [C]'function void foo(S0&)' has some indirect sub-type changes: |
| parameter 0 of type 'S0&' has sub-type changes: |
| in referenced type 'struct S0': |
| size changed from 32 to 64 bits |
| 1 data member insertion: |
| 'char S0::inserted_member', at offset 0 (in bits) |
| 1 data member change: |
| 'int S0::m0' offset changed from 0 to 32 |
| |
| |
| $ |
| |
| 3. Detecting that functions got removed or added to a library: :: |
| |
| $ cat -n test-v0.cc |
| 1 // Compile this with: |
| 2 // g++ -g -Wall -shared -o libtest-v0.so test-v0.cc |
| 3 |
| 4 struct S0 |
| 5 { |
| 6 int m0; |
| 7 }; |
| 8 |
| 9 void |
| 10 foo(S0& /*parameter_name*/) |
| 11 { |
| 12 // do something with parameter_name. |
| 13 } |
| $ |
| $ cat -n test-v1.cc |
| 1 // Compile this with: |
| 2 // g++ -g -Wall -shared -o libtest-v1.so test-v1.cc |
| 3 |
| 4 struct S0 |
| 5 { |
| 6 char inserted_member; |
| 7 int m0; |
| 8 }; |
| 9 |
| 10 void |
| 11 bar(S0& /*parameter_name*/) |
| 12 { |
| 13 // do something with parameter_name. |
| 14 } |
| $ |
| $ g++ -g -Wall -shared -o libtest-v0.so test-v0.cc |
| $ g++ -g -Wall -shared -o libtest-v1.so test-v1.cc |
| $ |
| $ ../build/tools/abidiff libtest-v0.so libtest-v1.so |
| Functions changes summary: 1 Removed, 0 Changed, 1 Added functions |
| Variables changes summary: 0 Removed, 0 Changed, 0 Added variable |
| |
| 1 Removed function: |
| 'function void foo(S0&)' {_Z3fooR2S0} |
| |
| 1 Added function: |
| 'function void bar(S0&)' {_Z3barR2S0} |
| |
| $ |
| |
| .. _ELF: http://en.wikipedia.org/wiki/Executable_and_Linkable_Format |
| .. _DWARF: http://www.dwarfstd.org |
| |