diff --git a/compiler/aasmcnst.pas b/compiler/aasmcnst.pas index 5fec489b2c..b6d3e2b663 100644 --- a/compiler/aasmcnst.pas +++ b/compiler/aasmcnst.pas @@ -29,7 +29,7 @@ interface uses cclasses,globtype,constexp, aasmbase,aasmdata,aasmtai, - symtype,symdef,symsym; + symconst,symtype,symdef,symsym; type { typed const: integer/floating point/string/pointer/... const along with @@ -171,6 +171,12 @@ type another list first. This property should only be accessed once all data has been added. } function get_final_asmlist(sym: tasmsymbol; def: tdef; section: TAsmSectiontype; const secname: TSymStr; alignment: longint; lab: boolean): tasmlist; + + { returns the offset of the string data relative to ansi/unicode/widestring + constant labels. On most platforms, this is 0 (with the header at a + negative offset), but on some platforms such negative offsets are not + supported } + class function get_string_symofs(typ: tstringtype; winlikewidestring: boolean): pint; virtual; end; ttai_lowleveltypedconstbuilderclass = class of ttai_lowleveltypedconstbuilder; @@ -180,8 +186,8 @@ type implementation uses - verbose,globals, - symconst,defutil; + verbose,globals,systems, + defutil; {**************************************************************************** @@ -415,6 +421,42 @@ implementation end; + class function ttai_lowleveltypedconstbuilder.get_string_symofs(typ: tstringtype; winlikewidestring: boolean): pint; + const + ansistring_header_size = + { encoding } + 2 + + { elesize } + 2 + + {$ifdef cpu64bitaddr} + { alignment } + 4 + + {$endif cpu64bitaddr} + { reference count } + sizeof(pint) + + { length } + sizeof(pint); + unicodestring_header_size = ansistring_header_size; + begin + { darwin's linker does not support negative offsets } + if not(target_info.system in systems_darwin) then + result:=0 + else case typ of + st_ansistring: + result:=ansistring_header_size; + st_unicodestring: + result:=unicodestring_header_size; + st_widestring: + if winlikewidestring then + result:=0 + else + result:=unicodestring_header_size; + else + result:=0; + end; + end; + + constructor ttai_lowleveltypedconstbuilder.create; begin inherited create; diff --git a/compiler/asmutils.pas b/compiler/asmutils.pas index 45e2818781..34052cf881 100644 --- a/compiler/asmutils.pas +++ b/compiler/asmutils.pas @@ -40,8 +40,6 @@ uses function emit_ansistring_const(list:TAsmList;data:PChar;len:LongInt;encoding:tstringencoding;NewSection:Boolean=True):tasmlabofs; function emit_unicodestring_const(list:TAsmList;data:Pointer;encoding:tstringencoding;Winlike:Boolean):tasmlabofs; - function get_string_symofs(typ: tstringtype; winlikewidestring: boolean): pint; - implementation @@ -49,7 +47,7 @@ uses globals, systems, verbose, - aasmtai, + aasmtai,aasmcnst, widestr, symdef; @@ -88,7 +86,7 @@ uses result.ofs:=0; end; { sanity check } - if result.ofs<>get_string_symofs(st_ansistring,false) then + if result.ofs<>ctai_typedconstbuilder.get_string_symofs(st_ansistring,false) then internalerror(2012051701); getmem(s,len+1); @@ -141,7 +139,7 @@ uses result.ofs:=0; end; { sanity check } - if result.ofs<>get_string_symofs(st_unicodestring,false) then + if result.ofs<>ctai_typedconstbuilder.get_string_symofs(st_unicodestring,false) then internalerror(2012051702); end; if cwidechartype.size = 2 then @@ -156,39 +154,4 @@ uses end; - function get_string_symofs(typ: tstringtype; winlikewidestring: boolean): pint; - const - ansistring_header_size = - { encoding } - 2 + - { elesize } - 2 + -{$ifdef cpu64bitaddr} - { alignment } - 4 + -{$endif cpu64bitaddr} - { reference count } - sizeof(pint) + - { length } - sizeof(pint); - unicodestring_header_size = ansistring_header_size; - begin - if not(target_info.system in systems_darwin) then - result:=0 - else case typ of - st_ansistring: - result:=ansistring_header_size; - st_unicodestring: - result:=unicodestring_header_size; - st_widestring: - if winlikewidestring then - result:=0 - else - result:=unicodestring_header_size; - else - result:=0; - end; - end; - - end. diff --git a/compiler/llvm/nllvmtcon.pas b/compiler/llvm/nllvmtcon.pas index fc142ed181..82a10bb2d8 100644 --- a/compiler/llvm/nllvmtcon.pas +++ b/compiler/llvm/nllvmtcon.pas @@ -28,7 +28,7 @@ interface uses cclasses,constexp,globtype, aasmbase,aasmtai,aasmcnst,aasmllvm, - symtype,symdef,symsym, + symconst,symtype,symdef,symsym, ngtcon; type @@ -64,6 +64,8 @@ interface procedure queue_subscriptn(def: tabstractrecorddef; vs: tfieldvarsym); override; procedure queue_typeconvn(fromdef, todef: tdef); override; procedure queue_emit_asmsym(sym: tasmsymbol; def: tdef); override; + + class function get_string_symofs(typ: tstringtype; winlikewidestring: boolean): pint; override; end; implementation @@ -72,7 +74,7 @@ implementation verbose, aasmdata, cpubase,llvmbase, - symconst,symtable,llvmdef,defutil; + symtable,llvmdef,defutil; procedure tllvmtai_typedconstbuilder.finalize_asmlist(sym: tasmsymbol; def: tdef; section: TAsmSectiontype; const secname: TSymStr; alignment: shortint; lab: boolean); @@ -347,6 +349,13 @@ implementation end; + class function tllvmtai_typedconstbuilder.get_string_symofs(typ: tstringtype; winlikewidestring: boolean): pint; + begin + { LLVM does not support labels in the middle of a declaration } + result:=0; + end; + + begin ctai_typedconstbuilder:=tllvmtai_typedconstbuilder; end. diff --git a/compiler/ncgcon.pas b/compiler/ncgcon.pas index 9b92b285e2..7676a1fad4 100644 --- a/compiler/ncgcon.pas +++ b/compiler/ncgcon.pas @@ -73,6 +73,7 @@ implementation uses globtype,widestr,systems, verbose,globals,cutils, + aasmcnst, symconst,symdef,aasmtai,aasmdata,aasmcpu,defutil, cpuinfo,cpubase, cgbase,cgobj,cgutils, @@ -330,7 +331,7 @@ implementation lastlabel:=emit_ansistring_const(current_asmdata.AsmLists[al_typedconsts],value_str,len,tstringdef(resultdef).encoding); { because we hardcode the offset below due to it not being stored in the hashset, check here } - if lastlabel.ofs<>get_string_symofs(st_ansistring,false) then + if lastlabel.ofs<>ctai_typedconstbuilder.get_string_symofs(st_ansistring,false) then internalerror(2012051703); end; end; @@ -347,7 +348,7 @@ implementation winlikewidestring); { because we hardcode the offset below due to it not being stored in the hashset, check here } - if lastlabel.ofs<>get_string_symofs(tstringdef(resultdef).stringtype,winlikewidestring) then + if lastlabel.ofs<>ctai_typedconstbuilder.get_string_symofs(tstringdef(resultdef).stringtype,winlikewidestring) then internalerror(2012051704); end; end; @@ -394,7 +395,7 @@ implementation begin location_reset(location, LOC_REGISTER, def_cgsize(strpointerdef)); reference_reset_symbol(href, lab_str, - get_string_symofs(tstringdef(resultdef).stringtype,winlikewidestring), + ctai_typedconstbuilder.get_string_symofs(tstringdef(resultdef).stringtype,winlikewidestring), const_align(strpointerdef.size)); location.register:=hlcg.getaddressregister(current_asmdata.CurrAsmList,strpointerdef); hlcg.a_loadaddr_ref_reg(current_asmdata.CurrAsmList,elementdef,strpointerdef,href,location.register)