* Moved 4 procedures for basic reading/writing TObjSection contents into ogcoff.pas, so they don't have to be reimplemented for every output format.

git-svn-id: trunk@21492 -
This commit is contained in:
sergei 2012-06-05 19:52:40 +00:00
parent efe5362670
commit 7d3294b504
3 changed files with 105 additions and 118 deletions

View File

@ -273,6 +273,7 @@ interface
procedure afteralloc;virtual; procedure afteralloc;virtual;
procedure afterwrite;virtual; procedure afterwrite;virtual;
procedure resetsections; procedure resetsections;
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:TFPHashObjectList read FObjSymbolList;
@ -290,6 +291,7 @@ interface
FWriter : TObjectwriter; FWriter : TObjectwriter;
function writeData(Data:TObjData):boolean;virtual;abstract; function writeData(Data:TObjData):boolean;virtual;abstract;
property CObjData : TObjDataClass read FCObjData write FCObjData; property CObjData : TObjDataClass read FCObjData write FCObjData;
procedure WriteSectionContent(Data:TObjData);
public public
constructor create(AWriter:TObjectWriter);virtual; constructor create(AWriter:TObjectWriter);virtual;
destructor destroy;override; destructor destroy;override;
@ -309,6 +311,7 @@ interface
FReader : TObjectReader; FReader : TObjectReader;
InputFileName : string; InputFileName : string;
property CObjData : TObjDataClass read FCObjData write FCObjData; property CObjData : TObjDataClass read FCObjData write FCObjData;
procedure ReadSectionContent(Data:TObjData);
public public
constructor create;virtual; constructor create;virtual;
destructor destroy;override; destructor destroy;override;
@ -440,6 +443,7 @@ interface
property CExeSection:TExeSectionClass read FCExeSection write FCExeSection; property CExeSection:TExeSectionClass read FCExeSection write FCExeSection;
property CObjData:TObjDataClass read FCObjData write FCObjData; property CObjData:TObjDataClass read FCObjData write FCObjData;
procedure Order_ObjSectionList(ObjSectionList : TFPObjectList; const aPattern:string);virtual; procedure Order_ObjSectionList(ObjSectionList : TFPObjectList; const aPattern:string);virtual;
procedure WriteExeSectionContent;
public public
CurrDataPos : aword; CurrDataPos : aword;
MaxMemPos : qword; MaxMemPos : qword;
@ -1248,6 +1252,15 @@ implementation
end; end;
procedure TObjData.layoutsections(var DataPos:aword);
var
i: longint;
begin
for i:=0 to FObjSectionList.Count-1 do
TObjSection(FObjSectionList[i]).setDatapos(DataPos);
end;
{**************************************************************************** {****************************************************************************
TObjOutput TObjOutput
****************************************************************************} ****************************************************************************}
@ -1304,6 +1317,25 @@ implementation
FWriter.writesym(p.name); FWriter.writesym(p.name);
end; end;
procedure TObjOutput.WriteSectionContent(Data:TObjData);
var
i:longint;
sec:TObjSection;
begin
for i:=0 to Data.ObjSectionList.Count-1 do
begin
sec:=TObjSection(Data.ObjSectionList[i]);
if (oso_data in sec.SecOptions) then
begin
if sec.Data=nil then
internalerror(200403073);
FWriter.writezeros(sec.dataalignbytes);
if sec.Datapos<>FWriter.ObjSize then
internalerror(200604031);
FWriter.writearray(sec.data);
end;
end;
end;
{**************************************************************************** {****************************************************************************
TExeVTable TExeVTable
@ -2823,6 +2855,45 @@ implementation
end; end;
procedure TExeOutput.WriteExeSectionContent;
var
exesec : TExeSection;
objsec : TObjSection;
i,j : longint;
begin
for j:=0 to ExeSectionList.Count-1 do
begin
exesec:=TExeSection(ExeSectionList[j]);
{ don't write normal section if writing only debug info }
if (ExeWriteMode=ewm_dbgonly) and
not(oso_debug in exesec.SecOptions) then
exit;
if oso_data in exesec.SecOptions then
begin
FWriter.Writezeros(Align(FWriter.Size,SectionDataAlign)-FWriter.Size);
for i:=0 to exesec.ObjSectionList.Count-1 do
begin
objsec:=TObjSection(exesec.ObjSectionList[i]);
if oso_data in objsec.secoptions then
begin
if not assigned(objsec.data) then
internalerror(200603042);
FWriter.writezeros(objsec.dataalignbytes);
if objsec.DataPos<>FWriter.Size then
begin
writeln(objsec.name,' ',hexstr(objsec.datapos,8),' should be: ',hexstr(fwriter.size,8));
internalerror(200602251);
end;
FWriter.writearray(objsec.data);
end;
end;
end;
end;
end;
{**************************************************************************** {****************************************************************************
TObjInput TObjInput
****************************************************************************} ****************************************************************************}
@ -2850,6 +2921,33 @@ implementation
end; end;
procedure TObjInput.ReadSectionContent(Data:TObjData);
var
i: longint;
sec: TObjSection;
begin
for i:=0 to Data.ObjSectionList.Count-1 do
begin
sec:=TObjSection(Data.ObjSectionList[i]);
{ Skip debug sections }
if (oso_debug in sec.SecOptions) and
(cs_link_strip in current_settings.globalswitches) and
not(cs_link_separate_dbg_file in current_settings.globalswitches) then
continue;
if assigned(sec.Data) then
begin
FReader.Seek(sec.datapos);
if not FReader.ReadArray(sec.data,sec.Size) then
begin
InputError('Can''t read object data');
exit;
end;
end;
end;
end;
{$ifdef MEMDEBUG} {$ifdef MEMDEBUG}
initialization initialization
memobjsymbols:=TMemDebug.create('ObjSymbols'); memobjsymbols:=TMemDebug.create('ObjSymbols');

View File

@ -108,7 +108,6 @@ interface
coffrelocpos : aword; coffrelocpos : aword;
public public
secidx : longword; secidx : longword;
flags : longword;
constructor create(AList:TFPHashObjectList;const Aname:string;Aalign:shortint;Aoptions:TObjSectionOptions);override; constructor create(AList:TFPHashObjectList;const Aname:string;Aalign:shortint;Aoptions:TObjSectionOptions);override;
procedure addsymsizereloc(ofs:aword;p:TObjSymbol;symsize:aword;reloctype:TObjRelocationType); procedure addsymsizereloc(ofs:aword;p:TObjSymbol;symsize:aword;reloctype:TObjRelocationType);
procedure fixuprelocs;override; procedure fixuprelocs;override;
@ -154,10 +153,8 @@ interface
procedure section_write_symbol(p:TObject;arg:pointer); procedure section_write_symbol(p:TObject;arg:pointer);
procedure section_write_relocs(p:TObject;arg:pointer); procedure section_write_relocs(p:TObject;arg:pointer);
procedure create_symbols(data:TObjData); procedure create_symbols(data:TObjData);
procedure section_set_datapos(p:TObject;arg:pointer);
procedure section_set_reloc_datapos(p:TObject;arg:pointer); procedure section_set_reloc_datapos(p:TObject;arg:pointer);
procedure section_write_header(p:TObject;arg:pointer); procedure section_write_header(p:TObject;arg:pointer);
procedure section_write_data(p:TObject;arg:pointer);
protected protected
function writedata(data:TObjData):boolean;override; function writedata(data:TObjData):boolean;override;
public public
@ -187,7 +184,6 @@ interface
function Read_str(strpos:longword):string; function Read_str(strpos:longword):string;
procedure read_relocs(s:TCoffObjSection); procedure read_relocs(s:TCoffObjSection);
procedure read_symbols(objdata:TObjData); procedure read_symbols(objdata:TObjData);
procedure ObjSections_read_data(p:TObject;arg:pointer);
procedure ObjSections_read_relocs(p:TObject;arg:pointer); procedure ObjSections_read_relocs(p:TObject;arg:pointer);
public public
constructor createcoff(awin32:boolean); constructor createcoff(awin32:boolean);
@ -231,7 +227,6 @@ interface
procedure write_symbol(const name:string;value:aword;section:smallint;typ,aux:byte); procedure write_symbol(const name:string;value:aword;section:smallint;typ,aux:byte);
procedure globalsyms_write_symbol(p:TObject;arg:pointer); procedure globalsyms_write_symbol(p:TObject;arg:pointer);
procedure ExeSectionList_write_header(p:TObject;arg:pointer); procedure ExeSectionList_write_header(p:TObject;arg:pointer);
procedure ExeSectionList_write_data(p:TObject;arg:pointer);
protected protected
function writedata:boolean;override; function writedata:boolean;override;
procedure Order_ObjSectionList(ObjSectionList : TFPObjectList;const aPattern:string);override; procedure Order_ObjSectionList(ObjSectionList : TFPObjectList;const aPattern:string);override;
@ -1418,12 +1413,6 @@ const pemagic : array[0..3] of byte = (
end; end;
procedure TCoffObjOutput.section_set_datapos(p:TObject;arg:pointer);
begin
TObjSection(p).setdatapos(paword(arg)^);
end;
procedure TCoffObjOutput.section_set_reloc_datapos(p:TObject;arg:pointer); procedure TCoffObjOutput.section_set_reloc_datapos(p:TObject;arg:pointer);
begin begin
TCoffObjSection(p).coffrelocpos:=paint(arg)^; TCoffObjSection(p).coffrelocpos:=paint(arg)^;
@ -1474,21 +1463,6 @@ const pemagic : array[0..3] of byte = (
end; end;
procedure TCoffObjOutput.section_write_data(p:TObject;arg:pointer);
begin
with TObjSection(p) do
begin
if assigned(data) then
begin
FWriter.writezeros(dataalignbytes);
if Datapos<>FWriter.ObjSize then
internalerror(200603052);
FWriter.writearray(data);
end;
end;
end;
function TCoffObjOutput.writedata(data:TObjData):boolean; function TCoffObjOutput.writedata(data:TObjData):boolean;
var var
orgdatapos, orgdatapos,
@ -1509,7 +1483,7 @@ const pemagic : array[0..3] of byte = (
{ Calculate the filepositions } { Calculate the filepositions }
datapos:=sizeof(tcoffheader)+sizeof(tcoffsechdr)*ObjSectionList.Count; datapos:=sizeof(tcoffheader)+sizeof(tcoffsechdr)*ObjSectionList.Count;
{ Sections first } { Sections first }
ObjSectionList.ForEachCall(@section_set_datapos,@datapos); layoutsections(datapos);
{ relocs } { relocs }
orgdatapos:=datapos; orgdatapos:=datapos;
ObjSectionList.ForEachCall(@section_set_reloc_datapos,@datapos); ObjSectionList.ForEachCall(@section_set_reloc_datapos,@datapos);
@ -1545,7 +1519,7 @@ const pemagic : array[0..3] of byte = (
{ Section headers } { Section headers }
ObjSectionList.ForEachCall(@section_write_header,nil); ObjSectionList.ForEachCall(@section_write_header,nil);
{ ObjSections } { ObjSections }
ObjSectionList.ForEachCall(@section_write_data,nil); WriteSectionContent(data);
{ Relocs } { Relocs }
ObjSectionList.ForEachCall(@section_write_relocs,nil); ObjSectionList.ForEachCall(@section_write_relocs,nil);
{ ObjSymbols } { ObjSymbols }
@ -1826,29 +1800,6 @@ const pemagic : array[0..3] of byte = (
end; end;
procedure TCoffObjInput.ObjSections_read_data(p:TObject;arg:pointer);
begin
with TCoffObjSection(p) do
begin
{ Skip debug sections }
if (oso_debug in secoptions) and
(cs_link_strip in current_settings.globalswitches) and
not(cs_link_separate_dbg_file in current_settings.globalswitches) then
exit;
if assigned(data) then
begin
FReader.Seek(datapos);
if not FReader.ReadArray(data,Size) then
begin
Comment(V_Error,'Error reading coff file, can''t read object data');
exit;
end;
end;
end;
end;
procedure TCoffObjInput.ObjSections_read_relocs(p:TObject;arg:pointer); procedure TCoffObjInput.ObjSections_read_relocs(p:TObject;arg:pointer);
begin begin
with TCoffObjSection(p) do with TCoffObjSection(p) do
@ -1983,7 +1934,7 @@ const pemagic : array[0..3] of byte = (
{ Insert all ObjSymbols } { Insert all ObjSymbols }
read_symbols(objdata); read_symbols(objdata);
{ Section Data } { Section Data }
ObjSectionList.ForEachCall(@objsections_read_data,nil); ReadSectionContent(objdata);
{ Relocs } { Relocs }
ObjSectionList.ForEachCall(@objsections_read_relocs,nil); ObjSectionList.ForEachCall(@objsections_read_relocs,nil);
end; end;
@ -2183,39 +2134,6 @@ const pemagic : array[0..3] of byte = (
end; end;
procedure Tcoffexeoutput.ExeSectionList_write_Data(p:TObject;arg:pointer);
var
objsec : TObjSection;
i : longint;
begin
with texesection(p) do
begin
{ don't write normal section if writing only debug info }
if (ExeWriteMode=ewm_dbgonly) and
not(oso_debug in SecOptions) then
exit;
if oso_data in secoptions then
begin
FWriter.Writezeros(Align(FWriter.Size,SectionDataAlign)-FWriter.Size);
for i:=0 to ObjSectionList.Count-1 do
begin
objsec:=TObjSection(ObjSectionList[i]);
if oso_data in objsec.secoptions then
begin
if not assigned(objsec.data) then
internalerror(200603042);
FWriter.writezeros(objsec.dataalignbytes);
if objsec.DataPos<>FWriter.Size then
internalerror(200602251);
FWriter.writearray(objsec.data);
end;
end;
end;
end;
end;
function tcoffexeoutput.totalheadersize:longword; function tcoffexeoutput.totalheadersize:longword;
var var
stubsize, stubsize,
@ -2521,7 +2439,7 @@ const pemagic : array[0..3] of byte = (
{ Section headers } { Section headers }
ExeSectionList.ForEachCall(@ExeSectionList_write_header,nil); ExeSectionList.ForEachCall(@ExeSectionList_write_header,nil);
{ Section data } { Section data }
ExeSectionList.ForEachCall(@ExeSectionList_write_data,nil); WriteExeSectionContent;
{ Align after the last section } { Align after the last section }
FWriter.Writezeros(Align(FWriter.Size,SectionDataAlign)-FWriter.Size); FWriter.Writezeros(Align(FWriter.Size,SectionDataAlign)-FWriter.Size);

View File

@ -74,14 +74,11 @@ interface
procedure createshstrtab(data:TObjData); procedure createshstrtab(data:TObjData);
procedure createsymtab(data: TObjData); procedure createsymtab(data: TObjData);
procedure writesectionheader(s:TElfObjSection); procedure writesectionheader(s:TElfObjSection);
procedure writesectiondata(s:TElfObjSection);
procedure write_internal_symbol(astridx:longint;ainfo:byte;ashndx:word); procedure write_internal_symbol(astridx:longint;ainfo:byte;ashndx:word);
procedure section_write_symbol(p:TObject;arg:pointer); procedure section_write_symbol(p:TObject;arg:pointer);
procedure section_write_sh_string(p:TObject;arg:pointer); procedure section_write_sh_string(p:TObject;arg:pointer);
procedure section_count_sections(p:TObject;arg:pointer); procedure section_count_sections(p:TObject;arg:pointer);
procedure section_create_relocsec(p:TObject;arg:pointer); procedure section_create_relocsec(p:TObject;arg:pointer);
procedure section_set_datapos(p:TObject;arg:pointer);
procedure section_write_data(p:TObject;arg:pointer);
procedure section_write_sechdr(p:TObject;arg:pointer); procedure section_write_sechdr(p:TObject;arg:pointer);
protected protected
function writedata(data:TObjData):boolean;override; function writedata(data:TObjData):boolean;override;
@ -1200,15 +1197,6 @@ implementation
end; end;
procedure TElfObjectOutput.writesectiondata(s:TElfObjSection);
begin
FWriter.writezeros(s.dataalignbytes);
if s.Datapos<>FWriter.ObjSize then
internalerror(200604031);
FWriter.writearray(s.data);
end;
procedure TElfObjectOutput.section_count_sections(p:TObject;arg:pointer); procedure TElfObjectOutput.section_count_sections(p:TObject;arg:pointer);
begin begin
TElfObjSection(p).secshidx:=pword(arg)^; TElfObjSection(p).secshidx:=pword(arg)^;
@ -1223,23 +1211,6 @@ implementation
end; end;
procedure TElfObjectOutput.section_set_datapos(p:TObject;arg:pointer);
begin
TObjSection(p).setdatapos(paword(arg)^);
end;
procedure TElfObjectOutput.section_write_data(p:TObject;arg:pointer);
begin
if (oso_data in TObjSection(p).secoptions) then
begin
if TObjSection(p).data=nil then
internalerror(200403073);
writesectiondata(TElfObjSection(p));
end;
end;
procedure TElfObjectOutput.section_write_sechdr(p:TObject;arg:pointer); procedure TElfObjectOutput.section_write_sechdr(p:TObject;arg:pointer);
begin begin
writesectionheader(TElfObjSection(p)); writesectionheader(TElfObjSection(p));
@ -1250,7 +1221,7 @@ implementation
var var
header : telfheader; header : telfheader;
shoffset, shoffset,
datapos : aint; datapos : aword;
nsections : word; nsections : word;
begin begin
result:=false; result:=false;
@ -1284,7 +1255,7 @@ implementation
{ Calculate the filepositions } { Calculate the filepositions }
datapos:=$40; { elfheader + alignment } datapos:=$40; { elfheader + alignment }
{ section data } { section data }
ObjSectionList.ForEachCall(@section_set_datapos,@datapos); layoutsections(datapos);
{ section headers } { section headers }
shoffset:=datapos; shoffset:=datapos;
inc(datapos,(nsections+1)*sizeof(telfsechdr)); inc(datapos,(nsections+1)*sizeof(telfsechdr));
@ -1319,7 +1290,7 @@ implementation
writer.write(header,sizeof(header)); writer.write(header,sizeof(header));
writer.writezeros($40-sizeof(header)); { align } writer.writezeros($40-sizeof(header)); { align }
{ Sections } { Sections }
ObjSectionList.ForEachCall(@section_write_data,nil); WriteSectionContent(data);
{ section headers, start with an empty header for sh_undef } { section headers, start with an empty header for sh_undef }
writer.writezeros(sizeof(telfsechdr)); writer.writezeros(sizeof(telfsechdr));
ObjSectionList.ForEachCall(@section_write_sechdr,nil); ObjSectionList.ForEachCall(@section_write_sechdr,nil);