/* * fix_new() creates a fixS in obstack 'notes'. */ fixS * fix_new( fragS *frag, /* which frag? */ int where, /* where in that frag? */ int size, /* 1, 2, 4 or 8 bytes */ symbolS *add_symbol, /* X_add_symbol */ symbolS *sub_symbol, /* X_subtract_symbol */ signed_target_addr_t offset, /* X_add_number */ int pcrel, /* TRUE if PC-relative relocation */ int pcrel_reloc, /* TRUE if must have relocation entry */ int r_type) /* relocation type */ { struct fix *fixP; fixP = (struct fix *)obstack_alloc(¬es, sizeof(struct fix)); fixP->fx_frag = frag; fixP->fx_where = where; fixP->fx_size = size; fixP->fx_addsy = add_symbol; fixP->fx_subsy = sub_symbol; fixP->fx_offset = offset; fixP->fx_pcrel = pcrel; fixP->fx_pcrel_reloc = pcrel_reloc; fixP->fx_r_type = r_type; #if defined(I386) && defined(ARCH64) if(fixP->fx_r_type == X86_64_RELOC_SIGNED){ switch(offset){ case -1: fixP->fx_r_type = X86_64_RELOC_SIGNED_1; break; case -2: fixP->fx_r_type = X86_64_RELOC_SIGNED_2; break; case -4: fixP->fx_r_type = X86_64_RELOC_SIGNED_4; break; default: break; } } if(fixP->fx_r_type == X86_64_RELOC_GOT || fixP->fx_r_type == X86_64_RELOC_GOT_LOAD){ /* * GOT and GOT_LOAD relocs are always PC-relative and * should not be converted to non-PC-relative addressing * later. */ fixP->fx_pcrel = TRUE; fixP->fx_pcrel_reloc = TRUE; } /* We don't need this for non-local symbols, but it doesn't hurt. */ fixP->fx_localsy = symbol_new("L0\002", N_SECT, frchain_now->frch_nsect, 0, where, frag); symbol_assign_index(fixP->fx_localsy); #endif as_file_and_line (&fixP->file, &fixP->line); fixP->fx_next = frchain_now->frch_fix_root; frchain_now->frch_fix_root = fixP; return fixP; }
void colon( /* just seen "x:" - rattle symbols & frags */ char *sym_name) /* symbol name, as a cannonical string */ /* We copy this string: OK to alter later. */ { register struct symbol * symbolP; /* symbol we are working with */ if (frchain_now == NULL) { know(flagseen['n']); as_fatal("with -n a section directive must be seen before assembly " "can begin"); } if ((symbolP = symbol_table_lookup( sym_name ))) { /* * Now check for undefined symbols */ if ((symbolP -> sy_type & N_TYPE) == N_UNDF) { temp = symbolP->sy_desc; if( symbolP -> sy_other == 0 /* bug #50416 -O causes this not to work for: && ((symbolP->sy_desc) & (~REFERENCE_TYPE)) == 0 */ && (temp & (~(REFERENCE_TYPE | N_WEAK_REF | N_WEAK_DEF | N_ARM_THUMB_DEF | N_NO_DEAD_STRIP | REFERENCED_DYNAMICALLY))) == 0 && symbolP -> sy_value == 0) { symbolP -> sy_frag = frag_now; symbolP -> sy_value = obstack_next_free(& frags) - frag_now -> fr_literal; know( N_UNDF == 0 ); symbolP -> sy_type |= N_SECT; /* keep N_EXT bit */ symbolP -> sy_other = frchain_now->frch_nsect; symbolP -> sy_desc &= ~REFERENCE_TYPE; symbolP -> sy_desc &= ~N_WEAK_REF; symbol_assign_index(symbolP); if((symbolP->sy_desc & N_WEAK_DEF) == N_WEAK_DEF && (frchain_now->frch_section.flags & S_COALESCED) != S_COALESCED) as_fatal("symbol: %s can't be a weak_definition (currently " "only supported in section of type coalesced)", sym_name); #ifdef NeXT_MOD /* generate stabs for debugging assembly code */ if(flagseen['g']) make_stab_for_symbol(symbolP); #endif } else { as_fatal( "Symbol \"%s\" is already defined as \"%s\"/%d.%d." TA_DFMT ".", sym_name, seg_name [(int) N_TYPE_seg [symbolP -> sy_type & N_TYPE]], symbolP -> sy_other, symbolP -> sy_desc, TA_DFT_CAST(symbolP -> sy_value)); } } else { as_fatal("Symbol %s already defined.",sym_name); } } else { symbolP = symbol_new (sym_name, N_SECT, frchain_now->frch_nsect, 0, (valueT)(obstack_next_free(&frags)-frag_now->fr_literal), frag_now); symbol_table_insert (symbolP); symbol_assign_index (symbolP); #ifdef NeXT_MOD /* generate stabs for debugging assembly code */ if(flagseen['g']) make_stab_for_symbol(symbolP); #endif } #ifdef tc_frob_label tc_frob_label(symbolP); #endif }