c - 没有 -fPIC 的全局变量的位置



尽管存在一些关于-fPIC效应的帖子(例如,请参阅此SO帖子(,但其中大多数都不清楚。我写了一个非常简单的例子,但我仍然无法弄清楚在没有全局变量位置的情况下会发生什么-fPIC。这是我的 C 文件:

$ cat main.c
#include <stdio.h>
int var1 = 94;
int var2 = 76;
int main(int argc, char **argv)
{
    int var1Loc = (int) &var1;
    int var2Loc = (int) &var2;
    printf("var1 address is: %dn",var1Loc);
    printf("var2 address is: %dn",var2Loc);
    printf("diff         is: %dn",var2Loc-var1Loc);
    return var1+var2;
}

然后我-fPIC编译它并运行两次:

$ gcc -Wno-pointer-to-int-cast -O0 -g -o main main.c
$ ./main
var1 address is: -2019672048
var2 address is: -2019672044
diff         is: 4
$ ./main
var1 address is: 1441697808
var2 address is: 1441697812
diff         is: 4

当我在没有-fPIC的情况下做完全相同的事情时我得到了类似的结果。我以为没有-fPIC地址应该在运行中相同不是吗?

在首字母缩略词(或首字母缩写(中:ASLR — 地址空间布局随机化。

关于ASLR的维基百科 说:

ASLR 随机排列进程关键数据区域的地址空间位置,包括可执行文件的基础以及堆栈、堆和库的位置。

这描述了您所看到的内容。 您随后发现使用:

 echo 0 | sudo tee /proc/sys/kernel/randomize_va_space

关闭 ASLR 意味着地址在运行中是相同的,无论有没有-fPIC,从而确认 ASLR 是地址更改的原因。

请注意,您的地址打印可能应该使用 %p 格式和void *参数(尽管当您将(int)转换为地址时,您可能会截断数据转换 — 但使用 %d 格式是正确的(。 类型修饰符t用于ptrdiff_t,两个指针之间的差值。

#include <stdio.h>
int var1 = 94;
int var2 = 76;
int main(void)
{
    void *var1Loc = &var1;
    void *var2Loc = &var2;
    printf("var1 address is: %pn", var1Loc);
    printf("var2 address is: %pn", var2Loc);
    printf("diff         is: %tdn", &var2 - &var1);
    return 0;
}

相关内容

  • 没有找到相关文章

最新更新