静态库改为动态库后,可以影响到程序的执行结果

来源:互联网 发布:dnf卢克减防算法 编辑:程序博客网 时间:2024/05/13 19:39

源于systemd的例子


先看bus-error.h中的一个宏:

#define BUS_ERROR_MAP_ELF_REGISTER                                      \        __attribute__ ((__section__("BUS_ERROR_MAP")))                  \        __attribute__ ((__used__))                                      \        __attribute__ ((aligned(8)))

意思是将数据定义在BUS_ERROR_MAP段,8字节对齐,标记为已使用的


bus-error.c中定义了一个数组:

BUS_ERROR_MAP_ELF_REGISTER const sd_bus_error_map bus_standard_errors[] = {        SD_BUS_ERROR_MAP("org.freedesktop.DBus.Error.Failed",                           EACCES),        SD_BUS_ERROR_MAP("org.freedesktop.DBus.Error.NoMemory",                         ENOMEM),        ......        SD_BUS_ERROR_MAP("org.freedesktop.DBus.Error.ObjectPathInUse",                  EBUSY),        SD_BUS_ERROR_MAP_END};


test-bus-error.c中定义了两个数组:

BUS_ERROR_MAP_ELF_REGISTER const sd_bus_error_map test_errors[] = {        SD_BUS_ERROR_MAP("org.freedesktop.custom-dbus-error", 5),        SD_BUS_ERROR_MAP("org.freedesktop.custom-dbus-error-2", 52),        SD_BUS_ERROR_MAP_END};BUS_ERROR_MAP_ELF_REGISTER const sd_bus_error_map test_errors2[] = {        SD_BUS_ERROR_MAP("org.freedesktop.custom-dbus-error-3", 33),        SD_BUS_ERROR_MAP("org.freedesktop.custom-dbus-error-4", 44),        SD_BUS_ERROR_MAP("org.freedesktop.custom-dbus-error-33", 333),        SD_BUS_ERROR_MAP_END};


如果将bus-error.c编译到静态库,然后test-bus-error.c去连接该静态库,bus-error.c和test-bus-error.c中定义的BUS_ERROR_MAP段中的数据会合并到同一个ELF的BUS_ERROR_MAP段中,里面有三个数组;

如果将bus-error.c编译到动态库,然后test-bus-error.c去连接该动态库,bus-error.c在.so中,有一个BUS_ERROR_MAP段;test-bus-error.c在.exe中,有另一个BUS_ERROR_MAP段,里面只有两个数组。

当使用如下代码打印数组时,就会发现动态连接的输出会少很多(只打印了test-bus-error.c中的两个数组):

extern const sd_bus_error_map __start_BUS_ERROR_MAP[];extern const sd_bus_error_map __stop_BUS_ERROR_MAP[];static void dump_mapping_table(void) {        const sd_bus_error_map *m;        printf("----- errno mappings ------\n");        m = __start_BUS_ERROR_MAP;        while (m < __stop_BUS_ERROR_MAP) {                if (m->code == BUS_ERROR_MAP_END_MARKER) {                        m = ALIGN8_PTR(m+1);                        continue;                }                printf("%s -> %i/%s\n", strna(m->name), m->code, strna(errno_to_name(m->code)));                m ++;        }        printf("---------------------------\n");}

__start_BUS_ERROR_MAP和__stop_BUS_ERROR_MAP分别是段BUS_ERROR_MAP的起始和结尾地址,由GCC负责处理。



0 0
原创粉丝点击