|
@@ -2548,8 +2548,10 @@ implementation
|
|
|
j : longint;
|
|
|
hs : string;
|
|
|
exesym : TExeSymbol;
|
|
|
+ tmpsym,
|
|
|
objsym : TObjSymbol;
|
|
|
grp : TObjSectionGroup;
|
|
|
+ makeexternal : boolean;
|
|
|
begin
|
|
|
for j:=0 to ObjData.ObjSymbolList.Count-1 do
|
|
|
begin
|
|
@@ -2607,26 +2609,20 @@ implementation
|
|
|
begin
|
|
|
exesym:=texesymbol.Create(FExeSymbolList,objsym.name);
|
|
|
exesym.ObjSymbol:=objsym;
|
|
|
- end;
|
|
|
- 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
|
|
|
+ end
|
|
|
+ else
|
|
|
+ begin
|
|
|
+ if assigned(objsym.objsection) and assigned(exesym.objsymbol.objsection) then
|
|
|
+ begin
|
|
|
if (oso_comdat in exesym.ObjSymbol.objsection.SecOptions) and
|
|
|
(oso_comdat in objsym.objsection.SecOptions) then
|
|
|
begin
|
|
|
if exesym.ObjSymbol.objsection.ComdatSelection=objsym.objsection.ComdatSelection then
|
|
|
begin
|
|
|
+ makeexternal:=true;
|
|
|
case objsym.objsection.ComdatSelection of
|
|
|
oscs_none:
|
|
|
- Message1(link_e_duplicate_symbol,objsym.name);
|
|
|
+ makeexternal:=false;
|
|
|
oscs_any:
|
|
|
Message1(link_d_comdat_discard_any,objsym.name);
|
|
|
oscs_same_size:
|
|
@@ -2641,22 +2637,48 @@ implementation
|
|
|
Message1(link_d_comdat_discard_content,objsym.name);
|
|
|
oscs_associative:
|
|
|
{ this is handled in a different way }
|
|
|
- Message1(link_e_duplicate_symbol,objsym.name);
|
|
|
+ makeexternal:=false;
|
|
|
oscs_largest:
|
|
|
if objsym.size>exesym.ObjSymbol.size then
|
|
|
begin
|
|
|
Message1(link_d_comdat_replace_size,objsym.name);
|
|
|
- exesym.ObjSymbol.exesymbol:=nil;
|
|
|
- exesym.ObjSymbol:=objsym;
|
|
|
+ { we swap the symbols and turn the smaller one to an external
|
|
|
+ symbol }
|
|
|
+ tmpsym:=exesym.objsymbol;
|
|
|
+ exesym.objsymbol:=objsym;
|
|
|
+ objsym.exesymbol:=exesym;
|
|
|
+ objsym:=tmpsym;
|
|
|
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
|
|
|
else
|
|
|
Message1(link_e_comdat_selection_differs,objsym.name);
|
|
|
- end
|
|
|
- else
|
|
|
- { specific error if ComDat flags are different? }
|
|
|
- Message1(link_e_duplicate_symbol,objsym.name);
|
|
|
+ end;
|
|
|
+ end;
|
|
|
+ end;
|
|
|
+
|
|
|
+ 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 }
|
|
|
if objsym.bind=AB_PRIVATE_EXTERN then
|