aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--gas/ChangeLog15
-rw-r--r--gas/config/obj-coff.c99
-rw-r--r--gas/subsegs.h23
3 files changed, 104 insertions, 33 deletions
diff --git a/gas/ChangeLog b/gas/ChangeLog
index 0250fe6..0241327 100644
--- a/gas/ChangeLog
+++ b/gas/ChangeLog
@@ -1,5 +1,20 @@
Wed May 1 13:38:17 1996 Ian Lance Taylor <ian@cygnus.com>
+ * subsegs.h (segment_info_type): If MANY_SEGMENTS and not
+ BFD_ASSEMBLER, add name field.
+ * config/obj-coff.c (coff_header_append): Handle long section
+ names.
+ (crawl_symbols): Just use the name field for the symbol name,
+ without worrying about null byte termination.
+ (w_strings): Handle long section names.
+ (write_object_file): Likewise. Also, use the name field, rather
+ than scnhdr.s_name.
+ (obj_coff_add_segment): Permit long section names.
+ (obj_coff_init_stab_section): Use the name field, rather than
+ scnhdr.s_name.
+ (adjust_stab_section): Likewise.
+ * config/te-pe.h (COFF_LONG_SECTION_NAMES): Define.
+
* config/tc-i960.c (brtab_emit): Don't set fx_im_disp field.
(mem_fmt): Likewise.
(md_apply_fix): Don't check fx_im_disp field.
diff --git a/gas/config/obj-coff.c b/gas/config/obj-coff.c
index 087e250..3497ab2 100644
--- a/gas/config/obj-coff.c
+++ b/gas/config/obj-coff.c
@@ -1922,12 +1922,29 @@ coff_header_append (abfd, h)
for (i = SEG_E0; i < SEG_LAST; i++)
{
+#ifdef COFF_LONG_SECTION_NAMES
+ unsigned long string_size = 4;
+#endif
+
if (segment_info[i].scnhdr.s_name[0])
{
- unsigned int size =
- bfd_coff_swap_scnhdr_out (abfd,
- &(segment_info[i].scnhdr),
- buffer);
+ unsigned int size;
+
+#ifdef COFF_LONG_SECTION_NAMES
+ /* Support long section names as found in PE. This code
+ must coordinate with that in write_object_file and
+ w_strings. */
+ if (strlen (segment_info[i].name) > SCNNMLEN)
+ {
+ memset (segment_info[i].scnhdr.s_name, 0, SCNNMLEN);
+ sprintf (segment_info[i].scnhdr.s_name, "/%d", string_size);
+ string_size += strlen (segment_info[i].scnhdr.name) + 1;
+ }
+#endif
+
+ size = bfd_coff_swap_scnhdr_out (abfd,
+ &(segment_info[i].scnhdr),
+ buffer);
if (size == 0)
as_bad ("bfd_coff_swap_scnhdr_out failed");
bfd_write (buffer, size, 1, abfd);
@@ -2891,17 +2908,9 @@ crawl_symbols (h, abfd)
for (i = SEG_E0; i < SEG_LAST; i++)
- {
- if (segment_info[i].scnhdr.s_name[0])
- {
- char name[9];
-
- strncpy (name, segment_info[i].scnhdr.s_name, 8);
- name[8] = '\0';
- segment_info[i].dot = c_section_symbol (name, i - SEG_E0 + 1);
- }
- }
-
+ if (segment_info[i].scnhdr.s_name[0])
+ segment_info[i].dot = c_section_symbol (segment_info[i].name,
+ i - SEG_E0 + 1);
/* Take all the externals out and put them into another chain */
H_SET_SYMBOL_TABLE_SIZE (h, yank_symbols ());
@@ -2934,6 +2943,24 @@ w_strings (where)
/* Gotta do md_ byte-ordering stuff for string_byte_count first - KWK */
md_number_to_chars (where, (valueT) string_byte_count, 4);
where += 4;
+
+#ifdef COFF_LONG_SECTION_NAMES
+ /* Support long section names as found in PE. This code must
+ coordinate with that in coff_header_append and write_object_file. */
+ for (i = SEG_E0; i < SEG_LAST; i++)
+ {
+ if (segment_info[i].scnhdr.s_name[0]
+ && strlen (segment_info[i].name) > SCNNMLEN)
+ {
+ unsigned int size;
+
+ size = strlen (segment_info[i].name) + 1;
+ memcpy (where, segment_info[i].name, size);
+ where += size;
+ }
+ }
+#endif /* COFF_LONG_SECTION_NAMES */
+
for (symbolP = symbol_rootP;
symbolP;
symbolP = symbol_next (symbolP))
@@ -3120,6 +3147,19 @@ write_object_file ()
{
H_SET_NUMBER_OF_SECTIONS (&headers,
H_GET_NUMBER_OF_SECTIONS (&headers) + 1);
+
+#ifdef COFF_LONG_SECTION_NAMES
+ /* Support long section names as found in PE. This code
+ must coordinate with that in coff_header_append and
+ w_strings. */
+ {
+ unsigned int len;
+
+ len = strlen (segment_info[i].name);
+ if (len > SCNNMLEN)
+ string_byte_count += len + 1;
+ }
+#endif /* COFF_LONG_SECTION_NAMES */
}
size = size_section (abfd, (unsigned int) i);
@@ -3159,7 +3199,7 @@ write_object_file ()
correctly. */
for (i = SEG_E0; i < SEG_UNKNOWN; i++)
{
- name = segment_info[i].scnhdr.s_name;
+ name = segment_info[i].name;
if (name != NULL
&& strncmp (".stab", name, 5) == 0
@@ -3240,16 +3280,16 @@ obj_coff_add_segment (name)
unsigned int len;
unsigned int i;
- /* Find out if we've already got a section of this name. */
- len = strlen (name);
- if (len < sizeof (segment_info[i].scnhdr.s_name))
- ++len;
- else
- len = sizeof (segment_info[i].scnhdr.s_name);
+#ifndef COFF_LONG_SECTION_NAMES
+ char buf[SCNNMLEN + 1];
+
+ strncpy (buf, name, SCNNMLEN);
+ buf[SCNNMLEN] = '\0';
+ name = buf;
+#endif
+
for (i = SEG_E0; i < SEG_LAST && segment_info[i].scnhdr.s_name[0]; i++)
- if (strncmp (segment_info[i].scnhdr.s_name, name, len) == 0
- && (len == sizeof (segment_info[i].scnhdr.s_name)
- || segment_info[i].scnhdr.s_name[len] == '\0'))
+ if (strcmp (name, segment_info[i].name) == 0)
return (segT) i;
if (i == SEG_LAST)
@@ -3262,6 +3302,7 @@ obj_coff_add_segment (name)
strncpy (segment_info[i].scnhdr.s_name, name,
sizeof (segment_info[i].scnhdr.s_name));
segment_info[i].scnhdr.s_flags = STYP_REG;
+ segment_info[i].name = xstrdup (name);
return (segT) i;
}
@@ -4081,8 +4122,8 @@ obj_coff_init_stab_section (seg)
/* Zero it out. */
memset (p, 0, 12);
as_where (&file, (unsigned int *) NULL);
- stabstr_name = (char *) alloca (strlen (segment_info[seg].scnhdr.s_name) + 4);
- strcpy (stabstr_name, segment_info[seg].scnhdr.s_name);
+ stabstr_name = (char *) alloca (strlen (segment_info[seg].name) + 4);
+ strcpy (stabstr_name, segment_info[seg].name);
strcat (stabstr_name, "str");
stroff = get_stab_string_offset (file, stabstr_name);
know (stroff == 1);
@@ -4104,14 +4145,14 @@ adjust_stab_section(abfd, seg)
/* Look for the associated string table section. */
- secname = segment_info[seg].scnhdr.s_name;
+ secname = segment_info[seg].name;
name = (char *) alloca (strlen (secname) + 4);
strcpy (name, secname);
strcat (name, "str");
for (i = SEG_E0; i < SEG_UNKNOWN; i++)
{
- name2 = segment_info[i].scnhdr.s_name;
+ name2 = segment_info[i].name;
if (name2 != NULL && strncmp(name2, name, 8) == 0)
{
stabstrseg = i;
diff --git a/gas/subsegs.h b/gas/subsegs.h
index 2d3a100..7d71e8b 100644
--- a/gas/subsegs.h
+++ b/gas/subsegs.h
@@ -16,7 +16,7 @@
You should have received a copy of the GNU General Public License
along with GAS; see the file COPYING. If not, write to
- the Free Software Foundation, 675 Mass Ave, Cambridge, MA 02139, USA. */
+ the Free Software Foundation, 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */
/*
* For every sub-segment the user mentions in the ASsembler program,
@@ -37,6 +37,8 @@
* represent code fragments, for that sub-segment, forward chained.
*/
+#include "obstack.h"
+
struct frchain /* control building of a frag chain */
{ /* FRCH = FRagment CHain control */
struct frag *frch_root; /* 1st struct frag in chain, or NULL */
@@ -49,6 +51,7 @@ struct frchain /* control building of a frag chain */
fixS *fix_tail; /* Last fixup for this subsegment. */
#endif
struct obstack frch_obstack; /* for objects in this frag chain */
+ fragS *frch_frag_now; /* frag_now for this subsegment */
};
typedef struct frchain frchainS;
@@ -56,7 +59,7 @@ typedef struct frchain frchainS;
/* All subsegments' chains hang off here. NULL means no frchains yet. */
extern frchainS *frchain_root;
-/* Frchain we are assembling into now That is, the current segment's
+/* Frchain we are assembling into now. That is, the current segment's
frag chain, even if it contains no (complete) frags. */
extern frchainS *frchain_now;
@@ -64,14 +67,14 @@ extern frchainS *frchain_now;
typedef struct
{
frchainS *frchainP;
- int hadone : 1;
+ unsigned int hadone : 1;
/* This field is set if this is a .bss section which does not really
have any contents. Once upon a time a .bss section did not have
any frags, but that is no longer true. This field prevent the
SEC_HAS_CONTENTS flag from being set for the section even if
there are frags. */
- int bss : 1;
+ unsigned int bss : 1;
int user_stuff;
@@ -82,7 +85,10 @@ typedef struct
#if defined (MANY_SEGMENTS) && !defined (BFD_ASSEMBLER)
struct internal_scnhdr scnhdr;
+ enum linkonce_type linkonce;
+ const char *name;
#endif
+
symbolS *dot;
struct lineno_list *lineno_list_head;
@@ -131,6 +137,15 @@ extern segment_info_type segment_info[];
extern frchainS *data0_frchainP;
extern frchainS *bss0_frchainP;
+/* Dummy so stuff can compile. Should never be used. */
+struct seg_info_trash {
+ struct {
+ unsigned stab_string_size : 1;
+ } stabu;
+ unsigned hadone : 1;
+};
+#define seg_info(S) (abort (), (struct seg_info_trash *) 0)
+
#endif
#endif /* ! BFD_ASSEMBLER */