| 722 |
{ |
{ |
| 723 |
bfd_vma symval; |
bfd_vma symval; |
| 724 |
|
|
| 725 |
|
{ |
| 726 |
|
arelent bfd_reloc; |
| 727 |
|
reloc_howto_type *h; |
| 728 |
|
|
| 729 |
|
elf32_h8_info_to_howto (abfd, &bfd_reloc, irel); |
| 730 |
|
h = bfd_reloc.howto; |
| 731 |
|
} |
| 732 |
/* Keep track of the previous reloc so that we can delete |
/* Keep track of the previous reloc so that we can delete |
| 733 |
some long jumps created by the compiler. */ |
some long jumps created by the compiler. */ |
| 734 |
if (irel != internal_relocs) |
if (irel != internal_relocs) |
| 1001 |
/* This is bsr. */ |
/* This is bsr. */ |
| 1002 |
bfd_put_8 (abfd, 0x55, contents + irel->r_offset - 2); |
bfd_put_8 (abfd, 0x55, contents + irel->r_offset - 2); |
| 1003 |
else |
else |
| 1004 |
abort (); |
/* Might be MOVSD. */ |
| 1005 |
|
break; |
| 1006 |
|
|
| 1007 |
/* Fix the relocation's type. */ |
/* Fix the relocation's type. */ |
| 1008 |
irel->r_info = ELF32_R_INFO (ELF32_R_SYM (irel->r_info), |
irel->r_info = ELF32_R_INFO (ELF32_R_SYM (irel->r_info), |
| 1215 |
if (value <= 0x7fff || value >= 0xffff8000u) |
if (value <= 0x7fff || value >= 0xffff8000u) |
| 1216 |
{ |
{ |
| 1217 |
unsigned char code; |
unsigned char code; |
| 1218 |
|
unsigned char op0, op1, op2, op3; |
| 1219 |
|
unsigned char *op_ptr; |
| 1220 |
|
|
| 1221 |
/* Note that we've changed the relocs, section contents, |
/* Note that we've changed the relocs, section contents, |
| 1222 |
etc. */ |
etc. */ |
| 1224 |
elf_section_data (sec)->this_hdr.contents = contents; |
elf_section_data (sec)->this_hdr.contents = contents; |
| 1225 |
symtab_hdr->contents = (unsigned char *) isymbuf; |
symtab_hdr->contents = (unsigned char *) isymbuf; |
| 1226 |
|
|
| 1227 |
|
if (irel->r_offset >= 4) |
| 1228 |
|
{ |
| 1229 |
|
/* Check for 4-byte MOVA relaxation. */ |
| 1230 |
|
int second_reloc = 0; |
| 1231 |
|
|
| 1232 |
|
op_ptr = contents + irel->r_offset - 4; |
| 1233 |
|
|
| 1234 |
|
if (last_reloc) |
| 1235 |
|
{ |
| 1236 |
|
arelent bfd_reloc; |
| 1237 |
|
reloc_howto_type *h; |
| 1238 |
|
bfd_vma last_reloc_size; |
| 1239 |
|
|
| 1240 |
|
elf32_h8_info_to_howto (abfd, &bfd_reloc, last_reloc); |
| 1241 |
|
h = bfd_reloc.howto; |
| 1242 |
|
last_reloc_size = 1 << h->size; |
| 1243 |
|
if (last_reloc->r_offset + last_reloc_size |
| 1244 |
|
== irel->r_offset) |
| 1245 |
|
{ |
| 1246 |
|
op_ptr -= last_reloc_size; |
| 1247 |
|
second_reloc = 1; |
| 1248 |
|
} |
| 1249 |
|
} |
| 1250 |
|
if (irel < irelend) |
| 1251 |
|
{ |
| 1252 |
|
Elf_Internal_Rela *next_reloc = irel + 1; |
| 1253 |
|
arelent bfd_reloc; |
| 1254 |
|
reloc_howto_type *h; |
| 1255 |
|
bfd_vma next_reloc_size; |
| 1256 |
|
|
| 1257 |
|
elf32_h8_info_to_howto (abfd, &bfd_reloc, next_reloc); |
| 1258 |
|
h = bfd_reloc.howto; |
| 1259 |
|
next_reloc_size = 1 << h->size; |
| 1260 |
|
if (next_reloc->r_offset + next_reloc_size |
| 1261 |
|
== irel->r_offset) |
| 1262 |
|
{ |
| 1263 |
|
op_ptr -= next_reloc_size; |
| 1264 |
|
second_reloc = 1; |
| 1265 |
|
} |
| 1266 |
|
} |
| 1267 |
|
|
| 1268 |
|
op0 = bfd_get_8 (abfd, op_ptr + 0); |
| 1269 |
|
op1 = bfd_get_8 (abfd, op_ptr + 1); |
| 1270 |
|
op2 = bfd_get_8 (abfd, op_ptr + 2); |
| 1271 |
|
op3 = bfd_get_8 (abfd, op_ptr + 3); |
| 1272 |
|
|
| 1273 |
|
if (op0 == 0x01 |
| 1274 |
|
&& (op1 & 0xdf) == 0x5f |
| 1275 |
|
&& (op2 & 0x40) == 0x40 |
| 1276 |
|
&& (op3 & 0x80) == 0x80) |
| 1277 |
|
{ |
| 1278 |
|
if ((op2 & 0x08) == 0) |
| 1279 |
|
second_reloc = 1; |
| 1280 |
|
|
| 1281 |
|
if (second_reloc) |
| 1282 |
|
{ |
| 1283 |
|
op3 &= ~0x08; |
| 1284 |
|
bfd_put_8 (abfd, op3, op_ptr + 3); |
| 1285 |
|
} |
| 1286 |
|
else |
| 1287 |
|
{ |
| 1288 |
|
op2 &= ~0x08; |
| 1289 |
|
bfd_put_8 (abfd, op2, op_ptr + 2); |
| 1290 |
|
} |
| 1291 |
|
goto r_h8_dir32a16_common; |
| 1292 |
|
} |
| 1293 |
|
} |
| 1294 |
|
|
| 1295 |
|
/* Now check for short version of MOVA. */ |
| 1296 |
|
op_ptr = contents + irel->r_offset - 2; |
| 1297 |
|
op0 = bfd_get_8 (abfd, op_ptr + 0); |
| 1298 |
|
op1 = bfd_get_8 (abfd, op_ptr + 1); |
| 1299 |
|
|
| 1300 |
|
if (op0 == 0x7a |
| 1301 |
|
&& (op1 & 0x88) == 0x80) |
| 1302 |
|
{ |
| 1303 |
|
op1 |= 0x08; |
| 1304 |
|
bfd_put_8 (abfd, op1, op_ptr + 1); |
| 1305 |
|
goto r_h8_dir32a16_common; |
| 1306 |
|
} |
| 1307 |
|
|
| 1308 |
/* Get the opcode. */ |
/* Get the opcode. */ |
| 1309 |
code = bfd_get_8 (abfd, contents + irel->r_offset - 1); |
code = bfd_get_8 (abfd, contents + irel->r_offset - 1); |
| 1310 |
|
|
| 1315 |
|
|
| 1316 |
bfd_put_8 (abfd, code, contents + irel->r_offset - 1); |
bfd_put_8 (abfd, code, contents + irel->r_offset - 1); |
| 1317 |
|
|
| 1318 |
|
r_h8_dir32a16_common: |
| 1319 |
/* Fix the relocation's type. */ |
/* Fix the relocation's type. */ |
| 1320 |
irel->r_info = ELF32_R_INFO (ELF32_R_SYM (irel->r_info), |
irel->r_info = ELF32_R_INFO (ELF32_R_SYM (irel->r_info), |
| 1321 |
R_H8_DIR16); |
R_H8_DIR16); |