00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
00020
00021
00022
00023
00024
00025
00026
00027
00028
00029
00030
00031
00032
00033
00034
00035
00036
00037
00038 #include <stdlib.h>
00039 #include <stdio.h>
00040 #include <strings.h>
00041 #include <sys/unwindP.h>
00042 #include "unwind_producer.h"
00043
00044
00045
00046
00047 __unw_error_t unwind_info_add_body_epilogue_info(__unw_info_t *info,
00048 __uint64_t when, __uint64_t ecount) {
00049 __unw_error_t ret = __UNW_OK;
00050 __uint64_t rsize, esize, esize1, esize2;
00051 char encoded[1+2*__UNW_ENCODING_SIZE];
00052
00053
00054 if (NULL == info) {
00055 return __UNW_NULL_ERROR;
00056 } else if (_unwind_info + _unwind_info_size != info) {
00057 return __UNW_INV_ARG_ERROR;
00058 }
00059
00060
00061 if (when >= _current_region_total_size) {
00062 return __UNW_INV_SIZE_ERROR;
00063 }
00064
00065
00066 if (ecount < 32) {
00067
00068
00069
00070 __unw_format_b2_t *desc;
00071
00072 encoded[0] = 0xc0;
00073 encoded[0] |= (char)ecount;
00074 if ((esize = __leb128_encode((char *)&encoded[1],
00075 (__uint64_t)__UNW_ENCODING_SIZE,
00076 when)) == 0) {
00077 return __UNW_INTERNAL_ERROR;
00078 }
00079
00080 desc = (__unw_format_b2_t *)&encoded;
00081 rsize = 1 + esize;
00082
00083
00084 ret = unwind_info_add_desc(rsize, (char *)desc);
00085 } else {
00086
00087
00088
00089 __unw_format_b3_t *desc;
00090
00091 encoded[0] = 0xe0;
00092 if ((esize1 = __leb128_encode((char *)&encoded[1],
00093 (__uint64_t)__UNW_ENCODING_SIZE,
00094 when)) == 0) {
00095 return __UNW_INTERNAL_ERROR;
00096 }
00097 if ((esize2 = __leb128_encode((char *)&encoded[1+esize1],
00098 (__uint64_t)__UNW_ENCODING_SIZE,
00099 ecount)) == 0) {
00100 return __UNW_INTERNAL_ERROR;
00101 }
00102
00103 desc = (__unw_format_b3_t *)&encoded;
00104 rsize = 1 + esize1 + esize2;
00105
00106
00107 ret = unwind_info_add_desc(rsize, (char *)desc);
00108 }
00109
00110 return ret;
00111 }
00112
00113
00114
00115
00116 __unw_error_t unwind_info_add_body_label_state_info(__unw_info_t *info,
00117 __uint64_t label) {
00118 __unw_error_t ret = __UNW_OK;
00119
00120
00121 if (NULL == info) {
00122 return __UNW_NULL_ERROR;
00123 } else if (_unwind_info + _unwind_info_size != info) {
00124 return __UNW_INV_ARG_ERROR;
00125 }
00126
00127
00128 if (label < 32) {
00129
00130
00131
00132 __unw_format_b1_t desc;
00133 __uint64_t rsize;
00134
00135 desc._fix[0] = 0x80;
00136 desc._fix[0] |= (char)label;
00137 rsize = 1;
00138
00139
00140 ret = unwind_info_add_desc(rsize, (char *)&desc);
00141 } else {
00142
00143
00144
00145 __unw_format_b4_t *desc;
00146 __uint64_t rsize, esize;
00147 char encoded[1+__UNW_ENCODING_SIZE];
00148
00149 encoded[0] = 0xf0;
00150 if ((esize = __leb128_encode((char *)&encoded[1],
00151 (__uint64_t)__UNW_ENCODING_SIZE,
00152 label)) == 0) {
00153 return __UNW_INTERNAL_ERROR;
00154 }
00155
00156 desc = (__unw_format_b4_t *)&encoded;
00157 rsize = 1 + esize;
00158
00159
00160 ret = unwind_info_add_desc(rsize, (char *)desc);
00161 }
00162
00163 return ret;
00164 }
00165
00166
00167
00168
00169 __unw_error_t unwind_info_add_body_copy_state_info(__unw_info_t *info,
00170 __uint64_t label) {
00171 __unw_error_t ret = __UNW_OK;
00172
00173
00174 if (NULL == info) {
00175 return __UNW_NULL_ERROR;
00176 } else if (_unwind_info + _unwind_info_size != info) {
00177 return __UNW_INV_ARG_ERROR;
00178 }
00179
00180
00181 if (label < 32) {
00182
00183
00184
00185 __unw_format_b1_t desc;
00186 __uint64_t rsize;
00187
00188 desc._fix[0] = 0xa0;
00189 desc._fix[0] |= (char)label;
00190 rsize = 1;
00191
00192
00193 ret = unwind_info_add_desc(rsize, (char *)&desc);
00194 } else {
00195
00196
00197
00198 __unw_format_b4_t *desc;
00199 __uint64_t rsize, esize;
00200 char encoded[1+__UNW_ENCODING_SIZE];
00201
00202 encoded[0] = 0xf8;
00203 if ((esize = __leb128_encode((char *)&encoded[1],
00204 (__uint64_t)__UNW_ENCODING_SIZE,
00205 label)) == 0) {
00206 return __UNW_INTERNAL_ERROR;
00207 }
00208
00209 desc = (__unw_format_b4_t *)&encoded;
00210 rsize = 1 + esize;
00211
00212
00213 ret = unwind_info_add_desc(rsize, (char *)desc);
00214 }
00215
00216 return ret;
00217 }