关于llvm:C-打印生成的-LLVM-IR-以及-写入文件

如果你的指标是运行 LLVM IR, 则不倡议写入文件, 因为 LLVM 提供了 JIT 的形式间接从 C++ 运行. 后续会有相干文章链接放在此处.首先, 咱们必须有一个 LLVM Module 作为根底, 也就是生成 LLVM IR 的时候应用的 Module, 此处应用 theModule 作为例子. 查找 llvm/IR/Module.h 文件, 理解到 print 函数承受如下参数: 应用如下参数, 能够将后果输入到命令行, 即 stdout 或者 stderr. /* llvm ir -> stdout */theModule->print(llvm::outs(), nullptr);/* llvm ir -> stderr */// llvm_module -> print(llvm::errs(), nullptr);应用如下代码, 能够将后果输入到文件 output.ll 中: std::error_code EC;llvm::raw_fd_ostream output_stream( "output.ll", /* file name */ EC, llvm::sys::fs::OpenFlags::OF_None);if (EC) { std::cerr << "Can't open file output.ll; " << EC.message() << std::endl;}/* write to current_work_directory/output.ll */theModule->print(output_stream, nullptr);输入的文件关上后为人类可读代码, 能够应用 lli 工具执行, 在此咱们应用 C++ 的 system 函数: ...

February 26, 2024 · 1 min · jiezi

关于llvm:llvm-IR语法-全局变量

全局变量@.str.9 = private unnamed_addr constant [12 x i8] c"jinjingTest\00", section "__TEXT,__cstring,cstring_literals", align 1 @示意全局变量 与之绝对应的%示意局部变量,以%前缀 private 示意公有的 unnamed_addr 示意地址不重要,只有内容.被标记成这样的常量如果领有雷同的初始化器,能够合并. 比如说下面的 "jinjingTest"能够和其余的内容为"jinjingTest"的常量合并.local_unnamed_addr示意地址在模块中被认为是不重要的 constant 示意常量 [12 x i8] 示意12个1字节(i8为8位)的数组,也可示意字符串,这里包含分隔符\00 c"jinjingTest\00" 为llvm里的初始化器,示意c字符串,\00为结尾符 section 示意存储在Mach-o中的section中央 align 1 示意内存对齐为1,就是其中有余1的依照1对齐 语法如下: @<GlobalVarName> = [Linkage] [PreemptionSpecifier] [Visibility] [DLLStorageClass] [ThreadLocal] [(unnamed_addr|local_unnamed_addr)] [AddrSpace] [ExternallyInitialized] <global | constant> <Type>[<InitializerConstant>] [, section "name"] [, comdat [($name)]] [, align <Alignment>] (, !name !N)*Linkage 链接类型PreemptionSpecifier 运行抢占阐明Visibility 可见性规定DLLStorageClass DLL存储类别ThreadLocal 线程存储模型[(unnamed_addr|local_unnamed_addr)] 地址不重要或模块中地址不重要[AddrSpace] 地址空间?[ExternallyInitialized] 内部曾经初始化? <global | constant> 全局或常量Type 类型InitializerConstant 初始化器,即初始化值,section "name" 寄存的section段,后面有","和后面宰割,align <Alignment> 对齐类型, 后面有","和后面宰割 ...

June 17, 2022 · 1 min · jiezi

关于llvm:llvm-自动加载插件不用opt-load-libtestdylib-mypasses

https://llvm.liuxfe.com/post/...

April 11, 2022 · 1 min · jiezi

关于llvm:基于legacy-pass-manager的pass编写

1.在github页面下载最新的llvm工程,当初最新的版本应该对应着是llvm13 2.在llvm-project/llvm/lib/Transforms文件夹新建自定义的pass文件夹 cd llvm-project/llvm/lib/Transformsmkdir MyPass在MyPass文件夹下新建一个CMakeLists.txt 写入 add_llvm_library( MYPass MODULE MYPass.cpp DEPENDS intrinsics_gen PLUGIN_TOOL opt )3.在llvm-project/llvm/lib/Transforms/CmakeLists.txt中增加文件夹目录 add_subdirectory(MYPass) 4.编写Pass #include "llvm/ADT/Statistic.h"#include "llvm/IR/Function.h"#include "llvm/Pass.h"#include "llvm/Support/raw_ostream.h"#include "llvm/IR/LegacyPassManager.h"#include "llvm/Transforms/IPO/PassManagerBuilder.h"using namespace llvm;#define DEBUG_TYPE "hello"STATISTIC(HelloCounter, "Counts number of functions greeted");namespace { // Hello - The first implementation, without getAnalysisUsage.struct Hello : public FunctionPass { static char ID; // Pass identification, replacement for typeid Hello() : FunctionPass(ID) {} bool runOnFunction(Function &F) override { ++HelloCounter; errs() << "Hello: "; errs().write_escaped(F.getName()) << '\n'; return false; } void getAnalysisUsage(AnalysisUsage &AU) const override { AU.setPreservesAll(); } void releaseMemory() override { errs() << "releaseMemory"; }};}char Hello::ID = 0;static RegisterPass<Hello> X("hello", "Hello World Pass",false,false);static RegisterStandardPasses Y2(PassManagerBuilder::EP_EarlyAsPossible,[](const PassManagerBuilder &Builder,legacy::PassManagerBase &PM) { PM.add(new Hello()); });5.构建和编译pass ...

