FreeCalypso > hg > freecalypso-sw
annotate toolchain/binutils-patches/elf32-arm.patch @ 992:a7b0b426f9ca
target-utils: boot ROM UART autodetection revamped
The new implementation should work with both the familiar Calypso C035
boot ROM version found in our regular targets as well as the older
Calypso F741979B version found on the vintage D-Sample board.
author | Mychaela Falconia <falcon@ivan.Harhan.ORG> |
---|---|
date | Wed, 30 Dec 2015 21:28:41 +0000 |
parents | ebe258a85813 |
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 } |