Print this page
6070 libdisasm: attach/detach arch ops should be optional
Reviewed by: Robert Mustacchi <rm@joyent.com>


 126 dis_set_data(dis_handle_t *dhp, void *data)
 127 {
 128         dhp->dh_data = data;
 129 }
 130 
 131 void
 132 dis_flags_set(dis_handle_t *dhp, int f)
 133 {
 134         dhp->dh_flags |= f;
 135 }
 136 
 137 void
 138 dis_flags_clear(dis_handle_t *dhp, int f)
 139 {
 140         dhp->dh_flags &= ~f;
 141 }
 142 
 143 void
 144 dis_handle_destroy(dis_handle_t *dhp)
 145 {

 146         dhp->dh_arch->da_handle_detach(dhp);

 147         dis_free(dhp, sizeof (dis_handle_t));
 148 }
 149 
 150 dis_handle_t *
 151 dis_handle_create(int flags, void *data, dis_lookup_f lookup_func,
 152     dis_read_f read_func)
 153 {
 154         dis_handle_t *dhp;
 155         dis_arch_t *arch = NULL;
 156         int i;
 157 
 158         /* Select an architecture based on flags */
 159         for (i = 0; dis_archs[i] != NULL; i++) {
 160                 if (dis_archs[i]->da_supports_flags(flags)) {
 161                         arch = dis_archs[i];
 162                         break;
 163                 }
 164         }
 165         if (arch == NULL) {
 166                 (void) dis_seterrno(E_DIS_UNSUPARCH);
 167                 return (NULL);
 168         }
 169 
 170         if ((dhp = dis_zalloc(sizeof (dis_handle_t))) == NULL) {
 171                 (void) dis_seterrno(E_DIS_NOMEM);
 172                 return (NULL);
 173         }
 174         dhp->dh_arch = arch;
 175         dhp->dh_lookup = lookup_func;
 176         dhp->dh_read = read_func;
 177         dhp->dh_flags = flags;
 178         dhp->dh_data = data;
 179 
 180         /*
 181          * Allow the architecture-specific code to allocate
 182          * its private data.
 183          */
 184         if (arch->da_handle_attach(dhp) != 0) {

 185                 dis_free(dhp, sizeof (dis_handle_t));
 186                 /* dis errno already set */
 187                 return (NULL);
 188         }
 189 
 190         return (dhp);
 191 }
 192 
 193 int
 194 dis_disassemble(dis_handle_t *dhp, uint64_t addr, char *buf, size_t buflen)
 195 {
 196         return (dhp->dh_arch->da_disassemble(dhp, addr, buf, buflen));
 197 }
 198 
 199 /*
 200  * On some instruction sets (e.g., x86), we have no choice except to
 201  * disassemble everything from the start of the symbol, and stop when we
 202  * have reached our instruction address.  If we're not in the middle of a
 203  * known symbol, then we return the same address to indicate failure.
 204  */




 126 dis_set_data(dis_handle_t *dhp, void *data)
 127 {
 128         dhp->dh_data = data;
 129 }
 130 
 131 void
 132 dis_flags_set(dis_handle_t *dhp, int f)
 133 {
 134         dhp->dh_flags |= f;
 135 }
 136 
 137 void
 138 dis_flags_clear(dis_handle_t *dhp, int f)
 139 {
 140         dhp->dh_flags &= ~f;
 141 }
 142 
 143 void
 144 dis_handle_destroy(dis_handle_t *dhp)
 145 {
 146         if (dhp->dh_arch->da_handle_detach != NULL)
 147                 dhp->dh_arch->da_handle_detach(dhp);
 148 
 149         dis_free(dhp, sizeof (dis_handle_t));
 150 }
 151 
 152 dis_handle_t *
 153 dis_handle_create(int flags, void *data, dis_lookup_f lookup_func,
 154     dis_read_f read_func)
 155 {
 156         dis_handle_t *dhp;
 157         dis_arch_t *arch = NULL;
 158         int i;
 159 
 160         /* Select an architecture based on flags */
 161         for (i = 0; dis_archs[i] != NULL; i++) {
 162                 if (dis_archs[i]->da_supports_flags(flags)) {
 163                         arch = dis_archs[i];
 164                         break;
 165                 }
 166         }
 167         if (arch == NULL) {
 168                 (void) dis_seterrno(E_DIS_UNSUPARCH);
 169                 return (NULL);
 170         }
 171 
 172         if ((dhp = dis_zalloc(sizeof (dis_handle_t))) == NULL) {
 173                 (void) dis_seterrno(E_DIS_NOMEM);
 174                 return (NULL);
 175         }
 176         dhp->dh_arch = arch;
 177         dhp->dh_lookup = lookup_func;
 178         dhp->dh_read = read_func;
 179         dhp->dh_flags = flags;
 180         dhp->dh_data = data;
 181 
 182         /*
 183          * Allow the architecture-specific code to allocate
 184          * its private data.
 185          */
 186         if (arch->da_handle_attach != NULL &&
 187             arch->da_handle_attach(dhp) != 0) {
 188                 dis_free(dhp, sizeof (dis_handle_t));
 189                 /* dis errno already set */
 190                 return (NULL);
 191         }
 192 
 193         return (dhp);
 194 }
 195 
 196 int
 197 dis_disassemble(dis_handle_t *dhp, uint64_t addr, char *buf, size_t buflen)
 198 {
 199         return (dhp->dh_arch->da_disassemble(dhp, addr, buf, buflen));
 200 }
 201 
 202 /*
 203  * On some instruction sets (e.g., x86), we have no choice except to
 204  * disassemble everything from the start of the symbol, and stop when we
 205  * have reached our instruction address.  If we're not in the middle of a
 206  * known symbol, then we return the same address to indicate failure.
 207  */