Newbie questions
Quoted 14 lines · CH Gowri Kumar
I wrote the above program and compiled it and found the appropriate codes for the instructions using objdump -d and wrote the following program
char sc[] ="\x0a"
"\x10" "\x00" "\x18\x00\x21\x00\x92\x00\x00\x42\xe0\x11\x00\x20\x84\x0a"; main() { void (*fp)(void); fp = (void*)sc; fp(); }
Quoted 3 lines
But this program on execution gives me the error:
"Illegal instruction (core dumped)"
(A similar program for IA-32 worked well.)
function pointers on ia64 are "fat" -- that is, they are not the address of the function, they are the address of a function descriptor which contains (iirc) the GP and the address of the function. i believe glibc pokes around with this kind of thing, so you may wish to look at the ia64 assembly code in there to see how it does it.
Signature · 1 line
Revolutions do not require corporate support.
hello all,
I am a post-graduate student trying to write a JIT compiler for .NET CLR on Linux,IA-64.
I have some queries related to IA-64 assembly programming
I plan to write the JIT this way:
I generate the native code directly (instead of assembly language and then using assembler)for a particular method and jump to the address of the starting memory location where I have generated the native code. I have written a small program to check whether such a thing is feasible, which is as follows:
#include<unistd.h>
int main()
{
__asm__("
mov r32
mov r1525
break 0x100000" );
}
I wrote the above program and compiled it and found the appropriate codes for the instructions using objdump -d and wrote the following program
char sc[] ="\x0a"
"\x10"
"\x00"
"\x18\x00\x21\x00\x92\x00\x00\x42\xe0\x11\x00\x20\x84\x0a";
main()
{
void (*fp)(void);
fp = (void*)sc;
fp();
}But this program on execution gives me the error:
"Illegal instruction (core dumped)"
(A similar program for IA-32 worked well.)
I couldn't figure out what could be the problem.
I also tried using "br instruction" approach instead of the function pointer approach, but couldn't succeed.
Can anyone explain why it is failing or atleast give me pointers where to look for?
Thanks in advance.
Gowri Kumar
Quoted 19 lines · Matthew Wilcox
Quoted 14 lines · CH Gowri Kumar
I wrote the above program and compiled it and found the appropriate codes for the instructions using objdump -d and wrote the following program
char sc[] ="\x0a"
"\x10" "\x00" "\x18\x00\x21\x00\x92\x00\x00\x42\xe0\x11\x00\x20\x84\x0a"; main() { void (*fp)(void); fp = (void*)sc; fp(); }Quoted 3 lines
But this program on execution gives me the error:
"Illegal instruction (core dumped)"
(A similar program for IA-32 worked well.)
Quoted 6 lines
function pointers on ia64 are "fat" -- that is, they are not the address of the function, they are the address of a function descriptor which contains (iirc) the GP and the address of the function. i believe glibc pokes around with this kind of thing, so you may wish to look at the ia64 assembly code in there to see how it does it.
to be more precise a function descriptors is:
struct {
unsigned long func_addr;
unsigned long gp;
};You should also take a look at the calling convention documentation at:
http://developer.intel.com/design/itanium
Signature · 1 line
-Stephane
Quoted 1 line
Quoted 1 line
Quoted 1 line
Quoted 1 line
Quoted 1 line · CH Gowri Kumar
Gowri> char sc[] ="\x0a" "\x10" "\x00"
Gowri> "\x18\x00\x21\x00\x92\x00\x00\x42\xe0\x11\x00\x20\x84\x0a"; Gowri> main() { void (*fp)(void); fp = (void*)sc; fp(); }
Gowri> But this program on execution gives me the error: "Illegal Gowri> instruction (core dumped)" (A similar program for IA-32 Gowri> worked well.)
Gowri> I couldn't figure out what could be the problem. I also Gowri> tried using "br instruction" approach instead of the function Gowri> pointer approach, but couldn't succeed.
Gowri> Can anyone explain why it is failing or atleast give me Gowri> pointers where to look for?
You'll want to read the software convention manual, especially that portion talking about function descriptors. The manual is normally available at:
http://www.intel.com/design/Itanium/arch_spec.htm
Unfortunately, the URL it points to
(http://www.intel.com/design/itanium/downloads/24535803s.htm) is currently broken. [Could someone from Intel look into getting this fixed?]
But briefly, a function descriptor consists of (at least) two words:
the first one being the entry point (instruction address) and the second one being the global pointer. I attached a small test program that demos "dynamic" code generation (note: instruction bundles must be aligned to 16-byte boundary, which wasn't guaranteed in your test program).
--david
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <unistd.h>
#include <malloc.h>
#include <sys/mman.h>
#ifdef __ia64__
typedef struct _fp
{
long addr;
long gp;
} IA64_FUNCTION;
static void flush_cache (void *addr, unsigned long len) {
void *end = (char *) addr + len;
while (addr < end)
{
asm volatile ("fc %0" :: "r"(addr));
addr = (char *) addr + 32;
} asm volatile (";;sync.i;;srlz.i;;");
}
#endif
void TestApp(void)
{
#ifdef __ia64__
__asm__ __volatile__ ("nop.i 0");
__asm__ __volatile__ ("nop.i 0");
__asm__ __volatile__ ("nop.i 0");
__asm__ __volatile__ ("nop.i 0");
#else
__asm__ __volatile__ ("nop");
#endif
return;
}
int main(int argc, char *argv[])
{
void (*pSubroutine)(void);
unsigned char *pBuffer1;
long alignment;
#ifdef __ia64__
IA64_FUNCTION *fp;
IA64_FUNCTION newfp;
#endif
printf("Test ***\n");
malloc(0x10000);
// Allocate and align buffer on 16 byte boundary
pBuffer1 = (unsigned char *)malloc(0x1000);
alignment = ((unsigned long)pBuffer1 % 16);
pBuffer1 = pBuffer1 + 16 - alignment;#ifdef __ia64__
fp = (IA64_FUNCTION *)TestApp;
printf("pSub Addr = 0x%lX GP = 0x%lX\n", fp->addr, fp->gp); memcpy(pBuffer1, (unsigned char *)fp->addr, 256); flush_cache(pBuffer1, 0x1000);
newfp.gp = fp->gp;
newfp.addr = (long)pBuffer1;
printf("pSub Addr = 0x%lX GP = 0x%lX\n", newfp.addr, newfp.gp);
pSubroutine = (void (*)(void))&newfp;mprotect((void *) ((long) pBuffer1 & ~(getpagesize () - 1)),
getpagesize(), PROT_READ | PROT_WRITE | PROT_EXEC);
#else
printf("pSub Addr = 0x%lX\n", pBuffer1);
memcpy(pBuffer1, &TestApp, 32);
pSubroutine = (void (*)(void)) pBuffer1;
#endif
(*pSubroutine)();
printf ("done!\n");
return(0);
}
The Software conventions document is at
http://developer.intel.com/design/itanium/downloads/245358.htm
All documents can now be found at
http://developer.intel.com/design/itanium/arch_spec.htm
Thanks
Sunil
-----Original Message-----
From: David Mosberger [mailto:[email protected]]
Sent: Friday, November 08, 2002 11:09 AM
To: CH Gowri Kumar
Cc: '[email protected] '
Subject: Re: [Linux-ia64] Newbie questions
Quoted 1 line
Quoted 1 line
Quoted 1 line
Quoted 1 line
Quoted 1 line
On Sat, 9 Nov 2002 00:21:40 +0530 (IST), CH Gowri Kumar
<[email protected]> said:
Gowri> char sc[] ="\x0a" "\x10" "\x00"
Gowri> "\x18\x00\x21\x00\x92\x00\x00\x42\xe0\x11\x00\x20\x84\x0a"; Gowri> main() { void (*fp)(void); fp = (void*)sc; fp(); }
Gowri> But this program on execution gives me the error: "Illegal Gowri> instruction (core dumped)" (A similar program for IA-32 Gowri> worked well.)
Gowri> I couldn't figure out what could be the problem. I also Gowri> tried using "br instruction" approach instead of the function Gowri> pointer approach, but couldn't succeed.
Gowri> Can anyone explain why it is failing or atleast give me Gowri> pointers where to look for?
You'll want to read the software convention manual, especially that portion talking about function descriptors. The manual is normally available at:
http://www.intel.com/design/Itanium/arch_spec.htm
Unfortunately, the URL it points to
(http://www.intel.com/design/itanium/downloads/24535803s.htm) is currently broken. [Could someone from Intel look into getting this fixed?]
But briefly, a function descriptor consists of (at least) two words:
the first one being the entry point (instruction address) and the second one being the global pointer. I attached a small test program that demos "dynamic" code generation (note: instruction bundles must be aligned to 16-byte boundary, which wasn't guaranteed in your test program).
--david
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <unistd.h>
#include <malloc.h>
#include <sys/mman.h>
#ifdef __ia64__
typedef struct _fp
{
long addr;
long gp;
} IA64_FUNCTION;
static void flush_cache (void *addr, unsigned long len) {
void *end = (char *) addr + len;
while (addr < end)
{
asm volatile ("fc %0" :: "r"(addr));
addr = (char *) addr + 32;
} asm volatile (";;sync.i;;srlz.i;;");
}
#endif
void TestApp(void)
{
#ifdef __ia64__
__asm__ __volatile__ ("nop.i 0");
__asm__ __volatile__ ("nop.i 0");
__asm__ __volatile__ ("nop.i 0");
__asm__ __volatile__ ("nop.i 0");
#else
__asm__ __volatile__ ("nop");
#endif
return;
}
int main(int argc, char *argv[])
{
void (*pSubroutine)(void);
unsigned char *pBuffer1;
long alignment;
#ifdef __ia64__
IA64_FUNCTION *fp;
IA64_FUNCTION newfp;
#endif
printf("Test ***\n");
malloc(0x10000);
// Allocate and align buffer on 16 byte boundary
pBuffer1 = (unsigned char *)malloc(0x1000);
alignment = ((unsigned long)pBuffer1 % 16);
pBuffer1 = pBuffer1 + 16 - alignment;#ifdef __ia64__
fp = (IA64_FUNCTION *)TestApp;
printf("pSub Addr = 0x%lX GP = 0x%lX\n", fp->addr, fp->gp); memcpy(pBuffer1, (unsigned char *)fp->addr, 256); flush_cache(pBuffer1, 0x1000);
newfp.gp = fp->gp;
newfp.addr = (long)pBuffer1;
printf("pSub Addr = 0x%lX GP = 0x%lX\n", newfp.addr, newfp.gp);
pSubroutine = (void (*)(void))&newfp;mprotect((void *) ((long) pBuffer1 & ~(getpagesize () - 1)),
getpagesize(), PROT_READ | PROT_WRITE | PROT_EXEC);
#else
printf("pSub Addr = 0x%lX\n", pBuffer1);
memcpy(pBuffer1, &TestApp, 32);
pSubroutine = (void (*)(void)) pBuffer1;
#endif
(*pSubroutine)();
printf ("done!\n");
return(0);
}
_______________________________________________
Linux-IA64 mailing list
[email protected]
http://lists.linuxia64.org/lists/listinfo/linux-ia64
Quoted 1 line
Quoted 1 line
Quoted 1 line
Quoted 1 line
Quoted 1 line · Sunil
Sunil> The Software conventions document is at
Sunil> http://developer.intel.com/design/itanium/downloads/245358.htm
Ah, yes, this works!
Sunil> All documents can now be found at
Sunil> http://developer.intel.com/design/itanium/arch_spec.htm
Should this be: http://developer.intel.com/design/itanium/family/ ? The former results in a "this page has moved page" (it does redirect eventually, but it's slower).
In any case, thanks for providing the URL for the conventions manual.
--david