@@ -32,6 +32,134 @@ static ssize_t procfile_read(struct file *, char __user *, size_t, loff_t *);
3232static ssize_t procfile_write (struct file * , const char __user * , size_t ,
3333 loff_t * );
3434
35+ static void print_memory_layout (struct seq_file * m , struct task_struct * task ,
36+ unsigned long bss_start , unsigned long bss_end ,
37+ unsigned long heap_start ,
38+ unsigned long heap_end ,
39+ unsigned long stack_start ,
40+ unsigned long stack_end , unsigned long elf_base )
41+ {
42+ seq_puts (m , "\nMemory Layout:\n" );
43+ seq_puts (m , "----------------------------------------------------------"
44+ "----------------------\n" );
45+ seq_printf (m , " Code Section: 0x%016lx - 0x%016lx\n" ,
46+ task -> mm -> start_code , task -> mm -> end_code );
47+ seq_printf (m , " Data Section: 0x%016lx - 0x%016lx\n" ,
48+ task -> mm -> start_data , task -> mm -> end_data );
49+ seq_printf (m , " BSS Section: 0x%016lx - 0x%016lx\n" , bss_start ,
50+ bss_end );
51+ seq_printf (m , " Heap: 0x%016lx - 0x%016lx\n" , heap_start ,
52+ heap_end );
53+ seq_printf (m , " Stack: 0x%016lx - 0x%016lx\n" , stack_start ,
54+ stack_end );
55+ seq_printf (m , " ELF Base: 0x%016lx\n" , elf_base );
56+ }
57+
58+ static void print_memory_layout_visualization (
59+ struct seq_file * m , struct task_struct * task , unsigned long bss_start ,
60+ unsigned long bss_end , unsigned long heap_start , unsigned long heap_end ,
61+ unsigned long stack_start , unsigned long stack_end )
62+ {
63+ struct memory_region regions [5 ];
64+ unsigned long total_size ;
65+ unsigned long lowest_addr = task -> mm -> start_code ;
66+ unsigned long highest_addr = stack_start ;
67+ const int BAR_WIDTH = 50 ;
68+ int widths [5 ];
69+ char viz_buf [256 ];
70+ int i ;
71+
72+ /* Setup regions */
73+ regions [0 ].name = "CODE" ;
74+ regions [0 ].size = task -> mm -> end_code - task -> mm -> start_code ;
75+ regions [0 ].exists = (regions [0 ].size > 0 );
76+
77+ regions [1 ].name = "DATA" ;
78+ regions [1 ].size = task -> mm -> end_data - task -> mm -> start_data ;
79+ regions [1 ].exists = (regions [1 ].size > 0 );
80+
81+ regions [2 ].name = "BSS" ;
82+ regions [2 ].size = bss_end - bss_start ;
83+ regions [2 ].exists = (regions [2 ].size > 0 );
84+
85+ regions [3 ].name = "HEAP" ;
86+ regions [3 ].size = heap_end - heap_start ;
87+ regions [3 ].exists = (regions [3 ].size > 0 );
88+
89+ regions [4 ].name = "STACK" ;
90+ regions [4 ].size = stack_start - stack_end ;
91+ regions [4 ].exists = (regions [4 ].size > 0 );
92+
93+ /* Calculate total size */
94+ total_size = 0 ;
95+ for (i = 0 ; i < 5 ; i ++ ) {
96+ if (regions [i ].exists )
97+ total_size += regions [i ].size ;
98+ }
99+
100+ if (total_size == 0 )
101+ return ;
102+
103+ /* Calculate proportional widths */
104+ for (i = 0 ; i < 5 ; i ++ ) {
105+ widths [i ] =
106+ calculate_bar_width (regions [i ].size , total_size , BAR_WIDTH );
107+ }
108+
109+ seq_puts (m , "\n" );
110+ seq_puts (m , "Memory Layout Visualization:\n" );
111+ seq_puts (m , "------------------------------------------"
112+ "----------------"
113+ "----------------------\n" );
114+ seq_printf (m , "Low: 0x%016lx\n\n" , lowest_addr );
115+
116+ /* Generate visualization for each region */
117+ for (i = 0 ; i < 5 ; i ++ ) {
118+ if (generate_region_visualization (& regions [i ], widths [i ],
119+ BAR_WIDTH , viz_buf ,
120+ sizeof (viz_buf )) > 0 ) {
121+ seq_puts (m , viz_buf );
122+ }
123+ }
124+
125+ seq_printf (m , "High: 0x%016lx\n" , highest_addr );
126+ seq_puts (m , "------------------------------------------"
127+ "----------------"
128+ "----------------------\n" );
129+ }
130+
131+ static void print_thread_info_line (struct seq_file * m ,
132+ struct task_struct * thread )
133+ {
134+ char state_char ;
135+ char cpu_affinity [32 ];
136+ int cpu_mask [8 ] = {0 };
137+ int i ;
138+ u64 total_ns , delta_ns , usage_permyriad ;
139+
140+ /* Get thread state using helper function */
141+ state_char = get_thread_state_char (READ_ONCE (thread -> __state ));
142+
143+ /* CPU usage for this thread */
144+ total_ns = (u64 )thread -> utime + (u64 )thread -> stime ;
145+ delta_ns = ktime_get_ns () - thread -> start_time ;
146+ usage_permyriad = compute_usage_permyriad (total_ns , delta_ns );
147+
148+ /* Build CPU affinity mask array (show first 8 CPUs) */
149+ for (i = 0 ; i < 8 && i < nr_cpu_ids ; i ++ ) {
150+ cpu_mask [i ] = cpumask_test_cpu (i , & thread -> cpus_mask ) ? 1 : 0 ;
151+ }
152+ build_cpu_affinity_string (cpu_mask , 8 , cpu_affinity ,
153+ sizeof (cpu_affinity ));
154+
155+ seq_printf (m ,
156+ "%-5d %-15.15s %4llu.%02llu %c %4d %4d %s\n" ,
157+ thread -> pid , thread -> comm , (usage_permyriad / 100 ),
158+ (usage_permyriad % 100 ), state_char ,
159+ thread -> prio - 120 , /* Convert to nice value */
160+ task_nice (thread ), cpu_affinity );
161+ }
162+
35163// det proc file_operations starts
36164
37165/* Find the lower boundary of the stack VMA
@@ -135,89 +263,11 @@ static int elfdet_show(struct seq_file *m, void *v)
135263 seq_printf (m , "Name: %s\n" , task -> comm );
136264 seq_printf (m , "CPU Usage: %llu.%02llu%%\n" ,
137265 (usage_permyriad / 100 ), (usage_permyriad % 100 ));
138- seq_puts (m , "\nMemory Layout:\n" );
139- seq_puts (m , "----------------------------------------------------------"
140- "----------------------\n" );
141- seq_printf (m , " Code Section: 0x%016lx - 0x%016lx\n" ,
142- task -> mm -> start_code , task -> mm -> end_code );
143- seq_printf (m , " Data Section: 0x%016lx - 0x%016lx\n" ,
144- task -> mm -> start_data , task -> mm -> end_data );
145- seq_printf (m , " BSS Section: 0x%016lx - 0x%016lx\n" , bss_start ,
146- bss_end );
147- seq_printf (m , " Heap: 0x%016lx - 0x%016lx\n" , heap_start ,
148- heap_end );
149- seq_printf (m , " Stack: 0x%016lx - 0x%016lx\n" , stack_start ,
150- stack_end );
151- seq_printf (m , " ELF Base: 0x%016lx\n" , elf_base );
152-
153- /* Visual representation of memory layout */
154- {
155- struct memory_region regions [5 ];
156- unsigned long total_size ;
157- unsigned long lowest_addr = task -> mm -> start_code ;
158- unsigned long highest_addr = stack_start ;
159- const int BAR_WIDTH = 50 ;
160- int widths [5 ];
161- char viz_buf [256 ];
162- int i ;
163-
164- /* Setup regions */
165- regions [0 ].name = "CODE" ;
166- regions [0 ].size = task -> mm -> end_code - task -> mm -> start_code ;
167- regions [0 ].exists = (regions [0 ].size > 0 );
168-
169- regions [1 ].name = "DATA" ;
170- regions [1 ].size = task -> mm -> end_data - task -> mm -> start_data ;
171- regions [1 ].exists = (regions [1 ].size > 0 );
172-
173- regions [2 ].name = "BSS" ;
174- regions [2 ].size = bss_end - bss_start ;
175- regions [2 ].exists = (regions [2 ].size > 0 );
176-
177- regions [3 ].name = "HEAP" ;
178- regions [3 ].size = heap_end - heap_start ;
179- regions [3 ].exists = (regions [3 ].size > 0 );
180-
181- regions [4 ].name = "STACK" ;
182- regions [4 ].size = stack_start - stack_end ;
183- regions [4 ].exists = (regions [4 ].size > 0 );
184-
185- /* Calculate total size */
186- total_size = 0 ;
187- for (i = 0 ; i < 5 ; i ++ ) {
188- if (regions [i ].exists )
189- total_size += regions [i ].size ;
190- }
191-
192- if (total_size > 0 ) {
193- /* Calculate proportional widths */
194- for (i = 0 ; i < 5 ; i ++ ) {
195- widths [i ] = calculate_bar_width (
196- regions [i ].size , total_size , BAR_WIDTH );
197- }
198-
199- seq_puts (m , "\n" );
200- seq_puts (m , "Memory Layout Visualization:\n" );
201- seq_puts (m , "------------------------------------------"
202- "----------------"
203- "----------------------\n" );
204- seq_printf (m , "Low: 0x%016lx\n\n" , lowest_addr );
205-
206- /* Generate visualization for each region */
207- for (i = 0 ; i < 5 ; i ++ ) {
208- if (generate_region_visualization (
209- & regions [i ], widths [i ], BAR_WIDTH ,
210- viz_buf , sizeof (viz_buf )) > 0 ) {
211- seq_puts (m , viz_buf );
212- }
213- }
214-
215- seq_printf (m , "High: 0x%016lx\n" , highest_addr );
216- seq_puts (m , "------------------------------------------"
217- "----------------"
218- "----------------------\n" );
219- }
220- }
266+ print_memory_layout (m , task , bss_start , bss_end , heap_start , heap_end ,
267+ stack_start , stack_end , elf_base );
268+ print_memory_layout_visualization (m , task , bss_start , bss_end ,
269+ heap_start , heap_end , stack_start ,
270+ stack_end );
221271
222272 return 0 ;
223273}
@@ -227,7 +277,6 @@ static int elfdet_threads_show(struct seq_file *m, void *v)
227277{
228278 struct task_struct * task , * thread ;
229279 int ret , thread_count = 0 ;
230- u64 total_ns , delta_ns , usage_permyriad ;
231280
232281 ret = kstrtoint (buff , 10 , & user_pid );
233282 if (ret != 0 ) {
@@ -252,36 +301,8 @@ static int elfdet_threads_show(struct seq_file *m, void *v)
252301 rcu_read_lock ();
253302 for_each_thread (task , thread )
254303 {
255- char state_char ;
256- char cpu_affinity [32 ];
257- int cpu_mask [8 ] = {0 };
258- int i ;
259-
260304 thread_count ++ ;
261-
262- /* Get thread state using helper function */
263- state_char = get_thread_state_char (READ_ONCE (thread -> __state ));
264-
265- /* CPU usage for this thread */
266- total_ns = (u64 )thread -> utime + (u64 )thread -> stime ;
267- delta_ns = ktime_get_ns () - thread -> start_time ;
268- usage_permyriad = compute_usage_permyriad (total_ns , delta_ns );
269-
270- /* Build CPU affinity mask array (show first 8 CPUs) */
271- for (i = 0 ; i < 8 && i < nr_cpu_ids ; i ++ ) {
272- cpu_mask [i ] =
273- cpumask_test_cpu (i , & thread -> cpus_mask ) ? 1 : 0 ;
274- }
275- build_cpu_affinity_string (cpu_mask , 8 , cpu_affinity ,
276- sizeof (cpu_affinity ));
277-
278- seq_printf (
279- m ,
280- "%-5d %-15.15s %4llu.%02llu %c %4d %4d %s\n" ,
281- thread -> pid , thread -> comm , (usage_permyriad / 100 ),
282- (usage_permyriad % 100 ), state_char ,
283- thread -> prio - 120 , /* Convert to nice value */
284- task_nice (thread ), cpu_affinity );
305+ print_thread_info_line (m , thread );
285306 }
286307 rcu_read_unlock ();
287308
0 commit comments