static void subseg_set_rest (segT seg, subsegT subseg) { frchainS *frcP; /* crawl frchain chain */ frchainS **lastPP; /* address of last pointer */ frchainS *newP; /* address of new frchain */ segment_info_type *seginfo; mri_common_symbol = NULL; if (frag_now && frchain_now) frchain_now->frch_frag_now = frag_now; gas_assert (frchain_now == 0 || frchain_now->frch_last == frag_now); subseg_change (seg, (int) subseg); seginfo = seg_info (seg); /* Attempt to find or make a frchain for that subsection. We keep the list sorted by subsection number. */ for (frcP = *(lastPP = &seginfo->frchainP); frcP != NULL; frcP = *(lastPP = &frcP->frch_next)) if (frcP->frch_subseg >= subseg) break; if (frcP == NULL || frcP->frch_subseg != subseg) { /* This should be the only code that creates a frchainS. */ newP = (frchainS *) obstack_alloc (&frchains, sizeof (frchainS)); newP->frch_subseg = subseg; newP->fix_root = NULL; newP->fix_tail = NULL; obstack_begin (&newP->frch_obstack, chunksize); #if __GNUC__ >= 2 obstack_alignment_mask (&newP->frch_obstack) = __alignof__ (fragS) - 1; #endif newP->frch_frag_now = frag_alloc (&newP->frch_obstack); newP->frch_frag_now->fr_type = rs_fill; newP->frch_cfi_data = NULL; newP->frch_root = newP->frch_last = newP->frch_frag_now; *lastPP = newP; newP->frch_next = frcP; frcP = newP; } frchain_now = frcP; frag_now = frcP->frch_frag_now; gas_assert (frchain_now->frch_last == frag_now); }
static void emit_fixed_inc_line_addr (int line_delta, addressT addr_delta, fragS *frag, char *p, int len) { expressionS *pexp; segT line_seg; char *end = p + len; /* Line number sequences cannot go backward in addresses. This means we've incorrectly ordered the statements in the sequence. */ gas_assert ((offsetT) addr_delta >= 0); /* INT_MAX is a signal that this is actually a DW_LNE_end_sequence. */ if (line_delta != INT_MAX) { *p++ = DW_LNS_advance_line; p += output_leb128 (p, line_delta, 1); } pexp = symbol_get_value_expression (frag->fr_symbol); line_seg = subseg_get (".debug_line", 0); /* The DW_LNS_fixed_advance_pc opcode has a 2-byte operand so it can advance the address by at most 64K. Linker relaxation (without which this function would not be used) could change the operand by an unknown amount. If the address increment is getting close to the limit, just reset the address. */ if (addr_delta > 50000) { symbolS *to_sym; expressionS exp; gas_assert (pexp->X_op == O_subtract); to_sym = pexp->X_add_symbol; *p++ = DW_LNS_extended_op; p += output_leb128 (p, sizeof_address + 1, 0); *p++ = DW_LNE_set_address; exp.X_op = O_symbol; exp.X_add_symbol = to_sym; exp.X_add_number = 0; subseg_change (line_seg, 0); emit_expr_fix (&exp, sizeof_address, frag, p); p += sizeof_address; } else { *p++ = DW_LNS_fixed_advance_pc; subseg_change (line_seg, 0); emit_expr_fix (pexp, 2, frag, p); p += 2; } if (line_delta == INT_MAX) { *p++ = DW_LNS_extended_op; *p++ = 1; *p++ = DW_LNE_end_sequence; } else *p++ = DW_LNS_copy; gas_assert (p == end); }