Still need to port some kernel modules

This commit is contained in:
2025-08-23 00:35:29 +08:00
parent 015a64039d
commit 64dbb93260
5 changed files with 220 additions and 99 deletions

View File

@ -183,7 +183,7 @@ enum ihk_mc_pt_attribute {
PTATTR_WRITE_COMBINED = 0x40000,
};
enum ihk_mc_pt_attribute attr_mask;
extern enum ihk_mc_pt_attribute attr_mask;
static inline int pfn_is_write_combined(uintptr_t pfn)
{

View File

@ -20,17 +20,19 @@ target_include_directories(mcexec PUBLIC "${KERNEL_DIR}")
set_property(TARGET mcexec PROPERTY POSITION_INDEPENDENT_CODE ON)
set_property(TARGET mcexec PROPERTY LINK_FLAGS "-fPIE -pie")
#unset(LIBDWARF CACHE)
add_executable(mcinspect mcinspect.c)
if (NOT LIBDWARF)
target_include_directories(mcinspect PRIVATE "${CMAKE_CURRENT_BINARY_DIR}/lib/")
target_include_directories(mcinspect PRIVATE
"${CMAKE_CURRENT_SOURCE_DIR}/lib/libdwarf/libdwarf/libdwarf/")
target_link_libraries(mcinspect dwarf z elf)
else()
target_include_directories(mcinspect PRIVATE ${DWARF_H})
target_link_libraries(mcinspect ${LIBDWARF})
endif()
target_link_libraries(mcinspect ${LIBBFD})
target_link_libraries(mcinspect PRIVATE bfd dwarf z elf)
#if (NOT LIBDWARF)
# target_include_directories(mcinspect PRIVATE "${CMAKE_CURRENT_BINARY_DIR}/lib/")
# target_include_directories(mcinspect PRIVATE
# "${CMAKE_CURRENT_SOURCE_DIR}/lib/libdwarf/libdwarf/libdwarf/")
# target_link_libraries(mcinspect dwarf z elf)
#else()
# target_include_directories(mcinspect PRIVATE ${DWARF_H})
# target_link_libraries(mcinspect ${LIBDWARF})
#endif()
#target_link_libraries(mcinspect ${LIBBFD})
set_property(TARGET mcinspect PROPERTY POSITION_INDEPENDENT_CODE ON)
set_property(TARGET mcinspect PROPERTY LINK_FLAGS "-fPIE -pie")

View File

@ -279,13 +279,13 @@ void cmd_ldump2mcdump(void)
return;
}
ok = bfd_set_section_size(abfd, scn, cpsize);
ok = bfd_set_section_size(scn, cpsize);
if (!ok) {
bfd_perror("bfd_set_section_size");
return;
}
ok = bfd_set_section_flags(abfd, scn, SEC_HAS_CONTENTS);
ok = bfd_set_section_flags(scn, SEC_HAS_CONTENTS);
if (!ok) {
bfd_perror("bfd_set_setction_flags");
return;
@ -300,13 +300,13 @@ void cmd_ldump2mcdump(void)
return;
}
ok = bfd_set_section_size(abfd, scn, cpsize);
ok = bfd_set_section_size(scn, cpsize);
if (!ok) {
bfd_perror("bfd_set_section_size");
return;
}
ok = bfd_set_section_flags(abfd, scn, SEC_HAS_CONTENTS);
ok = bfd_set_section_flags(scn, SEC_HAS_CONTENTS);
if (!ok) {
bfd_perror("bfd_set_setction_flags");
return;
@ -321,13 +321,13 @@ void cmd_ldump2mcdump(void)
return;
}
ok = bfd_set_section_size(abfd, scn, cpsize);
ok = bfd_set_section_size(scn, cpsize);
if (!ok) {
bfd_perror("bfd_set_section_size");
return;
}
ok = bfd_set_section_flags(abfd, scn, SEC_HAS_CONTENTS);
ok = bfd_set_section_flags(scn, SEC_HAS_CONTENTS);
if (!ok) {
bfd_perror("bfd_set_setction_flags");
return;
@ -341,13 +341,13 @@ void cmd_ldump2mcdump(void)
return;
}
ok = bfd_set_section_size(abfd, scn, mem_size);
ok = bfd_set_section_size(scn, mem_size);
if (!ok) {
bfd_perror("bfd_set_section_size");
return;
}
ok = bfd_set_section_flags(abfd, scn, SEC_ALLOC|SEC_HAS_CONTENTS);
ok = bfd_set_section_flags(scn, SEC_ALLOC|SEC_HAS_CONTENTS);
if (!ok) {
bfd_perror("bfd_set_setction_flags");
return;
@ -366,14 +366,14 @@ void cmd_ldump2mcdump(void)
return;
}
ok = bfd_set_section_size(abfd, scn, mem_chunks->chunks[i].size);
ok = bfd_set_section_size(scn, mem_chunks->chunks[i].size);
if (!ok) {
bfd_perror("bfd_set_section_size");
return;
}
ok = bfd_set_section_flags(abfd, scn, SEC_ALLOC|SEC_HAS_CONTENTS);
ok = bfd_set_section_flags(scn, SEC_ALLOC|SEC_HAS_CONTENTS);
if (!ok) {
bfd_perror("bfd_set_setction_flags");
return;

View File

@ -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;