8.6.4 位置独立プログラムから位置独立でないプログラムへの参照

特定の手順によって,既存資産などの位置独立ではないプログラムを,位置独立プログラムから参照することができます。この場合の位置独立ではない側のプログラムを,共有部と呼びます。

(1)

事前の条件として,位置独立プログラムを作成する前に,共有部を作成済みである必要があります。

共有部の実行形式の作成時に,最適化リンカの-fsymbolオプションを使用して,位置独立プログラムから参照したい関数や変数のアドレスを,.fsyファイルに出力しておきます。

-

ライブラリ関数を共有部内では参照しないが,位置独立プログラムから共有部として参照したい場合は,次のような疑似的な参照コードを記述し,共有部にライブラリ関数をリンクさせます。

#include <string.h>
void* const dummy_libcall[] = {&memcpy, &memcmp, &strcpy};

 

次の操作で,common.fsyファイルが出力されます。

>ccrh dummy_libcall.c -ocommon.abs -Xlk_option=-fsymbol=.text

 

すでに作成済みの共有部の実行形式を位置独立プログラムから参照したい場合は,共有部のリンク・マップ・ファイルなどで参照したい関数や変数のアドレスを確認し,.fsyファイルに記述します。

リンク・マップ・ファイルに次のようにアドレスが表示されている場合:

FILE=memcmp
                                  00002000  00002023        24
  _memcmp
                                  00002000         0   none ,g         *
FILE=memcpy
                                  00002024  0000203b        18
  _memcpy
                                  00002024         0   none ,g         *
FILE=strcpy
                                  0000203c  0000204f        14
  _strcpy
                                  0000203c         0   none ,g         *

 

common.fsyファイルに記述する内容:

        .public _memcmp
_memcmp .equ 0x2000
        .public _memcpy
_memcpy .equ 0x2024
        .public _strcpy
_strcpy .equ 0x203c

 

(2)

位置独立プログラムの作成時には,参照したい共有部の関数や変数の宣言と,参照する処理を記述します。

このとき,宣言の所属するセクションを,共有部側の関数,変数定義のセクションと合わせておきます。参照する側のPIC関数は,PIC用のセクションに定義してください。

-pid,-pirod,-pidオプション指定時でも,#pragma section指令に,text,const,r0_disp16等の位置独立でないセクション再配置属性を指定することは可能です。この場合,関数や変数の宣言のみを記述できます。関数や変数の定義を記述するとエラーになります。

 

#pragma section text
extern  void *memcpy(void *, const void *, unsigned long);
extern  int memcmp(const void *, const void *, size_t);
extern  char *strcpy(char *, const char *);
 
#pragma section pctext  /* PIC関数を定義するときは,セクション再配置属性をPIC用に戻すこと */
 
void pic_func(char* a, char* b, unsigned long c) {
  memcpy(a, b, c);
}

 

共有部の関数,変数を参照するコードを記述し,位置独立プログラムをビルドします。このとき,共有部から作成した.fsyファイを一緒にビルドすることで,共有部側にある関数や変数への参照を絶対アドレスで解決します。

 

>ccrh pic.c common.fsy

 

(3)

位置独立プログラムから参照できる共有部の変数や関数には,参照方法に制約があります。

位置独立プログラム同士,また位置独立プログラムと共有部との間の,参照可能な関係と参照方法を次の表に示します。

 

参照先

PIC関数

非PIC関数

PIROD変数

非PIROD変数

PID変数注2

非PID変数

参照元

PIC関数

PC相対

R0相対

PC相対

R0相対

GP,EP相対

GP,EP相対

R0相対

非PIC関数

不可注1

PC相対

R0相対

不可注1

R0相対

GP,EP相対

GP,EP相対

R0相対

注 1.

非PIC関数のリンク時には,リンカがPIC関数,PIROD変数の実行時のアドレスを特定できないため,あらゆる直接参照ができません。実行時にポインタを受け取って,ポインタ経由で参照することは可能です。

注 2.

PID変数とは,GP相対,EP相対セクションに配置している変数全般ではなく,-pidオプションを指定してコンパイルした変数を指します。