ソースを参照

Move some of the local reloc calculation out of aasmcpu, and into COFF and ELF writers.

git-svn-id: trunk@32867 -
Jeppe Johansen 9 年 前
コミット
0251263234
3 ファイル変更34 行追加14 行削除
  1. 8 9
      compiler/arm/aasmcpu.pas
  2. 17 4
      compiler/ogcoff.pas
  3. 9 1
      compiler/ogelf.pas

+ 8 - 9
compiler/arm/aasmcpu.pas

@@ -2974,16 +2974,15 @@ implementation
               else
                 begin
                   currsym:=objdata.symbolref(oper[0]^.ref^.symbol);
-                  if (currsym.bind<>AB_LOCAL) or (currsym.objsection<>objdata.CurrObjSec) then
-                    begin
-                      if (opcode<>A_BL) or (condition<>C_None) then
-                        objdata.writereloc(oper[0]^.ref^.offset,0,currsym,RELOC_RELATIVE_24)
-                      else
-                        objdata.writereloc(oper[0]^.ref^.offset,0,currsym,RELOC_RELATIVE_CALL);
-                      bytes:=bytes or $fffffe; // TODO: Not sure this is right, but it matches the output of gas
-                    end
+
+                  bytes:=bytes or (((oper[0]^.ref^.offset-8) shr 2) and $ffffff);
+
+                  if (opcode<>A_BL) or (condition<>C_None) then
+                    objdata.writereloc(bytes,4,currsym,RELOC_RELATIVE_24)
                   else
-                    bytes:=bytes or (((currsym.offset-insoffset-8) shr 2) and $ffffff);
+                    objdata.writereloc(bytes,4,currsym,RELOC_RELATIVE_CALL);
+
+                  exit;
                 end;
             end;
           #$02:

+ 17 - 4
compiler/ogcoff.pas

@@ -914,7 +914,8 @@ const pemagic : array[0..3] of byte = (
                     inc(address,relocval);
                   end;
 {$ifdef arm}
-                RELOC_RELATIVE_24:
+                RELOC_RELATIVE_24,
+                RELOC_RELATIVE_CALL:
                   begin
                     addend:=sarlongint(((address and $ffffff) shl 8),6); // Sign-extend while shifting left twice
                     relocval:=longint(relocval - objsec.mempos - objreloc.dataoffset + addend) shr 2;
@@ -923,7 +924,8 @@ const pemagic : array[0..3] of byte = (
                     if (relocval<>$3f) and (relocval<>0) then
                       internalerror(200606085);  { offset overflow }
                   end;
-                RELOC_RELATIVE_24_THUMB:
+                RELOC_RELATIVE_24_THUMB,
+                RELOC_RELATIVE_CALL_THUMB:
                   begin
                     addend:=sarlongint(((address and $ffffff) shl 8),6); // Sign-extend while shifting left twice, the assembler never sets the H bit
                     relocval:=longint(relocval - objsec.mempos - objreloc.dataoffset + addend) shr 1;
@@ -1119,6 +1121,13 @@ const pemagic : array[0..3] of byte = (
                       //inc(data,symaddr-len-CurrObjSec.Size);
                       data:=data+symaddr-len-CurrObjSec.Size;
                     end;
+{$ifdef ARM}
+                  RELOC_RELATIVE_24,
+                  RELOC_RELATIVE_CALL:
+                    begin
+                      data:=(data and $ff000000) or (((((data and $ffffff) shl 2)+(symaddr-CurrObjSec.Size)) shr 2) and $FFFFFF); // TODO: Check overflow
+                    end;
+{$endif ARM}
                   RELOC_RVA,
                   RELOC_SECREL32 :
                     begin
@@ -1298,8 +1307,10 @@ const pemagic : array[0..3] of byte = (
                 rel.reloctype:=IMAGE_REL_ARM_SECREL;
               RELOC_RELATIVE_24 :
                 rel.reloctype:=IMAGE_REL_ARM_BRANCH24;
-              RELOC_RELATIVE_24_THUMB:
+              RELOC_RELATIVE_CALL :
                 rel.reloctype:=IMAGE_REL_ARM_BLX24;
+              RELOC_RELATIVE_24_THUMB:
+                rel.reloctype:=IMAGE_REL_ARM_BLX23T;
 {$endif arm}
 {$ifdef i386}
               RELOC_RELATIVE :
@@ -1616,9 +1627,11 @@ const pemagic : array[0..3] of byte = (
                rel_type:=RELOC_RVA;
              IMAGE_REL_ARM_BRANCH24:
                rel_type:=RELOC_RELATIVE_24;
+             IMAGE_REL_ARM_BLX24:
+               rel_type:=RELOC_RELATIVE_CALL;
              IMAGE_REL_ARM_SECREL:
                rel_type:=RELOC_SECREL32;
-             IMAGE_REL_ARM_BLX24:
+             IMAGE_REL_ARM_BLX23T:
                rel_type:=RELOC_RELATIVE_24_THUMB;
 {$endif arm}
 {$ifdef i386}

+ 9 - 1
compiler/ogelf.pas

@@ -858,8 +858,16 @@ implementation
            symaddr:=p.address;
            { Local ObjSymbols can be resolved already or need a section reloc }
            if (p.bind=AB_LOCAL) and
-              (reltype in [RELOC_RELATIVE,RELOC_ABSOLUTE{$ifdef x86_64},RELOC_ABSOLUTE32{$endif x86_64}]) then
+              (reltype in [RELOC_RELATIVE,RELOC_ABSOLUTE{$ifdef x86_64},RELOC_ABSOLUTE32{$endif x86_64}{$ifdef arm},RELOC_RELATIVE_24,RELOC_RELATIVE_CALL{$endif arm}]) then
              begin
+{$ifdef ARM}
+               if (reltype in [RELOC_RELATIVE_24,RELOC_RELATIVE_CALL]) and
+                  (p.objsection=CurrObjSec) then
+                 begin
+                   data:=(data and $ff000000) or (((((data and $ffffff) shl 2)+(symaddr-CurrObjSec.Size)) shr 2) and $FFFFFF); // TODO: Check overflow
+                 end
+               else
+{$endif ARM}
                { For a reltype relocation in the same section the
                  value can be calculated }
                if (p.objsection=CurrObjSec) and