|
@@ -45,6 +45,7 @@ interface
|
|
|
TGNUAssembler=class(texternalassembler)
|
|
|
protected
|
|
|
function sectionname(atype:TAsmSectiontype;const aname:string;aorder:TAsmSectionOrder):string;virtual;
|
|
|
+ function sectionattrs_coff(atype:TAsmSectiontype):string;virtual;
|
|
|
procedure WriteSection(atype:TAsmSectiontype;const aname:string;aorder:TAsmSectionOrder);
|
|
|
procedure WriteExtraHeader;virtual;
|
|
|
procedure WriteInstruction(hp: tai);
|
|
@@ -238,6 +239,19 @@ implementation
|
|
|
result := target_asm.labelprefix+'$set$'+tostr(setcount);
|
|
|
end;
|
|
|
|
|
|
+ function is_smart_section(atype:TAsmSectiontype):boolean;
|
|
|
+ begin
|
|
|
+ { For bss we need to set some flags that are target dependent,
|
|
|
+ it is easier to disable it for smartlinking. It doesn't take up
|
|
|
+ filespace }
|
|
|
+ result:=not(target_info.system in systems_darwin) and
|
|
|
+ create_smartlink_sections and
|
|
|
+ (atype<>sec_toc) and
|
|
|
+ (atype<>sec_user) and
|
|
|
+ { on embedded systems every byte counts, so smartlink bss too }
|
|
|
+ ((atype<>sec_bss) or (target_info.system in systems_embedded));
|
|
|
+ end;
|
|
|
+
|
|
|
function TGNUAssembler.sectionname(atype:TAsmSectiontype;const aname:string;aorder:TAsmSectionOrder):string;
|
|
|
const
|
|
|
secnames : array[TAsmSectiontype] of string[length('__DATA, __datacoal_nt,coalesced')] = ('','',
|
|
@@ -404,16 +418,7 @@ implementation
|
|
|
if atype=sec_user then
|
|
|
secname:=aname;
|
|
|
|
|
|
- { For bss we need to set some flags that are target dependent,
|
|
|
- it is easier to disable it for smartlinking. It doesn't take up
|
|
|
- filespace }
|
|
|
- if not(target_info.system in systems_darwin) and
|
|
|
- create_smartlink_sections and
|
|
|
- (aname<>'') and
|
|
|
- (atype<>sec_toc) and
|
|
|
- (atype<>sec_user) and
|
|
|
- { on embedded systems every byte counts, so smartlink bss too }
|
|
|
- ((atype<>sec_bss) or (target_info.system in systems_embedded)) then
|
|
|
+ if is_smart_section(atype) and (aname<>'') then
|
|
|
begin
|
|
|
case aorder of
|
|
|
secorder_begin :
|
|
@@ -430,6 +435,45 @@ implementation
|
|
|
end;
|
|
|
|
|
|
|
|
|
+ function TGNUAssembler.sectionattrs_coff(atype:TAsmSectiontype):string;
|
|
|
+ begin
|
|
|
+ case atype of
|
|
|
+ sec_code, sec_init, sec_fini, sec_stub:
|
|
|
+ result:='x';
|
|
|
+
|
|
|
+ { TODO: must be individual for each section }
|
|
|
+ sec_user:
|
|
|
+ result:='d';
|
|
|
+
|
|
|
+ sec_data, sec_data_lazy, sec_data_nonlazy, sec_fpc,
|
|
|
+ sec_idata2, sec_idata4, sec_idata5, sec_idata6, sec_idata7:
|
|
|
+ result:='d';
|
|
|
+
|
|
|
+ { TODO: these need a fix to become read-only }
|
|
|
+ sec_rodata, sec_rodata_norel:
|
|
|
+ result:='d';
|
|
|
+
|
|
|
+ sec_bss:
|
|
|
+ result:='b';
|
|
|
+
|
|
|
+ { TODO: Somewhat questionable. FPC does not allow initialized threadvars,
|
|
|
+ so no sense to mark it as containing data. But Windows allows it to
|
|
|
+ contain data, and Linux even has .tdata and .tbss }
|
|
|
+ sec_threadvar:
|
|
|
+ result:='b';
|
|
|
+
|
|
|
+ sec_pdata, sec_edata, sec_eh_frame, sec_toc:
|
|
|
+ result:='r';
|
|
|
+
|
|
|
+ sec_stab,sec_stabstr,
|
|
|
+ sec_debug_frame,sec_debug_info,sec_debug_line,sec_debug_abbrev:
|
|
|
+ result:='n';
|
|
|
+ else
|
|
|
+ result:=''; { defaults to data+load }
|
|
|
+ end;
|
|
|
+ end;
|
|
|
+
|
|
|
+
|
|
|
procedure TGNUAssembler.WriteSection(atype:TAsmSectiontype;const aname:string;aorder:TAsmSectionOrder);
|
|
|
var
|
|
|
s : string;
|
|
@@ -484,6 +528,20 @@ implementation
|
|
|
internalerror(2006031101);
|
|
|
end;
|
|
|
end;
|
|
|
+ else
|
|
|
+ { GNU AS won't recognize '.text.n_something' section name as belonging
|
|
|
+ to '.text' and assigns default attributes to it, which is not
|
|
|
+ always correct. We have to fix it.
|
|
|
+
|
|
|
+ TODO: This likely applies to all systems which smartlink without
|
|
|
+ creating libraries }
|
|
|
+ if (target_info.system in [system_i386_win32,system_x86_64_win64]) and
|
|
|
+ is_smart_section(atype) and (aname<>'') then
|
|
|
+ begin
|
|
|
+ s:=sectionattrs_coff(atype);
|
|
|
+ if (s<>'') then
|
|
|
+ AsmWrite(',"'+s+'"');
|
|
|
+ end;
|
|
|
end;
|
|
|
AsmLn;
|
|
|
LastSecType:=atype;
|