annotate ticoff/lowlevel.c @ 118:193926ccd1ec

tiobjd: better handling of section-relative relocs
author Michael Spacefalcon <msokolov@ivan.Harhan.ORG>
date Thu, 03 Apr 2014 07:47:03 +0000
parents 2eef88395908
children
Ignore whitespace changes - Everywhere: Within whitespace: At end of lines:
rev   line source
74
2eef88395908 tiobjd: a little refactoring
Michael Spacefalcon <msokolov@ivan.Harhan.ORG>
parents:
diff changeset
1 /*
2eef88395908 tiobjd: a little refactoring
Michael Spacefalcon <msokolov@ivan.Harhan.ORG>
parents:
diff changeset
2 * This C module implements the low-level steps of TI COFF image analysis.
2eef88395908 tiobjd: a little refactoring
Michael Spacefalcon <msokolov@ivan.Harhan.ORG>
parents:
diff changeset
3 */
2eef88395908 tiobjd: a little refactoring
Michael Spacefalcon <msokolov@ivan.Harhan.ORG>
parents:
diff changeset
4
2eef88395908 tiobjd: a little refactoring
Michael Spacefalcon <msokolov@ivan.Harhan.ORG>
parents:
diff changeset
5 #include <sys/types.h>
2eef88395908 tiobjd: a little refactoring
Michael Spacefalcon <msokolov@ivan.Harhan.ORG>
parents:
diff changeset
6 #include <sys/file.h>
2eef88395908 tiobjd: a little refactoring
Michael Spacefalcon <msokolov@ivan.Harhan.ORG>
parents:
diff changeset
7 #include <sys/stat.h>
2eef88395908 tiobjd: a little refactoring
Michael Spacefalcon <msokolov@ivan.Harhan.ORG>
parents:
diff changeset
8 #include <sys/mman.h>
2eef88395908 tiobjd: a little refactoring
Michael Spacefalcon <msokolov@ivan.Harhan.ORG>
parents:
diff changeset
9 #include <stdio.h>
2eef88395908 tiobjd: a little refactoring
Michael Spacefalcon <msokolov@ivan.Harhan.ORG>
parents:
diff changeset
10 #include <stdlib.h>
2eef88395908 tiobjd: a little refactoring
Michael Spacefalcon <msokolov@ivan.Harhan.ORG>
parents:
diff changeset
11 #include <unistd.h>
2eef88395908 tiobjd: a little refactoring
Michael Spacefalcon <msokolov@ivan.Harhan.ORG>
parents:
diff changeset
12 #include "filestruct.h"
2eef88395908 tiobjd: a little refactoring
Michael Spacefalcon <msokolov@ivan.Harhan.ORG>
parents:
diff changeset
13 #include "globals.h"
2eef88395908 tiobjd: a little refactoring
Michael Spacefalcon <msokolov@ivan.Harhan.ORG>
parents:
diff changeset
14
2eef88395908 tiobjd: a little refactoring
Michael Spacefalcon <msokolov@ivan.Harhan.ORG>
parents:
diff changeset
15 mmap_objfile()
2eef88395908 tiobjd: a little refactoring
Michael Spacefalcon <msokolov@ivan.Harhan.ORG>
parents:
diff changeset
16 {
2eef88395908 tiobjd: a little refactoring
Michael Spacefalcon <msokolov@ivan.Harhan.ORG>
parents:
diff changeset
17 int fd;
2eef88395908 tiobjd: a little refactoring
Michael Spacefalcon <msokolov@ivan.Harhan.ORG>
parents:
diff changeset
18 struct stat st;
2eef88395908 tiobjd: a little refactoring
Michael Spacefalcon <msokolov@ivan.Harhan.ORG>
parents:
diff changeset
19
2eef88395908 tiobjd: a little refactoring
Michael Spacefalcon <msokolov@ivan.Harhan.ORG>
parents:
diff changeset
20 fd = open(objfilename, O_RDONLY);
2eef88395908 tiobjd: a little refactoring
Michael Spacefalcon <msokolov@ivan.Harhan.ORG>
parents:
diff changeset
21 if (fd < 0) {
2eef88395908 tiobjd: a little refactoring
Michael Spacefalcon <msokolov@ivan.Harhan.ORG>
parents:
diff changeset
22 perror(objfilename);
2eef88395908 tiobjd: a little refactoring
Michael Spacefalcon <msokolov@ivan.Harhan.ORG>
parents:
diff changeset
23 exit(1);
2eef88395908 tiobjd: a little refactoring
Michael Spacefalcon <msokolov@ivan.Harhan.ORG>
parents:
diff changeset
24 }
2eef88395908 tiobjd: a little refactoring
Michael Spacefalcon <msokolov@ivan.Harhan.ORG>
parents:
diff changeset
25 fstat(fd, &st);
2eef88395908 tiobjd: a little refactoring
Michael Spacefalcon <msokolov@ivan.Harhan.ORG>
parents:
diff changeset
26 if (!S_ISREG(st.st_mode)) {
2eef88395908 tiobjd: a little refactoring
Michael Spacefalcon <msokolov@ivan.Harhan.ORG>
parents:
diff changeset
27 fprintf(stderr, "error: %s is not a regular file\n",
2eef88395908 tiobjd: a little refactoring
Michael Spacefalcon <msokolov@ivan.Harhan.ORG>
parents:
diff changeset
28 objfilename);
2eef88395908 tiobjd: a little refactoring
Michael Spacefalcon <msokolov@ivan.Harhan.ORG>
parents:
diff changeset
29 exit(1);
2eef88395908 tiobjd: a little refactoring
Michael Spacefalcon <msokolov@ivan.Harhan.ORG>
parents:
diff changeset
30 }
2eef88395908 tiobjd: a little refactoring
Michael Spacefalcon <msokolov@ivan.Harhan.ORG>
parents:
diff changeset
31 objfile_tot_size = st.st_size;
2eef88395908 tiobjd: a little refactoring
Michael Spacefalcon <msokolov@ivan.Harhan.ORG>
parents:
diff changeset
32 filemap = mmap(NULL, objfile_tot_size, PROT_READ, MAP_PRIVATE, fd, 0L);
2eef88395908 tiobjd: a little refactoring
Michael Spacefalcon <msokolov@ivan.Harhan.ORG>
parents:
diff changeset
33 if (filemap == MAP_FAILED) {
2eef88395908 tiobjd: a little refactoring
Michael Spacefalcon <msokolov@ivan.Harhan.ORG>
parents:
diff changeset
34 perror("mmap");
2eef88395908 tiobjd: a little refactoring
Michael Spacefalcon <msokolov@ivan.Harhan.ORG>
parents:
diff changeset
35 exit(1);
2eef88395908 tiobjd: a little refactoring
Michael Spacefalcon <msokolov@ivan.Harhan.ORG>
parents:
diff changeset
36 }
2eef88395908 tiobjd: a little refactoring
Michael Spacefalcon <msokolov@ivan.Harhan.ORG>
parents:
diff changeset
37 close(fd);
2eef88395908 tiobjd: a little refactoring
Michael Spacefalcon <msokolov@ivan.Harhan.ORG>
parents:
diff changeset
38 }
2eef88395908 tiobjd: a little refactoring
Michael Spacefalcon <msokolov@ivan.Harhan.ORG>
parents:
diff changeset
39
2eef88395908 tiobjd: a little refactoring
Michael Spacefalcon <msokolov@ivan.Harhan.ORG>
parents:
diff changeset
40 unsigned
2eef88395908 tiobjd: a little refactoring
Michael Spacefalcon <msokolov@ivan.Harhan.ORG>
parents:
diff changeset
41 get_u16(ptr)
2eef88395908 tiobjd: a little refactoring
Michael Spacefalcon <msokolov@ivan.Harhan.ORG>
parents:
diff changeset
42 u_char *ptr;
2eef88395908 tiobjd: a little refactoring
Michael Spacefalcon <msokolov@ivan.Harhan.ORG>
parents:
diff changeset
43 {
2eef88395908 tiobjd: a little refactoring
Michael Spacefalcon <msokolov@ivan.Harhan.ORG>
parents:
diff changeset
44 return ptr[0] | ptr[1] << 8;
2eef88395908 tiobjd: a little refactoring
Michael Spacefalcon <msokolov@ivan.Harhan.ORG>
parents:
diff changeset
45 }
2eef88395908 tiobjd: a little refactoring
Michael Spacefalcon <msokolov@ivan.Harhan.ORG>
parents:
diff changeset
46
2eef88395908 tiobjd: a little refactoring
Michael Spacefalcon <msokolov@ivan.Harhan.ORG>
parents:
diff changeset
47 get_s16(ptr)
2eef88395908 tiobjd: a little refactoring
Michael Spacefalcon <msokolov@ivan.Harhan.ORG>
parents:
diff changeset
48 u_char *ptr;
2eef88395908 tiobjd: a little refactoring
Michael Spacefalcon <msokolov@ivan.Harhan.ORG>
parents:
diff changeset
49 {
2eef88395908 tiobjd: a little refactoring
Michael Spacefalcon <msokolov@ivan.Harhan.ORG>
parents:
diff changeset
50 int i;
2eef88395908 tiobjd: a little refactoring
Michael Spacefalcon <msokolov@ivan.Harhan.ORG>
parents:
diff changeset
51
2eef88395908 tiobjd: a little refactoring
Michael Spacefalcon <msokolov@ivan.Harhan.ORG>
parents:
diff changeset
52 i = ptr[0] | ptr[1] << 8;
2eef88395908 tiobjd: a little refactoring
Michael Spacefalcon <msokolov@ivan.Harhan.ORG>
parents:
diff changeset
53 if (i >= 32768)
2eef88395908 tiobjd: a little refactoring
Michael Spacefalcon <msokolov@ivan.Harhan.ORG>
parents:
diff changeset
54 i -= 65536;
2eef88395908 tiobjd: a little refactoring
Michael Spacefalcon <msokolov@ivan.Harhan.ORG>
parents:
diff changeset
55 return(i);
2eef88395908 tiobjd: a little refactoring
Michael Spacefalcon <msokolov@ivan.Harhan.ORG>
parents:
diff changeset
56 }
2eef88395908 tiobjd: a little refactoring
Michael Spacefalcon <msokolov@ivan.Harhan.ORG>
parents:
diff changeset
57
2eef88395908 tiobjd: a little refactoring
Michael Spacefalcon <msokolov@ivan.Harhan.ORG>
parents:
diff changeset
58 unsigned
2eef88395908 tiobjd: a little refactoring
Michael Spacefalcon <msokolov@ivan.Harhan.ORG>
parents:
diff changeset
59 get_u32(ptr)
2eef88395908 tiobjd: a little refactoring
Michael Spacefalcon <msokolov@ivan.Harhan.ORG>
parents:
diff changeset
60 u_char *ptr;
2eef88395908 tiobjd: a little refactoring
Michael Spacefalcon <msokolov@ivan.Harhan.ORG>
parents:
diff changeset
61 {
2eef88395908 tiobjd: a little refactoring
Michael Spacefalcon <msokolov@ivan.Harhan.ORG>
parents:
diff changeset
62 return ptr[0] | ptr[1] << 8 | ptr[2] << 16 | ptr[3] << 24;
2eef88395908 tiobjd: a little refactoring
Michael Spacefalcon <msokolov@ivan.Harhan.ORG>
parents:
diff changeset
63 }
2eef88395908 tiobjd: a little refactoring
Michael Spacefalcon <msokolov@ivan.Harhan.ORG>
parents:
diff changeset
64
2eef88395908 tiobjd: a little refactoring
Michael Spacefalcon <msokolov@ivan.Harhan.ORG>
parents:
diff changeset
65 initial_parse_hdr()
2eef88395908 tiobjd: a little refactoring
Michael Spacefalcon <msokolov@ivan.Harhan.ORG>
parents:
diff changeset
66 {
2eef88395908 tiobjd: a little refactoring
Michael Spacefalcon <msokolov@ivan.Harhan.ORG>
parents:
diff changeset
67 unsigned symtab_offset;
2eef88395908 tiobjd: a little refactoring
Michael Spacefalcon <msokolov@ivan.Harhan.ORG>
parents:
diff changeset
68
2eef88395908 tiobjd: a little refactoring
Michael Spacefalcon <msokolov@ivan.Harhan.ORG>
parents:
diff changeset
69 filehdr_struct = (struct external_filehdr *) filemap;
2eef88395908 tiobjd: a little refactoring
Michael Spacefalcon <msokolov@ivan.Harhan.ORG>
parents:
diff changeset
70 if (get_u16(filehdr_struct->f_magic) != 0xC2) {
2eef88395908 tiobjd: a little refactoring
Michael Spacefalcon <msokolov@ivan.Harhan.ORG>
parents:
diff changeset
71 fprintf(stderr, "error: %s is not a TI COFF2 object\n",
2eef88395908 tiobjd: a little refactoring
Michael Spacefalcon <msokolov@ivan.Harhan.ORG>
parents:
diff changeset
72 objfilename);
2eef88395908 tiobjd: a little refactoring
Michael Spacefalcon <msokolov@ivan.Harhan.ORG>
parents:
diff changeset
73 exit(1);
2eef88395908 tiobjd: a little refactoring
Michael Spacefalcon <msokolov@ivan.Harhan.ORG>
parents:
diff changeset
74 }
2eef88395908 tiobjd: a little refactoring
Michael Spacefalcon <msokolov@ivan.Harhan.ORG>
parents:
diff changeset
75 if (get_u16(filehdr_struct->f_target_id) != 0x97) {
2eef88395908 tiobjd: a little refactoring
Michael Spacefalcon <msokolov@ivan.Harhan.ORG>
parents:
diff changeset
76 fprintf(stderr, "error: TI COFF object %s is not for TMS470\n",
2eef88395908 tiobjd: a little refactoring
Michael Spacefalcon <msokolov@ivan.Harhan.ORG>
parents:
diff changeset
77 objfilename);
2eef88395908 tiobjd: a little refactoring
Michael Spacefalcon <msokolov@ivan.Harhan.ORG>
parents:
diff changeset
78 exit(1);
2eef88395908 tiobjd: a little refactoring
Michael Spacefalcon <msokolov@ivan.Harhan.ORG>
parents:
diff changeset
79 }
2eef88395908 tiobjd: a little refactoring
Michael Spacefalcon <msokolov@ivan.Harhan.ORG>
parents:
diff changeset
80 if (get_u16(filehdr_struct->f_opthdr)) {
2eef88395908 tiobjd: a little refactoring
Michael Spacefalcon <msokolov@ivan.Harhan.ORG>
parents:
diff changeset
81 fprintf(stderr,
2eef88395908 tiobjd: a little refactoring
Michael Spacefalcon <msokolov@ivan.Harhan.ORG>
parents:
diff changeset
82 "error: %s has the \"optional\" header present\n",
2eef88395908 tiobjd: a little refactoring
Michael Spacefalcon <msokolov@ivan.Harhan.ORG>
parents:
diff changeset
83 objfilename);
2eef88395908 tiobjd: a little refactoring
Michael Spacefalcon <msokolov@ivan.Harhan.ORG>
parents:
diff changeset
84 exit(1);
2eef88395908 tiobjd: a little refactoring
Michael Spacefalcon <msokolov@ivan.Harhan.ORG>
parents:
diff changeset
85 }
2eef88395908 tiobjd: a little refactoring
Michael Spacefalcon <msokolov@ivan.Harhan.ORG>
parents:
diff changeset
86 sections_raw = (struct external_scnhdr *)
2eef88395908 tiobjd: a little refactoring
Michael Spacefalcon <msokolov@ivan.Harhan.ORG>
parents:
diff changeset
87 (filemap + sizeof(struct external_filehdr));
2eef88395908 tiobjd: a little refactoring
Michael Spacefalcon <msokolov@ivan.Harhan.ORG>
parents:
diff changeset
88 nsections = get_u16(filehdr_struct->f_nscns);
2eef88395908 tiobjd: a little refactoring
Michael Spacefalcon <msokolov@ivan.Harhan.ORG>
parents:
diff changeset
89 symtab_offset = get_u32(filehdr_struct->f_symptr);
2eef88395908 tiobjd: a little refactoring
Michael Spacefalcon <msokolov@ivan.Harhan.ORG>
parents:
diff changeset
90 symtab_raw = (struct external_syment *)(filemap + symtab_offset);
2eef88395908 tiobjd: a little refactoring
Michael Spacefalcon <msokolov@ivan.Harhan.ORG>
parents:
diff changeset
91 nsymtab = get_u32(filehdr_struct->f_nsyms);
2eef88395908 tiobjd: a little refactoring
Michael Spacefalcon <msokolov@ivan.Harhan.ORG>
parents:
diff changeset
92 strtab_offset = symtab_offset +
2eef88395908 tiobjd: a little refactoring
Michael Spacefalcon <msokolov@ivan.Harhan.ORG>
parents:
diff changeset
93 sizeof(struct external_syment) * nsymtab;
2eef88395908 tiobjd: a little refactoring
Michael Spacefalcon <msokolov@ivan.Harhan.ORG>
parents:
diff changeset
94 }