专利名称:共享库系统及构建该系统的方法
技术领域:
本发明涉及一种共享库系统,其中多个应用程序共享一个库实例,特别涉及一种共享库系统及构建该系统的方法,使得有可能在没有存储器管理单元(MMU)的情况下使用共享库。本申请主张根据2003年7月12日向韩国知识产权局提交的韩国专利申请第2003-47538号享受优先权,通过引用将其全部公开内容合并于此。
背景技术:
通常来说,库由代码和该代码中使用的数据的数据区组成。根据是否有多个应用程序共享并使用库代码,库可分为静态库和共享库。对于静态库(通常是*.a类型的文件),库代码在链接步骤中被复制,并随同应用程序被使用。对于共享库(通常是*.so类型的文件),库代码实例在运行时间在应用程序间共享并使用。同样地,在使用共享库的系统中,并不在链接步骤中发生库代码的复制。共享库的目的是为共享库代码的每个程序独立地提供每个数据区。因此,通过共享库的使用,有可能显著地减少随机存取存储器(RAM)和快闪存储器的消耗。
根据执行完全链接,即符号(symbol)地址绑定的时间,共享库分为静态链接共享库和动态链接共享库。通常说来,共享库是动态链接共享库。在动态链接共享库中,实际的符号地址绑定在运行时间加载程序的时候执行。因此,即使在构造(build)应用程序后库的内容改变,也不必重新构造应用程序。相反地,会产生在运行时间绑定符号的开销。然而,在静态链接共享库中,实际的符号地址绑定在链接时间执行。因此,如果库发生了改变,需要再次编译所有引用该库的应用程序。即使如此,运行时间开销比动态链接共享库要小得多。
在具有存储器管理单元(MMU)的系统中,由于多个进程有可能通过虚拟存储器映射来共享页面,使用共享库相对容易。在没有MMU的传统系统中,由于多个进程不可能共享页面,很难使用共享库。近来,没有MMU的系统,如uCLinuxTM得到了普遍的发展。因此,期望这样的系统为了存储器效率而利用共享库。
发明内容
本发明提出一种没有存储器管理单元(MMU)共享库系统,其有可能使用静态链接共享库。
本发明还提出了一种构建没有MMU的共享库系统的方法。
本发明还提出了一种在没有MMU的共享库系统中使用共享库的方法。
本发明还提出了一种在没有MMU的共享库系统中构造共享库的方法。
本发明还提出了一种计算机可读介质,其包括计算机可读程序代码单元,用来记录构建没有MMU的共享库系统的方法。
本发明还提出了一种计算机可读介质,其包括计算机可读程序代码单元,用来记录使用共享库的方法。
本发明还提出了一种计算机可读介质,其包括计算机可读程序代码单元,用来记录构造共享库的方法。
根据本发明的一个方面,提出了一种没有MMU的共享库系统,包括数据区基址寄存器,其中确立应用程序的数据区起始地址和共享库中分配给该应用程序的数据区起始地址之一;编译器,用来以位置独立代码(PIC)选项来编译源代码类型的程序和库,并定义库中包括的函数,使得在数据区基址寄存器中确立通过该库分配给应用程序的数据区起始地址;共享库构造器,通过使用已编译的库,生成共享库和地址库,所述共享库的代码和数据区为多个程序所共享,并作为符号存在于每个库中,所述地址库具有用于将符号地址绑定到程序的符号地址信息;应用程序构造器,根据链接器脚本,通过给已编译的程序的代码、数据和数据区表定位,将已编译的程序转换成执行文件类型的应用程序,所述数据区表定义在共享库中分配给该应用程序的数据区起始地址;以及运行时间加载器,用来在存储器中加载应用程序和共享库,并且,当在存储器中加载共享库时,根据通过符号地址信息中包括的符号重置类型进行必要的地址重置的结果,决定符号的最终地址。优选地,数据区包括全局偏移表(GOT)和数据字段,所述全局偏移表是有关全局数据的指针表,所述数据字段包括全局数据,并且数据区起始地址为GOT起始地址,应用程序使用GOT引用全局数据。
根据本发明的另一个方面,提出了一种构造没有MMU的共享库系统的方法,所述共享库系统具有数据区基址寄存器,在所述数据区基址寄存器中确立应用程序引用的数据区起始地址,所述方法包括(a)以PIC选项来编译要共享的库,并在编译的同时,在要共享的库的每个函数中,定义在数据区基址寄存器确立分配给要运行的程序的数据区起始地址;(b)通过使用已编译的库,生成共享库和地址库,所述共享库的实际的代码和数据存在于每个库中,所述地址库只具有用于将符号地址绑定到应用程序的符号的地址信息;(c)以PIC选项来编译程序;(d)根据链接器脚本,通过给已编译的程序的代码、数据和数据区表定位,将已编译的程序转换成执行文件类型的应用程序,所述数据区表指示在共享库中分配给应用程序的数据区起始地址;(e)加载为了执行存储器中的应用程序而构造的共享库。
根据本发明的另一个方面,提出了一种在没有MMU的共享库系统中,应用程序使用加载到存储器中的共享库的方法,所述共享库系统具有数据区基址寄存器,在所述数据区基址寄存器中确立应用程序引用的数据区起始地址,所述方法包括(a)如果应用程序调用共享库的函数,在数据区基址寄存器中确立共享库中分配给该应用程序的数据区起始地址;以及(b)由访问数据区基址寄存器中确立的地址的应用程序执行被调用的函数。
根据本发明的另一个方面,提出了一种在没有MMU的共享库系统中构造共享库的方法,包括(a)以PIC选项来编译要共享的库;(b)通过给要共享的库分配唯一编号作为标识符(ID)来重新确立库名;(c)将已编译的库中包括的多个目标文件重置到一个目标文件中;(d)转换步骤(c)的目标文件格式以适应目标系统,并生成格式转换后的目标文件作为具有要共享的代码和数据的共享库;(e)生成地址库,其中定义了每个目标文件的符号的地址,其中,生成步骤包括从已编译的库和共享库中提取符号的每个位置信息和地址信息。
通过结合附图对本发明的示范实施例进行详细描述,本发明上述及其它特征和优点将更清晰易懂,附图中图1为根据本发明的没有存储器管理单元(MMU)的共享库系统的实施例的示意方框图;图2为在图1所示没有MMU的共享库系统中构造共享库的过程和使用共享库的方法的实施例的流程图;图3显示了使用库构造器构造共享库的过程;图4显示了由图3所示的符号生成(gensym)实用程序(utility)定义的符号地址格式的实施例;图5显示了包括FLAT二进制重置表的链接器脚本;图6为应用程序的链接器脚本的详细图;图7描述了应用程序在程序运行时调用在共享库中定义的函数的过程。
具体实施例方式
下面,将描述本发明的说明性实施例。为了清晰,说明书中并未描述实际应用中的所有特征。将明白,在任何这种实际实施例的开发中,必须做大量具体实现的决定以达到开发者指定的目标,例如,符合系统相关和业务相关的约束,而所述约束将根据实现的不同而变化。此外,将明白,开发工作量可能很复杂并耗时,但是对于本领域普通技术人员而言,在这一公开文件的帮助下,该开发工作不过是其日常工作。
尽管很容易对本发明给出各种改变和替换形式,但是借助于插图中的示例显示了具体实施例。然而,应当理解,这里对具体实施例的描述并不打算将本发明限制为所公开的特定形式,相反地,发明将覆盖落入所附权利要求中限定的本发明的精神和范围的所有改变、等同物及替代物。还应当理解,这里描述的系统和方法可能将以各种硬件、软件、固件或其组合实现。
可以理解,由于对于减少嵌入式系统的运行时间的开销很重要,本发明的共享库系统优选使用静态链接共享库。
图1为根据本发明的实施例的没有存储器管理单元(MMU)的共享库系统的实施例的示意方框图。共享库系统包括编译器100、库构造器120、应用程序构造器130、运行时间加载器140、数据区基址寄存器160。为了描述方便,也显示了主存储器180。
编译器100以预定选项,即位置独立代码(PIC)选项,来编译要运行的程序102及要共享的库104,然后生成已编译的程序105及已编译的库108。实际上,在编译要运行的程序102及要共享的库104的源代码时,可简单地以-fpic选项生成PIC。通过在编译器100中以PIC选项来编译要运行的程序102及要共享的库104,不必在没有MMU的共享库系统中固定加载库的存储器地址。更确切地说,由于在PIC中,以指针计数器(PC)相关的分支或跳转来实现对每个函数的调用,可以不考虑加载到存储器中的代码的位置而运行这些调用;因此,不需要固定加载库的地址。而且,编译器100编译要共享的库104,以便在数据区基址寄存器160中确立(establish)每个库函数序言(prologue)中分配给要运行的程序102中的数据区起始地址。编译器100给每个共享库分配唯一的编号作为共享库的标识符(ID),确立每个库名,并将其编译为libID.so。举例来说,在共享库的数量为3的情况下,库名分别确立为lib1.so、lib2.so和lib3.so。
通过利用已被编译器100编译的库108,共享库构造器120生成共享库124a和每个共享库的地址库124b。共享库124a是具有实际代码和数据区的库。由运行时间加载器140将共享库124a加载到主存储器180中,以为多个应用程序所共享。数据区包括全局偏移表(GOT)和数据字段,全局偏移表是全局数据的指针表。GOT定位到正好在数据字段之前。此时,共享库124a为已编译的库,其被重置为包括多个目标文件的目标文件。地址库124b仅具有多个符号的地址信息,而没有实际代码和数据,为了将符号地址绑定到应用程序106中而存在。每个符号包括目标文件中包括的函数和全局变量的名称。地址库124b不加载到主存储器180中,仅在构造应用程序106时使用。此时,符号地址必定包括运行时间加载器140将共享库124a加载到主存储器180中所需要的信息。举例来说,符号地址可能包括有关目标文件中的符号或共享库文件中的符号的信息,以及有关地址重置的信息。
通过根据链接器脚本给应用程序的代码、数据和数据区表定位(locate),应用程序构造器130将已编译的程序105转换成执行文件类型的应用程序106。数据区表表示通过共享库124a分配给要运行的程序102的数据区的起始地址。在本发明中,定义链接器脚本,使得将表示每个库数据区起始地址的数据区表定位到正好在数据区之前。下面参考图6,将对链接器脚本进行更为详细的描述。
运行时间加载器140将应用程序106和共享库124a加载到主存储器180中。当运行时间加载器140加载共享库124a时,根据符号地址信息中包括的符号重置类型,运行时间加载器140执行必要的地址重置,并最终决定符号的地址。参考图4,下面将对符号的地址重置进行更为详细的描述。
在数据区基址寄存器160中,确立了加载到主存储器180中的应用程序106的数据区起始地址或共享库124a的数据区起始地址。如上所述,数据区有这样的模式(pattern),其中,GOT被定位到正好在全局数据字段之前;由此,数据区起始地址为GOT的起始地址。应用引用模型(ARM)的堆栈限制(sl)寄存器可用作数据区基址寄存器160。如果应用程序106引用数据区基址寄存器160中的自身数据区(非库)运行程序,那么将确立应用程序106的数据区起始地址。然而,如果应用程序106调用共享库124a中定义的函数,根据被调用函数的序言定义,在数据区基址寄存器160中确立由共享库124a分配给应用程序106的数据区起始地址。同样地,通过利用数据区基址寄存器160,在没有MMU的情况下,共享库124a可以为每个应用程序确保独立的数据区。即,如果在没有MMU的系统中使用PIC,有可能将共享库的代码共享。然而,仍然不可能为每个应用程序提供独立的数据区。在PIC中,由于以PC相关的分支和跳转来访问所有静态数据,所以代码和数据区的相对偏移必须为常数,并且分配给多个应用程序的库代码和数据区的偏移也必须为常数。然而,在根据本发明的共享库系统中,在应用程序106运行共享库124a的函数之前,编译应用程序106,以便应用程序106引用的数据区地址被加载到数据区基址寄存器160中。因此,分配给多个应用程序的库代码和数据区的偏移不必为常数,并且可为多个应用程序提供独立的数据区。即,当应用程序106访问分配给其自身的数据区时,应用程序106通过引用数据区基址寄存器160中的值访问数据区,从而为每个应用程序106确保独立的数据区。
通过使用数据区基址寄存器160,有可能独立提供每个应用程序106的静态数据,然而,应用程序106很难在不进行代码重置的情况下访问全局数据。全局代码在应用程序106和库之间或库与库之间被共享及使用。在静态链接库中,由于在加载步骤中确定全局数据的地址,当程序加载时,必须重置全局数据引用。为此,使用作为全局变量的指针表GOT。通过使用分配给数据区的指针,生成代码,以便直接引用全局数据,并且,如果在加载过程中最终确定全局变量数据,则根据该数据将GOT中的可应用项重置。如上所述,由于数据区中存在GOT,可以实现GOT的重置,而不需要考虑代码字段的重置。
图2为在图1所示没有MMU的共享库系统中构造共享库的过程和使用共享库的方法的实施例的流程图。
参考图1和2,编译器100在步骤200编译要共享的库104。此时,编译器100以PIC选项编译要共享的库104,并通过分配唯一的编号作为每个共享库的ID,确立每个库名为libID.so。同样地,使用分配给每个库的唯一编号来在应用程序106的数据区表中搜索分配给每个库的数据区起始地址。下面将参考图6更详细地描述。同样地,编译器100编译要共享的库104,以便在数据区基址寄存器160中确立共享库的每个函数的序言中分配给应用程序106的数据区起始地址。
在步骤205中,通过使用已编译的库108,库构造器120生成共享库124a,其实际代码和数据存在于每个库中;以及地址库124b,其仅具有用来将符号地址绑定到应用程序106的符号的地址信息。
编译器100在步骤210中编译要运行的程序102。编译器100以PIC选项编译要运行的程序102,如要共享的库104。
在步骤215中,通过根据链接器脚本给应用程序的代码、数据和数据区表定位,应用程序构造器130将已编译的程序105转换成执行文件类型的应用程序106。
运行时间加载器140将所构造的共享库124a和所构造的应用程序106加载到主存储器180中。当运行时间加载器140将共享库124a加载到主存储器180中时,根据地址库124b的符号地址中包括的符号重置类型,运行时间加载器140执行必要的地址重置,并最终决定符号地址。
在步骤225中运行应用程序106。如果应用程序106通过引用自身数据区来运行程序,则确立数据区基址寄存器160为应用程序106的数据区起始地址,即GOT起始地址。然而,如果在步骤230中应用程序106调用共享库124a中的函数,则在步骤235中根据共享库函数的序言定义,在数据区基址寄存器160中确立共享库124a中分配给应用程序106的数据区起始地址。应用程序106可通过数据区基址寄存器160中确立的地址来访问分配给应用程序106的数据区。应用程序106通过使用作为数据区中包括的全局变量的指针表的GOT,间接引用全局数据,在步骤240中,运行从共享库124a调用的函数。参考图7,下面对步骤235和240中执行的操作进行更详细的描述。
如上所述,为了使用没有MMU的共享库,本发明修改了运行时间加载器140和编译器100,并通过库构造器120改变了先前的共享库的形式。此外,通过使用数据区基址寄存器160和数据区的GOT,即使在没有MMU的情况下,仍有可能使用共享库。在没有MMU的传统系统的情况下,由于不可能固定加载库的地址,不能给应用程序分配独立的数据区,并且不可能在不重置代码的情况下访问全局数据,因此难以使用共享库。然而,根据本发明的共享库系统不必通过以PIC选项编译要运行的程序102和要共享的库104来固定加载库的地址,于是,可通过PC相关的分支或跳转来实现对每个函数的调用。同样地,通过编译要运行的程序102和要共享的库104,使得在应用程序106处理库代码之前,在数据区基址寄存器160中加载应用程序106引用的数据区起始地址,可以将独立的数据区给予每个应用程序106。而且,共享库系统生成代码,以便通过使用分配给数据区的指针来间接引用全局数据,并且如果在加载过程中最终决定全局变量的数据,则重置GOT的可应用项。由于应用程序106通过使用数据区的GOT来访问全局数据,在不重置代码的情况下访问全局数据是有可能的。结果,由于根据本发明的共享库系统解决了没有MMU的传统系统的问题,根据本发明,可以在共享库系统中无需MMU而使用共享库。
图3显示了使用库构造器120构造共享库的过程。
参考图1和3,libc_temp.a为已由编译器100编译的已编移库108,并且显示了包括在C库中的对象的文档(archive)。由编译器100编译这些文档中的目标文件,从而确立应用程序106引用的数据区起始地址(在数据区基址寄存器160中)的代码,并将其包括在每个目标文件的序言中。
链接器300生成库lib1.so.gdb,其中,库libc_temp.a中包括的多个目标文件被重置到单个目标文件中。此时,lib1.so.gdb的文件格式为可执行链接格式(ELF),并且,为适应目标系统,必须使用格式转换实用程序310恰当地重置ELF文件。举例来说,如果目标系统是uCLinuxTM,格式转换实用程序310将ELF文件lib1.so.gdb转换为FLAT文件格式lib1.so。同样地,已转换文件格式以适应目标系统的库被称为共享库。如上所述,共享库124a为具有实际代码和数据的库。由运行时间加载器140将共享库124a加载到主存储器180中,为多个应用程序106所共享。
由于本发明为静态链接共享库系统,静态链接到应用程序106的对象是必要的。为此,符号生成实用程序320生成文件libc.a,其仅具有用来将符号地址绑定到应用程序中的符号的地址信息,而没有实际代码和数据。libc.a为符号地址库,其仅定义了除库代码(即非库输出符号)之外的输出符号。此时,将每个符号恰当地划分并定义到多个目标文件(*.o)中很重要。如果在一个目标文件中定义所有符号,由于库中的所有符号都包括在一个模块中,所以可能会产生不必要的重复声明错误。因此,在为了将这些符号划分并定义到多个目标模块中,而将文档重置为一个目标文件之前,符号生成实用程序320提取必要的信息,即包括来自文档libc_temp.a的符号的目标文件的信息。即,符号生成实用程序320从C库中的lib1.so.gdb中获得符号的地址,并从重置前的文档libc_temp.a中获得必定定义了符号的目标模块的信息。如在libc.a中一样,符号生成实用程序320将全局符号划分并定义到多个目标模块中。此情况中,符号的地址表示符号在lib1.so.gdb中的偏移。即,符号地址库libc.a的内容包括由C库输出的符号名和符号在lib1.so.gdb中的偏移。库libc.a不包括除上面所述代码之外的任何代码。因此,通过仅引用链接libc.a时定义的符号的偏移,引用C库的应用程序106同lib1.so链接。即,不生成重复的代码,并绑定符号地址,即仅符号偏移。运行时间加载器140必须根据加载了运行时间库的主存储器180中的地址重置libc.a中定义的符号地址。为此,符号地址必须被格式化,以便使表示符号在目标文件或共享库中的符号信息包括在符号地址中。
图4显示了由图3所示的符号生成实用程序320定义的符号地址格式的符号地址以32位(4字节)表示,32位中的低24位表示符号的实际地址。此情况中,应用程序和库的总共尺寸不能超过16M(=224字节)。如果库的尺寸超过了这个限制,则必须要划分该库。从第24位到第29位的6位赋予定义了符号的库的唯一编号,即ID。如上所述,在编译过程中将ID赋予给每个库。在此情况中,可同时使用的库的数量最大为64(=26)。最高2位表示重置类型,主要分为3种类型。第一种重置类型对应下述情况,其中,最高2位为00,意味着符号地址是在加载的时候需要修改的绝对地址值,并且符号地址主要显示在数据区中。第二种重置类型对应下述情况,其中,最高2位为01,意味着符号地址必须被分配给GOT的地址,即数据区起始地址。第三种重置类型对应下述情况,其中,最高2位为11。这意味着符号地址为分支指令的目标地址,并用来修改调用动态库的函数的基准地址。在加载时确定基准地址。在此重申,在第一种重置类型的情况下,符号地址仅被重置到主存储器180的绝对地址中。否则需要额外的工作。即,在第二种重置类型的情况下,符号地址必须重置到指定的数据区起始地址,即GOT的起始地址。此外,在第三种重置类型的情况下,需要将代码直接修改为适应系统分支指令的格式。举例来说,在ARM中,由于每个分支指令的最高8位决定分支类型,而剩下的较低24位表示分支偏移,可基于重置信息修改符号地址,以适应适当的系统。
上述符号地址格式也同样适用于uCLinuxTM的FLAT二进制重置表400的条目(entry)。FLAT二进制重置表400定位为与数据区410紧接,如图5所示,FLAT二进制表400的每个条目指示需要由运行时间加载器140重置的代码和数据。
运行时间加载器140通常(1)将应用程序106引用的共享库124a加载到主存储器180;(2)重置共享库124a中包括的符号的地址;(3)确保库代码的共享。即,在多个应用程序同时使用一个共享库124a的情况下,库代码在主存储器180中仅加载一个实例。运行时间加载器140执行这些角色的主要原因是为在GOT表和重置表的条目中检测对库的引用。这可能容易从图4所示的符号的地址格式和重置条目中获得。举例来说,当应用程序106的ID被分配为0,而共享库124a的ID被分配为从1开始的预定序列号时,如果地址值的第24位至第29位(即表示库ID的位)不全为0,则该地址表示对库的引用。如果检测到对没有加载到主存储器180的库的引用,则运行时间加载器140在主存储器180中加载可应用的库,执行必要的重置,并基于加载的信息决定符号的地址。
图6为应用程序106的链接器脚本的详细图。文本106a是定义函数代码的字段。数据区表106b显示了分配给应用程序106引用的共享库124a的数据区起始地址。在数据区106c中,GOT 107a为全局变量的指针表,第一数据107b为定义全局变量的字段,第二数据107c为定义局域变量的字段。图6显示了应用程序106引用的共享库124a的数量为3的情况下的数据区表106b。数据区表106b被定位到正好在数据区106c之前,将每个库的名称转换为libID.so类型。为每个共享库124a给予一个ID1、2、3……,为应用程序106分配的ID为0。这些ID被用来寻找分配给应用程序106的数据区的位置。如果地址的尺寸为4字节,则每个库中被分配给应用程序106的数据区的地址可从公式(-4*ID-4)获得。举例来说,可通过从当前的数据区基址寄存器160表示的地址中减掉8字节得到ID为1的库的数据区。如果当前的数据区基址寄存器160表示应用程序106的数据区,并且当前的数据区基址寄存器160的值为sl,则应用程序106的数据区起始地址信息‘ptr to app data(指向应用程序数据的指针)’从地址sl-4得到,ID为1的库的数据区地址‘ptrto lib1.so data(指向lib1.so数据的指针)’从地址sl-8得到,ID为2的库的数据区地址‘ptr to lib2.so data(指向lib2.so数据的指针)’从地址sl-12得到,ID为3的库的数据区‘ptr to lib3.so data(指向lib3.so数据的指针)’从地址sl-16得到。而且,为了库检索的方便,在/lib目录下必须存在libID.so类型的库名。举例来说,如果唯一编号1分配给libc,在/lib目录下必须存在名为lib1.so的C共享库目标代码。
图7描述了运行程序时应用程序106调用共享库中定义的函数的过程。
参考图6和7,共享库X包括应用程序的数据区500到510。在共享库X中,数据区500到510被分别分配给应用程序1到Y。即,函数代码,如func1,被每个应用程序所共享,而全局数据被分配给每个应用程序。如果应用程序1通过引用应用程序的数据区执行,则在数据区基址寄存器160中确立应用程序的数据区起始地址,即GOT起始地址。然而,如果应用程序1调用库X中定义的函数代码func1,则根据函数代码func1的序言520的指令‘push sl’,将当前被分配给数据区基址寄存器160的数据存储在另一存储空间中。根据指令‘set sl…’,应用程序获得通过引用应用程序的数据区表106b,在共享库X中分配给应用程序1的数据区500的起始地址,并在数据区基址寄存器160中确立起始地址。而且,如果函数代码func1执行完毕,根据指令‘poolsl…’,在数据区基址寄存器160中再次确立该另一存储空间中存储的数据。
如上所述,修改运行时间加载器和编译器,以便在执行程序的时候引用共享库,前面的共享库的模式通过库构造器来修改。通过在此过程中使用共享库,可减少系统的存储器用量,并且最终减少系统的生产成本。
本发明可在通用计算机中通过运行来自计算机可读介质的程序来体现,所述计算机可读介质包括但不限于下列存储介质,如磁存储介质(ROM、RAM、软盘、磁带等等),光可读介质(CD-ROM、DVD等等),以及载波(在Internet中传输)。本发明可作为其中具体化了计算机可读程序代码单元的计算机可读介质来体现,用于使多个通过网络连接的计算机系统进行有效的分布式处理。
如上所述,根据没有MMU的共享库系统以及构造系统的方法,通过修改编译器、运行时间加载器和库构造器,可在没有诸如MMU等硬件的情况下使用共享库,并且通过由此获得的存储器使用的减少,可减少系统的生产成本。
尽管已参考示范实施例来具体显示和描述了本发明,但是本领域普通技术人员应当理解,在不脱离本发明的精神和所附权利要求书中所限定的范围的情况下,可以在形式和细节上有所改变。
权利要求
1.一种共享库系统,包括数据区基址寄存器,其中确立应用程序的数据区起始地址和共享库中分配给该应用程序的数据区起始地址之一;编译器,用来以位置独立代码(PIC)选项来编译源代码类型的程序和库,并定义库中包括的函数,使得在数据区基址寄存器中确立通过该库分配给应用程序的数据区起始地址;共享库构造器,通过使用已编译的库,生成共享库和地址库,所述共享库的代码和数据区为多个程序所共享,并作为符号存在于每个库中,所述地址库具有用于将符号地址绑定到程序的符号地址信息;应用程序构造器,根据链接器脚本,通过给已编译的程序的代码、数据和数据区表定位,将已编译的程序转换成执行文件类型的应用程序,所述数据区表定义在共享库中分配给该应用程序的数据区起始地址;以及运行时间加载器,用来在存储器中加载应用程序和共享库,并且,当在存储器中加载共享库时,根据通过符号地址信息中包括的符号重置类型进行必要的地址重置的结果,决定符号的最终地址;其中,数据区包括全局偏移表(GOT)和数据字段,所述全局偏移表是有关全局数据的指针表,所述数据字段包括全局数据,并且数据区起始地址为GOT起始地址,应用程序使用GOT引用全局数据。
2.如权利要求1所述的共享库系统,其中,编译器将从1开始的序列号作为标识符(ID)分别赋予库,并基于所赋予的ID来重新确立库名。
3.如权利要求2所述的共享库系统,其中,为了便于库检索,在预定的目录下存在重新确立的库名。
4.如权利要求2所述的共享库系统,其中,链接器脚本被定义为使得将数据区表定位到正好在数据区之前,并且,当地址的尺寸为n字节时,应用程序从公式(sl-n*m-n)得到ID为m的共享库的数据区起始地址,其中,sl为应用程序的数据区起始地址。
5.如权利要求1所述的共享库系统,其中,所述共享库构造器包括链接器,用来将已编译的库中包括的多个目标文件重置到单个目标文件中;格式转换实用程序,用来转换目标文件的格式,以适应目标系统,生成所述格式转换后的目标文件作为共享库;以及符号生成实用程序,用来从已编译的库中提取包括符号的目标文件的位置信息和符号在共享库中的偏移,作为符号地址信息,并通过利用位置信息生成地址库,其中符号地址在已对符号定位的目标文件中的地址库中定义。
6.如权利要求5所述的共享库系统,其中,地址库定义非库输出符号的地址信息。
7.如权利要求1所述的共享库系统,其中,符号地址的格式包括第一个p位字段,用来表示符号地址;第二个q位字段,用来表示其中定义了符号的库的ID;第三个r位字段,用来表示在主存储器中加载共享库时的地址重置类型。
8.如权利要求7所述的共享库系统,其中,应用程序和库之一的尺寸小于或等于2m位,如果库的尺寸超过2m位,则将库划分,使得库的尺寸小于或等于2m位。
9.如权利要求7所述的共享库系统,其中,地址重置类型包括第一重置类型,表示在主存储器中加载符号的地址时,符号的地址必须重置到主存储器的绝对地址;第二重置类型,表示符号的地址必须被GOT起始地址替代,所述GOT起始地址是数据区起始地址;以及第三重置类型,表示符号的地址为分支指令的目标地址,并必须修改为适应目标系统的分支指令的格式。
10.如权利要求7所述的共享库系统,其中,如果目标系统是uCLinuxTM,则FLAT二进制重置表的条目与所述符号有着相同的地址格式。
11.一种构造共享库系统的方法,所述共享库系统具有数据区基址寄存器,在所述数据区基址寄存器中确立应用程序引用的数据区起始地址,所述方法包括(a)以PIC选项来编译要共享的库,并在编译的同时,在要共享的库的每个函数中,定义在数据区基址寄存器确立分配给要运行的程序的数据区起始地址;(b)通过使用已编译的库,生成共享库和地址库,所述共享库的实际的代码和数据存在于每个库中,所述地址库只具有用于将符号地址绑定到应用程序的符号的地址信息;(c)以PIC选项来编译程序;(d)根据链接器脚本,通过给已编译的程序的代码、数据和数据区表定位,将已编译的程序转换成执行文件类型的应用程序,所述数据区表指示在共享库中分配给应用程序的数据区起始地址;(e)加载为了执行存储器中的应用程序而构造的共享库。
12.如权利要求11所述的方法,其中,编译器将从1开始的序列号作为标识符(ID)分别分配给库,并基于所分配的ID来重新确立库名。
13.如权利要求12所述的方法,其中,链接器脚本被定义为使得将数据区表定位到正好在数据区之前,并且,当地址的尺寸为n字节时,应用程序从公式(sl-n*m-n)得到ID为m的共享库的数据区起始地址,其中,sl为应用程序的数据区起始地址。
14.如权利要求11所述的方法,其中,(a)数据区包括GOT和数据字段,所述GOT是对全局数据的指针表,而所述数据字段包括全局数据,(b)数据区起始地址为GOT起始地址,并且(c)应用程序使用GOT引用全局数据。
15.如权利要求11所述的方法,其中,符号地址的格式包括第一个p位字段,用来表示符号地址;第二个q位字段,用来表示其中定义了符号的库的ID;第三个r位字段,用来表示在主存储器中加载共享库时的地址重置类型。
16.如权利要求15所述的方法,其中,应用程序和库之一的尺寸小于或等于2m位,如果库的尺寸超过2m位,则将库划分,使得库的尺寸小于或等于2m位。
17.如权利要求15所述的方法,其中,地址重置类型包括第一重置类型,表示在主存储器中加载符号的地址时,符号的地址必须重置到主存储器的绝对地址;第二重置类型,表示符号的地址必须被GOT起始地址替代,所述GOT起始地址是数据区起始地址;以及第三重置类型,表示符号的地址为分支指令的目标地址,并必须修改为适应目标系统的分支指令的格式。
18.如权利要求15所述的方法,其中,如果目标系统是uCLinuxTM,则FLAT二进制重置表的条目与所述符号有着相同的地址格式。
19.如权利要求15所述的方法,其中,当在存储器中加载共享库时,根据通过符号的重置类型执行必要的地址重置的结果,决定符号的最终地址。
20.一种具有计算机可读程序代码单元的计算机可读介质,其上记录有如权利要求11所述的方法。
21.一种使用共享库系统中的共享库的方法,所述共享库系统具有数据区基址寄存器,在所述数据区基址寄存器中确立应用程序引用的数据区起始地址,所述方法包括(a)如果应用程序调用共享库的函数,在数据区基址寄存器中确立共享库中分配给该应用程序的数据区起始地址;以及(b)通过访问数据区基址寄存器中确立的地址,执行应用程序调用的函数。
22.如权利要求21所述的方法,其中,步骤(a)包括(a1)如果应用程序调用共享库的函数,则将在数据区基址寄存器中确立的数据区地址存储到另一存储空间中;(a2)通过引用应用程序的数据区表,将在共享库中分配给该应用程序的数据区起始地址确立到数据区基址寄存器中;(a3)通过经涉及在数据区基址寄存器中确立的地址的GOT入口来引用全局数据,执行应用程序调用的函数;(a4)如果被调用的函数执行完毕,将步骤(a1)中存储到另一存储空间中的数据区地址重新确立到数据区基址寄存器中。
23.一种具有计算机可读程序代码单元的计算机可读介质,其上记录有如权利要求21所述的方法。
24.一种构造共享库系统中的共享库的方法,包括(a)以PIC选项来编译要共享的库;(b)通过给要共享的库分配唯一编号作为ID来重新确立库名;(c)将已编译的库中包括的多个目标文件重置到单个目标文件中;(d)转换步骤(c)的目标文件的格式以适应目标系统,并生成格式转换后的目标文件作为具有要共享的代码和数据的共享库;(e)生成地址库,其中定义了每个目标文件的符号的地址,其中,生成步骤包括从已编译的库和共享库中提取符号的每个位置信息和地址信息。
25.如权利要求24所述的方法,其中,地址库仅定义非库输出符号的地址信息。
26.如权利要求24所述的方法,其中,在编译时,定义要共享的库的每个函数,使得在预定寄存器中确立分配给应用程序的数据区起始地址。
27.如权利要求24所述的方法,其中,步骤(e)包括(e1)从已编译的库中提取包括有符号的目标文件的位置信息;(e2)提取共享库中的符号的偏移,作为符号地址信息;以及(e3)生成地址库,其中在已对符号定位的目标文件中定义符号的地址,其中,生成步骤包括利用位置信息。
28.一种具有计算机可读程序代码单元的计算机可读介质,其上记录有如权利要求24所述的方法。
全文摘要
公开了一种共享库系统和构造该系统的方法。修改了运行时间加载器和编译器,并使用库构造器改变了先前的共享库的模式。此外,通过利用数据区基址寄存器和数据区的全局偏移表,即使在没有存储器管理单元的情况下,也有可能使用共享库。
文档编号G06F9/45GK1577268SQ20041006358
公开日2005年2月9日 申请日期2004年7月12日 优先权日2003年7月12日
发明者金云基, 朴种一 申请人:三星电子株式会社