Readelf 查找绝对地址
Readelf finding absolute address
我有一个 C 程序,它有一个全局变量和一个局部变量。我的问题是关于 readelf。以下是我的问题;
1. 当我使用 "readelf --symbols" 获取地址转储时,我得到一个全局变量的地址,该地址与我在 运行 程序时打印的地址相同。 readelf 如何在我的程序 运行ning 或加载之前知道绝对地址?
2. 为什么没有关于局部变量符号的信息?。我只能看到全局变量的符号。
How readelf can know the absolute address before my programme is running or been loaded?
因为当 linker 完成工作时,计算的地址是
你的全局变量 是 程序加载器将在的地址
必须在运行时放置该变量。 linker 的工作主要是
将信息放入 executable 中,告诉程序加载器在哪里
符号将映射到内存中。
Why there are no informations on the local variables' symbols
你的程序中可能存在三种"local"变量。
main.c
static int static_filescope_i = 1;
int f()
{
static int static_local_i = 2;
return static_local_i;
}
int g()
{
int automatic_i = 3;
return automatic_i;
}
int global_i = 4;
int main()
{
return global_i + f() + g() + static_filescope_i;
}
运行时在栈上创建了一个类似automatic_local_i
的自动变量
每次程序进入定义它的块,然后停止存在
然后它离开那个块。这样的变量在executable中不占用存储空间
所以它没有在符号 table.
中表示
像 static_filescope_i
这样的变量通常被称为 static global,
以区别于 static_local_i
。 static_local_i
不能
在定义它的块之外可以看到。 static_filescope_i
可以
可以在同一目标文件 (main.o
) 中定义的任何函数中看到,但是
不在任何其他目标文件中:它在 main.o
中是 global 但是
在整个程序中本地 目标文件 。
static_filescope_i
和static_local_i
都必须有自己的
程序第一次使用变量时的初始值,然后保持
它具有的任何值,或分配给它的任何新值,直到下一次
它被使用 - 跨函数调用,直到程序结束。这表示
这些变量需要存储在 executable 中,而不是堆栈中,它们 可能是也可能不是
用符号 table.
表示
global_i
,当然对整个程序来说是全局的:可以在
main.o
以及我们可能 link 和 main.o
的任何其他文件。
如果我们用默认选项编译main.c
(没有优化):
$ gcc -c main.c
然后我们发现:
$ readelf -s main.o | grep automatic_i
$
...automatic_i
没有符号。
$ readelf -s main.o | grep global_i
12: 0000000000000004 4 OBJECT GLOBAL DEFAULT 3 global_i
...global_i
.
的全局符号
$ readelf -s main.o | grep static_filescope_i
5: 0000000000000000 4 OBJECT LOCAL DEFAULT 3 static_filescope_i
...static_filescope_i
的本地符号
$ readelf -s main.o | grep static_local_i
6: 0000000000000008 4 OBJECT LOCAL DEFAULT 3 static_local_i.1833
...也是 static_local_i
的局部符号,但具有范围区分
附加后缀。
这里,GLOBAL
表示可以被linker看到,LOCAL
表示不可见
由 linker.
因此,为了 linking main.o
与任何其他目标文件或库的目的
制作一个 executable、static_filescope_i
和 static_local_i
也可以
不存在.
这并不意味着它们在目标文件中完全没有用。它们很有用
用于调试。它们对于调查静态的内容很有用
executable 的存储由,正如我们现在所做的那样。
但是它们对 linker 没有用,因此,如果您编译 main.c
进行任何优化
level > 0 那么编译器会假设你想要的目标代码不是为了
调试或调查的目的,它将不会发出任何本地符号:
$ gcc -O1 -c main.c
$ readelf -s main.o | grep static_local_i
$ readelf -s main.o | grep static_filescope_i
$ readelf -s main.o | grep global_i
11: 0000000000000000 4 OBJECT GLOBAL DEFAULT 3 global_i
...只剩下 global_i
。
这应该可以解释为什么您没有看到任何 "local" 符号。你的自动
变量永远不会出现在符号 table 中。您的静态变量仅在
符号 table 如果您已禁用所有优化。
我有一个 C 程序,它有一个全局变量和一个局部变量。我的问题是关于 readelf。以下是我的问题; 1. 当我使用 "readelf --symbols" 获取地址转储时,我得到一个全局变量的地址,该地址与我在 运行 程序时打印的地址相同。 readelf 如何在我的程序 运行ning 或加载之前知道绝对地址? 2. 为什么没有关于局部变量符号的信息?。我只能看到全局变量的符号。
How readelf can know the absolute address before my programme is running or been loaded?
因为当 linker 完成工作时,计算的地址是 你的全局变量 是 程序加载器将在的地址 必须在运行时放置该变量。 linker 的工作主要是 将信息放入 executable 中,告诉程序加载器在哪里 符号将映射到内存中。
Why there are no informations on the local variables' symbols
你的程序中可能存在三种"local"变量。
main.c
static int static_filescope_i = 1;
int f()
{
static int static_local_i = 2;
return static_local_i;
}
int g()
{
int automatic_i = 3;
return automatic_i;
}
int global_i = 4;
int main()
{
return global_i + f() + g() + static_filescope_i;
}
运行时在栈上创建了一个类似automatic_local_i
的自动变量
每次程序进入定义它的块,然后停止存在
然后它离开那个块。这样的变量在executable中不占用存储空间
所以它没有在符号 table.
像 static_filescope_i
这样的变量通常被称为 static global,
以区别于 static_local_i
。 static_local_i
不能
在定义它的块之外可以看到。 static_filescope_i
可以
可以在同一目标文件 (main.o
) 中定义的任何函数中看到,但是
不在任何其他目标文件中:它在 main.o
中是 global 但是
在整个程序中本地 目标文件 。
static_filescope_i
和static_local_i
都必须有自己的
程序第一次使用变量时的初始值,然后保持
它具有的任何值,或分配给它的任何新值,直到下一次
它被使用 - 跨函数调用,直到程序结束。这表示
这些变量需要存储在 executable 中,而不是堆栈中,它们 可能是也可能不是
用符号 table.
global_i
,当然对整个程序来说是全局的:可以在
main.o
以及我们可能 link 和 main.o
的任何其他文件。
如果我们用默认选项编译main.c
(没有优化):
$ gcc -c main.c
然后我们发现:
$ readelf -s main.o | grep automatic_i
$
...automatic_i
没有符号。
$ readelf -s main.o | grep global_i
12: 0000000000000004 4 OBJECT GLOBAL DEFAULT 3 global_i
...global_i
.
$ readelf -s main.o | grep static_filescope_i
5: 0000000000000000 4 OBJECT LOCAL DEFAULT 3 static_filescope_i
...static_filescope_i
$ readelf -s main.o | grep static_local_i
6: 0000000000000008 4 OBJECT LOCAL DEFAULT 3 static_local_i.1833
...也是 static_local_i
的局部符号,但具有范围区分
附加后缀。
这里,GLOBAL
表示可以被linker看到,LOCAL
表示不可见
由 linker.
因此,为了 linking main.o
与任何其他目标文件或库的目的
制作一个 executable、static_filescope_i
和 static_local_i
也可以
不存在.
这并不意味着它们在目标文件中完全没有用。它们很有用 用于调试。它们对于调查静态的内容很有用 executable 的存储由,正如我们现在所做的那样。
但是它们对 linker 没有用,因此,如果您编译 main.c
进行任何优化
level > 0 那么编译器会假设你想要的目标代码不是为了
调试或调查的目的,它将不会发出任何本地符号:
$ gcc -O1 -c main.c
$ readelf -s main.o | grep static_local_i
$ readelf -s main.o | grep static_filescope_i
$ readelf -s main.o | grep global_i
11: 0000000000000000 4 OBJECT GLOBAL DEFAULT 3 global_i
...只剩下 global_i
。
这应该可以解释为什么您没有看到任何 "local" 符号。你的自动 变量永远不会出现在符号 table 中。您的静态变量仅在 符号 table 如果您已禁用所有优化。