From mboxrd@z Thu Jan 1 00:00:00 1970 Return-Path: Received: (qmail 5144 invoked by alias); 4 Jul 2012 21:08:30 -0000 Received: (qmail 5128 invoked by uid 22791); 4 Jul 2012 21:08:28 -0000 X-SWARE-Spam-Status: No, hits=-4.6 required=5.0 tests=AWL,BAYES_00,KHOP_RCVD_UNTRUST,KHOP_THREADED,RCVD_IN_DNSWL_HI,RCVD_IN_HOSTKARMA_W,TW_GJ,T_RP_MATCHES_RCVD X-Spam-Check-By: sourceware.org Received: from e24smtp05.br.ibm.com (HELO e24smtp05.br.ibm.com) (32.104.18.26) by sourceware.org (qpsmtpd/0.43rc1) with ESMTP; Wed, 04 Jul 2012 21:08:12 +0000 Received: from /spool/local by e24smtp05.br.ibm.com with IBM ESMTP SMTP Gateway: Authorized Use Only! Violators will be prosecuted for from ; Wed, 4 Jul 2012 18:08:08 -0300 Received: from d24dlp01.br.ibm.com (9.18.248.204) by e24smtp05.br.ibm.com (10.172.0.141) with IBM ESMTP SMTP Gateway: Authorized Use Only! Violators will be prosecuted; Wed, 4 Jul 2012 18:07:39 -0300 Received: from d24relay02.br.ibm.com (d24relay02.br.ibm.com [9.13.184.26]) by d24dlp01.br.ibm.com (Postfix) with ESMTP id 42011352004E for ; Wed, 4 Jul 2012 17:07:37 -0400 (EDT) Received: from d24av04.br.ibm.com (d24av04.br.ibm.com [9.8.31.97]) by d24relay02.br.ibm.com (8.13.8/8.13.8/NCO v10.0) with ESMTP id q64L6u0g35520692 for ; Wed, 4 Jul 2012 18:06:56 -0300 Received: from d24av04.br.ibm.com (loopback [127.0.0.1]) by d24av04.br.ibm.com (8.14.4/8.13.1/NCO v10.0 AVout) with ESMTP id q64J7QR3018638 for ; Wed, 4 Jul 2012 16:07:27 -0300 Received: from [9.12.227.20] ([9.12.227.20]) by d24av04.br.ibm.com (8.14.4/8.13.1/NCO v10.0 AVin) with ESMTP id q64J7NQb018526; Wed, 4 Jul 2012 16:07:24 -0300 Message-ID: <1341436052.10075.4.camel@hactar> Subject: Re: [patch] Support bionic's jmp_buf. From: Thiago Jung Bauermann To: Pedro Alves Cc: gdb-patches ml , Yao Qi , "Schnell, Fabian" Date: Wed, 04 Jul 2012 21:08:00 -0000 In-Reply-To: <4FEADDDE.6020904@redhat.com> References: <1337560528.4363.13.camel@hactar> <4FBA2920.4070909@redhat.com> <1337623164.22073.9.camel@hactar> <1340574375.31308.7.camel@hactar> <4FEADDDE.6020904@redhat.com> Content-Type: text/plain; charset="ISO-8859-1" Content-Transfer-Encoding: 7bit Mime-Version: 1.0 X-Content-Scanned: Fidelis XPS MAILER x-cbid: 12070421-2362-0000-0000-000007B35993 X-IsSubscribed: yes Mailing-List: contact gdb-patches-help@sourceware.org; run by ezmlm Precedence: bulk List-Id: List-Subscribe: List-Archive: List-Post: List-Help: , Sender: gdb-patches-owner@sourceware.org X-SW-Source: 2012-07/txt/msg00064.txt.bz2 On Wed, 2012-06-27 at 11:18 +0100, Pedro Alves wrote: > On 06/24/2012 10:46 PM, Thiago Jung Bauermann wrote: > > I submitted a patch to bionic which adds a .note.ABI-tag to Android > > binaries: > > > > https://android-review.googlesource.com/37590 > > The note has a flag which is set to 1 if the binary is for the Android > > platform. > > > > The patch was accepted by the Google engineers and applied to their > > internal tree. It wasn't merged yet to the AOSP tree because of > > conflicts with some of their internal patches, but will be in the near > > future. > > Thank you very much for persevering. I think that using "GNU" as > ABI_VENDOR for Android isn't the best thing to do, but from skimming > the binutils@ list I see you're already addressing that. Right. I updated the bionic patch in the link above to use .note.android.ident, which is similar to .note.netbsd.ident and .note.openbsd.ident. This patch uses that note, and also moves is_target_linux_android to linux-tdep.c. The function is now called linux_is_target_android for consistency with other functions in that file. -- []'s Thiago Jung Bauermann IBM Linux Technology Center 2012-07-04 Thiago Jung Bauermann Support bionic's jmp_buf. * arm-linux-tdep.c (ARM_LINUX_JB_PC_ANDROID): New macro. (arm_linux_jb_pc): New function. (arm_linux_init_abi): Set tdep->jb_pc to arm_linux_jb_pc instead of determining the jb_pc value right away. * arm-tdep.c (arm_get_longjmp_target): Call tdep->jb_pc. (arm_gdbarch_init): tdep->jb_pc is now a pointer. Assign it and test its value accordingly. * arm-tdep.h (struct gdbarch_tdep): Change jb_pc to a function pointer. * arm-wince-tdep.c (arm_wince_jb_pc): New function. (arm_wince_init_abi): Set tdep->jb_pc to arm_wince_jb_pc. * armnbsd-tdep.c (arm_netbsd_jb_pc): New function. (arm_netbsd_init_abi_common): Set tdep->jb_pc to arm_netbsd_jb_pc. * armobsd-tdep.c (arm_obsd_jb_pc): New function. (armobsd_init_abi): Set tdep->jb_pc to arm_obsd_jb_pc. * linux-tdep.c (NT_ANDROID_IDENT): New macro. (linux_is_target_android): New function. * linux-tdep.h (linux_is_target_android): New prototype. * osabi.c (check_note): Make function non-static. * osabi.h (check_note): New prototype. * solib-svr4.c (find_program_interpreter): Make function non-static. Rename to ... (find_elf_program_interpreter): ... this. * solib-svr4.h (find_program_interpreter): New prototype. diff --git a/gdb/arm-linux-tdep.c b/gdb/arm-linux-tdep.c index f4eaa5c..d35cfd3 100644 --- a/gdb/arm-linux-tdep.c +++ b/gdb/arm-linux-tdep.c @@ -105,6 +105,7 @@ static const char arm_linux_thumb2_le_breakpoint[] = { 0xf0, 0xf7, 0x00, 0xa0 }; #define ARM_LINUX_JB_ELEMENT_SIZE INT_REGISTER_SIZE #define ARM_LINUX_JB_PC_FPA 21 #define ARM_LINUX_JB_PC_EABI 9 +#define ARM_LINUX_JB_PC_ANDROID 29 /* Dynamic Linking on ARM GNU/Linux @@ -1178,6 +1179,36 @@ arm_stap_parse_special_token (struct gdbarch *gdbarch, return 1; } +/* Implements the gdbarch_tdep.jb_pc function in arm-tdep.h. */ + +static CORE_ADDR +arm_linux_jb_pc (struct gdbarch_tdep *tdep) +{ + int jb_pc; + + switch (tdep->fp_model) + { + case ARM_FLOAT_FPA: + jb_pc = ARM_LINUX_JB_PC_FPA; + break; + case ARM_FLOAT_SOFT_FPA: + case ARM_FLOAT_SOFT_VFP: + case ARM_FLOAT_VFP: + jb_pc = ARM_LINUX_JB_PC_EABI; + break; + default: + internal_error + (__FILE__, __LINE__, + _("arm_linux_init_abi: Floating point model not supported")); + break; + } + + if (linux_is_target_android ()) + jb_pc = ARM_LINUX_JB_PC_ANDROID; + + return jb_pc; +} + static void arm_linux_init_abi (struct gdbarch_info info, struct gdbarch *gdbarch) @@ -1212,22 +1243,7 @@ arm_linux_init_abi (struct gdbarch_info info, if (tdep->fp_model == ARM_FLOAT_AUTO) tdep->fp_model = ARM_FLOAT_FPA; - switch (tdep->fp_model) - { - case ARM_FLOAT_FPA: - tdep->jb_pc = ARM_LINUX_JB_PC_FPA; - break; - case ARM_FLOAT_SOFT_FPA: - case ARM_FLOAT_SOFT_VFP: - case ARM_FLOAT_VFP: - tdep->jb_pc = ARM_LINUX_JB_PC_EABI; - break; - default: - internal_error - (__FILE__, __LINE__, - _("arm_linux_init_abi: Floating point model not supported")); - break; - } + tdep->jb_pc = arm_linux_jb_pc; tdep->jb_elt_size = ARM_LINUX_JB_ELEMENT_SIZE; set_solib_svr4_fetch_link_map_offsets diff --git a/gdb/arm-tdep.c b/gdb/arm-tdep.c index 568ace5..f925d44 100644 --- a/gdb/arm-tdep.c +++ b/gdb/arm-tdep.c @@ -9086,12 +9086,13 @@ arm_get_longjmp_target (struct frame_info *frame, CORE_ADDR *pc) struct gdbarch *gdbarch = get_frame_arch (frame); struct gdbarch_tdep *tdep = gdbarch_tdep (gdbarch); enum bfd_endian byte_order = gdbarch_byte_order (gdbarch); - CORE_ADDR jb_addr; + CORE_ADDR jb_addr, jb_pc; char buf[INT_REGISTER_SIZE]; - + jb_addr = get_frame_register_unsigned (frame, ARM_A1_REGNUM); + jb_pc = tdep->jb_pc (tdep); - if (target_read_memory (jb_addr + tdep->jb_pc * tdep->jb_elt_size, buf, + if (target_read_memory (jb_addr + jb_pc * tdep->jb_elt_size, buf, INT_REGISTER_SIZE)) return 0; @@ -10135,7 +10136,7 @@ arm_gdbarch_init (struct gdbarch_info info, struct gdbarch_list *arches) /* This should be low enough for everything. */ tdep->lowest_pc = 0x20; - tdep->jb_pc = -1; /* Longjump support not enabled by default. */ + tdep->jb_pc = NULL; /* Longjump support not enabled by default. */ /* The default, for both APCS and AAPCS, is to return small structures in registers. */ @@ -10239,7 +10240,7 @@ arm_gdbarch_init (struct gdbarch_info info, struct gdbarch_list *arches) if (tdep->fp_model == ARM_FLOAT_AUTO) tdep->fp_model = ARM_FLOAT_SOFT_FPA; - if (tdep->jb_pc >= 0) + if (tdep->jb_pc != NULL) set_gdbarch_get_longjmp_target (gdbarch, arm_get_longjmp_target); /* Floating point sizes and format. */ diff --git a/gdb/arm-tdep.h b/gdb/arm-tdep.h index 97596d5..b95d548 100644 --- a/gdb/arm-tdep.h +++ b/gdb/arm-tdep.h @@ -185,9 +185,9 @@ struct gdbarch_tdep const char *thumb2_breakpoint; int thumb2_breakpoint_size; - int jb_pc; /* Offset to PC value in jump buffer. - If this is negative, longjmp support - will be disabled. */ + /* Return offset to PC value in jump buffer. If this is NULL, longjmp + support will be disabled. */ + CORE_ADDR (*jb_pc) (struct gdbarch_tdep *tdep); size_t jb_elt_size; /* And the size of each entry in the buf. */ /* Convention for returning structures. */ diff --git a/gdb/arm-wince-tdep.c b/gdb/arm-wince-tdep.c index 5bc6473..ce04ba0 100644 --- a/gdb/arm-wince-tdep.c +++ b/gdb/arm-wince-tdep.c @@ -111,6 +111,14 @@ arm_wince_skip_main_prologue (struct gdbarch *gdbarch, CORE_ADDR pc) return pc; } +/* Implements the gdbarch_tdep.jb_pc function in arm-tdep.h. */ + +static CORE_ADDR +arm_wince_jb_pc (struct gdbarch_tdep *tdep) +{ + return ARM_WINCE_JB_PC; +} + static void arm_wince_init_abi (struct gdbarch_info info, struct gdbarch *gdbarch) { @@ -124,7 +132,7 @@ arm_wince_init_abi (struct gdbarch_info info, struct gdbarch *gdbarch) tdep->fp_model = ARM_FLOAT_SOFT_VFP; - tdep->jb_pc = ARM_WINCE_JB_PC; + tdep->jb_pc = arm_wince_jb_pc; tdep->jb_elt_size = ARM_WINCE_JB_ELEMENT_SIZE; /* On ARM WinCE char defaults to signed. */ diff --git a/gdb/armnbsd-tdep.c b/gdb/armnbsd-tdep.c index 19aa000..144bd85 100644 --- a/gdb/armnbsd-tdep.c +++ b/gdb/armnbsd-tdep.c @@ -36,6 +36,14 @@ static const char arm_nbsd_arm_be_breakpoint[] = {0xe6, 0x00, 0x00, 0x11}; static const char arm_nbsd_thumb_le_breakpoint[] = {0xfe, 0xde}; static const char arm_nbsd_thumb_be_breakpoint[] = {0xde, 0xfe}; +/* Implements the gdbarch_tdep.jb_pc function in arm-tdep.h. */ + +static CORE_ADDR +arm_netbsd_jb_pc (struct gdbarch_tdep *tdep) +{ + return ARM_NBSD_JB_PC; +} + static void arm_netbsd_init_abi_common (struct gdbarch_info info, struct gdbarch *gdbarch) @@ -64,7 +72,7 @@ arm_netbsd_init_abi_common (struct gdbarch_info info, _("arm_gdbarch_init: bad byte order for float format")); } - tdep->jb_pc = ARM_NBSD_JB_PC; + tdep->jb_pc = arm_netbsd_jb_pc; tdep->jb_elt_size = ARM_NBSD_JB_ELEMENT_SIZE; /* Single stepping. */ diff --git a/gdb/armobsd-tdep.c b/gdb/armobsd-tdep.c index fab4e42..e48eeaa 100644 --- a/gdb/armobsd-tdep.c +++ b/gdb/armobsd-tdep.c @@ -74,6 +74,14 @@ static const struct tramp_frame armobsd_sigframe = static const char arm_obsd_thumb_le_breakpoint[] = {0xfe, 0xdf}; static const char arm_obsd_thumb_be_breakpoint[] = {0xdf, 0xfe}; +/* Implements the gdbarch_tdep.jb_pc function in arm-tdep.h. */ + +static CORE_ADDR +armobsd_jb_pc (struct gdbarch_tdep *tdep) +{ + return 24; +} + static void armobsd_init_abi (struct gdbarch_info info, struct gdbarch *gdbarch) @@ -90,7 +98,7 @@ armobsd_init_abi (struct gdbarch_info info, (gdbarch, svr4_ilp32_fetch_link_map_offsets); set_gdbarch_skip_solib_resolver (gdbarch, obsd_skip_solib_resolver); - tdep->jb_pc = 24; + tdep->jb_pc = armobsd_jb_pc; tdep->jb_elt_size = 4; set_gdbarch_regset_from_core_section diff --git a/gdb/linux-tdep.c b/gdb/linux-tdep.c index b6f2efb..42da96c 100644 --- a/gdb/linux-tdep.c +++ b/gdb/linux-tdep.c @@ -30,6 +30,8 @@ #include "elf-bfd.h" /* for elfcore_write_* */ #include "inferior.h" #include "cli/cli-utils.h" +#include "osabi.h" +#include "solib-svr4.h" #include @@ -188,6 +190,49 @@ linux_has_shared_address_space (struct gdbarch *gdbarch) return target_is_uclinux; } +/* Type of the .note.android.ident note. Note vendor is "Android". */ +#define NT_ANDROID_IDENT 1 + +/* Determines whether the inferior is an Android application. */ + +int +linux_is_target_android (void) +{ + int ret = 0; + gdb_byte *interp; + + if (exec_bfd + && bfd_get_flavour (exec_bfd) == bfd_target_elf_flavour) + { + struct bfd_section *ident; + + ident = bfd_get_section_by_name (exec_bfd, ".note.android.ident"); + if (ident != NULL) + { + int sect_size = bfd_section_size (exec_bfd, ident); + gdb_byte *note; + + note = alloca (sect_size); + bfd_get_section_contents (exec_bfd, ident, note, 0, sect_size); + + /* Android's ident note has one 32-bit integer specifying the + API level expected by the application. We don't need to + check it yet. */ + return check_note (exec_bfd, ident, note, "Android", 4, + NT_ANDROID_IDENT); + } + } + + interp = find_elf_program_interpreter (); + if (interp) + { + ret = !strcmp (interp, "/system/bin/linker"); + xfree (interp); + } + + return ret; +} + /* This is how we want PTIDs from core files to be printed. */ static char * diff --git a/gdb/linux-tdep.h b/gdb/linux-tdep.h index b211b53..1dab1c7 100644 --- a/gdb/linux-tdep.h +++ b/gdb/linux-tdep.h @@ -36,4 +36,6 @@ struct type *linux_get_siginfo_type (struct gdbarch *); extern void linux_init_abi (struct gdbarch_info info, struct gdbarch *gdbarch); +extern int linux_is_target_android (void); + #endif /* linux-tdep.h */ diff --git a/gdb/osabi.c b/gdb/osabi.c index faffe30..9d3eef4 100644 --- a/gdb/osabi.c +++ b/gdb/osabi.c @@ -372,7 +372,7 @@ gdbarch_init_osabi (struct gdbarch_info info, struct gdbarch *gdbarch) /* Return non-zero if NOTE matches NAME, DESCSZ and TYPE. */ -static int +int check_note (bfd *abfd, asection *sect, const char *note, const char *name, unsigned long descsz, unsigned long type) { diff --git a/gdb/osabi.h b/gdb/osabi.h index ced2fa5..ec3b948 100644 --- a/gdb/osabi.h +++ b/gdb/osabi.h @@ -54,4 +54,8 @@ const char *gdbarch_osabi_name (enum gdb_osabi); via bfd_map_over_sections. */ void generic_elf_osabi_sniff_abi_tag_sections (bfd *, asection *, void *); +/* Return non-zero if NOTE matches NAME, DESCSZ and TYPE. */ +int check_note (bfd *abfd, asection *sect, const char *note, + const char *name, unsigned long descsz, unsigned long type); + #endif /* OSABI_H */ diff --git a/gdb/solib-svr4.c b/gdb/solib-svr4.c index 307e483..cd3be82 100644 --- a/gdb/solib-svr4.c +++ b/gdb/solib-svr4.c @@ -496,8 +496,8 @@ read_program_header (int type, int *p_sect_size, int *p_arch_size) /* Return program interpreter string. */ -static gdb_byte * -find_program_interpreter (void) +gdb_byte * +find_elf_program_interpreter (void) { gdb_byte *buf = NULL; @@ -1528,7 +1528,7 @@ enable_break (struct svr4_info *info, int from_tty) /* Find the program interpreter; if not found, warn the user and drop into the old breakpoint at symbol code. */ - interp_name = find_program_interpreter (); + interp_name = find_elf_program_interpreter (); if (interp_name) { CORE_ADDR load_addr = 0; diff --git a/gdb/solib-svr4.h b/gdb/solib-svr4.h index f9a02c9..87f088d 100644 --- a/gdb/solib-svr4.h +++ b/gdb/solib-svr4.h @@ -84,4 +84,7 @@ extern struct link_map_offsets *svr4_lp64_fetch_link_map_offsets (void); SVR4 run time loader. */ int svr4_in_dynsym_resolve_code (CORE_ADDR pc); +/* Return program interpreter string. */ +gdb_byte *find_elf_program_interpreter (void); + #endif /* solib-svr4.h */