Dereference function descriptors. --- Just putting this out there. In addition to function descriptor deref (still in need of macros like LOAD_REG_ADDR_IMMEDIATE and LOAD_REG_ADDR) I checked whether it makes any difference whether we simulate the original ba by a bctr - not noticably. Also FYI my unsuccessful ldscript attempts.
arch/ppc/qemu/start.S | 30 ++++++++++++++++++++++++++++++ arch/ppc64/qemu/ldscript | 43 +++++++++++++++++++++++++++++++++++++++++-- 2 files changed, 71 insertions(+), 2 deletions(-)
diff --git a/arch/ppc/qemu/start.S b/arch/ppc/qemu/start.S index 6cf20cf..1a63082 100644 --- a/arch/ppc/qemu/start.S +++ b/arch/ppc/qemu/start.S @@ -274,15 +274,33 @@ GLOBL(__vectors):
call_dsi_exception: LOAD_REG_IMMEDIATE(r3, dsi_exception) +#ifdef __powerpc64__ + ld r3, 0(r3) +#endif mtctr r3 bctrl +#if 1 + LOAD_REG_IMMEDIATE(r3, exception_return) + mtctr r3 + bctr +#else b exception_return +#endif
call_isi_exception: LOAD_REG_IMMEDIATE(r3, isi_exception) +#ifdef __powerpc64__ + ld r3, 0(r3) +#endif mtctr r3 bctrl +#if 1 + LOAD_REG_IMMEDIATE(r3, exception_return) + mtctr r3 + bctr +#else b exception_return +#endif
exception_return: EXCEPTION_EPILOGUE @@ -363,6 +381,12 @@ GLOBL(__vectors_end): /* entry */ /************************************************************************/
+#ifdef __powerpc64__ +#define LOAD_REG_ADDR(reg, name) ld (reg), name@got(r2) +#else +#define LOAD_REG_ADDR(reg, name) LOAD_REG_IMMEDIATE(reg, name) +#endif + GLOBL(_entry):
#ifdef CONFIG_PPC_64BITSUPPORT @@ -448,7 +472,13 @@ GLOBL(_entry): /* save memory size in stack */
bl setup_mmu +#if 0 + LOAD_REG_ADDR(r3, entry) + mtctr r3 + bctrl +#else bl entry +#endif 1: nop b 1b
diff --git a/arch/ppc64/qemu/ldscript b/arch/ppc64/qemu/ldscript index 1d8aa8e..2849a45 100644 --- a/arch/ppc64/qemu/ldscript +++ b/arch/ppc64/qemu/ldscript @@ -26,9 +26,41 @@ SECTIONS
. = TEXT_ADDR; /* Normal sections */ + .rela.dyn : + { + *(.rela.opd) + *(.rela.init) + *(.rela.text .rela.text.* .rela.gnu.linkonce.t.*) + *(.rela.fini) + *(.rela.rodata .rela.rodata.* .rela.gnu.linkonce.r.*) + *(.rela.data .rela.data.* .rela.gnu.linkonce.d.*) + *(.rela.tdata .rela.tdata.* .rela.gnu.linkonce.td.*) + *(.rela.tbss .rela.tbss.* .rela.gnu.linkonce.tb.*) + *(.rela.ctors) + *(.rela.dtors) + *(.rela.got) + *(.rela.toc) + *(.rela.branch_lt) + *(.rela.sdata .rela.sdata.* .rela.gnu.linkonce.s.*) + *(.rela.sbss .rela.sbss.* .rela.gnu.linkonce.sb.*) + *(.rela.sdata2 .rela.sdata2.* .rela.gnu.linkonce.s2.*) + *(.rela.sbss2 .rela.sbss2.* .rela.gnu.linkonce.sb2.*) + *(.rela.bss .rela.bss.* .rela.gnu.linkonce.b.*) + PROVIDE_HIDDEN (__rel_iplt_start = .); + PROVIDE_HIDDEN (__rel_iplt_end = .); + PROVIDE_HIDDEN (__rela_iplt_start = .); + *(.rela.iplt) + PROVIDE_HIDDEN (__rela_iplt_end = .); + } + .rela.plt : + { + *(.rela.plt) + } + .rela.tocbss : { *(.rela.tocbss) } .text ALIGN(4096): { *(.text) *(.text.*) + *(.sfpr .glink) }
.rodata ALIGN(4096): { @@ -41,13 +73,20 @@ SECTIONS _data = .; *(.data) *(.data.*) - _edata = .; } + .data1 : { *(.data1) } + .toc1 : ALIGN(8) { *(.toc1) } + .opd : ALIGN(8) { KEEP (*(.opd)) } + .got : ALIGN(8) { *(.got .toc) } + _edata = .;
- .bss ALIGN(4096): { _bss = .; + .tocbss : ALIGN(8) { *(.tocbss) } + .bss ALIGN(4096): { *(.sbss) *(.sbss.*) + *(.plt) + *(.iplt) *(.bss) *(.bss.*) *(COMMON)