diff options
| -rw-r--r-- | arch/powerpc/reloc.h | 35 | ||||
| -rw-r--r-- | src/ldso/powerpc/start.s | 33 | 
2 files changed, 43 insertions, 25 deletions
| diff --git a/arch/powerpc/reloc.h b/arch/powerpc/reloc.h index 58e482d6..113dfa15 100644 --- a/arch/powerpc/reloc.h +++ b/arch/powerpc/reloc.h @@ -16,21 +16,40 @@ static inline void do_single_reloc(  	switch(type) {  	case R_PPC_GLOB_DAT:  	case R_PPC_JMP_SLOT: -		*reloc_addr = sym_val; -		break; -	case R_PPC_REL32: -		if (sym_val) *reloc_addr += sym_val; -		else *reloc_addr += (size_t)base_addr; +	case R_PPC_ADDR32: +		*reloc_addr = sym_val + addend;  		break;  	case R_PPC_COPY:  		memcpy(reloc_addr, (void *)sym_val, sym_size);  		break;  	case R_PPC_RELATIVE: -		*reloc_addr += (size_t)base_addr; +		*reloc_addr = (size_t)base_addr + addend;  		break; -	//case R_PPC64_DTPMOD64:  //R_X86_64_DTPMOD64: -	case R_PPC_DTPMOD32:  //R_386_TLS_DTPMOD32: +	case R_PPC_DTPMOD32:  		*reloc_addr = def.dso ? def.dso->tls_id : self->tls_id;  		break; +	case R_PPC_DTPREL32: +		*reloc_addr = def.sym->st_value + addend; +		break; +	case R_PPC_TPREL32: +		*reloc_addr += def.sym +			? def.sym->st_value + def.dso->tls_offset - 0x7000 +			: self->tls_offset - 0x7000; +		break;  	}  } + +void __reloc_self(int c, size_t *a, size_t *dynv) +{ +	char *base; +	size_t t[20], n; +	for (a+=c+1; *a; a++); +	for (a++; *a; a+=2) if (*a<20) t[*a] = a[1]; +	base = (char *)t[AT_BASE]; +	if (!base) base = (char *)(t[AT_PHDR] & -4096); +	for (a=dynv; *a; a+=2) if (*a<20) t[*a] = a[1]; +	n = t[DT_RELASZ]; +	for (a=(void *)(base+t[DT_RELA]); n; a+=3, n-=12) +		if (a[1]%256 == R_PPC_RELATIVE) +			*(size_t *)(base+a[0]) = (size_t)base + a[2]; +} diff --git a/src/ldso/powerpc/start.s b/src/ldso/powerpc/start.s index ac2c20c8..08b5979a 100644 --- a/src/ldso/powerpc/start.s +++ b/src/ldso/powerpc/start.s @@ -1,22 +1,21 @@ -# FIXME : does not work, the small data array needs to be relocated. -# see elfspec_ppc.pdf, page 76-84  	.global _start  	.type   _start,@function  _start: -	mr      9, 1                  # Save the original stack pointer. -	clrrwi  1, 1, 4               # Align the stack to 16 bytes. -	lis     13, _SDA_BASE_@ha      # r13 points to the small data area. -	addi    13, 13, _SDA_BASE_@l -	li      0, 0                   # Zero the frame pointer. -	lwz     3, 0(9)               # and argc... -	addi    4, 9, 4               # and argv ... -	mtlr    0                      # Clear the link register. -	# Go to the musl dynamic linker entry point. +	bl      1f +2:	.long   _DYNAMIC-2b +1:	mflr    5 +	lwz     0, 0(5) +	add     5, 0, 5 +	lwz     3, 0(1) +	addi    4, 1, 4 +	addi    1, 1, -16 +	bl      __reloc_self + +	lwz     3, 16(1) +	addi    4, 1, 20  	bl      __dynlink -	cmpi    4, 0, 3, 1            # Check for a 1. -	bne     4, .                   # Stay here -	mtlr    3                      # Set the link address... +	addi    1, 1, 16 + +	mtlr    3  	li      3, 0 -	blr                             # and go. -	.end    _start -	.size   _start, .-_start +	blr | 
