Import ELF Tool Chain snapshot at r3769
From https://svn.code.sf.net/p/elftoolchain/code/
This commit is contained in:
parent
2b92b30119
commit
a5b08c1484
22
.cirrus.yml
Normal file
22
.cirrus.yml
Normal file
@ -0,0 +1,22 @@
|
|||||||
|
freebsd_11_task:
|
||||||
|
freebsd_instance:
|
||||||
|
image: freebsd-11-2-release-amd64
|
||||||
|
install_script: pkg install -y git py27-yaml
|
||||||
|
script:
|
||||||
|
- fetch http://tetworks.opengroup.org/downloads/38/software/Sources/3.8/tet3.8-src.tar.gz
|
||||||
|
- tar -x -C test/tet -f tet3.8-src.tar.gz
|
||||||
|
- make
|
||||||
|
|
||||||
|
debian_stable_task:
|
||||||
|
container:
|
||||||
|
image: debian:stable
|
||||||
|
setup_script:
|
||||||
|
- apt-get update
|
||||||
|
- apt-get install -y
|
||||||
|
binutils bison bmake curl flex g++ gcc git
|
||||||
|
libarchive-dev libbsd-dev libc6-dev libexpat1-dev lsb-release
|
||||||
|
m4 perl python-yaml sharutils zlib1g-dev
|
||||||
|
script:
|
||||||
|
- curl -O http://tetworks.opengroup.org/downloads/38/software/Sources/3.8/tet3.8-src.tar.gz
|
||||||
|
- tar -x -C test/tet -z -f tet3.8-src.tar.gz
|
||||||
|
- bmake
|
10
README.rst
10
README.rst
@ -62,12 +62,12 @@ The project uses subversion_ for its version control system.
|
|||||||
The subversion branch for the current set of sources may be accessed
|
The subversion branch for the current set of sources may be accessed
|
||||||
at the following URL::
|
at the following URL::
|
||||||
|
|
||||||
https://elftoolchain.svn.sourceforge.net/svnroot/elftoolchain/trunk
|
https://sourceforge.net/p/elftoolchain/code/HEAD/tree/trunk/
|
||||||
|
|
||||||
The project's source tree may be checked out from its repository by
|
The project's source tree may be checked out from its repository by
|
||||||
using the ``svn checkout`` command::
|
using the ``svn checkout`` command::
|
||||||
|
|
||||||
% svn checkout https://elftoolchain.svn.sourceforge.net/svnroot/elftoolchain/trunk
|
% svn checkout https://svn.code.sf.net/p/elftoolchain/code/trunk
|
||||||
|
|
||||||
Checked-out sources may be kept upto-date by running ``svn update``
|
Checked-out sources may be kept upto-date by running ``svn update``
|
||||||
inside the source directory::
|
inside the source directory::
|
||||||
@ -105,10 +105,10 @@ The project's developers may be contacted using the mailing list:
|
|||||||
Reporting Bugs
|
Reporting Bugs
|
||||||
--------------
|
--------------
|
||||||
|
|
||||||
Please use our `Trac instance`_ for viewing existing bug reports and
|
Please use our `bug tracker`_ for viewing existing bug reports and
|
||||||
for submitting new bug reports.
|
for submitting new bug reports.
|
||||||
|
|
||||||
.. _`Trac instance`: http://sourceforge.net/apps/trac/elftoolchain/report
|
.. _`bug tracker`: https://sourceforge.net/p/elftoolchain/tickets/
|
||||||
|
|
||||||
|
|
||||||
Additional Information
|
Additional Information
|
||||||
@ -119,7 +119,7 @@ website`_.
|
|||||||
|
|
||||||
.. _project website: http://elftoolchain.sourceforge.net/
|
.. _project website: http://elftoolchain.sourceforge.net/
|
||||||
|
|
||||||
.. $Id: README.rst 3656 2018-12-26 09:46:24Z jkoshy $
|
.. $Id: README.rst 3677 2019-02-11 09:37:09Z jkoshy $
|
||||||
|
|
||||||
.. Local Variables:
|
.. Local Variables:
|
||||||
.. mode: rst
|
.. mode: rst
|
||||||
|
@ -40,7 +40,7 @@
|
|||||||
#include "uthash.h"
|
#include "uthash.h"
|
||||||
#include "_elftc.h"
|
#include "_elftc.h"
|
||||||
|
|
||||||
ELFTC_VCSID("$Id: addr2line.c 3544 2017-06-05 14:51:44Z emaste $");
|
ELFTC_VCSID("$Id: addr2line.c 3499 2016-11-25 16:06:29Z emaste $");
|
||||||
|
|
||||||
struct Func {
|
struct Func {
|
||||||
char *name;
|
char *name;
|
||||||
|
@ -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: elfdefinitions.h 3515 2017-01-24 22:04:22Z emaste $
|
* $Id: elfdefinitions.h 3769 2019-06-29 15:15:02Z emaste $
|
||||||
*/
|
*/
|
||||||
|
|
||||||
/*
|
/*
|
||||||
@ -72,7 +72,39 @@ _ELF_DEFINE_DF(DF_TEXTREL, 0x4, \
|
|||||||
_ELF_DEFINE_DF(DF_BIND_NOW, 0x8, \
|
_ELF_DEFINE_DF(DF_BIND_NOW, 0x8, \
|
||||||
"process relocation entries at load time") \
|
"process relocation entries at load time") \
|
||||||
_ELF_DEFINE_DF(DF_STATIC_TLS, 0x10, \
|
_ELF_DEFINE_DF(DF_STATIC_TLS, 0x10, \
|
||||||
"uses static thread-local storage")
|
"uses static thread-local storage") \
|
||||||
|
_ELF_DEFINE_DF(DF_1_BIND_NOW, 0x1, \
|
||||||
|
"process relocation entries at load time") \
|
||||||
|
_ELF_DEFINE_DF(DF_1_GLOBAL, 0x2, \
|
||||||
|
"unused") \
|
||||||
|
_ELF_DEFINE_DF(DF_1_GROUP, 0x4, \
|
||||||
|
"object is a member of a group") \
|
||||||
|
_ELF_DEFINE_DF(DF_1_NODELETE, 0x8, \
|
||||||
|
"object cannot be deleted from a process") \
|
||||||
|
_ELF_DEFINE_DF(DF_1_LOADFLTR, 0x10, \
|
||||||
|
"immediate load filtees") \
|
||||||
|
_ELF_DEFINE_DF(DF_1_INITFIRST, 0x20, \
|
||||||
|
"initialize object first") \
|
||||||
|
_ELF_DEFINE_DF(DF_1_NOOPEN, 0x40, \
|
||||||
|
"disallow dlopen()") \
|
||||||
|
_ELF_DEFINE_DF(DF_1_ORIGIN, 0x80, \
|
||||||
|
"object being loaded may refer to $ORIGIN") \
|
||||||
|
_ELF_DEFINE_DF(DF_1_DIRECT, 0x100, \
|
||||||
|
"direct bindings enabled") \
|
||||||
|
_ELF_DEFINE_DF(DF_1_INTERPOSE, 0x400, \
|
||||||
|
"object is interposer") \
|
||||||
|
_ELF_DEFINE_DF(DF_1_NODEFLIB, 0x800, \
|
||||||
|
"ignore default library search path") \
|
||||||
|
_ELF_DEFINE_DF(DF_1_NODUMP, 0x1000, \
|
||||||
|
"disallow dldump()") \
|
||||||
|
_ELF_DEFINE_DF(DF_1_CONFALT, 0x2000, \
|
||||||
|
"object is a configuration alternative") \
|
||||||
|
_ELF_DEFINE_DF(DF_1_ENDFILTEE, 0x4000, \
|
||||||
|
"filtee terminates filter search") \
|
||||||
|
_ELF_DEFINE_DF(DF_1_DISPRELDNE, 0x8000, \
|
||||||
|
"displacement relocation done") \
|
||||||
|
_ELF_DEFINE_DF(DF_1_DISPRELPND, 0x10000, \
|
||||||
|
"displacement relocation pending")
|
||||||
#undef _ELF_DEFINE_DF
|
#undef _ELF_DEFINE_DF
|
||||||
#define _ELF_DEFINE_DF(N, V, DESCR) N = V ,
|
#define _ELF_DEFINE_DF(N, V, DESCR) N = V ,
|
||||||
enum {
|
enum {
|
||||||
@ -2448,7 +2480,10 @@ _ELF_DEFINE_NT(NT_PSTATUS, 10, "Linux process status") \
|
|||||||
_ELF_DEFINE_NT(NT_FPREGS, 12, "Linux floating point regset") \
|
_ELF_DEFINE_NT(NT_FPREGS, 12, "Linux floating point regset") \
|
||||||
_ELF_DEFINE_NT(NT_PSINFO, 13, "Linux process information") \
|
_ELF_DEFINE_NT(NT_PSINFO, 13, "Linux process information") \
|
||||||
_ELF_DEFINE_NT(NT_LWPSTATUS, 16, "Linux lwpstatus_t type") \
|
_ELF_DEFINE_NT(NT_LWPSTATUS, 16, "Linux lwpstatus_t type") \
|
||||||
_ELF_DEFINE_NT(NT_LWPSINFO, 17, "Linux lwpinfo_t type")
|
_ELF_DEFINE_NT(NT_LWPSINFO, 17, "Linux lwpinfo_t type") \
|
||||||
|
_ELF_DEFINE_NT(NT_FREEBSD_NOINIT_TAG, 2, "FreeBSD no .init tag") \
|
||||||
|
_ELF_DEFINE_NT(NT_FREEBSD_ARCH_TAG, 3, "FreeBSD arch tag") \
|
||||||
|
_ELF_DEFINE_NT(NT_FREEBSD_FEATURE_CTL, 4, "FreeBSD feature control")
|
||||||
|
|
||||||
#undef _ELF_DEFINE_NT
|
#undef _ELF_DEFINE_NT
|
||||||
#define _ELF_DEFINE_NT(N, V, DESCR) N = V ,
|
#define _ELF_DEFINE_NT(N, V, DESCR) N = V ,
|
||||||
@ -2806,7 +2841,8 @@ typedef struct {
|
|||||||
|
|
||||||
#define ELF64_R_SYM(I) ((I) >> 32)
|
#define ELF64_R_SYM(I) ((I) >> 32)
|
||||||
#define ELF64_R_TYPE(I) ((I) & 0xFFFFFFFFUL)
|
#define ELF64_R_TYPE(I) ((I) & 0xFFFFFFFFUL)
|
||||||
#define ELF64_R_INFO(S,T) (((S) << 32) + ((T) & 0xFFFFFFFFUL))
|
#define ELF64_R_INFO(S,T) \
|
||||||
|
(((Elf64_Xword) (S) << 32) + ((T) & 0xFFFFFFFFUL))
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* Symbol versioning structures.
|
* Symbol versioning structures.
|
||||||
|
@ -1,6 +1,6 @@
|
|||||||
#!/bin/sh
|
#!/bin/sh
|
||||||
#
|
#
|
||||||
# $Id: native-elf-format 3650 2018-11-25 12:06:28Z jkoshy $
|
# $Id: native-elf-format 3735 2019-04-25 19:44:47Z jkoshy $
|
||||||
#
|
#
|
||||||
# Find the native ELF format for a host platform by compiling a
|
# Find the native ELF format for a host platform by compiling a
|
||||||
# test object and examining the resulting object.
|
# test object and examining the resulting object.
|
||||||
@ -37,6 +37,8 @@ $1 ~ "Machine:" {
|
|||||||
elfarch = "EM_MIPS";
|
elfarch = "EM_MIPS";
|
||||||
} else if (match($0, ".*[xX]86[-_]64")) {
|
} else if (match($0, ".*[xX]86[-_]64")) {
|
||||||
elfarch = "EM_X86_64";
|
elfarch = "EM_X86_64";
|
||||||
|
} else if (match($0, "PowerPC64")) {
|
||||||
|
elfarch = "EM_PPC64";
|
||||||
} else {
|
} else {
|
||||||
elfarch = "unknown";
|
elfarch = "unknown";
|
||||||
}
|
}
|
||||||
|
@ -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: libelf-by-example.tex 2457 2012-03-09 14:38:10Z jkoshy $
|
% $Id: libelf-by-example.tex 3699 2019-02-28 06:34:53Z jkoshy $
|
||||||
%
|
%
|
||||||
\documentclass[a4paper,pdftex]{book}
|
\documentclass[a4paper,pdftex]{book}
|
||||||
|
|
||||||
@ -2700,6 +2700,12 @@ typedef struct {
|
|||||||
\emph{parent} archive descriptor (referenced by
|
\emph{parent} archive descriptor (referenced by
|
||||||
variable \parameter{ar} in this example) to return the next
|
variable \parameter{ar} in this example) to return the next
|
||||||
archive member on the next call to function \function{elf\_begin}.
|
archive member on the next call to function \function{elf\_begin}.
|
||||||
|
|
||||||
|
The \function{elf\_next} function ordinarily returns the value
|
||||||
|
\constant{ELF\_C\_READ}, allowing the traversal of the archive to
|
||||||
|
continue normally. In the event of an error the function
|
||||||
|
returns the value \constant{ELF\_C\_NULL}, which causes the function
|
||||||
|
\function{elf\_begin} to stop archive traversal.
|
||||||
\item[\coref{6}] It is good programming practice to call
|
\item[\coref{6}] It is good programming practice to call
|
||||||
\function{elf\_end} on descriptors that are no longer needed.
|
\function{elf\_end} on descriptors that are no longer needed.
|
||||||
\end{description}
|
\end{description}
|
||||||
|
@ -1,7 +1,7 @@
|
|||||||
/*
|
/*
|
||||||
* Print the ELF Program Header Table in an ELF object.
|
* Print the ELF Program Header Table in an ELF object.
|
||||||
*
|
*
|
||||||
* $Id: prog3.txt 2133 2011-11-10 08:28:22Z jkoshy $
|
* $Id: prog3.txt 3686 2019-02-22 07:54:47Z jkoshy $
|
||||||
*/
|
*/
|
||||||
|
|
||||||
#include <err.h>
|
#include <err.h>
|
||||||
@ -11,7 +11,6 @@
|
|||||||
#include <stdint.h>
|
#include <stdint.h>
|
||||||
#include <stdlib.h>
|
#include <stdlib.h>
|
||||||
#include <unistd.h>
|
#include <unistd.h>
|
||||||
#include <vis.h>
|
|
||||||
|
|
||||||
void
|
void
|
||||||
print_ptype(size_t pt) @\co{7}@
|
print_ptype(size_t pt) @\co{7}@
|
||||||
|
@ -1,7 +1,7 @@
|
|||||||
/*
|
/*
|
||||||
* Print the names of ELF sections.
|
* Print the names of ELF sections.
|
||||||
*
|
*
|
||||||
* $Id: prog4.txt 2133 2011-11-10 08:28:22Z jkoshy $
|
* $Id: prog4.txt 3687 2019-02-22 07:55:09Z jkoshy $
|
||||||
*/
|
*/
|
||||||
|
|
||||||
#include <err.h>
|
#include <err.h>
|
||||||
@ -18,11 +18,11 @@ main(int argc, char **argv)
|
|||||||
{
|
{
|
||||||
int fd;
|
int fd;
|
||||||
Elf *e;
|
Elf *e;
|
||||||
char *name, *p, pc[4*sizeof(char)];
|
|
||||||
Elf_Scn *scn;
|
Elf_Scn *scn;
|
||||||
Elf_Data *data;
|
Elf_Data *data;
|
||||||
GElf_Shdr shdr;
|
GElf_Shdr shdr;
|
||||||
size_t n, shstrndx, sz;
|
size_t n, shstrndx, sz;
|
||||||
|
char *name, *p, pc[(4 * sizeof(char)) + 1];
|
||||||
|
|
||||||
if (argc != 2)
|
if (argc != 2)
|
||||||
errx(EXIT_FAILURE, "usage: %s file-name", argv[0]);
|
errx(EXIT_FAILURE, "usage: %s file-name", argv[0]);
|
||||||
|
@ -1,7 +1,7 @@
|
|||||||
/*
|
/*
|
||||||
* Iterate through an ar(1) archive.
|
* Iterate through an ar(1) archive.
|
||||||
*
|
*
|
||||||
* $Id: prog6.txt 2135 2011-11-10 08:59:47Z jkoshy $
|
* $Id: prog6.txt 3699 2019-02-28 06:34:53Z jkoshy $
|
||||||
*/
|
*/
|
||||||
|
|
||||||
#include <err.h>
|
#include <err.h>
|
||||||
@ -16,6 +16,7 @@ main(int argc, char **argv)
|
|||||||
{
|
{
|
||||||
int fd;
|
int fd;
|
||||||
Elf *ar, *e;
|
Elf *ar, *e;
|
||||||
|
Elf_Cmd cmd;
|
||||||
Elf_Arhdr *arh;
|
Elf_Arhdr *arh;
|
||||||
|
|
||||||
if (argc != 2)
|
if (argc != 2)
|
||||||
@ -39,7 +40,8 @@ main(int argc, char **argv)
|
|||||||
errx(EXIT_FAILURE, "%s is not an ar(1) archive.",
|
errx(EXIT_FAILURE, "%s is not an ar(1) archive.",
|
||||||
argv[1]);
|
argv[1]);
|
||||||
|
|
||||||
while ((e = elf_begin(fd, ELF_C_READ, ar)) != NULL) { @\co{3}@
|
cmd = ELF_C_READ;
|
||||||
|
while ((e = elf_begin(fd, cmd, ar)) != NULL) { @\co{3}@
|
||||||
if ((arh = elf_getarhdr(e)) == NULL) @\co{4}@
|
if ((arh = elf_getarhdr(e)) == NULL) @\co{4}@
|
||||||
errx(EXIT_FAILURE, "elf_getarhdr() failed: %s.",
|
errx(EXIT_FAILURE, "elf_getarhdr() failed: %s.",
|
||||||
elf_errmsg(-1));
|
elf_errmsg(-1));
|
||||||
@ -47,7 +49,7 @@ main(int argc, char **argv)
|
|||||||
(void) printf("%20s %zd\n", arh->ar_name,
|
(void) printf("%20s %zd\n", arh->ar_name,
|
||||||
arh->ar_size);
|
arh->ar_size);
|
||||||
|
|
||||||
(void) elf_next(e); @\co{5}@
|
cmd = elf_next(e); @\co{5}@
|
||||||
(void) elf_end(e); @\co{6}@
|
(void) elf_end(e); @\co{6}@
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -36,7 +36,7 @@
|
|||||||
|
|
||||||
#include "elfcopy.h"
|
#include "elfcopy.h"
|
||||||
|
|
||||||
ELFTC_VCSID("$Id: ascii.c 3487 2016-08-24 18:12:08Z emaste $");
|
ELFTC_VCSID("$Id: ascii.c 3757 2019-06-28 01:15:28Z emaste $");
|
||||||
|
|
||||||
static void append_data(struct section *s, const void *buf, size_t sz);
|
static void append_data(struct section *s, const void *buf, size_t sz);
|
||||||
static char hex_digit(uint8_t n);
|
static char hex_digit(uint8_t n);
|
||||||
@ -378,9 +378,6 @@ create_elf_from_srec(struct elfcopy *ecp, int ifd)
|
|||||||
errx(EXIT_FAILURE, "gelf_update_ehdr() failed: %s",
|
errx(EXIT_FAILURE, "gelf_update_ehdr() failed: %s",
|
||||||
elf_errmsg(-1));
|
elf_errmsg(-1));
|
||||||
|
|
||||||
/* Generate section name string table (.shstrtab). */
|
|
||||||
set_shstrtab(ecp);
|
|
||||||
|
|
||||||
/* Update sh_name pointer for each section header entry. */
|
/* Update sh_name pointer for each section header entry. */
|
||||||
update_shdr(ecp, 0);
|
update_shdr(ecp, 0);
|
||||||
|
|
||||||
@ -605,9 +602,6 @@ create_elf_from_ihex(struct elfcopy *ecp, int ifd)
|
|||||||
errx(EXIT_FAILURE, "gelf_update_ehdr() failed: %s",
|
errx(EXIT_FAILURE, "gelf_update_ehdr() failed: %s",
|
||||||
elf_errmsg(-1));
|
elf_errmsg(-1));
|
||||||
|
|
||||||
/* Generate section name string table (.shstrtab). */
|
|
||||||
set_shstrtab(ecp);
|
|
||||||
|
|
||||||
/* Update sh_name pointer for each section header entry. */
|
/* Update sh_name pointer for each section header entry. */
|
||||||
update_shdr(ecp, 0);
|
update_shdr(ecp, 0);
|
||||||
|
|
||||||
|
@ -36,7 +36,7 @@
|
|||||||
|
|
||||||
#include "elfcopy.h"
|
#include "elfcopy.h"
|
||||||
|
|
||||||
ELFTC_VCSID("$Id: binary.c 3611 2018-04-16 21:35:18Z jkoshy $");
|
ELFTC_VCSID("$Id: binary.c 3757 2019-06-28 01:15:28Z emaste $");
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* Convert ELF object to `binary'. Sections with SHF_ALLOC flag set
|
* Convert ELF object to `binary'. Sections with SHF_ALLOC flag set
|
||||||
@ -250,11 +250,8 @@ create_elf_from_binary(struct elfcopy *ecp, int ifd, const char *ifn)
|
|||||||
errx(EXIT_FAILURE, "gelf_update_ehdr() failed: %s",
|
errx(EXIT_FAILURE, "gelf_update_ehdr() failed: %s",
|
||||||
elf_errmsg(-1));
|
elf_errmsg(-1));
|
||||||
|
|
||||||
/* Generate section name string table (.shstrtab). */
|
|
||||||
ecp->flags |= SYMTAB_EXIST;
|
|
||||||
set_shstrtab(ecp);
|
|
||||||
|
|
||||||
/* Update sh_name pointer for each section header entry. */
|
/* Update sh_name pointer for each section header entry. */
|
||||||
|
ecp->flags |= SYMTAB_EXIST;
|
||||||
update_shdr(ecp, 0);
|
update_shdr(ecp, 0);
|
||||||
|
|
||||||
/* Properly set sh_link field of .symtab section. */
|
/* Properly set sh_link field of .symtab section. */
|
||||||
|
@ -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: elfcopy.h 3615 2018-05-17 04:12:24Z kaiwang27 $
|
* $Id: elfcopy.h 3757 2019-06-28 01:15:28Z emaste $
|
||||||
*/
|
*/
|
||||||
|
|
||||||
#include <sys/queue.h>
|
#include <sys/queue.h>
|
||||||
@ -135,9 +135,13 @@ struct section {
|
|||||||
int pseudo;
|
int pseudo;
|
||||||
int nocopy;
|
int nocopy;
|
||||||
|
|
||||||
|
Elftc_String_Table *strtab;
|
||||||
|
|
||||||
TAILQ_ENTRY(section) sec_list; /* next section */
|
TAILQ_ENTRY(section) sec_list; /* next section */
|
||||||
};
|
};
|
||||||
|
|
||||||
|
TAILQ_HEAD(sectionlist, section);
|
||||||
|
|
||||||
/* Internal data structure for segments. */
|
/* Internal data structure for segments. */
|
||||||
struct segment {
|
struct segment {
|
||||||
uint64_t vaddr; /* virtual addr (VMA) */
|
uint64_t vaddr; /* virtual addr (VMA) */
|
||||||
@ -311,7 +315,6 @@ struct sec_action *lookup_sec_act(struct elfcopy *_ecp,
|
|||||||
struct symop *lookup_symop_list(struct elfcopy *_ecp, const char *_name,
|
struct symop *lookup_symop_list(struct elfcopy *_ecp, const char *_name,
|
||||||
unsigned int _op);
|
unsigned int _op);
|
||||||
void resync_sections(struct elfcopy *_ecp);
|
void resync_sections(struct elfcopy *_ecp);
|
||||||
void set_shstrtab(struct elfcopy *_ecp);
|
|
||||||
void setup_phdr(struct elfcopy *_ecp);
|
void setup_phdr(struct elfcopy *_ecp);
|
||||||
void update_shdr(struct elfcopy *_ecp, int _update_link);
|
void update_shdr(struct elfcopy *_ecp, int _update_link);
|
||||||
|
|
||||||
|
@ -39,7 +39,7 @@
|
|||||||
|
|
||||||
#include "elfcopy.h"
|
#include "elfcopy.h"
|
||||||
|
|
||||||
ELFTC_VCSID("$Id: main.c 3577 2017-09-14 02:19:42Z emaste $");
|
ELFTC_VCSID("$Id: main.c 3757 2019-06-28 01:15:28Z emaste $");
|
||||||
|
|
||||||
enum options
|
enum options
|
||||||
{
|
{
|
||||||
@ -388,9 +388,6 @@ create_elf(struct elfcopy *ecp)
|
|||||||
errx(EXIT_FAILURE, "gelf_update_ehdr() failed: %s",
|
errx(EXIT_FAILURE, "gelf_update_ehdr() failed: %s",
|
||||||
elf_errmsg(-1));
|
elf_errmsg(-1));
|
||||||
|
|
||||||
/* Generate section name string table (.shstrtab). */
|
|
||||||
set_shstrtab(ecp);
|
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* Second processing of output sections: Update section headers.
|
* Second processing of output sections: Update section headers.
|
||||||
* At this stage we set name string index, update st_link and st_info
|
* At this stage we set name string index, update st_link and st_info
|
||||||
@ -486,6 +483,9 @@ free_elf(struct elfcopy *ecp)
|
|||||||
/* Free symbol table buffers. */
|
/* Free symbol table buffers. */
|
||||||
free_symtab(ecp);
|
free_symtab(ecp);
|
||||||
|
|
||||||
|
/* Free section name string table. */
|
||||||
|
elftc_string_table_destroy(ecp->shstrtab->strtab);
|
||||||
|
|
||||||
/* Free internal section list. */
|
/* Free internal section list. */
|
||||||
if (!TAILQ_EMPTY(&ecp->v_sec)) {
|
if (!TAILQ_EMPTY(&ecp->v_sec)) {
|
||||||
TAILQ_FOREACH_SAFE(sec, &ecp->v_sec, sec_list, sec_temp) {
|
TAILQ_FOREACH_SAFE(sec, &ecp->v_sec, sec_list, sec_temp) {
|
||||||
@ -1565,7 +1565,6 @@ main(int argc, char **argv)
|
|||||||
ecp = calloc(1, sizeof(*ecp));
|
ecp = calloc(1, sizeof(*ecp));
|
||||||
if (ecp == NULL)
|
if (ecp == NULL)
|
||||||
err(EXIT_FAILURE, "calloc failed");
|
err(EXIT_FAILURE, "calloc failed");
|
||||||
memset(ecp, 0, sizeof(*ecp));
|
|
||||||
|
|
||||||
ecp->itf = ecp->otf = ETF_ELF;
|
ecp->itf = ecp->otf = ETF_ELF;
|
||||||
ecp->iec = ecp->oec = ELFCLASSNONE;
|
ecp->iec = ecp->oec = ELFCLASSNONE;
|
||||||
|
@ -34,7 +34,7 @@
|
|||||||
|
|
||||||
#include "elfcopy.h"
|
#include "elfcopy.h"
|
||||||
|
|
||||||
ELFTC_VCSID("$Id: sections.c 3646 2018-10-27 02:25:39Z emaste $");
|
ELFTC_VCSID("$Id: sections.c 3758 2019-06-28 01:16:50Z emaste $");
|
||||||
|
|
||||||
static void add_gnu_debuglink(struct elfcopy *ecp);
|
static void add_gnu_debuglink(struct elfcopy *ecp);
|
||||||
static uint32_t calc_crc32(const char *p, size_t len, uint32_t crc);
|
static uint32_t calc_crc32(const char *p, size_t len, uint32_t crc);
|
||||||
@ -42,19 +42,18 @@ static void check_section_rename(struct elfcopy *ecp, struct section *s);
|
|||||||
static void filter_reloc(struct elfcopy *ecp, struct section *s);
|
static void filter_reloc(struct elfcopy *ecp, struct section *s);
|
||||||
static int get_section_flags(struct elfcopy *ecp, const char *name);
|
static int get_section_flags(struct elfcopy *ecp, const char *name);
|
||||||
static void insert_sections(struct elfcopy *ecp);
|
static void insert_sections(struct elfcopy *ecp);
|
||||||
static void insert_to_strtab(struct section *t, const char *s);
|
|
||||||
static int is_append_section(struct elfcopy *ecp, const char *name);
|
static int is_append_section(struct elfcopy *ecp, const char *name);
|
||||||
static int is_compress_section(struct elfcopy *ecp, const char *name);
|
static int is_compress_section(struct elfcopy *ecp, const char *name);
|
||||||
static int is_debug_section(const char *name);
|
static int is_debug_section(const char *name);
|
||||||
static int is_dwo_section(const char *name);
|
static int is_dwo_section(const char *name);
|
||||||
static int is_modify_section(struct elfcopy *ecp, const char *name);
|
static int is_modify_section(struct elfcopy *ecp, const char *name);
|
||||||
static int is_print_section(struct elfcopy *ecp, const char *name);
|
static int is_print_section(struct elfcopy *ecp, const char *name);
|
||||||
static int lookup_string(struct section *t, const char *s);
|
|
||||||
static void modify_section(struct elfcopy *ecp, struct section *s);
|
static void modify_section(struct elfcopy *ecp, struct section *s);
|
||||||
static void pad_section(struct elfcopy *ecp, struct section *s);
|
static void pad_section(struct elfcopy *ecp, struct section *s);
|
||||||
static void print_data(const char *d, size_t sz);
|
static void print_data(const char *d, size_t sz);
|
||||||
static void print_section(struct section *s);
|
static void print_section(struct section *s);
|
||||||
static void *read_section(struct section *s, size_t *size);
|
static void *read_section(struct section *s, size_t *size);
|
||||||
|
static void set_shstrtab(struct elfcopy *ecp);
|
||||||
static void update_reloc(struct elfcopy *ecp, struct section *s);
|
static void update_reloc(struct elfcopy *ecp, struct section *s);
|
||||||
static void update_section_group(struct elfcopy *ecp, struct section *s);
|
static void update_section_group(struct elfcopy *ecp, struct section *s);
|
||||||
|
|
||||||
@ -119,21 +118,19 @@ is_remove_reloc_sec(struct elfcopy *ecp, uint32_t sh_info)
|
|||||||
errx(EXIT_FAILURE, "elf_getshstrndx failed: %s",
|
errx(EXIT_FAILURE, "elf_getshstrndx failed: %s",
|
||||||
elf_errmsg(-1));
|
elf_errmsg(-1));
|
||||||
|
|
||||||
is = NULL;
|
is = elf_getscn(ecp->ein, sh_info);
|
||||||
while ((is = elf_nextscn(ecp->ein, is)) != NULL) {
|
if (is != NULL) {
|
||||||
if (sh_info == elf_ndxscn(is)) {
|
if (gelf_getshdr(is, &ish) == NULL)
|
||||||
if (gelf_getshdr(is, &ish) == NULL)
|
errx(EXIT_FAILURE, "gelf_getshdr failed: %s",
|
||||||
errx(EXIT_FAILURE, "gelf_getshdr failed: %s",
|
elf_errmsg(-1));
|
||||||
elf_errmsg(-1));
|
if ((name = elf_strptr(ecp->ein, indx, ish.sh_name)) ==
|
||||||
if ((name = elf_strptr(ecp->ein, indx, ish.sh_name)) ==
|
NULL)
|
||||||
NULL)
|
errx(EXIT_FAILURE, "elf_strptr failed: %s",
|
||||||
errx(EXIT_FAILURE, "elf_strptr failed: %s",
|
elf_errmsg(-1));
|
||||||
elf_errmsg(-1));
|
if (is_remove_section(ecp, name))
|
||||||
if (is_remove_section(ecp, name))
|
return (1);
|
||||||
return (1);
|
else
|
||||||
else
|
return (0);
|
||||||
return (0);
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
elferr = elf_errno();
|
elferr = elf_errno();
|
||||||
if (elferr != 0)
|
if (elferr != 0)
|
||||||
@ -314,18 +311,18 @@ insert_to_sec_list(struct elfcopy *ecp, struct section *sec, int tail)
|
|||||||
{
|
{
|
||||||
struct section *s;
|
struct section *s;
|
||||||
|
|
||||||
if (!tail) {
|
if (tail || TAILQ_EMPTY(&ecp->v_sec) ||
|
||||||
|
TAILQ_LAST(&ecp->v_sec, sectionlist)->off <= sec->off) {
|
||||||
|
TAILQ_INSERT_TAIL(&ecp->v_sec, sec, sec_list);
|
||||||
|
} else {
|
||||||
TAILQ_FOREACH(s, &ecp->v_sec, sec_list) {
|
TAILQ_FOREACH(s, &ecp->v_sec, sec_list) {
|
||||||
if (sec->off < s->off) {
|
if (sec->off < s->off) {
|
||||||
TAILQ_INSERT_BEFORE(s, sec, sec_list);
|
TAILQ_INSERT_BEFORE(s, sec, sec_list);
|
||||||
goto inc_nos;
|
break;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
TAILQ_INSERT_TAIL(&ecp->v_sec, sec, sec_list);
|
|
||||||
|
|
||||||
inc_nos:
|
|
||||||
if (sec->pseudo == 0)
|
if (sec->pseudo == 0)
|
||||||
ecp->nos++;
|
ecp->nos++;
|
||||||
}
|
}
|
||||||
@ -711,13 +708,13 @@ filter_reloc(struct elfcopy *ecp, struct section *s)
|
|||||||
#define COPYREL(REL, SZ) do { \
|
#define COPYREL(REL, SZ) do { \
|
||||||
if (nrels == 0) { \
|
if (nrels == 0) { \
|
||||||
if ((REL##SZ = malloc(cap * \
|
if ((REL##SZ = malloc(cap * \
|
||||||
sizeof(Elf##SZ##_Rel))) == NULL) \
|
sizeof(*REL##SZ))) == NULL) \
|
||||||
err(EXIT_FAILURE, "malloc failed"); \
|
err(EXIT_FAILURE, "malloc failed"); \
|
||||||
} \
|
} \
|
||||||
if (nrels >= cap) { \
|
if (nrels >= cap) { \
|
||||||
cap *= 2; \
|
cap *= 2; \
|
||||||
if ((REL##SZ = realloc(REL##SZ, cap * \
|
if ((REL##SZ = realloc(REL##SZ, cap * \
|
||||||
sizeof(Elf##SZ##_Rel))) == NULL) \
|
sizeof(*REL##SZ))) == NULL) \
|
||||||
err(EXIT_FAILURE, "realloc failed"); \
|
err(EXIT_FAILURE, "realloc failed"); \
|
||||||
} \
|
} \
|
||||||
REL##SZ[nrels].r_offset = REL.r_offset; \
|
REL##SZ[nrels].r_offset = REL.r_offset; \
|
||||||
@ -1335,10 +1332,9 @@ insert_sections(struct elfcopy *ecp)
|
|||||||
void
|
void
|
||||||
add_to_shstrtab(struct elfcopy *ecp, const char *name)
|
add_to_shstrtab(struct elfcopy *ecp, const char *name)
|
||||||
{
|
{
|
||||||
struct section *s;
|
|
||||||
|
|
||||||
s = ecp->shstrtab;
|
if (elftc_string_table_insert(ecp->shstrtab->strtab, name) == 0)
|
||||||
insert_to_strtab(s, name);
|
errx(EXIT_FAILURE, "elftc_string_table_insert failed");
|
||||||
}
|
}
|
||||||
|
|
||||||
void
|
void
|
||||||
@ -1348,6 +1344,9 @@ update_shdr(struct elfcopy *ecp, int update_link)
|
|||||||
GElf_Shdr osh;
|
GElf_Shdr osh;
|
||||||
int elferr;
|
int elferr;
|
||||||
|
|
||||||
|
/* Finalize the section name string table (.shstrtab). */
|
||||||
|
set_shstrtab(ecp);
|
||||||
|
|
||||||
TAILQ_FOREACH(s, &ecp->v_sec, sec_list) {
|
TAILQ_FOREACH(s, &ecp->v_sec, sec_list) {
|
||||||
if (s->pseudo)
|
if (s->pseudo)
|
||||||
continue;
|
continue;
|
||||||
@ -1357,7 +1356,8 @@ update_shdr(struct elfcopy *ecp, int update_link)
|
|||||||
elf_errmsg(-1));
|
elf_errmsg(-1));
|
||||||
|
|
||||||
/* Find section name in string table and set sh_name. */
|
/* Find section name in string table and set sh_name. */
|
||||||
osh.sh_name = lookup_string(ecp->shstrtab, s->name);
|
osh.sh_name = elftc_string_table_lookup(ecp->shstrtab->strtab,
|
||||||
|
s->name);
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* sh_link needs to be updated, since the index of the
|
* sh_link needs to be updated, since the index of the
|
||||||
@ -1395,7 +1395,23 @@ update_shdr(struct elfcopy *ecp, int update_link)
|
|||||||
void
|
void
|
||||||
init_shstrtab(struct elfcopy *ecp)
|
init_shstrtab(struct elfcopy *ecp)
|
||||||
{
|
{
|
||||||
|
Elf_Scn *shstrtab;
|
||||||
|
GElf_Shdr shdr;
|
||||||
struct section *s;
|
struct section *s;
|
||||||
|
size_t indx, sizehint;
|
||||||
|
|
||||||
|
if (elf_getshstrndx(ecp->ein, &indx) != 0) {
|
||||||
|
shstrtab = elf_getscn(ecp->ein, indx);
|
||||||
|
if (shstrtab == NULL)
|
||||||
|
errx(EXIT_FAILURE, "elf_getscn failed: %s",
|
||||||
|
elf_errmsg(-1));
|
||||||
|
if (gelf_getshdr(shstrtab, &shdr) != &shdr)
|
||||||
|
errx(EXIT_FAILURE, "gelf_getshdr failed: %s",
|
||||||
|
elf_errmsg(-1));
|
||||||
|
sizehint = shdr.sh_size;
|
||||||
|
} else {
|
||||||
|
sizehint = 0;
|
||||||
|
}
|
||||||
|
|
||||||
if ((ecp->shstrtab = calloc(1, sizeof(*ecp->shstrtab))) == NULL)
|
if ((ecp->shstrtab = calloc(1, sizeof(*ecp->shstrtab))) == NULL)
|
||||||
err(EXIT_FAILURE, "calloc failed");
|
err(EXIT_FAILURE, "calloc failed");
|
||||||
@ -1407,19 +1423,22 @@ init_shstrtab(struct elfcopy *ecp)
|
|||||||
s->loadable = 0;
|
s->loadable = 0;
|
||||||
s->type = SHT_STRTAB;
|
s->type = SHT_STRTAB;
|
||||||
s->vma = 0;
|
s->vma = 0;
|
||||||
|
s->strtab = elftc_string_table_create(sizehint);
|
||||||
|
|
||||||
insert_to_strtab(s, "");
|
add_to_shstrtab(ecp, "");
|
||||||
insert_to_strtab(s, ".symtab");
|
add_to_shstrtab(ecp, ".symtab");
|
||||||
insert_to_strtab(s, ".strtab");
|
add_to_shstrtab(ecp, ".strtab");
|
||||||
insert_to_strtab(s, ".shstrtab");
|
add_to_shstrtab(ecp, ".shstrtab");
|
||||||
}
|
}
|
||||||
|
|
||||||
void
|
static void
|
||||||
set_shstrtab(struct elfcopy *ecp)
|
set_shstrtab(struct elfcopy *ecp)
|
||||||
{
|
{
|
||||||
struct section *s;
|
struct section *s;
|
||||||
Elf_Data *data;
|
Elf_Data *data;
|
||||||
GElf_Shdr sh;
|
GElf_Shdr sh;
|
||||||
|
const char *image;
|
||||||
|
size_t sz;
|
||||||
|
|
||||||
s = ecp->shstrtab;
|
s = ecp->shstrtab;
|
||||||
|
|
||||||
@ -1452,19 +1471,21 @@ set_shstrtab(struct elfcopy *ecp)
|
|||||||
* which are reserved for this in the beginning of shstrtab.
|
* which are reserved for this in the beginning of shstrtab.
|
||||||
*/
|
*/
|
||||||
if (!(ecp->flags & SYMTAB_EXIST)) {
|
if (!(ecp->flags & SYMTAB_EXIST)) {
|
||||||
s->sz -= sizeof(".symtab\0.strtab");
|
elftc_string_table_remove(s->strtab, ".symtab");
|
||||||
memmove(s->buf, (char *)s->buf + sizeof(".symtab\0.strtab"),
|
elftc_string_table_remove(s->strtab, ".strtab");
|
||||||
s->sz);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
sh.sh_size = s->sz;
|
image = elftc_string_table_image(s->strtab, &sz);
|
||||||
|
s->sz = sz;
|
||||||
|
|
||||||
|
sh.sh_size = sz;
|
||||||
if (!gelf_update_shdr(s->os, &sh))
|
if (!gelf_update_shdr(s->os, &sh))
|
||||||
errx(EXIT_FAILURE, "gelf_update_shdr() failed: %s",
|
errx(EXIT_FAILURE, "gelf_update_shdr() failed: %s",
|
||||||
elf_errmsg(-1));
|
elf_errmsg(-1));
|
||||||
|
|
||||||
data->d_align = 1;
|
data->d_align = 1;
|
||||||
data->d_buf = s->buf;
|
data->d_buf = (void *)(uintptr_t)image;
|
||||||
data->d_size = s->sz;
|
data->d_size = sz;
|
||||||
data->d_off = 0;
|
data->d_off = 0;
|
||||||
data->d_type = ELF_T_BYTE;
|
data->d_type = ELF_T_BYTE;
|
||||||
data->d_version = EV_CURRENT;
|
data->d_version = EV_CURRENT;
|
||||||
@ -1590,73 +1611,6 @@ add_gnu_debuglink(struct elfcopy *ecp)
|
|||||||
ecp->flags |= SEC_ADD;
|
ecp->flags |= SEC_ADD;
|
||||||
}
|
}
|
||||||
|
|
||||||
static void
|
|
||||||
insert_to_strtab(struct section *t, const char *s)
|
|
||||||
{
|
|
||||||
const char *r;
|
|
||||||
char *b, *c;
|
|
||||||
size_t len, slen;
|
|
||||||
int append;
|
|
||||||
|
|
||||||
if (t->sz == 0) {
|
|
||||||
t->cap = 512;
|
|
||||||
if ((t->buf = malloc(t->cap)) == NULL)
|
|
||||||
err(EXIT_FAILURE, "malloc failed");
|
|
||||||
}
|
|
||||||
|
|
||||||
slen = strlen(s);
|
|
||||||
append = 0;
|
|
||||||
b = t->buf;
|
|
||||||
for (c = b; c < b + t->sz;) {
|
|
||||||
len = strlen(c);
|
|
||||||
if (!append && len >= slen) {
|
|
||||||
r = c + (len - slen);
|
|
||||||
if (strcmp(r, s) == 0)
|
|
||||||
return;
|
|
||||||
} else if (len < slen && len != 0) {
|
|
||||||
r = s + (slen - len);
|
|
||||||
if (strcmp(c, r) == 0) {
|
|
||||||
t->sz -= len + 1;
|
|
||||||
memmove(c, c + len + 1, t->sz - (c - b));
|
|
||||||
append = 1;
|
|
||||||
continue;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
c += len + 1;
|
|
||||||
}
|
|
||||||
|
|
||||||
while (t->sz + slen + 1 >= t->cap) {
|
|
||||||
t->cap *= 2;
|
|
||||||
if ((t->buf = realloc(t->buf, t->cap)) == NULL)
|
|
||||||
err(EXIT_FAILURE, "realloc failed");
|
|
||||||
}
|
|
||||||
b = t->buf;
|
|
||||||
strncpy(&b[t->sz], s, slen);
|
|
||||||
b[t->sz + slen] = '\0';
|
|
||||||
t->sz += slen + 1;
|
|
||||||
}
|
|
||||||
|
|
||||||
static int
|
|
||||||
lookup_string(struct section *t, const char *s)
|
|
||||||
{
|
|
||||||
const char *b, *c, *r;
|
|
||||||
size_t len, slen;
|
|
||||||
|
|
||||||
slen = strlen(s);
|
|
||||||
b = t->buf;
|
|
||||||
for (c = b; c < b + t->sz;) {
|
|
||||||
len = strlen(c);
|
|
||||||
if (len >= slen) {
|
|
||||||
r = c + (len - slen);
|
|
||||||
if (strcmp(r, s) == 0)
|
|
||||||
return (r - b);
|
|
||||||
}
|
|
||||||
c += len + 1;
|
|
||||||
}
|
|
||||||
|
|
||||||
return (-1);
|
|
||||||
}
|
|
||||||
|
|
||||||
static uint32_t crctable[256] =
|
static uint32_t crctable[256] =
|
||||||
{
|
{
|
||||||
0x00000000L, 0x77073096L, 0xEE0E612CL, 0x990951BAL,
|
0x00000000L, 0x77073096L, 0xEE0E612CL, 0x990951BAL,
|
||||||
|
@ -50,7 +50,7 @@
|
|||||||
|
|
||||||
#include "_elftc.h"
|
#include "_elftc.h"
|
||||||
|
|
||||||
ELFTC_VCSID("$Id: elfdump.c 3584 2017-11-05 20:51:43Z jkoshy $");
|
ELFTC_VCSID("$Id: elfdump.c 3762 2019-06-28 21:06:24Z emaste $");
|
||||||
|
|
||||||
#if defined(ELFTC_NEED_ELF_NOTE_DEFINITION)
|
#if defined(ELFTC_NEED_ELF_NOTE_DEFINITION)
|
||||||
#include "native-elf-format.h"
|
#include "native-elf-format.h"
|
||||||
@ -343,17 +343,20 @@ elf_phdr_type_str(unsigned int type)
|
|||||||
static char s_type[32];
|
static char s_type[32];
|
||||||
|
|
||||||
switch (type) {
|
switch (type) {
|
||||||
case PT_NULL: return "PT_NULL";
|
case PT_NULL: return "PT_NULL";
|
||||||
case PT_LOAD: return "PT_LOAD";
|
case PT_LOAD: return "PT_LOAD";
|
||||||
case PT_DYNAMIC: return "PT_DYNAMIC";
|
case PT_DYNAMIC: return "PT_DYNAMIC";
|
||||||
case PT_INTERP: return "PT_INTERP";
|
case PT_INTERP: return "PT_INTERP";
|
||||||
case PT_NOTE: return "PT_NOTE";
|
case PT_NOTE: return "PT_NOTE";
|
||||||
case PT_SHLIB: return "PT_SHLIB";
|
case PT_SHLIB: return "PT_SHLIB";
|
||||||
case PT_PHDR: return "PT_PHDR";
|
case PT_PHDR: return "PT_PHDR";
|
||||||
case PT_TLS: return "PT_TLS";
|
case PT_TLS: return "PT_TLS";
|
||||||
case PT_GNU_EH_FRAME: return "PT_GNU_EH_FRAME";
|
case PT_GNU_EH_FRAME: return "PT_GNU_EH_FRAME";
|
||||||
case PT_GNU_STACK: return "PT_GNU_STACK";
|
case PT_GNU_STACK: return "PT_GNU_STACK";
|
||||||
case PT_GNU_RELRO: return "PT_GNU_RELRO";
|
case PT_GNU_RELRO: return "PT_GNU_RELRO";
|
||||||
|
case PT_OPENBSD_RANDOMIZE: return "PT_OPENBSD_RANDOMIZE";
|
||||||
|
case PT_OPENBSD_WXNEEDED: return "PT_OPENBSD_WXNEEDED";
|
||||||
|
case PT_OPENBSD_BOOTDATA: return "PT_OPENBSD_BOOTDATA";
|
||||||
}
|
}
|
||||||
snprintf(s_type, sizeof(s_type), "<unknown: %#x>", type);
|
snprintf(s_type, sizeof(s_type), "<unknown: %#x>", type);
|
||||||
return (s_type);
|
return (s_type);
|
||||||
|
@ -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: dwarf.h 3494 2016-09-20 17:16:13Z emaste $
|
* $Id: dwarf.h 3749 2019-06-28 01:10:44Z emaste $
|
||||||
*/
|
*/
|
||||||
|
|
||||||
#ifndef _DWARF_H_
|
#ifndef _DWARF_H_
|
||||||
@ -523,6 +523,24 @@
|
|||||||
#define DW_LANG_ObjC_plus_plus 0x0011
|
#define DW_LANG_ObjC_plus_plus 0x0011
|
||||||
#define DW_LANG_UPC 0x0012
|
#define DW_LANG_UPC 0x0012
|
||||||
#define DW_LANG_D 0x0013
|
#define DW_LANG_D 0x0013
|
||||||
|
#define DW_LANG_Python 0x0014
|
||||||
|
#define DW_LANG_OpenCL 0x0015
|
||||||
|
#define DW_LANG_Go 0x0016
|
||||||
|
#define DW_LANG_Modula3 0x0017
|
||||||
|
#define DW_LANG_Haskell 0x0018
|
||||||
|
#define DW_LANG_C_plus_plus_03 0x0019
|
||||||
|
#define DW_LANG_C_plus_plus_11 0x001a
|
||||||
|
#define DW_LANG_OCaml 0x001b
|
||||||
|
#define DW_LANG_Rust 0x001c
|
||||||
|
#define DW_LANG_C11 0x001d
|
||||||
|
#define DW_LANG_Swift 0x001e
|
||||||
|
#define DW_LANG_Julia 0x001f
|
||||||
|
#define DW_LANG_Dylan 0x0020
|
||||||
|
#define DW_LANG_C_plus_plus_14 0x0021
|
||||||
|
#define DW_LANG_Fortran03 0x0022
|
||||||
|
#define DW_LANG_Fortran08 0x0023
|
||||||
|
#define DW_LANG_RenderScript 0x0024
|
||||||
|
#define DW_LANG_BLISS 0x0025
|
||||||
#define DW_LANG_lo_user 0x8000
|
#define DW_LANG_lo_user 0x8000
|
||||||
#define DW_LANG_Mips_Assembler 0x8001
|
#define DW_LANG_Mips_Assembler 0x8001
|
||||||
#define DW_LANG_hi_user 0xffff
|
#define DW_LANG_hi_user 0xffff
|
||||||
|
@ -27,7 +27,7 @@
|
|||||||
|
|
||||||
#include "_libdwarf.h"
|
#include "_libdwarf.h"
|
||||||
|
|
||||||
ELFTC_VCSID("$Id: dwarf_dump.c 3494 2016-09-20 17:16:13Z emaste $");
|
ELFTC_VCSID("$Id: dwarf_dump.c 3749 2019-06-28 01:10:44Z emaste $");
|
||||||
|
|
||||||
int
|
int
|
||||||
dwarf_get_ACCESS_name(unsigned access, const char **s)
|
dwarf_get_ACCESS_name(unsigned access, const char **s)
|
||||||
@ -605,7 +605,7 @@ dwarf_get_DS_name(unsigned ds, const char **s)
|
|||||||
case DW_DS_leading_separate:
|
case DW_DS_leading_separate:
|
||||||
*s = "DW_DS_leading_separate"; break;
|
*s = "DW_DS_leading_separate"; break;
|
||||||
case DW_DS_trailing_separate:
|
case DW_DS_trailing_separate:
|
||||||
*s = "DW_DS_trailing_separate";
|
*s = "DW_DS_trailing_separate"; break;
|
||||||
default:
|
default:
|
||||||
return (DW_DLV_NO_ENTRY);
|
return (DW_DLV_NO_ENTRY);
|
||||||
}
|
}
|
||||||
@ -788,6 +788,42 @@ dwarf_get_LANG_name(unsigned lang, const char **s)
|
|||||||
*s = "DW_LANG_UPC"; break;
|
*s = "DW_LANG_UPC"; break;
|
||||||
case DW_LANG_D:
|
case DW_LANG_D:
|
||||||
*s = "DW_LANG_D"; break;
|
*s = "DW_LANG_D"; break;
|
||||||
|
case DW_LANG_Python:
|
||||||
|
*s = "DW_LANG_Python"; break;
|
||||||
|
case DW_LANG_OpenCL:
|
||||||
|
*s = "DW_LANG_OpenCL"; break;
|
||||||
|
case DW_LANG_Go:
|
||||||
|
*s = "DW_LANG_Go"; break;
|
||||||
|
case DW_LANG_Modula3:
|
||||||
|
*s = "DW_LANG_Modula3"; break;
|
||||||
|
case DW_LANG_Haskell:
|
||||||
|
*s = "DW_LANG_Haskell"; break;
|
||||||
|
case DW_LANG_C_plus_plus_03:
|
||||||
|
*s = "DW_LANG_C_plus_plus_03"; break;
|
||||||
|
case DW_LANG_C_plus_plus_11:
|
||||||
|
*s = "DW_LANG_C_plus_plus_11"; break;
|
||||||
|
case DW_LANG_OCaml:
|
||||||
|
*s = "DW_LANG_OCaml"; break;
|
||||||
|
case DW_LANG_Rust:
|
||||||
|
*s = "DW_LANG_Rust"; break;
|
||||||
|
case DW_LANG_C11:
|
||||||
|
*s = "DW_LANG_C11"; break;
|
||||||
|
case DW_LANG_Swift:
|
||||||
|
*s = "DW_LANG_Swift"; break;
|
||||||
|
case DW_LANG_Julia:
|
||||||
|
*s = "DW_LANG_Julia"; break;
|
||||||
|
case DW_LANG_Dylan:
|
||||||
|
*s = "DW_LANG_Dylan"; break;
|
||||||
|
case DW_LANG_C_plus_plus_14:
|
||||||
|
*s = "DW_LANG_C_plus_plus_14"; break;
|
||||||
|
case DW_LANG_Fortran03:
|
||||||
|
*s = "DW_LANG_Fortran03"; break;
|
||||||
|
case DW_LANG_Fortran08:
|
||||||
|
*s = "DW_LANG_Fortran08"; break;
|
||||||
|
case DW_LANG_RenderScript:
|
||||||
|
*s = "DW_LANG_RenderScript"; break;
|
||||||
|
case DW_LANG_BLISS:
|
||||||
|
*s = "DW_LANG_BLISS"; break;
|
||||||
case DW_LANG_lo_user:
|
case DW_LANG_lo_user:
|
||||||
*s = "DW_LANG_lo_user"; break;
|
*s = "DW_LANG_lo_user"; break;
|
||||||
case DW_LANG_Mips_Assembler:
|
case DW_LANG_Mips_Assembler:
|
||||||
|
@ -27,7 +27,7 @@
|
|||||||
|
|
||||||
#include "_libdwarf.h"
|
#include "_libdwarf.h"
|
||||||
|
|
||||||
ELFTC_VCSID("$Id: libdwarf_attr.c 3064 2014-06-06 19:35:55Z kaiwang27 $");
|
ELFTC_VCSID("$Id: libdwarf_attr.c 3748 2019-06-28 01:11:13Z emaste $");
|
||||||
|
|
||||||
int
|
int
|
||||||
_dwarf_attr_alloc(Dwarf_Die die, Dwarf_Attribute *atp, Dwarf_Error *error)
|
_dwarf_attr_alloc(Dwarf_Die die, Dwarf_Attribute *atp, Dwarf_Error *error)
|
||||||
@ -100,7 +100,6 @@ _dwarf_attr_init(Dwarf_Debug dbg, Dwarf_Section *ds, uint64_t *offsetp,
|
|||||||
uint64_t form, int indirect, Dwarf_Error *error)
|
uint64_t form, int indirect, Dwarf_Error *error)
|
||||||
{
|
{
|
||||||
struct _Dwarf_Attribute atref;
|
struct _Dwarf_Attribute atref;
|
||||||
Dwarf_Section *str;
|
|
||||||
int ret;
|
int ret;
|
||||||
|
|
||||||
ret = DW_DLE_NONE;
|
ret = DW_DLE_NONE;
|
||||||
@ -183,9 +182,7 @@ _dwarf_attr_init(Dwarf_Debug dbg, Dwarf_Section *ds, uint64_t *offsetp,
|
|||||||
break;
|
break;
|
||||||
case DW_FORM_strp:
|
case DW_FORM_strp:
|
||||||
atref.u[0].u64 = dbg->read(ds->ds_data, offsetp, dwarf_size);
|
atref.u[0].u64 = dbg->read(ds->ds_data, offsetp, dwarf_size);
|
||||||
str = _dwarf_find_section(dbg, ".debug_str");
|
atref.u[1].s = _dwarf_strtab_get_table(dbg) + atref.u[0].u64;
|
||||||
assert(str != NULL);
|
|
||||||
atref.u[1].s = (char *) str->ds_data + atref.u[0].u64;
|
|
||||||
break;
|
break;
|
||||||
case DW_FORM_ref_sig8:
|
case DW_FORM_ref_sig8:
|
||||||
atref.u[0].u64 = 8;
|
atref.u[0].u64 = 8;
|
||||||
|
@ -26,7 +26,7 @@
|
|||||||
|
|
||||||
#include "_libdwarf.h"
|
#include "_libdwarf.h"
|
||||||
|
|
||||||
ELFTC_VCSID("$Id: libdwarf_reloc.c 3578 2017-09-14 02:21:28Z emaste $");
|
ELFTC_VCSID("$Id: libdwarf_reloc.c 3741 2019-06-07 06:32:01Z jkoshy $");
|
||||||
|
|
||||||
Dwarf_Unsigned
|
Dwarf_Unsigned
|
||||||
_dwarf_get_reloc_type(Dwarf_P_Debug dbg, int is64)
|
_dwarf_get_reloc_type(Dwarf_P_Debug dbg, int is64)
|
||||||
@ -44,7 +44,7 @@ _dwarf_get_reloc_type(Dwarf_P_Debug dbg, int is64)
|
|||||||
case DW_ISA_SPARC:
|
case DW_ISA_SPARC:
|
||||||
return (is64 ? R_SPARC_UA64 : R_SPARC_UA32);
|
return (is64 ? R_SPARC_UA64 : R_SPARC_UA32);
|
||||||
case DW_ISA_PPC:
|
case DW_ISA_PPC:
|
||||||
return (R_PPC_ADDR32);
|
return (is64 ? R_PPC64_ADDR64 : R_PPC_ADDR32);
|
||||||
case DW_ISA_ARM:
|
case DW_ISA_ARM:
|
||||||
return (R_ARM_ABS32);
|
return (R_ARM_ABS32);
|
||||||
case DW_ISA_MIPS:
|
case DW_ISA_MIPS:
|
||||||
@ -97,6 +97,12 @@ _dwarf_get_reloc_size(Dwarf_Debug dbg, Dwarf_Unsigned rel_type)
|
|||||||
if (rel_type == R_PPC_ADDR32)
|
if (rel_type == R_PPC_ADDR32)
|
||||||
return (4);
|
return (4);
|
||||||
break;
|
break;
|
||||||
|
case EM_PPC64:
|
||||||
|
if (rel_type == R_PPC_ADDR32)
|
||||||
|
return (4);
|
||||||
|
else if (rel_type == R_PPC64_ADDR64)
|
||||||
|
return (8);
|
||||||
|
break;
|
||||||
case EM_MIPS:
|
case EM_MIPS:
|
||||||
if (rel_type == R_MIPS_32)
|
if (rel_type == R_MIPS_32)
|
||||||
return (4);
|
return (4);
|
||||||
|
@ -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.h 3632 2018-10-10 21:12:43Z jkoshy $
|
* $Id: _libelf.h 3738 2019-05-05 21:49:06Z jkoshy $
|
||||||
*/
|
*/
|
||||||
|
|
||||||
#ifndef __LIBELF_H_
|
#ifndef __LIBELF_H_
|
||||||
@ -90,7 +90,7 @@ struct _Elf {
|
|||||||
Elf_Kind e_kind; /* ELF_K_* */
|
Elf_Kind e_kind; /* ELF_K_* */
|
||||||
Elf *e_parent; /* non-NULL for archive members */
|
Elf *e_parent; /* non-NULL for archive members */
|
||||||
unsigned char *e_rawfile; /* uninterpreted bytes */
|
unsigned char *e_rawfile; /* uninterpreted bytes */
|
||||||
size_t e_rawsize; /* size of uninterpreted bytes */
|
off_t e_rawsize; /* size of uninterpreted bytes */
|
||||||
unsigned int e_version; /* file version */
|
unsigned int e_version; /* file version */
|
||||||
|
|
||||||
/*
|
/*
|
||||||
@ -226,7 +226,7 @@ size_t _libelf_msize(Elf_Type _t, int _elfclass, unsigned int _version);
|
|||||||
void *_libelf_newphdr(Elf *_e, int _elfclass, size_t _count);
|
void *_libelf_newphdr(Elf *_e, int _elfclass, size_t _count);
|
||||||
Elf *_libelf_open_object(int _fd, Elf_Cmd _c, int _reporterror);
|
Elf *_libelf_open_object(int _fd, Elf_Cmd _c, int _reporterror);
|
||||||
struct _Libelf_Data *_libelf_release_data(struct _Libelf_Data *_d);
|
struct _Libelf_Data *_libelf_release_data(struct _Libelf_Data *_d);
|
||||||
Elf *_libelf_release_elf(Elf *_e);
|
void _libelf_release_elf(Elf *_e);
|
||||||
Elf_Scn *_libelf_release_scn(Elf_Scn *_s);
|
Elf_Scn *_libelf_release_scn(Elf_Scn *_s);
|
||||||
int _libelf_setphnum(Elf *_e, void *_eh, int _elfclass, size_t _phnum);
|
int _libelf_setphnum(Elf *_e, void *_eh, int _elfclass, size_t _phnum);
|
||||||
int _libelf_setshnum(Elf *_e, void *_eh, int _elfclass, size_t _shnum);
|
int _libelf_setshnum(Elf *_e, void *_eh, int _elfclass, size_t _shnum);
|
||||||
|
@ -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 3566 2017-08-31 02:28:40Z emaste $
|
* $Id: _libelf_config.h 3764 2019-06-28 21:44:46Z emaste $
|
||||||
*/
|
*/
|
||||||
|
|
||||||
#if defined(__APPLE__) || defined(__DragonFly__)
|
#if defined(__APPLE__) || defined(__DragonFly__)
|
||||||
@ -103,6 +103,12 @@
|
|||||||
#define LIBELF_BYTEORDER ELFDATA2LSB
|
#define LIBELF_BYTEORDER ELFDATA2LSB
|
||||||
#define LIBELF_CLASS ELFCLASS64
|
#define LIBELF_CLASS ELFCLASS64
|
||||||
|
|
||||||
|
#elif defined(__riscv64)
|
||||||
|
|
||||||
|
#define LIBELF_ARCH EM_RISCV
|
||||||
|
#define LIBELF_BYTEORDER ELFDATA2LSB
|
||||||
|
#define LIBELF_CLASS ELFCLASS64
|
||||||
|
|
||||||
#elif defined(__sparc__)
|
#elif defined(__sparc__)
|
||||||
|
|
||||||
#define LIBELF_ARCH EM_SPARCV9
|
#define LIBELF_ARCH EM_SPARCV9
|
||||||
|
54
libelf/elf.3
54
libelf/elf.3
@ -1,4 +1,4 @@
|
|||||||
.\" Copyright (c) 2006-2008,2011 Joseph Koshy. All rights reserved.
|
.\" Copyright (c) 2006-2008,2011,2019 Joseph Koshy. All rights reserved.
|
||||||
.\"
|
.\"
|
||||||
.\" Redistribution and use in source and binary forms, with or without
|
.\" Redistribution and use in source and binary forms, with or without
|
||||||
.\" modification, are permitted provided that the following conditions
|
.\" modification, are permitted provided that the following conditions
|
||||||
@ -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: elf.3 3643 2018-10-14 21:09:24Z jkoshy $
|
.\" $Id: elf.3 3743 2019-06-12 19:36:30Z jkoshy $
|
||||||
.\"
|
.\"
|
||||||
.Dd October 10, 2018
|
.Dd June 12, 2019
|
||||||
.Dt ELF 3
|
.Dt ELF 3
|
||||||
.Os
|
.Os
|
||||||
.Sh NAME
|
.Sh NAME
|
||||||
@ -266,36 +266,43 @@ The operating version for the data in this buffer.
|
|||||||
.El
|
.El
|
||||||
.Pp
|
.Pp
|
||||||
.Vt Elf_Data
|
.Vt Elf_Data
|
||||||
descriptors are usually associated with
|
descriptors are usually used in conjunction with
|
||||||
.Vt Elf_Scn
|
.Vt Elf_Scn
|
||||||
descriptors.
|
descriptors.
|
||||||
Existing data descriptors associated with an ELF section may be
|
|
||||||
structures are retrieved using the
|
|
||||||
.Fn elf_getdata
|
|
||||||
and
|
|
||||||
.Fn elf_rawdata
|
|
||||||
functions.
|
|
||||||
The
|
|
||||||
.Fn elf_newdata
|
|
||||||
function may be used to attach new data descriptors to an ELF section.
|
|
||||||
.It Vt Elf_Scn
|
.It Vt Elf_Scn
|
||||||
.Vt Elf_Scn
|
.Vt Elf_Scn
|
||||||
descriptors represent a section in an ELF object.
|
descriptors represent sections in an ELF object.
|
||||||
|
These descriptors are opaque and contain no application modifiable
|
||||||
|
fields.
|
||||||
.Pp
|
.Pp
|
||||||
They are retrieved using the
|
The
|
||||||
|
.Vt Elf_Scn
|
||||||
|
descriptor for a specific section in an ELF object can be
|
||||||
|
retrieved using the
|
||||||
.Fn elf_getscn
|
.Fn elf_getscn
|
||||||
function.
|
function.
|
||||||
An application may iterate through the existing sections of an ELF
|
The sections contained in an ELF object can be traversed using the
|
||||||
object using the
|
|
||||||
.Fn elf_nextscn
|
.Fn elf_nextscn
|
||||||
function.
|
function.
|
||||||
New sections may be allocated using the
|
New sections are allocated using the
|
||||||
.Fn elf_newscn
|
.Fn elf_newscn
|
||||||
function.
|
function.
|
||||||
.Pp
|
.Pp
|
||||||
The
|
The
|
||||||
.Vt Elf_Scn
|
.Vt Elf_Data
|
||||||
descriptor is opaque and contains no application modifiable fields.
|
descriptors associated with a given section can be retrieved
|
||||||
|
using the
|
||||||
|
.Fn elf_getdata
|
||||||
|
function.
|
||||||
|
New data descriptors can be added to a section
|
||||||
|
descriptor using the
|
||||||
|
.Fn elf_newdata
|
||||||
|
function.
|
||||||
|
The untranslated
|
||||||
|
.Dq file
|
||||||
|
representation of data in a section can be retrieved using the
|
||||||
|
.Fn elf_rawdata
|
||||||
|
function.
|
||||||
.El
|
.El
|
||||||
.Ss Supported Elf Types
|
.Ss Supported Elf Types
|
||||||
The following ELF datatypes are supported by the library.
|
The following ELF datatypes are supported by the library.
|
||||||
@ -608,8 +615,11 @@ descriptor itself.
|
|||||||
.Xr ar 5 ,
|
.Xr ar 5 ,
|
||||||
.Xr elf 5
|
.Xr elf 5
|
||||||
.Sh HISTORY
|
.Sh HISTORY
|
||||||
The original ELF(3) API was developed for Unix System V.
|
The original
|
||||||
The current implementation of the ELF(3) API appeared in
|
.Nm
|
||||||
|
API was developed for
|
||||||
|
.At V .
|
||||||
|
The current implementation of the API appeared in
|
||||||
.Fx 7.0 .
|
.Fx 7.0 .
|
||||||
.Sh AUTHORS
|
.Sh AUTHORS
|
||||||
The ELF library was written by
|
The ELF library was written by
|
||||||
|
@ -32,7 +32,7 @@
|
|||||||
|
|
||||||
#include "_libelf.h"
|
#include "_libelf.h"
|
||||||
|
|
||||||
ELFTC_VCSID("$Id: elf_data.c 3632 2018-10-10 21:12:43Z jkoshy $");
|
ELFTC_VCSID("$Id: elf_data.c 3732 2019-04-22 11:08:38Z jkoshy $");
|
||||||
|
|
||||||
Elf_Data *
|
Elf_Data *
|
||||||
elf_getdata(Elf_Scn *s, Elf_Data *ed)
|
elf_getdata(Elf_Scn *s, Elf_Data *ed)
|
||||||
@ -42,7 +42,7 @@ elf_getdata(Elf_Scn *s, Elf_Data *ed)
|
|||||||
int elfclass, elftype;
|
int elfclass, elftype;
|
||||||
size_t count, fsz, msz;
|
size_t count, fsz, msz;
|
||||||
struct _Libelf_Data *d;
|
struct _Libelf_Data *d;
|
||||||
uint64_t sh_align, sh_offset, sh_size;
|
uint64_t sh_align, sh_offset, sh_size, raw_size;
|
||||||
_libelf_translator_function *xlate;
|
_libelf_translator_function *xlate;
|
||||||
|
|
||||||
d = (struct _Libelf_Data *) ed;
|
d = (struct _Libelf_Data *) ed;
|
||||||
@ -59,7 +59,8 @@ elf_getdata(Elf_Scn *s, Elf_Data *ed)
|
|||||||
return (&d->d_data);
|
return (&d->d_data);
|
||||||
|
|
||||||
if (d != NULL)
|
if (d != NULL)
|
||||||
return (&STAILQ_NEXT(d, d_next)->d_data);
|
return (STAILQ_NEXT(d, d_next) ?
|
||||||
|
&STAILQ_NEXT(d, d_next)->d_data : NULL);
|
||||||
|
|
||||||
if (e->e_rawfile == NULL) {
|
if (e->e_rawfile == NULL) {
|
||||||
/*
|
/*
|
||||||
@ -91,9 +92,10 @@ elf_getdata(Elf_Scn *s, Elf_Data *ed)
|
|||||||
return (NULL);
|
return (NULL);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
raw_size = (uint64_t) e->e_rawsize;
|
||||||
if ((elftype = _libelf_xlate_shtype(sh_type)) < ELF_T_FIRST ||
|
if ((elftype = _libelf_xlate_shtype(sh_type)) < ELF_T_FIRST ||
|
||||||
elftype > ELF_T_LAST || (sh_type != SHT_NOBITS &&
|
elftype > ELF_T_LAST || (sh_type != SHT_NOBITS &&
|
||||||
(sh_offset > e->e_rawsize || sh_size > e->e_rawsize - sh_offset))) {
|
(sh_offset > raw_size || sh_size > raw_size - sh_offset))) {
|
||||||
LIBELF_SET_ERROR(SECTION, 0);
|
LIBELF_SET_ERROR(SECTION, 0);
|
||||||
return (NULL);
|
return (NULL);
|
||||||
}
|
}
|
||||||
@ -116,7 +118,8 @@ elf_getdata(Elf_Scn *s, Elf_Data *ed)
|
|||||||
|
|
||||||
count = (size_t) (sh_size / fsz);
|
count = (size_t) (sh_size / fsz);
|
||||||
|
|
||||||
msz = _libelf_msize(elftype, elfclass, e->e_version);
|
if ((msz = _libelf_msize(elftype, elfclass, e->e_version)) == 0)
|
||||||
|
return (NULL);
|
||||||
|
|
||||||
if (count > 0 && msz > SIZE_MAX / count) {
|
if (count > 0 && msz > SIZE_MAX / count) {
|
||||||
LIBELF_SET_ERROR(RANGE, 0);
|
LIBELF_SET_ERROR(RANGE, 0);
|
||||||
@ -215,7 +218,7 @@ elf_rawdata(Elf_Scn *s, Elf_Data *ed)
|
|||||||
int elf_class;
|
int elf_class;
|
||||||
uint32_t sh_type;
|
uint32_t sh_type;
|
||||||
struct _Libelf_Data *d;
|
struct _Libelf_Data *d;
|
||||||
uint64_t sh_align, sh_offset, sh_size;
|
uint64_t sh_align, sh_offset, sh_size, raw_size;
|
||||||
|
|
||||||
if (s == NULL || (e = s->s_elf) == NULL || e->e_rawfile == NULL) {
|
if (s == NULL || (e = s->s_elf) == NULL || e->e_rawfile == NULL) {
|
||||||
LIBELF_SET_ERROR(ARGUMENT, 0);
|
LIBELF_SET_ERROR(ARGUMENT, 0);
|
||||||
@ -253,8 +256,9 @@ elf_rawdata(Elf_Scn *s, Elf_Data *ed)
|
|||||||
return (NULL);
|
return (NULL);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
raw_size = (uint64_t) e->e_rawsize;
|
||||||
if (sh_type != SHT_NOBITS &&
|
if (sh_type != SHT_NOBITS &&
|
||||||
(sh_offset > e->e_rawsize || sh_size > e->e_rawsize - sh_offset)) {
|
(sh_offset > raw_size || sh_size > raw_size - sh_offset)) {
|
||||||
LIBELF_SET_ERROR(SECTION, 0);
|
LIBELF_SET_ERROR(SECTION, 0);
|
||||||
return (NULL);
|
return (NULL);
|
||||||
}
|
}
|
||||||
|
@ -34,7 +34,7 @@
|
|||||||
#include <sys/mman.h>
|
#include <sys/mman.h>
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
ELFTC_VCSID("$Id: elf_end.c 3174 2015-03-27 17:13:41Z emaste $");
|
ELFTC_VCSID("$Id: elf_end.c 3738 2019-05-05 21:49:06Z jkoshy $");
|
||||||
|
|
||||||
int
|
int
|
||||||
elf_end(Elf *e)
|
elf_end(Elf *e)
|
||||||
@ -81,14 +81,14 @@ elf_end(Elf *e)
|
|||||||
free(e->e_rawfile);
|
free(e->e_rawfile);
|
||||||
#if ELFTC_HAVE_MMAP
|
#if ELFTC_HAVE_MMAP
|
||||||
else if (e->e_flags & LIBELF_F_RAWFILE_MMAP)
|
else if (e->e_flags & LIBELF_F_RAWFILE_MMAP)
|
||||||
(void) munmap(e->e_rawfile, e->e_rawsize);
|
(void) munmap(e->e_rawfile, (size_t) e->e_rawsize);
|
||||||
#endif
|
#endif
|
||||||
}
|
}
|
||||||
|
|
||||||
sv = e;
|
sv = e;
|
||||||
if ((e = e->e_parent) != NULL)
|
if ((e = e->e_parent) != NULL)
|
||||||
e->e_u.e_ar.e_nchildren--;
|
e->e_u.e_ar.e_nchildren--;
|
||||||
sv = _libelf_release_elf(sv);
|
_libelf_release_elf(sv);
|
||||||
}
|
}
|
||||||
|
|
||||||
return (0);
|
return (0);
|
||||||
|
@ -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: elf_flagdata.3 3639 2018-10-14 14:07:02Z jkoshy $
|
.\" $Id: elf_flagdata.3 3743 2019-06-12 19:36:30Z jkoshy $
|
||||||
.\"
|
.\"
|
||||||
.Dd December 3, 2011
|
.Dd June 12, 2019
|
||||||
.Dt ELF_FLAGDATA 3
|
.Dt ELF_FLAGDATA 3
|
||||||
.Os
|
.Os
|
||||||
.Sh NAME
|
.Sh NAME
|
||||||
@ -34,7 +34,7 @@
|
|||||||
.Nm elf_flagphdr ,
|
.Nm elf_flagphdr ,
|
||||||
.Nm elf_flagscn ,
|
.Nm elf_flagscn ,
|
||||||
.Nm elf_flagshdr
|
.Nm elf_flagshdr
|
||||||
.Nd manipulate flags associated with ELF(3) data structures
|
.Nd manipulate flags associated with ELF data structures
|
||||||
.Sh LIBRARY
|
.Sh LIBRARY
|
||||||
.Lb libelf
|
.Lb libelf
|
||||||
.Sh SYNOPSIS
|
.Sh SYNOPSIS
|
||||||
@ -65,7 +65,9 @@ and
|
|||||||
.Ar scn
|
.Ar scn
|
||||||
denote the data structures whose flags need to be changed.
|
denote the data structures whose flags need to be changed.
|
||||||
These values should have been returned by prior calls to
|
These values should have been returned by prior calls to
|
||||||
functions in the ELF(3) API set:
|
functions in the
|
||||||
|
.Xr elf 3
|
||||||
|
API set:
|
||||||
.Bl -bullet -compact
|
.Bl -bullet -compact
|
||||||
.It
|
.It
|
||||||
Argument
|
Argument
|
||||||
@ -175,7 +177,9 @@ function and the
|
|||||||
.Dv ELF_F_ARCHIVE
|
.Dv ELF_F_ARCHIVE
|
||||||
and
|
and
|
||||||
.Dv ELF_F_ARCHIVE_SYSV
|
.Dv ELF_F_ARCHIVE_SYSV
|
||||||
flags are an extension to the ELF(3) API.
|
flags are an extension to the
|
||||||
|
.Xr elf 3
|
||||||
|
API.
|
||||||
.Sh ERRORS
|
.Sh ERRORS
|
||||||
These functions may fail with the following errors:
|
These functions may fail with the following errors:
|
||||||
.Bl -tag -width "[ELF_E_RESOURCE]"
|
.Bl -tag -width "[ELF_E_RESOURCE]"
|
||||||
|
@ -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: elf_getdata.3 3643 2018-10-14 21:09:24Z jkoshy $
|
.\" $Id: elf_getdata.3 3734 2019-04-22 14:10:49Z jkoshy $
|
||||||
.\"
|
.\"
|
||||||
.Dd January 26, 2011
|
.Dd April 22, 2019
|
||||||
.Dt ELF_GETDATA 3
|
.Dt ELF_GETDATA 3
|
||||||
.Os
|
.Os
|
||||||
.Sh NAME
|
.Sh NAME
|
||||||
@ -214,7 +214,12 @@ is incorrect.
|
|||||||
.It Bq Er ELF_E_UNIMPL
|
.It Bq Er ELF_E_UNIMPL
|
||||||
The section type associated with section
|
The section type associated with section
|
||||||
.Ar scn
|
.Ar scn
|
||||||
is currently unsupported by the library.
|
is not supported.
|
||||||
|
.It Bq Er ELF_E_VERSION
|
||||||
|
Section
|
||||||
|
.Ar scn
|
||||||
|
was associated with an ELF object with an unsupported
|
||||||
|
version.
|
||||||
.El
|
.El
|
||||||
.Sh SEE ALSO
|
.Sh SEE ALSO
|
||||||
.Xr elf 3 ,
|
.Xr elf 3 ,
|
||||||
|
@ -30,7 +30,7 @@
|
|||||||
|
|
||||||
#include "_libelf.h"
|
#include "_libelf.h"
|
||||||
|
|
||||||
ELFTC_VCSID("$Id: elf_getident.c 3174 2015-03-27 17:13:41Z emaste $");
|
ELFTC_VCSID("$Id: elf_getident.c 3712 2019-03-16 22:23:34Z jkoshy $");
|
||||||
|
|
||||||
char *
|
char *
|
||||||
elf_getident(Elf *e, size_t *sz)
|
elf_getident(Elf *e, size_t *sz)
|
||||||
@ -54,7 +54,7 @@ elf_getident(Elf *e, size_t *sz)
|
|||||||
else if (e->e_kind == ELF_K_ELF)
|
else if (e->e_kind == ELF_K_ELF)
|
||||||
*sz = EI_NIDENT;
|
*sz = EI_NIDENT;
|
||||||
else
|
else
|
||||||
*sz = e->e_rawsize;
|
*sz = (size_t) e->e_rawsize;
|
||||||
}
|
}
|
||||||
|
|
||||||
return ((char *) e->e_rawfile);
|
return ((char *) e->e_rawfile);
|
||||||
|
@ -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: elf_next.3 3639 2018-10-14 14:07:02Z jkoshy $
|
.\" $Id: elf_next.3 3698 2019-02-28 06:34:42Z jkoshy $
|
||||||
.\"
|
.\"
|
||||||
.Dd June 17, 2006
|
.Dd February 27, 2019
|
||||||
.Dt ELF_NEXT 3
|
.Dt ELF_NEXT 3
|
||||||
.Os
|
.Os
|
||||||
.Sh NAME
|
.Sh NAME
|
||||||
@ -88,6 +88,9 @@ Argument
|
|||||||
was not associated with a containing
|
was not associated with a containing
|
||||||
.Xr ar 1
|
.Xr ar 1
|
||||||
archive.
|
archive.
|
||||||
|
.It Bq Er ELF_E_ARGUMENT
|
||||||
|
An error was encountered while parsing the archive containing argument
|
||||||
|
.Ar elf .
|
||||||
.El
|
.El
|
||||||
.Sh SEE ALSO
|
.Sh SEE ALSO
|
||||||
.Xr elf 3 ,
|
.Xr elf 3 ,
|
||||||
|
@ -30,7 +30,7 @@
|
|||||||
|
|
||||||
#include "_libelf.h"
|
#include "_libelf.h"
|
||||||
|
|
||||||
ELFTC_VCSID("$Id: elf_next.c 3174 2015-03-27 17:13:41Z emaste $");
|
ELFTC_VCSID("$Id: elf_next.c 3710 2019-03-12 09:42:35Z jkoshy $");
|
||||||
|
|
||||||
Elf_Cmd
|
Elf_Cmd
|
||||||
elf_next(Elf *e)
|
elf_next(Elf *e)
|
||||||
@ -60,5 +60,19 @@ elf_next(Elf *e)
|
|||||||
parent->e_u.e_ar.e_next = (next >= (off_t) parent->e_rawsize) ?
|
parent->e_u.e_ar.e_next = (next >= (off_t) parent->e_rawsize) ?
|
||||||
(off_t) 0 : next;
|
(off_t) 0 : next;
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Return an error if the 'e_next' field falls outside the current
|
||||||
|
* file.
|
||||||
|
*
|
||||||
|
* This check is performed after updating the parent descriptor's
|
||||||
|
* 'e_next' field so that the next call to elf_begin(3) will terminate
|
||||||
|
* traversal of a too-small archive even if client code forgets to
|
||||||
|
* check the return value from elf_next(3).
|
||||||
|
*/
|
||||||
|
if (next > (off_t) parent->e_rawsize) {
|
||||||
|
LIBELF_SET_ERROR(ARGUMENT, 0);
|
||||||
|
return (ELF_C_NULL);
|
||||||
|
}
|
||||||
|
|
||||||
return (ELF_C_READ);
|
return (ELF_C_READ);
|
||||||
}
|
}
|
||||||
|
@ -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: elf_open.3 3643 2018-10-14 21:09:24Z jkoshy $
|
.\" $Id: elf_open.3 3743 2019-06-12 19:36:30Z jkoshy $
|
||||||
.\"
|
.\"
|
||||||
.Dd May 31, 2012
|
.Dd June 12, 2019
|
||||||
.Dt ELF_OPEN 3
|
.Dt ELF_OPEN 3
|
||||||
.Os
|
.Os
|
||||||
.Sh NAME
|
.Sh NAME
|
||||||
@ -43,7 +43,9 @@ The functions
|
|||||||
.Fn elf_open
|
.Fn elf_open
|
||||||
and
|
and
|
||||||
.Fn elf_openmemory
|
.Fn elf_openmemory
|
||||||
are extensions to the ELF(3) API, for the internal use of the
|
are extensions to the
|
||||||
|
.Xr elf 3
|
||||||
|
API, for the internal use of the
|
||||||
Elftoolchain project.
|
Elftoolchain project.
|
||||||
Portable applications should not use these functions.
|
Portable applications should not use these functions.
|
||||||
.Pp
|
.Pp
|
||||||
@ -71,7 +73,9 @@ specifies the size of the memory area in bytes.
|
|||||||
The function returns a pointer to a ELF descriptor if successful, or
|
The function returns a pointer to a ELF descriptor if successful, or
|
||||||
NULL if an error occurred.
|
NULL if an error occurred.
|
||||||
.Sh COMPATIBILITY
|
.Sh COMPATIBILITY
|
||||||
These functions are non-standard extensions to the ELF(3) API set.
|
These functions are non-standard extensions to the
|
||||||
|
.Xr elf 3
|
||||||
|
API set.
|
||||||
.Pp
|
.Pp
|
||||||
The behavior of these functions differs from their counterparts
|
The behavior of these functions differs from their counterparts
|
||||||
.Xr elf_begin 3
|
.Xr elf_begin 3
|
||||||
|
@ -29,16 +29,25 @@
|
|||||||
|
|
||||||
#include "_libelf.h"
|
#include "_libelf.h"
|
||||||
|
|
||||||
ELFTC_VCSID("$Id: elf_rand.c 3174 2015-03-27 17:13:41Z emaste $");
|
ELFTC_VCSID("$Id: elf_rand.c 3716 2019-03-18 22:01:01Z jkoshy $");
|
||||||
|
|
||||||
off_t
|
off_t
|
||||||
elf_rand(Elf *ar, off_t offset)
|
elf_rand(Elf *ar, off_t offset)
|
||||||
{
|
{
|
||||||
struct ar_hdr *arh;
|
struct ar_hdr *arh;
|
||||||
|
off_t offset_of_member;
|
||||||
|
|
||||||
if (ar == NULL || ar->e_kind != ELF_K_AR ||
|
if (ar == NULL || ar->e_kind != ELF_K_AR ||
|
||||||
(offset & 1) || offset < SARMAG ||
|
(offset & 1) || offset < SARMAG ||
|
||||||
(size_t) offset + sizeof(struct ar_hdr) >= ar->e_rawsize) {
|
offset >= ar->e_rawsize) {
|
||||||
|
LIBELF_SET_ERROR(ARGUMENT, 0);
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
offset_of_member = offset + (off_t) sizeof(struct ar_hdr);
|
||||||
|
|
||||||
|
if (offset_of_member <= 0 || /* Numeric overflow. */
|
||||||
|
offset_of_member >= ar->e_rawsize) {
|
||||||
LIBELF_SET_ERROR(ARGUMENT, 0);
|
LIBELF_SET_ERROR(ARGUMENT, 0);
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
@ -28,15 +28,13 @@
|
|||||||
|
|
||||||
#include "_libelf.h"
|
#include "_libelf.h"
|
||||||
|
|
||||||
ELFTC_VCSID("$Id: elf_rawfile.c 3174 2015-03-27 17:13:41Z emaste $");
|
ELFTC_VCSID("$Id: elf_rawfile.c 3712 2019-03-16 22:23:34Z jkoshy $");
|
||||||
|
|
||||||
char *
|
char *
|
||||||
elf_rawfile(Elf *e, size_t *sz)
|
elf_rawfile(Elf *e, size_t *sz)
|
||||||
{
|
{
|
||||||
size_t size;
|
|
||||||
unsigned char *ptr;
|
unsigned char *ptr;
|
||||||
|
|
||||||
size = e ? e->e_rawsize : 0;
|
|
||||||
ptr = NULL;
|
ptr = NULL;
|
||||||
|
|
||||||
if (e == NULL)
|
if (e == NULL)
|
||||||
@ -45,7 +43,7 @@ elf_rawfile(Elf *e, size_t *sz)
|
|||||||
LIBELF_SET_ERROR(SEQUENCE, 0);
|
LIBELF_SET_ERROR(SEQUENCE, 0);
|
||||||
|
|
||||||
if (sz)
|
if (sz)
|
||||||
*sz = size;
|
*sz = e ? (size_t) e->e_rawsize : 0;
|
||||||
|
|
||||||
return ((char *) ptr);
|
return ((char *) ptr);
|
||||||
}
|
}
|
||||||
|
@ -36,7 +36,7 @@
|
|||||||
|
|
||||||
#include "_libelf.h"
|
#include "_libelf.h"
|
||||||
|
|
||||||
ELFTC_VCSID("$Id: elf_scn.c 3632 2018-10-10 21:12:43Z jkoshy $");
|
ELFTC_VCSID("$Id: elf_scn.c 3712 2019-03-16 22:23:34Z jkoshy $");
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* Load an ELF section table and create a list of Elf_Scn structures.
|
* Load an ELF section table and create a list of Elf_Scn structures.
|
||||||
@ -58,10 +58,11 @@ _libelf_load_section_headers(Elf *e, void *ehdr)
|
|||||||
assert((e->e_flags & LIBELF_F_SHDRS_LOADED) == 0);
|
assert((e->e_flags & LIBELF_F_SHDRS_LOADED) == 0);
|
||||||
|
|
||||||
#define CHECK_EHDR(E,EH) do { \
|
#define CHECK_EHDR(E,EH) do { \
|
||||||
if (shoff > e->e_rawsize || \
|
uintmax_t rawsize = (uintmax_t) e->e_rawsize; \
|
||||||
|
if (shoff > (uintmax_t) e->e_rawsize || \
|
||||||
fsz != (EH)->e_shentsize || \
|
fsz != (EH)->e_shentsize || \
|
||||||
shnum > SIZE_MAX / fsz || \
|
shnum > SIZE_MAX / fsz || \
|
||||||
fsz * shnum > e->e_rawsize - shoff) { \
|
fsz * shnum > rawsize - shoff) { \
|
||||||
LIBELF_SET_ERROR(HEADER, 0); \
|
LIBELF_SET_ERROR(HEADER, 0); \
|
||||||
return (0); \
|
return (0); \
|
||||||
} \
|
} \
|
||||||
|
@ -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: elf_update.3 3639 2018-10-14 14:07:02Z jkoshy $
|
.\" $Id: elf_update.3 3734 2019-04-22 14:10:49Z jkoshy $
|
||||||
.\"
|
.\"
|
||||||
.Dd August 14, 2011
|
.Dd April 22, 2019
|
||||||
.Dt ELF_UPDATE 3
|
.Dt ELF_UPDATE 3
|
||||||
.Os
|
.Os
|
||||||
.Sh NAME
|
.Sh NAME
|
||||||
@ -345,6 +345,10 @@ operation was requested after a prior call to
|
|||||||
disassociated the ELF descriptor
|
disassociated the ELF descriptor
|
||||||
.Ar elf
|
.Ar elf
|
||||||
from its underlying file.
|
from its underlying file.
|
||||||
|
.It Bq Er ELF_E_UNIMPL
|
||||||
|
Argument
|
||||||
|
.Ar elf
|
||||||
|
contained a section with an unsupported ELF type.
|
||||||
.It Bq Er ELF_E_VERSION
|
.It Bq Er ELF_E_VERSION
|
||||||
Argument
|
Argument
|
||||||
.Ar elf
|
.Ar elf
|
||||||
|
@ -41,7 +41,7 @@
|
|||||||
#include <sys/mman.h>
|
#include <sys/mman.h>
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
ELFTC_VCSID("$Id: elf_update.c 3632 2018-10-10 21:12:43Z jkoshy $");
|
ELFTC_VCSID("$Id: elf_update.c 3763 2019-06-28 21:43:27Z emaste $");
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* Layout strategy:
|
* Layout strategy:
|
||||||
@ -142,7 +142,7 @@ _libelf_compute_section_extents(Elf *e, Elf_Scn *s, off_t rc)
|
|||||||
assert(sh_type != SHT_NULL && sh_type != SHT_NOBITS);
|
assert(sh_type != SHT_NULL && sh_type != SHT_NOBITS);
|
||||||
|
|
||||||
elftype = _libelf_xlate_shtype(sh_type);
|
elftype = _libelf_xlate_shtype(sh_type);
|
||||||
if (elftype > ELF_T_LAST) {
|
if (elftype < ELF_T_FIRST || elftype > ELF_T_LAST) {
|
||||||
LIBELF_SET_ERROR(SECTION, 0);
|
LIBELF_SET_ERROR(SECTION, 0);
|
||||||
return (0);
|
return (0);
|
||||||
}
|
}
|
||||||
@ -221,11 +221,17 @@ _libelf_compute_section_extents(Elf *e, Elf_Scn *s, off_t rc)
|
|||||||
return (0);
|
return (0);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/*
|
||||||
|
* The data buffer's ELF type, ELF class and ELF version
|
||||||
|
* should be supported.
|
||||||
|
*/
|
||||||
|
if ((msz = _libelf_msize(d->d_type, ec, e->e_version)) == 0)
|
||||||
|
return (0);
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* The buffer's size should be a multiple of the
|
* The buffer's size should be a multiple of the
|
||||||
* memory size of the underlying type.
|
* memory size of the underlying type.
|
||||||
*/
|
*/
|
||||||
msz = _libelf_msize(d->d_type, ec, e->e_version);
|
|
||||||
if (d->d_size % msz) {
|
if (d->d_size % msz) {
|
||||||
LIBELF_SET_ERROR(DATA, 0);
|
LIBELF_SET_ERROR(DATA, 0);
|
||||||
return (0);
|
return (0);
|
||||||
@ -800,7 +806,8 @@ _libelf_write_scn(Elf *e, unsigned char *nf, struct _Elf_Extent *ex)
|
|||||||
|
|
||||||
d = &ld->d_data;
|
d = &ld->d_data;
|
||||||
|
|
||||||
msz = _libelf_msize(d->d_type, ec, e->e_version);
|
if ((msz = _libelf_msize(d->d_type, ec, e->e_version)) == 0)
|
||||||
|
return ((off_t) -1);
|
||||||
|
|
||||||
if ((uint64_t) rc < sh_off + d->d_off)
|
if ((uint64_t) rc < sh_off + d->d_off)
|
||||||
(void) memset(nf + rc,
|
(void) memset(nf + rc,
|
||||||
@ -812,6 +819,7 @@ _libelf_write_scn(Elf *e, unsigned char *nf, struct _Elf_Extent *ex)
|
|||||||
assert(d->d_buf != NULL);
|
assert(d->d_buf != NULL);
|
||||||
assert(d->d_version == e->e_version);
|
assert(d->d_version == e->e_version);
|
||||||
assert(d->d_size % msz == 0);
|
assert(d->d_size % msz == 0);
|
||||||
|
assert(msz != 0);
|
||||||
|
|
||||||
nobjects = (size_t) (d->d_size / msz);
|
nobjects = (size_t) (d->d_size / msz);
|
||||||
|
|
||||||
@ -851,7 +859,8 @@ _libelf_write_ehdr(Elf *e, unsigned char *nf, struct _Elf_Extent *ex)
|
|||||||
assert(ehdr != NULL);
|
assert(ehdr != NULL);
|
||||||
|
|
||||||
fsz = _libelf_fsize(ELF_T_EHDR, ec, e->e_version, (size_t) 1);
|
fsz = _libelf_fsize(ELF_T_EHDR, ec, e->e_version, (size_t) 1);
|
||||||
msz = _libelf_msize(ELF_T_EHDR, ec, e->e_version);
|
if ((msz = _libelf_msize(ELF_T_EHDR, ec, e->e_version)) == 0)
|
||||||
|
return ((off_t) -1);
|
||||||
|
|
||||||
em = _libelf_elfmachine(e);
|
em = _libelf_elfmachine(e);
|
||||||
|
|
||||||
@ -885,15 +894,17 @@ _libelf_write_phdr(Elf *e, unsigned char *nf, struct _Elf_Extent *ex)
|
|||||||
Elf32_Ehdr *eh32;
|
Elf32_Ehdr *eh32;
|
||||||
Elf64_Ehdr *eh64;
|
Elf64_Ehdr *eh64;
|
||||||
Elf_Data dst, src;
|
Elf_Data dst, src;
|
||||||
size_t fsz, phnum;
|
size_t fsz, msz, phnum;
|
||||||
uint64_t phoff;
|
uint64_t phoff;
|
||||||
|
|
||||||
assert(ex->ex_type == ELF_EXTENT_PHDR);
|
assert(ex->ex_type == ELF_EXTENT_PHDR);
|
||||||
|
|
||||||
ec = e->e_class;
|
ec = e->e_class;
|
||||||
ehdr = _libelf_ehdr(e, ec, 0);
|
|
||||||
phnum = e->e_u.e_elf.e_nphdr;
|
|
||||||
|
|
||||||
|
ehdr = _libelf_ehdr(e, ec, 0);
|
||||||
|
assert(ehdr != NULL);
|
||||||
|
|
||||||
|
phnum = e->e_u.e_elf.e_nphdr;
|
||||||
assert(phnum > 0);
|
assert(phnum > 0);
|
||||||
|
|
||||||
if (ec == ELFCLASS32) {
|
if (ec == ELFCLASS32) {
|
||||||
@ -913,14 +924,15 @@ _libelf_write_phdr(Elf *e, unsigned char *nf, struct _Elf_Extent *ex)
|
|||||||
(void) memset(&dst, 0, sizeof(dst));
|
(void) memset(&dst, 0, sizeof(dst));
|
||||||
(void) memset(&src, 0, sizeof(src));
|
(void) memset(&src, 0, sizeof(src));
|
||||||
|
|
||||||
|
if ((msz = _libelf_msize(ELF_T_PHDR, ec, e->e_version)) == 0)
|
||||||
|
return ((off_t) -1);
|
||||||
fsz = _libelf_fsize(ELF_T_PHDR, ec, e->e_version, phnum);
|
fsz = _libelf_fsize(ELF_T_PHDR, ec, e->e_version, phnum);
|
||||||
assert(fsz > 0);
|
assert(fsz > 0);
|
||||||
|
|
||||||
src.d_buf = _libelf_getphdr(e, ec);
|
src.d_buf = _libelf_getphdr(e, ec);
|
||||||
src.d_version = dst.d_version = e->e_version;
|
src.d_version = dst.d_version = e->e_version;
|
||||||
src.d_type = ELF_T_PHDR;
|
src.d_type = ELF_T_PHDR;
|
||||||
src.d_size = phnum * _libelf_msize(ELF_T_PHDR, ec,
|
src.d_size = phnum * msz;
|
||||||
e->e_version);
|
|
||||||
|
|
||||||
dst.d_size = fsz;
|
dst.d_size = fsz;
|
||||||
dst.d_buf = nf + ex->ex_start;
|
dst.d_buf = nf + ex->ex_start;
|
||||||
@ -945,13 +957,16 @@ _libelf_write_shdr(Elf *e, unsigned char *nf, struct _Elf_Extent *ex)
|
|||||||
uint64_t shoff;
|
uint64_t shoff;
|
||||||
Elf32_Ehdr *eh32;
|
Elf32_Ehdr *eh32;
|
||||||
Elf64_Ehdr *eh64;
|
Elf64_Ehdr *eh64;
|
||||||
size_t fsz, nscn;
|
size_t fsz, msz, nscn;
|
||||||
Elf_Data dst, src;
|
Elf_Data dst, src;
|
||||||
|
|
||||||
assert(ex->ex_type == ELF_EXTENT_SHDR);
|
assert(ex->ex_type == ELF_EXTENT_SHDR);
|
||||||
|
|
||||||
ec = e->e_class;
|
ec = e->e_class;
|
||||||
|
|
||||||
ehdr = _libelf_ehdr(e, ec, 0);
|
ehdr = _libelf_ehdr(e, ec, 0);
|
||||||
|
assert(ehdr != NULL);
|
||||||
|
|
||||||
nscn = e->e_u.e_elf.e_nscn;
|
nscn = e->e_u.e_elf.e_nscn;
|
||||||
|
|
||||||
if (ec == ELFCLASS32) {
|
if (ec == ELFCLASS32) {
|
||||||
@ -971,8 +986,11 @@ _libelf_write_shdr(Elf *e, unsigned char *nf, struct _Elf_Extent *ex)
|
|||||||
(void) memset(&dst, 0, sizeof(dst));
|
(void) memset(&dst, 0, sizeof(dst));
|
||||||
(void) memset(&src, 0, sizeof(src));
|
(void) memset(&src, 0, sizeof(src));
|
||||||
|
|
||||||
|
if ((msz = _libelf_msize(ELF_T_SHDR, ec, e->e_version)) == 0)
|
||||||
|
return ((off_t) -1);
|
||||||
|
|
||||||
src.d_type = ELF_T_SHDR;
|
src.d_type = ELF_T_SHDR;
|
||||||
src.d_size = _libelf_msize(ELF_T_SHDR, ec, e->e_version);
|
src.d_size = msz;
|
||||||
src.d_version = dst.d_version = e->e_version;
|
src.d_version = dst.d_version = e->e_version;
|
||||||
|
|
||||||
fsz = _libelf_fsize(ELF_T_SHDR, ec, e->e_version, (size_t) 1);
|
fsz = _libelf_fsize(ELF_T_SHDR, ec, e->e_version, (size_t) 1);
|
||||||
@ -1084,7 +1102,7 @@ _libelf_write_elf(Elf *e, off_t newsize, struct _Elf_Extent_List *extents)
|
|||||||
if (e->e_flags & LIBELF_F_RAWFILE_MMAP) {
|
if (e->e_flags & LIBELF_F_RAWFILE_MMAP) {
|
||||||
assert(e->e_rawfile != NULL);
|
assert(e->e_rawfile != NULL);
|
||||||
assert(e->e_cmd == ELF_C_RDWR);
|
assert(e->e_cmd == ELF_C_RDWR);
|
||||||
if (munmap(e->e_rawfile, e->e_rawsize) < 0) {
|
if (munmap(e->e_rawfile, (size_t) e->e_rawsize) < 0) {
|
||||||
LIBELF_SET_ERROR(IO, errno);
|
LIBELF_SET_ERROR(IO, errno);
|
||||||
goto error;
|
goto error;
|
||||||
}
|
}
|
||||||
@ -1109,12 +1127,14 @@ _libelf_write_elf(Elf *e, off_t newsize, struct _Elf_Extent_List *extents)
|
|||||||
assert((e->e_flags & LIBELF_F_RAWFILE_MALLOC) ||
|
assert((e->e_flags & LIBELF_F_RAWFILE_MALLOC) ||
|
||||||
(e->e_flags & LIBELF_F_RAWFILE_MMAP));
|
(e->e_flags & LIBELF_F_RAWFILE_MMAP));
|
||||||
if (e->e_flags & LIBELF_F_RAWFILE_MALLOC) {
|
if (e->e_flags & LIBELF_F_RAWFILE_MALLOC) {
|
||||||
|
assert((e->e_flags & LIBELF_F_RAWFILE_MMAP) == 0);
|
||||||
free(e->e_rawfile);
|
free(e->e_rawfile);
|
||||||
e->e_rawfile = newfile;
|
e->e_rawfile = newfile;
|
||||||
newfile = NULL;
|
newfile = NULL;
|
||||||
}
|
}
|
||||||
#if ELFTC_HAVE_MMAP
|
#if ELFTC_HAVE_MMAP
|
||||||
else if (e->e_flags & LIBELF_F_RAWFILE_MMAP) {
|
else if (e->e_flags & LIBELF_F_RAWFILE_MMAP) {
|
||||||
|
assert((e->e_flags & LIBELF_F_RAWFILE_MALLOC) == 0);
|
||||||
if ((e->e_rawfile = mmap(NULL, (size_t) newsize,
|
if ((e->e_rawfile = mmap(NULL, (size_t) newsize,
|
||||||
PROT_READ, MAP_PRIVATE, e->e_fd, (off_t) 0)) ==
|
PROT_READ, MAP_PRIVATE, e->e_fd, (off_t) 0)) ==
|
||||||
MAP_FAILED) {
|
MAP_FAILED) {
|
||||||
@ -1125,7 +1145,7 @@ _libelf_write_elf(Elf *e, off_t newsize, struct _Elf_Extent_List *extents)
|
|||||||
#endif /* ELFTC_HAVE_MMAP */
|
#endif /* ELFTC_HAVE_MMAP */
|
||||||
|
|
||||||
/* Record the new size of the file. */
|
/* Record the new size of the file. */
|
||||||
e->e_rawsize = (size_t) newsize;
|
e->e_rawsize = newsize;
|
||||||
} else {
|
} else {
|
||||||
/* File opened in ELF_C_WRITE mode. */
|
/* File opened in ELF_C_WRITE mode. */
|
||||||
assert(e->e_rawfile == NULL);
|
assert(e->e_rawfile == NULL);
|
||||||
|
@ -21,13 +21,13 @@
|
|||||||
.\" 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: gelf.3 3643 2018-10-14 21:09:24Z jkoshy $
|
.\" $Id: gelf.3 3743 2019-06-12 19:36:30Z jkoshy $
|
||||||
.\"
|
.\"
|
||||||
.Dd September 1, 2006
|
.Dd June 12, 2019
|
||||||
.Dt GELF 3
|
.Dt GELF 3
|
||||||
.Os
|
.Os
|
||||||
.Sh NAME
|
.Sh NAME
|
||||||
.Nm GElf
|
.Nm gelf
|
||||||
.Nd class-independent API for ELF manipulation
|
.Nd class-independent API for ELF manipulation
|
||||||
.Sh LIBRARY
|
.Sh LIBRARY
|
||||||
.Lb libelf
|
.Lb libelf
|
||||||
@ -192,7 +192,10 @@ Copy back an ELF symbol table entry.
|
|||||||
.Xr elf 3 ,
|
.Xr elf 3 ,
|
||||||
.Xr elf 5
|
.Xr elf 5
|
||||||
.Sh HISTORY
|
.Sh HISTORY
|
||||||
The GELF(3) API first appeared in System V Release 4.
|
The
|
||||||
|
.Nm
|
||||||
|
API first appeared in
|
||||||
|
.At V.4 .
|
||||||
This implementation of the API first appeared in
|
This implementation of the API first appeared in
|
||||||
.Fx 7.0 .
|
.Fx 7.0 .
|
||||||
.Sh AUTHORS
|
.Sh AUTHORS
|
||||||
|
@ -31,7 +31,7 @@
|
|||||||
|
|
||||||
#include "_libelf.h"
|
#include "_libelf.h"
|
||||||
|
|
||||||
ELFTC_VCSID("$Id: gelf_cap.c 3177 2015-03-30 18:19:41Z emaste $");
|
ELFTC_VCSID("$Id: gelf_cap.c 3732 2019-04-22 11:08:38Z jkoshy $");
|
||||||
|
|
||||||
GElf_Cap *
|
GElf_Cap *
|
||||||
gelf_getcap(Elf_Data *ed, int ndx, GElf_Cap *dst)
|
gelf_getcap(Elf_Data *ed, int ndx, GElf_Cap *dst)
|
||||||
@ -67,9 +67,8 @@ gelf_getcap(Elf_Data *ed, int ndx, GElf_Cap *dst)
|
|||||||
return (NULL);
|
return (NULL);
|
||||||
}
|
}
|
||||||
|
|
||||||
msz = _libelf_msize(ELF_T_CAP, ec, e->e_version);
|
if ((msz = _libelf_msize(ELF_T_CAP, ec, e->e_version)) == 0)
|
||||||
|
return (NULL);
|
||||||
assert(msz > 0);
|
|
||||||
|
|
||||||
if (msz * (size_t) ndx >= d->d_data.d_size) {
|
if (msz * (size_t) ndx >= d->d_data.d_size) {
|
||||||
LIBELF_SET_ERROR(ARGUMENT, 0);
|
LIBELF_SET_ERROR(ARGUMENT, 0);
|
||||||
@ -127,8 +126,8 @@ gelf_update_cap(Elf_Data *ed, int ndx, GElf_Cap *gc)
|
|||||||
return (0);
|
return (0);
|
||||||
}
|
}
|
||||||
|
|
||||||
msz = _libelf_msize(ELF_T_CAP, ec, e->e_version);
|
if ((msz = _libelf_msize(ELF_T_CAP, ec, e->e_version)) == 0)
|
||||||
assert(msz > 0);
|
return (0);
|
||||||
|
|
||||||
if (msz * (size_t) ndx >= d->d_data.d_size) {
|
if (msz * (size_t) ndx >= d->d_data.d_size) {
|
||||||
LIBELF_SET_ERROR(ARGUMENT, 0);
|
LIBELF_SET_ERROR(ARGUMENT, 0);
|
||||||
|
@ -31,7 +31,7 @@
|
|||||||
|
|
||||||
#include "_libelf.h"
|
#include "_libelf.h"
|
||||||
|
|
||||||
ELFTC_VCSID("$Id: gelf_dyn.c 3177 2015-03-30 18:19:41Z emaste $");
|
ELFTC_VCSID("$Id: gelf_dyn.c 3732 2019-04-22 11:08:38Z jkoshy $");
|
||||||
|
|
||||||
GElf_Dyn *
|
GElf_Dyn *
|
||||||
gelf_getdyn(Elf_Data *ed, int ndx, GElf_Dyn *dst)
|
gelf_getdyn(Elf_Data *ed, int ndx, GElf_Dyn *dst)
|
||||||
@ -67,9 +67,9 @@ gelf_getdyn(Elf_Data *ed, int ndx, GElf_Dyn *dst)
|
|||||||
return (NULL);
|
return (NULL);
|
||||||
}
|
}
|
||||||
|
|
||||||
msz = _libelf_msize(ELF_T_DYN, ec, e->e_version);
|
if ((msz = _libelf_msize(ELF_T_DYN, ec, e->e_version)) == 0)
|
||||||
|
return (NULL);
|
||||||
|
|
||||||
assert(msz > 0);
|
|
||||||
assert(ndx >= 0);
|
assert(ndx >= 0);
|
||||||
|
|
||||||
if (msz * (size_t) ndx >= d->d_data.d_size) {
|
if (msz * (size_t) ndx >= d->d_data.d_size) {
|
||||||
@ -127,9 +127,9 @@ gelf_update_dyn(Elf_Data *ed, int ndx, GElf_Dyn *ds)
|
|||||||
return (0);
|
return (0);
|
||||||
}
|
}
|
||||||
|
|
||||||
msz = _libelf_msize(ELF_T_DYN, ec, e->e_version);
|
if ((msz = _libelf_msize(ELF_T_DYN, ec, e->e_version)) == 0)
|
||||||
|
return (0);
|
||||||
|
|
||||||
assert(msz > 0);
|
|
||||||
assert(ndx >= 0);
|
assert(ndx >= 0);
|
||||||
|
|
||||||
if (msz * (size_t) ndx >= d->d_data.d_size) {
|
if (msz * (size_t) ndx >= d->d_data.d_size) {
|
||||||
|
@ -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: gelf_getcap.3 3639 2018-10-14 14:07:02Z jkoshy $
|
.\" $Id: gelf_getcap.3 3734 2019-04-22 14:10:49Z jkoshy $
|
||||||
.\"
|
.\"
|
||||||
.Dd August 29, 2006
|
.Dd April 22, 2019
|
||||||
.Dt GELF_GETCAP 3
|
.Dt GELF_GETCAP 3
|
||||||
.Os
|
.Os
|
||||||
.Sh NAME
|
.Sh NAME
|
||||||
@ -113,6 +113,12 @@ was not associated with a section of type
|
|||||||
.Dv SHT_SUNW_cap .
|
.Dv SHT_SUNW_cap .
|
||||||
.It Bq Er ELF_E_RANGE
|
.It Bq Er ELF_E_RANGE
|
||||||
A value was not representable in the target type.
|
A value was not representable in the target type.
|
||||||
|
.It Bq Er ELF_E_VERSION
|
||||||
|
The
|
||||||
|
.Vt Elf_Data
|
||||||
|
descriptor denoted by argument
|
||||||
|
.Ar data
|
||||||
|
is associated with an ELF object with an unsupported version.
|
||||||
.El
|
.El
|
||||||
.Sh SEE ALSO
|
.Sh SEE ALSO
|
||||||
.Xr elf 3 ,
|
.Xr elf 3 ,
|
||||||
|
@ -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: gelf_getdyn.3 3639 2018-10-14 14:07:02Z jkoshy $
|
.\" $Id: gelf_getdyn.3 3734 2019-04-22 14:10:49Z jkoshy $
|
||||||
.\"
|
.\"
|
||||||
.Dd August 29, 2006
|
.Dd April 22, 2019
|
||||||
.Dt GELF_GETDYN 3
|
.Dt GELF_GETDYN 3
|
||||||
.Os
|
.Os
|
||||||
.Sh NAME
|
.Sh NAME
|
||||||
@ -115,6 +115,13 @@ was not associated with a section of type
|
|||||||
.Dv SHT_DYNAMIC .
|
.Dv SHT_DYNAMIC .
|
||||||
.It Bq Er ELF_E_RANGE
|
.It Bq Er ELF_E_RANGE
|
||||||
A value was not representable in the target type.
|
A value was not representable in the target type.
|
||||||
|
.It Bq Er ELF_E_VERSION
|
||||||
|
The
|
||||||
|
.Vt Elf_Data
|
||||||
|
descriptor denoted by argument
|
||||||
|
.Ar data
|
||||||
|
is associated with an ELF object with an unsupported version.
|
||||||
|
.El
|
||||||
.El
|
.El
|
||||||
.Sh SEE ALSO
|
.Sh SEE ALSO
|
||||||
.Xr elf 3 ,
|
.Xr elf 3 ,
|
||||||
|
@ -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: gelf_getmove.3 3639 2018-10-14 14:07:02Z jkoshy $
|
.\" $Id: gelf_getmove.3 3734 2019-04-22 14:10:49Z jkoshy $
|
||||||
.\"
|
.\"
|
||||||
.Dd August 29, 2006
|
.Dd April 22, 2019
|
||||||
.Dt GELF_GETMOVE 3
|
.Dt GELF_GETMOVE 3
|
||||||
.Os
|
.Os
|
||||||
.Sh NAME
|
.Sh NAME
|
||||||
@ -112,6 +112,12 @@ Data descriptor
|
|||||||
was not associated with a section containing move information.
|
was not associated with a section containing move information.
|
||||||
.It Bq Er ELF_E_RANGE
|
.It Bq Er ELF_E_RANGE
|
||||||
A value was not representable in the target type.
|
A value was not representable in the target type.
|
||||||
|
.It Bq Er ELF_E_VERSION
|
||||||
|
The
|
||||||
|
.Vt Elf_Data
|
||||||
|
descriptor denoted by argument
|
||||||
|
.Ar data
|
||||||
|
is associated with an ELF object with an unsupported version.
|
||||||
.El
|
.El
|
||||||
.Sh SEE ALSO
|
.Sh SEE ALSO
|
||||||
.Xr elf 3 ,
|
.Xr elf 3 ,
|
||||||
|
@ -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: gelf_getrel.3 3639 2018-10-14 14:07:02Z jkoshy $
|
.\" $Id: gelf_getrel.3 3734 2019-04-22 14:10:49Z jkoshy $
|
||||||
.\"
|
.\"
|
||||||
.Dd August 29, 2006
|
.Dd April 22, 2019
|
||||||
.Dt GELF_GETREL 3
|
.Dt GELF_GETREL 3
|
||||||
.Os
|
.Os
|
||||||
.Sh NAME
|
.Sh NAME
|
||||||
@ -113,6 +113,12 @@ was not associated with a section of type
|
|||||||
.Dv SHT_REL .
|
.Dv SHT_REL .
|
||||||
.It Bq Er ELF_E_RANGE
|
.It Bq Er ELF_E_RANGE
|
||||||
A value was not representable in the target type.
|
A value was not representable in the target type.
|
||||||
|
.It Bq Er ELF_E_VERSION
|
||||||
|
The
|
||||||
|
.Vt Elf_Data
|
||||||
|
descriptor denoted by argument
|
||||||
|
.Ar data
|
||||||
|
is associated with an ELF object with an unsupported version.
|
||||||
.El
|
.El
|
||||||
.Sh SEE ALSO
|
.Sh SEE ALSO
|
||||||
.Xr elf 3 ,
|
.Xr elf 3 ,
|
||||||
|
@ -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: gelf_getrela.3 3639 2018-10-14 14:07:02Z jkoshy $
|
.\" $Id: gelf_getrela.3 3734 2019-04-22 14:10:49Z jkoshy $
|
||||||
.\"
|
.\"
|
||||||
.Dd August 29, 2006
|
.Dd April 22, 2019
|
||||||
.Dt GELF_GETRELA 3
|
.Dt GELF_GETRELA 3
|
||||||
.Os
|
.Os
|
||||||
.Sh NAME
|
.Sh NAME
|
||||||
@ -113,6 +113,12 @@ was not associated with a section of type
|
|||||||
.Dv SHT_RELA .
|
.Dv SHT_RELA .
|
||||||
.It Bq Er ELF_E_RANGE
|
.It Bq Er ELF_E_RANGE
|
||||||
A value was not representable in the target type.
|
A value was not representable in the target type.
|
||||||
|
.It Bq Er ELF_E_VERSION
|
||||||
|
The
|
||||||
|
.Vt Elf_Data
|
||||||
|
descriptor denoted by argument
|
||||||
|
.Ar data
|
||||||
|
is associated with an ELF object with an unsupported version.
|
||||||
.El
|
.El
|
||||||
.Sh SEE ALSO
|
.Sh SEE ALSO
|
||||||
.Xr elf 3 ,
|
.Xr elf 3 ,
|
||||||
|
@ -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: gelf_getsym.3 3639 2018-10-14 14:07:02Z jkoshy $
|
.\" $Id: gelf_getsym.3 3734 2019-04-22 14:10:49Z jkoshy $
|
||||||
.\"
|
.\"
|
||||||
.Dd August 29, 2006
|
.Dd April 22, 2019
|
||||||
.Dt GELF_GETSYM 3
|
.Dt GELF_GETSYM 3
|
||||||
.Os
|
.Os
|
||||||
.Sh NAME
|
.Sh NAME
|
||||||
@ -115,6 +115,12 @@ Data descriptor
|
|||||||
was not associated with a section containing symbol information.
|
was not associated with a section containing symbol information.
|
||||||
.It Bq Er ELF_E_RANGE
|
.It Bq Er ELF_E_RANGE
|
||||||
A value was not representable in the target type.
|
A value was not representable in the target type.
|
||||||
|
.It Bq Er ELF_E_VERSION
|
||||||
|
The
|
||||||
|
.Vt Elf_Data
|
||||||
|
descriptor denoted by argument
|
||||||
|
.Ar data
|
||||||
|
is associated with an ELF object with an unsupported version.
|
||||||
.El
|
.El
|
||||||
.Sh SEE ALSO
|
.Sh SEE ALSO
|
||||||
.Xr elf 3 ,
|
.Xr elf 3 ,
|
||||||
|
@ -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: gelf_getsyminfo.3 3639 2018-10-14 14:07:02Z jkoshy $
|
.\" $Id: gelf_getsyminfo.3 3734 2019-04-22 14:10:49Z jkoshy $
|
||||||
.\"
|
.\"
|
||||||
.Dd August 29, 2006
|
.Dd April 22, 2019
|
||||||
.Dt GELF_GETSYMINFO 3
|
.Dt GELF_GETSYMINFO 3
|
||||||
.Os
|
.Os
|
||||||
.Sh NAME
|
.Sh NAME
|
||||||
@ -105,6 +105,12 @@ descriptor.
|
|||||||
Data descriptor
|
Data descriptor
|
||||||
.Ar data
|
.Ar data
|
||||||
was not associated with a section containing symbol information.
|
was not associated with a section containing symbol information.
|
||||||
|
.It Bq Er ELF_E_VERSION
|
||||||
|
The
|
||||||
|
.Vt Elf_Data
|
||||||
|
descriptor denoted by argument
|
||||||
|
.Ar data
|
||||||
|
is associated with an ELF object with an unsupported version.
|
||||||
.El
|
.El
|
||||||
.Sh SEE ALSO
|
.Sh SEE ALSO
|
||||||
.Xr elf 3 ,
|
.Xr elf 3 ,
|
||||||
|
@ -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: gelf_getsymshndx.3 3639 2018-10-14 14:07:02Z jkoshy $
|
.\" $Id: gelf_getsymshndx.3 3734 2019-04-22 14:10:49Z jkoshy $
|
||||||
.\"
|
.\"
|
||||||
.Dd November 5, 2006
|
.Dd April 22, 2019
|
||||||
.Dt GELF_GETSYMSHNDX 3
|
.Dt GELF_GETSYMSHNDX 3
|
||||||
.Os
|
.Os
|
||||||
.Sh NAME
|
.Sh NAME
|
||||||
@ -152,6 +152,14 @@ Data descriptor
|
|||||||
and
|
and
|
||||||
.Ar xndxdata
|
.Ar xndxdata
|
||||||
were associated with different ELF objects.
|
were associated with different ELF objects.
|
||||||
|
.It Bq Er ELF_E_VERSION
|
||||||
|
The
|
||||||
|
.Vt Elf_Data
|
||||||
|
descriptors denoted by arguments
|
||||||
|
.Ar symdata
|
||||||
|
and
|
||||||
|
.Ar xndxdata
|
||||||
|
are associated with an ELF object with an unsupported version.
|
||||||
.El
|
.El
|
||||||
.Sh SEE ALSO
|
.Sh SEE ALSO
|
||||||
.Xr elf 3 ,
|
.Xr elf 3 ,
|
||||||
|
@ -31,7 +31,7 @@
|
|||||||
|
|
||||||
#include "_libelf.h"
|
#include "_libelf.h"
|
||||||
|
|
||||||
ELFTC_VCSID("$Id: gelf_move.c 3177 2015-03-30 18:19:41Z emaste $");
|
ELFTC_VCSID("$Id: gelf_move.c 3732 2019-04-22 11:08:38Z jkoshy $");
|
||||||
|
|
||||||
GElf_Move *
|
GElf_Move *
|
||||||
gelf_getmove(Elf_Data *ed, int ndx, GElf_Move *dst)
|
gelf_getmove(Elf_Data *ed, int ndx, GElf_Move *dst)
|
||||||
@ -67,9 +67,9 @@ gelf_getmove(Elf_Data *ed, int ndx, GElf_Move *dst)
|
|||||||
return (NULL);
|
return (NULL);
|
||||||
}
|
}
|
||||||
|
|
||||||
msz = _libelf_msize(ELF_T_MOVE, ec, e->e_version);
|
if ((msz = _libelf_msize(ELF_T_MOVE, ec, e->e_version)) == 0)
|
||||||
|
return (NULL);
|
||||||
|
|
||||||
assert(msz > 0);
|
|
||||||
assert(ndx >= 0);
|
assert(ndx >= 0);
|
||||||
|
|
||||||
if (msz * (size_t) ndx >= d->d_data.d_size) {
|
if (msz * (size_t) ndx >= d->d_data.d_size) {
|
||||||
@ -130,9 +130,9 @@ gelf_update_move(Elf_Data *ed, int ndx, GElf_Move *gm)
|
|||||||
return (0);
|
return (0);
|
||||||
}
|
}
|
||||||
|
|
||||||
msz = _libelf_msize(ELF_T_MOVE, ec, e->e_version);
|
if ((msz = _libelf_msize(ELF_T_MOVE, ec, e->e_version)) == 0)
|
||||||
|
return (0);
|
||||||
|
|
||||||
assert(msz > 0);
|
|
||||||
assert(ndx >= 0);
|
assert(ndx >= 0);
|
||||||
|
|
||||||
if (msz * (size_t) ndx >= d->d_data.d_size) {
|
if (msz * (size_t) ndx >= d->d_data.d_size) {
|
||||||
|
@ -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: gelf_newehdr.3 3643 2018-10-14 21:09:24Z jkoshy $
|
.\" $Id: gelf_newehdr.3 3743 2019-06-12 19:36:30Z jkoshy $
|
||||||
.\"
|
.\"
|
||||||
.Dd October 22, 2007
|
.Dd June 12, 2019
|
||||||
.Dt GELF_NEWEHDR 3
|
.Dt GELF_NEWEHDR 3
|
||||||
.Os
|
.Os
|
||||||
.Sh NAME
|
.Sh NAME
|
||||||
@ -134,7 +134,9 @@ The
|
|||||||
function uses a type of
|
function uses a type of
|
||||||
.Ft "void *"
|
.Ft "void *"
|
||||||
for its returned value.
|
for its returned value.
|
||||||
This differs from some other implementations of the ELF(3) API, which use an
|
This differs from some other implementations of the
|
||||||
|
.Xr elf 3
|
||||||
|
API, which use an
|
||||||
.Ft "unsigned long"
|
.Ft "unsigned long"
|
||||||
return type.
|
return type.
|
||||||
.Sh ERRORS
|
.Sh ERRORS
|
||||||
|
@ -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: gelf_newphdr.3 3639 2018-10-14 14:07:02Z jkoshy $
|
.\" $Id: gelf_newphdr.3 3743 2019-06-12 19:36:30Z jkoshy $
|
||||||
.\"
|
.\"
|
||||||
.Dd October 22, 2007
|
.Dd June 12, 2019
|
||||||
.Dt GELF_NEWPHDR 3
|
.Dt GELF_NEWPHDR 3
|
||||||
.Os
|
.Os
|
||||||
.Sh NAME
|
.Sh NAME
|
||||||
@ -103,7 +103,9 @@ The
|
|||||||
function uses a type of
|
function uses a type of
|
||||||
.Ft "void *"
|
.Ft "void *"
|
||||||
for its returned value.
|
for its returned value.
|
||||||
This differs from some other implementations of the ELF(3) API, which use an
|
This differs from some other implementations of the
|
||||||
|
.Xr elf 3
|
||||||
|
API, which use an
|
||||||
.Ft "unsigned long"
|
.Ft "unsigned long"
|
||||||
return type.
|
return type.
|
||||||
.Sh ERRORS
|
.Sh ERRORS
|
||||||
|
@ -31,7 +31,7 @@
|
|||||||
|
|
||||||
#include "_libelf.h"
|
#include "_libelf.h"
|
||||||
|
|
||||||
ELFTC_VCSID("$Id: gelf_rel.c 3177 2015-03-30 18:19:41Z emaste $");
|
ELFTC_VCSID("$Id: gelf_rel.c 3739 2019-05-06 05:18:15Z jkoshy $");
|
||||||
|
|
||||||
GElf_Rel *
|
GElf_Rel *
|
||||||
gelf_getrel(Elf_Data *ed, int ndx, GElf_Rel *dst)
|
gelf_getrel(Elf_Data *ed, int ndx, GElf_Rel *dst)
|
||||||
@ -67,9 +67,9 @@ gelf_getrel(Elf_Data *ed, int ndx, GElf_Rel *dst)
|
|||||||
return (NULL);
|
return (NULL);
|
||||||
}
|
}
|
||||||
|
|
||||||
msz = _libelf_msize(ELF_T_REL, ec, e->e_version);
|
if ((msz = _libelf_msize(ELF_T_REL, ec, e->e_version)) == 0)
|
||||||
|
return (NULL);
|
||||||
|
|
||||||
assert(msz > 0);
|
|
||||||
assert(ndx >= 0);
|
assert(ndx >= 0);
|
||||||
|
|
||||||
if (msz * (size_t) ndx >= d->d_data.d_size) {
|
if (msz * (size_t) ndx >= d->d_data.d_size) {
|
||||||
@ -129,9 +129,9 @@ gelf_update_rel(Elf_Data *ed, int ndx, GElf_Rel *dr)
|
|||||||
return (0);
|
return (0);
|
||||||
}
|
}
|
||||||
|
|
||||||
msz = _libelf_msize(ELF_T_REL, ec, e->e_version);
|
if ((msz = _libelf_msize(ELF_T_REL, ec, e->e_version)) == 0)
|
||||||
|
return (0);
|
||||||
|
|
||||||
assert(msz > 0);
|
|
||||||
assert(ndx >= 0);
|
assert(ndx >= 0);
|
||||||
|
|
||||||
if (msz * (size_t) ndx >= d->d_data.d_size) {
|
if (msz * (size_t) ndx >= d->d_data.d_size) {
|
||||||
@ -144,7 +144,7 @@ gelf_update_rel(Elf_Data *ed, int ndx, GElf_Rel *dr)
|
|||||||
|
|
||||||
LIBELF_COPY_U32(rel32, dr, r_offset);
|
LIBELF_COPY_U32(rel32, dr, r_offset);
|
||||||
|
|
||||||
if (ELF64_R_SYM(dr->r_info) > ELF32_R_SYM(~0UL) ||
|
if (ELF64_R_SYM(dr->r_info) > ELF32_R_SYM(~0U) ||
|
||||||
ELF64_R_TYPE(dr->r_info) > ELF32_R_TYPE(~0U)) {
|
ELF64_R_TYPE(dr->r_info) > ELF32_R_TYPE(~0U)) {
|
||||||
LIBELF_SET_ERROR(RANGE, 0);
|
LIBELF_SET_ERROR(RANGE, 0);
|
||||||
return (0);
|
return (0);
|
||||||
|
@ -31,7 +31,7 @@
|
|||||||
|
|
||||||
#include "_libelf.h"
|
#include "_libelf.h"
|
||||||
|
|
||||||
ELFTC_VCSID("$Id: gelf_rela.c 3177 2015-03-30 18:19:41Z emaste $");
|
ELFTC_VCSID("$Id: gelf_rela.c 3739 2019-05-06 05:18:15Z jkoshy $");
|
||||||
|
|
||||||
GElf_Rela *
|
GElf_Rela *
|
||||||
gelf_getrela(Elf_Data *ed, int ndx, GElf_Rela *dst)
|
gelf_getrela(Elf_Data *ed, int ndx, GElf_Rela *dst)
|
||||||
@ -67,9 +67,9 @@ gelf_getrela(Elf_Data *ed, int ndx, GElf_Rela *dst)
|
|||||||
return (NULL);
|
return (NULL);
|
||||||
}
|
}
|
||||||
|
|
||||||
msz = _libelf_msize(ELF_T_RELA, ec, e->e_version);
|
if ((msz = _libelf_msize(ELF_T_RELA, ec, e->e_version)) == 0)
|
||||||
|
return (NULL);
|
||||||
|
|
||||||
assert(msz > 0);
|
|
||||||
assert(ndx >= 0);
|
assert(ndx >= 0);
|
||||||
|
|
||||||
if (msz * (size_t) ndx >= d->d_data.d_size) {
|
if (msz * (size_t) ndx >= d->d_data.d_size) {
|
||||||
@ -130,9 +130,9 @@ gelf_update_rela(Elf_Data *ed, int ndx, GElf_Rela *dr)
|
|||||||
return (0);
|
return (0);
|
||||||
}
|
}
|
||||||
|
|
||||||
msz = _libelf_msize(ELF_T_RELA, ec, e->e_version);
|
if ((msz = _libelf_msize(ELF_T_RELA, ec, e->e_version)) == 0)
|
||||||
|
return (0);
|
||||||
|
|
||||||
assert(msz > 0);
|
|
||||||
assert(ndx >= 0);
|
assert(ndx >= 0);
|
||||||
|
|
||||||
if (msz * (size_t) ndx >= d->d_data.d_size) {
|
if (msz * (size_t) ndx >= d->d_data.d_size) {
|
||||||
@ -145,7 +145,7 @@ gelf_update_rela(Elf_Data *ed, int ndx, GElf_Rela *dr)
|
|||||||
|
|
||||||
LIBELF_COPY_U32(rela32, dr, r_offset);
|
LIBELF_COPY_U32(rela32, dr, r_offset);
|
||||||
|
|
||||||
if (ELF64_R_SYM(dr->r_info) > ELF32_R_SYM(~0UL) ||
|
if (ELF64_R_SYM(dr->r_info) > ELF32_R_SYM(~0U) ||
|
||||||
ELF64_R_TYPE(dr->r_info) > ELF32_R_TYPE(~0U)) {
|
ELF64_R_TYPE(dr->r_info) > ELF32_R_TYPE(~0U)) {
|
||||||
LIBELF_SET_ERROR(RANGE, 0);
|
LIBELF_SET_ERROR(RANGE, 0);
|
||||||
return (0);
|
return (0);
|
||||||
|
@ -31,7 +31,7 @@
|
|||||||
|
|
||||||
#include "_libelf.h"
|
#include "_libelf.h"
|
||||||
|
|
||||||
ELFTC_VCSID("$Id: gelf_sym.c 3177 2015-03-30 18:19:41Z emaste $");
|
ELFTC_VCSID("$Id: gelf_sym.c 3732 2019-04-22 11:08:38Z jkoshy $");
|
||||||
|
|
||||||
GElf_Sym *
|
GElf_Sym *
|
||||||
gelf_getsym(Elf_Data *ed, int ndx, GElf_Sym *dst)
|
gelf_getsym(Elf_Data *ed, int ndx, GElf_Sym *dst)
|
||||||
@ -67,9 +67,9 @@ gelf_getsym(Elf_Data *ed, int ndx, GElf_Sym *dst)
|
|||||||
return (NULL);
|
return (NULL);
|
||||||
}
|
}
|
||||||
|
|
||||||
msz = _libelf_msize(ELF_T_SYM, ec, e->e_version);
|
if ((msz = _libelf_msize(ELF_T_SYM, ec, e->e_version)) == 0)
|
||||||
|
return (NULL);
|
||||||
|
|
||||||
assert(msz > 0);
|
|
||||||
assert(ndx >= 0);
|
assert(ndx >= 0);
|
||||||
|
|
||||||
if (msz * (size_t) ndx >= d->d_data.d_size) {
|
if (msz * (size_t) ndx >= d->d_data.d_size) {
|
||||||
@ -129,9 +129,9 @@ gelf_update_sym(Elf_Data *ed, int ndx, GElf_Sym *gs)
|
|||||||
return (0);
|
return (0);
|
||||||
}
|
}
|
||||||
|
|
||||||
msz = _libelf_msize(ELF_T_SYM, ec, e->e_version);
|
if ((msz = _libelf_msize(ELF_T_SYM, ec, e->e_version)) == 0)
|
||||||
|
return (0);
|
||||||
|
|
||||||
assert(msz > 0);
|
|
||||||
assert(ndx >= 0);
|
assert(ndx >= 0);
|
||||||
|
|
||||||
if (msz * (size_t) ndx >= d->d_data.d_size) {
|
if (msz * (size_t) ndx >= d->d_data.d_size) {
|
||||||
|
@ -29,7 +29,7 @@
|
|||||||
|
|
||||||
#include "_libelf.h"
|
#include "_libelf.h"
|
||||||
|
|
||||||
ELFTC_VCSID("$Id: gelf_syminfo.c 3174 2015-03-27 17:13:41Z emaste $");
|
ELFTC_VCSID("$Id: gelf_syminfo.c 3732 2019-04-22 11:08:38Z jkoshy $");
|
||||||
|
|
||||||
GElf_Syminfo *
|
GElf_Syminfo *
|
||||||
gelf_getsyminfo(Elf_Data *ed, int ndx, GElf_Syminfo *dst)
|
gelf_getsyminfo(Elf_Data *ed, int ndx, GElf_Syminfo *dst)
|
||||||
@ -65,9 +65,9 @@ gelf_getsyminfo(Elf_Data *ed, int ndx, GElf_Syminfo *dst)
|
|||||||
return (NULL);
|
return (NULL);
|
||||||
}
|
}
|
||||||
|
|
||||||
msz = _libelf_msize(ELF_T_SYMINFO, ec, e->e_version);
|
if ((msz = _libelf_msize(ELF_T_SYMINFO, ec, e->e_version)) == 0)
|
||||||
|
return (NULL);
|
||||||
|
|
||||||
assert(msz > 0);
|
|
||||||
assert(ndx >= 0);
|
assert(ndx >= 0);
|
||||||
|
|
||||||
if (msz * (size_t) ndx >= d->d_data.d_size) {
|
if (msz * (size_t) ndx >= d->d_data.d_size) {
|
||||||
@ -126,9 +126,9 @@ gelf_update_syminfo(Elf_Data *ed, int ndx, GElf_Syminfo *gs)
|
|||||||
return (0);
|
return (0);
|
||||||
}
|
}
|
||||||
|
|
||||||
msz = _libelf_msize(ELF_T_SYMINFO, ec, e->e_version);
|
if ((msz = _libelf_msize(ELF_T_SYMINFO, ec, e->e_version)) == 0)
|
||||||
|
return (0);
|
||||||
|
|
||||||
assert(msz > 0);
|
|
||||||
assert(ndx >= 0);
|
assert(ndx >= 0);
|
||||||
|
|
||||||
if (msz * (size_t) ndx >= d->d_data.d_size) {
|
if (msz * (size_t) ndx >= d->d_data.d_size) {
|
||||||
|
@ -29,7 +29,7 @@
|
|||||||
|
|
||||||
#include "_libelf.h"
|
#include "_libelf.h"
|
||||||
|
|
||||||
ELFTC_VCSID("$Id: gelf_symshndx.c 3174 2015-03-27 17:13:41Z emaste $");
|
ELFTC_VCSID("$Id: gelf_symshndx.c 3732 2019-04-22 11:08:38Z jkoshy $");
|
||||||
|
|
||||||
GElf_Sym *
|
GElf_Sym *
|
||||||
gelf_getsymshndx(Elf_Data *d, Elf_Data *id, int ndx, GElf_Sym *dst,
|
gelf_getsymshndx(Elf_Data *d, Elf_Data *id, int ndx, GElf_Sym *dst,
|
||||||
@ -69,9 +69,9 @@ gelf_getsymshndx(Elf_Data *d, Elf_Data *id, int ndx, GElf_Sym *dst,
|
|||||||
return (NULL);
|
return (NULL);
|
||||||
}
|
}
|
||||||
|
|
||||||
msz = _libelf_msize(ELF_T_WORD, ec, e->e_version);
|
if ((msz = _libelf_msize(ELF_T_WORD, ec, e->e_version)) == 0)
|
||||||
|
return (NULL);
|
||||||
|
|
||||||
assert(msz > 0);
|
|
||||||
assert(ndx >= 0);
|
assert(ndx >= 0);
|
||||||
|
|
||||||
if (msz * (size_t) ndx >= id->d_size) {
|
if (msz * (size_t) ndx >= id->d_size) {
|
||||||
@ -121,9 +121,9 @@ gelf_update_symshndx(Elf_Data *d, Elf_Data *id, int ndx, GElf_Sym *gs,
|
|||||||
return (0);
|
return (0);
|
||||||
}
|
}
|
||||||
|
|
||||||
msz = _libelf_msize(ELF_T_WORD, ec, e->e_version);
|
if ((msz = _libelf_msize(ELF_T_WORD, ec, e->e_version)) == 0)
|
||||||
|
return (0);
|
||||||
|
|
||||||
assert(msz > 0);
|
|
||||||
assert(ndx >= 0);
|
assert(ndx >= 0);
|
||||||
|
|
||||||
if (msz * (size_t) ndx >= id->d_size) {
|
if (msz * (size_t) ndx >= id->d_size) {
|
||||||
|
@ -36,33 +36,26 @@
|
|||||||
|
|
||||||
#include "_libelf.h"
|
#include "_libelf.h"
|
||||||
|
|
||||||
ELFTC_VCSID("$Id: libelf_allocate.c 3174 2015-03-27 17:13:41Z emaste $");
|
ELFTC_VCSID("$Id: libelf_allocate.c 3738 2019-05-05 21:49:06Z jkoshy $");
|
||||||
|
|
||||||
Elf *
|
Elf *
|
||||||
_libelf_allocate_elf(void)
|
_libelf_allocate_elf(void)
|
||||||
{
|
{
|
||||||
Elf *e;
|
Elf *e;
|
||||||
|
|
||||||
if ((e = malloc(sizeof(*e))) == NULL) {
|
if ((e = calloc((size_t) 1, sizeof(*e))) == NULL) {
|
||||||
LIBELF_SET_ERROR(RESOURCE, errno);
|
LIBELF_SET_ERROR(RESOURCE, errno);
|
||||||
return NULL;
|
return NULL;
|
||||||
}
|
}
|
||||||
|
|
||||||
e->e_activations = 1;
|
e->e_activations = 1;
|
||||||
e->e_hdr.e_rawhdr = NULL;
|
|
||||||
e->e_byteorder = ELFDATANONE;
|
e->e_byteorder = ELFDATANONE;
|
||||||
e->e_class = ELFCLASSNONE;
|
e->e_class = ELFCLASSNONE;
|
||||||
e->e_cmd = ELF_C_NULL;
|
e->e_cmd = ELF_C_NULL;
|
||||||
e->e_fd = -1;
|
e->e_fd = -1;
|
||||||
e->e_flags = 0;
|
|
||||||
e->e_kind = ELF_K_NONE;
|
e->e_kind = ELF_K_NONE;
|
||||||
e->e_parent = NULL;
|
|
||||||
e->e_rawfile = NULL;
|
|
||||||
e->e_rawsize = 0;
|
|
||||||
e->e_version = LIBELF_PRIVATE(version);
|
e->e_version = LIBELF_PRIVATE(version);
|
||||||
|
|
||||||
(void) memset(&e->e_u, 0, sizeof(e->e_u));
|
|
||||||
|
|
||||||
return (e);
|
return (e);
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -83,31 +76,25 @@ _libelf_init_elf(Elf *e, Elf_Kind kind)
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
#define FREE(P) do { \
|
void
|
||||||
if (P) \
|
|
||||||
free(P); \
|
|
||||||
} while (0)
|
|
||||||
|
|
||||||
|
|
||||||
Elf *
|
|
||||||
_libelf_release_elf(Elf *e)
|
_libelf_release_elf(Elf *e)
|
||||||
{
|
{
|
||||||
Elf_Arhdr *arh;
|
Elf_Arhdr *arh;
|
||||||
|
|
||||||
switch (e->e_kind) {
|
switch (e->e_kind) {
|
||||||
case ELF_K_AR:
|
case ELF_K_AR:
|
||||||
FREE(e->e_u.e_ar.e_symtab);
|
free(e->e_u.e_ar.e_symtab);
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case ELF_K_ELF:
|
case ELF_K_ELF:
|
||||||
switch (e->e_class) {
|
switch (e->e_class) {
|
||||||
case ELFCLASS32:
|
case ELFCLASS32:
|
||||||
FREE(e->e_u.e_elf.e_ehdr.e_ehdr32);
|
free(e->e_u.e_elf.e_ehdr.e_ehdr32);
|
||||||
FREE(e->e_u.e_elf.e_phdr.e_phdr32);
|
free(e->e_u.e_elf.e_phdr.e_phdr32);
|
||||||
break;
|
break;
|
||||||
case ELFCLASS64:
|
case ELFCLASS64:
|
||||||
FREE(e->e_u.e_elf.e_ehdr.e_ehdr64);
|
free(e->e_u.e_elf.e_ehdr.e_ehdr64);
|
||||||
FREE(e->e_u.e_elf.e_phdr.e_phdr64);
|
free(e->e_u.e_elf.e_phdr.e_phdr64);
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -115,8 +102,8 @@ _libelf_release_elf(Elf *e)
|
|||||||
|
|
||||||
if (e->e_flags & LIBELF_F_AR_HEADER) {
|
if (e->e_flags & LIBELF_F_AR_HEADER) {
|
||||||
arh = e->e_hdr.e_arhdr;
|
arh = e->e_hdr.e_arhdr;
|
||||||
FREE(arh->ar_name);
|
free(arh->ar_name);
|
||||||
FREE(arh->ar_rawname);
|
free(arh->ar_rawname);
|
||||||
free(arh);
|
free(arh);
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -127,8 +114,6 @@ _libelf_release_elf(Elf *e)
|
|||||||
}
|
}
|
||||||
|
|
||||||
free(e);
|
free(e);
|
||||||
|
|
||||||
return (NULL);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
struct _Libelf_Data *
|
struct _Libelf_Data *
|
||||||
|
@ -33,7 +33,7 @@
|
|||||||
#include "_libelf.h"
|
#include "_libelf.h"
|
||||||
#include "_libelf_ar.h"
|
#include "_libelf_ar.h"
|
||||||
|
|
||||||
ELFTC_VCSID("$Id: libelf_ar.c 3446 2016-05-03 01:31:17Z emaste $");
|
ELFTC_VCSID("$Id: libelf_ar.c 3712 2019-03-16 22:23:34Z jkoshy $");
|
||||||
|
|
||||||
#define LIBELF_NALLOC_SIZE 16
|
#define LIBELF_NALLOC_SIZE 16
|
||||||
|
|
||||||
@ -123,8 +123,16 @@ _libelf_ar_gethdr(Elf *e)
|
|||||||
arh = (struct ar_hdr *) (uintptr_t) e->e_hdr.e_rawhdr;
|
arh = (struct ar_hdr *) (uintptr_t) e->e_hdr.e_rawhdr;
|
||||||
|
|
||||||
assert((uintptr_t) arh >= (uintptr_t) parent->e_rawfile + SARMAG);
|
assert((uintptr_t) arh >= (uintptr_t) parent->e_rawfile + SARMAG);
|
||||||
assert((uintptr_t) arh <= (uintptr_t) parent->e_rawfile +
|
|
||||||
parent->e_rawsize - sizeof(struct ar_hdr));
|
/*
|
||||||
|
* There needs to be enough space remaining in the file for the
|
||||||
|
* archive header.
|
||||||
|
*/
|
||||||
|
if ((uintptr_t) arh > (uintptr_t) parent->e_rawfile +
|
||||||
|
(uintptr_t) parent->e_rawsize - sizeof(struct ar_hdr)) {
|
||||||
|
LIBELF_SET_ERROR(ARCHIVE, 0);
|
||||||
|
return (NULL);
|
||||||
|
}
|
||||||
|
|
||||||
if ((eh = malloc(sizeof(Elf_Arhdr))) == NULL) {
|
if ((eh = malloc(sizeof(Elf_Arhdr))) == NULL) {
|
||||||
LIBELF_SET_ERROR(RESOURCE, 0);
|
LIBELF_SET_ERROR(RESOURCE, 0);
|
||||||
@ -199,8 +207,8 @@ Elf *
|
|||||||
_libelf_ar_open_member(int fd, Elf_Cmd c, Elf *elf)
|
_libelf_ar_open_member(int fd, Elf_Cmd c, Elf *elf)
|
||||||
{
|
{
|
||||||
Elf *e;
|
Elf *e;
|
||||||
off_t next;
|
|
||||||
size_t nsz, sz;
|
size_t nsz, sz;
|
||||||
|
off_t next, end;
|
||||||
struct ar_hdr *arh;
|
struct ar_hdr *arh;
|
||||||
char *member, *namelen;
|
char *member, *namelen;
|
||||||
|
|
||||||
@ -217,6 +225,17 @@ _libelf_ar_open_member(int fd, Elf_Cmd c, Elf *elf)
|
|||||||
|
|
||||||
assert((next & 1) == 0);
|
assert((next & 1) == 0);
|
||||||
|
|
||||||
|
/*
|
||||||
|
* There needs to be enough space in the file to contain an
|
||||||
|
* ar(1) header.
|
||||||
|
*/
|
||||||
|
end = next + (off_t) sizeof(struct ar_hdr);
|
||||||
|
if ((uintmax_t) end < (uintmax_t) next || /* Overflow. */
|
||||||
|
end > (off_t) elf->e_rawsize) {
|
||||||
|
LIBELF_SET_ERROR(ARCHIVE, 0);
|
||||||
|
return (NULL);
|
||||||
|
}
|
||||||
|
|
||||||
arh = (struct ar_hdr *) (elf->e_rawfile + next);
|
arh = (struct ar_hdr *) (elf->e_rawfile + next);
|
||||||
|
|
||||||
/*
|
/*
|
||||||
@ -228,6 +247,17 @@ _libelf_ar_open_member(int fd, Elf_Cmd c, Elf *elf)
|
|||||||
return (NULL);
|
return (NULL);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Check if the archive member that follows will fit in the
|
||||||
|
* containing archive.
|
||||||
|
*/
|
||||||
|
end += (off_t) sz;
|
||||||
|
if (end < next || /* Overflow. */
|
||||||
|
end > (off_t) elf->e_rawsize) {
|
||||||
|
LIBELF_SET_ERROR(ARCHIVE, 0);
|
||||||
|
return (NULL);
|
||||||
|
}
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* Adjust the size field for members in BSD archives using
|
* Adjust the size field for members in BSD archives using
|
||||||
* extended naming.
|
* extended naming.
|
||||||
@ -286,7 +316,8 @@ Elf_Arsym *
|
|||||||
_libelf_ar_process_bsd_symtab(Elf *e, size_t *count)
|
_libelf_ar_process_bsd_symtab(Elf *e, size_t *count)
|
||||||
{
|
{
|
||||||
Elf_Arsym *symtab, *sym;
|
Elf_Arsym *symtab, *sym;
|
||||||
unsigned int n, nentries;
|
unsigned int n;
|
||||||
|
size_t nentries;
|
||||||
unsigned char *end, *p, *p0, *s, *s0;
|
unsigned char *end, *p, *p0, *s, *s0;
|
||||||
const size_t entrysize = 2 * sizeof(long);
|
const size_t entrysize = 2 * sizeof(long);
|
||||||
long arraysize, fileoffset, stroffset, strtabsize;
|
long arraysize, fileoffset, stroffset, strtabsize;
|
||||||
@ -343,7 +374,7 @@ _libelf_ar_process_bsd_symtab(Elf *e, size_t *count)
|
|||||||
GET_LONG(p, fileoffset);
|
GET_LONG(p, fileoffset);
|
||||||
|
|
||||||
if (stroffset < 0 || fileoffset < 0 ||
|
if (stroffset < 0 || fileoffset < 0 ||
|
||||||
(size_t) fileoffset >= e->e_rawsize)
|
(off_t) fileoffset >= e->e_rawsize)
|
||||||
goto symtaberror;
|
goto symtaberror;
|
||||||
|
|
||||||
s = s0 + stroffset;
|
s = s0 + stroffset;
|
||||||
|
@ -30,7 +30,7 @@
|
|||||||
|
|
||||||
#include "_libelf.h"
|
#include "_libelf.h"
|
||||||
|
|
||||||
ELFTC_VCSID("$Id: libelf_convert.m4 3632 2018-10-10 21:12:43Z jkoshy $");
|
ELFTC_VCSID("$Id: libelf_convert.m4 3712 2019-03-16 22:23:34Z jkoshy $");
|
||||||
|
|
||||||
/* WARNING: GENERATED FROM __file__. */
|
/* WARNING: GENERATED FROM __file__. */
|
||||||
|
|
||||||
@ -820,7 +820,7 @@ _libelf_cvt_GNUHASH64_tom(unsigned char *dst, size_t dsz, unsigned char *src,
|
|||||||
if (dsz < srcsz) /* Destination lacks space. */
|
if (dsz < srcsz) /* Destination lacks space. */
|
||||||
return (0);
|
return (0);
|
||||||
|
|
||||||
nchains = srcsz / sizeof(uint32_t);
|
nchains = (uint32_t) (srcsz / sizeof(uint32_t));
|
||||||
chains = (uint32_t *) (uintptr_t) dst;
|
chains = (uint32_t *) (uintptr_t) dst;
|
||||||
|
|
||||||
for (n = 0; n < nchains; n++) {
|
for (n = 0; n < nchains; n++) {
|
||||||
@ -901,7 +901,7 @@ _libelf_cvt_GNUHASH64_tof(unsigned char *dst, size_t dsz, unsigned char *src,
|
|||||||
if (dsz < srcsz)
|
if (dsz < srcsz)
|
||||||
return (0);
|
return (0);
|
||||||
|
|
||||||
nchains = srcsz / sizeof(uint32_t);
|
nchains = (uint32_t) (srcsz / sizeof(uint32_t));
|
||||||
for (n = 0; n < nchains; n++) {
|
for (n = 0; n < nchains; n++) {
|
||||||
t32 = *s32++;
|
t32 = *s32++;
|
||||||
if (byteswap)
|
if (byteswap)
|
||||||
@ -1078,13 +1078,8 @@ _libelf_translator_function *
|
|||||||
_libelf_get_translator(Elf_Type t, int direction, int elfclass, int elfmachine)
|
_libelf_get_translator(Elf_Type t, int direction, int elfclass, int elfmachine)
|
||||||
{
|
{
|
||||||
assert(elfclass == ELFCLASS32 || elfclass == ELFCLASS64);
|
assert(elfclass == ELFCLASS32 || elfclass == ELFCLASS64);
|
||||||
assert(elfmachine >= EM_NONE && elfmachine < EM__LAST__);
|
|
||||||
assert(direction == ELF_TOFILE || direction == ELF_TOMEMORY);
|
assert(direction == ELF_TOFILE || direction == ELF_TOMEMORY);
|
||||||
|
assert(t >= ELF_T_FIRST && t <= ELF_T_LAST);
|
||||||
if (t >= ELF_T_NUM ||
|
|
||||||
(elfclass != ELFCLASS32 && elfclass != ELFCLASS64) ||
|
|
||||||
(direction != ELF_TOFILE && direction != ELF_TOMEMORY))
|
|
||||||
return (NULL);
|
|
||||||
|
|
||||||
/* TODO: Handle MIPS64 REL{,A} sections (ticket #559). */
|
/* TODO: Handle MIPS64 REL{,A} sections (ticket #559). */
|
||||||
(void) elfmachine;
|
(void) elfmachine;
|
||||||
|
@ -28,7 +28,7 @@
|
|||||||
|
|
||||||
#include "_libelf.h"
|
#include "_libelf.h"
|
||||||
|
|
||||||
ELFTC_VCSID("$Id: libelf_data.c 3174 2015-03-27 17:13:41Z emaste $");
|
ELFTC_VCSID("$Id: libelf_data.c 3737 2019-05-05 14:49:50Z jkoshy $");
|
||||||
|
|
||||||
int
|
int
|
||||||
_libelf_xlate_shtype(uint32_t sht)
|
_libelf_xlate_shtype(uint32_t sht)
|
||||||
@ -89,8 +89,14 @@ _libelf_xlate_shtype(uint32_t sht)
|
|||||||
* OS, processor and user-defined section types) are
|
* OS, processor and user-defined section types) are
|
||||||
* legal, but since we do not know anything more about
|
* legal, but since we do not know anything more about
|
||||||
* their semantics, we return a type of ELF_T_BYTE.
|
* their semantics, we return a type of ELF_T_BYTE.
|
||||||
|
*
|
||||||
|
* The ELF specification uses 32 bit unsigned values for
|
||||||
|
* denoting section types, and defines SHT_HIUSER to be
|
||||||
|
* 0xFFFFFFFFUL (i.e., UINT32_MAX). Consequently, we only
|
||||||
|
* need to check that 'sht' is greater than or equal to
|
||||||
|
* SHT_LOOS.
|
||||||
*/
|
*/
|
||||||
if (sht >= SHT_LOOS && sht <= SHT_HIUSER)
|
if (sht >= SHT_LOOS)
|
||||||
return (ELF_T_BYTE);
|
return (ELF_T_BYTE);
|
||||||
|
|
||||||
/*
|
/*
|
||||||
|
@ -31,7 +31,7 @@
|
|||||||
|
|
||||||
#include "_libelf.h"
|
#include "_libelf.h"
|
||||||
|
|
||||||
ELFTC_VCSID("$Id: libelf_ehdr.c 3632 2018-10-10 21:12:43Z jkoshy $");
|
ELFTC_VCSID("$Id: libelf_ehdr.c 3732 2019-04-22 11:08:38Z jkoshy $");
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* Retrieve counts for sections, phdrs and the section string table index
|
* Retrieve counts for sections, phdrs and the section string table index
|
||||||
@ -51,7 +51,12 @@ _libelf_load_extended(Elf *e, int ec, uint64_t shoff, uint16_t phnum,
|
|||||||
fsz = _libelf_fsize(ELF_T_SHDR, ec, e->e_version, 1);
|
fsz = _libelf_fsize(ELF_T_SHDR, ec, e->e_version, 1);
|
||||||
assert(fsz > 0);
|
assert(fsz > 0);
|
||||||
|
|
||||||
if (e->e_rawsize < shoff + fsz) { /* raw file too small */
|
if (shoff + fsz < shoff) { /* Numeric overflow. */
|
||||||
|
LIBELF_SET_ERROR(HEADER, 0);
|
||||||
|
return (0);
|
||||||
|
}
|
||||||
|
|
||||||
|
if ((uint64_t) e->e_rawsize < shoff + fsz) {
|
||||||
LIBELF_SET_ERROR(HEADER, 0);
|
LIBELF_SET_ERROR(HEADER, 0);
|
||||||
return (0);
|
return (0);
|
||||||
}
|
}
|
||||||
@ -138,14 +143,13 @@ _libelf_ehdr(Elf *e, int ec, int allocate)
|
|||||||
fsz = _libelf_fsize(ELF_T_EHDR, ec, e->e_version, (size_t) 1);
|
fsz = _libelf_fsize(ELF_T_EHDR, ec, e->e_version, (size_t) 1);
|
||||||
assert(fsz > 0);
|
assert(fsz > 0);
|
||||||
|
|
||||||
if (e->e_cmd != ELF_C_WRITE && e->e_rawsize < fsz) {
|
if (e->e_cmd != ELF_C_WRITE && e->e_rawsize < (off_t) fsz) {
|
||||||
LIBELF_SET_ERROR(HEADER, 0);
|
LIBELF_SET_ERROR(HEADER, 0);
|
||||||
return (NULL);
|
return (NULL);
|
||||||
}
|
}
|
||||||
|
|
||||||
msz = _libelf_msize(ELF_T_EHDR, ec, EV_CURRENT);
|
if ((msz = _libelf_msize(ELF_T_EHDR, ec, EV_CURRENT)) == 0)
|
||||||
|
return (NULL);
|
||||||
assert(msz > 0);
|
|
||||||
|
|
||||||
if ((ehdr = calloc((size_t) 1, msz)) == NULL) {
|
if ((ehdr = calloc((size_t) 1, msz)) == NULL) {
|
||||||
LIBELF_SET_ERROR(RESOURCE, 0);
|
LIBELF_SET_ERROR(RESOURCE, 0);
|
||||||
|
@ -29,7 +29,7 @@
|
|||||||
|
|
||||||
#include "_libelf.h"
|
#include "_libelf.h"
|
||||||
|
|
||||||
ELFTC_VCSID("$Id: libelf_extended.c 3174 2015-03-27 17:13:41Z emaste $");
|
ELFTC_VCSID("$Id: libelf_extended.c 3712 2019-03-16 22:23:34Z jkoshy $");
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* Retrieve section #0, allocating a new section if needed.
|
* Retrieve section #0, allocating a new section if needed.
|
||||||
@ -57,7 +57,7 @@ _libelf_setshnum(Elf *e, void *eh, int ec, size_t shnum)
|
|||||||
assert(scn->s_ndx == SHN_UNDEF);
|
assert(scn->s_ndx == SHN_UNDEF);
|
||||||
|
|
||||||
if (ec == ELFCLASS32)
|
if (ec == ELFCLASS32)
|
||||||
scn->s_shdr.s_shdr32.sh_size = shnum;
|
scn->s_shdr.s_shdr32.sh_size = (Elf32_Word) shnum;
|
||||||
else
|
else
|
||||||
scn->s_shdr.s_shdr64.sh_size = shnum;
|
scn->s_shdr.s_shdr64.sh_size = shnum;
|
||||||
|
|
||||||
@ -87,9 +87,9 @@ _libelf_setshstrndx(Elf *e, void *eh, int ec, size_t shstrndx)
|
|||||||
assert(scn->s_ndx == SHN_UNDEF);
|
assert(scn->s_ndx == SHN_UNDEF);
|
||||||
|
|
||||||
if (ec == ELFCLASS32)
|
if (ec == ELFCLASS32)
|
||||||
scn->s_shdr.s_shdr32.sh_link = shstrndx;
|
scn->s_shdr.s_shdr32.sh_link = (Elf32_Word) shstrndx;
|
||||||
else
|
else
|
||||||
scn->s_shdr.s_shdr64.sh_link = shstrndx;
|
scn->s_shdr.s_shdr64.sh_link = (Elf64_Word) shstrndx;
|
||||||
|
|
||||||
(void) elf_flagshdr(scn, ELF_C_SET, ELF_F_DIRTY);
|
(void) elf_flagshdr(scn, ELF_C_SET, ELF_F_DIRTY);
|
||||||
|
|
||||||
@ -116,9 +116,9 @@ _libelf_setphnum(Elf *e, void *eh, int ec, size_t phnum)
|
|||||||
assert(scn->s_ndx == SHN_UNDEF);
|
assert(scn->s_ndx == SHN_UNDEF);
|
||||||
|
|
||||||
if (ec == ELFCLASS32)
|
if (ec == ELFCLASS32)
|
||||||
scn->s_shdr.s_shdr32.sh_info = phnum;
|
scn->s_shdr.s_shdr32.sh_info = (Elf32_Word) phnum;
|
||||||
else
|
else
|
||||||
scn->s_shdr.s_shdr64.sh_info = phnum;
|
scn->s_shdr.s_shdr64.sh_info = (Elf64_Word) phnum;
|
||||||
|
|
||||||
(void) elf_flagshdr(scn, ELF_C_SET, ELF_F_DIRTY);
|
(void) elf_flagshdr(scn, ELF_C_SET, ELF_F_DIRTY);
|
||||||
|
|
||||||
|
@ -31,7 +31,7 @@
|
|||||||
|
|
||||||
#include "_libelf.h"
|
#include "_libelf.h"
|
||||||
|
|
||||||
ELFTC_VCSID("$Id: libelf_memory.c 3013 2014-03-23 06:16:59Z jkoshy $");
|
ELFTC_VCSID("$Id: libelf_memory.c 3738 2019-05-05 21:49:06Z jkoshy $");
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* Create an ELF descriptor for a memory image, optionally reporting
|
* Create an ELF descriptor for a memory image, optionally reporting
|
||||||
@ -54,7 +54,7 @@ _libelf_memory(unsigned char *image, size_t sz, int reporterror)
|
|||||||
|
|
||||||
e->e_cmd = ELF_C_READ;
|
e->e_cmd = ELF_C_READ;
|
||||||
e->e_rawfile = image;
|
e->e_rawfile = image;
|
||||||
e->e_rawsize = sz;
|
e->e_rawsize = (off_t) sz;
|
||||||
|
|
||||||
#undef LIBELF_IS_ELF
|
#undef LIBELF_IS_ELF
|
||||||
#define LIBELF_IS_ELF(P) ((P)[EI_MAG0] == ELFMAG0 && \
|
#define LIBELF_IS_ELF(P) ((P)[EI_MAG0] == ELFMAG0 && \
|
||||||
@ -78,7 +78,7 @@ _libelf_memory(unsigned char *image, size_t sz, int reporterror)
|
|||||||
if (error != ELF_E_NONE) {
|
if (error != ELF_E_NONE) {
|
||||||
if (reporterror) {
|
if (reporterror) {
|
||||||
LIBELF_PRIVATE(error) = LIBELF_ERROR(error, 0);
|
LIBELF_PRIVATE(error) = LIBELF_ERROR(error, 0);
|
||||||
(void) _libelf_release_elf(e);
|
_libelf_release_elf(e);
|
||||||
return (NULL);
|
return (NULL);
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
|
@ -30,7 +30,7 @@
|
|||||||
|
|
||||||
#include "_libelf.h"
|
#include "_libelf.h"
|
||||||
|
|
||||||
ELFTC_VCSID("$Id: libelf_msize.m4 3174 2015-03-27 17:13:41Z emaste $");
|
ELFTC_VCSID("$Id: libelf_msize.m4 3732 2019-04-22 11:08:38Z jkoshy $");
|
||||||
|
|
||||||
/* WARNING: GENERATED FROM __file__. */
|
/* WARNING: GENERATED FROM __file__. */
|
||||||
|
|
||||||
@ -87,6 +87,14 @@ static struct msize msize[ELF_T_NUM] = {
|
|||||||
MSIZES(ELF_TYPE_LIST)
|
MSIZES(ELF_TYPE_LIST)
|
||||||
};
|
};
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Returns the memory size of the specified ELF type 't' of ELF
|
||||||
|
* class 'ec' and ELF version 'version'.
|
||||||
|
*
|
||||||
|
* If the specified combination of ELF type, class, and version is
|
||||||
|
* unsupported then a value of 0 will be returned and the appropriate
|
||||||
|
* library error code set.
|
||||||
|
*/
|
||||||
size_t
|
size_t
|
||||||
_libelf_msize(Elf_Type t, int elfclass, unsigned int version)
|
_libelf_msize(Elf_Type t, int elfclass, unsigned int version)
|
||||||
{
|
{
|
||||||
@ -102,5 +110,10 @@ _libelf_msize(Elf_Type t, int elfclass, unsigned int version)
|
|||||||
|
|
||||||
sz = (elfclass == ELFCLASS32) ? msize[t].msz32 : msize[t].msz64;
|
sz = (elfclass == ELFCLASS32) ? msize[t].msz32 : msize[t].msz64;
|
||||||
|
|
||||||
|
if (sz == 0) {
|
||||||
|
LIBELF_SET_ERROR(UNIMPL, 0);
|
||||||
|
return (0);
|
||||||
|
}
|
||||||
|
|
||||||
return (sz);
|
return (sz);
|
||||||
}
|
}
|
||||||
|
@ -31,7 +31,7 @@
|
|||||||
|
|
||||||
#include "_libelf.h"
|
#include "_libelf.h"
|
||||||
|
|
||||||
ELFTC_VCSID("$Id: libelf_phdr.c 3632 2018-10-10 21:12:43Z jkoshy $");
|
ELFTC_VCSID("$Id: libelf_phdr.c 3732 2019-04-22 11:08:38Z jkoshy $");
|
||||||
|
|
||||||
void *
|
void *
|
||||||
_libelf_getphdr(Elf *e, int ec)
|
_libelf_getphdr(Elf *e, int ec)
|
||||||
@ -77,14 +77,18 @@ _libelf_getphdr(Elf *e, int ec)
|
|||||||
|
|
||||||
assert(fsz > 0);
|
assert(fsz > 0);
|
||||||
|
|
||||||
|
if (phoff + fsz < phoff) { /* Numeric overflow. */
|
||||||
|
LIBELF_SET_ERROR(HEADER, 0);
|
||||||
|
return (NULL);
|
||||||
|
}
|
||||||
|
|
||||||
if ((uint64_t) e->e_rawsize < (phoff + fsz)) {
|
if ((uint64_t) e->e_rawsize < (phoff + fsz)) {
|
||||||
LIBELF_SET_ERROR(HEADER, 0);
|
LIBELF_SET_ERROR(HEADER, 0);
|
||||||
return (NULL);
|
return (NULL);
|
||||||
}
|
}
|
||||||
|
|
||||||
msz = _libelf_msize(ELF_T_PHDR, ec, EV_CURRENT);
|
if ((msz = _libelf_msize(ELF_T_PHDR, ec, EV_CURRENT)) == 0)
|
||||||
|
return (NULL);
|
||||||
assert(msz > 0);
|
|
||||||
|
|
||||||
if ((phdr = calloc(phnum, msz)) == NULL) {
|
if ((phdr = calloc(phnum, msz)) == NULL) {
|
||||||
LIBELF_SET_ERROR(RESOURCE, 0);
|
LIBELF_SET_ERROR(RESOURCE, 0);
|
||||||
@ -125,9 +129,8 @@ _libelf_newphdr(Elf *e, int ec, size_t count)
|
|||||||
assert(ec == ELFCLASS32 || ec == ELFCLASS64);
|
assert(ec == ELFCLASS32 || ec == ELFCLASS64);
|
||||||
assert(e->e_version == EV_CURRENT);
|
assert(e->e_version == EV_CURRENT);
|
||||||
|
|
||||||
msz = _libelf_msize(ELF_T_PHDR, ec, e->e_version);
|
if ((msz = _libelf_msize(ELF_T_PHDR, ec, e->e_version)) == 0)
|
||||||
|
return (NULL);
|
||||||
assert(msz > 0);
|
|
||||||
|
|
||||||
newphdr = NULL;
|
newphdr = NULL;
|
||||||
if (count > 0 && (newphdr = calloc(count, msz)) == NULL) {
|
if (count > 0 && (newphdr = calloc(count, msz)) == NULL) {
|
||||||
|
@ -29,7 +29,7 @@
|
|||||||
|
|
||||||
#include "_libelf.h"
|
#include "_libelf.h"
|
||||||
|
|
||||||
ELFTC_VCSID("$Id: libelf_xlate.c 3632 2018-10-10 21:12:43Z jkoshy $");
|
ELFTC_VCSID("$Id: libelf_xlate.c 3732 2019-04-22 11:08:38Z jkoshy $");
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* Translate to/from the file representation of ELF objects.
|
* Translate to/from the file representation of ELF objects.
|
||||||
@ -83,9 +83,8 @@ _libelf_xlate(Elf_Data *dst, const Elf_Data *src, unsigned int encoding,
|
|||||||
(src->d_type, (size_t) 1, src->d_version)) == 0)
|
(src->d_type, (size_t) 1, src->d_version)) == 0)
|
||||||
return (NULL);
|
return (NULL);
|
||||||
|
|
||||||
msz = _libelf_msize(src->d_type, elfclass, src->d_version);
|
if ((msz = _libelf_msize(src->d_type, elfclass, src->d_version)) == 0)
|
||||||
|
return (NULL);
|
||||||
assert(msz > 0);
|
|
||||||
|
|
||||||
if (src->d_size % (direction == ELF_TOMEMORY ? fsz : msz)) {
|
if (src->d_size % (direction == ELF_TOMEMORY ? fsz : msz)) {
|
||||||
LIBELF_SET_ERROR(DATA, 0);
|
LIBELF_SET_ERROR(DATA, 0);
|
||||||
|
31
libelf/os.Linux.mk
Normal file
31
libelf/os.Linux.mk
Normal file
@ -0,0 +1,31 @@
|
|||||||
|
# Enable additional warnings.
|
||||||
|
CFLAGS+= -Wa,--fatal-warnings
|
||||||
|
CFLAGS+= -Wall
|
||||||
|
CFLAGS+= -Wcast-align
|
||||||
|
CFLAGS+= -Wcast-qual
|
||||||
|
CFLAGS+= -Wchar-subscripts
|
||||||
|
CFLAGS+= -Wconversion
|
||||||
|
CFLAGS+= -Werror
|
||||||
|
CFLAGS+= -Wextra
|
||||||
|
CFLAGS+= -Wformat=2
|
||||||
|
CFLAGS+= -Winline
|
||||||
|
CFLAGS+= -Wmissing-prototypes
|
||||||
|
CFLAGS+= -Wnested-externs
|
||||||
|
CFLAGS+= -Wempty-body
|
||||||
|
CFLAGS+= -Wformat-y2k
|
||||||
|
CFLAGS+= -Wformat-zero-length
|
||||||
|
CFLAGS+= -Wpointer-sign
|
||||||
|
CFLAGS+= -Wpointer-to-int-cast
|
||||||
|
CFLAGS+= -Wsign-compare
|
||||||
|
CFLAGS+= -Wunused-const-variable
|
||||||
|
CFLAGS+= -Wunused-parameter
|
||||||
|
CFLAGS+= -Wold-style-definition
|
||||||
|
CFLAGS+= -Wpointer-arith
|
||||||
|
CFLAGS+= -Wredundant-decls
|
||||||
|
CFLAGS+= -Wreturn-type
|
||||||
|
CFLAGS+= -Wshadow
|
||||||
|
CFLAGS+= -Wstrict-prototypes
|
||||||
|
CFLAGS+= -Wstrict-overflow
|
||||||
|
CFLAGS+= -Wswitch
|
||||||
|
CFLAGS+= -Wunused-parameter
|
||||||
|
CFLAGS+= -Wwrite-strings
|
@ -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: elftc_bfd_find_target.3 3645 2018-10-15 20:17:14Z jkoshy $
|
.\" $Id: elftc_bfd_find_target.3 3752 2019-06-28 01:12:53Z emaste $
|
||||||
.\"
|
.\"
|
||||||
.Dd November 30, 2011
|
.Dd June 27, 2019
|
||||||
.Dt ELFTC_BFD_FIND_TARGET 3
|
.Dt ELFTC_BFD_FIND_TARGET 3
|
||||||
.Os
|
.Os
|
||||||
.Sh NAME
|
.Sh NAME
|
||||||
@ -76,6 +76,9 @@ Known descriptor names and their properties include:
|
|||||||
.It Li elf32-powerpc Ta ELF Ta MSB Ta 32
|
.It Li elf32-powerpc Ta ELF Ta MSB Ta 32
|
||||||
.It Li elf32-powerpc-freebsd Ta ELF Ta MSB Ta 32
|
.It Li elf32-powerpc-freebsd Ta ELF Ta MSB Ta 32
|
||||||
.It Li elf32-powerpcle Ta ELF Ta LSB Ta 32
|
.It Li elf32-powerpcle Ta ELF Ta LSB Ta 32
|
||||||
|
.It Li elf32-riscv Ta ELF Ta LSB Ta 32
|
||||||
|
.It Li elf64-riscv Ta ELF Ta LSB Ta 64
|
||||||
|
.It Li elf64-riscv-freebsd Ta ELF Ta LSB Ta 64
|
||||||
.It Li elf32-sh Ta ELF Ta MSB Ta 32
|
.It Li elf32-sh Ta ELF Ta MSB Ta 32
|
||||||
.It Li elf32-shl Ta ELF Ta LSB Ta 32
|
.It Li elf32-shl Ta ELF Ta LSB Ta 32
|
||||||
.It Li elf32-sh-nbsd Ta ELF Ta MSB Ta 32
|
.It Li elf32-sh-nbsd Ta ELF Ta MSB Ta 32
|
||||||
|
@ -402,6 +402,8 @@ elftc_reloc_type_str(unsigned int mach, unsigned int type)
|
|||||||
case 22: return "R_MIPS_GOT_HI16";
|
case 22: return "R_MIPS_GOT_HI16";
|
||||||
case 23: return "R_MIPS_GOT_LO16";
|
case 23: return "R_MIPS_GOT_LO16";
|
||||||
case 24: return "R_MIPS_SUB";
|
case 24: return "R_MIPS_SUB";
|
||||||
|
case 28: return "R_MIPS_HIGHER";
|
||||||
|
case 29: return "R_MIPS_HIGHEST";
|
||||||
case 30: return "R_MIPS_CALLHI16";
|
case 30: return "R_MIPS_CALLHI16";
|
||||||
case 31: return "R_MIPS_CALLLO16";
|
case 31: return "R_MIPS_CALLLO16";
|
||||||
case 37: return "R_MIPS_JALR";
|
case 37: return "R_MIPS_JALR";
|
||||||
|
@ -36,7 +36,7 @@
|
|||||||
#include "libelftc.h"
|
#include "libelftc.h"
|
||||||
#include "_libelftc.h"
|
#include "_libelftc.h"
|
||||||
|
|
||||||
ELFTC_VCSID("$Id: elftc_string_table.c 2869 2013-01-06 13:29:18Z jkoshy $");
|
ELFTC_VCSID("$Id: elftc_string_table.c 3750 2019-06-28 01:12:10Z emaste $");
|
||||||
|
|
||||||
#define ELFTC_STRING_TABLE_DEFAULT_SIZE (4*1024)
|
#define ELFTC_STRING_TABLE_DEFAULT_SIZE (4*1024)
|
||||||
#define ELFTC_STRING_TABLE_EXPECTED_STRING_SIZE 16
|
#define ELFTC_STRING_TABLE_EXPECTED_STRING_SIZE 16
|
||||||
@ -44,7 +44,7 @@ ELFTC_VCSID("$Id: elftc_string_table.c 2869 2013-01-06 13:29:18Z jkoshy $");
|
|||||||
#define ELFTC_STRING_TABLE_POOL_SIZE_INCREMENT (4*1024)
|
#define ELFTC_STRING_TABLE_POOL_SIZE_INCREMENT (4*1024)
|
||||||
|
|
||||||
struct _Elftc_String_Table_Entry {
|
struct _Elftc_String_Table_Entry {
|
||||||
int ste_idx;
|
ssize_t ste_idx;
|
||||||
SLIST_ENTRY(_Elftc_String_Table_Entry) ste_next;
|
SLIST_ENTRY(_Elftc_String_Table_Entry) ste_next;
|
||||||
};
|
};
|
||||||
|
|
||||||
@ -64,9 +64,9 @@ struct _Elftc_String_Table_Entry {
|
|||||||
} while (0)
|
} while (0)
|
||||||
|
|
||||||
struct _Elftc_String_Table {
|
struct _Elftc_String_Table {
|
||||||
unsigned int st_len; /* length and flags */
|
size_t st_len; /* length and flags */
|
||||||
int st_nbuckets;
|
int st_nbuckets;
|
||||||
int st_string_pool_size;
|
size_t st_string_pool_size;
|
||||||
char *st_string_pool;
|
char *st_string_pool;
|
||||||
SLIST_HEAD(_Elftc_String_Table_Bucket,
|
SLIST_HEAD(_Elftc_String_Table_Bucket,
|
||||||
_Elftc_String_Table_Entry) st_buckets[];
|
_Elftc_String_Table_Entry) st_buckets[];
|
||||||
@ -86,7 +86,7 @@ elftc_string_table_find_hash_entry(Elftc_String_Table *st, const char *string,
|
|||||||
*rhashindex = hashindex;
|
*rhashindex = hashindex;
|
||||||
|
|
||||||
SLIST_FOREACH(ste, &st->st_buckets[hashindex], ste_next) {
|
SLIST_FOREACH(ste, &st->st_buckets[hashindex], ste_next) {
|
||||||
s = st->st_string_pool + abs(ste->ste_idx);
|
s = st->st_string_pool + labs(ste->ste_idx);
|
||||||
|
|
||||||
assert(s > st->st_string_pool &&
|
assert(s > st->st_string_pool &&
|
||||||
s < st->st_string_pool + st->st_string_pool_size);
|
s < st->st_string_pool + st->st_string_pool_size);
|
||||||
@ -102,7 +102,7 @@ static int
|
|||||||
elftc_string_table_add_to_pool(Elftc_String_Table *st, const char *string)
|
elftc_string_table_add_to_pool(Elftc_String_Table *st, const char *string)
|
||||||
{
|
{
|
||||||
char *newpool;
|
char *newpool;
|
||||||
int len, newsize, stlen;
|
size_t len, newsize, stlen;
|
||||||
|
|
||||||
len = strlen(string) + 1; /* length, including the trailing NUL */
|
len = strlen(string) + 1; /* length, including the trailing NUL */
|
||||||
stlen = ELFTC_STRING_TABLE_LENGTH(st);
|
stlen = ELFTC_STRING_TABLE_LENGTH(st);
|
||||||
@ -119,17 +119,17 @@ elftc_string_table_add_to_pool(Elftc_String_Table *st, const char *string)
|
|||||||
st->st_string_pool_size = newsize;
|
st->st_string_pool_size = newsize;
|
||||||
}
|
}
|
||||||
|
|
||||||
strcpy(st->st_string_pool + stlen, string);
|
memcpy(st->st_string_pool + stlen, string, len);
|
||||||
ELFTC_STRING_TABLE_UPDATE_LENGTH(st, stlen + len);
|
ELFTC_STRING_TABLE_UPDATE_LENGTH(st, stlen + len);
|
||||||
|
|
||||||
return (stlen);
|
return (stlen);
|
||||||
}
|
}
|
||||||
|
|
||||||
Elftc_String_Table *
|
Elftc_String_Table *
|
||||||
elftc_string_table_create(int sizehint)
|
elftc_string_table_create(size_t sizehint)
|
||||||
{
|
{
|
||||||
int n, nbuckets, tablesize;
|
|
||||||
struct _Elftc_String_Table *st;
|
struct _Elftc_String_Table *st;
|
||||||
|
int n, nbuckets, tablesize;
|
||||||
|
|
||||||
if (sizehint < ELFTC_STRING_TABLE_DEFAULT_SIZE)
|
if (sizehint < ELFTC_STRING_TABLE_DEFAULT_SIZE)
|
||||||
sizehint = ELFTC_STRING_TABLE_DEFAULT_SIZE;
|
sizehint = ELFTC_STRING_TABLE_DEFAULT_SIZE;
|
||||||
@ -167,21 +167,19 @@ elftc_string_table_destroy(Elftc_String_Table *st)
|
|||||||
|
|
||||||
for (n = 0; n < st->st_nbuckets; n++)
|
for (n = 0; n < st->st_nbuckets; n++)
|
||||||
SLIST_FOREACH_SAFE(s, &st->st_buckets[n], ste_next, t)
|
SLIST_FOREACH_SAFE(s, &st->st_buckets[n], ste_next, t)
|
||||||
free(s);
|
free(s);
|
||||||
free(st->st_string_pool);
|
free(st->st_string_pool);
|
||||||
free(st);
|
free(st);
|
||||||
|
|
||||||
return;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
Elftc_String_Table *
|
Elftc_String_Table *
|
||||||
elftc_string_table_from_section(Elf_Scn *scn, int sizehint)
|
elftc_string_table_from_section(Elf_Scn *scn, size_t sizehint)
|
||||||
{
|
{
|
||||||
int len;
|
|
||||||
Elf_Data *d;
|
Elf_Data *d;
|
||||||
GElf_Shdr sh;
|
GElf_Shdr sh;
|
||||||
const char *s, *end;
|
const char *s, *end;
|
||||||
Elftc_String_Table *st;
|
Elftc_String_Table *st;
|
||||||
|
size_t len;
|
||||||
|
|
||||||
/* Verify the type of the section passed in. */
|
/* Verify the type of the section passed in. */
|
||||||
if (gelf_getshdr(scn, &sh) == NULL ||
|
if (gelf_getshdr(scn, &sh) == NULL ||
|
||||||
@ -237,7 +235,8 @@ elftc_string_table_image(Elftc_String_Table *st, size_t *size)
|
|||||||
char *r, *s, *end;
|
char *r, *s, *end;
|
||||||
struct _Elftc_String_Table_Entry *ste;
|
struct _Elftc_String_Table_Entry *ste;
|
||||||
struct _Elftc_String_Table_Bucket *head;
|
struct _Elftc_String_Table_Bucket *head;
|
||||||
int copied, hashindex, offset, length, newsize;
|
size_t copied, offset, length, newsize;
|
||||||
|
int hashindex;
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* For the common case of a string table has not seen
|
* For the common case of a string table has not seen
|
||||||
@ -305,8 +304,9 @@ elftc_string_table_image(Elftc_String_Table *st, size_t *size)
|
|||||||
size_t
|
size_t
|
||||||
elftc_string_table_insert(Elftc_String_Table *st, const char *string)
|
elftc_string_table_insert(Elftc_String_Table *st, const char *string)
|
||||||
{
|
{
|
||||||
int hashindex, idx;
|
|
||||||
struct _Elftc_String_Table_Entry *ste;
|
struct _Elftc_String_Table_Entry *ste;
|
||||||
|
ssize_t idx;
|
||||||
|
int hashindex;
|
||||||
|
|
||||||
hashindex = 0;
|
hashindex = 0;
|
||||||
|
|
||||||
@ -318,7 +318,7 @@ elftc_string_table_insert(Elftc_String_Table *st, const char *string)
|
|||||||
if ((ste = malloc(sizeof(*ste))) == NULL)
|
if ((ste = malloc(sizeof(*ste))) == NULL)
|
||||||
return (0);
|
return (0);
|
||||||
if ((ste->ste_idx = elftc_string_table_add_to_pool(st,
|
if ((ste->ste_idx = elftc_string_table_add_to_pool(st,
|
||||||
string)) == 0) {
|
string)) == 0) {
|
||||||
free(ste);
|
free(ste);
|
||||||
return (0);
|
return (0);
|
||||||
}
|
}
|
||||||
@ -328,7 +328,7 @@ elftc_string_table_insert(Elftc_String_Table *st, const char *string)
|
|||||||
|
|
||||||
idx = ste->ste_idx;
|
idx = ste->ste_idx;
|
||||||
if (idx < 0) /* Undelete. */
|
if (idx < 0) /* Undelete. */
|
||||||
ste->ste_idx = idx = (- idx);
|
ste->ste_idx = idx = -idx;
|
||||||
|
|
||||||
return (idx);
|
return (idx);
|
||||||
}
|
}
|
||||||
@ -336,8 +336,9 @@ elftc_string_table_insert(Elftc_String_Table *st, const char *string)
|
|||||||
size_t
|
size_t
|
||||||
elftc_string_table_lookup(Elftc_String_Table *st, const char *string)
|
elftc_string_table_lookup(Elftc_String_Table *st, const char *string)
|
||||||
{
|
{
|
||||||
int hashindex, idx;
|
|
||||||
struct _Elftc_String_Table_Entry *ste;
|
struct _Elftc_String_Table_Entry *ste;
|
||||||
|
ssize_t idx;
|
||||||
|
int hashindex;
|
||||||
|
|
||||||
ste = elftc_string_table_find_hash_entry(st, string, &hashindex);
|
ste = elftc_string_table_find_hash_entry(st, string, &hashindex);
|
||||||
|
|
||||||
@ -352,17 +353,17 @@ elftc_string_table_lookup(Elftc_String_Table *st, const char *string)
|
|||||||
int
|
int
|
||||||
elftc_string_table_remove(Elftc_String_Table *st, const char *string)
|
elftc_string_table_remove(Elftc_String_Table *st, const char *string)
|
||||||
{
|
{
|
||||||
int idx;
|
|
||||||
struct _Elftc_String_Table_Entry *ste;
|
struct _Elftc_String_Table_Entry *ste;
|
||||||
|
ssize_t idx;
|
||||||
|
|
||||||
ste = elftc_string_table_find_hash_entry(st, string, NULL);
|
ste = elftc_string_table_find_hash_entry(st, string, NULL);
|
||||||
|
|
||||||
if (ste == NULL || (idx = ste->ste_idx) < 0)
|
if (ste == NULL || (idx = ste->ste_idx) < 0)
|
||||||
return (ELFTC_FAILURE);
|
return (ELFTC_FAILURE);
|
||||||
|
|
||||||
assert(idx > 0 && idx < (int) ELFTC_STRING_TABLE_LENGTH(st));
|
assert(idx > 0 && (size_t)idx < ELFTC_STRING_TABLE_LENGTH(st));
|
||||||
|
|
||||||
ste->ste_idx = (- idx);
|
ste->ste_idx = -idx;
|
||||||
|
|
||||||
ELFTC_STRING_TABLE_SET_COMPACTION_FLAG(st);
|
ELFTC_STRING_TABLE_SET_COMPACTION_FLAG(st);
|
||||||
|
|
||||||
|
@ -22,9 +22,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: elftc_string_table_create.3 3645 2018-10-15 20:17:14Z jkoshy $
|
.\" $Id: elftc_string_table_create.3 3750 2019-06-28 01:12:10Z emaste $
|
||||||
.\"
|
.\"
|
||||||
.Dd January 5, 2013
|
.Dd June 27, 2019
|
||||||
.Dt ELFTC_STRING_TABLE_CREATE 3
|
.Dt ELFTC_STRING_TABLE_CREATE 3
|
||||||
.Os
|
.Os
|
||||||
.Sh NAME
|
.Sh NAME
|
||||||
@ -40,11 +40,11 @@
|
|||||||
.Sh SYNOPSIS
|
.Sh SYNOPSIS
|
||||||
.In libelftc.h
|
.In libelftc.h
|
||||||
.Ft "Elftc_String_Table *"
|
.Ft "Elftc_String_Table *"
|
||||||
.Fn elftc_string_table_create "int sizehint"
|
.Fn elftc_string_table_create "size_t sizehint"
|
||||||
.Ft int
|
.Ft void
|
||||||
.Fn elftc_string_table_destroy "Elftc_String_Table *table"
|
.Fn elftc_string_table_destroy "Elftc_String_Table *table"
|
||||||
.Ft "Elftc_String_Table *"
|
.Ft "Elftc_String_Table *"
|
||||||
.Fn elftc_string_table_from_section "Elf_Scn *scn" "int sizehint"
|
.Fn elftc_string_table_from_section "Elf_Scn *scn" "size_t sizehint"
|
||||||
.Ft "const char *"
|
.Ft "const char *"
|
||||||
.Fo elftc_string_table_image
|
.Fo elftc_string_table_image
|
||||||
.Fa "Elftc_String_Table *table"
|
.Fa "Elftc_String_Table *table"
|
||||||
@ -144,7 +144,7 @@ looks up the string referenced by argument
|
|||||||
in the string table specified by argument
|
in the string table specified by argument
|
||||||
.Ar table ,
|
.Ar table ,
|
||||||
and if found, returns the offset associated with the string.
|
and if found, returns the offset associated with the string.
|
||||||
The returned offset will be valid till the next call to function
|
The returned offset will be valid until the next call to
|
||||||
.Fn elftc_string_table_image .
|
.Fn elftc_string_table_image .
|
||||||
.Pp
|
.Pp
|
||||||
Function
|
Function
|
||||||
|
@ -24,7 +24,7 @@
|
|||||||
* THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
* THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||||
*
|
*
|
||||||
* $FreeBSD: users/kaiwang27/elftc/libelftc.h 392 2009-05-31 19:17:46Z kaiwang27 $
|
* $FreeBSD: users/kaiwang27/elftc/libelftc.h 392 2009-05-31 19:17:46Z kaiwang27 $
|
||||||
* $Id: libelftc.h 3489 2016-08-31 00:12:15Z emaste $
|
* $Id: libelftc.h 3744 2019-06-28 00:41:47Z emaste $
|
||||||
*/
|
*/
|
||||||
|
|
||||||
#ifndef _LIBELFTC_H_
|
#ifndef _LIBELFTC_H_
|
||||||
@ -77,10 +77,10 @@ int elftc_demangle(const char *_mangledname, char *_buffer,
|
|||||||
size_t _bufsize, unsigned int _flags);
|
size_t _bufsize, unsigned int _flags);
|
||||||
const char *elftc_reloc_type_str(unsigned int mach, unsigned int type);
|
const char *elftc_reloc_type_str(unsigned int mach, unsigned int type);
|
||||||
int elftc_set_timestamps(const char *_filename, struct stat *_sb);
|
int elftc_set_timestamps(const char *_filename, struct stat *_sb);
|
||||||
Elftc_String_Table *elftc_string_table_create(int _hint);
|
Elftc_String_Table *elftc_string_table_create(size_t _sizehint);
|
||||||
void elftc_string_table_destroy(Elftc_String_Table *_table);
|
void elftc_string_table_destroy(Elftc_String_Table *_table);
|
||||||
Elftc_String_Table *elftc_string_table_from_section(Elf_Scn *_scn,
|
Elftc_String_Table *elftc_string_table_from_section(Elf_Scn *_scn,
|
||||||
int _hint);
|
size_t _sizehint);
|
||||||
const char *elftc_string_table_image(Elftc_String_Table *_table,
|
const char *elftc_string_table_image(Elftc_String_Table *_table,
|
||||||
size_t *_sz);
|
size_t *_sz);
|
||||||
size_t elftc_string_table_insert(Elftc_String_Table *_table,
|
size_t elftc_string_table_insert(Elftc_String_Table *_table,
|
||||||
|
@ -30,7 +30,7 @@
|
|||||||
|
|
||||||
#include "_libelftc.h"
|
#include "_libelftc.h"
|
||||||
|
|
||||||
ELFTC_VCSID("$Id: libelftc_bfdtarget.c 3516 2017-02-10 02:33:08Z emaste $");
|
ELFTC_VCSID("$Id: libelftc_bfdtarget.c 3752 2019-06-28 01:12:53Z emaste $");
|
||||||
|
|
||||||
struct _Elftc_Bfd_Target _libelftc_targets[] = {
|
struct _Elftc_Bfd_Target _libelftc_targets[] = {
|
||||||
|
|
||||||
@ -315,6 +315,31 @@ struct _Elftc_Bfd_Target _libelftc_targets[] = {
|
|||||||
.bt_machine = EM_PPC64,
|
.bt_machine = EM_PPC64,
|
||||||
},
|
},
|
||||||
|
|
||||||
|
{
|
||||||
|
.bt_name = "elf32-riscv",
|
||||||
|
.bt_type = ETF_ELF,
|
||||||
|
.bt_byteorder = ELFDATA2LSB,
|
||||||
|
.bt_elfclass = ELFCLASS32,
|
||||||
|
.bt_machine = EM_RISCV,
|
||||||
|
},
|
||||||
|
|
||||||
|
{
|
||||||
|
.bt_name = "elf64-riscv",
|
||||||
|
.bt_type = ETF_ELF,
|
||||||
|
.bt_byteorder = ELFDATA2LSB,
|
||||||
|
.bt_elfclass = ELFCLASS64,
|
||||||
|
.bt_machine = EM_RISCV,
|
||||||
|
},
|
||||||
|
|
||||||
|
{
|
||||||
|
.bt_name = "elf64-riscv-freebsd",
|
||||||
|
.bt_type = ETF_ELF,
|
||||||
|
.bt_byteorder = ELFDATA2MSB,
|
||||||
|
.bt_elfclass = ELFCLASS64,
|
||||||
|
.bt_machine = EM_RISCV,
|
||||||
|
.bt_osabi = ELFOSABI_FREEBSD,
|
||||||
|
},
|
||||||
|
|
||||||
{
|
{
|
||||||
.bt_name = "elf64-sh64",
|
.bt_name = "elf64-sh64",
|
||||||
.bt_type = ETF_ELF,
|
.bt_type = ETF_ELF,
|
||||||
|
@ -3,7 +3,7 @@
|
|||||||
# This script generates a project-wide version identifier for use by
|
# This script generates a project-wide version identifier for use by
|
||||||
# the `elftc_version()' API.
|
# the `elftc_version()' API.
|
||||||
#
|
#
|
||||||
# $Id: make-toolchain-version 3414 2016-02-16 22:55:28Z jkoshy $
|
# $Id: make-toolchain-version 3731 2019-04-06 14:28:34Z jkoshy $
|
||||||
|
|
||||||
#
|
#
|
||||||
# Defaults.
|
# Defaults.
|
||||||
@ -33,6 +33,32 @@ usage()
|
|||||||
exit 1
|
exit 1
|
||||||
}
|
}
|
||||||
|
|
||||||
|
# Determine the revision number for the source tree.
|
||||||
|
#
|
||||||
|
# - If CVS is detected, we use the string `unknown'.
|
||||||
|
# - If SVN is detected, we use the `svninfo' tool to determine the
|
||||||
|
# in-tree revision number.
|
||||||
|
# - Otherwise, we use `git --describe'.
|
||||||
|
get_revision_string()
|
||||||
|
{
|
||||||
|
v="unknown:unknown"
|
||||||
|
if [ -d CVS ]; then # Look for CVS (NetBSD).
|
||||||
|
v="cvs:unknown"
|
||||||
|
elif [ -d .svn ]; then # An SVN checkout (SourceForge or FreeBSD).
|
||||||
|
svnversion="$(svnversion 2>/dev/null)"
|
||||||
|
if [ -n "${svnversion}" ]; then
|
||||||
|
v="svn:${svnversion}"
|
||||||
|
fi
|
||||||
|
else # Try git (DragonflyBSD).
|
||||||
|
gitversion="$(git describe --all --dirty --long 2> /dev/null)"
|
||||||
|
if [ -n "${gitversion}" ]; then
|
||||||
|
v="git:${gitversion}"
|
||||||
|
fi
|
||||||
|
fi
|
||||||
|
|
||||||
|
echo "${v}"
|
||||||
|
}
|
||||||
|
|
||||||
#
|
#
|
||||||
# Parse options.
|
# Parse options.
|
||||||
#
|
#
|
||||||
@ -51,37 +77,14 @@ done
|
|||||||
|
|
||||||
[ -n "${top}" ] || usage
|
[ -n "${top}" ] || usage
|
||||||
|
|
||||||
# Try to determine the in-tree revision number.
|
|
||||||
#
|
|
||||||
# This script attempts to handle the case where our sources have been
|
|
||||||
# incorporated into an operating system's base sources.
|
|
||||||
#
|
|
||||||
# - If SVN is detected, we use the `svninfo' tool to determine the
|
|
||||||
# in-tree revision number.
|
|
||||||
# - If CVS is detected, we use the string `unknown'.
|
|
||||||
# - Otherwise, we use `git --describe'.
|
|
||||||
|
|
||||||
curdir=`pwd`
|
curdir=`pwd`
|
||||||
cd ${top} || usage "ERROR: Cannot change directory to \"${top}\"."
|
cd ${top} || usage "ERROR: Cannot change directory to \"${top}\"."
|
||||||
|
|
||||||
if [ -d CVS ]; then # Look for CVS (NetBSD).
|
# Determine the in-tree revision number.
|
||||||
versionstring=" cvs:unknown"
|
versionstring="$(get_revision_string)" || {
|
||||||
else # Try git (DragonFlyBSD).
|
echo "ERROR: cannot determine a revision number." 1>&2;
|
||||||
gitversion="$(git describe --all --dirty --long 2> /dev/null)"
|
|
||||||
if [ -n "${gitversion}" ]; then
|
|
||||||
versionstring=" git:${gitversion}"
|
|
||||||
else # Assume an SVN checkout (SourceForge or FreeBSD).
|
|
||||||
svnversion="$(svnversion)"
|
|
||||||
if [ -n "${svnversion}" ]; then
|
|
||||||
versionstring=" svn:$(svnversion)"
|
|
||||||
fi
|
|
||||||
fi
|
|
||||||
fi
|
|
||||||
|
|
||||||
if [ -z "${versionstring}" ]; then
|
|
||||||
echo "ERROR: cannot determine a revision number." 1>&2
|
|
||||||
exit 1
|
exit 1
|
||||||
fi
|
}
|
||||||
|
|
||||||
cd ${curdir} || usage "Cannot change back to ${curdir}."
|
cd ${curdir} || usage "Cannot change back to ${curdir}."
|
||||||
|
|
||||||
@ -100,7 +103,7 @@ cat > ${tmpfile} <<EOF
|
|||||||
const char *
|
const char *
|
||||||
elftc_version(void)
|
elftc_version(void)
|
||||||
{
|
{
|
||||||
return "${elftcname} ${version} ${buildhost}${versionstring}";
|
return "${elftcname} ${version} ${buildhost} ${versionstring}";
|
||||||
}
|
}
|
||||||
EOF
|
EOF
|
||||||
|
|
||||||
|
@ -1,6 +1,6 @@
|
|||||||
#
|
#
|
||||||
# Rules for recursing into directories
|
# Rules for recursing into directories
|
||||||
# $Id: elftoolchain.subdir.mk 3608 2018-04-14 21:23:04Z jkoshy $
|
# $Id: elftoolchain.subdir.mk 3720 2019-03-23 08:40:59Z jkoshy $
|
||||||
|
|
||||||
# Pass down 'test' as a valid target.
|
# Pass down 'test' as a valid target.
|
||||||
|
|
||||||
@ -9,7 +9,7 @@
|
|||||||
.if ${OS_HOST} == FreeBSD
|
.if ${OS_HOST} == FreeBSD
|
||||||
SUBDIR_TARGETS+= clobber test
|
SUBDIR_TARGETS+= clobber test
|
||||||
.elif ${OS_HOST} == OpenBSD
|
.elif ${OS_HOST} == OpenBSD
|
||||||
clobber test:: _SUBDIRUSE
|
clobber: _SUBDIRUSE
|
||||||
.else # NetBSD, pmake on Linux
|
.else # NetBSD, pmake on Linux
|
||||||
TARGETS+= cleandepend clobber test
|
TARGETS+= cleandepend clobber test
|
||||||
.endif
|
.endif
|
||||||
|
@ -8,9 +8,8 @@
|
|||||||
.endif
|
.endif
|
||||||
|
|
||||||
TEST_BASE= $(TOP)/test/libtest
|
TEST_BASE= $(TOP)/test/libtest
|
||||||
TEST_LIB= $(TEST_BASE)/lib
|
TEST_LIB= $(TEST_BASE)/lib # The test(3) API.
|
||||||
TEST_DRIVER= ${TEST_BASE}/driver
|
TEST_DRIVER= ${TEST_BASE}/driver # A command-line driver for tests.
|
||||||
TEST_DRIVER_MAIN= $(TEST_DRIVER)/test_main.o
|
|
||||||
|
|
||||||
CFLAGS+= -I$(TEST_LIB) -I${TEST_DRIVER}
|
CFLAGS+= -I$(TEST_LIB) -I${TEST_DRIVER}
|
||||||
|
|
||||||
@ -29,7 +28,7 @@ _M4_SRCS= ${TEST_SRCS:M*.m4}
|
|||||||
SRCS= ${_C_SRCS} ${_M4_SRCS} # See <bsd.prog.mk>
|
SRCS= ${_C_SRCS} ${_M4_SRCS} # See <bsd.prog.mk>
|
||||||
CLEANFILES+= ${_M4_SRCS:S/.m4$/.c/g} ${TEST_DATA}
|
CLEANFILES+= ${_M4_SRCS:S/.m4$/.c/g} ${TEST_DATA}
|
||||||
|
|
||||||
${PROG}: ${TEST_DATA} ${TEST_LIB} ${TEST_DRIVER_MAIN}
|
${PROG}: ${TEST_DATA}
|
||||||
|
|
||||||
.if defined(MAKE_TEST_SCAFFOLDING) && ${MAKE_TEST_SCAFFOLDING} == "yes"
|
.if defined(MAKE_TEST_SCAFFOLDING) && ${MAKE_TEST_SCAFFOLDING} == "yes"
|
||||||
_TC_SRC= ${.OBJDIR}/tc.c # Test scaffolding.
|
_TC_SRC= ${.OBJDIR}/tc.c # Test scaffolding.
|
||||||
@ -45,6 +44,6 @@ ${_TC_SRC}: ${_TEST_OBJS}
|
|||||||
.endif
|
.endif
|
||||||
.endif
|
.endif
|
||||||
|
|
||||||
LDADD+= ${TEST_DRIVER_MAIN} -L${TEST_LIB} -ltest
|
LDADD+= -L${TEST_LIB} -ltest -L${TEST_DRIVER} -ldriver
|
||||||
|
|
||||||
.include "${TOP}/mk/elftoolchain.prog.mk"
|
.include "${TOP}/mk/elftoolchain.prog.mk"
|
||||||
|
5
nm/nm.c
5
nm/nm.c
@ -48,7 +48,7 @@
|
|||||||
|
|
||||||
#include "_elftc.h"
|
#include "_elftc.h"
|
||||||
|
|
||||||
ELFTC_VCSID("$Id: nm.c 3504 2016-12-17 15:33:16Z kaiwang27 $");
|
ELFTC_VCSID("$Id: nm.c 3722 2019-03-23 17:01:58Z jkoshy $");
|
||||||
|
|
||||||
/* symbol information list */
|
/* symbol information list */
|
||||||
STAILQ_HEAD(sym_head, sym_entry);
|
STAILQ_HEAD(sym_head, sym_entry);
|
||||||
@ -1143,7 +1143,6 @@ read_elf(Elf *elf, const char *filename, Elf_Kind kind)
|
|||||||
Elf_Arhdr *arhdr;
|
Elf_Arhdr *arhdr;
|
||||||
Elf_Scn *scn;
|
Elf_Scn *scn;
|
||||||
GElf_Shdr shdr;
|
GElf_Shdr shdr;
|
||||||
GElf_Half i;
|
|
||||||
Dwarf_Line *lbuf;
|
Dwarf_Line *lbuf;
|
||||||
Dwarf_Unsigned lineno;
|
Dwarf_Unsigned lineno;
|
||||||
Dwarf_Signed lcount, filecount;
|
Dwarf_Signed lcount, filecount;
|
||||||
@ -1158,7 +1157,7 @@ read_elf(Elf *elf, const char *filename, Elf_Kind kind)
|
|||||||
struct var_info_entry *var;
|
struct var_info_entry *var;
|
||||||
const char *shname, *objname;
|
const char *shname, *objname;
|
||||||
char *type_table, **sec_table, *sfile, **src_files;
|
char *type_table, **sec_table, *sfile, **src_files;
|
||||||
size_t shstrndx, shnum, dynndx, strndx;
|
size_t i, shstrndx, shnum, dynndx, strndx;
|
||||||
int ret, rtn, e_err;
|
int ret, rtn, e_err;
|
||||||
|
|
||||||
#define OBJNAME (objname == NULL ? filename : objname)
|
#define OBJNAME (objname == NULL ? filename : objname)
|
||||||
|
@ -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: readelf.1 3642 2018-10-14 14:24:28Z jkoshy $
|
.\" $Id: readelf.1 3753 2019-06-28 01:13:13Z emaste $
|
||||||
.\"
|
.\"
|
||||||
.Dd September 13, 2012
|
.Dd June 27, 2019
|
||||||
.Dt READELF 1
|
.Dt READELF 1
|
||||||
.Os
|
.Os
|
||||||
.Sh NAME
|
.Sh NAME
|
||||||
@ -113,6 +113,8 @@ Print symbol tables.
|
|||||||
.It Fl t | Fl -section-details
|
.It Fl t | Fl -section-details
|
||||||
Print additional information about sections, such as the flags
|
Print additional information about sections, such as the flags
|
||||||
fields in section headers.
|
fields in section headers.
|
||||||
|
Implies
|
||||||
|
.Fl S .
|
||||||
.It Fl v | Fl -version
|
.It Fl v | Fl -version
|
||||||
Prints a version identifier for
|
Prints a version identifier for
|
||||||
.Nm
|
.Nm
|
||||||
|
@ -47,7 +47,7 @@
|
|||||||
|
|
||||||
#include "_elftc.h"
|
#include "_elftc.h"
|
||||||
|
|
||||||
ELFTC_VCSID("$Id: readelf.c 3649 2018-11-24 03:26:23Z emaste $");
|
ELFTC_VCSID("$Id: readelf.c 3769 2019-06-29 15:15:02Z emaste $");
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* readelf(1) options.
|
* readelf(1) options.
|
||||||
@ -206,6 +206,11 @@ struct eflags_desc {
|
|||||||
const char *desc;
|
const char *desc;
|
||||||
};
|
};
|
||||||
|
|
||||||
|
struct flag_desc {
|
||||||
|
uint64_t flag;
|
||||||
|
const char *desc;
|
||||||
|
};
|
||||||
|
|
||||||
struct mips_option {
|
struct mips_option {
|
||||||
uint64_t flag;
|
uint64_t flag;
|
||||||
const char *desc;
|
const char *desc;
|
||||||
@ -284,6 +289,7 @@ static void dump_dwarf_ranges_foreach(struct readelf *re, Dwarf_Die die,
|
|||||||
static void dump_dwarf_str(struct readelf *re);
|
static void dump_dwarf_str(struct readelf *re);
|
||||||
static void dump_eflags(struct readelf *re, uint64_t e_flags);
|
static void dump_eflags(struct readelf *re, uint64_t e_flags);
|
||||||
static void dump_elf(struct readelf *re);
|
static void dump_elf(struct readelf *re);
|
||||||
|
static void dump_flags(struct flag_desc *fd, uint64_t flags);
|
||||||
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);
|
||||||
@ -298,6 +304,8 @@ static void dump_mips_specific_info(struct readelf *re);
|
|||||||
static void dump_notes(struct readelf *re);
|
static void dump_notes(struct readelf *re);
|
||||||
static void dump_notes_content(struct readelf *re, const char *buf, size_t sz,
|
static void dump_notes_content(struct readelf *re, const char *buf, size_t sz,
|
||||||
off_t off);
|
off_t off);
|
||||||
|
static void dump_notes_data(const char *name, uint32_t type, const char *buf,
|
||||||
|
size_t sz);
|
||||||
static void dump_svr4_hash(struct section *s);
|
static void dump_svr4_hash(struct section *s);
|
||||||
static void dump_svr4_hash64(struct readelf *re, struct section *s);
|
static void dump_svr4_hash64(struct readelf *re, struct section *s);
|
||||||
static void dump_gnu_hash(struct readelf *re, struct section *s);
|
static void dump_gnu_hash(struct readelf *re, struct section *s);
|
||||||
@ -1184,6 +1192,7 @@ note_type_gnu(unsigned int nt)
|
|||||||
case 2: return "NT_GNU_HWCAP (Hardware capabilities)";
|
case 2: return "NT_GNU_HWCAP (Hardware capabilities)";
|
||||||
case 3: return "NT_GNU_BUILD_ID (Build id set by ld(1))";
|
case 3: return "NT_GNU_BUILD_ID (Build id set by ld(1))";
|
||||||
case 4: return "NT_GNU_GOLD_VERSION (GNU gold version)";
|
case 4: return "NT_GNU_GOLD_VERSION (GNU gold version)";
|
||||||
|
case 5: return "NT_GNU_PROPERTY_TYPE_0";
|
||||||
default: return (note_type_unknown(nt));
|
default: return (note_type_unknown(nt));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -2261,8 +2270,15 @@ dump_eflags(struct readelf *re, uint64_t e_flags)
|
|||||||
}
|
}
|
||||||
edesc = mips_eflags_desc;
|
edesc = mips_eflags_desc;
|
||||||
break;
|
break;
|
||||||
case EM_PPC:
|
|
||||||
case EM_PPC64:
|
case EM_PPC64:
|
||||||
|
switch (e_flags) {
|
||||||
|
case 0: printf(", Unspecified or Power ELF V1 ABI"); break;
|
||||||
|
case 1: printf(", Power ELF V1 ABI"); break;
|
||||||
|
case 2: printf(", OpenPOWER ELF V2 ABI"); break;
|
||||||
|
default: break;
|
||||||
|
}
|
||||||
|
/* FALLTHROUGH */
|
||||||
|
case EM_PPC:
|
||||||
edesc = powerpc_eflags_desc;
|
edesc = powerpc_eflags_desc;
|
||||||
break;
|
break;
|
||||||
case EM_SPARC:
|
case EM_SPARC:
|
||||||
@ -2713,6 +2729,59 @@ dump_arch_dyn_val(struct readelf *re, GElf_Dyn *dyn)
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static void
|
||||||
|
dump_flags(struct flag_desc *desc, uint64_t val)
|
||||||
|
{
|
||||||
|
struct flag_desc *fd;
|
||||||
|
|
||||||
|
for (fd = desc; fd->flag != 0; fd++) {
|
||||||
|
if (val & fd->flag) {
|
||||||
|
val &= ~fd->flag;
|
||||||
|
printf(" %s", fd->desc);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
if (val != 0)
|
||||||
|
printf(" unknown (0x%jx)", (uintmax_t)val);
|
||||||
|
printf("\n");
|
||||||
|
}
|
||||||
|
|
||||||
|
static struct flag_desc dt_flags[] = {
|
||||||
|
{ DF_ORIGIN, "ORIGIN" },
|
||||||
|
{ DF_SYMBOLIC, "SYMBOLIC" },
|
||||||
|
{ DF_TEXTREL, "TEXTREL" },
|
||||||
|
{ DF_BIND_NOW, "BIND_NOW" },
|
||||||
|
{ DF_STATIC_TLS, "STATIC_TLS" },
|
||||||
|
{ 0, NULL }
|
||||||
|
};
|
||||||
|
|
||||||
|
static struct flag_desc dt_flags_1[] = {
|
||||||
|
{ DF_1_BIND_NOW, "NOW" },
|
||||||
|
{ DF_1_GLOBAL, "GLOBAL" },
|
||||||
|
{ 0x4, "GROUP" },
|
||||||
|
{ DF_1_NODELETE, "NODELETE" },
|
||||||
|
{ DF_1_LOADFLTR, "LOADFLTR" },
|
||||||
|
{ 0x20, "INITFIRST" },
|
||||||
|
{ DF_1_NOOPEN, "NOOPEN" },
|
||||||
|
{ DF_1_ORIGIN, "ORIGIN" },
|
||||||
|
{ 0x100, "DIRECT" },
|
||||||
|
{ DF_1_INTERPOSE, "INTERPOSE" },
|
||||||
|
{ DF_1_NODEFLIB, "NODEFLIB" },
|
||||||
|
{ 0x1000, "NODUMP" },
|
||||||
|
{ 0x2000, "CONFALT" },
|
||||||
|
{ 0x4000, "ENDFILTEE" },
|
||||||
|
{ 0x8000, "DISPRELDNE" },
|
||||||
|
{ 0x10000, "DISPRELPND" },
|
||||||
|
{ 0x20000, "NODIRECT" },
|
||||||
|
{ 0x40000, "IGNMULDEF" },
|
||||||
|
{ 0x80000, "NOKSYMS" },
|
||||||
|
{ 0x100000, "NOHDR" },
|
||||||
|
{ 0x200000, "EDITED" },
|
||||||
|
{ 0x400000, "NORELOC" },
|
||||||
|
{ 0x800000, "SYMINTPOSE" },
|
||||||
|
{ 0x1000000, "GLOBAUDIT" },
|
||||||
|
{ 0, NULL }
|
||||||
|
};
|
||||||
|
|
||||||
static void
|
static void
|
||||||
dump_dyn_val(struct readelf *re, GElf_Dyn *dyn, uint32_t stab)
|
dump_dyn_val(struct readelf *re, GElf_Dyn *dyn, uint32_t stab)
|
||||||
{
|
{
|
||||||
@ -2760,6 +2829,7 @@ dump_dyn_val(struct readelf *re, GElf_Dyn *dyn, uint32_t stab)
|
|||||||
case DT_SYMENT:
|
case DT_SYMENT:
|
||||||
case DT_RELSZ:
|
case DT_RELSZ:
|
||||||
case DT_RELENT:
|
case DT_RELENT:
|
||||||
|
case DT_PREINIT_ARRAYSZ:
|
||||||
case DT_INIT_ARRAYSZ:
|
case DT_INIT_ARRAYSZ:
|
||||||
case DT_FINI_ARRAYSZ:
|
case DT_FINI_ARRAYSZ:
|
||||||
case DT_GNU_CONFLICTSZ:
|
case DT_GNU_CONFLICTSZ:
|
||||||
@ -2796,6 +2866,12 @@ dump_dyn_val(struct readelf *re, GElf_Dyn *dyn, uint32_t stab)
|
|||||||
case DT_GNU_PRELINKED:
|
case DT_GNU_PRELINKED:
|
||||||
printf(" %s\n", timestamp(dyn->d_un.d_val));
|
printf(" %s\n", timestamp(dyn->d_un.d_val));
|
||||||
break;
|
break;
|
||||||
|
case DT_FLAGS:
|
||||||
|
dump_flags(dt_flags, dyn->d_un.d_val);
|
||||||
|
break;
|
||||||
|
case DT_FLAGS_1:
|
||||||
|
dump_flags(dt_flags_1, dyn->d_un.d_val);
|
||||||
|
break;
|
||||||
default:
|
default:
|
||||||
printf("\n");
|
printf("\n");
|
||||||
}
|
}
|
||||||
@ -3414,6 +3490,52 @@ dump_notes(struct readelf *re)
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static struct flag_desc note_feature_ctl_flags[] = {
|
||||||
|
{ 0x1, "ASLR_DISABLE" },
|
||||||
|
{ 0, NULL }
|
||||||
|
};
|
||||||
|
|
||||||
|
static void
|
||||||
|
dump_notes_data(const char *name, uint32_t type, const char *buf, size_t sz)
|
||||||
|
{
|
||||||
|
size_t i;
|
||||||
|
const uint32_t *ubuf;
|
||||||
|
|
||||||
|
/* Note data is at least 4-byte aligned. */
|
||||||
|
if (((uintptr_t)buf & 3) != 0) {
|
||||||
|
warnx("bad note data alignment");
|
||||||
|
goto unknown;
|
||||||
|
}
|
||||||
|
ubuf = (const uint32_t *)(const void *)buf;
|
||||||
|
|
||||||
|
if (strcmp(name, "FreeBSD") == 0) {
|
||||||
|
switch (type) {
|
||||||
|
case NT_FREEBSD_ABI_TAG:
|
||||||
|
if (sz != 4)
|
||||||
|
goto unknown;
|
||||||
|
printf(" ABI tag: %u\n", ubuf[0]);
|
||||||
|
return;
|
||||||
|
/* NT_FREEBSD_NOINIT_TAG carries no data, treat as unknown. */
|
||||||
|
case NT_FREEBSD_ARCH_TAG:
|
||||||
|
if (sz != 4)
|
||||||
|
goto unknown;
|
||||||
|
printf(" Arch tag: %x\n", ubuf[0]);
|
||||||
|
return;
|
||||||
|
case NT_FREEBSD_FEATURE_CTL:
|
||||||
|
if (sz != 4)
|
||||||
|
goto unknown;
|
||||||
|
printf(" Features:");
|
||||||
|
dump_flags(note_feature_ctl_flags, ubuf[0]);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
unknown:
|
||||||
|
printf(" description data:");
|
||||||
|
for (i = 0; i < sz; i++)
|
||||||
|
printf(" %02x", (unsigned char)buf[i]);
|
||||||
|
printf("\n");
|
||||||
|
}
|
||||||
|
|
||||||
static void
|
static void
|
||||||
dump_notes_content(struct readelf *re, const char *buf, size_t sz, off_t off)
|
dump_notes_content(struct readelf *re, const char *buf, size_t sz, off_t off)
|
||||||
{
|
{
|
||||||
@ -3430,7 +3552,9 @@ dump_notes_content(struct readelf *re, const char *buf, size_t sz, off_t off)
|
|||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
note = (Elf_Note *)(uintptr_t) buf;
|
note = (Elf_Note *)(uintptr_t) buf;
|
||||||
name = (char *)(uintptr_t)(note + 1);
|
buf += sizeof(Elf_Note);
|
||||||
|
name = buf;
|
||||||
|
buf += roundup2(note->n_namesz, 4);
|
||||||
/*
|
/*
|
||||||
* The name field is required to be nul-terminated, and
|
* The name field is required to be nul-terminated, and
|
||||||
* n_namesz includes the terminating nul in observed
|
* n_namesz includes the terminating nul in observed
|
||||||
@ -3448,8 +3572,8 @@ dump_notes_content(struct readelf *re, const char *buf, size_t sz, off_t off)
|
|||||||
printf(" %-13s %#010jx", name, (uintmax_t) note->n_descsz);
|
printf(" %-13s %#010jx", name, (uintmax_t) note->n_descsz);
|
||||||
printf(" %s\n", note_type(name, re->ehdr.e_type,
|
printf(" %s\n", note_type(name, re->ehdr.e_type,
|
||||||
note->n_type));
|
note->n_type));
|
||||||
buf += sizeof(Elf_Note) + roundup2(note->n_namesz, 4) +
|
dump_notes_data(name, note->n_type, buf, note->n_descsz);
|
||||||
roundup2(note->n_descsz, 4);
|
buf += roundup2(note->n_descsz, 4);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -6906,13 +7030,13 @@ dump_object(struct readelf *re)
|
|||||||
|
|
||||||
if ((re->elf = elf_begin(fd, ELF_C_READ, NULL)) == NULL) {
|
if ((re->elf = elf_begin(fd, ELF_C_READ, NULL)) == NULL) {
|
||||||
warnx("elf_begin() failed: %s", elf_errmsg(-1));
|
warnx("elf_begin() failed: %s", elf_errmsg(-1));
|
||||||
return;
|
goto done;
|
||||||
}
|
}
|
||||||
|
|
||||||
switch (elf_kind(re->elf)) {
|
switch (elf_kind(re->elf)) {
|
||||||
case ELF_K_NONE:
|
case ELF_K_NONE:
|
||||||
warnx("Not an ELF file.");
|
warnx("Not an ELF file.");
|
||||||
return;
|
goto done;
|
||||||
case ELF_K_ELF:
|
case ELF_K_ELF:
|
||||||
dump_elf(re);
|
dump_elf(re);
|
||||||
break;
|
break;
|
||||||
@ -6921,10 +7045,11 @@ dump_object(struct readelf *re)
|
|||||||
break;
|
break;
|
||||||
default:
|
default:
|
||||||
warnx("Internal: libelf returned unknown elf kind.");
|
warnx("Internal: libelf returned unknown elf kind.");
|
||||||
return;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
done:
|
||||||
elf_end(re->elf);
|
elf_end(re->elf);
|
||||||
|
close(fd);
|
||||||
}
|
}
|
||||||
|
|
||||||
static void
|
static void
|
||||||
@ -7345,7 +7470,7 @@ main(int argc, char **argv)
|
|||||||
re->options |= RE_S;
|
re->options |= RE_S;
|
||||||
break;
|
break;
|
||||||
case 't':
|
case 't':
|
||||||
re->options |= RE_T;
|
re->options |= RE_SS | RE_T;
|
||||||
break;
|
break;
|
||||||
case 'u':
|
case 'u':
|
||||||
re->options |= RE_U;
|
re->options |= RE_U;
|
||||||
|
1
test/ar/tc/add-nonexistent/out/archive.a
Normal file
1
test/ar/tc/add-nonexistent/out/archive.a
Normal file
@ -0,0 +1 @@
|
|||||||
|
!<arch>
|
@ -1,5 +1,5 @@
|
|||||||
#
|
#
|
||||||
# $Id: Makefile 3025 2014-04-18 16:20:25Z jkoshy $
|
# $Id: Makefile 3715 2019-03-18 09:15:40Z jkoshy $
|
||||||
#
|
#
|
||||||
|
|
||||||
TOP= ../../..
|
TOP= ../../..
|
||||||
@ -36,6 +36,7 @@ SUBDIR+= elf_ndxscn
|
|||||||
SUBDIR+= elf_next
|
SUBDIR+= elf_next
|
||||||
SUBDIR+= elf_newscn
|
SUBDIR+= elf_newscn
|
||||||
SUBDIR+= elf_nextscn
|
SUBDIR+= elf_nextscn
|
||||||
|
SUBDIR+= elf_rand
|
||||||
SUBDIR+= elf_rawfile
|
SUBDIR+= elf_rawfile
|
||||||
SUBDIR+= elf_strptr
|
SUBDIR+= elf_strptr
|
||||||
SUBDIR+= elf_update
|
SUBDIR+= elf_update
|
||||||
|
@ -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 3614 2018-04-21 19:48:04Z jkoshy $
|
# $Id: elfc 3689 2019-02-23 22:50:51Z jkoshy $
|
||||||
|
|
||||||
version = "%prog 1.0"
|
version = "%prog 1.0"
|
||||||
usage = "usage: %prog [options] [input-file]"
|
usage = "usage: %prog [options] [input-file]"
|
||||||
@ -442,6 +442,14 @@ def check_dict(d, l, node=None):
|
|||||||
raise ElfError(node, "{%s} Unknown key(s) %s" % \
|
raise ElfError(node, "{%s} Unknown key(s) %s" % \
|
||||||
(node.tag, unknown))
|
(node.tag, unknown))
|
||||||
|
|
||||||
|
def bounded_value(v, encoding):
|
||||||
|
"""Return the value of 'v' bounded to the maximum size for a type."""
|
||||||
|
if encoding == "H":
|
||||||
|
return (v & 0xFFFF)
|
||||||
|
elif encoding == "I":
|
||||||
|
return (v & 0xFFFFFFFF)
|
||||||
|
return v
|
||||||
|
|
||||||
#
|
#
|
||||||
# Helper classes.
|
# Helper classes.
|
||||||
#
|
#
|
||||||
@ -559,8 +567,10 @@ class ElfType:
|
|||||||
else:
|
else:
|
||||||
n = 3
|
n = 3
|
||||||
for t in self.fields:
|
for t in self.fields:
|
||||||
if t[n] != "":
|
field_encoding = t[n]
|
||||||
a.append(getattr(self, t[0]))
|
if field_encoding != "":
|
||||||
|
v = getattr(self, t[0])
|
||||||
|
a.append(bounded_value(v, field_encoding))
|
||||||
return tuple(a)
|
return tuple(a)
|
||||||
|
|
||||||
def getfields(self, elfclass):
|
def getfields(self, elfclass):
|
||||||
|
@ -1,10 +1,11 @@
|
|||||||
# $Id: Makefile 1719 2011-08-12 08:24:14Z jkoshy $
|
# $Id: Makefile 3690 2019-02-23 22:51:13Z jkoshy $
|
||||||
|
|
||||||
TOP= ../../../..
|
TOP= ../../../..
|
||||||
|
|
||||||
YAML_FILES= check_elf \
|
YAML_FILES= check_elf \
|
||||||
getclass \
|
getclass \
|
||||||
ehdr \
|
ehdr \
|
||||||
|
ehdr-malformed-1 \
|
||||||
fsize \
|
fsize \
|
||||||
newehdr newscn newscn2 \
|
newehdr newscn newscn2 \
|
||||||
phdr \
|
phdr \
|
||||||
|
23
test/libelf/tset/common/ehdr-malformed-1.yaml
Normal file
23
test/libelf/tset/common/ehdr-malformed-1.yaml
Normal file
@ -0,0 +1,23 @@
|
|||||||
|
%YAML 1.1
|
||||||
|
# $Id$
|
||||||
|
---
|
||||||
|
ehdr: !Ehdr
|
||||||
|
e_ident: !Ident # e_ident[] members
|
||||||
|
ei_class: ELFCLASSNONE
|
||||||
|
ei_data: ELFDATANONE
|
||||||
|
ei_osabi: ELFOSABI_SYSV
|
||||||
|
ei_abiversion: 0
|
||||||
|
# other members
|
||||||
|
e_type: 0xFF03
|
||||||
|
e_machine: 0x42
|
||||||
|
e_version: 0xFFFFFFFF
|
||||||
|
e_entry: 0xFFFFFFFFFFFFFFFF
|
||||||
|
e_phoff: 0xFFFFFFFFFFFFFFFF
|
||||||
|
e_shoff: 0xFFFFFFFFFFFFFFFF
|
||||||
|
e_flags: [ 64, 8, 2, 1]
|
||||||
|
e_ehsize: 62
|
||||||
|
e_phentsize: 228
|
||||||
|
e_phnum: 0
|
||||||
|
e_shentsize: 8192
|
||||||
|
e_shnum: 0
|
||||||
|
e_shstrndx: 0
|
@ -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: ehdr_template.m4 3174 2015-03-27 17:13:41Z emaste $
|
* $Id: ehdr_template.m4 3703 2019-03-02 20:41:03Z jkoshy $
|
||||||
*/
|
*/
|
||||||
|
|
||||||
include(`elfts.m4')
|
include(`elfts.m4')
|
||||||
@ -367,3 +367,51 @@ tcElfWrongSize$1(void)
|
|||||||
|
|
||||||
FN(`LSB')
|
FN(`LSB')
|
||||||
FN(`MSB')
|
FN(`MSB')
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Verify that malformed ELF objects are rejected.
|
||||||
|
*/
|
||||||
|
|
||||||
|
undefine(`FN')
|
||||||
|
define(`FN',`
|
||||||
|
void
|
||||||
|
tcMalformed1$1(void)
|
||||||
|
{
|
||||||
|
int error, fd, result;
|
||||||
|
Elf *e;
|
||||||
|
char *fn;
|
||||||
|
TS_EHDR *eh;
|
||||||
|
|
||||||
|
TP_CHECK_INITIALIZATION();
|
||||||
|
|
||||||
|
TP_ANNOUNCE("TS_ICNAME with a malformed ELF header "
|
||||||
|
"fails with ELF_E_HEADER.");
|
||||||
|
|
||||||
|
e = NULL;
|
||||||
|
fd = -1;
|
||||||
|
fn = "ehdr-malformed-1.TOLOWER($1)`'TS_EHDRSZ";
|
||||||
|
result = TET_UNRESOLVED;
|
||||||
|
|
||||||
|
_TS_OPEN_FILE(e, fn, ELF_C_READ, fd, goto done;);
|
||||||
|
|
||||||
|
error = 0;
|
||||||
|
if ((eh = TS_ICFUNC`'(e)) != NULL) {
|
||||||
|
TP_FAIL("\"%s\" TS_ICNAME`'() succeeded.", fn);
|
||||||
|
goto done;
|
||||||
|
} else if ((error = elf_errno()) != ELF_E_HEADER) {
|
||||||
|
TP_FAIL("\"%s\" incorrect error (%d).", fn, error);
|
||||||
|
goto done;
|
||||||
|
}
|
||||||
|
|
||||||
|
result = TET_PASS;
|
||||||
|
|
||||||
|
done:
|
||||||
|
if (e)
|
||||||
|
(void) elf_end(e);
|
||||||
|
if (fd != -1)
|
||||||
|
(void) close(fd);
|
||||||
|
tet_result(result);
|
||||||
|
}')
|
||||||
|
|
||||||
|
FN(`LSB')
|
||||||
|
FN(`MSB')
|
||||||
|
@ -1,8 +1,8 @@
|
|||||||
# $Id: Makefile 1368 2011-01-22 09:09:15Z jkoshy $
|
# $Id: Makefile 3691 2019-02-23 23:34:04Z jkoshy $
|
||||||
|
|
||||||
TOP= ../../../..
|
TOP= ../../../..
|
||||||
|
|
||||||
TS_SRCS= ehdr.m4
|
TS_SRCS= ehdr.m4
|
||||||
TS_YAML= ehdr
|
TS_YAML= ehdr ehdr-malformed-1
|
||||||
|
|
||||||
.include "${TOP}/mk/elftoolchain.tet.mk"
|
.include "${TOP}/mk/elftoolchain.tet.mk"
|
||||||
|
@ -1,9 +1,10 @@
|
|||||||
# $Id: Makefile 1358 2011-01-08 05:40:41Z jkoshy $
|
# $Id: Makefile 3702 2019-03-02 20:40:55Z jkoshy $
|
||||||
|
|
||||||
TOP= ../../../..
|
TOP= ../../../..
|
||||||
|
|
||||||
TS_SRCS= ehdr.m4
|
TS_SRCS= ehdr.m4
|
||||||
TS_DATA= ehdr.msb32 ehdr.lsb32 ehdr.msb64 ehdr.lsb64 \
|
TS_DATA= ehdr.msb32 ehdr.lsb32 ehdr.msb64 ehdr.lsb64 \
|
||||||
|
ehdr-malformed-1.lsb32 ehdr-malformed-1.msb32 \
|
||||||
newehdr.lsb32 newehdr.msb32
|
newehdr.lsb32 newehdr.msb32
|
||||||
|
|
||||||
.include "${TOP}/mk/elftoolchain.tet.mk"
|
.include "${TOP}/mk/elftoolchain.tet.mk"
|
||||||
|
@ -1,8 +1,8 @@
|
|||||||
# $Id: Makefile 1358 2011-01-08 05:40:41Z jkoshy $
|
# $Id: Makefile 3691 2019-02-23 23:34:04Z jkoshy $
|
||||||
|
|
||||||
TOP= ../../../..
|
TOP= ../../../..
|
||||||
|
|
||||||
TS_SRCS= ehdr.m4
|
TS_SRCS= ehdr.m4
|
||||||
TS_YAML= ehdr
|
TS_YAML= ehdr ehdr-malformed-1
|
||||||
|
|
||||||
.include "${TOP}/mk/elftoolchain.tet.mk"
|
.include "${TOP}/mk/elftoolchain.tet.mk"
|
||||||
|
@ -1,9 +1,10 @@
|
|||||||
# $Id: Makefile 1358 2011-01-08 05:40:41Z jkoshy $
|
# $Id: Makefile 3702 2019-03-02 20:40:55Z jkoshy $
|
||||||
|
|
||||||
TOP= ../../../..
|
TOP= ../../../..
|
||||||
|
|
||||||
TS_SRCS= ehdr.m4
|
TS_SRCS= ehdr.m4
|
||||||
TS_DATA= ehdr.msb64 ehdr.lsb64 ehdr.msb32 ehdr.lsb32 \
|
TS_DATA= ehdr.msb64 ehdr.lsb64 ehdr.msb32 ehdr.lsb32 \
|
||||||
|
ehdr-malformed-1.lsb64 ehdr-malformed-1.msb64 \
|
||||||
newehdr.lsb64 newehdr.msb64
|
newehdr.lsb64 newehdr.msb64
|
||||||
|
|
||||||
.include "${TOP}/mk/elftoolchain.tet.mk"
|
.include "${TOP}/mk/elftoolchain.tet.mk"
|
||||||
|
@ -1,8 +1,9 @@
|
|||||||
# $Id: Makefile 2933 2013-03-30 01:33:02Z jkoshy $
|
# $Id: Makefile 3704 2019-03-02 20:41:12Z jkoshy $
|
||||||
|
|
||||||
TOP= ../../../..
|
TOP= ../../../..
|
||||||
|
|
||||||
TS_SRCS= begin.m4
|
TS_SRCS= begin.m4
|
||||||
|
TS_FILES= entry-too-large.ar
|
||||||
TS_DATA= check_elf.msb32 check_elf.lsb32 check_elf.msb64 \
|
TS_DATA= check_elf.msb32 check_elf.lsb32 check_elf.msb64 \
|
||||||
check_elf.lsb64 a.ar a-bsd.ar a.o zero
|
check_elf.lsb64 a.ar a-bsd.ar a.o zero
|
||||||
CLEANFILES+= a.c
|
CLEANFILES+= a.c
|
||||||
|
@ -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: begin.m4 2933 2013-03-30 01:33:02Z jkoshy $
|
* $Id: begin.m4 3706 2019-03-02 20:57:45Z jkoshy $
|
||||||
*/
|
*/
|
||||||
|
|
||||||
#include <sys/stat.h>
|
#include <sys/stat.h>
|
||||||
@ -634,3 +634,44 @@ tcArMemoryFdIgnored_$1(void)
|
|||||||
|
|
||||||
ARFN(`BSD')
|
ARFN(`BSD')
|
||||||
ARFN(`SVR4')
|
ARFN(`SVR4')
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Verify behavior with a corrupted header containing a too-large size.
|
||||||
|
*/
|
||||||
|
void
|
||||||
|
tcArEntryTooLarge(void)
|
||||||
|
{
|
||||||
|
Elf *ar_e, *e;
|
||||||
|
int error, fd, result;
|
||||||
|
|
||||||
|
result = TET_UNRESOLVED;
|
||||||
|
ar_e = NULL;
|
||||||
|
e = NULL;
|
||||||
|
|
||||||
|
TP_ANNOUNCE("elf_begin() returns ELF_E_ARCHIVE for too-large archive "
|
||||||
|
"entries.");
|
||||||
|
|
||||||
|
TP_SET_VERSION();
|
||||||
|
|
||||||
|
_TS_OPEN_FILE(ar_e, "entry-too-large.ar", ELF_C_READ, fd, goto done;);
|
||||||
|
|
||||||
|
if ((e = elf_begin(fd, ELF_C_READ, ar_e)) != NULL) {
|
||||||
|
TP_FAIL("elf_begin() succeeded.");
|
||||||
|
goto done;
|
||||||
|
}
|
||||||
|
|
||||||
|
error = elf_errno();
|
||||||
|
if (error != ELF_E_ARCHIVE) {
|
||||||
|
TP_FAIL("unexpected error %d", error);
|
||||||
|
goto done;
|
||||||
|
}
|
||||||
|
|
||||||
|
result = TET_PASS;
|
||||||
|
|
||||||
|
done:
|
||||||
|
if (e)
|
||||||
|
(void) elf_end(e);
|
||||||
|
if (ar_e)
|
||||||
|
(void) elf_end(ar_e);
|
||||||
|
tet_result(result);
|
||||||
|
}
|
||||||
|
3
test/libelf/tset/elf_begin/entry-too-large.ar
Normal file
3
test/libelf/tset/elf_begin/entry-too-large.ar
Normal file
@ -0,0 +1,3 @@
|
|||||||
|
!<arch>
|
||||||
|
a1.c/ 1551379738 1000 1000 100644 9 `
|
||||||
|
1234567
|
@ -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: getdata.m4 2090 2011-10-27 08:07:39Z jkoshy $
|
* $Id: getdata.m4 3695 2019-02-25 18:55:07Z jkoshy $
|
||||||
*/
|
*/
|
||||||
|
|
||||||
#include <libelf.h>
|
#include <libelf.h>
|
||||||
@ -68,6 +68,36 @@ findscn(Elf *e, const char *name)
|
|||||||
return (NULL);
|
return (NULL);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Check the contents of an Elf_Data descriptor.
|
||||||
|
*
|
||||||
|
* The return value from this helper is as follows:
|
||||||
|
*
|
||||||
|
* 0 - the descriptor matched the specified content.
|
||||||
|
* -1 - the descriptor size had a mismatch.
|
||||||
|
* >0 - the content of the descriptor did not match. The returned value
|
||||||
|
* is the index of the first byte that differs.
|
||||||
|
*/
|
||||||
|
static int
|
||||||
|
match_content(Elf_Data *ed, size_t nbytes, const char *content)
|
||||||
|
{
|
||||||
|
int n;
|
||||||
|
const char *buf;
|
||||||
|
|
||||||
|
if (ed->d_size != nbytes)
|
||||||
|
return (-1);
|
||||||
|
|
||||||
|
buf = (const char *) ed->d_buf;
|
||||||
|
for (n = 0; n < nbytes; n++) {
|
||||||
|
if (*buf != *content)
|
||||||
|
return (n);
|
||||||
|
buf++;
|
||||||
|
content++;
|
||||||
|
}
|
||||||
|
|
||||||
|
return (0);
|
||||||
|
}
|
||||||
|
|
||||||
define(`ZEROSECTION',".zerosection")
|
define(`ZEROSECTION',".zerosection")
|
||||||
undefine(`FN')
|
undefine(`FN')
|
||||||
define(`FN',`
|
define(`FN',`
|
||||||
@ -106,6 +136,11 @@ tcZeroSection$1$2(void)
|
|||||||
goto done;
|
goto done;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if ((ed = elf_getdata(scn, ed)) != NULL) {
|
||||||
|
TP_FAIL("Extra data descriptor in section.");
|
||||||
|
goto done;
|
||||||
|
}
|
||||||
|
|
||||||
result = TET_PASS;
|
result = TET_PASS;
|
||||||
|
|
||||||
done:
|
done:
|
||||||
@ -139,16 +174,17 @@ define(`_FN',`
|
|||||||
void
|
void
|
||||||
tcNonZeroSection$1$2(void)
|
tcNonZeroSection$1$2(void)
|
||||||
{
|
{
|
||||||
Elf *e;
|
|
||||||
int error, fd, result;
|
int error, fd, result;
|
||||||
const size_t strsectionsize = sizeof stringsection;
|
int match_error;
|
||||||
size_t n, shstrndx;
|
size_t shstrndx;
|
||||||
const char *buf;
|
const char *buf;
|
||||||
Elf_Scn *scn;
|
Elf_Scn *scn;
|
||||||
Elf_Data *ed;
|
Elf_Data *ed;
|
||||||
|
Elf *e;
|
||||||
|
|
||||||
e = NULL;
|
|
||||||
fd = -1;
|
fd = -1;
|
||||||
|
e = NULL;
|
||||||
|
scn = NULL;
|
||||||
result = TET_UNRESOLVED;
|
result = TET_UNRESOLVED;
|
||||||
|
|
||||||
TP_ANNOUNCE("a data descriptor for a non-zero sized section "
|
TP_ANNOUNCE("a data descriptor for a non-zero sized section "
|
||||||
@ -170,19 +206,22 @@ tcNonZeroSection$1$2(void)
|
|||||||
goto done;
|
goto done;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (ed->d_size != strsectionsize) {
|
match_error = match_content(ed, sizeof(stringsection),
|
||||||
|
stringsection);
|
||||||
|
if (match_error == -1) {
|
||||||
TP_FAIL("Illegal values returned: d_size %d != expected %d",
|
TP_FAIL("Illegal values returned: d_size %d != expected %d",
|
||||||
(int) ed->d_size, strsectionsize);
|
(int) ed->d_size, sizeof(stringsection));
|
||||||
|
goto done;
|
||||||
|
} else if (match_error > 0) {
|
||||||
|
buf = (const char *) ed->d_buf;
|
||||||
|
TP_FAIL("String mismatch: buf[%d] \"%c\" != \"%c\"",
|
||||||
|
match_error, buf[match_error],
|
||||||
|
stringsection[match_error]);
|
||||||
goto done;
|
goto done;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (memcmp(stringsection, ed->d_buf, strsectionsize) != 0) {
|
if ((ed = elf_getdata(scn, ed)) != NULL) {
|
||||||
buf = (const char *) ed->d_buf;
|
TP_FAIL("Extra data descriptor in section.");
|
||||||
for (n = 0; n < strsectionsize; n++)
|
|
||||||
if (buf[n] != stringsection[n])
|
|
||||||
break;
|
|
||||||
TP_FAIL("String mismatch: buf[%d] \"%c\" != \"%c\"",
|
|
||||||
n, buf[n], stringsection[n]);
|
|
||||||
goto done;
|
goto done;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -201,3 +240,112 @@ _FN(lsb,32)
|
|||||||
_FN(lsb,64)
|
_FN(lsb,64)
|
||||||
_FN(msb,32)
|
_FN(msb,32)
|
||||||
_FN(msb,64)
|
_FN(msb,64)
|
||||||
|
|
||||||
|
static const char new_content[] = {
|
||||||
|
changequote({,})
|
||||||
|
'n', 'e', 'w', ' ', 'c', 'o', 'n', 't', 'e', 'n', 't', '\0'
|
||||||
|
changequote
|
||||||
|
};
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Verify that a section with multiple Elf_Data segments is handled correctly.
|
||||||
|
*/
|
||||||
|
undefine(`_FN')
|
||||||
|
define(`_FN',`
|
||||||
|
void
|
||||||
|
tcDataTraversal$1$2(void)
|
||||||
|
{
|
||||||
|
Elf *e;
|
||||||
|
Elf_Scn *scn;
|
||||||
|
Elf_Data *ed;
|
||||||
|
size_t shstrndx;
|
||||||
|
int error, fd, match_error, result;
|
||||||
|
|
||||||
|
e = NULL;
|
||||||
|
fd = -1;
|
||||||
|
result = TET_UNRESOLVED;
|
||||||
|
|
||||||
|
TP_ANNOUNCE("multiple Elf_Data segments can be traversed.");
|
||||||
|
_TS_OPEN_FILE(e, "zerosection.$1$2", ELF_C_READ, fd, goto done;);
|
||||||
|
|
||||||
|
if (elf_getshdrstrndx(e, &shstrndx) != 0 ||
|
||||||
|
(scn = elf_getscn(e, shstrndx)) == NULL) {
|
||||||
|
TP_UNRESOLVED("Cannot find the string table");
|
||||||
|
goto done;
|
||||||
|
}
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Add new data to the string section.
|
||||||
|
*/
|
||||||
|
if ((ed = elf_newdata(scn)) == NULL) {
|
||||||
|
TP_UNRESOLVED("Cannot allocate new data.");
|
||||||
|
goto done;
|
||||||
|
}
|
||||||
|
|
||||||
|
ed->d_buf = (char *) new_content;
|
||||||
|
ed->d_size = sizeof(new_content);
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Rescan the descriptor list for the section.
|
||||||
|
*/
|
||||||
|
ed = NULL;
|
||||||
|
if ((ed = elf_getdata(scn, ed)) == NULL) {
|
||||||
|
error = elf_errno();
|
||||||
|
TP_FAIL("elf_getdata failed %d \"%s\"", error,
|
||||||
|
elf_errmsg(error));
|
||||||
|
goto done;
|
||||||
|
}
|
||||||
|
|
||||||
|
match_error = match_content(ed, sizeof(stringsection),
|
||||||
|
stringsection);
|
||||||
|
if (match_error == -1) {
|
||||||
|
TP_FAIL("Unexpected size of first descriptor: "
|
||||||
|
"d_size %d != expected %d", (int) ed->d_size,
|
||||||
|
sizeof(stringsection));
|
||||||
|
goto done;
|
||||||
|
} else if (match_error > 0) {
|
||||||
|
TP_FAIL("String content mismatch for data descriptor 1.");
|
||||||
|
goto done;
|
||||||
|
}
|
||||||
|
|
||||||
|
if ((ed = elf_getdata(scn, ed)) == NULL) {
|
||||||
|
error = elf_errno();
|
||||||
|
TP_FAIL("Missing second data section: %d \"%s\"", error,
|
||||||
|
elf_errmsg(error));
|
||||||
|
goto done;
|
||||||
|
}
|
||||||
|
|
||||||
|
match_error = match_content(ed, sizeof(new_content),
|
||||||
|
new_content);
|
||||||
|
if (match_error == -1) {
|
||||||
|
TP_FAIL("Unexpected size of second descriptor: "
|
||||||
|
"d_size %d != expected %d", (int) ed->d_size,
|
||||||
|
sizeof(new_content));
|
||||||
|
goto done;
|
||||||
|
} else if (match_error > 0) {
|
||||||
|
TP_FAIL("String content mismatch for data descriptor 2.");
|
||||||
|
goto done;
|
||||||
|
}
|
||||||
|
|
||||||
|
/*
|
||||||
|
* There should be no other Elf_Data descriptors.
|
||||||
|
*/
|
||||||
|
if ((ed = elf_getdata(scn, ed)) != NULL) {
|
||||||
|
TP_FAIL("Too many Elf_Data descriptors for section.");
|
||||||
|
goto done;
|
||||||
|
}
|
||||||
|
|
||||||
|
result = TET_PASS;
|
||||||
|
|
||||||
|
done:
|
||||||
|
if (e)
|
||||||
|
elf_end(e);
|
||||||
|
if (fd != -1)
|
||||||
|
(void) close(fd);
|
||||||
|
tet_result(result);
|
||||||
|
}')
|
||||||
|
|
||||||
|
_FN(lsb,32)
|
||||||
|
_FN(lsb,64)
|
||||||
|
_FN(msb,32)
|
||||||
|
_FN(msb,64)
|
||||||
|
18
test/libelf/tset/elf_rand/Makefile
Normal file
18
test/libelf/tset/elf_rand/Makefile
Normal file
@ -0,0 +1,18 @@
|
|||||||
|
# $Id$
|
||||||
|
|
||||||
|
TOP= ../../../..
|
||||||
|
|
||||||
|
TS_SRCS= rand.m4
|
||||||
|
TS_DATA= a.ar s1 s2
|
||||||
|
TS_FILES= empty-file.ar missing-file.ar
|
||||||
|
|
||||||
|
s1: .SILENT
|
||||||
|
echo 'This is s1.' > ${.TARGET}
|
||||||
|
s2: .SILENT
|
||||||
|
echo 's2.' > ${.TARGET}
|
||||||
|
|
||||||
|
a.ar: s1 s2 .SILENT
|
||||||
|
rm -f ${.TARGET}
|
||||||
|
${AR} crv ${.TARGET} s1 s2 > /dev/null
|
||||||
|
|
||||||
|
.include "${TOP}/mk/elftoolchain.tet.mk"
|
2
test/libelf/tset/elf_rand/empty-file.ar
Normal file
2
test/libelf/tset/elf_rand/empty-file.ar
Normal file
@ -0,0 +1,2 @@
|
|||||||
|
!<arch>
|
||||||
|
e1/ 0 0 0 644 0 `
|
2
test/libelf/tset/elf_rand/missing-file.ar
Normal file
2
test/libelf/tset/elf_rand/missing-file.ar
Normal file
@ -0,0 +1,2 @@
|
|||||||
|
!<arch>
|
||||||
|
e1/ 0 0 0 644 42 `
|
415
test/libelf/tset/elf_rand/rand.m4
Normal file
415
test/libelf/tset/elf_rand/rand.m4
Normal file
@ -0,0 +1,415 @@
|
|||||||
|
/*-
|
||||||
|
* Copyright (c) 2019 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 THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND
|
||||||
|
* ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
|
||||||
|
* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
|
||||||
|
* ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
|
||||||
|
* FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
|
||||||
|
* DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
|
||||||
|
* OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
|
||||||
|
* HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
|
||||||
|
* LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
|
||||||
|
* OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
|
||||||
|
* SUCH DAMAGE.
|
||||||
|
*
|
||||||
|
* $Id$
|
||||||
|
*/
|
||||||
|
|
||||||
|
#include <sys/types.h>
|
||||||
|
#include <sys/stat.h>
|
||||||
|
|
||||||
|
#include <ar.h>
|
||||||
|
#include <libelf.h>
|
||||||
|
#include <limits.h>
|
||||||
|
#include <unistd.h>
|
||||||
|
|
||||||
|
#include "elfts.h"
|
||||||
|
#include "tet_api.h"
|
||||||
|
|
||||||
|
IC_REQUIRES_VERSION_INIT();
|
||||||
|
|
||||||
|
include(`elfts.m4')
|
||||||
|
|
||||||
|
/*
|
||||||
|
* The following definitions should match those in `./Makefile'.
|
||||||
|
*/
|
||||||
|
define(`TP_ARFILE',`"a.ar"')
|
||||||
|
define(`TP_NONARCHIVE', `"s1"')
|
||||||
|
|
||||||
|
/*
|
||||||
|
* The use of an offset less than SARMAG should fail.
|
||||||
|
*/
|
||||||
|
void
|
||||||
|
tcSeekBelowSarmag(void)
|
||||||
|
{
|
||||||
|
Elf *ar;
|
||||||
|
off_t offset;
|
||||||
|
int error, fd, result;
|
||||||
|
|
||||||
|
fd = -1;
|
||||||
|
ar = NULL;
|
||||||
|
result = TET_UNRESOLVED;
|
||||||
|
|
||||||
|
TP_CHECK_INITIALIZATION();
|
||||||
|
TP_ANNOUNCE("elf_rand() fails for an offset less than SARMAG");
|
||||||
|
|
||||||
|
TS_OPEN_FILE(ar, TP_ARFILE, ELF_C_READ, fd);
|
||||||
|
|
||||||
|
result = TET_PASS;
|
||||||
|
|
||||||
|
if ((offset = elf_rand(ar, 1)) != 0) {
|
||||||
|
TP_FAIL("elf_rand() succeeded with offset=%lld",
|
||||||
|
(unsigned long long) offset);
|
||||||
|
} else if ((error = elf_errno()) != ELF_E_ARGUMENT) {
|
||||||
|
TP_FAIL("unexpected error=%d \"%s\"", error,
|
||||||
|
elf_errmsg(error));
|
||||||
|
}
|
||||||
|
|
||||||
|
(void) elf_end(ar);
|
||||||
|
(void) close(fd);
|
||||||
|
|
||||||
|
tet_result(result);
|
||||||
|
}
|
||||||
|
|
||||||
|
/*
|
||||||
|
* The use of an offset greater than the largest valid file offset
|
||||||
|
* should fail.
|
||||||
|
*/
|
||||||
|
void
|
||||||
|
tcSeekMoreThanFileSize(void)
|
||||||
|
{
|
||||||
|
Elf *ar;
|
||||||
|
off_t offset;
|
||||||
|
struct stat sb;
|
||||||
|
int error, fd, result;
|
||||||
|
|
||||||
|
result = TET_UNRESOLVED;
|
||||||
|
ar = NULL;
|
||||||
|
fd = -1;
|
||||||
|
|
||||||
|
TP_CHECK_INITIALIZATION();
|
||||||
|
TP_ANNOUNCE("elf_rand() fails with a too-large offset");
|
||||||
|
|
||||||
|
TS_OPEN_FILE(ar, TP_ARFILE, ELF_C_READ, fd);
|
||||||
|
|
||||||
|
/* Get the file size of the archive. */
|
||||||
|
if (fstat(fd, &sb) < 0) {
|
||||||
|
TP_UNRESOLVED("cannot determine the size of \"%s\"",
|
||||||
|
TP_ARFILE);
|
||||||
|
goto done;
|
||||||
|
}
|
||||||
|
|
||||||
|
result = TET_PASS;
|
||||||
|
|
||||||
|
if ((offset = elf_rand(ar, sb.st_size)) != 0) {
|
||||||
|
TP_FAIL("elf_rand() succeeded with offset=%lld",
|
||||||
|
(unsigned long long) offset);
|
||||||
|
} else if ((error = elf_errno()) != ELF_E_ARGUMENT) {
|
||||||
|
TP_FAIL("unexpected error=%d \"%s\"", error,
|
||||||
|
elf_errmsg(error));
|
||||||
|
}
|
||||||
|
|
||||||
|
done:
|
||||||
|
if (ar)
|
||||||
|
(void) elf_end(ar);
|
||||||
|
if (fd != -1)
|
||||||
|
(void) close(fd);
|
||||||
|
|
||||||
|
tet_result(result);
|
||||||
|
}
|
||||||
|
|
||||||
|
/*
|
||||||
|
* An offset with value SARMAG is accepted.
|
||||||
|
*/
|
||||||
|
void
|
||||||
|
tcOffsetEqualsSARMAG(void)
|
||||||
|
{
|
||||||
|
Elf *ar;
|
||||||
|
off_t offset;
|
||||||
|
int fd, result;
|
||||||
|
|
||||||
|
fd = -1;
|
||||||
|
ar = NULL;
|
||||||
|
result = TET_UNRESOLVED;
|
||||||
|
|
||||||
|
TP_CHECK_INITIALIZATION();
|
||||||
|
TP_ANNOUNCE("elf_rand(SARMAG) succeeds.");
|
||||||
|
|
||||||
|
TS_OPEN_FILE(ar, TP_ARFILE, ELF_C_READ, fd);
|
||||||
|
|
||||||
|
if ((offset = elf_rand(ar, SARMAG)) != SARMAG) {
|
||||||
|
TP_FAIL("unexpected offset: %lld",
|
||||||
|
(long long) offset);
|
||||||
|
goto done;
|
||||||
|
}
|
||||||
|
|
||||||
|
result = TET_PASS;
|
||||||
|
|
||||||
|
done:
|
||||||
|
if (ar)
|
||||||
|
(void) elf_end(ar);
|
||||||
|
if (fd != -1)
|
||||||
|
(void) close(fd);
|
||||||
|
|
||||||
|
tet_result(result);
|
||||||
|
}
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Invoking elf_rand() on a non-archive should fail.
|
||||||
|
*/
|
||||||
|
void
|
||||||
|
tcOnNonArchive(void)
|
||||||
|
{
|
||||||
|
Elf *e;
|
||||||
|
off_t offset;
|
||||||
|
int error, fd, result;
|
||||||
|
|
||||||
|
fd = -1;
|
||||||
|
e = NULL;
|
||||||
|
result = TET_UNRESOLVED;
|
||||||
|
|
||||||
|
TP_CHECK_INITIALIZATION();
|
||||||
|
TP_ANNOUNCE("elf_rand(non-archive) fails.");
|
||||||
|
|
||||||
|
TS_OPEN_FILE(e, TP_NONARCHIVE, ELF_C_READ, fd);
|
||||||
|
|
||||||
|
if ((offset = elf_rand(e, SARMAG)) != 0 ||
|
||||||
|
(error = elf_errno()) != ELF_E_ARGUMENT) {
|
||||||
|
TP_FAIL("unexpected offset=%lld",
|
||||||
|
(long long) offset);
|
||||||
|
goto done;
|
||||||
|
}
|
||||||
|
|
||||||
|
result = TET_PASS;
|
||||||
|
|
||||||
|
done:
|
||||||
|
if (e)
|
||||||
|
(void) elf_end(e);
|
||||||
|
if (fd != -1)
|
||||||
|
(void) close(fd);
|
||||||
|
|
||||||
|
tet_result(result);
|
||||||
|
}
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Use an offset value that could cause an overflow.
|
||||||
|
*/
|
||||||
|
void
|
||||||
|
tcOffsetOverflow(void)
|
||||||
|
{
|
||||||
|
Elf *ar;
|
||||||
|
off_t offset;
|
||||||
|
uint64_t max_offset;
|
||||||
|
int error, fd, result;
|
||||||
|
|
||||||
|
fd = -1;
|
||||||
|
ar = NULL;
|
||||||
|
result = TET_UNRESOLVED;
|
||||||
|
|
||||||
|
/* A even offset that is close to overflowing. */
|
||||||
|
max_offset = (1ULL << (sizeof(off_t) * CHAR_BIT - 1)) - 2;
|
||||||
|
|
||||||
|
TP_CHECK_INITIALIZATION();
|
||||||
|
TP_ANNOUNCE("offset close to overflowing an off_t");
|
||||||
|
|
||||||
|
TS_OPEN_FILE(ar, TP_ARFILE, ELF_C_READ, fd);
|
||||||
|
|
||||||
|
if ((offset = elf_rand(ar, (off_t) max_offset)) != 0) {
|
||||||
|
TP_FAIL("unexpected success, offset=%lld",
|
||||||
|
(long long) offset);
|
||||||
|
goto done;
|
||||||
|
}
|
||||||
|
|
||||||
|
result = TET_PASS;
|
||||||
|
|
||||||
|
done:
|
||||||
|
if (ar)
|
||||||
|
(void) elf_end(ar);
|
||||||
|
if (fd != -1)
|
||||||
|
(void) close(fd);
|
||||||
|
|
||||||
|
tet_result(result);
|
||||||
|
}
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Setting the offset to a value that does not correspond to an ar header
|
||||||
|
* should fail.
|
||||||
|
*/
|
||||||
|
void
|
||||||
|
tcOffsetNotCorrespondingToAnArchiveHeader(void)
|
||||||
|
{
|
||||||
|
Elf *ar;
|
||||||
|
off_t offset;
|
||||||
|
int error, fd, result;
|
||||||
|
|
||||||
|
fd = -1;
|
||||||
|
ar = NULL;
|
||||||
|
result = TET_UNRESOLVED;
|
||||||
|
|
||||||
|
TP_CHECK_INITIALIZATION();
|
||||||
|
TP_ANNOUNCE("elf_rand(non-header-offset) should fail.");
|
||||||
|
|
||||||
|
TS_OPEN_FILE(ar, TP_ARFILE, ELF_C_READ, fd);
|
||||||
|
|
||||||
|
if ((offset = elf_rand(ar, SARMAG+2)) != 0) {
|
||||||
|
TP_FAIL("unexpected success, offset=%lld",
|
||||||
|
(long long) offset);
|
||||||
|
goto done;
|
||||||
|
} else if ((error = elf_errno()) != ELF_E_ARCHIVE) {
|
||||||
|
TP_FAIL("unexpected error=%d \"%s\"", error,
|
||||||
|
elf_errmsg(error));
|
||||||
|
goto done;
|
||||||
|
}
|
||||||
|
|
||||||
|
result = TET_PASS;
|
||||||
|
|
||||||
|
done:
|
||||||
|
if (ar)
|
||||||
|
(void) elf_end(ar);
|
||||||
|
if (fd != -1)
|
||||||
|
(void) close(fd);
|
||||||
|
|
||||||
|
tet_result(result);
|
||||||
|
}
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Odd values of offsets are not legal.
|
||||||
|
*/
|
||||||
|
void
|
||||||
|
tcOddOffset(void)
|
||||||
|
{
|
||||||
|
Elf *ar;
|
||||||
|
off_t offset;
|
||||||
|
int error, fd, result;
|
||||||
|
|
||||||
|
fd = -1;
|
||||||
|
ar = NULL;
|
||||||
|
result = TET_UNRESOLVED;
|
||||||
|
|
||||||
|
TP_CHECK_INITIALIZATION();
|
||||||
|
TP_ANNOUNCE("elf_rand(odd-offset-value) should fail.");
|
||||||
|
|
||||||
|
TS_OPEN_FILE(ar, TP_ARFILE, ELF_C_READ, fd);
|
||||||
|
|
||||||
|
if ((offset = elf_rand(ar, SARMAG+1)) != 0) {
|
||||||
|
TP_FAIL("unexpected success, offset=%lld",
|
||||||
|
(long long) offset);
|
||||||
|
goto done;
|
||||||
|
} else if ((error = elf_errno()) != ELF_E_ARGUMENT) {
|
||||||
|
TP_FAIL("unexpected error=%d \"%s\"", error,
|
||||||
|
elf_errmsg(error));
|
||||||
|
goto done;
|
||||||
|
}
|
||||||
|
|
||||||
|
result = TET_PASS;
|
||||||
|
|
||||||
|
done:
|
||||||
|
if (ar)
|
||||||
|
(void) elf_end(ar);
|
||||||
|
if (fd != -1)
|
||||||
|
(void) close(fd);
|
||||||
|
|
||||||
|
tet_result(result);
|
||||||
|
}
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Negative offset values are not legal.
|
||||||
|
*/
|
||||||
|
void
|
||||||
|
tcNegativeOffset(void)
|
||||||
|
{
|
||||||
|
Elf *ar;
|
||||||
|
off_t offset;
|
||||||
|
int error, fd, result;
|
||||||
|
|
||||||
|
fd = -1;
|
||||||
|
ar = NULL;
|
||||||
|
result = TET_UNRESOLVED;
|
||||||
|
|
||||||
|
TP_CHECK_INITIALIZATION();
|
||||||
|
TP_ANNOUNCE("elf_rand(odd-offset-value) should fail.");
|
||||||
|
|
||||||
|
TS_OPEN_FILE(ar, TP_ARFILE, ELF_C_READ, fd);
|
||||||
|
|
||||||
|
if ((offset = elf_rand(ar, -SARMAG)) != 0) {
|
||||||
|
TP_FAIL("unexpected success, offset=%lld",
|
||||||
|
(long long) offset);
|
||||||
|
goto done;
|
||||||
|
} else if ((error = elf_errno()) != ELF_E_ARGUMENT) {
|
||||||
|
TP_FAIL("unexpected error=%d \"%s\"", error,
|
||||||
|
elf_errmsg(error));
|
||||||
|
goto done;
|
||||||
|
}
|
||||||
|
|
||||||
|
result = TET_PASS;
|
||||||
|
|
||||||
|
done:
|
||||||
|
if (ar)
|
||||||
|
(void) elf_end(ar);
|
||||||
|
if (fd != -1)
|
||||||
|
(void) close(fd);
|
||||||
|
|
||||||
|
tet_result(result);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
/* These offsets correspond to archive TP_ARFILE. */
|
||||||
|
static off_t valid_offsets[] = {
|
||||||
|
SARMAG, /* File 's1'. */
|
||||||
|
80 /* File 's2'. */
|
||||||
|
};
|
||||||
|
|
||||||
|
static const int number_of_offsets =
|
||||||
|
sizeof(valid_offsets) / sizeof(valid_offsets[0]);
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Valid offsets should be usable.
|
||||||
|
*/
|
||||||
|
void
|
||||||
|
tcValidOffsets(void)
|
||||||
|
{
|
||||||
|
Elf *ar;
|
||||||
|
off_t offset;
|
||||||
|
int i, error, fd, result;
|
||||||
|
|
||||||
|
fd = -1;
|
||||||
|
ar = NULL;
|
||||||
|
result = TET_UNRESOLVED;
|
||||||
|
|
||||||
|
TP_CHECK_INITIALIZATION();
|
||||||
|
TP_ANNOUNCE("elf_rand(valid-offsets) succeeds.");
|
||||||
|
|
||||||
|
TS_OPEN_FILE(ar, TP_ARFILE, ELF_C_READ, fd);
|
||||||
|
|
||||||
|
for (i = 0; i < number_of_offsets; i++) {
|
||||||
|
if ((offset = elf_rand(ar, valid_offsets[i])) !=
|
||||||
|
valid_offsets[i]) {
|
||||||
|
error = elf_errno();
|
||||||
|
TP_FAIL("failed to seek to offset %lld, error=%d "
|
||||||
|
"\"%s\"", (long long) offset, error,
|
||||||
|
elf_errmsg(error));
|
||||||
|
goto done;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
result = TET_PASS;
|
||||||
|
|
||||||
|
done:
|
||||||
|
if (ar)
|
||||||
|
(void) elf_end(ar);
|
||||||
|
if (fd != -1)
|
||||||
|
(void) close(fd);
|
||||||
|
|
||||||
|
tet_result(result);
|
||||||
|
}
|
@ -9,9 +9,8 @@ SUBDIR+= lib
|
|||||||
SUBDIR+= driver
|
SUBDIR+= driver
|
||||||
SUBDIR+= examples
|
SUBDIR+= examples
|
||||||
|
|
||||||
.if !make(install)
|
.if !make(install) && !make(test)
|
||||||
.include "$(TOP)/mk/elftoolchain.subdir.mk"
|
.include "$(TOP)/mk/elftoolchain.subdir.mk"
|
||||||
.else
|
.else
|
||||||
install: .SILENT .PHONY
|
install test: .SILENT .PHONY
|
||||||
echo Nothing to install.
|
|
||||||
.endif
|
.endif
|
||||||
|
@ -43,7 +43,7 @@ functions contained in a test case named "``helloworld``":
|
|||||||
/* File: test.c */
|
/* File: test.c */
|
||||||
#include "test.h"
|
#include "test.h"
|
||||||
|
|
||||||
TESTCASE_DESCRIPTION(helloworld) =
|
TEST_CASE_DESCRIPTION(helloworld) =
|
||||||
"A description of the helloworld test case.";
|
"A description of the helloworld test case.";
|
||||||
|
|
||||||
enum test_result
|
enum test_result
|
||||||
@ -69,14 +69,14 @@ Test cases can define their own set up and tear down functions:
|
|||||||
tc_setup_helloworld(testcase_state *tcs)
|
tc_setup_helloworld(testcase_state *tcs)
|
||||||
{
|
{
|
||||||
*tcs = ..allocate a struct helloworld_test.. ;
|
*tcs = ..allocate a struct helloworld_test.. ;
|
||||||
return (TESTCASE_OK);
|
return (TEST_CASE_OK);
|
||||||
}
|
}
|
||||||
|
|
||||||
enum testcase_status
|
enum testcase_status
|
||||||
tc_teardown_helloworld(testcase_state tcs)
|
tc_teardown_helloworld(testcase_state tcs)
|
||||||
{
|
{
|
||||||
.. deallocate test case state..
|
.. deallocate test case state..
|
||||||
return (TESTCASE_OK);
|
return (TEST_CASE_OK);
|
||||||
}
|
}
|
||||||
|
|
||||||
The set up function for a test case will be invoked prior to any of
|
The set up function for a test case will be invoked prior to any of
|
||||||
|
@ -79,7 +79,7 @@ cat <<EOF
|
|||||||
/* GENERATED FROM: ${@} */
|
/* GENERATED FROM: ${@} */
|
||||||
#include <stddef.h>
|
#include <stddef.h>
|
||||||
#include "test.h"
|
#include "test.h"
|
||||||
#include "test_runner.h"
|
#include "test_case.h"
|
||||||
EOF
|
EOF
|
||||||
|
|
||||||
if ! nm ${*} | sort -k 3 | \
|
if ! nm ${*} | sort -k 3 | \
|
||||||
@ -108,9 +108,13 @@ if ! nm ${*} | sort -k 3 | \
|
|||||||
function print_test_case_record(tc_name) {
|
function print_test_case_record(tc_name) {
|
||||||
printf("\t{\n")
|
printf("\t{\n")
|
||||||
printf("\t\t.tc_name = \"%s\",\n", tc_name)
|
printf("\t\t.tc_name = \"%s\",\n", tc_name)
|
||||||
printf("\t\t.tc_description = %s,\n", test_case_descriptions[tc_name])
|
printf("\t\t.tc_description = %s,\n",
|
||||||
|
test_case_descriptions[tc_name])
|
||||||
printf("\t\t.tc_tags = %s,\n", test_case_tags[tc_name])
|
printf("\t\t.tc_tags = %s,\n", test_case_tags[tc_name])
|
||||||
printf("\t\t.tc_tests = test_functions_%s\n", tc_name)
|
tf_name = "test_functions_" tc_name
|
||||||
|
printf("\t\t.tc_tests = %s,\n", tf_name)
|
||||||
|
printf("\t\t.tc_count = sizeof (%s) / sizeof (%s[0]),\n",
|
||||||
|
tf_name, tf_name)
|
||||||
printf("\t},\n")
|
printf("\t},\n")
|
||||||
}
|
}
|
||||||
function delete_test_functions(tc_name) {
|
function delete_test_functions(tc_name) {
|
||||||
@ -120,16 +124,19 @@ if ! nm ${*} | sort -k 3 | \
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
function print_test_functions_record(tc_name) {
|
function print_test_functions_record(tc_name) {
|
||||||
printf("struct test_descriptor test_functions_%s[] = {\n", tc_name)
|
printf("struct test_function_descriptor test_functions_%s[]",
|
||||||
|
tc_name)
|
||||||
|
printf(" = {\n")
|
||||||
for (tf_name in test_functions) {
|
for (tf_name in test_functions) {
|
||||||
if (tc_name != matched_test_case(tf_name))
|
if (tc_name != matched_test_case(tf_name))
|
||||||
continue
|
continue
|
||||||
printf("\t{\n")
|
printf("\t{\n")
|
||||||
printf("\t\t.t_name = \"%s\",\n", tf_name)
|
printf("\t\t.tf_name = \"%s\",\n", tf_name)
|
||||||
printf("\t\t.t_description = %s,\n",
|
printf("\t\t.tf_description = %s,\n",
|
||||||
test_function_descriptions[tf_name])
|
test_function_descriptions[tf_name])
|
||||||
printf("\t\t.t_func = %s,\n", prefix_tf tf_name)
|
printf("\t\t.tf_func = %s,\n", prefix_tf tf_name)
|
||||||
printf("\t\t.t_tags = %s\n", test_function_tags[tf_name])
|
printf("\t\t.tf_tags = %s\n",
|
||||||
|
test_function_tags[tf_name])
|
||||||
printf("\t},\n")
|
printf("\t},\n")
|
||||||
}
|
}
|
||||||
printf("};\n")
|
printf("};\n")
|
||||||
@ -144,7 +151,7 @@ if ! nm ${*} | sort -k 3 | \
|
|||||||
test_case_tags[DEFAULT] = "NULL"
|
test_case_tags[DEFAULT] = "NULL"
|
||||||
}
|
}
|
||||||
($2 == "R" || $2 == "D") && $3 ~ "^" prefix_tc_descr {
|
($2 == "R" || $2 == "D") && $3 ~ "^" prefix_tc_descr {
|
||||||
printf("extern testcase_description %s;\n", $3)
|
printf("extern test_case_description %s;\n", $3)
|
||||||
tc_name = suffix($3, prefix_tc_descr)
|
tc_name = suffix($3, prefix_tc_descr)
|
||||||
test_cases[tc_name] = 1
|
test_cases[tc_name] = 1
|
||||||
test_case_descriptions[tc_name] = $3
|
test_case_descriptions[tc_name] = $3
|
||||||
@ -155,7 +162,7 @@ if ! nm ${*} | sort -k 3 | \
|
|||||||
test_case_setup[tc_name] = $3
|
test_case_setup[tc_name] = $3
|
||||||
}
|
}
|
||||||
($2 == "R" || $2 == "D") && $3 ~ "^" prefix_tc_tags {
|
($2 == "R" || $2 == "D") && $3 ~ "^" prefix_tc_tags {
|
||||||
printf("extern testcase_tags %s;\n", $3)
|
printf("extern test_case_tags %s;\n", $3)
|
||||||
tc_name = suffix($3, prefix_tc_tags)
|
tc_name = suffix($3, prefix_tc_tags)
|
||||||
test_cases[tc_name] = 1
|
test_cases[tc_name] = 1
|
||||||
test_case_tags[tc_name] = $3
|
test_case_tags[tc_name] = $3
|
||||||
@ -206,6 +213,8 @@ if ! nm ${*} | sort -k 3 | \
|
|||||||
if (needs_default)
|
if (needs_default)
|
||||||
print_test_case_record(DEFAULT)
|
print_test_case_record(DEFAULT)
|
||||||
printf("};\n")
|
printf("};\n")
|
||||||
|
printf("const int test_case_count = sizeof(test_cases) / ")
|
||||||
|
printf("sizeof(test_cases[0]);\n")
|
||||||
}'; then
|
}'; then
|
||||||
# Cleanup in case of an error.
|
# Cleanup in case of an error.
|
||||||
rm ${output_file}
|
rm ${output_file}
|
||||||
|
@ -6,9 +6,12 @@ TOP= ../../..
|
|||||||
|
|
||||||
CFLAGS+= -I${TOP}/test/libtest/lib
|
CFLAGS+= -I${TOP}/test/libtest/lib
|
||||||
|
|
||||||
LIB= test_main
|
LIB= driver
|
||||||
SRCS= test_main.c
|
SRCS= driver.c \
|
||||||
|
driver_main.c
|
||||||
|
|
||||||
WARNS?= 6
|
WARNS?= 6
|
||||||
|
|
||||||
|
MAN= test_driver.1
|
||||||
|
|
||||||
.include "$(TOP)/mk/elftoolchain.lib.mk"
|
.include "$(TOP)/mk/elftoolchain.lib.mk"
|
||||||
|
216
test/libtest/driver/driver.c
Normal file
216
test/libtest/driver/driver.c
Normal file
@ -0,0 +1,216 @@
|
|||||||
|
/*-
|
||||||
|
* Copyright (c) 2018, 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
|
||||||
|
* in this position and unchanged.
|
||||||
|
* 2. Redistributions in binary form must reproduce the above copyright
|
||||||
|
* notice, this list of conditions and the following disclaimer in the
|
||||||
|
* documentation and/or other materials provided with the distribution.
|
||||||
|
*
|
||||||
|
* THIS SOFTWARE IS PROVIDED BY THE AUTHOR(S) ``AS IS'' AND ANY EXPRESS OR
|
||||||
|
* IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
|
||||||
|
* OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
|
||||||
|
* IN NO EVENT SHALL THE AUTHOR(S) 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.
|
||||||
|
*/
|
||||||
|
|
||||||
|
/*
|
||||||
|
* The implementation of the test driver.
|
||||||
|
*/
|
||||||
|
|
||||||
|
#include <sys/types.h>
|
||||||
|
#include <sys/stat.h>
|
||||||
|
#include <sys/time.h>
|
||||||
|
|
||||||
|
#include <err.h>
|
||||||
|
#include <libgen.h>
|
||||||
|
#include <stdbool.h>
|
||||||
|
#include <stdio.h>
|
||||||
|
#include <stdlib.h>
|
||||||
|
#include <string.h>
|
||||||
|
#include <sysexits.h>
|
||||||
|
|
||||||
|
#include "driver.h"
|
||||||
|
|
||||||
|
#if defined(ELFTC_VCSID)
|
||||||
|
ELFTC_VCSID("$Id$");
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#define SYSTEM_TMPDIR_ENV_VAR "TMPDIR"
|
||||||
|
|
||||||
|
bool
|
||||||
|
test_driver_add_search_path(struct test_run *tr, const char *directory_name)
|
||||||
|
{
|
||||||
|
char *canonical_path;
|
||||||
|
struct test_search_path_entry *entry;
|
||||||
|
|
||||||
|
if (!test_driver_is_directory(directory_name))
|
||||||
|
return (false);
|
||||||
|
|
||||||
|
if ((canonical_path = realpath(directory_name, NULL)) == NULL)
|
||||||
|
err(1, "Cannot determine the canonical path for \"%s\"",
|
||||||
|
directory_name);
|
||||||
|
|
||||||
|
/* Look for, and ignore duplicates. */
|
||||||
|
STAILQ_FOREACH(entry, &tr->tr_search_path, tsp_next) {
|
||||||
|
if (strcmp(canonical_path, entry->tsp_directory) == 0)
|
||||||
|
return (true);
|
||||||
|
}
|
||||||
|
|
||||||
|
entry = calloc(1, sizeof(*entry));
|
||||||
|
entry->tsp_directory = canonical_path;
|
||||||
|
|
||||||
|
STAILQ_INSERT_TAIL(&tr->tr_search_path, entry, tsp_next);
|
||||||
|
|
||||||
|
return (true);
|
||||||
|
}
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Return an initialized test run descriptor.
|
||||||
|
*
|
||||||
|
* The caller should use test_driver_free_run() to release the returned
|
||||||
|
* descriptor.
|
||||||
|
*/
|
||||||
|
struct test_run *
|
||||||
|
test_driver_allocate_run(void)
|
||||||
|
{
|
||||||
|
struct test_run *tr;
|
||||||
|
|
||||||
|
tr = calloc(sizeof(struct test_run), 1);
|
||||||
|
tr->tr_action = TEST_RUN_EXECUTE;
|
||||||
|
tr->tr_style = TR_STYLE_LIBTEST;
|
||||||
|
STAILQ_INIT(&tr->tr_test_cases);
|
||||||
|
STAILQ_INIT(&tr->tr_search_path);
|
||||||
|
|
||||||
|
return (tr);
|
||||||
|
}
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Destroy an allocated test run descriptor.
|
||||||
|
*
|
||||||
|
* The passed in pointer should not be used after this function returns.
|
||||||
|
*/
|
||||||
|
void
|
||||||
|
test_driver_free_run(struct test_run *tr)
|
||||||
|
{
|
||||||
|
struct test_search_path_entry *path_entry;
|
||||||
|
struct test_case_selector *test_case_entry;
|
||||||
|
struct test_function_selector *function_entry;
|
||||||
|
|
||||||
|
free(tr->tr_runtime_base_directory);
|
||||||
|
free(tr->tr_name);
|
||||||
|
if (tr->tr_artefact_archive)
|
||||||
|
free(tr->tr_artefact_archive);
|
||||||
|
|
||||||
|
/* Free the search path list. */
|
||||||
|
while (!STAILQ_EMPTY(&tr->tr_search_path)) {
|
||||||
|
path_entry = STAILQ_FIRST(&tr->tr_search_path);
|
||||||
|
STAILQ_REMOVE_HEAD(&tr->tr_search_path, tsp_next);
|
||||||
|
free(path_entry);
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Free the test selector list. */
|
||||||
|
while (!STAILQ_EMPTY(&tr->tr_test_cases)) {
|
||||||
|
test_case_entry = STAILQ_FIRST(&tr->tr_test_cases);
|
||||||
|
STAILQ_REMOVE_HEAD(&tr->tr_test_cases, tcs_next);
|
||||||
|
|
||||||
|
/* Free the linked test functions. */
|
||||||
|
while (!STAILQ_EMPTY(&test_case_entry->tcs_functions)) {
|
||||||
|
function_entry =
|
||||||
|
STAILQ_FIRST(&test_case_entry->tcs_functions);
|
||||||
|
STAILQ_REMOVE_HEAD(&test_case_entry->tcs_functions,
|
||||||
|
tfs_next);
|
||||||
|
|
||||||
|
free(function_entry);
|
||||||
|
}
|
||||||
|
|
||||||
|
free(test_case_entry);
|
||||||
|
}
|
||||||
|
|
||||||
|
free(tr);
|
||||||
|
}
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Populate unset fields of a struct test_run with defaults.
|
||||||
|
*/
|
||||||
|
bool
|
||||||
|
test_driver_finish_run_initialization(struct test_run *tr, const char *argv0)
|
||||||
|
{
|
||||||
|
struct timeval tv;
|
||||||
|
const char *basedir;
|
||||||
|
const char *search_path;
|
||||||
|
const char *last_component;
|
||||||
|
char *argv0_copy, *path_copy, *path_element;
|
||||||
|
char test_name[NAME_MAX];
|
||||||
|
|
||||||
|
if (tr->tr_name == NULL) {
|
||||||
|
/* Per POSIX, basename(3) can modify its argument. */
|
||||||
|
argv0_copy = strdup(argv0);
|
||||||
|
last_component = basename(argv0_copy);
|
||||||
|
|
||||||
|
if (gettimeofday(&tv, NULL))
|
||||||
|
return (false);
|
||||||
|
|
||||||
|
(void) snprintf(test_name, sizeof(test_name), "%s+%ld%ld",
|
||||||
|
last_component, (long) tv.tv_sec, (long) tv.tv_usec);
|
||||||
|
|
||||||
|
tr->tr_name = strdup(test_name);
|
||||||
|
|
||||||
|
free(argv0_copy);
|
||||||
|
}
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Select a base directory, if one was not specified.
|
||||||
|
*/
|
||||||
|
if (tr->tr_runtime_base_directory == NULL) {
|
||||||
|
basedir = getenv(TEST_TMPDIR_ENV_VAR);
|
||||||
|
if (basedir == NULL)
|
||||||
|
basedir = getenv(SYSTEM_TMPDIR_ENV_VAR);
|
||||||
|
if (basedir == NULL)
|
||||||
|
basedir = "/tmp";
|
||||||
|
tr->tr_runtime_base_directory = realpath(basedir, NULL);
|
||||||
|
if (tr->tr_runtime_base_directory == NULL)
|
||||||
|
err(1, "realpath(%s) failed", basedir);
|
||||||
|
}
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Add the search paths specified by the environment variable
|
||||||
|
* 'TEST_PATH' to the end of the search list.
|
||||||
|
*/
|
||||||
|
if ((search_path = getenv(TEST_SEARCH_PATH_ENV_VAR)) != NULL &&
|
||||||
|
*search_path != '\0') {
|
||||||
|
path_copy = strdup(search_path);
|
||||||
|
path_element = strtok(path_copy, ":");
|
||||||
|
do {
|
||||||
|
if (!test_driver_add_search_path(tr, path_element))
|
||||||
|
warnx("in environment variable \"%s\": path "
|
||||||
|
"\"%s\" does not name a directory.",
|
||||||
|
TEST_SEARCH_PATH_ENV_VAR, path_element);
|
||||||
|
} while ((path_element = strtok(NULL, ":")) != NULL);
|
||||||
|
}
|
||||||
|
|
||||||
|
return (true);
|
||||||
|
}
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Helper: return true if the passed in path names a directory, or false
|
||||||
|
* otherwise.
|
||||||
|
*/
|
||||||
|
bool
|
||||||
|
test_driver_is_directory(const char *path)
|
||||||
|
{
|
||||||
|
struct stat sb;
|
||||||
|
if (stat(path, &sb) != 0)
|
||||||
|
return false;
|
||||||
|
return S_ISDIR(sb.st_mode);
|
||||||
|
}
|
Some files were not shown because too many files have changed in this diff Show More
Loading…
Reference in New Issue
Block a user