Import ELF Tool Chain snapshot at r3614

From http://svn.code.sf.net/p/elftoolchain/code/
This commit is contained in:
Ed Maste 2018-04-27 12:02:11 +00:00
parent 2b7f789ebf
commit 87ec209e33
56 changed files with 646 additions and 1309 deletions

136
INSTALL
View File

@ -13,12 +13,12 @@ operating systems.
================= ======== ======================= ================= ======== =======================
Operating System Version Supported Architectures Operating System Version Supported Architectures
----------------- -------- ----------------------- ----------------- -------- -----------------------
`DragonFly BSD`_ 2.10.1 i386 `DragonFly BSD`_ 5.2 amd64
FreeBSD_ 10.2 amd64 & i386 FreeBSD_ 11.1 amd64 & i386
Minix_ 3.0.2 i386 Minix_ 3.0.2 i386
NetBSD_ 7.0 i386 NetBSD_ 7.1.2 i386
OpenBSD_ v5.0 i386 OpenBSD_ 6.3 amd64
Ubuntu_ GNU/Linux 14.04LTS x86_64 Ubuntu_ GNU/Linux 17.10 x86_64
================= ======== ======================= ================= ======== =======================
.. _DragonFly BSD: http://www.dragonflybsd.org/ .. _DragonFly BSD: http://www.dragonflybsd.org/
@ -40,7 +40,7 @@ directories are present.
Prerequisites Prerequisites
------------- -------------
:DragonFly BSD 2.10.1: :DragonFly BSD 5.2:
- The core libraries and utilities should build out of the box on - The core libraries and utilities should build out of the box on
a stock install of DragonFly BSD. a stock install of DragonFly BSD.
@ -49,14 +49,14 @@ Prerequisites
#. The current release of the `Test Execution Toolkit`_ needs to #. The current release of the `Test Execution Toolkit`_ needs to
be downloaded and unpacked into the ``test/tet/`` directory. be downloaded and unpacked into the ``test/tet/`` directory.
#. The ``py26-yaml`` package needs to be installed:: #. The ``py27-yaml`` package needs to be installed::
% sudo pkgin install py26-yaml % sudo pkg install py27-yaml
- Building additional documentation is not currently supported - Building additional documentation is not currently supported
under DragonFly BSD. under DragonFly BSD.
:FreeBSD 10.2: :FreeBSD 11.1:
- The core libraries and utilities should build out of the box on - The core libraries and utilities should build out of the box on
a stock install of FreeBSD. a stock install of FreeBSD.
@ -73,7 +73,7 @@ Prerequisites
% sudo pkg install python py27-yaml % sudo pkg install python py27-yaml
- Building additional documentation is not currently supported under - Building additional documentation is not currently supported under
FreeBSD 10.2. FreeBSD 11.1.
:Minix 3.2.0: :Minix 3.2.0:
- The following packages are pre-requisites for building the - The following packages are pre-requisites for building the
@ -95,29 +95,9 @@ Prerequisites
- Building additional documentation is not currently supported - Building additional documentation is not currently supported
under Minix. under Minix.
:OpenBSD 5.0: :OpenBSD 6.3:
- The following packages are pre-requisites for building the - The following packages are pre-requisites for building the
sources on OpenBSD 5.0: sources on OpenBSD 6.3:
=================== =====================================
**Package** **Description**
=================== =====================================
``libarchive`` An archive access library.
=================== =====================================
The following command line may be used to install the necessary
pre-requisites::
# pkg_add libarchive-2.8.4p0
- The test suites cannot currently be built under OpenBSD.
- Building additional documentation is not currently supported
under OpenBSD.
:OpenBSD 5.4:
- The following packages are pre-requisites for building the
sources on OpenBSD 5.4:
=================== ===================================== =================== =====================================
**Package** **Description** **Package** **Description**
@ -135,20 +115,9 @@ Prerequisites
- Building additional documentation is not currently supported - Building additional documentation is not currently supported
under OpenBSD. under OpenBSD.
:NetBSD 7.0: :NetBSD 7.1.2:
- The following packages are pre-requisites for building the - The core libraries and utilities should build out of the box on
sources on NetBSD 7.0: a stock install of NetBSD 7.1.2.
=================== =====================================
**Package** **Description**
=================== =====================================
``libarchive`` An archive access library.
=================== =====================================
The following command line may be used to install the necessary
pre-requisites::
# pkg_add libarchive
- To build and run the test suite: - To build and run the test suite:
@ -159,14 +128,14 @@ Prerequisites
#. The following additional package needs to be installed, as #. The following additional package needs to be installed, as
listed in the example command line below :: listed in the example command line below ::
% sudo pkg_add py27-yaml % sudo pkgin install py27-yaml
- Building additional documentation is not currently supported - Building additional documentation is not currently supported
under NetBSD. under NetBSD.
:Ubuntu GNU/Linux 10.04: :Ubuntu GNU/Linux 17.10:
- The following packages are pre-requisites for building the - The following packages are pre-requisites for building the
sources on Ubuntu GNU/Linux 10.04: sources on Ubuntu GNU/Linux 17.10:
=================== ===================================== =================== =====================================
**Package** **Description** **Package** **Description**
@ -176,50 +145,10 @@ Prerequisites
``flex`` Lexical analyser. ``flex`` Lexical analyser.
``gcc`` C compiler. ``gcc`` C compiler.
``libarchive-dev`` Archive access library. ``libarchive-dev`` Archive access library.
``libbsd-dev`` BSD headers and libraries.
``libc6-dev`` Files for C language development. ``libc6-dev`` Files for C language development.
``libexpat1-dev`` An XML processing library. ``libexpat1-dev`` An XML processing library.
``m4`` Macro processor. ``m4`` Macro processor.
``pmake`` A ``make`` that uses BSD-make syntax.
``python-yaml`` A YAML library for Python.
``sharutils`` For ``uudecode``.
``zlib1g-dev`` Compression library.
=================== =====================================
The following command line may be used to install the necessary
pre-requisites::
% sudo apt-get install binutils bison flex gcc libarchive-dev \
libc6-dev m4 pmake zlib1g-dev
- To build and run the test suite:
#. The current release of the `Test Execution Toolkit`_, needs
to be downloaded and unpacked into the ``test/tet/``
directory.
#. The following additional packages need to be installed, as
listed in the example command line below::
% sudo apt-get install libexpat1-dev python-yaml sharutils
- To build additional documentation, the ``pgf`` package is
needed::
% sudo apt-get install pgf
:Ubuntu GNU/Linux 14.04:
- The following packages are pre-requisites for building the
sources on Ubuntu GNU/Linux 14.04:
=================== =====================================
**Package** **Description**
=================== =====================================
``bison`` Parser generator.
``build-essential`` Basic build tools.
``flex`` Lexical analyser.
``libarchive-dev`` Archive access library.
``libexpat1-dev`` An XML processing library.
``m4`` Macro processor.
``bmake`` NetBSD ``make``. ``bmake`` NetBSD ``make``.
``python-yaml`` A YAML library for Python. ``python-yaml`` A YAML library for Python.
``sharutils`` For ``uudecode``. ``sharutils`` For ``uudecode``.
@ -229,8 +158,8 @@ Prerequisites
The following command line may be used to install the necessary The following command line may be used to install the necessary
pre-requisites:: pre-requisites::
% sudo apt-get install bison build-essential flex libarchive-dev \ % sudo apt-get install binutils bison flex gcc libarchive-dev \
m4 bmake zlib1g-dev libc6-dev m4 bmake zlib1g-dev
- To build and run the test suite: - To build and run the test suite:
@ -243,8 +172,11 @@ Prerequisites
% sudo apt-get install libexpat1-dev python-yaml sharutils % sudo apt-get install libexpat1-dev python-yaml sharutils
- Builds of additional documentation are not currently supported - To build additional documentation, the packages listed in the
under Ubuntu GNU/Linux 14.04. example command line below are needed::
% sudo apt-get install texlive-latex-recommended texlive-pictures \
libbsd-dev
.. _Test Execution Toolkit: http://tetworks.opengroup.org/ .. _Test Execution Toolkit: http://tetworks.opengroup.org/
.. _OpenGroup: http://www.opengroup.org/ .. _OpenGroup: http://www.opengroup.org/
@ -259,9 +191,9 @@ On `DragonFly BSD`_, FreeBSD_, Minix_, NetBSD_ and OpenBSD_, use::
% make % make
On Ubuntu GNU/Linux with the **pmake** package installed, use:: On Ubuntu GNU/Linux with the **bmake** package installed, use::
% pmake % bmake
Testing the software Testing the software
@ -274,9 +206,9 @@ On `DragonFly BSD`_, FreeBSD_ and NetBSD_, use::
% make run-tests % make run-tests
On Ubuntu GNU/Linux with the **pmake** package installed, use:: On Ubuntu GNU/Linux with the **bmake** package installed, use::
% pmake run-tests % bmake run-tests
Installing the Software Installing the Software
======================= =======================
@ -287,9 +219,9 @@ On `DragonFly BSD`_, FreeBSD_, Minix_, NetBSD_ and OpenBSD_ use::
% make install % make install
On Ubuntu GNU/Linux with the **pmake** package installed, use:: On Ubuntu GNU/Linux with the **bmake** package installed, use::
% pmake install % bmake install
By default the ``install`` target will install utilities into By default the ``install`` target will install utilities into
@ -299,7 +231,7 @@ By default the ``install`` target will install utilities into
The installation directory may be changed using the ``DESTDIR`` The installation directory may be changed using the ``DESTDIR``
variable. For example:: variable. For example::
% pmake DESTDIR=$HOME/local install % bmake DESTDIR=$HOME/local install
Additional Information Additional Information
@ -310,7 +242,7 @@ website`_.
.. _project website: http://elftoolchain.sourceforge.net/ .. _project website: http://elftoolchain.sourceforge.net/
.. $Id: INSTALL 3353 2016-01-18 21:50:13Z jkoshy $ .. $Id: INSTALL 3613 2018-04-21 19:34:37Z jkoshy $
.. Local Variables: .. Local Variables:
.. mode: rst .. mode: rst

View File

@ -1,4 +1,4 @@
# $Id: Makefile 3382 2016-01-31 12:31:08Z jkoshy $ # $Id: Makefile 3605 2018-04-13 18:15:09Z jkoshy $
TOP= . TOP= .
@ -14,12 +14,12 @@ SUBDIR += libdwarf
# Build additional APIs. # Build additional APIs.
SUBDIR += libelftc SUBDIR += libelftc
.if defined(WITH_PE) && ${WITH_PE:tl} == "yes" .if defined(WITH_PE) && ${WITH_PE} == "yes"
SUBDIR += libpe SUBDIR += libpe
.endif .endif
# The instruction set analyser. # The instruction set analyser.
.if defined(WITH_ISA) && ${WITH_ISA:tl} == "yes" .if defined(WITH_ISA) && ${WITH_ISA} == "yes"
SUBDIR += isa # ('isa' does not build on all platforms yet). SUBDIR += isa # ('isa' does not build on all platforms yet).
.endif .endif
@ -39,18 +39,19 @@ SUBDIR += strings
SUBDIR += tools SUBDIR += tools
# Build the test suites. # Build the test suites.
.if exists(${.CURDIR}/test) && defined(WITH_TESTS) && ${WITH_TESTS:tl} == "yes" .if exists(${.CURDIR}/test) && defined(WITH_TESTS) && ${WITH_TESTS} == "yes"
SUBDIR += test SUBDIR += test
.endif .endif
# Build additional build tooling. # Build additional build tooling.
.if defined(WITH_BUILD_TOOLS) && ${WITH_BUILD_TOOLS:tl} == "yes" .if defined(WITH_BUILD_TOOLS) && ${WITH_BUILD_TOOLS} == "yes"
SUBDIR += tools SUBDIR += tools
.endif .endif
# Build documentation at the end. # Build documentation at the end.
.if exists(${.CURDIR}/documentation) && defined(WITH_DOCUMENTATION) && \ .if exists(${.CURDIR}/documentation) && \
${WITH_DOCUMENTATION:tl} == "yes" defined(WITH_ADDITIONAL_DOCUMENTATION) && \
${WITH_ADDITIONAL_DOCUMENTATION} == "yes"
SUBDIR += documentation SUBDIR += documentation
.endif .endif
@ -61,7 +62,7 @@ SUBDIR += documentation
# #
# Run the test suites. # Run the test suites.
.if exists(${.CURDIR}/test) && defined(WITH_TESTS) && ${WITH_TESTS:tl} == "yes" .if exists(${.CURDIR}/test) && defined(WITH_TESTS) && ${WITH_TESTS} == "yes"
run-tests: all .PHONY run-tests: all .PHONY
(cd ${.CURDIR}/test; ${MAKE} test) (cd ${.CURDIR}/test; ${MAKE} test)
.endif .endif

View File

@ -1,4 +1,4 @@
# $Id: Makefile 3107 2014-12-20 08:31:58Z kaiwang27 $ # $Id: Makefile 3608 2018-04-14 21:23:04Z jkoshy $
TOP= .. TOP= ..
@ -32,4 +32,6 @@ ${EXTRA_TARGETS}: ${PROG}
.if ${OS_HOST} == "OpenBSD" .if ${OS_HOST} == "OpenBSD"
CFLAGS+= -I/usr/local/include CFLAGS+= -I/usr/local/include
LDFLAGS+= -L/usr/local/lib LDFLAGS+= -L/usr/local/lib
.elif ${OS_HOST} == "DragonFly"
LDADD+= -lbz2
.endif .endif

View File

@ -24,6 +24,7 @@
* SUCH DAMAGE. * SUCH DAMAGE.
*/ */
#include <err.h>
#include <getopt.h> #include <getopt.h>
#include <stdarg.h> #include <stdarg.h>
#include <stdio.h> #include <stdio.h>
@ -34,7 +35,7 @@
#include <libelftc.h> #include <libelftc.h>
ELFTC_VCSID("$Id: as.c 2799 2012-12-22 09:03:29Z jkoshy $"); ELFTC_VCSID("$Id: as.c 3581 2017-10-13 23:27:45Z emaste $");
enum as_long_option_index { enum as_long_option_index {
AS_OPT_DEFSYM, AS_OPT_DEFSYM,
@ -204,7 +205,7 @@ main(int argc, char **argv)
if (option_index >= 0) if (option_index >= 0)
errx(1, errx(1,
"ERROR: option \"--%s\" is unimplemented.", "ERROR: option \"--%s\" is unimplemented.",
as_option_long_options[option_index]); as_option_long_options[option_index].name);
else else
errx(1, errx(1,
"ERROR: option '-%c' is unimplemented.", "ERROR: option '-%c' is unimplemented.",

View File

@ -1,4 +1,4 @@
# $Id: Makefile 3022 2014-04-17 18:05:58Z jkoshy $ # $Id: Makefile 3594 2018-04-11 18:26:50Z jkoshy $
TOP= .. TOP= ..
@ -7,12 +7,12 @@ INCSDIR= /usr/include
.PHONY: all clean clobber depend obj .PHONY: all clean clobber depend obj
all depend obj: all depend:
clean clobber: clean clobber:
rm -f ${CLEANFILES} rm -f ${CLEANFILES}
cleandepend: cleandepend:
rm -f .depend rm -f ${.OBJDIR}/.depend
.include "${TOP}/mk/elftoolchain.inc.mk" .include "${TOP}/mk/elftoolchain.inc.mk"

View File

@ -1,13 +1,15 @@
# #
# Build recipes for Linux based operating systems. # Build recipes for Linux based operating systems.
# #
# $Id: os.Linux.mk 2064 2011-10-26 15:12:32Z jkoshy $ # $Id: os.Linux.mk 3594 2018-04-11 18:26:50Z jkoshy $
_NATIVE_ELF_FORMAT = native-elf-format _NATIVE_ELF_FORMAT = native-elf-format
.BEGIN: ${_NATIVE_ELF_FORMAT}.h .if !make(obj)
.BEGIN: ${.OBJDIR}/${_NATIVE_ELF_FORMAT}.h
${_NATIVE_ELF_FORMAT}.h: ${.OBJDIR}/${_NATIVE_ELF_FORMAT}.h:
${.CURDIR}/${_NATIVE_ELF_FORMAT} > ${.TARGET} || rm ${.TARGET} ${.CURDIR}/${_NATIVE_ELF_FORMAT} > ${.TARGET} || rm ${.TARGET}
.endif
CLEANFILES += ${_NATIVE_ELF_FORMAT}.h CLEANFILES += ${.OBJDIR}/${_NATIVE_ELF_FORMAT}.h

View File

@ -1,7 +1,7 @@
# #
# Libelf by Example # Libelf by Example
# #
# $Id: Makefile 2441 2012-02-21 05:46:43Z jkoshy $ # $Id: Makefile 3600 2018-04-12 06:45:40Z jkoshy $
TOP = ../.. TOP = ../..
@ -10,19 +10,30 @@ DOC= libelf-by-example
SRCS= libelf-by-example.tex prog1.txt prog2.txt prog3.txt \ SRCS= libelf-by-example.tex prog1.txt prog2.txt prog3.txt \
prog4.txt prog5.txt prog6.txt prog4.txt prog5.txt prog6.txt
CLEANFILES+= ${SRCS:Mprog*:S/.txt/.c/}
.include "${TOP}/mk/elftoolchain.tex.mk" .include "${TOP}/mk/elftoolchain.tex.mk"
.if ${OS_HOST} == "Linux" .if ${OS_HOST} == "Linux"
EXTRA_FLAGS= -I/usr/include/bsd -DLIBBSD_OVERLAY
EXTRA_LIBS= -lbsd EXTRA_LIBS= -lbsd
.endif .endif
check-example-syntax: .PHONY check-example-syntax: .PHONY
.for f in ${SRCS:Mprog*} .for f in ${SRCS:Mprog*:S/.txt//}
@c=$$(basename ${f} .txt).c; sed -e 's/@[^@]*@//' \ @sed -e 's/@[^@]*@//' \
${.CURDIR}/${f} > ${.OBJDIR}/$${c}; \ ${.CURDIR}/${f}.txt > ${.OBJDIR}/${f}.c; \
echo -n $${c} ' '; cc -I${.CURDIR}/${TOP}/common \ echo -n ${f} ' '; \
-I${.CURDIR}/${TOP}/libelf ${.OBJDIR}/$${c} \ libelf="${.OBJDIR}/${TOP}/libelf"; \
-L${.CURDIR}/${TOP}/libelf -lelf ${EXTRA_LIBS} && \ if [ ! -d $${libelf} -a "${.CURDIR}" != "${.OBJDIR}" ]; then \
rm ${.OBJDIR}/$${c} a.out suffix="${.OBJDIR:S,${.CURDIR}/,,}"; \
libelf="${.CURDIR}/${TOP}/libelf/$${suffix}"; \
fi; \
cc -I${.CURDIR}/${TOP}/common \
-I${.CURDIR}/${TOP}/libelf \
${EXTRA_FLAGS} \
${.OBJDIR}/${f}.c \
-L"$${libelf}" -lelf ${EXTRA_LIBS} && \
rm ${.OBJDIR}/a.out
.endfor .endfor
@echo @echo

View File

@ -1,4 +1,4 @@
# $Id: Makefile 3381 2016-01-30 19:39:47Z jkoshy $ # $Id: Makefile 3608 2018-04-14 21:23:04Z jkoshy $
TOP= .. TOP= ..
@ -18,7 +18,7 @@ LDADD= -lelf -lelftc
LDADD+= -larchive LDADD+= -larchive
.endif .endif
.if defined(WITH_PE) && ${WITH_PE:tl} == "yes" .if defined(WITH_PE) && ${WITH_PE} == "yes"
SRCS+= pe.c SRCS+= pe.c
CFLAGS+= -DWITH_PE=1 CFLAGS+= -DWITH_PE=1
@ -51,4 +51,6 @@ ${EXTRA_TARGETS}: ${PROG}
.if ${OS_HOST} == "OpenBSD" .if ${OS_HOST} == "OpenBSD"
CFLAGS+= -I/usr/local/include CFLAGS+= -I/usr/local/include
LDFLAGS+= -L/usr/local/lib LDFLAGS+= -L/usr/local/lib
.elif ${OS_HOST} == "DragonFly"
LDADD+= -lbz2
.endif .endif

View File

@ -36,7 +36,7 @@
#include "elfcopy.h" #include "elfcopy.h"
ELFTC_VCSID("$Id: binary.c 3445 2016-04-20 19:08:30Z emaste $"); ELFTC_VCSID("$Id: binary.c 3611 2018-04-16 21:35:18Z jkoshy $");
/* /*
* Convert ELF object to `binary'. Sections with SHF_ALLOC flag set * Convert ELF object to `binary'. Sections with SHF_ALLOC flag set
@ -215,7 +215,7 @@ create_elf_from_binary(struct elfcopy *ecp, int ifd, const char *ifn)
if ((sym_basename = strdup(ifn)) == NULL) if ((sym_basename = strdup(ifn)) == NULL)
err(1, "strdup"); err(1, "strdup");
for (p = sym_basename; *p != '\0'; p++) for (p = sym_basename; *p != '\0'; p++)
if (!isalnum(*p)) if (!isalnum(*p & 0xFF))
*p = '_'; *p = '_';
#define _GEN_SYMNAME(S) do { \ #define _GEN_SYMNAME(S) do { \
snprintf(name, sizeof(name), "%s%s%s", "_binary_", sym_basename, S); \ snprintf(name, sizeof(name), "%s%s%s", "_binary_", sym_basename, S); \

