|
@@ -201,6 +201,8 @@ interface
|
|
property typ: TObjRelocationType read GetType write SetType;
|
|
property typ: TObjRelocationType read GetType write SetType;
|
|
end;
|
|
end;
|
|
|
|
|
|
|
|
+ TObjSectionGroup = class;
|
|
|
|
+
|
|
TObjSection = class(TFPHashObject)
|
|
TObjSection = class(TFPHashObject)
|
|
private
|
|
private
|
|
FData : TDynamicArray;
|
|
FData : TDynamicArray;
|
|
@@ -216,6 +218,7 @@ interface
|
|
Size,
|
|
Size,
|
|
DataPos,
|
|
DataPos,
|
|
MemPos : aword;
|
|
MemPos : aword;
|
|
|
|
+ Group : TObjSectionGroup;
|
|
DataAlignBytes : shortint;
|
|
DataAlignBytes : shortint;
|
|
{ Relocations (=references) to other sections }
|
|
{ Relocations (=references) to other sections }
|
|
ObjRelocations : TFPObjectList;
|
|
ObjRelocations : TFPObjectList;
|
|
@@ -245,6 +248,12 @@ interface
|
|
end;
|
|
end;
|
|
TObjSectionClass = class of TObjSection;
|
|
TObjSectionClass = class of TObjSection;
|
|
|
|
|
|
|
|
+ TObjSectionGroup = class(TFPHashObject)
|
|
|
|
+ public
|
|
|
|
+ members: array of TObjSection;
|
|
|
|
+ iscomdat: boolean;
|
|
|
|
+ end;
|
|
|
|
+
|
|
TString80 = string[80];
|
|
TString80 = string[80];
|
|
|
|
|
|
TObjData = class(TLinkedListItem)
|
|
TObjData = class(TLinkedListItem)
|
|
@@ -258,6 +267,7 @@ interface
|
|
{ Special info sections that are written to during object generation }
|
|
{ Special info sections that are written to during object generation }
|
|
FStabsObjSec,
|
|
FStabsObjSec,
|
|
FStabStrObjSec : TObjSection;
|
|
FStabStrObjSec : TObjSection;
|
|
|
|
+ FGroupsList : TFPHashObjectList;
|
|
procedure section_reset(p:TObject;arg:pointer);
|
|
procedure section_reset(p:TObject;arg:pointer);
|
|
procedure section_afteralloc(p:TObject;arg:pointer);
|
|
procedure section_afteralloc(p:TObject;arg:pointer);
|
|
procedure section_afterwrite(p:TObject;arg:pointer);
|
|
procedure section_afterwrite(p:TObject;arg:pointer);
|
|
@@ -275,6 +285,7 @@ interface
|
|
function sectiontype2align(atype:TAsmSectiontype):shortint;virtual;
|
|
function sectiontype2align(atype:TAsmSectiontype):shortint;virtual;
|
|
function createsection(atype:TAsmSectionType;const aname:string='';aorder:TAsmSectionOrder=secorder_default):TObjSection;
|
|
function createsection(atype:TAsmSectionType;const aname:string='';aorder:TAsmSectionOrder=secorder_default):TObjSection;
|
|
function createsection(const aname:string;aalign:shortint;aoptions:TObjSectionOptions;DiscardDuplicate:boolean=true):TObjSection;virtual;
|
|
function createsection(const aname:string;aalign:shortint;aoptions:TObjSectionOptions;DiscardDuplicate:boolean=true):TObjSection;virtual;
|
|
|
|
+ function createsectiongroup(const aname:string):TObjSectionGroup;
|
|
procedure CreateDebugSections;virtual;
|
|
procedure CreateDebugSections;virtual;
|
|
function findsection(const aname:string):TObjSection;
|
|
function findsection(const aname:string):TObjSection;
|
|
procedure setsection(asec:TObjSection);
|
|
procedure setsection(asec:TObjSection);
|
|
@@ -300,6 +311,7 @@ interface
|
|
property CurrObjSec:TObjSection read FCurrObjSec;
|
|
property CurrObjSec:TObjSection read FCurrObjSec;
|
|
property ObjSymbolList:TFPHashObjectList read FObjSymbolList;
|
|
property ObjSymbolList:TFPHashObjectList read FObjSymbolList;
|
|
property ObjSectionList:TFPHashObjectList read FObjSectionList;
|
|
property ObjSectionList:TFPHashObjectList read FObjSectionList;
|
|
|
|
+ property GroupsList:TFPHashObjectList read FGroupsList;
|
|
property StabsSec:TObjSection read FStabsObjSec write FStabsObjSec;
|
|
property StabsSec:TObjSection read FStabsObjSec write FStabsObjSec;
|
|
property StabStrSec:TObjSection read FStabStrObjSec write FStabStrObjSec;
|
|
property StabStrSec:TObjSection read FStabStrObjSec write FStabStrObjSec;
|
|
end;
|
|
end;
|
|
@@ -483,6 +495,7 @@ interface
|
|
EntrySym : TObjSymbol;
|
|
EntrySym : TObjSymbol;
|
|
SectionDataAlign,
|
|
SectionDataAlign,
|
|
SectionMemAlign : aword;
|
|
SectionMemAlign : aword;
|
|
|
|
+ ComdatGroups : TFPHashList;
|
|
FixedSectionAlign : boolean;
|
|
FixedSectionAlign : boolean;
|
|
function writeData:boolean;virtual;abstract;
|
|
function writeData:boolean;virtual;abstract;
|
|
property CExeSection:TExeSectionClass read FCExeSection write FCExeSection;
|
|
property CExeSection:TExeSectionClass read FCExeSection write FCExeSection;
|
|
@@ -938,6 +951,8 @@ implementation
|
|
{$ifdef MEMDEBUG}
|
|
{$ifdef MEMDEBUG}
|
|
MemObjSymbols.Stop;
|
|
MemObjSymbols.Stop;
|
|
{$endif}
|
|
{$endif}
|
|
|
|
+ GroupsList.free;
|
|
|
|
+
|
|
{ Sections }
|
|
{ Sections }
|
|
{$ifdef MEMDEBUG}
|
|
{$ifdef MEMDEBUG}
|
|
MemObjSections.Start;
|
|
MemObjSections.Start;
|
|
@@ -1073,6 +1088,14 @@ implementation
|
|
end;
|
|
end;
|
|
|
|
|
|
|
|
|
|
|
|
+ function TObjData.CreateSectionGroup(const aname:string):TObjSectionGroup;
|
|
|
|
+ begin
|
|
|
|
+ if FGroupsList=nil then
|
|
|
|
+ FGroupsList:=TFPHashObjectList.Create(true);
|
|
|
|
+ result:=TObjSectionGroup.Create(FGroupsList,aname);
|
|
|
|
+ end;
|
|
|
|
+
|
|
|
|
+
|
|
procedure TObjData.CreateDebugSections;
|
|
procedure TObjData.CreateDebugSections;
|
|
begin
|
|
begin
|
|
end;
|
|
end;
|
|
@@ -1638,6 +1661,7 @@ implementation
|
|
FProvidedObjSymbols:=TFPObjectList.Create(false);
|
|
FProvidedObjSymbols:=TFPObjectList.Create(false);
|
|
FIndirectObjSymbols:=TFPObjectList.Create(false);
|
|
FIndirectObjSymbols:=TFPObjectList.Create(false);
|
|
FExeVTableList:=TFPObjectList.Create(false);
|
|
FExeVTableList:=TFPObjectList.Create(false);
|
|
|
|
+ ComdatGroups:=TFPHashList.Create;
|
|
{ sections }
|
|
{ sections }
|
|
FExeSectionList:=TFPHashObjectList.Create(true);
|
|
FExeSectionList:=TFPHashObjectList.Create(true);
|
|
FImageBase:=0;
|
|
FImageBase:=0;
|
|
@@ -1664,6 +1688,7 @@ implementation
|
|
CommonObjSymbols.free;
|
|
CommonObjSymbols.free;
|
|
ExeVTableList.free;
|
|
ExeVTableList.free;
|
|
FExeSectionList.free;
|
|
FExeSectionList.free;
|
|
|
|
+ ComdatGroups.free;
|
|
ObjDatalist.free;
|
|
ObjDatalist.free;
|
|
FWriter.free;
|
|
FWriter.free;
|
|
inherited destroy;
|
|
inherited destroy;
|
|
@@ -2229,6 +2254,7 @@ implementation
|
|
hs : string;
|
|
hs : string;
|
|
exesym : TExeSymbol;
|
|
exesym : TExeSymbol;
|
|
objsym : TObjSymbol;
|
|
objsym : TObjSymbol;
|
|
|
|
+ grp : TObjSectionGroup;
|
|
begin
|
|
begin
|
|
for j:=0 to ObjData.ObjSymbolList.Count-1 do
|
|
for j:=0 to ObjData.ObjSymbolList.Count-1 do
|
|
begin
|
|
begin
|
|
@@ -2256,6 +2282,30 @@ implementation
|
|
end;
|
|
end;
|
|
continue;
|
|
continue;
|
|
end;
|
|
end;
|
|
|
|
+
|
|
|
|
+ { If this symbol comes from COMDAT group, see if a group with
|
|
|
|
+ matching signature is already included. }
|
|
|
|
+ if assigned(objsym.objsection) and
|
|
|
|
+ assigned(objsym.objsection.group) then
|
|
|
|
+ begin
|
|
|
|
+ grp:=objsym.objsection.group;
|
|
|
|
+ if grp.IsComdat then
|
|
|
|
+ begin
|
|
|
|
+ if ComdatGroups.Find(grp.name)=nil then
|
|
|
|
+ ComdatGroups.Add(grp.name,grp)
|
|
|
|
+ else
|
|
|
|
+ begin
|
|
|
|
+ { Undefine the symbol, causing relocations to it from same
|
|
|
|
+ objdata to be redirected to the symbol in the actually
|
|
|
|
+ linked group. }
|
|
|
|
+ if objsym.bind=AB_GLOBAL then
|
|
|
|
+ objsym.bind:=AB_EXTERNAL;
|
|
|
|
+ { AB_WEAK_EXTERNAL remains unchanged }
|
|
|
|
+ objsym.objsection:=nil;
|
|
|
|
+ end;
|
|
|
|
+ end;
|
|
|
|
+ end;
|
|
|
|
+
|
|
{ Search for existing exesymbol }
|
|
{ Search for existing exesymbol }
|
|
exesym:=texesymbol(FExeSymbolList.Find(objsym.name));
|
|
exesym:=texesymbol(FExeSymbolList.Find(objsym.name));
|
|
if not assigned(exesym) then
|
|
if not assigned(exesym) then
|