Still need to port some kernel modules
This commit is contained in:
@ -19,7 +19,7 @@
|
||||
#include <string.h>
|
||||
#include <errno.h>
|
||||
#include <dwarf.h>
|
||||
#include <libdwarf/libdwarf.h>
|
||||
#include <libdwarf-0/libdwarf.h>
|
||||
#include <getopt.h>
|
||||
#include <libgen.h>
|
||||
#include <bfd.h>
|
||||
@ -130,14 +130,15 @@ int dwarf_walk_tree(Dwarf_Debug dbg,
|
||||
Dwarf_Error err;
|
||||
Dwarf_Die unit;
|
||||
Dwarf_Die die;
|
||||
Dwarf_Half header_cu_type;
|
||||
int rc;
|
||||
|
||||
/* Iterate compile and type units */
|
||||
for (is_info = 0; is_info < 2; ++is_info) {
|
||||
rc = dwarf_next_cu_header_c(dbg, is_info, &cu_length,
|
||||
rc = dwarf_next_cu_header_d(dbg, is_info, &cu_length,
|
||||
&cu_version, &cu_abbrev_offset, &cu_pointer_size,
|
||||
&cu_offset_size, &cu_extension_size, &type_signature,
|
||||
&type_offset, &cu_next_offset, &err);
|
||||
&type_offset, &cu_next_offset, &header_cu_type, &err);
|
||||
|
||||
while (rc != DW_DLV_NO_ENTRY) {
|
||||
char *name = NULL;
|
||||
@ -151,9 +152,9 @@ int dwarf_walk_tree(Dwarf_Debug dbg,
|
||||
return -1;
|
||||
}
|
||||
|
||||
rc = dwarf_siblingof(dbg, NULL, &unit, &err);
|
||||
rc = dwarf_siblingof_b(dbg, NULL, is_info, &unit, &err);
|
||||
if (rc != DW_DLV_OK) {
|
||||
fprintf(stderr, "error: dwarf_siblingof failed: %d %s\n",
|
||||
fprintf(stderr, "error: dwarf_siblingof_b failed: %d %s\n",
|
||||
rc, dwarf_errmsg(err));
|
||||
return -1;
|
||||
}
|
||||
@ -237,7 +238,7 @@ int dwarf_walk_tree(Dwarf_Debug dbg,
|
||||
}
|
||||
}
|
||||
|
||||
rc = dwarf_siblingof(dbg, die, &next, &err);
|
||||
rc = dwarf_siblingof_b(dbg, die, is_info, &next, &err);
|
||||
dwarf_dealloc(dbg, die, DW_DLA_DIE);
|
||||
if (name)
|
||||
dwarf_dealloc(dbg, name, DW_DLA_STRING);
|
||||
@ -248,10 +249,10 @@ int dwarf_walk_tree(Dwarf_Debug dbg,
|
||||
die = next;
|
||||
}
|
||||
|
||||
rc = dwarf_next_cu_header_c(dbg, is_info, &cu_length,
|
||||
rc = dwarf_next_cu_header_d(dbg, is_info, &cu_length,
|
||||
&cu_version, &cu_abbrev_offset, &cu_pointer_size,
|
||||
&cu_offset_size, &cu_extension_size, &type_signature,
|
||||
&type_offset, &cu_next_offset, &err);
|
||||
&type_offset, &cu_next_offset, &header_cu_type, &err);
|
||||
}
|
||||
}
|
||||
|
||||
@ -294,34 +295,64 @@ int dwarf_get_size(Dwarf_Debug dbg,
|
||||
|
||||
if (ssize < 0) {
|
||||
fprintf(stderr, "%s: unsupported negative size\n",
|
||||
__func__);
|
||||
__func__);
|
||||
return DW_DLV_ERROR;
|
||||
}
|
||||
|
||||
size = (Dwarf_Unsigned) ssize;
|
||||
}
|
||||
else {
|
||||
Dwarf_Locdesc **locdescs;
|
||||
Dwarf_Signed len;
|
||||
Dwarf_Loc_Head_c loclist_head = 0;
|
||||
Dwarf_Unsigned lcount = 0;
|
||||
Dwarf_Locdesc_c locdesc_entry = 0;
|
||||
Dwarf_Small op;
|
||||
Dwarf_Unsigned opd1, opd2, opd3;
|
||||
Dwarf_Unsigned offsetforbranch;
|
||||
int lres;
|
||||
|
||||
if (dwarf_loclist_n(attr, &locdescs, &len, perr)
|
||||
== DW_DLV_ERROR) {
|
||||
|
||||
lres = dwarf_get_loclist_c(attr, &loclist_head, &lcount, perr);
|
||||
if (lres != DW_DLV_OK) {
|
||||
fprintf(stderr, "%s: unsupported member size\n",
|
||||
__func__);
|
||||
return DW_DLV_ERROR;
|
||||
}
|
||||
|
||||
if (len != 1 ||
|
||||
locdescs[0]->ld_cents != 1 ||
|
||||
(locdescs[0]->ld_s[0]).lr_atom
|
||||
!= DW_OP_plus_uconst) {
|
||||
if (lcount != 1) {
|
||||
fprintf(stderr,
|
||||
"%s: unsupported location expression\n",
|
||||
__func__);
|
||||
dwarf_loc_head_c_dealloc(loclist_head);
|
||||
return DW_DLV_ERROR;
|
||||
}
|
||||
|
||||
size = (locdescs[0]->ld_s[0]).lr_number;
|
||||
lres = dwarf_get_locdesc_entry_d(loclist_head, 0, 0, 0, 0, 0, 0, 0, 0, &locdesc_entry, 0, 0, 0, perr);
|
||||
if (lres != DW_DLV_OK) {
|
||||
fprintf(stderr,
|
||||
"%s: unsupported location expression\n",
|
||||
__func__);
|
||||
dwarf_loc_head_c_dealloc(loclist_head);
|
||||
return DW_DLV_ERROR;
|
||||
}
|
||||
|
||||
lres = dwarf_get_location_op_value_d(locdesc_entry, 0, &op, &opd1, &opd2, &opd3, NULL, NULL, NULL, &offsetforbranch, perr);
|
||||
if (lres != DW_DLV_OK) {
|
||||
fprintf(stderr,
|
||||
"%s: unsupported location expression\n",
|
||||
__func__);
|
||||
dwarf_loc_head_c_dealloc(loclist_head);
|
||||
return DW_DLV_ERROR;
|
||||
}
|
||||
|
||||
if (op != DW_OP_plus_uconst) {
|
||||
fprintf(stderr,
|
||||
"%s: unsupported location expression\n",
|
||||
__func__);
|
||||
dwarf_loc_head_c_dealloc(loclist_head);
|
||||
return DW_DLV_ERROR;
|
||||
}
|
||||
size = opd1;
|
||||
dwarf_loc_head_c_dealloc(loclist_head);
|
||||
}
|
||||
dwarf_dealloc(dbg, attr, DW_DLA_ATTR);
|
||||
|
||||
@ -455,27 +486,57 @@ int dwarf_get_offset(Dwarf_Debug dbg,
|
||||
offset = (Dwarf_Unsigned) soffset;
|
||||
}
|
||||
else {
|
||||
Dwarf_Locdesc **locdescs;
|
||||
Dwarf_Signed len;
|
||||
Dwarf_Loc_Head_c loclist_head = 0;
|
||||
Dwarf_Unsigned lcount = 0;
|
||||
Dwarf_Locdesc_c locdesc_entry = 0;
|
||||
Dwarf_Small op;
|
||||
Dwarf_Unsigned opd1, opd2, opd3;
|
||||
Dwarf_Unsigned offsetforbranch;
|
||||
int lres;
|
||||
|
||||
if (dwarf_loclist_n(attr, &locdescs, &len, perr)
|
||||
== DW_DLV_ERROR) {
|
||||
|
||||
lres = dwarf_get_loclist_c(attr, &loclist_head, &lcount, perr);
|
||||
if (lres != DW_DLV_OK) {
|
||||
fprintf(stderr, "%s: unsupported member offset\n",
|
||||
__func__);
|
||||
return DW_DLV_ERROR;
|
||||
}
|
||||
|
||||
if (len != 1 ||
|
||||
locdescs[0]->ld_cents != 1 ||
|
||||
(locdescs[0]->ld_s[0]).lr_atom
|
||||
!= DW_OP_plus_uconst) {
|
||||
if (lcount != 1) {
|
||||
fprintf(stderr,
|
||||
"%s: unsupported location expression\n",
|
||||
__func__);
|
||||
dwarf_loc_head_c_dealloc(loclist_head);
|
||||
return DW_DLV_ERROR;
|
||||
}
|
||||
|
||||
offset = (locdescs[0]->ld_s[0]).lr_number;
|
||||
lres = dwarf_get_locdesc_entry_d(loclist_head, 0, 0, 0, 0, 0, 0, 0, 0, &locdesc_entry, 0, 0, 0, perr);
|
||||
if (lres != DW_DLV_OK) {
|
||||
fprintf(stderr,
|
||||
"%s: unsupported location expression\n",
|
||||
__func__);
|
||||
dwarf_loc_head_c_dealloc(loclist_head);
|
||||
return DW_DLV_ERROR;
|
||||
}
|
||||
|
||||
lres = dwarf_get_location_op_value_d(locdesc_entry, 0, &op, &opd1, &opd2, &opd3, NULL, NULL, NULL, &offsetforbranch, perr);
|
||||
if (lres != DW_DLV_OK) {
|
||||
fprintf(stderr,
|
||||
"%s: unsupported location expression\n",
|
||||
__func__);
|
||||
dwarf_loc_head_c_dealloc(loclist_head);
|
||||
return DW_DLV_ERROR;
|
||||
}
|
||||
|
||||
if (op != DW_OP_plus_uconst) {
|
||||
fprintf(stderr,
|
||||
"%s: unsupported location expression\n",
|
||||
__func__);
|
||||
dwarf_loc_head_c_dealloc(loclist_head);
|
||||
return DW_DLV_ERROR;
|
||||
}
|
||||
offset = opd1;
|
||||
dwarf_loc_head_c_dealloc(loclist_head);
|
||||
}
|
||||
dwarf_dealloc(dbg, attr, DW_DLA_ATTR);
|
||||
|
||||
@ -579,10 +640,10 @@ int dwarf_struct_field_offset(Dwarf_Debug dbg, Dwarf_Die die, void *arg)
|
||||
break;
|
||||
|
||||
next_child:
|
||||
rc = dwarf_siblingof(dbg, child, &next, &err);
|
||||
rc = dwarf_siblingof_b(dbg, child, 1, &next, &err);
|
||||
dwarf_dealloc(dbg, child, DW_DLA_DIE);
|
||||
if (rc != DW_DLV_OK) {
|
||||
fprintf(stderr, "%s: error: dwarf_siblingof: %d %s\n",
|
||||
fprintf(stderr, "%s: error: dwarf_siblingof_b: %d %s\n",
|
||||
__func__, rc, dwarf_errmsg(err));
|
||||
rc = DW_DLV_NO_ENTRY;
|
||||
goto out;
|
||||
@ -617,7 +678,7 @@ out:
|
||||
rc = dwarf_walk_tree(dbg, dwarf_struct_field_offset, &dsfo); \
|
||||
if (rc != DW_DLV_OK) { \
|
||||
fprintf(stderr, "%s: error: finding %s in struct %s\n", \
|
||||
__func__, dsfo.field_name, dsfo.struct_name); \
|
||||
__func__, dsfo.field_name, dsfo.struct_name); \
|
||||
exit(1); \
|
||||
} \
|
||||
offset; \
|
||||
@ -681,7 +742,7 @@ int dwarf_get_address(Dwarf_Debug dbg,
|
||||
printf("%s: DW_AT_location\n", __func__);
|
||||
|
||||
rc = dwarf_whatform(attr, &form, perr);
|
||||
if (rc != DW_DLV_OK) {
|
||||
if (rc != DW_DLV_OK) {
|
||||
fprintf(stderr, "%s: error: getting whatform: %s\n",
|
||||
__func__, dwarf_errmsg(*perr));
|
||||
goto dealloc_out;
|
||||
@ -696,90 +757,148 @@ int dwarf_get_address(Dwarf_Debug dbg,
|
||||
form == DW_FORM_data8 ||
|
||||
form == DW_FORM_sec_offset) {
|
||||
|
||||
Dwarf_Locdesc **locdescs;
|
||||
Dwarf_Signed len;
|
||||
Dwarf_Loc_Head_c loclist_head = 0;
|
||||
Dwarf_Unsigned lcount = 0;
|
||||
Dwarf_Locdesc_c locdesc_entry = 0;
|
||||
Dwarf_Small op;
|
||||
Dwarf_Unsigned opd1, opd2, opd3;
|
||||
Dwarf_Unsigned offsetforbranch;
|
||||
int lres;
|
||||
|
||||
if (dwarf_loclist_n(attr, &locdescs, &len, perr)
|
||||
== DW_DLV_ERROR) {
|
||||
fprintf(stderr, "%s: dwarf_loclist_n: %s\n",
|
||||
lres = dwarf_get_loclist_c(attr, &loclist_head, &lcount, perr);
|
||||
if (lres != DW_DLV_OK) {
|
||||
fprintf(stderr, "%s: dwarf_get_loclist_c: %s\n",
|
||||
__func__, dwarf_errmsg(*perr));
|
||||
rc = DW_DLV_ERROR;
|
||||
goto dealloc_out;
|
||||
}
|
||||
|
||||
if (len != 1 ||
|
||||
locdescs[0]->ld_cents != 1 ||
|
||||
(locdescs[0]->ld_s[0]).lr_atom
|
||||
!= DW_OP_addr) {
|
||||
if (lcount != 1) {
|
||||
fprintf(stderr,
|
||||
"%s: unsupported addr expression\n",
|
||||
__func__);
|
||||
dwarf_loc_head_c_dealloc(loclist_head);
|
||||
rc = DW_DLV_ERROR;
|
||||
goto dealloc_out;
|
||||
}
|
||||
|
||||
addr = (locdescs[0]->ld_s[0]).lr_number;
|
||||
lres = dwarf_get_locdesc_entry_d(loclist_head, 0, 0, 0, 0, 0, 0, 0, 0, &locdesc_entry, 0, 0, 0, perr);
|
||||
if (lres != DW_DLV_OK) {
|
||||
fprintf(stderr,
|
||||
"%s: unsupported addr expression\n",
|
||||
__func__);
|
||||
dwarf_loc_head_c_dealloc(loclist_head);
|
||||
rc = DW_DLV_ERROR;
|
||||
goto dealloc_out;
|
||||
}
|
||||
|
||||
lres = dwarf_get_location_op_value_d(locdesc_entry, 0, &op, &opd1, &opd2, &opd3, NULL, NULL, NULL, &offsetforbranch, perr);
|
||||
if (lres != DW_DLV_OK) {
|
||||
fprintf(stderr,
|
||||
"%s: unsupported addr expression\n",
|
||||
__func__);
|
||||
dwarf_loc_head_c_dealloc(loclist_head);
|
||||
rc = DW_DLV_ERROR;
|
||||
goto dealloc_out;
|
||||
}
|
||||
|
||||
if (op != DW_OP_addr) {
|
||||
fprintf(stderr,
|
||||
"%s: unsupported addr expression\n",
|
||||
__func__);
|
||||
dwarf_loc_head_c_dealloc(loclist_head);
|
||||
rc = DW_DLV_ERROR;
|
||||
goto dealloc_out;
|
||||
}
|
||||
addr = opd1;
|
||||
dwarf_loc_head_c_dealloc(loclist_head);
|
||||
}
|
||||
else if (form == DW_FORM_exprloc) {
|
||||
Dwarf_Half address_size = 0;
|
||||
Dwarf_Ptr x = 0;
|
||||
Dwarf_Unsigned tempud = 0;
|
||||
Dwarf_Locdesc *locdescs = 0;
|
||||
Dwarf_Signed len = 0;
|
||||
Dwarf_Loc_Head_c loclist_head = 0;
|
||||
Dwarf_Unsigned lcount = 0;
|
||||
Dwarf_Locdesc_c locdesc_entry = 0;
|
||||
Dwarf_Small op;
|
||||
Dwarf_Unsigned opd1, opd2, opd3;
|
||||
Dwarf_Unsigned offsetforbranch;
|
||||
int lres;
|
||||
Dwarf_Half version;
|
||||
Dwarf_Half offset_size;
|
||||
|
||||
rc = dwarf_formexprloc(attr, &tempud, &x, perr);
|
||||
if (rc == DW_DLV_NO_ENTRY) {
|
||||
fprintf(stderr, "%s: dwarf_formexprloc: no entry?\n",
|
||||
__func__);
|
||||
goto dealloc_out;
|
||||
}
|
||||
else if (rc == DW_DLV_ERROR) {
|
||||
if (rc != DW_DLV_OK) {
|
||||
fprintf(stderr, "%s: dwarf_formexprloc(): %s\n",
|
||||
__func__, dwarf_errmsg(*perr));
|
||||
goto dealloc_out;
|
||||
}
|
||||
|
||||
rc = dwarf_get_die_address_size(die, &address_size, perr);
|
||||
if (rc == DW_DLV_NO_ENTRY) {
|
||||
fprintf(stderr, "%s: dwarf_get_die_address_size: no entry?\n",
|
||||
__func__);
|
||||
goto dealloc_out;
|
||||
}
|
||||
else if (rc == DW_DLV_ERROR) {
|
||||
if (rc != DW_DLV_OK) {
|
||||
fprintf(stderr, "%s: dwarf_get_die_address_size: %s\n",
|
||||
__func__, dwarf_errmsg(*perr));
|
||||
goto dealloc_out;
|
||||
}
|
||||
|
||||
rc = dwarf_loclist_from_expr_a(dbg, x, tempud, address_size,
|
||||
&locdescs, &len, perr);
|
||||
if (rc == DW_DLV_ERROR) {
|
||||
fprintf(stderr, "%s: dwarf_loclist_from_expr_a: %s\n",
|
||||
rc = dwarf_get_version_of_die(die, &version, &offset_size);
|
||||
if (rc != DW_DLV_OK) {
|
||||
fprintf(stderr, "%s: dwarf_get_version_of_die: %s\n",
|
||||
__func__, dwarf_errmsg(*perr));
|
||||
goto dealloc_out;
|
||||
}
|
||||
else if (rc == DW_DLV_NO_ENTRY) {
|
||||
fprintf(stderr, "%s: dwarf_loclist_from_expr_a: no entry?\n",
|
||||
__func__);
|
||||
|
||||
rc = dwarf_loclist_from_expr_c(dbg, x, tempud, address_size, offset_size, version,
|
||||
&loclist_head, &lcount, perr);
|
||||
if (rc != DW_DLV_OK) {
|
||||
fprintf(stderr, "%s: dwarf_loclist_from_expr_c: %s\n",
|
||||
__func__, dwarf_errmsg(*perr));
|
||||
goto dealloc_out;
|
||||
}
|
||||
|
||||
/* len is always 1 */
|
||||
if (len != 1 ||
|
||||
locdescs[0].ld_cents != 1 ||
|
||||
(locdescs[0].ld_s[0]).lr_atom
|
||||
!= DW_OP_addr) {
|
||||
if (lcount != 1) {
|
||||
fprintf(stderr,
|
||||
"%s: unsupported addr expression\n",
|
||||
__func__);
|
||||
dwarf_loc_head_c_dealloc(loclist_head);
|
||||
rc = DW_DLV_ERROR;
|
||||
goto dealloc_out;
|
||||
}
|
||||
|
||||
addr = (locdescs[0].ld_s[0]).lr_number;
|
||||
lres = dwarf_get_locdesc_entry_d(loclist_head, 0, 0, 0, 0, 0, 0, 0, 0, &locdesc_entry, 0, 0, 0, perr);
|
||||
if (lres != DW_DLV_OK) {
|
||||
fprintf(stderr,
|
||||
"%s: unsupported addr expression\n",
|
||||
__func__);
|
||||
dwarf_loc_head_c_dealloc(loclist_head);
|
||||
rc = DW_DLV_ERROR;
|
||||
goto dealloc_out;
|
||||
}
|
||||
|
||||
lres = dwarf_get_location_op_value_d(locdesc_entry, 0, &op, &opd1, &opd2, &opd3, NULL, NULL, NULL, &offsetforbranch, perr);
|
||||
if (lres != DW_DLV_OK) {
|
||||
fprintf(stderr,
|
||||
"%s: unsupported addr expression\n",
|
||||
__func__);
|
||||
dwarf_loc_head_c_dealloc(loclist_head);
|
||||
rc = DW_DLV_ERROR;
|
||||
goto dealloc_out;
|
||||
}
|
||||
|
||||
if (op != DW_OP_addr) {
|
||||
fprintf(stderr,
|
||||
"%s: unsupported addr expression\n",
|
||||
__func__);
|
||||
dwarf_loc_head_c_dealloc(loclist_head);
|
||||
rc = DW_DLV_ERROR;
|
||||
goto dealloc_out;
|
||||
}
|
||||
addr = opd1;
|
||||
dwarf_loc_head_c_dealloc(loclist_head);
|
||||
}
|
||||
else {
|
||||
fprintf(stderr, "%s: unsupported form type?\n",
|
||||
__func__);
|
||||
__func__);
|
||||
goto dealloc_out;
|
||||
}
|
||||
|
||||
@ -888,7 +1007,7 @@ out:
|
||||
rc = dwarf_walk_tree(dbg, dwarf_global_var_addr, &gva); \
|
||||
if (rc != DW_DLV_OK) { \
|
||||
fprintf(stderr, "%s: error: finding addr of %s\n", \
|
||||
__func__, gva.variable); \
|
||||
__func__, gva.variable); \
|
||||
exit(1); \
|
||||
} \
|
||||
} \
|
||||
@ -1210,25 +1329,25 @@ struct option mcinspect_options[] = {
|
||||
{
|
||||
.name = "ps",
|
||||
.has_arg = no_argument,
|
||||
.flag = &ps,
|
||||
.flag = &ps,
|
||||
.val = 1,
|
||||
},
|
||||
{
|
||||
.name = "help",
|
||||
.has_arg = no_argument,
|
||||
.flag = &help,
|
||||
.flag = &help,
|
||||
.val = 1,
|
||||
},
|
||||
{
|
||||
.name = "debug",
|
||||
.has_arg = no_argument,
|
||||
.flag = &debug,
|
||||
.flag = &debug,
|
||||
.val = 1,
|
||||
},
|
||||
{
|
||||
.name = "vtop",
|
||||
.has_arg = no_argument,
|
||||
.flag = &vtop,
|
||||
.flag = &vtop,
|
||||
.val = 1,
|
||||
},
|
||||
{
|
||||
@ -1277,7 +1396,7 @@ int main(int argc, char **argv)
|
||||
case 'v':
|
||||
vtop_addr = strtoul(optarg, 0, 16);
|
||||
if (vtop_addr == 0 ||
|
||||
errno == EINVAL || errno == ERANGE) {
|
||||
errno == EINVAL || errno == ERANGE) {
|
||||
fprintf(stderr, "error: invalid VA? (expected format: 0xXXXX)\n\n");
|
||||
usage(argv);
|
||||
exit(1);
|
||||
@ -1324,7 +1443,7 @@ int main(int argc, char **argv)
|
||||
exit(1);
|
||||
}
|
||||
|
||||
rc = dwarf_init(dwarffd, DW_DLC_READ, errhand, errarg, &dbg, &error);
|
||||
rc = dwarf_init_b(dwarffd, DW_DLA_WEAK, errhand, errarg, &dbg, &error);
|
||||
if (rc != DW_DLV_OK) {
|
||||
fprintf(stderr, "error: accessing DWARF information\n");
|
||||
exit(1);
|
||||
@ -1339,7 +1458,7 @@ int main(int argc, char **argv)
|
||||
mcvtop(dbg, pid, vtop_addr);
|
||||
}
|
||||
|
||||
dwarf_finish(dbg, &error);
|
||||
dwarf_finish(dbg);
|
||||
close(dwarffd);
|
||||
close(mcfd);
|
||||
return 0;
|
||||
|
||||
Reference in New Issue
Block a user