.init_array 函数参数的任何文档?
Any documentation for .init_array function arguments?
我可以看到很多复制的知识,在 .init_array 部分注册的函数具有命令行参数 argc 和 argv,如 main(),但我无法在网上找到任何实际发布的文档这证实了这种情况。
是的,为了清楚起见,函数本身并没有在 .init_array 中“声明”,而是在那里声明了指向函数的指针,“注册”了函数,并由某个迭代器调用在启动期间。问题仍然存在:向我展示该迭代器传入的参数列表的一些文档。
我的目的是以一种微妙但通常安全的方式从动态库中更改这些参数,所以我想在内存中找到“真正的交易”——而不是从 /proc/self/.
有关详细信息,请按照下面的 link 进行操作。
一些 Stack-overflow 知识:
即使是我最喜欢的 Oracle ( docs.oracle.com/cd/E23824_01/html/819-0690/chapter3-8.html ) 也只提到函数被调用,但没有承诺可能有什么参数。据我所知,与 elf 和 gcc 文档相同。
在 C/C++ UB 偏执狂的土地上,理想情况下,在我继续之前,我需要确定这是记录在案的行为吗?它存在吗?可以以某种方式暗示吗?
到目前为止 comments/answers 的摘要:
至少对于 GNU libc,此补丁发生了相关更改:BZ #974。
https://sourceware.org/pipermail/libc-alpha/2005-July/019240.html(在 glibc 的 ChangeLog.old/ChangeLog.16 条目 2005-04-13 H.J.Lu. 中提到。) –
伊恩·阿博特
对我来说,这表明 glbc 维护者知道通过 argc/argv/env 的要求——这不是偶然的——并将其扩展到主 exe 注册。它还告诉我们它在该日期之前正在为动态库工作。
这是否会绑定其他 libc 实现者以遵循该模式,这是一个有趣的问题。
我找到了这个 interesting article about Linux programs' start-up procedure by Patrick Horgan。但是我可能不保证这个来源的正确性。
至少,它解释了 .init_array
部分后面的代码:
void __libc_csu_init (int argc, char **argv, char **envp) {
_init ();
const size_t size = __init_array_end - __init_array_start;
for (size_t i = 0; i < size; i++) {
(*__init_array_start [i]) (argc, argv, envp);
}
}
看来__libc_csu_init()
函数首先计算.init_array
节内的元素个数,然后用参数argc
、argv
和[=调用每个函数指针16=]。此函数 (__libc_csu_init()
) 在 main()
.
之前调用
注意:.init_array
部分似乎特定于 ELF 二进制格式。
更新
看来 __libc_csu_init()
的实现(更一般地说,.init_array
函数的调用方式)与平台和 libc 相关。
但是,Linux 上的 GLIBC 似乎可以使用所需参数正确调用函数,正如您在 its source code.
中看到的那样
此外,阅读 GLIBC changelog,似乎此行为已在 2005 年引入。
我可以看到很多复制的知识,在 .init_array 部分注册的函数具有命令行参数 argc 和 argv,如 main(),但我无法在网上找到任何实际发布的文档这证实了这种情况。
是的,为了清楚起见,函数本身并没有在 .init_array 中“声明”,而是在那里声明了指向函数的指针,“注册”了函数,并由某个迭代器调用在启动期间。问题仍然存在:向我展示该迭代器传入的参数列表的一些文档。
我的目的是以一种微妙但通常安全的方式从动态库中更改这些参数,所以我想在内存中找到“真正的交易”——而不是从 /proc/self/.
有关详细信息,请按照下面的 link 进行操作。
一些 Stack-overflow 知识:
即使是我最喜欢的 Oracle ( docs.oracle.com/cd/E23824_01/html/819-0690/chapter3-8.html ) 也只提到函数被调用,但没有承诺可能有什么参数。据我所知,与 elf 和 gcc 文档相同。
在 C/C++ UB 偏执狂的土地上,理想情况下,在我继续之前,我需要确定这是记录在案的行为吗?它存在吗?可以以某种方式暗示吗?
到目前为止 comments/answers 的摘要:
至少对于 GNU libc,此补丁发生了相关更改:BZ #974。 https://sourceware.org/pipermail/libc-alpha/2005-July/019240.html(在 glibc 的 ChangeLog.old/ChangeLog.16 条目 2005-04-13 H.J.Lu. 中提到。) – 伊恩·阿博特
对我来说,这表明 glbc 维护者知道通过 argc/argv/env 的要求——这不是偶然的——并将其扩展到主 exe 注册。它还告诉我们它在该日期之前正在为动态库工作。
这是否会绑定其他 libc 实现者以遵循该模式,这是一个有趣的问题。
我找到了这个 interesting article about Linux programs' start-up procedure by Patrick Horgan。但是我可能不保证这个来源的正确性。
至少,它解释了 .init_array
部分后面的代码:
void __libc_csu_init (int argc, char **argv, char **envp) {
_init ();
const size_t size = __init_array_end - __init_array_start;
for (size_t i = 0; i < size; i++) {
(*__init_array_start [i]) (argc, argv, envp);
}
}
看来__libc_csu_init()
函数首先计算.init_array
节内的元素个数,然后用参数argc
、argv
和[=调用每个函数指针16=]。此函数 (__libc_csu_init()
) 在 main()
.
注意:.init_array
部分似乎特定于 ELF 二进制格式。
更新
看来 __libc_csu_init()
的实现(更一般地说,.init_array
函数的调用方式)与平台和 libc 相关。
但是,Linux 上的 GLIBC 似乎可以使用所需参数正确调用函数,正如您在 its source code.
中看到的那样此外,阅读 GLIBC changelog,似乎此行为已在 2005 年引入。