对于带有嵌入位码的二进制文件(即使用 编译-fembed-bitcode)。我怎样才能提取该部分,以便我可以像任何其他位码文件一样使用该位码文件,例如运行opt或llvm-dis
作为测试用例,我有这个 hello-world 程序:
// hello.cpp
#include<iostream>
int main() {
std::cout << "hello world";
return 0;
}
Run Code Online (Sandbox Code Playgroud)
编译为:clang++ -O2 test.cpp -o test.o -fembed-bitcode -c
显示其中objdump有一个__bitcode部分:
objdump -h test.o
test.o: file format Mach-O 64-bit x86-64
Sections:
Idx Name Size Address Type
0 __text 000002eb 0000000000000000 TEXT
1 __gcc_except_tab 00000068 00000000000002ec DATA
2 __cstring 0000000c 0000000000000354 DATA
3 __bitcode 00002bc0 0000000000000360 DATA
4 __cmdline 00000046 0000000000002f20 DATA
5 __compact_unwind 00000060 0000000000002f68 …Run Code Online (Sandbox Code Playgroud) 我正在出于自己的教育目的构建 Risk-V CPU 模拟器。我有小型 POC 工作,想要构建示例程序并在模拟器上测试它们。
我正在尝试用 Rust 构建示例程序,似乎取得了一些不错的进展,但是当我必须将编译后的程序加载到模拟器的内存中并将 CPU 执行转移到该程序时,我陷入了困境。
测试程序:
#![no_std]
#![no_main]
use core::panic::PanicInfo;
#[no_mangle]
pub extern "C" fn _start() -> ! {
loop {
for i in 0..1000 {
unsafe {
let r = i as *mut u32;
// This can panic because (500 - i) can be 0
*r = 20000 % (500 - i);
}
}
}
}
#[panic_handler]
fn panic(_info: &PanicInfo) -> ! {
loop {}
}
Run Code Online (Sandbox Code Playgroud)
建造:
$ cargo build --target riscv32i-unknown-none-elf --release …Run Code Online (Sandbox Code Playgroud) 我有Linux内核并尝试使用objcopy工具生成ELF Header,下面是第一步
objcopy -I binary -B i386 -O elf32-i386 --rename-section .data=.text linux_kernel.bin main.o
Run Code Online (Sandbox Code Playgroud)
在此之后我想使用readelf -s main.o读取符号表,但是输出下面的奇怪符号
Symbol table '.symtab' contains 5 entries:
Num: Value Size Type Bind Vis Ndx Name
0: 00000000 0 NOTYPE LOCAL DEFAULT UND
1: 00000000 0 SECTION LOCAL DEFAULT 1
2: 00000000 0 NOTYPE GLOBAL DEFAULT 1 _binary_linux_kernel_bin_
3: 004df650 0 NOTYPE GLOBAL DEFAULT 1 _binary_linux_kernel_bin_
4: 004df650 0 NOTYPE GLOBAL DEFAULT ABS _binary_linux_kernel_bin_
Run Code Online (Sandbox Code Playgroud)
现在应该可以看到像这样的符号
_binary_linux_kernel_bin_start
_binary_linux_kernel_bin__end
_binary_linux_kernel_bin_size
Run Code Online (Sandbox Code Playgroud)
任何人都可以让我知道我在哪里做错了吗?还是期待一个?
为什么我想看到正确的符号,因为必须做类似下面的事情
--entry_point=_binary_linux_kernel_bin_start
Run Code Online (Sandbox Code Playgroud) 我正在尝试编译和链接一个程序(我们称之为 myprog),该程序与共享库(在本例中为libcryto 和 libssl,但实际库不相关)链接。我正在Centos 5.5上构建它,但希望在其他类似RHEL的发行版(例如 CloudLinux)上运行相同的二进制文件。两者都具有相同库的版本SO_NAME(即DT_NEEDED版本对应)。
我的问题是这个。当我在 Centos 上编译时,我看到:
centos$ objdump -T myprog | fgrep SSL_new
0000000000000000 DF *UND* 0000000000000000 libssl.so.10 SSL_new
Run Code Online (Sandbox Code Playgroud)
这工作正常,因为:
centos$ objdump -T /usr/lib64/libssl.so.10 | fgrep SSL_new
00000000000447d0 g DF .text 0000000000000390 libssl.so.10 SSL_new
Run Code Online (Sandbox Code Playgroud)
但是,在 CloudLinux 上:
cloudlinux$ objdump -T /usr/lib64/libssl.so.10 | fgrep SSL_new
00000033a623a120 g DF .text 0000000000000390 Base SSL_new
Run Code Online (Sandbox Code Playgroud)
请注意 SSL 符号的版本已从 更改libssl.so.10为Base。
这意味着当我运行二进制文件时,我得到:
cloudlinux$ ./myprog
./myprog: /usr/lib64/libcrypto.so.10: no version information …Run Code Online (Sandbox Code Playgroud) 我需要更改共享库 (.so) 文件中的某些符号,如下例所示:我需要将abc.so 文件中的符号重命名为 symbol xyz。我有一个工具可以在头文件中替换它,我面临的唯一挑战是更改我的 .so 共享库。对于共享库,是否有任何工具或命令可以帮助我反汇编 .so 文件、更新符号并再次重新组装为 .so 文件?对于共享库,我们需要一种重建符号表的机制。如果有任何工具可以完成我的任务,需要帮助吗?
仅供参考:更改源是最好的方法,但对于短期的解决方案来说,它可以帮助在符号级别替换代码字。