* [patch] Support bionic's jmp_buf. @ 2012-05-21 0:36 Thiago Jung Bauermann 2012-05-21 11:38 ` Pedro Alves 0 siblings, 1 reply; 9+ messages in thread From: Thiago Jung Bauermann @ 2012-05-21 0:36 UTC (permalink / raw) To: gdb-patches ml Hello, Android uses a libc (bionic) which is derived from BSD instead of glibc, and stores the PC value at a different location in the jump buffer than regular arm-linux. Also, since there's no PC mangling this code works even without SystemTap probes. I'm using the ELF interpreter field to identify an Android binary (the program loader is /system/bin/linker). Also, I had to change gdbarch_tdep->jb_pc to a function so that the code to determine which kind of program we are dealing with runs when the value is actually needed. This is because by the time arm_linux_init_abi is called exec_bfd hasn't been set yet so there's no way to peek at the ELF interpreter field. This patch fixes gdb.base/longjmp.exp. There are no regressions on arm-linux native, arm-linux remote or i386-linux native. Ok? -- []'s Thiago Jung Bauermann Linaro Toolchain Working Group 2012-05-20 Thiago Jung Bauermann <thiago.bauermann@linaro.org> Support bionic's jmp_buf. * arm-linux-tdep.c (ARM_LINUX_JB_PC_ANDROID): New macro. (is_target_linux_android): New function. (arm_linux_jb_pc): Likewise. (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. * solib-svr4.c (find_program_interpreter): Remove static keyword. 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..b9d67b0 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,54 @@ arm_stap_parse_special_token (struct gdbarch *gdbarch, return 1; } +/* Determines whether the inferior is an Android application. */ + +static int +is_target_linux_android (void) +{ + int ret = 0; + gdb_byte *interp; + + interp = find_elf_program_interpreter (); + if (interp) + { + ret = !strcmp (interp, "/system/bin/linker"); + xfree (interp); + } + + return ret; +} + +/* 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 (is_target_linux_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 +1261,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 df5dea7..d1aa6b5 100644 --- a/gdb/arm-tdep.c +++ b/gdb/arm-tdep.c @@ -9083,12 +9083,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; @@ -10132,7 +10133,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. */ @@ -10236,7 +10237,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/solib-svr4.c b/gdb/solib-svr4.c index 69d3cb5..24f224f 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; @@ -1520,7 +1520,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 */ ^ permalink raw reply [flat|nested] 9+ messages in thread
* Re: [patch] Support bionic's jmp_buf. 2012-05-21 0:36 [patch] Support bionic's jmp_buf Thiago Jung Bauermann @ 2012-05-21 11:38 ` Pedro Alves 2012-05-21 17:59 ` Thiago Jung Bauermann 0 siblings, 1 reply; 9+ messages in thread From: Pedro Alves @ 2012-05-21 11:38 UTC (permalink / raw) To: Thiago Jung Bauermann; +Cc: gdb-patches ml On 05/21/2012 01:35 AM, Thiago Jung Bauermann wrote: > Hello, > > Android uses a libc (bionic) which is derived from BSD instead of glibc, > and stores the PC value at a different location in the jump buffer than > regular arm-linux. Also, since there's no PC mangling this code works > even without SystemTap probes. > > I'm using the ELF interpreter field to identify an Android binary (the > program loader is /system/bin/linker). Urgh. Isn't there a better way? This doesn't work with shared libraries, for starters. But I think question number one is: - Shouldn't there be an "Android" or "Bionic/Linux" OSABI instead of abusing "GNU/Linux" ? -- Pedro Alves ^ permalink raw reply [flat|nested] 9+ messages in thread
* Re: [patch] Support bionic's jmp_buf. 2012-05-21 11:38 ` Pedro Alves @ 2012-05-21 17:59 ` Thiago Jung Bauermann 2012-06-24 21:46 ` Thiago Jung Bauermann 0 siblings, 1 reply; 9+ messages in thread From: Thiago Jung Bauermann @ 2012-05-21 17:59 UTC (permalink / raw) To: Pedro Alves; +Cc: gdb-patches ml Hello Pedro, Thanks for the quick response. On Mon, 2012-05-21 at 12:38 +0100, Pedro Alves wrote: > On 05/21/2012 01:35 AM, Thiago Jung Bauermann wrote: > > I'm using the ELF interpreter field to identify an Android binary (the > > program loader is /system/bin/linker). > > > Urgh. Isn't there a better way? This doesn't work with shared libraries, > for starters. There is. I thought of adding an Android flag to .note.ABI-tag and I even have a patch ready which adds it to Android binaries. I gave up on it because I thought it was overkill but I can certainly use that if using the interpreter field is a worse solution. Regarding shared libraries, does it matter? If the executable uses bionic, then the shared libraries can't be using something else, or can they? > But I think question number one is: > > - Shouldn't there be an "Android" or "Bionic/Linux" OSABI instead > of abusing "GNU/Linux" ? I think it shouldn't, and I think it's not abuse. Android has the same ABI as GNU/Linux, the differences are in implementation details outside the scope of the ABI: "Note that the AAPCS standard defines 'EABI' as a moniker used to specify a _family_ of similar but distinct ABIs. Android follows the little-endian ARM GNU/Linux ABI as documented in the following document: http://www.codesourcery.com/gnu_toolchains/arm/arm_gnu_linux_abi.pdf With the exception that wchar_t is only one byte. This should not matter in practice since wchar_t is simply *not* really supported by the Android platform anyway. This ABI does *not* support hardware-assisted floating point computations. Instead, all FP operations are performed through software helper functions that come from the compiler's libgcc.a static library." It also doesn't support C++ exceptions. [1] http://www.kandroid.org/ndk/docs/CPU-ARCH-ABIS.html -- []'s Thiago Jung Bauermann Linaro Toolchain Working Group ^ permalink raw reply [flat|nested] 9+ messages in thread
* Re: [patch] Support bionic's jmp_buf. 2012-05-21 17:59 ` Thiago Jung Bauermann @ 2012-06-24 21:46 ` Thiago Jung Bauermann 2012-06-25 13:32 ` Yao Qi 2012-06-27 10:18 ` Pedro Alves 0 siblings, 2 replies; 9+ messages in thread From: Thiago Jung Bauermann @ 2012-06-24 21:46 UTC (permalink / raw) To: Pedro Alves; +Cc: gdb-patches ml On Mon, 2012-05-21 at 14:59 -0300, Thiago Jung Bauermann wrote: > On Mon, 2012-05-21 at 12:38 +0100, Pedro Alves wrote: > > On 05/21/2012 01:35 AM, Thiago Jung Bauermann wrote: > > > I'm using the ELF interpreter field to identify an Android binary (the > > > program loader is /system/bin/linker). > > > > > > Urgh. Isn't there a better way? This doesn't work with shared libraries, > > for starters. > > There is. I thought of adding an Android flag to .note.ABI-tag and I > even have a patch ready which adds it to Android binaries. I gave up on > it because I thought it was overkill but I can certainly use that if > using the interpreter field is a worse solution. 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. The patch below checks the .note.ABI-tag if it is present. If it is not, then it will fall back to checking the interpreter field. WDYT? -- []'s Thiago Jung Bauermann Linaro Toolchain Working Group 2012-06-24 Thiago Jung Bauermann <thiago.bauermann@linaro.org> Support bionic's jmp_buf. * arm-linux-tdep.c (ARM_LINUX_JB_PC_ANDROID): New macro. (is_target_linux_android): New function. (arm_linux_jb_pc): Likewise. (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. * osabi.c (check_note): Remove static keyword. * osabi.h (check_note): New prototype. * solib-svr4.c (find_program_interpreter): Remove static keyword. 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..eac7602 100644 --- a/gdb/arm-linux-tdep.c +++ b/gdb/arm-linux-tdep.c @@ -33,6 +33,7 @@ #include "tramp-frame.h" #include "breakpoint.h" #include "auxv.h" +#include "elf/common.h" #include "arm-tdep.h" #include "arm-linux-tdep.h" @@ -105,6 +106,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 +1180,85 @@ arm_stap_parse_special_token (struct gdbarch *gdbarch, return 1; } +/* Determines whether the inferior is an Android application. */ + +static int +is_target_linux_android (void) +{ + int ret = 0; + gdb_byte *interp; + + if (exec_bfd + && bfd_get_flavour (exec_bfd) == bfd_target_elf_flavour) + { + struct bfd_section *abi_tag; + + abi_tag = bfd_get_section_by_name (exec_bfd, ".note.ABI-tag"); + if (abi_tag != NULL) + { + int sect_size = bfd_section_size (exec_bfd, abi_tag); + gdb_byte *note; + + note = alloca (sect_size); + bfd_get_section_contents (exec_bfd, abi_tag, note, 0, sect_size); + + /* Android's .note.ABI-tag has two 32 bit integers after the + kernel version, so it's description size is 24 bytes. */ + if (!check_note (exec_bfd, abi_tag, note, "GNU", 24, NT_GNU_ABI_TAG)) + return 0; + + /* Check the OS. */ + if (bfd_h_get_32 (exec_bfd, note + 16) != GNU_ABI_TAG_LINUX) + return 0; + + /* Check the the OS variant (1 means Android). */ + if (bfd_h_get_32 (exec_bfd, note + 32) != 1) + return 0; + + return 1; + } + } + + interp = find_elf_program_interpreter (); + if (interp) + { + ret = !strcmp (interp, "/system/bin/linker"); + xfree (interp); + } + + return ret; +} + +/* 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 (is_target_linux_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 +1293,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 df5dea7..d1aa6b5 100644 --- a/gdb/arm-tdep.c +++ b/gdb/arm-tdep.c @@ -9083,12 +9083,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; @@ -10132,7 +10133,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. */ @@ -10236,7 +10237,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/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 */ ^ permalink raw reply [flat|nested] 9+ messages in thread
* Re: [patch] Support bionic's jmp_buf. 2012-06-24 21:46 ` Thiago Jung Bauermann @ 2012-06-25 13:32 ` Yao Qi 2012-06-25 17:55 ` Thiago Jung Bauermann 2012-06-27 10:18 ` Pedro Alves 1 sibling, 1 reply; 9+ messages in thread From: Yao Qi @ 2012-06-25 13:32 UTC (permalink / raw) To: gdb-patches; +Cc: Thiago Jung Bauermann, Pedro Alves On Sunday, June 24, 2012 06:46:15 PM Thiago Jung Bauermann wrote: > +/* Determines whether the inferior is an Android application. */ > + > +static int > +is_target_linux_android (void) Looks this function is not arm-specific, so we can move it to linux-tdep.c. -- Yao (齐尧) ^ permalink raw reply [flat|nested] 9+ messages in thread
* Re: [patch] Support bionic's jmp_buf. 2012-06-25 13:32 ` Yao Qi @ 2012-06-25 17:55 ` Thiago Jung Bauermann 2012-06-25 20:49 ` Schnell, Fabian 0 siblings, 1 reply; 9+ messages in thread From: Thiago Jung Bauermann @ 2012-06-25 17:55 UTC (permalink / raw) To: Yao Qi; +Cc: gdb-patches, Pedro Alves Hello, On Mon, 2012-06-25 at 21:32 +0800, Yao Qi wrote: > On Sunday, June 24, 2012 06:46:15 PM Thiago Jung Bauermann wrote: > > +/* Determines whether the inferior is an Android application. */ > > + > > +static int > > +is_target_linux_android (void) > > Looks this function is not arm-specific, so we can move it to linux-tdep.c. Thanks for your review. Android is officially supported on ARM and x86. I don't know how GDB fares on Android on x86, and at least for now it will only be used on ARM (I don't have plans to work on Android on x86). With that said, I'm happy to move to linux-tdep.c if that makes more sense. I'll do the change before I commit or on the next iteration of the patch if there is one. -- []'s Thiago Jung Bauermann Linaro Toolchain Working Group ^ permalink raw reply [flat|nested] 9+ messages in thread
* Re: [patch] Support bionic's jmp_buf. 2012-06-25 17:55 ` Thiago Jung Bauermann @ 2012-06-25 20:49 ` Schnell, Fabian 0 siblings, 0 replies; 9+ messages in thread From: Schnell, Fabian @ 2012-06-25 20:49 UTC (permalink / raw) To: Thiago Jung Bauermann; +Cc: Yao Qi, gdb-patches, Pedro Alves On 6/25/2012 10:54 AM, Thiago Jung Bauermann wrote: > Hello, > > On Mon, 2012-06-25 at 21:32 +0800, Yao Qi wrote: >> On Sunday, June 24, 2012 06:46:15 PM Thiago Jung Bauermann wrote: >>> +/* Determines whether the inferior is an Android application. */ >>> + >>> +static int >>> +is_target_linux_android (void) >> Looks this function is not arm-specific, so we can move it to linux-tdep.c. > Thanks for your review. > > Android is officially supported on ARM and x86. I don't know how GDB > fares on Android on x86, and at least for now it will only be used on > ARM (I don't have plans to work on Android on x86). > > With that said, I'm happy to move to linux-tdep.c if that makes more > sense. I'll do the change before I commit or on the next iteration of > the patch if there is one. > Looking at the original patch, the code is not required for bionic on x86. Yet, to have this function in a shared location might make it easier to code dependencies in the future. - Fabian ^ permalink raw reply [flat|nested] 9+ messages in thread
* Re: [patch] Support bionic's jmp_buf. 2012-06-24 21:46 ` Thiago Jung Bauermann 2012-06-25 13:32 ` Yao Qi @ 2012-06-27 10:18 ` Pedro Alves 2012-07-04 21:08 ` Thiago Jung Bauermann 1 sibling, 1 reply; 9+ messages in thread From: Pedro Alves @ 2012-06-27 10:18 UTC (permalink / raw) To: Thiago Jung Bauermann; +Cc: gdb-patches ml On 06/24/2012 10:46 PM, Thiago Jung Bauermann wrote:>>> Urgh. Isn't there a better way? This doesn't work with shared libraries, >>> > > for starters. >> > >> > There is. I thought of adding an Android flag to .note.ABI-tag and I >> > even have a patch ready which adds it to Android binaries. I gave up on >> > it because I thought it was overkill but I can certainly use that if >> > using the interpreter field is a worse solution. > 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. -- Pedro Alves ^ permalink raw reply [flat|nested] 9+ messages in thread
* Re: [patch] Support bionic's jmp_buf. 2012-06-27 10:18 ` Pedro Alves @ 2012-07-04 21:08 ` Thiago Jung Bauermann 0 siblings, 0 replies; 9+ messages in thread From: Thiago Jung Bauermann @ 2012-07-04 21:08 UTC (permalink / raw) To: Pedro Alves; +Cc: gdb-patches ml, Yao Qi, Schnell, Fabian 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 <thiago.bauermann@linaro.org> 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 <ctype.h> @@ -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 */ ^ permalink raw reply [flat|nested] 9+ messages in thread
end of thread, other threads:[~2012-07-04 21:08 UTC | newest] Thread overview: 9+ messages (download: mbox.gz / follow: Atom feed) -- links below jump to the message on this page -- 2012-05-21 0:36 [patch] Support bionic's jmp_buf Thiago Jung Bauermann 2012-05-21 11:38 ` Pedro Alves 2012-05-21 17:59 ` Thiago Jung Bauermann 2012-06-24 21:46 ` Thiago Jung Bauermann 2012-06-25 13:32 ` Yao Qi 2012-06-25 17:55 ` Thiago Jung Bauermann 2012-06-25 20:49 ` Schnell, Fabian 2012-06-27 10:18 ` Pedro Alves 2012-07-04 21:08 ` Thiago Jung Bauermann
This is a public inbox, see mirroring instructions for how to clone and mirror all data and code used for this inbox