* when targeting the ELFv2 ABI, don't reserve space for the (never used)

words in the linkage area reserved for use by the compiler and linker

git-svn-id: trunk@30206 -
This commit is contained in:
Jonas Maebe 2015-03-14 18:35:56 +00:00
parent 3d9713b9c8
commit 33ed32b024
4 changed files with 39 additions and 6 deletions

View File

@ -380,6 +380,7 @@ uses
LA_LR_SYSV = 4;
{ offset in the linkage area for the saved RTOC register}
LA_RTOC_AIX = 20;
LA_RTOC_ELFV2 = 12;
PARENT_FRAMEPOINTER_OFFSET = 12;

View File

@ -305,6 +305,22 @@ begin
end;
function get_rtoc_offset: longint;
begin
result:=0;
case target_info.abi of
abi_powerpc_aix,
abi_powerpc_darwin:
result:=LA_RTOC_AIX;
abi_powerpc_elfv1:
result:=LA_RTOC_SYSV;
abi_powerpc_elfv2:
result:=LA_RTOC_ELFV2;
else
internalerror(2015021001);
end;
end;
{ calling a procedure by address }
procedure tcgppc.a_call_reg(list: TAsmList; reg: tregister);
@ -322,7 +338,7 @@ begin
a_load_ref_reg(list, OS_ADDR, OS_ADDR, tmpref, tempreg);
{ save TOC pointer in stackframe }
reference_reset_base(tmpref, NR_STACK_POINTER_REG, LA_RTOC_SYSV, 8);
reference_reset_base(tmpref, NR_STACK_POINTER_REG, get_rtoc_offset, 8);
a_load_reg_ref(list, OS_ADDR, OS_ADDR, NR_RTOC, tmpref);
{ move actual function pointer to CTR register }
@ -349,7 +365,7 @@ begin
end;
{ we need to load the old RTOC from stackframe because we changed it}
reference_reset_base(tmpref, NR_STACK_POINTER_REG, LA_RTOC_SYSV, 8);
reference_reset_base(tmpref, NR_STACK_POINTER_REG, get_rtoc_offset, 8);
a_load_ref_reg(list, OS_ADDR, OS_ADDR, tmpref, NR_RTOC);
include(current_procinfo.flags, pi_do_call);

View File

@ -361,6 +361,7 @@ const
*****************************************************************************}
LinkageAreaSizeELF = 48;
LinkageAreaSizeELFv2 = 32;
{ offset in the linkage area for the saved stack pointer }
LA_SP = 0;
{ offset in the linkage area for the saved conditional register}
@ -371,6 +372,7 @@ const
{ offset in the linkage area for the saved RTOC register}
LA_RTOC_SYSV = 40;
LA_RTOC_AIX = 40;
LA_RTOC_ELFV2 = 24;
PARENT_FRAMEPOINTER_OFFSET = 24;
@ -384,6 +386,7 @@ const
{ minimum size of the stack frame if one exists }
MINIMUM_STACKFRAME_SIZE = 112;
MINIMUM_STACKFRAME_SIZE_ELFV2 = 112 - 16;
maxfpuregs = 8;

View File

@ -70,17 +70,30 @@ end;
procedure tppcprocinfo.set_first_temp_offset;
var
ofs: aword;
ofs,
lasize,
minstacksize: aword;
begin
if not (po_assembler in procdef.procoptions) then begin
{ align the stack properly }
ofs := align(maxpushedparasize + LinkageAreaSizeELF, ELF_STACK_ALIGN);
if target_info.abi<>abi_powerpc_elfv2 then
begin
{ same for AIX/Darwin }
lasize:=LinkageAreaSizeELF;
minstacksize:=MINIMUM_STACKFRAME_SIZE;
end
else
begin
lasize:=LinkageAreaSizeELFv2;
minstacksize:=MINIMUM_STACKFRAME_SIZE_ELFV2;
end;
ofs := align(maxpushedparasize + lasize, ELF_STACK_ALIGN);
{ the ABI specification says that it is required to always allocate space for 8 * 8 bytes
for registers R3-R10 and stack header if there's a stack frame, but GCC doesn't do that,
so we don't that too. Uncomment the next three lines if this is required }
if (cs_profile in init_settings.moduleswitches) and (ofs < MINIMUM_STACKFRAME_SIZE) then begin
ofs := MINIMUM_STACKFRAME_SIZE;
if (cs_profile in init_settings.moduleswitches) and (ofs < minstacksize) then begin
ofs := minstacksize;
end;
tg.setfirsttemp(ofs);
end else begin