CN113835686A - 代码处理方法和装置 - Google Patents
代码处理方法和装置 Download PDFInfo
- Publication number
- CN113835686A CN113835686A CN202010513307.7A CN202010513307A CN113835686A CN 113835686 A CN113835686 A CN 113835686A CN 202010513307 A CN202010513307 A CN 202010513307A CN 113835686 A CN113835686 A CN 113835686A
- Authority
- CN
- China
- Prior art keywords
- segment
- code
- segments
- variable
- function
- 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.)
- Pending
Links
Images
Classifications
-
- G—PHYSICS
- G06—COMPUTING; CALCULATING OR COUNTING
- G06F—ELECTRIC DIGITAL DATA PROCESSING
- G06F8/00—Arrangements for software engineering
- G06F8/30—Creation or generation of source code
-
- G—PHYSICS
- G06—COMPUTING; CALCULATING OR COUNTING
- G06F—ELECTRIC DIGITAL DATA PROCESSING
- G06F8/00—Arrangements for software engineering
- G06F8/40—Transformation of program code
- G06F8/41—Compilation
Abstract
本申请提供一种代码处理方法和装置,可以应用于嵌入式系统,进一步可以用于自动驾驶、智能驾驶、机器人、无人运输等场景。该方法通过将代码切分成一个或多个段,其中,该一个或多个段中的每个段只包括一个函数或一个变量,从而,在通过链接器对上述代码进行编译链接过程中,可以通过上述一个或多个段的被引用情况,识别出上述段内的无用函数或变量,并通过删除没有被引用的段,达到删除上述段内的无用函数或变量的目的,减小了代码的体积,适应受限资源环境。而且,本申请实施例可以对代码中某一无用函数或变量进行剪裁,代码裁剪粒度更小,实现对代码中无用代码的精确剪裁。另外,本申请实施例支持多种代码,满足多种应用需要。
Description
技术领域
本申请涉及计算机技术领域,尤其涉及一种代码处理方法和装置。
背景技术
随着计算机技术的发展,嵌入式设备已经渗透到社会经济、军事、车载、通信等相关行业,并深入到信息家电、娱乐、社会文化等各个领域。在嵌入式系统发展初期,其应用相对简单,嵌入式软件由定制的汇编语言或机器语言编写,功能主要体现在一些面向控制的系统,其直接面向应用,基于系统硬件开发,专有性很强,使得在开发新的嵌入式系统时,已经存在的嵌入式软硬件资源很少能够被复用,造成了巨大的资源浪费和重复劳动。
随着微电子技术的发展,嵌入式系统的硬件功能也越来越强大,嵌入式软件也逐渐面向高级语言如C、C++、Rust等,从软件体系架构上,也由单一的控制流程,逐渐引入了嵌入式操作系统。嵌入式操作系统首先从技术上解决了嵌入式系统标准化、层次化的问题,其次嵌入式操作系统软件提供高度模块化、移植性和复用性,简化开发流程,降低开发成本,使得在嵌入式设备上开发复杂的应用成为可能。
然而,尽管半导体技术的发展使得处理器的速度不断提高,片上存储器容量也不断增加,但是在大多数情况下,存储空间仍然是宝贵的,是成本和功耗的主要影响因素之一。因此,一个理想的嵌入式系统必定是经过高效率的设计、量体裁衣、去除冗余,力争在同样的硅片面积上实现更高的性能。为了实现这个目标,如何将复杂应用或系统移植到嵌入式系统,并通过裁剪,减小代码的体积,适应受限资源环境,提供丰富的应用功能,是目前研究的热点。
发明内容
本申请提供一种代码处理方法和装置,以减小代码的体积,适应受限资源环境。
第一方面,本申请实施例提供一种代码处理方法,该方法可以由链接器执行,该方法包括如下步骤:首先,获取待处理代码,该待处理代码被分成一个或多个段,其中,该一个或多个段中的每个段只包括一个函数或一个变量。示例性的,上述变量可以包括全局变量,以待处理代码中包括段sect,段sect内有函数func1和func2,全局变量var1和var2为例,段sect被分成一个或多个段,例如,在原段名的基础上添加后缀,如段sect.func1、sect.func2、sect.var1和sect.var2,段sect被分成段sect.func1、sect.func2、sect.var1和sect.var2。段sect.func1中只包括上述函数func1,段sect.func2中只包括上述函数func2,段sect.var1中只包括上述全局变量var1,段sect.var2中只包括上述全局变量var2。另外,上述待处理代码可以根据实际情况确定,例如上述待处理代码为汇编阶段组装的目标文件中的代码,本申请实施例对此不做特别限制。其次,链接器根据上述一个或多个段的被引用情况,删除没有被引用的段,获得可执行文件,其中上述被引用情况指示一个段被其它段引用的情况。示例性的,一个段被其它段引用可以理解为链接器在对上述待处理代码编译链接过程中,该段被除该段以外的其它段引用。
本申请实施例通过获取待处理代码,该待处理代码被分成一个或多个段,该一个或多个段中的每个段只包括一个函数或一个变量,从而,在上述待处理代码包括用户自定义段(即将多个函数和/或变量放置在自定义的段名内)时,能够获取到用户自定义段中每个函数或变量单独成段的信息,进而,在对上述待处理代码进行编译链接过程中,可以通过上述一个或多个段的被引用情况,识别出用户自定义段内的无用函数或变量,并通过删除没有被引用的段,达到删除用户自定义段内的无用函数或变量的目的,减小代码的体积,适应受限资源环境。而且,本申请实施例通过删除没有被引用的段,可以对代码中某一无用函数或变量进行剪裁,代码裁剪粒度更小,实现对代码中无用代码的精确剪裁。另外,本申请实施例支持多种代码,满足多种应用需要。本申请实施例不会改变代码布局,实现用户无感知的裁剪效果。
一种可能设计,上述获得可执行文件,包括:
获取段重映射信息,该段重映射信息包括段的标识和上述段包含的函数或变量的标识的对应关系;
根据上述段映射信息修改链接脚本,该链接脚本中包含至少一个函数或变量以及该至少一个函数或变量对应的段的标识,修改后的链接脚本中上述至少一个函数或变量对应的段的标识与上述至少一个函数或变量在上述段重映射信息中对应的段的标识相同;
根据修改后的上述链接脚本获得上述可执行文件。
这里,上述链接脚本可以是预先定义/配置的。链接器在对上述待处理代码进行编译链接过程中,可能会用到上述链接脚本,由于待处理代码被分成一个或多个段,段的标识已经发生了改变,而上述链接脚本中的段却没有做相应修改。因此,为了保证后续处理正确进行,链接器获取段重映射信息,该段重映射信息包括段的标识和该段包含的函数或变量的标识的对应关系,从而基于上述段重映射信息,修正链接脚本中,修改后的链接脚本中至少一个函数或变量对应的段的标识与上述至少一个函数或变量在上述段重映射信息中对应的段的标识相同。另外,上述段的标识可以为段的名称或编号等,本申请实施例对此不做特别限制。
一种可能设计,上述根据上述段映射信息修改链接脚本可以包括:
对上述链接脚本进行解析,该解析包括词法分析和语法分析,然后根据上述段重映射信息,对解析后得到的上述链接脚本的抽象语法树进行修改,例如,将链接脚本的抽象语法树中上述至少一个函数或变量对应的段的标识的节点,修改为通配节点,使得修改后的链接脚本中上述至少一个函数或变量对应的段的标识与上述至少一个函数或变量在上述段重映射信息中对应的段的标识相同,符合代码布局逻辑。
一种可能设计,上述获得可执行文件,包括:
根据上述一个或多个段,合并上述待处理代码中的同类型段。
其中,链接器在合并代码中的同类型段时,可以计算每个段的起始地址,并考虑段间对齐所产生的偏移等问题,进而合并代码中的同类型段。
一种可能设计,上述获得可执行文件,包括:
获取上述待处理代码的重定位信息,该重定位信息包括上述待处理代码中的函数调用地址或变量调用地址,从而,根据该重定位信息,在对上述待处理代码进行编译链接过程中,修正上述待处理代码中的上述函数调用地址或上述变量调用地址,获得代码正确、完整的可执行文件。
一种可能设计,上述获得可执行文件,包括:
可以根据ELF文件结构,完成可执行文件的组装。
这里,链接器可以对上述待处理代码进行同类段的合并、重定位等处理,具体处理的内容可以根据实际情况确定,本申请实施例对此不做特别限制。
第二方面,本申请实施例提供另一种代码处理方法,该方法可以由汇编器执行,该方法包括:将源代码切分成一个或多个段,其中,该一个或多个段中的每个段只包括一个函数或一个变量。示例性的,上述变量可以包括全局变量,以源代码中包括段sect,段sect内有函数func3和func4,全局变量var3和var4为例,汇编器将段sect切分成一个或多个段,例如,在原段名的基础上添加后缀,如段sect.func3、sect.func4、sect.var3和sect.var4,汇编器将段sect切分成段sect.func3、sect.func4、sect.var3和sect.var4。段sect.func3中只包括上述函数func4,段sect.func4中只包括上述函数func4,段sect.var3中只包括上述全局变量var3,段sect.var4中只包括上述全局变量var4。另外,上述源代码可以根据实际情况确定,例如,上述源代码为用汇编语言编写的代码,本申请实施例对此不做特别限制。
本申请实施例通过将源代码切分成一个或多个段,其中,该一个或多个段中的每个段只包括一个函数或一个变量,从而,能够将用户自定义段(即将多个函数和/或变量放置在自定义的段名内)分成一个或多个段,即将用户自定义段中每个函数或变量单独成段,进而,在后续通过链接器对上述源代码进行编译链接过程中,可以通过上述一个或多个段的被引用情况,识别出用户自定义段内的无用函数或变量,并通过删除没有被引用的段,达到删除用户自定义段内的无用函数或变量的目的,减小了代码的体积,适应受限资源环境。而且,本申请实施例可以对代码中某一无用函数或变量进行剪裁,代码裁剪粒度更小,实现对代码中无用代码的精确剪裁。另外,本申请实施例支持多种代码,例如用汇编语言编写的代码,即支持任何能够编译为用汇编语言编写的代码的高级语言,满足多种应用需要。本申请实施例不会改变代码布局,实现用户无感知的裁剪效果。
一种可能设计,在上述将源代码切分成一个或多个段之后,还包括:
生成段重映射信息,该段重映射信息包括段的标识和上述段包含的函数或变量的标识的对应关系。
这里,上述段重映射信息还可以包括上述函数或变量在所在段的偏移,示例性的,上述函数或变量在所在段的偏移为0。
一种可能设计,上述将源代码切分成一个或多个段,包括:
获取上述源代码中的函数标识或变量标识;
根据上述函数标识或所述变量标识,将源代码切分成一个或多个段。
其中,上述函数标识可以为函数名称或函数编号等,上述变量标识可以为变量名称或变量编号等,具体可以根据实际情况确定,本申请实施例对此不做特别限制。
一种可能设计,上述获取上述源代码中的函数标识或变量标识,包括:
对上述源代码进行解析,该解析包括词法分析和语法分析,从而,获取上述源代码中的函数标识或变量标识,例如func为函数名称,var为全局变量名称,进而,根据上述函数标识或所述变量标识,将源代码切分成一个或多个段。
一种可能设计,如果上述源代码为用汇编语言编写的代码,在上述将源代码切分成一个或多个段之前,还包括:
读入用汇编语言编写的代码源文件,其中,该代码源文件可以是由前端编译器生成,也可以是用户直接编写的源文件。
一种可能设计,如果上述源代码为用汇编语言编写的代码,在上述将源代码切分成一个或多个段之后,还包括:
将上述用汇编语言编写的代码转换为机器代码,例如二进制代码。
这里,汇编器可以将用汇编语言编写的代码翻译成初步的机器代码,也可以依据ELF文件结构,将上述机器代码组装到目标文件内。
一种可能设计,在上述生成段重映射信息之后,还包括:
将上述段重映射信息写入预设文件,例如log文件,或者,将上述段重映射信息写入上述目标文件的附加段内,或者,将上述段重映射信息嵌入相应段名。
示例性的,汇编器将上述段重映射信息写入到某log文件,随后链接器读取该指定log文件。或者,汇编器将上述段重映射信息写入到每一个目标文件的附加段内,随后链接器在读取所有目标文件时读取这些信息。或者汇编器直接在相应段名上以一定的格式嵌入详细的重映射信息,随后链接器通过解析每一个段名进行恢复。其中,具体采用哪种形式可以根据实际情况确定,本申请实施例对此不做特别限制。
第三方面,本申请实施例提供一种代码处理装置,这里的代码处理装置可以是上述链接器本身,或者是实现链接器的功能的芯片或者集成电路。该装置包括:
代码获取模块,用于获取待处理代码,该待处理代码被分成一个或多个段,其中,该一个或多个段中的每个段只包括一个函数或一个变量;
文件获得模块,用于根据上述一个或多个段的被引用情况,删除没有被引用的段,获得可执行文件,其中上述被引用情况指示一个段被其它段引用的情况。
一种可能设计,上述文件获得模块具体用于:
获取段重映射信息,该段重映射信息包括段的标识和上述段包含的函数或变量的标识的对应关系;
根据上述段映射信息修改链接脚本,该链接脚本中包含至少一个函数或变量以及该至少一个函数或变量对应的段的标识,修改后的链接脚本中上述至少一个函数或变量对应的段的标识与上述至少一个函数或变量在所述段重映射信息中对应的段的标识相同;
根据修改后的上述链接脚本获得上述可执行文件。
第四方面,本申请实施例提供另一种代码处理装置,这里的代码处理装置可以是上述汇编器本身,或者是实现汇编器的功能的芯片或者集成电路。该装置包括:
代码切分模块,用于将源代码切分成一个或多个段,其中,该一个或多个段中的每个段只包括一个函数或一个变量。
一种可能设计,上述代码切分模块还用于:
生成段重映射信息,该段重映射信息包括段的标识和上述段包含的函数或变量的标识的对应关系。
一种可能设计,所述源代码为用汇编语言编写的代码。
第五方面,本申请提供再一种代码处理装置,该代码处理装置包括至少一个处理器和至少一个存储器。该至少一个存储器存储计算机指令;该至少一个处理器执行该存储器存储的计算机指令,使得该计算设备执行上述第一方面或者第一方面的各种可能设计提供的方法,使得该代码处理装置部署上述第三方面或者第三方面的各种可能设计提供该代码处理装置。
第六方面,本申请提供又一种代码处理装置,该代码处理装置包括至少一个处理器和至少一个存储器。该至少一个存储器存储计算机指令;该至少一个处理器执行该存储器存储的计算机指令,使得该计算设备执行上述第二方面或者第二方面的各种可能设计提供的方法,使得该代码处理装置部署上述第四方面或者第四方面的各种可能设计提供该代码处理装置。
第七方面,本申请提供一种计算机可读存储介质,该计算机可读存储介质中存储有计算机指令,该计算机指令指示计算设备执行上述第一方面或者第一方面的各种可能设计提供的方法,或者该计算机指令指示该计算设备部署上述第三方面或者第三方面的各种可能设计提供该代码处理装置。
第八方面,本申请提供另一种计算机可读存储介质,该计算机可读存储介质中存储有计算机指令,该计算机指令指示计算设备执行上述第二方面或者第二方面的各种可能设计提供的方法,或者该计算机指令指示该计算设备部署上述第四方面或者第四方面的各种可能设计提供该代码处理装置。
第九方面,本申请提供一种计算机程序或计算机程序产品,该计算机程序或计算机程序产品包括计算机指令。可选地,该计算机指令存储在计算机可读存储介质中。计算设备的处理器可以从计算机可读存储介质读取该计算机指令,处理器执行该计算机指令,使得该计算设备执行上述第一方面或者第一方面的各种可能设计提供的方法,使得该计算设备部署上述第三方面或者第三方面的各种可能设计提供该代码处理装置。
第十方面,本申请提供另一种计算机程序或计算机程序产品,该计算机程序或计算机程序产品包括计算机指令。可选地,该计算机指令存储在计算机可读存储介质中。计算设备的处理器可以从计算机可读存储介质读取该计算机指令,处理器执行该计算机指令,使得该计算设备执行上述第二方面或者第二方面的各种可能设计提供的方法,使得该计算设备部署上述第四方面或者第四方面的各种可能设计提供该代码处理装置。
第十一方面,本申请实施例提供了一种芯片,包括至少一个处理器和通信接口。进一步可选的,所述芯片还包含至少一个存储器,用于存储计算机指令。其中,所述通信接口用于为所述至少一个处理器提供信息输入和/或输出。所述至少一个处理器用于执行指令以实现执行上述第一方面及其第一方面任意可能的实现方式中的方法。可选的,所述至少一个处理器包含数字信号处理器(digital signal processor,DSP)、中央处理器(CentralProcessing Unit,CPU)或者图形处理器(general process unit,GPU)中的至少一个。
第十二方面,本申请实施例提供了另一种芯片,包括至少一个处理器和通信接口。进一步可选的,所述芯片还包含至少一个存储器,用于存储计算机指令。其中,所述通信接口用于为所述至少一个处理器提供信息输入和/或输出。所述至少一个处理器用于执行指令以实现执行上述第二方面及其第二方面任意可能的实现方式中的方法。可选的,所述至少一个处理器包含DSP、CPU或者GPU中的至少一个。
附图说明
图1为本申请实施例提供的一种代码处理系统的架构示意图;
图2为本申请实施例提供的一种代码分段示意图;
图3为本申请实施例提供的一种函数调用图;
图4为本申请实施例提供的一种链接方式示意图;
图5为本申请实施例提供的剪裁效果对比图;
图6为本申请实施例提供的一种代码处理方法的流程示意图;
图7为本申请实施例提供的另一种代码处理方法的流程示意图;
图8为本申请实施例提供的一种链接脚本修改示意图;
图9为本申请实施例提供的再一种代码处理方法的流程示意图;
图10为本申请实施例提供的又一种代码处理方法的流程示意图;
图11为本申请实施例提供的又一种代码处理方法的流程示意图;
图12为本申请实施例提供的又一种代码处理方法的流程示意图;
图13为本申请实施例提供的又一种代码处理方法的流程示意图;
图14为本申请提供的一种代码处理装置的结构示意图;
图15为本申请提供的另一种代码处理装置的结构示意图;
图16A为本申请提供的一种代码处理装置的基本硬件架构示意图;
图16B为本申请提供的另一种代码处理装置的基本硬件架构示意图。
具体实施方式
下面结合各个附图对本发明实施例技术方案的主要实现原理、具体实施方式及其对应能够达到的有益效果进行详细的阐述。以下,术语“第一”、“第二”仅用于描述目的,而不能理解为暗示或暗示相对重要性或者隐含指明所指示的技术特征的数量。由此,限定有“第一”、“第二”的特征可以明示或者隐含地包括一个或者更多个该特征,在本申请实施例的描述中,除非另有说明,“多个”的含义是两个或两个以上。
本申请实施例所涉及的代码处理是指将代码切分成一个或多个段,其中,该一个或多个段中的每个段只包括一个函数或一个变量,从而,能够将用户自定义段(即将多个函数和/或变量放置在自定义的段名内)分成一个或多个段,即将用户自定义段中每个函数或变量单独成段,进而,在通过链接器对上述代码进行编译链接过程中,可以通过上述一个或多个段的被引用情况,识别出用户自定义段内的无用函数或变量,并通过删除没有被引用的段,达到删除用户自定义段内的无用函数或变量的目的,减小了代码的体积,适应受限资源环境。
本申请实施例提供的代码处理方法及装置可应用在嵌入式系统中,其中,该系统运行在嵌入式环境上。示例性的,上述嵌入式系统可以包括嵌入式实时操作系统μC/OS-II、嵌入式Linux、Windows Embedded、VxWorks等,以及应用在车辆、无人机、机器人、手机等设备中的Android、iOS等,本申请实施例对此不做特别限制。
可选地,本申请实施例提供的代码处理方法及装置可以应用于如图1所示的应用场景中。图1只是以示例的方式描述了本申请实施例提供的代码处理方法的一种可能的应用场景,本申请实施例提供的代码处理方法的应用场景不限于图1所示的应用场景。
图1为设备通信系统代码处理架构示意图。在图1中,以无线业务SRE系统的数据处理(DP)模块为例,SRE系统运行在嵌入式环境上。考虑到不同硬件平台,开发者会定义不同的编译配置,使用大量自定义的段名,以实现在不同部署场景下的代码的灵活布局。因此需要对SRE系统的DP模块进行代码处理,以减小代码的体积,适应受限资源环境。
上述代码处理架构可以包括汇编器(assembler)10和链接器(linker)20。
汇编器10是将源代码,例如用汇编语言编写的代码,翻译为目标机器代码,例如二进制代码的转换程序,将用汇编语言编写编写的.s文件翻译成目标文件(.o文件)。汇编器10可以包括代码读入模块、代码解析模块、段重映射模块和代码生成模块中至少一个。
在具体实现过程中,代码读入模块可以用于读入源代码,例如读入SRE系统的DP模块对应的用汇编语言编写的.s文件。
代码解析模块可以用于对读入的代码做解析,例如词法分析(lexer)和语法分析(parser),生成抽象语法树。通过解析,可识别语法模块,比如将sect视为段的名称,func视为函数名称,var视为全局变量名称。
段重映射模块可以用于将上述代码切分成一个或多个段,其中,该一个或多个段中的每个段只包括一个函数或一个变量,即上述代码的每个函数或变量被分配在独立的段(section)内,进而,生成段重映射信息(remapping information)。这里,段重映射模块会处理代码中所有的函数和变量,包括用户自定义段的部分,即能够将用户自定义段切分成一个或多个段,即将用户自定义段中每个函数或变量单独成段。示例性的,如图2所示,以上述代码中包括段sect,段sect内有函数func3和func4,全局变量var3和var4为例。段重映射模块将段sect切分成一个或多个段,例如,在原段名的基础上添加后缀,如段sect.func3、sect.func4、sect.var3和sect.var4,即段重映射模块将段sect切分成段sect.func3、sect.func4、sect.var3和sect.var4,段sect.func3中只包括上述函数func4,段sect.func4中只包括上述函数func4,段sect.var3中只包括上述全局变量var3,段sect.var4中只包括上述全局变量var4,即上述代码中的每个函数或变量单独成段。
代码生成模块可以用于将上述代码,例如SRE系统的DP模块对应的用汇编语言编写的代码翻译为目标机器代码,例如二进制代码,并组装到目标文件内。
这里,汇编器10在汇编阶段完成后,除常规的输出(目标文件等信息)之外,会额外输出段重映射信息供后续的链接器20使用。
另外,上述汇编器10还可以包括发送传输模块,该发送传输模块可以是输入/输出接口,也可以是通信接口,可以用于发送目标文件、段重映射信息等给链接器20。
链接器20是将多个目标文件正确地合并为可执行文件,链接器20可以包括文件读入模块、同类段合并模块、段垃圾回收模块、重定位模块、段布局管理模块和文件生成模块中至少一个。
在具体实现过程中,文件读入模块可以用于读入目标文件,这里,文件读入模块可以是输入/输出接口,也可以是通信接口,可以用于接收上述汇编器10发送的目标文件。
同类段合并模块可以用于合并目标文件的同类型段。
段垃圾回收模块可以用于通过判断段是否被引用,删除没有被引用的段,从而,将目标文件的无用的冗余代码删除。
重定位(relocation)模块可以用于按照重定位信息,对已经生成的代码做地址修正。
段布局管理模块可以用于在进行最终可执行文件组装之前,读取预先定义或者配置的链接脚本(lds),如图中.ld文件,根据链接脚本的语义,进行段布局管理。其间,使用汇编阶段提供的段重映射信息,修正链接脚本,使得输入文件中的段能正确映射到输出文件中对应的段内。
文件生成模块可以最后完成可执行文件的组装(code combination),例如根据ELF文件结构,完成可执行文件的组装,如图中.elf文件。
应理解,代码解析模块、段重映射模块、代码生成模块、同类段合并模块、段垃圾回收模块、重定位模块、段布局管理模块或者文件生成模块可以通过读取存储器中的指令并执行指令的方式实现,也可以通过芯片电路实现。
本申请实施例提供的代码处理方法可应用于汇编器10或者链接器20。
可以理解的是,本申请实施例示意的结构并不构成对代码处理架构的具体限定。在本申请另一些可行的实施方式中,上述代码处理架构可以包括比图示更多或更少的部件,或者组合某些部件,或者拆分某些部件,或者不同的部件布置,具体可根据实际应用场景确定,在此不做限制。图1所示的部件可以以硬件,软件,或软件与硬件的组合实现。
相关技术中,尽管半导体技术的发展使得处理器的速度不断提高,片上存储器容量也不断增加,但是大多数情况下,存储空间仍然是宝贵的,是成本和功耗的主要影响因素之一。因此,一个理想的嵌入式系统必定是经过高效率的设计、量体裁衣、去除冗余,力争在同样的硅片面积上实现更高的性能。为了实现这个目标,将复杂应用或系统移植到嵌入式系统,并通过裁剪,减小代码的体积,适应受限资源环境,提供丰富的应用功能,是目前研究的热点。
为了解决上述问题,现有主要有以下三种技术方案:
第一种技术方案是基于配置的裁剪方法,其可对系统、处理器架构、驱动等进行配置,设置为编译选项,在编译阶段根据应用需求进行取舍,读取配置文件,产生编译宏,决定所编译的文件列表,从而实现对系统的裁剪。
其裁剪的原理及流程包括:
首先获取配置文件。该配置文件通过某种描述语言对源代码组织结构和它们之间的依赖关系进行刻画。其次,利用程序分析配置文件,产生交互式的可视化的剪裁与配置界面,依据应用需求实现系统模块的剪裁和系统参数的配置,并将配置信息写入配置文件。最后,利用编译器进行条件编译形成实际运行的目标代码,并能对所生成的目标系统进行正确性测试。
然而,第一种技术方案裁剪的粒度过大,裁剪的最小单元为系统的整个功能模块,而且,在系统中需要插入许多条件编译语句,降低了源代码的可读性和维护性,增加了调试和测试的复杂性。
第二种技术方案是基于调用图(call graph)的裁剪方法。这里,函数或进程之间相互调用的关系即为调用关系,用于清楚表示这种调用关系的视图即为调用图。根据调用图,从源代码中分析调用关系,进行程序分析,判断是否存在从未被调用过的函数,若存在,则可将其删除。
程序的调用图定义为一个有向图C=(V,R),其中V表示程序中所有函数的集合,每个函数是调用图中的一个顶点,R表示函数之间调用关系的集合,即:
R={(V1,V2)|V1,V2∈V and V1调用V2一次以上}
举例说明,根据如下所示一段应用程序代码:
其对应的函数调用图如图3所示。定义:
裁剪依据:如果存在一个函数Q不属于S(main),那么Q就是应用程序不需要的函数,应该将Q从程序中删除。在图3所示的例子中,函数func5()和func6()是可以删除的。
然而,第二种技术方案对于变量(例如全局变量)无法裁剪,而且裁剪速度慢,为获取全局调用图,需进行二次编译,随着代码体积增长,基于源代码的程序分析并重新编译的开销会越来越大。
第三种技术方案是基于编译系统的段垃圾回收机制(section GC)。
为了更好的理解上述技术方案,首先了解一下可执行文件的生成过程。大多数情况下,编译器会把编译C代码生成的所有可执行代码放入.text段,只读数据放入.rodata段,读写数据放入.data段以及未初始化的数据放入.bss段,例如:
module1.c
int f(void){return 0;}
void unused_func(void){a_lot_of_code;}
main.c
int main(int argc,char**argv){return f();}
其中,module1.o的.text段包含f()与unused_func(),unused_func()并未被main()调用,属于无用代码;main.o的.text段包含main()的代码。当module1.o与其他.o被编译进一个公共库lib.a时,可以通过编译器将main.o与lib.a编译链接,生成一个可执行文件。可执行文件的产生通过链接器对符号进行解析。如图4所示,首先链接器查到main.o有一个未定义的符号f,接着链接器扫描lib.a并且发现module1.o有该符号的定义,于是链接器就会添加module1.o所有段,将完整的.text段添加进入可执行文件。而且,unused_func()也被添加到可执行文件中。由于链接器不清楚module1.o的.text段与module1.c内多个函数的布局对应关系,因此无法删除unused_func的代码,唯一知道的也只是f函数的起始地址,但即便是知道了f的代码大小,由于f可能会跳转到.text段内任意的地址,因此链接器只能选择将完整的.text段引入。
为解决这个问题,编译器使用两个编译选项(-ffunction-sections、-fdata-sections)将每个函数、全局变量放置到独立的唯一的段内。这样,链接器就可以通过段来区分不同的函数/变量实体,再通过—gc-sections链接选项,告知链接器在将所有段放置入可执行文件之前,丢弃那些无法从种子段(seed sections)到达的代码段或数据段。种子段指的是一些入口函数,如main(),是默认的第一个函数入口。
然而,第三种技术方案对于用户自定义段的情况,无法进行回收。因为第三种技术方案的一个前提是需将函数或变量放于唯一的段内,但是由于在很多嵌入式场景下,开发者会对一些函数或数据自定义特定的段名,以便定制化地对函数或数据归类,用于如内存保护、初始化内存销毁等操作。因此,用户自定义段(即,将多个函数/变量放置在自定义的段名内)与第三种技术方案的前提(即,将所有函数/变量放置在单独且唯一的段内)存在矛盾,导致第三种技术方案无法删除用户自定义段内的无用函数/变量。而且第三种技术方案无法直接对汇编语言进行无用代码/数据的裁剪。段名称的赋值是在编译器阶段完成的,因此汇编文件中的函数与变量依然会被合并入同一个代码段或数据段。
因此,为了解决上述问题,本申请实施例提供了一种代码处理方法,通过将代码切分成一个或多个段,其中,该一个或多个段中的每个段只包括一个函数或一个变量,从而,能够将用户自定义段(即将多个函数和/或变量放置在自定义的段名内)分成一个或多个段,即将用户自定义段中每个函数或变量单独成段,进而,在通过链接器对上述代码进行编译链接过程中,可以通过上述一个或多个段的被引用情况,识别出用户自定义段内的无用函数或变量,并通过删除没有被引用的段,达到删除用户自定义段内的无用函数或变量的目的,减小了代码的体积,适应受限资源环境。而且,本申请实施例可以对代码中某一无用函数或变量进行剪裁,代码裁剪粒度更小,实现对代码中无用代码的精确剪裁。另外,本申请实施例支持多种代码,满足多种应用需要。本申请实施例不会改变代码布局,实现用户无感知的裁剪效果。
示例性的,图5给出使用上述第三种方案(在图5中简称方案三)和本申请方案,分别对上述SRE系统的DP模块进行代码处理,统计构建生成的可执行文件大小的示意图。其中,可执行文件的大小包括主要section的大小(代码段text,数据段data,未初始化数据段bss)和整个文件的大小。
根据对可执行文件的统计数据,可计算上述第三种方案和本申请方案对代码裁剪比例,如图5所示:
与原始版本相比,本申请方案的裁剪效果全面优于上述第三种方案。比如,对data段,本申请方案的裁剪效果由上述第三种方案的47.62%提升至87.30%,增幅高达39.68%;对text段,本申请方案的裁剪效果由上述第三种方案的56.65%提升至73.49%,增幅高达16.84%;对整个文件,本申请方案的裁剪效果由上述第三种方案的52.80%提升至62.40%,增幅高达9.60%;对上述第三种方案效果不明显的bss段,本申请方案仍能有4.95%的裁剪效果。
由此可见,本申请技术方案对SRE系统的DP模块的无用代码进行准确剪裁,减小了代码的体积,适应受限资源环境。
下面以几个实施例为例对本申请的技术方案进行描述,对于相同或相似的概念或过程可能在某些实施例不再赘述。
图6为本申请实施例提供了一种代码处理方法的流程示意图,本实施例的执行主体可以为图1中的链接器20。如图6所示,该方法可以包括如下步骤。
S601:获取待处理代码,该待处理代码被分成一个或多个段,其中,该一个或多个段中的每个段只包括一个函数或一个变量。
这里,上述变量包括全局变量。上述待处理代码中的每个函数或变量被分别存放在一个独立段内,示例性的,以待处理代码中包括段sect,段sect内有函数func1和func2,全局变量var1和var2为例,段sect被分成一个或多个段,例如,在原段名的基础上添加后缀,如段sect.func1、sect.func2、sect.var1和sect.var2,段sect被分成段sect.func1、sect.func2、sect.var1和sect.var2。段sect.func1中只包括上述函数func1,段sect.func2中只包括上述函数func2,段sect.var1中只包括上述全局变量var1,段sect.var2中只包括上述全局变量var2。
其中,上述待处理代码可以根据实际情况确定,例如上述待处理代码为汇编阶段组装的目标文件中的代码,本申请实施例对此不做特别限制。
S602:根据上述一个或多个段的被引用情况,删除没有被引用的段,获得可执行文件,其中上述被引用情况指示一个段被其它段引用的情况。
其中,上述被引用情况可以指示上述段被引用的情况。示例性的,一个段被其它段引用可以理解为链接器在对上述待处理代码编译链接过程中,该段被除该段以外的其它段引用。
示例性的,上述获得可执行文件,包括:
根据ELF文件结构,完成可执行文件的组装。
本申请实施例,通过获取待处理代码,该待处理代码被分成一个或多个段,该一个或多个段中的每个段只包括一个函数或一个变量,从而,在上述待处理代码包括用户自定义段(即将多个函数和/或变量放置在自定义的段名内)时,能够获取到用户自定义段中每个函数或变量单独成段的信息,进而,在对上述待处理代码进行编译链接过程中,可以通过上述一个或多个段的被引用情况,识别出用户自定义段内的无用函数或变量,并通过删除没有被引用的段,达到删除用户自定义段内的无用函数或变量的目的,减小代码的体积,适应受限资源环境。而且,本申请实施例通过删除没有被引用的段,可以对代码中某一无用函数或变量进行剪裁,代码裁剪粒度更小,实现对代码中无用代码的精确剪裁。另外,本申请实施例支持多种代码,满足多种应用需要。本申请实施例不会改变代码布局,实现用户无感知的裁剪效果。
另外,本申请实施例在上述获得可执行文件时,还考虑对链接脚本进行相应修改。图7为本申请实施例提出的另一种代码处理方法的流程示意图,本实施例的执行主体可以为图1所示实施例中的链接器20。如图7所示,该方法包括:
S701:获取待处理代码,该待处理代码被分成一个或多个段,其中,该一个或多个段中的每个段只包括一个函数或一个变量。
S702:根据上述一个或多个段的被引用情况,删除没有被引用的段,其中上述被引用情况指示一个段被其它段引用的情况。
其中,步骤S701-S702的实现方式可以参照上述步骤S601-S602的实现方式,此处不再赘述。
S703:获取段重映射信息,该段重映射信息包括段的标识和上述段包含的函数或变量的标识的对应关系。
S704:根据上述段映射信息修改链接脚本,该链接脚本中包含至少一个函数或变量以及该至少一个函数或变量对应的段的标识,修改后的链接脚本中上述至少一个函数或变量对应的段的标识与上述至少一个函数或变量在上述段重映射信息中对应的段的标识相同。
S705:根据修改后的上述链接脚本获得上述可执行文件。
这里,上述链接脚本可以是预先定义/配置的。链接器在对上述待处理代码进行编译链接过程中,可能会用到上述链接脚本,由于待处理代码被分成一个或多个段,段的标识已经发生了改变,而上述链接脚本中的段却没有做相应修改。因此,为了保证后续处理正确进行,链接器获取段重映射信息,该段重映射信息包括段的标识和该段包含的函数或变量的标识的对应关系,从而基于上述段重映射信息,修正链接脚本中,修改后的链接脚本中至少一个函数或变量对应的段的标识与上述至少一个函数或变量在上述段重映射信息中对应的段的标识相同。另外,上述段的标识可以为段的名称或编号等,本申请实施例对此不做特别限制。
一种可能设计,上述根据上述段映射信息修改链接脚本可以包括:
对上述链接脚本进行解析,该解析包括词法分析和语法分析,然后根据上述段重映射信息,对解析后得到的上述链接脚本的抽象语法树进行修改,例如,将链接脚本的抽象语法树中上述至少一个函数或变量对应的段的标识的节点,修改为通配节点,使得修改后的链接脚本中上述至少一个函数或变量对应的段的标识与上述至少一个函数或变量在上述段重映射信息中对应的段的标识相同,符合代码布局逻辑。
如图8所示,图8通过一个示例详细描述了上述过程。链接器对链接脚本test.ld做词法分析和语法分析得到抽象语法树AST。链接器遍历该AST,识别AST中上述至少一个函数或变量对应的段的标识的节点,例如图中输入段(input section)的标识的节点,该标识为段的名称,将其名称修改为通配节点。示例中,输入段.func和.data分别被修改为.func.*和.data.*,使得修改后的链接脚本中上述至少一个函数或变量对应的段的标识与上述至少一个函数或变量在上述段重映射信息中对应的段的标识相同,进而使得上述待处理代码中的段正确映射到上述可执行文件中。
本申请实施例,在对上述待处理代码进行编译链接过程中,获取上述段重映射信息,修正链接脚本,使得待处理代码中的段正确映射到上述可执行文件中。而且本申请实施例通过获取待处理代码,该待处理代码被分成一个或多个段,该一个或多个段中的每个段只包括一个函数或一个变量,从而,在上述待处理代码包括用户自定义段(即将多个函数和/或变量放置在自定义的段名内)时,能够获取到用户自定义段中每个函数或变量单独成段的信息,进而,在对上述待处理代码进行编译链接过程中,可以通过上述一个或多个段的被引用情况,识别出用户自定义段内的无用函数或变量,并通过删除没有被引用的段,达到删除用户自定义段内的无用函数或变量的目的,减小代码的体积,适应受限资源环境。而且,本申请实施例通过删除没有被引用的段,可以对代码中某一无用函数或变量进行剪裁,代码裁剪粒度更小,实现对代码中无用代码的精确剪裁。另外,本申请实施例支持多种代码,满足多种应用需要。本申请实施例不会改变代码布局,实现用户无感知的裁剪效果。
另外,本申请实施例在上述获得可执行文件时,还考虑对上述待处理代码进行同类段的合并、重定位等处理。图9为本申请实施例提出的再一种代码处理方法的流程示意图,本实施例的执行主体可以为图1所示实施例中的链接器20。如图9所示,该方法包括:
S901:获取待处理代码,该待处理代码被分成一个或多个段,其中,该一个或多个段中的每个段只包括一个函数或一个变量。
S902:根据上述一个或多个段的被引用情况,删除没有被引用的段,其中上述被引用情况指示一个段被其它段引用的情况。
其中,步骤S901-S902的实现方式可以参照上述步骤S601-S602的实现方式,此处不再赘述。
S903:根据上述一个或多个段,合并上述待处理代码中的同类型段。
其中,链接器在合并代码中的同类型段时,可以计算每个段的起始地址,并考虑段间对齐所产生的偏移等问题,进而合并代码中的同类型段。
S904:获取上述待处理代码的重定位信息,该重定位信息包括上述待处理代码中的函数调用地址或变量调用地址,从而,根据该重定位信息,在对上述待处理代码进行编译链接过程中,修正上述待处理代码中的上述函数调用地址或上述变量调用地址,获得代码正确、完整的可执行文件。
这里,链接器可以对上述待处理代码进行同类段的合并、重定位等处理,具体处理的内容可以根据实际情况确定,本申请实施例对此不做特别限制。
另外,链接器在对上述待处理代码进行编译链接过程中,删除没有被引用的段,进行同类段的合并、重定位等的前后顺序可以根据实际情况确定,本申请实施例对此不做特别限制。
本申请实施例,在上述获得可执行文件时,还考虑对上述待处理代码进行同类段的合并、重定位等处理,满足应用需要。而且本申请实施例通过获取待处理代码,该待处理代码被分成一个或多个段,该一个或多个段中的每个段只包括一个函数或一个变量,从而,在上述待处理代码包括用户自定义段(即将多个函数和/或变量放置在自定义的段名内)时,能够获取到用户自定义段中每个函数或变量单独成段的信息,进而,在对上述待处理代码进行编译链接过程中,可以通过上述一个或多个段的被引用情况,识别出用户自定义段内的无用函数或变量,并通过删除没有被引用的段,达到删除用户自定义段内的无用函数或变量的目的,减小代码的体积,适应受限资源环境。而且,本申请实施例通过删除没有被引用的段,可以对代码中某一无用函数或变量进行剪裁,代码裁剪粒度更小,实现对代码中无用代码的精确剪裁。另外,本申请实施例支持多种代码,满足多种应用需要。本申请实施例不会改变代码布局,实现用户无感知的裁剪效果。
另外,本申请实施例在上述获得可执行文件时,不仅考虑对链接脚本进行相应修改,还考虑对上述待处理代码进行同类段的合并、重定位等处理。图10为本申请实施例提出的又一种代码处理方法的流程示意图,本实施例的执行主体可以为图1所示实施例中的链接器20。如图10所示,在图10中以一组上述目标文件作为输入,该方法包括:
S1001:扫描上述目标文件信息,获取待处理代码,该待处理代码被分成一个或多个段,其中,该一个或多个段中的每个段只包括一个函数或一个变量。
S1002:在对上述待处理代码进行编译链接过程中,根据上述一个或多个段,合并上述待处理代码中的同类型段。
S1003:根据上述一个或多个段的被引用情况,删除没有被引用的段。
S1004:获取上述待处理代码的重定位信息,该重定位信息包括上述待处理代码中的函数调用地址或变量调用地址,从而,根据该重定位信息,在对上述待处理代码进行编译链接过程中,修正上述待处理代码中的上述函数调用地址或上述变量调用地址,使得代码正确、完整。
S1005:获取段重映射信息,该段重映射信息包括段的标识和上述段包含的函数或变量的标识的对应关系。根据上述段映射信息修改链接脚本,该链接脚本中包含至少一个函数或变量以及该至少一个函数或变量对应的段的标识,修改后的链接脚本中上述至少一个函数或变量对应的段的标识与上述至少一个函数或变量在上述段重映射信息中对应的段的标识相同。根据修改后的上述链接脚本获得上述可执行文件。
S1006:根据ELF文件结构,完成可执行文件的组装。
这里,链接器在对上述待处理代码进行编译链接过程中,删除没有被引用的段,对链接脚本进行相应修改,以及进行同类段的合并、重定位等的前后顺序可以根据实际情况确定,本申请实施例对此不做特别限制。
本申请实施例,在对上述待处理代码进行编译链接过程中,获取上述段重映射信息,修正链接脚本,使得待处理代码中的段正确映射到上述可执行文件中。而且,本申请实施例,在上述获得可执行文件时,还考虑对上述待处理代码进行同类段的合并、重定位等处理,满足应用需要。另外,本申请实施例通过获取待处理代码,该待处理代码被分成一个或多个段,该一个或多个段中的每个段只包括一个函数或一个变量,从而,在上述待处理代码包括用户自定义段(即将多个函数和/或变量放置在自定义的段名内)时,能够获取到用户自定义段中每个函数或变量单独成段的信息,进而,在对上述待处理代码进行编译链接过程中,可以通过上述一个或多个段的被引用情况,识别出用户自定义段内的无用函数或变量,并通过删除没有被引用的段,达到删除用户自定义段内的无用函数或变量的目的,减小代码的体积,适应受限资源环境。本申请实施例通过删除没有被引用的段,可以对代码中某一无用函数或变量进行剪裁,代码裁剪粒度更小,实现对代码中无用代码的精确剪裁。本申请实施例支持多种代码,满足多种应用需要。本申请实施例不会改变代码布局,实现用户无感知的裁剪效果。
以上结合图6-10从链接器20侧详细描述了根据本申请实施例的代码处理方法,下面将结合图11-13从汇编器10侧详细描述根据本申请实施例提供的又一代码处理方法。应理解,汇编器10侧描述的某些概念、特性等与链接器20侧的描述相应,为了简洁,适当省略重复的描述。
图11为本申请实施例提供了又一种代码处理方法的流程示意图,本实施例的执行主体可以为图1所示实施例中的汇编器10,如图11所示,该方法可以包括:
S1101:将源代码切分成一个或多个段,其中,该一个或多个段中的每个段只包括一个函数或一个变量。
这里,上述源代码中的每个函数和变量被分别存放在一个独立段内,示例性的,上述变量可以包括全局变量,以源代码中包括段sect,段sect内有函数func3和func4,全局变量var3和var4为例,汇编器将段sect切分成一个或多个段,例如,在原段名的基础上添加后缀,如段sect.func3、sect.func4、sect.var3和sect.var4,汇编器将段sect切分成段sect.func3、sect.func4、sect.var3和sect.var4。段sect.func3中只包括上述函数func4,段sect.func4中只包括上述函数func4,段sect.var3中只包括上述全局变量var3,段sect.var4中只包括上述全局变量var4。
上述源代码可以根据实际情况确定,例如,上述源代码为用汇编语言编写的代码,本申请实施例对此不做特别限制。
示例性的,如果上述源代码为用汇编语言编写的代码,在上述将源代码切分成一个或多个段之前,还包括:
读入用汇编语言编写的代码源文件,其中,该代码源文件可以是由前端编译器生成,也可以是用户直接编写的源文件。
在一些可行的实施方式中,如果上述源代码为用汇编语言编写的代码,在上述将源代码切分成一个或多个段之后,还包括:
将上述用汇编语言编写的代码转换为机器代码,例如二进制代码。
这里,汇编器可以将用汇编语言编写的代码翻译成初步的机器代码,也可以依据ELF文件结构,将上述机器代码组装到目标文件内。
在一些可行的实施方式中,在上述将源代码切分成一个或多个段之后,还包括:
生成段重映射信息,该段重映射信息包括段的标识和上述段包含的函数或变量的标识的对应关系。
这里,上述段重映射信息还可以包括上述函数或变量在所在段的偏移,示例性的,上述函数或变量在所在段的偏移为0。
另外,在上述生成段重映射信息之后,还包括:
将上述段重映射信息写入预设文件,例如log文件,或者,将上述段重映射信息写入上述目标文件的附加段内,或者,将上述段重映射信息嵌入相应段名。
示例性的,汇编器将上述段重映射信息写入到某log文件,随后链接器读取该指定log文件。或者,汇编器将上述段重映射信息写入到每一个目标文件的附加段内,随后链接器在读取所有目标文件时读取这些信息。或者汇编器直接在相应段名上以一定的格式嵌入详细的重映射信息,随后链接器通过解析每一个段名进行恢复。其中,具体采用哪种形式可以根据实际情况确定,本申请实施例对此不做特别限制。
本申请实施例通过将源代码切分成一个或多个段,其中,该一个或多个段中的每个段只包括一个函数或一个变量,从而,能够将用户自定义段(即将多个函数和/或变量放置在自定义的段名内)分成一个或多个段,即将用户自定义段中每个函数或变量单独成段,进而,在后续通过链接器对上述源代码进行编译链接过程中,可以通过上述一个或多个段的被引用情况,识别出用户自定义段内的无用函数或变量,并通过删除没有被引用的段,达到删除用户自定义段内的无用函数或变量的目的,减小了代码的体积,适应受限资源环境。而且,本申请实施例可以对代码中某一无用函数或变量进行剪裁,代码裁剪粒度更小,实现对代码中无用代码的精确剪裁。另外,本申请实施例支持多种代码,例如用汇编语言编写的代码,即支持任何能够编译为用汇编语言编写的代码的高级语言,满足多种应用需要。本申请实施例不会改变代码布局,实现用户无感知的裁剪效果。
另外,本申请实施例将源代码切分成一个或多个段时,还考虑获取上述源代码中的函数标识或变量标识,进而,根据该函数标识或所述变量标识,将源代码切分成一个或多个段。图12为本申请实施例提出的又一种代码处理方法的流程示意图,本实施例的执行主体可以为图1所示实施例中的汇编器10。如图12所示,该方法包括:
S1201:获取上述源代码中的函数标识或变量标识。
其中,上述函数标识可以为函数名称或函数编号等,上述变量标识可以为变量名称或变量编号等,具体可以根据实际情况确定,本申请实施例对此不做特别限制。
一种可能设计,上述获取上述源代码中的函数标识或变量标识,包括:
对上述源代码进行解析,该解析包括词法分析和语法分析,从而,获取上述源代码中的函数标识或变量标识,例如func为函数名称,var为全局变量名称,进而,根据上述函数标识或所述变量标识,将源代码切分成一个或多个段。
S1202:根据上述函数标识或所述变量标识,将源代码切分成一个或多个段。
其中,步骤S1202的实现方式可以参照上述步骤S1101的实现方式,此处不再赘述。
本申请实施例,在对源代码进行分段时,还考虑获取上述源代码中的函数标识或变量标识,进而,根据该函数标识或所述变量标识,将源代码切分成一个或多个段,满足应用需要。而且本申请实施例通过将源代码切分成一个或多个段,其中,该一个或多个段中的每个段只包括一个函数或一个变量,从而,能够将用户自定义段(即将多个函数和/或变量放置在自定义的段名内)分成一个或多个段,即将用户自定义段中每个函数或变量单独成段,进而,在后续通过链接器对上述源代码进行编译链接过程中,可以通过上述一个或多个段的被引用情况,识别出用户自定义段内的无用函数或变量,并通过删除没有被引用的段,达到删除用户自定义段内的无用函数或变量的目的,减小了代码的体积,适应受限资源环境。而且,本申请实施例可以对代码中某一无用函数或变量进行剪裁,代码裁剪粒度更小,实现对代码中无用代码的精确剪裁。另外,本申请实施例支持多种代码,例如用汇编语言编写的代码,即支持任何能够编译为用汇编语言编写的代码的高级语言,满足多种应用需要。本申请实施例不会改变代码布局,实现用户无感知的裁剪效果。
另外,本申请实施例以上述源代码为用汇编语言编写的代码给出又一种代码处理方法。图13为本申请实施例提出的又一种代码处理方法的流程示意图,本实施例的执行主体可以为图1所示实施例中的汇编器10。如图13所示,该方法包括:
S1301:读入用汇编语言编写的代码源文件,其中,用汇编语言编写的代码源文件可以是由前端编译器生成,也可以是用户直接编写的源文件。
S1302:对上述用汇编语言编写的代码源文件做解析,该解析包括词法分析和语法分析,从而,获取上述用汇编语言编写的代码中的函数标识或变量标识。
S1303:根据上述函数标识或所述变量标识,对上述用汇编语言编写的代码切分成一个或多个段,其中,该一个或多个段中的每个段只包括一个函数或一个变量。
S1304:生成段重映射信息,该段重映射信息包括段的标识和上述段包含的函数或变量的标识的对应关系。
这里,汇编器可以将上述段重映射信息写入到某log文件,随后链接器读取该指定log文件。或者,汇编器也可以将上述段重映射信息写入到每一个目标文件的附加段内,随后链接器在读取所有目标文件时读取这些信息。或者汇编器直接在相应段名上以一定的格式嵌入详细的重映射信息,随后链接器通过解析每一个段名进行恢复。其中,具体采用哪种形式可以根据实际情况确定,本申请实施例对此不做特别限制。
S1305:将上述用汇编语言编写的代码转换为机器代码,例如二进制代码。
这里,汇编器可以将用汇编语言编写的代码翻译成初步的机器代码,也可以依据ELF文件结构,将上述机器代码组装到目标文件内。
本申请实施例,通过将用汇编语言编写的代码切分成一个或多个段,其中,该一个或多个段中的每个段只包括一个函数或一个变量,从而,能够将用户自定义段(即将多个函数和/或变量放置在自定义的段名内)分成一个或多个段,即将用户自定义段中每个函数或变量单独成段,进而,在后续通过链接器对上述代码进行编译链接过程中,可以通过上述一个或多个段的被引用情况,识别出用户自定义段内的无用函数或变量,并通过删除没有被引用的段,达到删除用户自定义段内的无用函数或变量的目的,减小了代码的体积,适应受限资源环境。而且,本申请实施例可以对代码中某一无用函数或变量进行剪裁,代码裁剪粒度更小,实现对代码中无用代码的精确剪裁。另外,本申请实施例支持多种代码,例如用汇编语言编写的代码,即支持任何能够编译为用汇编语言编写的代码的高级语言,满足多种应用需要。本申请实施例不会改变代码布局,实现用户无感知的裁剪效果。
图14为本申请提供的一种代码处理装置的结构示意图,该装置包括:代码获取模块1401和文件获得模块1402。这里的代码处理装置可以是上述链接器本身,或者是实现链接器的功能的芯片或者集成电路。这里需要说明的是,代码获取模块和文件获得模块的划分只是一种逻辑功能的划分,物理上两者可以是集成的,也可以是独立的。
其中,代码获取模块1401,用于获取待处理代码,该待处理代码被分成一个或多个段,其中,该一个或多个段中的每个段只包括一个函数或一个变量。
文件获得模块1402,用于根据上述一个或多个段的被引用情况,删除没有被引用的段,获得可执行文件,其中上述被引用情况指示一个段被其它段引用的情况。
一种可能设计,上述文件获得模块1402具体用于:
获取段重映射信息,该段重映射信息包括段的标识和上述段包含的函数或变量的标识的对应关系;
根据上述段映射信息修改链接脚本,该链接脚本中包含至少一个函数或变量以及该至少一个函数或变量对应的段的标识,修改后的链接脚本中上述至少一个函数或变量对应的段的标识与上述至少一个函数或变量在所述段重映射信息中对应的段的标识相同;
根据修改后的上述链接脚本获得上述可执行文件。
本实施例的装置,对应地可用于执行上述方法所示实施例中的技术方案,其实现原理、实现细节和技术效果类似,此处不再赘述。
图15为本申请提供的另一种代码处理装置的结构示意图,该装置包括:代码切分模块1501。这里的代码处理装置可以是上述汇编器本身,或者是实现汇编器的功能的芯片或者集成电路。这里需要说明的是,代码切分模块的划分只是一种逻辑功能的划分,物理上两者可以是集成的,也可以是独立的。
其中,代码切分模块1501,用于将源代码切分成一个或多个段,其中,该一个或多个段中的每个段只包括一个函数或一个变量。
一种可能设计,上述代码切分模块1501还用于:
生成段重映射信息,该段重映射信息包括段的标识和上述段包含的函数或变量的标识的对应关系。
一种可能设计,上述源代码为用汇编语言编写的代码。
本实施例的装置,对应地可用于执行上述方法所示实施例中的技术方案,其实现原理、实现细节和技术效果类似,此处不再赘述。
可选地,图16A和16B示意性地提供本申请所述代码处理装置的一种可能的基本硬件架构。
参见图16A和16B,代码处理装置1600包括至少一个处理器1601以及通信接口1603。进一步可选的,还可以包括存储器1602和总线1604。
其中,代码处理装置1600可以是计算机或服务器,本申请对此不作特别限制。代码处理装置1600中,处理器1601的数量可以是一个或多个,图16A和16B仅示意了其中一个处理器1601。可选地,处理器1601,可以是中央处理器(central processing unit,CPU)、图形处理器(graphics processing unit,GPU)或者数字信号处理器(digital signalprocessor,DSP)。如果代码处理装置1600具有多个处理器1601,多个处理器1601的类型可以不同,或者可以相同。可选地,代码处理装置1600的多个处理器1601还可以集成为多核处理器。
存储器1602存储计算机指令和数据;存储器1602可以存储实现本申请提供的上述代码处理方法所需的计算机指令和数据,例如,存储器1602存储用于实现上述代码处理方法的步骤的指令。存储器1602可以是以下存储介质的任一种或任一种组合:非易失性存储器(例如只读存储器(ROM)、固态硬盘(SSD)、硬盘(HDD)、光盘),易失性存储器。
通信接口1603可以为所述至少一个处理器提供信息输入/输出。也可以包括以下器件的任一种或任一种组合:网络接口(例如以太网接口)、无线网卡等具有网络接入功能的器件。
可选的,通信接口1603还可以用于代码处理装置1600与其它计算设备或者终端进行数据通信。
进一步可选的,图16A和16B用一条粗线表示总线1604。总线1604可以将处理器1601与存储器1602和通信接口1603连接。这样,通过总线1604,处理器1601可以访问存储器1602,还可以利用通信接口1603与其它计算设备或者终端进行数据交互。
在本申请中,代码处理装置1600执行存储器1602中的计算机指令,使得代码处理装置1600实现本申请提供的上述代码处理方法,或者使得代码处理装置1600部署上述的代码处理装置。
从逻辑功能划分来看,示例性的,如图16A所示,存储器1602中可以包括上述代码获取模块1401和文件获得模块1402。这里的包括仅仅涉及存储器中所存储的指令被执行时可以分别实现代码获取模块和文件获得模块的功能,而不限定是物理上的结构。
一种可能设计,如图16B所示,存储器1602中可以包括上述代码切分模块1501。这里的包括仅仅涉及存储器中所存储的指令被执行时可以分别实现代码切分模块的功能,而不限定是物理上的结构。
另外,上述的代码处理装置除了可以像上述图16A和16B通过软件实现外,也可以作为硬件模块,或者作为电路单元,通过硬件实现。
本申请提供一种计算机可读存储介质,所述计算机程序产品包括计算机指令,所述计算机指令指示计算设备执行本申请提供的上述代码处理方法。
本申请提供一种芯片,包括至少一个处理器和通信接口,所述通信接口为所述至少一个处理器提供信息输入和/或输出。进一步,所述芯片还可以包含至少一个存储器,所述存储器用于存储计算机指令。所述至少一个处理器用于调用并运行该计算机指令,以执行本申请提供的上述代码处理方法。
本申请提供一种终端,所述终端可以为运输工具或者智能设备,例如车辆、无人机、无人运输车或者机器人等,其上包含上述代码处理装置。
在本申请所提供的几个实施例中,应该理解到,所揭露的装置和方法,可以通过其它的方式实现。例如,以上所描述的装置实施例仅仅是示意性的,例如,所述单元的划分,仅仅为一种逻辑功能划分,实际实现时可以有另外的划分方式,例如多个单元或组件可以结合或者可以集成到另一个系统,或一些特征可以忽略,或不执行。另一点,所显示或讨论的相互之间的耦合或直接耦合或通信连接可以是通过一些接口,装置或单元的间接耦合或通信连接,可以是电性,机械或其它的形式。
所述作为分离部件说明的单元可以是或者也可以不是物理上分开的,作为单元显示的部件可以是或者也可以不是物理单元,即可以位于一个地方,或者也可以分布到多个网络单元上。可以根据实际的需要选择其中的部分或者全部单元来实现本实施例方案的目的。
另外,在本申请各个实施例中的各功能单元可以集成在一个处理单元中,也可以是各个单元单独物理存在,也可以两个或两个以上单元集成在一个单元中。上述集成的单元既可以采用硬件的形式实现,也可以采用硬件加软件功能单元的形式实现。
Claims (14)
1.一种代码处理方法,其特征在于,所述方法包括:
获取待处理代码,所述待处理代码被分成一个或多个段,其中,所述一个或多个段中的每个段只包括一个函数或一个变量;
根据所述一个或多个段的被引用情况,删除没有被引用的段,获得可执行文件,其中所述被引用情况指示一个段被其它段引用的情况。
2.根据权利要求1所述的方法,其特征在于,所述获得可执行文件,包括:
获取段重映射信息,所述段重映射信息包括段的标识和所述段包含的函数或变量的标识的对应关系;
根据所述段映射信息修改链接脚本,所述链接脚本中包含至少一个函数或变量以及该至少一个函数或变量对应的段的标识,修改后的链接脚本中所述至少一个函数或变量对应的段的标识与所述至少一个函数或变量在所述段重映射信息中对应的段的标识相同;
根据修改后的所述链接脚本获得所述可执行文件。
3.一种代码处理方法,其特征在于,所述方法包括:
将源代码切分成一个或多个段,其中,所述一个或多个段中的每个段只包括一个函数或一个变量。
4.根据权利要求3所述的方法,其特征在于,在所述将源代码切分成一个或多个段之后,还包括:
生成段重映射信息,所述段重映射信息包括段的标识和所述段包含的函数或变量的标识的对应关系。
5.根据权利要求3或4所述的方法,其特征在于,所述源代码为用汇编语言编写的代码。
6.一种代码处理装置,其特征在于,包括:
代码获取模块,用于获取待处理代码,所述待处理代码被分成一个或多个段,其中,所述一个或多个段中的每个段只包括一个函数或一个变量;
文件获得模块,用于根据所述一个或多个段的被引用情况,删除没有被引用的段,获得可执行文件,其中所述被引用情况指示一个段被其它段引用的情况。
7.根据权利要求6所述的装置,其特征在于,所述文件获得模块具体用于:
获取段重映射信息,所述段重映射信息包括段的标识和所述段包含的函数或变量的标识的对应关系;
根据所述段映射信息修改链接脚本,所述链接脚本中包含至少一个函数或变量以及该至少一个函数或变量对应的段的标识,修改后的链接脚本中所述至少一个函数或变量对应的段的标识与所述至少一个函数或变量在所述段重映射信息中对应的段的标识相同;
根据修改后的所述链接脚本获得所述可执行文件。
8.一种代码处理装置,其特征在于,包括:
代码切分模块,用于将源代码切分成一个或多个段,其中,所述一个或多个段中的每个段只包括一个函数或一个变量。
9.根据权利要求8所述的装置,其特征在于,所述代码切分模块还用于:
生成段重映射信息,所述段重映射信息包括段的标识和所述段包含的函数或变量的标识的对应关系。
10.根据权利要求8或9所述的装置,其特征在于,所述源代码为用汇编语言编写的代码。
11.一种代码处理装置,其特征在于,包括:
包括存储器和一个或多个处理器;
所述存储器,用于存储计算机指令;
所述一个或多个处理器,用于执行所述存储器存储的计算机指令,使得所述代码处理装置实现权利要求1或2所述的方法。
12.一种代码处理装置,其特征在于,包括:
包括存储器和一个或多个处理器;
所述存储器,用于存储计算机指令;
所述一个或多个处理器,用于执行所述存储器存储的计算机指令,使得所述代码处理装置实现权利要求3至5任一项所述的方法。
13.一种计算机程序产品,其特征在于,所述计算机程序产品包括计算机指令,所述计算机指令指示计算设备执行权利要求1或2所述的方法。
14.一种计算机程序产品,其特征在于,所述计算机程序产品包括计算机指令,所述计算机指令指示计算设备执行权利要求3至5任一项所述的方法。
Priority Applications (1)
Application Number | Priority Date | Filing Date | Title |
---|---|---|---|
CN202010513307.7A CN113835686A (zh) | 2020-06-08 | 2020-06-08 | 代码处理方法和装置 |
Applications Claiming Priority (1)
Application Number | Priority Date | Filing Date | Title |
---|---|---|---|
CN202010513307.7A CN113835686A (zh) | 2020-06-08 | 2020-06-08 | 代码处理方法和装置 |
Publications (1)
Publication Number | Publication Date |
---|---|
CN113835686A true CN113835686A (zh) | 2021-12-24 |
Family
ID=78963588
Family Applications (1)
Application Number | Title | Priority Date | Filing Date |
---|---|---|---|
CN202010513307.7A Pending CN113835686A (zh) | 2020-06-08 | 2020-06-08 | 代码处理方法和装置 |
Country Status (1)
Country | Link |
---|---|
CN (1) | CN113835686A (zh) |
Cited By (1)
Publication number | Priority date | Publication date | Assignee | Title |
---|---|---|---|---|
CN116166322A (zh) * | 2023-04-24 | 2023-05-26 | 麒麟软件有限公司 | 一种移植Linux内核的方法 |
-
2020
- 2020-06-08 CN CN202010513307.7A patent/CN113835686A/zh active Pending
Cited By (2)
Publication number | Priority date | Publication date | Assignee | Title |
---|---|---|---|---|
CN116166322A (zh) * | 2023-04-24 | 2023-05-26 | 麒麟软件有限公司 | 一种移植Linux内核的方法 |
CN116166322B (zh) * | 2023-04-24 | 2023-07-04 | 麒麟软件有限公司 | 一种移植Linux内核的方法 |
Similar Documents
Publication | Publication Date | Title |
---|---|---|
KR102059705B1 (ko) | 적응식 이식가능 라이브러리 | |
US6836883B1 (en) | Method and system for compiling multiple languages | |
CN110059456B (zh) | 代码保护方法、代码保护装置、存储介质与电子设备 | |
CN101002174B (zh) | 在便携式装置中加载具有面向对象的中间语言的软件的方法 | |
US10613844B2 (en) | Using comments of a program to provide optimizations | |
US10409559B2 (en) | Single-source-base compilation for multiple target environments | |
CN114816417B (zh) | 一种交叉编译方法、装置、计算设备及存储介质 | |
CN110688096B (zh) | 包含插件的应用程序的构建方法、装置、介质及电子设备 | |
CN114138281A (zh) | 软件工程的编译方法、装置、设备及介质 | |
CN116934330A (zh) | 一种调用智能合约的方法及执行方法、计算机设备及存储介质 | |
CN113312046A (zh) | 子应用页面处理方法、装置和计算机设备 | |
CN113835686A (zh) | 代码处理方法和装置 | |
CN111078279A (zh) | 字节码文件的处理方法、装置、设备及存储介质 | |
CN112269566B (zh) | 脚本生成处理方法、装置、设备及系统 | |
US20090187897A1 (en) | Compiling method and compiling program | |
CN116228515A (zh) | 硬件加速系统、方法及相关装置 | |
CN114174983B (zh) | 用于高级构造的优化的自动验证的方法和系统 | |
US9720660B2 (en) | Binary interface instrumentation | |
Bispo et al. | Challenges and Opportunities in C/C++ Source-To-Source Compilation | |
CN113296786B (zh) | 数据处理方法、装置、电子设备及存储介质 | |
CN115981652B (zh) | 语言互操作方法、装置、存储介质及程序产品 | |
CN117234466B (zh) | 企业管理软件开发方法、系统、设备及存储介质 | |
CN117539492A (zh) | 代码中冗余语句的删除方法、装置、电子设备及存储介质 | |
CN116931948A (zh) | 一种优化wasm字节码的方法及执行方法、计算机设备及存储介质 | |
CN116931949A (zh) | 一种优化wasm字节码的方法及执行方法、计算机设备及存储介质 |
Legal Events
Date | Code | Title | Description |
---|---|---|---|
PB01 | Publication | ||
PB01 | Publication | ||
SE01 | Entry into force of request for substantive examination | ||
SE01 | Entry into force of request for substantive examination |