Skip to content

Commit 654dbc1

Browse files
authored
add REL.rel26 fixup type (dlang#23138)
1 parent a8835be commit 654dbc1

5 files changed

Lines changed: 35 additions & 11 deletions

File tree

compiler/src/dmd/backend/arm/cod1.d

Lines changed: 4 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1677,6 +1677,9 @@ void callclib(ref CGstate cg, ref CodeBuilder cdb, elem* e, uint clib, ref regm_
16771677
}
16781678

16791679
cdb.gencs1(INSTR.branch_imm(1,0),0,FL.func,s); // CALL s
1680+
code_orflag(cdb.last(), CFselfrel26);
1681+
1682+
16801683
if (nalign)
16811684
cod3_stackadj(cdb, -nalign);
16821685
cg.calledafunc = 1;
@@ -2259,7 +2262,7 @@ private void funccall(ref CGstate cg, ref CodeBuilder cdb, elem* e, uint numpara
22592262
assert(0); // TODO AArch64
22602263
}
22612264
}
2262-
code_orflag(cdbe.last(), CFselfrel | CFoff);
2265+
code_orflag(cdbe.last(), CFselfrel | CFoff | CFselfrel26);
22632266
}
22642267
}
22652268
else

compiler/src/dmd/backend/arm/cod3.d

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1817,6 +1817,12 @@ void assignaddrc(ref CGstate cg, code* c)
18171817
printf("FL: %-8s ", fl_str(c.IFL1));
18181818
disassemble(ins);
18191819
}
1820+
1821+
static if (0)
1822+
if ((ins & 0x9F00_0000) == 0x9000_0000)
1823+
{ printf("ADRP: "); disassemble(ins);
1824+
if (code_next(c)) { printf(" "); disassemble(code_next(c).Iop); } else printf("fail\n");
1825+
}
18201826
switch (c.IFL1)
18211827
{
18221828
case FL.data:

compiler/src/dmd/backend/cdef.d

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -389,9 +389,10 @@ enum REL : ubyte
389389
{
390390
address = 1, // complete address
391391
rel = 2, // relative to location to be fixed up
392-
add = 3, // add in 12 extra bits of relocation (ARCH64)
392+
add = 3, // add in 12 extra bits of relocation (AArch64)
393393
seg = 4, // 2 byte section
394394
address32 = 5, // 4 byte offset
395+
rel26 = 6, // 26 bit signed offset for BL (AArch64)
395396
}
396397

397398
alias config_flags_t = uint;

compiler/src/dmd/backend/machobj.d

Lines changed: 22 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -896,19 +896,22 @@ void MachObj_term(const(char)[] objfilename)
896896
Relocation* rend = cast(Relocation*)(pseg.SDrel.buf + pseg.SDrel.length());
897897
for (; r != rend; r++)
898898
{ Symbol* s = r.targsym;
899-
const(char)* rs = r.rtype == REL.address ? "addr" : // 32 bit address
900-
r.rtype == REL.add ? "add" :
901-
"rel";
902-
//printf("%d:x%04llx : targseg %d targsym %s REL%s flag %d\n", seg, r.offset, r.targseg, s ? s.Sident.ptr : "0", rs, r.flag);
903-
// bool isPersonality = strcmp(s.Sident.ptr, "__dmd_personality_v0") == 0 ||
904-
// strcmp(s.Sident.ptr, "___dmd_personality_v0") == 0; // temporary scaffolding
905-
//symbol_print(*s);
899+
const(char)* rs = r.rtype == REL.address ? "address" : // 32 bit address
900+
r.rtype == REL.add ? "add" :
901+
r.rtype == REL.rel26 ? "rel26" :
902+
"rel";
906903
relocation_info rel;
907904
scattered_relocation_info srel;
908905
if (machobj.AArch64)
909906
{
910907
if (s)
911908
{
909+
//printf("s.Sident: %s\n", s.Sident.ptr);
910+
bool isPersonality = strcmp(s.Sident.ptr, "_D6object8TypeInfo8opEqualsMxFNbNfxCQBbZb") == 0;
911+
if (isPersonality)
912+
{ symbol_print(*s);
913+
printf("%d:x%04llx isCode %x : targseg %d targsym %s REL%s flag %d\n", seg, r.offset, pseg.isCode(), r.targseg, s ? s.Sident.ptr : "0", rs, r.flag);
914+
}
912915
if (r.flag == 1) // emit SUBTRACTOR/UNSIGNED pair
913916
{
914917
//printf("rel1\n");
@@ -944,8 +947,9 @@ void MachObj_term(const(char)[] objfilename)
944947
case SC.comdat:
945948
case SC.comdef:
946949
case SC.static_:
947-
if (s.Sfl == FL.func && r.rtype == REL.rel)
950+
if (/*s.Sfl == FL.func &&*/ r.rtype == REL.rel26)
948951
{
952+
//printf("BRANCHY26\n");
949953
rel.r_type = ARM64_RELOC_BRANCHY26;
950954
rel.r_pcrel = 1;
951955
}
@@ -973,6 +977,8 @@ void MachObj_term(const(char)[] objfilename)
973977
break;
974978

975979
case SC.global:
980+
if (/*s.Sfl == FL.func &&*/ r.rtype == REL.rel26)
981+
goto case SC.extern_;
976982
//rel.r_type = r.rtype == REL.add ? ARM64_RELOC_GOT_LOAD_PAGEOFF12 : ARM64_RELOC_GOT_LOAD_PAGE21;
977983
rel.r_type = r.rtype == REL.add ? ARM64_RELOC_PAGEOFF12 : ARM64_RELOC_PAGE21;
978984
if (s.Sfl == FL.tlsdata || s.Sfl == FL.data && (s.ty() & mTYLINK) == mTYthread)
@@ -989,6 +995,8 @@ void MachObj_term(const(char)[] objfilename)
989995
break;
990996

991997
case SC.locstat:
998+
if (/*s.Sfl == FL.func &&*/ r.rtype == REL.rel26)
999+
goto case SC.extern_;
9921000
assert(s.Sfl != FL.tlsdata);
9931001
rel.r_type = r.rtype == REL.add ? ARM64_RELOC_PAGEOFF12 : ARM64_RELOC_PAGE21;
9941002
rel.r_pcrel = r.rtype == REL.add ? 0 : 1;
@@ -2800,6 +2808,7 @@ void MachObj_reftocodeseg(int seg,targ_size_t offset,targ_size_t val)
28002808
* CFoff: get offset
28012809
* CFpc32: [RIP] addressing, val is 0, -1, -2 or -4
28022810
* CFoffset64: 8 byte offset for 64 bit builds
2811+
* CFselfrel26: 26 bit offset for BL function calls
28032812
* Returns:
28042813
* number of bytes in reference (4 or 8)
28052814
*/
@@ -3002,7 +3011,11 @@ int MachObj_reftoidentAArch64(int seg, targ_size_t offset, Symbol* s, targ_size_
30023011
int v = 0;
30033012
if (flags & CFpc32)
30043013
v = cast(int)val;
3005-
if (flags & CFselfrel)
3014+
if (flags & CFselfrel26)
3015+
{
3016+
MachObj_addrel(seg, offset, s, 0, REL.rel26, v);
3017+
}
3018+
else if (flags & CFselfrel)
30063019
{
30073020
MachObj_addrel(seg, offset, s, 0, REL.rel, v);
30083021
}

compiler/src/dmd/backend/x86/code_x86.d

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -298,6 +298,7 @@ enum
298298
// AArch64
299299
CFadd = 0x1000_0000,
300300
CFfixup = 0x2000_0000, // needs a fixup
301+
CFselfrel26 = 0x4000_0000, // 26 bit self-relative fixup for BL instruction (BRANCHY26)
301302
}
302303

303304
struct code

0 commit comments

Comments
 (0)