summaryrefslogtreecommitdiff
path: root/gnu/usr.bin/binutils/ld/ldwrite.c
diff options
context:
space:
mode:
Diffstat (limited to 'gnu/usr.bin/binutils/ld/ldwrite.c')
-rw-r--r--gnu/usr.bin/binutils/ld/ldwrite.c89
1 files changed, 65 insertions, 24 deletions
diff --git a/gnu/usr.bin/binutils/ld/ldwrite.c b/gnu/usr.bin/binutils/ld/ldwrite.c
index 7c8e81cbc2e..b56119a39ac 100644
--- a/gnu/usr.bin/binutils/ld/ldwrite.c
+++ b/gnu/usr.bin/binutils/ld/ldwrite.c
@@ -1,5 +1,6 @@
/* ldwrite.c -- write out the linked file
- Copyright (C) 1993 Free Software Foundation, Inc.
+ Copyright (C) 1991, 92, 93, 94, 95, 96, 97, 1998
+ Free Software Foundation, Inc.
Written by Steve Chamberlain sac@cygnus.com
This file is part of GLD, the Gnu Linker.
@@ -32,6 +33,8 @@ Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */
#include "ldmain.h"
static void build_link_order PARAMS ((lang_statement_union_type *));
+static asection *clone_section PARAMS ((bfd *, asection *, int *));
+static void split_sections PARAMS ((bfd *, struct bfd_link_info *));
/* Build link_order structures for the BFD linker. */
@@ -46,13 +49,14 @@ build_link_order (statement)
asection *output_section;
struct bfd_link_order *link_order;
bfd_vma value;
+ boolean big_endian = false;
output_section = statement->data_statement.output_section;
ASSERT (output_section->owner == output_bfd);
link_order = bfd_new_link_order (output_bfd, output_section);
if (link_order == NULL)
- einfo ("%P%F: bfd_new_link_order failed\n");
+ einfo (_("%P%F: bfd_new_link_order failed\n"));
link_order->type = bfd_data_link_order;
link_order->offset = statement->data_statement.output_vma;
@@ -65,25 +69,39 @@ build_link_order (statement)
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)
- && ! bfd_little_endian (output_bfd))
+ if (bfd_big_endian (output_bfd))
+ big_endian = true;
+ else if (bfd_little_endian (output_bfd))
+ big_endian = false;
+ else
{
boolean swap;
swap = false;
- if (command_line.endian == ENDIAN_LITTLE)
- swap = true;
+ if (command_line.endian == ENDIAN_BIG)
+ big_endian = true;
+ else if (command_line.endian == ENDIAN_LITTLE)
+ {
+ big_endian = false;
+ swap = true;
+ }
else if (command_line.endian == ENDIAN_UNSET)
{
- LANG_FOR_EACH_INPUT_STATEMENT (s)
- {
- if (s->the_bfd != NULL)
- {
- if (bfd_little_endian (s->the_bfd))
- swap = true;
- break;
- }
- }
+ big_endian = true;
+ {
+ LANG_FOR_EACH_INPUT_STATEMENT (s)
+ {
+ if (s->the_bfd != NULL)
+ {
+ if (bfd_little_endian (s->the_bfd))
+ {
+ big_endian = false;
+ swap = true;
+ }
+ break;
+ }
+ }
+ }
}
if (swap)
@@ -93,9 +111,14 @@ build_link_order (statement)
switch (statement->data_statement.type)
{
case QUAD:
- bfd_putl64 (value, buffer);
- value = bfd_getb64 (buffer);
- break;
+ case SQUAD:
+ if (sizeof (bfd_vma) >= QUAD_SIZE)
+ {
+ bfd_putl64 (value, buffer);
+ value = bfd_getb64 (buffer);
+ break;
+ }
+ /* Fall through. */
case LONG:
bfd_putl32 (value, buffer);
value = bfd_getb32 (buffer);
@@ -116,7 +139,26 @@ build_link_order (statement)
switch (statement->data_statement.type)
{
case QUAD:
- bfd_put_64 (output_bfd, value, link_order->u.data.contents);
+ case SQUAD:
+ if (sizeof (bfd_vma) >= QUAD_SIZE)
+ bfd_put_64 (output_bfd, value, link_order->u.data.contents);
+ else
+ {
+ bfd_vma high;
+
+ if (statement->data_statement.type == QUAD)
+ high = 0;
+ else if ((value & 0x80000000) == 0)
+ high = 0;
+ else
+ high = (bfd_vma) -1;
+ bfd_put_32 (output_bfd, high,
+ (link_order->u.data.contents
+ + (big_endian ? 0 : 4)));
+ bfd_put_32 (output_bfd, value,
+ (link_order->u.data.contents
+ + (big_endian ? 4 : 0)));
+ }
link_order->size = QUAD_SIZE;
break;
case LONG:
@@ -150,7 +192,7 @@ build_link_order (statement)
link_order = bfd_new_link_order (output_bfd, output_section);
if (link_order == NULL)
- einfo ("%P%F: bfd_new_link_order failed\n");
+ einfo (_("%P%F: bfd_new_link_order failed\n"));
link_order->offset = rs->output_vma;
link_order->size = bfd_get_reloc_size (rs->howto);
@@ -320,7 +362,7 @@ ds (s)
}
else
{
- printf ("%8x something else\n", l->offset);
+ printf (_("%8x something else\n"), l->offset);
}
l = l->next;
}
@@ -360,8 +402,7 @@ sanity_check (abfd)
#define dump(a, b, c)
#endif
-
-void
+static void
split_sections (abfd, info)
bfd *abfd;
struct bfd_link_info *info;
@@ -482,7 +523,7 @@ ldwrite ()
out. */
if (bfd_get_error () != bfd_error_no_error)
- einfo ("%F%P: final link failed: %E\n", output_bfd);
+ einfo (_("%F%P: final link failed: %E\n"), output_bfd);
else
xexit(1);
}