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_prologue_fr_mem_info(__unw_info_t *info,
00048 __uint32_t frmask) {
00049 __unw_error_t ret = __UNW_OK;
00050 __unw_format_p6_t desc;
00051 __uint64_t rsize;
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
00062
00063
00064 if (frmask >= 16) {
00065 return __UNW_INV_ARG_ERROR;
00066 }
00067 desc._fix[0] = 0xc0;
00068 desc._fix[0] |= frmask;
00069 rsize = 1;
00070
00071
00072 ret = unwind_info_add_desc(rsize, (char *)&desc);
00073
00074 return ret;
00075 }
00076
00077
00078
00079
00080 __unw_error_t unwind_info_add_prologue_frgr_mem_info(__unw_info_t *info,
00081 __uint32_t grmask, __uint32_t frmask) {
00082 __unw_error_t ret = __UNW_OK;
00083 __unw_format_p5_t desc;
00084 __uint64_t rsize;
00085
00086
00087 if (NULL == info) {
00088 return __UNW_NULL_ERROR;
00089 } else if (_unwind_info + _unwind_info_size != info) {
00090 return __UNW_INV_ARG_ERROR;
00091 }
00092
00093
00094
00095
00096
00097 if ((grmask >= 16) || (frmask >= 1048576)) {
00098 return __UNW_INV_ARG_ERROR;
00099 }
00100 desc._fix[0] = 0xb9;
00101 desc._fix[1] = (grmask << 4);
00102 desc._fix[1] |= ((frmask & 0xf0000) >> 16);
00103 desc._fix[2] = ((frmask & 0x0ff00) >> 8);
00104 desc._fix[3] = (frmask & 0x000ff);
00105 rsize = 4;
00106
00107
00108 ret = unwind_info_add_desc(rsize, (char *)&desc);
00109
00110 return ret;
00111 }
00112
00113
00114
00115
00116 __unw_error_t unwind_info_add_prologue_gr_gr_info(__unw_info_t *info, __uint32_t grmask,
00117 __uint32_t gr) {
00118 __unw_error_t ret = __UNW_OK;
00119 __unw_format_p9_t desc;
00120 __uint64_t rsize;
00121
00122
00123 if (NULL == info) {
00124 return __UNW_NULL_ERROR;
00125 } else if (_unwind_info + _unwind_info_size != info) {
00126 return __UNW_INV_ARG_ERROR;
00127 }
00128
00129
00130
00131
00132
00133 if ((grmask >= 16) || (gr >= 128)) {
00134 return __UNW_INV_ARG_ERROR;
00135 }
00136 desc._fix[0] = 0xf1;
00137 desc._fix[1] = 0x00;
00138 desc._fix[1] |= grmask;
00139 desc._fix[2] = 0x00;
00140 desc._fix[2] |= gr;
00141 rsize = 3;
00142
00143
00144 ret = unwind_info_add_desc(rsize, (char *)&desc);
00145
00146 return ret;
00147 }
00148
00149
00150
00151
00152 __unw_error_t unwind_info_add_prologue_gr_mem_info(__unw_info_t *info,
00153 __uint32_t grmask) {
00154 __unw_error_t ret = __UNW_OK;
00155 __unw_format_p6_t desc;
00156 __uint64_t rsize;
00157
00158
00159 if (NULL == info) {
00160 return __UNW_NULL_ERROR;
00161 } else if (_unwind_info + _unwind_info_size != info) {
00162 return __UNW_INV_ARG_ERROR;
00163 }
00164
00165
00166
00167
00168
00169 if (grmask >= 16) {
00170 return __UNW_INV_ARG_ERROR;
00171 }
00172 desc._fix[0] = 0xd0;
00173 desc._fix[0] |= grmask;
00174 rsize = 1;
00175
00176
00177 ret = unwind_info_add_desc(rsize, (char *)&desc);
00178
00179 return ret;
00180 }
00181
00182
00183
00184
00185 __unw_error_t unwind_info_add_prologue_br_mem_info(__unw_info_t *info,
00186 __uint32_t brmask) {
00187 __unw_error_t ret = __UNW_OK;
00188 __unw_format_p1_t desc;
00189 __uint64_t rsize;
00190
00191
00192 if (NULL == info) {
00193 return __UNW_NULL_ERROR;
00194 } else if (_unwind_info + _unwind_info_size != info) {
00195 return __UNW_INV_ARG_ERROR;
00196 }
00197
00198
00199
00200
00201
00202 if (brmask >= 32) {
00203 return __UNW_INV_ARG_ERROR;
00204 }
00205 desc._fix[0] = 0x80;
00206 desc._fix[0] |= brmask;
00207 rsize = 1;
00208
00209
00210 ret = unwind_info_add_desc(rsize, (char *)&desc);
00211
00212 return ret;
00213 }
00214
00215
00216
00217
00218 __unw_error_t unwind_info_add_prologue_br_gr_info(__unw_info_t *info,
00219 __uint32_t brmask, __uint32_t gr) {
00220 __unw_error_t ret = __UNW_OK;
00221 __unw_format_p2_t desc;
00222 __uint64_t rsize;
00223
00224
00225 if (NULL == info) {
00226 return __UNW_NULL_ERROR;
00227 } else if (_unwind_info + _unwind_info_size != info) {
00228 return __UNW_INV_ARG_ERROR;
00229 }
00230
00231
00232
00233
00234
00235 if ((brmask >= 32) || (gr >= 128)) {
00236 return __UNW_INV_ARG_ERROR;
00237 }
00238 desc._fix[0] = 0xa0;
00239 desc._fix[0] |= ((brmask & 0x1e) >> 1);
00240 desc._fix[1] = 0x00;
00241 desc._fix[1] |= ((brmask & 0x01) << 7);
00242 desc._fix[1] |= gr;
00243 rsize = 2;
00244
00245
00246 ret = unwind_info_add_desc(rsize, (char *)&desc);
00247
00248 return ret;
00249 }
00250
00251
00252
00253
00254 __unw_error_t unwind_info_add_prologue_spill_base_info(__unw_info_t *info,
00255 __uint64_t pspoffset) {
00256 __unw_error_t ret = __UNW_OK;
00257 __unw_format_p7_t *desc;
00258 __uint64_t rsize, esize;
00259 char encoded[1+__UNW_ENCODING_SIZE];
00260
00261
00262 if (NULL == info) {
00263 return __UNW_NULL_ERROR;
00264 } else if (_unwind_info + _unwind_info_size != info) {
00265 return __UNW_INV_ARG_ERROR;
00266 }
00267
00268
00269
00270
00271
00272 encoded[0] = 0xe2;
00273 if ((esize = __leb128_encode((char *)&encoded[1],
00274 (__uint64_t)__UNW_ENCODING_SIZE,
00275 pspoffset)) == 0) {
00276 return __UNW_INTERNAL_ERROR;
00277 }
00278
00279 desc = (__unw_format_p7_t *)&encoded;
00280 rsize = 1 + esize;
00281
00282
00283 ret = unwind_info_add_desc(rsize, (char *)desc);
00284
00285 return ret;
00286 }
00287
00288
00289
00290
00291 __unw_error_t unwind_info_add_prologue_spill_mask_info(__unw_info_t *info,
00292 void *ptr, __uint64_t size) {
00293 __unw_error_t ret;
00294 char type[1];
00295
00296
00297 if (NULL == info) {
00298 return __UNW_NULL_ERROR;
00299 } else if (_unwind_info + _unwind_info_size != info) {
00300 return __UNW_INV_ARG_ERROR;
00301 }
00302
00303
00304 type[0] = 0xb8;
00305 ret = unwind_info_add_desc(1, type);
00306 if (ret != __UNW_OK) {
00307 return ret;
00308 }
00309 return unwind_info_add_desc(size, (char *)ptr);
00310 }