X-Git-Url: http://drtracing.org/?a=blobdiff_plain;f=gdb%2Fgdbserver%2Flinux-i386-ipa.c;h=6cf4e45b48b09befe7f1cc63cca340c8547d3716;hb=476350ba4800f1144b125f6511a5e25b223cc90b;hp=ea6802f432f6f52953a1251c88f60295b2f326fc;hpb=0fb4aa4bfcc2aa61c27132f94cf1656dca137dc9;p=deliverable%2Fbinutils-gdb.git diff --git a/gdb/gdbserver/linux-i386-ipa.c b/gdb/gdbserver/linux-i386-ipa.c index ea6802f432..6cf4e45b48 100644 --- a/gdb/gdbserver/linux-i386-ipa.c +++ b/gdb/gdbserver/linux-i386-ipa.c @@ -1,7 +1,7 @@ /* GNU/Linux/x86 specific low level interface, for the in-process agent library for GDB. - Copyright (C) 2010 Free Software Foundation, Inc. + Copyright (C) 2010-2016 Free Software Foundation, Inc. This file is part of GDB. @@ -19,6 +19,9 @@ along with this program. If not, see . */ #include "server.h" +#include +#include "tracepoint.h" +#include "linux-x86-tdesc.h" /* GDB register numbers. */ @@ -45,9 +48,6 @@ enum i386_gdb_regnum #define i386_num_regs 16 -/* Defined in auto-generated file i386-linux.c. */ -void init_registers_i386_linux (void); - #define FT_CR_EAX 15 #define FT_CR_ECX 14 #define FT_CR_EDX 13 @@ -95,8 +95,8 @@ supply_fast_tracepoint_registers (struct regcache *regcache, } } -ULONGEST __attribute__ ((visibility("default"), used)) -gdb_agent_get_raw_reg (unsigned char *raw_regs, int regnum) +ULONGEST +get_raw_reg (const unsigned char *raw_regs, int regnum) { /* This should maybe be allowed to return an error code, or perhaps better, have the emit_reg detect this, and emit a constant zero, @@ -178,7 +178,7 @@ supply_static_tracepoint_registers (struct regcache *regcache, } break; default: - internal_error ("unhandled register size: %d", + internal_error (__FILE__, __LINE__, "unhandled register size: %d", i386_st_collect_regmap[i].size); } } @@ -191,8 +191,108 @@ supply_static_tracepoint_registers (struct regcache *regcache, may use it proper at some point. */ const char *gdbserver_xmltarget; +/* Attempt to allocate memory for trampolines in the first 64 KiB of + memory to enable smaller jump patches. */ + +static void +initialize_fast_tracepoint_trampoline_buffer (void) +{ + const CORE_ADDR buffer_end = 64 * 1024; + /* Ensure that the buffer will be at least 1 KiB in size, which is + enough space for over 200 fast tracepoints. */ + const int min_buffer_size = 1024; + char buf[IPA_BUFSIZ]; + CORE_ADDR mmap_min_addr = buffer_end + 1; + ULONGEST buffer_size; + FILE *f = fopen ("/proc/sys/vm/mmap_min_addr", "r"); + + if (!f) + { + snprintf (buf, sizeof (buf), "mmap_min_addr open failed: %s", + strerror (errno)); + set_trampoline_buffer_space (0, 0, buf); + return; + } + + if (fgets (buf, IPA_BUFSIZ, f)) + sscanf (buf, "%llu", &mmap_min_addr); + + fclose (f); + + buffer_size = buffer_end - mmap_min_addr; + + if (buffer_size >= min_buffer_size) + { + if (mmap ((void *) (uintptr_t) mmap_min_addr, buffer_size, + PROT_READ | PROT_EXEC | PROT_WRITE, + MAP_FIXED | MAP_PRIVATE | MAP_ANONYMOUS, + -1, 0) + != MAP_FAILED) + set_trampoline_buffer_space (mmap_min_addr, buffer_end, NULL); + else + { + snprintf (buf, IPA_BUFSIZ, "low-64K-buffer mmap() failed: %s", + strerror (errno)); + set_trampoline_buffer_space (0, 0, buf); + } + } + else + { + snprintf (buf, IPA_BUFSIZ, "mmap_min_addr is %d, must be %d or less", + (int) mmap_min_addr, (int) buffer_end - min_buffer_size); + set_trampoline_buffer_space (0, 0, buf); + } +} + +/* Return target_desc to use for IPA, given the tdesc index passed by + gdbserver. */ + +const struct target_desc * +get_ipa_tdesc (int idx) +{ + switch (idx) + { + case X86_TDESC_MMX: + return tdesc_i386_mmx_linux; + case X86_TDESC_SSE: + return tdesc_i386_linux; + case X86_TDESC_AVX: + return tdesc_i386_avx_linux; + case X86_TDESC_MPX: + return tdesc_i386_mpx_linux; + case X86_TDESC_AVX_MPX: + return tdesc_i386_avx_mpx_linux; + case X86_TDESC_AVX512: + return tdesc_i386_avx512_linux; + default: + internal_error (__FILE__, __LINE__, + "unknown ipa tdesc index: %d", idx); + return tdesc_i386_linux; + } +} + +/* Allocate buffer for the jump pads. On i386, we can reach an arbitrary + address with a jump instruction, so just allocate normally. */ + +void * +alloc_jump_pad_buffer (size_t size) +{ + void *res = mmap (NULL, size, PROT_READ | PROT_WRITE | PROT_EXEC, + MAP_PRIVATE | MAP_ANONYMOUS, -1, 0); + + if (res == MAP_FAILED) + return NULL; + + return res; +} + void initialize_low_tracepoint (void) { + init_registers_i386_mmx_linux (); init_registers_i386_linux (); + init_registers_i386_avx_linux (); + init_registers_i386_mpx_linux (); + init_registers_i386_avx512_linux (); + initialize_fast_tracepoint_trampoline_buffer (); }