зеркало из https://github.com/mozilla/gecko-dev.git
Bug 898998 - Turn BL into BLX when doing thumb call relocations and the target is ARM. r=nfroyd
This commit is contained in:
Родитель
378ab5094e
Коммит
8a3516b805
|
@ -240,9 +240,26 @@ private:
|
|||
unsigned int word0 = addend & 0xffff,
|
||||
word1 = addend >> 16;
|
||||
|
||||
if (((word0 & 0xf800) != 0xf000) || ((word1 & 0x9000) != 0x9000))
|
||||
/* Encoding T4 of B.W is 10x1 ; Encoding T1 of BL is 11x1. */
|
||||
unsigned int type = (word1 & 0xd000) >> 12;
|
||||
if (((word0 & 0xf800) != 0xf000) || ((type & 0x9) != 0x9))
|
||||
throw std::runtime_error("R_ARM_THM_JUMP24/R_ARM_THM_CALL relocation only supported for B.W <label> and BL <label>");
|
||||
|
||||
/* When the target address points to ARM code, switch a BL to a
|
||||
* BLX. This however can't be done with a B.W without adding a
|
||||
* trampoline, which is not supported as of now. */
|
||||
if ((addr & 0x1) == 0) {
|
||||
if (type == 0x9)
|
||||
throw std::runtime_error("R_ARM_THM_JUMP24/R_ARM_THM_CALL relocation only supported for BL <label> when label points to ARM code");
|
||||
/* The address of the target is always relative to a 4-bytes
|
||||
* aligned address, so if the address of the BL instruction is
|
||||
* not 4-bytes aligned, adjust for it. */
|
||||
if ((base_addr + offset) & 0x2)
|
||||
tmp += 2;
|
||||
/* Encoding T2 of BLX is 11x0. */
|
||||
type = 0xc;
|
||||
}
|
||||
|
||||
unsigned int s = (word0 & (1 << 10)) >> 10;
|
||||
unsigned int j1 = (word1 & (1 << 13)) >> 13;
|
||||
unsigned int j2 = (word1 & (1 << 11)) >> 11;
|
||||
|
@ -256,7 +273,7 @@ private:
|
|||
j2 = ((tmp & (1 << 22)) >> 22) ^ !s;
|
||||
|
||||
return 0xf000 | (s << 10) | ((tmp & (0x3ff << 12)) >> 12) |
|
||||
((word1 & 0xd000) << 16) | (j1 << 29) | (j2 << 27) | ((tmp & 0xffe) << 15);
|
||||
(type << 28) | (j1 << 29) | (j2 << 27) | ((tmp & 0xffe) << 15);
|
||||
}
|
||||
};
|
||||
|
||||
|
|
|
@ -22,7 +22,7 @@ extern __attribute__((visibility("hidden"))) void original_init(int argc, char *
|
|||
extern __attribute__((visibility("hidden"))) Elf32_Rel relhack[];
|
||||
extern __attribute__((visibility("hidden"))) Elf_Ehdr elf_header;
|
||||
|
||||
void init(int argc, char **argv, char **env)
|
||||
int init(int argc, char **argv, char **env)
|
||||
{
|
||||
Elf32_Rel *rel;
|
||||
Elf_Addr *ptr, *start;
|
||||
|
@ -35,4 +35,7 @@ void init(int argc, char **argv, char **env)
|
|||
#ifndef NOINIT
|
||||
original_init(argc, argv, env);
|
||||
#endif
|
||||
// Ensure there is no tail-call optimization, avoiding the use of the
|
||||
// B.W instruction in Thumb for the call above.
|
||||
return 0;
|
||||
}
|
||||
|
|
Загрузка…
Ссылка в новой задаче