Index: kernel/generic/src/debug/line.c
===================================================================
--- kernel/generic/src/debug/line.c	(revision 0373af921e46809be1f9f16e080f93fb2c354b2b)
+++ kernel/generic/src/debug/line.c	(revision d76862d0a73201d8cd706af4402d846671cb29c7)
@@ -297,5 +297,5 @@
 }
 
-static void debug_line_program_header_parse(const uint8_t *data, const uint8_t *data_end, struct debug_line_program_header *hdr)
+static void debug_line_program_header_parse(debug_sections_t *scs, const uint8_t *data, const uint8_t *data_end, struct debug_line_program_header *hdr)
 {
 	const uint8_t *unit_start = data;
@@ -378,5 +378,5 @@
 		hdr->v5.directories_end = data;
 
-		print_formatted_list("directories", hdr->v5.directories, hdr->v5.directories_end,
+		print_formatted_list(scs, "directories", hdr->v5.directories, hdr->v5.directories_end,
 		    hdr->v5.directory_entry_format, hdr->v5.directory_entry_format_end, width);
 
@@ -397,5 +397,5 @@
 		hdr->v5.file_names_end = data;
 
-		print_formatted_list("file_names", hdr->v5.file_names, hdr->v5.file_names_end,
+		print_formatted_list(scs, "file_names", hdr->v5.file_names, hdr->v5.file_names_end,
 		    hdr->v5.file_name_entry_format, hdr->v5.file_name_entry_format_end, width);
 	}
@@ -463,5 +463,5 @@
 }
 
-static const char *get_file_name_v5(struct debug_line_program_header *hdr, int file, int *dir)
+static const char *get_file_name_v5(debug_sections_t *scs, struct debug_line_program_header *hdr, int file, int *dir)
 {
 	// DWARF5 has dynamic layout for file information, which is why
@@ -493,6 +493,6 @@
 				if (form == DW_FORM_line_strp) {
 					uint64_t offset = read_uint(&fns, fns_end, hdr->width);
-					if (offset < debug_line_str_size) {
-						filename = debug_line_str + offset;
+					if (offset < scs->debug_line_str_size) {
+						filename = scs->debug_line_str + offset;
 					}
 					continue;
@@ -527,5 +527,5 @@
 }
 
-static const char *get_file_name(struct debug_line_program_header *hdr, int file, int *dir)
+static const char *get_file_name(debug_sections_t *scs, struct debug_line_program_header *hdr, int file, int *dir)
 {
 	switch (hdr->version) {
@@ -534,5 +534,5 @@
 		return get_file_name_v3(hdr, file, dir);
 	case 5:
-		return get_file_name_v5(hdr, file, dir);
+		return get_file_name_v5(scs, hdr, file, dir);
 	default:
 		return NULL;
@@ -558,5 +558,5 @@
 }
 
-static const char *get_dir_name_v5(struct debug_line_program_header *hdr, int dir)
+static const char *get_dir_name_v5(debug_sections_t *scs, struct debug_line_program_header *hdr, int dir)
 {
 	// TODO: basically a copypaste of get_file_name(). Try to deduplicate it.
@@ -587,6 +587,6 @@
 				if (form == DW_FORM_line_strp) {
 					uint64_t offset = read_uint(&fns, fns_end, hdr->width);
-					if (offset < debug_line_str_size) {
-						filename = debug_line_str + offset;
+					if (offset < scs->debug_line_str_size) {
+						filename = scs->debug_line_str + offset;
 					}
 					continue;
@@ -604,5 +604,5 @@
 }
 
-static const char *get_dir_name(struct debug_line_program_header *hdr, int dir)
+static const char *get_dir_name(debug_sections_t *scs, struct debug_line_program_header *hdr, int dir)
 {
 	switch (hdr->version) {
@@ -611,5 +611,5 @@
 		return get_dir_name_v3(hdr, dir);
 	case 5:
-		return get_dir_name_v5(hdr, dir);
+		return get_dir_name_v5(scs, hdr, dir);
 	default:
 		return NULL;
@@ -617,5 +617,5 @@
 }
 
-static const uint8_t *find_line_program(uintptr_t addr)
+static const uint8_t *find_line_program(debug_sections_t *scs, uintptr_t addr)
 {
 	// TODO: use .debug_aranges to find the data quickly
@@ -625,6 +625,6 @@
 	const uint8_t *closest_prog = NULL;
 
-	const uint8_t *debug_line_ptr = debug_line;
-	const uint8_t *const debug_line_end = debug_line + debug_line_size;
+	const uint8_t *debug_line_ptr = scs->debug_line;
+	const uint8_t *const debug_line_end = scs->debug_line + scs->debug_line_size;
 
 	while (debug_line_ptr < debug_line_end) {
@@ -633,5 +633,5 @@
 		// Parse header
 		struct debug_line_program_header hdr = { };
-		debug_line_program_header_parse(prog, debug_line_end, &hdr);
+		debug_line_program_header_parse(scs, prog, debug_line_end, &hdr);
 		assert(hdr.unit_end > debug_line_ptr);
 		assert(hdr.unit_end <= debug_line_end);
@@ -678,23 +678,27 @@
 		debug_line_program_advance(&lp);
 
-		if (!lp.truncated) {
-			// We check for the last address before addr, because addr
-			// is a return address and we want the call instruction.
-			if (lp.address >= addr && lp.op_advance >= op_index) {
-				if (!first) {
-					*file = last_file;
-					*line = last_line;
-					*column = last_column;
-					return true;
-				}
-
+		if (lp.truncated)
+			continue;
+
+		/*
+		 * Return previous entry when we pass the target address, because
+		 * the address may not be aligned perfectly on instruction boundary.
+		 */
+		if (lp.address > addr || (lp.address == addr && lp.op_advance > op_index)) {
+			if (first) {
 				// First address is already too large, skip to the next sequence.
 				debug_line_program_skip_to_sequence_end(&lp);
-			}
-
-			last_file = lp.file;
-			last_line = lp.line;
-			last_column = lp.column;
-		}
+				continue;
+			}
+
+			*file = last_file;
+			*line = last_line;
+			*column = last_column;
+			return true;
+		}
+
+		last_file = lp.file;
+		last_line = lp.line;
+		last_column = lp.column;
 	}
 
@@ -702,15 +706,15 @@
 }
 
-bool debug_line_get_address_info(uintptr_t addr, int op_index, const char **file_name, const char **dir_name, int *line, int *column)
-{
-	const uint8_t *data = find_line_program(addr);
+bool debug_line_get_address_info(debug_sections_t *scs, uintptr_t addr, int op_index, const char **file_name, const char **dir_name, int *line, int *column)
+{
+	const uint8_t *data = find_line_program(scs, addr);
 	if (data == NULL) {
 		return false;
 	}
 
-	const uint8_t *const debug_line_end = debug_line + debug_line_size;
+	const uint8_t *const debug_line_end = scs->debug_line + scs->debug_line_size;
 
 	struct debug_line_program_header hdr = { };
-	debug_line_program_header_parse(data, debug_line_end, &hdr);
+	debug_line_program_header_parse(scs, data, debug_line_end, &hdr);
 	assert(hdr.unit_end > data);
 	assert(hdr.unit_end <= debug_line_end);
@@ -727,8 +731,8 @@
 
 	if (file >= 0)
-		*file_name = get_file_name(&hdr, file, &dir);
+		*file_name = get_file_name(scs, &hdr, file, &dir);
 
 	if (dir >= 0)
-		*dir_name = get_dir_name(&hdr, dir);
+		*dir_name = get_dir_name(scs, &hdr, dir);
 
 	return true;
