Преглед на файлове

+ factor out PostProcessELFExecutable
+ write executable section size on linux

git-svn-id: trunk@47622 -

florian преди 4 години
родител
ревизия
ff87df7581
променени са 3 файла, в които са добавени 170 реда и са изтрити 152 реда
  1. 157 0
      compiler/link.pas
  2. 1 152
      compiler/systems/t_embed.pas
  3. 12 0
      compiler/systems/t_linux.pas

+ 157 - 0
compiler/link.pas

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

+ 1 - 152
compiler/systems/t_embed.pas

@@ -1664,159 +1664,8 @@ end;
 
 
 function TLinkerEmbedded.postprocessexecutable(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
-    postprocessexecutable:=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
-      ;
-    postprocessexecutable:=true;
+    Result:=PostProcessELFExecutable(fn,isdll);
   end;
 
 

+ 12 - 0
compiler/systems/t_linux.pas

@@ -49,6 +49,7 @@ interface
       reorder : boolean;
       linklibc: boolean;
       Function  WriteResponseFile(isdll:boolean) : Boolean;
+      function postprocessexecutable(const fn: string; isdll: boolean): boolean;
     public
       constructor Create;override;
       procedure SetDefaultInfo;override;
@@ -809,6 +810,11 @@ begin
   if (success) and not(cs_link_nolink in current_settings.globalswitches) then
    DeleteFile(outputexedir+Info.ResName);
 
+  { 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);
+
   MakeExecutable:=success;   { otherwise a recursive call to link method }
 end;
 
@@ -886,6 +892,12 @@ begin
   MakeSharedLibrary:=success;   { otherwise a recursive call to link method }
 end;
 
+
+function TLinkerLinux.postprocessexecutable(const fn : string;isdll:boolean):boolean;
+  begin
+    Result:=PostProcessELFExecutable(fn,isdll);
+  end;
+
 {*****************************************************************************
                               TINTERNALLINKERLINUX
 *****************************************************************************}