Re: setjmp needs fixing again, here's the issues

2003-09-12 Thread David Dawes
On Wed, Sep 10, 2003 at 02:17:50PM -0700, John Meacham wrote:
>On Wed, Sep 10, 2003 at 03:37:57PM -0400, John Dennis wrote:
>> 1) It may be hard to know the alignment requirements for all OS's and
>> architectures (thats part of the reason we have system header
>> files). We could guess 16 byte is sufficient. But even if we got the
>> alignment requirement right how do we specify the alignment requirement
>> to the compiler in a portable way such that it will build on a variety
>> of systems and compilers? My understanding is that compiler alignment
>> directives are not portable (e.g. not part of ANSI C). Are we
>> comfortable picking one or two common alignment directives and
>> conditionally compiling with the right one?
>
>Since we already have a jmp_buf which is much larger than necisarry, all
>that is needed is to take the first offset into it which is properly
>aligned for the given architecture and use that as the system jmp_buf.
>when the compiler can guarentee the proper alignment this becomes a
>'nop', otherwise we waste at most alignment - sizeof(intmax_t) - 1
>bytes. not a big deal. best of all, this can be implemented portably
>quite easily.

The attached patch is one way this could be done.  I've set the alignment
higher than it probably needs to be.

David
-- 
David Dawes X-Oz Technologies
www.XFree86.org/~dawes  www.x-oz.com
Index: loader/xf86sym.c
===
RCS file: /home/x-cvs/xc/programs/Xserver/hw/xfree86/loader/xf86sym.c,v
retrieving revision 1.235
diff -u -r1.235 xf86sym.c
--- loader/xf86sym.c24 Aug 2003 19:58:05 -  1.235
+++ loader/xf86sym.c12 Sep 2003 15:07:52 -
@@ -907,6 +907,7 @@
SYMFUNC(xf86setjmp1)
 #endif
SYMFUNCALIAS("xf86longjmp",longjmp)
+   SYMFUNCALIAS("xf86longjmp0",longjmp)
SYMFUNC(xf86getjmptype)
SYMFUNC(xf86setjmp1_arg2)
SYMFUNC(xf86setjmperror)
Index: os-support/xf86_ansic.h
===
RCS file: /home/x-cvs/xc/programs/Xserver/hw/xfree86/os-support/xf86_ansic.h,v
retrieving revision 3.51
diff -u -r3.51 xf86_ansic.h
--- os-support/xf86_ansic.h 24 Aug 2003 17:37:03 -  3.51
+++ os-support/xf86_ansic.h 12 Sep 2003 15:15:36 -
@@ -312,10 +312,19 @@
 extern int xf86setjmperror(xf86jmp_buf env);
 extern int xf86getjmptype(void);
 extern void xf86longjmp(xf86jmp_buf env, int val);
+extern void xf86longjmp0(xf86jmp_buf env, int val);
+
+#define jb_align(env) \
+   ((int *)(unsigned long)(env)) + JMP_BUF_ALIGN - 1) / \
+   JMP_BUF_ALIGN) * JMP_BUF_ALIGN))
+
 #define xf86setjmp_macro(env) \
