• R/O
  • HTTP
  • SSH
  • HTTPS

Commit

Tags
Keine Tags

Frequently used words (click to add to your profile)

javac++androidlinuxc#windowsobjective-ccocoa誰得qtpythonphprubygameguibathyscaphec計画中(planning stage)翻訳omegatframeworktwitterdomtestvb.netdirectxゲームエンジンbtronarduinopreviewer

GNU Binutils with patches for OS216


Commit MetaInfo

Revision3626824cea3dd1dc27f0d121c283dde67d8ef56c (tree)
Zeit2017-03-17 01:01:49
AutorPhilipp Rudo <prudo@linu...>
CommiterAndreas Arnez

Log Message

Add S390 support for linux-kernel target

After implementing the new linux-kernel target and preparing s390-tdep.
It is now time to get everything to work. Thus implement the hooks
required by the linux-kernel target and enable s390's privileged
registers.

gdb/ChangeLog:

* s390-lk-tdep.h: New file.
* s390-lk-tdep.c: New file.
* Makefile.in (ALL_TARGET_OBS): Add s390-lk-tdep.o.
(HFILES_NO_SRCDIR): Add s390-lk-tdep.h.
(ALLDEPFILES): Add s390-lk-tdep.c.
* configure.tgt (s390*-*-linux*): Add s390-lk-tdep.o.
* s390-tdep.h: Define macros for address translation.
* s390-tdep.c (s390-lk-tdep.h): New include.
(s390_iterate_over_regset_sections): Enable privileged registers.
(s390_core_read_description): Enable privileged registers.
(s390_gdbarch_init): : Enable privileged registers and adjust.

Ändern Zusammenfassung

Diff

