]> git.lizzy.rs Git - plan9front.git/blob - sys/src/9/xen/xenelf.c
merge
[plan9front.git] / sys / src / 9 / xen / xenelf.c
1 #include <u.h>
2 #include <libc.h>
3 #include "/sys/src/libmach/elf.h"
4
5 enum {
6         Page = 4096,
7 };
8
9 #define ROUND(n) ((n+Page-1)&~(Page-1))
10
11 Shdr isect, csect;
12
13 static ushort
14 GETS(void *a)
15 {
16         uchar *p = a;
17         return p[0] | p[1]<<8;
18 }
19
20 static ulong
21 GETL(void *a)
22 {
23         uchar *p = a;
24         return p[0] | p[1]<<8 | p[2]<<16 | p[3]<<24;
25 }
26
27 static void
28 PUTS(void *a, ushort v)
29 {
30         uchar *p = a;
31         p[0] = v;
32         p[1] = v>>8;
33 }
34
35 static void
36 PUTL(void *a, ulong v)
37 {
38         uchar *p = a;
39         p[0] = v;
40         p[1] = v>>8;
41         p[2] = v>>16;
42         p[3] = v>>24;
43 }
44
45 void
46 copy(int fin, int fout, ulong src, ulong dst, ulong size)
47 {
48         char buf[Page];
49         int n;
50
51         seek(fin, src, 0);
52         seek(fout, dst, 0);
53         n = Page;
54         while (size > 0) {
55                 if (n > size)
56                         n = size;
57                 read(fin, buf, n);
58                 write(fout, buf, n);
59                 size -= n;
60         }
61 }
62
63 void
64 main(int argc, char **argv)
65 {
66         Ehdr e;
67         Shdr s;
68         Phdr p;
69         int efd, ofd, ns, i, n;
70         ulong shoff, off, noff, size, msize;
71         char *sname, *sval;
72
73         if (argc != 5)
74                 sysfatal("Usage: xenelf input-elf-file output-elf-file section-name section-contents");
75         efd = open(argv[1], OREAD);
76         if (efd < 0)
77                 sysfatal("%s: %r", argv[1]);
78         ofd = create(argv[2], OWRITE, 0666);
79         if (ofd < 0)
80                 sysfatal("%s: %r", argv[2]);
81         sname = argv[3];
82         sval = argv[4];
83
84         read(efd, &e, sizeof e);
85         //if (e.shstrndx)
86         //      sysfatal("section header string index already present");
87         
88         /* page-align loadable segments in file */
89         ns = GETS(&e.phnum);
90         shoff = GETL(&e.phoff);
91         noff = shoff+ns*sizeof(Phdr);
92         noff = ROUND(noff);
93         for (i = 0; i < ns; i++) {
94                 seek(efd, shoff+i*sizeof(Phdr), 0);
95                 read(efd, &p, sizeof p);
96                 off = GETL(&p.offset);
97                 PUTL(&p.offset, noff);
98                 size = GETL(&p.filesz);
99                 copy(efd, ofd, off, noff, size);
100                 if (GETL(&p.type) == LOAD) {
101                         size = ROUND(size);
102                         PUTL(&p.filesz, size);
103                         if ((msize = GETL(&p.memsz)) != 0 && size > msize)
104                                 PUTL(&p.memsz, size);
105                 } else {
106                         /* memory size for symtab segment is actually line number table size */
107                         msize = GETL(&p.memsz);
108                         copy(efd, ofd, off+size, noff+size, msize);
109                         noff += msize;
110                 }
111                 noff += size;
112                 seek(ofd, shoff+i*sizeof(Phdr), 0);
113                 write(ofd, &p, sizeof p);
114         }
115
116         /* append single-entry shstrndx */
117         PUTL(&isect.offset, seek(ofd, noff, 0));
118         n = strlen(sname);
119         PUTL(&isect.size, n+2);
120         write(ofd, sname+n, 1);
121         write(ofd, sname, n+1);
122         
123         /* append comment section contents */
124         PUTL(&csect.name, 1);
125         PUTL(&csect.offset, seek(ofd, 0, 2));
126         n = strlen(sval);
127         PUTL(&csect.size, n+1);
128         write(ofd, sval, n+1);
129         
130         /* copy existing section headers to end */
131         ns = 0; //GETS(&e.shnum);
132         shoff = GETL(&e.shoff);
133         PUTL(&e.shoff, seek(ofd, 0, 2));
134         for (i = 0; i < ns; i++) {
135                 seek(efd, shoff+i*sizeof(Shdr), 0);
136                 read(efd, &s, sizeof s);
137                 seek(ofd, 0, 2);
138                 write(ofd, &s, sizeof s);
139         }
140         
141         /* append section header for comment section */
142         write(ofd, &csect, sizeof csect);
143         ++ns;
144
145         /* append section header for shstrndx */
146         PUTS(&e.shstrndx, ns);
147         ++ns;
148         write(ofd, &isect, sizeof isect);
149
150         /* rewrite elf header */
151         PUTS(&e.shentsize, sizeof(Shdr));
152         PUTS(&e.shnum, ns);
153         seek(ofd, 0, 0);
154         write(ofd, &e, sizeof e);
155
156         exits(0);
157 }