?? sunos.c
字號:
if ((h->flags & SUNOS_DEF_DYNAMIC) == 0 || (h->flags & SUNOS_DEF_REGULAR) != 0) continue; if (dynobj == NULL) { asection *sgot; if (! sunos_create_dynamic_sections (abfd, info, false)) return false; dynobj = sunos_hash_table (info)->dynobj; splt = bfd_get_section_by_name (dynobj, ".plt"); srel = bfd_get_section_by_name (dynobj, ".dynrel"); BFD_ASSERT (splt != NULL && srel != NULL); sgot = bfd_get_section_by_name (dynobj, ".got"); BFD_ASSERT (sgot != NULL); if (sgot->_raw_size == 0) sgot->_raw_size = BYTES_IN_WORD; sunos_hash_table (info)->got_needed = true; } BFD_ASSERT ((h->flags & SUNOS_REF_REGULAR) != 0); BFD_ASSERT (h->plt_offset != 0 || ((h->root.root.type == bfd_link_hash_defined || h->root.root.type == bfd_link_hash_defweak) ? (h->root.root.u.def.section->owner->flags & DYNAMIC) != 0 : (h->root.root.u.undef.abfd->flags & DYNAMIC) != 0)); /* This reloc is against a symbol defined only by a dynamic object. */ if (h->root.root.type == bfd_link_hash_undefined) { /* Presumably this symbol was marked as being undefined by an earlier reloc. */ srel->_raw_size += RELOC_STD_SIZE; } else if ((h->root.root.u.def.section->flags & SEC_CODE) == 0) { bfd *sub; /* This reloc is not in the .text section. It must be copied into the dynamic relocs. We mark the symbol as being undefined. */ srel->_raw_size += RELOC_STD_SIZE; sub = h->root.root.u.def.section->owner; h->root.root.type = bfd_link_hash_undefined; h->root.root.u.undef.abfd = sub; } else { /* This symbol is in the .text section. We must give it an entry in the procedure linkage table, if we have not already done so. We change the definition of the symbol to the .plt section; this will cause relocs against it to be handled correctly. */ if (h->plt_offset == 0) { if (splt->_raw_size == 0) splt->_raw_size = M68K_PLT_ENTRY_SIZE; h->plt_offset = splt->_raw_size; if ((h->flags & SUNOS_DEF_REGULAR) == 0) { h->root.root.u.def.section = splt; h->root.root.u.def.value = splt->_raw_size; } splt->_raw_size += M68K_PLT_ENTRY_SIZE; /* We may also need a dynamic reloc entry. */ if ((h->flags & SUNOS_DEF_REGULAR) == 0) srel->_raw_size += RELOC_STD_SIZE; } } } return true;}/* Scan the relocs for an input section using extended relocs. We need to figure out what to do for each reloc against a dynamic symbol. If the reloc is a WDISP30, and the symbol is in the .text section, an entry is made in the procedure linkage table. Otherwise, we must preserve the reloc as a dynamic reloc. */static booleansunos_scan_ext_relocs (info, abfd, sec, relocs, rel_size) struct bfd_link_info *info; bfd *abfd; asection *sec ATTRIBUTE_UNUSED; const struct reloc_ext_external *relocs; bfd_size_type rel_size;{ bfd *dynobj; struct sunos_link_hash_entry **sym_hashes; const struct reloc_ext_external *rel, *relend; asection *splt = NULL; asection *sgot = NULL; asection *srel = NULL; /* We only know how to handle SPARC plt entries. */ if (bfd_get_arch (abfd) != bfd_arch_sparc) { bfd_set_error (bfd_error_invalid_target); return false; } dynobj = NULL; sym_hashes = (struct sunos_link_hash_entry **) obj_aout_sym_hashes (abfd); relend = relocs + rel_size / RELOC_EXT_SIZE; for (rel = relocs; rel < relend; rel++) { unsigned int r_index; int r_extern; int r_type; struct sunos_link_hash_entry *h = NULL; /* Swap in the reloc information. */ if (bfd_header_big_endian (abfd)) { r_index = ((rel->r_index[0] << 16) | (rel->r_index[1] << 8) | rel->r_index[2]); r_extern = (0 != (rel->r_type[0] & RELOC_EXT_BITS_EXTERN_BIG)); r_type = ((rel->r_type[0] & RELOC_EXT_BITS_TYPE_BIG) >> RELOC_EXT_BITS_TYPE_SH_BIG); } else { r_index = ((rel->r_index[2] << 16) | (rel->r_index[1] << 8) | rel->r_index[0]); r_extern = (0 != (rel->r_type[0] & RELOC_EXT_BITS_EXTERN_LITTLE)); r_type = ((rel->r_type[0] & RELOC_EXT_BITS_TYPE_LITTLE) >> RELOC_EXT_BITS_TYPE_SH_LITTLE); } if (r_extern) { h = sym_hashes[r_index]; if (h == NULL) { /* This should not normally happen, but it will in any case be caught in the relocation phase. */ continue; } } /* If this is a base relative reloc, we need to make an entry in the .got section. */ if (r_type == RELOC_BASE10 || r_type == RELOC_BASE13 || r_type == RELOC_BASE22) { if (dynobj == NULL) { if (! sunos_create_dynamic_sections (abfd, info, false)) return false; dynobj = sunos_hash_table (info)->dynobj; splt = bfd_get_section_by_name (dynobj, ".plt"); sgot = bfd_get_section_by_name (dynobj, ".got"); srel = bfd_get_section_by_name (dynobj, ".dynrel"); BFD_ASSERT (splt != NULL && sgot != NULL && srel != NULL); /* Make sure we have an initial entry in the .got table. */ if (sgot->_raw_size == 0) sgot->_raw_size = BYTES_IN_WORD; sunos_hash_table (info)->got_needed = true; } if (r_extern) { if (h->got_offset != 0) continue; h->got_offset = sgot->_raw_size; } else { if (r_index >= bfd_get_symcount (abfd)) { /* This is abnormal, but should be caught in the relocation phase. */ continue; } if (adata (abfd).local_got_offsets == NULL) { adata (abfd).local_got_offsets = (bfd_vma *) bfd_zalloc (abfd, (bfd_get_symcount (abfd) * sizeof (bfd_vma))); if (adata (abfd).local_got_offsets == NULL) return false; } if (adata (abfd).local_got_offsets[r_index] != 0) continue; adata (abfd).local_got_offsets[r_index] = sgot->_raw_size; } sgot->_raw_size += BYTES_IN_WORD; /* If we are making a shared library, or if the symbol is defined by a dynamic object, we will need a dynamic reloc entry. */ if (info->shared || (h != NULL && (h->flags & SUNOS_DEF_DYNAMIC) != 0 && (h->flags & SUNOS_DEF_REGULAR) == 0)) srel->_raw_size += RELOC_EXT_SIZE; continue; } /* Otherwise, we are only interested in relocs against symbols defined in dynamic objects but not in regular objects. We only need to consider relocs against external symbols. */ if (! r_extern) { /* But, if we are creating a shared library, we need to generate an absolute reloc. */ if (info->shared) { if (dynobj == NULL) { if (! sunos_create_dynamic_sections (abfd, info, true)) return false; dynobj = sunos_hash_table (info)->dynobj; splt = bfd_get_section_by_name (dynobj, ".plt"); sgot = bfd_get_section_by_name (dynobj, ".got"); srel = bfd_get_section_by_name (dynobj, ".dynrel"); BFD_ASSERT (splt != NULL && sgot != NULL && srel != NULL); } srel->_raw_size += RELOC_EXT_SIZE; } continue; } /* At this point common symbols have already been allocated, so we don't have to worry about them. We need to consider that we may have already seen this symbol and marked it undefined; if the symbol is really undefined, then SUNOS_DEF_DYNAMIC will be zero. */ if (h->root.root.type != bfd_link_hash_defined && h->root.root.type != bfd_link_hash_defweak && h->root.root.type != bfd_link_hash_undefined) continue; if (r_type != RELOC_JMP_TBL && ! info->shared && ((h->flags & SUNOS_DEF_DYNAMIC) == 0 || (h->flags & SUNOS_DEF_REGULAR) != 0)) continue; if (r_type == RELOC_JMP_TBL && ! info->shared && (h->flags & SUNOS_DEF_DYNAMIC) == 0 && (h->flags & SUNOS_DEF_REGULAR) == 0) { /* This symbol is apparently undefined. Don't do anything here; just let the relocation routine report an undefined symbol. */ continue; } if (strcmp (h->root.root.root.string, "__GLOBAL_OFFSET_TABLE_") == 0) continue; if (dynobj == NULL) { if (! sunos_create_dynamic_sections (abfd, info, false)) return false; dynobj = sunos_hash_table (info)->dynobj; splt = bfd_get_section_by_name (dynobj, ".plt"); sgot = bfd_get_section_by_name (dynobj, ".got"); srel = bfd_get_section_by_name (dynobj, ".dynrel"); BFD_ASSERT (splt != NULL && sgot != NULL && srel != NULL); /* Make sure we have an initial entry in the .got table. */ if (sgot->_raw_size == 0) sgot->_raw_size = BYTES_IN_WORD; sunos_hash_table (info)->got_needed = true; } BFD_ASSERT (r_type == RELOC_JMP_TBL || info->shared || (h->flags & SUNOS_REF_REGULAR) != 0); BFD_ASSERT (r_type == RELOC_JMP_TBL || info->shared || h->plt_offset != 0 || ((h->root.root.type == bfd_link_hash_defined || h->root.root.type == bfd_link_hash_defweak) ? (h->root.root.u.def.section->owner->flags & DYNAMIC) != 0 : (h->root.root.u.undef.abfd->flags & DYNAMIC) != 0)); /* This reloc is against a symbol defined only by a dynamic object, or it is a jump table reloc from PIC compiled code. */ if (r_type != RELOC_JMP_TBL && h->root.root.type == bfd_link_hash_undefined) { /* Presumably this symbol was marked as being undefined by an earlier reloc. */ srel->_raw_size += RELOC_EXT_SIZE; } else if (r_type != RELOC_JMP_TBL && (h->root.root.u.def.section->flags & SEC_CODE) == 0) { bfd *sub; /* This reloc is not in the .text section. It must be copied into the dynamic relocs. We mark the symbol as being undefined. */ srel->_raw_size += RELOC_EXT_SIZE; if ((h->flags & SUNOS_DEF_REGULAR) == 0) { sub = h->root.root.u.def.section->owner; h->root.root.type = bfd_link_hash_undefined; h->root.root.u.undef.abfd = sub; } } else { /* This symbol is in the .text section. We must give it an entry in the procedure linkage table, if we have not already done so. We change the definition of the symbol to the .plt section; this will cause relocs against it to be handled correctly. */ if (h->plt_offset == 0) { if (splt->_raw_size == 0) splt->_raw_size = SPARC_PLT_ENTRY_SIZE; h->plt_offset = splt->_raw_size; if ((h->flags & SUNOS_DEF_REGULAR) == 0) { if (h->root.root.type == bfd_link_hash_undefined) h->root.root.type = bfd_link_hash_defined; h->root.root.u.def.section = splt; h->root.root.u.def.value = splt->_raw_size; } splt->_raw_size += SPARC_PLT_ENTRY_SIZE; /* We will also need a dynamic reloc entry, unless this is a JMP_TBL reloc produced by linking PIC compiled code, and we are not making a shared library. */ if (info->shared || (h->flags & SUNOS_DEF_REGULAR) == 0) srel->_raw_size += RELOC_EXT_SIZE; } /* If we are creating a shared library, we need to copy over any reloc other than a jump table reloc. */ if (info->shared && r_type != RELOC_JMP_TBL) srel->_raw_size += RELOC_EXT_SIZE; } } return true;}/* Build the hash table of dynamic symbols, and to mark as written all symbols from dynamic objects which we do not plan to write out. */static booleansunos_scan_dynamic_symbol (h, data) struct sunos_link_hash_entry *h; PTR data;{ struct bfd_link_info *info = (struct bfd_link_info *) data; /* Set the written flag for symbols we do not want to write out as part of the regular symbol table. This is all symbols which are not defined in a regular object file. For some reason symbols which are referenced by a regular object and defined by a dynamic object do not seem to show up in the regular symbol table. It is possible for a symbol to have only SUNOS_REF_REGULAR set here, it is an undefined symbol which was turned into a common symbol because it was found in an archive object which was not included in the link. */ if ((h->flags & SUNOS_DEF_REGULAR) == 0 && (h->flags & SUNOS_DEF_DYNAMIC) != 0 && strcmp (h->root.root.root.string, "__DYNAMIC") != 0) h->root.written = true; /* If this symbol is defined by a dynamic object and referenced by a regular object, see whether we gave it a reasonable value while scanning the relocs. */ if ((h->flags & SUNOS_DEF_REGULAR) == 0 && (h->flags & SUNOS_DEF_DYNAMIC) != 0 && (h->flags & SUNOS_REF_REGULAR) != 0) { if ((h->root.root.type == bfd_link_hash_defined || h->root.root.type == bfd_link_hash_defweak) && ((h->root.root.u.def.section->owner->flags & DYNAMIC) != 0) && h->root.root.u.def.section->output_section == NULL) { bfd *sub; /* This symbol is currently defined in a dynamic section which is not being put into the output file. This implies that there is no reloc against the symbol. I'm not sure why this case would ever occur. In any case, we change the symbol to be undefined. */ sub = h->root.root.u.def.section->owner; h->root.root.type = bfd_link_hash_undefined; h-
?? 快捷鍵說明
復制代碼
Ctrl + C
搜索代碼
Ctrl + F
全屏模式
F11
切換主題
Ctrl + Shift + D
顯示快捷鍵
?
增大字號
Ctrl + =
減小字號
Ctrl + -