home *** CD-ROM | disk | FTP | other *** search
/ Source Code 1992 March / Source_Code_CD-ROM_Walnut_Creek_March_1992.iso / usenet / altsrcs / 1 / 1288 / gdb-x386.02
Encoding:
Text File  |  1990-12-28  |  47.3 KB  |  1,764 lines

  1. *** dist-gdb.old/x386dbx.c    Thu Jan  1 00:00:00 1970
  2. --- x386dbx.c    Sat May  5 14:59:45 1990
  3. ***************
  4. *** 0 ****
  5. --- 1,478 ----
  6. + #include <stdio.h>
  7. + #include <a.out.h>
  8. + #include <fcntl.h>
  9. + #include <sys/types.h>
  10. + #include <sys/relsym.h>
  11. + #include <sys/param.h>
  12. + #include <sys/file.h>
  13. + #include "defs.h"
  14. + #include "param.h"
  15. + #include "symtab.h"
  16. + #include "gas-nlist.h"
  17. + /* XENIX symbol segment shape definitions */
  18. + struct section2 {            /* File info table shape */
  19. +     short        segment;    /* segment number */
  20. +     CORE_ADDR    address;    /* start address for this file */
  21. +     unsigned short    textsize;    /* size of the text for this file */
  22. +     long        type3off;    /* offset to type3 records, psym tab */
  23. +     long        type4off;    /* offset to type4 records, nlist tab */
  24. +     long        type5off;    /* offset to type5 records, str tab */
  25. +     long        type6off;    /* offset to type6 records */
  26. +     unsigned short    type3sz;    /* size of type3 records */
  27. +     unsigned short    type4sz;    /* size of type4 records */
  28. +     unsigned short    type5sz;    /* size of type5 records */
  29. +     unsigned short    type6sz;    /* size of type6 records */
  30. +     char        filelen;    /* length of filename */
  31. + };
  32. + /* psymtable (attribute 3) symbol segment shape */
  33. + struct psymbol_seg {
  34. +     long        address;    /* core address */
  35. +     short        segid;        /* segment number */
  36. +     short        typeid;        /* variable's type */
  37. +     char        varlen;        /* variable's length */
  38. + /*    char        name[0];    trailing name varlen long */
  39. + } record3;
  40. + /*  Info maintenance structures */
  41. + struct fileinfo {        /* per file info */
  42. +     CORE_ADDR    address;    /* start address for this file */
  43. +     unsigned short    textsize;    /* size of text for this file */
  44. +     long        psymoff;    /* psyms table */
  45. +     long        strtaboff;    /* string table aka $$TYPES */
  46. +     long        ntaboff;    /* nlist table aka $$SYMBOLS */
  47. +     unsigned short    psymsz;        /* size of psyms table */
  48. +     unsigned short    strtabsz;    /* size of string table */
  49. +     unsigned short    ntabsz;        /* size of nlist table */
  50. +     int        mscdebuginfo;    /* compiled with cc -g not gcc -g */
  51. +     char        *filename;    /* name of this file */
  52. +     struct fileinfo *next;
  53. + };
  54. + static struct fileinfo *fi_table = 0;
  55. + struct xseg *seg_table;
  56. + long num_seg_table_entries;
  57. + #ifdef __GNUC__
  58. + #define alloca __builtin_alloca
  59. + #endif
  60. + #define IGNORE_ATTR (-1)
  61. + static read_fileinfo_table(fp, segsize, name)
  62. + FILE *fp;
  63. + int segsize;
  64. + char *name;
  65. + {
  66. +   extern char *strrchr(), *xmalloc();
  67. +   char *fi_name;
  68. +   char *filename;
  69. +   struct section2 fi_entry;
  70. +   struct fileinfo *fi;
  71. +   fi_table = fi = (struct fileinfo *)xmalloc(sizeof(struct fileinfo));
  72. +   while (segsize > 0)
  73. +   {
  74. +     if ((fread((char *)&fi_entry.segment, sizeof(short), 1, fp) != 1)
  75. +       || (fread((char *)&fi_entry.address, sizeof(CORE_ADDR), 1, fp) != 1)
  76. +       || (fread((char *)&fi_entry.textsize, sizeof(unsigned short),1,fp) != 1)
  77. +       || (fread((char *)&fi_entry.type3off, sizeof(long), 1, fp) != 1)
  78. +       || (fread((char *)&fi_entry.type4off, sizeof(long), 1, fp) != 1)
  79. +       || (fread((char *)&fi_entry.type5off, sizeof(long), 1, fp) != 1)
  80. +       || (fread((char *)&fi_entry.type6off, sizeof(long), 1, fp) != 1)
  81. +       || (fread((char *)&fi_entry.type3sz, sizeof(unsigned short),1,fp) != 1)
  82. +       || (fread((char *)&fi_entry.type4sz, sizeof(unsigned short),1,fp) != 1)
  83. +       || (fread((char *)&fi_entry.type5sz, sizeof(unsigned short),1,fp) != 1)
  84. +       || (fread((char *)&fi_entry.type6sz, sizeof(unsigned short),1,fp) != 1)
  85. +       || (fread((char *)&fi_entry.filelen, sizeof(char), 1, fp) != 1))
  86. +       perror_with_name(name);
  87. +     segsize -= sizeof(short) + sizeof(CORE_ADDR) + 5 * sizeof(unsigned short)
  88. +            + 4 * sizeof(long) + sizeof(char);
  89. +     fi_name = alloca(fi_entry.filelen + 1);
  90. +     if (fread(fi_name, fi_entry.filelen, 1, fp) != 1)
  91. +       perror_with_name(name);
  92. +     fi_name[fi_entry.filelen] = '\0';
  93. +     segsize -= fi_entry.filelen;
  94. +     if ((filename = strrchr(fi_name, '/')) != (char *)0)
  95. +       fi_name = filename + 1;
  96. +     if ((filename = strrchr(fi_name, '(')) != (char *)0)
  97. +       fi_name = filename + 1;
  98. +     if ((filename = strrchr(fi_name, ')')) != (char *)0)
  99. +         *filename = '\0';
  100. +    
  101. +     {
  102. +       int len = strlen(fi_name);
  103. +       if (len > 2 && fi_name[len - 1] == 'o' && fi_name[len - 2] == '.')
  104. +       fi_name[len - 1] = 'c';
  105. +     }
  106. +     fi_name = savestring(fi_name, strlen(fi_name) + 1);
  107. +     fi->next = (struct fileinfo *)xmalloc(sizeof(struct fileinfo));
  108. +     fi = fi->next;
  109. +     fi->address = fi_entry.address;
  110. +     fi->textsize = fi_entry.textsize;
  111. +     fi->psymoff = fi_entry.type3off;
  112. +     fi->psymsz = fi_entry.type3sz;
  113. +     fi->strtaboff = fi_entry.type4off;
  114. +     fi->strtabsz = fi_entry.type4sz;
  115. +     fi->ntaboff = fi_entry.type5off;
  116. +     fi->ntabsz = fi_entry.type5sz;
  117. +     fi->mscdebuginfo = (fi_entry.type6sz != 0);
  118. +     fi->filename = fi_name;
  119. +   }
  120. +   fi->next = 0;  fi = fi_table;  fi_table = fi_table->next;  free(fi);
  121. + #ifdef X_DEBUG
  122. +     printf("\naddress   textsz  symoff   symsz  stroff   strsz  taboff   tabsz  name\n\n");
  123. +   for (fi = fi_table; fi != 0; fi = fi->next)
  124. +   {
  125. +     printf("% 8x  % 6d  % 6d  % 6d  % 6d  % 6d  % 6d  %6d  %s\n", fi->address, fi->textsize, fi->psymoff, fi->psymsz, fi->strtaboff, fi->strtabsz, fi->ntaboff, fi->ntabsz, fi->filename);
  126. +   }
  127. +   printf("\n");
  128. + #endif /* X_DEBUG */
  129. + }
  130. + static read_seg_table(fp, pos, size, name)
  131. + FILE *fp;
  132. + long pos, size;
  133. + {
  134. +   seg_table = (struct xseg *) xmalloc(size);
  135. +   fseek(fp, pos, 0);
  136. +   if (fread((char *)seg_table, size, 1, fp) != 1)
  137. +     perror_with_name(name);
  138. +   num_seg_table_entries = size / sizeof (struct xseg);
  139. + }
  140. + struct xseg *find_segment(type, attr)
  141. + int type, attr;
  142. + {
  143. +   struct xseg *cseg;
  144. +   for (cseg = seg_table; cseg < seg_table + num_seg_table_entries; ++cseg)
  145. +   if (cseg->xs_type == type &&
  146. +     (attr == IGNORE_ATTR || attr == cseg->xs_attr))
  147. +     return cseg;
  148. +   return NULL;
  149. + }
  150. + static int compare_misc_functions (fn1, fn2)
  151. + struct misc_function *fn1, *fn2;
  152. + {
  153. +   /* Return a signed result based on unsigned comparisons
  154. +      so that we sort into unsigned numeric order.  */
  155. +   if (fn1->address < fn2->address)
  156. +     return -1;
  157. +   if (fn1->address > fn2->address)
  158. +     return 1;
  159. +   return 0;
  160. + }
  161. + static int read_misc_functions(fp, segsize, name)
  162. + FILE *fp;
  163. + int segsize;
  164. + char *name;
  165. + {
  166. +   char *symdata, *p, *str_buff;
  167. +   long sym_count = 0, str_count = 0, i;
  168. +   struct misc_function *miscp;
  169. +   struct sym symb;
  170. +   /* grab the symbol table */
  171. +   symdata = alloca(segsize + 1);
  172. +   if (fread(symdata, segsize, 1, fp) != 1)
  173. +       perror_with_name(name);
  174. +   /* first pass, work out how many symbols there are and the size of the
  175. +    * strings
  176. +    */
  177. +   p = symdata;
  178. +   while (p < symdata + segsize)
  179. +   {
  180. +     int len;
  181. +     p += sizeof(struct sym);
  182. +     len = strlen(p) + 1;
  183. +     str_count += len;  p += len;  sym_count++;
  184. +   }
  185. +   /* Now build the misc function vector */
  186. +   str_buff = xmalloc(str_count+1);
  187. +   misc_function_vector =
  188. +     (struct misc_function *) xmalloc (sym_count * sizeof(struct misc_function));
  189. +   misc_function_count = sym_count;
  190. +   p = symdata;  miscp = misc_function_vector;
  191. +   while (p < symdata + segsize)
  192. +   {
  193. +     int len;
  194. +     symb = *((struct sym *)p);
  195. +     p += sizeof(struct sym);
  196. +     if (*p == '_')
  197. +       strcpy(str_buff, p+1);
  198. +     else
  199. +       strcpy(str_buff, p);
  200. +     /* the following will result in a garbage byte every time a symbol
  201. +      * starts with a _, I can'y be bothered to fix it.
  202. +      */
  203. +     miscp->name = str_buff;
  204. +     len = strlen(p) + 1;
  205. +     str_buff += len;  p += len;
  206. +     miscp->address = symb.s_value;
  207. +     switch(symb.s_type & S_TYPE)
  208. +     {
  209. +     case S_UNDEF:  miscp->type = mf_unknown;  break;
  210. +     case S_ABS:    miscp->type = mf_abs;  break;
  211. +     case S_TEXT:   miscp->type = mf_text;  break;
  212. +     case S_DATA:   miscp->type = mf_data;  break;
  213. +     case S_BSS:    miscp->type = mf_bss;  break;
  214. +     case S_COMM:   miscp->type = mf_data;  break;
  215. +     case S_REG:    miscp->type = mf_unknown;  break;
  216. +     case S_COMB:   miscp->type = mf_unknown;  break;
  217. +     case S_SEG:    miscp->type = mf_unknown;  break;
  218. +     case S_FN:     miscp->type = mf_unknown;  break;
  219. +     dewfault:      miscp->type = mf_unknown;  break;
  220. +     }
  221. +     miscp++;
  222. +   }
  223. +   qsort (misc_function_vector, misc_function_count,
  224. +     sizeof (struct misc_function), compare_misc_functions);
  225. + #ifdef X_DEBUG
  226. +   {
  227. +     struct misc_function *miscp;
  228. +     int i;
  229. +     printf("type      address  name\n\n");
  230. +     for (i = 0; i < misc_function_count; i++)
  231. +     {
  232. +       miscp = &misc_function_vector[i];
  233. +       switch (miscp->type)
  234. +       {
  235. +       case mf_unknown: printf("%-9s","unknown");  break;
  236. +       case mf_text:    printf("%-9s","text");  break;
  237. +       case mf_data:    printf("%-9s","data");  break;
  238. +       case mf_bss:     printf("%-9s","bss");  break;
  239. +       case mf_abs:     printf("%-9s","abs");  break;
  240. +       default:         printf("%-9s","UNKNOWN");  break;
  241. +       }
  242. +       printf("% 8x  ", miscp->address);
  243. +       printf("%s\n", miscp->name);
  244. +     }
  245. +   }
  246. + #endif /* X_DEBUG */
  247. +   return misc_function_count;
  248. + }
  249. + process_a_out(desc, name)
  250. + int desc;
  251. + char *name;
  252. + {
  253. +   struct xexec exec_aouthdr;
  254. +   struct xext *xext;
  255. +   struct xseg *cseg;
  256. +   FILE *fp;
  257. +   lseek(desc, 0L, 0);
  258. +   if ((fp = fdopen(dup(desc), "r")) == NULL)
  259. +         perror_with_name(name);
  260. +   if (fread((char *)&exec_aouthdr, sizeof(struct xexec), 1, fp) != 1)
  261. +     perror_with_name(name);
  262. +   
  263. +   xext = (struct xext *) alloca(exec_aouthdr.x_ext);
  264. +   if (fread((char *)xext, exec_aouthdr.x_ext, 1, fp) != 1)
  265. +     perror_with_name(name);
  266. +   
  267. +   read_seg_table(fp, xext->xe_segpos, xext->xe_segsize, name);
  268. +   if (cseg = find_segment(XS_TSYMS, 2))
  269. +   {
  270. +     fseek(fp, cseg->xs_filpos, 0);
  271. +     read_fileinfo_table(fp, cseg->xs_psize, name);
  272. +   }
  273. +   fclose(fp);
  274. + }
  275. + process_global_symbol_table(desc, name)
  276. + int desc;
  277. + char *name;
  278. + {
  279. +   struct xseg *cseg;
  280. +   FILE *fp;
  281. +   if ((fp = fdopen(dup(desc), "r")) == NULL)
  282. +         perror_with_name(name);
  283. +   if (cseg = find_segment(XS_TSYMS, 1))
  284. +   {
  285. +     fseek(fp, cseg->xs_filpos, 0);
  286. +     read_misc_functions(fp, cseg->xs_psize, name);
  287. +   }
  288. +   fclose(fp);
  289. + }
  290. + static struct fileinfo *current_fi;
  291. + static int first_get_fileinfo_call = 1;
  292. + init_fileinfo_processing()  /* start processing the list of files */
  293. + {
  294. +   first_get_fileinfo_call = 1;
  295. + }
  296. + long get_next_fileinfo(stroff, nsyms, address, symtaboff)
  297. + long *stroff, *nsyms, *address, *symtaboff;
  298. + {
  299. +   struct xseg *cseg;
  300. +   if (first_get_fileinfo_call)
  301. +   {
  302. +     current_fi = fi_table;
  303. +     first_get_fileinfo_call = 0;
  304. +   }
  305. +   else
  306. +     current_fi = current_fi->next;
  307. +   
  308. +   if (current_fi == 0)
  309. +     return 0;
  310. +   if (current_fi->mscdebuginfo)
  311. +   {
  312. +     *stroff = 0;
  313. +     *nsyms = 0;
  314. +     *address = current_fi->address;
  315. +   }
  316. +   else if (cseg = find_segment(XS_TSYMS, 5))
  317. +   {
  318. +     *symtaboff = cseg->xs_filpos + current_fi->ntaboff;
  319. +     *stroff = current_fi->strtaboff;
  320. +     *nsyms = current_fi->ntabsz / sizeof(struct gas_nlist);
  321. +     *address = current_fi->address;
  322. +     return 1;
  323. +   }
  324. +   else
  325. +   {
  326. +     *symtaboff = 0;
  327. +     *stroff = 0;
  328. +     *nsyms = 0;
  329. +     *address = 0;
  330. +   }
  331. + }
  332. + #ifdef TEST
  333. + main()
  334. + {
  335. +     char *stab;
  336. +     long str_offset, nsyms, address, ntaboff;
  337. +      int desc;
  338. +     struct xseg *cseg;
  339. +     process_a_out((desc = open("a.out", O_RDONLY, 0)), "a.out");
  340. +     printf("\n");
  341. +            if (cseg = find_segment(XS_TSYMS, 4))
  342. +            {
  343. +         lseek(desc, cseg->xs_filpos, 0);
  344. +         stab = alloca(cseg->xs_psize);
  345. +         read(desc, stab, cseg->xs_psize);
  346. +       }
  347. +       else
  348. +         stab = 0;
  349. +           init_fileinfo_processing();
  350. +       while (get_next_fileinfo(&str_offset,&nsyms,&address,&ntaboff))
  351. +       {
  352. +         lseek(desc, ntaboff, 0);
  353. +         printf("\n  type    desc     value  stroff  string (%#x)\n", address);
  354. +         while (nsyms--)
  355. +         {
  356. +           struct gas_nlist nl;
  357. +           read(desc, &nl, sizeof(nl));
  358. +           printf("% 6x  % 6x  % 8x  % 6x %s\n",
  359. +              (unsigned char)nl.n_type,
  360. +              (unsigned short)nl.n_desc,
  361. +              (unsigned int)nl.n_value,
  362. +              nl.n_un.n_strx ? stab + str_offset + nl.n_un.n_strx : "");
  363. +         }
  364. +         lseek(desc, 0L, 0);
  365. +       }
  366. + }
  367. + perror_with_name (string)
  368. +      char *string;
  369. + {
  370. +   extern int sys_nerr;
  371. +   extern char *sys_errlist[];
  372. +   extern int errno;
  373. +   char *err;
  374. +   char *combined;
  375. +   if (errno < sys_nerr)
  376. +     err = sys_errlist[errno];
  377. +   else
  378. +     err = "unknown error";
  379. +   combined = (char *) alloca (strlen (err) + strlen (string) + 3);
  380. +   strcpy (combined, string);
  381. +   strcat (combined, ": ");
  382. +   strcat (combined, err);
  383. +   error ("%s.", combined);
  384. + }
  385. + error (string, arg1, arg2, arg3)
  386. +      char *string;
  387. +      int arg1, arg2, arg3;
  388. + {
  389. +   fflush (stdout);
  390. +   fprintf (stderr, string, arg1, arg2, arg3);
  391. +   fprintf (stderr, "\n");
  392. +   exit(1);
  393. + }
  394. + char * xmalloc (size)
  395. +      long size;
  396. + {
  397. +   register char *val = (char *) malloc (size);
  398. +   if (!val)
  399. +     error ("virtual memory exhausted.");
  400. +   return val;
  401. + }
  402. + char *savestring (ptr, size)
  403. +      char *ptr;
  404. +      int size;
  405. + {
  406. +   register char *p = (char *) xmalloc (size + 1);
  407. +   memcpy(p, ptr, size);
  408. +   p[size] = 0;
  409. +   return p;
  410. + }
  411. + #endif /* TEST */
  412. *** dist-gdb.old/xenix386-dep.c    Thu Jan  1 00:00:00 1970
  413. --- xenix386-dep.c    Mon May  7 15:02:10 1990
  414. ***************
  415. *** 0 ****
  416. --- 1,1275 ----
  417. + /* Low level interface to ptrace, for GDB when running on the Intel 386.
  418. +    Copyright (C) 1988, 1989 Free Software Foundation, Inc.
  419. + This file is part of GDB.
  420. + GDB is free software; you can redistribute it and/or modify
  421. + it under the terms of the GNU General Public License as published by
  422. + the Free Software Foundation; either version 1, or (at your option)
  423. + any later version.
  424. + GDB is distributed in the hope that it will be useful,
  425. + but WITHOUT ANY WARRANTY; without even the implied warranty of
  426. + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
  427. + GNU General Public License for more details.
  428. + You should have received a copy of the GNU General Public License
  429. + along with GDB; see the file COPYING.  If not, write to
  430. + the Free Software Foundation, 675 Mass Ave, Cambridge, MA 02139, USA.  */
  431. + #include <stdio.h>
  432. + #include "defs.h"
  433. + #include "param.h"
  434. + #include "frame.h"
  435. + #include "inferior.h"
  436. + #ifdef USG
  437. + #include <sys/types.h>
  438. + #endif
  439. + #include <stdio.h>
  440. + #include <sys/param.h>
  441. + #include <sys/dir.h>
  442. + #include <signal.h>
  443. + #ifdef M_XENIX
  444. + #include <sys/page.h>
  445. + #include <sys/seg.h>
  446. + #endif
  447. + #include <sys/user.h>
  448. + #include <sys/ioctl.h>
  449. + #include <fcntl.h>
  450. + #ifdef COFF_ENCAPSULATE
  451. + #include "a.out.encap.h"
  452. + #else
  453. + #ifndef M_XENIX            /* brain-dead xenix strikes again */
  454. + #include <a.out.h>
  455. + #endif
  456. + #endif
  457. + #ifndef N_SET_MAGIC
  458. + #ifdef COFF_FORMAT
  459. + #define N_SET_MAGIC(exec, val) ((exec).magic = (val))
  460. + #else
  461. + #define N_SET_MAGIC(aexec, val) ((aexec).xa_magic = (val))
  462. + #endif
  463. + #endif
  464. + #include <sys/file.h>
  465. + #include <sys/stat.h>
  466. + #include <sys/proc.h>
  467. + #include <sys/reg.h>
  468. + unsigned short text_segid;    /* segment number of text segment */
  469. + unsigned short data_segid;    /* segment number of data segment */
  470. + extern CORE_ADDR text_end; \
  471. + #ifdef X_DEBUG
  472. + Ptrace(l, a, b, c, d)
  473. + int l;
  474. + int a, b, c, d;
  475. + {
  476. +     printf("at line %d, req = %d, pid = %d, addr = %#x, data = %d\n",
  477. +            l, a, b, c, d);
  478. +         return ptrace (a, b, c, d);
  479. + }
  480. + #define ptrace(a,b,c,d) Ptrace(__LINE__, a, b, c, d)
  481. + #endif /* X_DEBUG */
  482. + typedef struct saddr PTRACE;
  483. + static PTRACE tmptrace;
  484. + extern int errno;
  485. + /* This function simply calls ptrace with the given arguments.  
  486. +    It exists so that all calls to ptrace are isolated in this 
  487. +    machine-dependent file. */
  488. + int
  489. + call_ptrace (request, pid, arg3, arg4)
  490. +      int request, pid, arg3, arg4;
  491. + {
  492. +   return ptrace (request, pid, arg3, arg4);
  493. + }
  494. + kill_inferior ()
  495. + {
  496. +   if (remote_debugging)
  497. +     return;
  498. +   if (inferior_pid == 0)
  499. +     return;
  500. +   ptrace (8, inferior_pid, 0, 0);
  501. +   wait (0);
  502. +   inferior_died ();
  503. + }
  504. + /* This is used when GDB is exiting.  It gives less chance of error.*/
  505. + kill_inferior_fast ()
  506. + {
  507. +   if (remote_debugging)
  508. +     return;
  509. +   if (inferior_pid == 0)
  510. +     return;
  511. +   ptrace (8, inferior_pid, 0, 0);
  512. +   wait (0);
  513. + }
  514. + /* Resume execution of the inferior process.
  515. +    If STEP is nonzero, single-step it.
  516. +    If SIGNAL is nonzero, give it that signal.  */
  517. + void
  518. + resume (step, signal)
  519. +      int step;
  520. +      int signal;
  521. + {
  522. +   PTRACE addr;
  523. +   addr.sa_seg = 0;
  524. +   addr.sa_off = 1;
  525. +   errno = 0;
  526. +   if (remote_debugging)
  527. +     remote_resume (step, signal);
  528. +   else
  529. +     {
  530. +       /* ptrace (step ? 9 : 7, inferior_pid, &addr, signal); */
  531. +       ptrace (step ? 9 : 7, inferior_pid, 1, signal);
  532. +       if (errno)
  533. +     perror_with_name ("ptrace");
  534. +     }
  535. + }
  536. + void
  537. + fetch_inferior_registers ()
  538. + {
  539. +   register int regno;
  540. +   register unsigned int regaddr;
  541. +   char buf[MAX_REGISTER_RAW_SIZE];
  542. +   register int i;
  543. +   struct user u;
  544. +   unsigned int offset = (char *) &u.u_ar0 - (char *) &u;
  545. +   offset = ptrace (3, inferior_pid, offset, 0) - KERNEL_U_ADDR;
  546. +   for (regno = 0; regno < NUM_REGS; regno++)
  547. +     {
  548. +       regaddr = register_addr (regno, offset);
  549. +       for (i = 0; i < REGISTER_RAW_SIZE (regno); i += sizeof (int))
  550. +      {
  551. +        *(int *) &buf[i] = ptrace (3, inferior_pid, regaddr, 0);
  552. +        regaddr += sizeof (int);
  553. +      }
  554. +       supply_register (regno, buf);
  555. +     }
  556. + }
  557. + /* Store our register values back into the inferior.
  558. +    If REGNO is -1, do this for all registers.
  559. +    Otherwise, REGNO specifies which register (so we can save time).  */
  560. + store_inferior_registers (regno)
  561. +      int regno;
  562. + {
  563. +   register unsigned int regaddr;
  564. +   char buf[80];
  565. +   struct user u;
  566. +   unsigned int offset = (char *) &u.u_ar0 - (char *) &u;
  567. +   offset = ptrace (3, inferior_pid, offset, 0) - KERNEL_U_ADDR;
  568. +   if (regno >= 0)
  569. +     {
  570. +       regaddr = register_addr (regno, offset);
  571. +       errno = 0;
  572. +       ptrace (6, inferior_pid, regaddr, read_register (regno));
  573. +       if (errno != 0)
  574. +     {
  575. +       sprintf (buf, "writing register number %d", regno);
  576. +       perror_with_name (buf);
  577. +     }
  578. +     }
  579. +   else for (regno = 0; regno < NUM_REGS; regno++)
  580. +     {
  581. +       regaddr = register_addr (regno, offset);
  582. +       errno = 0;
  583. +       ptrace (6, inferior_pid, regaddr, read_register (regno));
  584. +       if (errno != 0)
  585. +     {
  586. +       sprintf (buf, "writing register number %d", regno);
  587. +       perror_with_name (buf);
  588. +     }
  589. +     }
  590. + }
  591. + /* Copy LEN bytes from inferior's memory starting at MEMADDR
  592. +    to debugger memory starting at MYADDR. 
  593. +    On failure (cannot read from inferior, usually because address is out
  594. +    of bounds) returns the value of errno. */
  595. + int
  596. + read_inferior_memory (memaddr, myaddr, len)
  597. +      CORE_ADDR memaddr;
  598. +      char *myaddr;
  599. +      int len;
  600. + {
  601. +   register int i;
  602. +   /* Round starting address down to longword boundary.  */
  603. +   register CORE_ADDR addr = memaddr & - sizeof (int);
  604. +   /* Round ending address up; get number of longwords that makes.  */
  605. +   register int count
  606. +     = (((memaddr + len) - addr) + sizeof (int) - 1) / sizeof (int);
  607. +   /* Allocate buffer of that many longwords.  */
  608. +   register int *buffer = (int *) alloca (count * sizeof (int));
  609. +   extern int errno;
  610. +   /* Read all the longwords */
  611. +   for (i = 0; i < count; i++, addr += sizeof (int))
  612. +     {
  613. +       errno = 0;
  614. +       if (remote_debugging)
  615. +     buffer[i] = remote_fetch_word (addr);
  616. +       else
  617. +     buffer[i] = ptrace (addr <= text_end ? 1 : 2, inferior_pid,
  618. +         addr, 0);
  619. +       if (errno)
  620. +     return errno;
  621. +     }
  622. +   /* Copy appropriate bytes out of the buffer.  */
  623. +   bcopy ((char *) buffer + (memaddr & (sizeof (int) - 1)), myaddr, len);
  624. +   return 0;
  625. + }
  626. + /* Copy LEN bytes of data from debugger memory at MYADDR
  627. +    to inferior's memory at MEMADDR.
  628. +    On failure (cannot write the inferior)
  629. +    returns the value of errno.  */
  630. + int
  631. + write_inferior_memory (memaddr, myaddr, len)
  632. +      CORE_ADDR memaddr;
  633. +      char *myaddr;
  634. +      int len;
  635. + {
  636. +   register int i;
  637. +   /* Round starting address down to longword boundary.  */
  638. +   register CORE_ADDR addr = memaddr & - sizeof (int);
  639. +   /* Round ending address up; get number of longwords that makes.  */
  640. +   register int count
  641. +     = (((memaddr + len) - addr) + sizeof (int) - 1) / sizeof (int);
  642. +   /* Allocate buffer of that many longwords.  */
  643. +   register int *buffer = (int *) alloca (count * sizeof (int));
  644. +   extern int errno;
  645. +   /* Fill start and end extra bytes of buffer with existing memory data.  */
  646. +   if (remote_debugging)
  647. +     buffer[0] = remote_fetch_word (addr);
  648. +   else
  649. +     buffer[0] = ptrace (addr <= text_end ? 1 : 2, inferior_pid, addr, 0);
  650. +   if (count > 1)
  651. +     {
  652. +       if (remote_debugging)
  653. +     buffer[count - 1]
  654. +       = remote_fetch_word (addr + (count - 1) * sizeof (int));
  655. +       else
  656. +     buffer[count - 1]
  657. +       = ptrace (addr <= text_end ? 1 : 2, inferior_pid,
  658. +                    (addr + (count - 1) * sizeof(int)) , 0);
  659. +     }
  660. +   /* Copy data to be written over corresponding part of buffer */
  661. +   bcopy (myaddr, (char *) buffer + (memaddr & (sizeof (int) - 1)), len);
  662. +   /* Write the entire buffer.  */
  663. +   for (i = 0; i < count; i++, addr += sizeof (int))
  664. +     {
  665. +       errno = 0;
  666. +       if (remote_debugging)
  667. +     remote_store_word (addr, buffer[i]);
  668. +       else
  669. +     ptrace (addr <= text_end ? 4 : 5, inferior_pid, addr, buffer[i]);
  670. +       if (errno)
  671. +     return errno;
  672. +     }
  673. +   return 0;
  674. + }
  675. + /* Work with core dump and executable files, for GDB. 
  676. +    This code would be in core.c if it weren't machine-dependent. */
  677. + #ifndef N_TXTADDR
  678. + #define N_TXTADDR(hdr) 0
  679. + #endif /* no N_TXTADDR */
  680. + #ifndef N_DATADDR
  681. + #define N_DATADDR(hdr) hdr.xa_text
  682. + #endif /* no N_DATADDR */
  683. + /* Make COFF and non-COFF names for things a little more compatible
  684. +    to reduce conditionals later.  */
  685. + #define AOUTHDR struct xexec
  686. + extern char *sys_siglist[];
  687. + /* Hook for `exec_file_command' command to call.  */
  688. + extern void (*exec_file_display_hook) ();
  689. +    
  690. + /* File names of core file and executable file.  */
  691. + extern char *corefile;
  692. + extern char *execfile;
  693. + /* Descriptors on which core file and executable file are open.
  694. +    Note that the execchan is closed when an inferior is created
  695. +    and reopened if the inferior dies or is killed.  */
  696. + extern int corechan;
  697. + extern int execchan;
  698. + /* Last modification time of executable file.
  699. +    Also used in source.c to compare against mtime of a source file.  */
  700. + extern int exec_mtime;
  701. + /* Virtual addresses of bounds of the two areas of memory in the core file.  */
  702. + extern CORE_ADDR data_start;
  703. + extern CORE_ADDR data_end;
  704. + extern CORE_ADDR stack_start;
  705. + extern CORE_ADDR stack_end;
  706. + /* Virtual addresses of bounds of two areas of memory in the exec file.
  707. +    Note that the data area in the exec file is used only when there is no core file.  */
  708. + extern CORE_ADDR text_start;
  709. + extern CORE_ADDR text_end;
  710. + extern CORE_ADDR exec_data_start;
  711. + extern CORE_ADDR exec_data_end;
  712. + /* Address in executable file of start of text area data.  */
  713. + extern int text_offset;
  714. + /* Address in executable file of start of data area data.  */
  715. + extern int exec_data_offset;
  716. + /* Address in core file of start of data area data.  */
  717. + extern int data_offset;
  718. + /* Address in core file of start of stack area data.  */
  719. + extern int stack_offset;
  720. + #ifdef COFF_FORMAT
  721. + /* various coff data structures */
  722. + extern FILHDR file_hdr;
  723. + extern SCNHDR text_hdr;
  724. + extern SCNHDR data_hdr;
  725. + #endif /* not COFF_FORMAT */
  726. + /* a.out header saved in core file.  */
  727. +   
  728. + extern AOUTHDR core_aouthdr;
  729. + /* a.out header of exec file.  */
  730. + extern AOUTHDR exec_aouthdr;
  731. + extern void validate_files ();
  732. + core_file_command (filename, from_tty)
  733. +      char *filename;
  734. +      int from_tty;
  735. + {
  736. +   int val;
  737. +   /* Discard all vestiges of any previous core file
  738. +      and mark data and stack spaces as empty.  */
  739. +   if (corefile)
  740. +     free (corefile);
  741. +   corefile = 0;
  742. +   if (corechan >= 0)
  743. +     close (corechan);
  744. +   corechan = -1;
  745. +   data_start = 0;
  746. +   data_end = 0;
  747. +   stack_start = 0;
  748. +   stack_end = 0;
  749. +   /* Now, if a new core file was specified, open it and digest it.  */
  750. +   if (filename)
  751. +     {
  752. +       filename = tilde_expand (filename);
  753. +       make_cleanup (free, filename);
  754. +       
  755. +       if (have_inferior_p ())
  756. +     error ("To look at a core file, you must kill the inferior with \"kill\".");
  757. +       corechan = open (filename, O_RDONLY, 0);
  758. +       if (corechan < 0)
  759. +     perror_with_name (filename);
  760. +       /* xenix style core dump */
  761. +       {
  762. +     struct user u;
  763. +     long user_area_size;
  764. +     int reg_offset;
  765. +     val = myread (corechan, &u, sizeof u);
  766. +     if (val < 0)
  767. +       perror_with_name (filename);
  768. +     user_area_size = ((sizeof u + (u.u_ldtlimit-1)*sizeof(struct descriptor)
  769. +              + NBPC - 1) / NBPC) * NBPC;
  770. +     data_start = (CORE_ADDR)u.u_sdata;
  771. +     data_end = (CORE_ADDR)u.u_edatau;
  772. +     stack_start = (CORE_ADDR)u.u_stktop;
  773. +     stack_end = (CORE_ADDR)u.u_stkbotu;
  774. +     data_offset = lseek(corechan, 0L, 2) - u.u_dsize;
  775. +     stack_offset = user_area_size;
  776. +     reg_offset = (int) u.u_ar0 - KERNEL_U_ADDR;
  777. + #ifdef X_DEBUG
  778. +     printf("data_offset = %#x\n", data_offset);
  779. +     printf("stack_offset  = %#x\n", stack_offset );
  780. +     printf("user_area_size = %#x\n", user_area_size);
  781. +     printf("test data_offset = %#x\n", user_area_size + u.u_ssize);
  782. + #endif /* X_DEBUG */
  783. +     /* I don't know where to find this info.
  784. +        So, for now, mark it as not available.  */
  785. + /*    N_SET_MAGIC (core_aouthdr, 0);  */
  786. +     bzero ((char *) &core_aouthdr, sizeof core_aouthdr);
  787. +     /* Read the register values out of the core file and store
  788. +        them where `read_register' will find them.  */
  789. +     {
  790. +       register int regno;
  791. +       for (regno = 0; regno < NUM_REGS; regno++)
  792. +         {
  793. +           char buf[MAX_REGISTER_RAW_SIZE];
  794. +           val = lseek (corechan, register_addr (regno, reg_offset), 0);
  795. +           if (val < 0)
  796. +         perror_with_name (filename);
  797. +            val = myread (corechan, buf, sizeof buf);
  798. +           if (val < 0)
  799. +         perror_with_name (filename);
  800. +           supply_register (regno, buf);
  801. +         }
  802. +     }
  803. +       }
  804. +       if (filename[0] == '/')
  805. +     corefile = savestring (filename, strlen (filename));
  806. +       else
  807. +     {
  808. +       corefile = concat (current_directory, "/", filename);
  809. +     }
  810. +       set_current_frame ( create_new_frame (read_register (FP_REGNUM),
  811. +                         read_pc ()));
  812. +       select_frame (get_current_frame (), 0);
  813. +       validate_files ();
  814. +     }
  815. +   else if (from_tty)
  816. +     printf ("No core file now.\n");
  817. + }
  818. + exec_file_command (filename, from_tty)
  819. +      char *filename;
  820. +      int from_tty;
  821. + {
  822. +   int val;
  823. +   /* Eliminate all traces of old exec file.
  824. +      Mark text segment as empty.  */
  825. +   if (execfile)
  826. +     free (execfile);
  827. +   execfile = 0;
  828. +   data_start = 0;
  829. +   data_end -= exec_data_start;
  830. +   text_start = 0;
  831. +   text_end = 0;
  832. +   exec_data_start = 0;
  833. +   exec_data_end = 0;
  834. +   if (execchan >= 0)
  835. +     close (execchan);
  836. +   execchan = -1;
  837. +   /* Now open and digest the file the user requested, if any.  */
  838. +   if (filename)
  839. +     {
  840. +       filename = tilde_expand (filename);
  841. +       make_cleanup (free, filename);
  842. +       
  843. +       execchan = openp (getenv ("PATH"), 1, filename, O_RDONLY, 0,
  844. +             &execfile);
  845. +       if (execchan < 0)
  846. +     perror_with_name (filename);
  847. +       {
  848. +     char *extended_header;
  849. +     struct xext *xext;
  850. +     struct stat st_exec;
  851. +     struct xseg xseg;
  852. +     extern char *malloc();
  853. +     val = myread (execchan, &exec_aouthdr, sizeof (AOUTHDR));
  854. +     if (val < 0)
  855. +       perror_with_name (filename);
  856. +         if (exec_aouthdr.x_magic != X_MAGIC)
  857. +       error ("\"%s\": not in executable format.", execfile);
  858. +     if ( (exec_aouthdr.x_cpu & XC_CPU) != XC_386 )
  859. +       error ("\"%s\": not a 386 executable.", execfile);
  860. +     if ( (exec_aouthdr.x_renv & XE_SEG) == 0)
  861. +       error ("\"%s\": not a segmented executable.", execfile);
  862. +     if ( (exec_aouthdr.x_renv & XE_EXEC) == 0)
  863. +       error ("\"%s\": not executable.", execfile);
  864. +     extended_header = malloc(exec_aouthdr.x_ext);
  865. +     val = myread (execchan, extended_header, exec_aouthdr.x_ext);
  866. +     if (val < 0)
  867. +       perror_with_name (filename);
  868. +     xext = (struct xext *)extended_header;
  869. +     lseek(execchan, xext->xe_segpos, 0);
  870. +     if (myread (execchan, (char *)&xseg, sizeof(xseg)) < 0)
  871. +       perror_with_name (filename);
  872. +     if ( xseg.xs_type != XS_TTEXT )
  873. +       error ("\"%s\": Text segment isn't first (huh?).", execfile);
  874. +     text_segid = xseg.xs_seg;
  875. +     text_start = xseg.xs_rbase;
  876. +     text_end = text_start + xseg.xs_vsize;
  877. +     text_offset = xseg.xs_filpos;
  878. +     if (myread (execchan, (char *)&xseg, sizeof(xseg)) < 0)
  879. +       perror_with_name (filename);
  880. +     if ( xseg.xs_type != XS_TDATA )
  881. +       error ("\"%s\": Data segment isn't second (huh?).", execfile);
  882. +     data_segid = xseg.xs_seg;
  883. +     exec_data_start = xseg.xs_rbase;
  884. +     exec_data_end = exec_data_start + xseg.xs_psize;
  885. +     exec_data_offset = xseg.xs_filpos;
  886. +     data_start = exec_data_start;
  887. +     data_end += exec_data_start;
  888. +     
  889. +     fstat (execchan, &st_exec);
  890. +     exec_mtime = st_exec.st_mtime;
  891. +     free(extended_header);
  892. +       }
  893. +       validate_files ();
  894. +     }
  895. +   else if (from_tty)
  896. +     printf ("No exec file now.\n");
  897. +   /* Tell display code (if any) about the changed file name.  */
  898. +   if (exec_file_display_hook)
  899. +     (*exec_file_display_hook) (filename);
  900. + }
  901. + /* helper functions for m-i386.h */
  902. + /* stdio style buffering to minimize calls to ptrace */
  903. + static CORE_ADDR codestream_next_addr;
  904. + static CORE_ADDR codestream_addr;
  905. + static unsigned char codestream_buf[sizeof (int)];
  906. + static int codestream_off;
  907. + static int codestream_cnt;
  908. + #define codestream_tell() (codestream_addr + codestream_off)
  909. + #define codestream_peek() (codestream_cnt == 0 ? \
  910. +                codestream_fill(1): codestream_buf[codestream_off])
  911. + #define codestream_get() (codestream_cnt-- == 0 ? \
  912. +              codestream_fill(0) : codestream_buf[codestream_off++])
  913. + static unsigned char 
  914. + codestream_fill (peek_flag)
  915. + {
  916. +   codestream_addr = codestream_next_addr;
  917. +   codestream_next_addr += sizeof (int);
  918. +   codestream_off = 0;
  919. +   codestream_cnt = sizeof (int);
  920. +   read_memory (codestream_addr,
  921. +            (unsigned char *)codestream_buf,
  922. +            sizeof (int));
  923. +   
  924. +   if (peek_flag)
  925. +     return (codestream_peek());
  926. +   else
  927. +     return (codestream_get());
  928. + }
  929. + static void
  930. + codestream_seek (place)
  931. + {
  932. +   codestream_next_addr = place & -sizeof (int);
  933. +   codestream_cnt = 0;
  934. +   codestream_fill (1);
  935. +   while (codestream_tell() != place)
  936. +     codestream_get ();
  937. + }
  938. + static void
  939. + codestream_read (buf, count)
  940. +      unsigned char *buf;
  941. + {
  942. +   unsigned char *p;
  943. +   int i;
  944. +   p = buf;
  945. +   for (i = 0; i < count; i++)
  946. +     *p++ = codestream_get ();
  947. + }
  948. + /* next instruction is a jump, move to target */
  949. + static
  950. + i386_follow_jump ()
  951. + {
  952. +   int long_delta;
  953. +   short short_delta;
  954. +   char byte_delta;
  955. +   int data16;
  956. +   int pos;
  957. +   
  958. +   pos = codestream_tell ();
  959. +   
  960. +   data16 = 0;
  961. +   if (codestream_peek () == 0x66)
  962. +     {
  963. +       codestream_get ();
  964. +       data16 = 1;
  965. +     }
  966. +   
  967. +   switch (codestream_get ())
  968. +     {
  969. +     case 0xe9:
  970. +       /* relative jump: if data16 == 0, disp32, else disp16 */
  971. +       if (data16)
  972. +     {
  973. +       codestream_read ((unsigned char *)&short_delta, 2);
  974. +       pos += short_delta + 3; /* include size of jmp inst */
  975. +     }
  976. +       else
  977. +     {
  978. +       codestream_read ((unsigned char *)&long_delta, 4);
  979. +       pos += long_delta + 5;
  980. +     }
  981. +       break;
  982. +     case 0xeb:
  983. +       /* relative jump, disp8 (ignore data16) */
  984. +       codestream_read ((unsigned char *)&byte_delta, 1);
  985. +       pos += byte_delta + 2;
  986. +       break;
  987. +     }
  988. +   codestream_seek (pos + data16);
  989. + }
  990. + /*
  991. +  * find & return amound a local space allocated, and advance codestream to
  992. +  * first register push (if any)
  993. +  *
  994. +  * if entry sequence doesn't make sense, return -1, and leave 
  995. +  * codestream pointer random
  996. +  */
  997. + static long
  998. + i386_get_frame_setup (pc)
  999. + {
  1000. +   unsigned char op;
  1001. +   
  1002. +   codestream_seek (pc);
  1003. +   
  1004. +   i386_follow_jump ();
  1005. +   
  1006. +   op = codestream_get ();
  1007. +   
  1008. +   if (op == 0x58)        /* popl %eax */
  1009. +     {
  1010. +       /*
  1011. +        * this function must start with
  1012. +        * 
  1013. +        *    popl %eax          0x58
  1014. +        *    xchgl %eax, (%esp)  0x87 0x04 0x24
  1015. +        * or xchgl %eax, 0(%esp) 0x87 0x44 0x24 0x00
  1016. +        *
  1017. +        * (the system 5 compiler puts out the second xchg
  1018. +        * inst, and the assembler doesn't try to optimize it,
  1019. +        * so the 'sib' form gets generated)
  1020. +        * 
  1021. +        * this sequence is used to get the address of the return
  1022. +        * buffer for a function that returns a structure
  1023. +        */
  1024. +       int pos;
  1025. +       unsigned char buf[4];
  1026. +       static unsigned char proto1[3] = { 0x87,0x04,0x24 };
  1027. +       static unsigned char proto2[4] = { 0x87,0x44,0x24,0x00 };
  1028. +       pos = codestream_tell ();
  1029. +       codestream_read (buf, 4);
  1030. +       if (bcmp (buf, proto1, 3) == 0)
  1031. +     pos += 3;
  1032. +       else if (bcmp (buf, proto2, 4) == 0)
  1033. +     pos += 4;
  1034. +       
  1035. +       codestream_seek (pos);
  1036. +       op = codestream_get (); /* update next opcode */
  1037. +     }
  1038. +   
  1039. +   if (op == 0x55)        /* pushl %esp */
  1040. +     {            
  1041. +       /* check for movl %esp, %ebp - can be written two ways */
  1042. +       switch (codestream_get ())
  1043. +     {
  1044. +     case 0x8b:
  1045. +       if (codestream_get () != 0xec)
  1046. +         return (-1);
  1047. +       break;
  1048. +     case 0x89:
  1049. +       if (codestream_get () != 0xe5)
  1050. +         return (-1);
  1051. +       break;
  1052. +     default:
  1053. +       return (-1);
  1054. +     }
  1055. +       /* check for stack adjustment 
  1056. +        *
  1057. +        *  subl $XXX, %esp
  1058. +        *
  1059. +        * note: you can't subtract a 16 bit immediate
  1060. +        * from a 32 bit reg, so we don't have to worry
  1061. +        * about a data16 prefix 
  1062. +        */
  1063. +       op = codestream_peek ();
  1064. +       if (op == 0x83)
  1065. +     {
  1066. +       /* subl with 8 bit immed */
  1067. +       codestream_get ();
  1068. +       if (codestream_get () != 0xec)
  1069. +         return (-1);
  1070. +       /* subl with signed byte immediate 
  1071. +        * (though it wouldn't make sense to be negative)
  1072. +        */
  1073. +       return (codestream_get());
  1074. +     }
  1075. +       else if (op == 0x81)
  1076. +     {
  1077. +       /* subl with 32 bit immed */
  1078. +       int locals;
  1079. +       codestream_get();
  1080. +       if (codestream_get () != 0xec)
  1081. +         return (-1);
  1082. +       /* subl with 32 bit immediate */
  1083. +       codestream_read ((unsigned char *)&locals, 4);
  1084. +       return (locals);
  1085. +     }
  1086. +       else
  1087. +     {
  1088. +       return (0);
  1089. +     }
  1090. +     }
  1091. +   else if (op == 0xc8)
  1092. +     {
  1093. +       /* enter instruction: arg is 16 bit unsigned immed */
  1094. +       unsigned short slocals;
  1095. +       codestream_read ((unsigned char *)&slocals, 2);
  1096. +       codestream_get (); /* flush final byte of enter instruction */
  1097. +       return (slocals);
  1098. +     }
  1099. +   return (-1);
  1100. + }
  1101. + /* Return number of args passed to a frame.
  1102. +    Can return -1, meaning no way to tell.  */
  1103. + /* on the 386, the instruction following the call could be:
  1104. +  *  popl %ecx        -  one arg
  1105. +  *  addl $imm, %esp  -  imm/4 args; imm may be 8 or 32 bits
  1106. +  *  anything else    -  zero args
  1107. +  */
  1108. + int
  1109. + i386_frame_num_args (fi)
  1110. +      struct frame_info fi;
  1111. + {
  1112. +   int retpc;                        
  1113. +   unsigned char op;                    
  1114. +   struct frame_info *pfi;
  1115. +   pfi = get_prev_frame_info ((fi));            
  1116. +   if (pfi == 0)
  1117. +     {
  1118. +       /* Note:  this can happen if we are looking at the frame for
  1119. +      main, because FRAME_CHAIN_VALID won't let us go into
  1120. +      start.  If we have debugging symbols, that's not really
  1121. +      a big deal; it just means it will only show as many arguments
  1122. +      to main as are declared.  */
  1123. +       return -1;
  1124. +     }
  1125. +   else
  1126. +     {
  1127. +       retpc = pfi->pc;                    
  1128. +       op = read_memory_integer (retpc, 1);            
  1129. +       if (op == 0x59)                    
  1130. +     /* pop %ecx */                   
  1131. +     return 1;                
  1132. +       else if (op == 0x83)
  1133. +     {
  1134. +       op = read_memory_integer (retpc+1, 1);    
  1135. +       if (op == 0xc4)                
  1136. +         /* addl $<signed imm 8 bits>, %esp */    
  1137. +         return (read_memory_integer (retpc+2,1)&0xff)/4;
  1138. +       else
  1139. +         return 0;
  1140. +     }
  1141. +       else if (op == 0x81)
  1142. +     { /* add with 32 bit immediate */
  1143. +       op = read_memory_integer (retpc+1, 1);    
  1144. +       if (op == 0xc4)                
  1145. +         /* addl $<imm 32>, %esp */        
  1146. +         return read_memory_integer (retpc+2, 4) / 4;
  1147. +       else
  1148. +         return 0;
  1149. +     }
  1150. +       else
  1151. +     {
  1152. +       return 0;
  1153. +     }
  1154. +     }
  1155. + }
  1156. + /*
  1157. +  * parse the first few instructions of the function to see
  1158. +  * what registers were stored.
  1159. +  *
  1160. +  * We handle these cases:
  1161. +  *
  1162. +  * The startup sequence can be at the start of the function,
  1163. +  * or the function can start with a branch to startup code at the end.
  1164. +  *
  1165. +  * %ebp can be set up with either the 'enter' instruction, or 
  1166. +  * 'pushl %ebp, movl %esp, %ebp' (enter is too slow to be useful,
  1167. +  * but was once used in the sys5 compiler)
  1168. +  *
  1169. +  * Local space is allocated just below the saved %ebp by either the
  1170. +  * 'enter' instruction, or by 'subl $<size>, %esp'.  'enter' has
  1171. +  * a 16 bit unsigned argument for space to allocate, and the
  1172. +  * 'addl' instruction could have either a signed byte, or
  1173. +  * 32 bit immediate.
  1174. +  *
  1175. +  * Next, the registers used by this function are pushed.  In
  1176. +  * the sys5 compiler they will always be in the order: %edi, %esi, %ebx
  1177. +  * (and sometimes a harmless bug causes it to also save but not restore %eax);
  1178. +  * however, the code below is willing to see the pushes in any order,
  1179. +  * and will handle up to 8 of them.
  1180. +  *
  1181. +  * If the setup sequence is at the end of the function, then the
  1182. +  * next instruction will be a branch back to the start.
  1183. +  */
  1184. + i386_frame_find_saved_regs (fip, fsrp)
  1185. +      struct frame_info *fip;
  1186. +      struct frame_saved_regs *fsrp;
  1187. + {
  1188. +   unsigned long locals;
  1189. +   unsigned char *p;
  1190. +   unsigned char op;
  1191. +   CORE_ADDR dummy_bottom;
  1192. +   CORE_ADDR adr;
  1193. +   int i;
  1194. +   
  1195. +   bzero (fsrp, sizeof *fsrp);
  1196. +   
  1197. +   /* if frame is the end of a dummy, compute where the
  1198. +    * beginning would be
  1199. +    */
  1200. +   dummy_bottom = fip->frame - 4 - NUM_REGS*4 - CALL_DUMMY_LENGTH;
  1201. +   
  1202. +   /* check if the PC is in the stack, in a dummy frame */
  1203. +   if (dummy_bottom <= fip->pc && fip->pc <= fip->frame) 
  1204. +     {
  1205. +       /* all regs were saved by push_call_dummy () */
  1206. +       adr = fip->frame - 4;
  1207. +       for (i = 0; i < NUM_REGS; i++) 
  1208. +     {
  1209. +       fsrp->regs[i] = adr;
  1210. +       adr -= 4;
  1211. +     }
  1212. +       return;
  1213. +     }
  1214. +   
  1215. +   locals = i386_get_frame_setup (get_pc_function_start (fip->pc));
  1216. +   
  1217. +   if (locals >= 0) 
  1218. +     {
  1219. +       adr = fip->frame - 4 - locals;
  1220. +       for (i = 0; i < 8; i++) 
  1221. +     {
  1222. +       op = codestream_get ();
  1223. +       if (op < 0x50 || op > 0x57)
  1224. +         break;
  1225. +       fsrp->regs[op - 0x50] = adr;
  1226. +       adr -= 4;
  1227. +     }
  1228. +     }
  1229. +   
  1230. +   fsrp->regs[PC_REGNUM] = fip->frame + 4;
  1231. +   fsrp->regs[FP_REGNUM] = fip->frame;
  1232. + }
  1233. + /* return pc of first real instruction */
  1234. + i386_skip_prologue (pc)
  1235. + {
  1236. +   unsigned char op;
  1237. +   int i;
  1238. +   
  1239. +   if (i386_get_frame_setup (pc) < 0)
  1240. +     return (pc);
  1241. +   
  1242. +   /* found valid frame setup - codestream now points to 
  1243. +    * start of push instructions for saving registers
  1244. +    */
  1245. +   
  1246. +   /* skip over register saves */
  1247. +   for (i = 0; i < 8; i++)
  1248. +     {
  1249. +       op = codestream_peek ();
  1250. +       /* break if not pushl inst */
  1251. +       if (op < 0x50 || op > 0x57) 
  1252. +     break;
  1253. +       codestream_get ();
  1254. +     }
  1255. +   
  1256. +   i386_follow_jump ();
  1257. +   
  1258. +   return (codestream_tell ());
  1259. + }
  1260. + i386_push_dummy_frame ()
  1261. + {
  1262. +   CORE_ADDR sp = read_register (SP_REGNUM);
  1263. +   int regnum;
  1264. +   
  1265. +   sp = push_word (sp, read_register (PC_REGNUM));
  1266. +   sp = push_word (sp, read_register (FP_REGNUM));
  1267. +   write_register (FP_REGNUM, sp);
  1268. +   for (regnum = 0; regnum < NUM_REGS; regnum++)
  1269. +     sp = push_word (sp, read_register (regnum));
  1270. +   write_register (SP_REGNUM, sp);
  1271. + }
  1272. + i386_pop_frame ()
  1273. + {
  1274. +   FRAME frame = get_current_frame ();
  1275. +   CORE_ADDR fp;
  1276. +   int regnum;
  1277. +   struct frame_saved_regs fsr;
  1278. +   struct frame_info *fi;
  1279. +   
  1280. +   fi = get_frame_info (frame);
  1281. +   fp = fi->frame;
  1282. +   get_frame_saved_regs (fi, &fsr);
  1283. +   for (regnum = 0; regnum < NUM_REGS; regnum++) 
  1284. +     {
  1285. +       CORE_ADDR adr;
  1286. +       adr = fsr.regs[regnum];
  1287. +       if (adr)
  1288. +     write_register (regnum, read_memory_integer (adr, 4));
  1289. +     }
  1290. +   write_register (FP_REGNUM, read_memory_integer (fp, 4));
  1291. +   write_register (PC_REGNUM, read_memory_integer (fp + 4, 4));
  1292. +   write_register (SP_REGNUM, fp + 8);
  1293. +   flush_cached_frames ();
  1294. +   set_current_frame ( create_new_frame (read_register (FP_REGNUM),
  1295. +                     read_pc ()));
  1296. + }
  1297. + /* this table must line up with REGISTER_NAMES in m-i386.h */
  1298. + /* symbols like 'EAX' come from <sys/reg.h> */
  1299. + static int regmap[] = 
  1300. + {
  1301. +   REAX, RECX, REDX, REBX,
  1302. +   RESP, REBP, RESI, REDI,
  1303. +   REIP, REFL, RCS, RSS,
  1304. +   RDS, RES, RFS, RGS,
  1305. + };
  1306. + /* blockend is the value of u.u_ar0, and points to the
  1307. +  * place where GS is stored
  1308. +  */
  1309. + i386_register_u_addr (blockend, regnum)
  1310. + {
  1311. + #if 0
  1312. +   /* this will be needed if fp registers are reinstated */
  1313. +   /* for now, you can look at them with 'info float'
  1314. +    * sys5 wont let you change them with ptrace anyway
  1315. +    */
  1316. +   if (regnum >= FP0_REGNUM && regnum <= FP7_REGNUM) 
  1317. +     {
  1318. +       int ubase, fpstate;
  1319. +       struct user u;
  1320. +       ubase = blockend + 4 * (SS + 1) - KSTKSZ;
  1321. +       fpstate = ubase + ((char *)&u.u_fpstate - (char *)&u);
  1322. +       return (fpstate + 0x1c + 10 * (regnum - FP0_REGNUM));
  1323. +     } 
  1324. +   else
  1325. + #endif
  1326. +     return (blockend + 4 * regmap[regnum]);
  1327. +   
  1328. + }
  1329. + i387_to_double (from, to)
  1330. +      char *from;
  1331. +      char *to;
  1332. + {
  1333. +   long *lp;
  1334. +   /* push extended mode on 387 stack, then pop in double mode
  1335. +    *
  1336. +    * first, set exception masks so no error is generated -
  1337. +    * number will be rounded to inf or 0, if necessary 
  1338. +    */
  1339. +   asm ("pushl %eax");         /* grab a stack slot */
  1340. +   asm ("fstcw (%esp)");        /* get 387 control word */
  1341. +   asm ("movl (%esp),%eax");    /* save old value */
  1342. +   asm ("orl $0x3f,%eax");        /* mask all exceptions */
  1343. +   asm ("pushl %eax");
  1344. +   asm ("fldcw (%esp)");        /* load new value into 387 */
  1345. +   
  1346. +   asm ("movl 8(%ebp),%eax");
  1347. +   asm ("fldt (%eax)");        /* push extended number on 387 stack */
  1348. +   asm ("fwait");
  1349. +   asm ("movl 12(%ebp),%eax");
  1350. +   asm ("fstpl (%eax)");        /* pop double */
  1351. +   asm ("fwait");
  1352. +   
  1353. +   asm ("popl %eax");        /* flush modified control word */
  1354. +   asm ("fnclex");            /* clear exceptions */
  1355. +   asm ("fldcw (%esp)");        /* restore original control word */
  1356. +   asm ("popl %eax");        /* flush saved copy */
  1357. + }
  1358. + double_to_i387 (from, to)
  1359. +      char *from;
  1360. +      char *to;
  1361. + {
  1362. +   /* push double mode on 387 stack, then pop in extended mode
  1363. +    * no errors are possible because every 64-bit pattern
  1364. +    * can be converted to an extended
  1365. +    */
  1366. +   asm ("movl 8(%ebp),%eax");
  1367. +   asm ("fldl (%eax)");
  1368. +   asm ("fwait");
  1369. +   asm ("movl 12(%ebp),%eax");
  1370. +   asm ("fstpt (%eax)");
  1371. +   asm ("fwait");
  1372. + }
  1373. + struct env387 
  1374. + {
  1375. +   unsigned int control;
  1376. +   unsigned int status;
  1377. +   unsigned int tag;
  1378. +   unsigned long eip;
  1379. +   unsigned short code_seg;
  1380. +   unsigned short operand_seg;
  1381. +   unsigned long opcode;
  1382. +   unsigned long operand;
  1383. +   unsigned char regs[8][10];
  1384. + };
  1385. + static
  1386. + print_387_control_word (control)
  1387. + unsigned short control;
  1388. + {
  1389. +   printf ("control 0x%04x: ", control);
  1390. +   printf ("compute to ");
  1391. +   switch ((control >> 8) & 3) 
  1392. +     {
  1393. +     case 0: printf ("24 bits; "); break;
  1394. +     case 1: printf ("(bad); "); break;
  1395. +     case 2: printf ("53 bits; "); break;
  1396. +     case 3: printf ("64 bits; "); break;
  1397. +     }
  1398. +   printf ("round ");
  1399. +   switch ((control >> 10) & 3) 
  1400. +     {
  1401. +     case 0: printf ("NEAREST; "); break;
  1402. +     case 1: printf ("DOWN; "); break;
  1403. +     case 2: printf ("UP; "); break;
  1404. +     case 3: printf ("CHOP; "); break;
  1405. +     }
  1406. +   if (control & 0x3f) 
  1407. +     {
  1408. +       printf ("mask:");
  1409. +       if (control & 0x0001) printf (" INVALID");
  1410. +       if (control & 0x0002) printf (" DENORM");
  1411. +       if (control & 0x0004) printf (" DIVZ");
  1412. +       if (control & 0x0008) printf (" OVERF");
  1413. +       if (control & 0x0010) printf (" UNDERF");
  1414. +       if (control & 0x0020) printf (" LOS");
  1415. +       printf (";");
  1416. +     }
  1417. +   printf ("\n");
  1418. +   if (control & 0xe080) printf ("warning: reserved bits on 0x%x\n",
  1419. +                 control & 0xe080);
  1420. + }
  1421. + static
  1422. + print_387_status_word (status)
  1423. +      unsigned short status;
  1424. + {
  1425. +   printf ("status 0x%04x: ", status);
  1426. +   if (status & 0xff) 
  1427. +     {
  1428. +       printf ("exceptions:");
  1429. +       if (status & 0x0001) printf (" INVALID");
  1430. +       if (status & 0x0002) printf (" DENORM");
  1431. +       if (status & 0x0004) printf (" DIVZ");
  1432. +       if (status & 0x0008) printf (" OVERF");
  1433. +       if (status & 0x0010) printf (" UNDERF");
  1434. +       if (status & 0x0020) printf (" LOS");
  1435. +       if (status & 0x0040) printf (" FPSTACK");
  1436. +       printf ("; ");
  1437. +     }
  1438. +   printf ("flags: %d%d%d%d; ",
  1439. +       (status & 0x4000) != 0,
  1440. +       (status & 0x0400) != 0,
  1441. +       (status & 0x0200) != 0,
  1442. +       (status & 0x0100) != 0);
  1443. +   
  1444. +   printf ("top %d\n", (status >> 11) & 7);
  1445. + }
  1446. + static
  1447. + print_387_status (ep)
  1448. +      struct env387 *ep;
  1449. + {
  1450. +   int i;
  1451. +   int top;
  1452. +   int fpreg;
  1453. +   unsigned char *p;
  1454. +   
  1455. +   if (ep->status != 0) 
  1456. +       print_387_status_word (ep->status);
  1457. +   
  1458. +   print_387_control_word (ep->control);
  1459. +   printf ("last exception: ");
  1460. +   printf ("opcode 0x%x; ", ep->opcode);
  1461. +   printf ("pc 0x%x:0x%x; ", ep->code_seg, ep->eip);
  1462. +   printf ("operand 0x%x:0x%x\n", ep->operand_seg, ep->operand);
  1463. +   
  1464. +   top = (ep->status >> 11) & 7;
  1465. +   
  1466. +   printf ("regno  tag  msb              lsb  value\n");
  1467. +   for (fpreg = 7; fpreg >= 0; fpreg--) 
  1468. +     {
  1469. +       double val;
  1470. +       
  1471. +       printf ("%s %d: ", fpreg == top ? "=>" : "  ", fpreg);
  1472. +       
  1473. +       switch ((ep->tag >> (fpreg * 2)) & 3) 
  1474. +     {
  1475. +     case 0: printf ("valid "); break;
  1476. +     case 1: printf ("zero  "); break;
  1477. +     case 2: printf ("trap  "); break;
  1478. +     case 3: printf ("empty "); break;
  1479. +     }
  1480. +       for (i = 9; i >= 0; i--)
  1481. +     printf ("%02x", ep->regs[fpreg][i]);
  1482. +       
  1483. +       i387_to_double (ep->regs[fpreg], (char *)&val);
  1484. +       printf ("  %g\n", val);
  1485. +     }
  1486. + }
  1487. + #ifndef U_FPSTATE
  1488. + #define U_FPSTATE(u) u.u_fps
  1489. + #endif
  1490. + i386_float_info ()
  1491. + {
  1492. +   struct user u; /* just for address computations */
  1493. +   int i;
  1494. +   /* fpstate defined in <sys/user.h> */
  1495. +   struct u_fps *fpstatep;
  1496. +   char buf[sizeof (struct u_fps) + 2 * sizeof (int)];
  1497. +   unsigned int uaddr;
  1498. +   char fpvalid;
  1499. +   unsigned int rounded_addr;
  1500. +   unsigned int rounded_size;
  1501. +   extern int corechan;
  1502. +   int skip;
  1503. +   
  1504. +   uaddr = (char *)&u.u_fpsaved - (char *)&u;
  1505. +   if (have_inferior_p()) 
  1506. +     {
  1507. +       unsigned int data;
  1508. +       unsigned int mask;
  1509. +       
  1510. +       rounded_addr = uaddr & -sizeof (int);
  1511. +       data = ptrace (3, inferior_pid, rounded_addr, 0);
  1512. +       mask = 0xff << ((uaddr - rounded_addr) * 8);
  1513. +       
  1514. +       fpvalid = ((data & mask) != 0);
  1515. +     } 
  1516. +   else 
  1517. +     {
  1518. +       if (lseek (corechan, uaddr, 0) < 0)
  1519. +     perror ("seek on core file");
  1520. +       if (myread (corechan, &fpvalid, 1) < 0) 
  1521. +     perror ("read on core file");
  1522. +       
  1523. +     }
  1524. +   
  1525. +   if (fpvalid == 0) 
  1526. +     {
  1527. +       printf ("no floating point status saved\n");
  1528. +       return;
  1529. +     }
  1530. +   
  1531. +   uaddr = (char *)&U_FPSTATE(u) - (char *)&u;
  1532. +   if (have_inferior_p ()) 
  1533. +     {
  1534. +       int *ip;
  1535. +       
  1536. +       rounded_addr = uaddr & -sizeof (int);
  1537. +       rounded_size = (((uaddr + sizeof (struct u_fps)) - uaddr) +
  1538. +               sizeof (int) - 1) / sizeof (int);
  1539. +       skip = uaddr - rounded_addr;
  1540. +       
  1541. +       ip = (int *)buf;
  1542. +       for (i = 0; i < rounded_size; i++) 
  1543. +     {
  1544. +       *ip++ = ptrace (3, inferior_pid, rounded_addr, 0);
  1545. +       rounded_addr += sizeof (int);
  1546. +     }
  1547. +     } 
  1548. +   else 
  1549. +     {
  1550. +       if (lseek (corechan, uaddr, 0) < 0)
  1551. +     perror_with_name ("seek on core file");
  1552. +       if (myread (corechan, buf, sizeof (struct u_fps)) < 0) 
  1553. +     perror_with_name ("read from core file");
  1554. +       skip = 0;
  1555. +     }
  1556. +   
  1557. +   fpstatep = (struct u_fps *)(buf + skip);
  1558. +   print_387_status ((struct env387 *)fpstatep);
  1559. + }
  1560.