【问题标题】:Location of global variables w/o -fPIC没有 -fPIC 的全局变量的位置
【发布时间】:2019-02-05 17:14:19
【问题描述】:

尽管存在一些关于-fPIC 效应的帖子(例如,参见this SO post),但其中大部分都不清楚。我写了一个非常简单的例子,但我仍然无法弄清楚没有-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: %d\n",var1Loc);
    printf("var2 address is: %d\n",var2Loc);
    printf("diff         is: %d\n",var2Loc-var1Loc);

    return var1+var2;
}

然后我编译它 with -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。并不是说我听说 ASLR 仅适用于堆栈内存——如果您说“仅共享库地址”,我就不会那么惊讶了。您将不得不等待其他有替代想法的人。抱歉,我帮不上忙。
  • Wikipedia on ASLR — 提到 “ASLR 随机排列进程关键数据区域的地址空间位置,包括可执行文件的基址以及堆栈、堆和库的位置。”
  • 我使用echo 0 | sudo tee /proc/sys/kernel/randomize_va_space 关闭了 ASLR,实际上地址在运行中是相同的。有或没有-fPIC

标签: c global-variables fpic


【解决方案1】:

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

ASLR 上的维基百科说:

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

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

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

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

请注意,您的地址打印可能应该使用 %p 格式和 void * 参数(尽管当您将 (int) 强制转换为地址时,您可能会截断数据转换 - 但使用 @ 格式是正确的987654328@)。类型修饰符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: %p\n", var1Loc);
    printf("var2 address is: %p\n", var2Loc);
    printf("diff         is: %td\n", &var2 - &var1);

    return 0;
}

【讨论】:

    猜你喜欢
    • 2011-11-10
    • 2021-06-21
    • 1970-01-01
    • 1970-01-01
    • 2012-04-29
    • 2020-10-29
    • 1970-01-01
    • 2017-12-12
    • 1970-01-01
    相关资源
    最近更新 更多