Re: how to realize long jump instruction in ia 64 assebly language?

James E Wilson <[email protected]> 17 Feb 2006 13:20:14 -0800
Newsgroups gmane.linux.redhat.ia64.general
Message-ID <[email protected]>
On Thu, 2006-02-16 at 20:04, ChenMingChun wrote:
>            1. mmap the ld-linux-ia64.so.2 to the memory .
>            For each PT_LOAD segment in the program header table,
>  the loader ensures that the ELF image from p_offset for p_filesz
>  bytes is copied into a memory buffer (with p_flags permissions)
>  at p_vaddr of p_memsz (aligned to p_align) bytes.

I don't think this is sufficient.  If you are loading segments with
run-time relocations, then you have to perform the relocations after
loading the segments.

Also, some segments are special, like the .got section.  You need to set
the gp pointer to point to this section before branching to the new
code.  Otherwise, all gp-relative references will fail.

> in IA32 or x86_64 it prints "this is test".it's ok.
> but in IA64 ,i think several differences between  IA32 and IA64.

Another important difference that you didn't list, is that on IA-64,
code is always PIC, even when compiled with -static.  I think this is
the main source of your problems.

>        1.the space of memory is divided into 8 regions. we must modify
> ld script to compile myld.c so that the data
> segment and text segment are loaded into region 1 0x2000000000000000
> -0x4000000000000000,otherwise it might be
> handing up when myld.so was as the dynamic  linker.

You didn't include this linker script.

I did manage to produce a segfault when I tried your testcase.  Trying
to debug it by adding "return 0;" statements, I discovered it died
inside the fstat call.  Looking at the disassembled code, I figured out
that it died inside the glibc routine __syscall_error.  This is a short
sequence of assembly code, so the only reason why it could have failed
is because either gp (global pointer) or tp (thread pointer) was set
wrong.

I tried compiling myld.c with -mno-pic, and it got farther, to the read
call, and then it died the same way.

I think what you are trying to do here is very complicated, and it just
happened to work on x86 because it uses a rather simple ABI.  The IA-64
ABI is much more complicated, and there are many more things that can go
wrong.  You will need to spend some time reading IA-64 ABI documents,
and you will probably need to spend some time learning how some low
level aspects of glibc work, and you will have to spend more time
debugging your code.