ld.so: fix build on macOS
This commit is contained in:
parent
33499036e4
commit
b9f0f8cbd1
97
src/loader.c
97
src/loader.c
@ -35,7 +35,11 @@
|
||||
#include <stdio.h>
|
||||
#include <string.h>
|
||||
#include <errno.h>
|
||||
#if defined(__APPLE__)
|
||||
# include <mach-o/loader.h>
|
||||
#elif defined(__ELF__)
|
||||
# include <elf.h>
|
||||
#endif
|
||||
#include "loader.h"
|
||||
|
||||
#ifndef PROGNAME_LOADER
|
||||
@ -46,9 +50,9 @@
|
||||
/* Loader */
|
||||
/* private */
|
||||
/* prototypes */
|
||||
static int _error(int code, char const * format, ...);
|
||||
static int _loader_elf(int fd, char const * filename, int argc, char * argv[]);
|
||||
|
||||
static int _prot(int flags);
|
||||
static int _error(int code, char const * format, ...);
|
||||
|
||||
|
||||
/* public */
|
||||
@ -58,14 +62,6 @@ extern char ** environ;
|
||||
|
||||
/* functions */
|
||||
/* loader */
|
||||
static int _loader_do(int fd, char const * filename, int argc, char * argv[]);
|
||||
static int _do_phdr(int fd, char const * filename, Elf_Ehdr * ehdr,
|
||||
void ** entrypoint);
|
||||
static size_t _do_phdr_align_bits(unsigned long align);
|
||||
static int _do_shdr(int fd, char const * filename, Elf_Ehdr * ehdr);
|
||||
static int _do_shdr_rela(int fd, char const * filename, Elf_Shdr * shdr,
|
||||
size_t entsize);
|
||||
|
||||
int loader(char const * filename, int argc, char * argv[])
|
||||
{
|
||||
int ret;
|
||||
@ -73,12 +69,24 @@ int loader(char const * filename, int argc, char * argv[])
|
||||
|
||||
if((fd = open(filename, O_RDONLY)) < 0)
|
||||
return _error(2, "%s: %s", filename, strerror(errno));
|
||||
ret = _loader_do(fd, filename, argc, argv);
|
||||
ret = _loader_elf(fd, filename, argc, argv);
|
||||
close(fd);
|
||||
return ret;
|
||||
}
|
||||
|
||||
static int _loader_do(int fd, char const * filename, int argc, char * argv[])
|
||||
|
||||
/* private */
|
||||
/* functions */
|
||||
#if defined(__ELF__)
|
||||
static int _elf_phdr(int fd, char const * filename, Elf_Ehdr * ehdr,
|
||||
void ** entrypoint);
|
||||
static size_t _elf_phdr_align_bits(unsigned long align);
|
||||
static int _elf_prot(int flags);
|
||||
static int _elf_shdr(int fd, char const * filename, Elf_Ehdr * ehdr);
|
||||
static int _elf_shdr_rela(int fd, char const * filename, Elf_Shdr * shdr,
|
||||
size_t entsize);
|
||||
|
||||
static int _loader_elf(int fd, char const * filename, int argc, char * argv[])
|
||||
{
|
||||
int ret;
|
||||
Elf_Ehdr ehdr;
|
||||
@ -95,8 +103,8 @@ static int _loader_do(int fd, char const * filename, int argc, char * argv[])
|
||||
if(ehdr.e_ehsize != sizeof(ehdr))
|
||||
return _error(2, "%s: %s", filename,
|
||||
"Invalid or unsupported ELF file");
|
||||
if((ret = _do_phdr(fd, filename, &ehdr, &entrypoint)) != 0
|
||||
|| (ret = _do_shdr(fd, filename, &ehdr)) != 0)
|
||||
if((ret = _elf_phdr(fd, filename, &ehdr, &entrypoint)) != 0
|
||||
|| (ret = _elf_shdr(fd, filename, &ehdr)) != 0)
|
||||
return ret;
|
||||
if(entrypoint == NULL)
|
||||
return _error(2, "%s: %s", filename, "Entrypoint not set");
|
||||
@ -109,7 +117,7 @@ static int _loader_do(int fd, char const * filename, int argc, char * argv[])
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int _do_phdr(int fd, char const * filename, Elf_Ehdr * ehdr,
|
||||
static int _elf_phdr(int fd, char const * filename, Elf_Ehdr * ehdr,
|
||||
void ** entrypoint)
|
||||
{
|
||||
Elf_Phdr phdr;
|
||||
@ -144,28 +152,17 @@ static int _do_phdr(int fd, char const * filename, Elf_Ehdr * ehdr,
|
||||
# endif
|
||||
if(phdr.p_type != PT_LOAD)
|
||||
continue;
|
||||
flags = MAP_ALIGNED(_do_phdr_align_bits(phdr.p_align));
|
||||
flags = MAP_ALIGNED(_elf_phdr_align_bits(phdr.p_align));
|
||||
if(phdr.p_filesz == 0)
|
||||
{
|
||||
#if 0
|
||||
addr = NULL;
|
||||
#endif
|
||||
flags |= MAP_ANON;
|
||||
prot = _prot(phdr.p_flags);
|
||||
prot = _elf_prot(phdr.p_flags);
|
||||
f = -1;
|
||||
offset = 0;
|
||||
}
|
||||
else if(phdr.p_filesz == phdr.p_memsz)
|
||||
{
|
||||
#if 0
|
||||
addr = (void *)phdr.p_vaddr;
|
||||
#endif
|
||||
flags |= MAP_FILE;
|
||||
prot = _prot(phdr.p_flags);
|
||||
#if 0
|
||||
if(phdr.p_vaddr != 0)
|
||||
flags |= MAP_TRYFIXED;
|
||||
#endif
|
||||
if(prot & PROT_WRITE)
|
||||
flags |= MAP_PRIVATE;
|
||||
f = fd;
|
||||
@ -199,7 +196,7 @@ static int _do_phdr(int fd, char const * filename, Elf_Ehdr * ehdr,
|
||||
strerror(errno));
|
||||
memset(&addr[phdr.p_filesz], 0,
|
||||
phdr.p_memsz - phdr.p_filesz);
|
||||
prot = _prot(phdr.p_flags);
|
||||
prot = _elf_prot(phdr.p_flags);
|
||||
# ifdef DEBUG
|
||||
fprintf(stderr, "DEBUG: mprotect(%p, %lu, %d)\n",
|
||||
addr, (unsigned long)phdr.p_memsz, prot);
|
||||
@ -230,7 +227,7 @@ static int _do_phdr(int fd, char const * filename, Elf_Ehdr * ehdr,
|
||||
return 0;
|
||||
}
|
||||
|
||||
static size_t _do_phdr_align_bits(unsigned long align)
|
||||
static size_t _elf_phdr_align_bits(unsigned long align)
|
||||
{
|
||||
size_t i = 0;
|
||||
|
||||
@ -248,7 +245,17 @@ static size_t _do_phdr_align_bits(unsigned long align)
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int _do_shdr(int fd, char const * filename, Elf_Ehdr * ehdr)
|
||||
static int _elf_prot(int flags)
|
||||
{
|
||||
int ret = PROT_NONE;
|
||||
|
||||
ret |= (flags & PF_R) ? PROT_READ : 0;
|
||||
ret |= (flags & PF_W) ? PROT_WRITE : 0;
|
||||
ret |= (flags & PF_X) ? PROT_EXEC : 0;
|
||||
return ret;
|
||||
}
|
||||
|
||||
static int _elf_shdr(int fd, char const * filename, Elf_Ehdr * ehdr)
|
||||
{
|
||||
int ret;
|
||||
Elf_Shdr shdr;
|
||||
@ -281,7 +288,7 @@ static int _do_shdr(int fd, char const * filename, Elf_Ehdr * ehdr)
|
||||
# endif
|
||||
if(shdr.sh_type == SHT_REL
|
||||
|| shdr.sh_type == SHT_RELA)
|
||||
ret = _do_shdr_rela(fd, filename, &shdr,
|
||||
ret = _elf_shdr_rela(fd, filename, &shdr,
|
||||
shdr.sh_entsize);
|
||||
else
|
||||
continue;
|
||||
@ -294,7 +301,7 @@ static int _do_shdr(int fd, char const * filename, Elf_Ehdr * ehdr)
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int _do_shdr_rela(int fd, char const * filename, Elf_Shdr * shdr,
|
||||
static int _elf_shdr_rela(int fd, char const * filename, Elf_Shdr * shdr,
|
||||
size_t entsize)
|
||||
{
|
||||
Elf_Rela rela;
|
||||
@ -339,10 +346,18 @@ static int _do_shdr_rela(int fd, char const * filename, Elf_Shdr * shdr,
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
#else
|
||||
static int _loader_elf(int fd, char const * filename, int argc, char * argv[])
|
||||
{
|
||||
(void) fd;
|
||||
(void) argc;
|
||||
(void) argv;
|
||||
|
||||
return _error(1, "%s: %s", filename, "Unsupported file format");
|
||||
}
|
||||
#endif
|
||||
|
||||
|
||||
/* private */
|
||||
/* functions */
|
||||
/* error */
|
||||
static int _error(int code, char const * format, ...)
|
||||
{
|
||||
@ -355,15 +370,3 @@ static int _error(int code, char const * format, ...)
|
||||
fputs("\n", stderr);
|
||||
return code;
|
||||
}
|
||||
|
||||
|
||||
/* prot */
|
||||
static int _prot(int flags)
|
||||
{
|
||||
int ret = PROT_NONE;
|
||||
|
||||
ret |= (flags & PF_R) ? PROT_READ : 0;
|
||||
ret |= (flags & PF_W) ? PROT_WRITE : 0;
|
||||
ret |= (flags & PF_X) ? PROT_EXEC : 0;
|
||||
return ret;
|
||||
}
|
||||
|
@ -6,8 +6,8 @@ asflags=$(CPPFLAGS) $(CFLAGS)
|
||||
cppflags_force=
|
||||
cflags_force=-g
|
||||
cflags=-W -Wall -O2 -fPIE -D_FORTIFY_SOURCE=2 -fstack-protector
|
||||
ldflags_force=-static
|
||||
ldflags=-pie -Wl,-z,relro -Wl,-z,now
|
||||
ldflags_force=
|
||||
ldflags=-static -pie -Wl,-z,relro -Wl,-z,now
|
||||
dist=Makefile,loader.h
|
||||
mode=amd64-debug
|
||||
|
||||
|
Loading…
Reference in New Issue
Block a user