GNU Binutils with patches for OS216
修訂 | ea32321d5d2156e644783eeaa025a04229a10c0e (tree) |
---|---|
時間 | 2003-06-11 02:58:52 |
作者 | Jim Blandy <jimb@code...> |
Commiter | Jim Blandy |
Recognize and skip 64-bit PowerPC Linux linkage functions.
* ppc-linux-tdep.c (insn_d, insn_ds, insn_xfx, read_insn, struct
insn_pattern, insns_match_pattern, d_field, ds_field): New
functions, macros, and types for working with PPC instructions.
(ppc64_standard_linkage, PPC64_STANDARD_LINKAGE_LEN,
ppc64_in_solib_call_trampoline, ppc64_standard_linkage_target,
ppc64_skip_trampoline_code): New functions, variables, and macros
for recognizing and skipping linkage functions.
(ppc_linux_init_abi): Use ppc64_in_solib_call_trampoline and
ppc64_skip_trampoline_code for the 64-bit PowerPC Linux ABI.
@@ -1,5 +1,16 @@ | ||
1 | 1 | 2003-06-10 Jim Blandy <jimb@redhat.com> |
2 | 2 | |
3 | + Recognize and skip 64-bit PowerPC Linux linkage functions. | |
4 | + * ppc-linux-tdep.c (insn_d, insn_ds, insn_xfx, read_insn, struct | |
5 | + insn_pattern, insns_match_pattern, d_field, ds_field): New | |
6 | + functions, macros, and types for working with PPC instructions. | |
7 | + (ppc64_standard_linkage, PPC64_STANDARD_LINKAGE_LEN, | |
8 | + ppc64_in_solib_call_trampoline, ppc64_standard_linkage_target, | |
9 | + ppc64_skip_trampoline_code): New functions, variables, and macros | |
10 | + for recognizing and skipping linkage functions. | |
11 | + (ppc_linux_init_abi): Use ppc64_in_solib_call_trampoline and | |
12 | + ppc64_skip_trampoline_code for the 64-bit PowerPC Linux ABI. | |
13 | + | |
3 | 14 | * ppc-linux-nat.c (ppc_register_u_addr): Correctly compute u-area |
4 | 15 | register offsets for both the 32- and 64-bit interfaces. |
5 | 16 |
@@ -632,6 +632,258 @@ ppc_linux_svr4_fetch_link_map_offsets (void) | ||
632 | 632 | return lmp; |
633 | 633 | } |
634 | 634 | |
635 | + | |
636 | +/* Macros for matching instructions. Note that, since all the | |
637 | + operands are masked off before they're or-ed into the instruction, | |
638 | + you can use -1 to make masks. */ | |
639 | + | |
640 | +#define insn_d(opcd, rts, ra, d) \ | |
641 | + ((((opcd) & 0x3f) << 26) \ | |
642 | + | (((rts) & 0x1f) << 21) \ | |
643 | + | (((ra) & 0x1f) << 16) \ | |
644 | + | ((d) & 0xffff)) | |
645 | + | |
646 | +#define insn_ds(opcd, rts, ra, d, xo) \ | |
647 | + ((((opcd) & 0x3f) << 26) \ | |
648 | + | (((rts) & 0x1f) << 21) \ | |
649 | + | (((ra) & 0x1f) << 16) \ | |
650 | + | ((d) & 0xfffc) \ | |
651 | + | ((xo) & 0x3)) | |
652 | + | |
653 | +#define insn_xfx(opcd, rts, spr, xo) \ | |
654 | + ((((opcd) & 0x3f) << 26) \ | |
655 | + | (((rts) & 0x1f) << 21) \ | |
656 | + | (((spr) & 0x1f) << 16) \ | |
657 | + | (((spr) & 0x3e0) << 6) \ | |
658 | + | (((xo) & 0x3ff) << 1)) | |
659 | + | |
660 | +/* Read a PPC instruction from memory. PPC instructions are always | |
661 | + big-endian, no matter what endianness the program is running in, so | |
662 | + we can't use read_memory_integer or one of its friends here. */ | |
663 | +static unsigned int | |
664 | +read_insn (CORE_ADDR pc) | |
665 | +{ | |
666 | + unsigned char buf[4]; | |
667 | + | |
668 | + read_memory (pc, buf, 4); | |
669 | + return (buf[0] << 24) | (buf[1] << 16) | (buf[2] << 8) | buf[3]; | |
670 | +} | |
671 | + | |
672 | + | |
673 | +/* An instruction to match. */ | |
674 | +struct insn_pattern | |
675 | +{ | |
676 | + unsigned int mask; /* mask the insn with this... */ | |
677 | + unsigned int data; /* ...and see if it matches this. */ | |
678 | + int optional; /* If non-zero, this insn may be absent. */ | |
679 | +}; | |
680 | + | |
681 | +/* Return non-zero if the instructions at PC match the series | |
682 | + described in PATTERN, or zero otherwise. PATTERN is an array of | |
683 | + 'struct insn_pattern' objects, terminated by an entry whose mask is | |
684 | + zero. | |
685 | + | |
686 | + When the match is successful, fill INSN[i] with what PATTERN[i] | |
687 | + matched. If PATTERN[i] is optional, and the instruction wasn't | |
688 | + present, set INSN[i] to 0 (which is not a valid PPC instruction). | |
689 | + INSN should have as many elements as PATTERN. Note that, if | |
690 | + PATTERN contains optional instructions which aren't present in | |
691 | + memory, then INSN will have holes, so INSN[i] isn't necessarily the | |
692 | + i'th instruction in memory. */ | |
693 | +static int | |
694 | +insns_match_pattern (CORE_ADDR pc, | |
695 | + struct insn_pattern *pattern, | |
696 | + unsigned int *insn) | |
697 | +{ | |
698 | + int i; | |
699 | + | |
700 | + for (i = 0; pattern[i].mask; i++) | |
701 | + { | |
702 | + insn[i] = read_insn (pc); | |
703 | + if ((insn[i] & pattern[i].mask) == pattern[i].data) | |
704 | + pc += 4; | |
705 | + else if (pattern[i].optional) | |
706 | + insn[i] = 0; | |
707 | + else | |
708 | + return 0; | |
709 | + } | |
710 | + | |
711 | + return 1; | |
712 | +} | |
713 | + | |
714 | + | |
715 | +/* Return the 'd' field of the d-form instruction INSN, properly | |
716 | + sign-extended. */ | |
717 | +static CORE_ADDR | |
718 | +insn_d_field (unsigned int insn) | |
719 | +{ | |
720 | + return ((((CORE_ADDR) insn & 0xffff) ^ 0x8000) - 0x8000); | |
721 | +} | |
722 | + | |
723 | + | |
724 | +/* Return the 'ds' field of the ds-form instruction INSN, with the two | |
725 | + zero bits concatenated at the right, and properly | |
726 | + sign-extended. */ | |
727 | +static CORE_ADDR | |
728 | +insn_ds_field (unsigned int insn) | |
729 | +{ | |
730 | + return ((((CORE_ADDR) insn & 0xfffc) ^ 0x8000) - 0x8000); | |
731 | +} | |
732 | + | |
733 | + | |
734 | +/* Pattern for the standard linkage function. These are built by | |
735 | + build_plt_stub in elf64-ppc.c, whose GLINK argument is always | |
736 | + zero. */ | |
737 | +static struct insn_pattern ppc64_standard_linkage[] = | |
738 | + { | |
739 | + /* addis r12, r2, <any> */ | |
740 | + { insn_d (-1, -1, -1, 0), insn_d (15, 12, 2, 0), 0 }, | |
741 | + | |
742 | + /* std r2, 40(r1) */ | |
743 | + { -1, insn_ds (62, 2, 1, 40, 0), 0 }, | |
744 | + | |
745 | + /* ld r11, <any>(r12) */ | |
746 | + { insn_ds (-1, -1, -1, 0, -1), insn_ds (58, 11, 12, 0, 0), 0 }, | |
747 | + | |
748 | + /* addis r12, r12, 1 <optional> */ | |
749 | + { insn_d (-1, -1, -1, -1), insn_d (15, 12, 2, 1), 1 }, | |
750 | + | |
751 | + /* ld r2, <any>(r12) */ | |
752 | + { insn_ds (-1, -1, -1, 0, -1), insn_ds (58, 2, 12, 0, 0), 0 }, | |
753 | + | |
754 | + /* addis r12, r12, 1 <optional> */ | |
755 | + { insn_d (-1, -1, -1, -1), insn_d (15, 12, 2, 1), 1 }, | |
756 | + | |
757 | + /* mtctr r11 */ | |
758 | + { insn_xfx (-1, -1, -1, -1), insn_xfx (31, 11, 9, 467), | |
759 | + 0 }, | |
760 | + | |
761 | + /* ld r11, <any>(r12) */ | |
762 | + { insn_ds (-1, -1, -1, 0, -1), insn_ds (58, 11, 12, 0, 0), 0 }, | |
763 | + | |
764 | + /* bctr */ | |
765 | + { -1, 0x4e800420, 0 }, | |
766 | + | |
767 | + { 0, 0, 0 } | |
768 | + }; | |
769 | +#define PPC64_STANDARD_LINKAGE_LEN \ | |
770 | + (sizeof (ppc64_standard_linkage) / sizeof (ppc64_standard_linkage[0])) | |
771 | + | |
772 | + | |
773 | +/* Recognize a 64-bit PowerPC Linux linkage function --- what GDB | |
774 | + calls a "solib trampoline". */ | |
775 | +static int | |
776 | +ppc64_in_solib_call_trampoline (CORE_ADDR pc, char *name) | |
777 | +{ | |
778 | + /* Detecting solib call trampolines on PPC64 Linux is a pain. | |
779 | + | |
780 | + It's not specifically solib call trampolines that are the issue. | |
781 | + Any call from one function to another function that uses a | |
782 | + different TOC requires a trampoline, to save the caller's TOC | |
783 | + pointer and then load the callee's TOC. An executable or shared | |
784 | + library may have more than one TOC, so even intra-object calls | |
785 | + may require a trampoline. Since executable and shared libraries | |
786 | + will all have their own distinct TOCs, every inter-object call is | |
787 | + also an inter-TOC call, and requires a trampoline --- so "solib | |
788 | + call trampolines" are just a special case. | |
789 | + | |
790 | + The 64-bit PowerPC Linux ABI calls these call trampolines | |
791 | + "linkage functions". Since they need to be near the functions | |
792 | + that call them, they all appear in .text, not in any special | |
793 | + section. The .plt section just contains an array of function | |
794 | + descriptors, from which the linkage functions load the callee's | |
795 | + entry point, TOC value, and environment pointer. So | |
796 | + in_plt_section is useless. The linkage functions don't have any | |
797 | + special linker symbols to name them, either. | |
798 | + | |
799 | + The only way I can see to recognize them is to actually look at | |
800 | + their code. They're generated by ppc_build_one_stub and some | |
801 | + other functions in bfd/elf64-ppc.c, so that should show us all | |
802 | + the instruction sequences we need to recognize. */ | |
803 | + unsigned int insn[PPC64_STANDARD_LINKAGE_LEN]; | |
804 | + | |
805 | + return insns_match_pattern (pc, ppc64_standard_linkage, insn); | |
806 | +} | |
807 | + | |
808 | + | |
809 | +/* When the dynamic linker is doing lazy symbol resolution, the first | |
810 | + call to a function in another object will go like this: | |
811 | + | |
812 | + - The user's function calls the linkage function: | |
813 | + | |
814 | + 100007c4: 4b ff fc d5 bl 10000498 | |
815 | + 100007c8: e8 41 00 28 ld r2,40(r1) | |
816 | + | |
817 | + - The linkage function loads the entry point (and other stuff) from | |
818 | + the function descriptor in the PLT, and jumps to it: | |
819 | + | |
820 | + 10000498: 3d 82 00 00 addis r12,r2,0 | |
821 | + 1000049c: f8 41 00 28 std r2,40(r1) | |
822 | + 100004a0: e9 6c 80 98 ld r11,-32616(r12) | |
823 | + 100004a4: e8 4c 80 a0 ld r2,-32608(r12) | |
824 | + 100004a8: 7d 69 03 a6 mtctr r11 | |
825 | + 100004ac: e9 6c 80 a8 ld r11,-32600(r12) | |
826 | + 100004b0: 4e 80 04 20 bctr | |
827 | + | |
828 | + - But since this is the first time that PLT entry has been used, it | |
829 | + sends control to its glink entry. That loads the number of the | |
830 | + PLT entry and jumps to the common glink0 code: | |
831 | + | |
832 | + 10000c98: 38 00 00 00 li r0,0 | |
833 | + 10000c9c: 4b ff ff dc b 10000c78 | |
834 | + | |
835 | + - The common glink0 code then transfers control to the dynamic | |
836 | + linker's fixup code: | |
837 | + | |
838 | + 10000c78: e8 41 00 28 ld r2,40(r1) | |
839 | + 10000c7c: 3d 82 00 00 addis r12,r2,0 | |
840 | + 10000c80: e9 6c 80 80 ld r11,-32640(r12) | |
841 | + 10000c84: e8 4c 80 88 ld r2,-32632(r12) | |
842 | + 10000c88: 7d 69 03 a6 mtctr r11 | |
843 | + 10000c8c: e9 6c 80 90 ld r11,-32624(r12) | |
844 | + 10000c90: 4e 80 04 20 bctr | |
845 | + | |
846 | + Eventually, this code will figure out how to skip all of this, | |
847 | + including the dynamic linker. At the moment, we just get through | |
848 | + the linkage function. */ | |
849 | + | |
850 | +/* If the current thread is about to execute a series of instructions | |
851 | + at PC matching the ppc64_standard_linkage pattern, and INSN is the result | |
852 | + from that pattern match, return the code address to which the | |
853 | + standard linkage function will send them. (This doesn't deal with | |
854 | + dynamic linker lazy symbol resolution stubs.) */ | |
855 | +static CORE_ADDR | |
856 | +ppc64_standard_linkage_target (CORE_ADDR pc, unsigned int *insn) | |
857 | +{ | |
858 | + struct gdbarch_tdep *tdep = gdbarch_tdep (current_gdbarch); | |
859 | + | |
860 | + /* The address of the function descriptor this linkage function | |
861 | + references. */ | |
862 | + CORE_ADDR desc | |
863 | + = ((CORE_ADDR) read_register (tdep->ppc_gp0_regnum + 2) | |
864 | + + (insn_d_field (insn[0]) << 16) | |
865 | + + insn_ds_field (insn[2])); | |
866 | + | |
867 | + /* The first word of the descriptor is the entry point. Return that. */ | |
868 | + return (CORE_ADDR) read_memory_unsigned_integer (desc, 8); | |
869 | +} | |
870 | + | |
871 | + | |
872 | +/* Given that we've begun executing a call trampoline at PC, return | |
873 | + the entry point of the function the trampoline will go to. */ | |
874 | +static CORE_ADDR | |
875 | +ppc64_skip_trampoline_code (CORE_ADDR pc) | |
876 | +{ | |
877 | + unsigned int ppc64_standard_linkage_insn[PPC64_STANDARD_LINKAGE_LEN]; | |
878 | + | |
879 | + if (insns_match_pattern (pc, ppc64_standard_linkage, | |
880 | + ppc64_standard_linkage_insn)) | |
881 | + return ppc64_standard_linkage_target (pc, ppc64_standard_linkage_insn); | |
882 | + else | |
883 | + return 0; | |
884 | +} | |
885 | + | |
886 | + | |
635 | 887 | enum { |
636 | 888 | ELF_NGREG = 48, |
637 | 889 | ELF_NFPREG = 33, |
@@ -743,13 +995,20 @@ ppc_linux_init_abi (struct gdbarch_info info, | ||
743 | 995 | |
744 | 996 | set_gdbarch_memory_remove_breakpoint (gdbarch, |
745 | 997 | ppc_linux_memory_remove_breakpoint); |
998 | + /* Shared library handling. */ | |
999 | + set_gdbarch_in_solib_call_trampoline (gdbarch, in_plt_section); | |
1000 | + set_gdbarch_skip_trampoline_code (gdbarch, | |
1001 | + ppc_linux_skip_trampoline_code); | |
746 | 1002 | set_solib_svr4_fetch_link_map_offsets |
747 | 1003 | (gdbarch, ppc_linux_svr4_fetch_link_map_offsets); |
748 | 1004 | } |
749 | - | |
750 | - /* Shared library handling. */ | |
751 | - set_gdbarch_in_solib_call_trampoline (gdbarch, in_plt_section); | |
752 | - set_gdbarch_skip_trampoline_code (gdbarch, ppc_linux_skip_trampoline_code); | |
1005 | + | |
1006 | + if (tdep->wordsize == 8) | |
1007 | + { | |
1008 | + set_gdbarch_in_solib_call_trampoline | |
1009 | + (gdbarch, ppc64_in_solib_call_trampoline); | |
1010 | + set_gdbarch_skip_trampoline_code (gdbarch, ppc64_skip_trampoline_code); | |
1011 | + } | |
753 | 1012 | } |
754 | 1013 | |
755 | 1014 | void |