[U-Boot] [RFC] [PATCH V2] arm: arm926ejs: use ELF relocations

Reinhard Meyer u-boot at emk-elektronik.de
Tue Oct 5 12:36:19 CEST 2010


Albert ARIBAUD schrieb:
> Le 05/10/2010 11:39, Reinhard Meyer a écrit :
>>> for (p = start; p<  end; p += 8)
>>>     work;
>>> and not
>>
>> Give me some time, and I will complete this loop to do
>> relocation in "C".

Almost finished with it :)

>> Reinhard
> 
> Be careful, though, that you need a way to obtain the 'source' address
> of the .rel.dyn start and end and of the .dynsym start, plus the offset
> from 'source' to 'target'; these may not be easy to compute in C

No problem, the statements

.globl _rel_dyn_start_ofs
_rel_dyn_start_ofs:
	.word __rel_dyn_start - _start
.globl _rel_dyn_end_ofs
_rel_dyn_end_ofs:
	.word __rel_dyn_end - _start
.globl _dynsym_start_ofs
_dynsym_start_ofs:
	.word __dynsym_start - _start

get the values to "C".

> 
> I think the right balance might be to have an ASM framework to prepare
> these four values and pass them to the C relocation routine.

see above.

> 
> Note that you may also have to make sure the routine itself is
> insensitive to relocation too.

Why? It runs while code is at the right TEXT_BASE. If that shall
be weakened, I am not sure it can be done in "C".

I am troubled by your following statements in assembly:


Note: my u-boot has only one type "2" relocation:
patch 21f151fc : 00000302

fixabs:
	/* absolute fix: set location to (offset) symbol value */
r1=00000302
	mov	r1, r1, LSR #4		/* r1 <- symbol index in .dynsym */
r1=00000030
	add	r1, r10, r1		/* r1 <- address of symbol in table */
r1=00000030+_dynsym_start_ofs
	ldr	r1, [r1, #4]		/* r1 <- symbol value */
r1=r1[4]
	add	r1, r9			/* r1 <- relocated sym addr */
	b	fixnext

Is an entry in _dynsym really 16 bytes long?

Best Regards,
Reinhard

PS: I am about there:

#ifdef CONFIG_USE_C_RELOCATION
	/* TODO: check for identical source and destination */
	/* TODO: check for overlapping */
	/* copy image, including initialized data */
	debug ("memcpy(%08lx,%08lx,%ld)\n",
		addr, _TEXT_BASE, _bss_start_ofs);
	memcpy (addr, _TEXT_BASE, _bss_start_ofs);
	/* now fix the code */
	debug ("_dynsym_start_ofs=%08lx _rel_dyn_start_ofs=%08lx _rel_dyn_end_ofs=%08lx\n",
		_dynsym_start_ofs, _rel_dyn_start_ofs, _rel_dyn_end_ofs);
	for (dyn_ptr = (ulong *)(_TEXT_BASE + _rel_dyn_start_ofs);
			dyn_ptr < (ulong *)(_TEXT_BASE + _rel_dyn_end_ofs);
			dyn_ptr += 8) {
		ulong *patchaddr = (ulong *) dyn_ptr[0] + addr;
		debug ("patch %08lx : %08lx\n",
			patchaddr, dyn_ptr[1]);
		switch (dyn_ptr[1] & 0xff) {
		case 23: /* rel fixup */
			*patchaddr += addr;
			break;
		case 2: /* abs fixup */
			break;
		default: /* unhandled fixup */
			break;
		}
	}

Beautifying comes later ;)



More information about the U-Boot mailing list