/* 32-bit ELF support for ARM
- Copyright 1998, 1999, 2000 Free Software Foundation, Inc.
+ Copyright 1998, 1999, 2000, 2001 Free Software Foundation, Inc.
This file is part of BFD, the Binary File Descriptor library.
this. It is set up so that any shared library function that is
called before the relocation has been set up calls the dynamic
linker first. */
-static const bfd_byte elf32_arm_plt0_entry [PLT_ENTRY_SIZE] =
+static const unsigned long elf32_arm_plt0_entry [PLT_ENTRY_SIZE / 4] =
{
- 0x04, 0xe0, 0x2d, 0xe5, /* str lr, [sp, #-4]! */
- 0x10, 0xe0, 0x9f, 0xe5, /* ldr lr, [pc, #16] */
- 0x0e, 0xe0, 0x8f, 0xe0, /* adr lr, pc, lr */
- 0x08, 0xf0, 0xbe, 0xe5 /* ldr pc, [lr, #8]! */
+ 0xe52de004, /* str lr, [sp, #-4]! */
+ 0xe59fe010, /* ldr lr, [pc, #16] */
+ 0xe08fe00e, /* add lr, pc, lr */
+ 0xe5bef008 /* ldr pc, [lr, #8]! */
};
/* Subsequent entries in a procedure linkage table look like
this. */
-static const bfd_byte elf32_arm_plt_entry [PLT_ENTRY_SIZE] =
+static const unsigned long elf32_arm_plt_entry [PLT_ENTRY_SIZE / 4] =
{
- 0x04, 0xc0, 0x9f, 0xe5, /* ldr ip, [pc, #4] */
- 0x0c, 0xc0, 0x8f, 0xe0, /* add ip, pc, ip */
- 0x00, 0xf0, 0x9c, 0xe5, /* ldr pc, [ip] */
- 0x00, 0x00, 0x00, 0x00 /* offset to symbol in got */
+ 0xe59fc004, /* ldr ip, [pc, #4] */
+ 0xe08fc00c, /* add ip, pc, ip */
+ 0xe59cf000, /* ldr pc, [ip] */
+ 0x00000000 /* offset to symbol in got */
};
/* The ARM linker needs to keep track of the number of relocs that it
bfd_signed_vma signed_addend;
struct elf32_arm_link_hash_table * globals;
+ /* If the start address has been set, then set the EF_ARM_HASENTRY
+ flag. Setting this more than once is redundant, but the cost is
+ not too high, and it keeps the code simple.
+
+ The test is done here, rather than somewhere else, because the
+ start address is only set just before the final link commences.
+
+ Note - if the user deliberately sets a start address of 0, the
+ flag will not be set. */
+ if (bfd_get_start_address (output_bfd) != 0)
+ elf_elfheader (output_bfd)->e_flags |= EF_ARM_HASENTRY;
+
globals = elf32_arm_hash_table (info);
dynobj = elf_hash_table (info)->dynobj;
case R_ARM_REL32:
value -= (input_section->output_section->vma
- + input_section->output_offset);
+ + input_section->output_offset + rel->r_offset);
value += addend;
break;
}
if ((in_flags & EF_ARM_INTERWORK) != (out_flags & EF_ARM_INTERWORK))
_bfd_error_handler (_("\
Warning: %s %s interworking, whereas %s %s"),
- bfd_get_filename (ibfd),
- in_flags & EF_ARM_INTERWORK ? _("supports") : _("does not support"),
- bfd_get_filename (obfd),
- out_flags & EF_ARM_INTERWORK ? _("does not") : _("does"));
+ bfd_get_filename (ibfd),
+ in_flags & EF_ARM_INTERWORK ? _("supports") : _("does not support"),
+ bfd_get_filename (obfd),
+ out_flags & EF_ARM_INTERWORK ? _("does") : _("does not"));
}
return flags_compatible;
got_offset = (plt_index + 3) * 4;
/* Fill in the entry in the procedure linkage table. */
- memcpy (splt->contents + h->plt.offset,
- elf32_arm_plt_entry,
- PLT_ENTRY_SIZE);
+ bfd_put_32 (output_bfd, elf32_arm_plt_entry[0],
+ splt->contents + h->plt.offset + 0);
+ bfd_put_32 (output_bfd, elf32_arm_plt_entry[1],
+ splt->contents + h->plt.offset + 4);
+ bfd_put_32 (output_bfd, elf32_arm_plt_entry[2],
+ splt->contents + h->plt.offset + 8);
bfd_put_32 (output_bfd,
(sgot->output_section->vma
+ sgot->output_offset
/* Mark the symbol as undefined, rather than as defined in
the .plt section. Leave the value alone. */
sym->st_shndx = SHN_UNDEF;
+ /* If the symbol is weak, we do need to clear the value.
+ Otherwise, the PLT entry would provide a definition for
+ the symbol even if the symbol wasn't defined anywhere,
+ and so the symbol would never be NULL. */
+ if ((h->elf_link_hash_flags & ELF_LINK_HASH_REF_REGULAR_NONWEAK)
+ == 0)
+ sym->st_value = 0;
}
}
/* Fill in the first entry in the procedure linkage table. */
if (splt->_raw_size > 0)
- memcpy (splt->contents, elf32_arm_plt0_entry, PLT_ENTRY_SIZE);
+ {
+ bfd_put_32 (output_bfd, elf32_arm_plt0_entry[0], splt->contents + 0);
+ bfd_put_32 (output_bfd, elf32_arm_plt0_entry[1], splt->contents + 4);
+ bfd_put_32 (output_bfd, elf32_arm_plt0_entry[2], splt->contents + 8);
+ bfd_put_32 (output_bfd, elf32_arm_plt0_entry[3], splt->contents + 12);
+ }
/* UnixWare sets the entsize of .plt to 4, although that doesn't
really seem like the right value. */