View File

@ -21,9 +21,9 @@
.\" out of the use of this software, even if advised of the possibility of .\" out of the use of this software, even if advised of the possibility of
.\" such damage. .\" such damage.
.\" .\"
.\" $Id: elfcopy.1 3426 2016-03-05 13:32:28Z emaste $ .\" $Id: elfcopy.1 3565 2017-08-31 02:24:19Z emaste $
.\" .\"
.Dd March 5, 2016 .Dd August 30, 2017
.Os .Os
.Dt ELFCOPY 1 .Dt ELFCOPY 1
.Sh NAME .Sh NAME
@ -83,6 +83,7 @@
.Op Fl -srec-forceS3 .Op Fl -srec-forceS3
.Op Fl -srec-len Ns = Ns Ar val .Op Fl -srec-len Ns = Ns Ar val
.Op Fl -strip-dwo .Op Fl -strip-dwo
.Op Fl -strip-symbols= Ns Ar filename
.Op Fl -strip-unneeded .Op Fl -strip-unneeded
.Ar infile .Ar infile
.Op Ar outfile .Op Ar outfile
@ -339,6 +340,10 @@ This option is only meaningful when the output target is set to
.Dq srec . .Dq srec .
.It Fl -strip-dwo .It Fl -strip-dwo
Do not copy .dwo debug sections to the output file. Do not copy .dwo debug sections to the output file.
.It Fl -strip-symbols= Ns Ar filename
Do not copy any of the symbols specified by
.Ar filename
to the output.
.It Fl -strip-unneeded .It Fl -strip-unneeded
Do not copy symbols that are not needed for relocation processing. Do not copy symbols that are not needed for relocation processing.
.El .El

View File

