FreeCalypso > hg > freecalypso-sw
view toolchain/binutils-patches/elf32-arm.patch @ 196:3daa8ebbe74d
pirexplore: a bit of refactoring
author | Michael Spacefalcon <msokolov@ivan.Harhan.ORG> |
---|---|
date | Sat, 14 Dec 2013 07:55:22 +0000 |
parents | ebe258a85813 |
children |
line wrap: on
line source
# The present patch to the ARM ELF linking code in binutils (made against # binutils-2.21.1a) is a hack that affects the generation of Thumb->ARM # call veneers. The binutils linker can make these veneers in two forms: # # "Short" "Long" # (16-bit) bx pc (16-bit) bx pc # (16-bit) nop (16-bit) nop # (32-bit) b dest (32-bit) ldr pc, [pc, #-4] # (32-bit) .long target # # For code that's going to run on the Calypso ARM7 processor, the # "short" form is the one we want: because of the way the address space # is laid out, the range of an ARM branch instruction will always be # sufficient for us, whereas the long version is more costly in terms # of the number of cycles required, especially when executing from # external memory. # # Unfortunately, the code which decides between these two forms # (located in the arm_type_of_stub() function in bfd/elf32-arm.c) # is broken. The original code (which you can see below in the # "before" part of the patch hunk) exhibits two problems: # # 1. The distance that matters here is not from the original # call point to the destination, but from the stub to # the destination - and in this function we don't know # where the stub will end up. # # 2. Because it's an ARM branch, the limits should be # ARM_MAX_[BF]WD_BRANCH_OFFSET, not the THM_ ones. # # The 2nd problem would be trivial to fix, but the 1st one # much less so: this function doesn't know where the stub # will end up, and considering that for the present purpose # of the FreeCalypso project always emitting the "short" # version would be perfect, there is no justification for # expending the time and effort to restructure the linker # to do the proper relaxation for the case at hand. # # Therefore, the patch we apply is a hack: we simply force the # use of the "short" form unconditionally. *** elf32-arm.c Wed May 11 07:29:12 2011 --- elf32-arm-patched.c Mon Aug 19 03:24:38 2013 *************** *** 3203,3211 **** : arm_stub_long_branch_v4t_thumb_arm); /* Handle v4t short branches. */ ! if ((stub_type == arm_stub_long_branch_v4t_thumb_arm) ! && (branch_offset <= THM_MAX_FWD_BRANCH_OFFSET) ! && (branch_offset >= THM_MAX_BWD_BRANCH_OFFSET)) stub_type = arm_stub_short_branch_v4t_thumb_arm; } } --- 3203,3209 ---- : arm_stub_long_branch_v4t_thumb_arm); /* Handle v4t short branches. */ ! if (stub_type == arm_stub_long_branch_v4t_thumb_arm) stub_type = arm_stub_short_branch_v4t_thumb_arm; } }