📄 write.c
字号:
remove_subsegs (head, seg, root, last) frchainS *head; int seg; fragS **root; fragS **last;{ *root = head->frch_root; *last = chain_frchains_together_1 (seg, head);}#endif /* BFD */#if defined (BFD_ASSEMBLER) || !defined (BFD)#ifdef BFD_ASSEMBLERstatic voidcvt_frag_to_fill (sec, fragP) segT sec ATTRIBUTE_UNUSED; fragS *fragP;#elsestatic voidcvt_frag_to_fill (headersP, sec, fragP) object_headers *headersP; segT sec; fragS *fragP;#endif{ switch (fragP->fr_type) { case rs_align: case rs_align_code: case rs_align_test: case rs_org: case rs_space:#ifdef HANDLE_ALIGN HANDLE_ALIGN (fragP);#endif know (fragP->fr_next != NULL); fragP->fr_offset = (fragP->fr_next->fr_address - fragP->fr_address - fragP->fr_fix) / fragP->fr_var; if (fragP->fr_offset < 0) { as_bad_where (fragP->fr_file, fragP->fr_line, _("attempt to .org/.space backwards? (%ld)"), (long) fragP->fr_offset); } fragP->fr_type = rs_fill; break; case rs_fill: break; case rs_leb128: { valueT value = S_GET_VALUE (fragP->fr_symbol); int size; size = output_leb128 (fragP->fr_literal + fragP->fr_fix, value, fragP->fr_subtype); fragP->fr_fix += size; fragP->fr_type = rs_fill; fragP->fr_var = 0; fragP->fr_offset = 0; fragP->fr_symbol = NULL; } break; case rs_cfa: eh_frame_convert_frag (fragP); break; case rs_dwarf2dbg: dwarf2dbg_convert_frag (fragP); break; case rs_machine_dependent:#ifdef BFD_ASSEMBLER md_convert_frag (stdoutput, sec, fragP);#else md_convert_frag (headersP, sec, fragP);#endif assert (fragP->fr_next == NULL || ((offsetT) (fragP->fr_next->fr_address - fragP->fr_address) == fragP->fr_fix)); /* After md_convert_frag, we make the frag into a ".space 0". md_convert_frag() should set up any fixSs and constants required. */ frag_wane (fragP); break;#ifndef WORKING_DOT_WORD case rs_broken_word: { struct broken_word *lie; if (fragP->fr_subtype) { fragP->fr_fix += md_short_jump_size; for (lie = (struct broken_word *) (fragP->fr_symbol); lie && lie->dispfrag == fragP; lie = lie->next_broken_word) if (lie->added == 1) fragP->fr_fix += md_long_jump_size; } frag_wane (fragP); } break;#endif default: BAD_CASE (fragP->fr_type); break; }}#endif /* defined (BFD_ASSEMBLER) || !defined (BFD) */#ifdef BFD_ASSEMBLERstatic voidrelax_seg (abfd, sec, do_code) bfd *abfd; asection *sec; PTR do_code;{ flagword flags = bfd_get_section_flags (abfd, sec); segment_info_type *seginfo = seg_info (sec); if (!(flags & SEC_CODE) == !do_code && seginfo && seginfo->frchainP) relax_segment (seginfo->frchainP->frch_root, sec);}static voidsize_seg (abfd, sec, xxx) bfd *abfd; asection *sec; PTR xxx ATTRIBUTE_UNUSED;{ flagword flags; fragS *fragp; segment_info_type *seginfo; int x; valueT size, newsize; subseg_change (sec, 0); seginfo = seg_info (sec); if (seginfo && seginfo->frchainP) { for (fragp = seginfo->frchainP->frch_root; fragp; fragp = fragp->fr_next) cvt_frag_to_fill (sec, fragp); for (fragp = seginfo->frchainP->frch_root; fragp->fr_next; fragp = fragp->fr_next) /* Walk to last elt. */ ; size = fragp->fr_address + fragp->fr_fix; } else size = 0; flags = bfd_get_section_flags (abfd, sec); if (size > 0 && ! seginfo->bss) flags |= SEC_HAS_CONTENTS; /* @@ This is just an approximation. */ if (seginfo && seginfo->fix_root) flags |= SEC_RELOC; else flags &= ~SEC_RELOC; x = bfd_set_section_flags (abfd, sec, flags); assert (x == true); newsize = md_section_align (sec, size); x = bfd_set_section_size (abfd, sec, newsize); assert (x == true); /* If the size had to be rounded up, add some padding in the last non-empty frag. */ assert (newsize >= size); if (size != newsize) { fragS *last = seginfo->frchainP->frch_last; fragp = seginfo->frchainP->frch_root; while (fragp->fr_next != last) fragp = fragp->fr_next; last->fr_address = size; fragp->fr_offset += newsize - size; }#ifdef tc_frob_section tc_frob_section (sec);#endif#ifdef obj_frob_section obj_frob_section (sec);#endif}#ifdef DEBUG2static voiddump_section_relocs (abfd, sec, stream_) bfd *abfd ATTRIBUTE_UNUSED; asection *sec; char *stream_;{ FILE *stream = (FILE *) stream_; segment_info_type *seginfo = seg_info (sec); fixS *fixp = seginfo->fix_root; if (!fixp) return; fprintf (stream, "sec %s relocs:\n", sec->name); while (fixp) { symbolS *s = fixp->fx_addsy; fprintf (stream, " %08lx: type %d ", (unsigned long) fixp, (int) fixp->fx_r_type); if (s == NULL) fprintf (stream, "no sym\n"); else { print_symbol_value_1 (stream, s); fprintf (stream, "\n"); } fixp = fixp->fx_next; }}#else#define dump_section_relocs(ABFD,SEC,STREAM) ((void) 0)#endif#ifndef EMIT_SECTION_SYMBOLS#define EMIT_SECTION_SYMBOLS 1#endifstatic voidadjust_reloc_syms (abfd, sec, xxx) bfd *abfd ATTRIBUTE_UNUSED; asection *sec; PTR xxx ATTRIBUTE_UNUSED;{ segment_info_type *seginfo = seg_info (sec); fixS *fixp; if (seginfo == NULL) return; dump_section_relocs (abfd, sec, stderr); for (fixp = seginfo->fix_root; fixp; fixp = fixp->fx_next) if (fixp->fx_done) /* Ignore it. */ ; else if (fixp->fx_addsy) { symbolS *sym; asection *symsec;#ifdef DEBUG5 fprintf (stderr, "\n\nadjusting fixup:\n"); print_fixup (fixp);#endif sym = fixp->fx_addsy; /* All symbols should have already been resolved at this point. It is possible to see unresolved expression symbols, though, since they are not in the regular symbol table. */ if (sym != NULL) resolve_symbol_value (sym, 1); if (fixp->fx_subsy != NULL) resolve_symbol_value (fixp->fx_subsy, 1); /* If this symbol is equated to an undefined symbol, convert the fixup to being against that symbol. */ if (sym != NULL && symbol_equated_p (sym) && (! S_IS_DEFINED (sym) || S_IS_COMMON (sym))) { fixp->fx_offset += symbol_get_value_expression (sym)->X_add_number; sym = symbol_get_value_expression (sym)->X_add_symbol; fixp->fx_addsy = sym; } if (sym != NULL && symbol_mri_common_p (sym)) { /* These symbols are handled specially in fixup_segment. */ goto done; } symsec = S_GET_SEGMENT (sym); if (symsec == NULL) abort (); if (bfd_is_abs_section (symsec)) { /* The fixup_segment routine will not use this symbol in a relocation unless TC_FORCE_RELOCATION returns 1. */ if (TC_FORCE_RELOCATION (fixp)) { symbol_mark_used_in_reloc (fixp->fx_addsy);#ifdef UNDEFINED_DIFFERENCE_OK if (fixp->fx_subsy != NULL) symbol_mark_used_in_reloc (fixp->fx_subsy);#endif } goto done; } /* If it's one of these sections, assume the symbol is definitely going to be output. The code in md_estimate_size_before_relax in tc-mips.c uses this test as well, so if you change this code you should look at that code. */ if (bfd_is_und_section (symsec) || bfd_is_com_section (symsec)) { symbol_mark_used_in_reloc (fixp->fx_addsy);#ifdef UNDEFINED_DIFFERENCE_OK /* We have the difference of an undefined symbol and some other symbol. Make sure to mark the other symbol as used in a relocation so that it will always be output. */ if (fixp->fx_subsy) symbol_mark_used_in_reloc (fixp->fx_subsy);#endif goto done; } /* Don't try to reduce relocs which refer to non-local symbols in .linkonce sections. It can lead to confusion when a debugging section refers to a .linkonce section. I hope this will always be correct. */ if (symsec != sec && ! S_IS_LOCAL (sym)) { boolean linkonce; linkonce = false;#ifdef BFD_ASSEMBLER if ((bfd_get_section_flags (stdoutput, symsec) & SEC_LINK_ONCE) != 0) linkonce = true;#endif#ifdef OBJ_ELF /* The GNU toolchain uses an extension for ELF: a section beginning with the magic string .gnu.linkonce is a linkonce section. */ if (strncmp (segment_name (symsec), ".gnu.linkonce", sizeof ".gnu.linkonce" - 1) == 0) linkonce = true;#endif if (linkonce) { symbol_mark_used_in_reloc (fixp->fx_addsy);#ifdef UNDEFINED_DIFFERENCE_OK if (fixp->fx_subsy != NULL) symbol_mark_used_in_reloc (fixp->fx_subsy);#endif goto done; } } /* Since we're reducing to section symbols, don't attempt to reduce anything that's already using one. */ if (symbol_section_p (sym)) { symbol_mark_used_in_reloc (fixp->fx_addsy); goto done; }#ifdef BFD_ASSEMBLER /* We can never adjust a reloc against a weak symbol. If we did, and the weak symbol was overridden by a real symbol somewhere else, then our relocation would be pointing at the wrong area of memory. */ if (S_IS_WEAK (sym)) { symbol_mark_used_in_reloc (fixp->fx_addsy); goto done; }#endif /* Is there some other reason we can't adjust this one? (E.g., call/bal links in i960-bout symbols.) */#ifdef obj_fix_adjustable if (! obj_fix_adjustable (fixp)) { symbol_mark_used_in_reloc (fixp->fx_addsy); goto done; }#endif /* Is there some other (target cpu dependent) reason we can't adjust this one? (E.g. relocations involving function addresses on the PA. */#ifdef tc_fix_adjustable if (! tc_fix_adjustable (fixp)) { symbol_mark_used_in_reloc (fixp->fx_addsy); goto done; }#endif /* If the section symbol isn't going to be output, the relocs at least should still work. If not, figure out what to do when we run into that case. We refetch the segment when calling section_symbol, rather than using symsec, because S_GET_VALUE may wind up changing the section when it calls resolve_symbol_value. */ fixp->fx_offset += S_GET_VALUE (sym); fixp->fx_addsy = section_symbol (S_GET_SEGMENT (sym)); symbol_mark_used_in_reloc (fixp->fx_addsy);#ifdef DEBUG5 fprintf (stderr, "\nadjusted fixup:\n"); print_fixup (fixp);#endif done: ; }#if 1 /* def RELOC_REQUIRES_SYMBOL */ else { /* There was no symbol required by this relocation. However, BFD doesn't really handle relocations without symbols well. (At least, the COFF support doesn't.) So for now we fake up a local symbol in the absolute section. */ fixp->fx_addsy = section_symbol (absolute_section);#if 0 fixp->fx_addsy->sy_used_in_reloc = 1;#endif }#endif dump_section_relocs (abfd, sec, stderr);}static voidwrite_relocs (abfd, sec, xxx) bfd *abfd; asection *sec; PTR xxx ATTRIBUTE_UNUSED;{ segment_info_type *seginfo = seg_info (sec); unsigned int i; unsigned int n; arelent **relocs; fixS *fixp; char *err; /* If seginfo is NULL, we did not create this section; don't do anything with it. */ if (seginfo == NULL) return; fixup_segment (seginfo->fix_root, sec); n = 0; for (fixp = seginfo->fix_root; fixp; fixp = fixp->fx_next) n++;#ifndef RELOC_EXPANSION_POSSIBLE /* Set up reloc information as well. */ relocs = (arelent **) xmalloc (n * sizeof (arelent *)); memset ((char *) relocs, 0, n * sizeof (arelent *)); i = 0;
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -