• R/O
  • HTTP
  • SSH
  • HTTPS

提交

标签
No Tags

Frequently used words (click to add to your profile)

javac++androidlinuxc#windowsobjective-ccocoa誰得qtpythonphprubygameguibathyscaphec計画中(planning stage)翻訳omegatframeworktwitterdomtestvb.netdirectxゲームエンジンbtronarduinopreviewer

GNU Binutils with patches for OS216


Commit MetaInfo

修订版f7d69005fb97f0d90c9eb414944a5035bfd67b36 (tree)
时间2016-08-31 12:48:34
作者Alan Modra <amodra@gmai...>
CommiterAlan Modra

Log Message

PowerPC VLE sh_flags and p_flags

ELF section sh_flags SHF_PPC_VLE was being set based on arch/mach,
which meant all code sections in an object file has the flag or all
lacked it. We can do better than that. Only those code sections
where VLE is enabled ought to have the flag, allowing an object file
to contain both VLE and non-VLE code.

Also, ELF header p_flags PF_PPC_VLE wasn't being set, and segments
were being split unnecessarily.

bfd/
* elf32-ppc.c (ppc_elf_section_processing): Delete.
(elf_backend_section_processing): Don't define.
(ppc_elf_modify_segment_map): Set p_flags and mark valid. Don't
split on non-exec sections differing in SHF_PPC_VLE. When
splitting segments, mark size invalid.
gas/
* config/tc-ppc.c (md_assemble): Set sh_flags for VLE. Test
ppc_cpu rather than calling ppc_mach to determine VLE mode.
(ppc_frag_check, ppc_handle_align): Likewise use ppc_cpu.

更改概述

差异

