+ user section type

+ parsing of section directive for variables
  + section test
  + write section names in the assembler/binary writers correctly
  * allow section only after ; and for embedded targets

git-svn-id: branches/usersections@17154 -
This commit is contained in:
florian 2011-03-20 15:42:28 +00:00
parent e4656050a7
commit f328b6d635
19 changed files with 507 additions and 424 deletions

1
.gitattributes vendored
View File

@ -9972,6 +9972,7 @@ tests/test/tsealed3.pp svneol=native#text/pascal
tests/test/tsealed4.pp svneol=native#text/pascal
tests/test/tsealed5.pp svneol=native#text/pascal
tests/test/tsealed6.pp svneol=native#text/pascal
tests/test/tsec1.pp svneol=native#text/plain
tests/test/tsel1.pp svneol=native#text/plain
tests/test/tsel2.pp svneol=native#text/plain
tests/test/tset1.pp svneol=native#text/plain

View File

@ -61,6 +61,8 @@ interface
type
TAsmSectiontype=(sec_none,
{ this section type allows to define a user named section }
sec_user,
sec_code,
sec_data,
{ read-only, but may contain relocations }

View File

@ -246,7 +246,7 @@ implementation
function TGNUAssembler.sectionname(atype:TAsmSectiontype;const aname:string;aorder:TAsmSectionOrder):string;
const
secnames : array[TAsmSectiontype] of string[length('__DATA, __datacoal_nt,coalesced')] = ('',
secnames : array[TAsmSectiontype] of string[length('__DATA, __datacoal_nt,coalesced')] = ('','',
'.text',
'.data',
{ why doesn't .rodata work? (FK) }
@ -264,7 +264,7 @@ implementation
{$if defined(m68k)} { Amiga/m68k GNU AS doesn't seem to like .rodata (KB) }
'.data',
{$else}
'.rodata',
'.rodata',
{$endif}
'.bss',
'.threadvar',
@ -318,7 +318,7 @@ implementation
'.obcj_nlcatlist',
'.objc_protolist'
);
secnames_pic : array[TAsmSectiontype] of string[length('__DATA, __datacoal_nt,coalesced')] = ('',
secnames_pic : array[TAsmSectiontype] of string[length('__DATA, __datacoal_nt,coalesced')] = ('','',
'.text',
'.data.rel',
'.data.rel',
@ -406,6 +406,10 @@ implementation
(target_info.system=system_i386_go32v2) then
secname:='.data';
{ section type user gives the user full controll on the section name }
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 }
@ -413,6 +417,7 @@ implementation
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
begin
@ -1466,6 +1471,7 @@ implementation
const
(* Translation table - replace unsupported section types with basic ones. *)
SecXTable: array[TAsmSectionType] of TAsmSectionType = (
sec_none,
sec_none,
sec_code,
sec_data,

View File

@ -445,7 +445,7 @@ interface
procedure T386NasmAssembler.WriteSection(atype:TAsmSectiontype;const aname:string);
const
secnames : array[TAsmSectiontype] of string[length('__DATA, __datacoal_nt,coalesced')] = ('',
secnames : array[TAsmSectiontype] of string[length('__DATA, __datacoal_nt,coalesced')] = ('','',
'.text',
'.data',
'.data',

View File

@ -1366,6 +1366,10 @@ parser_e_cant_use_type_parameters_here=03304_E_Type parameters may require initi
% Type parameters may be specialized with types which (e.g. \var{ansistring}) need initialization/finalization
% code which is implicitly generated by the compiler.
% \end{description}
parser_e_externals_no_section=03305_E_Variables being declared as external cannot be in a custom section
% A section directive is not valid for variables being declared as external.
parser_e_section_no_locals=03306_E_Non-static and non-global variables cannot have a section directive
% A variable placed in a custom section is always statically allocated so it must be either a static or global variable.
# Type Checking
#
# 04095 is the last used one

View File

@ -393,6 +393,8 @@ const
parser_e_no_constructor_in_records=03302;
parser_e_at_least_one_argument_must_be_of_type=03303;
parser_e_cant_use_type_parameters_here=03304;
parser_e_externals_no_section=03305;
parser_e_section_no_locals=03306;
type_e_mismatch=04000;
type_e_incompatible_types=04001;
type_e_not_equal_types=04002;
@ -882,9 +884,9 @@ const
option_info=11024;
option_help_pages=11025;
MsgTxtSize = 58686;
MsgTxtSize = 58837;
MsgIdxMax : array[1..20] of longint=(
24,88,305,99,84,54,111,22,202,63,
24,88,307,99,84,54,111,22,202,63,
49,20,1,1,1,1,1,1,1,1
);

File diff suppressed because it is too large Load Diff

View File

@ -2524,7 +2524,10 @@ implementation
sectype:=sec_bss;
end;
maybe_new_object_file(list);
new_section(list,sectype,lower(sym.mangledname),varalign);
if sym.section<>'' then
new_section(list,sec_user,sym.section,varalign)
else
new_section(list,sectype,lower(sym.mangledname),varalign);
if (sym.owner.symtabletype=globalsymtable) or
create_smartlink or
DLLSource or

View File

@ -823,7 +823,7 @@ implementation
function TObjData.sectionname(atype:TAsmSectiontype;const aname:string;aorder:TAsmSectionOrder):string;
const
secnames : array[TAsmSectiontype] of string[length('__DATA, __datacoal_nt,coalesced')] = ('',
secnames : array[TAsmSectiontype] of string[length('__DATA, __datacoal_nt,coalesced')] = ('','',
'code',
'Data',
'Data',
@ -902,6 +902,7 @@ implementation
function TObjData.sectiontype2options(atype:TAsmSectiontype):TObjSectionOptions;
const
secoptions : array[TAsmSectiontype] of TObjSectionOptions = ([],
{user} [oso_Data,oso_load,oso_write,oso_executable,oso_keep],
{code} [oso_Data,oso_load,oso_readonly,oso_executable,oso_keep],
{Data} [oso_Data,oso_load,oso_write,oso_keep],
{ TODO: Fix sec_rodata be read-only-with-relocs}

View File

@ -488,7 +488,7 @@ implementation
SymbolMaxGrow = 200*sizeof(coffsymbol);
StrsMaxGrow = 8192;
coffsecnames : array[TAsmSectiontype] of string[length('__DATA, __datacoal_nt,coalesced')] = ('',
coffsecnames : array[TAsmSectiontype] of string[length('__DATA, __datacoal_nt,coalesced')] = ('','',
'.text','.data','.data','.data','.bss','.tls',
'.pdata',{pdata}
'.text', {stub}
@ -1031,22 +1031,28 @@ const pemagic : array[0..3] of byte = (
sep : string[3];
secname : string;
begin
secname:=coffsecnames[atype];
if create_smartlink_sections and
(aname<>'') then
begin
case aorder of
secorder_begin :
sep:='.b_';
secorder_end :
sep:='.z_';
else
sep:='.n_';
end;
result:=secname+sep+aname
end
{ section type user gives the user full controll on the section name }
if atype=sec_user then
result:=aname
else
result:=secname;
begin
secname:=coffsecnames[atype];
if create_smartlink_sections and
(aname<>'') then
begin
case aorder of
secorder_begin :
sep:='.b_';
secorder_end :
sep:='.z_';
else
sep:='.n_';
end;
result:=secname+sep+aname
end
else
result:=secname;
end;
end;

View File

@ -584,7 +584,7 @@ implementation
function TElfObjData.sectionname(atype:TAsmSectiontype;const aname:string;aorder:TAsmSectionOrder):string;
const
secnames : array[TAsmSectiontype] of string[length('__DATA, __datacoal_nt,coalesced')] = ('',
secnames : array[TAsmSectiontype] of string[length('__DATA, __datacoal_nt,coalesced')] = ('','',
{$ifdef userodata}
'.text','.data','.data','.rodata','.bss','.threadvar',
{$else userodata}
@ -639,7 +639,7 @@ implementation
'.obcj_nlcatlist',
'.objc_protolist'
);
secnames_pic : array[TAsmSectiontype] of string[length('__DATA, __datacoal_nt,coalesced')] = ('',
secnames_pic : array[TAsmSectiontype] of string[length('__DATA, __datacoal_nt,coalesced')] = ('','',
'.text',
'.data.rel',
'.data.rel',
@ -700,30 +700,36 @@ implementation
sep : string[3];
secname : string;
begin
if (cs_create_pic in current_settings.moduleswitches) and
not(target_info.system in systems_darwin) then
secname:=secnames_pic[atype]
{ section type user gives the user full controll on the section name }
if atype=sec_user then
result:=aname
else
secname:=secnames[atype];
if (atype=sec_fpc) and (Copy(aname,1,3)='res') then
begin
result:=secname+'.'+aname;
exit;
if (cs_create_pic in current_settings.moduleswitches) and
not(target_info.system in systems_darwin) then
secname:=secnames_pic[atype]
else
secname:=secnames[atype];
if (atype=sec_fpc) and (Copy(aname,1,3)='res') then
begin
result:=secname+'.'+aname;
exit;
end;
if create_smartlink_sections and (aname<>'') then
begin
case aorder of
secorder_begin :
sep:='.b_';
secorder_end :
sep:='.z_';
else
sep:='.n_';
end;
result:=secname+sep+aname
end
else
result:=secname;
end;
if create_smartlink_sections and (aname<>'') then
begin
case aorder of
secorder_begin :
sep:='.b_';
secorder_end :
sep:='.z_';
else
sep:='.n_';
end;
result:=secname+sep+aname
end
else
result:=secname;
end;

View File

@ -180,6 +180,7 @@ implementation
= ('sec_debug_frame','__debug_info','__debug_line','__debug_abbrev');
begin
case atype of
sec_user: Result:=aname;
sec_bss: Result:=MakeSectionName(seg_DATA, '__common');
sec_stab: Result:='.stabs';
sec_stabstr: Result:='.stabsstr';

View File

@ -1041,6 +1041,17 @@ implementation
end;
procedure try_consume_sectiondirective(var asection: ansistring);
begin
if idtoken=_SECTION then
begin
consume(_ID);
asection:=get_stringconst;
consume(_SEMICOLON);
end;
end;
procedure read_var_decls(options:Tvar_dec_options);
procedure read_default_value(sc : TFPObjectList);
@ -1253,6 +1264,7 @@ implementation
hintsymoptions : tsymoptions;
deprecatedmsg : pshortstring;
old_block_type : tblock_type;
section : ansistring;
begin
old_block_type:=block_type;
block_type:=bt_var;
@ -1394,6 +1406,24 @@ implementation
) then
read_public_and_external_sc(sc);
{ try to parse a section directive }
if (target_info.system in systems_embedded) and (idtoken=_SECTION) then
begin
try_consume_sectiondirective(section);
if section<>'' then
begin
for i:=0 to sc.count-1 do
begin
vs:=tabstractvarsym(sc[i]);
if (vs.varoptions *[vo_is_external,vo_is_weak_external])<>[] then
Message(parser_e_externals_no_section);
if vs.typ<>staticvarsym then
Message(parser_e_section_no_locals);
tstaticvarsym(vs).section:=section;
end;
end;
end;
{ allocate normal variable (non-external and non-typed-const) staticvarsyms }
for i:=0 to sc.count-1 do
begin

View File

@ -70,6 +70,7 @@ interface
secnames : array[TAsmSectiontype] of string[10] = (
'', {none}
'', {user}
'csect', {code}
'csect', {data}
'csect', {read only data}

View File

@ -423,7 +423,8 @@ type
vo_is_msgsel,
{ first field of variant part of a record }
vo_is_first_field,
vo_volatile
vo_volatile,
vo_has_section
);
tvaroptions=set of tvaroption;

View File

@ -200,6 +200,7 @@ interface
private
_mangledname : pshortstring;
public
section : ansistring;
constructor create(const n : string;vsp:tvarspez;def:tdef;vopts:tvaroptions);
constructor create_dll(const n : string;vsp:tvarspez;def:tdef);
constructor create_C(const n,mangled : string;vsp:tvarspez;def:tdef);
@ -1312,6 +1313,8 @@ implementation
_mangledname:=stringdup(ppufile.getstring)
else
_mangledname:=nil;
if vo_has_section in varoptions then
section:=ppufile.getansistring;
end;
@ -1336,6 +1339,8 @@ implementation
inherited ppuwrite(ppufile);
if vo_has_mangledname in varoptions then
ppufile.putstring(_mangledname^);
if vo_has_section in varoptions then
ppufile.putansistring(section);
ppufile.writeentry(ibstaticvarsym);
end;

View File

@ -204,6 +204,7 @@ type
_PROGRAM,
_R12BASE,
_STDCALL,
_SECTION,
_SYSCALL,
_VARARGS,
_VIRTUAL,
@ -498,6 +499,7 @@ const
(str:'PROGRAM' ;special:false;keyword:m_all;op:NOTOKEN),
(str:'R12BASE' ;special:false;keyword:m_none;op:NOTOKEN), { Syscall variation on MorphOS }
(str:'STDCALL' ;special:false;keyword:m_none;op:NOTOKEN),
(str:'SECTION' ;special:false;keyword:m_none;op:NOTOKEN),
(str:'SYSCALL' ;special:false;keyword:m_none;op:NOTOKEN),
(str:'VARARGS' ;special:false;keyword:m_none;op:NOTOKEN),
(str:'VIRTUAL' ;special:false;keyword:m_none;op:NOTOKEN),

View File

@ -59,7 +59,7 @@ implementation
const
line_length = 70;
secnames : array[TAsmSectiontype] of string[4] = ('',
secnames : array[TAsmSectiontype] of string[4] = ('','',
'CODE','DATA','DATA','DATA','BSS','',
'','','','','','',
'','','','',
@ -109,7 +109,7 @@ implementation
''
);
secnamesml64 : array[TAsmSectiontype] of string[7] = ('',
secnamesml64 : array[TAsmSectiontype] of string[7] = ('','',
'_TEXT','_DATE','_DATA','_DATA','_BSS','',
'','','','',
'idata$2','idata$4','idata$5','idata$6','idata$7','edata',
@ -978,7 +978,7 @@ implementation
{ better do this at end of WriteTree, but then there comes a trouble with
al_const which does not have leading ait_section and thus goes out of segment }
{ TODO: probably ml64 needs 'closing' last section, too }
if LastSecType <> sec_none then
AsmWriteLn('_'+secnames[LasTSecType]+#9#9'ENDS');

6
tests/test/tsec1.pp Normal file
View File

@ -0,0 +1,6 @@
{ %target=embedded }
var
d : longint;section '.bss';
begin
end.