Method and apparatus for internal versioning of objects using a mapfile5805899Abstract A method and apparatus for providing versioning information for a plurality of software objects. When an object is compiled and linked, at build time, the link-editor creates a version definition section and a version symbol section in the object that specify the global symbols defined in various versions of the object. The object can be a shared object, a relocatable object, or a dynamic executable object. When an application software program is linked with the versioned object, at build time, the linker-editor creates a version dependency section in the resulting dynamic executable object that specifies which version of the object is required for execution of the software application program. At runtime, the runtime-linker determines whether all required versions of the object are present before the program is executed. The invention allows the definition of "weak" versions that do not contain new global symbols. The invention also allows the explicit specification of the version of an object to which the software application program should be linked. Claims What is claimed is: Description BACKGROUND OF THE INVENTION
TABLE 1
______________________________________
(source code for shared object)
______________________________________
$ cat foo.c
extern const char * .sub.-- foo1;
extern const char * .sub.-- foo2;
void foo1( )
(void) printf(.sub.-- foo1);
}
void foo2( )
{
(void) printf(.sub.-- foo2);
}
$ cat data.c
const char * .sub.-- foo1 = "string used by function foo1 (
).backslash.n";
const char * .sub.-- foo2 = "string used by function foo2 (
).backslash.n";
$ cat bar1.c
extern void foo1( );
void bar1( )
{
foo1( );
}
$ cat bar2.c
extern void foo2( );
void bar2( )
{
foo2( );
}
______________________________________
FIG. 4 shows a format of mapfile 130, using a format in which square brackets ("›" and "!") indicate an optional element. Shared object 114 provides global symbols to which other objects, such as dynamic executable 120, can bind at runtime. These global symbols are specified in mapfile 130 and describe an Application Binary Interface (ABI) of shared object 114. During the lifetime of shared object 114, the interface of an object can change due to the addition or deletion of global symbols. In addition, the evolution of shared object 114 may involve internal implementation changes to shared object 114 that do not affect the global symbols of the interface. Table 2 shows an example of mapfile 130. In Table 2, mapfile 130 contains version definitions for versions SUNW.1.1, SUNW.1.2, SUNW.1.2.1, SUNW.1.3a, SUNW.1.3b, and SUNW.1.4 of shared object 114. The version definitions include all versions (and their global symbols) ever defined for shared object 114. In the example, SUNW.1.1 is a version of shared object 114 contained in Release X; SUNW.1.2 is a version of shared object 114 contained in Release X+1, which inherits the global symbols of version SUNW.1.1. SUNW.1.2.1 is a version of shared object 114 contained in Release X+2, which inherits the global symbols of version SUNW.1.2. Note that SUNW.1.2.1 is a "weak" version because it does not contain any new global symbols. This version indicates an "implementation" change in the shared object. The other versions indicate "interface" changes. SUNW.1.2.1 represents a version having changes to the function of the shared object, but not to its interface. SUNW.1.3a is a version of shared object 114 contained in Release X+3, which inherits the global symbols of version SUNW.1.2. SUNW.1.3b is also a part of Release X+3 and also inherits the global symbols of version SUNW.1.2. Version SUNW.1.3b, however, defines the global symbol "bar2", instead of the global symbol "bar1", which is defined in version SUNW.1.3a. Version SUNW.1.4 defines one global symbol "bar3" and also inherits the global symbols of both SUNW.1.3a and SUNW.1.3b. In the example of Table 2, the symbol "foo1" is the only global symbol defined in the public interface of version SUNW.1.1. The special "auto-reduction" directive (".sup.* ") causes the reduction of all other global symbols of the shared object to have local scope so that they are not a part of the interface to the shared object. Thus, the public interface of shared object 114 for version SUNW.1.1 consists of the internal version definition for that version, associated with the global symbol "foo1". Table 3 shows unix commands to compile and link the source code files of Table 1. The object codes files "foo.o", "data.o" "bar1.o", and "bar2.o" (not shown) are dynamically linked using mapfile 130 of Table 2 to produce a shared object 114 called "libfoo.so.1". (In this example, the cc compiler automatically calls the ld(1) link-editor 124.) The "-G" option on the command line indicates that link-editor 124 should produce a shared object, and not an executable object. The "ln" command creates a "compilation environment" name suitable for the "-1" option of ld(1). The "pvs" Unix command prints out the versioning information for the shared object created by link-editor 124 and the global symbols available for each version. As shown in Table 3, a "base version" definition is also created for the object. This base version is defined using the name of the shared object itself (e.g., "libfoo.so.1"), and is used to associate any reserved symbols generated by the link-editor 124 with the object. In the example of Table 3, for instance, a base version definition is created for the shared object libfoo1.so.1 that contains reserved global symbols created by the linker (e.g.,.sub.-- etext, .sub.-- edata, .sub.-- end, .sub.-- DYNAMIC, PROCEDURE.sub.-- LINKAGE.sub.-- TABLE.sub.--, and GLOBAL.sub.-- OFFSET.sub.-- TABLE).
TABLE 3
______________________________________
(creating a versioned shared object (at build-time) and
displaying the version information)
______________________________________
$ cc -o libfoo.so.1 -M inapfile -G foo.c bar1.c bar2.c data.c
$ ln -s libfoo.so.1 libfoo.so
$ pvs -dsv libfoo.so.1
libfoo.so.1:
.sub.-- end;
.sub.-- GLOBAL.sub.-- OFFSET.sub.-- TABLE.sub.-- ;
.sub.-- DYNAMIC;
.sub.-- edata;
.sub.-- PROCEDURE.sub.-- LINKAGE.sub.-- TABLE.sub.-- ;
.sub.-- etext;
SUNW.1.1:
foo1;
SUNW.1.1;
SUNW.1.2: {SUNW.1.1}:
foo2;
SUNW. 1.2;
SUNW.1.2.1 ›WEAK!: {SUNW.1.2};
SUNW. 1.2. 1;
SUNW.1.3a: {SUNW.1.2};
bar1;
SUNW.1.3a;
SUNW.1.3b: {SUNW.1.2};
bar2;
SUNW.1.3b;
SUNW.1.4: {SUNW.1.3a SUNW.1.3b};
bar3;
SUNW.1.4;
______________________________________
Returning to FIG. 3(a), if (in step 304) a version name appears in mapfile 130, link-editor 124 creates several sections within shared object 114 that specifically relate to versioning. The special sections are shown in FIG. 5 and include a version definition section 506, a version symbol section 508, and an optional version dependency section 510. The following paragraphs discuss the creation and use of these sections. FIG. 6 shows a format of version definition section 506 of versioned shared object 114. FIG. 16 shows an example of a version definition section based on Tables 1-3. The section includes a section header 602 (see FIG. 12), a structure version 604, flags 606, a version S definition index 610, a count value 612, a hash value 614, an aux value 616, a next version definition pointer 618, the name of the version itself 620, and zero or more names of versions from which the defined version inherits global symbols 620, 622. Each shared object 114 includes a single version definition section 506, containing multiple version definitions. Each group of fields 604-622 is called a "version definition". The following paragraphs discuss the contents of a version definition. Section header 602 indicates the number of versions of the shared object contained in the version definition section. Each version definition section includes information for a base version that defines global symbols not explicitly defined in the mapfile. Thus, fields 604-622 (a "version definition") are created for a base version in step 306 of FIG. 3(a). Field 609 ("base" flag) is set in this base version definition. As shown in step 308, a version definition (fields 604-622) is created by link-editor 124 for each version of shared object 114 defined in mapfile 130. Thus, for the mapfile 130 of Table 2, six version definitions in addition to the base version definition are created in step 308. Steps 310-316 of FIG. 3(b) are performed for each version definition created in Steps 306, 308. As shown in step 310, if mapfile 130 does not define any global symbols for a version (see, e.g., SUNW.1.2.1 of Table 1), the "weak" flag 608 for that version definition is set in step 312 (see FIG. 16). Version 604 is a version number of the structure itself. Version definition index 610 has a different (unique) value for each version defined for shared object 114 and will be discussed below in connection with FIG. 7. Count value 612 refers to the number of instances of pairs of fields 620 and 622 in this version. Hash value 614 is a hash value to the name of the version and uses a conventional ELF hashing function. Aux value 616 is an index to the first field 620 for this version. Next version definition 618 is an index to field 604 of the next version definition in the version definition section. Step 313 creates an entry 620, 622 for the name of the current version and sets AUX to point to this entry. Thus, the first field 620 contains the version name of the version itself. Inheritance information consists of one or more version names from which the defined version inherits other versions. In step 314 of FIG. 3(b), if mapfile 130 includes inheritance information, as shown in FIG. 4 and Table 2. In step 316 link-editor 124 creates one or more entries 620 and 622 to hold inheritance information. Fields 620 and 622 exist for each version from which a version inherits other versions. Field 620 includes the name of the inherited version definition and field 622 points to the next field 620 (or null). In step 318 of FIG. 3(a), link-editor 124 creates a version symbol section for all symbols of the object being link-edited. FIG. 7 shows a format of a version symbol section 508. It is important to note that the entries in version symbol section 508 correspond one-to-one with the symbols in the symbol table for the object (see FIG. 17). Symbol tables are familiar to persons of ordinary skill in the art and are also described in the System V Application Binary Interface Manual, and will not be described herein. The format of section header 702 is discussed in connection with FIG. 13. Each entry 704 in version symbol section 508 is an index of the corresponding version for which the symbol is defined. Thus, referring to Table 2, if version SUNW.1.3b has an index 610 of "6" (see FIG. 16), then the entry in the version symbol section corresponding to the global symbol "bar2" will contain an entry of "6" (see FIG. 17). As indicated in FIG. 7, entries for symbols having local scope contain a value of "0". Entries for symbols in a base version definition contain an entry of "1". As discussed above, only symbols explicitly defined as global symbols (e.g., symbols for the base section, the names of each version, "foo1", "foo2", "bar1", and "bar2", and "bar 3") have non-zero entries 704 in version symbol section 508. Step 320 of FIG. 3(a) creates a version dependency section for shared object 114 (if needed). For example, shared object 114 may reference other versioned objects. Creation of a version dependency section is discussed below. b. Creation of Version Dependency Information at Build-Time Table 4 shows an example of a source version of application program software 116 ("prog.c"). "Prog.c" references two global symbols in shared object 114 libfoo.so.1, namely: "foo1" and "foo2". These symbols are defined to be part of the interfaces SUNW.1.1 and SUNW.1.2, respectively. In Table 4, at build-time, compiler cc also initiates ld link-editor 124. At build time, a binding occurs between "prog.c" and versions "SUNW.1.1, SUNW.1.2 and SUNW.1.2.1, which contains the global symbols "foo1" and "foo2". The former two versions represent the symbol bindings. The latter is recorded due to its weak nature. Because no version control directives are specified by the compile/link command, link-editor 124 will check all versions of shared object 114 present when resolving global symbols in prog.c. FIG. 8 shows steps performed by link-editor 124 at build time to create dynamic executable ELF file 120 from relocatable object 118 and shared object 114. The format of dynamic executable ELF file 120 is shown in FIG. 10. The format of FIG. 10 is similar to that of FIG. 5, except that FIG. 10 contains a version dependency section, but no
TABLE 4
______________________________________
(Source code for an application program and linking to
an object)
______________________________________
$ cat prog.c
extern void foo1( );
extern void foo2( );
main ( )
foo1( );
foo2( );
}
$ cc -o prog prog.c -L. -R. -lfoo
$ pvs -r prog
libfoo.so.1 {SUNW.1.2 SUNW.1.2.1);
______________________________________
version definition section or version symbol section. FIG. 11 shows a format of version dependency section 510. In step 802 of FIG. 8, link-editor 124 determines whether the object being linked (e.g., prog) depends on other objects (e.g., libfoo1.so.1) by checking for unresolved global symbols in prog against the global symbol table of the other objects being linked. If so, in step 804, link-editor 124 determines whether the needed object has versions i.e., whether the needed object has a version definition section. If, in step 806, link-editor 124 determines that only certain versions of the needed object are visible to link-editor 124, control passes to step 810. Otherwise, control passes to step 808. In step 808, link-editor 124 creates a version dependency section in dynamic executable 120 by looking at all available version definition sections of shared object 114 to determine which of these versions contains the global symbols required by relocatable object 118. Alternatively, mapfile 132 has identified only certain versions as being visible to link-editor 124. In step 810, link-editor 124 only looks at the visible version definition sections of shared object 114 to determine which of these versions contains the global symbols required by relocatable object 118. This provision allows linking to be restricted to specific versions of shared object 114. The dependencies recorded in the version dependency section of FIG. 10 are created whenever an application program references a global symbol in the interface to a shared object. Table 4 shows an example of a source version of application program software 116 ("prog.c"). Application program "prog.c" references global symbols "foo1", which is defined in version SUNW.1.1, and "foo2", which is defined in version SUNW.1.2 (see Table 2). Thus, a dependency exists between prog.c and SUNW.1.2 (which inherits from SUNW.1.1). Link-editor 124 creates a version dependency section in the dynamic executable 120 of prog indicating that it depends on version SUNW.1.2 (see FIG. 18). For each undefined global symbol in relocatable 118, link-editor 124 obtains the information telling where (in which version) the symbol is located by looking at the version definition section and version symbol section of all shared objects that are being linked with relocatable 118. FIG. 11 shows a format for version dependency section 510. Version dependency section 510 includes a section header 1102, as described in connection with FIG. 12, a structure version 1104, a count value 1106, a filename 1108, and aux value 1110, a next version value 1112, and a plurality of instances of fields 1114-1122. Fields 1114-1122 include a hash value 1114, a "weak" flag 1116, an unused field 1118, a name field 1120, and a next name field 1122. Structure version value 1104 is not related to the versioning of the present invention, as discussed above in connection with FIG. 6. Count value 1106 indicates a number of instances of fields 1114-1122. Filename 1108 is a name of a shared object dependency. Aux value 1110 is an index to the first field 1114 for this version. Next version dependency section value 1112 is an index to the next version field 1104 (or null). Each instance of fields 1114-1122 identifies a version that is required by the object being created. A version is required if it defines global symbols referenced by the object. At least one instance of fields 1114-1122 always exists. Hash value 1114 is generated from the name of the version 1120 and is generated using a conventional ELF hashing function. "Weak" flag 1116 indicates whether the version depended upon is a weak version, i.e., whether the version contains no global symbols. Field 1118 may not occur in all implementations of the invention and is included merely for alignment purposes. A first instance of name field 1120 contains a name of the version itself (e.g., "SUNW.1.2"). Next name field 1122 is a pointer to a next hash value 1114. A current implementation of the invention uses "version reduction", in which not all inheritances are recorded in version dependency section 510. Weak versions are recorded and needed version are recorded. When these versions inherit global symbols from other versions, however, the other versions generally are not recorded. For example, inheritance from a first weak version though a second weak version preferably is reduced before being recorded in fields 920, 922. Similarly, inheritance from a first non-weak version though a second non-weak version preferably is reduced before being recorded. Inheritance between a weak and a non-weak version is not reduced. Thus, SUNW.1.2 is recorded in fields 920, 922, but the inheritance from SUNW.1.1 is not recorded. In addition, a dependency upon weak version SUNW.1.2.1 is recorded. FIGS. 12-14 show various aspects of the sections of FIGS. 6, 7, and 11. Not all fields of FIGS. 12-14 will be described herein, as many of these fields are part of the conventional ELF format. Only fields relevant to the present invention will be discussed. FIG. 12 shows a format of a section header used in section headers 602, 702, and 1102. An "sh.sub.-- name" field 1202 holds a name of a section and an "sh.sub.-- type" field 1204 holds a type of the section. Values 1202 are particularly relevant to the present invention. FIG. 13 shows values indicating the various type values in field 1204. Values 1302 are particularly relevant to the present invention. The section header format of FIG. 12 also includes an "sh.sub.-- size" field 1306, which indicates a number of bytes in the section, an "sh.sub.-- link" field 1308, and an "sh.sub.-- info" field 1310. FIG. 14 shows example values for the "sh.sub.-- type", "sh.sub.-- link", and "sh.sub.-- info" fields. Values 1402 are particularly relevant to the present invention. The previous paragraphs discuss creation, at build time, of an ELF object 114 containing version definition section 506 and version symbol section 508, and further discuss creation of an ELF object 120 containing version dependency section 510. It should be understood that sections 506 and 508 are created only in objects containing definitions of global symbols and section 510 is created only in objects that depend on objects containing global symbols. Thus, a shared object having global interfaces will include sections 506 and 508 and possibly section 510. Executable application programs that reference the shared object will include section 510 only.
TABLE 5
______________________________________
(Linking using a mapfile to specify which version is
"legal" to link to)
______________________________________
$ cat mapfile
libfoo.so - SUNW.1.1;
cc -o prog prog.c -M mapfile -L. -R. -lfoo
Undefined first referenced
symbol in file
foo2 prog.o (symbol belongs to .backslash.
unavailable version ./libfoo.so (SUNW.1.2))
1d: fatal: Symbol referencing errors. No output written to
______________________________________
prog
c. Restricting an Application's Build At Build Time The previous paragraphs discuss an example of version binding between a relocatable and all available versions of shared object 114. Binding can also be restricted to occur between an application program and only a particular version of an object. FIG. 9 shows a format of a file control directive in the mapfile 132 of FIG. 2(c). A file control directive of this format is used to bind a dynamical executable object in accordance with a specific version of another object. As shown in FIG. 2(c) and Table 5, if the link-editor is run with mapfile 132 containing a file directive of the format shown in FIG. 9, then binding will occur only with the specified version of the object. In Table 5, the mapfile contains "libfoo.so - SUNW.1.1". As shown in Table 4, application software "prog.c" references global symbols "foo1" and "foo2". Symbol "foo2" is defined in version SUNW.1.2. When prog.c is linked (using the cc compiler and ld(1) link-editor) with an -M option, it is linked only with version SUNW.1.1. Thus, as shown in Table 5, link-editor 124 identifies "foo2", which is defined in version SUNW.1.2, as an undefined symbol. d. Promoting a Weak Version At Build Time Table 6 shows an example in which link-editor 124 is forced to "promote" a weak version (SUNW.1.2.1) to a strong version. Because of the "-u" option, command line link-editor 124 records a dependency of "prog" on version SUNW.1.2.1 in the version dependency section of "prog". Furthermore, "weak" flag 1116 is set to false for SUNW.1.2.1 in the version dependency section of "prog". In this case version SUNW.1.2.1 inherits version SUNW.1.2. Therefore, as all of prog's dependencies are "strong" Version reduction will mean that only SUNW.1.2.1 is recorded in prog and that it will be recorded as non-weak. Promotion of a weak version ensures that runtime linker 126 will verify that the formerly weak version is present when "prog" is executed.
TABLE 6
______________________________________
(Promotion of a weak version)
______________________________________
$ cc -o prog prog.c -L. -R. -u SUNW.1.2.1 -1foo
$pvs - r prog
libfoo.so.1 (SUNW.1.2.1)
______________________________________
3. Verifying Versioning Information at Runtime FIG. 15 is a flow chart 1500 showing steps performed by runtime linker 126 (see FIG. 2(d)) to insure that all required versions of referenced objects are present when linking and executing a dynamic executable object 120. The steps of FIG. 15 preferably are embodied by CPU 102 executing instructions stored in a memory. The steps of FIG. 15 are performed as a pre-execution check to determine whether all required dependencies are present. In step 1502, linker 126 determines whether the dynamic executable object being executed contains a version dependency section (see FIG. 11). If not, no checking is done and normal execution continues. Otherwise, in step 1504, linker 126 determines whether at least one of the objects 114 being linked includes a version definition section and a version symbol section. If not, no further checking is done and normal execution continues. Otherwise control passes to step 1506. In step 1506, runtime linker 126 determines whether all version dependencies in the current dynamic executable object have been processed. If so, normal execution continues, otherwise control passes to step 1508. In step 1508, runtime linker 126 determines whether a match exists between a needed version (as defined in the version dependency section of the dynamic executable 120) and the version definition section of the shared object 114. For example, in FIGS. 16 and 18, version SUNW.1.2 and SUNW.1.2.1 are defined in the version definition section of shared object 114 and are specified as needed in the version dependency section of dynamic executable 120. If a match is found in step 1508, then the needed version of object 114 is present and control returns to step 1506. Otherwise, the needed version is not present and it is necessary to determine whether the missing version is a weak or a non-weak version in step 1510. Runtime linker 126 determines whether a version is weak by checking the "weak" flag 1116 in the version dependency section of dynamic executable 120. (Note that flag 1116 may reflect the "promotion" of a version from weak to strong). If, in step 1510, runtime linker 126 determines that the version is a weak version, no error occurs and control returns to step 1506. Otherwise, a fatal error occurs because a needed, non-weak version is not present. Thus, a dependency on a missing "weak" version will not cause an error, but dependency on a missing "non-weak" version will. FIG. 16 shows an example of a version definition section 1600. FIG. 17 shows an example of a version symbol section 1700 for shared object 114 (libfoo.so.1 of Tables 1-3). FIG. 19 also shows an example of a version dependency section 1800 for the dynamical executable form of application program 120 ("prog" of Table 4). (In this example, shared object 14 has no dependencies on other objects, and so has no version dependency section). FIG. 16 contains a base version definition 1604 and six version definitions for, respectively, versions SUNW.1.1, SUNW.1.2, SUNW.1.2.1, SUNW.1.3a, SUNW.1.3b, and SUNW.1.4. Base version definition 1604 has its "base" flag set to "True". The version definition for SUNW.1.2.1 has its "weak" flag set to "True". Each version definition has a respective (unique) version definition index. Version reduction is applied in the version definition table. Application "prog" references the global symbols foo1 (in SUNW.1.1) and foo2 (in SUNW.1.2). Because SUNW.1.2 inherits the global symbols of SUNW.1.1, link-editor 124 applies version reduction and an entry (for SUNW.1.2) is made in version definition section. The weak version SUNW.1.2.1 is also recorded. FIG. 17 shows some of the symbols in version symbol section 1700. For example, the global variable "foo1" is defined in version SUNW.1.1, which has a version definition index of "2". Thus, the entry in the version symbol section corresponding to the entry in the symbol table for foo1 contains "2". In the described embodiment, the name for each version (e.g., SUNW.1.1) is also a global symbol that is created when generating the version definition. FIG. 18 shows an example of a version dependency section in dynamic executable 120. Because of version reduction, the section contains an entry for SUNW.1.2, but not for SUNW.1.1. The section also contains an entry for "weak" version SUNW.1.2.1. At runtime, linker 126 will determine that prog has a version dependency section (step 1502), will determine that libfoo.so.1 has a version definition section (step 1504), and will determine that the needed version (SUNW.1.2) is present (step 1508). Therefore, "prog" will be executed. Several preferred embodiments of the present invention have been described. Nevertheless, it will be understood that various modifications may be made without departing from the spirit and scope of the invention. In describing the preferred embodiments, a number of specific technologies used to implement the embodiments of various aspects of the invention were identified and related to more general terms in which the invention was described. However, it should be understood that such specificity is not intended to limit the scope of the claimed invention.
|
Same subclass Same class Consider this |
||||||||||
