mirror of
https://gitlab.com/freepascal.org/fpc/source.git
synced 2025-08-18 17:49:07 +02:00
* correctly handle PE COMDAT sections: like for the Comdat groups in ELF files the unused symbols need to be converted to externals so that relocations are handled correctly
git-svn-id: trunk@43359 -
This commit is contained in:
parent
c6a08cdc6e
commit
ccb169b0f1
@ -2548,8 +2548,10 @@ implementation
|
|||||||
j : longint;
|
j : longint;
|
||||||
hs : string;
|
hs : string;
|
||||||
exesym : TExeSymbol;
|
exesym : TExeSymbol;
|
||||||
|
tmpsym,
|
||||||
objsym : TObjSymbol;
|
objsym : TObjSymbol;
|
||||||
grp : TObjSectionGroup;
|
grp : TObjSectionGroup;
|
||||||
|
makeexternal : boolean;
|
||||||
begin
|
begin
|
||||||
for j:=0 to ObjData.ObjSymbolList.Count-1 do
|
for j:=0 to ObjData.ObjSymbolList.Count-1 do
|
||||||
begin
|
begin
|
||||||
@ -2607,26 +2609,20 @@ implementation
|
|||||||
begin
|
begin
|
||||||
exesym:=texesymbol.Create(FExeSymbolList,objsym.name);
|
exesym:=texesymbol.Create(FExeSymbolList,objsym.name);
|
||||||
exesym.ObjSymbol:=objsym;
|
exesym.ObjSymbol:=objsym;
|
||||||
end;
|
end
|
||||||
objsym.ExeSymbol:=exesym;
|
else
|
||||||
case objsym.bind of
|
begin
|
||||||
AB_GLOBAL,
|
if assigned(objsym.objsection) and assigned(exesym.objsymbol.objsection) then
|
||||||
AB_PRIVATE_EXTERN:
|
begin
|
||||||
begin
|
|
||||||
if exesym.State<>symstate_defined then
|
|
||||||
begin
|
|
||||||
exesym.ObjSymbol:=objsym;
|
|
||||||
exesym.State:=symstate_defined;
|
|
||||||
end
|
|
||||||
else
|
|
||||||
if (oso_comdat in exesym.ObjSymbol.objsection.SecOptions) and
|
if (oso_comdat in exesym.ObjSymbol.objsection.SecOptions) and
|
||||||
(oso_comdat in objsym.objsection.SecOptions) then
|
(oso_comdat in objsym.objsection.SecOptions) then
|
||||||
begin
|
begin
|
||||||
if exesym.ObjSymbol.objsection.ComdatSelection=objsym.objsection.ComdatSelection then
|
if exesym.ObjSymbol.objsection.ComdatSelection=objsym.objsection.ComdatSelection then
|
||||||
begin
|
begin
|
||||||
|
makeexternal:=true;
|
||||||
case objsym.objsection.ComdatSelection of
|
case objsym.objsection.ComdatSelection of
|
||||||
oscs_none:
|
oscs_none:
|
||||||
Message1(link_e_duplicate_symbol,objsym.name);
|
makeexternal:=false;
|
||||||
oscs_any:
|
oscs_any:
|
||||||
Message1(link_d_comdat_discard_any,objsym.name);
|
Message1(link_d_comdat_discard_any,objsym.name);
|
||||||
oscs_same_size:
|
oscs_same_size:
|
||||||
@ -2641,22 +2637,48 @@ implementation
|
|||||||
Message1(link_d_comdat_discard_content,objsym.name);
|
Message1(link_d_comdat_discard_content,objsym.name);
|
||||||
oscs_associative:
|
oscs_associative:
|
||||||
{ this is handled in a different way }
|
{ this is handled in a different way }
|
||||||
Message1(link_e_duplicate_symbol,objsym.name);
|
makeexternal:=false;
|
||||||
oscs_largest:
|
oscs_largest:
|
||||||
if objsym.size>exesym.ObjSymbol.size then
|
if objsym.size>exesym.ObjSymbol.size then
|
||||||
begin
|
begin
|
||||||
Message1(link_d_comdat_replace_size,objsym.name);
|
Message1(link_d_comdat_replace_size,objsym.name);
|
||||||
exesym.ObjSymbol.exesymbol:=nil;
|
{ we swap the symbols and turn the smaller one to an external
|
||||||
exesym.ObjSymbol:=objsym;
|
symbol }
|
||||||
|
tmpsym:=exesym.objsymbol;
|
||||||
|
exesym.objsymbol:=objsym;
|
||||||
|
objsym.exesymbol:=exesym;
|
||||||
|
objsym:=tmpsym;
|
||||||
end;
|
end;
|
||||||
end;
|
end;
|
||||||
|
if makeexternal then
|
||||||
|
begin
|
||||||
|
{ Undefine the symbol, causing relocations to it from same
|
||||||
|
objdata to be redirected to the symbol that is actually
|
||||||
|
used }
|
||||||
|
if objsym.bind=AB_GLOBAL then
|
||||||
|
objsym.bind:=AB_EXTERNAL;
|
||||||
|
{ AB_WEAK_EXTERNAL remains unchanged }
|
||||||
|
objsym.objsection:=nil;
|
||||||
|
end;
|
||||||
end
|
end
|
||||||
else
|
else
|
||||||
Message1(link_e_comdat_selection_differs,objsym.name);
|
Message1(link_e_comdat_selection_differs,objsym.name);
|
||||||
end
|
end;
|
||||||
else
|
end;
|
||||||
{ specific error if ComDat flags are different? }
|
end;
|
||||||
Message1(link_e_duplicate_symbol,objsym.name);
|
|
||||||
|
objsym.ExeSymbol:=exesym;
|
||||||
|
case objsym.bind of
|
||||||
|
AB_GLOBAL,
|
||||||
|
AB_PRIVATE_EXTERN:
|
||||||
|
begin
|
||||||
|
if exesym.State<>symstate_defined then
|
||||||
|
begin
|
||||||
|
exesym.ObjSymbol:=objsym;
|
||||||
|
exesym.State:=symstate_defined;
|
||||||
|
end
|
||||||
|
else
|
||||||
|
Message1(link_e_duplicate_symbol,objsym.name);
|
||||||
|
|
||||||
{ hidden symbols must become local symbols in the executable }
|
{ hidden symbols must become local symbols in the executable }
|
||||||
if objsym.bind=AB_PRIVATE_EXTERN then
|
if objsym.bind=AB_PRIVATE_EXTERN then
|
||||||
|
Loading…
Reference in New Issue
Block a user