Compare commits

...

34 Commits

Author SHA1 Message Date
7f235979ef ld.so: default to building native only 2024-04-09 03:34:24 +02:00
3950c363d1 Update the copyright notice 2024-04-09 03:16:25 +02:00
844bb9a404 tests: build fix for printself on Darwin 2024-04-09 03:16:09 +02:00
0005686852 Update the copyright notice 2024-04-09 02:23:56 +02:00
6f424aa3e8 loader: partial build fix for FreeBSD 2024-04-09 02:23:40 +02:00
af05d537cb ld.so: no longer build as a static binary
It seems that it is not required after all.
2024-04-09 02:21:17 +02:00
5a57b1e191 Update the copyright notice 2024-04-08 01:35:32 +02:00
78d14afcc6 tests: test 32-bit binaries if available 2024-04-08 01:35:22 +02:00
8a99c9590b tests: restore the tests.log target on amd64 2024-04-08 01:32:27 +02:00
863b9ac935 tests: add support for i386
While there, allow building 32-bit objects on 64-bit platforms.
Effectively implement it on amd64 platforms.

Default to 32-bit platforms for portability. (Native objects only)
2024-04-08 01:22:23 +02:00
707e7f920c ld.so: missing variable initialisation 2021-10-11 00:02:42 +02:00
b9f0f8cbd1 ld.so: fix build on macOS 2021-10-10 19:37:46 +02:00
33499036e4 Fix build with clang 2021-10-10 19:35:58 +02:00
9377b12f9b Disable debugging messages by default 2021-10-10 19:25:32 +02:00
ce70963043 ldd: fix build on macOS 2021-10-10 19:20:28 +02:00
3842ffdee1 Code cleanup 2021-10-09 00:54:35 +02:00
45db57f0d2 Register the "distcheck" test 2021-10-09 00:54:11 +02:00
73882121b4 Import a tests for "make distcheck" 2021-10-09 00:46:41 +02:00
6d7ed28cc5 Register a "make tests" target 2021-10-09 00:39:51 +02:00
493a3e186d Register tests.log 2021-10-09 00:37:07 +02:00
b947da0100 Register the first tests
They both fail so far.
2021-10-09 00:36:32 +02:00
1cc39e8841 Register printself-static 2021-10-09 00:31:57 +02:00
c2f0ad358b Build a normal and a static version of printself 2021-10-09 00:22:46 +02:00
563d988084 Avoid multiple inclusion of elf.c 2021-10-09 00:08:02 +02:00
caa81a4f8f Build executables as PIE by default 2021-10-08 21:26:46 +02:00
1a49c1cb00 Build ldd(1) as a PIE by default 2021-10-08 21:26:46 +02:00
c598b8c621 Register the "printself" test 2021-10-08 21:26:46 +02:00
93639abfdc Import a first helper for tests 2021-10-08 21:26:46 +02:00
6edda6ea24 Improve the handling of ASFLAGS{,F} 2021-10-08 21:26:46 +02:00
a50eee8a8b Detect the target architecture at compile-time 2021-10-08 21:26:46 +02:00
21c0ef048f Implement the assembly glue
It does not work yet though.
2021-10-08 21:26:46 +02:00
6d445f0255 Copy file contents to memory when smaller than the region 2021-10-08 21:26:46 +02:00
8e93085060 Implement relocations in a single function 2021-10-08 21:26:46 +02:00
b3170af3e2 Begin to implement ld.so 2021-10-08 21:26:46 +02:00
37 changed files with 1861 additions and 117 deletions

1
.gitignore vendored
View File

@ -1,2 +1,3 @@
Makefile
*.o
*.swp

View File

@ -1,5 +1,14 @@
package=Loader
version=0.0.0
subdirs=tools
subdirs=src,tests,tools
dist=Makefile,COPYING
targets=tests
#targets
[tests]
type=command
command=cd tests && (if [ -n "$(OBJDIR)" ]; then $(MAKE) OBJDIR="$(OBJDIR)tests/" "$(OBJDIR)tests/distcheck.log" "$(OBJDIR)tests/tests.log"; else $(MAKE) distcheck.log tests.log; fi)
depends=all
enabled=0
phony=1

5
src/.gitignore vendored Normal file
View File

@ -0,0 +1,5 @@
/ld.so
/ld.so-arm
/ld.so-i386
/ld.so-mips
/ld.so-sparc

45
src/arch/amd64/enter.S Normal file
View File

@ -0,0 +1,45 @@
/* $Id$ */
/* Copyright (c) 2021 Pierre Pronchery <khorben@defora.org> */
/* This file is part of DeforaOS System Loader */
/* All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions are
* met:
*
* 1. Redistributions of source code must retain the above copyright
* notice, this list of conditions and the following disclaimer.
*
* 2. Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in the
* documentation and/or other materials provided with the distribution.
*
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS
* IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED
* TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A
* PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
* HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
* SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED
* TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
* PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF
* LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
* NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
* SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. */
.text
.global loader_enter
#ifndef __clang__
.type loader_enter,@function
.type _loader_enter_do,@function
#endif
loader_enter:
/* reset the stack */
xor %rbp, %rbp
call _loader_enter_do
call _exit
_loader_enter_do:
jmp *%r8

View File

@ -0,0 +1 @@
dist=Makefile,enter.S

42
src/arch/i386/enter.S Normal file
View File

@ -0,0 +1,42 @@
/* $Id$ */
/* Copyright (c) 2021 Pierre Pronchery <khorben@defora.org> */
/* This file is part of DeforaOS System Loader */
/* All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions are
* met:
*
* 1. Redistributions of source code must retain the above copyright
* notice, this list of conditions and the following disclaimer.
*
* 2. Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in the
* documentation and/or other materials provided with the distribution.
*
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS
* IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED
* TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A
* PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
* HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
* SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED
* TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
* PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF
* LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
* NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
* SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. */
.text
#ifndef __clang__
.global loader_enter
.type loader_enter,@function
#endif
loader_enter:
/* reset the stack */
xor %ebp, %ebp
mov 0x10(%esp), %eax /* entrypoint */
jmp *%eax

View File

@ -0,0 +1 @@
dist=Makefile,enter.S

41
src/enter.S Normal file
View File

@ -0,0 +1,41 @@
/* $Id$ */
/* Copyright (c) 2021 Pierre Pronchery <khorben@defora.org> */
/* This file is part of DeforaOS System Loader */
/* All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions are
* met:
*
* 1. Redistributions of source code must retain the above copyright
* notice, this list of conditions and the following disclaimer.
*
* 2. Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in the
* documentation and/or other materials provided with the distribution.
*
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS
* IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED
* TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A
* PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
* HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
* SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED
* TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
* PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF
* LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
* NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
* SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. */
/* amd64 */
#if defined(__amd64__)
# include "arch/amd64/enter.S"
/* i386 */
#elif defined(__i386__)
# include "arch/i386/enter.S"
#else
# error "Unsupported platform"
#endif

31
src/enter32.S Normal file
View File

