diff options
Diffstat (limited to 'usr/src/tools/ctf/dwarf/common/pro_frame.c')
| -rw-r--r-- | usr/src/tools/ctf/dwarf/common/pro_frame.c | 660 |
1 files changed, 353 insertions, 307 deletions
diff --git a/usr/src/tools/ctf/dwarf/common/pro_frame.c b/usr/src/tools/ctf/dwarf/common/pro_frame.c index e23dce4598..bd1ef6a637 100644 --- a/usr/src/tools/ctf/dwarf/common/pro_frame.c +++ b/usr/src/tools/ctf/dwarf/common/pro_frame.c @@ -1,6 +1,6 @@ /* - Copyright (C) 2000 Silicon Graphics, Inc. All Rights Reserved. + Copyright (C) 2000,2004 Silicon Graphics, Inc. All Rights Reserved. This program is free software; you can redistribute it and/or modify it under the terms of version 2.1 of the GNU Lesser General Public License @@ -19,10 +19,10 @@ You should have received a copy of the GNU Lesser General Public License along with this program; if not, write the Free Software - Foundation, Inc., 59 Temple Place - Suite 330, Boston MA 02111-1307, + Foundation, Inc., 51 Franklin Street - Fifth Floor, Boston MA 02110-1301, USA. - Contact information: Silicon Graphics, Inc., 1600 Amphitheatre Pky, + Contact information: Silicon Graphics, Inc., 1500 Crittenden Lane, Mountain View, CA 94043, or: http://www.sgi.com @@ -44,47 +44,47 @@ #include "pro_frame.h" static void _dwarf_pro_add_to_fde(Dwarf_P_Fde fde, - Dwarf_P_Frame_Pgm inst); + Dwarf_P_Frame_Pgm inst); /*------------------------------------------------------------------------- - This functions adds a cie struct to the debug pointer. Its in the - form of a linked list. - augmenter: string reps augmentation (implementation defined) - code_align: alignment of code - data_align: alignment of data - init_bytes: byts having initial instructions - init_n_bytes: number of bytes of initial instructions + This function adds a cie struct to the debug pointer. Its in the + form of a linked list. + augmenter: string reps augmentation (implementation defined) + code_align: alignment of code + data_align: alignment of data + init_bytes: byts having initial instructions + init_n_bytes: number of bytes of initial instructions --------------------------------------------------------------------------*/ Dwarf_Unsigned dwarf_add_frame_cie(Dwarf_P_Debug dbg, - char *augmenter, - Dwarf_Small code_align, - Dwarf_Small data_align, - Dwarf_Small return_reg, - Dwarf_Ptr init_bytes, - Dwarf_Unsigned init_n_bytes, Dwarf_Error * error) + char *augmenter, + Dwarf_Small code_align, + Dwarf_Small data_align, + Dwarf_Small return_reg, + Dwarf_Ptr init_bytes, + Dwarf_Unsigned init_n_bytes, Dwarf_Error * error) { Dwarf_P_Cie curcie; if (dbg->de_frame_cies == NULL) { - dbg->de_frame_cies = (Dwarf_P_Cie) - _dwarf_p_get_alloc(dbg, sizeof(struct Dwarf_P_Cie_s)); - if (dbg->de_frame_cies == NULL) { - DWARF_P_DBG_ERROR(dbg, DW_DLE_CIE_ALLOC, DW_DLV_NOCOUNT); - } - curcie = dbg->de_frame_cies; - dbg->de_n_cie = 1; - dbg->de_last_cie = curcie; + dbg->de_frame_cies = (Dwarf_P_Cie) + _dwarf_p_get_alloc(dbg, sizeof(struct Dwarf_P_Cie_s)); + if (dbg->de_frame_cies == NULL) { + DWARF_P_DBG_ERROR(dbg, DW_DLE_CIE_ALLOC, DW_DLV_NOCOUNT); + } + curcie = dbg->de_frame_cies; + dbg->de_n_cie = 1; + dbg->de_last_cie = curcie; } else { - curcie = dbg->de_last_cie; - curcie->cie_next = (Dwarf_P_Cie) - _dwarf_p_get_alloc(dbg, sizeof(struct Dwarf_P_Cie_s)); - if (curcie->cie_next == NULL) { - DWARF_P_DBG_ERROR(dbg, DW_DLE_CIE_ALLOC, DW_DLV_NOCOUNT); - } - curcie = curcie->cie_next; - dbg->de_n_cie++; - dbg->de_last_cie = curcie; + curcie = dbg->de_last_cie; + curcie->cie_next = (Dwarf_P_Cie) + _dwarf_p_get_alloc(dbg, sizeof(struct Dwarf_P_Cie_s)); + if (curcie->cie_next == NULL) { + DWARF_P_DBG_ERROR(dbg, DW_DLE_CIE_ALLOC, DW_DLV_NOCOUNT); + } + curcie = curcie->cie_next; + dbg->de_n_cie++; + dbg->de_last_cie = curcie; } curcie->cie_version = DW_CIE_VERSION; curcie->cie_aug = augmenter; @@ -99,40 +99,40 @@ dwarf_add_frame_cie(Dwarf_P_Debug dbg, /*------------------------------------------------------------------------- - This functions adds a fde struct to the debug pointer. Its in the - form of a linked list. - die: subprogram/function die corresponding to this fde - cie: cie referred to by this fde, obtained from call to - add_frame_cie() routine. - virt_addr: beginning address - code_len: length of code reps by the fde + This functions adds a fde struct to the debug pointer. Its in the + form of a linked list. + die: subprogram/function die corresponding to this fde + cie: cie referred to by this fde, obtained from call to + add_frame_cie() routine. + virt_addr: beginning address + code_len: length of code reps by the fde --------------------------------------------------------------------------*/ - /*ARGSUSED*/ /* pretend all args used */ + /*ARGSUSED*/ /* pretend all args used */ Dwarf_Unsigned dwarf_add_frame_fde(Dwarf_P_Debug dbg, - Dwarf_P_Fde fde, - Dwarf_P_Die die, - Dwarf_Unsigned cie, - Dwarf_Unsigned virt_addr, - Dwarf_Unsigned code_len, - Dwarf_Unsigned symidx, Dwarf_Error * error) + Dwarf_P_Fde fde, + Dwarf_P_Die die, + Dwarf_Unsigned cie, + Dwarf_Unsigned virt_addr, + Dwarf_Unsigned code_len, + Dwarf_Unsigned symidx, Dwarf_Error * error) { return dwarf_add_frame_fde_b(dbg, fde, die, cie, virt_addr, - code_len, symidx, 0, 0, error); + code_len, symidx, 0, 0, error); } /*ARGSUSED10*/ Dwarf_Unsigned dwarf_add_frame_fde_b(Dwarf_P_Debug dbg, - Dwarf_P_Fde fde, - Dwarf_P_Die die, - Dwarf_Unsigned cie, - Dwarf_Unsigned virt_addr, - Dwarf_Unsigned code_len, - Dwarf_Unsigned symidx, - Dwarf_Unsigned symidx_of_end, - Dwarf_Addr offset_from_end_sym, - Dwarf_Error * error) + Dwarf_P_Fde fde, + Dwarf_P_Die die, + Dwarf_Unsigned cie, + Dwarf_Unsigned virt_addr, + Dwarf_Unsigned code_len, + Dwarf_Unsigned symidx, + Dwarf_Unsigned symidx_of_end, + Dwarf_Addr offset_from_end_sym, + Dwarf_Error * error) { Dwarf_P_Fde curfde; @@ -145,77 +145,78 @@ dwarf_add_frame_fde_b(Dwarf_P_Debug dbg, fde->fde_exception_table_symbol = 0; fde->fde_end_symbol_offset = offset_from_end_sym; fde->fde_end_symbol = symidx_of_end; + fde->fde_dbg = dbg; curfde = dbg->de_last_fde; if (curfde == NULL) { - dbg->de_frame_fdes = fde; - dbg->de_last_fde = fde; - dbg->de_n_fde = 1; + dbg->de_frame_fdes = fde; + dbg->de_last_fde = fde; + dbg->de_n_fde = 1; } else { - curfde->fde_next = fde; - dbg->de_last_fde = fde; - dbg->de_n_fde++; + curfde->fde_next = fde; + dbg->de_last_fde = fde; + dbg->de_n_fde++; } return dbg->de_n_fde; } /*------------------------------------------------------------------------- - This functions adds information to an fde. The fde is - linked into the linked list of fde's maintained in the Dwarf_P_Debug - structure. - dbg: The debug descriptor. - fde: The fde to be added. - die: subprogram/function die corresponding to this fde - cie: cie referred to by this fde, obtained from call to - add_frame_cie() routine. - virt_addr: beginning address - code_len: length of code reps by the fde - symidx: The symbol id of the symbol wrt to which relocation needs - to be performed for 'virt_addr'. - offset_into_exception_tables: The start of exception tables for - this function (indicated as an offset into the exception - tables). A value of -1 indicates that there is no exception - table entries associated with this function. - exception_table_symbol: The symbol id of the section for exception - tables wrt to which the offset_into_exception_tables will - be relocated. + This functions adds information to an fde. The fde is + linked into the linked list of fde's maintained in the Dwarf_P_Debug + structure. + dbg: The debug descriptor. + fde: The fde to be added. + die: subprogram/function die corresponding to this fde + cie: cie referred to by this fde, obtained from call to + add_frame_cie() routine. + virt_addr: beginning address + code_len: length of code reps by the fde + symidx: The symbol id of the symbol wrt to which relocation needs + to be performed for 'virt_addr'. + offset_into_exception_tables: The start of exception tables for + this function (indicated as an offset into the exception + tables). A value of -1 indicates that there is no exception + table entries associated with this function. + exception_table_symbol: The symbol id of the section for exception + tables wrt to which the offset_into_exception_tables will + be relocated. --------------------------------------------------------------------------*/ Dwarf_Unsigned dwarf_add_frame_info(Dwarf_P_Debug dbg, - Dwarf_P_Fde fde, - Dwarf_P_Die die, - Dwarf_Unsigned cie, - Dwarf_Unsigned virt_addr, - Dwarf_Unsigned code_len, - Dwarf_Unsigned symidx, - Dwarf_Signed offset_into_exception_tables, - Dwarf_Unsigned exception_table_symbol, - Dwarf_Error * error) + Dwarf_P_Fde fde, + Dwarf_P_Die die, + Dwarf_Unsigned cie, + Dwarf_Unsigned virt_addr, + Dwarf_Unsigned code_len, + Dwarf_Unsigned symidx, + Dwarf_Signed offset_into_exception_tables, + Dwarf_Unsigned exception_table_symbol, + Dwarf_Error * error) { return dwarf_add_frame_info_b(dbg, fde, die, cie, virt_addr, - code_len, symidx, - /* end_symbol */ 0, - /* offset_from_end */ 0, - offset_into_exception_tables, - exception_table_symbol, error); + code_len, symidx, + /* end_symbol */ 0, + /* offset_from_end */ 0, + offset_into_exception_tables, + exception_table_symbol, error); } - /*ARGSUSED*/ /* pretend all args used */ - Dwarf_Unsigned + /*ARGSUSED*/ /* pretend all args used */ +Dwarf_Unsigned dwarf_add_frame_info_b(Dwarf_P_Debug dbg, - Dwarf_P_Fde fde, - Dwarf_P_Die die, - Dwarf_Unsigned cie, - Dwarf_Unsigned virt_addr, - Dwarf_Unsigned code_len, - Dwarf_Unsigned symidx, - Dwarf_Unsigned end_symidx, - Dwarf_Unsigned offset_from_end_symbol, - Dwarf_Signed offset_into_exception_tables, - Dwarf_Unsigned exception_table_symbol, - Dwarf_Error * error) + Dwarf_P_Fde fde, + Dwarf_P_Die die, + Dwarf_Unsigned cie, + Dwarf_Unsigned virt_addr, + Dwarf_Unsigned code_len, + Dwarf_Unsigned symidx, + Dwarf_Unsigned end_symidx, + Dwarf_Unsigned offset_from_end_symbol, + Dwarf_Signed offset_into_exception_tables, + Dwarf_Unsigned exception_table_symbol, + Dwarf_Error * error) { Dwarf_P_Fde curfde; @@ -225,28 +226,51 @@ dwarf_add_frame_info_b(Dwarf_P_Debug dbg, fde->fde_r_symidx = symidx; fde->fde_addr_range = code_len; fde->fde_offset_into_exception_tables = - offset_into_exception_tables; + offset_into_exception_tables; fde->fde_exception_table_symbol = exception_table_symbol; fde->fde_end_symbol_offset = offset_from_end_symbol; fde->fde_end_symbol = end_symidx; - + fde->fde_dbg = dbg; curfde = dbg->de_last_fde; if (curfde == NULL) { - dbg->de_frame_fdes = fde; - dbg->de_last_fde = fde; - dbg->de_n_fde = 1; + dbg->de_frame_fdes = fde; + dbg->de_last_fde = fde; + dbg->de_n_fde = 1; } else { - curfde->fde_next = fde; - dbg->de_last_fde = fde; - dbg->de_n_fde++; + curfde->fde_next = fde; + dbg->de_last_fde = fde; + dbg->de_n_fde++; } return dbg->de_n_fde; } +/* This is an alternate to inserting frame instructions + one instruction at a time. But use either this + or instruction level, not both in one fde. */ +int +dwarf_insert_fde_inst_bytes(Dwarf_P_Debug dbg, + Dwarf_P_Fde fde,Dwarf_Unsigned len, Dwarf_Ptr ibytes, + Dwarf_Error *error) +{ + if( len == 0) { + return DW_DLV_OK; + } + if(fde->fde_block || fde->fde_inst) { + DWARF_P_DBG_ERROR(dbg, DW_DLE_DUPLICATE_INST_BLOCK, + (int)DW_DLV_BADADDR); + } + fde->fde_block = (Dwarf_Ptr)_dwarf_p_get_alloc(dbg, len); + memcpy(fde->fde_block,ibytes,len); + fde->fde_inst_block_size = len; + fde->fde_n_bytes += len; + return DW_DLV_OK; +} + + /*------------------------------------------------------------------- - Create a new fde + Create a new fde. ---------------------------------------------------------------------*/ Dwarf_P_Fde dwarf_new_fde(Dwarf_P_Debug dbg, Dwarf_Error * error) @@ -254,27 +278,25 @@ dwarf_new_fde(Dwarf_P_Debug dbg, Dwarf_Error * error) Dwarf_P_Fde fde; fde = (Dwarf_P_Fde) - _dwarf_p_get_alloc(dbg, sizeof(struct Dwarf_P_Fde_s)); + _dwarf_p_get_alloc(dbg, sizeof(struct Dwarf_P_Fde_s)); if (fde == NULL) { - DWARF_P_DBG_ERROR(dbg, DW_DLE_FDE_ALLOC, - (Dwarf_P_Fde) DW_DLV_BADADDR); + DWARF_P_DBG_ERROR(dbg, DW_DLE_FDE_ALLOC, + (Dwarf_P_Fde) DW_DLV_BADADDR); } - fde->fde_next = NULL; - fde->fde_inst = NULL; - fde->fde_n_inst = 0; - fde->fde_n_bytes = 0; - fde->fde_last_inst = NULL; + fde->fde_uwordb_size = dbg->de_offset_size; + return fde; } + /*------------------------------------------------------------------------ - Add cfe_offset instruction to 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_Unsigned reg, + Dwarf_Signed offset, Dwarf_Error * error) { Dwarf_Ubyte opc, regno; char *ptr; @@ -282,31 +304,32 @@ dwarf_fde_cfa_offset(Dwarf_P_Fde fde, int nbytes; int res; char buff1[ENCODE_SPACE_NEEDED]; + Dwarf_P_Debug dbg = fde->fde_dbg; curinst = (Dwarf_P_Frame_Pgm) - _dwarf_p_get_alloc(NULL, sizeof(struct Dwarf_P_Frame_Pgm_s)); + _dwarf_p_get_alloc(dbg, sizeof(struct Dwarf_P_Frame_Pgm_s)); if (curinst == NULL) { - DWARF_P_DBG_ERROR(NULL, DW_DLE_FPGM_ALLOC, - (Dwarf_P_Fde) DW_DLV_BADADDR); + 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(NULL, DW_DLE_REGNO_OVFL, - (Dwarf_P_Fde) DW_DLV_BADADDR); + DWARF_P_DBG_ERROR(dbg, DW_DLE_REGNO_OVFL, + (Dwarf_P_Fde) DW_DLV_BADADDR); } - opc = opc | regno; /* lower 6 bits are register number */ + opc = opc | regno; /* lower 6 bits are register number */ curinst->dfp_opcode = opc; res = _dwarf_pro_encode_leb128_nm(offset, &nbytes, - buff1, sizeof(buff1)); + buff1, sizeof(buff1)); if (res != DW_DLV_OK) { - _dwarf_p_error(NULL, error, DW_DLE_STRING_ALLOC); - return ((Dwarf_P_Fde) DW_DLV_BADADDR); + _dwarf_p_error(dbg, error, DW_DLE_STRING_ALLOC); + return ((Dwarf_P_Fde) DW_DLV_BADADDR); } - ptr = (char *) _dwarf_p_get_alloc(NULL, nbytes); + ptr = (char *) _dwarf_p_get_alloc(dbg, nbytes); if (ptr == NULL) { - _dwarf_p_error(NULL, error, DW_DLE_STRING_ALLOC); - return ((Dwarf_P_Fde) DW_DLV_BADADDR); + _dwarf_p_error(dbg, error, DW_DLE_STRING_ALLOC); + return ((Dwarf_P_Fde) DW_DLV_BADADDR); } memcpy(ptr, buff1, nbytes); @@ -329,12 +352,22 @@ dwarf_fde_cfa_offset(Dwarf_P_Fde fde, 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_Small op, + Dwarf_Unsigned val1, + Dwarf_Unsigned val2, Dwarf_Error * error) { Dwarf_P_Frame_Pgm curinst; int nbytes, nbytes1, nbytes2; @@ -346,177 +379,190 @@ dwarf_add_fde_inst(Dwarf_P_Fde fde, 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(NULL, sizeof(struct Dwarf_P_Frame_Pgm_s)); + _dwarf_p_get_alloc(dbg, 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); + _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(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; + 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(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; + 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: - 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; - + 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: - 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; - + 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: - 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; - + 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: - break; + _dwarf_p_error(dbg, error, DW_DLE_DEBUGFRAME_ERROR); + return ((Dwarf_P_Fde) DW_DLV_BADADDR); } curinst->dfp_opcode = op; @@ -530,23 +576,23 @@ dwarf_add_fde_inst(Dwarf_P_Fde fde, /*------------------------------------------------------------------------ - instructions are added to fde in the form of a linked - list. This function manages the linked list + Instructions are added to an fde in the form of a linked + list. This function manages the linked list. -------------------------------------------------------------------------*/ void _dwarf_pro_add_to_fde(Dwarf_P_Fde fde, Dwarf_P_Frame_Pgm curinst) { if (fde->fde_last_inst) { - fde->fde_last_inst->dfp_next = curinst; - fde->fde_last_inst = curinst; - fde->fde_n_inst++; - fde->fde_n_bytes += - (long) (curinst->dfp_nbytes + sizeof(Dwarf_Ubyte)); + fde->fde_last_inst->dfp_next = curinst; + fde->fde_last_inst = curinst; + fde->fde_n_inst++; + fde->fde_n_bytes += + (long) (curinst->dfp_nbytes + sizeof(Dwarf_Ubyte)); } else { - fde->fde_last_inst = curinst; - fde->fde_inst = curinst; - fde->fde_n_inst = 1; - fde->fde_n_bytes = - (long) (curinst->dfp_nbytes + sizeof(Dwarf_Ubyte)); + fde->fde_last_inst = curinst; + fde->fde_inst = curinst; + fde->fde_n_inst = 1; + fde->fde_n_bytes = + (long) (curinst->dfp_nbytes + sizeof(Dwarf_Ubyte)); } } |
