LLVM Cpu0 新后端9 objdump readelf

2024-06-09 15:52
文章标签 llvm objdump readelf cpu0 新后

本文主要是介绍LLVM Cpu0 新后端9 objdump readelf,希望对大家解决编程问题提供一定的参考价值,需要的开发者们随着小编来一起学习吧!

 想好好熟悉一下llvm开发一个新后端都要干什么,于是参考了老师的系列文章:

LLVM 后端实践笔记

代码在这里(还没来得及准备,先用网盘暂存一下):

链接: https://pan.baidu.com/s/1V_tZkt9uvxo5bnUufhMQ_Q?pwd=ggu5 提取码: ggu5 

这一章介绍如何生成 ELF 文件,ELF 文件是一种通用的可执行文件、目标文件和共享库与核心转储文件标准,最早是由 System V 应用二进制接口发布,之后成为一种标准,并很快被类 Unix 操作系统接受。几乎所有支持编译的后端平台都需要生成一种可执行文件格式来执行代码,现在主流的三种可执行文件分别是 Linux 系统及裸机系统支持的 ELF 文件、Windows 系统支持的 COFF 文件以及 MacOS 系统支持的 Mach-O 文件格式。我们让 Cpu0 后端生成 ELF 文件格式。

之前章节我们介绍了 Cpu0 后端生成各种指令编码的代码,所以有关于指令编码的行为,是由 td 文件中的描述来确定的,LLVM 的公共部分已经帮我们生成了指令编码的功能。但目前还没有定义生成 ELF 文件的头部、段组成、重定位信息等内容,这一章主要实现这部分内容。

这一章,我们会使用二进制解析工具来检查 ELF 文件,比如 objdump 和 readelf 文件。LLVM 中有类似于 objdump 的工具,默认生成名称为 llvm-objdump,基本使用和 objdump 一致,我们这一章也会试用这个工具。

一、ELF文件的简单介绍

这一节只是简单介绍,有关于详细的学习材料,在网上可以找到很多。ELF 文件格式的支持是 LLVM 默认便已经完成的,不需要我们做更多的工作(少量工作在第 2 章中已经完成)。ELF 文件格式有两种视图,分别是目标文件视图和可执行文件视图。目标文件视图是为链接器服务的,它的划分标准是段(Section),不同的段有 .text 段存放代码内容、.data 段存放数据、.rodata 段存放只读数据等,这些段的索引保存在 ELF 文件末尾的段头部表(Section header table)中。链接器通过访问段头部表来检索到各段。

可执行文件视图是为执行服务的,它的划分标准是节(Segment),不同的节可能是多个段的组合,比如执行时,因为要关心数据的访问权限,.text 段和 .rodata 段会合并为一个只读数据的节。加载器会访问位于 ELF 文件开头文件头部表之后的节头部表(Segment header table),来访问各节。

二、工具的使用

2.1 llvm-objdump和llvm-readelf的工具选择

我一般反汇编用的llvm-objdump,读字段用llvm-readelf较多,主要看大家习惯。虽然readelf写着是读elf文件,但是llvm对于llvm-readelf进行了扩展,也能用来读取coff和macho文件。

选项有多个的情况是有缩写

2.2 llvm-objdump

2.2.1 --mattr=a1, +a2, -a3...

指定架构特殊的属性,与llc的选项类似。

2.2.2 --mcpu=cpu-name

指定一个cpu类型,与llc的选项类似。

2.2.3 --disassemble-options=options/-M <value>

使用目标架构特殊的反汇编器选项

2.2.4 --disassemble-symbols=<value>

反汇编某一个符号,例如:llvm-objdump --disassemble-symbols='_Z3fooSt6vectorIiSaIiEE' test.o

2.2.5 --disassemble/-d

对文件的执行字段进行反汇编,llvm-objdump -d test.o

2.2.6  --disassemble-all/-D

对文件的所有字段进行反汇编,llvm-objdump -D test.o

2.2.7 --dynamic-reloc/-R

打印文件的动态重定位信息,llvm-objdump -R test.so

2.2.8 --dynamic-syms/-T

打印文件的动态符号表

2.2.9 --syms/-t

打印文件的符号表

2.2.10 --file-headers/-f

打印文件头信息

2.2.11 --section-headers

打印各个section的概述信息

2.2.12 --headers/-h

打印section header信息,我看效果貌似跟--section-headers是差不多的

2.2.13 --all-headers/-x

打印可用的头信息,重定位信息和符号表。

2.2.14 --full-contents/-s

打印所有内容

2.2.15 --x86-asm-syntax

--x86-asm-syntax=att/intel,打印AT&T还是Intel风格的反汇编代码。

2.3 llvm-readelf

2.3.1 -program-headers/-l/--segments

打印segments信息

2.3.2 --section-headers/--sections/-S

打印sections headers信息

2.3.3 --section-details/-t

打印sections细节信息(不知道为啥说成细节,我觉得与-S类似)

2.3.4 --file-header/-h

打印文件头

2.3.5 --section-relocations/--sr

打印sections的重定位信息

2.3.6 --relocations/--relocs/-r

打印重定位信息

2.3.7 --symbols/--syms/-s

打印符号表,包括动态符号表

2.3.8 --dynamic-table/--dynamic/-d

打印dynamic section信息

2.3.9 --dyn-symbols/--dyn-syms/--dt

打印动态符号表

2.3.10 --dyn-relocations

打印动态重定位信息。

2.3.11 --headers/-e

相当于--file-header, --program-headers, --section-headers