-   (xf86getjmptype() == 0 ? xf86setjmp0((env)) : \
-   (xf86getjmptype() == 1 ? xf86setjmp1((env), xf86setjmp1_arg2()) : \
-   xf86setjmperror((env
+   (xf86getjmptype() == 0 ? xf86setjmp0(jb_align(env)) : \
+   (xf86getjmptype() == 1 ? xf86setjmp1(jb_align(env), xf86setjmp1_arg2()) : \
+   xf86setjmperror(jb_align(env
+
+#define xf86longjmp_macro(env, val) \
+   xf86longjmp(jb_align(env), val)
 
 #else /* XFree86LOADER || NEED_XF86_PROTOTYPES */
 #include 
Index: os-support/xf86_libc.h
===
RCS file: /home/x-cvs/xc/programs/Xserver/hw/xfree86/os-support/xf86_libc.h,v
retrieving revision 3.57
diff -u -r3.57 xf86_libc.h
--- os-support/xf86_libc.h  24 Aug 2003 17:37:03 -  3.57
+++ os-support/xf86_libc.h  12 Sep 2003 15:19:33 -
@@ -95,7 +95,9 @@
 typedef int xf86key_t;
 
 /* setjmp/longjmp */
-typedef int xf86jmp_buf[1024];
+#define JMP_BUF_SIZE 4096
+#define JMP_BUF_ALIGN 4096
+typedef int xf86jmp_buf[(JMP_BUF_SIZE + JMP_BUF_ALIGN) / sizeof(int)];
 
 /* for setvbuf */
 #define XF86_IONBF1
@@ -688,7 +690,7 @@
 #undef setjmp
 #define setjmp(a)   xf86setjmp_macro(a)
 #undef longjmp
-#define longjmp(a,b)xf86longjmp(a,b) 
+#define longjmp(a,b)xf86longjmp_macro(a,b) 
 #undef jmp_buf
 #define jmp_buf xf86jmp_buf
 #endif


Re: setjmp needs fixing again, here's the issues

2003-09-11 Thread David Dawes
On Thu, Sep 11, 2003 at 05:24:40PM -0400, John Dennis wrote:
>On Thu, 2003-09-11 at 14:35, David Dawes wrote:
>> What's the difference between this in the core executable:
>> 
>>   xf86A(pointer data)
>>   {
>>  return A(data);
>>   }
>> 
>>   SYMFUNC(xf86A)
>> 
>> and this:
>> 
>>   SYMFUNCALIAS(xf86A, A)
>
>The difference is that xf86A may massage "data" in some system specific
>manner specific to the libraries the main executable is linked against.

You left out that I said "when data is opaque to both the module and
the core executable".  Why?

>O.K. I'll make this patch and put it in the bugzilla. I'm not completely
>happy with it because its not really addressing the root problem. Setjmp
>may "blow up" on some other system in the future because we're ignoring
>the system defined requirements. For example in the non-ia64 case
>xf86jmp_buf will only be aligned on int boundaries, what if a system
>needs long alignment, or some other requirement?

When that happens we'll fix it.  If we want to be more defensive against
such possibilities, we can try using stronger alignment on all platforms
where the compiler supports it.

>libc version 1.0 requires 8  byte alignment, server XFree86 A is linked
>against this library.
>
>libc version 1.1 requires 16 byte alignment, server XFree86 B is linked
>against this library.
>
>The module in "theory" can be loaded into either XFree86 server A or B.
>If the module was built against the libc 1.0 requirement it will fail
>when loaded into XFree86 B. This is because unlike the system loader

Yes, if the size of jmp_buf or its alignment aren't sufficient, it will
be a problem.  We've been fixing the bugs in this as they are found.
We knew of the size issue, but the extra alignment issue didn't occur
to us.  If it had been tested on IA64 before 4.3 we'd probably have
found the problem and fixed it then.  I did specifically test the setjmp
behaviour for correctness on the platforms I have access too, but
unfortunately IA64 isn't one of them.

>which enforces the right version of the library to be loaded when
>XFree86 is loaded by the system, the module loader does not deal with
>version dependencies. In part because the version dependencies in theory
>have been isolated in the main executable image via wrappers and
>enforced by the system loader. The current setjmp implementation
>violates all these assumptions which is why I conclude this negatively
>impacts module portability. It is also true that if setjmp were in a

Bugs or limitations in our implementation impact module portability,
yes.  setjmp() isn't the first place we've had a portability problem
because of a bug or limitation in an implementation.  So far nobody has
given a reason why this approach must be inherently not portable, but
only correctable limitations in the implmentation that have led to
problems.  That what testing is for.

>Granted, if we are lucky this may never bite us, there is a reasonable
>chance it won't, but on the other hand to assert we haven't lost module
>independence and portability is not being honest about the new situation
>with modules that import xf86set_jmp.
>
>I'm not saying I have an answer to the problem we've created for
>ourselves, but I am saying we need to be honest about the impact, that
>any module that imports xf86set_jmp is no longer portable, is tied the
>libraries the main XFree86 is linked against, and as such we might as
>well use the system definitions of jmp_buf because its the robust
>solution and is no more, no less portable than inventing a jmp_buf
>abstraction that inherently is not robust. So if you're not getting
>portability and independence with the abstraction why sacrifice
>robustness?

I obviously disagree with your take on the situation.  You've found a
bug, lets fix it, test it as widely as possible, and move on.  The
"portability" issues you're raising here are hypothetical rather than
real reported cases.  The problem you found was on IA64.  That wasn't
specifically a module portability issue.  It was the fact that our
setjmp is currently plain broken on IA64.

David
-- 
David Dawes X-Oz Technologies
www.XFree86.org/~dawes  www.x-oz.com
___
Devel mailing list
[EMAIL PROTECTED]
http://XFree86.Org/mailman/listinfo/devel


Re: setjmp needs fixing again, here's the issues

2003-09-11 Thread John Dennis
On Thu, 2003-09-11 at 14:35, David Dawes wrote:
> What's the difference between this in the core executable:
> 
>   xf86A(pointer data)
>   {
>  return A(data);
>   }
> 
>   SYMFUNC(xf86A)
> 
> and this:
> 
>   SYMFUNCALIAS(xf86A, A)

The difference is that xf86A may massage "data" in some system specific
manner specific to the libraries the main executable is linked against.
Examples might include parameters to mmap where the base address and
size have to be adjusted for page boundaries and the mapping flags
passed. Or anything passed into an ioctl. I don't think the current set
of wrapped functions includes anything of this nature, but I thought it
was the principle behind it.

> Module independence comes from providing a more uniform ABI to the
> modules than you might get by linking directly with the functions provided
> by the system libraries.

Isn't that what I'm saying above? Xfree86 imposes its own interface
leaving the wrappers to translate when the underlying system differs.

Perhaps just as importantly since the wrappers are in the main
executable, which is the ONLY place loadable object dependencies are
enforced, its the only place you can be guaranteed that you'll be linked
to the version of shared object you're expecting!

> >If I following your reasoning then you would be happy with this
> >definition in xf86_libc.h

> Yes.

O.K. I'll make this patch and put it in the bugzilla. I'm not completely
happy with it because its not really addressing the root problem. Setjmp
may "blow up" on some other system in the future because we're ignoring
the system defined requirements. For example in the non-ia64 case
xf86jmp_buf will only be aligned on int boundaries, what if a system
needs long alignment, or some other requirement?

> I'll grant that what we're going with setjmp is a little hairy, but I
> haven't seen anything so far that says the basic approach doesn't work
> or impacts the portability of modules.

Yes, you are right setjmp is a true exception because it can't be
wrapped and thus isolate system specifics outside the module. And you're
also right its a bit hairy, it took me a while to fully understand
exactly what was going on.

As for impacting portability of modules, why isn't the following true?

libc version 1.0 requires 8  byte alignment, server XFree86 A is linked
against this library.

libc version 1.1 requires 16 byte alignment, server XFree86 B is linked
against this library.

The module in "theory" can be loaded into either XFree86 server A or B.
If the module was built against the libc 1.0 requirement it will fail
when loaded into XFree86 B. This is because unlike the system loader
which enforces the right version of the library to be loaded when
XFree86 is loaded by the system, the module loader does not deal with
version dependencies. In part because the version dependencies in theory
have been isolated in the main executable image via wrappers and
enforced by the system loader. The current setjmp implementation
violates all these assumptions which is why I conclude this negatively
impacts module portability. It is also true that if setjmp were in a
wrapper the module could be loaded into XFree86 server A or B without
issue, but thats not the case, it will crash the server if loaded in
XFree86 server B.

Granted, if we are lucky this may never bite us, there is a reasonable
chance it won't, but on the other hand to assert we haven't lost module
independence and portability is not being honest about the new situation
with modules that import xf86set_jmp.

I'm not saying I have an answer to the problem we've created for
ourselves, but I am saying we need to be honest about the impact, that
any module that imports xf86set_jmp is no longer portable, is tied the
libraries the main XFree86 is linked against, and as such we might as
well use the system definitions of jmp_buf because its the robust
solution and is no more, no less portable than inventing a jmp_buf
abstraction that inherently is not robust. So if you're not getting
portability and independence with the abstraction why sacrifice
robustness?




___
Devel mailing list
[EMAIL PROTECTED]
http://XFree86.Org/mailman/listinfo/devel


Re: setjmp needs fixing again, here's the issues

2003-09-11 Thread David Dawes
On Thu, Sep 11, 2003 at 11:18:44AM -0400, John Dennis wrote:
>On Wed, 2003-09-10 at 20:11, David Dawes wrote: 
>
>John> wrapper. So as long as we've already lost module
>John> independence by virtue of linking the system function why
>John> not go all the way and use the system definition of the
>John> system function's argument? It seems like
>
>David> We haven't lost module independence by doing that.
>
>Perhaps I'm misunderstanding module independence, can you confirm or
>deny some of the assumptions I've been working with:
>
>1) System specific functions are wrapped in an xf86* wrapper so that:
>
>   a) system differences are isolated at a single point which provides
>  a common interface to the rest of the server
>
>   b) all system specific functions are wrapped and live in the
>  executable XFree86. The XFree86 executable is linked against
>  the system libraries and hence the XFree86 executable is not
>  system independent.

b) is only necessary when required by a).

What's the difference between this in the core executable:

  xf86A(pointer data)
  {
 return A(data);
  }

  SYMFUNC(xf86A)

and this:

  SYMFUNCALIAS(xf86A, A)

when data is opaque to both the module and the core executable, and
interpreted only by A() in the system-provided library that the core
executable is linked against?

That the data is opaque to the module isn't true in most cases, hence the
wrapping.  It's possible we wrap more functions than is strictly necessary.

>2) module independence derives from the following:
>
>   a) modules only link against (e.g. import) from the XFree86
>  executable that loaded it. In other words all system
>  specific elements are contained in the executable, not a
>  loaded module.
>
>   b) The executable and modules share the same linking, 
>  relocation, exception, and call conventions. This makes
>  a module mostly system independent, but not 100%, e.g.
>  its possible, but not common, for different OS's on the same
>  architecture to have a different ABI, but less common today
>  as the industry is converging on standardized ABI's.