March 25, 2022 · 1 min · jiezi

Tea-一门新的编程语言

# 安装sudo apt install tealangsudo brew install tealangsudo yum install tealang# 运行tea run app.teatea install dependency# 引入依赖import http os# 赋值与数据类型a1 = 1 # 整数a2 = "a" # 字符串a3 = true # 布尔a4 = null # 空a5 = 1.1 # 浮点a6 = [a1 a2 a3] # 列表a7 = {name: "Elliot" age:26} # 字典a8 = (a1 a2 a3) # 元组a9 = {a1 a2 a3} # 集合# 基本运算+,-,*,/,%,^,&,|,!,==,>=,<=,>,<,~,?# 函数hello name: "Hello {name}"default : "Hello World"main arg1 arg2...: print arg1 print arg2# 类Myclass object: attibute = "class attibute" __init name: .name = name ._private = 1 __str:.name show:.name# 判断i = 0if i == 0 hello ielif 20 > i > 10 defaultelse exit# 循环for i ~ 0:10 print ifor k v ~ {"name": "Elliot"} print k print v# 推导式print i for i ~ ["a" "b" "c" "d"]print i for i ~ 0:100:10:2 = [0 2 4 6 8]# 数组切片[0 1 2 3 4 5][0:2] = [0 1][0 1 2 3 4 5][-2:-0] = [4 5]# 异步函数async callme: "Async Hello World"await [callme callme callme callme]# 解构赋值theBait = 1000theSwitch = 0[theBait theSwitch] = [theSwitch theBait]futurists = { sculptor:"Umberto Boccioni" painter:"Vladimir Burliuk" poet: { name:"Tom" address:["Via Roma 42R" "Bellagio, Italy 22021"] }}{poet: {name, address: [street, city]}} = futuriststag = "<impossible>"[open contents... close] = tag.split# 异常捕获try somethingcatch ValueError print "Value is wrong."catch CustomError print "CustomError"else print errorfinally anything

August 8, 2019 · 2 min · jiezi

OCLint-实现-Code-Review-给你的代码提提质量

工程代码质量,一个永恒的话题。好的质量的好处不言而喻,团队成员间除了保持统一的风格和较高的自我约束力之外,还需要一些工具来统计分析代码质量问题。 本文就是针对 OC 项目,提出的一个思路和实践步骤的记录,最后形成了一个可以直接用的脚本。如果觉得文章篇幅过长,则直接可以下载脚本 OCLint is a static code analysis tool for improving quality and reducing defects by inspecting C, C++ and Objective-C code and looking for potential problems ...从官方的解释来看,它通过检查 C、C++、Objective-C 代码来寻找潜在问题,来提高代码质量并减少缺陷的静态代码分析工具 OCLint 的下载和安装有3种方式安装,分别为 Homebrew、源代码编译安装、下载安装包安装。区别: 如果需要自定义 Lint 规则,则需要下载源码编译安装如果仅仅是使用自带的规则来 Lint,那么以上3种安装方式都可以1. Homebrew 安装在安装前,确保安装了 homebrew。步骤简单快捷 brew tap oclint/formulae brew install oclint2. 安装包安装进入 OCLint 在 Github 中的地址,选择 Release。选择最新版本的安装包(目前最新版本为:oclint-0.13.1-x86_64-darwin-17.4.0.tar.gz)解压下载文件。将文件存放到一个合适的位置。(比如我选择将这些需要的源代码存放到 Document 目录下)在终端编辑当前环境的配置文件,我使用的是 zsh,所以编辑 .zshrc 文件。(如果使用系统的终端则编辑 .bash_profile 文件) OCLint_PATH=/Users/liubinpeng/Desktop/oclint/build/oclint-releaseexport PATH=$OCLint_PATH/bin:$PATH将配置文件 source 一下。 source .zshrc // 如果你使用系统的终端则执行 soucer .bash_profile验证是否安装成功。在终端输入 oclint --version3. 源码编译安装homebrew 安装 CMake 和 Ninja 这2个编译工具 ...

May 26, 2019 · 6 min · jiezi

Mac上的gdb之:从入门到放弃

