read.c 53 KB

12345678910111213141516171819202122232425262728293031323334353637383940414243444546474849505152535455565758596061626364656667686970717273747576777879808182838485868788899091929394959697989910010110210310410510610710810911011111211311411511611711811912012112212312412512612712812913013113213313413513613713813914014114214314414514614714814915015115215315415515615715815916016116216316416516616716816917017117217317417517617717817918018118218318418518618718818919019119219319419519619719819920020120220320420520620720820921021121221321421521621721821922022122222322422522622722822923023123223323423523623723823924024124224324424524624724824925025125225325425525625725825926026126226326426526626726826927027127227327427527627727827928028128228328428528628728828929029129229329429529629729829930030130230330430530630730830931031131231331431531631731831932032132232332432532632732832933033133233333433533633733833934034134234334434534634734834935035135235335435535635735835936036136236336436536636736836937037137237337437537637737837938038138238338438538638738838939039139239339439539639739839940040140240340440540640740840941041141241341441541641741841942042142242342442542642742842943043143243343443543643743843944044144244344444544644744844945045145245345445545645745845946046146246346446546646746846947047147247347447547647747847948048148248348448548648748848949049149249349449549649749849950050150250350450550650750850951051151251351451551651751851952052152252352452552652752852953053153253353453553653753853954054154254354454554654754854955055155255355455555655755855956056156256356456556656756856957057157257357457557657757857958058158258358458558658758858959059159259359459559659759859960060160260360460560660760860961061161261361461561661761861962062162262362462562662762862963063163263363463563663763863964064164264364464564664764864965065165265365465565665765865966066166266366466566666766866967067167267367467567667767867968068168268368468568668768868969069169269369469569669769869970070170270370470570670770870971071171271371471571671771871972072172272372472572672772872973073173273373473573673773873974074174274374474574674774874975075175275375475575675775875976076176276376476576676776876977077177277377477577677777877978078178278378478578678778878979079179279379479579679779879980080180280380480580680780880981081181281381481581681781881982082182282382482582682782882983083183283383483583683783883984084184284384484584684784884985085185285385485585685785885986086186286386486586686786886987087187287387487587687787887988088188288388488588688788888989089189289389489589689789889990090190290390490590690790890991091191291391491591691791891992092192292392492592692792892993093193293393493593693793893994094194294394494594694794894995095195295395495595695795895996096196296396496596696796896997097197297397497597697797897998098198298398498598698798898999099199299399499599699799899910001001100210031004100510061007100810091010101110121013101410151016101710181019102010211022102310241025102610271028102910301031103210331034103510361037103810391040104110421043104410451046104710481049105010511052105310541055105610571058105910601061106210631064106510661067106810691070107110721073107410751076107710781079108010811082108310841085108610871088108910901091109210931094109510961097109810991100110111021103110411051106110711081109111011111112111311141115111611171118111911201121112211231124112511261127112811291130113111321133113411351136113711381139114011411142114311441145114611471148114911501151115211531154115511561157115811591160116111621163116411651166116711681169117011711172117311741175117611771178117911801181118211831184118511861187118811891190119111921193119411951196119711981199120012011202120312041205120612071208120912101211121212131214121512161217121812191220122112221223122412251226122712281229123012311232123312341235123612371238123912401241124212431244124512461247124812491250125112521253125412551256125712581259126012611262126312641265126612671268126912701271127212731274127512761277127812791280128112821283128412851286128712881289129012911292129312941295129612971298129913001301130213031304130513061307130813091310131113121313131413151316131713181319132013211322132313241325132613271328132913301331133213331334133513361337133813391340134113421343134413451346134713481349135013511352135313541355135613571358135913601361136213631364136513661367136813691370137113721373137413751376137713781379138013811382138313841385138613871388138913901391139213931394139513961397139813991400140114021403140414051406140714081409141014111412141314141415141614171418141914201421142214231424142514261427142814291430143114321433143414351436143714381439144014411442144314441445144614471448144914501451145214531454145514561457145814591460146114621463146414651466146714681469147014711472147314741475147614771478147914801481148214831484148514861487148814891490149114921493149414951496149714981499150015011502150315041505150615071508150915101511151215131514151515161517151815191520152115221523152415251526152715281529153015311532153315341535153615371538153915401541154215431544154515461547154815491550155115521553155415551556155715581559156015611562156315641565156615671568156915701571157215731574157515761577157815791580158115821583158415851586158715881589159015911592159315941595159615971598159916001601160216031604160516061607160816091610161116121613161416151616161716181619162016211622162316241625162616271628162916301631163216331634163516361637163816391640164116421643164416451646164716481649165016511652165316541655165616571658165916601661166216631664166516661667166816691670167116721673167416751676167716781679168016811682168316841685168616871688168916901691169216931694169516961697169816991700170117021703170417051706170717081709171017111712171317141715171617171718171917201721172217231724172517261727172817291730173117321733173417351736173717381739174017411742174317441745174617471748174917501751175217531754175517561757175817591760176117621763176417651766176717681769177017711772177317741775177617771778177917801781178217831784178517861787178817891790179117921793179417951796179717981799180018011802180318041805180618071808180918101811181218131814181518161817181818191820182118221823182418251826182718281829183018311832183318341835183618371838183918401841184218431844184518461847184818491850185118521853185418551856185718581859186018611862186318641865186618671868186918701871187218731874187518761877187818791880188118821883188418851886188718881889189018911892189318941895189618971898189919001901190219031904190519061907190819091910191119121913191419151916191719181919192019211922192319241925192619271928192919301931193219331934193519361937193819391940194119421943194419451946194719481949195019511952195319541955195619571958195919601961196219631964196519661967196819691970197119721973197419751976197719781979198019811982198319841985198619871988198919901991199219931994199519961997199819992000200120022003200420052006200720082009201020112012
  1. /* read.c - read a source file -
  2. Copyright (C) 1986,1987 Free Software Foundation, Inc.
  3. This file is part of GAS, the GNU Assembler.
  4. GAS is free software; you can redistribute it and/or modify
  5. it under the terms of the GNU General Public License as published by
  6. the Free Software Foundation; either version 1, or (at your option)
  7. any later version.
  8. GAS is distributed in the hope that it will be useful,
  9. but WITHOUT ANY WARRANTY; without even the implied warranty of
  10. MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
  11. GNU General Public License for more details.
  12. You should have received a copy of the GNU General Public License
  13. along with GAS; see the file COPYING. If not, write to
  14. the Free Software Foundation, 675 Mass Ave, Cambridge, MA 02139, USA. */
  15. #define MASK_CHAR (0xFF) /* If your chars aren't 8 bits, you will
  16. change this a bit. But then, GNU isn't
  17. spozed to run on your machine anyway.
  18. (RMS is so shortsighted sometimes.)
  19. */
  20. #define MAXIMUM_NUMBER_OF_CHARS_FOR_FLOAT (16)
  21. /* This is the largest known floating point */
  22. /* format (for now). It will grow when we */
  23. /* do 4361 style flonums. */
  24. /* Routines that read assembler source text to build spagetti in memory. */
  25. /* Another group of these functions is in the as-expr.c module */
  26. #include <ctype.h>
  27. #include <sys/types.h>
  28. #include <sys/stat.h>
  29. #include "as.h"
  30. #include "read.h"
  31. #include "md.h"
  32. #include "hash.h"
  33. #include "obstack.h"
  34. #include "frags.h"
  35. #include "flonum.h"
  36. #include "struc-symbol.h"
  37. #include "expr.h"
  38. #include "symbols.h"
  39. #ifdef SPARC
  40. #include "sparc.h"
  41. #endif
  42. char * input_line_pointer; /* -> next char of source file to parse. */
  43. #if BITS_PER_CHAR != 8
  44. The following table is indexed by [ (char) ] and will break if
  45. a char does not have exactly 256 states (hopefully 0:255!) !
  46. #endif
  47. char /* used by is_... macros. our ctype[] */
  48. lex_type [256] = {
  49. 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, /* @ABCDEFGHIJKLMNO */
  50. 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, /* PQRSTUVWXYZ[\]^_ */
  51. 0, 0, 0, 0, 3, 0, 0, 0, 0, 0, 0, 0, 0, 0, 3, 0, /* _!"#$%&'()*+,-./ */
  52. 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 0, 0, 0, 0, 0, 0, /* 0123456789:;<=>? */
  53. 0, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, /* @ABCDEFGHIJKLMNO */
  54. 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 0, 0, 0, 3, /* PQRSTUVWXYZ[\]^_ */
  55. 0, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, /* `abcdefghijklmno */
  56. 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 0, 0, 0, 0, /* pqrstuvwxyz{|}~. */
  57. 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
  58. 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
  59. 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
  60. 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
  61. 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
  62. 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
  63. 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0
  64. };
  65. /*
  66. * In: a character.
  67. * Out: TRUE if this character ends a line.
  68. */
  69. #define _ (0)
  70. char is_end_of_line [256] = {
  71. _, _, _, _, _, _, _, _, _, _,99, _, _, _, _, _, /* @abcdefghijklmno */
  72. _, _, _, _, _, _, _, _, _, _, _, _, _, _, _, _, /* */
  73. _, _, _, _, _, _, _, _, _, _, _, _, _, _, _, _, /* */
  74. _, _, _, _, _, _, _, _, _, _, _,99, _, _, _, _, /* 0123456789:;<=>? */
  75. _, _, _, _, _, _, _, _, _, _, _, _, _, _, _, _, /* */
  76. _, _, _, _, _, _, _, _, _, _, _, _, _, _, _, _, /* */
  77. _, _, _, _, _, _, _, _, _, _, _, _, _, _, _, _, /* */
  78. _, _, _, _, _, _, _, _, _, _, _, _, _, _, _, _, /* */
  79. _, _, _, _, _, _, _, _, _, _, _, _, _, _, _, _, /* */
  80. _, _, _, _, _, _, _, _, _, _, _, _, _, _, _, _, /* */
  81. _, _, _, _, _, _, _, _, _, _, _, _, _, _, _, _, /* */
  82. _, _, _, _, _, _, _, _, _, _, _, _, _, _, _, _, /* */
  83. _, _, _, _, _, _, _, _, _, _, _, _, _, _, _, _ /* */
  84. };
  85. #undef _
  86. /* Functions private to this file. */
  87. void equals();
  88. void big_cons();
  89. void cons();
  90. static char* demand_copy_C_string();
  91. static char* demand_copy_string();
  92. void demand_empty_rest_of_line();
  93. void float_cons();
  94. long int get_absolute_expression();
  95. static char get_absolute_expression_and_terminator();
  96. static segT get_known_segmented_expression();
  97. void ignore_rest_of_line();
  98. static int is_it_end_of_statement();
  99. static void pobegin();
  100. static void pseudo_set();
  101. static void stab();
  102. static void stringer();
  103. extern char line_comment_chars[];
  104. static char * buffer_limit; /* -> 1 + last char in buffer. */
  105. static char * bignum_low; /* Lowest char of bignum. */
  106. static char * bignum_limit; /* 1st illegal address of bignum. */
  107. static char * bignum_high; /* Highest char of bignum. */
  108. /* May point to (bignum_start-1). */
  109. /* Never >= bignum_limit. */
  110. static char *old_buffer = 0; /* JF a hack */
  111. static char *old_input;
  112. static char *old_limit;
  113. #ifndef WORKING_DOT_WORD
  114. struct broken_word *broken_words;
  115. int new_broken_words = 0;
  116. #endif
  117. static void grow_bignum ();
  118. static int next_char_of_string ();
  119. void
  120. read_begin()
  121. {
  122. pobegin();
  123. obstack_begin( &notes, 5000 );
  124. #define BIGNUM_BEGIN_SIZE (16)
  125. bignum_low = xmalloc((long)BIGNUM_BEGIN_SIZE);
  126. bignum_limit = bignum_low + BIGNUM_BEGIN_SIZE;
  127. }
  128. /* set up pseudo-op tables */
  129. static struct hash_control *
  130. po_hash = NULL; /* use before set up: NULL-> address error */
  131. void s_abort(), s_align(), s_comm(), s_data();
  132. void s_desc(), s_even(), s_file(), s_fill();
  133. void s_gdbbeg(), s_gdbblock(), s_gdbend(), s_gdbsym();
  134. void s_globl(), s_lcomm(), s_line(), s_lsym();
  135. void s_org(), s_set(), s_space(), s_text();
  136. void s_gdbline(), s_gdblinetab();
  137. void stringer();
  138. void cons();
  139. void float_cons();
  140. void big_cons();
  141. void stab();
  142. static pseudo_typeS
  143. potable[] =
  144. {
  145. { "abort", s_abort, 0 },
  146. { "align", s_align, 0 },
  147. { "ascii", stringer, 0 },
  148. { "asciz", stringer, 1 },
  149. { "byte", cons, 1 },
  150. { "comm", s_comm, 0 },
  151. { "data", s_data, 0 },
  152. { "desc", s_desc, 0 },
  153. { "double", float_cons, 'd' },
  154. { "file", s_file, 0 },
  155. { "fill", s_fill, 0 },
  156. { "float", float_cons, 'f' },
  157. { "gdbbeg", s_gdbbeg, 0 },
  158. { "gdbblock", s_gdbblock, 0 },
  159. { "gdbend", s_gdbend, 0 },
  160. { "gdbsym", s_gdbsym, 0 },
  161. { "gdbline", s_gdbline, 0 },
  162. { "gdblinetab",s_gdblinetab, 0 },
  163. { "globl", s_globl, 0 },
  164. { "int", cons, 4 },
  165. { "lcomm", s_lcomm, 0 },
  166. { "line", s_line, 0 },
  167. { "long", cons, 4 },
  168. { "lsym", s_lsym, 0 },
  169. { "octa", big_cons, 16 },
  170. { "org", s_org, 0 },
  171. { "quad", big_cons, 8 },
  172. { "set", s_set, 0 },
  173. { "short", cons, 2 },
  174. { "single", float_cons, 'f' },
  175. { "space", s_space, 0 },
  176. { "stabd", stab, 'd' },
  177. { "stabn", stab, 'n' },
  178. { "stabs", stab, 's' },
  179. { "text", s_text, 0 },
  180. #ifndef SPARC
  181. { "word", cons, 2 },
  182. #endif
  183. { NULL} /* end sentinel */
  184. };
  185. static void
  186. pobegin()
  187. {
  188. char * errtxt; /* error text */
  189. pseudo_typeS * pop;
  190. po_hash = hash_new();
  191. errtxt = ""; /* OK so far */
  192. for (pop=potable; pop->poc_name && !*errtxt; pop++)
  193. {
  194. errtxt = hash_insert (po_hash, pop->poc_name, (char *)pop);
  195. }
  196. for(pop=md_pseudo_table; pop->poc_name && !*errtxt; pop++)
  197. errtxt = hash_insert (po_hash, pop->poc_name, (char *)pop);
  198. if (*errtxt)
  199. {
  200. as_fatal ("error constructing pseudo-op table");
  201. }
  202. } /* pobegin() */
  203. /* read_a_source_file()
  204. *
  205. * File has already been opened, and will be closed by our caller.
  206. *
  207. * We read the file, putting things into a web that
  208. * represents what we have been reading.
  209. */
  210. void
  211. read_a_source_file (buffer)
  212. char * buffer; /* 1st character of each buffer of lines is here. */
  213. {
  214. register char c;
  215. register char * s; /* string of symbol, '\0' appended */
  216. register int temp;
  217. /* register struct frag * fragP; JF unused */ /* a frag we just made */
  218. pseudo_typeS *pop;
  219. void gdb_block_beg();
  220. void gdb_block_position();
  221. void gdb_block_end();
  222. void gdb_symbols_fixup();
  223. subseg_new (SEG_TEXT, 0);
  224. while ( buffer_limit = input_scrub_next_buffer (&buffer) )
  225. { /* We have another line to parse. */
  226. know( buffer_limit [-1] == '\n' ); /* Must have a sentinel. */
  227. input_line_pointer = buffer;
  228. contin: /* JF this goto is my fault I admit it. Someone brave please re-write
  229. the whole input section here? Pleeze??? */
  230. while ( input_line_pointer < buffer_limit )
  231. { /* We have more of this buffer to parse. */
  232. /*
  233. * We now have input_line_pointer -> 1st char of next line.
  234. * If input_line_pointer [-1] == '\n' then we just
  235. * scanned another line: so bump line counters.
  236. */
  237. if (input_line_pointer [-1] == '\n')
  238. {
  239. bump_line_counters ();
  240. }
  241. /*
  242. * We are at the begining of a line, or similar place.
  243. * We expect a well-formed assembler statement.
  244. * A "symbol-name:" is a statement.
  245. *
  246. * Depending on what compiler is used, the order of these tests
  247. * may vary to catch most common case 1st.
  248. * Each test is independent of all other tests at the (top) level.
  249. * PLEASE make a compiler that doesn't use this assembler.
  250. * It is crufty to waste a compiler's time encoding things for this
  251. * assembler, which then wastes more time decoding it.
  252. * (And communicating via (linear) files is silly!
  253. * If you must pass stuff, please pass a tree!)
  254. */
  255. if ( (c= * input_line_pointer ++) == '\t' || c == ' ' || c=='\f')
  256. {
  257. c = * input_line_pointer ++;
  258. }
  259. know( c != ' ' ); /* No further leading whitespace. */
  260. /*
  261. * C is the 1st significant character.
  262. * Input_line_pointer points after that character.
  263. */
  264. if ( is_name_beginner(c) )
  265. { /* want user-defined label or pseudo/opcode */
  266. s = -- input_line_pointer;
  267. c = get_symbol_end(); /* name's delimiter */
  268. /*
  269. * C is character after symbol.
  270. * That character's place in the input line is now '\0'.
  271. * S points to the beginning of the symbol.
  272. * [In case of pseudo-op, s -> '.'.]
  273. * Input_line_pointer -> '\0' where c was.
  274. */
  275. if ( c == ':' )
  276. {
  277. colon(s); /* user-defined label */
  278. * input_line_pointer ++ = ':'; /* Put ':' back for error messages' sake. */
  279. /* Input_line_pointer -> after ':'. */
  280. SKIP_WHITESPACE();
  281. }
  282. else if(c=='=' || input_line_pointer[1]=='=') /* JF deal with FOO=BAR */
  283. {
  284. equals(s);
  285. demand_empty_rest_of_line();
  286. }
  287. else
  288. { /* expect pseudo-op or machine instruction */
  289. if ( *s=='.' )
  290. {
  291. /*
  292. * PSEUDO - OP.
  293. *
  294. * WARNING: c has next char, which may be end-of-line.
  295. * We lookup the pseudo-op table with s+1 because we
  296. * already know that the pseudo-op begins with a '.'.
  297. */
  298. pop= (pseudo_typeS *) hash_find (po_hash, s+1);
  299. /* Put it back for error messages etc. */
  300. * input_line_pointer = c;
  301. /* The following skip of whitespace is compulsory. */
  302. /* A well shaped space is sometimes all that seperates keyword from operands. */
  303. if ( c == ' ' || c == '\t' )
  304. { /* Skip seperator after keyword. */
  305. input_line_pointer ++;
  306. }
  307. /*
  308. * Input_line is restored.
  309. * Input_line_pointer -> 1st non-blank char
  310. * after pseudo-operation.
  311. */
  312. if(!pop) {
  313. as_warn("Unknown pseudo-op");
  314. ignore_rest_of_line();
  315. break;
  316. }
  317. else
  318. (*pop->poc_handler)(pop->poc_val);
  319. }
  320. else
  321. { /* machine instruction */
  322. /* WARNING: c has char, which may be end-of-line. */
  323. /* Also: input_line_pointer -> `\0` where c was. */
  324. * input_line_pointer = c;
  325. while ( ! is_end_of_line [* input_line_pointer] )
  326. {
  327. input_line_pointer ++;
  328. }
  329. c = * input_line_pointer;
  330. * input_line_pointer = '\0';
  331. md_assemble (s); /* Assemble 1 instruction. */
  332. * input_line_pointer ++ = c;
  333. /* We resume loop AFTER the end-of-line from this instruction */
  334. } /* if (*s=='.') */
  335. } /* if c==':' */
  336. continue;
  337. } /* if (is_name_beginner(c) */
  338. if ( is_end_of_line [c] )
  339. { /* empty statement */
  340. continue;
  341. }
  342. if ( isdigit(c) )
  343. { /* local label ("4:") */
  344. temp = c - '0';
  345. #ifdef SUN_ASM_SYNTAX
  346. if( *input_line_pointer=='$')
  347. input_line_pointer++;
  348. #endif
  349. if ( * input_line_pointer ++ == ':' )
  350. {
  351. local_colon (temp);
  352. }
  353. else
  354. {
  355. as_warn( "Spurious digit %d.", temp);
  356. input_line_pointer -- ;
  357. ignore_rest_of_line();
  358. }
  359. continue;
  360. }
  361. if(c && index(line_comment_chars,c)) { /* Its a comment. Better say APP or NO_APP */
  362. char *ends;
  363. char *strstr();
  364. char *new_buf;
  365. char *new_tmp;
  366. int new_length;
  367. char *tmp_buf = 0;
  368. extern char *scrub_string,*scrub_last_string;
  369. int scrub_from_string();
  370. void scrub_to_string();
  371. bump_line_counters();
  372. s=input_line_pointer;
  373. if(strncmp(s,"APP\n",4))
  374. continue; /* We ignore it */
  375. s+=4;
  376. ends=strstr(s,"#NO_APP\n");
  377. if(!ends) {
  378. int tmp_len;
  379. int num;
  380. /* The end of the #APP wasn't in this buffer. We
  381. keep reading in buffers until we find the #NO_APP
  382. that goes with this #APP There is one. The specs
  383. guarentee it. . .*/
  384. tmp_len=buffer_limit-s;
  385. tmp_buf=xmalloc(tmp_len);
  386. bcopy(s,tmp_buf,tmp_len);
  387. do {
  388. new_tmp = input_scrub_next_buffer(&buffer);
  389. if(!new_tmp)
  390. break;
  391. else
  392. buffer_limit = new_tmp;
  393. input_line_pointer = buffer;
  394. ends = strstr(buffer,"#NO_APP\n");
  395. if(ends)
  396. num=ends-buffer;
  397. else
  398. num=buffer_limit-buffer;
  399. tmp_buf=xrealloc(tmp_buf,tmp_len+num);
  400. bcopy(buffer,tmp_buf+tmp_len,num);
  401. tmp_len+=num;
  402. } while(!ends);
  403. input_line_pointer= ends ? ends+8 : NULL;
  404. s=tmp_buf;
  405. ends=s+tmp_len;
  406. } else {
  407. input_line_pointer=ends+8;
  408. }
  409. new_buf=xmalloc(100);
  410. new_length=100;
  411. new_tmp=new_buf;
  412. scrub_string=s;
  413. scrub_last_string = ends;
  414. for(;;) {
  415. int ch;
  416. ch=do_scrub_next_char(scrub_from_string,scrub_to_string);
  417. if(ch==EOF) break;
  418. *new_tmp++=ch;
  419. if(new_tmp==new_buf+new_length) {
  420. new_buf=xrealloc(new_buf,new_length+100);
  421. new_tmp=new_buf+new_length;
  422. new_length+=100;
  423. }
  424. }
  425. if(tmp_buf)
  426. free(tmp_buf);
  427. old_buffer=buffer;
  428. old_input=input_line_pointer;
  429. old_limit=buffer_limit;
  430. buffer=new_buf;
  431. input_line_pointer=new_buf;
  432. buffer_limit=new_tmp;
  433. continue;
  434. }
  435. as_warn("Junk character %d.",c);
  436. ignore_rest_of_line();
  437. } /* while (input_line_pointer<buffer_limit )*/
  438. if(old_buffer) {
  439. bump_line_counters();
  440. if(old_input == 0)
  441. return;
  442. buffer=old_buffer;
  443. input_line_pointer=old_input;
  444. buffer_limit=old_limit;
  445. old_buffer = 0;
  446. goto contin;
  447. }
  448. } /* while (more bufrers to scan) */
  449. } /* read_a_source_file() */
  450. void
  451. s_abort()
  452. {
  453. as_fatal(".abort detected. Abandoning ship.");
  454. }
  455. void
  456. s_align()
  457. {
  458. register int temp;
  459. register long int temp_fill;
  460. temp = get_absolute_expression ();
  461. #define MAX_ALIGNMENT (15)
  462. if ( temp > MAX_ALIGNMENT )
  463. as_warn("Alignment too large: %d. assumed.", temp = MAX_ALIGNMENT);
  464. else if ( temp < 0 ) {
  465. as_warn("Alignment negative. 0 assumed.");
  466. temp = 0;
  467. }
  468. if ( *input_line_pointer == ',' ) {
  469. input_line_pointer ++;
  470. temp_fill = get_absolute_expression ();
  471. } else
  472. temp_fill = 0;
  473. /* Only make a frag if we HAVE to. . . */
  474. if ( temp && ! need_pass_2 )
  475. frag_align (temp, (int)temp_fill);
  476. demand_empty_rest_of_line();
  477. }
  478. void
  479. s_comm()
  480. {
  481. register char *name;
  482. register char c;
  483. register char *p;
  484. register int temp;
  485. register symbolS * symbolP;
  486. name = input_line_pointer;
  487. c = get_symbol_end();
  488. /* just after name is now '\0' */
  489. p = input_line_pointer;
  490. *p = c;
  491. SKIP_WHITESPACE();
  492. if ( * input_line_pointer != ',' ) {
  493. as_warn("Expected comma after symbol-name");
  494. ignore_rest_of_line();
  495. return;
  496. }
  497. input_line_pointer ++; /* skip ',' */
  498. if ( (temp = get_absolute_expression ()) < 0 ) {
  499. as_warn(".COMMon length (%d.) <0! Ignored.", temp);
  500. ignore_rest_of_line();
  501. return;
  502. }
  503. *p = 0;
  504. symbolP = symbol_find_or_make (name);
  505. *p = c;
  506. if ( (symbolP -> sy_type & N_TYPE) != N_UNDF ||
  507. symbolP -> sy_other != 0 || symbolP -> sy_desc != 0) {
  508. as_warn( "Ignoring attempt to re-define symbol");
  509. ignore_rest_of_line();
  510. return;
  511. }
  512. if (symbolP -> sy_value) {
  513. if (symbolP -> sy_value != temp)
  514. as_warn( "Length of .comm \"%s\" is already %d. Not changed to %d.",
  515. symbolP -> sy_name, symbolP -> sy_value, temp);
  516. } else {
  517. symbolP -> sy_value = temp;
  518. symbolP -> sy_type |= N_EXT;
  519. }
  520. know( symbolP -> sy_frag == &zero_address_frag );
  521. demand_empty_rest_of_line();
  522. }
  523. void
  524. s_data()
  525. {
  526. register int temp;
  527. temp = get_absolute_expression ();
  528. subseg_new (SEG_DATA, (subsegT)temp);
  529. demand_empty_rest_of_line();
  530. }
  531. void
  532. s_desc()
  533. {
  534. register char *name;
  535. register char c;
  536. register char *p;
  537. register symbolS * symbolP;
  538. register int temp;
  539. /*
  540. * Frob invented at RMS' request. Set the n_desc of a symbol.
  541. */
  542. name = input_line_pointer;
  543. c = get_symbol_end();
  544. p = input_line_pointer;
  545. symbolP = symbol_table_lookup (name);
  546. * p = c;
  547. SKIP_WHITESPACE();
  548. if ( * input_line_pointer != ',' ) {
  549. *p = 0;
  550. as_warn("Expected comma after name \"%s\"", name);
  551. *p = c;
  552. ignore_rest_of_line();
  553. } else {
  554. input_line_pointer ++;
  555. temp = get_absolute_expression ();
  556. *p = 0;
  557. symbolP = symbol_find_or_make (name);
  558. *p = c;
  559. symbolP -> sy_desc = temp;
  560. }
  561. demand_empty_rest_of_line();
  562. }
  563. void
  564. s_file()
  565. {
  566. register char *s;
  567. int length;
  568. /* Some assemblers tolerate immediately following '"' */
  569. if ( s = demand_copy_string( & length ) ) {
  570. new_logical_line (s, -1);
  571. demand_empty_rest_of_line();
  572. }
  573. }
  574. void
  575. s_fill()
  576. {
  577. long int temp_repeat;
  578. long int temp_size;
  579. register long int temp_fill;
  580. char *p;
  581. if ( get_absolute_expression_and_terminator(& temp_repeat) != ',' ) {
  582. input_line_pointer --; /* Backup over what was not a ','. */
  583. as_warn("Expect comma after rep-size in .fill");
  584. ignore_rest_of_line();
  585. return;
  586. }
  587. if ( get_absolute_expression_and_terminator( & temp_size) != ',' ) {
  588. input_line_pointer --; /* Backup over what was not a ','. */
  589. as_warn("Expected comma after size in .fill");
  590. ignore_rest_of_line();
  591. return;
  592. }
  593. /*
  594. * This is to be compatible with BSD 4.2 AS, not for any rational reason.
  595. */
  596. #define BSD_FILL_SIZE_CROCK_8 (8)
  597. if ( temp_size > BSD_FILL_SIZE_CROCK_8 ) {
  598. as_warn(".fill size clamped to %d.", BSD_FILL_SIZE_CROCK_8);
  599. temp_size = BSD_FILL_SIZE_CROCK_8 ;
  600. } if ( temp_size < 0 ) {
  601. as_warn("Size negative: .fill ignored.");
  602. temp_size = 0;
  603. } else if ( temp_repeat <= 0 ) {
  604. as_warn("Repeat < 0, .fill ignored");
  605. temp_size = 0;
  606. }
  607. temp_fill = get_absolute_expression ();
  608. if ( temp_size && !need_pass_2 ) {
  609. p = frag_var (rs_fill, (int)temp_size, (int)temp_size, (relax_substateT)0, (symbolS *)0, temp_repeat, (char *)0);
  610. bzero (p, (int)temp_size);
  611. /*
  612. * The magic number BSD_FILL_SIZE_CROCK_4 is from BSD 4.2 VAX flavoured AS.
  613. * The following bizzare behaviour is to be compatible with above.
  614. * I guess they tried to take up to 8 bytes from a 4-byte expression
  615. * and they forgot to sign extend. Un*x Sux.
  616. */
  617. #define BSD_FILL_SIZE_CROCK_4 (4)
  618. md_number_to_chars (p, temp_fill, temp_size > BSD_FILL_SIZE_CROCK_4 ? BSD_FILL_SIZE_CROCK_4 : (int)temp_size);
  619. /*
  620. * Note: .fill (),0 emits no frag (since we are asked to .fill 0 bytes)
  621. * but emits no error message because it seems a legal thing to do.
  622. * It is a degenerate case of .fill but could be emitted by a compiler.
  623. */
  624. }
  625. demand_empty_rest_of_line();
  626. }
  627. void
  628. s_gdbbeg()
  629. {
  630. register int temp;
  631. temp = get_absolute_expression ();
  632. if (temp < 0)
  633. as_warn( "Block number <0. Ignored." );
  634. else if (flagseen ['G'])
  635. gdb_block_beg ( (long int) temp, frag_now, (long int)(obstack_next_free(& frags) - frag_now -> fr_literal));
  636. demand_empty_rest_of_line ();
  637. }
  638. void
  639. s_gdbblock()
  640. {
  641. register int position;
  642. int temp;
  643. if (get_absolute_expression_and_terminator (&temp) != ',') {
  644. as_warn( "expected comma before position in .gdbblock");
  645. --input_line_pointer;
  646. ignore_rest_of_line ();
  647. return;
  648. }
  649. position = get_absolute_expression ();
  650. if (flagseen ['G'])
  651. gdb_block_position ((long int) temp, (long int) position);
  652. demand_empty_rest_of_line ();
  653. }
  654. void
  655. s_gdbend()
  656. {
  657. register int temp;
  658. temp = get_absolute_expression ();
  659. if (temp < 0)
  660. as_warn( "Block number <0. Ignored." );
  661. else if (flagseen ['G'])
  662. gdb_block_end ( (long int) temp, frag_now, (long int)(obstack_next_free(& frags) - frag_now -> fr_literal));
  663. demand_empty_rest_of_line ();
  664. }
  665. void
  666. s_gdbsym()
  667. {
  668. register char *name,
  669. *p;
  670. register char c;
  671. register symbolS * symbolP;
  672. register int temp;
  673. name = input_line_pointer;
  674. c = get_symbol_end();
  675. p = input_line_pointer;
  676. symbolP = symbol_find_or_make (name);
  677. *p = c;
  678. SKIP_WHITESPACE();
  679. if ( * input_line_pointer != ',' ) {
  680. as_warn("Expected comma after name");
  681. ignore_rest_of_line();
  682. return;
  683. }
  684. input_line_pointer ++;
  685. if ( (temp = get_absolute_expression ()) < 0 ) {
  686. as_warn("Bad GDB symbol file offset (%d.) <0! Ignored.", temp);
  687. ignore_rest_of_line();
  688. return;
  689. }
  690. if (flagseen ['G'])
  691. gdb_symbols_fixup (symbolP, (long int)temp);
  692. demand_empty_rest_of_line ();
  693. }
  694. void
  695. s_gdbline()
  696. {
  697. int file_number,
  698. lineno;
  699. if(get_absolute_expression_and_terminator(&file_number) != ',') {
  700. as_warn("expected comman after filenum in .gdbline");
  701. ignore_rest_of_line();
  702. return;
  703. }
  704. lineno=get_absolute_expression();
  705. if(flagseen['G'])
  706. gdb_line(file_number,lineno);
  707. demand_empty_rest_of_line();
  708. }
  709. void
  710. s_gdblinetab()
  711. {
  712. int file_number,
  713. offset;
  714. if(get_absolute_expression_and_terminator(&file_number) != ',') {
  715. as_warn("expected comman after filenum in .gdblinetab");
  716. ignore_rest_of_line();
  717. return;
  718. }
  719. offset=get_absolute_expression();
  720. if(flagseen['G'])
  721. gdb_line_tab(file_number,offset);
  722. demand_empty_rest_of_line();
  723. }
  724. void
  725. s_globl()
  726. {
  727. register char *name;
  728. register int c;
  729. register symbolS * symbolP;
  730. do {
  731. name = input_line_pointer;
  732. c = get_symbol_end();
  733. symbolP = symbol_find_or_make (name);
  734. * input_line_pointer = c;
  735. SKIP_WHITESPACE();
  736. symbolP -> sy_type |= N_EXT;
  737. if(c==',') {
  738. input_line_pointer++;
  739. SKIP_WHITESPACE();
  740. if(*input_line_pointer=='\n')
  741. c='\n';
  742. }
  743. } while(c==',');
  744. demand_empty_rest_of_line();
  745. }
  746. void
  747. s_lcomm()
  748. {
  749. register char *name;
  750. register char c;
  751. register char *p;
  752. register int temp;
  753. register symbolS * symbolP;
  754. name = input_line_pointer;
  755. c = get_symbol_end();
  756. p = input_line_pointer;
  757. *p = c;
  758. SKIP_WHITESPACE();
  759. if ( * input_line_pointer != ',' ) {
  760. as_warn("Expected comma after name");
  761. ignore_rest_of_line();
  762. return;
  763. }
  764. input_line_pointer ++;
  765. if ( (temp = get_absolute_expression ()) < 0 ) {
  766. as_warn("BSS length (%d.) <0! Ignored.", temp);
  767. ignore_rest_of_line();
  768. return;
  769. }
  770. *p = 0;
  771. symbolP = symbol_find_or_make (name);
  772. *p = c;
  773. if ( symbolP -> sy_other == 0
  774. && symbolP -> sy_desc == 0
  775. && ( ( symbolP -> sy_type == N_BSS
  776. && symbolP -> sy_value == local_bss_counter)
  777. || ( (symbolP -> sy_type & N_TYPE) == N_UNDF
  778. && symbolP -> sy_value == 0))) {
  779. symbolP -> sy_value = local_bss_counter;
  780. symbolP -> sy_type = N_BSS;
  781. symbolP -> sy_frag = & bss_address_frag;
  782. local_bss_counter += temp;
  783. } else
  784. as_warn( "Ignoring attempt to re-define symbol from %d. to %d.",
  785. symbolP -> sy_value, local_bss_counter );
  786. demand_empty_rest_of_line();
  787. }
  788. void
  789. s_line()
  790. {
  791. /* Assume delimiter is part of expression. */
  792. /* BSD4.2 as fails with delightful bug, so we */
  793. /* are not being incompatible here. */
  794. new_logical_line ((char *)NULL, (int)(get_absolute_expression ()));
  795. demand_empty_rest_of_line();
  796. }
  797. void
  798. s_long()
  799. {
  800. cons(4);
  801. }
  802. void
  803. s_int()
  804. {
  805. cons(4);
  806. }
  807. void
  808. s_lsym()
  809. {
  810. register char *name;
  811. register char c;
  812. register char *p;
  813. register segT segment;
  814. expressionS exp;
  815. register symbolS *symbolP;
  816. /* we permit ANY expression: BSD4.2 demands constants */
  817. name = input_line_pointer;
  818. c = get_symbol_end();
  819. p = input_line_pointer;
  820. *p = c;
  821. SKIP_WHITESPACE();
  822. if ( * input_line_pointer != ',' ) {
  823. *p = 0;
  824. as_warn("Expected comma after name \"%s\"", name);
  825. *p = c;
  826. ignore_rest_of_line();
  827. return;
  828. }
  829. input_line_pointer ++;
  830. segment = expression (& exp);
  831. if ( segment != SEG_ABSOLUTE && segment != SEG_DATA &&
  832. segment != SEG_TEXT && segment != SEG_BSS) {
  833. as_warn("Bad expression: %s", seg_name [(int)segment]);
  834. ignore_rest_of_line();
  835. return;
  836. }
  837. know( segment == SEG_ABSOLUTE || segment == SEG_DATA || segment == SEG_TEXT || segment == SEG_BSS );
  838. *p = 0;
  839. symbolP = symbol_new (name,(unsigned char)(seg_N_TYPE [(int) segment]),
  840. 0, 0, (valueT)(exp . X_add_number), & zero_address_frag);
  841. *p = c;
  842. demand_empty_rest_of_line();
  843. }
  844. void
  845. s_org()
  846. {
  847. register segT segment;
  848. expressionS exp;
  849. register long int temp_fill;
  850. register char *p;
  851. /*
  852. * Don't believe the documentation of BSD 4.2 AS.
  853. * There is no such thing as a sub-segment-relative origin.
  854. * Any absolute origin is given a warning, then assumed to be segment-relative.
  855. * Any segmented origin expression ("foo+42") had better be in the right
  856. * segment or the .org is ignored.
  857. *
  858. * BSD 4.2 AS warns if you try to .org backwards. We cannot because we
  859. * never know sub-segment sizes when we are reading code.
  860. * BSD will crash trying to emit -ve numbers of filler bytes in certain
  861. * .orgs. We don't crash, but see as-write for that code.
  862. */
  863. /*
  864. * Don't make frag if need_pass_2==TRUE.
  865. */
  866. segment = get_known_segmented_expression(& exp);
  867. if ( *input_line_pointer == ',' ) {
  868. input_line_pointer ++;
  869. temp_fill = get_absolute_expression ();
  870. } else
  871. temp_fill = 0;
  872. if ( ! need_pass_2 ) {
  873. if (segment != now_seg && segment != SEG_ABSOLUTE)
  874. as_warn("Illegal segment \"%s\". Segment \"%s\" assumed.",
  875. seg_name [(int) segment], seg_name [(int) now_seg]);
  876. p = frag_var (rs_org, 1, 1, (relax_substateT)0, exp . X_add_symbol,
  877. exp . X_add_number, (char *)0);
  878. * p = temp_fill;
  879. } /* if (ok to make frag) */
  880. demand_empty_rest_of_line();
  881. }
  882. void
  883. s_set()
  884. {
  885. register char *name;
  886. register char delim;
  887. register char *end_name;
  888. register symbolS *symbolP;
  889. /*
  890. * Especial apologies for the random logic:
  891. * this just grew, and could be parsed much more simply!
  892. * Dean in haste.
  893. */
  894. name = input_line_pointer;
  895. delim = get_symbol_end();
  896. end_name = input_line_pointer;
  897. *end_name = delim;
  898. SKIP_WHITESPACE();
  899. if ( * input_line_pointer != ',' ) {
  900. *end_name = 0;
  901. as_warn("Expected comma after name \"%s\"", name);
  902. *end_name = delim;
  903. ignore_rest_of_line();
  904. return;
  905. }
  906. input_line_pointer ++;
  907. *end_name = 0;
  908. if(name[0]=='.' && name[1]=='\0') {
  909. /* Turn '. = mumble' into a .org mumble */
  910. register segT segment;
  911. expressionS exp;
  912. register char *ptr;
  913. segment = get_known_segmented_expression(& exp);
  914. if ( ! need_pass_2 ) {
  915. if (segment != now_seg && segment != SEG_ABSOLUTE)
  916. as_warn("Illegal segment \"%s\". Segment \"%s\" assumed.",
  917. seg_name [(int) segment], seg_name [(int) now_seg]);
  918. ptr = frag_var (rs_org, 1, 1, (relax_substateT)0, exp.X_add_symbol,
  919. exp.X_add_number, (char *)0);
  920. *ptr= 0;
  921. } /* if (ok to make frag) */
  922. *end_name = delim;
  923. return;
  924. }
  925. symbolP = symbol_find_or_make (name);
  926. *end_name = delim;
  927. pseudo_set (symbolP);
  928. demand_empty_rest_of_line ();
  929. }
  930. void
  931. s_space()
  932. {
  933. long int temp_repeat;
  934. register long int temp_fill;
  935. register char *p;
  936. /* Just like .fill, but temp_size = 1 */
  937. if ( get_absolute_expression_and_terminator( & temp_repeat) == ',' ) {
  938. temp_fill = get_absolute_expression ();
  939. } else {
  940. input_line_pointer --; /* Backup over what was not a ','. */
  941. temp_fill = 0;
  942. }
  943. if ( temp_repeat <= 0 ) {
  944. as_warn("Repeat < 0, .space ignored");
  945. ignore_rest_of_line();
  946. return;
  947. }
  948. if ( ! need_pass_2 ) {
  949. p = frag_var (rs_fill, 1, 1, (relax_substateT)0, (symbolS *)0,
  950. temp_repeat, (char *)0);
  951. * p = temp_fill;
  952. }
  953. demand_empty_rest_of_line();
  954. }
  955. void
  956. s_text()
  957. {
  958. register int temp;
  959. temp = get_absolute_expression ();
  960. subseg_new (SEG_TEXT, (subsegT)temp);
  961. demand_empty_rest_of_line();
  962. }
  963. /*( JF was static, but can't be if machine dependent pseudo-ops are to use it */
  964. void
  965. demand_empty_rest_of_line()
  966. {
  967. SKIP_WHITESPACE();
  968. if ( is_end_of_line [* input_line_pointer] )
  969. {
  970. input_line_pointer ++;
  971. }
  972. else
  973. {
  974. ignore_rest_of_line();
  975. }
  976. /* Return having already swallowed end-of-line. */
  977. } /* Return pointing just after end-of-line. */
  978. void
  979. ignore_rest_of_line() /* For suspect lines: gives warning. */
  980. {
  981. if ( ! is_end_of_line [* input_line_pointer])
  982. {
  983. as_warn("Rest of line ignored. 1st junk character valued %d."
  984. , * input_line_pointer);
  985. while ( input_line_pointer < buffer_limit
  986. && ! is_end_of_line [* input_line_pointer] )
  987. {
  988. input_line_pointer ++;
  989. }
  990. }
  991. input_line_pointer ++; /* Return pointing just after end-of-line. */
  992. know( is_end_of_line [input_line_pointer [-1]] );
  993. }
  994. /*
  995. * stab()
  996. *
  997. * Handle .stabX directives, which used to be open-coded.
  998. * So much creeping featurism overloaded the semantics that we decided
  999. * to put all .stabX thinking in one place. Here.
  1000. *
  1001. * We try to make any .stabX directive legal. Other people's AS will often
  1002. * do assembly-time consistency checks: eg assigning meaning to n_type bits
  1003. * and "protecting" you from setting them to certain values. (They also zero
  1004. * certain bits before emitting symbols. Tut tut.)
  1005. *
  1006. * If an expression is not absolute we either gripe or use the relocation
  1007. * information. Other people's assemblers silently forget information they
  1008. * don't need and invent information they need that you didn't supply.
  1009. *
  1010. * .stabX directives always make a symbol table entry. It may be junk if
  1011. * the rest of your .stabX directive is malformed.
  1012. */
  1013. static void
  1014. stab (what)
  1015. int what;
  1016. {
  1017. register symbolS * symbolP;
  1018. register char * string;
  1019. int saved_type;
  1020. int length;
  1021. int goof; /* TRUE if we have aborted. */
  1022. long int longint;
  1023. /*
  1024. * Enter with input_line_pointer pointing past .stabX and any following
  1025. * whitespace.
  1026. */
  1027. goof = FALSE; /* JF who forgot this?? */
  1028. if (what == 's') {
  1029. string = demand_copy_C_string (& length);
  1030. SKIP_WHITESPACE();
  1031. if (* input_line_pointer == ',')
  1032. input_line_pointer ++;
  1033. else {
  1034. as_warn( "I need a comma after symbol's name" );
  1035. goof = TRUE;
  1036. }
  1037. } else
  1038. string = "";
  1039. /*
  1040. * Input_line_pointer->after ','. String -> symbol name.
  1041. */
  1042. if (! goof) {
  1043. symbolP = symbol_new (string, 0,0,0,0,(struct frag *)0);
  1044. switch (what) {
  1045. case 'd':
  1046. symbolP->sy_name = NULL; /* .stabd feature. */
  1047. symbolP->sy_value = obstack_next_free(& frags) - frag_now->fr_literal;
  1048. symbolP->sy_frag = frag_now;
  1049. break;
  1050. case 'n':
  1051. symbolP->sy_frag = &zero_address_frag;
  1052. break;
  1053. case 's':
  1054. symbolP->sy_frag = & zero_address_frag;
  1055. break;
  1056. default:
  1057. BAD_CASE( what );
  1058. break;
  1059. }
  1060. if (get_absolute_expression_and_terminator (& longint) == ',')
  1061. symbolP->sy_type = saved_type = longint;
  1062. else {
  1063. as_warn( "I want a comma after the n_type expression" );
  1064. goof = TRUE;
  1065. input_line_pointer --; /* Backup over a non-',' char. */
  1066. }
  1067. }
  1068. if (! goof) {
  1069. if (get_absolute_expression_and_terminator (& longint) == ',')
  1070. symbolP->sy_other = longint;
  1071. else {
  1072. as_warn( "I want a comma after the n_other expression" );
  1073. goof = TRUE;
  1074. input_line_pointer --; /* Backup over a non-',' char. */
  1075. }
  1076. }
  1077. if (! goof) {
  1078. symbolP->sy_desc = get_absolute_expression ();
  1079. if (what == 's' || what == 'n') {
  1080. if (* input_line_pointer != ',') {
  1081. as_warn( "I want a comma after the n_desc expression" );
  1082. goof = TRUE;
  1083. } else {
  1084. input_line_pointer ++;
  1085. }
  1086. }
  1087. }
  1088. if ((! goof) && (what=='s' || what=='n')) {
  1089. pseudo_set (symbolP);
  1090. symbolP->sy_type = saved_type;
  1091. }
  1092. if (goof)
  1093. ignore_rest_of_line ();
  1094. else
  1095. demand_empty_rest_of_line ();
  1096. }
  1097. /*
  1098. * pseudo_set()
  1099. *
  1100. * In: Pointer to a symbol.
  1101. * Input_line_pointer -> expression.
  1102. *
  1103. * Out: Input_line_pointer -> just after any whitespace after expression.
  1104. * Tried to set symbol to value of expression.
  1105. * Will change sy_type, sy_value, sy_frag;
  1106. * May set need_pass_2 == TRUE.
  1107. */
  1108. static void
  1109. pseudo_set (symbolP)
  1110. symbolS * symbolP;
  1111. {
  1112. expressionS exp;
  1113. register segT segment;
  1114. know( symbolP ); /* NULL pointer is logic error. */
  1115. if ((segment = expression( & exp )) == SEG_NONE)
  1116. {
  1117. as_warn( "Missing expression: absolute 0 assumed" );
  1118. exp . X_seg = SEG_ABSOLUTE;
  1119. exp . X_add_number = 0;
  1120. }
  1121. switch (segment)
  1122. {
  1123. case SEG_BIG:
  1124. as_warn( "%s number illegal. Absolute 0 assumed.",
  1125. exp . X_add_number > 0 ? "Bignum" : "Floating-Point" );
  1126. symbolP -> sy_type = N_ABS;
  1127. symbolP -> sy_value = 0;
  1128. symbolP -> sy_frag = & zero_address_frag;
  1129. break;
  1130. case SEG_NONE:
  1131. as_warn("No expression: Using absolute 0");
  1132. symbolP -> sy_type = N_ABS;
  1133. symbolP -> sy_value = 0;
  1134. symbolP -> sy_frag = & zero_address_frag;
  1135. break;
  1136. case SEG_DIFFERENCE:
  1137. if (exp.X_add_symbol && exp.X_subtract_symbol
  1138. && (exp.X_add_symbol->sy_type & N_TYPE)
  1139. == (exp.X_subtract_symbol->sy_type & N_TYPE))
  1140. exp.X_add_number+=exp.X_add_symbol->sy_value - exp.X_subtract_symbol->sy_value;
  1141. else
  1142. as_warn( "Complex expression. Absolute segment assumed." );
  1143. case SEG_ABSOLUTE:
  1144. symbolP -> sy_type = N_ABS;
  1145. symbolP -> sy_value = exp . X_add_number;
  1146. symbolP -> sy_frag = & zero_address_frag;
  1147. break;
  1148. case SEG_DATA:
  1149. case SEG_TEXT:
  1150. case SEG_BSS:
  1151. symbolP -> sy_type = seg_N_TYPE [(int) segment];
  1152. symbolP -> sy_value= exp . X_add_number + exp . X_add_symbol -> sy_value;
  1153. symbolP -> sy_frag = exp . X_add_symbol -> sy_frag;
  1154. break;
  1155. case SEG_PASS1: /* Not an error. Just try another pass. */
  1156. symbolP->sy_forward=exp.X_add_symbol;
  1157. as_warn("Unknown expression");
  1158. know( need_pass_2 == TRUE );
  1159. break;
  1160. case SEG_UNKNOWN:
  1161. symbolP->sy_forward=exp.X_add_symbol;
  1162. /* as_warn("unknown symbol"); */
  1163. /* need_pass_2 = TRUE; */
  1164. break;
  1165. default:
  1166. BAD_CASE( segment );
  1167. break;
  1168. }
  1169. }
  1170. /*
  1171. * cons()
  1172. *
  1173. * CONStruct more frag of .bytes, or .words etc.
  1174. * Should need_pass_2 be TRUE then emit no frag(s).
  1175. * This understands EXPRESSIONS, as opposed to big_cons().
  1176. *
  1177. * Bug (?)
  1178. *
  1179. * This has a split personality. We use expression() to read the
  1180. * value. We can detect if the value won't fit in a byte or word.
  1181. * But we can't detect if expression() discarded significant digits
  1182. * in the case of a long. Not worth the crocks required to fix it.
  1183. */
  1184. void
  1185. cons(nbytes) /* worker to do .byte etc statements */
  1186. /* clobbers input_line_pointer, checks */
  1187. /* end-of-line. */
  1188. register int nbytes; /* 1=.byte, 2=.word, 4=.long */
  1189. {
  1190. register char c;
  1191. register long int mask; /* High-order bits we will left-truncate, */
  1192. /* but includes sign bit also. */
  1193. register long int get; /* what we get */
  1194. register long int use; /* get after truncation. */
  1195. register long int unmask; /* what bits we will store */
  1196. register char * p;
  1197. register segT segment;
  1198. expressionS exp;
  1199. #ifdef NS32K
  1200. void fix_new_ns32k();
  1201. #else
  1202. void fix_new();
  1203. #endif
  1204. /*
  1205. * Input_line_pointer -> 1st char after pseudo-op-code and could legally
  1206. * be a end-of-line. (Or, less legally an eof - which we cope with.)
  1207. */
  1208. /* JF << of >= number of bits in the object is undefined. In particular
  1209. SPARC (Sun 4) has problems */
  1210. if(nbytes>=sizeof(long int))
  1211. mask = 0;
  1212. else
  1213. mask = ~0 << (BITS_PER_CHAR * nbytes); /* Don't store these bits. */
  1214. unmask = ~ mask; /* Do store these bits. */
  1215. #ifdef NEVER
  1216. "Do this mod if you want every overflow check to assume SIGNED 2's complement data.";
  1217. mask = ~ (unmask >> 1); /* Includes sign bit now. */
  1218. #endif
  1219. /*
  1220. * The following awkward logic is to parse ZERO or more expressions,
  1221. * comma seperated. Recall an expression includes its leading &
  1222. * trailing blanks. We fake a leading ',' if there is (supposed to
  1223. * be) a 1st expression, and keep demanding 1 expression for each ','.
  1224. */
  1225. if (is_it_end_of_statement())
  1226. {
  1227. c = 0; /* Skip loop. */
  1228. input_line_pointer ++; /* Matches end-of-loop 'correction'. */
  1229. }
  1230. else
  1231. c = ','; /* Do loop. */
  1232. while ( c == ',' )
  1233. {
  1234. segment = expression( &exp ); /* At least scan over the expression. */
  1235. if ( ! need_pass_2 )
  1236. { /* Still worthwhile making frags. */
  1237. /* Don't call this if we are going to junk this pass anyway! */
  1238. know( segment != SEG_PASS1 );
  1239. if ( segment == SEG_DIFFERENCE && exp . X_add_symbol == NULL )
  1240. {
  1241. as_warn( "Subtracting symbol \"%s\"(segment\"%s\") is too hard. Absolute segment assumed.",
  1242. exp . X_subtract_symbol -> sy_name,
  1243. seg_name [(int) N_TYPE_seg [exp . X_subtract_symbol -> sy_type & N_TYPE]]);
  1244. segment = SEG_ABSOLUTE;
  1245. /* Leave exp . X_add_number alone. */
  1246. }
  1247. p = frag_more (nbytes);
  1248. switch (segment)
  1249. {
  1250. case SEG_BIG:
  1251. as_warn( "%s number illegal. Absolute 0 assumed.",
  1252. exp . X_add_number > 0 ? "Bignum" : "Floating-Point");
  1253. md_number_to_chars (p, (long)0, nbytes);
  1254. break;
  1255. case SEG_NONE:
  1256. as_warn( "0 assumed for missing expression" );
  1257. exp . X_add_number = 0;
  1258. know( exp . X_add_symbol == NULL );
  1259. /* fall into SEG_ABSOLUTE */
  1260. case SEG_ABSOLUTE:
  1261. get = exp . X_add_number;
  1262. use = get & unmask;
  1263. if ( (get & mask) && (get & mask) != mask )
  1264. { /* Leading bits contain both 0s & 1s. */
  1265. as_warn("Value x%x truncated to x%x.", get, use);
  1266. }
  1267. md_number_to_chars (p, use, nbytes); /* put bytes in right order. */
  1268. break;
  1269. case SEG_DIFFERENCE:
  1270. #ifndef WORKING_DOT_WORD
  1271. if(nbytes==2) {
  1272. struct broken_word *x;
  1273. x=(struct broken_word *)xmalloc(sizeof(struct broken_word));
  1274. x->next_broken_word=broken_words;
  1275. broken_words=x;
  1276. x->frag=frag_now;
  1277. x->word_goes_here=p;
  1278. x->dispfrag=0;
  1279. x->add=exp.X_add_symbol;
  1280. x->sub=exp.X_subtract_symbol;
  1281. x->addnum=exp.X_add_number;
  1282. x->added=0;
  1283. new_broken_words++;
  1284. break;
  1285. }
  1286. /* Else Fall through into. . . */
  1287. #endif
  1288. case SEG_BSS:
  1289. case SEG_UNKNOWN:
  1290. case SEG_TEXT:
  1291. case SEG_DATA:
  1292. #ifdef SPARC
  1293. fix_new (frag_now, p - frag_now -> fr_literal, nbytes,
  1294. exp . X_add_symbol, exp . X_subtract_symbol,
  1295. exp . X_add_number, 0, RELOC_32);
  1296. #endif
  1297. #ifdef NS32K
  1298. fix_new_ns32k (frag_now, p - frag_now -> fr_literal, nbytes,
  1299. exp . X_add_symbol, exp . X_subtract_symbol,
  1300. exp . X_add_number, 0, 0, 2, 0, 0);
  1301. #endif
  1302. #if !defined(SPARC) && !defined(NS32K)
  1303. fix_new (frag_now, p - frag_now -> fr_literal, nbytes,
  1304. exp . X_add_symbol, exp . X_subtract_symbol,
  1305. exp . X_add_number, 0);
  1306. #endif
  1307. break;
  1308. default:
  1309. BAD_CASE( segment );
  1310. break;
  1311. } /* switch(segment) */
  1312. } /* if(!need_pass_2) */
  1313. c = * input_line_pointer ++;
  1314. } /* while(c==',') */
  1315. input_line_pointer --; /* Put terminator back into stream. */
  1316. demand_empty_rest_of_line();
  1317. } /* cons() */
  1318. /*
  1319. * big_cons()
  1320. *
  1321. * CONStruct more frag(s) of .quads, or .octa etc.
  1322. * Makes 0 or more new frags.
  1323. * If need_pass_2 == TRUE, generate no frag.
  1324. * This understands only bignums, not expressions. Cons() understands
  1325. * expressions.
  1326. *
  1327. * Constants recognised are '0...'(octal) '0x...'(hex) '...'(decimal).
  1328. *
  1329. * This creates objects with struct obstack_control objs, destroying
  1330. * any context objs held about a partially completed object. Beware!
  1331. *
  1332. *
  1333. * I think it sucks to have 2 different types of integers, with 2
  1334. * routines to read them, store them etc.
  1335. * It would be nicer to permit bignums in expressions and only
  1336. * complain if the result overflowed. However, due to "efficiency"...
  1337. */
  1338. void
  1339. big_cons(nbytes) /* worker to do .quad etc statements */
  1340. /* clobbers input_line_pointer, checks */
  1341. /* end-of-line. */
  1342. register int nbytes; /* 8=.quad 16=.octa ... */
  1343. {
  1344. register char c; /* input_line_pointer -> c. */
  1345. register int radix;
  1346. register long int length; /* Number of chars in an object. */
  1347. register int digit; /* Value of 1 digit. */
  1348. register int carry; /* For multi-precision arithmetic. */
  1349. register int work; /* For multi-precision arithmetic. */
  1350. register char * p; /* For multi-precision arithmetic. */
  1351. extern char hex_value[]; /* In hex_value.c. */
  1352. /*
  1353. * The following awkward logic is to parse ZERO or more strings,
  1354. * comma seperated. Recall an expression includes its leading &
  1355. * trailing blanks. We fake a leading ',' if there is (supposed to
  1356. * be) a 1st expression, and keep demanding 1 expression for each ','.
  1357. */
  1358. if (is_it_end_of_statement())
  1359. {
  1360. c = 0; /* Skip loop. */
  1361. }
  1362. else
  1363. {
  1364. c = ','; /* Do loop. */
  1365. -- input_line_pointer;
  1366. }
  1367. while (c == ',')
  1368. {
  1369. ++ input_line_pointer;
  1370. SKIP_WHITESPACE();
  1371. c = * input_line_pointer;
  1372. /* C contains 1st non-blank character of what we hope is a number. */
  1373. if (c == '0')
  1374. {
  1375. c = * ++ input_line_pointer;
  1376. if (c == 'x' || c=='X')
  1377. {
  1378. c = * ++ input_line_pointer;
  1379. radix = 16;
  1380. }
  1381. else
  1382. {
  1383. radix = 8;
  1384. }
  1385. }
  1386. else
  1387. {
  1388. radix = 10;
  1389. }
  1390. /*
  1391. * This feature (?) is here to stop people worrying about
  1392. * mysterious zero constants: which is what they get when
  1393. * they completely omit digits.
  1394. */
  1395. if (hex_value[c] >= radix)
  1396. {
  1397. as_warn( "Missing digits. 0 assumed." );
  1398. }
  1399. bignum_high = bignum_low - 1; /* Start constant with 0 chars. */
  1400. for( ; (digit = hex_value [c]) < radix; c = * ++ input_line_pointer)
  1401. {
  1402. /* Multiply existing number by radix, then add digit. */
  1403. carry = digit;
  1404. for (p=bignum_low; p <= bignum_high; p++)
  1405. {
  1406. work = (*p & MASK_CHAR) * radix + carry;
  1407. *p = work & MASK_CHAR;
  1408. carry = work >> BITS_PER_CHAR;
  1409. }
  1410. if (carry)
  1411. {
  1412. grow_bignum();
  1413. * bignum_high = carry & MASK_CHAR;
  1414. know( (carry & ~ MASK_CHAR) == 0);
  1415. }
  1416. }
  1417. length = bignum_high - bignum_low + 1;
  1418. if (length > nbytes)
  1419. {
  1420. as_warn( "Most significant bits truncated in integer constant." );
  1421. }
  1422. else
  1423. {
  1424. register long int leading_zeroes;
  1425. for(leading_zeroes = nbytes - length;
  1426. leading_zeroes;
  1427. leading_zeroes --)
  1428. {
  1429. grow_bignum();
  1430. * bignum_high = 0;
  1431. }
  1432. }
  1433. if (! need_pass_2)
  1434. {
  1435. p = frag_more (nbytes);
  1436. bcopy (bignum_low, p, (int)nbytes);
  1437. }
  1438. /* C contains character after number. */
  1439. SKIP_WHITESPACE();
  1440. c = * input_line_pointer;
  1441. /* C contains 1st non-blank character after number. */
  1442. }
  1443. demand_empty_rest_of_line();
  1444. } /* big_cons() */
  1445. static void
  1446. grow_bignum() /* Extend bignum by 1 char. */
  1447. {
  1448. register long int length;
  1449. bignum_high ++;
  1450. if (bignum_high >= bignum_limit)
  1451. {
  1452. length = bignum_limit - bignum_low;
  1453. bignum_low = xrealloc (bignum_low, length + length);
  1454. bignum_high = bignum_low + length;
  1455. bignum_limit = bignum_low + length + length;
  1456. }
  1457. } /* grow_bignum(); */
  1458. /*
  1459. * float_cons()
  1460. *
  1461. * CONStruct some more frag chars of .floats .ffloats etc.
  1462. * Makes 0 or more new frags.
  1463. * If need_pass_2 == TRUE, no frags are emitted.
  1464. * This understands only floating literals, not expressions. Sorry.
  1465. *
  1466. * A floating constant is defined by atof_generic(), except it is preceded
  1467. * by 0d 0f 0g or 0h. After observing the STRANGE way my BSD AS does its
  1468. * reading, I decided to be incompatible. This always tries to give you
  1469. * rounded bits to the precision of the pseudo-op. Former AS did premature
  1470. * truncatation, restored noisy bits instead of trailing 0s AND gave you
  1471. * a choice of 2 flavours of noise according to which of 2 floating-point
  1472. * scanners you directed AS to use.
  1473. *
  1474. * In: input_line_pointer -> whitespace before, or '0' of flonum.
  1475. *
  1476. */
  1477. void /* JF was static, but can't be if VAX.C is goning to use it */
  1478. float_cons(float_type) /* Worker to do .float etc statements. */
  1479. /* Clobbers input_line-pointer, checks end-of-line. */
  1480. register float_type; /* 'f':.ffloat ... 'F':.float ... */
  1481. {
  1482. register char * p;
  1483. register char c;
  1484. int length; /* Number of chars in an object. */
  1485. register char * err; /* Error from scanning floating literal. */
  1486. char temp [MAXIMUM_NUMBER_OF_CHARS_FOR_FLOAT];
  1487. /*
  1488. * The following awkward logic is to parse ZERO or more strings,
  1489. * comma seperated. Recall an expression includes its leading &
  1490. * trailing blanks. We fake a leading ',' if there is (supposed to
  1491. * be) a 1st expression, and keep demanding 1 expression for each ','.
  1492. */
  1493. if (is_it_end_of_statement())
  1494. {
  1495. c = 0; /* Skip loop. */
  1496. ++ input_line_pointer; /* -> past termintor. */
  1497. }
  1498. else
  1499. {
  1500. c = ','; /* Do loop. */
  1501. }
  1502. while (c == ',')
  1503. {
  1504. /* input_line_pointer -> 1st char of a flonum (we hope!). */
  1505. SKIP_WHITESPACE();
  1506. /* Skip any 0{letter} that may be present. Don't even check if the
  1507. * letter is legal. Someone may invent a "z" format and this routine
  1508. * has no use for such information. Lusers beware: you get
  1509. * diagnostics if your input is ill-conditioned.
  1510. */
  1511. if(input_line_pointer[0]=='0' && isalpha(input_line_pointer[1]))
  1512. input_line_pointer+=2;
  1513. err = md_atof (float_type, temp, &length);
  1514. know( length <= MAXIMUM_NUMBER_OF_CHARS_FOR_FLOAT);
  1515. know( length > 0 );
  1516. if (* err)
  1517. {
  1518. as_warn( "Bad floating literal: %s", err);
  1519. ignore_rest_of_line();
  1520. /* Input_line_pointer -> just after end-of-line. */
  1521. c = 0; /* Break out of loop. */
  1522. }
  1523. else
  1524. {
  1525. if ( ! need_pass_2)
  1526. {
  1527. p = frag_more (length);
  1528. bcopy (temp, p, length);
  1529. }
  1530. SKIP_WHITESPACE();
  1531. c = * input_line_pointer ++;
  1532. /* C contains 1st non-white character after number. */
  1533. /* input_line_pointer -> just after terminator (c). */
  1534. }
  1535. }
  1536. -- input_line_pointer; /* -> terminator (is not ','). */
  1537. demand_empty_rest_of_line();
  1538. } /* float_cons() */
  1539. /*
  1540. * stringer()
  1541. *
  1542. * We read 0 or more ',' seperated, double-quoted strings.
  1543. *
  1544. * Caller should have checked need_pass_2 is FALSE because we don't check it.
  1545. */
  1546. static void
  1547. stringer(append_zero) /* Worker to do .ascii etc statements. */
  1548. /* Checks end-of-line. */
  1549. register int append_zero; /* 0: don't append '\0', else 1 */
  1550. {
  1551. /* register char * p; JF unused */
  1552. /* register int length; JF unused */ /* Length of string we read, excluding */
  1553. /* trailing '\0' implied by closing quote. */
  1554. /* register char * where; JF unused */
  1555. /* register fragS * fragP; JF unused */
  1556. register int c;
  1557. /*
  1558. * The following awkward logic is to parse ZERO or more strings,
  1559. * comma seperated. Recall a string expression includes spaces
  1560. * before the opening '\"' and spaces after the closing '\"'.
  1561. * We fake a leading ',' if there is (supposed to be)
  1562. * a 1st, expression. We keep demanding expressions for each
  1563. * ','.
  1564. */
  1565. if (is_it_end_of_statement())
  1566. {
  1567. c = 0; /* Skip loop. */
  1568. ++ input_line_pointer; /* Compensate for end of loop. */
  1569. }
  1570. else
  1571. {
  1572. c = ','; /* Do loop. */
  1573. }
  1574. for ( ; c == ','; c = *input_line_pointer ++)
  1575. {
  1576. SKIP_WHITESPACE();
  1577. if (* input_line_pointer == '\"')
  1578. {
  1579. ++ input_line_pointer; /* -> 1st char of string. */
  1580. while ( (c = next_char_of_string()) >= 0)
  1581. {
  1582. FRAG_APPEND_1_CHAR( c );
  1583. }
  1584. if (append_zero)
  1585. {
  1586. FRAG_APPEND_1_CHAR( 0 );
  1587. }
  1588. know( input_line_pointer [-1] == '\"' );
  1589. }
  1590. else
  1591. {
  1592. as_warn( "Expected \"-ed string" );
  1593. }
  1594. SKIP_WHITESPACE();
  1595. }
  1596. -- input_line_pointer;
  1597. demand_empty_rest_of_line();
  1598. } /* stringer() */
  1599. static int
  1600. next_char_of_string ()
  1601. {
  1602. register int c;
  1603. c = * input_line_pointer ++;
  1604. switch (c)
  1605. {
  1606. case '\"':
  1607. c = -1;
  1608. break;
  1609. case '\\':
  1610. switch (c = * input_line_pointer ++)
  1611. {
  1612. case 'b':
  1613. c = '\b';
  1614. break;
  1615. case 'f':
  1616. c = '\f';
  1617. break;
  1618. case 'n':
  1619. c = '\n';
  1620. break;
  1621. case 'r':
  1622. c = '\r';
  1623. break;
  1624. case 't':
  1625. c = '\t';
  1626. break;
  1627. case '\\':
  1628. case '"':
  1629. break; /* As itself. */
  1630. case '0':
  1631. case '1':
  1632. case '2':
  1633. case '3':
  1634. case '4':
  1635. case '5':
  1636. case '6':
  1637. case '7':
  1638. case '8':
  1639. case '9':
  1640. {
  1641. long int number;
  1642. for (number = 0; isdigit(c); c = * input_line_pointer ++)
  1643. {
  1644. number = number * 8 + c - '0';
  1645. }
  1646. c = number;
  1647. }
  1648. -- input_line_pointer;
  1649. break;
  1650. case '\n':
  1651. /* as_fatal( "Unterminated string - use app!" ); */
  1652. /* To be compatible with BSD 4.2 as: give the luser a linefeed!! */
  1653. c = '\n';
  1654. break;
  1655. default:
  1656. as_warn( "Bad escaped character in string, '?' assumed" );
  1657. c = '?';
  1658. break;
  1659. }
  1660. break;
  1661. default:
  1662. break;
  1663. }
  1664. return (c);
  1665. }
  1666. static segT
  1667. get_segmented_expression ( expP )
  1668. register expressionS * expP;
  1669. {
  1670. register segT retval;
  1671. if ( (retval = expression( expP )) == SEG_PASS1 || retval == SEG_NONE || retval == SEG_BIG )
  1672. {
  1673. as_warn("Expected address expression: absolute 0 assumed");
  1674. retval = expP -> X_seg = SEG_ABSOLUTE;
  1675. expP -> X_add_number = 0;
  1676. expP -> X_add_symbol = expP -> X_subtract_symbol = 0;
  1677. }
  1678. return (retval); /* SEG_ ABSOLUTE,UNKNOWN,DATA,TEXT,BSS */
  1679. }
  1680. static segT
  1681. get_known_segmented_expression ( expP )
  1682. register expressionS * expP;
  1683. {
  1684. register segT retval;
  1685. register char * name1;
  1686. register char * name2;
  1687. if ( (retval = get_segmented_expression (expP)) == SEG_UNKNOWN
  1688. )
  1689. {
  1690. name1 = expP -> X_add_symbol ? expP -> X_add_symbol -> sy_name : "";
  1691. name2 = expP -> X_subtract_symbol ? expP -> X_subtract_symbol -> sy_name : "";
  1692. if ( name1 && name2 )
  1693. {
  1694. as_warn("Symbols \"%s\" \"%s\" are undefined: absolute 0 assumed.",
  1695. name1, name2);
  1696. }
  1697. else
  1698. {
  1699. as_warn("Symbol \"%s\" undefined: absolute 0 assumed.",
  1700. name1 ? name1 : name2);
  1701. }
  1702. retval = expP -> X_seg = SEG_ABSOLUTE;
  1703. expP -> X_add_number = 0;
  1704. expP -> X_add_symbol = expP -> X_subtract_symbol = NULL;
  1705. }
  1706. know( retval == SEG_ABSOLUTE || retval == SEG_DATA || retval == SEG_TEXT || retval == SEG_BSS || retval == SEG_DIFFERENCE );
  1707. return (retval);
  1708. } /* get_known_segmented_expression() */
  1709. /* static */ long int /* JF was static, but can't be if the MD pseudos are to use it */
  1710. get_absolute_expression ()
  1711. {
  1712. expressionS exp;
  1713. register segT s;
  1714. if ( (s = expression(& exp)) != SEG_ABSOLUTE )
  1715. {
  1716. if ( s != SEG_NONE )
  1717. {
  1718. as_warn( "Bad Absolute Expression, absolute 0 assumed.");
  1719. }
  1720. exp . X_add_number = 0;
  1721. }
  1722. return (exp . X_add_number);
  1723. }
  1724. static char /* return terminator */
  1725. get_absolute_expression_and_terminator( val_pointer)
  1726. long int * val_pointer; /* return value of expression */
  1727. {
  1728. * val_pointer = get_absolute_expression ();
  1729. return ( * input_line_pointer ++ );
  1730. }
  1731. /*
  1732. * demand_copy_C_string()
  1733. *
  1734. * Like demand_copy_string, but return NULL if the string contains any '\0's.
  1735. * Give a warning if that happens.
  1736. */
  1737. static char *
  1738. demand_copy_C_string (len_pointer)
  1739. int * len_pointer;
  1740. {
  1741. register char * s;
  1742. if (s = demand_copy_string (len_pointer))
  1743. {
  1744. register int len;
  1745. for (len = * len_pointer;
  1746. len > 0;
  1747. len--)
  1748. {
  1749. if (* s == 0)
  1750. {
  1751. s = 0;
  1752. len = 1;
  1753. * len_pointer = 0;
  1754. as_warn( "This string may not contain \'\\0\'" );
  1755. }
  1756. }
  1757. }
  1758. return (s);
  1759. }
  1760. /*
  1761. * demand_copy_string()
  1762. *
  1763. * Demand string, but return a safe (=private) copy of the string.
  1764. * Return NULL if we can't read a string here.
  1765. */
  1766. static char *
  1767. demand_copy_string (lenP)
  1768. int * lenP;
  1769. {
  1770. register int c;
  1771. register int len;
  1772. char * retval;
  1773. len = 0;
  1774. SKIP_WHITESPACE();
  1775. if (* input_line_pointer == '\"')
  1776. {
  1777. input_line_pointer ++; /* Skip opening quote. */
  1778. while ( (c = next_char_of_string()) >= 0 ) {
  1779. obstack_1grow ( &notes, c );
  1780. len ++;
  1781. }
  1782. /* JF this next line is so demand_copy_C_string will return a null
  1783. termanated string. */
  1784. obstack_1grow(&notes,'\0');
  1785. retval=obstack_finish( &notes);
  1786. } else {
  1787. as_warn( "Missing string" );
  1788. retval = NULL;
  1789. ignore_rest_of_line ();
  1790. }
  1791. * lenP = len;
  1792. return (retval);
  1793. }
  1794. /*
  1795. * is_it_end_of_statement()
  1796. *
  1797. * In: Input_line_pointer -> next character.
  1798. *
  1799. * Do: Skip input_line_pointer over all whitespace.
  1800. *
  1801. * Out: TRUE if input_line_pointer -> end-of-line.
  1802. */
  1803. static int
  1804. is_it_end_of_statement()
  1805. {
  1806. SKIP_WHITESPACE();
  1807. return (is_end_of_line [* input_line_pointer]);
  1808. }
  1809. void
  1810. equals(sym_name)
  1811. char *sym_name;
  1812. {
  1813. register struct symbol * symbolP; /* symbol we are working with */
  1814. if(sym_name[0]=='.' && sym_name[1]=='\0') {
  1815. /* Turn '. = mumble' into a .org mumble */
  1816. register segT segment;
  1817. expressionS exp;
  1818. register char *p;
  1819. if(input_line_pointer[1]=='=')
  1820. input_line_pointer+=2;
  1821. else
  1822. *input_line_pointer++='='; /* Put it back */
  1823. if(*input_line_pointer==' ' || *input_line_pointer=='\t')
  1824. input_line_pointer++;
  1825. segment = get_known_segmented_expression(& exp);
  1826. if ( ! need_pass_2 ) {
  1827. if (segment != now_seg && segment != SEG_ABSOLUTE)
  1828. as_warn("Illegal segment \"%s\". Segment \"%s\" assumed.",
  1829. seg_name [(int) segment], seg_name [(int) now_seg]);
  1830. p = frag_var (rs_org, 1, 1, (relax_substateT)0, exp.X_add_symbol,
  1831. exp.X_add_number, (char *)0);
  1832. * p = 0;
  1833. } /* if (ok to make frag) */
  1834. return;
  1835. }
  1836. symbolP=symbol_find_or_make(sym_name);
  1837. if(input_line_pointer[1]=='=')
  1838. input_line_pointer+=2;
  1839. else
  1840. *input_line_pointer++='='; /* Put it back */
  1841. pseudo_set(symbolP);
  1842. }
  1843. /* end: read.c */