From 563d988084f446ac9a23f1cff8082aec2c654259 Mon Sep 17 00:00:00 2001 From: Pierre Pronchery Date: Sat, 9 Oct 2021 00:08:02 +0200 Subject: [PATCH] Avoid multiple inclusion of elf.c --- tools/common.c | 47 +++++++++++++++++++++++++++++++++++++ tools/common.h | 38 ++++++++++++++++++++++++++++++ tools/elf.c | 58 ++++++++++++++++++++++------------------------ tools/elf.h | 44 +++++++++++++++++++++++++++++++++++ tools/elf32.c | 35 ++++++++++++++++++++++++++++ tools/elf64.c | 35 ++++++++++++++++++++++++++++ tools/ldd.c | 41 ++++++++++++-------------------- tools/project.conf | 15 +++++++++--- 8 files changed, 254 insertions(+), 59 deletions(-) create mode 100644 tools/common.c create mode 100644 tools/common.h create mode 100644 tools/elf.h create mode 100644 tools/elf32.c create mode 100644 tools/elf64.c diff --git a/tools/common.c b/tools/common.c new file mode 100644 index 0000000..a356281 --- /dev/null +++ b/tools/common.c @@ -0,0 +1,47 @@ +/* $Id$ */ +/* Copyright (c) 2021 Pierre Pronchery */ +/* 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 +#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; +} diff --git a/tools/common.h b/tools/common.h new file mode 100644 index 0000000..1f1db84 --- /dev/null +++ b/tools/common.h @@ -0,0 +1,38 @@ +/* $Id$ */ +/* Copyright (c) 2021 Pierre Pronchery */ +/* 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 */ diff --git a/tools/elf.c b/tools/elf.c index 02609c1..b2bea8e 100644 --- a/tools/elf.c +++ b/tools/elf.c @@ -29,29 +29,27 @@ #include +#include +#include +#include +#include "common.h" +#include "elf.h" /* macros */ -# undef ELFFUNC -# undef ELFTYPE #if ELFSIZE == 32 -# define ELFFUNC(func) _do_ ## func ## 32 +# define ELFFUNC(func) elf32_ ## func # define ELFTYPE(type) Elf ## 32 ## _ ## type #elif ELFSIZE == 64 -# define ELFFUNC(func) _do_ ## func ## 64 +# define ELFFUNC(func) elf64_ ## func # 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); - - /* 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 +59,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 +89,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 +102,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 +116,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,7 +148,7 @@ 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); @@ -224,7 +222,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 +230,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 +242,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 +258,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; } diff --git a/tools/elf.h b/tools/elf.h new file mode 100644 index 0000000..bea4056 --- /dev/null +++ b/tools/elf.h @@ -0,0 +1,44 @@ +/* $Id$ */ +/* Copyright (c) 2021 Pierre Pronchery */ +/* 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 + +# include +# include + + +/* 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 /* !LDD_ELF_H */ diff --git a/tools/elf32.c b/tools/elf32.c new file mode 100644 index 0000000..52d2c43 --- /dev/null +++ b/tools/elf32.c @@ -0,0 +1,35 @@ +/* $Id$ */ +/* Copyright (c) 2021 Pierre Pronchery */ +/* 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" diff --git a/tools/elf64.c b/tools/elf64.c new file mode 100644 index 0000000..8901e6e --- /dev/null +++ b/tools/elf64.c @@ -0,0 +1,35 @@ +/* $Id$ */ +/* Copyright (c) 2021 Pierre Pronchery */ +/* 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" diff --git a/tools/ldd.c b/tools/ldd.c index bf2b915..935c838 100644 --- a/tools/ldd.c +++ b/tools/ldd.c @@ -33,19 +33,17 @@ #include #include #include -#include +#include "common.h" +#include "elf.h" + +#ifndef PROGNAME_LDD +# define PROGNAME_LDD "ldd" +#endif /* 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); @@ -89,34 +87,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); - 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 : ""); + ret = -error(filename, strerror(errno), 1); return ret; } @@ -124,6 +113,6 @@ static int _error(char const * error1, char const * error2, int ret) /* usage */ static int _usage(void) { - fputs("Usage: ldd filename...\n", stderr); + fputs("Usage: " PROGNAME_LDD " filename...\n", stderr); return 1; } diff --git a/tools/project.conf b/tools/project.conf index 4d1bcfb..c07fc89 100644 --- a/tools/project.conf +++ b/tools/project.conf @@ -3,7 +3,7 @@ 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,elf.c +dist=Makefile,common.h,elf.c,elf.h mode=amd64-debug #modes @@ -30,9 +30,18 @@ cflags_force= #targets [ldd] type=binary -sources=ldd.c +sources=common.c,elf32.c,elf64.c,ldd.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