--- a/gdb/Makefile.in
+++ b/gdb/Makefile.in
@@ -863,6 +863,7 @@ ALL_TARGET_OBS = \
863863 rs6000-tdep.o \
864864 rx-tdep.o \
865865 s390-linux-tdep.o \
866+ s390-lk-tdep.o \
866867 s390-tdep.o \
867868 score-tdep.o \
868869 sh-linux-tdep.o \
@@ -1421,6 +1422,7 @@ HFILES_NO_SRCDIR = \
14211422 rs6000-aix-tdep.h \
14221423 rs6000-tdep.h \
14231424 s390-linux-tdep.h \
1425+ s390-lk-tdep.h \
14241426 s390-tdep.h \
14251427 score-tdep.h \
14261428 selftest-arch.h \
@@ -2620,6 +2622,7 @@ ALLDEPFILES = \
26202622 rx-tdep.c \
26212623 s390-linux-nat.c \
26222624 s390-linux-tdep.c \
2625+ s390-lk-tdep.c \
26232626 s390-tdep.c \
26242627 score-tdep.c \
26252628 ser-go32.c \
--- a/gdb/configure.tgt
+++ b/gdb/configure.tgt
@@ -482,8 +482,9 @@ powerpc*-*-*)
482482
483483 s390*-*-linux*)
484484 # Target: S390 running Linux
485- gdb_target_obs="s390-tdep.o s390-linux-tdep.o solib-svr4.o \
486- linux-tdep.o linux-record.o ${lk_target_obs}"
485+ gdb_target_obs="s390-tdep.o s390-linux-tdep.o s390-lk-tdep.o \
486+ solib-svr4.o linux-tdep.o linux-record.o \
487+ ${lk_target_obs}"
487488 build_gdbserver=yes
488489 ;;
489490
--- /dev/null
+++ b/gdb/s390-lk-tdep.c
@@ -0,0 +1,390 @@
1+/* Target-dependent code for linux-kernel target on S390.
2+ Copyright (C) 2017 Free Software Foundation, Inc.
3+
4+ This file is part of GDB.
5+
6+ This program is free software; you can redistribute it and/or modify
7+ it under the terms of the GNU General Public License as published by
8+ the Free Software Foundation; either version 3 of the License, or
9+ (at your option) any later version.
10+
11+ This program is distributed in the hope that it will be useful,
12+ but WITHOUT ANY WARRANTY; without even the implied warranty of
13+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
14+ GNU General Public License for more details.
15+
16+ You should have received a copy of the GNU General Public License
17+ along with this program. If not, see <http://www.gnu.org/licenses/>. */
18+
19+#include "defs.h"
20+
21+#include "gdbarch.h"
22+#include "gdbcore.h"
23+#include "gdbthread.h"
24+#include "lk-low.h"
25+#include "osabi.h"
26+#include "regcache.h"
27+#include "regset.h"
28+#include "s390-tdep.h"
29+#include "s390-lk-tdep.h"
30+
31+#include "features/s390x-cr-linux64.c"
32+#include "features/s390x-vxcr-linux64.c"
33+
34+/* Register maps and sets. */
35+
36+static const struct regcache_map_entry s390x_gregmap_lk[] =
37+ {
38+ { 10, S390_R6_REGNUM }, /* r0-r5 volatile */
39+ { -2, REGCACHE_MAP_SKIP, 8 },
40+ { 1, S390_PSWA_REGNUM }, /* Use r14 for PSWA. */
41+ { 0 }
42+ };
43+
44+static const struct regcache_map_entry s390x_regmap_cr [] =
45+ {
46+ { 16, S390_CR0_REGNUM, 8 },
47+ { 0 }
48+ };
49+
50+static const struct regcache_map_entry s390x_regmap_timer [] =
51+ {
52+ { 1, S390_TIMER_REGNUM, 8 },
53+ { 0 }
54+ };
55+
56+static const struct regcache_map_entry s390x_regmap_todcmp [] =
57+ {
58+ { 1, S390_TODCMP_REGNUM, 8 },
59+ { 0 }
60+ };
61+
62+static const struct regcache_map_entry s390x_regmap_todpreg [] =
63+ {
64+ { 1, S390_TODPREG_REGNUM, 4 },
65+ { 0 }
66+ };
67+
68+static const struct regcache_map_entry s390x_regmap_prefix [] =
69+ {
70+ { 1, S390_PREFIX_REGNUM, 4 },
71+ { 0 }
72+ };
73+
74+const struct regset s390x_gregset_lk = {
75+ s390x_gregmap_lk,
76+ regcache_supply_regset,
77+ regcache_collect_regset
78+};
79+
80+const struct regset s390x_cr_regset = {
81+ s390x_regmap_cr,
82+ regcache_supply_regset,
83+ regcache_collect_regset
84+};
85+
86+const struct regset s390x_timer_regset = {
87+ s390x_regmap_timer,
88+ regcache_supply_regset,
89+ regcache_collect_regset
90+};
91+
92+const struct regset s390x_todcmp_regset = {
93+ s390x_regmap_todcmp,
94+ regcache_supply_regset,
95+ regcache_collect_regset
96+};
97+
98+const struct regset s390x_todpreg_regset = {
99+ s390x_regmap_todpreg,
100+ regcache_supply_regset,
101+ regcache_collect_regset
102+};
103+
104+const struct regset s390x_prefix_regset = {
105+ s390x_regmap_prefix,
106+ regcache_supply_regset,
107+ regcache_collect_regset
108+};
109+
110+/* Function for Linux kernel target get_registers hook. Supplies gprs for
111+ task TASK to REGCACHE. Uses r14 (back jump address) as current pswa. */
112+
113+void
114+s390_lk_get_registers (CORE_ADDR task, struct target_ops *target,
115+ struct regcache *regcache, int regnum)
116+{
117+ const struct regset *regset;
118+ CORE_ADDR ksp, gprs, pswa;
119+ gdb_byte buf[80]; /* 80 = 10 (#registers saved) * 8 (64 bit width) */
120+ size_t size;
121+
122+ regset = &s390x_gregset_lk;
123+
124+ ksp = lk_read_addr (task + LK_OFFSET (task_struct, thread)
125+ + LK_OFFSET (thread_struct, ksp));
126+ gprs = ksp + LK_OFFSET (stack_frame, gprs);
127+ size = FIELD_SIZE (LK_FIELD (stack_frame, gprs));
128+ gdb_assert (size <= sizeof (buf));
129+
130+ read_memory (gprs, buf, size);
131+ regset->supply_regset (regset, regcache, -1, buf, size);
132+}
133+
134+/* Function for Linux kernel target get_percpu_offset hook. Returns the
135+ percpu_offset from lowcore for cpu CPU. */
136+
137+CORE_ADDR
138+s390_lk_get_percpu_offset (unsigned int cpu)
139+{
140+ CORE_ADDR lowcore_ptr, lowcore;
141+ size_t ptr_len = lk_builtin_type_size (unsigned_long);
142+
143+ lowcore_ptr = LK_ADDR (lowcore_ptr) + (ptr_len * cpu);
144+ lowcore = lk_read_addr (lowcore_ptr);
145+
146+ return lk_read_addr (lowcore + LK_OFFSET (lowcore, percpu_offset));
147+}
148+
149+/* Function for Linux kernel target map_running_task_to_cpu hook. */
150+
151+unsigned int
152+s390_lk_map_running_task_to_cpu (struct thread_info *ti)
153+{
154+ struct regcache *regcache;
155+ enum register_status reg_status;
156+ CORE_ADDR lowcore;
157+ unsigned int cpu;
158+
159+ regcache = get_thread_regcache (ti->ptid);
160+ reg_status = regcache_raw_read_unsigned (regcache, S390_PREFIX_REGNUM,
161+ (ULONGEST *) &lowcore);
162+ if (reg_status != REG_VALID)
163+ error (_("Could not find prefix register for thread with pid %d, lwp %li."),
164+ ti->ptid.pid, ti->ptid.lwp);
165+
166+ cpu = lk_read_uint (lowcore + LK_OFFSET (lowcore, cpu_nr));
167+
168+ return cpu;
169+}
170+
171+/* Function for Linux kernel target is_kvaddr hook. */
172+
173+int
174+s390_lk_is_kvaddr (CORE_ADDR addr)
175+{
176+ return addr >= LK_ADDR (high_memory);
177+}
178+
179+/* Read table entry from TABLE at offset OFFSET. Helper for s390_lk_vtop. */
180+
181+static inline ULONGEST
182+s390_lk_read_table_entry (CORE_ADDR table, ULONGEST offset)
183+{
184+ return lk_read_ulong (table + offset * lk_builtin_type_size (unsigned_long));
185+}
186+
187+/* Function for Linux kernel target vtop hook. Assume 64 bit addresses. */
188+
189+CORE_ADDR
190+s390_lk_vtop (CORE_ADDR table, CORE_ADDR vaddr)
191+{
192+ ULONGEST entry, offset;
193+ CORE_ADDR paddr;
194+ unsigned int table_type;
195+ size_t addr_size = lk_builtin_type_size (unsigned_long);
196+
197+ /* Read first entry in table to get its type. As the Table-Type bits are
198+ the same in every table assume Region1-Table. */
199+ entry = s390_lk_read_table_entry (table, 0);
200+ table_type = (entry & S390_LK_RFTE_TT) >> 2;
201+
202+ switch (table_type)
203+ {
204+ case S390_LK_DAT_TT_REGION1:
205+ {
206+ offset = (vaddr & S390_LK_VADDR_RFX) >> 53;
207+ entry = s390_lk_read_table_entry (table, offset);
208+
209+ /* Do sanity checks. */
210+ if (!entry)
211+ warning (_("Trying to translate address 0x%s with empty "\
212+ "region-first-table entry."),
213+ phex (vaddr, addr_size));
214+ else if ((entry & S390_LK_RFTE_TT) >> 2 != S390_LK_DAT_TT_REGION1)
215+ warning (_("Trying to translate address 0x%s with corrupt "\
216+ "table type in region-first-table entry."),
217+ phex (vaddr, addr_size));
218+ else if (entry & S390_LK_RFTE_I)
219+ warning (_("Translating address 0x%s with invalid bit set at "\
220+ "region-first-table entry."),
221+ phex (vaddr, addr_size));
222+
223+ table = entry & S390_LK_RFTE_O;
224+ }
225+ /* fall through */
226+ case S390_LK_DAT_TT_REGION2:
227+ {
228+ offset = (vaddr & S390_LK_VADDR_RSX) >> 42;
229+ entry = s390_lk_read_table_entry (table, offset);
230+
231+ /* Do sanity checks. */
232+ if (!entry)
233+ warning (_("Trying to translate address 0x%s with empty "\
234+ "region-second-table entry."),
235+ phex (vaddr, addr_size));
236+ else if ((entry & S390_LK_RSTE_TT) >> 2 != S390_LK_DAT_TT_REGION2)
237+ warning (_("Trying to translate address 0x%s with corrupt "\
238+ "table type in region-second-table entry."),
239+ phex (vaddr, addr_size));
240+ else if (entry & S390_LK_RSTE_I)
241+ warning (_("Translating address 0x%s with invalid bit set at "\
242+ "region-second-table entry."),
243+ phex (vaddr, addr_size));
244+
245+ table = entry & S390_LK_RSTE_O;
246+ }
247+ /* fall through */
248+ case S390_LK_DAT_TT_REGION3:
249+ {
250+ offset = (vaddr & S390_LK_VADDR_RTX) >> 31;
251+ entry = s390_lk_read_table_entry (table, offset);
252+
253+ /* Do sanity checks. */
254+ if (!entry)
255+ warning (_("Trying to translate address 0x%s with empty "\
256+ "region-third-table entry."),
257+ phex (vaddr, addr_size));
258+ else if ((entry & S390_LK_RTTE_TT) >> 2 != S390_LK_DAT_TT_REGION3)
259+ warning (_("Trying to translate address 0x%s with corrupt "\
260+ "table type in region-third-table entry."),
261+ phex (vaddr, addr_size));
262+ else if (entry & S390_LK_RTTE_I)
263+ warning (_("Translating address 0x%s with invalid bit set at "\
264+ "region-third-table entry."),
265+ phex (vaddr, addr_size));
266+
267+ /* Check for huge page. */
268+ if (entry & S390_LK_RTTE_FC)
269+ {
270+ paddr = ((entry & S390_LK_RTTE_RFAA)
271+ + (vaddr & ~S390_LK_RTTE_RFAA));
272+ return paddr;
273+ }
274+
275+ table = entry & S390_LK_RTTE_O;
276+ }
277+ /* fall through */
278+ case S390_LK_DAT_TT_SEGMENT:
279+ {
280+ offset = (vaddr & S390_LK_VADDR_SX) >> 20;
281+ entry = s390_lk_read_table_entry (table, offset);
282+
283+ /* Do sanity checks. */
284+ if (!entry)
285+ warning (_("Trying to translate address 0x%s with empty "\
286+ "segment-table entry."),
287+ phex (vaddr, addr_size));
288+ else if ((entry & S390_LK_STE_TT) >> 2 != S390_LK_DAT_TT_SEGMENT)
289+ warning (_("Trying to translate address 0x%s with corrupt "\
290+ "table type in segment-table entry."),
291+ phex (vaddr, addr_size));
292+ else if (entry & S390_LK_STE_I)
293+ warning (_("Translating address 0x%s with invalid bit set at "\
294+ "segment-table entry."),
295+ phex (vaddr, addr_size));
296+
297+ /* Check for large page. */
298+ if (entry & S390_LK_STE_FC)
299+ {
300+ paddr = ((entry & S390_LK_STE_SFAA)
301+ + (vaddr & ~S390_LK_STE_SFAA));
302+ return paddr;
303+ }
304+
305+ table = entry & S390_LK_STE_O;
306+ break;
307+ }
308+ } /* switch (table_type) */
309+
310+ offset = (vaddr & S390_LK_VADDR_PX) >> 12;
311+ entry = s390_lk_read_table_entry (table, offset);
312+
313+ /* Do sanity checks. */
314+ if (!entry)
315+ warning (_("Trying to translate address 0x%s with empty page-table "\
316+ "entry."),
317+ phex (vaddr, addr_size));
318+ else if (entry & S390_LK_PTE_I)
319+ warning (_("Translating address 0x%s with invalid bit set at page-table "\
320+ "entry."),
321+ phex (vaddr, addr_size));
322+
323+ paddr = ((entry & S390_LK_PTE_PFAA) + (vaddr & ~S390_LK_PTE_PFAA));
324+
325+ return paddr;
326+}
327+
328+/* Function for Linux kernel target get_module_text_offset hook. */
329+
330+CORE_ADDR
331+s390_lk_get_module_text_offset (CORE_ADDR mod)
332+{
333+ CORE_ADDR offset, mod_arch;
334+
335+ mod_arch = mod + LK_OFFSET (module, arch);
336+ offset = lk_read_ulong (mod_arch + LK_OFFSET (mod_arch_specific, got_size));
337+ offset += lk_read_ulong (mod_arch + LK_OFFSET (mod_arch_specific, plt_size));
338+
339+ return offset;
340+}
341+
342+/* Initialize s390 dependent private data for linux kernel target. */
343+
344+static void
345+s390_lk_init_private (struct gdbarch *gdbarch)
346+{
347+ LK_DECLARE_FIELD (stack_frame, gprs);
348+
349+ LK_DECLARE_FIELD (thread_struct, ksp);
350+
351+ LK_DECLARE_STRUCT_ALIAS (_lowcore, lowcore); /* linux -4.4 */
352+ LK_DECLARE_STRUCT_ALIAS (lowcore, lowcore); /* linux 4.5+ */
353+ if (LK_STRUCT (lowcore) == NULL)
354+ error (_("Could not find struct lowcore. Aborting."));
355+ LK_DECLARE_FIELD (lowcore, percpu_offset);
356+ LK_DECLARE_FIELD (lowcore, current_pid);
357+ LK_DECLARE_FIELD (lowcore, cpu_nr);
358+
359+ LK_DECLARE_FIELD (mod_arch_specific, got_size);
360+ LK_DECLARE_FIELD (mod_arch_specific, plt_size);
361+
362+ LK_DECLARE_ADDR (lowcore_ptr);
363+ LK_DECLARE_ADDR (high_memory);
364+
365+ LK_HOOK->get_registers = s390_lk_get_registers;
366+ LK_HOOK->is_kvaddr = s390_lk_is_kvaddr;
367+ LK_HOOK->vtop = s390_lk_vtop;
368+ LK_HOOK->get_percpu_offset = s390_lk_get_percpu_offset;
369+ LK_HOOK->map_running_task_to_cpu = s390_lk_map_running_task_to_cpu;
370+ LK_HOOK->get_module_text_offset = s390_lk_get_module_text_offset;
371+}
372+
373+/* Initialize Linux kernel specific gdbarch hooks. */
374+
375+void
376+s390_gdbarch_lk_init (struct gdbarch_info info, struct gdbarch *gdbarch)
377+{
378+ /* Support linux kernel debugging. */
379+ set_gdbarch_lk_init_private (gdbarch, s390_lk_init_private);
380+}
381+
382+extern initialize_file_ftype _initialize_s390_lk_tdep; /* -Wmissing-prototypes */
383+
384+void
385+_initialize_s390_lk_tdep (void)
386+{
387+ /* Initialize the Linux kernel target descriptions. */
388+ initialize_tdesc_s390x_cr_linux64 ();
389+ initialize_tdesc_s390x_vxcr_linux64 ();
390+}
--- /dev/null
+++ b/gdb/s390-lk-tdep.h
@@ -0,0 +1,36 @@
1+/* Target-dependent code for linux-kernel target on S390.
2+ Copyright (C) 2017 Free Software Foundation, Inc.
3+
4+ This file is part of GDB.
5+
6+ This program is free software; you can redistribute it and/or modify
7+ it under the terms of the GNU General Public License as published by
8+ the Free Software Foundation; either version 3 of the License, or
9+ (at your option) any later version.
10+
11+ This program is distributed in the hope that it will be useful,
12+ but WITHOUT ANY WARRANTY; without even the implied warranty of
13+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
14+ GNU General Public License for more details.
15+
16+ You should have received a copy of the GNU General Public License
17+ along with this program. If not, see <http://www.gnu.org/licenses/>. */
18+
19+#ifndef S390_LK_TDEP_H
20+#define S390_LK_TDEP_H
21+
22+extern void s390_gdbarch_lk_init (struct gdbarch_info info,
23+ struct gdbarch *gdbarch);
24+
25+/* Core file privileged register sets, defined in s390-lk-tdep.c. */
26+extern const struct regset s390x_gregset_lk;
27+extern const struct regset s390x_cr_regset;
28+extern const struct regset s390x_timer_regset;
29+extern const struct regset s390x_todcmp_regset;
30+extern const struct regset s390x_todpreg_regset;
31+extern const struct regset s390x_prefix_regset;
32+
33+extern struct target_desc *tdesc_s390x_cr_linux64;
34+extern struct target_desc *tdesc_s390x_vxcr_linux64;
35+
36+#endif /* S390_LK_TDEP_H */
--- a/gdb/s390-tdep.c
+++ b/gdb/s390-tdep.c
@@ -40,6 +40,7 @@
4040 #include "reggroups.h"
4141 #include "regset.h"
4242 #include "s390-linux-tdep.h"
43+#include "s390-lk-tdep.h"
4344 #include "s390-tdep.h"
4445 #include "target-descriptions.h"
4546 #include "trad-frame.h"
@@ -1032,7 +1033,7 @@ s390_core_read_description (struct gdbarch *gdbarch,
10321033 {
10331034 asection *section = bfd_get_section_by_name (abfd, ".reg");
10341035 CORE_ADDR hwcap = 0;
1035- int high_gprs, v1, v2, te, vx;
1036+ int high_gprs, v1, v2, te, vx, cr;
10361037
10371038 target_auxv_search (target, AT_HWCAP, &hwcap);
10381039 if (!section)
@@ -1044,6 +1045,7 @@ s390_core_read_description (struct gdbarch *gdbarch,
10441045 v2 = (bfd_get_section_by_name (abfd, ".reg-s390-system-call") != NULL);
10451046 vx = (hwcap & HWCAP_S390_VX);
10461047 te = (hwcap & HWCAP_S390_TE);
1048+ cr = (bfd_get_section_by_name (abfd, ".reg-s390-ctrs") != NULL);
10471049
10481050 switch (bfd_section_size (abfd, section))
10491051 {
@@ -1060,6 +1062,8 @@ s390_core_read_description (struct gdbarch *gdbarch,
10601062
10611063 case s390x_sizeof_gregset:
10621064 return (te && vx ? tdesc_s390x_tevx_linux64 :
1065+ vx && cr ? tdesc_s390x_vxcr_linux64 :
1066+ cr ? tdesc_s390x_cr_linux64 :
10631067 vx ? tdesc_s390x_vx_linux64 :
10641068 te ? tdesc_s390x_te_linux64 :
10651069 v2 ? tdesc_s390x_linux64v2 :
@@ -1116,6 +1120,22 @@ s390_iterate_over_regset_sections (struct gdbarch *gdbarch,
11161120 cb (".reg-s390-vxrs-high", 16 * 16, &s390_vxrs_high_regset,
11171121 "s390 vector registers 16-31", cb_data);
11181122 }
1123+
1124+ /* Privileged registers for kernel debugging. */
1125+ if (bfd_get_section_by_name (core_bfd, ".reg-s390-timer"))
1126+ cb (".reg-s390-timer", 8, &s390x_timer_regset, "s390 timer", cb_data);
1127+ if (bfd_get_section_by_name (core_bfd, ".reg-s390-todcmp"))
1128+ cb (".reg-s390-todcmp", 8, &s390x_todcmp_regset,
1129+ "s390 clock comperator", cb_data);
1130+ if (bfd_get_section_by_name (core_bfd, ".reg-s390-todpreg"))
1131+ cb (".reg-s390-todpreg", 4, &s390x_todpreg_regset,
1132+ "s390 TOD programable register", cb_data);
1133+ if (bfd_get_section_by_name (core_bfd, ".reg-s390-ctrs"))
1134+ cb (".reg-s390-ctrs", 16 * 8, &s390x_cr_regset,
1135+ "s390 control registers", cb_data);
1136+ if (bfd_get_section_by_name (core_bfd, ".reg-s390-prefix"))
1137+ cb (".reg-s390-prefix", 4, &s390x_prefix_regset,
1138+ "s390 prefix area", cb_data);
11191139 }
11201140
11211141
@@ -2986,6 +3006,7 @@ s390_gdbarch_init (struct gdbarch_info info, struct gdbarch_list *arches)
29863006 int have_linux_v2 = 0;
29873007 int have_tdb = 0;
29883008 int have_vx = 0;
3009+ int have_privileged = 0;
29893010 int first_pseudo_reg, last_pseudo_reg;
29903011 static const char *const stap_register_prefixes[] = { "%", NULL };
29913012 static const char *const stap_register_indirection_prefixes[] = { "(",
@@ -3160,6 +3181,30 @@ s390_gdbarch_init (struct gdbarch_info info, struct gdbarch_list *arches)
31603181 have_vx = 1;
31613182 }
31623183
3184+ /* Control registers. */
3185+ feature = tdesc_find_feature (tdesc, "org.gnu.gdb.s390.cr");
3186+ if (feature)
3187+ {
3188+ for (i = 0; i < 16; i++)
3189+ valid_p &= tdesc_numbered_register (feature, tdesc_data,
3190+ S390_CR0_REGNUM + i, cr[i]);
3191+ }
3192+
3193+ /* Privileged registers. */
3194+ feature = tdesc_find_feature (tdesc, "org.gnu.gdb.s390.privileged");
3195+ if (feature)
3196+ {
3197+ valid_p &= tdesc_numbered_register (feature, tdesc_data,
3198+ S390_TIMER_REGNUM, "timer");
3199+ valid_p &= tdesc_numbered_register (feature, tdesc_data,
3200+ S390_TODCMP_REGNUM, "todcmp");
3201+ valid_p &= tdesc_numbered_register (feature, tdesc_data,
3202+ S390_TODPREG_REGNUM, "todpreg");
3203+ valid_p &= tdesc_numbered_register (feature, tdesc_data,
3204+ S390_PREFIX_REGNUM, "prefix");
3205+ have_privileged = 1;
3206+ }
3207+
31633208 if (!valid_p)
31643209 {
31653210 tdesc_data_cleanup (tdesc_data);
@@ -3340,8 +3385,14 @@ s390_gdbarch_init (struct gdbarch_info info, struct gdbarch_list *arches)
33403385 set_gdbarch_valid_disassembler_options (gdbarch,
33413386 disassembler_options_s390 ());
33423387
3343- /* Note that GNU/Linux is the only OS supported on this platform. */
3344- s390_gdbarch_linux_init (info, gdbarch);
3388+ /* Note that GNU/Linux is the only OS supported on this platform.
3389+ Nevertheless we need to distinguish between a kernel- and user-space
3390+ gdbarch. GDBs osabi support is not sufficient for our case as for both
3391+ cases the ELF bits are for Linux. Thus fallback to this method. */
3392+ if (have_privileged)
3393+ s390_gdbarch_lk_init (info, gdbarch);
3394+ else
3395+ s390_gdbarch_linux_init (info, gdbarch);
33453396
33463397 return gdbarch;
33473398 }
--- a/gdb/s390-tdep.h
+++ b/gdb/s390-tdep.h
@@ -319,4 +319,66 @@ enum
319319 #define S390_IS_TDBREGSET_REGNUM(i) \
320320 ((i) >= S390_TDB_DWORD0_REGNUM && (i) <= S390_TDB_R15_REGNUM)
321321
322+/* Definitions for address translation. */
323+/* DAT Table types. */
324+#define S390_LK_DAT_TT_REGION1 3
325+#define S390_LK_DAT_TT_REGION2 2
326+#define S390_LK_DAT_TT_REGION3 1
327+#define S390_LK_DAT_TT_SEGMENT 0
328+
329+/* Region-First-Table */
330+#define S390_LK_RFTE_TL 0x3ULL /* Table-Length */
331+#define S390_LK_RFTE_TT 0xcULL /* Table-Type */
332+#define S390_LK_RFTE_I 0x20ULL /* Region-Invalid Bit */
333+#define S390_LK_RFTE_TF 0xc0ULL /* Table Offset */
334+#define S390_LK_RFTE_P 0x200ULL /* DAT-Protection Bit */
335+#define S390_LK_RFTE_O ~0xfffULL /* Region-Second-Table Origin */
336+
337+/* Region-Second-Table flags. */
338+#define S390_LK_RSTE_TL 0x3ULL /* Table-Length */
339+#define S390_LK_RSTE_TT 0xcULL /* Table-Type */
340+#define S390_LK_RSTE_I 0x20ULL /* Region-Invalid Bit */
341+#define S390_LK_RSTE_TF 0xc0ULL /* Table Offset */
342+#define S390_LK_RSTE_P 0x200ULL /* DAT-Protection Bit */
343+#define S390_LK_RSTE_O ~0xfffULL /* Region-Third-Table Origin */
344+
345+/* Region-Third-Table flags. */
346+#define S390_LK_RTTE_TL 0x3ULL /* Table-Length */
347+#define S390_LK_RTTE_TT 0xcULL /* Table-Type */
348+#define S390_LK_RTTE_CR 0x10ULL /* Common-Region Bit */
349+#define S390_LK_RTTE_I 0x20ULL /* Region-Invalid Bit */
350+#define S390_LK_RTTE_TF 0xc0ULL /* Table Offset */
351+#define S390_LK_RTTE_P 0x200ULL /* DAT-Protection Bit */
352+#define S390_LK_RTTE_FC 0x400ULL /* Format-Control Bit */
353+#define S390_LK_RTTE_F 0x800ULL /* Fetch-Protection Bit */
354+#define S390_LK_RTTE_ACC 0xf000ULL /* Access-Control Bits */
355+#define S390_LK_RTTE_AV 0x10000ULL /* ACCF-Validity Control */
356+#define S390_LK_RTTE_O ~0xfffULL /* Segment-Table Origin */
357+#define S390_LK_RTTE_RFAA ~0x7fffffffULL /* Region-Frame Absolute Address */
358+
359+/* Segment-Table flags. */
360+#define S390_LK_STE_TT 0xcULL /* Table-Type */
361+#define S390_LK_STE_I 0x20ULL /* Segment-Invalid Bit */
362+#define S390_LK_STE_TF 0xc0ULL /* Table Offset */
363+#define S390_LK_STE_P 0x200ULL /* DAT-Protection Bit */
364+#define S390_LK_STE_FC 0x400ULL /* Format-Control Bit */
365+#define S390_LK_STE_F 0x800ULL /* Fetch-Protection Bit */
366+#define S390_LK_STE_ACC 0xf000ULL /* Access-Control Bits */
367+#define S390_LK_STE_AV 0x10000ULL /* ACCF-Validity Control */
368+#define S390_LK_STE_O ~0x7ffULL /* Page-Table Origin */
369+#define S390_LK_STE_SFAA ~0xfffffULL /* Segment-Frame Absolute Address */
370+
371+/* Page-Table flags. */
372+#define S390_LK_PTE_P 0x200ULL /* DAT-Protection Bit */
373+#define S390_LK_PTE_I 0x400ULL /* Page-Invalid Bit */
374+#define S390_LK_PTE_PFAA ~0xfffULL /* Page-Frame Absolute Address */
375+
376+/* Virtual Address Fields. */
377+#define S390_LK_VADDR_RFX 0xffe0000000000000ULL
378+#define S390_LK_VADDR_RSX 0x001ffc0000000000ULL
379+#define S390_LK_VADDR_RTX 0x000003ff80000000ULL
380+#define S390_LK_VADDR_SX 0x000000007ff00000ULL
381+#define S390_LK_VADDR_PX 0x00000000000ff000ULL
382+#define S390_LK_VADDR_BX 0x0000000000000fffULL
383+
322384 #endif /* S390_TDEP_H */