/* ldwrite.c -- write out the linked file
Copyright 1991, 1992, 1993, 1994, 1995, 1996, 1997, 1998, 2000, 2002,
- 2003, 2004, 2005 Free Software Foundation, Inc.
+ 2003, 2004, 2005, 2006, 2007, 2008, 2010, 2012
+ Free Software Foundation, Inc.
Written by Steve Chamberlain sac@cygnus.com
-This file is part of GLD, the Gnu Linker.
+ This file is part of the GNU Binutils.
-This program 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 of the License, or
-(at your option) any later version.
+ This program 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 3 of the License, or
+ (at your option) any later version.
-This program is distributed in the hope that it will be useful,
-but WITHOUT ANY WARRANTY; without even the implied warranty of
-MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
-GNU General Public License for more details.
+ This program is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ GNU General Public License for more details.
-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., 51 Franklin Street - Fifth Floor, Boston, MA 02110-1301, USA. */
+ 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., 51 Franklin Street - Fifth Floor, Boston,
+ MA 02110-1301, USA. */
-#include "bfd.h"
#include "sysdep.h"
+#include "bfd.h"
#include "bfdlink.h"
#include "libiberty.h"
#include "safe-ctype.h"
bfd_boolean big_endian = FALSE;
output_section = statement->data_statement.output_section;
- ASSERT (output_section->owner == output_bfd);
+ ASSERT (output_section->owner == link_info.output_bfd);
- link_order = bfd_new_link_order (output_bfd, output_section);
+ if (!((output_section->flags & SEC_HAS_CONTENTS) != 0
+ || ((output_section->flags & SEC_LOAD) != 0
+ && (output_section->flags & SEC_THREAD_LOCAL))))
+ break;
+
+ link_order = bfd_new_link_order (link_info.output_bfd, output_section);
if (link_order == NULL)
einfo (_("%P%F: bfd_new_link_order failed\n"));
link_order->type = bfd_data_link_order;
- link_order->offset = statement->data_statement.output_vma;
- link_order->u.data.contents = xmalloc (QUAD_SIZE);
+ link_order->offset = statement->data_statement.output_offset;
+ link_order->u.data.contents = (bfd_byte *) xmalloc (QUAD_SIZE);
value = statement->data_statement.value;
By convention, the bfd_put routines for an unknown
endianness are big endian, so we must swap here if the
input file is little endian. */
- if (bfd_big_endian (output_bfd))
+ if (bfd_big_endian (link_info.output_bfd))
big_endian = TRUE;
- else if (bfd_little_endian (output_bfd))
+ else if (bfd_little_endian (link_info.output_bfd))
big_endian = FALSE;
else
{
}
}
- ASSERT (output_section->owner == output_bfd);
+ ASSERT (output_section->owner == link_info.output_bfd);
switch (statement->data_statement.type)
{
case QUAD:
case SQUAD:
if (sizeof (bfd_vma) >= QUAD_SIZE)
- bfd_put_64 (output_bfd, value, link_order->u.data.contents);
+ bfd_put_64 (link_info.output_bfd, value,
+ link_order->u.data.contents);
else
{
bfd_vma high;
high = 0;
else
high = (bfd_vma) -1;
- bfd_put_32 (output_bfd, high,
+ bfd_put_32 (link_info.output_bfd, high,
(link_order->u.data.contents
+ (big_endian ? 0 : 4)));
- bfd_put_32 (output_bfd, value,
+ bfd_put_32 (link_info.output_bfd, value,
(link_order->u.data.contents
+ (big_endian ? 4 : 0)));
}
link_order->size = QUAD_SIZE;
break;
case LONG:
- bfd_put_32 (output_bfd, value, link_order->u.data.contents);
+ bfd_put_32 (link_info.output_bfd, value,
+ link_order->u.data.contents);
link_order->size = LONG_SIZE;
break;
case SHORT:
- bfd_put_16 (output_bfd, value, link_order->u.data.contents);
+ bfd_put_16 (link_info.output_bfd, value,
+ link_order->u.data.contents);
link_order->size = SHORT_SIZE;
break;
case BYTE:
- bfd_put_8 (output_bfd, value, link_order->u.data.contents);
+ bfd_put_8 (link_info.output_bfd, value,
+ link_order->u.data.contents);
link_order->size = BYTE_SIZE;
break;
default:
abort ();
}
+ link_order->u.data.size = link_order->size;
}
break;
rs = &statement->reloc_statement;
output_section = rs->output_section;
- ASSERT (output_section->owner == output_bfd);
+ ASSERT (output_section->owner == link_info.output_bfd);
- link_order = bfd_new_link_order (output_bfd, output_section);
+ if (!((output_section->flags & SEC_HAS_CONTENTS) != 0
+ || ((output_section->flags & SEC_LOAD) != 0
+ && (output_section->flags & SEC_THREAD_LOCAL))))
+ break;
+
+ link_order = bfd_new_link_order (link_info.output_bfd, output_section);
if (link_order == NULL)
einfo (_("%P%F: bfd_new_link_order failed\n"));
- link_order->offset = rs->output_vma;
+ link_order->offset = rs->output_offset;
link_order->size = bfd_get_reloc_size (rs->howto);
- link_order->u.reloc.p = xmalloc (sizeof (struct bfd_link_order_reloc));
+ link_order->u.reloc.p = (struct bfd_link_order_reloc *)
+ xmalloc (sizeof (struct bfd_link_order_reloc));
link_order->u.reloc.p->reloc = rs->reloc;
link_order->u.reloc.p->addend = rs->addend_value;
if (rs->name == NULL)
{
link_order->type = bfd_section_reloc_link_order;
- if (rs->section->owner == output_bfd)
+ if (rs->section->owner == link_info.output_bfd)
link_order->u.reloc.p->u.section = rs->section;
else
{
break;
case lang_input_section_enum:
- /* Create a new link_order in the output section with this
- attached */
- if (!statement->input_section.ifile->just_syms_flag
- && (statement->input_section.section->flags & SEC_EXCLUDE) == 0)
- {
- asection *i = statement->input_section.section;
- asection *output_section = i->output_section;
+ {
+ /* Create a new link_order in the output section with this
+ attached */
+ asection *i = statement->input_section.section;
+
+ if (i->sec_info_type != SEC_INFO_TYPE_JUST_SYMS
+ && (i->flags & SEC_EXCLUDE) == 0)
+ {
+ asection *output_section = i->output_section;
+ struct bfd_link_order *link_order;
- ASSERT (output_section->owner == output_bfd);
+ ASSERT (output_section->owner == link_info.output_bfd);
- if ((output_section->flags & SEC_HAS_CONTENTS) != 0
- || ((output_section->flags & SEC_LOAD) != 0
- && (output_section->flags & SEC_THREAD_LOCAL)))
- {
- struct bfd_link_order *link_order;
+ if (!((output_section->flags & SEC_HAS_CONTENTS) != 0
+ || ((output_section->flags & SEC_LOAD) != 0
+ && (output_section->flags & SEC_THREAD_LOCAL))))
+ break;
- link_order = bfd_new_link_order (output_bfd, output_section);
+ link_order = bfd_new_link_order (link_info.output_bfd,
+ output_section);
- if (i->flags & SEC_NEVER_LOAD)
- {
- /* We've got a never load section inside one which
- is going to be output, we'll change it into a
- fill. */
- link_order->type = bfd_data_link_order;
- link_order->u.data.contents = (unsigned char *) "";
- link_order->u.data.size = 1;
- }
- else
- {
- link_order->type = bfd_indirect_link_order;
- link_order->u.indirect.section = i;
- ASSERT (i->output_section == output_section);
- }
- link_order->size = i->size;
- link_order->offset = i->output_offset;
- }
- }
+ if ((i->flags & SEC_NEVER_LOAD) != 0
+ && (i->flags & SEC_DEBUGGING) == 0)
+ {
+ /* We've got a never load section inside one which is
+ going to be output, we'll change it into a fill. */
+ link_order->type = bfd_data_link_order;
+ link_order->u.data.contents = (unsigned char *) "";
+ link_order->u.data.size = 1;
+ }
+ else
+ {
+ link_order->type = bfd_indirect_link_order;
+ link_order->u.indirect.section = i;
+ ASSERT (i->output_section == output_section);
+ }
+ link_order->size = i->size;
+ link_order->offset = i->output_offset;
+ }
+ }
break;
case lang_padding_statement_enum:
output_section = statement->padding_statement.output_section;
ASSERT (statement->padding_statement.output_section->owner
- == output_bfd);
- if ((output_section->flags & SEC_HAS_CONTENTS) != 0)
- {
- link_order = bfd_new_link_order (output_bfd, output_section);
- link_order->type = bfd_data_link_order;
- link_order->size = statement->padding_statement.size;
- link_order->offset = statement->padding_statement.output_offset;
- link_order->u.data.contents = statement->padding_statement.fill->data;
- link_order->u.data.size = statement->padding_statement.fill->size;
- }
+ == link_info.output_bfd);
+
+ if (!((output_section->flags & SEC_HAS_CONTENTS) != 0
+ || ((output_section->flags & SEC_LOAD) != 0
+ && (output_section->flags & SEC_THREAD_LOCAL))))
+ break;
+
+ link_order = bfd_new_link_order (link_info.output_bfd,
+ output_section);
+ link_order->type = bfd_data_link_order;
+ link_order->size = statement->padding_statement.size;
+ link_order->offset = statement->padding_statement.output_offset;
+ link_order->u.data.contents = statement->padding_statement.fill->data;
+ link_order->u.data.size = statement->padding_statement.fill->size;
}
break;
static bfd_boolean
unsplittable_name (const char *name)
{
- if (strncmp (name, ".stab", 5) == 0)
+ if (CONST_STRNEQ (name, ".stab"))
{
/* There are several stab like string sections. We pattern match on
".stab...str" */
/* Invent a section name from the section name and a dotted numeric
suffix. */
len = strlen (name);
- tname = xmalloc (len + 1);
+ tname = (char *) xmalloc (len + 1);
memcpy (tname, name, len + 1);
/* Remove a dotted number suffix, from a previous split link. */
while (len && ISDIGIT (tname[len-1]))
{
/* Some section names cannot be truncated, as the name is
used to locate some other section. */
- if (strncmp (name, ".stab", 5) == 0
+ if (CONST_STRNEQ (name, ".stab")
|| strcmp (name, "$GDB_SYMBOLS$") == 0)
{
einfo (_ ("%F%P: cannot create split section name for %s\n"), name);
}
tname[5] = 0;
}
-
+
if ((sname = bfd_get_unique_section_name (abfd, tname, count)) == NULL
|| (n = bfd_make_section_anyway (abfd, sname)) == NULL
|| (h = bfd_link_hash_lookup (link_info.hash,
return NULL;
}
free (tname);
-
+
/* Set up section symbol. */
h->type = bfd_link_hash_defined;
h->u.def.value = 0;
n->orelocation = 0;
n->reloc_count = 0;
n->alignment_power = s->alignment_power;
+
+ bfd_copy_private_section_data (abfd, s, abfd, n);
+
return n;
}
if (config.split_by_reloc != (unsigned) -1
|| config.split_by_file != (bfd_size_type) -1)
- split_sections (output_bfd, &link_info);
- if (!bfd_final_link (output_bfd, &link_info))
+ split_sections (link_info.output_bfd, &link_info);
+ if (!bfd_final_link (link_info.output_bfd, &link_info))
{
/* If there was an error recorded, print it out. Otherwise assume
an appropriate error message like unknown symbol was printed