--- a/bfd/ChangeLog
+++ b/bfd/ChangeLog
@@ -1,3 +1,11 @@
1+2016-08-31 Alan Modra <amodra@gmail.com>
2+
3+ * elf32-ppc.c (ppc_elf_section_processing): Delete.
4+ (elf_backend_section_processing): Don't define.
5+ (ppc_elf_modify_segment_map): Set p_flags and mark valid. Don't
6+ split on non-exec sections differing in SHF_PPC_VLE. When
7+ splitting segments, mark size invalid.
8+
19 2016-08-30 Alan Modra <amodra@gmail.com>
210
311 PR 20531
--- a/bfd/elf32-ppc.c
+++ b/bfd/elf32-ppc.c
@@ -2444,18 +2444,6 @@ ppc_elf_lookup_section_flags (char *flag_name)
24442444 return 0;
24452445 }
24462446
2447-/* Add the VLE flag if required. */
2448-
2449-bfd_boolean
2450-ppc_elf_section_processing (bfd *abfd, Elf_Internal_Shdr *shdr)
2451-{
2452- if (bfd_get_mach (abfd) == bfd_mach_ppc_vle
2453- && (shdr->sh_flags & SHF_EXECINSTR) != 0)
2454- shdr->sh_flags |= SHF_PPC_VLE;
2455-
2456- return TRUE;
2457-}
2458-
24592447 /* Return address for Ith PLT stub in section PLT, for relocation REL
24602448 or (bfd_vma) -1 if it should not be included. */
24612449
@@ -2535,10 +2523,7 @@ bfd_boolean
25352523 ppc_elf_modify_segment_map (bfd *abfd,
25362524 struct bfd_link_info *info ATTRIBUTE_UNUSED)
25372525 {
2538- struct elf_segment_map *m, *n;
2539- bfd_size_type amt;
2540- unsigned int j, k;
2541- bfd_boolean sect0_vle, sectj_vle;
2526+ struct elf_segment_map *m;
25422527
25432528 /* At this point in the link, output sections have already been sorted by
25442529 LMA and assigned to segments. All that is left to do is to ensure
@@ -2548,25 +2533,59 @@ ppc_elf_modify_segment_map (bfd *abfd,
25482533
25492534 for (m = elf_seg_map (abfd); m != NULL; m = m->next)
25502535 {
2551- if (m->count == 0)
2536+ struct elf_segment_map *n;
2537+ bfd_size_type amt;
2538+ unsigned int j, k;
2539+ unsigned int p_flags;
2540+
2541+ if (m->p_type != PT_LOAD || m->count == 0)
25522542 continue;
25532543
2554- sect0_vle = (elf_section_flags (m->sections[0]) & SHF_PPC_VLE) != 0;
2555- for (j = 1; j < m->count; ++j)
2544+ for (p_flags = PF_R, j = 0; j != m->count; ++j)
25562545 {
2557- sectj_vle = (elf_section_flags (m->sections[j]) & SHF_PPC_VLE) != 0;
2546+ if ((m->sections[j]->flags & SEC_READONLY) == 0)
2547+ p_flags |= PF_W;
2548+ if ((m->sections[j]->flags & SEC_CODE) != 0)
2549+ {
2550+ p_flags |= PF_X;
2551+ if ((elf_section_flags (m->sections[j]) & SHF_PPC_VLE) != 0)
2552+ p_flags |= PF_PPC_VLE;
2553+ break;
2554+ }
2555+ }
2556+ if (j != m->count)
2557+ while (++j != m->count)
2558+ {
2559+ unsigned int p_flags1 = PF_R;
25582560
2559- if (sectj_vle != sect0_vle)
2560- break;
2561- }
2562- if (j >= m->count)
2561+ if ((m->sections[j]->flags & SEC_READONLY) == 0)
2562+ p_flags1 |= PF_W;
2563+ if ((m->sections[j]->flags & SEC_CODE) != 0)
2564+ {
2565+ p_flags1 |= PF_X;
2566+ if ((elf_section_flags (m->sections[j]) & SHF_PPC_VLE) != 0)
2567+ p_flags1 |= PF_PPC_VLE;
2568+ if (((p_flags1 ^ p_flags) & PF_PPC_VLE) != 0)
2569+ break;
2570+ }
2571+ p_flags |= p_flags1;
2572+ }
2573+ /* If we're splitting a segment which originally contained rw
2574+ sections then those sections might now only be in one of the
2575+ two parts. So always set p_flags if splitting, even if we
2576+ are being called for objcopy with p_flags_valid set. */
2577+ if (j != m->count || !m->p_flags_valid)
2578+ {
2579+ m->p_flags_valid = 1;
2580+ m->p_flags = p_flags;
2581+ }
2582+ if (j == m->count)
25632583 continue;
25642584
2565- /* sections 0..j-1 stay in this (current) segment,
2585+ /* Sections 0..j-1 stay in this (current) segment,
25662586 the remainder are put in a new segment.
25672587 The scan resumes with the new segment. */
25682588
2569- /* Fix the new segment. */
25702589 amt = sizeof (struct elf_segment_map);
25712590 amt += (m->count - j - 1) * sizeof (asection *);
25722591 n = (struct elf_segment_map *) bfd_zalloc (abfd, amt);
@@ -2574,20 +2593,13 @@ ppc_elf_modify_segment_map (bfd *abfd,
25742593 return FALSE;
25752594
25762595 n->p_type = PT_LOAD;
2577- n->p_flags = PF_X | PF_R;
2578- if (sectj_vle)
2579- n->p_flags |= PF_PPC_VLE;
25802596 n->count = m->count - j;
25812597 for (k = 0; k < n->count; ++k)
2582- {
2583- n->sections[k] = m->sections[j+k];
2584- m->sections[j+k] = NULL;
2585- }
2598+ n->sections[k] = m->sections[j + k];
2599+ m->count = j;
2600+ m->p_size_valid = 0;
25862601 n->next = m->next;
25872602 m->next = n;
2588-
2589- /* Fix the current segment */
2590- m->count = j;
25912603 }
25922604
25932605 return TRUE;
@@ -10860,7 +10872,6 @@ ppc_elf_finish_dynamic_sections (bfd *output_bfd,
1086010872 #define elf_backend_action_discarded ppc_elf_action_discarded
1086110873 #define elf_backend_init_index_section _bfd_elf_init_1_index_section
1086210874 #define elf_backend_lookup_section_flags_hook ppc_elf_lookup_section_flags
10863-#define elf_backend_section_processing ppc_elf_section_processing
1086410875
1086510876 #include "elf32-target.h"
1086610877
--- a/gas/ChangeLog
+++ b/gas/ChangeLog
@@ -1,3 +1,9 @@
1+2016-08-31 Alan Modra <amodra@gmail.com>
2+
3+ * config/tc-ppc.c (md_assemble): Set sh_flags for VLE. Test
4+ ppc_cpu rather than calling ppc_mach to determine VLE mode.
5+ (ppc_frag_check, ppc_handle_align): Likewise use ppc_cpu.
6+
17 2016-08-26 Jose E. Marchesi <jose.marchesi@oracle.com>
28
39 * testsuite/gas/sparc/crypto.d: Rename invalid opcode camellia_fi
--- a/gas/config/tc-ppc.c
+++ b/gas/config/tc-ppc.c
@@ -3377,13 +3377,17 @@ md_assemble (char *str)
33773377 however it'll remain clear for dual-mode instructions on
33783378 dual-mode and, more importantly, standard-mode processors. */
33793379 if ((ppc_cpu & opcode->flags) == PPC_OPCODE_VLE)
3380- ppc_apuinfo_section_add (PPC_APUINFO_VLE, 1);
3380+ {
3381+ ppc_apuinfo_section_add (PPC_APUINFO_VLE, 1);
3382+ if (elf_section_data (now_seg) != NULL)
3383+ elf_section_data (now_seg)->this_hdr.sh_flags |= SHF_PPC_VLE;
3384+ }
33813385 }
33823386 #endif
33833387
33843388 /* Write out the instruction. */
33853389 /* Differentiate between two and four byte insns. */
3386- if (ppc_mach () == bfd_mach_ppc_vle)
3390+ if ((ppc_cpu & PPC_OPCODE_VLE) != 0)
33873391 {
33883392 if (PPC_OP_SE_VLE (insn))
33893393 insn_length = 2;
@@ -3400,7 +3404,7 @@ md_assemble (char *str)
34003404 f = frag_more (insn_length);
34013405 if (frag_now->has_code && frag_now->insn_addr != addr_mod)
34023406 {
3403- if (ppc_mach() == bfd_mach_ppc_vle)
3407+ if ((ppc_cpu & PPC_OPCODE_VLE) != 0)
34043408 as_bad (_("instruction address is not a multiple of 2"));
34053409 else
34063410 as_bad (_("instruction address is not a multiple of 4"));
@@ -6346,7 +6350,7 @@ ppc_frag_check (struct frag *fragP)
63466350 if (!fragP->has_code)
63476351 return;
63486352
6349- if (ppc_mach() == bfd_mach_ppc_vle)
6353+ if ((ppc_cpu & PPC_OPCODE_VLE) != 0)
63506354 {
63516355 if (((fragP->fr_address + fragP->insn_addr) & 1) != 0)
63526356 as_bad (_("instruction address is not a multiple of 2"));
@@ -6367,7 +6371,7 @@ ppc_handle_align (struct frag *fragP)
63676371 valueT count = (fragP->fr_next->fr_address
63686372 - (fragP->fr_address + fragP->fr_fix));
63696373
6370- if (ppc_mach() == bfd_mach_ppc_vle && count != 0 && (count & 1) == 0)
6374+ if ((ppc_cpu & PPC_OPCODE_VLE) != 0 && count != 0 && (count & 1) == 0)
63716375 {
63726376 char *dest = fragP->fr_literal + fragP->fr_fix;
63736377