Module independence comes from providing a more uniform ABI to the
modules than you might get by linking directly with the functions provided
by the system libraries.  It also comes from having a loader that can
handle different object formats.

>If I following your reasoning then you would be happy with this
>definition in xf86_libc.h
>
>/* setjmp/longjmp */
>#if defined(__ia64__)
>typedef int xf86jmp_buf[1024]; __attribute__ ((aligned (16))); /* guarantees 128-bit 
>alignment! */
>#else
>typedef int xf86jmp_buf[1024];
>#endif

Yes.

>But if one is going to special case the definition of jmp_buf based on
>architecture why not use the system definition and typedef xf86jmp_buf
>to be jmp_buf? I suspect the answer will be that the system libraries
>could change requiring a different size buffer. I'd buy that if it
>weren't for the fact we are directly linking the library specfic
>version of setjmp into the module.

That it's directly linked makes no difference.  The size of jmp_buf is
determined when the module is compiled.  It needs to be large enough for
all the host systems it might run on, since that's where it gets used.
Taking the size of jmp_buf from the module system's headers doesn't
guarantee that.

I'll grant that what we're going with setjmp is a little hairy, but I
haven't seen anything so far that says the basic approach doesn't work
or impacts the portability of modules.

>Why a module referencing setjmp is tied to a specific system library:
>-
>
>As far as I can tell we've tied the module to a specific system
>library. Here is why I believe this. I'm going to simplify the
>discussion by assming there is only one xf86set_jmp symbol and ignore
>the type 0 and type 1 variants that select setjmp or sigsetjmp.
>
>1) a module makes a reference to xf86set_jmp.
>
>2) the xfree86 loader when it loads that module searches for that
>   symbol in its hash table of symbols, that table was populated in
>   part by the table in xf86sym.c which in a loadable build contains
>   this definition in the main executable:
>
>   #include 
>   SYMFUNCALIAS("xf86setjmp",setjmp)
>
>3) the above definition means when the symbol name "xf86setjmp" is
>   looked up by the loader it will get the address of setjmp that was
>   linked into the main executable. This is the function address that
>   the xfree86 loader will insert into module during its relocation
>   phase. 
>
>4) How does the address of setjmp get into the main executable? It
>   depends on whether the main executable was statically or
>   dynamically linked, but in either case the system will assure it
>   comes from a specific version of the library defined at the time
>   the main executable was linked.
>
>5) Therefore when a module that referenced setjmp is called its
>   

