2010-04-06 32 views
6

Tôi đang thực hiện một số thử nghiệm và muốn có thể xem những gì được lưu trên ngăn xếp trong suốt cuộc gọi hệ thống (trạng thái đã lưu của quy trình sử dụng đất). Theo http://lxr.linux.no/#linux+v2.6.30.1/arch/x86/kernel/entry_32.S nó cho thấy rằng các giá trị khác nhau của sổ đăng ký được lưu tại các vị trí cụ thể đó cho con trỏ ngăn xếp. Đây là mã tôi đã cố gắng sử dụng để kiểm tra những gì được lưu trên ngăn xếp (đây là trong một cuộc gọi hệ thống tùy chỉnh mà tôi đã tạo):Làm cách nào để xác định giá trị được lưu trên ngăn xếp?

asm("movl 0x1C(%esp), %ecx"); 
asm("movl %%ecx, %0" : "=r" (value)); 

giá trị không dài.

Hiện tại, giá trị này không phải là giá trị được mong đợi (nó hiển thị giá trị 0 được lưu cho giá trị người dùng của ds).

Tôi có đang truy cập chính xác phần bù của con trỏ ngăn xếp không?

Một khả năng khác có thể là tôi có thể sử dụng trình gỡ lỗi như GDB để kiểm tra nội dung ngăn xếp trong khi ở hạt nhân? Tôi không có nhiều sử dụng rộng rãi với gỡ lỗi và không chắc chắn về cách gỡ lỗi mã bên trong hạt nhân. Bất kỳ sự giúp đỡ nào cũng được đánh giá cao.

Trả lời

0

Hãy nhớ rằng x86_64 mã thường sẽ vượt qua giá trị trong sổ đăng ký (vì nó có quá nhiều) nên không có gì sẽ được trên ngăn xếp. Kiểm tra đầu ra trung gian gcc (-S IIRC) và tìm push trong hội đồng.

Tôi không quen với việc gỡ lỗi mã hạt nhân, nhưng gdb chắc chắn sẽ đẹp hơn khi kiểm tra chồng tương tác.

4

Lắp ráp nội tuyến phức tạp hơn vẻ bề ngoài. Đang cố gắng che giấu những lo ngại cho GCC một cách ngắn gọn:

  1. Nếu nó sửa đổi sổ đăng ký bộ xử lý, cần phải đặt những thanh ghi này vào danh sách theo dõi. Điều quan trọng cần lưu ý là danh sách phím tắt phải chứa TẤT CẢ sổ đăng ký mà bạn đã thay đổi trực tiếp (đọc rõ ràng) hoặc gián tiếp (đọc hoàn toàn);
  2. Để củng cố (1), hoạt động toán học có điều kiện cũng thay đổi sổ đăng ký, được gọi là cờ trạng thái (không, mang, tràn, v.v.), vì vậy bạn phải thông báo bằng cách thêm "cc" vào danh sách phím tắt;
  3. Thêm "bộ nhớ" nếu nó thay đổi vị trí bộ nhớ khác (đọc ngẫu nhiên);
  4. Thêm dễ bay hơi từ khóa nếu nó sửa đổi bộ nhớ không được đề cập trên các đối số đầu vào/đầu ra;

Sau đó, mã của bạn trở thành:

asm("movl 0x1C(%%esp), %0;" 
    : "=r" (value) 
    : /* no inputs :) */ 
    /* no modified registers */ 
); 

Đối số đầu ra là không cần thiết để được vào danh sách clobber vì GCC đã biết nó sẽ được thay đổi.

Ngoài ra, kể từ khi tất cả các bạn muốn là giá trị của ESP đăng ký, bạn có thể tránh tất cả sự đau đớn làm điều này:

register int esp asm("esp"); 
esp += 0x1C; 

Nó có thể không giải quyết vấn đề của bạn, nhưng đó là cách để đi. Để tham khảo, hãy kiểm tra this, thisthis.

5

Không cần lắp ráp nội tuyến. Các trạng thái lưu trữ mà entry_32.S đẩy vào ngăn xếp cho một syscall được đặt ra như một struct pt_regs, và bạn có thể nhận được một con trỏ đến nó như thế này (bạn sẽ cần phải bao gồm <asm/ptrace.h> và/hoặc <asm/processor.h> trực tiếp hoặc gián tiếp):

struct pt_regs *regs = task_pt_regs(current);

Các vấn đề liên quan