This is the mail archive of the libc-hacker@sources.redhat.com mailing list for the glibc project.

Note that libc-hacker is a closed list. You may look at the archives of this list, but subscription and posting are not open.


Index Nav: [Date Index] [Subject Index] [Author Index] [Thread Index]
Message Nav: [Date Prev] [Date Next] [Thread Prev] [Thread Next]

A symbol version patch for glibc 2.x compatibility


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) ()	\

Index Nav: [Date Index] [Subject Index] [Author Index] [Thread Index]
Message Nav: [Date Prev] [Date Next] [Thread Prev] [Thread Next]