5obj.c 2.6 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147
  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. * 5obj.c - identify and parse an arm object file
  11. */
  12. #include <u.h>
  13. #include <libc.h>
  14. #include <bio.h>
  15. #include <mach.h>
  16. #include "5c/5.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. _is5(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. _read5(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 = leswal(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, 6); /* scond(1), reg(1), lineno(4) */
  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:
  95. case D_REG:
  96. case D_FREG:
  97. case D_PSR:
  98. case D_FPCR:
  99. break;
  100. case D_OREG:
  101. case D_CONST:
  102. case D_BRANCH:
  103. case D_SHIFT:
  104. off = Bgetc(bp);
  105. off |= Bgetc(bp) << 8;
  106. off |= Bgetc(bp) << 16;
  107. off |= Bgetc(bp) << 24;
  108. if(off < 0)
  109. off = -off;
  110. if(a.sym && (a.name==D_PARAM || a.name==D_AUTO))
  111. _offset(a.sym, off);
  112. break;
  113. case D_SCONST:
  114. skip(bp, NSNAME);
  115. break;
  116. case D_FCONST:
  117. skip(bp, 8);
  118. break;
  119. }
  120. return a;
  121. }
  122. static char
  123. type2char(int t)
  124. {
  125. switch(t){
  126. case D_EXTERN: return 'U';
  127. case D_STATIC: return 'b';
  128. case D_AUTO: return 'a';
  129. case D_PARAM: return 'p';
  130. default: return UNKNOWN;
  131. }
  132. }
  133. static void
  134. skip(Biobuf *bp, int n)
  135. {
  136. while (n-- > 0)
  137. Bgetc(bp);
  138. }