2012-06-18 13 views
5

Adres początkowy można uzyskać za pomocą nazwy funkcji, jak znaleźć adres końcowy funkcji? Zostałem poproszony o to pytanie w wywiadzie:Jak znaleźć adres końcowy funkcji w C progu?

Rozważmy funkcję f(), którą napisałem, przekroczyła sekcję tekstową i rozpoczęła się od napisania sąsiedniej sekcji (sekcji danych). Jak mogę sobie z tym poradzić? Dodał także, że powinienem go obsłużyć za pomocą kodu C. Nie powinienem zobaczyć pliku mapy symboli i uzyskać adresu.

+0

Nie ma standardowego sposobu. Możesz spróbować wpisać adres następnej funkcji w pliku, a następnie odjąć - ale nie ma gwarancji, że zadziała. Na przykład linker może sortować funkcje w kolejności alfabetycznej, może więc zawierać miejsce na inne funkcje lub może dawać rozmiar ujemny. –

+1

Musisz podać architekturę i ABI, inaczej nie uzyskasz przydatnych odpowiedzi. –

+0

"Zadano mi to pytanie w wywiadzie" Podejrzewam, że źle zinterpretowałeś to pytanie, a oni pytali, jak powiedzieć, czy zacząłeś przypadkowo wykonywać dane. Odpowiedź brzmiałaby: "Zapobieganie wykonywaniu danych", inaczej znana jest funkcja sprzętowa do oznaczania pamięci jako nie do wykonania. – Ben

Odpowiedz

1

Nie można używać języka jako takiego, C nie ujawnia pojęcia "rozmiaru" dla funkcji.

Co możesz zrobić, to sprawdzić plik binarny twojego programu i przeanalizować tabele symboli i tak dalej.

+0

Czy istnieje jakaś biblioteka zalecająca pomoc w analizie tabeli symboli? O dziwo, nie jestem w stanie znaleźć "biblioteki elfów", ale tylko narzędzie wiersza poleceń –

2

Standard C nie gwarantuje, że istnieje coś takiego jak adres docelowy funkcji.

W praktyce funkcje nie muszą być pojedynczą ciągłą częścią pamięci, ale mogą się nakładać lub być fragmentowane na kilka części za pomocą optymalizatorów kodu.

Z tego powodu nie ma sposobu, aby znaleźć to w czasie wykonywania.

Co więcej, nie ma gwarancji, że "adres początkowy" otrzymany z adresu GetProcAddress lub adres URL funkcji (dla wskaźnika funkcji) będzie miał jakikolwiek związek z faktycznym kodem.

Wszystkie wskaźniki funkcji gwarantują, że po wywołaniu adresu funkcja zostanie wykonana. Nie gwarantuje, że kod faktycznie tam się znajduje. Może to być po prostu adres thunk, na przykład.

0

Twój kompilator prawdopodobnie utworzy plik z listą zestawów, a twój linker prawdopodobnie utworzy plik mapy. Pozwoli to sprawdzić, jak długo dana funkcja jest wykonywana ręcznie. Nie wiem, czy musisz określić rozmiar z poziomu samego programu C.

5

Za pomocą GCC można pobrać adres etykiety za pomocą operatora && (tak - &&, a nie &).
ten może być stosowany w sposób następujący:

void f(void) { 
    printf("Start %p End %p\n", f, &&f_end); 
    f_end: return; 
} 

nie daje dokładnie do końca, ponieważ istnieje jakiś kod epilog po etykiecie, ale myślę, że to wystarczy za odpowiedź wywiad.

Powiązane problemy