在 Binutils 中,"bfd_section_already_linked_table_init()" 用于初始化一个哈希表,其主要目的可能是跟踪已经被链接的节(sections)以避免重复链接。链接过程中,特定的节可能已经被链接到输出文件中,如果不加以跟踪,可能会导致不必要的重复链接。
这个哈希表的使用可能在链接过程中的某个阶段,例如节合并(section merging)或符号解析(symbol resolution)时,用于检查某个节是否已经被链接,以便做出适当的决策。
- if (!bfd_section_already_linked_table_init ()) // 初始化了一个hash table
- einfo (_("%P%F: Failed to create hash table\n"));
- bfd_boolean
- bfd_section_already_linked_table_init (void)
- {
- return bfd_hash_table_init_n (&_bfd_section_already_linked_table,
- already_linked_newfunc,
- sizeof (struct bfd_section_already_linked_hash_entry),
- 42);
- }
static struct bfd_hash_table _bfd_section_already_linked_table;
- struct bfd_section_already_linked_hash_entry
- {
- struct bfd_hash_entry root;
- struct bfd_section_already_linked *entry;
- };
-
- struct bfd_section_already_linked
- {
- struct bfd_section_already_linked *next;
- asection *sec;
- };
-
- struct bfd_hash_entry
- {
- /* Next entry for this hash code. */
- struct bfd_hash_entry *next;
- /* String being hashed. */
- const char *string;
- /* Hash code. This is the full hash code, not the index into the
- table. */
- unsigned long hash;
- };
- static struct bfd_hash_entry *
- already_linked_newfunc (struct bfd_hash_entry *entry ATTRIBUTE_UNUSED,
- struct bfd_hash_table *table,
- const char *string ATTRIBUTE_UNUSED)
- {
- struct bfd_section_already_linked_hash_entry *ret =
- (struct bfd_section_already_linked_hash_entry *)
- bfd_hash_allocate (table, sizeof *ret);
-
- if (ret == NULL)
- return NULL;
-
- ret->entry = NULL;
-
- return &ret->root;
- }
- static struct bfd_hash_entry *
- already_linked_newfunc (struct bfd_hash_entry *entry ATTRIBUTE_UNUSED,
- struct bfd_hash_table *table,
- const char *string ATTRIBUTE_UNUSED)
- {
- struct bfd_section_already_linked_hash_entry *ret =
- (struct bfd_section_already_linked_hash_entry *)
- bfd_hash_allocate (table, sizeof *ret);
-
- if (ret == NULL)
- return NULL;
-
- ret->entry = NULL;
-
- return &ret->root;
- }
这里的函数调用中,&_bfd_section_already_linked_table是一个指向哈希表的指针,表示将要初始化的哈希表的地址,用于存储已经链接过的段的信息。这个数据结构解释如下:
标有SEC_LINK_ONCE标志的节应仅链接到输出中一次。此例程检查每个节,如果已经链接了相同名称的节,则安排丢弃该节。此代码假定所有相关部分都设置了SEC_LINK_ONCE标志;
already_linked_newfunc是一个回调函数,用于在哈希表中创建新的条目。
- bfd_boolean
- bfd_hash_table_init_n (struct bfd_hash_table *table,
- struct bfd_hash_entry *(*newfunc) (struct bfd_hash_entry *,
- struct bfd_hash_table *,
- const char *),
- unsigned int entsize,
- unsigned int size)
- {
- unsigned long alloc;
-
- alloc = size;
- alloc *= sizeof (struct bfd_hash_entry *);
- if (alloc / sizeof (struct bfd_hash_entry *) != size)
- {
- bfd_set_error (bfd_error_no_memory);
- return FALSE;
- }
-
- table->memory = (void *) objalloc_create ();
- if (table->memory == NULL)
- {
- bfd_set_error (bfd_error_no_memory);
- return FALSE;
- }
- table->table = (struct bfd_hash_entry **)
- objalloc_alloc ((struct objalloc *) table->memory, alloc);
- if (table->table == NULL)
- {
- bfd_hash_table_free (table);
- bfd_set_error (bfd_error_no_memory);
- return FALSE;
- }
- memset ((void *) table->table, 0, alloc);
- table->size = size;
- table->entsize = entsize;
- table->count = 0;
- table->frozen = 0;
- table->newfunc = newfunc;
- return TRUE;
- }