Re: setjmp needs fixing again, here's the issues

2003-09-11 Thread John Dennis
On Wed, 2003-09-10 at 20:11, David Dawes wrote: 

John> wrapper. So as long as we've already lost module
John> independence by virtue of linking the system function why
John> not go all the way and use the system definition of the
John> system function's argument? It seems like

David> We haven't lost module independence by doing that.

Perhaps I'm misunderstanding module independence, can you confirm or
deny some of the assumptions I've been working with:

1) System specific functions are wrapped in an xf86* wrapper so that:

   a) system differences are isolated at a single point which provides
  a common interface to the rest of the server

   b) all system specific functions are wrapped and live in the
  executable XFree86. The XFree86 executable is linked against
  the system libraries and hence the XFree86 executable is not
  system independent.

2) module independence derives from the following:

   a) modules only link against (e.g. import) from the XFree86
  executable that loaded it. In other words all system
  specific elements are contained in the executable, not a
  loaded module.

   b) The executable and modules share the same linking, 
  relocation, exception, and call conventions. This makes
  a module mostly system independent, but not 100%, e.g.
  its possible, but not common, for different OS's on the same
  architecture to have a different ABI, but less common today
  as the industry is converging on standardized ABI's.

Is the above basically correct?

If so then by directly linking a reference to the system's setjmp call
in a module haven't we violated the notion that only the main
executable has dependencies on the system libraries? The module is now
making a call whose parameters and behavior is specific to the
system. Actually, more correctly, its specific to the how the main
executable was linked (which is system specific), see below for why
this is true.

