/* Similar to dwarf_add_fde_inst, except that the offset denoted by VAL2 is signed. */ Dwarf_P_Fde dwarf_add_fde_inst_with_signed_offset(Dwarf_P_Fde fde, Dwarf_Small op, Dwarf_Unsigned val1, Dwarf_Signed val2, Dwarf_Error * error) { Dwarf_P_Frame_Pgm curinst; int nbytes, nbytes1, nbytes2; char *ptr; int res; char buff1[ENCODE_SPACE_NEEDED]; char buff2[ENCODE_SPACE_NEEDED]; nbytes = 0; ptr = NULL; curinst = (Dwarf_P_Frame_Pgm) _dwarf_p_get_alloc(NULL, sizeof(struct Dwarf_P_Frame_Pgm_s)); if (curinst == NULL) { _dwarf_p_error(NULL, error, DW_DLE_FPGM_ALLOC); return ((Dwarf_P_Fde) DW_DLV_BADADDR); } if (op == DW_CFA_offset_extended_sf) { res = _dwarf_pro_encode_leb128_nm(val1, &nbytes1, buff1, sizeof(buff1)); if (res != DW_DLV_OK) { _dwarf_p_error(NULL, error, DW_DLE_STRING_ALLOC); return ((Dwarf_P_Fde) DW_DLV_BADADDR); } res = _dwarf_pro_encode_signed_leb128_nm(val2, &nbytes2, buff2, sizeof(buff2)); if (res != DW_DLV_OK) { _dwarf_p_error(NULL, error, DW_DLE_STRING_ALLOC); return ((Dwarf_P_Fde) DW_DLV_BADADDR); } ptr = (char *) _dwarf_p_get_alloc(NULL, nbytes1 + nbytes2); if (ptr == NULL) { _dwarf_p_error(NULL, error, DW_DLE_STRING_ALLOC); return ((Dwarf_P_Fde) DW_DLV_BADADDR); } memcpy(ptr, buff1, nbytes1); memcpy(ptr + nbytes1, buff2, nbytes2); nbytes = nbytes1 + nbytes2; } curinst->dfp_opcode = op; curinst->dfp_args = ptr; curinst->dfp_nbytes = nbytes; curinst->dfp_next = NULL; _dwarf_pro_add_to_fde(fde, curinst); return fde; }
/* Add a cfe_offset instruction to the fde passed in. */ Dwarf_P_Fde dwarf_fde_cfa_offset(Dwarf_P_Fde fde, Dwarf_Unsigned reg, Dwarf_Signed offset, Dwarf_Error * error) { Dwarf_Ubyte opc, regno; char *ptr = 0; Dwarf_P_Frame_Pgm curinst; int nbytes = 0; int res = 0; char buff1[ENCODE_SPACE_NEEDED]; Dwarf_P_Debug dbg = fde->fde_dbg; curinst = (Dwarf_P_Frame_Pgm) _dwarf_p_get_alloc(dbg, sizeof(struct Dwarf_P_Frame_Pgm_s)); if (curinst == NULL) { DWARF_P_DBG_ERROR(dbg, DW_DLE_FPGM_ALLOC, (Dwarf_P_Fde) DW_DLV_BADADDR); } opc = DW_CFA_offset; regno = reg; if (regno & 0xc0) { DWARF_P_DBG_ERROR(dbg, DW_DLE_REGNO_OVFL, (Dwarf_P_Fde) DW_DLV_BADADDR); } opc = opc | regno; /* lower 6 bits are register number */ curinst->dfp_opcode = opc; res = _dwarf_pro_encode_leb128_nm(offset, &nbytes, buff1, sizeof(buff1)); if (res != DW_DLV_OK) { _dwarf_p_error(dbg, error, DW_DLE_STRING_ALLOC); return ((Dwarf_P_Fde) DW_DLV_BADADDR); } ptr = (char *) _dwarf_p_get_alloc(dbg, nbytes); if (ptr == NULL) { _dwarf_p_error(dbg, error, DW_DLE_STRING_ALLOC); return ((Dwarf_P_Fde) DW_DLV_BADADDR); } memcpy(ptr, buff1, nbytes); curinst->dfp_args = ptr; curinst->dfp_nbytes = nbytes; curinst->dfp_next = NULL; _dwarf_pro_add_to_fde(fde, curinst); return fde; }
/* Generic routine to add opcode to fde instructions. val1 and val2 are parameters whose interpretation depends on the 'op'. This does not work properly for DW_DLC_SYMBOLIC_RELOCATIONS for DW_CFA_set_loc or DW_DVA_advance_loc* 'op', as these ops normally are addresses or (DW_CFA_set_loc) or code lengths (DW_DVA_advance_loc*) and such must be represented with relocations and symbol indices for DW_DLC_SYMBOLIC_RELOCATIONS. */ Dwarf_P_Fde dwarf_add_fde_inst(Dwarf_P_Fde fde, Dwarf_Small op, Dwarf_Unsigned val1, Dwarf_Unsigned val2, Dwarf_Error * error) { Dwarf_P_Frame_Pgm curinst; int nbytes, nbytes1, nbytes2; Dwarf_Ubyte db; Dwarf_Half dh; Dwarf_Word dw; Dwarf_Unsigned du; char *ptr; int res; char buff1[ENCODE_SPACE_NEEDED]; char buff2[ENCODE_SPACE_NEEDED]; nbytes = 0; ptr = NULL; curinst = (Dwarf_P_Frame_Pgm) _dwarf_p_get_alloc(NULL, sizeof(struct Dwarf_P_Frame_Pgm_s)); if (curinst == NULL) { _dwarf_p_error(NULL, error, DW_DLE_FPGM_ALLOC); return ((Dwarf_P_Fde) DW_DLV_BADADDR); } switch (op) { #ifdef TARG_X8664 case DW_CFA_advance_loc4: // We will use 2 half-words to copy the labels; cg will later // fix the relocatable symbols. dh = val1; ptr = (char *) _dwarf_p_get_alloc(NULL, 4); if (ptr == NULL) { _dwarf_p_error(NULL, error, DW_DLE_STRING_ALLOC); return((Dwarf_P_Fde)DW_DLV_BADADDR); } memcpy((void *)ptr, (const void *)&dh,2); dh = val2; memcpy((void *)ptr+2, (const void *)&dh,2); nbytes = 4; break; #endif // TARG_X8664 case DW_CFA_advance_loc: if (val1 <= 0x3f) { db = val1; op |= db; } /* test not portable FIX */ else if (val1 <= UCHAR_MAX) { op = DW_CFA_advance_loc1; db = val1; ptr = (char *) _dwarf_p_get_alloc(NULL, 1); if (ptr == NULL) { _dwarf_p_error(NULL, error, DW_DLE_STRING_ALLOC); return ((Dwarf_P_Fde) DW_DLV_BADADDR); } memcpy((void *) ptr, (const void *) &db, 1); nbytes = 1; } /* test not portable FIX */ else if (val1 <= USHRT_MAX) { op = DW_CFA_advance_loc2; dh = val1; ptr = (char *) _dwarf_p_get_alloc(NULL, 2); if (ptr == NULL) { _dwarf_p_error(NULL, error, DW_DLE_STRING_ALLOC); return ((Dwarf_P_Fde) DW_DLV_BADADDR); } memcpy((void *) ptr, (const void *) &dh, 2); nbytes = 2; } /* test not portable FIX */ else if (val1 <= ULONG_MAX) { op = DW_CFA_advance_loc4; dw = (Dwarf_Word) val1; ptr = (char *) _dwarf_p_get_alloc(NULL, 4); if (ptr == NULL) { _dwarf_p_error(NULL, error, DW_DLE_STRING_ALLOC); return ((Dwarf_P_Fde) DW_DLV_BADADDR); } memcpy((void *) ptr, (const void *) &dw, 4); nbytes = 4; } else { op = DW_CFA_MIPS_advance_loc8; du = val1; ptr = (char *) _dwarf_p_get_alloc(NULL, sizeof(Dwarf_Unsigned)); if (ptr == NULL) { _dwarf_p_error(NULL, error, DW_DLE_STRING_ALLOC); return ((Dwarf_P_Fde) DW_DLV_BADADDR); } memcpy((void *) ptr, (const void *) &du, 8); nbytes = 8; } break; case DW_CFA_offset: if (val1 <= MAX_6_BIT_VALUE) { db = val1; op |= db; res = _dwarf_pro_encode_leb128_nm(val2, &nbytes, buff1, sizeof(buff1)); if (res != DW_DLV_OK) { _dwarf_p_error(NULL, error, DW_DLE_STRING_ALLOC); return ((Dwarf_P_Fde) DW_DLV_BADADDR); } ptr = (char *) _dwarf_p_get_alloc(NULL, nbytes); if (ptr == NULL) { _dwarf_p_error(NULL, error, DW_DLE_STRING_ALLOC); return ((Dwarf_P_Fde) DW_DLV_BADADDR); } memcpy(ptr, buff1, nbytes); } else { op = DW_CFA_offset_extended; res = _dwarf_pro_encode_leb128_nm(val1, &nbytes1, buff1, sizeof(buff1)); if (res != DW_DLV_OK) { _dwarf_p_error(NULL, error, DW_DLE_STRING_ALLOC); return ((Dwarf_P_Fde) DW_DLV_BADADDR); } res = _dwarf_pro_encode_leb128_nm(val2, &nbytes2, buff2, sizeof(buff2)); if (res != DW_DLV_OK) { _dwarf_p_error(NULL, error, DW_DLE_STRING_ALLOC); return ((Dwarf_P_Fde) DW_DLV_BADADDR); } ptr = (char *) _dwarf_p_get_alloc(NULL, nbytes1 + nbytes2); if (ptr == NULL) { _dwarf_p_error(NULL, error, DW_DLE_STRING_ALLOC); return ((Dwarf_P_Fde) DW_DLV_BADADDR); } memcpy(ptr, buff1, nbytes1); memcpy(ptr + nbytes1, buff2, nbytes2); nbytes = nbytes1 + nbytes2; } break; case DW_CFA_undefined: case DW_CFA_same_value: res = _dwarf_pro_encode_leb128_nm(val1, &nbytes, buff1, sizeof(buff1)); if (res != DW_DLV_OK) { _dwarf_p_error(NULL, error, DW_DLE_STRING_ALLOC); return ((Dwarf_P_Fde) DW_DLV_BADADDR); } ptr = (char *) _dwarf_p_get_alloc(NULL, nbytes); if (ptr == NULL) { _dwarf_p_error(NULL, error, DW_DLE_STRING_ALLOC); return ((Dwarf_P_Fde) DW_DLV_BADADDR); } memcpy(ptr, buff1, nbytes); break; case DW_CFA_register: case DW_CFA_def_cfa: res = _dwarf_pro_encode_leb128_nm(val1, &nbytes1, buff1, sizeof(buff1)); if (res != DW_DLV_OK) { _dwarf_p_error(NULL, error, DW_DLE_STRING_ALLOC); return ((Dwarf_P_Fde) DW_DLV_BADADDR); } res = _dwarf_pro_encode_leb128_nm(val2, &nbytes2, buff2, sizeof(buff2)); if (res != DW_DLV_OK) { _dwarf_p_error(NULL, error, DW_DLE_STRING_ALLOC); return ((Dwarf_P_Fde) DW_DLV_BADADDR); } ptr = (char *) _dwarf_p_get_alloc(NULL, nbytes1 + nbytes2); if (ptr == NULL) { _dwarf_p_error(NULL, error, DW_DLE_STRING_ALLOC); return ((Dwarf_P_Fde) DW_DLV_BADADDR); } memcpy(ptr, buff1, nbytes1); memcpy(ptr + nbytes1, buff2, nbytes2); nbytes = nbytes1 + nbytes2; break; case DW_CFA_def_cfa_register: case DW_CFA_def_cfa_offset: res = _dwarf_pro_encode_leb128_nm(val1, &nbytes, buff1, sizeof(buff1)); if (res != DW_DLV_OK) { _dwarf_p_error(NULL, error, DW_DLE_STRING_ALLOC); return ((Dwarf_P_Fde) DW_DLV_BADADDR); } ptr = (char *) _dwarf_p_get_alloc(NULL, nbytes); if (ptr == NULL) { _dwarf_p_error(NULL, error, DW_DLE_STRING_ALLOC); return ((Dwarf_P_Fde) DW_DLV_BADADDR); } memcpy(ptr, buff1, nbytes); break; default: break; } curinst->dfp_opcode = op; curinst->dfp_args = ptr; curinst->dfp_nbytes = nbytes; curinst->dfp_next = NULL; _dwarf_pro_add_to_fde(fde, curinst); return fde; }
/* Generic routine to add opcode to fde instructions. val1 and val2 are parameters whose interpretation depends on the 'op'. This does not work properly for DW_DLC_SYMBOLIC_RELOCATIONS for DW_CFA_set_loc or DW_DVA_advance_loc* 'op', as these ops normally are addresses or (DW_CFA_set_loc) or code lengths (DW_DVA_advance_loc*) and such must be represented with relocations and symbol indices for DW_DLC_SYMBOLIC_RELOCATIONS. This does not treat all DW_CFA instructions yet. For certain operations a val? value must be signed (though passed in as unsigned here). Currently this does not check that the frame version is 3(for dwarf3) or 4 (for dwarf4) when applying operations that are only valid for dwarf3 or dwarf4. */ Dwarf_P_Fde dwarf_add_fde_inst(Dwarf_P_Fde fde, Dwarf_Small op, Dwarf_Unsigned val1, Dwarf_Unsigned val2, Dwarf_Error * error) { Dwarf_P_Frame_Pgm curinst; int nbytes, nbytes1, nbytes2; Dwarf_Ubyte db; Dwarf_Half dh; Dwarf_Word dw; Dwarf_Unsigned du; char *ptr; int res; char buff1[ENCODE_SPACE_NEEDED]; char buff2[ENCODE_SPACE_NEEDED]; Dwarf_P_Debug dbg = fde->fde_dbg; /* This is a hack telling the code when to transform a value to a signed leb number. */ int signed_second = 0; int signed_first = 0; nbytes = 0; ptr = NULL; curinst = (Dwarf_P_Frame_Pgm) _dwarf_p_get_alloc(dbg, sizeof(struct Dwarf_P_Frame_Pgm_s)); if (curinst == NULL) { _dwarf_p_error(dbg, error, DW_DLE_FPGM_ALLOC); return ((Dwarf_P_Fde) DW_DLV_BADADDR); } switch (op) { case DW_CFA_advance_loc: if (val1 <= 0x3f) { db = val1; op |= db; } /* test not portable FIX */ else if (val1 <= UCHAR_MAX) { op = DW_CFA_advance_loc1; db = val1; ptr = (char *) _dwarf_p_get_alloc(dbg, 1); if (ptr == NULL) { _dwarf_p_error(dbg, error, DW_DLE_STRING_ALLOC); return ((Dwarf_P_Fde) DW_DLV_BADADDR); } memcpy((void *) ptr, (const void *) &db, 1); nbytes = 1; } /* test not portable FIX */ else if (val1 <= USHRT_MAX) { op = DW_CFA_advance_loc2; dh = val1; ptr = (char *) _dwarf_p_get_alloc(dbg, 2); if (ptr == NULL) { _dwarf_p_error(dbg, error, DW_DLE_STRING_ALLOC); return ((Dwarf_P_Fde) DW_DLV_BADADDR); } memcpy((void *) ptr, (const void *) &dh, 2); nbytes = 2; } /* test not portable FIX */ else if (val1 <= ULONG_MAX) { op = DW_CFA_advance_loc4; dw = (Dwarf_Word) val1; ptr = (char *) _dwarf_p_get_alloc(dbg, 4); if (ptr == NULL) { _dwarf_p_error(dbg, error, DW_DLE_STRING_ALLOC); return ((Dwarf_P_Fde) DW_DLV_BADADDR); } memcpy((void *) ptr, (const void *) &dw, 4); nbytes = 4; } else { op = DW_CFA_MIPS_advance_loc8; du = val1; ptr = (char *) _dwarf_p_get_alloc(dbg, sizeof(Dwarf_Unsigned)); if (ptr == NULL) { _dwarf_p_error(dbg, error, DW_DLE_STRING_ALLOC); return ((Dwarf_P_Fde) DW_DLV_BADADDR); } memcpy((void *) ptr, (const void *) &du, 8); nbytes = 8; } break; case DW_CFA_offset: if (val1 <= MAX_6_BIT_VALUE) { db = val1; op |= db; res = _dwarf_pro_encode_leb128_nm(val2, &nbytes, buff1, sizeof(buff1)); if (res != DW_DLV_OK) { _dwarf_p_error(dbg, error, DW_DLE_STRING_ALLOC); return ((Dwarf_P_Fde) DW_DLV_BADADDR); } ptr = (char *) _dwarf_p_get_alloc(dbg, nbytes); if (ptr == NULL) { _dwarf_p_error(dbg, error, DW_DLE_STRING_ALLOC); return ((Dwarf_P_Fde) DW_DLV_BADADDR); } memcpy(ptr, buff1, nbytes); } else { op = DW_CFA_offset_extended; goto two_leb; } break; case DW_CFA_offset_extended_sf: /* DWARF3 */ signed_second = 1; goto two_leb; case DW_CFA_offset_extended: goto two_leb; case DW_CFA_undefined: case DW_CFA_same_value: goto one_leb; case DW_CFA_val_offset: goto two_leb; case DW_CFA_val_offset_sf: signed_second = 1; goto two_leb; case DW_CFA_def_cfa_sf: signed_second = 1; goto two_leb; case DW_CFA_register: case DW_CFA_def_cfa: two_leb: res = _dwarf_pro_encode_leb128_nm(val1, &nbytes1, buff1, sizeof(buff1)); if (res != DW_DLV_OK) { _dwarf_p_error(dbg, error, DW_DLE_STRING_ALLOC); return ((Dwarf_P_Fde) DW_DLV_BADADDR); } if (!signed_second) { res = _dwarf_pro_encode_leb128_nm(val2, &nbytes2, buff2, sizeof(buff2)); } else { Dwarf_Signed val2s = val2; res = _dwarf_pro_encode_signed_leb128_nm(val2s, &nbytes2, buff2, sizeof(buff2)); } res = _dwarf_pro_encode_leb128_nm(val2, &nbytes2, buff2, sizeof(buff2)); if (res != DW_DLV_OK) { _dwarf_p_error(dbg, error, DW_DLE_STRING_ALLOC); return ((Dwarf_P_Fde) DW_DLV_BADADDR); } ptr = (char *) _dwarf_p_get_alloc(dbg, nbytes1 + nbytes2); if (ptr == NULL) { _dwarf_p_error(dbg, error, DW_DLE_STRING_ALLOC); return ((Dwarf_P_Fde) DW_DLV_BADADDR); } memcpy(ptr, buff1, nbytes1); memcpy(ptr + nbytes1, buff2, nbytes2); nbytes = nbytes1 + nbytes2; break; case DW_CFA_def_cfa_offset_sf: /* DWARF3 */ signed_first = 1; goto one_leb; case DW_CFA_def_cfa_register: case DW_CFA_def_cfa_offset: one_leb: if (!signed_first) { res = _dwarf_pro_encode_leb128_nm(val1, &nbytes, buff1, sizeof(buff1)); } else { Dwarf_Signed val1s = val1; res = _dwarf_pro_encode_signed_leb128_nm(val1s, &nbytes, buff1, sizeof(buff1)); } if (res != DW_DLV_OK) { _dwarf_p_error(dbg, error, DW_DLE_STRING_ALLOC); return ((Dwarf_P_Fde) DW_DLV_BADADDR); } ptr = (char *) _dwarf_p_get_alloc(dbg, nbytes); if (ptr == NULL) { _dwarf_p_error(dbg, error, DW_DLE_STRING_ALLOC); return ((Dwarf_P_Fde) DW_DLV_BADADDR); } memcpy(ptr, buff1, nbytes); break; case DW_CFA_def_cfa_expression: /* DWARF3 */ /* FIXME: argument is dwarf expr, not handled yet. */ case DW_CFA_expression: /* DWARF3 */ /* First arg: ULEB reg num. 2nd arg dwarf expr in form block. FIXME: not handled yet. */ case DW_CFA_val_expression: /* DWARF3f */ /* First arg: ULEB reg num. 2nd arg dwarf expr in form block. FIXME: not handled yet. */ default: _dwarf_p_error(dbg, error, DW_DLE_DEBUGFRAME_ERROR); return ((Dwarf_P_Fde) DW_DLV_BADADDR); } curinst->dfp_opcode = op; curinst->dfp_args = ptr; curinst->dfp_nbytes = nbytes; curinst->dfp_next = NULL; _dwarf_pro_add_to_fde(fde, curinst); return fde; }
/* Generic routine to add opcode to fde instructions. val1 and val2 are parameters whose interpretation depends on the 'op'. This does not work properly for DW_DLC_SYMBOLIC_RELOCATIONS for DW_CFA_set_loc or DW_DVA_advance_loc* 'op', as these ops normally are addresses or (DW_CFA_set_loc) or code lengths (DW_DVA_advance_loc*) and such must be represented with relocations and symbol indices for DW_DLC_SYMBOLIC_RELOCATIONS. */ Dwarf_P_Fde dwarf_add_fde_inst(Dwarf_P_Fde fde, Dwarf_Small op, Dwarf_Unsigned val1, Dwarf_Unsigned val2, Dwarf_Error * error) { Dwarf_P_Frame_Pgm curinst; int nbytes, nbytes1, nbytes2; Dwarf_Ubyte db; Dwarf_Half dh; Dwarf_Word dw; Dwarf_Unsigned du; char *ptr; int res; char buff1[ENCODE_SPACE_NEEDED]; char buff2[ENCODE_SPACE_NEEDED]; nbytes = 0; ptr = NULL; curinst = (Dwarf_P_Frame_Pgm) _dwarf_p_get_alloc(NULL, sizeof(struct Dwarf_P_Frame_Pgm_s)); if (curinst == NULL) { _dwarf_p_error(NULL, error, DW_DLE_FPGM_ALLOC); return ((Dwarf_P_Fde) DW_DLV_BADADDR); } switch (op) { #if defined TARG_X8664 // This does not seem specific to x8664, but I will leave it for now. // The previous code here apparently assumed the labels for this "op" // need to be encoded in 4 bytes --- that is not the case. This "op" // limits to 4 bytes whatever follows it. And whatever follows it is // the subtraction between the 2 labels, i.e., each label may need // more number of bytes. // Use Dwarf_Unsigned for each label (bugs 4071, 4490, 9729), also // affects code in pro_section.c and dwf_section.c. case DW_CFA_advance_loc4: du = val1; ptr = (char *) _dwarf_p_get_alloc(NULL, 2 * sizeof(Dwarf_Unsigned)); if (ptr == NULL) { _dwarf_p_error(NULL, error, DW_DLE_STRING_ALLOC); return((Dwarf_P_Fde)DW_DLV_BADADDR); } memcpy((void *)ptr, (const void *)&du, sizeof(Dwarf_Unsigned)); du = val2; memcpy((void *)ptr + sizeof(Dwarf_Unsigned), (const void *)&du, sizeof(Dwarf_Unsigned)); nbytes = 4; break; #endif // TARG_X8664 case DW_CFA_advance_loc: if (val1 <= 0x3f) { db = val1; op |= db; } /* test not portable FIX */ else if (val1 <= UCHAR_MAX) { op = DW_CFA_advance_loc1; db = val1; ptr = (char *) _dwarf_p_get_alloc(NULL, 1); if (ptr == NULL) { _dwarf_p_error(NULL, error, DW_DLE_STRING_ALLOC); return ((Dwarf_P_Fde) DW_DLV_BADADDR); } memcpy((void *) ptr, (const void *) &db, 1); nbytes = 1; } /* test not portable FIX */ else if (val1 <= USHRT_MAX) { op = DW_CFA_advance_loc2; dh = val1; ptr = (char *) _dwarf_p_get_alloc(NULL, 2); if (ptr == NULL) { _dwarf_p_error(NULL, error, DW_DLE_STRING_ALLOC); return ((Dwarf_P_Fde) DW_DLV_BADADDR); } memcpy((void *) ptr, (const void *) &dh, 2); nbytes = 2; } /* test not portable FIX */ else if (val1 <= ULONG_MAX) { op = DW_CFA_advance_loc4; dw = (Dwarf_Word) val1; ptr = (char *) _dwarf_p_get_alloc(NULL, 4); if (ptr == NULL) { _dwarf_p_error(NULL, error, DW_DLE_STRING_ALLOC); return ((Dwarf_P_Fde) DW_DLV_BADADDR); } memcpy((void *) ptr, (const void *) &dw, 4); nbytes = 4; } else { op = DW_CFA_MIPS_advance_loc8; du = val1; ptr = (char *) _dwarf_p_get_alloc(NULL, sizeof(Dwarf_Unsigned)); if (ptr == NULL) { _dwarf_p_error(NULL, error, DW_DLE_STRING_ALLOC); return ((Dwarf_P_Fde) DW_DLV_BADADDR); } memcpy((void *) ptr, (const void *) &du, 8); nbytes = 8; } break; case DW_CFA_offset: if (val1 <= MAX_6_BIT_VALUE) { db = val1; op |= db; res = _dwarf_pro_encode_leb128_nm(val2, &nbytes, buff1, sizeof(buff1)); if (res != DW_DLV_OK) { _dwarf_p_error(NULL, error, DW_DLE_STRING_ALLOC); return ((Dwarf_P_Fde) DW_DLV_BADADDR); } ptr = (char *) _dwarf_p_get_alloc(NULL, nbytes); if (ptr == NULL) { _dwarf_p_error(NULL, error, DW_DLE_STRING_ALLOC); return ((Dwarf_P_Fde) DW_DLV_BADADDR); } memcpy(ptr, buff1, nbytes); } else { op = DW_CFA_offset_extended; res = _dwarf_pro_encode_leb128_nm(val1, &nbytes1, buff1, sizeof(buff1)); if (res != DW_DLV_OK) { _dwarf_p_error(NULL, error, DW_DLE_STRING_ALLOC); return ((Dwarf_P_Fde) DW_DLV_BADADDR); } res = _dwarf_pro_encode_leb128_nm(val2, &nbytes2, buff2, sizeof(buff2)); if (res != DW_DLV_OK) { _dwarf_p_error(NULL, error, DW_DLE_STRING_ALLOC); return ((Dwarf_P_Fde) DW_DLV_BADADDR); } ptr = (char *) _dwarf_p_get_alloc(NULL, nbytes1 + nbytes2); if (ptr == NULL) { _dwarf_p_error(NULL, error, DW_DLE_STRING_ALLOC); return ((Dwarf_P_Fde) DW_DLV_BADADDR); } memcpy(ptr, buff1, nbytes1); memcpy(ptr + nbytes1, buff2, nbytes2); nbytes = nbytes1 + nbytes2; } break; case DW_CFA_undefined: case DW_CFA_same_value: res = _dwarf_pro_encode_leb128_nm(val1, &nbytes, buff1, sizeof(buff1)); if (res != DW_DLV_OK) { _dwarf_p_error(NULL, error, DW_DLE_STRING_ALLOC); return ((Dwarf_P_Fde) DW_DLV_BADADDR); } ptr = (char *) _dwarf_p_get_alloc(NULL, nbytes); if (ptr == NULL) { _dwarf_p_error(NULL, error, DW_DLE_STRING_ALLOC); return ((Dwarf_P_Fde) DW_DLV_BADADDR); } memcpy(ptr, buff1, nbytes); break; case DW_CFA_register: case DW_CFA_def_cfa: res = _dwarf_pro_encode_leb128_nm(val1, &nbytes1, buff1, sizeof(buff1)); if (res != DW_DLV_OK) { _dwarf_p_error(NULL, error, DW_DLE_STRING_ALLOC); return ((Dwarf_P_Fde) DW_DLV_BADADDR); } res = _dwarf_pro_encode_leb128_nm(val2, &nbytes2, buff2, sizeof(buff2)); if (res != DW_DLV_OK) { _dwarf_p_error(NULL, error, DW_DLE_STRING_ALLOC); return ((Dwarf_P_Fde) DW_DLV_BADADDR); } ptr = (char *) _dwarf_p_get_alloc(NULL, nbytes1 + nbytes2); if (ptr == NULL) { _dwarf_p_error(NULL, error, DW_DLE_STRING_ALLOC); return ((Dwarf_P_Fde) DW_DLV_BADADDR); } memcpy(ptr, buff1, nbytes1); memcpy(ptr + nbytes1, buff2, nbytes2); nbytes = nbytes1 + nbytes2; break; case DW_CFA_def_cfa_register: case DW_CFA_def_cfa_offset: res = _dwarf_pro_encode_leb128_nm(val1, &nbytes, buff1, sizeof(buff1)); if (res != DW_DLV_OK) { _dwarf_p_error(NULL, error, DW_DLE_STRING_ALLOC); return ((Dwarf_P_Fde) DW_DLV_BADADDR); } ptr = (char *) _dwarf_p_get_alloc(NULL, nbytes); if (ptr == NULL) { _dwarf_p_error(NULL, error, DW_DLE_STRING_ALLOC); return ((Dwarf_P_Fde) DW_DLV_BADADDR); } memcpy(ptr, buff1, nbytes); break; #ifdef TARG_SL case DW_CFA_SL_gpr_reginfo: case DW_CFA_SL_cr_reginfo: case DW_CFA_SL_sr_reginfo: nbytes = 4; res = _dwarf_pro_encode_leb128_nm(val1, &nbytes, buff1, sizeof(buff1)); if (res != DW_DLV_OK) { _dwarf_p_error(NULL, error, DW_DLE_STRING_ALLOC); return ((Dwarf_P_Fde) DW_DLV_BADADDR); } ptr = (char *) _dwarf_p_get_alloc(NULL, nbytes); if (ptr == NULL) { _dwarf_p_error(NULL, error, DW_DLE_STRING_ALLOC); return ((Dwarf_P_Fde) DW_DLV_BADADDR); } memcpy(ptr, buff1, nbytes); break; #endif default: break; } curinst->dfp_opcode = op; curinst->dfp_args = ptr; curinst->dfp_nbytes = nbytes; curinst->dfp_next = NULL; _dwarf_pro_add_to_fde(fde, curinst); return fde; }