浏览代码

dpkg-gensymbols(1): document patterns in the manual page

And small fixups of other parts of the manual page.

Signed-off-by: Modestas Vainius <modax@debian.org>
Signed-off-by: Raphaël Hertzog <hertzog@debian.org>
Modestas Vainius 16 年之前
父节点
当前提交
81f26dad1d
共有 1 个文件被更改,包括 139 次插入27 次删除
  1. 139 27
      man/dpkg-gensymbols.1

+ 139 - 27
man/dpkg-gensymbols.1

@@ -157,12 +157,147 @@ implementation details of the toolchain. If for some reason, you really
 want one of those symbols to be included in the symbols file, you should
 tag the symbol with \fBignore\-blacklist\fP. It can be necessary for
 some low level toolchain libraries like libgcc.
+.TP
+.B c++
+Denotes \fIc++\fR symbol pattern. See \fBUsing symbol patterns\fR subsection
+below.
+.TP
+.B regex
+Denotes \fIregex\fR symbol pattern. See \fBUsing symbol patterns\fR subsection
+below.
+.SS Using symbol patterns
+.P
+Unlike a standard symbol specification, a pattern may cover multiple real
+symbols from the library. \fBdpkg-gensymbols\fR will attempt to match each
+pattern against each real symbol that does \fInot\fR have a specific symbol
+counterpart defined in the symbol file. Whenever the first matching pattern is
+found, all its tags and properties will be used as a basis specification of the
+symbol. If none of the patterns matches, the symbol will be considered as new.
+
+A pattern is considered lost if it does not match any symbol in the library. By
+default this will trigger a \fBdpkg-gensymbols\fR failure under \fI-c1\fR or
+higher level. However, if the failure is undesired, the pattern may be marked
+with the \fIoptional\fR tag. Then if the pattern does not match anything, it
+will only appear in the diff as MISSING. Moreover, like any symbol, the pattern
+may be limited to the specific architectures with the \fIarch\fR tag. Please
+refer to \fBStandard symbol tags\fR subsection above for more information.
+
+Patterns are an extension of the \fIdeb\-symbols(5)\fR format hence they are
+only valid in symbol file templates. Pattern specification syntax is not any
+different from the one of a specific symbol. However, symbol name part of the
+specification serves as an expression to be matched against \fIname@version\fR
+of the real symbol. In order to distinguish among different pattern types, a
+pattern will typically be tagged with a special tag.
+
+At the moment, \fBdpkg\-gensymbols\fR supports three basic pattern types:
+.TP 3
+.B c++
+This pattern is denoted by the \fIc++\fR tag. It matches only C++ symbols by
+their demangled symbol name (as emitted by \fBc++filt\fR(1) utility). This
+pattern is very handy for matching symbols which mangled names might vary
+across different architectures while their demangled names remain the same. One
+group of such symbols is \fInon-virtual thunks\fR which have architecture
+specific offsets embedded in their mangled names. A common instance of this
+case is a virtual destructor which under diamond inheritance needs a
+non-virtual thunk symbol. For example, even if _ZThn8_N3NSB6ClassDD1Ev@Base on
+32bit architectures will probably be _ZThn16_N3NSB6ClassDD1Ev@Base on 64bit
+ones, it can be matched with a single \fIc++\fR pattern:
+.RS
+.PP
+libdummy.so.1 libdummy1 #MINVER#
+ [...]
+ (c++)"non-virtual thunk to NSB::ClassD::~ClassD()@Base" 1.0
+ [...]
+.P
+The demangled name above can be obtained by executing the following command:
+.PP
+ $ echo '_ZThn8_N3NSB6ClassDD1Ev@Base' | c++filt
+.P
+Please note that while mangled name is unique in the library by definition,
+this is not necessarily true for demangled names. A couple of distinct real
+symbols may have the same demangled name. For example, that's the case with
+non-virtual thunk symbols in complex inheritance configurations or with most
+constructors and destructors (since g++ typically generates two real symbols
+for them). However, as these collisions happen on the ABI level, they should
+not degrade quality of the symbol file.
+.RE
+.TP
+.B wildcards
+Wildcard patterns are denoted by the string of the form \fI*@version\fR in the
+symbol name field, e.g. "*@GLIBC_2.0". Well maintained libraries have
+versioned symbols where each version corresponds to the upstream version where
+the symbol got added. If that's the case, you can use wildcard patterns to
+match any symbol associated to the specific version. So "*@GLIBC_2.0" would
+match all symbols associated to the version GLIBC_2.0. For example:
+.RS
+.PP
+libc.so.6 libc6 #MINVER#
+ *@GLIBC_2.0 2.0
+ [...]
+ *@GLIBC_2.7 2.7
+ access@GLIBC_2.0 2.2
+.PP
+All symbols associated with versions GLIBC_2.0 and GLIBC_2.7 will lead to
+minimal version of 2.0 and 2.7 respectively with the exception of the symbol
+access@GLIBC_2.0. The latter will lead to a minimal dependency on libc6 version
+2.2 despite being in the scope of the wildcard "*@GLIBC_2.0" because specific
+symbols take precedence over patterns.
+.RE
+.TP
+.B regex
+Regular expression patterns are denoted by the \fIregex\fR tag. They match by
+the perl regular expression specified in the symbol name field. A regular
+expression is matched as it is, therefore do not forget to start it with the
+\fI^\fR character or it may match any part of the real symbol
+\fIname@version\fR string. For example:
+.RS
+.PP
+libdummy.so.1 libdummy1 #MINVER#
+ (regex)"^mystack_.*@Base$" 1.0
+ (regex|optional)"private" 1.0
+.P
+Symbols like "mystack_new@Base", "mystack_push@Base", "mystack_pop@Base" etc.
+will be matched by the first pattern while e.g. "ng_mystack_new@Base" won't.
+The second pattern will match all symbols having the string "private" in their
+names and matches will inherit \fIoptional\fR tag from the pattern.
+.RE
+.P
+Basic patterns listed above can be combined where it makes sense. In that case,
+they are processed in the order in which the tags are specified. Since wildcard
+pattern does not have a specific tag, it is processed last if the symbol
+specification looks like a wildcard. For example, both
+.PP
+ (c++|regex)"^NSA::ClassA::Private::privmethod\\d\\(int\\)@Base" 1.0
+ (regex|c++)N3NSA6ClassA7Private11privmethod\\dEi@Base 1.0
+.P
+will match symbols "_ZN3NSA6ClassA7Private11privmethod1Ei@Base" and
+"_ZN3NSA6ClassA7Private11privmethod2Ei@Base". When matching the first pattern,
+the raw symbol is first demangled as c++ symbol, then the demangled name is
+matched against the regular expression. On the other hand, when matching the
+second pattern, regular expression is matched against the raw symbol name, then
+the symbol is tested if it is c++ one by attempting to demangle it. A failure
+of any basic pattern will result in the failure of the whole pattern.
+Therefore, for example, "__N3NSA6ClassA7Private11privmethod\\dEi@Base" will not
+match either of the patterns because it is not a valid c++ symbol.
+.P
+In general, all patterns are divided into two groups: aliases (basic c++ and
+wildcards) and generic patterns (regex, all combinations of multiple basic
+patterns). Matching of basic alias-based patterns is fast (O(1)) while generic
+patterns are O(N) (N - generic pattern count) for each symbol.  Therefore, it
+is recommended not to overuse generic patterns.
+.P
+When multiple patterns match the same real symbol, aliases (first c++, then
+wildcards) are preferred over generic patterns. Generic patterns are matched in
+the order they are found in the symbol file template until the first success.
+Please note, however, that manual reordering of template file entries is not
+recommended because \fBdpkg-gensymbols\fR generates diffs based on the
+alphanumerical order of their names.
 .SS Using includes
