mirror of
https://gitlab.com/freepascal.org/fpc/source.git
synced 2025-04-21 13:09:32 +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);
|
||||
property Name:TSymStr read GetName;
|
||||
property Hash:Longword read GetHash;
|
||||
property OwnerList: TFPHashObjectList read FOwner;
|
||||
end;
|
||||
|
||||
TFPHashObjectList = class(TObject)
|
||||
|
@ -169,6 +169,7 @@ interface
|
||||
constructor create(AList:TFPHashObjectList;const AName:string);
|
||||
function address:aword;
|
||||
procedure SetAddress(apass:byte;aobjsec:TObjSection;abind:TAsmsymbind;atyp:Tasmsymtype);
|
||||
function ObjData: TObjData;
|
||||
end;
|
||||
|
||||
{ Stabs is common for all targets }
|
||||
@ -256,13 +257,18 @@ interface
|
||||
|
||||
TString80 = string[80];
|
||||
|
||||
TObjSymbolList = class(TFPHashObjectList)
|
||||
public
|
||||
Owner: TObjData;
|
||||
end;
|
||||
|
||||
TObjData = class(TLinkedListItem)
|
||||
private
|
||||
FCurrObjSec : TObjSection;
|
||||
FObjSectionList : TFPHashObjectList;
|
||||
FCObjSection : TObjSectionClass;
|
||||
{ Symbols that will be defined in this object file }
|
||||
FObjSymbolList : TFPHashObjectList;
|
||||
FObjSymbolList : TObjSymbolList;
|
||||
FCachedAsmSymbolList : TFPObjectList;
|
||||
{ Special info sections that are written to during object generation }
|
||||
FStabsObjSec,
|
||||
@ -309,7 +315,7 @@ interface
|
||||
procedure layoutsections(var datapos:aword);
|
||||
property Name:TString80 read FName;
|
||||
property CurrObjSec:TObjSection read FCurrObjSec;
|
||||
property ObjSymbolList:TFPHashObjectList read FObjSymbolList;
|
||||
property ObjSymbolList:TObjSymbolList read FObjSymbolList;
|
||||
property ObjSectionList:TFPHashObjectList read FObjSectionList;
|
||||
property GroupsList:TFPHashObjectList read FGroupsList;
|
||||
property StabsSec:TObjSection read FStabsObjSec write FStabsObjSec;
|
||||
@ -522,6 +528,7 @@ interface
|
||||
procedure DoRelocationFixup(objsec:TObjSection);virtual;abstract;
|
||||
function MemAlign(exesec: TExeSection): longword;
|
||||
function DataAlign(exesec: TExeSection): longword;
|
||||
procedure ReplaceExeSectionList(newlist: TFPList);
|
||||
public
|
||||
CurrDataPos : aword;
|
||||
MaxMemPos : qword;
|
||||
@ -707,6 +714,12 @@ implementation
|
||||
offset:=aobjsec.size;
|
||||
end;
|
||||
|
||||
|
||||
function TObjSymbol.ObjData: TObjData;
|
||||
begin
|
||||
result:=(OwnerList as TObjSymbolList).Owner;
|
||||
end;
|
||||
|
||||
{****************************************************************************
|
||||
TObjRelocation
|
||||
****************************************************************************}
|
||||
@ -960,7 +973,8 @@ implementation
|
||||
FStabsObjSec:=nil;
|
||||
FStabStrObjSec:=nil;
|
||||
{ symbols }
|
||||
FObjSymbolList:=TFPHashObjectList.Create(true);
|
||||
FObjSymbolList:=TObjSymbolList.Create(true);
|
||||
FObjSymbolList.Owner:=Self;
|
||||
FCachedAsmSymbolList:=TFPObjectList.Create(false);
|
||||
{ section class type for creating of new sections }
|
||||
FCObjSection:=TObjSection;
|
||||
@ -2524,7 +2538,7 @@ implementation
|
||||
commonsym.size:=objsym.size;
|
||||
internalObjData.alloc(objsym.size);
|
||||
if assigned(exemap) then
|
||||
exemap.AddCommonSymbol(commonsym);
|
||||
exemap.AddCommonSymbol(objsym);
|
||||
{ Assign to the exesymbol }
|
||||
objsym.exesymbol.objsymbol:=commonsym;
|
||||
objsym.exesymbol.state:=symstate_defined;
|
||||
@ -3290,6 +3304,22 @@ implementation
|
||||
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
|
||||
****************************************************************************}
|
||||
|
@ -271,6 +271,7 @@ interface
|
||||
procedure WriteShstrtab;
|
||||
procedure FixupSectionLinks;
|
||||
procedure InitDynlink;
|
||||
procedure OrderOrphanSections;
|
||||
protected
|
||||
dynamiclink: boolean;
|
||||
hastextrelocs: boolean;
|
||||
@ -2348,6 +2349,7 @@ implementation
|
||||
end;
|
||||
|
||||
begin
|
||||
OrderOrphanSections;
|
||||
inherited Order_end;
|
||||
set_oso_keep('.init');
|
||||
set_oso_keep('.fini');
|
||||
@ -2366,6 +2368,90 @@ implementation
|
||||
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;
|
||||
var
|
||||
i:longint;
|
||||
|
@ -145,7 +145,7 @@ implementation
|
||||
writeln(t,p.name);
|
||||
s:='';
|
||||
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;
|
||||
|
||||
|
||||
|
@ -1380,20 +1380,6 @@ begin
|
||||
Concat('EXESECTION .text');
|
||||
Concat(' OBJSECTION .text*');
|
||||
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(' OBJSECTION .fini');
|
||||
Concat(' PROVIDE __etext');
|
||||
@ -1494,13 +1480,6 @@ begin
|
||||
Concat(' SYMBOL _end');
|
||||
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,'+
|
||||
'.debug_abbrev,.debug_line,.debug_frame,.debug_str,.debug_loc,'+
|
||||
'.debug_macinfo,.debug_weaknames,.debug_funcnames,.debug_typenames,.debug_varnames,.debug_ranges');
|
||||
|
Loading…
Reference in New Issue
Block a user