以下问题是相关的,但不回答我的问题:
我之前提出了一个非常类似的问题,但是由于我开始的上一个问题在评论部分有些混乱而没有得到完全回答(但我将其标记为已回答,因为这是一项很好的努力并至少部分回答了它)我会问一个新问题.问题是具体如何将libc链接为静态,同时动态链接其他库(例如libm).有人提出在第一个问题中无法做到,是真的吗?如果是这样,知道为什么不是很有趣.
甚至可以这样做吗?有人发表了意见(这是出于某种原因删除,也许这是不正确的?),这是可能的,但那么一定还存在libc中的动态链接的版本,因为它会通过动态库需要(如动态的libm会需要动态libc(?)).
这对我来说很好,但对我来说如何告诉GCC这样做并不明显,即在libc中链接为静态和动态.我该怎么做(我做了几次尝试,有些会在后面的问题中展示)?或者还有其他方法可以做我想要的吗?
我们首先看到,通过简单地运行gcc test.c -lm,一切都是动态链接的,如下所示:
$ gcc test.c -lm
$ ldd a.out
linux-vdso.so.1 (0x00007fffb37d1000)
libm.so.6 => /lib64/libm.so.6 (0x00007f3b0eeb6000)
libc.so.6 => /lib64/libc.so.6 (0x00007f3b0eb10000)
/lib64/ld-linux-x86-64.so.2 (0x00007f3b0f1b0000)
Run Code Online (Sandbox Code Playgroud)
要仅将libm链接为静态,同时允许libc保持动态,我们可以这样做(正如Z boson在前面提到的一个问题中指出的那样):
$ gcc test.c /usr/lib/gcc/x86_64-pc-linux-gnu/4.7.3/../../../../lib64/libm.a
$ ldd a.out
linux-vdso.so.1 (0x00007fff747ff000)
libc.so.6 => /lib64/libc.so.6 (0x00007f09aaa0c000)
/lib64/ld-linux-x86-64.so.2 (0x00007f09aadb2000)
Run Code Online (Sandbox Code Playgroud)
但是,尝试使用相同的过程来链接libc static和libm dynamic,似乎不起作用:
$ gcc test.c /usr/lib/gcc/x86_64-pc-linux-gnu/4.7.3/../../../../lib64/libc.a -lm
/usr/lib/gcc/x86_64-pc-linux-gnu/4.7.3/../../../../x86_64-pc-linux-gnu/bin/ld: dynamic STT_GNU_IFUNC symbol `strcmp' with pointer equality in `/usr/lib/gcc/x86_64-pc-linux-gnu/4.7.3/../../../../lib64/libc.a(strcmp.o)' can not be used when making an executable; recompile with -fPIE and relink …Run Code Online (Sandbox Code Playgroud) 英特尔MPX,在以下文档中描述了新手:https://software.intel.com/sites/default/files/managed/68/8b/319433-019.pdf
我不确定我理解BNDLDX和BNDSTX是如何工作的.以BNDSTX为例.
从文档(第855页):
"BNDSTX用于通过使用两级结构的地址转换将与缓冲区关联的边界和指向该缓冲区的指针的"指针值"存储到绑定表条目中,请参见第9.3.8节.例如,软件有一个存储在BND0中的边界的缓冲区,指向缓冲区的指针在ESI中,以下序列将"指针值"(缓冲区)和边界存储到已配置的绑定表条目中,使用与相关的线性地址的地址转换由基址寄存器和索引寄存器组成的SIB寻址形式的基础:"
MOV ECX, Dword ptr [ESI] ; store the pointer value in the index register ECX
MOV EAX, ESI ; store the pointer in the base register EAX
BNDSTX Dword ptr [EAX+ECX], BND0 ; perform address translation from the linear address of the base EAX and store bounds and pointer value ECX onto a bound table entry.
Run Code Online (Sandbox Code Playgroud)
该示例说明ESI包含一些指针,如果是这样,那么第一条指令mov ecx,dword ptr [esi]通过间接寻址执行一个简单的mov并获取任何esi 指向 ecx 的dword ,这就是我所假设的用"指针值"表示,或者它们是否代表其他东西?这是什么目的,这与BNDSTX执行的地址转换有何关系?
第二条指令似乎足够直观,它只是想将这个指针存储到缓冲区并复制它.然而,为什么这是严格需要也有点奇怪.BND0不包含缓冲区的开头吗?它不是简单地复制下限指针吗?而且,这个"指针值"的用途到底是什么目的还不清楚.
我正在尝试使用 GCC 的动态和静态链接来编译一个非常简单(就像 hello world 一样简单)的 C 程序。我想知道一般如何做到这一点,所以我的最小测试示例只是尝试将 libc 链接为静态,将 libm 动态链接。
我至少遇到过以下有关同一主题的其他问题:
其中的一些答案建议使用 -Wl,-Bstatic 和 -Wl,-Bdynamic 来指定哪些库分别是静态库和动态库。还建议简单地指定要链接的静态库的完整路径。
我已经尝试过其中的一些建议及其变体。我不明白它给我的错误消息。我知道 PIE 是什么,但我不明白它与我想做的事情有什么关系。
以下是一些失败的尝试:
$ gcc test.c /usr/lib64/libc.a
linux-gnu/4.7.3/../../../../x86_64-pc-linux-gnu/bin/ld: dynamic STT_GNU_IFUNC symbol `strcmp' with pointer equality in `/usr/lib64/libc.a(strcmp.o)' can not be used when making an executable; recompile with -fPIE and relink with -pie
urned 1 exit status
$ gcc test.c -Wl,-Bdynamic -lm -Wl,-Bstatic -lc
/usr/lib/gcc/x86_64-pc-linux-gnu/4.7.3/../../../../x86_64-pc-linux-gnu/bin/ld: cannot find -lgcc_s
/usr/lib/gcc/x86_64-pc-linux-gnu/4.7.3/../../../../x86_64-pc-linux-gnu/bin/ld: cannot find -lgcc_s
collect2: error: ld returned 1 exit status
$ …Run Code Online (Sandbox Code Playgroud) 在寄存器约束下,扩展 GCC asm 中的多个输入和输出操作数的正确使用是什么?考虑一下我的问题的最小版本。下面简要介绍 GCC、AT&T 语法的扩展 asm 代码:
int input0 = 10;
int input1 = 15;
int output0 = 0;
int output1 = 1;
asm volatile("mov %[input0], %[output0]\t\n"
"mov %[input1], %[output1]\t\n"
: [output0] "=r" (output0), [output1] "=r" (output1)
: [input0] "r" (input0), [input1] "r" (input1)
:);
printf("output0: %d\n", output0);
printf("output1: %d\n", output1);
Run Code Online (Sandbox Code Playgroud)
基于https://gcc.gnu.org/onlinedocs/gcc/Extended-Asm.html,语法看起来是正确的,但是,我一定忽略了某些东西,或者犯了一些由于某种原因我看不到的小错误。
GCC 5.3.0 p1.0(无编译器参数)的输出是:
输出0:10
输出1:10
预期输出是:
输出 0: 10
输出 1: 15
在 GDB 中查看显示:
0x0000000000400581 <+43>:mov eax,DWORD PTR [rbp-0x10]
0x0000000000400584 <+46>:mov edx,DWORD PTR [rbp-0xc] 0x0000000000400587 …
声明是什么:
stack;
Run Code Online (Sandbox Code Playgroud)
在LVM2源代码中使用的单独一行是什么意思?https://www.sourceware.org/lvm2/
if (!_mountinfo_parse_line(buffer, &maj, &min, target) ||
!read_fn(buffer, maj, min, target, cb_data)) {
stack;
r = 0;
break;
}
Run Code Online (Sandbox Code Playgroud)
我在gdb中看到语句"stack;" 编译为:
lea r8,[rip+0x936db] # 0xdd704
lea rsi,[rip+0xa2f5d] # 0xecf8d
xor ecx,ecx
mov edx,0xb37
mov edi,0x7
xor eax,eax
call 0x80950 <print_log>
Run Code Online (Sandbox Code Playgroud)
我还注意到我无法将结果分配给变量:
错误:无法忽略void值,因为它应该是
不能像stack(0)那样调用stack()或给定的参数:
错误:被调用对象不是函数或函数指针
我还试图通过"堆栈"的源代码来查看它是如何派生或定义的,但我找不到它.
当我自己扫描时,我会经常看到随机打开的端口:
nmap -sT -T normal -p 1-65535 localhost
Run Code Online (Sandbox Code Playgroud)
例如
43194/tcp open unknown
58167/tcp open unknown
Run Code Online (Sandbox Code Playgroud)
有时没什么,有时像这样的一对.
然而,我看到之前这是一个误报,但它现在已经很老了:
http://seclists.org/incidents/2002/Dec/136
还有一些其他用户最近也报告了这一点:
https://bbs.archlinux.org/viewtopic.php?id=168197
但似乎并没有那么多人注意到它.我也觉得奇怪的是,这仍然是内核的"bug"/问题.这个问题真的长期存在吗?
任何人都可以确认这是正常的行为(测试必须执行几次才能确定,如果这确实是内核/ nmap问题,可能会因系统而异)?我现在在几台物理机器上测试了这个,结果是一样的.包括一台最近安装了操作系统的机器,从未运行过面向服务的网络,因此妥协似乎不太可能.
我的ip_local_port_range是32768 61000
测试的内核:3.16.3-smp,3.17.8-gentoo-r1
Nmap版本:6.4,6.47
如果我扫描我的IP,但是来自同一台物理机,也会发生这种情况.如果我从另一台机器扫描机器,即使-T疯了,我也从未看到这些端口打开.