-.P 
+.P
 When the set of exported symbols differ between architectures, it may become
 inefficient to use a single symbol file. In those cases, an include directive
 may prove to be useful in a couple of ways:
-.IP \(bu
+.IP \(bu 4
 You can factorize the common part in some external file
 and include that file in your \fIpackage\fR.symbols.\fIarch\fR file by
 using an include directive like this:
@@ -199,29 +334,6 @@ to do it is the following:
 .PP
 #include "libsomething1.symbols.common"
  arch_specific_symbol@Base 1.0
-.SS Using wildcards with versioned symbols
-.P
-Well maintained libraries have versioned symbols where each version
-corresponds to the upstream version where the symbol got added. If that's
-the case, it's possible to write a symbols file with wildcard entries like
-"*@GLIBC_2.0" that would match any symbol associated to the version
-GLIBC_2.0. It's still possible to include specific symbols in the file,
-they'll take precedence over any matching wildcard entry. An example:
-.PP
-libc.so.6 libc6 #MINVER#
- *@GLIBC_2.0 2.0
- [...]
- *@GLIBC_2.7 2.7
- access@GLIBC_2.0 2.2
-.P
-The symbol access@GLIBC_2.0 will lead to a minimal dependency on libc6
-version 2.2 despite the wildcard entry *@GLIBC_2.0 which associates
-symbols versioned as GLIBC_2.0 with the minimal version 2.0.
-.P
-Note that using wildcards means that \fBdpkg\-gensymbols\fR can't check
-for symbols that might have disappeared and can't generate a diff between
-the maintainer-supplied symbols file and the generated one in the binary
-package.
 .SS Good library management
 .P
 A well-maintained library has the following features:
@@ -278,11 +390,11 @@ newer upstream version of your library.
 .TP
 .BI \-t
 Write the symbol file in template mode rather than the format compatible with
-\fIdeb-symbols(5)\fR. The main difference is that in the template mode symbol
+\fIdeb\-symbols(5)\fR. The main difference is that in the template mode symbol
 names and tags are written in their original form contrary to the
 post-processed symbol names with tags stripped in the compatibility mode.
 Moreover, some symbols might be omitted when writing a standard
-\fIdeb-symbols(5)\fR file (according to the tag processing rules) while all
+\fIdeb\-symbols(5)\fR file (according to the tag processing rules) while all
 symbols are always written to the symbol file template.
 .TP
 .BI \-c [0-4]