elf64-alpha.c
来自「基于4个mips核的noc设计」· C语言 代码 · 共 2,160 行 · 第 1/5 页
C
2,160 行
char *name;{ asection *newsect; /* There ought to be a place to keep ELF backend specific flags, but at the moment there isn't one. We just keep track of the sections by their name, instead. Fortunately, the ABI gives suggested names for all the MIPS specific sections, so we will probably get away with this. */ switch (hdr->sh_type) { case SHT_ALPHA_DEBUG: if (strcmp (name, ".mdebug") != 0) return false; break;#ifdef ERIC_neverdef case SHT_ALPHA_REGINFO: if (strcmp (name, ".reginfo") != 0 || hdr->sh_size != sizeof (Elf64_External_RegInfo)) return false; break;#endif default: return false; } if (! _bfd_elf_make_section_from_shdr (abfd, hdr, name)) return false; newsect = hdr->bfd_section; if (hdr->sh_type == SHT_ALPHA_DEBUG) { if (! bfd_set_section_flags (abfd, newsect, (bfd_get_section_flags (abfd, newsect) | SEC_DEBUGGING))) return false; }#ifdef ERIC_neverdef /* For a .reginfo section, set the gp value in the tdata information from the contents of this section. We need the gp value while processing relocs, so we just get it now. */ if (hdr->sh_type == SHT_ALPHA_REGINFO) { Elf64_External_RegInfo ext; Elf64_RegInfo s; if (! bfd_get_section_contents (abfd, newsect, (PTR) &ext, (file_ptr) 0, sizeof ext)) return false; bfd_alpha_elf64_swap_reginfo_in (abfd, &ext, &s); elf_gp (abfd) = s.ri_gp_value; }#endif return true;}/* Set the correct type for an Alpha ELF section. We do this by the section name, which is a hack, but ought to work. */static booleanelf64_alpha_fake_sections (abfd, hdr, sec) bfd *abfd; Elf64_Internal_Shdr *hdr; asection *sec;{ register const char *name; name = bfd_get_section_name (abfd, sec); if (strcmp (name, ".mdebug") == 0) { hdr->sh_type = SHT_ALPHA_DEBUG; /* In a shared object on Irix 5.3, the .mdebug section has an entsize of 0. FIXME: Does this matter? */ if ((abfd->flags & DYNAMIC) != 0 ) hdr->sh_entsize = 0; else hdr->sh_entsize = 1; }#ifdef ERIC_neverdef else if (strcmp (name, ".reginfo") == 0) { hdr->sh_type = SHT_ALPHA_REGINFO; /* In a shared object on Irix 5.3, the .reginfo section has an entsize of 0x18. FIXME: Does this matter? */ if ((abfd->flags & DYNAMIC) != 0) hdr->sh_entsize = sizeof (Elf64_External_RegInfo); else hdr->sh_entsize = 1; /* Force the section size to the correct value, even if the linker thinks it is larger. The link routine below will only write out this much data for .reginfo. */ hdr->sh_size = sec->_raw_size = sizeof (Elf64_External_RegInfo); } else if (strcmp (name, ".hash") == 0 || strcmp (name, ".dynamic") == 0 || strcmp (name, ".dynstr") == 0) { hdr->sh_entsize = 0; hdr->sh_info = SIZEOF_ALPHA_DYNSYM_SECNAMES; }#endif else if (strcmp (name, ".sdata") == 0 || strcmp (name, ".sbss") == 0 || strcmp (name, ".lit4") == 0 || strcmp (name, ".lit8") == 0) hdr->sh_flags |= SHF_ALPHA_GPREL; return true;}/* Hook called by the linker routine which adds symbols from an object file. We use it to put .comm items in .sbss, and not .bss. */static booleanelf64_alpha_add_symbol_hook (abfd, info, sym, namep, flagsp, secp, valp) bfd *abfd; struct bfd_link_info *info; const Elf_Internal_Sym *sym; const char **namep ATTRIBUTE_UNUSED; flagword *flagsp ATTRIBUTE_UNUSED; asection **secp; bfd_vma *valp;{ if (sym->st_shndx == SHN_COMMON && !info->relocateable && sym->st_size <= bfd_get_gp_size (abfd)) { /* Common symbols less than or equal to -G nn bytes are automatically put into .sbss. */ asection *scomm = bfd_get_section_by_name (abfd, ".scommon"); if (scomm == NULL) { scomm = bfd_make_section (abfd, ".scommon"); if (scomm == NULL || !bfd_set_section_flags (abfd, scomm, (SEC_ALLOC | SEC_IS_COMMON | SEC_LINKER_CREATED))) return false; } *secp = scomm; *valp = sym->st_size; } return true;}/* Create the .got section. */static booleanelf64_alpha_create_got_section(abfd, info) bfd *abfd; struct bfd_link_info *info ATTRIBUTE_UNUSED;{ asection *s; if (bfd_get_section_by_name (abfd, ".got")) return true; s = bfd_make_section (abfd, ".got"); if (s == NULL || !bfd_set_section_flags (abfd, s, (SEC_ALLOC | SEC_LOAD | SEC_HAS_CONTENTS | SEC_IN_MEMORY | SEC_LINKER_CREATED)) || !bfd_set_section_alignment (abfd, s, 3)) return false; alpha_elf_tdata (abfd)->got = s; return true;}/* Create all the dynamic sections. */static booleanelf64_alpha_create_dynamic_sections (abfd, info) bfd *abfd; struct bfd_link_info *info;{ asection *s; struct elf_link_hash_entry *h; /* We need to create .plt, .rela.plt, .got, and .rela.got sections. */ s = bfd_make_section (abfd, ".plt"); if (s == NULL || ! bfd_set_section_flags (abfd, s, (SEC_ALLOC | SEC_LOAD | SEC_HAS_CONTENTS | SEC_IN_MEMORY | SEC_LINKER_CREATED | SEC_CODE)) || ! bfd_set_section_alignment (abfd, s, 3)) return false; /* Define the symbol _PROCEDURE_LINKAGE_TABLE_ at the start of the .plt section. */ h = NULL; if (! (_bfd_generic_link_add_one_symbol (info, abfd, "_PROCEDURE_LINKAGE_TABLE_", BSF_GLOBAL, s, (bfd_vma) 0, (const char *) NULL, false, get_elf_backend_data (abfd)->collect, (struct bfd_link_hash_entry **) &h))) return false; h->elf_link_hash_flags |= ELF_LINK_HASH_DEF_REGULAR; h->type = STT_OBJECT; if (info->shared && ! _bfd_elf_link_record_dynamic_symbol (info, h)) return false; s = bfd_make_section (abfd, ".rela.plt"); if (s == NULL || !bfd_set_section_flags (abfd, s, (SEC_ALLOC | SEC_LOAD | SEC_HAS_CONTENTS | SEC_IN_MEMORY | SEC_LINKER_CREATED | SEC_READONLY)) || ! bfd_set_section_alignment (abfd, s, 3)) return false; /* We may or may not have created a .got section for this object, but we definitely havn't done the rest of the work. */ if (!elf64_alpha_create_got_section (abfd, info)) return false; s = bfd_make_section(abfd, ".rela.got"); if (s == NULL || !bfd_set_section_flags (abfd, s, (SEC_ALLOC | SEC_LOAD | SEC_HAS_CONTENTS | SEC_IN_MEMORY | SEC_LINKER_CREATED | SEC_READONLY)) || !bfd_set_section_alignment (abfd, s, 3)) return false; /* Define the symbol _GLOBAL_OFFSET_TABLE_ at the start of the dynobj's .got section. We don't do this in the linker script because we don't want to define the symbol if we are not creating a global offset table. */ h = NULL; if (!(_bfd_generic_link_add_one_symbol (info, abfd, "_GLOBAL_OFFSET_TABLE_", BSF_GLOBAL, alpha_elf_tdata(abfd)->got, (bfd_vma) 0, (const char *) NULL, false, get_elf_backend_data (abfd)->collect, (struct bfd_link_hash_entry **) &h))) return false; h->elf_link_hash_flags |= ELF_LINK_HASH_DEF_REGULAR; h->type = STT_OBJECT; if (info->shared && ! _bfd_elf_link_record_dynamic_symbol (info, h)) return false; elf_hash_table (info)->hgot = h; return true;}/* Read ECOFF debugging information from a .mdebug section into a ecoff_debug_info structure. */static booleanelf64_alpha_read_ecoff_info (abfd, section, debug) bfd *abfd; asection *section; struct ecoff_debug_info *debug;{ HDRR *symhdr; const struct ecoff_debug_swap *swap; char *ext_hdr = NULL; swap = get_elf_backend_data (abfd)->elf_backend_ecoff_debug_swap; memset (debug, 0, sizeof (*debug)); ext_hdr = (char *) bfd_malloc ((size_t) swap->external_hdr_size); if (ext_hdr == NULL && swap->external_hdr_size != 0) goto error_return; if (bfd_get_section_contents (abfd, section, ext_hdr, (file_ptr) 0, swap->external_hdr_size) == false) goto error_return; symhdr = &debug->symbolic_header; (*swap->swap_hdr_in) (abfd, ext_hdr, symhdr); /* The symbolic header contains absolute file offsets and sizes to read. */#define READ(ptr, offset, count, size, type) \ if (symhdr->count == 0) \ debug->ptr = NULL; \ else \ { \ debug->ptr = (type) bfd_malloc ((size_t) (size * symhdr->count)); \ if (debug->ptr == NULL) \ goto error_return; \ if (bfd_seek (abfd, (file_ptr) symhdr->offset, SEEK_SET) != 0 \ || (bfd_read (debug->ptr, size, symhdr->count, \ abfd) != size * symhdr->count)) \ goto error_return; \ } READ (line, cbLineOffset, cbLine, sizeof (unsigned char), unsigned char *); READ (external_dnr, cbDnOffset, idnMax, swap->external_dnr_size, PTR); READ (external_pdr, cbPdOffset, ipdMax, swap->external_pdr_size, PTR); READ (external_sym, cbSymOffset, isymMax, swap->external_sym_size, PTR); READ (external_opt, cbOptOffset, ioptMax, swap->external_opt_size, PTR); READ (external_aux, cbAuxOffset, iauxMax, sizeof (union aux_ext), union aux_ext *); READ (ss, cbSsOffset, issMax, sizeof (char), char *); READ (ssext, cbSsExtOffset, issExtMax, sizeof (char), char *); READ (external_fdr, cbFdOffset, ifdMax, swap->external_fdr_size, PTR); READ (external_rfd, cbRfdOffset, crfd, swap->external_rfd_size, PTR); READ (external_ext, cbExtOffset, iextMax, swap->external_ext_size, PTR);#undef READ debug->fdr = NULL; debug->adjust = NULL; return true; error_return: if (ext_hdr != NULL) free (ext_hdr); if (debug->line != NULL) free (debug->line); if (debug->external_dnr != NULL) free (debug->external_dnr); if (debug->external_pdr != NULL) free (debug->external_pdr); if (debug->external_sym != NULL) free (debug->external_sym); if (debug->external_opt != NULL) free (debug->external_opt); if (debug->external_aux != NULL) free (debug->external_aux); if (debug->ss != NULL) free (debug->ss); if (debug->ssext != NULL) free (debug->ssext); if (debug->external_fdr != NULL) free (debug->external_fdr); if (debug->external_rfd != NULL) free (debug->external_rfd); if (debug->external_ext != NULL) free (debug->external_ext); return false;}/* Alpha ELF local labels start with '$'. */static booleanelf64_alpha_is_local_label_name (abfd, name) bfd *abfd ATTRIBUTE_UNUSED; const char *name;{ return name[0] == '$';}/* Alpha ELF follows MIPS ELF in using a special find_nearest_line routine in order to handle the ECOFF debugging information. We still call this mips_elf_find_line because of the slot find_line_info in elf_obj_tdata is declared that way. */struct mips_elf_find_line{ struct ecoff_debug_info d; struct ecoff_find_line i;};static booleanelf64_alpha_find_nearest_line (abfd, section, symbols, offset, filename_ptr, functionname_ptr, line_ptr) bfd *abfd; asection *section; asymbol **symbols; bfd_vma offset; const char **filename_ptr; const char **functionname_ptr; unsigned int *line_ptr;{ asection *msec; if (_bfd_dwarf2_find_nearest_line (abfd, section, symbols, offset, filename_ptr, functionname_ptr, line_ptr, 0, &elf_tdata (abfd)->dwarf2_find_line_info)) return true; msec = bfd_get_section_by_name (abfd, ".mdebug"); if (msec != NULL) { flagword origflags; struct mips_elf_find_line *fi; const struct ecoff_debug_swap * const swap = get_elf_backend_data (abfd)->elf_backend_ecoff_debug_swap; /* If we are called during a link, alpha_elf_final_link may have cleared the SEC_HAS_CONTENTS field. We force it back on here if appropriate (which it normally will be). */ origflags = msec->flags; if (elf_section_data (msec)->this_hdr.sh_type != SHT_NOBITS) msec->flags |= SEC_HAS_CONTENTS; fi = elf_tdata (abfd)->find_line_info; if (fi == NULL) { bfd_size_type external_fdr_size; char *fraw_src; char *fraw_end; struct fdr *fdr_ptr; fi = ((struct mips_elf_find_line *) bfd_zalloc (abfd, sizeof (struct mips_elf_find_line))); if (fi == NULL) { msec->flags = origflags; return false; } if (!elf64_alpha_read_ecoff_info (abfd, msec, &fi->d)) { msec->flags = origflags; return
⌨️ 快捷键说明
复制代码Ctrl + C
搜索代码Ctrl + F
全屏模式F11
增大字号Ctrl + =
减小字号Ctrl + -
显示快捷键?