+ 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:
sergei 2013-07-30 09:23:48 +00:00
parent 42e82c9de3
commit 1f8a67f552
5 changed files with 122 additions and 26 deletions

View File

@ -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)

View File

@ -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
****************************************************************************}

View File

@ -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;

View File

@ -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;

View File

@ -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');