return 0;
}
-/* Add the VLE flag if required. */
-
-bfd_boolean
-ppc_elf_section_processing (bfd *abfd, Elf_Internal_Shdr *shdr)
-{
- if (bfd_get_mach (abfd) == bfd_mach_ppc_vle
- && (shdr->sh_flags & SHF_EXECINSTR) != 0)
- shdr->sh_flags |= SHF_PPC_VLE;
-
- return TRUE;
-}
-
/* Return address for Ith PLT stub in section PLT, for relocation REL
or (bfd_vma) -1 if it should not be included. */
ppc_elf_modify_segment_map (bfd *abfd,
struct bfd_link_info *info ATTRIBUTE_UNUSED)
{
- struct elf_segment_map *m, *n;
- bfd_size_type amt;
- unsigned int j, k;
- bfd_boolean sect0_vle, sectj_vle;
+ struct elf_segment_map *m;
/* At this point in the link, output sections have already been sorted by
LMA and assigned to segments. All that is left to do is to ensure
for (m = elf_seg_map (abfd); m != NULL; m = m->next)
{
- if (m->count == 0)
+ struct elf_segment_map *n;
+ bfd_size_type amt;
+ unsigned int j, k;
+ unsigned int p_flags;
+
+ if (m->p_type != PT_LOAD || m->count == 0)
continue;
- sect0_vle = (elf_section_flags (m->sections[0]) & SHF_PPC_VLE) != 0;
- for (j = 1; j < m->count; ++j)
+ for (p_flags = PF_R, j = 0; j != m->count; ++j)
{
- sectj_vle = (elf_section_flags (m->sections[j]) & SHF_PPC_VLE) != 0;
+ if ((m->sections[j]->flags & SEC_READONLY) == 0)
+ p_flags |= PF_W;
+ if ((m->sections[j]->flags & SEC_CODE) != 0)
+ {
+ p_flags |= PF_X;
+ if ((elf_section_flags (m->sections[j]) & SHF_PPC_VLE) != 0)
+ p_flags |= PF_PPC_VLE;
+ break;
+ }
+ }
+ if (j != m->count)
+ while (++j != m->count)
+ {
+ unsigned int p_flags1 = PF_R;
- if (sectj_vle != sect0_vle)
- break;
- }
- if (j >= m->count)
+ if ((m->sections[j]->flags & SEC_READONLY) == 0)
+ p_flags1 |= PF_W;
+ if ((m->sections[j]->flags & SEC_CODE) != 0)
+ {
+ p_flags1 |= PF_X;
+ if ((elf_section_flags (m->sections[j]) & SHF_PPC_VLE) != 0)
+ p_flags1 |= PF_PPC_VLE;
+ if (((p_flags1 ^ p_flags) & PF_PPC_VLE) != 0)
+ break;
+ }
+ p_flags |= p_flags1;
+ }
+ /* If we're splitting a segment which originally contained rw
+ sections then those sections might now only be in one of the
+ two parts. So always set p_flags if splitting, even if we
+ are being called for objcopy with p_flags_valid set. */
+ if (j != m->count || !m->p_flags_valid)
+ {
+ m->p_flags_valid = 1;
+ m->p_flags = p_flags;
+ }
+ if (j == m->count)
continue;
- /* sections 0..j-1 stay in this (current) segment,
+ /* Sections 0..j-1 stay in this (current) segment,
the remainder are put in a new segment.
The scan resumes with the new segment. */
- /* Fix the new segment. */
amt = sizeof (struct elf_segment_map);
amt += (m->count - j - 1) * sizeof (asection *);
n = (struct elf_segment_map *) bfd_zalloc (abfd, amt);
return FALSE;
n->p_type = PT_LOAD;
- n->p_flags = PF_X | PF_R;
- if (sectj_vle)
- n->p_flags |= PF_PPC_VLE;
n->count = m->count - j;
for (k = 0; k < n->count; ++k)
- {
- n->sections[k] = m->sections[j+k];
- m->sections[j+k] = NULL;
- }
+ n->sections[k] = m->sections[j + k];
+ m->count = j;
+ m->p_size_valid = 0;
n->next = m->next;
m->next = n;
-
- /* Fix the current segment */
- m->count = j;
}
return TRUE;
#define elf_backend_action_discarded ppc_elf_action_discarded
#define elf_backend_init_index_section _bfd_elf_init_1_index_section
#define elf_backend_lookup_section_flags_hook ppc_elf_lookup_section_flags
-#define elf_backend_section_processing ppc_elf_section_processing
#include "elf32-target.h"
however it'll remain clear for dual-mode instructions on
dual-mode and, more importantly, standard-mode processors. */
if ((ppc_cpu & opcode->flags) == PPC_OPCODE_VLE)
- ppc_apuinfo_section_add (PPC_APUINFO_VLE, 1);
+ {
+ ppc_apuinfo_section_add (PPC_APUINFO_VLE, 1);
+ if (elf_section_data (now_seg) != NULL)
+ elf_section_data (now_seg)->this_hdr.sh_flags |= SHF_PPC_VLE;
+ }
}
#endif
/* Write out the instruction. */
/* Differentiate between two and four byte insns. */
- if (ppc_mach () == bfd_mach_ppc_vle)
+ if ((ppc_cpu & PPC_OPCODE_VLE) != 0)
{
if (PPC_OP_SE_VLE (insn))
insn_length = 2;
f = frag_more (insn_length);
if (frag_now->has_code && frag_now->insn_addr != addr_mod)
{
- if (ppc_mach() == bfd_mach_ppc_vle)
+ if ((ppc_cpu & PPC_OPCODE_VLE) != 0)
as_bad (_("instruction address is not a multiple of 2"));
else
as_bad (_("instruction address is not a multiple of 4"));
if (!fragP->has_code)
return;
- if (ppc_mach() == bfd_mach_ppc_vle)
+ if ((ppc_cpu & PPC_OPCODE_VLE) != 0)
{
if (((fragP->fr_address + fragP->insn_addr) & 1) != 0)
as_bad (_("instruction address is not a multiple of 2"));
valueT count = (fragP->fr_next->fr_address
- (fragP->fr_address + fragP->fr_fix));
- if (ppc_mach() == bfd_mach_ppc_vle && count != 0 && (count & 1) == 0)
+ if ((ppc_cpu & PPC_OPCODE_VLE) != 0 && count != 0 && (count & 1) == 0)
{
char *dest = fragP->fr_literal + fragP->fr_fix;