A symbol version patch for glibc 2.x compatibility
H . J . Lu
hjl@valinux.com
Mon Nov 6 12:19:00 GMT 2000
Glibc 2.2 is run-time compatible with glibc 2.0 and 2.1. But it is not
enough for ISVs. Oracle 8i compiled against glibc 2.1 won't install
under glibc 2.2 since the Oracle installation involves relinking. Also,
all the libraries are compiled against glibc 2.1. It is not easy to
develop Oracle 8i applications under glibc 2.2.
I am working on providing the compile-time, link-time compatible option
to glibc. The idea is <sys/cdefs.h> or <features.h> will include
<bits/symver.h> which will provide all the symbol information. Depending
on the glibc version selected at the command line, <bits/symver.h> will
provide the correct
__asm__ (".symver bar,bar@GLIBC_2.x.x");
for each versioned symbol.
I modified as so that it will
1. Allow duplicated version name like
.symver bar,bar@GLIBC_2.1
.symver bar,bar@GLIBC_2.1
2. Remove unneeded versioned symbols from the symbol table. The asm
code like
----
.file "x.c"
.version "01.01"
.symver bar,bar@GLIBC_2.1
.symver bar,bar@GLIBC_2.1
.globl foobar
foobar:
.long foo
.symver foobar,foobar@GLIBC_2.1
dummy:
.long foo
.symver foo,foo@GLIBC_2.1
-----
will get
# gcc -c x.s
# readelf -a x.o
ELF Header:
Magic: 7f 45 4c 46 01 01 01 00 00 00 00 00 00 00 00 00
Class: ELF32
Data: 2's complement, little endian
Version: 1 (current)
OS/ABI: UNIX - System V
ABI Version: 0
Type: REL (Relocatable file)
Machine: Intel 80386
Version: 0x1
Entry point address: 0x0
Start of program headers: 0 (bytes into file)
Start of section headers: 196 (bytes into file)
Flags: 0x0
Size of this header: 52 (bytes)
Size of program headers: 0 (bytes)
Number of program headers: 0
Size of section headers: 40 (bytes)
Number of section headers: 10
Section header string table index: 7
Section Headers:
[Nr] Name Type Addr Off Size ES Flg Lk Inf Al
[ 0] NULL 00000000 000000 000000 00 0 0 0
[ 1] .text PROGBITS 00000000 000034 000008 00 AX 0 0 4
[ 2] .rel.text REL 00000000 000340 000010 08 8 1 4
[ 3] .data PROGBITS 00000000 00003c 000000 00 WA 0 0 4
[ 4] .bss NOBITS 00000000 00003c 000000 00 WA 0 0 4
[ 5] .note NOTE 00000000 00003c 000014 00 0 0 1
[ 6] .comment PROGBITS 00000000 000050 00002e 00 0 0 1
[ 7] .shstrtab STRTAB 00000000 00007e 000045 00 0 0 1
[ 8] .symtab SYMTAB 00000000 000254 0000b0 10 9 8 4
[ 9] .strtab STRTAB 00000000 000304 00003a 00 0 0 1
Key to Flags: W (write), A (alloc), X (execute), M (merge), S (strings)
I (info), L (link order), O (extra OS processing required)
o (os specific), p (processor specific) x (unknown)
There are no program headers in this file.
There is no dynamic segment in this file.
Relocation section '.rel.text' at offset 0x340 contains 2 entries:
Offset Info Type Symbol's Value Symbol's Name
00000000 00901 R_386_32 00000000 foo@GLIBC_2.1
00000004 00901 R_386_32 00000000 foo@GLIBC_2.1
Symbol table '.symtab' contains 11 entries:
Num: Value Size Type Bind Vis Ndx Name
0: 00000000 0 NOTYPE LOCAL DEFAULT UND
1: 00000000 0 FILE LOCAL DEFAULT ABS x.c
2: 00000000 0 SECTION LOCAL DEFAULT 1
3: 00000000 0 SECTION LOCAL DEFAULT 3
4: 00000000 0 SECTION LOCAL DEFAULT 4
5: 00000004 0 NOTYPE LOCAL DEFAULT 1 gcc2_compiled.
6: 00000000 0 SECTION LOCAL DEFAULT 5
7: 00000000 0 SECTION LOCAL DEFAULT 6
8: 00000000 0 NOTYPE GLOBAL DEFAULT 1 foobar
9: 00000000 0 NOTYPE GLOBAL DEFAULT UND foo@GLIBC_2.1
10: 00000000 0 NOTYPE GLOBAL DEFAULT 1 foobar@GLIBC_2.1
No version information found in this file.
Any comments?
--
H.J. Lu (hjl@gnu.org)
---
2000-11-06 H.J. Lu <hjl@gnu.org>
* obj.h (format_ops): Add the frob_file_before_adjust field.
* config/obj-aout.c (aout_format_ops): Set the
frob_file_before_adjust field to 0.
* config/obj-coff.c (coff_format_ops): Likewise.
* config/obj-ecoff.c (ecoff_format_ops): Likewise.
* config/obj-elf.c (obj_elf_symver): Allow duplicated version
name.
(elf_frob_file_before_adjust): New function to remove unneeded
versioned symbols from the symbol table.
(elf_format_ops): Set the frob_file_before_adjust field to
elf_frob_file_before_adjust.
* config/obj-elf.h (obj_frob_file_before_adjust): Defined if
not defined.
* config/obj-multi.h (obj_frob_file_before_adjust): Defined.
Index: obj.h
===================================================================
RCS file: /work/cvs/gnu/binutils/gas/obj.h,v
retrieving revision 1.1.1.3
diff -u -p -r1.1.1.3 obj.h
--- obj.h 2000/05/30 05:36:04 1.1.1.3
+++ obj.h 2000/11/06 19:04:11
@@ -54,6 +54,7 @@ struct format_ops {
void (*app_file) PARAMS ((const char *));
void (*frob_symbol) PARAMS ((symbolS *, int *));
void (*frob_file) PARAMS ((void));
+ void (*frob_file_before_adjust) PARAMS ((void));
void (*frob_file_after_relocs) PARAMS ((void));
bfd_vma (*s_get_size) PARAMS ((symbolS *));
void (*s_set_size) PARAMS ((symbolS *, bfd_vma));
Index: config/obj-aout.c
===================================================================
RCS file: /work/cvs/gnu/binutils/gas/config/obj-aout.c,v
retrieving revision 1.1.1.8
diff -u -p -r1.1.1.8 obj-aout.c
--- config/obj-aout.c 2000/09/17 23:02:05 1.1.1.8
+++ config/obj-aout.c 2000/11/06 19:03:24
@@ -732,6 +732,7 @@ const struct format_ops aout_format_ops
0, /* app_file */
obj_aout_frob_symbol,
obj_aout_frob_file,
+ 0, /* frob_file_before_adjust */
0, /* frob_file_after_relocs */
0, /* s_get_size */
0, /* s_set_size */
Index: config/obj-coff.c
===================================================================
RCS file: /work/cvs/gnu/binutils/gas/config/obj-coff.c,v
retrieving revision 1.1.1.23
diff -u -p -r1.1.1.23 obj-coff.c
--- config/obj-coff.c 2000/09/17 23:02:05 1.1.1.23
+++ config/obj-coff.c 2000/11/06 19:03:29
@@ -4653,6 +4653,7 @@ const struct format_ops coff_format_ops
c_dot_file_symbol,
coff_frob_symbol,
0, /* frob_file */
+ 0, /* frob_file_before_adjust */
coff_frob_file_after_relocs,
0, /* s_get_size */
0, /* s_set_size */
Index: config/obj-ecoff.c
===================================================================
RCS file: /work/cvs/gnu/binutils/gas/config/obj-ecoff.c,v
retrieving revision 1.1.1.5
diff -u -p -r1.1.1.5 obj-ecoff.c
--- config/obj-ecoff.c 2000/09/17 23:02:05 1.1.1.5
+++ config/obj-ecoff.c 2000/11/06 19:03:33
@@ -309,6 +309,7 @@ const struct format_ops ecoff_format_ops
ecoff_new_file,
obj_ecoff_frob_symbol,
ecoff_frob_file,
+ 0, /* frob_file_before_adjust */
0, /* frob_file_after_relocs */
0, /* s_get_size */
0, /* s_set_size */
Index: config/obj-elf.c
===================================================================
RCS file: /work/cvs/gnu/binutils/gas/config/obj-elf.c,v
retrieving revision 1.22
diff -u -p -r1.22 obj-elf.c
--- config/obj-elf.c 2000/10/11 18:23:38 1.22
+++ config/obj-elf.c 2000/11/06 19:57:09
@@ -1106,14 +1106,6 @@ obj_elf_symver (ignore)
*input_line_pointer = c;
- if (symbol_get_obj (sym)->versioned_name != NULL)
- {
- as_bad (_("multiple .symver directives for symbol `%s'"),
- S_GET_NAME (sym));
- ignore_rest_of_line ();
- return;
- }
-
SKIP_WHITESPACE ();
if (*input_line_pointer != ',')
{
@@ -1132,16 +1124,33 @@ obj_elf_symver (ignore)
*input_line_pointer++ = c;
}
- symbol_get_obj (sym)->versioned_name = xstrdup (name);
+ if (symbol_get_obj (sym)->versioned_name == NULL)
+ {
+ symbol_get_obj (sym)->versioned_name = xstrdup (name);
- *input_line_pointer = c;
+ *input_line_pointer = c;
- if (strchr (symbol_get_obj (sym)->versioned_name, ELF_VER_CHR) == NULL)
+ if (strchr (symbol_get_obj (sym)->versioned_name,
+ ELF_VER_CHR) == NULL)
+ {
+ as_bad (_("missing version name in `%s' for symbol `%s'"),
+ symbol_get_obj (sym)->versioned_name,
+ S_GET_NAME (sym));
+ ignore_rest_of_line ();
+ return;
+ }
+ }
+ else
{
- as_bad (_("missing version name in `%s' for symbol `%s'"),
- symbol_get_obj (sym)->versioned_name, S_GET_NAME (sym));
- ignore_rest_of_line ();
- return;
+ if (strcmp (symbol_get_obj (sym)->versioned_name, name))
+ {
+ as_bad (_("multiple .symver directives for symbol `%s'"),
+ S_GET_NAME (sym));
+ ignore_rest_of_line ();
+ return;
+ }
+
+ *input_line_pointer = c;
}
demand_empty_rest_of_line ();
@@ -1753,6 +1762,24 @@ elf_frob_file ()
#endif
}
+/* It removes any unneeded versioned symbols from the symbol table. */
+
+void
+elf_frob_file_before_adjust ()
+{
+ if (symbol_rootP)
+ {
+ symbolS *symp;
+
+ for (symp = symbol_rootP; symp; symp = symbol_next (symp))
+ if (symbol_get_obj (symp)->versioned_name
+ && !S_IS_DEFINED (symp)
+ && symbol_used_p (symp) == 0
+ && symbol_used_in_reloc_p (symp) == 0)
+ symbol_remove (symp, &symbol_rootP, &symbol_lastP);
+ }
+}
+
/* It is required that we let write_relocs have the opportunity to
optimize away fixups before output has begun, since it is possible
to eliminate all fixups for a section and thus we never should
@@ -1957,6 +1984,7 @@ const struct format_ops elf_format_ops =
elf_file_symbol,
elf_frob_symbol,
elf_frob_file,
+ elf_frob_file_before_adjust,
elf_frob_file_after_relocs,
elf_s_get_size, elf_s_set_size,
elf_s_get_align, elf_s_set_align,
Index: config/obj-elf.h
===================================================================
RCS file: /work/cvs/gnu/binutils/gas/config/obj-elf.h,v
retrieving revision 1.8
diff -u -p -r1.8 obj-elf.h
--- config/obj-elf.h 2000/09/17 23:09:52 1.8
+++ config/obj-elf.h 2000/11/06 19:02:24
@@ -132,6 +132,11 @@ extern asection *gdb_section;
#endif
extern void elf_frob_file PARAMS ((void));
+#ifndef obj_frob_file_before_adjust
+#define obj_frob_file_before_adjust elf_frob_file_before_adjust
+#endif
+extern void elf_frob_file_before_adjust PARAMS ((void));
+
#ifndef obj_frob_file_after_relocs
#define obj_frob_file_after_relocs elf_frob_file_after_relocs
#endif
Index: config/obj-multi.h
===================================================================
RCS file: /work/cvs/gnu/binutils/gas/config/obj-multi.h,v
retrieving revision 1.1.1.4
diff -u -p -r1.1.1.4 obj-multi.h
--- config/obj-multi.h 2000/05/30 05:36:07 1.1.1.4
+++ config/obj-multi.h 2000/11/06 19:02:47
@@ -50,6 +50,11 @@
? (*this_format->frob_file) () \
: (void) 0)
+#define obj_frob_file_before_adjust() \
+ (this_format->frob_file_before_adjust \
+ ? (*this_format->frob_file_before_adjust) () \
+ : (void) 0)
+
#define obj_frob_file_after_relocs() \
(this_format->frob_file_after_relocs \
? (*this_format->frob_file_after_relocs) () \
More information about the Binutils
mailing list