annotate toolchain/binutils-patches/elf32-arm.patch @ 83:ebe258a85813

toolchain: binutils patch to emit the "short" form of Thumb->ARM call veneers
author Michael Spacefalcon <msokolov@ivan.Harhan.ORG>
date Mon, 19 Aug 2013 05:16:34 +0000
parents
children
Ignore whitespace changes - Everywhere: Within whitespace: At end of lines:
rev   line source
83
ebe258a85813 toolchain: binutils patch to emit the "short" form of Thumb->ARM call veneers
Michael Spacefalcon <msokolov@ivan.Harhan.ORG>
parents:
diff changeset
1 # The present patch to the ARM ELF linking code in binutils (made against
ebe258a85813 toolchain: binutils patch to emit the "short" form of Thumb->ARM call veneers
Michael Spacefalcon <msokolov@ivan.Harhan.ORG>
parents:
diff changeset
2 # binutils-2.21.1a) is a hack that affects the generation of Thumb->ARM
ebe258a85813 toolchain: binutils patch to emit the "short" form of Thumb->ARM call veneers
Michael Spacefalcon <msokolov@ivan.Harhan.ORG>
parents:
diff changeset
3 # call veneers. The binutils linker can make these veneers in two forms:
ebe258a85813 toolchain: binutils patch to emit the "short" form of Thumb->ARM call veneers
Michael Spacefalcon <msokolov@ivan.Harhan.ORG>
parents:
diff changeset
4 #
ebe258a85813 toolchain: binutils patch to emit the "short" form of Thumb->ARM call veneers
Michael Spacefalcon <msokolov@ivan.Harhan.ORG>
parents:
diff changeset
5 # "Short" "Long"
ebe258a85813 toolchain: binutils patch to emit the "short" form of Thumb->ARM call veneers
Michael Spacefalcon <msokolov@ivan.Harhan.ORG>
parents:
diff changeset
6 # (16-bit) bx pc (16-bit) bx pc
ebe258a85813 toolchain: binutils patch to emit the "short" form of Thumb->ARM call veneers
Michael Spacefalcon <msokolov@ivan.Harhan.ORG>
parents:
diff changeset
7 # (16-bit) nop (16-bit) nop
ebe258a85813 toolchain: binutils patch to emit the "short" form of Thumb->ARM call veneers
Michael Spacefalcon <msokolov@ivan.Harhan.ORG>
parents:
diff changeset
8 # (32-bit) b dest (32-bit) ldr pc, [pc, #-4]
ebe258a85813 toolchain: binutils patch to emit the "short" form of Thumb->ARM call veneers
Michael Spacefalcon <msokolov@ivan.Harhan.ORG>
parents:
diff changeset
9 # (32-bit) .long target
ebe258a85813 toolchain: binutils patch to emit the "short" form of Thumb->ARM call veneers
Michael Spacefalcon <msokolov@ivan.Harhan.ORG>
parents:
diff changeset
10 #
ebe258a85813 toolchain: binutils patch to emit the "short" form of Thumb->ARM call veneers
Michael Spacefalcon <msokolov@ivan.Harhan.ORG>
parents:
diff changeset
11 # For code that's going to run on the Calypso ARM7 processor, the
ebe258a85813 toolchain: binutils patch to emit the "short" form of Thumb->ARM call veneers
Michael Spacefalcon <msokolov@ivan.Harhan.ORG>
parents:
diff changeset
12 # "short" form is the one we want: because of the way the address space
ebe258a85813 toolchain: binutils patch to emit the "short" form of Thumb->ARM call veneers
Michael Spacefalcon <msokolov@ivan.Harhan.ORG>
parents:
diff changeset
13 # is laid out, the range of an ARM branch instruction will always be
ebe258a85813 toolchain: binutils patch to emit the "short" form of Thumb->ARM call veneers
Michael Spacefalcon <msokolov@ivan.Harhan.ORG>
parents:
diff changeset
14 # sufficient for us, whereas the long version is more costly in terms
ebe258a85813 toolchain: binutils patch to emit the "short" form of Thumb->ARM call veneers
Michael Spacefalcon <msokolov@ivan.Harhan.ORG>
parents:
diff changeset
15 # of the number of cycles required, especially when executing from
ebe258a85813 toolchain: binutils patch to emit the "short" form of Thumb->ARM call veneers
Michael Spacefalcon <msokolov@ivan.Harhan.ORG>
parents:
diff changeset
16 # external memory.
ebe258a85813 toolchain: binutils patch to emit the "short" form of Thumb->ARM call veneers
Michael Spacefalcon <msokolov@ivan.Harhan.ORG>
parents:
diff changeset
17 #
ebe258a85813 toolchain: binutils patch to emit the "short" form of Thumb->ARM call veneers
Michael Spacefalcon <msokolov@ivan.Harhan.ORG>
parents:
diff changeset
18 # Unfortunately, the code which decides between these two forms
ebe258a85813 toolchain: binutils patch to emit the "short" form of Thumb->ARM call veneers
Michael Spacefalcon <msokolov@ivan.Harhan.ORG>
parents:
diff changeset
19 # (located in the arm_type_of_stub() function in bfd/elf32-arm.c)
ebe258a85813 toolchain: binutils patch to emit the "short" form of Thumb->ARM call veneers
Michael Spacefalcon <msokolov@ivan.Harhan.ORG>
parents:
diff changeset
20 # is broken. The original code (which you can see below in the
ebe258a85813 toolchain: binutils patch to emit the "short" form of Thumb->ARM call veneers
Michael Spacefalcon <msokolov@ivan.Harhan.ORG>
parents:
diff changeset
21 # "before" part of the patch hunk) exhibits two problems:
ebe258a85813 toolchain: binutils patch to emit the "short" form of Thumb->ARM call veneers
Michael Spacefalcon <msokolov@ivan.Harhan.ORG>
parents:
diff changeset
22 #
ebe258a85813 toolchain: binutils patch to emit the "short" form of Thumb->ARM call veneers
Michael Spacefalcon <msokolov@ivan.Harhan.ORG>
parents:
diff changeset
23 # 1. The distance that matters here is not from the original
ebe258a85813 toolchain: binutils patch to emit the "short" form of Thumb->ARM call veneers
Michael Spacefalcon <msokolov@ivan.Harhan.ORG>
parents:
diff changeset
24 # call point to the destination, but from the stub to
ebe258a85813 toolchain: binutils patch to emit the "short" form of Thumb->ARM call veneers
Michael Spacefalcon <msokolov@ivan.Harhan.ORG>
parents:
diff changeset
25 # the destination - and in this function we don't know
ebe258a85813 toolchain: binutils patch to emit the "short" form of Thumb->ARM call veneers
Michael Spacefalcon <msokolov@ivan.Harhan.ORG>
parents:
diff changeset
26 # where the stub will end up.
ebe258a85813 toolchain: binutils patch to emit the "short" form of Thumb->ARM call veneers
Michael Spacefalcon <msokolov@ivan.Harhan.ORG>
parents:
diff changeset
27 #
ebe258a85813 toolchain: binutils patch to emit the "short" form of Thumb->ARM call veneers
Michael Spacefalcon <msokolov@ivan.Harhan.ORG>
parents:
diff changeset
28 # 2. Because it's an ARM branch, the limits should be
ebe258a85813 toolchain: binutils patch to emit the "short" form of Thumb->ARM call veneers
Michael Spacefalcon <msokolov@ivan.Harhan.ORG>
parents:
diff changeset
29 # ARM_MAX_[BF]WD_BRANCH_OFFSET, not the THM_ ones.
ebe258a85813 toolchain: binutils patch to emit the "short" form of Thumb->ARM call veneers
Michael Spacefalcon <msokolov@ivan.Harhan.ORG>
parents:
diff changeset
30 #
ebe258a85813 toolchain: binutils patch to emit the "short" form of Thumb->ARM call veneers
Michael Spacefalcon <msokolov@ivan.Harhan.ORG>
parents:
diff changeset
31 # The 2nd problem would be trivial to fix, but the 1st one
ebe258a85813 toolchain: binutils patch to emit the "short" form of Thumb->ARM call veneers
Michael Spacefalcon <msokolov@ivan.Harhan.ORG>
parents:
diff changeset
32 # much less so: this function doesn't know where the stub
ebe258a85813 toolchain: binutils patch to emit the "short" form of Thumb->ARM call veneers
Michael Spacefalcon <msokolov@ivan.Harhan.ORG>
parents:
diff changeset
33 # will end up, and considering that for the present purpose
ebe258a85813 toolchain: binutils patch to emit the "short" form of Thumb->ARM call veneers
Michael Spacefalcon <msokolov@ivan.Harhan.ORG>
parents:
diff changeset
34 # of the FreeCalypso project always emitting the "short"
ebe258a85813 toolchain: binutils patch to emit the "short" form of Thumb->ARM call veneers
Michael Spacefalcon <msokolov@ivan.Harhan.ORG>
parents:
diff changeset
35 # version would be perfect, there is no justification for
ebe258a85813 toolchain: binutils patch to emit the "short" form of Thumb->ARM call veneers
Michael Spacefalcon <msokolov@ivan.Harhan.ORG>
parents:
diff changeset
36 # expending the time and effort to restructure the linker
ebe258a85813 toolchain: binutils patch to emit the "short" form of Thumb->ARM call veneers
Michael Spacefalcon <msokolov@ivan.Harhan.ORG>
parents:
diff changeset
37 # to do the proper relaxation for the case at hand.
ebe258a85813 toolchain: binutils patch to emit the "short" form of Thumb->ARM call veneers
Michael Spacefalcon <msokolov@ivan.Harhan.ORG>
parents:
diff changeset
38 #
ebe258a85813 toolchain: binutils patch to emit the "short" form of Thumb->ARM call veneers
Michael Spacefalcon <msokolov@ivan.Harhan.ORG>
parents:
diff changeset
39 # Therefore, the patch we apply is a hack: we simply force the
ebe258a85813 toolchain: binutils patch to emit the "short" form of Thumb->ARM call veneers
Michael Spacefalcon <msokolov@ivan.Harhan.ORG>
parents:
diff changeset
40 # use of the "short" form unconditionally.
ebe258a85813 toolchain: binutils patch to emit the "short" form of Thumb->ARM call veneers
Michael Spacefalcon <msokolov@ivan.Harhan.ORG>
parents:
diff changeset
41
ebe258a85813 toolchain: binutils patch to emit the "short" form of Thumb->ARM call veneers
Michael Spacefalcon <msokolov@ivan.Harhan.ORG>
parents:
diff changeset
42 *** elf32-arm.c Wed May 11 07:29:12 2011
ebe258a85813 toolchain: binutils patch to emit the "short" form of Thumb->ARM call veneers
Michael Spacefalcon <msokolov@ivan.Harhan.ORG>
parents:
diff changeset
43 --- elf32-arm-patched.c Mon Aug 19 03:24:38 2013
ebe258a85813 toolchain: binutils patch to emit the "short" form of Thumb->ARM call veneers
Michael Spacefalcon <msokolov@ivan.Harhan.ORG>
parents:
diff changeset
44 ***************
ebe258a85813 toolchain: binutils patch to emit the "short" form of Thumb->ARM call veneers
Michael Spacefalcon <msokolov@ivan.Harhan.ORG>
parents:
diff changeset
45 *** 3203,3211 ****
ebe258a85813 toolchain: binutils patch to emit the "short" form of Thumb->ARM call veneers
Michael Spacefalcon <msokolov@ivan.Harhan.ORG>
parents:
diff changeset
46 : arm_stub_long_branch_v4t_thumb_arm);
ebe258a85813 toolchain: binutils patch to emit the "short" form of Thumb->ARM call veneers
Michael Spacefalcon <msokolov@ivan.Harhan.ORG>
parents:
diff changeset
47
ebe258a85813 toolchain: binutils patch to emit the "short" form of Thumb->ARM call veneers
Michael Spacefalcon <msokolov@ivan.Harhan.ORG>
parents:
diff changeset
48 /* Handle v4t short branches. */
ebe258a85813 toolchain: binutils patch to emit the "short" form of Thumb->ARM call veneers
Michael Spacefalcon <msokolov@ivan.Harhan.ORG>
parents:
diff changeset
49 ! if ((stub_type == arm_stub_long_branch_v4t_thumb_arm)
ebe258a85813 toolchain: binutils patch to emit the "short" form of Thumb->ARM call veneers
Michael Spacefalcon <msokolov@ivan.Harhan.ORG>
parents:
diff changeset
50 ! && (branch_offset <= THM_MAX_FWD_BRANCH_OFFSET)
ebe258a85813 toolchain: binutils patch to emit the "short" form of Thumb->ARM call veneers
Michael Spacefalcon <msokolov@ivan.Harhan.ORG>
parents:
diff changeset
51 ! && (branch_offset >= THM_MAX_BWD_BRANCH_OFFSET))
ebe258a85813 toolchain: binutils patch to emit the "short" form of Thumb->ARM call veneers
Michael Spacefalcon <msokolov@ivan.Harhan.ORG>
parents:
diff changeset
52 stub_type = arm_stub_short_branch_v4t_thumb_arm;
ebe258a85813 toolchain: binutils patch to emit the "short" form of Thumb->ARM call veneers
Michael Spacefalcon <msokolov@ivan.Harhan.ORG>
parents:
diff changeset
53 }
ebe258a85813 toolchain: binutils patch to emit the "short" form of Thumb->ARM call veneers
Michael Spacefalcon <msokolov@ivan.Harhan.ORG>
parents:
diff changeset
54 }
ebe258a85813 toolchain: binutils patch to emit the "short" form of Thumb->ARM call veneers
Michael Spacefalcon <msokolov@ivan.Harhan.ORG>
parents:
diff changeset
55 --- 3203,3209 ----
ebe258a85813 toolchain: binutils patch to emit the "short" form of Thumb->ARM call veneers
Michael Spacefalcon <msokolov@ivan.Harhan.ORG>
parents:
diff changeset
56 : arm_stub_long_branch_v4t_thumb_arm);
ebe258a85813 toolchain: binutils patch to emit the "short" form of Thumb->ARM call veneers
Michael Spacefalcon <msokolov@ivan.Harhan.ORG>
parents:
diff changeset
57
ebe258a85813 toolchain: binutils patch to emit the "short" form of Thumb->ARM call veneers
Michael Spacefalcon <msokolov@ivan.Harhan.ORG>
parents:
diff changeset
58 /* Handle v4t short branches. */
ebe258a85813 toolchain: binutils patch to emit the "short" form of Thumb->ARM call veneers
Michael Spacefalcon <msokolov@ivan.Harhan.ORG>
parents:
diff changeset
59 ! if (stub_type == arm_stub_long_branch_v4t_thumb_arm)
ebe258a85813 toolchain: binutils patch to emit the "short" form of Thumb->ARM call veneers
Michael Spacefalcon <msokolov@ivan.Harhan.ORG>
parents:
diff changeset
60 stub_type = arm_stub_short_branch_v4t_thumb_arm;
ebe258a85813 toolchain: binutils patch to emit the "short" form of Thumb->ARM call veneers
Michael Spacefalcon <msokolov@ivan.Harhan.ORG>
parents:
diff changeset
61 }
ebe258a85813 toolchain: binutils patch to emit the "short" form of Thumb->ARM call veneers
Michael Spacefalcon <msokolov@ivan.Harhan.ORG>
parents:
diff changeset
62 }