You should have received a copy of the GNU General Public License
along with this program; if not, write to the Free Software
-Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02110-1301, USA. */
+Foundation, Inc., 51 Franklin Street - Fifth Floor, Boston, MA 02110-1301, USA. */
/*
SECTION
. output sections that have an input section. *}
. unsigned int linker_has_input : 1;
.
-. {* A mark flag used by some linker backends for garbage collection. *}
+. {* Mark flags used by some linker backends for garbage collection. *}
. unsigned int gc_mark : 1;
+. unsigned int gc_mark_from_eh : 1;
.
. {* The following flags are used by the ELF linker. *}
.
. struct bfd_symbol *symbol;
. struct bfd_symbol **symbol_ptr_ptr;
.
-. struct bfd_link_order *link_order_head;
-. struct bfd_link_order *link_order_tail;
+. {* Early in the link process, map_head and map_tail are used to build
+. a list of input sections attached to an output section. Later,
+. output sections use these fields for a list of bfd_link_order
+. structs. *}
+. union {
+. struct bfd_link_order *link_order;
+. struct bfd_section *s;
+. } map_head, map_tail;
.} asection;
.
.{* These sections are global, and are managed by BFD. The application
.#define bfd_section_removed_from_list(ABFD, S) \
. ((S)->next == NULL ? (ABFD)->section_last != (S) : (S)->next->prev != (S))
.
+.#define BFD_FAKE_SECTION(SEC, FLAGS, SYM, SYM_PTR, NAME, IDX) \
+. {* name, id, index, next, prev, flags, user_set_vma, *} \
+. { NAME, IDX, 0, NULL, NULL, FLAGS, 0, \
+. \
+. {* linker_mark, linker_has_input, gc_mark, gc_mark_from_eh, *} \
+. 0, 0, 1, 0, \
+. \
+. {* segment_mark, sec_info_type, use_rela_p, has_tls_reloc, *} \
+. 0, 0, 0, 0, \
+. \
+. {* has_gp_reloc, need_finalize_relax, reloc_done, *} \
+. 0, 0, 0, \
+. \
+. {* vma, lma, size, rawsize *} \
+. 0, 0, 0, 0, \
+. \
+. {* output_offset, output_section, alignment_power, *} \
+. 0, (struct bfd_section *) &SEC, 0, \
+. \
+. {* relocation, orelocation, reloc_count, filepos, rel_filepos, *} \
+. NULL, NULL, 0, 0, 0, \
+. \
+. {* line_filepos, userdata, contents, lineno, lineno_count, *} \
+. 0, NULL, NULL, NULL, 0, \
+. \
+. {* entsize, kept_section, moving_line_filepos, *} \
+. 0, NULL, 0, \
+. \
+. {* target_index, used_by_bfd, constructor_chain, owner, *} \
+. 0, NULL, NULL, NULL, \
+. \
+. {* symbol, *} \
+. (struct bfd_symbol *) SYM, \
+. \
+. {* symbol_ptr_ptr, *} \
+. (struct bfd_symbol **) SYM_PTR, \
+. \
+. {* map_head, map_tail *} \
+. { NULL }, { NULL } \
+. }
+.
*/
/* We use a macro to initialize the static asymbol structures because
#define STD_SECTION(SEC, FLAGS, SYM, NAME, IDX) \
const asymbol * const SYM = (asymbol *) &global_syms[IDX]; \
- asection SEC = \
- /* name, id, index, next, prev, flags, user_set_vma, */ \
- { NAME, IDX, 0, NULL, NULL, FLAGS, 0, \
- \
- /* linker_mark, linker_has_input, gc_mark, segment_mark, */ \
- 0, 0, 1, 0, \
- \
- /* sec_info_type, use_rela_p, has_tls_reloc, has_gp_reloc, */ \
- 0, 0, 0, 0, \
- \
- /* need_finalize_relax, reloc_done, */ \
- 0, 0, \
- \
- /* vma, lma, size, rawsize */ \
- 0, 0, 0, 0, \
- \
- /* output_offset, output_section, alignment_power, */ \
- 0, (struct bfd_section *) &SEC, 0, \
- \
- /* relocation, orelocation, reloc_count, filepos, rel_filepos, */ \
- NULL, NULL, 0, 0, 0, \
- \
- /* line_filepos, userdata, contents, lineno, lineno_count, */ \
- 0, NULL, NULL, NULL, 0, \
- \
- /* entsize, kept_section, moving_line_filepos, */ \
- 0, NULL, 0, \
- \
- /* target_index, used_by_bfd, constructor_chain, owner, */ \
- 0, NULL, NULL, NULL, \
- \
- /* symbol, */ \
- (struct bfd_symbol *) &global_syms[IDX], \
- \
- /* symbol_ptr_ptr, */ \
- (struct bfd_symbol **) &SYM, \
- \
- /* link_order_head, link_order_tail */ \
- NULL, NULL \
- }
+ asection SEC = BFD_FAKE_SECTION(SEC, FLAGS, &global_syms[IDX], &SYM, \
+ NAME, IDX)
STD_SECTION (bfd_com_section, SEC_IS_COMMON, bfd_com_symbol,
BFD_COM_SECTION_NAME, 0);
/*
FUNCTION
- bfd_make_section_anyway
+ bfd_make_section_anyway_with_flags
SYNOPSIS
- asection *bfd_make_section_anyway (bfd *abfd, const char *name);
+ asection *bfd_make_section_anyway_with_flags
+ (bfd *abfd, const char *name, flagword flags);
DESCRIPTION
Create a new empty section called @var{name} and attach it to the end of
the chain of sections for @var{abfd}. Create a new section even if there
- is already a section with that name.
+ is already a section with that name. Also set the attributes of the
+ new section to the value @var{flags}.
Return <<NULL>> and set <<bfd_error>> on error; possible errors are:
o <<bfd_error_invalid_operation>> - If output has already started for @var{abfd}.
*/
sec_ptr
-bfd_make_section_anyway (bfd *abfd, const char *name)
+bfd_make_section_anyway_with_flags (bfd *abfd, const char *name,
+ flagword flags)
{
struct section_hash_entry *sh;
asection *newsect;
newsect = &new_sh->section;
}
+ newsect->flags = flags;
newsect->name = name;
return bfd_section_init (abfd, newsect);
}
/*
FUNCTION
- bfd_make_section
+ bfd_make_section_anyway
SYNOPSIS
- asection *bfd_make_section (bfd *, const char *name);
+ asection *bfd_make_section_anyway (bfd *abfd, const char *name);
+
+DESCRIPTION
+ Create a new empty section called @var{name} and attach it to the end of
+ the chain of sections for @var{abfd}. Create a new section even if there
+ is already a section with that name.
+
+ Return <<NULL>> and set <<bfd_error>> on error; possible errors are:
+ o <<bfd_error_invalid_operation>> - If output has already started for @var{abfd}.
+ o <<bfd_error_no_memory>> - If memory allocation fails.
+*/
+
+sec_ptr
+bfd_make_section_anyway (bfd *abfd, const char *name)
+{
+ return bfd_make_section_anyway_with_flags (abfd, name, 0);
+}
+
+/*
+FUNCTION
+ bfd_make_section_with_flags
+
+SYNOPSIS
+ asection *bfd_make_section_with_flags
+ (bfd *, const char *name, flagword flags);
DESCRIPTION
Like <<bfd_make_section_anyway>>, but return <<NULL>> (without calling
bfd_set_error ()) without changing the section chain if there is already a
- section named @var{name}. If there is an error, return <<NULL>> and set
+ section named @var{name}. Also set the attributes of the new section to
+ the value @var{flags}. If there is an error, return <<NULL>> and set
<<bfd_error>>.
*/
asection *
-bfd_make_section (bfd *abfd, const char *name)
+bfd_make_section_with_flags (bfd *abfd, const char *name,
+ flagword flags)
{
struct section_hash_entry *sh;
asection *newsect;
}
newsect->name = name;
+ newsect->flags = flags;
return bfd_section_init (abfd, newsect);
}
+/*
+FUNCTION
+ bfd_make_section
+
+SYNOPSIS
+ asection *bfd_make_section (bfd *, const char *name);
+
+DESCRIPTION
+ Like <<bfd_make_section_anyway>>, but return <<NULL>> (without calling
+ bfd_set_error ()) without changing the section chain if there is already a
+ section named @var{name}. If there is an error, return <<NULL>> and set
+ <<bfd_error>>.
+*/
+
+asection *
+bfd_make_section (bfd *abfd, const char *name)
+{
+ return bfd_make_section_with_flags (abfd, name, 0);
+}
+
/*
FUNCTION
bfd_set_section_flags
return FALSE;
}
- switch (abfd->direction)
+ if (!bfd_write_p (abfd))
{
- case read_direction:
- case no_direction:
bfd_set_error (bfd_error_invalid_operation);
return FALSE;
-
- case write_direction:
- break;
-
- case both_direction:
- /* File is opened for update. `output_has_begun' some time ago when
- the file was created. Do not recompute sections sizes or alignments
- in _bfd_set_section_content. */
- abfd->output_has_begun = TRUE;
- break;
}
/* Record a copy of the data in memory if desired. */
. (ibfd, isection, obfd, osection))
*/
-/*
-FUNCTION
- _bfd_strip_section_from_output
-
-SYNOPSIS
- void _bfd_strip_section_from_output
- (struct bfd_link_info *info, asection *section);
-
-DESCRIPTION
- Remove @var{section} from the output. If the output section
- becomes empty, remove it from the output bfd.
-
- This function won't actually do anything except twiddle flags
- if called too late in the linking process, when it's not safe
- to remove sections.
-*/
-void
-_bfd_strip_section_from_output (struct bfd_link_info *info, asection *s)
-{
- asection *os;
- asection *is;
- bfd *abfd;
-
- s->flags |= SEC_EXCLUDE;
-
- /* If the section wasn't assigned to an output section, or the
- section has been discarded by the linker script, there's nothing
- more to do. */
- os = s->output_section;
- if (os == NULL || os->owner == NULL)
- return;
-
- /* If the output section has other (non-excluded) input sections, we
- can't remove it. */
- for (abfd = info->input_bfds; abfd != NULL; abfd = abfd->link_next)
- for (is = abfd->sections; is != NULL; is = is->next)
- if (is->output_section == os && (is->flags & SEC_EXCLUDE) == 0)
- return;
-
- /* If the output section is empty, flag it for removal too.
- See ldlang.c:strip_excluded_output_sections for the action. */
- os->flags |= SEC_EXCLUDE;
-}
-
/*
FUNCTION
bfd_generic_is_group_section