X-Git-Url: http://drtracing.org/?a=blobdiff_plain;f=gas%2Fsubsegs.c;h=0647653f8784e1d8c9bec2bd248082454ff4b215;hb=b42e9fa8cc214f0fa94598da86aa112713a9b192;hp=c81c09a43d4928fdfd968268cddbba4ac01180f2;hpb=f592407e4d75fc64e87c25cdd8b21361b3d322d1;p=deliverable%2Fbinutils-gdb.git diff --git a/gas/subsegs.c b/gas/subsegs.c index c81c09a43d..0647653f87 100644 --- a/gas/subsegs.c +++ b/gas/subsegs.c @@ -1,13 +1,11 @@ /* subsegs.c - subsegments - - Copyright 1987, 1990, 1991, 1992, 1993, 1994, 1995, 1996, 1997, 1998, - 1999, 2000, 2001, 2002, 2003, 2004, 2005, 2006 - Free Software Foundation, Inc. + Copyright (C) 1987-2016 Free Software Foundation, Inc. This file is part of GAS, the GNU Assembler. GAS is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by - the Free Software Foundation; either version 2, or (at your option) + the Free Software Foundation; either version 3, or (at your option) any later version. GAS is distributed in the hope that it will be useful, @@ -27,20 +25,12 @@ #include "subsegs.h" #include "obstack.h" -frchainS *frchain_root, *frchain_now; +frchainS *frchain_now; static struct obstack frchains; -/* Gas segment information for bfd_abs_section_ptr and - bfd_und_section_ptr. */ -static segment_info_type *abs_seg_info; -static segment_info_type *und_seg_info; - -static void subseg_set_rest (segT, subsegT); - static fragS dummy_frag; -static frchainS absolute_frchain; void subsegs_begin (void) @@ -50,16 +40,8 @@ subsegs_begin (void) obstack_alignment_mask (&frchains) = __alignof__ (frchainS) - 1; #endif - frchain_root = NULL; frchain_now = NULL; /* Warn new_subseg() that we are booting. */ - frag_now = &dummy_frag; - - absolute_frchain.frch_seg = absolute_section; - absolute_frchain.frch_subseg = 0; - absolute_frchain.fix_root = absolute_frchain.fix_tail = 0; - absolute_frchain.frch_frag_now = &zero_address_frag; - absolute_frchain.frch_root = absolute_frchain.frch_last = &zero_address_frag; } /* @@ -73,112 +55,54 @@ subsegs_begin (void) * segment context correct. */ void -subseg_change (register segT seg, register int subseg) +subseg_change (segT seg, int subseg) { - segment_info_type *seginfo; + segment_info_type *seginfo = seg_info (seg); now_seg = seg; now_subseg = subseg; - if (now_seg == absolute_section) - return; - - seginfo = (segment_info_type *) bfd_get_section_userdata (stdoutput, seg); if (! seginfo) { - seginfo = (segment_info_type *) xmalloc (sizeof (*seginfo)); - memset ((PTR) seginfo, 0, sizeof (*seginfo)); - seginfo->fix_root = NULL; - seginfo->fix_tail = NULL; + seginfo = XCNEW (segment_info_type); seginfo->bfd_section = seg; - seginfo->sym = 0; - if (seg == bfd_abs_section_ptr) - abs_seg_info = seginfo; - else if (seg == bfd_und_section_ptr) - und_seg_info = seginfo; - else - bfd_set_section_userdata (stdoutput, seg, (PTR) seginfo); + bfd_set_section_userdata (stdoutput, seg, seginfo); } } static void subseg_set_rest (segT seg, subsegT subseg) { - register frchainS *frcP; /* crawl frchain chain */ - register frchainS **lastPP; /* address of last pointer */ + frchainS *frcP; /* crawl frchain chain */ + frchainS **lastPP; /* address of last pointer */ frchainS *newP; /* address of new frchain */ + segment_info_type *seginfo; mri_common_symbol = NULL; if (frag_now && frchain_now) frchain_now->frch_frag_now = frag_now; - assert (frchain_now == 0 - || now_seg == undefined_section - || now_seg == absolute_section + gas_assert (frchain_now == 0 || frchain_now->frch_last == frag_now); subseg_change (seg, (int) subseg); - if (seg == absolute_section) - { - frchain_now = &absolute_frchain; - frag_now = &zero_address_frag; - return; - } - - assert (frchain_now == 0 - || now_seg == undefined_section - || frchain_now->frch_last == frag_now); + seginfo = seg_info (seg); - /* - * Attempt to find or make a frchain for that sub seg. - * Crawl along chain of frchainSs, begins @ frchain_root. - * If we need to make a frchainS, link it into correct - * position of chain rooted in frchain_root. - */ - for (frcP = *(lastPP = &frchain_root); - frcP && frcP->frch_seg <= seg; + /* Attempt to find or make a frchain for that subsection. + We keep the list sorted by subsection number. */ + for (frcP = *(lastPP = &seginfo->frchainP); + frcP != NULL; frcP = *(lastPP = &frcP->frch_next)) + if (frcP->frch_subseg >= subseg) + break; + + if (frcP == NULL || frcP->frch_subseg != subseg) { - if (frcP->frch_seg == seg - && frcP->frch_subseg >= subseg) - { - break; - } - } - /* - * frcP: Address of the 1st frchainS in correct segment with - * frch_subseg >= subseg. - * We want to either use this frchainS, or we want - * to insert a new frchainS just before it. - * - * If frcP==NULL, then we are at the end of the chain - * of frchainS-s. A NULL frcP means we fell off the end - * of the chain looking for a - * frch_subseg >= subseg, so we - * must make a new frchainS. - * - * If we ever maintain a pointer to - * the last frchainS in the chain, we change that pointer - * ONLY when frcP==NULL. - * - * lastPP: Address of the pointer with value frcP; - * Never NULL. - * May point to frchain_root. - * - */ - if (!frcP - || (frcP->frch_seg > seg - || frcP->frch_subseg > subseg)) /* Kinky logic only works with 2 segments. */ - { - /* - * This should be the only code that creates a frchainS. - */ - segment_info_type *seginfo; + /* This should be the only code that creates a frchainS. */ newP = (frchainS *) obstack_alloc (&frchains, sizeof (frchainS)); newP->frch_subseg = subseg; - newP->frch_seg = seg; newP->fix_root = NULL; newP->fix_tail = NULL; obstack_begin (&newP->frch_obstack, chunksize); @@ -187,25 +111,19 @@ subseg_set_rest (segT seg, subsegT subseg) #endif newP->frch_frag_now = frag_alloc (&newP->frch_obstack); newP->frch_frag_now->fr_type = rs_fill; + newP->frch_cfi_data = NULL; newP->frch_root = newP->frch_last = newP->frch_frag_now; *lastPP = newP; - newP->frch_next = frcP; /* perhaps NULL */ - - seginfo = seg_info (seg); - if (seginfo && (!seginfo->frchainP || seginfo->frchainP == frcP)) - seginfo->frchainP = newP; - + newP->frch_next = frcP; frcP = newP; } - /* - * Here with frcP pointing to the frchainS for subseg. - */ + frchain_now = frcP; frag_now = frcP->frch_frag_now; - assert (frchain_now->frch_last == frag_now); + gas_assert (frchain_now->frch_last == frag_now); } /* @@ -221,7 +139,6 @@ subseg_set_rest (segT seg, subsegT subseg) * Out: now_subseg, now_seg updated. * Frchain_now points to the (possibly new) struct frchain for this * sub-segment. - * Frchain_root updated if needed. */ segT @@ -247,25 +164,10 @@ subseg_get (const char *segname, int force_new) seginfo = seg_info (secptr); if (! seginfo) { - /* Check whether output_section is set first because secptr may - be bfd_abs_section_ptr. */ - if (secptr->output_section != secptr) - secptr->output_section = secptr; - seginfo = (segment_info_type *) xmalloc (sizeof (*seginfo)); - memset ((PTR) seginfo, 0, sizeof (*seginfo)); - seginfo->fix_root = NULL; - seginfo->fix_tail = NULL; + secptr->output_section = secptr; + seginfo = XCNEW (segment_info_type); seginfo->bfd_section = secptr; - if (secptr == bfd_abs_section_ptr) - abs_seg_info = seginfo; - else if (secptr == bfd_und_section_ptr) - und_seg_info = seginfo; - else - bfd_set_section_userdata (stdoutput, secptr, (PTR) seginfo); - seginfo->frchainP = NULL; - seginfo->lineno_list_head = seginfo->lineno_list_tail = NULL; - seginfo->sym = NULL; - seginfo->dot = NULL; + bfd_set_section_userdata (stdoutput, secptr, seginfo); } return secptr; } @@ -274,13 +176,9 @@ segT subseg_new (const char *segname, subsegT subseg) { segT secptr; - segment_info_type *seginfo; secptr = subseg_get (segname, 0); subseg_set_rest (secptr, subseg); - seginfo = seg_info (secptr); - if (! seginfo->frchainP) - seginfo->frchainP = frchain_now; return secptr; } @@ -290,13 +188,9 @@ segT subseg_force_new (const char *segname, subsegT subseg) { segT secptr; - segment_info_type *seginfo; secptr = subseg_get (segname, 1); subseg_set_rest (secptr, subseg); - seginfo = seg_info (secptr); - if (! seginfo->frchainP) - seginfo->frchainP = frchain_now; return secptr; } @@ -312,19 +206,6 @@ subseg_set (segT secptr, subsegT subseg) #define obj_sec_sym_ok_for_reloc(SEC) 0 #endif -/* Get the gas information we are storing for a section. */ - -segment_info_type * -seg_info (segT sec) -{ - if (sec == bfd_abs_section_ptr) - return abs_seg_info; - else if (sec == bfd_und_section_ptr) - return und_seg_info; - else - return (segment_info_type *) bfd_get_section_userdata (stdoutput, sec); -} - symbolS * section_symbol (segT sec) { @@ -397,7 +278,7 @@ seg_not_empty_p (segT sec ATTRIBUTE_UNUSED) if (!seginfo) return 0; - + for (chain = seginfo->frchainP; chain; chain = chain->frch_next) { for (frag = chain->frch_root; frag; frag = frag->fr_next) @@ -414,28 +295,33 @@ void subsegs_print_statistics (FILE *file) { frchainS *frchp; + asection *s; + fprintf (file, "frag chains:\n"); - for (frchp = frchain_root; frchp; frchp = frchp->frch_next) + for (s = stdoutput->sections; s; s = s->next) { - int count = 0; - fragS *fragp; + segment_info_type *seginfo; - /* If frch_subseg is non-zero, it's probably been chained onto - the end of a previous subsection. Don't count it again. */ - if (frchp->frch_subseg != 0) + /* Skip gas-internal sections. */ + if (segment_name (s)[0] == '*') continue; - /* Skip gas-internal sections. */ - if (segment_name (frchp->frch_seg)[0] == '*') + seginfo = seg_info (s); + if (!seginfo) continue; - for (fragp = frchp->frch_root; fragp; fragp = fragp->fr_next) + for (frchp = seginfo->frchainP; frchp; frchp = frchp->frch_next) { - count++; + int count = 0; + fragS *fragp; + + for (fragp = frchp->frch_root; fragp; fragp = fragp->fr_next) + count++; + + fprintf (file, "\n"); + fprintf (file, "\t%p %-10s\t%10d frags\n", (void *) frchp, + segment_name (s), count); } - fprintf (file, "\n"); - fprintf (file, "\t%p %-10s\t%10d frags\n", (void *) frchp, - segment_name (frchp->frch_seg), count); } }