xref: /illumos-gate/usr/src/lib/README.mapfiles (revision 86c48bbfeb72d5a6ee171e713059939bab658b77)
1#
2# CDDL HEADER START
3#
4# The contents of this file are subject to the terms of the
5# Common Development and Distribution License (the "License").
6# You may not use this file except in compliance with the License.
7#
8# You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
9# or http://www.opensolaris.org/os/licensing.
10# See the License for the specific language governing permissions
11# and limitations under the License.
12#
13# When distributing Covered Code, include this CDDL HEADER in each
14# file and include the License file at usr/src/OPENSOLARIS.LICENSE.
15# If applicable, add the following below this CDDL HEADER, with the
16# fields enclosed by brackets "[]" replaced with your own identifying
17# information: Portions Copyright [yyyy] [name of copyright owner]
18#
19# CDDL HEADER END
20#
21#
22# Copyright 2009 Sun Microsystems, Inc.  All rights reserved.
23# Use is subject to license terms.
24#
25
26Mapfiles and versioning in ON
27=============================
28
291.0 Objective of this README
30
31This README describes the engineering practices of creating and updating
32visible library interfaces.  It describes various kinds of actions that
33typically occur as libraries are evolved, and shows how interface
34specifications are affected or updated in accordance.  It tells you what
35you must do as a shared library developer if you:
36
37	1. Make interface additions to an existing library
38		- add a Public interface
39		- add a Private interface
40	2. Update an interface in an existing library
41		- remove an existing interface
42		- promote a Private interface to Public
43		- scope a Private interface to local
44		- move an interface from one library to another
45		- copy interfaces which are part of the standard to a new or
46		  existing library
47	3. Introduce a new library
48		- source directory hierarchy
49		- creation of the "mapfile-vers" file
50		- Makefiles
51	4. Make an entire library obsolete before end-of-life
52		- introduce SUNWobsolete to the "mapfile-vers" file
53
54-------------------------------------------------------------------------------
55
562.0 What's a mapfile?
57
58Mapfiles are used to tell the link editor ("ld") all sorts of things about
59how to generate an executable file or a shared object from a collection of
60relocatable objects, such as generated by a compiler.  For all the gory
61details, see the Solaris Linker and Libraries Guide, which can be found
62under http://docs.sun.com.
63
64Here, we are only concerned with specifying externally-visible interfaces
65for shared libraries (shared objects) and with specifying their versions
66for ABI (Application Binary Interface) purposes.  For these purposes, we
67only need to deal with a subset of the mapfile interfaces.
68
69There should be a "mapfile-vers" file associated with every shared library
70and it should reside in the common source directory for that library, most
71often in a "common" directory.  This is the usual layout of a library's
72top-level directory (usr/src/lib/libwombat):
73	Makefile       amd64/         i386/          sparcv9/
74	Makefile.com   common/        sparc/
75
76The "common" directory contains the source files and other common files
77for the library:
78	bat.c              libwombat_impl.h   mapfile-vers       wom.c
79	libwombat.h        llib-lwombat       util.c             wombat.c
80
81The mapfile's name is, by convention, "mapfile-vers" because it is used
82for only two purposes: to specify externally-visible interface names while
83suppressing visibility of all other names, and to specify their respective
84unique version names.
85
86-------------------------------------------------------------------------------
87
883.0 Contents of mapfile-vers
89
90The structure of mapfile-vers is best explained by an example
91(the license notification and copyright notice is omitted here
92for brevity):
93
94SUNW_1.2 {	# update to libwombat, Solaris 10
95    global:
96	wb_readv;
97	wb_stat;
98	wb_writev;
99} SUNW_1.1;
100
101SUNW_1.1 {	# first release of libwombat, Solaris 9
102    global:
103	wb_read;
104	wb_write;
105};
106
107SUNWprivate {	# private libwombat symbols
108    global:
109	wb_add;
110	wb_delete;
111	wb_search;
112    local:
113	*;
114};
115
116The SUNW_1.* names are the Public version names for the library.
117There should be at most one version name for each release of Solaris,
118with the minor number incremented by one over the previous version.
119
120If no update to the Public-visible names in the library is made
121in a given Solaris release, no new version name should be generated
122for that release.  If multiple updates are made to the library at
123different points in the development of a given release of Solaris,
124only one version should be used for the entire release.
125
126So, for example, if an update to libwombat is made in Solaris 11,
127you would add "SUNW_1.3" at the start of the mapfile:
128
129SUNW_1.3 {	# update to libwombat, Solaris 11
130    global:
131	wb_lseek;
132} SUNW_1.2;
133
134Each version must inherit all symbols from its preceding version,
135specified at the ending "}" for each version.  SUNW_1.1 does not
136inherit any symbols.  SUNWprivate, if present, stands alone.
137
138The two lines in SUNWprivate:
139    local:
140	*;
141ensure that no symbols other than those listed in the mapfile are
142visible to clients of the library.  If there is no SUNWprivate,
143these two lines should appear in SUNW_1.1.
144
145For maintainability, the list of names in each version block should
146be sorted in dictionary order (sort -d).  Please comply.
147
148In addition to the common mapfile:
149	common/mapfile-vers
150some libraries require ISA-specific supplemental mapfiles, one in each
151of the ISA directories:
152	amd64/mapfile-vers
153	i386/mapfile-vers
154	sparc/mapfile-vers
155	sparcv9/mapfile-vers
156This is necessary only if there are ISA-specific library interfaces not
157common to all instances of the library.  For example, see libproc, or,
158if you are masochistic, libc or libnsl.
159
160The ISA-specific mapfiles look like the common mapfile, except that only
161the ISA-specific names appear.  The version names are the same as those
162in the common mapfile, but only non-empty version instances are present
163and no inheritance specification is present. The link-editor reads the
164information from the common and ISA-specific mapfiles and merges them
165in memory into a single description used to create the resulting object.
166
167-------------------------------------------------------------------------------
168
1694.0 Making interface additions to an existing library
170
1714.1 Adding a Public interface
172
173The first engineer to update the existing mapfile-vers file in a release needs
174to identify the current highest version name and properly increment the minor
175version number by 1 to be the new version name.  If this is the first Public
176interface in the shared object, a new SUNW_1.1 version name must be introduced.
177
178The major revision number is incremented whenever an incompatible change is
179made to an interface.  This could be the case if an API changes so dramatically
180as to invalidate dependencies.  This rarely occurs in practice.  It also
181requires changing the suffix of the shared object from, say, .so.1 to .so.2
182and introducing code to continue to ship the .so.1 version of the library.
183
184The minor revision number is incremented whenever one or more new interfaces
185is added to a library.  Note that the minor number is not incremented on every
186putback that makes an interface addition to the library.  Rather, it is
187incremented at most once per (external to Sun) release of the library.
188
1894.2 Adding a Private interface
190
191Private interfaces are the non-ABI interfaces of the library.  Unlike
192introducing a Public interface, a new entry is simply added to the
193SUNWprivate version.  No minor number increment is necessary.
194
195If this interface happens to be the first Private interface introduced
196into the library, the SUNWprivate version must be created (no major.minor
197version numbers).  It inherits nothing and nothing inherits from it.
198
199If the library already has Private interfaces, they may have numbered version
200names like SUNWprivate_m.n (due to errors of the past).  If so, just use the
201highest numbered private version name to version the new interface.  There
202is no need to introduce a new private version name.  Be careful not to use
203a lower numbered private version name; doing so can cause runtime errors
204(as opposed to load time errors) when running an application with older
205versions of the library.
206
207There are libraries in the OSnet consolidation that contain only private
208interfaces. In such libraries, the SUNWprivate_m.n may be incremented
209to ensure that the programs that depend on them are built and delivered as a
210integrated unit. A notable example of this is libld.so (usr/src/cmd/sgs/libld),
211which contains the implementation of the link-editor, the public interface to
212which is provided by the ld command. When making a modification to the interface
213of such a library, you should follow the convention already in place.
214
2154.3 Adding new public interfaces in an update release
216
217Adding new public interfaces in an update release requires careful
218coordination with the next marketing release currently under development.
219Multiple updates ship during the period before the next marketing release
220ships, and since it is generally impossible to know the full set of new
221interfaces in the next marketing release until late in its development
222(after multiple updates have shipped) it must be assumed that not all
223interfaces added to the next marketing release will be added to an update.
224
225Consequently, the new version number for an update cannot be a minor
226increment, but must be a micro increment.  For example, if Release N
227has version number SUNW_1.3 and Release N+1 will have SUNW_1.4, then
228interfaces added to an update of Release N must have micro numbers such
229as SUNW_1.3.1, SUNW_1.3.2, etc.  (note that the micro number is not
230directly tied to the update number: SUNW_1.3.1 may appear in Update 2).
231The micro versions form an inheritance chain that is inserted between
232two successive minor versions.  For example, the mapfile-vers file for
233minor release "N+1" to reflect its inclusion of micro releases will
234look like the following:
235
236SUNW_1.4 {		# release N+1
237    global:
238	...
239} SUNW_1.3.2;
240
241SUNW_1.3.2 {		# micro release 2 (e.g., release NU3)
242    global:
243	...
244} SUNW_1.3.1;
245
246SUNW_1.3.1 {		# micro release 1 (e.g., release NU2)
247    global:
248	...
249} SUNW_1.3;
250
251SUNW_1.3 {		# release N
252    global:
253	...
254} SUNW_1.2;
255
256SUNW_1.2 {		# release N-1
257    global:
258	...
259} SUNW_1.1;
260
261SUNW_1.1 {		# first release
262    global:
263	...
264};
265
266SUNW_private {		# same in all releases
267    global:
268	...
269    local:
270	*;
271};
272
273The corresponding update/patch mapfile-vers file will be identical
274except for the exclusion of SUNW_1.4.
275
276Those interfaces which are only present in Release N+1 are always put
277into the next minor version set, SUNW_1.4.
278
279Thus when adding a new public interface to an update, both the mapfiles
280of the update release and next marketing release must be modified to be
281consistent.  The update versions should not be added to the marketing
282release until the putback to the update release has occurred, to avoid
283timing problems with the update releases (it's all too easy for projects
284to slip out of updates, or to change ordering).
285
286-------------------------------------------------------------------------------
287
2885.0 How to update an interface in an existing library
289
2905.1 Removing an existing interface
291
2925.1.1 Moving a Public interface
293
294No Public interfaces should ever be removed from any mapfile.
295
296To move an interface from one library to (say) libc, the code has to be
297deleted from the library and added to libc, then the mapfile for the
298library has to have the interface's entry changed from:
299	getfoobar;
300to:
301	getfoobar = FUNCTION FILTER libc.so.1;
302See, for example, libnsl's common/mapfile-vers file.
303
304Follow the rules for adding a new interface for the necessary changes
305to libc's mapfile to accommodate the moved interface.  In particular,
306the new interface must be added to the current highest libc version.
307
308To move an entire library into libc, look at what has already been done
309for libthread, libaio, and librt.
310
3115.1.2 Removing a Private interface
312
313Deletion of Private interfaces is allowed, but caution should be taken;
314it should first be established that the interface is not being used.
315To remove a Private interface, simply delete the corresponding entry
316for that symbol from the mapfile's SUNWprivate section.
317
318Do not forget to delete these Public or Private interfaces from the library's
319header files as well as from the code that implements the interfaces.
320
3215.2 Promoting a Private interface to Public
322
323This is similar to what's done when adding a Public interface.  Promoting an
324existing Private interface to a Public one only requires a change to the
325existing interface definition.  Private interfaces have the symbol version name
326"SUNWprivate" associated with them.  To make the interface a Public one, the
327interface must be put into a set associated with the current Public release
328level of the library.
329
330As an example, if we were modifying libwombat.so.1 and its version in the
331last release of Solaris was SUNW_1.23, any new ABI introduced in the next
332release would be put into a version called SUNW_1.24.  Therefore, whether
333you wish to promote an existing Private interface to Public, or to introduce
334a new Public interface, this (next successive minor numbered version level)
335would be the version that it would be associated with.
336
3375.3 Scoping a Private interface local
338
339Any interfaces not present in the mapfile-vers file will be scoped local
340due to the presence of the
341    local:
342	*;
343lines discussed earlier. This ensures that such interfaces will not be visible
344outside the library.  To move an interface from Private to local scope, simply
345remove the Private interface from the mapfile-vers file and the header file
346to prevent it from being exported.  This may require moving the Private
347interface into a library-private header file.  Scope reduction of Public
348interfaces is not allowed without specific ARC review and approval.
349
350For the interface to be used in more than one file within the library, it
351should be in a header file that can be included by each file in the library
352that uses the interface.  For example:
353
354	#include "libprivate.h"
355
3565.4 How to copy interfaces which are part of a standard to a new or existing
357    library
358
359SYSVABI and SISCD are reserved version names for interfaces listed in the
360System V Interface Definition and the Sparc Compliance Definition.  Avoid using
361these version names when copying the implementation of standard interfaces to
362another library.  Instead, use SUNW_1.1 for a new library, and SUNW_m.n for
363an existing library (where m.n is the next release version; i.e., if the
364last version was SUNW_1.18, then you should version the interfaces with
365SUNW_1.19).
366
367-------------------------------------------------------------------------------
368
3696.0 Introducing a new library
370
3716.1 Directories
372
373The normal discipline for introducing a new library in OS/Net is to create a
374new subdirectory of /usr/src/lib.  The interface definition discipline is to
375create a common/mapfile-vers file for the new library.  If we were introducing
376a new foo library, libfoo, we'd create /usr/src/lib/libfoo containing:
377	Makefile       amd64/         i386/          sparcv9/
378	Makefile.com   common/        sparc/
379The common subdirectory would contain the normal source files plus the
380mapfile-vers file.  See usr/src/lib/README.Makefiles for directions on
381how to organize the Makefiles.
382
3836.2 The mapfile
384
385The new common/mapfile-vers file would contain:
386
387SUNW_1.1 {	# first release of libfoo
388    global:
389	...
390};
391
392SUNWprivate {
393    global:
394	...
395    local:
396	*;
397};
398
399If there are no Public interfaces, the SUNW_1.1 section would be omitted.
400If there are no Private interfaces, the SUNWprivate section would be
401omitted and the two lines:
402    local:
403	*;
404would be moved into SUNW_1.1
405
406To decide which interfaces are Public (part of the ABI) and which are Private
407(unstable interfaces not intended to be used by third party applications or
408unbundled products), the heuristic which works to a first approximation is
409that if it has a man page then it's Public.  Also, it is really the ARC case
410for the new interfaces that prescribes which interfaces are Public and
411which are not (hence, which interfaces have man pages and which do not).
412
413For maintainability, the list of names in each version block should
414be sorted in dictionary order (sort -d).  Please comply.
415
416-------------------------------------------------------------------------------
417
4187.0 Make an entire library obsolete
419
4207.1 Introduce SUNWobsolete version
421
422Use this version name not for specific interfaces but for marking an entire
423library as obsolete.  The existing public/private version names are left
424unchanged, but a new SUNWobsolete version is created with no symbols in it.
425This becomes a tag by which the obsolescence of the library can be recognized.
426There is no numbering of this version name.
427
428SUNWobsolete {
429    global:
430	SUNWobsolete;	# This is the only way to do it.
431} SUNW_1.2;
432
433SUNW_1.2 {
434...
435
436-------------------------------------------------------------------------------
437
4388.0 Documentation
439
440For further information, please refer to the following documents:
441
442	"Solaris Linker and Libraries Guide", http://docs.sun.com
443	/shared/ON/general_docs/scoping-rules.fm.ps
444
445For information on the now-obsolete spec files, used in Solaris releases
4467 through 10, see:
447	/shared/ON/general_docs/README.spec
448	/shared/ON/general_docs/libspec-rules.ps
449	/shared/ON/general_docs/spectrans/*
450