FreeCalypso > hg > freecalypso-sw
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 |
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 } |