mach.h 9.7 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335
  1. /*
  2. * This file is part of the UCB release of Plan 9. It is subject to the license
  3. * terms in the LICENSE file found in the top-level directory of this
  4. * distribution and at http://akaros.cs.berkeley.edu/files/Plan9License. No
  5. * part of the UCB release of Plan 9, including this file, may be copied,
  6. * modified, propagated, or distributed except according to the terms contained
  7. * in the LICENSE file.
  8. */
  9. /*
  10. * Architecture-dependent application data
  11. */
  12. #include "elf.h"
  13. /*
  14. * Supported architectures:
  15. * mips,
  16. * 68020,
  17. * i386,
  18. * amd64,
  19. * sparc,
  20. * mips2 (R4000)
  21. * arm
  22. * powerpc,
  23. * powerpc64
  24. * arm64
  25. */
  26. enum
  27. {
  28. MMIPS, /* machine types */
  29. MSPARC,
  30. M68020,
  31. MI386,
  32. MI960, /* retired */
  33. M3210, /* retired */
  34. MMIPS2,
  35. NMIPS2,
  36. M29000, /* retired */
  37. MARM,
  38. MPOWER,
  39. MALPHA, /* retired */
  40. NMIPS,
  41. MSPARC64, /* retired */
  42. MAMD64,
  43. MPOWER64,
  44. MARM64,
  45. /* types of executables */
  46. FNONE = 0, /* unidentified */
  47. FMIPS, /* v.out */
  48. FMIPSB, /* mips bootable */
  49. FSPARC, /* k.out */
  50. FSPARCB, /* Sparc bootable */
  51. F68020, /* 2.out */
  52. F68020B, /* 68020 bootable */
  53. FNEXTB, /* Next bootable */
  54. FI386, /* 8.out */
  55. FI386B, /* I386 bootable */
  56. FI960, /* retired */
  57. FI960B, /* retired */
  58. F3210, /* retired */
  59. FMIPS2BE, /* 4.out */
  60. F29000, /* retired */
  61. FARM, /* 5.out */
  62. FARMB, /* ARM bootable */
  63. FPOWER, /* q.out */
  64. FPOWERB, /* power pc bootable */
  65. FMIPS2LE, /* 0.out */
  66. FALPHA, /* retired */
  67. FALPHAB, /* retired DEC Alpha bootable */
  68. FMIPSLE, /* 3k little endian */
  69. FSPARC64, /* retired */
  70. FAMD64, /* 6.out */
  71. FAMD64B, /* 6.out bootable */
  72. FPOWER64, /* 9.out */
  73. FPOWER64B, /* 9.out bootable */
  74. FARM64, /* arm64 */
  75. FARM64B, /* arm64 bootable */
  76. ANONE = 0, /* dissembler types */
  77. AMIPS,
  78. AMIPSCO, /* native mips */
  79. ASPARC,
  80. ASUNSPARC, /* native sun */
  81. A68020,
  82. AI386,
  83. AI8086, /* oh god */
  84. AI960, /* retired */
  85. A29000, /* retired */
  86. AARM,
  87. APOWER,
  88. AALPHA, /* retired */
  89. ASPARC64, /* retired */
  90. AAMD64,
  91. APOWER64,
  92. AARM64,
  93. /* object file types */
  94. Obj68020 = 0, /* .2 */
  95. ObjSparc, /* .k */
  96. ObjMips, /* .v */
  97. Obj386, /* .8 */
  98. Obj960, /* retired */
  99. Obj3210, /* retired */
  100. ObjMips2, /* .4 */
  101. Obj29000, /* retired */
  102. ObjArm, /* .5 */
  103. ObjPower, /* .q */
  104. ObjMips2le, /* .0 */
  105. ObjAlpha, /* retired */
  106. ObjSparc64, /* retired */
  107. ObjAmd64, /* .6 */
  108. ObjSpim, /* .0 */
  109. ObjPower64, /* .9 */
  110. ObjArm64, /* .4? */
  111. Maxobjtype,
  112. CNONE = 0, /* symbol table classes */
  113. CAUTO,
  114. CPARAM,
  115. CSTAB,
  116. CTEXT,
  117. CDATA,
  118. CANY, /* to look for any class */
  119. };
  120. typedef struct Map Map;
  121. typedef struct Symbol Symbol;
  122. typedef struct Reglist Reglist;
  123. typedef struct Mach Mach;
  124. typedef struct Machdata Machdata;
  125. /*
  126. * Structure to map a segment to a position in a file
  127. */
  128. struct Map {
  129. int nsegs; /* number of segments */
  130. struct segment { /* per-segment map */
  131. char *name; /* the segment name */
  132. int fd; /* file descriptor */
  133. int inuse; /* in use - not in use */
  134. int cache; /* should cache reads? */
  135. uint64_t b; /* base */
  136. uint64_t e; /* end */
  137. int64_t f; /* offset within file */
  138. } seg[1]; /* actually n of these */
  139. };
  140. /*
  141. * Internal structure describing a symbol table entry
  142. */
  143. struct Symbol {
  144. void *handle; /* used internally - owning func */
  145. struct {
  146. char *name;
  147. int64_t value; /* address or stack offset */
  148. char type; /* as in a.out.h */
  149. char class; /* as above */
  150. int index; /* in findlocal, globalsym, textsym */
  151. };
  152. };
  153. /*
  154. * machine register description
  155. */
  156. struct Reglist {
  157. char *rname; /* register name */
  158. int16_t roffs; /* offset in u-block */
  159. char rflags; /* INTEGER/FLOAT, WRITABLE */
  160. char rformat; /* print format: 'x', 'X', 'f', '8', '3', 'Y', 'W' */
  161. };
  162. enum { /* bits in rflags field */
  163. RINT = (0<<0),
  164. RFLT = (1<<0),
  165. RRDONLY = (1<<1),
  166. };
  167. /*
  168. * Machine-dependent data is stored in two structures:
  169. * Mach - miscellaneous general parameters
  170. * Machdata - jump vector of service functions used by debuggers
  171. *
  172. * Mach is defined in ?.c and set in executable.c
  173. *
  174. * Machdata is defined in ?db.c
  175. * and set in the debugger startup.
  176. */
  177. struct Mach{
  178. char *name;
  179. int mtype; /* machine type code */
  180. Reglist *reglist; /* register set */
  181. int32_t regsize; /* sizeof registers in bytes */
  182. int32_t fpregsize; /* sizeof fp registers in bytes */
  183. char *pc; /* pc name */
  184. char *sp; /* sp name */
  185. char *link; /* link register name */
  186. char *sbreg; /* static base register name */
  187. uint64_t sb; /* static base register value */
  188. int pgsize; /* page size */
  189. uint64_t kbase; /* kernel base address */
  190. uint64_t ktmask; /* ktzero = kbase & ~ktmask */
  191. uint64_t utop; /* user stack top */
  192. int pcquant; /* quantization of pc */
  193. int szaddr; /* sizeof(void*) */
  194. int szreg; /* sizeof(register) */
  195. int szfloat; /* sizeof(float) */
  196. int szdouble; /* sizeof(double) */
  197. };
  198. extern Mach *mach; /* Current machine */
  199. typedef uint64_t (*Rgetter)(Map*, char*);
  200. typedef void (*Tracer)(Map*, uint64_t, uint64_t, Symbol*);
  201. struct Machdata { /* Machine-dependent debugger support */
  202. uint8_t bpinst[4]; /* break point instr. */
  203. int16_t bpsize; /* size of break point instr. */
  204. uint16_t (*swab)(uint16_t); /* ushort to local byte order */
  205. uint32_t (*swal)(uint32_t); /* ulong to local byte order */
  206. uint64_t (*swav)(uint64_t); /* uvlong to local byte order */
  207. int (*ctrace)(Map*, uint64_t, uint64_t, uint64_t, Tracer); /* C traceback */
  208. uint64_t (*findframe)(Map*, uint64_t, uint64_t, uint64_t,
  209. uint64_t); /* frame finder */
  210. char* (*excep)(Map*, Rgetter); /* last exception */
  211. uint32_t (*bpfix)(uint64_t); /* breakpoint fixup */
  212. int (*sftos)(char*, int, void*); /* single precision float */
  213. int (*dftos)(char*, int, void*); /* double precision float */
  214. int (*foll)(Map*, uint64_t, Rgetter, uint64_t*); /* follow set */
  215. int (*das)(Map*, uint64_t, char, char*, int); /* symbolic disassembly */
  216. int (*hexinst)(Map*, uint64_t, char*, int); /* hex disassembly */
  217. int (*instsize)(Map*, uint64_t); /* instruction size */
  218. };
  219. /*
  220. * Common executable header describing all architectures
  221. */
  222. typedef struct Fhdr
  223. {
  224. char *name; /* identifier of executable */
  225. uint8_t type; /* file type - see codes above */
  226. uint8_t hdrsz; /* header size */
  227. uint8_t spare;
  228. int32_t magic; /* magic number */
  229. uint64_t txtaddr; /* text address */
  230. int64_t txtoff; /* start of text in file */
  231. uint64_t dataddr; /* start of data segment */
  232. int64_t datoff; /* offset to data seg in file */
  233. int64_t symoff; /* offset of symbol table in file */
  234. uint64_t entry; /* entry point */
  235. int64_t sppcoff; /* offset of sp-pc table in file */
  236. int64_t lnpcoff; /* offset of line number-pc table in file */
  237. int32_t txtsz; /* text size */
  238. int32_t datsz; /* size of data seg */
  239. int32_t bsssz; /* size of bss */
  240. int32_t symsz; /* size of symbol table */
  241. int32_t sppcsz; /* size of sp-pc table */
  242. int32_t lnpcsz; /* size of line number-pc table */
  243. // TODO work out which of the above are no longer useful
  244. // and which should be uint64
  245. int8_t bigendian; /* big endian or not */
  246. uint64_t stroff; /* strtab offset in file */
  247. uint64_t strsz; /* size of strtab seg */
  248. uint16_t bssidx; /* index of bss section */
  249. uint16_t dbglineidx; /* index of debug_line section */
  250. } Fhdr;
  251. extern int asstype; /* dissembler type - machdata.c */
  252. extern Machdata *machdata; /* jump vector - machdata.c */
  253. Map* attachproc(int, int, int, Fhdr*);
  254. int beieee80ftos(char*, int, void*);
  255. int beieeesftos(char*, int, void*);
  256. int beieeedftos(char*, int, void*);
  257. uint16_t beswab(uint16_t);
  258. uint32_t beswal(uint32_t);
  259. uint64_t beswav(uint64_t);
  260. uint64_t ciscframe(Map*, uint64_t, uint64_t, uint64_t, uint64_t);
  261. int cisctrace(Map*, uint64_t, uint64_t, uint64_t, Tracer);
  262. int crackhdr(int fd, Fhdr*);
  263. uint64_t file2pc(char*, int32_t);
  264. int fileelem(Sym**, uint8_t *, char*, int);
  265. int32_t fileline(char*, int, uint64_t);
  266. int filesym(int, char*, int);
  267. int findlocal(Symbol*, char*, Symbol*);
  268. int findseg(Map*, char*);
  269. int findsym(uint64_t, int, Symbol *);
  270. int fnbound(uint64_t, uint64_t*);
  271. int fpformat(Map*, Reglist*, char*, int, int);
  272. int get1(Map*, uint64_t, uint8_t*, int);
  273. int get2(Map*, uint64_t, uint16_t*);
  274. int get4(Map*, uint64_t, uint32_t*);
  275. int get8(Map*, uint64_t, uint64_t*);
  276. int geta(Map*, uint64_t, uint64_t*);
  277. int getauto(Symbol*, int, int, Symbol*);
  278. Sym* getsym(int);
  279. int globalsym(Symbol *, int);
  280. char* _hexify(char*, uint32_t, int);
  281. int ieeesftos(char*, int, uint32_t);
  282. int ieeedftos(char*, int, uint32_t, uint32_t);
  283. int isar(Biobuf*);
  284. int leieee80ftos(char*, int, void*);
  285. int leieeesftos(char*, int, void*);
  286. int leieeedftos(char*, int, void*);
  287. uint16_t leswab(uint16_t);
  288. uint32_t leswal(uint32_t);
  289. uint64_t leswav(uint64_t);
  290. uint64_t line2addr(int32_t, uint64_t, uint64_t);
  291. Map* loadmap(Map*, int, Fhdr*);
  292. int localaddr(Map*, char*, char*, uint64_t*, Rgetter);
  293. int localsym(Symbol*, int);
  294. int lookup(char*, char*, Symbol*);
  295. void machbytype(int);
  296. int machbyname(char*);
  297. int nextar(Biobuf*, int, char*);
  298. Map* newmap(Map*, int);
  299. void objtraverse(void(*)(Sym*, void*), void*);
  300. int objtype(Biobuf*, char**);
  301. uint64_t pc2sp(uint64_t);
  302. int32_t pc2line(uint64_t);
  303. int put1(Map*, uint64_t, uint8_t*, int);
  304. int put2(Map*, uint64_t, uint16_t);
  305. int put4(Map*, uint64_t, uint32_t);
  306. int put8(Map*, uint64_t, uint64_t);
  307. int puta(Map*, uint64_t, uint64_t);
  308. int readar(Biobuf*, int, int64_t, int);
  309. int readobj(Biobuf*, int);
  310. uint64_t riscframe(Map*, uint64_t, uint64_t, uint64_t, uint64_t);
  311. int risctrace(Map*, uint64_t, uint64_t, uint64_t, Tracer);
  312. int setmap(Map*, int, uint64_t, uint64_t, int64_t, char*);
  313. Sym* symbase(int32_t*);
  314. int syminit(int, Fhdr*);
  315. int symoff(char*, int, uint64_t, int);
  316. void textseg(uint64_t, Fhdr*);
  317. int textsym(Symbol*, int);
  318. void unusemap(Map*, int);