Bug#256312: How to jump in inline assembler with -fPIC?
Hi,
Bug #256312 is a problem that can be reproduced with 20 lines of C++ code:
---<boingboing.cc>-------------------------------------------------------------
extern "C" int putchar(int);
extern "C" void catchpoint(void);
struct thrower_t {
inline thrower_t() {
__asm__("jmp %*%0" : : "rm" ((void*)(catchpoint)));
}
};
#ifdef BOINGBOING
static thrower_t thrower;
#endif
class herring_t {
public:
herring_t() {
putchar('A');
}
};
static herring_t red_herring;
struct catcher_t {
inline catcher_t() {
__asm__("\ncatchpoint:");
}
};
static catcher_t catcher;
int main()
{
putchar('\n');
}
--------------------------------------------------------------------------------
The purpose of the code is to either jump over the construction of the
red_herring object or not, depending on whether -DBOINGBOING was def'ed.
All this is part of a scheme for ordering static C++ objects, in case you
are wondering why one writes such code.
When I compile that program on ia32 I get the expected result: it either
prints 'A' followed by a newline or just a newline:
gromit:~$ uname -a
Linux gromit 2.6.7 #1 Thu Jun 17 22:32:35 CEST 2004 i686 GNU/Linux
gromit:~$ g++ -O boingboing.cc && ./a.out
A
gromit:~$ g++ -DBOINGBOING -O boingboing.cc && ./a.out
gromit:~$ g++ -fPIC -DBOINGBOING -O boingboing.cc && ./a.out
Now, on amd64, the program segfaults if -fPIC has been set and
-DBOINGBOING is def'ed. Apparently the jump to the catchpoint label goes
havoc:
kreckel@ravel:~$ uname -a
Linux ravel 2.6.5 #3 SMP Tue Apr 13 13:41:54 UTC 2004 x86_64 GNU/Linux
kreckel@ravel:~$ g++ -O boingboing.cc && ./a.out
A
kreckel@ravel:~$ g++ -DBOINGBOING -O boingboing.cc && ./a.out
kreckel@ravel:~$ g++ -fPIC -DBOINGBOING -O boingboing.cc && ./a.out
Segmentation fault
I see the differences in GCC's config/i386/i386.md but I am not an expert
in GCC machine description files and the ABI. Does anybody have a
suggestion how to write the __asm__() statement in the thrower_t
constructor?
TIA
-richy.
--
.''`. Richard B. Kreckel
: :' : <kreckel@debian.org>
`. `' <kreckel@ginac.de>
`- <http://www.ginac.de/~kreckel/>
Reply to: