1/* read.c - read a source file - 2 Copyright (C) 1986,1987 Free Software Foundation, Inc. 3 4This file is part of GAS, the GNU Assembler. 5 6GAS is free software; you can redistribute it and/or modify 7it under the terms of the GNU General Public License as published by 8the Free Software Foundation; either version 1, or (at your option) 9any later version. 10 11GAS is distributed in the hope that it will be useful, 12but WITHOUT ANY WARRANTY; without even the implied warranty of 13MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 14GNU General Public License for more details. 15 16You should have received a copy of the GNU General Public License 17along with GAS; see the file COPYING. If not, write to 18the Free Software Foundation, 675 Mass Ave, Cambridge, MA 02139, USA. */ 19 20#define MASK_CHAR (0xFF) /* If your chars aren't 8 bits, you will 21 change this a bit. But then, GNU isnt 22 spozed to run on your machine anyway. 23 (RMS is so shortsighted sometimes.) 24 */ 25 26#define MAXIMUM_NUMBER_OF_CHARS_FOR_FLOAT (16) 27 /* This is the largest known floating point */ 28 /* format (for now). It will grow when we */ 29 /* do 4361 style flonums. */ 30 31 32/* Routines that read assembler source text to build spagetti in memory. */ 33/* Another group of these functions is in the expr.c module */ 34 35#include <ctype.h> 36#include <string.h> 37#include <stdlib.h> 38#include <sys/types.h> 39#include <sys/stat.h> 40#include "stuff/rnd.h" 41#include "stuff/arch.h" 42#include "stuff/best_arch.h" 43#include "as.h" 44#include "flonum.h" 45#include "struc-symbol.h" 46#include "expr.h" 47#include "read.h" 48#include "hash.h" 49#include "obstack.h" 50#include "md.h" 51#include "symbols.h" 52#include "sections.h" 53#include "input-scrub.h" 54#include "input-file.h" 55#include "hex_value.h" 56#include "messages.h" 57#include "xmalloc.h" 58#include "app.h" 59#if defined(I386) && defined(ARCH64) 60#include "i386.h" 61#endif 62#include "dwarf2dbg.h" 63 64/* 65 * Parsing of input is done off of this pointer which points to the next char 66 * of source file to parse. 67 */ 68char *input_line_pointer = NULL; 69 70/* 71 * buffer_limit is the value returned by the input_scrub_next_buffer() in 72 * read_a_source_file() and is not static only so read_an_include_file can save 73 * and restore it. 74 */ 75char *buffer_limit = NULL; /* -> 1 + last char in buffer. */ 76 77/* FROM line 164 */ 78#define TARGET_BYTES_BIG_ENDIAN 0 /* HACK */ 79/* TARGET_BYTES_BIG_ENDIAN is required to be defined to either 0 or 1 80 in the tc-<CPU>.h file. See the "Porting GAS" section of the 81 internals manual. */ 82int target_big_endian = TARGET_BYTES_BIG_ENDIAN; 83 84/* 85 * This table is used by the macros is_name_beginner() and is_part_of_name() 86 * defined in read.h . 87 */ 88#ifndef PPC 89const 90#endif /* PPC */ 91char lex_type[256] = { 92 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, /* @ABCDEFGHIJKLMNO */ 93 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, /* PQRSTUVWXYZ[\]^_ */ 94 0, 0, 0, 0, 3, 0, 0, 0, 0, 0, 0, 0, 0, 0, 3, 0, /* _!"#$%&'()*+,-./ */ 95 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 0, 0, 0, 0, 0, 0, /* 0123456789:;<=>? */ 96 0, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, /* @ABCDEFGHIJKLMNO */ 97 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 0, 0, 0, 0, 3, /* PQRSTUVWXYZ[\]^_ */ 98 0, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, /* `abcdefghijklmno */ 99 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 0, 0, 0, 0, /* pqrstuvwxyz{|}~. */ 100 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, /* Allow all chars */ 101 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, /* with the high bit */ 102 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, /* set in names */ 103 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 104 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 105 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 106 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3 107}; 108 109/* 110 * In: a character. 111 * Out: TRUE if this character ends a line. 112 */ 113static 114#ifndef PPC 115const 116#endif /* PPC */ 117char is_end_of_line_tab[256] = { 118 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, /* @abcdefghijklmno */ 119 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, /* */ 120 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, /* */ 121 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, /* 0123456789:;<=>? */ 122#if defined(M88K) || defined(PPC) || defined(HPPA) 123 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, /* @ABCDEFGHIJKLMNO */ 124#else 125 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, /* */ 126#endif 127 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, /* */ 128 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, /* */ 129 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, /* */ 130 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, /* */ 131 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, /* */ 132 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, /* */ 133 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, /* */ 134 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 /* */ 135}; 136// binutils references the table directly, but that requires a cast 137// whenever you try to index into the array with a char and that's 138// annoying. The function avoids this. We'd make this a macro, 139// but it needs to be referenced externally and we don't need to 140// export the table. 141char is_end_of_line(int c) { return is_end_of_line_tab[c & 0xFF]; } 142 143/* 144 * The conditional assembly feature (.if, .else, .elseif and .endif) is 145 * implemented with cond_state that tells us what we are in the middle of 146 * processing. ignore can be either TRUE or FALSE. When TRUE we are ignoring 147 * the block of code in the middle of a conditional. MAX_IF_DEPTH is the 148 * maximum depth that if's can be nested. 149 */ 150#define MAX_IF_DEPTH 20 151typedef enum { 152 no_cond, /* no conditional is being processed */ 153 if_cond, /* inside if conditional */ 154 elseif_cond,/* inside elseif conditional */ 155 else_cond /* inside else conditional */ 156}cond_type; 157 158struct cond_state { 159 cond_type the_cond; 160 int cond_met; 161 int ignore; 162}; 163typedef struct cond_state cond_stateS; 164static cond_stateS the_cond_state = {no_cond, FALSE, FALSE}; 165static cond_stateS last_states[MAX_IF_DEPTH]; 166static int if_depth = 0; 167 168/* 169 * Assembler macros are implemented with these variables and functions. 170 */ 171#define MAX_MACRO_DEPTH 20 172static int macro_depth = 0; 173static struct hash_control 174 *ma_hash = NULL; /* use before set up: NULL-> address error */ 175static struct obstack macros; /* obstack for macro text */ 176static char *macro_name = NULL; /* name of macro we are defining */ 177static int count_lines = TRUE; /* turns line number counting on and off */ 178static int macros_on = TRUE; /* .macros_on and .macros_off toggles this to 179 allow macros to be turned off, which allows 180 macros to override a machine instruction and 181 still use it. */ 182static void expand_macro(char *macro_contents); 183static void macro_begin(void); 184 185 186/* 187 * The .dump and .load feature is implemented with these variables and 188 * functions. 189 */ 190static FILE *dump_fp = NULL; 191static void write_macro(const char *string, PTR value); 192static void write_symbol(const char *string, PTR value); 193 194 195/* Functions private to this file */ 196static void parse_a_buffer(char *buffer); 197#ifdef PPC 198static void ppcasm_parse_a_buffer(char *buffer); 199#endif 200static void parse_line_comment(char **buffer); 201static segT get_segmented_expression(expressionS *expP); 202static void pseudo_op_begin(void); 203#ifdef PPC 204static void ppcasm_pseudo_op_begin(void); 205#endif 206static void stab(uintptr_t what); 207static char get_absolute_expression_and_terminator(int32_t *val_pointer); 208static char *demand_copy_string(int *lenP); 209static int is_it_end_of_statement(void); 210static void equals(char *sym_name); 211static int next_char_of_string(void); 212 213#ifdef M68K /* we allow big cons only on the 68k machines */ 214/* 215 * This is setup by read_begin() and used by big_cons() with using grow_bignum() 216 * to make it bigger if needed. 217 */ 218#define BIGNUM_BEGIN_SIZE (16) 219static char *bignum_low; /* Lowest char of bignum. */ 220static char *bignum_limit;/* 1st illegal address of bignum. */ 221static char *bignum_high; /* Highest char of bignum, may point to 222 (bignum_start-1), never >= bignum_limit. */ 223static void grow_bignum(void); 224#endif /* M68K */ 225/* 226 * This is set in read_a_source_file() to the section number of the text section 227 * for used by the machine dependent md_assemble() to create line number stabs 228 * for assembly instructions in the text section when -g is seen. 229 */ 230uint32_t text_nsect = 0; 231 232/* 233 * These are the names of the section types used by the .section directive. 234 */ 235struct type_name { 236 char *name; 237 unsigned type; 238}; 239static struct type_name type_names[] = { 240 { "regular", S_REGULAR }, 241 { "cstring_literals", S_CSTRING_LITERALS }, 242 { "4byte_literals", S_4BYTE_LITERALS }, 243 { "8byte_literals", S_8BYTE_LITERALS }, 244 { "16byte_literals", S_16BYTE_LITERALS }, 245 { "literal_pointers", S_LITERAL_POINTERS }, 246#if !(defined(I386) && defined(ARCH64)) 247 { "non_lazy_symbol_pointers", S_NON_LAZY_SYMBOL_POINTERS }, 248 { "lazy_symbol_pointers", S_LAZY_SYMBOL_POINTERS }, 249 { "symbol_stubs", S_SYMBOL_STUBS }, 250#endif 251 { "mod_init_funcs", S_MOD_INIT_FUNC_POINTERS }, 252 { "mod_term_funcs", S_MOD_TERM_FUNC_POINTERS }, 253 { "coalesced", S_COALESCED }, 254 { "interposing", S_INTERPOSING }, 255 { "thread_local_regular", S_THREAD_LOCAL_REGULAR }, 256 { "thread_local_variables", S_THREAD_LOCAL_VARIABLES }, 257 { "thread_local_init_function_pointers", 258 S_THREAD_LOCAL_INIT_FUNCTION_POINTERS }, 259 { NULL, 0 } 260}; 261 262/* 263 * These are the names of the section attributes used by the .section directive. 264 */ 265struct attribute_name { 266 char *name; 267 unsigned attribute; 268}; 269static struct attribute_name attribute_names[] = { 270 { "none", 0 }, 271 { "pure_instructions", S_ATTR_PURE_INSTRUCTIONS }, 272 { "no_toc", S_ATTR_NO_TOC }, 273 { "strip_static_syms", S_ATTR_STRIP_STATIC_SYMS }, 274 { "no_dead_strip", S_ATTR_NO_DEAD_STRIP }, 275 { "live_support", S_ATTR_LIVE_SUPPORT }, 276 { "self_modifying_code", S_ATTR_SELF_MODIFYING_CODE }, 277 { "debug", S_ATTR_DEBUG }, 278 { NULL, 0 } 279}; 280 281/* 282 * These are the built in sections known to the assembler with a directive. 283 * They are known as which segment and section name as well as the type & 284 * attribute, and default alignment. 285 */ 286struct builtin_section { 287 char *directive; 288 char *segname; 289 char *sectname; 290 uint32_t flags; /* type & attribute */ 291 uint32_t default_align; 292 uint32_t sizeof_stub; 293}; 294static const struct builtin_section builtin_sections[] = { 295 /* 296 * The text section must be first in this list as it is used by 297 * read_a_source_file() to do the equivalent of a .text at the start 298 * of the file. 299 */ 300 { "text", "__TEXT", "__text", S_ATTR_PURE_INSTRUCTIONS }, 301 { "const", "__TEXT", "__const" }, 302 { "static_const", "__TEXT", "__static_const" }, 303 { "cstring", "__TEXT", "__cstring", S_CSTRING_LITERALS }, 304 { "literal4", "__TEXT", "__literal4", S_4BYTE_LITERALS, 2 }, 305 { "literal8", "__TEXT", "__literal8", S_8BYTE_LITERALS, 3 }, 306 { "literal16", "__TEXT", "__literal16", S_16BYTE_LITERALS, 4 }, 307 { "constructor", "__TEXT", "__constructor" }, 308 { "destructor", "__TEXT", "__destructor" }, 309 { "fvmlib_init0", "__TEXT", "__fvmlib_init0" }, 310 { "fvmlib_init1", "__TEXT", "__fvmlib_init1" }, 311#if !(defined(I386) && defined(ARCH64)) 312 { "symbol_stub", "__TEXT", "__symbol_stub", 313 S_SYMBOL_STUBS | S_ATTR_PURE_INSTRUCTIONS, 314#if defined(M68K) 315 1, 20 316#endif 317#if defined(I386) 318 0, 16 319#endif 320#if defined(HPPA) 321 2, 28 322#endif 323#if defined(SPARC) 324 2, 32 325#endif 326#if defined(PPC) 327 2, 20 328#endif 329 }, 330#endif 331#if !(defined(I386) && defined(ARCH64)) 332 { "picsymbol_stub", "__TEXT", "__picsymbol_stub", 333 S_SYMBOL_STUBS | S_ATTR_PURE_INSTRUCTIONS, 334#if defined(M68K) 335 1, 24 336#endif 337#if defined(I386) 338 0, 26 339#endif 340#if defined(HPPA) 341 2, 32 342#endif 343#if defined(SPARC) 344 2, 60 345#endif 346#if defined(PPC) 347 2, 36 348#endif 349 }, 350#endif 351#if !(defined(I386) && defined(ARCH64)) 352 { "non_lazy_symbol_pointer","__DATA","__nl_symbol_ptr", 353 S_NON_LAZY_SYMBOL_POINTERS, 2 }, 354 { "lazy_symbol_pointer", "__DATA", "__la_symbol_ptr", 355 S_LAZY_SYMBOL_POINTERS, 2 }, 356#endif 357 { "mod_init_func", "__DATA", "__mod_init_func", 358 S_MOD_INIT_FUNC_POINTERS, 2 }, 359 { "mod_term_func", "__DATA", "__mod_term_func", 360 S_MOD_TERM_FUNC_POINTERS, 2 }, 361 { "dyld", "__DATA", "__dyld" }, 362 { "data", "__DATA", "__data" }, 363 { "static_data", "__DATA", "__static_data" }, 364 { "const_data", "__DATA", "__const" }, 365 { "tdata", "__DATA", "__thread_data", 366 S_THREAD_LOCAL_REGULAR }, 367 { "tlv", "__DATA", "__thread_vars", 368 S_THREAD_LOCAL_VARIABLES }, 369 { "thread_init_func", "__DATA", "__thread_init", 370 S_THREAD_LOCAL_INIT_FUNCTION_POINTERS }, 371 { "objc_class", "__OBJC", "__class", S_ATTR_NO_DEAD_STRIP }, 372 { "objc_meta_class", "__OBJC", "__meta_class", S_ATTR_NO_DEAD_STRIP }, 373 { "objc_string_object", "__OBJC", "__string_object", S_ATTR_NO_DEAD_STRIP}, 374 { "objc_protocol", "__OBJC", "__protocol", S_ATTR_NO_DEAD_STRIP }, 375 { "objc_cat_cls_meth", "__OBJC", "__cat_cls_meth", S_ATTR_NO_DEAD_STRIP }, 376 { "objc_cat_inst_meth", "__OBJC", "__cat_inst_meth", S_ATTR_NO_DEAD_STRIP}, 377 { "objc_cls_meth", "__OBJC", "__cls_meth", S_ATTR_NO_DEAD_STRIP }, 378 { "objc_inst_meth", "__OBJC", "__inst_meth", S_ATTR_NO_DEAD_STRIP }, 379 { "objc_message_refs", "__OBJC", "__message_refs", 380 S_LITERAL_POINTERS | S_ATTR_NO_DEAD_STRIP, 2}, 381 { "objc_cls_refs", "__OBJC", "__cls_refs", 382 S_LITERAL_POINTERS | S_ATTR_NO_DEAD_STRIP, 2}, 383 { "objc_class_names", "__TEXT", "__cstring", S_CSTRING_LITERALS }, 384 { "objc_module_info", "__OBJC", "__module_info", S_ATTR_NO_DEAD_STRIP }, 385 { "objc_symbols", "__OBJC", "__symbols", S_ATTR_NO_DEAD_STRIP }, 386 { "objc_category", "__OBJC", "__category", S_ATTR_NO_DEAD_STRIP }, 387 { "objc_meth_var_types", "__TEXT", "__cstring", S_CSTRING_LITERALS }, 388 { "objc_class_vars", "__OBJC", "__class_vars", S_ATTR_NO_DEAD_STRIP }, 389 { "objc_instance_vars", "__OBJC", "__instance_vars", S_ATTR_NO_DEAD_STRIP}, 390 { "objc_meth_var_names", "__TEXT", "__cstring", S_CSTRING_LITERALS }, 391 { "objc_selector_strs", "__OBJC", "__selector_strs", S_CSTRING_LITERALS }, 392 { 0 } 393}; 394 395/* set up pseudo-op tables */ 396static struct hash_control *po_hash = NULL; 397#ifdef PPC 398static struct hash_control *ppcasm_po_hash = NULL; 399#endif 400 401/* 402 * The routines that implement the pseudo-ops. 403 */ 404#if !defined(I860) /* i860 has it's own align and org */ 405static void s_align(int value, int bytes_p); 406static void s_align_bytes(uintptr_t arg); 407static void s_align_ptwo(uintptr_t arg); 408static void s_org(uintptr_t value); 409#endif 410static void s_private_extern(uintptr_t value); 411#if !(defined(I386) && defined(ARCH64)) 412static void s_indirect_symbol(uintptr_t value); 413#endif 414static void s_abort(uintptr_t value); 415static void s_comm(uintptr_t value); 416static void s_desc(uintptr_t value); 417static void s_fill(uintptr_t value); 418static void s_lcomm(uintptr_t value); 419static void s_lsym(uintptr_t value); 420static void s_set(uintptr_t value); 421static void s_reference(uintptr_t value); 422static void s_lazy_reference(uintptr_t value); 423static void s_weak_reference(uintptr_t value); 424static void s_weak_definition(uintptr_t value); 425static void s_weak_def_can_be_hidden(uintptr_t value); 426static void s_no_dead_strip(uintptr_t value); 427static void s_symbol_resolver(uintptr_t value); 428static void s_include(uintptr_t value); 429static void s_dump(uintptr_t value); 430static void s_load(uintptr_t value); 431static void s_if(uintptr_t value); 432static void s_elseif(uintptr_t value); 433static void s_else(uintptr_t value); 434static void s_endif(uintptr_t value); 435static void s_macros_on(uintptr_t value); 436static void s_macros_off(uintptr_t value); 437static void s_section(uintptr_t value); 438static void s_zerofill(uintptr_t value); 439static uint32_t s_builtin_section(const struct builtin_section *s); 440static void s_subsections_via_symbols(uintptr_t value); 441static void s_machine(uintptr_t value); 442static void s_secure_log_unique(uintptr_t value); 443static void s_secure_log_reset(uintptr_t value); 444static void s_inlineasm(uintptr_t value); 445static void s_leb128(uintptr_t sign); 446static void s_incbin(uintptr_t value); 447static void s_data_region(uintptr_t value); 448static void s_end_data_region(uintptr_t value); 449 450#ifdef PPC 451/* 452 * The routines that implement the ppcasm pseudo-ops. 453 */ 454static void s_ppcasm_end(uintptr_t value); 455#endif /* PPC */ 456 457/* 458 * The machine independent pseudo op table. 459 */ 460static const pseudo_typeS pseudo_table[] = { 461#if !defined(I860) /* i860 has it's own align and org */ 462 { "align", s_align_ptwo, 1 }, 463 { "align32", s_align_ptwo, 4 }, 464 { "p2align", s_align_ptwo, 1 }, 465 { "p2alignw", s_align_ptwo, 2 }, 466 { "p2alignl", s_align_ptwo, 4 }, 467 { "balign", s_align_bytes, 1 }, 468 { "balignw", s_align_bytes, 2 }, 469 { "balignl", s_align_bytes, 4 }, 470 { "org", s_org, 0 }, 471#endif 472#ifndef M88K /* m88k has it's own abs that uses the s_abs() in here */ 473 { "abs", s_abs, 0 }, 474#endif 475 { "private_extern", s_private_extern, 0}, 476#if !(defined(I386) && defined(ARCH64)) /* x86-64 doesn't support .indirect_symbol */ 477 { "indirect_symbol", s_indirect_symbol, 0}, 478#endif 479 { "abort", s_abort, 0 }, 480 { "ascii", stringer, 0 }, 481 { "asciz", stringer, 1 }, 482 { "byte", cons, 1 }, 483 { "comm", s_comm, 0 }, 484 { "desc", s_desc, 0 }, 485 { "double", float_cons, 'd' }, 486 { "appfile", s_app_file, 0 }, 487 { "fill", s_fill, 0 }, 488 { "globl", s_globl, 0 }, 489 { "lcomm", s_lcomm, 0 }, 490 { "line", s_line, 0 }, 491 { "long", cons, 4 }, 492 { "quad", cons, 8 }, 493 { "lsym", s_lsym, 0 }, 494 { "section", s_section, 0 }, 495 { "zerofill", s_zerofill, S_ZEROFILL }, 496 { "tbss", s_zerofill, S_THREAD_LOCAL_ZEROFILL }, 497 { "secure_log_unique",s_secure_log_unique, 0 }, 498 { "secure_log_reset",s_secure_log_reset, 0 }, 499 { "set", s_set, 0 }, 500 { "short", cons, 2 }, 501 { "single", float_cons, 'f' }, 502 { "space", s_space, 0 }, 503 { "sleb128", s_leb128, 1}, 504 { "uleb128", s_leb128, 0}, 505 { "stabd", stab, 'd' }, 506 { "stabn", stab, 'n' }, 507 { "stabs", stab, 's' }, 508 { "debug_note", stab, 's' }, 509 { "reference",s_reference, 0 }, 510 { "lazy_reference",s_lazy_reference, 0 }, 511 { "weak_reference",s_weak_reference, 0 }, 512 { "weak_definition",s_weak_definition, 0 }, 513 { "weak_def_can_be_hidden",s_weak_def_can_be_hidden, 0 }, 514 { "no_dead_strip",s_no_dead_strip, 0 }, 515 { "symbol_resolver",s_symbol_resolver, 0 }, 516 { "include", s_include, 0 }, 517 { "macro", s_macro, 0 }, 518 { "endmacro", s_endmacro, 0 }, 519 { "endm", s_endmacro, 0 }, 520 { "macros_on",s_macros_on, 0 }, 521 { "macros_off",s_macros_off, 0 }, 522 { "if", s_if, 0 }, 523 { "elseif", s_elseif, 0 }, 524 { "else", s_else, 0 }, 525 { "endif", s_endif, 0 }, 526 { "dump", s_dump, 0 }, 527 { "load", s_load, 0 }, 528 { "subsections_via_symbols", s_subsections_via_symbols, 0 }, 529 { "machine", s_machine, 0 }, 530 { "inlineasmstart", s_inlineasm, 1 }, 531 { "inlineasmend", s_inlineasm, 0 }, 532 { "incbin", s_incbin, 0 }, 533 { "data_region", s_data_region, 0 }, 534 { "end_data_region", s_end_data_region, 0 }, 535 { NULL } /* end sentinel */ 536}; 537 538#ifdef PPC 539/* 540 * The pseudo op table for the ppcasm flavor of the PowerPC assembler. 541 */ 542static const pseudo_typeS ppcasm_pseudo_table[] = { 543 { "include", s_include, 0 }, 544 { "end", s_ppcasm_end, 0 }, 545 { NULL } /* end sentinel */ 546}; 547#endif /* PPC */ 548 549/* 550 * True if .secure_log_unique has been used without; reset by .secure_log_reset 551 */ 552static enum bool s_secure_log_used = FALSE; 553 554/* 555 * read_begin() initializes the assember to read assembler source input. 556 */ 557void 558read_begin( 559void) 560{ 561 pseudo_op_begin(); 562 macro_begin(); 563 obstack_begin(¬es, 5000); 564 565#ifdef M68K /* we allow big cons only on the 68k machines */ 566 bignum_low = xmalloc((int32_t)BIGNUM_BEGIN_SIZE); 567 bignum_limit = bignum_low + BIGNUM_BEGIN_SIZE; 568#endif 569} 570 571#ifdef PPC 572/* 573 * ppcasm_read_begin() does all the things needed to set up for reading ppcasm 574 * PowerPC assembly syntax. 575 */ 576void 577ppcasm_read_begin( 578void) 579{ 580 /* 581 * For ppcasm allow '\r' as an end of line character and don't treat 582 * '@' and ':' as an end of line characters. 583 */ 584 is_end_of_line_tab['\r'] = 1; 585 is_end_of_line_tab['@'] = 0; 586 is_end_of_line_tab[':'] = 0; 587 588 ppcasm_pseudo_op_begin(); 589} 590#endif /* PPC */ 591 592/* 593 * pseudo_op_begin() creates a hash table of pseudo ops from the machine 594 * independent and machine dependent pseudo op tables. 595 */ 596static 597void 598pseudo_op_begin( 599void) 600{ 601 const char *errtxt; 602 const pseudo_typeS *pop; 603 uint32_t i; 604 pseudo_typeS *sections_pseudo_table; 605 606 po_hash = hash_new(); 607 errtxt = NULL; 608 609 for(pop = pseudo_table; 610 pop->poc_name && (!errtxt || *errtxt == '\0'); 611 pop++) 612 errtxt = hash_insert(po_hash, pop->poc_name, (char *)pop); 613 614 for(pop = md_pseudo_table; 615 pop->poc_name && (!errtxt || *errtxt == '\0'); 616 pop++) 617 errtxt = hash_insert(po_hash, pop->poc_name, (char *)pop); 618 619 for(i = 0; builtin_sections[i].directive != NULL; i++) 620 ; 621 sections_pseudo_table = xmalloc((i + 1) * sizeof(pseudo_typeS)); 622 for(i = 0; builtin_sections[i].directive != NULL; i++){ 623 sections_pseudo_table[i].poc_name = builtin_sections[i].directive; 624 sections_pseudo_table[i].poc_handler = 625 (void (*)(uintptr_t))s_builtin_section; 626 sections_pseudo_table[i].poc_val = (uintptr_t)(builtin_sections +i); 627 } 628 sections_pseudo_table[i].poc_name = NULL; 629 for(pop = (const pseudo_typeS *)sections_pseudo_table; 630 pop->poc_name && (!errtxt || *errtxt == '\0'); 631 pop++) 632 errtxt = hash_insert(po_hash, pop->poc_name, (char *)pop); 633 634 if(errtxt != NULL && *errtxt != '\0'){ 635 as_fatal("error constructing pseudo-op table (%s)", errtxt); 636 } 637} 638 639#ifdef PPC 640/* 641 * ppcasm_pseudo_op_begin() creates a hash table of pseudo ops for use with the 642 * ppcasm flavor of the PowerPC assembler. 643 */ 644static 645void 646ppcasm_pseudo_op_begin( 647void) 648{ 649 const char *errtxt; 650 char *uppercase; 651 const pseudo_typeS *pop; 652 uint32_t len, i; 653 654 ppcasm_po_hash = hash_new(); 655 errtxt = NULL; 656 for(pop = ppcasm_pseudo_table; pop->poc_name != NULL; pop++){ 657 errtxt = hash_insert(ppcasm_po_hash, pop->poc_name, (char *)pop); 658 if(errtxt != NULL && *errtxt != '\0') 659 as_fatal("error constructing pseudo-op table (%s)", errtxt); 660 661 len = strlen(pop->poc_name); 662 uppercase = xmalloc(len); 663 strcpy(uppercase, pop->poc_name); 664 for(i = 0; i < len; i++) 665 uppercase[i] = toupper(uppercase[i]); 666 errtxt = hash_insert(ppcasm_po_hash, uppercase, (char *)pop); 667 if(errtxt != NULL && *errtxt != '\0') 668 as_fatal("error constructing pseudo-op table (%s)", errtxt); 669 } 670} 671#endif /* PPC */ 672 673/* 674 * The NeXT version of: read_a_source_file() 675 * 676 * This differs from the GNU version by taking the guts of the GNU 677 * read_a_source_file() (with the outer most loop removed) and renaming it 678 * parse_a_buffer(). With the NeXT version of read_a_source file simply 679 * containing that outer loop and a call to parse_a_buffer(). This is done 680 * So that expand_macro() and parse_line_comment() can call parse_a_buffer() 681 * with the buffers they create. 682 */ 683void 684read_a_source_file( 685char *buffer) /* 1st character of each buffer of lines is here. */ 686{ 687 cond_stateS starting_cond_state; 688 short starting_if_depth; 689 690 symbolS *symbolP; 691 692 starting_cond_state = the_cond_state; 693 starting_if_depth = if_depth; 694 695 /* Do not change segments or subsegments if this is a .include */ 696 if(doing_include == FALSE){ 697 /* 698 * This is a new file so switch start as if a .text was seen. This 699 * call to s_builtin_section() relys on the fact that the text 700 * section is first in the built in sections list. 701 */ 702 if(flagseen['n'] == FALSE) 703 text_nsect = s_builtin_section(builtin_sections); 704 705 /* 706 * If the -g flag is present generate the lead stabs for this 707 * physical file that is not an include file. Each physical file's 708 * stabs are enclosed by a pair of source name stabs, N_SO, (one at 709 * the begining of the file with the name of the file and one at the 710 * end with the name ""). This is seen by nm(1) as: 711 * 00000000 - 01 0000 SO {standard input} 712 * ... 713 * 00000020 - 01 0000 SO 714 * To make the debugger work line numbers stabs, N_SLINE, must be 715 * contained "in a function" (after a function stab, N_FUN). To 716 * make a function stab work it must have a type number. Since type 717 * numbers 1 and 2 (the 1 in "int:t1=..." and the 2 in "char:t2=..." 718 * are "magic" to the debugger we use type 3 for the types of the 719 * function stabs we generate for each text label (see the routine 720 * make_stab_for_symbol() in symbols.c). So at lead stabs at the 721 * begining of each physical file include three type stabs, L_LSYM 722 * with the correct symbol name. The since we must have the types 723 * 1 and 2 they are just what the 'C' would produce but we don't 724 * use them. Type 3 is the void type like the 'C' compiler would 725 * produce which we use for the function stabs' type. These three 726 * look like this to nm(1): 727 * 00000000 - 00 0000 LSYM int:t1=r1;-2147483648;2147483647; 728 * 00000000 - 00 0000 LSYM char:t2=r2;0;127; 729 * 00000000 - 00 0000 LSYM void:t3=3 730 * 731 * Then for each text label we see, make_stab_for_symbol() will 732 * generate a stab like this (for the example lable _main): 733 * 00000000 - 01 0007 FUN _main:F3 734 * where the 'F' in F3 is an upper case 'F' for global labels and 735 * a lower case 'f' for non globals. 736 * 737 * Then for each instruction we assemble in the text we generate 738 * a line number, S_LINE, stab (see md_assembler in m68k.c, m88k.c 739 * etc). These look like: 740 * 00000000 - 01 0008 SLINE 741 * where the 0008 is the line number. 742 */ 743 if(flagseen['g']){ 744 symbolP = symbol_new( 745 physical_input_file, 746 100 /* N_SO */, 747 text_nsect, 748 0, 749 obstack_next_free(&frags) - frag_now->fr_literal, 750 frag_now); 751 symbolP = symbol_new( 752 "int:t1=r1;-2147483648;2147483647;", 753 128 /* N_LSYM */, 754 0,0,0, 755 &zero_address_frag); 756 symbolP = symbol_new( 757 "char:t2=r2;0;127;", 758 128 /* N_LSYM */, 759 0,0,0, 760 &zero_address_frag); 761 symbolP = symbol_new( 762 "void:t3=3", 763 128 /* N_LSYM */, 764 0,0,0, 765 &zero_address_frag); 766 } 767 /* 768 * If the --gdwarf2 flag is present generate a .file for this. 769 */ 770 if(debug_type == DEBUG_DWARF2){ 771 dwarf2_file(physical_input_file, ++dwarf2_file_number); 772 } 773 } 774 else{ 775 /* 776 * If we are now reading an include file we will bracket it's 777 * stabs with a pair of: 778 * 00000010 - 01 0000 SOL include_file 779 * ... 780 * 0000001c - 01 0000 SOL previous_file 781 * We generate the first N_SOL here and the one for the 782 * previous_file in s_include() in read.c. 783 * 784 * CAVAT: This will only work if the include file starts off in the 785 * (__TEXT,__text) sections and ends in the (__TEXT,__text) section. 786 */ 787 if(flagseen['g'] && frchain_now->frch_nsect == text_nsect){ 788 symbolP = symbol_new( 789 physical_input_file, 790 132 /* N_SOL */, 791 text_nsect, 792 0, 793 obstack_next_free(&frags) - frag_now->fr_literal, 794 frag_now); 795 } 796 } 797 798 while((buffer_limit = input_scrub_next_buffer(&buffer)) != NULL){ 799#ifdef PPC 800 if(flagseen[(int)'p'] == TRUE) 801 ppcasm_parse_a_buffer(buffer); 802 else 803#endif /* PPC */ 804 parse_a_buffer(buffer); 805 } 806 807 if(the_cond_state.the_cond != starting_cond_state.the_cond || 808 the_cond_state.ignore != starting_cond_state.ignore|| 809 if_depth != starting_if_depth) 810 as_bad("file contains unmatched .ifs or .elses"); 811 812 if(macro_name != NULL) 813 as_bad("file contains unmatched .macro and .endmacro for: %s", 814 macro_name); 815 816 if(doing_include == FALSE){ 817 /* See the comment at the top of this routine for a description of 818 what is going on here */ 819 if(flagseen['n'] == FALSE) 820 text_nsect = s_builtin_section(builtin_sections); 821 if(flagseen['g']){ 822 (void)symbol_new( 823 "", 824 100 /* N_SO */, 825 text_nsect, 826 0, 827 obstack_next_free(&frags) - frag_now->fr_literal, 828 frag_now); 829 } 830 } 831} 832 833/* 834 * parse_a_buffer() operates on a buffer of lines. It drives the 835 * parsing of lines of assembly code. The lines are assumed to be "well formed" 836 * assembly so the syntax recognized in here is that produced by the output of 837 * the assembly preprocessor (app) or by the compiler when it produces a file 838 * that starts with "#NO_APP\n". A "well formed" assembly is lines with exactly 839 * zero or one leading "well formed space character" (' ', '\t' or '\f') 840 * followed by lines of: 841 * zero or more lables (a name or a digit followed by a colon) 842 * each followed by zero or one "well formed space character" 843 * exactly one of the following followed by a logicial end of line: 844 * a pseudo opcode 845 * followed by zero or one space (' ') characters and it's 846 * arguments (the space is required when the first 847 * character of the first argument could be part of a name) 848 * a macro to be expanded 849 * a machine opcode 850 * a null statement 851 * an assignment to a symbol 852 * a full line comment (in the case of "well formed" assembly it 853 * must be "#APP\n" of a collection of lines 854 * wrapped in "#APP\n ... #NO_APP\n") 855 * 856 * input: 857 * buffer pointer to the start of the buffer of lines 858 * (passed as an argument) 859 * buffer_limit pointer to the end of the buffer of lines, that is the 860 * the character it points to is NOT part of the buffer 861 * (buffer_limit is declared in this file) 862 * 863 * Assumptions about the buffer of lines: 864 * buffer[-1] == '\n' as done in input-scrub.c with the cpp macro 865 * BEFORE_STRING ("\n") 866 * buffer_limit[-1] == '\n' also as done in input-scrub.c which handles 867 * partial lines internally to itself and always 868 * passes back a buffer of complete lines. 869 * 870 * input/output: (for other parsing routines) 871 * input_line_pointer pointer to the next thing in the buffer after 872 * what has been recognized (a global) 873 */ 874static 875void 876parse_a_buffer( 877char *buffer) 878{ 879 char c; /* contains the first non-space character the current 880 word used to figure out what it is */ 881 char *s; /* points to a name with character after the name 882 replaced with a '\0' so it is a 'C' string */ 883 char after_name; /* contains that first character after a name that 884 got replaced with a '\0' */ 885 char *after_name_pointer;/* points to the end of the name where the '\0' is 886 for error use only */ 887 char end_of_line; /* contains an end of line character that got replaced 888 with a '\0' */ 889 char *start_of_line;/* points to the locical start of line we're parsing, 890 used only for macro expansion */ 891 pseudo_typeS *pop; /* pointer to a pseudo op stucture returned by 892 hash_find(po_hash, s+1) to determine if it is one */ 893 char *the_macro; /* pointer to a macro name returned by 894 hash_find(ma_hash, s) to determine if it is one */ 895 int temp; /* the value of a number label as an integer, 1: == 1 */ 896 char *backup; 897 898 /* since this is a buffer of full lines it must end in a new line */ 899 know(buffer_limit[-1] == '\n'); 900 901 input_line_pointer = buffer; 902 903 /* while we have more of this buffer to parse keep parsing */ 904 while(input_line_pointer < buffer_limit){ 905 /* 906 * At the top of this loop we know that we just parsed a label or we 907 * are at the beginning of a logical line (since their can be more 908 * than one label on a line). start_of_line is only used by 909 * expand_macro() 910 */ 911 start_of_line = input_line_pointer; 912 913 /* 914 * If we are not counting lines (as in the case when called by 915 * expand_macro() ) and we just previously scaned over a newline 916 * (a physical end of line) bump the line counters (see the comments 917 * at the head of this routine about "assumptions about the buffer" 918 * and why it is safe to index input_line_pointer by -1. 919 */ 920 if(count_lines == TRUE && input_line_pointer[-1] == '\n') 921 bump_line_counters (); 922 923 /* 924 * We expect a "well-formed" assembler statement. This means it was 925 * processed by app or produced by a compiler where the file started 926 * with a leading "#APP\n". A "well-formed" statement allows zero 927 * or one leading white space characters. 928 */ 929 c = *input_line_pointer; 930 input_line_pointer++; 931 if(c == '\t' || c == ' ' || c=='\f'){ 932 c = *input_line_pointer; 933 input_line_pointer++; 934 } 935 know(c != ' '); /* No further leading whitespace. */ 936 /* 937 * c contains the 1st significant character, *input_line_pointer 938 * points after that character. 939 */ 940 941 /* 942 * look for the begining of a name which could be one of the 943 * following assembly statements: 944 * A pseudo opcode and locical end of line 945 * A macro to be expanded and locical end of line 946 * A machine opcode and locical end of line 947 * A user-defined label (name not digit)(no end of line needed) 948 * At NeXT labels can be enclosed in ""'s so that Objective-C like 949 * names (with spaces and colons) can be part of a name, the 950 * routine get_symbol_end() knows about this. 951 */ 952 if(is_name_beginner(c) || c == '"'){ 953 if( c == '"') 954 s = input_line_pointer--; 955 else 956 s = --input_line_pointer; 957 after_name = get_symbol_end(); /* name's delimiter */ 958 after_name_pointer = input_line_pointer; 959 /* 960 * after_name is the character after symbol. That character's 961 * place in the input line is now '\0',done by get_symbol_end(). 962 * s points to the beginning of the symbol (in the case of a 963 * pseudo-op, *s == '.'). *input_line_pointer == '\0' where 964 * after_name was. after_name_pointer is recorded so it their 965 * is an error after the line has been restored the '\0' can 966 * be reset and the name printed. 967 */ 968 969 /* 970 * Look for a name that should be a pseudo op. That is it is 971 * not a user defined label or an assignment to a symbol name. 972 * This must be done so such things as ".foo:" and ".bar=1" are 973 * not mistaken for illegal pseudo ops and that something like 974 * ".long: .long 1" creates a symbol named ".long". 975 */ 976 if(*s == '.' && 977 (after_name != ':' && 978 after_name != '=' && 979 !((after_name == ' ' || after_name == '\t') && 980 input_line_pointer[1] == '=') ) ){ 981 /* 982 * Lookup what should be a pseudo op and then restore the 983 * line. 984 */ 985 pop = (pseudo_typeS *)hash_find(po_hash, s+1); 986 *input_line_pointer = after_name; 987 988 /* 989 * A pseudo op must be followed by character that is not 990 * part of a name so it can be parsed. If their is a first 991 * argument that could start with a character in a name then 992 * one "well formed space" (space or a tab) must follow the 993 * pseudo op (otherwise the space is optional). 994 */ 995 if(after_name == ' ' || after_name == '\t') 996 input_line_pointer++; 997 998 /* 999 * Now the current state of the line is the after_name has 1000 * been placed back in the line (the line is restored) and 1001 * input_line_pointer is at the start of the first argument 1002 * of the pseudo op (if any). 1003 */ 1004 if(the_cond_state.ignore){ 1005 /* 1006 * When ignoring a block of code during conditional 1007 * assembly we can't ignore .if, .else, and .endif 1008 * pseudo ops. 1009 */ 1010 if(pop != NULL && 1011 ( (pop->poc_handler == s_if) || 1012 (pop->poc_handler == s_elseif) || 1013 (pop->poc_handler == s_else) || 1014 (pop->poc_handler == s_endif) ) ) 1015 (*pop->poc_handler)(pop->poc_val); 1016 else 1017 totally_ignore_line(); 1018 } 1019 else if(macro_name){ 1020 /* 1021 * When defining a macro we can't ignore .endmacro 1022 * pseudo ops. 1023 */ 1024 if(pop != NULL && 1025 pop->poc_handler == s_endmacro) 1026 (*pop->poc_handler)(pop->poc_val); 1027 else 1028 add_to_macro_definition(start_of_line); 1029 } 1030 else{ 1031 if(pop != NULL) 1032 (*pop->poc_handler)(pop->poc_val); 1033 else{ 1034 after_name = *after_name_pointer; 1035 *after_name_pointer = '\0'; 1036 /* 1037 * If macros are on see if this is a use of a macro 1038 * otherwise it is an unknown pseudo op. 1039 */ 1040 if(macros_on == TRUE && 1041 (the_macro = hash_find(ma_hash, s)) != NULL){ 1042 *after_name_pointer = after_name; 1043 expand_macro(the_macro); 1044 } 1045 else{ 1046 as_bad ("Unknown pseudo-op: %s", s); 1047 *after_name_pointer = after_name; 1048 ignore_rest_of_line(); 1049 } 1050 } 1051 } 1052 continue; 1053 1054 } /* if(*s == '.' && ... ) */ 1055 1056 /* 1057 * If we are in a conditional and the state is that we are now 1058 * not including lines to be assembled then ignore the line. 1059 */ 1060 if(the_cond_state.ignore){ 1061 *input_line_pointer = after_name; 1062 totally_ignore_line(); 1063 } 1064 /* 1065 * If we are in the state of defining a macro then take the line 1066 * for the macro definition. 1067 */ 1068 else if(macro_name != NULL){ 1069 *input_line_pointer = after_name; 1070 add_to_macro_definition(start_of_line); 1071 } 1072 /* 1073 * Look for a user defined label. 1074 */ 1075 else if(after_name == ':'){ 1076 colon(s, 0); 1077#ifdef I860 1078 /* 1079 * Intel :: feature, which makes the label global if 1080 * followed by two "::"'s . This is ifdef'ed in so their 1081 * is no else cause thus the slightly odd logic. 1082 */ 1083 if(input_line_pointer[1] == ':'){ 1084 struct symbol *symbolP; 1085 1086 symbolP = symbol_find_or_make(s); 1087 symbolP->sy_type |= N_EXT; /* make symbol name global */ 1088 *input_line_pointer = ':'; /* Restore first ':' */ 1089 input_line_pointer++; /* step over first ':' */ 1090 } 1091#endif 1092 /* put ':' back for error messages and step over it */ 1093 *input_line_pointer = ':'; 1094 input_line_pointer++; 1095 } 1096 /* 1097 * Parse the assignment to a symbol. The syntax for this is 1098 * <symbol><equal><expression>. 1099 */ 1100 else if(after_name == '=' || 1101 ((after_name == ' ' || after_name == '\t') && 1102 input_line_pointer[1] == '=')){ 1103 equals(s); 1104 demand_empty_rest_of_line(); 1105 } 1106 /* 1107 * If macros are on see if this is a use of a macro. 1108 */ 1109 else if(macros_on == TRUE && 1110 (the_macro = hash_find(ma_hash, s)) != NULL){ 1111 *input_line_pointer = after_name; 1112 expand_macro(the_macro); 1113 } 1114 /* 1115 * Now assume it is a machine instruction and if not it 1116 * will be handled as an error. Machine instructions must be 1117 * one to a line. 1118 */ 1119 else{ 1120 *input_line_pointer = after_name; 1121 while(is_end_of_line(*input_line_pointer) == 0) 1122 input_line_pointer++; 1123 end_of_line = *input_line_pointer; 1124 *input_line_pointer = '\0'; 1125 md_assemble(s); 1126 *input_line_pointer = end_of_line; 1127 input_line_pointer++; 1128 } 1129 /* 1130 * At this point we have parsed all things that could have 1131 * started with a name. Since one of these things (user defined 1132 * lables could appear more than once on a line we do a continue 1133 * here and start parsing as if at the begining of another 1134 * logicial line. 1135 */ 1136 continue; 1137 1138 } /* if(is_name_beginner(c) || c == '"') */ 1139 1140 /* empty statement */ 1141 if(is_end_of_line(c)) 1142 continue; 1143 1144 /* 1145 * If we are in a conditional and the state is that we are now 1146 * not including lines to be assembled then ignore the line. 1147 */ 1148 if(the_cond_state.ignore){ 1149 totally_ignore_line(); 1150 continue; 1151 } 1152 1153 /* 1154 * If we are in the state of defining a macro then take the line 1155 * for the macro definition. 1156 */ 1157 if(macro_name != NULL){ 1158 add_to_macro_definition(start_of_line); 1159 continue; 1160 } 1161 1162 /* local label ("4:") */ 1163 if(isdigit(c)){ 1164 backup = input_line_pointer; 1165 temp = c - '0'; 1166 /* Read the whole number. */ 1167 while(isdigit(*input_line_pointer)) 1168 { 1169 temp = (temp * 10) + *input_line_pointer - '0'; 1170 ++input_line_pointer; 1171 } 1172 if(*input_line_pointer++ == ':'){ 1173 local_colon(temp); 1174 continue; 1175 } 1176 input_line_pointer = backup; 1177 } 1178 1179 /* 1180 * The only full line comment that should make it here is the first 1181 * of the pair of "#APP\n ... #NO_APP\n" that the compiler uses to 1182 * wrap around asm() statements. If that is the case then 1183 * parse_line_comment() creates a buffer with those lines in it and 1184 * calls parse_a_buffer() with that buffer. Then returns here 1185 * skiping over that part of the current buffer. 1186 */ 1187 if(c != '\0' && strchr(md_line_comment_chars, c) != NULL){ 1188 parse_line_comment(&buffer); 1189 continue; 1190 } 1191 1192 as_bad("Junk character %d (%c).", c, c); 1193 ignore_rest_of_line(); 1194 1195 } /* while(input_line_pointer < buffer_limit) */ 1196} 1197 1198#ifdef PPC 1199/* 1200 * asmppc_parse_a_buffer() operates on a buffer of lines. It drives the 1201 * parsing of lines of assembly code for the PowerPC -ppcasm option. 1202 * 1203.* The lines are processed by the assembly preprocessor (app) but spaces have 1204 * been preserved by it when -ppcasm is specified. 1205 * 1206 * ppcasm assembly lines have the following fields: 1207 * 1208 * Label Operation Operand Comment 1209 * 1210 * The label identifier in the Label field must end with a space or a colon (and 1211 * must start at the beginning of the line) 1212 * 1213 * The operation field contains the assembler directive, the instruction 1214 * mnemonic or macro call. 1215 * 1216 * The operand follows the operation field for machine instructions, assembler 1217 * directives, and macros. However not all operations require operands. The 1218 * operand field is separated from the operation field by at least one space. 1219 * The operand field can contain subfields separated by commas. The number of 1220 * subfields is determined by the type of operation. Spaces can appear 1221 * anywhere in the operand field except within a single symbol. 1222 * 1223 * The comment field starts with a ; or a # . 1224 * 1225 * input: 1226 * buffer pointer to the start of the buffer of lines 1227 * (passed as an argument) 1228 * buffer_limit pointer to the end of the buffer of lines, that is the 1229 * the character it points to is NOT part of the buffer 1230 * (buffer_limit is declared in this file) 1231 * 1232 * Assumptions about the buffer of lines: 1233 * buffer[-1] == '\n' as done in input-scrub.c with the cpp macro 1234 * BEFORE_STRING ("\n") 1235 * buffer_limit[-1] == '\n' also as done in input-scrub.c which handles 1236 * partial lines internally to itself and always 1237 * passes back a buffer of complete lines. 1238 * 1239 * input/output: (for other parsing routines) 1240 * input_line_pointer pointer to the next thing in the buffer after 1241 * what has been recognized (a global) 1242 */ 1243static 1244void 1245ppcasm_parse_a_buffer( 1246char *buffer) 1247{ 1248 char c; /* contains the first non-space character the current 1249 word used to figure out what it is */ 1250 char *s; /* points to a name with character after the name 1251 replaced with a '\0' so it is a 'C' string */ 1252 char after_name; /* contains that first character after a name that 1253 got replaced with a '\0' */ 1254 char *after_name_pointer;/* points to the end of the name where the '\0' is 1255 for error use only */ 1256 char end_of_line; /* contains an end of line character that got replaced 1257 with a '\0' */ 1258 char *start_of_line;/* points to the locical start of line we're parsing, 1259 used only for macro expansion */ 1260 pseudo_typeS *pop; /* pointer to a pseudo op stucture returned by 1261 hash_find(ppcasm_po_hash, s) to determine if it is */ 1262 1263 /* since this is a buffer of full lines it must end in a new line */ 1264 know(buffer_limit[-1] == '\n'); 1265 1266 input_line_pointer = buffer; 1267 1268 /* while we have more of this buffer to parse keep parsing */ 1269 while(input_line_pointer < buffer_limit){ 1270 /* 1271 * Save a pointer to the start of the line so we can tell a label 1272 * without a trailing colon from the operation field. 1273 */ 1274 start_of_line = input_line_pointer; 1275 1276 /* 1277 * If we are not counting lines (as in the case when called by 1278 * expand_macro() ) and we just previously scaned over a newline 1279 * (a physical end of line) bump the line counters (see the comments 1280 * at the head of this routine about "assumptions about the buffer" 1281 * and why it is safe to index input_line_pointer by -1. 1282 */ 1283 if(count_lines == TRUE && input_line_pointer[-1] == '\n') 1284 bump_line_counters (); 1285 1286 /* 1287 * We are at the start of a line and if there is a name then this 1288 * must be a label. 1289 */ 1290 c = *input_line_pointer; 1291 if(is_name_beginner(c)){ 1292 s = input_line_pointer; 1293 while(is_part_of_name(c)){ 1294 input_line_pointer++; 1295 c = *input_line_pointer; 1296 } 1297 after_name = c; 1298 after_name_pointer = input_line_pointer; 1299 *after_name_pointer = '\0'; 1300 colon(s, 0); 1301 *after_name_pointer = after_name; 1302 /* 1303 * A colon after the name is optional and may have a spaces 1304 * before it. 1305 */ 1306 if(*input_line_pointer == ' ') 1307 input_line_pointer++; 1308 if(c == ':'){ 1309 input_line_pointer++; 1310 c = *input_line_pointer; 1311 } 1312 } 1313 1314 /* 1315 * Now that we have passed the label at the start of the line if 1316 * any skip any spaces that follow it. 1317 */ 1318 if(*input_line_pointer == ' ') 1319 input_line_pointer++; 1320 c = *input_line_pointer; 1321 1322 /* 1323 * The next thing on the line is the operation field which is a name 1324 * of a directive, instruction mnemonic or macro name. 1325 */ 1326 if(is_name_beginner(c)){ 1327 s = input_line_pointer; 1328 while(is_part_of_name(c)){ 1329 input_line_pointer++; 1330 c = *input_line_pointer; 1331 } 1332 after_name = c; 1333 after_name_pointer = input_line_pointer; 1334 *after_name_pointer = '\0'; 1335 1336 /* 1337 * Lookup what might be a ppcasm pseudo op and then restore the 1338 * line. 1339 */ 1340 pop = (pseudo_typeS *)hash_find(ppcasm_po_hash, s); 1341 *input_line_pointer = after_name; 1342 1343 if(*input_line_pointer == ' ') 1344 input_line_pointer++; 1345 1346 if(pop != NULL){ 1347 (*pop->poc_handler)(pop->poc_val); 1348 continue; 1349 } 1350 /* 1351 * Now assume the name in the operation field is a machine 1352 * instruction and if not it will be handled as an error. 1353 */ 1354 else{ 1355 while(is_end_of_line(*input_line_pointer) == 0) 1356 input_line_pointer++; 1357 end_of_line = *input_line_pointer; 1358 *input_line_pointer = '\0'; 1359 md_assemble(s); 1360 *input_line_pointer = end_of_line; 1361 input_line_pointer++; 1362 continue; 1363 } 1364 } 1365 1366 /* 1367 * If we ran into the end of the line we are done with this line. 1368 */ 1369 /* empty statement */ 1370 if(is_end_of_line(c)){ 1371 input_line_pointer++; 1372 continue; 1373 } 1374 1375 as_bad("Junk character %d (%c).", c, c); 1376 ignore_rest_of_line(); 1377 1378 } /* while(input_line_pointer < buffer_limit) */ 1379} 1380#endif /* PPC */ 1381 1382/* 1383 * parse_line_comment() parses a line comment for parse_a_buffer(). Since 1384 * parse_a_buffer() only operates on "well formed" assembly the only legal 1385 * line comment that should appear is a "#APP\n ... #NO_APP\n" pair which 1386 * tells us to scrub the characters between them and then parse them. 1387 */ 1388static 1389void 1390parse_line_comment( 1391char **buffer) 1392{ 1393 char *s; 1394 char *ends; 1395 1396 char *new_buf; 1397 char *new_tmp; 1398 int new_length; 1399 1400 char *tmp_buf; 1401 char *old_input_line_pointer; 1402 char *old_buffer_limit; 1403 1404 1405 /* parse_a_buffer should never see any line comment if app is on */ 1406 know(preprocess == FALSE); 1407 1408 s = input_line_pointer; 1409 /* This must be a #APP\n line comment if not ignore it */ 1410 if(strncmp(s,"APP\n",4) != 0) 1411 return; 1412 1413 if(count_lines == TRUE) 1414 bump_line_counters(); 1415 s += sizeof("APP\n") - 1; 1416 1417 /* 1418 * Search for the matching #NO_APP\n in this buffer, if it is found 1419 * in this buffer the un-scrubed characters between the "#APP\n" and 1420 * "#NO_APP\n" start where s is pointing to and end where ends is 1421 * pointing to. 1422 */ 1423 ends = strstr(s, "#NO_APP\n"); 1424 1425 tmp_buf = NULL; 1426 if(ends == NULL){ 1427 /* The matching #NO_APP\n for the #APP\n wasn't in this buffer. */ 1428 int tmp_len; 1429 int num; 1430 1431 /* 1432 * First create a temporary place (tmp_buf of size tmp_len) to 1433 * collect the un-scrubbed characters between the "#APP\n" and the 1434 * "#NO_APP\n" (or end of file) when we find it in some buffer. 1435 */ 1436 tmp_len = buffer_limit - s; 1437 tmp_buf = xmalloc(tmp_len); 1438 1439 /* 1440 * Copy the end of the buffer that contains the first part of 1441 * the un-scrubbed contents starting just after the "#APP\n". 1442 * This is so the the current buffer (buffer) can be used to 1443 * collect the the rest of the un-scrubbed contents and to find 1444 * the matching "#NO_APP\n". 1445 */ 1446 memcpy(tmp_buf, s, tmp_len); 1447 1448 /* 1449 * This loop collects the remaining un-scrubed contents between 1450 * "#APP\n" and the "#NO_APP\n" into tmp_buf (adjusting tmp_len) 1451 * and looks for the matching "#NO_APP\n". 1452 */ 1453 do{ 1454 buffer_limit = input_scrub_next_buffer(buffer); 1455 /* 1456 * We treat runing into the end of the file as if it was the 1457 * "#NO_APP" we were looking for. 1458 */ 1459 if(buffer_limit == NULL) 1460 break; 1461 1462 ends = strstr(*buffer, "#NO_APP\n"); 1463 if(ends != NULL) 1464 num = ends - *buffer; 1465 else 1466 num = buffer_limit - *buffer; 1467 1468 tmp_buf = xrealloc(tmp_buf, tmp_len + num); 1469 memcpy(tmp_buf + tmp_len, *buffer, num); 1470 tmp_len += num; 1471 }while(ends == NULL); 1472 1473 /* 1474 * Now set up buffer, buffer_limit and input_line_pointer be past 1475 * all the characters of the "#APP\n ... #NO_APP\n" set so that 1476 * when we return parsing will be picked up from their. 1477 */ 1478 if(ends != NULL) 1479 input_line_pointer = ends + sizeof("#NO_APP\n") - 1; 1480 else{ 1481 input_line_pointer = *buffer; 1482 buffer_limit = *buffer; 1483 } 1484 1485 /* 1486 * Now set s to the start, and ends to the end of the un-scrubed 1487 * contents of the collected characters between the "#APP\n" and 1488 * "#NO_APP\n" pair. 1489 */ 1490 s = tmp_buf; 1491 ends = s + tmp_len; 1492 } 1493 else{ 1494 /* 1495 * The matching "#NO_APP\n" was in the buffer as we were called so 1496 * s is the start, and ends is the end of the un-scrubed contents 1497 * of the characters between the "#APP\n" and "#NO_APP\n" pair. 1498 * Now to set up buffer, buffer_limit and input_line_pointer be past 1499 * all the characters of the "#APP\n ... #NO_APP\n" set so that 1500 * when we return parsing will be picked up from their all that has 1501 * to be done is move the input_line_pointer past the "#NO_APP\n". 1502 */ 1503 input_line_pointer = ends + sizeof("#NO_APP\n") - 1; 1504 } 1505 1506 /* 1507 * Now that we have the un-scrubed characters beween s and ends setup 1508 * to scrub them into a new buffer (new_buf of size new_length to 1509 * new_tmp). 1510 */ 1511 new_length = 100; 1512 new_buf = xmalloc(new_length); 1513 new_tmp = new_buf; 1514 *new_tmp++ = '\n'; /* place leading \n in buffer for parse_a_buffer */ 1515 1516 scrub_string = s; 1517 scrub_last_string = ends; 1518 for(;;){ 1519 int c; 1520 1521 c = do_scrub_next_char_from_string(); 1522 if(c == EOF) 1523 break; 1524 *new_tmp++ = c; 1525 if(new_tmp == new_buf + new_length){ 1526 new_buf = xrealloc(new_buf, new_length + 100); 1527 new_tmp = new_buf + new_length; 1528 new_length += 100; 1529 } 1530 } 1531 *new_tmp = '\n'; /* place trailing \n in buffer for parse_a_buffer */ 1532 1533 /* 1534 * If we used a temporary buffer to collect the un-scrubbed characters 1535 * it is no longer needed and can be free()'ed. 1536 */ 1537 if(tmp_buf != NULL) 1538 free(tmp_buf); 1539 1540 /* 1541 * Now we are ready to recursively call parse_a_buffer() with our buffer 1542 * of scrubed characters. So save the state of parse_a_buffer() and set 1543 * it up with our buffer of scrubed characters. 1544 */ 1545 old_input_line_pointer = input_line_pointer; 1546 old_buffer_limit = buffer_limit; 1547 1548 input_line_pointer = new_buf; 1549 buffer_limit = new_tmp; 1550#ifdef PPC 1551 if(flagseen[(int)'p'] == TRUE) 1552 ppcasm_parse_a_buffer(new_buf); 1553 else 1554#endif /* PPC */ 1555 parse_a_buffer(new_buf); 1556 1557 /* 1558 * Free the buffer that held the scrubbed characters 1559 */ 1560 free(new_buf); 1561 1562 /* 1563 * After coming back from our recursive call parse_a_buffer() we want 1564 * resume parsing after the "#NO_APP\n". So bump the line counters 1565 * for the "#NO_APP\n" and restore the state so we can return to 1566 * parse_a_buffer(). 1567 */ 1568 if(count_lines == TRUE) 1569 bump_line_counters(); 1570 input_line_pointer = old_input_line_pointer; 1571 buffer_limit = old_buffer_limit; 1572 1573 return; 1574} 1575 1576/* 1577 * s_abort() implements the pseudo op: 1578 * .abort [ "abort_string" ] 1579 */ 1580static 1581void 1582s_abort( 1583uintptr_t value) 1584{ 1585 char *p; 1586 1587 p = input_line_pointer; 1588 while(is_end_of_line(*p) == FALSE) 1589 p++; 1590 *p = '\0'; 1591 1592 as_fatal(".abort %s detected. Assembly stopping.", input_line_pointer); 1593} 1594 1595#if !defined(I860) /* i860 has it's own align and org */ 1596/* 1597 * s_align_bytes() handles the .align pseudo-op where ".align 4" means align to 1598 * a 4 byte boundary. 1599 */ 1600static 1601void 1602s_align_bytes( 1603uintptr_t arg) 1604{ 1605 s_align(arg, 1); 1606} 1607 1608/* 1609 * s_align_ptwo() handles the .align pseudo-op on where ".align 4" means align 1610 * to a 2**4 boundary. 1611 */ 1612static 1613void 1614s_align_ptwo( 1615uintptr_t arg) 1616{ 1617 s_align(arg, 0); 1618} 1619 1620/* 1621 * s_align() implements the pseudo ops 1622 * .align align_expression [ , 1byte_fill_expression [,max_bytes_to_fill]] 1623 * .p2align align_expression [ , 1byte_fill_expression [,max_bytes_to_fill]] 1624 * .p2alignw align_expression [ , 2byte_fill_expression [,max_bytes_to_fill]] 1625 * .p2alignl align_expression [ , 4byte_fill_expression [,max_bytes_to_fill]] 1626 * .align32 align_expression [ , 4byte_fill_expression [,max_bytes_to_fill]] 1627 * Where align_expression is a power of 2 alignment. 1628 * 1629 * The parameter fill_size can only be 1, 2 or 4 which is the size of the 1630 * fill_expression. If the parameter bytes_p is non-zero the alignment value 1631 * is interpreted as the byte boundary, rather than the power of 2. 1632 */ 1633static 1634void 1635s_align( 1636int fill_size, 1637int bytes_p) 1638{ 1639 int power_of_2_alignment, byte_alignment, i; 1640 int32_t temp_fill, fill_specified, max_bytes_to_fill; 1641 char fill[4]; 1642 1643 if(fill_size != 1 && fill_size != 2 && fill_size != 4) 1644 as_bad("Internal error, s_align() called with bad fill_size %d", 1645 fill_size); 1646 1647 power_of_2_alignment = 0; 1648 if(bytes_p == 0){ 1649 power_of_2_alignment = get_absolute_expression(); 1650 } 1651 else{ 1652 byte_alignment = get_absolute_expression(); 1653 if(byte_alignment != 0){ 1654 for(i = 0; (byte_alignment & 1) == 0; i++) 1655 byte_alignment >>= 1; 1656 if(byte_alignment != 1) 1657 as_bad("alignment not a power of 2"); 1658 power_of_2_alignment = i; 1659 } 1660 } 1661#define MAX_ALIGNMENT (15) 1662 if(power_of_2_alignment > MAX_ALIGNMENT) 1663 as_warn("Alignment too large: %d. assumed.", 1664 power_of_2_alignment = MAX_ALIGNMENT); 1665 else if(power_of_2_alignment < 0){ 1666 as_warn("Alignment negative. 0 assumed."); 1667 power_of_2_alignment = 0; 1668 } 1669 temp_fill = 0; 1670 fill_specified = 0; 1671 max_bytes_to_fill = 0; 1672 if(*input_line_pointer == ','){ 1673 input_line_pointer ++; 1674 if(*input_line_pointer != ','){ 1675 temp_fill = get_absolute_expression (); 1676 fill_specified = 1; 1677 } 1678 if(*input_line_pointer == ','){ 1679 input_line_pointer ++; 1680 max_bytes_to_fill = get_absolute_expression (); 1681 } 1682 } 1683 1684 /* 1685 * If the fill has not been specified and this section has 1686 * machine instructions then pad the section with nops. 1687 */ 1688 if(fill_specified == 0 && 1689 ((frchain_now->frch_section.flags & S_ATTR_SOME_INSTRUCTIONS) == 1690 S_ATTR_SOME_INSTRUCTIONS || 1691 (frchain_now->frch_section.flags & S_ATTR_PURE_INSTRUCTIONS) == 1692 S_ATTR_PURE_INSTRUCTIONS) ){ 1693#ifdef M68K 1694 if(power_of_2_alignment >= 1){ 1695 temp_fill = 0x4e71; /* m68k nop */ 1696 fill_size = 2; /* 2 byte fill size */ 1697 } 1698#endif /* M68K */ 1699#ifdef I386 1700 temp_fill = 0x90; /* i386 nop */ 1701 fill_size = 1; /* 1 byte fill size */ 1702#endif /* I386 */ 1703#ifdef HPPA 1704 if(power_of_2_alignment >= 2){ 1705 temp_fill = 0x08000240; /* hppa nop */ 1706 fill_size = 4; /* 4 byte fill size */ 1707 } 1708#endif /* HPPA */ 1709#ifdef SPARC 1710 if(power_of_2_alignment >= 2){ 1711 temp_fill = 0x01000000; /* sparc nop */ 1712 fill_size = 4; /* 4 byte fill size */ 1713 } 1714#endif /* SPARC */ 1715#ifdef M88K 1716 if(power_of_2_alignment >= 2){ 1717 temp_fill = 0xf4005800; /* m88k 'or r0,r0,r0' instruction */ 1718 fill_size = 4; /* 4 byte fill size */ 1719 } 1720#endif /* M88K */ 1721#ifdef PPC 1722 if(power_of_2_alignment >= 2){ 1723 temp_fill = 0x60000000; /* ppc nop */ 1724 fill_size = 4; /* 4 byte fill size */ 1725 } 1726#endif /* PPC */ 1727#ifdef ARM 1728 if(power_of_2_alignment >= 1){ 1729 extern int thumb_mode; /* from arm.c */ 1730 if(thumb_mode){ 1731 if(archflag_cpusubtype == CPU_SUBTYPE_ARM_V7 || 1732 archflag_cpusubtype == CPU_SUBTYPE_ARM_V7F || 1733 archflag_cpusubtype == CPU_SUBTYPE_ARM_V7K){ 1734 temp_fill = 0xbf00; /* thumb2 nop */ 1735 fill_size = 2; /* 2 byte fill size */ 1736 } 1737 else{ 1738 temp_fill = 0x46c0; /* thumb1 nop */ 1739 fill_size = 2; /* 2 byte fill size */ 1740 } 1741 } 1742 else if(power_of_2_alignment >= 2){ 1743 temp_fill = 0xe1a00000; /* arm nop */ 1744 fill_size = 4; /* 4 byte fill size */ 1745 } 1746 } 1747#endif /* ARM */ 1748 ; /* empty statement for other architectures */ 1749 } 1750 1751 md_number_to_chars(fill, temp_fill, fill_size); 1752 1753 /* Only make a frag if we HAVE to. . . */ 1754 if(power_of_2_alignment != 0) 1755 frag_align(power_of_2_alignment, fill, fill_size,max_bytes_to_fill); 1756 1757 /* 1758 * If there is not a max_bytes_to_fill specified and this alignment is 1759 * larger than any previous alignment then this becomes the section's 1760 * alignment. If there is a max_bytes_to_fill then this is handled in 1761 * relax_section() if the alignment can be done without exceeding 1762 * max_bytes_to_fill. 1763 */ 1764 if(max_bytes_to_fill == 0 && 1765 frchain_now->frch_section.align < 1766 (uint32_t)power_of_2_alignment) 1767 frchain_now->frch_section.align = power_of_2_alignment; 1768 1769 demand_empty_rest_of_line(); 1770} 1771#endif /* !defined(I860) i860 has it's own align and org */ 1772 1773/* 1774 * s_comm() implements the pseudo op: 1775 * .comm name , expression 1776 */ 1777static 1778void 1779s_comm( 1780uintptr_t value) 1781{ 1782 char *name; 1783 char c; 1784 char *p; 1785 signed_target_addr_t temp; 1786 symbolS *symbolP; 1787 int power_of_2_alignment; 1788 1789 if(*input_line_pointer == '"') 1790 name = input_line_pointer + 1; 1791 else 1792 name = input_line_pointer; 1793 c = get_symbol_end(); 1794 /* just after name is now '\0' */ 1795 p = input_line_pointer; 1796 *p = c; 1797 SKIP_WHITESPACE(); 1798 if(*input_line_pointer != ','){ 1799 as_bad("Expected comma after symbol-name"); 1800 ignore_rest_of_line(); 1801 return; 1802 } 1803 input_line_pointer++; /* skip ',' */ 1804 if((temp = get_absolute_expression ()) < 0){ 1805 as_bad(".COMMon length (" TA_DFMT ".) <0! Ignored.", temp); 1806 ignore_rest_of_line(); 1807 return; 1808 } 1809 power_of_2_alignment = 0; 1810#define MAX_ALIGNMENT (15) 1811 if(*input_line_pointer == ','){ 1812 input_line_pointer++; 1813 power_of_2_alignment = get_absolute_expression(); 1814 if(power_of_2_alignment > MAX_ALIGNMENT) 1815 as_warn("Alignment too large: %d. assumed.", 1816 power_of_2_alignment = MAX_ALIGNMENT); 1817 else if(power_of_2_alignment < 0){ 1818 as_warn("Alignment negative. 0 assumed."); 1819 power_of_2_alignment = 0; 1820 } 1821 } 1822 *p = 0; 1823 symbolP = symbol_find_or_make(name); 1824 *p = c; 1825 if((symbolP->sy_type & N_TYPE) != N_UNDF || 1826 symbolP->sy_other != 0 || 1827 (symbolP->sy_desc & ~N_NO_DEAD_STRIP) != 0) { 1828 as_bad("Ignoring attempt to re-define symbol"); 1829 ignore_rest_of_line(); 1830 return; 1831 } 1832 if(symbolP->sy_value != 0){ 1833 if(symbolP->sy_value != (uint32_t)temp) 1834 as_bad("Length of .comm \"%s\" is already " TA_DFMT ". Not " 1835 "changed to " TA_DFMT ".", symbolP->sy_name, 1836 symbolP->sy_value, temp); 1837 } 1838 else{ 1839 symbolP -> sy_value = temp; 1840 symbolP -> sy_type |= N_EXT; 1841 SET_COMM_ALIGN(symbolP->sy_desc, power_of_2_alignment); 1842 } 1843 know(symbolP->sy_frag == &zero_address_frag); 1844 demand_empty_rest_of_line(); 1845} 1846 1847/* 1848 * s_desc() implements the pseudo op: 1849 * .desc name , expression 1850 * sets the n_desc field of a symbol. 1851 */ 1852static 1853void 1854s_desc( 1855uintptr_t value) 1856{ 1857 char *name; 1858 char c; 1859 char *p; 1860 symbolS *symbolP; 1861 int temp; 1862 1863 if(*input_line_pointer == '"') 1864 name = input_line_pointer + 1; 1865 else 1866 name = input_line_pointer; 1867 c = get_symbol_end(); 1868 p = input_line_pointer; 1869 symbolP = symbol_table_lookup(name); 1870 *p = c; 1871 SKIP_WHITESPACE(); 1872 if(*input_line_pointer != ','){ 1873 *p = 0; 1874 as_bad("Expected comma after name \"%s\"", name); 1875 *p = c; 1876 ignore_rest_of_line(); 1877 } 1878 else{ 1879 input_line_pointer++; 1880 temp = get_absolute_expression(); 1881 *p = 0; 1882 symbolP = symbol_find_or_make(name); 1883 *p = c; 1884 symbolP->sy_desc = temp; 1885 } 1886 demand_empty_rest_of_line(); 1887} 1888 1889/* 1890 * s_app_file() implements the pseudo op: 1891 * .file name [ level_number ] 1892 * the level number is generated by /lib/cpp and is just ignored. 1893 */ 1894void 1895s_app_file( 1896uintptr_t value) 1897{ 1898 char *s; 1899 int length; 1900 struct symbol *symbolP; 1901 1902 /* Some assemblers tolerate immediately following '"' */ 1903 if((s = demand_copy_string(&length))){ 1904 SKIP_WHITESPACE(); 1905 if(*input_line_pointer >= '0' && *input_line_pointer <= '9'){ 1906 while(*input_line_pointer >= '0' && 1907 *input_line_pointer <= '9') 1908 input_line_pointer++; 1909 } 1910 new_logical_line(s, -1); 1911 demand_empty_rest_of_line(); 1912 1913 /* 1914 * This is to generate stabs for debugging assembly code. 1915 * See the comments about stabs in read_a_source_file() 1916 * for a description of what is going on here. 1917 */ 1918 if(flagseen['g'] && frchain_now->frch_nsect == text_nsect){ 1919 symbolP = symbol_new( 1920 logical_input_file, 1921 132 /* N_SOL */, 1922 text_nsect, 1923 0, 1924 obstack_next_free(&frags) - frag_now->fr_literal, 1925 frag_now); 1926 } 1927 } 1928} 1929 1930/* 1931 * s_fill() implements the pseudo op: 1932 * .fill repeat_expression , fill_size , fill_expression 1933 */ 1934static 1935void 1936s_fill( 1937uintptr_t value) 1938{ 1939 int32_t temp_repeat; 1940 int32_t temp_size; 1941 int32_t temp_fill; 1942 char *p; 1943 1944 if(get_absolute_expression_and_terminator(&temp_repeat) != ','){ 1945 input_line_pointer--; /* Backup over what was not a ','. */ 1946 as_bad("Expect comma after rep-size in .fill"); 1947 ignore_rest_of_line(); 1948 return; 1949 } 1950 if(get_absolute_expression_and_terminator(&temp_size) != ','){ 1951 input_line_pointer--; /* Backup over what was not a ','. */ 1952 as_bad("Expected comma after size in .fill"); 1953 ignore_rest_of_line(); 1954 return; 1955 } 1956 /* 1957 * This is to be compatible with BSD 4.2 AS, not for any rational 1958 * reason. 1959 */ 1960#define BSD_FILL_SIZE_CROCK_8 (8) 1961 if(temp_size > BSD_FILL_SIZE_CROCK_8){ 1962 as_bad(".fill size clamped to %d.", BSD_FILL_SIZE_CROCK_8); 1963 temp_size = BSD_FILL_SIZE_CROCK_8 ; 1964 } 1965 if(temp_size < 0){ 1966 as_bad("Size negative: .fill ignored."); 1967 temp_size = 0; 1968 } 1969 /* 1970 * bug fix, if md_number_to_chars() is called with something other than 1971 * 1,2 or 4 it calls abort(). So we don't let the size be something 1972 * like 3. Bug #13017. 1973 */ 1974 else if(temp_size != 0 && 1975 temp_size != 1 && 1976 temp_size != 2 && 1977 temp_size != 4 && 1978 temp_size != 8){ 1979 as_bad(".fill size must be 0,1,2,4 or 8, .fill ignored"); 1980 temp_size = 0; 1981 } 1982 else if(temp_repeat <= 0){ 1983 as_bad(".fill repeat <= 0, .fill ignored"); 1984 temp_size = 0; 1985 } 1986 temp_fill = get_absolute_expression(); 1987 /* 1988 * Note: .fill (),0 emits no frag (since we are asked to .fill 0 bytes) 1989 * but emits no error message because it seems a legal thing to do. 1990 * It is a degenerate case of .fill but could be emitted by a compiler. 1991 */ 1992 if(temp_size != 0){ 1993 p = frag_var(rs_fill, 1994 (int)temp_size, 1995 (int)temp_size, 1996 (relax_substateT)0, 1997 (symbolS *)0, 1998 temp_repeat, 1999 (char *)0); 2000 memset(p, '\0', (int)temp_size); 2001 /* 2002 * The magic number BSD_FILL_SIZE_CROCK_4 is from BSD 4.2 VAX 2003 * flavoured AS. The following bizzare behaviour is to be 2004 * compatible with above. I guess they tried to take up to 8 2005 * bytes from a 4-byte expression and they forgot to sign extend. 2006 */ 2007#define BSD_FILL_SIZE_CROCK_4 (4) 2008 md_number_to_chars(p, 2009 temp_fill, 2010 temp_size > BSD_FILL_SIZE_CROCK_4 ? 2011 BSD_FILL_SIZE_CROCK_4 : (int)temp_size); 2012 } 2013 demand_empty_rest_of_line(); 2014} 2015 2016/* 2017 * s_globl() implements the pseudo op: 2018 * .globl name [ , name ] 2019 */ 2020void 2021s_globl( 2022uintptr_t value) 2023{ 2024 char *name; 2025 int c; 2026 symbolS *symbolP; 2027 2028 do{ 2029 if(*input_line_pointer == '"') 2030 name = input_line_pointer + 1; 2031 else 2032 name = input_line_pointer; 2033 c = get_symbol_end(); 2034 symbolP = symbol_find_or_make(name); 2035 *input_line_pointer = c; 2036 SKIP_WHITESPACE(); 2037 symbolP->sy_type |= N_EXT; 2038 if(c == ','){ 2039 input_line_pointer++; 2040 SKIP_WHITESPACE(); 2041 if(*input_line_pointer == '\n') 2042 c = '\n'; 2043 } 2044 }while(c == ','); 2045 demand_empty_rest_of_line(); 2046} 2047 2048/* 2049 * s_private_extern() implements the pseudo op: 2050 * .private_extern name [ , name ] 2051 */ 2052static 2053void 2054s_private_extern( 2055uintptr_t value) 2056{ 2057 char *name; 2058 int c; 2059 symbolS *symbolP; 2060 2061 do{ 2062 if(*input_line_pointer == '"') 2063 name = input_line_pointer + 1; 2064 else 2065 name = input_line_pointer; 2066 c = get_symbol_end(); 2067 symbolP = symbol_find_or_make(name); 2068 *input_line_pointer = c; 2069 SKIP_WHITESPACE(); 2070 symbolP->sy_type |= N_EXT; 2071 symbolP->sy_type |= N_PEXT; 2072 if(c == ','){ 2073 input_line_pointer++; 2074 SKIP_WHITESPACE(); 2075 if(*input_line_pointer == '\n') 2076 c = '\n'; 2077 } 2078 }while(c == ','); 2079 demand_empty_rest_of_line(); 2080} 2081 2082#if !(defined(I386) && defined(ARCH64)) 2083/* 2084 * s_indirect_symbol() implements the pseudo op: 2085 * .indirect_symbol name 2086 */ 2087static 2088void 2089s_indirect_symbol( 2090uintptr_t value) 2091{ 2092 char *name; 2093 int c; 2094 uint32_t section_type; 2095 2096 if(!flagseen['k']) 2097 as_fatal("incompatible feature used: .indirect_symbol (must " 2098 "specify \"-dynamic\" to be used)"); 2099 if(frchain_now == NULL){ 2100 know(flagseen['n']); 2101 as_fatal("with -n a section directive must be seen before assembly " 2102 "can begin"); 2103 } 2104 section_type = frchain_now->frch_section.flags & SECTION_TYPE; 2105 if(section_type != S_NON_LAZY_SYMBOL_POINTERS && 2106 section_type != S_LAZY_SYMBOL_POINTERS && 2107 section_type != S_SYMBOL_STUBS){ 2108 as_bad("indirect symbol not in a symbol pointer or stub section, " 2109 ".indirect_symbol ignored"); 2110 ignore_rest_of_line(); 2111 return; 2112 } 2113 2114 if(*input_line_pointer == '"') 2115 name = input_line_pointer + 1; 2116 else 2117 name = input_line_pointer; 2118 c = get_symbol_end(); 2119 indirect_symbol_new(name, 2120 frag_now, 2121 obstack_next_free(&frags) - frag_now->fr_literal); 2122 *input_line_pointer = c; 2123 2124 demand_empty_rest_of_line(); 2125} 2126#endif 2127 2128/* 2129 * s_lcomm() implements the pseudo op: 2130 * .lcomm name , size_expression [ , align_expression ] 2131 */ 2132static 2133void 2134s_lcomm( 2135uintptr_t value) 2136{ 2137 char *name; 2138 char c; 2139 char *p; 2140 signed_target_addr_t size; 2141 symbolS *symbolP; 2142 int align; 2143 static frchainS *bss = NULL; 2144 2145 if(*input_line_pointer == '"') 2146 name = input_line_pointer + 1; 2147 else 2148 name = input_line_pointer; 2149 c = get_symbol_end(); 2150 p = input_line_pointer; 2151 *p = c; 2152 SKIP_WHITESPACE(); 2153 if(*input_line_pointer != ','){ 2154 as_bad("Expected comma after name"); 2155 ignore_rest_of_line(); 2156 return; 2157 } 2158 input_line_pointer ++; 2159 if((size = get_absolute_expression()) < 0){ 2160 as_bad("BSS length (" TA_DFMT ".) <0! Ignored.", size); 2161 ignore_rest_of_line(); 2162 return; 2163 } 2164#define MAX_ALIGNMENT (15) 2165 align = 0; 2166 if(*input_line_pointer == ','){ 2167 input_line_pointer++; 2168 align = get_absolute_expression(); 2169 if(align > MAX_ALIGNMENT){ 2170 as_warn("Alignment too large: %d. assumed.", MAX_ALIGNMENT); 2171 align = MAX_ALIGNMENT; 2172 } 2173 else if(align < 0){ 2174 as_warn("Alignment negative. 0 assumed."); 2175 align = 0; 2176 } 2177 } 2178 *p = 0; 2179 symbolP = symbol_find_or_make(name); 2180 *p = c; 2181 2182 if((symbolP->sy_type & N_TYPE) == N_UNDF && symbolP->sy_value == 0){ 2183 if(bss == NULL){ 2184 bss = section_new(SEG_DATA, SECT_BSS, S_ZEROFILL, 0, 0); 2185 bss->frch_root = xmalloc(SIZEOF_STRUCT_FRAG); 2186 memset(bss->frch_root, '\0', SIZEOF_STRUCT_FRAG); 2187 bss->frch_last = bss->frch_root; 2188 } 2189 bss->frch_root->fr_address = rnd(bss->frch_root->fr_address, 2190 1 << align); 2191 symbolP->sy_value = bss->frch_root->fr_address; 2192 symbolP->sy_type = N_SECT; 2193 symbolP->sy_other = bss->frch_nsect; 2194 symbolP->sy_frag = bss->frch_root; 2195 bss->frch_root->fr_address += size; 2196 /* 2197 * If this alignment is larger than any previous alignment then this 2198 * becomes the section's alignment. 2199 */ 2200 if(bss->frch_section.align < (uint32_t)align) 2201 bss->frch_section.align = align; 2202 } 2203 else 2204 as_bad("Ignoring attempt to re-define symbol."); 2205 demand_empty_rest_of_line(); 2206} 2207 2208/* 2209 * s_line() implements the pseudo op: 2210 * .line line_number 2211 */ 2212void 2213s_line( 2214uintptr_t value) 2215{ 2216 /* 2217 * Assume delimiter is part of expression. BSD4.2 as fails with 2218 * delightful bug, so we are not being incompatible here. 2219 */ 2220 /* 2221 * Since the assembler bumps it's line counters at the end of a line 2222 * and it is the case that the .line is on it's own line what the 2223 * intent is that the line number is for the next line. Thus 2224 * the -1 . This is the way cpp'ed assembler files work which is the 2225 * common case. 2226 */ 2227 new_logical_line((char *)NULL, (int)(get_absolute_expression()) - 1); 2228 demand_empty_rest_of_line(); 2229} 2230 2231/* 2232 * s_lsym() implements the pseudo op: 2233 * .lsym name , expression 2234 */ 2235static 2236void 2237s_lsym( 2238uintptr_t value) 2239{ 2240 char *name; 2241 char c; 2242 char *p; 2243 segT segment; 2244 expressionS exp; 2245 symbolS *symbolP; 2246 2247 /* we permit ANY expression: BSD4.2 demands constants */ 2248 if(*input_line_pointer == '"') 2249 name = input_line_pointer + 1; 2250 else 2251 name = input_line_pointer; 2252 c = get_symbol_end(); 2253 p = input_line_pointer; 2254 *p = c; 2255 SKIP_WHITESPACE(); 2256 if(*input_line_pointer != ','){ 2257 *p = 0; 2258 as_bad("Expected comma after name \"%s\"", name); 2259 *p = c; 2260 ignore_rest_of_line(); 2261 return; 2262 } 2263 input_line_pointer++; 2264 segment = expression(&exp); 2265 if(segment != SEG_ABSOLUTE && segment != SEG_SECT){ 2266/* this warning still need fixing */ 2267 as_bad("Bad expression: %s", seg_name[(int)segment]); 2268 ignore_rest_of_line(); 2269 return; 2270 } 2271 know(segment == SEG_ABSOLUTE || segment == SEG_SECT); 2272 *p = 0; 2273 if(segment == SEG_SECT) 2274 symbolP = symbol_new(name, 2275 N_SECT, 2276 frchain_now->frch_nsect, 2277 0, 2278 (valueT)(exp.X_add_number), 2279 &zero_address_frag); 2280 else 2281 symbolP = symbol_new(name, 2282 N_ABS, 2283 0, 2284 0, 2285 (valueT)(exp.X_add_number), 2286 &zero_address_frag); 2287 *p = c; 2288 demand_empty_rest_of_line(); 2289} 2290 2291#if !defined(I860) /* i860 has it's own align and org */ 2292/* 2293 * s_org() implements the pseudo op: 2294 * .org expression 2295 */ 2296static 2297void 2298s_org( 2299uintptr_t value) 2300{ 2301 segT segment; 2302 expressionS exp; 2303 int32_t temp_fill; 2304 char *p; 2305 2306 /* 2307 * Don't believe the documentation of BSD 4.2 AS. 2308 * There is no such thing as a sub-segment-relative origin. 2309 * Any absolute origin is given a warning, then assumed to be 2310 * segment-relative. 2311 * Any segmented origin expression ("foo+42") had better be in the right 2312 * segment or the .org is ignored. 2313 * 2314 * BSD 4.2 AS warns if you try to .org backwards. We cannot because we 2315 * never know sub-segment sizes when we are reading code. 2316 * BSD will crash trying to emit -ve numbers of filler bytes in certain 2317 * .orgs. We don't crash, but see as-write for that code. 2318 */ 2319 segment = get_known_segmented_expression(&exp); 2320 if(*input_line_pointer == ','){ 2321 input_line_pointer ++; 2322 temp_fill = get_absolute_expression (); 2323 } 2324 else 2325 temp_fill = 0; 2326 if((segment != SEG_SECT || 2327 exp.X_add_symbol->sy_other != frchain_now->frch_nsect) && 2328 segment != SEG_ABSOLUTE) 2329 as_bad("Illegal expression. current section assumed."); 2330 p = frag_var(rs_org, 2331 1, 2332 1, 2333 (relax_substateT)0, 2334 exp.X_add_symbol, 2335 exp.X_add_number, 2336 (char *)0); 2337 *p = temp_fill; 2338 demand_empty_rest_of_line(); 2339} 2340#endif /* !defined(I860) i860 has it's own align and org */ 2341 2342/* 2343 * s_set() implements the pseudo op: 2344 * .set name , expression 2345 */ 2346static 2347void 2348s_set( 2349uintptr_t value) 2350{ 2351 char *name; 2352 char delim; 2353 char *end_name; 2354 symbolS *symbolP; 2355 2356 if( * input_line_pointer == '"') 2357 name = input_line_pointer + 1; 2358 else 2359 name = input_line_pointer; 2360 delim = get_symbol_end(); 2361 end_name = input_line_pointer; 2362 *end_name = delim; 2363 SKIP_WHITESPACE(); 2364 if(*input_line_pointer != ','){ 2365 *end_name = 0; 2366 as_bad("Expected comma after name \"%s\"", name); 2367 *end_name = delim; 2368 ignore_rest_of_line(); 2369 return; 2370 } 2371 input_line_pointer++; 2372 *end_name = 0; 2373 if(name[0] == '.' && name[1] == '\0'){ 2374 /* Turn 'set . , mumble' into a .org mumble */ 2375 segT segment; 2376 expressionS exp; 2377 char *ptr; 2378 2379 segment = get_known_segmented_expression(&exp); 2380 if((segment != SEG_SECT || 2381 exp.X_add_symbol->sy_other != frchain_now->frch_nsect) && 2382 segment != SEG_ABSOLUTE) 2383 as_bad("Illegal expression. current section assumed."); 2384 ptr = frag_var(rs_org, 2385 1, 2386 1, 2387 (relax_substateT)0, 2388 exp.X_add_symbol, 2389 exp.X_add_number, 2390 (char *)0); 2391 *ptr = 0; 2392 *end_name = delim; 2393 return; 2394 } 2395 symbolP = symbol_find_or_make(name); 2396 symbolP->sy_desc |= N_NO_DEAD_STRIP; 2397 *end_name = delim; 2398 pseudo_set(symbolP); 2399 demand_empty_rest_of_line(); 2400} 2401 2402/* 2403 * s_abs() implements the pseudo op: 2404 * .abs name , expression 2405 * which sets symbol to 1 or 0 depending on if the expression is an absolute 2406 * expression. This is intended for use in macros. 2407 */ 2408void 2409s_abs( 2410uintptr_t value) 2411{ 2412 char *name; 2413 char c; 2414 char *p; 2415 segT segment; 2416 expressionS exp; 2417 symbolS *symbolP; 2418 2419 if(*input_line_pointer == '"') 2420 name = input_line_pointer + 1; 2421 else 2422 name = input_line_pointer; 2423 c = get_symbol_end(); 2424 p = input_line_pointer; 2425 *p = c; 2426 SKIP_WHITESPACE(); 2427 if(*input_line_pointer != ','){ 2428 *p = 0; 2429 as_bad("Expected comma after name \"%s\"", name); 2430 *p = c; 2431 ignore_rest_of_line(); 2432 return; 2433 } 2434 input_line_pointer++; 2435 *p = 0; 2436 segment = expression(&exp); 2437 symbolP = symbol_find_or_make(name); 2438 symbolP->sy_type = N_ABS; 2439 symbolP->sy_other = 0; /* NO_SECT */ 2440 symbolP->sy_frag = &zero_address_frag; 2441 if(segment == SEG_ABSOLUTE) 2442 symbolP->sy_value = 1; 2443 else 2444 symbolP->sy_value = 0; 2445 *p = c; 2446 totally_ignore_line(); 2447} 2448 2449/* 2450 * s_space() implements the pseudo op: 2451 * .space repeat_expression [ , fill_expression ] 2452 */ 2453void 2454s_space( 2455uintptr_t value) 2456{ 2457 int32_t temp_repeat; 2458 int32_t temp_fill; 2459 char *p; 2460 2461 /* Just like .fill, but temp_size = 1 */ 2462 if(get_absolute_expression_and_terminator(&temp_repeat) == ','){ 2463 temp_fill = get_absolute_expression(); 2464 } 2465 else{ 2466 input_line_pointer--; /* Backup over what was not a ','. */ 2467 temp_fill = 0; 2468 } 2469 if(temp_repeat <= 0){ 2470 as_bad("Repeat < 0, .space ignored"); 2471 ignore_rest_of_line(); 2472 return; 2473 } 2474 p = frag_var(rs_fill, 2475 1, 2476 1, 2477 (relax_substateT)0, 2478 (symbolS *)0, 2479 temp_repeat, 2480 (char *)0); 2481 *p = temp_fill; 2482 demand_empty_rest_of_line(); 2483} 2484 2485static 2486uint32_t 2487s_builtin_section( 2488const struct builtin_section *s) 2489{ 2490 frchainS *frcP; 2491 2492 if(!flagseen['k']){ 2493 if((s->flags & SECTION_TYPE) == S_NON_LAZY_SYMBOL_POINTERS || 2494 (s->flags & SECTION_TYPE) == S_LAZY_SYMBOL_POINTERS || 2495 (s->flags & SECTION_TYPE) == S_SYMBOL_STUBS || 2496#if !(defined(I386) && defined(ARCH64)) 2497 (s->flags & SECTION_TYPE) == S_MOD_INIT_FUNC_POINTERS || 2498 (s->flags & SECTION_TYPE) == S_MOD_TERM_FUNC_POINTERS || 2499#endif 2500 (s->flags & SECTION_ATTRIBUTES & ~S_ATTR_PURE_INSTRUCTIONS) != 0) 2501 as_fatal("incompatible feature used: directive .%s (must " 2502 "specify \"-dynamic\" to be used)", s->directive); 2503 } 2504 frcP = section_new(s->segname, s->sectname, 2505 s->flags & SECTION_TYPE, 2506 s->flags & SECTION_ATTRIBUTES, 2507 s->sizeof_stub); 2508 if(frcP->frch_section.align < s->default_align) 2509 frcP->frch_section.align = s->default_align; 2510 return(frcP->frch_nsect); 2511} 2512 2513/* 2514 * s_section() implements the pseudo op: 2515 * .section segname , sectname [[[ , type ] , attribute] , sizeof_stub] 2516 */ 2517static 2518void 2519s_section( 2520uintptr_t value) 2521{ 2522 char *segname, *sectname, *typename; 2523 char c, d, e, *p, *q, *r; 2524 struct type_name *type_name; 2525 uint32_t type, attribute; 2526 section_t s; 2527 frchainS *frcP; 2528 uint32_t sizeof_stub; 2529 2530 struct attribute_name *attribute_name; 2531 char *attributename, *sizeof_stub_name, f, g, *t, *u, *endp; 2532 2533 segname = input_line_pointer; 2534 do{ 2535 c = *input_line_pointer++ ; 2536 }while(c != ',' && c != '\0' && c != '\n'); 2537 if(c != ','){ 2538 as_bad("Expected comma after segment-name"); 2539 ignore_rest_of_line(); 2540 return; 2541 } 2542 p = input_line_pointer - 1; 2543 2544 SKIP_WHITESPACE(); 2545 sectname = input_line_pointer; 2546 do{ 2547 d = *input_line_pointer++ ; 2548 }while(d != ',' && d != '\0' && d != '\n'); 2549 if(p + 1 == input_line_pointer){ 2550 as_bad("Expected section-name after comma"); 2551 ignore_rest_of_line(); 2552 return; 2553 } 2554 q = input_line_pointer - 1; 2555 2556 *p = 0; 2557 if(strlen(segname) > sizeof(s.segname)){ 2558 as_bad("segment-name: %s too long (maximum %ld characters)", 2559 segname, sizeof(s.segname)); 2560 ignore_rest_of_line(); 2561 *p = c; 2562 return; 2563 } 2564 2565 *q = 0; 2566 if(strlen(sectname) > sizeof(s.sectname)){ 2567 as_bad("section-name: %s too long (maximum %ld characters)", 2568 sectname, sizeof(s.sectname)); 2569 ignore_rest_of_line(); 2570 return; 2571 } 2572 /* 2573 * Now see if the optional section type is present. 2574 */ 2575 type = 0; 2576 type_name = type_names; 2577 attribute = 0; 2578 attribute_name = attribute_names; 2579 sizeof_stub = 0; 2580 if(d == ','){ 2581 typename = input_line_pointer; 2582 do{ 2583 e = *input_line_pointer++ ; 2584 } 2585 while(e != ',' && !(is_end_of_line(e))); 2586 r = input_line_pointer - 1; 2587 *r = 0; 2588 for(type_name = type_names; type_name->name != NULL; type_name++) 2589 if(strcmp(type_name->name, typename) == 0) 2590 break; 2591 if(type_name->name == NULL){ 2592 as_bad("unknown section type: %s", typename); 2593 ignore_rest_of_line(); 2594 return; 2595 } 2596 *r = e; 2597 type = type_name->type; 2598 /* 2599 * Now see if the optional section attribute is present. 2600 */ 2601 if(e == ','){ 2602 do{ 2603 attributename = input_line_pointer; 2604 do{ 2605 f = *input_line_pointer++ ; 2606 }while(f != ',' && f != '+' && !(is_end_of_line(f))); 2607 t = input_line_pointer - 1; 2608 *t = 0; 2609 for(attribute_name = attribute_names; 2610 attribute_name->name != NULL; 2611 attribute_name++) 2612 if(strcmp(attribute_name->name, attributename) == 0) 2613 break; 2614 if(attribute_name->name == NULL){ 2615 as_bad("unknown section attribute: %s", attributename); 2616 ignore_rest_of_line(); 2617 return; 2618 } 2619 *t = f; 2620 attribute |= attribute_name->attribute; 2621 }while(f == '+'); 2622 2623 /* 2624 * Now get the section stub size if this is a stub section. 2625 */ 2626 if(type == S_SYMBOL_STUBS){ 2627 if(f == ','){ 2628 sizeof_stub_name = input_line_pointer; 2629 do{ 2630 g = *input_line_pointer++ ; 2631 }while(!(is_end_of_line(g))); 2632 u = input_line_pointer - 1; 2633 *u = 0; 2634 sizeof_stub = strtoul(sizeof_stub_name, &endp, 0); 2635 if(*endp != '\0'){ 2636 as_bad("size of stub section: %s not a proper " 2637 "number", sizeof_stub_name); 2638 ignore_rest_of_line(); 2639 return; 2640 } 2641 *u = g; 2642 } 2643 else{ 2644 as_bad("missing size of stub section (%s,%s)", segname, 2645 sectname); 2646 ignore_rest_of_line(); 2647 return; 2648 } 2649 } 2650 } 2651 else if(type == S_SYMBOL_STUBS){ 2652 as_bad("missing size of stub section (%s,%s)", segname, 2653 sectname); 2654 ignore_rest_of_line(); 2655 return; 2656 } 2657 } 2658 input_line_pointer--; 2659 2660 if(!flagseen['k']){ 2661 if(type == S_NON_LAZY_SYMBOL_POINTERS || 2662 type == S_LAZY_SYMBOL_POINTERS || 2663 type == S_SYMBOL_STUBS || 2664 type == S_MOD_INIT_FUNC_POINTERS || 2665 type == S_MOD_TERM_FUNC_POINTERS) 2666 as_fatal("incompatible feature used: section type %s (must " 2667 "specify \"-dynamic\" to be " 2668 "used)", type_name->name); 2669 } 2670 2671 frcP = section_new(segname, sectname, type, attribute, sizeof_stub); 2672 *p = c; 2673 *q = d; 2674 demand_empty_rest_of_line(); 2675} 2676 2677/* 2678 * s_zerofill() implements the pseudo op: 2679 * .zerofill segname , sectname [, symbolname , size_expression [ , align]] 2680 */ 2681static 2682void 2683s_zerofill( 2684uintptr_t value) 2685{ 2686 char *directive, *segname, *sectname, c, d, *p, *q, *name; 2687 section_t s; 2688 frchainS *frcP; 2689 symbolS *symbolP; 2690 uint64_t size; 2691 int align; 2692 2693 if(value == S_THREAD_LOCAL_ZEROFILL){ 2694 directive = "tbss"; 2695 frcP = section_new("__DATA", "__thread_bss", value, 0, 0); 2696 if(frcP->frch_root == NULL){ 2697 frcP->frch_root = xmalloc(SIZEOF_STRUCT_FRAG); 2698 frcP->frch_last = frcP->frch_root; 2699 memset(frcP->frch_root, '\0', SIZEOF_STRUCT_FRAG); 2700 } 2701 } 2702 else{ 2703 directive = "zerofill"; 2704 segname = input_line_pointer; 2705 do{ 2706 c = *input_line_pointer++ ; 2707 }while(c != ' ' && c != ',' && c != '\0' && c != '\n'); 2708 p = input_line_pointer - 1; 2709 while(c == ' '){ 2710 c = *input_line_pointer++ ; 2711 } 2712 if(c != ','){ 2713 as_bad("Expected comma after segment-name"); 2714 ignore_rest_of_line(); 2715 return; 2716 } 2717 2718 SKIP_WHITESPACE(); 2719 sectname = input_line_pointer; 2720 do{ 2721 d = *input_line_pointer++ ; 2722 }while(d != ',' && d != '\0' && d != '\n'); 2723 if(p + 1 == input_line_pointer){ 2724 as_bad("Expected section-name after comma"); 2725 ignore_rest_of_line(); 2726 return; 2727 } 2728 q = input_line_pointer - 1; 2729 2730 *p = 0; 2731 if(strlen(segname) > sizeof(s.segname)){ 2732 as_bad("segment-name: %s too long (maximum %ld characters)", 2733 segname, sizeof(s.segname)); 2734 ignore_rest_of_line(); 2735 *p = c; 2736 return; 2737 } 2738 2739 *q = 0; 2740 if(strlen(sectname) > sizeof(s.sectname)){ 2741 as_bad("section-name: %s too long (maximum %ld characters)", 2742 sectname, sizeof(s.sectname)); 2743 ignore_rest_of_line(); 2744 *p = c; 2745 *q = d; 2746 return; 2747 } 2748 2749 frcP = section_new(segname, sectname, value, 0, 0); 2750 if(frcP->frch_root == NULL){ 2751 frcP->frch_root = xmalloc(SIZEOF_STRUCT_FRAG); 2752 frcP->frch_last = frcP->frch_root; 2753 memset(frcP->frch_root, '\0', SIZEOF_STRUCT_FRAG); 2754 } 2755 *p = c; 2756 *q = d; 2757 /* 2758 * If this is the end of the line all that was wanted was to create 2759 * the the section which is now done, so return. 2760 */ 2761 if(d != ',') 2762 return; 2763 } 2764 2765 if(*input_line_pointer == '"') 2766 name = input_line_pointer + 1; 2767 else 2768 name = input_line_pointer; 2769 c = get_symbol_end(); 2770 p = input_line_pointer; 2771 *p = c; 2772 SKIP_WHITESPACE(); 2773 if(*input_line_pointer != ','){ 2774 as_bad("Expected comma after symbol-name"); 2775 ignore_rest_of_line(); 2776 return; 2777 } 2778 input_line_pointer ++; 2779 if((int)(size = get_absolute_expression()) < 0){ 2780 as_bad("%s size (%lld.) <0! Ignored.", directive, size); 2781 ignore_rest_of_line(); 2782 return; 2783 } 2784 align = 0; 2785 if(*input_line_pointer == ','){ 2786 input_line_pointer++; 2787 align = get_absolute_expression(); 2788 if(align > MAX_ALIGNMENT){ 2789 as_warn("Alignment too large: %d. assumed.", MAX_ALIGNMENT); 2790 align = MAX_ALIGNMENT; 2791 } 2792 else if(align < 0){ 2793 as_warn("Alignment negative. 0 assumed."); 2794 align = 0; 2795 } 2796 /* 2797 * If this alignment is larger than any previous alignment then this 2798 * becomes the section's alignment. 2799 */ 2800 if(frcP->frch_section.align < (uint32_t)align) 2801 frcP->frch_section.align = align; 2802 } 2803 *p = 0; 2804 symbolP = symbol_find_or_make(name); 2805 *p = c; 2806 2807 if((symbolP->sy_type & N_TYPE) == N_UNDF && symbolP->sy_value == 0){ 2808 frcP->frch_root->fr_address = rnd(frcP->frch_root->fr_address, 2809 1 << align); 2810 symbolP->sy_value = frcP->frch_root->fr_address; 2811 symbolP->sy_type = N_SECT | (symbolP->sy_type & (N_EXT | N_PEXT)); 2812 symbolP->sy_other = frcP->frch_nsect; 2813 symbolP->sy_frag = frcP->frch_root; 2814 frcP->frch_root->fr_address += size; 2815 } 2816 else 2817 as_bad("Ignoring attempt to re-define symbol."); 2818 2819 demand_empty_rest_of_line(); 2820} 2821 2822/* 2823 * s_reference() implements the pseudo op: 2824 * .reference name 2825 */ 2826static 2827void 2828s_reference( 2829uintptr_t value) 2830{ 2831 char *name; 2832 char c; 2833 char *p; 2834 symbolS *symbolP; 2835 2836 if(* input_line_pointer == '"') 2837 name = input_line_pointer + 1; 2838 else 2839 name = input_line_pointer; 2840 c = get_symbol_end(); 2841 p = input_line_pointer; 2842 2843 *p = 0; 2844 symbolP = symbol_find_or_make(name); 2845 symbolP->sy_desc |= N_NO_DEAD_STRIP; 2846 *p = c; 2847 demand_empty_rest_of_line(); 2848} 2849 2850/* 2851 * s_lazy_reference() implements the pseudo op: 2852 * .lazy_reference name 2853 */ 2854static 2855void 2856s_lazy_reference( 2857uintptr_t value) 2858{ 2859 char *name; 2860 char c; 2861 char *p; 2862 symbolS *symbolP; 2863 2864 if(!flagseen['k']) 2865 as_fatal("incompatible feature used: .lazy_reference (must specify " 2866 "\"-dynamic\" to be used)"); 2867 2868 if(* input_line_pointer == '"') 2869 name = input_line_pointer + 1; 2870 else 2871 name = input_line_pointer; 2872 c = get_symbol_end(); 2873 p = input_line_pointer; 2874 2875 *p = 0; 2876 symbolP = symbol_find_or_make(name); 2877 if((symbolP->sy_type & N_TYPE) == N_UNDF && symbolP->sy_value == 0) 2878 symbolP->sy_desc |= REFERENCE_FLAG_UNDEFINED_LAZY; 2879 symbolP->sy_desc |= N_NO_DEAD_STRIP; 2880 *p = c; 2881 demand_empty_rest_of_line(); 2882} 2883 2884/* 2885 * s_weak_reference() implements the pseudo op: 2886 * .weak_reference name 2887 */ 2888static 2889void 2890s_weak_reference( 2891uintptr_t value) 2892{ 2893 char *name; 2894 char c; 2895 char *p; 2896 symbolS *symbolP; 2897 2898 if(!flagseen['k']) 2899 as_fatal("incompatible feature used: .weak_reference (must specify " 2900 "\"-dynamic\" to be used)"); 2901 2902 if(* input_line_pointer == '"') 2903 name = input_line_pointer + 1; 2904 else 2905 name = input_line_pointer; 2906 c = get_symbol_end(); 2907 p = input_line_pointer; 2908 2909 *p = 0; 2910 symbolP = symbol_find_or_make(name); 2911 if((symbolP->sy_type & N_TYPE) == N_UNDF && symbolP->sy_value == 0) 2912 symbolP->sy_desc |= N_WEAK_REF; 2913 *p = c; 2914 demand_empty_rest_of_line(); 2915} 2916 2917/* 2918 * s_weak_definition() implements the pseudo op: 2919 * .weak_definition name 2920 */ 2921static 2922void 2923s_weak_definition( 2924uintptr_t value) 2925{ 2926 char *name; 2927 char c; 2928 char *p; 2929 symbolS *symbolP; 2930 2931 if(* input_line_pointer == '"') 2932 name = input_line_pointer + 1; 2933 else 2934 name = input_line_pointer; 2935 c = get_symbol_end(); 2936 p = input_line_pointer; 2937 2938 *p = 0; 2939 symbolP = symbol_find_or_make(name); 2940 symbolP->sy_desc |= N_WEAK_DEF; 2941 *p = c; 2942 demand_empty_rest_of_line(); 2943} 2944 2945/* 2946 * s_weak_def_can_be_hidden() implements the pseudo op: 2947 * .weak_def_can_be_hidden name 2948 */ 2949static 2950void 2951s_weak_def_can_be_hidden( 2952uintptr_t value) 2953{ 2954 char *name; 2955 char c; 2956 char *p; 2957 symbolS *symbolP; 2958 2959 if(* input_line_pointer == '"') 2960 name = input_line_pointer + 1; 2961 else 2962 name = input_line_pointer; 2963 c = get_symbol_end(); 2964 p = input_line_pointer; 2965 2966 *p = 0; 2967 symbolP = symbol_find_or_make(name); 2968 symbolP->sy_desc |= (N_WEAK_DEF | N_WEAK_REF); 2969 *p = c; 2970 demand_empty_rest_of_line(); 2971} 2972 2973/* 2974 * s_no_dead_strip() implements the pseudo op: 2975 * .no_dead_strip name 2976 */ 2977static 2978void 2979s_no_dead_strip( 2980uintptr_t value) 2981{ 2982 char *name; 2983 char c; 2984 char *p; 2985 symbolS *symbolP; 2986 2987 if(* input_line_pointer == '"') 2988 name = input_line_pointer + 1; 2989 else 2990 name = input_line_pointer; 2991 c = get_symbol_end(); 2992 p = input_line_pointer; 2993 2994 *p = 0; 2995 symbolP = symbol_find_or_make(name); 2996 symbolP->sy_desc |= N_NO_DEAD_STRIP; 2997 *p = c; 2998 demand_empty_rest_of_line(); 2999} 3000 3001/* 3002 * s_symbol_resolver() implements the pseudo op: 3003 * .symbol_resolver name 3004 */ 3005static 3006void 3007s_symbol_resolver( 3008uintptr_t value) 3009{ 3010 char *name; 3011 char c; 3012 char *p; 3013 symbolS *symbolP; 3014 3015 if(* input_line_pointer == '"') 3016 name = input_line_pointer + 1; 3017 else 3018 name = input_line_pointer; 3019 c = get_symbol_end(); 3020 p = input_line_pointer; 3021 3022 *p = 0; 3023 symbolP = symbol_find_or_make(name); 3024 symbolP->sy_desc |= N_SYMBOL_RESOLVER; 3025 *p = c; 3026 demand_empty_rest_of_line(); 3027} 3028 3029/* 3030 * s_include() implements the pseudo op: 3031 * .include "filename" 3032 */ 3033static 3034void 3035s_include( 3036uintptr_t value) 3037{ 3038 char *filename; 3039 int length; 3040 symbolS *symbolP; 3041 3042 /* Some assemblers tolerate immediately following '"' */ 3043 if((filename = demand_copy_string( & length ) )) { 3044 demand_empty_rest_of_line(); 3045 read_an_include_file(filename); 3046 } 3047 3048 /* 3049 * This is to generate stabs for debugging assembly code. 3050 * See the second comment about stabs in read_a_source_file() 3051 * for a description of what is going on here 3052 */ 3053 if(flagseen['g'] && frchain_now->frch_nsect == text_nsect){ 3054 symbolP = symbol_new( 3055 physical_input_file, 3056 132 /* N_SOL */, 3057 text_nsect, 3058 0, 3059 obstack_next_free(&frags) - frag_now->fr_literal, 3060 frag_now); 3061 } 3062} 3063 3064/* 3065 * demand_empty_rest_of_line() checks to make sure we are at the end of a line 3066 * and if not ignores the rest of the line. 3067 * This is global so machine dependent pseudo-ops can use this. 3068 */ 3069void 3070demand_empty_rest_of_line( 3071void) 3072{ 3073 SKIP_WHITESPACE(); 3074 if(is_end_of_line(*input_line_pointer)) 3075 input_line_pointer++; 3076 else 3077 ignore_rest_of_line(); 3078} 3079 3080/* we simply ignore the rest of this statement */ 3081void 3082s_ignore( 3083uintptr_t arg ATTRIBUTE_UNUSED) 3084{ 3085 totally_ignore_line (); 3086} 3087 3088/* 3089 * ignore_rest_of_line() advances input_line_pointer to the next line and if 3090 * there is anything left on the current line print a warning. 3091 * This is global so machine dependent pseudo-ops can use this. 3092 */ 3093void 3094ignore_rest_of_line( 3095void) 3096{ 3097 if(!is_end_of_line(*input_line_pointer)){ 3098 as_bad("Rest of line ignored. 1st junk character valued %d (%c).", 3099 *input_line_pointer, *input_line_pointer); 3100 while(input_line_pointer < buffer_limit && 3101 !is_end_of_line(*input_line_pointer)) 3102 input_line_pointer++; 3103 } 3104 input_line_pointer++; /* Return pointing just after end-of-line. */ 3105 know(is_end_of_line(input_line_pointer[-1])); 3106} 3107 3108/* 3109 * stab() 3110 * 3111 * Handle .stabX directives, which used to be open-coded. 3112 * So much creeping featurism overloaded the semantics that we decided 3113 * to put all .stabX thinking in one place. Here. 3114 * 3115 * We try to make any .stabX directive legal. Other people's AS will often 3116 * do assembly-time consistency checks: eg assigning meaning to n_type bits 3117 * and "protecting" you from setting them to certain values. (They also zero 3118 * certain bits before emitting symbols. Tut tut.) 3119 * 3120 * If an expression is not absolute we either gripe or use the relocation 3121 * information. Other people's assemblers silently forget information they 3122 * don't need and invent information they need that you didn't supply. 3123 * 3124 * .stabX directives always make a symbol table entry. It may be junk if 3125 * the rest of your .stabX directive is malformed. 3126 */ 3127static 3128void 3129stab( 3130uintptr_t what) /* d == .stabd, n == .stabn, and s == .stabs */ 3131{ 3132 symbolS *symbolP; 3133 char *string; 3134 int saved_type; 3135 int length; 3136 int goof; /* TRUE if we have aborted. */ 3137 int32_t longint; 3138 3139 saved_type = 0; 3140 symbolP = NULL; 3141 /* 3142 * Enter with input_line_pointer pointing past .stabX and any following 3143 * whitespace. 3144 */ 3145 goof = FALSE; 3146 if(what == 's'){ 3147 string = demand_copy_C_string(&length); 3148 SKIP_WHITESPACE(); 3149 if(*input_line_pointer == ',') 3150 input_line_pointer ++; 3151 else{ 3152 as_bad("I need a comma after symbol's name"); 3153 goof = TRUE; 3154 } 3155 } 3156 else 3157 string = ""; 3158 3159 /* 3160 * Input_line_pointer->after ','. String -> symbol name. 3161 */ 3162 if(!goof){ 3163 symbolP = symbol_new(string, 0,0,0,0,(struct frag *)0); 3164 switch(what){ 3165 case 'd': 3166 symbolP->sy_name = NULL; /* .stabd feature. */ 3167 symbolP->sy_value = obstack_next_free(&frags) - 3168 frag_now->fr_literal; 3169 symbolP->sy_frag = frag_now; 3170 break; 3171 3172 case 'n': 3173 case 's': 3174 symbolP->sy_frag = &zero_address_frag; 3175 break; 3176 3177 default: 3178 BAD_CASE( (int)what ); 3179 break; 3180 } 3181 if(get_absolute_expression_and_terminator(&longint) == ','){ 3182 saved_type = longint; 3183 symbolP->sy_type = longint; 3184 } 3185 else{ 3186 as_bad("I want a comma after the n_type expression"); 3187 goof = TRUE; 3188 input_line_pointer--; /* Backup over a non-',' char. */ 3189 } 3190 } 3191 3192 if(!goof){ 3193 if(get_absolute_expression_and_terminator(&longint) == ',') 3194 symbolP->sy_other = longint; 3195 else { 3196 as_bad("I want a comma after the n_other expression"); 3197 goof = TRUE; 3198 input_line_pointer--; /* Backup over a non-',' char. */ 3199 } 3200 } 3201 3202 if(!goof){ 3203 symbolP->sy_desc = get_absolute_expression(); 3204 if(what == 's' || what == 'n'){ 3205 if(*input_line_pointer != ','){ 3206 as_bad( "I want a comma after the n_desc expression" ); 3207 goof = TRUE; 3208 } 3209 else 3210 input_line_pointer ++; 3211 } 3212 } 3213 3214 if((!goof) && (what=='s' || what=='n')){ 3215 pseudo_set(symbolP); 3216 symbolP->sy_type = saved_type; 3217 } 3218 else if(!goof){ 3219 /* for stabd the sy_other (n_sect) gets set to the current section*/ 3220 symbolP->sy_other = frchain_now->frch_nsect; 3221 } 3222 if(goof) 3223 ignore_rest_of_line(); 3224 else 3225 demand_empty_rest_of_line(); 3226} 3227 3228/* 3229 * pseudo_set() 3230 * 3231 * In: Pointer to a symbol. 3232 * Input_line_pointer -> expression. 3233 * 3234 * Out: Input_line_pointer -> just after any whitespace after expression. 3235 * Tried to set symbol to value of expression. 3236 * Will change sy_type, sy_value, sy_frag; 3237 *(old ->> May set need_pass_2 == TRUE. <<-- commented out by GNU below it 3238 * uses symbolP->sy_forward = exp.X_add_symbol;) 3239 */ 3240void 3241pseudo_set( 3242symbolS *symbolP) 3243{ 3244 expressionS exp; 3245 segT segment; 3246 int ext; 3247 3248 know(symbolP); /* NULL pointer is logic error. */ 3249 ext = (symbolP->sy_type & (N_EXT | N_PEXT)); 3250 segment = expression(&exp); 3251 3252 switch(segment){ 3253 case SEG_BIG: 3254 as_bad("%s number illegal. Absolute 0 assumed.", 3255 exp.X_add_number > 0 ? "Bignum" : "Floating-Point"); 3256 symbolP->sy_type = N_ABS | ext; 3257 symbolP->sy_other = 0; /* NO_SECT */ 3258 symbolP->sy_value = 0; 3259 symbolP->sy_frag = &zero_address_frag; 3260 break; 3261 3262 case SEG_NONE: 3263 as_bad("No expression: Using absolute 0"); 3264 symbolP->sy_type = N_ABS | ext; 3265 symbolP->sy_other = 0; /* NO_SECT */ 3266 symbolP->sy_value = 0; 3267 symbolP->sy_frag = &zero_address_frag; 3268 break; 3269 3270 case SEG_DIFFSECT: 3271 if(exp.X_add_symbol && exp.X_subtract_symbol){ 3272 if(exp.X_add_symbol->sy_frag != 3273 exp.X_subtract_symbol->sy_frag || 3274 exp.X_add_symbol->sy_type == N_UNDF || 3275 exp.X_subtract_symbol->sy_type == N_UNDF ){ 3276 expressionS *expression; 3277 3278 expression = xmalloc(sizeof(expressionS)); 3279 *expression = exp; 3280 symbolP->expression = expression; 3281 } 3282 else{ 3283 exp.X_add_number += exp.X_add_symbol->sy_value - 3284 exp.X_subtract_symbol->sy_value; 3285 } 3286 } 3287 else if(exp.X_add_symbol && 3288 exp.X_subtract_symbol == NULL && 3289 exp.X_add_symbol->expression != NULL){ 3290 expressionS *expression; 3291 3292 expression = xmalloc(sizeof(expressionS)); 3293 memcpy(expression, exp.X_add_symbol->expression, 3294 sizeof(expressionS)); 3295 symbolP->expression = expression; 3296 } 3297 else 3298 as_bad("Complex expression. Absolute segment assumed." ); 3299 symbolP->sy_type = N_ABS | ext; 3300 symbolP->sy_other = 0; /* NO_SECT */ 3301 symbolP->sy_value = exp.X_add_number; 3302 symbolP->sy_frag = &zero_address_frag; 3303 break; 3304 3305 case SEG_ABSOLUTE: 3306 symbolP->sy_type = N_ABS | ext; 3307 symbolP->sy_other = 0; /* NO_SECT */ 3308 symbolP->sy_value = exp.X_add_number; 3309 symbolP->sy_frag = &zero_address_frag; 3310 symbolP->expression = NULL; 3311 break; 3312 3313 case SEG_SECT: 3314 symbolP->sy_type = N_SECT | ext; 3315 symbolP->sy_other = exp.X_add_symbol->sy_other; 3316 symbolP->sy_value = exp.X_add_number + exp.X_add_symbol->sy_value; 3317 symbolP->sy_frag = exp.X_add_symbol->sy_frag; 3318 break; 3319 3320 case SEG_UNKNOWN: 3321 symbolP->sy_forward = exp.X_add_symbol; 3322/* commented out by GNU */ 3323/* as_bad("unknown symbol"); */ 3324/* need_pass_2 = TRUE; */ 3325 break; 3326 3327 default: 3328 BAD_CASE(segment); 3329 break; 3330 } 3331} 3332 3333/* 3334 * cons() 3335 * 3336 * CONStruct more frag of .bytes, or .words etc. 3337 * This understands EXPRESSIONS, as opposed to big_cons(). 3338 * 3339 * Bug (?) 3340 * 3341 * This has a split personality. We use expression() to read the 3342 * value. We can detect if the value won't fit in a byte or word. 3343 * But we can't detect if expression() discarded significant digits 3344 * in the case of a long. Not worth the crocks required to fix it. 3345 * 3346 * Worker function to do .byte, .short, .long, .quad statements. 3347 * This clobbers input_line_pointer, checks end-of-line. 3348 */ 3349void 3350cons( 3351uintptr_t nbytes) /* nbytes == 1 for .byte, 2 for .word, 4 for .long, 8 for .quad */ 3352{ 3353 char c; 3354 signed_expr_t 3355 mask, /* high-order bits to truncate */ 3356 unmask, /* what bits we will store */ 3357 get, /* the bits of the expression we get */ 3358 use; /* the bits of the expression after truncation */ 3359 char *p; /* points into the frag */ 3360 segT segment; 3361 expressionS exp; 3362#ifndef TC_CONS_FIX_NEW 3363 fixS *fixP; 3364#endif 3365 3366 memset(&exp, '\0', sizeof(exp)); 3367 /* 3368 * Input_line_pointer -> 1st char after pseudo-op-code and could legally 3369 * be a end-of-line. (Or, less legally an eof - which we cope with.) 3370 */ 3371 if(nbytes >= (int)sizeof(signed_expr_t)) 3372 mask = 0; 3373 else 3374 /* Don't store these bits. */ 3375 mask = ~0ULL << (BITS_PER_CHAR * nbytes); 3376 unmask = ~mask; /* Do store these bits. */ 3377 3378 /* 3379 * The following awkward logic is to parse ZERO or more expressions, 3380 * comma seperated. Recall an expression includes its leading & 3381 * trailing blanks. We fake a leading ',' if there is (supposed to 3382 * be) a 1st expression, and keep demanding 1 expression for each ','. 3383 */ 3384 if(is_it_end_of_statement()){ 3385 c = 0; /* Skip loop. */ 3386 input_line_pointer++; /* Matches end-of-loop 'correction'. */ 3387 } 3388 else 3389 c = ','; /* Do loop. */ 3390 3391 while(c == ','){ 3392#ifdef TC_PARSE_CONS_EXPRESSION 3393 segment = TC_PARSE_CONS_EXPRESSION(&exp, nbytes); 3394#else 3395 segment = expression(&exp); /* At least scan over the expression */ 3396#endif 3397 3398 if(segment == SEG_DIFFSECT && exp.X_add_symbol == NULL){ 3399 as_bad("Subtracting symbol \"%s\"(segment\"%s\") is too " 3400 "hard. Absolute segment assumed.", 3401 exp.X_subtract_symbol->sy_name, 3402 seg_name[(int)N_TYPE_seg[ 3403 exp.X_subtract_symbol->sy_type & N_TYPE]]); 3404 segment = SEG_ABSOLUTE; 3405 /* Leave exp .X_add_number alone. */ 3406 } 3407 p = frag_more(nbytes); 3408 switch(segment){ 3409 case SEG_BIG: 3410 /* 3411 * Handle bignums small enough to fit in a long long and 3412 * thus be passed directly to md_number_to_chars. 3413 */ 3414 if(exp.X_add_number > 0 && 3415 (((LITTLENUM_NUMBER_OF_BITS * exp.X_add_number) / 8) <= 3416 sizeof(int64_t))){ 3417 int i; 3418 int64_t sum; 3419 3420 sum = 0; 3421 for(i = 0; i < exp.X_add_number; ++i) 3422 sum = (sum << LITTLENUM_NUMBER_OF_BITS) + 3423 generic_bignum[(exp.X_add_number - 1) - i]; 3424 md_number_to_chars(p, sum, nbytes); 3425 } 3426 else 3427 { 3428 as_bad("%s number illegal. Absolute 0 assumed.", 3429 exp.X_add_number > 0 ? "Bignum" : "Floating-Point"); 3430 md_number_to_chars(p, (int32_t)0, nbytes); 3431 } 3432 break; 3433 3434 case SEG_NONE: 3435 as_bad("0 assumed for missing expression"); 3436 exp.X_add_number = 0; 3437 know(exp.X_add_symbol == NULL); 3438 /* fall into SEG_ABSOLUTE */ 3439 3440 case SEG_ABSOLUTE: 3441 get = exp.X_add_number; 3442 use = get & unmask; 3443 if((get & mask) && (get & mask) != mask){ 3444 /* Leading bits contain both 0s & 1s. */ 3445 as_bad("Value 0x%llx truncated to 0x%llx.", get, use); 3446 } 3447 dwarf2_emit_insn(nbytes); 3448 /* put bytes in right order. */ 3449 md_number_to_chars(p, use, nbytes); 3450 break; 3451 3452 case SEG_DIFFSECT: 3453 case SEG_UNKNOWN: 3454 case SEG_SECT: 3455#ifdef TC_CONS_FIX_NEW 3456 TC_CONS_FIX_NEW(frag_now, 3457 p - frag_now->fr_literal, 3458 nbytes, 3459 &exp); 3460#else 3461 fixP = fix_new(frag_now, 3462 p - frag_now->fr_literal, 3463 nbytes, 3464 exp.X_add_symbol, 3465 exp.X_subtract_symbol, 3466 exp.X_add_number, 3467 0, 3468 0, 3469 0); 3470 /* 3471 * If we have the special assembly time constant expression 3472 * of the difference of two symbols defined in the same section 3473 * then divided by exactly 2 mark the fix to indicate this. 3474 */ 3475 fixP->fx_sectdiff_divide_by_two = exp.X_sectdiff_divide_by_two; 3476#endif 3477 break; 3478 3479 default: 3480 BAD_CASE(segment); 3481 break; 3482 } /* switch(segment) */ 3483 c = *input_line_pointer++; 3484 } /* while(c==',') */ 3485 input_line_pointer--; /* Put terminator back into stream. */ 3486 demand_empty_rest_of_line(); 3487} 3488 3489#ifdef M68K /* we allow big cons only on the 68k machines */ 3490/* 3491 * big_cons() 3492 * 3493 * CONStruct more frag(s) of .quads, or .octa etc. 3494 * Makes 0 or more new frags. 3495 * This understands only bignums, not expressions. Cons() understands 3496 * expressions. 3497 * 3498 * Constants recognised are '0...'(octal) '0x...'(hex) '...'(decimal). 3499 * 3500 * This creates objects with struct obstack_control objs, destroying 3501 * any context objs held about a partially completed object. Beware! 3502 * 3503 * 3504 * I think it sucks to have 2 different types of integers, with 2 3505 * routines to read them, store them etc. 3506 * It would be nicer to permit bignums in expressions and only 3507 * complain if the result overflowed. However, due to "efficiency"... 3508 * 3509 * Worker function to do .quad and .octa statements. 3510 * This clobbers input_line_pointer, checks end-of-line. 3511 */ 3512void 3513big_cons( 3514uintptr_t nbytes) /* 8 == .quad, 16 == .octa ... */ 3515{ 3516 char c; /* input_line_pointer -> c. */ 3517 int radix; 3518 int32_t length;/* Number of chars in an object. */ 3519 int digit; /* Value of 1 digit. */ 3520 int carry; /* For multi-precision arithmetic. */ 3521 int work; /* For multi-precision arithmetic. */ 3522 char *p,*q; /* For multi-precision arithmetic. */ 3523 int i; 3524 3525 /* 3526 * The following awkward logic is to parse ZERO or more strings, 3527 * comma seperated. Recall an expression includes its leading & 3528 * trailing blanks. We fake a leading ',' if there is (supposed to 3529 * be) a 1st expression, and keep demanding 1 expression for each ','. 3530 */ 3531 if(is_it_end_of_statement()){ 3532 c = 0; /* Skip loop. */ 3533 } 3534 else{ 3535 c = ','; /* Do loop. */ 3536 --input_line_pointer; 3537 } 3538 while(c == ','){ 3539 ++input_line_pointer; 3540 SKIP_WHITESPACE(); 3541 c = *input_line_pointer; 3542 /* c contains 1st non-blank char of what we hope is a number */ 3543 if(c == '0'){ 3544 c = *++input_line_pointer; 3545 if(c == 'x' || c=='X'){ 3546 c = *++input_line_pointer; 3547 radix = 16; 3548 } 3549 else{ 3550 radix = 8; 3551 } 3552 } 3553 else{ 3554 radix = 10; 3555 } 3556 /* 3557 * This feature (?) is here to stop people worrying about 3558 * mysterious zero constants: which is what they get when 3559 * they completely omit digits. 3560 */ 3561 if(hex_value[(int)c] >= radix){ 3562 as_bad("Missing digits. 0 assumed."); 3563 } 3564 bignum_high = bignum_low - 1; /* Start constant with 0 chars. */ 3565 for( ; 3566 (digit = hex_value[(int)c]) < radix; 3567 c = *++input_line_pointer){ 3568 /* Multiply existing number by radix, then add digit. */ 3569 carry = digit; 3570 for(p = bignum_low; p <= bignum_high; p++){ 3571 work = (*p & MASK_CHAR) * radix + carry; 3572 *p = work & MASK_CHAR; 3573 carry = work >> BITS_PER_CHAR; 3574 } 3575 if(carry){ 3576 grow_bignum(); 3577 *bignum_high = carry & MASK_CHAR; 3578 know((carry & ~ MASK_CHAR) == 0); 3579 } 3580 } 3581 length = bignum_high - bignum_low + 1; 3582 if(length > nbytes){ 3583 as_bad("Most significant bits truncated in integer constant."); 3584 } 3585 else{ 3586 int32_t leading_zeroes; 3587 3588 for(leading_zeroes = nbytes - length; 3589 leading_zeroes; 3590 leading_zeroes--){ 3591 grow_bignum(); 3592 *bignum_high = 0; 3593 } 3594 } 3595 p = frag_more(nbytes); 3596 if(md_target_byte_sex == BIG_ENDIAN_BYTE_SEX){ 3597 q = (char *)bignum_low; 3598 for(i = nbytes - 1; i >= 0; i--) 3599 *p++ = q[i]; 3600 } 3601 else{ 3602 memcpy(p, bignum_low, (int)nbytes); 3603 } 3604 /* C contains character after number. */ 3605 SKIP_WHITESPACE(); 3606 c = *input_line_pointer; 3607 /* C contains 1st non-blank character after number. */ 3608 } 3609 demand_empty_rest_of_line(); 3610} 3611 3612/* 3613 * grow_bignum() extends bignum (that is adjust bignum_low, bignum_high and 3614 * bignum_limit). 3615 */ 3616static 3617void 3618grow_bignum( 3619void) 3620{ 3621 int32_t length; 3622 3623 bignum_high++; 3624 if(bignum_high >= bignum_limit) 3625 { 3626 length = bignum_limit - bignum_low; 3627 bignum_low = xrealloc(bignum_low, length + length); 3628 bignum_high = bignum_low + length; 3629 bignum_limit = bignum_low + length + length; 3630 } 3631} 3632#endif /* M68K we allow big cons only on the 68k machines */ 3633 3634/* 3635 * float_cons() 3636 * 3637 * CONStruct some more frag chars of .floats .ffloats etc. 3638 * Makes 0 or more new frags. 3639 * This understands only floating literals, not expressions. Sorry. 3640 * 3641 * A floating constant is defined by atof_generic(), except it is preceded 3642 * by 0d 0f 0g or 0h. After observing the STRANGE way my BSD AS does its 3643 * reading, I decided to be incompatible. This always tries to give you 3644 * rounded bits to the precision of the pseudo-op. Former AS did premature 3645 * truncatation, restored noisy bits instead of trailing 0s AND gave you 3646 * a choice of 2 flavours of noise according to which of 2 floating-point 3647 * scanners you directed AS to use. 3648 * 3649 * In: input_line_pointer -> whitespace before, or '0' of flonum. 3650 * 3651 * Worker function to do .double, .float, .single statements. 3652 * This clobbers input_line-pointer, checks end-of-line. 3653 */ 3654void 3655float_cons( 3656uintptr_t float_type) /* 'f':.ffloat ... 'F':.float ... */ 3657{ 3658 char *p; 3659 char c; 3660 int length; /* Number of chars in an object. */ 3661 char *err; /* Error from scanning floating literal. */ 3662 char temp[MAXIMUM_NUMBER_OF_CHARS_FOR_FLOAT]; 3663 3664 /* 3665 * The following awkward logic is to parse ZERO or more strings, 3666 * comma seperated. Recall an expression includes its leading & 3667 * trailing blanks. We fake a leading ',' if there is (supposed to 3668 * be) a 1st expression, and keep demanding 1 expression for each ','. 3669 */ 3670 if(is_it_end_of_statement()){ 3671 c = 0; /* Skip loop. */ 3672 ++input_line_pointer; /* -> past termintor. */ 3673 } 3674 else{ 3675 c = ','; /* Do loop. */ 3676 } 3677 while(c == ','){ 3678 /* input_line_pointer -> 1st char of a flonum (we hope!). */ 3679 SKIP_WHITESPACE(); 3680 /* 3681 * Skip any 0{letter} that may be present. Don't even check if the 3682 * letter is legal. Someone may invent a "z" format and this routine 3683 * has no use for such information. Lusers beware: you get 3684 * diagnostics if your input is ill-conditioned. 3685 */ 3686 if(input_line_pointer[0] == '0' && isalpha(input_line_pointer[1])) 3687 input_line_pointer+=2; 3688 3689 err = md_atof(float_type, temp, &length); 3690 know(length <= MAXIMUM_NUMBER_OF_CHARS_FOR_FLOAT); 3691 know(length > 0); 3692 if(err != NULL && *err != '\0'){ 3693 as_bad( "Bad floating literal: %s", err); 3694 ignore_rest_of_line(); 3695 /* Input_line_pointer -> just after end-of-line. */ 3696 c = 0; /* Break out of loop. */ 3697 } 3698 else{ 3699 p = frag_more(length); 3700 memcpy(p, temp, length); 3701 SKIP_WHITESPACE(); 3702 c = *input_line_pointer ++; 3703 /* C contains 1st non-white character after number. */ 3704 /* input_line_pointer -> just after terminator (c). */ 3705 } 3706 } 3707 --input_line_pointer; /* -> terminator (is not ','). */ 3708 demand_empty_rest_of_line(); 3709} 3710 3711static void 3712emit_leb128_expr (expressionS *exp, int sign) 3713{ 3714 segT op = exp->X_op; 3715#ifdef notyet 3716 unsigned int nbytes; 3717#endif 3718 3719 if (op == O_absent) 3720 { 3721 as_warn (_("zero assumed for missing expression")); 3722 exp->X_add_number = 0; 3723 op = O_constant; 3724 } 3725 else if (op == O_big && exp->X_add_number <= 0) 3726 { 3727 as_bad (_("floating point number invalid")); 3728 exp->X_add_number = 0; 3729 op = O_constant; 3730 } 3731#ifdef notyet 3732 else if (op == O_register) 3733 { 3734 as_warn (_("register value used as expression")); 3735 op = O_constant; 3736 } 3737 else if (op == O_constant 3738 && sign 3739 && (exp->X_add_number < 0) != !exp->X_unsigned) 3740 { 3741 /* We're outputting a signed leb128 and the sign of X_add_number 3742 doesn't reflect the sign of the original value. Convert EXP 3743 to a correctly-extended bignum instead. */ 3744 convert_to_bignum (exp); 3745 op = O_big; 3746 } 3747 3748 /* Let check_eh_frame know that data is being emitted. nbytes == -1 is 3749 a signal that this is leb128 data. It shouldn't optimize this away. */ 3750 nbytes = (unsigned int) -1; 3751 if (check_eh_frame (exp, &nbytes)) 3752 abort (); 3753 3754 /* Let the backend know that subsequent data may be byte aligned. */ 3755#ifdef md_cons_align 3756 md_cons_align (1); 3757#endif 3758#endif /* notyet */ 3759 3760 if (op == O_constant) 3761 { 3762 /* If we've got a constant, emit the thing directly right now. */ 3763 3764 valueT value = exp->X_add_number; 3765 int size; 3766 char *p; 3767 3768 size = sizeof_leb128 (value, sign); 3769 p = frag_more (size); 3770 output_leb128 (p, value, sign); 3771 } 3772#ifdef notyet 3773 else if (op == O_big) 3774 { 3775 /* O_big is a different sort of constant. */ 3776 3777 int size; 3778 char *p; 3779 3780 size = output_big_leb128 (NULL, generic_bignum, exp->X_add_number, sign); 3781 p = frag_more (size); 3782 output_big_leb128 (p, generic_bignum, exp->X_add_number, sign); 3783 } 3784#endif /* notyet */ 3785 else 3786 { 3787 /* Otherwise, we have to create a variable sized fragment and 3788 resolve things later. */ 3789 3790#ifdef OLD 3791 frag_var (rs_leb128, sizeof_uleb128 (~(valueT) 0), 0, sign, 3792 make_expr_symbol (exp), 0, (char *) NULL); 3793#else 3794 symbolS *sym; 3795 expressionS *expression; 3796 3797 sym = symbol_temp_new(exp->X_add_symbol->sy_other /* GUESS */, 0, NULL); 3798 expression = xmalloc(sizeof(expressionS)); 3799 *expression = *exp; 3800 sym->expression = expression; 3801 sym->sy_frag = &zero_address_frag; 3802 frag_var (rs_leb128, sizeof_leb128 ( ((valueT) (~(valueT) 0) >> 1), 0), 0, sign, 3803 sym, 0, (char *) NULL); 3804 frchain_now->has_rs_leb128s = TRUE; 3805#endif 3806 3807 } 3808} 3809 3810/* Parse the .sleb128 and .uleb128 pseudos. */ 3811 3812static 3813void 3814s_leb128( 3815uintptr_t sign) 3816{ 3817 expressionS exp; 3818 3819#ifdef md_flush_pending_output 3820 md_flush_pending_output (); 3821#endif 3822 3823 do 3824 { 3825 expression (&exp); 3826 emit_leb128_expr (&exp, sign); 3827 } 3828 while (*input_line_pointer++ == ','); 3829 3830 input_line_pointer--; 3831 demand_empty_rest_of_line (); 3832} 3833 3834/* 3835 * stringer() 3836 * 3837 * We read 0 or more ',' seperated, double-quoted strings. 3838 * 3839 * Worker function to do .ascii etc statements. 3840 * Checks end-of-line. 3841 */ 3842void 3843stringer( 3844uintptr_t append_zero) /* 0: don't append '\0', else 1 */ 3845{ 3846 int c; 3847 3848 /* 3849 * The following awkward logic is to parse ZERO or more strings, 3850 * comma seperated. Recall a string expression includes spaces 3851 * before the opening '\"' and spaces after the closing '\"'. 3852 * We fake a leading ',' if there is (supposed to be) 3853 * a 1st, expression. We keep demanding expressions for each 3854 * ','. 3855 */ 3856 if(is_it_end_of_statement()){ 3857 c = 0; /* Skip loop. */ 3858 ++ input_line_pointer; /* Compensate for end of loop. */ 3859 } 3860 else{ 3861 c = ','; /* Do loop. */ 3862 } 3863 for( ; c == ','; c = *input_line_pointer++){ 3864 SKIP_WHITESPACE(); 3865 if(*input_line_pointer == '\"'){ 3866 ++input_line_pointer; /* -> 1st char of string. */ 3867 while((c = next_char_of_string()) >= 0){ 3868 FRAG_APPEND_1_CHAR(c); 3869 } 3870 if(append_zero){ 3871 FRAG_APPEND_1_CHAR(0); 3872 } 3873 know(input_line_pointer[-1] == '\"'); 3874 } 3875 else{ 3876 as_bad("Expected \"-ed string"); 3877 } 3878 SKIP_WHITESPACE(); 3879 } 3880 --input_line_pointer; 3881 demand_empty_rest_of_line(); 3882} 3883 3884/* 3885 * next_char_of_string() is used by stringer() and demand_copy_string() and 3886 * returns the next character from input_line_pointer that is in the string or 3887 * -1 for the trailing " character. This routine handles escaped characters 3888 * like \b, \f, etc. 3889 */ 3890static 3891int 3892next_char_of_string( 3893void) 3894{ 3895 int c; 3896 int32_t number, i; 3897 3898 c = *input_line_pointer++; 3899 /* make sure the 0xff char is not returned as -1 */ 3900 c = (c & MASK_CHAR); 3901 switch(c){ 3902 case '\"': 3903#ifdef PPC 3904 if(flagseen[(int)'p'] == TRUE) 3905 break; 3906#endif /* PPC */ 3907 c = -1; 3908 break; 3909 3910#ifdef PPC 3911 case '\'': 3912 if(flagseen[(int)'p'] == TRUE) 3913 c = -1; 3914 break; 3915#endif /* PPC */ 3916 3917 case '\\': 3918 c = *input_line_pointer++; 3919 switch(c){ 3920 case 'b': 3921 c = '\b'; 3922 break; 3923 case 'f': 3924 c = '\f'; 3925 break; 3926 case 'n': 3927 c = '\n'; 3928 break; 3929 case 'r': 3930 c = '\r'; 3931 break; 3932 case 't': 3933 c = '\t'; 3934 break; 3935 case '\\': 3936 case '"': 3937 case '\'': 3938 break; /* As itself. */ 3939 case '0': 3940 case '1': 3941 case '2': 3942 case '3': 3943 case '4': 3944 case '5': 3945 case '6': 3946 case '7': 3947 case '8': 3948 case '9': 3949 for(i = 0, number = 0; 3950 i < 3 && isdigit(c) && c < '8'; 3951 i++, c = *input_line_pointer++) 3952 number = number * 8 + c - '0'; 3953 c = number; 3954 --input_line_pointer; 3955 break; 3956 case '\n': 3957 /* To be compatible with BSD 4.2 as: give the user a linefeed */ 3958 c = '\n'; 3959 break; 3960 3961 default: 3962 as_bad( "Bad escaped character in string, '?' assumed" ); 3963 c = '?'; 3964 break; 3965 } 3966 break; 3967 default: 3968 break; 3969 } 3970 return(c); 3971} 3972 3973/* 3974 * get_segmented_expression() is passed an expression to fill in and return that 3975 * is anything except a bignum or a missing expression. 3976 */ 3977static 3978segT 3979get_segmented_expression( 3980expressionS *expP) 3981{ 3982 segT retval; 3983 3984 retval = expression(expP); 3985 if(retval == SEG_NONE || retval == SEG_BIG){ 3986 as_bad("Expected address expression: absolute 0 assumed"); 3987 retval = expP->X_seg = SEG_ABSOLUTE; 3988 expP->X_add_number = 0; 3989 expP->X_add_symbol = NULL; 3990 expP->X_subtract_symbol = NULL; 3991 } 3992 return(retval); /* SEG_ ABSOLUTE,UNKNOWN,SECT */ 3993} 3994 3995/* 3996 * get_known_segmented_expression() is passed an expression to fill in and 3997 * return that is anything except an unknown, bignum or a missing expression. 3998 */ 3999segT 4000get_known_segmented_expression( 4001expressionS *expP) 4002{ 4003 segT retval; 4004 char *name1; 4005 char *name2; 4006 4007 retval = get_segmented_expression(expP); 4008 if(retval == SEG_UNKNOWN){ 4009 name1 = expP->X_add_symbol ? 4010 expP->X_add_symbol->sy_name : ""; 4011 name2 = expP->X_subtract_symbol ? 4012 expP->X_subtract_symbol->sy_name : ""; 4013 if(name1 && name2){ 4014 as_bad("Symbols \"%s\" \"%s\" are undefined: absolute 0 " 4015 "assumed.", name1, name2); 4016 } 4017 else{ 4018 as_bad("Symbol \"%s\" undefined: absolute 0 assumed.", 4019 name1 ? name1 : name2); 4020 } 4021 retval = SEG_ABSOLUTE; 4022 expP->X_seg = SEG_ABSOLUTE; 4023 expP->X_add_number = 0; 4024 expP->X_add_symbol = NULL; 4025 expP->X_subtract_symbol = NULL; 4026 } 4027 know(retval == SEG_ABSOLUTE || 4028 retval == SEG_SECT || 4029 retval == SEG_DIFFSECT); 4030 return(retval); 4031} 4032 4033/* 4034 * get_absolute_expression() gets an absolute expression and returns the value 4035 * of that expression. 4036 */ 4037signed_target_addr_t 4038get_absolute_expression( 4039void) 4040{ 4041 expressionS exp; 4042 segT s; 4043 4044 s = expression(&exp); 4045 if(s != SEG_ABSOLUTE){ 4046/* is this right? if not absolute: no message and return 0 */ 4047 if(s != SEG_NONE){ 4048 as_bad("Bad Absolute Expression, absolute 0 assumed."); 4049 } 4050 exp.X_add_number = 0; 4051 } 4052 return(exp.X_add_number); 4053} 4054 4055/* 4056 * get_absolute_expression_and_terminator() gets an absolute expression and 4057 * returning the value of that expression indirectly through val_pointer and 4058 * returns the terminator. 4059 */ 4060static 4061char /* return terminator */ 4062get_absolute_expression_and_terminator( 4063int32_t *val_pointer) /* return value of expression */ 4064{ 4065 *val_pointer = get_absolute_expression(); 4066 return(*input_line_pointer++); 4067} 4068 4069/* 4070 * demand_copy_C_string() 4071 * 4072 * Like demand_copy_string, but return NULL if the string contains any '\0's. 4073 * Give a warning if that happens. 4074 */ 4075char * 4076demand_copy_C_string( 4077int *len_pointer) 4078{ 4079 char *s; 4080 int len; 4081 4082 if((s = demand_copy_string(len_pointer))){ 4083 for(len = *len_pointer; len > 0; len--){ 4084 if(*s == '\0'){ 4085 s = 0; 4086 len = 1; 4087 *len_pointer = 0; 4088 as_bad("This string may not contain \'\\0\'"); 4089 } 4090 } 4091 } 4092 return(s); 4093} 4094 4095/* 4096 * demand_copy_string() 4097 * 4098 * Demand string, but return a safe (=private) copy of the string. 4099 * Return NULL if we can't read a string here. 4100 */ 4101static 4102char * 4103demand_copy_string( 4104int *lenP) 4105{ 4106 int c; 4107 int len; 4108 char *retval; 4109 4110 len = 0; 4111 SKIP_WHITESPACE(); 4112#ifdef PPC 4113 if((flagseen[(int)'p'] == TRUE && *input_line_pointer == '\'') || 4114 (flagseen[(int)'p'] == FALSE && *input_line_pointer == '\"')) 4115#else 4116 if(*input_line_pointer == '\"') 4117#endif 4118 { 4119 input_line_pointer++; /* Skip opening quote. */ 4120 while((c = next_char_of_string()) >= 0){ 4121 (void)(obstack_1grow(¬es, c)); 4122 len++; 4123 } 4124 /* 4125 * This next line is so demand_copy_C_string will return a null 4126 * termanated string. 4127 */ 4128 (void)(obstack_1grow(¬es, '\0')); 4129 retval = obstack_finish(¬es); 4130 } 4131 else{ 4132 as_bad("Missing string"); 4133 retval = NULL; 4134 ignore_rest_of_line(); 4135 } 4136 *lenP = len; 4137 return(retval); 4138} 4139 4140/* 4141 * is_it_end_of_statement() 4142 * 4143 * In: Input_line_pointer -> next character. 4144 * 4145 * Do: Skip input_line_pointer over all whitespace. 4146 * 4147 * Out: TRUE if input_line_pointer -> end-of-line. 4148 */ 4149static 4150int 4151is_it_end_of_statement( 4152void) 4153{ 4154 SKIP_WHITESPACE(); 4155 return(is_end_of_line(*input_line_pointer)); 4156} 4157 4158/* 4159 * equals() implements the assembly statement: 4160 * x = expression 4161 */ 4162static 4163void 4164equals( 4165char *sym_name) 4166{ 4167 struct symbol *symbolP; 4168 segT segment; 4169 expressionS exp; 4170 char *p; 4171 4172 /* Turn '. = mumble' into a .org mumble */ 4173 if(sym_name[0]=='.' && sym_name[1]=='\0'){ 4174 if(input_line_pointer[1] == '=') 4175 input_line_pointer += 2; 4176 else 4177 *input_line_pointer++ = '='; /* Put it back */ 4178 if(*input_line_pointer==' ' || *input_line_pointer=='\t') 4179 input_line_pointer++; 4180 segment = get_known_segmented_expression(&exp); 4181 if((segment != SEG_SECT || 4182 exp.X_add_symbol->sy_other != frchain_now->frch_nsect) && 4183 segment != SEG_ABSOLUTE) 4184 as_bad("Illegal expression. current section assumed."); 4185 p = frag_var(rs_org, 4186 1, 4187 1, 4188 (relax_substateT)0, 4189 exp.X_add_symbol, 4190 exp.X_add_number, 4191 (char *)0); 4192 *p = 0; 4193 return; 4194 } 4195 4196 symbolP = symbol_find_or_make(sym_name); 4197 if(symbolP->sy_type & N_ABS) 4198 symbolP->sy_desc |= N_NO_DEAD_STRIP; 4199 if(input_line_pointer[1] == '=') 4200 input_line_pointer += 2; 4201 else 4202 *input_line_pointer++ = '='; /* Put it back */ 4203 if(*input_line_pointer==' ' || *input_line_pointer=='\t') 4204 input_line_pointer++; 4205 pseudo_set(symbolP); 4206} 4207 4208/* 4209 * s_if() implements the pseudo op: 4210 * .if expression 4211 * that does conditional assembly using assembler defined expressions. 4212 */ 4213static 4214void 4215s_if( 4216uintptr_t value) 4217{ 4218 if(if_depth >= MAX_IF_DEPTH) 4219 as_fatal("You can't nest if's more than %d levels deep", 4220 MAX_IF_DEPTH); 4221 last_states[if_depth++] = the_cond_state; 4222 the_cond_state.the_cond = if_cond; 4223 if(the_cond_state.ignore) 4224 totally_ignore_line(); 4225 else{ 4226 the_cond_state.cond_met = get_absolute_expression(); 4227 the_cond_state.ignore = !the_cond_state.cond_met; 4228 demand_empty_rest_of_line(); 4229 } 4230} 4231 4232/* 4233 * s_elseif() implements the pseudo op: 4234 * .elseif expression 4235 * that does conditional assembly using assembler defined expressions. 4236 */ 4237static 4238void 4239s_elseif( 4240uintptr_t value) 4241{ 4242 int last_ignore_state; 4243 4244 if(the_cond_state.the_cond != if_cond && 4245 the_cond_state.the_cond != elseif_cond) 4246 as_fatal("Encountered a .elseif that doesn't follow a .if or an " 4247 ".elseif"); 4248 the_cond_state.the_cond = elseif_cond; 4249 4250 last_ignore_state = FALSE; 4251 if(if_depth) 4252 last_ignore_state = last_states[if_depth-1].ignore; 4253 if(last_ignore_state || the_cond_state.cond_met){ 4254 the_cond_state.ignore = TRUE; 4255 totally_ignore_line(); 4256 } 4257 else{ 4258 the_cond_state.cond_met = get_absolute_expression(); 4259 the_cond_state.ignore = !the_cond_state.cond_met; 4260 demand_empty_rest_of_line(); 4261 } 4262} 4263 4264/* 4265 * s_else() implements the pseudo op: 4266 * .else 4267 * that does conditional assembly using assembler defined expressions. 4268 */ 4269static 4270void 4271s_else( 4272uintptr_t value) 4273{ 4274 int last_ignore_state; 4275 4276 if(the_cond_state.the_cond != if_cond && 4277 the_cond_state.the_cond != elseif_cond) 4278 as_fatal("Encountered a .else that doesn't follow a .if or an " 4279 ".elseif"); 4280 the_cond_state.the_cond = else_cond; 4281 last_ignore_state = FALSE; 4282 if(if_depth) 4283 last_ignore_state = last_states[if_depth-1].ignore; 4284 if(last_ignore_state || the_cond_state.cond_met) 4285 the_cond_state.ignore = TRUE; 4286 else 4287 the_cond_state.ignore = FALSE; 4288 demand_empty_rest_of_line(); 4289} 4290 4291/* 4292 * s_endif() implements the pseudo op: 4293 * .endif 4294 * that does conditional assembly using assembler defined expressions. 4295 */ 4296static 4297void 4298s_endif( 4299uintptr_t value) 4300{ 4301 if((the_cond_state.the_cond == no_cond) || (if_depth == 0)) 4302 as_fatal("Encountered a .endif that doesn't follow a .if or .else"); 4303 the_cond_state = last_states[--if_depth]; 4304 demand_empty_rest_of_line(); 4305} 4306 4307/* 4308 * totally_ignore_line() ignores lines during conditional assembly. 4309 */ 4310void 4311totally_ignore_line( 4312void) 4313{ 4314 if(!is_end_of_line(*input_line_pointer)){ 4315 while(input_line_pointer < buffer_limit && 4316 !is_end_of_line(*input_line_pointer)){ 4317 input_line_pointer ++; 4318 } 4319 } 4320 input_line_pointer++; /* Return pointing just after end-of-line. */ 4321 know(is_end_of_line(input_line_pointer[-1])); 4322} 4323 4324/* 4325 * s_macros_on() implements the pseudo op: 4326 * .macros_on 4327 */ 4328static 4329void 4330s_macros_on( 4331uintptr_t value) 4332{ 4333 macros_on = TRUE; 4334 demand_empty_rest_of_line(); 4335} 4336 4337/* 4338 * s_macros_off() implements the pseudo op: 4339 * .macros_off 4340 */ 4341void 4342s_macros_off( 4343uintptr_t value) 4344{ 4345 macros_on = FALSE; 4346 demand_empty_rest_of_line(); 4347} 4348 4349/* 4350 * s_macro() implements the pseudo op: 4351 * .macro macro_name 4352 * that defines a macro. 4353 */ 4354void 4355s_macro( 4356uintptr_t value) 4357{ 4358 int c; 4359 pseudo_typeS *pop; 4360 4361 if(macro_name) 4362 as_bad("Can't define a macro inside another macro definition"); 4363 else{ 4364 SKIP_WHITESPACE(); 4365 while(is_part_of_name(c = *input_line_pointer ++)) 4366 (void)(obstack_1grow (¯os, c)); 4367 (void)(obstack_1grow(¯os, '\0')); 4368 --input_line_pointer; 4369 macro_name = obstack_finish(¯os); 4370 if(macro_name == NULL) 4371 as_bad("Missing name of macro"); 4372 if(*macro_name == '.'){ 4373 pop = (pseudo_typeS *)hash_find(po_hash, macro_name + 1); 4374 if(pop != NULL) 4375 as_bad("Pseudo-op name: %s can't be a macro name", 4376 macro_name); 4377 } 4378 } 4379 totally_ignore_line(); 4380} 4381 4382/* 4383 * s_endmacro() implements the pseudo op: 4384 * .endmacro 4385 * which is the end of a macro definition. 4386 */ 4387void 4388s_endmacro( 4389uintptr_t value) 4390{ 4391 const char *errorString; 4392 4393 if(!macro_name){ 4394 as_bad ("This .endmacro does not match with a preceding .macro"); 4395 ignore_rest_of_line(); 4396 } 4397 else{ 4398 (void)(obstack_1grow(¯os, '\0')); 4399 errorString = hash_insert(ma_hash, macro_name, 4400 obstack_finish(¯os)); 4401 if(errorString != NULL && *errorString) 4402 as_warn("The macro named \"%s\" is already defined", 4403 macro_name); 4404 macro_name = NULL; 4405 } 4406} 4407 4408/* 4409 * macro_begin() initializes macros. 4410 */ 4411static 4412void 4413macro_begin( 4414void) 4415{ 4416 ma_hash = hash_new(); 4417 obstack_begin(¯os, 5000); 4418} 4419 4420/* 4421 * add_to_macro_definition() is called after a .macro to store the contents of 4422 * a macro into the obstack. 4423 */ 4424void 4425add_to_macro_definition( 4426char *char_pointer) 4427{ 4428 char c; 4429 4430 do{ 4431 c = *char_pointer ++; 4432 know(c != '\0'); 4433 (void)(obstack_1grow(¯os, c)); 4434 }while((c != ':') && !(is_end_of_line(c))); 4435 if(char_pointer > input_line_pointer) 4436 input_line_pointer = char_pointer; 4437} 4438 4439/* 4440 * expand_macro() is called to expand macros. 4441 */ 4442static 4443void 4444expand_macro( 4445char *macro_contents) 4446{ 4447 char *buffer; 4448 char c; 4449 int index, nargs; 4450 char *last_buffer_limit; 4451 int last_count_lines; 4452 char *last_input_line_pointer; 4453 char *arguments [10]; /* at most 10 arguments, each is substituted */ 4454 4455 if(macro_depth >= MAX_MACRO_DEPTH) 4456 as_fatal("You can't nest macros more than %d levels deep", 4457 MAX_MACRO_DEPTH); 4458 macro_depth++; 4459 4460 /* copy each argument to a object in the macro obstack */ 4461 nargs = 0; 4462 for(index = 0; index < 10; index ++){ 4463 if(*input_line_pointer == ' ') 4464 ++input_line_pointer; 4465 know(*input_line_pointer != ' '); 4466 c = *input_line_pointer; 4467 if(is_end_of_line(c)) 4468 arguments[index] = NULL; 4469 else{ 4470 int parenthesis_depth = 0; 4471 do{ 4472 SKIP_WHITESPACE(); 4473 c = *input_line_pointer++; 4474 if(parenthesis_depth){ 4475 if(c == ')') 4476 parenthesis_depth --; 4477 } 4478 else{ 4479 if(c == '(') 4480 parenthesis_depth ++; 4481 else 4482 if(is_end_of_line(c) || 4483 (c == ' ') || (c == ',')) 4484 break; 4485 } 4486 know(c != '\0'); 4487 if(is_end_of_line(c)) 4488 as_bad("mismatched parenthesis"); 4489 (void)(obstack_1grow(¯os, c)); 4490 }while(1); 4491 (void)(obstack_1grow(¯os, '\0')); 4492 arguments[index] = obstack_finish(¯os); 4493 nargs++; 4494 if(is_end_of_line(c)) 4495 --input_line_pointer; 4496 else if(c == ' ') 4497 if(*input_line_pointer == ',') 4498 input_line_pointer++; 4499 } 4500 } 4501 if(!is_end_of_line(c)){ 4502 as_bad("More than 10 arguments not allowed for macros"); 4503 ignore_rest_of_line(); 4504 } 4505 /* 4506 * Build a buffer containing the macro contents with arguments 4507 * substituted 4508 */ 4509 (void)(obstack_1grow(¯os, '\n')); 4510 while((c = *macro_contents++)){ 4511 if(c == '$'){ 4512 if(*macro_contents == '$'){ 4513 macro_contents++; 4514 } 4515 else if((*macro_contents >= '0') && (*macro_contents <= '9')){ 4516 index = *macro_contents++ - '0'; 4517 last_input_line_pointer = macro_contents; 4518 macro_contents = arguments[index]; 4519 if(macro_contents){ 4520 while ((c = * macro_contents ++)) 4521 (void)(obstack_1grow (¯os, c)); 4522 } 4523 macro_contents = last_input_line_pointer; 4524 continue; 4525 } 4526 else if (*macro_contents == 'n'){ 4527 macro_contents++ ; 4528 (void)(obstack_1grow(¯os, nargs + '0')); 4529 continue; 4530 } 4531 } 4532 (void)(obstack_1grow (¯os, c)); 4533 } 4534 (void)(obstack_1grow (¯os, '\n')); 4535 (void)(obstack_1grow (¯os, '\0')); 4536 last_buffer_limit = buffer_limit; 4537 last_count_lines = count_lines; 4538 last_input_line_pointer = input_line_pointer; 4539 buffer_limit = obstack_next_free (¯os) - 1; 4540 buffer = obstack_finish (¯os); 4541 count_lines = FALSE; 4542 /* 4543 printf("expanded macro: %s", buffer + 1); 4544 */ 4545#ifdef PPC 4546 if(flagseen[(int)'p'] == TRUE) 4547 ppcasm_parse_a_buffer(buffer + 1); 4548 else 4549#endif /* PPC */ 4550 parse_a_buffer(buffer + 1); 4551 obstack_free (¯os, buffer); 4552 for(index = 9; index >= 0; index --) 4553 if(arguments[index]) 4554 obstack_free(¯os, arguments[index]); 4555 buffer_limit = last_buffer_limit; 4556 count_lines = last_count_lines; 4557 input_line_pointer = last_input_line_pointer; 4558 macro_depth--; 4559} 4560 4561/* 4562 * s_dump() implements the pseudo op: 4563 * .dump filename 4564 * that does a quick binary dump of symbol tables. 4565 */ 4566static 4567void 4568s_dump( 4569uintptr_t value) 4570{ 4571 char *filename; 4572 int length; 4573 static char null_string[] = ""; 4574 4575 if((filename = demand_copy_string(&length))){ 4576 demand_empty_rest_of_line(); 4577 if((dump_fp = fopen(filename, "w+"))){ 4578 hash_traverse(ma_hash, write_macro); 4579 fwrite(null_string, 1, 1, dump_fp); 4580 hash_traverse(sy_hash, write_symbol); 4581 fwrite(null_string, 1, 1, dump_fp); 4582 fclose(dump_fp); 4583 } 4584 else 4585 as_bad("couldn't write to dump file: \"%s\"", filename); 4586 } 4587} 4588 4589/* 4590 * write_macro() used by hash_traverse indirectly through s_dump() to write one 4591 * macro. 4592 */ 4593static 4594void 4595write_macro( 4596const char *string, 4597PTR value1) 4598{ 4599 char *value = value1; 4600 know(string); 4601 know(value); 4602 know(strlen(string)); 4603 fwrite(string, (strlen(string) + 1), 1, dump_fp); 4604 fwrite(value, (strlen(value) + 1), 1, dump_fp); 4605} 4606 4607/* 4608 * write_symbol() used by hash_traverse indirectly through s_dump() to write one 4609 * N_ABS symbol and its value. 4610 */ 4611static 4612void 4613write_symbol( 4614const char *string, 4615PTR value) 4616{ 4617 symbolS *symbolP; 4618 4619 symbolP = (symbolS *)value; 4620 know(symbolP); 4621 if(((symbolP->sy_type) & N_TYPE) == N_ABS){ 4622 know(string); 4623 know(strlen(string)); 4624 fwrite(string, (strlen(string) + 1), 1, dump_fp); 4625 fwrite(&(symbolP -> sy_value), 4, 1, dump_fp); 4626 } 4627} 4628 4629/* 4630 * s_load() implements the pseudo op: 4631 * .load filename 4632 * that does a quick binary load of symbol tables. 4633 */ 4634static 4635void 4636s_load( 4637uintptr_t value) 4638{ 4639 char *char_pointer; 4640 char *filename; 4641 int length; 4642 char the_char; 4643 symbolS *the_symbol; 4644 symbolS *temp_symbol_lastP; 4645 static symbolS *dump_symbol_lastP; 4646 4647 if((filename = demand_copy_string(&length))){ 4648 demand_empty_rest_of_line(); 4649 if((dump_fp = fopen(filename, "r+"))){ 4650 do{ 4651 do{ 4652 the_char = getc_unlocked(dump_fp); 4653 (void)(obstack_1grow(¯os, the_char)); 4654 }while(the_char); 4655 char_pointer = obstack_finish (¯os); 4656 if(!(*char_pointer)) 4657 break; 4658 do{ 4659 the_char = getc_unlocked(dump_fp); 4660 (void)(obstack_1grow(¯os, the_char)); 4661 }while(the_char); 4662 if(hash_insert(ma_hash, char_pointer, 4663 obstack_finish(¯os))) 4664 as_bad("a macro named \"%s\" encountered in a .load " 4665 "is already defined", char_pointer); 4666 }while(1); 4667 /* 4668 * We don't want to link in symbols that were loaded so they 4669 * don't go out in the object file. Instead these symbols 4670 * should go out in the object file that did the .dump . 4671 */ 4672 temp_symbol_lastP = symbol_lastP; 4673 symbol_lastP = dump_symbol_lastP; 4674 do{ 4675 do{ 4676 the_char = getc_unlocked(dump_fp); 4677 (void)(obstack_1grow(¯os, the_char)); 4678 }while(the_char); 4679 char_pointer = obstack_base(¯os); 4680 obstack_next_free(¯os) = char_pointer; 4681 if(!(*char_pointer)) 4682 break; 4683 the_symbol = symbol_find_or_make(char_pointer); 4684 the_symbol->sy_type = N_ABS; 4685 char_pointer = (char *)&the_symbol->sy_value; 4686 *char_pointer++ = getc_unlocked(dump_fp); 4687 *char_pointer++ = getc_unlocked(dump_fp); 4688 *char_pointer++ = getc_unlocked(dump_fp); 4689 *char_pointer++ = getc_unlocked(dump_fp); 4690 the_symbol->sy_frag = &zero_address_frag; 4691 }while(1); 4692 dump_symbol_lastP = symbol_lastP; 4693 symbol_lastP = temp_symbol_lastP; 4694 fclose(dump_fp); 4695 } 4696 else 4697 as_fatal("Couldn't find the dump file: \"%s\"", filename); 4698 } 4699} 4700 4701/* 4702 * s_subsections_via_symbols() implements the pseudo op: 4703 * .subsections_via_symbols 4704 * which will cause the MH_SUBSECTIONS_VIA_SYMBOLS flag to be set in the output 4705 * file. This indicates to the static linker it is safe to divide up the 4706 * sections into sub-sections via symbols for dead code stripping. 4707 */ 4708static 4709void 4710s_subsections_via_symbols( 4711uintptr_t value) 4712{ 4713 demand_empty_rest_of_line(); 4714 subsections_via_symbols = TRUE; 4715} 4716 4717/* 4718 * s_machine() implements the pseudo op: 4719 * .machine <arch_name> 4720 * where <arch_name> is allowed to be the same strings as the argument to the 4721 * command line argument -arch <arch_name> . 4722 */ 4723static 4724void 4725s_machine( 4726uintptr_t value) 4727{ 4728 char *arch_name, c; 4729 struct arch_flag arch_flag; 4730 cpu_subtype_t new_cpusubtype; 4731 const struct arch_flag *family_arch_flag; 4732 4733 arch_name = input_line_pointer; 4734 /* 4735 * Can't call get_symbol_end() here as some arch names have '-' in them. 4736 */ 4737 do{ 4738 c = *input_line_pointer++ ; 4739 }while(c != '\0' && c != '\n' && c != '\t' && c != ' '); 4740 *--input_line_pointer = 0; 4741 4742 if(force_cpusubtype_ALL == FALSE){ 4743 family_arch_flag = NULL; 4744 if(strcmp(arch_name, "all") == 0){ 4745 family_arch_flag = get_arch_family_from_cputype(md_cputype); 4746 if(family_arch_flag != NULL) 4747 arch_flag = *family_arch_flag; 4748 } 4749 if(family_arch_flag == NULL && 4750 get_arch_from_flag(arch_name, &arch_flag) == 0){ 4751 as_bad("unknown .machine argument: %s", arch_name); 4752 return; 4753 } 4754 if(arch_flag.cputype != md_cputype){ 4755 as_bad("invalid .machine argument: %s", arch_name); 4756 } 4757 else{ 4758 new_cpusubtype = cpusubtype_combine(md_cputype, 4759 md_cpusubtype, 4760 arch_flag.cpusubtype); 4761 if(new_cpusubtype == -1){ 4762 as_bad(".machine argument: %s can not be combined " 4763 "with previous .machine directives, -arch " 4764 "arguments or machine specific instructions", 4765 arch_name); 4766 } 4767 else{ 4768 archflag_cpusubtype = new_cpusubtype; 4769 } 4770 } 4771 } 4772 4773 *input_line_pointer = c; 4774 demand_empty_rest_of_line(); 4775} 4776 4777/* 4778 * s_secure_log_reset() implements the pseudo op: 4779 * .secure_log_reset 4780 * .secure_log_reset takes no parameters, and resets the "unique" counter. As 4781 * it is an error if a .s_secure_log_unique directive is seen twice without 4782 * and .secure_log_reset appearing between them. 4783 */ 4784static 4785void 4786s_secure_log_reset( 4787uintptr_t value) 4788{ 4789 s_secure_log_used = FALSE; 4790 demand_empty_rest_of_line(); 4791} 4792 4793/* 4794 * s_secure_log_unique() implements the pseudo op: 4795 * .s_secure_log_unique log_msg 4796 * This opens the file given by the environment varable AS_SECURE_LOG_FILE, and 4797 * appends the current filename, line number, and the text given as the log_msg 4798 * in the directive. If this is present, but AS_SECURE_LOG_FILE is not set, 4799 * an error message is generated. If this appears twice without 4800 * .secure_log_reset appearing between them, an error message is generated. 4801 */ 4802static 4803void 4804s_secure_log_unique( 4805uintptr_t value) 4806{ 4807 FILE *secure_log_fp; 4808 char *log_msg, c; 4809 4810 if(s_secure_log_used != FALSE) 4811 as_fatal(".secure_log_unique specified multiple times"); 4812 4813 if(secure_log_file == FALSE) 4814 as_fatal(".secure_log_unique used but AS_SECURE_LOG_FILE " 4815 "environment variable unset."); 4816 4817 log_msg = input_line_pointer; 4818 do{ 4819 c = *input_line_pointer++; 4820 } while(is_end_of_line(c) == FALSE); 4821 *--input_line_pointer = 0; 4822 4823 if((secure_log_fp = fopen(secure_log_file, "a+"))){ 4824 char *file; 4825 unsigned int line; 4826 4827 as_file_and_line(&file, &line); 4828 fprintf(secure_log_fp, "%s:%d:%s\n", 4829 (file != NULL) ? file : "unknown", 4830 line, log_msg); 4831 4832 fclose(secure_log_fp); 4833 } 4834 else 4835 as_fatal("couldn't write to secure log file: \"%s\"", 4836 secure_log_file); 4837 4838 s_secure_log_used = TRUE; 4839 4840 *input_line_pointer = c; 4841 demand_empty_rest_of_line(); 4842} 4843 4844/* 4845 * When inlineasm_checks is non-zero, then these variable are set and used 4846 * when reporting errors for the properties of GCC function-scope inline asms. 4847 */ 4848int inlineasm_checks = 0; 4849char *inlineasm_file_name = NULL; 4850int inlineasm_line_number = 0; 4851int inlineasm_column_number = 0; 4852 4853/* 4854 * s_inlineasm() handles the pseudo ops: 4855 * .inlineasmstart [[["file_name"] [,<line_number>]] [,<column_number>]] 4856 * .inlineasmend 4857 * The parameter value is 1 for start and 0 for end. The arguments to the 4858 * start directive are optional. 4859 * 4860 * This causes the assembler enforces properties required of GCC function-scope 4861 * inline asms. 4862 * 4863 * The requirement that does not allow non-numeric labels to be defined in an 4864 * inline asm is checked for in colon(). 4865 */ 4866static 4867void 4868s_inlineasm( 4869uintptr_t value) 4870{ 4871 int length; 4872 4873 inlineasm_checks = value; 4874 inlineasm_file_name = NULL; 4875 inlineasm_line_number = 0; 4876 inlineasm_column_number = 0; 4877 4878 SKIP_WHITESPACE(); 4879 if(value == 1 && *input_line_pointer == '"'){ 4880 if((inlineasm_file_name = demand_copy_string(&length))){ 4881 SKIP_WHITESPACE(); 4882 if(*input_line_pointer == ','){ 4883 input_line_pointer++; 4884 inlineasm_line_number = get_absolute_expression(); 4885 SKIP_WHITESPACE(); 4886 if(*input_line_pointer == ','){ 4887 input_line_pointer++; 4888 inlineasm_column_number = get_absolute_expression(); 4889 } 4890 } 4891 } 4892 } 4893 demand_empty_rest_of_line(); 4894} 4895 4896/* 4897 * s_incbin() implements the pseudo op: 4898 * .incbin "filename" 4899 */ 4900static 4901void 4902s_incbin( 4903uintptr_t value) 4904{ 4905 char *filename, *whole_file_name, *p; 4906 int length; 4907 FILE *fp; 4908 int the_char; 4909 4910 /* Some assemblers tolerate immediately following '"' */ 4911 if((filename = demand_copy_string( & length ) )) { 4912 demand_empty_rest_of_line(); 4913 whole_file_name = find_an_include_file(filename); 4914 if(whole_file_name != NULL && 4915 (fp = fopen(whole_file_name, "r"))){ 4916 do{ 4917 the_char = getc_unlocked(fp); 4918 if (the_char != -1){ 4919 p = frag_more(1); 4920 *p = the_char; 4921 } 4922 }while(the_char != -1); 4923 fclose(fp); 4924 return; 4925 } 4926 as_fatal("Couldn't find the .incbin file: \"%s\"", filename); 4927 } 4928} 4929 4930/* 4931 * s_data_region() parses and ignores the pseudo op: 4932 * .data_region { region_type } 4933 * region_type := "jt8" | "jt16" | "jt32" | "jta32" 4934 */ 4935static 4936void 4937s_data_region( 4938uintptr_t value) 4939{ 4940 char *region_type, c; 4941 4942 c = *input_line_pointer; 4943 if(c != '\n'){ 4944 region_type = input_line_pointer; 4945 do{ 4946 c = *input_line_pointer++; 4947 }while(c != '\n'); 4948 input_line_pointer--; 4949 } 4950 demand_empty_rest_of_line(); 4951} 4952 4953/* 4954 * s_end_data_region() parses and ignores the pseudo op: 4955 * .end_data_region 4956 */ 4957static 4958void 4959s_end_data_region( 4960uintptr_t value) 4961{ 4962 demand_empty_rest_of_line(); 4963} 4964 4965#ifdef SPARC 4966 4967/* Special stuff to allow assembly of Sun assembler sources 4968 This unfortunatley needs to be here instead of sparc.c because it 4969 uses the hash tables defined here. 4970 see also sparc.c for pseudo_table entries 4971*/ 4972 4973/* Handle the SUN sparc assembler .seg directive. .seg should only occur with 4974 either a ".text" or ".data" argument. Call .text or .data accordingly 4975*/ 4976void 4977s_seg (ignore) 4978 int ignore; 4979{ 4980 pseudo_typeS *ps_t; 4981 char s[32]; 4982 4983 printf("S_SEG\n"); 4984 4985 if (strncmp (input_line_pointer, "\"text\"", 6) == 0) 4986 { 4987 input_line_pointer += 6; 4988 /* relies on .text being first section */ 4989 (void)s_builtin_section(builtin_sections); 4990 demand_empty_rest_of_line(); 4991 return; 4992 } 4993 if (strncmp (input_line_pointer, "\"data\"", 6) == 0) 4994 { 4995 /* copy the argument */ 4996 input_line_pointer++; 4997 strncpy(s, input_line_pointer, 4); 4998 input_line_pointer += 5; 4999 /* find the section table index for .data */ 5000 ps_t = (pseudo_typeS *) hash_find(po_hash, s); 5001 5002 if (ps_t == 0) 5003 as_bad ("invalid .seg argument"); 5004 5005 printf("INDEX %s, %p\n", s, (void *)ps_t->poc_val); 5006 5007 s_builtin_section ((const struct builtin_section *)ps_t->poc_val); 5008 demand_empty_rest_of_line(); 5009 return; 5010 } 5011 as_bad ("Unknown segment type"); 5012 demand_empty_rest_of_line (); 5013} 5014 5015#endif /* SPARC */ 5016 5017#ifdef PPC 5018/* 5019 * 5020 */ 5021/* 5022 * s_ppcasm_end() implements the ppcasm pseudo op: 5023 * end 5024 * it is basicly ignored. 5025 */ 5026static 5027void 5028s_ppcasm_end( 5029uintptr_t value) 5030{ 5031 demand_empty_rest_of_line(); 5032} 5033#endif /* PPC */ 5034 5035/* Return the size of a LEB128 value. */ 5036 5037static inline int 5038sizeof_sleb128_32 (int32_t value) 5039{ 5040 register int size = 0; 5041 register unsigned byte; 5042 5043 do 5044 { 5045 byte = (value & 0x7f); 5046 /* Sadly, we cannot rely on typical arithmetic right shift behaviour. 5047 Fortunately, we can structure things so that the extra work reduces 5048 to a noop on systems that do things "properly". */ 5049 value = (value >> 7) | ~(-(offsetT)1 >> 7); 5050 size += 1; 5051 } 5052 while (!(((value == 0) && ((byte & 0x40) == 0)) 5053 || ((value == -1) && ((byte & 0x40) != 0)))); 5054 5055 return size; 5056} 5057 5058static inline int 5059sizeof_sleb128_64 (int64_t value) 5060{ 5061 register int size = 0; 5062 register unsigned byte; 5063 5064 do 5065 { 5066 byte = (value & 0x7f); 5067 /* Sadly, we cannot rely on typical arithmetic right shift behaviour. 5068 Fortunately, we can structure things so that the extra work reduces 5069 to a noop on systems that do things "properly". */ 5070 value = (value >> 7) | ~(-(offsetT)1 >> 7); 5071 size += 1; 5072 } 5073 while (!(((value == 0) && ((byte & 0x40) == 0)) 5074 || ((value == -1) && ((byte & 0x40) != 0)))); 5075 5076 return size; 5077} 5078 5079static inline int 5080sizeof_uleb128_32 (uint32_t value) 5081{ 5082 register int size = 0; 5083 register unsigned byte; 5084 5085 do 5086 { 5087 byte = (value & 0x7f); 5088 value >>= 7; 5089 size += 1; 5090 } 5091 while (value != 0); 5092 5093 return size; 5094} 5095 5096static inline int 5097sizeof_uleb128_64 (uint64_t value) 5098{ 5099 register int size = 0; 5100 register unsigned byte; 5101 5102 do 5103 { 5104 byte = (value & 0x7f); 5105 value >>= 7; 5106 size += 1; 5107 } 5108 while (value != 0); 5109 5110 return size; 5111} 5112 5113#ifdef ARCH64 5114int 5115sizeof_leb128 (valueT value, int sign) 5116{ 5117 if (sign) 5118 return sizeof_sleb128_64 ((offsetT) value); 5119 else 5120 return sizeof_uleb128_64 (value); 5121} 5122#else 5123int 5124sizeof_leb128 (valueT value, int sign) 5125{ 5126 if (sign) 5127 return sizeof_sleb128_32 ((offsetT) value); 5128 else 5129 return sizeof_uleb128_32 (value); 5130} 5131#endif 5132 5133/* Output a LEB128 value. */ 5134 5135static inline int 5136output_sleb128 (char *p, offsetT value) 5137{ 5138 register char *orig = p; 5139 register int more; 5140 5141 do 5142 { 5143 unsigned byte = (value & 0x7f); 5144 5145 /* Sadly, we cannot rely on typical arithmetic right shift behaviour. 5146 Fortunately, we can structure things so that the extra work reduces 5147 to a noop on systems that do things "properly". */ 5148 value = (value >> 7) | ~(-(offsetT)1 >> 7); 5149 5150 more = !((((value == 0) && ((byte & 0x40) == 0)) 5151 || ((value == -1) && ((byte & 0x40) != 0)))); 5152 if (more) 5153 byte |= 0x80; 5154 5155 *p++ = byte; 5156 } 5157 while (more); 5158 5159 return p - orig; 5160} 5161 5162static inline int 5163output_uleb128 (char *p, valueT value) 5164{ 5165 char *orig = p; 5166 5167 do 5168 { 5169 unsigned byte = (value & 0x7f); 5170 value >>= 7; 5171 if (value != 0) 5172 /* More bytes to follow. */ 5173 byte |= 0x80; 5174 5175 *p++ = byte; 5176 } 5177 while (value != 0); 5178 5179 return p - orig; 5180} 5181 5182int 5183output_leb128 (char *p, valueT value, int sign) 5184{ 5185 if (sign) 5186 return output_sleb128 (p, (offsetT) value); 5187 else 5188 return output_uleb128 (p, value); 5189} 5190