David> All that matters is that the jmp_buf type be defined on
David> each architecture in such a way that it meets the
David> requirements of all the supported OSs on that architecture.
David> Newer architectures are more likely to have a
David> platform-independent ABI anyway than was necessarily true
David> in the past.  If the platform's  can define the
David> type with the correct alignment, then so can we.  It
David> doesn't matter if the methods for doing this are
David> compiler-specific.  If the 128-bit alignment is an IA64 ABI
David> requirement, then I'd expect that all complilers for IA64
David> will have a method for defining jmp_buf with the correct
David> alignment.

If I following your reasoning then you would be happy with this
definition in xf86_libc.h

/* setjmp/longjmp */
#if defined(__ia64__)
typedef int xf86jmp_buf[1024]; __attribute__ ((aligned (16))); /* guarantees 128-bit 
alignment! */
#else
typedef int xf86jmp_buf[1024];
#endif

But if one is going to special case the definition of jmp_buf based on
architecture why not use the system definition and typedef xf86jmp_buf
to be jmp_buf? I suspect the answer will be that the system libraries
could change requiring a different size buffer. I'd buy that if it
weren't for the fact we are directly linking the library specfic
version of setjmp into the module.

Why a module referencing setjmp is tied to a specific system library:
-

As far as I can tell we've tied the module to a specific system
library. Here is why I believe this. I'm going to simplify the
discussion by assming there is only one xf86set_jmp symbol and ignore
the type 0 and type 1 variants that select setjmp or sigsetjmp.

