📄 elf-hppa.h
字号:
}/* Set the correct type for an ELF section. We do this by the section name, which is a hack, but ought to work. */static booleanelf_hppa_fake_sections (abfd, hdr, sec) bfd *abfd; elf_hppa_internal_shdr *hdr; asection *sec;{ register const char *name; name = bfd_get_section_name (abfd, sec); if (strcmp (name, ".PARISC.unwind") == 0) { int indx; asection *asec;#if ARCH_SIZE == 64 hdr->sh_type = SHT_LOPROC + 1;#else hdr->sh_type = 1;#endif /* ?!? How are unwinds supposed to work for symbols in arbitrary sections? Or what if we have multiple .text sections in a single .o file? HP really messed up on this one. Ugh. We can not use elf_section_data (sec)->this_idx at this point because it is not initialized yet. So we (gasp) recompute it here. Hopefully nobody ever changes the way sections are numbered in elf.c! */ for (asec = abfd->sections, indx = 1; asec; asec = asec->next, indx++) { if (asec->name && strcmp (asec->name, ".text") == 0) { hdr->sh_info = indx; break; } } /* I have no idea if this is really necessary or what it means. */ hdr->sh_entsize = 4; } return true;}static voidelf_hppa_final_write_processing (abfd, linker) bfd *abfd; boolean linker ATTRIBUTE_UNUSED;{ int mach = bfd_get_mach (abfd); elf_elfheader (abfd)->e_flags &= ~(EF_PARISC_ARCH | EF_PARISC_TRAPNIL | EF_PARISC_EXT | EF_PARISC_LSB | EF_PARISC_WIDE | EF_PARISC_NO_KABP | EF_PARISC_LAZYSWAP); if (mach == 10) elf_elfheader (abfd)->e_flags |= EFA_PARISC_1_0; else if (mach == 11) elf_elfheader (abfd)->e_flags |= EFA_PARISC_1_1; else if (mach == 20) elf_elfheader (abfd)->e_flags |= EFA_PARISC_2_0; else if (mach == 25) elf_elfheader (abfd)->e_flags |= (EF_PARISC_WIDE | EFA_PARISC_2_0 /* The GNU tools have trapped without option since 1993, so need to take a step backwards with the ELF based toolchains. */ | EF_PARISC_TRAPNIL);}#if ARCH_SIZE == 64/* Hook called by the linker routine which adds symbols from an object file. HP's libraries define symbols with HP specific section indices, which we have to handle. */static booleanelf_hppa_add_symbol_hook (abfd, info, sym, namep, flagsp, secp, valp) bfd *abfd; struct bfd_link_info *info ATTRIBUTE_UNUSED; const Elf_Internal_Sym *sym; const char **namep ATTRIBUTE_UNUSED; flagword *flagsp ATTRIBUTE_UNUSED; asection **secp; bfd_vma *valp;{ int index = sym->st_shndx; switch (index) { case SHN_PARISC_ANSI_COMMON: *secp = bfd_make_section_old_way (abfd, ".PARISC.ansi.common"); (*secp)->flags |= SEC_IS_COMMON; *valp = sym->st_size; break; case SHN_PARISC_HUGE_COMMON: *secp = bfd_make_section_old_way (abfd, ".PARISC.huge.common"); (*secp)->flags |= SEC_IS_COMMON; *valp = sym->st_size; break; } return true;}static booleanelf_hppa_unmark_useless_dynamic_symbols (h, data) struct elf_link_hash_entry *h; PTR data;{ struct bfd_link_info *info = (struct bfd_link_info *)data; /* If we are not creating a shared library, and this symbol is referenced by a shared library but is not defined anywhere, then the generic code will warn that it is undefined. This behavior is undesirable on HPs since the standard shared libraries contain references to undefined symbols. So we twiddle the flags associated with such symbols so that they will not trigger the warning. ?!? FIXME. This is horribly fragile. Ultimately we should have better controls over the generic ELF BFD linker code. */ if (! info->relocateable && ! (info->shared && !info->no_undefined) && h->root.type == bfd_link_hash_undefined && (h->elf_link_hash_flags & ELF_LINK_HASH_REF_DYNAMIC) != 0 && (h->elf_link_hash_flags & ELF_LINK_HASH_REF_REGULAR) == 0) { h->elf_link_hash_flags &= ~ELF_LINK_HASH_REF_DYNAMIC; h->elf_link_hash_flags |= 0x8000; } return true;}static booleanelf_hppa_remark_useless_dynamic_symbols (h, data) struct elf_link_hash_entry *h; PTR data;{ struct bfd_link_info *info = (struct bfd_link_info *)data; /* If we are not creating a shared library, and this symbol is referenced by a shared library but is not defined anywhere, then the generic code will warn that it is undefined. This behavior is undesirable on HPs since the standard shared libraries contain reerences to undefined symbols. So we twiddle the flags associated with such symbols so that they will not trigger the warning. ?!? FIXME. This is horribly fragile. Ultimately we should have better controls over the generic ELF BFD linker code. */ if (! info->relocateable && ! (info->shared && !info->no_undefined) && h->root.type == bfd_link_hash_undefined && (h->elf_link_hash_flags & ELF_LINK_HASH_REF_DYNAMIC) == 0 && (h->elf_link_hash_flags & ELF_LINK_HASH_REF_REGULAR) == 0 && (h->elf_link_hash_flags & 0x8000) != 0) { h->elf_link_hash_flags |= ELF_LINK_HASH_REF_DYNAMIC; h->elf_link_hash_flags &= ~0x8000; } return true;}/* Record the lowest address for the data and text segments. */static voidelf_hppa_record_segment_addrs (abfd, section, data) bfd *abfd ATTRIBUTE_UNUSED; asection *section; PTR data;{ struct elf64_hppa_link_hash_table *hppa_info; bfd_vma value; hppa_info = (struct elf64_hppa_link_hash_table *)data; value = section->vma - section->filepos; if (((section->flags & (SEC_ALLOC | SEC_LOAD | SEC_READONLY)) == (SEC_ALLOC | SEC_LOAD | SEC_READONLY)) && value < hppa_info->text_segment_base) hppa_info->text_segment_base = value; else if (((section->flags & (SEC_ALLOC | SEC_LOAD | SEC_READONLY)) == (SEC_ALLOC | SEC_LOAD)) && value < hppa_info->data_segment_base) hppa_info->data_segment_base = value;}/* Called after we have seen all the input files/sections, but before final symbol resolution and section placement has been determined. We use this hook to (possibly) provide a value for __gp, then we fall back to the generic ELF final link routine. */static booleanelf_hppa_final_link (abfd, info) bfd *abfd; struct bfd_link_info *info;{ boolean retval; struct elf64_hppa_link_hash_table *hppa_info = elf64_hppa_hash_table (info); if (! info->relocateable) { struct elf_link_hash_entry *gp; bfd_vma gp_val; /* The linker script defines a value for __gp iff it was referenced by one of the objects being linked. First try to find the symbol in the hash table. If that fails, just compute the value __gp should have had. */ gp = elf_link_hash_lookup (elf_hash_table (info), "__gp", false, false, false); if (gp) { /* Adjust the value of __gp as we may want to slide it into the .plt section so that the stubs can access PLT entries without using an addil sequence. */ gp->root.u.def.value += hppa_info->gp_offset; gp_val = (gp->root.u.def.section->output_section->vma + gp->root.u.def.section->output_offset + gp->root.u.def.value); } else { asection *sec; /* First look for a .plt section. If found, then __gp is the address of the .plt + gp_offset. If no .plt is found, then look for .dlt, .opd and .data (in that order) and set __gp to the base address of whichever section is found first. */ sec = hppa_info->plt_sec; if (sec) gp_val = (sec->output_offset + sec->output_section->vma + hppa_info->gp_offset); else { sec = hppa_info->dlt_sec; if (!sec) sec = hppa_info->opd_sec; if (!sec) sec = bfd_get_section_by_name (abfd, ".data"); if (!sec) return false; gp_val = sec->output_offset + sec->output_section->vma; } } /* Install whatever value we found/computed for __gp. */ _bfd_set_gp_value (abfd, gp_val); } /* We need to know the base of the text and data segments so that we can perform SEGREL relocations. We will record the base addresses when we encounter the first SEGREL relocation. */ hppa_info->text_segment_base = (bfd_vma)-1; hppa_info->data_segment_base = (bfd_vma)-1; /* HP's shared libraries have references to symbols that are not defined anywhere. The generic ELF BFD linker code will complaim about such symbols. So we detect the losing case and arrange for the flags on the symbol to indicate that it was never referenced. This keeps the generic ELF BFD link code happy and appears to not create any secondary problems. Ultimately we need a way to control the behavior of the generic ELF BFD link code better. */ elf_link_hash_traverse (elf_hash_table (info), elf_hppa_unmark_useless_dynamic_symbols, info); /* Invoke the regular ELF backend linker to do all the work. */ retval = bfd_elf_bfd_final_link (abfd, info); elf_link_hash_traverse (elf_hash_table (info), elf_hppa_remark_useless_dynamic_symbols, info); return retval;}/* Relocate an HPPA ELF section. */static booleanelf_hppa_relocate_section (output_bfd, info, input_bfd, input_section, contents, relocs, local_syms, local_sections) bfd *output_bfd; struct bfd_link_info *info; bfd *input_bfd; asection *input_section; bfd_byte *contents; Elf_Internal_Rela *relocs; Elf_Internal_Sym *local_syms; asection **local_sections;
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -