@@ -39,6 +39,7 @@ import dmd.backend.oper;
3939import dmd.backend.symtab;
4040import dmd.backend.ty;
4141import dmd.backend.type;
42+ import dmd.backend.arm.instr;
4243
4344import dmd.common.outbuffer;
4445
@@ -3484,7 +3485,7 @@ void ElfObj_dehinfo(Symbol* scc)
34843485private void obj_rtinit ()
34853486{
34863487 if (config.target_cpu == TARGET_AArch64)
3487- return ;
3488+ return obj_rtinit_aarch64 () ;
34883489
34893490 // section start/stop symbols are defined by the linker (https://www.airs.com/blog/archives/56)
34903491 // make the symbols hidden so that each DSO gets its own brackets
@@ -3844,6 +3845,173 @@ else
38443845 p.sh_size = cast (uint )Offset(groupseg);
38453846}
38463847
3848+ /* *********************************
3849+ * Same as obj_rtinit() but for AArch64
3850+ */
3851+ private void obj_rtinit_aarch64 ()
3852+ {
3853+ // section start/stop symbols are defined by the linker (https://www.airs.com/blog/archives/56)
3854+ // make the symbols hidden so that each DSO gets its own brackets
3855+ IDXSYM minfo_beg, minfo_end, dso_rec;
3856+
3857+ IDXSYM deh_beg, deh_end;
3858+
3859+ {
3860+ // needs to be writeable for PIC code, see Bugzilla 13117
3861+ const shf_flags = SHF_ALLOC | SHF_WRITE ;
3862+
3863+ if (config.exe & (EX_OPENBSD | EX_OPENBSD64 ))
3864+ {
3865+ const namidx3 = ElfObj_addstr(&elfobj.symtab_strings," __start_deh" );
3866+ deh_beg = elf_addsym(namidx3, 0 , 0 , STT_NOTYPE , STB_GLOBAL , SHN_UNDEF , STV_HIDDEN );
3867+
3868+ ElfObj_getsegment(" deh" , null , SHT_PROGBITS , shf_flags, _tysize[TYnptr]);
3869+
3870+ const namidx4 = ElfObj_addstr(&elfobj.symtab_strings," __stop_deh" );
3871+ deh_end = elf_addsym(namidx4, 0 , 0 , STT_NOTYPE , STB_GLOBAL , SHN_UNDEF , STV_HIDDEN );
3872+ }
3873+
3874+ const namidx = ElfObj_addstr(&elfobj.symtab_strings," __start_minfo" );
3875+ minfo_beg = elf_addsym(namidx, 0 , 0 , STT_NOTYPE , STB_GLOBAL , SHN_UNDEF , STV_HIDDEN );
3876+
3877+ ElfObj_getsegment(" minfo" , null , SHT_PROGBITS , shf_flags, _tysize[TYnptr]);
3878+
3879+ const namidx2 = ElfObj_addstr(&elfobj.symtab_strings," __stop_minfo" );
3880+ minfo_end = elf_addsym(namidx2, 0 , 0 , STT_NOTYPE , STB_GLOBAL , SHN_UNDEF , STV_HIDDEN );
3881+ }
3882+
3883+ // Create a COMDAT section group
3884+ const groupseg = ElfObj_getsegment(" .group.d_dso" , null , SHT_GROUP , 0 , 0 );
3885+ SegData[groupseg].SDbuf.write32(GRP_COMDAT );
3886+
3887+ {
3888+ /*
3889+ * Create an instance of DSORec as global static data in the section .data.d_dso_rec
3890+ * It is writeable and allows the runtime to store information.
3891+ * Make it a COMDAT so there's only one per DSO.
3892+ *
3893+ * union DSO
3894+ * {
3895+ * size_t id;
3896+ * void* data;
3897+ * }
3898+ */
3899+ const seg = ElfObj_getsegment(" .data.d_dso_rec" , null , SHT_PROGBITS ,
3900+ SHF_ALLOC |SHF_WRITE |SHF_GROUP , _tysize[TYnptr]);
3901+ dso_rec = MAP_SEG2SYMIDX (seg);
3902+ ElfObj_bytes(seg, 0 , _tysize[TYnptr], null );
3903+ // add to section group
3904+ SegData[groupseg].SDbuf.write32(MAP_SEG2SECIDX (seg));
3905+
3906+ /*
3907+ * see druntime/src/rt/sections_elf_shared.d
3908+ * Create an instance of this on the stack:
3909+ *
3910+ * struct CompilerDSOData
3911+ * {
3912+ * size_t _version; // currently 1
3913+ * DSO* _slot; // used to store runtime data
3914+ * void* minfo_beg, minfo_end; // array of modules in this object file
3915+ * }
3916+ *
3917+ * Generate the function:
3918+ *
3919+ * void __dso_init()
3920+ * {
3921+ * CompilerDSOData dso;
3922+ * dso.minfo_end = &__stop_minfo;
3923+ * dso.minfo_beg = &__start_minfo;
3924+ * dso.slot = &d_dso_rec;
3925+ * dso.version = 1;
3926+ * _d_dso_registry(&dso);
3927+ * }
3928+ *
3929+ * and then put a pointer to that function in .init_array and in .fini_array so it'll
3930+ * get executed once upon loading and once upon unloading the DSO.
3931+ */
3932+ const codseg = ElfObj_getsegment(" .text.d_dso_init" , null , SHT_PROGBITS ,
3933+ SHF_ALLOC |SHF_EXECINSTR |SHF_GROUP , _tysize[TYnptr]);
3934+ // add to section group
3935+ SegData[groupseg].SDbuf.write32(MAP_SEG2SECIDX (codseg));
3936+
3937+ debug
3938+ {
3939+ // adds a local symbol (name) to the code, useful to set a breakpoint
3940+ const namidx = ElfObj_addstr(&elfobj.symtab_strings, " __d_dso_init" );
3941+ elf_addsym(namidx, 0 , 0 , STT_FUNC , STB_LOCAL , MAP_SEG2SECIDX (codseg));
3942+ }
3943+
3944+ OutBuffer * buf = SegData[codseg].SDbuf;
3945+ assert (! buf.length());
3946+ size_t off = 0 ;
3947+
3948+ static immutable uint [17 ] ins =
3949+ [ // implementation of __dso_init()
3950+ INSTR .ldstpair_pre(2 ,0 ,0 ,- 48 / 8 & 127 ,30 ,31 ,29 ), // STP x29,x30,[sp,#-48]!
3951+ INSTR .mov_add_addsub_imm(1 ,31 ,29 ), // MOV x29,sp
3952+ INSTR .adr(1 ,0 ,0 ), // ADRP x0,<minfo_end> R_AARCH64_ADR_PREL_PG_HI21 minfo_end
3953+ INSTR .addsub_imm(1 ,0 ,0 ,0 ,0 ,0 ,0 ), // ADD x0,x0,#0x0 R_AARCH64_ADD_ABS_LO12_NC minfo_end
3954+ INSTR .str_imm_gen(1 ,0 ,31 ,40 ), // STR x0,[sp,#40]
3955+ INSTR .adr(1 ,0 ,0 ), // ADRP x0,<minfo_beg> R_AARCH64_ADR_PREL_PG_HI21 minfo_beg
3956+ INSTR .addsub_imm(1 ,0 ,0 ,0 ,0 ,0 ,0 ), // ADD x0,x0,#0x0 R_AARCH64_ADD_ABS_LO12_NC minfo_beg
3957+ INSTR .str_imm_gen(1 ,0 ,31 ,32 ), // STR x0,[sp,#32]
3958+ INSTR .adr(1 ,0 ,0 ), // ADRP x0,<slot> R_AARCH64_ADR_PREL_PG_HI21 slot
3959+ INSTR .addsub_imm(1 ,0 ,0 ,0 ,0 ,0 ,0 ), // ADD x0,x0,#0x0 R_AARCH64_ADD_ABS_LO12_NC slot
3960+ INSTR .str_imm_gen(1 ,0 ,31 ,24 ), // STR x0,[sp,#24]
3961+ INSTR .movewide(1 ,2 ,0 ,1 ,0 ), // MOV x0,#1
3962+ INSTR .str_imm_gen(1 ,0 ,31 ,16 ), // STR x0,[sp,#16]
3963+ INSTR .addsub_imm(1 ,0 ,0 ,0 ,0x10 ,31 ,0 ), // ADD x0,sp,#0x10
3964+ INSTR .bl(0 ), // BL 0<dso_registry> R_AARCH64_CALL26 dso_registry
3965+ INSTR .ldstpair_post(2 ,0 ,1 ,48 / 8 ,30 ,31 ,29 ),// LDP x29,x30,[sp],#48
3966+ INSTR .ret(), // RET
3967+ ];
3968+ buf.write(ins);
3969+ ElfObj_writerel(codseg, off+ 2 * 4 , R_AARCH64_ADR_PREL_PG_HI21 , minfo_end, 0 );
3970+ ElfObj_writerel(codseg, off+ 3 * 4 , R_AARCH64_ADD_ABS_LO12_NC , minfo_end, 0 );
3971+ ElfObj_writerel(codseg, off+ 5 * 4 , R_AARCH64_ADR_PREL_PG_HI21 , minfo_beg, 0 );
3972+ ElfObj_writerel(codseg, off+ 6 * 4 , R_AARCH64_ADD_ABS_LO12_NC , minfo_beg, 0 );
3973+ ElfObj_writerel(codseg, off+ 8 * 4 , R_AARCH64_ADR_PREL_PG_HI21 , dso_rec, 0 );
3974+ ElfObj_writerel(codseg, off+ 9 * 4 , R_AARCH64_ADD_ABS_LO12_NC , dso_rec, 0 );
3975+ ElfObj_writerel(codseg, off+ 14 * 4 , R_AARCH64_CALL26 , dso_rec, 0 );
3976+ off = buf.length();
3977+
3978+ Offset(codseg) = off;
3979+
3980+ // put a reference into .init_array/.fini_array each
3981+ // needs to be writeable for PIC code, see Bugzilla 13117
3982+ const int flags = SHF_ALLOC | SHF_WRITE | SHF_GROUP ;
3983+ {
3984+ const fini_name = USE_INIT_ARRAY () ? " .fini_array.d_dso_dtor" : " .dtors.d_dso_dtor" ;
3985+ const fini_type = USE_INIT_ARRAY () ? SHT_FINI_ARRAY : SHT_PROGBITS ;
3986+ const cdseg = ElfObj_getsegment(fini_name.ptr, null , fini_type, flags, _tysize[TYnptr]);
3987+ assert (! SegData[cdseg].SDbuf.length());
3988+ // add to section group
3989+ SegData[groupseg].SDbuf.write32(MAP_SEG2SECIDX (cdseg));
3990+ // relocation
3991+ const reltype2 = I64 ? R_X86_64_64 : R_386_32 ;
3992+ SegData[cdseg].SDoffset += ElfObj_writerel(cdseg, 0 , reltype2, MAP_SEG2SYMIDX (codseg), 0 );
3993+ }
3994+ {
3995+ const init_name = USE_INIT_ARRAY () ? " .init_array.d_dso_ctor" : " .ctors.d_dso_ctor" ;
3996+ const init_type = USE_INIT_ARRAY () ? SHT_INIT_ARRAY : SHT_PROGBITS ;
3997+ const cdseg = ElfObj_getsegment(init_name.ptr, null , init_type, flags, _tysize[TYnptr]);
3998+ assert (! SegData[cdseg].SDbuf.length());
3999+ // add to section group
4000+ SegData[groupseg].SDbuf.write32(MAP_SEG2SECIDX (cdseg));
4001+ // relocation
4002+ const reltype2 = I64 ? R_X86_64_64 : R_386_32 ;
4003+ SegData[cdseg].SDoffset += ElfObj_writerel(cdseg, 0 , reltype2, MAP_SEG2SYMIDX (codseg), 0 );
4004+ }
4005+ }
4006+ // set group section infos
4007+ Offset(groupseg) = SegData[groupseg].SDbuf.length();
4008+ Elf32_Shdr* p = MAP_SEG2SEC (groupseg);
4009+ p.sh_link = SHN_SYMTAB ;
4010+ p.sh_info = dso_rec; // set the dso_rec as group symbol
4011+ p.sh_entsize = IDXSYM .sizeof;
4012+ p.sh_size = cast (uint )Offset(groupseg);
4013+ }
4014+
38474015/* ************************************
38484016 */
38494017
0 commit comments