1) a module makes a reference to xf86set_jmp.

2) the xfree86 loader when it loads that module searches for that
   symbol in its hash table of symbols, that table was populated in
   part by the table in xf86sym.c which in a loadable build contains
   this definition in the main executable:

   #include 
   SYMFUNCALIAS("xf86setjmp",setjmp)

3) the above definition means when the symbol name "xf86setjmp" is
   looked up by the loader it will get the address of setjmp that was
   linked into the main executable. This is the function address that
   the xfree86 loader will insert into module during its relocation
   phase. 

4) How does the address of setjmp get into the main executable? It
   depends on whether the main executable was statically or
   dynamically linked, but in either case the system will assure it
   comes from a specific version of the library defined at the time
   the main executable was linked.

5) Therefore when a module that referenced setjmp is called its
   calling the system version of setjmp in the exact library when the
   main executable was linked. 

I don't see how the above satisfies the conception of module
independence and by extension the avoidence of using th

Re: setjmp needs fixing again, here's the issues

2003-09-11 Thread Mike A. Harris
On Wed, 10 Sep 2003, John Dennis wrote:

>JD> alignment requirement right how do we specify the alignment requirement
>JD> to the compiler in a portable way such that it will build on a variety
>JD> of systems and compilers?
>
>Juliusz> typedef union {int i[1024]; long long l;} jmp_buf;
>
>Yes, I thought of that too, but "long long" isn't portable, right?
>Plus it still leaves us guessing we've covered the requirements.

long long is ISO C99


-- 
Mike A. Harris

___
Devel mailing list
[EMAIL PROTECTED]
http://XFree86.Org/mailman/listinfo/devel


Re: setjmp needs fixing again, here's the issues

2003-09-10 Thread David Dawes
On Wed, Sep 10, 2003 at 03:37:57PM -0400, John Dennis wrote:

>wrapper. So as long as we've already lost module independence by
>virtue of linking the system function why not go all the way and use
>the system definition of the system function's argument? It seems like

We haven't lost module independence by doing that.

All that matters is that the jmp_buf type be defined on each architecture
in such a way that it meets the requirements of all the supported OSs
on that architecture.  Newer architectures are more likely to have a
platform-independent ABI anyway than was necessarily true in the past.
If the platform's  can define the type with the correct
alignment, then so can we.  It doesn't matter if the methods for doing
this are compiler-specific.  If the 128-bit alignment is an IA64 ABI
requirement, then I'd expect that all complilers for IA64 will have a
method for defining jmp_buf with the correct alignment.

David
-- 
David Dawes X-Oz Technologies
www.XFree86.org/~dawes  www.x-oz.com
___
Devel mailing list
[EMAIL PROTECTED]
http://XFree86.Org/mailman/listinfo/devel


RE: setjmp needs fixing again, here's the issues

2003-09-10 Thread Alexander Stohr
> Since we already have a jmp_buf which is much larger than 
> necisarry, all
> that is needed is to take the first offset into it which is properly
> aligned for the given architecture and use that as the system jmp_buf.
> when the compiler can guarentee the proper alignment this becomes a
> 'nop', otherwise we waste at most alignment - sizeof(intmax_t) - 1
> bytes. not a big deal. best of all, this can be implemented portably
> quite easily.
> John

