? gdbarch.log Index: Makefile.in =================================================================== RCS file: /cvs/src/src/gdb/Makefile.in,v retrieving revision 1.158 diff -p -r1.158 Makefile.in *** Makefile.in 2002/02/13 20:47:16 1.158 --- Makefile.in 2002/02/14 18:17:15 *************** arm-linux-tdep.o: arm-linux-tdep.c $(def *** 1247,1255 **** arm-tdep.o: arm-tdep.c $(defs_h) $(frame_h) $(inferior_h) $(gdbcmd_h) \ $(gdbcore_h) $(gdb_string_h) $(dis_asm_h) $(regcache_h) $(doublest_h) \ $(value_h) $(arch_utils_h) $(solib_svr4_h) arm-tdep.h \ ! $(BFD_SRC)/elf-bfd.h $(INCLUDE_DIR)/coff/internal.h ! armnbsd-nat.o: armnbsd-nat.c $(defs_h) arm-tdep.h bcache.o: bcache.c $(bcache_h) $(defs_h) --- 1247,1256 ---- arm-tdep.o: arm-tdep.c $(defs_h) $(frame_h) $(inferior_h) $(gdbcmd_h) \ $(gdbcore_h) $(gdb_string_h) $(dis_asm_h) $(regcache_h) $(doublest_h) \ $(value_h) $(arch_utils_h) $(solib_svr4_h) arm-tdep.h \ ! $(BFD_SRC)/elf-bfd.h $(INCLUDE_DIR)/coff/internal.h \ ! $(INCLUDE_DIR)/elf/arm.h ! armnbsd-nat.o: armnbsd-nat.c $(defs_h) arm-tdep.h $(inferior_h) $(regcache_h) bcache.o: bcache.c $(bcache_h) $(defs_h) Index: arm-tdep.c =================================================================== RCS file: /cvs/src/src/gdb/arm-tdep.c,v retrieving revision 1.40 diff -p -r1.40 arm-tdep.c *** arm-tdep.c 2002/02/13 16:32:33 1.40 --- arm-tdep.c 2002/02/14 18:17:22 *************** *** 39,44 **** --- 39,45 ---- #include "elf-bfd.h" #include "coff/internal.h" + #include "elf/arm.h" /* Each OS has a different mechanism for accessing the various registers stored in the sigcontext structure. *************** arm_coff_make_msymbol_special(int val, s *** 2440,2455 **** MSYMBOL_SET_SPECIAL (msym); } static struct gdbarch * arm_gdbarch_init (struct gdbarch_info info, struct gdbarch_list *arches) { struct gdbarch *gdbarch; ! if (arches != NULL) ! return arches->gdbarch; ! /* XXX We'll probably need to set the tdep field soon. */ ! gdbarch = gdbarch_alloc (&info, NULL); /* Floating point sizes and format. */ switch (info.byte_order) --- 2441,2670 ---- MSYMBOL_SET_SPECIAL (msym); } + + static void + process_note_abi_tag_sections (bfd *abfd, asection *sect, void *obj) + { + enum arm_abi *os_ident_ptr = obj; + const char *name; + unsigned int sectsize; + + name = bfd_get_section_name (abfd, sect); + sectsize = bfd_section_size (abfd, sect); + + if (strcmp (name, ".note.ABI-tag") == 0 && sectsize > 0) + { + unsigned int name_length, data_length, note_type; + char *note; + + /* If the section is larger than this, it's probably not what we are + looking for. */ + if (sectsize > 128) + sectsize = 128; + + note = alloca (sectsize); + + bfd_get_section_contents (abfd, sect, note, + (file_ptr) 0, (bfd_size_type) sectsize); + + name_length = bfd_h_get_32 (abfd, note); + data_length = bfd_h_get_32 (abfd, note + 4); + note_type = bfd_h_get_32 (abfd, note + 8); + + if (name_length == 4 && data_length == 16 && note_type == 1 + && strcmp (note + 12, "GNU") == 0) + { + int os_number = bfd_h_get_32 (abfd, note + 16); + + /* The case numbers are from abi-tags in glibc */ + switch (os_number) + { + case 0 : + *os_ident_ptr = ARM_ABI_LINUX; + break; + + case 1 : + internal_error + (__FILE__, __LINE__, + "process_note_abi_sections: Hurd objects not supported"); + break; + + case 2 : + internal_error + (__FILE__, __LINE__, + "process_note_abi_sections: Solaris objects not supported"); + break; + + default : + internal_error + (__FILE__, __LINE__, + "process_note_abi_sections: unknown OS number %d", + os_number); + break; + } + } + } + /* NetBSD uses a similar trick. */ + else if (strcmp (name, ".note.netbsd.ident") == 0 && sectsize > 0) + { + unsigned int name_length, desc_length, note_type; + char *note; + + /* If the section is larger than this, it's probably not what we are + looking for. */ + if (sectsize > 128) + sectsize = 128; + + note = alloca (sectsize); + + bfd_get_section_contents (abfd, sect, note, + (file_ptr) 0, (bfd_size_type) sectsize); + + name_length = bfd_h_get_32 (abfd, note); + desc_length = bfd_h_get_32 (abfd, note + 4); + note_type = bfd_h_get_32 (abfd, note + 8); + + if (name_length == 7 && desc_length == 4 && note_type == 1 + && strcmp (note + 12, "NetBSD") == 0) + /* XXX Should we check the version here? + Probably not necessary yet. */ + *os_ident_ptr = ARM_ABI_NETBSD_ELF; + } + } + + /* Return one of the ELFOSABI_ constants for BFDs representing ELF + executables. If it's not an ELF executable or if the OS/ABI couldn't + be determined, simply return -1. */ + + static int + get_elfosabi (bfd *abfd) + { + int elfosabi; + enum arm_abi arm_abi = ARM_ABI_UNKNOWN; + + elfosabi = elf_elfheader (abfd)->e_ident[EI_OSABI]; + + /* When elfosabi is 0 (ELFOSABI_NONE), this is supposed to indicate + that we're on a SYSV system. However, GNU/Linux uses a note section + to record OS/ABI info, but leaves e_ident[EI_OSABI] zero. So we + have to check the note sections too. + + GNU/ARM tools set the EI_OSABI field to ELFOSABI_ARM, so handle that + as well.*/ + if (elfosabi == 0 || elfosabi == ELFOSABI_ARM) + { + bfd_map_over_sections (abfd, + process_note_abi_tag_sections, + &arm_abi); + } + + if (arm_abi != ARM_ABI_UNKNOWN) + return arm_abi; + + switch (elfosabi) + { + case ELFOSABI_NONE: + /* Existing ARM Tools don't set this field, so look at the EI_FLAGS + field for more information. */ + + switch (EF_ARM_EABI_VERSION(elf_elfheader(abfd)->e_flags)) + { + case EF_ARM_EABI_VER1: + return ARM_ABI_EABI_V1; + + case EF_ARM_EABI_VER2: + return ARM_ABI_EABI_V2; + + case EF_ARM_EABI_UNKNOWN: + /* Assume GNU tools. */ + return ARM_ABI_APCS; + + default: + internal_error (__FILE__, __LINE__, + "get_elfosabi: Unknown ARM EABI version 0x%lx", + EF_ARM_EABI_VERSION(elf_elfheader(abfd)->e_flags)); + + } + break; + + case ELFOSABI_NETBSD: + return ARM_ABI_NETBSD_ELF; + + case ELFOSABI_FREEBSD: + return ARM_ABI_FREEBSD; + + case ELFOSABI_LINUX: + return ARM_ABI_LINUX; + + case ELFOSABI_ARM: + /* Assume GNU tools with the old APCS abi. */ + return ARM_ABI_APCS; + + default: + } + + return ARM_ABI_UNKNOWN; + } + + /* Initialize the current architecture based on INFO. If possible, re-use an + architecture from ARCHES, which is a list of architectures already created + during this debugging session. + + Called e.g. at program startup, when reading a core file, and when reading + a binary file. */ + static struct gdbarch * arm_gdbarch_init (struct gdbarch_info info, struct gdbarch_list *arches) { + struct gdbarch_tdep *tdep; struct gdbarch *gdbarch; + enum arm_abi arm_abi = ARM_ABI_UNKNOWN; + + /* Try to deterimine the ABI of the object we are loading. */ + + if (info.abfd != NULL) + { + switch (bfd_get_flavour (info.abfd)) + { + case bfd_target_elf_flavour: + arm_abi = get_elfosabi (info.abfd); + break; + + case bfd_target_aout_flavour: + if (strcmp (bfd_get_target(info.abfd), "a.out-arm-netbsd") == 0) + arm_abi = ARM_ABI_NETBSD_AOUT; + else + /* Assume it's an old APCS-style ABI. */ + arm_abi = ARM_ABI_APCS; + break; + + case bfd_target_coff_flavour: + /* Assume it's an old APCS-style ABI. */ + /* XXX WinCE? */ + arm_abi = ARM_ABI_APCS; + break; ! default: ! /* Not sure what to do here, leave the ABI as unknown. */ ! break; ! } ! } ! ! /* Find a candidate among extant architectures. */ ! for (arches = gdbarch_list_lookup_by_info (arches, &info); ! arches != NULL; ! arches = gdbarch_list_lookup_by_info (arches->next, &info)) ! { ! /* Make sure the ABI selection matches. */ ! tdep = gdbarch_tdep (arches->gdbarch); ! if (tdep && tdep->arm_abi == arm_abi) ! return arches->gdbarch; ! } ! ! tdep = xmalloc (sizeof (struct gdbarch_tdep)); ! gdbarch = gdbarch_alloc (&info, tdep); ! tdep->arm_abi = arm_abi; /* Floating point sizes and format. */ switch (info.byte_order) *************** arm_gdbarch_init (struct gdbarch_info in *** 2473,2478 **** --- 2688,2711 ---- "arm_gdbarch_init: bad byte order for float format"); } + switch (arm_abi) + { + case ARM_ABI_UNKNOWN: + case ARM_ABI_EABI_V1: + case ARM_ABI_EABI_V2: + case ARM_ABI_APCS: + case ARM_ABI_WINCE: + tdep->lowest_pc = 0x20; /* Just beyond the vectors. */ + break; + + case ARM_ABI_LINUX: + case ARM_ABI_NETBSD_AOUT: + case ARM_ABI_NETBSD_ELF: + case ARM_ABI_FREEBSD: + tdep->lowest_pc = 0x8000; + break; + } + set_gdbarch_use_generic_dummy_frames (gdbarch, 0); /* Call dummy code. */ *************** arm_gdbarch_init (struct gdbarch_info in *** 2580,2585 **** --- 2813,2875 ---- return gdbarch; } + static void + arm_dump_tdep (struct gdbarch *current_gdbarch, struct ui_file *file) + { + struct gdbarch_tdep *tdep = gdbarch_tdep (current_gdbarch); + + if (tdep == NULL) + return; + + switch (tdep->arm_abi) + { + case ARM_ABI_UNKNOWN: + fprintf_unfiltered (file, "arm_dump_tdep: ABI = \n"); + break; + + case ARM_ABI_EABI_V1: + fprintf_unfiltered (file, "arm_dump_tdep: ABI = ARM EABI (version 1)\n"); + break; + + case ARM_ABI_EABI_V2: + fprintf_unfiltered (file, "arm_dump_tdep: ABI = ARM EABI (version 2)\n"); + break; + + case ARM_ABI_LINUX: + fprintf_unfiltered (file, "arm_dump_tdep: ABI = GNU/Linux\n"); + break; + + case ARM_ABI_NETBSD_AOUT: + fprintf_unfiltered (file, "arm_dump_tdep: ABI = NetBSD (a.out)\n"); + break; + + case ARM_ABI_NETBSD_ELF: + fprintf_unfiltered (file, "arm_dump_tdep: ABI = NetBSD (ELF)\n"); + break; + + case ARM_ABI_APCS: + fprintf_unfiltered (file, "arm_dump_tdep: ABI = APCS\n"); + break; + + case ARM_ABI_FREEBSD: + fprintf_unfiltered (file, "arm_dump_tdep: ABI = FreeBSD\n"); + break; + + case ARM_ABI_WINCE: + fprintf_unfiltered (file, "arm_dump_tdep: ABI = Windows CE\n"); + break; + + default: + internal_error (__FILE__, __LINE__, + "arm_dump_tdep: illegal setting of tdep->arm_abi (%d)", + (int) tdep->arm_abi); + break; + } + + fprintf_unfiltered (file, "arm_dump_tdep: Lowest pc = 0x%lx", + (unsigned long) tdep->lowest_pc); + } + void _initialize_arm_tdep (void) { *************** _initialize_arm_tdep (void) *** 2593,2599 **** static char *helptext; if (GDB_MULTI_ARCH) ! register_gdbarch_init (bfd_arch_arm, arm_gdbarch_init); tm_print_insn = gdb_print_insn_arm; --- 2883,2889 ---- static char *helptext; if (GDB_MULTI_ARCH) ! gdbarch_register (bfd_arch_arm, arm_gdbarch_init, arm_dump_tdep); tm_print_insn = gdb_print_insn_arm; Index: arm-tdep.h =================================================================== RCS file: /cvs/src/src/gdb/arm-tdep.h,v retrieving revision 1.2 diff -p -r1.2 arm-tdep.h *** arm-tdep.h 2002/02/13 17:09:07 1.2 --- arm-tdep.h 2002/02/14 18:17:22 *************** *** 99,104 **** --- 99,130 ---- #define FLAG_C 0x20000000 #define FLAG_V 0x10000000 + /* ABI variants that we know about. */ + enum arm_abi + { + ARM_ABI_UNKNOWN, + ARM_ABI_EABI_V1, + ARM_ABI_EABI_V2, + ARM_ABI_LINUX, + ARM_ABI_NETBSD_AOUT, + ARM_ABI_NETBSD_ELF, + ARM_ABI_APCS, + ARM_ABI_FREEBSD, + ARM_ABI_WINCE + }; + + /* Target-dependent structure in gdbarch. */ + struct gdbarch_tdep + { + enum arm_abi arm_abi; /* OS/ABI of inferior. */ + CORE_ADDR lowest_pc; /* Lowest address at which instructions + will appear. */ + }; + + #ifndef LOWEST_PC + #define LOWEST_PC (gdbarch_tdep (current_gdbarch)->lowest_pc) + #endif + /* Prototypes for internal interfaces needed by more than one MD file. */ int arm_pc_is_thumb_dummy (CORE_ADDR); Index: armnbsd-nat.c =================================================================== RCS file: /cvs/src/src/gdb/armnbsd-nat.c,v retrieving revision 1.3 diff -p -r1.3 armnbsd-nat.c *** armnbsd-nat.c 2002/02/11 18:34:08 1.3 --- armnbsd-nat.c 2002/02/14 18:17:22 *************** *** 29,34 **** --- 29,35 ---- #include #include #include "inferior.h" + #include "regcache.h" void fetch_inferior_registers (regno) Index: config/arm/tm-arm.h =================================================================== RCS file: /cvs/src/src/gdb/config/arm/tm-arm.h,v retrieving revision 1.27 diff -p -r1.27 tm-arm.h *** tm-arm.h 2002/02/13 16:32:34 1.27 --- tm-arm.h 2002/02/14 18:17:22 *************** *** 70,76 **** #define CALL_DUMMY_BREAKPOINT_OFFSET arm_call_dummy_breakpoint_offset() extern int arm_call_dummy_breakpoint_offset (void); - /* The first 0x20 bytes are the trap vectors. */ - #define LOWEST_PC 0x20 - #endif /* TM_ARM_H */ --- 70,73 ---- Index: config/arm/tm-nbsd.h =================================================================== RCS file: /cvs/src/src/gdb/config/arm/tm-nbsd.h,v retrieving revision 1.3 diff -p -r1.3 tm-nbsd.h *** tm-nbsd.h 2002/02/11 18:34:12 1.3 --- tm-nbsd.h 2002/02/14 18:17:22 *************** *** 27,36 **** #define JB_ELEMENT_SIZE sizeof(long) /* jmp_buf[_JBLEN] is array of ints */ #define JB_PC 24 /* Setjmp()'s return PC saved here */ - /* The first page is not writeable in NetBSD. */ - #undef LOWEST_PC - #define LOWEST_PC 0x8000 - /* Return non-zero if inside a shared-library entry stub. */ #undef IN_SOLIB_CALL_TRAMPOLINE #define IN_SOLIB_CALL_TRAMPOLINE(pc, name) \ --- 27,32 ----