📄 tc-i370.c
字号:
0x5C, 0x00, 0x53, 0x54, 0x55, 0x56, 0x57, 0x58, /*E8 Y Z */ 0x59, 0x5A, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /*F0 0 1 2 3 4 5 6 7 */ 0x30, 0x31, 0x32, 0x33, 0x34, 0x35, 0x36, 0x37, /*F8 8 9 */ 0x38, 0x39, 0x00, 0x00, 0x00, 0x00, 0x00, 0xFF};/* ebcdic translation tables needed for 3270 support */static voidi370_ebcdic (unused) int unused;{ char *p, *end; char delim = 0; size_t nbytes; nbytes = strlen (input_line_pointer); end = input_line_pointer + nbytes; while ('\r' == *end) end --; while ('\n' == *end) end --; delim = *input_line_pointer; if (('\'' == delim) || ('\"' == delim)) { input_line_pointer ++; end = rindex (input_line_pointer, delim); } if (end > input_line_pointer) { nbytes = end - input_line_pointer +1; p = frag_more (nbytes); while (end > input_line_pointer) { *p = ascebc [(unsigned char) (*input_line_pointer)]; ++p; ++input_line_pointer; } *p = '\0'; } if (delim == *input_line_pointer) ++input_line_pointer;}/* stub out a couple of routines */static voidi370_rmode (unused) int unused;{ as_tsktsk ("rmode ignored");}static voidi370_dsect (sect) int sect;{ char *save_line = input_line_pointer; static char section[] = ".data\n"; /* Just pretend this is .section .data */ input_line_pointer = section; obj_elf_section (sect); input_line_pointer = save_line;}static voidi370_csect (unused) int unused;{ as_tsktsk ("csect not supported");}/* DC Define Const is only partially supported. * For samplecode on what to do, look at i370_elf_cons() above. * This code handles pseudoops of the style * DC D'3.141592653' # in sysv4, .double 3.14159265 * DC F'1' # in sysv4, .long 1 */static voidi370_dc(unused) int unused;{ char * p, tmp[50]; int nbytes=0; expressionS exp; char type=0; if (is_it_end_of_statement ()) { demand_empty_rest_of_line (); return; } /* figure out the size */ type = *input_line_pointer++; switch (type) { case 'H': /* 16-bit */ nbytes = 2; break; case 'E': /* 32-bit */ case 'F': /* 32-bit */ nbytes = 4; break; case 'D': /* 64-bit */ nbytes = 8; break; default: as_bad ("unsupported DC type"); return; } /* get rid of pesky quotes */ if ('\'' == *input_line_pointer) { char * close; ++input_line_pointer; close = strchr (input_line_pointer, '\''); if (close) *close= ' '; else as_bad ("missing end-quote"); } if ('\"' == *input_line_pointer) { char * close; ++input_line_pointer; close = strchr (input_line_pointer, '\"'); if (close) *close= ' '; else as_bad ("missing end-quote"); } switch (type) { case 'H': /* 16-bit */ case 'F': /* 32-bit */ expression (&exp); emit_expr (&exp, nbytes); break; case 'E': /* 32-bit */ case 'D': /* 64-bit */ md_atof (type, tmp, &nbytes); p = frag_more (nbytes); memcpy (p, tmp, nbytes); break; default: as_bad ("unsupported DC type"); return; } demand_empty_rest_of_line ();}/* provide minimal support for DS Define Storage */static voidi370_ds (unused) int unused;{ /* DS 0H or DS 0F or DS 0D */ if ('0' == *input_line_pointer) { int alignment = 0; /* left shift 1<<align */ input_line_pointer ++; switch (*input_line_pointer++) { case 'H': /* 16-bit */ alignment = 1; break; case 'F': /* 32-bit */ alignment = 2; break; case 'D': /* 64-bit */ alignment = 3; break; default: as_bad ("unsupported alignment"); return; } frag_align (alignment, 0, 0); record_alignment (now_seg, alignment); } else { as_bad ("this DS form not yet supported"); }}/* Solaris pseudo op to change to the .rodata section. */static voidi370_elf_rdata (sect) int sect;{ char *save_line = input_line_pointer; static char section[] = ".rodata\n"; /* Just pretend this is .section .rodata */ input_line_pointer = section; obj_elf_section (sect); input_line_pointer = save_line;}/* Pseudo op to make file scope bss items */static voidi370_elf_lcomm(unused) int unused;{ register char *name; register char c; register char *p; offsetT size; register symbolS *symbolP; offsetT align; segT old_sec; int old_subsec; char *pfrag; int align2; name = input_line_pointer; c = get_symbol_end (); /* just after name is now '\0' */ p = input_line_pointer; *p = c; SKIP_WHITESPACE (); if (*input_line_pointer != ',') { as_bad ("Expected comma after symbol-name: rest of line ignored."); ignore_rest_of_line (); return; } input_line_pointer++; /* skip ',' */ if ((size = get_absolute_expression ()) < 0) { as_warn (".COMMon length (%ld.) <0! Ignored.", (long) size); ignore_rest_of_line (); return; } /* The third argument to .lcomm is the alignment. */ if (*input_line_pointer != ',') align = 8; else { ++input_line_pointer; align = get_absolute_expression (); if (align <= 0) { as_warn ("ignoring bad alignment"); align = 8; } } *p = 0; symbolP = symbol_find_or_make (name); *p = c; if (S_IS_DEFINED (symbolP) && ! S_IS_COMMON (symbolP)) { as_bad ("Ignoring attempt to re-define symbol `%s'.", S_GET_NAME (symbolP)); ignore_rest_of_line (); return; } if (S_GET_VALUE (symbolP) && S_GET_VALUE (symbolP) != (valueT) size) { as_bad ("Length of .lcomm \"%s\" is already %ld. Not changed to %ld.", S_GET_NAME (symbolP), (long) S_GET_VALUE (symbolP), (long) size); ignore_rest_of_line (); return; } /* allocate_bss: */ old_sec = now_seg; old_subsec = now_subseg; if (align) { /* convert to a power of 2 alignment */ for (align2 = 0; (align & 1) == 0; align >>= 1, ++align2) ; if (align != 1) { as_bad ("Common alignment not a power of 2"); ignore_rest_of_line (); return; } } else align2 = 0; record_alignment (bss_section, align2); subseg_set (bss_section, 0); if (align2) frag_align (align2, 0, 0); if (S_GET_SEGMENT (symbolP) == bss_section) symbol_get_frag (symbolP)->fr_symbol = 0; symbol_set_frag (symbolP, frag_now); pfrag = frag_var (rs_org, 1, 1, (relax_substateT) 0, symbolP, size, (char *) 0); *pfrag = 0; S_SET_SIZE (symbolP, size); S_SET_SEGMENT (symbolP, bss_section); subseg_set (old_sec, old_subsec); demand_empty_rest_of_line ();}/* Validate any relocations emitted for -mrelocatable, possibly adding fixups for word relocations in writable segments, so we can adjust them at runtime. */static voidi370_elf_validate_fix (fixp, seg) fixS *fixp; segT seg;{ if (fixp->fx_done || fixp->fx_pcrel) return; switch (shlib) { case SHLIB_NONE: case SHLIB_PIC: return; case SHILB_MRELOCATABLE: if (fixp->fx_r_type <= BFD_RELOC_UNUSED && fixp->fx_r_type != BFD_RELOC_16_GOTOFF && fixp->fx_r_type != BFD_RELOC_HI16_GOTOFF && fixp->fx_r_type != BFD_RELOC_LO16_GOTOFF && fixp->fx_r_type != BFD_RELOC_HI16_S_GOTOFF && fixp->fx_r_type != BFD_RELOC_32_BASEREL && fixp->fx_r_type != BFD_RELOC_LO16_BASEREL && fixp->fx_r_type != BFD_RELOC_HI16_BASEREL && fixp->fx_r_type != BFD_RELOC_HI16_S_BASEREL && strcmp (segment_name (seg), ".got2") != 0 && strcmp (segment_name (seg), ".dtors") != 0 && strcmp (segment_name (seg), ".ctors") != 0 && strcmp (segment_name (seg), ".fixup") != 0 && strcmp (segment_name (seg), ".stab") != 0 && strcmp (segment_name (seg), ".gcc_except_table") != 0 && strcmp (segment_name (seg), ".ex_shared") != 0) { if ((seg->flags & (SEC_READONLY | SEC_CODE)) != 0 || fixp->fx_r_type != BFD_RELOC_CTOR) { as_bad_where (fixp->fx_file, fixp->fx_line, "Relocation cannot be done when using -mrelocatable"); } } return; }}#endif /* OBJ_ELF */#define LITERAL_POOL_SUPPORT#ifdef LITERAL_POOL_SUPPORT/* Provide support for literal pools within the text section. *//* Loosely based on similar code from tc-arm.c *//* * We will use four symbols to locate four parts of the literal pool. * These four sections contain 64,32,16 and 8-bit constants; we use * four sections so that all memory access can be appropriately aligned. * That is, we want to avoid mixing these together so that we don't * waste space padding out to alignments. The four pointers * longlong_poolP, word_poolP, etc. point to a symbol labeling the * start of each pool part. * * lit_pool_num increments from zero to infinity and uniquely id's * -- its used to generate the *_poolP symbol name. */#define MAX_LITERAL_POOL_SIZE 1024typedef struct literalS{ struct expressionS exp; char * sym_name; char size; /* 1,2,4 or 8 */ short offset;} literalT;literalT literals[MAX_LITERAL_POOL_SIZE];int next_literal_pool_place = 0; /* Next free entry in the pool */static symbolS *longlong_poolP = NULL; /* 64-bit pool entries */static symbolS *word_poolP = NULL; /* 32-bit pool entries */static symbolS *short_poolP = NULL; /* 16-bit pool entries */static symbolS *byte_poolP = NULL; /* 8-bit pool entries */static int lit_pool_num = 1;/* create a new, empty symbol */static symbolS *symbol_make_empty (void){ return symbol_create (FAKE_LABEL_NAME, undefined_section, (valueT) 0, &zero_address_frag);}/* add an expression to the literal pool */static voidadd_to_lit_pool (expressionS *exx, char *name, int sz){ int lit_count = 0; int offset_in_pool = 0; /* start a new pool, if necessary */ if (8 == sz && NULL == longlong_poolP) longlong_poolP = symbol_make_empty(); else if (4 == sz && NULL == word_poolP) word_poolP = symbol_make_empty(); else if (2 == sz && NULL == short_poolP) short_poolP = symbol_make_empty(); else if (1 == sz && NULL == byte_poolP) byte_poolP = symbol_make_empty(); /* Check if this literal value is already in the pool: */ /* hack alert -- we should probably be checking expressions * of type O_symbol as well ... */ /* hack alert XXX this is probably(certainly?) broken for O_big, * which includes 64-bit long-longs ... */ while (lit_count < next_literal_pool_place) { if (exx->X_op == O_constant && literals[lit_count].exp.X_op == exx->X_op && literals[lit_count].exp.X_add_number == exx->X_add_number && literals[lit_count].exp.X_unsigned == exx->X_unsigned && literals[lit_count].size == sz) break; else if (literals[lit_count].sym_name && name && !strcmp (name, literals[lit_count].sym_name)) break; if (sz == literals[lit_count].size) offset_in_pool += sz; lit_count ++; } if (lit_count == next_literal_pool_place) /* new entry */ { if (next_literal_pool_place > MAX_LITERAL_POOL_SIZE) { as_bad("Literal Pool Overflow"); }
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -