CN100535856C - 一种构造中间库的方法 - Google Patents
一种构造中间库的方法 Download PDFInfo
- Publication number
- CN100535856C CN100535856C CNB2006101496616A CN200610149661A CN100535856C CN 100535856 C CN100535856 C CN 100535856C CN B2006101496616 A CNB2006101496616 A CN B2006101496616A CN 200610149661 A CN200610149661 A CN 200610149661A CN 100535856 C CN100535856 C CN 100535856C
- Authority
- CN
- China
- Prior art keywords
- mapping library
- mapping
- library
- symbol
- middle database
- Prior art date
- Legal status (The legal status is an assumption and is not a legal conclusion. Google has not performed a legal analysis and makes no representation as to the accuracy of the status listed.)
- Active
Links
Images
Abstract
本发明公开了一种构造中间库的方法,包括,生成实现函数跳转的中间文件;为每个映射库生成一个初始化文件;编译链接中间文件和初始化文件,得到与映射库一一对应的中间库;修改映射库的文件名;把中间库放到目标文件系统中所对应的映射库目录下。本发明在不对第三方软件做任何修改的前提下,通过构造中间库,解决了第三方软件不能访问映射库中的函数和全局变量的难题;把共享库编译链接为映射库,使整个软件系统的大小减少20%~30%,应用程序的运行时响应速度加快。
Description
技术领域
本发明涉及一种软件优化方法,尤其涉及一种嵌入式系统中对共享库的优化方法,具体涉及一种嵌入式系统中构造中间库的方法。
本发明主要应用于嵌入式系统软件中,也可用于普通的PC机软件和服务器软件系统中。
背景技术
在支持动态链接的系统中,一个应用程序通常依赖一个或多个共享库,一个共享库也可能会依赖一个或多个其它的共享库。这种依赖关系模型如附图1所示。
嵌入式系统的存储资源通常十分有限,而且对响应速度要求较高。嵌入式系统的专用性使得开发人员有可能采用某些特殊的技术手段对嵌入式软件进行优化,达到降低成本,提高性能的目的。
许多编译链接工具(如GNU gcc、ld等)提供了-T、-R等编译链接选项来对共享库和应用程序进行优化。在编译链接共享库时,使用连接器的-T选项把共享库的虚拟地址映射到应用程序的一维虚拟地址空间中(为方便表述,本文后面把这类共享库称为映射库),编译链接应用程序时,使用连接器的-R选项从映射库中读入符号表,具体实施流程如附图2所示,采用这种方式编译链接的应用程序的虚拟地址空间可以按照图3布局。
实践表明,上述方法可使目标文件的大小减少20%~30%(不同体系结构略有不同),而且程序运行时的响应速度更快。
但是,映射库失去了动态链接特性,普通动态加载机制不再有效。通常情况下,这并不成问题,只需要按照上述方法把相关的共享库和应用程序重新编译链接就可以了。但是,在嵌入式系统开发中,经常会遇到下面这种情况:
如附图1所示,某些应用程序没有源代码,只有二进制可执行文件(为方便描述,本文后面把这类软件称为第三方软件),而第三方软件依赖共享库有源代码。
由于第三方软件所依赖的共享库有源代码,因此可以按照上述方法,把这些共享库编译链接成映射库,从而节省20%~30%的存储空间。但是,如前面所述,映射库不再适用于普通的动态加载和动态链接机制,而第三方软件又没有源代码,不能重新编译链接。因此,有第三方软件存在的场合,很难使用上述方法对嵌入式系统软件进行优化。
发明内容
为了克服现有技术中存在的问题,本发明提出一种构造中间库的方法,在不对第三方软件做任何修改的前提下,通过构造中间库,解决了上述难题。
本发明具体是这样实现的:
一种构造中间库的方法,其特征在于,包括如下步骤:
第1步,通过生成第三方软件引用的外部符号以及每一个符号所对应的映射地址,生成实现函数跳转的中间文件;
第2步,通过加载映射库的符号表、完成映射库中全局变量和全局对象的初始化、完成虚函数表初始化和完成映射库中全局对象的析构操作,实现为每个映射库生成一个初始化文件;
第3步,编译链接中间文件和初始化文件,得到与映射库一一对应的中间库;
第4步,修改映射库的文件名;
第5步,把中间库放到目标文件系统中所对应的映射库目录下。
所述第一步,具体包括如下步骤:
(1)分析映射库的符号表,为映射库生成一个符号列表文件;
(2)从第三方软件的符号表中获取第三方软件引用的外部符号;
(3)生成第三方软件引用的外部符号以及每一个符号所对应的映射地址;
(4)生成实现函数跳转的中间文件。
重复上述步骤(1)至(4),可为其他映射库生成函数跳转中间文件。
所述全局变量和全局对象的初始化,可在中间库中重定义映射库中的全局变量或全局对象,并赋以映射库中相同的初始值。
所述虚函数表的初始化,通过把映射库中各个虚函数表的内容拷贝到中间库地址空间中实现。
由于第三方软件不能按照普通的动态加载和动态链接的方式调用映射库中的函数,也不能正确地访问映射库中的全局变量和全局对象。本发明通过为每一个映射库构造一个中间库,在中间库内部完成函数跳转、全局变量和全局对象初始化等操作,解决了上述难题。
采用本发明所述方法,通过构造中间库,解决了第三方软件不能访问映射库中的函数和全局变量的难题;把共享库编译链接为映射库,虽然增加了一些中间库,但是由于这些中间库都非常小,总体来看,整个软件系统的大小可减少20%~30%;并且应用程序的运行时响应速度也更快。软件变小意味着存储空间需求的减少,也就意味着硬件成本的降低,响应速度的提高意味更好的客户体验和更高的市场占有率。
附图说明
图1是支持动态链接的系统中应用程序和共享库的依赖关系模型;
图2是采用地址空间映射方式优化嵌入式软件的处理流程;
图3是采用地址空间映射方式编译的应用程序的虚拟地址空间布局;
图4是本发明所述方法的体系结构图;
图5是本发明所述方法的实施步骤。
具体实施方式
下面结合附图,对本发明所述方法进行详细的描述。
图1~图3是描述本发明相关背景技术的。
图1展示了支持动态连接的系统中应用程序和共享库的依赖关系模型。其中实线表示应用程序对共享库的依赖关系,虚线表示共享库对其它共享库的依赖关系。通常情况下,一个应用程序经常会依赖一个或多个共享库,一个共享库也可能会依赖一个或多个其它的共享库。
图2描述采用地址空间映射方法优化嵌入式软件的处理流程。按照此流程编译生成的应用程序和共享库的虚拟地址空间布局如图3所示。
图3显示采用地址空间映射方式编译的应用程序的虚拟地址空间布局。如图所示,如果一个应用程序依赖多个共享库,那么这些共享库的虚拟地址从addr1开始依次分布,每一个共享库占一个虚拟地址的槽位,虚拟地址槽位互不重叠和覆盖,应用程序的虚拟地址从addr2开始。
实践表明,映射库和使用映射库编译链接的应用程序的大小要比按照普通动态链接方式编译链接的结果小约20~30%(不同体系结构略有不同),而且,使用映射库的应用程序运行时,不再执行普通的动态链接过程,因此程序的响应速度更快。
下面结合附图4,以本发明在Linux操作系统上的应用为列来做进一步的详细说明:
图4是本发明的体系结构图。如图所示,第三方软件通过中间库访问映射库中的函数和全局变量。对于普通的动态链接,应用程序访问共享库中的函数时,首先检查被调用的函数是否已经加载到内存中,如果已经加载,则通过动态链接跳转到共享库中的函数执行,如果被调用的函数还没有加载到内存,则首先执行库的加载过程,然后在通过动态链接跳转到共享库中的函数执行。
在本发明中,映射库是不能被动态加载的,第三方软件调用映射库中的函数都已经被转换成了对中间库里面对应的跳转函数的调用,中间库中的跳转函数把程序流程跳转到映射库中指定函数的起始映射地址。
例如:某个第三方软件依赖于映射库1和映射库2,在如图3所示的虚拟地址布局中,映射库1的起始虚拟地址是maplib1addr,映射库2的起始虚拟地址是maplib2addr,第三方软件的起始虚拟地址是appaddr,第三方软件调用了映射库1中的函数maplib1func和映射库2中的函数maplib2func,这两个函数的虚拟地址在编译链接时已经确定,分别是maplib1addr+offset1和maplib2addr+offset2,中间库中与这两个函数对应的跳转函数可以用ARM汇编指令描述如下:
.glob1 maplib1func的符号
.type maplib1func的符号,#function
maplib1func的符号:
add ip,pc,#4
ldr ip,[ip]
mov pc,ip
.word maplib1addr+offset1
.glob1maplib2func的符号
.type maplib2func的符号,#function
maplib2func的符号:
addip,pc,#4
ldr ip,[ip]
mov pc,ip
.word maplib2addr+offset2
当第三方软件调用映射库1中的maplib1func函数时,程序实际调用中间库的maplib1func函数,从上面的代码可以看到,紧接着执行的四行代码将把流程跳转到虚拟地址maplib1addr+offset1,这正好就是映射库1中maplib1func函数的虚拟地址,这样就实现了对映射库中函数的调用。
中间库对映射库的初始化包括加载映射库的符号表、映射库中的全局变量和全局对象的初始化、以及虚函数表初始化。
全局变量和全局对象的初始化可以在中间库中重定义映射库中的全局变量或全局对象,并赋以映射库中相同的初始值。
初始化函数可以这样定义:
void_attribute_((constructor))lib_init()
{
加载映射库符号表;
中间库虚函数表初始化;
依次调用映射库中的构造函数,直到所有构造函数都已被执行
}
在Linux操作系统上,加载映射库的符号表可以通过设置环境变量LD_PRELOAD实现;
虚函数表的初始化可以通过把映射库中各个虚函数表的内容拷贝到中间库的地址空间中实现。
此外,中间库还要完成第三方软件退出时的善后工作,即执行映射库中全局对象的析构函数,释放资源。
在Linux操作系统上,可以在中间库中定义如下函数来实现:
void_attribute_((destructor))lib_finit()
{
依次调用映射库中的析构函数,直到所有析构函数都已被执行
}
图5展示了本发明的具体实施步骤。下面描述在Linux环境中各个子步骤的实现方法。
构造函数跳转中间文件,由以下几个步骤来具体完成:
1、分析映射库的符号表,为映射库生成一个符号列表文件:可以用nm工具方便地提取出ELF文件的符号表和它们的地址,在普通的共享库中,这个地址是共享库内部的偏移量;对映射库而言,这个地址是函数的绝对虚拟地址;
2、从第三方软件的符号表中获取第三方软件引用的外部符号:可以借助readelf、grep工具编写脚本实现;
3、生成第三方软件引用的外部符号以及每一个符号所对应的映射地址:前两步的输出是文本文件,可以编写一个shell脚本或者c程序,分析前两个子步骤输出的文本文件,从而提取出所需要的信息;
4、生成实现函数跳转功能的中间文件:跳转函数的功能简单,结构单一,因此可以用shell脚本或者c程序,根据上一步获得的第三方软件引用的外部符号和它们对应的虚拟地址,构造出跳转函数的汇编代码。跳转函数的具体处理流程参见前面对附图4的详细描述部分;
5、重复上述四个子步骤,依次为其它的映射库生成函数跳转中间文件。
构造中间库的初始化文件:初始化文件要完成的功能包括加载映射库的符号表、映射库中的全局变量和全局对象的初始化、以及虚函数表初始化,可以用汇编语言实现,也可以用c或者其它高级编程语言实现,该文件要完成的功能和具体实现参见前面对附图4的详细描述部分;
编译链接生成中间库:这是按照编译普通的共享库的方式,编译链接函数跳转中间文件和中间库的初始化文件,得到中间库。所有中间库都是标准的动态链接库。
映射库更名:修改映射库的文件名,以免与中间库文件名冲突。
最后,把每一个中间库都放到目标文件系统中它所对应的映射库所在的目录下。
完成上述操作,第三方软件就可以按照普通的方式正常运行了,不同之处在于这样生成的映射库、中间库和第三方软件的大小要比按照标准动态链接方式编译的文件小约20%~30%,而且软件的运行时响应速度更快。软件变小意味着硬件成本的降低,响应速度的提高意味更好的客户体验和更高的市场占有率。
Claims (5)
1、一种构造中间库的方法,其特征在于,包括如下步骤:
第1步,通过生成第三方软件引用的外部符号以及每一个符号所对应的映射地址,生成实现函数跳转的中间文件;
第2步,通过加载映射库的符号表、完成映射库中全局变量和全局对象的初始化、完成虚函数表初始化和完成映射库中全局对象的析构操作,实现为每个映射库生成一个初始化文件;
第3步,编译链接中间文件和初始化文件,得到与映射库一一对应的中间库;
第4步,修改映射库的文件名;
第5步,把中间库放到目标文件系统中所对应的映射库目录下。
2、如权利要求1所述的构造中间库的方法,其特征在于:
所述第一步,具体包括如下步骤:
(1)分析映射库的符号表,为映射库生成一个符号列表文件;
(2)从第三方软件的符号表中获取第三方软件引用的外部符号;
(3)生成第三方软件引用的外部符号以及每一个符号所对应的映射地址;
(4)生成实现函数跳转的中间文件。
3、如权利要求2所述的构造中间库的方法,其特征在于:
重复上述步骤(1)至(4),可为其他映射库生成函数跳转中间文件。
4、如权利要求1所述的构造中间库的方法,其特征在于:
所述全局变量和全局对象的初始化,可在中间库中重定义映射库中的全局变量或全局对象,并赋以映射库中相同的初始值。
5、如权利要求1构造中间库的方法,其特征在于:
所述虚函数表的初始化,通过把映射库中各个虚函数表的内容拷贝到中间库地址空间中实现。
Priority Applications (1)
Application Number | Priority Date | Filing Date | Title |
---|---|---|---|
CNB2006101496616A CN100535856C (zh) | 2006-10-16 | 2006-10-16 | 一种构造中间库的方法 |
Applications Claiming Priority (1)
Application Number | Priority Date | Filing Date | Title |
---|---|---|---|
CNB2006101496616A CN100535856C (zh) | 2006-10-16 | 2006-10-16 | 一种构造中间库的方法 |
Publications (2)
Publication Number | Publication Date |
---|---|
CN101165648A CN101165648A (zh) | 2008-04-23 |
CN100535856C true CN100535856C (zh) | 2009-09-02 |
Family
ID=39334358
Family Applications (1)
Application Number | Title | Priority Date | Filing Date |
---|---|---|---|
CNB2006101496616A Active CN100535856C (zh) | 2006-10-16 | 2006-10-16 | 一种构造中间库的方法 |
Country Status (1)
Country | Link |
---|---|
CN (1) | CN100535856C (zh) |
Families Citing this family (7)
Publication number | Priority date | Publication date | Assignee | Title |
---|---|---|---|---|
CN101916221A (zh) * | 2010-07-23 | 2010-12-15 | 中兴通讯股份有限公司 | 一种针对设备进行单元测试的方法和系统 |
CN105677341A (zh) * | 2016-01-04 | 2016-06-15 | 成都卫士通信息产业股份有限公司 | 一种解决软件分支语句过多的方法 |
CN107798038B (zh) * | 2017-05-05 | 2020-02-14 | 平安科技(深圳)有限公司 | 数据响应方法及数据响应设备 |
CN107391191B (zh) * | 2017-07-18 | 2020-10-13 | 杭州中天微系统有限公司 | 一种程序模块动态装载方法 |
CN107391190B (zh) * | 2017-07-18 | 2020-10-13 | 杭州中天微系统有限公司 | 一种程序模块动态装载方法 |
CN110362356B (zh) * | 2018-04-09 | 2022-06-24 | 腾讯科技(深圳)有限公司 | 函数数据处理方法、装置、计算机设备和存储介质 |
CN112667285B (zh) * | 2021-01-25 | 2023-11-03 | Vidaa(荷兰)国际控股有限公司 | 一种应用升级方法、显示设备及服务器 |
-
2006
- 2006-10-16 CN CNB2006101496616A patent/CN100535856C/zh active Active
Also Published As
Publication number | Publication date |
---|---|
CN101165648A (zh) | 2008-04-23 |
Similar Documents
Publication | Publication Date | Title |
---|---|---|
US10795660B1 (en) | Live code updates | |
CN100535856C (zh) | 一种构造中间库的方法 | |
US9161156B2 (en) | Tiles in a mobile application framework | |
US7885978B2 (en) | Systems and methods to facilitate utilization of database modeling | |
US7263699B2 (en) | Preparation of a software configuration using an XML type programming language | |
US9116680B2 (en) | Dynamically building locale objects or subsections of locale objects based on historical data | |
US20200264846A1 (en) | Generating dynamic modular proxies | |
US10331425B2 (en) | Automated source code adaption to inject features between platform versions | |
US20040268301A1 (en) | Adding new compiler methods to an integrated development environment | |
US20130173894A1 (en) | Sharing virtual functions in a shared virtual memory between heterogeneous processors of a computing platform | |
RU2009115662A (ru) | Среда разработки программного обеспечения для "тонкого" клиента | |
CN101799766B (zh) | Widget引擎中使用第三方引擎解析脚本文件的方法和装置 | |
US9141352B2 (en) | Dynamically building locale objects at run-time | |
CN102257474B (zh) | 多个运行时容器共享的值解析 | |
CN111880801A (zh) | 应用程序动态化方法、装置、电子设备 | |
CN111142848B (zh) | 一种软件程序编译方法、执行方法及装置 | |
CN116685946A (zh) | 在不停止应用的执行的情况下的更新的共享库的重新加载 | |
JP3051438B2 (ja) | 拡張グラフィック機能を与える方法 | |
Denisov | Annotations-driven configuration framework for Java applications | |
Juneau et al. | Jython and Java Integration | |
CN112988133A (zh) | 一种在引导阶段实现定制化功能及固定化函数地址的方法 | |
Swami et al. | Comparative Study on Techniques for Cross-Platform Mobile Application Development | |
US9778917B2 (en) | Dynamically building subsections of locale objects at run-time | |
Kouraklis et al. | Object-Oriented Programming (OOP) | |
Johnson et al. | Adding Functionality |
Legal Events
Date | Code | Title | Description |
---|---|---|---|
C06 | Publication | ||
PB01 | Publication | ||
C10 | Entry into substantive examination | ||
SE01 | Entry into force of request for substantive examination | ||
C14 | Grant of patent or utility model | ||
GR01 | Patent grant |