|
@@ -561,6 +561,7 @@ implementation
|
|
|
rotation:longint;
|
|
|
residual,g_n:longword;
|
|
|
curloc: aword;
|
|
|
+ bit_S,bit_I1,bit_I2: aint;
|
|
|
begin
|
|
|
data:=objsec.data;
|
|
|
for i:=0 to objsec.ObjRelocations.Count-1 do
|
|
@@ -660,7 +661,16 @@ implementation
|
|
|
2) when target is unresolved weak symbol, CALL must be changed to NOP,
|
|
|
while JUMP24 behavior is unspecified. }
|
|
|
tmp:=sarlongint((address and $00FFFFFF) shl 8,6);
|
|
|
- tmp:=tmp+relocval-curloc;
|
|
|
+ tmp:=tmp+relocval;
|
|
|
+ if odd(tmp) then { dest is Thumb? }
|
|
|
+ begin
|
|
|
+ if (reltyp=R_ARM_CALL) then
|
|
|
+ { change BL to BLX, dest bit 1 goes to instruction bit 24 }
|
|
|
+ address:=(address and $FE000000) or (((tmp-curloc) and 2) shl 23) or $10000000
|
|
|
+ else
|
|
|
+ InternalError(2014092001);
|
|
|
+ end;
|
|
|
+ tmp:=tmp-curloc;
|
|
|
// TODO: check overflow
|
|
|
address:=(address and $FF000000) or ((tmp and $3FFFFFE) shr 2);
|
|
|
end;
|
|
@@ -829,6 +839,38 @@ implementation
|
|
|
address:=address or (1 shl 23);
|
|
|
end;
|
|
|
|
|
|
+ R_ARM_THM_CALL:
|
|
|
+ begin
|
|
|
+ if (not ElfTarget.relocs_use_addend) then
|
|
|
+ begin
|
|
|
+ address:=((address and $ffff) shl 16) or word(address shr 16);
|
|
|
+ bit_S:=(address shr 26) and 1;
|
|
|
+ bit_I1:=(bit_S xor ((address shr 13) and 1)) xor 1;
|
|
|
+ bit_I2:=(bit_S xor ((address shr 11) and 1)) xor 1;
|
|
|
+ tmp:=((-bit_S) shl 24) or (bit_I1 shl 23) or (bit_I2 shl 22) or (((address shr 16) and $3ff) shl 12) or ((address and $7ff) shl 1);
|
|
|
+ end
|
|
|
+ else { TODO: must read the instruction anyway }
|
|
|
+ tmp:=address;
|
|
|
+ tmp:=tmp+relocval; { dest address }
|
|
|
+ if odd(tmp) then { if it's Thumb code, change possible BLX to BL }
|
|
|
+ address:=address or $1800;
|
|
|
+ tmp:=tmp-curloc; { now take PC-relative }
|
|
|
+ { TODO: overflow check, different limit for Thumb and Thumb-2 }
|
|
|
+
|
|
|
+ { now encode this mess back }
|
|
|
+ if (address and $5000)=$4000 then
|
|
|
+ tmp:=(tmp+2) and (not 3);
|
|
|
+
|
|
|
+ bit_S:=(tmp shr 31) and 1;
|
|
|
+ address:=(address and $F800D000) or
|
|
|
+ (bit_S shl 26) or
|
|
|
+ (((tmp shr 12) and $3ff) shl 16) or
|
|
|
+ ((tmp shr 1) and $7FF) or
|
|
|
+ ((((tmp shr 23) and 1) xor 1 xor bit_S) shl 13) or
|
|
|
+ ((((tmp shr 22) and 1) xor 1 xor bit_S) shl 11);
|
|
|
+ address:=((address and $ffff) shl 16) or word(address shr 16);
|
|
|
+ end;
|
|
|
+
|
|
|
R_ARM_TLS_IE32:
|
|
|
begin
|
|
|
relocval:=relocval-tlsseg.mempos+align_aword(TCB_SIZE,tlsseg.align);
|