使用GNU ld 2.21运行Debian/Linux x86_64.
很简单,如果我链接
ld -o main main.o /usr/lib/crti.o /usr/lib/crt1.o /usr/lib/crtn.o -lc -lm
Run Code Online (Sandbox Code Playgroud)
它有效,但是当我链接时
ld -r -o main1.o main.o /usr/lib/crti.o /usr/lib/crt1.o /usr/lib/crtn.o -lc -lm
Run Code Online (Sandbox Code Playgroud)
它抱怨
ld: cannot find -lc
ld: cannot find -lm
Run Code Online (Sandbox Code Playgroud)
我实际上并没有尝试以这种方式编译代码,而是我试图弄清楚为什么别人的测试看看库是否存在无效.(因此我真的不明白发生了什么ld
......通常我只是用GCC来链接)
为什么要ld
以可重定位的方式链接使它突然无法找到库?如果我只是想测试它-lm
存在,我还应该做些什么
ld -r -lm
Run Code Online (Sandbox Code Playgroud)
这样它会找到图书馆吗?
如果你想查看我正在处理的源代码,可以在这里下载:https://github.com/jeremysalwen/ESPS (注意,第一次提交是原始源代码,后续的是更改我亲自做过.)
我正在调查共享库的重定位,并遇到了一些奇怪的事情。考虑这段代码:
int myglob;
int ml_util_func(int p)
{
return p + 2;
}
int ml_func2(int a, int b)
{
int c = ml_util_func(a);
return c + b + myglob;
}
Run Code Online (Sandbox Code Playgroud)
我将其编译为非 PIC共享库,使用gcc -shared
. 我在 x86 上运行的 32 位 Ubuntu 上执行此操作。
结果.so
有一个用于调用ml_util_func
in的重定位条目ml_func2
。objdump -dR -Mintel
这是on的输出ml_func2
:
0000050d <ml_func2>:
50d: 55 push ebp
50e: 89 e5 mov ebp,esp
510: 83 ec 14 sub esp,0x14
513: 8b 45 08 mov eax,DWORD PTR …
Run Code Online (Sandbox Code Playgroud) 重新将主程序重新置于其自己的图像库之后.
我如何保证加载的DLL将加载0x400000
dllImageBase = LoadLibrary("test.dll");
printf("imagebase = 0x%x", dllImageBase);
Run Code Online (Sandbox Code Playgroud)
我总是得到0x460000而不是0x400000
我需要我的dll第一条指令从0x401000开始,它曾经在重新定位之前从0x600000开始
链接器到rebase的命令是
#pragma comment( linker, "/BASE:8000000")
Run Code Online (Sandbox Code Playgroud)
所以0x400000现在实际上是免费的,但它默认不使用它.所以我可以控制它,它应该重新定位的任何方式.有些WIN32API可能吗?
在创建最终图像之前,链接器在解析目标文件中的重定位时会采取哪些步骤?更具体地说,链接器如何处理已经存储在重定位站点的值?它总是将它添加到最终的VA/RVA中,还是有时会被忽略(例如某些重定位类型)?
我在MS PE/COFF Specfication中找不到清晰的解释,经过谷歌搜索和实验一段时间后,我所能发现的是:
您能否指出我的任何(相关)文档,它解释了链接器如何处理重定位?
我有MPICH 3.0.4我的机器(Ubuntu的12.04)上安装.我正在尝试安装一个名为Qthreads的库,我已经使用过并成功安装过(除了安装了MPICH2软件包).配置工作正常:
./configure --prefix=/usr/local/qthreads --enable-multinode --with-multinode-runtime=mpi --with-portals4=/usr/local/portals4 --with-hwloc=/usr/local/hwloc
:
...
...
...
System Characteristics:
Target Style: unix
Multi-node: yes, mpi
Topology API: hwloc
Qtimer type: clock_gettime
Aligned_t size: 8 (aligned on 8 byte boundaries)
Default Stack size: 4kB
Safety/Debugging:
Sanity assert()s: no
Check alignment: no
Profiling: none
Debugging Output: no
Guard Pages: no
Speed:
Scheduler: sherwood (multiworker shepherds)
Sinc Style: donecount
Barrier Style: feb
Dictionary Style: simple
Lazy Thread IDs: yes
Pools/caches: memory, spawns
RCRTool: no …
Run Code Online (Sandbox Code Playgroud) 我正在尝试理解C工具链的链接阶段.我编写了一个示例程序并剖析了生成的目标文件.虽然这有助于我更好地理解所涉及的过程,但有些事情对我来说仍然不清楚.
这是:
这是正确的,那些重定位表条目......
RELOCATION RECORDS FOR [.text]:
OFFSET TYPE VALUE
0000002b dir32 .data
00000035 dir32 .data
0000003f dir32 .data
Run Code Online (Sandbox Code Playgroud)
...基本上是告诉链接器,使存储在地址偏移2b
,35
并且3f
从.text
不是绝对不会忽略,但相对不会忽略(=偏移)有关.data
?据我所知,这使链接器能够
我不明白为什么未初始化的变量与初始化变量的处理方式不同.为什么寄存器地址存储在操作码中,
他们的重定位表条目的值字段对我来说完全不清楚.我原本期望在.bss
那里引用该部分.
RELOCATION RECORDS FOR [.text]:
OFFSET TYPE VALUE
0000000d dir32 _var1_zeroed-0x00000004
00000017 dir32 _var2_zeroed-0x00000004
00000021 dir32 _var3_zeroed-0x00000004
Run Code Online (Sandbox Code Playgroud) 背景:如果可执行文件具有在共享对象中定义的外部数据引用,则编译器将使用复制重定位并将副本放置在其 .bss 部分中。此站点详细介绍了复制重定位: http://www.shrubbery.net/solaris9ab/SUNWdev/LLM/p22.html#CHAPTER4-84604
然而,我的问题是:
是否可以像共享对象中的外部数据引用一样,通过GOT来实现?可执行文件可以通过其GOT条目间接访问该外部代码,并且该GOT条目可以在运行时填充该符号的真实地址。我不知道为什么GCC不这样实现。复制迁移有什么好处?
我的项目中有以下情况:
一个具有自己的依赖关系的大模块(称为转换器)正被集成到主应用程序中(由不同的人分别开发并具有自己的,部分重叠的依赖关系);
最初这个转换器模块可以从命令行调用为可执行jar,因此它有自己的入口点(定义了main()方法的runnable类); 这个可执行的jar总是通过maven shade插件创建为超级jar;
现在这个转换器模块必须可以从主应用程序中另外调用(为此,我现在在形成命令行参数后直接调用入口点类的main()).主应用程序也被创建为超级jar,并计划继续以这种方式创建.
在这种情况下,我将使用shade插件实现依赖关系的正确分离,为此,我已将以下重定位规范添加到转换器模块的pom.xml中:
<relocations>
<relocation>
<pattern>com</pattern>
<shadedPattern>quase.com</shadedPattern>
</relocation>
<!-- ... other top-level patterns for converter dependencies -->
<relocation>
<pattern>org</pattern>
<shadedPattern>quase.org</shadedPattern>
<excludes>
<exclude>org.aau.**</exclude> <!-- my own code for converter is not shaded -->
</excludes>
</relocation>
</relocations>
Run Code Online (Sandbox Code Playgroud)
因此,转换器模块的所有依赖关系都被加上阴影(对它们进行预先设定),同时组合到主应用程序的超级jar中.
此配置的问题是应用程序和转换器都使用日志记录(slf4j和log4j),并且从应用程序代码调用转换器方法并开始使用日志记录后,会发生以下错误:
log4j:ERROR A "org.apache.log4j.FileAppender" object is not assignable to a "quase.org.apache.log4j.Appender" variable.
log4j:ERROR The class "quase.org.apache.log4j.Appender" was loaded by
log4j:ERROR [sun.misc.Launcher$AppClassLoader@55f96302] whereas object of type
log4j:ERROR "org.apache.log4j.FileAppender" was loaded by [sun.misc.Launcher$AppClassLoader@55f96302].
log4j:ERROR Could not instantiate appender named "file1".
log4j:ERROR A …
Run Code Online (Sandbox Code Playgroud) 我刚刚开始进行嵌入式 arm 开发,有一段代码真的让我很烦恼:
/* Initialize the relocate segment */
pSrc = &_etext;
pDest = &_srelocate;
if (pSrc != pDest)
{
while (pDest < &_erelocate)
{
*pDest++ = *pSrc++;
}
}
Run Code Online (Sandbox Code Playgroud)
其中_etext
和_srelocate
是链接描述文件中定义的符号:
. = ALIGN(4);
_etext = .;
.relocate : AT (_etext)
{
. = ALIGN(4);
_srelocate = .;
*(.ramfunc .ramfunc.*);
*(.data .data.*);
. = ALIGN(4);
_erelocate = .;
} > ram
Run Code Online (Sandbox Code Playgroud)
哪里ram
是原点为 的内存段0x20000000
。我看到的问题是,这_etext
是一个标记.text
段结束边界的符号,它是不同内存段的一部分rom
。这意味着除非上述内存段 100% 已满,_etext …
我试图了解小代码模型中使用的 RIP 相对偏移量。也许互联网上有关此主题的唯一可用资源是: https: //eli.thegreenplace.net/2012/01/03/understanding-the-x64-code-models 但在这篇文章中也有一些事情不清楚。我使用这个简单的程序来了解一些事情:
// sample.cc
int arr[10] = {0};
int arr_big[100000] = {0};
int arr2[500] = {0};
int main() {
int t = 0;
t += arr[7];
t +=arr_big[6];
t += arr2[10];
return 0;
}
Run Code Online (Sandbox Code Playgroud)
汇编:g++ -c sample.cc -o sample.o
.text 部分的目标代码:( objdump -dS sample.o
)
Disassembly of section .text:
0000000000000000 <main>:
0: 55 push %rbp
1: 48 89 e5 mov %rsp,%rbp
4: c7 45 fc 00 00 00 00 movl $0x0,-0x4(%rbp)
b: 8b 05 00 …
Run Code Online (Sandbox Code Playgroud)