/* ELF object file format
Copyright 1992, 1993, 1994, 1995, 1996, 1997, 1998, 1999, 2000,
- 2001, 2002, 2003, 2004 Free Software Foundation, Inc.
+ 2001, 2002, 2003, 2004, 2005, 2006 Free Software Foundation, Inc.
This file is part of GAS, the GNU Assembler.
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, 59 Temple Place - Suite 330, Boston, MA
- 02111-1307, USA. */
+ Software Foundation, 51 Franklin Street - Fifth Floor, Boston, MA
+ 02110-1301, USA. */
#define OBJ_HEADER "obj-elf.h"
#include "as.h"
#include "elf/i370.h"
#endif
+#ifdef TC_I386
+#include "elf/x86-64.h"
+#endif
+
static void obj_elf_line (int);
static void obj_elf_size (int);
static void obj_elf_type (int);
static void obj_elf_popsection (int);
static void obj_elf_tls_common (int);
static void obj_elf_lcomm (int);
+static void obj_elf_struct (int);
static const pseudo_typeS elf_pseudo_table[] =
{
/* These are used for dwarf2. */
{ "file", (void (*) (int)) dwarf2_directive_file, 0 },
{ "loc", dwarf2_directive_loc, 0 },
+ { "loc_mark_labels", dwarf2_directive_loc_mark_labels, 0 },
/* We need to trap the section changing calls to handle .previous. */
{"data", obj_elf_data, 0},
+ {"offset", obj_elf_struct, 0},
+ {"struct", obj_elf_struct, 0},
{"text", obj_elf_text, 0},
{"tls_common", obj_elf_tls_common, 0},
/* This is called when the assembler starts. */
+asection *elf_com_section_ptr;
+
void
elf_begin (void)
{
symbol_table_insert (section_symbol (s));
s = bfd_get_section_by_name (stdoutput, BSS_SECTION_NAME);
symbol_table_insert (section_symbol (s));
+ elf_com_section_ptr = bfd_com_section_ptr;
}
void
}
#ifdef NEED_ECOFF_DEBUG
- ecoff_new_file (s);
+ ecoff_new_file (s, appfile);
#endif
}
/* Called from read.c:s_comm after we've parsed .comm symbol, size.
Parse a possible alignment value. */
-static symbolS *
+symbolS *
elf_common_parse (int ignore ATTRIBUTE_UNUSED, symbolS *symbolP, addressT size)
{
addressT align = 0;
S_SET_VALUE (symbolP, size);
S_SET_ALIGN (symbolP, align);
S_SET_EXTERNAL (symbolP);
- S_SET_SEGMENT (symbolP, bfd_com_section_ptr);
+ S_SET_SEGMENT (symbolP, elf_com_section_ptr);
}
symbol_get_bfdsym (symbolP)->flags |= BSF_OBJECT;
asection *old_sec;
segT sec;
flagword flags;
+ const struct elf_backend_data *bed;
const struct bfd_elf_special_section *ssect;
#ifdef md_flush_pending_output
else
sec = subseg_force_new (name, 0);
- ssect = _bfd_elf_get_sec_type_attr (stdoutput, name);
+ bed = get_elf_backend_data (stdoutput);
+ ssect = (*bed->get_sec_type_attr) (stdoutput, sec);
if (ssect != NULL)
{
.section .init_array,"aw",@progbits
for __attribute__ ((section (".init_array"))).
+ "@progbits" is incorrect. Also for x86-64 large bss
+ sections, gcc, as of 2005-07-06, will emit
+
+ .section .lbss,"aw",@progbits
+
"@progbits" is incorrect. */
+#ifdef TC_I386
+ && (bed->s->arch_size != 64
+ || !(ssect->attr & SHF_X86_64_LARGE))
+#endif
&& ssect->type != SHT_INIT_ARRAY
&& ssect->type != SHT_FINI_ARRAY
&& ssect->type != SHT_PREINIT_ARRAY)
else if (attr == SHF_EXECINSTR
&& strcmp (name, ".note.GNU-stack") == 0)
override = TRUE;
+#ifdef TC_ALPHA
+ /* A section on Alpha may have SHF_ALPHA_GPREL. */
+ else if ((attr & ~ssect->attr) == SHF_ALPHA_GPREL)
+ override = TRUE;
+#endif
else
{
if (group_name == NULL)
#endif
}
+/* Change to the *ABS* section. */
+
+void
+obj_elf_struct (int i)
+{
+#ifdef md_flush_pending_output
+ md_flush_pending_output ();
+#endif
+
+ previous_section = now_seg;
+ previous_subsection = now_subseg;
+ s_struct (i);
+
+#ifdef md_elf_section_change_hook
+ md_elf_section_change_hook ();
+#endif
+}
+
static void
obj_elf_subsection (int ignore ATTRIBUTE_UNUSED)
{
Elf_Internal_Note i_note;
Elf_External_Note e_note;
asection *note_secp = NULL;
- int len;
SKIP_WHITESPACE ();
if (*input_line_pointer == '\"')
{
+ unsigned int len;
+
++input_line_pointer; /* -> 1st char of string. */
name = input_line_pointer;
*(input_line_pointer - 1) = '\0';
*input_line_pointer = c;
- /* create the .note section */
-
+ /* Create the .note section. */
note_secp = subseg_new (".note", 0);
bfd_set_section_flags (stdoutput,
note_secp,
SEC_HAS_CONTENTS | SEC_READONLY);
- /* process the version string */
-
- len = strlen (name);
+ /* Process the version string. */
+ len = strlen (name) + 1;
- i_note.namesz = ((len + 1) + 3) & ~3; /* round this to word boundary */
- i_note.descsz = 0; /* no description */
+ /* PR 3456: Although the name field is padded out to an 4-byte
+ boundary, the namesz field should not be adjusted. */
+ i_note.namesz = len;
+ i_note.descsz = 0; /* No description. */
i_note.type = NT_VERSION;
p = frag_more (sizeof (e_note.namesz));
md_number_to_chars (p, i_note.namesz, sizeof (e_note.namesz));
md_number_to_chars (p, i_note.descsz, sizeof (e_note.descsz));
p = frag_more (sizeof (e_note.type));
md_number_to_chars (p, i_note.type, sizeof (e_note.type));
- p = frag_more (len + 1);
- strcpy (p, name);
+ p = frag_more (len);
+ memcpy (p, name, len);
frag_align (2, 0, 0);
subseg_set (seg, subseg);
}
else
- {
- as_bad (_("expected quoted string"));
- }
+ as_bad (_("expected quoted string"));
+
demand_empty_rest_of_line ();
}
&& (symbol_get_bfdsym (symp)->flags & BSF_FUNCTION) == 0)
symbol_get_bfdsym (symp)->flags |= BSF_OBJECT;
#endif
-
-#if 0 /* TC_PPC */
- /* If TC_PPC is defined, we used to force the type of a symbol to be
- BSF_OBJECT if it was otherwise unset. This was required by some
- that this is no longer needed, so it is now commented out. */
- if ((symbol_get_bfdsym (symp)->flags
- & (BSF_FUNCTION | BSF_FILE | BSF_SECTION_SYM)) == 0
- && S_IS_DEFINED (symp))
- symbol_get_bfdsym (symp)->flags |= BSF_OBJECT;
-#endif
}
struct group_list
size = 4 * (list.elt_count[i] + 1);
bfd_set_section_size (stdoutput, s, size);
- s->contents = frag_more (size);
+ s->contents = (unsigned char *) frag_more (size);
frag_now->fr_fix = frag_now_fix_octets ();
}