tinycc-devel
[Top][All Lists]
Advanced

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

[Tinycc-devel] Symbols visibility support (cont: Linking bug about _i686


From: Vince
Subject: [Tinycc-devel] Symbols visibility support (cont: Linking bug about _i686.get_pc_thunk.*)
Date: Thu, 12 Apr 2007 15:06:10 +0200
User-agent: Thunderbird 1.5.0.10 (X11/20070323)

-----BEGIN PGP SIGNED MESSAGE-----
Hash: SHA1

Hello,

I had the same linking problem as described in
http://lists.gnu.org/archive/html/tinycc-devel/2007-02/msg00004.html.
The people from the Gentoo bugzilla told me that this symbol had
actually its visibility flag set to HIDDEN, so the linker shouldn't
care about it (see https://bugs.gentoo.org/show_bug.cgi?id=174034).

- From the pieces of information available at
http://sourceware.org/ml/binutils/2003-03/msg00446.html and
http://www.sco.com/developers/gabi/2000-07-17/ch4.symtab.html#visibility.
I wrote a patch to set the visibility to the most restrictive one when
a duplicate symbol is added, and then to skip it if its visibility is
HIDDEN or INTERNAL. This seems to fix the problem.

Since I'm far from being an expert in linking, I'd be glad to hear
your comments about this patch.

Regards,

Vincent Pit.
-----BEGIN PGP SIGNATURE-----
Version: GnuPG v2.0.3 (GNU/Linux)
Comment: Using GnuPG with Mozilla - http://enigmail.mozdev.org

iD8DBQFGHi7BK9ByfI09oHARAin9AJwN4oiR3hmspYnVQaBx8c5TtrAW5wCgl8mq
NDNciNB5MyTnQmGpqQVemto=
=LLXN
-----END PGP SIGNATURE-----

--- tccelf.c    2007-04-10 21:20:16.000000000 +0200
+++ tccelf.c    2007-04-10 21:20:40.000000000 +0200
@@ -18,6 +18,8 @@
  * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
  */
 
+#include <limits.h>
+
 static int put_elf_str(Section *s, const char *sym)
 {
     int offset, len;
@@ -182,9 +184,11 @@
 {
     Elf32_Sym *esym;
     int sym_bind, sym_index, sym_type, esym_bind;
+    unsigned char sym_vis, esym_vis, new_vis;
 
     sym_bind = ELF32_ST_BIND(info);
     sym_type = ELF32_ST_TYPE(info);
+    sym_vis = ELF32_ST_VISIBILITY(other);
         
     if (sym_bind != STB_LOCAL) {
         /* we search global or weak symbols */
@@ -194,6 +198,19 @@
         esym = &((Elf32_Sym *)s->data)[sym_index];
         if (esym->st_shndx != SHN_UNDEF) {
             esym_bind = ELF32_ST_BIND(esym->st_info);
+            /* propagate the most constraining visibility */
+            /* STV_DEFAULT(0)<STV_PROTECTED(3)<STV_HIDDEN(2)<STV_INTERNAL(1) */
+            esym_vis = ELF32_ST_VISIBILITY(esym->st_other);
+            if (esym_vis == STV_DEFAULT) {
+                new_vis = sym_vis;
+            } else if (sym_vis == STV_DEFAULT) {
+                new_vis = esym_vis;
+            } else {
+                new_vis = (esym_vis < sym_vis) ? esym_vis : sym_vis;
+            }
+            esym->st_other = (esym->st_other & ~ELF32_ST_VISIBILITY(UCHAR_MAX))
+                             | new_vis;
+            other = esym->st_other; /* in case we have to patch esym */
             if (sh_num == SHN_UNDEF) {
                 /* ignore adding of undefined symbol if the
                    corresponding symbol is already defined */
@@ -202,6 +219,8 @@
                 goto do_patch;
             } else if (sym_bind == STB_WEAK && esym_bind == STB_GLOBAL) {
                 /* weak is ignored if already global */
+            } else if (sym_vis == STV_HIDDEN || sym_vis == STV_INTERNAL) {
+                /* ignore hidden symbols after */
             } else {
 #if 0
                 printf("new_bind=%d new_shndx=%d last_bind=%d old_shndx=%d\n",

reply via email to

[Prev in Thread] Current Thread [Next in Thread]