GNU Binutils with patches for OS216
Revisión | a2cee335061170366863d3d3837e242ad6ae93d9 (tree) |
---|---|
Tiempo | 2003-06-19 07:48:40 |
Autor | Jim Blandy <jimb@code...> |
Commiter | Jim Blandy |
* ppc-linux-tdep.c (ppc64_linux_bfd_entry_point): New function.
(ppc_linux_init_abi): Register it as our bfd_entry_point method.
@@ -1,5 +1,8 @@ | ||
1 | 1 | 2003-06-13 Jim Blandy <jimb@redhat.com> |
2 | 2 | |
3 | + * ppc-linux-tdep.c (ppc64_linux_bfd_entry_point): New function. | |
4 | + (ppc_linux_init_abi): Register it as our bfd_entry_point method. | |
5 | + | |
3 | 6 | * solib-svr4.c (bfd_lookup_symbol): New SECT_FLAGS argument. |
4 | 7 | (enable_break): Pass SEC_CODE as the SECT_FLAGS argument to |
5 | 8 | bfd_lookup_symbol, since we only want symbols in code sections. |
@@ -941,6 +941,60 @@ ppc64_call_dummy_address (void) | ||
941 | 941 | } |
942 | 942 | |
943 | 943 | |
944 | +/* Return the unrelocated code address at which execution begins for | |
945 | + ABFD, under the 64-bit PowerPC Linux ABI. | |
946 | + | |
947 | + On that system, the ELF header's e_entry field (which is what | |
948 | + bfd_get_start_address gives you) is not the address of the actual | |
949 | + machine instruction you need to jump to, as it is on almost every | |
950 | + other target. Instead, it's the address of a function descriptor | |
951 | + for the start function. A function descriptor is a structure | |
952 | + containing three addresses: the entry point, the TOC pointer for | |
953 | + the function, and an environment pointer for the function. The | |
954 | + first field is what we want to return. | |
955 | + | |
956 | + So all we do is find the section containing the start address, read | |
957 | + the address-sized word there out of the BFD, and return that. */ | |
958 | +static CORE_ADDR | |
959 | +ppc64_linux_bfd_entry_point (struct gdbarch *gdbarch, bfd *abfd) | |
960 | +{ | |
961 | + bfd_vma start_address = bfd_get_start_address (abfd); | |
962 | + unsigned int addr_size = (bfd_arch_bits_per_address (abfd) | |
963 | + / bfd_arch_bits_per_byte (abfd)); | |
964 | + unsigned char *entry_pt_buf = alloca (addr_size); | |
965 | + asection *sec; | |
966 | + file_ptr desc_offset; | |
967 | + | |
968 | + /* Find a data section containing an address-sized word at | |
969 | + start_address. */ | |
970 | + for (sec = abfd->sections; sec; sec = sec->next) | |
971 | + { | |
972 | + CORE_ADDR sec_vma = bfd_get_section_vma (abfd, sec); | |
973 | + CORE_ADDR sec_end_vma = sec_vma + bfd_section_size (abfd, sec); | |
974 | + | |
975 | + if (sec_vma <= start_address | |
976 | + && start_address + addr_size <= sec_end_vma) | |
977 | + break; | |
978 | + } | |
979 | + if (! sec) | |
980 | + return 0; | |
981 | + | |
982 | + /* Okay, we've found the section. What is the function descriptor's | |
983 | + offset within that section? */ | |
984 | + desc_offset = start_address - bfd_get_section_vma (abfd, sec); | |
985 | + | |
986 | + /* Seek to the descriptor, and read the first address-sized word it | |
987 | + contains. */ | |
988 | + if (bfd_seek (abfd, sec->filepos + desc_offset, SEEK_SET) | |
989 | + || bfd_bread (entry_pt_buf, addr_size, abfd) != addr_size) | |
990 | + return 0; | |
991 | + | |
992 | + /* That's the actual code entry point. */ | |
993 | + return (CORE_ADDR) bfd_get (bfd_arch_bits_per_address (abfd), | |
994 | + abfd, entry_pt_buf); | |
995 | +} | |
996 | + | |
997 | + | |
944 | 998 | enum { |
945 | 999 | ELF_NGREG = 48, |
946 | 1000 | ELF_NFPREG = 33, |
@@ -1072,6 +1126,8 @@ ppc_linux_init_abi (struct gdbarch_info info, | ||
1072 | 1126 | set_gdbarch_in_solib_call_trampoline |
1073 | 1127 | (gdbarch, ppc64_in_solib_call_trampoline); |
1074 | 1128 | set_gdbarch_skip_trampoline_code (gdbarch, ppc64_skip_trampoline_code); |
1129 | + | |
1130 | + set_gdbarch_bfd_entry_point (gdbarch, ppc64_linux_bfd_entry_point); | |
1075 | 1131 | } |
1076 | 1132 | } |
1077 | 1133 |