mirror of
https://gitlab.com/freepascal.org/fpc/source.git
synced 2025-08-13 09:39:09 +02:00
+ Property TObjSymbol.ObjData, allows to access owning TObjData for external/common symbols, i.e. ones with ObjSection=nil.
* For common symbols, report objdata of the original ObjSymbol, not of the resolving one, so the map file shows where it comes from. + TElfExeOutput.OrderOrphanSections method, handles object sections not mentioned in script similar to ld. - t_linux.pas: removed sections that are not part of ld scripts, they are now handled by OrderOrphanSections. git-svn-id: trunk@25184 -
This commit is contained in:
parent
42e82c9de3
commit
1f8a67f552
@ -273,6 +273,7 @@ type
|
|||||||
procedure Rename(const ANewName:TSymStr);
|
procedure Rename(const ANewName:TSymStr);
|
||||||
property Name:TSymStr read GetName;
|
property Name:TSymStr read GetName;
|
||||||
property Hash:Longword read GetHash;
|
property Hash:Longword read GetHash;
|
||||||
|
property OwnerList: TFPHashObjectList read FOwner;
|
||||||
end;
|
end;
|
||||||
|
|
||||||
TFPHashObjectList = class(TObject)
|
TFPHashObjectList = class(TObject)
|
||||||
|
@ -169,6 +169,7 @@ interface
|
|||||||
constructor create(AList:TFPHashObjectList;const AName:string);
|
constructor create(AList:TFPHashObjectList;const AName:string);
|
||||||
function address:aword;
|
function address:aword;
|
||||||
procedure SetAddress(apass:byte;aobjsec:TObjSection;abind:TAsmsymbind;atyp:Tasmsymtype);
|
procedure SetAddress(apass:byte;aobjsec:TObjSection;abind:TAsmsymbind;atyp:Tasmsymtype);
|
||||||
|
function ObjData: TObjData;
|
||||||
end;
|
end;
|
||||||
|
|
||||||
{ Stabs is common for all targets }
|
{ Stabs is common for all targets }
|
||||||
@ -256,13 +257,18 @@ interface
|
|||||||
|
|
||||||
TString80 = string[80];
|
TString80 = string[80];
|
||||||
|
|
||||||
|
TObjSymbolList = class(TFPHashObjectList)
|
||||||
|
public
|
||||||
|
Owner: TObjData;
|
||||||
|
end;
|
||||||
|
|
||||||
TObjData = class(TLinkedListItem)
|
TObjData = class(TLinkedListItem)
|
||||||
private
|
private
|
||||||
FCurrObjSec : TObjSection;
|
FCurrObjSec : TObjSection;
|
||||||
FObjSectionList : TFPHashObjectList;
|
FObjSectionList : TFPHashObjectList;
|
||||||
FCObjSection : TObjSectionClass;
|
FCObjSection : TObjSectionClass;
|
||||||
{ Symbols that will be defined in this object file }
|
{ Symbols that will be defined in this object file }
|
||||||
FObjSymbolList : TFPHashObjectList;
|
FObjSymbolList : TObjSymbolList;
|
||||||
FCachedAsmSymbolList : TFPObjectList;
|
FCachedAsmSymbolList : TFPObjectList;
|
||||||
{ Special info sections that are written to during object generation }
|
{ Special info sections that are written to during object generation }
|
||||||
FStabsObjSec,
|
FStabsObjSec,
|
||||||
@ -309,7 +315,7 @@ interface
|
|||||||
procedure layoutsections(var datapos:aword);
|
procedure layoutsections(var datapos:aword);
|
||||||
property Name:TString80 read FName;
|
property Name:TString80 read FName;
|
||||||
property CurrObjSec:TObjSection read FCurrObjSec;
|
property CurrObjSec:TObjSection read FCurrObjSec;
|
||||||
property ObjSymbolList:TFPHashObjectList read FObjSymbolList;
|
property ObjSymbolList:TObjSymbolList read FObjSymbolList;
|
||||||
property ObjSectionList:TFPHashObjectList read FObjSectionList;
|
property ObjSectionList:TFPHashObjectList read FObjSectionList;
|
||||||
property GroupsList:TFPHashObjectList read FGroupsList;
|
property GroupsList:TFPHashObjectList read FGroupsList;
|
||||||
property StabsSec:TObjSection read FStabsObjSec write FStabsObjSec;
|
property StabsSec:TObjSection read FStabsObjSec write FStabsObjSec;
|
||||||
@ -522,6 +528,7 @@ interface
|
|||||||
procedure DoRelocationFixup(objsec:TObjSection);virtual;abstract;
|
procedure DoRelocationFixup(objsec:TObjSection);virtual;abstract;
|
||||||
function MemAlign(exesec: TExeSection): longword;
|
function MemAlign(exesec: TExeSection): longword;
|
||||||
function DataAlign(exesec: TExeSection): longword;
|
function DataAlign(exesec: TExeSection): longword;
|
||||||
|
procedure ReplaceExeSectionList(newlist: TFPList);
|
||||||
public
|
public
|
||||||
CurrDataPos : aword;
|
CurrDataPos : aword;
|
||||||
MaxMemPos : qword;
|
MaxMemPos : qword;
|
||||||
@ -707,6 +714,12 @@ implementation
|
|||||||
offset:=aobjsec.size;
|
offset:=aobjsec.size;
|
||||||
end;
|
end;
|
||||||
|
|
||||||
|
|
||||||
|
function TObjSymbol.ObjData: TObjData;
|
||||||
|
begin
|
||||||
|
result:=(OwnerList as TObjSymbolList).Owner;
|
||||||
|
end;
|
||||||
|
|
||||||
{****************************************************************************
|
{****************************************************************************
|
||||||
TObjRelocation
|
TObjRelocation
|
||||||
****************************************************************************}
|
****************************************************************************}
|
||||||
@ -960,7 +973,8 @@ implementation
|
|||||||
FStabsObjSec:=nil;
|
FStabsObjSec:=nil;
|
||||||
FStabStrObjSec:=nil;
|
FStabStrObjSec:=nil;
|
||||||
{ symbols }
|
{ symbols }
|
||||||
FObjSymbolList:=TFPHashObjectList.Create(true);
|
FObjSymbolList:=TObjSymbolList.Create(true);
|
||||||
|
FObjSymbolList.Owner:=Self;
|
||||||
FCachedAsmSymbolList:=TFPObjectList.Create(false);
|
FCachedAsmSymbolList:=TFPObjectList.Create(false);
|
||||||
{ section class type for creating of new sections }
|
{ section class type for creating of new sections }
|
||||||
FCObjSection:=TObjSection;
|
FCObjSection:=TObjSection;
|
||||||
@ -2524,7 +2538,7 @@ implementation
|
|||||||
commonsym.size:=objsym.size;
|
commonsym.size:=objsym.size;
|
||||||
internalObjData.alloc(objsym.size);
|
internalObjData.alloc(objsym.size);
|
||||||
if assigned(exemap) then
|
if assigned(exemap) then
|
||||||
exemap.AddCommonSymbol(commonsym);
|
exemap.AddCommonSymbol(objsym);
|
||||||
{ Assign to the exesymbol }
|
{ Assign to the exesymbol }
|
||||||
objsym.exesymbol.objsymbol:=commonsym;
|
objsym.exesymbol.objsymbol:=commonsym;
|
||||||
objsym.exesymbol.state:=symstate_defined;
|
objsym.exesymbol.state:=symstate_defined;
|
||||||
@ -3290,6 +3304,22 @@ implementation
|
|||||||
end;
|
end;
|
||||||
|
|
||||||
|
|
||||||
|
procedure TExeOutput.ReplaceExeSectionList(newlist: TFPList);
|
||||||
|
var
|
||||||
|
tmp: TFPHashObjectList;
|
||||||
|
i: longint;
|
||||||
|
begin
|
||||||
|
tmp:=TFPHashObjectList.Create(true);
|
||||||
|
for i:=0 to newlist.count-1 do
|
||||||
|
TFPHashObject(newlist[i]).ChangeOwner(tmp);
|
||||||
|
{ prevent destruction of existing sections }
|
||||||
|
for i:=0 to ExeSectionList.count-1 do
|
||||||
|
ExeSectionList.List[i]:=nil;
|
||||||
|
FExeSectionList.Free;
|
||||||
|
FExeSectionList:=tmp;
|
||||||
|
end;
|
||||||
|
|
||||||
|
|
||||||
{****************************************************************************
|
{****************************************************************************
|
||||||
TObjInput
|
TObjInput
|
||||||
****************************************************************************}
|
****************************************************************************}
|
||||||
|
@ -271,6 +271,7 @@ interface
|
|||||||
procedure WriteShstrtab;
|
procedure WriteShstrtab;
|
||||||
procedure FixupSectionLinks;
|
procedure FixupSectionLinks;
|
||||||
procedure InitDynlink;
|
procedure InitDynlink;
|
||||||
|
procedure OrderOrphanSections;
|
||||||
protected
|
protected
|
||||||
dynamiclink: boolean;
|
dynamiclink: boolean;
|
||||||
hastextrelocs: boolean;
|
hastextrelocs: boolean;
|
||||||
@ -2348,6 +2349,7 @@ implementation
|
|||||||
end;
|
end;
|
||||||
|
|
||||||
begin
|
begin
|
||||||
|
OrderOrphanSections;
|
||||||
inherited Order_end;
|
inherited Order_end;
|
||||||
set_oso_keep('.init');
|
set_oso_keep('.init');
|
||||||
set_oso_keep('.fini');
|
set_oso_keep('.fini');
|
||||||
@ -2366,6 +2368,90 @@ implementation
|
|||||||
end;
|
end;
|
||||||
|
|
||||||
|
|
||||||
|
procedure TElfExeOutput.OrderOrphanSections;
|
||||||
|
var
|
||||||
|
i,j:longint;
|
||||||
|
objdata:TObjData;
|
||||||
|
objsec:TObjSection;
|
||||||
|
exesec:TExeSection;
|
||||||
|
opts:TObjSectionOptions;
|
||||||
|
s:string;
|
||||||
|
newsections,tmp:TFPHashObjectList;
|
||||||
|
allsections:TFPList;
|
||||||
|
inserts:array[0..6] of TExeSection;
|
||||||
|
idx,inspos:longint;
|
||||||
|
begin
|
||||||
|
newsections:=TFPHashObjectList.Create(false);
|
||||||
|
allsections:=TFPList.Create;
|
||||||
|
{ copy existing sections }
|
||||||
|
for i:=0 to ExeSectionList.Count-1 do
|
||||||
|
allsections.add(ExeSectionList[i]);
|
||||||
|
inserts[0]:=FindExeSection('.comment');
|
||||||
|
inserts[1]:=nil;
|
||||||
|
inserts[2]:=FindExeSection('.interp');
|
||||||
|
inserts[3]:=FindExeSection('.bss');
|
||||||
|
inserts[4]:=FindExeSection('.data');
|
||||||
|
inserts[5]:=FindExeSection('.rodata');
|
||||||
|
inserts[6]:=FindExeSection('.text');
|
||||||
|
|
||||||
|
for i:=0 to ObjDataList.Count-1 do
|
||||||
|
begin
|
||||||
|
ObjData:=TObjData(ObjDataList[i]);
|
||||||
|
for j:=0 to ObjData.ObjSectionList.Count-1 do
|
||||||
|
begin
|
||||||
|
objsec:=TObjSection(ObjData.ObjSectionList[j]);
|
||||||
|
if objsec.Used then
|
||||||
|
continue;
|
||||||
|
s:=objsec.name;
|
||||||
|
exesec:=TExeSection(newsections.Find(s));
|
||||||
|
if assigned(exesec) then
|
||||||
|
begin
|
||||||
|
exesec.AddObjSection(objsec);
|
||||||
|
continue;
|
||||||
|
end;
|
||||||
|
opts:=objsec.SecOptions*[oso_data,oso_load,oso_write,oso_executable];
|
||||||
|
if (objsec.SecOptions*[oso_load,oso_debug]=[]) then
|
||||||
|
{ non-alloc, after .comment
|
||||||
|
GNU ld places .comment between stabs and dwarf debug info }
|
||||||
|
inspos:=0
|
||||||
|
else if not (oso_load in objsec.SecOptions) then
|
||||||
|
inspos:=1 { debugging, skip }
|
||||||
|
else if (oso_load in objsec.SecOptions) and
|
||||||
|
(TElfObjSection(objsec).shtype=SHT_NOTE) then
|
||||||
|
inspos:=2 { after .interp }
|
||||||
|
else if (opts=[oso_load,oso_write]) then
|
||||||
|
inspos:=3 { after .bss }
|
||||||
|
else if (opts=[oso_data,oso_load,oso_write]) then
|
||||||
|
inspos:=4 { after .data }
|
||||||
|
else if (opts=[oso_data,oso_load]) then
|
||||||
|
inspos:=5 { rodata, relocs=??? }
|
||||||
|
else if (opts=[oso_data,oso_load,oso_executable]) then
|
||||||
|
inspos:=6 { text }
|
||||||
|
else
|
||||||
|
begin
|
||||||
|
Comment(v_debug,'Orphan section '+objsec.fullname+' has attributes that are not handled!');
|
||||||
|
continue;
|
||||||
|
end;
|
||||||
|
if (inserts[inspos]=nil) then
|
||||||
|
begin
|
||||||
|
Comment(v_debug,'Orphan section '+objsec.fullname+': nowhere to insert, ignored');
|
||||||
|
continue;
|
||||||
|
end;
|
||||||
|
idx:=allsections.IndexOf(inserts[inspos]);
|
||||||
|
exesec:=CExeSection.Create(newsections,s);
|
||||||
|
allsections.Insert(idx+1,exesec);
|
||||||
|
inserts[inspos]:=exesec;
|
||||||
|
exesec.AddObjSection(objsec);
|
||||||
|
end;
|
||||||
|
end;
|
||||||
|
{ Now replace the ExeSectionList with content of allsections }
|
||||||
|
if (newsections.count<>0) then
|
||||||
|
ReplaceExeSectionList(allsections);
|
||||||
|
newsections.Free;
|
||||||
|
allsections.Free;
|
||||||
|
end;
|
||||||
|
|
||||||
|
|
||||||
procedure TElfExeOutput.AfterUnusedSectionRemoval;
|
procedure TElfExeOutput.AfterUnusedSectionRemoval;
|
||||||
var
|
var
|
||||||
i:longint;
|
i:longint;
|
||||||
|
@ -145,7 +145,7 @@ implementation
|
|||||||
writeln(t,p.name);
|
writeln(t,p.name);
|
||||||
s:='';
|
s:='';
|
||||||
end;
|
end;
|
||||||
Add(PadSpace(s,20)+'0x'+PadSpace(sizestr(p.size),16)+p.objsection.objdata.name);
|
Add(PadSpace(s,20)+PadSpace(sizestr(p.size),16)+p.objdata.name);
|
||||||
end;
|
end;
|
||||||
|
|
||||||
|
|
||||||
|
@ -1380,20 +1380,6 @@ begin
|
|||||||
Concat('EXESECTION .text');
|
Concat('EXESECTION .text');
|
||||||
Concat(' OBJSECTION .text*');
|
Concat(' OBJSECTION .text*');
|
||||||
Concat('ENDEXESECTION');
|
Concat('ENDEXESECTION');
|
||||||
|
|
||||||
{ This is not in standard ld scripts, it is handled by 'orphan section' functionality }
|
|
||||||
Concat('EXESECTION __libc_thread_freeres_fn');
|
|
||||||
Concat(' PROVIDE __start__libc_thread_freeres_fn');
|
|
||||||
Concat(' OBJSECTION __libc_thread_freeres_fn');
|
|
||||||
Concat(' PROVIDE __stop__libc_thread_freeres_fn');
|
|
||||||
Concat('ENDEXESECTION');
|
|
||||||
|
|
||||||
Concat('EXESECTION __libc_freeres_fn');
|
|
||||||
Concat(' PROVIDE __start__libc_freeres_fn');
|
|
||||||
Concat(' OBJSECTION __libc_freeres_fn');
|
|
||||||
Concat(' PROVIDE __stop__libc_freeres_fn');
|
|
||||||
Concat('ENDEXESECTION');
|
|
||||||
|
|
||||||
Concat('EXESECTION .fini');
|
Concat('EXESECTION .fini');
|
||||||
Concat(' OBJSECTION .fini');
|
Concat(' OBJSECTION .fini');
|
||||||
Concat(' PROVIDE __etext');
|
Concat(' PROVIDE __etext');
|
||||||
@ -1494,13 +1480,6 @@ begin
|
|||||||
Concat(' SYMBOL _end');
|
Concat(' SYMBOL _end');
|
||||||
Concat('ENDEXESECTION');
|
Concat('ENDEXESECTION');
|
||||||
|
|
||||||
{ This is not in standard ld scripts, it is handled by 'orphan section' functionality }
|
|
||||||
Concat('EXESECTION __libc_freeres_ptrs');
|
|
||||||
Concat(' PROVIDE __start__libc_freeres_ptrs');
|
|
||||||
Concat(' OBJSECTION __libc_freeres_ptrs');
|
|
||||||
Concat(' PROVIDE __stop__libc_freeres_ptrs');
|
|
||||||
Concat('ENDEXESECTION');
|
|
||||||
|
|
||||||
ScriptAddGenericSections('.debug_aranges,.debug_pubnames,.debug_info,'+
|
ScriptAddGenericSections('.debug_aranges,.debug_pubnames,.debug_info,'+
|
||||||
'.debug_abbrev,.debug_line,.debug_frame,.debug_str,.debug_loc,'+
|
'.debug_abbrev,.debug_line,.debug_frame,.debug_str,.debug_loc,'+
|
||||||
'.debug_macinfo,.debug_weaknames,.debug_funcnames,.debug_typenames,.debug_varnames,.debug_ranges');
|
'.debug_macinfo,.debug_weaknames,.debug_funcnames,.debug_typenames,.debug_varnames,.debug_ranges');
|
||||||
|
Loading…
Reference in New Issue
Block a user