microblaze.patch 60 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734735736737738739740741742743744745746747748749750751752753754755756757758759760761762763764765766767768769770771772773774775776777778779780781782783784785786787788789790791792793794795796797798799800801802803804805806807808809810811812813814815816817818819820821822823824825826827828829830831832833834835836837838839840841842843844845846847848849850851852853854855856857858859860861862863864865866867868869870871872873874875876877878879880881882883884885886887888889890891892893894895896897898899900901902903904905906907908909910911912913914915916917918919920921922923924925926927928929930931932933934935936937938939940941942943944945946947948949950951952953954955956957958959960961962963964965966967968969970971972973974975976977978979980981982983984985986987988989990991992993994995996997998999100010011002100310041005100610071008100910101011101210131014101510161017101810191020102110221023102410251026102710281029103010311032103310341035103610371038103910401041104210431044104510461047104810491050105110521053105410551056105710581059106010611062106310641065106610671068106910701071107210731074107510761077107810791080108110821083108410851086108710881089109010911092109310941095109610971098109911001101110211031104110511061107110811091110111111121113111411151116111711181119112011211122112311241125112611271128112911301131113211331134113511361137113811391140114111421143114411451146114711481149115011511152115311541155115611571158115911601161116211631164116511661167116811691170117111721173117411751176117711781179118011811182118311841185118611871188118911901191119211931194119511961197119811991200120112021203120412051206120712081209121012111212121312141215121612171218121912201221122212231224122512261227122812291230123112321233123412351236123712381239124012411242124312441245124612471248124912501251125212531254125512561257125812591260126112621263126412651266126712681269127012711272127312741275127612771278127912801281128212831284128512861287128812891290129112921293129412951296129712981299130013011302130313041305130613071308130913101311131213131314131513161317131813191320132113221323132413251326132713281329133013311332133313341335133613371338133913401341134213431344134513461347134813491350135113521353135413551356135713581359136013611362136313641365136613671368136913701371137213731374137513761377137813791380138113821383138413851386138713881389139013911392139313941395139613971398139914001401140214031404140514061407140814091410141114121413141414151416141714181419142014211422142314241425142614271428142914301431143214331434143514361437143814391440144114421443144414451446144714481449145014511452145314541455145614571458145914601461146214631464146514661467146814691470147114721473147414751476147714781479148014811482148314841485148614871488148914901491149214931494149514961497149814991500150115021503150415051506150715081509151015111512151315141515151615171518151915201521152215231524152515261527152815291530153115321533153415351536153715381539154015411542154315441545154615471548154915501551155215531554155515561557155815591560156115621563156415651566156715681569157015711572157315741575157615771578157915801581158215831584158515861587158815891590159115921593159415951596159715981599160016011602160316041605160616071608160916101611161216131614161516161617161816191620162116221623162416251626162716281629163016311632163316341635163616371638163916401641164216431644164516461647164816491650165116521653165416551656165716581659166016611662166316641665166616671668166916701671167216731674167516761677167816791680168116821683168416851686168716881689169016911692169316941695169616971698169917001701170217031704170517061707170817091710171117121713171417151716171717181719172017211722172317241725172617271728172917301731173217331734173517361737173817391740174117421743174417451746174717481749175017511752175317541755175617571758175917601761176217631764176517661767176817691770177117721773177417751776177717781779178017811782178317841785178617871788178917901791179217931794179517961797179817991800180118021803180418051806180718081809181018111812181318141815181618171818181918201821182218231824182518261827182818291830183118321833183418351836183718381839184018411842184318441845184618471848
  1. diff -Nur gdb-7.8.2.orig/bfd/bfd-in2.h gdb-7.8.2/bfd/bfd-in2.h
  2. --- gdb-7.8.2.orig/bfd/bfd-in2.h 2015-01-15 11:58:11.000000000 +0100
  3. +++ gdb-7.8.2/bfd/bfd-in2.h 2016-05-14 21:29:38.989383220 +0200
  4. @@ -5449,6 +5449,11 @@
  5. expressions of the form "Symbol Op Symbol" */
  6. BFD_RELOC_MICROBLAZE_32_SYM_OP_SYM,
  7. +/* This is a 32 bit reloc that stores the 32 bit pc relative
  8. +value in two words (with an imm instruction). No relocation is
  9. +done here - only used for relaxing */
  10. + BFD_RELOC_MICROBLAZE_32_NONE,
  11. +
  12. /* This is a 64 bit reloc that stores the 32 bit pc relative
  13. value in two words (with an imm instruction). No relocation is
  14. done here - only used for relaxing */
  15. diff -Nur gdb-7.8.2.orig/bfd/elf32-microblaze.c gdb-7.8.2/bfd/elf32-microblaze.c
  16. --- gdb-7.8.2.orig/bfd/elf32-microblaze.c 2015-01-15 11:58:11.000000000 +0100
  17. +++ gdb-7.8.2/bfd/elf32-microblaze.c 2016-05-14 21:29:38.993383375 +0200
  18. @@ -177,6 +177,20 @@
  19. FALSE), /* PC relative offset? */
  20. /* This reloc does nothing. Used for relaxation. */
  21. + HOWTO (R_MICROBLAZE_32_NONE, /* Type. */
  22. + 0, /* Rightshift. */
  23. + 2, /* Size (0 = byte, 1 = short, 2 = long). */
  24. + 32, /* Bitsize. */
  25. + TRUE, /* PC_relative. */
  26. + 0, /* Bitpos. */
  27. + complain_overflow_bitfield, /* Complain on overflow. */
  28. + NULL, /* Special Function. */
  29. + "R_MICROBLAZE_32_NONE",/* Name. */
  30. + FALSE, /* Partial Inplace. */
  31. + 0, /* Source Mask. */
  32. + 0, /* Dest Mask. */
  33. + FALSE), /* PC relative offset? */
  34. +
  35. HOWTO (R_MICROBLAZE_64_NONE, /* Type. */
  36. 0, /* Rightshift. */
  37. 2, /* Size (0 = byte, 1 = short, 2 = long). */
  38. @@ -532,7 +546,10 @@
  39. case BFD_RELOC_NONE:
  40. microblaze_reloc = R_MICROBLAZE_NONE;
  41. break;
  42. - case BFD_RELOC_MICROBLAZE_64_NONE:
  43. + case BFD_RELOC_MICROBLAZE_32_NONE:
  44. + microblaze_reloc = R_MICROBLAZE_32_NONE;
  45. + break;
  46. + case BFD_RELOC_MICROBLAZE_64_NONE:
  47. microblaze_reloc = R_MICROBLAZE_64_NONE;
  48. break;
  49. case BFD_RELOC_32:
  50. @@ -668,6 +685,67 @@
  51. return _bfd_elf_is_local_label_name (abfd, name);
  52. }
  53. +/* Support for core dump NOTE sections. */
  54. +static bfd_boolean
  55. +microblaze_elf_grok_prstatus (bfd *abfd, Elf_Internal_Note *note)
  56. +{
  57. + int offset;
  58. + unsigned int size;
  59. +
  60. + switch (note->descsz)
  61. + {
  62. + default:
  63. + return FALSE;
  64. +
  65. + case 228: /* Linux/MicroBlaze */
  66. + /* pr_cursig */
  67. + elf_tdata (abfd)->core->signal = bfd_get_16 (abfd, note->descdata + 12);
  68. +
  69. + /* pr_pid */
  70. + elf_tdata (abfd)->core->pid = bfd_get_32 (abfd, note->descdata + 24);
  71. +
  72. + /* pr_reg */
  73. + offset = 72;
  74. + size = 50 * 4;
  75. +
  76. + break;
  77. + }
  78. +
  79. + /* Make a ".reg/999" section. */
  80. + return _bfd_elfcore_make_pseudosection (abfd, ".reg",
  81. + size, note->descpos + offset);
  82. +}
  83. +
  84. +static bfd_boolean
  85. +microblaze_elf_grok_psinfo (bfd *abfd, Elf_Internal_Note *note)
  86. +{
  87. + switch (note->descsz)
  88. + {
  89. + default:
  90. + return FALSE;
  91. +
  92. + case 128: /* Linux/MicroBlaze elf_prpsinfo */
  93. + elf_tdata (abfd)->core->program
  94. + = _bfd_elfcore_strndup (abfd, note->descdata + 32, 16);
  95. + elf_tdata (abfd)->core->command
  96. + = _bfd_elfcore_strndup (abfd, note->descdata + 48, 80);
  97. + }
  98. +
  99. + /* Note that for some reason, a spurious space is tacked
  100. + onto the end of the args in some (at least one anyway)
  101. + implementations, so strip it off if it exists. */
  102. +
  103. + {
  104. + char *command = elf_tdata (abfd)->core->command;
  105. + int n = strlen (command);
  106. +
  107. + if (0 < n && command[n - 1] == ' ')
  108. + command[n - 1] = '\0';
  109. + }
  110. +
  111. + return TRUE;
  112. +}
  113. +
  114. /* The microblaze linker (like many others) needs to keep track of
  115. the number of relocs that it decides to copy as dynamic relocs in
  116. check_relocs for each symbol. This is so that it can later discard
  117. @@ -1023,7 +1101,7 @@
  118. {
  119. /* External symbol. */
  120. bfd_boolean warned ATTRIBUTE_UNUSED;
  121. - bfd_boolean ignored ATTRIBUTE_UNUSED;
  122. + bfd_boolean ignored;
  123. RELOC_FOR_GLOBAL_SYMBOL (info, input_bfd, input_section, rel,
  124. r_symndx, symtab_hdr, sym_hashes,
  125. @@ -1852,14 +1930,22 @@
  126. }
  127. break;
  128. case R_MICROBLAZE_NONE:
  129. + case R_MICROBLAZE_32_NONE:
  130. {
  131. /* This was a PC-relative instruction that was
  132. completely resolved. */
  133. int sfix, efix;
  134. + unsigned int val;
  135. bfd_vma target_address;
  136. target_address = irel->r_addend + irel->r_offset;
  137. sfix = calc_fixup (irel->r_offset, 0, sec);
  138. efix = calc_fixup (target_address, 0, sec);
  139. +
  140. + /* Validate the in-band val. */
  141. + val = bfd_get_32 (abfd, contents + irel->r_offset);
  142. + if (val != irel->r_addend && ELF32_R_TYPE (irel->r_info) == R_MICROBLAZE_32_NONE) {
  143. + fprintf(stderr, "%d: CORRUPT relax reloc %x %lx\n", __LINE__, val, irel->r_addend);
  144. + }
  145. irel->r_addend -= (efix - sfix);
  146. /* Should use HOWTO. */
  147. microblaze_bfd_write_imm_value_32 (abfd, contents + irel->r_offset,
  148. @@ -1907,6 +1993,49 @@
  149. irelscanend = irelocs + o->reloc_count;
  150. for (irelscan = irelocs; irelscan < irelscanend; irelscan++)
  151. {
  152. + if (1 && ELF32_R_TYPE (irelscan->r_info) == (int) R_MICROBLAZE_32_NONE)
  153. + {
  154. + unsigned int val;
  155. +
  156. + isym = isymbuf + ELF32_R_SYM (irelscan->r_info);
  157. +
  158. + /* hax: We only do the following fixup for debug location lists. */
  159. + if (strcmp(".debug_loc", o->name))
  160. + continue;
  161. +
  162. + /* This was a PC-relative instruction that was completely resolved. */
  163. + if (ocontents == NULL)
  164. + {
  165. + if (elf_section_data (o)->this_hdr.contents != NULL)
  166. + ocontents = elf_section_data (o)->this_hdr.contents;
  167. + else
  168. + {
  169. + /* We always cache the section contents.
  170. + Perhaps, if info->keep_memory is FALSE, we
  171. + should free them, if we are permitted to. */
  172. +
  173. + if (o->rawsize == 0)
  174. + o->rawsize = o->size;
  175. + ocontents = (bfd_byte *) bfd_malloc (o->rawsize);
  176. + if (ocontents == NULL)
  177. + goto error_return;
  178. + if (!bfd_get_section_contents (abfd, o, ocontents,
  179. + (file_ptr) 0,
  180. + o->rawsize))
  181. + goto error_return;
  182. + elf_section_data (o)->this_hdr.contents = ocontents;
  183. + }
  184. + }
  185. +
  186. + val = bfd_get_32 (abfd, ocontents + irelscan->r_offset);
  187. + if (val != irelscan->r_addend) {
  188. + fprintf(stderr, "%d: CORRUPT relax reloc! %x %lx\n", __LINE__, val, irelscan->r_addend);
  189. + }
  190. +
  191. + irelscan->r_addend -= calc_fixup (irelscan->r_addend, 0, sec);
  192. + microblaze_bfd_write_imm_value_32 (abfd, ocontents + irelscan->r_offset,
  193. + irelscan->r_addend);
  194. + }
  195. if (ELF32_R_TYPE (irelscan->r_info) == (int) R_MICROBLAZE_32)
  196. {
  197. isym = isymbuf + ELF32_R_SYM (irelscan->r_info);
  198. @@ -1966,7 +2095,7 @@
  199. elf_section_data (o)->this_hdr.contents = ocontents;
  200. }
  201. }
  202. - irelscan->r_addend -= calc_fixup (irel->r_addend
  203. + irelscan->r_addend -= calc_fixup (irelscan->r_addend
  204. + isym->st_value,
  205. 0,
  206. sec);
  207. @@ -3506,4 +3635,7 @@
  208. #define elf_backend_size_dynamic_sections microblaze_elf_size_dynamic_sections
  209. #define elf_backend_add_symbol_hook microblaze_elf_add_symbol_hook
  210. +#define elf_backend_grok_prstatus microblaze_elf_grok_prstatus
  211. +#define elf_backend_grok_psinfo microblaze_elf_grok_psinfo
  212. +
  213. #include "elf32-target.h"
  214. diff -Nur gdb-7.8.2.orig/bfd/libbfd.h gdb-7.8.2/bfd/libbfd.h
  215. --- gdb-7.8.2.orig/bfd/libbfd.h 2015-01-15 11:58:11.000000000 +0100
  216. +++ gdb-7.8.2/bfd/libbfd.h 2016-05-14 21:29:38.993383375 +0200
  217. @@ -2644,6 +2644,7 @@
  218. "BFD_RELOC_MICROBLAZE_32_ROSDA",
  219. "BFD_RELOC_MICROBLAZE_32_RWSDA",
  220. "BFD_RELOC_MICROBLAZE_32_SYM_OP_SYM",
  221. + "BFD_RELOC_MICROBLAZE_32_NONE",
  222. "BFD_RELOC_MICROBLAZE_64_NONE",
  223. "BFD_RELOC_MICROBLAZE_64_GOTPC",
  224. "BFD_RELOC_MICROBLAZE_64_GOT",
  225. diff -Nur gdb-7.8.2.orig/gdb/config/microblaze/linux.mh gdb-7.8.2/gdb/config/microblaze/linux.mh
  226. --- gdb-7.8.2.orig/gdb/config/microblaze/linux.mh 1970-01-01 01:00:00.000000000 +0100
  227. +++ gdb-7.8.2/gdb/config/microblaze/linux.mh 2016-05-14 21:29:38.993383375 +0200
  228. @@ -0,0 +1,10 @@
  229. +# Host: Microblaze, running Linux
  230. +
  231. +NAT_FILE= config/nm-linux.h
  232. +NATDEPFILES= inf-ptrace.o fork-child.o \
  233. + microblaze-linux-nat.o proc-service.o linux-thread-db.o \
  234. + linux-nat.o linux-osdata.o linux-fork.o linux-procfs.o linux-ptrace.o \
  235. + linux-waitpid.o
  236. +NAT_CDEPS = $(srcdir)/proc-service.list
  237. +
  238. +LOADLIBES = -ldl $(RDYNAMIC)
  239. diff -Nur gdb-7.8.2.orig/gdb/configure.host gdb-7.8.2/gdb/configure.host
  240. --- gdb-7.8.2.orig/gdb/configure.host 2015-01-15 11:58:12.000000000 +0100
  241. +++ gdb-7.8.2/gdb/configure.host 2016-05-14 21:29:38.993383375 +0200
  242. @@ -59,6 +59,7 @@
  243. m68*) gdb_host_cpu=m68k ;;
  244. m88*) gdb_host_cpu=m88k ;;
  245. mips*) gdb_host_cpu=mips ;;
  246. +microblaze*) gdb_host_cpu=microblaze ;;
  247. powerpc* | rs6000) gdb_host_cpu=powerpc ;;
  248. sparcv9 | sparc64) gdb_host_cpu=sparc ;;
  249. s390*) gdb_host_cpu=s390 ;;
  250. @@ -133,6 +134,8 @@
  251. gdb_host=nbsd ;;
  252. mips64*-*-openbsd*) gdb_host=obsd64 ;;
  253. +microblaze*-*linux*) gdb_host=linux ;;
  254. +
  255. powerpc-*-aix* | rs6000-*-* | powerpc64-*-aix*)
  256. gdb_host=aix ;;
  257. powerpc*-*-freebsd*) gdb_host=fbsd ;;
  258. diff -Nur gdb-7.8.2.orig/gdb/configure.tgt gdb-7.8.2/gdb/configure.tgt
  259. --- gdb-7.8.2.orig/gdb/configure.tgt 2015-01-15 11:58:12.000000000 +0100
  260. +++ gdb-7.8.2/gdb/configure.tgt 2016-05-14 21:29:38.993383375 +0200
  261. @@ -340,9 +340,10 @@
  262. microblaze*-linux-*|microblaze*-*-linux*)
  263. # Target: Xilinx MicroBlaze running Linux
  264. - gdb_target_obs="microblaze-tdep.o microblaze-linux-tdep.o microblaze-rom.o \
  265. + gdb_target_obs="microblaze-tdep.o microblaze-linux-tdep.o microblaze-rom.o glibc-tdep.o \
  266. monitor.o dsrec.o solib-svr4.o symfile-mem.o linux-tdep.o"
  267. gdb_sim=../sim/microblaze/libsim.a
  268. + build_gdbserver=yes
  269. ;;
  270. microblaze*-*-*)
  271. # Target: Xilinx MicroBlaze running standalone
  272. diff -Nur gdb-7.8.2.orig/gdb/gdbserver/configure.srv gdb-7.8.2/gdb/gdbserver/configure.srv
  273. --- gdb-7.8.2.orig/gdb/gdbserver/configure.srv 2015-01-15 11:58:12.000000000 +0100
  274. +++ gdb-7.8.2/gdb/gdbserver/configure.srv 2016-05-14 21:29:38.993383375 +0200
  275. @@ -198,6 +198,13 @@
  276. srv_linux_usrregs=yes
  277. srv_linux_thread_db=yes
  278. ;;
  279. + microblaze*-*-linux*) srv_regobj=microblaze-linux.o
  280. + srv_tgtobj="$srv_linux_obj linux-microblaze-low.o"
  281. + srv_linux_usrregs=yes
  282. + srv_linux_regsets=yes
  283. + srv_linux_thread_db=yes
  284. + ;;
  285. +
  286. nios2*-*-linux*) srv_regobj="nios2-linux.o"
  287. srv_tgtobj="$srv_linux_obj linux-nios2-low.o"
  288. srv_xmlfiles="nios2-linux.xml"
  289. diff -Nur gdb-7.8.2.orig/gdb/gdbserver/linux-microblaze-low.c gdb-7.8.2/gdb/gdbserver/linux-microblaze-low.c
  290. --- gdb-7.8.2.orig/gdb/gdbserver/linux-microblaze-low.c 1970-01-01 01:00:00.000000000 +0100
  291. +++ gdb-7.8.2/gdb/gdbserver/linux-microblaze-low.c 2016-05-14 21:29:38.993383375 +0200
  292. @@ -0,0 +1,228 @@
  293. +/* GNU/Linux/Microblaze specific low level interface, for the remote server for
  294. + GDB.
  295. + Copyright (C) 1995-2013 Free Software Foundation, Inc.
  296. +
  297. + This file is part of GDB.
  298. +
  299. + This program is free software; you can redistribute it and/or modify
  300. + it under the terms of the GNU General Public License as published by
  301. + the Free Software Foundation; either version 3 of the License, or
  302. + (at your option) any later version.
  303. +
  304. + This program is distributed in the hope that it will be useful,
  305. + but WITHOUT ANY WARRANTY; without even the implied warranty of
  306. + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
  307. + GNU General Public License for more details.
  308. +
  309. + You should have received a copy of the GNU General Public License
  310. + along with this program. If not, see <http://www.gnu.org/licenses/>. */
  311. +
  312. +#include "server.h"
  313. +#include "linux-low.h"
  314. +
  315. +#include <asm/ptrace.h>
  316. +#include <sys/procfs.h>
  317. +#include <sys/ptrace.h>
  318. +
  319. +#include "gdb_proc_service.h"
  320. +
  321. +static int microblaze_regmap[] =
  322. + {PT_GPR(0), PT_GPR(1), PT_GPR(2), PT_GPR(3),
  323. + PT_GPR(4), PT_GPR(5), PT_GPR(6), PT_GPR(7),
  324. + PT_GPR(8), PT_GPR(9), PT_GPR(10), PT_GPR(11),
  325. + PT_GPR(12), PT_GPR(13), PT_GPR(14), PT_GPR(15),
  326. + PT_GPR(16), PT_GPR(17), PT_GPR(18), PT_GPR(19),
  327. + PT_GPR(20), PT_GPR(21), PT_GPR(22), PT_GPR(23),
  328. + PT_GPR(24), PT_GPR(25), PT_GPR(26), PT_GPR(27),
  329. + PT_GPR(28), PT_GPR(29), PT_GPR(30), PT_GPR(31),
  330. + PT_PC, PT_MSR, PT_EAR, PT_ESR,
  331. + PT_FSR
  332. + };
  333. +
  334. +#define microblaze_num_regs (sizeof microblaze_regmap / sizeof microblaze_regmap[0])
  335. +
  336. +/* Defined in auto-generated file microblaze-linux.c. */
  337. +void init_registers_microblaze (void);
  338. +extern const struct target_desc *tdesc_microblaze;
  339. +
  340. +static int
  341. +microblaze_cannot_store_register (int regno)
  342. +{
  343. + if (microblaze_regmap[regno] == -1 || regno == 0)
  344. + return 1;
  345. +
  346. + return 0;
  347. +}
  348. +
  349. +static int
  350. +microblaze_cannot_fetch_register (int regno)
  351. +{
  352. + return 0;
  353. +}
  354. +
  355. +static CORE_ADDR
  356. +microblaze_get_pc (struct regcache *regcache)
  357. +{
  358. + unsigned long pc;
  359. +
  360. + collect_register_by_name (regcache, "pc", &pc);
  361. + return (CORE_ADDR) pc;
  362. +}
  363. +
  364. +static void
  365. +microblaze_set_pc (struct regcache *regcache, CORE_ADDR pc)
  366. +{
  367. + unsigned long newpc = pc;
  368. +
  369. + supply_register_by_name (regcache, "pc", &newpc);
  370. +}
  371. +
  372. +/* dbtrap insn */
  373. +/* brki r16, 0x18; */
  374. +static const unsigned long microblaze_breakpoint = 0xba0c0018;
  375. +#define microblaze_breakpoint_len 4
  376. +
  377. +static int
  378. +microblaze_breakpoint_at (CORE_ADDR where)
  379. +{
  380. + unsigned long insn;
  381. +
  382. + (*the_target->read_memory) (where, (unsigned char *) &insn, 4);
  383. + if (insn == microblaze_breakpoint)
  384. + return 1;
  385. + /* If necessary, recognize more trap instructions here. GDB only uses the
  386. + one. */
  387. + return 0;
  388. +}
  389. +
  390. +static CORE_ADDR
  391. +microblaze_reinsert_addr (struct regcache *regcache)
  392. +{
  393. + unsigned long pc;
  394. + collect_register_by_name (regcache, "r15", &pc);
  395. + return pc;
  396. +}
  397. +
  398. +#ifdef HAVE_PTRACE_GETREGS
  399. +
  400. +static void
  401. +microblaze_collect_ptrace_register (struct regcache *regcache, int regno, char *buf)
  402. +{
  403. + int size = register_size (regcache->tdesc, regno);
  404. +
  405. + memset (buf, 0, sizeof (long));
  406. +
  407. + if (size < sizeof (long))
  408. + collect_register (regcache, regno, buf + sizeof (long) - size);
  409. + else
  410. + collect_register (regcache, regno, buf);
  411. +}
  412. +
  413. +static void
  414. +microblaze_supply_ptrace_register (struct regcache *regcache,
  415. + int regno, const char *buf)
  416. +{
  417. + int size = register_size (regcache->tdesc, regno);
  418. +
  419. + if (regno == 0) {
  420. + unsigned long regbuf_0 = 0;
  421. + /* clobbering r0 so that it is always 0 as enforced by hardware */
  422. + supply_register (regcache, regno, (const char*)&regbuf_0);
  423. + } else {
  424. + if (size < sizeof (long))
  425. + supply_register (regcache, regno, buf + sizeof (long) - size);
  426. + else
  427. + supply_register (regcache, regno, buf);
  428. + }
  429. +}
  430. +
  431. +/* Provide only a fill function for the general register set. ps_lgetregs
  432. + will use this for NPTL support. */
  433. +
  434. +static void microblaze_fill_gregset (struct regcache *regcache, void *buf)
  435. +{
  436. + int i;
  437. +
  438. + for (i = 0; i < 32; i++)
  439. + microblaze_collect_ptrace_register (regcache, i, (char *) buf + microblaze_regmap[i]);
  440. +}
  441. +
  442. +static void
  443. +microblaze_store_gregset (struct regcache *regcache, const void *buf)
  444. +{
  445. + int i;
  446. +
  447. + for (i = 0; i < 32; i++)
  448. + supply_register (regcache, i, (char *) buf + microblaze_regmap[i]);
  449. +}
  450. +
  451. +#endif /* HAVE_PTRACE_GETREGS */
  452. +
  453. +static struct regset_info microblaze_regsets[] = {
  454. +#ifdef HAVE_PTRACE_GETREGS
  455. + { PTRACE_GETREGS, PTRACE_SETREGS, 0, sizeof (elf_gregset_t), GENERAL_REGS, microblaze_fill_gregset, microblaze_store_gregset },
  456. + { 0, 0, 0, -1, -1, NULL, NULL },
  457. +#endif /* HAVE_PTRACE_GETREGS */
  458. + { 0, 0, 0, -1, -1, NULL, NULL }
  459. +};
  460. +
  461. +static struct regsets_info microblaze_regsets_info =
  462. + {
  463. + microblaze_regsets, /* regsets */
  464. + 0, /* num_regsets */
  465. + NULL, /* disabled_regsets */
  466. + };
  467. +
  468. +static struct usrregs_info microblaze_usrregs_info =
  469. + {
  470. + microblaze_num_regs,
  471. + microblaze_regmap,
  472. + };
  473. +
  474. +static struct regs_info regs_info =
  475. + {
  476. + NULL, /* regset_bitmap */
  477. + &microblaze_usrregs_info,
  478. + &microblaze_regsets_info
  479. + };
  480. +
  481. +static const struct regs_info *
  482. +microblaze_regs_info (void)
  483. +{
  484. + return &regs_info;
  485. +}
  486. +
  487. +static void
  488. +microblaze_arch_setup (void)
  489. +{
  490. + current_process ()->tdesc = tdesc_microblaze;
  491. +}
  492. +
  493. +struct linux_target_ops the_low_target = {
  494. + microblaze_arch_setup,
  495. + microblaze_regs_info,
  496. + microblaze_cannot_fetch_register,
  497. + microblaze_cannot_store_register,
  498. + NULL, /* fetch_register */
  499. + microblaze_get_pc,
  500. + microblaze_set_pc,
  501. + (const unsigned char *) &microblaze_breakpoint,
  502. + microblaze_breakpoint_len,
  503. + microblaze_reinsert_addr,
  504. + 0,
  505. + microblaze_breakpoint_at,
  506. + NULL,
  507. + NULL,
  508. + NULL,
  509. + NULL,
  510. + microblaze_collect_ptrace_register,
  511. + microblaze_supply_ptrace_register,
  512. +};
  513. +
  514. +void
  515. +initialize_low_arch (void)
  516. +{
  517. + init_registers_microblaze ();
  518. +
  519. + initialize_regsets_info (&microblaze_regsets_info);
  520. +}
  521. \ No newline at end of file
  522. diff -Nur gdb-7.8.2.orig/gdb/gdbserver/Makefile.in gdb-7.8.2/gdb/gdbserver/Makefile.in
  523. --- gdb-7.8.2.orig/gdb/gdbserver/Makefile.in 2015-01-15 11:58:12.000000000 +0100
  524. +++ gdb-7.8.2/gdb/gdbserver/Makefile.in 2016-05-14 21:29:38.993383375 +0200
  525. @@ -148,6 +148,7 @@
  526. $(srcdir)/linux-ia64-low.c $(srcdir)/linux-low.c \
  527. $(srcdir)/linux-m32r-low.c \
  528. $(srcdir)/linux-m68k-low.c $(srcdir)/linux-mips-low.c \
  529. + $(srcdir)/linux-microblaze-low.c \
  530. $(srcdir)/linux-nios2-low.c \
  531. $(srcdir)/linux-ppc-low.c \
  532. $(srcdir)/linux-s390-low.c \
  533. @@ -329,6 +330,7 @@
  534. rm -f arm-with-iwmmxt.c
  535. rm -f arm-with-vfpv2.c arm-with-vfpv3.c arm-with-neon.c
  536. rm -f mips-linux.c mips64-linux.c
  537. + rm -f microblaze-linux.c
  538. rm -f nios2-linux.c
  539. rm -f powerpc-32.c powerpc-32l.c powerpc-64l.c powerpc-e500l.c
  540. rm -f powerpc-altivec32l.c powerpc-cell32l.c powerpc-vsx32l.c
  541. @@ -620,6 +622,8 @@
  542. $(SHELL) $(regdat_sh) $(srcdir)/../regformats/mips64-linux.dat mips64-linux.c
  543. mips64-dsp-linux.c : $(srcdir)/../regformats/mips64-dsp-linux.dat $(regdat_sh)
  544. $(SHELL) $(regdat_sh) $(srcdir)/../regformats/mips64-dsp-linux.dat mips64-dsp-linux.c
  545. +microblaze-linux.c : $(srcdir)/../regformats/reg-microblaze.dat $(regdat_sh)
  546. + $(SHELL) $(regdat_sh) $(srcdir)/../regformats/reg-microblaze.dat microblaze-linux.c
  547. nios2-linux.c : $(srcdir)/../regformats/nios2-linux.dat $(regdat_sh)
  548. $(SHELL) $(regdat_sh) $(srcdir)/../regformats/nios2-linux.dat nios2-linux.c
  549. powerpc-32.c : $(srcdir)/../regformats/rs6000/powerpc-32.dat $(regdat_sh)
  550. diff -Nur gdb-7.8.2.orig/gdb/Makefile.in gdb-7.8.2/gdb/Makefile.in
  551. --- gdb-7.8.2.orig/gdb/Makefile.in 2015-01-15 11:58:12.000000000 +0100
  552. +++ gdb-7.8.2/gdb/Makefile.in 2016-05-14 21:29:38.993383375 +0200
  553. @@ -912,7 +912,7 @@
  554. annotate.h sim-regno.h dictionary.h dfp.h main.h frame-unwind.h \
  555. remote-fileio.h i386-linux-tdep.h vax-tdep.h objc-lang.h \
  556. sentinel-frame.h bcache.h symfile.h windows-tdep.h linux-tdep.h \
  557. -gdb_usleep.h jit.h xml-syscall.h microblaze-tdep.h \
  558. +gdb_usleep.h jit.h xml-syscall.h microblaze-tdep.h microblaze-linux-tdep.h \
  559. psymtab.h psympriv.h progspace.h bfin-tdep.h ia64-hpux-tdep.h \
  560. amd64-darwin-tdep.h charset-list.h \
  561. config/djgpp/langinfo.h config/djgpp/nl_types.h darwin-nat.h \
  562. @@ -1639,7 +1639,7 @@
  563. m68kbsd-nat.c m68kbsd-tdep.c \
  564. m68klinux-nat.c m68klinux-tdep.c \
  565. m88k-tdep.c m88kbsd-nat.c \
  566. - microblaze-tdep.c microblaze-linux-tdep.c \
  567. + microblaze-tdep.c microblaze-linux-nat.c microblaze-linux-tdep.c \
  568. mingw-hdep.c \
  569. mips-linux-nat.c mips-linux-tdep.c \
  570. mips-irix-tdep.c \
  571. diff -Nur gdb-7.8.2.orig/gdb/microblaze-linux-nat.c gdb-7.8.2/gdb/microblaze-linux-nat.c
  572. --- gdb-7.8.2.orig/gdb/microblaze-linux-nat.c 1970-01-01 01:00:00.000000000 +0100
  573. +++ gdb-7.8.2/gdb/microblaze-linux-nat.c 2016-05-14 21:29:38.993383375 +0200
  574. @@ -0,0 +1,430 @@
  575. +/* Microblaze GNU/Linux native support.
  576. +
  577. + Copyright (C) 1988-1989, 1991-1992, 1994, 1996, 2000-2012 Free
  578. + Software Foundation, Inc.
  579. +
  580. + This file is part of GDB.
  581. +
  582. + This program is free software; you can redistribute it and/or modify
  583. + it under the terms of the GNU General Public License as published by
  584. + the Free Software Foundation; either version 3 of the License, or
  585. + (at your option) any later version.
  586. +
  587. + This program is distributed in the hope that it will be useful,
  588. + but WITHOUT ANY WARRANTY; without even the implied warranty of
  589. + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
  590. + GNU General Public License for more details.
  591. +
  592. + You should have received a copy of the GNU General Public License
  593. + along with this program. If not, see <http://www.gnu.org/licenses/>. */
  594. +
  595. +#include "defs.h"
  596. +#include "arch-utils.h"
  597. +#include "dis-asm.h"
  598. +#include "frame.h"
  599. +#include "trad-frame.h"
  600. +#include "symtab.h"
  601. +#include "value.h"
  602. +#include "gdbcmd.h"
  603. +#include "breakpoint.h"
  604. +#include "inferior.h"
  605. +#include "regcache.h"
  606. +#include "target.h"
  607. +#include "frame.h"
  608. +#include "frame-base.h"
  609. +#include "frame-unwind.h"
  610. +#include "dwarf2-frame.h"
  611. +#include "osabi.h"
  612. +
  613. +#include "gdb_assert.h"
  614. +#include "target-descriptions.h"
  615. +#include "opcodes/microblaze-opcm.h"
  616. +#include "opcodes/microblaze-dis.h"
  617. +
  618. +#include "linux-nat.h"
  619. +#include "target-descriptions.h"
  620. +
  621. +#include <sys/user.h>
  622. +#include <sys/utsname.h>
  623. +#include <sys/procfs.h>
  624. +#include <sys/ptrace.h>
  625. +
  626. +/* Prototypes for supply_gregset etc. */
  627. +#include "gregset.h"
  628. +
  629. +#include "microblaze-tdep.h"
  630. +
  631. +#include <elf/common.h>
  632. +#include "auxv.h"
  633. +
  634. +/* Defines ps_err_e, struct ps_prochandle. */
  635. +#include "gdb_proc_service.h"
  636. +
  637. +/* On GNU/Linux, threads are implemented as pseudo-processes, in which
  638. + case we may be tracing more than one process at a time. In that
  639. + case, inferior_ptid will contain the main process ID and the
  640. + individual thread (process) ID. get_thread_id () is used to get
  641. + the thread id if it's available, and the process id otherwise. */
  642. +
  643. +int
  644. +get_thread_id (ptid_t ptid)
  645. +{
  646. + int tid = ptid_get_lwp (ptid);
  647. + if (0 == tid)
  648. + tid = ptid_get_pid (ptid);
  649. + return tid;
  650. +}
  651. +
  652. +#define GET_THREAD_ID(PTID) get_thread_id (PTID)
  653. +
  654. +/* Non-zero if our kernel may support the PTRACE_GETREGS and
  655. + PTRACE_SETREGS requests, for reading and writing the
  656. + general-purpose registers. Zero if we've tried one of
  657. + them and gotten an error. */
  658. +int have_ptrace_getsetregs = 1;
  659. +
  660. +static int
  661. +microblaze_register_u_addr (struct gdbarch *gdbarch, int regno)
  662. +{
  663. + int u_addr = -1;
  664. + struct gdbarch_tdep *tdep = gdbarch_tdep (gdbarch);
  665. + /* NOTE: cagney/2003-11-25: This is the word size used by the ptrace
  666. + interface, and not the wordsize of the program's ABI. */
  667. + int wordsize = sizeof (long);
  668. +
  669. + /* General purpose registers occupy 1 slot each in the buffer. */
  670. + if (regno >= MICROBLAZE_R0_REGNUM
  671. + && regno <= MICROBLAZE_FSR_REGNUM)
  672. + u_addr = (regno * wordsize);
  673. +
  674. + return u_addr;
  675. +}
  676. +
  677. +
  678. +static void
  679. +fetch_register (struct regcache *regcache, int tid, int regno)
  680. +{
  681. + struct gdbarch *gdbarch = get_regcache_arch (regcache);
  682. + struct gdbarch_tdep *tdep = gdbarch_tdep (gdbarch);
  683. + /* This isn't really an address. But ptrace thinks of it as one. */
  684. + CORE_ADDR regaddr = microblaze_register_u_addr (gdbarch, regno);
  685. + int bytes_transferred;
  686. + unsigned int offset; /* Offset of registers within the u area. */
  687. + char buf[MAX_REGISTER_SIZE];
  688. +
  689. + if (regaddr == -1)
  690. + {
  691. + memset (buf, '\0', register_size (gdbarch, regno)); /* Supply zeroes */
  692. + regcache_raw_supply (regcache, regno, buf);
  693. + return;
  694. + }
  695. +
  696. + /* Read the raw register using sizeof(long) sized chunks. On a
  697. + 32-bit platform, 64-bit floating-point registers will require two
  698. + transfers. */
  699. + for (bytes_transferred = 0;
  700. + bytes_transferred < register_size (gdbarch, regno);
  701. + bytes_transferred += sizeof (long))
  702. + {
  703. + long l;
  704. +
  705. + errno = 0;
  706. + l = ptrace (PTRACE_PEEKUSER, tid, (PTRACE_TYPE_ARG3) regaddr, 0);
  707. + regaddr += sizeof (long);
  708. + if (errno != 0)
  709. + {
  710. + char message[128];
  711. + sprintf (message, "reading register %s (#%d)",
  712. + gdbarch_register_name (gdbarch, regno), regno);
  713. + perror_with_name (message);
  714. + }
  715. + memcpy (&buf[bytes_transferred], &l, sizeof (l));
  716. + }
  717. +
  718. + /* Now supply the register. Keep in mind that the regcache's idea
  719. + of the register's size may not be a multiple of sizeof
  720. + (long). */
  721. + if (gdbarch_byte_order (gdbarch) == BFD_ENDIAN_LITTLE)
  722. + {
  723. + /* Little-endian values are always found at the left end of the
  724. + bytes transferred. */
  725. + regcache_raw_supply (regcache, regno, buf);
  726. + }
  727. + else if (gdbarch_byte_order (gdbarch) == BFD_ENDIAN_BIG)
  728. + {
  729. + /* Big-endian values are found at the right end of the bytes
  730. + transferred. */
  731. + size_t padding = (bytes_transferred - register_size (gdbarch, regno));
  732. + regcache_raw_supply (regcache, regno, buf + padding);
  733. + }
  734. + else
  735. + internal_error (__FILE__, __LINE__,
  736. + _("fetch_register: unexpected byte order: %d"),
  737. + gdbarch_byte_order (gdbarch));
  738. +}
  739. +
  740. +/* This function actually issues the request to ptrace, telling
  741. + it to get all general-purpose registers and put them into the
  742. + specified regset.
  743. +
  744. + If the ptrace request does not exist, this function returns 0
  745. + and properly sets the have_ptrace_* flag. If the request fails,
  746. + this function calls perror_with_name. Otherwise, if the request
  747. + succeeds, then the regcache gets filled and 1 is returned. */
  748. +static int
  749. +fetch_all_gp_regs (struct regcache *regcache, int tid)
  750. +{
  751. + struct gdbarch *gdbarch = get_regcache_arch (regcache);
  752. + struct gdbarch_tdep *tdep = gdbarch_tdep (gdbarch);
  753. + gdb_gregset_t gregset;
  754. +
  755. + if (ptrace (PTRACE_GETREGS, tid, 0, (void *) &gregset) < 0)
  756. + {
  757. + if (errno == EIO)
  758. + {
  759. + have_ptrace_getsetregs = 0;
  760. + return 0;
  761. + }
  762. + perror_with_name (_("Couldn't get general-purpose registers."));
  763. + }
  764. +
  765. + supply_gregset (regcache, (const gdb_gregset_t *) &gregset);
  766. +
  767. + return 1;
  768. +}
  769. +
  770. +
  771. +/* This is a wrapper for the fetch_all_gp_regs function. It is
  772. + responsible for verifying if this target has the ptrace request
  773. + that can be used to fetch all general-purpose registers at one
  774. + shot. If it doesn't, then we should fetch them using the
  775. + old-fashioned way, which is to iterate over the registers and
  776. + request them one by one. */
  777. +static void
  778. +fetch_gp_regs (struct regcache *regcache, int tid)
  779. +{
  780. + struct gdbarch *gdbarch = get_regcache_arch (regcache);
  781. + struct gdbarch_tdep *tdep = gdbarch_tdep (gdbarch);
  782. + int i;
  783. +
  784. + if (have_ptrace_getsetregs)
  785. + if (fetch_all_gp_regs (regcache, tid))
  786. + return;
  787. +
  788. + /* If we've hit this point, it doesn't really matter which
  789. + architecture we are using. We just need to read the
  790. + registers in the "old-fashioned way". */
  791. + for (i = MICROBLAZE_R0_REGNUM; i <= MICROBLAZE_FSR_REGNUM; i++)
  792. + fetch_register (regcache, tid, i);
  793. +}
  794. +
  795. +
  796. +static void
  797. +store_register (const struct regcache *regcache, int tid, int regno)
  798. +{
  799. + struct gdbarch *gdbarch = get_regcache_arch (regcache);
  800. + struct gdbarch_tdep *tdep = gdbarch_tdep (gdbarch);
  801. + /* This isn't really an address. But ptrace thinks of it as one. */
  802. + CORE_ADDR regaddr = microblaze_register_u_addr (gdbarch, regno);
  803. + int i;
  804. + size_t bytes_to_transfer;
  805. + char buf[MAX_REGISTER_SIZE];
  806. +
  807. + if (regaddr == -1)
  808. + return;
  809. +
  810. + /* First collect the register. Keep in mind that the regcache's
  811. + idea of the register's size may not be a multiple of sizeof
  812. + (long). */
  813. + memset (buf, 0, sizeof buf);
  814. + bytes_to_transfer = align_up (register_size (gdbarch, regno), sizeof (long));
  815. + if (gdbarch_byte_order (gdbarch) == BFD_ENDIAN_LITTLE)
  816. + {
  817. + /* Little-endian values always sit at the left end of the buffer. */
  818. + regcache_raw_collect (regcache, regno, buf);
  819. + }
  820. + else if (gdbarch_byte_order (gdbarch) == BFD_ENDIAN_BIG)
  821. + {
  822. + /* Big-endian values sit at the right end of the buffer. */
  823. + size_t padding = (bytes_to_transfer - register_size (gdbarch, regno));
  824. + regcache_raw_collect (regcache, regno, buf + padding);
  825. + }
  826. +
  827. + for (i = 0; i < bytes_to_transfer; i += sizeof (long))
  828. + {
  829. + long l;
  830. +
  831. + memcpy (&l, &buf[i], sizeof (l));
  832. + errno = 0;
  833. + ptrace (PTRACE_POKEUSER, tid, (PTRACE_TYPE_ARG3) regaddr, l);
  834. + regaddr += sizeof (long);
  835. +
  836. + if (errno != 0)
  837. + {
  838. + char message[128];
  839. + sprintf (message, "writing register %s (#%d)",
  840. + gdbarch_register_name (gdbarch, regno), regno);
  841. + perror_with_name (message);
  842. + }
  843. + }
  844. +}
  845. +
  846. +/* This function actually issues the request to ptrace, telling
  847. + it to store all general-purpose registers present in the specified
  848. + regset.
  849. +
  850. + If the ptrace request does not exist, this function returns 0
  851. + and properly sets the have_ptrace_* flag. If the request fails,
  852. + this function calls perror_with_name. Otherwise, if the request
  853. + succeeds, then the regcache is stored and 1 is returned. */
  854. +static int
  855. +store_all_gp_regs (const struct regcache *regcache, int tid, int regno)
  856. +{
  857. + struct gdbarch *gdbarch = get_regcache_arch (regcache);
  858. + struct gdbarch_tdep *tdep = gdbarch_tdep (gdbarch);
  859. + gdb_gregset_t gregset;
  860. +
  861. + if (ptrace (PTRACE_GETREGS, tid, 0, (void *) &gregset) < 0)
  862. + {
  863. + if (errno == EIO)
  864. + {
  865. + have_ptrace_getsetregs = 0;
  866. + return 0;
  867. + }
  868. + perror_with_name (_("Couldn't get general-purpose registers."));
  869. + }
  870. +
  871. + fill_gregset (regcache, &gregset, regno);
  872. +
  873. + if (ptrace (PTRACE_SETREGS, tid, 0, (void *) &gregset) < 0)
  874. + {
  875. + if (errno == EIO)
  876. + {
  877. + have_ptrace_getsetregs = 0;
  878. + return 0;
  879. + }
  880. + perror_with_name (_("Couldn't set general-purpose registers."));
  881. + }
  882. +
  883. + return 1;
  884. +}
  885. +
  886. +/* This is a wrapper for the store_all_gp_regs function. It is
  887. + responsible for verifying if this target has the ptrace request
  888. + that can be used to store all general-purpose registers at one
  889. + shot. If it doesn't, then we should store them using the
  890. + old-fashioned way, which is to iterate over the registers and
  891. + store them one by one. */
  892. +static void
  893. +store_gp_regs (const struct regcache *regcache, int tid, int regno)
  894. +{
  895. + struct gdbarch *gdbarch = get_regcache_arch (regcache);
  896. + struct gdbarch_tdep *tdep = gdbarch_tdep (gdbarch);
  897. + int i;
  898. +
  899. + if (have_ptrace_getsetregs)
  900. + if (store_all_gp_regs (regcache, tid, regno))
  901. + return;
  902. +
  903. + /* If we hit this point, it doesn't really matter which
  904. + architecture we are using. We just need to store the
  905. + registers in the "old-fashioned way". */
  906. + for (i = MICROBLAZE_R0_REGNUM; i <= MICROBLAZE_FSR_REGNUM; i++)
  907. + store_register (regcache, tid, i);
  908. +}
  909. +
  910. +
  911. +/* Fetch registers from the child process. Fetch all registers if
  912. + regno == -1, otherwise fetch all general registers or all floating
  913. + point registers depending upon the value of regno. */
  914. +
  915. +static void
  916. +microblaze_linux_fetch_inferior_registers (struct target_ops *ops,
  917. + struct regcache *regcache, int regno)
  918. +{
  919. + /* Get the thread id for the ptrace call. */
  920. + int tid = GET_THREAD_ID (inferior_ptid);
  921. +
  922. + if (regno == -1)
  923. + fetch_gp_regs (regcache, tid);
  924. + else
  925. + fetch_register (regcache, tid, regno);
  926. +}
  927. +
  928. +/* Store registers back into the inferior. Store all registers if
  929. + regno == -1, otherwise store all general registers or all floating
  930. + point registers depending upon the value of regno. */
  931. +
  932. +static void
  933. +microblaze_linux_store_inferior_registers (struct target_ops *ops,
  934. + struct regcache *regcache, int regno)
  935. +{
  936. + /* Get the thread id for the ptrace call. */
  937. + int tid = GET_THREAD_ID (inferior_ptid);
  938. +
  939. + if (regno >= 0)
  940. + store_register (regcache, tid, regno);
  941. + else
  942. + store_gp_regs (regcache, tid, -1);
  943. +}
  944. +
  945. +/* Wrapper functions for the standard regset handling, used by
  946. + thread debugging. */
  947. +
  948. +void
  949. +fill_gregset (const struct regcache *regcache,
  950. + gdb_gregset_t *gregsetp, int regno)
  951. +{
  952. + microblaze_collect_gregset (NULL, regcache, regno, gregsetp);
  953. +}
  954. +
  955. +void
  956. +supply_gregset (struct regcache *regcache, const gdb_gregset_t *gregsetp)
  957. +{
  958. + microblaze_supply_gregset (NULL, regcache, -1, gregsetp);
  959. +}
  960. +
  961. +void
  962. +fill_fpregset (const struct regcache *regcache,
  963. + gdb_fpregset_t *fpregsetp, int regno)
  964. +{
  965. + /* FIXME. */
  966. +}
  967. +
  968. +void
  969. +supply_fpregset (struct regcache *regcache, const gdb_fpregset_t *fpregsetp)
  970. +{
  971. + /* FIXME. */
  972. +}
  973. +
  974. +static const struct target_desc *
  975. +microblaze_linux_read_description (struct target_ops *ops)
  976. +{
  977. + CORE_ADDR microblaze_hwcap = 0;
  978. +
  979. + if (target_auxv_search (ops, AT_HWCAP, &microblaze_hwcap) != 1)
  980. + return NULL;
  981. +
  982. + return NULL;
  983. +}
  984. +
  985. +
  986. +void _initialize_microblaze_linux_nat (void);
  987. +
  988. +void
  989. +_initialize_microblaze_linux_nat (void)
  990. +{
  991. + struct target_ops *t;
  992. +
  993. + /* Fill in the generic GNU/Linux methods. */
  994. + t = linux_target ();
  995. +
  996. + /* Add our register access methods. */
  997. + t->to_fetch_registers = microblaze_linux_fetch_inferior_registers;
  998. + t->to_store_registers = microblaze_linux_store_inferior_registers;
  999. +
  1000. + t->to_read_description = microblaze_linux_read_description;
  1001. +
  1002. + /* Register the target. */
  1003. + linux_nat_add_target (t);
  1004. +}
  1005. diff -Nur gdb-7.8.2.orig/gdb/microblaze-linux-tdep.c gdb-7.8.2/gdb/microblaze-linux-tdep.c
  1006. --- gdb-7.8.2.orig/gdb/microblaze-linux-tdep.c 2015-01-15 11:58:12.000000000 +0100
  1007. +++ gdb-7.8.2/gdb/microblaze-linux-tdep.c 2016-05-15 13:56:18.171253048 +0200
  1008. @@ -1,6 +1,6 @@
  1009. /* Target-dependent code for Xilinx MicroBlaze.
  1010. - Copyright (C) 2009-2014 Free Software Foundation, Inc.
  1011. + Copyright (C) 2009-2013 Free Software Foundation, Inc.
  1012. This file is part of GDB.
  1013. @@ -32,11 +32,28 @@
  1014. #include "regset.h"
  1015. #include "solib-svr4.h"
  1016. #include "microblaze-tdep.h"
  1017. +#include "glibc-tdep.h"
  1018. #include "trad-frame.h"
  1019. #include "frame-unwind.h"
  1020. #include "tramp-frame.h"
  1021. #include "linux-tdep.h"
  1022. +static int microblaze_debug_flag = 0;
  1023. +
  1024. +static void
  1025. +microblaze_debug (const char *fmt, ...)
  1026. +{
  1027. + if (microblaze_debug_flag)
  1028. + {
  1029. + va_list args;
  1030. +
  1031. + va_start (args, fmt);
  1032. + printf_unfiltered ("MICROBLAZE LINUX: ");
  1033. + vprintf_unfiltered (fmt, args);
  1034. + va_end (args);
  1035. + }
  1036. +}
  1037. +
  1038. static int
  1039. microblaze_linux_memory_remove_breakpoint (struct gdbarch *gdbarch,
  1040. struct bp_target_info *bp_tgt)
  1041. @@ -46,20 +63,27 @@
  1042. int val;
  1043. int bplen;
  1044. gdb_byte old_contents[BREAKPOINT_MAX];
  1045. + struct cleanup *cleanup;
  1046. /* Determine appropriate breakpoint contents and size for this address. */
  1047. bp = gdbarch_breakpoint_from_pc (gdbarch, &addr, &bplen);
  1048. if (bp == NULL)
  1049. error (_("Software breakpoints not implemented for this target."));
  1050. + /* Make sure we see the memory breakpoints. */
  1051. + cleanup = make_show_memory_breakpoints_cleanup (1);
  1052. val = target_read_memory (addr, old_contents, bplen);
  1053. /* If our breakpoint is no longer at the address, this means that the
  1054. program modified the code on us, so it is wrong to put back the
  1055. old value. */
  1056. if (val == 0 && memcmp (bp, old_contents, bplen) == 0)
  1057. - val = target_write_raw_memory (addr, bp_tgt->shadow_contents, bplen);
  1058. + {
  1059. + val = target_write_raw_memory (addr, bp_tgt->shadow_contents, bplen);
  1060. + microblaze_debug ("microblaze_linux_memory_remove_breakpoint writing back to memory at addr 0x%lx\n", addr);
  1061. + }
  1062. + do_cleanups (cleanup);
  1063. return val;
  1064. }
  1065. @@ -116,6 +140,50 @@
  1066. microblaze_linux_sighandler_cache_init
  1067. };
  1068. +const struct microblaze_gregset microblaze_linux_core_gregset;
  1069. +
  1070. +static void
  1071. +microblaze_linux_supply_core_gregset (const struct regset *regset,
  1072. + struct regcache *regcache,
  1073. + int regnum, const void *gregs, size_t len)
  1074. +{
  1075. + microblaze_supply_gregset (&microblaze_linux_core_gregset, regcache,
  1076. + regnum, gregs);
  1077. +}
  1078. +
  1079. +static void
  1080. +microblaze_linux_collect_core_gregset (const struct regset *regset,
  1081. + const struct regcache *regcache,
  1082. + int regnum, void *gregs, size_t len)
  1083. +{
  1084. + microblaze_collect_gregset (&microblaze_linux_core_gregset, regcache,
  1085. + regnum, gregs);
  1086. +}
  1087. +
  1088. +static void
  1089. +microblaze_linux_supply_core_fpregset (const struct regset *regset,
  1090. + struct regcache *regcache,
  1091. + int regnum, const void *fpregs, size_t len)
  1092. +{
  1093. + /* FIXME. */
  1094. + microblaze_supply_fpregset (regcache, regnum, fpregs);
  1095. +}
  1096. +
  1097. +static void
  1098. +microblaze_linux_collect_core_fpregset (const struct regset *regset,
  1099. + const struct regcache *regcache,
  1100. + int regnum, void *fpregs, size_t len)
  1101. +{
  1102. + /* FIXME. */
  1103. + microblaze_collect_fpregset (regcache, regnum, fpregs);
  1104. +}
  1105. +
  1106. +static const struct regset microblaze_linux_gregset =
  1107. +{
  1108. + NULL,
  1109. + microblaze_linux_supply_core_gregset,
  1110. + microblaze_linux_collect_core_gregset
  1111. +};
  1112. static void
  1113. microblaze_linux_init_abi (struct gdbarch_info info,
  1114. @@ -123,6 +191,9 @@
  1115. {
  1116. struct gdbarch_tdep *tdep = gdbarch_tdep (gdbarch);
  1117. + tdep->gregset = &microblaze_linux_gregset;
  1118. + tdep->sizeof_gregset = 200;
  1119. +
  1120. linux_init_abi (info, gdbarch);
  1121. set_gdbarch_memory_remove_breakpoint (gdbarch,
  1122. @@ -135,6 +206,25 @@
  1123. /* Trampolines. */
  1124. tramp_frame_prepend_unwinder (gdbarch,
  1125. &microblaze_linux_sighandler_tramp_frame);
  1126. +
  1127. + /* BFD target for core files. */
  1128. + if (gdbarch_byte_order (gdbarch) == BFD_ENDIAN_BIG)
  1129. + set_gdbarch_gcore_bfd_target (gdbarch, "elf32-microblaze");
  1130. + else
  1131. + set_gdbarch_gcore_bfd_target (gdbarch, "elf32-microblazeel");
  1132. +
  1133. +
  1134. + /* Shared library handling. */
  1135. + set_gdbarch_skip_trampoline_code (gdbarch, find_solib_trampoline_target);
  1136. + set_gdbarch_skip_solib_resolver (gdbarch, glibc_skip_solib_resolver);
  1137. +
  1138. + set_gdbarch_regset_from_core_section (gdbarch,
  1139. + microblaze_regset_from_core_section);
  1140. +
  1141. + /* Enable TLS support. */
  1142. + set_gdbarch_fetch_tls_load_module_address (gdbarch,
  1143. + svr4_fetch_objfile_link_map);
  1144. +
  1145. }
  1146. /* -Wmissing-prototypes */
  1147. diff -Nur gdb-7.8.2.orig/gdb/microblaze-rom.c gdb-7.8.2/gdb/microblaze-rom.c
  1148. --- gdb-7.8.2.orig/gdb/microblaze-rom.c 2015-01-15 11:58:12.000000000 +0100
  1149. +++ gdb-7.8.2/gdb/microblaze-rom.c 2016-05-14 21:29:38.997383530 +0200
  1150. @@ -1,6 +1,6 @@
  1151. /* Remote debugging interface to Xilinx MicroBlaze.
  1152. - Copyright (C) 2009-2014 Free Software Foundation, Inc.
  1153. + Copyright (C) 2009-2013 Free Software Foundation, Inc.
  1154. This file is part of GDB.
  1155. @@ -21,7 +21,6 @@
  1156. #include "gdbcore.h"
  1157. #include "target.h"
  1158. #include "monitor.h"
  1159. -#include <string.h>
  1160. #include "serial.h"
  1161. #include "regcache.h"
  1162. diff -Nur gdb-7.8.2.orig/gdb/microblaze-tdep.c gdb-7.8.2/gdb/microblaze-tdep.c
  1163. --- gdb-7.8.2.orig/gdb/microblaze-tdep.c 2015-01-15 11:58:12.000000000 +0100
  1164. +++ gdb-7.8.2/gdb/microblaze-tdep.c 2016-05-14 21:29:38.997383530 +0200
  1165. @@ -1,6 +1,6 @@
  1166. /* Target-dependent code for Xilinx MicroBlaze.
  1167. - Copyright (C) 2009-2014 Free Software Foundation, Inc.
  1168. + Copyright (C) 2009-2013 Free Software Foundation, Inc.
  1169. This file is part of GDB.
  1170. @@ -29,13 +29,13 @@
  1171. #include "inferior.h"
  1172. #include "regcache.h"
  1173. #include "target.h"
  1174. +#include "frame.h"
  1175. #include "frame-base.h"
  1176. #include "frame-unwind.h"
  1177. #include "dwarf2-frame.h"
  1178. #include "osabi.h"
  1179. #include "gdb_assert.h"
  1180. -#include <string.h>
  1181. #include "target-descriptions.h"
  1182. #include "opcodes/microblaze-opcm.h"
  1183. #include "opcodes/microblaze-dis.h"
  1184. @@ -73,7 +73,8 @@
  1185. "rpc", "rmsr", "rear", "resr", "rfsr", "rbtr",
  1186. "rpvr0", "rpvr1", "rpvr2", "rpvr3", "rpvr4", "rpvr5", "rpvr6",
  1187. "rpvr7", "rpvr8", "rpvr9", "rpvr10", "rpvr11",
  1188. - "redr", "rpid", "rzpr", "rtlbx", "rtlbsx", "rtlblo", "rtlbhi"
  1189. + "redr", "rpid", "rzpr", "rtlbx", "rtlbsx", "rtlblo", "rtlbhi",
  1190. + "rslr", "rshr"
  1191. };
  1192. #define MICROBLAZE_NUM_REGS ARRAY_SIZE (microblaze_register_names)
  1193. @@ -145,6 +146,14 @@
  1194. return sp;
  1195. }
  1196. +static CORE_ADDR
  1197. +microblaze_store_arguments (struct regcache *regcache, int nargs,
  1198. + struct value **args, CORE_ADDR sp,
  1199. + int struct_return, CORE_ADDR struct_addr)
  1200. +{
  1201. + error (_("store_arguments not implemented"));
  1202. + return sp;
  1203. +}
  1204. static CORE_ADDR
  1205. microblaze_push_dummy_call (struct gdbarch *gdbarch, struct value *function,
  1206. @@ -156,14 +165,52 @@
  1207. return sp;
  1208. }
  1209. +static int
  1210. +microblaze_linux_memory_remove_breakpoint (struct gdbarch *gdbarch,
  1211. + struct bp_target_info *bp_tgt)
  1212. +{
  1213. + CORE_ADDR addr = bp_tgt->placed_address;
  1214. + const unsigned char *bp;
  1215. + int val;
  1216. + int bplen;
  1217. + gdb_byte old_contents[BREAKPOINT_MAX];
  1218. + struct cleanup *cleanup;
  1219. +
  1220. + /* Determine appropriate breakpoint contents and size for this address. */
  1221. + bp = gdbarch_breakpoint_from_pc (gdbarch, &addr, &bplen);
  1222. + if (bp == NULL)
  1223. + error (_("Software breakpoints not implemented for this target."));
  1224. +
  1225. + /* Make sure we see the memory breakpoints. */
  1226. + cleanup = make_show_memory_breakpoints_cleanup (1);
  1227. + val = target_read_memory (addr, old_contents, bplen);
  1228. +
  1229. + /* If our breakpoint is no longer at the address, this means that the
  1230. + program modified the code on us, so it is wrong to put back the
  1231. + old value. */
  1232. + if (val == 0 && memcmp (bp, old_contents, bplen) == 0)
  1233. + {
  1234. + val = target_write_raw_memory (addr, bp_tgt->shadow_contents, bplen);
  1235. + microblaze_debug ("microblaze_linux_memory_remove_breakpoint writing back to memory at addr 0x%lx\n", addr);
  1236. + }
  1237. +
  1238. + do_cleanups (cleanup);
  1239. + return val;
  1240. +}
  1241. +
  1242. static const gdb_byte *
  1243. microblaze_breakpoint_from_pc (struct gdbarch *gdbarch, CORE_ADDR *pc,
  1244. int *len)
  1245. {
  1246. + enum bfd_endian byte_order = gdbarch_byte_order (gdbarch);
  1247. static gdb_byte break_insn[] = MICROBLAZE_BREAKPOINT;
  1248. + static gdb_byte break_insn_le[] = MICROBLAZE_BREAKPOINT_LE;
  1249. *len = sizeof (break_insn);
  1250. - return break_insn;
  1251. + if (byte_order == BFD_ENDIAN_BIG)
  1252. + return break_insn;
  1253. + else
  1254. + return break_insn_le;
  1255. }
  1256. /* Allocate and initialize a frame cache. */
  1257. @@ -178,6 +225,7 @@
  1258. /* Base address. */
  1259. cache->base = 0;
  1260. cache->pc = 0;
  1261. + cache->saved_sp = 0;
  1262. /* Frameless until proven otherwise. */
  1263. cache->frameless_p = 1;
  1264. @@ -234,6 +282,8 @@
  1265. int flags = 0;
  1266. int save_hidden_pointer_found = 0;
  1267. int non_stack_instruction_found = 0;
  1268. + int n_insns;
  1269. + unsigned int *insn_block;
  1270. /* Find the start of this function. */
  1271. find_pc_partial_function (pc, &name, &func_addr, &func_end);
  1272. @@ -273,11 +323,18 @@
  1273. name, paddress (gdbarch, func_addr),
  1274. paddress (gdbarch, stop));
  1275. +/* Do a block read to minimize the transaction with the Debug Agent */
  1276. + n_insns = (stop == func_addr) ? 1 : ((stop - func_addr) / INST_WORD_SIZE);
  1277. + insn_block = calloc(n_insns, sizeof(unsigned long));
  1278. +
  1279. + target_read_memory (func_addr, (void*) insn_block, n_insns * INST_WORD_SIZE );
  1280. +
  1281. for (addr = func_addr; addr < stop; addr += INST_WORD_SIZE)
  1282. {
  1283. insn = microblaze_fetch_instruction (addr);
  1284. + //insn = insn_block[(addr - func_addr) / INST_WORD_SIZE];
  1285. op = microblaze_decode_insn (insn, &rd, &ra, &rb, &imm);
  1286. - microblaze_debug ("%s %08lx\n", paddress (gdbarch, pc), insn);
  1287. + microblaze_debug ("%s %08lx op=%x r%d r%d imm=%d\n", paddress (gdbarch, addr), insn, op, rd, ra, imm);
  1288. /* This code is very sensitive to what functions are present in the
  1289. prologue. It assumes that the (addi, addik, swi, sw) can be the
  1290. @@ -291,6 +348,7 @@
  1291. cache->frameless_p = 0; /* Frame found. */
  1292. save_hidden_pointer_found = 0;
  1293. non_stack_instruction_found = 0;
  1294. + cache->register_offsets[rd] = -imm;
  1295. continue;
  1296. }
  1297. else if (IS_SPILL_SP(op, rd, ra))
  1298. @@ -401,8 +459,8 @@
  1299. part of the prologue. */
  1300. if (save_hidden_pointer_found)
  1301. prologue_end_addr -= INST_WORD_SIZE;
  1302. -
  1303. - return prologue_end_addr;
  1304. + free(insn_block);
  1305. + return prologue_end_addr;
  1306. }
  1307. static CORE_ADDR
  1308. @@ -452,6 +510,7 @@
  1309. return start_pc;
  1310. }
  1311. +enum { REG_UNAVAIL = (CORE_ADDR) -1 };
  1312. /* Normal frames. */
  1313. static struct microblaze_frame_cache *
  1314. @@ -459,7 +518,7 @@
  1315. {
  1316. struct microblaze_frame_cache *cache;
  1317. struct gdbarch *gdbarch = get_frame_arch (next_frame);
  1318. - CORE_ADDR func;
  1319. + CORE_ADDR current_pc;
  1320. int rn;
  1321. if (*this_cache)
  1322. @@ -473,9 +532,18 @@
  1323. for (rn = 0; rn < gdbarch_num_regs (gdbarch); rn++)
  1324. cache->register_offsets[rn] = -1;
  1325. - func = get_frame_func (next_frame);
  1326. + cache->pc = get_frame_func (next_frame);
  1327. + current_pc = get_frame_pc (next_frame);
  1328. +
  1329. + if (cache->pc)
  1330. + microblaze_analyze_prologue (gdbarch, cache->pc, current_pc,
  1331. + cache);
  1332. +
  1333. + cache->base = get_frame_register_unsigned (next_frame, gdbarch_sp_regnum (gdbarch));
  1334. + cache->saved_sp = cache->base + cache->framesize;
  1335. - cache->pc = get_frame_address_in_block (next_frame);
  1336. + cache->register_offsets[MICROBLAZE_PREV_PC_REGNUM] = cache->base;
  1337. + cache->register_offsets[MICROBLAZE_SP_REGNUM] = cache->saved_sp;
  1338. return cache;
  1339. }
  1340. @@ -501,6 +569,14 @@
  1341. struct microblaze_frame_cache *cache =
  1342. microblaze_frame_cache (this_frame, this_cache);
  1343. + if ((regnum == MICROBLAZE_SP_REGNUM &&
  1344. + cache->register_offsets[MICROBLAZE_SP_REGNUM])
  1345. + || (regnum == MICROBLAZE_FP_REGNUM &&
  1346. + cache->register_offsets[MICROBLAZE_SP_REGNUM]))
  1347. +
  1348. + return frame_unwind_got_constant (this_frame, regnum,
  1349. + cache->register_offsets[MICROBLAZE_SP_REGNUM]);
  1350. +
  1351. if (cache->frameless_p)
  1352. {
  1353. if (regnum == MICROBLAZE_PC_REGNUM)
  1354. @@ -508,11 +584,18 @@
  1355. if (regnum == MICROBLAZE_SP_REGNUM)
  1356. regnum = 1;
  1357. return trad_frame_get_prev_register (this_frame,
  1358. - cache->saved_regs, regnum);
  1359. + cache->saved_regs, regnum);
  1360. }
  1361. - else
  1362. - return trad_frame_get_prev_register (this_frame, cache->saved_regs,
  1363. - regnum);
  1364. +
  1365. + if (regnum == MICROBLAZE_PC_REGNUM)
  1366. + {
  1367. + regnum = 15;
  1368. + return frame_unwind_got_memory (this_frame, regnum,
  1369. + cache->register_offsets[MICROBLAZE_PREV_PC_REGNUM]);
  1370. + }
  1371. +
  1372. + return trad_frame_get_prev_register (this_frame, cache->saved_regs,
  1373. + regnum);
  1374. }
  1375. @@ -536,6 +619,12 @@
  1376. return cache->base;
  1377. }
  1378. +static const struct frame_unwind *
  1379. +microblaze_frame_sniffer (struct frame_info *next_frame)
  1380. +{
  1381. + return &microblaze_frame_unwind;
  1382. +}
  1383. +
  1384. static const struct frame_base microblaze_frame_base =
  1385. {
  1386. &microblaze_frame_unwind,
  1387. @@ -628,6 +717,109 @@
  1388. return (TYPE_LENGTH (type) == 16);
  1389. }
  1390. +int
  1391. +microblaze_software_single_step (struct frame_info *frame)
  1392. +{
  1393. + struct gdbarch *arch = get_frame_arch (frame);
  1394. + struct address_space *aspace = get_frame_address_space (frame);
  1395. + struct gdbarch_tdep *tdep = gdbarch_tdep (arch);
  1396. + static char le_breakp[] = MICROBLAZE_BREAKPOINT_LE;
  1397. + static char be_breakp[] = MICROBLAZE_BREAKPOINT;
  1398. + enum bfd_endian byte_order = gdbarch_byte_order (arch);
  1399. + char *breakp = byte_order == BFD_ENDIAN_BIG ? be_breakp : le_breakp;
  1400. + int ret = 0;
  1401. +
  1402. + /* Save the address and the values of the next_pc and the target */
  1403. + static struct sstep_breaks
  1404. + {
  1405. + CORE_ADDR address;
  1406. + bfd_boolean valid;
  1407. + /* Shadow contents. */
  1408. + char data[INST_WORD_SIZE];
  1409. + } stepbreaks[2];
  1410. + int ii;
  1411. +
  1412. + if (1)
  1413. + {
  1414. + CORE_ADDR pc;
  1415. + long insn;
  1416. + enum microblaze_instr minstr;
  1417. + bfd_boolean isunsignednum;
  1418. + enum microblaze_instr_type insn_type;
  1419. + short delay_slots;
  1420. + int imm;
  1421. + bfd_boolean immfound = FALSE;
  1422. +
  1423. + /* Set a breakpoint at the next instruction */
  1424. + /* If the current instruction is an imm, set it at the inst after */
  1425. + /* If the instruction has a delay slot, skip the delay slot */
  1426. + pc = get_frame_pc (frame);
  1427. + insn = microblaze_fetch_instruction (pc);
  1428. + minstr = get_insn_microblaze (insn, &isunsignednum, &insn_type, &delay_slots);
  1429. + if (insn_type == immediate_inst)
  1430. + {
  1431. + int rd, ra, rb;
  1432. + immfound = TRUE;
  1433. + minstr = microblaze_decode_insn (insn, &rd, &ra, &rb, &imm);
  1434. + pc = pc + INST_WORD_SIZE;
  1435. + insn = microblaze_fetch_instruction (pc);
  1436. + minstr = get_insn_microblaze (insn, &isunsignednum, &insn_type, &delay_slots);
  1437. + }
  1438. + stepbreaks[0].address = pc + (delay_slots * INST_WORD_SIZE) + INST_WORD_SIZE;
  1439. + if (insn_type != return_inst) {
  1440. + stepbreaks[0].valid = TRUE;
  1441. + } else {
  1442. + stepbreaks[0].valid = FALSE;
  1443. + }
  1444. +
  1445. + microblaze_debug ("single-step insn_type=%x insn=%x\n", insn_type, insn);
  1446. + /* Now check for branch or return instructions */
  1447. + if (insn_type == branch_inst || insn_type == return_inst) {
  1448. + int limm;
  1449. + int lrd, lra, lrb;
  1450. + int ra, rb;
  1451. + bfd_boolean targetvalid;
  1452. + bfd_boolean unconditionalbranch;
  1453. + microblaze_decode_insn(insn, &lrd, &lra, &lrb, &limm);
  1454. + if (lra >= 0 && lra < MICROBLAZE_NUM_REGS)
  1455. + ra = get_frame_register_unsigned (frame, lra);
  1456. + else
  1457. + ra = 0;
  1458. + if (lrb >= 0 && lrb < MICROBLAZE_NUM_REGS)
  1459. + rb = get_frame_register_unsigned (frame, lrb);
  1460. + else
  1461. + rb = 0;
  1462. +
  1463. + stepbreaks[1].address = microblaze_get_target_address (insn, immfound, imm, pc, ra, rb, &targetvalid, &unconditionalbranch);
  1464. + microblaze_debug ("single-step uncondbr=%d targetvalid=%d target=%x\n", unconditionalbranch, targetvalid, stepbreaks[1].address);
  1465. +
  1466. + if (unconditionalbranch)
  1467. + stepbreaks[0].valid = FALSE; /* This is a unconditional branch: will not come to the next address */
  1468. + if (targetvalid && (stepbreaks[0].valid == FALSE ||
  1469. + (stepbreaks[0].address != stepbreaks[1].address))
  1470. + && (stepbreaks[1].address != pc)) {
  1471. + stepbreaks[1].valid = TRUE;
  1472. + } else {
  1473. + stepbreaks[1].valid = FALSE;
  1474. + }
  1475. + } else {
  1476. + stepbreaks[1].valid = FALSE;
  1477. + }
  1478. +
  1479. + /* Insert the breakpoints */
  1480. + for (ii = 0; ii < 2; ++ii)
  1481. + {
  1482. +
  1483. + /* ignore invalid breakpoint. */
  1484. + if (stepbreaks[ii].valid) {
  1485. + insert_single_step_breakpoint (arch, aspace, stepbreaks[ii].address);
  1486. + ret = 1;
  1487. + }
  1488. + }
  1489. + }
  1490. + return ret;
  1491. +}
  1492. +
  1493. static void
  1494. microblaze_write_pc (struct regcache *regcache, CORE_ADDR pc)
  1495. {
  1496. @@ -664,6 +856,70 @@
  1497. return dwarf2_to_reg_map[reg];
  1498. }
  1499. +
  1500. +void
  1501. +microblaze_supply_gregset (const struct microblaze_gregset *gregset,
  1502. + struct regcache *regcache,
  1503. + int regnum, const void *gregs)
  1504. +{
  1505. + unsigned int *regs = gregs;
  1506. + if (regnum >= 0)
  1507. + regcache_raw_supply (regcache, regnum, regs + regnum);
  1508. +
  1509. + if (regnum == -1) {
  1510. + int i;
  1511. +
  1512. + for (i = 0; i < 50; i++) {
  1513. + regcache_raw_supply (regcache, i, regs + i);
  1514. + }
  1515. + }
  1516. +}
  1517. +
  1518. +
  1519. +void
  1520. +microblaze_collect_gregset (const struct microblaze_gregset *gregset,
  1521. + const struct regcache *regcache,
  1522. + int regnum, void *gregs)
  1523. +{
  1524. + /* FIXME. */
  1525. +}
  1526. +
  1527. +void
  1528. +microblaze_supply_fpregset (struct regcache *regcache,
  1529. + int regnum, const void *fpregs)
  1530. +{
  1531. + /* FIXME. */
  1532. +}
  1533. +
  1534. +void
  1535. +microblaze_collect_fpregset (const struct regcache *regcache,
  1536. + int regnum, void *fpregs)
  1537. +{
  1538. + /* FIXME. */
  1539. +}
  1540. +
  1541. +
  1542. +/* Return the appropriate register set for the core section identified
  1543. + by SECT_NAME and SECT_SIZE. */
  1544. +
  1545. +const struct regset *
  1546. +microblaze_regset_from_core_section (struct gdbarch *gdbarch,
  1547. + const char *sect_name, size_t sect_size)
  1548. +{
  1549. + struct gdbarch_tdep *tdep = gdbarch_tdep (gdbarch);
  1550. +
  1551. + microblaze_debug ("microblaze_regset_from_core_section, sect_name = %s\n", sect_name);
  1552. +
  1553. + if (strcmp (sect_name, ".reg") == 0 && sect_size >= tdep->sizeof_gregset)
  1554. + return tdep->gregset;
  1555. +
  1556. + if (strcmp (sect_name, ".reg2") == 0 && sect_size >= tdep->sizeof_fpregset)
  1557. + return tdep->fpregset;
  1558. +
  1559. + microblaze_debug ("microblaze_regset_from_core_section returning null :-( \n");
  1560. + return NULL;
  1561. +}
  1562. +
  1563. static struct gdbarch *
  1564. microblaze_gdbarch_init (struct gdbarch_info info, struct gdbarch_list *arches)
  1565. {
  1566. @@ -679,6 +935,11 @@
  1567. tdep = XNEW (struct gdbarch_tdep);
  1568. gdbarch = gdbarch_alloc (&info, tdep);
  1569. + tdep->gregset = NULL;
  1570. + tdep->sizeof_gregset = 0;
  1571. + tdep->fpregset = NULL;
  1572. + tdep->sizeof_fpregset = 0;
  1573. +
  1574. set_gdbarch_long_double_bit (gdbarch, 128);
  1575. set_gdbarch_num_regs (gdbarch, MICROBLAZE_NUM_REGS);
  1576. @@ -706,7 +967,10 @@
  1577. /* Stack grows downward. */
  1578. set_gdbarch_inner_than (gdbarch, core_addr_lessthan);
  1579. + set_gdbarch_memory_remove_breakpoint (gdbarch, microblaze_linux_memory_remove_breakpoint);
  1580. +
  1581. set_gdbarch_breakpoint_from_pc (gdbarch, microblaze_breakpoint_from_pc);
  1582. + set_gdbarch_software_single_step (gdbarch, microblaze_software_single_step);
  1583. set_gdbarch_frame_args_skip (gdbarch, 8);
  1584. @@ -725,6 +989,13 @@
  1585. dwarf2_append_unwinders (gdbarch);
  1586. frame_unwind_append_unwinder (gdbarch, &microblaze_frame_unwind);
  1587. frame_base_append_sniffer (gdbarch, dwarf2_frame_base_sniffer);
  1588. + //frame_base_append_sniffer (gdbarch, microblaze_frame_sniffer);
  1589. +
  1590. + /* If we have register sets, enable the generic core file support. */
  1591. + if (tdep->gregset) {
  1592. + set_gdbarch_regset_from_core_section (gdbarch,
  1593. + microblaze_regset_from_core_section);
  1594. + }
  1595. return gdbarch;
  1596. }
  1597. diff -Nur gdb-7.8.2.orig/gdb/microblaze-tdep.h gdb-7.8.2/gdb/microblaze-tdep.h
  1598. --- gdb-7.8.2.orig/gdb/microblaze-tdep.h 2015-01-15 11:58:12.000000000 +0100
  1599. +++ gdb-7.8.2/gdb/microblaze-tdep.h 2016-05-14 21:29:38.997383530 +0200
  1600. @@ -1,6 +1,6 @@
  1601. /* Target-dependent code for Xilinx MicroBlaze.
  1602. - Copyright (C) 2009-2014 Free Software Foundation, Inc.
  1603. + Copyright (C) 2009-2013 Free Software Foundation, Inc.
  1604. This file is part of GDB.
  1605. @@ -22,8 +22,22 @@
  1606. /* Microblaze architecture-specific information. */
  1607. +struct microblaze_gregset
  1608. +{
  1609. + unsigned int gregs[32];
  1610. + unsigned int fpregs[32];
  1611. + unsigned int pregs[16];
  1612. +};
  1613. +
  1614. struct gdbarch_tdep
  1615. {
  1616. + int dummy; // declare something.
  1617. +
  1618. + /* Register sets. */
  1619. + struct regset *gregset;
  1620. + size_t sizeof_gregset;
  1621. + struct regset *fpregset;
  1622. + size_t sizeof_fpregset;
  1623. };
  1624. struct microblaze_frame_cache
  1625. @@ -42,7 +56,8 @@
  1626. int fp_regnum;
  1627. /* Offsets to saved registers. */
  1628. - int register_offsets[57]; /* Must match MICROBLAZE_NUM_REGS. */
  1629. + int register_offsets[59]; /* Must match MICROBLAZE_NUM_REGS. */
  1630. + CORE_ADDR saved_sp;
  1631. /* Table of saved registers. */
  1632. struct trad_frame_saved_reg *saved_regs;
  1633. @@ -66,11 +81,11 @@
  1634. MICROBLAZE_R12_REGNUM,
  1635. MICROBLAZE_R13_REGNUM,
  1636. MICROBLAZE_R14_REGNUM,
  1637. - MICROBLAZE_R15_REGNUM,
  1638. + MICROBLAZE_R15_REGNUM, MICROBLAZE_PREV_PC_REGNUM = MICROBLAZE_R15_REGNUM,
  1639. MICROBLAZE_R16_REGNUM,
  1640. MICROBLAZE_R17_REGNUM,
  1641. MICROBLAZE_R18_REGNUM,
  1642. - MICROBLAZE_R19_REGNUM,
  1643. + MICROBLAZE_R19_REGNUM, MICROBLAZE_FP_REGNUM = MICROBLAZE_R19_REGNUM,
  1644. MICROBLAZE_R20_REGNUM,
  1645. MICROBLAZE_R21_REGNUM,
  1646. MICROBLAZE_R22_REGNUM,
  1647. @@ -107,7 +122,9 @@
  1648. MICROBLAZE_RTLBX_REGNUM,
  1649. MICROBLAZE_RTLBSX_REGNUM,
  1650. MICROBLAZE_RTLBLO_REGNUM,
  1651. - MICROBLAZE_RTLBHI_REGNUM
  1652. + MICROBLAZE_RTLBHI_REGNUM,
  1653. + MICROBLAZE_SLR_REGNUM,
  1654. + MICROBLAZE_SHR_REGNUM
  1655. };
  1656. /* All registers are 32 bits. */
  1657. @@ -115,6 +132,21 @@
  1658. /* MICROBLAZE_BREAKPOINT defines the breakpoint that should be used.
  1659. Only used for native debugging. */
  1660. -#define MICROBLAZE_BREAKPOINT {0xb9, 0xcc, 0x00, 0x60}
  1661. +#define MICROBLAZE_BREAKPOINT {0xba, 0x0c, 0x00, 0x18}
  1662. +#define MICROBLAZE_BREAKPOINT_LE {0x18, 0x00, 0x0c, 0xba}
  1663. +
  1664. +extern void microblaze_supply_gregset (const struct microblaze_gregset *gregset,
  1665. + struct regcache *regcache,
  1666. + int regnum, const void *gregs);
  1667. +extern void microblaze_collect_gregset (const struct microblaze_gregset *gregset,
  1668. + const struct regcache *regcache,
  1669. + int regnum, void *gregs);
  1670. +extern void microblaze_supply_fpregset (struct regcache *regcache,
  1671. + int regnum, const void *fpregs);
  1672. +extern void microblaze_collect_fpregset (const struct regcache *regcache,
  1673. + int regnum, void *fpregs);
  1674. +
  1675. +extern const struct regset * microblaze_regset_from_core_section (struct gdbarch *gdbarch,
  1676. + const char *sect_name, size_t sect_size);
  1677. #endif /* microblaze-tdep.h */
  1678. diff -Nur gdb-7.8.2.orig/gdb/regformats/reg-microblaze.dat gdb-7.8.2/gdb/regformats/reg-microblaze.dat
  1679. --- gdb-7.8.2.orig/gdb/regformats/reg-microblaze.dat 1970-01-01 01:00:00.000000000 +0100
  1680. +++ gdb-7.8.2/gdb/regformats/reg-microblaze.dat 2016-05-14 21:29:38.997383530 +0200
  1681. @@ -0,0 +1,41 @@
  1682. +name:microblaze
  1683. +expedite:r1,pc
  1684. +32:r0
  1685. +32:r1
  1686. +32:r2
  1687. +32:r3
  1688. +32:r4
  1689. +32:r5
  1690. +32:r6
  1691. +32:r7
  1692. +32:r8
  1693. +32:r9
  1694. +32:r10
  1695. +32:r11
  1696. +32:r12
  1697. +32:r13
  1698. +32:r14
  1699. +32:r15
  1700. +32:r16
  1701. +32:r17
  1702. +32:r18
  1703. +32:r19
  1704. +32:r20
  1705. +32:r21
  1706. +32:r22
  1707. +32:r23
  1708. +32:r24
  1709. +32:r25
  1710. +32:r26
  1711. +32:r27
  1712. +32:r28
  1713. +32:r29
  1714. +32:r30
  1715. +32:r31
  1716. +32:pc
  1717. +32:msr
  1718. +32:ear
  1719. +32:esr
  1720. +32:fsr
  1721. +32:slr
  1722. +32:shr
  1723. diff -Nur gdb-7.8.2.orig/include/elf/microblaze.h gdb-7.8.2/include/elf/microblaze.h
  1724. --- gdb-7.8.2.orig/include/elf/microblaze.h 2015-01-15 11:58:12.000000000 +0100
  1725. +++ gdb-7.8.2/include/elf/microblaze.h 2016-05-14 21:29:38.997383530 +0200
  1726. @@ -58,6 +58,7 @@
  1727. RELOC_NUMBER (R_MICROBLAZE_TLSDTPREL64, 27) /* TLS Offset Within TLS Block */
  1728. RELOC_NUMBER (R_MICROBLAZE_TLSGOTTPREL32, 28) /* TLS Offset From Thread Pointer */
  1729. RELOC_NUMBER (R_MICROBLAZE_TLSTPREL32, 29) /* TLS Offset From Thread Pointer */
  1730. + RELOC_NUMBER (R_MICROBLAZE_32_NONE, 30)
  1731. END_RELOC_NUMBERS (R_MICROBLAZE_max)
  1732. diff -Nur gdb-7.8.2.orig/opcodes/microblaze-opc.h gdb-7.8.2/opcodes/microblaze-opc.h
  1733. --- gdb-7.8.2.orig/opcodes/microblaze-opc.h 2015-01-15 11:58:12.000000000 +0100
  1734. +++ gdb-7.8.2/opcodes/microblaze-opc.h 2016-05-14 21:29:38.997383530 +0200
  1735. @@ -91,6 +91,7 @@
  1736. #define OPCODE_MASK_H3 0xFC000600 /* High 6 bits and bits 21, 22. */
  1737. #define OPCODE_MASK_H32 0xFC00FC00 /* High 6 bits and bit 16-21. */
  1738. #define OPCODE_MASK_H34B 0xFC0000FF /* High 6 bits and low 8 bits. */
  1739. +#define OPCODE_MASK_H35B 0xFC0004FF /* High 6 bits and low 9 bits. */
  1740. #define OPCODE_MASK_H34C 0xFC0007E0 /* High 6 bits and bits 21-26. */
  1741. /* New Mask for msrset, msrclr insns. */
  1742. @@ -101,7 +102,7 @@
  1743. #define DELAY_SLOT 1
  1744. #define NO_DELAY_SLOT 0
  1745. -#define MAX_OPCODES 289
  1746. +#define MAX_OPCODES 291
  1747. struct op_code_struct
  1748. {
  1749. @@ -174,7 +175,9 @@
  1750. {"wic", INST_TYPE_R1_R2_SPECIAL, INST_NO_OFFSET, NO_DELAY_SLOT, IMMVAL_MASK_NON_SPECIAL, 0x90000068, OPCODE_MASK_H34B, wic, special_inst },
  1751. {"wdc", INST_TYPE_R1_R2_SPECIAL, INST_NO_OFFSET, NO_DELAY_SLOT, IMMVAL_MASK_NON_SPECIAL, 0x90000064, OPCODE_MASK_H34B, wdc, special_inst },
  1752. {"wdc.clear", INST_TYPE_R1_R2_SPECIAL, INST_NO_OFFSET, NO_DELAY_SLOT, IMMVAL_MASK_NON_SPECIAL, 0x90000066, OPCODE_MASK_H34B, wdcclear, special_inst },
  1753. + {"wdc.ext.clear", INST_TYPE_R1_R2_SPECIAL, INST_NO_OFFSET, NO_DELAY_SLOT, IMMVAL_MASK_NON_SPECIAL, 0x90000466, OPCODE_MASK_H35B, wdcextclear, special_inst },
  1754. {"wdc.flush", INST_TYPE_R1_R2_SPECIAL, INST_NO_OFFSET, NO_DELAY_SLOT, IMMVAL_MASK_NON_SPECIAL, 0x90000074, OPCODE_MASK_H34B, wdcflush, special_inst },
  1755. + {"wdc.ext.flush", INST_TYPE_R1_R2_SPECIAL, INST_NO_OFFSET, NO_DELAY_SLOT, IMMVAL_MASK_NON_SPECIAL, 0x90000476, OPCODE_MASK_H35B, wdcextflush, special_inst },
  1756. {"mts", INST_TYPE_SPECIAL_R1, INST_NO_OFFSET, NO_DELAY_SLOT, IMMVAL_MASK_MTS, 0x9400C000, OPCODE_MASK_H13S, mts, special_inst },
  1757. {"mfs", INST_TYPE_RD_SPECIAL, INST_NO_OFFSET, NO_DELAY_SLOT, IMMVAL_MASK_MFS, 0x94008000, OPCODE_MASK_H23S, mfs, special_inst },
  1758. {"br", INST_TYPE_R2, INST_PC_OFFSET, NO_DELAY_SLOT, IMMVAL_MASK_NON_SPECIAL, 0x98000000, OPCODE_MASK_H124, br, branch_inst },
  1759. diff -Nur gdb-7.8.2.orig/opcodes/microblaze-opcm.h gdb-7.8.2/opcodes/microblaze-opcm.h
  1760. --- gdb-7.8.2.orig/opcodes/microblaze-opcm.h 2015-01-15 11:58:12.000000000 +0100
  1761. +++ gdb-7.8.2/opcodes/microblaze-opcm.h 2016-05-14 21:29:38.997383530 +0200
  1762. @@ -31,9 +31,9 @@
  1763. idiv, idivu, bsll, bsra, bsrl, get, put, nget, nput, cget, cput,
  1764. ncget, ncput, muli, bslli, bsrai, bsrli, mului, or, and, xor,
  1765. andn, pcmpbf, pcmpbc, pcmpeq, pcmpne, sra, src, srl, sext8, sext16,
  1766. - wic, wdc, wdcclear, wdcflush, mts, mfs, mbar, br, brd,
  1767. - brld, bra, brad, brald, microblaze_brk, beq, beqd, bne, bned, blt,
  1768. - bltd, ble, bled, bgt, bgtd, bge, bged, ori, andi, xori, andni,
  1769. + wic, wdc, wdcclear, wdcextclear, wdcflush, wdcextflush, mts, mfs, mbar,
  1770. + br, brd, brld, bra, brad, brald, microblaze_brk, beq, beqd, bne, bned,
  1771. + blt, bltd, ble, bled, bgt, bgtd, bge, bged, ori, andi, xori, andni,
  1772. imm, rtsd, rtid, rtbd, rted, bri, brid, brlid, brai, braid, bralid,
  1773. brki, beqi, beqid, bnei, bneid, blti, bltid, blei, bleid, bgti,
  1774. bgtid, bgei, bgeid, lbu, lbur, lhu, lhur, lw, lwr, lwx, sb, sbr, sh,