/* BFD back-end for ARM COFF files.
- Copyright 1990, 91, 92, 93, 94, 95, 96, 97, 1998
+ Copyright 1990, 91, 92, 93, 94, 95, 96, 97, 98, 1999
Free Software Foundation, Inc.
Written by Cygnus Support.
return bfd_reloc_continue;
}
+/* If USER_LABEL_PREFIX is defined as "_" (see coff_arm_is_local_label_name()
+ in this file), then TARGET_UNDERSCORE should be defined, otherwise it
+ should not. */
+#ifndef TARGET_UNDERSCORE
#define TARGET_UNDERSCORE '_'
+#endif
#ifndef PCRELOFFSET
#define PCRELOFFSET true
*addendp -= pe_data(sec->output_section->owner)->pe_opthdr.ImageBase;
}
- /* The relocation_section function will skip pcrel_offset relocs
- when doing a relocateable link. However, we want to convert
- ARM26 to ARM26D relocs if possible. We return a fake howto in
- this case without pcrel_offset set, and adjust the addend to
- compensate. */
- if (rel->r_type == ARM_26
- && h != NULL
- && (h->root.type == bfd_link_hash_defined
- || h->root.type == bfd_link_hash_defweak)
- && h->root.u.def.section->output_section == sec->output_section)
- {
- static reloc_howto_type fake_arm26_reloc =
- HOWTO (ARM_26,
- 2,
- 2,
- 24,
- true,
- 0,
- complain_overflow_signed,
- aoutarm_fix_pcrel_26 ,
- "ARM_26",
- false,
- 0x00ffffff,
- 0x00ffffff,
- false);
-
- *addendp -= rel->r_vaddr - sec->vma;
- return & fake_arm26_reloc;
- }
-
return howto;
}
return & ret->root.root;
}
+static
+arm_emit_base_file_entry (info, output_bfd, input_section, reloc_offset)
+ struct bfd_link_info *info;
+ bfd *output_bfd;
+ asection *input_section;
+ bfd_vma reloc_offset;
+{
+ bfd_vma addr = reloc_offset
+ - input_section->vma
+ + input_section->output_offset
+ + input_section->output_section->vma;
+
+ if (coff_data(output_bfd)->pe)
+ addr -= pe_data(output_bfd)->pe_opthdr.ImageBase;
+ fwrite (&addr, 1, sizeof (addr), (FILE *) info->base_file);
+
+}
\f
/* The thumb form of a long branch is a bit finicky, because the offset
encoding is split over two fields, each in it's own instruction. They
addend = 0;
- howto = bfd_coff_rtype_to_howto (input_bfd, input_section, rel, h,
+ howto = coff_rtype_to_howto (input_bfd, input_section, rel, h,
sym, &addend);
if (howto == NULL)
return false;
+ /* The relocation_section function will skip pcrel_offset relocs
+ when doing a relocateable link. However, we want to convert
+ ARM26 to ARM26D relocs if possible. We return a fake howto in
+ this case without pcrel_offset set, and adjust the addend to
+ compensate. */
+ if (rel->r_type == ARM_26
+ && h != NULL
+ && info->relocateable
+ && (h->root.type == bfd_link_hash_defined
+ || h->root.type == bfd_link_hash_defweak)
+ && h->root.u.def.section->output_section == input_section->output_section)
+ {
+ static reloc_howto_type fake_arm26_reloc =
+ HOWTO (ARM_26,
+ 2,
+ 2,
+ 24,
+ true,
+ 0,
+ complain_overflow_signed,
+ aoutarm_fix_pcrel_26 ,
+ "ARM_26",
+ false,
+ 0x00ffffff,
+ 0x00ffffff,
+ false);
+
+ addend -= rel->r_vaddr - input_section->vma;
+ howto = &fake_arm26_reloc;
+ }
+
/* If we are doing a relocateable link, then we can just ignore
a PC relative reloc that is pcrel_offset. It will already
have the correct value. If this is not a relocateable link,
addend += sym->n_value;
}
- /* If we are doing a relocateable link, then we can just ignore
- a PC relative reloc that is pcrel_offset. It will already
- have the correct value. */
- if (info->relocateable
- && howto->pc_relative
- && howto->pcrel_offset)
- continue;
-
val = 0;
if (h == NULL)
/* It's a thumb address. Add the low order bit. */
bfd_put_32 (output_bfd, h_val | a2t3_func_addr_insn,
s->contents + my_offset + 8);
+
+ if (info->base_file)
+ arm_emit_base_file_entry (info, output_bfd, s,
+ my_offset + 8);
+
}
BFD_ASSERT (my_offset <= globals->arm_glue_size);
bfd_put_32 (output_bfd, tmp, contents + rel->r_vaddr
- input_section->vma);
-
done = 1;
}
}
/* Store the address of the function in the last word of the stub. */
bfd_put_32 (output_bfd, h_val,
s->contents + my_offset + 16);
+
+ if (info->base_file)
+ arm_emit_base_file_entry (info, output_bfd, s, my_offset + 16);
}
else
{
bfd_put_32 (output_bfd,
t2a3_b_insn | ((ret_offset >> 2) & 0x00FFFFFF),
s->contents + my_offset + 4);
+
}
}
{
/* Emit a reloc if the backend thinks it needs it. */
if (sym && pe_data(output_bfd)->in_reloc_p(output_bfd, howto))
- {
- /* relocation to a symbol in a section which
- isn't absolute - we output the address here
- to a file */
- bfd_vma addr = rel->r_vaddr
- - input_section->vma
- + input_section->output_offset
- + input_section->output_section->vma;
- if (coff_data(output_bfd)->pe)
- addr -= pe_data(output_bfd)->pe_opthdr.ImageBase;
- /* FIXME: Shouldn't 4 be sizeof (addr)? */
- fwrite (&addr, 1,4, (FILE *) info->base_file);
- }
+ arm_emit_base_file_entry (info, output_bfd, input_section, rel->r_vaddr);
}
#if 1 /* THUMBEXTENSION */
Probably not, but it works, and if it works it don't need fixing! nickc@cygnus.com */
/* Only perform this fix during the final link, not a relocatable link. nickc@cygnus.com */
if (! info->relocateable
- && rel->r_type == ARM_32)
+ && (rel->r_type == ARM_32 || rel->r_type == ARM_RVA32))
{
/* Determine if we need to set the bottom bit of a relocated address
because the address is the address of a Thumb code symbol. */
return true;
}
-#ifndef COFF_WITH_PE
+#ifdef COFF_IMAGE_WITH_PE
+static
+#endif
boolean
bfd_arm_allocate_interworking_sections (info)
struct bfd_link_info * info;
/* Select a BFD to be used to hold the sections used by the glue code.
This function is called from the linker scripts in ld/emultempl/
{armcoff/pe}.em */
+#ifdef COFF_IMAGE_WITH_PE
+static
+#endif
boolean
bfd_arm_get_bfd_for_interworking (abfd, info)
bfd * abfd;
return true;
}
+#ifdef COFF_IMAGE_WITH_PE
+static
+#endif
boolean
bfd_arm_process_before_allocation (abfd, info, support_old_code)
bfd * abfd;
return true;
}
-#endif /* ! COFF_WITH_PE */
-
#define coff_bfd_reloc_type_lookup coff_arm_reloc_type_lookup
#define coff_relocate_section coff_arm_relocate_section
#define coff_bfd_is_local_label_name coff_arm_is_local_label_name
}
/* Note: the definitions here of LOCAL_LABEL_PREFIX and USER_LABEL_PREIFX
- *must* match the definitions on gcc/config/arm/semi.h. */
+ *must* match the definitions in gcc/config/arm/coff.h and semi.h */
#define LOCAL_LABEL_PREFIX "."
+#ifndef USER_LABEL_PREFIX
#define USER_LABEL_PREFIX "_"
+#endif
static boolean
coff_arm_is_local_label_name (abfd, name)