kobj.c 2.6 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146
  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. * kobj.c - identify and parse a sparc object file
  11. */
  12. #include <u.h>
  13. #include <libc.h>
  14. #include <bio.h>
  15. #include <mach.h>
  16. #include "kc/k.out.h"
  17. #include "obj.h"
  18. typedef struct Addr Addr;
  19. struct Addr
  20. {
  21. char type;
  22. char sym;
  23. char name;
  24. };
  25. static Addr addr(Biobuf*);
  26. static char type2char(int);
  27. static void skip(Biobuf*, int);
  28. int
  29. _isk(char *s)
  30. {
  31. return s[0] == ANAME /* ANAME */
  32. && s[1] == D_FILE /* type */
  33. && s[2] == 1 /* sym */
  34. && s[3] == '<'; /* name of file */
  35. }
  36. int
  37. _readk(Biobuf *bp, Prog *p)
  38. {
  39. int as, n;
  40. Addr a;
  41. as = Bgetc(bp); /* as */
  42. if(as < 0)
  43. return 0;
  44. p->kind = aNone;
  45. p->sig = 0;
  46. if(as == ANAME || as == ASIGNAME){
  47. if(as == ASIGNAME){
  48. Bread(bp, &p->sig, 4);
  49. p->sig = beswal(p->sig);
  50. }
  51. p->kind = aName;
  52. p->type = type2char(Bgetc(bp)); /* type */
  53. p->sym = Bgetc(bp); /* sym */
  54. n = 0;
  55. for(;;) {
  56. as = Bgetc(bp);
  57. if(as < 0)
  58. return 0;
  59. n++;
  60. if(as == 0)
  61. break;
  62. }
  63. p->id = malloc(n);
  64. if(p->id == 0)
  65. return 0;
  66. Bseek(bp, -n, 1);
  67. if(Bread(bp, p->id, n) != n)
  68. return 0;
  69. return 1;
  70. }
  71. if(as == ATEXT)
  72. p->kind = aText;
  73. else if(as == AGLOBL)
  74. p->kind = aData;
  75. skip(bp, 5); /* reg (1 byte); lineno (4 bytes) */
  76. a = addr(bp);
  77. addr(bp);
  78. if(a.type != D_OREG || a.name != D_STATIC && a.name != D_EXTERN)
  79. p->kind = aNone;
  80. p->sym = a.sym;
  81. return 1;
  82. }
  83. static Addr
  84. addr(Biobuf *bp)
  85. {
  86. Addr a;
  87. int32_t off;
  88. a.type = Bgetc(bp); /* a.type */
  89. skip(bp, 1); /* reg */
  90. a.sym = Bgetc(bp); /* sym index */
  91. a.name = Bgetc(bp); /* sym type */
  92. switch(a.type) {
  93. default:
  94. case D_NONE: case D_REG: case D_FREG: case D_CREG: case D_PREG:
  95. break;
  96. case D_BRANCH:
  97. case D_OREG:
  98. case D_ASI:
  99. case D_CONST:
  100. off = Bgetc(bp);
  101. off |= Bgetc(bp) << 8;
  102. off |= Bgetc(bp) << 16;
  103. off |= Bgetc(bp) << 24;
  104. if(off < 0)
  105. off = -off;
  106. if(a.sym!=0 && (a.name==D_PARAM || a.name==D_AUTO))
  107. _offset(a.sym, off);
  108. break;
  109. case D_SCONST:
  110. skip(bp, NSNAME);
  111. break;
  112. case D_FCONST:
  113. skip(bp, 8);
  114. break;
  115. }
  116. return a;
  117. }
  118. static char
  119. type2char(int t)
  120. {
  121. switch(t){
  122. case D_EXTERN: return 'U';
  123. case D_STATIC: return 'b';
  124. case D_AUTO: return 'a';
  125. case D_PARAM: return 'p';
  126. default: return UNKNOWN;
  127. }
  128. }
  129. static void
  130. skip(Biobuf *bp, int n)
  131. {
  132. while (n-- > 0)
  133. Bgetc(bp);
  134. }