X-Git-Url: https://git.libre-soc.org/?a=blobdiff_plain;f=gdb%2Flinux-tdep.c;h=c51ede9c618f8eb99f3c483a36020b70560b3e05;hb=809df4465f01277ab689fb82b3f16ff79f9a2606;hp=e18e134ed361afc648f886087cdb83e6a8a3ab44;hpb=2c0b251b29eeafa90c84a3a938c744bc7ba81aea;p=binutils-gdb.git diff --git a/gdb/linux-tdep.c b/gdb/linux-tdep.c index e18e134ed36..c51ede9c618 100644 --- a/gdb/linux-tdep.c +++ b/gdb/linux-tdep.c @@ -1,6 +1,6 @@ /* Target-dependent code for GNU/Linux, architecture independent. - Copyright (C) 2009 Free Software Foundation, Inc. + Copyright (C) 2009, 2010 Free Software Foundation, Inc. This file is part of GDB. @@ -20,6 +20,29 @@ #include "defs.h" #include "gdbtypes.h" #include "linux-tdep.h" +#include "auxv.h" +#include "target.h" +#include "elf/common.h" +#include "inferior.h" + +static struct gdbarch_data *linux_gdbarch_data_handle; + +struct linux_gdbarch_data + { + struct type *siginfo_type; + }; + +static void * +init_linux_gdbarch_data (struct gdbarch *gdbarch) +{ + return GDBARCH_OBSTACK_ZALLOC (gdbarch, struct linux_gdbarch_data); +} + +static struct linux_gdbarch_data * +get_linux_gdbarch_data (struct gdbarch *gdbarch) +{ + return gdbarch_data (gdbarch, linux_gdbarch_data_handle); +} /* This function is suitable for architectures that don't extend/override the standard siginfo structure. */ @@ -27,49 +50,51 @@ struct type * linux_get_siginfo_type (struct gdbarch *gdbarch) { + struct linux_gdbarch_data *linux_gdbarch_data; struct type *int_type, *uint_type, *long_type, *void_ptr_type; struct type *uid_type, *pid_type; struct type *sigval_type, *clock_type; struct type *siginfo_type, *sifields_type; struct type *type; - int_type = init_type (TYPE_CODE_INT, - gdbarch_int_bit (gdbarch) / HOST_CHAR_BIT, - 0, "int", NULL); - uint_type = init_type (TYPE_CODE_INT, - gdbarch_int_bit (gdbarch) / HOST_CHAR_BIT, - 0, "unsigned int", NULL); - long_type = init_type (TYPE_CODE_INT, - gdbarch_long_bit (gdbarch) / HOST_CHAR_BIT, - 0, "long", NULL); + linux_gdbarch_data = get_linux_gdbarch_data (gdbarch); + if (linux_gdbarch_data->siginfo_type != NULL) + return linux_gdbarch_data->siginfo_type; + + int_type = arch_integer_type (gdbarch, gdbarch_int_bit (gdbarch), + 0, "int"); + uint_type = arch_integer_type (gdbarch, gdbarch_int_bit (gdbarch), + 1, "unsigned int"); + long_type = arch_integer_type (gdbarch, gdbarch_long_bit (gdbarch), + 0, "long"); void_ptr_type = lookup_pointer_type (builtin_type (gdbarch)->builtin_void); /* sival_t */ - sigval_type = init_composite_type (NULL, TYPE_CODE_UNION); + sigval_type = arch_composite_type (gdbarch, NULL, TYPE_CODE_UNION); TYPE_NAME (sigval_type) = xstrdup ("sigval_t"); append_composite_type_field (sigval_type, "sival_int", int_type); append_composite_type_field (sigval_type, "sival_ptr", void_ptr_type); /* __pid_t */ - pid_type = init_type (TYPE_CODE_TYPEDEF, TYPE_LENGTH (int_type), - TYPE_FLAG_TARGET_STUB, NULL, NULL); - TYPE_NAME (pid_type) = xstrdup ("__pid_t"); + pid_type = arch_type (gdbarch, TYPE_CODE_TYPEDEF, TYPE_LENGTH (int_type), + xstrdup ("__pid_t")); TYPE_TARGET_TYPE (pid_type) = int_type; + TYPE_TARGET_STUB (pid_type) = 1; /* __uid_t */ - uid_type = init_type (TYPE_CODE_TYPEDEF, TYPE_LENGTH (uint_type), - TYPE_FLAG_TARGET_STUB, NULL, NULL); - TYPE_NAME (uid_type) = xstrdup ("__uid_t"); + uid_type = arch_type (gdbarch, TYPE_CODE_TYPEDEF, TYPE_LENGTH (uint_type), + xstrdup ("__uid_t")); TYPE_TARGET_TYPE (uid_type) = uint_type; + TYPE_TARGET_STUB (uid_type) = 1; /* __clock_t */ - clock_type = init_type (TYPE_CODE_TYPEDEF, TYPE_LENGTH (long_type), - TYPE_FLAG_TARGET_STUB, NULL, NULL); - TYPE_NAME (clock_type) = xstrdup ("__clock_t"); + clock_type = arch_type (gdbarch, TYPE_CODE_TYPEDEF, TYPE_LENGTH (long_type), + xstrdup ("__clock_t")); TYPE_TARGET_TYPE (clock_type) = long_type; + TYPE_TARGET_STUB (clock_type) = 1; /* _sifields */ - sifields_type = init_composite_type (NULL, TYPE_CODE_UNION); + sifields_type = arch_composite_type (gdbarch, NULL, TYPE_CODE_UNION); { const int si_max_size = 128; @@ -86,27 +111,27 @@ linux_get_siginfo_type (struct gdbarch *gdbarch) } /* _kill */ - type = init_composite_type (NULL, TYPE_CODE_STRUCT); + type = arch_composite_type (gdbarch, NULL, TYPE_CODE_STRUCT); append_composite_type_field (type, "si_pid", pid_type); append_composite_type_field (type, "si_uid", uid_type); append_composite_type_field (sifields_type, "_kill", type); /* _timer */ - type = init_composite_type (NULL, TYPE_CODE_STRUCT); + type = arch_composite_type (gdbarch, NULL, TYPE_CODE_STRUCT); append_composite_type_field (type, "si_tid", int_type); append_composite_type_field (type, "si_overrun", int_type); append_composite_type_field (type, "si_sigval", sigval_type); append_composite_type_field (sifields_type, "_timer", type); /* _rt */ - type = init_composite_type (NULL, TYPE_CODE_STRUCT); + type = arch_composite_type (gdbarch, NULL, TYPE_CODE_STRUCT); append_composite_type_field (type, "si_pid", pid_type); append_composite_type_field (type, "si_uid", uid_type); append_composite_type_field (type, "si_sigval", sigval_type); append_composite_type_field (sifields_type, "_rt", type); /* _sigchld */ - type = init_composite_type (NULL, TYPE_CODE_STRUCT); + type = arch_composite_type (gdbarch, NULL, TYPE_CODE_STRUCT); append_composite_type_field (type, "si_pid", pid_type); append_composite_type_field (type, "si_uid", uid_type); append_composite_type_field (type, "si_status", int_type); @@ -115,18 +140,18 @@ linux_get_siginfo_type (struct gdbarch *gdbarch) append_composite_type_field (sifields_type, "_sigchld", type); /* _sigfault */ - type = init_composite_type (NULL, TYPE_CODE_STRUCT); + type = arch_composite_type (gdbarch, NULL, TYPE_CODE_STRUCT); append_composite_type_field (type, "si_addr", void_ptr_type); append_composite_type_field (sifields_type, "_sigfault", type); /* _sigpoll */ - type = init_composite_type (NULL, TYPE_CODE_STRUCT); + type = arch_composite_type (gdbarch, NULL, TYPE_CODE_STRUCT); append_composite_type_field (type, "si_band", long_type); append_composite_type_field (type, "si_fd", int_type); append_composite_type_field (sifields_type, "_sigpoll", type); /* struct siginfo */ - siginfo_type = init_composite_type (NULL, TYPE_CODE_STRUCT); + siginfo_type = arch_composite_type (gdbarch, NULL, TYPE_CODE_STRUCT); TYPE_NAME (siginfo_type) = xstrdup ("siginfo"); append_composite_type_field (siginfo_type, "si_signo", int_type); append_composite_type_field (siginfo_type, "si_errno", int_type); @@ -135,5 +160,54 @@ linux_get_siginfo_type (struct gdbarch *gdbarch) "_sifields", sifields_type, TYPE_LENGTH (long_type)); + linux_gdbarch_data->siginfo_type = siginfo_type; + return siginfo_type; } + +int +linux_has_shared_address_space (void) +{ + /* Determine whether we are running on uClinux or normal Linux + kernel. */ + CORE_ADDR dummy; + int target_is_uclinux; + + target_is_uclinux + = (target_auxv_search (¤t_target, AT_NULL, &dummy) > 0 + && target_auxv_search (¤t_target, AT_PAGESZ, &dummy) == 0); + + return target_is_uclinux; +} + +/* This is how we want PTIDs from core files to be printed. */ + +static char * +linux_core_pid_to_str (struct gdbarch *gdbarch, ptid_t ptid) +{ + static char buf[80]; + + if (ptid_get_lwp (ptid) != 0) + { + snprintf (buf, sizeof (buf), "LWP %ld", ptid_get_lwp (ptid)); + return buf; + } + + return normal_pid_to_str (ptid); +} + +/* To be called from the various GDB_OSABI_LINUX handlers for the + various GNU/Linux architectures and machine types. */ + +void +linux_init_abi (struct gdbarch_info info, struct gdbarch *gdbarch) +{ + set_gdbarch_core_pid_to_str (gdbarch, linux_core_pid_to_str); +} + +void +_initialize_linux_tdep (void) +{ + linux_gdbarch_data_handle = + gdbarch_data_register_post_init (init_linux_gdbarch_data); +}