3535#include "elf32-ppc.h"
3636#include "elf-vxworks.h"
3737#include "dwarf2.h"
38+ #include "opcode/ppc.h"
3839
3940typedef enum split16_format_type
4041{
@@ -1455,7 +1456,7 @@ static reloc_howto_type ppc_elf_howto_raw[] = {
14551456 "R_PPC_VLE_LO16A" , /* name */
14561457 FALSE, /* partial_inplace */
14571458 0 , /* src_mask */
1458- 0x1f007ff , /* dst_mask */
1459+ 0x1f07ff , /* dst_mask */
14591460 FALSE), /* pcrel_offset */
14601461
14611462 /* The 16 LSBS in split16d format. */
@@ -1470,7 +1471,7 @@ static reloc_howto_type ppc_elf_howto_raw[] = {
14701471 "R_PPC_VLE_LO16D" , /* name */
14711472 FALSE, /* partial_inplace */
14721473 0 , /* src_mask */
1473- 0x1f07ff , /* dst_mask */
1474+ 0x1f007ff , /* dst_mask */
14741475 FALSE), /* pcrel_offset */
14751476
14761477 /* Bits 16-31 split16a format. */
@@ -1485,7 +1486,7 @@ static reloc_howto_type ppc_elf_howto_raw[] = {
14851486 "R_PPC_VLE_HI16A" , /* name */
14861487 FALSE, /* partial_inplace */
14871488 0 , /* src_mask */
1488- 0x1f007ff , /* dst_mask */
1489+ 0x1f07ff , /* dst_mask */
14891490 FALSE), /* pcrel_offset */
14901491
14911492 /* Bits 16-31 split16d format. */
@@ -1500,7 +1501,7 @@ static reloc_howto_type ppc_elf_howto_raw[] = {
15001501 "R_PPC_VLE_HI16D" , /* name */
15011502 FALSE, /* partial_inplace */
15021503 0 , /* src_mask */
1503- 0x1f07ff , /* dst_mask */
1504+ 0x1f007ff , /* dst_mask */
15041505 FALSE), /* pcrel_offset */
15051506
15061507 /* Bits 16-31 (High Adjusted) in split16a format. */
@@ -1515,7 +1516,7 @@ static reloc_howto_type ppc_elf_howto_raw[] = {
15151516 "R_PPC_VLE_HA16A" , /* name */
15161517 FALSE, /* partial_inplace */
15171518 0 , /* src_mask */
1518- 0x1f007ff , /* dst_mask */
1519+ 0x1f07ff , /* dst_mask */
15191520 FALSE), /* pcrel_offset */
15201521
15211522 /* Bits 16-31 (High Adjusted) in split16d format. */
@@ -1530,7 +1531,7 @@ static reloc_howto_type ppc_elf_howto_raw[] = {
15301531 "R_PPC_VLE_HA16D" , /* name */
15311532 FALSE, /* partial_inplace */
15321533 0 , /* src_mask */
1533- 0x1f07ff , /* dst_mask */
1534+ 0x1f007ff , /* dst_mask */
15341535 FALSE), /* pcrel_offset */
15351536
15361537 /* This reloc is like R_PPC_EMB_SDA21 but only applies to e_add16i
@@ -1577,7 +1578,7 @@ static reloc_howto_type ppc_elf_howto_raw[] = {
15771578 "R_PPC_VLE_SDAREL_LO16A" , /* name */
15781579 FALSE, /* partial_inplace */
15791580 0 , /* src_mask */
1580- 0x1f007ff , /* dst_mask */
1581+ 0x1f07ff , /* dst_mask */
15811582 FALSE), /* pcrel_offset */
15821583
15831584 /* The 16 LSBS relative to _SDA_BASE_ in split16d format. */
@@ -1592,7 +1593,7 @@ static reloc_howto_type ppc_elf_howto_raw[] = {
15921593 "R_PPC_VLE_SDAREL_LO16D" , /* name */
15931594 FALSE, /* partial_inplace */
15941595 0 , /* src_mask */
1595- 0x1f07ff , /* dst_mask */
1596+ 0x1f007ff , /* dst_mask */
15961597 FALSE), /* pcrel_offset */
15971598
15981599 /* Bits 16-31 relative to _SDA_BASE_ in split16a format. */
@@ -1607,7 +1608,7 @@ static reloc_howto_type ppc_elf_howto_raw[] = {
16071608 "R_PPC_VLE_SDAREL_HI16A" , /* name */
16081609 FALSE, /* partial_inplace */
16091610 0 , /* src_mask */
1610- 0x1f007ff , /* dst_mask */
1611+ 0x1f07ff , /* dst_mask */
16111612 FALSE), /* pcrel_offset */
16121613
16131614 /* Bits 16-31 relative to _SDA_BASE_ in split16d format. */
@@ -1622,7 +1623,7 @@ static reloc_howto_type ppc_elf_howto_raw[] = {
16221623 "R_PPC_VLE_SDAREL_HI16D" , /* name */
16231624 FALSE, /* partial_inplace */
16241625 0 , /* src_mask */
1625- 0x1f07ff , /* dst_mask */
1626+ 0x1f007ff , /* dst_mask */
16261627 FALSE), /* pcrel_offset */
16271628
16281629 /* Bits 16-31 (HA) relative to _SDA_BASE split16a format. */
@@ -1637,7 +1638,7 @@ static reloc_howto_type ppc_elf_howto_raw[] = {
16371638 "R_PPC_VLE_SDAREL_HA16A" , /* name */
16381639 FALSE, /* partial_inplace */
16391640 0 , /* src_mask */
1640- 0x1f007ff , /* dst_mask */
1641+ 0x1f07ff , /* dst_mask */
16411642 FALSE), /* pcrel_offset */
16421643
16431644 /* Bits 16-31 (HA) relative to _SDA_BASE split16d format. */
@@ -1652,7 +1653,7 @@ static reloc_howto_type ppc_elf_howto_raw[] = {
16521653 "R_PPC_VLE_SDAREL_HA16D" , /* name */
16531654 FALSE, /* partial_inplace */
16541655 0 , /* src_mask */
1655- 0x1f07ff , /* dst_mask */
1656+ 0x1f007ff , /* dst_mask */
16561657 FALSE), /* pcrel_offset */
16571658
16581659 HOWTO (R_PPC_IRELATIVE , /* type */
@@ -3384,7 +3385,7 @@ ppc_elf_link_hash_table_create (bfd *abfd)
33843385{
33853386 struct ppc_elf_link_hash_table * ret ;
33863387 static struct ppc_elf_params default_params
3387- = { PLT_OLD , 0 , 1 , 0 , 0 , 12 , 0 , 0 };
3388+ = { PLT_OLD , 0 , 1 , 0 , 0 , 12 , 0 , 0 , 0 };
33883389
33893390 ret = bfd_zmalloc (sizeof (struct ppc_elf_link_hash_table ));
33903391 if (ret == NULL )
@@ -4925,16 +4926,56 @@ ppc_elf_merge_private_bfd_data (bfd *ibfd, struct bfd_link_info *info)
49254926
49264927static void
49274928ppc_elf_vle_split16 (bfd * input_bfd ,
4929+ asection * input_section ,
4930+ unsigned long offset ,
49284931 bfd_byte * loc ,
49294932 bfd_vma value ,
4930- split16_format_type split16_format )
4933+ split16_format_type split16_format ,
4934+ bfd_boolean fixup )
49314935{
4932- unsigned int insn , top5 ;
4936+ unsigned int insn , opcode , top5 ;
49334937
49344938 insn = bfd_get_32 (input_bfd , loc );
4939+ opcode = insn & 0xf300f800 ;
4940+ if (opcode == E_OR2I_INSN
4941+ || opcode == E_AND2I_DOT_INSN
4942+ || opcode == E_OR2IS_INSN
4943+ || opcode == E_LIS_INSN
4944+ || opcode == E_AND2IS_DOT_INSN )
4945+ {
4946+ if (split16_format != split16a_type )
4947+ {
4948+ if (fixup )
4949+ split16_format = split16a_type ;
4950+ else
4951+ _bfd_error_handler
4952+ /* xgettext:c-format */
4953+ (_ ("%B(%A+0x%lx): expected 16A style relocation on 0x%08x insn" ),
4954+ input_bfd , input_section , offset , opcode );
4955+ }
4956+ }
4957+ else if (opcode == E_ADD2I_DOT_INSN
4958+ || opcode == E_ADD2IS_INSN
4959+ || opcode == E_CMP16I_INSN
4960+ || opcode == E_MULL2I_INSN
4961+ || opcode == E_CMPL16I_INSN
4962+ || opcode == E_CMPH16I_INSN
4963+ || opcode == E_CMPHL16I_INSN )
4964+ {
4965+ if (split16_format != split16d_type )
4966+ {
4967+ if (fixup )
4968+ split16_format = split16d_type ;
4969+ else
4970+ _bfd_error_handler
4971+ /* xgettext:c-format */
4972+ (_ ("%B(%A+0x%lx): expected 16D style relocation on 0x%08x insn" ),
4973+ input_bfd , input_section , offset , opcode );
4974+ }
4975+ }
49354976 top5 = value & 0xf800 ;
4936- top5 = top5 << (split16_format == split16a_type ? 9 : 5 );
4937- insn &= (split16_format == split16a_type ? ~0x1f007ff : ~0x1f07ff );
4977+ top5 = top5 << (split16_format == split16a_type ? 5 : 9 );
4978+ insn &= (split16_format == split16a_type ? ~0x1f07ff : ~0x1f007ff );
49384979 insn |= top5 ;
49394980 insn |= value & 0x7ff ;
49404981 bfd_put_32 (input_bfd , insn , loc );
@@ -9220,38 +9261,44 @@ ppc_elf_relocate_section (bfd *output_bfd,
92209261
92219262 case R_PPC_VLE_LO16A :
92229263 relocation = relocation + addend ;
9223- ppc_elf_vle_split16 (input_bfd , contents + rel -> r_offset ,
9224- relocation , split16a_type );
9264+ ppc_elf_vle_split16 (input_bfd , input_section , rel -> r_offset ,
9265+ contents + rel -> r_offset , relocation ,
9266+ split16a_type , htab -> params -> vle_reloc_fixup );
92259267 goto copy_reloc ;
92269268
92279269 case R_PPC_VLE_LO16D :
92289270 relocation = relocation + addend ;
9229- ppc_elf_vle_split16 (input_bfd , contents + rel -> r_offset ,
9230- relocation , split16d_type );
9271+ ppc_elf_vle_split16 (input_bfd , input_section , rel -> r_offset ,
9272+ contents + rel -> r_offset , relocation ,
9273+ split16d_type , htab -> params -> vle_reloc_fixup );
92319274 goto copy_reloc ;
92329275
92339276 case R_PPC_VLE_HI16A :
92349277 relocation = (relocation + addend ) >> 16 ;
9235- ppc_elf_vle_split16 (input_bfd , contents + rel -> r_offset ,
9236- relocation , split16a_type );
9278+ ppc_elf_vle_split16 (input_bfd , input_section , rel -> r_offset ,
9279+ contents + rel -> r_offset , relocation ,
9280+ split16a_type , htab -> params -> vle_reloc_fixup );
92379281 goto copy_reloc ;
92389282
92399283 case R_PPC_VLE_HI16D :
92409284 relocation = (relocation + addend ) >> 16 ;
9241- ppc_elf_vle_split16 (input_bfd , contents + rel -> r_offset ,
9242- relocation , split16d_type );
9285+ ppc_elf_vle_split16 (input_bfd , input_section , rel -> r_offset ,
9286+ contents + rel -> r_offset , relocation ,
9287+ split16d_type , htab -> params -> vle_reloc_fixup );
92439288 goto copy_reloc ;
92449289
92459290 case R_PPC_VLE_HA16A :
92469291 relocation = (relocation + addend + 0x8000 ) >> 16 ;
9247- ppc_elf_vle_split16 (input_bfd , contents + rel -> r_offset ,
9248- relocation , split16a_type );
9292+ ppc_elf_vle_split16 (input_bfd , input_section , rel -> r_offset ,
9293+ contents + rel -> r_offset , relocation ,
9294+ split16a_type , htab -> params -> vle_reloc_fixup );
92499295 goto copy_reloc ;
92509296
92519297 case R_PPC_VLE_HA16D :
92529298 relocation = (relocation + addend + 0x8000 ) >> 16 ;
9253- ppc_elf_vle_split16 (input_bfd , contents + rel -> r_offset ,
9254- relocation , split16d_type );
9299+ ppc_elf_vle_split16 (input_bfd , input_section , rel -> r_offset ,
9300+ contents + rel -> r_offset , relocation ,
9301+ split16d_type , htab -> params -> vle_reloc_fixup );
92559302 goto copy_reloc ;
92569303
92579304 /* Relocate against either _SDA_BASE_, _SDA2_BASE_, or 0. */
@@ -9414,34 +9461,46 @@ ppc_elf_relocate_section (bfd *output_bfd,
94149461 + addend );
94159462
94169463 if (r_type == R_PPC_VLE_SDAREL_LO16A )
9417- ppc_elf_vle_split16 (input_bfd , contents + rel -> r_offset ,
9418- value , split16a_type );
9464+ ppc_elf_vle_split16 (input_bfd , input_section , rel -> r_offset ,
9465+ contents + rel -> r_offset , value ,
9466+ split16a_type ,
9467+ htab -> params -> vle_reloc_fixup );
94199468 else if (r_type == R_PPC_VLE_SDAREL_LO16D )
9420- ppc_elf_vle_split16 (input_bfd , contents + rel -> r_offset ,
9421- value , split16d_type );
9469+ ppc_elf_vle_split16 (input_bfd , input_section , rel -> r_offset ,
9470+ contents + rel -> r_offset , value ,
9471+ split16d_type ,
9472+ htab -> params -> vle_reloc_fixup );
94229473 else if (r_type == R_PPC_VLE_SDAREL_HI16A )
94239474 {
94249475 value = value >> 16 ;
9425- ppc_elf_vle_split16 (input_bfd , contents + rel -> r_offset ,
9426- value , split16a_type );
9476+ ppc_elf_vle_split16 (input_bfd , input_section , rel -> r_offset ,
9477+ contents + rel -> r_offset , value ,
9478+ split16a_type ,
9479+ htab -> params -> vle_reloc_fixup );
94279480 }
94289481 else if (r_type == R_PPC_VLE_SDAREL_HI16D )
94299482 {
94309483 value = value >> 16 ;
9431- ppc_elf_vle_split16 (input_bfd , contents + rel -> r_offset ,
9432- value , split16d_type );
9484+ ppc_elf_vle_split16 (input_bfd , input_section , rel -> r_offset ,
9485+ contents + rel -> r_offset , value ,
9486+ split16d_type ,
9487+ htab -> params -> vle_reloc_fixup );
94339488 }
94349489 else if (r_type == R_PPC_VLE_SDAREL_HA16A )
94359490 {
94369491 value = (value + 0x8000 ) >> 16 ;
9437- ppc_elf_vle_split16 (input_bfd , contents + rel -> r_offset ,
9438- value , split16a_type );
9492+ ppc_elf_vle_split16 (input_bfd , input_section , rel -> r_offset ,
9493+ contents + rel -> r_offset , value ,
9494+ split16a_type ,
9495+ htab -> params -> vle_reloc_fixup );
94399496 }
94409497 else if (r_type == R_PPC_VLE_SDAREL_HA16D )
94419498 {
94429499 value = (value + 0x8000 ) >> 16 ;
9443- ppc_elf_vle_split16 (input_bfd , contents + rel -> r_offset ,
9444- value , split16d_type );
9500+ ppc_elf_vle_split16 (input_bfd , input_section , rel -> r_offset ,
9501+ contents + rel -> r_offset , value ,
9502+ split16d_type ,
9503+ htab -> params -> vle_reloc_fixup );
94459504 }
94469505 }
94479506 goto copy_reloc ;
0 commit comments