ARM long branch stubs: be8

Richard Earnshaw rearnsha@arm.com
Mon Feb 23 13:38:00 GMT 2009


On Mon, 2009-02-23 at 12:40 +0100, Christophe LYON wrote:
> Hi all,
> 
> Following our recent discussion, I propose the attached patch to fix 
> big-endian / be8 stubs encoding issues.
> 
> I am not particularly proud of the way it's now done, but it does the job.
> In short, the Thumb instructions in the stubs now use 1 entry per 
> instruction (instead of 2 instr per entry), but this implies that the 
> encoding functions know the exact layout of each stub, so it makes 
> maintenance a bit more painful (I added some comments to warn about that).
> 
> I have added one more test (farcall-thumb-arm-be8).
> 
> Once this is OK, I'll come back to my original patches to improve 
> PIC/PLT support.
> 

I think the cleanest way of doing this is to encode each entry as a
tupple -- the bit pattern and a type marker, then we have macros
THUMB16_INSN() THUMB32_INSN(), ARM_INSN() and DATA_WORD() which are used
to initialize the arrays.  You then get an instruction block that looks
like:

#define THUMB16_INSN(X) {X, 1}
#define THUMB32_INSN(X) {X, 2}
#define ARM_INSN(X)     {X, 3}
#define DATA_WORD(X)    {X, 4}

struct insn_sequence
{
  bfd_vma  data;
  uint8_t  type;
};

 static const insn_sequence elf32_arm_stub_long_branch_thumb_only[] =
   {
	THUMB16_INSN(0xb540),  /* push { r6, lr} */
	THUMB16_INSN(0x4e02),  /* ldr r6, [pc, #8] */
	DATA_WORD(0)
   };

Then there is some common code that takes such a block and copies it out
to memory, setting any appropriate mapping symbols as appropriate.

The encoding is slightly expensive (you only need 2 bits to represent
the 4 types of data that can exist in the array, which wastes at least
30 bits for every instruction in the list, but there aren't that many
stubs and the risk of errors over having separate arrays for the
instructions and the map is significantly higher.

R.



More information about the Binutils mailing list