|| signed_check < reloc_signed_min)
overflow = true;
- /* For the BLX(1) instruction remove bit 0 of the adjusted offset.
- Bit 0 can only be set if the upper insn is at a half-word boundary,
- since the destination address, an ARM instruction, must always be
- on a word boundary. The semantics of the BLX (1) instruction,
- however, are that bit 0 in the offset must always be 0, and the
- corresponding bit 1 in the target address will be set from bit
- 1 of the source address. */
- if ((x & 0x18000000) == 0x08000000)
- relocation &= ~0x2;
-
- /* Put the relocation into the correct bits. */
+ /* Put the relocation into the correct bits.
+ For a BLX instruction, make sure that the relocation is rounded up
+ to a word boundary. This follows the semantics of the instruction
+ which specifies that bit 1 of the target address will come from bit
+ 1 of the base address. */
if (bfd_big_endian (input_bfd))
- relocation = (((relocation & 0xffe) >> 1) | ((relocation << 4) & 0x07ff0000));
+ {
+ if ((x & 0x1800) == 0x0800 && (relocation & 0x02))
+ relocation += 2;
+ relocation = (((relocation & 0xffe) >> 1) | ((relocation << 4) & 0x07ff0000));
+ }
else
- relocation = (((relocation & 0xffe) << 15) | ((relocation >> 12) & 0x7ff));
+ {
+ if ((x & 0x18000000) == 0x08000000 && (relocation & 0x02))
+ relocation += 2;
+ relocation = (((relocation & 0xffe) << 15) | ((relocation >> 12) & 0x7ff));
+ }
/* Add the relocation to the correct bits of X. */
x = ((x & ~howto->dst_mask) | relocation);
register asection * s;
char * tmp_name;
struct coff_link_hash_entry * myh;
+ struct bfd_link_hash_entry * bh;
struct coff_arm_link_hash_table * globals;
bfd_vma val;
bfd_size_type amt;
though the section isn't allocated yet, this is where we will be putting
it. */
+ bh = NULL;
val = globals->arm_glue_size + 1;
bfd_coff_link_add_one_symbol (info, globals->bfd_of_glue_owner, tmp_name,
- BSF_GLOBAL, s, val, NULL, true, false,
- (struct bfd_link_hash_entry **) & myh);
+ BSF_GLOBAL, s, val, NULL, true, false, &bh);
free (tmp_name);
register asection * s;
char * tmp_name;
struct coff_link_hash_entry * myh;
+ struct bfd_link_hash_entry * bh;
struct coff_arm_link_hash_table * globals;
bfd_vma val;
bfd_size_type amt;
return; /* we've already seen this guy */
}
+ bh = NULL;
val = globals->thumb_glue_size + 1;
bfd_coff_link_add_one_symbol (info, globals->bfd_of_glue_owner, tmp_name,
- BSF_GLOBAL, s, val, NULL, true, false,
- (struct bfd_link_hash_entry **) &myh);
+ BSF_GLOBAL, s, val, NULL, true, false, &bh);
/* If we mark it 'thumb', the disassembler will do a better job. */
+ myh = (struct coff_link_hash_entry *) bh;
myh->class = C_THUMBEXTFUNC;
free (tmp_name);
sprintf (tmp_name, globals->support_old_code ? BACK_FROM_ARM : CHANGE_TO_ARM, name);
- myh = NULL;
+ bh = NULL;
val = globals->thumb_glue_size + (globals->support_old_code ? 8 : 4);
bfd_coff_link_add_one_symbol (info, globals->bfd_of_glue_owner, tmp_name,
- BSF_LOCAL, s, val, NULL, true, false,
- (struct bfd_link_hash_entry **) & myh);
+ BSF_LOCAL, s, val, NULL, true, false, &bh);
free (tmp_name);