仕事の8週目で2019-2020-1 20199314「Linuxカーネルの原理と分析」

実行可能プログラムの動作、

1、次の三つのカテゴリーが含まれているELF(実行可能ファイルおよびリンク可能フォーマット)実行可能ファイルとリンク可能なファイルは、:

  1. 再配置可能ファイル(再配置可能ファイル):(.oファイルは主に)実行可能ファイル、静的ライブラリファイルまたは共有オブジェクトファイルを作成するために一緒に他のオブジェクトファイルに適したコードとデータを保持しています
  2. 実行可能ファイル(実行可能ファイル)は:一般的に結合再配置可能なファイル生成複数の実行のためのプログラムを保持している(解析され、ランタイムライブラリのシンボルを共有除く)作業の再配置とシンボル解決ファイルをすべて完了しています。
  3. 共有オブジェクトファイル(共有オブジェクトファイル):二つのリンクのリンクに適したコードとデータを保持しています。最初は、リンクエディタ(静的リンク)である、あなたは他のオブジェクトと他の再配置可能ファイルと共有オブジェクトファイルを作成することができます。第二は、動的リンカー、プロセスイメージを作成するために関節の実行可能ファイルや他の共有オブジェクト・ファイルです。

2、ELFファイル形式:

ELFファイルは、様々な身体の部分であり、以下に示すように、これらの記述は、セクション(プログラムヘッダテーブルとセクションヘッダテーブル)、及び情報ELFファイル(ELFヘッダ)の完全性を属性。

3、コンパイル

ソースコードから実行ファイルへのステッププログラム:前処理、コンパイル、アセンブリ、アダプタ - Aケーススタディのhello.c。

预处理: gcc -E hello.c -o hello.i  -m32
编译:gcc -S hello.i  -o hello.s -m32
汇编:gcc -c hello.s -o hello.o -m32
默认衔接(动态库):gcc hello.o -o hello -m32 
衔接静态库:gcc hello.o -o hello.static -m32 -static

得られたハローとハロー静的ファイルは実行可能ファイルです。実行可能ファイルにコンパイル機の内容物をさらにような情報は、文字列とデバッグ、そのようなシンボルテーブルの情報の一部を、必要とするデータ・リンクを含む、命令コードを含みます。
そのファイル形式は、下図のように。

4、静的および動的収束収束

静的リンクは:直接コンパイルコードでリンクコピー外部環境の実行速度が速くなり、低依存、最終的な実行可能ファイル、高速な読み込み速度コードの利点を実行するために必要。欠点は、複数のアプリケーションが同じライブラリ関数を使用する場合は、メモリを無駄に、複数回ロードすることができるということです。
ダイナミックリンクは:直接コンパイル時に、しかしプログラムは、オペレーティングシステムをロードするために実行したり、この情報を渡しているとき、シンボルと一連のパラメータを記録することにより、実行可能なコードをコピーしないでください。プログラムがすでにコードを実行するためにメモリにロードされた動的な共有ライブラリを実行し、最終的には、リンクの目的が実行されている達成するために指定されたコードを実行されると、オペレーティングシステムがメモリにロードするために必要な動的なライブラリを担当しています。利点は、複数のプログラムがディスク上に複製を複数格納することなく、コードの同じ部分を共有することができるということです。欠点はなく、高いライブラリの依存関係を使用するため、プログラムの初期の実装のパフォーマンスに影響を与える可能性があり、実行時にロードされます。(ダイナミックリンクと実行時ダイナミックにローディングにリンク)

図に示すように、GCC hello.o -o hello.static -static静的リンクの使用、得られた実行可能プログラムファイルは、ダイナミックリンクの100倍の大きさを発見しました。

5、動的接続

ダイナミック収束の2つのタイプがあります。

  1. 動的に実行可能な係合ロード
    動的接続2.ランタイム。

ロードが、それはプログラムの起動時に最初に提供するために、ライブラリーのニーズを呼び出し、ダイナミック収束プログラムはdllibexampleランタイムを訪問するだけで、関連する書類の実行時にそのダイナミック収束手段。

6、フォークとexecveの違いとの関係

フォーク()の場合:
1、親プロセスの子プロセスは、プロセスメモリアドレス空間にそのメモリのすべてをコピーします。親、子プロセス
「データセグメント」、「スタック・セグメント」および「コードブロック」と同一である、すなわち、子プロセスの各バイト
と親プロセス。
親プロセスの前に2、子プロセスの現在の作業ディレクトリ、umaskの値をマスクし、親プロセスと同様、フォーク()
開いているファイル記述子は、また、同一のファイルエントリに、子プロセスで開き、ポイント。
3、子プロセスは独自のプロセスIDを持っています。