副标题:Mac上的gdb无法正常调试的问题Mac上用brew install gdb安装gdb后,无法正常的运行run命令,报错如下:(gdb) break mainBreakpoint 1 at 0x100000f66: file a.c, line 4.(gdb) runStarting program: /Users/solomonxie/Workspace/tests/clang/aUnable to find Mach task port for process-id 63414: (os/kern) failure (0x5). (please check gdb is codesigned - see taskgated(8))这个不是c程序的问题,也不是gdb的问题,而是Mac的问题。参考:gdb doesn’t work on macos High Sierra 10.13.3为什么Mac不能调试?“因为 Darwin 内核在你没有特殊权限的情况下,不允许调试其它进程。调试某个进程,意味着你对这个进程有完全的控制权限,所以为了防止被恶意利用,它是默认禁止的。允许 gdb 控制其它进程最好的方法就是用系统信任的证书对它进行签名。“参考:gdb fails with “Unable to find Mach task port for process-id” error参考:How to install and codesign GDB on OS X El Capitan具体步骤如下:开启root权限用Spotlight搜索Directory Utility程序,打开后,点击左下角解锁,然后打开菜单->Edit->Enable root user->创建密码。修改/System/Library/LaunchDaemon/com.apple.atrun.plist文件将第22行的-s改为-sp然后保存退出。一般来讲管理员是没有权限修改的,所以需要重启进入“安全模式”用root权限解开系统文件的保护,再重启,修改文件,再重启进入安全模式,再开启系统文件保护,再重启回到正常系统。步骤为:重启,黑屏时按住Ctrl-r不松手一直到苹果标志出现。进入安全模式后,打开菜单Utilities-Terminal终端,输入csrutils disable解锁系统文件保护。然后重启,回到正常系统中,sudo vim /System/Library/LaunchDaemon/com.apple.atrun.plist将文件中22行-s改为-sp,保存退出。重启再次进入安全模式,命令行输入csrutils enable锁定系统文件保护。再重启,回到正常系统,进行下一步。删除所有现有的gdb版本:brew uninstall –force gdb打开系统的Applications -> Utilities -> Keychain Access删除所有gdb相关的证书。重新安装gdb:brew install gdb创建证书打开系统keychain管理器:Keychain Access, go to menu Keychain Access-> Certificate Assistant -> Create a Certificate。创建新的证书,所填内容如下:Name : gdb-certIdentity Type: Self Signed RootCertificate Type : Code Signing[X] Let me override defaultsSerial Number : 1Validity Period (days): 3650Key Size : 2048Algorithm : RSA[X] Include Key Usage Extension[X] This extension is criticalCapabilities:[X] Signature[X] Include Extended Key Usage Extension[X] This extension is criticalCapabilities:[X] Code Signing[X] Include Subject Alternate Name ExtensionKeychain: System为证书添加信任在Keychain管理器里,双击刚刚创建好的证书,在Trust中全部选择为Always Trust:重启taskgated并codesign将程序与证书关联再打开命令行输入:sudo killall taskgatedcodesign -fs “gdb-cert” which gdblaunchctl load /System/Library/LaunchDaemons/com.apple.taskgated.plist设置set startup-with-shell off进入gdb调试程序,然后输入命令:(gdb) set startup-with-shell off然后正式开始调试。如果调试没有问题,则将set startup-with-shell off这句话写入~/.gdbinit文件中,长久生效。如果经历了这一切都没用,那么试试自己编译第三方gdb因为看到有人是由于更新了gdb或更新了os系统后才遇到问题,所以想是不是gdb版本与当前os版本不合的问题。所以决定自己编译别的版本gdb。官方各个版本的下载地址:https://ftp.gnu.org/gnu/gdb/(经过测试,我的在MacOS 10.12 Sierra上编译各个新老版本gdb都编译不成功)开始下载编译:cd /tmpwget https://ftp.gnu.org/gnu/gdb/gdb-7.12.1.tar.gzcd gdb-*/./configure –prefix=/opt/gdb-7.12 && echo [ OK ]make && echo [ OK ]sudo make install && echo [ OK ]如果还是没用,那么需要针对自己的OS版本做调查了我当前的系统是MacOS 10.12 Sierra。相关的说法是:“None GDB 7.11 or 7.12.1 will not work on Sierra 10.12.4 In short it’s because of Apple security upgrade. We need to wait for re-enabling when some new version will shows up.“顺着这条思路搜索,找到一个有人已经编译好的gdb二进制单文件。然后再用codesign给它签名,竟然就可以用了!在这里下载gdb_7.12.1_ sierra .zip或在百度网盘下载。解压后,备份并替换本机的gdb,放到/usr/local/bin/中。然后pkill taskgated并codesign -s gdb-cert /usr/local/bin/gdb进行签名。但是直接gdb还不行,需要用sudo gdb ..才能正常用。注意:重新安装gdb后。第三方软件如cgdb,需要重新安装才能使用,否则完全无法用。最后的最后Mac上LLDB才是王道。Xcode默认调试器是LLDB,说明了苹果不鸟GNU。也有人说,GDB是过去,LLDB是将来。虽然不一定正确,但也证明了LLDB也很强大。再有一点最重要的理由:你的项目生产环境真的是在Mac上吗?既然生产环境不在Mac,为什么要用Mac编译?这个逻辑一想通,就全通了—— 一般生产环境是在Linux服务器上的,所以你大可以共享项目文件夹给服务器,然后SSH进服务器进行编译调试。如果只是学习语言用的小文件,那么更没必要用到强大的GDB功能,在Mac本地用LLDB即可。所以,唯一的缺点就是用不了各类GDB的衍生品、GUI一类,排除这点,还是安心用LLDB吧,不要在Mac上折腾GDB了。。。 ...

April 16, 2019 · 2 min · jiezi