mirror of
https://gitlab.com/freepascal.org/fpc/source.git
synced 2025-12-03 00:07:28 +01:00
+ read 64-Bit ELF executable info correctly
git-svn-id: trunk@47695 -
This commit is contained in:
parent
e60a367f1b
commit
7da0284bfc
@ -993,7 +993,7 @@ Implementation
|
||||
function TExternalLinker.PostProcessELFExecutable(const fn : string;isdll:boolean):boolean;
|
||||
type
|
||||
TElf32header=packed record
|
||||
magic0123 : longint;
|
||||
magic0123 : array[0..3] of char;
|
||||
file_class : byte;
|
||||
data_encoding : byte;
|
||||
file_version : byte;
|
||||
@ -1029,6 +1029,41 @@ Implementation
|
||||
sh_entsize : longint;
|
||||
end;
|
||||
|
||||
telf64header=packed record
|
||||
magic0123 : array[0..3] of char;
|
||||
file_class : byte;
|
||||
data_encoding : byte;
|
||||
file_version : byte;
|
||||
padding : array[$07..$0f] of byte;
|
||||
|
||||
e_type : word;
|
||||
e_machine : word;
|
||||
e_version : longword;
|
||||
e_entry : qword; { entrypoint }
|
||||
e_phoff : qword; { program header offset }
|
||||
e_shoff : qword; { sections header offset }
|
||||
e_flags : longword;
|
||||
e_ehsize : word; { elf header size in bytes }
|
||||
e_phentsize : word; { size of an entry in the program header array }
|
||||
e_phnum : word; { 0..e_phnum-1 of entrys }
|
||||
e_shentsize : word; { size of an entry in sections header array }
|
||||
e_shnum : word; { 0..e_shnum-1 of entrys }
|
||||
e_shstrndx : word; { index of string section header }
|
||||
end;
|
||||
TElf64sechdr=packed record
|
||||
sh_name : longword;
|
||||
sh_type : longword;
|
||||
sh_flags : qword;
|
||||
sh_addr : qword;
|
||||
sh_offset : qword;
|
||||
sh_size : qword;
|
||||
sh_link : longword;
|
||||
sh_info : longword;
|
||||
sh_addralign : qword;
|
||||
sh_entsize : qword;
|
||||
end;
|
||||
|
||||
|
||||
function MayBeSwapHeader(h : telf32header) : telf32header;
|
||||
begin
|
||||
result:=h;
|
||||
@ -1051,6 +1086,30 @@ Implementation
|
||||
end;
|
||||
end;
|
||||
|
||||
|
||||
function MayBeSwapHeader(h : telf64header) : telf64header;
|
||||
begin
|
||||
result:=h;
|
||||
if source_info.endian<>target_info.endian then
|
||||
with h do
|
||||
begin
|
||||
result.e_type:=swapendian(e_type);
|
||||
result.e_machine:=swapendian(e_machine);
|
||||
result.e_version:=swapendian(e_version);
|
||||
result.e_entry:=swapendian(e_entry);
|
||||
result.e_phoff:=swapendian(e_phoff);
|
||||
result.e_shoff:=swapendian(e_shoff);
|
||||
result.e_flags:=swapendian(e_flags);
|
||||
result.e_ehsize:=swapendian(e_ehsize);
|
||||
result.e_phentsize:=swapendian(e_phentsize);
|
||||
result.e_phnum:=swapendian(e_phnum);
|
||||
result.e_shentsize:=swapendian(e_shentsize);
|
||||
result.e_shnum:=swapendian(e_shnum);
|
||||
result.e_shstrndx:=swapendian(e_shstrndx);
|
||||
end;
|
||||
end;
|
||||
|
||||
|
||||
function MaybeSwapSecHeader(h : telf32sechdr) : telf32sechdr;
|
||||
begin
|
||||
result:=h;
|
||||
@ -1070,6 +1129,26 @@ Implementation
|
||||
end;
|
||||
end;
|
||||
|
||||
|
||||
function MaybeSwapSecHeader(h : telf64sechdr) : telf64sechdr;
|
||||
begin
|
||||
result:=h;
|
||||
if source_info.endian<>target_info.endian then
|
||||
with h do
|
||||
begin
|
||||
result.sh_name:=swapendian(sh_name);
|
||||
result.sh_type:=swapendian(sh_type);
|
||||
result.sh_flags:=swapendian(sh_flags);
|
||||
result.sh_addr:=swapendian(sh_addr);
|
||||
result.sh_offset:=swapendian(sh_offset);
|
||||
result.sh_size:=swapendian(sh_size);
|
||||
result.sh_link:=swapendian(sh_link);
|
||||
result.sh_info:=swapendian(sh_info);
|
||||
result.sh_addralign:=swapendian(sh_addralign);
|
||||
result.sh_entsize:=swapendian(sh_entsize);
|
||||
end;
|
||||
end;
|
||||
|
||||
var
|
||||
f : file;
|
||||
|
||||
@ -1092,8 +1171,10 @@ Implementation
|
||||
end;
|
||||
|
||||
var
|
||||
elfheader : TElf32header;
|
||||
secheader : TElf32sechdr;
|
||||
elfheader32 : TElf32header;
|
||||
secheader32 : TElf32sechdr;
|
||||
elfheader64 : TElf64header;
|
||||
secheader64 : TElf64sechdr;
|
||||
i : longint;
|
||||
stringoffset : longint;
|
||||
secname : string;
|
||||
@ -1106,39 +1187,95 @@ Implementation
|
||||
if ioresult<>0 then
|
||||
Message1(execinfo_f_cant_open_executable,fn);
|
||||
{ read header }
|
||||
blockread(f,elfheader,sizeof(tElf32header));
|
||||
elfheader:=MayBeSwapHeader(elfheader);
|
||||
seek(f,elfheader.e_shoff);
|
||||
{ read string section header }
|
||||
seek(f,elfheader.e_shoff+sizeof(TElf32sechdr)*elfheader.e_shstrndx);
|
||||
blockread(f,secheader,sizeof(secheader));
|
||||
secheader:=MaybeSwapSecHeader(secheader);
|
||||
stringoffset:=secheader.sh_offset;
|
||||
blockread(f,elfheader32,sizeof(tElf32header));
|
||||
with elfheader32 do
|
||||
if not((magic0123[0]=#$7f) and (magic0123[1]='E') and (magic0123[2]='L') and (magic0123[3]='F')) then
|
||||
Exit;
|
||||
case elfheader32.file_class of
|
||||
1:
|
||||
begin
|
||||
elfheader32:=MayBeSwapHeader(elfheader32);
|
||||
seek(f,elfheader32.e_shoff);
|
||||
{ read string section header }
|
||||
seek(f,elfheader32.e_shoff+sizeof(TElf32sechdr)*elfheader32.e_shstrndx);
|
||||
blockread(f,secheader32,sizeof(secheader32));
|
||||
secheader32:=MaybeSwapSecHeader(secheader32);
|
||||
stringoffset:=secheader32.sh_offset;
|
||||
|
||||
seek(f,elfheader.e_shoff);
|
||||
status.datasize:=0;
|
||||
for i:=0 to elfheader.e_shnum-1 do
|
||||
begin
|
||||
blockread(f,secheader,sizeof(secheader));
|
||||
secheader:=MaybeSwapSecHeader(secheader);
|
||||
secname:=ReadSectionName(stringoffset+secheader.sh_name);
|
||||
if secname='.text' then
|
||||
begin
|
||||
Message1(execinfo_x_codesize,tostr(secheader.sh_size));
|
||||
status.codesize:=secheader.sh_size;
|
||||
end
|
||||
else if secname='.data' then
|
||||
begin
|
||||
Message1(execinfo_x_initdatasize,tostr(secheader.sh_size));
|
||||
inc(status.datasize,secheader.sh_size);
|
||||
end
|
||||
else if secname='.bss' then
|
||||
begin
|
||||
Message1(execinfo_x_uninitdatasize,tostr(secheader.sh_size));
|
||||
inc(status.datasize,secheader.sh_size);
|
||||
end;
|
||||
seek(f,elfheader32.e_shoff);
|
||||
status.datasize:=0;
|
||||
for i:=0 to elfheader32.e_shnum-1 do
|
||||
begin
|
||||
blockread(f,secheader32,sizeof(secheader32));
|
||||
secheader32:=MaybeSwapSecHeader(secheader32);
|
||||
secname:=ReadSectionName(stringoffset+secheader32.sh_name);
|
||||
case secname of
|
||||
'.text':
|
||||
begin
|
||||
Message1(execinfo_x_codesize,tostr(secheader32.sh_size));
|
||||
status.codesize:=secheader32.sh_size;
|
||||
end;
|
||||
'.fpcdata',
|
||||
'.rodata',
|
||||
'.data':
|
||||
begin
|
||||
Message1(execinfo_x_initdatasize,tostr(secheader32.sh_size));
|
||||
inc(status.datasize,secheader32.sh_size);
|
||||
end;
|
||||
'.bss':
|
||||
begin
|
||||
Message1(execinfo_x_uninitdatasize,tostr(secheader32.sh_size));
|
||||
inc(status.datasize,secheader32.sh_size);
|
||||
end;
|
||||
end;
|
||||
end;
|
||||
end;
|
||||
2:
|
||||
begin
|
||||
seek(f,0);
|
||||
blockread(f,elfheader64,sizeof(tElf64header));
|
||||
with elfheader64 do
|
||||
if not((magic0123[0]=#$7f) and (magic0123[1]='E') and (magic0123[2]='L') and (magic0123[3]='F')) then
|
||||
Exit;
|
||||
elfheader64:=MayBeSwapHeader(elfheader64);
|
||||
seek(f,elfheader64.e_shoff);
|
||||
{ read string section header }
|
||||
seek(f,elfheader64.e_shoff+sizeof(TElf64sechdr)*elfheader64.e_shstrndx);
|
||||
blockread(f,secheader64,sizeof(secheader64));
|
||||
secheader64:=MaybeSwapSecHeader(secheader64);
|
||||
stringoffset:=secheader64.sh_offset;
|
||||
|
||||
end;
|
||||
seek(f,elfheader64.e_shoff);
|
||||
status.datasize:=0;
|
||||
for i:=0 to elfheader64.e_shnum-1 do
|
||||
begin
|
||||
blockread(f,secheader64,sizeof(secheader64));
|
||||
secheader64:=MaybeSwapSecHeader(secheader64);
|
||||
secname:=ReadSectionName(stringoffset+secheader64.sh_name);
|
||||
case secname of
|
||||
'.text':
|
||||
begin
|
||||
Message1(execinfo_x_codesize,tostr(secheader64.sh_size));
|
||||
status.codesize:=secheader64.sh_size;
|
||||
end;
|
||||
'.fpcdata',
|
||||
'.rodata',
|
||||
'.data':
|
||||
begin
|
||||
Message1(execinfo_x_initdatasize,tostr(secheader64.sh_size));
|
||||
inc(status.datasize,secheader64.sh_size);
|
||||
end;
|
||||
'.bss':
|
||||
begin
|
||||
Message1(execinfo_x_uninitdatasize,tostr(secheader64.sh_size));
|
||||
inc(status.datasize,secheader64.sh_size);
|
||||
end;
|
||||
end;
|
||||
end;
|
||||
end;
|
||||
else
|
||||
exit;
|
||||
end;
|
||||
close(f);
|
||||
{$pop}
|
||||
if ioresult<>0 then
|
||||
|
||||
@ -816,7 +816,8 @@ begin
|
||||
{ Post process,
|
||||
as it only writes sections sizes so far, do this only if V_Info is set }
|
||||
if success and CheckVerbosity(V_Info) and not(cs_link_nolink in current_settings.globalswitches) then
|
||||
success:=PostProcessExecutable(current_module.exefilename,false);
|
||||
{ do not change success here as we are only writing some info, so if this fails, it does not matter }
|
||||
{ success:= }PostProcessExecutable(current_module.exefilename,false);
|
||||
|
||||
MakeExecutable:=success; { otherwise a recursive call to link method }
|
||||
end;
|
||||
|
||||
Loading…
Reference in New Issue
Block a user