EXECため():
1)、プロセスは(EXEC呼び出し、同じブロック処理メモリにコールを置き換えるために、新しいプログラムに使用する
プロセスのEXEC()は、新たなプログラムは、現在のプロセスの現在のプロセスイメージ「セグメント」に置き換え、
「スタック・セグメント」と「スニペット」バック書き換え新しいプログラム。
2、新しいIDプログラムはそのまま呼び出しのexec()プロセスのままになります。
図3は、オープンコールのexecワード)が(以前にオープンを開くために続けて記述するために(パラメータが開くようにすることができるもののように
、新たなプログラムを記述するために単語を閉じています)

実験1:

実行可能ファイルをロードするには、exec *ライブラリ関数を使用して、プログラミング、動的にリンクすると、実行時の動的な実行ファイルがロードされたとき、ダイナミックリンクライブラリは、演習をプログラミングリンクの両方を使用するダイナミックにリンク。

1、Webサイト上の2つのソースを言ったから、次のような実験の上の階をダウンロードしてください:

shlibexample.h(1.3キロバイト) -共有ライブラリの例のインタフェース
shlibexample.c(1.2 KB) -共有ライブラリの例の実装
が、後で2つのコードのための網易クラウド有料クラスアクセサリが、たとえば、そんなにお金を費やす必要はありませんことがわかりました本の源となっている、あなたがあなた自身の再を書くことができますが、コードブックは、直接実験をやって私の後ろに進行に影響を与えるピットを持って、私はそれを後で説明します。

shlibexample.h
#ifndef  _SH_LTB_EXAMPLE_H_
#define  _SH_LTB_EXAMPLE_H_
#define SUCCESS 0
#define FAILURE (-1)
#ifdef __cplusplus
extern "C" {
#endif
int SharedLibApi();
#ifdef __cplusplus
}
#endif
#endif

dllibexample.h
#ifndef  _DL_LTB_EXAMPLE_H_
#define  _DL_LTB_EXAMPLE_H_
#ifdef _cplusplus
extern "C"{
#endif
int DynamicalLoadingLibApi();
#ifdef _cplusplus
}
#endif
#endif

shlibexample.c
#include <stdio.h>
#include "shlibexample.h"
int SharedLibApi()
{
printf("This is a shared libary!\n");
return SUCCESS;
}

dllibexample.c
#include <stdio.h>
#include "dllibexample.h"
#define SUCCESS 0
#define FAILURE(-1)
int DynamicalLoadingLibApi()
{
printf(“This is a Dynamical Loading library”!\n”);
return SUCCESS;
}

2、コンパイルしたファイルlibshlibexample.so

$ gcc -shared shlibexample.c -o libshlibexample.so -m32
$ gcc -shared dllibexample.c -o libdllibexample.so -m32

私は再びので、検索Cヘッダファイル名の競合は、ああ、とにかく、答えのすべての種類は、まだ与えられている長い時間を費やして何のgccああ、更新する必要があるものの答えの多くは、エラーがここに表示するには、なぜ私がオンラインに文句を言うだろう泥棒は小さな場所を見つけるまで、本は誤解しやすい、コードを数回押してください。

注ルック!これは明らかにそれが正しいLIBだったことを見ている、私もほぼ同じ本のようにvimエディタと彼らをノックしたが、私は慎重にクロスを見て、私は少し様々な長さのクロスの下にありましたこの株式は、Tバーではありません!結果は私の判断は、この株式はT、LTBであることを検証します。最後に、その理由を発見しました

図3は、共有ライブラリのように、動的にそれぞれミアン機能は、ファイルとファイルlibdllibexample.so libshlibexample.so使用して共有ライブラリをロード

main.c
#include <stdio.h>
#include "shlibexample.h" 
#include <dlfcn.h>

int main()
{
   printf("This is a Main program!\n");
/* Use Shared Lib */
  printf("Calling SharedLibApi() function of libshlibexample.so!\n");
 SharedLibApi(); //直接调用共享库
/* Use Dynamical Loading Lib */
  void * handle = dlopen("libdllibexample.so",RTLD_NOW);//打开动态库并将其加载到内存
  if(handle == NULL)
{
    printf("Open Lib libdllibexample.so Error:%s\n",dlerror());
    return   FAILURE;
}
int (*func)(void);
char * error;
func = dlsym(handle,"DynamicalLoadingLibApi");
if((error = dlerror()) != NULL)
{
    printf("DynamicalLoadingLibApi not found:%s\n",error);
    return   FAILURE;
}    
printf("Calling DynamicalLoadingLibApi() function of libdllibexample.so!\n");
func();  
dlclose(handle); //卸载库  
return SUCCESS;
}

4、動的収束試運転

あなたは収束のパスを指定する必要がありshilibexampleので、対応するヘッダファイルは、コンパイラで場所を見つけることができるようにする必要がありshilibexample.h。-Lパラメータは、ファイルパス、-lライブラリファイル名が表すことを示しています。
dllibexampleプログラムは、関連書類の共有ライブラリのdlopen -ldl彼らが必要示し、修正LD_LIBRARY_PATH dllibexample.soを見つけることができることを確認を使用して、コンパイル時に任意の関連情報なしで、訪問する実行されます。

gcc main.c -o main -L./ -l shlibexample -ldl -m32
export LD_LIBRARY_PATH=$PWD
./main

実験2:

execveのカーネルのシステムコールハンドラsys_execveの分析は、Linuxシステム上で実行可能なプログラムは、GDBを使用するプロセスを追跡するために必要な負荷を理解することを確認します。

第二の実験だけではない良いローカルの仮想マシン環境で、すべての後、実験棟の環境で行うことができます。

1は、最初にコンパイルされるように、githubの上のフォルダからtest_exec.cファイルを含むファイルをダウンロードしてください。

ls
cd ~/LinuxKernel
rm menu -rf
git clone https://github.com/mengning/menu.git
cd menu 
mv test_exec.c test.c
make rootfs

2、コンパイルはQEMUインターフェイスに成功しているかどうかを確認するために、ヘルプやexecコマンドを使用して。

3、その後、QEMUを再起動します。

4、カーネルお​​よびポートをロードします。

5、3ブレークポイント。

6、デバッグやプログラムを実行しています。

おすすめ

転載: www.cnblogs.com/morvalhe/p/11815584.html