This will allow adapting to misc code compatible
CPU designs that do have but different alignment 
constrains. XServer can resolve that at runtime. 

This might happen when e.g. a more evolved CPU 
suddenly allows more freedom or some "shrinked"
derivate introduces more restrictions. In contrast
to this, if dynamic resolvement takes place you 
have to trim all your binaries for worst case
or you do have to provide multiple binaries.
Nothing that e.g. Linux distributions would like.

Hmmm, if there would be a way for making those
table a dynamically callocateable resource
rather than a static one...

-Alex.

___
Devel mailing list
[EMAIL PROTECTED]
http://XFree86.Org/mailman/listinfo/devel


Re: setjmp needs fixing again, here's the issues

2003-09-10 Thread Tim Roberts
On Wed, 10 Sep 2003 14:17:50 -0700, John Meacham wrote:
>
>Since we already have a jmp_buf which is much larger than necisarry, all
>that is needed is to take the first offset into it which is properly
>aligned for the given architecture and use that as the system jmp_buf.

But how will you do that at run-time?  Remember that it's supposed to be 
binary-compatible across systems.

--
- Tim Roberts, [EMAIL PROTECTED]
  Providenza & Boekelheide, Inc.


___
Devel mailing list
[EMAIL PROTECTED]
http://XFree86.Org/mailman/listinfo/devel


Re: setjmp needs fixing again, here's the issues

2003-09-10 Thread John Meacham
On Wed, Sep 10, 2003 at 03:37:57PM -0400, John Dennis wrote:
> 1) It may be hard to know the alignment requirements for all OS's and
> architectures (thats part of the reason we have system header
> files). We could guess 16 byte is sufficient. But even if we got the
> alignment requirement right how do we specify the alignment requirement
> to the compiler in a portable way such that it will build on a variety
> of systems and compilers? My understanding is that compiler alignment
> directives are not portable (e.g. not part of ANSI C). Are we
> comfortable picking one or two common alignment directives and
> conditionally compiling with the right one?

Since we already have a jmp_buf which is much larger than necisarry, all
that is needed is to take the first offset into it which is properly
aligned for the given architecture and use that as the system jmp_buf.
when the compiler can guarentee the proper alignment this becomes a
'nop', otherwise we waste at most alignment - sizeof(intmax_t) - 1
bytes. not a big deal. best of all, this can be implemented portably
quite easily.
John

-- 
---
John Meacham - California Institute of Technology, Alum. - [EMAIL PROTECTED]
---
___
Devel mailing list
[EMAIL PROTECTED]
http://XFree86.Org/mailman/listinfo/devel


Re: setjmp needs fixing again, here's the issues

2003-09-10 Thread John Dennis
On Wed, 2003-09-10 at 15:52, Juliusz Chroboczek wrote:
JD> alignment requirement right how do we specify the alignment requirement
JD> to the compiler in a portable way such that it will build on a variety
JD> of systems and compilers?

Juliusz> typedef union {int i[1024]; long long l;} jmp_buf;

Yes, I thought of that too, but "long long" isn't portable, right?
Plus it still leaves us guessing we've covered the requirements.

> JD> Given the argument in 3 above I'd recommend taking out xf86jmp_buf and
> JD> putting back in #include . It seems the simplist, most
> JD> robust, and in practical terms sacrifices little.

Juliusz> I agree.

Good, thank you


___
Devel mailing list
[EMAIL PROTECTED]
http://XFree86.Org/mailman/listinfo/devel


Re: setjmp needs fixing again, here's the issues

2003-09-10 Thread Juliusz Chroboczek
JD> alignment requirement right how do we specify the alignment requirement
JD> to the compiler in a portable way such that it will build on a variety
JD> of systems and compilers?

typedef union {int i[1024]; long long l;} jmp_buf;

JD> Given the argument in 3 above I'd recommend taking out xf86jmp_buf and
JD> putting back in #include . It seems the simplist, most
JD> robust, and in practical terms sacrifices little.

