1 // SPDX-License-Identifier: GPL-2.0-only
4 * Copyright (C) 2014, Google, Inc
7 * Stephane Eranian <eranian@gmail.com>
10 #include <sys/types.h>
19 #ifdef HAVE_LIBDW_SUPPORT
24 #include "../util/jitdump.h"
25 #include <linux/compiler.h>
27 #ifndef NT_GNU_BUILD_ID
28 #define NT_GNU_BUILD_ID 3
31 #define BUILD_ID_URANDOM /* different uuid for each run */
33 #ifdef HAVE_LIBCRYPTO_SUPPORT
36 #undef BUILD_ID_SHA /* does not seem to work well when linked with Java */
37 #undef BUILD_ID_URANDOM /* different uuid for each run */
40 #include <openssl/sha.h>
44 #include <openssl/evp.h>
45 #include <openssl/md5.h>
51 unsigned int namesz
; /* Size of entry's owner string */
52 unsigned int descsz
; /* Size of the note descriptor */
53 unsigned int type
; /* Interpretation of the descriptor */
54 char name
[0]; /* Start of the name+desc data */
57 static char shd_string_table
[] = {
59 '.', 't', 'e', 'x', 't', 0, /* 1 */
60 '.', 's', 'h', 's', 't', 'r', 't', 'a', 'b', 0, /* 7 */
61 '.', 's', 'y', 'm', 't', 'a', 'b', 0, /* 17 */
62 '.', 's', 't', 'r', 't', 'a', 'b', 0, /* 25 */
63 '.', 'n', 'o', 't', 'e', '.', 'g', 'n', 'u', '.', 'b', 'u', 'i', 'l', 'd', '-', 'i', 'd', 0, /* 33 */
64 '.', 'd', 'e', 'b', 'u', 'g', '_', 'l', 'i', 'n', 'e', 0, /* 52 */
65 '.', 'd', 'e', 'b', 'u', 'g', '_', 'i', 'n', 'f', 'o', 0, /* 64 */
66 '.', 'd', 'e', 'b', 'u', 'g', '_', 'a', 'b', 'b', 'r', 'e', 'v', 0, /* 76 */
67 '.', 'e', 'h', '_', 'f', 'r', 'a', 'm', 'e', '_', 'h', 'd', 'r', 0, /* 90 */
68 '.', 'e', 'h', '_', 'f', 'r', 'a', 'm', 'e', 0, /* 104 */
71 static struct buildid_note
{
72 Elf_Note desc
; /* descsz: size of build-id, must be multiple of 4 */
73 char name
[4]; /* GNU\0 */
77 static Elf_Sym symtab
[]={
78 /* symbol 0 MUST be the undefined symbol */
79 { .st_name
= 0, /* index in sym_string table */
80 .st_info
= ELF_ST_TYPE(STT_NOTYPE
),
81 .st_shndx
= 0, /* for now */
83 .st_other
= ELF_ST_VIS(STV_DEFAULT
),
86 { .st_name
= 1, /* index in sym_string table */
87 .st_info
= ELF_ST_BIND(STB_LOCAL
) | ELF_ST_TYPE(STT_FUNC
),
89 .st_value
= 0, /* for now */
90 .st_other
= ELF_ST_VIS(STV_DEFAULT
),
91 .st_size
= 0, /* for now */
95 #ifdef BUILD_ID_URANDOM
97 gen_build_id(struct buildid_note
*note
,
98 unsigned long load_addr __maybe_unused
,
99 const void *code __maybe_unused
,
100 size_t csize __maybe_unused
)
103 size_t sz
= sizeof(note
->build_id
);
106 fd
= open("/dev/urandom", O_RDONLY
);
108 err(1, "cannot access /dev/urandom for buildid");
110 sret
= read(fd
, note
->build_id
, sz
);
114 if (sret
!= (ssize_t
)sz
)
115 memset(note
->build_id
, 0, sz
);
121 gen_build_id(struct buildid_note
*note
,
122 unsigned long load_addr __maybe_unused
,
126 if (sizeof(note
->build_id
) < SHA_DIGEST_LENGTH
)
127 errx(1, "build_id too small for SHA1");
129 SHA1(code
, csize
, (unsigned char *)note
->build_id
);
135 gen_build_id(struct buildid_note
*note
, unsigned long load_addr
, const void *code
, size_t csize
)
139 if (sizeof(note
->build_id
) < 16)
140 errx(1, "build_id too small for MD5");
142 mdctx
= EVP_MD_CTX_new();
144 errx(2, "failed to create EVP_MD_CTX");
146 EVP_DigestInit_ex(mdctx
, EVP_md5(), NULL
);
147 EVP_DigestUpdate(mdctx
, &load_addr
, sizeof(load_addr
));
148 EVP_DigestUpdate(mdctx
, code
, csize
);
149 EVP_DigestFinal_ex(mdctx
, (unsigned char *)note
->build_id
, NULL
);
150 EVP_MD_CTX_free(mdctx
);
155 jit_add_eh_frame_info(Elf
*e
, void* unwinding
, uint64_t unwinding_header_size
,
156 uint64_t unwinding_size
, uint64_t base_offset
)
161 uint64_t unwinding_table_size
= unwinding_size
- unwinding_header_size
;
164 * setup eh_frame section
168 warnx("cannot create section");
172 d
= elf_newdata(scn
);
174 warnx("cannot get new data");
180 d
->d_buf
= unwinding
;
181 d
->d_type
= ELF_T_BYTE
;
182 d
->d_size
= unwinding_table_size
;
183 d
->d_version
= EV_CURRENT
;
185 shdr
= elf_getshdr(scn
);
187 warnx("cannot get section header");
192 shdr
->sh_type
= SHT_PROGBITS
;
193 shdr
->sh_addr
= base_offset
;
194 shdr
->sh_flags
= SHF_ALLOC
;
195 shdr
->sh_entsize
= 0;
198 * setup eh_frame_hdr section
202 warnx("cannot create section");
206 d
= elf_newdata(scn
);
208 warnx("cannot get new data");
214 d
->d_buf
= unwinding
+ unwinding_table_size
;
215 d
->d_type
= ELF_T_BYTE
;
216 d
->d_size
= unwinding_header_size
;
217 d
->d_version
= EV_CURRENT
;
219 shdr
= elf_getshdr(scn
);
221 warnx("cannot get section header");
226 shdr
->sh_type
= SHT_PROGBITS
;
227 shdr
->sh_addr
= base_offset
+ unwinding_table_size
;
228 shdr
->sh_flags
= SHF_ALLOC
;
229 shdr
->sh_entsize
= 0;
235 * fd: file descriptor open for writing for the output file
236 * load_addr: code load address (could be zero, just used for buildid)
237 * sym: function name (for native code - used as the symbol)
238 * code: the native code
239 * csize: the code size in bytes
242 jit_write_elf(int fd
, uint64_t load_addr
, const char *sym
,
243 const void *code
, int csize
,
244 void *debug __maybe_unused
, int nr_debug_entries __maybe_unused
,
245 void *unwinding
, uint64_t unwinding_header_size
, uint64_t unwinding_size
)
253 uint64_t eh_frame_base_offset
;
258 if (elf_version(EV_CURRENT
) == EV_NONE
) {
259 warnx("ELF initialization failed");
263 e
= elf_begin(fd
, ELF_C_WRITE
, NULL
);
265 warnx("elf_begin failed");
272 ehdr
= elf_newehdr(e
);
274 warnx("cannot get ehdr");
278 ehdr
->e_ident
[EI_DATA
] = GEN_ELF_ENDIAN
;
279 ehdr
->e_ident
[EI_CLASS
] = GEN_ELF_CLASS
;
280 ehdr
->e_machine
= GEN_ELF_ARCH
;
281 ehdr
->e_type
= ET_DYN
;
282 ehdr
->e_entry
= GEN_ELF_TEXT_OFFSET
;
283 ehdr
->e_version
= EV_CURRENT
;
284 ehdr
->e_shstrndx
= unwinding
? 4 : 2; /* shdr index for section name */
287 * setup program header
289 phdr
= elf_newphdr(e
, 1);
290 phdr
[0].p_type
= PT_LOAD
;
291 phdr
[0].p_offset
= GEN_ELF_TEXT_OFFSET
;
292 phdr
[0].p_vaddr
= GEN_ELF_TEXT_OFFSET
;
293 phdr
[0].p_paddr
= GEN_ELF_TEXT_OFFSET
;
294 phdr
[0].p_filesz
= csize
;
295 phdr
[0].p_memsz
= csize
;
296 phdr
[0].p_flags
= PF_X
| PF_R
;
304 warnx("cannot create section");
308 d
= elf_newdata(scn
);
310 warnx("cannot get new data");
316 d
->d_buf
= (void *)code
;
317 d
->d_type
= ELF_T_BYTE
;
319 d
->d_version
= EV_CURRENT
;
321 shdr
= elf_getshdr(scn
);
323 warnx("cannot get section header");
328 shdr
->sh_type
= SHT_PROGBITS
;
329 shdr
->sh_addr
= GEN_ELF_TEXT_OFFSET
;
330 shdr
->sh_flags
= SHF_EXECINSTR
| SHF_ALLOC
;
331 shdr
->sh_entsize
= 0;
334 * Setup .eh_frame_hdr and .eh_frame
337 eh_frame_base_offset
= ALIGN_8(GEN_ELF_TEXT_OFFSET
+ csize
);
338 retval
= jit_add_eh_frame_info(e
, unwinding
,
339 unwinding_header_size
, unwinding_size
,
340 eh_frame_base_offset
);
347 * setup section headers string table
351 warnx("cannot create section");
355 d
= elf_newdata(scn
);
357 warnx("cannot get new data");
363 d
->d_buf
= shd_string_table
;
364 d
->d_type
= ELF_T_BYTE
;
365 d
->d_size
= sizeof(shd_string_table
);
366 d
->d_version
= EV_CURRENT
;
368 shdr
= elf_getshdr(scn
);
370 warnx("cannot get section header");
374 shdr
->sh_name
= 7; /* offset of '.shstrtab' in shd_string_table */
375 shdr
->sh_type
= SHT_STRTAB
;
377 shdr
->sh_entsize
= 0;
380 * setup symtab section
382 symtab
[1].st_size
= csize
;
383 symtab
[1].st_value
= GEN_ELF_TEXT_OFFSET
;
387 warnx("cannot create section");
391 d
= elf_newdata(scn
);
393 warnx("cannot get new data");
400 d
->d_type
= ELF_T_SYM
;
401 d
->d_size
= sizeof(symtab
);
402 d
->d_version
= EV_CURRENT
;
404 shdr
= elf_getshdr(scn
);
406 warnx("cannot get section header");
410 shdr
->sh_name
= 17; /* offset of '.symtab' in shd_string_table */
411 shdr
->sh_type
= SHT_SYMTAB
;
413 shdr
->sh_entsize
= sizeof(Elf_Sym
);
414 shdr
->sh_link
= unwinding
? 6 : 4; /* index of .strtab section */
417 * setup symbols string table
418 * 2 = 1 for 0 in 1st entry, 1 for the 0 at end of symbol for 2nd entry
420 symlen
= 2 + strlen(sym
);
421 strsym
= calloc(1, symlen
);
423 warnx("cannot allocate strsym");
426 strcpy(strsym
+ 1, sym
);
430 warnx("cannot create section");
434 d
= elf_newdata(scn
);
436 warnx("cannot get new data");
443 d
->d_type
= ELF_T_BYTE
;
445 d
->d_version
= EV_CURRENT
;
447 shdr
= elf_getshdr(scn
);
449 warnx("cannot get section header");
453 shdr
->sh_name
= 25; /* offset in shd_string_table */
454 shdr
->sh_type
= SHT_STRTAB
;
456 shdr
->sh_entsize
= 0;
459 * setup build-id section
463 warnx("cannot create section");
467 d
= elf_newdata(scn
);
469 warnx("cannot get new data");
474 * build-id generation
476 gen_build_id(&bnote
, load_addr
, code
, csize
);
477 bnote
.desc
.namesz
= sizeof(bnote
.name
); /* must include 0 termination */
478 bnote
.desc
.descsz
= sizeof(bnote
.build_id
);
479 bnote
.desc
.type
= NT_GNU_BUILD_ID
;
480 strcpy(bnote
.name
, "GNU");
485 d
->d_type
= ELF_T_BYTE
;
486 d
->d_size
= sizeof(bnote
);
487 d
->d_version
= EV_CURRENT
;
489 shdr
= elf_getshdr(scn
);
491 warnx("cannot get section header");
495 shdr
->sh_name
= 33; /* offset in shd_string_table */
496 shdr
->sh_type
= SHT_NOTE
;
498 shdr
->sh_flags
= SHF_ALLOC
;
499 shdr
->sh_size
= sizeof(bnote
);
500 shdr
->sh_entsize
= 0;
502 #ifdef HAVE_LIBDW_SUPPORT
503 if (debug
&& nr_debug_entries
) {
504 retval
= jit_add_debug_info(e
, load_addr
, debug
, nr_debug_entries
);
510 if (elf_update(e
, ELF_C_WRITE
) < 0) {
511 warnx("elf_update 4 failed");