[cairo] [PATCH] Fix the AMD64 link failure

Nicholas Miell nmiell at comcast.net
Wed Sep 6 16:09:37 PDT 2006


The final link on AMD64 was recent broken by commit
06246b9b1015eb89112f628d5820fcb350a7335 (pixman: Add pixman_private
decorations to hide pixman symbols from public interface), resulting in
the following error:

/usr/bin/ld: .libs/cairo-clip.o: relocation R_X86_64_PC32 against
`_cairo_pixman_region_copy' can not be used when making a shared object;
recompile with -fPIC

Attached are a couple of patches -- the first is just a small cleanup
that came out of my attempts to diagnose and fix the bug and the second
is the actual fix. It's more of a workaround (I'm still not sure why it
broke exactly in the first place), but it's the good kind of workaround
-- the kind that is a perfectly correct thing to do all by itself and
happens to fix the other bug as a fortunate side-effect.

The actual commit messages are much more detailed than this little
summary.

-- 
Nicholas Miell <nmiell at comcast.net>
-------------- next part --------------
>From 13e00cdb1d0e258dcb9c8198f9c0455db962448d Mon Sep 17 00:00:00 2001
From: Nicholas Miell <nmiell at gmail.com>
Date: Wed, 6 Sep 2006 14:43:44 -0700
Subject: [PATCH] Make the SLIM macros robust in the face of macro-renamed symbols

This doesn't actually fix the AMD64 link failure, but it does make the
foo/EXT_foo/INT_foo symbol names generated by the slim_hidden_proto()
and slim_hidden_def() macros consistent in the face of the meddling of
pixman-remap.h.

Signed-off-by: Nicholas Miell <nmiell at gmail.com>
---
 pixman/src/slim_internal.h |    5 +++--
 src/cairoint.h             |    5 +++--
 2 files changed, 6 insertions(+), 4 deletions(-)

diff --git a/pixman/src/slim_internal.h b/pixman/src/slim_internal.h
index 742059c..3d1e9a6 100644
--- a/pixman/src/slim_internal.h
+++ b/pixman/src/slim_internal.h
@@ -78,8 +78,9 @@ #endif
    level.  */
 
 #if __GNUC__ >= 3 && defined(__ELF__)
-# define slim_hidden_proto(name)	slim_hidden_proto1(name, INT_##name)
-# define slim_hidden_def(name)		slim_hidden_def1(name, INT_##name)
+# define slim_hidden_proto(name)	slim_hidden_proto1(name, slim_hidden_int_name(name))
+# define slim_hidden_def(name)		slim_hidden_def1(name, slim_hidden_int_name(name))
+# define slim_hidden_int_name(name) INT_##name
 # define slim_hidden_proto1(name, internal)				\
   extern __typeof (name) name						\
 	__asm__ (slim_hidden_asmname (internal))			\
diff --git a/src/cairoint.h b/src/cairoint.h
index bf7d288..f17be94 100644
--- a/src/cairoint.h
+++ b/src/cairoint.h
@@ -68,8 +68,9 @@ #include <pixman.h>
 CAIRO_BEGIN_DECLS
 
 #if __GNUC__ >= 3 && defined(__ELF__)
-# define slim_hidden_proto(name)	slim_hidden_proto1(name, INT_##name)
-# define slim_hidden_def(name)		slim_hidden_def1(name, INT_##name)
+# define slim_hidden_proto(name)	slim_hidden_proto1(name, slim_hidden_int_name(name))
+# define slim_hidden_def(name)		slim_hidden_def1(name, slim_hidden_int_name(name))
+# define slim_hidden_int_name(name) INT_##name
 # define slim_hidden_proto1(name, internal)				\
   extern __typeof (name) name						\
 	__asm__ (slim_hidden_asmname (internal))			\
-- 
1.4.1

-------------- next part --------------
>From ef0f76a7af3877d98aa6a4089b69f0f89195320c Mon Sep 17 00:00:00 2001
From: Nicholas Miell <nmiell at gmail.com>
Date: Wed, 6 Sep 2006 15:45:00 -0700
Subject: [PATCH] Fix the AMD64 final link by removing SLIM from pixman

In order for SLIM's PLT indirection avoidance to work, everything in
the library that makes internal function calls needs to see the
relevant slim_hidden_proto() macro in addition to the function's
prototype. However, external headers used by clients of the shared
library should not use the SLIM macros at all.

Pixman is a rather odd case -- it's mostly independent from cairo, so
it has it's own public interface, but it's built as a part of cairo
instead of its own shared library. This means that cairo would need to
see all of pixman's slim_hidden_proto() macros in order to function
and it doesn't currently, which results in a link failure on AMD64
systems and on i386 systems (I think, I haven't actually verified
this) it produces a shared object that isn't actally sharable.

I have no idea why exactly the link failure only showed up as a result
of commit e06246b9b1015eb89112f628d5820fcb350a7335. I think it has
something to do with the pixman functions no longer having PLT entries
at all, but the exact interaction isn't clear to me.

However, all of these pixman functions aren't part of the cairo ABI
(which is why they were marked pixman_private in the first place),
which means that the SLIMification of pixman is largely pointless --
they aren't externally visible, so they don't need PLT entries at
all. Furthermore, while pixman may eventually be shared among cairo
and X, I'm told that this sharing will be source-level only, which
means it won't ever be an actual shared library and thus won't ever
need SLIM at all.

So, I just removed all use of SLIM in pixman (leaving behind
slim_internal.h for the future edification of anyone who cares).This
fixes the AMD64 link failure and passes the check-plt & check-def
parts of make check.

Signed-off-by: Nicholas Miell <nmiell at gmail.com>
---
 pixman/src/fbpict.c    |    1 -
 pixman/src/iccolor.c   |    1 -
 pixman/src/icformat.c  |    1 -
 pixman/src/icimage.c   |    4 ----
 pixman/src/icint.h     |   13 -------------
 pixman/src/icrect.c    |    1 -
 pixman/src/pixregion.c |    8 --------
 7 files changed, 0 insertions(+), 29 deletions(-)

diff --git a/pixman/src/fbpict.c b/pixman/src/fbpict.c
index 07c293a..675d1fb 100644
--- a/pixman/src/fbpict.c
+++ b/pixman/src/fbpict.c
@@ -1902,7 +1902,6 @@ #endif
     }
     pixman_region_destroy (region);
 }
-slim_hidden_def(pixman_composite);
 
 /* The CPU detection code needs to be in a file not compiled with
  * "-mmmx -msse", as gcc would generate CMOV instructions otherwise
diff --git a/pixman/src/iccolor.c b/pixman/src/iccolor.c
index 716382f..26b4aaf 100644
--- a/pixman/src/iccolor.c
+++ b/pixman/src/iccolor.c
@@ -53,7 +53,6 @@ pixman_color_to_pixel (const pixman_form
     a = a << format->alpha;
     *pixel = r|g|b|a;
 }
-slim_hidden_def(pixman_color_to_pixel);
 
 static uint16_t
 FbFillColor (uint32_t pixel, int bits)
diff --git a/pixman/src/icformat.c b/pixman/src/icformat.c
index f55d443..bf93a6c 100644
--- a/pixman/src/icformat.c
+++ b/pixman/src/icformat.c
@@ -171,7 +171,6 @@ pixman_format_init (pixman_format_t *for
 			     (format->blueMask << format->blue) |
 			     (format->greenMask << format->green));
 }
-slim_hidden_def(pixman_format_init);
 
 void
 pixman_format_destroy (pixman_format_t *format)
diff --git a/pixman/src/icimage.c b/pixman/src/icimage.c
index 11e8396..44c4c8b 100644
--- a/pixman/src/icimage.c
+++ b/pixman/src/icimage.c
@@ -45,7 +45,6 @@ pixman_image_create (pixman_format_t	*fo
 
     return image;
 }
-slim_hidden_def(pixman_image_create);
 
 pixman_image_t *
 pixman_image_create_for_data (FbBits *data, pixman_format_t *format, int width, int height, int bpp, int stride)
@@ -369,7 +368,6 @@ pixman_image_set_component_alpha (pixman
     if (image)
 	image->componentAlpha = component_alpha;
 }
-slim_hidden_def(pixman_image_set_component_alpha);
 
 int
 pixman_image_set_transform (pixman_image_t		*image,
@@ -412,7 +410,6 @@ pixman_image_set_repeat (pixman_image_t	
     if (image)
 	image->repeat = repeat;
 }
-slim_hidden_def(pixman_image_set_repeat);
 
 void
 pixman_image_set_filter (pixman_image_t	*image,
@@ -505,7 +502,6 @@ pixman_image_destroy (pixman_image_t *im
 
     free (image);
 }
-slim_hidden_def(pixman_image_destroy);
 
 void
 pixman_image_destroyClip (pixman_image_t *image)
diff --git a/pixman/src/icint.h b/pixman/src/icint.h
index e1265eb..c846a51 100644
--- a/pixman/src/icint.h
+++ b/pixman/src/icint.h
@@ -33,8 +33,6 @@ #include <stdlib.h>
 #include <string.h>
 #include <limits.h>
 
-#include "slim_internal.h"
-
 #ifndef __GNUC__
 #define __inline
 #endif
@@ -852,17 +850,6 @@ pixman_private int
 pixman_transform_point (pixman_transform_t	*transform,
 		  pixman_vector_t	*vector);
 
-/* Avoid unnessecary PLT entries.  */
-
-slim_hidden_proto(pixman_image_create)
-slim_hidden_proto(pixman_color_to_pixel)
-slim_hidden_proto(pixman_format_init)
-slim_hidden_proto(pixman_image_destroy)
-slim_hidden_proto(pixman_fill_rectangles)
-slim_hidden_proto(pixman_image_set_component_alpha)
-slim_hidden_proto(pixman_image_set_repeat)
-slim_hidden_proto(pixman_composite)
-
 #include "icrop.h"
 
 /* XXX: For now, I'm just wholesale pasting Xserver/render/picture.h here: */
diff --git a/pixman/src/icrect.c b/pixman/src/icrect.c
index 7253bfa..e4d0c12 100644
--- a/pixman/src/icrect.c
+++ b/pixman/src/icrect.c
@@ -363,4 +363,3 @@ bail1:
 	;
     }
 }
-slim_hidden_def(pixman_fill_rectangles);
diff --git a/pixman/src/pixregion.c b/pixman/src/pixregion.c
index c9bc219..5112157 100644
--- a/pixman/src/pixregion.c
+++ b/pixman/src/pixregion.c
@@ -50,7 +50,6 @@ #include <limits.h>
 #include <string.h>
 
 #include "pixregionint.h"
-#include "slim_internal.h"
 
 #if defined (__GNUC__) && !defined (NO_INLINES)
 #define INLINE	__inline
@@ -89,10 +88,6 @@ pixman_init (pixman_region16_t *region, 
 static void
 pixman_uninit (pixman_region16_t *region);
 
-slim_hidden_proto(pixman_region_create_simple)
-slim_hidden_proto(pixman_region_copy)
-slim_hidden_proto(pixman_region_union)
-
 /*
  * The functions in this file implement the Region abstraction used extensively
  * throughout the X11 sample server. A Region is simply a set of disjoint
@@ -327,7 +322,6 @@ pixman_region_create_simple (pixman_box1
 
     return region;
 }
-slim_hidden_def(pixman_region_create_simple);
 
 /*****************************************************************
  *   RegionInit(pReg, rect, size)
@@ -452,7 +446,6 @@ pixman_region_copy(pixman_region16_t *ds
 	  dst->data->numRects * sizeof(pixman_box16_t));
     return PIXMAN_REGION_STATUS_SUCCESS;
 }
-slim_hidden_def(pixman_region_copy);
 
 /*======================================================================
  *	    Generic Region Operator
@@ -1232,7 +1225,6 @@ pixman_region_union(pixman_region16_t *n
     good(newReg);
     return PIXMAN_REGION_STATUS_SUCCESS;
 }
-slim_hidden_def(pixman_region_union);
 
 /*======================================================================
  *	    Batch Rectangle Union
-- 
1.4.1



More information about the cairo mailing list