70
Michael Spacefalcon <msokolov@ivan.Harhan.ORG>
parents:
diff
changeset
|
1 /*
|
Michael Spacefalcon <msokolov@ivan.Harhan.ORG>
parents:
diff
changeset
|
2 * This C module implements the "basics" of TI COFF image analysis.
|
Michael Spacefalcon <msokolov@ivan.Harhan.ORG>
parents:
diff
changeset
|
3 */
|
Michael Spacefalcon <msokolov@ivan.Harhan.ORG>
parents:
diff
changeset
|
4
|
Michael Spacefalcon <msokolov@ivan.Harhan.ORG>
parents:
diff
changeset
|
5 #include <sys/types.h>
|
Michael Spacefalcon <msokolov@ivan.Harhan.ORG>
parents:
diff
changeset
|
6 #include <sys/file.h>
|
Michael Spacefalcon <msokolov@ivan.Harhan.ORG>
parents:
diff
changeset
|
7 #include <sys/stat.h>
|
Michael Spacefalcon <msokolov@ivan.Harhan.ORG>
parents:
diff
changeset
|
8 #include <sys/mman.h>
|
Michael Spacefalcon <msokolov@ivan.Harhan.ORG>
parents:
diff
changeset
|
9 #include <stdio.h>
|
Michael Spacefalcon <msokolov@ivan.Harhan.ORG>
parents:
diff
changeset
|
10 #include <stdlib.h>
|
Michael Spacefalcon <msokolov@ivan.Harhan.ORG>
parents:
diff
changeset
|
11 #include <unistd.h>
|
Michael Spacefalcon <msokolov@ivan.Harhan.ORG>
parents:
diff
changeset
|
12 #include <time.h>
|
Michael Spacefalcon <msokolov@ivan.Harhan.ORG>
parents:
diff
changeset
|
13 #include "filestruct.h"
|
Michael Spacefalcon <msokolov@ivan.Harhan.ORG>
parents:
diff
changeset
|
14 #include "globals.h"
|
Michael Spacefalcon <msokolov@ivan.Harhan.ORG>
parents:
diff
changeset
|
15
|
Michael Spacefalcon <msokolov@ivan.Harhan.ORG>
parents:
diff
changeset
|
16 mmap_objfile()
|
Michael Spacefalcon <msokolov@ivan.Harhan.ORG>
parents:
diff
changeset
|
17 {
|
Michael Spacefalcon <msokolov@ivan.Harhan.ORG>
parents:
diff
changeset
|
18 int fd;
|
Michael Spacefalcon <msokolov@ivan.Harhan.ORG>
parents:
diff
changeset
|
19 struct stat st;
|
Michael Spacefalcon <msokolov@ivan.Harhan.ORG>
parents:
diff
changeset
|
20
|
Michael Spacefalcon <msokolov@ivan.Harhan.ORG>
parents:
diff
changeset
|
21 fd = open(objfilename, O_RDONLY);
|
Michael Spacefalcon <msokolov@ivan.Harhan.ORG>
parents:
diff
changeset
|
22 if (fd < 0) {
|
Michael Spacefalcon <msokolov@ivan.Harhan.ORG>
parents:
diff
changeset
|
23 perror(objfilename);
|
Michael Spacefalcon <msokolov@ivan.Harhan.ORG>
parents:
diff
changeset
|
24 exit(1);
|
Michael Spacefalcon <msokolov@ivan.Harhan.ORG>
parents:
diff
changeset
|
25 }
|
Michael Spacefalcon <msokolov@ivan.Harhan.ORG>
parents:
diff
changeset
|
26 fstat(fd, &st);
|
Michael Spacefalcon <msokolov@ivan.Harhan.ORG>
parents:
diff
changeset
|
27 if (!S_ISREG(st.st_mode)) {
|
Michael Spacefalcon <msokolov@ivan.Harhan.ORG>
parents:
diff
changeset
|
28 fprintf(stderr, "error: %s is not a regular file\n",
|
Michael Spacefalcon <msokolov@ivan.Harhan.ORG>
parents:
diff
changeset
|
29 objfilename);
|
Michael Spacefalcon <msokolov@ivan.Harhan.ORG>
parents:
diff
changeset
|
30 exit(1);
|
Michael Spacefalcon <msokolov@ivan.Harhan.ORG>
parents:
diff
changeset
|
31 }
|
Michael Spacefalcon <msokolov@ivan.Harhan.ORG>
parents:
diff
changeset
|
32 objfile_tot_size = st.st_size;
|
Michael Spacefalcon <msokolov@ivan.Harhan.ORG>
parents:
diff
changeset
|
33 filemap = mmap(NULL, objfile_tot_size, PROT_READ, MAP_PRIVATE, fd, 0L);
|
Michael Spacefalcon <msokolov@ivan.Harhan.ORG>
parents:
diff
changeset
|
34 if (filemap == MAP_FAILED) {
|
Michael Spacefalcon <msokolov@ivan.Harhan.ORG>
parents:
diff
changeset
|
35 perror("mmap");
|
Michael Spacefalcon <msokolov@ivan.Harhan.ORG>
parents:
diff
changeset
|
36 exit(1);
|
Michael Spacefalcon <msokolov@ivan.Harhan.ORG>
parents:
diff
changeset
|
37 }
|
Michael Spacefalcon <msokolov@ivan.Harhan.ORG>
parents:
diff
changeset
|
38 close(fd);
|
Michael Spacefalcon <msokolov@ivan.Harhan.ORG>
parents:
diff
changeset
|
39 }
|
Michael Spacefalcon <msokolov@ivan.Harhan.ORG>
parents:
diff
changeset
|
40
|
Michael Spacefalcon <msokolov@ivan.Harhan.ORG>
parents:
diff
changeset
|
41 unsigned
|
Michael Spacefalcon <msokolov@ivan.Harhan.ORG>
parents:
diff
changeset
|
42 get_u16(ptr)
|
Michael Spacefalcon <msokolov@ivan.Harhan.ORG>
parents:
diff
changeset
|
43 u_char *ptr;
|
Michael Spacefalcon <msokolov@ivan.Harhan.ORG>
parents:
diff
changeset
|
44 {
|
Michael Spacefalcon <msokolov@ivan.Harhan.ORG>
parents:
diff
changeset
|
45 return ptr[0] | ptr[1] << 8;
|
Michael Spacefalcon <msokolov@ivan.Harhan.ORG>
parents:
diff
changeset
|
46 }
|
Michael Spacefalcon <msokolov@ivan.Harhan.ORG>
parents:
diff
changeset
|
47
|
Michael Spacefalcon <msokolov@ivan.Harhan.ORG>
parents:
diff
changeset
|
48 unsigned
|
Michael Spacefalcon <msokolov@ivan.Harhan.ORG>
parents:
diff
changeset
|
49 get_u32(ptr)
|
Michael Spacefalcon <msokolov@ivan.Harhan.ORG>
parents:
diff
changeset
|
50 u_char *ptr;
|
Michael Spacefalcon <msokolov@ivan.Harhan.ORG>
parents:
diff
changeset
|
51 {
|
Michael Spacefalcon <msokolov@ivan.Harhan.ORG>
parents:
diff
changeset
|
52 return ptr[0] | ptr[1] << 8 | ptr[2] << 16 | ptr[3] << 24;
|
Michael Spacefalcon <msokolov@ivan.Harhan.ORG>
parents:
diff
changeset
|
53 }
|
Michael Spacefalcon <msokolov@ivan.Harhan.ORG>
parents:
diff
changeset
|
54
|
Michael Spacefalcon <msokolov@ivan.Harhan.ORG>
parents:
diff
changeset
|
55 initial_parse_hdr()
|
Michael Spacefalcon <msokolov@ivan.Harhan.ORG>
parents:
diff
changeset
|
56 {
|
Michael Spacefalcon <msokolov@ivan.Harhan.ORG>
parents:
diff
changeset
|
57 unsigned symtab_offset;
|
Michael Spacefalcon <msokolov@ivan.Harhan.ORG>
parents:
diff
changeset
|
58
|
Michael Spacefalcon <msokolov@ivan.Harhan.ORG>
parents:
diff
changeset
|
59 filehdr_struct = (struct external_filehdr *) filemap;
|
Michael Spacefalcon <msokolov@ivan.Harhan.ORG>
parents:
diff
changeset
|
60 if (get_u16(filehdr_struct->f_magic) != 0xC2) {
|
Michael Spacefalcon <msokolov@ivan.Harhan.ORG>
parents:
diff
changeset
|
61 fprintf(stderr, "error: %s is not a TI COFF2 object\n",
|
Michael Spacefalcon <msokolov@ivan.Harhan.ORG>
parents:
diff
changeset
|
62 objfilename);
|
Michael Spacefalcon <msokolov@ivan.Harhan.ORG>
parents:
diff
changeset
|
63 exit(1);
|
Michael Spacefalcon <msokolov@ivan.Harhan.ORG>
parents:
diff
changeset
|
64 }
|
Michael Spacefalcon <msokolov@ivan.Harhan.ORG>
parents:
diff
changeset
|
65 if (get_u16(filehdr_struct->f_target_id) != 0x97) {
|
Michael Spacefalcon <msokolov@ivan.Harhan.ORG>
parents:
diff
changeset
|
66 fprintf(stderr, "error: TI COFF object %s is not for TMS470\n",
|
Michael Spacefalcon <msokolov@ivan.Harhan.ORG>
parents:
diff
changeset
|
67 objfilename);
|
Michael Spacefalcon <msokolov@ivan.Harhan.ORG>
parents:
diff
changeset
|
68 exit(1);
|
Michael Spacefalcon <msokolov@ivan.Harhan.ORG>
parents:
diff
changeset
|
69 }
|
Michael Spacefalcon <msokolov@ivan.Harhan.ORG>
parents:
diff
changeset
|
70 if (get_u16(filehdr_struct->f_opthdr)) {
|
Michael Spacefalcon <msokolov@ivan.Harhan.ORG>
parents:
diff
changeset
|
71 fprintf(stderr,
|
Michael Spacefalcon <msokolov@ivan.Harhan.ORG>
parents:
diff
changeset
|
72 "error: %s has the \"optional\" header present\n",
|
Michael Spacefalcon <msokolov@ivan.Harhan.ORG>
parents:
diff
changeset
|
73 objfilename);
|
Michael Spacefalcon <msokolov@ivan.Harhan.ORG>
parents:
diff
changeset
|
74 exit(1);
|
Michael Spacefalcon <msokolov@ivan.Harhan.ORG>
parents:
diff
changeset
|
75 }
|
Michael Spacefalcon <msokolov@ivan.Harhan.ORG>
parents:
diff
changeset
|
76 sections_raw = (struct external_scnhdr *)
|
Michael Spacefalcon <msokolov@ivan.Harhan.ORG>
parents:
diff
changeset
|
77 (filemap + sizeof(struct external_filehdr));
|
Michael Spacefalcon <msokolov@ivan.Harhan.ORG>
parents:
diff
changeset
|
78 nsections = get_u16(filehdr_struct->f_nscns);
|
Michael Spacefalcon <msokolov@ivan.Harhan.ORG>
parents:
diff
changeset
|
79 symtab_offset = get_u32(filehdr_struct->f_symptr);
|
Michael Spacefalcon <msokolov@ivan.Harhan.ORG>
parents:
diff
changeset
|
80 symtab_raw = (struct external_syment *)(filemap + symtab_offset);
|
Michael Spacefalcon <msokolov@ivan.Harhan.ORG>
parents:
diff
changeset
|
81 nsymtab = get_u32(filehdr_struct->f_nsyms);
|
Michael Spacefalcon <msokolov@ivan.Harhan.ORG>
parents:
diff
changeset
|
82 strtab_offset = symtab_offset +
|
Michael Spacefalcon <msokolov@ivan.Harhan.ORG>
parents:
diff
changeset
|
83 sizeof(struct external_syment) * nsymtab;
|
Michael Spacefalcon <msokolov@ivan.Harhan.ORG>
parents:
diff
changeset
|
84 }
|
Michael Spacefalcon <msokolov@ivan.Harhan.ORG>
parents:
diff
changeset
|
85
|
Michael Spacefalcon <msokolov@ivan.Harhan.ORG>
parents:
diff
changeset
|
86 dump_filehdr_info()
|
Michael Spacefalcon <msokolov@ivan.Harhan.ORG>
parents:
diff
changeset
|
87 {
|
Michael Spacefalcon <msokolov@ivan.Harhan.ORG>
parents:
diff
changeset
|
88 time_t timestamp;
|
Michael Spacefalcon <msokolov@ivan.Harhan.ORG>
parents:
diff
changeset
|
89 struct tm *timedec;
|
Michael Spacefalcon <msokolov@ivan.Harhan.ORG>
parents:
diff
changeset
|
90
|
Michael Spacefalcon <msokolov@ivan.Harhan.ORG>
parents:
diff
changeset
|
91 timestamp = get_u32(filehdr_struct->f_timdat);
|
Michael Spacefalcon <msokolov@ivan.Harhan.ORG>
parents:
diff
changeset
|
92 timedec = gmtime(×tamp);
|
Michael Spacefalcon <msokolov@ivan.Harhan.ORG>
parents:
diff
changeset
|
93 printf("timestamp: %d-%02d-%02dT%02d:%02d:%02dZ\n",
|
Michael Spacefalcon <msokolov@ivan.Harhan.ORG>
parents:
diff
changeset
|
94 timedec->tm_year + 1900, timedec->tm_mon + 1, timedec->tm_mday,
|
Michael Spacefalcon <msokolov@ivan.Harhan.ORG>
parents:
diff
changeset
|
95 timedec->tm_hour, timedec->tm_min, timedec->tm_sec);
|
Michael Spacefalcon <msokolov@ivan.Harhan.ORG>
parents:
diff
changeset
|
96 printf("file flags: 0x%x\n", get_u16(filehdr_struct->f_flags));
|
Michael Spacefalcon <msokolov@ivan.Harhan.ORG>
parents:
diff
changeset
|
97 printf("%u sections, %u symtab entries\n", nsections, nsymtab);
|
Michael Spacefalcon <msokolov@ivan.Harhan.ORG>
parents:
diff
changeset
|
98 return(0);
|
Michael Spacefalcon <msokolov@ivan.Harhan.ORG>
parents:
diff
changeset
|
99 }
|