@ -39,7 +39,7 @@
#include "elfcopy.h" #include "elfcopy.h"
ELFTC_VCSID("$Id: main.c 3520 2017-04-17 01:47:52Z kaiwang27 $"); ELFTC_VCSID("$Id: main.c 3577 2017-09-14 02:19:42Z emaste $");
enum options enum options
{ {
@ -679,6 +679,8 @@ create_file(struct elfcopy *ecp, const char *src, const char *dst)
if ((ifd = open(elftemp, O_RDONLY)) == -1) if ((ifd = open(elftemp, O_RDONLY)) == -1)
err(EXIT_FAILURE, "open %s failed", src); err(EXIT_FAILURE, "open %s failed", src);
close(efd); close(efd);
if (unlink(elftemp) < 0)
err(EXIT_FAILURE, "unlink %s failed", elftemp);
free(elftemp); free(elftemp);
} }
@ -1283,8 +1285,9 @@ parse_symlist_file(struct elfcopy *ecp, const char *fn, unsigned int op)
err(EXIT_FAILURE, "can not open %s", fn); err(EXIT_FAILURE, "can not open %s", fn);
if ((data = malloc(sb.st_size + 1)) == NULL) if ((data = malloc(sb.st_size + 1)) == NULL)
err(EXIT_FAILURE, "malloc failed"); err(EXIT_FAILURE, "malloc failed");
if (fread(data, 1, sb.st_size, fp) == 0 || ferror(fp)) if (sb.st_size > 0)
err(EXIT_FAILURE, "fread failed"); if (fread(data, sb.st_size, 1, fp) != 1)
err(EXIT_FAILURE, "fread failed");
fclose(fp); fclose(fp);
data[sb.st_size] = '\0'; data[sb.st_size] = '\0';
@ -1534,6 +1537,22 @@ print_version(void)
exit(EXIT_SUCCESS); exit(EXIT_SUCCESS);
} }
/*
* Compare the ending of s with end.
*/
static int
strrcmp(const char *s, const char *end)
{
size_t endlen, slen;
slen = strlen(s);
endlen = strlen(end);
if (slen >= endlen)
s += slen - endlen;
return (strcmp(s, end));
}
int int
main(int argc, char **argv) main(int argc, char **argv)
{ {
@ -1567,12 +1586,16 @@ main(int argc, char **argv)
if ((ecp->progname = ELFTC_GETPROGNAME()) == NULL) if ((ecp->progname = ELFTC_GETPROGNAME()) == NULL)
ecp->progname = "elfcopy"; ecp->progname = "elfcopy";
if (strcmp(ecp->progname, "strip") == 0) if (strrcmp(ecp->progname, "strip") == 0)
strip_main(ecp, argc, argv); strip_main(ecp, argc, argv);
else if (strcmp(ecp->progname, "mcs") == 0) else if (strrcmp(ecp->progname, "mcs") == 0)
mcs_main(ecp, argc, argv); mcs_main(ecp, argc, argv);
else else {
if (strrcmp(ecp->progname, "elfcopy") != 0 &&
strrcmp(ecp->progname, "objcopy") != 0)
warnx("program mode not known, defaulting to elfcopy");
elfcopy_main(ecp, argc, argv); elfcopy_main(ecp, argc, argv);
}
free_sec_add(ecp); free_sec_add(ecp);
free_sec_act(ecp); free_sec_act(ecp);

View File

@ -50,7 +50,7 @@
#include "_elftc.h" #include "_elftc.h"
ELFTC_VCSID("$Id: elfdump.c 3521 2017-06-04 20:07:09Z jkoshy $"); ELFTC_VCSID("$Id: elfdump.c 3584 2017-11-05 20:51:43Z jkoshy $");
#if defined(ELFTC_NEED_ELF_NOTE_DEFINITION) #if defined(ELFTC_NEED_ELF_NOTE_DEFINITION)
#include "native-elf-format.h" #include "native-elf-format.h"
@ -915,7 +915,7 @@ elf_print_ar(struct elfdump *ed, int fd)
Elf_Arhdr *arh; Elf_Arhdr *arh;
Elf_Arsym *arsym; Elf_Arsym *arsym;
Elf_Cmd cmd; Elf_Cmd cmd;
char idx[10]; char idx[21];
size_t cnt, i; size_t cnt, i;
ed->ar = ed->elf; ed->ar = ed->elf;
@ -1496,7 +1496,7 @@ elf_print_symtab(struct elfdump *ed, int i)
struct section *s; struct section *s;
const char *name; const char *name;
uint16_t *vs; uint16_t *vs;
char idx[10]; char idx[13];
Elf_Data *data; Elf_Data *data;
GElf_Sym sym; GElf_Sym sym;
int len, j, elferr, nvs; int len, j, elferr, nvs;
@ -1590,7 +1590,7 @@ elf_print_dynamic(struct elfdump *ed)
{ {
struct section *s; struct section *s;
const char *name; const char *name;
char idx[10]; char idx[13];
Elf_Data *data; Elf_Data *data;
GElf_Dyn dyn; GElf_Dyn dyn;
int elferr, i, len; int elferr, i, len;
@ -2052,7 +2052,7 @@ elf_print_note(struct elfdump *ed)
size_t count; size_t count;
int elferr, i; int elferr, i;
uint8_t *src; uint8_t *src;
char idx[10]; char idx[17];
s = NULL; s = NULL;
for (i = 0; (size_t)i < ed->shnum; i++) { for (i = 0; (size_t)i < ed->shnum; i++) {

View File

@ -1,4 +1,4 @@
# $Id: Makefile 3407 2016-02-14 17:47:23Z jkoshy $ # $Id: Makefile 3594 2018-04-11 18:26:50Z jkoshy $
TOP= .. TOP= ..
@ -47,6 +47,6 @@ YFLAGS= -d
.SUFFIXES: .ld .c .SUFFIXES: .ld .c
.ld.c: .ld.c:
awk -f ld_script.awk ${.ALLSRC} > ${.TARGET} awk -f ${.CURDIR}/ld_script.awk ${.ALLSRC} > ${.TARGET}
.include "${TOP}/mk/elftoolchain.prog.mk" .include "${TOP}/mk/elftoolchain.prog.mk"

View File

@ -1,10 +1,19 @@
# $Id: ld_script.awk 2493 2012-04-15 18:59:09Z kaiwang27 $ # Transform text file contents into a string literal.
#
# Usage: awk -f THIS-SCRIPT INPUT > OUTPUT
#
# $Id: ld_script.awk 3593 2018-04-11 18:26:20Z jkoshy $
BEGIN { BEGIN {
# Generate a symbol name based on the last component
# of the input file name.
split(ARGV[1], s, "."); split(ARGV[1], s, ".");
sub(".*/", "", s[1]);
printf "const char *%s = ", s[1]; printf "const char *%s = ", s[1];
} }
# Enclose each line of text with a preceding and trailing '"',
# escaping any '"' characters that are present.
{ {
printf "\""; printf "\"";
gsub("\"", "\\\""); gsub("\"", "\\\"");

View File

@ -1,6 +1,6 @@
# $Id: Makefile 3097 2014-09-02 22:10:18Z kaiwang27 $ # $Id: Makefile 3594 2018-04-11 18:26:50Z jkoshy $
TOP= ${.CURDIR}/.. TOP= ..
LIB= dwarf LIB= dwarf

View File

@ -24,7 +24,7 @@
* OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
* SUCH DAMAGE. * SUCH DAMAGE.
* *
* $Id: libdwarf.h 3295 2016-01-08 22:08:10Z jkoshy $ * $Id: libdwarf.h 3578 2017-09-14 02:21:28Z emaste $
*/ */
#ifndef _LIBDWARF_H_ #ifndef _LIBDWARF_H_
@ -440,6 +440,7 @@ enum Dwarf_ISA {
DW_ISA_X86, DW_ISA_X86,
DW_ISA_X86_64, DW_ISA_X86_64,
DW_ISA_AARCH64, DW_ISA_AARCH64,
DW_ISA_RISCV,
DW_ISA_MAX DW_ISA_MAX
}; };

View File

@ -26,7 +26,7 @@
#include "_libdwarf.h" #include "_libdwarf.h"
ELFTC_VCSID("$Id: libdwarf_frame.c 3106 2014-12-19 16:00:58Z kaiwang27 $"); ELFTC_VCSID("$Id: libdwarf_frame.c 3589 2018-03-13 20:34:33Z kaiwang27 $");
static int static int
_dwarf_frame_find_cie(Dwarf_FrameSec fs, Dwarf_Unsigned offset, _dwarf_frame_find_cie(Dwarf_FrameSec fs, Dwarf_Unsigned offset,
@ -142,6 +142,8 @@ _dwarf_frame_parse_lsb_cie_augment(Dwarf_Debug dbg, Dwarf_Cie cie,
augdata_p = cie->cie_augdata; augdata_p = cie->cie_augdata;
while (*aug_p != '\0') { while (*aug_p != '\0') {
switch (*aug_p) { switch (*aug_p) {
case 'S':
break;
case 'L': case 'L':
/* Skip one augment in augment data. */ /* Skip one augment in augment data. */
augdata_p++; augdata_p++;

View File

@ -26,7 +26,7 @@
#include "_libdwarf.h" #include "_libdwarf.h"
ELFTC_VCSID("$Id: libdwarf_reloc.c 3198 2015-05-14 18:36:19Z emaste $"); ELFTC_VCSID("$Id: libdwarf_reloc.c 3578 2017-09-14 02:21:28Z emaste $");
Dwarf_Unsigned Dwarf_Unsigned
_dwarf_get_reloc_type(Dwarf_P_Debug dbg, int is64) _dwarf_get_reloc_type(Dwarf_P_Debug dbg, int is64)
@ -49,6 +49,8 @@ _dwarf_get_reloc_type(Dwarf_P_Debug dbg, int is64)
return (R_ARM_ABS32); return (R_ARM_ABS32);
case DW_ISA_MIPS: case DW_ISA_MIPS:
return (is64 ? R_MIPS_64 : R_MIPS_32); return (is64 ? R_MIPS_64 : R_MIPS_32);
case DW_ISA_RISCV:
return (is64 ? R_RISCV_64 : R_RISCV_32);
case DW_ISA_IA64: case DW_ISA_IA64:
return (is64 ? R_IA_64_DIR64LSB : R_IA_64_DIR32LSB); return (is64 ? R_IA_64_DIR64LSB : R_IA_64_DIR32LSB);
default: default:
@ -101,6 +103,12 @@ _dwarf_get_reloc_size(Dwarf_Debug dbg, Dwarf_Unsigned rel_type)
else if (rel_type == R_MIPS_64) else if (rel_type == R_MIPS_64)
return (8); return (8);
break; break;
case EM_RISCV:
if (rel_type == R_RISCV_32)
return (4);
else if (rel_type == R_RISCV_64)
return (8);
break;
case EM_IA_64: case EM_IA_64:
if (rel_type == R_IA_64_SECREL32LSB) if (rel_type == R_IA_64_SECREL32LSB)
return (4); return (4);

View File

@ -1,6 +1,6 @@
# $Id: Makefile 2605 2012-10-02 17:52:20Z jkoshy $ # $Id: Makefile 3594 2018-04-11 18:26:50Z jkoshy $
TOP= ${.CURDIR}/.. TOP= ..
LIB= elf LIB= elf

View File

@ -23,7 +23,7 @@
* OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
* SUCH DAMAGE. * SUCH DAMAGE.
* *
* $Id: _libelf_config.h 3400 2016-02-12 18:38:49Z emaste $ * $Id: _libelf_config.h 3566 2017-08-31 02:28:40Z emaste $
*/ */
#if defined(__APPLE__) || defined(__DragonFly__) #if defined(__APPLE__) || defined(__DragonFly__)
@ -97,7 +97,7 @@
#define LIBELF_BYTEORDER ELFDATA2MSB #define LIBELF_BYTEORDER ELFDATA2MSB
#define LIBELF_CLASS ELFCLASS32 #define LIBELF_CLASS ELFCLASS32
#elif defined(__riscv64) #elif defined(__riscv) && (__riscv_xlen == 64)
#define LIBELF_ARCH EM_RISCV #define LIBELF_ARCH EM_RISCV
#define LIBELF_BYTEORDER ELFDATA2LSB #define LIBELF_BYTEORDER ELFDATA2LSB

View File

@ -31,7 +31,7 @@
#include "_libelf.h" #include "_libelf.h"
ELFTC_VCSID("$Id: gelf_phdr.c 3177 2015-03-30 18:19:41Z emaste $"); ELFTC_VCSID("$Id: gelf_phdr.c 3576 2017-09-14 02:15:29Z emaste $");
Elf32_Phdr * Elf32_Phdr *
elf32_getphdr(Elf *e) elf32_getphdr(Elf *e)
@ -53,10 +53,17 @@ gelf_getphdr(Elf *e, int index, GElf_Phdr *d)
Elf64_Ehdr *eh64; Elf64_Ehdr *eh64;
Elf32_Phdr *ep32; Elf32_Phdr *ep32;
Elf64_Phdr *ep64; Elf64_Phdr *ep64;
size_t phnum;
if (d == NULL || e == NULL || if (d == NULL || e == NULL ||
((ec = e->e_class) != ELFCLASS32 && ec != ELFCLASS64) || ((ec = e->e_class) != ELFCLASS32 && ec != ELFCLASS64) ||
(e->e_kind != ELF_K_ELF) || index < 0) { (e->e_kind != ELF_K_ELF) || index < 0 ||
elf_getphdrnum(e, &phnum) < 0) {
LIBELF_SET_ERROR(ARGUMENT, 0);
return (NULL);
}
if ((size_t)index >= phnum) {
LIBELF_SET_ERROR(ARGUMENT, 0); LIBELF_SET_ERROR(ARGUMENT, 0);
return (NULL); return (NULL);
} }
@ -66,11 +73,6 @@ gelf_getphdr(Elf *e, int index, GElf_Phdr *d)
((ep32 = _libelf_getphdr(e, ELFCLASS32)) == NULL)) ((ep32 = _libelf_getphdr(e, ELFCLASS32)) == NULL))
return (NULL); return (NULL);
if (index >= eh32->e_phnum) {
LIBELF_SET_ERROR(ARGUMENT, 0);
return (NULL);
}
ep32 += index; ep32 += index;
d->p_type = ep32->p_type; d->p_type = ep32->p_type;
@ -87,11 +89,6 @@ gelf_getphdr(Elf *e, int index, GElf_Phdr *d)
(ep64 = _libelf_getphdr(e, ELFCLASS64)) == NULL) (ep64 = _libelf_getphdr(e, ELFCLASS64)) == NULL)
return (NULL); return (NULL);
if (index >= eh64->e_phnum) {
LIBELF_SET_ERROR(ARGUMENT, 0);
return (NULL);
}
ep64 += index; ep64 += index;
*d = *ep64; *d = *ep64;
@ -125,13 +122,15 @@ gelf_newphdr(Elf *e, size_t count)
int int
gelf_update_phdr(Elf *e, int ndx, GElf_Phdr *s) gelf_update_phdr(Elf *e, int ndx, GElf_Phdr *s)
{ {
int ec, phnum; int ec;
size_t phnum;
void *ehdr; void *ehdr;
Elf32_Phdr *ph32; Elf32_Phdr *ph32;
Elf64_Phdr *ph64; Elf64_Phdr *ph64;
if (s == NULL || e == NULL || e->e_kind != ELF_K_ELF || if (s == NULL || e == NULL || e->e_kind != ELF_K_ELF ||
((ec = e->e_class) != ELFCLASS32 && ec != ELFCLASS64)) { ((ec = e->e_class) != ELFCLASS32 && ec != ELFCLASS64) ||
elf_getphdrnum(e, &phnum) < 0) {
LIBELF_SET_ERROR(ARGUMENT, 0); LIBELF_SET_ERROR(ARGUMENT, 0);
return (0); return (0);
} }
@ -144,12 +143,7 @@ gelf_update_phdr(Elf *e, int ndx, GElf_Phdr *s)
if ((ehdr = _libelf_ehdr(e, ec, 0)) == NULL) if ((ehdr = _libelf_ehdr(e, ec, 0)) == NULL)
return (0); return (0);
if (ec == ELFCLASS32) if (ndx < 0 || (size_t)ndx > phnum) {
phnum = ((Elf32_Ehdr *) ehdr)->e_phnum;
else
phnum = ((Elf64_Ehdr *) ehdr)->e_phnum;
if (ndx < 0 || ndx > phnum) {
LIBELF_SET_ERROR(ARGUMENT, 0); LIBELF_SET_ERROR(ARGUMENT, 0);
return (0); return (0);
} }

View File

@ -31,7 +31,7 @@
#include "_libelf.h" #include "_libelf.h"
ELFTC_VCSID("$Id: libelf_ehdr.c 3174 2015-03-27 17:13:41Z emaste $"); ELFTC_VCSID("$Id: libelf_ehdr.c 3575 2017-09-14 02:13:36Z emaste $");
/* /*
* Retrieve counts for sections, phdrs and the section string table index * Retrieve counts for sections, phdrs and the section string table index
@ -170,10 +170,6 @@ _libelf_ehdr(Elf *e, int ec, int allocate)
(*xlator)((unsigned char*) ehdr, msz, e->e_rawfile, (size_t) 1, (*xlator)((unsigned char*) ehdr, msz, e->e_rawfile, (size_t) 1,
e->e_byteorder != LIBELF_PRIVATE(byteorder)); e->e_byteorder != LIBELF_PRIVATE(byteorder));
/*
* If extended numbering is being used, read the correct
* number of sections and program header entries.
*/
if (ec == ELFCLASS32) { if (ec == ELFCLASS32) {
phnum = ((Elf32_Ehdr *) ehdr)->e_phnum; phnum = ((Elf32_Ehdr *) ehdr)->e_phnum;
shnum = ((Elf32_Ehdr *) ehdr)->e_shnum; shnum = ((Elf32_Ehdr *) ehdr)->e_shnum;
@ -193,12 +189,19 @@ _libelf_ehdr(Elf *e, int ec, int allocate)
return (NULL); return (NULL);
} }
if (shnum != 0 || shoff == 0LL) { /* not using extended numbering */ /*
* If extended numbering is being used, read the correct
* number of sections and program header entries.
*/
if ((shnum == 0 && shoff != 0) || phnum == PN_XNUM || strndx == SHN_XINDEX) {
if (_libelf_load_extended(e, ec, shoff, phnum, strndx) == 0)
return (NULL);
} else {
/* not using extended numbering */
e->e_u.e_elf.e_nphdr = phnum; e->e_u.e_elf.e_nphdr = phnum;
e->e_u.e_elf.e_nscn = shnum; e->e_u.e_elf.e_nscn = shnum;
e->e_u.e_elf.e_strndx = strndx; e->e_u.e_elf.e_strndx = strndx;
} else if (_libelf_load_extended(e, ec, shoff, phnum, strndx) == 0) }
return (NULL);
return (ehdr); return (ehdr);
} }

View File

@ -1,6 +1,6 @@
# $Id: Makefile 3489 2016-08-31 00:12:15Z emaste $ # $Id: Makefile 3601 2018-04-12 16:58:53Z jkoshy $
TOP= ${.CURDIR}/.. TOP= ..
LIB= elftc LIB= elftc
@ -28,7 +28,8 @@ SHLIB_MAJOR= 1
WARNS?= 6 WARNS?= 6
CLEANFILES+= elftc_version.c ELFTC_VERSION_FILE= ${.OBJDIR}/elftc_version.c
CLEANFILES+= ${ELFTC_VERSION_FILE}
LDADD+= -lelf LDADD+= -lelf
@ -50,10 +51,10 @@ MLINKS= elftc_bfd_find_target.3 elftc_bfd_target_byteorder.3 \
elftc_string_table_create.3 elftc_string_table_insert.3 \ elftc_string_table_create.3 elftc_string_table_insert.3 \
elftc_string_table_create.3 elftc_string_table_lookup.3 elftc_string_table_create.3 elftc_string_table_lookup.3
.if !make(clean) && !make(clobber) .if !make(clean) && !make(clobber) && !make(obj)
.BEGIN: .SILENT .BEGIN: .SILENT
${.CURDIR}/make-toolchain-version -t ${TOP} -r ${RELEASE} \ ${.CURDIR}/make-toolchain-version -t ${.CURDIR}/${TOP} \
-h ${OS_HOST} -r ${RELEASE} -h ${OS_HOST} -o ${ELFTC_VERSION_FILE}
.endif .endif
.include "${TOP}/mk/elftoolchain.lib.mk" .include "${TOP}/mk/elftoolchain.lib.mk"

View File

@ -501,6 +501,120 @@ elftc_reloc_type_str(unsigned int mach, unsigned int type)
case 116: return "R_PPC_EMB_RELSDA"; case 116: return "R_PPC_EMB_RELSDA";
} }
break; break;
case EM_PPC64:
switch(type) {
case 0: return "R_PPC64_NONE";
case 1: return "R_PPC64_ADDR32";
case 2: return "R_PPC64_ADDR24";
case 3: return "R_PPC64_ADDR16";
case 4: return "R_PPC64_ADDR16_LO";
case 5: return "R_PPC64_ADDR16_HI";
case 6: return "R_PPC64_ADDR16_HA";
case 7: return "R_PPC64_ADDR14";
case 8: return "R_PPC64_ADDR14_BRTAKEN";
case 9: return "R_PPC64_ADDR14_BRNTAKEN";
case 10: return "R_PPC64_REL24";
case 11: return "R_PPC64_REL14";
case 12: return "R_PPC64_REL14_BRTAKEN";
case 13: return "R_PPC64_REL14_BRNTAKEN";
case 14: return "R_PPC64_GOT16";
case 15: return "R_PPC64_GOT16_LO";
case 16: return "R_PPC64_GOT16_HI";
case 17: return "R_PPC64_GOT16_HA";
case 19: return "R_PPC64_COPY";
case 20: return "R_PPC64_GLOB_DAT";
case 21: return "R_PPC64_JMP_SLOT";
case 22: return "R_PPC64_RELATIVE";
case 24: return "R_PPC64_UADDR32";
case 25: return "R_PPC64_UADDR16";
case 26: return "R_PPC64_REL32";
case 27: return "R_PPC64_PLT32";
case 28: return "R_PPC64_PLTREL32";
case 29: return "R_PPC64_PLT16_LO";
case 30: return "R_PPC64_PLT16_HI";
case 31: return "R_PPC64_PLT16_HA";
case 33: return "R_PPC64_SECTOFF";
case 34: return "R_PPC64_SECTOFF_LO";
case 35: return "R_PPC64_SECTOFF_HI";
case 36: return "R_PPC64_SECTOFF_HA";
case 37: return "R_PPC64_ADDR30";
case 38: return "R_PPC64_ADDR64";
case 39: return "R_PPC64_ADDR16_HIGHER";
case 40: return "R_PPC64_ADDR16_HIGHERA";
case 41: return "R_PPC64_ADDR16_HIGHEST";
case 42: return "R_PPC64_ADDR16_HIGHESTA";
case 43: return "R_PPC64_UADDR64";
case 44: return "R_PPC64_REL64";
case 45: return "R_PPC64_PLT64";
case 46: return "R_PPC64_PLTREL64";
case 47: return "R_PPC64_TOC16";
case 48: return "R_PPC64_TOC16_LO";
case 49: return "R_PPC64_TOC16_HI";
case 50: return "R_PPC64_TOC16_HA";
case 51: return "R_PPC64_TOC";
case 52: return "R_PPC64_PLTGOT16";
case 53: return "R_PPC64_PLTGOT16_LO";
case 54: return "R_PPC64_PLTGOT16_HI";
case 55: return "R_PPC64_PLTGOT16_HA";
case 56: return "R_PPC64_ADDR16_DS";
case 57: return "R_PPC64_ADDR16_LO_DS";
case 58: return "R_PPC64_GOT16_DS";
case 59: return "R_PPC64_GOT16_LO_DS";
case 60: return "R_PPC64_PLT16_LO_DS";
case 61: return "R_PPC64_SECTOFF_DS";
case 62: return "R_PPC64_SECTOFF_LO_DS";
case 63: return "R_PPC64_TOC16_DS";
case 64: return "R_PPC64_TOC16_LO_DS";
case 65: return "R_PPC64_PLTGOT16_DS";
case 66: return "R_PPC64_PLTGOT16_LO_DS";
case 67: return "R_PPC64_TLS";
case 68: return "R_PPC64_DTPMOD64";
case 69: return "R_PPC64_TPREL16";
case 70: return "R_PPC64_TPREL16_LO";
case 71: return "R_PPC64_TPREL16_HI";
case 72: return "R_PPC64_TPREL16_HA";
case 73: return "R_PPC64_TPREL64";
case 74: return "R_PPC64_DTPREL16";
case 75: return "R_PPC64_DTPREL16_LO";
case 76: return "R_PPC64_DTPREL16_HI";
case 77: return "R_PPC64_DTPREL16_HA";
case 78: return "R_PPC64_DTPREL64";
case 79: return "R_PPC64_GOT_TLSGD16";
case 80: return "R_PPC64_GOT_TLSGD16_LO";
case 81: return "R_PPC64_GOT_TLSGD16_HI";
case 82: return "R_PPC64_GOT_TLSGD16_HA";
case 83: return "R_PPC64_GOT_TLSLD16";
case 84: return "R_PPC64_GOT_TLSLD16_LO";
case 85: return "R_PPC64_GOT_TLSLD16_HI";
case 86: return "R_PPC64_GOT_TLSLD16_HA";
case 87: return "R_PPC64_GOT_TPREL16_DS";
case 88: return "R_PPC64_GOT_TPREL16_LO_DS";
case 89: return "R_PPC64_GOT_TPREL16_HI";
case 90: return "R_PPC64_GOT_TPREL16_HA";
case 91: return "R_PPC64_GOT_DTPREL16_DS";
case 92: return "R_PPC64_GOT_DTPREL16_LO_DS";
case 93: return "R_PPC64_GOT_DTPREL16_HI";
case 94: return "R_PPC64_GOT_DTPREL16_HA";
case 95: return "R_PPC64_TPREL16_DS";
case 96: return "R_PPC64_TPREL16_LO_DS";
case 97: return "R_PPC64_TPREL16_HIGHER";
case 98: return "R_PPC64_TPREL16_HIGHERA";
case 99: return "R_PPC64_TPREL16_HIGHEST";
case 100: return "R_PPC64_TPREL16_HIGHESTA";
case 101: return "R_PPC64_DTPREL16_DS";
case 102: return "R_PPC64_DTPREL16_LO_DS";
case 103: return "R_PPC64_DTPREL16_HIGHER";
case 104: return "R_PPC64_DTPREL16_HIGHERA";
case 105: return "R_PPC64_DTPREL16_HIGHEST";
case 106: return "R_PPC64_DTPREL16_HIGHESTA";
case 107: return "R_PPC64_TLSGD";
case 108: return "R_PPC64_TLSLD";
case 249: return "R_PPC64_REL16";
case 250: return "R_PPC64_REL16_LO";
case 251: return "R_PPC64_REL16_HI";
case 252: return "R_PPC64_REL16_HA";
}
break;
case EM_RISCV: case EM_RISCV:
switch(type) { switch(type) {
case 0: return "R_RISCV_NONE"; case 0: return "R_RISCV_NONE";
@ -550,6 +664,37 @@ elftc_reloc_type_str(unsigned int mach, unsigned int type)
case 48: return "R_RISCV_GPREL_S"; case 48: return "R_RISCV_GPREL_S";
} }
break; break;
case EM_S390:
switch (type) {
case 0: return "R_390_NONE";
case 1: return "R_390_8";
case 2: return "R_390_12";
case 3: return "R_390_16";
case 4: return "R_390_32";
case 5: return "R_390_PC32";
case 6: return "R_390_GOT12";
case 7: return "R_390_GOT32";
case 8: return "R_390_PLT32";
case 9: return "R_390_COPY";
case 10: return "R_390_GLOB_DAT";
case 11: return "R_390_JMP_SLOT";
case 12: return "R_390_RELATIVE";
case 13: return "R_390_GOTOFF";
case 14: return "R_390_GOTPC";
case 15: return "R_390_GOT16";
case 16: return "R_390_PC16";
case 17: return "R_390_PC16DBL";
case 18: return "R_390_PLT16DBL";
case 19: return "R_390_PC32DBL";
case 20: return "R_390_PLT32DBL";
case 21: return "R_390_GOTPCDBL";
case 22: return "R_390_64";
case 23: return "R_390_PC64";
case 24: return "R_390_GOT64";
case 25: return "R_390_PLT64";
case 26: return "R_390_GOTENT";
}
break;
case EM_SPARC: case EM_SPARC:
case EM_SPARCV9: case EM_SPARCV9:
switch(type) { switch(type) {

View File

@ -37,7 +37,7 @@
#include "_libelftc.h" #include "_libelftc.h"
ELFTC_VCSID("$Id: libelftc_dem_gnu3.c 3560 2017-06-25 00:28:23Z kaiwang27 $"); ELFTC_VCSID("$Id: libelftc_dem_gnu3.c 3583 2017-10-15 15:38:47Z emaste $");
/** /**
* @file cpp_demangle.c * @file cpp_demangle.c
@ -574,8 +574,7 @@ cpp_demangle_push_type_qualifier(struct cpp_demangle_data *ddata,
if (!DEM_PUSH_STR(ddata, " imaginary")) if (!DEM_PUSH_STR(ddata, " imaginary"))
goto clean; goto clean;
if (type_str != NULL) { if (type_str != NULL) {
if (!vector_str_push(&subst_v, " imaginary", if (!VEC_PUSH_STR(&subst_v, " imaginary"))
10))
goto clean; goto clean;
if (!cpp_demangle_push_subst_v(ddata, if (!cpp_demangle_push_subst_v(ddata,
&subst_v)) &subst_v))
@ -1616,8 +1615,7 @@ cpp_demangle_read_encoding(struct cpp_demangle_data *ddata)
case SIMPLE_HASH('T', 'v'): case SIMPLE_HASH('T', 'v'):
/* virtual function virtual override thunk */ /* virtual function virtual override thunk */
if (!DEM_PUSH_STR(ddata, if (!DEM_PUSH_STR(ddata, "virtual function virtual override "))
"virtual function virtual override "))
return (0); return (0);
ddata->cur += 2; ddata->cur += 2;
if (*ddata->cur == '\0') if (*ddata->cur == '\0')

View File

@ -1,6 +1,6 @@
# $Id: Makefile 3349 2016-01-18 21:09:16Z jkoshy $ # $Id: Makefile 3594 2018-04-11 18:26:50Z jkoshy $
TOP= ${.CURDIR}/.. TOP= ..
LIB= pe LIB= pe

View File

@ -1,21 +1,50 @@
# #
# $Id: elftoolchain.components.mk 3316 2016-01-11 22:48:22Z jkoshy $ # $Id: elftoolchain.components.mk 3607 2018-04-13 19:41:17Z jkoshy $
# #
# Knobs to turn parts of the source tree on or off. # Knobs to turn parts of the source tree on or off.
#
# Build the automation tools. # These knobs should be set to one of "yes" or "no".
WITH_BUILD_TOOLS= no
# Build additional tutorial documentation. (Manual page generation is # Build additional tutorial documentation. (Manual page generation is
# controlled by the 'MKDOC' knob). # controlled by the 'MKDOC' knob).
WITH_DOCUMENTATION=yes WITH_ADDITIONAL_DOCUMENTATION?=yes
# Build the automation tools.
WITH_BUILD_TOOLS?= no
# Build the instruction set analyser. # Build the instruction set analyser.
WITH_ISA= no WITH_ISA?= no
# Build PE support. # Build PE support.
WITH_PE= yes WITH_PE?= yes
# Build test suites. # Build test suites.
WITH_TESTS= yes .if defined(MAKEOBJDIR) || defined(MAKEOBJDIRPREFIX)
.if defined(WITH_TESTS) && ${WITH_TESTS} == "yes"
.error Only in-tree builds are supported for tests currently [#271].
.endif
WITH_TESTS?= no
.else
WITH_TESTS?= yes
.endif
# Fail the build with an informative message if the value of any
# build knob is not a "yes" or "no".
.if ${WITH_ADDITIONAL_DOCUMENTATION} != "yes" && \
${WITH_ADDITIONAL_DOCUMENTATION} != "no"
.error Unrecognized value for WITH_ADDITIONAL_DOCUMENTATION:\
"${WITH_ADDITIONAL_DOCUMENTATION}".
.endif
.if ${WITH_BUILD_TOOLS} != "yes" && ${WITH_BUILD_TOOLS} != "no"
.error Unrecognized value for WITH_BUILD_TOOLS: "${WITH_BUILD_TOOLS}".
.endif
.if ${WITH_ISA} != "yes" && ${WITH_ISA} != "no"
.error Unrecognized value for WITH_ISA: "${WITH_ISA}".
.endif
.if ${WITH_PE} != "yes" && ${WITH_PE} != "no"
.error Unrecognized value for WITH_PE: "${WITH_PE}".
.endif
.if ${WITH_TESTS} != "yes" && ${WITH_TESTS} != "no"
.error Unrecognized value for WITH_TESTS: "${WITH_TESTS}".
.endif

View File

@ -1,7 +1,7 @@
# #
# Rules for handling include files. # Rules for handling include files.
# #
# $Id: elftoolchain.inc.mk 3245 2015-08-31 19:54:13Z emaste $ # $Id: elftoolchain.inc.mk 3602 2018-04-12 20:52:01Z jkoshy $
.if !defined(TOP) .if !defined(TOP)
.error Make variable \"TOP\" has not been defined. .error Make variable \"TOP\" has not been defined.
@ -9,7 +9,7 @@
.include "${TOP}/mk/elftoolchain.os.mk" .include "${TOP}/mk/elftoolchain.os.mk"
.include <bsd.own.mk> .include <bsd.obj.mk>
.if ${OS_HOST} == "Darwin" || ${OS_HOST} == "DragonFly" || \ .if ${OS_HOST} == "Darwin" || ${OS_HOST} == "DragonFly" || \
${OS_HOST} == "FreeBSD" || ${OS_HOST} == "OpenBSD" ${OS_HOST} == "FreeBSD" || ${OS_HOST} == "OpenBSD"
@ -20,7 +20,7 @@ NOBINMODE?= 444 # Missing in OpenBSD's rule set.
.PHONY: incinstall .PHONY: incinstall
includes: ${INCS} incinstall includes: ${INCS} incinstall
.for inc in ${INCS} .for inc in ${INCS}
install incinstall:: ${DESTDIR}${INCSDIR}/${inc} install incinstall: ${DESTDIR}${INCSDIR}/${inc}
.PRECIOUS: ${DESTDIR}${INCSDIR}/${inc} .PRECIOUS: ${DESTDIR}${INCSDIR}/${inc}
${DESTDIR}${INCSDIR}/${inc}: ${inc} ${DESTDIR}${INCSDIR}/${inc}: ${inc}
cmp -s $> $@ > /dev/null 2>&1 || \ cmp -s $> $@ > /dev/null 2>&1 || \

View File

@ -1,5 +1,5 @@
# #
# $Id: elftoolchain.lib.mk 3026 2014-04-18 16:20:30Z jkoshy $ # $Id: elftoolchain.lib.mk 3594 2018-04-11 18:26:50Z jkoshy $
# #
.if !defined(TOP) .if !defined(TOP)
@ -19,13 +19,20 @@ CLEANFILES+= .depend
# Adjust CFLAGS # Adjust CFLAGS
CFLAGS+= -I. # OBJDIR CFLAGS+= -I. # OBJDIR
CFLAGS+= -I${.CURDIR} # Sources CFLAGS+= -I${.CURDIR} # Sources
CFLAGS+= -I${TOP}/common # common code CFLAGS+= -I${.CURDIR}/${TOP}/common # Common code
.if defined(MAKEOBJDIRPREFIX)
CFLAGS+= -I${.OBJDIR}/${TOP}/common # Generated common code.
.else
.if ${.CURDIR} != ${.OBJDIR}
CFLAGS+= -I${.CURDIR}/${TOP}/common/${.OBJDIR:S/${.CURDIR}//}
.endif
.endif
.if defined(LDADD) .if defined(LDADD)
_LDADD_LIBELF=${LDADD:M-lelf} _LDADD_LIBELF=${LDADD:M-lelf}
.if !empty(_LDADD_LIBELF) .if !empty(_LDADD_LIBELF)
CFLAGS+= -I${TOP}/libelf CFLAGS+= -I${.CURDIR}/${TOP}/libelf
LDFLAGS+= -L${TOP}/libelf LDFLAGS+= -L${.OBJDIR}/${TOP}/libelf
.endif .endif
.endif .endif

View File

@ -1,7 +1,7 @@
# #
# Rules for building programs. # Rules for building programs.
# #
# $Id: elftoolchain.prog.mk 3352 2016-01-18 21:50:10Z jkoshy $ # $Id: elftoolchain.prog.mk 3607 2018-04-13 19:41:17Z jkoshy $
.if !defined(TOP) .if !defined(TOP)
.error Make variable \"TOP\" has not been defined. .error Make variable \"TOP\" has not been defined.
@ -15,32 +15,58 @@ LIBELFTC?= ${TOP}/libelftc
BINDIR?= /usr/bin BINDIR?= /usr/bin
CFLAGS+= -I. -I${.CURDIR} -I${TOP}/common CFLAGS+= -I. -I${.CURDIR} -I${.CURDIR}/${TOP}/common
CLEANFILES+= .depend CLEANFILES+= .depend
# TODO[#271]: Reduce the code duplication below.
.if defined(LDADD) .if defined(LDADD)
_LDADD_LIBDWARF=${LDADD:M-ldwarf} _LDADD_LIBDWARF=${LDADD:M-ldwarf}
.if !empty(_LDADD_LIBDWARF) .if !empty(_LDADD_LIBDWARF)
CFLAGS+= -I${TOP}/libdwarf CFLAGS+= -I${.CURDIR}/${TOP}/libdwarf
LDFLAGS+= -L${TOP}/libdwarf .if exists(${.OBJDIR}/${TOP}/libdwarf)
LDFLAGS+= -L${.OBJDIR}/${TOP}/libdwarf
.elif exists(${TOP}/libdwarf/${.OBJDIR:S,${.CURDIR}/,,})
LDFLAGS+= -L${.CURDIR}/${TOP}/libdwarf/${.OBJDIR:S,${.CURDIR}/,,}
.else
.error Cannot determine LDFLAGS for -ldwarf.
.endif
.endif .endif
_LDADD_LIBELF=${LDADD:M-lelf} _LDADD_LIBELF=${LDADD:M-lelf}
.if !empty(_LDADD_LIBELF) .if !empty(_LDADD_LIBELF)
CFLAGS+= -I${TOP}/libelf CFLAGS+= -I${.CURDIR}/${TOP}/libelf
LDFLAGS+= -L${TOP}/libelf .if exists(${.OBJDIR}/${TOP}/libelf)
LDFLAGS+= -L${.OBJDIR}/${TOP}/libelf
.elif exists(${TOP}/libelf/${.OBJDIR:S,${.CURDIR}/,,})
LDFLAGS+= -L${.CURDIR}/${TOP}/libelf/${.OBJDIR:S,${.CURDIR}/,,}
.else
.error Cannot determine LDFLAGS for -lelf.
.endif
.endif .endif
_LDADD_LIBELFTC=${LDADD:M-lelftc} _LDADD_LIBELFTC=${LDADD:M-lelftc}
.if !empty(_LDADD_LIBELFTC) .if !empty(_LDADD_LIBELFTC)
CFLAGS+= -I${TOP}/libelftc CFLAGS+= -I${.CURDIR}/${TOP}/libelftc
LDFLAGS+= -L${TOP}/libelftc .if exists(${.OBJDIR}/${TOP}/libelftc)
LDFLAGS+= -L${.OBJDIR}/${TOP}/libelftc
.elif exists(${TOP}/libelftc/${.OBJDIR:S,${.CURDIR}/,,})
LDFLAGS+= -L${.CURDIR}/${TOP}/libelftc/${.OBJDIR:S,${.CURDIR}/,,}
.else
.error Cannot determine LDFLAGS for -lelftc.
.endif
.endif .endif
_LDADD_LIBPE=${LDADD:M-lpe} _LDADD_LIBPE=${LDADD:M-lpe}
.if !empty(_LDADD_LIBPE) .if !empty(_LDADD_LIBPE)
CFLAGS+= -I${TOP}/libpe CFLAGS+= -I${.CURDIR}/${TOP}/libpe
LDFLAGS+= -L${TOP}/libpe .if exists(${.OBJDIR}/${TOP}/libpe)
LDFLAGS+= -L${.OBJDIR}/${TOP}/libpe
.elif exists(${TOP}/libpe/${.OBJDIR:S,${.CURDIR}/,,})
LDFLAGS+= -L${.CURDIR}/${TOP}/libpe/${.OBJDIR:S,${.CURDIR}/,,}
.else
.error Cannot determine LDFLAGS for -lpe.
.endif
.endif .endif
.endif .endif

View File

@ -1,14 +1,12 @@
# #
# Rules for recursing into directories # Rules for recursing into directories
# $Id: elftoolchain.subdir.mk 3023 2014-04-17 18:06:06Z jkoshy $ # $Id: elftoolchain.subdir.mk 3608 2018-04-14 21:23:04Z jkoshy $
# Pass down 'test' as a valid target. # Pass down 'test' as a valid target.
.include "$(TOP)/mk/elftoolchain.os.mk" .include "$(TOP)/mk/elftoolchain.os.mk"
.if ${OS_HOST} == DragonFly .if ${OS_HOST} == FreeBSD
clobber test:: _SUBDIR
.elif ${OS_HOST} == FreeBSD
SUBDIR_TARGETS+= clobber test SUBDIR_TARGETS+= clobber test
.elif ${OS_HOST} == OpenBSD .elif ${OS_HOST} == OpenBSD
clobber test:: _SUBDIRUSE clobber test:: _SUBDIRUSE

View File

@ -1,7 +1,7 @@
# #
# Rules to build LateX documentation. # Rules to build LateX documentation.
# #
# $Id: elftoolchain.tex.mk 2552 2012-08-28 03:39:09Z jkoshy $ # $Id: elftoolchain.tex.mk 3595 2018-04-11 19:43:46Z jkoshy $
# #
.include "${TOP}/mk/elftoolchain.os.mk" .include "${TOP}/mk/elftoolchain.os.mk"
@ -87,7 +87,7 @@ install: all
.else .else
all clean clobber depend install obj: .PHONY .SILENT all clean cleandepend clobber depend install obj: .PHONY .SILENT
echo -n WARNING: make \"${.TARGET}\" in \"${.CURDIR:T}\" skipped: echo -n WARNING: make \"${.TARGET}\" in \"${.CURDIR:T}\" skipped:
.if defined(MKTEX) && ${MKTEX} == "yes" .if defined(MKTEX) && ${MKTEX} == "yes"
echo " missing tools." echo " missing tools."

View File

@ -22,9 +22,9 @@
.\" (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF .\" (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
.\" THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. .\" THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
.\" .\"
.\" $Id: nm.1 3195 2015-05-12 17:22:19Z emaste $ .\" $Id: nm.1 3573 2017-09-14 02:06:31Z emaste $
.\" .\"
.Dd February 15, 2015 .Dd September 13, 2017
.Os .Os
.Dt NM 1 .Dt NM 1
.Sh NAME .Sh NAME
@ -304,6 +304,8 @@ A local
(uninitialized data) symbol. (uninitialized data) symbol.
.It d .It d
A local data symbol. A local data symbol.
.It r
A local read-only data symbol.
.It t .It t
A local text symbol. A local text symbol.
.It v .It v

View File

@ -47,7 +47,7 @@
#include "_elftc.h" #include "_elftc.h"
ELFTC_VCSID("$Id: readelf.c 3519 2017-04-09 23:15:58Z kaiwang27 $"); ELFTC_VCSID("$Id: readelf.c 3580 2017-09-15 23:29:59Z emaste $");
/* /*
* readelf(1) options. * readelf(1) options.
@ -287,6 +287,7 @@ static void dump_elf(struct readelf *re);
static void dump_dyn_val(struct readelf *re, GElf_Dyn *dyn, uint32_t stab); static void dump_dyn_val(struct readelf *re, GElf_Dyn *dyn, uint32_t stab);
static void dump_dynamic(struct readelf *re); static void dump_dynamic(struct readelf *re);
static void dump_liblist(struct readelf *re); static void dump_liblist(struct readelf *re);
static void dump_mips_abiflags(struct readelf *re, struct section *s);
static void dump_mips_attributes(struct readelf *re, uint8_t *p, uint8_t *pe); static void dump_mips_attributes(struct readelf *re, uint8_t *p, uint8_t *pe);
static void dump_mips_odk_reginfo(struct readelf *re, uint8_t *p, size_t sz); static void dump_mips_odk_reginfo(struct readelf *re, uint8_t *p, size_t sz);
static void dump_mips_options(struct readelf *re, struct section *s); static void dump_mips_options(struct readelf *re, struct section *s);
@ -316,6 +317,7 @@ static const char *dwarf_regname(struct readelf *re, unsigned int num);
static struct dumpop *find_dumpop(struct readelf *re, size_t si, static struct dumpop *find_dumpop(struct readelf *re, size_t si,
const char *sn, int op, int t); const char *sn, int op, int t);
static int get_ent_count(struct section *s, int *ent_count); static int get_ent_count(struct section *s, int *ent_count);
static int get_mips_register_size(uint8_t flag);
static char *get_regoff_str(struct readelf *re, Dwarf_Half reg, static char *get_regoff_str(struct readelf *re, Dwarf_Half reg,
Dwarf_Addr off); Dwarf_Addr off);
static const char *get_string(struct readelf *re, int strtab, size_t off); static const char *get_string(struct readelf *re, int strtab, size_t off);
@ -775,6 +777,81 @@ dt_type(unsigned int mach, unsigned int dtype)
{ {
static char s_dtype[32]; static char s_dtype[32];
switch (dtype) {
case DT_NULL: return "NULL";
case DT_NEEDED: return "NEEDED";
case DT_PLTRELSZ: return "PLTRELSZ";
case DT_PLTGOT: return "PLTGOT";
case DT_HASH: return "HASH";
case DT_STRTAB: return "STRTAB";
case DT_SYMTAB: return "SYMTAB";
case DT_RELA: return "RELA";
case DT_RELASZ: return "RELASZ";
case DT_RELAENT: return "RELAENT";
case DT_STRSZ: return "STRSZ";
case DT_SYMENT: return "SYMENT";
case DT_INIT: return "INIT";
case DT_FINI: return "FINI";
case DT_SONAME: return "SONAME";
case DT_RPATH: return "RPATH";
case DT_SYMBOLIC: return "SYMBOLIC";
case DT_REL: return "REL";
case DT_RELSZ: return "RELSZ";
case DT_RELENT: return "RELENT";
case DT_PLTREL: return "PLTREL";
case DT_DEBUG: return "DEBUG";
case DT_TEXTREL: return "TEXTREL";
case DT_JMPREL: return "JMPREL";
case DT_BIND_NOW: return "BIND_NOW";
case DT_INIT_ARRAY: return "INIT_ARRAY";
case DT_FINI_ARRAY: return "FINI_ARRAY";
case DT_INIT_ARRAYSZ: return "INIT_ARRAYSZ";
case DT_FINI_ARRAYSZ: return "FINI_ARRAYSZ";
case DT_RUNPATH: return "RUNPATH";
case DT_FLAGS: return "FLAGS";
case DT_PREINIT_ARRAY: return "PREINIT_ARRAY";
case DT_PREINIT_ARRAYSZ: return "PREINIT_ARRAYSZ";
case DT_MAXPOSTAGS: return "MAXPOSTAGS";
case DT_SUNW_AUXILIARY: return "SUNW_AUXILIARY";
case DT_SUNW_RTLDINF: return "SUNW_RTLDINF";
case DT_SUNW_FILTER: return "SUNW_FILTER";
case DT_SUNW_CAP: return "SUNW_CAP";
case DT_SUNW_ASLR: return "SUNW_ASLR";
case DT_CHECKSUM: return "CHECKSUM";
case DT_PLTPADSZ: return "PLTPADSZ";
case DT_MOVEENT: return "MOVEENT";
case DT_MOVESZ: return "MOVESZ";
case DT_FEATURE: return "FEATURE";
case DT_POSFLAG_1: return "POSFLAG_1";
case DT_SYMINSZ: return "SYMINSZ";
case DT_SYMINENT: return "SYMINENT";
case DT_GNU_HASH: return "GNU_HASH";
case DT_TLSDESC_PLT: return "DT_TLSDESC_PLT";
case DT_TLSDESC_GOT: return "DT_TLSDESC_GOT";
case DT_GNU_CONFLICT: return "GNU_CONFLICT";
case DT_GNU_LIBLIST: return "GNU_LIBLIST";
case DT_CONFIG: return "CONFIG";
case DT_DEPAUDIT: return "DEPAUDIT";
case DT_AUDIT: return "AUDIT";
case DT_PLTPAD: return "PLTPAD";
case DT_MOVETAB: return "MOVETAB";
case DT_SYMINFO: return "SYMINFO";
case DT_VERSYM: return "VERSYM";
case DT_RELACOUNT: return "RELACOUNT";
case DT_RELCOUNT: return "RELCOUNT";
case DT_FLAGS_1: return "FLAGS_1";
case DT_VERDEF: return "VERDEF";
case DT_VERDEFNUM: return "VERDEFNUM";
case DT_VERNEED: return "VERNEED";
case DT_VERNEEDNUM: return "VERNEEDNUM";
case DT_AUXILIARY: return "AUXILIARY";
case DT_USED: return "USED";
case DT_FILTER: return "FILTER";
case DT_GNU_PRELINKED: return "GNU_PRELINKED";
case DT_GNU_CONFLICTSZ: return "GNU_CONFLICTSZ";
case DT_GNU_LIBLISTSZ: return "GNU_LIBLISTSZ";
}
if (dtype >= DT_LOPROC && dtype <= DT_HIPROC) { if (dtype >= DT_LOPROC && dtype <= DT_HIPROC) {
switch (mach) { switch (mach) {
case EM_ARM: case EM_ARM:
@ -895,87 +972,10 @@ dt_type(unsigned int mach, unsigned int dtype)
default: default:
break; break;
} }
snprintf(s_dtype, sizeof(s_dtype), "<unknown: %#x>", dtype);
return (s_dtype);
} }
switch (dtype) { snprintf(s_dtype, sizeof(s_dtype), "<unknown: %#x>", dtype);
case DT_NULL: return "NULL"; return (s_dtype);
case DT_NEEDED: return "NEEDED";
case DT_PLTRELSZ: return "PLTRELSZ";
case DT_PLTGOT: return "PLTGOT";
case DT_HASH: return "HASH";
case DT_STRTAB: return "STRTAB";
case DT_SYMTAB: return "SYMTAB";
case DT_RELA: return "RELA";
case DT_RELASZ: return "RELASZ";
case DT_RELAENT: return "RELAENT";
case DT_STRSZ: return "STRSZ";
case DT_SYMENT: return "SYMENT";
case DT_INIT: return "INIT";
case DT_FINI: return "FINI";
case DT_SONAME: return "SONAME";
case DT_RPATH: return "RPATH";
case DT_SYMBOLIC: return "SYMBOLIC";
case DT_REL: return "REL";
case DT_RELSZ: return "RELSZ";
case DT_RELENT: return "RELENT";
case DT_PLTREL: return "PLTREL";
case DT_DEBUG: return "DEBUG";
case DT_TEXTREL: return "TEXTREL";
case DT_JMPREL: return "JMPREL";
case DT_BIND_NOW: return "BIND_NOW";
case DT_INIT_ARRAY: return "INIT_ARRAY";
case DT_FINI_ARRAY: return "FINI_ARRAY";
case DT_INIT_ARRAYSZ: return "INIT_ARRAYSZ";
case DT_FINI_ARRAYSZ: return "FINI_ARRAYSZ";
case DT_RUNPATH: return "RUNPATH";
case DT_FLAGS: return "FLAGS";
case DT_PREINIT_ARRAY: return "PREINIT_ARRAY";
case DT_PREINIT_ARRAYSZ: return "PREINIT_ARRAYSZ";
case DT_MAXPOSTAGS: return "MAXPOSTAGS";
case DT_SUNW_AUXILIARY: return "SUNW_AUXILIARY";
case DT_SUNW_RTLDINF: return "SUNW_RTLDINF";
case DT_SUNW_FILTER: return "SUNW_FILTER";
case DT_SUNW_CAP: return "SUNW_CAP";
case DT_SUNW_ASLR: return "SUNW_ASLR";
case DT_CHECKSUM: return "CHECKSUM";
case DT_PLTPADSZ: return "PLTPADSZ";
case DT_MOVEENT: return "MOVEENT";
case DT_MOVESZ: return "MOVESZ";
case DT_FEATURE: return "FEATURE";
case DT_POSFLAG_1: return "POSFLAG_1";
case DT_SYMINSZ: return "SYMINSZ";
case DT_SYMINENT: return "SYMINENT";
case DT_GNU_HASH: return "GNU_HASH";
case DT_TLSDESC_PLT: return "DT_TLSDESC_PLT";
case DT_TLSDESC_GOT: return "DT_TLSDESC_GOT";
case DT_GNU_CONFLICT: return "GNU_CONFLICT";
case DT_GNU_LIBLIST: return "GNU_LIBLIST";
case DT_CONFIG: return "CONFIG";
case DT_DEPAUDIT: return "DEPAUDIT";
case DT_AUDIT: return "AUDIT";
case DT_PLTPAD: return "PLTPAD";
case DT_MOVETAB: return "MOVETAB";
case DT_SYMINFO: return "SYMINFO";
case DT_VERSYM: return "VERSYM";
case DT_RELACOUNT: return "RELACOUNT";
case DT_RELCOUNT: return "RELCOUNT";
case DT_FLAGS_1: return "FLAGS_1";
case DT_VERDEF: return "VERDEF";
case DT_VERDEFNUM: return "VERDEFNUM";
case DT_VERNEED: return "VERNEED";
case DT_VERNEEDNUM: return "VERNEEDNUM";
case DT_AUXILIARY: return "AUXILIARY";
case DT_USED: return "USED";
case DT_FILTER: return "FILTER";
case DT_GNU_PRELINKED: return "GNU_PRELINKED";
case DT_GNU_CONFLICTSZ: return "GNU_CONFLICTSZ";
case DT_GNU_LIBLISTSZ: return "GNU_LIBLISTSZ";
default:
snprintf(s_dtype, sizeof(s_dtype), "<unknown: %#x>", dtype);
return (s_dtype);
}
} }
static const char * static const char *
@ -1136,7 +1136,9 @@ note_type_freebsd_core(unsigned int nt)
case 14: return "NT_PROCSTAT_OSREL"; case 14: return "NT_PROCSTAT_OSREL";
case 15: return "NT_PROCSTAT_PSSTRINGS"; case 15: return "NT_PROCSTAT_PSSTRINGS";
case 16: return "NT_PROCSTAT_AUXV"; case 16: return "NT_PROCSTAT_AUXV";
case 17: return "NT_PTLWPINFO";
case 0x202: return "NT_X86_XSTATE (x86 XSAVE extended state)"; case 0x202: return "NT_X86_XSTATE (x86 XSAVE extended state)";
case 0x400: return "NT_ARM_VFP (arm VFP registers)";
default: return (note_type_unknown(nt)); default: return (note_type_unknown(nt));
} }
} }
@ -2631,10 +2633,8 @@ dyn_str(struct readelf *re, uint32_t stab, uint64_t d_val)
} }
static void static void
dump_arch_dyn_val(struct readelf *re, GElf_Dyn *dyn, uint32_t stab) dump_arch_dyn_val(struct readelf *re, GElf_Dyn *dyn)
{ {
const char *name;
switch (re->ehdr.e_machine) { switch (re->ehdr.e_machine) {
case EM_MIPS: case EM_MIPS:
case EM_MIPS_RS3_LE: case EM_MIPS_RS3_LE:
@ -2687,14 +2687,12 @@ dump_arch_dyn_val(struct readelf *re, GElf_Dyn *dyn, uint32_t stab)
break; break;
case DT_MIPS_IVERSION: case DT_MIPS_IVERSION:
case DT_MIPS_PERF_SUFFIX: case DT_MIPS_PERF_SUFFIX:
case DT_AUXILIARY:
case DT_FILTER:
name = dyn_str(re, stab, dyn->d_un.d_val);
printf(" %s\n", name);
break;
case DT_MIPS_TIME_STAMP: case DT_MIPS_TIME_STAMP:
printf(" %s\n", timestamp(dyn->d_un.d_val)); printf(" %s\n", timestamp(dyn->d_un.d_val));
break; break;
default:
printf("\n");
break;
} }
break; break;
default: default:
@ -2708,14 +2706,16 @@ dump_dyn_val(struct readelf *re, GElf_Dyn *dyn, uint32_t stab)
{ {
const char *name; const char *name;
if (dyn->d_tag >= DT_LOPROC && dyn->d_tag <= DT_HIPROC) { if (dyn->d_tag >= DT_LOPROC && dyn->d_tag <= DT_HIPROC &&
dump_arch_dyn_val(re, dyn, stab); dyn->d_tag != DT_AUXILIARY && dyn->d_tag != DT_FILTER) {
dump_arch_dyn_val(re, dyn);
return; return;
} }
/* These entry values are index into the string table. */ /* These entry values are index into the string table. */
name = NULL; name = NULL;
if (dyn->d_tag == DT_NEEDED || dyn->d_tag == DT_SONAME || if (dyn->d_tag == DT_AUXILIARY || dyn->d_tag == DT_FILTER ||
dyn->d_tag == DT_NEEDED || dyn->d_tag == DT_SONAME ||
dyn->d_tag == DT_RPATH || dyn->d_tag == DT_RUNPATH) dyn->d_tag == DT_RPATH || dyn->d_tag == DT_RUNPATH)
name = dyn_str(re, stab, dyn->d_un.d_val); name = dyn_str(re, stab, dyn->d_un.d_val);
@ -2760,6 +2760,12 @@ dump_dyn_val(struct readelf *re, GElf_Dyn *dyn, uint32_t stab)
case DT_VERNEEDNUM: case DT_VERNEEDNUM:
printf(" %ju\n", (uintmax_t) dyn->d_un.d_val); printf(" %ju\n", (uintmax_t) dyn->d_un.d_val);
break; break;
case DT_AUXILIARY:
printf(" Auxiliary library: [%s]\n", name);
break;
case DT_FILTER:
printf(" Filter library: [%s]\n", name);
break;
case DT_NEEDED: case DT_NEEDED:
printf(" Shared library: [%s]\n", name); printf(" Shared library: [%s]\n", name);
break; break;
@ -2833,6 +2839,8 @@ dump_rel(struct readelf *re, struct section *s, Elf_Data *d)
type2 = (type >> 8) & 0xFF; type2 = (type >> 8) & 0xFF;
type3 = (type >> 16) & 0xFF; type3 = (type >> 16) & 0xFF;
type = type & 0xFF; type = type & 0xFF;
} else {
type2 = type3 = 0;
} }
if (re->options & RE_WW) if (re->options & RE_WW)
printf("%16.16jx %16.16jx %-24.24s" printf("%16.16jx %16.16jx %-24.24s"
@ -2916,6 +2924,8 @@ dump_rela(struct readelf *re, struct section *s, Elf_Data *d)
type2 = (type >> 8) & 0xFF; type2 = (type >> 8) & 0xFF;
type3 = (type >> 16) & 0xFF; type3 = (type >> 16) & 0xFF;
type = type & 0xFF; type = type & 0xFF;
} else {
type2 = type3 = 0;
} }
if (re->options & RE_WW) if (re->options & RE_WW)
printf("%16.16jx %16.16jx %-24.24s" printf("%16.16jx %16.16jx %-24.24s"
@ -4099,6 +4109,10 @@ dump_mips_specific_info(struct readelf *re)
} }
} }
if (s->name != NULL && (!strcmp(s->name, ".MIPS.abiflags") ||
(s->type == SHT_MIPS_ABIFLAGS)))
dump_mips_abiflags(re, s);
/* /*
* Dump .reginfo if present (although it will be ignored by an OS if a * Dump .reginfo if present (although it will be ignored by an OS if a
* .MIPS.options section is present, according to SGI mips64 spec). * .MIPS.options section is present, according to SGI mips64 spec).
@ -4111,6 +4125,82 @@ dump_mips_specific_info(struct readelf *re)
} }
} }
static void
dump_mips_abiflags(struct readelf *re, struct section *s)
{
Elf_Data *d;
uint8_t *p;
int elferr;
uint32_t isa_ext, ases, flags1, flags2;
uint16_t version;
uint8_t isa_level, isa_rev, gpr_size, cpr1_size, cpr2_size, fp_abi;
if ((d = elf_rawdata(s->scn, NULL)) == NULL) {
elferr = elf_errno();
if (elferr != 0)
warnx("elf_rawdata failed: %s",
elf_errmsg(elferr));
return;
}
if (d->d_size != 24) {
warnx("invalid MIPS abiflags section size");
return;
}
p = d->d_buf;
version = re->dw_decode(&p, 2);
printf("MIPS ABI Flags Version: %u", version);
if (version != 0) {
printf(" (unknown)\n\n");
return;
}
printf("\n\n");
isa_level = re->dw_decode(&p, 1);
isa_rev = re->dw_decode(&p, 1);
gpr_size = re->dw_decode(&p, 1);
cpr1_size = re->dw_decode(&p, 1);
cpr2_size = re->dw_decode(&p, 1);
fp_abi = re->dw_decode(&p, 1);
isa_ext = re->dw_decode(&p, 4);
ases = re->dw_decode(&p, 4);
flags1 = re->dw_decode(&p, 4);
flags2 = re->dw_decode(&p, 4);
printf("ISA: ");
if (isa_rev <= 1)
printf("MIPS%u\n", isa_level);
else
printf("MIPS%ur%u\n", isa_level, isa_rev);
printf("GPR size: %d\n", get_mips_register_size(gpr_size));
printf("CPR1 size: %d\n", get_mips_register_size(cpr1_size));
printf("CPR2 size: %d\n", get_mips_register_size(cpr2_size));
printf("FP ABI: ");
switch (fp_abi) {
case 3:
printf("Soft float");
break;
default:
printf("%u", fp_abi);
break;
}
printf("\nISA Extension: %u\n", isa_ext);
printf("ASEs: %u\n", ases);
printf("FLAGS 1: %08x\n", flags1);
printf("FLAGS 2: %08x\n", flags2);
}
static int
get_mips_register_size(uint8_t flag)
{
switch (flag) {
case 0: return 0;
case 1: return 32;
case 2: return 64;
case 3: return 128;
default: return -1;
}
}
static void static void
dump_mips_reginfo(struct readelf *re, struct section *s) dump_mips_reginfo(struct readelf *re, struct section *s)
{ {

View File

@ -46,7 +46,7 @@
#include "_elftc.h" #include "_elftc.h"
ELFTC_VCSID("$Id: strings.c 3498 2016-10-26 19:25:13Z emaste $"); ELFTC_VCSID("$Id: strings.c 3571 2017-09-14 02:04:50Z emaste $");
enum radix_style { enum radix_style {
RADIX_DECIMAL, RADIX_DECIMAL,
@ -189,7 +189,7 @@ main(int argc, char **argv)
if (!min_len) if (!min_len)
min_len = 4; min_len = 4;
if (!*argv) if (!*argv)
rc = handle_file("{standard input}"); rc = find_strings("{standard input}", 0, 0);
else while (*argv) { else while (*argv) {
if (handle_file(*argv) != 0) if (handle_file(*argv) != 0)
rc = 1; rc = 1;
@ -205,13 +205,9 @@ handle_file(const char *name)
if (name == NULL) if (name == NULL)
return (1); return (1);
if (strcmp("{standard input}", name) != 0) { if (freopen(name, "rb", stdin) == NULL) {
if (freopen(name, "rb", stdin) == NULL) { warnx("'%s': %s", name, strerror(errno));
warnx("'%s': %s", name, strerror(errno)); return (1);
return (1);
}
} else {
return (find_strings(name, (off_t)0, (off_t)0));
} }
fd = fileno(stdin); fd = fileno(stdin);

View File

@ -1,4 +1,4 @@
# $Id: Makefile.ardiff 3120 2014-12-21 05:45:51Z kaiwang27 $ # $Id: Makefile.ardiff 3609 2018-04-14 21:34:45Z jkoshy $
TOP= ../../.. TOP= ../../..
@ -12,3 +12,7 @@ DPADD= ${LIBARCHIVE}
LDADD= -larchive LDADD= -larchive
.include "${TOP}/mk/elftoolchain.prog.mk" .include "${TOP}/mk/elftoolchain.prog.mk"
.if ${OS_HOST} == "DragonFly"
LDADD+= -lbz2
.endif

View File

@ -1,4 +1,4 @@
# $Id: Makefile.ardiff 3121 2014-12-21 05:46:01Z kaiwang27 $ # $Id: Makefile.ardiff 3609 2018-04-14 21:34:45Z jkoshy $
TOP= ../../.. TOP= ../../..
@ -12,3 +12,7 @@ DPADD= ${LIBARCHIVE}
LDADD= -larchive LDADD= -larchive
.include "${TOP}/mk/elftoolchain.prog.mk" .include "${TOP}/mk/elftoolchain.prog.mk"
.if ${OS_HOST} == "DragonFly"
LDADD+= -lbz2
.endif

View File

@ -23,7 +23,7 @@
* OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
* SUCH DAMAGE. * SUCH DAMAGE.
* *
* $Id: driver.c 2121 2011-11-09 08:43:56Z jkoshy $ * $Id: driver.c 3585 2017-11-06 08:04:16Z jkoshy $
*/ */
#include <sys/types.h> #include <sys/types.h>
@ -31,6 +31,7 @@
#include <dirent.h> #include <dirent.h>
#include <fcntl.h> #include <fcntl.h>
#include <inttypes.h> #include <inttypes.h>
#include <limits.h>
#include <stdio.h> #include <stdio.h>
#include <stdlib.h> #include <stdlib.h>
#include <string.h> #include <string.h>
@ -441,7 +442,7 @@ _xml_data_cb(void *data, const char *s, int len)
} }
} }
#define _CMD_SIZE 256 #define _CMD_SIZE (2*PATH_MAX + 32) /* Two paths and a command */
static void static void
driver_parse_ic_desc(const char *fname) driver_parse_ic_desc(const char *fname)

View File

@ -1,6 +1,6 @@
#!/usr/bin/env python #!/usr/bin/env python2.7
# #
# $Id: elf-hash 2054 2011-10-26 12:12:06Z jkoshy $ # $Id: elf-hash 3614 2018-04-21 19:48:04Z jkoshy $
import sys, os import sys, os

View File

@ -1,4 +1,4 @@
#!/usr/bin/env python #!/usr/bin/env python2.7
# #
# This script converts a textual (YAML) description of an ELF file to # This script converts a textual (YAML) description of an ELF file to
# an equivalent 'binary' file. # an equivalent 'binary' file.
@ -74,7 +74,7 @@
# sections, a section index may be manually specified using a # sections, a section index may be manually specified using a
# 'sh_index' pseudo field. # 'sh_index' pseudo field.
# #
# $Id: elfc 1718 2011-08-12 07:30:43Z jkoshy $ # $Id: elfc 3614 2018-04-21 19:48:04Z jkoshy $
version = "%prog 1.0" version = "%prog 1.0"
usage = "usage: %prog [options] [input-file]" usage = "usage: %prog [options] [input-file]"

View File

@ -1,7 +1,7 @@
# #
# Build TET from source. # Build TET from source.
# #
# $Id: Makefile 3024 2014-04-18 16:20:11Z jkoshy $ # $Id: Makefile 3595 2018-04-11 19:43:46Z jkoshy $
# #
TOP= ../.. TOP= ../..
@ -13,7 +13,7 @@ TET_PATCH_MARKER= .tet-patch-done
.MAIN: all .MAIN: all
.PHONY: all clean clobber depend test .PHONY: all clean cleandepend clobber depend test
.if exists(${TET_ROOT}/configure) .if exists(${TET_ROOT}/configure)
@ -61,4 +61,6 @@ all depend test: .SILENT
clean clobber: clean clobber:
rm -f ${TET_BUILD_MARKER} ${TET_PATCH_MARKER} rm -f ${TET_BUILD_MARKER} ${TET_PATCH_MARKER}
cleandepend: # Nothing to do.
.endif .endif

View File

@ -1,82 +1,10 @@
# $Id: Makefile 2563 2012-09-01 14:31:42Z jkoshy $ # $Id: Makefile 3588 2018-02-26 10:03:02Z jkoshy $
# #
# The same 'source' for a literate program is used to build both # Yet Another Build System.
# documentation and the program itself.
#
# Keeping the build rules for program code and documentation in
# separate Makefiles help to keep each rule set simple.
TOP= ../.. TOP= ../..
# The literate program input, in order of presentation in the SUBDIR= controller \
# generated text. executor
NW_SRCS= introduction.nw
NW_SRCS+= userguide.nw
NW_SRCS+= implementation.nw
NW_SRCS+= slave.nw
NW_SRCS+= master.nw
NW_SRCS+= utilities.nw
NW_ROOTS!= noroots ${NW_SRCS} /dev/null | sed -e 's:<<::' -e 's:>>::' .include "${TOP}/mk/elftoolchain.subdir.mk"
# The name of the document's base file.
DOC= build-system
PROGRAMDIRS= master slave
SUBMAKEFILES= documentation manuals program
# Declare make targets with special characteristics.
.MAIN: all
.PHONY: all clean clobber index install test
# Capture actions shared by multiple targets in a macro.
.dosubmake: .USE
.for rules in ${SUBMAKEFILES}
@${MAKE} -f Makefile.${rules} ${.TARGET} NW_SRCS="${NW_SRCS}" \
DOC=${DOC} TOP="${TOP}"
.endfor
# Standard targets.
all: ${PROGRAMDIRS} ${NW_ROOTS} ${DOC}.tex .dosubmake
install: all .dosubmake
clean: .dosubmake
rm -f ${CLEANFILES}
# Create the directories holding the program source code, if needed.
${PROGRAMDIRS}: .SILENT
[ -d ${.TARGET} ] || mkdir ${.TARGET}
# Extract all program 'root chunks' from the literate program inputs.
.for n in ${NW_ROOTS}
$n: ${NW_SRCS}
@tmpfile=`mktemp /tmp/mba.XXXXXXX`; \
trap "rm $${tmpfile}" 0 1 2 3 15; \
notangle -L -R${.TARGET} ${NW_SRCS} > $${tmpfile} || exit $$?; \
cpif ${.TARGET} < $${tmpfile}
CLEANFILES+= $n
.endfor
# Create a single TeX file holding the material to be typeset.
# By passing the complete literate program as input to 'noweave', we
# avoid noweb's limitation on chunk names having file scope.
${DOC}.tex: ${DOC}.pre.nw ${NW_SRCS} ${DOC}.post.nw
cat ${.ALLSRC} | noweave -delay -index | cpif ${.TARGET}
#
# Special targets.
#
# The 'index' target only applies to the documentation.
index:
@${MAKE} -f Makefile.documentation ${.TARGET} NW_SRCS="${NW_SRCS}" \
TOP="${TOP}"
# The 'test' target only applies to the programs.
test:
@${MAKE} -f Makefile.program ${.TARGET} NW_SRCS="${NW_SRCS}" \
TOP="${TOP}"
# Provide a 'clobber' target that goes beyond 'clean'.
clobber: clean
rm -rf ${PROGRAMDIRS}

View File

@ -1,12 +0,0 @@
# -*- mode: makefile -*-
#
# Typeset documentation previously extracted by the invoking Makefile.
#
# $Id: Makefile.documentation 2546 2012-08-17 15:43:44Z jkoshy $
DOC?= build-system
SRCS= ${DOC}.tex
CLEANFILES+= ${SRCS}
.include "${TOP}/mk/elftoolchain.tex.mk"

View File

@ -1,7 +0,0 @@
# -*- mode: makefile; -*-
# $Id: Makefile.manuals 2581 2012-09-14 07:09:42Z jkoshy $
MAN= yabs-slave.1 \
yabs.1
.include <bsd.man.mk>

View File

@ -1,18 +0,0 @@
# -*- mode: makefile -*-
#
# Build the programs previously extracted from the literate program
# input.
#
# $Id: Makefile.program 2546 2012-08-17 15:43:44Z jkoshy $
SUBDIR=
.if exists(master)
SUBDIR+= master
.endif
.if exists(slave)
SUBDIR+= slave
.endif
.include <bsd.subdir.mk>

View File

@ -7,7 +7,4 @@ This directory contains a utility to build and test the Elftoolchain
project's sources on a variety of target operating systems and processor project's sources on a variety of target operating systems and processor
architectures. architectures.
These tools are written as a literate program, in noweb_ syntax. .. $Id: README 3587 2018-02-26 09:40:57Z jkoshy $
.. _noweb: http://www.cs.tufts.edu/~nr/noweb/
.. $Id: README 2459 2012-03-10 17:17:35Z jkoshy $

View File

@ -1,19 +0,0 @@
% $Id: build-system.post.nw 2534 2012-08-04 04:07:20Z jkoshy $
%
% The last chunk of input presented to noweb(1).
\backmatter
\part{Appendices}
% Typeset the index.
\printindex
% Add indices generated by noweb(1).
% TODO: These need to be merged with the LaTeX index.
\chapter*{Index of Identifiers}
\nowebindex
\chapter*{Index of Code Fragments}
\nowebchunks
\end{document}

View File

@ -1,189 +0,0 @@
% Copyright (c) 2006-2010 Joseph Koshy. 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 Joseph Koshy ``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 Joseph Koshy 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.
%
% $Id: build-system.pre.nw 2561 2012-08-31 02:46:33Z jkoshy $
%
% A Build Automation system.
%
\documentclass[a4paper,pdftex]{book}
\usepackage{amsthm}
\usepackage{bookmark}
\usepackage{hyperref}
\usepackage{makeidx}
\usepackage{noweb}
\usepackage{tikz}
\usepackage{varioref}
\usepackage{xspace}
% Typesetting requirements.
\theoremstyle{remark}
\newtheorem{goal}{Design Goal}
% Add meta-data to the PDF file.
\hypersetup{
pdftitle={A Build Automation System},
pdfauthor={Joseph Koshy},
pdfsubject={A build automation system},
pdfkeywords={%
automation,%
build,%
literate program
}
}
% Fix a bug in the PDF TOC.
\bookmarksetup{startatroot}
% Document-specific LaTeX macros.
\makeatletter
\newcommand{\definition}[1]{\textit{#1}\index{#1!definition~of}\xspace}
\newcommand{\elftoolchain}{\href{http://elftoolchain.sourceforge.net/}%
{ElfToolChain}\xspace}
\newcommand{\file}[1]{\texttt{#1}\xspace}
\newcommand{\func}[1]{\texttt{#1()}\xspace}
\newcommand{\foreignphrase}[1]{\textit{#1}\xspace}
\newcommand{\protoarg}[1]{\textit{#1}\xspace}
\newcommand{\protocmd}[1]{\texttt{#1}\xspace}
\newcommand{\protodef}[2]{\protocmd{#1} #2%
\index{#1@\texttt{#1}!protocol~definition}\\}
\newcommand{\reg}{\textregistered\xspace}
\newcommand{\term}[1]{\textit{#1}\xspace}
\newcommand{\tool}[1]{\textbf{#1}\xspace}
\newcommand{\trade}{\texttrademark\xspace}
\newcommand{\var}[1]{\texttt{#1}\xspace}
\makeatother
% Noweb related
\noweboptions{shift,hideunuseddefs,noidentxref}
% Index related.
\makeindex
% The main document.
\begin{document}
\frontmatter %
% The title page.
\title{Yet Another Build System}
\author{Joseph~Koshy}
\maketitle
% Typeset a table of contents.
\tableofcontents
\chapter*{Preface}
This document describes a build automation system being developed at
the \elftoolchain project on
\href{http://sourceforge.net/}{SourceForge.Net}. The original
motivation for this system was to automate the process of building and
testing the \elftoolchain project's source tree on a variety of
operating systems and machine architectures. However, the design of
the system is general enough that it can be used in other contexts
too.
The system has been designed to be easy to use and to frugal in its
use of computing resources. For handling non-native platforms, the
system uses emulators such as \href{http://www.qemu.org}{QEMU},
\href{http://gxemul.sourceforge.net/}{GXemul} and
\href{http://www.virtualbox.org}{VirtualBox}. The system is not tied
to these specific emulators---it can as well manage physical machines,
given the appropriate control specifications.
This document itself is a
\href{http://en.wikipedia.org/wiki/Literate_programming}%
{literate program}---it is both a human-readable description of the
system, as well as the source code of the system itself.
\section*{Target Audience}
This document would be useful to two audiences:
\begin{itemize}
\item Users of the system would find part~\ref{part.intro}, which
contains an overview and a user guide, to be of interest.
\item For the maintainers of the system,
part~\ref{part.implementation} contains the implementation itself.
\end{itemize}
\section*{Document Overview}
\begin{itemize}
\item Chapter~\vref{chap.introduction} describes the rationale and the
requirements for the system.
\item Chapter~\vref{chap.userguide} contains a brief user guide
showing how the system may be used.
\item Chapter~\vref{chap.overview} presents an overview of the
implementation.
\item Chapter~\vref{chap.slave} describes the implementation of the
build slave.
\item Chapter~\vref{chap.master} describes the implementation of the
build master.
\end{itemize}
\section*{Legal Notice}
Copyright \copyright{} 2012 Joseph Koshy. All rights reserved.
\vskip.8\baselineskip
Redistribution and use in source and binary forms, with or without
modification, are permitted provided that the following conditions
are met:
\begin{itemize}
\item Redistributions of source code must retain the above copyright
notice, this list of conditions and the following disclaimer.
\item 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.
\end{itemize}
\subsubsection*{Disclaimer}
THIS DOCUMENTATION IS PROVIDED BY THE AUTHOR AND CON\-TRIBUTORS
``\hskip-0.5ex{}AS~IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES,
INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
MER\-CHANT\-ABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
DISCLAIMED. IN NO EVENT SHALL THE AUTHOR AND CON\-TRIBUTORS BE LIABLE
FOR ANY DIRECT, IN\-DIRECT, INCIDENT\-AL, SPECIAL, EX\-EMPLARY, OR
CON\-SEQUENT\-IAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
PRO\-CURE\-MENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF
LIABILITY, WHE\-THER IN CONTRACT, STRICT LIA\-BILITY, OR TORT
(INCLUDING NEGLIGENCE OR OTHER\-WISE) ARISING IN ANY WAY OUT OF THE
USE OF THIS DOCUMENTATION, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH
DAMAGE.
\vskip.8\baselineskip
Many of the designations used by manufacturers and sellers to
distinguish their products are claimed as trademarks. Where those
designations appear in this document, and the author and contributors
were aware of the trademark claim, the designations have been followed
by the ``\raisebox{-.5ex}{\texttrademark}'' or the ``\textregistered'' symbol.
% The rest of the text proper.
\mainmatter

View File

@ -1,89 +0,0 @@
% $Id: implementation.nw 2555 2012-08-29 13:16:38Z jkoshy $
%
% The implementation itself.
\part{The Implementation}\label{part.implementation}
\chapter{Overview}\label{chap.overview}
\chapter{Protocol}\label{chap.protocol}
From the despatcher to the slave.
\begin{itemize}
\item \protodef{BYE}{\protoarg{nbytes}}
Terminate the session. A human readable message providing the
reason for termination follows.
\item \protodef{CLOSE}{\protoarg{token} \protoarg{childfd}}
Close a file descriptor for a running script.
\item \protodef{CWD}{\protoarg{childfd}}
Set the current directory for new scripts.
\item \protodef{ENV}{\protoarg{nbytes}}
Store a default environment for use with subsequent
\protodef{SCRIPT} commands.
\item \protodef{ERROR}{\protoarg{severity} \protoarg{nbytes}}
Receive an error message sent from the despatcher.
\item \protodef{SCRIPT}{\protoarg{token} \protoarg{uid} \protoarg{gid} \protoarg{nbytes} \protoarg{fd}\ldots}
Execute a script with the given privileges, while monitoring the
specified file descriptors.
\item \protodef{SIGNAL}{\protoarg{token} \protoarg{signal}}
Send a signal to an executing script.
\item \protodef{STATUS}{\protoarg{token}}
Retrieve the status of a previously issued \protocmd{SCRIPT}
command.
\item \protodef{SYSINFO}{}
Return system information.
\item \protodef{WRITE}{\protoarg{token} \protoarg{fd} \protoarg{nbytes}}
Write to an executing script on the specified file descriptor.
\end{itemize}
From the slave to the despatcher:
\begin{itemize}
\item \protodef{CLOSE}{\protoarg{token} \protoarg{fd}}
Report the closing of a file descriptor by a script.
\item \protodef{DATA}{\protoarg{token} \protoarg{fd} \protoarg{nbytes}}
Read data generated by a script.
\item \protodef{ERROR}{\protoarg{args}\ldots}
Report an error.
\item \protodef{EXIT}{\protoarg{token} \protoarg{exittype} \protoarg{code}}
Report a script exit.
\item \protodef{HELLO}{\protoarg{identifier} \protoarg{version}}
Announce presence to the despatcher.
\item \protodef{OK}{\protoarg{args}\ldots}
Acknowledge successful execution of a command.
\item \protodef{SYSINFO}{\protoarg{nbytes}}
Return system information.
\end{itemize}

View File

@ -1,82 +0,0 @@
% $Id: introduction.nw 2532 2012-08-03 06:31:47Z jkoshy $
%
% The introduction to the build system.
\part{The Build System}\label{part.intro}
\chapter{Introduction}\label{chap.introduction}
\section{Design Goals}
\begin{goal}
The system should support build and testing our source tree, on the
target operating systems and machine architectures of our interest.
\end{goal}
This is the primary design goal for the tool, its
\foreignphrase{raison d'\^etre}.
\begin{goal}
The system should support building and testing our source tree on
non-native architectures (relative to the build host).
\end{goal}
Builds on non-native machine architectures and operating systems are
would involve the use of virtual machines and CPU emulators. The
actual build will be done using \tool{make} or equivalent utility.
\begin{goal}
The system should be easy to use.
\end{goal}
Defining a build needs to be intuitive, and should utilize
pre-existing tools where possible.
The number of new notations and file formats that a user needs to
learn should be kept to a minimum.
Invoking a build should be simple. Sensible defaults should be used
to minimize the need for user input at the time of invocation.
\begin{goal}
The system should be able to run entirely on a relatively power and
resource constrained system such as a laptop, i.e., without needing
a beefy build box, or architecture-specific hardware.
\end{goal}
The ability to be able to work using a low power compute platform is a
necessity in the project's current development environment
The need to be frugal in resource consumption rules out the use of
certain convenient but resource hungry implementation options.
\begin{goal}
The system should work in ``offline'' mode, without requiring
external network access to function.
\end{goal}
The intent is to be able to work in ``standalone'' mode, without
needing to contact a master server on the network.
\begin{goal}
The system should allow a source tree that is in-development to be
built and tested, prior to a check-in.
\end{goal}
This system is primarily a development aid, and not primarily a tool
for implementing continuous integration.
\begin{goal}
The system should be easy to deploy, with the minimum of software
dependencies.
\end{goal}
The fewer dependencies on third party packages, the easier it is to
support target operating systems.
\begin{goal}
The utility should be easy to port to a new operating system.
\end{goal}
This goal is meant to reduce the effort needed to support new
operating systems.

View File

@ -1,13 +0,0 @@
% $Id: master.nw 2461 2012-03-11 10:15:00Z jkoshy $
%
% The build master.
\chapter{The Build Master}\label{chap.master}
% Stub.
<<build-master>>=
def main():
print "Hello World\n"
@ %def main
% End-of-file.

View File

@ -1,340 +0,0 @@
% -*- mode: Noweb; -*-
%
% $Id: slave.nw 2561 2012-08-31 02:46:33Z jkoshy $
%
% The build slave.
\chapter{The Build Slave}\label{chap.slave}
\section{Overview}
\paragraph{File structure}
The implementation of the \tool{yabs} slave is structured along
conventional lines.
<<slave/slave.c>>=
<<generated file warning>>
<<slave: include headers>>
<<slave: declare types and constants>>
<<slave: define helper functions>>
<<slave: define main()>>
@
\section{Data Types}
The data structures used in the \tool{yabs} slave are:
\begin{itemize}
\item A data structure to record command-line options
([[struct slave_options]]).
\item Others...(TBD).
\end{itemize}
<<slave: declare types and constants>>=
<<define common constants>>
<<slave: declare slave options>>
@
\paragraph{Slave Options}\label{para:slave-options}
The [[slave_options]] structure is used to track the options
controlling the slave's behavior.
This structure is populated in the \func{main} function.
<<slave: declare slave options>>=
struct slave_options {
char *sl_id;
unsigned long sl_port;
const char *sl_server;
enum yabs_server_type sl_servertype;
int sl_verbose;
};
@ %def slave_options
\begin{itemize}
\item The \var{sl\_id} member specifies the identifier that the slave
sends to the \tool{yabs} despatcher at connect time.
The default identifier is the system's hostname (see chunk
[[<<slave: set the slave identifier if not set>>]]). The ``-i''
option is used to change the identifier (see [[<<slave: handle -i>>]]).
\item The \var{sl\_port} field specifies the TCP port on the server
running the \tool{yabs} despatcher that the slave should connect to.
This is overrideable by the ``-p'' command-line option (see
[[<<slave: handle -p>>]]).
\item The \var{sl\_server} field specifies the server to connect to.
The \var{sc\_servertype} field specifies whether to use a TCP
connection, a local socket, or to use standard input and output
(see [[enum yabs_server_type]]).
\item The \var{sl\_verbose} field specifies the verbosity level for
the slave.
\end{itemize}
<<slave: initialize option structure>>=
options.sl_id = NULL;
options.sl_port = YABS_DEFAULT_DESPATCHER_PORT;
options.sl_server = NULL;
options.sl_servertype = YABS_SERVER_STDIN;
options.sl_verbose = 0;
@
\section{The Program Entry Point}
<<slave: define main()>>=
int
main(int argc, char **argv)
{
<<slave: main: local variables>>
<<slave: initialize option structure>>
<<slave: parse options>>
<<slave: invoke libevent main loop>>
return (0);
}
@ %def main
The [[<<slave: main: local variables>>]] chunk declares the local
variables needed by the function.
\paragraph{Option Parsing}
Option parsing uses the POSIX \func{getopt} API. The end result of
the option parsing is an appropriately configured [[slave_options]]
structure.
<<slave: main: local variables>>=
struct slave_options options;
int option;
@
<<slave: parse options>>=
while ((option = getopt(argc, argv, "hi:p:vV")) != -1) {
switch (option) {
case 'h':
display_usage_message(); exit(0);
break;
case 'i':
<<slave: handle -i>>
break;
case 'p':
<<slave: handle -p>>
break;
case 'v':
<<slave: handle -v>>
break;
case 'V':
<<slave: handle -V>>
break;
case '?':
display_usage_message(); exit(1);
break;
default:
errx(1, "FATAL: Unrecognized option value %c (%d)",
option, option);
break;
}
}
<<slave: set the slave identifier if not set>>
@
\paragraph{Handling ``-i''}
The identifier by which the slave identifies itself to the despatcher
can be set using the ``-i'' option. If this option is specified
multiple times, the last one takes precedence.
<<slave: handle -i>>=
if (options.sl_id)
free(options.sl_id);
options.sl_id = strdup(optarg);
@
\paragraph{Handling ``-p''}
The ``-p'' option is used to specify the port the slave should connect
to. It is required to be a decimal number: we use the \func{strtoul}
function to convert the option argument to a number.
<<slave: main: local variables>>=
char *end;
@
<<slave: handle -p>>=
options.sl_port = strtoul(optarg, &end, 10);
if (options.sl_port == 0 || *end != '\0')
errx(1, "Invalid port number \"%s\"", optarg);
@
\paragraph{Handling ``-v'''}
The ``-v'' option increases verbosity. The current verbosity level is
recorded in the \var{sc\_verbose} field.
<<slave: handle -v>>=
options.sl_verbose++;
@
\paragraph{Handling ``-V''}
The ``-V'' option prints a version number, and exits.
<<slave: declare types and constants>>=
#define YABS_SLAVE_NAME "yabs-slave"
@ %def YABS_SLAVE_NAME
<<slave: handle -V>>=
(void) printf(YABS_SLAVE_NAME " " YABS_SLAVE_VERSION " (Protocol: "
YABS_PROTOCOL_VERSION ")\n");
exit(0);
@
\paragraph{Setting a default identifier}
If an identifier was not specified by a '-i' command line option, we
use the name of the host the slave is running on.
<<slave: set the slave identifier if not set>>=
if (options.sl_id == NULL) {
<<slave: allocate space for the slave identifier>>
<<slave: retrieve the host name>>
}
@
<<slave: allocate space for the slave identifier>>=
if ((options.sl_id = malloc(HOST_NAME_MAX)) == NULL)
err(1, "malloc failed: [%s,%d]", __FILE__, __LINE__);
@
The system's host name is retrieved using the \func{gethostname} library
function. We explicitly NUL-terminate the array after calling \func{gethostname},
since portable programs cannot assume that function does so for host names
that are exactly HOST\_NAME\_MAX bytes long.
<<slave: retrieve the host name>>=
if (gethostname(options.sl_id, HOST_NAME_MAX) < 0)
err(1, "gethostname failed: [%s,%d]", __FILE__, __LINE__);
options.sl_id[HOST_NAME_MAX - 1] = '\0';
@
\paragraph{Invoking libevent}
<<slave: invoke libevent main loop>>=
event_base_loop((void *) 0, 0);
@
\section{Helper Functions}
<<slave: define helper functions>>=
void
display_usage_message(void)
{
(void) printf("usage: " YABS_SLAVE_NAME " [options] [server]\n\n" \
"Supported options:\n" \
" -h\t\tPrint a help message and exit.\n" \
" -i ID\tUse ID as an identifier [host name]\n" \
" -p PORT\tConnect to port PORT on the server [0x4242].\n" \
" -v\t\tBe more verbose.\n" \
" -V\t\tPrint a version identifier and exit.\n");
}
@ %def display_usage_message
\section{Header Inclusions}
The use of the \func{errx} family of functions requires the standard
header \file{err.h}.
<<slave: include headers>>=
#include <err.h>
@
The \var{HOST\_NAME\_MAX} constant used in the chunk
[[<<slave: set the slave identifier if not set>>]] is
defined by the \file{limits.h} header.
<<slave: include headers>>=
#include <limits.h>
@
The use of the \func{printf} function requires the use of the system
header \file{stdio.h}.
<<slave: include headers>>=
#include <stdio.h>
@
The header file \file{stdlib.h} is needed for the prototypes for the
\func{exit}, \func{free} and \func{malloc} functions.
<<slave: include headers>>=
#include <stdlib.h>
@
The header file \file{string.h} provides the prototype for
\func{strdup} used in chunk [[<<Handling ``-i''>>]].
<<slave: include headers>>=
#include <string.h>
@
The header file \file{unistd.h} is needed for the prototype for the
\func{getopt} function used in chunk [[<<slave: parse options>>]].
<<slave: include headers>>=
#include <unistd.h>
@
\tool{Libevent} specific headers are needed for the libevent APIs:
<<slave: include headers>>=
#include <event2/event.h>
@
\section{Build Rules}
Using the facilities provided by the standard rules in
\verb|<bsd.prog.mk>|, a simple \file{Makefile} suffices to build the
slave.
The \file{Makefile} indicates that the generated progam is to be
called \tool{yabs-slave} and that the file \file{slave.c} is the
source file to be compiled. The contents of this source file is
defined by the chunk [[<<slave/slave.c>>]].
<<slave/Makefile>>=
PROG= yabs-slave
SRCS= slave.c
CFLAGS+= -Wall -Wextra -Werror -pedantic
<<make: libevent related definitions>>
.include <bsd.prog.mk>
<<make: override debug flags during development>>
@
We look in a set of standard locations to determine where the headers
and library files for \tool{libevent} are located.
<<make: libevent related definitions>>=
.if exists(${HOME}/local/include/event2)
LIBEVENT_INCLUDE= -I ${HOME}/local/include
LIBEVENT_LIB= -L ${HOME}/local/lib
.elif exists(/usr/local/include/event2)
LIBEVENT_INCLUDE= -I /usr/local/include
LIBEVENT_LIB= -L /usr/local/lib
.endif
CFLAGS+= ${LIBEVENT_INCLUDE}
LDADD+= ${LIBEVENT_LIB} -levent
@
Debugging is simpler if compiler optimizations are turned off. We
thus remove the \term{-O2} flag during development.
<<make: override debug flags during development>>=
CFLAGS:= ${CFLAGS:N-O2} -g
LDFLAGS+= -g
@
% Local Variables:
% noweb-code-mode: c-mode
% c-electric-flag: nil
% End:

View File

@ -1,80 +0,0 @@
% $Id: userguide.nw 2556 2012-08-29 13:17:07Z jkoshy $
%
% A user guide on how to use the system--configuring and running a
% build.
\chapter{Using The Build System}\label{chap.userguide}
This chapter describes how to use the system.
\section{Terminology}
First, some definitions:
\begin{itemize}
\item A \definition{machine} is hardware that could be invoked during
the execution of a job.
A ``machine'' could be a physical machines that is to be powered up
for the job, or a virtual machine that is to be started up.
The \tool{yabs} utility uses user-provided shell script fragments to
control machines. Hence a ``machine'' could also be an invocation
of a remote host via the \tool{ssh} program.
A machine is expected to execute the ``slave'' program (see below)
once it is has booted.
\item A \definition{job definition} specifies the information needed
to run a job. A job definition will specify:
\begin{itemize}
\item The list of machines to be invoked.
\item The specific commands be run inside each machine.
\item The results to retrieved from each machine, after the
commands are run.
\item The name of a ``job scheduler'' (see below).
\end{itemize}
\item A \definition{job} is a particular invocation of a \term{job
definition}.
\item A \definition{job scheduler} is a program that implements the
logic for starting and stopping individual steps that are part of a
job. The system provides a default scheduler which would suffice
for most cases. Users can override the default scheduler if their
jobs have special needs.
\item The \tool{yabs} \definition{slave} is a program that runs
inside a booted machine, running the tasks defined in the
job definition.
\item A \definition{slave script} is a shell script that lists the
actions to be executed inside a particular virtual machine. Slave
scripts are usually written in the shell (\tool{sh}) programming
language.
\end{itemize}
\section{Configuration}
TODO: describe how to configure the tool.
% File locations for $ROOT:
% /etc/yabs/default/
% /etc/yabs/<job-name>/
% $HOME/.yabs/default/
% $HOME/.yabs/<job-name>/
% $ROOT/build-name/config -- configuration
% $ROOT/build-name/scheduler -- which order to run stuff
% $ROOT/build-name/<machine>.startup -- how to (externally) start the machine
% $ROOT/build-name/<machine>.shutdown -- how to (externally) stop the machine
% $ROOT/build-name/<machine>.commands -- the build commands to be issued
% Logs:
% /var/logs/yabs/build-name.NNN

View File

@ -1,38 +0,0 @@
% $Id$
%
% Code chunks containing utility functions.
\chapter{Common Code}\label{chap.utility}
\paragraph{Default despatcher port}
<<define common constants>>=
#define YABS_DEFAULT_DESPATCHER_PORT 0x4242
@ %def YABS_DEFAULT_DESPATCHER_PORT
\paragraph{Version numbers}
<<define common constants>>=
#define YABS_PROTOCOL_VERSION "1.0"
#define YABS_SLAVE_VERSION "1.0"
@ %def YABS_SLAVE_VERSION YABS_PROTOCOL_VERSION
\paragraph{Slave connection types}
<<define common constants>>=
enum yabs_server_type {
YABS_SERVER_STDIN,
YABS_SERVER_LOCAL,
YABS_SERVER_TCP
};
@ %def yabs_server_type YABS_SERVER_STDIN YABS_SERVER_LOCAL YABS_SERVER_TCP
\paragraph{Warning Template}
<<generated file warning>>=
/*
* WARNING. GENERATED CODE. DO NOT EDIT.
*
* This file contained generated code. You should be looking at
* its literate program source instead.
*
* WARNING. GENERATED CODE. DO NOT EDIT.
*/
@