2.3.12 --all/-a

打印所有信息,相当于--file-header, --program-header, --section-headers, --symbols, --relocations, --dynamic-table, --notes, --verson-info, --unwind, --section-groups and --histogram

三、修改前的效果

我们使用llvm-objdump -d打印我们编出的cpu0架构的目标文件的反汇编试一下:

会提示我们cpu0架构没有反汇编器,这是我们这一章要适配的内容。

四、修改部分

4.1 新增的文件

4.1.1 Disassembler/Cpu0Disassembler.cpp

在这个反汇编文件中,实现了 td 文件中所有反汇编函数引用的函数,即 DecoderMethod 关键字指定的函数,尤其是对应一些特殊操作数的反汇编,比如内存引用的反汇编,因为这种特殊操作数格式是我们自定义的 td 类来定义的,所以也需要指定其反汇编方法。

4.2 修改的文件

4.2.1 Cpu0InstrInfo.td

对一些基本类添加反汇编函数的引用。这里添加了 JumpFR 类的引用。

五、修改后的效果

能正确打印出反汇编的内容。

这篇关于LLVM Cpu0 新后端9 objdump readelf的文章就介绍到这儿,希望我们推荐的文章对编程师们有所帮助!



http://www.chinasem.cn/article/1045622

相关文章

LLVM入门2:如何基于自己的代码生成IR-LLVM IR code generation实例介绍

概述 本节将通过一个简单的例子来介绍如何生成llvm IR,以Kaleidoscope IR中的例子为例,我们基于LLVM接口构建一个简单的编译器,实现简单的语句解析并转化为LLVM IR,生成对应的LLVM IR部分,代码如下,文件名为toy.cpp,先给出代码,后面会详细介绍每一步分代码: #include "llvm/ADT/APFloat.h"#include "llvm/ADT/S

LLVM IR指令VM混淆分析

未混淆编译  编写一个最简单的测试代码,对 test_add函数用于对两个数相加: int __attribute((__annotate__("vm"))) test_add(int a, int b) {int c = a + b;return c;}int main(void) {int c = test_add(1, 2);return c;} 编译成中间代码:  未加

Windows编译Hikari-LLVM15[llvm-18.1.8rel]并集成到Android Studio NDK

Windows编译Hikari-LLVM15[llvm-18.1.8rel]并集成到Android Studio NDK 工具1、w64devkit2、ndk3、cmake 编译1、准备工作2、开始编译 集成1、替换文件2、使用 工具 1、w64devkit w64devkit 解压出来给个环境变量 验证一下 2、ndk 通过android studio安装 nd

VS2022使用指定的LLVM版本

LLVM下载地址:Releases · llvm/llvm-project · GitHub LLVM/Clang toolsets for Visual Studio 2022, 2019, 2017, 2015, 2013, 2012 and 2010. GitHub - zufuliu/llvm-utils: LLVM/Clang toolsets for Visual Studio 2

简述 LLVM 与 Clang 及其关系

随着 Android P 的逐步应用,越来越多的客户要求编译库时用 libc++ 来代替 libstdc++。libc++ 和 libstdc++ 这两个库有关系呢?它们两个都是 C++ 标准库,libc++ 是针对 Clang 编译器特别重写的 C++ 标准库,而 libstdc++ 则是 GCC 的对应 C++ 标准库了。从 Android 市场来说,Android NDK 已在具体应用中放弃

linux下objdump命令用法介绍

objdump是用查看目标文件或者可执行的目标文件的构成的GCC工具 linux下objdump命令常见用法举例: objdump -x obj:以某种分类信息的形式把目标文件的数据组成输出;<可查到该文件的的所有动态库> objdump -t obj:输出目标文件的符号表() objdump -h obj:输出目标文件的所有段概括() objdump -j ./text/.d

llvm windows编译成功

一、所需工具 Visual Studio 推荐版本:Visual Studio 2022。其他版本亦可支持。 CMake 下载地址 Ninja 下载地址 LLVM 版本参考:llvm-project-llvmorg-18.1.8下载地址 二、配置与编译步骤 以管理员身份打开命令行终端,输入以下命令来设置执行策略: Set-ExecutionPolicy Unrestricted

LLVM——安装多版本LLVM和Clang并切换使用(Ubuntu)

1、描述 本机(Ubuntu22)已经安装了LLVM-14,但是需要使用LLVM-12。安装LLVM-12和Clang-12并切换使用。 2、过程 安装LLVM-12和Clang-12。 sudo apt-get install llvm-12sudo apt-get install clang-12 【注】运行 sudo apt-get install llvm-12 命令时,默认情况

【LLVM】‘ffast-math’ and ‘ffp-contract’

最近看到一个issue,修改的核心代码部分并不多,可以参考此处的介绍以及此处的issue。 看起来关键就是判断-ffp-contract会将contract的值设为最后一个此选项的值,否则的话,如果只指定了-ffast-math但是没有通过-ffp-contract设置值,就会将FPContract设置成on。 用伪代码表示: if(option == -ffp-contract) {FPCon

LLVM 中 的 pass 及其管理机制

概述 LLVM 编译器框架的核心概念是任务调用和执行 编译器开发者将IR分解为不同的处理对象,并将其处理过程实现为单独的pass类型。在编译器初始化,pass被实例化,并被添加到pass管理中 pass 管理器(pass manager) 以流水线的方式将各个独立的pass 衔接起来,然后以预定义顺序遍历每个pass,根据pass实例返回值启动、停止或重复运行不同的pass 因此,LLVM