elf32-i370.c
来自「基于4个mips核的noc设计」· C语言 代码 · 共 1,723 行 · 第 1/4 页
C
1,723 行
i370_elf_howto_init (); local_got_offsets = elf_local_got_offsets (input_bfd); for (; rel < relend; rel++) { enum i370_reloc_type r_type = (enum i370_reloc_type)ELF32_R_TYPE (rel->r_info); bfd_vma offset = rel->r_offset; bfd_vma addend = rel->r_addend; bfd_reloc_status_type r = bfd_reloc_other; Elf_Internal_Sym *sym = (Elf_Internal_Sym *)0; asection *sec = (asection *)0; struct elf_link_hash_entry *h = (struct elf_link_hash_entry *)0; const char *sym_name = (const char *)0; reloc_howto_type *howto; unsigned long r_symndx; bfd_vma relocation; /* Unknown relocation handling */ if ((unsigned)r_type >= (unsigned)R_I370_max || !i370_elf_howto_table[(int)r_type]) { (*_bfd_error_handler) ("%s: unknown relocation type %d", bfd_get_filename (input_bfd), (int)r_type); bfd_set_error (bfd_error_bad_value); ret = false; continue; } howto = i370_elf_howto_table[(int)r_type]; r_symndx = ELF32_R_SYM (rel->r_info); if (info->relocateable) { /* This is a relocateable link. We don't have to change anything, unless the reloc is against a section symbol, in which case we have to adjust according to where the section symbol winds up in the output section. */ if (r_symndx < symtab_hdr->sh_info) { sym = local_syms + r_symndx; if ((unsigned)ELF_ST_TYPE (sym->st_info) == STT_SECTION) { sec = local_sections[r_symndx]; addend = rel->r_addend += sec->output_offset + sym->st_value; } }#ifdef DEBUG fprintf (stderr, "\ttype = %s (%d), symbol index = %ld, offset = %ld, addend = %ld\n", howto->name, (int)r_type, r_symndx, (long)offset, (long)addend);#endif continue; } /* This is a final link. */ if (r_symndx < symtab_hdr->sh_info) { sym = local_syms + r_symndx; sec = local_sections[r_symndx]; sym_name = "<local symbol>"; relocation = (sec->output_section->vma + sec->output_offset + sym->st_value); } else { h = sym_hashes[r_symndx - symtab_hdr->sh_info]; while (h->root.type == bfd_link_hash_indirect || h->root.type == bfd_link_hash_warning) h = (struct elf_link_hash_entry *) h->root.u.i.link; sym_name = h->root.root.string; if (h->root.type == bfd_link_hash_defined || h->root.type == bfd_link_hash_defweak) { sec = h->root.u.def.section; if (info->shared && ((! info->symbolic && h->dynindx != -1) || (h->elf_link_hash_flags & ELF_LINK_HASH_DEF_REGULAR) == 0) && (input_section->flags & SEC_ALLOC) != 0 && (r_type == R_I370_ADDR31 || r_type == R_I370_COPY || r_type == R_I370_ADDR16 || r_type == R_I370_RELATIVE)) { /* In these cases, we don't need the relocation value. We check specially because in some obscure cases sec->output_section will be NULL. */ relocation = 0; } else relocation = (h->root.u.def.value + sec->output_section->vma + sec->output_offset); } else if (h->root.type == bfd_link_hash_undefweak) relocation = 0; else if (info->shared && ELF_ST_VISIBILITY (h->other) == STV_DEFAULT) relocation = 0; else { (*info->callbacks->undefined_symbol) (info, h->root.root.string, input_bfd, input_section, rel->r_offset, true); ret = false; continue; } } switch ((int)r_type) { default: (*_bfd_error_handler) ("%s: unknown relocation type %d for symbol %s", bfd_get_filename (input_bfd), (int)r_type, sym_name); bfd_set_error (bfd_error_bad_value); ret = false; continue; /* Relocations that may need to be propagated if this is a shared object. */ case (int)R_I370_REL31: /* If these relocations are not to a named symbol, they can be handled right here, no need to bother the dynamic linker. */ if (h == NULL || strcmp (h->root.root.string, "_GLOBAL_OFFSET_TABLE_") == 0) break; /* fall through */ /* Relocations that always need to be propagated if this is a shared object. */ case (int)R_I370_NONE: case (int)R_I370_ADDR31: case (int)R_I370_ADDR16: if (info->shared) { Elf_Internal_Rela outrel; boolean skip;#ifdef DEBUG fprintf (stderr, "i370_elf_relocate_section needs to create relocation for %s\n", (h && h->root.root.string) ? h->root.root.string : "<unknown>");#endif /* When generating a shared object, these relocations are copied into the output file to be resolved at run time. */ if (sreloc == NULL) { const char *name; name = (bfd_elf_string_from_elf_section (input_bfd, elf_elfheader (input_bfd)->e_shstrndx, elf_section_data (input_section)->rel_hdr.sh_name)); if (name == NULL) return false; BFD_ASSERT (strncmp (name, ".rela", 5) == 0 && strcmp (bfd_get_section_name (input_bfd, input_section), name + 5) == 0); sreloc = bfd_get_section_by_name (dynobj, name); BFD_ASSERT (sreloc != NULL); } skip = false; if (elf_section_data (input_section)->stab_info == NULL) outrel.r_offset = rel->r_offset; else { bfd_vma off; off = (_bfd_stab_section_offset (output_bfd, &elf_hash_table (info)->stab_info, input_section, &elf_section_data (input_section)->stab_info, rel->r_offset)); if (off == (bfd_vma) -1) skip = true; outrel.r_offset = off; } outrel.r_offset += (input_section->output_section->vma + input_section->output_offset); if (skip) memset (&outrel, 0, sizeof outrel); /* h->dynindx may be -1 if this symbol was marked to become local. */ else if (h != NULL && ((! info->symbolic && h->dynindx != -1) || (h->elf_link_hash_flags & ELF_LINK_HASH_DEF_REGULAR) == 0)) { BFD_ASSERT (h->dynindx != -1); outrel.r_info = ELF32_R_INFO (h->dynindx, r_type); outrel.r_addend = rel->r_addend; } else { if (r_type == R_I370_ADDR31) { outrel.r_info = ELF32_R_INFO (0, R_I370_RELATIVE); outrel.r_addend = relocation + rel->r_addend; } else { long indx; if (h == NULL) sec = local_sections[r_symndx]; else { BFD_ASSERT (h->root.type == bfd_link_hash_defined || (h->root.type == bfd_link_hash_defweak)); sec = h->root.u.def.section; } if (sec != NULL && bfd_is_abs_section (sec)) indx = 0; else if (sec == NULL || sec->owner == NULL) { bfd_set_error (bfd_error_bad_value); return false; } else { asection *osec; osec = sec->output_section; indx = elf_section_data (osec)->dynindx; BFD_ASSERT(indx > 0);#ifdef DEBUG if (indx <= 0) { printf ("indx=%d section=%s flags=%08x name=%s\n", indx, osec->name, osec->flags, h->root.root.string); }#endif } outrel.r_info = ELF32_R_INFO (indx, r_type); outrel.r_addend = relocation + rel->r_addend; } } bfd_elf32_swap_reloca_out (output_bfd, &outrel, (((Elf32_External_Rela *) sreloc->contents) + sreloc->reloc_count)); ++sreloc->reloc_count; /* This reloc will be computed at runtime, so there's no need to do anything now, unless this is a RELATIVE reloc in an unallocated section. */ if (skip || (input_section->flags & SEC_ALLOC) != 0 || ELF32_R_TYPE (outrel.r_info) != R_I370_RELATIVE) continue; } break; case (int)R_I370_COPY: case (int)R_I370_RELATIVE: (*_bfd_error_handler) ("%s: Relocation %s is not yet supported for symbol %s.", bfd_get_filename (input_bfd), i370_elf_howto_table[ (int)r_type ]->name, sym_name); bfd_set_error (bfd_error_invalid_operation); ret = false; continue; }#ifdef DEBUG fprintf (stderr, "\ttype = %s (%d), name = %s, symbol index = %ld, offset = %ld, addend = %ld\n", howto->name, (int)r_type, sym_name, r_symndx, (long)offset, (long)addend);#endif r = _bfd_final_link_relocate (howto, input_bfd, input_section, contents, offset, relocation, addend); if (r != bfd_reloc_ok) { ret = false; switch (r) { default: break; case bfd_reloc_overflow: { const char *name; if (h != NULL) name = h->root.root.string; else { name = bfd_elf_string_from_elf_section (input_bfd, symtab_hdr->sh_link, sym->st_name); if (name == NULL) break; if (*name == '\0') name = bfd_section_name (input_bfd, sec); } (*info->callbacks->reloc_overflow) (info, name, howto->name, (bfd_vma) 0, input_bfd, input_section, offset); } break; } } }#ifdef DEBUG fprintf (stderr, "\n");#endif return ret;}static voidi370_elf_post_process_headers (abfd, link_info) bfd * abfd; struct bfd_link_info * link_info ATTRIBUTE_UNUSED;{ Elf_Internal_Ehdr * i_ehdrp; /* Elf file header, internal form */ i_ehdrp = elf_elfheader (abfd); i_ehdrp->e_ident[EI_OSABI] = ELFOSABI_LINUX;}#define TARGET_BIG_SYM bfd_elf32_i370_vec#define TARGET_BIG_NAME "elf32-i370"#define ELF_ARCH bfd_arch_i370#define ELF_MACHINE_CODE EM_S370#ifdef EM_I370_OLD#define ELF_MACHINE_ALT1 EM_I370_OLD#endif#define ELF_MAXPAGESIZE 0x1000#define elf_info_to_howto i370_elf_info_to_howto#define elf_backend_plt_not_loaded 1#define elf_backend_got_symbol_offset 4#define bfd_elf32_bfd_reloc_type_lookup i370_elf_reloc_type_lookup#define bfd_elf32_bfd_set_private_flags i370_elf_set_private_flags#define bfd_elf32_bfd_copy_private_bfd_data i370_elf_copy_private_bfd_data#define bfd_elf32_bfd_merge_private_bfd_data i370_elf_merge_private_bfd_data#define elf_backend_relocate_section i370_elf_relocate_section/* dynamic loader support is mostly broken; just enough here to be able to * link glibc's ld.so without errors. */#define elf_backend_create_dynamic_sections i370_elf_create_dynamic_sections#define elf_backend_size_dynamic_sections i370_elf_size_dynamic_sections#define elf_backend_finish_dynamic_sections i370_elf_finish_dynamic_sections#define elf_backend_fake_sections i370_elf_fake_sections#define elf_backend_section_from_shdr i370_elf_section_from_shdr#define elf_backend_adjust_dynamic_symbol i370_elf_adjust_dynamic_symbol#define elf_backend_check_relocs i370_elf_check_relocs/*#define elf_backend_add_symbol_hook i370_elf_add_symbol_hook#define elf_backend_finish_dynamic_symbol i370_elf_finish_dynamic_symbol#define elf_backend_additional_program_headers i370_elf_additional_program_headers#define elf_backend_modify_segment_map i370_elf_modify_segment_map*/#define elf_backend_post_process_headers i370_elf_post_process_headersint i370_noop(){ return 1;}/* we need to define these at least as no-ops to link glibc ld.so */#define elf_backend_add_symbol_hook \ (boolean (*) PARAMS ((bfd *, struct bfd_link_info *, \ const Elf_Internal_Sym *, const char **, flagword *, \ asection **, bfd_vma *))) i370_noop#define elf_backend_finish_dynamic_symbol \ (boolean (*) PARAMS ((bfd *, struct bfd_link_info *, \ struct elf_link_hash_entry *, \ Elf_Internal_Sym *))) i370_noop#define elf_backend_additional_program_headers \ (int (*) PARAMS ((bfd *))) i370_noop#define elf_backend_modify_segment_map \ (boolean (*) PARAMS ((bfd *))) i370_noop#include "elf32-target.h"
⌨️ 快捷键说明
复制代码Ctrl + C
搜索代码Ctrl + F
全屏模式F11
增大字号Ctrl + =
减小字号Ctrl + -
显示快捷键?