|
@@ -91,6 +91,8 @@ interface
|
|
|
Function MakeStaticLibrary:boolean;override;
|
|
|
|
|
|
Function UniqueName(const str:TCmdStr): TCmdStr;
|
|
|
+
|
|
|
+ function PostProcessELFExecutable(const fn: string; isdll: boolean): boolean;
|
|
|
end;
|
|
|
|
|
|
TBooleanArray = array [1..1024] of boolean;
|
|
@@ -988,6 +990,161 @@ Implementation
|
|
|
end;
|
|
|
|
|
|
|
|
|
+ function TExternalLinker.PostProcessELFExecutable(const fn : string;isdll:boolean):boolean;
|
|
|
+ type
|
|
|
+ TElf32header=packed record
|
|
|
+ magic0123 : longint;
|
|
|
+ file_class : byte;
|
|
|
+ data_encoding : byte;
|
|
|
+ file_version : byte;
|
|
|
+ padding : array[$07..$0f] of byte;
|
|
|
+
|
|
|
+ e_type : word;
|
|
|
+ e_machine : word;
|
|
|
+ e_version : longint;
|
|
|
+ e_entry : longint; { entrypoint }
|
|
|
+ e_phoff : longint; { program header offset }
|
|
|
+
|
|
|
+ e_shoff : longint; { sections header offset }
|
|
|
+ e_flags : longint;
|
|
|
+ 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;
|
|
|
+ TElf32sechdr=packed record
|
|
|
+ sh_name : longint;
|
|
|
+ sh_type : longint;
|
|
|
+ sh_flags : longint;
|
|
|
+ sh_addr : longint;
|
|
|
+
|
|
|
+ sh_offset : longint;
|
|
|
+ sh_size : longint;
|
|
|
+ sh_link : longint;
|
|
|
+ sh_info : longint;
|
|
|
+
|
|
|
+ sh_addralign : longint;
|
|
|
+ sh_entsize : longint;
|
|
|
+ end;
|
|
|
+
|
|
|
+ function MayBeSwapHeader(h : telf32header) : telf32header;
|
|
|
+ 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;
|
|
|
+ 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;
|
|
|
+
|
|
|
+ function ReadSectionName(pos : longint) : String;
|
|
|
+ var
|
|
|
+ oldpos : longint;
|
|
|
+ c : char;
|
|
|
+ begin
|
|
|
+ oldpos:=filepos(f);
|
|
|
+ seek(f,pos);
|
|
|
+ Result:='';
|
|
|
+ while true do
|
|
|
+ begin
|
|
|
+ blockread(f,c,1);
|
|
|
+ if c=#0 then
|
|
|
+ break;
|
|
|
+ Result:=Result+c;
|
|
|
+ end;
|
|
|
+ seek(f,oldpos);
|
|
|
+ end;
|
|
|
+
|
|
|
+ var
|
|
|
+ elfheader : TElf32header;
|
|
|
+ secheader : TElf32sechdr;
|
|
|
+ i : longint;
|
|
|
+ stringoffset : longint;
|
|
|
+ secname : string;
|
|
|
+ begin
|
|
|
+ Result:=false;
|
|
|
+ { open file }
|
|
|
+ assign(f,fn);
|
|
|
+ {$push}{$I-}
|
|
|
+ reset(f,1);
|
|
|
+ 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;
|
|
|
+
|
|
|
+ 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;
|
|
|
+
|
|
|
+ end;
|
|
|
+ close(f);
|
|
|
+ {$pop}
|
|
|
+ if ioresult<>0 then
|
|
|
+ ;
|
|
|
+ Result:=true;
|
|
|
+ end;
|
|
|
{*****************************************************************************
|
|
|
TINTERNALLINKER
|
|
|
*****************************************************************************}
|