@ -0,0 +1,31 @@
/* $Id$ */
/* Copyright (c) 2021 Pierre Pronchery <khorben@defora.org> */
/* This file is part of DeforaOS System Loader */
/* All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions are
* met:
*
* 1. Redistributions of source code must retain the above copyright
* notice, this list of conditions and the following disclaimer.
*
* 2. Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in the
* documentation and/or other materials provided with the distribution.
*
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS
* IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED
* TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A
* PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
* HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
* SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED
* TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
* PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF
* LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
* NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
* SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. */
#include "enter.S"

377
src/loader.c Normal file
View File

@ -0,0 +1,377 @@
/* $Id$ */
/* Copyright (c) 2021-2024 Pierre Pronchery <khorben@defora.org> */
/* This file is part of DeforaOS System Loader */
/* All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions are
* met:
*
* 1. Redistributions of source code must retain the above copyright
* notice, this list of conditions and the following disclaimer.
*
* 2. Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in the
* documentation and/or other materials provided with the distribution.
*
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS
* IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED
* TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A
* PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
* HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
* SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED
* TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
* PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF
* LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
* NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
* SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. */
#include <sys/mman.h>
#include <stdarg.h>
#include <fcntl.h>
#include <unistd.h>
#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
# define PROGNAME_LOADER "ld.so"
#endif
/* Loader */
/* private */
/* prototypes */
static int _loader_elf(int fd, char const * filename, int argc, char * argv[]);
static int _error(int code, char const * format, ...);
/* public */
/* variables */
extern char ** environ;
/* functions */
/* loader */
int loader(char const * filename, int argc, char * argv[])
{
int ret;
int fd;
if((fd = open(filename, O_RDONLY)) < 0)
return _error(2, "%s: %s", filename, strerror(errno));
ret = _loader_elf(fd, filename, argc, argv);
close(fd);
return ret;
}
/* 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;
void * entrypoint = NULL;
if(read(fd, &ehdr, sizeof(ehdr)) != sizeof(ehdr))
return _error(2, "%s: %s", filename, strerror(errno));
/* sanity checks */
if(memcmp(ehdr.e_ident, ELFMAG, SELFMAG) != 0)
return _error(2, "%s: %s", filename, "Not an ELF file");
if(ehdr.e_version != EV_CURRENT)
return _error(2, "%s: %u: %s", filename, ehdr.e_version,
"Unsupported ELF version");
if(ehdr.e_ehsize != sizeof(ehdr))
return _error(2, "%s: %s", filename,
"Invalid or unsupported ELF file");
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");
# ifdef DEBUG
fprintf(stderr, "DEBUG: loader_enter(%d, %p, %p, %p, %p)\n",
argc, argv, environ, NULL, entrypoint);
# endif
ret = loader_enter(argc, argv, environ, NULL, entrypoint);
_exit(ret);
return 0;
}
static int _elf_phdr(int fd, char const * filename, Elf_Ehdr * ehdr,
void ** entrypoint)
{
Elf_Phdr phdr;
size_t i;
char * addr;
int prot;
int flags;
int f;
off_t offset;
if(ehdr->e_phentsize != sizeof(phdr))
return _error(2, "%s: %s", filename,
"Invalid or unsupported ELF file");
if(lseek(fd, ehdr->e_phoff, SEEK_SET) != (off_t)ehdr->e_phoff)
return _error(2, "%s: %s", filename, strerror(errno));
for(i = 0; i < ehdr->e_phnum; i++)
{
if(read(fd, &phdr, sizeof(phdr)) != sizeof(phdr))
return _error(2, "%s: %s", filename,
"Invalid or unsupported ELF file");
# ifdef DEBUG
fprintf(stderr, "DEBUG: %zu: p_type=%u p_flags=%#x"
" p_offset=%#lx p_vaddr=%#lx, p_paddr=%#lx"
" p_filesz=%lu p_memsz=%lu p_align=%lu\n", i,
phdr.p_type, phdr.p_flags,
(unsigned long)phdr.p_offset,
(unsigned long)phdr.p_vaddr,
(unsigned long)phdr.p_paddr,
(unsigned long)phdr.p_filesz,
(unsigned long)phdr.p_memsz,
(unsigned long)phdr.p_align);
# endif
if(phdr.p_type != PT_LOAD)
continue;
flags = MAP_ALIGNED(_elf_phdr_align_bits(phdr.p_align));
if(phdr.p_filesz == 0)
{
flags |= MAP_ANON;
prot = _elf_prot(phdr.p_flags);
f = -1;
offset = 0;
}
else if(phdr.p_filesz == phdr.p_memsz)
{
flags |= MAP_FILE;
prot = _elf_prot(phdr.p_flags);
if(prot & PROT_WRITE)
flags |= MAP_PRIVATE;
f = fd;
offset = phdr.p_offset;
}
else if(phdr.p_filesz < phdr.p_memsz)
{
flags |= MAP_ANON;
prot = PROT_READ | PROT_WRITE;
f = -1;
offset = 0;
}
else
return _error(2, "%s: %s", filename,
"Invalid or unsupported ELF file");
# ifdef DEBUG
fprintf(stderr, "DEBUG: mmap(%p, %lu, %d, %d, %d, %lld)\n",
NULL, (unsigned long)phdr.p_memsz, prot, flags,
f, (long long)offset);
# endif
if((addr = mmap(NULL, phdr.p_memsz, prot, flags, f, offset))
== MAP_FAILED)
return _error(2, "%s: %s", filename, strerror(errno));
/* copy and zero memory if relevant */
if(phdr.p_filesz > 0 && phdr.p_memsz > phdr.p_filesz)
{
if(lseek(fd, offset, SEEK_SET) != offset
|| read(fd, addr, phdr.p_filesz)
!= (ssize_t)phdr.p_filesz)
return _error(2, "%s: %s", filename,
strerror(errno));
memset(&addr[phdr.p_filesz], 0,
phdr.p_memsz - phdr.p_filesz);
prot = _elf_prot(phdr.p_flags);
# ifdef DEBUG
fprintf(stderr, "DEBUG: mprotect(%p, %lu, %d)\n",
addr, (unsigned long)phdr.p_memsz, prot);
# endif
if(prot != (PROT_READ | PROT_WRITE)
&& mprotect(addr, phdr.p_memsz,
prot) != 0)
return _error(2, "%s: %s", filename,
strerror(errno));
offset = ehdr->e_phoff + (i * ehdr->e_phentsize);
if(lseek(fd, offset, SEEK_SET) != offset)
return _error(2, "%s: %s", filename,
strerror(errno));
}
if(prot & PROT_EXEC)
{
*entrypoint = (char *)(ehdr->e_entry - phdr.p_vaddr
+ (intptr_t)addr);
# ifdef DEBUG
fprintf(stderr, "DEBUG: e_entry=%#lx p_vaddr=%#lx"
" addr=%p => %p\n",
(unsigned long)ehdr->e_entry,
(unsigned long)phdr.p_vaddr,
addr, *entrypoint);
# endif
}
}
return 0;
}
static size_t _elf_phdr_align_bits(unsigned long align)
{
size_t i = 0;
if(align == 0)
return 0;
for(i = 0; i < sizeof(align) * 8; i++)
if(align & (1 << i))
{
# ifdef DEBUG
fprintf(stderr, "DEBUG: %s(0x%lx) => %zu\n", __func__,
align, i);
# endif
return i;
}
return 0;
}
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;
size_t i;
off_t offset;
if(ehdr->e_shentsize != sizeof(shdr))
return _error(2, "%s: %s", filename,
"Invalid or unsupported ELF file");
if(lseek(fd, ehdr->e_shoff, SEEK_SET) != (off_t)ehdr->e_shoff)
return _error(2, "%s: %s", filename, strerror(errno));
for(i = 0; i < ehdr->e_shnum; i++)
{
if(read(fd, &shdr, sizeof(shdr)) != sizeof(shdr))
return _error(2, "%s: %s", filename,
"Invalid or unsupported ELF file");
# ifdef DEBUG
fprintf(stderr, "DEBUG: %zu: sh_name=%u sh_type=%u"
" sh_flags=%#lx sh_addr=%#lx sh_offset=%#lx"
" sh_size=%lu sh_link=%u sh_info=%u"
" sh_addralign=%#lx sh_entsize=%lu\n", i,
shdr.sh_name, shdr.sh_type,
(unsigned long)shdr.sh_flags,
(unsigned long)shdr.sh_addr,
(unsigned long)shdr.sh_offset,
(unsigned long)shdr.sh_size,
shdr.sh_link, shdr.sh_info,
(unsigned long)shdr.sh_addralign,
(unsigned long)shdr.sh_entsize);
# endif
if(shdr.sh_type == SHT_REL
|| shdr.sh_type == SHT_RELA)
ret = _elf_shdr_rela(fd, filename, &shdr,
shdr.sh_entsize);
else
continue;
if(ret != 0)
return ret;
offset = ehdr->e_shoff + i * sizeof(shdr);
if(lseek(fd, offset, SEEK_SET) != offset)
return _error(2, "%s: %s", filename, strerror(errno));
}
return 0;
}
static int _elf_shdr_rela(int fd, char const * filename, Elf_Shdr * shdr,
size_t entsize)
{
Elf_Rela rela;
size_t i;
rela.r_addend = 0;
/* TODO test according to sh_type */
if(entsize != sizeof(rela) && entsize != sizeof(Elf_Rel))
return _error(2, "%s: %s", filename,
"Invalid or unsupported ELF file");
if(lseek(fd, shdr->sh_offset, SEEK_SET) != (off_t)shdr->sh_offset)
return _error(2, "%s: %s", filename, strerror(errno));
for(i = 0; i + entsize < shdr->sh_size; i += entsize)
{
if(read(fd, &rela, entsize) != (ssize_t)entsize)
return _error(2, "%s: %s", filename,
"Invalid or unsupported ELF file");
# ifdef DEBUG
fprintf(stderr, "DEBUG: %zu: r_offset=%#lx r_type=%lu"
" r_addend=%ld\n", i,
(unsigned long)rela.r_offset,
(unsigned long)ELF_R_TYPE(rela.r_info),
(long)rela.r_addend);
# endif
switch(ELF_R_TYPE(rela.r_info))
{
# if defined(__amd64__)
case R_X86_64_NONE:
break;
case R_X86_64_GLOB_DAT:
# if defined(R_X86_64_JMP_SLOT)
case R_X86_64_JMP_SLOT:
# else
case R_X86_64_JUMP_SLOT:
# endif
case R_X86_64_RELATIVE:
/* FIXME implement */
break;
# endif
default:
return _error(2, "%s: %lu:"
" Unsupported relocation\n",
filename,
ELF_R_TYPE(rela.r_info));
}
}
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
/* error */
static int _error(int code, char const * format, ...)
{
va_list ap;
fputs(PROGNAME_LOADER ": ", stderr);
va_start(ap, format);
vfprintf(stderr, format, ap);
va_end(ap);
fputs("\n", stderr);
return code;
}

42
src/loader.h Normal file
View File

@ -0,0 +1,42 @@
/* $Id$ */
/* Copyright (c) 2021 Pierre Pronchery <khorben@defora.org> */
/* This file is part of DeforaOS System Loader */
/* All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions are
* met:
*
* 1. Redistributions of source code must retain the above copyright
* notice, this list of conditions and the following disclaimer.
*
* 2. Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in the
* documentation and/or other materials provided with the distribution.
*
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS
* IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED
* TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A
* PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
* HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
* SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED
* TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
* PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF
* LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
* NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
* SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. */
#ifndef LOADER_LOADER_H
# define LOADER_LOADER_H
/* Loader */
/* public */
/* functions */
int loader(char const * filename, int argc, char * argv[]);
int loader_enter(int argc, char * argv[], char ** envp, void * auxv,
void * entrypoint);
#endif /* !LOADER_LOADER_H */

31
src/loader32.c Normal file
View File

@ -0,0 +1,31 @@
/* $Id$ */
/* Copyright (c) 2021 Pierre Pronchery <khorben@defora.org> */
/* This file is part of DeforaOS System Loader */
/* All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions are
* met:
*
* 1. Redistributions of source code must retain the above copyright
* notice, this list of conditions and the following disclaimer.
*
* 2. Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in the
* documentation and/or other materials provided with the distribution.
*
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS
* IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED
* TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A
* PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
* HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
* SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED
* TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
* PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF
* LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
* NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
* SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. */
#include "loader.c"

76
src/main.c Normal file
View File

@ -0,0 +1,76 @@
/* $Id$ */
/* Copyright (c) 2021 Pierre Pronchery <khorben@defora.org> */
/* This file is part of DeforaOS System Loader */
/* All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions are
* met:
*
* 1. Redistributions of source code must retain the above copyright
* notice, this list of conditions and the following disclaimer.
*
* 2. Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in the
* documentation and/or other materials provided with the distribution.
*
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS
* IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED
* TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A
* PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
* HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
* SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED
* TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
* PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF
* LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
* NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
* SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. */
#include <unistd.h>
#include <stdio.h>
#include "loader.h"
#ifndef PROGNAME_LOADER
# define PROGNAME_LOADER "ld.so"
#endif
/* private */
/* prototypes */
static int _usage(void);
/* functions */
static int _usage(void)
{
fputs("Usage: " PROGNAME_LOADER " [-f filename] file [argument...]\n",
stderr);
return 1;
}
/* public */
/* functions */
/* main */
int main(int argc, char * argv[])
{
int o;
char const * filename = NULL;
while((o = getopt(argc, argv, "f:")) != -1)
switch(o)
{
case 'f':
filename = optarg;
break;
default:
return _usage();
}
if(optind == argc)
return _usage();
if(filename == NULL)
filename = argv[optind];
return loader(filename, argc - optind, &argv[optind]);
}

31
src/main32.c Normal file
View File

@ -0,0 +1,31 @@
/* $Id$ */
/* Copyright (c) 2021 Pierre Pronchery <khorben@defora.org> */
/* This file is part of DeforaOS System Loader */
/* All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions are
* met:
*
* 1. Redistributions of source code must retain the above copyright
* notice, this list of conditions and the following disclaimer.
*
* 2. Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in the
* documentation and/or other materials provided with the distribution.
*
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS
* IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED
* TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A
* PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
* HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
* SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED
* TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
* PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF
* LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
* NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
* SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. */
#include "main.c"

119
src/project.conf Normal file
View File

@ -0,0 +1,119 @@
subdirs=arch/amd64,arch/i386
targets=ld.so
as=$(CC)
asflags_force=$(CPPFLAGSF) $(CFLAGSF) -c
asflags=$(CPPFLAGS) $(CFLAGS)
cppflags_force=
cflags_force=-g
cflags=-W -Wall -O2 -fPIE -D_FORTIFY_SOURCE=2 -fstack-protector
ldflags_force=
ldflags=-Wl,-z,relro -Wl,-z,now
dist=Makefile,loader.h,loader32.c,main32.c
mode=native-debug
#modes
[mode::aarch64-debug]
targets=ld.so,ld.so-arm
[mode::aarch64-release]
targets=ld.so,ld.so-arm
cppflags_force=-DNDEBUG
cflags_force=
[mode::amd64-debug]
targets=ld.so,ld.so-i386
[mode::amd64-release]
targets=ld.so,ld.so-i386
cppflags_force=-DNDEBUG
cflags_force=
[mode::arm-debug]
targets=ld.so
[mode::arm-release]
targets=ld.so
cppflags_force=-DNDEBUG
cflags_force=
[mode::i386-debug]
[mode::i386-release]
cppflags_force=-DNDEBUG
cflags_force=
[mode::mips64-debug]
targets=ld.so,ld.so-mips
[mode::mips64-release]
targets=ld.so,ld.so-mips
cppflags_force=-DNDEBUG
cflags_force=
[mode::native-debug]
[mode::native-release]
cppflags_force=-DNDEBUG
cflags_force=
[mode::sparc64-debug]
targets=ld.so,ld.so-sparc
[mode::sparc64-release]
targets=ld.so,ld.so-sparc
cppflags_force=-DNDEBUG
cflags_force=
#targets
[ld.so]
type=binary
sources=enter.S,loader.c,main.c
install=$(PREFIX)/libexec
[ld.so-arm]
type=binary
sources=enter32.S,loader32.c,main32.c
cflags=-m32
ldflags=-m32
install=$(PREFIX)/libexec
[ld.so-i386]
type=binary
sources=enter32.S,loader32.c,main32.c
asflags=-m32
cflags=-m32
ldflags=-m32
install=$(PREFIX)/libexec
[ld.so-mips]
type=binary
sources=enter32.S,loader32.c,main32.c
cflags=-m32
ldflags=-m32
install=$(PREFIX)/libexec
[ld.so-sparc]
type=binary
sources=enter32.S,loader32.c,main32.c
cflags=-m32
ldflags=-m32
install=$(PREFIX)/libexec
#sources
[enter.S]
depends=enter.S,arch/amd64/enter.S,arch/i386/enter.S
[enter32.S]
depends=enter.S,arch/i386/enter.S
[loader.c]
depends=loader.h
[loader32.c]
depends=loader.h,loader.c
[main.c]
depends=loader.h
[main32.c]
depends=loader.h,main.c

4
tests/.gitignore vendored Normal file
View File

@ -0,0 +1,4 @@
/distcheck.log
/printself
/printself-static
/tests.log

View File

@ -0,0 +1,56 @@
/* $Id$ */
/* Copyright (c) 2021-2024 Pierre Pronchery <khorben@defora.org> */
/* This file is part of DeforaOS System Loader */
/* All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions are
* met:
*
* 1. Redistributions of source code must retain the above copyright
* notice, this list of conditions and the following disclaimer.
*
* 2. Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in the
* documentation and/or other materials provided with the distribution.
*
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS
* IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED
* TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A
* PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
* HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
* SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED
* TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
* PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF
* LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
* NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
* SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. */
#if defined(__APPLE__)
# define main _main
# define puts _puts
#endif
/* main */
.text
#if defined(__clang__)
.globl main
#else
.global main
.type main,@function
#endif
main:
/* puts(argv[0]) */
mov (%rsi), %rdi
#if defined(__PIC__) && !defined(__clang__)
call puts@PLT
#else
call puts
#endif
/* return 0x42 */
mov $0x42, %rax
ret

View File

@ -0,0 +1 @@
dist=Makefile,printself.S

View File

@ -0,0 +1,46 @@
/* $Id$ */
/* Copyright (c) 2024 Pierre Pronchery <khorben@defora.org> */
/* This file is part of DeforaOS System Loader */
/* All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions are
* met:
*
* 1. Redistributions of source code must retain the above copyright
* notice, this list of conditions and the following disclaimer.
*
* 2. Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in the
* documentation and/or other materials provided with the distribution.
*
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS
* IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED
* TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A
* PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
* HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
* SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED
* TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
* PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF
* LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
* NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
* SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. */
/* main */
.text
#ifndef __clang__
.global main
.type main,@function
#endif
main:
/* puts(argv[0]) */
movl 0x8(%esp), %eax
push (%eax)
call puts
add $0x4, %esp
/* return 0x42 */
mov $0x42, %al
ret

View File

@ -0,0 +1 @@
dist=Makefile,printself.S

108
tests/distcheck.sh Executable file
View File

@ -0,0 +1,108 @@
#!/bin/sh
#$Id$
#Copyright (c) 2021 Pierre Pronchery <khorben@defora.org>
#This file is part of DeforaOS System Loader
#All rights reserved.
#
#Redistribution and use in source and binary forms, with or without
#modification, are permitted provided that the following conditions are
#met:
#
#1. Redistributions of source code must retain the above copyright
# notice, this list of conditions and the following disclaimer.
#
#2. Redistributions in binary form must reproduce the above copyright
# notice, this list of conditions and the following disclaimer in the
# documentation and/or other materials provided with the distribution.
#
#THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS
#IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED
#TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A
#PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
#HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
#SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED
#TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
#PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF
#LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
#NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
#SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
#variables
CONFIGSH="${0%/distcheck.sh}/../config.sh"
CFLAGS=
LDFLAGS=
PROGNAME="distcheck.sh"
TARGET="tests.log"
TZ="UTC"
#executables
DATE="date"
[ -n "$MAKE" ] || MAKE="make"
MKDIR="mkdir -p"
MKTEMP="mktemp"
RM="rm -f"
[ -f "$CONFIGSH" ] && . "$CONFIGSH"
#distcheck
_distcheck()
{
(cd .. && $MAKE distcheck)
}
#date
_date()
{
if [ -n "$SOURCE_DATE_EPOCH" ]; then
TZ="$TZ" $DATE -d "@$SOURCE_DATE_EPOCH" '+%a %b %d %T %Z %Y'
else
$DATE
fi
}
#usage
_usage()
{
echo "Usage: $PROGNAME [-c] target..." 1>&2
return 1
}
#main
clean=0
while getopts "cO:P:" name; do
case "$name" in
c)
clean=1
;;
O)
export "${OPTARG%%=*}"="${OPTARG#*=}"
;;
P)
#XXX ignored
;;
?)
_usage
exit $?
;;
esac
done
shift $((OPTIND - 1))
if [ $# -eq 0 ]; then
_usage
exit $?
fi
while [ $# -ne 0 ]; do
target="$1"
shift
[ "$clean" -eq 0 ] || break
(_date; echo; _distcheck) > "$target" || exit 2
done
exit 0

31
tests/printself-static.S Normal file
View File

@ -0,0 +1,31 @@
/* $Id$ */
/* Copyright (c) 2021 Pierre Pronchery <khorben@defora.org> */
/* This file is part of DeforaOS System Loader */
/* All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions are
* met:
*
* 1. Redistributions of source code must retain the above copyright
* notice, this list of conditions and the following disclaimer.
*
* 2. Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in the
* documentation and/or other materials provided with the distribution.
*
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS
* IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED
* TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A
* PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
* HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
* SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED
* TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
* PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF
* LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
* NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
* SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. */
#include "printself.S"

41
tests/printself.S Normal file
View File

@ -0,0 +1,41 @@
/* $Id$ */
/* Copyright (c) 2021 Pierre Pronchery <khorben@defora.org> */
/* This file is part of DeforaOS System Loader */
/* All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions are
* met:
*
* 1. Redistributions of source code must retain the above copyright
* notice, this list of conditions and the following disclaimer.
*
* 2. Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in the
* documentation and/or other materials provided with the distribution.
*
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS
* IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED
* TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A
* PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
* HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
* SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED
* TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
* PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF
* LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
* NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
* SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. */
/* amd64 */
#if defined(__amd64__)
# include "arch/amd64/printself.S"
/* i386 */
#elif defined(__i386__)
# include "arch/i386/printself.S"
#else
# error "Unsupported platform"
#endif

View File

@ -0,0 +1,31 @@
/* $Id$ */
/* Copyright (c) 2024 Pierre Pronchery <khorben@defora.org> */
/* This file is part of DeforaOS System Loader */
/* All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions are
* met:
*
* 1. Redistributions of source code must retain the above copyright
* notice, this list of conditions and the following disclaimer.
*
* 2. Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in the
* documentation and/or other materials provided with the distribution.
*
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS
* IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED
* TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A
* PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
* HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
* SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED
* TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
* PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF
* LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
* NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
* SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. */
#include "printself.S"

31
tests/printself32.S Normal file
View File

@ -0,0 +1,31 @@
/* $Id$ */
/* Copyright (c) 2024 Pierre Pronchery <khorben@defora.org> */
/* This file is part of DeforaOS System Loader */
/* All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions are
* met:
*
* 1. Redistributions of source code must retain the above copyright
* notice, this list of conditions and the following disclaimer.
*
* 2. Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in the
* documentation and/or other materials provided with the distribution.
*
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS
* IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED
* TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A
* PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
* HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
* SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED
* TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
* PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF
* LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
* NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
* SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. */
#include "printself.S"

77
tests/project.conf Normal file
View File

@ -0,0 +1,77 @@
subdirs=arch/amd64,arch/i386
targets=distcheck.log,printself,printself-static,tests.log
as=$(CC)
asflags_force=$(CPPFLAGSF) $(CFLAGSF) -c
asflags=$(CPPFLAGS) $(CFLAGS)
cppflags_force=
cflags_force=-g
cflags=-W -Wall -O2 -fPIE -D_FORTIFY_SOURCE=2 -fstack-protector
ldflags=-pie -Wl,-z,relro -Wl,-z,now
dist=Makefile,distcheck.sh,tests.sh
mode=native-debug
#modes
[mode::amd64-debug]
targets=printself,printself-static,printself32,printself32-static,tests.log
[mode::amd64-release]
cppflags_force=-DNDEBUG
cflags_force=
targets=printself,printself-static,printself32,printself32-static,tests.log
[mode::i386-release]
cppflags_force=-DNDEBUG
cflags_force=
[mode::native-debug]
[mode::native-release]
cppflags_force=-DNDEBUG
cflags_force=
#targets
[distcheck.log]
type=script
script=./distcheck.sh
depends=distcheck.sh
enabled=0
[printself]
type=binary
sources=printself.S
[printself-static]
type=binary
ldflags=-static
sources=printself-static.S
[printself32]
type=binary
asflags=-m32
ldflags=-m32
sources=printself32.S
[printself32-static]
type=binary
asflags=-m32
ldflags=-m32 -static
sources=printself32-static.S
[tests.log]
type=script
script=./tests.sh
depends=$(OBJDIR)printself,$(OBJDIR)printself-static,tests.sh
enabled=0
#sources
[printself.S]
depends=arch/amd64/printself.S,arch/i386/printself.S
[printself-static.S]
depends=arch/amd64/printself.S,arch/i386/printself.S
[printself32.S]
depends=arch/amd64/printself.S,arch/i386/printself.S
[printself32-static.S]
depends=arch/amd64/printself.S,arch/i386/printself.S

148
tests/tests.sh Executable file
View File

@ -0,0 +1,148 @@
#!/bin/sh
#$Id$
#Copyright (c) 2021-2024 Pierre Pronchery <khorben@defora.org>
#This file is part of DeforaOS System Loader
#Redistribution and use in source and binary forms, with or without
#modification, are permitted provided that the following conditions are met:
#
# * Redistributions of source code must retain the above copyright notice, this
# list of conditions and the following disclaimer.
# * Redistributions in binary form must reproduce the above copyright notice,
# this list of conditions and the following disclaimer in the documentation
# and/or other materials provided with the distribution.
#
#THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
#AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
#IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
#DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE
#FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
#DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
#SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
#CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
#OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
#OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
#variables
#executables
DATE="date"
LDSO="../src/ld.so"
#settings
PROGNAME="tests.sh"
TZ="UTC"
#functions
#date
_date()
{
if [ -n "$SOURCE_DATE_EPOCH" ]; then
TZ="$TZ" $DATE -d "@$SOURCE_DATE_EPOCH" '+%a %b %d %T %Z %Y'
else
$DATE
fi
}
#error
_error()
{
echo "$PROGNAME: $@" 1>&2
return 2
}
#fail
_fail()
{
_run "$@" >> "$target"
}
#run
_run()
{
test="$1"
sep=
[ $# -eq 1 ] || sep=" "
shift
echo -n "$test:" 1>&2
(echo
echo "Testing: $test" "$@"
[ -n "$OBJDIR" ] || OBJDIR="./"
$OBJDIR$LDSO "$test" "$@") 2>&1
res=$?
if [ $res -ne 0 ]; then
echo "Test: $test$sep$@: FAIL (error $res)"
echo " FAIL" 1>&2
else
echo "Test: $test$sep$@: PASS"
echo " PASS" 1>&2
fi
return $res
}
#test
_test()
{
_run "$@" >> "$target"
res=$?
[ $res -eq 0 ] || FAILED="$FAILED $test(error $res)"
}
#usage
_usage()
{
echo "Usage: $PROGNAME [-c] target" 1>&2
echo " -c Clean the target selected" 1>&2
return 1
}
#main
clean=0
while getopts "cO:P:" name; do
case "$name" in
c)
clean=1
;;
O)
export "${OPTARG%%=*}"="${OPTARG#*=}"
;;
P)
#XXX ignored
;;
?)
_usage
exit $?
;;
esac
done
shift $((OPTIND - 1))
if [ $# -ne 1 ]; then
_error "No target specified"
_usage
exit $?
fi
target="$1"
[ "$clean" -ne 0 ] && exit 0
#main
_date > "$target"
FAILED=
echo "Performing tests:" 1>&2
echo "Expected failures:" 1>&2
_fail "printself"
_fail "printself-static"
[ -x "$OBJDIR"printself32 ] && _fail "printself32"
[ -x "$OBJDIR"printself32-static ] && _fail "printself32-static"
if [ -n "$FAILED" ]; then
_error "Failed tests:$FAILED" 1>&2
exit $?
fi
echo "All tests completed" 1>&2

47
tools/common.c Normal file
View File

@ -0,0 +1,47 @@
/* $Id$ */
/* Copyright (c) 2021 Pierre Pronchery <khorben@defora.org> */
/* This file is part of DeforaOS System Loader */
/* All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions are
* met:
*
* 1. Redistributions of source code must retain the above copyright
* notice, this list of conditions and the following disclaimer.
*
* 2. Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in the
* documentation and/or other materials provided with the distribution.
*
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS
* IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED
* TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A
* PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
* HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
* SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED
* TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
* PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF
* LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
* NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
* SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. */
#include <stdio.h>
#include "common.h"
#ifndef PROGNAME_LDD
# define PROGNAME_LDD "ldd"
#endif
/* functions */
/* error */
int error(char const * error1, char const * error2, int ret)
{
fprintf(stderr, "%s: %s%s%s\n", PROGNAME_LDD, error1,
(error2 != NULL) ? ": " : "",
(error2 != NULL) ? error2 : "");
return ret;
}

38
tools/common.h Normal file
View File

@ -0,0 +1,38 @@
/* $Id$ */
/* Copyright (c) 2021 Pierre Pronchery <khorben@defora.org> */
/* This file is part of DeforaOS System Loader */
/* All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions are
* met:
*
* 1. Redistributions of source code must retain the above copyright
* notice, this list of conditions and the following disclaimer.
*
* 2. Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in the
* documentation and/or other materials provided with the distribution.
*
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS
* IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED
* TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A
* PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
* HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
* SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED
* TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
* PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF
* LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
* NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
* SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. */
#ifndef LDD_COMMON_H
# define LDD_COMMON_H
/* functions */
int error(char const * error1, char const * error2, int ret);
#endif /* !LDD_ELF_H */

View File

@ -29,29 +29,28 @@
#include <sys/stat.h>
#include <stdlib.h>
#include <string.h>
#include <errno.h>
#include "common.h"
#include "elf.h"
#if defined(__ELF__)
/* macros */
# undef ELFFUNC
# undef ELFTYPE
#if ELFSIZE == 32
# define ELFFUNC(func) _do_ ## func ## 32
# define ELFTYPE(type) Elf ## 32 ## _ ## type
#elif ELFSIZE == 64
# define ELFFUNC(func) _do_ ## func ## 64
# define ELFTYPE(type) Elf ## 64 ## _ ## type
#else
# error ELFSIZE is not defined
#endif
/* prototypes */
static int ELFFUNC(ldd)(char const * filename, FILE * fp, ELFTYPE(Ehdr) * ehdr,
char const * ldpath);
# if ELFSIZE == 32
# define ELFFUNC(func) elf32_ ## func
# define ELFTYPE(type) Elf ## 32 ## _ ## type
# elif ELFSIZE == 64
# define ELFFUNC(func) elf64_ ## func
# define ELFTYPE(type) Elf ## 64 ## _ ## type
# else
# error ELFSIZE is not defined
# endif
/* functions */
/* ldd */
/* elf_ldd */
static int ELFFUNC(phdr)(char const * filename, FILE * fp, ELFTYPE(Ehdr) * ehdr,
ELFTYPE(Phdr) * phdr, char const * ldpath);
static int ELFFUNC(phdr_dyn)(char const * filename, FILE * fp,
@ -61,20 +60,20 @@ static int ELFFUNC(phdr_dyn_print)(char const * filename, char const * rpath);
static char * ELFFUNC(string)(char const * filename, FILE * fp,
ELFTYPE(Ehdr) * ehdr, ELFTYPE(Addr) addr, ELFTYPE(Addr) index);
static int ELFFUNC(ldd)(char const * filename, FILE * fp, ELFTYPE(Ehdr) * ehdr,
int ELFFUNC(ldd)(char const * filename, FILE * fp, ELFTYPE(Ehdr) * ehdr,
char const * ldpath)
{
int ret;
ELFTYPE(Phdr) * phdr;
if(ehdr->e_phnum == 0)
return -_error(filename, "No program header found", 1);
return -error(filename, "No program header found", 1);
if(ehdr->e_phentsize != sizeof(*phdr))
return -_error(filename, "Unexpected program header size", 1);
return -error(filename, "Unexpected program header size", 1);
if(fseek(fp, ehdr->e_phoff, SEEK_SET) != 0)
return -_error(filename, strerror(errno), 1);
return -error(filename, strerror(errno), 1);
if((phdr = malloc(sizeof(*phdr) * ehdr->e_phnum)) == NULL)
return -_error(filename, strerror(errno), 1);
return -error(filename, strerror(errno), 1);
ret = ELFFUNC(phdr)(filename, fp, ehdr, phdr, ldpath);
free(phdr);
return ret;
@ -91,9 +90,9 @@ static int ELFFUNC(phdr)(char const * filename, FILE * fp, ELFTYPE(Ehdr) * ehdr,
if(fread(phdr, sizeof(*phdr), ehdr->e_phnum, fp) != ehdr->e_phnum)
{
if(ferror(fp) != 0)
ret = -_error(filename, strerror(errno), 1);
ret = -error(filename, strerror(errno), 1);
else
ret = -_error(filename, "Corrupted ELF file", 1);
ret = -error(filename, "Corrupted ELF file", 1);
return ret;
}
for(i = 0, cnt = 0; i < ehdr->e_phnum; i++)
@ -104,12 +103,12 @@ static int ELFFUNC(phdr)(char const * filename, FILE * fp, ELFTYPE(Ehdr) * ehdr,
printf("%s:\n", filename);
if(fseek(fp, phdr[i].p_offset, SEEK_SET) != 0)
{
ret |= -_error(filename, strerror(errno), 1);
ret |= -error(filename, strerror(errno), 1);
continue;
}
if((dyn = malloc(phdr[i].p_filesz)) == NULL)
{
ret |= -_error(filename, strerror(errno), 1);
ret |= -error(filename, strerror(errno), 1);
continue;
}
if(fread(dyn, phdr[i].p_filesz, 1, fp) == 1)
@ -118,15 +117,15 @@ static int ELFFUNC(phdr)(char const * filename, FILE * fp, ELFTYPE(Ehdr) * ehdr,
else
{
if(ferror(fp) != 0)
ret |= -_error(filename, strerror(errno), 1);
ret |= -error(filename, strerror(errno), 1);
else
ret |= -_error(filename, "Corrupted ELF file",
ret |= -error(filename, "Corrupted ELF file",
1);
}
free(dyn);
}
if(cnt == 0)
ret |= -_error(filename, "Not a dynamic ELF object", 1);
ret |= -error(filename, "Not a dynamic ELF object", 1);
return ret;
}
@ -150,14 +149,14 @@ static int ELFFUNC(phdr_dyn)(char const * filename, FILE * fp,
r = i;
}
if(s < 0)
return -_error(filename, "Missing string section", 1);
return -error(filename, "Missing string section", 1);
if(s >= 0 && r >= 0)
rpath = ELFFUNC(string)(filename, fp, ehdr, dyn[s].d_un.d_val,
dyn[r].d_un.d_val);
#ifdef DEBUG
# ifdef DEBUG
fprintf(stderr, "DEBUG: %s() strtab=%ld rpath=%ld \"%s\"\n", __func__,
dyn[s].d_un.d_val, dyn[r].d_un.d_val, rpath);
#endif
# endif
for(i = 0; (i + 1) * sizeof(*dyn) < phdr->p_filesz; i++)
{
if(dyn[i].d_tag == DT_NULL)
@ -185,10 +184,10 @@ static int ELFFUNC(phdr_dyn_print)(char const * filename, char const * rpath)
struct stat st;
int res;
#ifdef DEBUG
# ifdef DEBUG
fprintf(stderr, "DEBUG: %s(\"%s\", \"%s\")\n", __func__, filename,
rpath);
#endif
# endif
if(rpath == NULL)
return -1;
for(i = 0;;)
@ -224,7 +223,7 @@ static char * ELFFUNC(string)(char const * filename, FILE * fp,
if(fseek(fp, ehdr->e_shoff, SEEK_SET) != 0)
{
_error(filename, strerror(errno), 1);
error(filename, strerror(errno), 1);
return NULL;
}
for(i = 0; i < ehdr->e_shnum; i++)
@ -232,9 +231,9 @@ static char * ELFFUNC(string)(char const * filename, FILE * fp,
if(fread(&shdr, sizeof(shdr), 1, fp) != 1)
{
if(ferror(fp) != 0)
_error(filename, strerror(errno), 1);
error(filename, strerror(errno), 1);
else
_error(filename, "Corrupted ELF file", 1);
error(filename, "Corrupted ELF file", 1);
break;
}
if(shdr.sh_type != SHT_STRTAB)
@ -244,15 +243,15 @@ static char * ELFFUNC(string)(char const * filename, FILE * fp,
if(fseek(fp, shdr.sh_offset, SEEK_SET) != 0
|| (p = malloc(shdr.sh_size)) == NULL)
{
_error(filename, strerror(errno), 1);
error(filename, strerror(errno), 1);
break;
}
if(fread(p, sizeof(*p), shdr.sh_size, fp) != shdr.sh_size)
{
if(ferror(fp) != 0)
_error(filename, strerror(errno), 1);
error(filename, strerror(errno), 1);
else
_error(filename, "Corrupted ELF file", 1);
error(filename, "Corrupted ELF file", 1);
break;
}
for(i = index; i < shdr.sh_size; i++)
@ -260,7 +259,7 @@ static char * ELFFUNC(string)(char const * filename, FILE * fp,
if(p[i] != '\0')
continue;
if((ret = strdup(&p[index])) == NULL)
_error(filename, strerror(errno), 1);
error(filename, strerror(errno), 1);
free(p);
return ret;
}
@ -269,3 +268,4 @@ static char * ELFFUNC(string)(char const * filename, FILE * fp,
free(p);
return NULL;
}
#endif

46
tools/elf.h Normal file
View File

@ -0,0 +1,46 @@
/* $Id$ */
/* Copyright (c) 2021 Pierre Pronchery <khorben@defora.org> */
/* This file is part of DeforaOS System Loader */
/* All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions are
* met:
*
* 1. Redistributions of source code must retain the above copyright
* notice, this list of conditions and the following disclaimer.
*
* 2. Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in the
* documentation and/or other materials provided with the distribution.
*
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS
* IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED
* TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A
* PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
* HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
* SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED
* TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
* PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF
* LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
* NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
* SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. */
#ifndef LDD_ELF_H
# define LDD_ELF_H
# if defined(__ELF__)
# include <stdio.h>
# include <elf.h>
/* functions */
int elf32_ldd(char const * filename, FILE * fp, Elf32_Ehdr * ehdr,
char const * ldpath);
int elf64_ldd(char const * filename, FILE * fp, Elf64_Ehdr * ehdr,
char const * ldpath);
# endif /* __ELF__ */
#endif /* !LDD_ELF_H */

35
tools/elf32.c Normal file
View File

@ -0,0 +1,35 @@
/* $Id$ */
/* Copyright (c) 2021 Pierre Pronchery <khorben@defora.org> */
/* This file is part of DeforaOS System Loader */
/* All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions are
* met:
*
* 1. Redistributions of source code must retain the above copyright
* notice, this list of conditions and the following disclaimer.
*
* 2. Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in the
* documentation and/or other materials provided with the distribution.
*
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS
* IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED
* TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A
* PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
* HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
* SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED
* TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
* PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF
* LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
* NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
* SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. */
#define ELFSIZE 32
#include "elf.h"
#include "elf.c"

35
tools/elf64.c Normal file
View File

@ -0,0 +1,35 @@
/* $Id$ */
/* Copyright (c) 2021 Pierre Pronchery <khorben@defora.org> */
/* This file is part of DeforaOS System Loader */
/* All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions are
* met:
*
* 1. Redistributions of source code must retain the above copyright
* notice, this list of conditions and the following disclaimer.
*
* 2. Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in the
* documentation and/or other materials provided with the distribution.
*
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS
* IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED
* TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A
* PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
* HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
* SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED
* TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
* PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF
* LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
* NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
* SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. */
#define ELFSIZE 64
#include "elf.h"
#include "elf.c"

View File

@ -28,56 +28,19 @@
#include <unistd.h>
#include <stdlib.h>
#include <stdio.h>
#include <string.h>
#include <errno.h>
#include <elf.h>
/* private */
/* prototypes */
static int _error(char const * error1, char const * error2, int ret);
static int _ldd(char const * filename, char const * ldpath);
#undef ELFSIZE
#define ELFSIZE 32
#include "elf.c"
#undef ELFSIZE
#define ELFSIZE 64
#include "elf.c"
static int _usage(void);
#include "common.h"
#include "elf.h"
#include "ldd.h"
/* public */
/* functions */
/* main */
int main(int argc, char * argv[])
{
int ret = 0;
int o;
int i;
char const * ldpath;
while((o = getopt(argc, argv, "")) != -1)
switch(o)
{
default:
return _usage();
}
if(optind == argc)
return _usage();
ldpath = getenv("LD_LIBRARY_PATH");
for(i = optind; i < argc; i++)
ret |= _ldd(argv[i], ldpath);
return (ret == 0) ? 0 : 2;
}
/* private */
/* functions */
/* ldd */
static int _ldd(char const * filename, char const * ldpath)
#if defined(__ELF__)
/* ldd_elf */
int ldd_elf(char const * filename, char const * ldpath)
{
int ret = 1;
FILE * fp;
@ -89,41 +52,25 @@ static int _ldd(char const * filename, char const * ldpath)
} elf;
if((fp = fopen(filename, "r")) == NULL)
return _error(filename, strerror(errno), 1);
return error(filename, strerror(errno), 1);
if(fread(&elf, sizeof(elf), 1, fp) == 1)
{
if(memcmp(elf.e_ident, ELFMAG, SELFMAG) != 0)
ret = -_error(filename, "Not an ELF file", 1);
ret = -error(filename, "Not an ELF file", 1);
else if(elf.e_ident[EI_CLASS] == ELFCLASS32)
ret = _do_ldd32(filename, fp, &elf.ehdr32, ldpath);
ret = elf32_ldd(filename, fp, &elf.ehdr32, ldpath);
else if(elf.e_ident[EI_CLASS] == ELFCLASS64)
ret = _do_ldd64(filename, fp, &elf.ehdr64, ldpath);
ret = elf64_ldd(filename, fp, &elf.ehdr64, ldpath);
else
ret = -_error(filename, "Could not determine ELF class",
ret = -error(filename, "Could not determine ELF class",
1);
}
else if(ferror(fp) != 0)
ret = -_error(filename, strerror(errno), 1);
ret = -error(filename, strerror(errno), 1);
else
ret = -_error(filename, "Not an ELF file", 1);
ret = -error(filename, "Not an ELF file", 1);
if(fclose(fp) != 0)
ret = -_error(filename, strerror(errno), 1);
ret = -error(filename, strerror(errno), 1);
return ret;
}
/* error */
static int _error(char const * error1, char const * error2, int ret)
{
fprintf(stderr, "%s: %s%s%s\n", "ldd", error1, (error2 != NULL) ? ": "
: "", (error2 != NULL) ? error2 : "");
return ret;
}
/* usage */
static int _usage(void)
{
fputs("Usage: ldd filename...\n", stderr);
return 1;
}
#endif

40
tools/ldd.h Normal file
View File

@ -0,0 +1,40 @@
/* $Id$ */
/* Copyright (c) 2021 Pierre Pronchery <khorben@defora.org> */
/* This file is part of DeforaOS System Loader */
/* All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions are
* met:
*
* 1. Redistributions of source code must retain the above copyright
* notice, this list of conditions and the following disclaimer.
*
* 2. Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in the
* documentation and/or other materials provided with the distribution.
*
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS
* IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED
* TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A
* PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
* HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
* SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED
* TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
* PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF
* LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
* NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
* SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. */
#ifndef LDD_LDD_H
# define LDD_LDD_H
/* functions */
# if defined(__ELF__)
int ldd_elf(char const * filename, char const * ldpath);
# endif
#endif /* !LDD_LDD_H */

95
tools/main.c Normal file
View File

@ -0,0 +1,95 @@
/* $Id$ */
/* Copyright (c) 2010-2021 Pierre Pronchery <khorben@defora.org> */
/* This file is part of DeforaOS System Loader */
/* All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions are
* met:
*
* 1. Redistributions of source code must retain the above copyright
* notice, this list of conditions and the following disclaimer.
*
* 2. Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in the
* documentation and/or other materials provided with the distribution.
*
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS
* IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED
* TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A
* PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
* HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
* SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED
* TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
* PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF
* LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
* NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
* SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. */
#include <unistd.h>
#include <stdlib.h>
#include <stdio.h>
#include <string.h>
#include <errno.h>
#include "common.h"
#include "ldd.h"
#ifndef PROGNAME_LDD
# define PROGNAME_LDD "ldd"
#endif
/* private */
/* prototypes */
static int _ldd_unsupported(char const * filename, char const * ldpath);
static int _usage(void);
/* public */
/* functions */
/* main */
int main(int argc, char * argv[])
{
int ret = 0;
int o;
int i;
char const * ldpath;
while((o = getopt(argc, argv, "")) != -1)
switch(o)
{
default:
return _usage();
}
if(optind == argc)
return _usage();
ldpath = getenv("LD_LIBRARY_PATH");
for(i = optind; i < argc; i++)
#if defined(__ELF__)
ret |= ldd_elf(argv[i], ldpath);
#else
ret |= _ldd_unsupported(argv[i], ldpath);
#endif
return (ret == 0) ? 0 : 2;
}
/* private */
/* functions */
/* ldd_unsupported */
static int _ldd_unsupported(char const * filename, char const * ldpath)
{
(void) ldpath;
return -error(filename, "Unsupported file format", 1);
}
/* usage */
static int _usage(void)
{
fputs("Usage: " PROGNAME_LDD " filename...\n", stderr);
return 1;
}

View File

@ -1,22 +1,56 @@
targets=ldd
cppflags_force=
cflags_force=-g
cflags=-W -Wall -O2 -pedantic -D_FORTIFY_SOURCE=2 -fstack-protector
ldflags=-Wl,-z,relro -Wl,-z,now
dist=Makefile,elf.c
mode=debug
cflags=-W -Wall -O2 -fPIE -D_FORTIFY_SOURCE=2 -fstack-protector
ldflags=-pie -Wl,-z,relro -Wl,-z,now
dist=Makefile,common.h,elf.c,elf.h,ldd.h
mode=native-debug
#modes
[mode::release]
[mode::aarch64-release]
cppflags_force=-DNDEBUG
cflags_force=
[mode::amd64-release]
cppflags_force=-DNDEBUG
cflags_force=
[mode::i386-release]
cppflags_force=-DNDEBUG
cflags_force=
[mode::mips64-release]
cppflags_force=-DNDEBUG
cflags_force=
[mode::native-debug]
[mode::native-release]
cppflags_force=-DNDEBUG
cflags_force=
[mode::sparc64-release]
cppflags_force=-DNDEBUG
cflags_force=
#targets
[ldd]
type=binary
sources=ldd.c
sources=common.c,elf32.c,elf64.c,ldd.c,main.c
install=$(BINDIR)
#sources
[common.c]
depends=common.h
[elf32.c]
depends=common.h,elf.c,elf.h
[elf64.c]
depends=common.h,elf.c,elf.h
[ldd.c]
depends=elf.c
depends=common.h,elf.h,ldd.h
[main.c]
depends=ldd.h