coffcode.h
来自「基于4个mips核的noc设计」· C头文件 代码 · 共 2,097 行 · 第 1/5 页
H
2,097 行
styp_flags = STYP_DEBUG_INFO; }#endif#ifdef RS6000COFF_C else if (!strcmp (sec_name, _PAD)) { styp_flags = STYP_PAD; } else if (!strcmp (sec_name, _LOADER)) { styp_flags = STYP_LOADER; }#endif /* Try and figure out what it should be */ else if (sec_flags & SEC_CODE) { styp_flags = STYP_TEXT; } else if (sec_flags & SEC_DATA) { styp_flags = STYP_DATA; } else if (sec_flags & SEC_READONLY) {#ifdef STYP_LIT /* 29k readonly text/data section */ styp_flags = STYP_LIT;#else styp_flags = STYP_TEXT;#endif /* STYP_LIT */ } else if (sec_flags & SEC_LOAD) { styp_flags = STYP_TEXT; } else if (sec_flags & SEC_ALLOC) { styp_flags = STYP_BSS; }#ifdef STYP_CLINK if (sec_flags & SEC_CLINK) styp_flags |= STYP_CLINK;#endif#ifdef STYP_BLOCK if (sec_flags & SEC_BLOCK) styp_flags |= STYP_BLOCK;#endif#ifdef STYP_NOLOAD if ((sec_flags & (SEC_NEVER_LOAD | SEC_COFF_SHARED_LIBRARY)) != 0) styp_flags |= STYP_NOLOAD;#endif return styp_flags;}#else /* COFF_WITH_PE *//* The PE version; see above for the general comments. The non-PE case seems to be more guessing, and breaks PE format; specifically, .rdata is readonly, but it sure ain't text. Really, all this should be set up properly in gas (or whatever assembler is in use), and honor whatever objcopy/strip, etc. sent us as input. */static longsec_to_styp_flags (sec_name, sec_flags) const char *sec_name ATTRIBUTE_UNUSED; flagword sec_flags;{ long styp_flags = 0; /* caution: there are at least three groups of symbols that have very similar bits and meanings: IMAGE_SCN*, SEC_*, and STYP_*. SEC_* are the BFD internal flags, used for generic BFD information. STYP_* are the COFF section flags which appear in COFF files. IMAGE_SCN_* are the PE section flags which appear in PE files. The STYP_* flags and the IMAGE_SCN_* flags overlap, but there are more IMAGE_SCN_* flags. */ /* skip LOAD */ /* READONLY later */ /* skip RELOC */ if ((sec_flags & SEC_CODE) != 0) styp_flags |= IMAGE_SCN_CNT_CODE; if ((sec_flags & SEC_DATA) != 0) styp_flags |= IMAGE_SCN_CNT_INITIALIZED_DATA; if ((sec_flags & SEC_ALLOC) != 0 && (sec_flags & SEC_LOAD) == 0) styp_flags |= IMAGE_SCN_CNT_UNINITIALIZED_DATA; /* ==STYP_BSS */ /* skip ROM */ /* skip CONSTRUCTOR */ /* skip CONTENTS */#ifdef STYP_NOLOAD if ((sec_flags & (SEC_NEVER_LOAD | SEC_COFF_SHARED_LIBRARY)) != 0) styp_flags |= STYP_NOLOAD;#endif if ((sec_flags & SEC_IS_COMMON) != 0) styp_flags |= IMAGE_SCN_LNK_COMDAT; if ((sec_flags & SEC_DEBUGGING) != 0) styp_flags |= IMAGE_SCN_MEM_DISCARDABLE; if ((sec_flags & SEC_EXCLUDE) != 0) styp_flags |= IMAGE_SCN_LNK_REMOVE; if ((sec_flags & SEC_NEVER_LOAD) != 0) styp_flags |= IMAGE_SCN_LNK_REMOVE; /* skip IN_MEMORY */ /* skip SORT */ if (sec_flags & SEC_LINK_ONCE) styp_flags |= IMAGE_SCN_LNK_COMDAT; /* skip LINK_DUPLICATES */ /* skip LINKER_CREATED */ /* For now, the read/write bits are mapped onto SEC_READONLY, even though the semantics don't quite match. The bits from the input are retained in pei_section_data(abfd, section)->pe_flags */ styp_flags |= IMAGE_SCN_MEM_READ; /* always readable. */ if ((sec_flags & SEC_READONLY) == 0) styp_flags |= IMAGE_SCN_MEM_WRITE; /* Invert READONLY for write */ if (sec_flags & SEC_CODE) styp_flags |= IMAGE_SCN_MEM_EXECUTE; /* CODE->EXECUTE */ if (sec_flags & SEC_SHARED) styp_flags |= IMAGE_SCN_MEM_SHARED; /* Shared remains meaningful */ return styp_flags;}#endif /* COFF_WITH_PE *//* Return a word with SEC_* flags set to represent the incoming STYP_* flags (from scnhdr.s_flags). The inverse of this function is sec_to_styp_flags(). NOTE: If you add to/change this routine, you should probably mirror the changes in sec_to_styp_flags(). */#ifndef COFF_WITH_PEstatic flagwordstyp_to_sec_flags (abfd, hdr, name, section) bfd *abfd ATTRIBUTE_UNUSED; PTR hdr; const char *name; asection *section ATTRIBUTE_UNUSED;{ struct internal_scnhdr *internal_s = (struct internal_scnhdr *) hdr; long styp_flags = internal_s->s_flags; flagword sec_flags = 0;#ifdef STYP_BLOCK if (styp_flags & STYP_BLOCK) sec_flags |= SEC_BLOCK;#endif#ifdef STYP_CLINK if (styp_flags & STYP_CLINK) sec_flags |= SEC_CLINK;#endif#ifdef STYP_NOLOAD if (styp_flags & STYP_NOLOAD) { sec_flags |= SEC_NEVER_LOAD; }#endif /* STYP_NOLOAD */ /* For 386 COFF, at least, an unloadable text or data section is actually a shared library section. */ if (styp_flags & STYP_TEXT) { if (sec_flags & SEC_NEVER_LOAD) sec_flags |= SEC_CODE | SEC_COFF_SHARED_LIBRARY; else sec_flags |= SEC_CODE | SEC_LOAD | SEC_ALLOC; } else if (styp_flags & STYP_DATA) { if (sec_flags & SEC_NEVER_LOAD) sec_flags |= SEC_DATA | SEC_COFF_SHARED_LIBRARY; else sec_flags |= SEC_DATA | SEC_LOAD | SEC_ALLOC; } else if (styp_flags & STYP_BSS) {#ifdef BSS_NOLOAD_IS_SHARED_LIBRARY if (sec_flags & SEC_NEVER_LOAD) sec_flags |= SEC_ALLOC | SEC_COFF_SHARED_LIBRARY; else#endif sec_flags |= SEC_ALLOC; } else if (styp_flags & STYP_INFO) { /* We mark these as SEC_DEBUGGING, but only if COFF_PAGE_SIZE is defined. coff_compute_section_file_positions uses COFF_PAGE_SIZE to ensure that the low order bits of the section VMA and the file offset match. If we don't know COFF_PAGE_SIZE, we can't ensure the correct correspondence, and demand page loading of the file will fail. */#if defined (COFF_PAGE_SIZE) && !defined (COFF_ALIGN_IN_S_FLAGS) sec_flags |= SEC_DEBUGGING;#endif } else if (styp_flags & STYP_PAD) { sec_flags = 0; } else if (strcmp (name, _TEXT) == 0) { if (sec_flags & SEC_NEVER_LOAD) sec_flags |= SEC_CODE | SEC_COFF_SHARED_LIBRARY; else sec_flags |= SEC_CODE | SEC_LOAD | SEC_ALLOC; } else if (strcmp (name, _DATA) == 0) { if (sec_flags & SEC_NEVER_LOAD) sec_flags |= SEC_DATA | SEC_COFF_SHARED_LIBRARY; else sec_flags |= SEC_DATA | SEC_LOAD | SEC_ALLOC; } else if (strcmp (name, _BSS) == 0) {#ifdef BSS_NOLOAD_IS_SHARED_LIBRARY if (sec_flags & SEC_NEVER_LOAD) sec_flags |= SEC_ALLOC | SEC_COFF_SHARED_LIBRARY; else#endif sec_flags |= SEC_ALLOC; } else if (strncmp (name, ".debug", 6) == 0#ifdef _COMMENT || strcmp (name, _COMMENT) == 0#endif#ifdef COFF_LONG_SECTION_NAMES || strncmp (name, ".gnu.linkonce.wi.", 17) == 0#endif || strncmp (name, ".stab", 5) == 0) {#ifdef COFF_PAGE_SIZE sec_flags |= SEC_DEBUGGING;#endif }#ifdef _LIB else if (strcmp (name, _LIB) == 0) ;#endif#ifdef _LIT else if (strcmp (name, _LIT) == 0) { sec_flags = SEC_LOAD | SEC_ALLOC | SEC_READONLY; }#endif else { sec_flags |= SEC_ALLOC | SEC_LOAD; }#ifdef STYP_LIT /* A29k readonly text/data section type */ if ((styp_flags & STYP_LIT) == STYP_LIT) { sec_flags = (SEC_LOAD | SEC_ALLOC | SEC_READONLY); }#endif /* STYP_LIT */#ifdef STYP_OTHER_LOAD /* Other loaded sections */ if (styp_flags & STYP_OTHER_LOAD) { sec_flags = (SEC_LOAD | SEC_ALLOC); }#endif /* STYP_SDATA */#if defined (COFF_LONG_SECTION_NAMES) && defined (COFF_SUPPORT_GNU_LINKONCE) /* As a GNU extension, if the name begins with .gnu.linkonce, we only link a single copy of the section. This is used to support g++. g++ will emit each template expansion in its own section. The symbols will be defined as weak, so that multiple definitions are permitted. The GNU linker extension is to actually discard all but one of the sections. */ if (strncmp (name, ".gnu.linkonce", sizeof ".gnu.linkonce" - 1) == 0) sec_flags |= SEC_LINK_ONCE | SEC_LINK_DUPLICATES_DISCARD;#endif return sec_flags;}#else /* COFF_WITH_PE */static flagwordhandle_COMDAT (abfd, sec_flags, hdr, name, section) bfd * abfd; flagword sec_flags; PTR hdr; const char *name; asection *section;{ struct internal_scnhdr *internal_s = (struct internal_scnhdr *) hdr; bfd_byte *esymstart, *esym, *esymend; int seen_state = 0; char *target_name = NULL; sec_flags |= SEC_LINK_ONCE; /* Unfortunately, the PE format stores essential information in the symbol table, of all places. We need to extract that information now, so that objdump and the linker will know how to handle the section without worrying about the symbols. We can't call slurp_symtab, because the linker doesn't want the swapped symbols. */ /* COMDAT sections are special. The first symbol is the section symbol, which tells what kind of COMDAT section it is. The second symbol is the "comdat symbol" - the one with the unique name. GNU uses the section symbol for the unique name; MS uses ".text" for every comdat section. Sigh. - DJ */ /* This is not mirrored in sec_to_styp_flags(), but there doesn't seem to be a need to, either, and it would at best be rather messy. */ if (! _bfd_coff_get_external_symbols (abfd)) return sec_flags; esymstart = esym = (bfd_byte *) obj_coff_external_syms (abfd); esymend = esym + obj_raw_syment_count (abfd) * bfd_coff_symesz (abfd); while (esym < esymend) { struct internal_syment isym; char buf[SYMNMLEN + 1]; const char *symname; bfd_coff_swap_sym_in (abfd, (PTR) esym, (PTR) &isym); if (sizeof (internal_s->s_name) > SYMNMLEN) { /* This case implies that the matching symbol name will be in the string table. */ abort (); } if (isym.n_scnum == section->target_index) { /* According to the MSVC documentation, the first TWO entries with the section # are both of interest to us. The first one is the "section symbol" (section name). The second is the comdat symbol name. Here, we've found the first qualifying entry; we distinguish it from the second with a state flag. In the case of gas-generated (at least until that is fixed) .o files, it isn't necessarily the second one. It may be some other later symbol. Since gas also doesn't follow MS conventions and emits the section similar to .text$<name>, where <something> is the name we're looking for, we distinguish the two as follows: If the section name is simply a section name (no $) we presume it's MS-generated, and look at precisely the second symbol for the comdat name. If the section name has a $, we assume it's gas-generated, and look for <something> (whatever follows the $) as the comdat symbol. */ /* All 3 branches use this */ symname = _bfd_coff_internal_syment_name (abfd, &isym, buf); if (symname == NULL) abort (); switch (seen_state) { case 0: { /* The first time we've seen the symbol. */ union internal_auxent aux; seen_state = 1; /* If it isn't the stuff we're expecting, die; The MS documentation is vague, but it appears that the second entry serves BOTH as the comdat symbol and the defining symbol record (either C_STAT or C_EXT, possibly with an aux entry with debug information if it's a function.) It appears the only way to find the second one is to count. (On Intel, they appear to be adjacent, but on Alpha, they have been found separated.) Here, we think we've found the first one, but there's some checking we can do to be sure. */ if (! (isym.n_sclass == C_STAT && isym.n_type == T_NULL && isym.n_value == 0)) abort (); /* FIXME LATER: MSVC generates section names like .text for comdats. Gas generates names like .text$foo__Fv (in the case of a function). See comment above for more. */ if (strcmp (name, symname) != 0) abort (); /* This is the section symbol. */ bfd_coff_swap_aux_in (abfd, (PTR) (esym + bfd_coff_symesz (abfd)), isym.n_type, isym.n_sclass, 0, isym.n_numaux, (PTR) &aux); target_name = strchr (name, '$'); if (target_name != NULL) { /* Gas mode. */ seen_state = 2; /* Skip the `$'. */ target_name += 1; }
⌨️ 快捷键说明
复制代码Ctrl + C
搜索代码Ctrl + F
全屏模式F11
增大字号Ctrl + =
减小字号Ctrl + -
显示快捷键?