diff --git a/core/utils.c b/core/utils.c index 7ca087bb..56d0c9f9 100644 --- a/core/utils.c +++ b/core/utils.c @@ -2531,6 +2531,18 @@ char *uwsgi_open_and_read(char *url, int *size, int add_zero, char *magic_table[ memcpy(buffer, sym_start_ptr, sym_end_ptr - sym_start_ptr); } +#if defined(__linux__) && !defined(__BIG_ENDIAN__) + else if (!strncmp("section://", url, 10)) { + size_t s_len = 0; + buffer = uwsgi_elf_section(uwsgi.binary_path, url+10, &s_len); + if (!buffer) { + uwsgi_log("unable to find section %s in %s\n", url+10, uwsgi.binary_path); + exit(1); + } + *size = s_len; + if (add_zero) *size += 1; + } +#endif // fallback to file else { fd = open(url, O_RDONLY); @@ -4738,3 +4750,97 @@ void uwsgi_set_cpu_affinity() { } } + +#if defined(__linux__) && !defined(__BIG_ENDIAN__) +#include +char *uwsgi_elf_section(char *filename, char *s, size_t *len) { + struct stat st; + char *output = NULL; + int fd = open(filename, O_RDONLY); + if (fd < 0) { + uwsgi_error_open(filename); + return NULL; + } + + if (fstat(fd, &st)) { + uwsgi_error("stat()"); + close(fd); + return NULL; + } + + if (st.st_size < EI_NIDENT) { + uwsgi_log("invalid elf file: %s\n", filename); + close(fd); + return NULL; + } + + char *addr = mmap(NULL, st.st_size , PROT_READ, MAP_PRIVATE, fd, 0); + if (addr == MAP_FAILED) { + uwsgi_error("mmap()"); + close(fd); + return NULL; + } + + if (addr[0] != ELFMAG0) goto clear; + if (addr[1] != ELFMAG1) goto clear; + if (addr[2] != ELFMAG2) goto clear; + if (addr[3] != ELFMAG3) goto clear; + + if (addr[4] == ELFCLASS32) { + // elf header + Elf32_Ehdr *elfh = (Elf32_Ehdr *) addr; + // first section + Elf32_Shdr *sections = ((Elf32_Shdr *) (addr + elfh->e_shoff)); + // number of sections + int ns = elfh->e_shnum; + // the names table + Elf32_Shdr *table = §ions[elfh->e_shstrndx]; + // string table session pointer + char *names = addr + table->sh_offset; + Elf32_Shdr *ss = NULL; int i; + for(i=0;ish_size; + output = uwsgi_concat2n(addr + ss->sh_offset, ss->sh_size, "", 0); + } + } + else if (addr[4] == ELFCLASS64) { + // elf header + Elf64_Ehdr *elfh = (Elf64_Ehdr *) addr; + // first section + Elf64_Shdr *sections = ((Elf64_Shdr *) (addr + elfh->e_shoff)); + // number of sections + int ns = elfh->e_shnum; + // the names table + Elf64_Shdr *table = §ions[elfh->e_shstrndx]; + // string table session pointer + char *names = addr + table->sh_offset; + Elf64_Shdr *ss = NULL; int i; + for(i=0;ish_size; + output = uwsgi_concat2n(addr + ss->sh_offset, ss->sh_size, "", 0); + } + } + + +clear: + close(fd); + munmap(addr, st.st_size); + return output; +} +#endif diff --git a/uwsgi.h b/uwsgi.h index 40096911..32d9de41 100644 --- a/uwsgi.h +++ b/uwsgi.h @@ -34,7 +34,7 @@ extern "C" { #define thunder_lock if (uwsgi.threads > 1 && !uwsgi.is_et) {pthread_mutex_lock(&uwsgi.thunder_mutex);} #define thunder_unlock if (uwsgi.threads > 1 && !uwsgi.is_et) {pthread_mutex_unlock(&uwsgi.thunder_mutex);} -#define uwsgi_check_scheme(file) (!uwsgi_startswith(file, "http://", 7) || !uwsgi_startswith(file, "data://", 7) || !uwsgi_startswith(file, "sym://", 6) || !uwsgi_startswith(file, "fd://", 5) || !uwsgi_startswith(file, "exec://", 7)) +#define uwsgi_check_scheme(file) (!uwsgi_startswith(file, "http://", 7) || !uwsgi_startswith(file, "data://", 7) || !uwsgi_startswith(file, "sym://", 6) || !uwsgi_startswith(file, "fd://", 5) || !uwsgi_startswith(file, "exec://", 7) || !uwsgi_startswith(file, "section://", 10)) #define ushared uwsgi.shared @@ -3247,6 +3247,10 @@ ssize_t uwsgi_pipe_sized(int, int, size_t, int); int uwsgi_buffer_send(struct uwsgi_buffer *, int); void uwsgi_master_cleanup_hooks(void); +#if defined(__linux__) && !defined(__BIG_ENDIAN__) +char *uwsgi_elf_section(char *, char *, size_t *); +#endif + void uwsgi_check_emperor(void); #ifdef UWSGI_AS_SHARED_LIBRARY int uwsgi_init(int, char **, char **);