I agree.

Juliusz

___
Devel mailing list
[EMAIL PROTECTED]
http://XFree86.Org/mailman/listinfo/devel


setjmp needs fixing again, here's the issues

2003-09-10 Thread John Dennis
I have found the problem with XFree86's implementation of setjmp on
ia64. It occurs because we are ignoring the type definition of
setjmp's argument.

   int setjmp(jmp_buf env);

In xf86_lib.h we redefine jmp_buf thusly:

/* setjmp/longjmp */
typedef int xf86jmp_buf[1024];

#undef jmp_buf
#define jmp_buf xf86jmp_buf

Based on the discussions that occurred last Feb and March I believe
this was done to preserve a loadable modules system independence. The
notion being that each system may have a different jmp_buf size, we
can't know aprori what that is, so make it bigger than we think is
necessary and it should be big enough no matter on what system the
module is loaded on.

However ignoring the system defined type for jmp_buf we've ignored the
system specific alignment requirement of jmp_buf. On ia64 it must be
16 byte aligned because setjmp when it saves the execution context on
ia64 uses machine instructions that writes the contents of the 16 byte
floating point registers, the destination address must be 16 byte
aligned or a SIGBUS fault is signaled.

On ia64 you can see in /usr/include/bits/setjmp.h the following
jmp_buf definition:

/* the __jmp_buf element type should be __float80 per ABI... */
typedef long __jmp_buf[_JBLEN] __attribute__ ((aligned (16))); /*
guarantees 128-bit alignment! */

I did an experiment where I defeated the use of xf86jmp_buf and
instead used the systems definition of jmp_buf and the SIGBUS problem
went away. Earlier I had noted that a static server did not exhibit
the problem, thats because the xf86jmp_buf is only used in a loadable
build. 

How do we fix this?
---

1) It may be hard to know the alignment requirements for all OS's and
architectures (thats part of the reason we have system header
files). We could guess 16 byte is sufficient. But even if we got the
alignment requirement right how do we specify the alignment requirement
to the compiler in a portable way such that it will build on a variety
of systems and compilers? My understanding is that compiler alignment
directives are not portable (e.g. not part of ANSI C). Are we
comfortable picking one or two common alignment directives and
conditionally compiling with the right one?

2) We cannot force alignment without the use of compiler directives
for any alignment greater than the maximum size of a basic type by
creating artifical structs. This is because in C structs are aligned
to the size of the maximum basic type, which on ia64 is 8 (long,
double, etc), half the alignment requirement. Plus such a scheme would
put us back into guessing type sizes, alignment requrements, etc. It
would not be robust.

3) We could use the systems's definition of jmp_buf. That means it
will always be correct on the system it was compiled on, but that
module may be loaded on another system with potentially different
jmp_buf definitions and cause problems. I realize we have a goal of
system independence for loadable modules, but do we really expect
modules built on one system to be loaded on a significantly different
system? They are after all binary modules. I also realize that setjmp
is currently the only thing in our loadable modules which is not
wrapped by a core server function so it would kind of be a shame to
let this one item polute module independence but we have no choice,
the loader now links the system implementation of setjmp and not a
wrapper. So as long as we've already lost module independence by
virtue of linking the system function why not go all the way and use
the system definition of the system function's argument? It seems like
we would not have lost anything and would have picked up robustness
we've given up by trying to use a system neutral definition of the
jmp_buf argument.

Given the argument in 3 above I'd recommend taking out xf86jmp_buf and
putting back in #include . It seems the simplist, most
robust, and in practical terms sacrifices little.

Comments?

I'm going to file a bugzilla on this, its very definitely broken on
ia64 and causes the server to crash. I will put the text of this in
the bugzilla.

John



___
Devel mailing list
[EMAIL PROTECTED]
http://XFree86.Org/mailman/listinfo/devel