summaryrefslogtreecommitdiffstats
path: root/binutils-2.25/gas/write.c
diff options
context:
space:
mode:
Diffstat (limited to 'binutils-2.25/gas/write.c')
-rw-r--r--binutils-2.25/gas/write.c162
1 files changed, 90 insertions, 72 deletions
diff --git a/binutils-2.25/gas/write.c b/binutils-2.25/gas/write.c
index 745abe66..0f82d479 100644
--- a/binutils-2.25/gas/write.c
+++ b/binutils-2.25/gas/write.c
@@ -1,7 +1,5 @@
/* write.c - emit .o file
- Copyright 1986, 1987, 1990, 1991, 1992, 1993, 1994, 1995, 1996, 1997,
- 1998, 1999, 2000, 2001, 2002, 2003, 2004, 2005, 2006, 2007, 2008, 2009,
- 2010, 2011, 2012 Free Software Foundation, Inc.
+ Copyright (C) 1986-2014 Free Software Foundation, Inc.
This file is part of GAS, the GNU Assembler.
@@ -838,7 +836,8 @@ adjust_reloc_syms (bfd *abfd ATTRIBUTE_UNUSED,
if (symsec == NULL)
abort ();
- if (bfd_is_abs_section (symsec))
+ if (bfd_is_abs_section (symsec)
+ || symsec == reg_section)
{
/* The fixup_segment routine normally will not use this
symbol in a relocation. */
@@ -1694,64 +1693,99 @@ set_symtab (void)
#endif
#endif
-void
-subsegs_finish (void)
+static void
+subsegs_finish_section (asection *s)
{
struct frchain *frchainP;
- asection *s;
+ segment_info_type *seginfo = seg_info (s);
+ if (!seginfo)
+ return;
- for (s = stdoutput->sections; s; s = s->next)
+ for (frchainP = seginfo->frchainP;
+ frchainP != NULL;
+ frchainP = frchainP->frch_next)
{
- segment_info_type *seginfo = seg_info (s);
- if (!seginfo)
- continue;
-
- for (frchainP = seginfo->frchainP;
- frchainP != NULL;
- frchainP = frchainP->frch_next)
- {
- int alignment = 0;
+ int alignment = 0;
- subseg_set (s, frchainP->frch_subseg);
+ subseg_set (s, frchainP->frch_subseg);
- /* This now gets called even if we had errors. In that case,
- any alignment is meaningless, and, moreover, will look weird
- if we are generating a listing. */
- if (!had_errors ())
+ /* This now gets called even if we had errors. In that case,
+ any alignment is meaningless, and, moreover, will look weird
+ if we are generating a listing. */
+ if (!had_errors ())
+ {
+ alignment = SUB_SEGMENT_ALIGN (now_seg, frchainP);
+ if ((bfd_get_section_flags (now_seg->owner, now_seg) & SEC_MERGE)
+ && now_seg->entsize)
{
- alignment = SUB_SEGMENT_ALIGN (now_seg, frchainP);
- if ((bfd_get_section_flags (now_seg->owner, now_seg) & SEC_MERGE)
- && now_seg->entsize)
- {
- unsigned int entsize = now_seg->entsize;
- int entalign = 0;
+ unsigned int entsize = now_seg->entsize;
+ int entalign = 0;
- while ((entsize & 1) == 0)
- {
- ++entalign;
- entsize >>= 1;
- }
- if (entalign > alignment)
- alignment = entalign;
+ while ((entsize & 1) == 0)
+ {
+ ++entalign;
+ entsize >>= 1;
}
+
+ if (entalign > alignment)
+ alignment = entalign;
}
+ }
- if (subseg_text_p (now_seg))
- frag_align_code (alignment, 0);
- else
- frag_align (alignment, 0, 0);
+ if (subseg_text_p (now_seg))
+ frag_align_code (alignment, 0);
+ else
+ frag_align (alignment, 0, 0);
- /* frag_align will have left a new frag.
- Use this last frag for an empty ".fill".
+ /* frag_align will have left a new frag.
+ Use this last frag for an empty ".fill".
- For this segment ...
- Create a last frag. Do not leave a "being filled in frag". */
- frag_wane (frag_now);
- frag_now->fr_fix = 0;
- know (frag_now->fr_next == NULL);
- }
+ For this segment ...
+ Create a last frag. Do not leave a "being filled in frag". */
+ frag_wane (frag_now);
+ frag_now->fr_fix = 0;
+ know (frag_now->fr_next == NULL);
+ }
+}
+
+static void
+subsegs_finish (void)
+{
+ asection *s;
+
+ for (s = stdoutput->sections; s; s = s->next)
+ subsegs_finish_section (s);
+}
+
+#ifdef OBJ_ELF
+static void
+create_obj_attrs_section (void)
+{
+ segT s;
+ char *p;
+ offsetT size;
+ const char *name;
+
+ size = bfd_elf_obj_attr_size (stdoutput);
+ if (size)
+ {
+ name = get_elf_backend_data (stdoutput)->obj_attrs_section;
+ if (!name)
+ name = ".gnu.attributes";
+ s = subseg_new (name, 0);
+ elf_section_type (s)
+ = get_elf_backend_data (stdoutput)->obj_attrs_section_type;
+ bfd_set_section_flags (stdoutput, s, SEC_READONLY | SEC_DATA);
+ frag_now_fix ();
+ p = frag_more (size);
+ bfd_elf_set_obj_attr_contents (stdoutput, (bfd_byte *)p, size);
+
+ subsegs_finish_section (s);
+ relax_segment (seg_info (s)->frchainP->frch_root, s, 0);
+ size_seg (stdoutput, s, NULL);
}
}
+#endif
/* Write the object file. */
@@ -1763,33 +1797,12 @@ write_object_file (void)
fragS *fragP; /* Track along all frags. */
#endif
+ subsegs_finish ();
+
#ifdef md_pre_output_hook
md_pre_output_hook;
#endif
- /* Do we really want to write it? */
- {
- int n_warns, n_errs;
- n_warns = had_warnings ();
- n_errs = had_errors ();
- /* The -Z flag indicates that an object file should be generated,
- regardless of warnings and errors. */
- if (flag_always_generate_output)
- {
- if (n_warns || n_errs)
- as_warn (_("%d error%s, %d warning%s, generating bad object file"),
- n_errs, n_errs == 1 ? "" : "s",
- n_warns, n_warns == 1 ? "" : "s");
- }
- else
- {
- if (n_errs)
- as_fatal (_("%d error%s, %d warning%s, no object file generated"),
- n_errs, n_errs == 1 ? "" : "s",
- n_warns, n_warns == 1 ? "" : "s");
- }
- }
-
#ifdef md_pre_relax_hook
md_pre_relax_hook;
#endif
@@ -1866,6 +1879,11 @@ write_object_file (void)
md_post_relax_hook;
#endif
+#ifdef OBJ_ELF
+ if (IS_ELF)
+ create_obj_attrs_section ();
+#endif
+
#ifndef WORKING_DOT_WORD
{
struct broken_word *lie;
@@ -1885,7 +1903,7 @@ write_object_file (void)
#ifdef TC_CONS_FIX_NEW
TC_CONS_FIX_NEW (lie->frag,
lie->word_goes_here - lie->frag->fr_literal,
- 2, &exp);
+ 2, &exp, TC_PARSE_CONS_RETURN_NONE);
#else
fix_new_exp (lie->frag,
lie->word_goes_here - lie->frag->fr_literal,
@@ -2292,7 +2310,7 @@ relax_align (register relax_addressT address, /* Address now. */
relax_addressT mask;
relax_addressT new_address;
- mask = ~((~0) << alignment);
+ mask = ~((relax_addressT) ~0 << alignment);
new_address = (address + mask) & (~mask);
#ifdef LINKER_RELAXING_SHRINKS_ONLY
if (linkrelax)