Skip to content

Commit b0cea44

Browse files
Code: added code for other tasks
1 parent d4c00d4 commit b0cea44

File tree

8 files changed

+433
-1
lines changed

8 files changed

+433
-1
lines changed

0x15-file_io/100-elf_header.c

Lines changed: 314 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,314 @@
1+
#include <elf.h>
2+
#include <sys/types.h>
3+
#include <sys/stat.h>
4+
#include <fcntl.h>
5+
#include <unistd.h>
6+
#include <stdio.h>
7+
#include <stdlib.h>
8+
9+
void check_elf(unsigned char *e_ident);
10+
void print_magic(unsigned char *e_ident);
11+
void print_class(unsigned char *e_ident);
12+
void print_data(unsigned char *e_ident);
13+
void print_version(unsigned char *e_ident);
14+
void print_abi(unsigned char *e_ident);
15+
void print_osabi(unsigned char *e_ident);
16+
void print_type(unsigned int e_type, unsigned char *e_ident);
17+
void print_entry(unsigned long int e_entry, unsigned char *e_ident);
18+
void close_elf(int elf);
19+
20+
/**
21+
* check_elf - Checks if a file is an ELF file.
22+
* @e_ident: A pointer to an array containing the ELF magic numbers.
23+
*
24+
* Description: If the file is not an ELF file - exit code 98.
25+
*/
26+
void check_elf(unsigned char *e_ident)
27+
{
28+
int index;
29+
30+
for (index = 0; index < 4; index++)
31+
{
32+
if (e_ident[index] != 127 &&
33+
e_ident[index] != 'E' &&
34+
e_ident[index] != 'L' &&
35+
e_ident[index] != 'F')
36+
{
37+
dprintf(STDERR_FILENO, "Error: Not an ELF file\n");
38+
exit(98);
39+
}
40+
}
41+
}
42+
43+
/**
44+
* print_magic - Prints the magic numbers of an ELF header.
45+
* @e_ident: A pointer to an array containing the ELF magic numbers.
46+
*
47+
* Description: Magic numbers are separated by spaces.
48+
*/
49+
void print_magic(unsigned char *e_ident)
50+
{
51+
int index;
52+
53+
printf(" Magic: ");
54+
55+
for (index = 0; index < EI_NIDENT; index++)
56+
{
57+
printf("%02x", e_ident[index]);
58+
59+
if (index == EI_NIDENT - 1)
60+
printf("\n");
61+
else
62+
printf(" ");
63+
}
64+
}
65+
66+
/**
67+
* print_class - Prints the class of an ELF header.
68+
* @e_ident: A pointer to an array containing the ELF class.
69+
*/
70+
void print_class(unsigned char *e_ident)
71+
{
72+
printf(" Class: ");
73+
74+
switch (e_ident[EI_CLASS])
75+
{
76+
case ELFCLASSNONE:
77+
printf("none\n");
78+
break;
79+
case ELFCLASS32:
80+
printf("ELF32\n");
81+
break;
82+
case ELFCLASS64:
83+
printf("ELF64\n");
84+
break;
85+
default:
86+
printf("<unknown: %x>\n", e_ident[EI_CLASS]);
87+
}
88+
}
89+
90+
/**
91+
* print_data - Prints the data of an ELF header.
92+
* @e_ident: A pointer to an array containing the ELF class.
93+
*/
94+
void print_data(unsigned char *e_ident)
95+
{
96+
printf(" Data: ");
97+
98+
switch (e_ident[EI_DATA])
99+
{
100+
case ELFDATANONE:
101+
printf("none\n");
102+
break;
103+
case ELFDATA2LSB:
104+
printf("2's complement, little endian\n");
105+
break;
106+
case ELFDATA2MSB:
107+
printf("2's complement, big endian\n");
108+
break;
109+
default:
110+
printf("<unknown: %x>\n", e_ident[EI_CLASS]);
111+
}
112+
}
113+
114+
/**
115+
* print_version - Prints the version of an ELF header.
116+
* @e_ident: A pointer to an array containing the ELF version.
117+
*/
118+
void print_version(unsigned char *e_ident)
119+
{
120+
printf(" Version: %d",
121+
e_ident[EI_VERSION]);
122+
123+
switch (e_ident[EI_VERSION])
124+
{
125+
case EV_CURRENT:
126+
printf(" (current)\n");
127+
break;
128+
default:
129+
printf("\n");
130+
break;
131+
}
132+
}
133+
134+
/**
135+
* print_osabi - Prints the OS/ABI of an ELF header.
136+
* @e_ident: A pointer to an array containing the ELF version.
137+
*/
138+
void print_osabi(unsigned char *e_ident)
139+
{
140+
printf(" OS/ABI: ");
141+
142+
switch (e_ident[EI_OSABI])
143+
{
144+
case ELFOSABI_NONE:
145+
printf("UNIX - System V\n");
146+
break;
147+
case ELFOSABI_HPUX:
148+
printf("UNIX - HP-UX\n");
149+
break;
150+
case ELFOSABI_NETBSD:
151+
printf("UNIX - NetBSD\n");
152+
break;
153+
case ELFOSABI_LINUX:
154+
printf("UNIX - Linux\n");
155+
break;
156+
case ELFOSABI_SOLARIS:
157+
printf("UNIX - Solaris\n");
158+
break;
159+
case ELFOSABI_IRIX:
160+
printf("UNIX - IRIX\n");
161+
break;
162+
case ELFOSABI_FREEBSD:
163+
printf("UNIX - FreeBSD\n");
164+
break;
165+
case ELFOSABI_TRU64:
166+
printf("UNIX - TRU64\n");
167+
break;
168+
case ELFOSABI_ARM:
169+
printf("ARM\n");
170+
break;
171+
case ELFOSABI_STANDALONE:
172+
printf("Standalone App\n");
173+
break;
174+
default:
175+
printf("<unknown: %x>\n", e_ident[EI_OSABI]);
176+
}
177+
}
178+
179+
/**
180+
* print_abi - Prints the ABI version of an ELF header.
181+
* @e_ident: A pointer to an array containing the ELF ABI version.
182+
*/
183+
void print_abi(unsigned char *e_ident)
184+
{
185+
printf(" ABI Version: %d\n",
186+
e_ident[EI_ABIVERSION]);
187+
}
188+
189+
/**
190+
* print_type - Prints the type of an ELF header.
191+
* @e_type: The ELF type.
192+
* @e_ident: A pointer to an array containing the ELF class.
193+
*/
194+
void print_type(unsigned int e_type, unsigned char *e_ident)
195+
{
196+
if (e_ident[EI_DATA] == ELFDATA2MSB)
197+
e_type >>= 8;
198+
199+
printf(" Type: ");
200+
201+
switch (e_type)
202+
{
203+
case ET_NONE:
204+
printf("NONE (None)\n");
205+
break;
206+
case ET_REL:
207+
printf("REL (Relocatable file)\n");
208+
break;
209+
case ET_EXEC:
210+
printf("EXEC (Executable file)\n");
211+
break;
212+
case ET_DYN:
213+
printf("DYN (Shared object file)\n");
214+
break;
215+
case ET_CORE:
216+
printf("CORE (Core file)\n");
217+
break;
218+
default:
219+
printf("<unknown: %x>\n", e_type);
220+
}
221+
}
222+
223+
/**
224+
* print_entry - Prints the entry point of an ELF header.
225+
* @e_entry: The address of the ELF entry point.
226+
* @e_ident: A pointer to an array containing the ELF class.
227+
*/
228+
void print_entry(unsigned long int e_entry, unsigned char *e_ident)
229+
{
230+
printf(" Entry point address: ");
231+
232+
if (e_ident[EI_DATA] == ELFDATA2MSB)
233+
{
234+
e_entry = ((e_entry << 8) & 0xFF00FF00) |
235+
((e_entry >> 8) & 0xFF00FF);
236+
e_entry = (e_entry << 16) | (e_entry >> 16);
237+
}
238+
239+
if (e_ident[EI_CLASS] == ELFCLASS32)
240+
printf("%#x\n", (unsigned int)e_entry);
241+
242+
else
243+
printf("%#lx\n", e_entry);
244+
}
245+
246+
/**
247+
* close_elf - Closes an ELF file.
248+
* @elf: The file descriptor of the ELF file.
249+
*
250+
* Description: If the file cannot be closed - exit code 98.
251+
*/
252+
void close_elf(int elf)
253+
{
254+
if (close(elf) == -1)
255+
{
256+
dprintf(STDERR_FILENO,
257+
"Error: Can't close fd %d\n", elf);
258+
exit(98);
259+
}
260+
}
261+
262+
/**
263+
* main - Displays the information contained in the
264+
* ELF header at the start of an ELF file.
265+
* @argc: The number of arguments supplied to the program.
266+
* @argv: An array of pointers to the arguments.
267+
*
268+
* Return: 0 on success.
269+
*
270+
* Description: If the file is not an ELF File or
271+
* the function fails - exit code 98.
272+
*/
273+
int main(int __attribute__((__unused__)) argc, char *argv[])
274+
{
275+
Elf64_Ehdr *header;
276+
int o, r;
277+
278+
o = open(argv[1], O_RDONLY);
279+
if (o == -1)
280+
{
281+
dprintf(STDERR_FILENO, "Error: Can't read file %s\n", argv[1]);
282+
exit(98);
283+
}
284+
header = malloc(sizeof(Elf64_Ehdr));
285+
if (header == NULL)
286+
{
287+
close_elf(o);
288+
dprintf(STDERR_FILENO, "Error: Can't read file %s\n", argv[1]);
289+
exit(98);
290+
}
291+
r = read(o, header, sizeof(Elf64_Ehdr));
292+
if (r == -1)
293+
{
294+
free(header);
295+
close_elf(o);
296+
dprintf(STDERR_FILENO, "Error: `%s`: No such file\n", argv[1]);
297+
exit(98);
298+
}
299+
300+
check_elf(header->e_ident);
301+
printf("ELF Header:\n");
302+
print_magic(header->e_ident);
303+
print_class(header->e_ident);
304+
print_data(header->e_ident);
305+
print_version(header->e_ident);
306+
print_osabi(header->e_ident);
307+
print_abi(header->e_ident);
308+
print_type(header->e_type, header->e_ident);
309+
print_entry(header->e_entry, header->e_ident);
310+
311+
free(header);
312+
close_elf(o);
313+
return (0);
314+
}

0 commit comments

Comments
 (0)