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
|
73
|
48 get_s16(ptr)
|
|
49 u_char *ptr;
|
|
50 {
|
|
51 int i;
|
|
52
|
|
53 i = ptr[0] | ptr[1] << 8;
|
|
54 if (i >= 32768)
|
|
55 i -= 65536;
|
|
56 return(i);
|
|
57 }
|
|
58
|
70
Michael Spacefalcon <msokolov@ivan.Harhan.ORG>
parents:
diff
changeset
|
59 unsigned
|
Michael Spacefalcon <msokolov@ivan.Harhan.ORG>
parents:
diff
changeset
|
60 get_u32(ptr)
|
Michael Spacefalcon <msokolov@ivan.Harhan.ORG>
parents:
diff
changeset
|
61 u_char *ptr;
|
Michael Spacefalcon <msokolov@ivan.Harhan.ORG>
parents:
diff
changeset
|
62 {
|
Michael Spacefalcon <msokolov@ivan.Harhan.ORG>
parents:
diff
changeset
|
63 return ptr[0] | ptr[1] << 8 | ptr[2] << 16 | ptr[3] << 24;
|
Michael Spacefalcon <msokolov@ivan.Harhan.ORG>
parents:
diff
changeset
|
64 }
|
Michael Spacefalcon <msokolov@ivan.Harhan.ORG>
parents:
diff
changeset
|
65
|
Michael Spacefalcon <msokolov@ivan.Harhan.ORG>
parents:
diff
changeset
|
66 initial_parse_hdr()
|
Michael Spacefalcon <msokolov@ivan.Harhan.ORG>
parents:
diff
changeset
|
67 {
|
Michael Spacefalcon <msokolov@ivan.Harhan.ORG>
parents:
diff
changeset
|
68 unsigned symtab_offset;
|
Michael Spacefalcon <msokolov@ivan.Harhan.ORG>
parents:
diff
changeset
|
69
|
Michael Spacefalcon <msokolov@ivan.Harhan.ORG>
parents:
diff
changeset
|
70 filehdr_struct = (struct external_filehdr *) filemap;
|
Michael Spacefalcon <msokolov@ivan.Harhan.ORG>
parents:
diff
changeset
|
71 if (get_u16(filehdr_struct->f_magic) != 0xC2) {
|
Michael Spacefalcon <msokolov@ivan.Harhan.ORG>
parents:
diff
changeset
|
72 fprintf(stderr, "error: %s is not a TI COFF2 object\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 if (get_u16(filehdr_struct->f_target_id) != 0x97) {
|
Michael Spacefalcon <msokolov@ivan.Harhan.ORG>
parents:
diff
changeset
|
77 fprintf(stderr, "error: TI COFF object %s is not for TMS470\n",
|
Michael Spacefalcon <msokolov@ivan.Harhan.ORG>
parents:
diff
changeset
|
78 objfilename);
|
Michael Spacefalcon <msokolov@ivan.Harhan.ORG>
parents:
diff
changeset
|
79 exit(1);
|
Michael Spacefalcon <msokolov@ivan.Harhan.ORG>
parents:
diff
changeset
|
80 }
|
Michael Spacefalcon <msokolov@ivan.Harhan.ORG>
parents:
diff
changeset
|
81 if (get_u16(filehdr_struct->f_opthdr)) {
|
Michael Spacefalcon <msokolov@ivan.Harhan.ORG>
parents:
diff
changeset
|
82 fprintf(stderr,
|
Michael Spacefalcon <msokolov@ivan.Harhan.ORG>
parents:
diff
changeset
|
83 "error: %s has the \"optional\" header present\n",
|
Michael Spacefalcon <msokolov@ivan.Harhan.ORG>
parents:
diff
changeset
|
84 objfilename);
|
Michael Spacefalcon <msokolov@ivan.Harhan.ORG>
parents:
diff
changeset
|
85 exit(1);
|
Michael Spacefalcon <msokolov@ivan.Harhan.ORG>
parents:
diff
changeset
|
86 }
|
Michael Spacefalcon <msokolov@ivan.Harhan.ORG>
parents:
diff
changeset
|
87 sections_raw = (struct external_scnhdr *)
|
Michael Spacefalcon <msokolov@ivan.Harhan.ORG>
parents:
diff
changeset
|
88 (filemap + sizeof(struct external_filehdr));
|
Michael Spacefalcon <msokolov@ivan.Harhan.ORG>
parents:
diff
changeset
|
89 nsections = get_u16(filehdr_struct->f_nscns);
|
Michael Spacefalcon <msokolov@ivan.Harhan.ORG>
parents:
diff
changeset
|
90 symtab_offset = get_u32(filehdr_struct->f_symptr);
|
Michael Spacefalcon <msokolov@ivan.Harhan.ORG>
parents:
diff
changeset
|
91 symtab_raw = (struct external_syment *)(filemap + symtab_offset);
|
Michael Spacefalcon <msokolov@ivan.Harhan.ORG>
parents:
diff
changeset
|
92 nsymtab = get_u32(filehdr_struct->f_nsyms);
|
Michael Spacefalcon <msokolov@ivan.Harhan.ORG>
parents:
diff
changeset
|
93 strtab_offset = symtab_offset +
|
Michael Spacefalcon <msokolov@ivan.Harhan.ORG>
parents:
diff
changeset
|
94 sizeof(struct external_syment) * nsymtab;
|
Michael Spacefalcon <msokolov@ivan.Harhan.ORG>
parents:
diff
changeset
|
95 }
|
Michael Spacefalcon <msokolov@ivan.Harhan.ORG>
parents:
diff
changeset
|
96
|
Michael Spacefalcon <msokolov@ivan.Harhan.ORG>
parents:
diff
changeset
|
97 dump_filehdr_info()
|
Michael Spacefalcon <msokolov@ivan.Harhan.ORG>
parents:
diff
changeset
|
98 {
|
Michael Spacefalcon <msokolov@ivan.Harhan.ORG>
parents:
diff
changeset
|
99 time_t timestamp;
|
Michael Spacefalcon <msokolov@ivan.Harhan.ORG>
parents:
diff
changeset
|
100 struct tm *timedec;
|
Michael Spacefalcon <msokolov@ivan.Harhan.ORG>
parents:
diff
changeset
|
101
|
Michael Spacefalcon <msokolov@ivan.Harhan.ORG>
parents:
diff
changeset
|
102 timestamp = get_u32(filehdr_struct->f_timdat);
|
Michael Spacefalcon <msokolov@ivan.Harhan.ORG>
parents:
diff
changeset
|
103 timedec = gmtime(×tamp);
|
Michael Spacefalcon <msokolov@ivan.Harhan.ORG>
parents:
diff
changeset
|
104 printf("timestamp: %d-%02d-%02dT%02d:%02d:%02dZ\n",
|
Michael Spacefalcon <msokolov@ivan.Harhan.ORG>
parents:
diff
changeset
|
105 timedec->tm_year + 1900, timedec->tm_mon + 1, timedec->tm_mday,
|
Michael Spacefalcon <msokolov@ivan.Harhan.ORG>
parents:
diff
changeset
|
106 timedec->tm_hour, timedec->tm_min, timedec->tm_sec);
|
Michael Spacefalcon <msokolov@ivan.Harhan.ORG>
parents:
diff
changeset
|
107 printf("file flags: 0x%x\n", get_u16(filehdr_struct->f_flags));
|
Michael Spacefalcon <msokolov@ivan.Harhan.ORG>
parents:
diff
changeset
|
108 printf("%u sections, %u symtab entries\n", nsections, nsymtab);
|
Michael Spacefalcon <msokolov@ivan.Harhan.ORG>
parents:
diff
changeset
|
109 return(0);
|
Michael Spacefalcon <msokolov@ivan.Harhan.ORG>
parents:
diff
changeset
|
110 }
|