源於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在.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負責處理。