(linenum→info "unix/slp.c:2238")

glibc/2.7/nptl_db/fetch-value.c

    1: /* Helper routines for libthread_db.
    2:    Copyright (C) 2003, 2004 Free Software Foundation, Inc.
    3:    This file is part of the GNU C Library.
    4: 
    5:    The GNU C Library is free software; you can redistribute it and/or
    6:    modify it under the terms of the GNU Lesser General Public
    7:    License as published by the Free Software Foundation; either
    8:    version 2.1 of the License, or (at your option) any later version.
    9: 
   10:    The GNU C Library is distributed in the hope that it will be useful,
   11:    but WITHOUT ANY WARRANTY; without even the implied warranty of
   12:    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
   13:    Lesser General Public License for more details.
   14: 
   15:    You should have received a copy of the GNU Lesser General Public
   16:    License along with the GNU C Library; if not, write to the Free
   17:    Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA
   18:    02111-1307 USA.  */
   19: 
   20: #include "thread_dbP.h"
   21: #include <byteswap.h>
   22: #include <assert.h>
   23: 
   24: td_err_e
   25: _td_check_sizeof (td_thragent_t *ta, uint32_t *sizep, int sizep_name)
   26: {
   27:   if (*sizep == 0)
   28:     {
   29:       psaddr_t descptr;
   30:       ps_err_e err = td_lookup (ta->ph, sizep_name, &descptr);
   31:       if (err == PS_NOSYM)
   32:         return TD_NOCAPAB;
   33:       if (err == PS_OK)
   34:         err = ps_pdread (ta->ph, descptr, sizep, sizeof *sizep);
   35:       if (err != PS_OK)
   36:         return TD_ERR;
   37:       if (*sizep & 0xff000000U)
   38:         *sizep = bswap_32 (*sizep);
   39:     }
   40:   return TD_OK;
   41: }
   42: 
   43: td_err_e
   44: _td_locate_field (td_thragent_t *ta,
   45:                   db_desc_t desc, int descriptor_name,
   46:                   psaddr_t idx, psaddr_t *address)
   47: {
   48:   uint32_t elemsize;
   49: 
   50:   if (DB_DESC_SIZE (desc) == 0)
   51:     {
   52:       /* Read the information about this field from the inferior.  */
   53:       psaddr_t descptr;
   54:       ps_err_e err = td_lookup (ta->ph, descriptor_name, &descptr);
   55:       if (err == PS_NOSYM)
   56:         return TD_NOCAPAB;
   57:       if (err == PS_OK)
   58:         err = ps_pdread (ta->ph, descptr, desc, DB_SIZEOF_DESC);
   59:       if (err != PS_OK)
   60:         return TD_ERR;
   61:       if (DB_DESC_SIZE (desc) == 0)
   62:         return TD_DBERR;
   63:       if (DB_DESC_SIZE (desc) & 0xff000000U)
   64:         {
   65:           /* Byte-swap these words, though we leave the size word
   66:              in native order as the handy way to distinguish.  */
   67:           DB_DESC_OFFSET (desc) = bswap_32 (DB_DESC_OFFSET (desc));
   68:           DB_DESC_NELEM (desc) = bswap_32 (DB_DESC_NELEM (desc));
   69:         }
   70:     }
   71: 
   72:   if (idx != 0 && idx - (psaddr_t) 0 > DB_DESC_NELEM (desc))
   73:     /* This is an internal indicator to callers with nonzero IDX
   74:        that the IDX value is too big.  */
   75:     return TD_NOAPLIC;
   76: 
   77:   elemsize = DB_DESC_SIZE (desc);
   78:   if (elemsize & 0xff000000U)
   79:     elemsize = bswap_32 (elemsize);
   80: 
   81:   *address += (int32_t) DB_DESC_OFFSET (desc);
   82:   *address += (elemsize / 8 * (idx - (psaddr_t) 0));
   83:   return TD_OK;
   84: }
   85: 
   86: td_err_e
   87: _td_fetch_value (td_thragent_t *ta,
   88:                  db_desc_t desc, int descriptor_name,
   89:                  psaddr_t idx, psaddr_t address,
   90:                  psaddr_t *result)
   91: {
   92:   ps_err_e err;
   93:   td_err_e terr = _td_locate_field (ta, desc, descriptor_name, idx, &address);
   94:   if (terr != TD_OK)
   95:     return terr;
   96: 
   97:   if (DB_DESC_SIZE (desc) == 8 || DB_DESC_SIZE (desc) == bswap_32 (8))
   98:     {
   99:       uint8_t value;
  100:       err = ps_pdread (ta->ph, address, &value, sizeof value);
  101:       *result = (psaddr_t) 0 + value;
  102:     }
  103:   else if (DB_DESC_SIZE (desc) == 32)
  104:     {
  105:       uint32_t value;
  106:       err = ps_pdread (ta->ph, address, &value, sizeof value);
  107:       *result = (psaddr_t) 0 + value;
  108:     }
  109:   else if (DB_DESC_SIZE (desc) == 64)
  110:     {
  111:       uint64_t value;
  112:       if (sizeof (psaddr_t) < 8)
  113:         return TD_NOCAPAB;
  114:       err = ps_pdread (ta->ph, address, &value, sizeof value);
  115:       *result = (psaddr_t) 0 + value;
  116:     }
  117:   else if (DB_DESC_SIZE (desc) == bswap_32 (32))
  118:     {
  119:       uint32_t value;
  120:       err = ps_pdread (ta->ph, address, &value, sizeof value);
  121:       value = bswap_32 (value);
  122:       *result = (psaddr_t) 0 + value;
  123:     }
  124:   else if (DB_DESC_SIZE (desc) == bswap_32 (64))
  125:     {
  126:       uint64_t value;
  127:       if (sizeof (psaddr_t) < 8)
  128:         return TD_NOCAPAB;
  129:       err = ps_pdread (ta->ph, address, &value, sizeof value);
  130:       value = bswap_64 (value);
  131:       *result = (psaddr_t) 0 + value;
  132:     }
  133:   else
  134:     return TD_DBERR;
  135: 
  136:   return err == PS_OK ? TD_OK : TD_ERR;
  137: }
  138: 
  139: 
  140: td_err_e
  141: _td_store_value (td_thragent_t *ta,
  142:                  uint32_t desc[2], int descriptor_name, psaddr_t idx,
  143:                  psaddr_t address, psaddr_t widened_value)
  144: {
  145:   ps_err_e err;
  146:   td_err_e terr = _td_locate_field (ta, desc, descriptor_name, idx, &address);
  147:   if (terr != TD_OK)
  148:     return terr;
  149: 
  150:   if (DB_DESC_SIZE (desc) == 8 || DB_DESC_SIZE (desc) == bswap_32 (8))
  151:     {
  152:       uint8_t value = widened_value - (psaddr_t) 0;
  153:       err = ps_pdwrite (ta->ph, address, &value, sizeof value);
  154:     }
  155:   else if (DB_DESC_SIZE (desc) == 32)
  156:     {
  157:       uint32_t value = widened_value - (psaddr_t) 0;
  158:       err = ps_pdwrite (ta->ph, address, &value, sizeof value);
  159:     }
  160:   else if (DB_DESC_SIZE (desc) == 64)
  161:     {
  162:       uint64_t value = widened_value - (psaddr_t) 0;
  163:       if (sizeof (psaddr_t) < 8)
  164:         return TD_NOCAPAB;
  165:       err = ps_pdwrite (ta->ph, address, &value, sizeof value);
  166:     }
  167:   else if (DB_DESC_SIZE (desc) == bswap_32 (32))
  168:     {
  169:       uint32_t value = widened_value - (psaddr_t) 0;
  170:       value = bswap_32 (value);
  171:       err = ps_pdwrite (ta->ph, address, &value, sizeof value);
  172:     }
  173:   else if (DB_DESC_SIZE (desc) == bswap_32 (64))
  174:     {
  175:       uint64_t value = widened_value - (psaddr_t) 0;
  176:       if (sizeof (psaddr_t) < 8)
  177:         return TD_NOCAPAB;
  178:       value = bswap_64 (value);
  179:       err = ps_pdwrite (ta->ph, address, &value, sizeof value);
  180:     }
  181:   else
  182:     return TD_DBERR;
  183: 
  184:   return err == PS_OK ? TD_OK : TD_ERR;
  185: }
  186: 
  187: td_err_e
  188: _td_fetch_value_local (td_thragent_t *ta,
  189:                        db_desc_t desc, int descriptor_name, psaddr_t idx,
  190:                        void *address,
  191:                        psaddr_t *result)
  192: {
  193:   td_err_e terr = _td_locate_field (ta, desc, descriptor_name, idx, &address);
  194:   if (terr != TD_OK)
  195:     return terr;
  196: 
  197:   if (DB_DESC_SIZE (desc) == 8 || DB_DESC_SIZE (desc) == bswap_32 (8))
  198:     {
  199:       uint8_t value;
  200:       memcpy (&value, address, sizeof value);
  201:       *result = (psaddr_t) 0 + value;
  202:     }
  203:   else if (DB_DESC_SIZE (desc) == 32)
  204:     {
  205:       uint32_t value;
  206:       memcpy (&value, address, sizeof value);
  207:       *result = (psaddr_t) 0 + value;
  208:     }
  209:   else if (DB_DESC_SIZE (desc) == 64)
  210:     {
  211:       uint64_t value;
  212:       if (sizeof (psaddr_t) < 8)
  213:         return TD_NOCAPAB;
  214:       memcpy (&value, address, sizeof value);
  215:       *result = (psaddr_t) 0 + value;
  216:     }
  217:   else if (DB_DESC_SIZE (desc) == bswap_32 (32))
  218:     {
  219:       uint32_t value;
  220:       memcpy (&value, address, sizeof value);
  221:       value = bswap_32 (value);
  222:       *result = (psaddr_t) 0 + value;
  223:     }
  224:   else if (DB_DESC_SIZE (desc) == bswap_32 (64))
  225:     {
  226:       uint64_t value;
  227:       if (sizeof (psaddr_t) < 8)
  228:         return TD_NOCAPAB;
  229:       memcpy (&value, address, sizeof value);
  230:       value = bswap_64 (value);
  231:       *result = (psaddr_t) 0 + value;
  232:     }
  233:   else
  234:     return TD_DBERR;
  235: 
  236:   return TD_OK;
  237: }
  238: 
  239: 
  240: td_err_e
  241: _td_store_value_local (td_thragent_t *ta,
  242:                        uint32_t desc[2], int descriptor_name, psaddr_t idx,
  243:                        void *address, psaddr_t widened_value)
  244: {
  245:   td_err_e terr = _td_locate_field (ta, desc, descriptor_name, idx, &address);
  246:   if (terr != TD_OK)
  247:     return terr;
  248: 
  249:   if (DB_DESC_SIZE (desc) == 8 || DB_DESC_SIZE (desc) == bswap_32 (8))
  250:     {
  251:       uint8_t value = widened_value - (psaddr_t) 0;
  252:       memcpy (address, &value, sizeof value);
  253:     }
  254:   else if (DB_DESC_SIZE (desc) == 32)
  255:     {
  256:       uint32_t value = widened_value - (psaddr_t) 0;
  257:       memcpy (address, &value, sizeof value);
  258:     }
  259:   else if (DB_DESC_SIZE (desc) == 64)
  260:     {
  261:       uint64_t value = widened_value - (psaddr_t) 0;
  262:       if (sizeof (psaddr_t) < 8)
  263:         return TD_NOCAPAB;
  264:       memcpy (address, &value, sizeof value);
  265:     }
  266:   else if (DB_DESC_SIZE (desc) == bswap_32 (32))
  267:     {
  268:       uint32_t value = widened_value - (psaddr_t) 0;
  269:       value = bswap_32 (value);
  270:       memcpy (address, &value, sizeof value);
  271:     }
  272:   else if (DB_DESC_SIZE (desc) == bswap_32 (64))
  273:     {
  274:       uint64_t value = widened_value - (psaddr_t) 0;
  275:       if (sizeof (psaddr_t) < 8)
  276:         return TD_NOCAPAB;
  277:       value = bswap_64 (value);
  278:       memcpy (address, &value, sizeof value);
  279:     }
  280:   else
  281:     return TD_DBERR;
  282: 
  283:   return TD_OK;
  284: }
Syntax (Markdown)