aboutsummaryrefslogtreecommitdiff
path: root/ld/ldwrite.c
diff options
context:
space:
mode:
Diffstat (limited to 'ld/ldwrite.c')
-rw-r--r--ld/ldwrite.c60
1 files changed, 57 insertions, 3 deletions
diff --git a/ld/ldwrite.c b/ld/ldwrite.c
index 376e650..1dacb3d 100644
--- a/ld/ldwrite.c
+++ b/ld/ldwrite.c
@@ -48,13 +48,17 @@ build_link_order (statement)
it just does the output directly. */
{
bfd_vma value = statement->data_statement.value;
- bfd_byte play_area[LONG_SIZE];
+ bfd_byte play_area[QUAD_SIZE];
unsigned int size = 0;
asection *output_section = statement->data_statement.output_section;
ASSERT (output_section->owner == output_bfd);
switch (statement->data_statement.type)
{
+ case QUAD:
+ bfd_put_64 (output_bfd, value, play_area);
+ size = QUAD_SIZE;
+ break;
case LONG:
bfd_put_32 (output_bfd, value, play_area);
size = LONG_SIZE;
@@ -79,6 +83,52 @@ build_link_order (statement)
}
break;
+ case lang_reloc_statement_enum:
+ {
+ lang_reloc_statement_type *rs;
+ asection *output_section;
+ struct bfd_link_order *link_order;
+
+ rs = &statement->reloc_statement;
+
+ output_section = rs->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");
+
+ link_order->offset = rs->output_vma;
+ link_order->size = bfd_get_reloc_size (rs->howto);
+
+ 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->section != (asection *) NULL)
+ {
+ ASSERT (rs->name == (const char *) NULL);
+ link_order->type = bfd_section_reloc_link_order;
+ if (rs->section->owner == output_bfd)
+ link_order->u.reloc.p->u.section = rs->section;
+ else
+ {
+ link_order->u.reloc.p->u.section = rs->section->output_section;
+ link_order->u.reloc.p->addend += rs->section->output_offset;
+ }
+ }
+ else
+ {
+ ASSERT (rs->name != (const char *) NULL);
+ link_order->type = bfd_symbol_reloc_link_order;
+ link_order->u.reloc.p->u.name = rs->name;
+ }
+ }
+ break;
+
case lang_input_section_enum:
/* Create a new link_order in the output section with this
attached */
@@ -109,7 +159,10 @@ build_link_order (statement)
link_order->u.indirect.section = i;
ASSERT (i->output_section == output_section);
}
- link_order->size = bfd_section_size (i->owner, i);
+ if (i->_cooked_size)
+ link_order->size = i->_cooked_size;
+ else
+ link_order->size = bfd_get_section_size_before_reloc (i);
link_order->offset = i->output_offset;
}
}
@@ -149,7 +202,7 @@ ldwrite ()
lang_for_each_statement (build_link_order);
if (! bfd_final_link (output_bfd, &link_info))
- einfo ("%F%P: %B: %E\n", output_bfd);
+ einfo ("%F%P: final link failed: %E\n", output_bfd);
if (config.map_file)
{
@@ -226,6 +279,7 @@ print_file_stuff (f)
/* Print a symbol. */
+/*ARGSUSED*/
static boolean
print_symbol (p, ignore)
struct bfd_link_hash_entry *p;