6 #define MAXSECS (1 << 7)
7 #define MAXSYMS (1 << 10)
8 #define MAXRELA (1 << 10)
13 static Elf64_Ehdr ehdr
;
14 static Elf64_Shdr shdr
[MAXSECS
];
15 static int nshdr
= SEC_BEG
;
16 static Elf64_Sym syms
[MAXSYMS
];
18 static char symstr
[MAXSYMS
* 8];
19 static int nsymstr
= 1;
25 Elf64_Rela rela
[MAXRELA
];
31 static struct sec
*sec
;
33 static char *putstr(char *s
, char *r
)
41 static Elf64_Sym
*put_sym(char *name
)
43 Elf64_Sym
*sym
= &syms
[nsyms
++];
44 sym
->st_name
= nsymstr
;
45 nsymstr
= putstr(symstr
+ nsymstr
, name
) - symstr
;
46 sym
->st_info
= ELF64_ST_INFO(STB_GLOBAL
, STT_FUNC
);
50 static int sym_find(char *name
)
54 for (i
= 0; i
< nsyms
; i
++)
55 if (!strcmp(name
, symstr
+ syms
[i
].st_name
))
58 sym
->st_shndx
= SHN_UNDEF
;
62 void out_func_beg(char *name
)
65 sec
->sym
= put_sym(name
);
66 sec
->sym
->st_shndx
= nshdr
;
67 sec
->sec_shdr
= &shdr
[nshdr
++];
68 sec
->rel_shdr
= &shdr
[nshdr
++];
69 sec
->rel_shdr
->sh_link
= SEC_SYMS
;
70 sec
->rel_shdr
->sh_info
= sec
->sec_shdr
- shdr
;
73 void out_func_end(char *buf
, int len
)
75 memcpy(sec
->buf
, buf
, len
);
77 sec
->sym
->st_size
= len
;
80 void out_rela(char *name
, int off
)
82 Elf64_Rela
*rela
= &sec
->rela
[sec
->nrela
++];
84 rela
->r_info
= ELF64_R_INFO(sym_find(name
), R_X86_64_32
);
87 void out_write(int fd
)
89 Elf64_Shdr
*symstr_shdr
= &shdr
[SEC_SYMSTR
];
90 Elf64_Shdr
*syms_shdr
= &shdr
[SEC_SYMS
];
91 unsigned long offset
= sizeof(ehdr
);
94 ehdr
.e_ident
[0] = 0x7f;
95 ehdr
.e_ident
[1] = 'E';
96 ehdr
.e_ident
[2] = 'L';
97 ehdr
.e_ident
[3] = 'F';
98 ehdr
.e_ident
[4] = ELFCLASS64
;
99 ehdr
.e_ident
[5] = ELFDATA2LSB
;
100 ehdr
.e_ident
[6] = EV_CURRENT
;
101 ehdr
.e_type
= ET_REL
;
102 ehdr
.e_machine
= EM_X86_64
;
103 ehdr
.e_version
= EV_CURRENT
;
104 ehdr
.e_ehsize
= sizeof(ehdr
);
105 ehdr
.e_shentsize
= sizeof(shdr
[0]);
106 ehdr
.e_shoff
= offset
;
107 ehdr
.e_shnum
= nshdr
;
108 ehdr
.e_shstrndx
= SEC_SYMSTR
;
109 offset
+= sizeof(shdr
[0]) * nshdr
;
111 syms_shdr
->sh_type
= SHT_SYMTAB
;
112 syms_shdr
->sh_offset
= offset
;
113 syms_shdr
->sh_size
= nsyms
* sizeof(syms
[0]);
114 syms_shdr
->sh_entsize
= sizeof(syms
[0]);
115 syms_shdr
->sh_link
= SEC_SYMSTR
;
116 offset
+= syms_shdr
->sh_size
;
118 symstr_shdr
->sh_type
= SHT_STRTAB
;
119 symstr_shdr
->sh_offset
= offset
;
120 symstr_shdr
->sh_size
= nsymstr
;
121 symstr_shdr
->sh_entsize
= 1;
122 offset
+= symstr_shdr
->sh_size
;
124 for (i
= 0; i
< nsecs
; i
++) {
125 struct sec
*sec
= &secs
[i
];
127 sec
->sec_shdr
->sh_type
= SHT_PROGBITS
;
128 sec
->sec_shdr
->sh_flags
= SHF_EXECINSTR
;
129 sec
->sec_shdr
->sh_offset
= offset
;
130 sec
->sec_shdr
->sh_size
= sec
->len
;
131 sec
->sec_shdr
->sh_entsize
= 1;
132 offset
+= sec
->sec_shdr
->sh_size
;
134 sec
->rel_shdr
->sh_type
= SHT_RELA
;
135 sec
->rel_shdr
->sh_offset
= offset
;
136 sec
->rel_shdr
->sh_size
= sec
->nrela
* sizeof(sec
->rela
[0]);
137 sec
->rel_shdr
->sh_entsize
= sizeof(sec
->rela
[0]);
138 offset
+= sec
->rel_shdr
->sh_size
;
141 write(fd
, &ehdr
, sizeof(ehdr
));
142 write(fd
, shdr
, sizeof(shdr
[0]) * nshdr
);
143 write(fd
, syms
, sizeof(syms
[0]) * nsyms
);
144 write(fd
, symstr
, nsymstr
);
145 for (i
= 0; i
< nsecs
; i
++) {
146 struct sec
*sec
= &secs
[i
];
147 write(fd
, sec
->buf
, sec
->len
);
148 write(fd
, sec
->rela
, sec
->nrela
* sizeof(sec
->rela
[0]));