Linux 静态链接库默认入口点

Linux 静态链接库默认入口点,linux,linker,openssl,static-libraries,static-linking,Linux,Linker,Openssl,Static Libraries,Static Linking,链接静态库时,该特定库是否有默认入口点 我认为没有,但我想澄清一下。我们需要在链接期间为静态库添加一个入口点,以启动一些初始化/验证调用 例如,我们有一个静态库libstuff.a,希望能够在该库中调用initStuff()例程,但在加载期间(或尽可能接近加载),而不是运行时(我知道它在技术上是运行时,但不受任何post _start()/main()例程的控制) 澄清一下,这是为了满足NIST FIPS 140.2规范的要求,特别是本规范第9.10节的要求。这包括数据和文本段签名验证(参见第9

链接静态库时,该特定库是否有默认入口点

我认为没有,但我想澄清一下。我们需要在链接期间为静态库添加一个入口点,以启动一些初始化/验证调用

例如,我们有一个静态库libstuff.a,希望能够在该库中调用initStuff()例程,但在加载期间(或尽可能接近加载),而不是运行时(我知道它在技术上是运行时,但不受任何post _start()/main()例程的控制)


澄清一下,这是为了满足NIST FIPS 140.2规范的要求,特别是本规范第9.10节的要求。这包括数据和文本段签名验证(参见第9.10节的注释3)。

最常见的方法是公开初始化函数,库用户在使用库之前必须首先调用这些函数

在C++中,可以使用构造函数和析构函数来拥有全局对象。但是,当这些对象位于静态库中时,需要引用它们,否则链接器可能会排除它们,因为它们没有被引用。此外,您可能需要在不同的翻译单元之间强制执行初始化顺序

使用gcc时,函数可以有属性。达到与使用C++构造器相同的效果。
<>你可以在使用C++习惯用法前强制你的库自动初始化。它适用于共享库和静态库

下面是一个如何在普通C中执行此操作的示例:

库的标题:

// lib.h

// These get called by every translation unit including this header file.
extern void lib_ctor();
extern void lib_dtor();

// These are the automatic callers of the above functions.
// Embedded in every translation unit that includes this header.
static void local_lib_ctor() __attribute__((constructor));
static void local_lib_dtor() __attribute__((destructor));
void local_lib_ctor() { lib_ctor(); }
void local_lib_dtor() { lib_dtor(); }

// There rest of lib API.
初始化例程的实现:

// lib.c

static int ref_counter = 0;

void lib_ctor() {
    if(!ref_counter++) {
        // Do construction here.
    }
}

void lib_dtor() {
    if(!--ref_counter) {
        // Do destruction here.
    }
}

不,不符合NIST FIPS 140-2规范

实现我所追求的目标的唯一解决方案是使用共享库,在该库中使用构造函数属性调用初始化函数(或修改的.init ELF hook,但构造函数更清晰)。这确保在应用程序启动之前调用初始化


由于存档库只是一堆对象文件,无法将它们作为一个组与它们自己的初始化例程隔离开来,只有应用程序范围的初始化例程调用存档库中包含的符号。

谢谢Maxim,我已经在研究如何使用构造函数属性,这是我能找到的最接近的东西,但不幸的是,它仍然在链接存档库的边界之外。不幸的是,这些初始化器必须在库代码本身的领域内调用,构造函数属性调用仍然被视为运行时调用,而不是所需的加载时间。@mrtimdog不清楚您称之为加载时间的内容。在运行时加载程序完成加载可执行文件和共享库之前,您的可执行文件不会获得控制权。之后,控制被传递到通常由libc实现的
\u start
。这就是最终调用构造函数和全局对象构造函数的libc。。。为了更清楚一点,这是关于OpenSSL的libcrypto.a和FIPS 140-2实现。有关具体实施需求,请参见第9.10节的注释3。基本上,OpenSSL看起来是一个无法实现的痛苦(或者很可能永远都是,看)。@Timdog先生,我明白了。NIST的那篇论文确实建议使用
构造函数
函数属性。你可以为一堆.o文件设置一个初始化例程。看见你也可以在C语言中使用类似的技巧。为你添加了一个例子。也许我需要在这个问题上更清楚一点,正如我对FIPS NIST静态库认证的评论所指出的。具体地说,链接的库必须是自包含的,其初始化例程完全位于仅包含该库中的符号的边界内,并且所有这些符号(而不是其他符号)都可以作为一个整体进行指纹识别。这一切必须仅在链接库的领域内发生。这就是为什么这是正确的答案,因为它不能在Linux中完成。不需要下一票。初始化例程完全在一个边界内,只包含该库中的符号,这意味着什么?