Wspólny format plików obiektów
Common Object File Format ( COFF , niemiecki ogólny obiekt format pliku ) jest w formacie binarnym do programów i plików obiektowych. Został wprowadzony przez AT&T dla systemu operacyjnego Unix System V i jest obecnie używany głównie w opartym na nim formacie PE dla Windows (patrz Portable Executable ). W przypadku rozszerzeń plików „cof”, „obj” lub „ lib ” są często używane, jeśli są dostępne, poza rozszerzeniami używanymi w PE .
fabuła
Format a.out był pierwotnie używany do plików wykonywalnych w systemie Unix . Jednak nie obsługuje to nowoczesnych rozwiązań, takich jak osadzone informacje debugowania lub biblioteki dynamiczne . Dlatego AT&T opracowało wspólny format plików obiektów dla wydania 3 systemu Unix V. Ponieważ oryginalny COFF był ograniczony pod względem projektu, różne warianty opracowano wśród producentów Uniksa (np.XCOFF firmy IBM dla AIX , ECOFF firmy SGI i inne). Wraz z wydaniem 4 Systemu V w 1989 roku AT&T zastąpiło COFF nowym formatem ELF ( format wykonywalny i łączący) opracowanym wspólnie z Sun Microsystems .
cechy
COFF umożliwił osadzenie informacji debugowania bezpośrednio w pliku binarnym. Biblioteki można łączyć dynamicznie i obsługiwać jako oddzielne pliki, dzięki czemu nie muszą stać się niezmienną, niewymienialną częścią pliku programu. W tym celu wszystkie adresy we wpisach relokacji są ładowane do pamięci wirtualnej aplikacji względem faktycznego adresu sekcji. Ten adres wymaga sekcji tylko dla czasu kompilacji, który ma być już ustawiony w programowaniu. Formaty opracowane zgodnie z COFF również mają te możliwości.
posługiwać się
Nowoczesne wersje Unix i Linux nie obsługują już COFF, ale nadal jest używany w systemach wbudowanych . W systemie Windows NT (i wcześniejszych) wariant COFF Portable Executable (PE, czasem także PE / COFF) jest standardowym formatem plików bibliotek i plików wykonywalnych, ale ten wariant różni się nieco od oryginalnego COFF.
Struktura
Plik COFF składa się z kilku części. Rozpoczyna się nagłówkiem pliku i opcjonalnym nagłówkiem . Po nim następuje kilka sekcji , składających się z nagłówka, sekcji danych i obszaru na wpisy numerów linii oraz obszaru na wpisy relokacji. Na końcu pliku znajduje się tablica symboli i tablica ciągów znaków .
Nagłówek pliku
Nagłówek pliku jest na początku pliku. Tam przechowywane są dane opisujące strukturę całego pliku. Obejmuje to magiczną liczbę , która jest różna dla różnych wariantów ( PE , XCOFF itp.), Uniksowy znacznik czasu z czasem utworzenia pliku oraz położenie i rozmiar innych sekcji. Oprócz używania flagi, różne właściwości pliku do zdefiniowania (np. Czy jest wykonywalny).
struct filehdr {
unsigned short f_magic; /* Magische Zahl */
unsigned short f_nscns; /* Anzahl der Sektionen in der Datei */
long f_timdat; /* Zeitstempel der Erstellung */
long f_symptr; /* Zeiger zur Symboltabelle */
long f_nsyms; /* Größe der Symboltabelle */
unsigned short f_opthdr; /* Größe der "optional header" */
unsigned short f_flags; /* Flags */
};
Opcjonalny nagłówek
Opcjonalny nagłówek zawiera różne dane w zależności od wariantu COFF. Często jest używany do innych informacji wymaganych do realizacji (np. Adres wejściowy). Ponieważ może mieć różne długości, jego rozmiar jest przechowywany w „Nagłówku pliku”.
Nagłówek sekcji
Nagłówka sekcja zawiera dane dotyczące sekcji, w szczególności, jak duże to jest i gdzie to powinno być załadowane do pamięci wirtualnej . W przypadku plików wykonywalnych zwykle początek pamięci, tj. H. pierwsza sekcja jest ładowana pod adres 0; może to wyglądać inaczej w przypadku połączonych danych. Zawierają również wskaźnik i rozmiar pozycji numerów linii i pozycji relokacji.
struct sectionhdr {
char s_name[8]; /* Name der Sektion */
unsigned long s_paddr; /* Speicheradresse, an die diese Sektion geladen werden soll*/
unsigned long s_vaddr; /* virtuelle Adresse, an die diese Sektion geladen werden soll */
unsigned long s_size; /* Größe der Sektion (inklusive Header)*/
unsigned long s_scnptr; /* Zeiger zu den Daten dieser Sektion */
unsigned long s_relptr; /* Zeiger zu den Relokationseinträgen dieser Sektion */
unsigned long s_lnnoptr; /* Zeiger zu dem Zeilennummerneinträgen dieser Sektion */
unsigned short s_nreloc; /* Anzahl der Relokationseinträge */
unsigned short s_nlnno; /* Anzahl der Zeilennummerneinträge */
unsigned long s_flags; /* Flags */
};
Sekcja danych
Sekcja danych może mieć różną długość. Zawiera rzeczywiste dane w pliku. Są to zwykle instrukcje w kodzie maszynowym , miejsce na zmienne i dane wymagane do wykonania - w skrócie rzeczywisty program.
Wpis relokacji
Wpis relokacji określa, gdzie w sekcji danych można znaleźć symbole. Jest to definiowane indywidualnie dla każdego symbolu.
typedef struct reloc{
unsigned long r_vaddr; /* Adresse für die Relokation */
unsigned long r_symndx; /* Symbol, für das die Relokation gilt */
unsigned short r_type; /* Type der Relokation*/
};
Wprowadzanie numeru wiersza
Numer linii określa, która linia w kodzie źródłowym odpowiada instrukcji w kodzie maszynowym. Jest to szczególnie ważne w przypadku debugowania aplikacji. Każda sekcja ma własną tabelę numerów linii. Wiersze liczone są indywidualnie dla każdej funkcji w sekcji.
typedef struct lineno{
union l_addr{
unsigned long l_symndx; /* Index des Namens der Funktion */
unsigned long l_paddr; /* Adresse der Zeilennummer */
};
unsigned short l_lnno; /* Zeilennummer */
};
Numery wierszy są liczone od początku każdej funkcji od 0. W przypadku wiersza, w którym zaczyna się funkcja, wpis z l_lnno = 0i symbol utworzonej funkcji l_symndx. Dla każdego dodatkowego wiersza funkcji tworzony jest wpis zawierający liczbę wierszy od początku funkcji jako l_lnnooraz adres pierwszej instrukcji z tego wiersza jako l_paddr.
Tabela symboli
Tablica symboli zawiera informacje o symbolach w pliku. Symbole to np. B. Funkcje lub zmienne, które mogą być używane przez inne programy. Rozmiar i położenie tablicy symboli są określone w nagłówku pliku . Tablica symboli składa się z wpisów formularza
typedef struct sysent{
union e {
char e_name[8]; /* Name des Symbols */
struct e {
unsigned long e_zeroes; /* Falls 0, ist der Name des Symbols in der Zeichenkettentabelle angelegt*/
unsigned long e_offset; /* Position des Symbols in der Zeichenkettentabelle */
};
};
unsigned long e_value; /* Wert (in der Regel Adresse) des Symbols */
short e_scnum; /* Sektion */
unsigned short e_type; /* Datentyp */
unsigned char e_sclass; /* Speicherklasse */
unsigned char e_numaux; /* Anzahl zusätzlicher Einträge*/
};
Nazwa symbolu jest e_namezapisywana, jeśli ma osiem znaków lub mniej. W przeciwnym razie jest przechowywany w tabeli ciągów znaków, a następnie jest e_zeros = 0i e_offsetwskazuje pozycję tego wpisu w tabeli ciągów znaków. „Wartość” symbolu jest e_valuezapisywana w. Zwykle jest to adres, pod którym przechowywany jest ten symbol, co z kolei zależy od typu danych i klasy pamięci, w której jest e_sclassprzechowywany. e_typeokreśla typ danych symbolu. Może to być typ elementarny (int, float itp.) Lub typ złożony (struct, union). Ponadto symbol może definiować wartość, wskaźnik, pole („tablicę”) lub funkcję zwracającą tę wartość. e_classokreśla klasę pamięci, tj. gdzie i jak symbol jest przechowywany (np. może to być symbol zewnętrzny, argument funkcji, zmienna globalna lub statyczna itp.). W zależności od rodzaju symbolu mogą nastąpić dodatkowe wpisy. Podana jest również liczba tych wpisów e_numaux.
Tabela strun
Tablica ciągów następuje po pliku na końcu. Rozpoczyna się liczbą całkowitą, w której przechowywana jest długość tabeli. Następnie wszystkie struny następują po sobie. Aby odczytać ciąg znaków, musisz znać jego pozycję i możesz zacząć czytać w tym miejscu. Ciągi są zakończone zerem .
Indywidualne dowody
- ↑ Common Object File Format Texas Instruments, dostęp 8 marca 2014
- ↑ Informacje na SCO System V Release 3 ( pamiątka z oryginałem od 9 marca 2014 roku w Internet Archive ) Info: archiwum Link został automatycznie wstawiony i jeszcze nie sprawdzone. Sprawdź oryginalny i archiwalny link zgodnie z instrukcjami, a następnie usuń to powiadomienie. HP, dostęp 8 marca 2014
- ^ XCOFF Object File Format IBM, dostęp 8 marca 2013
- ↑ Specyfikacja formatu pliku obiektu / tabeli symboli Compaq / HP, dostęp 8 marca 2014
- ↑ Typer wykonywalnego ( pamiątka z oryginałem od 9 marca 2014 roku w Internet Archive ) Info: archiwum Link został wstawiony automatycznie i nie została jeszcze sprawdzona. Sprawdź oryginalny i archiwalny link zgodnie z instrukcjami, a następnie usuń to powiadomienie. Linux.org, dostęp 8 marca 2014
- ↑ PE and COFF Specification , Microsoft Developer Network, dostęp 8 marca 2014
linki internetowe
- Specyfikacja DJGPP COFF - więcej szczegółów na temat implementacji COFF
- MIPS COFF jako typy danych C.
- Informacje firmy Microsoft COFF