1. 概要

アプリケーションを実行するために、64ビットLinuxシステムに32ビットライブラリと64ビットライブラリの両方をインストールできます。 ここでは、特定のアーキテクチャ用にコンパイルされたC /C++ライブラリについて説明します。

特定のライブラリが32ビットか64ビットかを知りたい場合があります。 この短いチュートリアルでは、ライブラリの形式を決定するいくつかの方法を学習します。

2. 共有ライブラリと静的ライブラリ

ライブラリは、事前にコンパイルされたコードのコレクションを1つのファイルにグループ化して、さまざまなプログラムで使用できるようにします。

Linuxには、次の2種類のライブラリがあります。

  • 静的—コンパイル時に静的にプログラムにバインドされます。通常は「*。a」という名前です。
  • 共有—プログラムの起動時にロードされ、実行時にメモリにロードされます。通常、「*。so」という名前が付けられます。

静的ライブラリは実行可能ファイルではありません。 代わりに、ar形式のファイルです。 これは、ELFオブジェクトファイルなどの他のファイルの単なるアーカイブです。

一方、共有ライブラリはELFファイルです。

ELFヘッダーは、ライブラリが32ビットアドレスと64ビットアドレスのどちらを使用するかを定義します。

このチュートリアルでは、fileおよびobjdumpコマンドを使用して、ライブラリの形式を決定します。 これが静的ライブラリと共有ライブラリの両方にどのように適用されるかを見ていきます。

3. fileコマンドの使用

fileコマンドは、ファイルの種類を確認するのに便利なユーティリティです。 ファイルを使用してライブラリの形式を教えてください。

3.1. 共有ライブラリ

まず、2つの共有ライブラリでテストしてみましょう。

$ file /usr/lib/libc-2.33.so
/usr/lib/libc-2.33.so: ELF 64-bit LSB shared object, x86-64, version 1 (GNU/Linux), dynamically linked, ....

$ file /usr/lib32/libc-2.33.so
/usr/lib32/libc-2.33.so: ELF 32-bit LSB shared object, Intel 80386, version 1 (GNU/Linux), dynamically linked, ...

ここでは、32ビットおよび64ビットのライブラリファイルに対してfileを実行しました。 ご覧のとおり、 file コマンドはELFヘッダーを読み取り、使用するアドレス幅など、各ライブラリの詳細情報を報告します。

3.2. 静的ライブラリ

次に、静的ライブラリで同様のテストを実行しましょう。

$ file /usr/lib/libc.a
/usr/lib/libc.a: current ar archive

$ file /usr/lib32/libc.a
/usr/lib32/libc.a: current ar archive

今回は、 file コマンドは、それらが ar アーカイブであることを通知しますが、はそれらが32ビットか64ビットかを報告しません。

これは、静的ライブラリがELFファイルではなく単なるアーカイブであるためです。 file コマンドは、静的ライブラリ内のすべてのELFオブジェクトファイルを調べて、それらのヘッダーを読み取るわけではありません。

4. objdumpコマンドの使用

objdump コマンドは、パッケージ GNUBinutilsのメンバーです。 オブジェクトファイルからの情報を表示します。

-f オプションを使用して、ELFファイルのヘッダーを読み取ることができます。

4.1. 共有ライブラリ

まず、いくつかの共有ライブラリで実行した場合にobjdumpが出力する内容を見てみましょう。

$ objdump -f /usr/lib/libc-2.33.so

/usr/lib/libc-2.33.so:     file format elf64-x86-64
architecture: i386:x86-64, flags 0x00000150:
HAS_SYMS, DYNAMIC, D_PAGED
start address 0x0000000000027c60

$ objdump -f /usr/lib32/libc-2.33.so

/usr/lib32/libc-2.33.so:     file format elf32-i386
architecture: i386, flags 0x00000150:
HAS_SYMS, DYNAMIC, D_PAGED
start address 0x0001ebc0

上記の出力では、「ファイル形式」フィールドはELFファイルが64ビット(elf64-…)または32ビット(elf32-…)アドレスを使用していることを報告します。

したがって、「 /usr/lib/libc-2.33.so 」ファイルは64ビットライブラリであり、もう1つは32ビットライブラリです。 また、「 start address 」フィールドを見ると、それぞれ64ビットと32ビット幅のアドレスがあります。

4.2. 静的ライブラリ

次に、静的ライブラリで同じコマンドを実行してみましょう。

$ objdump -f /usr/lib/libc.a
In archive /usr/lib/libc.a:

init-first.o:     file format elf64-x86-64
architecture: i386:x86-64, flags 0x00000011:
HAS_RELOC, HAS_SYMS
start address 0x0000000000000000


libc-start.o:     file format elf64-x86-64
architecture: i386:x86-64, flags 0x00000011:
HAS_RELOC, HAS_SYMS
start address 0x0000000000000000


sysdep.o:     file format elf64-x86-64
architecture: i386:x86-64, flags 0x00000000:

start address 0x0000000000000000

...

上記の出力は、静的ライブラリ内のすべてのオブジェクトファイルを処理してELFヘッダーを出力するobjdumpコマンドを示しています。

このソリューションは機能しますが、大きな出力を生成する可能性があります。たとえば、上記の出力は10,000行を超えます。

4.3. 簡単な出力の取得

ELFヘッダー情報を要約すると、 objdumpの出力をawkにパイプして、検索と置換によってファイル形式の値を抽出し、重複を削除できます。

$ objdump -f /usr/lib/libc.a | awk 'sub(/.*file format /,"") && !a[$0]++'
elf64-x86-64

これで、出力は静的ライブラリ内のすべてのオブジェクトファイルが64ビットアドレスを使用していることを意味します。 したがって、/usr/lib/libc.aは64ビットの静的ライブラリであると言えます。

最後に、32ビットの静的ライブラリでコマンドをテストしてみましょう。

$ objdump -f /usr/lib32/libc.a | awk 'sub(/.*file format /,"") && !a[$0]++'
elf32-i386

elf32-*」は、ライブラリ内のすべてのオブジェクトファイルが32ビットアドレスを使用していることを示します。 したがって、これは32ビットライブラリです。

5. 結論

この記事では、Linuxでライブラリが32ビットか64ビットかを確認する方法を学びました。

共有ライブラリの場合、fileコマンドがおそらく最も簡単な解決策です。

ただし、静的ライブラリの場合は、ライブラリ内のオブジェクトファイルのヘッダーを読み取る必要があります。この場合、objdumpを使用できます。