diff options
author | Ian Lance Taylor <ian@airs.com> | 1996-03-29 21:35:44 +0000 |
---|---|---|
committer | Ian Lance Taylor <ian@airs.com> | 1996-03-29 21:35:44 +0000 |
commit | 7d3741edcbbe31bf48ccb504500aa3beceebc501 (patch) | |
tree | 7307366aa6bbbd1a2f6f3d4cbbbbb647a5dba70e /gas/read.c | |
parent | 38d7c0125d0dbdd38f94e3c8756f75e281d92523 (diff) | |
download | gdb-7d3741edcbbe31bf48ccb504500aa3beceebc501.zip gdb-7d3741edcbbe31bf48ccb504500aa3beceebc501.tar.gz gdb-7d3741edcbbe31bf48ccb504500aa3beceebc501.tar.bz2 |
* read.h (enum linkonce_type): Define.
(s_linkonce): Declare.
* read.c (potable): Add "linkonce".
(s_linkonce): New function.
* subsegs.h (segment_info_type): Add linkonce field to
MANY_SEGMENTS && ! BFD_ASSEMBLER section.
* config/obj-coff.h (obj_handle_link_once): Define if TE_PE.
(obj_coff_pe_handle_link_once): Declare if TE_PE.
* config/obj-coff.c: If TE_PE and not BFD_ASSEMBLER, #include
"coff/pe.h".
(obj_coff_pe_handle_link_once): New function, defined if TE_PE.
(c_section_symbol): If TE_PE, set the x_comdat field in the aux
entry based on the linkonce field in segment_info.
* doc/as.texinfo: Document .linkonce.
Diffstat (limited to 'gas/read.c')
-rw-r--r-- | gas/read.c | 78 |
1 files changed, 78 insertions, 0 deletions
@@ -327,6 +327,7 @@ static const pseudo_typeS potable[] = {"irepc", s_irp, 1}, {"lcomm", s_lcomm, 0}, {"lflags", listing_flags, 0}, /* Listing flags */ + {"linkonce", s_linkonce, 0}, {"list", listing_list, 1}, /* Turn listing on */ {"llen", listing_psize, 1}, {"long", cons, 4}, @@ -1689,6 +1690,83 @@ s_irp (irpc) buffer_limit = input_scrub_next_buffer (&input_line_pointer); } +/* Handle the .linkonce pseudo-op. This tells the assembler to mark + the section to only be linked once. However, this is not supported + by most object file formats. This takes an optional argument, + which is what to do about duplicates. */ + +void +s_linkonce (ignore) + int ignore; +{ + enum linkonce_type type; + + SKIP_WHITESPACE (); + + type = LINKONCE_DISCARD; + + if (! is_end_of_line[(unsigned char) *input_line_pointer]) + { + char *s; + char c; + + s = input_line_pointer; + c = get_symbol_end (); + if (strcasecmp (s, "discard") == 0) + type = LINKONCE_DISCARD; + else if (strcasecmp (s, "one_only") == 0) + type = LINKONCE_ONE_ONLY; + else if (strcasecmp (s, "same_size") == 0) + type = LINKONCE_SAME_SIZE; + else if (strcasecmp (s, "same_contents") == 0) + type = LINKONCE_SAME_CONTENTS; + else + as_warn ("unrecognized .linkonce type `%s'", s); + + *input_line_pointer = c; + } + +#ifdef obj_handle_link_once + obj_handle_link_once (type); +#else /* ! defined (obj_handle_link_once) */ +#ifdef BFD_ASSEMBLER + { + flagword flags; + + if ((bfd_applicable_section_flags (stdoutput) & SEC_LINK_ONCE) == 0) + as_warn (".linkonce is not supported for this object file format"); + + flags = bfd_get_section_flags (stdoutput, now_seg); + flags |= SEC_LINK_ONCE; + switch (type) + { + default: + abort (); + case LINKONCE_DISCARD: + flags |= SEC_LINK_DUPLICATES_DISCARD; + break; + case LINKONCE_ONE_ONLY: + flags |= SEC_LINK_DUPLICATES_ONE_ONLY; + break; + case LINKONCE_SAME_SIZE: + flags |= SEC_LINK_DUPLICATES_SAME_SIZE; + break; + case LINKONCE_SAME_CONTENTS: + flags |= SEC_LINK_DUPLICATES_SAME_CONTENTS; + break; + } + if (! bfd_set_section_flags (stdoutput, now_seg, flags)) + as_bad ("bfd_set_section_flags: %s", + bfd_errmsg (bfd_get_error ())); + } +#else /* ! defined (BFD_ASSEMBLER) */ + as_warn (".linkonce is not supported for this object file format"); +#endif /* ! defined (BFD_ASSEMBLER) */ +#endif /* ! defined (obj_handle_link_once) */ + + demand_empty_rest_of_line (); +} + void s_lcomm (needs_align) /* 1 if this was a ".bss" directive, which may require a 3rd argument |